[go: nahoru, domu]

1/*
2 * STMicroelectronics accelerometers driver
3 *
4 * Copyright 2012-2013 STMicroelectronics Inc.
5 *
6 * Denis Ciocca <denis.ciocca@st.com>
7 *
8 * Licensed under the GPL-2.
9 */
10
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/slab.h>
14#include <linux/errno.h>
15#include <linux/types.h>
16#include <linux/mutex.h>
17#include <linux/interrupt.h>
18#include <linux/i2c.h>
19#include <linux/gpio.h>
20#include <linux/irq.h>
21#include <linux/iio/iio.h>
22#include <linux/iio/sysfs.h>
23#include <linux/iio/trigger.h>
24#include <linux/iio/buffer.h>
25
26#include <linux/iio/common/st_sensors.h>
27#include "st_accel.h"
28
29#define ST_ACCEL_NUMBER_DATA_CHANNELS		3
30
31/* DEFAULT VALUE FOR SENSORS */
32#define ST_ACCEL_DEFAULT_OUT_X_L_ADDR		0x28
33#define ST_ACCEL_DEFAULT_OUT_Y_L_ADDR		0x2a
34#define ST_ACCEL_DEFAULT_OUT_Z_L_ADDR		0x2c
35
36/* FULLSCALE */
37#define ST_ACCEL_FS_AVL_2G			2
38#define ST_ACCEL_FS_AVL_4G			4
39#define ST_ACCEL_FS_AVL_6G			6
40#define ST_ACCEL_FS_AVL_8G			8
41#define ST_ACCEL_FS_AVL_16G			16
42
43/* CUSTOM VALUES FOR SENSOR 1 */
44#define ST_ACCEL_1_WAI_EXP			0x33
45#define ST_ACCEL_1_ODR_ADDR			0x20
46#define ST_ACCEL_1_ODR_MASK			0xf0
47#define ST_ACCEL_1_ODR_AVL_1HZ_VAL		0x01
48#define ST_ACCEL_1_ODR_AVL_10HZ_VAL		0x02
49#define ST_ACCEL_1_ODR_AVL_25HZ_VAL		0x03
50#define ST_ACCEL_1_ODR_AVL_50HZ_VAL		0x04
51#define ST_ACCEL_1_ODR_AVL_100HZ_VAL		0x05
52#define ST_ACCEL_1_ODR_AVL_200HZ_VAL		0x06
53#define ST_ACCEL_1_ODR_AVL_400HZ_VAL		0x07
54#define ST_ACCEL_1_ODR_AVL_1600HZ_VAL		0x08
55#define ST_ACCEL_1_FS_ADDR			0x23
56#define ST_ACCEL_1_FS_MASK			0x30
57#define ST_ACCEL_1_FS_AVL_2_VAL			0x00
58#define ST_ACCEL_1_FS_AVL_4_VAL			0x01
59#define ST_ACCEL_1_FS_AVL_8_VAL			0x02
60#define ST_ACCEL_1_FS_AVL_16_VAL		0x03
61#define ST_ACCEL_1_FS_AVL_2_GAIN		IIO_G_TO_M_S_2(1000)
62#define ST_ACCEL_1_FS_AVL_4_GAIN		IIO_G_TO_M_S_2(2000)
63#define ST_ACCEL_1_FS_AVL_8_GAIN		IIO_G_TO_M_S_2(4000)
64#define ST_ACCEL_1_FS_AVL_16_GAIN		IIO_G_TO_M_S_2(12000)
65#define ST_ACCEL_1_BDU_ADDR			0x23
66#define ST_ACCEL_1_BDU_MASK			0x80
67#define ST_ACCEL_1_DRDY_IRQ_ADDR		0x22
68#define ST_ACCEL_1_DRDY_IRQ_INT1_MASK		0x10
69#define ST_ACCEL_1_DRDY_IRQ_INT2_MASK		0x08
70#define ST_ACCEL_1_MULTIREAD_BIT		true
71
72/* CUSTOM VALUES FOR SENSOR 2 */
73#define ST_ACCEL_2_WAI_EXP			0x32
74#define ST_ACCEL_2_ODR_ADDR			0x20
75#define ST_ACCEL_2_ODR_MASK			0x18
76#define ST_ACCEL_2_ODR_AVL_50HZ_VAL		0x00
77#define ST_ACCEL_2_ODR_AVL_100HZ_VAL		0x01
78#define ST_ACCEL_2_ODR_AVL_400HZ_VAL		0x02
79#define ST_ACCEL_2_ODR_AVL_1000HZ_VAL		0x03
80#define ST_ACCEL_2_PW_ADDR			0x20
81#define ST_ACCEL_2_PW_MASK			0xe0
82#define ST_ACCEL_2_FS_ADDR			0x23
83#define ST_ACCEL_2_FS_MASK			0x30
84#define ST_ACCEL_2_FS_AVL_2_VAL			0X00
85#define ST_ACCEL_2_FS_AVL_4_VAL			0X01
86#define ST_ACCEL_2_FS_AVL_8_VAL			0x03
87#define ST_ACCEL_2_FS_AVL_2_GAIN		IIO_G_TO_M_S_2(1000)
88#define ST_ACCEL_2_FS_AVL_4_GAIN		IIO_G_TO_M_S_2(2000)
89#define ST_ACCEL_2_FS_AVL_8_GAIN		IIO_G_TO_M_S_2(3900)
90#define ST_ACCEL_2_BDU_ADDR			0x23
91#define ST_ACCEL_2_BDU_MASK			0x80
92#define ST_ACCEL_2_DRDY_IRQ_ADDR		0x22
93#define ST_ACCEL_2_DRDY_IRQ_INT1_MASK		0x02
94#define ST_ACCEL_2_DRDY_IRQ_INT2_MASK		0x10
95#define ST_ACCEL_2_MULTIREAD_BIT		true
96
97/* CUSTOM VALUES FOR SENSOR 3 */
98#define ST_ACCEL_3_WAI_EXP			0x40
99#define ST_ACCEL_3_ODR_ADDR			0x20
100#define ST_ACCEL_3_ODR_MASK			0xf0
101#define ST_ACCEL_3_ODR_AVL_3HZ_VAL		0x01
102#define ST_ACCEL_3_ODR_AVL_6HZ_VAL		0x02
103#define ST_ACCEL_3_ODR_AVL_12HZ_VAL		0x03
104#define ST_ACCEL_3_ODR_AVL_25HZ_VAL		0x04
105#define ST_ACCEL_3_ODR_AVL_50HZ_VAL		0x05
106#define ST_ACCEL_3_ODR_AVL_100HZ_VAL		0x06
107#define ST_ACCEL_3_ODR_AVL_200HZ_VAL		0x07
108#define ST_ACCEL_3_ODR_AVL_400HZ_VAL		0x08
109#define ST_ACCEL_3_ODR_AVL_800HZ_VAL		0x09
110#define ST_ACCEL_3_ODR_AVL_1600HZ_VAL		0x0a
111#define ST_ACCEL_3_FS_ADDR			0x24
112#define ST_ACCEL_3_FS_MASK			0x38
113#define ST_ACCEL_3_FS_AVL_2_VAL			0X00
114#define ST_ACCEL_3_FS_AVL_4_VAL			0X01
115#define ST_ACCEL_3_FS_AVL_6_VAL			0x02
116#define ST_ACCEL_3_FS_AVL_8_VAL			0x03
117#define ST_ACCEL_3_FS_AVL_16_VAL		0x04
118#define ST_ACCEL_3_FS_AVL_2_GAIN		IIO_G_TO_M_S_2(61)
119#define ST_ACCEL_3_FS_AVL_4_GAIN		IIO_G_TO_M_S_2(122)
120#define ST_ACCEL_3_FS_AVL_6_GAIN		IIO_G_TO_M_S_2(183)
121#define ST_ACCEL_3_FS_AVL_8_GAIN		IIO_G_TO_M_S_2(244)
122#define ST_ACCEL_3_FS_AVL_16_GAIN		IIO_G_TO_M_S_2(732)
123#define ST_ACCEL_3_BDU_ADDR			0x20
124#define ST_ACCEL_3_BDU_MASK			0x08
125#define ST_ACCEL_3_DRDY_IRQ_ADDR		0x23
126#define ST_ACCEL_3_DRDY_IRQ_INT1_MASK		0x80
127#define ST_ACCEL_3_DRDY_IRQ_INT2_MASK		0x00
128#define ST_ACCEL_3_IG1_EN_ADDR			0x23
129#define ST_ACCEL_3_IG1_EN_MASK			0x08
130#define ST_ACCEL_3_MULTIREAD_BIT		false
131
132static const struct iio_chan_spec st_accel_12bit_channels[] = {
133	ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
134			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
135			ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 12, 16,
136			ST_ACCEL_DEFAULT_OUT_X_L_ADDR),
137	ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
138			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
139			ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 12, 16,
140			ST_ACCEL_DEFAULT_OUT_Y_L_ADDR),
141	ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
142			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
143			ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 12, 16,
144			ST_ACCEL_DEFAULT_OUT_Z_L_ADDR),
145	IIO_CHAN_SOFT_TIMESTAMP(3)
146};
147
148static const struct iio_chan_spec st_accel_16bit_channels[] = {
149	ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
150			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
151			ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16,
152			ST_ACCEL_DEFAULT_OUT_X_L_ADDR),
153	ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
154			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
155			ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16,
156			ST_ACCEL_DEFAULT_OUT_Y_L_ADDR),
157	ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
158			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
159			ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16,
160			ST_ACCEL_DEFAULT_OUT_Z_L_ADDR),
161	IIO_CHAN_SOFT_TIMESTAMP(3)
162};
163
164static const struct st_sensors st_accel_sensors[] = {
165	{
166		.wai = ST_ACCEL_1_WAI_EXP,
167		.sensors_supported = {
168			[0] = LIS3DH_ACCEL_DEV_NAME,
169			[1] = LSM303DLHC_ACCEL_DEV_NAME,
170			[2] = LSM330D_ACCEL_DEV_NAME,
171			[3] = LSM330DL_ACCEL_DEV_NAME,
172			[4] = LSM330DLC_ACCEL_DEV_NAME,
173		},
174		.ch = (struct iio_chan_spec *)st_accel_12bit_channels,
175		.odr = {
176			.addr = ST_ACCEL_1_ODR_ADDR,
177			.mask = ST_ACCEL_1_ODR_MASK,
178			.odr_avl = {
179				{ 1, ST_ACCEL_1_ODR_AVL_1HZ_VAL, },
180				{ 10, ST_ACCEL_1_ODR_AVL_10HZ_VAL, },
181				{ 25, ST_ACCEL_1_ODR_AVL_25HZ_VAL, },
182				{ 50, ST_ACCEL_1_ODR_AVL_50HZ_VAL, },
183				{ 100, ST_ACCEL_1_ODR_AVL_100HZ_VAL, },
184				{ 200, ST_ACCEL_1_ODR_AVL_200HZ_VAL, },
185				{ 400, ST_ACCEL_1_ODR_AVL_400HZ_VAL, },
186				{ 1600, ST_ACCEL_1_ODR_AVL_1600HZ_VAL, },
187			},
188		},
189		.pw = {
190			.addr = ST_ACCEL_1_ODR_ADDR,
191			.mask = ST_ACCEL_1_ODR_MASK,
192			.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
193		},
194		.enable_axis = {
195			.addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
196			.mask = ST_SENSORS_DEFAULT_AXIS_MASK,
197		},
198		.fs = {
199			.addr = ST_ACCEL_1_FS_ADDR,
200			.mask = ST_ACCEL_1_FS_MASK,
201			.fs_avl = {
202				[0] = {
203					.num = ST_ACCEL_FS_AVL_2G,
204					.value = ST_ACCEL_1_FS_AVL_2_VAL,
205					.gain = ST_ACCEL_1_FS_AVL_2_GAIN,
206				},
207				[1] = {
208					.num = ST_ACCEL_FS_AVL_4G,
209					.value = ST_ACCEL_1_FS_AVL_4_VAL,
210					.gain = ST_ACCEL_1_FS_AVL_4_GAIN,
211				},
212				[2] = {
213					.num = ST_ACCEL_FS_AVL_8G,
214					.value = ST_ACCEL_1_FS_AVL_8_VAL,
215					.gain = ST_ACCEL_1_FS_AVL_8_GAIN,
216				},
217				[3] = {
218					.num = ST_ACCEL_FS_AVL_16G,
219					.value = ST_ACCEL_1_FS_AVL_16_VAL,
220					.gain = ST_ACCEL_1_FS_AVL_16_GAIN,
221				},
222			},
223		},
224		.bdu = {
225			.addr = ST_ACCEL_1_BDU_ADDR,
226			.mask = ST_ACCEL_1_BDU_MASK,
227		},
228		.drdy_irq = {
229			.addr = ST_ACCEL_1_DRDY_IRQ_ADDR,
230			.mask_int1 = ST_ACCEL_1_DRDY_IRQ_INT1_MASK,
231			.mask_int2 = ST_ACCEL_1_DRDY_IRQ_INT2_MASK,
232		},
233		.multi_read_bit = ST_ACCEL_1_MULTIREAD_BIT,
234		.bootime = 2,
235	},
236	{
237		.wai = ST_ACCEL_2_WAI_EXP,
238		.sensors_supported = {
239			[0] = LIS331DLH_ACCEL_DEV_NAME,
240			[1] = LSM303DL_ACCEL_DEV_NAME,
241			[2] = LSM303DLH_ACCEL_DEV_NAME,
242			[3] = LSM303DLM_ACCEL_DEV_NAME,
243		},
244		.ch = (struct iio_chan_spec *)st_accel_12bit_channels,
245		.odr = {
246			.addr = ST_ACCEL_2_ODR_ADDR,
247			.mask = ST_ACCEL_2_ODR_MASK,
248			.odr_avl = {
249				{ 50, ST_ACCEL_2_ODR_AVL_50HZ_VAL, },
250				{ 100, ST_ACCEL_2_ODR_AVL_100HZ_VAL, },
251				{ 400, ST_ACCEL_2_ODR_AVL_400HZ_VAL, },
252				{ 1000, ST_ACCEL_2_ODR_AVL_1000HZ_VAL, },
253			},
254		},
255		.pw = {
256			.addr = ST_ACCEL_2_PW_ADDR,
257			.mask = ST_ACCEL_2_PW_MASK,
258			.value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
259			.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
260		},
261		.enable_axis = {
262			.addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
263			.mask = ST_SENSORS_DEFAULT_AXIS_MASK,
264		},
265		.fs = {
266			.addr = ST_ACCEL_2_FS_ADDR,
267			.mask = ST_ACCEL_2_FS_MASK,
268			.fs_avl = {
269				[0] = {
270					.num = ST_ACCEL_FS_AVL_2G,
271					.value = ST_ACCEL_2_FS_AVL_2_VAL,
272					.gain = ST_ACCEL_2_FS_AVL_2_GAIN,
273				},
274				[1] = {
275					.num = ST_ACCEL_FS_AVL_4G,
276					.value = ST_ACCEL_2_FS_AVL_4_VAL,
277					.gain = ST_ACCEL_2_FS_AVL_4_GAIN,
278				},
279				[2] = {
280					.num = ST_ACCEL_FS_AVL_8G,
281					.value = ST_ACCEL_2_FS_AVL_8_VAL,
282					.gain = ST_ACCEL_2_FS_AVL_8_GAIN,
283				},
284			},
285		},
286		.bdu = {
287			.addr = ST_ACCEL_2_BDU_ADDR,
288			.mask = ST_ACCEL_2_BDU_MASK,
289		},
290		.drdy_irq = {
291			.addr = ST_ACCEL_2_DRDY_IRQ_ADDR,
292			.mask_int1 = ST_ACCEL_2_DRDY_IRQ_INT1_MASK,
293			.mask_int2 = ST_ACCEL_2_DRDY_IRQ_INT2_MASK,
294		},
295		.multi_read_bit = ST_ACCEL_2_MULTIREAD_BIT,
296		.bootime = 2,
297	},
298	{
299		.wai = ST_ACCEL_3_WAI_EXP,
300		.sensors_supported = {
301			[0] = LSM330_ACCEL_DEV_NAME,
302		},
303		.ch = (struct iio_chan_spec *)st_accel_16bit_channels,
304		.odr = {
305			.addr = ST_ACCEL_3_ODR_ADDR,
306			.mask = ST_ACCEL_3_ODR_MASK,
307			.odr_avl = {
308				{ 3, ST_ACCEL_3_ODR_AVL_3HZ_VAL },
309				{ 6, ST_ACCEL_3_ODR_AVL_6HZ_VAL, },
310				{ 12, ST_ACCEL_3_ODR_AVL_12HZ_VAL, },
311				{ 25, ST_ACCEL_3_ODR_AVL_25HZ_VAL, },
312				{ 50, ST_ACCEL_3_ODR_AVL_50HZ_VAL, },
313				{ 100, ST_ACCEL_3_ODR_AVL_100HZ_VAL, },
314				{ 200, ST_ACCEL_3_ODR_AVL_200HZ_VAL, },
315				{ 400, ST_ACCEL_3_ODR_AVL_400HZ_VAL, },
316				{ 800, ST_ACCEL_3_ODR_AVL_800HZ_VAL, },
317				{ 1600, ST_ACCEL_3_ODR_AVL_1600HZ_VAL, },
318			},
319		},
320		.pw = {
321			.addr = ST_ACCEL_3_ODR_ADDR,
322			.mask = ST_ACCEL_3_ODR_MASK,
323			.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
324		},
325		.enable_axis = {
326			.addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
327			.mask = ST_SENSORS_DEFAULT_AXIS_MASK,
328		},
329		.fs = {
330			.addr = ST_ACCEL_3_FS_ADDR,
331			.mask = ST_ACCEL_3_FS_MASK,
332			.fs_avl = {
333				[0] = {
334					.num = ST_ACCEL_FS_AVL_2G,
335					.value = ST_ACCEL_3_FS_AVL_2_VAL,
336					.gain = ST_ACCEL_3_FS_AVL_2_GAIN,
337				},
338				[1] = {
339					.num = ST_ACCEL_FS_AVL_4G,
340					.value = ST_ACCEL_3_FS_AVL_4_VAL,
341					.gain = ST_ACCEL_3_FS_AVL_4_GAIN,
342				},
343				[2] = {
344					.num = ST_ACCEL_FS_AVL_6G,
345					.value = ST_ACCEL_3_FS_AVL_6_VAL,
346					.gain = ST_ACCEL_3_FS_AVL_6_GAIN,
347				},
348				[3] = {
349					.num = ST_ACCEL_FS_AVL_8G,
350					.value = ST_ACCEL_3_FS_AVL_8_VAL,
351					.gain = ST_ACCEL_3_FS_AVL_8_GAIN,
352				},
353				[4] = {
354					.num = ST_ACCEL_FS_AVL_16G,
355					.value = ST_ACCEL_3_FS_AVL_16_VAL,
356					.gain = ST_ACCEL_3_FS_AVL_16_GAIN,
357				},
358			},
359		},
360		.bdu = {
361			.addr = ST_ACCEL_3_BDU_ADDR,
362			.mask = ST_ACCEL_3_BDU_MASK,
363		},
364		.drdy_irq = {
365			.addr = ST_ACCEL_3_DRDY_IRQ_ADDR,
366			.mask_int1 = ST_ACCEL_3_DRDY_IRQ_INT1_MASK,
367			.mask_int2 = ST_ACCEL_3_DRDY_IRQ_INT2_MASK,
368			.ig1 = {
369				.en_addr = ST_ACCEL_3_IG1_EN_ADDR,
370				.en_mask = ST_ACCEL_3_IG1_EN_MASK,
371			},
372		},
373		.multi_read_bit = ST_ACCEL_3_MULTIREAD_BIT,
374		.bootime = 2,
375	},
376};
377
378static int st_accel_read_raw(struct iio_dev *indio_dev,
379			struct iio_chan_spec const *ch, int *val,
380							int *val2, long mask)
381{
382	int err;
383	struct st_sensor_data *adata = iio_priv(indio_dev);
384
385	switch (mask) {
386	case IIO_CHAN_INFO_RAW:
387		err = st_sensors_read_info_raw(indio_dev, ch, val);
388		if (err < 0)
389			goto read_error;
390
391		return IIO_VAL_INT;
392	case IIO_CHAN_INFO_SCALE:
393		*val = 0;
394		*val2 = adata->current_fullscale->gain;
395		return IIO_VAL_INT_PLUS_MICRO;
396	case IIO_CHAN_INFO_SAMP_FREQ:
397		*val = adata->odr;
398		return IIO_VAL_INT;
399	default:
400		return -EINVAL;
401	}
402
403read_error:
404	return err;
405}
406
407static int st_accel_write_raw(struct iio_dev *indio_dev,
408		struct iio_chan_spec const *chan, int val, int val2, long mask)
409{
410	int err;
411
412	switch (mask) {
413	case IIO_CHAN_INFO_SCALE:
414		err = st_sensors_set_fullscale_by_gain(indio_dev, val2);
415		break;
416	case IIO_CHAN_INFO_SAMP_FREQ:
417		if (val2)
418			return -EINVAL;
419		mutex_lock(&indio_dev->mlock);
420		err = st_sensors_set_odr(indio_dev, val);
421		mutex_unlock(&indio_dev->mlock);
422		return err;
423	default:
424		return -EINVAL;
425	}
426
427	return err;
428}
429
430static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
431static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_accel_scale_available);
432
433static struct attribute *st_accel_attributes[] = {
434	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
435	&iio_dev_attr_in_accel_scale_available.dev_attr.attr,
436	NULL,
437};
438
439static const struct attribute_group st_accel_attribute_group = {
440	.attrs = st_accel_attributes,
441};
442
443static const struct iio_info accel_info = {
444	.driver_module = THIS_MODULE,
445	.attrs = &st_accel_attribute_group,
446	.read_raw = &st_accel_read_raw,
447	.write_raw = &st_accel_write_raw,
448};
449
450#ifdef CONFIG_IIO_TRIGGER
451static const struct iio_trigger_ops st_accel_trigger_ops = {
452	.owner = THIS_MODULE,
453	.set_trigger_state = ST_ACCEL_TRIGGER_SET_STATE,
454};
455#define ST_ACCEL_TRIGGER_OPS (&st_accel_trigger_ops)
456#else
457#define ST_ACCEL_TRIGGER_OPS NULL
458#endif
459
460int st_accel_common_probe(struct iio_dev *indio_dev,
461				struct st_sensors_platform_data *plat_data)
462{
463	struct st_sensor_data *adata = iio_priv(indio_dev);
464	int irq = adata->get_irq_data_ready(indio_dev);
465	int err;
466
467	indio_dev->modes = INDIO_DIRECT_MODE;
468	indio_dev->info = &accel_info;
469
470	st_sensors_power_enable(indio_dev);
471
472	err = st_sensors_check_device_support(indio_dev,
473				ARRAY_SIZE(st_accel_sensors), st_accel_sensors);
474	if (err < 0)
475		return err;
476
477	adata->num_data_channels = ST_ACCEL_NUMBER_DATA_CHANNELS;
478	adata->multiread_bit = adata->sensor->multi_read_bit;
479	indio_dev->channels = adata->sensor->ch;
480	indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS;
481
482	adata->current_fullscale = (struct st_sensor_fullscale_avl *)
483						&adata->sensor->fs.fs_avl[0];
484	adata->odr = adata->sensor->odr.odr_avl[0].hz;
485
486	if (!plat_data)
487		plat_data =
488			(struct st_sensors_platform_data *)&default_accel_pdata;
489
490	err = st_sensors_init_sensor(indio_dev, plat_data);
491	if (err < 0)
492		return err;
493
494	err = st_accel_allocate_ring(indio_dev);
495	if (err < 0)
496		return err;
497
498	if (irq > 0) {
499		err = st_sensors_allocate_trigger(indio_dev,
500						 ST_ACCEL_TRIGGER_OPS);
501		if (err < 0)
502			goto st_accel_probe_trigger_error;
503	}
504
505	err = iio_device_register(indio_dev);
506	if (err)
507		goto st_accel_device_register_error;
508
509	dev_info(&indio_dev->dev, "registered accelerometer %s\n",
510		 indio_dev->name);
511
512	return 0;
513
514st_accel_device_register_error:
515	if (irq > 0)
516		st_sensors_deallocate_trigger(indio_dev);
517st_accel_probe_trigger_error:
518	st_accel_deallocate_ring(indio_dev);
519
520	return err;
521}
522EXPORT_SYMBOL(st_accel_common_probe);
523
524void st_accel_common_remove(struct iio_dev *indio_dev)
525{
526	struct st_sensor_data *adata = iio_priv(indio_dev);
527
528	st_sensors_power_disable(indio_dev);
529
530	iio_device_unregister(indio_dev);
531	if (adata->get_irq_data_ready(indio_dev) > 0)
532		st_sensors_deallocate_trigger(indio_dev);
533
534	st_accel_deallocate_ring(indio_dev);
535}
536EXPORT_SYMBOL(st_accel_common_remove);
537
538MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
539MODULE_DESCRIPTION("STMicroelectronics accelerometers driver");
540MODULE_LICENSE("GPL v2");
541