diff options
author | Denis CIOCCA <denis.ciocca@st.com> | 2013-06-03 10:58:00 -0400 |
---|---|---|
committer | Jonathan Cameron <jic23@kernel.org> | 2013-06-05 13:41:23 -0400 |
commit | 217494e5b780ad85485c1bb6382ce50b5fa2dc26 (patch) | |
tree | 26e9fd1c62477c099c05a3fbcdd265c287bc1ef8 /drivers/iio/pressure | |
parent | 607a568ab69c5ac345a286267a27294888f8bb5f (diff) |
iio:pressure: Add STMicroelectronics pressures driver
This patch adds a generic pressure driver for STMicroelectronics
pressure sensors, currently it supports: LPS331AP.
Signed-off-by: Denis Ciocca <denis.ciocca@st.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Diffstat (limited to 'drivers/iio/pressure')
-rw-r--r-- | drivers/iio/pressure/Kconfig | 35 | ||||
-rw-r--r-- | drivers/iio/pressure/Makefile | 10 | ||||
-rw-r--r-- | drivers/iio/pressure/st_pressure.h | 39 | ||||
-rw-r--r-- | drivers/iio/pressure/st_pressure_buffer.c | 105 | ||||
-rw-r--r-- | drivers/iio/pressure/st_pressure_core.c | 272 | ||||
-rw-r--r-- | drivers/iio/pressure/st_pressure_i2c.c | 77 | ||||
-rw-r--r-- | drivers/iio/pressure/st_pressure_spi.c | 76 |
7 files changed, 614 insertions, 0 deletions
diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig new file mode 100644 index 000000000000..9427f01e1499 --- /dev/null +++ b/drivers/iio/pressure/Kconfig | |||
@@ -0,0 +1,35 @@ | |||
1 | # | ||
2 | # Pressure drivers | ||
3 | # | ||
4 | menu "Pressure Sensors" | ||
5 | |||
6 | config IIO_ST_PRESS | ||
7 | tristate "STMicroelectronics pressures Driver" | ||
8 | depends on (I2C || SPI_MASTER) && SYSFS | ||
9 | select IIO_ST_SENSORS_CORE | ||
10 | select IIO_ST_PRESS_I2C if (I2C) | ||
11 | select IIO_ST_PRESS_SPI if (SPI_MASTER) | ||
12 | select IIO_TRIGGERED_BUFFER if (IIO_BUFFER) | ||
13 | help | ||
14 | Say yes here to build support for STMicroelectronics pressures: | ||
15 | LPS331AP. | ||
16 | |||
17 | This driver can also be built as a module. If so, will be created | ||
18 | these modules: | ||
19 | - st_pressure (core functions for the driver [it is mandatory]); | ||
20 | - st_pressure_i2c (necessary for the I2C devices [optional*]); | ||
21 | - st_pressure_spi (necessary for the SPI devices [optional*]); | ||
22 | |||
23 | (*) one of these is necessary to do something. | ||
24 | |||
25 | config IIO_ST_PRESS_I2C | ||
26 | tristate | ||
27 | depends on IIO_ST_PRESS | ||
28 | depends on IIO_ST_SENSORS_I2C | ||
29 | |||
30 | config IIO_ST_PRESS_SPI | ||
31 | tristate | ||
32 | depends on IIO_ST_PRESS | ||
33 | depends on IIO_ST_SENSORS_SPI | ||
34 | |||
35 | endmenu | ||
diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile new file mode 100644 index 000000000000..d4bb33e5c846 --- /dev/null +++ b/drivers/iio/pressure/Makefile | |||
@@ -0,0 +1,10 @@ | |||
1 | # | ||
2 | # Makefile for industrial I/O pressure drivers | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_IIO_ST_PRESS) += st_pressure.o | ||
6 | st_pressure-y := st_pressure_core.o | ||
7 | st_pressure-$(CONFIG_IIO_BUFFER) += st_pressure_buffer.o | ||
8 | |||
9 | obj-$(CONFIG_IIO_ST_PRESS_I2C) += st_pressure_i2c.o | ||
10 | obj-$(CONFIG_IIO_ST_PRESS_SPI) += st_pressure_spi.o | ||
diff --git a/drivers/iio/pressure/st_pressure.h b/drivers/iio/pressure/st_pressure.h new file mode 100644 index 000000000000..414e45ac9b9b --- /dev/null +++ b/drivers/iio/pressure/st_pressure.h | |||
@@ -0,0 +1,39 @@ | |||
1 | /* | ||
2 | * STMicroelectronics pressures driver | ||
3 | * | ||
4 | * Copyright 2013 STMicroelectronics Inc. | ||
5 | * | ||
6 | * Denis Ciocca <denis.ciocca@st.com> | ||
7 | * v. 1.0.0 | ||
8 | * Licensed under the GPL-2. | ||
9 | */ | ||
10 | |||
11 | #ifndef ST_PRESS_H | ||
12 | #define ST_PRESS_H | ||
13 | |||
14 | #include <linux/types.h> | ||
15 | #include <linux/iio/common/st_sensors.h> | ||
16 | |||
17 | #define LPS331AP_PRESS_DEV_NAME "lps331ap" | ||
18 | |||
19 | int st_press_common_probe(struct iio_dev *indio_dev); | ||
20 | void st_press_common_remove(struct iio_dev *indio_dev); | ||
21 | |||
22 | #ifdef CONFIG_IIO_BUFFER | ||
23 | int st_press_allocate_ring(struct iio_dev *indio_dev); | ||
24 | void st_press_deallocate_ring(struct iio_dev *indio_dev); | ||
25 | int st_press_trig_set_state(struct iio_trigger *trig, bool state); | ||
26 | #define ST_PRESS_TRIGGER_SET_STATE (&st_press_trig_set_state) | ||
27 | #else /* CONFIG_IIO_BUFFER */ | ||
28 | static inline int st_press_allocate_ring(struct iio_dev *indio_dev) | ||
29 | { | ||
30 | return 0; | ||
31 | } | ||
32 | |||
33 | static inline void st_press_deallocate_ring(struct iio_dev *indio_dev) | ||
34 | { | ||
35 | } | ||
36 | #define ST_PRESS_TRIGGER_SET_STATE NULL | ||
37 | #endif /* CONFIG_IIO_BUFFER */ | ||
38 | |||
39 | #endif /* ST_PRESS_H */ | ||
diff --git a/drivers/iio/pressure/st_pressure_buffer.c b/drivers/iio/pressure/st_pressure_buffer.c new file mode 100644 index 000000000000..f877ef8af520 --- /dev/null +++ b/drivers/iio/pressure/st_pressure_buffer.c | |||
@@ -0,0 +1,105 @@ | |||
1 | /* | ||
2 | * STMicroelectronics pressures driver | ||
3 | * | ||
4 | * Copyright 2013 STMicroelectronics Inc. | ||
5 | * | ||
6 | * Denis Ciocca <denis.ciocca@st.com> | ||
7 | * | ||
8 | * Licensed under the GPL-2. | ||
9 | */ | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/stat.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/i2c.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/iio/iio.h> | ||
19 | #include <linux/iio/buffer.h> | ||
20 | #include <linux/iio/trigger_consumer.h> | ||
21 | #include <linux/iio/triggered_buffer.h> | ||
22 | |||
23 | #include <linux/iio/common/st_sensors.h> | ||
24 | #include "st_pressure.h" | ||
25 | |||
26 | int st_press_trig_set_state(struct iio_trigger *trig, bool state) | ||
27 | { | ||
28 | struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); | ||
29 | |||
30 | return st_sensors_set_dataready_irq(indio_dev, state); | ||
31 | } | ||
32 | |||
33 | static int st_press_buffer_preenable(struct iio_dev *indio_dev) | ||
34 | { | ||
35 | int err; | ||
36 | |||
37 | err = st_sensors_set_enable(indio_dev, true); | ||
38 | if (err < 0) | ||
39 | goto st_press_set_enable_error; | ||
40 | |||
41 | err = iio_sw_buffer_preenable(indio_dev); | ||
42 | |||
43 | st_press_set_enable_error: | ||
44 | return err; | ||
45 | } | ||
46 | |||
47 | static int st_press_buffer_postenable(struct iio_dev *indio_dev) | ||
48 | { | ||
49 | int err; | ||
50 | struct st_sensor_data *pdata = iio_priv(indio_dev); | ||
51 | |||
52 | pdata->buffer_data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); | ||
53 | if (pdata->buffer_data == NULL) { | ||
54 | err = -ENOMEM; | ||
55 | goto allocate_memory_error; | ||
56 | } | ||
57 | |||
58 | err = iio_triggered_buffer_postenable(indio_dev); | ||
59 | if (err < 0) | ||
60 | goto st_press_buffer_postenable_error; | ||
61 | |||
62 | return err; | ||
63 | |||
64 | st_press_buffer_postenable_error: | ||
65 | kfree(pdata->buffer_data); | ||
66 | allocate_memory_error: | ||
67 | return err; | ||
68 | } | ||
69 | |||
70 | static int st_press_buffer_predisable(struct iio_dev *indio_dev) | ||
71 | { | ||
72 | int err; | ||
73 | struct st_sensor_data *pdata = iio_priv(indio_dev); | ||
74 | |||
75 | err = iio_triggered_buffer_predisable(indio_dev); | ||
76 | if (err < 0) | ||
77 | goto st_press_buffer_predisable_error; | ||
78 | |||
79 | err = st_sensors_set_enable(indio_dev, false); | ||
80 | |||
81 | st_press_buffer_predisable_error: | ||
82 | kfree(pdata->buffer_data); | ||
83 | return err; | ||
84 | } | ||
85 | |||
86 | static const struct iio_buffer_setup_ops st_press_buffer_setup_ops = { | ||
87 | .preenable = &st_press_buffer_preenable, | ||
88 | .postenable = &st_press_buffer_postenable, | ||
89 | .predisable = &st_press_buffer_predisable, | ||
90 | }; | ||
91 | |||
92 | int st_press_allocate_ring(struct iio_dev *indio_dev) | ||
93 | { | ||
94 | return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, | ||
95 | &st_sensors_trigger_handler, &st_press_buffer_setup_ops); | ||
96 | } | ||
97 | |||
98 | void st_press_deallocate_ring(struct iio_dev *indio_dev) | ||
99 | { | ||
100 | iio_triggered_buffer_cleanup(indio_dev); | ||
101 | } | ||
102 | |||
103 | MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>"); | ||
104 | MODULE_DESCRIPTION("STMicroelectronics pressures buffer"); | ||
105 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c new file mode 100644 index 000000000000..9c343b40665e --- /dev/null +++ b/drivers/iio/pressure/st_pressure_core.c | |||
@@ -0,0 +1,272 @@ | |||
1 | /* | ||
2 | * STMicroelectronics pressures driver | ||
3 | * | ||
4 | * Copyright 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/delay.h> | ||
22 | #include <linux/iio/iio.h> | ||
23 | #include <linux/iio/sysfs.h> | ||
24 | #include <linux/iio/trigger.h> | ||
25 | #include <linux/iio/buffer.h> | ||
26 | #include <asm/unaligned.h> | ||
27 | |||
28 | #include <linux/iio/common/st_sensors.h> | ||
29 | #include "st_pressure.h" | ||
30 | |||
31 | #define ST_PRESS_MBAR_TO_KPASCAL(x) (x * 10) | ||
32 | #define ST_PRESS_NUMBER_DATA_CHANNELS 1 | ||
33 | |||
34 | /* DEFAULT VALUE FOR SENSORS */ | ||
35 | #define ST_PRESS_DEFAULT_OUT_XL_ADDR 0x28 | ||
36 | #define ST_TEMP_DEFAULT_OUT_L_ADDR 0x2b | ||
37 | |||
38 | /* FULLSCALE */ | ||
39 | #define ST_PRESS_FS_AVL_1260MB 1260 | ||
40 | |||
41 | /* CUSTOM VALUES FOR SENSOR 1 */ | ||
42 | #define ST_PRESS_1_WAI_EXP 0xbb | ||
43 | #define ST_PRESS_1_ODR_ADDR 0x20 | ||
44 | #define ST_PRESS_1_ODR_MASK 0x70 | ||
45 | #define ST_PRESS_1_ODR_AVL_1HZ_VAL 0x01 | ||
46 | #define ST_PRESS_1_ODR_AVL_7HZ_VAL 0x05 | ||
47 | #define ST_PRESS_1_ODR_AVL_13HZ_VAL 0x06 | ||
48 | #define ST_PRESS_1_ODR_AVL_25HZ_VAL 0x07 | ||
49 | #define ST_PRESS_1_PW_ADDR 0x20 | ||
50 | #define ST_PRESS_1_PW_MASK 0x80 | ||
51 | #define ST_PRESS_1_FS_ADDR 0x23 | ||
52 | #define ST_PRESS_1_FS_MASK 0x30 | ||
53 | #define ST_PRESS_1_FS_AVL_1260_VAL 0x00 | ||
54 | #define ST_PRESS_1_FS_AVL_1260_GAIN ST_PRESS_MBAR_TO_KPASCAL(244141) | ||
55 | #define ST_PRESS_1_FS_AVL_TEMP_GAIN 2083000 | ||
56 | #define ST_PRESS_1_BDU_ADDR 0x20 | ||
57 | #define ST_PRESS_1_BDU_MASK 0x04 | ||
58 | #define ST_PRESS_1_DRDY_IRQ_ADDR 0x22 | ||
59 | #define ST_PRESS_1_DRDY_IRQ_MASK 0x04 | ||
60 | #define ST_PRESS_1_MULTIREAD_BIT true | ||
61 | #define ST_PRESS_1_TEMP_OFFSET 42500 | ||
62 | |||
63 | static const struct iio_chan_spec st_press_channels[] = { | ||
64 | ST_SENSORS_LSM_CHANNELS(IIO_PRESSURE, | ||
65 | BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), | ||
66 | ST_SENSORS_SCAN_X, 0, IIO_NO_MOD, 'u', IIO_LE, 24, 24, | ||
67 | ST_PRESS_DEFAULT_OUT_XL_ADDR), | ||
68 | ST_SENSORS_LSM_CHANNELS(IIO_TEMP, | ||
69 | BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) | | ||
70 | BIT(IIO_CHAN_INFO_OFFSET), | ||
71 | -1, 0, IIO_NO_MOD, 's', IIO_LE, 16, 16, | ||
72 | ST_TEMP_DEFAULT_OUT_L_ADDR), | ||
73 | IIO_CHAN_SOFT_TIMESTAMP(1) | ||
74 | }; | ||
75 | |||
76 | static const struct st_sensors st_press_sensors[] = { | ||
77 | { | ||
78 | .wai = ST_PRESS_1_WAI_EXP, | ||
79 | .sensors_supported = { | ||
80 | [0] = LPS331AP_PRESS_DEV_NAME, | ||
81 | }, | ||
82 | .ch = (struct iio_chan_spec *)st_press_channels, | ||
83 | .odr = { | ||
84 | .addr = ST_PRESS_1_ODR_ADDR, | ||
85 | .mask = ST_PRESS_1_ODR_MASK, | ||
86 | .odr_avl = { | ||
87 | { 1, ST_PRESS_1_ODR_AVL_1HZ_VAL, }, | ||
88 | { 7, ST_PRESS_1_ODR_AVL_7HZ_VAL, }, | ||
89 | { 13, ST_PRESS_1_ODR_AVL_13HZ_VAL, }, | ||
90 | { 25, ST_PRESS_1_ODR_AVL_25HZ_VAL, }, | ||
91 | }, | ||
92 | }, | ||
93 | .pw = { | ||
94 | .addr = ST_PRESS_1_PW_ADDR, | ||
95 | .mask = ST_PRESS_1_PW_MASK, | ||
96 | .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE, | ||
97 | .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE, | ||
98 | }, | ||
99 | .fs = { | ||
100 | .addr = ST_PRESS_1_FS_ADDR, | ||
101 | .mask = ST_PRESS_1_FS_MASK, | ||
102 | .fs_avl = { | ||
103 | [0] = { | ||
104 | .num = ST_PRESS_FS_AVL_1260MB, | ||
105 | .value = ST_PRESS_1_FS_AVL_1260_VAL, | ||
106 | .gain = ST_PRESS_1_FS_AVL_1260_GAIN, | ||
107 | .gain2 = ST_PRESS_1_FS_AVL_TEMP_GAIN, | ||
108 | }, | ||
109 | }, | ||
110 | }, | ||
111 | .bdu = { | ||
112 | .addr = ST_PRESS_1_BDU_ADDR, | ||
113 | .mask = ST_PRESS_1_BDU_MASK, | ||
114 | }, | ||
115 | .drdy_irq = { | ||
116 | .addr = ST_PRESS_1_DRDY_IRQ_ADDR, | ||
117 | .mask = ST_PRESS_1_DRDY_IRQ_MASK, | ||
118 | }, | ||
119 | .multi_read_bit = ST_PRESS_1_MULTIREAD_BIT, | ||
120 | .bootime = 2, | ||
121 | }, | ||
122 | }; | ||
123 | |||
124 | static int st_press_read_raw(struct iio_dev *indio_dev, | ||
125 | struct iio_chan_spec const *ch, int *val, | ||
126 | int *val2, long mask) | ||
127 | { | ||
128 | int err; | ||
129 | struct st_sensor_data *pdata = iio_priv(indio_dev); | ||
130 | |||
131 | switch (mask) { | ||
132 | case IIO_CHAN_INFO_RAW: | ||
133 | err = st_sensors_read_info_raw(indio_dev, ch, val); | ||
134 | if (err < 0) | ||
135 | goto read_error; | ||
136 | |||
137 | return IIO_VAL_INT; | ||
138 | case IIO_CHAN_INFO_SCALE: | ||
139 | *val = 0; | ||
140 | |||
141 | switch (ch->type) { | ||
142 | case IIO_PRESSURE: | ||
143 | *val2 = pdata->current_fullscale->gain; | ||
144 | break; | ||
145 | case IIO_TEMP: | ||
146 | *val2 = pdata->current_fullscale->gain2; | ||
147 | break; | ||
148 | default: | ||
149 | err = -EINVAL; | ||
150 | goto read_error; | ||
151 | } | ||
152 | |||
153 | return IIO_VAL_INT_PLUS_NANO; | ||
154 | case IIO_CHAN_INFO_OFFSET: | ||
155 | switch (ch->type) { | ||
156 | case IIO_TEMP: | ||
157 | *val = 425; | ||
158 | *val2 = 10; | ||
159 | break; | ||
160 | default: | ||
161 | err = -EINVAL; | ||
162 | goto read_error; | ||
163 | } | ||
164 | |||
165 | return IIO_VAL_FRACTIONAL; | ||
166 | default: | ||
167 | return -EINVAL; | ||
168 | } | ||
169 | |||
170 | read_error: | ||
171 | return err; | ||
172 | } | ||
173 | |||
174 | static ST_SENSOR_DEV_ATTR_SAMP_FREQ(); | ||
175 | static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL(); | ||
176 | |||
177 | static struct attribute *st_press_attributes[] = { | ||
178 | &iio_dev_attr_sampling_frequency_available.dev_attr.attr, | ||
179 | &iio_dev_attr_sampling_frequency.dev_attr.attr, | ||
180 | NULL, | ||
181 | }; | ||
182 | |||
183 | static const struct attribute_group st_press_attribute_group = { | ||
184 | .attrs = st_press_attributes, | ||
185 | }; | ||
186 | |||
187 | static const struct iio_info press_info = { | ||
188 | .driver_module = THIS_MODULE, | ||
189 | .attrs = &st_press_attribute_group, | ||
190 | .read_raw = &st_press_read_raw, | ||
191 | }; | ||
192 | |||
193 | #ifdef CONFIG_IIO_TRIGGER | ||
194 | static const struct iio_trigger_ops st_press_trigger_ops = { | ||
195 | .owner = THIS_MODULE, | ||
196 | .set_trigger_state = ST_PRESS_TRIGGER_SET_STATE, | ||
197 | }; | ||
198 | #define ST_PRESS_TRIGGER_OPS (&st_press_trigger_ops) | ||
199 | #else | ||
200 | #define ST_PRESS_TRIGGER_OPS NULL | ||
201 | #endif | ||
202 | |||
203 | int st_press_common_probe(struct iio_dev *indio_dev) | ||
204 | { | ||
205 | int err; | ||
206 | struct st_sensor_data *pdata = iio_priv(indio_dev); | ||
207 | |||
208 | indio_dev->modes = INDIO_DIRECT_MODE; | ||
209 | indio_dev->info = &press_info; | ||
210 | |||
211 | err = st_sensors_check_device_support(indio_dev, | ||
212 | ARRAY_SIZE(st_press_sensors), st_press_sensors); | ||
213 | if (err < 0) | ||
214 | goto st_press_common_probe_error; | ||
215 | |||
216 | pdata->num_data_channels = ST_PRESS_NUMBER_DATA_CHANNELS; | ||
217 | pdata->multiread_bit = pdata->sensor->multi_read_bit; | ||
218 | indio_dev->channels = pdata->sensor->ch; | ||
219 | indio_dev->num_channels = ARRAY_SIZE(st_press_channels); | ||
220 | |||
221 | pdata->current_fullscale = (struct st_sensor_fullscale_avl *) | ||
222 | &pdata->sensor->fs.fs_avl[0]; | ||
223 | pdata->odr = pdata->sensor->odr.odr_avl[0].hz; | ||
224 | |||
225 | err = st_sensors_init_sensor(indio_dev); | ||
226 | if (err < 0) | ||
227 | goto st_press_common_probe_error; | ||
228 | |||
229 | if (pdata->get_irq_data_ready(indio_dev) > 0) { | ||
230 | err = st_press_allocate_ring(indio_dev); | ||
231 | if (err < 0) | ||
232 | goto st_press_common_probe_error; | ||
233 | |||
234 | err = st_sensors_allocate_trigger(indio_dev, | ||
235 | ST_PRESS_TRIGGER_OPS); | ||
236 | if (err < 0) | ||
237 | goto st_press_probe_trigger_error; | ||
238 | } | ||
239 | |||
240 | err = iio_device_register(indio_dev); | ||
241 | if (err) | ||
242 | goto st_press_device_register_error; | ||
243 | |||
244 | return err; | ||
245 | |||
246 | st_press_device_register_error: | ||
247 | if (pdata->get_irq_data_ready(indio_dev) > 0) | ||
248 | st_sensors_deallocate_trigger(indio_dev); | ||
249 | st_press_probe_trigger_error: | ||
250 | if (pdata->get_irq_data_ready(indio_dev) > 0) | ||
251 | st_press_deallocate_ring(indio_dev); | ||
252 | st_press_common_probe_error: | ||
253 | return err; | ||
254 | } | ||
255 | EXPORT_SYMBOL(st_press_common_probe); | ||
256 | |||
257 | void st_press_common_remove(struct iio_dev *indio_dev) | ||
258 | { | ||
259 | struct st_sensor_data *pdata = iio_priv(indio_dev); | ||
260 | |||
261 | iio_device_unregister(indio_dev); | ||
262 | if (pdata->get_irq_data_ready(indio_dev) > 0) { | ||
263 | st_sensors_deallocate_trigger(indio_dev); | ||
264 | st_press_deallocate_ring(indio_dev); | ||
265 | } | ||
266 | iio_device_free(indio_dev); | ||
267 | } | ||
268 | EXPORT_SYMBOL(st_press_common_remove); | ||
269 | |||
270 | MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>"); | ||
271 | MODULE_DESCRIPTION("STMicroelectronics pressures driver"); | ||
272 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/iio/pressure/st_pressure_i2c.c b/drivers/iio/pressure/st_pressure_i2c.c new file mode 100644 index 000000000000..7cebcc73bfb0 --- /dev/null +++ b/drivers/iio/pressure/st_pressure_i2c.c | |||
@@ -0,0 +1,77 @@ | |||
1 | /* | ||
2 | * STMicroelectronics pressures driver | ||
3 | * | ||
4 | * Copyright 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/i2c.h> | ||
15 | #include <linux/iio/iio.h> | ||
16 | |||
17 | #include <linux/iio/common/st_sensors.h> | ||
18 | #include <linux/iio/common/st_sensors_i2c.h> | ||
19 | #include "st_pressure.h" | ||
20 | |||
21 | static int st_press_i2c_probe(struct i2c_client *client, | ||
22 | const struct i2c_device_id *id) | ||
23 | { | ||
24 | struct iio_dev *indio_dev; | ||
25 | struct st_sensor_data *pdata; | ||
26 | int err; | ||
27 | |||
28 | indio_dev = iio_device_alloc(sizeof(*pdata)); | ||
29 | if (indio_dev == NULL) { | ||
30 | err = -ENOMEM; | ||
31 | goto iio_device_alloc_error; | ||
32 | } | ||
33 | |||
34 | pdata = iio_priv(indio_dev); | ||
35 | pdata->dev = &client->dev; | ||
36 | |||
37 | st_sensors_i2c_configure(indio_dev, client, pdata); | ||
38 | |||
39 | err = st_press_common_probe(indio_dev); | ||
40 | if (err < 0) | ||
41 | goto st_press_common_probe_error; | ||
42 | |||
43 | return 0; | ||
44 | |||
45 | st_press_common_probe_error: | ||
46 | iio_device_free(indio_dev); | ||
47 | iio_device_alloc_error: | ||
48 | return err; | ||
49 | } | ||
50 | |||
51 | static int st_press_i2c_remove(struct i2c_client *client) | ||
52 | { | ||
53 | st_press_common_remove(i2c_get_clientdata(client)); | ||
54 | |||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | static const struct i2c_device_id st_press_id_table[] = { | ||
59 | { LPS331AP_PRESS_DEV_NAME }, | ||
60 | {}, | ||
61 | }; | ||
62 | MODULE_DEVICE_TABLE(i2c, st_press_id_table); | ||
63 | |||
64 | static struct i2c_driver st_press_driver = { | ||
65 | .driver = { | ||
66 | .owner = THIS_MODULE, | ||
67 | .name = "st-press-i2c", | ||
68 | }, | ||
69 | .probe = st_press_i2c_probe, | ||
70 | .remove = st_press_i2c_remove, | ||
71 | .id_table = st_press_id_table, | ||
72 | }; | ||
73 | module_i2c_driver(st_press_driver); | ||
74 | |||
75 | MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>"); | ||
76 | MODULE_DESCRIPTION("STMicroelectronics pressures i2c driver"); | ||
77 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/iio/pressure/st_pressure_spi.c b/drivers/iio/pressure/st_pressure_spi.c new file mode 100644 index 000000000000..17a14907940a --- /dev/null +++ b/drivers/iio/pressure/st_pressure_spi.c | |||
@@ -0,0 +1,76 @@ | |||
1 | /* | ||
2 | * STMicroelectronics pressures driver | ||
3 | * | ||
4 | * Copyright 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/spi/spi.h> | ||
15 | #include <linux/iio/iio.h> | ||
16 | |||
17 | #include <linux/iio/common/st_sensors.h> | ||
18 | #include <linux/iio/common/st_sensors_spi.h> | ||
19 | #include "st_pressure.h" | ||
20 | |||
21 | static int st_press_spi_probe(struct spi_device *spi) | ||
22 | { | ||
23 | struct iio_dev *indio_dev; | ||
24 | struct st_sensor_data *pdata; | ||
25 | int err; | ||
26 | |||
27 | indio_dev = iio_device_alloc(sizeof(*pdata)); | ||
28 | if (indio_dev == NULL) { | ||
29 | err = -ENOMEM; | ||
30 | goto iio_device_alloc_error; | ||
31 | } | ||
32 | |||
33 | pdata = iio_priv(indio_dev); | ||
34 | pdata->dev = &spi->dev; | ||
35 | |||
36 | st_sensors_spi_configure(indio_dev, spi, pdata); | ||
37 | |||
38 | err = st_press_common_probe(indio_dev); | ||
39 | if (err < 0) | ||
40 | goto st_press_common_probe_error; | ||
41 | |||
42 | return 0; | ||
43 | |||
44 | st_press_common_probe_error: | ||
45 | iio_device_free(indio_dev); | ||
46 | iio_device_alloc_error: | ||
47 | return err; | ||
48 | } | ||
49 | |||
50 | static int st_press_spi_remove(struct spi_device *spi) | ||
51 | { | ||
52 | st_press_common_remove(spi_get_drvdata(spi)); | ||
53 | |||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | static const struct spi_device_id st_press_id_table[] = { | ||
58 | { LPS331AP_PRESS_DEV_NAME }, | ||
59 | {}, | ||
60 | }; | ||
61 | MODULE_DEVICE_TABLE(spi, st_press_id_table); | ||
62 | |||
63 | static struct spi_driver st_press_driver = { | ||
64 | .driver = { | ||
65 | .owner = THIS_MODULE, | ||
66 | .name = "st-press-spi", | ||
67 | }, | ||
68 | .probe = st_press_spi_probe, | ||
69 | .remove = st_press_spi_remove, | ||
70 | .id_table = st_press_id_table, | ||
71 | }; | ||
72 | module_spi_driver(st_press_driver); | ||
73 | |||
74 | MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>"); | ||
75 | MODULE_DESCRIPTION("STMicroelectronics pressures spi driver"); | ||
76 | MODULE_LICENSE("GPL v2"); | ||