diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-12-26 20:05:25 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-12-26 20:05:25 -0500 |
commit | 02c34ccc1d2d528d2de2897881b97933363432b5 (patch) | |
tree | 8d1f53965b2c828a11066759cbe2797a4c54cf4d | |
parent | 35ea984daccc60e6b9dd90074bb2f4f6b57e6309 (diff) | |
parent | e8aab48b34d3bd069dfcf4ccb8f13ba8c98f7845 (diff) |
Merge tag 'iio-for-4.5c' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next
Jonathan writes:
Third set of new stuff for IIO in the 4.5 cycle.
New driver features
- us5182
* Add interrupt support and rising / falling threshold events.
Cleanups / fixes to new stuff / minor additions
* Expose the IIO value formatting function for drivers to
make use of internally.
- ina2xx
* Fix wrong channel order
* Fix incorrect reporting of endianness
* Adding documentation of ABI unique to this device
- mma8452
* Drop an unused register description
* Use an enum for the channel index to aid readability
- sca3000
* Use standard NULL comparison style
- us5182
* fix an inconsistency in status of enable (a bug with no real effect until
above patches are applied)
* refactor the read_raw function to improve maintainability / readability.
-rw-r--r-- | Documentation/ABI/testing/sysfs-bus-iio-ina2xx-adc | 24 | ||||
-rw-r--r-- | drivers/iio/accel/mma8452.c | 40 | ||||
-rw-r--r-- | drivers/iio/adc/ina2xx-adc.c | 6 | ||||
-rw-r--r-- | drivers/iio/industrialio-core.c | 1 | ||||
-rw-r--r-- | drivers/iio/light/us5182d.c | 442 | ||||
-rw-r--r-- | drivers/staging/iio/accel/sca3000_ring.c | 2 | ||||
-rw-r--r-- | include/linux/iio/iio.h | 2 |
7 files changed, 414 insertions, 103 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-iio-ina2xx-adc b/Documentation/ABI/testing/sysfs-bus-iio-ina2xx-adc new file mode 100644 index 000000000000..8916f7ec6507 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-ina2xx-adc | |||
@@ -0,0 +1,24 @@ | |||
1 | What: /sys/bus/iio/devices/iio:deviceX/in_allow_async_readout | ||
2 | Date: December 2015 | ||
3 | KernelVersion: 4.4 | ||
4 | Contact: linux-iio@vger.kernel.org | ||
5 | Description: | ||
6 | By default (value '0'), the capture thread checks for the Conversion | ||
7 | Ready Flag to being set prior to committing a new value to the sample | ||
8 | buffer. This synchronizes the in-chip conversion rate with the | ||
9 | in-driver readout rate at the cost of an additional register read. | ||
10 | |||
11 | Writing '1' will remove the polling for the Conversion Ready Flags to | ||
12 | save the additional i2c transaction, which will improve the bandwidth | ||
13 | available for reading data. However, samples can be occasionally skipped | ||
14 | or repeated, depending on the beat between the capture and conversion | ||
15 | rates. | ||
16 | |||
17 | What: /sys/bus/iio/devices/iio:deviceX/in_shunt_resistor | ||
18 | Date: December 2015 | ||
19 | KernelVersion: 4.4 | ||
20 | Contact: linux-iio@vger.kernel.org | ||
21 | Description: | ||
22 | The value of the shunt resistor may be known only at runtime fom an | ||
23 | eeprom content read by a client application. This attribute allows to | ||
24 | set its value in ohms. | ||
diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c index 116a6e401a6a..ccc632a7cf01 100644 --- a/drivers/iio/accel/mma8452.c +++ b/drivers/iio/accel/mma8452.c | |||
@@ -58,7 +58,6 @@ | |||
58 | #define MMA8452_FF_MT_COUNT 0x18 | 58 | #define MMA8452_FF_MT_COUNT 0x18 |
59 | #define MMA8452_TRANSIENT_CFG 0x1d | 59 | #define MMA8452_TRANSIENT_CFG 0x1d |
60 | #define MMA8452_TRANSIENT_CFG_HPF_BYP BIT(0) | 60 | #define MMA8452_TRANSIENT_CFG_HPF_BYP BIT(0) |
61 | #define MMA8452_TRANSIENT_CFG_CHAN(chan) BIT(chan + 1) | ||
62 | #define MMA8452_TRANSIENT_CFG_ELE BIT(4) | 61 | #define MMA8452_TRANSIENT_CFG_ELE BIT(4) |
63 | #define MMA8452_TRANSIENT_SRC 0x1e | 62 | #define MMA8452_TRANSIENT_SRC 0x1e |
64 | #define MMA8452_TRANSIENT_SRC_XTRANSE BIT(1) | 63 | #define MMA8452_TRANSIENT_SRC_XTRANSE BIT(1) |
@@ -144,6 +143,13 @@ struct mma_chip_info { | |||
144 | u8 ev_count; | 143 | u8 ev_count; |
145 | }; | 144 | }; |
146 | 145 | ||
146 | enum { | ||
147 | idx_x, | ||
148 | idx_y, | ||
149 | idx_z, | ||
150 | idx_ts, | ||
151 | }; | ||
152 | |||
147 | static int mma8452_drdy(struct mma8452_data *data) | 153 | static int mma8452_drdy(struct mma8452_data *data) |
148 | { | 154 | { |
149 | int tries = 150; | 155 | int tries = 150; |
@@ -817,31 +823,31 @@ static struct attribute_group mma8452_event_attribute_group = { | |||
817 | } | 823 | } |
818 | 824 | ||
819 | static const struct iio_chan_spec mma8452_channels[] = { | 825 | static const struct iio_chan_spec mma8452_channels[] = { |
820 | MMA8452_CHANNEL(X, 0, 12), | 826 | MMA8452_CHANNEL(X, idx_x, 12), |
821 | MMA8452_CHANNEL(Y, 1, 12), | 827 | MMA8452_CHANNEL(Y, idx_y, 12), |
822 | MMA8452_CHANNEL(Z, 2, 12), | 828 | MMA8452_CHANNEL(Z, idx_z, 12), |
823 | IIO_CHAN_SOFT_TIMESTAMP(3), | 829 | IIO_CHAN_SOFT_TIMESTAMP(idx_ts), |
824 | }; | 830 | }; |
825 | 831 | ||
826 | static const struct iio_chan_spec mma8453_channels[] = { | 832 | static const struct iio_chan_spec mma8453_channels[] = { |
827 | MMA8452_CHANNEL(X, 0, 10), | 833 | MMA8452_CHANNEL(X, idx_x, 10), |
828 | MMA8452_CHANNEL(Y, 1, 10), | 834 | MMA8452_CHANNEL(Y, idx_y, 10), |
829 | MMA8452_CHANNEL(Z, 2, 10), | 835 | MMA8452_CHANNEL(Z, idx_z, 10), |
830 | IIO_CHAN_SOFT_TIMESTAMP(3), | 836 | IIO_CHAN_SOFT_TIMESTAMP(idx_ts), |
831 | }; | 837 | }; |
832 | 838 | ||
833 | static const struct iio_chan_spec mma8652_channels[] = { | 839 | static const struct iio_chan_spec mma8652_channels[] = { |
834 | MMA8652_CHANNEL(X, 0, 12), | 840 | MMA8652_CHANNEL(X, idx_x, 12), |
835 | MMA8652_CHANNEL(Y, 1, 12), | 841 | MMA8652_CHANNEL(Y, idx_y, 12), |
836 | MMA8652_CHANNEL(Z, 2, 12), | 842 | MMA8652_CHANNEL(Z, idx_z, 12), |
837 | IIO_CHAN_SOFT_TIMESTAMP(3), | 843 | IIO_CHAN_SOFT_TIMESTAMP(idx_ts), |
838 | }; | 844 | }; |
839 | 845 | ||
840 | static const struct iio_chan_spec mma8653_channels[] = { | 846 | static const struct iio_chan_spec mma8653_channels[] = { |
841 | MMA8652_CHANNEL(X, 0, 10), | 847 | MMA8652_CHANNEL(X, idx_x, 10), |
842 | MMA8652_CHANNEL(Y, 1, 10), | 848 | MMA8652_CHANNEL(Y, idx_y, 10), |
843 | MMA8652_CHANNEL(Z, 2, 10), | 849 | MMA8652_CHANNEL(Z, idx_z, 10), |
844 | IIO_CHAN_SOFT_TIMESTAMP(3), | 850 | IIO_CHAN_SOFT_TIMESTAMP(idx_ts), |
845 | }; | 851 | }; |
846 | 852 | ||
847 | enum { | 853 | enum { |
diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c index 4c18c4cc8939..d803e5018a42 100644 --- a/drivers/iio/adc/ina2xx-adc.c +++ b/drivers/iio/adc/ina2xx-adc.c | |||
@@ -400,7 +400,7 @@ static ssize_t ina2xx_shunt_resistor_store(struct device *dev, | |||
400 | .sign = 'u', \ | 400 | .sign = 'u', \ |
401 | .realbits = 16, \ | 401 | .realbits = 16, \ |
402 | .storagebits = 16, \ | 402 | .storagebits = 16, \ |
403 | .endianness = IIO_LE, \ | 403 | .endianness = IIO_CPU, \ |
404 | } \ | 404 | } \ |
405 | } | 405 | } |
406 | 406 | ||
@@ -428,8 +428,8 @@ static ssize_t ina2xx_shunt_resistor_store(struct device *dev, | |||
428 | static const struct iio_chan_spec ina2xx_channels[] = { | 428 | static const struct iio_chan_spec ina2xx_channels[] = { |
429 | INA2XX_CHAN_VOLTAGE(0, INA2XX_SHUNT_VOLTAGE), | 429 | INA2XX_CHAN_VOLTAGE(0, INA2XX_SHUNT_VOLTAGE), |
430 | INA2XX_CHAN_VOLTAGE(1, INA2XX_BUS_VOLTAGE), | 430 | INA2XX_CHAN_VOLTAGE(1, INA2XX_BUS_VOLTAGE), |
431 | INA2XX_CHAN(IIO_CURRENT, 2, INA2XX_CURRENT), | 431 | INA2XX_CHAN(IIO_POWER, 2, INA2XX_POWER), |
432 | INA2XX_CHAN(IIO_POWER, 3, INA2XX_POWER), | 432 | INA2XX_CHAN(IIO_CURRENT, 3, INA2XX_CURRENT), |
433 | IIO_CHAN_SOFT_TIMESTAMP(4), | 433 | IIO_CHAN_SOFT_TIMESTAMP(4), |
434 | }; | 434 | }; |
435 | 435 | ||
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 8966f85ca4cd..fd01f3493fc7 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c | |||
@@ -470,6 +470,7 @@ ssize_t iio_format_value(char *buf, unsigned int type, int size, int *vals) | |||
470 | return 0; | 470 | return 0; |
471 | } | 471 | } |
472 | } | 472 | } |
473 | EXPORT_SYMBOL_GPL(iio_format_value); | ||
473 | 474 | ||
474 | static ssize_t iio_read_channel_info(struct device *dev, | 475 | static ssize_t iio_read_channel_info(struct device *dev, |
475 | struct device_attribute *attr, | 476 | struct device_attribute *attr, |
diff --git a/drivers/iio/light/us5182d.c b/drivers/iio/light/us5182d.c index 256c4bc12d21..45bc2f742f46 100644 --- a/drivers/iio/light/us5182d.c +++ b/drivers/iio/light/us5182d.c | |||
@@ -20,7 +20,10 @@ | |||
20 | #include <linux/acpi.h> | 20 | #include <linux/acpi.h> |
21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
22 | #include <linux/i2c.h> | 22 | #include <linux/i2c.h> |
23 | #include <linux/iio/events.h> | ||
23 | #include <linux/iio/iio.h> | 24 | #include <linux/iio/iio.h> |
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/irq.h> | ||
24 | #include <linux/iio/sysfs.h> | 27 | #include <linux/iio/sysfs.h> |
25 | #include <linux/mutex.h> | 28 | #include <linux/mutex.h> |
26 | #include <linux/pm.h> | 29 | #include <linux/pm.h> |
@@ -30,6 +33,8 @@ | |||
30 | #define US5182D_CFG0_ONESHOT_EN BIT(6) | 33 | #define US5182D_CFG0_ONESHOT_EN BIT(6) |
31 | #define US5182D_CFG0_SHUTDOWN_EN BIT(7) | 34 | #define US5182D_CFG0_SHUTDOWN_EN BIT(7) |
32 | #define US5182D_CFG0_WORD_ENABLE BIT(0) | 35 | #define US5182D_CFG0_WORD_ENABLE BIT(0) |
36 | #define US5182D_CFG0_PROX BIT(3) | ||
37 | #define US5182D_CFG0_PX_IRQ BIT(2) | ||
33 | 38 | ||
34 | #define US5182D_REG_CFG1 0x01 | 39 | #define US5182D_REG_CFG1 0x01 |
35 | #define US5182D_CFG1_ALS_RES16 BIT(4) | 40 | #define US5182D_CFG1_ALS_RES16 BIT(4) |
@@ -41,6 +46,7 @@ | |||
41 | 46 | ||
42 | #define US5182D_REG_CFG3 0x03 | 47 | #define US5182D_REG_CFG3 0x03 |
43 | #define US5182D_CFG3_LED_CURRENT100 (BIT(4) | BIT(5)) | 48 | #define US5182D_CFG3_LED_CURRENT100 (BIT(4) | BIT(5)) |
49 | #define US5182D_CFG3_INT_SOURCE_PX BIT(3) | ||
44 | 50 | ||
45 | #define US5182D_REG_CFG4 0x10 | 51 | #define US5182D_REG_CFG4 0x10 |
46 | 52 | ||
@@ -55,6 +61,13 @@ | |||
55 | #define US5182D_REG_AUTO_LDARK_GAIN 0x29 | 61 | #define US5182D_REG_AUTO_LDARK_GAIN 0x29 |
56 | #define US5182D_REG_AUTO_HDARK_GAIN 0x2a | 62 | #define US5182D_REG_AUTO_HDARK_GAIN 0x2a |
57 | 63 | ||
64 | /* Thresholds for events: px low (0x08-l, 0x09-h), px high (0x0a-l 0x0b-h) */ | ||
65 | #define US5182D_REG_PXL_TH 0x08 | ||
66 | #define US5182D_REG_PXH_TH 0x0a | ||
67 | |||
68 | #define US5182D_REG_PXL_TH_DEFAULT 1000 | ||
69 | #define US5182D_REG_PXH_TH_DEFAULT 30000 | ||
70 | |||
58 | #define US5182D_OPMODE_ALS 0x01 | 71 | #define US5182D_OPMODE_ALS 0x01 |
59 | #define US5182D_OPMODE_PX 0x02 | 72 | #define US5182D_OPMODE_PX 0x02 |
60 | #define US5182D_OPMODE_SHIFT 4 | 73 | #define US5182D_OPMODE_SHIFT 4 |
@@ -84,6 +97,8 @@ | |||
84 | #define US5182D_READ_WORD 2 | 97 | #define US5182D_READ_WORD 2 |
85 | #define US5182D_OPSTORE_SLEEP_TIME 20 /* ms */ | 98 | #define US5182D_OPSTORE_SLEEP_TIME 20 /* ms */ |
86 | #define US5182D_SLEEP_MS 3000 /* ms */ | 99 | #define US5182D_SLEEP_MS 3000 /* ms */ |
100 | #define US5182D_PXH_TH_DISABLE 0xffff | ||
101 | #define US5182D_PXL_TH_DISABLE 0x0000 | ||
87 | 102 | ||
88 | /* Available ranges: [12354, 7065, 3998, 2202, 1285, 498, 256, 138] lux */ | 103 | /* Available ranges: [12354, 7065, 3998, 2202, 1285, 498, 256, 138] lux */ |
89 | static const int us5182d_scales[] = {188500, 107800, 61000, 33600, 19600, 7600, | 104 | static const int us5182d_scales[] = {188500, 107800, 61000, 33600, 19600, 7600, |
@@ -119,6 +134,12 @@ struct us5182d_data { | |||
119 | u8 upper_dark_gain; | 134 | u8 upper_dark_gain; |
120 | u16 *us5182d_dark_ths; | 135 | u16 *us5182d_dark_ths; |
121 | 136 | ||
137 | u16 px_low_th; | ||
138 | u16 px_high_th; | ||
139 | |||
140 | int rising_en; | ||
141 | int falling_en; | ||
142 | |||
122 | u8 opmode; | 143 | u8 opmode; |
123 | u8 power_mode; | 144 | u8 power_mode; |
124 | 145 | ||
@@ -148,10 +169,26 @@ static const struct { | |||
148 | {US5182D_REG_CFG1, US5182D_CFG1_ALS_RES16}, | 169 | {US5182D_REG_CFG1, US5182D_CFG1_ALS_RES16}, |
149 | {US5182D_REG_CFG2, (US5182D_CFG2_PX_RES16 | | 170 | {US5182D_REG_CFG2, (US5182D_CFG2_PX_RES16 | |
150 | US5182D_CFG2_PXGAIN_DEFAULT)}, | 171 | US5182D_CFG2_PXGAIN_DEFAULT)}, |
151 | {US5182D_REG_CFG3, US5182D_CFG3_LED_CURRENT100}, | 172 | {US5182D_REG_CFG3, US5182D_CFG3_LED_CURRENT100 | |
173 | US5182D_CFG3_INT_SOURCE_PX}, | ||
152 | {US5182D_REG_CFG4, 0x00}, | 174 | {US5182D_REG_CFG4, 0x00}, |
153 | }; | 175 | }; |
154 | 176 | ||
177 | static const struct iio_event_spec us5182d_events[] = { | ||
178 | { | ||
179 | .type = IIO_EV_TYPE_THRESH, | ||
180 | .dir = IIO_EV_DIR_RISING, | ||
181 | .mask_separate = BIT(IIO_EV_INFO_VALUE) | | ||
182 | BIT(IIO_EV_INFO_ENABLE), | ||
183 | }, | ||
184 | { | ||
185 | .type = IIO_EV_TYPE_THRESH, | ||
186 | .dir = IIO_EV_DIR_FALLING, | ||
187 | .mask_separate = BIT(IIO_EV_INFO_VALUE) | | ||
188 | BIT(IIO_EV_INFO_ENABLE), | ||
189 | }, | ||
190 | }; | ||
191 | |||
155 | static const struct iio_chan_spec us5182d_channels[] = { | 192 | static const struct iio_chan_spec us5182d_channels[] = { |
156 | { | 193 | { |
157 | .type = IIO_LIGHT, | 194 | .type = IIO_LIGHT, |
@@ -161,26 +198,11 @@ static const struct iio_chan_spec us5182d_channels[] = { | |||
161 | { | 198 | { |
162 | .type = IIO_PROXIMITY, | 199 | .type = IIO_PROXIMITY, |
163 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), | 200 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), |
201 | .event_spec = us5182d_events, | ||
202 | .num_event_specs = ARRAY_SIZE(us5182d_events), | ||
164 | } | 203 | } |
165 | }; | 204 | }; |
166 | 205 | ||
167 | static int us5182d_get_als(struct us5182d_data *data) | ||
168 | { | ||
169 | int ret; | ||
170 | unsigned long result; | ||
171 | |||
172 | ret = i2c_smbus_read_word_data(data->client, | ||
173 | US5182D_REG_ADL); | ||
174 | if (ret < 0) | ||
175 | return ret; | ||
176 | |||
177 | result = ret * data->ga / US5182D_GA_RESOLUTION; | ||
178 | if (result > 0xffff) | ||
179 | result = 0xffff; | ||
180 | |||
181 | return result; | ||
182 | } | ||
183 | |||
184 | static int us5182d_oneshot_en(struct us5182d_data *data) | 206 | static int us5182d_oneshot_en(struct us5182d_data *data) |
185 | { | 207 | { |
186 | int ret; | 208 | int ret; |
@@ -238,8 +260,12 @@ static int us5182d_als_enable(struct us5182d_data *data) | |||
238 | int ret; | 260 | int ret; |
239 | u8 mode; | 261 | u8 mode; |
240 | 262 | ||
241 | if (data->power_mode == US5182D_ONESHOT) | 263 | if (data->power_mode == US5182D_ONESHOT) { |
242 | return us5182d_set_opmode(data, US5182D_ALS_ONLY); | 264 | ret = us5182d_set_opmode(data, US5182D_ALS_ONLY); |
265 | if (ret < 0) | ||
266 | return ret; | ||
267 | data->px_enabled = false; | ||
268 | } | ||
243 | 269 | ||
244 | if (data->als_enabled) | 270 | if (data->als_enabled) |
245 | return 0; | 271 | return 0; |
@@ -260,8 +286,12 @@ static int us5182d_px_enable(struct us5182d_data *data) | |||
260 | int ret; | 286 | int ret; |
261 | u8 mode; | 287 | u8 mode; |
262 | 288 | ||
263 | if (data->power_mode == US5182D_ONESHOT) | 289 | if (data->power_mode == US5182D_ONESHOT) { |
264 | return us5182d_set_opmode(data, US5182D_PX_ONLY); | 290 | ret = us5182d_set_opmode(data, US5182D_PX_ONLY); |
291 | if (ret < 0) | ||
292 | return ret; | ||
293 | data->als_enabled = false; | ||
294 | } | ||
265 | 295 | ||
266 | if (data->px_enabled) | 296 | if (data->px_enabled) |
267 | return 0; | 297 | return 0; |
@@ -277,6 +307,39 @@ static int us5182d_px_enable(struct us5182d_data *data) | |||
277 | return 0; | 307 | return 0; |
278 | } | 308 | } |
279 | 309 | ||
310 | static int us5182d_get_als(struct us5182d_data *data) | ||
311 | { | ||
312 | int ret; | ||
313 | unsigned long result; | ||
314 | |||
315 | ret = us5182d_als_enable(data); | ||
316 | if (ret < 0) | ||
317 | return ret; | ||
318 | |||
319 | ret = i2c_smbus_read_word_data(data->client, | ||
320 | US5182D_REG_ADL); | ||
321 | if (ret < 0) | ||
322 | return ret; | ||
323 | |||
324 | result = ret * data->ga / US5182D_GA_RESOLUTION; | ||
325 | if (result > 0xffff) | ||
326 | result = 0xffff; | ||
327 | |||
328 | return result; | ||
329 | } | ||
330 | |||
331 | static int us5182d_get_px(struct us5182d_data *data) | ||
332 | { | ||
333 | int ret; | ||
334 | |||
335 | ret = us5182d_px_enable(data); | ||
336 | if (ret < 0) | ||
337 | return ret; | ||
338 | |||
339 | return i2c_smbus_read_word_data(data->client, | ||
340 | US5182D_REG_PDL); | ||
341 | } | ||
342 | |||
280 | static int us5182d_shutdown_en(struct us5182d_data *data, u8 state) | 343 | static int us5182d_shutdown_en(struct us5182d_data *data, u8 state) |
281 | { | 344 | { |
282 | int ret; | 345 | int ret; |
@@ -323,6 +386,46 @@ static int us5182d_set_power_state(struct us5182d_data *data, bool on) | |||
323 | return ret; | 386 | return ret; |
324 | } | 387 | } |
325 | 388 | ||
389 | static int us5182d_read_value(struct us5182d_data *data, | ||
390 | struct iio_chan_spec const *chan) | ||
391 | { | ||
392 | int ret, value; | ||
393 | |||
394 | mutex_lock(&data->lock); | ||
395 | |||
396 | if (data->power_mode == US5182D_ONESHOT) { | ||
397 | ret = us5182d_oneshot_en(data); | ||
398 | if (ret < 0) | ||
399 | goto out_err; | ||
400 | } | ||
401 | |||
402 | ret = us5182d_set_power_state(data, true); | ||
403 | if (ret < 0) | ||
404 | goto out_err; | ||
405 | |||
406 | if (chan->type == IIO_LIGHT) | ||
407 | ret = us5182d_get_als(data); | ||
408 | else | ||
409 | ret = us5182d_get_px(data); | ||
410 | if (ret < 0) | ||
411 | goto out_poweroff; | ||
412 | |||
413 | value = ret; | ||
414 | |||
415 | ret = us5182d_set_power_state(data, false); | ||
416 | if (ret < 0) | ||
417 | goto out_err; | ||
418 | |||
419 | mutex_unlock(&data->lock); | ||
420 | return value; | ||
421 | |||
422 | out_poweroff: | ||
423 | us5182d_set_power_state(data, false); | ||
424 | out_err: | ||
425 | mutex_unlock(&data->lock); | ||
426 | return ret; | ||
427 | } | ||
428 | |||
326 | static int us5182d_read_raw(struct iio_dev *indio_dev, | 429 | static int us5182d_read_raw(struct iio_dev *indio_dev, |
327 | struct iio_chan_spec const *chan, int *val, | 430 | struct iio_chan_spec const *chan, int *val, |
328 | int *val2, long mask) | 431 | int *val2, long mask) |
@@ -332,76 +435,21 @@ static int us5182d_read_raw(struct iio_dev *indio_dev, | |||
332 | 435 | ||
333 | switch (mask) { | 436 | switch (mask) { |
334 | case IIO_CHAN_INFO_RAW: | 437 | case IIO_CHAN_INFO_RAW: |
335 | switch (chan->type) { | 438 | ret = us5182d_read_value(data, chan); |
336 | case IIO_LIGHT: | 439 | if (ret < 0) |
337 | mutex_lock(&data->lock); | 440 | return ret; |
338 | if (data->power_mode == US5182D_ONESHOT) { | 441 | *val = ret; |
339 | ret = us5182d_oneshot_en(data); | 442 | return IIO_VAL_INT; |
340 | if (ret < 0) | ||
341 | goto out_err; | ||
342 | } | ||
343 | ret = us5182d_set_power_state(data, true); | ||
344 | if (ret < 0) | ||
345 | goto out_err; | ||
346 | ret = us5182d_als_enable(data); | ||
347 | if (ret < 0) | ||
348 | goto out_poweroff; | ||
349 | ret = us5182d_get_als(data); | ||
350 | if (ret < 0) | ||
351 | goto out_poweroff; | ||
352 | *val = ret; | ||
353 | ret = us5182d_set_power_state(data, false); | ||
354 | if (ret < 0) | ||
355 | goto out_err; | ||
356 | mutex_unlock(&data->lock); | ||
357 | return IIO_VAL_INT; | ||
358 | case IIO_PROXIMITY: | ||
359 | mutex_lock(&data->lock); | ||
360 | if (data->power_mode == US5182D_ONESHOT) { | ||
361 | ret = us5182d_oneshot_en(data); | ||
362 | if (ret < 0) | ||
363 | goto out_err; | ||
364 | } | ||
365 | ret = us5182d_set_power_state(data, true); | ||
366 | if (ret < 0) | ||
367 | goto out_err; | ||
368 | ret = us5182d_px_enable(data); | ||
369 | if (ret < 0) | ||
370 | goto out_poweroff; | ||
371 | ret = i2c_smbus_read_word_data(data->client, | ||
372 | US5182D_REG_PDL); | ||
373 | if (ret < 0) | ||
374 | goto out_poweroff; | ||
375 | *val = ret; | ||
376 | ret = us5182d_set_power_state(data, false); | ||
377 | if (ret < 0) | ||
378 | goto out_err; | ||
379 | mutex_unlock(&data->lock); | ||
380 | return IIO_VAL_INT; | ||
381 | default: | ||
382 | return -EINVAL; | ||
383 | } | ||
384 | |||
385 | case IIO_CHAN_INFO_SCALE: | 443 | case IIO_CHAN_INFO_SCALE: |
386 | ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG1); | 444 | ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG1); |
387 | if (ret < 0) | 445 | if (ret < 0) |
388 | return ret; | 446 | return ret; |
389 | |||
390 | *val = 0; | 447 | *val = 0; |
391 | *val2 = us5182d_scales[ret & US5182D_AGAIN_MASK]; | 448 | *val2 = us5182d_scales[ret & US5182D_AGAIN_MASK]; |
392 | |||
393 | return IIO_VAL_INT_PLUS_MICRO; | 449 | return IIO_VAL_INT_PLUS_MICRO; |
394 | default: | 450 | default: |
395 | return -EINVAL; | 451 | return -EINVAL; |
396 | } | 452 | } |
397 | |||
398 | return -EINVAL; | ||
399 | |||
400 | out_poweroff: | ||
401 | us5182d_set_power_state(data, false); | ||
402 | out_err: | ||
403 | mutex_unlock(&data->lock); | ||
404 | return ret; | ||
405 | } | 453 | } |
406 | 454 | ||
407 | /** | 455 | /** |
@@ -479,11 +527,201 @@ static int us5182d_write_raw(struct iio_dev *indio_dev, | |||
479 | return -EINVAL; | 527 | return -EINVAL; |
480 | } | 528 | } |
481 | 529 | ||
530 | static int us5182d_setup_prox(struct iio_dev *indio_dev, | ||
531 | enum iio_event_direction dir, u16 val) | ||
532 | { | ||
533 | struct us5182d_data *data = iio_priv(indio_dev); | ||
534 | |||
535 | if (dir == IIO_EV_DIR_FALLING) | ||
536 | return i2c_smbus_write_word_data(data->client, | ||
537 | US5182D_REG_PXL_TH, val); | ||
538 | else if (dir == IIO_EV_DIR_RISING) | ||
539 | return i2c_smbus_write_word_data(data->client, | ||
540 | US5182D_REG_PXH_TH, val); | ||
541 | |||
542 | return 0; | ||
543 | } | ||
544 | |||
545 | static int us5182d_read_thresh(struct iio_dev *indio_dev, | ||
546 | const struct iio_chan_spec *chan, enum iio_event_type type, | ||
547 | enum iio_event_direction dir, enum iio_event_info info, int *val, | ||
548 | int *val2) | ||
549 | { | ||
550 | struct us5182d_data *data = iio_priv(indio_dev); | ||
551 | |||
552 | switch (dir) { | ||
553 | case IIO_EV_DIR_RISING: | ||
554 | mutex_lock(&data->lock); | ||
555 | *val = data->px_high_th; | ||
556 | mutex_unlock(&data->lock); | ||
557 | break; | ||
558 | case IIO_EV_DIR_FALLING: | ||
559 | mutex_lock(&data->lock); | ||
560 | *val = data->px_low_th; | ||
561 | mutex_unlock(&data->lock); | ||
562 | break; | ||
563 | default: | ||
564 | return -EINVAL; | ||
565 | } | ||
566 | |||
567 | return IIO_VAL_INT; | ||
568 | } | ||
569 | |||
570 | static int us5182d_write_thresh(struct iio_dev *indio_dev, | ||
571 | const struct iio_chan_spec *chan, enum iio_event_type type, | ||
572 | enum iio_event_direction dir, enum iio_event_info info, int val, | ||
573 | int val2) | ||
574 | { | ||
575 | struct us5182d_data *data = iio_priv(indio_dev); | ||
576 | int ret; | ||
577 | |||
578 | if (val < 0 || val > USHRT_MAX || val2 != 0) | ||
579 | return -EINVAL; | ||
580 | |||
581 | switch (dir) { | ||
582 | case IIO_EV_DIR_RISING: | ||
583 | mutex_lock(&data->lock); | ||
584 | if (data->rising_en) { | ||
585 | ret = us5182d_setup_prox(indio_dev, dir, val); | ||
586 | if (ret < 0) | ||
587 | goto err; | ||
588 | } | ||
589 | data->px_high_th = val; | ||
590 | mutex_unlock(&data->lock); | ||
591 | break; | ||
592 | case IIO_EV_DIR_FALLING: | ||
593 | mutex_lock(&data->lock); | ||
594 | if (data->falling_en) { | ||
595 | ret = us5182d_setup_prox(indio_dev, dir, val); | ||
596 | if (ret < 0) | ||
597 | goto err; | ||
598 | } | ||
599 | data->px_low_th = val; | ||
600 | mutex_unlock(&data->lock); | ||
601 | break; | ||
602 | default: | ||
603 | return -EINVAL; | ||
604 | } | ||
605 | |||
606 | return 0; | ||
607 | err: | ||
608 | mutex_unlock(&data->lock); | ||
609 | return ret; | ||
610 | } | ||
611 | |||
612 | static int us5182d_read_event_config(struct iio_dev *indio_dev, | ||
613 | const struct iio_chan_spec *chan, enum iio_event_type type, | ||
614 | enum iio_event_direction dir) | ||
615 | { | ||
616 | struct us5182d_data *data = iio_priv(indio_dev); | ||
617 | int ret; | ||
618 | |||
619 | switch (dir) { | ||
620 | case IIO_EV_DIR_RISING: | ||
621 | mutex_lock(&data->lock); | ||
622 | ret = data->rising_en; | ||
623 | mutex_unlock(&data->lock); | ||
624 | break; | ||
625 | case IIO_EV_DIR_FALLING: | ||
626 | mutex_lock(&data->lock); | ||
627 | ret = data->falling_en; | ||
628 | mutex_unlock(&data->lock); | ||
629 | break; | ||
630 | default: | ||
631 | ret = -EINVAL; | ||
632 | break; | ||
633 | } | ||
634 | |||
635 | return ret; | ||
636 | } | ||
637 | |||
638 | static int us5182d_write_event_config(struct iio_dev *indio_dev, | ||
639 | const struct iio_chan_spec *chan, enum iio_event_type type, | ||
640 | enum iio_event_direction dir, int state) | ||
641 | { | ||
642 | struct us5182d_data *data = iio_priv(indio_dev); | ||
643 | int ret; | ||
644 | u16 new_th; | ||
645 | |||
646 | mutex_lock(&data->lock); | ||
647 | |||
648 | switch (dir) { | ||
649 | case IIO_EV_DIR_RISING: | ||
650 | if (data->rising_en == state) { | ||
651 | mutex_unlock(&data->lock); | ||
652 | return 0; | ||
653 | } | ||
654 | new_th = US5182D_PXH_TH_DISABLE; | ||
655 | if (state) { | ||
656 | data->power_mode = US5182D_CONTINUOUS; | ||
657 | ret = us5182d_set_power_state(data, true); | ||
658 | if (ret < 0) | ||
659 | goto err; | ||
660 | ret = us5182d_px_enable(data); | ||
661 | if (ret < 0) | ||
662 | goto err_poweroff; | ||
663 | new_th = data->px_high_th; | ||
664 | } | ||
665 | ret = us5182d_setup_prox(indio_dev, dir, new_th); | ||
666 | if (ret < 0) | ||
667 | goto err_poweroff; | ||
668 | data->rising_en = state; | ||
669 | break; | ||
670 | case IIO_EV_DIR_FALLING: | ||
671 | if (data->falling_en == state) { | ||
672 | mutex_unlock(&data->lock); | ||
673 | return 0; | ||
674 | } | ||
675 | new_th = US5182D_PXL_TH_DISABLE; | ||
676 | if (state) { | ||
677 | data->power_mode = US5182D_CONTINUOUS; | ||
678 | ret = us5182d_set_power_state(data, true); | ||
679 | if (ret < 0) | ||
680 | goto err; | ||
681 | ret = us5182d_px_enable(data); | ||
682 | if (ret < 0) | ||
683 | goto err_poweroff; | ||
684 | new_th = data->px_low_th; | ||
685 | } | ||
686 | ret = us5182d_setup_prox(indio_dev, dir, new_th); | ||
687 | if (ret < 0) | ||
688 | goto err_poweroff; | ||
689 | data->falling_en = state; | ||
690 | break; | ||
691 | default: | ||
692 | ret = -EINVAL; | ||
693 | goto err; | ||
694 | } | ||
695 | |||
696 | if (!state) { | ||
697 | ret = us5182d_set_power_state(data, false); | ||
698 | if (ret < 0) | ||
699 | goto err; | ||
700 | } | ||
701 | |||
702 | if (!data->falling_en && !data->rising_en && !data->default_continuous) | ||
703 | data->power_mode = US5182D_ONESHOT; | ||
704 | |||
705 | mutex_unlock(&data->lock); | ||
706 | return 0; | ||
707 | |||
708 | err_poweroff: | ||
709 | if (state) | ||
710 | us5182d_set_power_state(data, false); | ||
711 | err: | ||
712 | mutex_unlock(&data->lock); | ||
713 | return ret; | ||
714 | } | ||
715 | |||
482 | static const struct iio_info us5182d_info = { | 716 | static const struct iio_info us5182d_info = { |
483 | .driver_module = THIS_MODULE, | 717 | .driver_module = THIS_MODULE, |
484 | .read_raw = us5182d_read_raw, | 718 | .read_raw = us5182d_read_raw, |
485 | .write_raw = us5182d_write_raw, | 719 | .write_raw = us5182d_write_raw, |
486 | .attrs = &us5182d_attr_group, | 720 | .attrs = &us5182d_attr_group, |
721 | .read_event_value = &us5182d_read_thresh, | ||
722 | .write_event_value = &us5182d_write_thresh, | ||
723 | .read_event_config = &us5182d_read_event_config, | ||
724 | .write_event_config = &us5182d_write_event_config, | ||
487 | }; | 725 | }; |
488 | 726 | ||
489 | static int us5182d_reset(struct iio_dev *indio_dev) | 727 | static int us5182d_reset(struct iio_dev *indio_dev) |
@@ -505,6 +743,9 @@ static int us5182d_init(struct iio_dev *indio_dev) | |||
505 | 743 | ||
506 | data->opmode = 0; | 744 | data->opmode = 0; |
507 | data->power_mode = US5182D_CONTINUOUS; | 745 | data->power_mode = US5182D_CONTINUOUS; |
746 | data->px_low_th = US5182D_REG_PXL_TH_DEFAULT; | ||
747 | data->px_high_th = US5182D_REG_PXH_TH_DEFAULT; | ||
748 | |||
508 | for (i = 0; i < ARRAY_SIZE(us5182d_regvals); i++) { | 749 | for (i = 0; i < ARRAY_SIZE(us5182d_regvals); i++) { |
509 | ret = i2c_smbus_write_byte_data(data->client, | 750 | ret = i2c_smbus_write_byte_data(data->client, |
510 | us5182d_regvals[i].reg, | 751 | us5182d_regvals[i].reg, |
@@ -575,6 +816,33 @@ static int us5182d_dark_gain_config(struct iio_dev *indio_dev) | |||
575 | US5182D_REG_DARK_AUTO_EN_DEFAULT); | 816 | US5182D_REG_DARK_AUTO_EN_DEFAULT); |
576 | } | 817 | } |
577 | 818 | ||
819 | static irqreturn_t us5182d_irq_thread_handler(int irq, void *private) | ||
820 | { | ||
821 | struct iio_dev *indio_dev = private; | ||
822 | struct us5182d_data *data = iio_priv(indio_dev); | ||
823 | enum iio_event_direction dir; | ||
824 | int ret; | ||
825 | u64 ev; | ||
826 | |||
827 | ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG0); | ||
828 | if (ret < 0) { | ||
829 | dev_err(&data->client->dev, "i2c transfer error in irq\n"); | ||
830 | return IRQ_HANDLED; | ||
831 | } | ||
832 | |||
833 | dir = ret & US5182D_CFG0_PROX ? IIO_EV_DIR_RISING : IIO_EV_DIR_FALLING; | ||
834 | ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 1, IIO_EV_TYPE_THRESH, dir); | ||
835 | |||
836 | iio_push_event(indio_dev, ev, iio_get_time_ns()); | ||
837 | |||
838 | ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG0, | ||
839 | ret & ~US5182D_CFG0_PX_IRQ); | ||
840 | if (ret < 0) | ||
841 | dev_err(&data->client->dev, "i2c transfer error in irq\n"); | ||
842 | |||
843 | return IRQ_HANDLED; | ||
844 | } | ||
845 | |||
578 | static int us5182d_probe(struct i2c_client *client, | 846 | static int us5182d_probe(struct i2c_client *client, |
579 | const struct i2c_device_id *id) | 847 | const struct i2c_device_id *id) |
580 | { | 848 | { |
@@ -606,6 +874,16 @@ static int us5182d_probe(struct i2c_client *client, | |||
606 | return (ret < 0) ? ret : -ENODEV; | 874 | return (ret < 0) ? ret : -ENODEV; |
607 | } | 875 | } |
608 | 876 | ||
877 | if (client->irq > 0) { | ||
878 | ret = devm_request_threaded_irq(&client->dev, client->irq, NULL, | ||
879 | us5182d_irq_thread_handler, | ||
880 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | ||
881 | "us5182d-irq", indio_dev); | ||
882 | if (ret < 0) | ||
883 | return ret; | ||
884 | } else | ||
885 | dev_warn(&client->dev, "no valid irq found\n"); | ||
886 | |||
609 | us5182d_get_platform_data(indio_dev); | 887 | us5182d_get_platform_data(indio_dev); |
610 | ret = us5182d_init(indio_dev); | 888 | ret = us5182d_init(indio_dev); |
611 | if (ret < 0) | 889 | if (ret < 0) |
diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c index 20b878d35ea2..1920dc60cf3d 100644 --- a/drivers/staging/iio/accel/sca3000_ring.c +++ b/drivers/staging/iio/accel/sca3000_ring.c | |||
@@ -48,7 +48,7 @@ static int sca3000_read_data(struct sca3000_state *st, | |||
48 | } | 48 | } |
49 | }; | 49 | }; |
50 | *rx_p = kmalloc(len, GFP_KERNEL); | 50 | *rx_p = kmalloc(len, GFP_KERNEL); |
51 | if (*rx_p == NULL) { | 51 | if (!*rx_p) { |
52 | ret = -ENOMEM; | 52 | ret = -ENOMEM; |
53 | goto error_ret; | 53 | goto error_ret; |
54 | } | 54 | } |
diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 19c94c9acc81..b5894118755f 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h | |||
@@ -636,6 +636,8 @@ static inline struct dentry *iio_get_debugfs_dentry(struct iio_dev *indio_dev) | |||
636 | } | 636 | } |
637 | #endif | 637 | #endif |
638 | 638 | ||
639 | ssize_t iio_format_value(char *buf, unsigned int type, int size, int *vals); | ||
640 | |||
639 | int iio_str_to_fixpoint(const char *str, int fract_mult, int *integer, | 641 | int iio_str_to_fixpoint(const char *str, int fract_mult, int *integer, |
640 | int *fract); | 642 | int *fract); |
641 | 643 | ||