diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-03-24 17:53:52 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-03-24 17:53:52 -0400 |
commit | dc5f2c5f6aa159ebf4b29b169aa1f71cf98d3d6a (patch) | |
tree | f9fd13fd4025e8844adbe27383cfcd1ad9c5106f | |
parent | c754ff966d54b3a6cb45cd57524186a16e7f5831 (diff) | |
parent | c0644160a8b5e56b3c3896d77ac3d50d41fa9336 (diff) |
Merge tag 'iio-for-4.1a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next
Jonathan writes:
First set of new drivers, cleanups and functionality for IIO in the 4.1 cycle.
New drivers
* CM3323 color sensor.
* MS5611 pressure and temperature sensor.
New functionality
* mup6050 - create mux clients for devices described via ACPI. The reasoning
and approach taken in this patch are complex. Basically there is no
otherway of finding out what is there than by some esoteric look ups in
the ACPI data.
* cm3232 - PM support
* itg3200 - suspend/resume support
* mcp320x - add more ADCs to the kconfig to reflect what the driver supports
(this patch and the bindings got left behind when the support was added
a while back).
Docs / utils
* ti-adc128s052 - DT bindings.
* mcp3422 - DT bindings.
* mcp320x - DT bindings
* ABI docs for event threshold scale attributes, in_magn_offset, proximity
scan_element and thresh falling/rising values for accelerometers. All
elements long in use that have slipped by being explicitly documented.
* Tidy up the tools previously in drivers/staging/iio/Documentation and move
them out to /tools/iio. Yet another move that should have happened long ago.
This time Roberta Dobrescu did the leg work. Thanks!
Core Cleanups
* Export userspace IIO headers. We should have done the appropriate header
splitting a long time ago. Thanks to Daniel for sorting this out.
* Refactor the registring of attributes for buffers to move all non-custom
ones to a vector allowing easier additions to the current set in the future.
Driver Cleanups
* gpiod related cleanups. Make use of the additional parameter to specify
initial direciton to avoid extra code.
* bmc150 - Various refactorings to reduce code repitition and prepare for
hardware buffer support. Some of these cleanups are good even
without the new functionality.
* kmx61 - direct use of index to an array avoiding a structure element which
was always the index to an element in an array of that structure.
* vf610 - avoid incorrect type for return from wait_for_completion_timeout.
* gp2ap020a00f - use put_unaligned_le32 for slight code simplification.
* ade7754 - improve error handling including suppressing some build warnings.
* ade7759 - improve error handling including suppressing some build warnings.
* hmc5843 - Long line and indentation fixes. Also some constifying of various
constant data.
* ade7854 - 80+ character line splitting.
* ad2s1210 - fix wrong printf format string.
* mxs-lradc - fix wrong printf format string.
* ade7954-i2c - code alignment fixes and other trivial but worthwhile bits.
* periodic rtc trigger - make the frequency type an unsigned int as it
is always treated as such.
* jsa1212 - constify struct regmap_config as it is constant.
* ad7793 - typo in the MODULE_DESCRIPTION
* mma9551 - check gpiod_to_irq errors. Note that this doesn't actually cause
any trouble but is worth tidying up as obviously incorrect.
* mlx90614 - refactor the register symbols to make it clear which reads are to
RAM not PROM.
53 files changed, 1884 insertions, 577 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index 9a70c31619ea..6be17c2c5c65 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio | |||
@@ -253,6 +253,7 @@ What: /sys/bus/iio/devices/iio:deviceX/in_temp_offset | |||
253 | What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_offset | 253 | What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_offset |
254 | What: /sys/bus/iio/devices/iio:deviceX/in_pressure_offset | 254 | What: /sys/bus/iio/devices/iio:deviceX/in_pressure_offset |
255 | What: /sys/bus/iio/devices/iio:deviceX/in_humidityrelative_offset | 255 | What: /sys/bus/iio/devices/iio:deviceX/in_humidityrelative_offset |
256 | What: /sys/bus/iio/devices/iio:deviceX/in_magn_offset | ||
256 | KernelVersion: 2.6.35 | 257 | KernelVersion: 2.6.35 |
257 | Contact: linux-iio@vger.kernel.org | 258 | Contact: linux-iio@vger.kernel.org |
258 | Description: | 259 | Description: |
@@ -612,6 +613,8 @@ Description: | |||
612 | a given event type is enabled a future point (and not those for | 613 | a given event type is enabled a future point (and not those for |
613 | whatever event was previously enabled). | 614 | whatever event was previously enabled). |
614 | 615 | ||
616 | What: /sys/.../events/in_accel_thresh_rising_value | ||
617 | What: /sys/.../events/in_accel_thresh_falling_value | ||
615 | What: /sys/.../events/in_accel_x_raw_thresh_rising_value | 618 | What: /sys/.../events/in_accel_x_raw_thresh_rising_value |
616 | What: /sys/.../events/in_accel_x_raw_thresh_falling_value | 619 | What: /sys/.../events/in_accel_x_raw_thresh_falling_value |
617 | What: /sys/.../events/in_accel_y_raw_thresh_rising_value | 620 | What: /sys/.../events/in_accel_y_raw_thresh_rising_value |
@@ -661,6 +664,24 @@ Description: | |||
661 | value is in raw device units or in processed units (as _raw | 664 | value is in raw device units or in processed units (as _raw |
662 | and _input do on sysfs direct channel read attributes). | 665 | and _input do on sysfs direct channel read attributes). |
663 | 666 | ||
667 | What: /sys/.../events/in_accel_scale | ||
668 | What: /sys/.../events/in_accel_peak_scale | ||
669 | What: /sys/.../events/in_anglvel_scale | ||
670 | What: /sys/.../events/in_magn_scale | ||
671 | What: /sys/.../events/in_rot_from_north_magnetic_scale | ||
672 | What: /sys/.../events/in_rot_from_north_true_scale | ||
673 | What: /sys/.../events/in_voltage_scale | ||
674 | What: /sys/.../events/in_voltage_supply_scale | ||
675 | What: /sys/.../events/in_temp_scale | ||
676 | What: /sys/.../events/in_illuminance_scale | ||
677 | What: /sys/.../events/in_proximity_scale | ||
678 | KernelVersion: 3.21 | ||
679 | Contact: linux-iio@vger.kernel.org | ||
680 | Description: | ||
681 | Specifies the conversion factor from the standard units | ||
682 | to device specific units used to set the event trigger | ||
683 | threshold. | ||
684 | |||
664 | What: /sys/.../events/in_accel_x_thresh_rising_hysteresis | 685 | What: /sys/.../events/in_accel_x_thresh_rising_hysteresis |
665 | What: /sys/.../events/in_accel_x_thresh_falling_hysteresis | 686 | What: /sys/.../events/in_accel_x_thresh_falling_hysteresis |
666 | What: /sys/.../events/in_accel_x_thresh_either_hysteresis | 687 | What: /sys/.../events/in_accel_x_thresh_either_hysteresis |
@@ -997,6 +1018,7 @@ What: /sys/.../iio:deviceX/scan_elements/in_incli_y_en | |||
997 | What: /sys/.../iio:deviceX/scan_elements/in_pressureY_en | 1018 | What: /sys/.../iio:deviceX/scan_elements/in_pressureY_en |
998 | What: /sys/.../iio:deviceX/scan_elements/in_pressure_en | 1019 | What: /sys/.../iio:deviceX/scan_elements/in_pressure_en |
999 | What: /sys/.../iio:deviceX/scan_elements/in_rot_quaternion_en | 1020 | What: /sys/.../iio:deviceX/scan_elements/in_rot_quaternion_en |
1021 | What: /sys/.../iio:deviceX/scan_elements/in_proximity_en | ||
1000 | KernelVersion: 2.6.37 | 1022 | KernelVersion: 2.6.37 |
1001 | Contact: linux-iio@vger.kernel.org | 1023 | Contact: linux-iio@vger.kernel.org |
1002 | Description: | 1024 | Description: |
@@ -1013,6 +1035,7 @@ What: /sys/.../iio:deviceX/scan_elements/in_timestamp_type | |||
1013 | What: /sys/.../iio:deviceX/scan_elements/in_pressureY_type | 1035 | What: /sys/.../iio:deviceX/scan_elements/in_pressureY_type |
1014 | What: /sys/.../iio:deviceX/scan_elements/in_pressure_type | 1036 | What: /sys/.../iio:deviceX/scan_elements/in_pressure_type |
1015 | What: /sys/.../iio:deviceX/scan_elements/in_rot_quaternion_type | 1037 | What: /sys/.../iio:deviceX/scan_elements/in_rot_quaternion_type |
1038 | What: /sys/.../iio:deviceX/scan_elements/in_proximity_type | ||
1016 | KernelVersion: 2.6.37 | 1039 | KernelVersion: 2.6.37 |
1017 | Contact: linux-iio@vger.kernel.org | 1040 | Contact: linux-iio@vger.kernel.org |
1018 | Description: | 1041 | Description: |
@@ -1064,6 +1087,7 @@ What: /sys/.../iio:deviceX/scan_elements/in_timestamp_index | |||
1064 | What: /sys/.../iio:deviceX/scan_elements/in_pressureY_index | 1087 | What: /sys/.../iio:deviceX/scan_elements/in_pressureY_index |
1065 | What: /sys/.../iio:deviceX/scan_elements/in_pressure_index | 1088 | What: /sys/.../iio:deviceX/scan_elements/in_pressure_index |
1066 | What: /sys/.../iio:deviceX/scan_elements/in_rot_quaternion_index | 1089 | What: /sys/.../iio:deviceX/scan_elements/in_rot_quaternion_index |
1090 | What: /sys/.../iio:deviceX/scan_elements/in_proximity_index | ||
1067 | KernelVersion: 2.6.37 | 1091 | KernelVersion: 2.6.37 |
1068 | Contact: linux-iio@vger.kernel.org | 1092 | Contact: linux-iio@vger.kernel.org |
1069 | Description: | 1093 | Description: |
diff --git a/Documentation/devicetree/bindings/iio/adc/mcp320x.txt b/Documentation/devicetree/bindings/iio/adc/mcp320x.txt new file mode 100644 index 000000000000..b85184391b78 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/mcp320x.txt | |||
@@ -0,0 +1,30 @@ | |||
1 | * Microchip Analog to Digital Converter (ADC) | ||
2 | |||
3 | The node for this driver must be a child node of a SPI controller, hence | ||
4 | all mandatory properties described in | ||
5 | |||
6 | Documentation/devicetree/bindings/spi/spi-bus.txt | ||
7 | |||
8 | must be specified. | ||
9 | |||
10 | Required properties: | ||
11 | - compatible: Must be one of the following, depending on the | ||
12 | model: | ||
13 | "mcp3001" | ||
14 | "mcp3002" | ||
15 | "mcp3004" | ||
16 | "mcp3008" | ||
17 | "mcp3201" | ||
18 | "mcp3202" | ||
19 | "mcp3204" | ||
20 | "mcp3208" | ||
21 | |||
22 | |||
23 | Examples: | ||
24 | spi_controller { | ||
25 | mcp3x0x@0 { | ||
26 | compatible = "mcp3002"; | ||
27 | reg = <0>; | ||
28 | spi-max-frequency = <1000000>; | ||
29 | }; | ||
30 | }; | ||
diff --git a/Documentation/devicetree/bindings/iio/adc/mcp3422.txt b/Documentation/devicetree/bindings/iio/adc/mcp3422.txt new file mode 100644 index 000000000000..333139cc0bfb --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/mcp3422.txt | |||
@@ -0,0 +1,17 @@ | |||
1 | * Microchip mcp3422/3/4/6/7/8 chip family (ADC) | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: Should be | ||
5 | "microchip,mcp3422" or | ||
6 | "microchip,mcp3423" or | ||
7 | "microchip,mcp3424" or | ||
8 | "microchip,mcp3426" or | ||
9 | "microchip,mcp3427" or | ||
10 | "microchip,mcp3428" | ||
11 | - reg: I2C address for the device | ||
12 | |||
13 | Example: | ||
14 | adc@0 { | ||
15 | compatible = "microchip,mcp3424"; | ||
16 | reg = <0x68>; | ||
17 | }; | ||
diff --git a/Documentation/devicetree/bindings/iio/adc/ti-adc128s052.txt b/Documentation/devicetree/bindings/iio/adc/ti-adc128s052.txt new file mode 100644 index 000000000000..42ca7deec97d --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti-adc128s052.txt | |||
@@ -0,0 +1,18 @@ | |||
1 | * Texas Instruments' ADC128S052 ADC chip | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: Should be "ti,adc128s052" | ||
5 | - reg: spi chip select number for the device | ||
6 | - vref-supply: The regulator supply for ADC reference voltage | ||
7 | |||
8 | Recommended properties: | ||
9 | - spi-max-frequency: Definition as per | ||
10 | Documentation/devicetree/bindings/spi/spi-bus.txt | ||
11 | |||
12 | Example: | ||
13 | adc@0 { | ||
14 | compatible = "ti,adc128s052"; | ||
15 | reg = <0>; | ||
16 | vref-supply = <&vdd_supply>; | ||
17 | spi-max-frequency = <1000000>; | ||
18 | }; | ||
diff --git a/MAINTAINERS b/MAINTAINERS index ccf1c898afb1..036284f6cf45 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -4947,6 +4947,7 @@ S: Maintained | |||
4947 | F: drivers/iio/ | 4947 | F: drivers/iio/ |
4948 | F: drivers/staging/iio/ | 4948 | F: drivers/staging/iio/ |
4949 | F: include/linux/iio/ | 4949 | F: include/linux/iio/ |
4950 | F: tools/iio/ | ||
4950 | 4951 | ||
4951 | IKANOS/ADI EAGLE ADSL USB DRIVER | 4952 | IKANOS/ADI EAGLE ADSL USB DRIVER |
4952 | M: Matthieu Castet <castet.matthieu@free.fr> | 4953 | M: Matthieu Castet <castet.matthieu@free.fr> |
diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c index 066d0c04072c..f1b80c4c0b35 100644 --- a/drivers/iio/accel/bmc150-accel.c +++ b/drivers/iio/accel/bmc150-accel.c | |||
@@ -147,10 +147,37 @@ struct bmc150_accel_chip_info { | |||
147 | const struct bmc150_scale_info scale_table[4]; | 147 | const struct bmc150_scale_info scale_table[4]; |
148 | }; | 148 | }; |
149 | 149 | ||
150 | struct bmc150_accel_interrupt { | ||
151 | const struct bmc150_accel_interrupt_info *info; | ||
152 | atomic_t users; | ||
153 | }; | ||
154 | |||
155 | struct bmc150_accel_trigger { | ||
156 | struct bmc150_accel_data *data; | ||
157 | struct iio_trigger *indio_trig; | ||
158 | int (*setup)(struct bmc150_accel_trigger *t, bool state); | ||
159 | int intr; | ||
160 | bool enabled; | ||
161 | }; | ||
162 | |||
163 | enum bmc150_accel_interrupt_id { | ||
164 | BMC150_ACCEL_INT_DATA_READY, | ||
165 | BMC150_ACCEL_INT_ANY_MOTION, | ||
166 | BMC150_ACCEL_INT_WATERMARK, | ||
167 | BMC150_ACCEL_INTERRUPTS, | ||
168 | }; | ||
169 | |||
170 | enum bmc150_accel_trigger_id { | ||
171 | BMC150_ACCEL_TRIGGER_DATA_READY, | ||
172 | BMC150_ACCEL_TRIGGER_ANY_MOTION, | ||
173 | BMC150_ACCEL_TRIGGERS, | ||
174 | }; | ||
175 | |||
150 | struct bmc150_accel_data { | 176 | struct bmc150_accel_data { |
151 | struct i2c_client *client; | 177 | struct i2c_client *client; |
152 | struct iio_trigger *dready_trig; | 178 | struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS]; |
153 | struct iio_trigger *motion_trig; | 179 | atomic_t active_intr; |
180 | struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS]; | ||
154 | struct mutex mutex; | 181 | struct mutex mutex; |
155 | s16 buffer[8]; | 182 | s16 buffer[8]; |
156 | u8 bw_bits; | 183 | u8 bw_bits; |
@@ -158,8 +185,6 @@ struct bmc150_accel_data { | |||
158 | u32 slope_thres; | 185 | u32 slope_thres; |
159 | u32 range; | 186 | u32 range; |
160 | int ev_enable_state; | 187 | int ev_enable_state; |
161 | bool dready_trigger_on; | ||
162 | bool motion_trigger_on; | ||
163 | int64_t timestamp; | 188 | int64_t timestamp; |
164 | const struct bmc150_accel_chip_info *chip_info; | 189 | const struct bmc150_accel_chip_info *chip_info; |
165 | }; | 190 | }; |
@@ -269,6 +294,46 @@ static int bmc150_accel_set_bw(struct bmc150_accel_data *data, int val, | |||
269 | return -EINVAL; | 294 | return -EINVAL; |
270 | } | 295 | } |
271 | 296 | ||
297 | static int bmc150_accel_update_slope(struct bmc150_accel_data *data) | ||
298 | { | ||
299 | int ret, val; | ||
300 | |||
301 | ret = i2c_smbus_write_byte_data(data->client, BMC150_ACCEL_REG_INT_6, | ||
302 | data->slope_thres); | ||
303 | if (ret < 0) { | ||
304 | dev_err(&data->client->dev, "Error writing reg_int_6\n"); | ||
305 | return ret; | ||
306 | } | ||
307 | |||
308 | ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_INT_5); | ||
309 | if (ret < 0) { | ||
310 | dev_err(&data->client->dev, "Error reading reg_int_5\n"); | ||
311 | return ret; | ||
312 | } | ||
313 | |||
314 | val = (ret & ~BMC150_ACCEL_SLOPE_DUR_MASK) | data->slope_dur; | ||
315 | ret = i2c_smbus_write_byte_data(data->client, BMC150_ACCEL_REG_INT_5, | ||
316 | val); | ||
317 | if (ret < 0) { | ||
318 | dev_err(&data->client->dev, "Error write reg_int_5\n"); | ||
319 | return ret; | ||
320 | } | ||
321 | |||
322 | dev_dbg(&data->client->dev, "%s: %x %x\n", __func__, data->slope_thres, | ||
323 | data->slope_dur); | ||
324 | |||
325 | return ret; | ||
326 | } | ||
327 | |||
328 | static int bmc150_accel_any_motion_setup(struct bmc150_accel_trigger *t, | ||
329 | bool state) | ||
330 | { | ||
331 | if (state) | ||
332 | return bmc150_accel_update_slope(t->data); | ||
333 | |||
334 | return 0; | ||
335 | } | ||
336 | |||
272 | static int bmc150_accel_chip_init(struct bmc150_accel_data *data) | 337 | static int bmc150_accel_chip_init(struct bmc150_accel_data *data) |
273 | { | 338 | { |
274 | int ret; | 339 | int ret; |
@@ -307,32 +372,12 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data) | |||
307 | 372 | ||
308 | data->range = BMC150_ACCEL_DEF_RANGE_4G; | 373 | data->range = BMC150_ACCEL_DEF_RANGE_4G; |
309 | 374 | ||
310 | /* Set default slope duration */ | 375 | /* Set default slope duration and thresholds */ |
311 | ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_INT_5); | ||
312 | if (ret < 0) { | ||
313 | dev_err(&data->client->dev, "Error reading reg_int_5\n"); | ||
314 | return ret; | ||
315 | } | ||
316 | data->slope_dur |= BMC150_ACCEL_DEF_SLOPE_DURATION; | ||
317 | ret = i2c_smbus_write_byte_data(data->client, | ||
318 | BMC150_ACCEL_REG_INT_5, | ||
319 | data->slope_dur); | ||
320 | if (ret < 0) { | ||
321 | dev_err(&data->client->dev, "Error writing reg_int_5\n"); | ||
322 | return ret; | ||
323 | } | ||
324 | dev_dbg(&data->client->dev, "slope_dur %x\n", data->slope_dur); | ||
325 | |||
326 | /* Set default slope thresholds */ | ||
327 | ret = i2c_smbus_write_byte_data(data->client, | ||
328 | BMC150_ACCEL_REG_INT_6, | ||
329 | BMC150_ACCEL_DEF_SLOPE_THRESHOLD); | ||
330 | if (ret < 0) { | ||
331 | dev_err(&data->client->dev, "Error writing reg_int_6\n"); | ||
332 | return ret; | ||
333 | } | ||
334 | data->slope_thres = BMC150_ACCEL_DEF_SLOPE_THRESHOLD; | 376 | data->slope_thres = BMC150_ACCEL_DEF_SLOPE_THRESHOLD; |
335 | dev_dbg(&data->client->dev, "slope_thres %x\n", data->slope_thres); | 377 | data->slope_dur = BMC150_ACCEL_DEF_SLOPE_DURATION; |
378 | ret = bmc150_accel_update_slope(data); | ||
379 | if (ret < 0) | ||
380 | return ret; | ||
336 | 381 | ||
337 | /* Set default as latched interrupts */ | 382 | /* Set default as latched interrupts */ |
338 | ret = i2c_smbus_write_byte_data(data->client, | 383 | ret = i2c_smbus_write_byte_data(data->client, |
@@ -348,155 +393,6 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data) | |||
348 | return 0; | 393 | return 0; |
349 | } | 394 | } |
350 | 395 | ||
351 | static int bmc150_accel_setup_any_motion_interrupt( | ||
352 | struct bmc150_accel_data *data, | ||
353 | bool status) | ||
354 | { | ||
355 | int ret; | ||
356 | |||
357 | /* Enable/Disable INT1 mapping */ | ||
358 | ret = i2c_smbus_read_byte_data(data->client, | ||
359 | BMC150_ACCEL_REG_INT_MAP_0); | ||
360 | if (ret < 0) { | ||
361 | dev_err(&data->client->dev, "Error reading reg_int_map_0\n"); | ||
362 | return ret; | ||
363 | } | ||
364 | if (status) | ||
365 | ret |= BMC150_ACCEL_INT_MAP_0_BIT_SLOPE; | ||
366 | else | ||
367 | ret &= ~BMC150_ACCEL_INT_MAP_0_BIT_SLOPE; | ||
368 | |||
369 | ret = i2c_smbus_write_byte_data(data->client, | ||
370 | BMC150_ACCEL_REG_INT_MAP_0, | ||
371 | ret); | ||
372 | if (ret < 0) { | ||
373 | dev_err(&data->client->dev, "Error writing reg_int_map_0\n"); | ||
374 | return ret; | ||
375 | } | ||
376 | |||
377 | if (status) { | ||
378 | /* Set slope duration (no of samples) */ | ||
379 | ret = i2c_smbus_write_byte_data(data->client, | ||
380 | BMC150_ACCEL_REG_INT_5, | ||
381 | data->slope_dur); | ||
382 | if (ret < 0) { | ||
383 | dev_err(&data->client->dev, "Error write reg_int_5\n"); | ||
384 | return ret; | ||
385 | } | ||
386 | |||
387 | /* Set slope thresholds */ | ||
388 | ret = i2c_smbus_write_byte_data(data->client, | ||
389 | BMC150_ACCEL_REG_INT_6, | ||
390 | data->slope_thres); | ||
391 | if (ret < 0) { | ||
392 | dev_err(&data->client->dev, "Error write reg_int_6\n"); | ||
393 | return ret; | ||
394 | } | ||
395 | |||
396 | /* | ||
397 | * New data interrupt is always non-latched, | ||
398 | * which will have higher priority, so no need | ||
399 | * to set latched mode, we will be flooded anyway with INTR | ||
400 | */ | ||
401 | if (!data->dready_trigger_on) { | ||
402 | ret = i2c_smbus_write_byte_data(data->client, | ||
403 | BMC150_ACCEL_REG_INT_RST_LATCH, | ||
404 | BMC150_ACCEL_INT_MODE_LATCH_INT | | ||
405 | BMC150_ACCEL_INT_MODE_LATCH_RESET); | ||
406 | if (ret < 0) { | ||
407 | dev_err(&data->client->dev, | ||
408 | "Error writing reg_int_rst_latch\n"); | ||
409 | return ret; | ||
410 | } | ||
411 | } | ||
412 | |||
413 | ret = i2c_smbus_write_byte_data(data->client, | ||
414 | BMC150_ACCEL_REG_INT_EN_0, | ||
415 | BMC150_ACCEL_INT_EN_BIT_SLP_X | | ||
416 | BMC150_ACCEL_INT_EN_BIT_SLP_Y | | ||
417 | BMC150_ACCEL_INT_EN_BIT_SLP_Z); | ||
418 | } else | ||
419 | ret = i2c_smbus_write_byte_data(data->client, | ||
420 | BMC150_ACCEL_REG_INT_EN_0, | ||
421 | 0); | ||
422 | |||
423 | if (ret < 0) { | ||
424 | dev_err(&data->client->dev, "Error writing reg_int_en_0\n"); | ||
425 | return ret; | ||
426 | } | ||
427 | |||
428 | return 0; | ||
429 | } | ||
430 | |||
431 | static int bmc150_accel_setup_new_data_interrupt(struct bmc150_accel_data *data, | ||
432 | bool status) | ||
433 | { | ||
434 | int ret; | ||
435 | |||
436 | /* Enable/Disable INT1 mapping */ | ||
437 | ret = i2c_smbus_read_byte_data(data->client, | ||
438 | BMC150_ACCEL_REG_INT_MAP_1); | ||
439 | if (ret < 0) { | ||
440 | dev_err(&data->client->dev, "Error reading reg_int_map_1\n"); | ||
441 | return ret; | ||
442 | } | ||
443 | if (status) | ||
444 | ret |= BMC150_ACCEL_INT_MAP_1_BIT_DATA; | ||
445 | else | ||
446 | ret &= ~BMC150_ACCEL_INT_MAP_1_BIT_DATA; | ||
447 | |||
448 | ret = i2c_smbus_write_byte_data(data->client, | ||
449 | BMC150_ACCEL_REG_INT_MAP_1, | ||
450 | ret); | ||
451 | if (ret < 0) { | ||
452 | dev_err(&data->client->dev, "Error writing reg_int_map_1\n"); | ||
453 | return ret; | ||
454 | } | ||
455 | |||
456 | if (status) { | ||
457 | /* | ||
458 | * Set non latched mode interrupt and clear any latched | ||
459 | * interrupt | ||
460 | */ | ||
461 | ret = i2c_smbus_write_byte_data(data->client, | ||
462 | BMC150_ACCEL_REG_INT_RST_LATCH, | ||
463 | BMC150_ACCEL_INT_MODE_NON_LATCH_INT | | ||
464 | BMC150_ACCEL_INT_MODE_LATCH_RESET); | ||
465 | if (ret < 0) { | ||
466 | dev_err(&data->client->dev, | ||
467 | "Error writing reg_int_rst_latch\n"); | ||
468 | return ret; | ||
469 | } | ||
470 | |||
471 | ret = i2c_smbus_write_byte_data(data->client, | ||
472 | BMC150_ACCEL_REG_INT_EN_1, | ||
473 | BMC150_ACCEL_INT_EN_BIT_DATA_EN); | ||
474 | |||
475 | } else { | ||
476 | /* Restore default interrupt mode */ | ||
477 | ret = i2c_smbus_write_byte_data(data->client, | ||
478 | BMC150_ACCEL_REG_INT_RST_LATCH, | ||
479 | BMC150_ACCEL_INT_MODE_LATCH_INT | | ||
480 | BMC150_ACCEL_INT_MODE_LATCH_RESET); | ||
481 | if (ret < 0) { | ||
482 | dev_err(&data->client->dev, | ||
483 | "Error writing reg_int_rst_latch\n"); | ||
484 | return ret; | ||
485 | } | ||
486 | |||
487 | ret = i2c_smbus_write_byte_data(data->client, | ||
488 | BMC150_ACCEL_REG_INT_EN_1, | ||
489 | 0); | ||
490 | } | ||
491 | |||
492 | if (ret < 0) { | ||
493 | dev_err(&data->client->dev, "Error writing reg_int_en_1\n"); | ||
494 | return ret; | ||
495 | } | ||
496 | |||
497 | return 0; | ||
498 | } | ||
499 | |||
500 | static int bmc150_accel_get_bw(struct bmc150_accel_data *data, int *val, | 396 | static int bmc150_accel_get_bw(struct bmc150_accel_data *data, int *val, |
501 | int *val2) | 397 | int *val2) |
502 | { | 398 | { |
@@ -554,6 +450,114 @@ static int bmc150_accel_set_power_state(struct bmc150_accel_data *data, bool on) | |||
554 | } | 450 | } |
555 | #endif | 451 | #endif |
556 | 452 | ||
453 | static const struct bmc150_accel_interrupt_info { | ||
454 | u8 map_reg; | ||
455 | u8 map_bitmask; | ||
456 | u8 en_reg; | ||
457 | u8 en_bitmask; | ||
458 | } bmc150_accel_interrupts[BMC150_ACCEL_INTERRUPTS] = { | ||
459 | { /* data ready interrupt */ | ||
460 | .map_reg = BMC150_ACCEL_REG_INT_MAP_1, | ||
461 | .map_bitmask = BMC150_ACCEL_INT_MAP_1_BIT_DATA, | ||
462 | .en_reg = BMC150_ACCEL_REG_INT_EN_1, | ||
463 | .en_bitmask = BMC150_ACCEL_INT_EN_BIT_DATA_EN, | ||
464 | }, | ||
465 | { /* motion interrupt */ | ||
466 | .map_reg = BMC150_ACCEL_REG_INT_MAP_0, | ||
467 | .map_bitmask = BMC150_ACCEL_INT_MAP_0_BIT_SLOPE, | ||
468 | .en_reg = BMC150_ACCEL_REG_INT_EN_0, | ||
469 | .en_bitmask = BMC150_ACCEL_INT_EN_BIT_SLP_X | | ||
470 | BMC150_ACCEL_INT_EN_BIT_SLP_Y | | ||
471 | BMC150_ACCEL_INT_EN_BIT_SLP_Z | ||
472 | }, | ||
473 | }; | ||
474 | |||
475 | static void bmc150_accel_interrupts_setup(struct iio_dev *indio_dev, | ||
476 | struct bmc150_accel_data *data) | ||
477 | { | ||
478 | int i; | ||
479 | |||
480 | for (i = 0; i < BMC150_ACCEL_INTERRUPTS; i++) | ||
481 | data->interrupts[i].info = &bmc150_accel_interrupts[i]; | ||
482 | } | ||
483 | |||
484 | static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i, | ||
485 | bool state) | ||
486 | { | ||
487 | struct bmc150_accel_interrupt *intr = &data->interrupts[i]; | ||
488 | const struct bmc150_accel_interrupt_info *info = intr->info; | ||
489 | int ret; | ||
490 | |||
491 | if (state) { | ||
492 | if (atomic_inc_return(&intr->users) > 1) | ||
493 | return 0; | ||
494 | } else { | ||
495 | if (atomic_dec_return(&intr->users) > 0) | ||
496 | return 0; | ||
497 | } | ||
498 | |||
499 | /* | ||
500 | * We will expect the enable and disable to do operation in | ||
501 | * in reverse order. This will happen here anyway as our | ||
502 | * resume operation uses sync mode runtime pm calls, the | ||
503 | * suspend operation will be delayed by autosuspend delay | ||
504 | * So the disable operation will still happen in reverse of | ||
505 | * enable operation. When runtime pm is disabled the mode | ||
506 | * is always on so sequence doesn't matter | ||
507 | */ | ||
508 | ret = bmc150_accel_set_power_state(data, state); | ||
509 | if (ret < 0) | ||
510 | return ret; | ||
511 | |||
512 | /* map the interrupt to the appropriate pins */ | ||
513 | ret = i2c_smbus_read_byte_data(data->client, info->map_reg); | ||
514 | if (ret < 0) { | ||
515 | dev_err(&data->client->dev, "Error reading reg_int_map\n"); | ||
516 | goto out_fix_power_state; | ||
517 | } | ||
518 | if (state) | ||
519 | ret |= info->map_bitmask; | ||
520 | else | ||
521 | ret &= ~info->map_bitmask; | ||
522 | |||
523 | ret = i2c_smbus_write_byte_data(data->client, info->map_reg, | ||
524 | ret); | ||
525 | if (ret < 0) { | ||
526 | dev_err(&data->client->dev, "Error writing reg_int_map\n"); | ||
527 | goto out_fix_power_state; | ||
528 | } | ||
529 | |||
530 | /* enable/disable the interrupt */ | ||
531 | ret = i2c_smbus_read_byte_data(data->client, info->en_reg); | ||
532 | if (ret < 0) { | ||
533 | dev_err(&data->client->dev, "Error reading reg_int_en\n"); | ||
534 | goto out_fix_power_state; | ||
535 | } | ||
536 | |||
537 | if (state) | ||
538 | ret |= info->en_bitmask; | ||
539 | else | ||
540 | ret &= ~info->en_bitmask; | ||
541 | |||
542 | ret = i2c_smbus_write_byte_data(data->client, info->en_reg, ret); | ||
543 | if (ret < 0) { | ||
544 | dev_err(&data->client->dev, "Error writing reg_int_en\n"); | ||
545 | goto out_fix_power_state; | ||
546 | } | ||
547 | |||
548 | if (state) | ||
549 | atomic_inc(&data->active_intr); | ||
550 | else | ||
551 | atomic_dec(&data->active_intr); | ||
552 | |||
553 | return 0; | ||
554 | |||
555 | out_fix_power_state: | ||
556 | bmc150_accel_set_power_state(data, false); | ||
557 | return ret; | ||
558 | } | ||
559 | |||
560 | |||
557 | static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val) | 561 | static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val) |
558 | { | 562 | { |
559 | int ret, i; | 563 | int ret, i; |
@@ -732,7 +736,7 @@ static int bmc150_accel_read_event(struct iio_dev *indio_dev, | |||
732 | *val = data->slope_thres; | 736 | *val = data->slope_thres; |
733 | break; | 737 | break; |
734 | case IIO_EV_INFO_PERIOD: | 738 | case IIO_EV_INFO_PERIOD: |
735 | *val = data->slope_dur & BMC150_ACCEL_SLOPE_DUR_MASK; | 739 | *val = data->slope_dur; |
736 | break; | 740 | break; |
737 | default: | 741 | default: |
738 | return -EINVAL; | 742 | return -EINVAL; |
@@ -755,11 +759,10 @@ static int bmc150_accel_write_event(struct iio_dev *indio_dev, | |||
755 | 759 | ||
756 | switch (info) { | 760 | switch (info) { |
757 | case IIO_EV_INFO_VALUE: | 761 | case IIO_EV_INFO_VALUE: |
758 | data->slope_thres = val; | 762 | data->slope_thres = val & 0xFF; |
759 | break; | 763 | break; |
760 | case IIO_EV_INFO_PERIOD: | 764 | case IIO_EV_INFO_PERIOD: |
761 | data->slope_dur &= ~BMC150_ACCEL_SLOPE_DUR_MASK; | 765 | data->slope_dur = val & BMC150_ACCEL_SLOPE_DUR_MASK; |
762 | data->slope_dur |= val & BMC150_ACCEL_SLOPE_DUR_MASK; | ||
763 | break; | 766 | break; |
764 | default: | 767 | default: |
765 | return -EINVAL; | 768 | return -EINVAL; |
@@ -788,36 +791,14 @@ static int bmc150_accel_write_event_config(struct iio_dev *indio_dev, | |||
788 | struct bmc150_accel_data *data = iio_priv(indio_dev); | 791 | struct bmc150_accel_data *data = iio_priv(indio_dev); |
789 | int ret; | 792 | int ret; |
790 | 793 | ||
791 | if (state && data->ev_enable_state) | 794 | if (state == data->ev_enable_state) |
792 | return 0; | 795 | return 0; |
793 | 796 | ||
794 | mutex_lock(&data->mutex); | 797 | mutex_lock(&data->mutex); |
795 | 798 | ||
796 | if (!state && data->motion_trigger_on) { | 799 | ret = bmc150_accel_set_interrupt(data, BMC150_ACCEL_INT_ANY_MOTION, |
797 | data->ev_enable_state = 0; | 800 | state); |
798 | mutex_unlock(&data->mutex); | ||
799 | return 0; | ||
800 | } | ||
801 | |||
802 | /* | ||
803 | * We will expect the enable and disable to do operation in | ||
804 | * in reverse order. This will happen here anyway as our | ||
805 | * resume operation uses sync mode runtime pm calls, the | ||
806 | * suspend operation will be delayed by autosuspend delay | ||
807 | * So the disable operation will still happen in reverse of | ||
808 | * enable operation. When runtime pm is disabled the mode | ||
809 | * is always on so sequence doesn't matter | ||
810 | */ | ||
811 | |||
812 | ret = bmc150_accel_set_power_state(data, state); | ||
813 | if (ret < 0) { | ||
814 | mutex_unlock(&data->mutex); | ||
815 | return ret; | ||
816 | } | ||
817 | |||
818 | ret = bmc150_accel_setup_any_motion_interrupt(data, state); | ||
819 | if (ret < 0) { | 801 | if (ret < 0) { |
820 | bmc150_accel_set_power_state(data, false); | ||
821 | mutex_unlock(&data->mutex); | 802 | mutex_unlock(&data->mutex); |
822 | return ret; | 803 | return ret; |
823 | } | 804 | } |
@@ -832,11 +813,14 @@ static int bmc150_accel_validate_trigger(struct iio_dev *indio_dev, | |||
832 | struct iio_trigger *trig) | 813 | struct iio_trigger *trig) |
833 | { | 814 | { |
834 | struct bmc150_accel_data *data = iio_priv(indio_dev); | 815 | struct bmc150_accel_data *data = iio_priv(indio_dev); |
816 | int i; | ||
835 | 817 | ||
836 | if (data->dready_trig != trig && data->motion_trig != trig) | 818 | for (i = 0; i < BMC150_ACCEL_TRIGGERS; i++) { |
837 | return -EINVAL; | 819 | if (data->triggers[i].indio_trig == trig) |
820 | return 0; | ||
821 | } | ||
838 | 822 | ||
839 | return 0; | 823 | return -EINVAL; |
840 | } | 824 | } |
841 | 825 | ||
842 | static IIO_CONST_ATTR_SAMP_FREQ_AVAIL( | 826 | static IIO_CONST_ATTR_SAMP_FREQ_AVAIL( |
@@ -1008,12 +992,12 @@ err_read: | |||
1008 | 992 | ||
1009 | static int bmc150_accel_trig_try_reen(struct iio_trigger *trig) | 993 | static int bmc150_accel_trig_try_reen(struct iio_trigger *trig) |
1010 | { | 994 | { |
1011 | struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); | 995 | struct bmc150_accel_trigger *t = iio_trigger_get_drvdata(trig); |
1012 | struct bmc150_accel_data *data = iio_priv(indio_dev); | 996 | struct bmc150_accel_data *data = t->data; |
1013 | int ret; | 997 | int ret; |
1014 | 998 | ||
1015 | /* new data interrupts don't need ack */ | 999 | /* new data interrupts don't need ack */ |
1016 | if (data->dready_trigger_on) | 1000 | if (t == &t->data->triggers[BMC150_ACCEL_TRIGGER_DATA_READY]) |
1017 | return 0; | 1001 | return 0; |
1018 | 1002 | ||
1019 | mutex_lock(&data->mutex); | 1003 | mutex_lock(&data->mutex); |
@@ -1032,43 +1016,35 @@ static int bmc150_accel_trig_try_reen(struct iio_trigger *trig) | |||
1032 | return 0; | 1016 | return 0; |
1033 | } | 1017 | } |
1034 | 1018 | ||
1035 | static int bmc150_accel_data_rdy_trigger_set_state(struct iio_trigger *trig, | 1019 | static int bmc150_accel_trigger_set_state(struct iio_trigger *trig, |
1036 | bool state) | 1020 | bool state) |
1037 | { | 1021 | { |
1038 | struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); | 1022 | struct bmc150_accel_trigger *t = iio_trigger_get_drvdata(trig); |
1039 | struct bmc150_accel_data *data = iio_priv(indio_dev); | 1023 | struct bmc150_accel_data *data = t->data; |
1040 | int ret; | 1024 | int ret; |
1041 | 1025 | ||
1042 | mutex_lock(&data->mutex); | 1026 | mutex_lock(&data->mutex); |
1043 | 1027 | ||
1044 | if (!state && data->ev_enable_state && data->motion_trigger_on) { | 1028 | if (t->enabled == state) { |
1045 | data->motion_trigger_on = false; | ||
1046 | mutex_unlock(&data->mutex); | 1029 | mutex_unlock(&data->mutex); |
1047 | return 0; | 1030 | return 0; |
1048 | } | 1031 | } |
1049 | 1032 | ||
1050 | /* | 1033 | if (t->setup) { |
1051 | * Refer to comment in bmc150_accel_write_event_config for | 1034 | ret = t->setup(t, state); |
1052 | * enable/disable operation order | 1035 | if (ret < 0) { |
1053 | */ | 1036 | mutex_unlock(&data->mutex); |
1054 | ret = bmc150_accel_set_power_state(data, state); | 1037 | return ret; |
1055 | if (ret < 0) { | 1038 | } |
1056 | mutex_unlock(&data->mutex); | ||
1057 | return ret; | ||
1058 | } | 1039 | } |
1059 | if (data->motion_trig == trig) | 1040 | |
1060 | ret = bmc150_accel_setup_any_motion_interrupt(data, state); | 1041 | ret = bmc150_accel_set_interrupt(data, t->intr, state); |
1061 | else | ||
1062 | ret = bmc150_accel_setup_new_data_interrupt(data, state); | ||
1063 | if (ret < 0) { | 1042 | if (ret < 0) { |
1064 | bmc150_accel_set_power_state(data, false); | ||
1065 | mutex_unlock(&data->mutex); | 1043 | mutex_unlock(&data->mutex); |
1066 | return ret; | 1044 | return ret; |
1067 | } | 1045 | } |
1068 | if (data->motion_trig == trig) | 1046 | |
1069 | data->motion_trigger_on = state; | 1047 | t->enabled = state; |
1070 | else | ||
1071 | data->dready_trigger_on = state; | ||
1072 | 1048 | ||
1073 | mutex_unlock(&data->mutex); | 1049 | mutex_unlock(&data->mutex); |
1074 | 1050 | ||
@@ -1076,7 +1052,7 @@ static int bmc150_accel_data_rdy_trigger_set_state(struct iio_trigger *trig, | |||
1076 | } | 1052 | } |
1077 | 1053 | ||
1078 | static const struct iio_trigger_ops bmc150_accel_trigger_ops = { | 1054 | static const struct iio_trigger_ops bmc150_accel_trigger_ops = { |
1079 | .set_trigger_state = bmc150_accel_data_rdy_trigger_set_state, | 1055 | .set_trigger_state = bmc150_accel_trigger_set_state, |
1080 | .try_reenable = bmc150_accel_trig_try_reen, | 1056 | .try_reenable = bmc150_accel_trig_try_reen, |
1081 | .owner = THIS_MODULE, | 1057 | .owner = THIS_MODULE, |
1082 | }; | 1058 | }; |
@@ -1122,7 +1098,7 @@ static irqreturn_t bmc150_accel_event_handler(int irq, void *private) | |||
1122 | dir), | 1098 | dir), |
1123 | data->timestamp); | 1099 | data->timestamp); |
1124 | ack_intr_status: | 1100 | ack_intr_status: |
1125 | if (!data->dready_trigger_on) | 1101 | if (!data->triggers[BMC150_ACCEL_TRIGGER_DATA_READY].enabled) |
1126 | ret = i2c_smbus_write_byte_data(data->client, | 1102 | ret = i2c_smbus_write_byte_data(data->client, |
1127 | BMC150_ACCEL_REG_INT_RST_LATCH, | 1103 | BMC150_ACCEL_REG_INT_RST_LATCH, |
1128 | BMC150_ACCEL_INT_MODE_LATCH_INT | | 1104 | BMC150_ACCEL_INT_MODE_LATCH_INT | |
@@ -1135,13 +1111,16 @@ static irqreturn_t bmc150_accel_data_rdy_trig_poll(int irq, void *private) | |||
1135 | { | 1111 | { |
1136 | struct iio_dev *indio_dev = private; | 1112 | struct iio_dev *indio_dev = private; |
1137 | struct bmc150_accel_data *data = iio_priv(indio_dev); | 1113 | struct bmc150_accel_data *data = iio_priv(indio_dev); |
1114 | int i; | ||
1138 | 1115 | ||
1139 | data->timestamp = iio_get_time_ns(); | 1116 | data->timestamp = iio_get_time_ns(); |
1140 | 1117 | ||
1141 | if (data->dready_trigger_on) | 1118 | for (i = 0; i < BMC150_ACCEL_TRIGGERS; i++) { |
1142 | iio_trigger_poll(data->dready_trig); | 1119 | if (data->triggers[i].enabled) { |
1143 | else if (data->motion_trigger_on) | 1120 | iio_trigger_poll(data->triggers[i].indio_trig); |
1144 | iio_trigger_poll(data->motion_trig); | 1121 | break; |
1122 | } | ||
1123 | } | ||
1145 | 1124 | ||
1146 | if (data->ev_enable_state) | 1125 | if (data->ev_enable_state) |
1147 | return IRQ_WAKE_THREAD; | 1126 | return IRQ_WAKE_THREAD; |
@@ -1176,16 +1155,12 @@ static int bmc150_accel_gpio_probe(struct i2c_client *client, | |||
1176 | dev = &client->dev; | 1155 | dev = &client->dev; |
1177 | 1156 | ||
1178 | /* data ready gpio interrupt pin */ | 1157 | /* data ready gpio interrupt pin */ |
1179 | gpio = devm_gpiod_get_index(dev, BMC150_ACCEL_GPIO_NAME, 0); | 1158 | gpio = devm_gpiod_get_index(dev, BMC150_ACCEL_GPIO_NAME, 0, GPIOD_IN); |
1180 | if (IS_ERR(gpio)) { | 1159 | if (IS_ERR(gpio)) { |
1181 | dev_err(dev, "Failed: gpio get index\n"); | 1160 | dev_err(dev, "Failed: gpio get index\n"); |
1182 | return PTR_ERR(gpio); | 1161 | return PTR_ERR(gpio); |
1183 | } | 1162 | } |
1184 | 1163 | ||
1185 | ret = gpiod_direction_input(gpio); | ||
1186 | if (ret) | ||
1187 | return ret; | ||
1188 | |||
1189 | ret = gpiod_to_irq(gpio); | 1164 | ret = gpiod_to_irq(gpio); |
1190 | 1165 | ||
1191 | dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret); | 1166 | dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret); |
@@ -1193,6 +1168,70 @@ static int bmc150_accel_gpio_probe(struct i2c_client *client, | |||
1193 | return ret; | 1168 | return ret; |
1194 | } | 1169 | } |
1195 | 1170 | ||
1171 | static const struct { | ||
1172 | int intr; | ||
1173 | const char *name; | ||
1174 | int (*setup)(struct bmc150_accel_trigger *t, bool state); | ||
1175 | } bmc150_accel_triggers[BMC150_ACCEL_TRIGGERS] = { | ||
1176 | { | ||
1177 | .intr = 0, | ||
1178 | .name = "%s-dev%d", | ||
1179 | }, | ||
1180 | { | ||
1181 | .intr = 1, | ||
1182 | .name = "%s-any-motion-dev%d", | ||
1183 | .setup = bmc150_accel_any_motion_setup, | ||
1184 | }, | ||
1185 | }; | ||
1186 | |||
1187 | static void bmc150_accel_unregister_triggers(struct bmc150_accel_data *data, | ||
1188 | int from) | ||
1189 | { | ||
1190 | int i; | ||
1191 | |||
1192 | for (i = from; i >= 0; i++) { | ||
1193 | if (data->triggers[i].indio_trig) { | ||
1194 | iio_trigger_unregister(data->triggers[i].indio_trig); | ||
1195 | data->triggers[i].indio_trig = NULL; | ||
1196 | } | ||
1197 | } | ||
1198 | } | ||
1199 | |||
1200 | static int bmc150_accel_triggers_setup(struct iio_dev *indio_dev, | ||
1201 | struct bmc150_accel_data *data) | ||
1202 | { | ||
1203 | int i, ret; | ||
1204 | |||
1205 | for (i = 0; i < BMC150_ACCEL_TRIGGERS; i++) { | ||
1206 | struct bmc150_accel_trigger *t = &data->triggers[i]; | ||
1207 | |||
1208 | t->indio_trig = devm_iio_trigger_alloc(&data->client->dev, | ||
1209 | bmc150_accel_triggers[i].name, | ||
1210 | indio_dev->name, | ||
1211 | indio_dev->id); | ||
1212 | if (!t->indio_trig) { | ||
1213 | ret = -ENOMEM; | ||
1214 | break; | ||
1215 | } | ||
1216 | |||
1217 | t->indio_trig->dev.parent = &data->client->dev; | ||
1218 | t->indio_trig->ops = &bmc150_accel_trigger_ops; | ||
1219 | t->intr = bmc150_accel_triggers[i].intr; | ||
1220 | t->data = data; | ||
1221 | t->setup = bmc150_accel_triggers[i].setup; | ||
1222 | iio_trigger_set_drvdata(t->indio_trig, t); | ||
1223 | |||
1224 | ret = iio_trigger_register(t->indio_trig); | ||
1225 | if (ret) | ||
1226 | break; | ||
1227 | } | ||
1228 | |||
1229 | if (ret) | ||
1230 | bmc150_accel_unregister_triggers(data, i - 1); | ||
1231 | |||
1232 | return ret; | ||
1233 | } | ||
1234 | |||
1196 | static int bmc150_accel_probe(struct i2c_client *client, | 1235 | static int bmc150_accel_probe(struct i2c_client *client, |
1197 | const struct i2c_device_id *id) | 1236 | const struct i2c_device_id *id) |
1198 | { | 1237 | { |
@@ -1247,36 +1286,26 @@ static int bmc150_accel_probe(struct i2c_client *client, | |||
1247 | if (ret) | 1286 | if (ret) |
1248 | return ret; | 1287 | return ret; |
1249 | 1288 | ||
1250 | data->dready_trig = devm_iio_trigger_alloc(&client->dev, | 1289 | /* |
1251 | "%s-dev%d", | 1290 | * Set latched mode interrupt. While certain interrupts are |
1252 | indio_dev->name, | 1291 | * non-latched regardless of this settings (e.g. new data) we |
1253 | indio_dev->id); | 1292 | * want to use latch mode when we can to prevent interrupt |
1254 | if (!data->dready_trig) | 1293 | * flooding. |
1255 | return -ENOMEM; | 1294 | */ |
1256 | 1295 | ret = i2c_smbus_write_byte_data(data->client, | |
1257 | data->motion_trig = devm_iio_trigger_alloc(&client->dev, | 1296 | BMC150_ACCEL_REG_INT_RST_LATCH, |
1258 | "%s-any-motion-dev%d", | 1297 | BMC150_ACCEL_INT_MODE_LATCH_RESET); |
1259 | indio_dev->name, | 1298 | if (ret < 0) { |
1260 | indio_dev->id); | 1299 | dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n"); |
1261 | if (!data->motion_trig) | ||
1262 | return -ENOMEM; | ||
1263 | |||
1264 | data->dready_trig->dev.parent = &client->dev; | ||
1265 | data->dready_trig->ops = &bmc150_accel_trigger_ops; | ||
1266 | iio_trigger_set_drvdata(data->dready_trig, indio_dev); | ||
1267 | ret = iio_trigger_register(data->dready_trig); | ||
1268 | if (ret) | ||
1269 | return ret; | 1300 | return ret; |
1270 | |||
1271 | data->motion_trig->dev.parent = &client->dev; | ||
1272 | data->motion_trig->ops = &bmc150_accel_trigger_ops; | ||
1273 | iio_trigger_set_drvdata(data->motion_trig, indio_dev); | ||
1274 | ret = iio_trigger_register(data->motion_trig); | ||
1275 | if (ret) { | ||
1276 | data->motion_trig = NULL; | ||
1277 | goto err_trigger_unregister; | ||
1278 | } | 1301 | } |
1279 | 1302 | ||
1303 | bmc150_accel_interrupts_setup(indio_dev, data); | ||
1304 | |||
1305 | ret = bmc150_accel_triggers_setup(indio_dev, data); | ||
1306 | if (ret) | ||
1307 | return ret; | ||
1308 | |||
1280 | ret = iio_triggered_buffer_setup(indio_dev, | 1309 | ret = iio_triggered_buffer_setup(indio_dev, |
1281 | &iio_pollfunc_store_time, | 1310 | &iio_pollfunc_store_time, |
1282 | bmc150_accel_trigger_handler, | 1311 | bmc150_accel_trigger_handler, |
@@ -1308,13 +1337,10 @@ static int bmc150_accel_probe(struct i2c_client *client, | |||
1308 | err_iio_unregister: | 1337 | err_iio_unregister: |
1309 | iio_device_unregister(indio_dev); | 1338 | iio_device_unregister(indio_dev); |
1310 | err_buffer_cleanup: | 1339 | err_buffer_cleanup: |
1311 | if (data->dready_trig) | 1340 | if (indio_dev->pollfunc) |
1312 | iio_triggered_buffer_cleanup(indio_dev); | 1341 | iio_triggered_buffer_cleanup(indio_dev); |
1313 | err_trigger_unregister: | 1342 | err_trigger_unregister: |
1314 | if (data->dready_trig) | 1343 | bmc150_accel_unregister_triggers(data, BMC150_ACCEL_TRIGGERS - 1); |
1315 | iio_trigger_unregister(data->dready_trig); | ||
1316 | if (data->motion_trig) | ||
1317 | iio_trigger_unregister(data->motion_trig); | ||
1318 | 1344 | ||
1319 | return ret; | 1345 | return ret; |
1320 | } | 1346 | } |
@@ -1330,11 +1356,7 @@ static int bmc150_accel_remove(struct i2c_client *client) | |||
1330 | 1356 | ||
1331 | iio_device_unregister(indio_dev); | 1357 | iio_device_unregister(indio_dev); |
1332 | 1358 | ||
1333 | if (data->dready_trig) { | 1359 | bmc150_accel_unregister_triggers(data, BMC150_ACCEL_TRIGGERS - 1); |
1334 | iio_triggered_buffer_cleanup(indio_dev); | ||
1335 | iio_trigger_unregister(data->dready_trig); | ||
1336 | iio_trigger_unregister(data->motion_trig); | ||
1337 | } | ||
1338 | 1360 | ||
1339 | mutex_lock(&data->mutex); | 1361 | mutex_lock(&data->mutex); |
1340 | bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_DEEP_SUSPEND, 0); | 1362 | bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_DEEP_SUSPEND, 0); |
@@ -1362,8 +1384,7 @@ static int bmc150_accel_resume(struct device *dev) | |||
1362 | struct bmc150_accel_data *data = iio_priv(indio_dev); | 1384 | struct bmc150_accel_data *data = iio_priv(indio_dev); |
1363 | 1385 | ||
1364 | mutex_lock(&data->mutex); | 1386 | mutex_lock(&data->mutex); |
1365 | if (data->dready_trigger_on || data->motion_trigger_on || | 1387 | if (atomic_read(&data->active_intr)) |
1366 | data->ev_enable_state) | ||
1367 | bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0); | 1388 | bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0); |
1368 | mutex_unlock(&data->mutex); | 1389 | mutex_unlock(&data->mutex); |
1369 | 1390 | ||
diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c index 567de269cc00..a98b5d212fb3 100644 --- a/drivers/iio/accel/kxcjk-1013.c +++ b/drivers/iio/accel/kxcjk-1013.c | |||
@@ -1169,16 +1169,12 @@ static int kxcjk1013_gpio_probe(struct i2c_client *client, | |||
1169 | dev = &client->dev; | 1169 | dev = &client->dev; |
1170 | 1170 | ||
1171 | /* data ready gpio interrupt pin */ | 1171 | /* data ready gpio interrupt pin */ |
1172 | gpio = devm_gpiod_get_index(dev, "kxcjk1013_int", 0); | 1172 | gpio = devm_gpiod_get_index(dev, "kxcjk1013_int", 0, GPIOD_IN); |
1173 | if (IS_ERR(gpio)) { | 1173 | if (IS_ERR(gpio)) { |
1174 | dev_err(dev, "acpi gpio get index failed\n"); | 1174 | dev_err(dev, "acpi gpio get index failed\n"); |
1175 | return PTR_ERR(gpio); | 1175 | return PTR_ERR(gpio); |
1176 | } | 1176 | } |
1177 | 1177 | ||
1178 | ret = gpiod_direction_input(gpio); | ||
1179 | if (ret) | ||
1180 | return ret; | ||
1181 | |||
1182 | ret = gpiod_to_irq(gpio); | 1178 | ret = gpiod_to_irq(gpio); |
1183 | 1179 | ||
1184 | dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret); | 1180 | dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret); |
diff --git a/drivers/iio/accel/mma9551.c b/drivers/iio/accel/mma9551.c index 46c38351c6a3..7db7cc0bf362 100644 --- a/drivers/iio/accel/mma9551.c +++ b/drivers/iio/accel/mma9551.c | |||
@@ -418,17 +418,18 @@ static int mma9551_gpio_probe(struct iio_dev *indio_dev) | |||
418 | struct device *dev = &data->client->dev; | 418 | struct device *dev = &data->client->dev; |
419 | 419 | ||
420 | for (i = 0; i < MMA9551_GPIO_COUNT; i++) { | 420 | for (i = 0; i < MMA9551_GPIO_COUNT; i++) { |
421 | gpio = devm_gpiod_get_index(dev, MMA9551_GPIO_NAME, i); | 421 | gpio = devm_gpiod_get_index(dev, MMA9551_GPIO_NAME, i, |
422 | GPIOD_IN); | ||
422 | if (IS_ERR(gpio)) { | 423 | if (IS_ERR(gpio)) { |
423 | dev_err(dev, "acpi gpio get index failed\n"); | 424 | dev_err(dev, "acpi gpio get index failed\n"); |
424 | return PTR_ERR(gpio); | 425 | return PTR_ERR(gpio); |
425 | } | 426 | } |
426 | 427 | ||
427 | ret = gpiod_direction_input(gpio); | 428 | ret = gpiod_to_irq(gpio); |
428 | if (ret) | 429 | if (ret < 0) |
429 | return ret; | 430 | return ret; |
430 | 431 | ||
431 | data->irqs[i] = gpiod_to_irq(gpio); | 432 | data->irqs[i] = ret; |
432 | ret = devm_request_threaded_irq(dev, data->irqs[i], | 433 | ret = devm_request_threaded_irq(dev, data->irqs[i], |
433 | NULL, mma9551_event_handler, | 434 | NULL, mma9551_event_handler, |
434 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, | 435 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, |
diff --git a/drivers/iio/accel/mma9553.c b/drivers/iio/accel/mma9553.c index d23ebf192f63..2df1af7d43fc 100644 --- a/drivers/iio/accel/mma9553.c +++ b/drivers/iio/accel/mma9553.c | |||
@@ -1109,16 +1109,12 @@ static int mma9553_gpio_probe(struct i2c_client *client) | |||
1109 | dev = &client->dev; | 1109 | dev = &client->dev; |
1110 | 1110 | ||
1111 | /* data ready gpio interrupt pin */ | 1111 | /* data ready gpio interrupt pin */ |
1112 | gpio = devm_gpiod_get_index(dev, MMA9553_GPIO_NAME, 0); | 1112 | gpio = devm_gpiod_get_index(dev, MMA9553_GPIO_NAME, 0, GPIOD_IN); |
1113 | if (IS_ERR(gpio)) { | 1113 | if (IS_ERR(gpio)) { |
1114 | dev_err(dev, "acpi gpio get index failed\n"); | 1114 | dev_err(dev, "acpi gpio get index failed\n"); |
1115 | return PTR_ERR(gpio); | 1115 | return PTR_ERR(gpio); |
1116 | } | 1116 | } |
1117 | 1117 | ||
1118 | ret = gpiod_direction_input(gpio); | ||
1119 | if (ret) | ||
1120 | return ret; | ||
1121 | |||
1122 | ret = gpiod_to_irq(gpio); | 1118 | ret = gpiod_to_irq(gpio); |
1123 | 1119 | ||
1124 | dev_dbg(dev, "gpio resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret); | 1120 | dev_dbg(dev, "gpio resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret); |
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 202daf889be2..9eaa8d1e582d 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig | |||
@@ -186,10 +186,11 @@ config MAX1363 | |||
186 | data via the iio dev interface. | 186 | data via the iio dev interface. |
187 | 187 | ||
188 | config MCP320X | 188 | config MCP320X |
189 | tristate "Microchip Technology MCP3204/08" | 189 | tristate "Microchip Technology MCP3x01/02/04/08" |
190 | depends on SPI | 190 | depends on SPI |
191 | help | 191 | help |
192 | Say yes here to build support for Microchip Technology's MCP3204 or | 192 | Say yes here to build support for Microchip Technology's |
193 | MCP3001, MCP3002, MCP3004, MCP3008, MCP3201, MCP3202, MCP3204 or | ||
193 | MCP3208 analog to digital converter. | 194 | MCP3208 analog to digital converter. |
194 | 195 | ||
195 | This driver can also be built as a module. If so, the module will be | 196 | This driver can also be built as a module. If so, the module will be |
diff --git a/drivers/iio/adc/ad7793.c b/drivers/iio/adc/ad7793.c index 4dddeabdfbb0..b84922a4b32e 100644 --- a/drivers/iio/adc/ad7793.c +++ b/drivers/iio/adc/ad7793.c | |||
@@ -861,5 +861,5 @@ static struct spi_driver ad7793_driver = { | |||
861 | module_spi_driver(ad7793_driver); | 861 | module_spi_driver(ad7793_driver); |
862 | 862 | ||
863 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | 863 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); |
864 | MODULE_DESCRIPTION("Analog Devices AD7793 and simialr ADCs"); | 864 | MODULE_DESCRIPTION("Analog Devices AD7793 and similar ADCs"); |
865 | MODULE_LICENSE("GPL v2"); | 865 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c index 8ec353c01d98..5b72d170fd36 100644 --- a/drivers/iio/adc/vf610_adc.c +++ b/drivers/iio/adc/vf610_adc.c | |||
@@ -259,7 +259,6 @@ static void vf610_adc_cfg_post_set(struct vf610_adc *info) | |||
259 | static void vf610_adc_calibration(struct vf610_adc *info) | 259 | static void vf610_adc_calibration(struct vf610_adc *info) |
260 | { | 260 | { |
261 | int adc_gc, hc_cfg; | 261 | int adc_gc, hc_cfg; |
262 | int timeout; | ||
263 | 262 | ||
264 | if (!info->adc_feature.calibration) | 263 | if (!info->adc_feature.calibration) |
265 | return; | 264 | return; |
@@ -271,9 +270,7 @@ static void vf610_adc_calibration(struct vf610_adc *info) | |||
271 | adc_gc = readl(info->regs + VF610_REG_ADC_GC); | 270 | adc_gc = readl(info->regs + VF610_REG_ADC_GC); |
272 | writel(adc_gc | VF610_ADC_CAL, info->regs + VF610_REG_ADC_GC); | 271 | writel(adc_gc | VF610_ADC_CAL, info->regs + VF610_REG_ADC_GC); |
273 | 272 | ||
274 | timeout = wait_for_completion_timeout | 273 | if (!wait_for_completion_timeout(&info->completion, VF610_ADC_TIMEOUT)) |
275 | (&info->completion, VF610_ADC_TIMEOUT); | ||
276 | if (timeout == 0) | ||
277 | dev_err(info->dev, "Timeout for adc calibration\n"); | 274 | dev_err(info->dev, "Timeout for adc calibration\n"); |
278 | 275 | ||
279 | adc_gc = readl(info->regs + VF610_REG_ADC_GS); | 276 | adc_gc = readl(info->regs + VF610_REG_ADC_GS); |
diff --git a/drivers/iio/gyro/bmg160.c b/drivers/iio/gyro/bmg160.c index 60451b328242..56d68e1d0987 100644 --- a/drivers/iio/gyro/bmg160.c +++ b/drivers/iio/gyro/bmg160.c | |||
@@ -1001,16 +1001,12 @@ static int bmg160_gpio_probe(struct i2c_client *client, | |||
1001 | dev = &client->dev; | 1001 | dev = &client->dev; |
1002 | 1002 | ||
1003 | /* data ready gpio interrupt pin */ | 1003 | /* data ready gpio interrupt pin */ |
1004 | gpio = devm_gpiod_get_index(dev, BMG160_GPIO_NAME, 0); | 1004 | gpio = devm_gpiod_get_index(dev, BMG160_GPIO_NAME, 0, GPIOD_IN); |
1005 | if (IS_ERR(gpio)) { | 1005 | if (IS_ERR(gpio)) { |
1006 | dev_err(dev, "acpi gpio get index failed\n"); | 1006 | dev_err(dev, "acpi gpio get index failed\n"); |
1007 | return PTR_ERR(gpio); | 1007 | return PTR_ERR(gpio); |
1008 | } | 1008 | } |
1009 | 1009 | ||
1010 | ret = gpiod_direction_input(gpio); | ||
1011 | if (ret) | ||
1012 | return ret; | ||
1013 | |||
1014 | ret = gpiod_to_irq(gpio); | 1010 | ret = gpiod_to_irq(gpio); |
1015 | 1011 | ||
1016 | dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret); | 1012 | dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret); |
diff --git a/drivers/iio/gyro/itg3200_core.c b/drivers/iio/gyro/itg3200_core.c index 6a8020d48140..f0fd94055d88 100644 --- a/drivers/iio/gyro/itg3200_core.c +++ b/drivers/iio/gyro/itg3200_core.c | |||
@@ -223,6 +223,10 @@ static int itg3200_initial_setup(struct iio_dev *indio_dev) | |||
223 | int ret; | 223 | int ret; |
224 | u8 val; | 224 | u8 val; |
225 | 225 | ||
226 | ret = itg3200_reset(indio_dev); | ||
227 | if (ret) | ||
228 | goto err_ret; | ||
229 | |||
226 | ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_ADDRESS, &val); | 230 | ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_ADDRESS, &val); |
227 | if (ret) | 231 | if (ret) |
228 | goto err_ret; | 232 | goto err_ret; |
@@ -233,10 +237,6 @@ static int itg3200_initial_setup(struct iio_dev *indio_dev) | |||
233 | goto err_ret; | 237 | goto err_ret; |
234 | } | 238 | } |
235 | 239 | ||
236 | ret = itg3200_reset(indio_dev); | ||
237 | if (ret) | ||
238 | goto err_ret; | ||
239 | |||
240 | ret = itg3200_enable_full_scale(indio_dev); | 240 | ret = itg3200_enable_full_scale(indio_dev); |
241 | err_ret: | 241 | err_ret: |
242 | return ret; | 242 | return ret; |
@@ -351,6 +351,26 @@ static int itg3200_remove(struct i2c_client *client) | |||
351 | return 0; | 351 | return 0; |
352 | } | 352 | } |
353 | 353 | ||
354 | static int __maybe_unused itg3200_suspend(struct device *dev) | ||
355 | { | ||
356 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | ||
357 | struct itg3200 *st = iio_priv(indio_dev); | ||
358 | |||
359 | dev_dbg(&st->i2c->dev, "suspend device"); | ||
360 | |||
361 | return itg3200_write_reg_8(indio_dev, ITG3200_REG_POWER_MANAGEMENT, | ||
362 | ITG3200_SLEEP); | ||
363 | } | ||
364 | |||
365 | static int __maybe_unused itg3200_resume(struct device *dev) | ||
366 | { | ||
367 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | ||
368 | |||
369 | return itg3200_initial_setup(indio_dev); | ||
370 | } | ||
371 | |||
372 | static SIMPLE_DEV_PM_OPS(itg3200_pm_ops, itg3200_suspend, itg3200_resume); | ||
373 | |||
354 | static const struct i2c_device_id itg3200_id[] = { | 374 | static const struct i2c_device_id itg3200_id[] = { |
355 | { "itg3200", 0 }, | 375 | { "itg3200", 0 }, |
356 | { } | 376 | { } |
@@ -361,6 +381,7 @@ static struct i2c_driver itg3200_driver = { | |||
361 | .driver = { | 381 | .driver = { |
362 | .owner = THIS_MODULE, | 382 | .owner = THIS_MODULE, |
363 | .name = "itg3200", | 383 | .name = "itg3200", |
384 | .pm = &itg3200_pm_ops, | ||
364 | }, | 385 | }, |
365 | .id_table = itg3200_id, | 386 | .id_table = itg3200_id, |
366 | .probe = itg3200_probe, | 387 | .probe = itg3200_probe, |
diff --git a/drivers/iio/imu/inv_mpu6050/Makefile b/drivers/iio/imu/inv_mpu6050/Makefile index 3a677c778afb..f566f6a7b3a9 100644 --- a/drivers/iio/imu/inv_mpu6050/Makefile +++ b/drivers/iio/imu/inv_mpu6050/Makefile | |||
@@ -3,4 +3,4 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_INV_MPU6050_IIO) += inv-mpu6050.o | 5 | obj-$(CONFIG_INV_MPU6050_IIO) += inv-mpu6050.o |
6 | inv-mpu6050-objs := inv_mpu_core.o inv_mpu_ring.o inv_mpu_trigger.o | 6 | inv-mpu6050-objs := inv_mpu_core.o inv_mpu_ring.o inv_mpu_trigger.o inv_mpu_acpi.o |
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c new file mode 100644 index 000000000000..1c982a56acd5 --- /dev/null +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c | |||
@@ -0,0 +1,211 @@ | |||
1 | /* | ||
2 | * inv_mpu_acpi: ACPI processing for creating client devices | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifdef CONFIG_ACPI | ||
16 | |||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/i2c.h> | ||
19 | #include <linux/dmi.h> | ||
20 | #include <linux/acpi.h> | ||
21 | #include "inv_mpu_iio.h" | ||
22 | |||
23 | enum inv_mpu_product_name { | ||
24 | INV_MPU_NOT_MATCHED, | ||
25 | INV_MPU_ASUS_T100TA, | ||
26 | }; | ||
27 | |||
28 | static enum inv_mpu_product_name matched_product_name; | ||
29 | |||
30 | static int __init asus_t100_matched(const struct dmi_system_id *d) | ||
31 | { | ||
32 | matched_product_name = INV_MPU_ASUS_T100TA; | ||
33 | |||
34 | return 0; | ||
35 | } | ||
36 | |||
37 | static const struct dmi_system_id inv_mpu_dev_list[] = { | ||
38 | { | ||
39 | .callback = asus_t100_matched, | ||
40 | .ident = "Asus Transformer Book T100", | ||
41 | .matches = { | ||
42 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC"), | ||
43 | DMI_MATCH(DMI_PRODUCT_NAME, "T100TA"), | ||
44 | DMI_MATCH(DMI_PRODUCT_VERSION, "1.0"), | ||
45 | }, | ||
46 | }, | ||
47 | /* Add more matching tables here..*/ | ||
48 | {} | ||
49 | }; | ||
50 | |||
51 | static int asus_acpi_get_sensor_info(struct acpi_device *adev, | ||
52 | struct i2c_client *client, | ||
53 | struct i2c_board_info *info) | ||
54 | { | ||
55 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
56 | int i; | ||
57 | acpi_status status; | ||
58 | union acpi_object *cpm; | ||
59 | |||
60 | status = acpi_evaluate_object(adev->handle, "CNF0", NULL, &buffer); | ||
61 | if (ACPI_FAILURE(status)) | ||
62 | return -ENODEV; | ||
63 | |||
64 | cpm = buffer.pointer; | ||
65 | for (i = 0; i < cpm->package.count; ++i) { | ||
66 | union acpi_object *elem; | ||
67 | int j; | ||
68 | |||
69 | elem = &(cpm->package.elements[i]); | ||
70 | for (j = 0; j < elem->package.count; ++j) { | ||
71 | union acpi_object *sub_elem; | ||
72 | |||
73 | sub_elem = &(elem->package.elements[j]); | ||
74 | if (sub_elem->type == ACPI_TYPE_STRING) | ||
75 | strlcpy(info->type, sub_elem->string.pointer, | ||
76 | sizeof(info->type)); | ||
77 | else if (sub_elem->type == ACPI_TYPE_INTEGER) { | ||
78 | if (sub_elem->integer.value != client->addr) { | ||
79 | info->addr = sub_elem->integer.value; | ||
80 | break; /* Not a MPU6500 primary */ | ||
81 | } | ||
82 | } | ||
83 | } | ||
84 | } | ||
85 | |||
86 | kfree(buffer.pointer); | ||
87 | |||
88 | return cpm->package.count; | ||
89 | } | ||
90 | |||
91 | static int acpi_i2c_check_resource(struct acpi_resource *ares, void *data) | ||
92 | { | ||
93 | u32 *addr = data; | ||
94 | |||
95 | if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) { | ||
96 | struct acpi_resource_i2c_serialbus *sb; | ||
97 | |||
98 | sb = &ares->data.i2c_serial_bus; | ||
99 | if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_I2C) { | ||
100 | if (*addr) | ||
101 | *addr |= (sb->slave_address << 16); | ||
102 | else | ||
103 | *addr = sb->slave_address; | ||
104 | } | ||
105 | } | ||
106 | |||
107 | /* Tell the ACPI core that we already copied this address */ | ||
108 | return 1; | ||
109 | } | ||
110 | |||
111 | static int inv_mpu_process_acpi_config(struct i2c_client *client, | ||
112 | unsigned short *primary_addr, | ||
113 | unsigned short *secondary_addr) | ||
114 | { | ||
115 | const struct acpi_device_id *id; | ||
116 | struct acpi_device *adev; | ||
117 | u32 i2c_addr = 0; | ||
118 | LIST_HEAD(resources); | ||
119 | int ret; | ||
120 | |||
121 | id = acpi_match_device(client->dev.driver->acpi_match_table, | ||
122 | &client->dev); | ||
123 | if (!id) | ||
124 | return -ENODEV; | ||
125 | |||
126 | adev = ACPI_COMPANION(&client->dev); | ||
127 | if (!adev) | ||
128 | return -ENODEV; | ||
129 | |||
130 | ret = acpi_dev_get_resources(adev, &resources, | ||
131 | acpi_i2c_check_resource, &i2c_addr); | ||
132 | if (ret < 0) | ||
133 | return ret; | ||
134 | |||
135 | acpi_dev_free_resource_list(&resources); | ||
136 | *primary_addr = i2c_addr & 0x0000ffff; | ||
137 | *secondary_addr = (i2c_addr & 0xffff0000) >> 16; | ||
138 | |||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | int inv_mpu_acpi_create_mux_client(struct inv_mpu6050_state *st) | ||
143 | { | ||
144 | |||
145 | st->mux_client = NULL; | ||
146 | if (ACPI_HANDLE(&st->client->dev)) { | ||
147 | struct i2c_board_info info; | ||
148 | struct acpi_device *adev; | ||
149 | int ret = -1; | ||
150 | |||
151 | adev = ACPI_COMPANION(&st->client->dev); | ||
152 | memset(&info, 0, sizeof(info)); | ||
153 | |||
154 | dmi_check_system(inv_mpu_dev_list); | ||
155 | switch (matched_product_name) { | ||
156 | case INV_MPU_ASUS_T100TA: | ||
157 | ret = asus_acpi_get_sensor_info(adev, st->client, | ||
158 | &info); | ||
159 | break; | ||
160 | /* Add more matched product processing here */ | ||
161 | default: | ||
162 | break; | ||
163 | } | ||
164 | |||
165 | if (ret < 0) { | ||
166 | /* No matching DMI, so create device on INV6XX type */ | ||
167 | unsigned short primary, secondary; | ||
168 | |||
169 | ret = inv_mpu_process_acpi_config(st->client, &primary, | ||
170 | &secondary); | ||
171 | if (!ret && secondary) { | ||
172 | char *name; | ||
173 | |||
174 | info.addr = secondary; | ||
175 | strlcpy(info.type, dev_name(&adev->dev), | ||
176 | sizeof(info.type)); | ||
177 | name = strchr(info.type, ':'); | ||
178 | if (name) | ||
179 | *name = '\0'; | ||
180 | strlcat(info.type, "-client", | ||
181 | sizeof(info.type)); | ||
182 | } else | ||
183 | return 0; /* no secondary addr, which is OK */ | ||
184 | } | ||
185 | st->mux_client = i2c_new_device(st->mux_adapter, &info); | ||
186 | if (!st->mux_client) | ||
187 | return -ENODEV; | ||
188 | |||
189 | } | ||
190 | |||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | void inv_mpu_acpi_delete_mux_client(struct inv_mpu6050_state *st) | ||
195 | { | ||
196 | if (st->mux_client) | ||
197 | i2c_unregister_device(st->mux_client); | ||
198 | } | ||
199 | #else | ||
200 | |||
201 | #include "inv_mpu_iio.h" | ||
202 | |||
203 | int inv_mpu_acpi_create_mux_client(struct inv_mpu6050_state *st) | ||
204 | { | ||
205 | return 0; | ||
206 | } | ||
207 | |||
208 | void inv_mpu_acpi_delete_mux_client(struct inv_mpu6050_state *st) | ||
209 | { | ||
210 | } | ||
211 | #endif | ||
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index d8d5bed65e07..5613f3ab9f96 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | |||
@@ -825,8 +825,14 @@ static int inv_mpu_probe(struct i2c_client *client, | |||
825 | goto out_unreg_device; | 825 | goto out_unreg_device; |
826 | } | 826 | } |
827 | 827 | ||
828 | result = inv_mpu_acpi_create_mux_client(st); | ||
829 | if (result) | ||
830 | goto out_del_mux; | ||
831 | |||
828 | return 0; | 832 | return 0; |
829 | 833 | ||
834 | out_del_mux: | ||
835 | i2c_del_mux_adapter(st->mux_adapter); | ||
830 | out_unreg_device: | 836 | out_unreg_device: |
831 | iio_device_unregister(indio_dev); | 837 | iio_device_unregister(indio_dev); |
832 | out_remove_trigger: | 838 | out_remove_trigger: |
@@ -841,6 +847,7 @@ static int inv_mpu_remove(struct i2c_client *client) | |||
841 | struct iio_dev *indio_dev = i2c_get_clientdata(client); | 847 | struct iio_dev *indio_dev = i2c_get_clientdata(client); |
842 | struct inv_mpu6050_state *st = iio_priv(indio_dev); | 848 | struct inv_mpu6050_state *st = iio_priv(indio_dev); |
843 | 849 | ||
850 | inv_mpu_acpi_delete_mux_client(st); | ||
844 | i2c_del_mux_adapter(st->mux_adapter); | 851 | i2c_del_mux_adapter(st->mux_adapter); |
845 | iio_device_unregister(indio_dev); | 852 | iio_device_unregister(indio_dev); |
846 | inv_mpu6050_remove_trigger(st); | 853 | inv_mpu6050_remove_trigger(st); |
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h index aa837de57079..db0a4a2758ab 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | |||
@@ -121,6 +121,7 @@ struct inv_mpu6050_state { | |||
121 | spinlock_t time_stamp_lock; | 121 | spinlock_t time_stamp_lock; |
122 | struct i2c_client *client; | 122 | struct i2c_client *client; |
123 | struct i2c_adapter *mux_adapter; | 123 | struct i2c_adapter *mux_adapter; |
124 | struct i2c_client *mux_client; | ||
124 | unsigned int powerup_count; | 125 | unsigned int powerup_count; |
125 | struct inv_mpu6050_platform_data plat_data; | 126 | struct inv_mpu6050_platform_data plat_data; |
126 | DECLARE_KFIFO(timestamps, long long, TIMESTAMP_FIFO_SIZE); | 127 | DECLARE_KFIFO(timestamps, long long, TIMESTAMP_FIFO_SIZE); |
@@ -251,3 +252,5 @@ int inv_reset_fifo(struct iio_dev *indio_dev); | |||
251 | int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en, u32 mask); | 252 | int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en, u32 mask); |
252 | int inv_mpu6050_write_reg(struct inv_mpu6050_state *st, int reg, u8 val); | 253 | int inv_mpu6050_write_reg(struct inv_mpu6050_state *st, int reg, u8 val); |
253 | int inv_mpu6050_set_power_itg(struct inv_mpu6050_state *st, bool power_on); | 254 | int inv_mpu6050_set_power_itg(struct inv_mpu6050_state *st, bool power_on); |
255 | int inv_mpu_acpi_create_mux_client(struct inv_mpu6050_state *st); | ||
256 | void inv_mpu_acpi_delete_mux_client(struct inv_mpu6050_state *st); | ||
diff --git a/drivers/iio/imu/kmx61.c b/drivers/iio/imu/kmx61.c index 5cc3692acf37..75ab70100015 100644 --- a/drivers/iio/imu/kmx61.c +++ b/drivers/iio/imu/kmx61.c | |||
@@ -169,19 +169,18 @@ static const u16 kmx61_uscale_table[] = {9582, 19163, 38326}; | |||
169 | static const struct { | 169 | static const struct { |
170 | int val; | 170 | int val; |
171 | int val2; | 171 | int val2; |
172 | u8 odr_bits; | 172 | } kmx61_samp_freq_table[] = { {12, 500000}, |
173 | } kmx61_samp_freq_table[] = { {12, 500000, 0x00}, | 173 | {25, 0}, |
174 | {25, 0, 0x01}, | 174 | {50, 0}, |
175 | {50, 0, 0x02}, | 175 | {100, 0}, |
176 | {100, 0, 0x03}, | 176 | {200, 0}, |
177 | {200, 0, 0x04}, | 177 | {400, 0}, |
178 | {400, 0, 0x05}, | 178 | {800, 0}, |
179 | {800, 0, 0x06}, | 179 | {1600, 0}, |
180 | {1600, 0, 0x07}, | 180 | {0, 781000}, |
181 | {0, 781000, 0x08}, | 181 | {1, 563000}, |
182 | {1, 563000, 0x09}, | 182 | {3, 125000}, |
183 | {3, 125000, 0x0A}, | 183 | {6, 250000} }; |
184 | {6, 250000, 0x0B} }; | ||
185 | 184 | ||
186 | static const struct { | 185 | static const struct { |
187 | int val; | 186 | int val; |
@@ -302,24 +301,10 @@ static int kmx61_convert_freq_to_bit(int val, int val2) | |||
302 | for (i = 0; i < ARRAY_SIZE(kmx61_samp_freq_table); i++) | 301 | for (i = 0; i < ARRAY_SIZE(kmx61_samp_freq_table); i++) |
303 | if (val == kmx61_samp_freq_table[i].val && | 302 | if (val == kmx61_samp_freq_table[i].val && |
304 | val2 == kmx61_samp_freq_table[i].val2) | 303 | val2 == kmx61_samp_freq_table[i].val2) |
305 | return kmx61_samp_freq_table[i].odr_bits; | 304 | return i; |
306 | return -EINVAL; | 305 | return -EINVAL; |
307 | } | 306 | } |
308 | 307 | ||
309 | static int kmx61_convert_bit_to_freq(u8 odr_bits, int *val, int *val2) | ||
310 | { | ||
311 | int i; | ||
312 | |||
313 | for (i = 0; i < ARRAY_SIZE(kmx61_samp_freq_table); i++) | ||
314 | if (odr_bits == kmx61_samp_freq_table[i].odr_bits) { | ||
315 | *val = kmx61_samp_freq_table[i].val; | ||
316 | *val2 = kmx61_samp_freq_table[i].val2; | ||
317 | return 0; | ||
318 | } | ||
319 | return -EINVAL; | ||
320 | } | ||
321 | |||
322 | |||
323 | static int kmx61_convert_wake_up_odr_to_bit(int val, int val2) | 308 | static int kmx61_convert_wake_up_odr_to_bit(int val, int val2) |
324 | { | 309 | { |
325 | int i; | 310 | int i; |
@@ -478,7 +463,7 @@ static int kmx61_set_odr(struct kmx61_data *data, int val, int val2, u8 device) | |||
478 | 463 | ||
479 | static int kmx61_get_odr(struct kmx61_data *data, int *val, int *val2, | 464 | static int kmx61_get_odr(struct kmx61_data *data, int *val, int *val2, |
480 | u8 device) | 465 | u8 device) |
481 | { int i; | 466 | { |
482 | u8 lodr_bits; | 467 | u8 lodr_bits; |
483 | 468 | ||
484 | if (device & KMX61_ACC) | 469 | if (device & KMX61_ACC) |
@@ -490,13 +475,13 @@ static int kmx61_get_odr(struct kmx61_data *data, int *val, int *val2, | |||
490 | else | 475 | else |
491 | return -EINVAL; | 476 | return -EINVAL; |
492 | 477 | ||
493 | for (i = 0; i < ARRAY_SIZE(kmx61_samp_freq_table); i++) | 478 | if (lodr_bits >= ARRAY_SIZE(kmx61_samp_freq_table)) |
494 | if (lodr_bits == kmx61_samp_freq_table[i].odr_bits) { | 479 | return -EINVAL; |
495 | *val = kmx61_samp_freq_table[i].val; | 480 | |
496 | *val2 = kmx61_samp_freq_table[i].val2; | 481 | *val = kmx61_samp_freq_table[lodr_bits].val; |
497 | return 0; | 482 | *val2 = kmx61_samp_freq_table[lodr_bits].val2; |
498 | } | 483 | |
499 | return -EINVAL; | 484 | return 0; |
500 | } | 485 | } |
501 | 486 | ||
502 | static int kmx61_set_range(struct kmx61_data *data, u8 range) | 487 | static int kmx61_set_range(struct kmx61_data *data, u8 range) |
@@ -580,8 +565,11 @@ static int kmx61_chip_init(struct kmx61_data *data) | |||
580 | } | 565 | } |
581 | data->odr_bits = ret; | 566 | data->odr_bits = ret; |
582 | 567 | ||
583 | /* set output data rate for wake up (motion detection) function */ | 568 | /* |
584 | ret = kmx61_convert_bit_to_freq(data->odr_bits, &val, &val2); | 569 | * set output data rate for wake up (motion detection) function |
570 | * to match data rate for accelerometer sampling | ||
571 | */ | ||
572 | ret = kmx61_get_odr(data, &val, &val2, KMX61_ACC); | ||
585 | if (ret < 0) | 573 | if (ret < 0) |
586 | return ret; | 574 | return ret; |
587 | 575 | ||
@@ -1267,16 +1255,12 @@ static int kmx61_gpio_probe(struct i2c_client *client, struct kmx61_data *data) | |||
1267 | dev = &client->dev; | 1255 | dev = &client->dev; |
1268 | 1256 | ||
1269 | /* data ready gpio interrupt pin */ | 1257 | /* data ready gpio interrupt pin */ |
1270 | gpio = devm_gpiod_get_index(dev, KMX61_GPIO_NAME, 0); | 1258 | gpio = devm_gpiod_get_index(dev, KMX61_GPIO_NAME, 0, GPIOD_IN); |
1271 | if (IS_ERR(gpio)) { | 1259 | if (IS_ERR(gpio)) { |
1272 | dev_err(dev, "acpi gpio get index failed\n"); | 1260 | dev_err(dev, "acpi gpio get index failed\n"); |
1273 | return PTR_ERR(gpio); | 1261 | return PTR_ERR(gpio); |
1274 | } | 1262 | } |
1275 | 1263 | ||
1276 | ret = gpiod_direction_input(gpio); | ||
1277 | if (ret) | ||
1278 | return ret; | ||
1279 | |||
1280 | ret = gpiod_to_irq(gpio); | 1264 | ret = gpiod_to_irq(gpio); |
1281 | 1265 | ||
1282 | dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret); | 1266 | dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret); |
diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 71333140d42c..c2d5440aa226 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c | |||
@@ -761,6 +761,11 @@ static struct device_attribute dev_attr_length_ro = __ATTR(length, | |||
761 | static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, | 761 | static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, |
762 | iio_buffer_show_enable, iio_buffer_store_enable); | 762 | iio_buffer_show_enable, iio_buffer_store_enable); |
763 | 763 | ||
764 | static struct attribute *iio_buffer_attrs[] = { | ||
765 | &dev_attr_length.attr, | ||
766 | &dev_attr_enable.attr, | ||
767 | }; | ||
768 | |||
764 | int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev) | 769 | int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev) |
765 | { | 770 | { |
766 | struct iio_dev_attr *p; | 771 | struct iio_dev_attr *p; |
@@ -778,21 +783,23 @@ int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev) | |||
778 | attrcount++; | 783 | attrcount++; |
779 | } | 784 | } |
780 | 785 | ||
781 | buffer->buffer_group.name = "buffer"; | 786 | attr = kcalloc(attrcount + ARRAY_SIZE(iio_buffer_attrs) + 1, |
782 | buffer->buffer_group.attrs = kcalloc(attrcount + 3, | 787 | sizeof(struct attribute *), GFP_KERNEL); |
783 | sizeof(*buffer->buffer_group.attrs), GFP_KERNEL); | 788 | if (!attr) |
784 | if (!buffer->buffer_group.attrs) | ||
785 | return -ENOMEM; | 789 | return -ENOMEM; |
786 | 790 | ||
787 | if (buffer->access->set_length) | 791 | memcpy(attr, iio_buffer_attrs, sizeof(iio_buffer_attrs)); |
788 | buffer->buffer_group.attrs[0] = &dev_attr_length.attr; | 792 | if (!buffer->access->set_length) |
789 | else | 793 | attr[0] = &dev_attr_length_ro.attr; |
790 | buffer->buffer_group.attrs[0] = &dev_attr_length_ro.attr; | 794 | |
791 | buffer->buffer_group.attrs[1] = &dev_attr_enable.attr; | ||
792 | if (buffer->attrs) | 795 | if (buffer->attrs) |
793 | memcpy(&buffer->buffer_group.attrs[2], buffer->attrs, | 796 | memcpy(&attr[ARRAY_SIZE(iio_buffer_attrs)], buffer->attrs, |
794 | sizeof(*&buffer->buffer_group.attrs) * attrcount); | 797 | sizeof(struct attribute *) * attrcount); |
795 | buffer->buffer_group.attrs[attrcount+2] = NULL; | 798 | |
799 | attr[attrcount + ARRAY_SIZE(iio_buffer_attrs)] = NULL; | ||
800 | |||
801 | buffer->buffer_group.name = "buffer"; | ||
802 | buffer->buffer_group.attrs = attr; | ||
796 | 803 | ||
797 | indio_dev->groups[indio_dev->groupcounter++] = &buffer->buffer_group; | 804 | indio_dev->groups[indio_dev->groupcounter++] = &buffer->buffer_group; |
798 | 805 | ||
diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig index a224afd6380c..01a1a16ab7be 100644 --- a/drivers/iio/light/Kconfig +++ b/drivers/iio/light/Kconfig | |||
@@ -59,6 +59,16 @@ config CM3232 | |||
59 | To compile this driver as a module, choose M here: | 59 | To compile this driver as a module, choose M here: |
60 | the module will be called cm3232. | 60 | the module will be called cm3232. |
61 | 61 | ||
62 | config CM3323 | ||
63 | depends on I2C | ||
64 | tristate "Capella CM3323 color light sensor" | ||
65 | help | ||
66 | Say Y here if you want to build a driver for Capela CM3323 | ||
67 | color sensor. | ||
68 | |||
69 | To compile this driver as a module, choose M here: the module will | ||
70 | be called cm3323. | ||
71 | |||
62 | config CM36651 | 72 | config CM36651 |
63 | depends on I2C | 73 | depends on I2C |
64 | tristate "CM36651 driver" | 74 | tristate "CM36651 driver" |
diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile index b12a5160d9e0..ad7c30fe443b 100644 --- a/drivers/iio/light/Makefile +++ b/drivers/iio/light/Makefile | |||
@@ -8,6 +8,7 @@ obj-$(CONFIG_AL3320A) += al3320a.o | |||
8 | obj-$(CONFIG_APDS9300) += apds9300.o | 8 | obj-$(CONFIG_APDS9300) += apds9300.o |
9 | obj-$(CONFIG_CM32181) += cm32181.o | 9 | obj-$(CONFIG_CM32181) += cm32181.o |
10 | obj-$(CONFIG_CM3232) += cm3232.o | 10 | obj-$(CONFIG_CM3232) += cm3232.o |
11 | obj-$(CONFIG_CM3323) += cm3323.o | ||
11 | obj-$(CONFIG_CM36651) += cm36651.o | 12 | obj-$(CONFIG_CM36651) += cm36651.o |
12 | obj-$(CONFIG_GP2AP020A00F) += gp2ap020a00f.o | 13 | obj-$(CONFIG_GP2AP020A00F) += gp2ap020a00f.o |
13 | obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o | 14 | obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o |
diff --git a/drivers/iio/light/cm3232.c b/drivers/iio/light/cm3232.c index 90e3519a91de..39c8d99cc48e 100644 --- a/drivers/iio/light/cm3232.c +++ b/drivers/iio/light/cm3232.c | |||
@@ -378,6 +378,39 @@ static const struct i2c_device_id cm3232_id[] = { | |||
378 | {} | 378 | {} |
379 | }; | 379 | }; |
380 | 380 | ||
381 | #ifdef CONFIG_PM_SLEEP | ||
382 | static int cm3232_suspend(struct device *dev) | ||
383 | { | ||
384 | struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); | ||
385 | struct cm3232_chip *chip = iio_priv(indio_dev); | ||
386 | struct i2c_client *client = chip->client; | ||
387 | int ret; | ||
388 | |||
389 | chip->regs_cmd |= CM3232_CMD_ALS_DISABLE; | ||
390 | ret = i2c_smbus_write_byte_data(client, CM3232_REG_ADDR_CMD, | ||
391 | chip->regs_cmd); | ||
392 | |||
393 | return ret; | ||
394 | } | ||
395 | |||
396 | static int cm3232_resume(struct device *dev) | ||
397 | { | ||
398 | struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); | ||
399 | struct cm3232_chip *chip = iio_priv(indio_dev); | ||
400 | struct i2c_client *client = chip->client; | ||
401 | int ret; | ||
402 | |||
403 | chip->regs_cmd &= ~CM3232_CMD_ALS_DISABLE; | ||
404 | ret = i2c_smbus_write_byte_data(client, CM3232_REG_ADDR_CMD, | ||
405 | chip->regs_cmd | CM3232_CMD_ALS_RESET); | ||
406 | |||
407 | return ret; | ||
408 | } | ||
409 | |||
410 | static const struct dev_pm_ops cm3232_pm_ops = { | ||
411 | SET_SYSTEM_SLEEP_PM_OPS(cm3232_suspend, cm3232_resume)}; | ||
412 | #endif | ||
413 | |||
381 | MODULE_DEVICE_TABLE(i2c, cm3232_id); | 414 | MODULE_DEVICE_TABLE(i2c, cm3232_id); |
382 | 415 | ||
383 | static const struct of_device_id cm3232_of_match[] = { | 416 | static const struct of_device_id cm3232_of_match[] = { |
@@ -390,6 +423,9 @@ static struct i2c_driver cm3232_driver = { | |||
390 | .name = "cm3232", | 423 | .name = "cm3232", |
391 | .owner = THIS_MODULE, | 424 | .owner = THIS_MODULE, |
392 | .of_match_table = of_match_ptr(cm3232_of_match), | 425 | .of_match_table = of_match_ptr(cm3232_of_match), |
426 | #ifdef CONFIG_PM_SLEEP | ||
427 | .pm = &cm3232_pm_ops, | ||
428 | #endif | ||
393 | }, | 429 | }, |
394 | .id_table = cm3232_id, | 430 | .id_table = cm3232_id, |
395 | .probe = cm3232_probe, | 431 | .probe = cm3232_probe, |
diff --git a/drivers/iio/light/cm3323.c b/drivers/iio/light/cm3323.c new file mode 100644 index 000000000000..869033e48a1f --- /dev/null +++ b/drivers/iio/light/cm3323.c | |||
@@ -0,0 +1,286 @@ | |||
1 | /* | ||
2 | * CM3323 - Capella Color Light Sensor | ||
3 | * | ||
4 | * Copyright (c) 2015, Intel Corporation. | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of version 2 of | ||
7 | * the GNU General Public License. See the file COPYING in the main | ||
8 | * directory of this archive for more details. | ||
9 | * | ||
10 | * IIO driver for CM3323 (7-bit I2C slave address 0x10) | ||
11 | * | ||
12 | * TODO: calibscale to correct the lens factor | ||
13 | */ | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/i2c.h> | ||
17 | #include <linux/mutex.h> | ||
18 | |||
19 | #include <linux/iio/iio.h> | ||
20 | #include <linux/iio/sysfs.h> | ||
21 | |||
22 | #define CM3323_DRV_NAME "cm3323" | ||
23 | |||
24 | #define CM3323_CMD_CONF 0x00 | ||
25 | #define CM3323_CMD_RED_DATA 0x08 | ||
26 | #define CM3323_CMD_GREEN_DATA 0x09 | ||
27 | #define CM3323_CMD_BLUE_DATA 0x0A | ||
28 | #define CM3323_CMD_CLEAR_DATA 0x0B | ||
29 | |||
30 | #define CM3323_CONF_SD_BIT BIT(0) /* sensor disable */ | ||
31 | #define CM3323_CONF_AF_BIT BIT(1) /* auto/manual force mode */ | ||
32 | #define CM3323_CONF_IT_MASK (BIT(4) | BIT(5) | BIT(6)) | ||
33 | #define CM3323_CONF_IT_SHIFT 4 | ||
34 | |||
35 | #define CM3323_INT_TIME_AVAILABLE "0.04 0.08 0.16 0.32 0.64 1.28" | ||
36 | |||
37 | static const struct { | ||
38 | int val; | ||
39 | int val2; | ||
40 | } cm3323_int_time[] = { | ||
41 | {0, 40000}, /* 40 ms */ | ||
42 | {0, 80000}, /* 80 ms */ | ||
43 | {0, 160000}, /* 160 ms */ | ||
44 | {0, 320000}, /* 320 ms */ | ||
45 | {0, 640000}, /* 640 ms */ | ||
46 | {1, 280000}, /* 1280 ms */ | ||
47 | }; | ||
48 | |||
49 | struct cm3323_data { | ||
50 | struct i2c_client *client; | ||
51 | u16 reg_conf; | ||
52 | struct mutex mutex; | ||
53 | }; | ||
54 | |||
55 | #define CM3323_COLOR_CHANNEL(_color, _addr) { \ | ||
56 | .type = IIO_INTENSITY, \ | ||
57 | .modified = 1, \ | ||
58 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ | ||
59 | .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME), \ | ||
60 | .channel2 = IIO_MOD_LIGHT_##_color, \ | ||
61 | .address = _addr, \ | ||
62 | } | ||
63 | |||
64 | static const struct iio_chan_spec cm3323_channels[] = { | ||
65 | CM3323_COLOR_CHANNEL(RED, CM3323_CMD_RED_DATA), | ||
66 | CM3323_COLOR_CHANNEL(GREEN, CM3323_CMD_GREEN_DATA), | ||
67 | CM3323_COLOR_CHANNEL(BLUE, CM3323_CMD_BLUE_DATA), | ||
68 | CM3323_COLOR_CHANNEL(CLEAR, CM3323_CMD_CLEAR_DATA), | ||
69 | }; | ||
70 | |||
71 | static IIO_CONST_ATTR_INT_TIME_AVAIL(CM3323_INT_TIME_AVAILABLE); | ||
72 | |||
73 | static struct attribute *cm3323_attributes[] = { | ||
74 | &iio_const_attr_integration_time_available.dev_attr.attr, | ||
75 | NULL | ||
76 | }; | ||
77 | |||
78 | static const struct attribute_group cm3323_attribute_group = { | ||
79 | .attrs = cm3323_attributes, | ||
80 | }; | ||
81 | |||
82 | static int cm3323_init(struct iio_dev *indio_dev) | ||
83 | { | ||
84 | int ret; | ||
85 | struct cm3323_data *data = iio_priv(indio_dev); | ||
86 | |||
87 | ret = i2c_smbus_read_word_data(data->client, CM3323_CMD_CONF); | ||
88 | if (ret < 0) { | ||
89 | dev_err(&data->client->dev, "Error reading reg_conf\n"); | ||
90 | return ret; | ||
91 | } | ||
92 | |||
93 | /* enable sensor and set auto force mode */ | ||
94 | ret &= ~(CM3323_CONF_SD_BIT | CM3323_CONF_AF_BIT); | ||
95 | |||
96 | ret = i2c_smbus_write_word_data(data->client, CM3323_CMD_CONF, ret); | ||
97 | if (ret < 0) { | ||
98 | dev_err(&data->client->dev, "Error writing reg_conf\n"); | ||
99 | return ret; | ||
100 | } | ||
101 | |||
102 | data->reg_conf = ret; | ||
103 | |||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | static void cm3323_disable(struct iio_dev *indio_dev) | ||
108 | { | ||
109 | int ret; | ||
110 | struct cm3323_data *data = iio_priv(indio_dev); | ||
111 | |||
112 | ret = i2c_smbus_write_word_data(data->client, CM3323_CMD_CONF, | ||
113 | CM3323_CONF_SD_BIT); | ||
114 | if (ret < 0) | ||
115 | dev_err(&data->client->dev, "Error writing reg_conf\n"); | ||
116 | } | ||
117 | |||
118 | static int cm3323_set_it_bits(struct cm3323_data *data, int val, int val2) | ||
119 | { | ||
120 | int i, ret; | ||
121 | u16 reg_conf; | ||
122 | |||
123 | for (i = 0; i < ARRAY_SIZE(cm3323_int_time); i++) { | ||
124 | if (val == cm3323_int_time[i].val && | ||
125 | val2 == cm3323_int_time[i].val2) { | ||
126 | reg_conf = data->reg_conf; | ||
127 | reg_conf |= i << CM3323_CONF_IT_SHIFT; | ||
128 | |||
129 | ret = i2c_smbus_write_word_data(data->client, | ||
130 | CM3323_CMD_CONF, | ||
131 | reg_conf); | ||
132 | if (ret < 0) | ||
133 | return ret; | ||
134 | |||
135 | data->reg_conf = reg_conf; | ||
136 | return 0; | ||
137 | } | ||
138 | } | ||
139 | return -EINVAL; | ||
140 | } | ||
141 | |||
142 | static int cm3323_get_it_bits(struct cm3323_data *data) | ||
143 | { | ||
144 | int bits; | ||
145 | |||
146 | bits = (data->reg_conf & CM3323_CONF_IT_MASK) >> | ||
147 | CM3323_CONF_IT_SHIFT; | ||
148 | |||
149 | if (bits >= ARRAY_SIZE(cm3323_int_time)) | ||
150 | return -EINVAL; | ||
151 | return bits; | ||
152 | } | ||
153 | |||
154 | static int cm3323_read_raw(struct iio_dev *indio_dev, | ||
155 | struct iio_chan_spec const *chan, int *val, | ||
156 | int *val2, long mask) | ||
157 | { | ||
158 | int i, ret; | ||
159 | struct cm3323_data *data = iio_priv(indio_dev); | ||
160 | |||
161 | switch (mask) { | ||
162 | case IIO_CHAN_INFO_RAW: | ||
163 | mutex_lock(&data->mutex); | ||
164 | ret = i2c_smbus_read_word_data(data->client, chan->address); | ||
165 | if (ret < 0) { | ||
166 | mutex_unlock(&data->mutex); | ||
167 | return ret; | ||
168 | } | ||
169 | *val = ret; | ||
170 | mutex_unlock(&data->mutex); | ||
171 | |||
172 | return IIO_VAL_INT; | ||
173 | case IIO_CHAN_INFO_INT_TIME: | ||
174 | mutex_lock(&data->mutex); | ||
175 | i = cm3323_get_it_bits(data); | ||
176 | if (i < 0) { | ||
177 | mutex_unlock(&data->mutex); | ||
178 | return -EINVAL; | ||
179 | } | ||
180 | |||
181 | *val = cm3323_int_time[i].val; | ||
182 | *val2 = cm3323_int_time[i].val2; | ||
183 | mutex_unlock(&data->mutex); | ||
184 | |||
185 | return IIO_VAL_INT_PLUS_MICRO; | ||
186 | default: | ||
187 | return -EINVAL; | ||
188 | } | ||
189 | } | ||
190 | |||
191 | static int cm3323_write_raw(struct iio_dev *indio_dev, | ||
192 | struct iio_chan_spec const *chan, int val, | ||
193 | int val2, long mask) | ||
194 | { | ||
195 | struct cm3323_data *data = iio_priv(indio_dev); | ||
196 | int ret; | ||
197 | |||
198 | switch (mask) { | ||
199 | case IIO_CHAN_INFO_INT_TIME: | ||
200 | mutex_lock(&data->mutex); | ||
201 | ret = cm3323_set_it_bits(data, val, val2); | ||
202 | mutex_unlock(&data->mutex); | ||
203 | |||
204 | return ret; | ||
205 | default: | ||
206 | return -EINVAL; | ||
207 | } | ||
208 | } | ||
209 | |||
210 | static const struct iio_info cm3323_info = { | ||
211 | .driver_module = THIS_MODULE, | ||
212 | .read_raw = cm3323_read_raw, | ||
213 | .write_raw = cm3323_write_raw, | ||
214 | .attrs = &cm3323_attribute_group, | ||
215 | }; | ||
216 | |||
217 | static int cm3323_probe(struct i2c_client *client, | ||
218 | const struct i2c_device_id *id) | ||
219 | { | ||
220 | struct cm3323_data *data; | ||
221 | struct iio_dev *indio_dev; | ||
222 | int ret; | ||
223 | |||
224 | indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); | ||
225 | if (!indio_dev) | ||
226 | return -ENOMEM; | ||
227 | |||
228 | data = iio_priv(indio_dev); | ||
229 | i2c_set_clientdata(client, indio_dev); | ||
230 | data->client = client; | ||
231 | |||
232 | mutex_init(&data->mutex); | ||
233 | |||
234 | indio_dev->dev.parent = &client->dev; | ||
235 | indio_dev->info = &cm3323_info; | ||
236 | indio_dev->name = CM3323_DRV_NAME; | ||
237 | indio_dev->channels = cm3323_channels; | ||
238 | indio_dev->num_channels = ARRAY_SIZE(cm3323_channels); | ||
239 | indio_dev->modes = INDIO_DIRECT_MODE; | ||
240 | |||
241 | ret = cm3323_init(indio_dev); | ||
242 | if (ret < 0) { | ||
243 | dev_err(&client->dev, "cm3323 chip init failed\n"); | ||
244 | return ret; | ||
245 | } | ||
246 | ret = iio_device_register(indio_dev); | ||
247 | if (ret < 0) { | ||
248 | dev_err(&client->dev, "failed to register iio dev\n"); | ||
249 | goto err_init; | ||
250 | } | ||
251 | return 0; | ||
252 | err_init: | ||
253 | cm3323_disable(indio_dev); | ||
254 | return ret; | ||
255 | } | ||
256 | |||
257 | static int cm3323_remove(struct i2c_client *client) | ||
258 | { | ||
259 | struct iio_dev *indio_dev = i2c_get_clientdata(client); | ||
260 | |||
261 | iio_device_unregister(indio_dev); | ||
262 | cm3323_disable(indio_dev); | ||
263 | |||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | static const struct i2c_device_id cm3323_id[] = { | ||
268 | {"cm3323", 0}, | ||
269 | {} | ||
270 | }; | ||
271 | MODULE_DEVICE_TABLE(i2c, cm3323_id); | ||
272 | |||
273 | static struct i2c_driver cm3323_driver = { | ||
274 | .driver = { | ||
275 | .name = CM3323_DRV_NAME, | ||
276 | }, | ||
277 | .probe = cm3323_probe, | ||
278 | .remove = cm3323_remove, | ||
279 | .id_table = cm3323_id, | ||
280 | }; | ||
281 | |||
282 | module_i2c_driver(cm3323_driver); | ||
283 | |||
284 | MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com>"); | ||
285 | MODULE_DESCRIPTION("Capella CM3323 Color Light Sensor driver"); | ||
286 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/iio/light/gp2ap020a00f.c b/drivers/iio/light/gp2ap020a00f.c index 221ed16de1f7..32b6449833fa 100644 --- a/drivers/iio/light/gp2ap020a00f.c +++ b/drivers/iio/light/gp2ap020a00f.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/regmap.h> | 46 | #include <linux/regmap.h> |
47 | #include <linux/regulator/consumer.h> | 47 | #include <linux/regulator/consumer.h> |
48 | #include <linux/slab.h> | 48 | #include <linux/slab.h> |
49 | #include <asm/unaligned.h> | ||
49 | #include <linux/iio/buffer.h> | 50 | #include <linux/iio/buffer.h> |
50 | #include <linux/iio/events.h> | 51 | #include <linux/iio/events.h> |
51 | #include <linux/iio/iio.h> | 52 | #include <linux/iio/iio.h> |
@@ -966,7 +967,6 @@ static irqreturn_t gp2ap020a00f_trigger_handler(int irq, void *data) | |||
966 | struct iio_dev *indio_dev = pf->indio_dev; | 967 | struct iio_dev *indio_dev = pf->indio_dev; |
967 | struct gp2ap020a00f_data *priv = iio_priv(indio_dev); | 968 | struct gp2ap020a00f_data *priv = iio_priv(indio_dev); |
968 | size_t d_size = 0; | 969 | size_t d_size = 0; |
969 | __le32 light_lux; | ||
970 | int i, out_val, ret; | 970 | int i, out_val, ret; |
971 | 971 | ||
972 | for_each_set_bit(i, indio_dev->active_scan_mask, | 972 | for_each_set_bit(i, indio_dev->active_scan_mask, |
@@ -981,8 +981,8 @@ static irqreturn_t gp2ap020a00f_trigger_handler(int irq, void *data) | |||
981 | i == GP2AP020A00F_SCAN_MODE_LIGHT_IR) { | 981 | i == GP2AP020A00F_SCAN_MODE_LIGHT_IR) { |
982 | out_val = le16_to_cpup((__le16 *)&priv->buffer[d_size]); | 982 | out_val = le16_to_cpup((__le16 *)&priv->buffer[d_size]); |
983 | gp2ap020a00f_output_to_lux(priv, &out_val); | 983 | gp2ap020a00f_output_to_lux(priv, &out_val); |
984 | light_lux = cpu_to_le32(out_val); | 984 | |
985 | memcpy(&priv->buffer[d_size], (u8 *)&light_lux, 4); | 985 | put_unaligned_le32(out_val, &priv->buffer[d_size]); |
986 | d_size += 4; | 986 | d_size += 4; |
987 | } else { | 987 | } else { |
988 | d_size += 2; | 988 | d_size += 2; |
diff --git a/drivers/iio/light/jsa1212.c b/drivers/iio/light/jsa1212.c index 29de7e7d9562..3a3af89beaf9 100644 --- a/drivers/iio/light/jsa1212.c +++ b/drivers/iio/light/jsa1212.c | |||
@@ -308,7 +308,7 @@ static bool jsa1212_is_volatile_reg(struct device *dev, unsigned int reg) | |||
308 | } | 308 | } |
309 | } | 309 | } |
310 | 310 | ||
311 | static struct regmap_config jsa1212_regmap_config = { | 311 | static const struct regmap_config jsa1212_regmap_config = { |
312 | .name = JSA1212_REGMAP_NAME, | 312 | .name = JSA1212_REGMAP_NAME, |
313 | .reg_bits = 8, | 313 | .reg_bits = 8, |
314 | .val_bits = 8, | 314 | .val_bits = 8, |
diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig index a3be53792072..fa6295041947 100644 --- a/drivers/iio/pressure/Kconfig +++ b/drivers/iio/pressure/Kconfig | |||
@@ -52,6 +52,33 @@ config MPL3115 | |||
52 | To compile this driver as a module, choose M here: the module | 52 | To compile this driver as a module, choose M here: the module |
53 | will be called mpl3115. | 53 | will be called mpl3115. |
54 | 54 | ||
55 | config MS5611 | ||
56 | tristate "Measurement Specialities MS5611 pressure sensor driver" | ||
57 | help | ||
58 | Say Y here to build support for the Measurement Specialities | ||
59 | MS5611 pressure and temperature sensor. | ||
60 | |||
61 | To compile this driver as a module, choose M here: the module will | ||
62 | be called ms5611_core. | ||
63 | |||
64 | config MS5611_I2C | ||
65 | tristate "support I2C bus connection" | ||
66 | depends on I2C && MS5611 | ||
67 | help | ||
68 | Say Y here to build I2C bus support for MS5611. | ||
69 | |||
70 | To compile this driver as a module, choose M here: the module will | ||
71 | be called ms5611_i2c. | ||
72 | |||
73 | config MS5611_SPI | ||
74 | tristate "support SPI bus connection" | ||
75 | depends on SPI_MASTER && MS5611 | ||
76 | help | ||
77 | Say Y here to build SPI bus support for MS5611. | ||
78 | |||
79 | To compile this driver as a module, choose M here: the module will | ||
80 | be called ms5611_spi. | ||
81 | |||
55 | config IIO_ST_PRESS | 82 | config IIO_ST_PRESS |
56 | tristate "STMicroelectronics pressure sensor Driver" | 83 | tristate "STMicroelectronics pressure sensor Driver" |
57 | depends on (I2C || SPI_MASTER) && SYSFS | 84 | depends on (I2C || SPI_MASTER) && SYSFS |
diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile index 88011f2ae00e..a4f98f8d90ed 100644 --- a/drivers/iio/pressure/Makefile +++ b/drivers/iio/pressure/Makefile | |||
@@ -7,6 +7,9 @@ obj-$(CONFIG_BMP280) += bmp280.o | |||
7 | obj-$(CONFIG_HID_SENSOR_PRESS) += hid-sensor-press.o | 7 | obj-$(CONFIG_HID_SENSOR_PRESS) += hid-sensor-press.o |
8 | obj-$(CONFIG_MPL115) += mpl115.o | 8 | obj-$(CONFIG_MPL115) += mpl115.o |
9 | obj-$(CONFIG_MPL3115) += mpl3115.o | 9 | obj-$(CONFIG_MPL3115) += mpl3115.o |
10 | obj-$(CONFIG_MS5611) += ms5611_core.o | ||
11 | obj-$(CONFIG_MS5611_I2C) += ms5611_i2c.o | ||
12 | obj-$(CONFIG_MS5611_SPI) += ms5611_spi.o | ||
10 | obj-$(CONFIG_IIO_ST_PRESS) += st_pressure.o | 13 | obj-$(CONFIG_IIO_ST_PRESS) += st_pressure.o |
11 | st_pressure-y := st_pressure_core.o | 14 | st_pressure-y := st_pressure_core.o |
12 | st_pressure-$(CONFIG_IIO_BUFFER) += st_pressure_buffer.o | 15 | st_pressure-$(CONFIG_IIO_BUFFER) += st_pressure_buffer.o |
diff --git a/drivers/iio/pressure/ms5611.h b/drivers/iio/pressure/ms5611.h new file mode 100644 index 000000000000..099c6cdea43f --- /dev/null +++ b/drivers/iio/pressure/ms5611.h | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | * MS5611 pressure and temperature sensor driver | ||
3 | * | ||
4 | * Copyright (c) Tomasz Duszynski <tduszyns@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #ifndef _MS5611_H | ||
13 | #define _MS5611_H | ||
14 | |||
15 | #include <linux/device.h> | ||
16 | #include <linux/iio/iio.h> | ||
17 | #include <linux/mutex.h> | ||
18 | |||
19 | #define MS5611_RESET 0x1e | ||
20 | #define MS5611_READ_ADC 0x00 | ||
21 | #define MS5611_READ_PROM_WORD 0xA0 | ||
22 | #define MS5611_START_TEMP_CONV 0x58 | ||
23 | #define MS5611_START_PRESSURE_CONV 0x48 | ||
24 | |||
25 | #define MS5611_CONV_TIME_MIN 9040 | ||
26 | #define MS5611_CONV_TIME_MAX 10000 | ||
27 | |||
28 | #define MS5611_PROM_WORDS_NB 8 | ||
29 | |||
30 | struct ms5611_state { | ||
31 | void *client; | ||
32 | struct mutex lock; | ||
33 | |||
34 | int (*reset)(struct device *dev); | ||
35 | int (*read_prom_word)(struct device *dev, int index, u16 *word); | ||
36 | int (*read_adc_temp_and_pressure)(struct device *dev, | ||
37 | s32 *temp, s32 *pressure); | ||
38 | |||
39 | u16 prom[MS5611_PROM_WORDS_NB]; | ||
40 | }; | ||
41 | |||
42 | int ms5611_probe(struct iio_dev *indio_dev, struct device *dev); | ||
43 | |||
44 | #endif /* _MS5611_H */ | ||
diff --git a/drivers/iio/pressure/ms5611_core.c b/drivers/iio/pressure/ms5611_core.c new file mode 100644 index 000000000000..e42c8531d9b3 --- /dev/null +++ b/drivers/iio/pressure/ms5611_core.c | |||
@@ -0,0 +1,215 @@ | |||
1 | /* | ||
2 | * MS5611 pressure and temperature sensor driver | ||
3 | * | ||
4 | * Copyright (c) Tomasz Duszynski <tduszyns@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * Data sheet: | ||
11 | * http://www.meas-spec.com/downloads/MS5611-01BA03.pdf | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | #include <linux/iio/iio.h> | ||
17 | #include <linux/delay.h> | ||
18 | |||
19 | #include "ms5611.h" | ||
20 | |||
21 | static bool ms5611_prom_is_valid(u16 *prom, size_t len) | ||
22 | { | ||
23 | int i, j; | ||
24 | uint16_t crc = 0, crc_orig = prom[7] & 0x000F; | ||
25 | |||
26 | prom[7] &= 0xFF00; | ||
27 | |||
28 | for (i = 0; i < len * 2; i++) { | ||
29 | if (i % 2 == 1) | ||
30 | crc ^= prom[i >> 1] & 0x00FF; | ||
31 | else | ||
32 | crc ^= prom[i >> 1] >> 8; | ||
33 | |||
34 | for (j = 0; j < 8; j++) { | ||
35 | if (crc & 0x8000) | ||
36 | crc = (crc << 1) ^ 0x3000; | ||
37 | else | ||
38 | crc <<= 1; | ||
39 | } | ||
40 | } | ||
41 | |||
42 | crc = (crc >> 12) & 0x000F; | ||
43 | |||
44 | return crc_orig != 0x0000 && crc == crc_orig; | ||
45 | } | ||
46 | |||
47 | static int ms5611_read_prom(struct iio_dev *indio_dev) | ||
48 | { | ||
49 | int ret, i; | ||
50 | struct ms5611_state *st = iio_priv(indio_dev); | ||
51 | |||
52 | for (i = 0; i < MS5611_PROM_WORDS_NB; i++) { | ||
53 | ret = st->read_prom_word(&indio_dev->dev, i, &st->prom[i]); | ||
54 | if (ret < 0) { | ||
55 | dev_err(&indio_dev->dev, | ||
56 | "failed to read prom at %d\n", i); | ||
57 | return ret; | ||
58 | } | ||
59 | } | ||
60 | |||
61 | if (!ms5611_prom_is_valid(st->prom, MS5611_PROM_WORDS_NB)) { | ||
62 | dev_err(&indio_dev->dev, "PROM integrity check failed\n"); | ||
63 | return -ENODEV; | ||
64 | } | ||
65 | |||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | static int ms5611_read_temp_and_pressure(struct iio_dev *indio_dev, | ||
70 | s32 *temp, s32 *pressure) | ||
71 | { | ||
72 | int ret; | ||
73 | s32 t, p; | ||
74 | s64 off, sens, dt; | ||
75 | struct ms5611_state *st = iio_priv(indio_dev); | ||
76 | |||
77 | ret = st->read_adc_temp_and_pressure(&indio_dev->dev, &t, &p); | ||
78 | if (ret < 0) { | ||
79 | dev_err(&indio_dev->dev, | ||
80 | "failed to read temperature and pressure\n"); | ||
81 | return ret; | ||
82 | } | ||
83 | |||
84 | dt = t - (st->prom[5] << 8); | ||
85 | off = ((s64)st->prom[2] << 16) + ((st->prom[4] * dt) >> 7); | ||
86 | sens = ((s64)st->prom[1] << 15) + ((st->prom[3] * dt) >> 8); | ||
87 | |||
88 | t = 2000 + ((st->prom[6] * dt) >> 23); | ||
89 | if (t < 2000) { | ||
90 | s64 off2, sens2, t2; | ||
91 | |||
92 | t2 = (dt * dt) >> 31; | ||
93 | off2 = (5 * (t - 2000) * (t - 2000)) >> 1; | ||
94 | sens2 = off2 >> 1; | ||
95 | |||
96 | if (t < -1500) { | ||
97 | s64 tmp = (t + 1500) * (t + 1500); | ||
98 | |||
99 | off2 += 7 * tmp; | ||
100 | sens2 += (11 * tmp) >> 1; | ||
101 | } | ||
102 | |||
103 | t -= t2; | ||
104 | off -= off2; | ||
105 | sens -= sens2; | ||
106 | } | ||
107 | |||
108 | *temp = t; | ||
109 | *pressure = (((p * sens) >> 21) - off) >> 15; | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | static int ms5611_reset(struct iio_dev *indio_dev) | ||
115 | { | ||
116 | int ret; | ||
117 | struct ms5611_state *st = iio_priv(indio_dev); | ||
118 | |||
119 | ret = st->reset(&indio_dev->dev); | ||
120 | if (ret < 0) { | ||
121 | dev_err(&indio_dev->dev, "failed to reset device\n"); | ||
122 | return ret; | ||
123 | } | ||
124 | |||
125 | usleep_range(3000, 4000); | ||
126 | |||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | static int ms5611_read_raw(struct iio_dev *indio_dev, | ||
131 | struct iio_chan_spec const *chan, | ||
132 | int *val, int *val2, long mask) | ||
133 | { | ||
134 | int ret; | ||
135 | s32 temp, pressure; | ||
136 | struct ms5611_state *st = iio_priv(indio_dev); | ||
137 | |||
138 | switch (mask) { | ||
139 | case IIO_CHAN_INFO_PROCESSED: | ||
140 | mutex_lock(&st->lock); | ||
141 | ret = ms5611_read_temp_and_pressure(indio_dev, | ||
142 | &temp, &pressure); | ||
143 | mutex_unlock(&st->lock); | ||
144 | if (ret < 0) | ||
145 | return ret; | ||
146 | |||
147 | switch (chan->type) { | ||
148 | case IIO_TEMP: | ||
149 | *val = temp * 10; | ||
150 | return IIO_VAL_INT; | ||
151 | case IIO_PRESSURE: | ||
152 | *val = pressure / 1000; | ||
153 | *val2 = (pressure % 1000) * 1000; | ||
154 | return IIO_VAL_INT_PLUS_MICRO; | ||
155 | default: | ||
156 | return -EINVAL; | ||
157 | } | ||
158 | } | ||
159 | |||
160 | return -EINVAL; | ||
161 | } | ||
162 | |||
163 | static const struct iio_chan_spec ms5611_channels[] = { | ||
164 | { | ||
165 | .type = IIO_PRESSURE, | ||
166 | .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | | ||
167 | BIT(IIO_CHAN_INFO_SCALE) | ||
168 | }, | ||
169 | { | ||
170 | .type = IIO_TEMP, | ||
171 | .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | | ||
172 | BIT(IIO_CHAN_INFO_SCALE) | ||
173 | } | ||
174 | }; | ||
175 | |||
176 | static const struct iio_info ms5611_info = { | ||
177 | .read_raw = &ms5611_read_raw, | ||
178 | .driver_module = THIS_MODULE, | ||
179 | }; | ||
180 | |||
181 | static int ms5611_init(struct iio_dev *indio_dev) | ||
182 | { | ||
183 | int ret; | ||
184 | |||
185 | ret = ms5611_reset(indio_dev); | ||
186 | if (ret < 0) | ||
187 | return ret; | ||
188 | |||
189 | return ms5611_read_prom(indio_dev); | ||
190 | } | ||
191 | |||
192 | int ms5611_probe(struct iio_dev *indio_dev, struct device *dev) | ||
193 | { | ||
194 | int ret; | ||
195 | struct ms5611_state *st = iio_priv(indio_dev); | ||
196 | |||
197 | mutex_init(&st->lock); | ||
198 | indio_dev->dev.parent = dev; | ||
199 | indio_dev->name = dev->driver->name; | ||
200 | indio_dev->info = &ms5611_info; | ||
201 | indio_dev->channels = ms5611_channels; | ||
202 | indio_dev->num_channels = ARRAY_SIZE(ms5611_channels); | ||
203 | indio_dev->modes = INDIO_DIRECT_MODE; | ||
204 | |||
205 | ret = ms5611_init(indio_dev); | ||
206 | if (ret < 0) | ||
207 | return ret; | ||
208 | |||
209 | return devm_iio_device_register(dev, indio_dev); | ||
210 | } | ||
211 | EXPORT_SYMBOL(ms5611_probe); | ||
212 | |||
213 | MODULE_AUTHOR("Tomasz Duszynski <tduszyns@gmail.com>"); | ||
214 | MODULE_DESCRIPTION("MS5611 core driver"); | ||
215 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/iio/pressure/ms5611_i2c.c b/drivers/iio/pressure/ms5611_i2c.c new file mode 100644 index 000000000000..748fd9acaad8 --- /dev/null +++ b/drivers/iio/pressure/ms5611_i2c.c | |||
@@ -0,0 +1,128 @@ | |||
1 | /* | ||
2 | * MS5611 pressure and temperature sensor driver (I2C bus) | ||
3 | * | ||
4 | * Copyright (c) Tomasz Duszynski <tduszyns@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * 7-bit I2C slave addresses: | ||
11 | * | ||
12 | * 0x77 (CSB pin low) | ||
13 | * 0x76 (CSB pin high) | ||
14 | * | ||
15 | */ | ||
16 | |||
17 | #include <linux/delay.h> | ||
18 | #include <linux/i2c.h> | ||
19 | #include <linux/module.h> | ||
20 | |||
21 | #include "ms5611.h" | ||
22 | |||
23 | static int ms5611_i2c_reset(struct device *dev) | ||
24 | { | ||
25 | struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev)); | ||
26 | |||
27 | return i2c_smbus_write_byte(st->client, MS5611_RESET); | ||
28 | } | ||
29 | |||
30 | static int ms5611_i2c_read_prom_word(struct device *dev, int index, u16 *word) | ||
31 | { | ||
32 | int ret; | ||
33 | struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev)); | ||
34 | |||
35 | ret = i2c_smbus_read_word_swapped(st->client, | ||
36 | MS5611_READ_PROM_WORD + (index << 1)); | ||
37 | if (ret < 0) | ||
38 | return ret; | ||
39 | |||
40 | *word = ret; | ||
41 | |||
42 | return 0; | ||
43 | } | ||
44 | |||
45 | static int ms5611_i2c_read_adc(struct ms5611_state *st, s32 *val) | ||
46 | { | ||
47 | int ret; | ||
48 | u8 buf[3]; | ||
49 | |||
50 | ret = i2c_smbus_read_i2c_block_data(st->client, MS5611_READ_ADC, | ||
51 | 3, buf); | ||
52 | if (ret < 0) | ||
53 | return ret; | ||
54 | |||
55 | *val = (buf[0] << 16) | (buf[1] << 8) | buf[2]; | ||
56 | |||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | static int ms5611_i2c_read_adc_temp_and_pressure(struct device *dev, | ||
61 | s32 *temp, s32 *pressure) | ||
62 | { | ||
63 | int ret; | ||
64 | struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev)); | ||
65 | |||
66 | ret = i2c_smbus_write_byte(st->client, MS5611_START_TEMP_CONV); | ||
67 | if (ret < 0) | ||
68 | return ret; | ||
69 | |||
70 | usleep_range(MS5611_CONV_TIME_MIN, MS5611_CONV_TIME_MAX); | ||
71 | |||
72 | ret = ms5611_i2c_read_adc(st, temp); | ||
73 | if (ret < 0) | ||
74 | return ret; | ||
75 | |||
76 | ret = i2c_smbus_write_byte(st->client, MS5611_START_PRESSURE_CONV); | ||
77 | if (ret < 0) | ||
78 | return ret; | ||
79 | |||
80 | usleep_range(MS5611_CONV_TIME_MIN, MS5611_CONV_TIME_MAX); | ||
81 | |||
82 | return ms5611_i2c_read_adc(st, pressure); | ||
83 | } | ||
84 | |||
85 | static int ms5611_i2c_probe(struct i2c_client *client, | ||
86 | const struct i2c_device_id *id) | ||
87 | { | ||
88 | struct ms5611_state *st; | ||
89 | struct iio_dev *indio_dev; | ||
90 | |||
91 | if (!i2c_check_functionality(client->adapter, | ||
92 | I2C_FUNC_SMBUS_WRITE_BYTE | | ||
93 | I2C_FUNC_SMBUS_READ_WORD_DATA | | ||
94 | I2C_FUNC_SMBUS_READ_I2C_BLOCK)) | ||
95 | return -ENODEV; | ||
96 | |||
97 | indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st)); | ||
98 | if (!indio_dev) | ||
99 | return -ENOMEM; | ||
100 | |||
101 | st = iio_priv(indio_dev); | ||
102 | st->reset = ms5611_i2c_reset; | ||
103 | st->read_prom_word = ms5611_i2c_read_prom_word; | ||
104 | st->read_adc_temp_and_pressure = ms5611_i2c_read_adc_temp_and_pressure; | ||
105 | st->client = client; | ||
106 | |||
107 | return ms5611_probe(indio_dev, &client->dev); | ||
108 | } | ||
109 | |||
110 | static const struct i2c_device_id ms5611_id[] = { | ||
111 | { "ms5611", 0 }, | ||
112 | { } | ||
113 | }; | ||
114 | MODULE_DEVICE_TABLE(i2c, ms5611_id); | ||
115 | |||
116 | static struct i2c_driver ms5611_driver = { | ||
117 | .driver = { | ||
118 | .name = "ms5611", | ||
119 | .owner = THIS_MODULE, | ||
120 | }, | ||
121 | .id_table = ms5611_id, | ||
122 | .probe = ms5611_i2c_probe, | ||
123 | }; | ||
124 | module_i2c_driver(ms5611_driver); | ||
125 | |||
126 | MODULE_AUTHOR("Tomasz Duszynski <tduszyns@gmail.com>"); | ||
127 | MODULE_DESCRIPTION("MS5611 i2c driver"); | ||
128 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/iio/pressure/ms5611_spi.c b/drivers/iio/pressure/ms5611_spi.c new file mode 100644 index 000000000000..976726fd4e6c --- /dev/null +++ b/drivers/iio/pressure/ms5611_spi.c | |||
@@ -0,0 +1,127 @@ | |||
1 | /* | ||
2 | * MS5611 pressure and temperature sensor driver (SPI bus) | ||
3 | * | ||
4 | * Copyright (c) Tomasz Duszynski <tduszyns@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/delay.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/spi/spi.h> | ||
15 | |||
16 | #include "ms5611.h" | ||
17 | |||
18 | static int ms5611_spi_reset(struct device *dev) | ||
19 | { | ||
20 | u8 cmd = MS5611_RESET; | ||
21 | struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev)); | ||
22 | |||
23 | return spi_write_then_read(st->client, &cmd, 1, NULL, 0); | ||
24 | } | ||
25 | |||
26 | static int ms5611_spi_read_prom_word(struct device *dev, int index, u16 *word) | ||
27 | { | ||
28 | int ret; | ||
29 | struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev)); | ||
30 | |||
31 | ret = spi_w8r16be(st->client, MS5611_READ_PROM_WORD + (index << 1)); | ||
32 | if (ret < 0) | ||
33 | return ret; | ||
34 | |||
35 | *word = ret; | ||
36 | |||
37 | return 0; | ||
38 | } | ||
39 | |||
40 | static int ms5611_spi_read_adc(struct device *dev, s32 *val) | ||
41 | { | ||
42 | int ret; | ||
43 | u8 buf[3] = { MS5611_READ_ADC }; | ||
44 | struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev)); | ||
45 | |||
46 | ret = spi_write_then_read(st->client, buf, 1, buf, 3); | ||
47 | if (ret < 0) | ||
48 | return ret; | ||
49 | |||
50 | *val = (buf[0] << 16) | (buf[1] << 8) | buf[2]; | ||
51 | |||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | static int ms5611_spi_read_adc_temp_and_pressure(struct device *dev, | ||
56 | s32 *temp, s32 *pressure) | ||
57 | { | ||
58 | u8 cmd; | ||
59 | int ret; | ||
60 | struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev)); | ||
61 | |||
62 | cmd = MS5611_START_TEMP_CONV; | ||
63 | ret = spi_write_then_read(st->client, &cmd, 1, NULL, 0); | ||
64 | if (ret < 0) | ||
65 | return ret; | ||
66 | |||
67 | usleep_range(MS5611_CONV_TIME_MIN, MS5611_CONV_TIME_MAX); | ||
68 | |||
69 | ret = ms5611_spi_read_adc(dev, temp); | ||
70 | if (ret < 0) | ||
71 | return ret; | ||
72 | |||
73 | cmd = MS5611_START_PRESSURE_CONV; | ||
74 | ret = spi_write_then_read(st->client, &cmd, 1, NULL, 0); | ||
75 | if (ret < 0) | ||
76 | return ret; | ||
77 | |||
78 | usleep_range(MS5611_CONV_TIME_MIN, MS5611_CONV_TIME_MAX); | ||
79 | |||
80 | return ms5611_spi_read_adc(dev, pressure); | ||
81 | } | ||
82 | |||
83 | static int ms5611_spi_probe(struct spi_device *spi) | ||
84 | { | ||
85 | int ret; | ||
86 | struct ms5611_state *st; | ||
87 | struct iio_dev *indio_dev; | ||
88 | |||
89 | indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); | ||
90 | if (!indio_dev) | ||
91 | return -ENOMEM; | ||
92 | |||
93 | spi->mode = SPI_MODE_0; | ||
94 | spi->max_speed_hz = 20000000; | ||
95 | spi->bits_per_word = 8; | ||
96 | ret = spi_setup(spi); | ||
97 | if (ret < 0) | ||
98 | return ret; | ||
99 | |||
100 | st = iio_priv(indio_dev); | ||
101 | st->reset = ms5611_spi_reset; | ||
102 | st->read_prom_word = ms5611_spi_read_prom_word; | ||
103 | st->read_adc_temp_and_pressure = ms5611_spi_read_adc_temp_and_pressure; | ||
104 | st->client = spi; | ||
105 | |||
106 | return ms5611_probe(indio_dev, &spi->dev); | ||
107 | } | ||
108 | |||
109 | static const struct spi_device_id ms5611_id[] = { | ||
110 | { "ms5611", 0 }, | ||
111 | { } | ||
112 | }; | ||
113 | MODULE_DEVICE_TABLE(spi, ms5611_id); | ||
114 | |||
115 | static struct spi_driver ms5611_driver = { | ||
116 | .driver = { | ||
117 | .name = "ms5611", | ||
118 | .owner = THIS_MODULE, | ||
119 | }, | ||
120 | .id_table = ms5611_id, | ||
121 | .probe = ms5611_spi_probe, | ||
122 | }; | ||
123 | module_spi_driver(ms5611_driver); | ||
124 | |||
125 | MODULE_AUTHOR("Tomasz Duszynski <tduszyns@gmail.com>"); | ||
126 | MODULE_DESCRIPTION("MS5611 spi driver"); | ||
127 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/iio/proximity/sx9500.c b/drivers/iio/proximity/sx9500.c index 74dff4e4a11a..0b4d79490b05 100644 --- a/drivers/iio/proximity/sx9500.c +++ b/drivers/iio/proximity/sx9500.c | |||
@@ -618,16 +618,12 @@ static int sx9500_gpio_probe(struct i2c_client *client, | |||
618 | dev = &client->dev; | 618 | dev = &client->dev; |
619 | 619 | ||
620 | /* data ready gpio interrupt pin */ | 620 | /* data ready gpio interrupt pin */ |
621 | gpio = devm_gpiod_get_index(dev, SX9500_GPIO_NAME, 0); | 621 | gpio = devm_gpiod_get_index(dev, SX9500_GPIO_NAME, 0, GPIOD_IN); |
622 | if (IS_ERR(gpio)) { | 622 | if (IS_ERR(gpio)) { |
623 | dev_err(dev, "acpi gpio get index failed\n"); | 623 | dev_err(dev, "acpi gpio get index failed\n"); |
624 | return PTR_ERR(gpio); | 624 | return PTR_ERR(gpio); |
625 | } | 625 | } |
626 | 626 | ||
627 | ret = gpiod_direction_input(gpio); | ||
628 | if (ret) | ||
629 | return ret; | ||
630 | |||
631 | ret = gpiod_to_irq(gpio); | 627 | ret = gpiod_to_irq(gpio); |
632 | 628 | ||
633 | dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret); | 629 | dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret); |
diff --git a/drivers/iio/temperature/mlx90614.c b/drivers/iio/temperature/mlx90614.c index c8b6ac8b2d69..e2c6f1a0d27f 100644 --- a/drivers/iio/temperature/mlx90614.c +++ b/drivers/iio/temperature/mlx90614.c | |||
@@ -23,8 +23,8 @@ | |||
23 | #define MLX90614_OP_RAM 0x00 | 23 | #define MLX90614_OP_RAM 0x00 |
24 | 24 | ||
25 | /* RAM offsets with 16-bit data, MSB first */ | 25 | /* RAM offsets with 16-bit data, MSB first */ |
26 | #define MLX90614_TA 0x06 /* ambient temperature */ | 26 | #define MLX90614_TA (MLX90614_OP_RAM | 0x06) /* ambient temperature */ |
27 | #define MLX90614_TOBJ1 0x07 /* object temperature */ | 27 | #define MLX90614_TOBJ1 (MLX90614_OP_RAM | 0x07) /* object 1 temperature */ |
28 | 28 | ||
29 | struct mlx90614_data { | 29 | struct mlx90614_data { |
30 | struct i2c_client *client; | 30 | struct i2c_client *client; |
@@ -42,13 +42,13 @@ static int mlx90614_read_raw(struct iio_dev *indio_dev, | |||
42 | switch (channel->channel2) { | 42 | switch (channel->channel2) { |
43 | case IIO_MOD_TEMP_AMBIENT: | 43 | case IIO_MOD_TEMP_AMBIENT: |
44 | ret = i2c_smbus_read_word_data(data->client, | 44 | ret = i2c_smbus_read_word_data(data->client, |
45 | MLX90614_OP_RAM | MLX90614_TA); | 45 | MLX90614_TA); |
46 | if (ret < 0) | 46 | if (ret < 0) |
47 | return ret; | 47 | return ret; |
48 | break; | 48 | break; |
49 | case IIO_MOD_TEMP_OBJECT: | 49 | case IIO_MOD_TEMP_OBJECT: |
50 | ret = i2c_smbus_read_word_data(data->client, | 50 | ret = i2c_smbus_read_word_data(data->client, |
51 | MLX90614_OP_RAM | MLX90614_TOBJ1); | 51 | MLX90614_TOBJ1); |
52 | if (ret < 0) | 52 | if (ret < 0) |
53 | return ret; | 53 | return ret; |
54 | break; | 54 | break; |
diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c index 816174388f13..17f4ee7f8b76 100644 --- a/drivers/staging/iio/adc/mxs-lradc.c +++ b/drivers/staging/iio/adc/mxs-lradc.c | |||
@@ -993,7 +993,7 @@ static ssize_t mxs_lradc_show_scale_available_ch(struct device *dev, | |||
993 | int i, len = 0; | 993 | int i, len = 0; |
994 | 994 | ||
995 | for (i = 0; i < ARRAY_SIZE(lradc->scale_avail[ch]); i++) | 995 | for (i = 0; i < ARRAY_SIZE(lradc->scale_avail[ch]); i++) |
996 | len += sprintf(buf + len, "%d.%09u ", | 996 | len += sprintf(buf + len, "%u.%09u ", |
997 | lradc->scale_avail[ch][i].integer, | 997 | lradc->scale_avail[ch][i].integer, |
998 | lradc->scale_avail[ch][i].nano); | 998 | lradc->scale_avail[ch][i].nano); |
999 | 999 | ||
diff --git a/drivers/staging/iio/magnetometer/hmc5843_i2c.c b/drivers/staging/iio/magnetometer/hmc5843_i2c.c index 6b4c74236916..ff08667fa2f6 100644 --- a/drivers/staging/iio/magnetometer/hmc5843_i2c.c +++ b/drivers/staging/iio/magnetometer/hmc5843_i2c.c | |||
@@ -19,41 +19,41 @@ | |||
19 | #include "hmc5843.h" | 19 | #include "hmc5843.h" |
20 | 20 | ||
21 | static const struct regmap_range hmc5843_readable_ranges[] = { | 21 | static const struct regmap_range hmc5843_readable_ranges[] = { |
22 | regmap_reg_range(0, HMC5843_ID_END), | 22 | regmap_reg_range(0, HMC5843_ID_END), |
23 | }; | 23 | }; |
24 | 24 | ||
25 | static struct regmap_access_table hmc5843_readable_table = { | 25 | static const struct regmap_access_table hmc5843_readable_table = { |
26 | .yes_ranges = hmc5843_readable_ranges, | 26 | .yes_ranges = hmc5843_readable_ranges, |
27 | .n_yes_ranges = ARRAY_SIZE(hmc5843_readable_ranges), | 27 | .n_yes_ranges = ARRAY_SIZE(hmc5843_readable_ranges), |
28 | }; | 28 | }; |
29 | 29 | ||
30 | static const struct regmap_range hmc5843_writable_ranges[] = { | 30 | static const struct regmap_range hmc5843_writable_ranges[] = { |
31 | regmap_reg_range(0, HMC5843_MODE_REG), | 31 | regmap_reg_range(0, HMC5843_MODE_REG), |
32 | }; | 32 | }; |
33 | 33 | ||
34 | static struct regmap_access_table hmc5843_writable_table = { | 34 | static const struct regmap_access_table hmc5843_writable_table = { |
35 | .yes_ranges = hmc5843_writable_ranges, | 35 | .yes_ranges = hmc5843_writable_ranges, |
36 | .n_yes_ranges = ARRAY_SIZE(hmc5843_writable_ranges), | 36 | .n_yes_ranges = ARRAY_SIZE(hmc5843_writable_ranges), |
37 | }; | 37 | }; |
38 | 38 | ||
39 | static const struct regmap_range hmc5843_volatile_ranges[] = { | 39 | static const struct regmap_range hmc5843_volatile_ranges[] = { |
40 | regmap_reg_range(HMC5843_DATA_OUT_MSB_REGS, HMC5843_STATUS_REG), | 40 | regmap_reg_range(HMC5843_DATA_OUT_MSB_REGS, HMC5843_STATUS_REG), |
41 | }; | 41 | }; |
42 | 42 | ||
43 | static struct regmap_access_table hmc5843_volatile_table = { | 43 | static const struct regmap_access_table hmc5843_volatile_table = { |
44 | .yes_ranges = hmc5843_volatile_ranges, | 44 | .yes_ranges = hmc5843_volatile_ranges, |
45 | .n_yes_ranges = ARRAY_SIZE(hmc5843_volatile_ranges), | 45 | .n_yes_ranges = ARRAY_SIZE(hmc5843_volatile_ranges), |
46 | }; | 46 | }; |
47 | 47 | ||
48 | static struct regmap_config hmc5843_i2c_regmap_config = { | 48 | static const struct regmap_config hmc5843_i2c_regmap_config = { |
49 | .reg_bits = 8, | 49 | .reg_bits = 8, |
50 | .val_bits = 8, | 50 | .val_bits = 8, |
51 | 51 | ||
52 | .rd_table = &hmc5843_readable_table, | 52 | .rd_table = &hmc5843_readable_table, |
53 | .wr_table = &hmc5843_writable_table, | 53 | .wr_table = &hmc5843_writable_table, |
54 | .volatile_table = &hmc5843_volatile_table, | 54 | .volatile_table = &hmc5843_volatile_table, |
55 | 55 | ||
56 | .cache_type = REGCACHE_RBTREE, | 56 | .cache_type = REGCACHE_RBTREE, |
57 | }; | 57 | }; |
58 | 58 | ||
59 | static int hmc5843_i2c_probe(struct i2c_client *cli, | 59 | static int hmc5843_i2c_probe(struct i2c_client *cli, |
diff --git a/drivers/staging/iio/magnetometer/hmc5843_spi.c b/drivers/staging/iio/magnetometer/hmc5843_spi.c index 98c4b57101c9..8e658f736e1f 100644 --- a/drivers/staging/iio/magnetometer/hmc5843_spi.c +++ b/drivers/staging/iio/magnetometer/hmc5843_spi.c | |||
@@ -19,7 +19,7 @@ static const struct regmap_range hmc5843_readable_ranges[] = { | |||
19 | regmap_reg_range(0, HMC5843_ID_END), | 19 | regmap_reg_range(0, HMC5843_ID_END), |
20 | }; | 20 | }; |
21 | 21 | ||
22 | static struct regmap_access_table hmc5843_readable_table = { | 22 | static const struct regmap_access_table hmc5843_readable_table = { |
23 | .yes_ranges = hmc5843_readable_ranges, | 23 | .yes_ranges = hmc5843_readable_ranges, |
24 | .n_yes_ranges = ARRAY_SIZE(hmc5843_readable_ranges), | 24 | .n_yes_ranges = ARRAY_SIZE(hmc5843_readable_ranges), |
25 | }; | 25 | }; |
@@ -28,7 +28,7 @@ static const struct regmap_range hmc5843_writable_ranges[] = { | |||
28 | regmap_reg_range(0, HMC5843_MODE_REG), | 28 | regmap_reg_range(0, HMC5843_MODE_REG), |
29 | }; | 29 | }; |
30 | 30 | ||
31 | static struct regmap_access_table hmc5843_writable_table = { | 31 | static const struct regmap_access_table hmc5843_writable_table = { |
32 | .yes_ranges = hmc5843_writable_ranges, | 32 | .yes_ranges = hmc5843_writable_ranges, |
33 | .n_yes_ranges = ARRAY_SIZE(hmc5843_writable_ranges), | 33 | .n_yes_ranges = ARRAY_SIZE(hmc5843_writable_ranges), |
34 | }; | 34 | }; |
@@ -37,12 +37,12 @@ static const struct regmap_range hmc5843_volatile_ranges[] = { | |||
37 | regmap_reg_range(HMC5843_DATA_OUT_MSB_REGS, HMC5843_STATUS_REG), | 37 | regmap_reg_range(HMC5843_DATA_OUT_MSB_REGS, HMC5843_STATUS_REG), |
38 | }; | 38 | }; |
39 | 39 | ||
40 | static struct regmap_access_table hmc5843_volatile_table = { | 40 | static const struct regmap_access_table hmc5843_volatile_table = { |
41 | .yes_ranges = hmc5843_volatile_ranges, | 41 | .yes_ranges = hmc5843_volatile_ranges, |
42 | .n_yes_ranges = ARRAY_SIZE(hmc5843_volatile_ranges), | 42 | .n_yes_ranges = ARRAY_SIZE(hmc5843_volatile_ranges), |
43 | }; | 43 | }; |
44 | 44 | ||
45 | static struct regmap_config hmc5843_spi_regmap_config = { | 45 | static const struct regmap_config hmc5843_spi_regmap_config = { |
46 | .reg_bits = 8, | 46 | .reg_bits = 8, |
47 | .val_bits = 8, | 47 | .val_bits = 8, |
48 | 48 | ||
diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c index 8dc5089772a3..6335b5815acd 100644 --- a/drivers/staging/iio/meter/ade7754.c +++ b/drivers/staging/iio/meter/ade7754.c | |||
@@ -216,9 +216,13 @@ error_ret: | |||
216 | 216 | ||
217 | static int ade7754_reset(struct device *dev) | 217 | static int ade7754_reset(struct device *dev) |
218 | { | 218 | { |
219 | int ret; | ||
219 | u8 val; | 220 | u8 val; |
220 | 221 | ||
221 | ade7754_spi_read_reg_8(dev, ADE7754_OPMODE, &val); | 222 | ret = ade7754_spi_read_reg_8(dev, ADE7754_OPMODE, &val); |
223 | if (ret < 0) | ||
224 | return ret; | ||
225 | |||
222 | val |= 1 << 6; /* Software Chip Reset */ | 226 | val |= 1 << 6; /* Software Chip Reset */ |
223 | return ade7754_spi_write_reg_8(dev, ADE7754_OPMODE, val); | 227 | return ade7754_spi_write_reg_8(dev, ADE7754_OPMODE, val); |
224 | } | 228 | } |
@@ -362,9 +366,16 @@ error_ret: | |||
362 | /* Power down the device */ | 366 | /* Power down the device */ |
363 | static int ade7754_stop_device(struct device *dev) | 367 | static int ade7754_stop_device(struct device *dev) |
364 | { | 368 | { |
369 | int ret; | ||
365 | u8 val; | 370 | u8 val; |
366 | 371 | ||
367 | ade7754_spi_read_reg_8(dev, ADE7754_OPMODE, &val); | 372 | ret = ade7754_spi_read_reg_8(dev, ADE7754_OPMODE, &val); |
373 | if (ret < 0) { | ||
374 | dev_err(dev, "unable to power down the device, error: %d", | ||
375 | ret); | ||
376 | return ret; | ||
377 | } | ||
378 | |||
368 | val |= 7 << 3; /* ADE7754 powered down */ | 379 | val |= 7 << 3; /* ADE7754 powered down */ |
369 | return ade7754_spi_write_reg_8(dev, ADE7754_OPMODE, val); | 380 | return ade7754_spi_write_reg_8(dev, ADE7754_OPMODE, val); |
370 | } | 381 | } |
diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c index 7eef8b9573fc..dbceda1e67ea 100644 --- a/drivers/staging/iio/meter/ade7759.c +++ b/drivers/staging/iio/meter/ade7759.c | |||
@@ -215,11 +215,15 @@ error_ret: | |||
215 | 215 | ||
216 | static int ade7759_reset(struct device *dev) | 216 | static int ade7759_reset(struct device *dev) |
217 | { | 217 | { |
218 | int ret; | ||
218 | u16 val; | 219 | u16 val; |
219 | 220 | ||
220 | ade7759_spi_read_reg_16(dev, | 221 | ret = ade7759_spi_read_reg_16(dev, |
221 | ADE7759_MODE, | 222 | ADE7759_MODE, |
222 | &val); | 223 | &val); |
224 | if (ret < 0) | ||
225 | return ret; | ||
226 | |||
223 | val |= 1 << 6; /* Software Chip Reset */ | 227 | val |= 1 << 6; /* Software Chip Reset */ |
224 | return ade7759_spi_write_reg_16(dev, | 228 | return ade7759_spi_write_reg_16(dev, |
225 | ADE7759_MODE, | 229 | ADE7759_MODE, |
@@ -298,11 +302,18 @@ error_ret: | |||
298 | /* Power down the device */ | 302 | /* Power down the device */ |
299 | static int ade7759_stop_device(struct device *dev) | 303 | static int ade7759_stop_device(struct device *dev) |
300 | { | 304 | { |
305 | int ret; | ||
301 | u16 val; | 306 | u16 val; |
302 | 307 | ||
303 | ade7759_spi_read_reg_16(dev, | 308 | ret = ade7759_spi_read_reg_16(dev, |
304 | ADE7759_MODE, | 309 | ADE7759_MODE, |
305 | &val); | 310 | &val); |
311 | if (ret < 0) { | ||
312 | dev_err(dev, "unable to power down the device, error: %d\n", | ||
313 | ret); | ||
314 | return ret; | ||
315 | } | ||
316 | |||
306 | val |= 1 << 4; /* AD converters can be turned off */ | 317 | val |= 1 << 4; /* AD converters can be turned off */ |
307 | 318 | ||
308 | return ade7759_spi_write_reg_16(dev, ADE7759_MODE, val); | 319 | return ade7759_spi_write_reg_16(dev, ADE7759_MODE, val); |
diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c index 5b1daeacac7a..7bc3e4a73834 100644 --- a/drivers/staging/iio/resolver/ad2s1210.c +++ b/drivers/staging/iio/resolver/ad2s1210.c | |||
@@ -198,7 +198,7 @@ static ssize_t ad2s1210_show_fclkin(struct device *dev, | |||
198 | { | 198 | { |
199 | struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev)); | 199 | struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev)); |
200 | 200 | ||
201 | return sprintf(buf, "%d\n", st->fclkin); | 201 | return sprintf(buf, "%u\n", st->fclkin); |
202 | } | 202 | } |
203 | 203 | ||
204 | static ssize_t ad2s1210_store_fclkin(struct device *dev, | 204 | static ssize_t ad2s1210_store_fclkin(struct device *dev, |
@@ -237,7 +237,7 @@ static ssize_t ad2s1210_show_fexcit(struct device *dev, | |||
237 | { | 237 | { |
238 | struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev)); | 238 | struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev)); |
239 | 239 | ||
240 | return sprintf(buf, "%d\n", st->fexcit); | 240 | return sprintf(buf, "%u\n", st->fexcit); |
241 | } | 241 | } |
242 | 242 | ||
243 | static ssize_t ad2s1210_store_fexcit(struct device *dev, | 243 | static ssize_t ad2s1210_store_fexcit(struct device *dev, |
diff --git a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c index a24caf73ae0b..89df1d32874d 100644 --- a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c +++ b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c | |||
@@ -24,7 +24,7 @@ static DEFINE_MUTEX(iio_prtc_trigger_list_lock); | |||
24 | 24 | ||
25 | struct iio_prtc_trigger_info { | 25 | struct iio_prtc_trigger_info { |
26 | struct rtc_device *rtc; | 26 | struct rtc_device *rtc; |
27 | int frequency; | 27 | unsigned int frequency; |
28 | struct rtc_task task; | 28 | struct rtc_task task; |
29 | bool state; | 29 | bool state; |
30 | }; | 30 | }; |
@@ -36,7 +36,7 @@ static int iio_trig_periodic_rtc_set_state(struct iio_trigger *trig, bool state) | |||
36 | 36 | ||
37 | if (trig_info->frequency == 0 && state) | 37 | if (trig_info->frequency == 0 && state) |
38 | return -EINVAL; | 38 | return -EINVAL; |
39 | dev_dbg(&trig_info->rtc->dev, "trigger frequency is %d\n", | 39 | dev_dbg(&trig_info->rtc->dev, "trigger frequency is %u\n", |
40 | trig_info->frequency); | 40 | trig_info->frequency); |
41 | ret = rtc_irq_set_state(trig_info->rtc, &trig_info->task, state); | 41 | ret = rtc_irq_set_state(trig_info->rtc, &trig_info->task, state); |
42 | if (ret == 0) | 42 | if (ret == 0) |
@@ -62,10 +62,10 @@ static ssize_t iio_trig_periodic_write_freq(struct device *dev, | |||
62 | { | 62 | { |
63 | struct iio_trigger *trig = to_iio_trigger(dev); | 63 | struct iio_trigger *trig = to_iio_trigger(dev); |
64 | struct iio_prtc_trigger_info *trig_info = iio_trigger_get_drvdata(trig); | 64 | struct iio_prtc_trigger_info *trig_info = iio_trigger_get_drvdata(trig); |
65 | int val; | 65 | unsigned int val; |
66 | int ret; | 66 | int ret; |
67 | 67 | ||
68 | ret = kstrtoint(buf, 10, &val); | 68 | ret = kstrtouint(buf, 10, &val); |
69 | if (ret) | 69 | if (ret) |
70 | goto error_ret; | 70 | goto error_ret; |
71 | 71 | ||
@@ -74,10 +74,8 @@ static ssize_t iio_trig_periodic_write_freq(struct device *dev, | |||
74 | if (ret == 0 && trig_info->state && trig_info->frequency == 0) | 74 | if (ret == 0 && trig_info->state && trig_info->frequency == 0) |
75 | ret = rtc_irq_set_state(trig_info->rtc, | 75 | ret = rtc_irq_set_state(trig_info->rtc, |
76 | &trig_info->task, 1); | 76 | &trig_info->task, 1); |
77 | } else if (val == 0) { | ||
78 | ret = rtc_irq_set_state(trig_info->rtc, &trig_info->task, 0); | ||
79 | } else | 77 | } else |
80 | ret = -EINVAL; | 78 | ret = rtc_irq_set_state(trig_info->rtc, &trig_info->task, 0); |
81 | if (ret) | 79 | if (ret) |
82 | goto error_ret; | 80 | goto error_ret; |
83 | 81 | ||
diff --git a/include/linux/iio/events.h b/include/linux/iio/events.h index 03fa332ad2a8..8ad87d1c5340 100644 --- a/include/linux/iio/events.h +++ b/include/linux/iio/events.h | |||
@@ -9,22 +9,8 @@ | |||
9 | #ifndef _IIO_EVENTS_H_ | 9 | #ifndef _IIO_EVENTS_H_ |
10 | #define _IIO_EVENTS_H_ | 10 | #define _IIO_EVENTS_H_ |
11 | 11 | ||
12 | #include <linux/ioctl.h> | ||
13 | #include <linux/types.h> | ||
14 | #include <linux/iio/types.h> | 12 | #include <linux/iio/types.h> |
15 | 13 | #include <uapi/linux/iio/events.h> | |
16 | /** | ||
17 | * struct iio_event_data - The actual event being pushed to userspace | ||
18 | * @id: event identifier | ||
19 | * @timestamp: best estimate of time of event occurrence (often from | ||
20 | * the interrupt handler) | ||
21 | */ | ||
22 | struct iio_event_data { | ||
23 | __u64 id; | ||
24 | __s64 timestamp; | ||
25 | }; | ||
26 | |||
27 | #define IIO_GET_EVENT_FD_IOCTL _IOR('i', 0x90, int) | ||
28 | 14 | ||
29 | /** | 15 | /** |
30 | * IIO_EVENT_CODE() - create event identifier | 16 | * IIO_EVENT_CODE() - create event identifier |
@@ -70,18 +56,4 @@ struct iio_event_data { | |||
70 | #define IIO_UNMOD_EVENT_CODE(chan_type, number, type, direction) \ | 56 | #define IIO_UNMOD_EVENT_CODE(chan_type, number, type, direction) \ |
71 | IIO_EVENT_CODE(chan_type, 0, 0, direction, type, number, 0, 0) | 57 | IIO_EVENT_CODE(chan_type, 0, 0, direction, type, number, 0, 0) |
72 | 58 | ||
73 | #define IIO_EVENT_CODE_EXTRACT_TYPE(mask) ((mask >> 56) & 0xFF) | ||
74 | |||
75 | #define IIO_EVENT_CODE_EXTRACT_DIR(mask) ((mask >> 48) & 0x7F) | ||
76 | |||
77 | #define IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(mask) ((mask >> 32) & 0xFF) | ||
78 | |||
79 | /* Event code number extraction depends on which type of event we have. | ||
80 | * Perhaps review this function in the future*/ | ||
81 | #define IIO_EVENT_CODE_EXTRACT_CHAN(mask) ((__s16)(mask & 0xFFFF)) | ||
82 | #define IIO_EVENT_CODE_EXTRACT_CHAN2(mask) ((__s16)(((mask) >> 16) & 0xFFFF)) | ||
83 | |||
84 | #define IIO_EVENT_CODE_EXTRACT_MODIFIER(mask) ((mask >> 40) & 0xFF) | ||
85 | #define IIO_EVENT_CODE_EXTRACT_DIFF(mask) (((mask) >> 55) & 0x1) | ||
86 | |||
87 | #endif | 59 | #endif |
diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h index 580ed5bdb3fa..942b6de68e2f 100644 --- a/include/linux/iio/types.h +++ b/include/linux/iio/types.h | |||
@@ -10,76 +10,7 @@ | |||
10 | #ifndef _IIO_TYPES_H_ | 10 | #ifndef _IIO_TYPES_H_ |
11 | #define _IIO_TYPES_H_ | 11 | #define _IIO_TYPES_H_ |
12 | 12 | ||
13 | enum iio_chan_type { | 13 | #include <uapi/linux/iio/types.h> |
14 | IIO_VOLTAGE, | ||
15 | IIO_CURRENT, | ||
16 | IIO_POWER, | ||
17 | IIO_ACCEL, | ||
18 | IIO_ANGL_VEL, | ||
19 | IIO_MAGN, | ||
20 | IIO_LIGHT, | ||
21 | IIO_INTENSITY, | ||
22 | IIO_PROXIMITY, | ||
23 | IIO_TEMP, | ||
24 | IIO_INCLI, | ||
25 | IIO_ROT, | ||
26 | IIO_ANGL, | ||
27 | IIO_TIMESTAMP, | ||
28 | IIO_CAPACITANCE, | ||
29 | IIO_ALTVOLTAGE, | ||
30 | IIO_CCT, | ||
31 | IIO_PRESSURE, | ||
32 | IIO_HUMIDITYRELATIVE, | ||
33 | IIO_ACTIVITY, | ||
34 | IIO_STEPS, | ||
35 | IIO_ENERGY, | ||
36 | IIO_DISTANCE, | ||
37 | IIO_VELOCITY, | ||
38 | }; | ||
39 | |||
40 | enum iio_modifier { | ||
41 | IIO_NO_MOD, | ||
42 | IIO_MOD_X, | ||
43 | IIO_MOD_Y, | ||
44 | IIO_MOD_Z, | ||
45 | IIO_MOD_X_AND_Y, | ||
46 | IIO_MOD_X_AND_Z, | ||
47 | IIO_MOD_Y_AND_Z, | ||
48 | IIO_MOD_X_AND_Y_AND_Z, | ||
49 | IIO_MOD_X_OR_Y, | ||
50 | IIO_MOD_X_OR_Z, | ||
51 | IIO_MOD_Y_OR_Z, | ||
52 | IIO_MOD_X_OR_Y_OR_Z, | ||
53 | IIO_MOD_LIGHT_BOTH, | ||
54 | IIO_MOD_LIGHT_IR, | ||
55 | IIO_MOD_ROOT_SUM_SQUARED_X_Y, | ||
56 | IIO_MOD_SUM_SQUARED_X_Y_Z, | ||
57 | IIO_MOD_LIGHT_CLEAR, | ||
58 | IIO_MOD_LIGHT_RED, | ||
59 | IIO_MOD_LIGHT_GREEN, | ||
60 | IIO_MOD_LIGHT_BLUE, | ||
61 | IIO_MOD_QUATERNION, | ||
62 | IIO_MOD_TEMP_AMBIENT, | ||
63 | IIO_MOD_TEMP_OBJECT, | ||
64 | IIO_MOD_NORTH_MAGN, | ||
65 | IIO_MOD_NORTH_TRUE, | ||
66 | IIO_MOD_NORTH_MAGN_TILT_COMP, | ||
67 | IIO_MOD_NORTH_TRUE_TILT_COMP, | ||
68 | IIO_MOD_RUNNING, | ||
69 | IIO_MOD_JOGGING, | ||
70 | IIO_MOD_WALKING, | ||
71 | IIO_MOD_STILL, | ||
72 | IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z, | ||
73 | }; | ||
74 | |||
75 | enum iio_event_type { | ||
76 | IIO_EV_TYPE_THRESH, | ||
77 | IIO_EV_TYPE_MAG, | ||
78 | IIO_EV_TYPE_ROC, | ||
79 | IIO_EV_TYPE_THRESH_ADAPTIVE, | ||
80 | IIO_EV_TYPE_MAG_ADAPTIVE, | ||
81 | IIO_EV_TYPE_CHANGE, | ||
82 | }; | ||
83 | 14 | ||
84 | enum iio_event_info { | 15 | enum iio_event_info { |
85 | IIO_EV_INFO_ENABLE, | 16 | IIO_EV_INFO_ENABLE, |
@@ -88,13 +19,6 @@ enum iio_event_info { | |||
88 | IIO_EV_INFO_PERIOD, | 19 | IIO_EV_INFO_PERIOD, |
89 | }; | 20 | }; |
90 | 21 | ||
91 | enum iio_event_direction { | ||
92 | IIO_EV_DIR_EITHER, | ||
93 | IIO_EV_DIR_RISING, | ||
94 | IIO_EV_DIR_FALLING, | ||
95 | IIO_EV_DIR_NONE, | ||
96 | }; | ||
97 | |||
98 | #define IIO_VAL_INT 1 | 22 | #define IIO_VAL_INT 1 |
99 | #define IIO_VAL_INT_PLUS_MICRO 2 | 23 | #define IIO_VAL_INT_PLUS_MICRO 2 |
100 | #define IIO_VAL_INT_PLUS_NANO 3 | 24 | #define IIO_VAL_INT_PLUS_NANO 3 |
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index 68ceb97c458c..38df23435ebb 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild | |||
@@ -6,6 +6,7 @@ header-y += caif/ | |||
6 | header-y += dvb/ | 6 | header-y += dvb/ |
7 | header-y += hdlc/ | 7 | header-y += hdlc/ |
8 | header-y += hsi/ | 8 | header-y += hsi/ |
9 | header-y += iio/ | ||
9 | header-y += isdn/ | 10 | header-y += isdn/ |
10 | header-y += mmc/ | 11 | header-y += mmc/ |
11 | header-y += nfsd/ | 12 | header-y += nfsd/ |
diff --git a/include/uapi/linux/iio/Kbuild b/include/uapi/linux/iio/Kbuild new file mode 100644 index 000000000000..86f76d84c44f --- /dev/null +++ b/include/uapi/linux/iio/Kbuild | |||
@@ -0,0 +1,3 @@ | |||
1 | # UAPI Header export list | ||
2 | header-y += events.h | ||
3 | header-y += types.h | ||
diff --git a/include/uapi/linux/iio/events.h b/include/uapi/linux/iio/events.h new file mode 100644 index 000000000000..00bbdaed2f97 --- /dev/null +++ b/include/uapi/linux/iio/events.h | |||
@@ -0,0 +1,42 @@ | |||
1 | /* The industrial I/O - event passing to userspace | ||
2 | * | ||
3 | * Copyright (c) 2008-2011 Jonathan Cameron | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License version 2 as published by | ||
7 | * the Free Software Foundation. | ||
8 | */ | ||
9 | #ifndef _UAPI_IIO_EVENTS_H_ | ||
10 | #define _UAPI_IIO_EVENTS_H_ | ||
11 | |||
12 | #include <linux/ioctl.h> | ||
13 | #include <linux/types.h> | ||
14 | |||
15 | /** | ||
16 | * struct iio_event_data - The actual event being pushed to userspace | ||
17 | * @id: event identifier | ||
18 | * @timestamp: best estimate of time of event occurrence (often from | ||
19 | * the interrupt handler) | ||
20 | */ | ||
21 | struct iio_event_data { | ||
22 | __u64 id; | ||
23 | __s64 timestamp; | ||
24 | }; | ||
25 | |||
26 | #define IIO_GET_EVENT_FD_IOCTL _IOR('i', 0x90, int) | ||
27 | |||
28 | #define IIO_EVENT_CODE_EXTRACT_TYPE(mask) ((mask >> 56) & 0xFF) | ||
29 | |||
30 | #define IIO_EVENT_CODE_EXTRACT_DIR(mask) ((mask >> 48) & 0x7F) | ||
31 | |||
32 | #define IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(mask) ((mask >> 32) & 0xFF) | ||
33 | |||
34 | /* Event code number extraction depends on which type of event we have. | ||
35 | * Perhaps review this function in the future*/ | ||
36 | #define IIO_EVENT_CODE_EXTRACT_CHAN(mask) ((__s16)(mask & 0xFFFF)) | ||
37 | #define IIO_EVENT_CODE_EXTRACT_CHAN2(mask) ((__s16)(((mask) >> 16) & 0xFFFF)) | ||
38 | |||
39 | #define IIO_EVENT_CODE_EXTRACT_MODIFIER(mask) ((mask >> 40) & 0xFF) | ||
40 | #define IIO_EVENT_CODE_EXTRACT_DIFF(mask) (((mask) >> 55) & 0x1) | ||
41 | |||
42 | #endif /* _UAPI_IIO_EVENTS_H_ */ | ||
diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h new file mode 100644 index 000000000000..5c4601935005 --- /dev/null +++ b/include/uapi/linux/iio/types.h | |||
@@ -0,0 +1,92 @@ | |||
1 | /* industrial I/O data types needed both in and out of kernel | ||
2 | * | ||
3 | * Copyright (c) 2008 Jonathan Cameron | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License version 2 as published by | ||
7 | * the Free Software Foundation. | ||
8 | */ | ||
9 | |||
10 | #ifndef _UAPI_IIO_TYPES_H_ | ||
11 | #define _UAPI_IIO_TYPES_H_ | ||
12 | |||
13 | enum iio_chan_type { | ||
14 | IIO_VOLTAGE, | ||
15 | IIO_CURRENT, | ||
16 | IIO_POWER, | ||
17 | IIO_ACCEL, | ||
18 | IIO_ANGL_VEL, | ||
19 | IIO_MAGN, | ||
20 | IIO_LIGHT, | ||
21 | IIO_INTENSITY, | ||
22 | IIO_PROXIMITY, | ||
23 | IIO_TEMP, | ||
24 | IIO_INCLI, | ||
25 | IIO_ROT, | ||
26 | IIO_ANGL, | ||
27 | IIO_TIMESTAMP, | ||
28 | IIO_CAPACITANCE, | ||
29 | IIO_ALTVOLTAGE, | ||
30 | IIO_CCT, | ||
31 | IIO_PRESSURE, | ||
32 | IIO_HUMIDITYRELATIVE, | ||
33 | IIO_ACTIVITY, | ||
34 | IIO_STEPS, | ||
35 | IIO_ENERGY, | ||
36 | IIO_DISTANCE, | ||
37 | IIO_VELOCITY, | ||
38 | }; | ||
39 | |||
40 | enum iio_modifier { | ||
41 | IIO_NO_MOD, | ||
42 | IIO_MOD_X, | ||
43 | IIO_MOD_Y, | ||
44 | IIO_MOD_Z, | ||
45 | IIO_MOD_X_AND_Y, | ||
46 | IIO_MOD_X_AND_Z, | ||
47 | IIO_MOD_Y_AND_Z, | ||
48 | IIO_MOD_X_AND_Y_AND_Z, | ||
49 | IIO_MOD_X_OR_Y, | ||
50 | IIO_MOD_X_OR_Z, | ||
51 | IIO_MOD_Y_OR_Z, | ||
52 | IIO_MOD_X_OR_Y_OR_Z, | ||
53 | IIO_MOD_LIGHT_BOTH, | ||
54 | IIO_MOD_LIGHT_IR, | ||
55 | IIO_MOD_ROOT_SUM_SQUARED_X_Y, | ||
56 | IIO_MOD_SUM_SQUARED_X_Y_Z, | ||
57 | IIO_MOD_LIGHT_CLEAR, | ||
58 | IIO_MOD_LIGHT_RED, | ||
59 | IIO_MOD_LIGHT_GREEN, | ||
60 | IIO_MOD_LIGHT_BLUE, | ||
61 | IIO_MOD_QUATERNION, | ||
62 | IIO_MOD_TEMP_AMBIENT, | ||
63 | IIO_MOD_TEMP_OBJECT, | ||
64 | IIO_MOD_NORTH_MAGN, | ||
65 | IIO_MOD_NORTH_TRUE, | ||
66 | IIO_MOD_NORTH_MAGN_TILT_COMP, | ||
67 | IIO_MOD_NORTH_TRUE_TILT_COMP, | ||
68 | IIO_MOD_RUNNING, | ||
69 | IIO_MOD_JOGGING, | ||
70 | IIO_MOD_WALKING, | ||
71 | IIO_MOD_STILL, | ||
72 | IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z, | ||
73 | }; | ||
74 | |||
75 | enum iio_event_type { | ||
76 | IIO_EV_TYPE_THRESH, | ||
77 | IIO_EV_TYPE_MAG, | ||
78 | IIO_EV_TYPE_ROC, | ||
79 | IIO_EV_TYPE_THRESH_ADAPTIVE, | ||
80 | IIO_EV_TYPE_MAG_ADAPTIVE, | ||
81 | IIO_EV_TYPE_CHANGE, | ||
82 | }; | ||
83 | |||
84 | enum iio_event_direction { | ||
85 | IIO_EV_DIR_EITHER, | ||
86 | IIO_EV_DIR_RISING, | ||
87 | IIO_EV_DIR_FALLING, | ||
88 | IIO_EV_DIR_NONE, | ||
89 | }; | ||
90 | |||
91 | #endif /* _UAPI_IIO_TYPES_H_ */ | ||
92 | |||
diff --git a/tools/iio/Makefile b/tools/iio/Makefile new file mode 100644 index 000000000000..bf7ae6d6612a --- /dev/null +++ b/tools/iio/Makefile | |||
@@ -0,0 +1,16 @@ | |||
1 | CC = gcc | ||
2 | CFLAGS = -Wall -g -D_GNU_SOURCE | ||
3 | |||
4 | all: iio_event_monitor lsiio generic_buffer | ||
5 | |||
6 | iio_event_monitor: iio_event_monitor.o iio_utils.o | ||
7 | |||
8 | lsiio: lsiio.o iio_utils.o | ||
9 | |||
10 | generic_buffer: generic_buffer.o iio_utils.o | ||
11 | |||
12 | %.o: %.c iio_utils.h | ||
13 | |||
14 | .PHONY: clean | ||
15 | clean: | ||
16 | rm -f *.o iio_event_monitor lsiio generic_buffer | ||
diff --git a/drivers/staging/iio/Documentation/generic_buffer.c b/tools/iio/generic_buffer.c index 59b250545d4c..f805493be3eb 100644 --- a/drivers/staging/iio/Documentation/generic_buffer.c +++ b/tools/iio/generic_buffer.c | |||
@@ -18,9 +18,8 @@ | |||
18 | * | 18 | * |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #define _GNU_SOURCE | ||
22 | |||
23 | #include <unistd.h> | 21 | #include <unistd.h> |
22 | #include <stdlib.h> | ||
24 | #include <dirent.h> | 23 | #include <dirent.h> |
25 | #include <fcntl.h> | 24 | #include <fcntl.h> |
26 | #include <stdio.h> | 25 | #include <stdio.h> |
diff --git a/drivers/staging/iio/Documentation/iio_event_monitor.c b/tools/iio/iio_event_monitor.c index 72c96aa6e992..427c271ac0d6 100644 --- a/drivers/staging/iio/Documentation/iio_event_monitor.c +++ b/tools/iio/iio_event_monitor.c | |||
@@ -16,9 +16,8 @@ | |||
16 | * | 16 | * |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #define _GNU_SOURCE | ||
20 | |||
21 | #include <unistd.h> | 19 | #include <unistd.h> |
20 | #include <stdlib.h> | ||
22 | #include <stdbool.h> | 21 | #include <stdbool.h> |
23 | #include <stdio.h> | 22 | #include <stdio.h> |
24 | #include <errno.h> | 23 | #include <errno.h> |
@@ -28,6 +27,7 @@ | |||
28 | #include <sys/ioctl.h> | 27 | #include <sys/ioctl.h> |
29 | #include "iio_utils.h" | 28 | #include "iio_utils.h" |
30 | #include <linux/iio/events.h> | 29 | #include <linux/iio/events.h> |
30 | #include <linux/iio/types.h> | ||
31 | 31 | ||
32 | static const char * const iio_chan_type_name_spec[] = { | 32 | static const char * const iio_chan_type_name_spec[] = { |
33 | [IIO_VOLTAGE] = "voltage", | 33 | [IIO_VOLTAGE] = "voltage", |
diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/tools/iio/iio_utils.c index bd6982c12d0d..2680a2e0f113 100644 --- a/drivers/staging/iio/Documentation/iio_utils.h +++ b/tools/iio/iio_utils.c | |||
@@ -11,17 +11,12 @@ | |||
11 | 11 | ||
12 | #include <string.h> | 12 | #include <string.h> |
13 | #include <stdlib.h> | 13 | #include <stdlib.h> |
14 | #include <ctype.h> | ||
15 | #include <stdio.h> | 14 | #include <stdio.h> |
16 | #include <stdint.h> | 15 | #include <stdint.h> |
17 | #include <dirent.h> | 16 | #include <dirent.h> |
18 | #include <errno.h> | 17 | #include <errno.h> |
19 | 18 | #include <ctype.h> | |
20 | /* Made up value to limit allocation sizes */ | 19 | #include "iio_utils.h" |
21 | #define IIO_MAX_NAME_LENGTH 30 | ||
22 | |||
23 | #define FORMAT_SCAN_ELEMENTS_DIR "%s/scan_elements" | ||
24 | #define FORMAT_TYPE_FILE "%s_type" | ||
25 | 20 | ||
26 | const char *iio_dir = "/sys/bus/iio/devices/"; | 21 | const char *iio_dir = "/sys/bus/iio/devices/"; |
27 | 22 | ||
@@ -30,7 +25,7 @@ const char *iio_dir = "/sys/bus/iio/devices/"; | |||
30 | * @full_name: the full channel name | 25 | * @full_name: the full channel name |
31 | * @generic_name: the output generic channel name | 26 | * @generic_name: the output generic channel name |
32 | **/ | 27 | **/ |
33 | inline int iioutils_break_up_name(const char *full_name, | 28 | int iioutils_break_up_name(const char *full_name, |
34 | char **generic_name) | 29 | char **generic_name) |
35 | { | 30 | { |
36 | char *current; | 31 | char *current; |
@@ -57,33 +52,6 @@ inline int iioutils_break_up_name(const char *full_name, | |||
57 | } | 52 | } |
58 | 53 | ||
59 | /** | 54 | /** |
60 | * struct iio_channel_info - information about a given channel | ||
61 | * @name: channel name | ||
62 | * @generic_name: general name for channel type | ||
63 | * @scale: scale factor to be applied for conversion to si units | ||
64 | * @offset: offset to be applied for conversion to si units | ||
65 | * @index: the channel index in the buffer output | ||
66 | * @bytes: number of bytes occupied in buffer output | ||
67 | * @mask: a bit mask for the raw output | ||
68 | * @is_signed: is the raw value stored signed | ||
69 | * @enabled: is this channel enabled | ||
70 | **/ | ||
71 | struct iio_channel_info { | ||
72 | char *name; | ||
73 | char *generic_name; | ||
74 | float scale; | ||
75 | float offset; | ||
76 | unsigned index; | ||
77 | unsigned bytes; | ||
78 | unsigned bits_used; | ||
79 | unsigned shift; | ||
80 | uint64_t mask; | ||
81 | unsigned be; | ||
82 | unsigned is_signed; | ||
83 | unsigned location; | ||
84 | }; | ||
85 | |||
86 | /** | ||
87 | * iioutils_get_type() - find and process _type attribute data | 55 | * iioutils_get_type() - find and process _type attribute data |
88 | * @is_signed: output whether channel is signed | 56 | * @is_signed: output whether channel is signed |
89 | * @bytes: output how many bytes the channel storage occupies | 57 | * @bytes: output how many bytes the channel storage occupies |
@@ -93,7 +61,7 @@ struct iio_channel_info { | |||
93 | * @name: the channel name | 61 | * @name: the channel name |
94 | * @generic_name: the channel type name | 62 | * @generic_name: the channel type name |
95 | **/ | 63 | **/ |
96 | inline int iioutils_get_type(unsigned *is_signed, | 64 | int iioutils_get_type(unsigned *is_signed, |
97 | unsigned *bytes, | 65 | unsigned *bytes, |
98 | unsigned *bits_used, | 66 | unsigned *bits_used, |
99 | unsigned *shift, | 67 | unsigned *shift, |
@@ -197,7 +165,7 @@ error_ret: | |||
197 | return ret; | 165 | return ret; |
198 | } | 166 | } |
199 | 167 | ||
200 | inline int iioutils_get_param_float(float *output, | 168 | int iioutils_get_param_float(float *output, |
201 | const char *param_name, | 169 | const char *param_name, |
202 | const char *device_dir, | 170 | const char *device_dir, |
203 | const char *name, | 171 | const char *name, |
@@ -261,7 +229,7 @@ error_ret: | |||
261 | * | 229 | * |
262 | **/ | 230 | **/ |
263 | 231 | ||
264 | inline void bsort_channel_array_by_index(struct iio_channel_info **ci_array, | 232 | void bsort_channel_array_by_index(struct iio_channel_info **ci_array, |
265 | int cnt) | 233 | int cnt) |
266 | { | 234 | { |
267 | 235 | ||
@@ -282,7 +250,7 @@ inline void bsort_channel_array_by_index(struct iio_channel_info **ci_array, | |||
282 | * @device_dir: the IIO device directory in sysfs | 250 | * @device_dir: the IIO device directory in sysfs |
283 | * @ | 251 | * @ |
284 | **/ | 252 | **/ |
285 | inline int build_channel_array(const char *device_dir, | 253 | int build_channel_array(const char *device_dir, |
286 | struct iio_channel_info **ci_array, | 254 | struct iio_channel_info **ci_array, |
287 | int *counter) | 255 | int *counter) |
288 | { | 256 | { |
@@ -445,7 +413,7 @@ error_ret: | |||
445 | * | 413 | * |
446 | * Typical types this is used for are device and trigger. | 414 | * Typical types this is used for are device and trigger. |
447 | **/ | 415 | **/ |
448 | inline int find_type_by_name(const char *name, const char *type) | 416 | int find_type_by_name(const char *name, const char *type) |
449 | { | 417 | { |
450 | const struct dirent *ent; | 418 | const struct dirent *ent; |
451 | int number, numstrlen; | 419 | int number, numstrlen; |
@@ -504,7 +472,7 @@ inline int find_type_by_name(const char *name, const char *type) | |||
504 | return -ENODEV; | 472 | return -ENODEV; |
505 | } | 473 | } |
506 | 474 | ||
507 | inline int _write_sysfs_int(char *filename, char *basedir, int val, int verify) | 475 | int _write_sysfs_int(char *filename, char *basedir, int val, int verify) |
508 | { | 476 | { |
509 | int ret = 0; | 477 | int ret = 0; |
510 | FILE *sysfsfp; | 478 | FILE *sysfsfp; |
diff --git a/tools/iio/iio_utils.h b/tools/iio/iio_utils.h new file mode 100644 index 000000000000..1bc837b2d769 --- /dev/null +++ b/tools/iio/iio_utils.h | |||
@@ -0,0 +1,71 @@ | |||
1 | #ifndef _IIO_UTILS_H_ | ||
2 | #define _IIO_UTILS_H_ | ||
3 | |||
4 | /* IIO - useful set of util functionality | ||
5 | * | ||
6 | * Copyright (c) 2008 Jonathan Cameron | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License version 2 as published by | ||
10 | * the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <stdint.h> | ||
14 | |||
15 | /* Made up value to limit allocation sizes */ | ||
16 | #define IIO_MAX_NAME_LENGTH 30 | ||
17 | |||
18 | #define FORMAT_SCAN_ELEMENTS_DIR "%s/scan_elements" | ||
19 | #define FORMAT_TYPE_FILE "%s_type" | ||
20 | |||
21 | extern const char *iio_dir; | ||
22 | |||
23 | /** | ||
24 | * struct iio_channel_info - information about a given channel | ||
25 | * @name: channel name | ||
26 | * @generic_name: general name for channel type | ||
27 | * @scale: scale factor to be applied for conversion to si units | ||
28 | * @offset: offset to be applied for conversion to si units | ||
29 | * @index: the channel index in the buffer output | ||
30 | * @bytes: number of bytes occupied in buffer output | ||
31 | * @mask: a bit mask for the raw output | ||
32 | * @is_signed: is the raw value stored signed | ||
33 | * @enabled: is this channel enabled | ||
34 | **/ | ||
35 | struct iio_channel_info { | ||
36 | char *name; | ||
37 | char *generic_name; | ||
38 | float scale; | ||
39 | float offset; | ||
40 | unsigned index; | ||
41 | unsigned bytes; | ||
42 | unsigned bits_used; | ||
43 | unsigned shift; | ||
44 | uint64_t mask; | ||
45 | unsigned be; | ||
46 | unsigned is_signed; | ||
47 | unsigned location; | ||
48 | }; | ||
49 | |||
50 | int iioutils_break_up_name(const char *full_name, char **generic_name); | ||
51 | int iioutils_get_type(unsigned *is_signed, unsigned *bytes, | ||
52 | unsigned *bits_used, unsigned *shift, | ||
53 | uint64_t *mask, unsigned *be, | ||
54 | const char *device_dir, const char *name, | ||
55 | const char *generic_name); | ||
56 | int iioutils_get_param_float(float *output, const char *param_name, | ||
57 | const char *device_dir, const char *name, | ||
58 | const char *generic_name); | ||
59 | void bsort_channel_array_by_index(struct iio_channel_info **ci_array, int cnt); | ||
60 | int build_channel_array(const char *device_dir, | ||
61 | struct iio_channel_info **ci_array, int *counter); | ||
62 | int find_type_by_name(const char *name, const char *type); | ||
63 | int write_sysfs_int(char *filename, char *basedir, int val); | ||
64 | int write_sysfs_int_and_verify(char *filename, char *basedir, int val); | ||
65 | int write_sysfs_string_and_verify(char *filename, char *basedir, char *val); | ||
66 | int write_sysfs_string(char *filename, char *basedir, char *val); | ||
67 | int read_sysfs_posint(char *filename, char *basedir); | ||
68 | int read_sysfs_float(char *filename, char *basedir, float *val); | ||
69 | int read_sysfs_string(const char *filename, const char *basedir, char *str); | ||
70 | |||
71 | #endif /* _IIO_UTILS_H_ */ | ||
diff --git a/drivers/staging/iio/Documentation/lsiio.c b/tools/iio/lsiio.c index 98a0de098130..c585440f864e 100644 --- a/drivers/staging/iio/Documentation/lsiio.c +++ b/tools/iio/lsiio.c | |||
@@ -95,12 +95,7 @@ static int dump_one_trigger(const char *dev_dir_name) | |||
95 | static void dump_devices(void) | 95 | static void dump_devices(void) |
96 | { | 96 | { |
97 | const struct dirent *ent; | 97 | const struct dirent *ent; |
98 | int number, numstrlen; | ||
99 | |||
100 | FILE *nameFile; | ||
101 | DIR *dp; | 98 | DIR *dp; |
102 | char thisname[IIO_MAX_NAME_LENGTH]; | ||
103 | char *filename; | ||
104 | 99 | ||
105 | dp = opendir(iio_dir); | 100 | dp = opendir(iio_dir); |
106 | if (dp == NULL) { | 101 | if (dp == NULL) { |