Jonathan writes: Second set of new device support, cleanups and features for IIO in the 5.8 cycle Usual mixed back but with a few subsystem wide or device type wide cleanups. New device support * adis16475 - New driver supporting adis16470, adis16475, adis16477, adis16465, adis16467, adis16500, adis16505 and adis16507. Includes some rework of the adis library to simplify using it for this new driver. * ak8974 - Add support for Alps hscdt008a. ID only. Related patches add support for scale. * atlas-sensor - Add support for RTD-SM OEM temperature sensor. * cm32181 - Add support for CM3218 including support for SMBUS alert via ACPI resources. * ltc2632 - Add support for ltc2634-12/10/8 DACS including handling per device type numbers of channels. Major Features * cm32181 - ACPI bindings including parsing CPM0 and CPM1 custom ACPI tables. Includes minor tidy ups and fixes. * vcnl4000 - Add event support - Add buffered data capture support - Add control of sampling frequency Cleanups and minor fixes. * core - Trivial rework of iio_device_alloc to use an early return and improve readability. - Precursors to addition of multiple buffer support. So far minor refactoring. * subsystem wide - Use get_unaligned_be24 slightly improve readability over open coding it. * adis drivers - Use iio_get_debugfs_dentry access function. * bh1780, cm32181, cm3232, gp2ap02a00f, opt3001, st_uvis25, vl6180, dmard06, kxsd9 - Drop use of of_match_ptr to allow ACPI based probing via PRP0001. Part of clear out of this to avoid cut and paste into new drivers. * ad5592r, ad5593r - Fix typos * ad5933 - Use managed interfaces to automate error handling and remove. * ak8974 - Fix wrong number of 'real bits' for buffered data. - Refactor to pull measurement code out as separate function. bmp280 - Fix lack of clamp on range during data capture. * at91-sama5d2_adc - Handle unfinished conversions correctly. - Allow use of triggers other than it's own. - Reorganize buffer setup and tear down as part of long running subsystem wide rework. * ccs811 - Add DT binding docs and match table. - Support external reset and wakeup pins. * hid-sensors - Reorganize buffer setup and tear down as part of long running subsystem wide rework. * ltr501 - Constify some structs. * vcnl4000 - Fix an endian issue by using explicit byte swapped i2c accessors. * tag 'iio-for-5.8b' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (74 commits) iio: light: ltr501: Constify structs staging: iio: ad5933: attach life-cycle of kfifo buffer to parent device and use managed calls throughout iio: bmp280: fix compensation of humidity iio: light: cm32181: Fix integartion time typo iio: light: cm32181: Add support for parsing CPM0 and CPM1 ACPI tables iio: light: cm32181: Make lux_per_bit and lux_per_bit_base_it runtime settings iio: light: cm32181: Use units of 1/100000th for calibscale and lux_per_bit iio: light: cm32181: Change reg_init to use a bitmap of which registers to init iio: light: cm32181: Handle CM3218 ACPI devices with 2 I2C resources iio: light: cm32181: Clean up the probe function a bit iio: light: cm32181: Add support for the CM3218 iio: light: cm32181: Add some extra register defines iio: light: cm32181: Add support for ACPI enumeration iio: light: cm32181: Switch to new style i2c-driver probe function iio: hid-sensors: move triggered buffer setup into hid_sensor_setup_trigger iio: vcnl4000: Add buffer support for VCNL4010/20. iio: vcnl4000: Add sampling frequency support for VCNL4010/20. iio: vcnl4000: Add event support for VCNL4010/20. iio: vcnl4000: Factorize data reading and writing. iio: vcnl4000: Fix i2c swapped word reading. ...
Unified · Split
| @@ -0,0 +1,53 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/iio/chemical/ams,ccs811.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: AMS CCS811 VOC Sensor | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Narcisa Vasile <narcisaanamaria12@gmail.com> | ||
| 11 | |||
| 12 | description: | | ||
| 13 | Ultra-Low Power Digital Gas Sensor for Monitoring Indoor Air Quality. | ||
| 14 | |||
| 15 | properties: | ||
| 16 | compatible: | ||
| 17 | enum: | ||
| 18 | - ams,ccs811 | ||
| 19 | reg: | ||
| 20 | maxItems: 1 | ||
| 21 | |||
| 22 | reset-gpios: | ||
| 23 | description: GPIO connected to the nRESET line. This is an active low | ||
| 24 | input to CCS811. | ||
| 25 | maxItems: 1 | ||
| 26 | |||
| 27 | wakeup-gpios: | ||
| 28 | description: GPIO connected to the nWAKE line. This is an active low | ||
| 29 | input to CCS811. | ||
| 30 | maxItems: 1 | ||
| 31 | |||
| 32 | required: | ||
| 33 | - compatible | ||
| 34 | - reg | ||
| 35 | |||
| 36 | additionalProperties: false | ||
| 37 | |||
| 38 | examples: | ||
| 39 | - | | ||
| 40 | #include <dt-bindings/gpio/gpio.h> | ||
| 41 | i2c { | ||
| 42 | #address-cells = <1>; | ||
| 43 | #size-cells = <0>; | ||
| 44 | |||
| 45 | voc@5b { | ||
| 46 | compatible = "ams,ccs811"; | ||
| 47 | reg = <0x5b>; | ||
| 48 | reset-gpios = <&gpioa 11 GPIO_ACTIVE_LOW>; | ||
| 49 | wakeup-gpios = <&gpioa 12 GPIO_ACTIVE_LOW>; | ||
| 50 | }; | ||
| 51 | }; | ||
| 52 | |||
| 53 | ... | ||
| @@ -17,6 +17,7 @@ description: | · 16 unmodified lines | |||
| 17 | http://www.atlas-scientific.com/_files/_datasheets/_oem/EC_oem_datasheet.pdf | 17 | http://www.atlas-scientific.com/_files/_datasheets/_oem/EC_oem_datasheet.pdf |
| 18 | http://www.atlas-scientific.com/_files/_datasheets/_oem/ORP_oem_datasheet.pdf | 18 | http://www.atlas-scientific.com/_files/_datasheets/_oem/ORP_oem_datasheet.pdf |
| 19 | http://www.atlas-scientific.com/_files/_datasheets/_oem/pH_oem_datasheet.pdf | 19 | http://www.atlas-scientific.com/_files/_datasheets/_oem/pH_oem_datasheet.pdf |
| 20 | http://www.atlas-scientific.com/_files/_datasheets/_oem/RTD_oem_datasheet.pdf | ||
| 20 | 21 | ||
| 21 | properties: | 22 | properties: |
| 22 | compatible: | 23 | compatible: |
| @@ -25,6 +26,7 @@ properties: · 2 unmodified lines | |||
| 25 | - atlas,ec-sm | 26 | - atlas,ec-sm |
| 26 | - atlas,orp-sm | 27 | - atlas,orp-sm |
| 27 | - atlas,ph-sm | 28 | - atlas,ph-sm |
| 29 | - atlas,rtd-sm | ||
| 28 | 30 | ||
| 29 | reg: | 31 | reg: |
| 30 | maxItems: 1 | 32 | maxItems: 1 |
| @@ -1,4 +1,4 @@ | |||
| 1 | Linear Technology LTC2632/2636 DAC | 1 | Linear Technology LTC2632/2634/2636 DAC |
| 2 | 2 | ||
| 3 | Required properties: | 3 | Required properties: |
| 4 | - compatible: Has to contain one of the following: | 4 | - compatible: Has to contain one of the following: |
| @@ -8,6 +8,12 @@ Required properties: · 3 unmodified lines | |||
| 8 | lltc,ltc2632-h12 | 8 | lltc,ltc2632-h12 |
| 9 | lltc,ltc2632-h10 | 9 | lltc,ltc2632-h10 |
| 10 | lltc,ltc2632-h8 | 10 | lltc,ltc2632-h8 |
| 11 | lltc,ltc2634-l12 | ||
| 12 | lltc,ltc2634-l10 | ||
| 13 | lltc,ltc2634-l8 | ||
| 14 | lltc,ltc2634-h12 | ||
| 15 | lltc,ltc2634-h10 | ||
| 16 | lltc,ltc2634-h8 | ||
| 11 | lltc,ltc2636-l12 | 17 | lltc,ltc2636-l12 |
| 12 | lltc,ltc2636-l10 | 18 | lltc,ltc2636-l10 |
| 13 | lltc,ltc2636-l8 | 19 | lltc,ltc2636-l8 |
| @@ -0,0 +1,137 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/iio/imu/adi,adis16475.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: Analog Devices ADIS16475 and similar IMUs | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Nuno Sá <nuno.sa@analog.com> | ||
| 11 | |||
| 12 | description: | | ||
| 13 | Analog Devices ADIS16475 and similar IMUs | ||
| 14 | https://www.analog.com/media/en/technical-documentation/data-sheets/ADIS16475.pdf | ||
| 15 | |||
| 16 | properties: | ||
| 17 | compatible: | ||
| 18 | enum: | ||
| 19 | - adi,adis16475-1 | ||
| 20 | - adi,adis16475-2 | ||
| 21 | - adi,adis16475-3 | ||
| 22 | - adi,adis16477-1 | ||
| 23 | - adi,adis16477-2 | ||
| 24 | - adi,adis16477-3 | ||
| 25 | - adi,adis16470 | ||
| 26 | - adi,adis16465-1 | ||
| 27 | - adi,adis16465-2 | ||
| 28 | - adi,adis16465-3 | ||
| 29 | - adi,adis16467-1 | ||
| 30 | - adi,adis16467-2 | ||
| 31 | - adi,adis16467-3 | ||
| 32 | - adi,adis16500 | ||
| 33 | - adi,adis16505-1 | ||
| 34 | - adi,adis16505-2 | ||
| 35 | - adi,adis16505-3 | ||
| 36 | - adi,adis16507-1 | ||
| 37 | - adi,adis16507-2 | ||
| 38 | - adi,adis16507-3 | ||
| 39 | |||
| 40 | reg: | ||
| 41 | maxItems: 1 | ||
| 42 | |||
| 43 | spi-cpha: true | ||
| 44 | |||
| 45 | spi-cpol: true | ||
| 46 | |||
| 47 | spi-max-frequency: | ||
| 48 | maximum: 2000000 | ||
| 49 | |||
| 50 | interrupts: | ||
| 51 | maxItems: 1 | ||
| 52 | |||
| 53 | clocks: | ||
| 54 | maxItems: 1 | ||
| 55 | |||
| 56 | reset-gpios: | ||
| 57 | description: | ||
| 58 | Must be the device tree identifier of the RESET pin. If specified, | ||
| 59 | it will be asserted during driver probe. As the line is active low, | ||
| 60 | it should be marked GPIO_ACTIVE_LOW. | ||
| 61 | maxItems: 1 | ||
| 62 | |||
| 63 | adi,sync-mode: | ||
| 64 | description: | ||
| 65 | Configures the device SYNC pin. The following modes are supported | ||
| 66 | 0 - output_sync | ||
| 67 | 1 - direct_sync | ||
| 68 | 2 - scaled_sync | ||
| 69 | 3 - pulse_sync | ||
| 70 | allOf: | ||
| 71 | - $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 72 | minimum: 0 | ||
| 73 | maximum: 3 | ||
| 74 | |||
| 75 | adi,scaled-output-hz: | ||
| 76 | description: | ||
| 77 | This property must be present if the clock mode is scaled-sync through | ||
| 78 | clock-names property. In this mode, the input clock can have a range | ||
| 79 | of 1Hz to 128HZ which must be scaled to originate an allowable sample | ||
| 80 | rate. This property specifies that rate. | ||
| 81 | minimum: 1900 | ||
| 82 | maximum: 2100 | ||
| 83 | |||
| 84 | required: | ||
| 85 | - compatible | ||
| 86 | - reg | ||
| 87 | - interrupts | ||
| 88 | - spi-cpha | ||
| 89 | - spi-cpol | ||
| 90 | |||
| 91 | allOf: | ||
| 92 | - if: | ||
| 93 | properties: | ||
| 94 | compatible: | ||
| 95 | contains: | ||
| 96 | enum: | ||
| 97 | - adi,adis16500 | ||
| 98 | - adi,adis16505-1 | ||
| 99 | - adi,adis16505-2 | ||
| 100 | - adi,adis16505-3 | ||
| 101 | - adi,adis16507-1 | ||
| 102 | - adi,adis16507-2 | ||
| 103 | - adi,adis16507-3 | ||
| 104 | |||
| 105 | then: | ||
| 106 | properties: | ||
| 107 | adi,sync-mode: | ||
| 108 | minimum: 0 | ||
| 109 | maximum: 2 | ||
| 110 | |||
| 111 | - if: | ||
| 112 | properties: | ||
| 113 | adi,sync-mode: | ||
| 114 | enum: [1, 2, 3] | ||
| 115 | |||
| 116 | then: | ||
| 117 | dependencies: | ||
| 118 | adi,sync-mode: [ clocks ] | ||
| 119 | |||
| 120 | examples: | ||
| 121 | - | | ||
| 122 | #include <dt-bindings/interrupt-controller/irq.h> | ||
| 123 | spi { | ||
| 124 | #address-cells = <1>; | ||
| 125 | #size-cells = <0>; | ||
| 126 | |||
| 127 | adis16475: adis16475-3@0 { | ||
| 128 | compatible = "adi,adis16475-3"; | ||
| 129 | reg = <0>; | ||
| 130 | spi-cpha; | ||
| 131 | spi-cpol; | ||
| 132 | spi-max-frequency = <2000000>; | ||
| 133 | interrupts = <4 IRQ_TYPE_EDGE_RISING>; | ||
| 134 | interrupt-parent = <&gpio>; | ||
| 135 | }; | ||
| 136 | }; | ||
| 137 | ... | ||
| @@ -2,7 +2,9 @@ · 1 unmodified line | |||
| 2 | 2 | ||
| 3 | Required properties: | 3 | Required properties: |
| 4 | 4 | ||
| 5 | - compatible : should be "asahi-kasei,ak8974" | 5 | - compatible: |
| 6 | * "asahi-kasei,ak8974" | ||
| 7 | * "alps,hscdtd008a" | ||
| 6 | - reg : the I2C address of the magnetometer | 8 | - reg : the I2C address of the magnetometer |
| 7 | 9 | ||
| 8 | Optional properties: | 10 | Optional properties: |
| @@ -1031,6 +1031,14 @@ W: http://ez.analog.com/community/linux-device-drivers · 1030 unmodified lines | |||
| 1031 | F: Documentation/devicetree/bindings/iio/imu/adi,adis16460.yaml | 1031 | F: Documentation/devicetree/bindings/iio/imu/adi,adis16460.yaml |
| 1032 | F: drivers/iio/imu/adis16460.c | 1032 | F: drivers/iio/imu/adis16460.c |
| 1033 | 1033 | ||
| 1034 | ANALOG DEVICES INC ADIS16475 DRIVER | ||
| 1035 | M: Nuno Sa <nuno.sa@analog.com> | ||
| 1036 | L: linux-iio@vger.kernel.org | ||
| 1037 | W: http://ez.analog.com/community/linux-device-drivers | ||
| 1038 | S: Supported | ||
| 1039 | F: drivers/iio/imu/adis16475.c | ||
| 1040 | F: Documentation/devicetree/bindings/iio/imu/adi,adis16475.yaml | ||
| 1041 | |||
| 1034 | ANALOG DEVICES INC ADM1177 DRIVER | 1042 | ANALOG DEVICES INC ADM1177 DRIVER |
| 1035 | M: Beniamin Bia <beniamin.bia@analog.com> | 1043 | M: Beniamin Bia <beniamin.bia@analog.com> |
| 1036 | M: Michael Hennerich <Michael.Hennerich@analog.com> | 1044 | M: Michael Hennerich <Michael.Hennerich@analog.com> |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | */ | 6 | */ |
| 7 | 7 | ||
| 8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
| 9 | #include <linux/mod_devicetable.h> | ||
| 9 | #include <linux/i2c.h> | 10 | #include <linux/i2c.h> |
| 10 | #include <linux/iio/iio.h> | 11 | #include <linux/iio/iio.h> |
| 11 | 12 | ||
| @@ -226,7 +227,7 @@ static struct i2c_driver dmard06_driver = { · 214 unmodified lines | |||
| 226 | .id_table = dmard06_id, | 227 | .id_table = dmard06_id, |
| 227 | .driver = { | 228 | .driver = { |
| 228 | .name = DMARD06_DRV_NAME, | 229 | .name = DMARD06_DRV_NAME, |
| 229 | .of_match_table = of_match_ptr(dmard06_of_match), | 230 | .of_match_table = dmard06_of_match, |
| 230 | .pm = DMARD06_PM_OPS, | 231 | .pm = DMARD06_PM_OPS, |
| 231 | }, | 232 | }, |
| 232 | }; | 233 | }; |
| @@ -14,8 +14,6 @@ · 13 unmodified lines | |||
| 14 | #include <linux/iio/iio.h> | 14 | #include <linux/iio/iio.h> |
| 15 | #include <linux/iio/sysfs.h> | 15 | #include <linux/iio/sysfs.h> |
| 16 | #include <linux/iio/buffer.h> | 16 | #include <linux/iio/buffer.h> |
| 17 | #include <linux/iio/trigger_consumer.h> | ||
| 18 | #include <linux/iio/triggered_buffer.h> | ||
| 19 | #include "../common/hid-sensors/hid-sensor-trigger.h" | 17 | #include "../common/hid-sensors/hid-sensor-trigger.h" |
| 20 | 18 | ||
| 21 | enum accel_3d_channel { | 19 | enum accel_3d_channel { |
| @@ -391,18 +389,13 @@ static int hid_accel_3d_probe(struct platform_device *pdev) · 369 unmodified lines | |||
| 391 | indio_dev->name = name; | 389 | indio_dev->name = name; |
| 392 | indio_dev->modes = INDIO_DIRECT_MODE; | 390 | indio_dev->modes = INDIO_DIRECT_MODE; |
| 393 | 391 | ||
| 394 | ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, | ||
| 395 | NULL, NULL); | ||
| 396 | if (ret) { | ||
| 397 | dev_err(&pdev->dev, "failed to initialize trigger buffer\n"); | ||
| 398 | goto error_free_dev_mem; | ||
| 399 | } | ||
| 400 | atomic_set(&accel_state->common_attributes.data_ready, 0); | 392 | atomic_set(&accel_state->common_attributes.data_ready, 0); |
| 393 | |||
| 401 | ret = hid_sensor_setup_trigger(indio_dev, name, | 394 | ret = hid_sensor_setup_trigger(indio_dev, name, |
| 402 | &accel_state->common_attributes); | 395 | &accel_state->common_attributes); |
| 403 | if (ret < 0) { | 396 | if (ret < 0) { |
| 404 | dev_err(&pdev->dev, "trigger setup failed\n"); | 397 | dev_err(&pdev->dev, "trigger setup failed\n"); |
| 405 | goto error_unreg_buffer_funcs; | 398 | goto error_free_dev_mem; |
| 406 | } | 399 | } |
| 407 | 400 | ||
| 408 | ret = iio_device_register(indio_dev); | 401 | ret = iio_device_register(indio_dev); |
| @@ -426,9 +419,7 @@ static int hid_accel_3d_probe(struct platform_device *pdev) · 17 unmodified lines | |||
| 426 | error_iio_unreg: | 419 | error_iio_unreg: |
| 427 | iio_device_unregister(indio_dev); | 420 | iio_device_unregister(indio_dev); |
| 428 | error_remove_trigger: | 421 | error_remove_trigger: |
| 429 | hid_sensor_remove_trigger(&accel_state->common_attributes); | 422 | hid_sensor_remove_trigger(indio_dev, &accel_state->common_attributes); |
| 430 | error_unreg_buffer_funcs: | ||
| 431 | iio_triggered_buffer_cleanup(indio_dev); | ||
| 432 | error_free_dev_mem: | 423 | error_free_dev_mem: |
| 433 | kfree(indio_dev->channels); | 424 | kfree(indio_dev->channels); |
| 434 | return ret; | 425 | return ret; |
| @@ -443,8 +434,7 @@ static int hid_accel_3d_remove(struct platform_device *pdev) · 8 unmodified lines | |||
| 443 | 434 | ||
| 444 | sensor_hub_remove_callback(hsdev, hsdev->usage); | 435 | sensor_hub_remove_callback(hsdev, hsdev->usage); |
| 445 | iio_device_unregister(indio_dev); | 436 | iio_device_unregister(indio_dev); |
| 446 | hid_sensor_remove_trigger(&accel_state->common_attributes); | 437 | hid_sensor_remove_trigger(indio_dev, &accel_state->common_attributes); |
| 447 | iio_triggered_buffer_cleanup(indio_dev); | ||
| 448 | kfree(indio_dev->channels); | 438 | kfree(indio_dev->channels); |
| 449 | 439 | ||
| 450 | return 0; | 440 | return 0; |
| @@ -2,6 +2,7 @@ · 1 unmodified line | |||
| 2 | #include <linux/device.h> | 2 | #include <linux/device.h> |
| 3 | #include <linux/kernel.h> | 3 | #include <linux/kernel.h> |
| 4 | #include <linux/module.h> | 4 | #include <linux/module.h> |
| 5 | #include <linux/mod_devicetable.h> | ||
| 5 | #include <linux/slab.h> | 6 | #include <linux/slab.h> |
| 6 | #include <linux/i2c.h> | 7 | #include <linux/i2c.h> |
| 7 | #include <linux/delay.h> | 8 | #include <linux/delay.h> |
| @@ -36,15 +37,11 @@ static int kxsd9_i2c_remove(struct i2c_client *client) · 28 unmodified lines | |||
| 36 | return kxsd9_common_remove(&client->dev); | 37 | return kxsd9_common_remove(&client->dev); |
| 37 | } | 38 | } |
| 38 | 39 | ||
| 39 | #ifdef CONFIG_OF | ||
| 40 | static const struct of_device_id kxsd9_of_match[] = { | 40 | static const struct of_device_id kxsd9_of_match[] = { |
| 41 | { .compatible = "kionix,kxsd9", }, | 41 | { .compatible = "kionix,kxsd9", }, |
| 42 | { }, | 42 | { }, |
| 43 | }; | 43 | }; |
| 44 | MODULE_DEVICE_TABLE(of, kxsd9_of_match); | 44 | MODULE_DEVICE_TABLE(of, kxsd9_of_match); |
| 45 | #else | ||
| 46 | #define kxsd9_of_match NULL | ||
| 47 | #endif | ||
| 48 | 45 | ||
| 49 | static const struct i2c_device_id kxsd9_i2c_id[] = { | 46 | static const struct i2c_device_id kxsd9_i2c_id[] = { |
| 50 | {"kxsd9", 0}, | 47 | {"kxsd9", 0}, |
| @@ -55,7 +52,7 @@ MODULE_DEVICE_TABLE(i2c, kxsd9_i2c_id); · 4 unmodified lines | |||
| 55 | static struct i2c_driver kxsd9_i2c_driver = { | 52 | static struct i2c_driver kxsd9_i2c_driver = { |
| 56 | .driver = { | 53 | .driver = { |
| 57 | .name = "kxsd9", | 54 | .name = "kxsd9", |
| 58 | .of_match_table = of_match_ptr(kxsd9_of_match), | 55 | .of_match_table = kxsd9_of_match, |
| 59 | .pm = &kxsd9_dev_pm_ops, | 56 | .pm = &kxsd9_dev_pm_ops, |
| 60 | }, | 57 | }, |
| 61 | .probe = kxsd9_i2c_probe, | 58 | .probe = kxsd9_i2c_probe, |
| @@ -309,7 +309,7 @@ static int ad7476_probe(struct spi_device *spi) · 308 unmodified lines | |||
| 309 | indio_dev->num_channels = 2; | 309 | indio_dev->num_channels = 2; |
| 310 | indio_dev->info = &ad7476_info; | 310 | indio_dev->info = &ad7476_info; |
| 311 | 311 | ||
| 312 | if (st->convst_gpio && st->chip_info->convst_channel) | 312 | if (st->convst_gpio) |
| 313 | indio_dev->channels = st->chip_info->convst_channel; | 313 | indio_dev->channels = st->chip_info->convst_channel; |
| 314 | /* Setup default message */ | 314 | /* Setup default message */ |
| 315 | 315 | ||
| @@ -70,9 +70,7 @@ int ad_sd_write_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg, · 69 unmodified lines | |||
| 70 | 70 | ||
| 71 | switch (size) { | 71 | switch (size) { |
| 72 | case 3: | 72 | case 3: |
| 73 | data[1] = val >> 16; | 73 | put_unaligned_be24(val, &data[1]); |
| 74 | data[2] = val >> 8; | ||
| 75 | data[3] = val; | ||
| 76 | break; | 74 | break; |
| 77 | case 2: | 75 | case 2: |
| 78 | put_unaligned_be16(val, &data[1]); | 76 | put_unaligned_be16(val, &data[1]); |
| @@ -157,9 +155,7 @@ int ad_sd_read_reg(struct ad_sigma_delta *sigma_delta, · 78 unmodified lines | |||
| 157 | *val = get_unaligned_be32(sigma_delta->data); | 155 | *val = get_unaligned_be32(sigma_delta->data); |
| 158 | break; | 156 | break; |
| 159 | case 3: | 157 | case 3: |
| 160 | *val = (sigma_delta->data[0] << 16) | | 158 | *val = get_unaligned_be24(&sigma_delta->data[0]); |
| 161 | (sigma_delta->data[1] << 8) | | ||
| 162 | sigma_delta->data[2]; | ||
| 163 | break; | 159 | break; |
| 164 | case 2: | 160 | case 2: |
| 165 | *val = get_unaligned_be16(sigma_delta->data); | 161 | *val = get_unaligned_be16(sigma_delta->data); |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | |||
| 8 | 8 | ||
| 9 | #include <linux/bitops.h> | 9 | #include <linux/bitops.h> |
| 10 | #include <linux/clk.h> | 10 | #include <linux/clk.h> |
| 11 | #include <linux/delay.h> | ||
| 11 | #include <linux/dma-mapping.h> | 12 | #include <linux/dma-mapping.h> |
| 12 | #include <linux/dmaengine.h> | 13 | #include <linux/dmaengine.h> |
| 13 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
| @@ -100,6 +101,8 @@ · 86 unmodified lines | |||
| 100 | #define AT91_SAMA5D2_IER_YRDY BIT(21) | 101 | #define AT91_SAMA5D2_IER_YRDY BIT(21) |
| 101 | /* Interrupt Enable Register - TS pressure measurement ready */ | 102 | /* Interrupt Enable Register - TS pressure measurement ready */ |
| 102 | #define AT91_SAMA5D2_IER_PRDY BIT(22) | 103 | #define AT91_SAMA5D2_IER_PRDY BIT(22) |
| 104 | /* Interrupt Enable Register - Data ready */ | ||
| 105 | #define AT91_SAMA5D2_IER_DRDY BIT(24) | ||
| 103 | /* Interrupt Enable Register - general overrun error */ | 106 | /* Interrupt Enable Register - general overrun error */ |
| 104 | #define AT91_SAMA5D2_IER_GOVRE BIT(25) | 107 | #define AT91_SAMA5D2_IER_GOVRE BIT(25) |
| 105 | /* Interrupt Enable Register - Pen detect */ | 108 | /* Interrupt Enable Register - Pen detect */ |
| @@ -486,6 +489,21 @@ static inline int at91_adc_of_xlate(struct iio_dev *indio_dev, · 380 unmodified lines | |||
| 486 | return at91_adc_chan_xlate(indio_dev, iiospec->args[0]); | 489 | return at91_adc_chan_xlate(indio_dev, iiospec->args[0]); |
| 487 | } | 490 | } |
| 488 | 491 | ||
| 492 | static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev) | ||
| 493 | { | ||
| 494 | u32 mask = 0; | ||
| 495 | u8 bit; | ||
| 496 | |||
| 497 | for_each_set_bit(bit, indio_dev->active_scan_mask, | ||
| 498 | indio_dev->num_channels) { | ||
| 499 | struct iio_chan_spec const *chan = | ||
| 500 | at91_adc_chan_get(indio_dev, bit); | ||
| 501 | mask |= BIT(chan->channel); | ||
| 502 | } | ||
| 503 | |||
| 504 | return mask & GENMASK(11, 0); | ||
| 505 | } | ||
| 506 | |||
| 489 | static void at91_adc_config_emr(struct at91_adc_state *st) | 507 | static void at91_adc_config_emr(struct at91_adc_state *st) |
| 490 | { | 508 | { |
| 491 | /* configure the extended mode register */ | 509 | /* configure the extended mode register */ |
| @@ -710,7 +728,6 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state) · 218 unmodified lines | |||
| 710 | struct iio_dev *indio = iio_trigger_get_drvdata(trig); | 728 | struct iio_dev *indio = iio_trigger_get_drvdata(trig); |
| 711 | struct at91_adc_state *st = iio_priv(indio); | 729 | struct at91_adc_state *st = iio_priv(indio); |
| 712 | u32 status = at91_adc_readl(st, AT91_SAMA5D2_TRGR); | 730 | u32 status = at91_adc_readl(st, AT91_SAMA5D2_TRGR); |
| 713 | u8 bit; | ||
| 714 | 731 | ||
| 715 | /* clear TRGMOD */ | 732 | /* clear TRGMOD */ |
| 716 | status &= ~AT91_SAMA5D2_TRGR_TRGMOD_MASK; | 733 | status &= ~AT91_SAMA5D2_TRGR_TRGMOD_MASK; |
| @@ -721,50 +738,6 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state) · 4 unmodified lines | |||
| 721 | /* set/unset hw trigger */ | 738 | /* set/unset hw trigger */ |
| 722 | at91_adc_writel(st, AT91_SAMA5D2_TRGR, status); | 739 | at91_adc_writel(st, AT91_SAMA5D2_TRGR, status); |
| 723 | 740 | ||
| 724 | for_each_set_bit(bit, indio->active_scan_mask, indio->num_channels) { | ||
| 725 | struct iio_chan_spec const *chan = at91_adc_chan_get(indio, bit); | ||
| 726 | u32 cor; | ||
| 727 | |||
| 728 | if (!chan) | ||
| 729 | continue; | ||
| 730 | /* these channel types cannot be handled by this trigger */ | ||
| 731 | if (chan->type == IIO_POSITIONRELATIVE || | ||
| 732 | chan->type == IIO_PRESSURE) | ||
| 733 | continue; | ||
| 734 | |||
| 735 | if (state) { | ||
| 736 | cor = at91_adc_readl(st, AT91_SAMA5D2_COR); | ||
| 737 | |||
| 738 | if (chan->differential) | ||
| 739 | cor |= (BIT(chan->channel) | | ||
| 740 | BIT(chan->channel2)) << | ||
| 741 | AT91_SAMA5D2_COR_DIFF_OFFSET; | ||
| 742 | else | ||
| 743 | cor &= ~(BIT(chan->channel) << | ||
| 744 | AT91_SAMA5D2_COR_DIFF_OFFSET); | ||
| 745 | |||
| 746 | at91_adc_writel(st, AT91_SAMA5D2_COR, cor); | ||
| 747 | } | ||
| 748 | |||
| 749 | if (state) { | ||
| 750 | at91_adc_writel(st, AT91_SAMA5D2_CHER, | ||
| 751 | BIT(chan->channel)); | ||
| 752 | /* enable irq only if not using DMA */ | ||
| 753 | if (!st->dma_st.dma_chan) { | ||
| 754 | at91_adc_writel(st, AT91_SAMA5D2_IER, | ||
| 755 | BIT(chan->channel)); | ||
| 756 | } | ||
| 757 | } else { | ||
| 758 | /* disable irq only if not using DMA */ | ||
| 759 | if (!st->dma_st.dma_chan) { | ||
| 760 | at91_adc_writel(st, AT91_SAMA5D2_IDR, | ||
| 761 | BIT(chan->channel)); | ||
| 762 | } | ||
| 763 | at91_adc_writel(st, AT91_SAMA5D2_CHDR, | ||
| 764 | BIT(chan->channel)); | ||
| 765 | } | ||
| 766 | } | ||
| 767 | |||
| 768 | return 0; | 741 | return 0; |
| 769 | } | 742 | } |
| 770 | 743 | ||
| @@ -781,6 +754,7 @@ static int at91_adc_reenable_trigger(struct iio_trigger *trig) · 10 unmodified lines | |||
| 781 | 754 | ||
| 782 | /* Needed to ACK the DRDY interruption */ | 755 | /* Needed to ACK the DRDY interruption */ |
| 783 | at91_adc_readl(st, AT91_SAMA5D2_LCDR); | 756 | at91_adc_readl(st, AT91_SAMA5D2_LCDR); |
| 757 | |||
| 784 | return 0; | 758 | return 0; |
| 785 | } | 759 | } |
| 786 | 760 | ||
| @@ -888,18 +862,37 @@ static int at91_adc_dma_start(struct iio_dev *indio_dev) · 101 unmodified lines | |||
| 888 | return 0; | 862 | return 0; |
| 889 | } | 863 | } |
| 890 | 864 | ||
| 891 | static int at91_adc_buffer_postenable(struct iio_dev *indio_dev) | 865 | static bool at91_adc_buffer_check_use_irq(struct iio_dev *indio, |
| 866 | struct at91_adc_state *st) | ||
| 867 | { | ||
| 868 | /* if using DMA, we do not use our own IRQ (we use DMA-controller) */ | ||
| 869 | if (st->dma_st.dma_chan) | ||
| 870 | return false; | ||
| 871 | /* if the trigger is not ours, then it has its own IRQ */ | ||
| 872 | if (iio_trigger_validate_own_device(indio->trig, indio)) | ||
| 873 | return false; | ||
| 874 | return true; | ||
| 875 | } | ||
| 876 | |||
| 877 | static bool at91_adc_current_chan_is_touch(struct iio_dev *indio_dev) | ||
| 878 | { | ||
| 879 | struct at91_adc_state *st = iio_priv(indio_dev); | ||
| 880 | |||
| 881 | return !!bitmap_subset(indio_dev->active_scan_mask, | ||
| 882 | &st->touch_st.channels_bitmask, | ||
| 883 | AT91_SAMA5D2_MAX_CHAN_IDX + 1); | ||
| 884 | } | ||
| 885 | |||
| 886 | static int at91_adc_buffer_preenable(struct iio_dev *indio_dev) | ||
| 892 | { | 887 | { |
| 893 | int ret; | 888 | int ret; |
| 889 | u8 bit; | ||
| 894 | struct at91_adc_state *st = iio_priv(indio_dev); | 890 | struct at91_adc_state *st = iio_priv(indio_dev); |
| 895 | 891 | ||
| 896 | /* check if we are enabling triggered buffer or the touchscreen */ | 892 | /* check if we are enabling triggered buffer or the touchscreen */ |
| 897 | if (bitmap_subset(indio_dev->active_scan_mask, | 893 | if (at91_adc_current_chan_is_touch(indio_dev)) |
| 898 | &st->touch_st.channels_bitmask, | ||
| 899 | AT91_SAMA5D2_MAX_CHAN_IDX + 1)) { | ||
| 900 | /* touchscreen enabling */ | ||
| 901 | return at91_adc_configure_touch(st, true); | 894 | return at91_adc_configure_touch(st, true); |
| 902 | } | 895 | |
| 903 | /* if we are not in triggered mode, we cannot enable the buffer. */ | 896 | /* if we are not in triggered mode, we cannot enable the buffer. */ |
| 904 | if (!(indio_dev->currentmode & INDIO_ALL_TRIGGERED_MODES)) | 897 | if (!(indio_dev->currentmode & INDIO_ALL_TRIGGERED_MODES)) |
| 905 | return -EINVAL; | 898 | return -EINVAL; |
| @@ -911,41 +904,65 @@ static int at91_adc_buffer_postenable(struct iio_dev *indio_dev) · 5 unmodified lines | |||
| 911 | return ret; | 904 | return ret; |
| 912 | } | 905 | } |
| 913 | 906 | ||
| 907 | for_each_set_bit(bit, indio_dev->active_scan_mask, | ||
| 908 | indio_dev->num_channels) { | ||
| 909 | struct iio_chan_spec const *chan = | ||
| 910 | at91_adc_chan_get(indio_dev, bit); | ||
| 911 | u32 cor; | ||
| 912 | |||
| 913 | if (!chan) | ||
| 914 | continue; | ||
| 915 | /* these channel types cannot be handled by this trigger */ | ||
| 916 | if (chan->type == IIO_POSITIONRELATIVE || | ||
| 917 | chan->type == IIO_PRESSURE) | ||
| 918 | continue; | ||
| 919 | |||
| 920 | cor = at91_adc_readl(st, AT91_SAMA5D2_COR); | ||
| 921 | |||
| 922 | if (chan->differential) | ||
| 923 | cor |= (BIT(chan->channel) | BIT(chan->channel2)) << | ||
| 924 | AT91_SAMA5D2_COR_DIFF_OFFSET; | ||
| 925 | else | ||
| 926 | cor &= ~(BIT(chan->channel) << | ||
| 927 | AT91_SAMA5D2_COR_DIFF_OFFSET); | ||
| 928 | |||
| 929 | at91_adc_writel(st, AT91_SAMA5D2_COR, cor); | ||
| 930 | |||
| 931 | at91_adc_writel(st, AT91_SAMA5D2_CHER, BIT(chan->channel)); | ||
| 932 | } | ||
| 933 | |||
| 934 | if (at91_adc_buffer_check_use_irq(indio_dev, st)) | ||
| 935 | at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_DRDY); | ||
| 936 | |||
| 937 | return 0; | ||
| 938 | } | ||
| 939 | |||
| 940 | static int at91_adc_buffer_postenable(struct iio_dev *indio_dev) | ||
| 941 | { | ||
| 942 | if (at91_adc_current_chan_is_touch(indio_dev)) | ||
| 943 | return 0; | ||
| 944 | |||
| 914 | return iio_triggered_buffer_postenable(indio_dev); | 945 | return iio_triggered_buffer_postenable(indio_dev); |
| 915 | } | 946 | } |
| 916 | 947 | ||
| 917 | static int at91_adc_buffer_predisable(struct iio_dev *indio_dev) | 948 | static int at91_adc_buffer_postdisable(struct iio_dev *indio_dev) |
| 918 | { | 949 | { |
| 919 | struct at91_adc_state *st = iio_priv(indio_dev); | 950 | struct at91_adc_state *st = iio_priv(indio_dev); |
| 920 | int ret; | ||
| 921 | u8 bit; | 951 | u8 bit; |
| 922 | 952 | ||
| 923 | /* check if we are disabling triggered buffer or the touchscreen */ | 953 | /* check if we are disabling triggered buffer or the touchscreen */ |
| 924 | if (bitmap_subset(indio_dev->active_scan_mask, | 954 | if (at91_adc_current_chan_is_touch(indio_dev)) |
| 925 | &st->touch_st.channels_bitmask, | ||
| 926 | AT91_SAMA5D2_MAX_CHAN_IDX + 1)) { | ||
| 927 | /* touchscreen disable */ | ||
| 928 | return at91_adc_configure_touch(st, false); | 955 | return at91_adc_configure_touch(st, false); |
| 929 | } | 956 | |
| 930 | /* if we are not in triggered mode, nothing to do here */ | 957 | /* if we are not in triggered mode, nothing to do here */ |
| 931 | if (!(indio_dev->currentmode & INDIO_ALL_TRIGGERED_MODES)) | 958 | if (!(indio_dev->currentmode & INDIO_ALL_TRIGGERED_MODES)) |
| 932 | return -EINVAL; | 959 | return -EINVAL; |
| 933 | 960 | ||
| 934 | /* continue with the triggered buffer */ | ||
| 935 | ret = iio_triggered_buffer_predisable(indio_dev); | ||
| 936 | if (ret < 0) | ||
| 937 | dev_err(&indio_dev->dev, "buffer predisable failed\n"); | ||
| 938 | |||
| 939 | if (!st->dma_st.dma_chan) | ||
| 940 | return ret; | ||
| 941 | |||
| 942 | /* if we are using DMA we must clear registers and end DMA */ | ||
| 943 | dmaengine_terminate_sync(st->dma_st.dma_chan); | ||
| 944 | |||
| 945 | /* | 961 | /* |
| 946 | * For each enabled channel we must read the last converted value | 962 | * For each enable channel we must disable it in hardware. |
| 963 | * In the case of DMA, we must read the last converted value | ||
| 947 | * to clear EOC status and not get a possible interrupt later. | 964 | * to clear EOC status and not get a possible interrupt later. |
| 948 | * This value is being read by DMA from LCDR anyway | 965 | * This value is being read by DMA from LCDR anyway, so it's not lost. |
| 949 | */ | 966 | */ |
| 950 | for_each_set_bit(bit, indio_dev->active_scan_mask, | 967 | for_each_set_bit(bit, indio_dev->active_scan_mask, |
| 951 | indio_dev->num_channels) { | 968 | indio_dev->num_channels) { |
| @@ -958,16 +975,37 @@ static int at91_adc_buffer_predisable(struct iio_dev *indio_dev) · 6 unmodified lines | |||
| 958 | if (chan->type == IIO_POSITIONRELATIVE || | 975 | if (chan->type == IIO_POSITIONRELATIVE || |
| 959 | chan->type == IIO_PRESSURE) | 976 | chan->type == IIO_PRESSURE) |
| 960 | continue; | 977 | continue; |
| 978 | |||
| 979 | at91_adc_writel(st, AT91_SAMA5D2_CHDR, BIT(chan->channel)); | ||
| 980 | |||
| 961 | if (st->dma_st.dma_chan) | 981 | if (st->dma_st.dma_chan) |
| 962 | at91_adc_readl(st, chan->address); | 982 | at91_adc_readl(st, chan->address); |
| 963 | } | 983 | } |
| 964 | 984 | ||
| 985 | if (at91_adc_buffer_check_use_irq(indio_dev, st)) | ||
| 986 | at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_DRDY); | ||
| 987 | |||
| 965 | /* read overflow register to clear possible overflow status */ | 988 | /* read overflow register to clear possible overflow status */ |
| 966 | at91_adc_readl(st, AT91_SAMA5D2_OVER); | 989 | at91_adc_readl(st, AT91_SAMA5D2_OVER); |
| 967 | return ret; | 990 | |
| 991 | /* if we are using DMA we must clear registers and end DMA */ | ||
| 992 | if (st->dma_st.dma_chan) | ||
| 993 | dmaengine_terminate_sync(st->dma_st.dma_chan); | ||
| 994 | |||
| 995 | return 0; | ||
| 996 | } | ||
| 997 | |||
| 998 | static int at91_adc_buffer_predisable(struct iio_dev *indio_dev) | ||
| 999 | { | ||
| 1000 | if (at91_adc_current_chan_is_touch(indio_dev)) | ||
| 1001 | return 0; | ||
| 1002 | |||
| 1003 | return iio_triggered_buffer_predisable(indio_dev); | ||
| 968 | } | 1004 | } |
| 969 | 1005 | ||
| 970 | static const struct iio_buffer_setup_ops at91_buffer_setup_ops = { | 1006 | static const struct iio_buffer_setup_ops at91_buffer_setup_ops = { |
| 1007 | .preenable = &at91_adc_buffer_preenable, | ||
| 1008 | .postdisable = &at91_adc_buffer_postdisable, | ||
| 971 | .postenable = &at91_adc_buffer_postenable, | 1009 | .postenable = &at91_adc_buffer_postenable, |
| 972 | .predisable = &at91_adc_buffer_predisable, | 1010 | .predisable = &at91_adc_buffer_predisable, |
| 973 | }; | 1011 | }; |
| @@ -1015,6 +1053,22 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev, · 41 unmodified lines | |||
| 1015 | int i = 0; | 1053 | int i = 0; |
| 1016 | int val; | 1054 | int val; |
| 1017 | u8 bit; | 1055 | u8 bit; |
| 1056 | u32 mask = at91_adc_active_scan_mask_to_reg(indio_dev); | ||
| 1057 | unsigned int timeout = 50; | ||
| 1058 | |||
| 1059 | /* | ||
| 1060 | * Check if the conversion is ready. If not, wait a little bit, and | ||
| 1061 | * in case of timeout exit with an error. | ||
| 1062 | */ | ||
| 1063 | while ((at91_adc_readl(st, AT91_SAMA5D2_ISR) & mask) != mask && | ||
| 1064 | timeout) { | ||
| 1065 | usleep_range(50, 100); | ||
| 1066 | timeout--; | ||
| 1067 | } | ||
| 1068 | |||
| 1069 | /* Cannot read data, not ready. Continue without reporting data */ | ||
| 1070 | if (!timeout) | ||
| 1071 | return; | ||
| 1018 | 1072 | ||
| 1019 | for_each_set_bit(bit, indio_dev->active_scan_mask, | 1073 | for_each_set_bit(bit, indio_dev->active_scan_mask, |
| 1020 | indio_dev->num_channels) { | 1074 | indio_dev->num_channels) { |
| @@ -1102,6 +1156,13 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p) · 81 unmodified lines | |||
| 1102 | struct iio_dev *indio_dev = pf->indio_dev; | 1156 | struct iio_dev *indio_dev = pf->indio_dev; |
| 1103 | struct at91_adc_state *st = iio_priv(indio_dev); | 1157 | struct at91_adc_state *st = iio_priv(indio_dev); |
| 1104 | 1158 | ||
| 1159 | /* | ||
| 1160 | * If it's not our trigger, start a conversion now, as we are | ||
| 1161 | * actually polling the trigger now. | ||
| 1162 | */ | ||
| 1163 | if (iio_trigger_validate_own_device(indio_dev->trig, indio_dev)) | ||
| 1164 | at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_START); | ||
| 1165 | |||
| 1105 | if (st->dma_st.dma_chan) | 1166 | if (st->dma_st.dma_chan) |
| 1106 | at91_adc_trigger_handler_dma(indio_dev); | 1167 | at91_adc_trigger_handler_dma(indio_dev); |
| 1107 | else | 1168 | else |
| @@ -1114,20 +1175,9 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p) · 6 unmodified lines | |||
| 1114 | 1175 | ||
| 1115 | static int at91_adc_buffer_init(struct iio_dev *indio) | 1176 | static int at91_adc_buffer_init(struct iio_dev *indio) |
| 1116 | { | 1177 | { |
| 1117 | struct at91_adc_state *st = iio_priv(indio); | 1178 | return devm_iio_triggered_buffer_setup(&indio->dev, indio, |
| 1118 | 1179 | &iio_pollfunc_store_time, | |
| 1119 | if (st->selected_trig->hw_trig) { | 1180 | &at91_adc_trigger_handler, &at91_buffer_setup_ops); |
| 1120 | return devm_iio_triggered_buffer_setup(&indio->dev, indio, | ||
| 1121 | &iio_pollfunc_store_time, | ||
| 1122 | &at91_adc_trigger_handler, &at91_buffer_setup_ops); | ||
| 1123 | } | ||
| 1124 | /* | ||
| 1125 | * we need to prepare the buffer ops in case we will get | ||
| 1126 | * another buffer attached (like a callback buffer for the touchscreen) | ||
| 1127 | */ | ||
| 1128 | indio->setup_ops = &at91_buffer_setup_ops; | ||
| 1129 | |||
| 1130 | return 0; | ||
| 1131 | } | 1181 | } |
| 1132 | 1182 | ||
| 1133 | static unsigned at91_adc_startup_time(unsigned startup_time_min, | 1183 | static unsigned at91_adc_startup_time(unsigned startup_time_min, |
| @@ -1281,7 +1331,8 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private) · 147 unmodified lines | |||
| 1281 | status = at91_adc_readl(st, AT91_SAMA5D2_XPOSR); | 1331 | status = at91_adc_readl(st, AT91_SAMA5D2_XPOSR); |
| 1282 | status = at91_adc_readl(st, AT91_SAMA5D2_YPOSR); | 1332 | status = at91_adc_readl(st, AT91_SAMA5D2_YPOSR); |
| 1283 | status = at91_adc_readl(st, AT91_SAMA5D2_PRESSR); | 1333 | status = at91_adc_readl(st, AT91_SAMA5D2_PRESSR); |
| 1284 | } else if (iio_buffer_enabled(indio) && !st->dma_st.dma_chan) { | 1334 | } else if (iio_buffer_enabled(indio) && |
| 1335 | (status & AT91_SAMA5D2_IER_DRDY)) { | ||
| 1285 | /* triggered buffer without DMA */ | 1336 | /* triggered buffer without DMA */ |
| 1286 | disable_irq_nosync(irq); | 1337 | disable_irq_nosync(irq); |
| 1287 | iio_trigger_poll(indio->trig); | 1338 | iio_trigger_poll(indio->trig); |
| @@ -1901,14 +1952,10 @@ static __maybe_unused int at91_adc_resume(struct device *dev) · 613 unmodified lines | |||
| 1901 | return 0; | 1952 | return 0; |
| 1902 | 1953 | ||
| 1903 | /* check if we are enabling triggered buffer or the touchscreen */ | 1954 | /* check if we are enabling triggered buffer or the touchscreen */ |
| 1904 | if (bitmap_subset(indio_dev->active_scan_mask, | 1955 | if (at91_adc_current_chan_is_touch(indio_dev)) |
| 1905 | &st->touch_st.channels_bitmask, | ||
| 1906 | AT91_SAMA5D2_MAX_CHAN_IDX + 1)) { | ||
| 1907 | /* touchscreen enabling */ | ||
| 1908 | return at91_adc_configure_touch(st, true); | 1956 | return at91_adc_configure_touch(st, true); |
| 1909 | } else { | 1957 | else |
| 1910 | return at91_adc_configure_trigger(st->trig, true); | 1958 | return at91_adc_configure_trigger(st->trig, true); |
| 1911 | } | ||
| 1912 | 1959 | ||
| 1913 | /* not needed but more explicit */ | 1960 | /* not needed but more explicit */ |
| 1914 | return 0; | 1961 | return 0; |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
| 20 | #include <linux/sysfs.h> | 20 | #include <linux/sysfs.h> |
| 21 | #include <linux/of.h> | 21 | #include <linux/of.h> |
| 22 | #include <asm/unaligned.h> | ||
| 22 | 23 | ||
| 23 | #include <linux/iio/iio.h> | 24 | #include <linux/iio/iio.h> |
| 24 | #include <linux/iio/sysfs.h> | 25 | #include <linux/iio/sysfs.h> |
| @@ -117,11 +118,11 @@ static int mcp3422_read(struct mcp3422 *adc, int *value, u8 *config) · 92 unmodified lines | |||
| 117 | 118 | ||
| 118 | if (sample_rate == MCP3422_SRATE_3) { | 119 | if (sample_rate == MCP3422_SRATE_3) { |
| 119 | ret = i2c_master_recv(adc->i2c, buf, 4); | 120 | ret = i2c_master_recv(adc->i2c, buf, 4); |
| 120 | temp = buf[0] << 16 | buf[1] << 8 | buf[2]; | 121 | temp = get_unaligned_be24(&buf[0]); |
| 121 | *config = buf[3]; | 122 | *config = buf[3]; |
| 122 | } else { | 123 | } else { |
| 123 | ret = i2c_master_recv(adc->i2c, buf, 3); | 124 | ret = i2c_master_recv(adc->i2c, buf, 3); |
| 124 | temp = buf[0] << 8 | buf[1]; | 125 | temp = get_unaligned_be16(&buf[0]); |
| 125 | *config = buf[2]; | 126 | *config = buf[2]; |
| 126 | } | 127 | } |
| 127 | 128 | ||
| @@ -22,6 +22,8 @@ · 21 unmodified lines | |||
| 22 | #include <linux/iio/triggered_buffer.h> | 22 | #include <linux/iio/triggered_buffer.h> |
| 23 | #include <linux/iio/sysfs.h> | 23 | #include <linux/iio/sysfs.h> |
| 24 | 24 | ||
| 25 | #include <asm/unaligned.h> | ||
| 26 | |||
| 25 | /* Commands */ | 27 | /* Commands */ |
| 26 | #define ADS124S08_CMD_NOP 0x00 | 28 | #define ADS124S08_CMD_NOP 0x00 |
| 27 | #define ADS124S08_CMD_WAKEUP 0x02 | 29 | #define ADS124S08_CMD_WAKEUP 0x02 |
| @@ -188,7 +190,6 @@ static int ads124s_read(struct iio_dev *indio_dev, unsigned int chan) · 160 unmodified lines | |||
| 188 | { | 190 | { |
| 189 | struct ads124s_private *priv = iio_priv(indio_dev); | 191 | struct ads124s_private *priv = iio_priv(indio_dev); |
| 190 | int ret; | 192 | int ret; |
| 191 | u32 tmp; | ||
| 192 | struct spi_transfer t[] = { | 193 | struct spi_transfer t[] = { |
| 193 | { | 194 | { |
| 194 | .tx_buf = &priv->data[0], | 195 | .tx_buf = &priv->data[0], |
| @@ -208,9 +209,7 @@ static int ads124s_read(struct iio_dev *indio_dev, unsigned int chan) · 13 unmodified lines | |||
| 208 | if (ret < 0) | 209 | if (ret < 0) |
| 209 | return ret; | 210 | return ret; |
| 210 | 211 | ||
| 211 | tmp = priv->data[2] << 16 | priv->data[3] << 8 | priv->data[4]; | 212 | return get_unaligned_be24(&priv->data[2]); |
| 212 | |||
| 213 | return tmp; | ||
| 214 | } | 213 | } |
| 215 | 214 | ||
| 216 | static int ads124s_read_raw(struct iio_dev *indio_dev, | 215 | static int ads124s_read_raw(struct iio_dev *indio_dev, |
| @@ -53,6 +53,8 @@ · 52 unmodified lines | |||
| 53 | #define ATLAS_REG_DO_CALIB_STATUS_PRESSURE BIT(0) | 53 | #define ATLAS_REG_DO_CALIB_STATUS_PRESSURE BIT(0) |
| 54 | #define ATLAS_REG_DO_CALIB_STATUS_DO BIT(1) | 54 | #define ATLAS_REG_DO_CALIB_STATUS_DO BIT(1) |
| 55 | 55 | ||
| 56 | #define ATLAS_REG_RTD_DATA 0x0e | ||
| 57 | |||
| 56 | #define ATLAS_REG_PH_TEMP_DATA 0x0e | 58 | #define ATLAS_REG_PH_TEMP_DATA 0x0e |
| 57 | #define ATLAS_REG_PH_DATA 0x16 | 59 | #define ATLAS_REG_PH_DATA 0x16 |
| 58 | 60 | ||
| @@ -72,12 +74,14 @@ · 13 unmodified lines | |||
| 72 | #define ATLAS_EC_INT_TIME_IN_MS 650 | 74 | #define ATLAS_EC_INT_TIME_IN_MS 650 |
| 73 | #define ATLAS_ORP_INT_TIME_IN_MS 450 | 75 | #define ATLAS_ORP_INT_TIME_IN_MS 450 |
| 74 | #define ATLAS_DO_INT_TIME_IN_MS 450 | 76 | #define ATLAS_DO_INT_TIME_IN_MS 450 |
| 77 | #define ATLAS_RTD_INT_TIME_IN_MS 450 | ||
| 75 | 78 | ||
| 76 | enum { | 79 | enum { |
| 77 | ATLAS_PH_SM, | 80 | ATLAS_PH_SM, |
| 78 | ATLAS_EC_SM, | 81 | ATLAS_EC_SM, |
| 79 | ATLAS_ORP_SM, | 82 | ATLAS_ORP_SM, |
| 80 | ATLAS_DO_SM, | 83 | ATLAS_DO_SM, |
| 84 | ATLAS_RTD_SM, | ||
| 81 | }; | 85 | }; |
| 82 | 86 | ||
| 83 | struct atlas_data { | 87 | struct atlas_data { |
| @@ -206,6 +210,22 @@ static const struct iio_chan_spec atlas_do_channels[] = { · 122 unmodified lines | |||
| 206 | }, | 210 | }, |
| 207 | }; | 211 | }; |
| 208 | 212 | ||
| 213 | static const struct iio_chan_spec atlas_rtd_channels[] = { | ||
| 214 | { | ||
| 215 | .type = IIO_TEMP, | ||
| 216 | .address = ATLAS_REG_RTD_DATA, | ||
| 217 | .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), | ||
| 218 | .scan_index = 0, | ||
| 219 | .scan_type = { | ||
| 220 | .sign = 's', | ||
| 221 | .realbits = 32, | ||
| 222 | .storagebits = 32, | ||
| 223 | .endianness = IIO_BE, | ||
| 224 | }, | ||
| 225 | }, | ||
| 226 | IIO_CHAN_SOFT_TIMESTAMP(1), | ||
| 227 | }; | ||
| 228 | |||
| 209 | static int atlas_check_ph_calibration(struct atlas_data *data) | 229 | static int atlas_check_ph_calibration(struct atlas_data *data) |
| 210 | { | 230 | { |
| 211 | struct device *dev = &data->client->dev; | 231 | struct device *dev = &data->client->dev; |
| @@ -350,6 +370,12 @@ static struct atlas_device atlas_devices[] = { · 138 unmodified lines | |||
| 350 | .calibration = &atlas_check_do_calibration, | 370 | .calibration = &atlas_check_do_calibration, |
| 351 | .delay = ATLAS_DO_INT_TIME_IN_MS, | 371 | .delay = ATLAS_DO_INT_TIME_IN_MS, |
| 352 | }, | 372 | }, |
| 373 | [ATLAS_RTD_SM] = { | ||
| 374 | .channels = atlas_rtd_channels, | ||
| 375 | .num_channels = 2, | ||
| 376 | .data_reg = ATLAS_REG_RTD_DATA, | ||
| 377 | .delay = ATLAS_RTD_INT_TIME_IN_MS, | ||
| 378 | }, | ||
| 353 | }; | 379 | }; |
| 354 | 380 | ||
| 355 | static int atlas_set_powermode(struct atlas_data *data, int on) | 381 | static int atlas_set_powermode(struct atlas_data *data, int on) |
| @@ -477,6 +503,7 @@ static int atlas_read_raw(struct iio_dev *indio_dev, · 121 unmodified lines | |||
| 477 | struct atlas_data *data = iio_priv(indio_dev); | 503 | struct atlas_data *data = iio_priv(indio_dev); |
| 478 | 504 | ||
| 479 | switch (mask) { | 505 | switch (mask) { |
| 506 | case IIO_CHAN_INFO_PROCESSED: | ||
| 480 | case IIO_CHAN_INFO_RAW: { | 507 | case IIO_CHAN_INFO_RAW: { |
| 481 | int ret; | 508 | int ret; |
| 482 | __be32 reg; | 509 | __be32 reg; |
| @@ -565,6 +592,7 @@ static const struct i2c_device_id atlas_id[] = { · 82 unmodified lines | |||
| 565 | { "atlas-ec-sm", ATLAS_EC_SM}, | 592 | { "atlas-ec-sm", ATLAS_EC_SM}, |
| 566 | { "atlas-orp-sm", ATLAS_ORP_SM}, | 593 | { "atlas-orp-sm", ATLAS_ORP_SM}, |
| 567 | { "atlas-do-sm", ATLAS_DO_SM}, | 594 | { "atlas-do-sm", ATLAS_DO_SM}, |
| 595 | { "atlas-rtd-sm", ATLAS_RTD_SM}, | ||
| 568 | {} | 596 | {} |
| 569 | }; | 597 | }; |
| 570 | MODULE_DEVICE_TABLE(i2c, atlas_id); | 598 | MODULE_DEVICE_TABLE(i2c, atlas_id); |
| @@ -574,6 +602,7 @@ static const struct of_device_id atlas_dt_ids[] = { · 3 unmodified lines | |||
| 574 | { .compatible = "atlas,ec-sm", .data = (void *)ATLAS_EC_SM, }, | 602 | { .compatible = "atlas,ec-sm", .data = (void *)ATLAS_EC_SM, }, |
| 575 | { .compatible = "atlas,orp-sm", .data = (void *)ATLAS_ORP_SM, }, | 603 | { .compatible = "atlas,orp-sm", .data = (void *)ATLAS_ORP_SM, }, |
| 576 | { .compatible = "atlas,do-sm", .data = (void *)ATLAS_DO_SM, }, | 604 | { .compatible = "atlas,do-sm", .data = (void *)ATLAS_DO_SM, }, |
| 605 | { .compatible = "atlas,rtd-sm", .data = (void *)ATLAS_RTD_SM, }, | ||
| 577 | { } | 606 | { } |
| 578 | }; | 607 | }; |
| 579 | MODULE_DEVICE_TABLE(of, atlas_dt_ids); | 608 | MODULE_DEVICE_TABLE(of, atlas_dt_ids); |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | |||
| 16 | */ | 16 | */ |
| 17 | 17 | ||
| 18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
| 19 | #include <linux/gpio/consumer.h> | ||
| 19 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
| 20 | #include <linux/iio/iio.h> | 21 | #include <linux/iio/iio.h> |
| 21 | #include <linux/iio/buffer.h> | 22 | #include <linux/iio/buffer.h> |
| @@ -36,6 +37,7 @@ · 14 unmodified lines | |||
| 36 | #define CCS811_ERR 0xE0 | 37 | #define CCS811_ERR 0xE0 |
| 37 | /* Used to transition from boot to application mode */ | 38 | /* Used to transition from boot to application mode */ |
| 38 | #define CCS811_APP_START 0xF4 | 39 | #define CCS811_APP_START 0xF4 |
| 40 | #define CCS811_SW_RESET 0xFF | ||
| 39 | 41 | ||
| 40 | /* Status register flags */ | 42 | /* Status register flags */ |
| 41 | #define CCS811_STATUS_ERROR BIT(0) | 43 | #define CCS811_STATUS_ERROR BIT(0) |
| @@ -74,6 +76,7 @@ struct ccs811_data { · 32 unmodified lines | |||
| 74 | struct mutex lock; /* Protect readings */ | 76 | struct mutex lock; /* Protect readings */ |
| 75 | struct ccs811_reading buffer; | 77 | struct ccs811_reading buffer; |
| 76 | struct iio_trigger *drdy_trig; | 78 | struct iio_trigger *drdy_trig; |
| 79 | struct gpio_desc *wakeup_gpio; | ||
| 77 | bool drdy_trig_on; | 80 | bool drdy_trig_on; |
| 78 | }; | 81 | }; |
| 79 | 82 | ||
| @@ -166,10 +169,25 @@ static int ccs811_setup(struct i2c_client *client) · 86 unmodified lines | |||
| 166 | CCS811_MODE_IAQ_1SEC); | 169 | CCS811_MODE_IAQ_1SEC); |
| 167 | } | 170 | } |
| 168 | 171 | ||
| 172 | static void ccs811_set_wakeup(struct ccs811_data *data, bool enable) | ||
| 173 | { | ||
| 174 | if (!data->wakeup_gpio) | ||
| 175 | return; | ||
| 176 | |||
| 177 | gpiod_set_value(data->wakeup_gpio, enable); | ||
| 178 | |||
| 179 | if (enable) | ||
| 180 | usleep_range(50, 60); | ||
| 181 | else | ||
| 182 | usleep_range(20, 30); | ||
| 183 | } | ||
| 184 | |||
| 169 | static int ccs811_get_measurement(struct ccs811_data *data) | 185 | static int ccs811_get_measurement(struct ccs811_data *data) |
| 170 | { | 186 | { |
| 171 | int ret, tries = 11; | 187 | int ret, tries = 11; |
| 172 | 188 | ||
| 189 | ccs811_set_wakeup(data, true); | ||
| 190 | |||
| 173 | /* Maximum waiting time: 1s, as measurements are made every second */ | 191 | /* Maximum waiting time: 1s, as measurements are made every second */ |
| 174 | while (tries-- > 0) { | 192 | while (tries-- > 0) { |
| 175 | ret = i2c_smbus_read_byte_data(data->client, CCS811_STATUS); | 193 | ret = i2c_smbus_read_byte_data(data->client, CCS811_STATUS); |
| @@ -183,9 +201,12 @@ static int ccs811_get_measurement(struct ccs811_data *data) · 7 unmodified lines | |||
| 183 | if (!(ret & CCS811_STATUS_DATA_READY)) | 201 | if (!(ret & CCS811_STATUS_DATA_READY)) |
| 184 | return -EIO; | 202 | return -EIO; |
| 185 | 203 | ||
| 186 | return i2c_smbus_read_i2c_block_data(data->client, | 204 | ret = i2c_smbus_read_i2c_block_data(data->client, |
| 187 | CCS811_ALG_RESULT_DATA, 8, | 205 | CCS811_ALG_RESULT_DATA, 8, |
| 188 | (char *)&data->buffer); | 206 | (char *)&data->buffer); |
| 207 | ccs811_set_wakeup(data, false); | ||
| 208 | |||
| 209 | return ret; | ||
| 189 | } | 210 | } |
| 190 | 211 | ||
| 191 | static int ccs811_read_raw(struct iio_dev *indio_dev, | 212 | static int ccs811_read_raw(struct iio_dev *indio_dev, |
| @@ -336,6 +357,45 @@ static irqreturn_t ccs811_data_rdy_trigger_poll(int irq, void *private) · 144 unmodified lines | |||
| 336 | return IRQ_HANDLED; | 357 | return IRQ_HANDLED; |
| 337 | } | 358 | } |
| 338 | 359 | ||
| 360 | static int ccs811_reset(struct i2c_client *client) | ||
| 361 | { | ||
| 362 | struct gpio_desc *reset_gpio; | ||
| 363 | int ret; | ||
| 364 | |||
| 365 | reset_gpio = devm_gpiod_get_optional(&client->dev, "reset", | ||
| 366 | GPIOD_OUT_LOW); | ||
| 367 | if (IS_ERR(reset_gpio)) | ||
| 368 | return PTR_ERR(reset_gpio); | ||
| 369 | |||
| 370 | /* Try to reset using nRESET pin if available else do SW reset */ | ||
| 371 | if (reset_gpio) { | ||
| 372 | gpiod_set_value(reset_gpio, 1); | ||
| 373 | usleep_range(20, 30); | ||
| 374 | gpiod_set_value(reset_gpio, 0); | ||
| 375 | } else { | ||
| 376 | /* | ||
| 377 | * As per the datasheet, this sequence of values needs to be | ||
| 378 | * written to the SW_RESET register for triggering the soft | ||
| 379 | * reset in the device and placing it in boot mode. | ||
| 380 | */ | ||
| 381 | static const u8 reset_seq[] = { | ||
| 382 | 0x11, 0xE5, 0x72, 0x8A, | ||
| 383 | }; | ||
| 384 | |||
| 385 | ret = i2c_smbus_write_i2c_block_data(client, CCS811_SW_RESET, | ||
| 386 | sizeof(reset_seq), reset_seq); | ||
| 387 | if (ret < 0) { | ||
| 388 | dev_err(&client->dev, "Failed to reset sensor\n"); | ||
| 389 | return ret; | ||
| 390 | } | ||
| 391 | } | ||
| 392 | |||
| 393 | /* tSTART delay required after reset */ | ||
| 394 | usleep_range(1000, 2000); | ||
| 395 | |||
| 396 | return 0; | ||
| 397 | } | ||
| 398 | |||
| 339 | static int ccs811_probe(struct i2c_client *client, | 399 | static int ccs811_probe(struct i2c_client *client, |
| 340 | const struct i2c_device_id *id) | 400 | const struct i2c_device_id *id) |
| 341 | { | 401 | { |
| @@ -348,36 +408,59 @@ static int ccs811_probe(struct i2c_client *client, · 6 unmodified lines | |||
| 348 | | I2C_FUNC_SMBUS_READ_I2C_BLOCK)) | 408 | | I2C_FUNC_SMBUS_READ_I2C_BLOCK)) |
| 349 | return -EOPNOTSUPP; | 409 | return -EOPNOTSUPP; |
| 350 | 410 | ||
| 411 | indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); | ||
| 412 | if (!indio_dev) | ||
| 413 | return -ENOMEM; | ||
| 414 | |||
| 415 | data = iio_priv(indio_dev); | ||
| 416 | i2c_set_clientdata(client, indio_dev); | ||
| 417 | data->client = client; | ||
| 418 | |||
| 419 | data->wakeup_gpio = devm_gpiod_get_optional(&client->dev, "wakeup", | ||
| 420 | GPIOD_OUT_HIGH); | ||
| 421 | if (IS_ERR(data->wakeup_gpio)) | ||
| 422 | return PTR_ERR(data->wakeup_gpio); | ||
| 423 | |||
| 424 | ccs811_set_wakeup(data, true); | ||
| 425 | |||
| 426 | ret = ccs811_reset(client); | ||
| 427 | if (ret) { | ||
| 428 | ccs811_set_wakeup(data, false); | ||
| 429 | return ret; | ||
| 430 | } | ||
| 431 | |||
| 351 | /* Check hardware id (should be 0x81 for this family of devices) */ | 432 | /* Check hardware id (should be 0x81 for this family of devices) */ |
| 352 | ret = i2c_smbus_read_byte_data(client, CCS811_HW_ID); | 433 | ret = i2c_smbus_read_byte_data(client, CCS811_HW_ID); |
| 353 | if (ret < 0) | 434 | if (ret < 0) { |
| 435 | ccs811_set_wakeup(data, false); | ||
| 354 | return ret; | 436 | return ret; |
| 437 | } | ||
| 355 | 438 | ||
| 356 | if (ret != CCS811_HW_ID_VALUE) { | 439 | if (ret != CCS811_HW_ID_VALUE) { |
| 357 | dev_err(&client->dev, "hardware id doesn't match CCS81x\n"); | 440 | dev_err(&client->dev, "hardware id doesn't match CCS81x\n"); |
| 441 | ccs811_set_wakeup(data, false); | ||
| 358 | return -ENODEV; | 442 | return -ENODEV; |
| 359 | } | 443 | } |
| 360 | 444 | ||
| 361 | ret = i2c_smbus_read_byte_data(client, CCS811_HW_VERSION); | 445 | ret = i2c_smbus_read_byte_data(client, CCS811_HW_VERSION); |
| 362 | if (ret < 0) | 446 | if (ret < 0) { |
| 447 | ccs811_set_wakeup(data, false); | ||
| 363 | return ret; | 448 | return ret; |
| 449 | } | ||
| 364 | 450 | ||
| 365 | if ((ret & CCS811_HW_VERSION_MASK) != CCS811_HW_VERSION_VALUE) { | 451 | if ((ret & CCS811_HW_VERSION_MASK) != CCS811_HW_VERSION_VALUE) { |
| 366 | dev_err(&client->dev, "no CCS811 sensor\n"); | 452 | dev_err(&client->dev, "no CCS811 sensor\n"); |
| 453 | ccs811_set_wakeup(data, false); | ||
| 367 | return -ENODEV; | 454 | return -ENODEV; |
| 368 | } | 455 | } |
| 369 | 456 | ||
| 370 | indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); | ||
| 371 | if (!indio_dev) | ||
| 372 | return -ENOMEM; | ||
| 373 | |||
| 374 | ret = ccs811_setup(client); | 457 | ret = ccs811_setup(client); |
| 375 | if (ret < 0) | 458 | if (ret < 0) { |
| 459 | ccs811_set_wakeup(data, false); | ||
| 376 | return ret; | 460 | return ret; |
| 461 | } | ||
| 377 | 462 | ||
| 378 | data = iio_priv(indio_dev); | 463 | ccs811_set_wakeup(data, false); |
| 379 | i2c_set_clientdata(client, indio_dev); | ||
| 380 | data->client = client; | ||
| 381 | 464 | ||
| 382 | mutex_init(&data->lock); | 465 | mutex_init(&data->lock); |
| 383 | 466 | ||
| @@ -466,9 +549,16 @@ static const struct i2c_device_id ccs811_id[] = { · 82 unmodified lines | |||
| 466 | }; | 549 | }; |
| 467 | MODULE_DEVICE_TABLE(i2c, ccs811_id); | 550 | MODULE_DEVICE_TABLE(i2c, ccs811_id); |
| 468 | 551 | ||
| 552 | static const struct of_device_id ccs811_dt_ids[] = { | ||
| 553 | { .compatible = "ams,ccs811" }, | ||
| 554 | { } | ||
| 555 | }; | ||
| 556 | MODULE_DEVICE_TABLE(of, ccs811_dt_ids); | ||
| 557 | |||
| 469 | static struct i2c_driver ccs811_driver = { | 558 | static struct i2c_driver ccs811_driver = { |
| 470 | .driver = { | 559 | .driver = { |
| 471 | .name = "ccs811", | 560 | .name = "ccs811", |
| 561 | .of_match_table = ccs811_dt_ids, | ||
| 472 | }, | 562 | }, |
| 473 | .probe = ccs811_probe, | 563 | .probe = ccs811_probe, |
| 474 | .remove = ccs811_remove, | 564 | .remove = ccs811_remove, |
| @@ -13,6 +13,8 @@ · 12 unmodified lines | |||
| 13 | #include <linux/hid-sensor-hub.h> | 13 | #include <linux/hid-sensor-hub.h> |
| 14 | #include <linux/iio/iio.h> | 14 | #include <linux/iio/iio.h> |
| 15 | #include <linux/iio/trigger.h> | 15 | #include <linux/iio/trigger.h> |
| 16 | #include <linux/iio/triggered_buffer.h> | ||
| 17 | #include <linux/iio/trigger_consumer.h> | ||
| 16 | #include <linux/iio/buffer.h> | 18 | #include <linux/iio/buffer.h> |
| 17 | #include <linux/iio/sysfs.h> | 19 | #include <linux/iio/sysfs.h> |
| 18 | #include "hid-sensor-trigger.h" | 20 | #include "hid-sensor-trigger.h" |
| @@ -222,7 +224,8 @@ static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig, · 203 unmodified lines | |||
| 222 | return hid_sensor_power_state(iio_trigger_get_drvdata(trig), state); | 224 | return hid_sensor_power_state(iio_trigger_get_drvdata(trig), state); |
| 223 | } | 225 | } |
| 224 | 226 | ||
| 225 | void hid_sensor_remove_trigger(struct hid_sensor_common *attrb) | 227 | void hid_sensor_remove_trigger(struct iio_dev *indio_dev, |
| 228 | struct hid_sensor_common *attrb) | ||
| 226 | { | 229 | { |
| 227 | if (atomic_read(&attrb->runtime_pm_enable)) | 230 | if (atomic_read(&attrb->runtime_pm_enable)) |
| 228 | pm_runtime_disable(&attrb->pdev->dev); | 231 | pm_runtime_disable(&attrb->pdev->dev); |
| @@ -233,6 +236,7 @@ void hid_sensor_remove_trigger(struct hid_sensor_common *attrb) · 4 unmodified lines | |||
| 233 | cancel_work_sync(&attrb->work); | 236 | cancel_work_sync(&attrb->work); |
| 234 | iio_trigger_unregister(attrb->trigger); | 237 | iio_trigger_unregister(attrb->trigger); |
| 235 | iio_trigger_free(attrb->trigger); | 238 | iio_trigger_free(attrb->trigger); |
| 239 | iio_triggered_buffer_cleanup(indio_dev); | ||
| 236 | } | 240 | } |
| 237 | EXPORT_SYMBOL(hid_sensor_remove_trigger); | 241 | EXPORT_SYMBOL(hid_sensor_remove_trigger); |
| 238 | 242 | ||
| @@ -246,11 +250,18 @@ int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name, · 7 unmodified lines | |||
| 246 | int ret; | 250 | int ret; |
| 247 | struct iio_trigger *trig; | 251 | struct iio_trigger *trig; |
| 248 | 252 | ||
| 253 | ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, | ||
| 254 | NULL, NULL); | ||
| 255 | if (ret) { | ||
| 256 | dev_err(&indio_dev->dev, "Triggered Buffer Setup Failed\n"); | ||
| 257 | return ret; | ||
| 258 | } | ||
| 259 | |||
| 249 | trig = iio_trigger_alloc("%s-dev%d", name, indio_dev->id); | 260 | trig = iio_trigger_alloc("%s-dev%d", name, indio_dev->id); |
| 250 | if (trig == NULL) { | 261 | if (trig == NULL) { |
| 251 | dev_err(&indio_dev->dev, "Trigger Allocate Failed\n"); | 262 | dev_err(&indio_dev->dev, "Trigger Allocate Failed\n"); |
| 252 | ret = -ENOMEM; | 263 | ret = -ENOMEM; |
| 253 | goto error_ret; | 264 | goto error_triggered_buffer_cleanup; |
| 254 | } | 265 | } |
| 255 | 266 | ||
| 256 | trig->dev.parent = indio_dev->dev.parent; | 267 | trig->dev.parent = indio_dev->dev.parent; |
| @@ -284,7 +295,8 @@ error_unreg_trigger: · 27 unmodified lines | |||
| 284 | iio_trigger_unregister(trig); | 295 | iio_trigger_unregister(trig); |
| 285 | error_free_trig: | 296 | error_free_trig: |
| 286 | iio_trigger_free(trig); | 297 | iio_trigger_free(trig); |
| 287 | error_ret: | 298 | error_triggered_buffer_cleanup: |
| 299 | iio_triggered_buffer_cleanup(indio_dev); | ||
| 288 | return ret; | 300 | return ret; |
| 289 | } | 301 | } |
| 290 | EXPORT_SYMBOL(hid_sensor_setup_trigger); | 302 | EXPORT_SYMBOL(hid_sensor_setup_trigger); |
| @@ -13,7 +13,8 @@ extern const struct dev_pm_ops hid_sensor_pm_ops; · 12 unmodified lines | |||
| 13 | 13 | ||
| 14 | int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name, | 14 | int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name, |
| 15 | struct hid_sensor_common *attrb); | 15 | struct hid_sensor_common *attrb); |
| 16 | void hid_sensor_remove_trigger(struct hid_sensor_common *attrb); | 16 | void hid_sensor_remove_trigger(struct iio_dev *indio_dev, |
| 17 | struct hid_sensor_common *attrb); | ||
| 17 | int hid_sensor_power_state(struct hid_sensor_common *st, bool state); | 18 | int hid_sensor_power_state(struct hid_sensor_common *st, bool state); |
| 18 | 19 | ||
| 19 | #endif | 20 | #endif |
| @@ -20,11 +20,6 @@ · 19 unmodified lines | |||
| 20 | 20 | ||
| 21 | #include "st_sensors_core.h" | 21 | #include "st_sensors_core.h" |
| 22 | 22 | ||
| 23 | static inline u32 st_sensors_get_unaligned_le24(const u8 *p) | ||
| 24 | { | ||
| 25 | return (s32)((p[0] | p[1] << 8 | p[2] << 16) << 8) >> 8; | ||
| 26 | } | ||
| 27 | |||
| 28 | int st_sensors_write_data_with_mask(struct iio_dev *indio_dev, | 23 | int st_sensors_write_data_with_mask(struct iio_dev *indio_dev, |
| 29 | u8 reg_addr, u8 mask, u8 data) | 24 | u8 reg_addr, u8 mask, u8 data) |
| 30 | { | 25 | { |
| @@ -543,7 +538,7 @@ static int st_sensors_read_axis_data(struct iio_dev *indio_dev, · 512 unmodified lines | |||
| 543 | else if (byte_for_channel == 2) | 538 | else if (byte_for_channel == 2) |
| 544 | *data = (s16)get_unaligned_le16(outdata); | 539 | *data = (s16)get_unaligned_le16(outdata); |
| 545 | else if (byte_for_channel == 3) | 540 | else if (byte_for_channel == 3) |
| 546 | *data = (s32)st_sensors_get_unaligned_le24(outdata); | 541 | *data = (s32)sign_extend32(get_unaligned_le24(outdata), 23); |
| 547 | 542 | ||
| 548 | st_sensors_free_memory: | 543 | st_sensors_free_memory: |
| 549 | kfree(outdata); | 544 | kfree(outdata); |
| @@ -279,12 +279,12 @@ config LTC1660 · 278 unmodified lines | |||
| 279 | module will be called ltc1660. | 279 | module will be called ltc1660. |
| 280 | 280 | ||
| 281 | config LTC2632 | 281 | config LTC2632 |
| 282 | tristate "Linear Technology LTC2632-12/10/8 and LTC2636-12/10/8 DAC spi driver" | 282 | tristate "Linear Technology LTC2632-12/10/8 and similar DAC spi driver" |
| 283 | depends on SPI | 283 | depends on SPI |
| 284 | help | 284 | help |
| 285 | Say yes here to build support for Linear Technology | 285 | Say yes here to build support for Linear Technology |
| 286 | LTC2632-12, LTC2632-10, LTC2632-8, LTC2636-12, LTC2636-10 and | 286 | LTC2632, LTC2634 and LTC2636 DAC resolution 12/10/8 bit |
| 287 | LTC2636-8 converters (DAC). | 287 | low 0-2.5V and high 0-4.096V range converters. |
| 288 | 288 | ||
| 289 | To compile this driver as a module, choose M here: the | 289 | To compile this driver as a module, choose M here: the |
| 290 | module will be called ltc2632. | 290 | module will be called ltc2632. |
| @@ -21,6 +21,8 @@ · 20 unmodified lines | |||
| 21 | #include <linux/iio/iio.h> | 21 | #include <linux/iio/iio.h> |
| 22 | #include <linux/iio/sysfs.h> | 22 | #include <linux/iio/sysfs.h> |
| 23 | 23 | ||
| 24 | #include <asm/unaligned.h> | ||
| 25 | |||
| 24 | #define MODE_PWRDWN_1k 0x1 | 26 | #define MODE_PWRDWN_1k 0x1 |
| 25 | #define MODE_PWRDWN_100k 0x2 | 27 | #define MODE_PWRDWN_100k 0x2 |
| 26 | #define MODE_PWRDWN_TRISTATE 0x3 | 28 | #define MODE_PWRDWN_TRISTATE 0x3 |
| @@ -302,9 +304,7 @@ static int ad5660_write(struct ad5446_state *st, unsigned val) · 275 unmodified lines | |||
| 302 | struct spi_device *spi = to_spi_device(st->dev); | 304 | struct spi_device *spi = to_spi_device(st->dev); |
| 303 | uint8_t data[3]; | 305 | uint8_t data[3]; |
| 304 | 306 | ||
| 305 | data[0] = (val >> 16) & 0xFF; | 307 | put_unaligned_be24(val, &data[0]); |
| 306 | data[1] = (val >> 8) & 0xFF; | ||
| 307 | data[2] = val & 0xFF; | ||
| 308 | 308 | ||
| 309 | return spi_write(spi, data, sizeof(data)); | 309 | return spi_write(spi, data, sizeof(data)); |
| 310 | } | 310 | } |
| @@ -98,7 +98,7 @@ static int ad5592r_reg_read(struct ad5592r_state *st, u8 reg, u16 *value) · 97 unmodified lines | |||
| 98 | return 0; | 98 | return 0; |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | static int ad5593r_gpio_read(struct ad5592r_state *st, u8 *value) | 101 | static int ad5592r_gpio_read(struct ad5592r_state *st, u8 *value) |
| 102 | { | 102 | { |
| 103 | int ret; | 103 | int ret; |
| 104 | 104 | ||
| @@ -121,7 +121,7 @@ static const struct ad5592r_rw_ops ad5592r_rw_ops = { · 16 unmodified lines | |||
| 121 | .read_adc = ad5592r_read_adc, | 121 | .read_adc = ad5592r_read_adc, |
| 122 | .reg_write = ad5592r_reg_write, | 122 | .reg_write = ad5592r_reg_write, |
| 123 | .reg_read = ad5592r_reg_read, | 123 | .reg_read = ad5592r_reg_read, |
| 124 | .gpio_read = ad5593r_gpio_read, | 124 | .gpio_read = ad5592r_gpio_read, |
| 125 | }; | 125 | }; |
| 126 | 126 | ||
| 127 | static int ad5592r_spi_probe(struct spi_device *spi) | 127 | static int ad5592r_spi_probe(struct spi_device *spi) |
| @@ -134,5 +134,5 @@ static struct i2c_driver ad5593r_driver = { · 133 unmodified lines | |||
| 134 | module_i2c_driver(ad5593r_driver); | 134 | module_i2c_driver(ad5593r_driver); |
| 135 | 135 | ||
| 136 | MODULE_AUTHOR("Paul Cercueil <paul.cercueil@analog.com>"); | 136 | MODULE_AUTHOR("Paul Cercueil <paul.cercueil@analog.com>"); |
| 137 | MODULE_DESCRIPTION("Analog Devices AD5592R multi-channel converters"); | 137 | MODULE_DESCRIPTION("Analog Devices AD5593R multi-channel converters"); |
| 138 | MODULE_LICENSE("GPL v2"); | 138 | MODULE_LICENSE("GPL v2"); |
| @@ -18,6 +18,8 @@ · 17 unmodified lines | |||
| 18 | #include <linux/iio/iio.h> | 18 | #include <linux/iio/iio.h> |
| 19 | #include <linux/iio/sysfs.h> | 19 | #include <linux/iio/sysfs.h> |
| 20 | 20 | ||
| 21 | #include <asm/unaligned.h> | ||
| 22 | |||
| 21 | #include "ad5624r.h" | 23 | #include "ad5624r.h" |
| 22 | 24 | ||
| 23 | static int ad5624r_spi_write(struct spi_device *spi, | 25 | static int ad5624r_spi_write(struct spi_device *spi, |
| @@ -35,11 +37,9 @@ static int ad5624r_spi_write(struct spi_device *spi, · 11 unmodified lines | |||
| 35 | * for the AD5664R, AD5644R, and AD5624R, respectively. | 37 | * for the AD5664R, AD5644R, and AD5624R, respectively. |
| 36 | */ | 38 | */ |
| 37 | data = (0 << 22) | (cmd << 19) | (addr << 16) | (val << shift); | 39 | data = (0 << 22) | (cmd << 19) | (addr << 16) | (val << shift); |
| 38 | msg[0] = data >> 16; | 40 | put_unaligned_be24(data, &msg[0]); |
| 39 | msg[1] = data >> 8; | ||
| 40 | msg[2] = data; | ||
| 41 | 41 | ||
| 42 | return spi_write(spi, msg, 3); | 42 | return spi_write(spi, msg, sizeof(msg)); |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | static int ad5624r_read_raw(struct iio_dev *indio_dev, | 45 | static int ad5624r_read_raw(struct iio_dev *indio_dev, |
| @@ -12,6 +12,8 @@ · 11 unmodified lines | |||
| 12 | #include <linux/iio/iio.h> | 12 | #include <linux/iio/iio.h> |
| 13 | #include <linux/regulator/consumer.h> | 13 | #include <linux/regulator/consumer.h> |
| 14 | 14 | ||
| 15 | #include <asm/unaligned.h> | ||
| 16 | |||
| 15 | #define LTC2632_CMD_WRITE_INPUT_N 0x0 | 17 | #define LTC2632_CMD_WRITE_INPUT_N 0x0 |
| 16 | #define LTC2632_CMD_UPDATE_DAC_N 0x1 | 18 | #define LTC2632_CMD_UPDATE_DAC_N 0x1 |
| 17 | #define LTC2632_CMD_WRITE_INPUT_N_UPDATE_ALL 0x2 | 19 | #define LTC2632_CMD_WRITE_INPUT_N_UPDATE_ALL 0x2 |
| @@ -24,6 +26,7 @@ · 6 unmodified lines | |||
| 24 | /** | 26 | /** |
| 25 | * struct ltc2632_chip_info - chip specific information | 27 | * struct ltc2632_chip_info - chip specific information |
| 26 | * @channels: channel spec for the DAC | 28 | * @channels: channel spec for the DAC |
| 29 | * @num_channels: DAC channel count of the chip | ||
| 27 | * @vref_mv: internal reference voltage | 30 | * @vref_mv: internal reference voltage |
| 28 | */ | 31 | */ |
| 29 | struct ltc2632_chip_info { | 32 | struct ltc2632_chip_info { |
| @@ -53,6 +56,12 @@ enum ltc2632_supported_device_ids { · 23 unmodified lines | |||
| 53 | ID_LTC2632H12, | 56 | ID_LTC2632H12, |
| 54 | ID_LTC2632H10, | 57 | ID_LTC2632H10, |
| 55 | ID_LTC2632H8, | 58 | ID_LTC2632H8, |
| 59 | ID_LTC2634L12, | ||
| 60 | ID_LTC2634L10, | ||
| 61 | ID_LTC2634L8, | ||
| 62 | ID_LTC2634H12, | ||
| 63 | ID_LTC2634H10, | ||
| 64 | ID_LTC2634H8, | ||
| 56 | ID_LTC2636L12, | 65 | ID_LTC2636L12, |
| 57 | ID_LTC2636L10, | 66 | ID_LTC2636L10, |
| 58 | ID_LTC2636L8, | 67 | ID_LTC2636L8, |
| @@ -75,9 +84,7 @@ static int ltc2632_spi_write(struct spi_device *spi, · 16 unmodified lines | |||
| 75 | * 10-, 8-bit input code followed by 4, 6, or 8 don't care bits. | 84 | * 10-, 8-bit input code followed by 4, 6, or 8 don't care bits. |
| 76 | */ | 85 | */ |
| 77 | data = (cmd << 20) | (addr << 16) | (val << shift); | 86 | data = (cmd << 20) | (addr << 16) | (val << shift); |
| 78 | msg[0] = data >> 16; | 87 | put_unaligned_be24(data, &msg[0]); |
| 79 | msg[1] = data >> 8; | ||
| 80 | msg[2] = data; | ||
| 81 | 88 | ||
| 82 | return spi_write(spi, msg, sizeof(msg)); | 89 | return spi_write(spi, msg, sizeof(msg)); |
| 83 | } | 90 | } |
| @@ -235,6 +242,36 @@ static const struct ltc2632_chip_info ltc2632_chip_info_tbl[] = { · 151 unmodified lines | |||
| 235 | .num_channels = 2, | 242 | .num_channels = 2, |
| 236 | .vref_mv = 4096, | 243 | .vref_mv = 4096, |
| 237 | }, | 244 | }, |
| 245 | [ID_LTC2634L12] = { | ||
| 246 | .channels = ltc2632x12_channels, | ||
| 247 | .num_channels = 4, | ||
| 248 | .vref_mv = 2500, | ||
| 249 | }, | ||
| 250 | [ID_LTC2634L10] = { | ||
| 251 | .channels = ltc2632x10_channels, | ||
| 252 | .num_channels = 4, | ||
| 253 | .vref_mv = 2500, | ||
| 254 | }, | ||
| 255 | [ID_LTC2634L8] = { | ||
| 256 | .channels = ltc2632x8_channels, | ||
| 257 | .num_channels = 4, | ||
| 258 | .vref_mv = 2500, | ||
| 259 | }, | ||
| 260 | [ID_LTC2634H12] = { | ||
| 261 | .channels = ltc2632x12_channels, | ||
| 262 | .num_channels = 4, | ||
| 263 | .vref_mv = 4096, | ||
| 264 | }, | ||
| 265 | [ID_LTC2634H10] = { | ||
| 266 | .channels = ltc2632x10_channels, | ||
| 267 | .num_channels = 4, | ||
| 268 | .vref_mv = 4096, | ||
| 269 | }, | ||
| 270 | [ID_LTC2634H8] = { | ||
| 271 | .channels = ltc2632x8_channels, | ||
| 272 | .num_channels = 4, | ||
| 273 | .vref_mv = 4096, | ||
| 274 | }, | ||
| 238 | [ID_LTC2636L12] = { | 275 | [ID_LTC2636L12] = { |
| 239 | .channels = ltc2632x12_channels, | 276 | .channels = ltc2632x12_channels, |
| 240 | .num_channels = 8, | 277 | .num_channels = 8, |
| @@ -356,6 +393,12 @@ static const struct spi_device_id ltc2632_id[] = { · 115 unmodified lines | |||
| 356 | { "ltc2632-h12", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2632H12] }, | 393 | { "ltc2632-h12", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2632H12] }, |
| 357 | { "ltc2632-h10", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2632H10] }, | 394 | { "ltc2632-h10", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2632H10] }, |
| 358 | { "ltc2632-h8", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2632H8] }, | 395 | { "ltc2632-h8", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2632H8] }, |
| 396 | { "ltc2634-l12", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2634L12] }, | ||
| 397 | { "ltc2634-l10", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2634L10] }, | ||
| 398 | { "ltc2634-l8", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2634L8] }, | ||
| 399 | { "ltc2634-h12", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2634H12] }, | ||
| 400 | { "ltc2634-h10", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2634H10] }, | ||
| 401 | { "ltc2634-h8", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2634H8] }, | ||
| 359 | { "ltc2636-l12", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2636L12] }, | 402 | { "ltc2636-l12", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2636L12] }, |
| 360 | { "ltc2636-l10", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2636L10] }, | 403 | { "ltc2636-l10", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2636L10] }, |
| 361 | { "ltc2636-l8", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2636L8] }, | 404 | { "ltc2636-l8", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2636L8] }, |
| @@ -385,6 +428,24 @@ static const struct of_device_id ltc2632_of_match[] = { · 23 unmodified lines | |||
| 385 | }, { | 428 | }, { |
| 386 | .compatible = "lltc,ltc2632-h8", | 429 | .compatible = "lltc,ltc2632-h8", |
| 387 | .data = <c2632_chip_info_tbl[ID_LTC2632H8] | 430 | .data = <c2632_chip_info_tbl[ID_LTC2632H8] |
| 431 | }, { | ||
| 432 | .compatible = "lltc,ltc2634-l12", | ||
| 433 | .data = <c2632_chip_info_tbl[ID_LTC2634L12] | ||
| 434 | }, { | ||
| 435 | .compatible = "lltc,ltc2634-l10", | ||
| 436 | .data = <c2632_chip_info_tbl[ID_LTC2634L10] | ||
| 437 | }, { | ||
| 438 | .compatible = "lltc,ltc2634-l8", | ||
| 439 | .data = <c2632_chip_info_tbl[ID_LTC2634L8] | ||
| 440 | }, { | ||
| 441 | .compatible = "lltc,ltc2634-h12", | ||
| 442 | .data = <c2632_chip_info_tbl[ID_LTC2634H12] | ||
| 443 | }, { | ||
| 444 | .compatible = "lltc,ltc2634-h10", | ||
| 445 | .data = <c2632_chip_info_tbl[ID_LTC2634H10] | ||
| 446 | }, { | ||
| 447 | .compatible = "lltc,ltc2634-h8", | ||
| 448 | .data = <c2632_chip_info_tbl[ID_LTC2634H8] | ||
| 388 | }, { | 449 | }, { |
| 389 | .compatible = "lltc,ltc2636-l12", | 450 | .compatible = "lltc,ltc2636-l12", |
| 390 | .data = <c2632_chip_info_tbl[ID_LTC2636L12] | 451 | .data = <c2632_chip_info_tbl[ID_LTC2636L12] |
| @@ -12,6 +12,8 @@ · 11 unmodified lines | |||
| 12 | 12 | ||
| 13 | #include <linux/iio/iio.h> | 13 | #include <linux/iio/iio.h> |
| 14 | 14 | ||
| 15 | #include <asm/unaligned.h> | ||
| 16 | |||
| 15 | #define ADIS16130_CON 0x0 | 17 | #define ADIS16130_CON 0x0 |
| 16 | #define ADIS16130_CON_RD (1 << 6) | 18 | #define ADIS16130_CON_RD (1 << 6) |
| 17 | #define ADIS16130_IOP 0x1 | 19 | #define ADIS16130_IOP 0x1 |
| @@ -59,7 +61,7 @@ static int adis16130_spi_read(struct iio_dev *indio_dev, u8 reg_addr, u32 *val) · 41 unmodified lines | |||
| 59 | 61 | ||
| 60 | ret = spi_sync_transfer(st->us, &xfer, 1); | 62 | ret = spi_sync_transfer(st->us, &xfer, 1); |
| 61 | if (ret == 0) | 63 | if (ret == 0) |
| 62 | *val = (st->buf[1] << 16) | (st->buf[2] << 8) | st->buf[3]; | 64 | *val = get_unaligned_be24(&st->buf[1]); |
| 63 | mutex_unlock(&st->buf_lock); | 65 | mutex_unlock(&st->buf_lock); |
| 64 | 66 | ||
| 65 | return ret; | 67 | return ret; |
| @@ -148,16 +148,14 @@ DEFINE_DEBUGFS_ATTRIBUTE(adis16136_flash_count_fops, · 147 unmodified lines | |||
| 148 | static int adis16136_debugfs_init(struct iio_dev *indio_dev) | 148 | static int adis16136_debugfs_init(struct iio_dev *indio_dev) |
| 149 | { | 149 | { |
| 150 | struct adis16136 *adis16136 = iio_priv(indio_dev); | 150 | struct adis16136 *adis16136 = iio_priv(indio_dev); |
| 151 | struct dentry *d = iio_get_debugfs_dentry(indio_dev); | ||
| 151 | 152 | ||
| 152 | debugfs_create_file_unsafe("serial_number", 0400, | 153 | debugfs_create_file_unsafe("serial_number", 0400, |
| 153 | indio_dev->debugfs_dentry, adis16136, | 154 | d, adis16136, &adis16136_serial_fops); |
| 154 | &adis16136_serial_fops); | ||
| 155 | debugfs_create_file_unsafe("product_id", 0400, | 155 | debugfs_create_file_unsafe("product_id", 0400, |
| 156 | indio_dev->debugfs_dentry, | 156 | d, adis16136, &adis16136_product_id_fops); |
| 157 | adis16136, &adis16136_product_id_fops); | ||
| 158 | debugfs_create_file_unsafe("flash_count", 0400, | 157 | debugfs_create_file_unsafe("flash_count", 0400, |
| 159 | indio_dev->debugfs_dentry, | 158 | d, adis16136, &adis16136_flash_count_fops); |
| 160 | adis16136, &adis16136_flash_count_fops); | ||
| 161 | 159 | ||
| 162 | return 0; | 160 | return 0; |
| 163 | } | 161 | } |
| @@ -14,8 +14,6 @@ · 13 unmodified lines | |||
| 14 | #include <linux/iio/iio.h> | 14 | #include <linux/iio/iio.h> |
| 15 | #include <linux/iio/sysfs.h> | 15 | #include <linux/iio/sysfs.h> |
| 16 | #include <linux/iio/buffer.h> | 16 | #include <linux/iio/buffer.h> |
| 17 | #include <linux/iio/trigger_consumer.h> | ||
| 18 | #include <linux/iio/triggered_buffer.h> | ||
| 19 | #include "../common/hid-sensors/hid-sensor-trigger.h" | 17 | #include "../common/hid-sensors/hid-sensor-trigger.h" |
| 20 | 18 | ||
| 21 | enum gyro_3d_channel { | 19 | enum gyro_3d_channel { |
| @@ -326,18 +324,13 @@ static int hid_gyro_3d_probe(struct platform_device *pdev) · 304 unmodified lines | |||
| 326 | indio_dev->name = name; | 324 | indio_dev->name = name; |
| 327 | indio_dev->modes = INDIO_DIRECT_MODE; | 325 | indio_dev->modes = INDIO_DIRECT_MODE; |
| 328 | 326 | ||
| 329 | ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, | ||
| 330 | NULL, NULL); | ||
| 331 | if (ret) { | ||
| 332 | dev_err(&pdev->dev, "failed to initialize trigger buffer\n"); | ||
| 333 | goto error_free_dev_mem; | ||
| 334 | } | ||
| 335 | atomic_set(&gyro_state->common_attributes.data_ready, 0); | 327 | atomic_set(&gyro_state->common_attributes.data_ready, 0); |
| 328 | |||
| 336 | ret = hid_sensor_setup_trigger(indio_dev, name, | 329 | ret = hid_sensor_setup_trigger(indio_dev, name, |
| 337 | &gyro_state->common_attributes); | 330 | &gyro_state->common_attributes); |
| 338 | if (ret < 0) { | 331 | if (ret < 0) { |
| 339 | dev_err(&pdev->dev, "trigger setup failed\n"); | 332 | dev_err(&pdev->dev, "trigger setup failed\n"); |
| 340 | goto error_unreg_buffer_funcs; | 333 | goto error_free_dev_mem; |
| 341 | } | 334 | } |
| 342 | 335 | ||
| 343 | ret = iio_device_register(indio_dev); | 336 | ret = iio_device_register(indio_dev); |
| @@ -361,9 +354,7 @@ static int hid_gyro_3d_probe(struct platform_device *pdev) · 17 unmodified lines | |||
| 361 | error_iio_unreg: | 354 | error_iio_unreg: |
| 362 | iio_device_unregister(indio_dev); | 355 | iio_device_unregister(indio_dev); |
| 363 | error_remove_trigger: | 356 | error_remove_trigger: |
| 364 | hid_sensor_remove_trigger(&gyro_state->common_attributes); | 357 | hid_sensor_remove_trigger(indio_dev, &gyro_state->common_attributes); |
| 365 | error_unreg_buffer_funcs: | ||
| 366 | iio_triggered_buffer_cleanup(indio_dev); | ||
| 367 | error_free_dev_mem: | 358 | error_free_dev_mem: |
| 368 | kfree(indio_dev->channels); | 359 | kfree(indio_dev->channels); |
| 369 | return ret; | 360 | return ret; |
| @@ -378,8 +369,7 @@ static int hid_gyro_3d_remove(struct platform_device *pdev) · 8 unmodified lines | |||
| 378 | 369 | ||
| 379 | sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_GYRO_3D); | 370 | sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_GYRO_3D); |
| 380 | iio_device_unregister(indio_dev); | 371 | iio_device_unregister(indio_dev); |
| 381 | hid_sensor_remove_trigger(&gyro_state->common_attributes); | 372 | hid_sensor_remove_trigger(indio_dev, &gyro_state->common_attributes); |
| 382 | iio_triggered_buffer_cleanup(indio_dev); | ||
| 383 | kfree(indio_dev->channels); | 373 | kfree(indio_dev->channels); |
| 384 | 374 | ||
| 385 | return 0; | 375 | return 0; |
| @@ -23,6 +23,8 @@ · 22 unmodified lines | |||
| 23 | #include <linux/iio/triggered_buffer.h> | 23 | #include <linux/iio/triggered_buffer.h> |
| 24 | #include <linux/iio/trigger_consumer.h> | 24 | #include <linux/iio/trigger_consumer.h> |
| 25 | 25 | ||
| 26 | #include <asm/unaligned.h> | ||
| 27 | |||
| 26 | #include "afe440x.h" | 28 | #include "afe440x.h" |
| 27 | 29 | ||
| 28 | #define AFE4403_DRIVER_NAME "afe4403" | 30 | #define AFE4403_DRIVER_NAME "afe4403" |
| @@ -220,13 +222,11 @@ static int afe4403_read(struct afe4403_data *afe, unsigned int reg, u32 *val) · 191 unmodified lines | |||
| 220 | if (ret) | 222 | if (ret) |
| 221 | return ret; | 223 | return ret; |
| 222 | 224 | ||
| 223 | ret = spi_write_then_read(afe->spi, ®, 1, rx, 3); | 225 | ret = spi_write_then_read(afe->spi, ®, 1, rx, sizeof(rx)); |
| 224 | if (ret) | 226 | if (ret) |
| 225 | return ret; | 227 | return ret; |
| 226 | 228 | ||
| 227 | *val = (rx[0] << 16) | | 229 | *val = get_unaligned_be24(&rx[0]); |
| 228 | (rx[1] << 8) | | ||
| 229 | (rx[2]); | ||
| 230 | 230 | ||
| 231 | /* Disable reading from the device */ | 231 | /* Disable reading from the device */ |
| 232 | tx[3] = AFE440X_CONTROL0_WRITE; | 232 | tx[3] = AFE440X_CONTROL0_WRITE; |
| @@ -322,13 +322,11 @@ static irqreturn_t afe4403_trigger_handler(int irq, void *private) · 89 unmodified lines | |||
| 322 | indio_dev->masklength) { | 322 | indio_dev->masklength) { |
| 323 | ret = spi_write_then_read(afe->spi, | 323 | ret = spi_write_then_read(afe->spi, |
| 324 | &afe4403_channel_values[bit], 1, | 324 | &afe4403_channel_values[bit], 1, |
| 325 | rx, 3); | 325 | rx, sizeof(rx)); |
| 326 | if (ret) | 326 | if (ret) |
| 327 | goto err; | 327 | goto err; |
| 328 | 328 | ||
| 329 | buffer[i++] = (rx[0] << 16) | | 329 | buffer[i++] = get_unaligned_be24(&rx[0]); |
| 330 | (rx[1] << 8) | | ||
| 331 | (rx[2]); | ||
| 332 | } | 330 | } |
| 333 | 331 | ||
| 334 | /* Disable reading from the device */ | 332 | /* Disable reading from the device */ |
| @@ -7,8 +7,6 @@ · 6 unmodified lines | |||
| 7 | #include <linux/hid-sensor-hub.h> | 7 | #include <linux/hid-sensor-hub.h> |
| 8 | #include <linux/iio/buffer.h> | 8 | #include <linux/iio/buffer.h> |
| 9 | #include <linux/iio/iio.h> | 9 | #include <linux/iio/iio.h> |
| 10 | #include <linux/iio/triggered_buffer.h> | ||
| 11 | #include <linux/iio/trigger_consumer.h> | ||
| 12 | #include <linux/module.h> | 10 | #include <linux/module.h> |
| 13 | #include <linux/platform_device.h> | 11 | #include <linux/platform_device.h> |
| 14 | 12 | ||
| @@ -233,12 +231,8 @@ static int hid_humidity_probe(struct platform_device *pdev) · 218 unmodified lines | |||
| 233 | indio_dev->name = name; | 231 | indio_dev->name = name; |
| 234 | indio_dev->modes = INDIO_DIRECT_MODE; | 232 | indio_dev->modes = INDIO_DIRECT_MODE; |
| 235 | 233 | ||
| 236 | ret = devm_iio_triggered_buffer_setup(&pdev->dev, indio_dev, | ||
| 237 | &iio_pollfunc_store_time, NULL, NULL); | ||
| 238 | if (ret) | ||
| 239 | return ret; | ||
| 240 | |||
| 241 | atomic_set(&humid_st->common_attributes.data_ready, 0); | 234 | atomic_set(&humid_st->common_attributes.data_ready, 0); |
| 235 | |||
| 242 | ret = hid_sensor_setup_trigger(indio_dev, name, | 236 | ret = hid_sensor_setup_trigger(indio_dev, name, |
| 243 | &humid_st->common_attributes); | 237 | &humid_st->common_attributes); |
| 244 | if (ret) | 238 | if (ret) |
| @@ -261,7 +255,7 @@ static int hid_humidity_probe(struct platform_device *pdev) · 16 unmodified lines | |||
| 261 | error_remove_callback: | 255 | error_remove_callback: |
| 262 | sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_HUMIDITY); | 256 | sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_HUMIDITY); |
| 263 | error_remove_trigger: | 257 | error_remove_trigger: |
| 264 | hid_sensor_remove_trigger(&humid_st->common_attributes); | 258 | hid_sensor_remove_trigger(indio_dev, &humid_st->common_attributes); |
| 265 | return ret; | 259 | return ret; |
| 266 | } | 260 | } |
| 267 | 261 | ||
| @@ -274,7 +268,7 @@ static int hid_humidity_remove(struct platform_device *pdev) · 6 unmodified lines | |||
| 274 | 268 | ||
| 275 | iio_device_unregister(indio_dev); | 269 | iio_device_unregister(indio_dev); |
| 276 | sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_HUMIDITY); | 270 | sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_HUMIDITY); |
| 277 | hid_sensor_remove_trigger(&humid_st->common_attributes); | 271 | hid_sensor_remove_trigger(indio_dev, &humid_st->common_attributes); |
| 278 | 272 | ||
| 279 | return 0; | 273 | return 0; |
| 280 | } | 274 | } |
| @@ -29,6 +29,19 @@ config ADIS16460 · 28 unmodified lines | |||
| 29 | To compile this driver as a module, choose M here: the module will be | 29 | To compile this driver as a module, choose M here: the module will be |
| 30 | called adis16460. | 30 | called adis16460. |
| 31 | 31 | ||
| 32 | config ADIS16475 | ||
| 33 | tristate "Analog Devices ADIS16475 and similar IMU driver" | ||
| 34 | depends on SPI | ||
| 35 | select IIO_ADIS_LIB | ||
| 36 | select IIO_ADIS_LIB_BUFFER if IIO_BUFFER | ||
| 37 | help | ||
| 38 | Say yes here to build support for Analog Devices ADIS16470, ADIS16475, | ||
| 39 | ADIS16477, ADIS16465, ADIS16467, ADIS16500, ADIS16505, ADIS16507 inertial | ||
| 40 | sensors. | ||
| 41 | |||
| 42 | To compile this driver as a module, choose M here: the module will be | ||
| 43 | called adis16475. | ||
| 44 | |||
| 32 | config ADIS16480 | 45 | config ADIS16480 |
| 33 | tristate "Analog Devices ADIS16480 and similar IMU driver" | 46 | tristate "Analog Devices ADIS16480 and similar IMU driver" |
| 34 | depends on SPI | 47 | depends on SPI |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | # When adding new entries keep the list in alphabetical order | 6 | # When adding new entries keep the list in alphabetical order |
| 7 | obj-$(CONFIG_ADIS16400) += adis16400.o | 7 | obj-$(CONFIG_ADIS16400) += adis16400.o |
| 8 | obj-$(CONFIG_ADIS16460) += adis16460.o | 8 | obj-$(CONFIG_ADIS16460) += adis16460.o |
| 9 | obj-$(CONFIG_ADIS16475) += adis16475.o | ||
| 9 | obj-$(CONFIG_ADIS16480) += adis16480.o | 10 | obj-$(CONFIG_ADIS16480) += adis16480.o |
| 10 | 11 | ||
| 11 | adis_lib-y += adis.o | 12 | adis_lib-y += adis.o |
| @@ -223,6 +223,31 @@ int __adis_read_reg(struct adis *adis, unsigned int reg, · 222 unmodified lines | |||
| 223 | return ret; | 223 | return ret; |
| 224 | } | 224 | } |
| 225 | EXPORT_SYMBOL_GPL(__adis_read_reg); | 225 | EXPORT_SYMBOL_GPL(__adis_read_reg); |
| 226 | /** | ||
| 227 | * __adis_update_bits_base() - ADIS Update bits function - Unlocked version | ||
| 228 | * @adis: The adis device | ||
| 229 | * @reg: The address of the lower of the two registers | ||
| 230 | * @mask: Bitmask to change | ||
| 231 | * @val: Value to be written | ||
| 232 | * @size: Size of the register to update | ||
| 233 | * | ||
| 234 | * Updates the desired bits of @reg in accordance with @mask and @val. | ||
| 235 | */ | ||
| 236 | int __adis_update_bits_base(struct adis *adis, unsigned int reg, const u32 mask, | ||
| 237 | const u32 val, u8 size) | ||
| 238 | { | ||
| 239 | int ret; | ||
| 240 | u32 __val; | ||
| 241 | |||
| 242 | ret = __adis_read_reg(adis, reg, &__val, size); | ||
| 243 | if (ret) | ||
| 244 | return ret; | ||
| 245 | |||
| 246 | __val = (__val & ~mask) | (val & mask); | ||
| 247 | |||
| 248 | return __adis_write_reg(adis, reg, __val, size); | ||
| 249 | } | ||
| 250 | EXPORT_SYMBOL_GPL(__adis_update_bits_base); | ||
| 226 | 251 | ||
| 227 | #ifdef CONFIG_DEBUG_FS | 252 | #ifdef CONFIG_DEBUG_FS |
| 228 | 253 | ||
| @@ -281,18 +281,16 @@ DEFINE_DEBUGFS_ATTRIBUTE(adis16400_flash_count_fops, · 280 unmodified lines | |||
| 281 | static int adis16400_debugfs_init(struct iio_dev *indio_dev) | 281 | static int adis16400_debugfs_init(struct iio_dev *indio_dev) |
| 282 | { | 282 | { |
| 283 | struct adis16400_state *st = iio_priv(indio_dev); | 283 | struct adis16400_state *st = iio_priv(indio_dev); |
| 284 | struct dentry *d = iio_get_debugfs_dentry(indio_dev); | ||
| 284 | 285 | ||
| 285 | if (st->variant->flags & ADIS16400_HAS_SERIAL_NUMBER) | 286 | if (st->variant->flags & ADIS16400_HAS_SERIAL_NUMBER) |
| 286 | debugfs_create_file_unsafe("serial_number", 0400, | 287 | debugfs_create_file_unsafe("serial_number", 0400, |
| 287 | indio_dev->debugfs_dentry, st, | 288 | d, st, &adis16400_serial_number_fops); |
| 288 | &adis16400_serial_number_fops); | ||
| 289 | if (st->variant->flags & ADIS16400_HAS_PROD_ID) | 289 | if (st->variant->flags & ADIS16400_HAS_PROD_ID) |
| 290 | debugfs_create_file_unsafe("product_id", 0400, | 290 | debugfs_create_file_unsafe("product_id", 0400, |
| 291 | indio_dev->debugfs_dentry, st, | 291 | d, st, &adis16400_product_id_fops); |
| 292 | &adis16400_product_id_fops); | ||
| 293 | debugfs_create_file_unsafe("flash_count", 0400, | 292 | debugfs_create_file_unsafe("flash_count", 0400, |
| 294 | indio_dev->debugfs_dentry, st, | 293 | d, st, &adis16400_flash_count_fops); |
| 295 | &adis16400_flash_count_fops); | ||
| 296 | 294 | ||
| 297 | return 0; | 295 | return 0; |
| 298 | } | 296 | } |
| @@ -1195,7 +1193,7 @@ static int adis16400_probe(struct spi_device *spi) · 896 unmodified lines | |||
| 1195 | indio_dev->available_scan_masks = st->avail_scan_mask; | 1193 | indio_dev->available_scan_masks = st->avail_scan_mask; |
| 1196 | st->adis.burst = &adis16400_burst; | 1194 | st->adis.burst = &adis16400_burst; |
| 1197 | if (st->variant->flags & ADIS16400_BURST_DIAG_STAT) | 1195 | if (st->variant->flags & ADIS16400_BURST_DIAG_STAT) |
| 1198 | st->adis.burst->extra_len = sizeof(u16); | 1196 | st->adis.burst_extra_len = sizeof(u16); |
| 1199 | } | 1197 | } |
| 1200 | 1198 | ||
| 1201 | adis16400_data = &st->variant->adis_data; | 1199 | adis16400_data = &st->variant->adis_data; |
| @@ -129,16 +129,14 @@ DEFINE_DEBUGFS_ATTRIBUTE(adis16460_flash_count_fops, · 128 unmodified lines | |||
| 129 | static int adis16460_debugfs_init(struct iio_dev *indio_dev) | 129 | static int adis16460_debugfs_init(struct iio_dev *indio_dev) |
| 130 | { | 130 | { |
| 131 | struct adis16460 *adis16460 = iio_priv(indio_dev); | 131 | struct adis16460 *adis16460 = iio_priv(indio_dev); |
| 132 | struct dentry *d = iio_get_debugfs_dentry(indio_dev); | ||
| 132 | 133 | ||
| 133 | debugfs_create_file_unsafe("serial_number", 0400, | 134 | debugfs_create_file_unsafe("serial_number", 0400, |
| 134 | indio_dev->debugfs_dentry, adis16460, | 135 | d, adis16460, &adis16460_serial_number_fops); |
| 135 | &adis16460_serial_number_fops); | ||
| 136 | debugfs_create_file_unsafe("product_id", 0400, | 136 | debugfs_create_file_unsafe("product_id", 0400, |
| 137 | indio_dev->debugfs_dentry, adis16460, | 137 | d, adis16460, &adis16460_product_id_fops); |
| 138 | &adis16460_product_id_fops); | ||
| 139 | debugfs_create_file_unsafe("flash_count", 0400, | 138 | debugfs_create_file_unsafe("flash_count", 0400, |
| 140 | indio_dev->debugfs_dentry, adis16460, | 139 | d, adis16460, &adis16460_flash_count_fops); |
| 141 | &adis16460_flash_count_fops); | ||
| 142 | 140 | ||
| 143 | return 0; | 141 | return 0; |
| 144 | } | 142 | } |
| @@ -0,0 +1,1338 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * ADIS16475 IMU driver | ||
| 4 | * | ||
| 5 | * Copyright 2019 Analog Devices Inc. | ||
| 6 | */ | ||
| 7 | #include <linux/bitfield.h> | ||
| 8 | #include <linux/bitops.h> | ||
| 9 | #include <linux/clk.h> | ||
| 10 | #include <linux/debugfs.h> | ||
| 11 | #include <linux/delay.h> | ||
| 12 | #include <linux/device.h> | ||
| 13 | #include <linux/kernel.h> | ||
| 14 | #include <linux/iio/buffer.h> | ||
| 15 | #include <linux/iio/iio.h> | ||
| 16 | #include <linux/iio/imu/adis.h> | ||
| 17 | #include <linux/iio/sysfs.h> | ||
| 18 | #include <linux/iio/trigger_consumer.h> | ||
| 19 | #include <linux/irq.h> | ||
| 20 | #include <linux/module.h> | ||
| 21 | #include <linux/mod_devicetable.h> | ||
| 22 | #include <linux/property.h> | ||
| 23 | #include <linux/spi/spi.h> | ||
| 24 | |||
| 25 | #define ADIS16475_REG_DIAG_STAT 0x02 | ||
| 26 | #define ADIS16475_REG_X_GYRO_L 0x04 | ||
| 27 | #define ADIS16475_REG_Y_GYRO_L 0x08 | ||
| 28 | #define ADIS16475_REG_Z_GYRO_L 0x0C | ||
| 29 | #define ADIS16475_REG_X_ACCEL_L 0x10 | ||
| 30 | #define ADIS16475_REG_Y_ACCEL_L 0x14 | ||
| 31 | #define ADIS16475_REG_Z_ACCEL_L 0x18 | ||
| 32 | #define ADIS16475_REG_TEMP_OUT 0x1c | ||
| 33 | #define ADIS16475_REG_X_GYRO_BIAS_L 0x40 | ||
| 34 | #define ADIS16475_REG_Y_GYRO_BIAS_L 0x44 | ||
| 35 | #define ADIS16475_REG_Z_GYRO_BIAS_L 0x48 | ||
| 36 | #define ADIS16475_REG_X_ACCEL_BIAS_L 0x4c | ||
| 37 | #define ADIS16475_REG_Y_ACCEL_BIAS_L 0x50 | ||
| 38 | #define ADIS16475_REG_Z_ACCEL_BIAS_L 0x54 | ||
| 39 | #define ADIS16475_REG_FILT_CTRL 0x5c | ||
| 40 | #define ADIS16475_FILT_CTRL_MASK GENMASK(2, 0) | ||
| 41 | #define ADIS16475_FILT_CTRL(x) FIELD_PREP(ADIS16475_FILT_CTRL_MASK, x) | ||
| 42 | #define ADIS16475_REG_MSG_CTRL 0x60 | ||
| 43 | #define ADIS16475_MSG_CTRL_DR_POL_MASK BIT(0) | ||
| 44 | #define ADIS16475_MSG_CTRL_DR_POL(x) \ | ||
| 45 | FIELD_PREP(ADIS16475_MSG_CTRL_DR_POL_MASK, x) | ||
| 46 | #define ADIS16475_SYNC_MODE_MASK GENMASK(4, 2) | ||
| 47 | #define ADIS16475_SYNC_MODE(x) FIELD_PREP(ADIS16475_SYNC_MODE_MASK, x) | ||
| 48 | #define ADIS16475_REG_UP_SCALE 0x62 | ||
| 49 | #define ADIS16475_REG_DEC_RATE 0x64 | ||
| 50 | #define ADIS16475_REG_GLOB_CMD 0x68 | ||
| 51 | #define ADIS16475_REG_FIRM_REV 0x6c | ||
| 52 | #define ADIS16475_REG_FIRM_DM 0x6e | ||
| 53 | #define ADIS16475_REG_FIRM_Y 0x70 | ||
| 54 | #define ADIS16475_REG_PROD_ID 0x72 | ||
| 55 | #define ADIS16475_REG_SERIAL_NUM 0x74 | ||
| 56 | #define ADIS16475_REG_FLASH_CNT 0x7c | ||
| 57 | #define ADIS16500_BURST32_MASK BIT(9) | ||
| 58 | #define ADIS16500_BURST32(x) FIELD_PREP(ADIS16500_BURST32_MASK, x) | ||
| 59 | /* number of data elements in burst mode */ | ||
| 60 | #define ADIS16475_BURST32_MAX_DATA 32 | ||
| 61 | #define ADIS16475_BURST_MAX_DATA 20 | ||
| 62 | #define ADIS16475_MAX_SCAN_DATA 20 | ||
| 63 | /* spi max speed in brust mode */ | ||
| 64 | #define ADIS16475_BURST_MAX_SPEED 1000000 | ||
| 65 | #define ADIS16475_LSB_DEC_MASK BIT(0) | ||
| 66 | #define ADIS16475_LSB_FIR_MASK BIT(1) | ||
| 67 | |||
| 68 | enum { | ||
| 69 | ADIS16475_SYNC_DIRECT = 1, | ||
| 70 | ADIS16475_SYNC_SCALED, | ||
| 71 | ADIS16475_SYNC_OUTPUT, | ||
| 72 | ADIS16475_SYNC_PULSE = 5, | ||
| 73 | }; | ||
| 74 | |||
| 75 | struct adis16475_sync { | ||
| 76 | u16 sync_mode; | ||
| 77 | u16 min_rate; | ||
| 78 | u16 max_rate; | ||
| 79 | }; | ||
| 80 | |||
| 81 | struct adis16475_chip_info { | ||
| 82 | const struct iio_chan_spec *channels; | ||
| 83 | const struct adis16475_sync *sync; | ||
| 84 | const struct adis_data adis_data; | ||
| 85 | const char *name; | ||
| 86 | u32 num_channels; | ||
| 87 | u32 gyro_max_val; | ||
| 88 | u32 gyro_max_scale; | ||
| 89 | u32 accel_max_val; | ||
| 90 | u32 accel_max_scale; | ||
| 91 | u32 temp_scale; | ||
| 92 | u32 int_clk; | ||
| 93 | u16 max_dec; | ||
| 94 | u8 num_sync; | ||
| 95 | bool has_burst32; | ||
| 96 | }; | ||
| 97 | |||
| 98 | struct adis16475 { | ||
| 99 | const struct adis16475_chip_info *info; | ||
| 100 | struct adis adis; | ||
| 101 | u32 clk_freq; | ||
| 102 | bool burst32; | ||
| 103 | unsigned long lsb_flag; | ||
| 104 | /* Alignment needed for the timestamp */ | ||
| 105 | __be16 data[ADIS16475_MAX_SCAN_DATA] __aligned(8); | ||
| 106 | }; | ||
| 107 | |||
| 108 | enum { | ||
| 109 | ADIS16475_SCAN_GYRO_X, | ||
| 110 | ADIS16475_SCAN_GYRO_Y, | ||
| 111 | ADIS16475_SCAN_GYRO_Z, | ||
| 112 | ADIS16475_SCAN_ACCEL_X, | ||
| 113 | ADIS16475_SCAN_ACCEL_Y, | ||
| 114 | ADIS16475_SCAN_ACCEL_Z, | ||
| 115 | ADIS16475_SCAN_TEMP, | ||
| 116 | ADIS16475_SCAN_DIAG_S_FLAGS, | ||
| 117 | ADIS16475_SCAN_CRC_FAILURE, | ||
| 118 | }; | ||
| 119 | |||
| 120 | #ifdef CONFIG_DEBUG_FS | ||
| 121 | static ssize_t adis16475_show_firmware_revision(struct file *file, | ||
| 122 | char __user *userbuf, | ||
| 123 | size_t count, loff_t *ppos) | ||
| 124 | { | ||
| 125 | struct adis16475 *st = file->private_data; | ||
| 126 | char buf[7]; | ||
| 127 | size_t len; | ||
| 128 | u16 rev; | ||
| 129 | int ret; | ||
| 130 | |||
| 131 | ret = adis_read_reg_16(&st->adis, ADIS16475_REG_FIRM_REV, &rev); | ||
| 132 | if (ret) | ||
| 133 | return ret; | ||
| 134 | |||
| 135 | len = scnprintf(buf, sizeof(buf), "%x.%x\n", rev >> 8, rev & 0xff); | ||
| 136 | |||
| 137 | return simple_read_from_buffer(userbuf, count, ppos, buf, len); | ||
| 138 | } | ||
| 139 | |||
| 140 | static const struct file_operations adis16475_firmware_revision_fops = { | ||
| 141 | .open = simple_open, | ||
| 142 | .read = adis16475_show_firmware_revision, | ||
| 143 | .llseek = default_llseek, | ||
| 144 | .owner = THIS_MODULE, | ||
| 145 | }; | ||
| 146 | |||
| 147 | static ssize_t adis16475_show_firmware_date(struct file *file, | ||
| 148 | char __user *userbuf, | ||
| 149 | size_t count, loff_t *ppos) | ||
| 150 | { | ||
| 151 | struct adis16475 *st = file->private_data; | ||
| 152 | u16 md, year; | ||
| 153 | char buf[12]; | ||
| 154 | size_t len; | ||
| 155 | int ret; | ||
| 156 | |||
| 157 | ret = adis_read_reg_16(&st->adis, ADIS16475_REG_FIRM_Y, &year); | ||
| 158 | if (ret) | ||
| 159 | return ret; | ||
| 160 | |||
| 161 | ret = adis_read_reg_16(&st->adis, ADIS16475_REG_FIRM_DM, &md); | ||
| 162 | if (ret) | ||
| 163 | return ret; | ||
| 164 | |||
| 165 | len = snprintf(buf, sizeof(buf), "%.2x-%.2x-%.4x\n", md >> 8, md & 0xff, | ||
| 166 | year); | ||
| 167 | |||
| 168 | return simple_read_from_buffer(userbuf, count, ppos, buf, len); | ||
| 169 | } | ||
| 170 | |||
| 171 | static const struct file_operations adis16475_firmware_date_fops = { | ||
| 172 | .open = simple_open, | ||
| 173 | .read = adis16475_show_firmware_date, | ||
| 174 | .llseek = default_llseek, | ||
| 175 | .owner = THIS_MODULE, | ||
| 176 | }; | ||
| 177 | |||
| 178 | static int adis16475_show_serial_number(void *arg, u64 *val) | ||
| 179 | { | ||
| 180 | struct adis16475 *st = arg; | ||
| 181 | u16 serial; | ||
| 182 | int ret; | ||
| 183 | |||
| 184 | ret = adis_read_reg_16(&st->adis, ADIS16475_REG_SERIAL_NUM, &serial); | ||
| 185 | if (ret) | ||
| 186 | return ret; | ||
| 187 | |||
| 188 | *val = serial; | ||
| 189 | |||
| 190 | return 0; | ||
| 191 | } | ||
| 192 | DEFINE_DEBUGFS_ATTRIBUTE(adis16475_serial_number_fops, | ||
| 193 | adis16475_show_serial_number, NULL, "0x%.4llx\n"); | ||
| 194 | |||
| 195 | static int adis16475_show_product_id(void *arg, u64 *val) | ||
| 196 | { | ||
| 197 | struct adis16475 *st = arg; | ||
| 198 | u16 prod_id; | ||
| 199 | int ret; | ||
| 200 | |||
| 201 | ret = adis_read_reg_16(&st->adis, ADIS16475_REG_PROD_ID, &prod_id); | ||
| 202 | if (ret) | ||
| 203 | return ret; | ||
| 204 | |||
| 205 | *val = prod_id; | ||
| 206 | |||
| 207 | return 0; | ||
| 208 | } | ||
| 209 | DEFINE_DEBUGFS_ATTRIBUTE(adis16475_product_id_fops, | ||
| 210 | adis16475_show_product_id, NULL, "%llu\n"); | ||
| 211 | |||
| 212 | static int adis16475_show_flash_count(void *arg, u64 *val) | ||
| 213 | { | ||
| 214 | struct adis16475 *st = arg; | ||
| 215 | u32 flash_count; | ||
| 216 | int ret; | ||
| 217 | |||
| 218 | ret = adis_read_reg_32(&st->adis, ADIS16475_REG_FLASH_CNT, | ||
| 219 | &flash_count); | ||
| 220 | if (ret) | ||
| 221 | return ret; | ||
| 222 | |||
| 223 | *val = flash_count; | ||
| 224 | |||
| 225 | return 0; | ||
| 226 | } | ||
| 227 | DEFINE_DEBUGFS_ATTRIBUTE(adis16475_flash_count_fops, | ||
| 228 | adis16475_show_flash_count, NULL, "%lld\n"); | ||
| 229 | |||
| 230 | static void adis16475_debugfs_init(struct iio_dev *indio_dev) | ||
| 231 | { | ||
| 232 | struct adis16475 *st = iio_priv(indio_dev); | ||
| 233 | struct dentry *d = iio_get_debugfs_dentry(indio_dev); | ||
| 234 | |||
| 235 | debugfs_create_file_unsafe("serial_number", 0400, | ||
| 236 | d, st, &adis16475_serial_number_fops); | ||
| 237 | debugfs_create_file_unsafe("product_id", 0400, | ||
| 238 | d, st, &adis16475_product_id_fops); | ||
| 239 | debugfs_create_file_unsafe("flash_count", 0400, | ||
| 240 | d, st, &adis16475_flash_count_fops); | ||
| 241 | debugfs_create_file("firmware_revision", 0400, | ||
| 242 | d, st, &adis16475_firmware_revision_fops); | ||
| 243 | debugfs_create_file("firmware_date", 0400, d, | ||
| 244 | st, &adis16475_firmware_date_fops); | ||
| 245 | } | ||
| 246 | #else | ||
| 247 | static void adis16475_debugfs_init(struct iio_dev *indio_dev) | ||
| 248 | { | ||
| 249 | } | ||
| 250 | #endif | ||
| 251 | |||
| 252 | static int adis16475_get_freq(struct adis16475 *st, u32 *freq) | ||
| 253 | { | ||
| 254 | int ret; | ||
| 255 | u16 dec; | ||
| 256 | |||
| 257 | ret = adis_read_reg_16(&st->adis, ADIS16475_REG_DEC_RATE, &dec); | ||
| 258 | if (ret) | ||
| 259 | return -EINVAL; | ||
| 260 | |||
| 261 | *freq = DIV_ROUND_CLOSEST(st->clk_freq, dec + 1); | ||
| 262 | |||
| 263 | return 0; | ||
| 264 | } | ||
| 265 | |||
| 266 | static int adis16475_set_freq(struct adis16475 *st, const u32 freq) | ||
| 267 | { | ||
| 268 | u16 dec; | ||
| 269 | int ret; | ||
| 270 | |||
| 271 | if (!freq) | ||
| 272 | return -EINVAL; | ||
| 273 | |||
| 274 | dec = DIV_ROUND_CLOSEST(st->clk_freq, freq); | ||
| 275 | |||
| 276 | if (dec) | ||
| 277 | dec--; | ||
| 278 | |||
| 279 | if (dec > st->info->max_dec) | ||
| 280 | dec = st->info->max_dec; | ||
| 281 | |||
| 282 | ret = adis_write_reg_16(&st->adis, ADIS16475_REG_DEC_RATE, dec); | ||
| 283 | if (ret) | ||
| 284 | return ret; | ||
| 285 | |||
| 286 | /* | ||
| 287 | * If decimation is used, then gyro and accel data will have meaningful | ||
| 288 | * bits on the LSB registers. This info is used on the trigger handler. | ||
| 289 | */ | ||
| 290 | assign_bit(ADIS16475_LSB_DEC_MASK, &st->lsb_flag, dec); | ||
| 291 | |||
| 292 | return 0; | ||
| 293 | } | ||
| 294 | |||
| 295 | /* The values are approximated. */ | ||
| 296 | static const u32 adis16475_3db_freqs[] = { | ||
| 297 | [0] = 720, /* Filter disabled, full BW (~720Hz) */ | ||
| 298 | [1] = 360, | ||
| 299 | [2] = 164, | ||
| 300 | [3] = 80, | ||
| 301 | [4] = 40, | ||
| 302 | [5] = 20, | ||
| 303 | [6] = 10, | ||
| 304 | }; | ||
| 305 | |||
| 306 | static int adis16475_get_filter(struct adis16475 *st, u32 *filter) | ||
| 307 | { | ||
| 308 | u16 filter_sz; | ||
| 309 | int ret; | ||
| 310 | const int mask = ADIS16475_FILT_CTRL_MASK; | ||
| 311 | |||
| 312 | ret = adis_read_reg_16(&st->adis, ADIS16475_REG_FILT_CTRL, &filter_sz); | ||
| 313 | if (ret) | ||
| 314 | return ret; | ||
| 315 | |||
| 316 | *filter = adis16475_3db_freqs[filter_sz & mask]; | ||
| 317 | |||
| 318 | return 0; | ||
| 319 | } | ||
| 320 | |||
| 321 | static int adis16475_set_filter(struct adis16475 *st, const u32 filter) | ||
| 322 | { | ||
| 323 | int i = ARRAY_SIZE(adis16475_3db_freqs); | ||
| 324 | int ret; | ||
| 325 | |||
| 326 | while (--i) { | ||
| 327 | if (adis16475_3db_freqs[i] >= filter) | ||
| 328 | break; | ||
| 329 | } | ||
| 330 | |||
| 331 | ret = adis_write_reg_16(&st->adis, ADIS16475_REG_FILT_CTRL, | ||
| 332 | ADIS16475_FILT_CTRL(i)); | ||
| 333 | if (ret) | ||
| 334 | return ret; | ||
| 335 | |||
| 336 | /* | ||
| 337 | * If FIR is used, then gyro and accel data will have meaningful | ||
| 338 | * bits on the LSB registers. This info is used on the trigger handler. | ||
| 339 | */ | ||
| 340 | assign_bit(ADIS16475_LSB_FIR_MASK, &st->lsb_flag, i); | ||
| 341 | |||
| 342 | return 0; | ||
| 343 | } | ||
| 344 | |||
| 345 | static const u32 adis16475_calib_regs[] = { | ||
| 346 | [ADIS16475_SCAN_GYRO_X] = ADIS16475_REG_X_GYRO_BIAS_L, | ||
| 347 | [ADIS16475_SCAN_GYRO_Y] = ADIS16475_REG_Y_GYRO_BIAS_L, | ||
| 348 | [ADIS16475_SCAN_GYRO_Z] = ADIS16475_REG_Z_GYRO_BIAS_L, | ||
| 349 | [ADIS16475_SCAN_ACCEL_X] = ADIS16475_REG_X_ACCEL_BIAS_L, | ||
| 350 | [ADIS16475_SCAN_ACCEL_Y] = ADIS16475_REG_Y_ACCEL_BIAS_L, | ||
| 351 | [ADIS16475_SCAN_ACCEL_Z] = ADIS16475_REG_Z_ACCEL_BIAS_L, | ||
| 352 | }; | ||
| 353 | |||
| 354 | static int adis16475_read_raw(struct iio_dev *indio_dev, | ||
| 355 | const struct iio_chan_spec *chan, | ||
| 356 | int *val, int *val2, long info) | ||
| 357 | { | ||
| 358 | struct adis16475 *st = iio_priv(indio_dev); | ||
| 359 | int ret; | ||
| 360 | u32 tmp; | ||
| 361 | |||
| 362 | switch (info) { | ||
| 363 | case IIO_CHAN_INFO_RAW: | ||
| 364 | return adis_single_conversion(indio_dev, chan, 0, val); | ||
| 365 | case IIO_CHAN_INFO_SCALE: | ||
| 366 | switch (chan->type) { | ||
| 367 | case IIO_ANGL_VEL: | ||
| 368 | *val = st->info->gyro_max_val; | ||
| 369 | *val2 = st->info->gyro_max_scale; | ||
| 370 | return IIO_VAL_FRACTIONAL; | ||
| 371 | case IIO_ACCEL: | ||
| 372 | *val = st->info->accel_max_val; | ||
| 373 | *val2 = st->info->accel_max_scale; | ||
| 374 | return IIO_VAL_FRACTIONAL; | ||
| 375 | case IIO_TEMP: | ||
| 376 | *val = st->info->temp_scale; | ||
| 377 | return IIO_VAL_INT; | ||
| 378 | default: | ||
| 379 | return -EINVAL; | ||
| 380 | } | ||
| 381 | case IIO_CHAN_INFO_CALIBBIAS: | ||
| 382 | ret = adis_read_reg_32(&st->adis, | ||
| 383 | adis16475_calib_regs[chan->scan_index], | ||
| 384 | val); | ||
| 385 | if (ret) | ||
| 386 | return ret; | ||
| 387 | |||
| 388 | return IIO_VAL_INT; | ||
| 389 | case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: | ||
| 390 | ret = adis16475_get_filter(st, val); | ||
| 391 | if (ret) | ||
| 392 | return ret; | ||
| 393 | |||
| 394 | return IIO_VAL_INT; | ||
| 395 | case IIO_CHAN_INFO_SAMP_FREQ: | ||
| 396 | ret = adis16475_get_freq(st, &tmp); | ||
| 397 | if (ret) | ||
| 398 | return ret; | ||
| 399 | |||
| 400 | *val = tmp / 1000; | ||
| 401 | *val2 = (tmp % 1000) * 1000; | ||
| 402 | return IIO_VAL_INT_PLUS_MICRO; | ||
| 403 | default: | ||
| 404 | return -EINVAL; | ||
| 405 | } | ||
| 406 | } | ||
| 407 | |||
| 408 | static int adis16475_write_raw(struct iio_dev *indio_dev, | ||
| 409 | const struct iio_chan_spec *chan, | ||
| 410 | int val, int val2, long info) | ||
| 411 | { | ||
| 412 | struct adis16475 *st = iio_priv(indio_dev); | ||
| 413 | u32 tmp; | ||
| 414 | |||
| 415 | switch (info) { | ||
| 416 | case IIO_CHAN_INFO_SAMP_FREQ: | ||
| 417 | tmp = val * 1000 + val2 / 1000; | ||
| 418 | return adis16475_set_freq(st, tmp); | ||
| 419 | case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: | ||
| 420 | return adis16475_set_filter(st, val); | ||
| 421 | case IIO_CHAN_INFO_CALIBBIAS: | ||
| 422 | return adis_write_reg_32(&st->adis, | ||
| 423 | adis16475_calib_regs[chan->scan_index], | ||
| 424 | val); | ||
| 425 | default: | ||
| 426 | return -EINVAL; | ||
| 427 | } | ||
| 428 | } | ||
| 429 | |||
| 430 | #define ADIS16475_MOD_CHAN(_type, _mod, _address, _si, _r_bits, _s_bits) \ | ||
| 431 | { \ | ||
| 432 | .type = (_type), \ | ||
| 433 | .modified = 1, \ | ||
| 434 | .channel2 = (_mod), \ | ||
| 435 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ | ||
| 436 | BIT(IIO_CHAN_INFO_CALIBBIAS), \ | ||
| 437 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ | ||
| 438 | .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ | ||
| 439 | BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \ | ||
| 440 | .address = (_address), \ | ||
| 441 | .scan_index = (_si), \ | ||
| 442 | .scan_type = { \ | ||
| 443 | .sign = 's', \ | ||
| 444 | .realbits = (_r_bits), \ | ||
| 445 | .storagebits = (_s_bits), \ | ||
| 446 | .endianness = IIO_BE, \ | ||
| 447 | }, \ | ||
| 448 | } | ||
| 449 | |||
| 450 | #define ADIS16475_GYRO_CHANNEL(_mod) \ | ||
| 451 | ADIS16475_MOD_CHAN(IIO_ANGL_VEL, IIO_MOD_ ## _mod, \ | ||
| 452 | ADIS16475_REG_ ## _mod ## _GYRO_L, \ | ||
| 453 | ADIS16475_SCAN_GYRO_ ## _mod, 32, 32) | ||
| 454 | |||
| 455 | #define ADIS16475_ACCEL_CHANNEL(_mod) \ | ||
| 456 | ADIS16475_MOD_CHAN(IIO_ACCEL, IIO_MOD_ ## _mod, \ | ||
| 457 | ADIS16475_REG_ ## _mod ## _ACCEL_L, \ | ||
| 458 | ADIS16475_SCAN_ACCEL_ ## _mod, 32, 32) | ||
| 459 | |||
| 460 | #define ADIS16475_TEMP_CHANNEL() { \ | ||
| 461 | .type = IIO_TEMP, \ | ||
| 462 | .indexed = 1, \ | ||
| 463 | .channel = 0, \ | ||
| 464 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ | ||
| 465 | BIT(IIO_CHAN_INFO_SCALE), \ | ||
| 466 | .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ | ||
| 467 | BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \ | ||
| 468 | .address = ADIS16475_REG_TEMP_OUT, \ | ||
| 469 | .scan_index = ADIS16475_SCAN_TEMP, \ | ||
| 470 | .scan_type = { \ | ||
| 471 | .sign = 's', \ | ||
| 472 | .realbits = 16, \ | ||
| 473 | .storagebits = 16, \ | ||
| 474 | .endianness = IIO_BE, \ | ||
| 475 | }, \ | ||
| 476 | } | ||
| 477 | |||
| 478 | static const struct iio_chan_spec adis16475_channels[] = { | ||
| 479 | ADIS16475_GYRO_CHANNEL(X), | ||
| 480 | ADIS16475_GYRO_CHANNEL(Y), | ||
| 481 | ADIS16475_GYRO_CHANNEL(Z), | ||
| 482 | ADIS16475_ACCEL_CHANNEL(X), | ||
| 483 | ADIS16475_ACCEL_CHANNEL(Y), | ||
| 484 | ADIS16475_ACCEL_CHANNEL(Z), | ||
| 485 | ADIS16475_TEMP_CHANNEL(), | ||
| 486 | IIO_CHAN_SOFT_TIMESTAMP(7) | ||
| 487 | }; | ||
| 488 | |||
| 489 | enum adis16475_variant { | ||
| 490 | ADIS16470, | ||
| 491 | ADIS16475_1, | ||
| 492 | ADIS16475_2, | ||
| 493 | ADIS16475_3, | ||
| 494 | ADIS16477_1, | ||
| 495 | ADIS16477_2, | ||
| 496 | ADIS16477_3, | ||
| 497 | ADIS16465_1, | ||
| 498 | ADIS16465_2, | ||
| 499 | ADIS16465_3, | ||
| 500 | ADIS16467_1, | ||
| 501 | ADIS16467_2, | ||
| 502 | ADIS16467_3, | ||
| 503 | ADIS16500, | ||
| 504 | ADIS16505_1, | ||
| 505 | ADIS16505_2, | ||
| 506 | ADIS16505_3, | ||
| 507 | ADIS16507_1, | ||
| 508 | ADIS16507_2, | ||
| 509 | ADIS16507_3, | ||
| 510 | }; | ||
| 511 | |||
| 512 | enum { | ||
| 513 | ADIS16475_DIAG_STAT_DATA_PATH = 1, | ||
| 514 | ADIS16475_DIAG_STAT_FLASH_MEM, | ||
| 515 | ADIS16475_DIAG_STAT_SPI, | ||
| 516 | ADIS16475_DIAG_STAT_STANDBY, | ||
| 517 | ADIS16475_DIAG_STAT_SENSOR, | ||
| 518 | ADIS16475_DIAG_STAT_MEMORY, | ||
| 519 | ADIS16475_DIAG_STAT_CLK, | ||
| 520 | }; | ||
| 521 | |||
| 522 | static const char * const adis16475_status_error_msgs[] = { | ||
| 523 | [ADIS16475_DIAG_STAT_DATA_PATH] = "Data Path Overrun", | ||
| 524 | [ADIS16475_DIAG_STAT_FLASH_MEM] = "Flash memory update failure", | ||
| 525 | [ADIS16475_DIAG_STAT_SPI] = "SPI communication error", | ||
| 526 | [ADIS16475_DIAG_STAT_STANDBY] = "Standby mode", | ||
| 527 | [ADIS16475_DIAG_STAT_SENSOR] = "Sensor failure", | ||
| 528 | [ADIS16475_DIAG_STAT_MEMORY] = "Memory failure", | ||
| 529 | [ADIS16475_DIAG_STAT_CLK] = "Clock error", | ||
| 530 | }; | ||
| 531 | |||
| 532 | static int adis16475_enable_irq(struct adis *adis, bool enable) | ||
| 533 | { | ||
| 534 | /* | ||
| 535 | * There is no way to gate the data-ready signal internally inside the | ||
| 536 | * ADIS16475. We can only control it's polarity... | ||
| 537 | */ | ||
| 538 | if (enable) | ||
| 539 | enable_irq(adis->spi->irq); | ||
| 540 | else | ||
| 541 | disable_irq(adis->spi->irq); | ||
| 542 | |||
| 543 | return 0; | ||
| 544 | } | ||
| 545 | |||
| 546 | #define ADIS16475_DATA(_prod_id, _timeouts) \ | ||
| 547 | { \ | ||
| 548 | .msc_ctrl_reg = ADIS16475_REG_MSG_CTRL, \ | ||
| 549 | .glob_cmd_reg = ADIS16475_REG_GLOB_CMD, \ | ||
| 550 | .diag_stat_reg = ADIS16475_REG_DIAG_STAT, \ | ||
| 551 | .prod_id_reg = ADIS16475_REG_PROD_ID, \ | ||
| 552 | .prod_id = (_prod_id), \ | ||
| 553 | .self_test_mask = BIT(2), \ | ||
| 554 | .self_test_reg = ADIS16475_REG_GLOB_CMD, \ | ||
| 555 | .cs_change_delay = 16, \ | ||
| 556 | .read_delay = 5, \ | ||
| 557 | .write_delay = 5, \ | ||
| 558 | .status_error_msgs = adis16475_status_error_msgs, \ | ||
| 559 | .status_error_mask = BIT(ADIS16475_DIAG_STAT_DATA_PATH) | \ | ||
| 560 | BIT(ADIS16475_DIAG_STAT_FLASH_MEM) | \ | ||
| 561 | BIT(ADIS16475_DIAG_STAT_SPI) | \ | ||
| 562 | BIT(ADIS16475_DIAG_STAT_STANDBY) | \ | ||
| 563 | BIT(ADIS16475_DIAG_STAT_SENSOR) | \ | ||
| 564 | BIT(ADIS16475_DIAG_STAT_MEMORY) | \ | ||
| 565 | BIT(ADIS16475_DIAG_STAT_CLK), \ | ||
| 566 | .enable_irq = adis16475_enable_irq, \ | ||
| 567 | .timeouts = (_timeouts), \ | ||
| 568 | } | ||
| 569 | |||
| 570 | static const struct adis16475_sync adis16475_sync_mode[] = { | ||
| 571 | { ADIS16475_SYNC_OUTPUT }, | ||
| 572 | { ADIS16475_SYNC_DIRECT, 1900, 2100 }, | ||
| 573 | { ADIS16475_SYNC_SCALED, 1, 128 }, | ||
| 574 | { ADIS16475_SYNC_PULSE, 1000, 2100 }, | ||
| 575 | }; | ||
| 576 | |||
| 577 | static const struct adis_timeout adis16475_timeouts = { | ||
| 578 | .reset_ms = 200, | ||
| 579 | .sw_reset_ms = 200, | ||
| 580 | .self_test_ms = 20, | ||
| 581 | }; | ||
| 582 | |||
| 583 | static const struct adis_timeout adis1650x_timeouts = { | ||
| 584 | .reset_ms = 260, | ||
| 585 | .sw_reset_ms = 260, | ||
| 586 | .self_test_ms = 30, | ||
| 587 | }; | ||
| 588 | |||
| 589 | static const struct adis16475_chip_info adis16475_chip_info[] = { | ||
| 590 | [ADIS16470] = { | ||
| 591 | .name = "adis16470", | ||
| 592 | .num_channels = ARRAY_SIZE(adis16475_channels), | ||
| 593 | .channels = adis16475_channels, | ||
| 594 | .gyro_max_val = 1, | ||
| 595 | .gyro_max_scale = IIO_RAD_TO_DEGREE(10 << 16), | ||
| 596 | .accel_max_val = 1, | ||
| 597 | .accel_max_scale = IIO_M_S_2_TO_G(800 << 16), | ||
| 598 | .temp_scale = 100, | ||
| 599 | .int_clk = 2000, | ||
| 600 | .max_dec = 1999, | ||
| 601 | .sync = adis16475_sync_mode, | ||
| 602 | .num_sync = ARRAY_SIZE(adis16475_sync_mode), | ||
| 603 | .adis_data = ADIS16475_DATA(16470, &adis16475_timeouts), | ||
| 604 | }, | ||
| 605 | [ADIS16475_1] = { | ||
| 606 | .name = "adis16475-1", | ||
| 607 | .num_channels = ARRAY_SIZE(adis16475_channels), | ||
| 608 | .channels = adis16475_channels, | ||
| 609 | .gyro_max_val = 1, | ||
| 610 | .gyro_max_scale = IIO_RAD_TO_DEGREE(160 << 16), | ||
| 611 | .accel_max_val = 1, | ||
| 612 | .accel_max_scale = IIO_M_S_2_TO_G(4000 << 16), | ||
| 613 | .temp_scale = 100, | ||
| 614 | .int_clk = 2000, | ||
| 615 | .max_dec = 1999, | ||
| 616 | .sync = adis16475_sync_mode, | ||
| 617 | .num_sync = ARRAY_SIZE(adis16475_sync_mode), | ||
| 618 | .adis_data = ADIS16475_DATA(16475, &adis16475_timeouts), | ||
| 619 | }, | ||
| 620 | [ADIS16475_2] = { | ||
| 621 | .name = "adis16475-2", | ||
| 622 | .num_channels = ARRAY_SIZE(adis16475_channels), | ||
| 623 | .channels = adis16475_channels, | ||
| 624 | .gyro_max_val = 1, | ||
| 625 | .gyro_max_scale = IIO_RAD_TO_DEGREE(40 << 16), | ||
| 626 | .accel_max_val = 1, | ||
| 627 | .accel_max_scale = IIO_M_S_2_TO_G(4000 << 16), | ||
| 628 | .temp_scale = 100, | ||
| 629 | .int_clk = 2000, | ||
| 630 | .max_dec = 1999, | ||
| 631 | .sync = adis16475_sync_mode, | ||
| 632 | .num_sync = ARRAY_SIZE(adis16475_sync_mode), | ||
| 633 | .adis_data = ADIS16475_DATA(16475, &adis16475_timeouts), | ||
| 634 | }, | ||
| 635 | [ADIS16475_3] = { | ||
| 636 | .name = "adis16475-3", | ||
| 637 | .num_channels = ARRAY_SIZE(adis16475_channels), | ||
| 638 | .channels = adis16475_channels, | ||
| 639 | .gyro_max_val = 1, | ||
| 640 | .gyro_max_scale = IIO_RAD_TO_DEGREE(10 << 16), | ||
| 641 | .accel_max_val = 1, | ||
| 642 | .accel_max_scale = IIO_M_S_2_TO_G(4000 << 16), | ||
| 643 | .temp_scale = 100, | ||
| 644 | .int_clk = 2000, | ||
| 645 | .max_dec = 1999, | ||
| 646 | .sync = adis16475_sync_mode, | ||
| 647 | .num_sync = ARRAY_SIZE(adis16475_sync_mode), | ||
| 648 | .adis_data = ADIS16475_DATA(16475, &adis16475_timeouts), | ||
| 649 | }, | ||
| 650 | [ADIS16477_1] = { | ||
| 651 | .name = "adis16477-1", | ||
| 652 | .num_channels = ARRAY_SIZE(adis16475_channels), | ||
| 653 | .channels = adis16475_channels, | ||
| 654 | .gyro_max_val = 1, | ||
| 655 | .gyro_max_scale = IIO_RAD_TO_DEGREE(160 << 16), | ||
| 656 | .accel_max_val = 1, | ||
| 657 | .accel_max_scale = IIO_M_S_2_TO_G(800 << 16), | ||
| 658 | .temp_scale = 100, | ||
| 659 | .int_clk = 2000, | ||
| 660 | .max_dec = 1999, | ||
| 661 | .sync = adis16475_sync_mode, | ||
| 662 | .num_sync = ARRAY_SIZE(adis16475_sync_mode), | ||
| 663 | .adis_data = ADIS16475_DATA(16477, &adis16475_timeouts), | ||
| 664 | }, | ||
| 665 | [ADIS16477_2] = { | ||
| 666 | .name = "adis16477-2", | ||
| 667 | .num_channels = ARRAY_SIZE(adis16475_channels), | ||
| 668 | .channels = adis16475_channels, | ||
| 669 | .gyro_max_val = 1, | ||
| 670 | .gyro_max_scale = IIO_RAD_TO_DEGREE(40 << 16), | ||
| 671 | .accel_max_val = 1, | ||
| 672 | .accel_max_scale = IIO_M_S_2_TO_G(800 << 16), | ||
| 673 | .temp_scale = 100, | ||
| 674 | .int_clk = 2000, | ||
| 675 | .max_dec = 1999, | ||
| 676 | .sync = adis16475_sync_mode, | ||
| 677 | .num_sync = ARRAY_SIZE(adis16475_sync_mode), | ||
| 678 | .adis_data = ADIS16475_DATA(16477, &adis16475_timeouts), | ||
| 679 | }, | ||
| 680 | [ADIS16477_3] = { | ||
| 681 | .name = "adis16477-3", | ||
| 682 | .num_channels = ARRAY_SIZE(adis16475_channels), | ||
| 683 | .channels = adis16475_channels, | ||
| 684 | .gyro_max_val = 1, | ||
| 685 | .gyro_max_scale = IIO_RAD_TO_DEGREE(10 << 16), | ||
| 686 | .accel_max_val = 1, | ||
| 687 | .accel_max_scale = IIO_M_S_2_TO_G(800 << 16), | ||
| 688 | .temp_scale = 100, | ||
| 689 | .int_clk = 2000, | ||
| 690 | .max_dec = 1999, | ||
| 691 | .sync = adis16475_sync_mode, | ||
| 692 | .num_sync = ARRAY_SIZE(adis16475_sync_mode), | ||
| 693 | .adis_data = ADIS16475_DATA(16477, &adis16475_timeouts), | ||
| 694 | }, | ||
| 695 | [ADIS16465_1] = { | ||
| 696 | .name = "adis16465-1", | ||
| 697 | .num_channels = ARRAY_SIZE(adis16475_channels), | ||
| 698 | .channels = adis16475_channels, | ||
| 699 | .gyro_max_val = 1, | ||
| 700 | .gyro_max_scale = IIO_RAD_TO_DEGREE(160 << 16), | ||
| 701 | .accel_max_val = 1, | ||
| 702 | .accel_max_scale = IIO_M_S_2_TO_G(4000 << 16), | ||
| 703 | .temp_scale = 100, | ||
| 704 | .int_clk = 2000, | ||
| 705 | .max_dec = 1999, | ||
| 706 | .sync = adis16475_sync_mode, | ||
| 707 | .num_sync = ARRAY_SIZE(adis16475_sync_mode), | ||
| 708 | .adis_data = ADIS16475_DATA(16465, &adis16475_timeouts), | ||
| 709 | }, | ||
| 710 | [ADIS16465_2] = { | ||
| 711 | .name = "adis16465-2", | ||
| 712 | .num_channels = ARRAY_SIZE(adis16475_channels), | ||
| 713 | .channels = adis16475_channels, | ||
| 714 | .gyro_max_val = 1, | ||
| 715 | .gyro_max_scale = IIO_RAD_TO_DEGREE(40 << 16), | ||
| 716 | .accel_max_val = 1, | ||
| 717 | .accel_max_scale = IIO_M_S_2_TO_G(4000 << 16), | ||
| 718 | .temp_scale = 100, | ||
| 719 | .int_clk = 2000, | ||
| 720 | .max_dec = 1999, | ||
| 721 | .sync = adis16475_sync_mode, | ||
| 722 | .num_sync = ARRAY_SIZE(adis16475_sync_mode), | ||
| 723 | .adis_data = ADIS16475_DATA(16465, &adis16475_timeouts), | ||
| 724 | }, | ||
| 725 | [ADIS16465_3] = { | ||
| 726 | .name = "adis16465-3", | ||
| 727 | .num_channels = ARRAY_SIZE(adis16475_channels), | ||
| 728 | .channels = adis16475_channels, | ||
| 729 | .gyro_max_val = 1, | ||
| 730 | .gyro_max_scale = IIO_RAD_TO_DEGREE(10 << 16), | ||
| 731 | .accel_max_val = 1, | ||
| 732 | .accel_max_scale = IIO_M_S_2_TO_G(4000 << 16), | ||
| 733 | .temp_scale = 100, | ||
| 734 | .int_clk = 2000, | ||
| 735 | .max_dec = 1999, | ||
| 736 | .sync = adis16475_sync_mode, | ||
| 737 | .num_sync = ARRAY_SIZE(adis16475_sync_mode), | ||
| 738 | .adis_data = ADIS16475_DATA(16465, &adis16475_timeouts), | ||
| 739 | }, | ||
| 740 | [ADIS16467_1] = { | ||
| 741 | .name = "adis16467-1", | ||
| 742 | .num_channels = ARRAY_SIZE(adis16475_channels), | ||
| 743 | .channels = adis16475_channels, | ||
| 744 | .gyro_max_val = 1, | ||
| 745 | .gyro_max_scale = IIO_RAD_TO_DEGREE(160 << 16), | ||
| 746 | .accel_max_val = 1, | ||
| 747 | .accel_max_scale = IIO_M_S_2_TO_G(800 << 16), | ||
| 748 | .temp_scale = 100, | ||
| 749 | .int_clk = 2000, | ||
| 750 | .max_dec = 1999, | ||
| 751 | .sync = adis16475_sync_mode, | ||
| 752 | .num_sync = ARRAY_SIZE(adis16475_sync_mode), | ||
| 753 | .adis_data = ADIS16475_DATA(16467, &adis16475_timeouts), | ||
| 754 | }, | ||
| 755 | [ADIS16467_2] = { | ||
| 756 | .name = "adis16467-2", | ||
| 757 | .num_channels = ARRAY_SIZE(adis16475_channels), | ||
| 758 | .channels = adis16475_channels, | ||
| 759 | .gyro_max_val = 1, | ||
| 760 | .gyro_max_scale = IIO_RAD_TO_DEGREE(40 << 16), | ||
| 761 | .accel_max_val = 1, | ||
| 762 | .accel_max_scale = IIO_M_S_2_TO_G(800 << 16), | ||
| 763 | .temp_scale = 100, | ||
| 764 | .int_clk = 2000, | ||
| 765 | .max_dec = 1999, | ||
| 766 | .sync = adis16475_sync_mode, | ||
| 767 | .num_sync = ARRAY_SIZE(adis16475_sync_mode), | ||
| 768 | .adis_data = ADIS16475_DATA(16467, &adis16475_timeouts), | ||
| 769 | }, | ||
| 770 | [ADIS16467_3] = { | ||
| 771 | .name = "adis16467-3", | ||
| 772 | .num_channels = ARRAY_SIZE(adis16475_channels), | ||
| 773 | .channels = adis16475_channels, | ||
| 774 | .gyro_max_val = 1, | ||
| 775 | .gyro_max_scale = IIO_RAD_TO_DEGREE(10 << 16), | ||
| 776 | .accel_max_val = 1, | ||
| 777 | .accel_max_scale = IIO_M_S_2_TO_G(800 << 16), | ||
| 778 | .temp_scale = 100, | ||
| 779 | .int_clk = 2000, | ||
| 780 | .max_dec = 1999, | ||
| 781 | .sync = adis16475_sync_mode, | ||
| 782 | .num_sync = ARRAY_SIZE(adis16475_sync_mode), | ||
| 783 | .adis_data = ADIS16475_DATA(16467, &adis16475_timeouts), | ||
| 784 | }, | ||
| 785 | [ADIS16500] = { | ||
| 786 | .name = "adis16500", | ||
| 787 | .num_channels = ARRAY_SIZE(adis16475_channels), | ||
| 788 | .channels = adis16475_channels, | ||
| 789 | .gyro_max_val = 1, | ||
| 790 | .gyro_max_scale = IIO_RAD_TO_DEGREE(10 << 16), | ||
| 791 | .accel_max_val = 392, | ||
| 792 | .accel_max_scale = 32000 << 16, | ||
| 793 | .temp_scale = 100, | ||
| 794 | .int_clk = 2000, | ||
| 795 | .max_dec = 1999, | ||
| 796 | .sync = adis16475_sync_mode, | ||
| 797 | /* pulse sync not supported */ | ||
| 798 | .num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1, | ||
| 799 | .has_burst32 = true, | ||
| 800 | .adis_data = ADIS16475_DATA(16500, &adis1650x_timeouts), | ||
| 801 | }, | ||
| 802 | [ADIS16505_1] = { | ||
| 803 | .name = "adis16505-1", | ||
| 804 | .num_channels = ARRAY_SIZE(adis16475_channels), | ||
| 805 | .channels = adis16475_channels, | ||
| 806 | .gyro_max_val = 1, | ||
| 807 | .gyro_max_scale = IIO_RAD_TO_DEGREE(160 << 16), | ||
| 808 | .accel_max_val = 78, | ||
| 809 | .accel_max_scale = 32000 << 16, | ||
| 810 | .temp_scale = 100, | ||
| 811 | .int_clk = 2000, | ||
| 812 | .max_dec = 1999, | ||
| 813 | .sync = adis16475_sync_mode, | ||
| 814 | /* pulse sync not supported */ | ||
| 815 | .num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1, | ||
| 816 | .has_burst32 = true, | ||
| 817 | .adis_data = ADIS16475_DATA(16505, &adis1650x_timeouts), | ||
| 818 | }, | ||
| 819 | [ADIS16505_2] = { | ||
| 820 | .name = "adis16505-2", | ||
| 821 | .num_channels = ARRAY_SIZE(adis16475_channels), | ||
| 822 | .channels = adis16475_channels, | ||
| 823 | .gyro_max_val = 1, | ||
| 824 | .gyro_max_scale = IIO_RAD_TO_DEGREE(40 << 16), | ||
| 825 | .accel_max_val = 78, | ||
| 826 | .accel_max_scale = 32000 << 16, | ||
| 827 | .temp_scale = 100, | ||
| 828 | .int_clk = 2000, | ||
| 829 | .max_dec = 1999, | ||
| 830 | .sync = adis16475_sync_mode, | ||
| 831 | /* pulse sync not supported */ | ||
| 832 | .num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1, | ||
| 833 | .has_burst32 = true, | ||
| 834 | .adis_data = ADIS16475_DATA(16505, &adis1650x_timeouts), | ||
| 835 | }, | ||
| 836 | [ADIS16505_3] = { | ||
| 837 | .name = "adis16505-3", | ||
| 838 | .num_channels = ARRAY_SIZE(adis16475_channels), | ||
| 839 | .channels = adis16475_channels, | ||
| 840 | .gyro_max_val = 1, | ||
| 841 | .gyro_max_scale = IIO_RAD_TO_DEGREE(10 << 16), | ||
| 842 | .accel_max_val = 78, | ||
| 843 | .accel_max_scale = 32000 << 16, | ||
| 844 | .temp_scale = 100, | ||
| 845 | .int_clk = 2000, | ||
| 846 | .max_dec = 1999, | ||
| 847 | .sync = adis16475_sync_mode, | ||
| 848 | /* pulse sync not supported */ | ||
| 849 | .num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1, | ||
| 850 | .has_burst32 = true, | ||
| 851 | .adis_data = ADIS16475_DATA(16505, &adis1650x_timeouts), | ||
| 852 | }, | ||
| 853 | [ADIS16507_1] = { | ||
| 854 | .name = "adis16507-1", | ||
| 855 | .num_channels = ARRAY_SIZE(adis16475_channels), | ||
| 856 | .channels = adis16475_channels, | ||
| 857 | .gyro_max_val = 1, | ||
| 858 | .gyro_max_scale = IIO_RAD_TO_DEGREE(160 << 16), | ||
| 859 | .accel_max_val = 392, | ||
| 860 | .accel_max_scale = 32000 << 16, | ||
| 861 | .temp_scale = 100, | ||
| 862 | .int_clk = 2000, | ||
| 863 | .max_dec = 1999, | ||
| 864 | .sync = adis16475_sync_mode, | ||
| 865 | /* pulse sync not supported */ | ||
| 866 | .num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1, | ||
| 867 | .has_burst32 = true, | ||
| 868 | .adis_data = ADIS16475_DATA(16507, &adis1650x_timeouts), | ||
| 869 | }, | ||
| 870 | [ADIS16507_2] = { | ||
| 871 | .name = "adis16507-2", | ||
| 872 | .num_channels = ARRAY_SIZE(adis16475_channels), | ||
| 873 | .channels = adis16475_channels, | ||
| 874 | .gyro_max_val = 1, | ||
| 875 | .gyro_max_scale = IIO_RAD_TO_DEGREE(40 << 16), | ||
| 876 | .accel_max_val = 392, | ||
| 877 | .accel_max_scale = 32000 << 16, | ||
| 878 | .temp_scale = 100, | ||
| 879 | .int_clk = 2000, | ||
| 880 | .max_dec = 1999, | ||
| 881 | .sync = adis16475_sync_mode, | ||
| 882 | /* pulse sync not supported */ | ||
| 883 | .num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1, | ||
| 884 | .has_burst32 = true, | ||
| 885 | .adis_data = ADIS16475_DATA(16507, &adis1650x_timeouts), | ||
| 886 | }, | ||
| 887 | [ADIS16507_3] = { | ||
| 888 | .name = "adis16507-3", | ||
| 889 | .num_channels = ARRAY_SIZE(adis16475_channels), | ||
| 890 | .channels = adis16475_channels, | ||
| 891 | .gyro_max_val = 1, | ||
| 892 | .gyro_max_scale = IIO_RAD_TO_DEGREE(10 << 16), | ||
| 893 | .accel_max_val = 392, | ||
| 894 | .accel_max_scale = 32000 << 16, | ||
| 895 | .temp_scale = 100, | ||
| 896 | .int_clk = 2000, | ||
| 897 | .max_dec = 1999, | ||
| 898 | .sync = adis16475_sync_mode, | ||
| 899 | /* pulse sync not supported */ | ||
| 900 | .num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1, | ||
| 901 | .has_burst32 = true, | ||
| 902 | .adis_data = ADIS16475_DATA(16507, &adis1650x_timeouts), | ||
| 903 | }, | ||
| 904 | }; | ||
| 905 | |||
| 906 | static const struct iio_info adis16475_info = { | ||
| 907 | .read_raw = &adis16475_read_raw, | ||
| 908 | .write_raw = &adis16475_write_raw, | ||
| 909 | .update_scan_mode = adis_update_scan_mode, | ||
| 910 | .debugfs_reg_access = adis_debugfs_reg_access, | ||
| 911 | }; | ||
| 912 | |||
| 913 | static struct adis_burst adis16475_burst = { | ||
| 914 | .en = true, | ||
| 915 | .reg_cmd = ADIS16475_REG_GLOB_CMD, | ||
| 916 | /* | ||
| 917 | * adis_update_scan_mode_burst() sets the burst length in respect with | ||
| 918 | * the number of channels and allocates 16 bits for each. However, | ||
| 919 | * adis1647x devices also need space for DIAG_STAT, DATA_CNTR or | ||
| 920 | * TIME_STAMP (depending on the clock mode but for us these bytes are | ||
| 921 | * don't care...) and CRC. | ||
| 922 | */ | ||
| 923 | .extra_len = 3 * sizeof(u16), | ||
| 924 | .burst_max_len = ADIS16475_BURST32_MAX_DATA, | ||
| 925 | }; | ||
| 926 | |||
| 927 | static bool adis16475_validate_crc(const u8 *buffer, u16 crc, | ||
| 928 | const bool burst32) | ||
| 929 | { | ||
| 930 | int i; | ||
| 931 | /* extra 6 elements for low gyro and accel */ | ||
| 932 | const u16 sz = burst32 ? ADIS16475_BURST32_MAX_DATA : | ||
| 933 | ADIS16475_BURST_MAX_DATA; | ||
| 934 | |||
| 935 | for (i = 0; i < sz - 2; i++) | ||
| 936 | crc -= buffer[i]; | ||
| 937 | |||
| 938 | return crc == 0; | ||
| 939 | } | ||
| 940 | |||
| 941 | static void adis16475_burst32_check(struct adis16475 *st) | ||
| 942 | { | ||
| 943 | int ret; | ||
| 944 | struct adis *adis = &st->adis; | ||
| 945 | |||
| 946 | if (!st->info->has_burst32) | ||
| 947 | return; | ||
| 948 | |||
| 949 | if (st->lsb_flag && !st->burst32) { | ||
| 950 | const u16 en = ADIS16500_BURST32(1); | ||
| 951 | |||
| 952 | ret = __adis_update_bits(&st->adis, ADIS16475_REG_MSG_CTRL, | ||
| 953 | ADIS16500_BURST32_MASK, en); | ||
| 954 | if (ret) | ||
| 955 | return; | ||
| 956 | |||
| 957 | st->burst32 = true; | ||
| 958 | |||
| 959 | /* | ||
| 960 | * In 32-bit mode we need extra 2 bytes for all gyro | ||
| 961 | * and accel channels. | ||
| 962 | */ | ||
| 963 | adis->burst_extra_len = 6 * sizeof(u16); | ||
| 964 | adis->xfer[1].len += 6 * sizeof(u16); | ||
| 965 | dev_dbg(&adis->spi->dev, "Enable burst32 mode, xfer:%d", | ||
| 966 | adis->xfer[1].len); | ||
| 967 | |||
| 968 | } else if (!st->lsb_flag && st->burst32) { | ||
| 969 | const u16 en = ADIS16500_BURST32(0); | ||
| 970 | |||
| 971 | ret = __adis_update_bits(&st->adis, ADIS16475_REG_MSG_CTRL, | ||
| 972 | ADIS16500_BURST32_MASK, en); | ||
| 973 | if (ret) | ||
| 974 | return; | ||
| 975 | |||
| 976 | st->burst32 = false; | ||
| 977 | |||
| 978 | /* Remove the extra bits */ | ||
| 979 | adis->burst_extra_len = 0; | ||
| 980 | adis->xfer[1].len -= 6 * sizeof(u16); | ||
| 981 | dev_dbg(&adis->spi->dev, "Disable burst32 mode, xfer:%d\n", | ||
| 982 | adis->xfer[1].len); | ||
| 983 | } | ||
| 984 | } | ||
| 985 | |||
| 986 | static irqreturn_t adis16475_trigger_handler(int irq, void *p) | ||
| 987 | { | ||
| 988 | struct iio_poll_func *pf = p; | ||
| 989 | struct iio_dev *indio_dev = pf->indio_dev; | ||
| 990 | struct adis16475 *st = iio_priv(indio_dev); | ||
| 991 | struct adis *adis = &st->adis; | ||
| 992 | int ret, bit, i = 0; | ||
| 993 | __be16 *buffer; | ||
| 994 | u16 crc; | ||
| 995 | bool valid; | ||
| 996 | /* offset until the first element after gyro and accel */ | ||
| 997 | const u8 offset = st->burst32 ? 13 : 7; | ||
| 998 | const u32 cached_spi_speed_hz = adis->spi->max_speed_hz; | ||
| 999 | |||
| 1000 | adis->spi->max_speed_hz = ADIS16475_BURST_MAX_SPEED; | ||
| 1001 | |||
| 1002 | ret = spi_sync(adis->spi, &adis->msg); | ||
| 1003 | if (ret) | ||
| 1004 | return ret; | ||
| 1005 | |||
| 1006 | adis->spi->max_speed_hz = cached_spi_speed_hz; | ||
| 1007 | buffer = adis->buffer; | ||
| 1008 | |||
| 1009 | crc = be16_to_cpu(buffer[offset + 2]); | ||
| 1010 | valid = adis16475_validate_crc(adis->buffer, crc, st->burst32); | ||
| 1011 | if (!valid) { | ||
| 1012 | dev_err(&adis->spi->dev, "Invalid crc\n"); | ||
| 1013 | goto check_burst32; | ||
| 1014 | } | ||
| 1015 | |||
| 1016 | for_each_set_bit(bit, indio_dev->active_scan_mask, | ||
| 1017 | indio_dev->masklength) { | ||
| 1018 | /* | ||
| 1019 | * When burst mode is used, system flags is the first data | ||
| 1020 | * channel in the sequence, but the scan index is 7. | ||
| 1021 | */ | ||
| 1022 | switch (bit) { | ||
| 1023 | case ADIS16475_SCAN_TEMP: | ||
| 1024 | st->data[i++] = buffer[offset]; | ||
| 1025 | break; | ||
| 1026 | case ADIS16475_SCAN_GYRO_X ... ADIS16475_SCAN_ACCEL_Z: | ||
| 1027 | /* | ||
| 1028 | * The first 2 bytes on the received data are the | ||
| 1029 | * DIAG_STAT reg, hence the +1 offset here... | ||
| 1030 | */ | ||
| 1031 | if (st->burst32) { | ||
| 1032 | /* upper 16 */ | ||
| 1033 | st->data[i++] = buffer[bit * 2 + 2]; | ||
| 1034 | /* lower 16 */ | ||
| 1035 | st->data[i++] = buffer[bit * 2 + 1]; | ||
| 1036 | } else { | ||
| 1037 | st->data[i++] = buffer[bit + 1]; | ||
| 1038 | /* | ||
| 1039 | * Don't bother in doing the manual read if the | ||
| 1040 | * device supports burst32. burst32 will be | ||
| 1041 | * enabled in the next call to | ||
| 1042 | * adis16475_burst32_check()... | ||
| 1043 | */ | ||
| 1044 | if (st->lsb_flag && !st->info->has_burst32) { | ||
| 1045 | u16 val = 0; | ||
| 1046 | const u32 reg = ADIS16475_REG_X_GYRO_L + | ||
| 1047 | bit * 4; | ||
| 1048 | |||
| 1049 | adis_read_reg_16(adis, reg, &val); | ||
| 1050 | st->data[i++] = cpu_to_be16(val); | ||
| 1051 | } else { | ||
| 1052 | /* lower not used */ | ||
| 1053 | st->data[i++] = 0; | ||
| 1054 | } | ||
| 1055 | } | ||
| 1056 | break; | ||
| 1057 | } | ||
| 1058 | } | ||
| 1059 | |||
| 1060 | iio_push_to_buffers_with_timestamp(indio_dev, st->data, pf->timestamp); | ||
| 1061 | check_burst32: | ||
| 1062 | /* | ||
| 1063 | * We only check the burst mode at the end of the current capture since | ||
| 1064 | * it takes a full data ready cycle for the device to update the burst | ||
| 1065 | * array. | ||
| 1066 | */ | ||
| 1067 | adis16475_burst32_check(st); | ||
| 1068 | iio_trigger_notify_done(indio_dev->trig); | ||
| 1069 | |||
| 1070 | return IRQ_HANDLED; | ||
| 1071 | } | ||
| 1072 | |||
| 1073 | static void adis16475_disable_clk(void *data) | ||
| 1074 | { | ||
| 1075 | clk_disable_unprepare((struct clk *)data); | ||
| 1076 | } | ||
| 1077 | |||
| 1078 | static int adis16475_config_sync_mode(struct adis16475 *st) | ||
| 1079 | { | ||
| 1080 | int ret; | ||
| 1081 | struct device *dev = &st->adis.spi->dev; | ||
| 1082 | const struct adis16475_sync *sync; | ||
| 1083 | u32 sync_mode; | ||
| 1084 | |||
| 1085 | /* default to internal clk */ | ||
| 1086 | st->clk_freq = st->info->int_clk * 1000; | ||
| 1087 | |||
| 1088 | ret = device_property_read_u32(dev, "adi,sync-mode", &sync_mode); | ||
| 1089 | if (ret) | ||
| 1090 | return 0; | ||
| 1091 | |||
| 1092 | if (sync_mode >= st->info->num_sync) { | ||
| 1093 | dev_err(dev, "Invalid sync mode: %u for %s\n", sync_mode, | ||
| 1094 | st->info->name); | ||
| 1095 | return -EINVAL; | ||
| 1096 | } | ||
| 1097 | |||
| 1098 | sync = &st->info->sync[sync_mode]; | ||
| 1099 | |||
| 1100 | /* All the other modes require external input signal */ | ||
| 1101 | if (sync->sync_mode != ADIS16475_SYNC_OUTPUT) { | ||
| 1102 | struct clk *clk = devm_clk_get(dev, NULL); | ||
| 1103 | |||
| 1104 | if (IS_ERR(clk)) | ||
| 1105 | return PTR_ERR(clk); | ||
| 1106 | |||
| 1107 | ret = clk_prepare_enable(clk); | ||
| 1108 | if (ret) | ||
| 1109 | return ret; | ||
| 1110 | |||
| 1111 | ret = devm_add_action_or_reset(dev, adis16475_disable_clk, clk); | ||
| 1112 | if (ret) | ||
| 1113 | return ret; | ||
| 1114 | |||
| 1115 | st->clk_freq = clk_get_rate(clk); | ||
| 1116 | if (st->clk_freq < sync->min_rate || | ||
| 1117 | st->clk_freq > sync->max_rate) { | ||
| 1118 | dev_err(dev, | ||
| 1119 | "Clk rate:%u not in a valid range:[%u %u]\n", | ||
| 1120 | st->clk_freq, sync->min_rate, sync->max_rate); | ||
| 1121 | return -EINVAL; | ||
| 1122 | } | ||
| 1123 | |||
| 1124 | if (sync->sync_mode == ADIS16475_SYNC_SCALED) { | ||
| 1125 | u16 up_scale; | ||
| 1126 | u32 scaled_out_freq = 0; | ||
| 1127 | /* | ||
| 1128 | * If we are in scaled mode, we must have an up_scale. | ||
| 1129 | * In scaled mode the allowable input clock range is | ||
| 1130 | * 1 Hz to 128 Hz, and the allowable output range is | ||
| 1131 | * 1900 to 2100 Hz. Hence, a scale must be given to | ||
| 1132 | * get the allowable output. | ||
| 1133 | */ | ||
| 1134 | ret = device_property_read_u32(dev, | ||
| 1135 | "adi,scaled-output-hz", | ||
| 1136 | &scaled_out_freq); | ||
| 1137 | if (ret) { | ||
| 1138 | dev_err(dev, "adi,scaled-output-hz must be given when in scaled sync mode"); | ||
| 1139 | return -EINVAL; | ||
| 1140 | } else if (scaled_out_freq < 1900 || | ||
| 1141 | scaled_out_freq > 2100) { | ||
| 1142 | dev_err(dev, "Invalid value: %u for adi,scaled-output-hz", | ||
| 1143 | scaled_out_freq); | ||
| 1144 | return -EINVAL; | ||
| 1145 | } | ||
| 1146 | |||
| 1147 | up_scale = DIV_ROUND_CLOSEST(scaled_out_freq, | ||
| 1148 | st->clk_freq); | ||
| 1149 | |||
| 1150 | ret = __adis_write_reg_16(&st->adis, | ||
| 1151 | ADIS16475_REG_UP_SCALE, | ||
| 1152 | up_scale); | ||
| 1153 | if (ret) | ||
| 1154 | return ret; | ||
| 1155 | |||
| 1156 | st->clk_freq = scaled_out_freq; | ||
| 1157 | } | ||
| 1158 | |||
| 1159 | st->clk_freq *= 1000; | ||
| 1160 | } | ||
| 1161 | /* | ||
| 1162 | * Keep in mind that the mask for the clk modes in adis1650* | ||
| 1163 | * chips is different (1100 instead of 11100). However, we | ||
| 1164 | * are not configuring BIT(4) in these chips and the default | ||
| 1165 | * value is 0, so we are fine in doing the below operations. | ||
| 1166 | * I'm keeping this for simplicity and avoiding extra variables | ||
| 1167 | * in chip_info. | ||
| 1168 | */ | ||
| 1169 | ret = __adis_update_bits(&st->adis, ADIS16475_REG_MSG_CTRL, | ||
| 1170 | ADIS16475_SYNC_MODE_MASK, sync->sync_mode); | ||
| 1171 | if (ret) | ||
| 1172 | return ret; | ||
| 1173 | |||
| 1174 | usleep_range(250, 260); | ||
| 1175 | |||
| 1176 | return 0; | ||
| 1177 | } | ||
| 1178 | |||
| 1179 | static int adis16475_config_irq_pin(struct adis16475 *st) | ||
| 1180 | { | ||
| 1181 | int ret; | ||
| 1182 | struct irq_data *desc; | ||
| 1183 | u32 irq_type; | ||
| 1184 | u16 val = 0; | ||
| 1185 | u8 polarity; | ||
| 1186 | struct spi_device *spi = st->adis.spi; | ||
| 1187 | |||
| 1188 | desc = irq_get_irq_data(spi->irq); | ||
| 1189 | if (!desc) { | ||
| 1190 | dev_err(&spi->dev, "Could not find IRQ %d\n", spi->irq); | ||
| 1191 | return -EINVAL; | ||
| 1192 | } | ||
| 1193 | /* | ||
| 1194 | * It is possible to configure the data ready polarity. Furthermore, we | ||
| 1195 | * need to update the adis struct if we want data ready as active low. | ||
| 1196 | */ | ||
| 1197 | irq_type = irqd_get_trigger_type(desc); | ||
| 1198 | if (irq_type == IRQ_TYPE_EDGE_RISING) { | ||
| 1199 | polarity = 1; | ||
| 1200 | st->adis.irq_flag = IRQF_TRIGGER_RISING; | ||
| 1201 | } else if (irq_type == IRQ_TYPE_EDGE_FALLING) { | ||
| 1202 | polarity = 0; | ||
| 1203 | st->adis.irq_flag = IRQF_TRIGGER_FALLING; | ||
| 1204 | } else { | ||
| 1205 | dev_err(&spi->dev, "Invalid interrupt type 0x%x specified\n", | ||
| 1206 | irq_type); | ||
| 1207 | return -EINVAL; | ||
| 1208 | } | ||
| 1209 | |||
| 1210 | val = ADIS16475_MSG_CTRL_DR_POL(polarity); | ||
| 1211 | ret = __adis_update_bits(&st->adis, ADIS16475_REG_MSG_CTRL, | ||
| 1212 | ADIS16475_MSG_CTRL_DR_POL_MASK, val); | ||
| 1213 | if (ret) | ||
| 1214 | return ret; | ||
| 1215 | /* | ||
| 1216 | * There is a delay writing to any bits written to the MSC_CTRL | ||
| 1217 | * register. It should not be bigger than 200us, so 250 should be more | ||
| 1218 | * than enough! | ||
| 1219 | */ | ||
| 1220 | usleep_range(250, 260); | ||
| 1221 | |||
| 1222 | return 0; | ||
| 1223 | } | ||
| 1224 | |||
| 1225 | static const struct of_device_id adis16475_of_match[] = { | ||
| 1226 | { .compatible = "adi,adis16470", | ||
| 1227 | .data = &adis16475_chip_info[ADIS16470] }, | ||
| 1228 | { .compatible = "adi,adis16475-1", | ||
| 1229 | .data = &adis16475_chip_info[ADIS16475_1] }, | ||
| 1230 | { .compatible = "adi,adis16475-2", | ||
| 1231 | .data = &adis16475_chip_info[ADIS16475_2] }, | ||
| 1232 | { .compatible = "adi,adis16475-3", | ||
| 1233 | .data = &adis16475_chip_info[ADIS16475_3] }, | ||
| 1234 | { .compatible = "adi,adis16477-1", | ||
| 1235 | .data = &adis16475_chip_info[ADIS16477_1] }, | ||
| 1236 | { .compatible = "adi,adis16477-2", | ||
| 1237 | .data = &adis16475_chip_info[ADIS16477_2] }, | ||
| 1238 | { .compatible = "adi,adis16477-3", | ||
| 1239 | .data = &adis16475_chip_info[ADIS16477_3] }, | ||
| 1240 | { .compatible = "adi,adis16465-1", | ||
| 1241 | .data = &adis16475_chip_info[ADIS16465_1] }, | ||
| 1242 | { .compatible = "adi,adis16465-2", | ||
| 1243 | .data = &adis16475_chip_info[ADIS16465_2] }, | ||
| 1244 | { .compatible = "adi,adis16465-3", | ||
| 1245 | .data = &adis16475_chip_info[ADIS16465_3] }, | ||
| 1246 | { .compatible = "adi,adis16467-1", | ||
| 1247 | .data = &adis16475_chip_info[ADIS16467_1] }, | ||
| 1248 | { .compatible = "adi,adis16467-2", | ||
| 1249 | .data = &adis16475_chip_info[ADIS16467_2] }, | ||
| 1250 | { .compatible = "adi,adis16467-3", | ||
| 1251 | .data = &adis16475_chip_info[ADIS16467_3] }, | ||
| 1252 | { .compatible = "adi,adis16500", | ||
| 1253 | .data = &adis16475_chip_info[ADIS16500] }, | ||
| 1254 | { .compatible = "adi,adis16505-1", | ||
| 1255 | .data = &adis16475_chip_info[ADIS16505_1] }, | ||
| 1256 | { .compatible = "adi,adis16505-2", | ||
| 1257 | .data = &adis16475_chip_info[ADIS16505_2] }, | ||
| 1258 | { .compatible = "adi,adis16505-3", | ||
| 1259 | .data = &adis16475_chip_info[ADIS16505_3] }, | ||
| 1260 | { .compatible = "adi,adis16507-1", | ||
| 1261 | .data = &adis16475_chip_info[ADIS16507_1] }, | ||
| 1262 | { .compatible = "adi,adis16507-2", | ||
| 1263 | .data = &adis16475_chip_info[ADIS16507_2] }, | ||
| 1264 | { .compatible = "adi,adis16507-3", | ||
| 1265 | .data = &adis16475_chip_info[ADIS16507_3] }, | ||
| 1266 | { }, | ||
| 1267 | }; | ||
| 1268 | MODULE_DEVICE_TABLE(of, adis16475_of_match); | ||
| 1269 | |||
| 1270 | static int adis16475_probe(struct spi_device *spi) | ||
| 1271 | { | ||
| 1272 | struct iio_dev *indio_dev; | ||
| 1273 | struct adis16475 *st; | ||
| 1274 | int ret; | ||
| 1275 | |||
| 1276 | indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); | ||
| 1277 | if (!indio_dev) | ||
| 1278 | return -ENOMEM; | ||
| 1279 | |||
| 1280 | st = iio_priv(indio_dev); | ||
| 1281 | spi_set_drvdata(spi, indio_dev); | ||
| 1282 | st->adis.burst = &adis16475_burst; | ||
| 1283 | |||
| 1284 | st->info = device_get_match_data(&spi->dev); | ||
| 1285 | if (!st->info) | ||
| 1286 | return -EINVAL; | ||
| 1287 | |||
| 1288 | ret = adis_init(&st->adis, indio_dev, spi, &st->info->adis_data); | ||
| 1289 | if (ret) | ||
| 1290 | return ret; | ||
| 1291 | |||
| 1292 | indio_dev->dev.parent = &spi->dev; | ||
| 1293 | indio_dev->name = st->info->name; | ||
| 1294 | indio_dev->channels = st->info->channels; | ||
| 1295 | indio_dev->num_channels = st->info->num_channels; | ||
| 1296 | indio_dev->info = &adis16475_info; | ||
| 1297 | indio_dev->modes = INDIO_DIRECT_MODE; | ||
| 1298 | |||
| 1299 | ret = __adis_initial_startup(&st->adis); | ||
| 1300 | if (ret) | ||
| 1301 | return ret; | ||
| 1302 | |||
| 1303 | ret = adis16475_config_irq_pin(st); | ||
| 1304 | if (ret) | ||
| 1305 | return ret; | ||
| 1306 | |||
| 1307 | ret = adis16475_config_sync_mode(st); | ||
| 1308 | if (ret) | ||
| 1309 | return ret; | ||
| 1310 | |||
| 1311 | ret = devm_adis_setup_buffer_and_trigger(&st->adis, indio_dev, | ||
| 1312 | adis16475_trigger_handler); | ||
| 1313 | if (ret) | ||
| 1314 | return ret; | ||
| 1315 | |||
| 1316 | adis16475_enable_irq(&st->adis, false); | ||
| 1317 | |||
| 1318 | ret = devm_iio_device_register(&spi->dev, indio_dev); | ||
| 1319 | if (ret) | ||
| 1320 | return ret; | ||
| 1321 | |||
| 1322 | adis16475_debugfs_init(indio_dev); | ||
| 1323 | |||
| 1324 | return 0; | ||
| 1325 | } | ||
| 1326 | |||
| 1327 | static struct spi_driver adis16475_driver = { | ||
| 1328 | .driver = { | ||
| 1329 | .name = "adis16475", | ||
| 1330 | .of_match_table = adis16475_of_match, | ||
| 1331 | }, | ||
| 1332 | .probe = adis16475_probe, | ||
| 1333 | }; | ||
| 1334 | module_spi_driver(adis16475_driver); | ||
| 1335 | |||
| 1336 | MODULE_AUTHOR("Nuno Sa <nuno.sa@analog.com>"); | ||
| 1337 | MODULE_DESCRIPTION("Analog Devices ADIS16475 IMU driver"); | ||
| 1338 | MODULE_LICENSE("GPL"); | ||
| @@ -284,22 +284,18 @@ DEFINE_DEBUGFS_ATTRIBUTE(adis16480_flash_count_fops, · 283 unmodified lines | |||
| 284 | static int adis16480_debugfs_init(struct iio_dev *indio_dev) | 284 | static int adis16480_debugfs_init(struct iio_dev *indio_dev) |
| 285 | { | 285 | { |
| 286 | struct adis16480 *adis16480 = iio_priv(indio_dev); | 286 | struct adis16480 *adis16480 = iio_priv(indio_dev); |
| 287 | struct dentry *d = iio_get_debugfs_dentry(indio_dev); | ||
| 287 | 288 | ||
| 288 | debugfs_create_file_unsafe("firmware_revision", 0400, | 289 | debugfs_create_file_unsafe("firmware_revision", 0400, |
| 289 | indio_dev->debugfs_dentry, adis16480, | 290 | d, adis16480, &adis16480_firmware_revision_fops); |
| 290 | &adis16480_firmware_revision_fops); | ||
| 291 | debugfs_create_file_unsafe("firmware_date", 0400, | 291 | debugfs_create_file_unsafe("firmware_date", 0400, |
| 292 | indio_dev->debugfs_dentry, adis16480, | 292 | d, adis16480, &adis16480_firmware_date_fops); |
| 293 | &adis16480_firmware_date_fops); | ||
| 294 | debugfs_create_file_unsafe("serial_number", 0400, | 293 | debugfs_create_file_unsafe("serial_number", 0400, |
| 295 | indio_dev->debugfs_dentry, adis16480, | 294 | d, adis16480, &adis16480_serial_number_fops); |
| 296 | &adis16480_serial_number_fops); | ||
| 297 | debugfs_create_file_unsafe("product_id", 0400, | 295 | debugfs_create_file_unsafe("product_id", 0400, |
| 298 | indio_dev->debugfs_dentry, adis16480, | 296 | d, adis16480, &adis16480_product_id_fops); |
| 299 | &adis16480_product_id_fops); | ||
| 300 | debugfs_create_file_unsafe("flash_count", 0400, | 297 | debugfs_create_file_unsafe("flash_count", 0400, |
| 301 | indio_dev->debugfs_dentry, adis16480, | 298 | d, adis16480, &adis16480_flash_count_fops); |
| 302 | &adis16480_flash_count_fops); | ||
| 303 | 299 | ||
| 304 | return 0; | 300 | return 0; |
| 305 | } | 301 | } |
| @@ -23,25 +23,30 @@ static int adis_update_scan_mode_burst(struct iio_dev *indio_dev, · 22 unmodified lines | |||
| 23 | const unsigned long *scan_mask) | 23 | const unsigned long *scan_mask) |
| 24 | { | 24 | { |
| 25 | struct adis *adis = iio_device_get_drvdata(indio_dev); | 25 | struct adis *adis = iio_device_get_drvdata(indio_dev); |
| 26 | unsigned int burst_length; | 26 | unsigned int burst_length, burst_max_length; |
| 27 | u8 *tx; | 27 | u8 *tx; |
| 28 | 28 | ||
| 29 | /* All but the timestamp channel */ | 29 | /* All but the timestamp channel */ |
| 30 | burst_length = (indio_dev->num_channels - 1) * sizeof(u16); | 30 | burst_length = (indio_dev->num_channels - 1) * sizeof(u16); |
| 31 | burst_length += adis->burst->extra_len; | 31 | burst_length += adis->burst->extra_len + adis->burst_extra_len; |
| 32 | |||
| 33 | if (adis->burst->burst_max_len) | ||
| 34 | burst_max_length = adis->burst->burst_max_len; | ||
| 35 | else | ||
| 36 | burst_max_length = burst_length; | ||
| 32 | 37 | ||
| 33 | adis->xfer = kcalloc(2, sizeof(*adis->xfer), GFP_KERNEL); | 38 | adis->xfer = kcalloc(2, sizeof(*adis->xfer), GFP_KERNEL); |
| 34 | if (!adis->xfer) | 39 | if (!adis->xfer) |
| 35 | return -ENOMEM; | 40 | return -ENOMEM; |
| 36 | 41 | ||
| 37 | adis->buffer = kzalloc(burst_length + sizeof(u16), GFP_KERNEL); | 42 | adis->buffer = kzalloc(burst_max_length + sizeof(u16), GFP_KERNEL); |
| 38 | if (!adis->buffer) { | 43 | if (!adis->buffer) { |
| 39 | kfree(adis->xfer); | 44 | kfree(adis->xfer); |
| 40 | adis->xfer = NULL; | 45 | adis->xfer = NULL; |
| 41 | return -ENOMEM; | 46 | return -ENOMEM; |
| 42 | } | 47 | } |
| 43 | 48 | ||
| 44 | tx = adis->buffer + burst_length; | 49 | tx = adis->buffer + burst_max_length; |
| 45 | tx[0] = ADIS_READ_REG(adis->burst->reg_cmd); | 50 | tx[0] = ADIS_READ_REG(adis->burst->reg_cmd); |
| 46 | tx[1] = 0; | 51 | tx[1] = 0; |
| 47 | 52 | ||
| @@ -156,6 +161,14 @@ static irqreturn_t adis_trigger_handler(int irq, void *p) · 108 unmodified lines | |||
| 156 | return IRQ_HANDLED; | 161 | return IRQ_HANDLED; |
| 157 | } | 162 | } |
| 158 | 163 | ||
| 164 | static void adis_buffer_cleanup(void *arg) | ||
| 165 | { | ||
| 166 | struct adis *adis = arg; | ||
| 167 | |||
| 168 | kfree(adis->buffer); | ||
| 169 | kfree(adis->xfer); | ||
| 170 | } | ||
| 171 | |||
| 159 | /** | 172 | /** |
| 160 | * adis_setup_buffer_and_trigger() - Sets up buffer and trigger for the adis device | 173 | * adis_setup_buffer_and_trigger() - Sets up buffer and trigger for the adis device |
| 161 | * @adis: The adis device. | 174 | * @adis: The adis device. |
| @@ -198,6 +211,43 @@ error_buffer_cleanup: · 36 unmodified lines | |||
| 198 | } | 211 | } |
| 199 | EXPORT_SYMBOL_GPL(adis_setup_buffer_and_trigger); | 212 | EXPORT_SYMBOL_GPL(adis_setup_buffer_and_trigger); |
| 200 | 213 | ||
| 214 | /** | ||
| 215 | * devm_adis_setup_buffer_and_trigger() - Sets up buffer and trigger for | ||
| 216 | * the managed adis device | ||
| 217 | * @adis: The adis device | ||
| 218 | * @indio_dev: The IIO device | ||
| 219 | * @trigger_handler: Optional trigger handler, may be NULL. | ||
| 220 | * | ||
| 221 | * Returns 0 on success, a negative error code otherwise. | ||
| 222 | * | ||
| 223 | * This function perfoms exactly the same as adis_setup_buffer_and_trigger() | ||
| 224 | */ | ||
| 225 | int | ||
| 226 | devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, | ||
| 227 | irq_handler_t trigger_handler) | ||
| 228 | { | ||
| 229 | int ret; | ||
| 230 | |||
| 231 | if (!trigger_handler) | ||
| 232 | trigger_handler = adis_trigger_handler; | ||
| 233 | |||
| 234 | ret = devm_iio_triggered_buffer_setup(&adis->spi->dev, indio_dev, | ||
| 235 | &iio_pollfunc_store_time, | ||
| 236 | trigger_handler, NULL); | ||
| 237 | if (ret) | ||
| 238 | return ret; | ||
| 239 | |||
| 240 | if (adis->spi->irq) { | ||
| 241 | ret = devm_adis_probe_trigger(adis, indio_dev); | ||
| 242 | if (ret) | ||
| 243 | return ret; | ||
| 244 | } | ||
| 245 | |||
| 246 | return devm_add_action_or_reset(&adis->spi->dev, adis_buffer_cleanup, | ||
| 247 | adis); | ||
| 248 | } | ||
| 249 | EXPORT_SYMBOL_GPL(devm_adis_setup_buffer_and_trigger); | ||
| 250 | |||
| 201 | /** | 251 | /** |
| 202 | * adis_cleanup_buffer_and_trigger() - Free buffer and trigger resources | 252 | * adis_cleanup_buffer_and_trigger() - Free buffer and trigger resources |
| 203 | * @adis: The adis device. | 253 | * @adis: The adis device. |
| @@ -27,6 +27,34 @@ static const struct iio_trigger_ops adis_trigger_ops = { · 26 unmodified lines | |||
| 27 | .set_trigger_state = &adis_data_rdy_trigger_set_state, | 27 | .set_trigger_state = &adis_data_rdy_trigger_set_state, |
| 28 | }; | 28 | }; |
| 29 | 29 | ||
| 30 | static void adis_trigger_setup(struct adis *adis) | ||
| 31 | { | ||
| 32 | adis->trig->dev.parent = &adis->spi->dev; | ||
| 33 | adis->trig->ops = &adis_trigger_ops; | ||
| 34 | iio_trigger_set_drvdata(adis->trig, adis); | ||
| 35 | } | ||
| 36 | |||
| 37 | static int adis_validate_irq_flag(struct adis *adis) | ||
| 38 | { | ||
| 39 | /* | ||
| 40 | * Typically this devices have data ready either on the rising edge or | ||
| 41 | * on the falling edge of the data ready pin. This checks enforces that | ||
| 42 | * one of those is set in the drivers... It defaults to | ||
| 43 | * IRQF_TRIGGER_RISING for backward compatibility wiht devices that | ||
| 44 | * don't support changing the pin polarity. | ||
| 45 | */ | ||
| 46 | if (!adis->irq_flag) { | ||
| 47 | adis->irq_flag = IRQF_TRIGGER_RISING; | ||
| 48 | return 0; | ||
| 49 | } else if (adis->irq_flag != IRQF_TRIGGER_RISING && | ||
| 50 | adis->irq_flag != IRQF_TRIGGER_FALLING) { | ||
| 51 | dev_err(&adis->spi->dev, "Invalid IRQ mask: %08lx\n", | ||
| 52 | adis->irq_flag); | ||
| 53 | return -EINVAL; | ||
| 54 | } | ||
| 55 | |||
| 56 | return 0; | ||
| 57 | } | ||
| 30 | /** | 58 | /** |
| 31 | * adis_probe_trigger() - Sets up trigger for a adis device | 59 | * adis_probe_trigger() - Sets up trigger for a adis device |
| 32 | * @adis: The adis device | 60 | * @adis: The adis device |
| @@ -45,13 +73,15 @@ int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev) · 12 unmodified lines | |||
| 45 | if (adis->trig == NULL) | 73 | if (adis->trig == NULL) |
| 46 | return -ENOMEM; | 74 | return -ENOMEM; |
| 47 | 75 | ||
| 48 | adis->trig->dev.parent = &adis->spi->dev; | 76 | adis_trigger_setup(adis); |
| 49 | adis->trig->ops = &adis_trigger_ops; | 77 | |
| 50 | iio_trigger_set_drvdata(adis->trig, adis); | 78 | ret = adis_validate_irq_flag(adis); |
| 79 | if (ret) | ||
| 80 | return ret; | ||
| 51 | 81 | ||
| 52 | ret = request_irq(adis->spi->irq, | 82 | ret = request_irq(adis->spi->irq, |
| 53 | &iio_trigger_generic_data_rdy_poll, | 83 | &iio_trigger_generic_data_rdy_poll, |
| 54 | IRQF_TRIGGER_RISING, | 84 | adis->irq_flag, |
| 55 | indio_dev->name, | 85 | indio_dev->name, |
| 56 | adis->trig); | 86 | adis->trig); |
| 57 | if (ret) | 87 | if (ret) |
| @@ -73,6 +103,40 @@ error_free_trig: · 15 unmodified lines | |||
| 73 | } | 103 | } |
| 74 | EXPORT_SYMBOL_GPL(adis_probe_trigger); | 104 | EXPORT_SYMBOL_GPL(adis_probe_trigger); |
| 75 | 105 | ||
| 106 | /** | ||
| 107 | * devm_adis_probe_trigger() - Sets up trigger for a managed adis device | ||
| 108 | * @adis: The adis device | ||
| 109 | * @indio_dev: The IIO device | ||
| 110 | * | ||
| 111 | * Returns 0 on success or a negative error code | ||
| 112 | */ | ||
| 113 | int devm_adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev) | ||
| 114 | { | ||
| 115 | int ret; | ||
| 116 | |||
| 117 | adis->trig = devm_iio_trigger_alloc(&adis->spi->dev, "%s-dev%d", | ||
| 118 | indio_dev->name, indio_dev->id); | ||
| 119 | if (!adis->trig) | ||
| 120 | return -ENOMEM; | ||
| 121 | |||
| 122 | adis_trigger_setup(adis); | ||
| 123 | |||
| 124 | ret = adis_validate_irq_flag(adis); | ||
| 125 | if (ret) | ||
| 126 | return ret; | ||
| 127 | |||
| 128 | ret = devm_request_irq(&adis->spi->dev, adis->spi->irq, | ||
| 129 | &iio_trigger_generic_data_rdy_poll, | ||
| 130 | adis->irq_flag, | ||
| 131 | indio_dev->name, | ||
| 132 | adis->trig); | ||
| 133 | if (ret) | ||
| 134 | return ret; | ||
| 135 | |||
| 136 | return devm_iio_trigger_register(&adis->spi->dev, adis->trig); | ||
| 137 | } | ||
| 138 | EXPORT_SYMBOL_GPL(devm_adis_probe_trigger); | ||
| 139 | |||
| 76 | /** | 140 | /** |
| 77 | * adis_remove_trigger() - Remove trigger for a adis devices | 141 | * adis_remove_trigger() - Remove trigger for a adis devices |
| 78 | * @adis: The adis device | 142 | * @adis: The adis device |
| @@ -27,7 +27,8 @@ · 26 unmodified lines | |||
| 27 | * - FIFO size: 4KB | 27 | * - FIFO size: 4KB |
| 28 | * | 28 | * |
| 29 | * - LSM6DSO/LSM6DSOX/ASM330LHH/LSM6DSR/ISM330DHCX: | 29 | * - LSM6DSO/LSM6DSOX/ASM330LHH/LSM6DSR/ISM330DHCX: |
| 30 | * - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416 | 30 | * - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416, |
| 31 | * 833 | ||
| 31 | * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 | 32 | * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 |
| 32 | * - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000 | 33 | * - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000 |
| 33 | * - FIFO size: 3KB | 34 | * - FIFO size: 3KB |
| @@ -791,7 +792,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 757 unmodified lines | |||
| 791 | .odr_avl[3] = { 104000, 0x04 }, | 792 | .odr_avl[3] = { 104000, 0x04 }, |
| 792 | .odr_avl[4] = { 208000, 0x05 }, | 793 | .odr_avl[4] = { 208000, 0x05 }, |
| 793 | .odr_avl[5] = { 416000, 0x06 }, | 794 | .odr_avl[5] = { 416000, 0x06 }, |
| 794 | .odr_len = 6, | 795 | .odr_avl[6] = { 833000, 0x07 }, |
| 796 | .odr_len = 7, | ||
| 795 | }, | 797 | }, |
| 796 | [ST_LSM6DSX_ID_GYRO] = { | 798 | [ST_LSM6DSX_ID_GYRO] = { |
| 797 | .reg = { | 799 | .reg = { |
| @@ -804,7 +806,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 6 unmodified lines | |||
| 804 | .odr_avl[3] = { 104000, 0x04 }, | 806 | .odr_avl[3] = { 104000, 0x04 }, |
| 805 | .odr_avl[4] = { 208000, 0x05 }, | 807 | .odr_avl[4] = { 208000, 0x05 }, |
| 806 | .odr_avl[5] = { 416000, 0x06 }, | 808 | .odr_avl[5] = { 416000, 0x06 }, |
| 807 | .odr_len = 6, | 809 | .odr_avl[6] = { 833000, 0x07 }, |
| 810 | .odr_len = 7, | ||
| 808 | }, | 811 | }, |
| 809 | }, | 812 | }, |
| 810 | .fs_table = { | 813 | .fs_table = { |
| @@ -994,7 +997,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 183 unmodified lines | |||
| 994 | .odr_avl[3] = { 104000, 0x04 }, | 997 | .odr_avl[3] = { 104000, 0x04 }, |
| 995 | .odr_avl[4] = { 208000, 0x05 }, | 998 | .odr_avl[4] = { 208000, 0x05 }, |
| 996 | .odr_avl[5] = { 416000, 0x06 }, | 999 | .odr_avl[5] = { 416000, 0x06 }, |
| 997 | .odr_len = 6, | 1000 | .odr_avl[6] = { 833000, 0x07 }, |
| 1001 | .odr_len = 7, | ||
| 998 | }, | 1002 | }, |
| 999 | [ST_LSM6DSX_ID_GYRO] = { | 1003 | [ST_LSM6DSX_ID_GYRO] = { |
| 1000 | .reg = { | 1004 | .reg = { |
| @@ -1007,7 +1011,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 6 unmodified lines | |||
| 1007 | .odr_avl[3] = { 104000, 0x04 }, | 1011 | .odr_avl[3] = { 104000, 0x04 }, |
| 1008 | .odr_avl[4] = { 208000, 0x05 }, | 1012 | .odr_avl[4] = { 208000, 0x05 }, |
| 1009 | .odr_avl[5] = { 416000, 0x06 }, | 1013 | .odr_avl[5] = { 416000, 0x06 }, |
| 1010 | .odr_len = 6, | 1014 | .odr_avl[6] = { 833000, 0x07 }, |
| 1015 | .odr_len = 7, | ||
| 1011 | }, | 1016 | }, |
| 1012 | }, | 1017 | }, |
| 1013 | .fs_table = { | 1018 | .fs_table = { |
| @@ -1171,7 +1176,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 157 unmodified lines | |||
| 1171 | .odr_avl[3] = { 104000, 0x04 }, | 1176 | .odr_avl[3] = { 104000, 0x04 }, |
| 1172 | .odr_avl[4] = { 208000, 0x05 }, | 1177 | .odr_avl[4] = { 208000, 0x05 }, |
| 1173 | .odr_avl[5] = { 416000, 0x06 }, | 1178 | .odr_avl[5] = { 416000, 0x06 }, |
| 1174 | .odr_len = 6, | 1179 | .odr_avl[6] = { 833000, 0x07 }, |
| 1180 | .odr_len = 7, | ||
| 1175 | }, | 1181 | }, |
| 1176 | [ST_LSM6DSX_ID_GYRO] = { | 1182 | [ST_LSM6DSX_ID_GYRO] = { |
| 1177 | .reg = { | 1183 | .reg = { |
| @@ -1184,7 +1190,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 6 unmodified lines | |||
| 1184 | .odr_avl[3] = { 104000, 0x04 }, | 1190 | .odr_avl[3] = { 104000, 0x04 }, |
| 1185 | .odr_avl[4] = { 208000, 0x05 }, | 1191 | .odr_avl[4] = { 208000, 0x05 }, |
| 1186 | .odr_avl[5] = { 416000, 0x06 }, | 1192 | .odr_avl[5] = { 416000, 0x06 }, |
| 1187 | .odr_len = 6, | 1193 | .odr_avl[6] = { 833000, 0x07 }, |
| 1194 | .odr_len = 7, | ||
| 1188 | }, | 1195 | }, |
| 1189 | }, | 1196 | }, |
| 1190 | .fs_table = { | 1197 | .fs_table = { |
| @@ -189,10 +189,12 @@ __poll_t iio_buffer_poll(struct file *filp, · 188 unmodified lines | |||
| 189 | */ | 189 | */ |
| 190 | void iio_buffer_wakeup_poll(struct iio_dev *indio_dev) | 190 | void iio_buffer_wakeup_poll(struct iio_dev *indio_dev) |
| 191 | { | 191 | { |
| 192 | if (!indio_dev->buffer) | 192 | struct iio_buffer *buffer = indio_dev->buffer; |
| 193 | |||
| 194 | if (!buffer) | ||
| 193 | return; | 195 | return; |
| 194 | 196 | ||
| 195 | wake_up(&indio_dev->buffer->pollq); | 197 | wake_up(&buffer->pollq); |
| 196 | } | 198 | } |
| 197 | 199 | ||
| 198 | void iio_buffer_init(struct iio_buffer *buffer) | 200 | void iio_buffer_init(struct iio_buffer *buffer) |
| @@ -262,10 +264,11 @@ static ssize_t iio_scan_el_show(struct device *dev, · 63 unmodified lines | |||
| 262 | { | 264 | { |
| 263 | int ret; | 265 | int ret; |
| 264 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); | 266 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); |
| 267 | struct iio_buffer *buffer = indio_dev->buffer; | ||
| 265 | 268 | ||
| 266 | /* Ensure ret is 0 or 1. */ | 269 | /* Ensure ret is 0 or 1. */ |
| 267 | ret = !!test_bit(to_iio_dev_attr(attr)->address, | 270 | ret = !!test_bit(to_iio_dev_attr(attr)->address, |
| 268 | indio_dev->buffer->scan_mask); | 271 | buffer->scan_mask); |
| 269 | 272 | ||
| 270 | return sprintf(buf, "%d\n", ret); | 273 | return sprintf(buf, "%d\n", ret); |
| 271 | } | 274 | } |
| @@ -381,7 +384,7 @@ static ssize_t iio_scan_el_store(struct device *dev, · 109 unmodified lines | |||
| 381 | if (ret < 0) | 384 | if (ret < 0) |
| 382 | return ret; | 385 | return ret; |
| 383 | mutex_lock(&indio_dev->mlock); | 386 | mutex_lock(&indio_dev->mlock); |
| 384 | if (iio_buffer_is_active(indio_dev->buffer)) { | 387 | if (iio_buffer_is_active(buffer)) { |
| 385 | ret = -EBUSY; | 388 | ret = -EBUSY; |
| 386 | goto error_ret; | 389 | goto error_ret; |
| 387 | } | 390 | } |
| @@ -410,7 +413,9 @@ static ssize_t iio_scan_el_ts_show(struct device *dev, · 22 unmodified lines | |||
| 410 | char *buf) | 413 | char *buf) |
| 411 | { | 414 | { |
| 412 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); | 415 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); |
| 413 | return sprintf(buf, "%d\n", indio_dev->buffer->scan_timestamp); | 416 | struct iio_buffer *buffer = indio_dev->buffer; |
| 417 | |||
| 418 | return sprintf(buf, "%d\n", buffer->scan_timestamp); | ||
| 414 | } | 419 | } |
| 415 | 420 | ||
| 416 | static ssize_t iio_scan_el_ts_store(struct device *dev, | 421 | static ssize_t iio_scan_el_ts_store(struct device *dev, |
| @@ -420,6 +425,7 @@ static ssize_t iio_scan_el_ts_store(struct device *dev, · 3 unmodified lines | |||
| 420 | { | 425 | { |
| 421 | int ret; | 426 | int ret; |
| 422 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); | 427 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); |
| 428 | struct iio_buffer *buffer = indio_dev->buffer; | ||
| 423 | bool state; | 429 | bool state; |
| 424 | 430 | ||
| 425 | ret = strtobool(buf, &state); | 431 | ret = strtobool(buf, &state); |
| @@ -427,11 +433,11 @@ static ssize_t iio_scan_el_ts_store(struct device *dev, · 1 unmodified line | |||
| 427 | return ret; | 433 | return ret; |
| 428 | 434 | ||
| 429 | mutex_lock(&indio_dev->mlock); | 435 | mutex_lock(&indio_dev->mlock); |
| 430 | if (iio_buffer_is_active(indio_dev->buffer)) { | 436 | if (iio_buffer_is_active(buffer)) { |
| 431 | ret = -EBUSY; | 437 | ret = -EBUSY; |
| 432 | goto error_ret; | 438 | goto error_ret; |
| 433 | } | 439 | } |
| 434 | indio_dev->buffer->scan_timestamp = state; | 440 | buffer->scan_timestamp = state; |
| 435 | error_ret: | 441 | error_ret: |
| 436 | mutex_unlock(&indio_dev->mlock); | 442 | mutex_unlock(&indio_dev->mlock); |
| 437 | 443 | ||
| @@ -439,10 +445,10 @@ error_ret: · 1 unmodified line | |||
| 439 | } | 445 | } |
| 440 | 446 | ||
| 441 | static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev, | 447 | static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev, |
| 448 | struct iio_buffer *buffer, | ||
| 442 | const struct iio_chan_spec *chan) | 449 | const struct iio_chan_spec *chan) |
| 443 | { | 450 | { |
| 444 | int ret, attrcount = 0; | 451 | int ret, attrcount = 0; |
| 445 | struct iio_buffer *buffer = indio_dev->buffer; | ||
| 446 | 452 | ||
| 447 | ret = __iio_add_chan_devattr("index", | 453 | ret = __iio_add_chan_devattr("index", |
| 448 | chan, | 454 | chan, |
| @@ -518,7 +524,7 @@ static ssize_t iio_buffer_write_length(struct device *dev, · 69 unmodified lines | |||
| 518 | return len; | 524 | return len; |
| 519 | 525 | ||
| 520 | mutex_lock(&indio_dev->mlock); | 526 | mutex_lock(&indio_dev->mlock); |
| 521 | if (iio_buffer_is_active(indio_dev->buffer)) { | 527 | if (iio_buffer_is_active(buffer)) { |
| 522 | ret = -EBUSY; | 528 | ret = -EBUSY; |
| 523 | } else { | 529 | } else { |
| 524 | buffer->access->set_length(buffer, val); | 530 | buffer->access->set_length(buffer, val); |
| @@ -539,7 +545,9 @@ static ssize_t iio_buffer_show_enable(struct device *dev, · 14 unmodified lines | |||
| 539 | char *buf) | 545 | char *buf) |
| 540 | { | 546 | { |
| 541 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); | 547 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); |
| 542 | return sprintf(buf, "%d\n", iio_buffer_is_active(indio_dev->buffer)); | 548 | struct iio_buffer *buffer = indio_dev->buffer; |
| 549 | |||
| 550 | return sprintf(buf, "%d\n", iio_buffer_is_active(buffer)); | ||
| 543 | } | 551 | } |
| 544 | 552 | ||
| 545 | static unsigned int iio_storage_bytes_for_si(struct iio_dev *indio_dev, | 553 | static unsigned int iio_storage_bytes_for_si(struct iio_dev *indio_dev, |
| @@ -1129,6 +1137,7 @@ static ssize_t iio_buffer_store_enable(struct device *dev, · 583 unmodified lines | |||
| 1129 | int ret; | 1137 | int ret; |
| 1130 | bool requested_state; | 1138 | bool requested_state; |
| 1131 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); | 1139 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); |
| 1140 | struct iio_buffer *buffer = indio_dev->buffer; | ||
| 1132 | bool inlist; | 1141 | bool inlist; |
| 1133 | 1142 | ||
| 1134 | ret = strtobool(buf, &requested_state); | 1143 | ret = strtobool(buf, &requested_state); |
| @@ -1138,17 +1147,15 @@ static ssize_t iio_buffer_store_enable(struct device *dev, · 3 unmodified lines | |||
| 1138 | mutex_lock(&indio_dev->mlock); | 1147 | mutex_lock(&indio_dev->mlock); |
| 1139 | 1148 | ||
| 1140 | /* Find out if it is in the list */ | 1149 | /* Find out if it is in the list */ |
| 1141 | inlist = iio_buffer_is_active(indio_dev->buffer); | 1150 | inlist = iio_buffer_is_active(buffer); |
| 1142 | /* Already in desired state */ | 1151 | /* Already in desired state */ |
| 1143 | if (inlist == requested_state) | 1152 | if (inlist == requested_state) |
| 1144 | goto done; | 1153 | goto done; |
| 1145 | 1154 | ||
| 1146 | if (requested_state) | 1155 | if (requested_state) |
| 1147 | ret = __iio_update_buffers(indio_dev, | 1156 | ret = __iio_update_buffers(indio_dev, buffer, NULL); |
| 1148 | indio_dev->buffer, NULL); | ||
| 1149 | else | 1157 | else |
| 1150 | ret = __iio_update_buffers(indio_dev, | 1158 | ret = __iio_update_buffers(indio_dev, NULL, buffer); |
| 1151 | NULL, indio_dev->buffer); | ||
| 1152 | 1159 | ||
| 1153 | done: | 1160 | done: |
| 1154 | mutex_unlock(&indio_dev->mlock); | 1161 | mutex_unlock(&indio_dev->mlock); |
| @@ -1190,7 +1197,7 @@ static ssize_t iio_buffer_store_watermark(struct device *dev, · 35 unmodified lines | |||
| 1190 | goto out; | 1197 | goto out; |
| 1191 | } | 1198 | } |
| 1192 | 1199 | ||
| 1193 | if (iio_buffer_is_active(indio_dev->buffer)) { | 1200 | if (iio_buffer_is_active(buffer)) { |
| 1194 | ret = -EBUSY; | 1201 | ret = -EBUSY; |
| 1195 | goto out; | 1202 | goto out; |
| 1196 | } | 1203 | } |
| @@ -1207,11 +1214,9 @@ static ssize_t iio_dma_show_data_available(struct device *dev, · 10 unmodified lines | |||
| 1207 | char *buf) | 1214 | char *buf) |
| 1208 | { | 1215 | { |
| 1209 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); | 1216 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); |
| 1210 | size_t bytes; | 1217 | struct iio_buffer *buffer = indio_dev->buffer; |
| 1211 | |||
| 1212 | bytes = iio_buffer_data_available(indio_dev->buffer); | ||
| 1213 | 1218 | ||
| 1214 | return sprintf(buf, "%zu\n", bytes); | 1219 | return sprintf(buf, "%zu\n", iio_buffer_data_available(buffer)); |
| 1215 | } | 1220 | } |
| 1216 | 1221 | ||
| 1217 | static DEVICE_ATTR(length, S_IRUGO | S_IWUSR, iio_buffer_read_length, | 1222 | static DEVICE_ATTR(length, S_IRUGO | S_IWUSR, iio_buffer_read_length, |
| @@ -1292,7 +1297,7 @@ int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev) · 74 unmodified lines | |||
| 1292 | if (channels[i].scan_index < 0) | 1297 | if (channels[i].scan_index < 0) |
| 1293 | continue; | 1298 | continue; |
| 1294 | 1299 | ||
| 1295 | ret = iio_buffer_add_channel_sysfs(indio_dev, | 1300 | ret = iio_buffer_add_channel_sysfs(indio_dev, buffer, |
| 1296 | &channels[i]); | 1301 | &channels[i]); |
| 1297 | if (ret < 0) | 1302 | if (ret < 0) |
| 1298 | goto error_cleanup_dynamic; | 1303 | goto error_cleanup_dynamic; |
| @@ -1332,20 +1337,22 @@ error_free_scan_mask: · 33 unmodified lines | |||
| 1332 | bitmap_free(buffer->scan_mask); | 1337 | bitmap_free(buffer->scan_mask); |
| 1333 | error_cleanup_dynamic: | 1338 | error_cleanup_dynamic: |
| 1334 | iio_free_chan_devattr_list(&buffer->scan_el_dev_attr_list); | 1339 | iio_free_chan_devattr_list(&buffer->scan_el_dev_attr_list); |
| 1335 | kfree(indio_dev->buffer->buffer_group.attrs); | 1340 | kfree(buffer->buffer_group.attrs); |
| 1336 | 1341 | ||
| 1337 | return ret; | 1342 | return ret; |
| 1338 | } | 1343 | } |
| 1339 | 1344 | ||
| 1340 | void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev) | 1345 | void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev) |
| 1341 | { | 1346 | { |
| 1342 | if (!indio_dev->buffer) | 1347 | struct iio_buffer *buffer = indio_dev->buffer; |
| 1348 | |||
| 1349 | if (!buffer) | ||
| 1343 | return; | 1350 | return; |
| 1344 | 1351 | ||
| 1345 | bitmap_free(indio_dev->buffer->scan_mask); | 1352 | bitmap_free(buffer->scan_mask); |
| 1346 | kfree(indio_dev->buffer->buffer_group.attrs); | 1353 | kfree(buffer->buffer_group.attrs); |
| 1347 | kfree(indio_dev->buffer->scan_el_group.attrs); | 1354 | kfree(buffer->scan_el_group.attrs); |
| 1348 | iio_free_chan_devattr_list(&indio_dev->buffer->scan_el_dev_attr_list); | 1355 | iio_free_chan_devattr_list(&buffer->scan_el_dev_attr_list); |
| 1349 | } | 1356 | } |
| 1350 | 1357 | ||
| 1351 | /** | 1358 | /** |
| @@ -1507,27 +1507,27 @@ struct iio_dev *iio_device_alloc(int sizeof_priv) · 1506 unmodified lines | |||
| 1507 | alloc_size += IIO_ALIGN - 1; | 1507 | alloc_size += IIO_ALIGN - 1; |
| 1508 | 1508 | ||
| 1509 | dev = kzalloc(alloc_size, GFP_KERNEL); | 1509 | dev = kzalloc(alloc_size, GFP_KERNEL); |
| 1510 | if (!dev) | ||
| 1511 | return NULL; | ||
| 1510 | 1512 | ||
| 1511 | if (dev) { | 1513 | dev->dev.groups = dev->groups; |
| 1512 | dev->dev.groups = dev->groups; | 1514 | dev->dev.type = &iio_device_type; |
| 1513 | dev->dev.type = &iio_device_type; | 1515 | dev->dev.bus = &iio_bus_type; |
| 1514 | dev->dev.bus = &iio_bus_type; | 1516 | device_initialize(&dev->dev); |
| 1515 | device_initialize(&dev->dev); | 1517 | dev_set_drvdata(&dev->dev, (void *)dev); |
| 1516 | dev_set_drvdata(&dev->dev, (void *)dev); | 1518 | mutex_init(&dev->mlock); |
| 1517 | mutex_init(&dev->mlock); | 1519 | mutex_init(&dev->info_exist_lock); |
| 1518 | mutex_init(&dev->info_exist_lock); | 1520 | INIT_LIST_HEAD(&dev->channel_attr_list); |
| 1519 | INIT_LIST_HEAD(&dev->channel_attr_list); | 1521 | |
| 1520 | 1522 | dev->id = ida_simple_get(&iio_ida, 0, 0, GFP_KERNEL); | |
| 1521 | dev->id = ida_simple_get(&iio_ida, 0, 0, GFP_KERNEL); | 1523 | if (dev->id < 0) { |
| 1522 | if (dev->id < 0) { | 1524 | /* cannot use a dev_err as the name isn't available */ |
| 1523 | /* cannot use a dev_err as the name isn't available */ | 1525 | pr_err("failed to get device id\n"); |
| 1524 | pr_err("failed to get device id\n"); | 1526 | kfree(dev); |
| 1525 | kfree(dev); | 1527 | return NULL; |
| 1526 | return NULL; | ||
| 1527 | } | ||
| 1528 | dev_set_name(&dev->dev, "iio:device%d", dev->id); | ||
| 1529 | INIT_LIST_HEAD(&dev->buffer_list); | ||
| 1530 | } | 1528 | } |
| 1529 | dev_set_name(&dev->dev, "iio:device%d", dev->id); | ||
| 1530 | INIT_LIST_HEAD(&dev->buffer_list); | ||
| 1531 | 1531 | ||
| 1532 | return dev; | 1532 | return dev; |
| 1533 | } | 1533 | } |
| @@ -516,6 +516,8 @@ config US5182D · 515 unmodified lines | |||
| 516 | 516 | ||
| 517 | config VCNL4000 | 517 | config VCNL4000 |
| 518 | tristate "VCNL4000/4010/4020/4200 combined ALS and proximity sensor" | 518 | tristate "VCNL4000/4010/4020/4200 combined ALS and proximity sensor" |
| 519 | select IIO_BUFFER | ||
| 520 | select IIO_TRIGGERED_BUFFER | ||
| 519 | depends on I2C | 521 | depends on I2C |
| 520 | help | 522 | help |
| 521 | Say Y here if you want to build a driver for the Vishay VCNL4000, | 523 | Say Y here if you want to build a driver for the Vishay VCNL4000, |
| @@ -13,7 +13,7 @@ · 12 unmodified lines | |||
| 13 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
| 14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
| 15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 16 | #include <linux/of.h> | 16 | #include <linux/mod_devicetable.h> |
| 17 | #include <linux/pm_runtime.h> | 17 | #include <linux/pm_runtime.h> |
| 18 | #include <linux/iio/iio.h> | 18 | #include <linux/iio/iio.h> |
| 19 | #include <linux/iio/sysfs.h> | 19 | #include <linux/iio/sysfs.h> |
| @@ -273,13 +273,11 @@ static const struct i2c_device_id bh1780_id[] = { · 253 unmodified lines | |||
| 273 | 273 | ||
| 274 | MODULE_DEVICE_TABLE(i2c, bh1780_id); | 274 | MODULE_DEVICE_TABLE(i2c, bh1780_id); |
| 275 | 275 | ||
| 276 | #ifdef CONFIG_OF | ||
| 277 | static const struct of_device_id of_bh1780_match[] = { | 276 | static const struct of_device_id of_bh1780_match[] = { |
| 278 | { .compatible = "rohm,bh1780gli", }, | 277 | { .compatible = "rohm,bh1780gli", }, |
| 279 | {}, | 278 | {}, |
| 280 | }; | 279 | }; |
| 281 | MODULE_DEVICE_TABLE(of, of_bh1780_match); | 280 | MODULE_DEVICE_TABLE(of, of_bh1780_match); |
| 282 | #endif | ||
| 283 | 281 | ||
| 284 | static struct i2c_driver bh1780_driver = { | 282 | static struct i2c_driver bh1780_driver = { |
| 285 | .probe = bh1780_probe, | 283 | .probe = bh1780_probe, |
| @@ -288,7 +286,7 @@ static struct i2c_driver bh1780_driver = { · 2 unmodified lines | |||
| 288 | .driver = { | 286 | .driver = { |
| 289 | .name = "bh1780", | 287 | .name = "bh1780", |
| 290 | .pm = &bh1780_dev_pm_ops, | 288 | .pm = &bh1780_dev_pm_ops, |
| 291 | .of_match_table = of_match_ptr(of_bh1780_match), | 289 | .of_match_table = of_bh1780_match, |
| 292 | }, | 290 | }, |
| 293 | }; | 291 | }; |
| 294 | 292 | ||
| @@ -4,11 +4,13 @@ · 3 unmodified lines | |||
| 4 | * Author: Kevin Tsai <ktsai@capellamicro.com> | 4 | * Author: Kevin Tsai <ktsai@capellamicro.com> |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #include <linux/acpi.h> | ||
| 7 | #include <linux/delay.h> | 8 | #include <linux/delay.h> |
| 8 | #include <linux/err.h> | 9 | #include <linux/err.h> |
| 9 | #include <linux/i2c.h> | 10 | #include <linux/i2c.h> |
| 10 | #include <linux/mutex.h> | 11 | #include <linux/mutex.h> |
| 11 | #include <linux/module.h> | 12 | #include <linux/module.h> |
| 13 | #include <linux/mod_devicetable.h> | ||
| 12 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
| 13 | #include <linux/regulator/consumer.h> | 15 | #include <linux/regulator/consumer.h> |
| 14 | #include <linux/iio/iio.h> | 16 | #include <linux/iio/iio.h> |
| @@ -18,17 +20,24 @@ · 3 unmodified lines | |||
| 18 | 20 | ||
| 19 | /* Registers Address */ | 21 | /* Registers Address */ |
| 20 | #define CM32181_REG_ADDR_CMD 0x00 | 22 | #define CM32181_REG_ADDR_CMD 0x00 |
| 23 | #define CM32181_REG_ADDR_WH 0x01 | ||
| 24 | #define CM32181_REG_ADDR_WL 0x02 | ||
| 25 | #define CM32181_REG_ADDR_TEST 0x03 | ||
| 21 | #define CM32181_REG_ADDR_ALS 0x04 | 26 | #define CM32181_REG_ADDR_ALS 0x04 |
| 22 | #define CM32181_REG_ADDR_STATUS 0x06 | 27 | #define CM32181_REG_ADDR_STATUS 0x06 |
| 23 | #define CM32181_REG_ADDR_ID 0x07 | 28 | #define CM32181_REG_ADDR_ID 0x07 |
| 24 | 29 | ||
| 25 | /* Number of Configurable Registers */ | 30 | /* Number of Configurable Registers */ |
| 26 | #define CM32181_CONF_REG_NUM 0x01 | 31 | #define CM32181_CONF_REG_NUM 4 |
| 27 | 32 | ||
| 28 | /* CMD register */ | 33 | /* CMD register */ |
| 29 | #define CM32181_CMD_ALS_ENABLE 0x00 | 34 | #define CM32181_CMD_ALS_DISABLE BIT(0) |
| 30 | #define CM32181_CMD_ALS_DISABLE 0x01 | 35 | #define CM32181_CMD_ALS_INT_EN BIT(1) |
| 31 | #define CM32181_CMD_ALS_INT_EN 0x02 | 36 | #define CM32181_CMD_ALS_THRES_WINDOW BIT(2) |
| 37 | |||
| 38 | #define CM32181_CMD_ALS_PERS_SHIFT 4 | ||
| 39 | #define CM32181_CMD_ALS_PERS_MASK (0x03 << CM32181_CMD_ALS_PERS_SHIFT) | ||
| 40 | #define CM32181_CMD_ALS_PERS_DEFAULT (0x01 << CM32181_CMD_ALS_PERS_SHIFT) | ||
| 32 | 41 | ||
| 33 | #define CM32181_CMD_ALS_IT_SHIFT 6 | 42 | #define CM32181_CMD_ALS_IT_SHIFT 6 |
| 34 | #define CM32181_CMD_ALS_IT_MASK (0x0F << CM32181_CMD_ALS_IT_SHIFT) | 43 | #define CM32181_CMD_ALS_IT_MASK (0x0F << CM32181_CMD_ALS_IT_SHIFT) |
| @@ -38,27 +47,133 @@ · 3 unmodified lines | |||
| 38 | #define CM32181_CMD_ALS_SM_MASK (0x03 << CM32181_CMD_ALS_SM_SHIFT) | 47 | #define CM32181_CMD_ALS_SM_MASK (0x03 << CM32181_CMD_ALS_SM_SHIFT) |
| 39 | #define CM32181_CMD_ALS_SM_DEFAULT (0x01 << CM32181_CMD_ALS_SM_SHIFT) | 48 | #define CM32181_CMD_ALS_SM_DEFAULT (0x01 << CM32181_CMD_ALS_SM_SHIFT) |
| 40 | 49 | ||
| 41 | #define CM32181_MLUX_PER_BIT 5 /* ALS_SM=01 IT=800ms */ | 50 | #define CM32181_LUX_PER_BIT 500 /* ALS_SM=01 IT=800ms */ |
| 42 | #define CM32181_MLUX_PER_BIT_BASE_IT 800000 /* Based on IT=800ms */ | 51 | #define CM32181_LUX_PER_BIT_RESOLUTION 100000 |
| 43 | #define CM32181_CALIBSCALE_DEFAULT 1000 | 52 | #define CM32181_LUX_PER_BIT_BASE_IT 800000 /* Based on IT=800ms */ |
| 44 | #define CM32181_CALIBSCALE_RESOLUTION 1000 | 53 | #define CM32181_CALIBSCALE_DEFAULT 100000 |
| 45 | #define MLUX_PER_LUX 1000 | 54 | #define CM32181_CALIBSCALE_RESOLUTION 100000 |
| 46 | 55 | ||
| 47 | static const u8 cm32181_reg[CM32181_CONF_REG_NUM] = { | 56 | #define SMBUS_ALERT_RESPONSE_ADDRESS 0x0c |
| 48 | CM32181_REG_ADDR_CMD, | 57 | |
| 49 | }; | 58 | /* CPM0 Index 0: device-id (3218 or 32181), 1: Unknown, 2: init_regs_bitmap */ |
| 59 | #define CPM0_REGS_BITMAP 2 | ||
| 60 | #define CPM0_HEADER_SIZE 3 | ||
| 50 | 61 | ||
| 51 | static const int als_it_bits[] = {12, 8, 0, 1, 2, 3}; | 62 | /* CPM1 Index 0: lux_per_bit, 1: calibscale, 2: resolution (100000) */ |
| 52 | static const int als_it_value[] = {25000, 50000, 100000, 200000, 400000, | 63 | #define CPM1_LUX_PER_BIT 0 |
| 53 | 800000}; | 64 | #define CPM1_CALIBSCALE 1 |
| 65 | #define CPM1_SIZE 3 | ||
| 66 | |||
| 67 | /* CM3218 Family */ | ||
| 68 | static const int cm3218_als_it_bits[] = { 0, 1, 2, 3 }; | ||
| 69 | static const int cm3218_als_it_values[] = { 100000, 200000, 400000, 800000 }; | ||
| 70 | |||
| 71 | /* CM32181 Family */ | ||
| 72 | static const int cm32181_als_it_bits[] = { 12, 8, 0, 1, 2, 3 }; | ||
| 73 | static const int cm32181_als_it_values[] = { | ||
| 74 | 25000, 50000, 100000, 200000, 400000, 800000 | ||
| 75 | }; | ||
| 54 | 76 | ||
| 55 | struct cm32181_chip { | 77 | struct cm32181_chip { |
| 56 | struct i2c_client *client; | 78 | struct i2c_client *client; |
| 79 | struct device *dev; | ||
| 57 | struct mutex lock; | 80 | struct mutex lock; |
| 58 | u16 conf_regs[CM32181_CONF_REG_NUM]; | 81 | u16 conf_regs[CM32181_CONF_REG_NUM]; |
| 82 | unsigned long init_regs_bitmap; | ||
| 59 | int calibscale; | 83 | int calibscale; |
| 84 | int lux_per_bit; | ||
| 85 | int lux_per_bit_base_it; | ||
| 86 | int num_als_it; | ||
| 87 | const int *als_it_bits; | ||
| 88 | const int *als_it_values; | ||
| 60 | }; | 89 | }; |
| 61 | 90 | ||
| 91 | static int cm32181_read_als_it(struct cm32181_chip *cm32181, int *val2); | ||
| 92 | |||
| 93 | #ifdef CONFIG_ACPI | ||
| 94 | /** | ||
| 95 | * cm32181_acpi_get_cpm() - Get CPM object from ACPI | ||
| 96 | * @client pointer of struct i2c_client. | ||
| 97 | * @obj_name pointer of ACPI object name. | ||
| 98 | * @count maximum size of return array. | ||
| 99 | * @vals pointer of array for return elements. | ||
| 100 | * | ||
| 101 | * Convert ACPI CPM table to array. | ||
| 102 | * | ||
| 103 | * Return: -ENODEV for fail. Otherwise is number of elements. | ||
| 104 | */ | ||
| 105 | static int cm32181_acpi_get_cpm(struct device *dev, char *obj_name, | ||
| 106 | u64 *values, int count) | ||
| 107 | { | ||
| 108 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
| 109 | union acpi_object *cpm, *elem; | ||
| 110 | acpi_handle handle; | ||
| 111 | acpi_status status; | ||
| 112 | int i; | ||
| 113 | |||
| 114 | handle = ACPI_HANDLE(dev); | ||
| 115 | if (!handle) | ||
| 116 | return -ENODEV; | ||
| 117 | |||
| 118 | status = acpi_evaluate_object(handle, obj_name, NULL, &buffer); | ||
| 119 | if (ACPI_FAILURE(status)) { | ||
| 120 | dev_err(dev, "object %s not found\n", obj_name); | ||
| 121 | return -ENODEV; | ||
| 122 | } | ||
| 123 | |||
| 124 | cpm = buffer.pointer; | ||
| 125 | if (cpm->package.count > count) | ||
| 126 | dev_warn(dev, "%s table contains %u values, only using first %d values\n", | ||
| 127 | obj_name, cpm->package.count, count); | ||
| 128 | |||
| 129 | count = min_t(int, cpm->package.count, count); | ||
| 130 | for (i = 0; i < count; i++) { | ||
| 131 | elem = &(cpm->package.elements[i]); | ||
| 132 | values[i] = elem->integer.value; | ||
| 133 | } | ||
| 134 | |||
| 135 | kfree(buffer.pointer); | ||
| 136 | |||
| 137 | return count; | ||
| 138 | } | ||
| 139 | |||
| 140 | static void cm32181_acpi_parse_cpm_tables(struct cm32181_chip *cm32181) | ||
| 141 | { | ||
| 142 | u64 vals[CPM0_HEADER_SIZE + CM32181_CONF_REG_NUM]; | ||
| 143 | struct device *dev = cm32181->dev; | ||
| 144 | int i, count; | ||
| 145 | |||
| 146 | count = cm32181_acpi_get_cpm(dev, "CPM0", vals, ARRAY_SIZE(vals)); | ||
| 147 | if (count <= CPM0_HEADER_SIZE) | ||
| 148 | return; | ||
| 149 | |||
| 150 | count -= CPM0_HEADER_SIZE; | ||
| 151 | |||
| 152 | cm32181->init_regs_bitmap = vals[CPM0_REGS_BITMAP]; | ||
| 153 | cm32181->init_regs_bitmap &= GENMASK(count - 1, 0); | ||
| 154 | for_each_set_bit(i, &cm32181->init_regs_bitmap, count) | ||
| 155 | cm32181->conf_regs[i] = vals[CPM0_HEADER_SIZE + i]; | ||
| 156 | |||
| 157 | count = cm32181_acpi_get_cpm(dev, "CPM1", vals, ARRAY_SIZE(vals)); | ||
| 158 | if (count != CPM1_SIZE) | ||
| 159 | return; | ||
| 160 | |||
| 161 | cm32181->lux_per_bit = vals[CPM1_LUX_PER_BIT]; | ||
| 162 | |||
| 163 | /* Check for uncalibrated devices */ | ||
| 164 | if (vals[CPM1_CALIBSCALE] == CM32181_CALIBSCALE_DEFAULT) | ||
| 165 | return; | ||
| 166 | |||
| 167 | cm32181->calibscale = vals[CPM1_CALIBSCALE]; | ||
| 168 | /* CPM1 lux_per_bit is for the current it value */ | ||
| 169 | cm32181_read_als_it(cm32181, &cm32181->lux_per_bit_base_it); | ||
| 170 | } | ||
| 171 | #else | ||
| 172 | static void cm32181_acpi_parse_cpm_tables(struct cm32181_chip *cm32181) | ||
| 173 | { | ||
| 174 | } | ||
| 175 | #endif /* CONFIG_ACPI */ | ||
| 176 | |||
| 62 | /** | 177 | /** |
| 63 | * cm32181_reg_init() - Initialize CM32181 registers | 178 | * cm32181_reg_init() - Initialize CM32181 registers |
| 64 | * @cm32181: pointer of struct cm32181. | 179 | * @cm32181: pointer of struct cm32181. |
| @@ -78,18 +193,37 @@ static int cm32181_reg_init(struct cm32181_chip *cm32181) · 13 unmodified lines | |||
| 78 | return ret; | 193 | return ret; |
| 79 | 194 | ||
| 80 | /* check device ID */ | 195 | /* check device ID */ |
| 81 | if ((ret & 0xFF) != 0x81) | 196 | switch (ret & 0xFF) { |
| 197 | case 0x18: /* CM3218 */ | ||
| 198 | cm32181->num_als_it = ARRAY_SIZE(cm3218_als_it_bits); | ||
| 199 | cm32181->als_it_bits = cm3218_als_it_bits; | ||
| 200 | cm32181->als_it_values = cm3218_als_it_values; | ||
| 201 | break; | ||
| 202 | case 0x81: /* CM32181 */ | ||
| 203 | case 0x82: /* CM32182, fully compat. with CM32181 */ | ||
| 204 | cm32181->num_als_it = ARRAY_SIZE(cm32181_als_it_bits); | ||
| 205 | cm32181->als_it_bits = cm32181_als_it_bits; | ||
| 206 | cm32181->als_it_values = cm32181_als_it_values; | ||
| 207 | break; | ||
| 208 | default: | ||
| 82 | return -ENODEV; | 209 | return -ENODEV; |
| 210 | } | ||
| 83 | 211 | ||
| 84 | /* Default Values */ | 212 | /* Default Values */ |
| 85 | cm32181->conf_regs[CM32181_REG_ADDR_CMD] = CM32181_CMD_ALS_ENABLE | | 213 | cm32181->conf_regs[CM32181_REG_ADDR_CMD] = |
| 86 | CM32181_CMD_ALS_IT_DEFAULT | CM32181_CMD_ALS_SM_DEFAULT; | 214 | CM32181_CMD_ALS_IT_DEFAULT | CM32181_CMD_ALS_SM_DEFAULT; |
| 215 | cm32181->init_regs_bitmap = BIT(CM32181_REG_ADDR_CMD); | ||
| 87 | cm32181->calibscale = CM32181_CALIBSCALE_DEFAULT; | 216 | cm32181->calibscale = CM32181_CALIBSCALE_DEFAULT; |
| 217 | cm32181->lux_per_bit = CM32181_LUX_PER_BIT; | ||
| 218 | cm32181->lux_per_bit_base_it = CM32181_LUX_PER_BIT_BASE_IT; | ||
| 219 | |||
| 220 | if (ACPI_HANDLE(cm32181->dev)) | ||
| 221 | cm32181_acpi_parse_cpm_tables(cm32181); | ||
| 88 | 222 | ||
| 89 | /* Initialize registers*/ | 223 | /* Initialize registers*/ |
| 90 | for (i = 0; i < CM32181_CONF_REG_NUM; i++) { | 224 | for_each_set_bit(i, &cm32181->init_regs_bitmap, CM32181_CONF_REG_NUM) { |
| 91 | ret = i2c_smbus_write_word_data(client, cm32181_reg[i], | 225 | ret = i2c_smbus_write_word_data(client, i, |
| 92 | cm32181->conf_regs[i]); | 226 | cm32181->conf_regs[i]); |
| 93 | if (ret < 0) | 227 | if (ret < 0) |
| 94 | return ret; | 228 | return ret; |
| 95 | } | 229 | } |
| @@ -102,7 +236,7 @@ static int cm32181_reg_init(struct cm32181_chip *cm32181) · 6 unmodified lines | |||
| 102 | * @cm32181: pointer of struct cm32181 | 236 | * @cm32181: pointer of struct cm32181 |
| 103 | * @val2: pointer of int to load the als_it value. | 237 | * @val2: pointer of int to load the als_it value. |
| 104 | * | 238 | * |
| 105 | * Report the current integartion time by millisecond. | 239 | * Report the current integration time in milliseconds. |
| 106 | * | 240 | * |
| 107 | * Return: IIO_VAL_INT_PLUS_MICRO for success, otherwise -EINVAL. | 241 | * Return: IIO_VAL_INT_PLUS_MICRO for success, otherwise -EINVAL. |
| 108 | */ | 242 | */ |
| @@ -114,9 +248,9 @@ static int cm32181_read_als_it(struct cm32181_chip *cm32181, int *val2) · 5 unmodified lines | |||
| 114 | als_it = cm32181->conf_regs[CM32181_REG_ADDR_CMD]; | 248 | als_it = cm32181->conf_regs[CM32181_REG_ADDR_CMD]; |
| 115 | als_it &= CM32181_CMD_ALS_IT_MASK; | 249 | als_it &= CM32181_CMD_ALS_IT_MASK; |
| 116 | als_it >>= CM32181_CMD_ALS_IT_SHIFT; | 250 | als_it >>= CM32181_CMD_ALS_IT_SHIFT; |
| 117 | for (i = 0; i < ARRAY_SIZE(als_it_bits); i++) { | 251 | for (i = 0; i < cm32181->num_als_it; i++) { |
| 118 | if (als_it == als_it_bits[i]) { | 252 | if (als_it == cm32181->als_it_bits[i]) { |
| 119 | *val2 = als_it_value[i]; | 253 | *val2 = cm32181->als_it_values[i]; |
| 120 | return IIO_VAL_INT_PLUS_MICRO; | 254 | return IIO_VAL_INT_PLUS_MICRO; |
| 121 | } | 255 | } |
| 122 | } | 256 | } |
| @@ -139,14 +273,14 @@ static int cm32181_write_als_it(struct cm32181_chip *cm32181, int val) · 16 unmodified lines | |||
| 139 | u16 als_it; | 273 | u16 als_it; |
| 140 | int ret, i, n; | 274 | int ret, i, n; |
| 141 | 275 | ||
| 142 | n = ARRAY_SIZE(als_it_value); | 276 | n = cm32181->num_als_it; |
| 143 | for (i = 0; i < n; i++) | 277 | for (i = 0; i < n; i++) |
| 144 | if (val <= als_it_value[i]) | 278 | if (val <= cm32181->als_it_values[i]) |
| 145 | break; | 279 | break; |
| 146 | if (i >= n) | 280 | if (i >= n) |
| 147 | i = n - 1; | 281 | i = n - 1; |
| 148 | 282 | ||
| 149 | als_it = als_it_bits[i]; | 283 | als_it = cm32181->als_it_bits[i]; |
| 150 | als_it <<= CM32181_CMD_ALS_IT_SHIFT; | 284 | als_it <<= CM32181_CMD_ALS_IT_SHIFT; |
| 151 | 285 | ||
| 152 | mutex_lock(&cm32181->lock); | 286 | mutex_lock(&cm32181->lock); |
| @@ -175,15 +309,15 @@ static int cm32181_get_lux(struct cm32181_chip *cm32181) · 22 unmodified lines | |||
| 175 | struct i2c_client *client = cm32181->client; | 309 | struct i2c_client *client = cm32181->client; |
| 176 | int ret; | 310 | int ret; |
| 177 | int als_it; | 311 | int als_it; |
| 178 | unsigned long lux; | 312 | u64 lux; |
| 179 | 313 | ||
| 180 | ret = cm32181_read_als_it(cm32181, &als_it); | 314 | ret = cm32181_read_als_it(cm32181, &als_it); |
| 181 | if (ret < 0) | 315 | if (ret < 0) |
| 182 | return -EINVAL; | 316 | return -EINVAL; |
| 183 | 317 | ||
| 184 | lux = CM32181_MLUX_PER_BIT; | 318 | lux = cm32181->lux_per_bit; |
| 185 | lux *= CM32181_MLUX_PER_BIT_BASE_IT; | 319 | lux *= cm32181->lux_per_bit_base_it; |
| 186 | lux /= als_it; | 320 | lux = div_u64(lux, als_it); |
| 187 | 321 | ||
| 188 | ret = i2c_smbus_read_word_data(client, CM32181_REG_ADDR_ALS); | 322 | ret = i2c_smbus_read_word_data(client, CM32181_REG_ADDR_ALS); |
| 189 | if (ret < 0) | 323 | if (ret < 0) |
| @@ -191,8 +325,8 @@ static int cm32181_get_lux(struct cm32181_chip *cm32181) · 1 unmodified line | |||
| 191 | 325 | ||
| 192 | lux *= ret; | 326 | lux *= ret; |
| 193 | lux *= cm32181->calibscale; | 327 | lux *= cm32181->calibscale; |
| 194 | lux /= CM32181_CALIBSCALE_RESOLUTION; | 328 | lux = div_u64(lux, CM32181_CALIBSCALE_RESOLUTION); |
| 195 | lux /= MLUX_PER_LUX; | 329 | lux = div_u64(lux, CM32181_LUX_PER_BIT_RESOLUTION); |
| 196 | 330 | ||
| 197 | if (lux > 0xFFFF) | 331 | if (lux > 0xFFFF) |
| 198 | lux = 0xFFFF; | 332 | lux = 0xFFFF; |
| @@ -258,11 +392,12 @@ static int cm32181_write_raw(struct iio_dev *indio_dev, · 59 unmodified lines | |||
| 258 | static ssize_t cm32181_get_it_available(struct device *dev, | 392 | static ssize_t cm32181_get_it_available(struct device *dev, |
| 259 | struct device_attribute *attr, char *buf) | 393 | struct device_attribute *attr, char *buf) |
| 260 | { | 394 | { |
| 395 | struct cm32181_chip *cm32181 = iio_priv(dev_to_iio_dev(dev)); | ||
| 261 | int i, n, len; | 396 | int i, n, len; |
| 262 | 397 | ||
| 263 | n = ARRAY_SIZE(als_it_value); | 398 | n = cm32181->num_als_it; |
| 264 | for (i = 0, len = 0; i < n; i++) | 399 | for (i = 0, len = 0; i < n; i++) |
| 265 | len += sprintf(buf + len, "0.%06u ", als_it_value[i]); | 400 | len += sprintf(buf + len, "0.%06u ", cm32181->als_it_values[i]); |
| 266 | return len + sprintf(buf + len, "\n"); | 401 | return len + sprintf(buf + len, "\n"); |
| 267 | } | 402 | } |
| 268 | 403 | ||
| @@ -294,70 +429,86 @@ static const struct iio_info cm32181_info = { · 25 unmodified lines | |||
| 294 | .attrs = &cm32181_attribute_group, | 429 | .attrs = &cm32181_attribute_group, |
| 295 | }; | 430 | }; |
| 296 | 431 | ||
| 297 | static int cm32181_probe(struct i2c_client *client, | 432 | static int cm32181_probe(struct i2c_client *client) |
| 298 | const struct i2c_device_id *id) | ||
| 299 | { | 433 | { |
| 434 | struct device *dev = &client->dev; | ||
| 300 | struct cm32181_chip *cm32181; | 435 | struct cm32181_chip *cm32181; |
| 301 | struct iio_dev *indio_dev; | 436 | struct iio_dev *indio_dev; |
| 302 | int ret; | 437 | int ret; |
| 303 | 438 | ||
| 304 | indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*cm32181)); | 439 | indio_dev = devm_iio_device_alloc(dev, sizeof(*cm32181)); |
| 305 | if (!indio_dev) { | 440 | if (!indio_dev) |
| 306 | dev_err(&client->dev, "devm_iio_device_alloc failed\n"); | ||
| 307 | return -ENOMEM; | 441 | return -ENOMEM; |
| 442 | |||
| 443 | /* | ||
| 444 | * Some ACPI systems list 2 I2C resources for the CM3218 sensor, the | ||
| 445 | * SMBus Alert Response Address (ARA, 0x0c) and the actual I2C address. | ||
| 446 | * Detect this and take the following step to deal with it: | ||
| 447 | * 1. When a SMBus Alert capable sensor has an Alert asserted, it will | ||
| 448 | * not respond on its actual I2C address. Read a byte from the ARA | ||
| 449 | * to clear any pending Alerts. | ||
| 450 | * 2. Create a "dummy" client for the actual I2C address and | ||
| 451 | * use that client to communicate with the sensor. | ||
| 452 | */ | ||
| 453 | if (ACPI_HANDLE(dev) && client->addr == SMBUS_ALERT_RESPONSE_ADDRESS) { | ||
| 454 | struct i2c_board_info board_info = { .type = "dummy" }; | ||
| 455 | |||
| 456 | i2c_smbus_read_byte(client); | ||
| 457 | |||
| 458 | client = i2c_acpi_new_device(dev, 1, &board_info); | ||
| 459 | if (IS_ERR(client)) | ||
| 460 | return PTR_ERR(client); | ||
| 308 | } | 461 | } |
| 309 | 462 | ||
| 310 | cm32181 = iio_priv(indio_dev); | 463 | cm32181 = iio_priv(indio_dev); |
| 311 | i2c_set_clientdata(client, indio_dev); | ||
| 312 | cm32181->client = client; | 464 | cm32181->client = client; |
| 465 | cm32181->dev = dev; | ||
| 313 | 466 | ||
| 314 | mutex_init(&cm32181->lock); | 467 | mutex_init(&cm32181->lock); |
| 315 | indio_dev->dev.parent = &client->dev; | 468 | indio_dev->dev.parent = dev; |
| 316 | indio_dev->channels = cm32181_channels; | 469 | indio_dev->channels = cm32181_channels; |
| 317 | indio_dev->num_channels = ARRAY_SIZE(cm32181_channels); | 470 | indio_dev->num_channels = ARRAY_SIZE(cm32181_channels); |
| 318 | indio_dev->info = &cm32181_info; | 471 | indio_dev->info = &cm32181_info; |
| 319 | indio_dev->name = id->name; | 472 | indio_dev->name = dev_name(dev); |
| 320 | indio_dev->modes = INDIO_DIRECT_MODE; | 473 | indio_dev->modes = INDIO_DIRECT_MODE; |
| 321 | 474 | ||
| 322 | ret = cm32181_reg_init(cm32181); | 475 | ret = cm32181_reg_init(cm32181); |
| 323 | if (ret) { | 476 | if (ret) { |
| 324 | dev_err(&client->dev, | 477 | dev_err(dev, "%s: register init failed\n", __func__); |
| 325 | "%s: register init failed\n", | ||
| 326 | __func__); | ||
| 327 | return ret; | 478 | return ret; |
| 328 | } | 479 | } |
| 329 | 480 | ||
| 330 | ret = devm_iio_device_register(&client->dev, indio_dev); | 481 | ret = devm_iio_device_register(dev, indio_dev); |
| 331 | if (ret) { | 482 | if (ret) { |
| 332 | dev_err(&client->dev, | 483 | dev_err(dev, "%s: regist device failed\n", __func__); |
| 333 | "%s: regist device failed\n", | ||
| 334 | __func__); | ||
| 335 | return ret; | 484 | return ret; |
| 336 | } | 485 | } |
| 337 | 486 | ||
| 338 | return 0; | 487 | return 0; |
| 339 | } | 488 | } |
| 340 | 489 | ||
| 341 | static const struct i2c_device_id cm32181_id[] = { | ||
| 342 | { "cm32181", 0 }, | ||
| 343 | { } | ||
| 344 | }; | ||
| 345 | |||
| 346 | MODULE_DEVICE_TABLE(i2c, cm32181_id); | ||
| 347 | |||
| 348 | static const struct of_device_id cm32181_of_match[] = { | 490 | static const struct of_device_id cm32181_of_match[] = { |
| 491 | { .compatible = "capella,cm3218" }, | ||
| 349 | { .compatible = "capella,cm32181" }, | 492 | { .compatible = "capella,cm32181" }, |
| 350 | { } | 493 | { } |
| 351 | }; | 494 | }; |
| 352 | MODULE_DEVICE_TABLE(of, cm32181_of_match); | 495 | MODULE_DEVICE_TABLE(of, cm32181_of_match); |
| 353 | 496 | ||
| 497 | #ifdef CONFIG_ACPI | ||
| 498 | static const struct acpi_device_id cm32181_acpi_match[] = { | ||
| 499 | { "CPLM3218", 0 }, | ||
| 500 | { } | ||
| 501 | }; | ||
| 502 | MODULE_DEVICE_TABLE(acpi, cm32181_acpi_match); | ||
| 503 | #endif | ||
| 504 | |||
| 354 | static struct i2c_driver cm32181_driver = { | 505 | static struct i2c_driver cm32181_driver = { |
| 355 | .driver = { | 506 | .driver = { |
| 356 | .name = "cm32181", | 507 | .name = "cm32181", |
| 357 | .of_match_table = of_match_ptr(cm32181_of_match), | 508 | .acpi_match_table = ACPI_PTR(cm32181_acpi_match), |
| 509 | .of_match_table = cm32181_of_match, | ||
| 358 | }, | 510 | }, |
| 359 | .id_table = cm32181_id, | 511 | .probe_new = cm32181_probe, |
| 360 | .probe = cm32181_probe, | ||
| 361 | }; | 512 | }; |
| 362 | 513 | ||
| 363 | module_i2c_driver(cm32181_driver); | 514 | module_i2c_driver(cm32181_driver); |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | |||
| 10 | 10 | ||
| 11 | #include <linux/i2c.h> | 11 | #include <linux/i2c.h> |
| 12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
| 13 | #include <linux/mod_devicetable.h> | ||
| 13 | #include <linux/iio/iio.h> | 14 | #include <linux/iio/iio.h> |
| 14 | #include <linux/iio/sysfs.h> | 15 | #include <linux/iio/sysfs.h> |
| 15 | #include <linux/init.h> | 16 | #include <linux/init.h> |
| @@ -418,7 +419,7 @@ MODULE_DEVICE_TABLE(of, cm3232_of_match); · 402 unmodified lines | |||
| 418 | static struct i2c_driver cm3232_driver = { | 419 | static struct i2c_driver cm3232_driver = { |
| 419 | .driver = { | 420 | .driver = { |
| 420 | .name = "cm3232", | 421 | .name = "cm3232", |
| 421 | .of_match_table = of_match_ptr(cm3232_of_match), | 422 | .of_match_table = cm3232_of_match, |
| 422 | #ifdef CONFIG_PM_SLEEP | 423 | #ifdef CONFIG_PM_SLEEP |
| 423 | .pm = &cm3232_pm_ops, | 424 | .pm = &cm3232_pm_ops, |
| 424 | #endif | 425 | #endif |
| @@ -38,8 +38,8 @@ · 37 unmodified lines | |||
| 38 | #include <linux/irq.h> | 38 | #include <linux/irq.h> |
| 39 | #include <linux/irq_work.h> | 39 | #include <linux/irq_work.h> |
| 40 | #include <linux/module.h> | 40 | #include <linux/module.h> |
| 41 | #include <linux/mod_devicetable.h> | ||
| 41 | #include <linux/mutex.h> | 42 | #include <linux/mutex.h> |
| 42 | #include <linux/of.h> | ||
| 43 | #include <linux/regmap.h> | 43 | #include <linux/regmap.h> |
| 44 | #include <linux/regulator/consumer.h> | 44 | #include <linux/regulator/consumer.h> |
| 45 | #include <linux/slab.h> | 45 | #include <linux/slab.h> |
| @@ -1617,18 +1617,16 @@ static const struct i2c_device_id gp2ap020a00f_id[] = { · 1571 unmodified lines | |||
| 1617 | 1617 | ||
| 1618 | MODULE_DEVICE_TABLE(i2c, gp2ap020a00f_id); | 1618 | MODULE_DEVICE_TABLE(i2c, gp2ap020a00f_id); |
| 1619 | 1619 | ||
| 1620 | #ifdef CONFIG_OF | ||
| 1621 | static const struct of_device_id gp2ap020a00f_of_match[] = { | 1620 | static const struct of_device_id gp2ap020a00f_of_match[] = { |
| 1622 | { .compatible = "sharp,gp2ap020a00f" }, | 1621 | { .compatible = "sharp,gp2ap020a00f" }, |
| 1623 | { } | 1622 | { } |
| 1624 | }; | 1623 | }; |
| 1625 | MODULE_DEVICE_TABLE(of, gp2ap020a00f_of_match); | 1624 | MODULE_DEVICE_TABLE(of, gp2ap020a00f_of_match); |
| 1626 | #endif | ||
| 1627 | 1625 | ||
| 1628 | static struct i2c_driver gp2ap020a00f_driver = { | 1626 | static struct i2c_driver gp2ap020a00f_driver = { |
| 1629 | .driver = { | 1627 | .driver = { |
| 1630 | .name = GP2A_I2C_NAME, | 1628 | .name = GP2A_I2C_NAME, |
| 1631 | .of_match_table = of_match_ptr(gp2ap020a00f_of_match), | 1629 | .of_match_table = gp2ap020a00f_of_match, |
| 1632 | }, | 1630 | }, |
| 1633 | .probe = gp2ap020a00f_probe, | 1631 | .probe = gp2ap020a00f_probe, |
| 1634 | .remove = gp2ap020a00f_remove, | 1632 | .remove = gp2ap020a00f_remove, |
| @@ -14,8 +14,6 @@ · 13 unmodified lines | |||
| 14 | #include <linux/iio/iio.h> | 14 | #include <linux/iio/iio.h> |
| 15 | #include <linux/iio/sysfs.h> | 15 | #include <linux/iio/sysfs.h> |
| 16 | #include <linux/iio/buffer.h> | 16 | #include <linux/iio/buffer.h> |
| 17 | #include <linux/iio/trigger_consumer.h> | ||
| 18 | #include <linux/iio/triggered_buffer.h> | ||
| 19 | #include "../common/hid-sensors/hid-sensor-trigger.h" | 17 | #include "../common/hid-sensors/hid-sensor-trigger.h" |
| 20 | 18 | ||
| 21 | enum { | 19 | enum { |
| @@ -308,18 +306,13 @@ static int hid_als_probe(struct platform_device *pdev) · 286 unmodified lines | |||
| 308 | indio_dev->name = name; | 306 | indio_dev->name = name; |
| 309 | indio_dev->modes = INDIO_DIRECT_MODE; | 307 | indio_dev->modes = INDIO_DIRECT_MODE; |
| 310 | 308 | ||
| 311 | ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, | ||
| 312 | NULL, NULL); | ||
| 313 | if (ret) { | ||
| 314 | dev_err(&pdev->dev, "failed to initialize trigger buffer\n"); | ||
| 315 | goto error_free_dev_mem; | ||
| 316 | } | ||
| 317 | atomic_set(&als_state->common_attributes.data_ready, 0); | 309 | atomic_set(&als_state->common_attributes.data_ready, 0); |
| 310 | |||
| 318 | ret = hid_sensor_setup_trigger(indio_dev, name, | 311 | ret = hid_sensor_setup_trigger(indio_dev, name, |
| 319 | &als_state->common_attributes); | 312 | &als_state->common_attributes); |
| 320 | if (ret < 0) { | 313 | if (ret < 0) { |
| 321 | dev_err(&pdev->dev, "trigger setup failed\n"); | 314 | dev_err(&pdev->dev, "trigger setup failed\n"); |
| 322 | goto error_unreg_buffer_funcs; | 315 | goto error_free_dev_mem; |
| 323 | } | 316 | } |
| 324 | 317 | ||
| 325 | ret = iio_device_register(indio_dev); | 318 | ret = iio_device_register(indio_dev); |
| @@ -343,9 +336,7 @@ static int hid_als_probe(struct platform_device *pdev) · 17 unmodified lines | |||
| 343 | error_iio_unreg: | 336 | error_iio_unreg: |
| 344 | iio_device_unregister(indio_dev); | 337 | iio_device_unregister(indio_dev); |
| 345 | error_remove_trigger: | 338 | error_remove_trigger: |
| 346 | hid_sensor_remove_trigger(&als_state->common_attributes); | 339 | hid_sensor_remove_trigger(indio_dev, &als_state->common_attributes); |
| 347 | error_unreg_buffer_funcs: | ||
| 348 | iio_triggered_buffer_cleanup(indio_dev); | ||
| 349 | error_free_dev_mem: | 340 | error_free_dev_mem: |
| 350 | kfree(indio_dev->channels); | 341 | kfree(indio_dev->channels); |
| 351 | return ret; | 342 | return ret; |
| @@ -360,8 +351,7 @@ static int hid_als_remove(struct platform_device *pdev) · 8 unmodified lines | |||
| 360 | 351 | ||
| 361 | sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_ALS); | 352 | sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_ALS); |
| 362 | iio_device_unregister(indio_dev); | 353 | iio_device_unregister(indio_dev); |
| 363 | hid_sensor_remove_trigger(&als_state->common_attributes); | 354 | hid_sensor_remove_trigger(indio_dev, &als_state->common_attributes); |
| 364 | iio_triggered_buffer_cleanup(indio_dev); | ||
| 365 | kfree(indio_dev->channels); | 355 | kfree(indio_dev->channels); |
| 366 | 356 | ||
| 367 | return 0; | 357 | return 0; |
| @@ -14,8 +14,6 @@ · 13 unmodified lines | |||
| 14 | #include <linux/iio/iio.h> | 14 | #include <linux/iio/iio.h> |
| 15 | #include <linux/iio/sysfs.h> | 15 | #include <linux/iio/sysfs.h> |
| 16 | #include <linux/iio/buffer.h> | 16 | #include <linux/iio/buffer.h> |
| 17 | #include <linux/iio/trigger_consumer.h> | ||
| 18 | #include <linux/iio/triggered_buffer.h> | ||
| 19 | #include "../common/hid-sensors/hid-sensor-trigger.h" | 17 | #include "../common/hid-sensors/hid-sensor-trigger.h" |
| 20 | 18 | ||
| 21 | #define CHANNEL_SCAN_INDEX_PRESENCE 0 | 19 | #define CHANNEL_SCAN_INDEX_PRESENCE 0 |
| @@ -286,18 +284,13 @@ static int hid_prox_probe(struct platform_device *pdev) · 264 unmodified lines | |||
| 286 | indio_dev->name = name; | 284 | indio_dev->name = name; |
| 287 | indio_dev->modes = INDIO_DIRECT_MODE; | 285 | indio_dev->modes = INDIO_DIRECT_MODE; |
| 288 | 286 | ||
| 289 | ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, | ||
| 290 | NULL, NULL); | ||
| 291 | if (ret) { | ||
| 292 | dev_err(&pdev->dev, "failed to initialize trigger buffer\n"); | ||
| 293 | goto error_free_dev_mem; | ||
| 294 | } | ||
| 295 | atomic_set(&prox_state->common_attributes.data_ready, 0); | 287 | atomic_set(&prox_state->common_attributes.data_ready, 0); |
| 288 | |||
| 296 | ret = hid_sensor_setup_trigger(indio_dev, name, | 289 | ret = hid_sensor_setup_trigger(indio_dev, name, |
| 297 | &prox_state->common_attributes); | 290 | &prox_state->common_attributes); |
| 298 | if (ret) { | 291 | if (ret) { |
| 299 | dev_err(&pdev->dev, "trigger setup failed\n"); | 292 | dev_err(&pdev->dev, "trigger setup failed\n"); |
| 300 | goto error_unreg_buffer_funcs; | 293 | goto error_free_dev_mem; |
| 301 | } | 294 | } |
| 302 | 295 | ||
| 303 | ret = iio_device_register(indio_dev); | 296 | ret = iio_device_register(indio_dev); |
| @@ -321,9 +314,7 @@ static int hid_prox_probe(struct platform_device *pdev) · 17 unmodified lines | |||
| 321 | error_iio_unreg: | 314 | error_iio_unreg: |
| 322 | iio_device_unregister(indio_dev); | 315 | iio_device_unregister(indio_dev); |
| 323 | error_remove_trigger: | 316 | error_remove_trigger: |
| 324 | hid_sensor_remove_trigger(&prox_state->common_attributes); | 317 | hid_sensor_remove_trigger(indio_dev, &prox_state->common_attributes); |
| 325 | error_unreg_buffer_funcs: | ||
| 326 | iio_triggered_buffer_cleanup(indio_dev); | ||
| 327 | error_free_dev_mem: | 318 | error_free_dev_mem: |
| 328 | kfree(indio_dev->channels); | 319 | kfree(indio_dev->channels); |
| 329 | return ret; | 320 | return ret; |
| @@ -338,8 +329,7 @@ static int hid_prox_remove(struct platform_device *pdev) · 8 unmodified lines | |||
| 338 | 329 | ||
| 339 | sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_PROX); | 330 | sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_PROX); |
| 340 | iio_device_unregister(indio_dev); | 331 | iio_device_unregister(indio_dev); |
| 341 | hid_sensor_remove_trigger(&prox_state->common_attributes); | 332 | hid_sensor_remove_trigger(indio_dev, &prox_state->common_attributes); |
| 342 | iio_triggered_buffer_cleanup(indio_dev); | ||
| 343 | kfree(indio_dev->channels); | 333 | kfree(indio_dev->channels); |
| 344 | 334 | ||
| 345 | return 0; | 335 | return 0; |
| @@ -101,12 +101,12 @@ struct ltr501_gain { · 100 unmodified lines | |||
| 101 | int uscale; | 101 | int uscale; |
| 102 | }; | 102 | }; |
| 103 | 103 | ||
| 104 | static struct ltr501_gain ltr501_als_gain_tbl[] = { | 104 | static const struct ltr501_gain ltr501_als_gain_tbl[] = { |
| 105 | {1, 0}, | 105 | {1, 0}, |
| 106 | {0, 5000}, | 106 | {0, 5000}, |
| 107 | }; | 107 | }; |
| 108 | 108 | ||
| 109 | static struct ltr501_gain ltr559_als_gain_tbl[] = { | 109 | static const struct ltr501_gain ltr559_als_gain_tbl[] = { |
| 110 | {1, 0}, | 110 | {1, 0}, |
| 111 | {0, 500000}, | 111 | {0, 500000}, |
| 112 | {0, 250000}, | 112 | {0, 250000}, |
| @@ -117,14 +117,14 @@ static struct ltr501_gain ltr559_als_gain_tbl[] = { · 4 unmodified lines | |||
| 117 | {0, 10000}, | 117 | {0, 10000}, |
| 118 | }; | 118 | }; |
| 119 | 119 | ||
| 120 | static struct ltr501_gain ltr501_ps_gain_tbl[] = { | 120 | static const struct ltr501_gain ltr501_ps_gain_tbl[] = { |
| 121 | {1, 0}, | 121 | {1, 0}, |
| 122 | {0, 250000}, | 122 | {0, 250000}, |
| 123 | {0, 125000}, | 123 | {0, 125000}, |
| 124 | {0, 62500}, | 124 | {0, 62500}, |
| 125 | }; | 125 | }; |
| 126 | 126 | ||
| 127 | static struct ltr501_gain ltr559_ps_gain_tbl[] = { | 127 | static const struct ltr501_gain ltr559_ps_gain_tbl[] = { |
| 128 | {0, 62500}, /* x16 gain */ | 128 | {0, 62500}, /* x16 gain */ |
| 129 | {0, 31250}, /* x32 gain */ | 129 | {0, 31250}, /* x32 gain */ |
| 130 | {0, 15625}, /* bits X1 are for x64 gain */ | 130 | {0, 15625}, /* bits X1 are for x64 gain */ |
| @@ -133,9 +133,9 @@ static struct ltr501_gain ltr559_ps_gain_tbl[] = { · 2 unmodified lines | |||
| 133 | 133 | ||
| 134 | struct ltr501_chip_info { | 134 | struct ltr501_chip_info { |
| 135 | u8 partid; | 135 | u8 partid; |
| 136 | struct ltr501_gain *als_gain; | 136 | const struct ltr501_gain *als_gain; |
| 137 | int als_gain_tbl_size; | 137 | int als_gain_tbl_size; |
| 138 | struct ltr501_gain *ps_gain; | 138 | const struct ltr501_gain *ps_gain; |
| 139 | int ps_gain_tbl_size; | 139 | int ps_gain_tbl_size; |
| 140 | u8 als_mode_active; | 140 | u8 als_mode_active; |
| 141 | u8 als_gain_mask; | 141 | u8 als_gain_mask; |
| @@ -192,7 +192,7 @@ static int ltr501_match_samp_freq(const struct ltr501_samp_table *tab, · 50 unmodified lines | |||
| 192 | return -EINVAL; | 192 | return -EINVAL; |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | static int ltr501_als_read_samp_freq(struct ltr501_data *data, | 195 | static int ltr501_als_read_samp_freq(const struct ltr501_data *data, |
| 196 | int *val, int *val2) | 196 | int *val, int *val2) |
| 197 | { | 197 | { |
| 198 | int ret, i; | 198 | int ret, i; |
| @@ -210,7 +210,7 @@ static int ltr501_als_read_samp_freq(struct ltr501_data *data, · 11 unmodified lines | |||
| 210 | return IIO_VAL_INT_PLUS_MICRO; | 210 | return IIO_VAL_INT_PLUS_MICRO; |
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | static int ltr501_ps_read_samp_freq(struct ltr501_data *data, | 213 | static int ltr501_ps_read_samp_freq(const struct ltr501_data *data, |
| 214 | int *val, int *val2) | 214 | int *val, int *val2) |
| 215 | { | 215 | { |
| 216 | int ret, i; | 216 | int ret, i; |
| @@ -266,7 +266,7 @@ static int ltr501_ps_write_samp_freq(struct ltr501_data *data, · 49 unmodified lines | |||
| 266 | return ret; | 266 | return ret; |
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | static int ltr501_als_read_samp_period(struct ltr501_data *data, int *val) | 269 | static int ltr501_als_read_samp_period(const struct ltr501_data *data, int *val) |
| 270 | { | 270 | { |
| 271 | int ret, i; | 271 | int ret, i; |
| 272 | 272 | ||
| @@ -282,7 +282,7 @@ static int ltr501_als_read_samp_period(struct ltr501_data *data, int *val) · 9 unmodified lines | |||
| 282 | return IIO_VAL_INT; | 282 | return IIO_VAL_INT; |
| 283 | } | 283 | } |
| 284 | 284 | ||
| 285 | static int ltr501_ps_read_samp_period(struct ltr501_data *data, int *val) | 285 | static int ltr501_ps_read_samp_period(const struct ltr501_data *data, int *val) |
| 286 | { | 286 | { |
| 287 | int ret, i; | 287 | int ret, i; |
| 288 | 288 | ||
| @@ -321,7 +321,7 @@ static unsigned long ltr501_calculate_lux(u16 vis_data, u16 ir_data) · 32 unmodified lines | |||
| 321 | return lux / 1000; | 321 | return lux / 1000; |
| 322 | } | 322 | } |
| 323 | 323 | ||
| 324 | static int ltr501_drdy(struct ltr501_data *data, u8 drdy_mask) | 324 | static int ltr501_drdy(const struct ltr501_data *data, u8 drdy_mask) |
| 325 | { | 325 | { |
| 326 | int tries = 100; | 326 | int tries = 100; |
| 327 | int ret, status; | 327 | int ret, status; |
| @@ -373,7 +373,8 @@ static int ltr501_set_it_time(struct ltr501_data *data, int it) · 45 unmodified lines | |||
| 373 | } | 373 | } |
| 374 | 374 | ||
| 375 | /* read int time in micro seconds */ | 375 | /* read int time in micro seconds */ |
| 376 | static int ltr501_read_it_time(struct ltr501_data *data, int *val, int *val2) | 376 | static int ltr501_read_it_time(const struct ltr501_data *data, |
| 377 | int *val, int *val2) | ||
| 377 | { | 378 | { |
| 378 | int ret, index; | 379 | int ret, index; |
| 379 | 380 | ||
| @@ -391,7 +392,7 @@ static int ltr501_read_it_time(struct ltr501_data *data, int *val, int *val2) · 11 unmodified lines | |||
| 391 | return IIO_VAL_INT_PLUS_MICRO; | 392 | return IIO_VAL_INT_PLUS_MICRO; |
| 392 | } | 393 | } |
| 393 | 394 | ||
| 394 | static int ltr501_read_als(struct ltr501_data *data, __le16 buf[2]) | 395 | static int ltr501_read_als(const struct ltr501_data *data, __le16 buf[2]) |
| 395 | { | 396 | { |
| 396 | int ret; | 397 | int ret; |
| 397 | 398 | ||
| @@ -403,7 +404,7 @@ static int ltr501_read_als(struct ltr501_data *data, __le16 buf[2]) · 5 unmodified lines | |||
| 403 | buf, 2 * sizeof(__le16)); | 404 | buf, 2 * sizeof(__le16)); |
| 404 | } | 405 | } |
| 405 | 406 | ||
| 406 | static int ltr501_read_ps(struct ltr501_data *data) | 407 | static int ltr501_read_ps(const struct ltr501_data *data) |
| 407 | { | 408 | { |
| 408 | int ret, status; | 409 | int ret, status; |
| 409 | 410 | ||
| @@ -419,7 +420,7 @@ static int ltr501_read_ps(struct ltr501_data *data) · 9 unmodified lines | |||
| 419 | return status; | 420 | return status; |
| 420 | } | 421 | } |
| 421 | 422 | ||
| 422 | static int ltr501_read_intr_prst(struct ltr501_data *data, | 423 | static int ltr501_read_intr_prst(const struct ltr501_data *data, |
| 423 | enum iio_chan_type type, | 424 | enum iio_chan_type type, |
| 424 | int *val2) | 425 | int *val2) |
| 425 | { | 426 | { |
| @@ -716,7 +717,7 @@ static int ltr501_read_raw(struct iio_dev *indio_dev, · 290 unmodified lines | |||
| 716 | return -EINVAL; | 717 | return -EINVAL; |
| 717 | } | 718 | } |
| 718 | 719 | ||
| 719 | static int ltr501_get_gain_index(struct ltr501_gain *gain, int size, | 720 | static int ltr501_get_gain_index(const struct ltr501_gain *gain, int size, |
| 720 | int val, int val2) | 721 | int val, int val2) |
| 721 | { | 722 | { |
| 722 | int i; | 723 | int i; |
| @@ -848,14 +849,14 @@ static int ltr501_write_raw(struct iio_dev *indio_dev, · 125 unmodified lines | |||
| 848 | return ret; | 849 | return ret; |
| 849 | } | 850 | } |
| 850 | 851 | ||
| 851 | static int ltr501_read_thresh(struct iio_dev *indio_dev, | 852 | static int ltr501_read_thresh(const struct iio_dev *indio_dev, |
| 852 | const struct iio_chan_spec *chan, | 853 | const struct iio_chan_spec *chan, |
| 853 | enum iio_event_type type, | 854 | enum iio_event_type type, |
| 854 | enum iio_event_direction dir, | 855 | enum iio_event_direction dir, |
| 855 | enum iio_event_info info, | 856 | enum iio_event_info info, |
| 856 | int *val, int *val2) | 857 | int *val, int *val2) |
| 857 | { | 858 | { |
| 858 | struct ltr501_data *data = iio_priv(indio_dev); | 859 | const struct ltr501_data *data = iio_priv(indio_dev); |
| 859 | int ret, thresh_data; | 860 | int ret, thresh_data; |
| 860 | 861 | ||
| 861 | switch (chan->type) { | 862 | switch (chan->type) { |
| @@ -1359,7 +1360,7 @@ static bool ltr501_is_volatile_reg(struct device *dev, unsigned int reg) · 497 unmodified lines | |||
| 1359 | } | 1360 | } |
| 1360 | } | 1361 | } |
| 1361 | 1362 | ||
| 1362 | static struct regmap_config ltr501_regmap_config = { | 1363 | static const struct regmap_config ltr501_regmap_config = { |
| 1363 | .name = LTR501_REGMAP_NAME, | 1364 | .name = LTR501_REGMAP_NAME, |
| 1364 | .reg_bits = 8, | 1365 | .reg_bits = 8, |
| 1365 | .val_bits = 8, | 1366 | .val_bits = 8, |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | |||
| 16 | #include <linux/irq.h> | 16 | #include <linux/irq.h> |
| 17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
| 18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
| 19 | #include <linux/mod_devicetable.h> | ||
| 19 | #include <linux/mutex.h> | 20 | #include <linux/mutex.h> |
| 20 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
| 21 | #include <linux/types.h> | 22 | #include <linux/types.h> |
| @@ -844,7 +845,7 @@ static struct i2c_driver opt3001_driver = { · 822 unmodified lines | |||
| 844 | 845 | ||
| 845 | .driver = { | 846 | .driver = { |
| 846 | .name = "opt3001", | 847 | .name = "opt3001", |
| 847 | .of_match_table = of_match_ptr(opt3001_of_match), | 848 | .of_match_table = opt3001_of_match, |
| 848 | }, | 849 | }, |
| 849 | }; | 850 | }; |
| 850 | 851 | ||
| @@ -17,6 +17,8 @@ · 16 unmodified lines | |||
| 17 | 17 | ||
| 18 | #include <linux/util_macros.h> | 18 | #include <linux/util_macros.h> |
| 19 | 19 | ||
| 20 | #include <asm/unaligned.h> | ||
| 21 | |||
| 20 | #define SI1133_REG_PART_ID 0x00 | 22 | #define SI1133_REG_PART_ID 0x00 |
| 21 | #define SI1133_REG_REV_ID 0x01 | 23 | #define SI1133_REG_REV_ID 0x01 |
| 22 | #define SI1133_REG_MFR_ID 0x02 | 24 | #define SI1133_REG_MFR_ID 0x02 |
| @@ -104,8 +106,6 @@ · 81 unmodified lines | |||
| 104 | #define SI1133_LUX_BUFFER_SIZE 9 | 106 | #define SI1133_LUX_BUFFER_SIZE 9 |
| 105 | #define SI1133_MEASURE_BUFFER_SIZE 3 | 107 | #define SI1133_MEASURE_BUFFER_SIZE 3 |
| 106 | 108 | ||
| 107 | #define SI1133_SIGN_BIT_INDEX 23 | ||
| 108 | |||
| 109 | static const int si1133_scale_available[] = { | 109 | static const int si1133_scale_available[] = { |
| 110 | 1, 2, 4, 8, 16, 32, 64, 128}; | 110 | 1, 2, 4, 8, 16, 32, 64, 128}; |
| 111 | 111 | ||
| @@ -633,8 +633,7 @@ static int si1133_measure(struct si1133_data *data, · 521 unmodified lines | |||
| 633 | if (err) | 633 | if (err) |
| 634 | return err; | 634 | return err; |
| 635 | 635 | ||
| 636 | *val = sign_extend32((buffer[0] << 16) | (buffer[1] << 8) | buffer[2], | 636 | *val = sign_extend32(get_unaligned_be24(&buffer[0]), 23); |
| 637 | SI1133_SIGN_BIT_INDEX); | ||
| 638 | 637 | ||
| 639 | return err; | 638 | return err; |
| 640 | } | 639 | } |
| @@ -723,16 +722,11 @@ static int si1133_get_lux(struct si1133_data *data, int *val) · 82 unmodified lines | |||
| 723 | if (err) | 722 | if (err) |
| 724 | return err; | 723 | return err; |
| 725 | 724 | ||
| 726 | high_vis = | 725 | high_vis = sign_extend32(get_unaligned_be24(&buffer[0]), 23); |
| 727 | sign_extend32((buffer[0] << 16) | (buffer[1] << 8) | buffer[2], | ||
| 728 | SI1133_SIGN_BIT_INDEX); | ||
| 729 | 726 | ||
| 730 | low_vis = | 727 | low_vis = sign_extend32(get_unaligned_be24(&buffer[3]), 23); |
| 731 | sign_extend32((buffer[3] << 16) | (buffer[4] << 8) | buffer[5], | ||
| 732 | SI1133_SIGN_BIT_INDEX); | ||
| 733 | 728 | ||
| 734 | ir = sign_extend32((buffer[6] << 16) | (buffer[7] << 8) | buffer[8], | 729 | ir = sign_extend32(get_unaligned_be24(&buffer[6]), 23); |
| 735 | SI1133_SIGN_BIT_INDEX); | ||
| 736 | 730 | ||
| 737 | if (high_vis > SI1133_ADC_THRESHOLD || ir > SI1133_ADC_THRESHOLD) | 731 | if (high_vis > SI1133_ADC_THRESHOLD || ir > SI1133_ADC_THRESHOLD) |
| 738 | lux = si1133_calc_polynomial(high_vis, ir, | 732 | lux = si1133_calc_polynomial(high_vis, ir, |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | |||
| 9 | 9 | ||
| 10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
| 11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
| 12 | #include <linux/mod_devicetable.h> | ||
| 12 | #include <linux/i2c.h> | 13 | #include <linux/i2c.h> |
| 13 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
| 14 | #include <linux/regmap.h> | 15 | #include <linux/regmap.h> |
| @@ -55,7 +56,7 @@ static struct i2c_driver st_uvis25_driver = { · 40 unmodified lines | |||
| 55 | .driver = { | 56 | .driver = { |
| 56 | .name = "st_uvis25_i2c", | 57 | .name = "st_uvis25_i2c", |
| 57 | .pm = &st_uvis25_pm_ops, | 58 | .pm = &st_uvis25_pm_ops, |
| 58 | .of_match_table = of_match_ptr(st_uvis25_i2c_of_match), | 59 | .of_match_table = st_uvis25_i2c_of_match, |
| 59 | }, | 60 | }, |
| 60 | .probe = st_uvis25_i2c_probe, | 61 | .probe = st_uvis25_i2c_probe, |
| 61 | .id_table = st_uvis25_i2c_id_table, | 62 | .id_table = st_uvis25_i2c_id_table, |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | |||
| 9 | 9 | ||
| 10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
| 11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
| 12 | #include <linux/mod_devicetable.h> | ||
| 12 | #include <linux/spi/spi.h> | 13 | #include <linux/spi/spi.h> |
| 13 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
| 14 | #include <linux/regmap.h> | 15 | #include <linux/regmap.h> |
| @@ -55,7 +56,7 @@ static struct spi_driver st_uvis25_driver = { · 40 unmodified lines | |||
| 55 | .driver = { | 56 | .driver = { |
| 56 | .name = "st_uvis25_spi", | 57 | .name = "st_uvis25_spi", |
| 57 | .pm = &st_uvis25_pm_ops, | 58 | .pm = &st_uvis25_pm_ops, |
| 58 | .of_match_table = of_match_ptr(st_uvis25_spi_of_match), | 59 | .of_match_table = st_uvis25_spi_of_match, |
| 59 | }, | 60 | }, |
| 60 | .probe = st_uvis25_spi_probe, | 61 | .probe = st_uvis25_spi_probe, |
| 61 | .id_table = st_uvis25_spi_id_table, | 62 | .id_table = st_uvis25_spi_id_table, |
| @@ -5,6 +5,7 @@ · 4 unmodified lines | |||
| 5 | * | 5 | * |
| 6 | * Copyright 2012 Peter Meerwald <pmeerw@pmeerw.net> | 6 | * Copyright 2012 Peter Meerwald <pmeerw@pmeerw.net> |
| 7 | * Copyright 2019 Pursim SPC | 7 | * Copyright 2019 Pursim SPC |
| 8 | * Copyright 2020 Mathieu Othacehe <m.othacehe@gmail.com> | ||
| 8 | * | 9 | * |
| 9 | * IIO driver for: | 10 | * IIO driver for: |
| 10 | * VCNL4000/10/20 (7-bit I2C slave address 0x13) | 11 | * VCNL4000/10/20 (7-bit I2C slave address 0x13) |
| @@ -13,9 +14,7 @@ · 2 unmodified lines | |||
| 13 | * | 14 | * |
| 14 | * TODO: | 15 | * TODO: |
| 15 | * allow to adjust IR current | 16 | * allow to adjust IR current |
| 16 | * proximity threshold and event handling | 17 | * interrupts (VCNL4040, VCNL4200) |
| 17 | * periodic ALS/proximity measurement (VCNL4010/20) | ||
| 18 | * interrupts (VCNL4010/20/40, VCNL4200) | ||
| 19 | */ | 18 | */ |
| 20 | 19 | ||
| 21 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| @@ -23,9 +22,15 @@ · 1 unmodified line | |||
| 23 | #include <linux/err.h> | 22 | #include <linux/err.h> |
| 24 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
| 25 | #include <linux/pm_runtime.h> | 24 | #include <linux/pm_runtime.h> |
| 25 | #include <linux/interrupt.h> | ||
| 26 | 26 | ||
| 27 | #include <linux/iio/buffer.h> | ||
| 28 | #include <linux/iio/events.h> | ||
| 27 | #include <linux/iio/iio.h> | 29 | #include <linux/iio/iio.h> |
| 28 | #include <linux/iio/sysfs.h> | 30 | #include <linux/iio/sysfs.h> |
| 31 | #include <linux/iio/trigger.h> | ||
| 32 | #include <linux/iio/trigger_consumer.h> | ||
| 33 | #include <linux/iio/triggered_buffer.h> | ||
| 29 | 34 | ||
| 30 | #define VCNL4000_DRV_NAME "vcnl4000" | 35 | #define VCNL4000_DRV_NAME "vcnl4000" |
| 31 | #define VCNL4000_PROD_ID 0x01 | 36 | #define VCNL4000_PROD_ID 0x01 |
| @@ -35,14 +40,22 @@ · 3 unmodified lines | |||
| 35 | 40 | ||
| 36 | #define VCNL4000_COMMAND 0x80 /* Command register */ | 41 | #define VCNL4000_COMMAND 0x80 /* Command register */ |
| 37 | #define VCNL4000_PROD_REV 0x81 /* Product ID and Revision ID */ | 42 | #define VCNL4000_PROD_REV 0x81 /* Product ID and Revision ID */ |
| 43 | #define VCNL4010_PROX_RATE 0x82 /* Proximity rate */ | ||
| 38 | #define VCNL4000_LED_CURRENT 0x83 /* IR LED current for proximity mode */ | 44 | #define VCNL4000_LED_CURRENT 0x83 /* IR LED current for proximity mode */ |
| 39 | #define VCNL4000_AL_PARAM 0x84 /* Ambient light parameter register */ | 45 | #define VCNL4000_AL_PARAM 0x84 /* Ambient light parameter register */ |
| 46 | #define VCNL4010_ALS_PARAM 0x84 /* ALS rate */ | ||
| 40 | #define VCNL4000_AL_RESULT_HI 0x85 /* Ambient light result register, MSB */ | 47 | #define VCNL4000_AL_RESULT_HI 0x85 /* Ambient light result register, MSB */ |
| 41 | #define VCNL4000_AL_RESULT_LO 0x86 /* Ambient light result register, LSB */ | 48 | #define VCNL4000_AL_RESULT_LO 0x86 /* Ambient light result register, LSB */ |
| 42 | #define VCNL4000_PS_RESULT_HI 0x87 /* Proximity result register, MSB */ | 49 | #define VCNL4000_PS_RESULT_HI 0x87 /* Proximity result register, MSB */ |
| 43 | #define VCNL4000_PS_RESULT_LO 0x88 /* Proximity result register, LSB */ | 50 | #define VCNL4000_PS_RESULT_LO 0x88 /* Proximity result register, LSB */ |
| 44 | #define VCNL4000_PS_MEAS_FREQ 0x89 /* Proximity test signal frequency */ | 51 | #define VCNL4000_PS_MEAS_FREQ 0x89 /* Proximity test signal frequency */ |
| 52 | #define VCNL4010_INT_CTRL 0x89 /* Interrupt control */ | ||
| 45 | #define VCNL4000_PS_MOD_ADJ 0x8a /* Proximity modulator timing adjustment */ | 53 | #define VCNL4000_PS_MOD_ADJ 0x8a /* Proximity modulator timing adjustment */ |
| 54 | #define VCNL4010_LOW_THR_HI 0x8a /* Low threshold, MSB */ | ||
| 55 | #define VCNL4010_LOW_THR_LO 0x8b /* Low threshold, LSB */ | ||
| 56 | #define VCNL4010_HIGH_THR_HI 0x8c /* High threshold, MSB */ | ||
| 57 | #define VCNL4010_HIGH_THR_LO 0x8d /* High threshold, LSB */ | ||
| 58 | #define VCNL4010_ISR 0x8e /* Interrupt status */ | ||
| 46 | 59 | ||
| 47 | #define VCNL4200_AL_CONF 0x00 /* Ambient light configuration */ | 60 | #define VCNL4200_AL_CONF 0x00 /* Ambient light configuration */ |
| 48 | #define VCNL4200_PS_CONF1 0x03 /* Proximity configuration */ | 61 | #define VCNL4200_PS_CONF1 0x03 /* Proximity configuration */ |
| @@ -57,6 +70,36 @@ · 8 unmodified lines | |||
| 57 | #define VCNL4000_PS_RDY BIT(5) /* proximity data ready? */ | 70 | #define VCNL4000_PS_RDY BIT(5) /* proximity data ready? */ |
| 58 | #define VCNL4000_AL_OD BIT(4) /* start on-demand ALS measurement */ | 71 | #define VCNL4000_AL_OD BIT(4) /* start on-demand ALS measurement */ |
| 59 | #define VCNL4000_PS_OD BIT(3) /* start on-demand proximity measurement */ | 72 | #define VCNL4000_PS_OD BIT(3) /* start on-demand proximity measurement */ |
| 73 | #define VCNL4000_ALS_EN BIT(2) /* start ALS measurement */ | ||
| 74 | #define VCNL4000_PROX_EN BIT(1) /* start proximity measurement */ | ||
| 75 | #define VCNL4000_SELF_TIMED_EN BIT(0) /* start self-timed measurement */ | ||
| 76 | |||
| 77 | /* Bit masks for interrupt registers. */ | ||
| 78 | #define VCNL4010_INT_THR_SEL BIT(0) /* Select threshold interrupt source */ | ||
| 79 | #define VCNL4010_INT_THR_EN BIT(1) /* Threshold interrupt type */ | ||
| 80 | #define VCNL4010_INT_ALS_EN BIT(2) /* Enable on ALS data ready */ | ||
| 81 | #define VCNL4010_INT_PROX_EN BIT(3) /* Enable on proximity data ready */ | ||
| 82 | |||
| 83 | #define VCNL4010_INT_THR_HIGH 0 /* High threshold exceeded */ | ||
| 84 | #define VCNL4010_INT_THR_LOW 1 /* Low threshold exceeded */ | ||
| 85 | #define VCNL4010_INT_ALS 2 /* ALS data ready */ | ||
| 86 | #define VCNL4010_INT_PROXIMITY 3 /* Proximity data ready */ | ||
| 87 | |||
| 88 | #define VCNL4010_INT_THR \ | ||
| 89 | (BIT(VCNL4010_INT_THR_LOW) | BIT(VCNL4010_INT_THR_HIGH)) | ||
| 90 | #define VCNL4010_INT_DRDY \ | ||
| 91 | (BIT(VCNL4010_INT_PROXIMITY) | BIT(VCNL4010_INT_ALS)) | ||
| 92 | |||
| 93 | static const int vcnl4010_prox_sampling_frequency[][2] = { | ||
| 94 | {1, 950000}, | ||
| 95 | {3, 906250}, | ||
| 96 | {7, 812500}, | ||
| 97 | {16, 625000}, | ||
| 98 | {31, 250000}, | ||
| 99 | {62, 500000}, | ||
| 100 | {125, 0}, | ||
| 101 | {250, 0}, | ||
| 102 | }; | ||
| 60 | 103 | ||
| 61 | #define VCNL4000_SLEEP_DELAY_MS 2000 /* before we enter pm_runtime_suspend */ | 104 | #define VCNL4000_SLEEP_DELAY_MS 2000 /* before we enter pm_runtime_suspend */ |
| 62 | 105 | ||
| @@ -88,6 +131,10 @@ struct vcnl4000_data { · 25 unmodified lines | |||
| 88 | 131 | ||
| 89 | struct vcnl4000_chip_spec { | 132 | struct vcnl4000_chip_spec { |
| 90 | const char *prod; | 133 | const char *prod; |
| 134 | struct iio_chan_spec const *channels; | ||
| 135 | const int num_channels; | ||
| 136 | const struct iio_info *info; | ||
| 137 | bool irq_support; | ||
| 91 | int (*init)(struct vcnl4000_data *data); | 138 | int (*init)(struct vcnl4000_data *data); |
| 92 | int (*measure_light)(struct vcnl4000_data *data, int *val); | 139 | int (*measure_light)(struct vcnl4000_data *data, int *val); |
| 93 | int (*measure_proximity)(struct vcnl4000_data *data, int *val); | 140 | int (*measure_proximity)(struct vcnl4000_data *data, int *val); |
| @@ -216,11 +263,31 @@ static int vcnl4200_init(struct vcnl4000_data *data) · 122 unmodified lines | |||
| 216 | return 0; | 263 | return 0; |
| 217 | }; | 264 | }; |
| 218 | 265 | ||
| 266 | static int vcnl4000_read_data(struct vcnl4000_data *data, u8 data_reg, int *val) | ||
| 267 | { | ||
| 268 | s32 ret; | ||
| 269 | |||
| 270 | ret = i2c_smbus_read_word_swapped(data->client, data_reg); | ||
| 271 | if (ret < 0) | ||
| 272 | return ret; | ||
| 273 | |||
| 274 | *val = ret; | ||
| 275 | return 0; | ||
| 276 | } | ||
| 277 | |||
| 278 | static int vcnl4000_write_data(struct vcnl4000_data *data, u8 data_reg, int val) | ||
| 279 | { | ||
| 280 | if (val > U16_MAX) | ||
| 281 | return -ERANGE; | ||
| 282 | |||
| 283 | return i2c_smbus_write_word_swapped(data->client, data_reg, val); | ||
| 284 | } | ||
| 285 | |||
| 286 | |||
| 219 | static int vcnl4000_measure(struct vcnl4000_data *data, u8 req_mask, | 287 | static int vcnl4000_measure(struct vcnl4000_data *data, u8 req_mask, |
| 220 | u8 rdy_mask, u8 data_reg, int *val) | 288 | u8 rdy_mask, u8 data_reg, int *val) |
| 221 | { | 289 | { |
| 222 | int tries = 20; | 290 | int tries = 20; |
| 223 | __be16 buf; | ||
| 224 | int ret; | 291 | int ret; |
| 225 | 292 | ||
| 226 | mutex_lock(&data->vcnl4000_lock); | 293 | mutex_lock(&data->vcnl4000_lock); |
| @@ -247,13 +314,11 @@ static int vcnl4000_measure(struct vcnl4000_data *data, u8 req_mask, · 20 unmodified lines | |||
| 247 | goto fail; | 314 | goto fail; |
| 248 | } | 315 | } |
| 249 | 316 | ||
| 250 | ret = i2c_smbus_read_i2c_block_data(data->client, | 317 | ret = vcnl4000_read_data(data, data_reg, val); |
| 251 | data_reg, sizeof(buf), (u8 *) &buf); | ||
| 252 | if (ret < 0) | 318 | if (ret < 0) |
| 253 | goto fail; | 319 | goto fail; |
| 254 | 320 | ||
| 255 | mutex_unlock(&data->vcnl4000_lock); | 321 | mutex_unlock(&data->vcnl4000_lock); |
| 256 | *val = be16_to_cpu(buf); | ||
| 257 | 322 | ||
| 258 | return 0; | 323 | return 0; |
| 259 | 324 | ||
| @@ -313,67 +378,34 @@ static int vcnl4200_measure_proximity(struct vcnl4000_data *data, int *val) · 53 unmodified lines | |||
| 313 | return vcnl4200_measure(data, &data->vcnl4200_ps, val); | 378 | return vcnl4200_measure(data, &data->vcnl4200_ps, val); |
| 314 | } | 379 | } |
| 315 | 380 | ||
| 316 | static const struct vcnl4000_chip_spec vcnl4000_chip_spec_cfg[] = { | 381 | static int vcnl4010_read_proxy_samp_freq(struct vcnl4000_data *data, int *val, |
| 317 | [VCNL4000] = { | 382 | int *val2) |
| 318 | .prod = "VCNL4000", | ||
| 319 | .init = vcnl4000_init, | ||
| 320 | .measure_light = vcnl4000_measure_light, | ||
| 321 | .measure_proximity = vcnl4000_measure_proximity, | ||
| 322 | .set_power_state = vcnl4000_set_power_state, | ||
| 323 | }, | ||
| 324 | [VCNL4010] = { | ||
| 325 | .prod = "VCNL4010/4020", | ||
| 326 | .init = vcnl4000_init, | ||
| 327 | .measure_light = vcnl4000_measure_light, | ||
| 328 | .measure_proximity = vcnl4000_measure_proximity, | ||
| 329 | .set_power_state = vcnl4000_set_power_state, | ||
| 330 | }, | ||
| 331 | [VCNL4040] = { | ||
| 332 | .prod = "VCNL4040", | ||
| 333 | .init = vcnl4200_init, | ||
| 334 | .measure_light = vcnl4200_measure_light, | ||
| 335 | .measure_proximity = vcnl4200_measure_proximity, | ||
| 336 | .set_power_state = vcnl4200_set_power_state, | ||
| 337 | }, | ||
| 338 | [VCNL4200] = { | ||
| 339 | .prod = "VCNL4200", | ||
| 340 | .init = vcnl4200_init, | ||
| 341 | .measure_light = vcnl4200_measure_light, | ||
| 342 | .measure_proximity = vcnl4200_measure_proximity, | ||
| 343 | .set_power_state = vcnl4200_set_power_state, | ||
| 344 | }, | ||
| 345 | }; | ||
| 346 | |||
| 347 | static ssize_t vcnl4000_read_near_level(struct iio_dev *indio_dev, | ||
| 348 | uintptr_t priv, | ||
| 349 | const struct iio_chan_spec *chan, | ||
| 350 | char *buf) | ||
| 351 | { | 383 | { |
| 352 | struct vcnl4000_data *data = iio_priv(indio_dev); | 384 | int ret; |
| 353 | 385 | ||
| 354 | return sprintf(buf, "%u\n", data->near_level); | 386 | ret = i2c_smbus_read_byte_data(data->client, VCNL4010_PROX_RATE); |
| 387 | if (ret < 0) | ||
| 388 | return ret; | ||
| 389 | |||
| 390 | if (ret >= ARRAY_SIZE(vcnl4010_prox_sampling_frequency)) | ||
| 391 | return -EINVAL; | ||
| 392 | |||
| 393 | *val = vcnl4010_prox_sampling_frequency[ret][0]; | ||
| 394 | *val2 = vcnl4010_prox_sampling_frequency[ret][1]; | ||
| 395 | |||
| 396 | return 0; | ||
| 355 | } | 397 | } |
| 356 | 398 | ||
| 357 | static const struct iio_chan_spec_ext_info vcnl4000_ext_info[] = { | 399 | static bool vcnl4010_is_in_periodic_mode(struct vcnl4000_data *data) |
| 358 | { | 400 | { |
| 359 | .name = "nearlevel", | 401 | int ret; |
| 360 | .shared = IIO_SEPARATE, | ||
| 361 | .read = vcnl4000_read_near_level, | ||
| 362 | }, | ||
| 363 | { /* sentinel */ } | ||
| 364 | }; | ||
| 365 | 402 | ||
| 366 | static const struct iio_chan_spec vcnl4000_channels[] = { | 403 | ret = i2c_smbus_read_byte_data(data->client, VCNL4000_COMMAND); |
| 367 | { | 404 | if (ret < 0) |
| 368 | .type = IIO_LIGHT, | 405 | return false; |
| 369 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | | 406 | |
| 370 | BIT(IIO_CHAN_INFO_SCALE), | 407 | return !!(ret & VCNL4000_SELF_TIMED_EN); |
| 371 | }, { | 408 | } |
| 372 | .type = IIO_PROXIMITY, | ||
| 373 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), | ||
| 374 | .ext_info = vcnl4000_ext_info, | ||
| 375 | } | ||
| 376 | }; | ||
| 377 | 409 | ||
| 378 | static int vcnl4000_set_pm_runtime_state(struct vcnl4000_data *data, bool on) | 410 | static int vcnl4000_set_pm_runtime_state(struct vcnl4000_data *data, bool on) |
| 379 | { | 411 | { |
| @@ -433,10 +465,571 @@ static int vcnl4000_read_raw(struct iio_dev *indio_dev, · 53 unmodified lines | |||
| 433 | } | 465 | } |
| 434 | } | 466 | } |
| 435 | 467 | ||
| 468 | static int vcnl4010_read_raw(struct iio_dev *indio_dev, | ||
| 469 | struct iio_chan_spec const *chan, | ||
| 470 | int *val, int *val2, long mask) | ||
| 471 | { | ||
| 472 | int ret; | ||
| 473 | struct vcnl4000_data *data = iio_priv(indio_dev); | ||
| 474 | |||
| 475 | switch (mask) { | ||
| 476 | case IIO_CHAN_INFO_RAW: | ||
| 477 | case IIO_CHAN_INFO_SCALE: | ||
| 478 | ret = iio_device_claim_direct_mode(indio_dev); | ||
| 479 | if (ret) | ||
| 480 | return ret; | ||
| 481 | |||
| 482 | /* Protect against event capture. */ | ||
| 483 | if (vcnl4010_is_in_periodic_mode(data)) { | ||
| 484 | ret = -EBUSY; | ||
| 485 | } else { | ||
| 486 | ret = vcnl4000_read_raw(indio_dev, chan, val, val2, | ||
| 487 | mask); | ||
| 488 | } | ||
| 489 | |||
| 490 | iio_device_release_direct_mode(indio_dev); | ||
| 491 | return ret; | ||
| 492 | case IIO_CHAN_INFO_SAMP_FREQ: | ||
| 493 | switch (chan->type) { | ||
| 494 | case IIO_PROXIMITY: | ||
| 495 | ret = vcnl4010_read_proxy_samp_freq(data, val, val2); | ||
| 496 | if (ret < 0) | ||
| 497 | return ret; | ||
| 498 | return IIO_VAL_INT_PLUS_MICRO; | ||
| 499 | default: | ||
| 500 | return -EINVAL; | ||
| 501 | } | ||
| 502 | default: | ||
| 503 | return -EINVAL; | ||
| 504 | } | ||
| 505 | } | ||
| 506 | |||
| 507 | static int vcnl4010_read_avail(struct iio_dev *indio_dev, | ||
| 508 | struct iio_chan_spec const *chan, | ||
| 509 | const int **vals, int *type, int *length, | ||
| 510 | long mask) | ||
| 511 | { | ||
| 512 | switch (mask) { | ||
| 513 | case IIO_CHAN_INFO_SAMP_FREQ: | ||
| 514 | *vals = (int *)vcnl4010_prox_sampling_frequency; | ||
| 515 | *type = IIO_VAL_INT_PLUS_MICRO; | ||
| 516 | *length = 2 * ARRAY_SIZE(vcnl4010_prox_sampling_frequency); | ||
| 517 | return IIO_AVAIL_LIST; | ||
| 518 | default: | ||
| 519 | return -EINVAL; | ||
| 520 | } | ||
| 521 | } | ||
| 522 | |||
| 523 | static int vcnl4010_write_proxy_samp_freq(struct vcnl4000_data *data, int val, | ||
| 524 | int val2) | ||
| 525 | { | ||
| 526 | unsigned int i; | ||
| 527 | int index = -1; | ||
| 528 | |||
| 529 | for (i = 0; i < ARRAY_SIZE(vcnl4010_prox_sampling_frequency); i++) { | ||
| 530 | if (val == vcnl4010_prox_sampling_frequency[i][0] && | ||
| 531 | val2 == vcnl4010_prox_sampling_frequency[i][1]) { | ||
| 532 | index = i; | ||
| 533 | break; | ||
| 534 | } | ||
| 535 | } | ||
| 536 | |||
| 537 | if (index < 0) | ||
| 538 | return -EINVAL; | ||
| 539 | |||
| 540 | return i2c_smbus_write_byte_data(data->client, VCNL4010_PROX_RATE, | ||
| 541 | index); | ||
| 542 | } | ||
| 543 | |||
| 544 | static int vcnl4010_write_raw(struct iio_dev *indio_dev, | ||
| 545 | struct iio_chan_spec const *chan, | ||
| 546 | int val, int val2, long mask) | ||
| 547 | { | ||
| 548 | int ret; | ||
| 549 | struct vcnl4000_data *data = iio_priv(indio_dev); | ||
| 550 | |||
| 551 | ret = iio_device_claim_direct_mode(indio_dev); | ||
| 552 | if (ret) | ||
| 553 | return ret; | ||
| 554 | |||
| 555 | /* Protect against event capture. */ | ||
| 556 | if (vcnl4010_is_in_periodic_mode(data)) { | ||
| 557 | ret = -EBUSY; | ||
| 558 | goto end; | ||
| 559 | } | ||
| 560 | |||
| 561 | switch (mask) { | ||
| 562 | case IIO_CHAN_INFO_SAMP_FREQ: | ||
| 563 | switch (chan->type) { | ||
| 564 | case IIO_PROXIMITY: | ||
| 565 | ret = vcnl4010_write_proxy_samp_freq(data, val, val2); | ||
| 566 | goto end; | ||
| 567 | default: | ||
| 568 | ret = -EINVAL; | ||
| 569 | goto end; | ||
| 570 | } | ||
| 571 | default: | ||
| 572 | ret = -EINVAL; | ||
| 573 | goto end; | ||
| 574 | } | ||
| 575 | |||
| 576 | end: | ||
| 577 | iio_device_release_direct_mode(indio_dev); | ||
| 578 | return ret; | ||
| 579 | } | ||
| 580 | |||
| 581 | static int vcnl4010_read_event(struct iio_dev *indio_dev, | ||
| 582 | const struct iio_chan_spec *chan, | ||
| 583 | enum iio_event_type type, | ||
| 584 | enum iio_event_direction dir, | ||
| 585 | enum iio_event_info info, | ||
| 586 | int *val, int *val2) | ||
| 587 | { | ||
| 588 | int ret; | ||
| 589 | struct vcnl4000_data *data = iio_priv(indio_dev); | ||
| 590 | |||
| 591 | switch (info) { | ||
| 592 | case IIO_EV_INFO_VALUE: | ||
| 593 | switch (dir) { | ||
| 594 | case IIO_EV_DIR_RISING: | ||
| 595 | ret = vcnl4000_read_data(data, VCNL4010_HIGH_THR_HI, | ||
| 596 | val); | ||
| 597 | if (ret < 0) | ||
| 598 | return ret; | ||
| 599 | return IIO_VAL_INT; | ||
| 600 | case IIO_EV_DIR_FALLING: | ||
| 601 | ret = vcnl4000_read_data(data, VCNL4010_LOW_THR_HI, | ||
| 602 | val); | ||
| 603 | if (ret < 0) | ||
| 604 | return ret; | ||
| 605 | return IIO_VAL_INT; | ||
| 606 | default: | ||
| 607 | return -EINVAL; | ||
| 608 | } | ||
| 609 | default: | ||
| 610 | return -EINVAL; | ||
| 611 | } | ||
| 612 | } | ||
| 613 | |||
| 614 | static int vcnl4010_write_event(struct iio_dev *indio_dev, | ||
| 615 | const struct iio_chan_spec *chan, | ||
| 616 | enum iio_event_type type, | ||
| 617 | enum iio_event_direction dir, | ||
| 618 | enum iio_event_info info, | ||
| 619 | int val, int val2) | ||
| 620 | { | ||
| 621 | int ret; | ||
| 622 | struct vcnl4000_data *data = iio_priv(indio_dev); | ||
| 623 | |||
| 624 | switch (info) { | ||
| 625 | case IIO_EV_INFO_VALUE: | ||
| 626 | switch (dir) { | ||
| 627 | case IIO_EV_DIR_RISING: | ||
| 628 | ret = vcnl4000_write_data(data, VCNL4010_HIGH_THR_HI, | ||
| 629 | val); | ||
| 630 | if (ret < 0) | ||
| 631 | return ret; | ||
| 632 | return IIO_VAL_INT; | ||
| 633 | case IIO_EV_DIR_FALLING: | ||
| 634 | ret = vcnl4000_write_data(data, VCNL4010_LOW_THR_HI, | ||
| 635 | val); | ||
| 636 | if (ret < 0) | ||
| 637 | return ret; | ||
| 638 | return IIO_VAL_INT; | ||
| 639 | default: | ||
| 640 | return -EINVAL; | ||
| 641 | } | ||
| 642 | default: | ||
| 643 | return -EINVAL; | ||
| 644 | } | ||
| 645 | } | ||
| 646 | |||
| 647 | static bool vcnl4010_is_thr_enabled(struct vcnl4000_data *data) | ||
| 648 | { | ||
| 649 | int ret; | ||
| 650 | |||
| 651 | ret = i2c_smbus_read_byte_data(data->client, VCNL4010_INT_CTRL); | ||
| 652 | if (ret < 0) | ||
| 653 | return false; | ||
| 654 | |||
| 655 | return !!(ret & VCNL4010_INT_THR_EN); | ||
| 656 | } | ||
| 657 | |||
| 658 | static int vcnl4010_read_event_config(struct iio_dev *indio_dev, | ||
| 659 | const struct iio_chan_spec *chan, | ||
| 660 | enum iio_event_type type, | ||
| 661 | enum iio_event_direction dir) | ||
| 662 | { | ||
| 663 | struct vcnl4000_data *data = iio_priv(indio_dev); | ||
| 664 | |||
| 665 | switch (chan->type) { | ||
| 666 | case IIO_PROXIMITY: | ||
| 667 | return vcnl4010_is_thr_enabled(data); | ||
| 668 | default: | ||
| 669 | return -EINVAL; | ||
| 670 | } | ||
| 671 | } | ||
| 672 | |||
| 673 | static int vcnl4010_config_threshold(struct iio_dev *indio_dev, bool state) | ||
| 674 | { | ||
| 675 | struct vcnl4000_data *data = iio_priv(indio_dev); | ||
| 676 | int ret; | ||
| 677 | int icr; | ||
| 678 | int command; | ||
| 679 | |||
| 680 | if (state) { | ||
| 681 | ret = iio_device_claim_direct_mode(indio_dev); | ||
| 682 | if (ret) | ||
| 683 | return ret; | ||
| 684 | |||
| 685 | /* Enable periodic measurement of proximity data. */ | ||
| 686 | command = VCNL4000_SELF_TIMED_EN | VCNL4000_PROX_EN; | ||
| 687 | |||
| 688 | /* | ||
| 689 | * Enable interrupts on threshold, for proximity data by | ||
| 690 | * default. | ||
| 691 | */ | ||
| 692 | icr = VCNL4010_INT_THR_EN; | ||
| 693 | } else { | ||
| 694 | if (!vcnl4010_is_thr_enabled(data)) | ||
| 695 | return 0; | ||
| 696 | |||
| 697 | command = 0; | ||
| 698 | icr = 0; | ||
| 699 | } | ||
| 700 | |||
| 701 | ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, | ||
| 702 | command); | ||
| 703 | if (ret < 0) | ||
| 704 | goto end; | ||
| 705 | |||
| 706 | ret = i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL, icr); | ||
| 707 | |||
| 708 | end: | ||
| 709 | if (state) | ||
| 710 | iio_device_release_direct_mode(indio_dev); | ||
| 711 | |||
| 712 | return ret; | ||
| 713 | } | ||
| 714 | |||
| 715 | static int vcnl4010_write_event_config(struct iio_dev *indio_dev, | ||
| 716 | const struct iio_chan_spec *chan, | ||
| 717 | enum iio_event_type type, | ||
| 718 | enum iio_event_direction dir, | ||
| 719 | int state) | ||
| 720 | { | ||
| 721 | switch (chan->type) { | ||
| 722 | case IIO_PROXIMITY: | ||
| 723 | return vcnl4010_config_threshold(indio_dev, state); | ||
| 724 | default: | ||
| 725 | return -EINVAL; | ||
| 726 | } | ||
| 727 | } | ||
| 728 | |||
| 729 | static ssize_t vcnl4000_read_near_level(struct iio_dev *indio_dev, | ||
| 730 | uintptr_t priv, | ||
| 731 | const struct iio_chan_spec *chan, | ||
| 732 | char *buf) | ||
| 733 | { | ||
| 734 | struct vcnl4000_data *data = iio_priv(indio_dev); | ||
| 735 | |||
| 736 | return sprintf(buf, "%u\n", data->near_level); | ||
| 737 | } | ||
| 738 | |||
| 739 | static const struct iio_chan_spec_ext_info vcnl4000_ext_info[] = { | ||
| 740 | { | ||
| 741 | .name = "nearlevel", | ||
| 742 | .shared = IIO_SEPARATE, | ||
| 743 | .read = vcnl4000_read_near_level, | ||
| 744 | }, | ||
| 745 | { /* sentinel */ } | ||
| 746 | }; | ||
| 747 | |||
| 748 | static const struct iio_event_spec vcnl4000_event_spec[] = { | ||
| 749 | { | ||
| 750 | .type = IIO_EV_TYPE_THRESH, | ||
| 751 | .dir = IIO_EV_DIR_RISING, | ||
| 752 | .mask_separate = BIT(IIO_EV_INFO_VALUE), | ||
| 753 | }, { | ||
| 754 | .type = IIO_EV_TYPE_THRESH, | ||
| 755 | .dir = IIO_EV_DIR_FALLING, | ||
| 756 | .mask_separate = BIT(IIO_EV_INFO_VALUE), | ||
| 757 | }, { | ||
| 758 | .type = IIO_EV_TYPE_THRESH, | ||
| 759 | .dir = IIO_EV_DIR_EITHER, | ||
| 760 | .mask_separate = BIT(IIO_EV_INFO_ENABLE), | ||
| 761 | } | ||
| 762 | }; | ||
| 763 | |||
| 764 | static const struct iio_chan_spec vcnl4000_channels[] = { | ||
| 765 | { | ||
| 766 | .type = IIO_LIGHT, | ||
| 767 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | | ||
| 768 | BIT(IIO_CHAN_INFO_SCALE), | ||
| 769 | }, { | ||
| 770 | .type = IIO_PROXIMITY, | ||
| 771 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), | ||
| 772 | .ext_info = vcnl4000_ext_info, | ||
| 773 | } | ||
| 774 | }; | ||
| 775 | |||
| 776 | static const struct iio_chan_spec vcnl4010_channels[] = { | ||
| 777 | { | ||
| 778 | .type = IIO_LIGHT, | ||
| 779 | .scan_index = -1, | ||
| 780 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | | ||
| 781 | BIT(IIO_CHAN_INFO_SCALE), | ||
| 782 | }, { | ||
| 783 | .type = IIO_PROXIMITY, | ||
| 784 | .scan_index = 0, | ||
| 785 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | | ||
| 786 | BIT(IIO_CHAN_INFO_SAMP_FREQ), | ||
| 787 | .info_mask_separate_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), | ||
| 788 | .event_spec = vcnl4000_event_spec, | ||
| 789 | .num_event_specs = ARRAY_SIZE(vcnl4000_event_spec), | ||
| 790 | .ext_info = vcnl4000_ext_info, | ||
| 791 | .scan_type = { | ||
| 792 | .sign = 'u', | ||
| 793 | .realbits = 16, | ||
| 794 | .storagebits = 16, | ||
| 795 | .endianness = IIO_CPU, | ||
| 796 | }, | ||
| 797 | }, | ||
| 798 | IIO_CHAN_SOFT_TIMESTAMP(1), | ||
| 799 | }; | ||
| 800 | |||
| 436 | static const struct iio_info vcnl4000_info = { | 801 | static const struct iio_info vcnl4000_info = { |
| 437 | .read_raw = vcnl4000_read_raw, | 802 | .read_raw = vcnl4000_read_raw, |
| 438 | }; | 803 | }; |
| 439 | 804 | ||
| 805 | static const struct iio_info vcnl4010_info = { | ||
| 806 | .read_raw = vcnl4010_read_raw, | ||
| 807 | .read_avail = vcnl4010_read_avail, | ||
| 808 | .write_raw = vcnl4010_write_raw, | ||
| 809 | .read_event_value = vcnl4010_read_event, | ||
| 810 | .write_event_value = vcnl4010_write_event, | ||
| 811 | .read_event_config = vcnl4010_read_event_config, | ||
| 812 | .write_event_config = vcnl4010_write_event_config, | ||
| 813 | }; | ||
| 814 | |||
| 815 | static const struct vcnl4000_chip_spec vcnl4000_chip_spec_cfg[] = { | ||
| 816 | [VCNL4000] = { | ||
| 817 | .prod = "VCNL4000", | ||
| 818 | .init = vcnl4000_init, | ||
| 819 | .measure_light = vcnl4000_measure_light, | ||
| 820 | .measure_proximity = vcnl4000_measure_proximity, | ||
| 821 | .set_power_state = vcnl4000_set_power_state, | ||
| 822 | .channels = vcnl4000_channels, | ||
| 823 | .num_channels = ARRAY_SIZE(vcnl4000_channels), | ||
| 824 | .info = &vcnl4000_info, | ||
| 825 | .irq_support = false, | ||
| 826 | }, | ||
| 827 | [VCNL4010] = { | ||
| 828 | .prod = "VCNL4010/4020", | ||
| 829 | .init = vcnl4000_init, | ||
| 830 | .measure_light = vcnl4000_measure_light, | ||
| 831 | .measure_proximity = vcnl4000_measure_proximity, | ||
| 832 | .set_power_state = vcnl4000_set_power_state, | ||
| 833 | .channels = vcnl4010_channels, | ||
| 834 | .num_channels = ARRAY_SIZE(vcnl4010_channels), | ||
| 835 | .info = &vcnl4010_info, | ||
| 836 | .irq_support = true, | ||
| 837 | }, | ||
| 838 | [VCNL4040] = { | ||
| 839 | .prod = "VCNL4040", | ||
| 840 | .init = vcnl4200_init, | ||
| 841 | .measure_light = vcnl4200_measure_light, | ||
| 842 | .measure_proximity = vcnl4200_measure_proximity, | ||
| 843 | .set_power_state = vcnl4200_set_power_state, | ||
| 844 | .channels = vcnl4000_channels, | ||
| 845 | .num_channels = ARRAY_SIZE(vcnl4000_channels), | ||
| 846 | .info = &vcnl4000_info, | ||
| 847 | .irq_support = false, | ||
| 848 | }, | ||
| 849 | [VCNL4200] = { | ||
| 850 | .prod = "VCNL4200", | ||
| 851 | .init = vcnl4200_init, | ||
| 852 | .measure_light = vcnl4200_measure_light, | ||
| 853 | .measure_proximity = vcnl4200_measure_proximity, | ||
| 854 | .set_power_state = vcnl4200_set_power_state, | ||
| 855 | .channels = vcnl4000_channels, | ||
| 856 | .num_channels = ARRAY_SIZE(vcnl4000_channels), | ||
| 857 | .info = &vcnl4000_info, | ||
| 858 | .irq_support = false, | ||
| 859 | }, | ||
| 860 | }; | ||
| 861 | |||
| 862 | static irqreturn_t vcnl4010_irq_thread(int irq, void *p) | ||
| 863 | { | ||
| 864 | struct iio_dev *indio_dev = p; | ||
| 865 | struct vcnl4000_data *data = iio_priv(indio_dev); | ||
| 866 | unsigned long isr; | ||
| 867 | int ret; | ||
| 868 | |||
| 869 | ret = i2c_smbus_read_byte_data(data->client, VCNL4010_ISR); | ||
| 870 | if (ret < 0) | ||
| 871 | goto end; | ||
| 872 | |||
| 873 | isr = ret; | ||
| 874 | |||
| 875 | if (isr & VCNL4010_INT_THR) { | ||
| 876 | if (test_bit(VCNL4010_INT_THR_LOW, &isr)) { | ||
| 877 | iio_push_event(indio_dev, | ||
| 878 | IIO_UNMOD_EVENT_CODE( | ||
| 879 | IIO_PROXIMITY, | ||
| 880 | 1, | ||
| 881 | IIO_EV_TYPE_THRESH, | ||
| 882 | IIO_EV_DIR_FALLING), | ||
| 883 | iio_get_time_ns(indio_dev)); | ||
| 884 | } | ||
| 885 | |||
| 886 | if (test_bit(VCNL4010_INT_THR_HIGH, &isr)) { | ||
| 887 | iio_push_event(indio_dev, | ||
| 888 | IIO_UNMOD_EVENT_CODE( | ||
| 889 | IIO_PROXIMITY, | ||
| 890 | 1, | ||
| 891 | IIO_EV_TYPE_THRESH, | ||
| 892 | IIO_EV_DIR_RISING), | ||
| 893 | iio_get_time_ns(indio_dev)); | ||
| 894 | } | ||
| 895 | |||
| 896 | i2c_smbus_write_byte_data(data->client, VCNL4010_ISR, | ||
| 897 | isr & VCNL4010_INT_THR); | ||
| 898 | } | ||
| 899 | |||
| 900 | if (isr & VCNL4010_INT_DRDY && iio_buffer_enabled(indio_dev)) | ||
| 901 | iio_trigger_poll_chained(indio_dev->trig); | ||
| 902 | |||
| 903 | end: | ||
| 904 | return IRQ_HANDLED; | ||
| 905 | } | ||
| 906 | |||
| 907 | static irqreturn_t vcnl4010_trigger_handler(int irq, void *p) | ||
| 908 | { | ||
| 909 | struct iio_poll_func *pf = p; | ||
| 910 | struct iio_dev *indio_dev = pf->indio_dev; | ||
| 911 | struct vcnl4000_data *data = iio_priv(indio_dev); | ||
| 912 | const unsigned long *active_scan_mask = indio_dev->active_scan_mask; | ||
| 913 | u16 buffer[8] = {0}; /* 1x16-bit + ts */ | ||
| 914 | bool data_read = false; | ||
| 915 | unsigned long isr; | ||
| 916 | int val = 0; | ||
| 917 | int ret; | ||
| 918 | |||
| 919 | ret = i2c_smbus_read_byte_data(data->client, VCNL4010_ISR); | ||
| 920 | if (ret < 0) | ||
| 921 | goto end; | ||
| 922 | |||
| 923 | isr = ret; | ||
| 924 | |||
| 925 | if (test_bit(0, active_scan_mask)) { | ||
| 926 | if (test_bit(VCNL4010_INT_PROXIMITY, &isr)) { | ||
| 927 | ret = vcnl4000_read_data(data, | ||
| 928 | VCNL4000_PS_RESULT_HI, | ||
| 929 | &val); | ||
| 930 | if (ret < 0) | ||
| 931 | goto end; | ||
| 932 | |||
| 933 | buffer[0] = val; | ||
| 934 | data_read = true; | ||
| 935 | } | ||
| 936 | } | ||
| 937 | |||
| 938 | ret = i2c_smbus_write_byte_data(data->client, VCNL4010_ISR, | ||
| 939 | isr & VCNL4010_INT_DRDY); | ||
| 940 | if (ret < 0) | ||
| 941 | goto end; | ||
| 942 | |||
| 943 | if (!data_read) | ||
| 944 | goto end; | ||
| 945 | |||
| 946 | iio_push_to_buffers_with_timestamp(indio_dev, buffer, | ||
| 947 | iio_get_time_ns(indio_dev)); | ||
| 948 | |||
| 949 | end: | ||
| 950 | iio_trigger_notify_done(indio_dev->trig); | ||
| 951 | return IRQ_HANDLED; | ||
| 952 | } | ||
| 953 | |||
| 954 | static int vcnl4010_buffer_postenable(struct iio_dev *indio_dev) | ||
| 955 | { | ||
| 956 | struct vcnl4000_data *data = iio_priv(indio_dev); | ||
| 957 | int ret; | ||
| 958 | int cmd; | ||
| 959 | |||
| 960 | ret = iio_triggered_buffer_postenable(indio_dev); | ||
| 961 | if (ret) | ||
| 962 | return ret; | ||
| 963 | |||
| 964 | /* Do not enable the buffer if we are already capturing events. */ | ||
| 965 | if (vcnl4010_is_in_periodic_mode(data)) { | ||
| 966 | ret = -EBUSY; | ||
| 967 | goto end; | ||
| 968 | } | ||
| 969 | |||
| 970 | ret = i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL, | ||
| 971 | VCNL4010_INT_PROX_EN); | ||
| 972 | if (ret < 0) | ||
| 973 | goto end; | ||
| 974 | |||
| 975 | cmd = VCNL4000_SELF_TIMED_EN | VCNL4000_PROX_EN; | ||
| 976 | ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, cmd); | ||
| 977 | if (ret < 0) | ||
| 978 | goto end; | ||
| 979 | |||
| 980 | return 0; | ||
| 981 | end: | ||
| 982 | iio_triggered_buffer_predisable(indio_dev); | ||
| 983 | |||
| 984 | return ret; | ||
| 985 | } | ||
| 986 | |||
| 987 | static int vcnl4010_buffer_predisable(struct iio_dev *indio_dev) | ||
| 988 | { | ||
| 989 | struct vcnl4000_data *data = iio_priv(indio_dev); | ||
| 990 | int ret, ret_disable; | ||
| 991 | |||
| 992 | ret = i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL, 0); | ||
| 993 | if (ret < 0) | ||
| 994 | goto end; | ||
| 995 | |||
| 996 | ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, 0); | ||
| 997 | |||
| 998 | end: | ||
| 999 | ret_disable = iio_triggered_buffer_predisable(indio_dev); | ||
| 1000 | if (ret == 0) | ||
| 1001 | ret = ret_disable; | ||
| 1002 | |||
| 1003 | return ret; | ||
| 1004 | } | ||
| 1005 | |||
| 1006 | static const struct iio_buffer_setup_ops vcnl4010_buffer_ops = { | ||
| 1007 | .postenable = &vcnl4010_buffer_postenable, | ||
| 1008 | .predisable = &vcnl4010_buffer_predisable, | ||
| 1009 | }; | ||
| 1010 | |||
| 1011 | static const struct iio_trigger_ops vcnl4010_trigger_ops = { | ||
| 1012 | .validate_device = iio_trigger_validate_own_device, | ||
| 1013 | }; | ||
| 1014 | |||
| 1015 | static int vcnl4010_probe_trigger(struct iio_dev *indio_dev) | ||
| 1016 | { | ||
| 1017 | struct vcnl4000_data *data = iio_priv(indio_dev); | ||
| 1018 | struct i2c_client *client = data->client; | ||
| 1019 | struct iio_trigger *trigger; | ||
| 1020 | |||
| 1021 | trigger = devm_iio_trigger_alloc(&client->dev, "%s-dev%d", | ||
| 1022 | indio_dev->name, indio_dev->id); | ||
| 1023 | if (!trigger) | ||
| 1024 | return -ENOMEM; | ||
| 1025 | |||
| 1026 | trigger->dev.parent = &client->dev; | ||
| 1027 | trigger->ops = &vcnl4010_trigger_ops; | ||
| 1028 | iio_trigger_set_drvdata(trigger, indio_dev); | ||
| 1029 | |||
| 1030 | return devm_iio_trigger_register(&client->dev, trigger); | ||
| 1031 | } | ||
| 1032 | |||
| 440 | static int vcnl4000_probe(struct i2c_client *client, | 1033 | static int vcnl4000_probe(struct i2c_client *client, |
| 441 | const struct i2c_device_id *id) | 1034 | const struct i2c_device_id *id) |
| 442 | { | 1035 | { |
| @@ -466,12 +1059,39 @@ static int vcnl4000_probe(struct i2c_client *client, · 23 unmodified lines | |||
| 466 | data->near_level = 0; | 1059 | data->near_level = 0; |
| 467 | 1060 | ||
| 468 | indio_dev->dev.parent = &client->dev; | 1061 | indio_dev->dev.parent = &client->dev; |
| 469 | indio_dev->info = &vcnl4000_info; | 1062 | indio_dev->info = data->chip_spec->info; |
| 470 | indio_dev->channels = vcnl4000_channels; | 1063 | indio_dev->channels = data->chip_spec->channels; |
| 471 | indio_dev->num_channels = ARRAY_SIZE(vcnl4000_channels); | 1064 | indio_dev->num_channels = data->chip_spec->num_channels; |
| 472 | indio_dev->name = VCNL4000_DRV_NAME; | 1065 | indio_dev->name = VCNL4000_DRV_NAME; |
| 473 | indio_dev->modes = INDIO_DIRECT_MODE; | 1066 | indio_dev->modes = INDIO_DIRECT_MODE; |
| 474 | 1067 | ||
| 1068 | if (client->irq && data->chip_spec->irq_support) { | ||
| 1069 | ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev, | ||
| 1070 | NULL, | ||
| 1071 | vcnl4010_trigger_handler, | ||
| 1072 | &vcnl4010_buffer_ops); | ||
| 1073 | if (ret < 0) { | ||
| 1074 | dev_err(&client->dev, | ||
| 1075 | "unable to setup iio triggered buffer\n"); | ||
| 1076 | return ret; | ||
| 1077 | } | ||
| 1078 | |||
| 1079 | ret = devm_request_threaded_irq(&client->dev, client->irq, | ||
| 1080 | NULL, vcnl4010_irq_thread, | ||
| 1081 | IRQF_TRIGGER_FALLING | | ||
| 1082 | IRQF_ONESHOT, | ||
| 1083 | "vcnl4010_irq", | ||
| 1084 | indio_dev); | ||
| 1085 | if (ret < 0) { | ||
| 1086 | dev_err(&client->dev, "irq request failed\n"); | ||
| 1087 | return ret; | ||
| 1088 | } | ||
| 1089 | |||
| 1090 | ret = vcnl4010_probe_trigger(indio_dev); | ||
| 1091 | if (ret < 0) | ||
| 1092 | return ret; | ||
| 1093 | } | ||
| 1094 | |||
| 475 | ret = pm_runtime_set_active(&client->dev); | 1095 | ret = pm_runtime_set_active(&client->dev); |
| 476 | if (ret < 0) | 1096 | if (ret < 0) |
| 477 | goto fail_poweroff; | 1097 | goto fail_poweroff; |
| @@ -565,5 +1185,6 @@ static struct i2c_driver vcnl4000_driver = { · 87 unmodified lines | |||
| 565 | module_i2c_driver(vcnl4000_driver); | 1185 | module_i2c_driver(vcnl4000_driver); |
| 566 | 1186 | ||
| 567 | MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>"); | 1187 | MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>"); |
| 1188 | MODULE_AUTHOR("Mathieu Othacehe <m.othacehe@gmail.com>"); | ||
| 568 | MODULE_DESCRIPTION("Vishay VCNL4000 proximity/ambient light sensor driver"); | 1189 | MODULE_DESCRIPTION("Vishay VCNL4000 proximity/ambient light sensor driver"); |
| 569 | MODULE_LICENSE("GPL"); | 1190 | MODULE_LICENSE("GPL"); |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | |||
| 16 | */ | 16 | */ |
| 17 | 17 | ||
| 18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
| 19 | #include <linux/mod_devicetable.h> | ||
| 19 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
| 20 | #include <linux/mutex.h> | 21 | #include <linux/mutex.h> |
| 21 | #include <linux/err.h> | 22 | #include <linux/err.h> |
| @@ -537,7 +538,7 @@ MODULE_DEVICE_TABLE(i2c, vl6180_id); · 515 unmodified lines | |||
| 537 | static struct i2c_driver vl6180_driver = { | 538 | static struct i2c_driver vl6180_driver = { |
| 538 | .driver = { | 539 | .driver = { |
| 539 | .name = VL6180_DRV_NAME, | 540 | .name = VL6180_DRV_NAME, |
| 540 | .of_match_table = of_match_ptr(vl6180_of_match), | 541 | .of_match_table = vl6180_of_match, |
| 541 | }, | 542 | }, |
| 542 | .probe = vl6180_probe, | 543 | .probe = vl6180_probe, |
| 543 | .id_table = vl6180_id, | 544 | .id_table = vl6180_id, |
| @@ -19,6 +19,8 @@ · 18 unmodified lines | |||
| 19 | #include <linux/iio/iio.h> | 19 | #include <linux/iio/iio.h> |
| 20 | #include <linux/iio/sysfs.h> | 20 | #include <linux/iio/sysfs.h> |
| 21 | 21 | ||
| 22 | #include <asm/unaligned.h> | ||
| 23 | |||
| 22 | #define ZOPT2201_DRV_NAME "zopt2201" | 24 | #define ZOPT2201_DRV_NAME "zopt2201" |
| 23 | 25 | ||
| 24 | /* Registers */ | 26 | /* Registers */ |
| @@ -219,7 +221,7 @@ static int zopt2201_read(struct zopt2201_data *data, u8 reg) · 194 unmodified lines | |||
| 219 | goto fail; | 221 | goto fail; |
| 220 | mutex_unlock(&data->lock); | 222 | mutex_unlock(&data->lock); |
| 221 | 223 | ||
| 222 | return (buf[2] << 16) | (buf[1] << 8) | buf[0]; | 224 | return get_unaligned_le24(&buf[0]); |
| 223 | 225 | ||
| 224 | fail: | 226 | fail: |
| 225 | mutex_unlock(&data->lock); | 227 | mutex_unlock(&data->lock); |
| @@ -49,6 +49,7 @@ · 48 unmodified lines | |||
| 49 | #define AK8974_WHOAMI_VALUE_AMI306 0x46 | 49 | #define AK8974_WHOAMI_VALUE_AMI306 0x46 |
| 50 | #define AK8974_WHOAMI_VALUE_AMI305 0x47 | 50 | #define AK8974_WHOAMI_VALUE_AMI305 0x47 |
| 51 | #define AK8974_WHOAMI_VALUE_AK8974 0x48 | 51 | #define AK8974_WHOAMI_VALUE_AK8974 0x48 |
| 52 | #define AK8974_WHOAMI_VALUE_HSCDTD008A 0x49 | ||
| 52 | 53 | ||
| 53 | #define AK8974_DATA_X 0x10 | 54 | #define AK8974_DATA_X 0x10 |
| 54 | #define AK8974_DATA_Y 0x12 | 55 | #define AK8974_DATA_Y 0x12 |
| @@ -140,6 +141,12 @@ · 85 unmodified lines | |||
| 140 | #define AK8974_INT_CTRL_PULSE BIT(1) /* 0 = latched; 1 = pulse (50 usec) */ | 141 | #define AK8974_INT_CTRL_PULSE BIT(1) /* 0 = latched; 1 = pulse (50 usec) */ |
| 141 | #define AK8974_INT_CTRL_RESDEF (AK8974_INT_CTRL_XYZEN | AK8974_INT_CTRL_POL) | 142 | #define AK8974_INT_CTRL_RESDEF (AK8974_INT_CTRL_XYZEN | AK8974_INT_CTRL_POL) |
| 142 | 143 | ||
| 144 | /* HSCDTD008A-specific control register */ | ||
| 145 | #define HSCDTD008A_CTRL4 0x1E | ||
| 146 | #define HSCDTD008A_CTRL4_MMD BIT(7) /* must be set to 1 */ | ||
| 147 | #define HSCDTD008A_CTRL4_RANGE BIT(4) /* 0 = 14-bit output; 1 = 15-bit output */ | ||
| 148 | #define HSCDTD008A_CTRL4_RESDEF (HSCDTD008A_CTRL4_MMD | HSCDTD008A_CTRL4_RANGE) | ||
| 149 | |||
| 143 | /* The AMI305 has elaborate FW version and serial number registers */ | 150 | /* The AMI305 has elaborate FW version and serial number registers */ |
| 144 | #define AMI305_VER 0xE8 | 151 | #define AMI305_VER 0xE8 |
| 145 | #define AMI305_SN 0xEA | 152 | #define AMI305_SN 0xEA |
| @@ -241,10 +248,17 @@ static int ak8974_reset(struct ak8974 *ak8974) · 95 unmodified lines | |||
| 241 | ret = regmap_write(ak8974->map, AK8974_CTRL3, AK8974_CTRL3_RESDEF); | 248 | ret = regmap_write(ak8974->map, AK8974_CTRL3, AK8974_CTRL3_RESDEF); |
| 242 | if (ret) | 249 | if (ret) |
| 243 | return ret; | 250 | return ret; |
| 244 | ret = regmap_write(ak8974->map, AK8974_INT_CTRL, | 251 | if (ak8974->variant != AK8974_WHOAMI_VALUE_HSCDTD008A) { |
| 245 | AK8974_INT_CTRL_RESDEF); | 252 | ret = regmap_write(ak8974->map, AK8974_INT_CTRL, |
| 246 | if (ret) | 253 | AK8974_INT_CTRL_RESDEF); |
| 247 | return ret; | 254 | if (ret) |
| 255 | return ret; | ||
| 256 | } else { | ||
| 257 | ret = regmap_write(ak8974->map, HSCDTD008A_CTRL4, | ||
| 258 | HSCDTD008A_CTRL4_RESDEF); | ||
| 259 | if (ret) | ||
| 260 | return ret; | ||
| 261 | } | ||
| 248 | 262 | ||
| 249 | /* After reset, power off is default state */ | 263 | /* After reset, power off is default state */ |
| 250 | return ak8974_set_power(ak8974, AK8974_PWR_OFF); | 264 | return ak8974_set_power(ak8974, AK8974_PWR_OFF); |
| @@ -267,6 +281,8 @@ static int ak8974_configure(struct ak8974 *ak8974) · 16 unmodified lines | |||
| 267 | if (ret) | 281 | if (ret) |
| 268 | return ret; | 282 | return ret; |
| 269 | } | 283 | } |
| 284 | if (ak8974->variant == AK8974_WHOAMI_VALUE_HSCDTD008A) | ||
| 285 | return 0; | ||
| 270 | ret = regmap_write(ak8974->map, AK8974_INT_CTRL, AK8974_INT_CTRL_POL); | 286 | ret = regmap_write(ak8974->map, AK8974_INT_CTRL, AK8974_INT_CTRL_POL); |
| 271 | if (ret) | 287 | if (ret) |
| 272 | return ret; | 288 | return ret; |
| @@ -495,6 +511,10 @@ static int ak8974_detect(struct ak8974 *ak8974) · 222 unmodified lines | |||
| 495 | name = "ak8974"; | 511 | name = "ak8974"; |
| 496 | dev_info(&ak8974->i2c->dev, "detected AK8974\n"); | 512 | dev_info(&ak8974->i2c->dev, "detected AK8974\n"); |
| 497 | break; | 513 | break; |
| 514 | case AK8974_WHOAMI_VALUE_HSCDTD008A: | ||
| 515 | name = "hscdtd008a"; | ||
| 516 | dev_info(&ak8974->i2c->dev, "detected hscdtd008a\n"); | ||
| 517 | break; | ||
| 498 | default: | 518 | default: |
| 499 | dev_err(&ak8974->i2c->dev, "unsupported device (%02x) ", | 519 | dev_err(&ak8974->i2c->dev, "unsupported device (%02x) ", |
| 500 | whoami); | 520 | whoami); |
| @@ -534,47 +554,103 @@ static int ak8974_detect(struct ak8974 *ak8974) · 33 unmodified lines | |||
| 534 | return 0; | 554 | return 0; |
| 535 | } | 555 | } |
| 536 | 556 | ||
| 557 | static int ak8974_measure_channel(struct ak8974 *ak8974, unsigned long address, | ||
| 558 | int *val) | ||
| 559 | { | ||
| 560 | __le16 hw_values[3]; | ||
| 561 | int ret; | ||
| 562 | |||
| 563 | pm_runtime_get_sync(&ak8974->i2c->dev); | ||
| 564 | mutex_lock(&ak8974->lock); | ||
| 565 | |||
| 566 | /* | ||
| 567 | * We read all axes and discard all but one, for optimized | ||
| 568 | * reading, use the triggered buffer. | ||
| 569 | */ | ||
| 570 | ret = ak8974_trigmeas(ak8974); | ||
| 571 | if (ret) | ||
| 572 | goto out_unlock; | ||
| 573 | ret = ak8974_getresult(ak8974, hw_values); | ||
| 574 | if (ret) | ||
| 575 | goto out_unlock; | ||
| 576 | /* | ||
| 577 | * This explicit cast to (s16) is necessary as the measurement | ||
| 578 | * is done in 2's complement with positive and negative values. | ||
| 579 | * The follwing assignment to *val will then convert the signed | ||
| 580 | * s16 value to a signed int value. | ||
| 581 | */ | ||
| 582 | *val = (s16)le16_to_cpu(hw_values[address]); | ||
| 583 | out_unlock: | ||
| 584 | mutex_unlock(&ak8974->lock); | ||
| 585 | pm_runtime_mark_last_busy(&ak8974->i2c->dev); | ||
| 586 | pm_runtime_put_autosuspend(&ak8974->i2c->dev); | ||
| 587 | |||
| 588 | return ret; | ||
| 589 | } | ||
| 590 | |||
| 537 | static int ak8974_read_raw(struct iio_dev *indio_dev, | 591 | static int ak8974_read_raw(struct iio_dev *indio_dev, |
| 538 | struct iio_chan_spec const *chan, | 592 | struct iio_chan_spec const *chan, |
| 539 | int *val, int *val2, | 593 | int *val, int *val2, |
| 540 | long mask) | 594 | long mask) |
| 541 | { | 595 | { |
| 542 | struct ak8974 *ak8974 = iio_priv(indio_dev); | 596 | struct ak8974 *ak8974 = iio_priv(indio_dev); |
| 543 | __le16 hw_values[3]; | 597 | int ret; |
| 544 | int ret = -EINVAL; | ||
| 545 | |||
| 546 | pm_runtime_get_sync(&ak8974->i2c->dev); | ||
| 547 | mutex_lock(&ak8974->lock); | ||
| 548 | 598 | ||
| 549 | switch (mask) { | 599 | switch (mask) { |
| 550 | case IIO_CHAN_INFO_RAW: | 600 | case IIO_CHAN_INFO_RAW: |
| 551 | if (chan->address > 2) { | 601 | if (chan->address > 2) { |
| 552 | dev_err(&ak8974->i2c->dev, "faulty channel address\n"); | 602 | dev_err(&ak8974->i2c->dev, "faulty channel address\n"); |
| 553 | ret = -EIO; | 603 | return -EIO; |
| 554 | goto out_unlock; | ||
| 555 | } | 604 | } |
| 556 | ret = ak8974_trigmeas(ak8974); | 605 | ret = ak8974_measure_channel(ak8974, chan->address, val); |
| 557 | if (ret) | ||
| 558 | goto out_unlock; | ||
| 559 | ret = ak8974_getresult(ak8974, hw_values); | ||
| 560 | if (ret) | 606 | if (ret) |
| 561 | goto out_unlock; | 607 | return ret; |
| 562 | 608 | return IIO_VAL_INT; | |
| 563 | /* | 609 | case IIO_CHAN_INFO_SCALE: |
| 564 | * We read all axes and discard all but one, for optimized | 610 | switch (ak8974->variant) { |
| 565 | * reading, use the triggered buffer. | 611 | case AK8974_WHOAMI_VALUE_AMI306: |
| 566 | */ | 612 | case AK8974_WHOAMI_VALUE_AMI305: |
| 567 | *val = (s16)le16_to_cpu(hw_values[chan->address]); | 613 | /* |
| 568 | 614 | * The datasheet for AMI305 and AMI306, page 6 | |
| 569 | ret = IIO_VAL_INT; | 615 | * specifies the range of the sensor to be |
| 616 | * +/- 12 Gauss. | ||
| 617 | */ | ||
| 618 | *val = 12; | ||
| 619 | /* | ||
| 620 | * 12 bits are used, +/- 2^11 | ||
| 621 | * [ -2048 .. 2047 ] (manual page 20) | ||
| 622 | * [ 0xf800 .. 0x07ff ] | ||
| 623 | */ | ||
| 624 | *val2 = 11; | ||
| 625 | return IIO_VAL_FRACTIONAL_LOG2; | ||
| 626 | case AK8974_WHOAMI_VALUE_HSCDTD008A: | ||
| 627 | /* | ||
| 628 | * The datasheet for HSCDTF008A, page 3 specifies the | ||
| 629 | * range of the sensor as +/- 2.4 mT per axis, which | ||
| 630 | * corresponds to +/- 2400 uT = +/- 24 Gauss. | ||
| 631 | */ | ||
| 632 | *val = 24; | ||
| 633 | /* | ||
| 634 | * 15 bits are used (set up in CTRL4), +/- 2^14 | ||
| 635 | * [ -16384 .. 16383 ] (manual page 24) | ||
| 636 | * [ 0xc000 .. 0x3fff ] | ||
| 637 | */ | ||
| 638 | *val2 = 14; | ||
| 639 | return IIO_VAL_FRACTIONAL_LOG2; | ||
| 640 | default: | ||
| 641 | /* GUESSING +/- 12 Gauss */ | ||
| 642 | *val = 12; | ||
| 643 | /* GUESSING 12 bits ADC +/- 2^11 */ | ||
| 644 | *val2 = 11; | ||
| 645 | return IIO_VAL_FRACTIONAL_LOG2; | ||
| 646 | } | ||
| 647 | break; | ||
| 648 | default: | ||
| 649 | /* Unknown request */ | ||
| 650 | break; | ||
| 570 | } | 651 | } |
| 571 | 652 | ||
| 572 | out_unlock: | 653 | return -EINVAL; |
| 573 | mutex_unlock(&ak8974->lock); | ||
| 574 | pm_runtime_mark_last_busy(&ak8974->i2c->dev); | ||
| 575 | pm_runtime_put_autosuspend(&ak8974->i2c->dev); | ||
| 576 | |||
| 577 | return ret; | ||
| 578 | } | 654 | } |
| 579 | 655 | ||
| 580 | static void ak8974_fill_buffer(struct iio_dev *indio_dev) | 656 | static void ak8974_fill_buffer(struct iio_dev *indio_dev) |
| @@ -631,27 +707,44 @@ static const struct iio_chan_spec_ext_info ak8974_ext_info[] = { · 50 unmodified lines | |||
| 631 | { }, | 707 | { }, |
| 632 | }; | 708 | }; |
| 633 | 709 | ||
| 634 | #define AK8974_AXIS_CHANNEL(axis, index) \ | 710 | #define AK8974_AXIS_CHANNEL(axis, index, bits) \ |
| 635 | { \ | 711 | { \ |
| 636 | .type = IIO_MAGN, \ | 712 | .type = IIO_MAGN, \ |
| 637 | .modified = 1, \ | 713 | .modified = 1, \ |
| 638 | .channel2 = IIO_MOD_##axis, \ | 714 | .channel2 = IIO_MOD_##axis, \ |
| 639 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ | 715 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ |
| 716 | BIT(IIO_CHAN_INFO_SCALE), \ | ||
| 640 | .ext_info = ak8974_ext_info, \ | 717 | .ext_info = ak8974_ext_info, \ |
| 641 | .address = index, \ | 718 | .address = index, \ |
| 642 | .scan_index = index, \ | 719 | .scan_index = index, \ |
| 643 | .scan_type = { \ | 720 | .scan_type = { \ |
| 644 | .sign = 's', \ | 721 | .sign = 's', \ |
| 645 | .realbits = 16, \ | 722 | .realbits = bits, \ |
| 646 | .storagebits = 16, \ | 723 | .storagebits = 16, \ |
| 647 | .endianness = IIO_LE \ | 724 | .endianness = IIO_LE \ |
| 648 | }, \ | 725 | }, \ |
| 649 | } | 726 | } |
| 650 | 727 | ||
| 651 | static const struct iio_chan_spec ak8974_channels[] = { | 728 | /* |
| 652 | AK8974_AXIS_CHANNEL(X, 0), | 729 | * We have no datasheet for the AK8974 but we guess that its |
| 653 | AK8974_AXIS_CHANNEL(Y, 1), | 730 | * ADC is 12 bits. The AMI305 and AMI306 certainly has 12bit |
| 654 | AK8974_AXIS_CHANNEL(Z, 2), | 731 | * ADC. |
| 732 | */ | ||
| 733 | static const struct iio_chan_spec ak8974_12_bits_channels[] = { | ||
| 734 | AK8974_AXIS_CHANNEL(X, 0, 12), | ||
| 735 | AK8974_AXIS_CHANNEL(Y, 1, 12), | ||
| 736 | AK8974_AXIS_CHANNEL(Z, 2, 12), | ||
| 737 | IIO_CHAN_SOFT_TIMESTAMP(3), | ||
| 738 | }; | ||
| 739 | |||
| 740 | /* | ||
| 741 | * The HSCDTD008A has 15 bits resolution the way we set it up | ||
| 742 | * in CTRL4. | ||
| 743 | */ | ||
| 744 | static const struct iio_chan_spec ak8974_15_bits_channels[] = { | ||
| 745 | AK8974_AXIS_CHANNEL(X, 0, 15), | ||
| 746 | AK8974_AXIS_CHANNEL(Y, 1, 15), | ||
| 747 | AK8974_AXIS_CHANNEL(Z, 2, 15), | ||
| 655 | IIO_CHAN_SOFT_TIMESTAMP(3), | 748 | IIO_CHAN_SOFT_TIMESTAMP(3), |
| 656 | }; | 749 | }; |
| 657 | 750 | ||
| @@ -674,18 +767,18 @@ static bool ak8974_writeable_reg(struct device *dev, unsigned int reg) · 16 unmodified lines | |||
| 674 | case AK8974_INT_CTRL: | 767 | case AK8974_INT_CTRL: |
| 675 | case AK8974_INT_THRES: | 768 | case AK8974_INT_THRES: |
| 676 | case AK8974_INT_THRES + 1: | 769 | case AK8974_INT_THRES + 1: |
| 770 | return true; | ||
| 677 | case AK8974_PRESET: | 771 | case AK8974_PRESET: |
| 678 | case AK8974_PRESET + 1: | 772 | case AK8974_PRESET + 1: |
| 679 | return true; | 773 | return ak8974->variant != AK8974_WHOAMI_VALUE_HSCDTD008A; |
| 680 | case AK8974_OFFSET_X: | 774 | case AK8974_OFFSET_X: |
| 681 | case AK8974_OFFSET_X + 1: | 775 | case AK8974_OFFSET_X + 1: |
| 682 | case AK8974_OFFSET_Y: | 776 | case AK8974_OFFSET_Y: |
| 683 | case AK8974_OFFSET_Y + 1: | 777 | case AK8974_OFFSET_Y + 1: |
| 684 | case AK8974_OFFSET_Z: | 778 | case AK8974_OFFSET_Z: |
| 685 | case AK8974_OFFSET_Z + 1: | 779 | case AK8974_OFFSET_Z + 1: |
| 686 | if (ak8974->variant == AK8974_WHOAMI_VALUE_AK8974) | 780 | return ak8974->variant == AK8974_WHOAMI_VALUE_AK8974 || |
| 687 | return true; | 781 | ak8974->variant == AK8974_WHOAMI_VALUE_HSCDTD008A; |
| 688 | return false; | ||
| 689 | case AMI305_OFFSET_X: | 782 | case AMI305_OFFSET_X: |
| 690 | case AMI305_OFFSET_X + 1: | 783 | case AMI305_OFFSET_X + 1: |
| 691 | case AMI305_OFFSET_Y: | 784 | case AMI305_OFFSET_Y: |
| @@ -800,8 +893,21 @@ static int ak8974_probe(struct i2c_client *i2c, · 108 unmodified lines | |||
| 800 | pm_runtime_put(&i2c->dev); | 893 | pm_runtime_put(&i2c->dev); |
| 801 | 894 | ||
| 802 | indio_dev->dev.parent = &i2c->dev; | 895 | indio_dev->dev.parent = &i2c->dev; |
| 803 | indio_dev->channels = ak8974_channels; | 896 | switch (ak8974->variant) { |
| 804 | indio_dev->num_channels = ARRAY_SIZE(ak8974_channels); | 897 | case AK8974_WHOAMI_VALUE_AMI306: |
| 898 | case AK8974_WHOAMI_VALUE_AMI305: | ||
| 899 | indio_dev->channels = ak8974_12_bits_channels; | ||
| 900 | indio_dev->num_channels = ARRAY_SIZE(ak8974_12_bits_channels); | ||
| 901 | break; | ||
| 902 | case AK8974_WHOAMI_VALUE_HSCDTD008A: | ||
| 903 | indio_dev->channels = ak8974_15_bits_channels; | ||
| 904 | indio_dev->num_channels = ARRAY_SIZE(ak8974_15_bits_channels); | ||
| 905 | break; | ||
| 906 | default: | ||
| 907 | indio_dev->channels = ak8974_12_bits_channels; | ||
| 908 | indio_dev->num_channels = ARRAY_SIZE(ak8974_12_bits_channels); | ||
| 909 | break; | ||
| 910 | } | ||
| 805 | indio_dev->info = &ak8974_info; | 911 | indio_dev->info = &ak8974_info; |
| 806 | indio_dev->available_scan_masks = ak8974_scan_masks; | 912 | indio_dev->available_scan_masks = ak8974_scan_masks; |
| 807 | indio_dev->modes = INDIO_DIRECT_MODE; | 913 | indio_dev->modes = INDIO_DIRECT_MODE; |
| @@ -931,12 +1037,14 @@ static const struct i2c_device_id ak8974_id[] = { · 123 unmodified lines | |||
| 931 | {"ami305", 0 }, | 1037 | {"ami305", 0 }, |
| 932 | {"ami306", 0 }, | 1038 | {"ami306", 0 }, |
| 933 | {"ak8974", 0 }, | 1039 | {"ak8974", 0 }, |
| 1040 | {"hscdtd008a", 0 }, | ||
| 934 | {} | 1041 | {} |
| 935 | }; | 1042 | }; |
| 936 | MODULE_DEVICE_TABLE(i2c, ak8974_id); | 1043 | MODULE_DEVICE_TABLE(i2c, ak8974_id); |
| 937 | 1044 | ||
| 938 | static const struct of_device_id ak8974_of_match[] = { | 1045 | static const struct of_device_id ak8974_of_match[] = { |
| 939 | { .compatible = "asahi-kasei,ak8974", }, | 1046 | { .compatible = "asahi-kasei,ak8974", }, |
| 1047 | { .compatible = "alps,hscdtd008a", }, | ||
| 940 | {} | 1048 | {} |
| 941 | }; | 1049 | }; |
| 942 | MODULE_DEVICE_TABLE(of, ak8974_of_match); | 1050 | MODULE_DEVICE_TABLE(of, ak8974_of_match); |
| @@ -14,8 +14,6 @@ · 13 unmodified lines | |||
| 14 | #include <linux/iio/iio.h> | 14 | #include <linux/iio/iio.h> |
| 15 | #include <linux/iio/sysfs.h> | 15 | #include <linux/iio/sysfs.h> |
| 16 | #include <linux/iio/buffer.h> | 16 | #include <linux/iio/buffer.h> |
| 17 | #include <linux/iio/trigger_consumer.h> | ||
| 18 | #include <linux/iio/triggered_buffer.h> | ||
| 19 | #include "../common/hid-sensors/hid-sensor-trigger.h" | 17 | #include "../common/hid-sensors/hid-sensor-trigger.h" |
| 20 | 18 | ||
| 21 | enum magn_3d_channel { | 19 | enum magn_3d_channel { |
| @@ -519,18 +517,13 @@ static int hid_magn_3d_probe(struct platform_device *pdev) · 497 unmodified lines | |||
| 519 | indio_dev->name = name; | 517 | indio_dev->name = name; |
| 520 | indio_dev->modes = INDIO_DIRECT_MODE; | 518 | indio_dev->modes = INDIO_DIRECT_MODE; |
| 521 | 519 | ||
| 522 | ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, | ||
| 523 | NULL, NULL); | ||
| 524 | if (ret) { | ||
| 525 | dev_err(&pdev->dev, "failed to initialize trigger buffer\n"); | ||
| 526 | return ret; | ||
| 527 | } | ||
| 528 | atomic_set(&magn_state->magn_flux_attributes.data_ready, 0); | 520 | atomic_set(&magn_state->magn_flux_attributes.data_ready, 0); |
| 521 | |||
| 529 | ret = hid_sensor_setup_trigger(indio_dev, name, | 522 | ret = hid_sensor_setup_trigger(indio_dev, name, |
| 530 | &magn_state->magn_flux_attributes); | 523 | &magn_state->magn_flux_attributes); |
| 531 | if (ret < 0) { | 524 | if (ret < 0) { |
| 532 | dev_err(&pdev->dev, "trigger setup failed\n"); | 525 | dev_err(&pdev->dev, "trigger setup failed\n"); |
| 533 | goto error_unreg_buffer_funcs; | 526 | return ret; |
| 534 | } | 527 | } |
| 535 | 528 | ||
| 536 | ret = iio_device_register(indio_dev); | 529 | ret = iio_device_register(indio_dev); |
| @@ -554,9 +547,7 @@ static int hid_magn_3d_probe(struct platform_device *pdev) · 17 unmodified lines | |||
| 554 | error_iio_unreg: | 547 | error_iio_unreg: |
| 555 | iio_device_unregister(indio_dev); | 548 | iio_device_unregister(indio_dev); |
| 556 | error_remove_trigger: | 549 | error_remove_trigger: |
| 557 | hid_sensor_remove_trigger(&magn_state->magn_flux_attributes); | 550 | hid_sensor_remove_trigger(indio_dev, &magn_state->magn_flux_attributes); |
| 558 | error_unreg_buffer_funcs: | ||
| 559 | iio_triggered_buffer_cleanup(indio_dev); | ||
| 560 | return ret; | 551 | return ret; |
| 561 | } | 552 | } |
| 562 | 553 | ||
| @@ -569,8 +560,7 @@ static int hid_magn_3d_remove(struct platform_device *pdev) · 6 unmodified lines | |||
| 569 | 560 | ||
| 570 | sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_COMPASS_3D); | 561 | sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_COMPASS_3D); |
| 571 | iio_device_unregister(indio_dev); | 562 | iio_device_unregister(indio_dev); |
| 572 | hid_sensor_remove_trigger(&magn_state->magn_flux_attributes); | 563 | hid_sensor_remove_trigger(indio_dev, &magn_state->magn_flux_attributes); |
| 573 | iio_triggered_buffer_cleanup(indio_dev); | ||
| 574 | 564 | ||
| 575 | return 0; | 565 | return 0; |
| 576 | } | 566 | } |
| @@ -22,6 +22,8 @@ · 21 unmodified lines | |||
| 22 | #include <linux/iio/triggered_buffer.h> | 22 | #include <linux/iio/triggered_buffer.h> |
| 23 | #include <linux/iio/trigger_consumer.h> | 23 | #include <linux/iio/trigger_consumer.h> |
| 24 | 24 | ||
| 25 | #include <asm/unaligned.h> | ||
| 26 | |||
| 25 | #include "rm3100.h" | 27 | #include "rm3100.h" |
| 26 | 28 | ||
| 27 | /* Cycle Count Registers. */ | 29 | /* Cycle Count Registers. */ |
| @@ -223,8 +225,7 @@ static int rm3100_read_mag(struct rm3100_data *data, int idx, int *val) · 195 unmodified lines | |||
| 223 | goto unlock_return; | 225 | goto unlock_return; |
| 224 | mutex_unlock(&data->lock); | 226 | mutex_unlock(&data->lock); |
| 225 | 227 | ||
| 226 | *val = sign_extend32((buffer[0] << 16) | (buffer[1] << 8) | buffer[2], | 228 | *val = sign_extend32(get_unaligned_be24(&buffer[0]), 23); |
| 227 | 23); | ||
| 228 | 229 | ||
| 229 | return IIO_VAL_INT; | 230 | return IIO_VAL_INT; |
| 230 | 231 | ||
| @@ -15,8 +15,6 @@ · 14 unmodified lines | |||
| 15 | #include <linux/iio/iio.h> | 15 | #include <linux/iio/iio.h> |
| 16 | #include <linux/iio/sysfs.h> | 16 | #include <linux/iio/sysfs.h> |
| 17 | #include <linux/iio/buffer.h> | 17 | #include <linux/iio/buffer.h> |
| 18 | #include <linux/iio/trigger_consumer.h> | ||
| 19 | #include <linux/iio/triggered_buffer.h> | ||
| 20 | #include "../common/hid-sensors/hid-sensor-trigger.h" | 18 | #include "../common/hid-sensors/hid-sensor-trigger.h" |
| 21 | 19 | ||
| 22 | enum incl_3d_channel { | 20 | enum incl_3d_channel { |
| @@ -346,18 +344,13 @@ static int hid_incl_3d_probe(struct platform_device *pdev) · 323 unmodified lines | |||
| 346 | indio_dev->name = name; | 344 | indio_dev->name = name; |
| 347 | indio_dev->modes = INDIO_DIRECT_MODE; | 345 | indio_dev->modes = INDIO_DIRECT_MODE; |
| 348 | 346 | ||
| 349 | ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, | ||
| 350 | NULL, NULL); | ||
| 351 | if (ret) { | ||
| 352 | dev_err(&pdev->dev, "failed to initialize trigger buffer\n"); | ||
| 353 | goto error_free_dev_mem; | ||
| 354 | } | ||
| 355 | atomic_set(&incl_state->common_attributes.data_ready, 0); | 347 | atomic_set(&incl_state->common_attributes.data_ready, 0); |
| 348 | |||
| 356 | ret = hid_sensor_setup_trigger(indio_dev, name, | 349 | ret = hid_sensor_setup_trigger(indio_dev, name, |
| 357 | &incl_state->common_attributes); | 350 | &incl_state->common_attributes); |
| 358 | if (ret) { | 351 | if (ret) { |
| 359 | dev_err(&pdev->dev, "trigger setup failed\n"); | 352 | dev_err(&pdev->dev, "trigger setup failed\n"); |
| 360 | goto error_unreg_buffer_funcs; | 353 | goto error_free_dev_mem; |
| 361 | } | 354 | } |
| 362 | 355 | ||
| 363 | ret = iio_device_register(indio_dev); | 356 | ret = iio_device_register(indio_dev); |
| @@ -382,9 +375,7 @@ static int hid_incl_3d_probe(struct platform_device *pdev) · 18 unmodified lines | |||
| 382 | error_iio_unreg: | 375 | error_iio_unreg: |
| 383 | iio_device_unregister(indio_dev); | 376 | iio_device_unregister(indio_dev); |
| 384 | error_remove_trigger: | 377 | error_remove_trigger: |
| 385 | hid_sensor_remove_trigger(&incl_state->common_attributes); | 378 | hid_sensor_remove_trigger(indio_dev, &incl_state->common_attributes); |
| 386 | error_unreg_buffer_funcs: | ||
| 387 | iio_triggered_buffer_cleanup(indio_dev); | ||
| 388 | error_free_dev_mem: | 379 | error_free_dev_mem: |
| 389 | kfree(indio_dev->channels); | 380 | kfree(indio_dev->channels); |
| 390 | return ret; | 381 | return ret; |
| @@ -399,8 +390,7 @@ static int hid_incl_3d_remove(struct platform_device *pdev) · 8 unmodified lines | |||
| 399 | 390 | ||
| 400 | sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_INCLINOMETER_3D); | 391 | sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_INCLINOMETER_3D); |
| 401 | iio_device_unregister(indio_dev); | 392 | iio_device_unregister(indio_dev); |
| 402 | hid_sensor_remove_trigger(&incl_state->common_attributes); | 393 | hid_sensor_remove_trigger(indio_dev, &incl_state->common_attributes); |
| 403 | iio_triggered_buffer_cleanup(indio_dev); | ||
| 404 | kfree(indio_dev->channels); | 394 | kfree(indio_dev->channels); |
| 405 | 395 | ||
| 406 | return 0; | 396 | return 0; |
| @@ -14,8 +14,6 @@ · 13 unmodified lines | |||
| 14 | #include <linux/iio/iio.h> | 14 | #include <linux/iio/iio.h> |
| 15 | #include <linux/iio/sysfs.h> | 15 | #include <linux/iio/sysfs.h> |
| 16 | #include <linux/iio/buffer.h> | 16 | #include <linux/iio/buffer.h> |
| 17 | #include <linux/iio/trigger_consumer.h> | ||
| 18 | #include <linux/iio/triggered_buffer.h> | ||
| 19 | #include "../common/hid-sensors/hid-sensor-trigger.h" | 17 | #include "../common/hid-sensors/hid-sensor-trigger.h" |
| 20 | 18 | ||
| 21 | struct dev_rot_state { | 19 | struct dev_rot_state { |
| @@ -288,18 +286,13 @@ static int hid_dev_rot_probe(struct platform_device *pdev) · 266 unmodified lines | |||
| 288 | indio_dev->name = name; | 286 | indio_dev->name = name; |
| 289 | indio_dev->modes = INDIO_DIRECT_MODE; | 287 | indio_dev->modes = INDIO_DIRECT_MODE; |
| 290 | 288 | ||
| 291 | ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, | ||
| 292 | NULL, NULL); | ||
| 293 | if (ret) { | ||
| 294 | dev_err(&pdev->dev, "failed to initialize trigger buffer\n"); | ||
| 295 | return ret; | ||
| 296 | } | ||
| 297 | atomic_set(&rot_state->common_attributes.data_ready, 0); | 289 | atomic_set(&rot_state->common_attributes.data_ready, 0); |
| 290 | |||
| 298 | ret = hid_sensor_setup_trigger(indio_dev, name, | 291 | ret = hid_sensor_setup_trigger(indio_dev, name, |
| 299 | &rot_state->common_attributes); | 292 | &rot_state->common_attributes); |
| 300 | if (ret) { | 293 | if (ret) { |
| 301 | dev_err(&pdev->dev, "trigger setup failed\n"); | 294 | dev_err(&pdev->dev, "trigger setup failed\n"); |
| 302 | goto error_unreg_buffer_funcs; | 295 | return ret; |
| 303 | } | 296 | } |
| 304 | 297 | ||
| 305 | ret = iio_device_register(indio_dev); | 298 | ret = iio_device_register(indio_dev); |
| @@ -323,9 +316,7 @@ static int hid_dev_rot_probe(struct platform_device *pdev) · 17 unmodified lines | |||
| 323 | error_iio_unreg: | 316 | error_iio_unreg: |
| 324 | iio_device_unregister(indio_dev); | 317 | iio_device_unregister(indio_dev); |
| 325 | error_remove_trigger: | 318 | error_remove_trigger: |
| 326 | hid_sensor_remove_trigger(&rot_state->common_attributes); | 319 | hid_sensor_remove_trigger(indio_dev, &rot_state->common_attributes); |
| 327 | error_unreg_buffer_funcs: | ||
| 328 | iio_triggered_buffer_cleanup(indio_dev); | ||
| 329 | return ret; | 320 | return ret; |
| 330 | } | 321 | } |
| 331 | 322 | ||
| @@ -338,8 +329,7 @@ static int hid_dev_rot_remove(struct platform_device *pdev) · 6 unmodified lines | |||
| 338 | 329 | ||
| 339 | sensor_hub_remove_callback(hsdev, hsdev->usage); | 330 | sensor_hub_remove_callback(hsdev, hsdev->usage); |
| 340 | iio_device_unregister(indio_dev); | 331 | iio_device_unregister(indio_dev); |
| 341 | hid_sensor_remove_trigger(&rot_state->common_attributes); | 332 | hid_sensor_remove_trigger(indio_dev, &rot_state->common_attributes); |
| 342 | iio_triggered_buffer_cleanup(indio_dev); | ||
| 343 | 333 | ||
| 344 | return 0; | 334 | return 0; |
| 345 | } | 335 | } |
| @@ -271,6 +271,8 @@ static u32 bmp280_compensate_humidity(struct bmp280_data *data, · 270 unmodified lines | |||
| 271 | + (s32)2097152) * calib->H2 + 8192) >> 14); | 271 | + (s32)2097152) * calib->H2 + 8192) >> 14); |
| 272 | var -= ((((var >> 15) * (var >> 15)) >> 7) * (s32)calib->H1) >> 4; | 272 | var -= ((((var >> 15) * (var >> 15)) >> 7) * (s32)calib->H1) >> 4; |
| 273 | 273 | ||
| 274 | var = clamp_val(var, 0, 419430400); | ||
| 275 | |||
| 274 | return var >> 12; | 276 | return var >> 12; |
| 275 | }; | 277 | }; |
| 276 | 278 | ||
| @@ -14,8 +14,6 @@ · 13 unmodified lines | |||
| 14 | #include <linux/iio/iio.h> | 14 | #include <linux/iio/iio.h> |
| 15 | #include <linux/iio/sysfs.h> | 15 | #include <linux/iio/sysfs.h> |
| 16 | #include <linux/iio/buffer.h> | 16 | #include <linux/iio/buffer.h> |
| 17 | #include <linux/iio/trigger_consumer.h> | ||
| 18 | #include <linux/iio/triggered_buffer.h> | ||
| 19 | #include "../common/hid-sensors/hid-sensor-trigger.h" | 17 | #include "../common/hid-sensors/hid-sensor-trigger.h" |
| 20 | 18 | ||
| 21 | #define CHANNEL_SCAN_INDEX_PRESSURE 0 | 19 | #define CHANNEL_SCAN_INDEX_PRESSURE 0 |
| @@ -290,18 +288,13 @@ static int hid_press_probe(struct platform_device *pdev) · 268 unmodified lines | |||
| 290 | indio_dev->name = name; | 288 | indio_dev->name = name; |
| 291 | indio_dev->modes = INDIO_DIRECT_MODE; | 289 | indio_dev->modes = INDIO_DIRECT_MODE; |
| 292 | 290 | ||
| 293 | ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, | ||
| 294 | NULL, NULL); | ||
| 295 | if (ret) { | ||
| 296 | dev_err(&pdev->dev, "failed to initialize trigger buffer\n"); | ||
| 297 | goto error_free_dev_mem; | ||
| 298 | } | ||
| 299 | atomic_set(&press_state->common_attributes.data_ready, 0); | 291 | atomic_set(&press_state->common_attributes.data_ready, 0); |
| 292 | |||
| 300 | ret = hid_sensor_setup_trigger(indio_dev, name, | 293 | ret = hid_sensor_setup_trigger(indio_dev, name, |
| 301 | &press_state->common_attributes); | 294 | &press_state->common_attributes); |
| 302 | if (ret) { | 295 | if (ret) { |
| 303 | dev_err(&pdev->dev, "trigger setup failed\n"); | 296 | dev_err(&pdev->dev, "trigger setup failed\n"); |
| 304 | goto error_unreg_buffer_funcs; | 297 | goto error_free_dev_mem; |
| 305 | } | 298 | } |
| 306 | 299 | ||
| 307 | ret = iio_device_register(indio_dev); | 300 | ret = iio_device_register(indio_dev); |
| @@ -325,9 +318,7 @@ static int hid_press_probe(struct platform_device *pdev) · 17 unmodified lines | |||
| 325 | error_iio_unreg: | 318 | error_iio_unreg: |
| 326 | iio_device_unregister(indio_dev); | 319 | iio_device_unregister(indio_dev); |
| 327 | error_remove_trigger: | 320 | error_remove_trigger: |
| 328 | hid_sensor_remove_trigger(&press_state->common_attributes); | 321 | hid_sensor_remove_trigger(indio_dev, &press_state->common_attributes); |
| 329 | error_unreg_buffer_funcs: | ||
| 330 | iio_triggered_buffer_cleanup(indio_dev); | ||
| 331 | error_free_dev_mem: | 322 | error_free_dev_mem: |
| 332 | kfree(indio_dev->channels); | 323 | kfree(indio_dev->channels); |
| 333 | return ret; | 324 | return ret; |
| @@ -342,8 +333,7 @@ static int hid_press_remove(struct platform_device *pdev) · 8 unmodified lines | |||
| 342 | 333 | ||
| 343 | sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_PRESSURE); | 334 | sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_PRESSURE); |
| 344 | iio_device_unregister(indio_dev); | 335 | iio_device_unregister(indio_dev); |
| 345 | hid_sensor_remove_trigger(&press_state->common_attributes); | 336 | hid_sensor_remove_trigger(indio_dev, &press_state->common_attributes); |
| 346 | iio_triggered_buffer_cleanup(indio_dev); | ||
| 347 | kfree(indio_dev->channels); | 337 | kfree(indio_dev->channels); |
| 348 | 338 | ||
| 349 | return 0; | 339 | return 0; |
| @@ -18,6 +18,8 @@ · 17 unmodified lines | |||
| 18 | #include <linux/util_macros.h> | 18 | #include <linux/util_macros.h> |
| 19 | #include <linux/acpi.h> | 19 | #include <linux/acpi.h> |
| 20 | 20 | ||
| 21 | #include <asm/unaligned.h> | ||
| 22 | |||
| 21 | /* I2C commands: */ | 23 | /* I2C commands: */ |
| 22 | #define HP206C_CMD_SOFT_RST 0x06 | 24 | #define HP206C_CMD_SOFT_RST 0x06 |
| 23 | 25 | ||
| @@ -93,12 +95,12 @@ static int hp206c_read_20bit(struct i2c_client *client, u8 cmd) · 69 unmodified lines | |||
| 93 | int ret; | 95 | int ret; |
| 94 | u8 values[3]; | 96 | u8 values[3]; |
| 95 | 97 | ||
| 96 | ret = i2c_smbus_read_i2c_block_data(client, cmd, 3, values); | 98 | ret = i2c_smbus_read_i2c_block_data(client, cmd, sizeof(values), values); |
| 97 | if (ret < 0) | 99 | if (ret < 0) |
| 98 | return ret; | 100 | return ret; |
| 99 | if (ret != 3) | 101 | if (ret != sizeof(values)) |
| 100 | return -EIO; | 102 | return -EIO; |
| 101 | return ((values[0] & 0xF) << 16) | (values[1] << 8) | (values[2]); | 103 | return get_unaligned_be24(&values[0]) & GENMASK(19, 0); |
| 102 | } | 104 | } |
| 103 | 105 | ||
| 104 | /* Spin for max 160ms until DEV_RDY is 1, or return error. */ | 106 | /* Spin for max 160ms until DEV_RDY is 1, or return error. */ |
| @@ -16,6 +16,8 @@ · 15 unmodified lines | |||
| 16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
| 17 | #include <linux/of_device.h> | 17 | #include <linux/of_device.h> |
| 18 | 18 | ||
| 19 | #include <asm/unaligned.h> | ||
| 20 | |||
| 19 | #include "ms5611.h" | 21 | #include "ms5611.h" |
| 20 | 22 | ||
| 21 | static int ms5611_i2c_reset(struct device *dev) | 23 | static int ms5611_i2c_reset(struct device *dev) |
| @@ -50,7 +52,7 @@ static int ms5611_i2c_read_adc(struct ms5611_state *st, s32 *val) · 28 unmodified lines | |||
| 50 | if (ret < 0) | 52 | if (ret < 0) |
| 51 | return ret; | 53 | return ret; |
| 52 | 54 | ||
| 53 | *val = (buf[0] << 16) | (buf[1] << 8) | buf[2]; | 55 | *val = get_unaligned_be24(&buf[0]); |
| 54 | 56 | ||
| 55 | return 0; | 57 | return 0; |
| 56 | } | 58 | } |
| @@ -11,6 +11,8 @@ · 10 unmodified lines | |||
| 11 | #include <linux/spi/spi.h> | 11 | #include <linux/spi/spi.h> |
| 12 | #include <linux/of_device.h> | 12 | #include <linux/of_device.h> |
| 13 | 13 | ||
| 14 | #include <asm/unaligned.h> | ||
| 15 | |||
| 14 | #include "ms5611.h" | 16 | #include "ms5611.h" |
| 15 | 17 | ||
| 16 | static int ms5611_spi_reset(struct device *dev) | 18 | static int ms5611_spi_reset(struct device *dev) |
| @@ -45,7 +47,7 @@ static int ms5611_spi_read_adc(struct device *dev, s32 *val) · 28 unmodified lines | |||
| 45 | if (ret < 0) | 47 | if (ret < 0) |
| 46 | return ret; | 48 | return ret; |
| 47 | 49 | ||
| 48 | *val = (buf[0] << 16) | (buf[1] << 8) | buf[2]; | 50 | *val = get_unaligned_be24(&buf[0]); |
| 49 | 51 | ||
| 50 | return 0; | 52 | return 0; |
| 51 | } | 53 | } |
| @@ -64,6 +64,7 @@ · 63 unmodified lines | |||
| 64 | #include <linux/iio/trigger.h> | 64 | #include <linux/iio/trigger.h> |
| 65 | #include <linux/iio/trigger_consumer.h> | 65 | #include <linux/iio/trigger_consumer.h> |
| 66 | #include <linux/iio/triggered_buffer.h> | 66 | #include <linux/iio/triggered_buffer.h> |
| 67 | #include <asm/unaligned.h> | ||
| 67 | #include "zpa2326.h" | 68 | #include "zpa2326.h" |
| 68 | 69 | ||
| 69 | /* 200 ms should be enough for the longest conversion time in one-shot mode. */ | 70 | /* 200 ms should be enough for the longest conversion time in one-shot mode. */ |
| @@ -1005,22 +1006,20 @@ static int zpa2326_fetch_raw_sample(const struct iio_dev *indio_dev, · 935 unmodified lines | |||
| 1005 | struct regmap *regs = ((struct zpa2326_private *) | 1006 | struct regmap *regs = ((struct zpa2326_private *) |
| 1006 | iio_priv(indio_dev))->regmap; | 1007 | iio_priv(indio_dev))->regmap; |
| 1007 | int err; | 1008 | int err; |
| 1009 | u8 v[3]; | ||
| 1008 | 1010 | ||
| 1009 | switch (type) { | 1011 | switch (type) { |
| 1010 | case IIO_PRESSURE: | 1012 | case IIO_PRESSURE: |
| 1011 | zpa2326_dbg(indio_dev, "fetching raw pressure sample"); | 1013 | zpa2326_dbg(indio_dev, "fetching raw pressure sample"); |
| 1012 | 1014 | ||
| 1013 | err = regmap_bulk_read(regs, ZPA2326_PRESS_OUT_XL_REG, value, | 1015 | err = regmap_bulk_read(regs, ZPA2326_PRESS_OUT_XL_REG, v, sizeof(v)); |
| 1014 | 3); | ||
| 1015 | if (err) { | 1016 | if (err) { |
| 1016 | zpa2326_warn(indio_dev, "failed to fetch pressure (%d)", | 1017 | zpa2326_warn(indio_dev, "failed to fetch pressure (%d)", |
| 1017 | err); | 1018 | err); |
| 1018 | return err; | 1019 | return err; |
| 1019 | } | 1020 | } |
| 1020 | 1021 | ||
| 1021 | /* Pressure is a 24 bits wide little-endian unsigned int. */ | 1022 | *value = get_unaligned_le24(&v[0]); |
| 1022 | *value = (((u8 *)value)[2] << 16) | (((u8 *)value)[1] << 8) | | ||
| 1023 | ((u8 *)value)[0]; | ||
| 1024 | 1023 | ||
| 1025 | return IIO_VAL_INT; | 1024 | return IIO_VAL_INT; |
| 1026 | 1025 | ||
| @@ -7,8 +7,6 @@ · 6 unmodified lines | |||
| 7 | #include <linux/hid-sensor-hub.h> | 7 | #include <linux/hid-sensor-hub.h> |
| 8 | #include <linux/iio/buffer.h> | 8 | #include <linux/iio/buffer.h> |
| 9 | #include <linux/iio/iio.h> | 9 | #include <linux/iio/iio.h> |
| 10 | #include <linux/iio/triggered_buffer.h> | ||
| 11 | #include <linux/iio/trigger_consumer.h> | ||
| 12 | #include <linux/module.h> | 10 | #include <linux/module.h> |
| 13 | #include <linux/platform_device.h> | 11 | #include <linux/platform_device.h> |
| 14 | 12 | ||
| @@ -230,12 +228,8 @@ static int hid_temperature_probe(struct platform_device *pdev) · 215 unmodified lines | |||
| 230 | indio_dev->name = name; | 228 | indio_dev->name = name; |
| 231 | indio_dev->modes = INDIO_DIRECT_MODE; | 229 | indio_dev->modes = INDIO_DIRECT_MODE; |
| 232 | 230 | ||
| 233 | ret = devm_iio_triggered_buffer_setup(&pdev->dev, indio_dev, | ||
| 234 | &iio_pollfunc_store_time, NULL, NULL); | ||
| 235 | if (ret) | ||
| 236 | return ret; | ||
| 237 | |||
| 238 | atomic_set(&temp_st->common_attributes.data_ready, 0); | 231 | atomic_set(&temp_st->common_attributes.data_ready, 0); |
| 232 | |||
| 239 | ret = hid_sensor_setup_trigger(indio_dev, name, | 233 | ret = hid_sensor_setup_trigger(indio_dev, name, |
| 240 | &temp_st->common_attributes); | 234 | &temp_st->common_attributes); |
| 241 | if (ret) | 235 | if (ret) |
| @@ -258,7 +252,7 @@ static int hid_temperature_probe(struct platform_device *pdev) · 16 unmodified lines | |||
| 258 | error_remove_callback: | 252 | error_remove_callback: |
| 259 | sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TEMPERATURE); | 253 | sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TEMPERATURE); |
| 260 | error_remove_trigger: | 254 | error_remove_trigger: |
| 261 | hid_sensor_remove_trigger(&temp_st->common_attributes); | 255 | hid_sensor_remove_trigger(indio_dev, &temp_st->common_attributes); |
| 262 | return ret; | 256 | return ret; |
| 263 | } | 257 | } |
| 264 | 258 | ||
| @@ -270,7 +264,7 @@ static int hid_temperature_remove(struct platform_device *pdev) · 5 unmodified lines | |||
| 270 | struct temperature_state *temp_st = iio_priv(indio_dev); | 264 | struct temperature_state *temp_st = iio_priv(indio_dev); |
| 271 | 265 | ||
| 272 | sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TEMPERATURE); | 266 | sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TEMPERATURE); |
| 273 | hid_sensor_remove_trigger(&temp_st->common_attributes); | 267 | hid_sensor_remove_trigger(indio_dev, &temp_st->common_attributes); |
| 274 | 268 | ||
| 275 | return 0; | 269 | return 0; |
| 276 | } | 270 | } |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | |||
| 14 | #include <linux/iio/iio.h> | 14 | #include <linux/iio/iio.h> |
| 15 | #include <linux/iio/sysfs.h> | 15 | #include <linux/iio/sysfs.h> |
| 16 | #include <linux/util_macros.h> | 16 | #include <linux/util_macros.h> |
| 17 | #include <asm/unaligned.h> | ||
| 17 | #include <dt-bindings/iio/temperature/thermocouple.h> | 18 | #include <dt-bindings/iio/temperature/thermocouple.h> |
| 18 | /* | 19 | /* |
| 19 | * The MSB of the register value determines whether the following byte will | 20 | * The MSB of the register value determines whether the following byte will |
| @@ -168,7 +169,7 @@ static int max31856_thermocouple_read(struct max31856_data *data, · 148 unmodified lines | |||
| 168 | if (ret) | 169 | if (ret) |
| 169 | return ret; | 170 | return ret; |
| 170 | /* Skip last 5 dead bits of LTCBL */ | 171 | /* Skip last 5 dead bits of LTCBL */ |
| 171 | *val = (reg_val[0] << 16 | reg_val[1] << 8 | reg_val[2]) >> 5; | 172 | *val = get_unaligned_be24(®_val[0]) >> 5; |
| 172 | /* Check 7th bit of LTCBH reg. value for sign*/ | 173 | /* Check 7th bit of LTCBH reg. value for sign*/ |
| 173 | if (reg_val[0] & 0x80) | 174 | if (reg_val[0] & 0x80) |
| 174 | *val -= 0x80000; | 175 | *val -= 0x80000; |
| @@ -185,7 +186,7 @@ static int max31856_thermocouple_read(struct max31856_data *data, · 10 unmodified lines | |||
| 185 | /* Get Cold Junction Temp. offset register value */ | 186 | /* Get Cold Junction Temp. offset register value */ |
| 186 | offset_cjto = reg_val[0]; | 187 | offset_cjto = reg_val[0]; |
| 187 | /* Get CJTH and CJTL value and skip last 2 dead bits of CJTL */ | 188 | /* Get CJTH and CJTL value and skip last 2 dead bits of CJTL */ |
| 188 | *val = (reg_val[1] << 8 | reg_val[2]) >> 2; | 189 | *val = get_unaligned_be16(®_val[1]) >> 2; |
| 189 | /* As per datasheet add offset into CJTH and CJTL */ | 190 | /* As per datasheet add offset into CJTH and CJTL */ |
| 190 | *val += offset_cjto; | 191 | *val += offset_cjto; |
| 191 | /* Check 7th bit of CJTH reg. value for sign */ | 192 | /* Check 7th bit of CJTH reg. value for sign */ |
| @@ -602,11 +602,12 @@ static const struct iio_buffer_setup_ops ad5933_ring_setup_ops = { · 601 unmodified lines | |||
| 602 | .postdisable = ad5933_ring_postdisable, | 602 | .postdisable = ad5933_ring_postdisable, |
| 603 | }; | 603 | }; |
| 604 | 604 | ||
| 605 | static int ad5933_register_ring_funcs_and_init(struct iio_dev *indio_dev) | 605 | static int ad5933_register_ring_funcs_and_init(struct device *dev, |
| 606 | struct iio_dev *indio_dev) | ||
| 606 | { | 607 | { |
| 607 | struct iio_buffer *buffer; | 608 | struct iio_buffer *buffer; |
| 608 | 609 | ||
| 609 | buffer = iio_kfifo_allocate(); | 610 | buffer = devm_iio_kfifo_allocate(dev); |
| 610 | if (!buffer) | 611 | if (!buffer) |
| 611 | return -ENOMEM; | 612 | return -ENOMEM; |
| 612 | 613 | ||
| @@ -676,6 +677,20 @@ static void ad5933_work(struct work_struct *work) · 63 unmodified lines | |||
| 676 | } | 677 | } |
| 677 | } | 678 | } |
| 678 | 679 | ||
| 680 | static void ad5933_reg_disable(void *data) | ||
| 681 | { | ||
| 682 | struct ad5933_state *st = data; | ||
| 683 | |||
| 684 | regulator_disable(st->reg); | ||
| 685 | } | ||
| 686 | |||
| 687 | static void ad5933_clk_disable(void *data) | ||
| 688 | { | ||
| 689 | struct ad5933_state *st = data; | ||
| 690 | |||
| 691 | clk_disable_unprepare(st->mclk); | ||
| 692 | } | ||
| 693 | |||
| 679 | static int ad5933_probe(struct i2c_client *client, | 694 | static int ad5933_probe(struct i2c_client *client, |
| 680 | const struct i2c_device_id *id) | 695 | const struct i2c_device_id *id) |
| 681 | { | 696 | { |
| @@ -703,23 +718,32 @@ static int ad5933_probe(struct i2c_client *client, · 21 unmodified lines | |||
| 703 | dev_err(&client->dev, "Failed to enable specified VDD supply\n"); | 718 | dev_err(&client->dev, "Failed to enable specified VDD supply\n"); |
| 704 | return ret; | 719 | return ret; |
| 705 | } | 720 | } |
| 706 | ret = regulator_get_voltage(st->reg); | ||
| 707 | 721 | ||
| 722 | ret = devm_add_action_or_reset(&client->dev, ad5933_reg_disable, st); | ||
| 723 | if (ret) | ||
| 724 | return ret; | ||
| 725 | |||
| 726 | ret = regulator_get_voltage(st->reg); | ||
| 708 | if (ret < 0) | 727 | if (ret < 0) |
| 709 | goto error_disable_reg; | 728 | return ret; |
| 710 | 729 | ||
| 711 | st->vref_mv = ret / 1000; | 730 | st->vref_mv = ret / 1000; |
| 712 | 731 | ||
| 713 | st->mclk = devm_clk_get(&client->dev, "mclk"); | 732 | st->mclk = devm_clk_get(&client->dev, "mclk"); |
| 714 | if (IS_ERR(st->mclk) && PTR_ERR(st->mclk) != -ENOENT) { | 733 | if (IS_ERR(st->mclk) && PTR_ERR(st->mclk) != -ENOENT) |
| 715 | ret = PTR_ERR(st->mclk); | 734 | return PTR_ERR(st->mclk); |
| 716 | goto error_disable_reg; | ||
| 717 | } | ||
| 718 | 735 | ||
| 719 | if (!IS_ERR(st->mclk)) { | 736 | if (!IS_ERR(st->mclk)) { |
| 720 | ret = clk_prepare_enable(st->mclk); | 737 | ret = clk_prepare_enable(st->mclk); |
| 721 | if (ret < 0) | 738 | if (ret < 0) |
| 722 | goto error_disable_reg; | 739 | return ret; |
| 740 | |||
| 741 | ret = devm_add_action_or_reset(&client->dev, | ||
| 742 | ad5933_clk_disable, | ||
| 743 | st); | ||
| 744 | if (ret) | ||
| 745 | return ret; | ||
| 746 | |||
| 723 | ext_clk_hz = clk_get_rate(st->mclk); | 747 | ext_clk_hz = clk_get_rate(st->mclk); |
| 724 | } | 748 | } |
| 725 | 749 | ||
| @@ -742,41 +766,15 @@ static int ad5933_probe(struct i2c_client *client, · 16 unmodified lines | |||
| 742 | indio_dev->channels = ad5933_channels; | 766 | indio_dev->channels = ad5933_channels; |
| 743 | indio_dev->num_channels = ARRAY_SIZE(ad5933_channels); | 767 | indio_dev->num_channels = ARRAY_SIZE(ad5933_channels); |
| 744 | 768 | ||
| 745 | ret = ad5933_register_ring_funcs_and_init(indio_dev); | 769 | ret = ad5933_register_ring_funcs_and_init(&client->dev, indio_dev); |
| 746 | if (ret) | 770 | if (ret) |
| 747 | goto error_disable_mclk; | 771 | return ret; |
| 748 | 772 | ||
| 749 | ret = ad5933_setup(st); | 773 | ret = ad5933_setup(st); |
| 750 | if (ret) | 774 | if (ret) |
| 751 | goto error_unreg_ring; | 775 | return ret; |
| 752 | |||
| 753 | ret = iio_device_register(indio_dev); | ||
| 754 | if (ret) | ||
| 755 | goto error_unreg_ring; | ||
| 756 | |||
| 757 | return 0; | ||
| 758 | |||
| 759 | error_unreg_ring: | ||
| 760 | iio_kfifo_free(indio_dev->buffer); | ||
| 761 | error_disable_mclk: | ||
| 762 | clk_disable_unprepare(st->mclk); | ||
| 763 | error_disable_reg: | ||
| 764 | regulator_disable(st->reg); | ||
| 765 | |||
| 766 | return ret; | ||
| 767 | } | ||
| 768 | |||
| 769 | static int ad5933_remove(struct i2c_client *client) | ||
| 770 | { | ||
| 771 | struct iio_dev *indio_dev = i2c_get_clientdata(client); | ||
| 772 | struct ad5933_state *st = iio_priv(indio_dev); | ||
| 773 | |||
| 774 | iio_device_unregister(indio_dev); | ||
| 775 | iio_kfifo_free(indio_dev->buffer); | ||
| 776 | regulator_disable(st->reg); | ||
| 777 | clk_disable_unprepare(st->mclk); | ||
| 778 | 776 | ||
| 779 | return 0; | 777 | return devm_iio_device_register(&client->dev, indio_dev); |
| 780 | } | 778 | } |
| 781 | 779 | ||
| 782 | static const struct i2c_device_id ad5933_id[] = { | 780 | static const struct i2c_device_id ad5933_id[] = { |
| @@ -801,7 +799,6 @@ static struct i2c_driver ad5933_driver = { · 18 unmodified lines | |||
| 801 | .of_match_table = ad5933_of_match, | 799 | .of_match_table = ad5933_of_match, |
| 802 | }, | 800 | }, |
| 803 | .probe = ad5933_probe, | 801 | .probe = ad5933_probe, |
| 804 | .remove = ad5933_remove, | ||
| 805 | .id_table = ad5933_id, | 802 | .id_table = ad5933_id, |
| 806 | }; | 803 | }; |
| 807 | module_i2c_driver(ad5933_driver); | 804 | module_i2c_driver(ad5933_driver); |
| @@ -83,10 +83,13 @@ struct adis_data { · 82 unmodified lines | |||
| 83 | * @trig: IIO trigger object data | 83 | * @trig: IIO trigger object data |
| 84 | * @data: ADIS chip variant specific data | 84 | * @data: ADIS chip variant specific data |
| 85 | * @burst: ADIS burst transfer information | 85 | * @burst: ADIS burst transfer information |
| 86 | * @burst_extra_len: Burst extra length. Should only be used by devices that can | ||
| 87 | * dynamically change their burst mode length. | ||
| 86 | * @state_lock: Lock used by the device to protect state | 88 | * @state_lock: Lock used by the device to protect state |
| 87 | * @msg: SPI message object | 89 | * @msg: SPI message object |
| 88 | * @xfer: SPI transfer objects to be used for a @msg | 90 | * @xfer: SPI transfer objects to be used for a @msg |
| 89 | * @current_page: Some ADIS devices have registers, this selects current page | 91 | * @current_page: Some ADIS devices have registers, this selects current page |
| 92 | * @irq_flag: IRQ handling flags as passed to request_irq() | ||
| 90 | * @buffer: Data buffer for information read from the device | 93 | * @buffer: Data buffer for information read from the device |
| 91 | * @tx: DMA safe TX buffer for SPI transfers | 94 | * @tx: DMA safe TX buffer for SPI transfers |
| 92 | * @rx: DMA safe RX buffer for SPI transfers | 95 | * @rx: DMA safe RX buffer for SPI transfers |
| @@ -97,7 +100,7 @@ struct adis { · 4 unmodified lines | |||
| 97 | 100 | ||
| 98 | const struct adis_data *data; | 101 | const struct adis_data *data; |
| 99 | struct adis_burst *burst; | 102 | struct adis_burst *burst; |
| 100 | 103 | unsigned int burst_extra_len; | |
| 101 | /** | 104 | /** |
| 102 | * The state_lock is meant to be used during operations that require | 105 | * The state_lock is meant to be used during operations that require |
| 103 | * a sequence of SPI R/W in order to protect the SPI transfer | 106 | * a sequence of SPI R/W in order to protect the SPI transfer |
| @@ -113,6 +116,7 @@ struct adis { · 9 unmodified lines | |||
| 113 | struct spi_message msg; | 116 | struct spi_message msg; |
| 114 | struct spi_transfer *xfer; | 117 | struct spi_transfer *xfer; |
| 115 | unsigned int current_page; | 118 | unsigned int current_page; |
| 119 | unsigned long irq_flag; | ||
| 116 | void *buffer; | 120 | void *buffer; |
| 117 | 121 | ||
| 118 | uint8_t tx[10] ____cacheline_aligned; | 122 | uint8_t tx[10] ____cacheline_aligned; |
| @@ -331,6 +335,65 @@ static inline int adis_read_reg_32(struct adis *adis, unsigned int reg, · 212 unmodified lines | |||
| 331 | return ret; | 335 | return ret; |
| 332 | } | 336 | } |
| 333 | 337 | ||
| 338 | int __adis_update_bits_base(struct adis *adis, unsigned int reg, const u32 mask, | ||
| 339 | const u32 val, u8 size); | ||
| 340 | /** | ||
| 341 | * adis_update_bits_base() - ADIS Update bits function - Locked version | ||
| 342 | * @adis: The adis device | ||
| 343 | * @reg: The address of the lower of the two registers | ||
| 344 | * @mask: Bitmask to change | ||
| 345 | * @val: Value to be written | ||
| 346 | * @size: Size of the register to update | ||
| 347 | * | ||
| 348 | * Updates the desired bits of @reg in accordance with @mask and @val. | ||
| 349 | */ | ||
| 350 | static inline int adis_update_bits_base(struct adis *adis, unsigned int reg, | ||
| 351 | const u32 mask, const u32 val, u8 size) | ||
| 352 | { | ||
| 353 | int ret; | ||
| 354 | |||
| 355 | mutex_lock(&adis->state_lock); | ||
| 356 | ret = __adis_update_bits_base(adis, reg, mask, val, size); | ||
| 357 | mutex_unlock(&adis->state_lock); | ||
| 358 | return ret; | ||
| 359 | } | ||
| 360 | |||
| 361 | /** | ||
| 362 | * adis_update_bits() - Wrapper macro for adis_update_bits_base - Locked version | ||
| 363 | * @adis: The adis device | ||
| 364 | * @reg: The address of the lower of the two registers | ||
| 365 | * @mask: Bitmask to change | ||
| 366 | * @val: Value to be written | ||
| 367 | * | ||
| 368 | * This macro evaluates the sizeof of @val at compile time and calls | ||
| 369 | * adis_update_bits_base() accordingly. Be aware that using MACROS/DEFINES for | ||
| 370 | * @val can lead to undesired behavior if the register to update is 16bit. | ||
| 371 | */ | ||
| 372 | #define adis_update_bits(adis, reg, mask, val) ({ \ | ||
| 373 | BUILD_BUG_ON(sizeof(val) == 1 || sizeof(val) == 8); \ | ||
| 374 | __builtin_choose_expr(sizeof(val) == 4, \ | ||
| 375 | adis_update_bits_base(adis, reg, mask, val, 4), \ | ||
| 376 | adis_update_bits_base(adis, reg, mask, val, 2)); \ | ||
| 377 | }) | ||
| 378 | |||
| 379 | /** | ||
| 380 | * adis_update_bits() - Wrapper macro for adis_update_bits_base | ||
| 381 | * @adis: The adis device | ||
| 382 | * @reg: The address of the lower of the two registers | ||
| 383 | * @mask: Bitmask to change | ||
| 384 | * @val: Value to be written | ||
| 385 | * | ||
| 386 | * This macro evaluates the sizeof of @val at compile time and calls | ||
| 387 | * adis_update_bits_base() accordingly. Be aware that using MACROS/DEFINES for | ||
| 388 | * @val can lead to undesired behavior if the register to update is 16bit. | ||
| 389 | */ | ||
| 390 | #define __adis_update_bits(adis, reg, mask, val) ({ \ | ||
| 391 | BUILD_BUG_ON(sizeof(val) == 1 || sizeof(val) == 8); \ | ||
| 392 | __builtin_choose_expr(sizeof(val) == 4, \ | ||
| 393 | __adis_update_bits_base(adis, reg, mask, val, 4), \ | ||
| 394 | __adis_update_bits_base(adis, reg, mask, val, 2)); \ | ||
| 395 | }) | ||
| 396 | |||
| 334 | int adis_enable_irq(struct adis *adis, bool enable); | 397 | int adis_enable_irq(struct adis *adis, bool enable); |
| 335 | int __adis_check_status(struct adis *adis); | 398 | int __adis_check_status(struct adis *adis); |
| 336 | int __adis_initial_startup(struct adis *adis); | 399 | int __adis_initial_startup(struct adis *adis); |
| @@ -441,18 +504,25 @@ int adis_single_conversion(struct iio_dev *indio_dev, · 104 unmodified lines | |||
| 441 | * @en burst mode enabled | 504 | * @en burst mode enabled |
| 442 | * @reg_cmd register command that triggers burst | 505 | * @reg_cmd register command that triggers burst |
| 443 | * @extra_len extra length to account in the SPI RX buffer | 506 | * @extra_len extra length to account in the SPI RX buffer |
| 507 | * @burst_max_len holds the maximum burst size when the device supports | ||
| 508 | * more than one burst mode with different sizes | ||
| 444 | */ | 509 | */ |
| 445 | struct adis_burst { | 510 | struct adis_burst { |
| 446 | bool en; | 511 | bool en; |
| 447 | unsigned int reg_cmd; | 512 | unsigned int reg_cmd; |
| 448 | unsigned int extra_len; | 513 | const u32 extra_len; |
| 514 | const u32 burst_max_len; | ||
| 449 | }; | 515 | }; |
| 450 | 516 | ||
| 517 | int | ||
| 518 | devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, | ||
| 519 | irq_handler_t trigger_handler); | ||
| 451 | int adis_setup_buffer_and_trigger(struct adis *adis, | 520 | int adis_setup_buffer_and_trigger(struct adis *adis, |
| 452 | struct iio_dev *indio_dev, irqreturn_t (*trigger_handler)(int, void *)); | 521 | struct iio_dev *indio_dev, irqreturn_t (*trigger_handler)(int, void *)); |
| 453 | void adis_cleanup_buffer_and_trigger(struct adis *adis, | 522 | void adis_cleanup_buffer_and_trigger(struct adis *adis, |
| 454 | struct iio_dev *indio_dev); | 523 | struct iio_dev *indio_dev); |
| 455 | 524 | ||
| 525 | int devm_adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev); | ||
| 456 | int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev); | 526 | int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev); |
| 457 | void adis_remove_trigger(struct adis *adis); | 527 | void adis_remove_trigger(struct adis *adis); |
| 458 | 528 | ||
| @@ -461,6 +531,13 @@ int adis_update_scan_mode(struct iio_dev *indio_dev, · 2 unmodified lines | |||
| 461 | 531 | ||
| 462 | #else /* CONFIG_IIO_BUFFER */ | 532 | #else /* CONFIG_IIO_BUFFER */ |
| 463 | 533 | ||
| 534 | static inline int | ||
| 535 | devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, | ||
| 536 | irq_handler_t trigger_handler) | ||
| 537 | { | ||
| 538 | return 0; | ||
| 539 | } | ||
| 540 | |||
| 464 | static inline int adis_setup_buffer_and_trigger(struct adis *adis, | 541 | static inline int adis_setup_buffer_and_trigger(struct adis *adis, |
| 465 | struct iio_dev *indio_dev, irqreturn_t (*trigger_handler)(int, void *)) | 542 | struct iio_dev *indio_dev, irqreturn_t (*trigger_handler)(int, void *)) |
| 466 | { | 543 | { |
| @@ -472,6 +549,12 @@ static inline void adis_cleanup_buffer_and_trigger(struct adis *adis, · 5 unmodified lines | |||
| 472 | { | 549 | { |
| 473 | } | 550 | } |
| 474 | 551 | ||
| 552 | static inline int devm_adis_probe_trigger(struct adis *adis, | ||
| 553 | struct iio_dev *indio_dev) | ||
| 554 | { | ||
| 555 | return 0; | ||
| 556 | } | ||
| 557 | |||
| 475 | static inline int adis_probe_trigger(struct adis *adis, | 558 | static inline int adis_probe_trigger(struct adis *adis, |
| 476 | struct iio_dev *indio_dev) | 559 | struct iio_dev *indio_dev) |
| 477 | { | 560 | { |