Pull staging / IIO driver updates from Greg KH: "Here is the large set of staging and IIO driver updates for 5.10-rc1. Included in here are: - new IIO drivers - new IIO driver frameworks - various IIO driver fixes and updates - IIO device tree conversions to yaml - so many minor staging driver coding style cleanups - most cdev driver moved out of staging - no staging drivers added or removed Full details are in the shortlog. All of these have been in linux-next for a while with no reported issues" * tag 'staging-5.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (476 commits) staging: comedi: check validity of wMaxPacketSize of usb endpoints found staging: wfx: improve robustness of wfx_get_hw_rate() staging: wfx: drop unicode characters from strings staging: wfx: gpiod_get_value() can return an error staging: wfx: increase robustness of hif_generic_confirm() staging: wfx: wfx_init_common() returns NULL on error staging: wfx: standardize the error when vif does not exist staging: wfx: check memory allocation staging: wfx: improve error handling of hif_join() staging: dpaa2-switch: add a dpaa2_switch prefix to all functions in ethsw.c staging: dpaa2-switch: add a dpaa2_switch_ prefix to all functions in ethsw-ethtool.c staging: rtl8188eu: Fix long lines dt-bindings: staging: wfx: silabs,wfx yaml conversion staging: wfx: update copyrights dates staging: wfx: fix QoS priority for slow buses staging: wfx: fix BA sessions for older firmwares staging: wfx: remove remaining code of 'secure link' feature staging: wfx: fix handling of MMIC error staging: vchiq: Fix list_for_each exit tests staging: greybus: use __force when assigning __u8 value to snd_ctl_elem_type_t ...
Unified · Split
| @@ -1942,6 +1942,10 @@ S: Post Office Box 611311 · 1941 unmodified lines | ||
| 1942 | 1942 | S: San Jose, California 95161-1311 |
| 1943 | 1943 | S: USA |
| 1944 | 1944 | |
| 1945 | +N: Hartmut Knaack | |
| 1946 | +E: knaack.h@gmx.de | |
| 1947 | +D: IIO subsystem and drivers | |
| 1948 | + | |
| 1945 | 1949 | N: Thorsten Knabe |
| 1946 | 1950 | E: Thorsten Knabe <tek@rbg.informatik.tu-darmstadt.de> |
| 1947 | 1951 | E: Thorsten Knabe <tek01@hrzpub.tu-darmstadt.de> |
| @@ -40,6 +40,7 @@ Description: · 39 unmodified lines | ||
| 40 | 40 | buffered samples and events for device X. |
| 41 | 41 | |
| 42 | 42 | What: /sys/bus/iio/devices/iio:deviceX/sampling_frequency |
| 43 | +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_sampling_frequency | |
| 43 | 44 | What: /sys/bus/iio/devices/iio:deviceX/buffer/sampling_frequency |
| 44 | 45 | What: /sys/bus/iio/devices/triggerX/sampling_frequency |
| 45 | 46 | KernelVersion: 2.6.35 |
| @@ -49,12 +50,13 @@ Description: · 3 unmodified lines | ||
| 49 | 50 | resulting sampling frequency. In many devices this |
| 50 | 51 | parameter has an effect on input filters etc. rather than |
| 51 | 52 | simply controlling when the input is sampled. As this |
| 52 | − effects data ready triggers, hardware buffers and the sysfs | |
| 53 | + affects data ready triggers, hardware buffers and the sysfs | |
| 53 | 54 | direct access interfaces, it may be found in any of the |
| 54 | − relevant directories. If it effects all of the above | |
| 55 | + relevant directories. If it affects all of the above | |
| 55 | 56 | then it is to be found in the base device directory. |
| 56 | 57 | |
| 57 | 58 | What: /sys/bus/iio/devices/iio:deviceX/sampling_frequency_available |
| 59 | +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_sampling_frequency_available | |
| 58 | 60 | What: /sys/bus/iio/devices/iio:deviceX/in_proximity_sampling_frequency_available |
| 59 | 61 | What: /sys/.../iio:deviceX/buffer/sampling_frequency_available |
| 60 | 62 | What: /sys/bus/iio/devices/triggerX/sampling_frequency_available |
| @@ -374,6 +376,9 @@ What: /sys/bus/iio/devices/iio:deviceX/in_velocity_sqrt(x^2+y^2+z^2)_scale · 313 unmodified lines | ||
| 374 | 376 | What: /sys/bus/iio/devices/iio:deviceX/in_illuminance_scale |
| 375 | 377 | What: /sys/bus/iio/devices/iio:deviceX/in_countY_scale |
| 376 | 378 | What: /sys/bus/iio/devices/iio:deviceX/in_angl_scale |
| 379 | +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_x_scale | |
| 380 | +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_y_scale | |
| 381 | +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_z_scale | |
| 377 | 382 | KernelVersion: 2.6.35 |
| 378 | 383 | Contact: linux-iio@vger.kernel.org |
| 379 | 384 | Description: |
| @@ -401,21 +406,21 @@ Description: · 21 unmodified lines | ||
| 401 | 406 | Hardware applied calibration offset (assumed to fix production |
| 402 | 407 | inaccuracies). |
| 403 | 408 | |
| 404 | −What /sys/bus/iio/devices/iio:deviceX/in_voltageY_calibscale | |
| 405 | −What /sys/bus/iio/devices/iio:deviceX/in_voltageY_supply_calibscale | |
| 406 | −What /sys/bus/iio/devices/iio:deviceX/in_voltageY_i_calibscale | |
| 407 | −What /sys/bus/iio/devices/iio:deviceX/in_voltageY_q_calibscale | |
| 408 | −What /sys/bus/iio/devices/iio:deviceX/in_voltage_i_calibscale | |
| 409 | −What /sys/bus/iio/devices/iio:deviceX/in_voltage_q_calibscale | |
| 410 | −What /sys/bus/iio/devices/iio:deviceX/in_voltage_calibscale | |
| 411 | −What /sys/bus/iio/devices/iio:deviceX/in_accel_x_calibscale | |
| 412 | −What /sys/bus/iio/devices/iio:deviceX/in_accel_y_calibscale | |
| 413 | −What /sys/bus/iio/devices/iio:deviceX/in_accel_z_calibscale | |
| 414 | −What /sys/bus/iio/devices/iio:deviceX/in_anglvel_x_calibscale | |
| 415 | −What /sys/bus/iio/devices/iio:deviceX/in_anglvel_y_calibscale | |
| 416 | −What /sys/bus/iio/devices/iio:deviceX/in_anglvel_z_calibscale | |
| 417 | −what /sys/bus/iio/devices/iio:deviceX/in_illuminance0_calibscale | |
| 418 | −what /sys/bus/iio/devices/iio:deviceX/in_proximity0_calibscale | |
| 409 | +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_calibscale | |
| 410 | +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_supply_calibscale | |
| 411 | +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_i_calibscale | |
| 412 | +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_q_calibscale | |
| 413 | +What: /sys/bus/iio/devices/iio:deviceX/in_voltage_i_calibscale | |
| 414 | +What: /sys/bus/iio/devices/iio:deviceX/in_voltage_q_calibscale | |
| 415 | +What: /sys/bus/iio/devices/iio:deviceX/in_voltage_calibscale | |
| 416 | +What: /sys/bus/iio/devices/iio:deviceX/in_accel_x_calibscale | |
| 417 | +What: /sys/bus/iio/devices/iio:deviceX/in_accel_y_calibscale | |
| 418 | +What: /sys/bus/iio/devices/iio:deviceX/in_accel_z_calibscale | |
| 419 | +What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_x_calibscale | |
| 420 | +What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_y_calibscale | |
| 421 | +What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_z_calibscale | |
| 422 | +What: /sys/bus/iio/devices/iio:deviceX/in_illuminance0_calibscale | |
| 423 | +What: /sys/bus/iio/devices/iio:deviceX/in_proximity0_calibscale | |
| 419 | 424 | What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_calibscale |
| 420 | 425 | What: /sys/bus/iio/devices/iio:deviceX/in_pressure_calibscale |
| 421 | 426 | What: /sys/bus/iio/devices/iio:deviceX/in_illuminance_calibscale |
| @@ -483,7 +488,8 @@ Description: · 61 unmodified lines | ||
| 483 | 488 | If a discrete set of scale values is available, they |
| 484 | 489 | are listed in this attribute. |
| 485 | 490 | |
| 486 | −What /sys/bus/iio/devices/iio:deviceX/out_voltageY_hardwaregain | |
| 491 | +What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_hardwaregain | |
| 492 | +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_hardwaregain | |
| 487 | 493 | What: /sys/bus/iio/devices/iio:deviceX/in_intensity_red_hardwaregain |
| 488 | 494 | What: /sys/bus/iio/devices/iio:deviceX/in_intensity_green_hardwaregain |
| 489 | 495 | What: /sys/bus/iio/devices/iio:deviceX/in_intensity_blue_hardwaregain |
| @@ -494,6 +500,13 @@ Description: · 4 unmodified lines | ||
| 494 | 500 | Hardware applied gain factor. If shared across all channels, |
| 495 | 501 | <type>_hardwaregain is used. |
| 496 | 502 | |
| 503 | +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_hardwaregain_available | |
| 504 | +KernelVersion: 5.10 | |
| 505 | +Contact: linux-iio@vger.kernel.org | |
| 506 | +Description: | |
| 507 | + Lists all available hardware applied gain factors. Shared across all | |
| 508 | + channels. | |
| 509 | + | |
| 497 | 510 | What: /sys/.../in_accel_filter_low_pass_3db_frequency |
| 498 | 511 | What: /sys/.../in_magn_filter_low_pass_3db_frequency |
| 499 | 512 | What: /sys/.../in_anglvel_filter_low_pass_3db_frequency |
| @@ -750,9 +763,9 @@ What: /sys/.../events/in_voltageY_raw_thresh_falling_value · 250 unmodified lines | ||
| 750 | 763 | What: /sys/.../events/in_tempY_raw_thresh_rising_value |
| 751 | 764 | What: /sys/.../events/in_tempY_raw_thresh_falling_value |
| 752 | 765 | What: /sys/.../events/in_illuminance0_thresh_falling_value |
| 753 | −what: /sys/.../events/in_illuminance0_thresh_rising_value | |
| 754 | −what: /sys/.../events/in_proximity0_thresh_falling_value | |
| 755 | −what: /sys/.../events/in_proximity0_thresh_rising_value | |
| 766 | +What: /sys/.../events/in_illuminance0_thresh_rising_value | |
| 767 | +What: /sys/.../events/in_proximity0_thresh_falling_value | |
| 768 | +What: /sys/.../events/in_proximity0_thresh_rising_value | |
| 756 | 769 | What: /sys/.../events/in_illuminance_thresh_rising_value |
| 757 | 770 | What: /sys/.../events/in_illuminance_thresh_falling_value |
| 758 | 771 | KernelVersion: 2.6.37 |
| @@ -832,11 +845,11 @@ What: /sys/.../events/in_tempY_thresh_rising_hysteresis · 73 unmodified lines | ||
| 832 | 845 | What: /sys/.../events/in_tempY_thresh_falling_hysteresis |
| 833 | 846 | What: /sys/.../events/in_tempY_thresh_either_hysteresis |
| 834 | 847 | What: /sys/.../events/in_illuminance0_thresh_falling_hysteresis |
| 835 | −what: /sys/.../events/in_illuminance0_thresh_rising_hysteresis | |
| 836 | −what: /sys/.../events/in_illuminance0_thresh_either_hysteresis | |
| 837 | −what: /sys/.../events/in_proximity0_thresh_falling_hysteresis | |
| 838 | −what: /sys/.../events/in_proximity0_thresh_rising_hysteresis | |
| 839 | −what: /sys/.../events/in_proximity0_thresh_either_hysteresis | |
| 848 | +What: /sys/.../events/in_illuminance0_thresh_rising_hysteresis | |
| 849 | +What: /sys/.../events/in_illuminance0_thresh_either_hysteresis | |
| 850 | +What: /sys/.../events/in_proximity0_thresh_falling_hysteresis | |
| 851 | +What: /sys/.../events/in_proximity0_thresh_rising_hysteresis | |
| 852 | +What: /sys/.../events/in_proximity0_thresh_either_hysteresis | |
| 840 | 853 | KernelVersion: 3.13 |
| 841 | 854 | Contact: linux-iio@vger.kernel.org |
| 842 | 855 | Description: |
| @@ -1013,7 +1026,7 @@ What: /sys/.../events/in_activity_running_thresh_falling_en · 170 unmodified lines | ||
| 1013 | 1026 | KernelVersion: 3.19 |
| 1014 | 1027 | Contact: linux-iio@vger.kernel.org |
| 1015 | 1028 | Description: |
| 1016 | − Enables or disables activitity events. Depending on direction | |
| 1029 | + Enables or disables activity events. Depending on direction | |
| 1017 | 1030 | an event is generated when sensor ENTERS or LEAVES a given state. |
| 1018 | 1031 | |
| 1019 | 1032 | What: /sys/.../events/in_activity_still_thresh_rising_value |
| @@ -1333,6 +1346,7 @@ Description: · 313 unmodified lines | ||
| 1333 | 1346 | standardised CIE Erythemal Action Spectrum. UV index values range |
| 1334 | 1347 | from 0 (low) to >=11 (extreme). |
| 1335 | 1348 | |
| 1349 | +What: /sys/.../iio:deviceX/in_intensity_integration_time | |
| 1336 | 1350 | What: /sys/.../iio:deviceX/in_intensity_red_integration_time |
| 1337 | 1351 | What: /sys/.../iio:deviceX/in_intensity_green_integration_time |
| 1338 | 1352 | What: /sys/.../iio:deviceX/in_intensity_blue_integration_time |
| @@ -1342,7 +1356,8 @@ KernelVersion: 3.12 · 3 unmodified lines | ||
| 1342 | 1356 | Contact: linux-iio@vger.kernel.org |
| 1343 | 1357 | Description: |
| 1344 | 1358 | This attribute is used to get/set the integration time in |
| 1345 | − seconds. | |
| 1359 | + seconds. If shared across all channels of a given type, | |
| 1360 | + <type>_integration_time is used. | |
| 1346 | 1361 | |
| 1347 | 1362 | What: /sys/.../iio:deviceX/in_velocity_sqrt(x^2+y^2+z^2)_integration_time |
| 1348 | 1363 | KernelVersion: 4.0 |
| @@ -1564,6 +1579,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_concentration_ethanol_raw · 215 unmodified lines | ||
| 1564 | 1579 | What: /sys/bus/iio/devices/iio:deviceX/in_concentrationX_ethanol_raw |
| 1565 | 1580 | What: /sys/bus/iio/devices/iio:deviceX/in_concentration_h2_raw |
| 1566 | 1581 | What: /sys/bus/iio/devices/iio:deviceX/in_concentrationX_h2_raw |
| 1582 | +What: /sys/bus/iio/devices/iio:deviceX/in_concentration_o2_raw | |
| 1583 | +What: /sys/bus/iio/devices/iio:deviceX/in_concentrationX_o2_raw | |
| 1567 | 1584 | What: /sys/bus/iio/devices/iio:deviceX/in_concentration_voc_raw |
| 1568 | 1585 | What: /sys/bus/iio/devices/iio:deviceX/in_concentrationX_voc_raw |
| 1569 | 1586 | KernelVersion: 4.3 |
| @@ -1740,3 +1757,20 @@ KernelVersion: 5.5 · 170 unmodified lines | ||
| 1740 | 1757 | Contact: linux-iio@vger.kernel.org |
| 1741 | 1758 | Description: |
| 1742 | 1759 | One of the following thermocouple types: B, E, J, K, N, R, S, T. |
| 1760 | + | |
| 1761 | +What: /sys/bus/iio/devices/iio:deviceX/in_temp_object_calibambient | |
| 1762 | +What: /sys/bus/iio/devices/iio:deviceX/in_tempX_object_calibambient | |
| 1763 | +KernelVersion: 5.10 | |
| 1764 | +Contact: linux-iio@vger.kernel.org | |
| 1765 | +Description: | |
| 1766 | + Calibrated ambient temperature for object temperature | |
| 1767 | + calculation in milli degrees Celsius. | |
| 1768 | + | |
| 1769 | +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_x_raw | |
| 1770 | +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_y_raw | |
| 1771 | +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_z_raw | |
| 1772 | +KernelVersion: 5.10 | |
| 1773 | +Contact: linux-iio@vger.kernel.org | |
| 1774 | +Description: | |
| 1775 | + Unscaled light intensity according to CIE 1931/DIN 5033 color space. | |
| 1776 | + Units after application of scale are nano nanowatts per square meter. | |
| @@ -0,0 +1,7 @@ | ||
| 1 | +What: /sys/bus/iio/devices/triggerX/name = "adxl372-devX-peak" | |
| 2 | +KernelVersion: | |
| 3 | +Contact: linux-iio@vger.kernel.org | |
| 4 | +Description: | |
| 5 | + The adxl372 accelerometer kernel module provides an additional trigger, | |
| 6 | + which sets the device in a mode in which it will record only the peak acceleration | |
| 7 | + sensed over the set period of time in the events sysfs. | |
| @@ -0,0 +1,9 @@ | ||
| 1 | +What: /sys/bus/iio/devices/iio:deviceX/out_current_heater_raw | |
| 2 | +What: /sys/bus/iio/devices/iio:deviceX/out_current_heater_raw_available | |
| 3 | +KernelVersion: 5.3.8 | |
| 4 | +Contact: linux-iio@vger.kernel.org | |
| 5 | +Description: | |
| 6 | + Controls the heater device within the humidity sensor to get | |
| 7 | + rid of excess condensation. | |
| 8 | + | |
| 9 | + Valid control values are 0 = OFF, and 1 = ON. | |
File renamed without changes.
| @@ -1,16 +0,0 @@ | ||
| 1 | −* Analog Devices AD7949/AD7682/AD7689 | |
| 2 | − | |
| 3 | −Required properties: | |
| 4 | − - compatible: Should be one of | |
| 5 | − * "adi,ad7949" | |
| 6 | − * "adi,ad7682" | |
| 7 | − * "adi,ad7689" | |
| 8 | − - reg: spi chip select number for the device | |
| 9 | − - vref-supply: The regulator supply for ADC reference voltage | |
| 10 | − | |
| 11 | −Example: | |
| 12 | −adc@0 { | |
| 13 | − compatible = "adi,ad7949"; | |
| 14 | − reg = <0>; | |
| 15 | − vref-supply = <&vdd_supply>; | |
| 16 | −}; | |
| @@ -0,0 +1,46 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/adi,ad7291.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: AD7291 8-Channel, I2C, 12-Bit SAR ADC with Temperature Sensor | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Michael Auchter <michael.auchter@ni.com> | |
| 11 | + | |
| 12 | +description: | | |
| 13 | + Analog Devices AD7291 8-Channel I2C 12-Bit SAR ADC with Temperature Sensor | |
| 14 | + https://www.analog.com/media/en/technical-documentation/data-sheets/ad7291.pdf | |
| 15 | + | |
| 16 | +properties: | |
| 17 | + compatible: | |
| 18 | + enum: | |
| 19 | + - adi,ad7291 | |
| 20 | + | |
| 21 | + reg: | |
| 22 | + maxItems: 1 | |
| 23 | + | |
| 24 | + vref-supply: | |
| 25 | + description: | | |
| 26 | + The regulator supply for ADC reference voltage. | |
| 27 | + | |
| 28 | +required: | |
| 29 | + - compatible | |
| 30 | + - reg | |
| 31 | + | |
| 32 | +additionalProperties: false | |
| 33 | + | |
| 34 | +examples: | |
| 35 | + - | | |
| 36 | + i2c { | |
| 37 | + #address-cells = <1>; | |
| 38 | + #size-cells = <0>; | |
| 39 | + | |
| 40 | + ad7291: adc@0 { | |
| 41 | + compatible = "adi,ad7291"; | |
| 42 | + reg = <0>; | |
| 43 | + vref-supply = <&adc_vref>; | |
| 44 | + }; | |
| 45 | + }; | |
| 46 | +... | |
| @@ -1,41 +0,0 @@ | ||
| 1 | −Analog Devices AD7768-1 ADC device driver | |
| 2 | − | |
| 3 | −Required properties for the AD7768-1: | |
| 4 | − | |
| 5 | −- compatible: Must be "adi,ad7768-1" | |
| 6 | −- reg: SPI chip select number for the device | |
| 7 | −- spi-max-frequency: Max SPI frequency to use | |
| 8 | − see: Documentation/devicetree/bindings/spi/spi-bus.txt | |
| 9 | −- clocks: phandle to the master clock (mclk) | |
| 10 | − see: Documentation/devicetree/bindings/clock/clock-bindings.txt | |
| 11 | −- clock-names: Must be "mclk". | |
| 12 | −- interrupts: IRQ line for the ADC | |
| 13 | − see: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt | |
| 14 | −- vref-supply: vref supply can be used as reference for conversion | |
| 15 | −- adi,sync-in-gpios: must be the device tree identifier of the SYNC-IN pin. Enables | |
| 16 | − synchronization of multiple devices that require simultaneous sampling. | |
| 17 | − A pulse is always required if the configuration is changed in any way, for example | |
| 18 | − if the filter decimation rate changes. As the line is active low, it should | |
| 19 | − be marked GPIO_ACTIVE_LOW. | |
| 20 | − | |
| 21 | −Optional properties: | |
| 22 | − | |
| 23 | − - reset-gpios : GPIO spec for the RESET pin. If specified, it will be asserted during | |
| 24 | − driver probe. As the line is active low, it should be marked GPIO_ACTIVE_LOW. | |
| 25 | − | |
| 26 | −Example: | |
| 27 | − | |
| 28 | − adc@0 { | |
| 29 | − compatible = "adi,ad7768-1"; | |
| 30 | − reg = <0>; | |
| 31 | − spi-max-frequency = <2000000>; | |
| 32 | − spi-cpol; | |
| 33 | − spi-cpha; | |
| 34 | − vref-supply = <&adc_vref>; | |
| 35 | − interrupts = <25 IRQ_TYPE_EDGE_RISING>; | |
| 36 | − interrupt-parent = <&gpio>; | |
| 37 | − adi,sync-in-gpios = <&gpio 22 GPIO_ACTIVE_LOW>; | |
| 38 | − reset-gpios = <&gpio 27 GPIO_ACTIVE_LOW>; | |
| 39 | − clocks = <&ad7768_mclk>; | |
| 40 | − clock-names = "mclk"; | |
| 41 | − }; | |
| @@ -0,0 +1,89 @@ | ||
| 1 | +# SPDX-License-Identifier: GPL-2.0 | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/adi,ad7768-1.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Analog Devices AD7768-1 ADC device driver | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Michael Hennerich <michael.hennerich@analog.com> | |
| 11 | + | |
| 12 | +description: | | |
| 13 | + Datasheet at: | |
| 14 | + https://www.analog.com/media/en/technical-documentation/data-sheets/ad7768-1.pdf | |
| 15 | + | |
| 16 | +properties: | |
| 17 | + compatible: | |
| 18 | + const: adi,ad7768-1 | |
| 19 | + | |
| 20 | + reg: | |
| 21 | + maxItems: 1 | |
| 22 | + | |
| 23 | + clocks: | |
| 24 | + maxItems: 1 | |
| 25 | + | |
| 26 | + clock-names: | |
| 27 | + const: mclk | |
| 28 | + | |
| 29 | + interrupts: | |
| 30 | + maxItems: 1 | |
| 31 | + | |
| 32 | + vref-supply: | |
| 33 | + description: | |
| 34 | + ADC reference voltage supply | |
| 35 | + | |
| 36 | + adi,sync-in-gpios: | |
| 37 | + description: | |
| 38 | + Enables synchronization of multiple devices that require simultaneous | |
| 39 | + sampling. A pulse is always required if the configuration is changed | |
| 40 | + in any way, for example if the filter decimation rate changes. | |
| 41 | + As the line is active low, it should be marked GPIO_ACTIVE_LOW. | |
| 42 | + | |
| 43 | + reset-gpios: | |
| 44 | + maxItems: 1 | |
| 45 | + | |
| 46 | + spi-max-frequency: true | |
| 47 | + | |
| 48 | + spi-cpol: true | |
| 49 | + spi-cpha : true | |
| 50 | + | |
| 51 | + "#io-channel-cells": | |
| 52 | + const: 1 | |
| 53 | + | |
| 54 | +required: | |
| 55 | + - compatible | |
| 56 | + - reg | |
| 57 | + - clocks | |
| 58 | + - clock-names | |
| 59 | + - vref-supply | |
| 60 | + - spi-cpol | |
| 61 | + - spi-cpha | |
| 62 | + - adi,sync-in-gpios | |
| 63 | + | |
| 64 | +additionalProperties: false | |
| 65 | + | |
| 66 | +examples: | |
| 67 | + - | | |
| 68 | + #include <dt-bindings/interrupt-controller/irq.h> | |
| 69 | + #include <dt-bindings/gpio/gpio.h> | |
| 70 | + spi { | |
| 71 | + #address-cells = <1>; | |
| 72 | + #size-cells = <0>; | |
| 73 | + | |
| 74 | + adc@0 { | |
| 75 | + compatible = "adi,ad7768-1"; | |
| 76 | + reg = <0>; | |
| 77 | + spi-max-frequency = <2000000>; | |
| 78 | + spi-cpol; | |
| 79 | + spi-cpha; | |
| 80 | + vref-supply = <&adc_vref>; | |
| 81 | + interrupts = <25 IRQ_TYPE_EDGE_RISING>; | |
| 82 | + interrupt-parent = <&gpio>; | |
| 83 | + adi,sync-in-gpios = <&gpio 22 GPIO_ACTIVE_LOW>; | |
| 84 | + reset-gpios = <&gpio 27 GPIO_ACTIVE_LOW>; | |
| 85 | + clocks = <&ad7768_mclk>; | |
| 86 | + clock-names = "mclk"; | |
| 87 | + }; | |
| 88 | + }; | |
| 89 | +... | |
| @@ -0,0 +1,57 @@ | ||
| 1 | +# SPDX-License-Identifier: GPL-2.0 | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/adi,ad7949.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Analog Devices AD7949/AD7682/AD7689 analog to digital converters | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Charles-Antoine Couret <charles-antoine.couret@essensium.com> | |
| 11 | + | |
| 12 | +description: | | |
| 13 | + Specifications on the converters can be found at: | |
| 14 | + AD7949: | |
| 15 | + https://www.analog.com/media/en/technical-documentation/data-sheets/AD7949.pdf | |
| 16 | + AD7682/AD7698: | |
| 17 | + https://www.analog.com/media/en/technical-documentation/data-sheets/AD7682_7689.pdf | |
| 18 | + | |
| 19 | +properties: | |
| 20 | + compatible: | |
| 21 | + enum: | |
| 22 | + - adi,ad7682 | |
| 23 | + - adi,ad7689 | |
| 24 | + - adi,ad7949 | |
| 25 | + | |
| 26 | + reg: | |
| 27 | + maxItems: 1 | |
| 28 | + | |
| 29 | + vref-supply: | |
| 30 | + description: | |
| 31 | + ADC reference voltage supply | |
| 32 | + | |
| 33 | + spi-max-frequency: true | |
| 34 | + | |
| 35 | + "#io-channel-cells": | |
| 36 | + const: 1 | |
| 37 | + | |
| 38 | +required: | |
| 39 | + - compatible | |
| 40 | + - reg | |
| 41 | + - vref-supply | |
| 42 | + | |
| 43 | +additionalProperties: false | |
| 44 | + | |
| 45 | +examples: | |
| 46 | + - | | |
| 47 | + spi { | |
| 48 | + #address-cells = <1>; | |
| 49 | + #size-cells = <0>; | |
| 50 | + | |
| 51 | + adc@0 { | |
| 52 | + compatible = "adi,ad7949"; | |
| 53 | + reg = <0>; | |
| 54 | + vref-supply = <&vdd_supply>; | |
| 55 | + }; | |
| 56 | + }; | |
| 57 | +... | |
| @@ -4,21 +4,30 @@ · 3 unmodified lines | ||
| 4 | 4 | $id: http://devicetree.org/schemas/iio/adc/adi,ad9467.yaml# |
| 5 | 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# |
| 6 | 6 | |
| 7 | −title: Analog Devices AD9467 High-Speed ADC | |
| 7 | +title: Analog Devices AD9467 and similar High-Speed ADCs | |
| 8 | 8 | |
| 9 | 9 | maintainers: |
| 10 | 10 | - Michael Hennerich <michael.hennerich@analog.com> |
| 11 | 11 | - Alexandru Ardelean <alexandru.ardelean@analog.com> |
| 12 | 12 | |
| 13 | 13 | description: | |
| 14 | − The AD9467 is a 16-bit, monolithic, IF sampling analog-to-digital | |
| 15 | − converter (ADC). | |
| 14 | + The AD9467 and the parts similar with it, are high-speed analog-to-digital | |
| 15 | + converters (ADCs), operating in the range of 100 to 500 mega samples | |
| 16 | + per second (MSPS). Some parts support higher MSPS and some | |
| 17 | + lower MSPS, suitable for the intended application of each part. | |
| 16 | 18 | |
| 19 | + All the parts support the register map described by Application Note AN-877 | |
| 20 | + https://www.analog.com/media/en/technical-documentation/application-notes/AN-877.pdf | |
| 21 | + | |
| 22 | + https://www.analog.com/media/en/technical-documentation/data-sheets/AD9265.pdf | |
| 23 | + https://www.analog.com/media/en/technical-documentation/data-sheets/AD9434.pdf | |
| 17 | 24 | https://www.analog.com/media/en/technical-documentation/data-sheets/AD9467.pdf |
| 18 | 25 | |
| 19 | 26 | properties: |
| 20 | 27 | compatible: |
| 21 | 28 | enum: |
| 29 | + - adi,ad9265 | |
| 30 | + - adi,ad9434 | |
| 22 | 31 | - adi,ad9467 |
| 23 | 32 | |
| 24 | 33 | reg: |
| @@ -1,73 +0,0 @@ | ||
| 1 | −ADS1015 (I2C) | |
| 2 | − | |
| 3 | −This device is a 12-bit A-D converter with 4 inputs. | |
| 4 | − | |
| 5 | −The inputs can be used single ended or in certain differential combinations. | |
| 6 | − | |
| 7 | −For configuration all possible combinations are mapped to 8 channels: | |
| 8 | − 0: Voltage over AIN0 and AIN1. | |
| 9 | − 1: Voltage over AIN0 and AIN3. | |
| 10 | − 2: Voltage over AIN1 and AIN3. | |
| 11 | − 3: Voltage over AIN2 and AIN3. | |
| 12 | − 4: Voltage over AIN0 and GND. | |
| 13 | − 5: Voltage over AIN1 and GND. | |
| 14 | − 6: Voltage over AIN2 and GND. | |
| 15 | − 7: Voltage over AIN3 and GND. | |
| 16 | − | |
| 17 | −Each channel can be configured individually: | |
| 18 | − - pga is the programmable gain amplifier (values are full scale) | |
| 19 | − 0: +/- 6.144 V | |
| 20 | − 1: +/- 4.096 V | |
| 21 | − 2: +/- 2.048 V (default) | |
| 22 | − 3: +/- 1.024 V | |
| 23 | − 4: +/- 0.512 V | |
| 24 | − 5: +/- 0.256 V | |
| 25 | − - data_rate in samples per second | |
| 26 | − 0: 128 | |
| 27 | − 1: 250 | |
| 28 | − 2: 490 | |
| 29 | − 3: 920 | |
| 30 | − 4: 1600 (default) | |
| 31 | − 5: 2400 | |
| 32 | − 6: 3300 | |
| 33 | − | |
| 34 | −1) The /ads1015 node | |
| 35 | − | |
| 36 | − Required properties: | |
| 37 | − | |
| 38 | − - compatible : must be "ti,ads1015" | |
| 39 | − - reg : I2C bus address of the device | |
| 40 | − - #address-cells : must be <1> | |
| 41 | − - #size-cells : must be <0> | |
| 42 | − | |
| 43 | − The node contains child nodes for each channel that the platform uses. | |
| 44 | − | |
| 45 | − Example ADS1015 node: | |
| 46 | − | |
| 47 | − ads1015@49 { | |
| 48 | − compatible = "ti,ads1015"; | |
| 49 | − reg = <0x49>; | |
| 50 | − #address-cells = <1>; | |
| 51 | − #size-cells = <0>; | |
| 52 | − | |
| 53 | − [ child node definitions... ] | |
| 54 | − } | |
| 55 | − | |
| 56 | −2) channel nodes | |
| 57 | − | |
| 58 | − Required properties: | |
| 59 | − | |
| 60 | − - reg : the channel number | |
| 61 | − | |
| 62 | − Optional properties: | |
| 63 | − | |
| 64 | − - ti,gain : the programmable gain amplifier setting | |
| 65 | − - ti,datarate : the converter data rate | |
| 66 | − | |
| 67 | − Example ADS1015 channel node: | |
| 68 | − | |
| 69 | − channel@4 { | |
| 70 | − reg = <4>; | |
| 71 | − ti,gain = <3>; | |
| 72 | − ti,datarate = <5>; | |
| 73 | − }; | |
| @@ -1,48 +0,0 @@ | ||
| 1 | −* Amlogic Meson SAR (Successive Approximation Register) A/D converter | |
| 2 | − | |
| 3 | −Required properties: | |
| 4 | −- compatible: depending on the SoC this should be one of: | |
| 5 | − - "amlogic,meson8-saradc" for Meson8 | |
| 6 | − - "amlogic,meson8b-saradc" for Meson8b | |
| 7 | − - "amlogic,meson8m2-saradc" for Meson8m2 | |
| 8 | − - "amlogic,meson-gxbb-saradc" for GXBB | |
| 9 | − - "amlogic,meson-gxl-saradc" for GXL | |
| 10 | − - "amlogic,meson-gxm-saradc" for GXM | |
| 11 | − - "amlogic,meson-axg-saradc" for AXG | |
| 12 | − - "amlogic,meson-g12a-saradc" for AXG | |
| 13 | − along with the generic "amlogic,meson-saradc" | |
| 14 | −- reg: the physical base address and length of the registers | |
| 15 | −- interrupts: the interrupt indicating end of sampling | |
| 16 | −- clocks: phandle and clock identifier (see clock-names) | |
| 17 | −- clock-names: mandatory clocks: | |
| 18 | − - "clkin" for the reference clock (typically XTAL) | |
| 19 | − - "core" for the SAR ADC core clock | |
| 20 | − optional clocks: | |
| 21 | − - "adc_clk" for the ADC (sampling) clock | |
| 22 | − - "adc_sel" for the ADC (sampling) clock mux | |
| 23 | −- vref-supply: the regulator supply for the ADC reference voltage | |
| 24 | −- #io-channel-cells: must be 1, see ../iio-bindings.txt | |
| 25 | − | |
| 26 | −Optional properties: | |
| 27 | −- amlogic,hhi-sysctrl: phandle to the syscon which contains the 5th bit | |
| 28 | − of the TSC (temperature sensor coefficient) on | |
| 29 | − Meson8b and Meson8m2 (which used to calibrate the | |
| 30 | − temperature sensor) | |
| 31 | −- nvmem-cells: phandle to the temperature_calib eFuse cells | |
| 32 | −- nvmem-cell-names: if present (to enable the temperature sensor | |
| 33 | − calibration) this must contain "temperature_calib" | |
| 34 | − | |
| 35 | − | |
| 36 | −Example: | |
| 37 | − saradc: adc@8680 { | |
| 38 | − compatible = "amlogic,meson-gxl-saradc", "amlogic,meson-saradc"; | |
| 39 | − #io-channel-cells = <1>; | |
| 40 | − reg = <0x0 0x8680 0x0 0x34>; | |
| 41 | − interrupts = <GIC_SPI 73 IRQ_TYPE_EDGE_RISING>; | |
| 42 | − clocks = <&xtal>, | |
| 43 | − <&clkc CLKID_SAR_ADC>, | |
| 44 | − <&clkc CLKID_SANA>, | |
| 45 | − <&clkc CLKID_SAR_ADC_CLK>, | |
| 46 | − <&clkc CLKID_SAR_ADC_SEL>; | |
| 47 | − clock-names = "clkin", "core", "sana", "adc_clk", "adc_sel"; | |
| 48 | − }; | |
| @@ -0,0 +1,149 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/amlogic,meson-saradc.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Amlogic Meson SAR (Successive Approximation Register) A/D converter | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Martin Blumenstingl <martin.blumenstingl@googlemail.com> | |
| 11 | + | |
| 12 | +description: | |
| 13 | + Binding covers a range of ADCs found on Amlogic Meson SoCs. | |
| 14 | + | |
| 15 | +properties: | |
| 16 | + compatible: | |
| 17 | + oneOf: | |
| 18 | + - const: amlogic,meson-saradc | |
| 19 | + - items: | |
| 20 | + - enum: | |
| 21 | + - amlogic,meson8-saradc | |
| 22 | + - amlogic,meson8b-saradc | |
| 23 | + - amlogic,meson8m2-saradc | |
| 24 | + - amlogic,meson-gxbb-saradc | |
| 25 | + - amlogic,meson-gxl-saradc | |
| 26 | + - amlogic,meson-gxm-saradc | |
| 27 | + - amlogic,meson-axg-saradc | |
| 28 | + - amlogic,meson-g12a-saradc | |
| 29 | + - const: amlogic,meson-saradc | |
| 30 | + | |
| 31 | + reg: | |
| 32 | + maxItems: 1 | |
| 33 | + | |
| 34 | + interrupts: | |
| 35 | + description: Interrupt indicates end of sampling. | |
| 36 | + maxItems: 1 | |
| 37 | + | |
| 38 | + clocks: | |
| 39 | + minItems: 2 | |
| 40 | + maxItems: 4 | |
| 41 | + | |
| 42 | + clock-names: | |
| 43 | + minItems: 2 | |
| 44 | + maxItems: 4 | |
| 45 | + items: | |
| 46 | + - const: clkin | |
| 47 | + - const: core | |
| 48 | + - const: adc_clk | |
| 49 | + - const: adc_sel | |
| 50 | + | |
| 51 | + vref-supply: true | |
| 52 | + | |
| 53 | + "#io-channel-cells": | |
| 54 | + const: 1 | |
| 55 | + | |
| 56 | + amlogic,hhi-sysctrl: | |
| 57 | + $ref: /schemas/types.yaml#/definitions/phandle | |
| 58 | + description: | |
| 59 | + Syscon which contains the 5th bit of the TSC (temperature sensor | |
| 60 | + coefficient) on Meson8b and Meson8m2 (which used to calibrate the | |
| 61 | + temperature sensor) | |
| 62 | + | |
| 63 | + nvmem-cells: | |
| 64 | + description: phandle to the temperature_calib eFuse cells | |
| 65 | + maxItems: 1 | |
| 66 | + | |
| 67 | + nvmem-cell-names: | |
| 68 | + const: temperature_calib | |
| 69 | + | |
| 70 | +allOf: | |
| 71 | + - if: | |
| 72 | + properties: | |
| 73 | + compatible: | |
| 74 | + contains: | |
| 75 | + enum: | |
| 76 | + - amlogic,meson8-saradc | |
| 77 | + - amlogic,meson8b-saradc | |
| 78 | + - amlogic,meson8m2-saradc | |
| 79 | + then: | |
| 80 | + properties: | |
| 81 | + clocks: | |
| 82 | + maxItems: 2 | |
| 83 | + clock-names: | |
| 84 | + maxItems: 2 | |
| 85 | + else: | |
| 86 | + properties: | |
| 87 | + nvmem-cells: false | |
| 88 | + mvmem-cel-names: false | |
| 89 | + clocks: | |
| 90 | + minItems: 4 | |
| 91 | + clock-names: | |
| 92 | + minItems: 4 | |
| 93 | + | |
| 94 | + - if: | |
| 95 | + properties: | |
| 96 | + compatible: | |
| 97 | + contains: | |
| 98 | + enum: | |
| 99 | + - amlogic,meson8b-saradc | |
| 100 | + - amlogic,meson8m2-saradc | |
| 101 | + then: | |
| 102 | + properties: | |
| 103 | + amlogic,hhi-sysctrl: true | |
| 104 | + else: | |
| 105 | + properties: | |
| 106 | + amlogic,hhi-sysctrl: false | |
| 107 | + | |
| 108 | +required: | |
| 109 | + - compatible | |
| 110 | + - reg | |
| 111 | + - interrupts | |
| 112 | + - clocks | |
| 113 | + - clock-names | |
| 114 | + - "#io-channel-cells" | |
| 115 | + | |
| 116 | +additionalProperties: false | |
| 117 | + | |
| 118 | +examples: | |
| 119 | + - | | |
| 120 | + #include <dt-bindings/interrupt-controller/irq.h> | |
| 121 | + #include <dt-bindings/clock/gxbb-clkc.h> | |
| 122 | + #include <dt-bindings/interrupt-controller/arm-gic.h> | |
| 123 | + soc { | |
| 124 | + #address-cells = <2>; | |
| 125 | + #size-cells = <2>; | |
| 126 | + adc@8680 { | |
| 127 | + compatible = "amlogic,meson-gxl-saradc", "amlogic,meson-saradc"; | |
| 128 | + #io-channel-cells = <1>; | |
| 129 | + reg = <0x0 0x8680 0x0 0x34>; | |
| 130 | + interrupts = <GIC_SPI 73 IRQ_TYPE_EDGE_RISING>; | |
| 131 | + clocks = <&xtal>, | |
| 132 | + <&clkc CLKID_SAR_ADC>, | |
| 133 | + <&clkc CLKID_SAR_ADC_CLK>, | |
| 134 | + <&clkc CLKID_SAR_ADC_SEL>; | |
| 135 | + clock-names = "clkin", "core", "adc_clk", "adc_sel"; | |
| 136 | + }; | |
| 137 | + adc@9680 { | |
| 138 | + compatible = "amlogic,meson8b-saradc", "amlogic,meson-saradc"; | |
| 139 | + #io-channel-cells = <1>; | |
| 140 | + reg = <0x0 0x9680 0x0 0x34>; | |
| 141 | + interrupts = <GIC_SPI 73 IRQ_TYPE_EDGE_RISING>; | |
| 142 | + clocks = <&xtal>, <&clkc CLKID_SAR_ADC>; | |
| 143 | + clock-names = "clkin", "core"; | |
| 144 | + nvmem-cells = <&tsens_caldata>; | |
| 145 | + nvmem-cell-names = "temperature_calib"; | |
| 146 | + amlogic,hhi-sysctrl = <&hhi>; | |
| 147 | + }; | |
| 148 | + }; | |
| 149 | +... | |
| @@ -0,0 +1,55 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/aspeed,ast2400-adc.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: ADC that forms part of an ASPEED server management processor. | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Joel Stanley <joel@jms.id.au> | |
| 11 | + | |
| 12 | +description: | |
| 13 | + This device is a 10-bit converter for 16 voltage channels. All inputs are | |
| 14 | + single ended. | |
| 15 | + | |
| 16 | +properties: | |
| 17 | + compatible: | |
| 18 | + enum: | |
| 19 | + - aspeed,ast2400-adc | |
| 20 | + - aspeed,ast2500-adc | |
| 21 | + | |
| 22 | + reg: | |
| 23 | + maxItems: 1 | |
| 24 | + | |
| 25 | + clocks: | |
| 26 | + description: | |
| 27 | + Input clock used to derive the sample clock. Expected to be the | |
| 28 | + SoC's APB clock. | |
| 29 | + | |
| 30 | + resets: | |
| 31 | + maxItems: 1 | |
| 32 | + | |
| 33 | + "#io-channel-cells": | |
| 34 | + const: 1 | |
| 35 | + | |
| 36 | +required: | |
| 37 | + - compatible | |
| 38 | + - reg | |
| 39 | + - clocks | |
| 40 | + - resets | |
| 41 | + - "#io-channel-cells" | |
| 42 | + | |
| 43 | +additionalProperties: false | |
| 44 | + | |
| 45 | +examples: | |
| 46 | + - | | |
| 47 | + #include <dt-bindings/clock/aspeed-clock.h> | |
| 48 | + adc@1e6e9000 { | |
| 49 | + compatible = "aspeed,ast2400-adc"; | |
| 50 | + reg = <0x1e6e9000 0xb0>; | |
| 51 | + clocks = <&syscon ASPEED_CLK_APB>; | |
| 52 | + resets = <&syscon ASPEED_RESET_ADC>; | |
| 53 | + #io-channel-cells = <1>; | |
| 54 | + }; | |
| 55 | +... | |
| @@ -1,22 +0,0 @@ | ||
| 1 | −Aspeed ADC | |
| 2 | − | |
| 3 | −This device is a 10-bit converter for 16 voltage channels. All inputs are | |
| 4 | −single ended. | |
| 5 | − | |
| 6 | −Required properties: | |
| 7 | −- compatible: Should be "aspeed,ast2400-adc" or "aspeed,ast2500-adc" | |
| 8 | −- reg: memory window mapping address and length | |
| 9 | −- clocks: Input clock used to derive the sample clock. Expected to be the | |
| 10 | − SoC's APB clock. | |
| 11 | −- resets: Reset controller phandle | |
| 12 | −- #io-channel-cells: Must be set to <1> to indicate channels are selected | |
| 13 | − by index. | |
| 14 | − | |
| 15 | −Example: | |
| 16 | − adc@1e6e9000 { | |
| 17 | − compatible = "aspeed,ast2400-adc"; | |
| 18 | − reg = <0x1e6e9000 0xb0>; | |
| 19 | − clocks = <&syscon ASPEED_CLK_APB>; | |
| 20 | − resets = <&syscon ASPEED_RESET_ADC>; | |
| 21 | − #io-channel-cells = <1>; | |
| 22 | − }; | |
| @@ -1,19 +0,0 @@ | ||
| 1 | −* Berlin Analog to Digital Converter (ADC) | |
| 2 | − | |
| 3 | −The Berlin ADC has 8 channels, with one connected to a temperature sensor. | |
| 4 | −It is part of the system controller register set. The ADC node should be a | |
| 5 | −sub-node of the system controller node. | |
| 6 | − | |
| 7 | −Required properties: | |
| 8 | −- compatible: must be "marvell,berlin2-adc" | |
| 9 | −- interrupts: the interrupts for the ADC and the temperature sensor | |
| 10 | −- interrupt-names: should be "adc" and "tsen" | |
| 11 | − | |
| 12 | −Example: | |
| 13 | − | |
| 14 | −adc: adc { | |
| 15 | − compatible = "marvell,berlin2-adc"; | |
| 16 | − interrupt-parent = <&sic>; | |
| 17 | − interrupts = <12>, <14>; | |
| 18 | − interrupt-names = "adc", "tsen"; | |
| 19 | −}; | |
| @@ -1,22 +0,0 @@ | ||
| 1 | −* Cosmic Circuits - Analog to Digital Converter (CC-10001-ADC) | |
| 2 | − | |
| 3 | −Required properties: | |
| 4 | − - compatible: Should be "cosmic,10001-adc" | |
| 5 | − - reg: Should contain adc registers location and length. | |
| 6 | − - clock-names: Should contain "adc". | |
| 7 | − - clocks: Should contain a clock specifier for each entry in clock-names | |
| 8 | − - vref-supply: The regulator supply ADC reference voltage. | |
| 9 | − | |
| 10 | −Optional properties: | |
| 11 | − - adc-reserved-channels: Bitmask of reserved channels, | |
| 12 | − i.e. channels that cannot be used by the OS. | |
| 13 | − | |
| 14 | −Example: | |
| 15 | −adc: adc@18101600 { | |
| 16 | − compatible = "cosmic,10001-adc"; | |
| 17 | − reg = <0x18101600 0x24>; | |
| 18 | − adc-reserved-channels = <0x2>; | |
| 19 | − clocks = <&adc_clk>; | |
| 20 | − clock-names = "adc"; | |
| 21 | − vref-supply = <®_1v8>; | |
| 22 | −}; | |
| @@ -0,0 +1,59 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/cosmic,10001-adc.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Cosmic Circuits CC-10001 ADC | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Jonathan Cameron <jic23@kernel.org> | |
| 11 | + | |
| 12 | +description: | |
| 13 | + Cosmic Circuits 10001 10-bit ADC device. | |
| 14 | + | |
| 15 | +properties: | |
| 16 | + compatible: | |
| 17 | + const: cosmic,10001-adc | |
| 18 | + | |
| 19 | + reg: | |
| 20 | + maxItems: 1 | |
| 21 | + | |
| 22 | + adc-reserved-channels: | |
| 23 | + $ref: /schemas/types.yaml#/definitions/uint32 | |
| 24 | + description: | |
| 25 | + Bitmask of reserved channels, i.e. channels that cannot be | |
| 26 | + used by the OS. | |
| 27 | + | |
| 28 | + clocks: | |
| 29 | + maxItems: 1 | |
| 30 | + | |
| 31 | + clock-names: | |
| 32 | + const: adc | |
| 33 | + | |
| 34 | + vref-supply: true | |
| 35 | + | |
| 36 | + "#io-channel-cells": | |
| 37 | + const: 1 | |
| 38 | + | |
| 39 | + | |
| 40 | +required: | |
| 41 | + - compatible | |
| 42 | + - reg | |
| 43 | + - clocks | |
| 44 | + - clock-names | |
| 45 | + - vref-supply | |
| 46 | + | |
| 47 | +additionalProperties: false | |
| 48 | + | |
| 49 | +examples: | |
| 50 | + - | | |
| 51 | + adc@18101600 { | |
| 52 | + compatible = "cosmic,10001-adc"; | |
| 53 | + reg = <0x18101600 0x24>; | |
| 54 | + adc-reserved-channels = <0x2>; | |
| 55 | + clocks = <&adc_clk>; | |
| 56 | + clock-names = "adc"; | |
| 57 | + vref-supply = <®_1v8>; | |
| 58 | + }; | |
| 59 | +... | |
| @@ -1,17 +0,0 @@ | ||
| 1 | −Motorola CPCAP PMIC ADC binding | |
| 2 | − | |
| 3 | −Required properties: | |
| 4 | −- compatible: Should be "motorola,cpcap-adc" or "motorola,mapphone-cpcap-adc" | |
| 5 | −- interrupts: The interrupt number for the ADC device | |
| 6 | −- interrupt-names: Should be "adcdone" | |
| 7 | −- #io-channel-cells: Number of cells in an IIO specifier | |
| 8 | − | |
| 9 | −Example: | |
| 10 | − | |
| 11 | −cpcap_adc: adc { | |
| 12 | − compatible = "motorola,mapphone-cpcap-adc"; | |
| 13 | − interrupt-parent = <&cpcap>; | |
| 14 | − interrupts = <8 IRQ_TYPE_NONE>; | |
| 15 | − interrupt-names = "adcdone"; | |
| 16 | − #io-channel-cells = <1>; | |
| 17 | −}; | |
| @@ -1,16 +0,0 @@ | ||
| 1 | −Dialog Semiconductor DA9150 IIO GPADC bindings | |
| 2 | − | |
| 3 | −Required properties: | |
| 4 | −- compatible: "dlg,da9150-gpadc" for DA9150 IIO GPADC | |
| 5 | −- #io-channel-cells: Should be set to <1> | |
| 6 | − (See Documentation/devicetree/bindings/iio/iio-bindings.txt for further info) | |
| 7 | − | |
| 8 | −For further information on GPADC channels, see device datasheet. | |
| 9 | − | |
| 10 | − | |
| 11 | −Example: | |
| 12 | − | |
| 13 | − gpadc: da9150-gpadc { | |
| 14 | − compatible = "dlg,da9150-gpadc"; | |
| 15 | − #io-channel-cells = <1>; | |
| 16 | − }; | |
| @@ -0,0 +1,35 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/dlg,da9150-gpadc.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Dialog Semiconductor DA9150 IIO GPADC | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Adam Thomson <Adam.Thomson.Opensource@diasemi.com> | |
| 11 | + | |
| 12 | +description: | |
| 13 | + This patch adds support for general purpose ADC within the | |
| 14 | + DA9150 Charger & Fuel-Gauge IC. | |
| 15 | + | |
| 16 | +properties: | |
| 17 | + compatible: | |
| 18 | + const: dlg,da9150-gpadc | |
| 19 | + | |
| 20 | + "#io-channel-cells": | |
| 21 | + const: 1 | |
| 22 | + | |
| 23 | +required: | |
| 24 | + - compatible | |
| 25 | + - "#io-channel-cells" | |
| 26 | + | |
| 27 | +additionalProperties: false | |
| 28 | + | |
| 29 | +examples: | |
| 30 | + - | | |
| 31 | + adc { | |
| 32 | + compatible = "dlg,da9150-gpadc"; | |
| 33 | + #io-channel-cells = <1>; | |
| 34 | + }; | |
| 35 | +... | |
| @@ -1,57 +0,0 @@ | ||
| 1 | −Freescale i.MX25 ADC GCQ device | |
| 2 | − | |
| 3 | −This is a generic conversion queue device that can convert any of the | |
| 4 | −analog inputs using the ADC unit of the i.MX25. | |
| 5 | − | |
| 6 | −Required properties: | |
| 7 | − - compatible: Should be "fsl,imx25-gcq". | |
| 8 | − - reg: Should be the register range of the module. | |
| 9 | − - interrupts: Should be the interrupt number of the module. | |
| 10 | − Typically this is <1>. | |
| 11 | − - #address-cells: Should be <1> (setting for the subnodes) | |
| 12 | − - #size-cells: Should be <0> (setting for the subnodes) | |
| 13 | − | |
| 14 | −Optional properties: | |
| 15 | − - vref-ext-supply: The regulator supplying the ADC reference voltage. | |
| 16 | − Required when at least one subnode uses the this reference. | |
| 17 | − - vref-xp-supply: The regulator supplying the ADC reference voltage on pin XP. | |
| 18 | − Required when at least one subnode uses this reference. | |
| 19 | − - vref-yp-supply: The regulator supplying the ADC reference voltage on pin YP. | |
| 20 | − Required when at least one subnode uses this reference. | |
| 21 | − | |
| 22 | −Sub-nodes: | |
| 23 | −Optionally you can define subnodes which define the reference voltage | |
| 24 | −for the analog inputs. | |
| 25 | − | |
| 26 | −Required properties for subnodes: | |
| 27 | − - reg: Should be the number of the analog input. | |
| 28 | − 0: xp | |
| 29 | − 1: yp | |
| 30 | − 2: xn | |
| 31 | − 3: yn | |
| 32 | − 4: wiper | |
| 33 | − 5: inaux0 | |
| 34 | − 6: inaux1 | |
| 35 | − 7: inaux2 | |
| 36 | −Optional properties for subnodes: | |
| 37 | − - fsl,adc-refp: specifies the positive reference input as defined in | |
| 38 | − <dt-bindings/iio/adc/fsl-imx25-gcq.h> | |
| 39 | − - fsl,adc-refn: specifies the negative reference input as defined in | |
| 40 | − <dt-bindings/iio/adc/fsl-imx25-gcq.h> | |
| 41 | − | |
| 42 | −Example: | |
| 43 | − | |
| 44 | − adc: adc@50030800 { | |
| 45 | − compatible = "fsl,imx25-gcq"; | |
| 46 | − reg = <0x50030800 0x60>; | |
| 47 | − interrupt-parent = <&tscadc>; | |
| 48 | − interrupts = <1>; | |
| 49 | − #address-cells = <1>; | |
| 50 | − #size-cells = <0>; | |
| 51 | − | |
| 52 | − inaux@5 { | |
| 53 | − reg = <5>; | |
| 54 | − fsl,adc-refp = <MX25_ADC_REFP_INT>; | |
| 55 | − fsl,adc-refn = <MX25_ADC_REFN_NGND>; | |
| 56 | − }; | |
| 57 | − }; | |
| @@ -0,0 +1,131 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/fsl,imx25-gcq.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Freescale ADC GCQ device | |
| 8 | + | |
| 9 | +description: | |
| 10 | + This is a generic conversion queue device that can convert any of the | |
| 11 | + analog inputs using the ADC unit of the i.MX25. | |
| 12 | + | |
| 13 | +maintainers: | |
| 14 | + - Jonathan Cameron <jic23@kernel.org> | |
| 15 | + | |
| 16 | +properties: | |
| 17 | + compatible: | |
| 18 | + const: fsl,imx25-gcq | |
| 19 | + | |
| 20 | + reg: | |
| 21 | + maxItems: 1 | |
| 22 | + | |
| 23 | + interrupts: | |
| 24 | + maxItems: 1 | |
| 25 | + | |
| 26 | + vref-ext-supply: | |
| 27 | + description: | |
| 28 | + The regulator supplying the ADC reference voltage. | |
| 29 | + Required when at least one subnode uses the this reference. | |
| 30 | + | |
| 31 | + vref-xp-supply: | |
| 32 | + description: | |
| 33 | + The regulator supplying the ADC reference voltage on pin XP. | |
| 34 | + Required when at least one subnode uses this reference. | |
| 35 | + | |
| 36 | + vref-yp-supply: | |
| 37 | + description: | |
| 38 | + The regulator supplying the ADC reference voltage on pin YP. | |
| 39 | + Required when at least one subnode uses this reference. | |
| 40 | + | |
| 41 | + "#io-channel-cells": | |
| 42 | + const: 1 | |
| 43 | + | |
| 44 | + "#address-cells": | |
| 45 | + const: 1 | |
| 46 | + | |
| 47 | + "#size-cells": | |
| 48 | + const: 0 | |
| 49 | + | |
| 50 | +required: | |
| 51 | + - compatible | |
| 52 | + - reg | |
| 53 | + - interrupts | |
| 54 | + - "#address-cells" | |
| 55 | + - "#size-cells" | |
| 56 | + | |
| 57 | +patternProperties: | |
| 58 | + "[a-z][a-z0-9]+@[0-9a-f]+$": | |
| 59 | + type: object | |
| 60 | + description: | |
| 61 | + Child nodes used to define the reference voltages used for each channel | |
| 62 | + | |
| 63 | + properties: | |
| 64 | + reg: | |
| 65 | + description: | | |
| 66 | + Number of the analog input. | |
| 67 | + 0: xp | |
| 68 | + 1: yp | |
| 69 | + 2: xn | |
| 70 | + 3: yn | |
| 71 | + 4: wiper | |
| 72 | + 5: inaux0 | |
| 73 | + 6: inaux1 | |
| 74 | + 7: inaux2 | |
| 75 | + items: | |
| 76 | + - minimum: 0 | |
| 77 | + maximum: 7 | |
| 78 | + | |
| 79 | + fsl,adc-refp: | |
| 80 | + $ref: /schemas/types.yaml#/definitions/uint32 | |
| 81 | + description: | | |
| 82 | + Specifies the positive reference input as defined in | |
| 83 | + <dt-bindings/iio/adc/fsl-imx25-gcq.h> | |
| 84 | + 0: YP voltage reference | |
| 85 | + 1: XP voltage reference | |
| 86 | + 2: External voltage reference | |
| 87 | + 3: Internal voltage reference (default) | |
| 88 | + minimum: 0 | |
| 89 | + maximum: 3 | |
| 90 | + | |
| 91 | + fsl,adc-refn: | |
| 92 | + $ref: /schemas/types.yaml#/definitions/uint32 | |
| 93 | + description: | | |
| 94 | + Specifies the negative reference input as defined in | |
| 95 | + <dt-bindings/iio/adc/fsl-imx25-gcq.h> | |
| 96 | + 0: XN ground reference | |
| 97 | + 1: YN ground reference | |
| 98 | + 2: Internal ground reference | |
| 99 | + 3: External ground reference (default) | |
| 100 | + minimum: 0 | |
| 101 | + maximum: 3 | |
| 102 | + | |
| 103 | + required: | |
| 104 | + - reg | |
| 105 | + | |
| 106 | + additionalProperties: false | |
| 107 | + | |
| 108 | +additionalProperties: false | |
| 109 | + | |
| 110 | +examples: | |
| 111 | + - | | |
| 112 | + #include <dt-bindings/iio/adc/fsl-imx25-gcq.h> | |
| 113 | + soc { | |
| 114 | + #address-cells = <1>; | |
| 115 | + #size-cells = <1>; | |
| 116 | + adc@50030800 { | |
| 117 | + compatible = "fsl,imx25-gcq"; | |
| 118 | + reg = <0x50030800 0x60>; | |
| 119 | + interrupt-parent = <&tscadc>; | |
| 120 | + interrupts = <1>; | |
| 121 | + #address-cells = <1>; | |
| 122 | + #size-cells = <0>; | |
| 123 | + | |
| 124 | + inaux@5 { | |
| 125 | + reg = <5>; | |
| 126 | + fsl,adc-refp = <MX25_ADC_REFP_INT>; | |
| 127 | + fsl,adc-refn = <MX25_ADC_REFN_NGND>; | |
| 128 | + }; | |
| 129 | + }; | |
| 130 | + }; | |
| 131 | +... | |
| @@ -0,0 +1,62 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/fsl,imx7d-adc.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Freescale ADC found on the imx7d SoC | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Haibo Chen <haibo.chen@nxp.com> | |
| 11 | + | |
| 12 | +properties: | |
| 13 | + compatible: | |
| 14 | + const: fsl,imx7d-adc | |
| 15 | + | |
| 16 | + reg: | |
| 17 | + maxItems: 1 | |
| 18 | + | |
| 19 | + interrupts: | |
| 20 | + maxItems: 1 | |
| 21 | + | |
| 22 | + clocks: | |
| 23 | + maxItems: 1 | |
| 24 | + | |
| 25 | + clock-names: | |
| 26 | + const: adc | |
| 27 | + | |
| 28 | + vref-supply: true | |
| 29 | + | |
| 30 | + "#io-channel-cells": | |
| 31 | + const: 1 | |
| 32 | + | |
| 33 | +required: | |
| 34 | + - compatible | |
| 35 | + - reg | |
| 36 | + - interrupts | |
| 37 | + - clocks | |
| 38 | + - clock-names | |
| 39 | + - vref-supply | |
| 40 | + - "#io-channel-cells" | |
| 41 | + | |
| 42 | +additionalProperties: false | |
| 43 | + | |
| 44 | +examples: | |
| 45 | + - | | |
| 46 | + #include <dt-bindings/interrupt-controller/irq.h> | |
| 47 | + #include <dt-bindings/clock/imx7d-clock.h> | |
| 48 | + #include <dt-bindings/interrupt-controller/arm-gic.h> | |
| 49 | + soc { | |
| 50 | + #address-cells = <1>; | |
| 51 | + #size-cells = <1>; | |
| 52 | + adc@30610000 { | |
| 53 | + compatible = "fsl,imx7d-adc"; | |
| 54 | + reg = <0x30610000 0x10000>; | |
| 55 | + interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; | |
| 56 | + clocks = <&clks IMX7D_ADC_ROOT_CLK>; | |
| 57 | + clock-names = "adc"; | |
| 58 | + vref-supply = <®_vcc_3v3_mcu>; | |
| 59 | + #io-channel-cells = <1>; | |
| 60 | + }; | |
| 61 | + }; | |
| 62 | +... | |
| @@ -0,0 +1,81 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/fsl,vf610-adc.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: ADC found on Freescale vf610 and similar SoCs | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Fugang Duan <fugang.duan@nxp.com> | |
| 11 | + | |
| 12 | +description: | |
| 13 | + ADCs found on vf610/i.MX6slx and upward SoCs from Freescale. | |
| 14 | + | |
| 15 | +properties: | |
| 16 | + compatible: | |
| 17 | + const: fsl,vf610-adc | |
| 18 | + | |
| 19 | + reg: | |
| 20 | + maxItems: 1 | |
| 21 | + | |
| 22 | + interrupts: | |
| 23 | + maxItems: 1 | |
| 24 | + | |
| 25 | + clocks: | |
| 26 | + description: ADC source clock (ipg clock) | |
| 27 | + maxItems: 1 | |
| 28 | + | |
| 29 | + clock-names: | |
| 30 | + const: adc | |
| 31 | + | |
| 32 | + vref-supply: | |
| 33 | + description: ADC reference voltage supply. | |
| 34 | + | |
| 35 | + fsl,adck-max-frequency: | |
| 36 | + $ref: /schemas/types.yaml#/definitions/uint32-array | |
| 37 | + minItems: 3 | |
| 38 | + maxItems: 3 | |
| 39 | + description: | | |
| 40 | + Maximum frequencies from datasheet operating requirements. | |
| 41 | + Three values necessary to cover the 3 conversion modes. | |
| 42 | + * Frequency in normal mode (ADLPC=0, ADHSC=0) | |
| 43 | + * Frequency in high-speed mode (ADLPC=0, ADHSC=1) | |
| 44 | + * Frequency in low-power mode (ADLPC=1, ADHSC=0) | |
| 45 | + | |
| 46 | + min-sample-time: | |
| 47 | + $ref: /schemas/types.yaml#/definitions/uint32 | |
| 48 | + description: | |
| 49 | + Minimum sampling time in nanoseconds. This value has | |
| 50 | + to be chosen according to the conversion mode and the connected analog | |
| 51 | + source resistance (R_as) and capacitance (C_as). Refer the datasheet's | |
| 52 | + operating requirements. A safe default across a wide range of R_as and | |
| 53 | + C_as as well as conversion modes is 1000ns. | |
| 54 | + | |
| 55 | + "#io-channel-cells": | |
| 56 | + const: 1 | |
| 57 | + | |
| 58 | +required: | |
| 59 | + - compatible | |
| 60 | + - reg | |
| 61 | + - interrupts | |
| 62 | + - clocks | |
| 63 | + - clock-names | |
| 64 | + - vref-supply | |
| 65 | + | |
| 66 | +additionalProperties: false | |
| 67 | + | |
| 68 | +examples: | |
| 69 | + - | | |
| 70 | + #include <dt-bindings/clock/vf610-clock.h> | |
| 71 | + adc@4003b000 { | |
| 72 | + compatible = "fsl,vf610-adc"; | |
| 73 | + reg = <0x4003b000 0x1000>; | |
| 74 | + interrupts = <0 53 0x04>; | |
| 75 | + clocks = <&clks VF610_CLK_ADC0>; | |
| 76 | + clock-names = "adc"; | |
| 77 | + fsl,adck-max-frequency = <30000000>, <40000000>, <20000000>; | |
| 78 | + vref-supply = <®_vcc_3v3_mcu>; | |
| 79 | + min-sample-time = <10000>; | |
| 80 | + }; | |
| 81 | +... | |
| @@ -1,21 +0,0 @@ | ||
| 1 | −Holt Integrated Circuits HI-8435 threshold detector bindings | |
| 2 | − | |
| 3 | −Required properties: | |
| 4 | − - compatible: should be "holt,hi8435" | |
| 5 | − - reg: spi chip select number for the device | |
| 6 | − | |
| 7 | −Recommended properties: | |
| 8 | − - spi-max-frequency: definition as per | |
| 9 | − Documentation/devicetree/bindings/spi/spi-bus.txt | |
| 10 | − | |
| 11 | −Optional properties: | |
| 12 | − - gpios: GPIO used for controlling the reset pin | |
| 13 | − | |
| 14 | −Example: | |
| 15 | −sensor@0 { | |
| 16 | − compatible = "holt,hi8435"; | |
| 17 | − reg = <0>; | |
| 18 | − gpios = <&gpio6 1 0>; | |
| 19 | − | |
| 20 | − spi-max-frequency = <1000000>; | |
| 21 | −}; | |
| @@ -0,0 +1,50 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/holt,hi8435.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Holt Integrated Circuits HI-8435 SPI threshold detector | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Vladimir Barinov <vladimir.barinov@cogentembedded.com> | |
| 11 | + | |
| 12 | +description: | | |
| 13 | + Datasheet: http://www.holtic.com/documents/427-hi-8435_v-rev-lpdf.do | |
| 14 | + | |
| 15 | +properties: | |
| 16 | + compatible: | |
| 17 | + const: holt,hi8435 | |
| 18 | + | |
| 19 | + reg: | |
| 20 | + maxItems: 1 | |
| 21 | + | |
| 22 | + gpios: | |
| 23 | + description: | |
| 24 | + GPIO used for controlling the reset pin | |
| 25 | + maxItems: 1 | |
| 26 | + | |
| 27 | + spi-max-frequency: true | |
| 28 | + | |
| 29 | + "#io-channel-cells": | |
| 30 | + const: 1 | |
| 31 | + | |
| 32 | +required: | |
| 33 | + - compatible | |
| 34 | + - reg | |
| 35 | + | |
| 36 | +additionalProperties: false | |
| 37 | + | |
| 38 | +examples: | |
| 39 | + - | | |
| 40 | + spi { | |
| 41 | + #address-cells = <1>; | |
| 42 | + #size-cells = <0>; | |
| 43 | + threshold-detector@0 { | |
| 44 | + compatible = "holt,hi8435"; | |
| 45 | + reg = <0>; | |
| 46 | + gpios = <&gpio6 1 0>; | |
| 47 | + spi-max-frequency = <1000000>; | |
| 48 | + }; | |
| 49 | + }; | |
| 50 | +... | |
| @@ -1,24 +0,0 @@ | ||
| 1 | −Freescale imx7d ADC bindings | |
| 2 | − | |
| 3 | −The devicetree bindings are for the ADC driver written for | |
| 4 | −imx7d SoC. | |
| 5 | − | |
| 6 | −Required properties: | |
| 7 | −- compatible: Should be "fsl,imx7d-adc" | |
| 8 | −- reg: Offset and length of the register set for the ADC device | |
| 9 | −- interrupts: The interrupt number for the ADC device | |
| 10 | −- clocks: The root clock of the ADC controller | |
| 11 | −- clock-names: Must contain "adc", matching entry in the clocks property | |
| 12 | −- vref-supply: The regulator supply ADC reference voltage | |
| 13 | −- #io-channel-cells: Must be 1 as per ../iio-bindings.txt | |
| 14 | − | |
| 15 | −Example: | |
| 16 | −adc1: adc@30610000 { | |
| 17 | − compatible = "fsl,imx7d-adc"; | |
| 18 | − reg = <0x30610000 0x10000>; | |
| 19 | − interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; | |
| 20 | − clocks = <&clks IMX7D_ADC_ROOT_CLK>; | |
| 21 | − clock-names = "adc"; | |
| 22 | − vref-supply = <®_vcc_3v3_mcu>; | |
| 23 | − #io-channel-cells = <1>; | |
| 24 | −}; | |
| @@ -0,0 +1,44 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/lltc,ltc2497.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Linear Technology / Analog Devices LTC2497 ADC | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Michael Hennerich <michael.hennerich@analog.com> | |
| 11 | + | |
| 12 | +description: | | |
| 13 | + 16bit ADC supporting up to 16 single ended or 8 differential inputs. | |
| 14 | + I2C interface. | |
| 15 | + | |
| 16 | +properties: | |
| 17 | + compatible: | |
| 18 | + const: | |
| 19 | + lltc,ltc2497 | |
| 20 | + | |
| 21 | + reg: true | |
| 22 | + vref-supply: true | |
| 23 | + "#io-channel-cells": | |
| 24 | + const: 1 | |
| 25 | + | |
| 26 | +required: | |
| 27 | + - compatible | |
| 28 | + - reg | |
| 29 | + - vref-supply | |
| 30 | + | |
| 31 | +examples: | |
| 32 | + - | | |
| 33 | + i2c { | |
| 34 | + #address-cells = <1>; | |
| 35 | + #size-cells = <0>; | |
| 36 | + | |
| 37 | + adc@76 { | |
| 38 | + compatible = "lltc,ltc2497"; | |
| 39 | + reg = <0x76>; | |
| 40 | + vref-supply = <<c2497_reg>; | |
| 41 | + #io-channel-cells = <1>; | |
| 42 | + }; | |
| 43 | + }; | |
| 44 | +... | |
| @@ -1,20 +0,0 @@ | ||
| 1 | −NXP LPC1850 ADC bindings | |
| 2 | − | |
| 3 | −Required properties: | |
| 4 | −- compatible: Should be "nxp,lpc1850-adc" | |
| 5 | −- reg: Offset and length of the register set for the ADC device | |
| 6 | −- interrupts: The interrupt number for the ADC device | |
| 7 | −- clocks: The root clock of the ADC controller | |
| 8 | −- vref-supply: The regulator supply ADC reference voltage | |
| 9 | −- resets: phandle to reset controller and line specifier | |
| 10 | − | |
| 11 | −Example: | |
| 12 | − | |
| 13 | −adc0: adc@400e3000 { | |
| 14 | − compatible = "nxp,lpc1850-adc"; | |
| 15 | − reg = <0x400e3000 0x1000>; | |
| 16 | − interrupts = <17>; | |
| 17 | − clocks = <&ccu1 CLK_APB3_ADC0>; | |
| 18 | − vref-supply = <®_vdda>; | |
| 19 | − resets = <&rgu 40>; | |
| 20 | −}; | |
| @@ -1,21 +0,0 @@ | ||
| 1 | −* NXP LPC32xx SoC ADC controller | |
| 2 | − | |
| 3 | −Required properties: | |
| 4 | −- compatible: must be "nxp,lpc3220-adc" | |
| 5 | −- reg: physical base address of the controller and length of memory mapped | |
| 6 | − region. | |
| 7 | −- interrupts: The ADC interrupt | |
| 8 | − | |
| 9 | −Optional: | |
| 10 | − - vref-supply: The regulator supply ADC reference voltage, optional | |
| 11 | − for legacy reason, but highly encouraging to us in new device tree | |
| 12 | − | |
| 13 | −Example: | |
| 14 | − | |
| 15 | − adc@40048000 { | |
| 16 | − compatible = "nxp,lpc3220-adc"; | |
| 17 | − reg = <0x40048000 0x1000>; | |
| 18 | − interrupt-parent = <&mic>; | |
| 19 | − interrupts = <39 0>; | |
| 20 | − vref-supply = <&vcc>; | |
| 21 | − }; | |
| @@ -1,13 +0,0 @@ | ||
| 1 | −* Linear Technology / Analog Devices LTC2497 ADC | |
| 2 | − | |
| 3 | −Required properties: | |
| 4 | − - compatible: Must be "lltc,ltc2497" | |
| 5 | − - reg: Must contain the ADC I2C address | |
| 6 | − - vref-supply: The regulator supply for ADC reference voltage | |
| 7 | − | |
| 8 | −Example: | |
| 9 | − ltc2497: adc@76 { | |
| 10 | − compatible = "lltc,ltc2497"; | |
| 11 | − reg = <0x76>; | |
| 12 | − vref-supply = <<c2497_reg>; | |
| 13 | − }; | |
| @@ -0,0 +1,50 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/marvell,berlin2-adc.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Berlin 2 Analog to Digital Converter (ADC) | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Antoine Tenart <antoine.tenart@free-electrons.com> | |
| 11 | + | |
| 12 | +description: | |
| 13 | + The Berlin ADC has 8 channels, with one connected to a temperature sensor. | |
| 14 | + It is part of the system controller register set. The ADC node should be a | |
| 15 | + sub-node of the system controller node. | |
| 16 | + | |
| 17 | +properties: | |
| 18 | + compatible: | |
| 19 | + const: marvell,berlin2-adc | |
| 20 | + | |
| 21 | + interrupts: | |
| 22 | + minItems: 2 | |
| 23 | + maxItems: 2 | |
| 24 | + | |
| 25 | + interrupt-names: | |
| 26 | + items: | |
| 27 | + - const: adc | |
| 28 | + - const: tsen | |
| 29 | + | |
| 30 | + "#io-channel-cells": | |
| 31 | + const: 1 | |
| 32 | + | |
| 33 | +required: | |
| 34 | + - compatible | |
| 35 | + - interrupts | |
| 36 | + - interrupt-names | |
| 37 | + | |
| 38 | +additionalProperties: false | |
| 39 | + | |
| 40 | +examples: | |
| 41 | + - | | |
| 42 | + sysctrl { | |
| 43 | + adc { | |
| 44 | + compatible = "marvell,berlin2-adc"; | |
| 45 | + interrupt-parent = <&sic>; | |
| 46 | + interrupts = <12>, <14>; | |
| 47 | + interrupt-names = "adc", "tsen"; | |
| 48 | + }; | |
| 49 | + }; | |
| 50 | +... | |
| @@ -1,18 +0,0 @@ | ||
| 1 | −* Maxim max11100 Analog to Digital Converter (ADC) | |
| 2 | − | |
| 3 | −Required properties: | |
| 4 | − - compatible: Should be "maxim,max11100" | |
| 5 | − - reg: the adc unit address | |
| 6 | − - vref-supply: phandle to the regulator that provides reference voltage | |
| 7 | − | |
| 8 | −Optional properties: | |
| 9 | − - spi-max-frequency: SPI maximum frequency | |
| 10 | − | |
| 11 | −Example: | |
| 12 | − | |
| 13 | −max11100: adc@0 { | |
| 14 | − compatible = "maxim,max11100"; | |
| 15 | − reg = <0>; | |
| 16 | − vref-supply = <&adc0_vref>; | |
| 17 | − spi-max-frequency = <240000>; | |
| 18 | −}; | |
| @@ -1,21 +0,0 @@ | ||
| 1 | −* MAX1117/MAX1118/MAX1119 8-bit, dual-channel ADCs | |
| 2 | − | |
| 3 | −Required properties: | |
| 4 | − - compatible: Should be one of | |
| 5 | − * "maxim,max1117" | |
| 6 | − * "maxim,max1118" | |
| 7 | − * "maxim,max1119" | |
| 8 | − - reg: spi chip select number for the device | |
| 9 | − - (max1118 only) vref-supply: The regulator supply for ADC reference voltage | |
| 10 | − | |
| 11 | −Recommended properties: | |
| 12 | − - spi-max-frequency: Definition as per | |
| 13 | − Documentation/devicetree/bindings/spi/spi-bus.txt | |
| 14 | − | |
| 15 | −Example: | |
| 16 | −adc@0 { | |
| 17 | − compatible = "maxim,max1118"; | |
| 18 | − reg = <0>; | |
| 19 | − vref-supply = <&vdd_supply>; | |
| 20 | − spi-max-frequency = <1000000>; | |
| 21 | −}; | |
| @@ -1,27 +0,0 @@ | ||
| 1 | −* Maxim max9611/max9612 current sense amplifier with 12-bits ADC interface | |
| 2 | − | |
| 3 | −Maxim max9611/max9612 is an high-side current sense amplifier with integrated | |
| 4 | −12-bits ADC communicating over I2c bus. | |
| 5 | −The device node for this driver shall be a child of a I2c controller. | |
| 6 | − | |
| 7 | −Required properties | |
| 8 | − - compatible: Should be "maxim,max9611" or "maxim,max9612" | |
| 9 | − - reg: The 7-bits long I2c address of the device | |
| 10 | − - shunt-resistor-micro-ohms: Value, in micro Ohms, of the current sense shunt | |
| 11 | − resistor | |
| 12 | − | |
| 13 | −Example: | |
| 14 | − | |
| 15 | −&i2c4 { | |
| 16 | − csa: adc@7c { | |
| 17 | − compatible = "maxim,max9611"; | |
| 18 | − reg = <0x7c>; | |
| 19 | − | |
| 20 | − shunt-resistor-micro-ohms = <5000>; | |
| 21 | − }; | |
| 22 | −}; | |
| 23 | − | |
| 24 | −This device node describes a current sense amplifier sitting on I2c4 bus | |
| 25 | −with address 0x7c (read address is 0xf9, write address is 0xf8). | |
| 26 | −A sense resistor of 0,005 Ohm is installed between RS+ and RS- current-sensing | |
| 27 | −inputs. | |
| @@ -0,0 +1,49 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/maxim,max11100.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Maxim MAX11100 ADC | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Jacopo Mondi <jacopo@jmondi.org> | |
| 11 | + | |
| 12 | +description: | | |
| 13 | + Single channel 16 bit ADC with SPI interface. | |
| 14 | + | |
| 15 | +properties: | |
| 16 | + compatible: | |
| 17 | + const: maxim,max11100 | |
| 18 | + | |
| 19 | + reg: | |
| 20 | + maxItems: 1 | |
| 21 | + | |
| 22 | + vref-supply: | |
| 23 | + description: External reference, needed to establish input scaling. | |
| 24 | + | |
| 25 | + spi-max-frequency: | |
| 26 | + minimum: 100000 | |
| 27 | + maximum: 4800000 | |
| 28 | + | |
| 29 | +additionalProperties: false | |
| 30 | + | |
| 31 | +required: | |
| 32 | + - compatible | |
| 33 | + - reg | |
| 34 | + - vref-supply | |
| 35 | + | |
| 36 | +examples: | |
| 37 | + - | | |
| 38 | + spi { | |
| 39 | + #address-cells = <1>; | |
| 40 | + #size-cells = <0>; | |
| 41 | + | |
| 42 | + adc@0 { | |
| 43 | + compatible = "maxim,max11100"; | |
| 44 | + reg = <0>; | |
| 45 | + vref-supply = <&adc_vref>; | |
| 46 | + spi-max-frequency = <240000>; | |
| 47 | + }; | |
| 48 | + }; | |
| 49 | +... | |
| @@ -0,0 +1,62 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/maxim,max1118.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Maxim MAX1118 and similar ADCs | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Akinobu Mita <akinobu.mita@gmail.com> | |
| 11 | + | |
| 12 | +description: | | |
| 13 | + Dual channel 8bit ADCs. | |
| 14 | + | |
| 15 | +properties: | |
| 16 | + compatible: | |
| 17 | + enum: | |
| 18 | + - maxim,max1117 | |
| 19 | + - maxim,max1118 | |
| 20 | + - maxim,max1119 | |
| 21 | + | |
| 22 | + reg: | |
| 23 | + maxItems: 1 | |
| 24 | + | |
| 25 | + spi-max-frequency: | |
| 26 | + maximum: 5000000 | |
| 27 | + | |
| 28 | + vref-supply: | |
| 29 | + description: External reference, needed to establish input scaling | |
| 30 | + | |
| 31 | +if: | |
| 32 | + properties: | |
| 33 | + compatible: | |
| 34 | + contains: | |
| 35 | + const: maxim,max1118 | |
| 36 | +then: | |
| 37 | + required: | |
| 38 | + - vref-supply | |
| 39 | +else: | |
| 40 | + properties: | |
| 41 | + vref-supply: false | |
| 42 | + | |
| 43 | +required: | |
| 44 | + - compatible | |
| 45 | + - reg | |
| 46 | + | |
| 47 | +additionalProperties: false | |
| 48 | + | |
| 49 | +examples: | |
| 50 | + - | | |
| 51 | + spi { | |
| 52 | + #address-cells = <1>; | |
| 53 | + #size-cells = <0>; | |
| 54 | + | |
| 55 | + adc@0 { | |
| 56 | + compatible = "maxim,max1118"; | |
| 57 | + reg = <0>; | |
| 58 | + vref-supply = <&adc_vref>; | |
| 59 | + spi-max-frequency = <1000000>; | |
| 60 | + }; | |
| 61 | + }; | |
| 62 | +... | |
| @@ -0,0 +1,51 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/maxim,max9611.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Maxim MAX9611 and similar current sense amplifiers with integrated ADCs | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Jacopo Mondi <jacopo@jmondi.org> | |
| 11 | + | |
| 12 | +description: | | |
| 13 | + These devices combine a high-side current sense amplifier with a 12 bit ADC. | |
| 14 | + They have an i2c interface. | |
| 15 | + | |
| 16 | +properties: | |
| 17 | + compatible: | |
| 18 | + enum: | |
| 19 | + - maxim,max9611 | |
| 20 | + - maxim,max9612 | |
| 21 | + | |
| 22 | + reg: | |
| 23 | + maxItems: 1 | |
| 24 | + | |
| 25 | + shunt-resistor-micro-ohms: | |
| 26 | + $ref: /schemas/types.yaml#/definitions/uint32 | |
| 27 | + description: | | |
| 28 | + Value in micro Ohms of the shunt resistor connected between the RS+ and | |
| 29 | + RS- inputs, across which the current is measured. Value needed to compute | |
| 30 | + the scaling of the measured current. | |
| 31 | + | |
| 32 | +additionalProperties: false | |
| 33 | + | |
| 34 | +required: | |
| 35 | + - compatible | |
| 36 | + - reg | |
| 37 | + - shunt-resistor-micro-ohms | |
| 38 | + | |
| 39 | +examples: | |
| 40 | + - | | |
| 41 | + i2c { | |
| 42 | + #address-cells = <1>; | |
| 43 | + #size-cells = <0>; | |
| 44 | + | |
| 45 | + adc@7c { | |
| 46 | + compatible = "maxim,max9611"; | |
| 47 | + reg = <0x7c>; | |
| 48 | + shunt-resistor-micro-ohms = <5000>; | |
| 49 | + }; | |
| 50 | + }; | |
| 51 | +... | |
| @@ -1,57 +0,0 @@ | ||
| 1 | −* Microchip Analog to Digital Converter (ADC) | |
| 2 | − | |
| 3 | −The node for this driver must be a child node of a SPI controller, hence | |
| 4 | −all mandatory properties described in | |
| 5 | − | |
| 6 | − Documentation/devicetree/bindings/spi/spi-bus.txt | |
| 7 | − | |
| 8 | −must be specified. | |
| 9 | − | |
| 10 | −Required properties: | |
| 11 | − - compatible: Must be one of the following, depending on the | |
| 12 | − model: | |
| 13 | − "mcp3001" (DEPRECATED) | |
| 14 | − "mcp3002" (DEPRECATED) | |
| 15 | − "mcp3004" (DEPRECATED) | |
| 16 | − "mcp3008" (DEPRECATED) | |
| 17 | − "mcp3201" (DEPRECATED) | |
| 18 | − "mcp3202" (DEPRECATED) | |
| 19 | − "mcp3204" (DEPRECATED) | |
| 20 | − "mcp3208" (DEPRECATED) | |
| 21 | − "mcp3301" (DEPRECATED) | |
| 22 | − | |
| 23 | − "microchip,mcp3001" | |
| 24 | − "microchip,mcp3002" | |
| 25 | − "microchip,mcp3004" | |
| 26 | − "microchip,mcp3008" | |
| 27 | − "microchip,mcp3201" | |
| 28 | − "microchip,mcp3202" | |
| 29 | − "microchip,mcp3204" | |
| 30 | − "microchip,mcp3208" | |
| 31 | − "microchip,mcp3301" | |
| 32 | − "microchip,mcp3550-50" | |
| 33 | − "microchip,mcp3550-60" | |
| 34 | − "microchip,mcp3551" | |
| 35 | − "microchip,mcp3553" | |
| 36 | − | |
| 37 | − NOTE: The use of the compatibles with no vendor prefix | |
| 38 | − is deprecated and only listed because old DT use them. | |
| 39 | − | |
| 40 | − - spi-cpha, spi-cpol (boolean): | |
| 41 | − Either SPI mode (0,0) or (1,1) must be used, so specify | |
| 42 | − none or both of spi-cpha, spi-cpol. The MCP3550/1/3 | |
| 43 | − is more efficient in mode (1,1) as only 3 instead of | |
| 44 | − 4 bytes need to be read from the ADC, but not all SPI | |
| 45 | − masters support it. | |
| 46 | − | |
| 47 | − - vref-supply: Phandle to the external reference voltage supply. | |
| 48 | − | |
| 49 | −Examples: | |
| 50 | −spi_controller { | |
| 51 | − mcp3x0x@0 { | |
| 52 | − compatible = "microchip,mcp3002"; | |
| 53 | − reg = <0>; | |
| 54 | − spi-max-frequency = <1000000>; | |
| 55 | − vref-supply = <&vref_reg>; | |
| 56 | − }; | |
| 57 | −}; | |
| @@ -1,19 +0,0 @@ | ||
| 1 | −* Microchip mcp3421/2/3/4/6/7/8 chip family (ADC) | |
| 2 | − | |
| 3 | −Required properties: | |
| 4 | − - compatible: Should be | |
| 5 | − "microchip,mcp3421" or | |
| 6 | − "microchip,mcp3422" or | |
| 7 | − "microchip,mcp3423" or | |
| 8 | − "microchip,mcp3424" or | |
| 9 | − "microchip,mcp3425" or | |
| 10 | − "microchip,mcp3426" or | |
| 11 | − "microchip,mcp3427" or | |
| 12 | − "microchip,mcp3428" | |
| 13 | − - reg: I2C address for the device | |
| 14 | − | |
| 15 | −Example: | |
| 16 | −adc@0 { | |
| 17 | − compatible = "microchip,mcp3424"; | |
| 18 | − reg = <0x68>; | |
| 19 | −}; | |
| @@ -0,0 +1,77 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/microchip,mcp3201.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Microchip mcp3201 and similar ADCs | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Oskar Andero <oskar.andero@gmail.com> | |
| 11 | + | |
| 12 | +description: | | |
| 13 | + Family of simple ADCs with an I2C inteface. | |
| 14 | + | |
| 15 | +properties: | |
| 16 | + compatible: | |
| 17 | + enum: | |
| 18 | + - microchip,mcp3001 | |
| 19 | + - microchip,mcp3002 | |
| 20 | + - microchip,mcp3004 | |
| 21 | + - microchip,mcp3008 | |
| 22 | + - microchip,mcp3201 | |
| 23 | + - microchip,mcp3202 | |
| 24 | + - microchip,mcp3204 | |
| 25 | + - microchip,mcp3208 | |
| 26 | + - microchip,mcp3301 | |
| 27 | + - microchip,mcp3550-50 | |
| 28 | + - microchip,mcp3550-60 | |
| 29 | + - microchip,mcp3551 | |
| 30 | + - microchip,mcp3553 | |
| 31 | + | |
| 32 | + reg: | |
| 33 | + maxItems: 1 | |
| 34 | + | |
| 35 | + spi-max-frequency: true | |
| 36 | + spi-cpha: true | |
| 37 | + spi-cpol: true | |
| 38 | + | |
| 39 | + vref-supply: | |
| 40 | + description: External reference. | |
| 41 | + | |
| 42 | + "#io-channel-cells": | |
| 43 | + const: 1 | |
| 44 | + | |
| 45 | +dependencies: | |
| 46 | + spi-cpol: [ spi-cpha ] | |
| 47 | + spi-cpha: [ spi-cpol ] | |
| 48 | + | |
| 49 | +required: | |
| 50 | + - compatible | |
| 51 | + - reg | |
| 52 | + - vref-supply | |
| 53 | + | |
| 54 | +additionalProperties: false | |
| 55 | + | |
| 56 | +examples: | |
| 57 | + - | | |
| 58 | + spi { | |
| 59 | + #address-cells = <1>; | |
| 60 | + #size-cells = <0>; | |
| 61 | + | |
| 62 | + adc@0 { | |
| 63 | + compatible = "microchip,mcp3002"; | |
| 64 | + reg = <0>; | |
| 65 | + vref-supply = <&vref_reg>; | |
| 66 | + spi-cpha; | |
| 67 | + spi-cpol; | |
| 68 | + #io-channel-cells = <1>; | |
| 69 | + }; | |
| 70 | + adc@1 { | |
| 71 | + compatible = "microchip,mcp3002"; | |
| 72 | + reg = <1>; | |
| 73 | + vref-supply = <&vref_reg>; | |
| 74 | + spi-max-frequency = <1500000>; | |
| 75 | + }; | |
| 76 | + }; | |
| 77 | +... | |
| @@ -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/adc/motorola,cpcap-adc.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Motorola CPCAP PMIC ADC binding | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Tony Lindgren <tony@atomide.com> | |
| 11 | + | |
| 12 | +description: | |
| 13 | + On Motorola phones like droid 4 there is a custom CPCAP PMIC. This PMIC | |
| 14 | + has ADCs that are used for battery charging and USB PHY VBUS and ID pin | |
| 15 | + detection. | |
| 16 | + | |
| 17 | +properties: | |
| 18 | + compatible: | |
| 19 | + enum: | |
| 20 | + - motorola,cpcap-adc | |
| 21 | + - motorola,mapphone-cpcap-adc | |
| 22 | + | |
| 23 | + interrupts: | |
| 24 | + maxItems: 1 | |
| 25 | + | |
| 26 | + interrupt-names: | |
| 27 | + const: adcdone | |
| 28 | + | |
| 29 | + "#io-channel-cells": | |
| 30 | + const: 1 | |
| 31 | + | |
| 32 | +required: | |
| 33 | + - compatible | |
| 34 | + - interrupts | |
| 35 | + - "#io-channel-cells" | |
| 36 | + | |
| 37 | +additionalProperties: false | |
| 38 | + | |
| 39 | +examples: | |
| 40 | + - | | |
| 41 | + #include <dt-bindings/interrupt-controller/irq.h> | |
| 42 | + pmic { | |
| 43 | + #address-cells = <1>; | |
| 44 | + #size-cells = <0>; | |
| 45 | + adc { | |
| 46 | + compatible = "motorola,mapphone-cpcap-adc"; | |
| 47 | + interrupt-parent = <&cpcap>; | |
| 48 | + interrupts = <8 IRQ_TYPE_NONE>; | |
| 49 | + interrupt-names = "adcdone"; | |
| 50 | + #io-channel-cells = <1>; | |
| 51 | + }; | |
| 52 | + }; | |
| 53 | +... | |
| @@ -0,0 +1,50 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/nuvoton,nau7802.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Nuvoton NAU7802 I2c Analog to Digital Converter (ADC) | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Alexandre Belloni <alexandre.belloni@bootlin.com> | |
| 11 | + - Maxime Ripard <mripard@kernel.org> | |
| 12 | + | |
| 13 | +properties: | |
| 14 | + compatible: | |
| 15 | + const: nuvoton,nau7802 | |
| 16 | + | |
| 17 | + reg: | |
| 18 | + maxItems: 1 | |
| 19 | + | |
| 20 | + interrupts: | |
| 21 | + maxItems: 1 | |
| 22 | + | |
| 23 | + nuvoton,vldo: | |
| 24 | + $ref: /schemas/types.yaml#/definitions/uint32 | |
| 25 | + description: | |
| 26 | + Internal reference voltage in millivolts to be configured. | |
| 27 | + minimum: 2400 | |
| 28 | + maximum: 4500 | |
| 29 | + | |
| 30 | + "#io-channel-cells": | |
| 31 | + const: 1 | |
| 32 | + | |
| 33 | +required: | |
| 34 | + - compatible | |
| 35 | + - reg | |
| 36 | + | |
| 37 | +additionalProperties: false | |
| 38 | + | |
| 39 | +examples: | |
| 40 | + - | | |
| 41 | + i2c { | |
| 42 | + #address-cells = <1>; | |
| 43 | + #size-cells = <0>; | |
| 44 | + nau7802@2a { | |
| 45 | + compatible = "nuvoton,nau7802"; | |
| 46 | + reg = <0x2a>; | |
| 47 | + nuvoton,vldo = <3000>; | |
| 48 | + }; | |
| 49 | + }; | |
| 50 | +... | |
| @@ -1,26 +0,0 @@ | ||
| 1 | −Nuvoton NPCM Analog to Digital Converter (ADC) | |
| 2 | − | |
| 3 | −The NPCM ADC is a 10-bit converter for eight channel inputs. | |
| 4 | − | |
| 5 | −Required properties: | |
| 6 | −- compatible: "nuvoton,npcm750-adc" for the NPCM7XX BMC. | |
| 7 | −- reg: specifies physical base address and size of the registers. | |
| 8 | −- interrupts: Contain the ADC interrupt with flags for falling edge. | |
| 9 | −- resets : phandle to the reset control for this device. | |
| 10 | − | |
| 11 | −Optional properties: | |
| 12 | −- clocks: phandle of ADC reference clock, in case the clock is not | |
| 13 | − added the ADC will use the default ADC sample rate. | |
| 14 | −- vref-supply: The regulator supply ADC reference voltage, in case the | |
| 15 | − vref-supply is not added the ADC will use internal voltage | |
| 16 | − reference. | |
| 17 | − | |
| 18 | −Example: | |
| 19 | − | |
| 20 | −adc: adc@f000c000 { | |
| 21 | − compatible = "nuvoton,npcm750-adc"; | |
| 22 | − reg = <0xf000c000 0x8>; | |
| 23 | − interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; | |
| 24 | − clocks = <&clk NPCM7XX_CLK_ADC>; | |
| 25 | − resets = <&rstc NPCM7XX_RESET_IPSRST1 NPCM7XX_RESET_ADC>; | |
| 26 | −}; | |
| @@ -0,0 +1,64 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/nuvoton,npcm750-adc.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Nuvoton NPCM BMC Analog to Digital Converter (ADC) | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Tomer Maimon <tmaimon77@gmail.com> | |
| 11 | + | |
| 12 | +description: | |
| 13 | + The NPCM ADC is a 10-bit converter for eight channel inputs. | |
| 14 | + | |
| 15 | +properties: | |
| 16 | + compatible: | |
| 17 | + const: nuvoton,npcm750-adc | |
| 18 | + | |
| 19 | + reg: | |
| 20 | + maxItems: 1 | |
| 21 | + | |
| 22 | + interrupts: | |
| 23 | + maxItems: 1 | |
| 24 | + description: ADC interrupt, should be set for falling edge. | |
| 25 | + | |
| 26 | + resets: | |
| 27 | + maxItems: 1 | |
| 28 | + | |
| 29 | + clocks: | |
| 30 | + maxItems: 1 | |
| 31 | + description: If not provided the defulat ADC sample rate will be used. | |
| 32 | + | |
| 33 | + vref-supply: | |
| 34 | + description: If not supplied, the internal voltage reference will be used. | |
| 35 | + | |
| 36 | + "#io-channel-cells": | |
| 37 | + const: 1 | |
| 38 | + | |
| 39 | +required: | |
| 40 | + - compatible | |
| 41 | + - reg | |
| 42 | + - interrupts | |
| 43 | + - resets | |
| 44 | + | |
| 45 | +additionalProperties: false | |
| 46 | + | |
| 47 | +examples: | |
| 48 | + - | | |
| 49 | + #include <dt-bindings/interrupt-controller/irq.h> | |
| 50 | + #include <dt-bindings/interrupt-controller/arm-gic.h> | |
| 51 | + #include <dt-bindings/clock/nuvoton,npcm7xx-clock.h> | |
| 52 | + #include <dt-bindings/reset/nuvoton,npcm7xx-reset.h> | |
| 53 | + soc { | |
| 54 | + #address-cells = <1>; | |
| 55 | + #size-cells = <1>; | |
| 56 | + adc@f000c000 { | |
| 57 | + compatible = "nuvoton,npcm750-adc"; | |
| 58 | + reg = <0xf000c000 0x8>; | |
| 59 | + interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; | |
| 60 | + clocks = <&clk NPCM7XX_CLK_ADC>; | |
| 61 | + resets = <&rstc NPCM7XX_RESET_IPSRST1 NPCM7XX_RESET_ADC>; | |
| 62 | + }; | |
| 63 | + }; | |
| 64 | +... | |
| @@ -1,18 +0,0 @@ | ||
| 1 | −* Nuvoton NAU7802 Analog to Digital Converter (ADC) | |
| 2 | − | |
| 3 | −Required properties: | |
| 4 | − - compatible: Should be "nuvoton,nau7802" | |
| 5 | − - reg: Should contain the ADC I2C address | |
| 6 | − | |
| 7 | −Optional properties: | |
| 8 | − - nuvoton,vldo: Internal reference voltage in millivolts to be | |
| 9 | − configured valid values are between 2400 mV and 4500 mV. | |
| 10 | − - interrupts: IRQ line for the ADC. If not used the driver will use | |
| 11 | − polling. | |
| 12 | − | |
| 13 | −Example: | |
| 14 | −adc2: nau7802@2a { | |
| 15 | − compatible = "nuvoton,nau7802"; | |
| 16 | − reg = <0x2a>; | |
| 17 | − nuvoton,vldo = <3000>; | |
| 18 | −}; | |
| @@ -0,0 +1,61 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/nxp,lpc1850-adc.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: NXP LPC1850 ADC bindings | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Joachim Eastwood <manabian@gmail.com> | |
| 11 | + | |
| 12 | +description: | |
| 13 | + Supports the ADC found on the LPC1850 SoC. | |
| 14 | + | |
| 15 | +properties: | |
| 16 | + compatible: | |
| 17 | + const: nxp,lpc1850-adc | |
| 18 | + | |
| 19 | + reg: | |
| 20 | + maxItems: 1 | |
| 21 | + | |
| 22 | + interrupts: | |
| 23 | + maxItems: 1 | |
| 24 | + | |
| 25 | + clocks: | |
| 26 | + maxItems: 1 | |
| 27 | + | |
| 28 | + vref-supply: true | |
| 29 | + | |
| 30 | + resets: | |
| 31 | + maxItems: 1 | |
| 32 | + | |
| 33 | + "#io-channel-cells": | |
| 34 | + const: 1 | |
| 35 | + | |
| 36 | +required: | |
| 37 | + - compatible | |
| 38 | + - reg | |
| 39 | + - interrupts | |
| 40 | + - clocks | |
| 41 | + - vref-supply | |
| 42 | + - resets | |
| 43 | + | |
| 44 | +additionalProperties: false | |
| 45 | + | |
| 46 | +examples: | |
| 47 | + - | | |
| 48 | + #include <dt-bindings/clock/lpc18xx-ccu.h> | |
| 49 | + soc { | |
| 50 | + #address-cells = <1>; | |
| 51 | + #size-cells = <1>; | |
| 52 | + adc@400e3000 { | |
| 53 | + compatible = "nxp,lpc1850-adc"; | |
| 54 | + reg = <0x400e3000 0x1000>; | |
| 55 | + interrupts = <17>; | |
| 56 | + clocks = <&ccu1 CLK_APB3_ADC0>; | |
| 57 | + vref-supply = <®_vdda>; | |
| 58 | + resets = <&rgu 40>; | |
| 59 | + }; | |
| 60 | + }; | |
| 61 | +... | |
| @@ -0,0 +1,50 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/nxp,lpc3220-adc.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: NXP LPC3220 SoC ADC controller | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Gregory Clement <gregory.clement@bootlin.com> | |
| 11 | + | |
| 12 | +description: | |
| 13 | + This hardware block has been used on several LPC32XX SoCs. | |
| 14 | + | |
| 15 | +properties: | |
| 16 | + compatible: | |
| 17 | + const: nxp,lpc3220-adc | |
| 18 | + | |
| 19 | + reg: | |
| 20 | + maxItems: 1 | |
| 21 | + | |
| 22 | + interrupts: | |
| 23 | + maxItems: 1 | |
| 24 | + | |
| 25 | + vref-supply: true | |
| 26 | + | |
| 27 | + "#io-channel-cells": | |
| 28 | + const: 1 | |
| 29 | + | |
| 30 | +required: | |
| 31 | + - compatible | |
| 32 | + - reg | |
| 33 | + - interrupts | |
| 34 | + | |
| 35 | +additionalProperties: false | |
| 36 | + | |
| 37 | +examples: | |
| 38 | + - | | |
| 39 | + soc { | |
| 40 | + #address-cells = <1>; | |
| 41 | + #size-cells = <1>; | |
| 42 | + adc@40048000 { | |
| 43 | + compatible = "nxp,lpc3220-adc"; | |
| 44 | + reg = <0x40048000 0x1000>; | |
| 45 | + interrupt-parent = <&mic>; | |
| 46 | + interrupts = <39 0>; | |
| 47 | + vref-supply = <&vcc>; | |
| 48 | + }; | |
| 49 | + }; | |
| 50 | +... | |
| @@ -41,7 +41,10 @@ properties: · 40 unmodified lines | ||
| 41 | 41 | maxItems: 2 |
| 42 | 42 | |
| 43 | 43 | interrupts: |
| 44 | − maxItems: 1 | |
| 44 | + description: | |
| 45 | + ADC interrupt followed by optional touchscreen interrupt. | |
| 46 | + minItems: 1 | |
| 47 | + maxItems: 2 | |
| 45 | 48 | |
| 46 | 49 | "#io-channel-cells": |
| 47 | 50 | const: 1 |
| @@ -83,7 +86,6 @@ allOf: · 35 unmodified lines | ||
| 83 | 86 | - samsung,exynos-adc-v2 |
| 84 | 87 | - samsung,exynos3250-adc |
| 85 | 88 | - samsung,exynos4212-adc |
| 86 | − - samsung,s5pv210-adc | |
| 87 | 89 | then: |
| 88 | 90 | required: |
| 89 | 91 | - samsung,syscon-phandle |
| @@ -112,6 +114,15 @@ allOf: · 22 unmodified lines | ||
| 112 | 114 | items: |
| 113 | 115 | - const: adc |
| 114 | 116 | |
| 117 | + - if: | |
| 118 | + required: | |
| 119 | + - has-touchscreen | |
| 120 | + then: | |
| 121 | + properties: | |
| 122 | + interrupts: | |
| 123 | + minItems: 2 | |
| 124 | + maxItems: 2 | |
| 125 | + | |
| 115 | 126 | examples: |
| 116 | 127 | - | |
| 117 | 128 | adc: adc@12d10000 { |
| @@ -0,0 +1,72 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/sprd,sc2720-adc.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Spreadtrum SC27XX series PMICs ADC binding | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Baolin Wang <baolin.wang7@gmail.com> | |
| 11 | + | |
| 12 | +description: | |
| 13 | + Supports the ADC found on these PMICs. | |
| 14 | + | |
| 15 | +properties: | |
| 16 | + compatible: | |
| 17 | + enum: | |
| 18 | + - sprd,sc2720-adc | |
| 19 | + - sprd,sc2721-adc | |
| 20 | + - sprd,sc2723-adc | |
| 21 | + - sprd,sc2730-adc | |
| 22 | + - sprd,sc2731-adc | |
| 23 | + | |
| 24 | + reg: | |
| 25 | + maxItems: 1 | |
| 26 | + | |
| 27 | + interrupts: | |
| 28 | + maxItems: 1 | |
| 29 | + | |
| 30 | + "#io-channel-cells": | |
| 31 | + const: 1 | |
| 32 | + | |
| 33 | + hwlocks: | |
| 34 | + maxItems: 1 | |
| 35 | + | |
| 36 | + nvmem-cells: | |
| 37 | + maxItems: 2 | |
| 38 | + | |
| 39 | + nvmem-cell-names: | |
| 40 | + items: | |
| 41 | + - const: big_scale_calib | |
| 42 | + - const: small_scale_calib | |
| 43 | + | |
| 44 | +required: | |
| 45 | + - compatible | |
| 46 | + - reg | |
| 47 | + - interrupts | |
| 48 | + - "#io-channel-cells" | |
| 49 | + - hwlocks | |
| 50 | + - nvmem-cells | |
| 51 | + - nvmem-cell-names | |
| 52 | + | |
| 53 | +additionalProperties: false | |
| 54 | + | |
| 55 | +examples: | |
| 56 | + - | | |
| 57 | + #include <dt-bindings/interrupt-controller/irq.h> | |
| 58 | + pmic { | |
| 59 | + #address-cells = <1>; | |
| 60 | + #size-cells = <0>; | |
| 61 | + adc@480 { | |
| 62 | + compatible = "sprd,sc2731-adc"; | |
| 63 | + reg = <0x480>; | |
| 64 | + interrupt-parent = <&sc2731_pmic>; | |
| 65 | + interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; | |
| 66 | + #io-channel-cells = <1>; | |
| 67 | + hwlocks = <&hwlock 4>; | |
| 68 | + nvmem-cells = <&adc_big_scale>, <&adc_small_scale>; | |
| 69 | + nvmem-cell-names = "big_scale_calib", "small_scale_calib"; | |
| 70 | + }; | |
| 71 | + }; | |
| 72 | +... | |
| @@ -1,40 +0,0 @@ | ||
| 1 | −Spreadtrum SC27XX series PMICs ADC binding | |
| 2 | − | |
| 3 | −Required properties: | |
| 4 | −- compatible: Should be one of the following. | |
| 5 | − "sprd,sc2720-adc" | |
| 6 | − "sprd,sc2721-adc" | |
| 7 | − "sprd,sc2723-adc" | |
| 8 | − "sprd,sc2730-adc" | |
| 9 | − "sprd,sc2731-adc" | |
| 10 | −- reg: The address offset of ADC controller. | |
| 11 | −- interrupt-parent: The interrupt controller. | |
| 12 | −- interrupts: The interrupt number for the ADC device. | |
| 13 | −- #io-channel-cells: Number of cells in an IIO specifier. | |
| 14 | −- hwlocks: Reference to a phandle of a hwlock provider node. | |
| 15 | −- nvmem-cells: A phandle to the calibration cells provided by eFuse device. | |
| 16 | −- nvmem-cell-names: Should be "big_scale_calib", "small_scale_calib". | |
| 17 | − | |
| 18 | −Example: | |
| 19 | − | |
| 20 | − sc2731_pmic: pmic@0 { | |
| 21 | − compatible = "sprd,sc2731"; | |
| 22 | − reg = <0>; | |
| 23 | − spi-max-frequency = <26000000>; | |
| 24 | − interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>; | |
| 25 | − interrupt-controller; | |
| 26 | − #interrupt-cells = <2>; | |
| 27 | − #address-cells = <1>; | |
| 28 | − #size-cells = <0>; | |
| 29 | − | |
| 30 | − pmic_adc: adc@480 { | |
| 31 | − compatible = "sprd,sc2731-adc"; | |
| 32 | − reg = <0x480>; | |
| 33 | − interrupt-parent = <&sc2731_pmic>; | |
| 34 | − interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; | |
| 35 | − #io-channel-cells = <1>; | |
| 36 | − hwlocks = <&hwlock 4>; | |
| 37 | − nvmem-cells = <&adc_big_scale>, <&adc_small_scale>; | |
| 38 | − nvmem-cell-names = "big_scale_calib", "small_scale_calib"; | |
| 39 | − }; | |
| 40 | − }; | |
| @@ -0,0 +1,45 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/st,stmpe-adc.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: ADC on an STMPE multifunction device. | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Stefan Agner <stefan@agner.ch> | |
| 11 | + | |
| 12 | +description: | |
| 13 | + This ADC forms part of an ST microelectronics STMPE multifunction device . | |
| 14 | + The ADC is shared with the STMPE touchscreen. As a result some ADC related | |
| 15 | + settings are specified in the parent node. | |
| 16 | + The node name myst be stmpe_adc and should be a child node of the stmpe node | |
| 17 | + to which it belongs. | |
| 18 | + | |
| 19 | +properties: | |
| 20 | + compatible: | |
| 21 | + const: st,stmpe-adc | |
| 22 | + | |
| 23 | + st,norequest-mask: | |
| 24 | + $ref: /schemas/types.yaml#/definitions/uint32 | |
| 25 | + description: | |
| 26 | + Bitmask specifying which ADC channels should _not_ be | |
| 27 | + requestable due to different usage (e.g. touch). | |
| 28 | + | |
| 29 | + "#io-channel-cells": | |
| 30 | + const: 1 | |
| 31 | + | |
| 32 | +required: | |
| 33 | + - compatible | |
| 34 | + | |
| 35 | +additionalProperties: false | |
| 36 | + | |
| 37 | +examples: | |
| 38 | + - | | |
| 39 | + stmpe { | |
| 40 | + stmpe_adc { | |
| 41 | + compatible = "st,stmpe-adc"; | |
| 42 | + st,norequest-mask = <0x0F>; /* dont use ADC CH3-0 */ | |
| 43 | + }; | |
| 44 | + }; | |
| 45 | +... | |
| @@ -1,21 +0,0 @@ | ||
| 1 | −STMPE ADC driver | |
| 2 | −---------------- | |
| 3 | − | |
| 4 | −Required properties: | |
| 5 | − - compatible: "st,stmpe-adc" | |
| 6 | − | |
| 7 | −Optional properties: | |
| 8 | −Note that the ADC is shared with the STMPE touchscreen. ADC related settings | |
| 9 | −have to be done in the mfd. | |
| 10 | −- st,norequest-mask: bitmask specifying which ADC channels should _not_ be | |
| 11 | − requestable due to different usage (e.g. touch) | |
| 12 | − | |
| 13 | −Node name must be stmpe_adc and should be child node of stmpe node to | |
| 14 | −which it belongs. | |
| 15 | − | |
| 16 | −Example: | |
| 17 | − | |
| 18 | − stmpe_adc { | |
| 19 | − compatible = "st,stmpe-adc"; | |
| 20 | − st,norequest-mask = <0x0F>; /* dont use ADC CH3-0 */ | |
| 21 | − }; | |
| @@ -0,0 +1,56 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/ti,adc0832.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Texas Instruments ADC0832 and similar ADCs | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Akinobu Mita <akinobu.mita@gmail.com> | |
| 11 | + | |
| 12 | +description: | | |
| 13 | + 8 bit ADCs with 1, 2, 4 or 8 inputs for single ended or differential | |
| 14 | + conversion. | |
| 15 | + | |
| 16 | +properties: | |
| 17 | + compatible: | |
| 18 | + enum: | |
| 19 | + - ti,adc0831 | |
| 20 | + - ti,adc0832 | |
| 21 | + - ti,adc0834 | |
| 22 | + - ti,adc0838 | |
| 23 | + | |
| 24 | + reg: | |
| 25 | + maxItems: 1 | |
| 26 | + | |
| 27 | + spi-max-frequency: true | |
| 28 | + | |
| 29 | + vref-supply: | |
| 30 | + description: External reference, needed to establish input scaling | |
| 31 | + | |
| 32 | + "#io-channel-cells": | |
| 33 | + const: 1 | |
| 34 | + | |
| 35 | +required: | |
| 36 | + - compatible | |
| 37 | + - reg | |
| 38 | + - vref-supply | |
| 39 | + | |
| 40 | +additionalProperties: false | |
| 41 | + | |
| 42 | +examples: | |
| 43 | + - | | |
| 44 | + spi { | |
| 45 | + #address-cells = <1>; | |
| 46 | + #size-cells = <0>; | |
| 47 | + | |
| 48 | + adc@0 { | |
| 49 | + compatible = "ti,adc0832"; | |
| 50 | + reg = <0>; | |
| 51 | + vref-supply = <&vdd_supply>; | |
| 52 | + spi-max-frequency = <200000>; | |
| 53 | + #io-channel-cells = <1>; | |
| 54 | + }; | |
| 55 | + }; | |
| 56 | +... | |
| @@ -0,0 +1,47 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/ti,adc108s102.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Texas Instruments ADC108S102 and ADC128S102 | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Bogdan Pricop <bogdan.pricop@emutex.com> | |
| 11 | + | |
| 12 | +description: | | |
| 13 | + Family of 8 channel, 10/12 bit, SPI, single ended ADCs. | |
| 14 | + | |
| 15 | +properties: | |
| 16 | + compatible: | |
| 17 | + const: | |
| 18 | + ti,adc108s102 | |
| 19 | + | |
| 20 | + reg: true | |
| 21 | + vref-supply: true | |
| 22 | + spi-max-frequency: true | |
| 23 | + "#io-channel-cells": | |
| 24 | + const: 1 | |
| 25 | + | |
| 26 | +required: | |
| 27 | + - compatible | |
| 28 | + - reg | |
| 29 | + - vref-supply | |
| 30 | + | |
| 31 | +additionalProperties: false | |
| 32 | + | |
| 33 | +examples: | |
| 34 | + - | | |
| 35 | + spi { | |
| 36 | + #address-cells= <1>; | |
| 37 | + #size-cells = <0>; | |
| 38 | + | |
| 39 | + adc@0 { | |
| 40 | + compatible = "ti,adc108s102"; | |
| 41 | + reg = <0>; | |
| 42 | + vref-supply = <&vdd_supply>; | |
| 43 | + spi-max-frequency = <1000000>; | |
| 44 | + #io-channel-cells = <1>; | |
| 45 | + }; | |
| 46 | + }; | |
| 47 | +... | |
| @@ -0,0 +1,86 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/ti,adc12138.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Texas Instruments ADC12138 and similar self-calibrating ADCs | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Akinobu Mita <akinobu.mita@gmail.com> | |
| 11 | + | |
| 12 | +description: | | |
| 13 | + 13 bit ADCs with 1, 2 or 8 inputs and self calibrating circuitry to | |
| 14 | + correct for linearity, zero and full scale errors. | |
| 15 | + | |
| 16 | +properties: | |
| 17 | + compatible: | |
| 18 | + enum: | |
| 19 | + - ti,adc12130 | |
| 20 | + - ti,adc12132 | |
| 21 | + - ti,adc12138 | |
| 22 | + | |
| 23 | + reg: | |
| 24 | + maxItems: 1 | |
| 25 | + | |
| 26 | + interrupts: | |
| 27 | + maxItems: 1 | |
| 28 | + description: End of Conversion (EOC) interrupt | |
| 29 | + | |
| 30 | + clocks: | |
| 31 | + maxItems: 1 | |
| 32 | + description: Conversion clock input. | |
| 33 | + | |
| 34 | + spi-max-frequency: true | |
| 35 | + | |
| 36 | + vref-p-supply: | |
| 37 | + description: The regulator supply for positive analog voltage reference | |
| 38 | + | |
| 39 | + vref-n-supply: | |
| 40 | + description: | | |
| 41 | + The regulator supply for negative analog voltage reference | |
| 42 | + (Note that this must not go below GND or exceed vref-p) | |
| 43 | + If not specified, this is assumed to be analog ground. | |
| 44 | + | |
| 45 | + ti,acquisition-time: | |
| 46 | + $ref: /schemas/types.yaml#/definitions/uint32 | |
| 47 | + enum: [ 6, 10, 18, 34 ] | |
| 48 | + description: | | |
| 49 | + The number of conversion clock periods for the S/H's acquisition time. | |
| 50 | + For high source impedances, this value can be increased to 18 or 34. | |
| 51 | + For less ADC accuracy and/or slower CCLK frequencies this value may be | |
| 52 | + decreased to 6. See section 6.0 INPUT SOURCE RESISTANCE in the | |
| 53 | + datasheet for details. | |
| 54 | + | |
| 55 | + "#io-channel-cells": | |
| 56 | + const: 1 | |
| 57 | + | |
| 58 | +required: | |
| 59 | + - compatible | |
| 60 | + - reg | |
| 61 | + - interrupts | |
| 62 | + - clocks | |
| 63 | + - vref-p-supply | |
| 64 | + | |
| 65 | +additionalProperties: false | |
| 66 | + | |
| 67 | +examples: | |
| 68 | + - | | |
| 69 | + #include <dt-bindings/interrupt-controller/irq.h> | |
| 70 | + spi { | |
| 71 | + #address-cells = <1>; | |
| 72 | + #size-cells = <0>; | |
| 73 | + | |
| 74 | + adc@0 { | |
| 75 | + compatible = "ti,adc12138"; | |
| 76 | + reg = <0>; | |
| 77 | + interrupts = <28 IRQ_TYPE_EDGE_RISING>; | |
| 78 | + interrupt-parent = <&gpio1>; | |
| 79 | + clocks = <&cclk>; | |
| 80 | + vref-p-supply = <&ldo4_reg>; | |
| 81 | + spi-max-frequency = <5000000>; | |
| 82 | + ti,acquisition-time = <6>; | |
| 83 | + #io-channel-cells = <1>; | |
| 84 | + }; | |
| 85 | + }; | |
| 86 | +... | |
| @@ -0,0 +1,59 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/ti,adc128s052.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Texas Instruments ADC128S052 and similar ADCs | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Angelo Compagnucci <angelo.compagnucci@gmail.com> | |
| 11 | + | |
| 12 | +description: | | |
| 13 | + Family of 12 bit SPI ADCs with 2 to 8 channels with a range of different | |
| 14 | + target sample rates. | |
| 15 | + | |
| 16 | +properties: | |
| 17 | + compatible: | |
| 18 | + enum: | |
| 19 | + - ti,adc122s021 | |
| 20 | + - ti,adc122s051 | |
| 21 | + - ti,adc122s101 | |
| 22 | + - ti,adc124s021 | |
| 23 | + - ti,adc124s051 | |
| 24 | + - ti,adc124s101 | |
| 25 | + - ti,adc128s052 | |
| 26 | + | |
| 27 | + reg: | |
| 28 | + maxItems: 1 | |
| 29 | + | |
| 30 | + spi-max-frequency: true | |
| 31 | + | |
| 32 | + vref-supply: true | |
| 33 | + | |
| 34 | + "#io-channel-cells": | |
| 35 | + const: 1 | |
| 36 | + | |
| 37 | +required: | |
| 38 | + - compatible | |
| 39 | + - reg | |
| 40 | + - vref-supply | |
| 41 | + | |
| 42 | +additionalProperties: false | |
| 43 | + | |
| 44 | +examples: | |
| 45 | + - | | |
| 46 | + #include <dt-bindings/interrupt-controller/irq.h> | |
| 47 | + spi { | |
| 48 | + #address-cells = <1>; | |
| 49 | + #size-cells = <0>; | |
| 50 | + | |
| 51 | + adc@0 { | |
| 52 | + compatible = "ti,adc128s052"; | |
| 53 | + reg = <0>; | |
| 54 | + vref-supply = <&vdd_supply>; | |
| 55 | + spi-max-frequency = <1000000>; | |
| 56 | + #io-channel-cells = <1>; | |
| 57 | + }; | |
| 58 | + }; | |
| 59 | +... | |
| @@ -0,0 +1,51 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/ti,adc161s626.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Texas Instruments ADC141S626 and ADC161S626 ADCs | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Matt Ranostay <matt.ranostay@konsulko.com> | |
| 11 | + | |
| 12 | +description: | | |
| 13 | + Single channel 14/16bit differential ADCs | |
| 14 | + | |
| 15 | +properties: | |
| 16 | + compatible: | |
| 17 | + enum: | |
| 18 | + - ti,adc141s626 | |
| 19 | + - ti,adc161s626 | |
| 20 | + | |
| 21 | + reg: | |
| 22 | + maxItems: 1 | |
| 23 | + | |
| 24 | + spi-max-frequency: true | |
| 25 | + | |
| 26 | + vdda-supply: true | |
| 27 | + | |
| 28 | + "#io-channel-cells": | |
| 29 | + const: 1 | |
| 30 | + | |
| 31 | +required: | |
| 32 | + - compatible | |
| 33 | + - reg | |
| 34 | + | |
| 35 | +additionalProperties: false | |
| 36 | + | |
| 37 | +examples: | |
| 38 | + - | | |
| 39 | + spi { | |
| 40 | + #address-cells = <1>; | |
| 41 | + #size-cells = <0>; | |
| 42 | + | |
| 43 | + adc@0 { | |
| 44 | + compatible = "ti,adc161s626"; | |
| 45 | + vdda-supply = <&vdda_fixed>; | |
| 46 | + reg = <0>; | |
| 47 | + spi-max-frequency = <4300000>; | |
| 48 | + #io-channel-cells = <1>; | |
| 49 | + }; | |
| 50 | + }; | |
| 51 | +... | |
| @@ -0,0 +1,112 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/ti,ads1015.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: TI ADS1015 4 channel I2C analog to digital converter | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Daniel Baluta <daniel.baluta@nxp.com> | |
| 11 | + | |
| 12 | +description: | | |
| 13 | + Datasheet at: https://www.ti.com/lit/gpn/ads1015 | |
| 14 | + Supports both single ended and differential channels. | |
| 15 | + | |
| 16 | +properties: | |
| 17 | + compatible: | |
| 18 | + const: ti,ads1015 | |
| 19 | + | |
| 20 | + reg: | |
| 21 | + maxItems: 1 | |
| 22 | + | |
| 23 | + "#address-cells": | |
| 24 | + const: 1 | |
| 25 | + | |
| 26 | + "#size-cells": | |
| 27 | + const: 0 | |
| 28 | + | |
| 29 | + "#io-channel-cells": | |
| 30 | + const: 1 | |
| 31 | + | |
| 32 | +required: | |
| 33 | + - compatible | |
| 34 | + - reg | |
| 35 | + - "#address-cells" | |
| 36 | + - "#size-cells" | |
| 37 | + | |
| 38 | +additionalProperties: false | |
| 39 | + | |
| 40 | +patternProperties: | |
| 41 | + "^channel@[0-7]+$": | |
| 42 | + type: object | |
| 43 | + description: | |
| 44 | + Child nodes needed for each channel that the platform uses. | |
| 45 | + | |
| 46 | + properties: | |
| 47 | + reg: | |
| 48 | + description: | | |
| 49 | + 0: Voltage over AIN0 and AIN1. | |
| 50 | + 1: Voltage over AIN0 and AIN3. | |
| 51 | + 2: Voltage over AIN1 and AIN3. | |
| 52 | + 3: Voltage over AIN2 and AIN3. | |
| 53 | + 4: Voltage over AIN0 and GND. | |
| 54 | + 5: Voltage over AIN1 and GND. | |
| 55 | + 6: Voltage over AIN2 and GND. | |
| 56 | + 7: Voltage over AIN3 and GND. | |
| 57 | + items: | |
| 58 | + - minimum: 0 | |
| 59 | + maximum: 7 | |
| 60 | + | |
| 61 | + ti,gain: | |
| 62 | + $ref: /schemas/types.yaml#/definitions/uint32 | |
| 63 | + minimum: 0 | |
| 64 | + maximum: 5 | |
| 65 | + description: | | |
| 66 | + pga is the programmable gain amplifier (values are full scale) | |
| 67 | + 0: +/- 6.144 V | |
| 68 | + 1: +/- 4.096 V | |
| 69 | + 2: +/- 2.048 V (default) | |
| 70 | + 3: +/- 1.024 V | |
| 71 | + 4: +/- 0.512 V | |
| 72 | + 5: +/- 0.256 V | |
| 73 | + | |
| 74 | + ti,datarate: | |
| 75 | + $ref: /schemas/types.yaml#/definitions/uint32 | |
| 76 | + minimum: 0 | |
| 77 | + maximum: 6 | |
| 78 | + description: | | |
| 79 | + Data acquisition rate in samples per second | |
| 80 | + 0: 128 | |
| 81 | + 1: 250 | |
| 82 | + 2: 490 | |
| 83 | + 3: 920 | |
| 84 | + 4: 1600 (default) | |
| 85 | + 5: 2400 | |
| 86 | + 6: 3300 | |
| 87 | + | |
| 88 | + required: | |
| 89 | + - reg | |
| 90 | + | |
| 91 | +examples: | |
| 92 | + - | | |
| 93 | + i2c { | |
| 94 | + #address-cells = <1>; | |
| 95 | + #size-cells = <0>; | |
| 96 | + | |
| 97 | + adc@49 { | |
| 98 | + compatible = "ti,ads1015"; | |
| 99 | + reg = <0x49>; | |
| 100 | + #address-cells = <1>; | |
| 101 | + #size-cells = <0>; | |
| 102 | + channel@0 { | |
| 103 | + reg = <0>; | |
| 104 | + }; | |
| 105 | + channel@4 { | |
| 106 | + reg = <4>; | |
| 107 | + ti,gain = <3>; | |
| 108 | + ti,datarate = <5>; | |
| 109 | + }; | |
| 110 | + }; | |
| 111 | + }; | |
| 112 | +... | |
| @@ -0,0 +1,65 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/ti,ads7950.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Texas Instruments ADS7950 and similar ADCs | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - David Lechner <david@lechnology.com> | |
| 11 | + | |
| 12 | +description: | | |
| 13 | + Family of 4-16 channel, 8-12 bit ADCs with SPI interface. | |
| 14 | + | |
| 15 | +properties: | |
| 16 | + compatible: | |
| 17 | + enum: | |
| 18 | + - ti,ads7950 | |
| 19 | + - ti,ads7951 | |
| 20 | + - ti,ads7952 | |
| 21 | + - ti,ads7953 | |
| 22 | + - ti,ads7954 | |
| 23 | + - ti,ads7955 | |
| 24 | + - ti,ads7956 | |
| 25 | + - ti,ads7957 | |
| 26 | + - ti,ads7958 | |
| 27 | + - ti,ads7959 | |
| 28 | + - ti,ads7960 | |
| 29 | + - ti,ads7961 | |
| 30 | + | |
| 31 | + reg: | |
| 32 | + maxItems: 1 | |
| 33 | + | |
| 34 | + spi-max-frequency: | |
| 35 | + maximum: 20000000 | |
| 36 | + | |
| 37 | + vref-supply: | |
| 38 | + description: Supplies the 2.5V or 5V reference voltage | |
| 39 | + | |
| 40 | + "#io-channel-cells": | |
| 41 | + const: 1 | |
| 42 | + | |
| 43 | +required: | |
| 44 | + - compatible | |
| 45 | + - reg | |
| 46 | + - vref-supply | |
| 47 | + - "#io-channel-cells" | |
| 48 | + | |
| 49 | +additionalProperties: false | |
| 50 | + | |
| 51 | +examples: | |
| 52 | + - | | |
| 53 | + spi { | |
| 54 | + #address-cells = <1>; | |
| 55 | + #size-cells = <0>; | |
| 56 | + | |
| 57 | + adc@0 { | |
| 58 | + compatible = "ti,ads7957"; | |
| 59 | + reg = <0>; | |
| 60 | + vref-supply = <&refin_supply>; | |
| 61 | + spi-max-frequency = <10000000>; | |
| 62 | + #io-channel-cells = <1>; | |
| 63 | + }; | |
| 64 | + }; | |
| 65 | +... | |
| @@ -0,0 +1,51 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/ti,ads8344.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Texas Instruments ADS8344 ADC | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Gregory Clement <gregory.clement@bootlin.com> | |
| 11 | + | |
| 12 | +description: | | |
| 13 | + 16bit 8-channel ADC with single ended inputs. | |
| 14 | + | |
| 15 | +properties: | |
| 16 | + compatible: | |
| 17 | + const: ti,ads8344 | |
| 18 | + | |
| 19 | + reg: | |
| 20 | + maxItems: 1 | |
| 21 | + | |
| 22 | + spi-max-frequency: true | |
| 23 | + | |
| 24 | + vref-supply: | |
| 25 | + description: Supply the 2.5V or 5V reference voltage | |
| 26 | + | |
| 27 | + "#io-channel-cells": | |
| 28 | + const: 1 | |
| 29 | + | |
| 30 | +required: | |
| 31 | + - compatible | |
| 32 | + - reg | |
| 33 | + - vref-supply | |
| 34 | + | |
| 35 | +additionalProperties: false | |
| 36 | + | |
| 37 | +examples: | |
| 38 | + - | | |
| 39 | + spi { | |
| 40 | + #address-cells = <1>; | |
| 41 | + #size-cells = <0>; | |
| 42 | + | |
| 43 | + adc@0 { | |
| 44 | + compatible = "ti,ads8344"; | |
| 45 | + reg = <0>; | |
| 46 | + vref-supply = <&refin_supply>; | |
| 47 | + spi-max-frequency = <10000000>; | |
| 48 | + #io-channel-cells = <1>; | |
| 49 | + }; | |
| 50 | + }; | |
| 51 | +... | |
| @@ -0,0 +1,52 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/ti,tlc4541.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Texas Instruments TLC4541 and similar ADCs | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Phil Reid <preid@electromag.com.au> | |
| 11 | + | |
| 12 | +description: | | |
| 13 | + 14/16bit single channel ADC with SPI interface. | |
| 14 | + | |
| 15 | +properties: | |
| 16 | + compatible: | |
| 17 | + enum: | |
| 18 | + - ti,tlc3541 | |
| 19 | + - ti,tlc4541 | |
| 20 | + | |
| 21 | + reg: | |
| 22 | + maxItems: 1 | |
| 23 | + | |
| 24 | + spi-max-frequency: true | |
| 25 | + | |
| 26 | + vref-supply: true | |
| 27 | + | |
| 28 | + "#io-channel-cells": | |
| 29 | + const: 1 | |
| 30 | + | |
| 31 | +required: | |
| 32 | + - compatible | |
| 33 | + - reg | |
| 34 | + - vref-supply | |
| 35 | + | |
| 36 | +additionalProperties: false | |
| 37 | + | |
| 38 | +examples: | |
| 39 | + - | | |
| 40 | + spi { | |
| 41 | + #address-cells = <1>; | |
| 42 | + #size-cells = <0>; | |
| 43 | + | |
| 44 | + adc@0 { | |
| 45 | + compatible = "ti,tlc4541"; | |
| 46 | + reg = <0>; | |
| 47 | + vref-supply = <&vdd_supply>; | |
| 48 | + spi-max-frequency = <200000>; | |
| 49 | + #io-channel-cells = <1>; | |
| 50 | + }; | |
| 51 | + }; | |
| 52 | +... | |
| @@ -0,0 +1,48 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/adc/ti,twl4030-madc.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: MADC subsystem in the TWL4030 power module | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Sebastian Reichel <sre@kernel.org> | |
| 11 | + | |
| 12 | +description: | |
| 13 | + The MADC subsystem in the TWL4030 consists of a 10-bit ADC | |
| 14 | + combined with a 16-input analog multiplexer. | |
| 15 | + | |
| 16 | +properties: | |
| 17 | + compatible: | |
| 18 | + const: ti,twl4030-madc | |
| 19 | + | |
| 20 | + interrupts: | |
| 21 | + maxItems: 1 | |
| 22 | + | |
| 23 | + ti,system-uses-second-madc-irq: | |
| 24 | + type: boolean | |
| 25 | + description: | |
| 26 | + Set if the second madc irq register should be used, which is intended | |
| 27 | + to be used by Co-Processors (e.g. a modem). | |
| 28 | + | |
| 29 | + "#io-channel-cells": | |
| 30 | + const: 1 | |
| 31 | + | |
| 32 | +required: | |
| 33 | + - compatible | |
| 34 | + - interrupts | |
| 35 | + - "#io-channel-cells" | |
| 36 | + | |
| 37 | +additionalProperties: false | |
| 38 | + | |
| 39 | +examples: | |
| 40 | + - | | |
| 41 | + twl { | |
| 42 | + madc { | |
| 43 | + compatible = "ti,twl4030-madc"; | |
| 44 | + interrupts = <3>; | |
| 45 | + #io-channel-cells = <1>; | |
| 46 | + }; | |
| 47 | + }; | |
| 48 | +... | |
| @@ -1,19 +0,0 @@ | ||
| 1 | −* Texas Instruments' ADC0831/ADC0832/ADC0832/ADC0838 | |
| 2 | − | |
| 3 | −Required properties: | |
| 4 | − - compatible: Should be one of | |
| 5 | − * "ti,adc0831" | |
| 6 | − * "ti,adc0832" | |
| 7 | − * "ti,adc0834" | |
| 8 | − * "ti,adc0838" | |
| 9 | − - reg: spi chip select number for the device | |
| 10 | − - vref-supply: The regulator supply for ADC reference voltage | |
| 11 | − - spi-max-frequency: Max SPI frequency to use (< 400000) | |
| 12 | − | |
| 13 | −Example: | |
| 14 | −adc@0 { | |
| 15 | − compatible = "ti,adc0832"; | |
| 16 | − reg = <0>; | |
| 17 | − vref-supply = <&vdd_supply>; | |
| 18 | − spi-max-frequency = <200000>; | |
| 19 | −}; | |
| @@ -1,18 +0,0 @@ | ||
| 1 | −* Texas Instruments' ADC108S102 and ADC128S102 ADC chip | |
| 2 | − | |
| 3 | −Required properties: | |
| 4 | − - compatible: Should be "ti,adc108s102" | |
| 5 | − - reg: spi chip select number for the device | |
| 6 | − - vref-supply: The regulator supply for ADC reference voltage | |
| 7 | − | |
| 8 | −Recommended properties: | |
| 9 | − - spi-max-frequency: Definition as per | |
| 10 | − Documentation/devicetree/bindings/spi/spi-bus.txt | |
| 11 | − | |
| 12 | −Example: | |
| 13 | −adc@0 { | |
| 14 | − compatible = "ti,adc108s102"; | |
| 15 | − reg = <0>; | |
| 16 | − vref-supply = <&vdd_supply>; | |
| 17 | − spi-max-frequency = <1000000>; | |
| 18 | −}; | |
| @@ -1,37 +0,0 @@ | ||
| 1 | −* Texas Instruments' ADC12130/ADC12132/ADC12138 | |
| 2 | − | |
| 3 | −Required properties: | |
| 4 | − - compatible: Should be one of | |
| 5 | − * "ti,adc12130" | |
| 6 | − * "ti,adc12132" | |
| 7 | − * "ti,adc12138" | |
| 8 | − - reg: SPI chip select number for the device | |
| 9 | − - interrupts: Should contain interrupt for EOC (end of conversion) | |
| 10 | − - clocks: phandle to conversion clock input | |
| 11 | − - spi-max-frequency: Definision as per | |
| 12 | − Documentation/devicetree/bindings/spi/spi-bus.txt | |
| 13 | − - vref-p-supply: The regulator supply for positive analog voltage reference | |
| 14 | − | |
| 15 | −Optional properties: | |
| 16 | − - vref-n-supply: The regulator supply for negative analog voltage reference | |
| 17 | − (Note that this must not go below GND or exceed vref-p) | |
| 18 | − If not specified, this is assumed to be analog ground. | |
| 19 | − - ti,acquisition-time: The number of conversion clock periods for the S/H's | |
| 20 | − acquisition time. Should be one of 6, 10, 18, 34. If not specified, | |
| 21 | − default value of 10 is used. | |
| 22 | − For high source impedances, this value can be increased to 18 or 34. | |
| 23 | − For less ADC accuracy and/or slower CCLK frequencies this value may be | |
| 24 | − decreased to 6. See section 6.0 INPUT SOURCE RESISTANCE in the | |
| 25 | − datasheet for details. | |
| 26 | − | |
| 27 | −Example: | |
| 28 | −adc@0 { | |
| 29 | − compatible = "ti,adc12138"; | |
| 30 | − reg = <0>; | |
| 31 | − interrupts = <28 IRQ_TYPE_EDGE_RISING>; | |
| 32 | − interrupt-parent = <&gpio1>; | |
| 33 | − clocks = <&cclk>; | |
| 34 | − vref-p-supply = <&ldo4_reg>; | |
| 35 | − spi-max-frequency = <5000000>; | |
| 36 | − ti,acquisition-time = <6>; | |
| 37 | −}; | |
| @@ -1,25 +0,0 @@ | ||
| 1 | −* Texas Instruments' ADC128S052, ADC122S021 and ADC124S021 ADC chip | |
| 2 | − | |
| 3 | −Required properties: | |
| 4 | − - compatible: Should be one of: | |
| 5 | − - "ti,adc128s052" | |
| 6 | − - "ti,adc122s021" | |
| 7 | − - "ti,adc122s051" | |
| 8 | − - "ti,adc122s101" | |
| 9 | − - "ti,adc124s021" | |
| 10 | − - "ti,adc124s051" | |
| 11 | − - "ti,adc124s101" | |
| 12 | − - reg: spi chip select number for the device | |
| 13 | − - vref-supply: The regulator supply for ADC reference voltage | |
| 14 | − | |
| 15 | −Recommended properties: | |
| 16 | − - spi-max-frequency: Definition as per | |
| 17 | − Documentation/devicetree/bindings/spi/spi-bus.txt | |
| 18 | − | |
| 19 | −Example: | |
| 20 | −adc@0 { | |
| 21 | − compatible = "ti,adc128s052"; | |
| 22 | − reg = <0>; | |
| 23 | − vref-supply = <&vdd_supply>; | |
| 24 | − spi-max-frequency = <1000000>; | |
| 25 | −}; | |
| @@ -1,18 +0,0 @@ | ||
| 1 | −* Texas Instruments ADC141S626 and ADC161S626 chips | |
| 2 | − | |
| 3 | −Required properties: | |
| 4 | − - compatible: Should be "ti,adc141s626" or "ti,adc161s626" | |
| 5 | − - reg: spi chip select number for the device | |
| 6 | − - vdda-supply: supply voltage to VDDA pin | |
| 7 | − | |
| 8 | −Recommended properties: | |
| 9 | − - spi-max-frequency: Definition as per | |
| 10 | − Documentation/devicetree/bindings/spi/spi-bus.txt | |
| 11 | − | |
| 12 | −Example: | |
| 13 | −adc@0 { | |
| 14 | − compatible = "ti,adc161s626"; | |
| 15 | − vdda-supply = <&vdda_fixed>; | |
| 16 | − reg = <0>; | |
| 17 | − spi-max-frequency = <4300000>; | |
| 18 | −}; | |
| @@ -1,23 +0,0 @@ | ||
| 1 | −* Texas Instruments ADS7950 family of A/DC chips | |
| 2 | − | |
| 3 | −Required properties: | |
| 4 | − - compatible: Must be one of "ti,ads7950", "ti,ads7951", "ti,ads7952", | |
| 5 | − "ti,ads7953", "ti,ads7954", "ti,ads7955", "ti,ads7956", "ti,ads7957", | |
| 6 | − "ti,ads7958", "ti,ads7959", "ti,ads7960", or "ti,ads7961" | |
| 7 | − - reg: SPI chip select number for the device | |
| 8 | − - #io-channel-cells: Must be 1 as per ../iio-bindings.txt | |
| 9 | − - vref-supply: phandle to a regulator node that supplies the 2.5V or 5V | |
| 10 | − reference voltage | |
| 11 | − | |
| 12 | −Recommended properties: | |
| 13 | − - spi-max-frequency: Definition as per | |
| 14 | − Documentation/devicetree/bindings/spi/spi-bus.txt | |
| 15 | − | |
| 16 | −Example: | |
| 17 | −adc@0 { | |
| 18 | − compatible = "ti,ads7957"; | |
| 19 | − reg = <0>; | |
| 20 | − #io-channel-cells = <1>; | |
| 21 | − vref-supply = <&refin_supply>; | |
| 22 | − spi-max-frequency = <10000000>; | |
| 23 | −}; | |
| @@ -1,19 +0,0 @@ | ||
| 1 | −* Texas Instruments ADS8344 A/DC chip | |
| 2 | − | |
| 3 | −Required properties: | |
| 4 | − - compatible: Must be "ti,ads8344" | |
| 5 | − - reg: SPI chip select number for the device | |
| 6 | − - vref-supply: phandle to a regulator node that supplies the | |
| 7 | − reference voltage | |
| 8 | − | |
| 9 | −Recommended properties: | |
| 10 | − - spi-max-frequency: Definition as per | |
| 11 | − Documentation/devicetree/bindings/spi/spi-bus.txt | |
| 12 | − | |
| 13 | −Example: | |
| 14 | −adc@0 { | |
| 15 | − compatible = "ti,ads8344"; | |
| 16 | − reg = <0>; | |
| 17 | − vref-supply = <&refin_supply>; | |
| 18 | − spi-max-frequency = <10000000>; | |
| 19 | −}; | |
| @@ -1,24 +0,0 @@ | ||
| 1 | −* TWL4030 Monitoring Analog to Digital Converter (MADC) | |
| 2 | − | |
| 3 | −The MADC subsystem in the TWL4030 consists of a 10-bit ADC | |
| 4 | −combined with a 16-input analog multiplexer. | |
| 5 | − | |
| 6 | −Required properties: | |
| 7 | − - compatible: Should contain "ti,twl4030-madc". | |
| 8 | − - interrupts: IRQ line for the MADC submodule. | |
| 9 | − - #io-channel-cells: Should be set to <1>. | |
| 10 | − | |
| 11 | −Optional properties: | |
| 12 | − - ti,system-uses-second-madc-irq: boolean, set if the second madc irq register | |
| 13 | − should be used, which is intended to be used | |
| 14 | − by Co-Processors (e.g. a modem). | |
| 15 | − | |
| 16 | −Example: | |
| 17 | − | |
| 18 | −&twl { | |
| 19 | − madc { | |
| 20 | − compatible = "ti,twl4030-madc"; | |
| 21 | − interrupts = <3>; | |
| 22 | − #io-channel-cells = <1>; | |
| 23 | − }; | |
| 24 | −}; | |
| @@ -1,36 +0,0 @@ | ||
| 1 | −Freescale vf610 Analog to Digital Converter bindings | |
| 2 | − | |
| 3 | −The devicetree bindings are for the new ADC driver written for | |
| 4 | −vf610/i.MX6slx and upward SoCs from Freescale. | |
| 5 | − | |
| 6 | −Required properties: | |
| 7 | −- compatible: Should contain "fsl,vf610-adc" | |
| 8 | −- reg: Offset and length of the register set for the device | |
| 9 | −- interrupts: Should contain the interrupt for the device | |
| 10 | −- clocks: The clock is needed by the ADC controller, ADC clock source is ipg clock. | |
| 11 | −- clock-names: Must contain "adc", matching entry in the clocks property. | |
| 12 | −- vref-supply: The regulator supply ADC reference voltage. | |
| 13 | − | |
| 14 | −Recommended properties: | |
| 15 | −- fsl,adck-max-frequency: Maximum frequencies according to datasheets operating | |
| 16 | − requirements. Three values are required, depending on conversion mode: | |
| 17 | − - Frequency in normal mode (ADLPC=0, ADHSC=0) | |
| 18 | − - Frequency in high-speed mode (ADLPC=0, ADHSC=1) | |
| 19 | − - Frequency in low-power mode (ADLPC=1, ADHSC=0) | |
| 20 | −- min-sample-time: Minimum sampling time in nanoseconds. This value has | |
| 21 | − to be chosen according to the conversion mode and the connected analog | |
| 22 | − source resistance (R_as) and capacitance (C_as). Refer the datasheet's | |
| 23 | − operating requirements. A safe default across a wide range of R_as and | |
| 24 | − C_as as well as conversion modes is 1000ns. | |
| 25 | − | |
| 26 | −Example: | |
| 27 | −adc0: adc@4003b000 { | |
| 28 | − compatible = "fsl,vf610-adc"; | |
| 29 | − reg = <0x4003b000 0x1000>; | |
| 30 | − interrupts = <0 53 0x04>; | |
| 31 | − clocks = <&clks VF610_CLK_ADC0>; | |
| 32 | − clock-names = "adc"; | |
| 33 | − fsl,adck-max-frequency = <30000000>, <40000000>, | |
| 34 | − <20000000>; | |
| 35 | − vref-supply = <®_vcc_3v3_mcu>; | |
| 36 | −}; | |
| @@ -19,6 +19,8 @@ description: | · 18 unmodified lines | ||
| 19 | 19 | http://www.atlas-scientific.com/_files/_datasheets/_oem/pH_oem_datasheet.pdf |
| 20 | 20 | http://www.atlas-scientific.com/_files/_datasheets/_oem/RTD_oem_datasheet.pdf |
| 21 | 21 | http://www.atlas-scientific.com/_files/_datasheets/_probe/EZO_CO2_Datasheet.pdf |
| 22 | + https://www.atlas-scientific.com/files/EZO_O2_datasheet.pdf | |
| 23 | + https://www.atlas-scientific.com/files/EZO_HUM_Datasheet.pdf | |
| 22 | 24 | |
| 23 | 25 | properties: |
| 24 | 26 | compatible: |
| @@ -29,6 +31,8 @@ properties: · 4 unmodified lines | ||
| 29 | 31 | - atlas,ph-sm |
| 30 | 32 | - atlas,rtd-sm |
| 31 | 33 | - atlas,co2-ezo |
| 34 | + - atlas,o2-ezo | |
| 35 | + - atlas,hum-ezo | |
| 32 | 36 | |
| 33 | 37 | reg: |
| 34 | 38 | maxItems: 1 |
| @@ -0,0 +1,77 @@ | ||
| 1 | +# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: "http://devicetree.org/schemas/iio/dac/lltc,ltc2632.yaml#" | |
| 5 | +$schema: "http://devicetree.org/meta-schemas/core.yaml#" | |
| 6 | + | |
| 7 | +title: Linear Technology LTC263x 12-/10-/8-Bit Rail-to-Rail DAC | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Michael Hennerich <michael.hennerich@analog.com> | |
| 11 | + | |
| 12 | +description: | | |
| 13 | + Bindings for the Linear Technology LTC2632/2634/2636 DAC | |
| 14 | + Datasheet can be found here: https://www.analog.com/media/en/technical-documentation/data-sheets/LTC263[246].pdf | |
| 15 | + | |
| 16 | +properties: | |
| 17 | + compatible: | |
| 18 | + enum: | |
| 19 | + - lltc,ltc2632-l12 | |
| 20 | + - lltc,ltc2632-l10 | |
| 21 | + - lltc,ltc2632-l8 | |
| 22 | + - lltc,ltc2632-h12 | |
| 23 | + - lltc,ltc2632-h10 | |
| 24 | + - lltc,ltc2632-h8 | |
| 25 | + - lltc,ltc2634-l12 | |
| 26 | + - lltc,ltc2634-l10 | |
| 27 | + - lltc,ltc2634-l8 | |
| 28 | + - lltc,ltc2634-h12 | |
| 29 | + - lltc,ltc2634-h10 | |
| 30 | + - lltc,ltc2634-h8 | |
| 31 | + - lltc,ltc2636-l12 | |
| 32 | + - lltc,ltc2636-l10 | |
| 33 | + - lltc,ltc2636-l8 | |
| 34 | + - lltc,ltc2636-h12 | |
| 35 | + - lltc,ltc2636-h10 | |
| 36 | + - lltc,ltc2636-h8 | |
| 37 | + | |
| 38 | + reg: | |
| 39 | + maxItems: 1 | |
| 40 | + | |
| 41 | + spi-max-frequency: | |
| 42 | + maximum: 2000000 | |
| 43 | + | |
| 44 | + vref-supply: | |
| 45 | + description: | |
| 46 | + Phandle to the external reference voltage supply. This should | |
| 47 | + only be set if there is an external reference voltage connected to the VREF | |
| 48 | + pin. If the property is not set the internal reference is used. | |
| 49 | + | |
| 50 | +required: | |
| 51 | + - compatible | |
| 52 | + - reg | |
| 53 | + | |
| 54 | +additionalProperties: false | |
| 55 | + | |
| 56 | +examples: | |
| 57 | + - | | |
| 58 | + vref: regulator-vref { | |
| 59 | + compatible = "regulator-fixed"; | |
| 60 | + regulator-name = "vref-ltc2632"; | |
| 61 | + regulator-min-microvolt = <1250000>; | |
| 62 | + regulator-max-microvolt = <1250000>; | |
| 63 | + regulator-always-on; | |
| 64 | + }; | |
| 65 | + | |
| 66 | + spi { | |
| 67 | + #address-cells = <1>; | |
| 68 | + #size-cells = <0>; | |
| 69 | + | |
| 70 | + dac@0 { | |
| 71 | + compatible = "lltc,ltc2632"; | |
| 72 | + reg = <0>; /* CS0 */ | |
| 73 | + spi-max-frequency = <1000000>; | |
| 74 | + vref-supply = <&vref>; | |
| 75 | + }; | |
| 76 | + }; | |
| 77 | +... | |
| @@ -1,49 +0,0 @@ | ||
| 1 | −Linear Technology LTC2632/2634/2636 DAC | |
| 2 | − | |
| 3 | −Required properties: | |
| 4 | − - compatible: Has to contain one of the following: | |
| 5 | − lltc,ltc2632-l12 | |
| 6 | − lltc,ltc2632-l10 | |
| 7 | − lltc,ltc2632-l8 | |
| 8 | − lltc,ltc2632-h12 | |
| 9 | − lltc,ltc2632-h10 | |
| 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 | |
| 17 | − lltc,ltc2636-l12 | |
| 18 | − lltc,ltc2636-l10 | |
| 19 | − lltc,ltc2636-l8 | |
| 20 | − lltc,ltc2636-h12 | |
| 21 | − lltc,ltc2636-h10 | |
| 22 | − lltc,ltc2636-h8 | |
| 23 | − | |
| 24 | −Property rules described in Documentation/devicetree/bindings/spi/spi-bus.txt | |
| 25 | −apply. In particular, "reg" and "spi-max-frequency" properties must be given. | |
| 26 | − | |
| 27 | −Optional properties: | |
| 28 | − - vref-supply: Phandle to the external reference voltage supply. This should | |
| 29 | − only be set if there is an external reference voltage connected to the VREF | |
| 30 | − pin. If the property is not set the internal reference is used. | |
| 31 | − | |
| 32 | −Example: | |
| 33 | − | |
| 34 | − vref: regulator-vref { | |
| 35 | − compatible = "regulator-fixed"; | |
| 36 | − regulator-name = "vref-ltc2632"; | |
| 37 | − regulator-min-microvolt = <1250000>; | |
| 38 | − regulator-max-microvolt = <1250000>; | |
| 39 | − regulator-always-on; | |
| 40 | − }; | |
| 41 | − | |
| 42 | − spi_master { | |
| 43 | − dac: ltc2632@0 { | |
| 44 | − compatible = "lltc,ltc2632-l12"; | |
| 45 | − reg = <0>; /* CS0 */ | |
| 46 | − spi-max-frequency = <1000000>; | |
| 47 | − vref-supply = <&vref>; /* optional */ | |
| 48 | − }; | |
| 49 | − }; | |
| @@ -0,0 +1,59 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +# Copyright 2020 Analog Devices Inc. | |
| 3 | +%YAML 1.2 | |
| 4 | +--- | |
| 5 | +$id: http://devicetree.org/schemas/iio/gyroscope/adi,adxrs290.yaml# | |
| 6 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 7 | + | |
| 8 | +title: Analog Devices ADXRS290 Dual-Axis MEMS Gyroscope | |
| 9 | + | |
| 10 | +maintainers: | |
| 11 | + - Nishant Malpani <nish.malpani25@gmail.com> | |
| 12 | + | |
| 13 | +description: | | |
| 14 | + Bindings for the Analog Devices ADXRS290 dual-axis MEMS gyroscope device. | |
| 15 | + https://www.analog.com/media/en/technical-documentation/data-sheets/ADXRS290.pdf | |
| 16 | + | |
| 17 | +properties: | |
| 18 | + compatible: | |
| 19 | + const: adi,adxrs290 | |
| 20 | + | |
| 21 | + reg: | |
| 22 | + maxItems: 1 | |
| 23 | + | |
| 24 | + spi-max-frequency: | |
| 25 | + maximum: 5000000 | |
| 26 | + | |
| 27 | + spi-cpol: true | |
| 28 | + | |
| 29 | + spi-cpha: true | |
| 30 | + | |
| 31 | + interrupts: | |
| 32 | + maxItems: 1 | |
| 33 | + | |
| 34 | +required: | |
| 35 | + - compatible | |
| 36 | + - reg | |
| 37 | + - spi-max-frequency | |
| 38 | + - spi-cpol | |
| 39 | + - spi-cpha | |
| 40 | + | |
| 41 | +additionalProperties: false | |
| 42 | + | |
| 43 | +examples: | |
| 44 | + - | | |
| 45 | + #include <dt-bindings/interrupt-controller/irq.h> | |
| 46 | + spi { | |
| 47 | + #address-cells = <1>; | |
| 48 | + #size-cells = <0>; | |
| 49 | + gyro@0 { | |
| 50 | + compatible = "adi,adxrs290"; | |
| 51 | + reg = <0>; | |
| 52 | + spi-max-frequency = <5000000>; | |
| 53 | + spi-cpol; | |
| 54 | + spi-cpha; | |
| 55 | + interrupt-parent = <&gpio>; | |
| 56 | + interrupts = <25 IRQ_TYPE_EDGE_RISING>; | |
| 57 | + }; | |
| 58 | + }; | |
| 59 | +... | |
| @@ -0,0 +1,45 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/humidity/ti,hdc2010.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: HDC2010/HDC2080 humidity and temperature iio sensors | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Eugene Zaikonnikov <ez@norophonic.com> | |
| 11 | + | |
| 12 | +description: | | |
| 13 | + Relative humidity and tempereature sensors on I2C bus | |
| 14 | + | |
| 15 | + Datasheets are available at: | |
| 16 | + http://www.ti.com/product/HDC2010/datasheet | |
| 17 | + http://www.ti.com/product/HDC2080/datasheet | |
| 18 | + | |
| 19 | +properties: | |
| 20 | + compatible: | |
| 21 | + enum: | |
| 22 | + - ti,hdc2010 | |
| 23 | + - ti,hdc2080 | |
| 24 | + | |
| 25 | + vdd-supply: | |
| 26 | + maxItems: 1 | |
| 27 | + | |
| 28 | + reg: | |
| 29 | + maxItems: 1 | |
| 30 | + | |
| 31 | +required: | |
| 32 | + - compatible | |
| 33 | + - reg | |
| 34 | + | |
| 35 | +examples: | |
| 36 | + - | | |
| 37 | + i2c0 { | |
| 38 | + #address-cells = <1>; | |
| 39 | + #size-cells = <0>; | |
| 40 | + | |
| 41 | + humidity@40 { | |
| 42 | + compatible = "ti,hdc2010"; | |
| 43 | + reg = <0x40>; | |
| 44 | + }; | |
| 45 | + }; | |
| @@ -0,0 +1,54 @@ | ||
| 1 | +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/light/ams,as73211.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: AMS AS73211 JENCOLOR(R) Digital XYZ Sensor | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Christian Eggers <ceggers@arri.de> | |
| 11 | + | |
| 12 | +description: | | |
| 13 | + XYZ True Color Sensor with I2C Interface | |
| 14 | + https://ams.com/documents/20143/36005/AS73211_DS000556_3-01.pdf/a65474c0-b302-c2fd-e30a-c98df87616df | |
| 15 | + | |
| 16 | +properties: | |
| 17 | + compatible: | |
| 18 | + enum: | |
| 19 | + - ams,as73211 | |
| 20 | + | |
| 21 | + reg: | |
| 22 | + description: | |
| 23 | + I2C address of the device (0x74...0x77). | |
| 24 | + maxItems: 1 | |
| 25 | + | |
| 26 | + interrupts: | |
| 27 | + description: | |
| 28 | + Interrupt specifier for the READY interrupt generated by the device. | |
| 29 | + maxItems: 1 | |
| 30 | + | |
| 31 | +required: | |
| 32 | + - compatible | |
| 33 | + - reg | |
| 34 | + | |
| 35 | +additionalProperties: false | |
| 36 | + | |
| 37 | +examples: | |
| 38 | + - | | |
| 39 | + #include <dt-bindings/interrupt-controller/irq.h> | |
| 40 | + | |
| 41 | + i2c { | |
| 42 | + #address-cells = <1>; | |
| 43 | + #size-cells = <0>; | |
| 44 | + | |
| 45 | + as73211@74 { | |
| 46 | + compatible = "ams,as73211"; | |
| 47 | + reg = <0x74>; | |
| 48 | + pinctrl-names = "default"; | |
| 49 | + pinctrl-0 = <&pinctrl_color_sensor>; | |
| 50 | + interrupt-parent = <&gpio2>; | |
| 51 | + interrupts = <19 IRQ_TYPE_EDGE_RISING>; /* READY */ | |
| 52 | + }; | |
| 53 | + }; | |
| 54 | +... | |
| @@ -24,6 +24,10 @@ properties: · 23 unmodified lines | ||
| 24 | 24 | - vishay,vcnl4020 |
| 25 | 25 | - vishay,vcnl4040 |
| 26 | 26 | - vishay,vcnl4200 |
| 27 | + | |
| 28 | + interrupts: | |
| 29 | + maxItems: 1 | |
| 30 | + | |
| 27 | 31 | reg: |
| 28 | 32 | maxItems: 1 |
| 29 | 33 | |
| @@ -0,0 +1,65 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/iio/proximity/semtech,sx9310.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Semtech's SX9310 capacitive proximity sensor | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Daniel Campello <campello@chromium.org> | |
| 11 | + | |
| 12 | +description: | | |
| 13 | + Semtech's SX9310/SX9311 capacitive proximity/button solution. | |
| 14 | + | |
| 15 | + Specifications about the devices can be found at: | |
| 16 | + https://www.semtech.com/products/smart-sensing/sar-sensors/sx9310 | |
| 17 | + | |
| 18 | +properties: | |
| 19 | + compatible: | |
| 20 | + enum: | |
| 21 | + - semtech,sx9310 | |
| 22 | + - semtech,sx9311 | |
| 23 | + | |
| 24 | + reg: | |
| 25 | + maxItems: 1 | |
| 26 | + | |
| 27 | + interrupts: | |
| 28 | + description: | |
| 29 | + The sole interrupt generated by the device used to announce the | |
| 30 | + preceding reading request has finished and that data is | |
| 31 | + available or that a close/far proximity event has happened. | |
| 32 | + maxItems: 1 | |
| 33 | + | |
| 34 | + vdd-supply: | |
| 35 | + description: Main power supply | |
| 36 | + | |
| 37 | + svdd-supply: | |
| 38 | + description: Host interface power supply | |
| 39 | + | |
| 40 | + "#io-channel-cells": | |
| 41 | + const: 1 | |
| 42 | + | |
| 43 | +required: | |
| 44 | + - compatible | |
| 45 | + - reg | |
| 46 | + - "#io-channel-cells" | |
| 47 | + | |
| 48 | +additionalProperties: false | |
| 49 | + | |
| 50 | +examples: | |
| 51 | + - | | |
| 52 | + #include <dt-bindings/interrupt-controller/irq.h> | |
| 53 | + i2c { | |
| 54 | + #address-cells = <1>; | |
| 55 | + #size-cells = <0>; | |
| 56 | + proximity@28 { | |
| 57 | + compatible = "semtech,sx9310"; | |
| 58 | + reg = <0x28>; | |
| 59 | + interrupt-parent = <&pio>; | |
| 60 | + interrupts = <5 IRQ_TYPE_LEVEL_LOW 5>; | |
| 61 | + vdd-supply = <&pp3300_a>; | |
| 62 | + svdd-supply = <&pp1800_prox>; | |
| 63 | + #io-channel-cells = <1>; | |
| 64 | + }; | |
| 65 | + }; | |
| @@ -4,9 +4,15 @@ Required properties: · 3 unmodified lines | ||
| 4 | 4 | - compatible: must be "st,vl53l0x" |
| 5 | 5 | - reg: i2c address where to find the device |
| 6 | 6 | |
| 7 | +Optional properties: | |
| 8 | + - interrupts: Interrupt for notifying that new measurement is ready. | |
| 9 | + If no interrupt is specified, polling is used. | |
| 10 | + | |
| 7 | 11 | Example: |
| 8 | 12 | |
| 9 | 13 | vl53l0x@29 { |
| 10 | 14 | compatible = "st,vl53l0x"; |
| 11 | 15 | reg = <0x29>; |
| 16 | + interrupt-parent = <&gpio>; | |
| 17 | + interrupts = <23 IRQ_TYPE_EDGE_FALLING>; | |
| 12 | 18 | }; |
| @@ -132,6 +132,22 @@ properties: · 131 unmodified lines | ||
| 132 | 132 | - mcube,mc3230 |
| 133 | 133 | # MEMSIC 2-axis 8-bit digital accelerometer |
| 134 | 134 | - memsic,mxc6225 |
| 135 | + # Microchip differential I2C ADC, 1 Channel, 18 bit | |
| 136 | + - microchip,mcp3421 | |
| 137 | + # Microchip differential I2C ADC, 2 Channel, 18 bit | |
| 138 | + - microchip,mcp3422 | |
| 139 | + # Microchip differential I2C ADC, 2 Channel, 18 bit | |
| 140 | + - microchip,mcp3423 | |
| 141 | + # Microchip differential I2C ADC, 4 Channel, 18 bit | |
| 142 | + - microchip,mcp3424 | |
| 143 | + # Microchip differential I2C ADC, 1 Channel, 16 bit | |
| 144 | + - microchip,mcp3425 | |
| 145 | + # Microchip differential I2C ADC, 2 Channel, 16 bit | |
| 146 | + - microchip,mcp3426 | |
| 147 | + # Microchip differential I2C ADC, 2 Channel, 16 bit | |
| 148 | + - microchip,mcp3427 | |
| 149 | + # Microchip differential I2C ADC, 4 Channel, 16 bit | |
| 150 | + - microchip,mcp3428 | |
| 135 | 151 | # Microchip 7-bit Single I2C Digital POT (5k) |
| 136 | 152 | - microchip,mcp4017-502 |
| 137 | 153 | # Microchip 7-bit Single I2C Digital POT (10k) |
| @@ -950,37 +950,12 @@ S: Supported · 949 unmodified lines | ||
| 950 | 950 | F: arch/arm64/boot/dts/amd/amd-seattle-xgbe*.dtsi |
| 951 | 951 | F: drivers/net/ethernet/amd/xgbe/ |
| 952 | 952 | |
| 953 | −ANALOG DEVICES INC AD5686 DRIVER | |
| 954 | −M: Michael Hennerich <Michael.Hennerich@analog.com> | |
| 955 | −L: linux-pm@vger.kernel.org | |
| 956 | −S: Supported | |
| 957 | −W: http://ez.analog.com/community/linux-device-drivers | |
| 958 | −F: drivers/iio/dac/ad5686* | |
| 959 | −F: drivers/iio/dac/ad5696* | |
| 960 | − | |
| 961 | −ANALOG DEVICES INC AD5758 DRIVER | |
| 962 | −M: Michael Hennerich <Michael.Hennerich@analog.com> | |
| 963 | −L: linux-iio@vger.kernel.org | |
| 964 | −S: Supported | |
| 965 | −W: http://ez.analog.com/community/linux-device-drivers | |
| 966 | −F: Documentation/devicetree/bindings/iio/dac/ad5758.txt | |
| 967 | −F: drivers/iio/dac/ad5758.c | |
| 968 | − | |
| 969 | −ANALOG DEVICES INC AD7091R5 DRIVER | |
| 970 | −M: Beniamin Bia <beniamin.bia@analog.com> | |
| 971 | −L: linux-iio@vger.kernel.org | |
| 972 | −S: Supported | |
| 973 | −W: http://ez.analog.com/community/linux-device-drivers | |
| 974 | −F: Documentation/devicetree/bindings/iio/adc/adi,ad7091r5.yaml | |
| 975 | −F: drivers/iio/adc/ad7091r5.c | |
| 976 | − | |
| 977 | −ANALOG DEVICES INC AD7124 DRIVER | |
| 978 | −M: Michael Hennerich <Michael.Hennerich@analog.com> | |
| 953 | +AMS AS73211 DRIVER | |
| 954 | +M: Christian Eggers <ceggers@arri.de> | |
| 979 | 955 | L: linux-iio@vger.kernel.org |
| 980 | −S: Supported | |
| 981 | −W: http://ez.analog.com/community/linux-device-drivers | |
| 982 | −F: Documentation/devicetree/bindings/iio/adc/adi,ad7124.yaml | |
| 983 | −F: drivers/iio/adc/ad7124.c | |
| 956 | +S: Maintained | |
| 957 | +F: Documentation/devicetree/bindings/iio/light/ams,as73211.yaml | |
| 958 | +F: drivers/iio/light/as73211.c | |
| 984 | 959 | |
| 985 | 960 | ANALOG DEVICES INC AD7192 DRIVER |
| 986 | 961 | M: Alexandru Tachici <alexandru.tachici@analog.com> |
| @@ -998,15 +973,6 @@ W: http://ez.analog.com/community/linux-device-drivers · 11 unmodified lines | ||
| 998 | 973 | F: Documentation/devicetree/bindings/iio/adc/adi,ad7292.yaml |
| 999 | 974 | F: drivers/iio/adc/ad7292.c |
| 1000 | 975 | |
| 1001 | −ANALOG DEVICES INC AD7606 DRIVER | |
| 1002 | −M: Michael Hennerich <Michael.Hennerich@analog.com> | |
| 1003 | −M: Beniamin Bia <beniamin.bia@analog.com> | |
| 1004 | −L: linux-iio@vger.kernel.org | |
| 1005 | −S: Supported | |
| 1006 | −W: http://ez.analog.com/community/linux-device-drivers | |
| 1007 | −F: Documentation/devicetree/bindings/iio/adc/adi,ad7606.yaml | |
| 1008 | −F: drivers/iio/adc/ad7606.c | |
| 1009 | − | |
| 1010 | 976 | ANALOG DEVICES INC AD7768-1 DRIVER |
| 1011 | 977 | M: Michael Hennerich <Michael.Hennerich@analog.com> |
| 1012 | 978 | L: linux-iio@vger.kernel.org |
| @@ -1068,7 +1034,6 @@ F: drivers/iio/imu/adis16475.c · 55 unmodified lines | ||
| 1068 | 1034 | F: Documentation/devicetree/bindings/iio/imu/adi,adis16475.yaml |
| 1069 | 1035 | |
| 1070 | 1036 | ANALOG DEVICES INC ADM1177 DRIVER |
| 1071 | −M: Beniamin Bia <beniamin.bia@analog.com> | |
| 1072 | 1037 | M: Michael Hennerich <Michael.Hennerich@analog.com> |
| 1073 | 1038 | L: linux-hwmon@vger.kernel.org |
| 1074 | 1039 | S: Supported |
| @@ -1115,6 +1080,13 @@ L: linux-media@vger.kernel.org · 40 unmodified lines | ||
| 1115 | 1080 | S: Maintained |
| 1116 | 1081 | F: drivers/media/i2c/adv7842* |
| 1117 | 1082 | |
| 1083 | +ANALOG DEVICES INC ADXRS290 DRIVER | |
| 1084 | +M: Nishant Malpani <nish.malpani25@gmail.com> | |
| 1085 | +L: linux-iio@vger.kernel.org | |
| 1086 | +S: Supported | |
| 1087 | +F: drivers/iio/gyro/adxrs290.c | |
| 1088 | +F: Documentation/devicetree/bindings/iio/gyroscope/adi,adxrs290.yaml | |
| 1089 | + | |
| 1118 | 1090 | ANALOG DEVICES INC ASOC CODEC DRIVERS |
| 1119 | 1091 | M: Lars-Peter Clausen <lars@metafoo.de> |
| 1120 | 1092 | M: Nuno Sá <nuno.sa@analog.com> |
| @@ -1135,15 +1107,6 @@ S: Supported · 14 unmodified lines | ||
| 1135 | 1107 | W: http://ez.analog.com/community/linux-device-drivers |
| 1136 | 1108 | F: drivers/dma/dma-axi-dmac.c |
| 1137 | 1109 | |
| 1138 | −ANALOG DEVICES INC HMC425A DRIVER | |
| 1139 | −M: Beniamin Bia <beniamin.bia@analog.com> | |
| 1140 | −M: Michael Hennerich <michael.hennerich@analog.com> | |
| 1141 | −L: linux-iio@vger.kernel.org | |
| 1142 | −S: Supported | |
| 1143 | −W: http://ez.analog.com/community/linux-device-drivers | |
| 1144 | −F: Documentation/devicetree/bindings/iio/amplifiers/adi,hmc425a.yaml | |
| 1145 | −F: drivers/iio/amplifiers/hmc425a.c | |
| 1146 | − | |
| 1147 | 1110 | ANALOG DEVICES INC IIO DRIVERS |
| 1148 | 1111 | M: Lars-Peter Clausen <lars@metafoo.de> |
| 1149 | 1112 | M: Michael Hennerich <Michael.Hennerich@analog.com> |
| @@ -1152,8 +1115,11 @@ W: http://wiki.analog.com/ · 2 unmodified lines | ||
| 1152 | 1115 | W: http://ez.analog.com/community/linux-device-drivers |
| 1153 | 1116 | F: Documentation/ABI/testing/sysfs-bus-iio-frequency-ad9523 |
| 1154 | 1117 | F: Documentation/ABI/testing/sysfs-bus-iio-frequency-adf4350 |
| 1118 | +F: Documentation/devicetree/bindings/iio/*/adi,* | |
| 1119 | +F: Documentation/devicetree/bindings/iio/dac/ad5758.txt | |
| 1155 | 1120 | F: drivers/iio/*/ad* |
| 1156 | 1121 | F: drivers/iio/adc/ltc249* |
| 1122 | +F: drivers/iio/amplifiers/hmc425a.c | |
| 1157 | 1123 | F: drivers/staging/iio/*/ad* |
| 1158 | 1124 | X: drivers/iio/*/adjd* |
| 1159 | 1125 | |
| @@ -7944,6 +7910,12 @@ F: drivers/crypto/hisilicon/sec2/sec_crypto.c · 6784 unmodified lines | ||
| 7944 | 7910 | F: drivers/crypto/hisilicon/sec2/sec_crypto.h |
| 7945 | 7911 | F: drivers/crypto/hisilicon/sec2/sec_main.c |
| 7946 | 7912 | |
| 7913 | +HISILICON STAGING DRIVERS FOR HIKEY 960/970 | |
| 7914 | +M: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> | |
| 7915 | +L: devel@driverdev.osuosl.org | |
| 7916 | +S: Maintained | |
| 7917 | +F: drivers/staging/hikey9xx/ | |
| 7918 | + | |
| 7947 | 7919 | HISILICON TRUE RANDOM NUMBER GENERATOR V2 SUPPORT |
| 7948 | 7920 | M: Zaibo Xu <xuzaibo@huawei.com> |
| 7949 | 7921 | S: Maintained |
| @@ -8521,7 +8493,6 @@ F: drivers/iio/multiplexer/iio-mux.c · 571 unmodified lines | ||
| 8521 | 8493 | |
| 8522 | 8494 | IIO SUBSYSTEM AND DRIVERS |
| 8523 | 8495 | M: Jonathan Cameron <jic23@kernel.org> |
| 8524 | −R: Hartmut Knaack <knaack.h@gmx.de> | |
| 8525 | 8496 | R: Lars-Peter Clausen <lars@metafoo.de> |
| 8526 | 8497 | R: Peter Meerwald-Stadler <pmeerw@pmeerw.net> |
| 8527 | 8498 | L: linux-iio@vger.kernel.org |
| @@ -16533,7 +16504,6 @@ F: drivers/staging/rtl8712/ · 8005 unmodified lines | ||
| 16533 | 16504 | |
| 16534 | 16505 | STAGING - SEPS525 LCD CONTROLLER DRIVERS |
| 16535 | 16506 | M: Michael Hennerich <michael.hennerich@analog.com> |
| 16536 | −M: Beniamin Bia <beniamin.bia@analog.com> | |
| 16537 | 16507 | L: linux-fbdev@vger.kernel.org |
| 16538 | 16508 | S: Supported |
| 16539 | 16509 | F: Documentation/devicetree/bindings/iio/adc/adi,ad7606.yaml |
| @@ -253,7 +253,7 @@ static struct counter_count mchp_tc_counts[] = { · 252 unmodified lines | ||
| 253 | 253 | }, |
| 254 | 254 | }; |
| 255 | 255 | |
| 256 | −static struct counter_ops mchp_tc_ops = { | |
| 256 | +static const struct counter_ops mchp_tc_ops = { | |
| 257 | 257 | .signal_read = mchp_tc_count_signal_read, |
| 258 | 258 | .count_read = mchp_tc_count_read, |
| 259 | 259 | .function_get = mchp_tc_count_function_get, |
| @@ -439,7 +439,7 @@ static int ti_eqep_remove(struct platform_device *pdev) · 438 unmodified lines | ||
| 439 | 439 | struct device *dev = &pdev->dev; |
| 440 | 440 | |
| 441 | 441 | counter_unregister(&priv->counter); |
| 442 | − pm_runtime_put_sync(dev), | |
| 442 | + pm_runtime_put_sync(dev); | |
| 443 | 443 | pm_runtime_disable(dev); |
| 444 | 444 | |
| 445 | 445 | return 0; |
| @@ -63,7 +63,7 @@ config IIO_SW_TRIGGER · 62 unmodified lines | ||
| 63 | 63 | using the API provided. |
| 64 | 64 | |
| 65 | 65 | config IIO_TRIGGERED_EVENT |
| 66 | − tristate | |
| 66 | + tristate "Enable triggered events support" | |
| 67 | 67 | select IIO_TRIGGER |
| 68 | 68 | help |
| 69 | 69 | Provides helper functions for setting up triggered events. |
| @@ -281,34 +281,15 @@ static int adis16201_probe(struct spi_device *spi) · 280 unmodified lines | ||
| 281 | 281 | if (ret) |
| 282 | 282 | return ret; |
| 283 | 283 | |
| 284 | − ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL); | |
| 284 | + ret = devm_adis_setup_buffer_and_trigger(st, indio_dev, NULL); | |
| 285 | 285 | if (ret) |
| 286 | 286 | return ret; |
| 287 | 287 | |
| 288 | 288 | ret = adis_initial_startup(st); |
| 289 | 289 | if (ret) |
| 290 | − goto error_cleanup_buffer_trigger; | |
| 291 | − | |
| 292 | − ret = iio_device_register(indio_dev); | |
| 293 | − if (ret < 0) | |
| 294 | − goto error_cleanup_buffer_trigger; | |
| 295 | − | |
| 296 | − return 0; | |
| 297 | − | |
| 298 | −error_cleanup_buffer_trigger: | |
| 299 | − adis_cleanup_buffer_and_trigger(st, indio_dev); | |
| 300 | − return ret; | |
| 301 | −} | |
| 302 | − | |
| 303 | −static int adis16201_remove(struct spi_device *spi) | |
| 304 | −{ | |
| 305 | − struct iio_dev *indio_dev = spi_get_drvdata(spi); | |
| 306 | − struct adis *st = iio_priv(indio_dev); | |
| 307 | − | |
| 308 | − iio_device_unregister(indio_dev); | |
| 309 | − adis_cleanup_buffer_and_trigger(st, indio_dev); | |
| 290 | + return ret; | |
| 310 | 291 | |
| 311 | − return 0; | |
| 292 | + return devm_iio_device_register(&spi->dev, indio_dev); | |
| 312 | 293 | } |
| 313 | 294 | |
| 314 | 295 | static struct spi_driver adis16201_driver = { |
| @@ -316,7 +297,6 @@ static struct spi_driver adis16201_driver = { · 1 unmodified line | ||
| 316 | 297 | .name = "adis16201", |
| 317 | 298 | }, |
| 318 | 299 | .probe = adis16201_probe, |
| 319 | − .remove = adis16201_remove, | |
| 320 | 300 | }; |
| 321 | 301 | module_spi_driver(adis16201_driver); |
| 322 | 302 | |
| @@ -291,33 +291,15 @@ static int adis16209_probe(struct spi_device *spi) · 290 unmodified lines | ||
| 291 | 291 | if (ret) |
| 292 | 292 | return ret; |
| 293 | 293 | |
| 294 | − ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL); | |
| 294 | + ret = devm_adis_setup_buffer_and_trigger(st, indio_dev, NULL); | |
| 295 | 295 | if (ret) |
| 296 | 296 | return ret; |
| 297 | 297 | |
| 298 | 298 | ret = adis_initial_startup(st); |
| 299 | 299 | if (ret) |
| 300 | − goto error_cleanup_buffer_trigger; | |
| 301 | − ret = iio_device_register(indio_dev); | |
| 302 | − if (ret) | |
| 303 | − goto error_cleanup_buffer_trigger; | |
| 304 | − | |
| 305 | − return 0; | |
| 306 | − | |
| 307 | −error_cleanup_buffer_trigger: | |
| 308 | − adis_cleanup_buffer_and_trigger(st, indio_dev); | |
| 309 | − return ret; | |
| 310 | −} | |
| 311 | − | |
| 312 | −static int adis16209_remove(struct spi_device *spi) | |
| 313 | −{ | |
| 314 | − struct iio_dev *indio_dev = spi_get_drvdata(spi); | |
| 315 | − struct adis *st = iio_priv(indio_dev); | |
| 316 | − | |
| 317 | − iio_device_unregister(indio_dev); | |
| 318 | − adis_cleanup_buffer_and_trigger(st, indio_dev); | |
| 300 | + return ret; | |
| 319 | 301 | |
| 320 | − return 0; | |
| 302 | + return devm_iio_device_register(&spi->dev, indio_dev); | |
| 321 | 303 | } |
| 322 | 304 | |
| 323 | 305 | static struct spi_driver adis16209_driver = { |
| @@ -325,7 +307,6 @@ static struct spi_driver adis16209_driver = { · 1 unmodified line | ||
| 325 | 307 | .name = "adis16209", |
| 326 | 308 | }, |
| 327 | 309 | .probe = adis16209_probe, |
| 328 | − .remove = adis16209_remove, | |
| 329 | 310 | }; |
| 330 | 311 | module_spi_driver(adis16209_driver); |
| 331 | 312 | |
| @@ -5,6 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | * Copyright 2018 Analog Devices Inc. |
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | +#include <linux/bitfield.h> | |
| 8 | 9 | #include <linux/bitops.h> |
| 9 | 10 | #include <linux/interrupt.h> |
| 10 | 11 | #include <linux/irq.h> |
| @@ -113,6 +114,11 @@ · 102 unmodified lines | ||
| 113 | 114 | #define ADXL372_STATUS_1_AWAKE(x) (((x) >> 6) & 0x1) |
| 114 | 115 | #define ADXL372_STATUS_1_ERR_USR_REGS(x) (((x) >> 7) & 0x1) |
| 115 | 116 | |
| 117 | +/* ADXL372_STATUS_2 */ | |
| 118 | +#define ADXL372_STATUS_2_INACT(x) (((x) >> 4) & 0x1) | |
| 119 | +#define ADXL372_STATUS_2_ACT(x) (((x) >> 5) & 0x1) | |
| 120 | +#define ADXL372_STATUS_2_AC2(x) (((x) >> 6) & 0x1) | |
| 121 | + | |
| 116 | 122 | /* ADXL372_INT1_MAP */ |
| 117 | 123 | #define ADXL372_INT1_MAP_DATA_RDY_MSK BIT(0) |
| 118 | 124 | #define ADXL372_INT1_MAP_DATA_RDY_MODE(x) (((x) & 0x1) << 0) |
| @@ -131,8 +137,17 @@ · 12 unmodified lines | ||
| 131 | 137 | #define ADXL372_INT1_MAP_LOW_MSK BIT(7) |
| 132 | 138 | #define ADXL372_INT1_MAP_LOW_MODE(x) (((x) & 0x1) << 7) |
| 133 | 139 | |
| 140 | +/* ADX372_THRESH */ | |
| 141 | +#define ADXL372_THRESH_VAL_H_MSK GENMASK(10, 3) | |
| 142 | +#define ADXL372_THRESH_VAL_H_SEL(x) FIELD_GET(ADXL372_THRESH_VAL_H_MSK, x) | |
| 143 | +#define ADXL372_THRESH_VAL_L_MSK GENMASK(2, 0) | |
| 144 | +#define ADXL372_THRESH_VAL_L_SEL(x) FIELD_GET(ADXL372_THRESH_VAL_L_MSK, x) | |
| 145 | + | |
| 134 | 146 | /* The ADXL372 includes a deep, 512 sample FIFO buffer */ |
| 135 | 147 | #define ADXL372_FIFO_SIZE 512 |
| 148 | +#define ADXL372_X_AXIS_EN(x) ((x) & BIT(0)) | |
| 149 | +#define ADXL372_Y_AXIS_EN(x) ((x) & BIT(1)) | |
| 150 | +#define ADXL372_Z_AXIS_EN(x) ((x) & BIT(2)) | |
| 136 | 151 | |
| 137 | 152 | /* |
| 138 | 153 | * At +/- 200g with 12-bit resolution, scale is computed as: |
| @@ -222,6 +237,20 @@ static const struct adxl372_axis_lookup adxl372_axis_lookup_table[] = { · 83 unmodified lines | ||
| 222 | 237 | { BIT(0) | BIT(1) | BIT(2), ADXL372_XYZ_FIFO }, |
| 223 | 238 | }; |
| 224 | 239 | |
| 240 | +static const struct iio_event_spec adxl372_events[] = { | |
| 241 | + { | |
| 242 | + .type = IIO_EV_TYPE_THRESH, | |
| 243 | + .dir = IIO_EV_DIR_RISING, | |
| 244 | + .mask_separate = BIT(IIO_EV_INFO_VALUE), | |
| 245 | + .mask_shared_by_all = BIT(IIO_EV_INFO_PERIOD) | BIT(IIO_EV_INFO_ENABLE), | |
| 246 | + }, { | |
| 247 | + .type = IIO_EV_TYPE_THRESH, | |
| 248 | + .dir = IIO_EV_DIR_FALLING, | |
| 249 | + .mask_separate = BIT(IIO_EV_INFO_VALUE), | |
| 250 | + .mask_shared_by_all = BIT(IIO_EV_INFO_PERIOD) | BIT(IIO_EV_INFO_ENABLE), | |
| 251 | + }, | |
| 252 | +}; | |
| 253 | + | |
| 225 | 254 | #define ADXL372_ACCEL_CHANNEL(index, reg, axis) { \ |
| 226 | 255 | .type = IIO_ACCEL, \ |
| 227 | 256 | .address = reg, \ |
| @@ -239,6 +268,8 @@ static const struct adxl372_axis_lookup adxl372_axis_lookup_table[] = { · 11 unmodified lines | ||
| 239 | 268 | .shift = 4, \ |
| 240 | 269 | .endianness = IIO_BE, \ |
| 241 | 270 | }, \ |
| 271 | + .event_spec = adxl372_events, \ | |
| 272 | + .num_event_specs = ARRAY_SIZE(adxl372_events) \ | |
| 242 | 273 | } |
| 243 | 274 | |
| 244 | 275 | static const struct iio_chan_spec adxl372_channels[] = { |
| @@ -252,8 +283,10 @@ struct adxl372_state { · 7 unmodified lines | ||
| 252 | 283 | struct device *dev; |
| 253 | 284 | struct regmap *regmap; |
| 254 | 285 | struct iio_trigger *dready_trig; |
| 286 | + struct iio_trigger *peak_datardy_trig; | |
| 255 | 287 | enum adxl372_fifo_mode fifo_mode; |
| 256 | 288 | enum adxl372_fifo_format fifo_format; |
| 289 | + unsigned int fifo_axis_mask; | |
| 257 | 290 | enum adxl372_op_mode op_mode; |
| 258 | 291 | enum adxl372_act_proc_mode act_proc_mode; |
| 259 | 292 | enum adxl372_odr odr; |
| @@ -261,10 +294,12 @@ struct adxl372_state { · 1 unmodified line | ||
| 261 | 294 | u32 act_time_ms; |
| 262 | 295 | u32 inact_time_ms; |
| 263 | 296 | u8 fifo_set_size; |
| 264 | − u8 int1_bitmask; | |
| 265 | − u8 int2_bitmask; | |
| 297 | + unsigned long int1_bitmask; | |
| 298 | + unsigned long int2_bitmask; | |
| 266 | 299 | u16 watermark; |
| 267 | 300 | __be16 fifo_buf[ADXL372_FIFO_SIZE]; |
| 301 | + bool peak_fifo_mode_en; | |
| 302 | + struct mutex threshold_m; /* lock for threshold */ | |
| 268 | 303 | }; |
| 269 | 304 | |
| 270 | 305 | static const unsigned long adxl372_channel_masks[] = { |
| @@ -276,6 +311,46 @@ static const unsigned long adxl372_channel_masks[] = { · 5 unmodified lines | ||
| 276 | 311 | 0 |
| 277 | 312 | }; |
| 278 | 313 | |
| 314 | +static ssize_t adxl372_read_threshold_value(struct iio_dev *indio_dev, unsigned int addr, | |
| 315 | + u16 *threshold) | |
| 316 | +{ | |
| 317 | + struct adxl372_state *st = iio_priv(indio_dev); | |
| 318 | + __be16 raw_regval; | |
| 319 | + u16 regval; | |
| 320 | + int ret; | |
| 321 | + | |
| 322 | + ret = regmap_bulk_read(st->regmap, addr, &raw_regval, sizeof(raw_regval)); | |
| 323 | + if (ret < 0) | |
| 324 | + return ret; | |
| 325 | + | |
| 326 | + regval = be16_to_cpu(raw_regval); | |
| 327 | + regval >>= 5; | |
| 328 | + | |
| 329 | + *threshold = regval; | |
| 330 | + | |
| 331 | + return 0; | |
| 332 | +} | |
| 333 | + | |
| 334 | +static ssize_t adxl372_write_threshold_value(struct iio_dev *indio_dev, unsigned int addr, | |
| 335 | + u16 threshold) | |
| 336 | +{ | |
| 337 | + struct adxl372_state *st = iio_priv(indio_dev); | |
| 338 | + int ret; | |
| 339 | + | |
| 340 | + mutex_lock(&st->threshold_m); | |
| 341 | + ret = regmap_write(st->regmap, addr, ADXL372_THRESH_VAL_H_SEL(threshold)); | |
| 342 | + if (ret < 0) | |
| 343 | + goto unlock; | |
| 344 | + | |
| 345 | + ret = regmap_update_bits(st->regmap, addr + 1, GENMASK(7, 5), | |
| 346 | + ADXL372_THRESH_VAL_L_SEL(threshold) << 5); | |
| 347 | + | |
| 348 | +unlock: | |
| 349 | + mutex_unlock(&st->threshold_m); | |
| 350 | + | |
| 351 | + return ret; | |
| 352 | +} | |
| 353 | + | |
| 279 | 354 | static int adxl372_read_axis(struct adxl372_state *st, u8 addr) |
| 280 | 355 | { |
| 281 | 356 | __be16 regval; |
| @@ -453,8 +528,8 @@ static int adxl372_set_inactivity_time_ms(struct adxl372_state *st, · 171 unmodified lines | ||
| 453 | 528 | } |
| 454 | 529 | |
| 455 | 530 | static int adxl372_set_interrupts(struct adxl372_state *st, |
| 456 | − unsigned char int1_bitmask, | |
| 457 | − unsigned char int2_bitmask) | |
| 531 | + unsigned long int1_bitmask, | |
| 532 | + unsigned long int2_bitmask) | |
| 458 | 533 | { |
| 459 | 534 | int ret; |
| 460 | 535 | |
| @@ -523,6 +598,39 @@ static int adxl372_get_status(struct adxl372_state *st, · 62 unmodified lines | ||
| 523 | 598 | return ret; |
| 524 | 599 | } |
| 525 | 600 | |
| 601 | +static void adxl372_arrange_axis_data(struct adxl372_state *st, __be16 *sample) | |
| 602 | +{ | |
| 603 | + __be16 axis_sample[3]; | |
| 604 | + int i = 0; | |
| 605 | + | |
| 606 | + memset(axis_sample, 0, 3 * sizeof(__be16)); | |
| 607 | + if (ADXL372_X_AXIS_EN(st->fifo_axis_mask)) | |
| 608 | + axis_sample[i++] = sample[0]; | |
| 609 | + if (ADXL372_Y_AXIS_EN(st->fifo_axis_mask)) | |
| 610 | + axis_sample[i++] = sample[1]; | |
| 611 | + if (ADXL372_Z_AXIS_EN(st->fifo_axis_mask)) | |
| 612 | + axis_sample[i++] = sample[2]; | |
| 613 | + | |
| 614 | + memcpy(sample, axis_sample, 3 * sizeof(__be16)); | |
| 615 | +} | |
| 616 | + | |
| 617 | +static void adxl372_push_event(struct iio_dev *indio_dev, s64 timestamp, u8 status2) | |
| 618 | +{ | |
| 619 | + unsigned int ev_dir = IIO_EV_DIR_NONE; | |
| 620 | + | |
| 621 | + if (ADXL372_STATUS_2_ACT(status2)) | |
| 622 | + ev_dir = IIO_EV_DIR_RISING; | |
| 623 | + | |
| 624 | + if (ADXL372_STATUS_2_INACT(status2)) | |
| 625 | + ev_dir = IIO_EV_DIR_FALLING; | |
| 626 | + | |
| 627 | + if (ev_dir != IIO_EV_DIR_NONE) | |
| 628 | + iio_push_event(indio_dev, | |
| 629 | + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_X_OR_Y_OR_Z, | |
| 630 | + IIO_EV_TYPE_THRESH, ev_dir), | |
| 631 | + timestamp); | |
| 632 | +} | |
| 633 | + | |
| 526 | 634 | static irqreturn_t adxl372_trigger_handler(int irq, void *p) |
| 527 | 635 | { |
| 528 | 636 | struct iio_poll_func *pf = p; |
| @@ -536,6 +644,8 @@ static irqreturn_t adxl372_trigger_handler(int irq, void *p) · 7 unmodified lines | ||
| 536 | 644 | if (ret < 0) |
| 537 | 645 | goto err; |
| 538 | 646 | |
| 647 | + adxl372_push_event(indio_dev, iio_get_time_ns(indio_dev), status2); | |
| 648 | + | |
| 539 | 649 | if (st->fifo_mode != ADXL372_FIFO_BYPASSED && |
| 540 | 650 | ADXL372_STATUS_1_FIFO_FULL(status1)) { |
| 541 | 651 | /* |
| @@ -554,8 +664,12 @@ static irqreturn_t adxl372_trigger_handler(int irq, void *p) · 12 unmodified lines | ||
| 554 | 664 | goto err; |
| 555 | 665 | |
| 556 | 666 | /* Each sample is 2 bytes */ |
| 557 | − for (i = 0; i < fifo_entries; i += st->fifo_set_size) | |
| 667 | + for (i = 0; i < fifo_entries; i += st->fifo_set_size) { | |
| 668 | + /* filter peak detection data */ | |
| 669 | + if (st->peak_fifo_mode_en) | |
| 670 | + adxl372_arrange_axis_data(st, &st->fifo_buf[i]); | |
| 558 | 671 | iio_push_to_buffers(indio_dev, &st->fifo_buf[i]); |
| 672 | + } | |
| 559 | 673 | } |
| 560 | 674 | err: |
| 561 | 675 | iio_trigger_notify_done(indio_dev->trig); |
| @@ -723,6 +837,129 @@ static int adxl372_write_raw(struct iio_dev *indio_dev, · 161 unmodified lines | ||
| 723 | 837 | } |
| 724 | 838 | } |
| 725 | 839 | |
| 840 | +static int adxl372_read_event_value(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, | |
| 841 | + enum iio_event_type type, enum iio_event_direction dir, | |
| 842 | + enum iio_event_info info, int *val, int *val2) | |
| 843 | +{ | |
| 844 | + struct adxl372_state *st = iio_priv(indio_dev); | |
| 845 | + unsigned int addr; | |
| 846 | + u16 raw_value; | |
| 847 | + int ret; | |
| 848 | + | |
| 849 | + switch (info) { | |
| 850 | + case IIO_EV_INFO_VALUE: | |
| 851 | + switch (dir) { | |
| 852 | + case IIO_EV_DIR_RISING: | |
| 853 | + addr = ADXL372_X_THRESH_ACT_H + 2 * chan->scan_index; | |
| 854 | + ret = adxl372_read_threshold_value(indio_dev, addr, &raw_value); | |
| 855 | + if (ret < 0) | |
| 856 | + return ret; | |
| 857 | + *val = raw_value * ADXL372_USCALE; | |
| 858 | + *val2 = 1000000; | |
| 859 | + return IIO_VAL_FRACTIONAL; | |
| 860 | + case IIO_EV_DIR_FALLING: | |
| 861 | + addr = ADXL372_X_THRESH_INACT_H + 2 * chan->scan_index; | |
| 862 | + ret = adxl372_read_threshold_value(indio_dev, addr, &raw_value); | |
| 863 | + if (ret < 0) | |
| 864 | + return ret; | |
| 865 | + *val = raw_value * ADXL372_USCALE; | |
| 866 | + *val2 = 1000000; | |
| 867 | + return IIO_VAL_FRACTIONAL; | |
| 868 | + default: | |
| 869 | + return -EINVAL; | |
| 870 | + } | |
| 871 | + case IIO_EV_INFO_PERIOD: | |
| 872 | + switch (dir) { | |
| 873 | + case IIO_EV_DIR_RISING: | |
| 874 | + *val = st->act_time_ms; | |
| 875 | + *val2 = 1000; | |
| 876 | + return IIO_VAL_FRACTIONAL; | |
| 877 | + case IIO_EV_DIR_FALLING: | |
| 878 | + *val = st->inact_time_ms; | |
| 879 | + *val2 = 1000; | |
| 880 | + return IIO_VAL_FRACTIONAL; | |
| 881 | + default: | |
| 882 | + return -EINVAL; | |
| 883 | + } | |
| 884 | + default: | |
| 885 | + return -EINVAL; | |
| 886 | + } | |
| 887 | +} | |
| 888 | + | |
| 889 | +static int adxl372_write_event_value(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, | |
| 890 | + enum iio_event_type type, enum iio_event_direction dir, | |
| 891 | + enum iio_event_info info, int val, int val2) | |
| 892 | +{ | |
| 893 | + struct adxl372_state *st = iio_priv(indio_dev); | |
| 894 | + unsigned int val_ms; | |
| 895 | + unsigned int addr; | |
| 896 | + u16 raw_val; | |
| 897 | + | |
| 898 | + switch (info) { | |
| 899 | + case IIO_EV_INFO_VALUE: | |
| 900 | + raw_val = DIV_ROUND_UP(val * 1000000, ADXL372_USCALE); | |
| 901 | + switch (dir) { | |
| 902 | + case IIO_EV_DIR_RISING: | |
| 903 | + addr = ADXL372_X_THRESH_ACT_H + 2 * chan->scan_index; | |
| 904 | + return adxl372_write_threshold_value(indio_dev, addr, raw_val); | |
| 905 | + case IIO_EV_DIR_FALLING: | |
| 906 | + addr = ADXL372_X_THRESH_INACT_H + 2 * chan->scan_index; | |
| 907 | + return adxl372_write_threshold_value(indio_dev, addr, raw_val); | |
| 908 | + default: | |
| 909 | + return -EINVAL; | |
| 910 | + } | |
| 911 | + case IIO_EV_INFO_PERIOD: | |
| 912 | + val_ms = val * 1000 + DIV_ROUND_UP(val2, 1000); | |
| 913 | + switch (dir) { | |
| 914 | + case IIO_EV_DIR_RISING: | |
| 915 | + return adxl372_set_activity_time_ms(st, val_ms); | |
| 916 | + case IIO_EV_DIR_FALLING: | |
| 917 | + return adxl372_set_inactivity_time_ms(st, val_ms); | |
| 918 | + default: | |
| 919 | + return -EINVAL; | |
| 920 | + } | |
| 921 | + default: | |
| 922 | + return -EINVAL; | |
| 923 | + } | |
| 924 | +} | |
| 925 | + | |
| 926 | +static int adxl372_read_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, | |
| 927 | + enum iio_event_type type, enum iio_event_direction dir) | |
| 928 | +{ | |
| 929 | + struct adxl372_state *st = iio_priv(indio_dev); | |
| 930 | + | |
| 931 | + switch (dir) { | |
| 932 | + case IIO_EV_DIR_RISING: | |
| 933 | + return FIELD_GET(ADXL372_INT1_MAP_ACT_MSK, st->int1_bitmask); | |
| 934 | + case IIO_EV_DIR_FALLING: | |
| 935 | + return FIELD_GET(ADXL372_INT1_MAP_INACT_MSK, st->int1_bitmask); | |
| 936 | + default: | |
| 937 | + return -EINVAL; | |
| 938 | + } | |
| 939 | +} | |
| 940 | + | |
| 941 | +static int adxl372_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, | |
| 942 | + enum iio_event_type type, enum iio_event_direction dir, | |
| 943 | + int state) | |
| 944 | +{ | |
| 945 | + struct adxl372_state *st = iio_priv(indio_dev); | |
| 946 | + | |
| 947 | + switch (dir) { | |
| 948 | + case IIO_EV_DIR_RISING: | |
| 949 | + set_mask_bits(&st->int1_bitmask, ADXL372_INT1_MAP_ACT_MSK, | |
| 950 | + ADXL372_INT1_MAP_ACT_MODE(state)); | |
| 951 | + break; | |
| 952 | + case IIO_EV_DIR_FALLING: | |
| 953 | + set_mask_bits(&st->int1_bitmask, ADXL372_INT1_MAP_INACT_MSK, | |
| 954 | + ADXL372_INT1_MAP_INACT_MODE(state)); | |
| 955 | + break; | |
| 956 | + default: | |
| 957 | + return -EINVAL; | |
| 958 | + } | |
| 959 | + | |
| 960 | + return adxl372_set_interrupts(st, st->int1_bitmask, 0); | |
| 961 | +} | |
| 962 | + | |
| 726 | 963 | static ssize_t adxl372_show_filter_freq_avail(struct device *dev, |
| 727 | 964 | struct device_attribute *attr, |
| 728 | 965 | char *buf) |
| @@ -795,7 +1032,8 @@ static int adxl372_buffer_postenable(struct iio_dev *indio_dev) · 66 unmodified lines | ||
| 795 | 1032 | unsigned int mask; |
| 796 | 1033 | int i, ret; |
| 797 | 1034 | |
| 798 | − ret = adxl372_set_interrupts(st, ADXL372_INT1_MAP_FIFO_FULL_MSK, 0); | |
| 1035 | + st->int1_bitmask |= ADXL372_INT1_MAP_FIFO_FULL_MSK; | |
| 1036 | + ret = adxl372_set_interrupts(st, st->int1_bitmask, 0); | |
| 799 | 1037 | if (ret < 0) |
| 800 | 1038 | return ret; |
| 801 | 1039 | |
| @@ -810,13 +1048,22 @@ static int adxl372_buffer_postenable(struct iio_dev *indio_dev) · 8 unmodified lines | ||
| 810 | 1048 | return -EINVAL; |
| 811 | 1049 | |
| 812 | 1050 | st->fifo_format = adxl372_axis_lookup_table[i].fifo_format; |
| 1051 | + st->fifo_axis_mask = adxl372_axis_lookup_table[i].bits; | |
| 813 | 1052 | st->fifo_set_size = bitmap_weight(indio_dev->active_scan_mask, |
| 814 | 1053 | indio_dev->masklength); |
| 1054 | + | |
| 1055 | + /* Configure the FIFO to store sets of impact event peak. */ | |
| 1056 | + if (st->peak_fifo_mode_en) { | |
| 1057 | + st->fifo_set_size = 3; | |
| 1058 | + st->fifo_format = ADXL372_XYZ_PEAK_FIFO; | |
| 1059 | + } | |
| 1060 | + | |
| 815 | 1061 | /* |
| 816 | 1062 | * The 512 FIFO samples can be allotted in several ways, such as: |
| 817 | 1063 | * 170 sample sets of concurrent 3-axis data |
| 818 | 1064 | * 256 sample sets of concurrent 2-axis data (user selectable) |
| 819 | 1065 | * 512 sample sets of single-axis data |
| 1066 | + * 170 sets of impact event peak (x, y, z) | |
| 820 | 1067 | */ |
| 821 | 1068 | if ((st->watermark * st->fifo_set_size) > ADXL372_FIFO_SIZE) |
| 822 | 1069 | st->watermark = (ADXL372_FIFO_SIZE / st->fifo_set_size); |
| @@ -826,7 +1073,8 @@ static int adxl372_buffer_postenable(struct iio_dev *indio_dev) · 3 unmodified lines | ||
| 826 | 1073 | ret = adxl372_configure_fifo(st); |
| 827 | 1074 | if (ret < 0) { |
| 828 | 1075 | st->fifo_mode = ADXL372_FIFO_BYPASSED; |
| 829 | − adxl372_set_interrupts(st, 0, 0); | |
| 1076 | + st->int1_bitmask &= ~ADXL372_INT1_MAP_FIFO_FULL_MSK; | |
| 1077 | + adxl372_set_interrupts(st, st->int1_bitmask, 0); | |
| 830 | 1078 | return ret; |
| 831 | 1079 | } |
| 832 | 1080 | |
| @@ -837,7 +1085,8 @@ static int adxl372_buffer_predisable(struct iio_dev *indio_dev) · 4 unmodified lines | ||
| 837 | 1085 | { |
| 838 | 1086 | struct adxl372_state *st = iio_priv(indio_dev); |
| 839 | 1087 | |
| 840 | − adxl372_set_interrupts(st, 0, 0); | |
| 1088 | + st->int1_bitmask &= ~ADXL372_INT1_MAP_FIFO_FULL_MSK; | |
| 1089 | + adxl372_set_interrupts(st, st->int1_bitmask, 0); | |
| 841 | 1090 | st->fifo_mode = ADXL372_FIFO_BYPASSED; |
| 842 | 1091 | adxl372_configure_fifo(st); |
| 843 | 1092 | |
| @@ -854,12 +1103,11 @@ static int adxl372_dready_trig_set_state(struct iio_trigger *trig, · 10 unmodified lines | ||
| 854 | 1103 | { |
| 855 | 1104 | struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); |
| 856 | 1105 | struct adxl372_state *st = iio_priv(indio_dev); |
| 857 | − unsigned long int mask = 0; | |
| 858 | 1106 | |
| 859 | 1107 | if (state) |
| 860 | − mask = ADXL372_INT1_MAP_FIFO_FULL_MSK; | |
| 1108 | + st->int1_bitmask |= ADXL372_INT1_MAP_FIFO_FULL_MSK; | |
| 861 | 1109 | |
| 862 | − return adxl372_set_interrupts(st, mask, 0); | |
| 1110 | + return adxl372_set_interrupts(st, st->int1_bitmask, 0); | |
| 863 | 1111 | } |
| 864 | 1112 | |
| 865 | 1113 | static int adxl372_validate_trigger(struct iio_dev *indio_dev, |
| @@ -867,7 +1115,7 @@ static int adxl372_validate_trigger(struct iio_dev *indio_dev, · 1 unmodified line | ||
| 867 | 1115 | { |
| 868 | 1116 | struct adxl372_state *st = iio_priv(indio_dev); |
| 869 | 1117 | |
| 870 | − if (st->dready_trig != trig) | |
| 1118 | + if (st->dready_trig != trig && st->peak_datardy_trig != trig) | |
| 871 | 1119 | return -EINVAL; |
| 872 | 1120 | |
| 873 | 1121 | return 0; |
| @@ -878,6 +1126,25 @@ static const struct iio_trigger_ops adxl372_trigger_ops = { · 4 unmodified lines | ||
| 878 | 1126 | .set_trigger_state = adxl372_dready_trig_set_state, |
| 879 | 1127 | }; |
| 880 | 1128 | |
| 1129 | +static int adxl372_peak_dready_trig_set_state(struct iio_trigger *trig, | |
| 1130 | + bool state) | |
| 1131 | +{ | |
| 1132 | + struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); | |
| 1133 | + struct adxl372_state *st = iio_priv(indio_dev); | |
| 1134 | + | |
| 1135 | + if (state) | |
| 1136 | + st->int1_bitmask |= ADXL372_INT1_MAP_FIFO_FULL_MSK; | |
| 1137 | + | |
| 1138 | + st->peak_fifo_mode_en = state; | |
| 1139 | + | |
| 1140 | + return adxl372_set_interrupts(st, st->int1_bitmask, 0); | |
| 1141 | +} | |
| 1142 | + | |
| 1143 | +static const struct iio_trigger_ops adxl372_peak_data_trigger_ops = { | |
| 1144 | + .validate_device = &iio_trigger_validate_own_device, | |
| 1145 | + .set_trigger_state = adxl372_peak_dready_trig_set_state, | |
| 1146 | +}; | |
| 1147 | + | |
| 881 | 1148 | static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("400 800 1600 3200 6400"); |
| 882 | 1149 | static IIO_DEVICE_ATTR(in_accel_filter_low_pass_3db_frequency_available, |
| 883 | 1150 | 0444, adxl372_show_filter_freq_avail, NULL, 0); |
| @@ -897,6 +1164,10 @@ static const struct iio_info adxl372_info = { · 13 unmodified lines | ||
| 897 | 1164 | .attrs = &adxl372_attrs_group, |
| 898 | 1165 | .read_raw = adxl372_read_raw, |
| 899 | 1166 | .write_raw = adxl372_write_raw, |
| 1167 | + .read_event_config = adxl372_read_event_config, | |
| 1168 | + .write_event_config = adxl372_write_event_config, | |
| 1169 | + .read_event_value = adxl372_read_event_value, | |
| 1170 | + .write_event_value = adxl372_write_event_value, | |
| 900 | 1171 | .debugfs_reg_access = &adxl372_reg_access, |
| 901 | 1172 | .hwfifo_set_watermark = adxl372_set_watermark, |
| 902 | 1173 | }; |
| @@ -925,6 +1196,8 @@ int adxl372_probe(struct device *dev, struct regmap *regmap, · 22 unmodified lines | ||
| 925 | 1196 | st->regmap = regmap; |
| 926 | 1197 | st->irq = irq; |
| 927 | 1198 | |
| 1199 | + mutex_init(&st->threshold_m); | |
| 1200 | + | |
| 928 | 1201 | indio_dev->channels = adxl372_channels; |
| 929 | 1202 | indio_dev->num_channels = ARRAY_SIZE(adxl372_channels); |
| 930 | 1203 | indio_dev->available_scan_masks = adxl372_channel_masks; |
| @@ -955,13 +1228,27 @@ int adxl372_probe(struct device *dev, struct regmap *regmap, · 24 unmodified lines | ||
| 955 | 1228 | if (st->dready_trig == NULL) |
| 956 | 1229 | return -ENOMEM; |
| 957 | 1230 | |
| 1231 | + st->peak_datardy_trig = devm_iio_trigger_alloc(dev, | |
| 1232 | + "%s-dev%d-peak", | |
| 1233 | + indio_dev->name, | |
| 1234 | + indio_dev->id); | |
| 1235 | + if (!st->peak_datardy_trig) | |
| 1236 | + return -ENOMEM; | |
| 1237 | + | |
| 958 | 1238 | st->dready_trig->ops = &adxl372_trigger_ops; |
| 1239 | + st->peak_datardy_trig->ops = &adxl372_peak_data_trigger_ops; | |
| 959 | 1240 | st->dready_trig->dev.parent = dev; |
| 1241 | + st->peak_datardy_trig->dev.parent = dev; | |
| 960 | 1242 | iio_trigger_set_drvdata(st->dready_trig, indio_dev); |
| 1243 | + iio_trigger_set_drvdata(st->peak_datardy_trig, indio_dev); | |
| 961 | 1244 | ret = devm_iio_trigger_register(dev, st->dready_trig); |
| 962 | 1245 | if (ret < 0) |
| 963 | 1246 | return ret; |
| 964 | 1247 | |
| 1248 | + ret = devm_iio_trigger_register(dev, st->peak_datardy_trig); | |
| 1249 | + if (ret < 0) | |
| 1250 | + return ret; | |
| 1251 | + | |
| 965 | 1252 | indio_dev->trig = iio_trigger_get(st->dready_trig); |
| 966 | 1253 | |
| 967 | 1254 | ret = devm_request_threaded_irq(dev, st->irq, |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | 8 | #include <linux/i2c.h> |
| 9 | +#include <linux/mod_devicetable.h> | |
| 9 | 10 | #include <linux/module.h> |
| 10 | 11 | #include <linux/regmap.h> |
| 11 | 12 | |
| @@ -46,9 +47,16 @@ static const struct i2c_device_id adxl372_i2c_id[] = { · 34 unmodified lines | ||
| 46 | 47 | }; |
| 47 | 48 | MODULE_DEVICE_TABLE(i2c, adxl372_i2c_id); |
| 48 | 49 | |
| 50 | +static const struct of_device_id adxl372_of_match[] = { | |
| 51 | + { .compatible = "adi,adxl372" }, | |
| 52 | + { } | |
| 53 | +}; | |
| 54 | +MODULE_DEVICE_TABLE(of, adxl372_of_match); | |
| 55 | + | |
| 49 | 56 | static struct i2c_driver adxl372_i2c_driver = { |
| 50 | 57 | .driver = { |
| 51 | 58 | .name = "adxl372_i2c", |
| 59 | + .of_match_table = adxl372_of_match, | |
| 52 | 60 | }, |
| 53 | 61 | .probe = adxl372_i2c_probe, |
| 54 | 62 | .id_table = adxl372_i2c_id, |
| @@ -40,8 +40,8 @@ static const struct spi_device_id adxl372_spi_id[] = { · 39 unmodified lines | ||
| 40 | 40 | MODULE_DEVICE_TABLE(spi, adxl372_spi_id); |
| 41 | 41 | |
| 42 | 42 | static const struct of_device_id adxl372_of_match[] = { |
| 43 | − { .compatible = "adi,adxl372" }, | |
| 44 | − { }, | |
| 43 | + { .compatible = "adi,adxl372" }, | |
| 44 | + { } | |
| 45 | 45 | }; |
| 46 | 46 | MODULE_DEVICE_TABLE(of, adxl372_of_match); |
| 47 | 47 | |
| @@ -673,7 +673,7 @@ static const struct iio_chan_spec_ext_info bma023_ext_info[] = { · 672 unmodified lines | ||
| 673 | 673 | }; |
| 674 | 674 | |
| 675 | 675 | static const struct iio_chan_spec_ext_info bma180_ext_info[] = { |
| 676 | − IIO_ENUM("power_mode", true, &bma180_power_mode_enum), | |
| 676 | + IIO_ENUM("power_mode", IIO_SHARED_BY_TYPE, &bma180_power_mode_enum), | |
| 677 | 677 | IIO_ENUM_AVAILABLE("power_mode", &bma180_power_mode_enum), |
| 678 | 678 | IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, bma180_accel_get_mount_matrix), |
| 679 | 679 | { } |
| @@ -1000,19 +1000,15 @@ static int bma180_probe(struct i2c_client *client, · 320 unmodified lines | ||
| 1000 | 1000 | return ret; |
| 1001 | 1001 | |
| 1002 | 1002 | data->vdd_supply = devm_regulator_get(dev, "vdd"); |
| 1003 | − if (IS_ERR(data->vdd_supply)) { | |
| 1004 | − if (PTR_ERR(data->vdd_supply) != -EPROBE_DEFER) | |
| 1005 | − dev_err(dev, "Failed to get vdd regulator %d\n", | |
| 1006 | − (int)PTR_ERR(data->vdd_supply)); | |
| 1007 | − return PTR_ERR(data->vdd_supply); | |
| 1008 | − } | |
| 1003 | + if (IS_ERR(data->vdd_supply)) | |
| 1004 | + return dev_err_probe(dev, PTR_ERR(data->vdd_supply), | |
| 1005 | + "Failed to get vdd regulator\n"); | |
| 1006 | + | |
| 1009 | 1007 | data->vddio_supply = devm_regulator_get(dev, "vddio"); |
| 1010 | − if (IS_ERR(data->vddio_supply)) { | |
| 1011 | − if (PTR_ERR(data->vddio_supply) != -EPROBE_DEFER) | |
| 1012 | − dev_err(dev, "Failed to get vddio regulator %d\n", | |
| 1013 | − (int)PTR_ERR(data->vddio_supply)); | |
| 1014 | − return PTR_ERR(data->vddio_supply); | |
| 1015 | − } | |
| 1008 | + if (IS_ERR(data->vddio_supply)) | |
| 1009 | + return dev_err_probe(dev, PTR_ERR(data->vddio_supply), | |
| 1010 | + "Failed to get vddio regulator\n"); | |
| 1011 | + | |
| 1016 | 1012 | /* Typical voltage 2.4V these are min and max */ |
| 1017 | 1013 | ret = regulator_set_voltage(data->vdd_supply, 1620000, 3600000); |
| 1018 | 1014 | if (ret) |
| @@ -2,16 +2,18 @@ · 1 unmodified line | ||
| 2 | 2 | /** |
| 3 | 3 | * BMA220 Digital triaxial acceleration sensor driver |
| 4 | 4 | * |
| 5 | − * Copyright (c) 2016, Intel Corporation. | |
| 5 | + * Copyright (c) 2016,2020 Intel Corporation. | |
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | −#include <linux/acpi.h> | |
| 8 | +#include <linux/bits.h> | |
| 9 | 9 | #include <linux/kernel.h> |
| 10 | +#include <linux/mod_devicetable.h> | |
| 10 | 11 | #include <linux/module.h> |
| 12 | +#include <linux/spi/spi.h> | |
| 13 | + | |
| 11 | 14 | #include <linux/iio/buffer.h> |
| 12 | 15 | #include <linux/iio/iio.h> |
| 13 | 16 | #include <linux/iio/sysfs.h> |
| 14 | −#include <linux/spi/spi.h> | |
| 15 | 17 | #include <linux/iio/trigger_consumer.h> |
| 16 | 18 | #include <linux/iio/triggered_buffer.h> |
| 17 | 19 | |
| @@ -23,14 +25,13 @@ · 5 unmodified lines | ||
| 23 | 25 | #define BMA220_REG_SUSPEND 0x18 |
| 24 | 26 | |
| 25 | 27 | #define BMA220_CHIP_ID 0xDD |
| 26 | −#define BMA220_READ_MASK 0x80 | |
| 27 | −#define BMA220_RANGE_MASK 0x03 | |
| 28 | +#define BMA220_READ_MASK BIT(7) | |
| 29 | +#define BMA220_RANGE_MASK GENMASK(1, 0) | |
| 28 | 30 | #define BMA220_DATA_SHIFT 2 |
| 29 | 31 | #define BMA220_SUSPEND_SLEEP 0xFF |
| 30 | 32 | #define BMA220_SUSPEND_WAKE 0x00 |
| 31 | 33 | |
| 32 | 34 | #define BMA220_DEVICE_NAME "bma220" |
| 33 | −#define BMA220_SCALE_AVAILABLE "0.623 1.248 2.491 4.983" | |
| 34 | 35 | |
| 35 | 36 | #define BMA220_ACCEL_CHANNEL(index, reg, axis) { \ |
| 36 | 37 | .type = IIO_ACCEL, \ |
| @@ -55,19 +56,8 @@ enum bma220_axis { · 18 unmodified lines | ||
| 55 | 56 | AXIS_Z, |
| 56 | 57 | }; |
| 57 | 58 | |
| 58 | −static IIO_CONST_ATTR(in_accel_scale_available, BMA220_SCALE_AVAILABLE); | |
| 59 | − | |
| 60 | −static struct attribute *bma220_attributes[] = { | |
| 61 | − &iio_const_attr_in_accel_scale_available.dev_attr.attr, | |
| 62 | − NULL, | |
| 63 | −}; | |
| 64 | − | |
| 65 | −static const struct attribute_group bma220_attribute_group = { | |
| 66 | − .attrs = bma220_attributes, | |
| 67 | −}; | |
| 68 | − | |
| 69 | −static const int bma220_scale_table[][4] = { | |
| 70 | − {0, 623000}, {1, 248000}, {2, 491000}, {4, 983000} | |
| 59 | +static const int bma220_scale_table[][2] = { | |
| 60 | + {0, 623000}, {1, 248000}, {2, 491000}, {4, 983000}, | |
| 71 | 61 | }; |
| 72 | 62 | |
| 73 | 63 | struct bma220_data { |
| @@ -182,10 +172,26 @@ static int bma220_write_raw(struct iio_dev *indio_dev, · 108 unmodified lines | ||
| 182 | 172 | return -EINVAL; |
| 183 | 173 | } |
| 184 | 174 | |
| 175 | +static int bma220_read_avail(struct iio_dev *indio_dev, | |
| 176 | + struct iio_chan_spec const *chan, | |
| 177 | + const int **vals, int *type, int *length, | |
| 178 | + long mask) | |
| 179 | +{ | |
| 180 | + switch (mask) { | |
| 181 | + case IIO_CHAN_INFO_SCALE: | |
| 182 | + *vals = (int *)bma220_scale_table; | |
| 183 | + *type = IIO_VAL_INT_PLUS_MICRO; | |
| 184 | + *length = ARRAY_SIZE(bma220_scale_table) * 2; | |
| 185 | + return IIO_AVAIL_LIST; | |
| 186 | + default: | |
| 187 | + return -EINVAL; | |
| 188 | + } | |
| 189 | +} | |
| 190 | + | |
| 185 | 191 | static const struct iio_info bma220_info = { |
| 186 | 192 | .read_raw = bma220_read_raw, |
| 187 | 193 | .write_raw = bma220_write_raw, |
| 188 | − .attrs = &bma220_attribute_group, | |
| 194 | + .read_avail = bma220_read_avail, | |
| 189 | 195 | }; |
| 190 | 196 | |
| 191 | 197 | static int bma220_init(struct spi_device *spi) |
| @@ -198,10 +204,12 @@ static int bma220_init(struct spi_device *spi) · 6 unmodified lines | ||
| 198 | 204 | |
| 199 | 205 | /* Make sure the chip is powered on */ |
| 200 | 206 | ret = bma220_read_reg(spi, BMA220_REG_SUSPEND); |
| 207 | + if (ret == BMA220_SUSPEND_WAKE) | |
| 208 | + ret = bma220_read_reg(spi, BMA220_REG_SUSPEND); | |
| 201 | 209 | if (ret < 0) |
| 202 | 210 | return ret; |
| 203 | − else if (ret == BMA220_SUSPEND_WAKE) | |
| 204 | − return bma220_read_reg(spi, BMA220_REG_SUSPEND); | |
| 211 | + if (ret == BMA220_SUSPEND_WAKE) | |
| 212 | + return -EBUSY; | |
| 205 | 213 | |
| 206 | 214 | return 0; |
| 207 | 215 | } |
| @@ -212,10 +220,12 @@ static int bma220_deinit(struct spi_device *spi) · 4 unmodified lines | ||
| 212 | 220 | |
| 213 | 221 | /* Make sure the chip is powered off */ |
| 214 | 222 | ret = bma220_read_reg(spi, BMA220_REG_SUSPEND); |
| 223 | + if (ret == BMA220_SUSPEND_SLEEP) | |
| 224 | + ret = bma220_read_reg(spi, BMA220_REG_SUSPEND); | |
| 215 | 225 | if (ret < 0) |
| 216 | 226 | return ret; |
| 217 | − else if (ret == BMA220_SUSPEND_SLEEP) | |
| 218 | − return bma220_read_reg(spi, BMA220_REG_SUSPEND); | |
| 227 | + if (ret == BMA220_SUSPEND_SLEEP) | |
| 228 | + return -EBUSY; | |
| 219 | 229 | |
| 220 | 230 | return 0; |
| 221 | 231 | } |
| @@ -245,7 +255,7 @@ static int bma220_probe(struct spi_device *spi) · 23 unmodified lines | ||
| 245 | 255 | indio_dev->available_scan_masks = bma220_accel_scan_masks; |
| 246 | 256 | |
| 247 | 257 | ret = bma220_init(data->spi_device); |
| 248 | − if (ret < 0) | |
| 258 | + if (ret) | |
| 249 | 259 | return ret; |
| 250 | 260 | |
| 251 | 261 | ret = iio_triggered_buffer_setup(indio_dev, iio_pollfunc_store_time, |
| @@ -278,56 +288,43 @@ static int bma220_remove(struct spi_device *spi) · 26 unmodified lines | ||
| 278 | 288 | return bma220_deinit(spi); |
| 279 | 289 | } |
| 280 | 290 | |
| 281 | −#ifdef CONFIG_PM_SLEEP | |
| 282 | −static int bma220_suspend(struct device *dev) | |
| 291 | +static __maybe_unused int bma220_suspend(struct device *dev) | |
| 283 | 292 | { |
| 284 | − struct bma220_data *data = | |
| 285 | − iio_priv(spi_get_drvdata(to_spi_device(dev))); | |
| 293 | + struct bma220_data *data = iio_priv(dev_get_drvdata(dev)); | |
| 286 | 294 | |
| 287 | 295 | /* The chip can be suspended/woken up by a simple register read. */ |
| 288 | 296 | return bma220_read_reg(data->spi_device, BMA220_REG_SUSPEND); |
| 289 | 297 | } |
| 290 | 298 | |
| 291 | −static int bma220_resume(struct device *dev) | |
| 299 | +static __maybe_unused int bma220_resume(struct device *dev) | |
| 292 | 300 | { |
| 293 | − struct bma220_data *data = | |
| 294 | − iio_priv(spi_get_drvdata(to_spi_device(dev))); | |
| 301 | + struct bma220_data *data = iio_priv(dev_get_drvdata(dev)); | |
| 295 | 302 | |
| 296 | 303 | return bma220_read_reg(data->spi_device, BMA220_REG_SUSPEND); |
| 297 | 304 | } |
| 298 | − | |
| 299 | 305 | static SIMPLE_DEV_PM_OPS(bma220_pm_ops, bma220_suspend, bma220_resume); |
| 300 | 306 | |
| 301 | −#define BMA220_PM_OPS (&bma220_pm_ops) | |
| 302 | −#else | |
| 303 | −#define BMA220_PM_OPS NULL | |
| 304 | −#endif | |
| 305 | − | |
| 306 | 307 | static const struct spi_device_id bma220_spi_id[] = { |
| 307 | 308 | {"bma220", 0}, |
| 308 | 309 | {} |
| 309 | 310 | }; |
| 310 | 311 | |
| 311 | −#ifdef CONFIG_ACPI | |
| 312 | 312 | static const struct acpi_device_id bma220_acpi_id[] = { |
| 313 | 313 | {"BMA0220", 0}, |
| 314 | 314 | {} |
| 315 | 315 | }; |
| 316 | − | |
| 317 | 316 | MODULE_DEVICE_TABLE(spi, bma220_spi_id); |
| 318 | −#endif | |
| 319 | 317 | |
| 320 | 318 | static struct spi_driver bma220_driver = { |
| 321 | 319 | .driver = { |
| 322 | 320 | .name = "bma220_spi", |
| 323 | − .pm = BMA220_PM_OPS, | |
| 324 | − .acpi_match_table = ACPI_PTR(bma220_acpi_id), | |
| 321 | + .pm = &bma220_pm_ops, | |
| 322 | + .acpi_match_table = bma220_acpi_id, | |
| 325 | 323 | }, |
| 326 | 324 | .probe = bma220_probe, |
| 327 | 325 | .remove = bma220_remove, |
| 328 | 326 | .id_table = bma220_spi_id, |
| 329 | 327 | }; |
| 330 | − | |
| 331 | 328 | module_spi_driver(bma220_driver); |
| 332 | 329 | |
| 333 | 330 | MODULE_AUTHOR("Tiberiu Breana <tiberiu.a.breana@intel.com>"); |
| @@ -215,7 +215,7 @@ static int cros_ec_accel_legacy_probe(struct platform_device *pdev) · 214 unmodified lines | ||
| 215 | 215 | return -ENOMEM; |
| 216 | 216 | |
| 217 | 217 | ret = cros_ec_sensors_core_init(pdev, indio_dev, true, |
| 218 | − cros_ec_sensors_capture, NULL); | |
| 218 | + cros_ec_sensors_capture, NULL, false); | |
| 219 | 219 | if (ret) |
| 220 | 220 | return ret; |
| 221 | 221 | |
| @@ -1543,22 +1543,14 @@ static int mma8452_probe(struct i2c_client *client, · 1542 unmodified lines | ||
| 1543 | 1543 | data->chip_info = match->data; |
| 1544 | 1544 | |
| 1545 | 1545 | data->vdd_reg = devm_regulator_get(&client->dev, "vdd"); |
| 1546 | − if (IS_ERR(data->vdd_reg)) { | |
| 1547 | − if (PTR_ERR(data->vdd_reg) == -EPROBE_DEFER) | |
| 1548 | − return -EPROBE_DEFER; | |
| 1549 | − | |
| 1550 | − dev_err(&client->dev, "failed to get VDD regulator!\n"); | |
| 1551 | − return PTR_ERR(data->vdd_reg); | |
| 1552 | − } | |
| 1546 | + if (IS_ERR(data->vdd_reg)) | |
| 1547 | + return dev_err_probe(&client->dev, PTR_ERR(data->vdd_reg), | |
| 1548 | + "failed to get VDD regulator!\n"); | |
| 1553 | 1549 | |
| 1554 | 1550 | data->vddio_reg = devm_regulator_get(&client->dev, "vddio"); |
| 1555 | − if (IS_ERR(data->vddio_reg)) { | |
| 1556 | − if (PTR_ERR(data->vddio_reg) == -EPROBE_DEFER) | |
| 1557 | − return -EPROBE_DEFER; | |
| 1558 | − | |
| 1559 | − dev_err(&client->dev, "failed to get VDDIO regulator!\n"); | |
| 1560 | − return PTR_ERR(data->vddio_reg); | |
| 1561 | − } | |
| 1551 | + if (IS_ERR(data->vddio_reg)) | |
| 1552 | + return dev_err_probe(&client->dev, PTR_ERR(data->vddio_reg), | |
| 1553 | + "failed to get VDDIO regulator!\n"); | |
| 1562 | 1554 | |
| 1563 | 1555 | ret = regulator_enable(data->vdd_reg); |
| 1564 | 1556 | if (ret) { |
| @@ -340,7 +340,7 @@ config AXP288_ADC · 339 unmodified lines | ||
| 340 | 340 | |
| 341 | 341 | config BCM_IPROC_ADC |
| 342 | 342 | tristate "Broadcom IPROC ADC driver" |
| 343 | − depends on ARCH_BCM_IPROC || COMPILE_TEST | |
| 343 | + depends on (ARCH_BCM_IPROC && OF) || COMPILE_TEST | |
| 344 | 344 | depends on MFD_SYSCON |
| 345 | 345 | default ARCH_BCM_CYGNUS |
| 346 | 346 | help |
| @@ -863,7 +863,7 @@ config RN5T618_ADC · 516 unmodified lines | ||
| 863 | 863 | |
| 864 | 864 | config ROCKCHIP_SARADC |
| 865 | 865 | tristate "Rockchip SARADC driver" |
| 866 | − depends on ARCH_ROCKCHIP || (ARM && COMPILE_TEST) | |
| 866 | + depends on ARCH_ROCKCHIP || COMPILE_TEST | |
| 867 | 867 | depends on RESET_CONTROLLER |
| 868 | 868 | select IIO_BUFFER |
| 869 | 869 | select IIO_TRIGGERED_BUFFER |
| @@ -20,8 +20,6 @@ · 19 unmodified lines | ||
| 20 | 20 | #include <linux/iio/sysfs.h> |
| 21 | 21 | #include <linux/iio/events.h> |
| 22 | 22 | |
| 23 | −#include <linux/platform_data/ad7291.h> | |
| 24 | − | |
| 25 | 23 | /* |
| 26 | 24 | * Simplified handling |
| 27 | 25 | * |
| @@ -465,7 +463,6 @@ static const struct iio_info ad7291_info = { · 437 unmodified lines | ||
| 465 | 463 | static int ad7291_probe(struct i2c_client *client, |
| 466 | 464 | const struct i2c_device_id *id) |
| 467 | 465 | { |
| 468 | − struct ad7291_platform_data *pdata = client->dev.platform_data; | |
| 469 | 466 | struct ad7291_chip_info *chip; |
| 470 | 467 | struct iio_dev *indio_dev; |
| 471 | 468 | int ret; |
| @@ -475,16 +472,6 @@ static int ad7291_probe(struct i2c_client *client, · 3 unmodified lines | ||
| 475 | 472 | return -ENOMEM; |
| 476 | 473 | chip = iio_priv(indio_dev); |
| 477 | 474 | |
| 478 | − if (pdata && pdata->use_external_ref) { | |
| 479 | − chip->reg = devm_regulator_get(&client->dev, "vref"); | |
| 480 | − if (IS_ERR(chip->reg)) | |
| 481 | − return PTR_ERR(chip->reg); | |
| 482 | − | |
| 483 | − ret = regulator_enable(chip->reg); | |
| 484 | − if (ret) | |
| 485 | − return ret; | |
| 486 | − } | |
| 487 | − | |
| 488 | 475 | mutex_init(&chip->state_lock); |
| 489 | 476 | /* this is only used for device removal purposes */ |
| 490 | 477 | i2c_set_clientdata(client, indio_dev); |
| @@ -495,8 +482,21 @@ static int ad7291_probe(struct i2c_client *client, · 4 unmodified lines | ||
| 495 | 482 | AD7291_T_SENSE_MASK | /* Tsense always enabled */ |
| 496 | 483 | AD7291_ALERT_POLARITY; /* set irq polarity low level */ |
| 497 | 484 | |
| 498 | − if (pdata && pdata->use_external_ref) | |
| 485 | + chip->reg = devm_regulator_get_optional(&client->dev, "vref"); | |
| 486 | + if (IS_ERR(chip->reg)) { | |
| 487 | + if (PTR_ERR(chip->reg) != -ENODEV) | |
| 488 | + return PTR_ERR(chip->reg); | |
| 489 | + | |
| 490 | + chip->reg = NULL; | |
| 491 | + } | |
| 492 | + | |
| 493 | + if (chip->reg) { | |
| 494 | + ret = regulator_enable(chip->reg); | |
| 495 | + if (ret) | |
| 496 | + return ret; | |
| 497 | + | |
| 499 | 498 | chip->command |= AD7291_EXT_REF; |
| 499 | + } | |
| 500 | 500 | |
| 501 | 501 | indio_dev->name = id->name; |
| 502 | 502 | indio_dev->channels = ad7291_channels; |
| @@ -567,9 +567,16 @@ static const struct i2c_device_id ad7291_id[] = { · 64 unmodified lines | ||
| 567 | 567 | |
| 568 | 568 | MODULE_DEVICE_TABLE(i2c, ad7291_id); |
| 569 | 569 | |
| 570 | +static const struct of_device_id ad7291_of_match[] = { | |
| 571 | + { .compatible = "adi,ad7291" }, | |
| 572 | + {} | |
| 573 | +}; | |
| 574 | +MODULE_DEVICE_TABLE(of, ad7291_of_match); | |
| 575 | + | |
| 570 | 576 | static struct i2c_driver ad7291_driver = { |
| 571 | 577 | .driver = { |
| 572 | 578 | .name = KBUILD_MODNAME, |
| 579 | + .of_match_table = ad7291_of_match, | |
| 573 | 580 | }, |
| 574 | 581 | .probe = ad7291_probe, |
| 575 | 582 | .remove = ad7291_remove, |
| @@ -310,8 +310,10 @@ static int ad7292_probe(struct spi_device *spi) · 309 unmodified lines | ||
| 310 | 310 | |
| 311 | 311 | for_each_available_child_of_node(spi->dev.of_node, child) { |
| 312 | 312 | diff_channels = of_property_read_bool(child, "diff-channels"); |
| 313 | − if (diff_channels) | |
| 313 | + if (diff_channels) { | |
| 314 | + of_node_put(child); | |
| 314 | 315 | break; |
| 316 | + } | |
| 315 | 317 | } |
| 316 | 318 | |
| 317 | 319 | if (diff_channels) { |
| @@ -39,7 +39,7 @@ static const struct ad7949_adc_spec ad7949_adc_spec[] = { · 38 unmodified lines | ||
| 39 | 39 | * struct ad7949_adc_chip - AD ADC chip |
| 40 | 40 | * @lock: protects write sequences |
| 41 | 41 | * @vref: regulator generating Vref |
| 42 | − * @iio_dev: reference to iio structure | |
| 42 | + * @indio_dev: reference to iio structure | |
| 43 | 43 | * @spi: reference to spi structure |
| 44 | 44 | * @resolution: resolution of the chip |
| 45 | 45 | * @cfg: copy of the configuration register |
| @@ -76,6 +76,22 @@ · 75 unmodified lines | ||
| 76 | 76 | /* AN877_ADC_REG_OUTPUT_DELAY */ |
| 77 | 77 | #define AN877_ADC_DCO_DELAY_ENABLE 0x80 |
| 78 | 78 | |
| 79 | +/* | |
| 80 | + * Analog Devices AD9265 16-Bit, 125/105/80 MSPS ADC | |
| 81 | + */ | |
| 82 | + | |
| 83 | +#define CHIPID_AD9265 0x64 | |
| 84 | +#define AD9265_DEF_OUTPUT_MODE 0x40 | |
| 85 | +#define AD9265_REG_VREF_MASK 0xC0 | |
| 86 | + | |
| 87 | +/* | |
| 88 | + * Analog Devices AD9434 12-Bit, 370/500 MSPS ADC | |
| 89 | + */ | |
| 90 | + | |
| 91 | +#define CHIPID_AD9434 0x6A | |
| 92 | +#define AD9434_DEF_OUTPUT_MODE 0x00 | |
| 93 | +#define AD9434_REG_VREF_MASK 0xC0 | |
| 94 | + | |
| 79 | 95 | /* |
| 80 | 96 | * Analog Devices AD9467 16-Bit, 200/250 MSPS ADC |
| 81 | 97 | */ |
| @@ -85,9 +101,20 @@ · 3 unmodified lines | ||
| 85 | 101 | #define AD9467_REG_VREF_MASK 0x0F |
| 86 | 102 | |
| 87 | 103 | enum { |
| 104 | + ID_AD9265, | |
| 105 | + ID_AD9434, | |
| 88 | 106 | ID_AD9467, |
| 89 | 107 | }; |
| 90 | 108 | |
| 109 | +struct ad9467_chip_info { | |
| 110 | + struct adi_axi_adc_chip_info axi_adc_info; | |
| 111 | + unsigned int default_output_mode; | |
| 112 | + unsigned int vref_mask; | |
| 113 | +}; | |
| 114 | + | |
| 115 | +#define to_ad9467_chip_info(_info) \ | |
| 116 | + container_of(_info, struct ad9467_chip_info, axi_adc_info) | |
| 117 | + | |
| 91 | 118 | struct ad9467_state { |
| 92 | 119 | struct spi_device *spi; |
| 93 | 120 | struct clk *clk; |
| @@ -149,6 +176,17 @@ static int ad9467_reg_access(struct adi_axi_adc_conv *conv, unsigned int reg, · 55 unmodified lines | ||
| 149 | 176 | return 0; |
| 150 | 177 | } |
| 151 | 178 | |
| 179 | +static const unsigned int ad9265_scale_table[][2] = { | |
| 180 | + {1250, 0x00}, {1500, 0x40}, {1750, 0x80}, {2000, 0xC0}, | |
| 181 | +}; | |
| 182 | + | |
| 183 | +static const unsigned int ad9434_scale_table[][2] = { | |
| 184 | + {1600, 0x1C}, {1580, 0x1D}, {1550, 0x1E}, {1520, 0x1F}, {1500, 0x00}, | |
| 185 | + {1470, 0x01}, {1440, 0x02}, {1420, 0x03}, {1390, 0x04}, {1360, 0x05}, | |
| 186 | + {1340, 0x06}, {1310, 0x07}, {1280, 0x08}, {1260, 0x09}, {1230, 0x0A}, | |
| 187 | + {1200, 0x0B}, {1180, 0x0C}, | |
| 188 | +}; | |
| 189 | + | |
| 152 | 190 | static const unsigned int ad9467_scale_table[][2] = { |
| 153 | 191 | {2000, 0}, {2100, 6}, {2200, 7}, |
| 154 | 192 | {2300, 8}, {2400, 9}, {2500, 10}, |
| @@ -182,39 +220,63 @@ static void __ad9467_get_scale(struct adi_axi_adc_conv *conv, int index, · 27 unmodified lines | ||
| 182 | 220 | }, \ |
| 183 | 221 | } |
| 184 | 222 | |
| 223 | +static const struct iio_chan_spec ad9434_channels[] = { | |
| 224 | + AD9467_CHAN(0, 0, 12, 'S'), | |
| 225 | +}; | |
| 226 | + | |
| 185 | 227 | static const struct iio_chan_spec ad9467_channels[] = { |
| 186 | 228 | AD9467_CHAN(0, 0, 16, 'S'), |
| 187 | 229 | }; |
| 188 | 230 | |
| 189 | −static const struct adi_axi_adc_chip_info ad9467_chip_tbl[] = { | |
| 231 | +static const struct ad9467_chip_info ad9467_chip_tbl[] = { | |
| 232 | + [ID_AD9265] = { | |
| 233 | + .axi_adc_info = { | |
| 234 | + .id = CHIPID_AD9265, | |
| 235 | + .max_rate = 125000000UL, | |
| 236 | + .scale_table = ad9265_scale_table, | |
| 237 | + .num_scales = ARRAY_SIZE(ad9265_scale_table), | |
| 238 | + .channels = ad9467_channels, | |
| 239 | + .num_channels = ARRAY_SIZE(ad9467_channels), | |
| 240 | + }, | |
| 241 | + .default_output_mode = AD9265_DEF_OUTPUT_MODE, | |
| 242 | + .vref_mask = AD9265_REG_VREF_MASK, | |
| 243 | + }, | |
| 244 | + [ID_AD9434] = { | |
| 245 | + .axi_adc_info = { | |
| 246 | + .id = CHIPID_AD9434, | |
| 247 | + .max_rate = 500000000UL, | |
| 248 | + .scale_table = ad9434_scale_table, | |
| 249 | + .num_scales = ARRAY_SIZE(ad9434_scale_table), | |
| 250 | + .channels = ad9434_channels, | |
| 251 | + .num_channels = ARRAY_SIZE(ad9434_channels), | |
| 252 | + }, | |
| 253 | + .default_output_mode = AD9434_DEF_OUTPUT_MODE, | |
| 254 | + .vref_mask = AD9434_REG_VREF_MASK, | |
| 255 | + }, | |
| 190 | 256 | [ID_AD9467] = { |
| 191 | − .id = CHIPID_AD9467, | |
| 192 | − .max_rate = 250000000UL, | |
| 193 | − .scale_table = ad9467_scale_table, | |
| 194 | − .num_scales = ARRAY_SIZE(ad9467_scale_table), | |
| 195 | − .channels = ad9467_channels, | |
| 196 | − .num_channels = ARRAY_SIZE(ad9467_channels), | |
| 257 | + .axi_adc_info = { | |
| 258 | + .id = CHIPID_AD9467, | |
| 259 | + .max_rate = 250000000UL, | |
| 260 | + .scale_table = ad9467_scale_table, | |
| 261 | + .num_scales = ARRAY_SIZE(ad9467_scale_table), | |
| 262 | + .channels = ad9467_channels, | |
| 263 | + .num_channels = ARRAY_SIZE(ad9467_channels), | |
| 264 | + }, | |
| 265 | + .default_output_mode = AD9467_DEF_OUTPUT_MODE, | |
| 266 | + .vref_mask = AD9467_REG_VREF_MASK, | |
| 197 | 267 | }, |
| 198 | 268 | }; |
| 199 | 269 | |
| 200 | 270 | static int ad9467_get_scale(struct adi_axi_adc_conv *conv, int *val, int *val2) |
| 201 | 271 | { |
| 202 | 272 | const struct adi_axi_adc_chip_info *info = conv->chip_info; |
| 273 | + const struct ad9467_chip_info *info1 = to_ad9467_chip_info(info); | |
| 203 | 274 | struct ad9467_state *st = adi_axi_adc_conv_priv(conv); |
| 204 | − unsigned int i, vref_val, vref_mask; | |
| 275 | + unsigned int i, vref_val; | |
| 205 | 276 | |
| 206 | 277 | vref_val = ad9467_spi_read(st->spi, AN877_ADC_REG_VREF); |
| 207 | 278 | |
| 208 | − switch (info->id) { | |
| 209 | − case CHIPID_AD9467: | |
| 210 | − vref_mask = AD9467_REG_VREF_MASK; | |
| 211 | − break; | |
| 212 | − default: | |
| 213 | − vref_mask = 0xFFFF; | |
| 214 | − break; | |
| 215 | − } | |
| 216 | − | |
| 217 | − vref_val &= vref_mask; | |
| 279 | + vref_val &= info1->vref_mask; | |
| 218 | 280 | |
| 219 | 281 | for (i = 0; i < info->num_scales; i++) { |
| 220 | 282 | if (vref_val == info->scale_table[i][1]) |
| @@ -316,18 +378,6 @@ static int ad9467_preenable_setup(struct adi_axi_adc_conv *conv) · 95 unmodified lines | ||
| 316 | 378 | return ad9467_outputmode_set(st->spi, st->output_mode); |
| 317 | 379 | } |
| 318 | 380 | |
| 319 | −static int ad9467_setup(struct ad9467_state *st, unsigned int chip_id) | |
| 320 | −{ | |
| 321 | − switch (chip_id) { | |
| 322 | − case CHIPID_AD9467: | |
| 323 | − st->output_mode = AD9467_DEF_OUTPUT_MODE | | |
| 324 | − AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT; | |
| 325 | − return 0; | |
| 326 | − default: | |
| 327 | − return -EINVAL; | |
| 328 | − } | |
| 329 | −} | |
| 330 | − | |
| 331 | 381 | static void ad9467_clk_disable(void *data) |
| 332 | 382 | { |
| 333 | 383 | struct ad9467_state *st = data; |
| @@ -337,7 +387,7 @@ static void ad9467_clk_disable(void *data) · 3 unmodified lines | ||
| 337 | 387 | |
| 338 | 388 | static int ad9467_probe(struct spi_device *spi) |
| 339 | 389 | { |
| 340 | − const struct adi_axi_adc_chip_info *info; | |
| 390 | + const struct ad9467_chip_info *info; | |
| 341 | 391 | struct adi_axi_adc_conv *conv; |
| 342 | 392 | struct ad9467_state *st; |
| 343 | 393 | unsigned int id; |
| @@ -386,11 +436,12 @@ static int ad9467_probe(struct spi_device *spi) · 42 unmodified lines | ||
| 386 | 436 | |
| 387 | 437 | spi_set_drvdata(spi, st); |
| 388 | 438 | |
| 389 | − conv->chip_info = info; | |
| 439 | + conv->chip_info = &info->axi_adc_info; | |
| 390 | 440 | |
| 391 | 441 | id = ad9467_spi_read(spi, AN877_ADC_REG_CHIP_ID); |
| 392 | 442 | if (id != conv->chip_info->id) { |
| 393 | − dev_err(&spi->dev, "Unrecognized CHIP_ID 0x%X\n", id); | |
| 443 | + dev_err(&spi->dev, "Mismatch CHIP_ID, got 0x%X, expected 0x%X\n", | |
| 444 | + id, conv->chip_info->id); | |
| 394 | 445 | return -ENODEV; |
| 395 | 446 | } |
| 396 | 447 | |
| @@ -399,10 +450,15 @@ static int ad9467_probe(struct spi_device *spi) · 2 unmodified lines | ||
| 399 | 450 | conv->read_raw = ad9467_read_raw; |
| 400 | 451 | conv->preenable_setup = ad9467_preenable_setup; |
| 401 | 452 | |
| 402 | − return ad9467_setup(st, id); | |
| 453 | + st->output_mode = info->default_output_mode | | |
| 454 | + AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT; | |
| 455 | + | |
| 456 | + return 0; | |
| 403 | 457 | } |
| 404 | 458 | |
| 405 | 459 | static const struct of_device_id ad9467_of_match[] = { |
| 460 | + { .compatible = "adi,ad9265", .data = &ad9467_chip_tbl[ID_AD9265], }, | |
| 461 | + { .compatible = "adi,ad9434", .data = &ad9467_chip_tbl[ID_AD9434], }, | |
| 406 | 462 | { .compatible = "adi,ad9467", .data = &ad9467_chip_tbl[ID_AD9467], }, |
| 407 | 463 | {} |
| 408 | 464 | }; |
| @@ -276,7 +276,7 @@ static struct attribute *adi_axi_adc_attributes[] = { · 275 unmodified lines | ||
| 276 | 276 | static umode_t axi_adc_attr_is_visible(struct kobject *kobj, |
| 277 | 277 | struct attribute *attr, int n) |
| 278 | 278 | { |
| 279 | − struct device *dev = container_of(kobj, struct device, kobj); | |
| 279 | + struct device *dev = kobj_to_dev(kobj); | |
| 280 | 280 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); |
| 281 | 281 | struct adi_axi_adc_state *st = iio_priv(indio_dev); |
| 282 | 282 | struct adi_axi_adc_conv *conv = &st->client->conv; |
| @@ -884,7 +884,7 @@ static bool at91_adc_current_chan_is_touch(struct iio_dev *indio_dev) · 883 unmodified lines | ||
| 884 | 884 | AT91_SAMA5D2_MAX_CHAN_IDX + 1); |
| 885 | 885 | } |
| 886 | 886 | |
| 887 | −static int at91_adc_buffer_preenable(struct iio_dev *indio_dev) | |
| 887 | +static int at91_adc_buffer_prepare(struct iio_dev *indio_dev) | |
| 888 | 888 | { |
| 889 | 889 | int ret; |
| 890 | 890 | u8 bit; |
| @@ -901,7 +901,7 @@ static int at91_adc_buffer_preenable(struct iio_dev *indio_dev) · 10 unmodified lines | ||
| 901 | 901 | /* we continue with the triggered buffer */ |
| 902 | 902 | ret = at91_adc_dma_start(indio_dev); |
| 903 | 903 | if (ret) { |
| 904 | − dev_err(&indio_dev->dev, "buffer postenable failed\n"); | |
| 904 | + dev_err(&indio_dev->dev, "buffer prepare failed\n"); | |
| 905 | 905 | return ret; |
| 906 | 906 | } |
| 907 | 907 | |
| @@ -989,7 +989,6 @@ static int at91_adc_buffer_postdisable(struct iio_dev *indio_dev) · 81 unmodified lines | ||
| 989 | 989 | } |
| 990 | 990 | |
| 991 | 991 | static const struct iio_buffer_setup_ops at91_buffer_setup_ops = { |
| 992 | − .preenable = &at91_adc_buffer_preenable, | |
| 993 | 992 | .postdisable = &at91_adc_buffer_postdisable, |
| 994 | 993 | }; |
| 995 | 994 | |
| @@ -1563,6 +1562,7 @@ static void at91_adc_dma_disable(struct platform_device *pdev) · 567 unmodified lines | ||
| 1563 | 1562 | static int at91_adc_set_watermark(struct iio_dev *indio_dev, unsigned int val) |
| 1564 | 1563 | { |
| 1565 | 1564 | struct at91_adc_state *st = iio_priv(indio_dev); |
| 1565 | + int ret; | |
| 1566 | 1566 | |
| 1567 | 1567 | if (val > AT91_HWFIFO_MAX_SIZE) |
| 1568 | 1568 | return -EINVAL; |
| @@ -1586,7 +1586,15 @@ static int at91_adc_set_watermark(struct iio_dev *indio_dev, unsigned int val) · 17 unmodified lines | ||
| 1586 | 1586 | else if (val > 1) |
| 1587 | 1587 | at91_adc_dma_init(to_platform_device(&indio_dev->dev)); |
| 1588 | 1588 | |
| 1589 | − return 0; | |
| 1589 | + /* | |
| 1590 | + * We can start the DMA only after setting the watermark and | |
| 1591 | + * having the DMA initialization completed | |
| 1592 | + */ | |
| 1593 | + ret = at91_adc_buffer_prepare(indio_dev); | |
| 1594 | + if (ret) | |
| 1595 | + at91_adc_dma_disable(to_platform_device(&indio_dev->dev)); | |
| 1596 | + | |
| 1597 | + return ret; | |
| 1590 | 1598 | } |
| 1591 | 1599 | |
| 1592 | 1600 | static int at91_adc_update_scan_mode(struct iio_dev *indio_dev, |
| @@ -1764,17 +1772,13 @@ static int at91_adc_probe(struct platform_device *pdev) · 171 unmodified lines | ||
| 1764 | 1772 | mutex_init(&st->lock); |
| 1765 | 1773 | INIT_WORK(&st->touch_st.workq, at91_adc_workq_handler); |
| 1766 | 1774 | |
| 1767 | − res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 1768 | − if (!res) | |
| 1769 | − return -EINVAL; | |
| 1775 | + st->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); | |
| 1776 | + if (IS_ERR(st->base)) | |
| 1777 | + return PTR_ERR(st->base); | |
| 1770 | 1778 | |
| 1771 | 1779 | /* if we plan to use DMA, we need the physical address of the regs */ |
| 1772 | 1780 | st->dma_st.phys_addr = res->start; |
| 1773 | 1781 | |
| 1774 | − st->base = devm_ioremap_resource(&pdev->dev, res); | |
| 1775 | − if (IS_ERR(st->base)) | |
| 1776 | − return PTR_ERR(st->base); | |
| 1777 | − | |
| 1778 | 1782 | st->irq = platform_get_irq(pdev, 0); |
| 1779 | 1783 | if (st->irq <= 0) { |
| 1780 | 1784 | if (!st->irq) |
| @@ -9,10 +9,10 @@ · 8 unmodified lines | ||
| 9 | 9 | #include <linux/interrupt.h> |
| 10 | 10 | #include <linux/io.h> |
| 11 | 11 | #include <linux/module.h> |
| 12 | −#include <linux/of.h> | |
| 13 | −#include <linux/of_device.h> | |
| 12 | +#include <linux/mod_devicetable.h> | |
| 14 | 13 | #include <linux/platform_device.h> |
| 15 | 14 | #include <linux/pm_runtime.h> |
| 15 | +#include <linux/property.h> | |
| 16 | 16 | #include <linux/regmap.h> |
| 17 | 17 | #include <linux/thermal.h> |
| 18 | 18 | |
| @@ -67,7 +67,7 @@ struct axp_data; · 48 unmodified lines | ||
| 67 | 67 | |
| 68 | 68 | struct axp20x_adc_iio { |
| 69 | 69 | struct regmap *regmap; |
| 70 | − struct axp_data *data; | |
| 70 | + const struct axp_data *data; | |
| 71 | 71 | }; |
| 72 | 72 | |
| 73 | 73 | enum axp20x_adc_channel_v { |
| @@ -670,15 +670,15 @@ static int axp20x_probe(struct platform_device *pdev) · 596 unmodified lines | ||
| 670 | 670 | info->regmap = axp20x_dev->regmap; |
| 671 | 671 | indio_dev->modes = INDIO_DIRECT_MODE; |
| 672 | 672 | |
| 673 | − if (!pdev->dev.of_node) { | |
| 673 | + if (!dev_fwnode(&pdev->dev)) { | |
| 674 | 674 | const struct platform_device_id *id; |
| 675 | 675 | |
| 676 | 676 | id = platform_get_device_id(pdev); |
| 677 | − info->data = (struct axp_data *)id->driver_data; | |
| 677 | + info->data = (const struct axp_data *)id->driver_data; | |
| 678 | 678 | } else { |
| 679 | 679 | struct device *dev = &pdev->dev; |
| 680 | 680 | |
| 681 | − info->data = (struct axp_data *)of_device_get_match_data(dev); | |
| 681 | + info->data = device_get_match_data(dev); | |
| 682 | 682 | } |
| 683 | 683 | |
| 684 | 684 | indio_dev->name = platform_get_device_id(pdev)->name; |
| @@ -742,7 +742,7 @@ static int axp20x_remove(struct platform_device *pdev) · 57 unmodified lines | ||
| 742 | 742 | static struct platform_driver axp20x_adc_driver = { |
| 743 | 743 | .driver = { |
| 744 | 744 | .name = "axp20x-adc", |
| 745 | − .of_match_table = of_match_ptr(axp20x_adc_of_match), | |
| 745 | + .of_match_table = axp20x_adc_of_match, | |
| 746 | 746 | }, |
| 747 | 747 | .id_table = axp20x_adc_id_match, |
| 748 | 748 | .probe = axp20x_probe, |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | */ |
| 5 | 5 | |
| 6 | 6 | #include <linux/module.h> |
| 7 | −#include <linux/of.h> | |
| 7 | +#include <linux/mod_devicetable.h> | |
| 8 | 8 | #include <linux/io.h> |
| 9 | 9 | #include <linux/clk.h> |
| 10 | 10 | #include <linux/mfd/syscon.h> |
| @@ -617,7 +617,7 @@ static struct platform_driver iproc_adc_driver = { · 606 unmodified lines | ||
| 617 | 617 | .remove = iproc_adc_remove, |
| 618 | 618 | .driver = { |
| 619 | 619 | .name = "iproc-static-adc", |
| 620 | − .of_match_table = of_match_ptr(iproc_adc_of_match), | |
| 620 | + .of_match_table = iproc_adc_of_match, | |
| 621 | 621 | }, |
| 622 | 622 | }; |
| 623 | 623 | module_platform_driver(iproc_adc_driver); |
| @@ -348,11 +348,9 @@ static int envelope_detector_probe(struct platform_device *pdev) · 347 unmodified lines | ||
| 348 | 348 | indio_dev->num_channels = 1; |
| 349 | 349 | |
| 350 | 350 | env->dac = devm_iio_channel_get(dev, "dac"); |
| 351 | − if (IS_ERR(env->dac)) { | |
| 352 | − if (PTR_ERR(env->dac) != -EPROBE_DEFER) | |
| 353 | − dev_err(dev, "failed to get dac input channel\n"); | |
| 354 | − return PTR_ERR(env->dac); | |
| 355 | − } | |
| 351 | + if (IS_ERR(env->dac)) | |
| 352 | + return dev_err_probe(dev, PTR_ERR(env->dac), | |
| 353 | + "failed to get dac input channel\n"); | |
| 356 | 354 | |
| 357 | 355 | env->comp_irq = platform_get_irq_byname(pdev, "comp"); |
| 358 | 356 | if (env->comp_irq < 0) |
| @@ -360,11 +358,9 @@ static int envelope_detector_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 360 | 358 | |
| 361 | 359 | ret = devm_request_irq(dev, env->comp_irq, envelope_detector_comp_isr, |
| 362 | 360 | 0, "envelope-detector", env); |
| 363 | − if (ret) { | |
| 364 | − if (ret != -EPROBE_DEFER) | |
| 365 | − dev_err(dev, "failed to request interrupt\n"); | |
| 366 | − return ret; | |
| 367 | − } | |
| 361 | + if (ret) | |
| 362 | + return dev_err_probe(dev, ret, "failed to request interrupt\n"); | |
| 363 | + | |
| 368 | 364 | env->comp_irq_trigger = irq_get_trigger_type(env->comp_irq); |
| 369 | 365 | if (env->comp_irq_trigger & IRQF_TRIGGER_RISING) |
| 370 | 366 | env->comp_irq_trigger_inv |= IRQF_TRIGGER_FALLING; |
| @@ -138,6 +138,16 @@ struct exynos_adc { · 137 unmodified lines | ||
| 138 | 138 | bool read_ts; |
| 139 | 139 | u32 ts_x; |
| 140 | 140 | u32 ts_y; |
| 141 | + | |
| 142 | + /* | |
| 143 | + * Lock to protect from potential concurrent access to the | |
| 144 | + * completion callback during a manual conversion. For this driver | |
| 145 | + * a wait-callback is used to wait for the conversion result, | |
| 146 | + * so in the meantime no other read request (or conversion start) | |
| 147 | + * must be performed, otherwise it would interfere with the | |
| 148 | + * current conversion result. | |
| 149 | + */ | |
| 150 | + struct mutex lock; | |
| 141 | 151 | }; |
| 142 | 152 | |
| 143 | 153 | struct exynos_adc_data { |
| @@ -542,7 +552,7 @@ static int exynos_read_raw(struct iio_dev *indio_dev, · 398 unmodified lines | ||
| 542 | 552 | return -EINVAL; |
| 543 | 553 | } |
| 544 | 554 | |
| 545 | − mutex_lock(&indio_dev->mlock); | |
| 555 | + mutex_lock(&info->lock); | |
| 546 | 556 | reinit_completion(&info->completion); |
| 547 | 557 | |
| 548 | 558 | /* Select the channel to be used and Trigger conversion */ |
| @@ -562,7 +572,7 @@ static int exynos_read_raw(struct iio_dev *indio_dev, · 13 unmodified lines | ||
| 562 | 572 | ret = IIO_VAL_INT; |
| 563 | 573 | } |
| 564 | 574 | |
| 565 | − mutex_unlock(&indio_dev->mlock); | |
| 575 | + mutex_unlock(&info->lock); | |
| 566 | 576 | |
| 567 | 577 | return ret; |
| 568 | 578 | } |
| @@ -573,7 +583,7 @@ static int exynos_read_s3c64xx_ts(struct iio_dev *indio_dev, int *x, int *y) · 4 unmodified lines | ||
| 573 | 583 | unsigned long timeout; |
| 574 | 584 | int ret; |
| 575 | 585 | |
| 576 | − mutex_lock(&indio_dev->mlock); | |
| 586 | + mutex_lock(&info->lock); | |
| 577 | 587 | info->read_ts = true; |
| 578 | 588 | |
| 579 | 589 | reinit_completion(&info->completion); |
| @@ -598,7 +608,7 @@ static int exynos_read_s3c64xx_ts(struct iio_dev *indio_dev, int *x, int *y) · 18 unmodified lines | ||
| 598 | 608 | } |
| 599 | 609 | |
| 600 | 610 | info->read_ts = false; |
| 601 | − mutex_unlock(&indio_dev->mlock); | |
| 611 | + mutex_unlock(&info->lock); | |
| 602 | 612 | |
| 603 | 613 | return ret; |
| 604 | 614 | } |
| @@ -844,13 +854,9 @@ static int exynos_adc_probe(struct platform_device *pdev) · 239 unmodified lines | ||
| 844 | 854 | } |
| 845 | 855 | |
| 846 | 856 | info->vdd = devm_regulator_get(&pdev->dev, "vdd"); |
| 847 | − if (IS_ERR(info->vdd)) { | |
| 848 | − if (PTR_ERR(info->vdd) != -EPROBE_DEFER) | |
| 849 | − dev_err(&pdev->dev, | |
| 850 | − "failed getting regulator, err = %ld\n", | |
| 851 | − PTR_ERR(info->vdd)); | |
| 852 | − return PTR_ERR(info->vdd); | |
| 853 | − } | |
| 857 | + if (IS_ERR(info->vdd)) | |
| 858 | + return dev_err_probe(&pdev->dev, PTR_ERR(info->vdd), | |
| 859 | + "failed getting regulator"); | |
| 854 | 860 | |
| 855 | 861 | ret = regulator_enable(info->vdd); |
| 856 | 862 | if (ret) |
| @@ -872,6 +878,8 @@ static int exynos_adc_probe(struct platform_device *pdev) · 15 unmodified lines | ||
| 872 | 878 | indio_dev->channels = exynos_adc_iio_channels; |
| 873 | 879 | indio_dev->num_channels = info->data->num_channels; |
| 874 | 880 | |
| 881 | + mutex_init(&info->lock); | |
| 882 | + | |
| 875 | 883 | ret = request_irq(info->irq, exynos_adc_isr, |
| 876 | 884 | 0, dev_name(&pdev->dev), info); |
| 877 | 885 | if (ret < 0) { |
| @@ -40,6 +40,15 @@ struct mx25_gcq_priv { · 39 unmodified lines | ||
| 40 | 40 | int irq; |
| 41 | 41 | struct regulator *vref[4]; |
| 42 | 42 | u32 channel_vref_mv[MX25_NUM_CFGS]; |
| 43 | + /* | |
| 44 | + * Lock to protect the device state during a potential concurrent | |
| 45 | + * read access from userspace. Reading a raw value requires a sequence | |
| 46 | + * of register writes, then a wait for a completion callback, | |
| 47 | + * and finally a register read, during which userspace could issue | |
| 48 | + * another read request. This lock protects a read access from | |
| 49 | + * ocurring before another one has finished. | |
| 50 | + */ | |
| 51 | + struct mutex lock; | |
| 43 | 52 | }; |
| 44 | 53 | |
| 45 | 54 | #define MX25_CQG_CHAN(chan, id) {\ |
| @@ -137,9 +146,9 @@ static int mx25_gcq_read_raw(struct iio_dev *indio_dev, · 91 unmodified lines | ||
| 137 | 146 | |
| 138 | 147 | switch (mask) { |
| 139 | 148 | case IIO_CHAN_INFO_RAW: |
| 140 | − mutex_lock(&indio_dev->mlock); | |
| 149 | + mutex_lock(&priv->lock); | |
| 141 | 150 | ret = mx25_gcq_get_raw_value(&indio_dev->dev, chan, priv, val); |
| 142 | − mutex_unlock(&indio_dev->mlock); | |
| 151 | + mutex_unlock(&priv->lock); | |
| 143 | 152 | return ret; |
| 144 | 153 | |
| 145 | 154 | case IIO_CHAN_INFO_SCALE: |
| @@ -314,6 +323,8 @@ static int mx25_gcq_probe(struct platform_device *pdev) · 168 unmodified lines | ||
| 314 | 323 | return PTR_ERR(priv->regs); |
| 315 | 324 | } |
| 316 | 325 | |
| 326 | + mutex_init(&priv->lock); | |
| 327 | + | |
| 317 | 328 | init_completion(&priv->completed); |
| 318 | 329 | |
| 319 | 330 | ret = mx25_gcq_setup_cfgs(pdev, priv); |
| @@ -180,13 +180,9 @@ int ltc2497core_probe(struct device *dev, struct iio_dev *indio_dev) · 179 unmodified lines | ||
| 180 | 180 | return ret; |
| 181 | 181 | |
| 182 | 182 | ddata->ref = devm_regulator_get(dev, "vref"); |
| 183 | − if (IS_ERR(ddata->ref)) { | |
| 184 | − if (PTR_ERR(ddata->ref) != -EPROBE_DEFER) | |
| 185 | − dev_err(dev, "Failed to get vref regulator: %pe\n", | |
| 186 | − ddata->ref); | |
| 187 | − | |
| 188 | − return PTR_ERR(ddata->ref); | |
| 189 | − } | |
| 183 | + if (IS_ERR(ddata->ref)) | |
| 184 | + return dev_err_probe(dev, PTR_ERR(ddata->ref), | |
| 185 | + "Failed to get vref regulator\n"); | |
| 190 | 186 | |
| 191 | 187 | ret = regulator_enable(ddata->ref); |
| 192 | 188 | if (ret < 0) { |
| @@ -719,11 +719,8 @@ static int meson_sar_adc_temp_sensor_init(struct iio_dev *indio_dev) · 718 unmodified lines | ||
| 719 | 719 | if (ret == -ENODEV) |
| 720 | 720 | return 0; |
| 721 | 721 | |
| 722 | − if (ret != -EPROBE_DEFER) | |
| 723 | − dev_err(indio_dev->dev.parent, | |
| 724 | − "failed to get temperature_calib cell\n"); | |
| 725 | − | |
| 726 | − return ret; | |
| 722 | + return dev_err_probe(indio_dev->dev.parent, ret, | |
| 723 | + "failed to get temperature_calib cell\n"); | |
| 727 | 724 | } |
| 728 | 725 | |
| 729 | 726 | priv->tsc_regmap = |
| @@ -1153,16 +1150,13 @@ static const struct of_device_id meson_sar_adc_of_match[] = { · 423 unmodified lines | ||
| 1153 | 1150 | { |
| 1154 | 1151 | .compatible = "amlogic,meson8-saradc", |
| 1155 | 1152 | .data = &meson_sar_adc_meson8_data, |
| 1156 | − }, | |
| 1157 | − { | |
| 1153 | + }, { | |
| 1158 | 1154 | .compatible = "amlogic,meson8b-saradc", |
| 1159 | 1155 | .data = &meson_sar_adc_meson8b_data, |
| 1160 | − }, | |
| 1161 | − { | |
| 1156 | + }, { | |
| 1162 | 1157 | .compatible = "amlogic,meson8m2-saradc", |
| 1163 | 1158 | .data = &meson_sar_adc_meson8m2_data, |
| 1164 | − }, | |
| 1165 | − { | |
| 1159 | + }, { | |
| 1166 | 1160 | .compatible = "amlogic,meson-gxbb-saradc", |
| 1167 | 1161 | .data = &meson_sar_adc_gxbb_data, |
| 1168 | 1162 | }, { |
| @@ -1178,7 +1172,7 @@ static const struct of_device_id meson_sar_adc_of_match[] = { · 9 unmodified lines | ||
| 1178 | 1172 | .compatible = "amlogic,meson-g12a-saradc", |
| 1179 | 1173 | .data = &meson_sar_adc_g12a_data, |
| 1180 | 1174 | }, |
| 1181 | − {}, | |
| 1175 | + { /* sentinel */ } | |
| 1182 | 1176 | }; |
| 1183 | 1177 | MODULE_DEVICE_TABLE(of, meson_sar_adc_of_match); |
| 1184 | 1178 | |
| @@ -834,18 +834,7 @@ static struct platform_driver palmas_gpadc_driver = { · 833 unmodified lines | ||
| 834 | 834 | .of_match_table = of_palmas_gpadc_match_tbl, |
| 835 | 835 | }, |
| 836 | 836 | }; |
| 837 | − | |
| 838 | −static int __init palmas_gpadc_init(void) | |
| 839 | −{ | |
| 840 | − return platform_driver_register(&palmas_gpadc_driver); | |
| 841 | −} | |
| 842 | −module_init(palmas_gpadc_init); | |
| 843 | − | |
| 844 | −static void __exit palmas_gpadc_exit(void) | |
| 845 | −{ | |
| 846 | − platform_driver_unregister(&palmas_gpadc_driver); | |
| 847 | −} | |
| 848 | −module_exit(palmas_gpadc_exit); | |
| 837 | +module_platform_driver(palmas_gpadc_driver); | |
| 849 | 838 | |
| 850 | 839 | MODULE_DESCRIPTION("palmas GPADC driver"); |
| 851 | 840 | MODULE_AUTHOR("Pradeep Goudagunta<pgoudagunta@nvidia.com>"); |
| @@ -357,7 +357,7 @@ static int rcar_gyroadc_parse_subdevs(struct iio_dev *indio_dev) · 356 unmodified lines | ||
| 357 | 357 | num_channels = ARRAY_SIZE(rcar_gyroadc_iio_channels_3); |
| 358 | 358 | break; |
| 359 | 359 | default: |
| 360 | − return -EINVAL; | |
| 360 | + goto err_e_inval; | |
| 361 | 361 | } |
| 362 | 362 | |
| 363 | 363 | /* |
| @@ -374,7 +374,7 @@ static int rcar_gyroadc_parse_subdevs(struct iio_dev *indio_dev) · 10 unmodified lines | ||
| 374 | 374 | dev_err(dev, |
| 375 | 375 | "Failed to get child reg property of ADC \"%pOFn\".\n", |
| 376 | 376 | child); |
| 377 | − return ret; | |
| 377 | + goto err_of_node_put; | |
| 378 | 378 | } |
| 379 | 379 | |
| 380 | 380 | /* Channel number is too high. */ |
| @@ -382,7 +382,7 @@ static int rcar_gyroadc_parse_subdevs(struct iio_dev *indio_dev) · 1 unmodified line | ||
| 382 | 382 | dev_err(dev, |
| 383 | 383 | "Only %i channels supported with %pOFn, but reg = <%i>.\n", |
| 384 | 384 | num_channels, child, reg); |
| 385 | − return -EINVAL; | |
| 385 | + goto err_e_inval; | |
| 386 | 386 | } |
| 387 | 387 | } |
| 388 | 388 | |
| @@ -391,7 +391,7 @@ static int rcar_gyroadc_parse_subdevs(struct iio_dev *indio_dev) · 2 unmodified lines | ||
| 391 | 391 | dev_err(dev, |
| 392 | 392 | "Channel %i uses different ADC mode than the rest.\n", |
| 393 | 393 | reg); |
| 394 | − return -EINVAL; | |
| 394 | + goto err_e_inval; | |
| 395 | 395 | } |
| 396 | 396 | |
| 397 | 397 | /* Channel is valid, grab the regulator. */ |
| @@ -401,7 +401,8 @@ static int rcar_gyroadc_parse_subdevs(struct iio_dev *indio_dev) · 3 unmodified lines | ||
| 401 | 401 | if (IS_ERR(vref)) { |
| 402 | 402 | dev_dbg(dev, "Channel %i 'vref' supply not connected.\n", |
| 403 | 403 | reg); |
| 404 | − return PTR_ERR(vref); | |
| 404 | + ret = PTR_ERR(vref); | |
| 405 | + goto err_of_node_put; | |
| 405 | 406 | } |
| 406 | 407 | |
| 407 | 408 | priv->vref[reg] = vref; |
| @@ -425,8 +426,10 @@ static int rcar_gyroadc_parse_subdevs(struct iio_dev *indio_dev) · 17 unmodified lines | ||
| 425 | 426 | * attached to the GyroADC at a time, so if we found it, |
| 426 | 427 | * we can stop parsing here. |
| 427 | 428 | */ |
| 428 | − if (childmode == RCAR_GYROADC_MODE_SELECT_1_MB88101A) | |
| 429 | + if (childmode == RCAR_GYROADC_MODE_SELECT_1_MB88101A) { | |
| 430 | + of_node_put(child); | |
| 429 | 431 | break; |
| 432 | + } | |
| 430 | 433 | } |
| 431 | 434 | |
| 432 | 435 | if (first) { |
| @@ -435,6 +438,12 @@ static int rcar_gyroadc_parse_subdevs(struct iio_dev *indio_dev) · 2 unmodified lines | ||
| 435 | 438 | } |
| 436 | 439 | |
| 437 | 440 | return 0; |
| 441 | + | |
| 442 | +err_e_inval: | |
| 443 | + ret = -EINVAL; | |
| 444 | +err_of_node_put: | |
| 445 | + of_node_put(child); | |
| 446 | + return ret; | |
| 438 | 447 | } |
| 439 | 448 | |
| 440 | 449 | static void rcar_gyroadc_deinit_supplies(struct iio_dev *indio_dev) |
| @@ -495,12 +504,9 @@ static int rcar_gyroadc_probe(struct platform_device *pdev) · 54 unmodified lines | ||
| 495 | 504 | return PTR_ERR(priv->regs); |
| 496 | 505 | |
| 497 | 506 | priv->clk = devm_clk_get(dev, "fck"); |
| 498 | − if (IS_ERR(priv->clk)) { | |
| 499 | − ret = PTR_ERR(priv->clk); | |
| 500 | − if (ret != -EPROBE_DEFER) | |
| 501 | − dev_err(dev, "Failed to get IF clock (ret=%i)\n", ret); | |
| 502 | − return ret; | |
| 503 | − } | |
| 507 | + if (IS_ERR(priv->clk)) | |
| 508 | + return dev_err_probe(dev, PTR_ERR(priv->clk), | |
| 509 | + "Failed to get IF clock\n"); | |
| 504 | 510 | |
| 505 | 511 | ret = rcar_gyroadc_parse_subdevs(indio_dev); |
| 506 | 512 | if (ret) |
| @@ -582,11 +582,9 @@ static int stm32_adc_core_switches_probe(struct device *dev, · 581 unmodified lines | ||
| 582 | 582 | priv->syscfg = syscon_regmap_lookup_by_phandle(np, "st,syscfg"); |
| 583 | 583 | if (IS_ERR(priv->syscfg)) { |
| 584 | 584 | ret = PTR_ERR(priv->syscfg); |
| 585 | − if (ret != -ENODEV) { | |
| 586 | − if (ret != -EPROBE_DEFER) | |
| 587 | − dev_err(dev, "Can't probe syscfg: %d\n", ret); | |
| 588 | − return ret; | |
| 589 | − } | |
| 585 | + if (ret != -ENODEV) | |
| 586 | + return dev_err_probe(dev, ret, "Can't probe syscfg\n"); | |
| 587 | + | |
| 590 | 588 | priv->syscfg = NULL; |
| 591 | 589 | } |
| 592 | 590 | |
| @@ -596,12 +594,9 @@ static int stm32_adc_core_switches_probe(struct device *dev, · 3 unmodified lines | ||
| 596 | 594 | priv->booster = devm_regulator_get_optional(dev, "booster"); |
| 597 | 595 | if (IS_ERR(priv->booster)) { |
| 598 | 596 | ret = PTR_ERR(priv->booster); |
| 599 | − if (ret != -ENODEV) { | |
| 600 | − if (ret != -EPROBE_DEFER) | |
| 601 | − dev_err(dev, "can't get booster %d\n", | |
| 602 | − ret); | |
| 603 | − return ret; | |
| 604 | − } | |
| 597 | + if (ret != -ENODEV) | |
| 598 | + return dev_err_probe(dev, ret, "can't get booster\n"); | |
| 599 | + | |
| 605 | 600 | priv->booster = NULL; |
| 606 | 601 | } |
| 607 | 602 | } |
| @@ -612,11 +607,9 @@ static int stm32_adc_core_switches_probe(struct device *dev, · 4 unmodified lines | ||
| 612 | 607 | priv->vdd = devm_regulator_get_optional(dev, "vdd"); |
| 613 | 608 | if (IS_ERR(priv->vdd)) { |
| 614 | 609 | ret = PTR_ERR(priv->vdd); |
| 615 | − if (ret != -ENODEV) { | |
| 616 | − if (ret != -EPROBE_DEFER) | |
| 617 | − dev_err(dev, "can't get vdd %d\n", ret); | |
| 618 | − return ret; | |
| 619 | − } | |
| 610 | + if (ret != -ENODEV) | |
| 611 | + return dev_err_probe(dev, ret, "can't get vdd\n"); | |
| 612 | + | |
| 620 | 613 | priv->vdd = NULL; |
| 621 | 614 | } |
| 622 | 615 | } |
| @@ -669,42 +662,24 @@ static int stm32_adc_probe(struct platform_device *pdev) · 46 unmodified lines | ||
| 669 | 662 | priv->common.phys_base = res->start; |
| 670 | 663 | |
| 671 | 664 | priv->vdda = devm_regulator_get(&pdev->dev, "vdda"); |
| 672 | − if (IS_ERR(priv->vdda)) { | |
| 673 | − ret = PTR_ERR(priv->vdda); | |
| 674 | − if (ret != -EPROBE_DEFER) | |
| 675 | − dev_err(&pdev->dev, "vdda get failed, %d\n", ret); | |
| 676 | − return ret; | |
| 677 | − } | |
| 665 | + if (IS_ERR(priv->vdda)) | |
| 666 | + return dev_err_probe(&pdev->dev, PTR_ERR(priv->vdda), | |
| 667 | + "vdda get failed\n"); | |
| 678 | 668 | |
| 679 | 669 | priv->vref = devm_regulator_get(&pdev->dev, "vref"); |
| 680 | − if (IS_ERR(priv->vref)) { | |
| 681 | − ret = PTR_ERR(priv->vref); | |
| 682 | − if (ret != -EPROBE_DEFER) | |
| 683 | − dev_err(&pdev->dev, "vref get failed, %d\n", ret); | |
| 684 | − return ret; | |
| 685 | − } | |
| 670 | + if (IS_ERR(priv->vref)) | |
| 671 | + return dev_err_probe(&pdev->dev, PTR_ERR(priv->vref), | |
| 672 | + "vref get failed\n"); | |
| 686 | 673 | |
| 687 | − priv->aclk = devm_clk_get(&pdev->dev, "adc"); | |
| 688 | − if (IS_ERR(priv->aclk)) { | |
| 689 | − ret = PTR_ERR(priv->aclk); | |
| 690 | − if (ret != -ENOENT) { | |
| 691 | − if (ret != -EPROBE_DEFER) | |
| 692 | − dev_err(&pdev->dev, "Can't get 'adc' clock\n"); | |
| 693 | − return ret; | |
| 694 | − } | |
| 695 | − priv->aclk = NULL; | |
| 696 | − } | |
| 674 | + priv->aclk = devm_clk_get_optional(&pdev->dev, "adc"); | |
| 675 | + if (IS_ERR(priv->aclk)) | |
| 676 | + return dev_err_probe(&pdev->dev, PTR_ERR(priv->aclk), | |
| 677 | + "Can't get 'adc' clock\n"); | |
| 697 | 678 | |
| 698 | − priv->bclk = devm_clk_get(&pdev->dev, "bus"); | |
| 699 | − if (IS_ERR(priv->bclk)) { | |
| 700 | − ret = PTR_ERR(priv->bclk); | |
| 701 | − if (ret != -ENOENT) { | |
| 702 | − if (ret != -EPROBE_DEFER) | |
| 703 | − dev_err(&pdev->dev, "Can't get 'bus' clock\n"); | |
| 704 | − return ret; | |
| 705 | − } | |
| 706 | − priv->bclk = NULL; | |
| 707 | − } | |
| 679 | + priv->bclk = devm_clk_get_optional(&pdev->dev, "bus"); | |
| 680 | + if (IS_ERR(priv->bclk)) | |
| 681 | + return dev_err_probe(&pdev->dev, PTR_ERR(priv->bclk), | |
| 682 | + "Can't get 'bus' clock\n"); | |
| 708 | 683 | |
| 709 | 684 | ret = stm32_adc_core_switches_probe(dev, priv); |
| 710 | 685 | if (ret) |
| @@ -794,6 +769,13 @@ static int stm32_adc_core_runtime_resume(struct device *dev) · 83 unmodified lines | ||
| 794 | 769 | { |
| 795 | 770 | return stm32_adc_core_hw_start(dev); |
| 796 | 771 | } |
| 772 | + | |
| 773 | +static int stm32_adc_core_runtime_idle(struct device *dev) | |
| 774 | +{ | |
| 775 | + pm_runtime_mark_last_busy(dev); | |
| 776 | + | |
| 777 | + return 0; | |
| 778 | +} | |
| 797 | 779 | #endif |
| 798 | 780 | |
| 799 | 781 | static const struct dev_pm_ops stm32_adc_core_pm_ops = { |
| @@ -801,7 +783,7 @@ static const struct dev_pm_ops stm32_adc_core_pm_ops = { · 1 unmodified line | ||
| 801 | 783 | pm_runtime_force_resume) |
| 802 | 784 | SET_RUNTIME_PM_OPS(stm32_adc_core_runtime_suspend, |
| 803 | 785 | stm32_adc_core_runtime_resume, |
| 804 | − NULL) | |
| 786 | + stm32_adc_core_runtime_idle) | |
| 805 | 787 | }; |
| 806 | 788 | |
| 807 | 789 | static const struct stm32_adc_priv_cfg stm32f4_adc_priv_cfg = { |
| @@ -1805,13 +1805,9 @@ static int stm32_adc_dma_request(struct device *dev, struct iio_dev *indio_dev) · 1804 unmodified lines | ||
| 1805 | 1805 | adc->dma_chan = dma_request_chan(dev, "rx"); |
| 1806 | 1806 | if (IS_ERR(adc->dma_chan)) { |
| 1807 | 1807 | ret = PTR_ERR(adc->dma_chan); |
| 1808 | − if (ret != -ENODEV) { | |
| 1809 | − if (ret != -EPROBE_DEFER) | |
| 1810 | − dev_err(dev, | |
| 1811 | − "DMA channel request failed with %d\n", | |
| 1812 | − ret); | |
| 1813 | − return ret; | |
| 1814 | − } | |
| 1808 | + if (ret != -ENODEV) | |
| 1809 | + return dev_err_probe(dev, ret, | |
| 1810 | + "DMA channel request failed with\n"); | |
| 1815 | 1811 | |
| 1816 | 1812 | /* DMA is optional: fall back to IRQ mode */ |
| 1817 | 1813 | adc->dma_chan = NULL; |
| @@ -1473,13 +1473,9 @@ static int stm32_dfsdm_adc_init(struct device *dev, struct iio_dev *indio_dev) · 1472 unmodified lines | ||
| 1473 | 1473 | /* Optionally request DMA */ |
| 1474 | 1474 | ret = stm32_dfsdm_dma_request(dev, indio_dev); |
| 1475 | 1475 | if (ret) { |
| 1476 | − if (ret != -ENODEV) { | |
| 1477 | − if (ret != -EPROBE_DEFER) | |
| 1478 | − dev_err(dev, | |
| 1479 | − "DMA channel request failed with %d\n", | |
| 1480 | − ret); | |
| 1481 | − return ret; | |
| 1482 | − } | |
| 1476 | + if (ret != -ENODEV) | |
| 1477 | + return dev_err_probe(dev, ret, | |
| 1478 | + "DMA channel request failed with\n"); | |
| 1483 | 1479 | |
| 1484 | 1480 | dev_dbg(dev, "No DMA support\n"); |
| 1485 | 1481 | return 0; |
| @@ -226,16 +226,13 @@ static int stm32_dfsdm_parse_of(struct platform_device *pdev, · 225 unmodified lines | ||
| 226 | 226 | if (!node) |
| 227 | 227 | return -EINVAL; |
| 228 | 228 | |
| 229 | − res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 230 | − if (!res) { | |
| 231 | − dev_err(&pdev->dev, "Failed to get memory resource\n"); | |
| 232 | − return -ENODEV; | |
| 233 | − } | |
| 234 | − priv->dfsdm.phys_base = res->start; | |
| 235 | − priv->dfsdm.base = devm_ioremap_resource(&pdev->dev, res); | |
| 229 | + priv->dfsdm.base = devm_platform_get_and_ioremap_resource(pdev, 0, | |
| 230 | + &res); | |
| 236 | 231 | if (IS_ERR(priv->dfsdm.base)) |
| 237 | 232 | return PTR_ERR(priv->dfsdm.base); |
| 238 | 233 | |
| 234 | + priv->dfsdm.phys_base = res->start; | |
| 235 | + | |
| 239 | 236 | /* |
| 240 | 237 | * "dfsdm" clock is mandatory for DFSDM peripheral clocking. |
| 241 | 238 | * "dfsdm" or "audio" clocks can be used as source clock for |
| @@ -243,12 +240,9 @@ static int stm32_dfsdm_parse_of(struct platform_device *pdev, · 1 unmodified line | ||
| 243 | 240 | * on use case. |
| 244 | 241 | */ |
| 245 | 242 | priv->clk = devm_clk_get(&pdev->dev, "dfsdm"); |
| 246 | − if (IS_ERR(priv->clk)) { | |
| 247 | − ret = PTR_ERR(priv->clk); | |
| 248 | − if (ret != -EPROBE_DEFER) | |
| 249 | − dev_err(&pdev->dev, "Failed to get clock (%d)\n", ret); | |
| 250 | − return ret; | |
| 251 | − } | |
| 243 | + if (IS_ERR(priv->clk)) | |
| 244 | + return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk), | |
| 245 | + "Failed to get clock\n"); | |
| 252 | 246 | |
| 253 | 247 | priv->aclk = devm_clk_get(&pdev->dev, "audio"); |
| 254 | 248 | if (IS_ERR(priv->aclk)) |
| @@ -19,7 +19,6 @@ · 18 unmodified lines | ||
| 19 | 19 | #include <linux/i2c.h> |
| 20 | 20 | #include <linux/module.h> |
| 21 | 21 | #include <linux/mod_devicetable.h> |
| 22 | −#include <linux/acpi.h> | |
| 23 | 22 | |
| 24 | 23 | #include <linux/iio/iio.h> |
| 25 | 24 | #include <linux/iio/buffer.h> |
| @@ -158,17 +157,7 @@ static int adc081c_probe(struct i2c_client *client, · 132 unmodified lines | ||
| 158 | 157 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) |
| 159 | 158 | return -EOPNOTSUPP; |
| 160 | 159 | |
| 161 | − if (ACPI_COMPANION(&client->dev)) { | |
| 162 | − const struct acpi_device_id *ad_id; | |
| 163 | − | |
| 164 | − ad_id = acpi_match_device(client->dev.driver->acpi_match_table, | |
| 165 | − &client->dev); | |
| 166 | − if (!ad_id) | |
| 167 | − return -ENODEV; | |
| 168 | − model = &adcxx1c_models[ad_id->driver_data]; | |
| 169 | − } else { | |
| 170 | − model = &adcxx1c_models[id->driver_data]; | |
| 171 | − } | |
| 160 | + model = &adcxx1c_models[id->driver_data]; | |
| 172 | 161 | |
| 173 | 162 | iio = devm_iio_device_alloc(&client->dev, sizeof(*adc)); |
| 174 | 163 | if (!iio) |
| @@ -243,21 +232,10 @@ static const struct of_device_id adc081c_of_match[] = { · 68 unmodified lines | ||
| 243 | 232 | }; |
| 244 | 233 | MODULE_DEVICE_TABLE(of, adc081c_of_match); |
| 245 | 234 | |
| 246 | −#ifdef CONFIG_ACPI | |
| 247 | −static const struct acpi_device_id adc081c_acpi_match[] = { | |
| 248 | − { "ADC081C", ADC081C }, | |
| 249 | − { "ADC101C", ADC101C }, | |
| 250 | − { "ADC121C", ADC121C }, | |
| 251 | − { } | |
| 252 | −}; | |
| 253 | −MODULE_DEVICE_TABLE(acpi, adc081c_acpi_match); | |
| 254 | −#endif | |
| 255 | − | |
| 256 | 235 | static struct i2c_driver adc081c_driver = { |
| 257 | 236 | .driver = { |
| 258 | 237 | .name = "adc081c", |
| 259 | 238 | .of_match_table = adc081c_of_match, |
| 260 | − .acpi_match_table = ACPI_PTR(adc081c_acpi_match), | |
| 261 | 239 | }, |
| 262 | 240 | .probe = adc081c_probe, |
| 263 | 241 | .remove = adc081c_remove, |
| @@ -29,6 +29,12 @@ struct adc0832 { · 28 unmodified lines | ||
| 29 | 29 | struct regulator *reg; |
| 30 | 30 | struct mutex lock; |
| 31 | 31 | u8 mux_bits; |
| 32 | + /* | |
| 33 | + * Max size needed: 16x 1 byte ADC data + 8 bytes timestamp | |
| 34 | + * May be shorter if not all channels are enabled subject | |
| 35 | + * to the timestamp remaining 8 byte aligned. | |
| 36 | + */ | |
| 37 | + u8 data[24] __aligned(8); | |
| 32 | 38 | |
| 33 | 39 | u8 tx_buf[2] ____cacheline_aligned; |
| 34 | 40 | u8 rx_buf[2]; |
| @@ -200,7 +206,6 @@ static irqreturn_t adc0832_trigger_handler(int irq, void *p) · 165 unmodified lines | ||
| 200 | 206 | struct iio_poll_func *pf = p; |
| 201 | 207 | struct iio_dev *indio_dev = pf->indio_dev; |
| 202 | 208 | struct adc0832 *adc = iio_priv(indio_dev); |
| 203 | − u8 data[24] = { }; /* 16x 1 byte ADC data + 8 bytes timestamp */ | |
| 204 | 209 | int scan_index; |
| 205 | 210 | int i = 0; |
| 206 | 211 | |
| @@ -218,10 +223,10 @@ static irqreturn_t adc0832_trigger_handler(int irq, void *p) · 11 unmodified lines | ||
| 218 | 223 | goto out; |
| 219 | 224 | } |
| 220 | 225 | |
| 221 | − data[i] = ret; | |
| 226 | + adc->data[i] = ret; | |
| 222 | 227 | i++; |
| 223 | 228 | } |
| 224 | − iio_push_to_buffers_with_timestamp(indio_dev, data, | |
| 229 | + iio_push_to_buffers_with_timestamp(indio_dev, adc->data, | |
| 225 | 230 | iio_get_time_ns(indio_dev)); |
| 226 | 231 | out: |
| 227 | 232 | mutex_unlock(&adc->lock); |
| @@ -20,6 +20,7 @@ · 19 unmodified lines | ||
| 20 | 20 | #include <linux/iio/trigger_consumer.h> |
| 21 | 21 | #include <linux/interrupt.h> |
| 22 | 22 | #include <linux/module.h> |
| 23 | +#include <linux/mod_devicetable.h> | |
| 23 | 24 | #include <linux/property.h> |
| 24 | 25 | #include <linux/regulator/consumer.h> |
| 25 | 26 | #include <linux/spi/spi.h> |
| @@ -299,13 +300,11 @@ static int adc108s102_remove(struct spi_device *spi) · 273 unmodified lines | ||
| 299 | 300 | return 0; |
| 300 | 301 | } |
| 301 | 302 | |
| 302 | −#ifdef CONFIG_OF | |
| 303 | 303 | static const struct of_device_id adc108s102_of_match[] = { |
| 304 | 304 | { .compatible = "ti,adc108s102" }, |
| 305 | 305 | { } |
| 306 | 306 | }; |
| 307 | 307 | MODULE_DEVICE_TABLE(of, adc108s102_of_match); |
| 308 | −#endif | |
| 309 | 308 | |
| 310 | 309 | #ifdef CONFIG_ACPI |
| 311 | 310 | static const struct acpi_device_id adc108s102_acpi_ids[] = { |
| @@ -324,7 +323,7 @@ MODULE_DEVICE_TABLE(spi, adc108s102_id); · 12 unmodified lines | ||
| 324 | 323 | static struct spi_driver adc108s102_driver = { |
| 325 | 324 | .driver = { |
| 326 | 325 | .name = "adc108s102", |
| 327 | − .of_match_table = of_match_ptr(adc108s102_of_match), | |
| 326 | + .of_match_table = adc108s102_of_match, | |
| 328 | 327 | .acpi_match_table = ACPI_PTR(adc108s102_acpi_ids), |
| 329 | 328 | }, |
| 330 | 329 | .probe = adc108s102_probe, |
| @@ -47,6 +47,12 @@ struct adc12138 { · 46 unmodified lines | ||
| 47 | 47 | struct completion complete; |
| 48 | 48 | /* The number of cclk periods for the S/H's acquisition time */ |
| 49 | 49 | unsigned int acquisition_time; |
| 50 | + /* | |
| 51 | + * Maximum size needed: 16x 2 bytes ADC data + 8 bytes timestamp. | |
| 52 | + * Less may be need if not all channels are enabled, as long as | |
| 53 | + * the 8 byte alignment of the timestamp is maintained. | |
| 54 | + */ | |
| 55 | + __be16 data[20] __aligned(8); | |
| 50 | 56 | |
| 51 | 57 | u8 tx_buf[2] ____cacheline_aligned; |
| 52 | 58 | u8 rx_buf[2]; |
| @@ -329,7 +335,6 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p) · 276 unmodified lines | ||
| 329 | 335 | struct iio_poll_func *pf = p; |
| 330 | 336 | struct iio_dev *indio_dev = pf->indio_dev; |
| 331 | 337 | struct adc12138 *adc = iio_priv(indio_dev); |
| 332 | − __be16 data[20] = { }; /* 16x 2 bytes ADC data + 8 bytes timestamp */ | |
| 333 | 338 | __be16 trash; |
| 334 | 339 | int ret; |
| 335 | 340 | int scan_index; |
| @@ -345,7 +350,7 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p) · 9 unmodified lines | ||
| 345 | 350 | reinit_completion(&adc->complete); |
| 346 | 351 | |
| 347 | 352 | ret = adc12138_start_and_read_conv(adc, scan_chan, |
| 348 | − i ? &data[i - 1] : &trash); | |
| 353 | + i ? &adc->data[i - 1] : &trash); | |
| 349 | 354 | if (ret) { |
| 350 | 355 | dev_warn(&adc->spi->dev, |
| 351 | 356 | "failed to start conversion\n"); |
| @@ -362,7 +367,7 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p) · 10 unmodified lines | ||
| 362 | 367 | } |
| 363 | 368 | |
| 364 | 369 | if (i) { |
| 365 | − ret = adc12138_read_conv_data(adc, &data[i - 1]); | |
| 370 | + ret = adc12138_read_conv_data(adc, &adc->data[i - 1]); | |
| 366 | 371 | if (ret) { |
| 367 | 372 | dev_warn(&adc->spi->dev, |
| 368 | 373 | "failed to get conversion data\n"); |
| @@ -370,7 +375,7 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p) · 1 unmodified line | ||
| 370 | 375 | } |
| 371 | 376 | } |
| 372 | 377 | |
| 373 | − iio_push_to_buffers_with_timestamp(indio_dev, data, | |
| 378 | + iio_push_to_buffers_with_timestamp(indio_dev, adc->data, | |
| 374 | 379 | iio_get_time_ns(indio_dev)); |
| 375 | 380 | out: |
| 376 | 381 | mutex_unlock(&adc->lock); |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <linux/err.h> |
| 14 | 14 | #include <linux/spi/spi.h> |
| 15 | 15 | #include <linux/module.h> |
| 16 | +#include <linux/mod_devicetable.h> | |
| 16 | 17 | #include <linux/iio/iio.h> |
| 17 | 18 | #include <linux/property.h> |
| 18 | 19 | #include <linux/regulator/consumer.h> |
| @@ -220,7 +221,7 @@ MODULE_DEVICE_TABLE(acpi, adc128_acpi_match); · 201 unmodified lines | ||
| 220 | 221 | static struct spi_driver adc128_driver = { |
| 221 | 222 | .driver = { |
| 222 | 223 | .name = "adc128s052", |
| 223 | − .of_match_table = of_match_ptr(adc128_of_match), | |
| 224 | + .of_match_table = adc128_of_match, | |
| 224 | 225 | .acpi_match_table = ACPI_PTR(adc128_acpi_match), |
| 225 | 226 | }, |
| 226 | 227 | .probe = adc128_probe, |
| @@ -276,11 +276,9 @@ static int rescale_probe(struct platform_device *pdev) · 275 unmodified lines | ||
| 276 | 276 | int ret; |
| 277 | 277 | |
| 278 | 278 | source = devm_iio_channel_get(dev, NULL); |
| 279 | − if (IS_ERR(source)) { | |
| 280 | − if (PTR_ERR(source) != -EPROBE_DEFER) | |
| 281 | − dev_err(dev, "failed to get source channel\n"); | |
| 282 | − return PTR_ERR(source); | |
| 283 | − } | |
| 279 | + if (IS_ERR(source)) | |
| 280 | + return dev_err_probe(dev, PTR_ERR(source), | |
| 281 | + "failed to get source channel\n"); | |
| 284 | 282 | |
| 285 | 283 | sizeof_ext_info = iio_get_channel_ext_info_count(source); |
| 286 | 284 | if (sizeof_ext_info) { |
| @@ -18,6 +18,7 @@ config AD8366 · 17 unmodified lines | ||
| 18 | 18 | AD8366 Dual-Digital Variable Gain Amplifier (VGA) |
| 19 | 19 | ADA4961 BiCMOS RF Digital Gain Amplifier (DGA) |
| 20 | 20 | ADL5240 Digitally controlled variable gain amplifier (VGA) |
| 21 | + HMC1119 0.25 dB LSB, 7-Bit, Silicon Digital Attenuator | |
| 21 | 22 | |
| 22 | 23 | To compile this driver as a module, choose M here: the |
| 23 | 24 | module will be called ad8366. |
| @@ -201,12 +201,9 @@ static int hmc425a_probe(struct platform_device *pdev) · 200 unmodified lines | ||
| 201 | 201 | st->gain = st->chip_info->default_gain; |
| 202 | 202 | |
| 203 | 203 | st->gpios = devm_gpiod_get_array(&pdev->dev, "ctrl", GPIOD_OUT_LOW); |
| 204 | − if (IS_ERR(st->gpios)) { | |
| 205 | − ret = PTR_ERR(st->gpios); | |
| 206 | − if (ret != -EPROBE_DEFER) | |
| 207 | − dev_err(&pdev->dev, "failed to get gpios\n"); | |
| 208 | − return ret; | |
| 209 | − } | |
| 204 | + if (IS_ERR(st->gpios)) | |
| 205 | + return dev_err_probe(&pdev->dev, PTR_ERR(st->gpios), | |
| 206 | + "failed to get gpios\n"); | |
| 210 | 207 | |
| 211 | 208 | if (st->gpios->ndescs != st->chip_info->num_gpios) { |
| 212 | 209 | dev_err(&pdev->dev, "%d GPIOs needed to operate\n", |
| @@ -11,7 +11,7 @@ config IIO_BUFFER_CB · 10 unmodified lines | ||
| 11 | 11 | usage. That is, those where the data is pushed to the consumer. |
| 12 | 12 | |
| 13 | 13 | config IIO_BUFFER_DMA |
| 14 | − tristate | |
| 14 | + tristate "Industrial I/O DMA buffer infrastructure" | |
| 15 | 15 | help |
| 16 | 16 | Provides the generic IIO DMA buffer infrastructure that can be used by |
| 17 | 17 | drivers for devices with DMA support to implement the IIO buffer. |
| @@ -20,13 +20,13 @@ config IIO_BUFFER_DMA · 2 unmodified lines | ||
| 20 | 20 | infrastructure. |
| 21 | 21 | |
| 22 | 22 | config IIO_BUFFER_DMAENGINE |
| 23 | − tristate | |
| 23 | + tristate "Industrial I/O DMA buffer integration with DMAEngine" | |
| 24 | 24 | select IIO_BUFFER_DMA |
| 25 | 25 | help |
| 26 | 26 | Provides a bonding of the generic IIO DMA buffer infrastructure with the |
| 27 | − DMAengine framework. This can be used by converter drivers with a DMA port | |
| 27 | + DMAEngine framework. This can be used by converter drivers with a DMA port | |
| 28 | 28 | connected to an external DMA controller which is supported by the |
| 29 | − DMAengine framework. | |
| 29 | + DMAEngine framework. | |
| 30 | 30 | |
| 31 | 31 | Should be selected by drivers that want to use this functionality. |
| 32 | 32 | |
| @@ -48,7 +48,7 @@ config IIO_KFIFO_BUF · 15 unmodified lines | ||
| 48 | 48 | often to read from the buffer. |
| 49 | 49 | |
| 50 | 50 | config IIO_TRIGGERED_BUFFER |
| 51 | − tristate | |
| 51 | + tristate "Industrial I/O triggered buffer support" | |
| 52 | 52 | select IIO_TRIGGER |
| 53 | 53 | select IIO_KFIFO_BUF |
| 54 | 54 | help |
| @@ -45,7 +45,8 @@ static struct dmaengine_buffer *iio_buffer_to_dmaengine_buffer( · 44 unmodified lines | ||
| 45 | 45 | return container_of(buffer, struct dmaengine_buffer, queue.buffer); |
| 46 | 46 | } |
| 47 | 47 | |
| 48 | −static void iio_dmaengine_buffer_block_done(void *data) | |
| 48 | +static void iio_dmaengine_buffer_block_done(void *data, | |
| 49 | + const struct dmaengine_result *result) | |
| 49 | 50 | { |
| 50 | 51 | struct iio_dma_buffer_block *block = data; |
| 51 | 52 | unsigned long flags; |
| @@ -53,6 +54,7 @@ static void iio_dmaengine_buffer_block_done(void *data) · 1 unmodified line | ||
| 53 | 54 | spin_lock_irqsave(&block->queue->list_lock, flags); |
| 54 | 55 | list_del(&block->head); |
| 55 | 56 | spin_unlock_irqrestore(&block->queue->list_lock, flags); |
| 57 | + block->bytes_used -= result->residue; | |
| 56 | 58 | iio_dma_buffer_block_done(block); |
| 57 | 59 | } |
| 58 | 60 | |
| @@ -74,7 +76,7 @@ static int iio_dmaengine_buffer_submit_block(struct iio_dma_buffer_queue *queue, · 15 unmodified lines | ||
| 74 | 76 | if (!desc) |
| 75 | 77 | return -ENOMEM; |
| 76 | 78 | |
| 77 | − desc->callback = iio_dmaengine_buffer_block_done; | |
| 79 | + desc->callback_result = iio_dmaengine_buffer_block_done; | |
| 78 | 80 | desc->callback_param = block; |
| 79 | 81 | |
| 80 | 82 | cookie = dmaengine_submit(desc); |
| @@ -157,7 +159,7 @@ static const struct attribute *iio_dmaengine_buffer_attrs[] = { · 76 unmodified lines | ||
| 157 | 159 | * Once done using the buffer iio_dmaengine_buffer_free() should be used to |
| 158 | 160 | * release it. |
| 159 | 161 | */ |
| 160 | −struct iio_buffer *iio_dmaengine_buffer_alloc(struct device *dev, | |
| 162 | +static struct iio_buffer *iio_dmaengine_buffer_alloc(struct device *dev, | |
| 161 | 163 | const char *channel) |
| 162 | 164 | { |
| 163 | 165 | struct dmaengine_buffer *dmaengine_buffer; |
| @@ -209,7 +211,6 @@ err_free: · 45 unmodified lines | ||
| 209 | 211 | kfree(dmaengine_buffer); |
| 210 | 212 | return ERR_PTR(ret); |
| 211 | 213 | } |
| 212 | −EXPORT_SYMBOL(iio_dmaengine_buffer_alloc); | |
| 213 | 214 | |
| 214 | 215 | /** |
| 215 | 216 | * iio_dmaengine_buffer_free() - Free dmaengine buffer |
| @@ -217,7 +218,7 @@ EXPORT_SYMBOL(iio_dmaengine_buffer_alloc); · 1 unmodified line | ||
| 217 | 218 | * |
| 218 | 219 | * Frees a buffer previously allocated with iio_dmaengine_buffer_alloc(). |
| 219 | 220 | */ |
| 220 | −void iio_dmaengine_buffer_free(struct iio_buffer *buffer) | |
| 221 | +static void iio_dmaengine_buffer_free(struct iio_buffer *buffer) | |
| 221 | 222 | { |
| 222 | 223 | struct dmaengine_buffer *dmaengine_buffer = |
| 223 | 224 | iio_buffer_to_dmaengine_buffer(buffer); |
| @@ -227,7 +228,6 @@ void iio_dmaengine_buffer_free(struct iio_buffer *buffer) · 3 unmodified lines | ||
| 227 | 228 | |
| 228 | 229 | iio_buffer_put(buffer); |
| 229 | 230 | } |
| 230 | −EXPORT_SYMBOL_GPL(iio_dmaengine_buffer_free); | |
| 231 | 231 | |
| 232 | 232 | static void __devm_iio_dmaengine_buffer_free(struct device *dev, void *res) |
| 233 | 233 | { |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | */ |
| 8 | 8 | |
| 9 | 9 | #include <linux/module.h> |
| 10 | +#include <linux/mod_devicetable.h> | |
| 10 | 11 | #include <linux/mutex.h> |
| 11 | 12 | #include <linux/init.h> |
| 12 | 13 | #include <linux/i2c.h> |
| @@ -177,7 +178,7 @@ MODULE_DEVICE_TABLE(of, ams_iaqcore_dt_ids); · 164 unmodified lines | ||
| 177 | 178 | static struct i2c_driver ams_iaqcore_driver = { |
| 178 | 179 | .driver = { |
| 179 | 180 | .name = "ams-iaq-core", |
| 180 | − .of_match_table = of_match_ptr(ams_iaqcore_dt_ids), | |
| 181 | + .of_match_table = ams_iaqcore_dt_ids, | |
| 181 | 182 | }, |
| 182 | 183 | .probe = ams_iaqcore_probe, |
| 183 | 184 | .id_table = ams_iaqcore_id, |
| @@ -16,10 +16,13 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <linux/iio/iio.h> |
| 17 | 17 | |
| 18 | 18 | #define ATLAS_EZO_DRV_NAME "atlas-ezo-sensor" |
| 19 | −#define ATLAS_CO2_INT_TIME_IN_MS 950 | |
| 19 | +#define ATLAS_INT_TIME_IN_MS 950 | |
| 20 | +#define ATLAS_INT_HUM_TIME_IN_MS 350 | |
| 20 | 21 | |
| 21 | 22 | enum { |
| 22 | 23 | ATLAS_CO2_EZO, |
| 24 | + ATLAS_O2_EZO, | |
| 25 | + ATLAS_HUM_EZO, | |
| 23 | 26 | }; |
| 24 | 27 | |
| 25 | 28 | struct atlas_ezo_device { |
| @@ -38,15 +41,37 @@ struct atlas_ezo_data { · 12 unmodified lines | ||
| 38 | 41 | u8 buffer[8]; |
| 39 | 42 | }; |
| 40 | 43 | |
| 44 | +#define ATLAS_CONCENTRATION_CHANNEL(_modifier) \ | |
| 45 | + { \ | |
| 46 | + .type = IIO_CONCENTRATION, \ | |
| 47 | + .modified = 1,\ | |
| 48 | + .channel2 = _modifier, \ | |
| 49 | + .info_mask_separate = \ | |
| 50 | + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), \ | |
| 51 | + .scan_index = 0, \ | |
| 52 | + .scan_type = { \ | |
| 53 | + .sign = 'u', \ | |
| 54 | + .realbits = 32, \ | |
| 55 | + .storagebits = 32, \ | |
| 56 | + .endianness = IIO_CPU, \ | |
| 57 | + }, \ | |
| 58 | + } | |
| 59 | + | |
| 41 | 60 | static const struct iio_chan_spec atlas_co2_ezo_channels[] = { |
| 61 | + ATLAS_CONCENTRATION_CHANNEL(IIO_MOD_CO2), | |
| 62 | +}; | |
| 63 | + | |
| 64 | +static const struct iio_chan_spec atlas_o2_ezo_channels[] = { | |
| 65 | + ATLAS_CONCENTRATION_CHANNEL(IIO_MOD_O2), | |
| 66 | +}; | |
| 67 | + | |
| 68 | +static const struct iio_chan_spec atlas_hum_ezo_channels[] = { | |
| 42 | 69 | { |
| 43 | − .type = IIO_CONCENTRATION, | |
| 44 | − .modified = 1, | |
| 45 | − .channel2 = IIO_MOD_CO2, | |
| 70 | + .type = IIO_HUMIDITYRELATIVE, | |
| 46 | 71 | .info_mask_separate = |
| 47 | 72 | BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), |
| 48 | 73 | .scan_index = 0, |
| 49 | − .scan_type = { | |
| 74 | + .scan_type = { | |
| 50 | 75 | .sign = 'u', |
| 51 | 76 | .realbits = 32, |
| 52 | 77 | .storagebits = 32, |
| @@ -59,10 +84,30 @@ static struct atlas_ezo_device atlas_ezo_devices[] = { · 6 unmodified lines | ||
| 59 | 84 | [ATLAS_CO2_EZO] = { |
| 60 | 85 | .channels = atlas_co2_ezo_channels, |
| 61 | 86 | .num_channels = 1, |
| 62 | − .delay = ATLAS_CO2_INT_TIME_IN_MS, | |
| 87 | + .delay = ATLAS_INT_TIME_IN_MS, | |
| 88 | + }, | |
| 89 | + [ATLAS_O2_EZO] = { | |
| 90 | + .channels = atlas_o2_ezo_channels, | |
| 91 | + .num_channels = 1, | |
| 92 | + .delay = ATLAS_INT_TIME_IN_MS, | |
| 93 | + }, | |
| 94 | + [ATLAS_HUM_EZO] = { | |
| 95 | + .channels = atlas_hum_ezo_channels, | |
| 96 | + .num_channels = 1, | |
| 97 | + .delay = ATLAS_INT_HUM_TIME_IN_MS, | |
| 63 | 98 | }, |
| 64 | 99 | }; |
| 65 | 100 | |
| 101 | +static void atlas_ezo_sanitize(char *buf) | |
| 102 | +{ | |
| 103 | + char *ptr = strchr(buf, '.'); | |
| 104 | + | |
| 105 | + if (!ptr) | |
| 106 | + return; | |
| 107 | + | |
| 108 | + memmove(ptr, ptr + 1, strlen(ptr)); | |
| 109 | +} | |
| 110 | + | |
| 66 | 111 | static int atlas_ezo_read_raw(struct iio_dev *indio_dev, |
| 67 | 112 | struct iio_chan_spec const *chan, |
| 68 | 113 | int *val, int *val2, long mask) |
| @@ -96,6 +141,9 @@ static int atlas_ezo_read_raw(struct iio_dev *indio_dev, · 27 unmodified lines | ||
| 96 | 141 | return -EBUSY; |
| 97 | 142 | } |
| 98 | 143 | |
| 144 | + /* removing floating point for fixed number representation */ | |
| 145 | + atlas_ezo_sanitize(data->buffer + 2); | |
| 146 | + | |
| 99 | 147 | ret = kstrtol(data->buffer + 1, 10, &tmp); |
| 100 | 148 | |
| 101 | 149 | *val = tmp; |
| @@ -105,9 +153,27 @@ static int atlas_ezo_read_raw(struct iio_dev *indio_dev, · 3 unmodified lines | ||
| 105 | 153 | return ret ? ret : IIO_VAL_INT; |
| 106 | 154 | } |
| 107 | 155 | case IIO_CHAN_INFO_SCALE: |
| 108 | − *val = 0; | |
| 109 | − *val2 = 100; /* 0.0001 */ | |
| 110 | − return IIO_VAL_INT_PLUS_MICRO; | |
| 156 | + switch (chan->type) { | |
| 157 | + case IIO_HUMIDITYRELATIVE: | |
| 158 | + *val = 10; | |
| 159 | + return IIO_VAL_INT; | |
| 160 | + case IIO_CONCENTRATION: | |
| 161 | + break; | |
| 162 | + default: | |
| 163 | + return -EINVAL; | |
| 164 | + } | |
| 165 | + | |
| 166 | + /* IIO_CONCENTRATION modifiers */ | |
| 167 | + switch (chan->channel2) { | |
| 168 | + case IIO_MOD_CO2: | |
| 169 | + *val = 0; | |
| 170 | + *val2 = 100; /* 0.0001 */ | |
| 171 | + return IIO_VAL_INT_PLUS_MICRO; | |
| 172 | + case IIO_MOD_O2: | |
| 173 | + *val = 100; | |
| 174 | + return IIO_VAL_INT; | |
| 175 | + } | |
| 176 | + return -EINVAL; | |
| 111 | 177 | } |
| 112 | 178 | |
| 113 | 179 | return 0; |
| @@ -119,12 +185,16 @@ static const struct iio_info atlas_info = { · 5 unmodified lines | ||
| 119 | 185 | |
| 120 | 186 | static const struct i2c_device_id atlas_ezo_id[] = { |
| 121 | 187 | { "atlas-co2-ezo", ATLAS_CO2_EZO }, |
| 188 | + { "atlas-o2-ezo", ATLAS_O2_EZO }, | |
| 189 | + { "atlas-hum-ezo", ATLAS_HUM_EZO }, | |
| 122 | 190 | {} |
| 123 | 191 | }; |
| 124 | 192 | MODULE_DEVICE_TABLE(i2c, atlas_ezo_id); |
| 125 | 193 | |
| 126 | 194 | static const struct of_device_id atlas_ezo_dt_ids[] = { |
| 127 | 195 | { .compatible = "atlas,co2-ezo", .data = (void *)ATLAS_CO2_EZO, }, |
| 196 | + { .compatible = "atlas,o2-ezo", .data = (void *)ATLAS_O2_EZO, }, | |
| 197 | + { .compatible = "atlas,hum-ezo", .data = (void *)ATLAS_HUM_EZO, }, | |
| 128 | 198 | {} |
| 129 | 199 | }; |
| 130 | 200 | MODULE_DEVICE_TABLE(of, atlas_ezo_dt_ids); |
| @@ -15,7 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/irq.h> |
| 16 | 16 | #include <linux/irq_work.h> |
| 17 | 17 | #include <linux/i2c.h> |
| 18 | −#include <linux/of_device.h> | |
| 18 | +#include <linux/mod_devicetable.h> | |
| 19 | 19 | #include <linux/regmap.h> |
| 20 | 20 | #include <linux/iio/iio.h> |
| 21 | 21 | #include <linux/iio/buffer.h> |
| @@ -620,7 +620,6 @@ static int atlas_probe(struct i2c_client *client, · 598 unmodified lines | ||
| 620 | 620 | { |
| 621 | 621 | struct atlas_data *data; |
| 622 | 622 | struct atlas_device *chip; |
| 623 | − const struct of_device_id *of_id; | |
| 624 | 623 | struct iio_trigger *trig; |
| 625 | 624 | struct iio_dev *indio_dev; |
| 626 | 625 | int ret; |
| @@ -629,11 +628,10 @@ static int atlas_probe(struct i2c_client *client, · 2 unmodified lines | ||
| 629 | 628 | if (!indio_dev) |
| 630 | 629 | return -ENOMEM; |
| 631 | 630 | |
| 632 | − of_id = of_match_device(atlas_dt_ids, &client->dev); | |
| 633 | − if (!of_id) | |
| 631 | + if (!dev_fwnode(&client->dev)) | |
| 634 | 632 | chip = &atlas_devices[id->driver_data]; |
| 635 | 633 | else |
| 636 | − chip = &atlas_devices[(unsigned long)of_id->data]; | |
| 634 | + chip = &atlas_devices[(unsigned long)device_get_match_data(&client->dev)]; | |
| 637 | 635 | |
| 638 | 636 | indio_dev->info = &atlas_info; |
| 639 | 637 | indio_dev->name = ATLAS_DRV_NAME; |
| @@ -775,7 +773,7 @@ static const struct dev_pm_ops atlas_pm_ops = { · 135 unmodified lines | ||
| 775 | 773 | static struct i2c_driver atlas_driver = { |
| 776 | 774 | .driver = { |
| 777 | 775 | .name = ATLAS_DRV_NAME, |
| 778 | − .of_match_table = of_match_ptr(atlas_dt_ids), | |
| 776 | + .of_match_table = atlas_dt_ids, | |
| 779 | 777 | .pm = &atlas_pm_ops, |
| 780 | 778 | }, |
| 781 | 779 | .probe = atlas_probe, |
| @@ -705,13 +705,8 @@ int scd30_probe(struct device *dev, int irq, const char *name, void *priv, · 704 unmodified lines | ||
| 705 | 705 | indio_dev->available_scan_masks = scd30_scan_masks; |
| 706 | 706 | |
| 707 | 707 | state->vdd = devm_regulator_get(dev, "vdd"); |
| 708 | − if (IS_ERR(state->vdd)) { | |
| 709 | − if (PTR_ERR(state->vdd) == -EPROBE_DEFER) | |
| 710 | − return -EPROBE_DEFER; | |
| 711 | − | |
| 712 | − dev_err(dev, "failed to get regulator\n"); | |
| 713 | − return PTR_ERR(state->vdd); | |
| 714 | − } | |
| 708 | + if (IS_ERR(state->vdd)) | |
| 709 | + return dev_err_probe(dev, PTR_ERR(state->vdd), "failed to get regulator\n"); | |
| 715 | 710 | |
| 716 | 711 | ret = regulator_enable(state->vdd); |
| 717 | 712 | if (ret) |
| @@ -20,9 +20,9 @@ · 19 unmodified lines | ||
| 20 | 20 | #include <linux/delay.h> |
| 21 | 21 | #include <linux/kthread.h> |
| 22 | 22 | #include <linux/module.h> |
| 23 | +#include <linux/mod_devicetable.h> | |
| 23 | 24 | #include <linux/mutex.h> |
| 24 | 25 | #include <linux/i2c.h> |
| 25 | −#include <linux/of_device.h> | |
| 26 | 26 | #include <linux/iio/iio.h> |
| 27 | 27 | #include <linux/iio/sysfs.h> |
| 28 | 28 | |
| @@ -227,6 +227,7 @@ static int sgp_verify_buffer(const struct sgp_data *data, · 198 unmodified lines | ||
| 227 | 227 | * @cmd: SGP Command to issue |
| 228 | 228 | * @buf: Raw data buffer to use |
| 229 | 229 | * @word_count: Num words to read, excluding CRC bytes |
| 230 | + * @duration_us: Time taken to sensor to take a reading and data to be ready. | |
| 230 | 231 | * |
| 231 | 232 | * Return: 0 on success, negative error otherwise. |
| 232 | 233 | */ |
| @@ -409,6 +410,7 @@ static int sgp_read_raw(struct iio_dev *indio_dev, · 176 unmodified lines | ||
| 409 | 410 | static int sgp_check_compat(struct sgp_data *data, |
| 410 | 411 | unsigned int product_id) |
| 411 | 412 | { |
| 413 | + struct device *dev = &data->client->dev; | |
| 412 | 414 | const struct sgp_version *supported_versions; |
| 413 | 415 | u16 ix, num_fs; |
| 414 | 416 | u16 product, generation, major, minor; |
| @@ -416,21 +418,20 @@ static int sgp_check_compat(struct sgp_data *data, · 1 unmodified line | ||
| 416 | 418 | /* driver does not match product */ |
| 417 | 419 | generation = SGP_VERS_GEN(data); |
| 418 | 420 | if (generation != 0) { |
| 419 | − dev_err(&data->client->dev, | |
| 421 | + dev_err(dev, | |
| 420 | 422 | "incompatible product generation %d != 0", generation); |
| 421 | 423 | return -ENODEV; |
| 422 | 424 | } |
| 423 | 425 | |
| 424 | 426 | product = SGP_VERS_PRODUCT(data); |
| 425 | 427 | if (product != product_id) { |
| 426 | − dev_err(&data->client->dev, | |
| 427 | − "sensor reports a different product: 0x%04hx\n", | |
| 428 | + dev_err(dev, "sensor reports a different product: 0x%04hx\n", | |
| 428 | 429 | product); |
| 429 | 430 | return -ENODEV; |
| 430 | 431 | } |
| 431 | 432 | |
| 432 | 433 | if (SGP_VERS_RESERVED(data)) |
| 433 | − dev_warn(&data->client->dev, "reserved bit is set\n"); | |
| 434 | + dev_warn(dev, "reserved bit is set\n"); | |
| 434 | 435 | |
| 435 | 436 | /* engineering samples are not supported: no interface guarantees */ |
| 436 | 437 | if (SGP_VERS_ENG_BIT(data)) |
| @@ -456,8 +457,7 @@ static int sgp_check_compat(struct sgp_data *data, · 19 unmodified lines | ||
| 456 | 457 | minor >= supported_versions[ix].minor) |
| 457 | 458 | return 0; |
| 458 | 459 | } |
| 459 | − dev_err(&data->client->dev, "unsupported sgp version: %d.%d\n", | |
| 460 | − major, minor); | |
| 460 | + dev_err(dev, "unsupported sgp version: %d.%d\n", major, minor); | |
| 461 | 461 | |
| 462 | 462 | return -ENODEV; |
| 463 | 463 | } |
| @@ -499,19 +499,18 @@ static const struct of_device_id sgp_dt_ids[] = { · 35 unmodified lines | ||
| 499 | 499 | static int sgp_probe(struct i2c_client *client, |
| 500 | 500 | const struct i2c_device_id *id) |
| 501 | 501 | { |
| 502 | + struct device *dev = &client->dev; | |
| 502 | 503 | struct iio_dev *indio_dev; |
| 503 | 504 | struct sgp_data *data; |
| 504 | − const struct of_device_id *of_id; | |
| 505 | 505 | unsigned long product_id; |
| 506 | 506 | int ret; |
| 507 | 507 | |
| 508 | − indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); | |
| 508 | + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); | |
| 509 | 509 | if (!indio_dev) |
| 510 | 510 | return -ENOMEM; |
| 511 | 511 | |
| 512 | − of_id = of_match_device(sgp_dt_ids, &client->dev); | |
| 513 | − if (of_id) | |
| 514 | − product_id = (unsigned long)of_id->data; | |
| 512 | + if (dev_fwnode(dev)) | |
| 513 | + product_id = (unsigned long)device_get_match_data(dev); | |
| 515 | 514 | else |
| 516 | 515 | product_id = id->driver_data; |
| 517 | 516 | |
| @@ -541,9 +540,9 @@ static int sgp_probe(struct i2c_client *client, · 23 unmodified lines | ||
| 541 | 540 | |
| 542 | 541 | sgp_init(data); |
| 543 | 542 | |
| 544 | − ret = devm_iio_device_register(&client->dev, indio_dev); | |
| 543 | + ret = devm_iio_device_register(dev, indio_dev); | |
| 545 | 544 | if (ret) { |
| 546 | − dev_err(&client->dev, "failed to register iio device\n"); | |
| 545 | + dev_err(dev, "failed to register iio device\n"); | |
| 547 | 546 | return ret; |
| 548 | 547 | } |
| 549 | 548 | |
| @@ -576,7 +575,7 @@ MODULE_DEVICE_TABLE(of, sgp_dt_ids); · 26 unmodified lines | ||
| 576 | 575 | static struct i2c_driver sgp_driver = { |
| 577 | 576 | .driver = { |
| 578 | 577 | .name = "sgp30", |
| 579 | − .of_match_table = of_match_ptr(sgp_dt_ids), | |
| 578 | + .of_match_table = sgp_dt_ids, | |
| 580 | 579 | }, |
| 581 | 580 | .probe = sgp_probe, |
| 582 | 581 | .remove = sgp_remove, |
| @@ -10,8 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | #include <linux/mutex.h> |
| 11 | 11 | #include <linux/init.h> |
| 12 | 12 | #include <linux/i2c.h> |
| 13 | −#include <linux/of.h> | |
| 14 | −#include <linux/of_device.h> | |
| 13 | +#include <linux/mod_devicetable.h> | |
| 15 | 14 | |
| 16 | 15 | #include <linux/iio/iio.h> |
| 17 | 16 | #include <linux/iio/sysfs.h> |
| @@ -352,12 +351,12 @@ MODULE_DEVICE_TABLE(of, vz89x_dt_ids); · 334 unmodified lines | ||
| 352 | 351 | static int vz89x_probe(struct i2c_client *client, |
| 353 | 352 | const struct i2c_device_id *id) |
| 354 | 353 | { |
| 354 | + struct device *dev = &client->dev; | |
| 355 | 355 | struct iio_dev *indio_dev; |
| 356 | 356 | struct vz89x_data *data; |
| 357 | − const struct of_device_id *of_id; | |
| 358 | 357 | int chip_id; |
| 359 | 358 | |
| 360 | − indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); | |
| 359 | + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); | |
| 361 | 360 | if (!indio_dev) |
| 362 | 361 | return -ENOMEM; |
| 363 | 362 | data = iio_priv(indio_dev); |
| @@ -370,11 +369,10 @@ static int vz89x_probe(struct i2c_client *client, · 6 unmodified lines | ||
| 370 | 369 | else |
| 371 | 370 | return -EOPNOTSUPP; |
| 372 | 371 | |
| 373 | − of_id = of_match_device(vz89x_dt_ids, &client->dev); | |
| 374 | − if (!of_id) | |
| 372 | + if (!dev_fwnode(dev)) | |
| 375 | 373 | chip_id = id->driver_data; |
| 376 | 374 | else |
| 377 | − chip_id = (unsigned long)of_id->data; | |
| 375 | + chip_id = (unsigned long)device_get_match_data(dev); | |
| 378 | 376 | |
| 379 | 377 | i2c_set_clientdata(client, indio_dev); |
| 380 | 378 | data->client = client; |
| @@ -383,13 +381,13 @@ static int vz89x_probe(struct i2c_client *client, · 2 unmodified lines | ||
| 383 | 381 | mutex_init(&data->lock); |
| 384 | 382 | |
| 385 | 383 | indio_dev->info = &vz89x_info; |
| 386 | − indio_dev->name = dev_name(&client->dev); | |
| 384 | + indio_dev->name = dev_name(dev); | |
| 387 | 385 | indio_dev->modes = INDIO_DIRECT_MODE; |
| 388 | 386 | |
| 389 | 387 | indio_dev->channels = data->chip->channels; |
| 390 | 388 | indio_dev->num_channels = data->chip->num_channels; |
| 391 | 389 | |
| 392 | − return devm_iio_device_register(&client->dev, indio_dev); | |
| 390 | + return devm_iio_device_register(dev, indio_dev); | |
| 393 | 391 | } |
| 394 | 392 | |
| 395 | 393 | static const struct i2c_device_id vz89x_id[] = { |
| @@ -402,7 +400,7 @@ MODULE_DEVICE_TABLE(i2c, vz89x_id); · 6 unmodified lines | ||
| 402 | 400 | static struct i2c_driver vz89x_driver = { |
| 403 | 401 | .driver = { |
| 404 | 402 | .name = "vz89x", |
| 405 | − .of_match_table = of_match_ptr(vz89x_dt_ids), | |
| 403 | + .of_match_table = vz89x_dt_ids, | |
| 406 | 404 | }, |
| 407 | 405 | .probe = vz89x_probe, |
| 408 | 406 | .id_table = vz89x_id, |
| @@ -97,7 +97,8 @@ static int cros_ec_lid_angle_probe(struct platform_device *pdev) · 96 unmodified lines | ||
| 97 | 97 | if (!indio_dev) |
| 98 | 98 | return -ENOMEM; |
| 99 | 99 | |
| 100 | − ret = cros_ec_sensors_core_init(pdev, indio_dev, false, NULL, NULL); | |
| 100 | + ret = cros_ec_sensors_core_init(pdev, indio_dev, false, NULL, | |
| 101 | + NULL, false); | |
| 101 | 102 | if (ret) |
| 102 | 103 | return ret; |
| 103 | 104 | |
| @@ -236,12 +236,11 @@ static int cros_ec_sensors_probe(struct platform_device *pdev) · 235 unmodified lines | ||
| 236 | 236 | |
| 237 | 237 | ret = cros_ec_sensors_core_init(pdev, indio_dev, true, |
| 238 | 238 | cros_ec_sensors_capture, |
| 239 | − cros_ec_sensors_push_data); | |
| 239 | + cros_ec_sensors_push_data, | |
| 240 | + true); | |
| 240 | 241 | if (ret) |
| 241 | 242 | return ret; |
| 242 | 243 | |
| 243 | − iio_buffer_set_attrs(indio_dev->buffer, cros_ec_sensor_fifo_attributes); | |
| 244 | − | |
| 245 | 244 | indio_dev->info = &ec_sensors_info; |
| 246 | 245 | state = iio_priv(indio_dev); |
| 247 | 246 | for (channel = state->channels, i = CROS_EC_SENSOR_X; |
| @@ -177,12 +177,11 @@ static ssize_t hwfifo_watermark_max_show(struct device *dev, · 176 unmodified lines | ||
| 177 | 177 | |
| 178 | 178 | static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0); |
| 179 | 179 | |
| 180 | −const struct attribute *cros_ec_sensor_fifo_attributes[] = { | |
| 180 | +static const struct attribute *cros_ec_sensor_fifo_attributes[] = { | |
| 181 | 181 | &iio_dev_attr_hwfifo_timeout.dev_attr.attr, |
| 182 | 182 | &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr, |
| 183 | 183 | NULL, |
| 184 | 184 | }; |
| 185 | −EXPORT_SYMBOL_GPL(cros_ec_sensor_fifo_attributes); | |
| 186 | 185 | |
| 187 | 186 | int cros_ec_sensors_push_data(struct iio_dev *indio_dev, |
| 188 | 187 | s16 *data, |
| @@ -241,6 +240,7 @@ static void cros_ec_sensors_core_clean(void *arg) · 52 unmodified lines | ||
| 241 | 240 | * for backward compatibility. |
| 242 | 241 | * @push_data: function to call when cros_ec_sensorhub receives |
| 243 | 242 | * a sample for that sensor. |
| 243 | + * @has_hw_fifo: Set true if this device has/uses a HW FIFO | |
| 244 | 244 | * |
| 245 | 245 | * Return: 0 on success, -errno on failure. |
| 246 | 246 | */ |
| @@ -248,7 +248,8 @@ int cros_ec_sensors_core_init(struct platform_device *pdev, · 1 unmodified line | ||
| 248 | 248 | struct iio_dev *indio_dev, |
| 249 | 249 | bool physical_device, |
| 250 | 250 | cros_ec_sensors_capture_t trigger_capture, |
| 251 | − cros_ec_sensorhub_push_data_cb_t push_data) | |
| 251 | + cros_ec_sensorhub_push_data_cb_t push_data, | |
| 252 | + bool has_hw_fifo) | |
| 252 | 253 | { |
| 253 | 254 | struct device *dev = &pdev->dev; |
| 254 | 255 | struct cros_ec_sensors_core_state *state = iio_priv(indio_dev); |
| @@ -361,6 +362,10 @@ int cros_ec_sensors_core_init(struct platform_device *pdev, · 106 unmodified lines | ||
| 361 | 362 | NULL); |
| 362 | 363 | if (ret) |
| 363 | 364 | return ret; |
| 365 | + | |
| 366 | + if (has_hw_fifo) | |
| 367 | + iio_buffer_set_attrs(indio_dev->buffer, | |
| 368 | + cros_ec_sensor_fifo_attributes); | |
| 364 | 369 | } |
| 365 | 370 | } |
| 366 | 371 | |
| @@ -503,7 +503,8 @@ static int ssp_probe(struct spi_device *spi) · 502 unmodified lines | ||
| 503 | 503 | return -ENODEV; |
| 504 | 504 | } |
| 505 | 505 | |
| 506 | − ret = mfd_add_devices(&spi->dev, -1, sensorhub_sensor_devs, | |
| 506 | + ret = mfd_add_devices(&spi->dev, PLATFORM_DEVID_NONE, | |
| 507 | + sensorhub_sensor_devs, | |
| 507 | 508 | ARRAY_SIZE(sensorhub_sensor_devs), NULL, 0, NULL); |
| 508 | 509 | if (ret < 0) { |
| 509 | 510 | dev_err(&spi->dev, "mfd add devices fail\n"); |
| @@ -68,8 +68,8 @@ enum ad5064_regmap_type { · 67 unmodified lines | ||
| 68 | 68 | * struct ad5064_chip_info - chip specific information |
| 69 | 69 | * @shared_vref: whether the vref supply is shared between channels |
| 70 | 70 | * @internal_vref: internal reference voltage. 0 if the chip has no |
| 71 | − internal vref. | |
| 72 | − * @channel: channel specification | |
| 71 | + * internal vref. | |
| 72 | + * @channels: channel specification | |
| 73 | 73 | * @num_channels: number of channels |
| 74 | 74 | * @regmap_type: register map layout variant |
| 75 | 75 | */ |
| @@ -98,6 +98,7 @@ typedef int (*ad5064_write_func)(struct ad5064_state *st, unsigned int cmd, · 22 unmodified lines | ||
| 98 | 98 | * @use_internal_vref: set to true if the internal reference voltage should be |
| 99 | 99 | * used. |
| 100 | 100 | * @write: register write callback |
| 101 | + * @lock: maintain consistency between cached and dev state | |
| 101 | 102 | * @data: i2c/spi transfer buffers |
| 102 | 103 | */ |
| 103 | 104 | |
| @@ -111,7 +112,6 @@ struct ad5064_state { · 7 unmodified lines | ||
| 111 | 112 | bool use_internal_vref; |
| 112 | 113 | |
| 113 | 114 | ad5064_write_func write; |
| 114 | − /* Lock used to maintain consistency between cached and dev state */ | |
| 115 | 115 | struct mutex lock; |
| 116 | 116 | |
| 117 | 117 | /* |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <linux/regulator/consumer.h> |
| 18 | 18 | #include <linux/err.h> |
| 19 | 19 | #include <linux/module.h> |
| 20 | +#include <linux/mod_devicetable.h> | |
| 20 | 21 | |
| 21 | 22 | #include <linux/iio/iio.h> |
| 22 | 23 | #include <linux/iio/sysfs.h> |
| @@ -478,13 +479,11 @@ static const struct spi_device_id ad5446_spi_ids[] = { · 455 unmodified lines | ||
| 478 | 479 | }; |
| 479 | 480 | MODULE_DEVICE_TABLE(spi, ad5446_spi_ids); |
| 480 | 481 | |
| 481 | −#ifdef CONFIG_OF | |
| 482 | 482 | static const struct of_device_id ad5446_of_ids[] = { |
| 483 | 483 | { .compatible = "ti,dac7512" }, |
| 484 | 484 | { } |
| 485 | 485 | }; |
| 486 | 486 | MODULE_DEVICE_TABLE(of, ad5446_of_ids); |
| 487 | −#endif | |
| 488 | 487 | |
| 489 | 488 | static int ad5446_spi_probe(struct spi_device *spi) |
| 490 | 489 | { |
| @@ -502,7 +501,7 @@ static int ad5446_spi_remove(struct spi_device *spi) · 11 unmodified lines | ||
| 502 | 501 | static struct spi_driver ad5446_spi_driver = { |
| 503 | 502 | .driver = { |
| 504 | 503 | .name = "ad5446", |
| 505 | − .of_match_table = of_match_ptr(ad5446_of_ids), | |
| 504 | + .of_match_table = ad5446_of_ids, | |
| 506 | 505 | }, |
| 507 | 506 | .probe = ad5446_spi_probe, |
| 508 | 507 | .remove = ad5446_spi_remove, |
| @@ -374,36 +374,36 @@ static int ad5592r_read_raw(struct iio_dev *iio_dev, · 373 unmodified lines | ||
| 374 | 374 | { |
| 375 | 375 | struct ad5592r_state *st = iio_priv(iio_dev); |
| 376 | 376 | u16 read_val; |
| 377 | − int ret; | |
| 377 | + int ret, mult; | |
| 378 | 378 | |
| 379 | 379 | switch (m) { |
| 380 | 380 | case IIO_CHAN_INFO_RAW: |
| 381 | − mutex_lock(&st->lock); | |
| 382 | − | |
| 383 | 381 | if (!chan->output) { |
| 382 | + mutex_lock(&st->lock); | |
| 384 | 383 | ret = st->ops->read_adc(st, chan->channel, &read_val); |
| 384 | + mutex_unlock(&st->lock); | |
| 385 | 385 | if (ret) |
| 386 | − goto unlock; | |
| 386 | + return ret; | |
| 387 | 387 | |
| 388 | 388 | if ((read_val >> 12 & 0x7) != (chan->channel & 0x7)) { |
| 389 | 389 | dev_err(st->dev, "Error while reading channel %u\n", |
| 390 | 390 | chan->channel); |
| 391 | − ret = -EIO; | |
| 392 | − goto unlock; | |
| 391 | + return -EIO; | |
| 393 | 392 | } |
| 394 | 393 | |
| 395 | 394 | read_val &= GENMASK(11, 0); |
| 396 | 395 | |
| 397 | 396 | } else { |
| 397 | + mutex_lock(&st->lock); | |
| 398 | 398 | read_val = st->cached_dac[chan->channel]; |
| 399 | + mutex_unlock(&st->lock); | |
| 399 | 400 | } |
| 400 | 401 | |
| 401 | 402 | dev_dbg(st->dev, "Channel %u read: 0x%04hX\n", |
| 402 | 403 | chan->channel, read_val); |
| 403 | 404 | |
| 404 | 405 | *val = (int) read_val; |
| 405 | − ret = IIO_VAL_INT; | |
| 406 | − break; | |
| 406 | + return IIO_VAL_INT; | |
| 407 | 407 | case IIO_CHAN_INFO_SCALE: |
| 408 | 408 | *val = ad5592r_get_vref(st); |
| 409 | 409 | |
| @@ -412,24 +412,24 @@ static int ad5592r_read_raw(struct iio_dev *iio_dev, · 2 unmodified lines | ||
| 412 | 412 | *val = div_s64_rem(tmp, 1000000000LL, val2); |
| 413 | 413 | |
| 414 | 414 | return IIO_VAL_INT_PLUS_MICRO; |
| 415 | − } else { | |
| 416 | − int mult; | |
| 415 | + } | |
| 417 | 416 | |
| 418 | − mutex_lock(&st->lock); | |
| 417 | + mutex_lock(&st->lock); | |
| 419 | 418 | |
| 420 | − if (chan->output) | |
| 421 | − mult = !!(st->cached_gp_ctrl & | |
| 422 | − AD5592R_REG_CTRL_DAC_RANGE); | |
| 423 | − else | |
| 424 | − mult = !!(st->cached_gp_ctrl & | |
| 425 | − AD5592R_REG_CTRL_ADC_RANGE); | |
| 419 | + if (chan->output) | |
| 420 | + mult = !!(st->cached_gp_ctrl & | |
| 421 | + AD5592R_REG_CTRL_DAC_RANGE); | |
| 422 | + else | |
| 423 | + mult = !!(st->cached_gp_ctrl & | |
| 424 | + AD5592R_REG_CTRL_ADC_RANGE); | |
| 426 | 425 | |
| 427 | − *val *= ++mult; | |
| 426 | + mutex_unlock(&st->lock); | |
| 428 | 427 | |
| 429 | − *val2 = chan->scan_type.realbits; | |
| 430 | − ret = IIO_VAL_FRACTIONAL_LOG2; | |
| 431 | − } | |
| 432 | − break; | |
| 428 | + *val *= ++mult; | |
| 429 | + | |
| 430 | + *val2 = chan->scan_type.realbits; | |
| 431 | + | |
| 432 | + return IIO_VAL_FRACTIONAL_LOG2; | |
| 433 | 433 | case IIO_CHAN_INFO_OFFSET: |
| 434 | 434 | ret = ad5592r_get_vref(st); |
| 435 | 435 | |
| @@ -439,15 +439,13 @@ static int ad5592r_read_raw(struct iio_dev *iio_dev, · 3 unmodified lines | ||
| 439 | 439 | *val = (-34365 * 25) / ret; |
| 440 | 440 | else |
| 441 | 441 | *val = (-75365 * 25) / ret; |
| 442 | − ret = IIO_VAL_INT; | |
| 443 | − break; | |
| 442 | + | |
| 443 | + mutex_unlock(&st->lock); | |
| 444 | + | |
| 445 | + return IIO_VAL_INT; | |
| 444 | 446 | default: |
| 445 | 447 | return -EINVAL; |
| 446 | 448 | } |
| 447 | − | |
| 448 | −unlock: | |
| 449 | − mutex_unlock(&st->lock); | |
| 450 | − return ret; | |
| 451 | 449 | } |
| 452 | 450 | |
| 453 | 451 | static int ad5592r_write_raw_get_fmt(struct iio_dev *indio_dev, |
| @@ -486,7 +484,7 @@ static const struct iio_chan_spec_ext_info ad5592r_ext_info[] = { · 32 unmodified lines | ||
| 486 | 484 | { |
| 487 | 485 | .name = "scale_available", |
| 488 | 486 | .read = ad5592r_show_scale_available, |
| 489 | − .shared = true, | |
| 487 | + .shared = IIO_SHARED_BY_TYPE, | |
| 490 | 488 | }, |
| 491 | 489 | {}, |
| 492 | 490 | }; |
| @@ -10,9 +10,8 @@ · 9 unmodified lines | ||
| 10 | 10 | |
| 11 | 11 | #include <linux/bitops.h> |
| 12 | 12 | #include <linux/module.h> |
| 13 | −#include <linux/of.h> | |
| 13 | +#include <linux/mod_devicetable.h> | |
| 14 | 14 | #include <linux/spi/spi.h> |
| 15 | −#include <linux/acpi.h> | |
| 16 | 15 | |
| 17 | 16 | #define AD5592R_GPIO_READBACK_EN BIT(10) |
| 18 | 17 | #define AD5592R_LDAC_READBACK_EN BIT(6) |
| @@ -157,8 +156,8 @@ MODULE_DEVICE_TABLE(acpi, ad5592r_acpi_match); · 138 unmodified lines | ||
| 157 | 156 | static struct spi_driver ad5592r_spi_driver = { |
| 158 | 157 | .driver = { |
| 159 | 158 | .name = "ad5592r", |
| 160 | − .of_match_table = of_match_ptr(ad5592r_of_match), | |
| 161 | − .acpi_match_table = ACPI_PTR(ad5592r_acpi_match), | |
| 159 | + .of_match_table = ad5592r_of_match, | |
| 160 | + .acpi_match_table = ad5592r_acpi_match, | |
| 162 | 161 | }, |
| 163 | 162 | .probe = ad5592r_spi_probe, |
| 164 | 163 | .remove = ad5592r_spi_remove, |
| @@ -11,8 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/bitops.h> |
| 12 | 12 | #include <linux/i2c.h> |
| 13 | 13 | #include <linux/module.h> |
| 14 | −#include <linux/of.h> | |
| 15 | −#include <linux/acpi.h> | |
| 14 | +#include <linux/mod_devicetable.h> | |
| 16 | 15 | |
| 17 | 16 | #define AD5593R_MODE_CONF (0 << 4) |
| 18 | 17 | #define AD5593R_MODE_DAC_WRITE (1 << 4) |
| @@ -124,8 +123,8 @@ MODULE_DEVICE_TABLE(acpi, ad5593r_acpi_match); · 105 unmodified lines | ||
| 124 | 123 | static struct i2c_driver ad5593r_driver = { |
| 125 | 124 | .driver = { |
| 126 | 125 | .name = "ad5593r", |
| 127 | − .of_match_table = of_match_ptr(ad5593r_of_match), | |
| 128 | − .acpi_match_table = ACPI_PTR(ad5593r_acpi_match), | |
| 126 | + .of_match_table = ad5593r_of_match, | |
| 127 | + .acpi_match_table = ad5593r_acpi_match, | |
| 129 | 128 | }, |
| 130 | 129 | .probe = ad5593r_i2c_probe, |
| 131 | 130 | .remove = ad5593r_i2c_remove, |
| @@ -206,12 +206,12 @@ static const struct iio_chan_spec_ext_info ad5686_ext_info[] = { · 205 unmodified lines | ||
| 206 | 206 | } |
| 207 | 207 | |
| 208 | 208 | #define DECLARE_AD5693_CHANNELS(name, bits, _shift) \ |
| 209 | −static struct iio_chan_spec name[] = { \ | |
| 209 | +static const struct iio_chan_spec name[] = { \ | |
| 210 | 210 | AD5868_CHANNEL(0, 0, bits, _shift), \ |
| 211 | 211 | } |
| 212 | 212 | |
| 213 | 213 | #define DECLARE_AD5686_CHANNELS(name, bits, _shift) \ |
| 214 | −static struct iio_chan_spec name[] = { \ | |
| 214 | +static const struct iio_chan_spec name[] = { \ | |
| 215 | 215 | AD5868_CHANNEL(0, 1, bits, _shift), \ |
| 216 | 216 | AD5868_CHANNEL(1, 2, bits, _shift), \ |
| 217 | 217 | AD5868_CHANNEL(2, 4, bits, _shift), \ |
| @@ -219,7 +219,7 @@ static struct iio_chan_spec name[] = { \ · 1 unmodified line | ||
| 219 | 219 | } |
| 220 | 220 | |
| 221 | 221 | #define DECLARE_AD5676_CHANNELS(name, bits, _shift) \ |
| 222 | −static struct iio_chan_spec name[] = { \ | |
| 222 | +static const struct iio_chan_spec name[] = { \ | |
| 223 | 223 | AD5868_CHANNEL(0, 0, bits, _shift), \ |
| 224 | 224 | AD5868_CHANNEL(1, 1, bits, _shift), \ |
| 225 | 225 | AD5868_CHANNEL(2, 2, bits, _shift), \ |
| @@ -231,7 +231,7 @@ static struct iio_chan_spec name[] = { \ · 5 unmodified lines | ||
| 231 | 231 | } |
| 232 | 232 | |
| 233 | 233 | #define DECLARE_AD5679_CHANNELS(name, bits, _shift) \ |
| 234 | −static struct iio_chan_spec name[] = { \ | |
| 234 | +static const struct iio_chan_spec name[] = { \ | |
| 235 | 235 | AD5868_CHANNEL(0, 0, bits, _shift), \ |
| 236 | 236 | AD5868_CHANNEL(1, 1, bits, _shift), \ |
| 237 | 237 | AD5868_CHANNEL(2, 2, bits, _shift), \ |
| @@ -104,7 +104,7 @@ typedef int (*ad5686_read_func)(struct ad5686_state *st, u8 addr); · 103 unmodified lines | ||
| 104 | 104 | struct ad5686_chip_info { |
| 105 | 105 | u16 int_vref_mv; |
| 106 | 106 | unsigned int num_channels; |
| 107 | − struct iio_chan_spec *channels; | |
| 107 | + const struct iio_chan_spec *channels; | |
| 108 | 108 | enum ad5686_regmap_type regmap_type; |
| 109 | 109 | }; |
| 110 | 110 | |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | |
| 8 | 8 | #include <linux/err.h> |
| 9 | 9 | #include <linux/module.h> |
| 10 | +#include <linux/mod_devicetable.h> | |
| 10 | 11 | #include <linux/kernel.h> |
| 11 | 12 | #include <linux/spi/spi.h> |
| 12 | 13 | #include <linux/slab.h> |
| @@ -29,6 +30,9 @@ · 16 unmodified lines | ||
| 29 | 30 | * @spi: the device for this driver instance |
| 30 | 31 | * @config: cached config register value |
| 31 | 32 | * @dac_cache: current DAC raw value (chip does not support readback) |
| 33 | + * @vdd_reg: reference to VDD regulator | |
| 34 | + * @vref_reg: reference to VREF regulator | |
| 35 | + * @lock: protect writes and cache updates | |
| 32 | 36 | * @data: spi transfer buffer |
| 33 | 37 | */ |
| 34 | 38 | |
| @@ -287,7 +291,7 @@ MODULE_DEVICE_TABLE(spi, ad7303_spi_ids); · 252 unmodified lines | ||
| 287 | 291 | static struct spi_driver ad7303_driver = { |
| 288 | 292 | .driver = { |
| 289 | 293 | .name = "ad7303", |
| 290 | − .of_match_table = of_match_ptr(ad7303_spi_of_match), | |
| 294 | + .of_match_table = ad7303_spi_of_match, | |
| 291 | 295 | }, |
| 292 | 296 | .probe = ad7303_probe, |
| 293 | 297 | .remove = ad7303_remove, |
| @@ -184,18 +184,14 @@ static int dpot_dac_probe(struct platform_device *pdev) · 183 unmodified lines | ||
| 184 | 184 | indio_dev->num_channels = 1; |
| 185 | 185 | |
| 186 | 186 | dac->vref = devm_regulator_get(dev, "vref"); |
| 187 | − if (IS_ERR(dac->vref)) { | |
| 188 | − if (PTR_ERR(dac->vref) != -EPROBE_DEFER) | |
| 189 | − dev_err(&pdev->dev, "failed to get vref regulator\n"); | |
| 190 | − return PTR_ERR(dac->vref); | |
| 191 | − } | |
| 187 | + if (IS_ERR(dac->vref)) | |
| 188 | + return dev_err_probe(&pdev->dev, PTR_ERR(dac->vref), | |
| 189 | + "failed to get vref regulator\n"); | |
| 192 | 190 | |
| 193 | 191 | dac->dpot = devm_iio_channel_get(dev, "dpot"); |
| 194 | − if (IS_ERR(dac->dpot)) { | |
| 195 | − if (PTR_ERR(dac->dpot) != -EPROBE_DEFER) | |
| 196 | − dev_err(dev, "failed to get dpot input channel\n"); | |
| 197 | − return PTR_ERR(dac->dpot); | |
| 198 | − } | |
| 192 | + if (IS_ERR(dac->dpot)) | |
| 193 | + return dev_err_probe(&pdev->dev, PTR_ERR(dac->dpot), | |
| 194 | + "failed to get dpot input channel\n"); | |
| 199 | 195 | |
| 200 | 196 | ret = iio_get_channel_type(dac->dpot, &type); |
| 201 | 197 | if (ret < 0) |
| @@ -16,8 +16,8 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <linux/err.h> |
| 17 | 17 | #include <linux/delay.h> |
| 18 | 18 | #include <linux/regulator/consumer.h> |
| 19 | −#include <linux/of_device.h> | |
| 20 | −#include <linux/of.h> | |
| 19 | +#include <linux/mod_devicetable.h> | |
| 20 | +#include <linux/property.h> | |
| 21 | 21 | |
| 22 | 22 | #include <linux/iio/iio.h> |
| 23 | 23 | #include <linux/iio/sysfs.h> |
| @@ -357,29 +357,16 @@ static const struct iio_info mcp4725_info = { · 333 unmodified lines | ||
| 357 | 357 | .attrs = &mcp4725_attribute_group, |
| 358 | 358 | }; |
| 359 | 359 | |
| 360 | −#ifdef CONFIG_OF | |
| 361 | 360 | static int mcp4725_probe_dt(struct device *dev, |
| 362 | 361 | struct mcp4725_platform_data *pdata) |
| 363 | 362 | { |
| 364 | − struct device_node *np = dev->of_node; | |
| 365 | − | |
| 366 | − if (!np) | |
| 367 | − return -ENODEV; | |
| 368 | − | |
| 369 | 363 | /* check if is the vref-supply defined */ |
| 370 | − pdata->use_vref = of_property_read_bool(np, "vref-supply"); | |
| 364 | + pdata->use_vref = device_property_read_bool(dev, "vref-supply"); | |
| 371 | 365 | pdata->vref_buffered = |
| 372 | − of_property_read_bool(np, "microchip,vref-buffered"); | |
| 366 | + device_property_read_bool(dev, "microchip,vref-buffered"); | |
| 373 | 367 | |
| 374 | 368 | return 0; |
| 375 | 369 | } |
| 376 | −#else | |
| 377 | −static int mcp4725_probe_dt(struct device *dev, | |
| 378 | − struct mcp4725_platform_data *platform_data) | |
| 379 | −{ | |
| 380 | − return -ENODEV; | |
| 381 | −} | |
| 382 | −#endif | |
| 383 | 370 | |
| 384 | 371 | static int mcp4725_probe(struct i2c_client *client, |
| 385 | 372 | const struct i2c_device_id *id) |
| @@ -398,8 +385,8 @@ static int mcp4725_probe(struct i2c_client *client, · 12 unmodified lines | ||
| 398 | 385 | data = iio_priv(indio_dev); |
| 399 | 386 | i2c_set_clientdata(client, indio_dev); |
| 400 | 387 | data->client = client; |
| 401 | − if (client->dev.of_node) | |
| 402 | − data->id = (enum chip_id)of_device_get_match_data(&client->dev); | |
| 388 | + if (dev_fwnode(&client->dev)) | |
| 389 | + data->id = (enum chip_id)device_get_match_data(&client->dev); | |
| 403 | 390 | else |
| 404 | 391 | data->id = id->driver_data; |
| 405 | 392 | pdata = dev_get_platdata(&client->dev); |
| @@ -519,7 +506,6 @@ static const struct i2c_device_id mcp4725_id[] = { · 113 unmodified lines | ||
| 519 | 506 | }; |
| 520 | 507 | MODULE_DEVICE_TABLE(i2c, mcp4725_id); |
| 521 | 508 | |
| 522 | −#ifdef CONFIG_OF | |
| 523 | 509 | static const struct of_device_id mcp4725_of_match[] = { |
| 524 | 510 | { |
| 525 | 511 | .compatible = "microchip,mcp4725", |
| @@ -532,12 +518,11 @@ static const struct of_device_id mcp4725_of_match[] = { · 6 unmodified lines | ||
| 532 | 518 | { } |
| 533 | 519 | }; |
| 534 | 520 | MODULE_DEVICE_TABLE(of, mcp4725_of_match); |
| 535 | −#endif | |
| 536 | 521 | |
| 537 | 522 | static struct i2c_driver mcp4725_driver = { |
| 538 | 523 | .driver = { |
| 539 | 524 | .name = MCP4725_DRV_NAME, |
| 540 | − .of_match_table = of_match_ptr(mcp4725_of_match), | |
| 525 | + .of_match_table = mcp4725_of_match, | |
| 541 | 526 | .pm = &mcp4725_pm_ops, |
| 542 | 527 | }, |
| 543 | 528 | .probe = mcp4725_probe, |
| @@ -150,10 +150,7 @@ static int stm32_dac_probe(struct platform_device *pdev) · 149 unmodified lines | ||
| 150 | 150 | rst = devm_reset_control_get_optional_exclusive(dev, NULL); |
| 151 | 151 | if (rst) { |
| 152 | 152 | if (IS_ERR(rst)) { |
| 153 | − ret = PTR_ERR(rst); | |
| 154 | − if (ret != -EPROBE_DEFER) | |
| 155 | − dev_err(dev, "reset get failed, %d\n", ret); | |
| 156 | − | |
| 153 | + ret = dev_err_probe(dev, PTR_ERR(rst), "reset get failed\n"); | |
| 157 | 154 | goto err_hw_stop; |
| 158 | 155 | } |
| 159 | 156 | |
| @@ -26,9 +26,12 @@ · 25 unmodified lines | ||
| 26 | 26 | /** |
| 27 | 27 | * struct stm32_dac - private data of DAC driver |
| 28 | 28 | * @common: reference to DAC common data |
| 29 | + * @lock: lock to protect against potential races when reading | |
| 30 | + * and update CR, to keep it in sync with pm_runtime | |
| 29 | 31 | */ |
| 30 | 32 | struct stm32_dac { |
| 31 | 33 | struct stm32_dac_common *common; |
| 34 | + struct mutex lock; | |
| 32 | 35 | }; |
| 33 | 36 | |
| 34 | 37 | static int stm32_dac_is_enabled(struct iio_dev *indio_dev, int channel) |
| @@ -58,10 +61,10 @@ static int stm32_dac_set_enable_state(struct iio_dev *indio_dev, int ch, · 23 unmodified lines | ||
| 58 | 61 | int ret; |
| 59 | 62 | |
| 60 | 63 | /* already enabled / disabled ? */ |
| 61 | − mutex_lock(&indio_dev->mlock); | |
| 64 | + mutex_lock(&dac->lock); | |
| 62 | 65 | ret = stm32_dac_is_enabled(indio_dev, ch); |
| 63 | 66 | if (ret < 0 || enable == !!ret) { |
| 64 | − mutex_unlock(&indio_dev->mlock); | |
| 67 | + mutex_unlock(&dac->lock); | |
| 65 | 68 | return ret < 0 ? ret : 0; |
| 66 | 69 | } |
| 67 | 70 | |
| @@ -69,13 +72,13 @@ static int stm32_dac_set_enable_state(struct iio_dev *indio_dev, int ch, · 1 unmodified line | ||
| 69 | 72 | ret = pm_runtime_get_sync(dev); |
| 70 | 73 | if (ret < 0) { |
| 71 | 74 | pm_runtime_put_noidle(dev); |
| 72 | − mutex_unlock(&indio_dev->mlock); | |
| 75 | + mutex_unlock(&dac->lock); | |
| 73 | 76 | return ret; |
| 74 | 77 | } |
| 75 | 78 | } |
| 76 | 79 | |
| 77 | 80 | ret = regmap_update_bits(dac->common->regmap, STM32_DAC_CR, msk, en); |
| 78 | − mutex_unlock(&indio_dev->mlock); | |
| 81 | + mutex_unlock(&dac->lock); | |
| 79 | 82 | if (ret < 0) { |
| 80 | 83 | dev_err(&indio_dev->dev, "%s failed\n", en ? |
| 81 | 84 | "Enable" : "Disable"); |
| @@ -327,6 +330,8 @@ static int stm32_dac_probe(struct platform_device *pdev) · 245 unmodified lines | ||
| 327 | 330 | indio_dev->info = &stm32_dac_iio_info; |
| 328 | 331 | indio_dev->modes = INDIO_DIRECT_MODE; |
| 329 | 332 | |
| 333 | + mutex_init(&dac->lock); | |
| 334 | + | |
| 330 | 335 | ret = stm32_dac_chan_of_init(indio_dev); |
| 331 | 336 | if (ret < 0) |
| 332 | 337 | return ret; |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | |
| 15 | 15 | #include <linux/iio/iio.h> |
| 16 | 16 | #include <linux/module.h> |
| 17 | +#include <linux/mod_devicetable.h> | |
| 17 | 18 | #include <linux/regulator/consumer.h> |
| 18 | 19 | #include <linux/spi/spi.h> |
| 19 | 20 | |
| @@ -324,7 +325,6 @@ static int ti_dac_remove(struct spi_device *spi) · 304 unmodified lines | ||
| 324 | 325 | return 0; |
| 325 | 326 | } |
| 326 | 327 | |
| 327 | −#ifdef CONFIG_OF | |
| 328 | 328 | static const struct of_device_id ti_dac_of_id[] = { |
| 329 | 329 | { .compatible = "ti,dac082s085" }, |
| 330 | 330 | { .compatible = "ti,dac102s085" }, |
| @@ -335,7 +335,6 @@ static const struct of_device_id ti_dac_of_id[] = { · 4 unmodified lines | ||
| 335 | 335 | { } |
| 336 | 336 | }; |
| 337 | 337 | MODULE_DEVICE_TABLE(of, ti_dac_of_id); |
| 338 | −#endif | |
| 339 | 338 | |
| 340 | 339 | static const struct spi_device_id ti_dac_spi_id[] = { |
| 341 | 340 | { "dac082s085", dual_8bit }, |
| @@ -351,7 +350,7 @@ MODULE_DEVICE_TABLE(spi, ti_dac_spi_id); · 9 unmodified lines | ||
| 351 | 350 | static struct spi_driver ti_dac_driver = { |
| 352 | 351 | .driver = { |
| 353 | 352 | .name = "ti-dac082s085", |
| 354 | − .of_match_table = of_match_ptr(ti_dac_of_id), | |
| 353 | + .of_match_table = ti_dac_of_id, | |
| 355 | 354 | }, |
| 356 | 355 | .probe = ti_dac_probe, |
| 357 | 356 | .remove = ti_dac_remove, |
| @@ -18,8 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <linux/iio/iio.h> |
| 19 | 19 | #include <linux/i2c.h> |
| 20 | 20 | #include <linux/module.h> |
| 21 | −#include <linux/of_device.h> | |
| 22 | −#include <linux/of.h> | |
| 21 | +#include <linux/mod_devicetable.h> | |
| 23 | 22 | #include <linux/regulator/consumer.h> |
| 24 | 23 | |
| 25 | 24 | enum chip_id { |
| @@ -47,8 +46,8 @@ struct dac5571_data { · 21 unmodified lines | ||
| 47 | 46 | struct mutex lock; |
| 48 | 47 | struct regulator *vref; |
| 49 | 48 | u16 val[4]; |
| 50 | − bool powerdown; | |
| 51 | − u8 powerdown_mode; | |
| 49 | + bool powerdown[4]; | |
| 50 | + u8 powerdown_mode[4]; | |
| 52 | 51 | struct dac5571_spec const *spec; |
| 53 | 52 | int (*dac5571_cmd)(struct dac5571_data *data, int channel, u16 val); |
| 54 | 53 | int (*dac5571_pwrdwn)(struct dac5571_data *data, int channel, u8 pwrdwn); |
| @@ -125,7 +124,7 @@ static int dac5571_get_powerdown_mode(struct iio_dev *indio_dev, · 70 unmodified lines | ||
| 125 | 124 | { |
| 126 | 125 | struct dac5571_data *data = iio_priv(indio_dev); |
| 127 | 126 | |
| 128 | − return data->powerdown_mode; | |
| 127 | + return data->powerdown_mode[chan->channel]; | |
| 129 | 128 | } |
| 130 | 129 | |
| 131 | 130 | static int dac5571_set_powerdown_mode(struct iio_dev *indio_dev, |
| @@ -135,17 +134,17 @@ static int dac5571_set_powerdown_mode(struct iio_dev *indio_dev, · 3 unmodified lines | ||
| 135 | 134 | struct dac5571_data *data = iio_priv(indio_dev); |
| 136 | 135 | int ret = 0; |
| 137 | 136 | |
| 138 | − if (data->powerdown_mode == mode) | |
| 137 | + if (data->powerdown_mode[chan->channel] == mode) | |
| 139 | 138 | return 0; |
| 140 | 139 | |
| 141 | 140 | mutex_lock(&data->lock); |
| 142 | − if (data->powerdown) { | |
| 141 | + if (data->powerdown[chan->channel]) { | |
| 143 | 142 | ret = data->dac5571_pwrdwn(data, chan->channel, |
| 144 | 143 | DAC5571_POWERDOWN(mode)); |
| 145 | 144 | if (ret) |
| 146 | 145 | goto out; |
| 147 | 146 | } |
| 148 | − data->powerdown_mode = mode; | |
| 147 | + data->powerdown_mode[chan->channel] = mode; | |
| 149 | 148 | |
| 150 | 149 | out: |
| 151 | 150 | mutex_unlock(&data->lock); |
| @@ -167,7 +166,7 @@ static ssize_t dac5571_read_powerdown(struct iio_dev *indio_dev, · 15 unmodified lines | ||
| 167 | 166 | { |
| 168 | 167 | struct dac5571_data *data = iio_priv(indio_dev); |
| 169 | 168 | |
| 170 | − return sprintf(buf, "%d\n", data->powerdown); | |
| 169 | + return sprintf(buf, "%d\n", data->powerdown[chan->channel]); | |
| 171 | 170 | } |
| 172 | 171 | |
| 173 | 172 | static ssize_t dac5571_write_powerdown(struct iio_dev *indio_dev, |
| @@ -183,19 +182,20 @@ static ssize_t dac5571_write_powerdown(struct iio_dev *indio_dev, · 9 unmodified lines | ||
| 183 | 182 | if (ret) |
| 184 | 183 | return ret; |
| 185 | 184 | |
| 186 | − if (data->powerdown == powerdown) | |
| 185 | + if (data->powerdown[chan->channel] == powerdown) | |
| 187 | 186 | return len; |
| 188 | 187 | |
| 189 | 188 | mutex_lock(&data->lock); |
| 190 | 189 | if (powerdown) |
| 191 | 190 | ret = data->dac5571_pwrdwn(data, chan->channel, |
| 192 | − DAC5571_POWERDOWN(data->powerdown_mode)); | |
| 191 | + DAC5571_POWERDOWN(data->powerdown_mode[chan->channel])); | |
| 193 | 192 | else |
| 194 | − ret = data->dac5571_cmd(data, chan->channel, data->val[0]); | |
| 193 | + ret = data->dac5571_cmd(data, chan->channel, | |
| 194 | + data->val[chan->channel]); | |
| 195 | 195 | if (ret) |
| 196 | 196 | goto out; |
| 197 | 197 | |
| 198 | − data->powerdown = powerdown; | |
| 198 | + data->powerdown[chan->channel] = powerdown; | |
| 199 | 199 | |
| 200 | 200 | out: |
| 201 | 201 | mutex_unlock(&data->lock); |
| @@ -209,9 +209,9 @@ static const struct iio_chan_spec_ext_info dac5571_ext_info[] = { · 7 unmodified lines | ||
| 209 | 209 | .name = "powerdown", |
| 210 | 210 | .read = dac5571_read_powerdown, |
| 211 | 211 | .write = dac5571_write_powerdown, |
| 212 | − .shared = IIO_SHARED_BY_TYPE, | |
| 212 | + .shared = IIO_SEPARATE, | |
| 213 | 213 | }, |
| 214 | − IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE, &dac5571_powerdown_mode), | |
| 214 | + IIO_ENUM("powerdown_mode", IIO_SEPARATE, &dac5571_powerdown_mode), | |
| 215 | 215 | IIO_ENUM_AVAILABLE("powerdown_mode", &dac5571_powerdown_mode), |
| 216 | 216 | {}, |
| 217 | 217 | }; |
| @@ -276,7 +276,7 @@ static int dac5571_write_raw(struct iio_dev *indio_dev, · 58 unmodified lines | ||
| 276 | 276 | if (val >= (1 << data->spec->resolution) || val < 0) |
| 277 | 277 | return -EINVAL; |
| 278 | 278 | |
| 279 | − if (data->powerdown) | |
| 279 | + if (data->powerdown[chan->channel]) | |
| 280 | 280 | return -EBUSY; |
| 281 | 281 | |
| 282 | 282 | mutex_lock(&data->lock); |
| @@ -383,7 +383,6 @@ static int dac5571_remove(struct i2c_client *i2c) · 100 unmodified lines | ||
| 383 | 383 | return 0; |
| 384 | 384 | } |
| 385 | 385 | |
| 386 | −#ifdef CONFIG_OF | |
| 387 | 386 | static const struct of_device_id dac5571_of_id[] = { |
| 388 | 387 | {.compatible = "ti,dac5571"}, |
| 389 | 388 | {.compatible = "ti,dac6571"}, |
| @@ -397,7 +396,6 @@ static const struct of_device_id dac5571_of_id[] = { · 7 unmodified lines | ||
| 397 | 396 | {} |
| 398 | 397 | }; |
| 399 | 398 | MODULE_DEVICE_TABLE(of, dac5571_of_id); |
| 400 | −#endif | |
| 401 | 399 | |
| 402 | 400 | static const struct i2c_device_id dac5571_id[] = { |
| 403 | 401 | {"dac5571", single_8bit}, |
| @@ -416,7 +414,7 @@ MODULE_DEVICE_TABLE(i2c, dac5571_id); · 12 unmodified lines | ||
| 416 | 414 | static struct i2c_driver dac5571_driver = { |
| 417 | 415 | .driver = { |
| 418 | 416 | .name = "ti-dac5571", |
| 419 | − .of_match_table = of_match_ptr(dac5571_of_id), | |
| 417 | + .of_match_table = dac5571_of_id, | |
| 420 | 418 | }, |
| 421 | 419 | .probe = dac5571_probe, |
| 422 | 420 | .remove = dac5571_remove, |
| @@ -22,6 +22,14 @@ struct dac7612 { · 21 unmodified lines | ||
| 22 | 22 | struct gpio_desc *loaddacs; |
| 23 | 23 | uint16_t cache[2]; |
| 24 | 24 | |
| 25 | + /* | |
| 26 | + * Lock to protect the state of the device from potential concurrent | |
| 27 | + * write accesses from userspace. The write operation requires an | |
| 28 | + * SPI write, then toggling of a GPIO, so the lock aims to protect | |
| 29 | + * the sanity of the entire sequence of operation. | |
| 30 | + */ | |
| 31 | + struct mutex lock; | |
| 32 | + | |
| 25 | 33 | /* |
| 26 | 34 | * DMA (thus cache coherency maintenance) requires the |
| 27 | 35 | * transfer buffers to live in their own cache lines. |
| @@ -101,9 +109,9 @@ static int dac7612_write_raw(struct iio_dev *iio_dev, · 73 unmodified lines | ||
| 101 | 109 | if (val == priv->cache[chan->channel]) |
| 102 | 110 | return 0; |
| 103 | 111 | |
| 104 | − mutex_lock(&iio_dev->mlock); | |
| 112 | + mutex_lock(&priv->lock); | |
| 105 | 113 | ret = dac7612_cmd_single(priv, chan->channel, val); |
| 106 | − mutex_unlock(&iio_dev->mlock); | |
| 114 | + mutex_unlock(&priv->lock); | |
| 107 | 115 | |
| 108 | 116 | return ret; |
| 109 | 117 | } |
| @@ -145,6 +153,8 @@ static int dac7612_probe(struct spi_device *spi) · 35 unmodified lines | ||
| 145 | 153 | iio_dev->num_channels = ARRAY_SIZE(priv->cache); |
| 146 | 154 | iio_dev->name = spi_get_device_id(spi)->name; |
| 147 | 155 | |
| 156 | + mutex_init(&priv->lock); | |
| 157 | + | |
| 148 | 158 | for (i = 0; i < ARRAY_SIZE(priv->cache); i++) { |
| 149 | 159 | ret = dac7612_cmd_single(priv, i, 0); |
| 150 | 160 | if (ret) |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | −/** | |
| 2 | +/* | |
| 3 | 3 | * Copyright (c) 2011 Jonathan Cameron |
| 4 | 4 | * |
| 5 | 5 | * Companion module to the iio simple dummy example driver. |
| @@ -27,11 +27,13 @@ · 21 unmodified lines | ||
| 27 | 27 | #define IIO_EVENTGEN_NO 10 |
| 28 | 28 | |
| 29 | 29 | /** |
| 30 | + * struct iio_dummy_eventgen - event generator specific state | |
| 30 | 31 | * @regs: irq regs we are faking |
| 31 | 32 | * @lock: protect the evgen state |
| 32 | 33 | * @inuse: mask of which irqs are connected |
| 33 | 34 | * @irq_sim: interrupt simulator |
| 34 | 35 | * @base: base of irq range |
| 36 | + * @irq_sim_domain: irq simulator domain | |
| 35 | 37 | */ |
| 36 | 38 | struct iio_dummy_eventgen { |
| 37 | 39 | struct iio_dummy_regs regs[IIO_EVENTGEN_NO]; |
| @@ -969,6 +969,13 @@ static int ad9523_setup(struct iio_dev *indio_dev) · 968 unmodified lines | ||
| 969 | 969 | return 0; |
| 970 | 970 | } |
| 971 | 971 | |
| 972 | +static void ad9523_reg_disable(void *data) | |
| 973 | +{ | |
| 974 | + struct regulator *reg = data; | |
| 975 | + | |
| 976 | + regulator_disable(reg); | |
| 977 | +} | |
| 978 | + | |
| 972 | 979 | static int ad9523_probe(struct spi_device *spi) |
| 973 | 980 | { |
| 974 | 981 | struct ad9523_platform_data *pdata = spi->dev.platform_data; |
| @@ -994,21 +1001,22 @@ static int ad9523_probe(struct spi_device *spi) · 19 unmodified lines | ||
| 994 | 1001 | ret = regulator_enable(st->reg); |
| 995 | 1002 | if (ret) |
| 996 | 1003 | return ret; |
| 1004 | + | |
| 1005 | + ret = devm_add_action_or_reset(&spi->dev, ad9523_reg_disable, | |
| 1006 | + st->reg); | |
| 1007 | + if (ret) | |
| 1008 | + return ret; | |
| 997 | 1009 | } |
| 998 | 1010 | |
| 999 | 1011 | st->pwrdown_gpio = devm_gpiod_get_optional(&spi->dev, "powerdown", |
| 1000 | 1012 | GPIOD_OUT_HIGH); |
| 1001 | − if (IS_ERR(st->pwrdown_gpio)) { | |
| 1002 | − ret = PTR_ERR(st->pwrdown_gpio); | |
| 1003 | − goto error_disable_reg; | |
| 1004 | − } | |
| 1013 | + if (IS_ERR(st->pwrdown_gpio)) | |
| 1014 | + return PTR_ERR(st->pwrdown_gpio); | |
| 1005 | 1015 | |
| 1006 | 1016 | st->reset_gpio = devm_gpiod_get_optional(&spi->dev, "reset", |
| 1007 | 1017 | GPIOD_OUT_LOW); |
| 1008 | − if (IS_ERR(st->reset_gpio)) { | |
| 1009 | − ret = PTR_ERR(st->reset_gpio); | |
| 1010 | − goto error_disable_reg; | |
| 1011 | − } | |
| 1018 | + if (IS_ERR(st->reset_gpio)) | |
| 1019 | + return PTR_ERR(st->reset_gpio); | |
| 1012 | 1020 | |
| 1013 | 1021 | if (st->reset_gpio) { |
| 1014 | 1022 | udelay(1); |
| @@ -1017,10 +1025,8 @@ static int ad9523_probe(struct spi_device *spi) · 2 unmodified lines | ||
| 1017 | 1025 | |
| 1018 | 1026 | st->sync_gpio = devm_gpiod_get_optional(&spi->dev, "sync", |
| 1019 | 1027 | GPIOD_OUT_HIGH); |
| 1020 | − if (IS_ERR(st->sync_gpio)) { | |
| 1021 | − ret = PTR_ERR(st->sync_gpio); | |
| 1022 | − goto error_disable_reg; | |
| 1023 | − } | |
| 1028 | + if (IS_ERR(st->sync_gpio)) | |
| 1029 | + return PTR_ERR(st->sync_gpio); | |
| 1024 | 1030 | |
| 1025 | 1031 | spi_set_drvdata(spi, indio_dev); |
| 1026 | 1032 | st->spi = spi; |
| @@ -1035,34 +1041,9 @@ static int ad9523_probe(struct spi_device *spi) · 8 unmodified lines | ||
| 1035 | 1041 | |
| 1036 | 1042 | ret = ad9523_setup(indio_dev); |
| 1037 | 1043 | if (ret < 0) |
| 1038 | − goto error_disable_reg; | |
| 1039 | − | |
| 1040 | − ret = iio_device_register(indio_dev); | |
| 1041 | − if (ret) | |
| 1042 | − goto error_disable_reg; | |
| 1043 | − | |
| 1044 | − dev_info(&spi->dev, "probed %s\n", indio_dev->name); | |
| 1045 | − | |
| 1046 | − return 0; | |
| 1047 | − | |
| 1048 | −error_disable_reg: | |
| 1049 | − if (!IS_ERR(st->reg)) | |
| 1050 | − regulator_disable(st->reg); | |
| 1051 | − | |
| 1052 | − return ret; | |
| 1053 | −} | |
| 1054 | − | |
| 1055 | −static int ad9523_remove(struct spi_device *spi) | |
| 1056 | −{ | |
| 1057 | − struct iio_dev *indio_dev = spi_get_drvdata(spi); | |
| 1058 | − struct ad9523_state *st = iio_priv(indio_dev); | |
| 1059 | − | |
| 1060 | − iio_device_unregister(indio_dev); | |
| 1061 | − | |
| 1062 | − if (!IS_ERR(st->reg)) | |
| 1063 | − regulator_disable(st->reg); | |
| 1044 | + return ret; | |
| 1064 | 1045 | |
| 1065 | − return 0; | |
| 1046 | + return devm_iio_device_register(&spi->dev, indio_dev); | |
| 1066 | 1047 | } |
| 1067 | 1048 | |
| 1068 | 1049 | static const struct spi_device_id ad9523_id[] = { |
| @@ -1076,7 +1057,6 @@ static struct spi_driver ad9523_driver = { · 7 unmodified lines | ||
| 1076 | 1057 | .name = "ad9523", |
| 1077 | 1058 | }, |
| 1078 | 1059 | .probe = ad9523_probe, |
| 1079 | − .remove = ad9523_remove, | |
| 1080 | 1060 | .id_table = ad9523_id, |
| 1081 | 1061 | }; |
| 1082 | 1062 | module_spi_driver(ad9523_driver); |
| @@ -47,6 +47,13 @@ struct adf4350_state { · 46 unmodified lines | ||
| 47 | 47 | unsigned long regs[6]; |
| 48 | 48 | unsigned long regs_hw[6]; |
| 49 | 49 | unsigned long long freq_req; |
| 50 | + /* | |
| 51 | + * Lock to protect the state of the device from potential concurrent | |
| 52 | + * writes. The device is configured via a sequence of SPI writes, | |
| 53 | + * and this lock is meant to prevent the start of another sequence | |
| 54 | + * before another one has finished. | |
| 55 | + */ | |
| 56 | + struct mutex lock; | |
| 50 | 57 | /* |
| 51 | 58 | * DMA (thus cache coherency maintenance) requires the |
| 52 | 59 | * transfer buffers to live in their own cache lines. |
| @@ -99,7 +106,7 @@ static int adf4350_reg_access(struct iio_dev *indio_dev, · 46 unmodified lines | ||
| 99 | 106 | if (reg > ADF4350_REG5) |
| 100 | 107 | return -EINVAL; |
| 101 | 108 | |
| 102 | − mutex_lock(&indio_dev->mlock); | |
| 109 | + mutex_lock(&st->lock); | |
| 103 | 110 | if (readval == NULL) { |
| 104 | 111 | st->regs[reg] = writeval & ~(BIT(0) | BIT(1) | BIT(2)); |
| 105 | 112 | ret = adf4350_sync_config(st); |
| @@ -107,7 +114,7 @@ static int adf4350_reg_access(struct iio_dev *indio_dev, · 1 unmodified line | ||
| 107 | 114 | *readval = st->regs_hw[reg]; |
| 108 | 115 | ret = 0; |
| 109 | 116 | } |
| 110 | − mutex_unlock(&indio_dev->mlock); | |
| 117 | + mutex_unlock(&st->lock); | |
| 111 | 118 | |
| 112 | 119 | return ret; |
| 113 | 120 | } |
| @@ -254,7 +261,7 @@ static ssize_t adf4350_write(struct iio_dev *indio_dev, · 140 unmodified lines | ||
| 254 | 261 | if (ret) |
| 255 | 262 | return ret; |
| 256 | 263 | |
| 257 | − mutex_lock(&indio_dev->mlock); | |
| 264 | + mutex_lock(&st->lock); | |
| 258 | 265 | switch ((u32)private) { |
| 259 | 266 | case ADF4350_FREQ: |
| 260 | 267 | ret = adf4350_set_freq(st, readin); |
| @@ -295,7 +302,7 @@ static ssize_t adf4350_write(struct iio_dev *indio_dev, · 34 unmodified lines | ||
| 295 | 302 | default: |
| 296 | 303 | ret = -EINVAL; |
| 297 | 304 | } |
| 298 | − mutex_unlock(&indio_dev->mlock); | |
| 305 | + mutex_unlock(&st->lock); | |
| 299 | 306 | |
| 300 | 307 | return ret ? ret : len; |
| 301 | 308 | } |
| @@ -309,7 +316,7 @@ static ssize_t adf4350_read(struct iio_dev *indio_dev, · 7 unmodified lines | ||
| 309 | 316 | unsigned long long val; |
| 310 | 317 | int ret = 0; |
| 311 | 318 | |
| 312 | − mutex_lock(&indio_dev->mlock); | |
| 319 | + mutex_lock(&st->lock); | |
| 313 | 320 | switch ((u32)private) { |
| 314 | 321 | case ADF4350_FREQ: |
| 315 | 322 | val = (u64)((st->r0_int * st->r1_mod) + st->r0_fract) * |
| @@ -338,7 +345,7 @@ static ssize_t adf4350_read(struct iio_dev *indio_dev, · 22 unmodified lines | ||
| 338 | 345 | ret = -EINVAL; |
| 339 | 346 | val = 0; |
| 340 | 347 | } |
| 341 | − mutex_unlock(&indio_dev->mlock); | |
| 348 | + mutex_unlock(&st->lock); | |
| 342 | 349 | |
| 343 | 350 | return ret < 0 ? ret : sprintf(buf, "%llu\n", val); |
| 344 | 351 | } |
| @@ -539,6 +546,8 @@ static int adf4350_probe(struct spi_device *spi) · 194 unmodified lines | ||
| 539 | 546 | indio_dev->channels = &adf4350_chan; |
| 540 | 547 | indio_dev->num_channels = 1; |
| 541 | 548 | |
| 549 | + mutex_init(&st->lock); | |
| 550 | + | |
| 542 | 551 | st->chspc = pdata->channel_spacing; |
| 543 | 552 | if (clk) { |
| 544 | 553 | st->clk = clk; |
| @@ -41,6 +41,18 @@ config ADIS16260 · 40 unmodified lines | ||
| 41 | 41 | This driver can also be built as a module. If so, the module |
| 42 | 42 | will be called adis16260. |
| 43 | 43 | |
| 44 | +config ADXRS290 | |
| 45 | + tristate "Analog Devices ADXRS290 Dual-Axis MEMS Gyroscope SPI driver" | |
| 46 | + depends on SPI | |
| 47 | + select IIO_BUFFER | |
| 48 | + select IIO_TRIGGERED_BUFFER | |
| 49 | + help | |
| 50 | + Say yes here to build support for Analog Devices ADXRS290 programmable | |
| 51 | + digital output gyroscope. | |
| 52 | + | |
| 53 | + This driver can also be built as a module. If so, the module will be | |
| 54 | + called adxrs290. | |
| 55 | + | |
| 44 | 56 | config ADXRS450 |
| 45 | 57 | tristate "Analog Devices ADXRS450/3 Digital Output Gyroscope SPI driver" |
| 46 | 58 | depends on SPI |
| @@ -8,6 +8,7 @@ obj-$(CONFIG_ADIS16080) += adis16080.o · 7 unmodified lines | ||
| 8 | 8 | obj-$(CONFIG_ADIS16130) += adis16130.o |
| 9 | 9 | obj-$(CONFIG_ADIS16136) += adis16136.o |
| 10 | 10 | obj-$(CONFIG_ADIS16260) += adis16260.o |
| 11 | +obj-$(CONFIG_ADXRS290) += adxrs290.o | |
| 11 | 12 | obj-$(CONFIG_ADXRS450) += adxrs450.o |
| 12 | 13 | obj-$(CONFIG_BMG160) += bmg160_core.o |
| 13 | 14 | obj-$(CONFIG_BMG160_I2C) += bmg160_i2c.o |
| @@ -38,7 +38,7 @@ struct adis16080_chip_info { · 37 unmodified lines | ||
| 38 | 38 | * @us: actual spi_device to write data |
| 39 | 39 | * @info: chip specific parameters |
| 40 | 40 | * @buf: transmit or receive buffer |
| 41 | − * @lock lock to protect buffer during reads | |
| 41 | + * @lock: lock to protect buffer during reads | |
| 42 | 42 | **/ |
| 43 | 43 | struct adis16080_state { |
| 44 | 44 | struct spi_device *us; |
| @@ -523,6 +523,11 @@ static const struct adis16136_chip_info adis16136_chip_info[] = { · 522 unmodified lines | ||
| 523 | 523 | }, |
| 524 | 524 | }; |
| 525 | 525 | |
| 526 | +static void adis16136_stop(void *data) | |
| 527 | +{ | |
| 528 | + adis16136_stop_device(data); | |
| 529 | +} | |
| 530 | + | |
| 526 | 531 | static int adis16136_probe(struct spi_device *spi) |
| 527 | 532 | { |
| 528 | 533 | const struct spi_device_id *id = spi_get_device_id(spi); |
| @@ -552,38 +557,23 @@ static int adis16136_probe(struct spi_device *spi) · 23 unmodified lines | ||
| 552 | 557 | if (ret) |
| 553 | 558 | return ret; |
| 554 | 559 | |
| 555 | − ret = adis_setup_buffer_and_trigger(&adis16136->adis, indio_dev, NULL); | |
| 560 | + ret = devm_adis_setup_buffer_and_trigger(&adis16136->adis, indio_dev, NULL); | |
| 556 | 561 | if (ret) |
| 557 | 562 | return ret; |
| 558 | 563 | |
| 559 | 564 | ret = adis16136_initial_setup(indio_dev); |
| 560 | 565 | if (ret) |
| 561 | − goto error_cleanup_buffer; | |
| 566 | + return ret; | |
| 562 | 567 | |
| 563 | − ret = iio_device_register(indio_dev); | |
| 568 | + ret = devm_add_action_or_reset(&spi->dev, adis16136_stop, indio_dev); | |
| 564 | 569 | if (ret) |
| 565 | − goto error_stop_device; | |
| 566 | − | |
| 567 | − adis16136_debugfs_init(indio_dev); | |
| 568 | − | |
| 569 | − return 0; | |
| 570 | − | |
| 571 | −error_stop_device: | |
| 572 | − adis16136_stop_device(indio_dev); | |
| 573 | −error_cleanup_buffer: | |
| 574 | − adis_cleanup_buffer_and_trigger(&adis16136->adis, indio_dev); | |
| 575 | − return ret; | |
| 576 | −} | |
| 577 | − | |
| 578 | −static int adis16136_remove(struct spi_device *spi) | |
| 579 | −{ | |
| 580 | − struct iio_dev *indio_dev = spi_get_drvdata(spi); | |
| 581 | − struct adis16136 *adis16136 = iio_priv(indio_dev); | |
| 570 | + return ret; | |
| 582 | 571 | |
| 583 | − iio_device_unregister(indio_dev); | |
| 584 | − adis16136_stop_device(indio_dev); | |
| 572 | + ret = devm_iio_device_register(&spi->dev, indio_dev); | |
| 573 | + if (ret) | |
| 574 | + return ret; | |
| 585 | 575 | |
| 586 | − adis_cleanup_buffer_and_trigger(&adis16136->adis, indio_dev); | |
| 576 | + adis16136_debugfs_init(indio_dev); | |
| 587 | 577 | |
| 588 | 578 | return 0; |
| 589 | 579 | } |
| @@ -603,7 +593,6 @@ static struct spi_driver adis16136_driver = { · 13 unmodified lines | ||
| 603 | 593 | }, |
| 604 | 594 | .id_table = adis16136_ids, |
| 605 | 595 | .probe = adis16136_probe, |
| 606 | − .remove = adis16136_remove, | |
| 607 | 596 | }; |
| 608 | 597 | module_spi_driver(adis16136_driver); |
| 609 | 598 | |
| @@ -359,6 +359,11 @@ static const struct adis_data adis16260_data = { · 358 unmodified lines | ||
| 359 | 359 | BIT(ADIS16260_DIAG_STAT_POWER_LOW_BIT), |
| 360 | 360 | }; |
| 361 | 361 | |
| 362 | +static void adis16260_stop(void *data) | |
| 363 | +{ | |
| 364 | + adis16260_stop_device(data); | |
| 365 | +} | |
| 366 | + | |
| 362 | 367 | static int adis16260_probe(struct spi_device *spi) |
| 363 | 368 | { |
| 364 | 369 | const struct spi_device_id *id; |
| @@ -390,35 +395,20 @@ static int adis16260_probe(struct spi_device *spi) · 25 unmodified lines | ||
| 390 | 395 | if (ret) |
| 391 | 396 | return ret; |
| 392 | 397 | |
| 393 | − ret = adis_setup_buffer_and_trigger(&adis16260->adis, indio_dev, NULL); | |
| 398 | + ret = devm_adis_setup_buffer_and_trigger(&adis16260->adis, indio_dev, NULL); | |
| 394 | 399 | if (ret) |
| 395 | 400 | return ret; |
| 396 | 401 | |
| 397 | 402 | /* Get the device into a sane initial state */ |
| 398 | 403 | ret = adis_initial_startup(&adis16260->adis); |
| 399 | 404 | if (ret) |
| 400 | − goto error_cleanup_buffer_trigger; | |
| 401 | − ret = iio_device_register(indio_dev); | |
| 402 | − if (ret) | |
| 403 | − goto error_cleanup_buffer_trigger; | |
| 404 | − | |
| 405 | − return 0; | |
| 406 | − | |
| 407 | −error_cleanup_buffer_trigger: | |
| 408 | − adis_cleanup_buffer_and_trigger(&adis16260->adis, indio_dev); | |
| 409 | − return ret; | |
| 410 | −} | |
| 411 | − | |
| 412 | −static int adis16260_remove(struct spi_device *spi) | |
| 413 | −{ | |
| 414 | − struct iio_dev *indio_dev = spi_get_drvdata(spi); | |
| 415 | − struct adis16260 *adis16260 = iio_priv(indio_dev); | |
| 405 | + return ret; | |
| 416 | 406 | |
| 417 | − iio_device_unregister(indio_dev); | |
| 418 | − adis16260_stop_device(indio_dev); | |
| 419 | − adis_cleanup_buffer_and_trigger(&adis16260->adis, indio_dev); | |
| 407 | + ret = devm_add_action_or_reset(&spi->dev, adis16260_stop, indio_dev); | |
| 408 | + if (ret) | |
| 409 | + return ret; | |
| 420 | 410 | |
| 421 | − return 0; | |
| 411 | + return devm_iio_device_register(&spi->dev, indio_dev); | |
| 422 | 412 | } |
| 423 | 413 | |
| 424 | 414 | /* |
| @@ -441,7 +431,6 @@ static struct spi_driver adis16260_driver = { · 16 unmodified lines | ||
| 441 | 431 | .name = "adis16260", |
| 442 | 432 | }, |
| 443 | 433 | .probe = adis16260_probe, |
| 444 | − .remove = adis16260_remove, | |
| 445 | 434 | .id_table = adis16260_id, |
| 446 | 435 | }; |
| 447 | 436 | module_spi_driver(adis16260_driver); |
| @@ -0,0 +1,710 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later | |
| 2 | +/* | |
| 3 | + * ADXRS290 SPI Gyroscope Driver | |
| 4 | + * | |
| 5 | + * Copyright (C) 2020 Nishant Malpani <nish.malpani25@gmail.com> | |
| 6 | + * Copyright (C) 2020 Analog Devices, Inc. | |
| 7 | + */ | |
| 8 | + | |
| 9 | +#include <linux/bitfield.h> | |
| 10 | +#include <linux/delay.h> | |
| 11 | +#include <linux/device.h> | |
| 12 | +#include <linux/kernel.h> | |
| 13 | +#include <linux/module.h> | |
| 14 | +#include <linux/spi/spi.h> | |
| 15 | + | |
| 16 | +#include <linux/iio/buffer.h> | |
| 17 | +#include <linux/iio/iio.h> | |
| 18 | +#include <linux/iio/sysfs.h> | |
| 19 | +#include <linux/iio/trigger.h> | |
| 20 | +#include <linux/iio/triggered_buffer.h> | |
| 21 | +#include <linux/iio/trigger_consumer.h> | |
| 22 | + | |
| 23 | +#define ADXRS290_ADI_ID 0xAD | |
| 24 | +#define ADXRS290_MEMS_ID 0x1D | |
| 25 | +#define ADXRS290_DEV_ID 0x92 | |
| 26 | + | |
| 27 | +#define ADXRS290_REG_ADI_ID 0x00 | |
| 28 | +#define ADXRS290_REG_MEMS_ID 0x01 | |
| 29 | +#define ADXRS290_REG_DEV_ID 0x02 | |
| 30 | +#define ADXRS290_REG_REV_ID 0x03 | |
| 31 | +#define ADXRS290_REG_SN0 0x04 /* Serial Number Registers, 4 bytes */ | |
| 32 | +#define ADXRS290_REG_DATAX0 0x08 /* Roll Rate o/p Data Regs, 2 bytes */ | |
| 33 | +#define ADXRS290_REG_DATAY0 0x0A /* Pitch Rate o/p Data Regs, 2 bytes */ | |
| 34 | +#define ADXRS290_REG_TEMP0 0x0C | |
| 35 | +#define ADXRS290_REG_POWER_CTL 0x10 | |
| 36 | +#define ADXRS290_REG_FILTER 0x11 | |
| 37 | +#define ADXRS290_REG_DATA_RDY 0x12 | |
| 38 | + | |
| 39 | +#define ADXRS290_READ BIT(7) | |
| 40 | +#define ADXRS290_TSM BIT(0) | |
| 41 | +#define ADXRS290_MEASUREMENT BIT(1) | |
| 42 | +#define ADXRS290_DATA_RDY_OUT BIT(0) | |
| 43 | +#define ADXRS290_SYNC_MASK GENMASK(1, 0) | |
| 44 | +#define ADXRS290_SYNC(x) FIELD_PREP(ADXRS290_SYNC_MASK, x) | |
| 45 | +#define ADXRS290_LPF_MASK GENMASK(2, 0) | |
| 46 | +#define ADXRS290_LPF(x) FIELD_PREP(ADXRS290_LPF_MASK, x) | |
| 47 | +#define ADXRS290_HPF_MASK GENMASK(7, 4) | |
| 48 | +#define ADXRS290_HPF(x) FIELD_PREP(ADXRS290_HPF_MASK, x) | |
| 49 | + | |
| 50 | +#define ADXRS290_READ_REG(reg) (ADXRS290_READ | (reg)) | |
| 51 | + | |
| 52 | +#define ADXRS290_MAX_TRANSITION_TIME_MS 100 | |
| 53 | + | |
| 54 | +enum adxrs290_mode { | |
| 55 | + ADXRS290_MODE_STANDBY, | |
| 56 | + ADXRS290_MODE_MEASUREMENT, | |
| 57 | +}; | |
| 58 | + | |
| 59 | +enum adxrs290_scan_index { | |
| 60 | + ADXRS290_IDX_X, | |
| 61 | + ADXRS290_IDX_Y, | |
| 62 | + ADXRS290_IDX_TEMP, | |
| 63 | + ADXRS290_IDX_TS, | |
| 64 | +}; | |
| 65 | + | |
| 66 | +struct adxrs290_state { | |
| 67 | + struct spi_device *spi; | |
| 68 | + /* Serialize reads and their subsequent processing */ | |
| 69 | + struct mutex lock; | |
| 70 | + enum adxrs290_mode mode; | |
| 71 | + unsigned int lpf_3db_freq_idx; | |
| 72 | + unsigned int hpf_3db_freq_idx; | |
| 73 | + struct iio_trigger *dready_trig; | |
| 74 | + /* Ensure correct alignment of timestamp when present */ | |
| 75 | + struct { | |
| 76 | + s16 channels[3]; | |
| 77 | + s64 ts __aligned(8); | |
| 78 | + } buffer; | |
| 79 | +}; | |
| 80 | + | |
| 81 | +/* | |
| 82 | + * Available cut-off frequencies of the low pass filter in Hz. | |
| 83 | + * The integer part and fractional part are represented separately. | |
| 84 | + */ | |
| 85 | +static const int adxrs290_lpf_3db_freq_hz_table[][2] = { | |
| 86 | + [0] = {480, 0}, | |
| 87 | + [1] = {320, 0}, | |
| 88 | + [2] = {160, 0}, | |
| 89 | + [3] = {80, 0}, | |
| 90 | + [4] = {56, 600000}, | |
| 91 | + [5] = {40, 0}, | |
| 92 | + [6] = {28, 300000}, | |
| 93 | + [7] = {20, 0}, | |
| 94 | +}; | |
| 95 | + | |
| 96 | +/* | |
| 97 | + * Available cut-off frequencies of the high pass filter in Hz. | |
| 98 | + * The integer part and fractional part are represented separately. | |
| 99 | + */ | |
| 100 | +static const int adxrs290_hpf_3db_freq_hz_table[][2] = { | |
| 101 | + [0] = {0, 0}, | |
| 102 | + [1] = {0, 11000}, | |
| 103 | + [2] = {0, 22000}, | |
| 104 | + [3] = {0, 44000}, | |
| 105 | + [4] = {0, 87000}, | |
| 106 | + [5] = {0, 175000}, | |
| 107 | + [6] = {0, 350000}, | |
| 108 | + [7] = {0, 700000}, | |
| 109 | + [8] = {1, 400000}, | |
| 110 | + [9] = {2, 800000}, | |
| 111 | + [10] = {11, 300000}, | |
| 112 | +}; | |
| 113 | + | |
| 114 | +static int adxrs290_get_rate_data(struct iio_dev *indio_dev, const u8 cmd, int *val) | |
| 115 | +{ | |
| 116 | + struct adxrs290_state *st = iio_priv(indio_dev); | |
| 117 | + int ret = 0; | |
| 118 | + int temp; | |
| 119 | + | |
| 120 | + mutex_lock(&st->lock); | |
| 121 | + temp = spi_w8r16(st->spi, cmd); | |
| 122 | + if (temp < 0) { | |
| 123 | + ret = temp; | |
| 124 | + goto err_unlock; | |
| 125 | + } | |
| 126 | + | |
| 127 | + *val = temp; | |
| 128 | + | |
| 129 | +err_unlock: | |
| 130 | + mutex_unlock(&st->lock); | |
| 131 | + return ret; | |
| 132 | +} | |
| 133 | + | |
| 134 | +static int adxrs290_get_temp_data(struct iio_dev *indio_dev, int *val) | |
| 135 | +{ | |
| 136 | + const u8 cmd = ADXRS290_READ_REG(ADXRS290_REG_TEMP0); | |
| 137 | + struct adxrs290_state *st = iio_priv(indio_dev); | |
| 138 | + int ret = 0; | |
| 139 | + int temp; | |
| 140 | + | |
| 141 | + mutex_lock(&st->lock); | |
| 142 | + temp = spi_w8r16(st->spi, cmd); | |
| 143 | + if (temp < 0) { | |
| 144 | + ret = temp; | |
| 145 | + goto err_unlock; | |
| 146 | + } | |
| 147 | + | |
| 148 | + /* extract lower 12 bits temperature reading */ | |
| 149 | + *val = temp & 0x0FFF; | |
| 150 | + | |
| 151 | +err_unlock: | |
| 152 | + mutex_unlock(&st->lock); | |
| 153 | + return ret; | |
| 154 | +} | |
| 155 | + | |
| 156 | +static int adxrs290_get_3db_freq(struct iio_dev *indio_dev, u8 *val, u8 *val2) | |
| 157 | +{ | |
| 158 | + const u8 cmd = ADXRS290_READ_REG(ADXRS290_REG_FILTER); | |
| 159 | + struct adxrs290_state *st = iio_priv(indio_dev); | |
| 160 | + int ret = 0; | |
| 161 | + short temp; | |
| 162 | + | |
| 163 | + mutex_lock(&st->lock); | |
| 164 | + temp = spi_w8r8(st->spi, cmd); | |
| 165 | + if (temp < 0) { | |
| 166 | + ret = temp; | |
| 167 | + goto err_unlock; | |
| 168 | + } | |
| 169 | + | |
| 170 | + *val = FIELD_GET(ADXRS290_LPF_MASK, temp); | |
| 171 | + *val2 = FIELD_GET(ADXRS290_HPF_MASK, temp); | |
| 172 | + | |
| 173 | +err_unlock: | |
| 174 | + mutex_unlock(&st->lock); | |
| 175 | + return ret; | |
| 176 | +} | |
| 177 | + | |
| 178 | +static int adxrs290_spi_write_reg(struct spi_device *spi, const u8 reg, | |
| 179 | + const u8 val) | |
| 180 | +{ | |
| 181 | + u8 buf[2]; | |
| 182 | + | |
| 183 | + buf[0] = reg; | |
| 184 | + buf[1] = val; | |
| 185 | + | |
| 186 | + return spi_write_then_read(spi, buf, ARRAY_SIZE(buf), NULL, 0); | |
| 187 | +} | |
| 188 | + | |
| 189 | +static int adxrs290_find_match(const int (*freq_tbl)[2], const int n, | |
| 190 | + const int val, const int val2) | |
| 191 | +{ | |
| 192 | + int i; | |
| 193 | + | |
| 194 | + for (i = 0; i < n; i++) { | |
| 195 | + if (freq_tbl[i][0] == val && freq_tbl[i][1] == val2) | |
| 196 | + return i; | |
| 197 | + } | |
| 198 | + | |
| 199 | + return -EINVAL; | |
| 200 | +} | |
| 201 | + | |
| 202 | +static int adxrs290_set_filter_freq(struct iio_dev *indio_dev, | |
| 203 | + const unsigned int lpf_idx, | |
| 204 | + const unsigned int hpf_idx) | |
| 205 | +{ | |
| 206 | + struct adxrs290_state *st = iio_priv(indio_dev); | |
| 207 | + u8 val; | |
| 208 | + | |
| 209 | + val = ADXRS290_HPF(hpf_idx) | ADXRS290_LPF(lpf_idx); | |
| 210 | + | |
| 211 | + return adxrs290_spi_write_reg(st->spi, ADXRS290_REG_FILTER, val); | |
| 212 | +} | |
| 213 | + | |
| 214 | +static int adxrs290_set_mode(struct iio_dev *indio_dev, enum adxrs290_mode mode) | |
| 215 | +{ | |
| 216 | + struct adxrs290_state *st = iio_priv(indio_dev); | |
| 217 | + int val, ret; | |
| 218 | + | |
| 219 | + if (st->mode == mode) | |
| 220 | + return 0; | |
| 221 | + | |
| 222 | + mutex_lock(&st->lock); | |
| 223 | + | |
| 224 | + ret = spi_w8r8(st->spi, ADXRS290_READ_REG(ADXRS290_REG_POWER_CTL)); | |
| 225 | + if (ret < 0) | |
| 226 | + goto out_unlock; | |
| 227 | + | |
| 228 | + val = ret; | |
| 229 | + | |
| 230 | + switch (mode) { | |
| 231 | + case ADXRS290_MODE_STANDBY: | |
| 232 | + val &= ~ADXRS290_MEASUREMENT; | |
| 233 | + break; | |
| 234 | + case ADXRS290_MODE_MEASUREMENT: | |
| 235 | + val |= ADXRS290_MEASUREMENT; | |
| 236 | + break; | |
| 237 | + default: | |
| 238 | + ret = -EINVAL; | |
| 239 | + goto out_unlock; | |
| 240 | + } | |
| 241 | + | |
| 242 | + ret = adxrs290_spi_write_reg(st->spi, ADXRS290_REG_POWER_CTL, val); | |
| 243 | + if (ret < 0) { | |
| 244 | + dev_err(&st->spi->dev, "unable to set mode: %d\n", ret); | |
| 245 | + goto out_unlock; | |
| 246 | + } | |
| 247 | + | |
| 248 | + /* update cached mode */ | |
| 249 | + st->mode = mode; | |
| 250 | + | |
| 251 | +out_unlock: | |
| 252 | + mutex_unlock(&st->lock); | |
| 253 | + return ret; | |
| 254 | +} | |
| 255 | + | |
| 256 | +static void adxrs290_chip_off_action(void *data) | |
| 257 | +{ | |
| 258 | + struct iio_dev *indio_dev = data; | |
| 259 | + | |
| 260 | + adxrs290_set_mode(indio_dev, ADXRS290_MODE_STANDBY); | |
| 261 | +} | |
| 262 | + | |
| 263 | +static int adxrs290_initial_setup(struct iio_dev *indio_dev) | |
| 264 | +{ | |
| 265 | + struct adxrs290_state *st = iio_priv(indio_dev); | |
| 266 | + struct spi_device *spi = st->spi; | |
| 267 | + int ret; | |
| 268 | + | |
| 269 | + ret = adxrs290_spi_write_reg(spi, ADXRS290_REG_POWER_CTL, | |
| 270 | + ADXRS290_MEASUREMENT | ADXRS290_TSM); | |
| 271 | + if (ret < 0) | |
| 272 | + return ret; | |
| 273 | + | |
| 274 | + st->mode = ADXRS290_MODE_MEASUREMENT; | |
| 275 | + | |
| 276 | + return devm_add_action_or_reset(&spi->dev, adxrs290_chip_off_action, | |
| 277 | + indio_dev); | |
| 278 | +} | |
| 279 | + | |
| 280 | +static int adxrs290_read_raw(struct iio_dev *indio_dev, | |
| 281 | + struct iio_chan_spec const *chan, | |
| 282 | + int *val, | |
| 283 | + int *val2, | |
| 284 | + long mask) | |
| 285 | +{ | |
| 286 | + struct adxrs290_state *st = iio_priv(indio_dev); | |
| 287 | + unsigned int t; | |
| 288 | + int ret; | |
| 289 | + | |
| 290 | + switch (mask) { | |
| 291 | + case IIO_CHAN_INFO_RAW: | |
| 292 | + ret = iio_device_claim_direct_mode(indio_dev); | |
| 293 | + if (ret) | |
| 294 | + return ret; | |
| 295 | + | |
| 296 | + switch (chan->type) { | |
| 297 | + case IIO_ANGL_VEL: | |
| 298 | + ret = adxrs290_get_rate_data(indio_dev, | |
| 299 | + ADXRS290_READ_REG(chan->address), | |
| 300 | + val); | |
| 301 | + if (ret < 0) | |
| 302 | + break; | |
| 303 | + | |
| 304 | + ret = IIO_VAL_INT; | |
| 305 | + break; | |
| 306 | + case IIO_TEMP: | |
| 307 | + ret = adxrs290_get_temp_data(indio_dev, val); | |
| 308 | + if (ret < 0) | |
| 309 | + break; | |
| 310 | + | |
| 311 | + ret = IIO_VAL_INT; | |
| 312 | + break; | |
| 313 | + default: | |
| 314 | + ret = -EINVAL; | |
| 315 | + break; | |
| 316 | + } | |
| 317 | + | |
| 318 | + iio_device_release_direct_mode(indio_dev); | |
| 319 | + return ret; | |
| 320 | + case IIO_CHAN_INFO_SCALE: | |
| 321 | + switch (chan->type) { | |
| 322 | + case IIO_ANGL_VEL: | |
| 323 | + /* 1 LSB = 0.005 degrees/sec */ | |
| 324 | + *val = 0; | |
| 325 | + *val2 = 87266; | |
| 326 | + return IIO_VAL_INT_PLUS_NANO; | |
| 327 | + case IIO_TEMP: | |
| 328 | + /* 1 LSB = 0.1 degrees Celsius */ | |
| 329 | + *val = 100; | |
| 330 | + return IIO_VAL_INT; | |
| 331 | + default: | |
| 332 | + return -EINVAL; | |
| 333 | + } | |
| 334 | + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: | |
| 335 | + switch (chan->type) { | |
| 336 | + case IIO_ANGL_VEL: | |
| 337 | + t = st->lpf_3db_freq_idx; | |
| 338 | + *val = adxrs290_lpf_3db_freq_hz_table[t][0]; | |
| 339 | + *val2 = adxrs290_lpf_3db_freq_hz_table[t][1]; | |
| 340 | + return IIO_VAL_INT_PLUS_MICRO; | |
| 341 | + default: | |
| 342 | + return -EINVAL; | |
| 343 | + } | |
| 344 | + case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY: | |
| 345 | + switch (chan->type) { | |
| 346 | + case IIO_ANGL_VEL: | |
| 347 | + t = st->hpf_3db_freq_idx; | |
| 348 | + *val = adxrs290_hpf_3db_freq_hz_table[t][0]; | |
| 349 | + *val2 = adxrs290_hpf_3db_freq_hz_table[t][1]; | |
| 350 | + return IIO_VAL_INT_PLUS_MICRO; | |
| 351 | + default: | |
| 352 | + return -EINVAL; | |
| 353 | + } | |
| 354 | + } | |
| 355 | + | |
| 356 | + return -EINVAL; | |
| 357 | +} | |
| 358 | + | |
| 359 | +static int adxrs290_write_raw(struct iio_dev *indio_dev, | |
| 360 | + struct iio_chan_spec const *chan, | |
| 361 | + int val, | |
| 362 | + int val2, | |
| 363 | + long mask) | |
| 364 | +{ | |
| 365 | + struct adxrs290_state *st = iio_priv(indio_dev); | |
| 366 | + int ret, lpf_idx, hpf_idx; | |
| 367 | + | |
| 368 | + ret = iio_device_claim_direct_mode(indio_dev); | |
| 369 | + if (ret) | |
| 370 | + return ret; | |
| 371 | + | |
| 372 | + switch (mask) { | |
| 373 | + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: | |
| 374 | + lpf_idx = adxrs290_find_match(adxrs290_lpf_3db_freq_hz_table, | |
| 375 | + ARRAY_SIZE(adxrs290_lpf_3db_freq_hz_table), | |
| 376 | + val, val2); | |
| 377 | + if (lpf_idx < 0) { | |
| 378 | + ret = -EINVAL; | |
| 379 | + break; | |
| 380 | + } | |
| 381 | + | |
| 382 | + /* caching the updated state of the low-pass filter */ | |
| 383 | + st->lpf_3db_freq_idx = lpf_idx; | |
| 384 | + /* retrieving the current state of the high-pass filter */ | |
| 385 | + hpf_idx = st->hpf_3db_freq_idx; | |
| 386 | + ret = adxrs290_set_filter_freq(indio_dev, lpf_idx, hpf_idx); | |
| 387 | + break; | |
| 388 | + | |
| 389 | + case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY: | |
| 390 | + hpf_idx = adxrs290_find_match(adxrs290_hpf_3db_freq_hz_table, | |
| 391 | + ARRAY_SIZE(adxrs290_hpf_3db_freq_hz_table), | |
| 392 | + val, val2); | |
| 393 | + if (hpf_idx < 0) { | |
| 394 | + ret = -EINVAL; | |
| 395 | + break; | |
| 396 | + } | |
| 397 | + | |
| 398 | + /* caching the updated state of the high-pass filter */ | |
| 399 | + st->hpf_3db_freq_idx = hpf_idx; | |
| 400 | + /* retrieving the current state of the low-pass filter */ | |
| 401 | + lpf_idx = st->lpf_3db_freq_idx; | |
| 402 | + ret = adxrs290_set_filter_freq(indio_dev, lpf_idx, hpf_idx); | |
| 403 | + break; | |
| 404 | + | |
| 405 | + default: | |
| 406 | + ret = -EINVAL; | |
| 407 | + break; | |
| 408 | + } | |
| 409 | + | |
| 410 | + iio_device_release_direct_mode(indio_dev); | |
| 411 | + return ret; | |
| 412 | +} | |
| 413 | + | |
| 414 | +static int adxrs290_read_avail(struct iio_dev *indio_dev, | |
| 415 | + struct iio_chan_spec const *chan, | |
| 416 | + const int **vals, int *type, int *length, | |
| 417 | + long mask) | |
| 418 | +{ | |
| 419 | + switch (mask) { | |
| 420 | + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: | |
| 421 | + *vals = (const int *)adxrs290_lpf_3db_freq_hz_table; | |
| 422 | + *type = IIO_VAL_INT_PLUS_MICRO; | |
| 423 | + /* Values are stored in a 2D matrix */ | |
| 424 | + *length = ARRAY_SIZE(adxrs290_lpf_3db_freq_hz_table) * 2; | |
| 425 | + | |
| 426 | + return IIO_AVAIL_LIST; | |
| 427 | + case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY: | |
| 428 | + *vals = (const int *)adxrs290_hpf_3db_freq_hz_table; | |
| 429 | + *type = IIO_VAL_INT_PLUS_MICRO; | |
| 430 | + /* Values are stored in a 2D matrix */ | |
| 431 | + *length = ARRAY_SIZE(adxrs290_hpf_3db_freq_hz_table) * 2; | |
| 432 | + | |
| 433 | + return IIO_AVAIL_LIST; | |
| 434 | + default: | |
| 435 | + return -EINVAL; | |
| 436 | + } | |
| 437 | +} | |
| 438 | + | |
| 439 | +static int adxrs290_reg_access_rw(struct spi_device *spi, unsigned int reg, | |
| 440 | + unsigned int *readval) | |
| 441 | +{ | |
| 442 | + int ret; | |
| 443 | + | |
| 444 | + ret = spi_w8r8(spi, ADXRS290_READ_REG(reg)); | |
| 445 | + if (ret < 0) | |
| 446 | + return ret; | |
| 447 | + | |
| 448 | + *readval = ret; | |
| 449 | + | |
| 450 | + return 0; | |
| 451 | +} | |
| 452 | + | |
| 453 | +static int adxrs290_reg_access(struct iio_dev *indio_dev, unsigned int reg, | |
| 454 | + unsigned int writeval, unsigned int *readval) | |
| 455 | +{ | |
| 456 | + struct adxrs290_state *st = iio_priv(indio_dev); | |
| 457 | + | |
| 458 | + if (readval) | |
| 459 | + return adxrs290_reg_access_rw(st->spi, reg, readval); | |
| 460 | + else | |
| 461 | + return adxrs290_spi_write_reg(st->spi, reg, writeval); | |
| 462 | +} | |
| 463 | + | |
| 464 | +static int adxrs290_data_rdy_trigger_set_state(struct iio_trigger *trig, | |
| 465 | + bool state) | |
| 466 | +{ | |
| 467 | + struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); | |
| 468 | + struct adxrs290_state *st = iio_priv(indio_dev); | |
| 469 | + int ret; | |
| 470 | + u8 val; | |
| 471 | + | |
| 472 | + val = state ? ADXRS290_SYNC(ADXRS290_DATA_RDY_OUT) : 0; | |
| 473 | + | |
| 474 | + ret = adxrs290_spi_write_reg(st->spi, ADXRS290_REG_DATA_RDY, val); | |
| 475 | + if (ret < 0) | |
| 476 | + dev_err(&st->spi->dev, "failed to start data rdy interrupt\n"); | |
| 477 | + | |
| 478 | + return ret; | |
| 479 | +} | |
| 480 | + | |
| 481 | +static int adxrs290_reset_trig(struct iio_trigger *trig) | |
| 482 | +{ | |
| 483 | + struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); | |
| 484 | + int val; | |
| 485 | + | |
| 486 | + /* | |
| 487 | + * Data ready interrupt is reset after a read of the data registers. | |
| 488 | + * Here, we only read the 16b DATAY registers as that marks the end of | |
| 489 | + * a read of the data registers and initiates a reset for the interrupt | |
| 490 | + * line. | |
| 491 | + */ | |
| 492 | + adxrs290_get_rate_data(indio_dev, | |
| 493 | + ADXRS290_READ_REG(ADXRS290_REG_DATAY0), &val); | |
| 494 | + | |
| 495 | + return 0; | |
| 496 | +} | |
| 497 | + | |
| 498 | +static const struct iio_trigger_ops adxrs290_trigger_ops = { | |
| 499 | + .set_trigger_state = &adxrs290_data_rdy_trigger_set_state, | |
| 500 | + .validate_device = &iio_trigger_validate_own_device, | |
| 501 | + .try_reenable = &adxrs290_reset_trig, | |
| 502 | +}; | |
| 503 | + | |
| 504 | +static irqreturn_t adxrs290_trigger_handler(int irq, void *p) | |
| 505 | +{ | |
| 506 | + struct iio_poll_func *pf = p; | |
| 507 | + struct iio_dev *indio_dev = pf->indio_dev; | |
| 508 | + struct adxrs290_state *st = iio_priv(indio_dev); | |
| 509 | + u8 tx = ADXRS290_READ_REG(ADXRS290_REG_DATAX0); | |
| 510 | + int ret; | |
| 511 | + | |
| 512 | + mutex_lock(&st->lock); | |
| 513 | + | |
| 514 | + /* exercise a bulk data capture starting from reg DATAX0... */ | |
| 515 | + ret = spi_write_then_read(st->spi, &tx, sizeof(tx), st->buffer.channels, | |
| 516 | + sizeof(st->buffer.channels)); | |
| 517 | + if (ret < 0) | |
| 518 | + goto out_unlock_notify; | |
| 519 | + | |
| 520 | + iio_push_to_buffers_with_timestamp(indio_dev, &st->buffer, | |
| 521 | + pf->timestamp); | |
| 522 | + | |
| 523 | +out_unlock_notify: | |
| 524 | + mutex_unlock(&st->lock); | |
| 525 | + iio_trigger_notify_done(indio_dev->trig); | |
| 526 | + | |
| 527 | + return IRQ_HANDLED; | |
| 528 | +} | |
| 529 | + | |
| 530 | +#define ADXRS290_ANGL_VEL_CHANNEL(reg, axis) { \ | |
| 531 | + .type = IIO_ANGL_VEL, \ | |
| 532 | + .address = reg, \ | |
| 533 | + .modified = 1, \ | |
| 534 | + .channel2 = IIO_MOD_##axis, \ | |
| 535 | + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ | |
| 536 | + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ | |
| 537 | + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | \ | |
| 538 | + BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY), \ | |
| 539 | + .info_mask_shared_by_type_available = \ | |
| 540 | + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | \ | |
| 541 | + BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY), \ | |
| 542 | + .scan_index = ADXRS290_IDX_##axis, \ | |
| 543 | + .scan_type = { \ | |
| 544 | + .sign = 's', \ | |
| 545 | + .realbits = 16, \ | |
| 546 | + .storagebits = 16, \ | |
| 547 | + .endianness = IIO_LE, \ | |
| 548 | + }, \ | |
| 549 | +} | |
| 550 | + | |
| 551 | +static const struct iio_chan_spec adxrs290_channels[] = { | |
| 552 | + ADXRS290_ANGL_VEL_CHANNEL(ADXRS290_REG_DATAX0, X), | |
| 553 | + ADXRS290_ANGL_VEL_CHANNEL(ADXRS290_REG_DATAY0, Y), | |
| 554 | + { | |
| 555 | + .type = IIO_TEMP, | |
| 556 | + .address = ADXRS290_REG_TEMP0, | |
| 557 | + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | | |
| 558 | + BIT(IIO_CHAN_INFO_SCALE), | |
| 559 | + .scan_index = ADXRS290_IDX_TEMP, | |
| 560 | + .scan_type = { | |
| 561 | + .sign = 's', | |
| 562 | + .realbits = 12, | |
| 563 | + .storagebits = 16, | |
| 564 | + .endianness = IIO_LE, | |
| 565 | + }, | |
| 566 | + }, | |
| 567 | + IIO_CHAN_SOFT_TIMESTAMP(ADXRS290_IDX_TS), | |
| 568 | +}; | |
| 569 | + | |
| 570 | +static const unsigned long adxrs290_avail_scan_masks[] = { | |
| 571 | + BIT(ADXRS290_IDX_X) | BIT(ADXRS290_IDX_Y) | BIT(ADXRS290_IDX_TEMP), | |
| 572 | + 0 | |
| 573 | +}; | |
| 574 | + | |
| 575 | +static const struct iio_info adxrs290_info = { | |
| 576 | + .read_raw = &adxrs290_read_raw, | |
| 577 | + .write_raw = &adxrs290_write_raw, | |
| 578 | + .read_avail = &adxrs290_read_avail, | |
| 579 | + .debugfs_reg_access = &adxrs290_reg_access, | |
| 580 | +}; | |
| 581 | + | |
| 582 | +static int adxrs290_probe_trigger(struct iio_dev *indio_dev) | |
| 583 | +{ | |
| 584 | + struct adxrs290_state *st = iio_priv(indio_dev); | |
| 585 | + int ret; | |
| 586 | + | |
| 587 | + if (!st->spi->irq) { | |
| 588 | + dev_info(&st->spi->dev, "no irq, using polling\n"); | |
| 589 | + return 0; | |
| 590 | + } | |
| 591 | + | |
| 592 | + st->dready_trig = devm_iio_trigger_alloc(&st->spi->dev, "%s-dev%d", | |
| 593 | + indio_dev->name, | |
| 594 | + indio_dev->id); | |
| 595 | + if (!st->dready_trig) | |
| 596 | + return -ENOMEM; | |
| 597 | + | |
| 598 | + st->dready_trig->dev.parent = &st->spi->dev; | |
| 599 | + st->dready_trig->ops = &adxrs290_trigger_ops; | |
| 600 | + iio_trigger_set_drvdata(st->dready_trig, indio_dev); | |
| 601 | + | |
| 602 | + ret = devm_request_irq(&st->spi->dev, st->spi->irq, | |
| 603 | + &iio_trigger_generic_data_rdy_poll, | |
| 604 | + IRQF_ONESHOT, "adxrs290_irq", st->dready_trig); | |
| 605 | + if (ret < 0) | |
| 606 | + return dev_err_probe(&st->spi->dev, ret, | |
| 607 | + "request irq %d failed\n", st->spi->irq); | |
| 608 | + | |
| 609 | + ret = devm_iio_trigger_register(&st->spi->dev, st->dready_trig); | |
| 610 | + if (ret) { | |
| 611 | + dev_err(&st->spi->dev, "iio trigger register failed\n"); | |
| 612 | + return ret; | |
| 613 | + } | |
| 614 | + | |
| 615 | + indio_dev->trig = iio_trigger_get(st->dready_trig); | |
| 616 | + | |
| 617 | + return 0; | |
| 618 | +} | |
| 619 | + | |
| 620 | +static int adxrs290_probe(struct spi_device *spi) | |
| 621 | +{ | |
| 622 | + struct iio_dev *indio_dev; | |
| 623 | + struct adxrs290_state *st; | |
| 624 | + u8 val, val2; | |
| 625 | + int ret; | |
| 626 | + | |
| 627 | + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); | |
| 628 | + if (!indio_dev) | |
| 629 | + return -ENOMEM; | |
| 630 | + | |
| 631 | + st = iio_priv(indio_dev); | |
| 632 | + st->spi = spi; | |
| 633 | + | |
| 634 | + indio_dev->name = "adxrs290"; | |
| 635 | + indio_dev->modes = INDIO_DIRECT_MODE; | |
| 636 | + indio_dev->channels = adxrs290_channels; | |
| 637 | + indio_dev->num_channels = ARRAY_SIZE(adxrs290_channels); | |
| 638 | + indio_dev->info = &adxrs290_info; | |
| 639 | + indio_dev->available_scan_masks = adxrs290_avail_scan_masks; | |
| 640 | + | |
| 641 | + mutex_init(&st->lock); | |
| 642 | + | |
| 643 | + val = spi_w8r8(spi, ADXRS290_READ_REG(ADXRS290_REG_ADI_ID)); | |
| 644 | + if (val != ADXRS290_ADI_ID) { | |
| 645 | + dev_err(&spi->dev, "Wrong ADI ID 0x%02x\n", val); | |
| 646 | + return -ENODEV; | |
| 647 | + } | |
| 648 | + | |
| 649 | + val = spi_w8r8(spi, ADXRS290_READ_REG(ADXRS290_REG_MEMS_ID)); | |
| 650 | + if (val != ADXRS290_MEMS_ID) { | |
| 651 | + dev_err(&spi->dev, "Wrong MEMS ID 0x%02x\n", val); | |
| 652 | + return -ENODEV; | |
| 653 | + } | |
| 654 | + | |
| 655 | + val = spi_w8r8(spi, ADXRS290_READ_REG(ADXRS290_REG_DEV_ID)); | |
| 656 | + if (val != ADXRS290_DEV_ID) { | |
| 657 | + dev_err(&spi->dev, "Wrong DEV ID 0x%02x\n", val); | |
| 658 | + return -ENODEV; | |
| 659 | + } | |
| 660 | + | |
| 661 | + /* default mode the gyroscope starts in */ | |
| 662 | + st->mode = ADXRS290_MODE_STANDBY; | |
| 663 | + | |
| 664 | + /* switch to measurement mode and switch on the temperature sensor */ | |
| 665 | + ret = adxrs290_initial_setup(indio_dev); | |
| 666 | + if (ret < 0) | |
| 667 | + return ret; | |
| 668 | + | |
| 669 | + /* max transition time to measurement mode */ | |
| 670 | + msleep(ADXRS290_MAX_TRANSITION_TIME_MS); | |
| 671 | + | |
| 672 | + ret = adxrs290_get_3db_freq(indio_dev, &val, &val2); | |
| 673 | + if (ret < 0) | |
| 674 | + return ret; | |
| 675 | + | |
| 676 | + st->lpf_3db_freq_idx = val; | |
| 677 | + st->hpf_3db_freq_idx = val2; | |
| 678 | + | |
| 679 | + ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, | |
| 680 | + &iio_pollfunc_store_time, | |
| 681 | + &adxrs290_trigger_handler, NULL); | |
| 682 | + if (ret < 0) | |
| 683 | + return dev_err_probe(&spi->dev, ret, | |
| 684 | + "iio triggered buffer setup failed\n"); | |
| 685 | + | |
| 686 | + ret = adxrs290_probe_trigger(indio_dev); | |
| 687 | + if (ret < 0) | |
| 688 | + return ret; | |
| 689 | + | |
| 690 | + return devm_iio_device_register(&spi->dev, indio_dev); | |
| 691 | +} | |
| 692 | + | |
| 693 | +static const struct of_device_id adxrs290_of_match[] = { | |
| 694 | + { .compatible = "adi,adxrs290" }, | |
| 695 | + { } | |
| 696 | +}; | |
| 697 | +MODULE_DEVICE_TABLE(of, adxrs290_of_match); | |
| 698 | + | |
| 699 | +static struct spi_driver adxrs290_driver = { | |
| 700 | + .driver = { | |
| 701 | + .name = "adxrs290", | |
| 702 | + .of_match_table = adxrs290_of_match, | |
| 703 | + }, | |
| 704 | + .probe = adxrs290_probe, | |
| 705 | +}; | |
| 706 | +module_spi_driver(adxrs290_driver); | |
| 707 | + | |
| 708 | +MODULE_AUTHOR("Nishant Malpani <nish.malpani25@gmail.com>"); | |
| 709 | +MODULE_DESCRIPTION("Analog Devices ADXRS290 Gyroscope SPI driver"); | |
| 710 | +MODULE_LICENSE("GPL"); | |
| @@ -46,13 +46,20 @@ static irqreturn_t itg3200_trigger_handler(int irq, void *p) · 45 unmodified lines | ||
| 46 | 46 | struct iio_poll_func *pf = p; |
| 47 | 47 | struct iio_dev *indio_dev = pf->indio_dev; |
| 48 | 48 | struct itg3200 *st = iio_priv(indio_dev); |
| 49 | − __be16 buf[ITG3200_SCAN_ELEMENTS + sizeof(s64)/sizeof(u16)]; | |
| 50 | − | |
| 51 | − int ret = itg3200_read_all_channels(st->i2c, buf); | |
| 49 | + /* | |
| 50 | + * Ensure correct alignment and padding including for the | |
| 51 | + * timestamp that may be inserted. | |
| 52 | + */ | |
| 53 | + struct { | |
| 54 | + __be16 buf[ITG3200_SCAN_ELEMENTS]; | |
| 55 | + s64 ts __aligned(8); | |
| 56 | + } scan; | |
| 57 | + | |
| 58 | + int ret = itg3200_read_all_channels(st->i2c, scan.buf); | |
| 52 | 59 | if (ret < 0) |
| 53 | 60 | goto error_ret; |
| 54 | 61 | |
| 55 | − iio_push_to_buffers_with_timestamp(indio_dev, buf, pf->timestamp); | |
| 62 | + iio_push_to_buffers_with_timestamp(indio_dev, &scan, pf->timestamp); | |
| 56 | 63 | |
| 57 | 64 | iio_trigger_notify_done(indio_dev->trig); |
| 58 | 65 | |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | /* |
| 3 | 3 | * max30102.c - Support for MAX30102 heart rate and pulse oximeter sensor |
| 4 | 4 | * |
| 5 | − * Copyright (C) 2017 Matt Ranostay <matt@ranostay.consulting> | |
| 5 | + * Copyright (C) 2017 Matt Ranostay <matt.ranostay@konsulko.com> | |
| 6 | 6 | * |
| 7 | 7 | * Support for MAX30105 optical particle sensor |
| 8 | 8 | * Copyright (C) 2017 Peter Meerwald-Stadler <pmeerw@pmeerw.net> |
| @@ -19,7 +19,7 @@ · 10 unmodified lines | ||
| 19 | 19 | #include <linux/irq.h> |
| 20 | 20 | #include <linux/i2c.h> |
| 21 | 21 | #include <linux/mutex.h> |
| 22 | −#include <linux/of.h> | |
| 22 | +#include <linux/mod_devicetable.h> | |
| 23 | 23 | #include <linux/regmap.h> |
| 24 | 24 | #include <linux/iio/iio.h> |
| 25 | 25 | #include <linux/iio/buffer.h> |
| @@ -323,11 +323,10 @@ static int max30102_get_current_idx(unsigned int val, int *reg) · 297 unmodified lines | ||
| 323 | 323 | static int max30102_led_init(struct max30102_data *data) |
| 324 | 324 | { |
| 325 | 325 | struct device *dev = &data->client->dev; |
| 326 | − struct device_node *np = dev->of_node; | |
| 327 | 326 | unsigned int val; |
| 328 | 327 | int reg, ret; |
| 329 | 328 | |
| 330 | − ret = of_property_read_u32(np, "maxim,red-led-current-microamp", &val); | |
| 329 | + ret = device_property_read_u32(dev, "maxim,red-led-current-microamp", &val); | |
| 331 | 330 | if (ret) { |
| 332 | 331 | dev_info(dev, "no red-led-current-microamp set\n"); |
| 333 | 332 | |
| @@ -346,7 +345,7 @@ static int max30102_led_init(struct max30102_data *data) · 12 unmodified lines | ||
| 346 | 345 | return ret; |
| 347 | 346 | |
| 348 | 347 | if (data->chip_id == max30105) { |
| 349 | − ret = of_property_read_u32(np, | |
| 348 | + ret = device_property_read_u32(dev, | |
| 350 | 349 | "maxim,green-led-current-microamp", &val); |
| 351 | 350 | if (ret) { |
| 352 | 351 | dev_info(dev, "no green-led-current-microamp set\n"); |
| @@ -368,7 +367,7 @@ static int max30102_led_init(struct max30102_data *data) · 15 unmodified lines | ||
| 368 | 367 | return ret; |
| 369 | 368 | } |
| 370 | 369 | |
| 371 | − ret = of_property_read_u32(np, "maxim,ir-led-current-microamp", &val); | |
| 370 | + ret = device_property_read_u32(dev, "maxim,ir-led-current-microamp", &val); | |
| 372 | 371 | if (ret) { |
| 373 | 372 | dev_info(dev, "no ir-led-current-microamp set\n"); |
| 374 | 373 | |
| @@ -624,7 +623,7 @@ MODULE_DEVICE_TABLE(of, max30102_dt_ids); · 249 unmodified lines | ||
| 624 | 623 | static struct i2c_driver max30102_driver = { |
| 625 | 624 | .driver = { |
| 626 | 625 | .name = MAX30102_DRV_NAME, |
| 627 | − .of_match_table = of_match_ptr(max30102_dt_ids), | |
| 626 | + .of_match_table = max30102_dt_ids, | |
| 628 | 627 | }, |
| 629 | 628 | .probe = max30102_probe, |
| 630 | 629 | .remove = max30102_remove, |
| @@ -632,6 +631,6 @@ static struct i2c_driver max30102_driver = { · 1 unmodified line | ||
| 632 | 631 | }; |
| 633 | 632 | module_i2c_driver(max30102_driver); |
| 634 | 633 | |
| 635 | −MODULE_AUTHOR("Matt Ranostay <matt@ranostay.consulting>"); | |
| 634 | +MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>"); | |
| 636 | 635 | MODULE_DESCRIPTION("MAX30102 heart rate/pulse oximeter and MAX30105 particle sensor driver"); |
| 637 | 636 | MODULE_LICENSE("GPL"); |
| @@ -38,6 +38,16 @@ config HDC100X · 37 unmodified lines | ||
| 38 | 38 | To compile this driver as a module, choose M here: the module |
| 39 | 39 | will be called hdc100x. |
| 40 | 40 | |
| 41 | +config HDC2010 | |
| 42 | + tristate "TI HDC2010 relative humidity and temperature sensor" | |
| 43 | + depends on I2C | |
| 44 | + help | |
| 45 | + Say yes here to build support for the Texas Instruments | |
| 46 | + HDC2010 and HDC2080 relative humidity and temperature sensors. | |
| 47 | + | |
| 48 | + To compile this driver as a module, choose M here: the module | |
| 49 | + will be called hdc2010. | |
| 50 | + | |
| 41 | 51 | config HID_SENSOR_HUMIDITY |
| 42 | 52 | tristate "HID Environmental humidity sensor" |
| 43 | 53 | depends on HID_SENSOR_HUB |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | obj-$(CONFIG_AM2315) += am2315.o |
| 7 | 7 | obj-$(CONFIG_DHT11) += dht11.o |
| 8 | 8 | obj-$(CONFIG_HDC100X) += hdc100x.o |
| 9 | +obj-$(CONFIG_HDC2010) += hdc2010.o | |
| 9 | 10 | obj-$(CONFIG_HID_SENSOR_HUMIDITY) += hid-sensor-humidity.o |
| 10 | 11 | |
| 11 | 12 | hts221-y := hts221_core.o \ |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | |
| 16 | 16 | #include <linux/delay.h> |
| 17 | 17 | #include <linux/module.h> |
| 18 | +#include <linux/mod_devicetable.h> | |
| 18 | 19 | #include <linux/init.h> |
| 19 | 20 | #include <linux/i2c.h> |
| 20 | 21 | |
| @@ -417,7 +418,7 @@ MODULE_DEVICE_TABLE(of, hdc100x_dt_ids); · 396 unmodified lines | ||
| 417 | 418 | static struct i2c_driver hdc100x_driver = { |
| 418 | 419 | .driver = { |
| 419 | 420 | .name = "hdc100x", |
| 420 | − .of_match_table = of_match_ptr(hdc100x_dt_ids), | |
| 421 | + .of_match_table = hdc100x_dt_ids, | |
| 421 | 422 | }, |
| 422 | 423 | .probe = hdc100x_probe, |
| 423 | 424 | .id_table = hdc100x_id, |
| @@ -0,0 +1,353 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0+ | |
| 2 | +/* | |
| 3 | + * hdc2010.c - Support for the TI HDC2010 and HDC2080 | |
| 4 | + * temperature + relative humidity sensors | |
| 5 | + * | |
| 6 | + * Copyright (C) 2020 Norphonic AS | |
| 7 | + * Author: Eugene Zaikonnikov <ez@norphonic.com> | |
| 8 | + * | |
| 9 | + * Datasheet: https://www.ti.com/product/HDC2010/datasheet | |
| 10 | + * Datasheet: https://www.ti.com/product/HDC2080/datasheet | |
| 11 | + */ | |
| 12 | + | |
| 13 | +#include <linux/module.h> | |
| 14 | +#include <linux/init.h> | |
| 15 | +#include <linux/i2c.h> | |
| 16 | +#include <linux/bitops.h> | |
| 17 | + | |
| 18 | +#include <linux/iio/iio.h> | |
| 19 | +#include <linux/iio/sysfs.h> | |
| 20 | + | |
| 21 | +#define HDC2010_REG_TEMP_LOW 0x00 | |
| 22 | +#define HDC2010_REG_TEMP_HIGH 0x01 | |
| 23 | +#define HDC2010_REG_HUMIDITY_LOW 0x02 | |
| 24 | +#define HDC2010_REG_HUMIDITY_HIGH 0x03 | |
| 25 | +#define HDC2010_REG_INTERRUPT_DRDY 0x04 | |
| 26 | +#define HDC2010_REG_TEMP_MAX 0x05 | |
| 27 | +#define HDC2010_REG_HUMIDITY_MAX 0x06 | |
| 28 | +#define HDC2010_REG_INTERRUPT_EN 0x07 | |
| 29 | +#define HDC2010_REG_TEMP_OFFSET_ADJ 0x08 | |
| 30 | +#define HDC2010_REG_HUMIDITY_OFFSET_ADJ 0x09 | |
| 31 | +#define HDC2010_REG_TEMP_THR_L 0x0a | |
| 32 | +#define HDC2010_REG_TEMP_THR_H 0x0b | |
| 33 | +#define HDC2010_REG_RH_THR_L 0x0c | |
| 34 | +#define HDC2010_REG_RH_THR_H 0x0d | |
| 35 | +#define HDC2010_REG_RESET_DRDY_INT_CONF 0x0e | |
| 36 | +#define HDC2010_REG_MEASUREMENT_CONF 0x0f | |
| 37 | + | |
| 38 | +#define HDC2010_MEAS_CONF GENMASK(2, 1) | |
| 39 | +#define HDC2010_MEAS_TRIG BIT(0) | |
| 40 | +#define HDC2010_HEATER_EN BIT(3) | |
| 41 | +#define HDC2010_AMM GENMASK(6, 4) | |
| 42 | + | |
| 43 | +struct hdc2010_data { | |
| 44 | + struct i2c_client *client; | |
| 45 | + struct mutex lock; | |
| 46 | + u8 measurement_config; | |
| 47 | + u8 interrupt_config; | |
| 48 | + u8 drdy_config; | |
| 49 | +}; | |
| 50 | + | |
| 51 | +enum hdc2010_addr_groups { | |
| 52 | + HDC2010_GROUP_TEMP = 0, | |
| 53 | + HDC2010_GROUP_HUMIDITY, | |
| 54 | +}; | |
| 55 | + | |
| 56 | +struct hdc2010_reg_record { | |
| 57 | + unsigned long primary; | |
| 58 | + unsigned long peak; | |
| 59 | +}; | |
| 60 | + | |
| 61 | +static const struct hdc2010_reg_record hdc2010_reg_translation[] = { | |
| 62 | + [HDC2010_GROUP_TEMP] = { | |
| 63 | + .primary = HDC2010_REG_TEMP_LOW, | |
| 64 | + .peak = HDC2010_REG_TEMP_MAX, | |
| 65 | + }, | |
| 66 | + [HDC2010_GROUP_HUMIDITY] = { | |
| 67 | + .primary = HDC2010_REG_HUMIDITY_LOW, | |
| 68 | + .peak = HDC2010_REG_HUMIDITY_MAX, | |
| 69 | + }, | |
| 70 | +}; | |
| 71 | + | |
| 72 | +static IIO_CONST_ATTR(out_current_heater_raw_available, "0 1"); | |
| 73 | + | |
| 74 | +static struct attribute *hdc2010_attributes[] = { | |
| 75 | + &iio_const_attr_out_current_heater_raw_available.dev_attr.attr, | |
| 76 | + NULL | |
| 77 | +}; | |
| 78 | + | |
| 79 | +static const struct attribute_group hdc2010_attribute_group = { | |
| 80 | + .attrs = hdc2010_attributes, | |
| 81 | +}; | |
| 82 | + | |
| 83 | +static const struct iio_chan_spec hdc2010_channels[] = { | |
| 84 | + { | |
| 85 | + .type = IIO_TEMP, | |
| 86 | + .address = HDC2010_GROUP_TEMP, | |
| 87 | + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | | |
| 88 | + BIT(IIO_CHAN_INFO_PEAK) | | |
| 89 | + BIT(IIO_CHAN_INFO_OFFSET) | | |
| 90 | + BIT(IIO_CHAN_INFO_SCALE), | |
| 91 | + }, | |
| 92 | + { | |
| 93 | + .type = IIO_HUMIDITYRELATIVE, | |
| 94 | + .address = HDC2010_GROUP_HUMIDITY, | |
| 95 | + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | | |
| 96 | + BIT(IIO_CHAN_INFO_PEAK) | | |
| 97 | + BIT(IIO_CHAN_INFO_SCALE), | |
| 98 | + }, | |
| 99 | + { | |
| 100 | + .type = IIO_CURRENT, | |
| 101 | + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), | |
| 102 | + .extend_name = "heater", | |
| 103 | + .output = 1, | |
| 104 | + }, | |
| 105 | +}; | |
| 106 | + | |
| 107 | +static int hdc2010_update_drdy_config(struct hdc2010_data *data, | |
| 108 | + char mask, char val) | |
| 109 | +{ | |
| 110 | + u8 tmp = (~mask & data->drdy_config) | val; | |
| 111 | + int ret; | |
| 112 | + | |
| 113 | + ret = i2c_smbus_write_byte_data(data->client, | |
| 114 | + HDC2010_REG_RESET_DRDY_INT_CONF, tmp); | |
| 115 | + if (ret) | |
| 116 | + return ret; | |
| 117 | + | |
| 118 | + data->drdy_config = tmp; | |
| 119 | + | |
| 120 | + return 0; | |
| 121 | +} | |
| 122 | + | |
| 123 | +static int hdc2010_get_prim_measurement_word(struct hdc2010_data *data, | |
| 124 | + struct iio_chan_spec const *chan) | |
| 125 | +{ | |
| 126 | + struct i2c_client *client = data->client; | |
| 127 | + s32 ret; | |
| 128 | + | |
| 129 | + ret = i2c_smbus_read_word_data(client, | |
| 130 | + hdc2010_reg_translation[chan->address].primary); | |
| 131 | + | |
| 132 | + if (ret < 0) | |
| 133 | + dev_err(&client->dev, "Could not read sensor measurement word\n"); | |
| 134 | + | |
| 135 | + return ret; | |
| 136 | +} | |
| 137 | + | |
| 138 | +static int hdc2010_get_peak_measurement_byte(struct hdc2010_data *data, | |
| 139 | + struct iio_chan_spec const *chan) | |
| 140 | +{ | |
| 141 | + struct i2c_client *client = data->client; | |
| 142 | + s32 ret; | |
| 143 | + | |
| 144 | + ret = i2c_smbus_read_byte_data(client, | |
| 145 | + hdc2010_reg_translation[chan->address].peak); | |
| 146 | + | |
| 147 | + if (ret < 0) | |
| 148 | + dev_err(&client->dev, "Could not read sensor measurement byte\n"); | |
| 149 | + | |
| 150 | + return ret; | |
| 151 | +} | |
| 152 | + | |
| 153 | +static int hdc2010_get_heater_status(struct hdc2010_data *data) | |
| 154 | +{ | |
| 155 | + return !!(data->drdy_config & HDC2010_HEATER_EN); | |
| 156 | +} | |
| 157 | + | |
| 158 | +static int hdc2010_read_raw(struct iio_dev *indio_dev, | |
| 159 | + struct iio_chan_spec const *chan, int *val, | |
| 160 | + int *val2, long mask) | |
| 161 | +{ | |
| 162 | + struct hdc2010_data *data = iio_priv(indio_dev); | |
| 163 | + | |
| 164 | + switch (mask) { | |
| 165 | + case IIO_CHAN_INFO_RAW: { | |
| 166 | + int ret; | |
| 167 | + | |
| 168 | + if (chan->type == IIO_CURRENT) { | |
| 169 | + *val = hdc2010_get_heater_status(data); | |
| 170 | + return IIO_VAL_INT; | |
| 171 | + } | |
| 172 | + ret = iio_device_claim_direct_mode(indio_dev); | |
| 173 | + if (ret) | |
| 174 | + return ret; | |
| 175 | + mutex_lock(&data->lock); | |
| 176 | + ret = hdc2010_get_prim_measurement_word(data, chan); | |
| 177 | + mutex_unlock(&data->lock); | |
| 178 | + iio_device_release_direct_mode(indio_dev); | |
| 179 | + if (ret < 0) | |
| 180 | + return ret; | |
| 181 | + *val = ret; | |
| 182 | + return IIO_VAL_INT; | |
| 183 | + } | |
| 184 | + case IIO_CHAN_INFO_PEAK: { | |
| 185 | + int ret; | |
| 186 | + | |
| 187 | + ret = iio_device_claim_direct_mode(indio_dev); | |
| 188 | + if (ret) | |
| 189 | + return ret; | |
| 190 | + mutex_lock(&data->lock); | |
| 191 | + ret = hdc2010_get_peak_measurement_byte(data, chan); | |
| 192 | + mutex_unlock(&data->lock); | |
| 193 | + iio_device_release_direct_mode(indio_dev); | |
| 194 | + if (ret < 0) | |
| 195 | + return ret; | |
| 196 | + /* Scaling up the value so we can use same offset as RAW */ | |
| 197 | + *val = ret * 256; | |
| 198 | + return IIO_VAL_INT; | |
| 199 | + } | |
| 200 | + case IIO_CHAN_INFO_SCALE: | |
| 201 | + *val2 = 65536; | |
| 202 | + if (chan->type == IIO_TEMP) | |
| 203 | + *val = 165000; | |
| 204 | + else | |
| 205 | + *val = 100000; | |
| 206 | + return IIO_VAL_FRACTIONAL; | |
| 207 | + case IIO_CHAN_INFO_OFFSET: | |
| 208 | + *val = -15887; | |
| 209 | + *val2 = 515151; | |
| 210 | + return IIO_VAL_INT_PLUS_MICRO; | |
| 211 | + default: | |
| 212 | + return -EINVAL; | |
| 213 | + } | |
| 214 | +} | |
| 215 | + | |
| 216 | +static int hdc2010_write_raw(struct iio_dev *indio_dev, | |
| 217 | + struct iio_chan_spec const *chan, | |
| 218 | + int val, int val2, long mask) | |
| 219 | +{ | |
| 220 | + struct hdc2010_data *data = iio_priv(indio_dev); | |
| 221 | + int new, ret; | |
| 222 | + | |
| 223 | + switch (mask) { | |
| 224 | + case IIO_CHAN_INFO_RAW: | |
| 225 | + if (chan->type != IIO_CURRENT || val2 != 0) | |
| 226 | + return -EINVAL; | |
| 227 | + | |
| 228 | + switch (val) { | |
| 229 | + case 1: | |
| 230 | + new = HDC2010_HEATER_EN; | |
| 231 | + break; | |
| 232 | + case 0: | |
| 233 | + new = 0; | |
| 234 | + break; | |
| 235 | + default: | |
| 236 | + return -EINVAL; | |
| 237 | + } | |
| 238 | + | |
| 239 | + mutex_lock(&data->lock); | |
| 240 | + ret = hdc2010_update_drdy_config(data, HDC2010_HEATER_EN, new); | |
| 241 | + mutex_unlock(&data->lock); | |
| 242 | + return ret; | |
| 243 | + default: | |
| 244 | + return -EINVAL; | |
| 245 | + } | |
| 246 | +} | |
| 247 | + | |
| 248 | +static const struct iio_info hdc2010_info = { | |
| 249 | + .read_raw = hdc2010_read_raw, | |
| 250 | + .write_raw = hdc2010_write_raw, | |
| 251 | + .attrs = &hdc2010_attribute_group, | |
| 252 | +}; | |
| 253 | + | |
| 254 | +static int hdc2010_probe(struct i2c_client *client, | |
| 255 | + const struct i2c_device_id *id) | |
| 256 | +{ | |
| 257 | + struct iio_dev *indio_dev; | |
| 258 | + struct hdc2010_data *data; | |
| 259 | + u8 tmp; | |
| 260 | + int ret; | |
| 261 | + | |
| 262 | + if (!i2c_check_functionality(client->adapter, | |
| 263 | + I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C)) | |
| 264 | + return -EOPNOTSUPP; | |
| 265 | + | |
| 266 | + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); | |
| 267 | + if (!indio_dev) | |
| 268 | + return -ENOMEM; | |
| 269 | + | |
| 270 | + data = iio_priv(indio_dev); | |
| 271 | + i2c_set_clientdata(client, indio_dev); | |
| 272 | + data->client = client; | |
| 273 | + mutex_init(&data->lock); | |
| 274 | + | |
| 275 | + indio_dev->dev.parent = &client->dev; | |
| 276 | + /* | |
| 277 | + * As DEVICE ID register does not differentiate between | |
| 278 | + * HDC2010 and HDC2080, we have the name hardcoded | |
| 279 | + */ | |
| 280 | + indio_dev->name = "hdc2010"; | |
| 281 | + indio_dev->modes = INDIO_DIRECT_MODE; | |
| 282 | + indio_dev->info = &hdc2010_info; | |
| 283 | + | |
| 284 | + indio_dev->channels = hdc2010_channels; | |
| 285 | + indio_dev->num_channels = ARRAY_SIZE(hdc2010_channels); | |
| 286 | + | |
| 287 | + /* Enable Automatic Measurement Mode at 5Hz */ | |
| 288 | + ret = hdc2010_update_drdy_config(data, HDC2010_AMM, HDC2010_AMM); | |
| 289 | + if (ret) | |
| 290 | + return ret; | |
| 291 | + | |
| 292 | + /* | |
| 293 | + * We enable both temp and humidity measurement. | |
| 294 | + * However the measurement won't start even in AMM until triggered. | |
| 295 | + */ | |
| 296 | + tmp = (data->measurement_config & ~HDC2010_MEAS_CONF) | | |
| 297 | + HDC2010_MEAS_TRIG; | |
| 298 | + | |
| 299 | + ret = i2c_smbus_write_byte_data(client, HDC2010_REG_MEASUREMENT_CONF, tmp); | |
| 300 | + if (ret) { | |
| 301 | + dev_warn(&client->dev, "Unable to set up measurement\n"); | |
| 302 | + if (hdc2010_update_drdy_config(data, HDC2010_AMM, 0)) | |
| 303 | + dev_warn(&client->dev, "Unable to restore default AMM\n"); | |
| 304 | + return ret; | |
| 305 | + } | |
| 306 | + | |
| 307 | + data->measurement_config = tmp; | |
| 308 | + | |
| 309 | + return iio_device_register(indio_dev); | |
| 310 | +} | |
| 311 | + | |
| 312 | +static int hdc2010_remove(struct i2c_client *client) | |
| 313 | +{ | |
| 314 | + struct iio_dev *indio_dev = i2c_get_clientdata(client); | |
| 315 | + struct hdc2010_data *data = iio_priv(indio_dev); | |
| 316 | + | |
| 317 | + iio_device_unregister(indio_dev); | |
| 318 | + | |
| 319 | + /* Disable Automatic Measurement Mode */ | |
| 320 | + if (hdc2010_update_drdy_config(data, HDC2010_AMM, 0)) | |
| 321 | + dev_warn(&client->dev, "Unable to restore default AMM\n"); | |
| 322 | + | |
| 323 | + return 0; | |
| 324 | +} | |
| 325 | + | |
| 326 | +static const struct i2c_device_id hdc2010_id[] = { | |
| 327 | + { "hdc2010" }, | |
| 328 | + { "hdc2080" }, | |
| 329 | + { } | |
| 330 | +}; | |
| 331 | +MODULE_DEVICE_TABLE(i2c, hdc2010_id); | |
| 332 | + | |
| 333 | +static const struct of_device_id hdc2010_dt_ids[] = { | |
| 334 | + { .compatible = "ti,hdc2010" }, | |
| 335 | + { .compatible = "ti,hdc2080" }, | |
| 336 | + { } | |
| 337 | +}; | |
| 338 | +MODULE_DEVICE_TABLE(of, hdc2010_dt_ids); | |
| 339 | + | |
| 340 | +static struct i2c_driver hdc2010_driver = { | |
| 341 | + .driver = { | |
| 342 | + .name = "hdc2010", | |
| 343 | + .of_match_table = hdc2010_dt_ids, | |
| 344 | + }, | |
| 345 | + .probe = hdc2010_probe, | |
| 346 | + .remove = hdc2010_remove, | |
| 347 | + .id_table = hdc2010_id, | |
| 348 | +}; | |
| 349 | +module_i2c_driver(hdc2010_driver); | |
| 350 | + | |
| 351 | +MODULE_AUTHOR("Eugene Zaikonnikov <ez@norphonic.com>"); | |
| 352 | +MODULE_DESCRIPTION("TI HDC2010 humidity and temperature sensor driver"); | |
| 353 | +MODULE_LICENSE("GPL"); | |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | #include <linux/kernel.h> |
| 20 | 20 | #include <linux/stat.h> |
| 21 | 21 | #include <linux/module.h> |
| 22 | +#include <linux/mod_devicetable.h> | |
| 22 | 23 | #include <linux/iio/iio.h> |
| 23 | 24 | #include <linux/iio/sysfs.h> |
| 24 | 25 | |
| @@ -247,7 +248,7 @@ static struct i2c_driver htu21_driver = { · 222 unmodified lines | ||
| 247 | 248 | .id_table = htu21_id, |
| 248 | 249 | .driver = { |
| 249 | 250 | .name = "htu21", |
| 250 | − .of_match_table = of_match_ptr(htu21_of_match), | |
| 251 | + .of_match_table = htu21_of_match, | |
| 251 | 252 | }, |
| 252 | 253 | }; |
| 253 | 254 | |
| @@ -20,6 +20,7 @@ · 19 unmodified lines | ||
| 20 | 20 | #include <linux/delay.h> |
| 21 | 21 | #include <linux/i2c.h> |
| 22 | 22 | #include <linux/module.h> |
| 23 | +#include <linux/mod_devicetable.h> | |
| 23 | 24 | #include <linux/slab.h> |
| 24 | 25 | #include <linux/sysfs.h> |
| 25 | 26 | |
| @@ -153,7 +154,7 @@ MODULE_DEVICE_TABLE(of, si7020_dt_ids); · 127 unmodified lines | ||
| 153 | 154 | static struct i2c_driver si7020_driver = { |
| 154 | 155 | .driver = { |
| 155 | 156 | .name = "si7020", |
| 156 | − .of_match_table = of_match_ptr(si7020_dt_ids), | |
| 157 | + .of_match_table = si7020_dt_ids, | |
| 157 | 158 | }, |
| 158 | 159 | .probe = si7020_probe, |
| 159 | 160 | .id_table = si7020_id, |
| @@ -30,7 +30,7 @@ int iio_trigger_detach_poll_func(struct iio_trigger *trig, · 29 unmodified lines | ||
| 30 | 30 | * iio_device_register_trigger_consumer() - set up an iio_dev to use triggers |
| 31 | 31 | * @indio_dev: iio_dev associated with the device that will consume the trigger |
| 32 | 32 | **/ |
| 33 | −static int iio_device_register_trigger_consumer(struct iio_dev *indio_dev) | |
| 33 | +static inline int iio_device_register_trigger_consumer(struct iio_dev *indio_dev) | |
| 34 | 34 | { |
| 35 | 35 | return 0; |
| 36 | 36 | } |
| @@ -39,7 +39,7 @@ static int iio_device_register_trigger_consumer(struct iio_dev *indio_dev) · 2 unmodified lines | ||
| 39 | 39 | * iio_device_unregister_trigger_consumer() - reverse the registration process |
| 40 | 40 | * @indio_dev: iio_dev associated with the device that consumed the trigger |
| 41 | 41 | **/ |
| 42 | −static void iio_device_unregister_trigger_consumer(struct iio_dev *indio_dev) | |
| 42 | +static inline void iio_device_unregister_trigger_consumer(struct iio_dev *indio_dev) | |
| 43 | 43 | { |
| 44 | 44 | } |
| 45 | 45 | |
| @@ -173,6 +173,8 @@ struct adis16400_chip_info { · 172 unmodified lines | ||
| 173 | 173 | * @variant: chip variant info |
| 174 | 174 | * @filt_int: integer part of requested filter frequency |
| 175 | 175 | * @adis: adis device |
| 176 | + * @avail_scan_mask: NULL terminated array of bitmaps of channels | |
| 177 | + * that must be enabled together | |
| 176 | 178 | **/ |
| 177 | 179 | struct adis16400_state { |
| 178 | 180 | struct adis16400_chip_info *variant; |
| @@ -317,11 +319,6 @@ enum adis16400_chip_variant { · 138 unmodified lines | ||
| 317 | 319 | ADIS16448, |
| 318 | 320 | }; |
| 319 | 321 | |
| 320 | −static struct adis_burst adis16400_burst = { | |
| 321 | − .en = true, | |
| 322 | − .reg_cmd = ADIS16400_GLOB_CMD, | |
| 323 | −}; | |
| 324 | − | |
| 325 | 322 | static int adis16334_get_freq(struct adis16400_state *st) |
| 326 | 323 | { |
| 327 | 324 | int ret; |
| @@ -947,7 +944,7 @@ static const char * const adis16400_status_error_msgs[] = { · 619 unmodified lines | ||
| 947 | 944 | [ADIS16400_DIAG_STAT_POWER_LOW] = "Power supply below 4.75V", |
| 948 | 945 | }; |
| 949 | 946 | |
| 950 | −#define ADIS16400_DATA(_timeouts) \ | |
| 947 | +#define ADIS16400_DATA(_timeouts, _burst_len) \ | |
| 951 | 948 | { \ |
| 952 | 949 | .msc_ctrl_reg = ADIS16400_MSC_CTRL, \ |
| 953 | 950 | .glob_cmd_reg = ADIS16400_GLOB_CMD, \ |
| @@ -973,6 +970,8 @@ static const char * const adis16400_status_error_msgs[] = { · 19 unmodified lines | ||
| 973 | 970 | BIT(ADIS16400_DIAG_STAT_POWER_HIGH) | \ |
| 974 | 971 | BIT(ADIS16400_DIAG_STAT_POWER_LOW), \ |
| 975 | 972 | .timeouts = (_timeouts), \ |
| 973 | + .burst_reg_cmd = ADIS16400_GLOB_CMD, \ | |
| 974 | + .burst_len = (_burst_len) \ | |
| 976 | 975 | } |
| 977 | 976 | |
| 978 | 977 | static const struct adis_timeout adis16300_timeouts = { |
| @@ -1023,7 +1022,7 @@ static struct adis16400_chip_info adis16400_chips[] = { · 44 unmodified lines | ||
| 1023 | 1022 | .temp_offset = 25000000 / 140000, /* 25 C = 0x00 */ |
| 1024 | 1023 | .set_freq = adis16400_set_freq, |
| 1025 | 1024 | .get_freq = adis16400_get_freq, |
| 1026 | − .adis_data = ADIS16400_DATA(&adis16300_timeouts), | |
| 1025 | + .adis_data = ADIS16400_DATA(&adis16300_timeouts, 18), | |
| 1027 | 1026 | }, |
| 1028 | 1027 | [ADIS16334] = { |
| 1029 | 1028 | .channels = adis16334_channels, |
| @@ -1036,7 +1035,7 @@ static struct adis16400_chip_info adis16400_chips[] = { · 6 unmodified lines | ||
| 1036 | 1035 | .temp_offset = 25000000 / 67850, /* 25 C = 0x00 */ |
| 1037 | 1036 | .set_freq = adis16334_set_freq, |
| 1038 | 1037 | .get_freq = adis16334_get_freq, |
| 1039 | − .adis_data = ADIS16400_DATA(&adis16334_timeouts), | |
| 1038 | + .adis_data = ADIS16400_DATA(&adis16334_timeouts, 0), | |
| 1040 | 1039 | }, |
| 1041 | 1040 | [ADIS16350] = { |
| 1042 | 1041 | .channels = adis16350_channels, |
| @@ -1048,7 +1047,7 @@ static struct adis16400_chip_info adis16400_chips[] = { · 5 unmodified lines | ||
| 1048 | 1047 | .flags = ADIS16400_NO_BURST | ADIS16400_HAS_SLOW_MODE, |
| 1049 | 1048 | .set_freq = adis16400_set_freq, |
| 1050 | 1049 | .get_freq = adis16400_get_freq, |
| 1051 | − .adis_data = ADIS16400_DATA(&adis16300_timeouts), | |
| 1050 | + .adis_data = ADIS16400_DATA(&adis16300_timeouts, 0), | |
| 1052 | 1051 | }, |
| 1053 | 1052 | [ADIS16360] = { |
| 1054 | 1053 | .channels = adis16350_channels, |
| @@ -1061,7 +1060,7 @@ static struct adis16400_chip_info adis16400_chips[] = { · 6 unmodified lines | ||
| 1061 | 1060 | .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ |
| 1062 | 1061 | .set_freq = adis16400_set_freq, |
| 1063 | 1062 | .get_freq = adis16400_get_freq, |
| 1064 | − .adis_data = ADIS16400_DATA(&adis16300_timeouts), | |
| 1063 | + .adis_data = ADIS16400_DATA(&adis16300_timeouts, 28), | |
| 1065 | 1064 | }, |
| 1066 | 1065 | [ADIS16362] = { |
| 1067 | 1066 | .channels = adis16350_channels, |
| @@ -1074,7 +1073,7 @@ static struct adis16400_chip_info adis16400_chips[] = { · 6 unmodified lines | ||
| 1074 | 1073 | .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ |
| 1075 | 1074 | .set_freq = adis16400_set_freq, |
| 1076 | 1075 | .get_freq = adis16400_get_freq, |
| 1077 | − .adis_data = ADIS16400_DATA(&adis16362_timeouts), | |
| 1076 | + .adis_data = ADIS16400_DATA(&adis16362_timeouts, 28), | |
| 1078 | 1077 | }, |
| 1079 | 1078 | [ADIS16364] = { |
| 1080 | 1079 | .channels = adis16350_channels, |
| @@ -1087,7 +1086,7 @@ static struct adis16400_chip_info adis16400_chips[] = { · 6 unmodified lines | ||
| 1087 | 1086 | .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ |
| 1088 | 1087 | .set_freq = adis16400_set_freq, |
| 1089 | 1088 | .get_freq = adis16400_get_freq, |
| 1090 | − .adis_data = ADIS16400_DATA(&adis16362_timeouts), | |
| 1089 | + .adis_data = ADIS16400_DATA(&adis16362_timeouts, 28), | |
| 1091 | 1090 | }, |
| 1092 | 1091 | [ADIS16367] = { |
| 1093 | 1092 | .channels = adis16350_channels, |
| @@ -1100,7 +1099,7 @@ static struct adis16400_chip_info adis16400_chips[] = { · 6 unmodified lines | ||
| 1100 | 1099 | .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ |
| 1101 | 1100 | .set_freq = adis16400_set_freq, |
| 1102 | 1101 | .get_freq = adis16400_get_freq, |
| 1103 | − .adis_data = ADIS16400_DATA(&adis16300_timeouts), | |
| 1102 | + .adis_data = ADIS16400_DATA(&adis16300_timeouts, 28), | |
| 1104 | 1103 | }, |
| 1105 | 1104 | [ADIS16400] = { |
| 1106 | 1105 | .channels = adis16400_channels, |
| @@ -1112,7 +1111,7 @@ static struct adis16400_chip_info adis16400_chips[] = { · 5 unmodified lines | ||
| 1112 | 1111 | .temp_offset = 25000000 / 140000, /* 25 C = 0x00 */ |
| 1113 | 1112 | .set_freq = adis16400_set_freq, |
| 1114 | 1113 | .get_freq = adis16400_get_freq, |
| 1115 | − .adis_data = ADIS16400_DATA(&adis16400_timeouts), | |
| 1114 | + .adis_data = ADIS16400_DATA(&adis16400_timeouts, 24), | |
| 1116 | 1115 | }, |
| 1117 | 1116 | [ADIS16445] = { |
| 1118 | 1117 | .channels = adis16445_channels, |
| @@ -1126,7 +1125,7 @@ static struct adis16400_chip_info adis16400_chips[] = { · 7 unmodified lines | ||
| 1126 | 1125 | .temp_offset = 31000000 / 73860, /* 31 C = 0x00 */ |
| 1127 | 1126 | .set_freq = adis16334_set_freq, |
| 1128 | 1127 | .get_freq = adis16334_get_freq, |
| 1129 | − .adis_data = ADIS16400_DATA(&adis16445_timeouts), | |
| 1128 | + .adis_data = ADIS16400_DATA(&adis16445_timeouts, 16), | |
| 1130 | 1129 | }, |
| 1131 | 1130 | [ADIS16448] = { |
| 1132 | 1131 | .channels = adis16448_channels, |
| @@ -1140,7 +1139,7 @@ static struct adis16400_chip_info adis16400_chips[] = { · 7 unmodified lines | ||
| 1140 | 1139 | .temp_offset = 31000000 / 73860, /* 31 C = 0x00 */ |
| 1141 | 1140 | .set_freq = adis16334_set_freq, |
| 1142 | 1141 | .get_freq = adis16334_get_freq, |
| 1143 | − .adis_data = ADIS16400_DATA(&adis16448_timeouts), | |
| 1142 | + .adis_data = ADIS16400_DATA(&adis16448_timeouts, 24), | |
| 1144 | 1143 | } |
| 1145 | 1144 | }; |
| 1146 | 1145 | |
| @@ -1164,6 +1163,12 @@ static void adis16400_setup_chan_mask(struct adis16400_state *st) · 17 unmodified lines | ||
| 1164 | 1163 | st->avail_scan_mask[0] |= BIT(ch->scan_index); |
| 1165 | 1164 | } |
| 1166 | 1165 | } |
| 1166 | + | |
| 1167 | +static void adis16400_stop(void *data) | |
| 1168 | +{ | |
| 1169 | + adis16400_stop_device(data); | |
| 1170 | +} | |
| 1171 | + | |
| 1167 | 1172 | static int adis16400_probe(struct spi_device *spi) |
| 1168 | 1173 | { |
| 1169 | 1174 | struct adis16400_state *st; |
| @@ -1190,9 +1195,6 @@ static int adis16400_probe(struct spi_device *spi) · 20 unmodified lines | ||
| 1190 | 1195 | if (!(st->variant->flags & ADIS16400_NO_BURST)) { |
| 1191 | 1196 | adis16400_setup_chan_mask(st); |
| 1192 | 1197 | indio_dev->available_scan_masks = st->avail_scan_mask; |
| 1193 | − st->adis.burst = &adis16400_burst; | |
| 1194 | − if (st->variant->flags & ADIS16400_BURST_DIAG_STAT) | |
| 1195 | − st->adis.burst_extra_len = sizeof(u16); | |
| 1196 | 1198 | } |
| 1197 | 1199 | |
| 1198 | 1200 | adis16400_data = &st->variant->adis_data; |
| @@ -1201,37 +1203,24 @@ static int adis16400_probe(struct spi_device *spi) · 2 unmodified lines | ||
| 1201 | 1203 | if (ret) |
| 1202 | 1204 | return ret; |
| 1203 | 1205 | |
| 1204 | − ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, | |
| 1205 | − adis16400_trigger_handler); | |
| 1206 | + ret = devm_adis_setup_buffer_and_trigger(&st->adis, indio_dev, adis16400_trigger_handler); | |
| 1206 | 1207 | if (ret) |
| 1207 | 1208 | return ret; |
| 1208 | 1209 | |
| 1209 | 1210 | /* Get the device into a sane initial state */ |
| 1210 | 1211 | ret = adis16400_initial_setup(indio_dev); |
| 1211 | 1212 | if (ret) |
| 1212 | − goto error_cleanup_buffer; | |
| 1213 | − ret = iio_device_register(indio_dev); | |
| 1214 | − if (ret) | |
| 1215 | − goto error_cleanup_buffer; | |
| 1216 | − | |
| 1217 | − adis16400_debugfs_init(indio_dev); | |
| 1218 | − return 0; | |
| 1219 | − | |
| 1220 | −error_cleanup_buffer: | |
| 1221 | − adis_cleanup_buffer_and_trigger(&st->adis, indio_dev); | |
| 1222 | − return ret; | |
| 1223 | −} | |
| 1224 | − | |
| 1225 | −static int adis16400_remove(struct spi_device *spi) | |
| 1226 | −{ | |
| 1227 | − struct iio_dev *indio_dev = spi_get_drvdata(spi); | |
| 1228 | − struct adis16400_state *st = iio_priv(indio_dev); | |
| 1213 | + return ret; | |
| 1229 | 1214 | |
| 1230 | − iio_device_unregister(indio_dev); | |
| 1231 | − adis16400_stop_device(indio_dev); | |
| 1215 | + ret = devm_add_action_or_reset(&spi->dev, adis16400_stop, indio_dev); | |
| 1216 | + if (ret) | |
| 1217 | + return ret; | |
| 1232 | 1218 | |
| 1233 | − adis_cleanup_buffer_and_trigger(&st->adis, indio_dev); | |
| 1219 | + ret = devm_iio_device_register(&spi->dev, indio_dev); | |
| 1220 | + if (ret) | |
| 1221 | + return ret; | |
| 1234 | 1222 | |
| 1223 | + adis16400_debugfs_init(indio_dev); | |
| 1235 | 1224 | return 0; |
| 1236 | 1225 | } |
| 1237 | 1226 | |
| @@ -1261,7 +1250,6 @@ static struct spi_driver adis16400_driver = { · 23 unmodified lines | ||
| 1261 | 1250 | }, |
| 1262 | 1251 | .id_table = adis16400_id, |
| 1263 | 1252 | .probe = adis16400_probe, |
| 1264 | − .remove = adis16400_remove, | |
| 1265 | 1253 | }; |
| 1266 | 1254 | module_spi_driver(adis16400_driver); |
| 1267 | 1255 | |
| @@ -403,7 +403,7 @@ static int adis16460_probe(struct spi_device *spi) · 402 unmodified lines | ||
| 403 | 403 | if (ret) |
| 404 | 404 | return ret; |
| 405 | 405 | |
| 406 | − ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL); | |
| 406 | + ret = devm_adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL); | |
| 407 | 407 | if (ret) |
| 408 | 408 | return ret; |
| 409 | 409 | |
| @@ -411,30 +411,14 @@ static int adis16460_probe(struct spi_device *spi) · 1 unmodified line | ||
| 411 | 411 | |
| 412 | 412 | ret = __adis_initial_startup(&st->adis); |
| 413 | 413 | if (ret) |
| 414 | − goto error_cleanup_buffer; | |
| 414 | + return ret; | |
| 415 | 415 | |
| 416 | − ret = iio_device_register(indio_dev); | |
| 416 | + ret = devm_iio_device_register(&spi->dev, indio_dev); | |
| 417 | 417 | if (ret) |
| 418 | − goto error_cleanup_buffer; | |
| 418 | + return ret; | |
| 419 | 419 | |
| 420 | 420 | adis16460_debugfs_init(indio_dev); |
| 421 | 421 | |
| 422 | − return 0; | |
| 423 | − | |
| 424 | −error_cleanup_buffer: | |
| 425 | − adis_cleanup_buffer_and_trigger(&st->adis, indio_dev); | |
| 426 | − return ret; | |
| 427 | −} | |
| 428 | − | |
| 429 | −static int adis16460_remove(struct spi_device *spi) | |
| 430 | −{ | |
| 431 | − struct iio_dev *indio_dev = spi_get_drvdata(spi); | |
| 432 | − struct adis16460 *st = iio_priv(indio_dev); | |
| 433 | − | |
| 434 | − iio_device_unregister(indio_dev); | |
| 435 | − | |
| 436 | − adis_cleanup_buffer_and_trigger(&st->adis, indio_dev); | |
| 437 | − | |
| 438 | 422 | return 0; |
| 439 | 423 | } |
| 440 | 424 | |
| @@ -457,7 +441,6 @@ static struct spi_driver adis16460_driver = { · 16 unmodified lines | ||
| 457 | 441 | }, |
| 458 | 442 | .id_table = adis16460_ids, |
| 459 | 443 | .probe = adis16460_probe, |
| 460 | − .remove = adis16460_remove, | |
| 461 | 444 | }; |
| 462 | 445 | module_spi_driver(adis16460_driver); |
| 463 | 446 | |
| @@ -565,6 +565,9 @@ static int adis16475_enable_irq(struct adis *adis, bool enable) · 564 unmodified lines | ||
| 565 | 565 | BIT(ADIS16475_DIAG_STAT_CLK), \ |
| 566 | 566 | .enable_irq = adis16475_enable_irq, \ |
| 567 | 567 | .timeouts = (_timeouts), \ |
| 568 | + .burst_reg_cmd = ADIS16475_REG_GLOB_CMD, \ | |
| 569 | + .burst_len = ADIS16475_BURST_MAX_DATA, \ | |
| 570 | + .burst_max_len = ADIS16475_BURST32_MAX_DATA \ | |
| 568 | 571 | } |
| 569 | 572 | |
| 570 | 573 | static const struct adis16475_sync adis16475_sync_mode[] = { |
| @@ -910,20 +913,6 @@ static const struct iio_info adis16475_info = { · 339 unmodified lines | ||
| 910 | 913 | .debugfs_reg_access = adis_debugfs_reg_access, |
| 911 | 914 | }; |
| 912 | 915 | |
| 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 | 916 | static bool adis16475_validate_crc(const u8 *buffer, u16 crc, |
| 928 | 917 | const bool burst32) |
| 929 | 918 | { |
| @@ -1279,7 +1268,6 @@ static int adis16475_probe(struct spi_device *spi) · 349 unmodified lines | ||
| 1279 | 1268 | |
| 1280 | 1269 | st = iio_priv(indio_dev); |
| 1281 | 1270 | spi_set_drvdata(spi, indio_dev); |
| 1282 | − st->adis.burst = &adis16475_burst; | |
| 1283 | 1271 | |
| 1284 | 1272 | st->info = device_get_match_data(&spi->dev); |
| 1285 | 1273 | if (!st->info) |
| @@ -1212,6 +1212,16 @@ static int adis16480_get_ext_clocks(struct adis16480 *st) · 1211 unmodified lines | ||
| 1212 | 1212 | return 0; |
| 1213 | 1213 | } |
| 1214 | 1214 | |
| 1215 | +static void adis16480_stop(void *data) | |
| 1216 | +{ | |
| 1217 | + adis16480_stop_device(data); | |
| 1218 | +} | |
| 1219 | + | |
| 1220 | +static void adis16480_clk_disable(void *data) | |
| 1221 | +{ | |
| 1222 | + clk_disable_unprepare(data); | |
| 1223 | +} | |
| 1224 | + | |
| 1215 | 1225 | static int adis16480_probe(struct spi_device *spi) |
| 1216 | 1226 | { |
| 1217 | 1227 | const struct spi_device_id *id = spi_get_device_id(spi); |
| @@ -1245,18 +1255,26 @@ static int adis16480_probe(struct spi_device *spi) · 27 unmodified lines | ||
| 1245 | 1255 | if (ret) |
| 1246 | 1256 | return ret; |
| 1247 | 1257 | |
| 1258 | + ret = devm_add_action_or_reset(&spi->dev, adis16480_stop, indio_dev); | |
| 1259 | + if (ret) | |
| 1260 | + return ret; | |
| 1261 | + | |
| 1248 | 1262 | ret = adis16480_config_irq_pin(spi->dev.of_node, st); |
| 1249 | 1263 | if (ret) |
| 1250 | − goto error_stop_device; | |
| 1264 | + return ret; | |
| 1251 | 1265 | |
| 1252 | 1266 | ret = adis16480_get_ext_clocks(st); |
| 1253 | 1267 | if (ret) |
| 1254 | − goto error_stop_device; | |
| 1268 | + return ret; | |
| 1255 | 1269 | |
| 1256 | 1270 | if (!IS_ERR_OR_NULL(st->ext_clk)) { |
| 1257 | 1271 | ret = adis16480_ext_clk_config(st, spi->dev.of_node, true); |
| 1258 | 1272 | if (ret) |
| 1259 | − goto error_stop_device; | |
| 1273 | + return ret; | |
| 1274 | + | |
| 1275 | + ret = devm_add_action_or_reset(&spi->dev, adis16480_clk_disable, st->ext_clk); | |
| 1276 | + if (ret) | |
| 1277 | + return ret; | |
| 1260 | 1278 | |
| 1261 | 1279 | st->clk_freq = clk_get_rate(st->ext_clk); |
| 1262 | 1280 | st->clk_freq *= 1000; /* micro */ |
| @@ -1264,38 +1282,16 @@ static int adis16480_probe(struct spi_device *spi) · 1 unmodified line | ||
| 1264 | 1282 | st->clk_freq = st->chip_info->int_clk; |
| 1265 | 1283 | } |
| 1266 | 1284 | |
| 1267 | − ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL); | |
| 1285 | + ret = devm_adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL); | |
| 1268 | 1286 | if (ret) |
| 1269 | − goto error_clk_disable_unprepare; | |
| 1287 | + return ret; | |
| 1270 | 1288 | |
| 1271 | − ret = iio_device_register(indio_dev); | |
| 1289 | + ret = devm_iio_device_register(&spi->dev, indio_dev); | |
| 1272 | 1290 | if (ret) |
| 1273 | − goto error_cleanup_buffer; | |
| 1291 | + return ret; | |
| 1274 | 1292 | |
| 1275 | 1293 | adis16480_debugfs_init(indio_dev); |
| 1276 | 1294 | |
| 1277 | − return 0; | |
| 1278 | − | |
| 1279 | −error_cleanup_buffer: | |
| 1280 | − adis_cleanup_buffer_and_trigger(&st->adis, indio_dev); | |
| 1281 | −error_clk_disable_unprepare: | |
| 1282 | − clk_disable_unprepare(st->ext_clk); | |
| 1283 | −error_stop_device: | |
| 1284 | − adis16480_stop_device(indio_dev); | |
| 1285 | − return ret; | |
| 1286 | −} | |
| 1287 | − | |
| 1288 | −static int adis16480_remove(struct spi_device *spi) | |
| 1289 | −{ | |
| 1290 | − struct iio_dev *indio_dev = spi_get_drvdata(spi); | |
| 1291 | − struct adis16480 *st = iio_priv(indio_dev); | |
| 1292 | − | |
| 1293 | − iio_device_unregister(indio_dev); | |
| 1294 | − adis16480_stop_device(indio_dev); | |
| 1295 | − | |
| 1296 | − adis_cleanup_buffer_and_trigger(&st->adis, indio_dev); | |
| 1297 | − clk_disable_unprepare(st->ext_clk); | |
| 1298 | − | |
| 1299 | 1295 | return 0; |
| 1300 | 1296 | } |
| 1301 | 1297 | |
| @@ -1338,7 +1334,6 @@ static struct spi_driver adis16480_driver = { · 36 unmodified lines | ||
| 1338 | 1334 | }, |
| 1339 | 1335 | .id_table = adis16480_ids, |
| 1340 | 1336 | .probe = adis16480_probe, |
| 1341 | − .remove = adis16480_remove, | |
| 1342 | 1337 | }; |
| 1343 | 1338 | module_spi_driver(adis16480_driver); |
| 1344 | 1339 | |
| @@ -26,12 +26,10 @@ static int adis_update_scan_mode_burst(struct iio_dev *indio_dev, · 25 unmodified lines | ||
| 26 | 26 | unsigned int burst_length, burst_max_length; |
| 27 | 27 | u8 *tx; |
| 28 | 28 | |
| 29 | − /* All but the timestamp channel */ | |
| 30 | − burst_length = (indio_dev->num_channels - 1) * sizeof(u16); | |
| 31 | − burst_length += adis->burst->extra_len + adis->burst_extra_len; | |
| 29 | + burst_length = adis->data->burst_len + adis->burst_extra_len; | |
| 32 | 30 | |
| 33 | − if (adis->burst->burst_max_len) | |
| 34 | − burst_max_length = adis->burst->burst_max_len; | |
| 31 | + if (adis->data->burst_max_len) | |
| 32 | + burst_max_length = adis->data->burst_max_len; | |
| 35 | 33 | else |
| 36 | 34 | burst_max_length = burst_length; |
| 37 | 35 | |
| @@ -47,7 +45,7 @@ static int adis_update_scan_mode_burst(struct iio_dev *indio_dev, · 9 unmodified lines | ||
| 47 | 45 | } |
| 48 | 46 | |
| 49 | 47 | tx = adis->buffer + burst_max_length; |
| 50 | − tx[0] = ADIS_READ_REG(adis->burst->reg_cmd); | |
| 48 | + tx[0] = ADIS_READ_REG(adis->data->burst_reg_cmd); | |
| 51 | 49 | tx[1] = 0; |
| 52 | 50 | |
| 53 | 51 | adis->xfer[0].tx_buf = tx; |
| @@ -76,7 +74,7 @@ int adis_update_scan_mode(struct iio_dev *indio_dev, · 22 unmodified lines | ||
| 76 | 74 | kfree(adis->xfer); |
| 77 | 75 | kfree(adis->buffer); |
| 78 | 76 | |
| 79 | − if (adis->burst && adis->burst->en) | |
| 77 | + if (adis->data->burst_len) | |
| 80 | 78 | return adis_update_scan_mode_burst(indio_dev, scan_mask); |
| 81 | 79 | |
| 82 | 80 | scan_count = indio_dev->scan_bytes / 2; |
| @@ -169,48 +167,6 @@ static void adis_buffer_cleanup(void *arg) · 86 unmodified lines | ||
| 169 | 167 | kfree(adis->xfer); |
| 170 | 168 | } |
| 171 | 169 | |
| 172 | −/** | |
| 173 | − * adis_setup_buffer_and_trigger() - Sets up buffer and trigger for the adis device | |
| 174 | − * @adis: The adis device. | |
| 175 | − * @indio_dev: The IIO device. | |
| 176 | − * @trigger_handler: Optional trigger handler, may be NULL. | |
| 177 | − * | |
| 178 | − * Returns 0 on success, a negative error code otherwise. | |
| 179 | − * | |
| 180 | − * This function sets up the buffer and trigger for a adis devices. If | |
| 181 | − * 'trigger_handler' is NULL the default trigger handler will be used. The | |
| 182 | − * default trigger handler will simply read the registers assigned to the | |
| 183 | − * currently active channels. | |
| 184 | − * | |
| 185 | − * adis_cleanup_buffer_and_trigger() should be called to free the resources | |
| 186 | − * allocated by this function. | |
| 187 | − */ | |
| 188 | −int adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, | |
| 189 | − irqreturn_t (*trigger_handler)(int, void *)) | |
| 190 | −{ | |
| 191 | − int ret; | |
| 192 | − | |
| 193 | − if (!trigger_handler) | |
| 194 | − trigger_handler = adis_trigger_handler; | |
| 195 | − | |
| 196 | − ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, | |
| 197 | − trigger_handler, NULL); | |
| 198 | − if (ret) | |
| 199 | − return ret; | |
| 200 | − | |
| 201 | − if (adis->spi->irq) { | |
| 202 | − ret = adis_probe_trigger(adis, indio_dev); | |
| 203 | − if (ret) | |
| 204 | − goto error_buffer_cleanup; | |
| 205 | − } | |
| 206 | − return 0; | |
| 207 | − | |
| 208 | −error_buffer_cleanup: | |
| 209 | − iio_triggered_buffer_cleanup(indio_dev); | |
| 210 | − return ret; | |
| 211 | −} | |
| 212 | −EXPORT_SYMBOL_GPL(adis_setup_buffer_and_trigger); | |
| 213 | − | |
| 214 | 170 | /** |
| 215 | 171 | * devm_adis_setup_buffer_and_trigger() - Sets up buffer and trigger for |
| 216 | 172 | * the managed adis device |
| @@ -220,7 +176,10 @@ EXPORT_SYMBOL_GPL(adis_setup_buffer_and_trigger); · 3 unmodified lines | ||
| 220 | 176 | * |
| 221 | 177 | * Returns 0 on success, a negative error code otherwise. |
| 222 | 178 | * |
| 223 | − * This function perfoms exactly the same as adis_setup_buffer_and_trigger() | |
| 179 | + * This function sets up the buffer and trigger for a adis devices. If | |
| 180 | + * 'trigger_handler' is NULL the default trigger handler will be used. The | |
| 181 | + * default trigger handler will simply read the registers assigned to the | |
| 182 | + * currently active channels. | |
| 224 | 183 | */ |
| 225 | 184 | int |
| 226 | 185 | devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, |
| @@ -248,20 +207,3 @@ devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, · 21 unmodified lines | ||
| 248 | 207 | } |
| 249 | 208 | EXPORT_SYMBOL_GPL(devm_adis_setup_buffer_and_trigger); |
| 250 | 209 | |
| 251 | −/** | |
| 252 | − * adis_cleanup_buffer_and_trigger() - Free buffer and trigger resources | |
| 253 | − * @adis: The adis device. | |
| 254 | − * @indio_dev: The IIO device. | |
| 255 | − * | |
| 256 | − * Frees resources allocated by adis_setup_buffer_and_trigger() | |
| 257 | − */ | |
| 258 | −void adis_cleanup_buffer_and_trigger(struct adis *adis, | |
| 259 | − struct iio_dev *indio_dev) | |
| 260 | −{ | |
| 261 | − if (adis->spi->irq) | |
| 262 | − adis_remove_trigger(adis); | |
| 263 | − kfree(adis->buffer); | |
| 264 | − kfree(adis->xfer); | |
| 265 | − iio_triggered_buffer_cleanup(indio_dev); | |
| 266 | −} | |
| 267 | −EXPORT_SYMBOL_GPL(adis_cleanup_buffer_and_trigger); | |
| @@ -55,53 +55,6 @@ static int adis_validate_irq_flag(struct adis *adis) · 54 unmodified lines | ||
| 55 | 55 | |
| 56 | 56 | return 0; |
| 57 | 57 | } |
| 58 | −/** | |
| 59 | − * adis_probe_trigger() - Sets up trigger for a adis device | |
| 60 | − * @adis: The adis device | |
| 61 | − * @indio_dev: The IIO device | |
| 62 | − * | |
| 63 | − * Returns 0 on success or a negative error code | |
| 64 | − * | |
| 65 | − * adis_remove_trigger() should be used to free the trigger. | |
| 66 | − */ | |
| 67 | −int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev) | |
| 68 | −{ | |
| 69 | − int ret; | |
| 70 | − | |
| 71 | − adis->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name, | |
| 72 | − indio_dev->id); | |
| 73 | − if (adis->trig == NULL) | |
| 74 | − return -ENOMEM; | |
| 75 | − | |
| 76 | − adis_trigger_setup(adis); | |
| 77 | − | |
| 78 | − ret = adis_validate_irq_flag(adis); | |
| 79 | − if (ret) | |
| 80 | − return ret; | |
| 81 | − | |
| 82 | − ret = request_irq(adis->spi->irq, | |
| 83 | − &iio_trigger_generic_data_rdy_poll, | |
| 84 | − adis->irq_flag, | |
| 85 | − indio_dev->name, | |
| 86 | − adis->trig); | |
| 87 | − if (ret) | |
| 88 | − goto error_free_trig; | |
| 89 | − | |
| 90 | − ret = iio_trigger_register(adis->trig); | |
| 91 | − | |
| 92 | − indio_dev->trig = iio_trigger_get(adis->trig); | |
| 93 | − if (ret) | |
| 94 | − goto error_free_irq; | |
| 95 | − | |
| 96 | − return 0; | |
| 97 | − | |
| 98 | −error_free_irq: | |
| 99 | − free_irq(adis->spi->irq, adis->trig); | |
| 100 | −error_free_trig: | |
| 101 | − iio_trigger_free(adis->trig); | |
| 102 | − return ret; | |
| 103 | −} | |
| 104 | −EXPORT_SYMBOL_GPL(adis_probe_trigger); | |
| 105 | 58 | |
| 106 | 59 | /** |
| 107 | 60 | * devm_adis_probe_trigger() - Sets up trigger for a managed adis device |
| @@ -137,16 +90,3 @@ int devm_adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev) · 29 unmodified lines | ||
| 137 | 90 | } |
| 138 | 91 | EXPORT_SYMBOL_GPL(devm_adis_probe_trigger); |
| 139 | 92 | |
| 140 | −/** | |
| 141 | − * adis_remove_trigger() - Remove trigger for a adis devices | |
| 142 | − * @adis: The adis device | |
| 143 | − * | |
| 144 | − * Removes the trigger previously registered with adis_probe_trigger(). | |
| 145 | − */ | |
| 146 | −void adis_remove_trigger(struct adis *adis) | |
| 147 | −{ | |
| 148 | − iio_trigger_unregister(adis->trig); | |
| 149 | − free_irq(adis->spi->irq, adis->trig); | |
| 150 | − iio_trigger_free(adis->trig); | |
| 151 | −} | |
| 152 | −EXPORT_SYMBOL_GPL(adis_remove_trigger); | |
| @@ -1475,22 +1475,14 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name, · 1474 unmodified lines | ||
| 1475 | 1475 | } |
| 1476 | 1476 | |
| 1477 | 1477 | st->vdd_supply = devm_regulator_get(dev, "vdd"); |
| 1478 | − if (IS_ERR(st->vdd_supply)) { | |
| 1479 | − if (PTR_ERR(st->vdd_supply) != -EPROBE_DEFER) | |
| 1480 | − dev_err(dev, "Failed to get vdd regulator %d\n", | |
| 1481 | − (int)PTR_ERR(st->vdd_supply)); | |
| 1482 | − | |
| 1483 | − return PTR_ERR(st->vdd_supply); | |
| 1484 | − } | |
| 1478 | + if (IS_ERR(st->vdd_supply)) | |
| 1479 | + return dev_err_probe(dev, PTR_ERR(st->vdd_supply), | |
| 1480 | + "Failed to get vdd regulator\n"); | |
| 1485 | 1481 | |
| 1486 | 1482 | st->vddio_supply = devm_regulator_get(dev, "vddio"); |
| 1487 | − if (IS_ERR(st->vddio_supply)) { | |
| 1488 | − if (PTR_ERR(st->vddio_supply) != -EPROBE_DEFER) | |
| 1489 | − dev_err(dev, "Failed to get vddio regulator %d\n", | |
| 1490 | − (int)PTR_ERR(st->vddio_supply)); | |
| 1491 | − | |
| 1492 | − return PTR_ERR(st->vddio_supply); | |
| 1493 | − } | |
| 1483 | + if (IS_ERR(st->vddio_supply)) | |
| 1484 | + return dev_err_probe(dev, PTR_ERR(st->vddio_supply), | |
| 1485 | + "Failed to get vddio regulator\n"); | |
| 1494 | 1486 | |
| 1495 | 1487 | result = regulator_enable(st->vdd_supply); |
| 1496 | 1488 | if (result) { |
| @@ -122,6 +122,13 @@ struct inv_mpu6050_chip_config { · 121 unmodified lines | ||
| 122 | 122 | u8 user_ctrl; |
| 123 | 123 | }; |
| 124 | 124 | |
| 125 | +/* | |
| 126 | + * Maximum of 6 + 6 + 2 + 7 (for MPU9x50) = 21 round up to 24 and plus 8. | |
| 127 | + * May be less if fewer channels are enabled, as long as the timestamp | |
| 128 | + * remains 8 byte aligned | |
| 129 | + */ | |
| 130 | +#define INV_MPU6050_OUTPUT_DATA_SIZE 32 | |
| 131 | + | |
| 125 | 132 | /** |
| 126 | 133 | * struct inv_mpu6050_hw - Other important hardware information. |
| 127 | 134 | * @whoami: Self identification byte from WHO_AM_I register |
| @@ -165,6 +172,7 @@ struct inv_mpu6050_hw { · 37 unmodified lines | ||
| 165 | 172 | * @magn_raw_to_gauss: coefficient to convert mag raw value to Gauss. |
| 166 | 173 | * @magn_orient: magnetometer sensor chip orientation if available. |
| 167 | 174 | * @suspended_sensors: sensors mask of sensors turned off for suspend |
| 175 | + * @data: dma safe buffer used for bulk reads. | |
| 168 | 176 | */ |
| 169 | 177 | struct inv_mpu6050_state { |
| 170 | 178 | struct mutex lock; |
| @@ -190,6 +198,7 @@ struct inv_mpu6050_state { · 19 unmodified lines | ||
| 190 | 198 | s32 magn_raw_to_gauss[3]; |
| 191 | 199 | struct iio_mount_matrix magn_orient; |
| 192 | 200 | unsigned int suspended_sensors; |
| 201 | + u8 data[INV_MPU6050_OUTPUT_DATA_SIZE] ____cacheline_aligned; | |
| 193 | 202 | }; |
| 194 | 203 | |
| 195 | 204 | /*register and associated bit definition*/ |
| @@ -334,9 +343,6 @@ struct inv_mpu6050_state { · 138 unmodified lines | ||
| 334 | 343 | #define INV_ICM20608_TEMP_OFFSET 8170 |
| 335 | 344 | #define INV_ICM20608_TEMP_SCALE 3059976 |
| 336 | 345 | |
| 337 | −/* 6 + 6 + 2 + 7 (for MPU9x50) = 21 round up to 24 and plus 8 */ | |
| 338 | −#define INV_MPU6050_OUTPUT_DATA_SIZE 32 | |
| 339 | − | |
| 340 | 346 | #define INV_MPU6050_REG_INT_PIN_CFG 0x37 |
| 341 | 347 | #define INV_MPU6050_ACTIVE_HIGH 0x00 |
| 342 | 348 | #define INV_MPU6050_ACTIVE_LOW 0x80 |
| @@ -13,7 +13,6 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <linux/interrupt.h> |
| 14 | 14 | #include <linux/poll.h> |
| 15 | 15 | #include <linux/math64.h> |
| 16 | −#include <asm/unaligned.h> | |
| 17 | 16 | #include "inv_mpu_iio.h" |
| 18 | 17 | |
| 19 | 18 | /** |
| @@ -121,7 +120,6 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) · 101 unmodified lines | ||
| 121 | 120 | struct inv_mpu6050_state *st = iio_priv(indio_dev); |
| 122 | 121 | size_t bytes_per_datum; |
| 123 | 122 | int result; |
| 124 | − u8 data[INV_MPU6050_OUTPUT_DATA_SIZE]; | |
| 125 | 123 | u16 fifo_count; |
| 126 | 124 | s64 timestamp; |
| 127 | 125 | int int_status; |
| @@ -160,11 +158,11 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) · 32 unmodified lines | ||
| 160 | 158 | * read fifo_count register to know how many bytes are inside the FIFO |
| 161 | 159 | * right now |
| 162 | 160 | */ |
| 163 | − result = regmap_bulk_read(st->map, st->reg->fifo_count_h, data, | |
| 164 | − INV_MPU6050_FIFO_COUNT_BYTE); | |
| 161 | + result = regmap_bulk_read(st->map, st->reg->fifo_count_h, | |
| 162 | + st->data, INV_MPU6050_FIFO_COUNT_BYTE); | |
| 165 | 163 | if (result) |
| 166 | 164 | goto end_session; |
| 167 | − fifo_count = get_unaligned_be16(&data[0]); | |
| 165 | + fifo_count = be16_to_cpup((__be16 *)&st->data[0]); | |
| 168 | 166 | |
| 169 | 167 | /* |
| 170 | 168 | * Handle fifo overflow by resetting fifo. |
| @@ -181,8 +179,8 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) · 10 unmodified lines | ||
| 181 | 179 | nb = fifo_count / bytes_per_datum; |
| 182 | 180 | inv_mpu6050_update_period(st, pf->timestamp, nb); |
| 183 | 181 | for (i = 0; i < nb; ++i) { |
| 184 | − result = regmap_bulk_read(st->map, st->reg->fifo_r_w, | |
| 185 | − data, bytes_per_datum); | |
| 182 | + result = regmap_noinc_read(st->map, st->reg->fifo_r_w, | |
| 183 | + st->data, bytes_per_datum); | |
| 186 | 184 | if (result) |
| 187 | 185 | goto flush_fifo; |
| 188 | 186 | /* skip first samples if needed */ |
| @@ -191,7 +189,7 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) · 2 unmodified lines | ||
| 191 | 189 | continue; |
| 192 | 190 | } |
| 193 | 191 | timestamp = inv_mpu6050_get_timestamp(st); |
| 194 | − iio_push_to_buffers_with_timestamp(indio_dev, data, timestamp); | |
| 192 | + iio_push_to_buffers_with_timestamp(indio_dev, st->data, timestamp); | |
| 195 | 193 | } |
| 196 | 194 | |
| 197 | 195 | end_session: |
| @@ -383,6 +383,7 @@ struct st_lsm6dsx_sensor { · 382 unmodified lines | ||
| 383 | 383 | * @iio_devs: Pointers to acc/gyro iio_dev instances. |
| 384 | 384 | * @settings: Pointer to the specific sensor settings in use. |
| 385 | 385 | * @orientation: sensor chip orientation relative to main hardware. |
| 386 | + * @scan: Temporary buffers used to align data before iio_push_to_buffers() | |
| 386 | 387 | */ |
| 387 | 388 | struct st_lsm6dsx_hw { |
| 388 | 389 | struct device *dev; |
| @@ -411,6 +412,11 @@ struct st_lsm6dsx_hw { · 22 unmodified lines | ||
| 411 | 412 | const struct st_lsm6dsx_settings *settings; |
| 412 | 413 | |
| 413 | 414 | struct iio_mount_matrix orientation; |
| 415 | + /* Ensure natural alignment of buffer elements */ | |
| 416 | + struct { | |
| 417 | + __le16 channels[3]; | |
| 418 | + s64 ts __aligned(8); | |
| 419 | + } scan[3]; | |
| 414 | 420 | }; |
| 415 | 421 | |
| 416 | 422 | static __maybe_unused const struct iio_event_spec st_lsm6dsx_event = { |
| @@ -353,9 +353,6 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) · 352 unmodified lines | ||
| 353 | 353 | int err, sip, acc_sip, gyro_sip, ts_sip, ext_sip, read_len, offset; |
| 354 | 354 | u16 fifo_len, pattern_len = hw->sip * ST_LSM6DSX_SAMPLE_SIZE; |
| 355 | 355 | u16 fifo_diff_mask = hw->settings->fifo_ops.fifo_diff.mask; |
| 356 | − u8 gyro_buff[ST_LSM6DSX_IIO_BUFF_SIZE]; | |
| 357 | − u8 acc_buff[ST_LSM6DSX_IIO_BUFF_SIZE]; | |
| 358 | − u8 ext_buff[ST_LSM6DSX_IIO_BUFF_SIZE]; | |
| 359 | 356 | bool reset_ts = false; |
| 360 | 357 | __le16 fifo_status; |
| 361 | 358 | s64 ts = 0; |
| @@ -416,19 +413,22 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) · 54 unmodified lines | ||
| 416 | 413 | |
| 417 | 414 | while (acc_sip > 0 || gyro_sip > 0 || ext_sip > 0) { |
| 418 | 415 | if (gyro_sip > 0 && !(sip % gyro_sensor->decimator)) { |
| 419 | − memcpy(gyro_buff, &hw->buff[offset], | |
| 420 | − ST_LSM6DSX_SAMPLE_SIZE); | |
| 421 | − offset += ST_LSM6DSX_SAMPLE_SIZE; | |
| 416 | + memcpy(hw->scan[ST_LSM6DSX_ID_GYRO].channels, | |
| 417 | + &hw->buff[offset], | |
| 418 | + sizeof(hw->scan[ST_LSM6DSX_ID_GYRO].channels)); | |
| 419 | + offset += sizeof(hw->scan[ST_LSM6DSX_ID_GYRO].channels); | |
| 422 | 420 | } |
| 423 | 421 | if (acc_sip > 0 && !(sip % acc_sensor->decimator)) { |
| 424 | − memcpy(acc_buff, &hw->buff[offset], | |
| 425 | − ST_LSM6DSX_SAMPLE_SIZE); | |
| 426 | − offset += ST_LSM6DSX_SAMPLE_SIZE; | |
| 422 | + memcpy(hw->scan[ST_LSM6DSX_ID_ACC].channels, | |
| 423 | + &hw->buff[offset], | |
| 424 | + sizeof(hw->scan[ST_LSM6DSX_ID_ACC].channels)); | |
| 425 | + offset += sizeof(hw->scan[ST_LSM6DSX_ID_ACC].channels); | |
| 427 | 426 | } |
| 428 | 427 | if (ext_sip > 0 && !(sip % ext_sensor->decimator)) { |
| 429 | − memcpy(ext_buff, &hw->buff[offset], | |
| 430 | − ST_LSM6DSX_SAMPLE_SIZE); | |
| 431 | − offset += ST_LSM6DSX_SAMPLE_SIZE; | |
| 428 | + memcpy(hw->scan[ST_LSM6DSX_ID_EXT0].channels, | |
| 429 | + &hw->buff[offset], | |
| 430 | + sizeof(hw->scan[ST_LSM6DSX_ID_EXT0].channels)); | |
| 431 | + offset += sizeof(hw->scan[ST_LSM6DSX_ID_EXT0].channels); | |
| 432 | 432 | } |
| 433 | 433 | |
| 434 | 434 | if (ts_sip-- > 0) { |
| @@ -458,19 +458,22 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) · 23 unmodified lines | ||
| 458 | 458 | if (gyro_sip > 0 && !(sip % gyro_sensor->decimator)) { |
| 459 | 459 | iio_push_to_buffers_with_timestamp( |
| 460 | 460 | hw->iio_devs[ST_LSM6DSX_ID_GYRO], |
| 461 | − gyro_buff, gyro_sensor->ts_ref + ts); | |
| 461 | + &hw->scan[ST_LSM6DSX_ID_GYRO], | |
| 462 | + gyro_sensor->ts_ref + ts); | |
| 462 | 463 | gyro_sip--; |
| 463 | 464 | } |
| 464 | 465 | if (acc_sip > 0 && !(sip % acc_sensor->decimator)) { |
| 465 | 466 | iio_push_to_buffers_with_timestamp( |
| 466 | 467 | hw->iio_devs[ST_LSM6DSX_ID_ACC], |
| 467 | − acc_buff, acc_sensor->ts_ref + ts); | |
| 468 | + &hw->scan[ST_LSM6DSX_ID_ACC], | |
| 469 | + acc_sensor->ts_ref + ts); | |
| 468 | 470 | acc_sip--; |
| 469 | 471 | } |
| 470 | 472 | if (ext_sip > 0 && !(sip % ext_sensor->decimator)) { |
| 471 | 473 | iio_push_to_buffers_with_timestamp( |
| 472 | 474 | hw->iio_devs[ST_LSM6DSX_ID_EXT0], |
| 473 | − ext_buff, ext_sensor->ts_ref + ts); | |
| 475 | + &hw->scan[ST_LSM6DSX_ID_EXT0], | |
| 476 | + ext_sensor->ts_ref + ts); | |
| 474 | 477 | ext_sip--; |
| 475 | 478 | } |
| 476 | 479 | sip++; |
| @@ -555,7 +558,14 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw) · 78 unmodified lines | ||
| 555 | 558 | { |
| 556 | 559 | u16 pattern_len = hw->sip * ST_LSM6DSX_TAGGED_SAMPLE_SIZE; |
| 557 | 560 | u16 fifo_len, fifo_diff_mask; |
| 558 | − u8 iio_buff[ST_LSM6DSX_IIO_BUFF_SIZE], tag; | |
| 561 | + /* | |
| 562 | + * Alignment needed as this can ultimately be passed to a | |
| 563 | + * call to iio_push_to_buffers_with_timestamp() which | |
| 564 | + * must be passed a buffer that is aligned to 8 bytes so | |
| 565 | + * as to allow insertion of a naturally aligned timestamp. | |
| 566 | + */ | |
| 567 | + u8 iio_buff[ST_LSM6DSX_IIO_BUFF_SIZE] __aligned(8); | |
| 568 | + u8 tag; | |
| 559 | 569 | bool reset_ts = false; |
| 560 | 570 | int i, err, read_len; |
| 561 | 571 | __le16 fifo_status; |
| @@ -157,10 +157,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 156 unmodified lines | ||
| 157 | 157 | .addr = 0x20, |
| 158 | 158 | .mask = GENMASK(4, 3), |
| 159 | 159 | }, |
| 160 | − .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, | |
| 161 | − .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, | |
| 162 | − .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, | |
| 163 | − .fs_avl[3] = { IIO_G_TO_M_S_2(732), 0x1 }, | |
| 160 | + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, | |
| 161 | + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, | |
| 162 | + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, | |
| 163 | + .fs_avl[3] = { IIO_G_TO_M_S_2(732000), 0x1 }, | |
| 164 | 164 | .fs_len = 4, |
| 165 | 165 | }, |
| 166 | 166 | [ST_LSM6DSX_ID_GYRO] = { |
| @@ -169,9 +169,9 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 2 unmodified lines | ||
| 169 | 169 | .mask = GENMASK(4, 3), |
| 170 | 170 | }, |
| 171 | 171 | |
| 172 | − .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, | |
| 173 | − .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, | |
| 174 | − .fs_avl[2] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, | |
| 172 | + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, | |
| 173 | + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, | |
| 174 | + .fs_avl[2] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, | |
| 175 | 175 | .fs_len = 3, |
| 176 | 176 | }, |
| 177 | 177 | }, |
| @@ -259,10 +259,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 81 unmodified lines | ||
| 259 | 259 | .addr = 0x10, |
| 260 | 260 | .mask = GENMASK(3, 2), |
| 261 | 261 | }, |
| 262 | − .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, | |
| 263 | − .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, | |
| 264 | − .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, | |
| 265 | − .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, | |
| 262 | + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, | |
| 263 | + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, | |
| 264 | + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, | |
| 265 | + .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, | |
| 266 | 266 | .fs_len = 4, |
| 267 | 267 | }, |
| 268 | 268 | [ST_LSM6DSX_ID_GYRO] = { |
| @@ -270,10 +270,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 1 unmodified line | ||
| 270 | 270 | .addr = 0x11, |
| 271 | 271 | .mask = GENMASK(3, 2), |
| 272 | 272 | }, |
| 273 | − .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, | |
| 274 | − .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, | |
| 275 | − .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, | |
| 276 | − .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, | |
| 273 | + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, | |
| 274 | + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, | |
| 275 | + .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, | |
| 276 | + .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, | |
| 277 | 277 | .fs_len = 4, |
| 278 | 278 | }, |
| 279 | 279 | }, |
| @@ -425,10 +425,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 145 unmodified lines | ||
| 425 | 425 | .addr = 0x10, |
| 426 | 426 | .mask = GENMASK(3, 2), |
| 427 | 427 | }, |
| 428 | − .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, | |
| 429 | − .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, | |
| 430 | − .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, | |
| 431 | − .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, | |
| 428 | + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, | |
| 429 | + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, | |
| 430 | + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, | |
| 431 | + .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, | |
| 432 | 432 | .fs_len = 4, |
| 433 | 433 | }, |
| 434 | 434 | [ST_LSM6DSX_ID_GYRO] = { |
| @@ -436,10 +436,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 1 unmodified line | ||
| 436 | 436 | .addr = 0x11, |
| 437 | 437 | .mask = GENMASK(3, 2), |
| 438 | 438 | }, |
| 439 | − .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, | |
| 440 | − .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, | |
| 441 | − .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, | |
| 442 | − .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, | |
| 439 | + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, | |
| 440 | + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, | |
| 441 | + .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, | |
| 442 | + .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, | |
| 443 | 443 | .fs_len = 4, |
| 444 | 444 | }, |
| 445 | 445 | }, |
| @@ -600,10 +600,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 154 unmodified lines | ||
| 600 | 600 | .addr = 0x10, |
| 601 | 601 | .mask = GENMASK(3, 2), |
| 602 | 602 | }, |
| 603 | − .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, | |
| 604 | − .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, | |
| 605 | − .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, | |
| 606 | − .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, | |
| 603 | + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, | |
| 604 | + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, | |
| 605 | + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, | |
| 606 | + .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, | |
| 607 | 607 | .fs_len = 4, |
| 608 | 608 | }, |
| 609 | 609 | [ST_LSM6DSX_ID_GYRO] = { |
| @@ -611,10 +611,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 1 unmodified line | ||
| 611 | 611 | .addr = 0x11, |
| 612 | 612 | .mask = GENMASK(3, 2), |
| 613 | 613 | }, |
| 614 | − .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, | |
| 615 | − .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, | |
| 616 | − .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, | |
| 617 | − .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, | |
| 614 | + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, | |
| 615 | + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, | |
| 616 | + .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, | |
| 617 | + .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, | |
| 618 | 618 | .fs_len = 4, |
| 619 | 619 | }, |
| 620 | 620 | }, |
| @@ -816,10 +816,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 195 unmodified lines | ||
| 816 | 816 | .addr = 0x10, |
| 817 | 817 | .mask = GENMASK(3, 2), |
| 818 | 818 | }, |
| 819 | − .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, | |
| 820 | − .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, | |
| 821 | − .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, | |
| 822 | − .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, | |
| 819 | + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, | |
| 820 | + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, | |
| 821 | + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, | |
| 822 | + .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, | |
| 823 | 823 | .fs_len = 4, |
| 824 | 824 | }, |
| 825 | 825 | [ST_LSM6DSX_ID_GYRO] = { |
| @@ -827,10 +827,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 1 unmodified line | ||
| 827 | 827 | .addr = 0x11, |
| 828 | 828 | .mask = GENMASK(3, 2), |
| 829 | 829 | }, |
| 830 | − .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, | |
| 831 | − .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, | |
| 832 | − .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, | |
| 833 | − .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, | |
| 830 | + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, | |
| 831 | + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, | |
| 832 | + .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, | |
| 833 | + .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, | |
| 834 | 834 | .fs_len = 4, |
| 835 | 835 | }, |
| 836 | 836 | }, |
| @@ -1021,10 +1021,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 184 unmodified lines | ||
| 1021 | 1021 | .addr = 0x10, |
| 1022 | 1022 | .mask = GENMASK(3, 2), |
| 1023 | 1023 | }, |
| 1024 | − .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, | |
| 1025 | − .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, | |
| 1026 | − .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, | |
| 1027 | − .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, | |
| 1024 | + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, | |
| 1025 | + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, | |
| 1026 | + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, | |
| 1027 | + .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, | |
| 1028 | 1028 | .fs_len = 4, |
| 1029 | 1029 | }, |
| 1030 | 1030 | [ST_LSM6DSX_ID_GYRO] = { |
| @@ -1032,10 +1032,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 1 unmodified line | ||
| 1032 | 1032 | .addr = 0x11, |
| 1033 | 1033 | .mask = GENMASK(3, 2), |
| 1034 | 1034 | }, |
| 1035 | − .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, | |
| 1036 | − .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, | |
| 1037 | − .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, | |
| 1038 | − .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, | |
| 1035 | + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, | |
| 1036 | + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, | |
| 1037 | + .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, | |
| 1038 | + .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, | |
| 1039 | 1039 | .fs_len = 4, |
| 1040 | 1040 | }, |
| 1041 | 1041 | }, |
| @@ -1200,10 +1200,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 158 unmodified lines | ||
| 1200 | 1200 | .addr = 0x10, |
| 1201 | 1201 | .mask = GENMASK(3, 2), |
| 1202 | 1202 | }, |
| 1203 | − .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, | |
| 1204 | − .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, | |
| 1205 | − .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, | |
| 1206 | − .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, | |
| 1203 | + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, | |
| 1204 | + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, | |
| 1205 | + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, | |
| 1206 | + .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, | |
| 1207 | 1207 | .fs_len = 4, |
| 1208 | 1208 | }, |
| 1209 | 1209 | [ST_LSM6DSX_ID_GYRO] = { |
| @@ -1211,10 +1211,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 1 unmodified line | ||
| 1211 | 1211 | .addr = 0x11, |
| 1212 | 1212 | .mask = GENMASK(3, 2), |
| 1213 | 1213 | }, |
| 1214 | − .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, | |
| 1215 | − .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, | |
| 1216 | − .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, | |
| 1217 | − .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, | |
| 1214 | + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, | |
| 1215 | + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, | |
| 1216 | + .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, | |
| 1217 | + .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, | |
| 1218 | 1218 | .fs_len = 4, |
| 1219 | 1219 | }, |
| 1220 | 1220 | }, |
| @@ -1598,7 +1598,7 @@ static int st_lsm6dsx_read_raw(struct iio_dev *iio_dev, · 377 unmodified lines | ||
| 1598 | 1598 | case IIO_CHAN_INFO_SCALE: |
| 1599 | 1599 | *val = 0; |
| 1600 | 1600 | *val2 = sensor->gain; |
| 1601 | − ret = IIO_VAL_INT_PLUS_MICRO; | |
| 1601 | + ret = IIO_VAL_INT_PLUS_NANO; | |
| 1602 | 1602 | break; |
| 1603 | 1603 | default: |
| 1604 | 1604 | ret = -EINVAL; |
| @@ -1836,13 +1836,31 @@ static ssize_t st_lsm6dsx_sysfs_scale_avail(struct device *dev, · 231 unmodified lines | ||
| 1836 | 1836 | |
| 1837 | 1837 | fs_table = &hw->settings->fs_table[sensor->id]; |
| 1838 | 1838 | for (i = 0; i < fs_table->fs_len; i++) |
| 1839 | − len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ", | |
| 1839 | + len += scnprintf(buf + len, PAGE_SIZE - len, "0.%09u ", | |
| 1840 | 1840 | fs_table->fs_avl[i].gain); |
| 1841 | 1841 | buf[len - 1] = '\n'; |
| 1842 | 1842 | |
| 1843 | 1843 | return len; |
| 1844 | 1844 | } |
| 1845 | 1845 | |
| 1846 | +static int st_lsm6dsx_write_raw_get_fmt(struct iio_dev *indio_dev, | |
| 1847 | + struct iio_chan_spec const *chan, | |
| 1848 | + long mask) | |
| 1849 | +{ | |
| 1850 | + switch (mask) { | |
| 1851 | + case IIO_CHAN_INFO_SCALE: | |
| 1852 | + switch (chan->type) { | |
| 1853 | + case IIO_ANGL_VEL: | |
| 1854 | + case IIO_ACCEL: | |
| 1855 | + return IIO_VAL_INT_PLUS_NANO; | |
| 1856 | + default: | |
| 1857 | + return IIO_VAL_INT_PLUS_MICRO; | |
| 1858 | + } | |
| 1859 | + default: | |
| 1860 | + return IIO_VAL_INT_PLUS_MICRO; | |
| 1861 | + } | |
| 1862 | +} | |
| 1863 | + | |
| 1846 | 1864 | static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(st_lsm6dsx_sysfs_sampling_frequency_avail); |
| 1847 | 1865 | static IIO_DEVICE_ATTR(in_accel_scale_available, 0444, |
| 1848 | 1866 | st_lsm6dsx_sysfs_scale_avail, NULL, 0); |
| @@ -1868,6 +1886,7 @@ static const struct iio_info st_lsm6dsx_acc_info = { · 19 unmodified lines | ||
| 1868 | 1886 | .read_event_config = st_lsm6dsx_read_event_config, |
| 1869 | 1887 | .write_event_config = st_lsm6dsx_write_event_config, |
| 1870 | 1888 | .hwfifo_set_watermark = st_lsm6dsx_set_watermark, |
| 1889 | + .write_raw_get_fmt = st_lsm6dsx_write_raw_get_fmt, | |
| 1871 | 1890 | }; |
| 1872 | 1891 | |
| 1873 | 1892 | static struct attribute *st_lsm6dsx_gyro_attributes[] = { |
| @@ -1885,6 +1904,7 @@ static const struct iio_info st_lsm6dsx_gyro_info = { · 11 unmodified lines | ||
| 1885 | 1904 | .read_raw = st_lsm6dsx_read_raw, |
| 1886 | 1905 | .write_raw = st_lsm6dsx_write_raw, |
| 1887 | 1906 | .hwfifo_set_watermark = st_lsm6dsx_set_watermark, |
| 1907 | + .write_raw_get_fmt = st_lsm6dsx_write_raw_get_fmt, | |
| 1888 | 1908 | }; |
| 1889 | 1909 | |
| 1890 | 1910 | static int st_lsm6dsx_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin) |
| @@ -313,6 +313,8 @@ st_lsm6dsx_shub_read(struct st_lsm6dsx_sensor *sensor, u8 addr, · 312 unmodified lines | ||
| 313 | 313 | |
| 314 | 314 | err = st_lsm6dsx_shub_read_output(hw, data, |
| 315 | 315 | len & ST_LS6DSX_READ_OP_MASK); |
| 316 | + if (err < 0) | |
| 317 | + return err; | |
| 316 | 318 | |
| 317 | 319 | st_lsm6dsx_shub_master_enable(sensor, false); |
| 318 | 320 | |
| @@ -1264,26 +1264,14 @@ static struct attribute *iio_buffer_attrs[] = { · 1263 unmodified lines | ||
| 1264 | 1264 | &dev_attr_data_available.attr, |
| 1265 | 1265 | }; |
| 1266 | 1266 | |
| 1267 | −int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev) | |
| 1267 | +static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer, | |
| 1268 | + struct iio_dev *indio_dev) | |
| 1268 | 1269 | { |
| 1269 | 1270 | struct iio_dev_attr *p; |
| 1270 | 1271 | struct attribute **attr; |
| 1271 | − struct iio_buffer *buffer = indio_dev->buffer; | |
| 1272 | 1272 | int ret, i, attrn, attrcount; |
| 1273 | 1273 | const struct iio_chan_spec *channels; |
| 1274 | 1274 | |
| 1275 | − channels = indio_dev->channels; | |
| 1276 | − if (channels) { | |
| 1277 | − int ml = indio_dev->masklength; | |
| 1278 | − | |
| 1279 | − for (i = 0; i < indio_dev->num_channels; i++) | |
| 1280 | − ml = max(ml, channels[i].scan_index + 1); | |
| 1281 | − indio_dev->masklength = ml; | |
| 1282 | − } | |
| 1283 | − | |
| 1284 | − if (!buffer) | |
| 1285 | − return 0; | |
| 1286 | − | |
| 1287 | 1275 | attrcount = 0; |
| 1288 | 1276 | if (buffer->attrs) { |
| 1289 | 1277 | while (buffer->attrs[attrcount] != NULL) |
| @@ -1367,19 +1355,45 @@ error_cleanup_dynamic: · 77 unmodified lines | ||
| 1367 | 1355 | return ret; |
| 1368 | 1356 | } |
| 1369 | 1357 | |
| 1370 | −void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev) | |
| 1358 | +int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev) | |
| 1371 | 1359 | { |
| 1372 | 1360 | struct iio_buffer *buffer = indio_dev->buffer; |
| 1361 | + const struct iio_chan_spec *channels; | |
| 1362 | + int i; | |
| 1363 | + | |
| 1364 | + channels = indio_dev->channels; | |
| 1365 | + if (channels) { | |
| 1366 | + int ml = indio_dev->masklength; | |
| 1367 | + | |
| 1368 | + for (i = 0; i < indio_dev->num_channels; i++) | |
| 1369 | + ml = max(ml, channels[i].scan_index + 1); | |
| 1370 | + indio_dev->masklength = ml; | |
| 1371 | + } | |
| 1373 | 1372 | |
| 1374 | 1373 | if (!buffer) |
| 1375 | − return; | |
| 1374 | + return 0; | |
| 1375 | + | |
| 1376 | + return __iio_buffer_alloc_sysfs_and_mask(buffer, indio_dev); | |
| 1377 | +} | |
| 1376 | 1378 | |
| 1379 | +static void __iio_buffer_free_sysfs_and_mask(struct iio_buffer *buffer) | |
| 1380 | +{ | |
| 1377 | 1381 | bitmap_free(buffer->scan_mask); |
| 1378 | 1382 | kfree(buffer->buffer_group.attrs); |
| 1379 | 1383 | kfree(buffer->scan_el_group.attrs); |
| 1380 | 1384 | iio_free_chan_devattr_list(&buffer->scan_el_dev_attr_list); |
| 1381 | 1385 | } |
| 1382 | 1386 | |
| 1387 | +void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev) | |
| 1388 | +{ | |
| 1389 | + struct iio_buffer *buffer = indio_dev->buffer; | |
| 1390 | + | |
| 1391 | + if (!buffer) | |
| 1392 | + return; | |
| 1393 | + | |
| 1394 | + __iio_buffer_free_sysfs_and_mask(buffer); | |
| 1395 | +} | |
| 1396 | + | |
| 1383 | 1397 | /** |
| 1384 | 1398 | * iio_validate_scan_mask_onehot() - Validates that exactly one channel is selected |
| 1385 | 1399 | * @indio_dev: the iio device |
| @@ -133,6 +133,7 @@ static const char * const iio_modifier_names[] = { · 132 unmodified lines | ||
| 133 | 133 | [IIO_MOD_PM10] = "pm10", |
| 134 | 134 | [IIO_MOD_ETHANOL] = "ethanol", |
| 135 | 135 | [IIO_MOD_H2] = "h2", |
| 136 | + [IIO_MOD_O2] = "o2", | |
| 136 | 137 | }; |
| 137 | 138 | |
| 138 | 139 | /* relies on pairs of these shared then separate */ |
| @@ -165,10 +166,11 @@ static const char * const iio_chan_info_postfix[] = { · 26 unmodified lines | ||
| 165 | 166 | [IIO_CHAN_INFO_CALIBEMISSIVITY] = "calibemissivity", |
| 166 | 167 | [IIO_CHAN_INFO_OVERSAMPLING_RATIO] = "oversampling_ratio", |
| 167 | 168 | [IIO_CHAN_INFO_THERMOCOUPLE_TYPE] = "thermocouple_type", |
| 169 | + [IIO_CHAN_INFO_CALIBAMBIENT] = "calibambient", | |
| 168 | 170 | }; |
| 169 | 171 | |
| 170 | 172 | #if defined(CONFIG_DEBUG_FS) |
| 171 | −/** | |
| 173 | +/* | |
| 172 | 174 | * There's also a CONFIG_DEBUG_FS guard in include/linux/iio/iio.h for |
| 173 | 175 | * iio_get_debugfs_dentry() to make it inline if CONFIG_DEBUG_FS is undefined |
| 174 | 176 | */ |
| @@ -1523,6 +1525,7 @@ struct device_type iio_device_type = { · 1348 unmodified lines | ||
| 1523 | 1525 | |
| 1524 | 1526 | /** |
| 1525 | 1527 | * iio_device_alloc() - allocate an iio_dev from a driver |
| 1528 | + * @parent: Parent device. | |
| 1526 | 1529 | * @sizeof_priv: Space to allocate for private structure. |
| 1527 | 1530 | **/ |
| 1528 | 1531 | struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv) |
| @@ -477,6 +477,7 @@ static const char *iio_event_group_name = "events"; · 476 unmodified lines | ||
| 477 | 477 | int iio_device_register_eventset(struct iio_dev *indio_dev) |
| 478 | 478 | { |
| 479 | 479 | struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); |
| 480 | + struct iio_event_interface *ev_int; | |
| 480 | 481 | struct iio_dev_attr *p; |
| 481 | 482 | int ret = 0, attrcount_orig = 0, attrcount, attrn; |
| 482 | 483 | struct attribute **attr; |
| @@ -485,14 +486,15 @@ int iio_device_register_eventset(struct iio_dev *indio_dev) · 2 unmodified lines | ||
| 485 | 486 | iio_check_for_dynamic_events(indio_dev))) |
| 486 | 487 | return 0; |
| 487 | 488 | |
| 488 | − iio_dev_opaque->event_interface = | |
| 489 | − kzalloc(sizeof(struct iio_event_interface), GFP_KERNEL); | |
| 490 | − if (iio_dev_opaque->event_interface == NULL) | |
| 489 | + ev_int = kzalloc(sizeof(struct iio_event_interface), GFP_KERNEL); | |
| 490 | + if (ev_int == NULL) | |
| 491 | 491 | return -ENOMEM; |
| 492 | 492 | |
| 493 | − INIT_LIST_HEAD(&iio_dev_opaque->event_interface->dev_attr_list); | |
| 493 | + iio_dev_opaque->event_interface = ev_int; | |
| 494 | 494 | |
| 495 | − iio_setup_ev_int(iio_dev_opaque->event_interface); | |
| 495 | + INIT_LIST_HEAD(&ev_int->dev_attr_list); | |
| 496 | + | |
| 497 | + iio_setup_ev_int(ev_int); | |
| 496 | 498 | if (indio_dev->info->event_attrs != NULL) { |
| 497 | 499 | attr = indio_dev->info->event_attrs->attrs; |
| 498 | 500 | while (*attr++ != NULL) |
| @@ -506,34 +508,29 @@ int iio_device_register_eventset(struct iio_dev *indio_dev) · 7 unmodified lines | ||
| 506 | 508 | attrcount += ret; |
| 507 | 509 | } |
| 508 | 510 | |
| 509 | − iio_dev_opaque->event_interface->group.name = iio_event_group_name; | |
| 510 | − iio_dev_opaque->event_interface->group.attrs = kcalloc(attrcount + 1, | |
| 511 | − sizeof(iio_dev_opaque->event_interface->group.attrs[0]), | |
| 512 | − GFP_KERNEL); | |
| 513 | − if (iio_dev_opaque->event_interface->group.attrs == NULL) { | |
| 511 | + ev_int->group.name = iio_event_group_name; | |
| 512 | + ev_int->group.attrs = kcalloc(attrcount + 1, | |
| 513 | + sizeof(ev_int->group.attrs[0]), | |
| 514 | + GFP_KERNEL); | |
| 515 | + if (ev_int->group.attrs == NULL) { | |
| 514 | 516 | ret = -ENOMEM; |
| 515 | 517 | goto error_free_setup_event_lines; |
| 516 | 518 | } |
| 517 | 519 | if (indio_dev->info->event_attrs) |
| 518 | − memcpy(iio_dev_opaque->event_interface->group.attrs, | |
| 520 | + memcpy(ev_int->group.attrs, | |
| 519 | 521 | indio_dev->info->event_attrs->attrs, |
| 520 | − sizeof(iio_dev_opaque->event_interface->group.attrs[0]) | |
| 521 | − *attrcount_orig); | |
| 522 | + sizeof(ev_int->group.attrs[0]) * attrcount_orig); | |
| 522 | 523 | attrn = attrcount_orig; |
| 523 | 524 | /* Add all elements from the list. */ |
| 524 | − list_for_each_entry(p, | |
| 525 | − &iio_dev_opaque->event_interface->dev_attr_list, | |
| 526 | − l) | |
| 527 | − iio_dev_opaque->event_interface->group.attrs[attrn++] = | |
| 528 | − &p->dev_attr.attr; | |
| 529 | − indio_dev->groups[indio_dev->groupcounter++] = | |
| 530 | − &iio_dev_opaque->event_interface->group; | |
| 525 | + list_for_each_entry(p, &ev_int->dev_attr_list, l) | |
| 526 | + ev_int->group.attrs[attrn++] = &p->dev_attr.attr; | |
| 527 | + indio_dev->groups[indio_dev->groupcounter++] = &ev_int->group; | |
| 531 | 528 | |
| 532 | 529 | return 0; |
| 533 | 530 | |
| 534 | 531 | error_free_setup_event_lines: |
| 535 | − iio_free_chan_devattr_list(&iio_dev_opaque->event_interface->dev_attr_list); | |
| 536 | − kfree(iio_dev_opaque->event_interface); | |
| 532 | + iio_free_chan_devattr_list(&ev_int->dev_attr_list); | |
| 533 | + kfree(ev_int); | |
| 537 | 534 | iio_dev_opaque->event_interface = NULL; |
| 538 | 535 | return ret; |
| 539 | 536 | } |
| @@ -557,10 +554,12 @@ void iio_device_wakeup_eventset(struct iio_dev *indio_dev) · 17 unmodified lines | ||
| 557 | 554 | void iio_device_unregister_eventset(struct iio_dev *indio_dev) |
| 558 | 555 | { |
| 559 | 556 | struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); |
| 557 | + struct iio_event_interface *ev_int = iio_dev_opaque->event_interface; | |
| 560 | 558 | |
| 561 | − if (iio_dev_opaque->event_interface == NULL) | |
| 559 | + if (ev_int == NULL) | |
| 562 | 560 | return; |
| 563 | − iio_free_chan_devattr_list(&iio_dev_opaque->event_interface->dev_attr_list); | |
| 564 | − kfree(iio_dev_opaque->event_interface->group.attrs); | |
| 565 | − kfree(iio_dev_opaque->event_interface); | |
| 561 | + iio_free_chan_devattr_list(&ev_int->dev_attr_list); | |
| 562 | + kfree(ev_int->group.attrs); | |
| 563 | + kfree(ev_int); | |
| 564 | + iio_dev_opaque->event_interface = NULL; | |
| 566 | 565 | } |
| @@ -516,7 +516,8 @@ static void iio_trig_subirqunmask(struct irq_data *d) · 515 unmodified lines | ||
| 516 | 516 | trig->subirqs[d->irq - trig->subirq_base].enabled = true; |
| 517 | 517 | } |
| 518 | 518 | |
| 519 | −static struct iio_trigger *viio_trigger_alloc(const char *fmt, va_list vargs) | |
| 519 | +static __printf(1, 0) | |
| 520 | +struct iio_trigger *viio_trigger_alloc(const char *fmt, va_list vargs) | |
| 520 | 521 | { |
| 521 | 522 | struct iio_trigger *trig; |
| 522 | 523 | int i; |
| @@ -86,6 +86,21 @@ config APDS9960 · 85 unmodified lines | ||
| 86 | 86 | To compile this driver as a module, choose M here: the |
| 87 | 87 | module will be called apds9960 |
| 88 | 88 | |
| 89 | +config AS73211 | |
| 90 | + tristate "AMS AS73211 XYZ color sensor" | |
| 91 | + depends on I2C | |
| 92 | + select IIO_BUFFER | |
| 93 | + select IIO_TRIGGERED_BUFFER | |
| 94 | + help | |
| 95 | + If you say yes here you get support for the AMS AS73211 | |
| 96 | + JENCOLOR(R) Digital XYZ Sensor. | |
| 97 | + | |
| 98 | + For triggered measurements, you will need an additional trigger driver | |
| 99 | + like IIO_HRTIMER_TRIGGER or IIO_SYSFS_TRIGGER. | |
| 100 | + | |
| 101 | + This driver can also be built as a module. If so, the module | |
| 102 | + will be called as73211. | |
| 103 | + | |
| 89 | 104 | config BH1750 |
| 90 | 105 | tristate "ROHM BH1750 ambient light sensor" |
| 91 | 106 | depends on I2C |
| @@ -11,6 +11,7 @@ obj-$(CONFIG_AL3010) += al3010.o · 10 unmodified lines | ||
| 11 | 11 | obj-$(CONFIG_AL3320A) += al3320a.o |
| 12 | 12 | obj-$(CONFIG_APDS9300) += apds9300.o |
| 13 | 13 | obj-$(CONFIG_APDS9960) += apds9960.o |
| 14 | +obj-$(CONFIG_AS73211) += as73211.o | |
| 14 | 15 | obj-$(CONFIG_BH1750) += bh1750.o |
| 15 | 16 | obj-$(CONFIG_BH1780) += bh1780.o |
| 16 | 17 | obj-$(CONFIG_CM32181) += cm32181.o |
| @@ -0,0 +1,800 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0-only | |
| 2 | +/* | |
| 3 | + * Support for AMS AS73211 JENCOLOR(R) Digital XYZ Sensor | |
| 4 | + * | |
| 5 | + * Author: Christian Eggers <ceggers@arri.de> | |
| 6 | + * | |
| 7 | + * Copyright (c) 2020 ARRI Lighting | |
| 8 | + * | |
| 9 | + * Color light sensor with 16-bit channels for x, y, z and temperature); | |
| 10 | + * 7-bit I2C slave address 0x74 .. 0x77. | |
| 11 | + * | |
| 12 | + * Datasheet: https://ams.com/documents/20143/36005/AS73211_DS000556_3-01.pdf | |
| 13 | + */ | |
| 14 | + | |
| 15 | +#include <linux/bitfield.h> | |
| 16 | +#include <linux/completion.h> | |
| 17 | +#include <linux/delay.h> | |
| 18 | +#include <linux/i2c.h> | |
| 19 | +#include <linux/iio/buffer.h> | |
| 20 | +#include <linux/iio/iio.h> | |
| 21 | +#include <linux/iio/sysfs.h> | |
| 22 | +#include <linux/iio/trigger_consumer.h> | |
| 23 | +#include <linux/iio/triggered_buffer.h> | |
| 24 | +#include <linux/module.h> | |
| 25 | +#include <linux/mutex.h> | |
| 26 | +#include <linux/pm.h> | |
| 27 | + | |
| 28 | +#define HZ_PER_KHZ 1000 | |
| 29 | + | |
| 30 | +#define AS73211_DRV_NAME "as73211" | |
| 31 | + | |
| 32 | +/* AS73211 configuration registers */ | |
| 33 | +#define AS73211_REG_OSR 0x0 | |
| 34 | +#define AS73211_REG_AGEN 0x2 | |
| 35 | +#define AS73211_REG_CREG1 0x6 | |
| 36 | +#define AS73211_REG_CREG2 0x7 | |
| 37 | +#define AS73211_REG_CREG3 0x8 | |
| 38 | + | |
| 39 | +/* AS73211 output register bank */ | |
| 40 | +#define AS73211_OUT_OSR_STATUS 0 | |
| 41 | +#define AS73211_OUT_TEMP 1 | |
| 42 | +#define AS73211_OUT_MRES1 2 | |
| 43 | +#define AS73211_OUT_MRES2 3 | |
| 44 | +#define AS73211_OUT_MRES3 4 | |
| 45 | + | |
| 46 | +#define AS73211_OSR_SS BIT(7) | |
| 47 | +#define AS73211_OSR_PD BIT(6) | |
| 48 | +#define AS73211_OSR_SW_RES BIT(3) | |
| 49 | +#define AS73211_OSR_DOS_MASK GENMASK(2, 0) | |
| 50 | +#define AS73211_OSR_DOS_CONFIG FIELD_PREP(AS73211_OSR_DOS_MASK, 0x2) | |
| 51 | +#define AS73211_OSR_DOS_MEASURE FIELD_PREP(AS73211_OSR_DOS_MASK, 0x3) | |
| 52 | + | |
| 53 | +#define AS73211_AGEN_DEVID_MASK GENMASK(7, 4) | |
| 54 | +#define AS73211_AGEN_DEVID(x) FIELD_PREP(AS73211_AGEN_DEVID_MASK, (x)) | |
| 55 | +#define AS73211_AGEN_MUT_MASK GENMASK(3, 0) | |
| 56 | +#define AS73211_AGEN_MUT(x) FIELD_PREP(AS73211_AGEN_MUT_MASK, (x)) | |
| 57 | + | |
| 58 | +#define AS73211_CREG1_GAIN_MASK GENMASK(7, 4) | |
| 59 | +#define AS73211_CREG1_GAIN_1 11 | |
| 60 | +#define AS73211_CREG1_TIME_MASK GENMASK(3, 0) | |
| 61 | + | |
| 62 | +#define AS73211_CREG3_CCLK_MASK GENMASK(1, 0) | |
| 63 | + | |
| 64 | +#define AS73211_OSR_STATUS_OUTCONVOF BIT(15) | |
| 65 | +#define AS73211_OSR_STATUS_MRESOF BIT(14) | |
| 66 | +#define AS73211_OSR_STATUS_ADCOF BIT(13) | |
| 67 | +#define AS73211_OSR_STATUS_LDATA BIT(12) | |
| 68 | +#define AS73211_OSR_STATUS_NDATA BIT(11) | |
| 69 | +#define AS73211_OSR_STATUS_NOTREADY BIT(10) | |
| 70 | + | |
| 71 | +#define AS73211_SAMPLE_FREQ_BASE 1024000 | |
| 72 | + | |
| 73 | +#define AS73211_SAMPLE_TIME_NUM 15 | |
| 74 | +#define AS73211_SAMPLE_TIME_MAX_MS BIT(AS73211_SAMPLE_TIME_NUM - 1) | |
| 75 | + | |
| 76 | +/* Available sample frequencies are 1.024MHz multiplied by powers of two. */ | |
| 77 | +static const int as73211_samp_freq_avail[] = { | |
| 78 | + AS73211_SAMPLE_FREQ_BASE * 1, | |
| 79 | + AS73211_SAMPLE_FREQ_BASE * 2, | |
| 80 | + AS73211_SAMPLE_FREQ_BASE * 4, | |
| 81 | + AS73211_SAMPLE_FREQ_BASE * 8, | |
| 82 | +}; | |
| 83 | + | |
| 84 | +static const int as73211_hardwaregain_avail[] = { | |
| 85 | + 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, | |
| 86 | +}; | |
| 87 | + | |
| 88 | +/** | |
| 89 | + * struct as73211_data - Instance data for one AS73211 | |
| 90 | + * @client: I2C client. | |
| 91 | + * @osr: Cached Operational State Register. | |
| 92 | + * @creg1: Cached Configuration Register 1. | |
| 93 | + * @creg2: Cached Configuration Register 2. | |
| 94 | + * @creg3: Cached Configuration Register 3. | |
| 95 | + * @mutex: Keeps cached registers in sync with the device. | |
| 96 | + * @completion: Completion to wait for interrupt. | |
| 97 | + * @int_time_avail: Available integration times (depend on sampling frequency). | |
| 98 | + */ | |
| 99 | +struct as73211_data { | |
| 100 | + struct i2c_client *client; | |
| 101 | + u8 osr; | |
| 102 | + u8 creg1; | |
| 103 | + u8 creg2; | |
| 104 | + u8 creg3; | |
| 105 | + struct mutex mutex; | |
| 106 | + struct completion completion; | |
| 107 | + int int_time_avail[AS73211_SAMPLE_TIME_NUM * 2]; | |
| 108 | +}; | |
| 109 | + | |
| 110 | +#define AS73211_COLOR_CHANNEL(_color, _si, _addr) { \ | |
| 111 | + .type = IIO_INTENSITY, \ | |
| 112 | + .modified = 1, \ | |
| 113 | + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), \ | |
| 114 | + .info_mask_shared_by_type = \ | |
| 115 | + BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ | |
| 116 | + BIT(IIO_CHAN_INFO_HARDWAREGAIN) | \ | |
| 117 | + BIT(IIO_CHAN_INFO_INT_TIME), \ | |
| 118 | + .info_mask_shared_by_type_available = \ | |
| 119 | + BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ | |
| 120 | + BIT(IIO_CHAN_INFO_HARDWAREGAIN) | \ | |
| 121 | + BIT(IIO_CHAN_INFO_INT_TIME), \ | |
| 122 | + .channel2 = IIO_MOD_##_color, \ | |
| 123 | + .address = _addr, \ | |
| 124 | + .scan_index = _si, \ | |
| 125 | + .scan_type = { \ | |
| 126 | + .sign = 'u', \ | |
| 127 | + .realbits = 16, \ | |
| 128 | + .storagebits = 16, \ | |
| 129 | + .endianness = IIO_LE, \ | |
| 130 | + }, \ | |
| 131 | +} | |
| 132 | + | |
| 133 | +#define AS73211_OFFSET_TEMP_INT (-66) | |
| 134 | +#define AS73211_OFFSET_TEMP_MICRO 900000 | |
| 135 | +#define AS73211_SCALE_TEMP_INT 0 | |
| 136 | +#define AS73211_SCALE_TEMP_MICRO 50000 | |
| 137 | + | |
| 138 | +#define AS73211_SCALE_X 277071108 /* nW/m^2 */ | |
| 139 | +#define AS73211_SCALE_Y 298384270 /* nW/m^2 */ | |
| 140 | +#define AS73211_SCALE_Z 160241927 /* nW/m^2 */ | |
| 141 | + | |
| 142 | +/* Channel order MUST match devices result register order */ | |
| 143 | +#define AS73211_SCAN_INDEX_TEMP 0 | |
| 144 | +#define AS73211_SCAN_INDEX_X 1 | |
| 145 | +#define AS73211_SCAN_INDEX_Y 2 | |
| 146 | +#define AS73211_SCAN_INDEX_Z 3 | |
| 147 | +#define AS73211_SCAN_INDEX_TS 4 | |
| 148 | + | |
| 149 | +#define AS73211_SCAN_MASK_COLOR ( \ | |
| 150 | + BIT(AS73211_SCAN_INDEX_X) | \ | |
| 151 | + BIT(AS73211_SCAN_INDEX_Y) | \ | |
| 152 | + BIT(AS73211_SCAN_INDEX_Z)) | |
| 153 | + | |
| 154 | +#define AS73211_SCAN_MASK_ALL ( \ | |
| 155 | + BIT(AS73211_SCAN_INDEX_TEMP) | \ | |
| 156 | + AS73211_SCAN_MASK_COLOR) | |
| 157 | + | |
| 158 | +static const struct iio_chan_spec as73211_channels[] = { | |
| 159 | + { | |
| 160 | + .type = IIO_TEMP, | |
| 161 | + .info_mask_separate = | |
| 162 | + BIT(IIO_CHAN_INFO_RAW) | | |
| 163 | + BIT(IIO_CHAN_INFO_OFFSET) | | |
| 164 | + BIT(IIO_CHAN_INFO_SCALE), | |
| 165 | + .address = AS73211_OUT_TEMP, | |
| 166 | + .scan_index = AS73211_SCAN_INDEX_TEMP, | |
| 167 | + .scan_type = { | |
| 168 | + .sign = 'u', | |
| 169 | + .realbits = 16, | |
| 170 | + .storagebits = 16, | |
| 171 | + .endianness = IIO_LE, | |
| 172 | + } | |
| 173 | + }, | |
| 174 | + AS73211_COLOR_CHANNEL(X, AS73211_SCAN_INDEX_X, AS73211_OUT_MRES1), | |
| 175 | + AS73211_COLOR_CHANNEL(Y, AS73211_SCAN_INDEX_Y, AS73211_OUT_MRES2), | |
| 176 | + AS73211_COLOR_CHANNEL(Z, AS73211_SCAN_INDEX_Z, AS73211_OUT_MRES3), | |
| 177 | + IIO_CHAN_SOFT_TIMESTAMP(AS73211_SCAN_INDEX_TS), | |
| 178 | +}; | |
| 179 | + | |
| 180 | +static unsigned int as73211_integration_time_1024cyc(struct as73211_data *data) | |
| 181 | +{ | |
| 182 | + /* | |
| 183 | + * Return integration time in units of 1024 clock cycles. Integration time | |
| 184 | + * in CREG1 is in powers of 2 (x 1024 cycles). | |
| 185 | + */ | |
| 186 | + return BIT(FIELD_GET(AS73211_CREG1_TIME_MASK, data->creg1)); | |
| 187 | +} | |
| 188 | + | |
| 189 | +static unsigned int as73211_integration_time_us(struct as73211_data *data, | |
| 190 | + unsigned int integration_time_1024cyc) | |
| 191 | +{ | |
| 192 | + /* | |
| 193 | + * f_samp is configured in CREG3 in powers of 2 (x 1.024 MHz) | |
| 194 | + * t_cycl is configured in CREG1 in powers of 2 (x 1024 cycles) | |
| 195 | + * t_int_us = 1 / (f_samp) * t_cycl * US_PER_SEC | |
| 196 | + * = 1 / (2^CREG3_CCLK * 1,024,000) * 2^CREG1_CYCLES * 1,024 * US_PER_SEC | |
| 197 | + * = 2^(-CREG3_CCLK) * 2^CREG1_CYCLES * 1,000 | |
| 198 | + * In order to get rid of negative exponents, we extend the "fraction" | |
| 199 | + * by 2^3 (CREG3_CCLK,max = 3) | |
| 200 | + * t_int_us = 2^(3-CREG3_CCLK) * 2^CREG1_CYCLES * 125 | |
| 201 | + */ | |
| 202 | + return BIT(3 - FIELD_GET(AS73211_CREG3_CCLK_MASK, data->creg3)) * | |
| 203 | + integration_time_1024cyc * 125; | |
| 204 | +} | |
| 205 | + | |
| 206 | +static void as73211_integration_time_calc_avail(struct as73211_data *data) | |
| 207 | +{ | |
| 208 | + int i; | |
| 209 | + | |
| 210 | + for (i = 0; i < ARRAY_SIZE(data->int_time_avail) / 2; i++) { | |
| 211 | + unsigned int time_us = as73211_integration_time_us(data, BIT(i)); | |
| 212 | + | |
| 213 | + data->int_time_avail[i * 2 + 0] = time_us / USEC_PER_SEC; | |
| 214 | + data->int_time_avail[i * 2 + 1] = time_us % USEC_PER_SEC; | |
| 215 | + } | |
| 216 | +} | |
| 217 | + | |
| 218 | +static unsigned int as73211_gain(struct as73211_data *data) | |
| 219 | +{ | |
| 220 | + /* gain can be calculated from CREG1 as 2^(11 - CREG1_GAIN) */ | |
| 221 | + return BIT(AS73211_CREG1_GAIN_1 - FIELD_GET(AS73211_CREG1_GAIN_MASK, data->creg1)); | |
| 222 | +} | |
| 223 | + | |
| 224 | +/* must be called with as73211_data::mutex held. */ | |
| 225 | +static int as73211_req_data(struct as73211_data *data) | |
| 226 | +{ | |
| 227 | + unsigned int time_us = as73211_integration_time_us(data, | |
| 228 | + as73211_integration_time_1024cyc(data)); | |
| 229 | + struct device *dev = &data->client->dev; | |
| 230 | + union i2c_smbus_data smbus_data; | |
| 231 | + u16 osr_status; | |
| 232 | + int ret; | |
| 233 | + | |
| 234 | + if (data->client->irq) | |
| 235 | + reinit_completion(&data->completion); | |
| 236 | + | |
| 237 | + /* | |
| 238 | + * During measurement, there should be no traffic on the i2c bus as the | |
| 239 | + * electrical noise would disturb the measurement process. | |
| 240 | + */ | |
| 241 | + i2c_lock_bus(data->client->adapter, I2C_LOCK_SEGMENT); | |
| 242 | + | |
| 243 | + data->osr &= ~AS73211_OSR_DOS_MASK; | |
| 244 | + data->osr |= AS73211_OSR_DOS_MEASURE | AS73211_OSR_SS; | |
| 245 | + | |
| 246 | + smbus_data.byte = data->osr; | |
| 247 | + ret = __i2c_smbus_xfer(data->client->adapter, data->client->addr, | |
| 248 | + data->client->flags, I2C_SMBUS_WRITE, | |
| 249 | + AS73211_REG_OSR, I2C_SMBUS_BYTE_DATA, &smbus_data); | |
| 250 | + if (ret < 0) { | |
| 251 | + i2c_unlock_bus(data->client->adapter, I2C_LOCK_SEGMENT); | |
| 252 | + return ret; | |
| 253 | + } | |
| 254 | + | |
| 255 | + /* | |
| 256 | + * Reset AS73211_OSR_SS (is self clearing) in order to avoid unintentional | |
| 257 | + * triggering of further measurements later. | |
| 258 | + */ | |
| 259 | + data->osr &= ~AS73211_OSR_SS; | |
| 260 | + | |
| 261 | + /* | |
| 262 | + * Add 33% extra margin for the timeout. fclk,min = fclk,typ - 27%. | |
| 263 | + */ | |
| 264 | + time_us += time_us / 3; | |
| 265 | + if (data->client->irq) { | |
| 266 | + ret = wait_for_completion_timeout(&data->completion, usecs_to_jiffies(time_us)); | |
| 267 | + if (!ret) { | |
| 268 | + dev_err(dev, "timeout waiting for READY IRQ\n"); | |
| 269 | + i2c_unlock_bus(data->client->adapter, I2C_LOCK_SEGMENT); | |
| 270 | + return -ETIMEDOUT; | |
| 271 | + } | |
| 272 | + } else { | |
| 273 | + /* Wait integration time */ | |
| 274 | + usleep_range(time_us, 2 * time_us); | |
| 275 | + } | |
| 276 | + | |
| 277 | + i2c_unlock_bus(data->client->adapter, I2C_LOCK_SEGMENT); | |
| 278 | + | |
| 279 | + ret = i2c_smbus_read_word_data(data->client, AS73211_OUT_OSR_STATUS); | |
| 280 | + if (ret < 0) | |
| 281 | + return ret; | |
| 282 | + | |
| 283 | + osr_status = ret; | |
| 284 | + if (osr_status != (AS73211_OSR_DOS_MEASURE | AS73211_OSR_STATUS_NDATA)) { | |
| 285 | + if (osr_status & AS73211_OSR_SS) { | |
| 286 | + dev_err(dev, "%s() Measurement has not stopped\n", __func__); | |
| 287 | + return -ETIME; | |
| 288 | + } | |
| 289 | + if (osr_status & AS73211_OSR_STATUS_NOTREADY) { | |
| 290 | + dev_err(dev, "%s() Data is not ready\n", __func__); | |
| 291 | + return -ENODATA; | |
| 292 | + } | |
| 293 | + if (!(osr_status & AS73211_OSR_STATUS_NDATA)) { | |
| 294 | + dev_err(dev, "%s() No new data available\n", __func__); | |
| 295 | + return -ENODATA; | |
| 296 | + } | |
| 297 | + if (osr_status & AS73211_OSR_STATUS_LDATA) { | |
| 298 | + dev_err(dev, "%s() Result buffer overrun\n", __func__); | |
| 299 | + return -ENOBUFS; | |
| 300 | + } | |
| 301 | + if (osr_status & AS73211_OSR_STATUS_ADCOF) { | |
| 302 | + dev_err(dev, "%s() ADC overflow\n", __func__); | |
| 303 | + return -EOVERFLOW; | |
| 304 | + } | |
| 305 | + if (osr_status & AS73211_OSR_STATUS_MRESOF) { | |
| 306 | + dev_err(dev, "%s() Measurement result overflow\n", __func__); | |
| 307 | + return -EOVERFLOW; | |
| 308 | + } | |
| 309 | + if (osr_status & AS73211_OSR_STATUS_OUTCONVOF) { | |
| 310 | + dev_err(dev, "%s() Timer overflow\n", __func__); | |
| 311 | + return -EOVERFLOW; | |
| 312 | + } | |
| 313 | + dev_err(dev, "%s() Unexpected status value\n", __func__); | |
| 314 | + return -EIO; | |
| 315 | + } | |
| 316 | + | |
| 317 | + return 0; | |
| 318 | +} | |
| 319 | + | |
| 320 | +static int as73211_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, | |
| 321 | + int *val, int *val2, long mask) | |
| 322 | +{ | |
| 323 | + struct as73211_data *data = iio_priv(indio_dev); | |
| 324 | + | |
| 325 | + switch (mask) { | |
| 326 | + case IIO_CHAN_INFO_RAW: { | |
| 327 | + int ret; | |
| 328 | + | |
| 329 | + ret = iio_device_claim_direct_mode(indio_dev); | |
| 330 | + if (ret < 0) | |
| 331 | + return ret; | |
| 332 | + | |
| 333 | + ret = as73211_req_data(data); | |
| 334 | + if (ret < 0) { | |
| 335 | + iio_device_release_direct_mode(indio_dev); | |
| 336 | + return ret; | |
| 337 | + } | |
| 338 | + | |
| 339 | + ret = i2c_smbus_read_word_data(data->client, chan->address); | |
| 340 | + iio_device_release_direct_mode(indio_dev); | |
| 341 | + if (ret < 0) | |
| 342 | + return ret; | |
| 343 | + | |
| 344 | + *val = ret; | |
| 345 | + return IIO_VAL_INT; | |
| 346 | + } | |
| 347 | + case IIO_CHAN_INFO_OFFSET: | |
| 348 | + *val = AS73211_OFFSET_TEMP_INT; | |
| 349 | + *val2 = AS73211_OFFSET_TEMP_MICRO; | |
| 350 | + return IIO_VAL_INT_PLUS_MICRO; | |
| 351 | + | |
| 352 | + case IIO_CHAN_INFO_SCALE: | |
| 353 | + switch (chan->type) { | |
| 354 | + case IIO_TEMP: | |
| 355 | + *val = AS73211_SCALE_TEMP_INT; | |
| 356 | + *val2 = AS73211_SCALE_TEMP_MICRO; | |
| 357 | + return IIO_VAL_INT_PLUS_MICRO; | |
| 358 | + | |
| 359 | + case IIO_INTENSITY: { | |
| 360 | + unsigned int scale; | |
| 361 | + | |
| 362 | + switch (chan->channel2) { | |
| 363 | + case IIO_MOD_X: | |
| 364 | + scale = AS73211_SCALE_X; | |
| 365 | + break; | |
| 366 | + case IIO_MOD_Y: | |
| 367 | + scale = AS73211_SCALE_Y; | |
| 368 | + break; | |
| 369 | + case IIO_MOD_Z: | |
| 370 | + scale = AS73211_SCALE_Z; | |
| 371 | + break; | |
| 372 | + default: | |
| 373 | + return -EINVAL; | |
| 374 | + } | |
| 375 | + scale /= as73211_gain(data); | |
| 376 | + scale /= as73211_integration_time_1024cyc(data); | |
| 377 | + *val = scale; | |
| 378 | + return IIO_VAL_INT; | |
| 379 | + | |
| 380 | + default: | |
| 381 | + return -EINVAL; | |
| 382 | + }} | |
| 383 | + | |
| 384 | + case IIO_CHAN_INFO_SAMP_FREQ: | |
| 385 | + /* f_samp is configured in CREG3 in powers of 2 (x 1.024 MHz) */ | |
| 386 | + *val = BIT(FIELD_GET(AS73211_CREG3_CCLK_MASK, data->creg3)) * | |
| 387 | + AS73211_SAMPLE_FREQ_BASE; | |
| 388 | + return IIO_VAL_INT; | |
| 389 | + | |
| 390 | + case IIO_CHAN_INFO_HARDWAREGAIN: | |
| 391 | + *val = as73211_gain(data); | |
| 392 | + return IIO_VAL_INT; | |
| 393 | + | |
| 394 | + case IIO_CHAN_INFO_INT_TIME: { | |
| 395 | + unsigned int time_us; | |
| 396 | + | |
| 397 | + mutex_lock(&data->mutex); | |
| 398 | + time_us = as73211_integration_time_us(data, as73211_integration_time_1024cyc(data)); | |
| 399 | + mutex_unlock(&data->mutex); | |
| 400 | + *val = time_us / USEC_PER_SEC; | |
| 401 | + *val2 = time_us % USEC_PER_SEC; | |
| 402 | + return IIO_VAL_INT_PLUS_MICRO; | |
| 403 | + | |
| 404 | + default: | |
| 405 | + return -EINVAL; | |
| 406 | + }} | |
| 407 | +} | |
| 408 | + | |
| 409 | +static int as73211_read_avail(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, | |
| 410 | + const int **vals, int *type, int *length, long mask) | |
| 411 | +{ | |
| 412 | + struct as73211_data *data = iio_priv(indio_dev); | |
| 413 | + | |
| 414 | + switch (mask) { | |
| 415 | + case IIO_CHAN_INFO_SAMP_FREQ: | |
| 416 | + *length = ARRAY_SIZE(as73211_samp_freq_avail); | |
| 417 | + *vals = as73211_samp_freq_avail; | |
| 418 | + *type = IIO_VAL_INT; | |
| 419 | + return IIO_AVAIL_LIST; | |
| 420 | + | |
| 421 | + case IIO_CHAN_INFO_HARDWAREGAIN: | |
| 422 | + *length = ARRAY_SIZE(as73211_hardwaregain_avail); | |
| 423 | + *vals = as73211_hardwaregain_avail; | |
| 424 | + *type = IIO_VAL_INT; | |
| 425 | + return IIO_AVAIL_LIST; | |
| 426 | + | |
| 427 | + case IIO_CHAN_INFO_INT_TIME: | |
| 428 | + *length = ARRAY_SIZE(data->int_time_avail); | |
| 429 | + *vals = data->int_time_avail; | |
| 430 | + *type = IIO_VAL_INT_PLUS_MICRO; | |
| 431 | + return IIO_AVAIL_LIST; | |
| 432 | + | |
| 433 | + default: | |
| 434 | + return -EINVAL; | |
| 435 | + } | |
| 436 | +} | |
| 437 | + | |
| 438 | +static int _as73211_write_raw(struct iio_dev *indio_dev, | |
| 439 | + struct iio_chan_spec const *chan __always_unused, | |
| 440 | + int val, int val2, long mask) | |
| 441 | +{ | |
| 442 | + struct as73211_data *data = iio_priv(indio_dev); | |
| 443 | + int ret; | |
| 444 | + | |
| 445 | + switch (mask) { | |
| 446 | + case IIO_CHAN_INFO_SAMP_FREQ: { | |
| 447 | + int reg_bits, freq_kHz = val / HZ_PER_KHZ; /* 1024, 2048, ... */ | |
| 448 | + | |
| 449 | + /* val must be 1024 * 2^x */ | |
| 450 | + if (val < 0 || (freq_kHz * HZ_PER_KHZ) != val || | |
| 451 | + !is_power_of_2(freq_kHz) || val2) | |
| 452 | + return -EINVAL; | |
| 453 | + | |
| 454 | + /* f_samp is configured in CREG3 in powers of 2 (x 1.024 MHz (=2^10)) */ | |
| 455 | + reg_bits = ilog2(freq_kHz) - 10; | |
| 456 | + if (!FIELD_FIT(AS73211_CREG3_CCLK_MASK, reg_bits)) | |
| 457 | + return -EINVAL; | |
| 458 | + | |
| 459 | + data->creg3 &= ~AS73211_CREG3_CCLK_MASK; | |
| 460 | + data->creg3 |= FIELD_PREP(AS73211_CREG3_CCLK_MASK, reg_bits); | |
| 461 | + as73211_integration_time_calc_avail(data); | |
| 462 | + | |
| 463 | + ret = i2c_smbus_write_byte_data(data->client, AS73211_REG_CREG3, data->creg3); | |
| 464 | + if (ret < 0) | |
| 465 | + return ret; | |
| 466 | + | |
| 467 | + return 0; | |
| 468 | + } | |
| 469 | + case IIO_CHAN_INFO_HARDWAREGAIN: { | |
| 470 | + unsigned int reg_bits; | |
| 471 | + | |
| 472 | + if (val < 0 || !is_power_of_2(val) || val2) | |
| 473 | + return -EINVAL; | |
| 474 | + | |
| 475 | + /* gain can be calculated from CREG1 as 2^(11 - CREG1_GAIN) */ | |
| 476 | + reg_bits = AS73211_CREG1_GAIN_1 - ilog2(val); | |
| 477 | + if (!FIELD_FIT(AS73211_CREG1_GAIN_MASK, reg_bits)) | |
| 478 | + return -EINVAL; | |
| 479 | + | |
| 480 | + data->creg1 &= ~AS73211_CREG1_GAIN_MASK; | |
| 481 | + data->creg1 |= FIELD_PREP(AS73211_CREG1_GAIN_MASK, reg_bits); | |
| 482 | + | |
| 483 | + ret = i2c_smbus_write_byte_data(data->client, AS73211_REG_CREG1, data->creg1); | |
| 484 | + if (ret < 0) | |
| 485 | + return ret; | |
| 486 | + | |
| 487 | + return 0; | |
| 488 | + } | |
| 489 | + case IIO_CHAN_INFO_INT_TIME: { | |
| 490 | + int val_us = val * USEC_PER_SEC + val2; | |
| 491 | + int time_ms; | |
| 492 | + int reg_bits; | |
| 493 | + | |
| 494 | + /* f_samp is configured in CREG3 in powers of 2 (x 1.024 MHz) */ | |
| 495 | + int f_samp_1_024mhz = BIT(FIELD_GET(AS73211_CREG3_CCLK_MASK, data->creg3)); | |
| 496 | + | |
| 497 | + /* | |
| 498 | + * time_ms = time_us * US_PER_MS * f_samp_1_024mhz / MHZ_PER_HZ | |
| 499 | + * = time_us * f_samp_1_024mhz / 1000 | |
| 500 | + */ | |
| 501 | + time_ms = (val_us * f_samp_1_024mhz) / 1000; /* 1 ms, 2 ms, ... (power of two) */ | |
| 502 | + if (time_ms < 0 || !is_power_of_2(time_ms) || time_ms > AS73211_SAMPLE_TIME_MAX_MS) | |
| 503 | + return -EINVAL; | |
| 504 | + | |
| 505 | + reg_bits = ilog2(time_ms); | |
| 506 | + if (!FIELD_FIT(AS73211_CREG1_TIME_MASK, reg_bits)) | |
| 507 | + return -EINVAL; /* not possible due to previous tests */ | |
| 508 | + | |
| 509 | + data->creg1 &= ~AS73211_CREG1_TIME_MASK; | |
| 510 | + data->creg1 |= FIELD_PREP(AS73211_CREG1_TIME_MASK, reg_bits); | |
| 511 | + | |
| 512 | + ret = i2c_smbus_write_byte_data(data->client, AS73211_REG_CREG1, data->creg1); | |
| 513 | + if (ret < 0) | |
| 514 | + return ret; | |
| 515 | + | |
| 516 | + return 0; | |
| 517 | + | |
| 518 | + default: | |
| 519 | + return -EINVAL; | |
| 520 | + }} | |
| 521 | +} | |
| 522 | + | |
| 523 | +static int as73211_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, | |
| 524 | + int val, int val2, long mask) | |
| 525 | +{ | |
| 526 | + struct as73211_data *data = iio_priv(indio_dev); | |
| 527 | + int ret; | |
| 528 | + | |
| 529 | + mutex_lock(&data->mutex); | |
| 530 | + | |
| 531 | + ret = iio_device_claim_direct_mode(indio_dev); | |
| 532 | + if (ret < 0) | |
| 533 | + goto error_unlock; | |
| 534 | + | |
| 535 | + /* Need to switch to config mode ... */ | |
| 536 | + if ((data->osr & AS73211_OSR_DOS_MASK) != AS73211_OSR_DOS_CONFIG) { | |
| 537 | + data->osr &= ~AS73211_OSR_DOS_MASK; | |
| 538 | + data->osr |= AS73211_OSR_DOS_CONFIG; | |
| 539 | + | |
| 540 | + ret = i2c_smbus_write_byte_data(data->client, AS73211_REG_OSR, data->osr); | |
| 541 | + if (ret < 0) | |
| 542 | + goto error_release; | |
| 543 | + } | |
| 544 | + | |
| 545 | + ret = _as73211_write_raw(indio_dev, chan, val, val2, mask); | |
| 546 | + | |
| 547 | +error_release: | |
| 548 | + iio_device_release_direct_mode(indio_dev); | |
| 549 | +error_unlock: | |
| 550 | + mutex_unlock(&data->mutex); | |
| 551 | + return ret; | |
| 552 | +} | |
| 553 | + | |
| 554 | +static irqreturn_t as73211_ready_handler(int irq __always_unused, void *priv) | |
| 555 | +{ | |
| 556 | + struct as73211_data *data = iio_priv(priv); | |
| 557 | + | |
| 558 | + complete(&data->completion); | |
| 559 | + | |
| 560 | + return IRQ_HANDLED; | |
| 561 | +} | |
| 562 | + | |
| 563 | +static irqreturn_t as73211_trigger_handler(int irq __always_unused, void *p) | |
| 564 | +{ | |
| 565 | + struct iio_poll_func *pf = p; | |
| 566 | + struct iio_dev *indio_dev = pf->indio_dev; | |
| 567 | + struct as73211_data *data = iio_priv(indio_dev); | |
| 568 | + struct { | |
| 569 | + __le16 chan[4]; | |
| 570 | + s64 ts __aligned(8); | |
| 571 | + } scan; | |
| 572 | + int data_result, ret; | |
| 573 | + | |
| 574 | + mutex_lock(&data->mutex); | |
| 575 | + | |
| 576 | + data_result = as73211_req_data(data); | |
| 577 | + if (data_result < 0 && data_result != -EOVERFLOW) | |
| 578 | + goto done; /* don't push any data for errors other than EOVERFLOW */ | |
| 579 | + | |
| 580 | + if (*indio_dev->active_scan_mask == AS73211_SCAN_MASK_ALL) { | |
| 581 | + /* Optimization for reading all (color + temperature) channels */ | |
| 582 | + u8 addr = as73211_channels[0].address; | |
| 583 | + struct i2c_msg msgs[] = { | |
| 584 | + { | |
| 585 | + .addr = data->client->addr, | |
| 586 | + .flags = 0, | |
| 587 | + .len = 1, | |
| 588 | + .buf = &addr, | |
| 589 | + }, | |
| 590 | + { | |
| 591 | + .addr = data->client->addr, | |
| 592 | + .flags = I2C_M_RD, | |
| 593 | + .len = sizeof(scan.chan), | |
| 594 | + .buf = (u8 *)&scan.chan, | |
| 595 | + }, | |
| 596 | + }; | |
| 597 | + | |
| 598 | + ret = i2c_transfer(data->client->adapter, msgs, ARRAY_SIZE(msgs)); | |
| 599 | + if (ret < 0) | |
| 600 | + goto done; | |
| 601 | + } else { | |
| 602 | + /* Optimization for reading only color channels */ | |
| 603 | + | |
| 604 | + /* AS73211 starts reading at address 2 */ | |
| 605 | + ret = i2c_master_recv(data->client, | |
| 606 | + (char *)&scan.chan[1], 3 * sizeof(scan.chan[1])); | |
| 607 | + if (ret < 0) | |
| 608 | + goto done; | |
| 609 | + } | |
| 610 | + | |
| 611 | + if (data_result) { | |
| 612 | + /* | |
| 613 | + * Saturate all channels (in case of overflows). Temperature channel | |
| 614 | + * is not affected by overflows. | |
| 615 | + */ | |
| 616 | + scan.chan[1] = cpu_to_le16(U16_MAX); | |
| 617 | + scan.chan[2] = cpu_to_le16(U16_MAX); | |
| 618 | + scan.chan[3] = cpu_to_le16(U16_MAX); | |
| 619 | + } | |
| 620 | + | |
| 621 | + iio_push_to_buffers_with_timestamp(indio_dev, &scan, iio_get_time_ns(indio_dev)); | |
| 622 | + | |
| 623 | +done: | |
| 624 | + mutex_unlock(&data->mutex); | |
| 625 | + iio_trigger_notify_done(indio_dev->trig); | |
| 626 | + | |
| 627 | + return IRQ_HANDLED; | |
| 628 | +} | |
| 629 | + | |
| 630 | +static const struct iio_info as73211_info = { | |
| 631 | + .read_raw = as73211_read_raw, | |
| 632 | + .read_avail = as73211_read_avail, | |
| 633 | + .write_raw = as73211_write_raw, | |
| 634 | +}; | |
| 635 | + | |
| 636 | +static int as73211_power(struct iio_dev *indio_dev, bool state) | |
| 637 | +{ | |
| 638 | + struct as73211_data *data = iio_priv(indio_dev); | |
| 639 | + int ret; | |
| 640 | + | |
| 641 | + mutex_lock(&data->mutex); | |
| 642 | + | |
| 643 | + if (state) | |
| 644 | + data->osr &= ~AS73211_OSR_PD; | |
| 645 | + else | |
| 646 | + data->osr |= AS73211_OSR_PD; | |
| 647 | + | |
| 648 | + ret = i2c_smbus_write_byte_data(data->client, AS73211_REG_OSR, data->osr); | |
| 649 | + | |
| 650 | + mutex_unlock(&data->mutex); | |
| 651 | + | |
| 652 | + if (ret < 0) | |
| 653 | + return ret; | |
| 654 | + | |
| 655 | + return 0; | |
| 656 | +} | |
| 657 | + | |
| 658 | +static void as73211_power_disable(void *data) | |
| 659 | +{ | |
| 660 | + struct iio_dev *indio_dev = data; | |
| 661 | + | |
| 662 | + as73211_power(indio_dev, false); | |
| 663 | +} | |
| 664 | + | |
| 665 | +static int as73211_probe(struct i2c_client *client) | |
| 666 | +{ | |
| 667 | + struct device *dev = &client->dev; | |
| 668 | + struct as73211_data *data; | |
| 669 | + struct iio_dev *indio_dev; | |
| 670 | + int ret; | |
| 671 | + | |
| 672 | + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); | |
| 673 | + if (!indio_dev) | |
| 674 | + return -ENOMEM; | |
| 675 | + | |
| 676 | + data = iio_priv(indio_dev); | |
| 677 | + i2c_set_clientdata(client, indio_dev); | |
| 678 | + data->client = client; | |
| 679 | + | |
| 680 | + mutex_init(&data->mutex); | |
| 681 | + init_completion(&data->completion); | |
| 682 | + | |
| 683 | + indio_dev->info = &as73211_info; | |
| 684 | + indio_dev->name = AS73211_DRV_NAME; | |
| 685 | + indio_dev->channels = as73211_channels; | |
| 686 | + indio_dev->num_channels = ARRAY_SIZE(as73211_channels); | |
| 687 | + indio_dev->modes = INDIO_DIRECT_MODE; | |
| 688 | + | |
| 689 | + ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_OSR); | |
| 690 | + if (ret < 0) | |
| 691 | + return ret; | |
| 692 | + data->osr = ret; | |
| 693 | + | |
| 694 | + /* reset device */ | |
| 695 | + data->osr |= AS73211_OSR_SW_RES; | |
| 696 | + ret = i2c_smbus_write_byte_data(data->client, AS73211_REG_OSR, data->osr); | |
| 697 | + if (ret < 0) | |
| 698 | + return ret; | |
| 699 | + | |
| 700 | + ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_OSR); | |
| 701 | + if (ret < 0) | |
| 702 | + return ret; | |
| 703 | + data->osr = ret; | |
| 704 | + | |
| 705 | + /* | |
| 706 | + * Reading AGEN is only possible after reset (AGEN is not available if | |
| 707 | + * device is in measurement mode). | |
| 708 | + */ | |
| 709 | + ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_AGEN); | |
| 710 | + if (ret < 0) | |
| 711 | + return ret; | |
| 712 | + | |
| 713 | + /* At the time of writing this driver, only DEVID 2 and MUT 1 are known. */ | |
| 714 | + if ((ret & AS73211_AGEN_DEVID_MASK) != AS73211_AGEN_DEVID(2) || | |
| 715 | + (ret & AS73211_AGEN_MUT_MASK) != AS73211_AGEN_MUT(1)) | |
| 716 | + return -ENODEV; | |
| 717 | + | |
| 718 | + ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_CREG1); | |
| 719 | + if (ret < 0) | |
| 720 | + return ret; | |
| 721 | + data->creg1 = ret; | |
| 722 | + | |
| 723 | + ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_CREG2); | |
| 724 | + if (ret < 0) | |
| 725 | + return ret; | |
| 726 | + data->creg2 = ret; | |
| 727 | + | |
| 728 | + ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_CREG3); | |
| 729 | + if (ret < 0) | |
| 730 | + return ret; | |
| 731 | + data->creg3 = ret; | |
| 732 | + as73211_integration_time_calc_avail(data); | |
| 733 | + | |
| 734 | + ret = as73211_power(indio_dev, true); | |
| 735 | + if (ret < 0) | |
| 736 | + return ret; | |
| 737 | + | |
| 738 | + ret = devm_add_action_or_reset(dev, as73211_power_disable, indio_dev); | |
| 739 | + if (ret) | |
| 740 | + return ret; | |
| 741 | + | |
| 742 | + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, as73211_trigger_handler, NULL); | |
| 743 | + if (ret) | |
| 744 | + return ret; | |
| 745 | + | |
| 746 | + if (client->irq) { | |
| 747 | + ret = devm_request_threaded_irq(&client->dev, client->irq, | |
| 748 | + NULL, | |
| 749 | + as73211_ready_handler, | |
| 750 | + IRQF_ONESHOT, | |
| 751 | + client->name, indio_dev); | |
| 752 | + if (ret) | |
| 753 | + return ret; | |
| 754 | + } | |
| 755 | + | |
| 756 | + return devm_iio_device_register(dev, indio_dev); | |
| 757 | +} | |
| 758 | + | |
| 759 | +static int __maybe_unused as73211_suspend(struct device *dev) | |
| 760 | +{ | |
| 761 | + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); | |
| 762 | + | |
| 763 | + return as73211_power(indio_dev, false); | |
| 764 | +} | |
| 765 | + | |
| 766 | +static int __maybe_unused as73211_resume(struct device *dev) | |
| 767 | +{ | |
| 768 | + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); | |
| 769 | + | |
| 770 | + return as73211_power(indio_dev, true); | |
| 771 | +} | |
| 772 | + | |
| 773 | +static SIMPLE_DEV_PM_OPS(as73211_pm_ops, as73211_suspend, as73211_resume); | |
| 774 | + | |
| 775 | +static const struct of_device_id as73211_of_match[] = { | |
| 776 | + { .compatible = "ams,as73211" }, | |
| 777 | + { } | |
| 778 | +}; | |
| 779 | +MODULE_DEVICE_TABLE(of, as73211_of_match); | |
| 780 | + | |
| 781 | +static const struct i2c_device_id as73211_id[] = { | |
| 782 | + { "as73211", 0 }, | |
| 783 | + { } | |
| 784 | +}; | |
| 785 | +MODULE_DEVICE_TABLE(i2c, as73211_id); | |
| 786 | + | |
| 787 | +static struct i2c_driver as73211_driver = { | |
| 788 | + .driver = { | |
| 789 | + .name = AS73211_DRV_NAME, | |
| 790 | + .of_match_table = as73211_of_match, | |
| 791 | + .pm = &as73211_pm_ops, | |
| 792 | + }, | |
| 793 | + .probe_new = as73211_probe, | |
| 794 | + .id_table = as73211_id, | |
| 795 | +}; | |
| 796 | +module_i2c_driver(as73211_driver); | |
| 797 | + | |
| 798 | +MODULE_AUTHOR("Christian Eggers <ceggers@arri.de>"); | |
| 799 | +MODULE_DESCRIPTION("AS73211 XYZ True Color Sensor driver"); | |
| 800 | +MODULE_LICENSE("GPL"); | |
| @@ -182,12 +182,11 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev) · 181 unmodified lines | ||
| 182 | 182 | |
| 183 | 183 | ret = cros_ec_sensors_core_init(pdev, indio_dev, true, |
| 184 | 184 | cros_ec_sensors_capture, |
| 185 | − cros_ec_sensors_push_data); | |
| 185 | + cros_ec_sensors_push_data, | |
| 186 | + true); | |
| 186 | 187 | if (ret) |
| 187 | 188 | return ret; |
| 188 | 189 | |
| 189 | − iio_buffer_set_attrs(indio_dev->buffer, cros_ec_sensor_fifo_attributes); | |
| 190 | − | |
| 191 | 190 | indio_dev->info = &cros_ec_light_prox_info; |
| 192 | 191 | state = iio_priv(indio_dev); |
| 193 | 192 | state->core.type = state->core.resp->info.type; |
| @@ -566,7 +566,7 @@ static int gp2ap002_probe(struct i2c_client *client, · 565 unmodified lines | ||
| 566 | 566 | |
| 567 | 567 | /* |
| 568 | 568 | * Initialize the device and signal to runtime PM that now we are |
| 569 | − * definately up and using power. | |
| 569 | + * definitely up and using power. | |
| 570 | 570 | */ |
| 571 | 571 | ret = gp2ap002_init(gp2ap002); |
| 572 | 572 | if (ret) { |
| @@ -746,12 +746,9 @@ static int isl29018_probe(struct i2c_client *client, · 745 unmodified lines | ||
| 746 | 746 | chip->suspended = false; |
| 747 | 747 | |
| 748 | 748 | chip->vcc_reg = devm_regulator_get(&client->dev, "vcc"); |
| 749 | − if (IS_ERR(chip->vcc_reg)) { | |
| 750 | − err = PTR_ERR(chip->vcc_reg); | |
| 751 | − if (err != -EPROBE_DEFER) | |
| 752 | − dev_err(&client->dev, "failed to get VCC regulator!\n"); | |
| 753 | − return err; | |
| 754 | − } | |
| 749 | + if (IS_ERR(chip->vcc_reg)) | |
| 750 | + return dev_err_probe(&client->dev, PTR_ERR(chip->vcc_reg), | |
| 751 | + "failed to get VCC regulator!\n"); | |
| 755 | 752 | |
| 756 | 753 | err = regulator_enable(chip->vcc_reg); |
| 757 | 754 | if (err) { |
| @@ -168,6 +168,7 @@ struct si1145_part_info { · 167 unmodified lines | ||
| 168 | 168 | * @part_info: Part information |
| 169 | 169 | * @trig: Pointer to iio trigger |
| 170 | 170 | * @meas_rate: Value of MEAS_RATE register. Only set in HW in auto mode |
| 171 | + * @buffer: Used to pack data read from sensor. | |
| 171 | 172 | */ |
| 172 | 173 | struct si1145_data { |
| 173 | 174 | struct i2c_client *client; |
| @@ -179,6 +180,14 @@ struct si1145_data { · 5 unmodified lines | ||
| 179 | 180 | bool autonomous; |
| 180 | 181 | struct iio_trigger *trig; |
| 181 | 182 | int meas_rate; |
| 183 | + /* | |
| 184 | + * Ensure timestamp will be naturally aligned if present. | |
| 185 | + * Maximum buffer size (may be only partly used if not all | |
| 186 | + * channels are enabled): | |
| 187 | + * 6*2 bytes channels data + 4 bytes alignment + | |
| 188 | + * 8 bytes timestamp | |
| 189 | + */ | |
| 190 | + u8 buffer[24] __aligned(8); | |
| 182 | 191 | }; |
| 183 | 192 | |
| 184 | 193 | /* |
| @@ -440,12 +449,6 @@ static irqreturn_t si1145_trigger_handler(int irq, void *private) · 255 unmodified lines | ||
| 440 | 449 | struct iio_poll_func *pf = private; |
| 441 | 450 | struct iio_dev *indio_dev = pf->indio_dev; |
| 442 | 451 | struct si1145_data *data = iio_priv(indio_dev); |
| 443 | − /* | |
| 444 | − * Maximum buffer size: | |
| 445 | − * 6*2 bytes channels data + 4 bytes alignment + | |
| 446 | − * 8 bytes timestamp | |
| 447 | − */ | |
| 448 | − u8 buffer[24]; | |
| 449 | 452 | int i, j = 0; |
| 450 | 453 | int ret; |
| 451 | 454 | u8 irq_status = 0; |
| @@ -478,7 +481,7 @@ static irqreturn_t si1145_trigger_handler(int irq, void *private) · 26 unmodified lines | ||
| 478 | 481 | |
| 479 | 482 | ret = i2c_smbus_read_i2c_block_data_or_emulated( |
| 480 | 483 | data->client, indio_dev->channels[i].address, |
| 481 | − sizeof(u16) * run, &buffer[j]); | |
| 484 | + sizeof(u16) * run, &data->buffer[j]); | |
| 482 | 485 | if (ret < 0) |
| 483 | 486 | goto done; |
| 484 | 487 | j += run * sizeof(u16); |
| @@ -493,7 +496,7 @@ static irqreturn_t si1145_trigger_handler(int irq, void *private) · 8 unmodified lines | ||
| 493 | 496 | goto done; |
| 494 | 497 | } |
| 495 | 498 | |
| 496 | − iio_push_to_buffers_with_timestamp(indio_dev, buffer, | |
| 499 | + iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, | |
| 497 | 500 | iio_get_time_ns(indio_dev)); |
| 498 | 501 | |
| 499 | 502 | done: |
| @@ -1776,14 +1776,8 @@ static int tsl2772_probe(struct i2c_client *clientp, · 1775 unmodified lines | ||
| 1776 | 1776 | ret = devm_regulator_bulk_get(&clientp->dev, |
| 1777 | 1777 | ARRAY_SIZE(chip->supplies), |
| 1778 | 1778 | chip->supplies); |
| 1779 | − if (ret < 0) { | |
| 1780 | − if (ret != -EPROBE_DEFER) | |
| 1781 | − dev_err(&clientp->dev, | |
| 1782 | − "Failed to get regulators: %d\n", | |
| 1783 | − ret); | |
| 1784 | − | |
| 1785 | − return ret; | |
| 1786 | − } | |
| 1779 | + if (ret < 0) | |
| 1780 | + return dev_err_probe(&clientp->dev, ret, "Failed to get regulators\n"); | |
| 1787 | 1781 | |
| 1788 | 1782 | ret = regulator_bulk_enable(ARRAY_SIZE(chip->supplies), chip->supplies); |
| 1789 | 1783 | if (ret < 0) { |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | * Author: Linus Walleij <linus.walleij@linaro.org> |
| 13 | 13 | */ |
| 14 | 14 | #include <linux/module.h> |
| 15 | +#include <linux/mod_devicetable.h> | |
| 15 | 16 | #include <linux/kernel.h> |
| 16 | 17 | #include <linux/i2c.h> |
| 17 | 18 | #include <linux/interrupt.h> |
| @@ -843,15 +844,8 @@ static int ak8974_probe(struct i2c_client *i2c, · 825 unmodified lines | ||
| 843 | 844 | ret = devm_regulator_bulk_get(&i2c->dev, |
| 844 | 845 | ARRAY_SIZE(ak8974->regs), |
| 845 | 846 | ak8974->regs); |
| 846 | − if (ret < 0) { | |
| 847 | − if (ret != -EPROBE_DEFER) | |
| 848 | − dev_err(&i2c->dev, "cannot get regulators: %d\n", ret); | |
| 849 | − else | |
| 850 | − dev_dbg(&i2c->dev, | |
| 851 | − "regulators unavailable, deferring probe\n"); | |
| 852 | − | |
| 853 | − return ret; | |
| 854 | − } | |
| 847 | + if (ret < 0) | |
| 848 | + return dev_err_probe(&i2c->dev, ret, "cannot get regulators\n"); | |
| 855 | 849 | |
| 856 | 850 | ret = regulator_bulk_enable(ARRAY_SIZE(ak8974->regs), ak8974->regs); |
| 857 | 851 | if (ret < 0) { |
| @@ -1058,7 +1052,7 @@ static struct i2c_driver ak8974_driver = { · 200 unmodified lines | ||
| 1058 | 1052 | .driver = { |
| 1059 | 1053 | .name = "ak8974", |
| 1060 | 1054 | .pm = &ak8974_dev_pm_ops, |
| 1061 | − .of_match_table = of_match_ptr(ak8974_of_match), | |
| 1055 | + .of_match_table = ak8974_of_match, | |
| 1062 | 1056 | }, |
| 1063 | 1057 | .probe = ak8974_probe, |
| 1064 | 1058 | .remove = ak8974_remove, |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | */ |
| 9 | 9 | |
| 10 | 10 | #include <linux/module.h> |
| 11 | +#include <linux/mod_devicetable.h> | |
| 11 | 12 | #include <linux/kernel.h> |
| 12 | 13 | #include <linux/slab.h> |
| 13 | 14 | #include <linux/i2c.h> |
| @@ -17,7 +18,6 @@ · 3 unmodified lines | ||
| 17 | 18 | #include <linux/delay.h> |
| 18 | 19 | #include <linux/bitops.h> |
| 19 | 20 | #include <linux/gpio/consumer.h> |
| 20 | −#include <linux/acpi.h> | |
| 21 | 21 | #include <linux/regulator/consumer.h> |
| 22 | 22 | #include <linux/pm_runtime.h> |
| 23 | 23 | |
| @@ -779,7 +779,6 @@ static const struct iio_info ak8975_info = { · 755 unmodified lines | ||
| 779 | 779 | .read_raw = &ak8975_read_raw, |
| 780 | 780 | }; |
| 781 | 781 | |
| 782 | −#ifdef CONFIG_ACPI | |
| 783 | 782 | static const struct acpi_device_id ak_acpi_match[] = { |
| 784 | 783 | {"AK8975", AK8975}, |
| 785 | 784 | {"AK8963", AK8963}, |
| @@ -791,7 +790,6 @@ static const struct acpi_device_id ak_acpi_match[] = { · 5 unmodified lines | ||
| 791 | 790 | { } |
| 792 | 791 | }; |
| 793 | 792 | MODULE_DEVICE_TABLE(acpi, ak_acpi_match); |
| 794 | −#endif | |
| 795 | 793 | |
| 796 | 794 | static void ak8975_fill_buffer(struct iio_dev *indio_dev) |
| 797 | 795 | { |
| @@ -1081,8 +1079,8 @@ static struct i2c_driver ak8975_driver = { · 283 unmodified lines | ||
| 1081 | 1079 | .driver = { |
| 1082 | 1080 | .name = "ak8975", |
| 1083 | 1081 | .pm = &ak8975_dev_pm_ops, |
| 1084 | − .of_match_table = of_match_ptr(ak8975_of_match), | |
| 1085 | − .acpi_match_table = ACPI_PTR(ak_acpi_match), | |
| 1082 | + .of_match_table = ak8975_of_match, | |
| 1083 | + .acpi_match_table = ak_acpi_match, | |
| 1086 | 1084 | }, |
| 1087 | 1085 | .probe = ak8975_probe, |
| 1088 | 1086 | .remove = ak8975_remove, |
| @@ -245,7 +245,7 @@ static const struct iio_enum hmc5843_meas_conf_enum = { · 244 unmodified lines | ||
| 245 | 245 | }; |
| 246 | 246 | |
| 247 | 247 | static const struct iio_chan_spec_ext_info hmc5843_ext_info[] = { |
| 248 | − IIO_ENUM("meas_conf", true, &hmc5843_meas_conf_enum), | |
| 248 | + IIO_ENUM("meas_conf", IIO_SHARED_BY_TYPE, &hmc5843_meas_conf_enum), | |
| 249 | 249 | IIO_ENUM_AVAILABLE("meas_conf", &hmc5843_meas_conf_enum), |
| 250 | 250 | IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, hmc5843_get_mount_matrix), |
| 251 | 251 | { } |
| @@ -259,7 +259,7 @@ static const struct iio_enum hmc5983_meas_conf_enum = { · 7 unmodified lines | ||
| 259 | 259 | }; |
| 260 | 260 | |
| 261 | 261 | static const struct iio_chan_spec_ext_info hmc5983_ext_info[] = { |
| 262 | − IIO_ENUM("meas_conf", true, &hmc5983_meas_conf_enum), | |
| 262 | + IIO_ENUM("meas_conf", IIO_SHARED_BY_TYPE, &hmc5983_meas_conf_enum), | |
| 263 | 263 | IIO_ENUM_AVAILABLE("meas_conf", &hmc5983_meas_conf_enum), |
| 264 | 264 | IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, hmc5843_get_mount_matrix), |
| 265 | 265 | { } |
| @@ -476,22 +476,14 @@ static int mag3110_probe(struct i2c_client *client, · 475 unmodified lines | ||
| 476 | 476 | data = iio_priv(indio_dev); |
| 477 | 477 | |
| 478 | 478 | data->vdd_reg = devm_regulator_get(&client->dev, "vdd"); |
| 479 | − if (IS_ERR(data->vdd_reg)) { | |
| 480 | − if (PTR_ERR(data->vdd_reg) == -EPROBE_DEFER) | |
| 481 | − return -EPROBE_DEFER; | |
| 482 | − | |
| 483 | − dev_err(&client->dev, "failed to get VDD regulator!\n"); | |
| 484 | − return PTR_ERR(data->vdd_reg); | |
| 485 | − } | |
| 479 | + if (IS_ERR(data->vdd_reg)) | |
| 480 | + return dev_err_probe(&client->dev, PTR_ERR(data->vdd_reg), | |
| 481 | + "failed to get VDD regulator!\n"); | |
| 486 | 482 | |
| 487 | 483 | data->vddio_reg = devm_regulator_get(&client->dev, "vddio"); |
| 488 | − if (IS_ERR(data->vddio_reg)) { | |
| 489 | − if (PTR_ERR(data->vddio_reg) == -EPROBE_DEFER) | |
| 490 | − return -EPROBE_DEFER; | |
| 491 | − | |
| 492 | − dev_err(&client->dev, "failed to get VDDIO regulator!\n"); | |
| 493 | − return PTR_ERR(data->vddio_reg); | |
| 494 | − } | |
| 484 | + if (IS_ERR(data->vddio_reg)) | |
| 485 | + return dev_err_probe(&client->dev, PTR_ERR(data->vddio_reg), | |
| 486 | + "failed to get VDDIO regulator!\n"); | |
| 495 | 487 | |
| 496 | 488 | ret = regulator_enable(data->vdd_reg); |
| 497 | 489 | if (ret) { |
| @@ -354,11 +354,9 @@ static int mux_probe(struct platform_device *pdev) · 353 unmodified lines | ||
| 354 | 354 | return -ENODEV; |
| 355 | 355 | |
| 356 | 356 | parent = devm_iio_channel_get(dev, "parent"); |
| 357 | − if (IS_ERR(parent)) { | |
| 358 | − if (PTR_ERR(parent) != -EPROBE_DEFER) | |
| 359 | − dev_err(dev, "failed to get parent channel\n"); | |
| 360 | − return PTR_ERR(parent); | |
| 361 | − } | |
| 357 | + if (IS_ERR(parent)) | |
| 358 | + return dev_err_probe(dev, PTR_ERR(parent), | |
| 359 | + "failed to get parent channel\n"); | |
| 362 | 360 | |
| 363 | 361 | sizeof_ext_info = iio_get_channel_ext_info_count(parent); |
| 364 | 362 | if (sizeof_ext_info) { |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/i2c.h> |
| 16 | 16 | #include <linux/iio/iio.h> |
| 17 | 17 | #include <linux/module.h> |
| 18 | +#include <linux/mod_devicetable.h> | |
| 18 | 19 | |
| 19 | 20 | #define AD5272_RDAC_WR 1 |
| 20 | 21 | #define AD5272_RDAC_RD 2 |
| @@ -192,7 +193,6 @@ static int ad5272_probe(struct i2c_client *client, · 171 unmodified lines | ||
| 192 | 193 | return devm_iio_device_register(dev, indio_dev); |
| 193 | 194 | } |
| 194 | 195 | |
| 195 | −#if defined(CONFIG_OF) | |
| 196 | 196 | static const struct of_device_id ad5272_dt_ids[] = { |
| 197 | 197 | { .compatible = "adi,ad5272-020", .data = (void *)AD5272_020 }, |
| 198 | 198 | { .compatible = "adi,ad5272-050", .data = (void *)AD5272_050 }, |
| @@ -202,7 +202,6 @@ static const struct of_device_id ad5272_dt_ids[] = { · 3 unmodified lines | ||
| 202 | 202 | {} |
| 203 | 203 | }; |
| 204 | 204 | MODULE_DEVICE_TABLE(of, ad5272_dt_ids); |
| 205 | −#endif /* CONFIG_OF */ | |
| 206 | 205 | |
| 207 | 206 | static const struct i2c_device_id ad5272_id[] = { |
| 208 | 207 | { "ad5272-020", AD5272_020 }, |
| @@ -217,7 +216,7 @@ MODULE_DEVICE_TABLE(i2c, ad5272_id); · 8 unmodified lines | ||
| 217 | 216 | static struct i2c_driver ad5272_driver = { |
| 218 | 217 | .driver = { |
| 219 | 218 | .name = "ad5272", |
| 220 | − .of_match_table = of_match_ptr(ad5272_dt_ids), | |
| 219 | + .of_match_table = ad5272_dt_ids, | |
| 221 | 220 | }, |
| 222 | 221 | .probe = ad5272_probe, |
| 223 | 222 | .id_table = ad5272_id, |
| @@ -14,7 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | #include <linux/i2c.h> |
| 15 | 15 | #include <linux/iio/iio.h> |
| 16 | 16 | #include <linux/module.h> |
| 17 | −#include <linux/of.h> | |
| 17 | +#include <linux/mod_devicetable.h> | |
| 18 | 18 | |
| 19 | 19 | #define DS1803_MAX_POS 255 |
| 20 | 20 | #define DS1803_WRITE(chan) (0xa8 | ((chan) + 1)) |
| @@ -134,7 +134,6 @@ static int ds1803_probe(struct i2c_client *client, · 113 unmodified lines | ||
| 134 | 134 | return devm_iio_device_register(dev, indio_dev); |
| 135 | 135 | } |
| 136 | 136 | |
| 137 | −#if defined(CONFIG_OF) | |
| 138 | 137 | static const struct of_device_id ds1803_dt_ids[] = { |
| 139 | 138 | { .compatible = "maxim,ds1803-010", .data = &ds1803_cfg[DS1803_010] }, |
| 140 | 139 | { .compatible = "maxim,ds1803-050", .data = &ds1803_cfg[DS1803_050] }, |
| @@ -142,7 +141,6 @@ static const struct of_device_id ds1803_dt_ids[] = { · 1 unmodified line | ||
| 142 | 141 | {} |
| 143 | 142 | }; |
| 144 | 143 | MODULE_DEVICE_TABLE(of, ds1803_dt_ids); |
| 145 | −#endif /* CONFIG_OF */ | |
| 146 | 144 | |
| 147 | 145 | static const struct i2c_device_id ds1803_id[] = { |
| 148 | 146 | { "ds1803-010", DS1803_010 }, |
| @@ -155,7 +153,7 @@ MODULE_DEVICE_TABLE(i2c, ds1803_id); · 6 unmodified lines | ||
| 155 | 153 | static struct i2c_driver ds1803_driver = { |
| 156 | 154 | .driver = { |
| 157 | 155 | .name = "ds1803", |
| 158 | − .of_match_table = of_match_ptr(ds1803_dt_ids), | |
| 156 | + .of_match_table = ds1803_dt_ids, | |
| 159 | 157 | }, |
| 160 | 158 | .probe = ds1803_probe, |
| 161 | 159 | .id_table = ds1803_id, |
| @@ -11,8 +11,8 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/iio/iio.h> |
| 12 | 12 | #include <linux/limits.h> |
| 13 | 13 | #include <linux/module.h> |
| 14 | −#include <linux/of.h> | |
| 15 | −#include <linux/of_device.h> | |
| 14 | +#include <linux/mod_devicetable.h> | |
| 15 | +#include <linux/property.h> | |
| 16 | 16 | |
| 17 | 17 | /* All chip variants have 32 wiper positions. */ |
| 18 | 18 | #define MAX5432_MAX_POS 31 |
| @@ -100,7 +100,7 @@ static int max5432_probe(struct i2c_client *client, · 81 unmodified lines | ||
| 100 | 100 | |
| 101 | 101 | data = iio_priv(indio_dev); |
| 102 | 102 | data->client = client; |
| 103 | − data->ohm = (unsigned long)of_device_get_match_data(dev); | |
| 103 | + data->ohm = (unsigned long)device_get_match_data(dev); | |
| 104 | 104 | |
| 105 | 105 | indio_dev->info = &max5432_info; |
| 106 | 106 | indio_dev->channels = max5432_channels; |
| @@ -122,7 +122,7 @@ MODULE_DEVICE_TABLE(of, max5432_dt_ids); · 15 unmodified lines | ||
| 122 | 122 | static struct i2c_driver max5432_driver = { |
| 123 | 123 | .driver = { |
| 124 | 124 | .name = "max5432", |
| 125 | − .of_match_table = of_match_ptr(max5432_dt_ids), | |
| 125 | + .of_match_table = max5432_dt_ids, | |
| 126 | 126 | }, |
| 127 | 127 | .probe = max5432_probe, |
| 128 | 128 | }; |
| @@ -7,12 +7,11 @@ · 6 unmodified lines | ||
| 7 | 7 | * https://datasheets.maximintegrated.com/en/ds/MAX5481-MAX5484.pdf |
| 8 | 8 | */ |
| 9 | 9 | |
| 10 | −#include <linux/acpi.h> | |
| 11 | 10 | #include <linux/iio/iio.h> |
| 12 | 11 | #include <linux/iio/sysfs.h> |
| 13 | 12 | #include <linux/module.h> |
| 14 | −#include <linux/of.h> | |
| 15 | −#include <linux/of_device.h> | |
| 13 | +#include <linux/mod_devicetable.h> | |
| 14 | +#include <linux/property.h> | |
| 16 | 15 | #include <linux/spi/spi.h> |
| 17 | 16 | |
| 18 | 17 | /* write wiper reg */ |
| @@ -117,7 +116,6 @@ static const struct iio_info max5481_info = { · 98 unmodified lines | ||
| 117 | 116 | .write_raw = max5481_write_raw, |
| 118 | 117 | }; |
| 119 | 118 | |
| 120 | −#if defined(CONFIG_OF) | |
| 121 | 119 | static const struct of_device_id max5481_match[] = { |
| 122 | 120 | { .compatible = "maxim,max5481", .data = &max5481_cfg[max5481] }, |
| 123 | 121 | { .compatible = "maxim,max5482", .data = &max5481_cfg[max5482] }, |
| @@ -126,7 +124,6 @@ static const struct of_device_id max5481_match[] = { · 2 unmodified lines | ||
| 126 | 124 | { } |
| 127 | 125 | }; |
| 128 | 126 | MODULE_DEVICE_TABLE(of, max5481_match); |
| 129 | −#endif | |
| 130 | 127 | |
| 131 | 128 | static int max5481_probe(struct spi_device *spi) |
| 132 | 129 | { |
| @@ -144,7 +141,7 @@ static int max5481_probe(struct spi_device *spi) · 11 unmodified lines | ||
| 144 | 141 | |
| 145 | 142 | data->spi = spi; |
| 146 | 143 | |
| 147 | − data->cfg = of_device_get_match_data(&spi->dev); | |
| 144 | + data->cfg = device_get_match_data(&spi->dev); | |
| 148 | 145 | if (!data->cfg) |
| 149 | 146 | data->cfg = &max5481_cfg[id->driver_data]; |
| 150 | 147 | |
| @@ -184,22 +181,10 @@ static const struct spi_device_id max5481_id_table[] = { · 33 unmodified lines | ||
| 184 | 181 | }; |
| 185 | 182 | MODULE_DEVICE_TABLE(spi, max5481_id_table); |
| 186 | 183 | |
| 187 | −#if defined(CONFIG_ACPI) | |
| 188 | −static const struct acpi_device_id max5481_acpi_match[] = { | |
| 189 | − { "max5481", max5481 }, | |
| 190 | − { "max5482", max5482 }, | |
| 191 | − { "max5483", max5483 }, | |
| 192 | − { "max5484", max5484 }, | |
| 193 | − { } | |
| 194 | −}; | |
| 195 | −MODULE_DEVICE_TABLE(acpi, max5481_acpi_match); | |
| 196 | −#endif | |
| 197 | − | |
| 198 | 184 | static struct spi_driver max5481_driver = { |
| 199 | 185 | .driver = { |
| 200 | 186 | .name = "max5481", |
| 201 | − .of_match_table = of_match_ptr(max5481_match), | |
| 202 | − .acpi_match_table = ACPI_PTR(max5481_acpi_match), | |
| 187 | + .of_match_table = max5481_match, | |
| 203 | 188 | }, |
| 204 | 189 | .probe = max5481_probe, |
| 205 | 190 | .remove = max5481_remove, |
| @@ -16,8 +16,8 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <linux/i2c.h> |
| 17 | 17 | #include <linux/iio/iio.h> |
| 18 | 18 | #include <linux/module.h> |
| 19 | −#include <linux/of.h> | |
| 20 | −#include <linux/of_device.h> | |
| 19 | +#include <linux/mod_devicetable.h> | |
| 20 | +#include <linux/property.h> | |
| 21 | 21 | |
| 22 | 22 | #define MCP4018_WIPER_MAX 127 |
| 23 | 23 | |
| @@ -116,8 +116,6 @@ static const struct i2c_device_id mcp4018_id[] = { · 92 unmodified lines | ||
| 116 | 116 | }; |
| 117 | 117 | MODULE_DEVICE_TABLE(i2c, mcp4018_id); |
| 118 | 118 | |
| 119 | −#ifdef CONFIG_OF | |
| 120 | − | |
| 121 | 119 | #define MCP4018_COMPATIBLE(of_compatible, cfg) { \ |
| 122 | 120 | .compatible = of_compatible, \ |
| 123 | 121 | .data = &mcp4018_cfg[cfg], \ |
| @@ -140,8 +138,6 @@ static const struct of_device_id mcp4018_of_match[] = { · 16 unmodified lines | ||
| 140 | 138 | }; |
| 141 | 139 | MODULE_DEVICE_TABLE(of, mcp4018_of_match); |
| 142 | 140 | |
| 143 | −#endif | |
| 144 | − | |
| 145 | 141 | static int mcp4018_probe(struct i2c_client *client) |
| 146 | 142 | { |
| 147 | 143 | struct device *dev = &client->dev; |
| @@ -161,7 +157,7 @@ static int mcp4018_probe(struct i2c_client *client) · 13 unmodified lines | ||
| 161 | 157 | i2c_set_clientdata(client, indio_dev); |
| 162 | 158 | data->client = client; |
| 163 | 159 | |
| 164 | − data->cfg = of_device_get_match_data(dev); | |
| 160 | + data->cfg = device_get_match_data(dev); | |
| 165 | 161 | if (!data->cfg) |
| 166 | 162 | data->cfg = &mcp4018_cfg[i2c_match_id(mcp4018_id, client)->driver_data]; |
| 167 | 163 | |
| @@ -176,7 +172,7 @@ static int mcp4018_probe(struct i2c_client *client) · 8 unmodified lines | ||
| 176 | 172 | static struct i2c_driver mcp4018_driver = { |
| 177 | 173 | .driver = { |
| 178 | 174 | .name = "mcp4018", |
| 179 | − .of_match_table = of_match_ptr(mcp4018_of_match), | |
| 175 | + .of_match_table = mcp4018_of_match, | |
| 180 | 176 | }, |
| 181 | 177 | .probe_new = mcp4018_probe, |
| 182 | 178 | .id_table = mcp4018_id, |
| @@ -37,9 +37,9 @@ · 36 unmodified lines | ||
| 37 | 37 | #include <linux/iio/iio.h> |
| 38 | 38 | #include <linux/iio/types.h> |
| 39 | 39 | #include <linux/module.h> |
| 40 | +#include <linux/mod_devicetable.h> | |
| 40 | 41 | #include <linux/mutex.h> |
| 41 | −#include <linux/of.h> | |
| 42 | −#include <linux/of_device.h> | |
| 42 | +#include <linux/property.h> | |
| 43 | 43 | #include <linux/spi/spi.h> |
| 44 | 44 | |
| 45 | 45 | #define MCP4131_WRITE (0x00 << 2) |
| @@ -252,7 +252,7 @@ static int mcp4131_probe(struct spi_device *spi) · 206 unmodified lines | ||
| 252 | 252 | data = iio_priv(indio_dev); |
| 253 | 253 | spi_set_drvdata(spi, indio_dev); |
| 254 | 254 | data->spi = spi; |
| 255 | − data->cfg = of_device_get_match_data(&spi->dev); | |
| 255 | + data->cfg = device_get_match_data(&spi->dev); | |
| 256 | 256 | if (!data->cfg) { |
| 257 | 257 | devid = spi_get_device_id(spi)->driver_data; |
| 258 | 258 | data->cfg = &mcp4131_cfg[devid]; |
| @@ -479,7 +479,7 @@ MODULE_DEVICE_TABLE(spi, mcp4131_id); · 220 unmodified lines | ||
| 479 | 479 | static struct spi_driver mcp4131_driver = { |
| 480 | 480 | .driver = { |
| 481 | 481 | .name = "mcp4131", |
| 482 | − .of_match_table = of_match_ptr(mcp4131_dt_ids), | |
| 482 | + .of_match_table = mcp4131_dt_ids, | |
| 483 | 483 | }, |
| 484 | 484 | .probe = mcp4131_probe, |
| 485 | 485 | .id_table = mcp4131_id, |
| @@ -28,8 +28,8 @@ · 27 unmodified lines | ||
| 28 | 28 | #include <linux/module.h> |
| 29 | 29 | #include <linux/i2c.h> |
| 30 | 30 | #include <linux/err.h> |
| 31 | −#include <linux/of.h> | |
| 32 | −#include <linux/of_device.h> | |
| 31 | +#include <linux/mod_devicetable.h> | |
| 32 | +#include <linux/property.h> | |
| 33 | 33 | |
| 34 | 34 | #include <linux/iio/iio.h> |
| 35 | 35 | |
| @@ -275,8 +275,6 @@ static const struct i2c_device_id mcp4531_id[] = { · 239 unmodified lines | ||
| 275 | 275 | }; |
| 276 | 276 | MODULE_DEVICE_TABLE(i2c, mcp4531_id); |
| 277 | 277 | |
| 278 | −#ifdef CONFIG_OF | |
| 279 | − | |
| 280 | 278 | #define MCP4531_COMPATIBLE(of_compatible, cfg) { \ |
| 281 | 279 | .compatible = of_compatible, \ |
| 282 | 280 | .data = &mcp4531_cfg[cfg], \ |
| @@ -350,7 +348,6 @@ static const struct of_device_id mcp4531_of_match[] = { · 67 unmodified lines | ||
| 350 | 348 | { /* sentinel */ } |
| 351 | 349 | }; |
| 352 | 350 | MODULE_DEVICE_TABLE(of, mcp4531_of_match); |
| 353 | −#endif | |
| 354 | 351 | |
| 355 | 352 | static int mcp4531_probe(struct i2c_client *client) |
| 356 | 353 | { |
| @@ -371,7 +368,7 @@ static int mcp4531_probe(struct i2c_client *client) · 14 unmodified lines | ||
| 371 | 368 | i2c_set_clientdata(client, indio_dev); |
| 372 | 369 | data->client = client; |
| 373 | 370 | |
| 374 | − data->cfg = of_device_get_match_data(dev); | |
| 371 | + data->cfg = device_get_match_data(dev); | |
| 375 | 372 | if (!data->cfg) |
| 376 | 373 | data->cfg = &mcp4531_cfg[i2c_match_id(mcp4531_id, client)->driver_data]; |
| 377 | 374 | |
| @@ -386,7 +383,7 @@ static int mcp4531_probe(struct i2c_client *client) · 8 unmodified lines | ||
| 386 | 383 | static struct i2c_driver mcp4531_driver = { |
| 387 | 384 | .driver = { |
| 388 | 385 | .name = "mcp4531", |
| 389 | − .of_match_table = of_match_ptr(mcp4531_of_match), | |
| 386 | + .of_match_table = mcp4531_of_match, | |
| 390 | 387 | }, |
| 391 | 388 | .probe_new = mcp4531_probe, |
| 392 | 389 | .id_table = mcp4531_id, |
| @@ -11,7 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/module.h> |
| 12 | 12 | #include <linux/i2c.h> |
| 13 | 13 | #include <linux/delay.h> |
| 14 | −#include <linux/of.h> | |
| 14 | +#include <linux/mod_devicetable.h> | |
| 15 | 15 | #include <linux/regmap.h> |
| 16 | 16 | #include <linux/iio/iio.h> |
| 17 | 17 | #include <linux/iio/buffer.h> |
| @@ -205,13 +205,12 @@ static const struct iio_info lmp91000_info = { · 187 unmodified lines | ||
| 205 | 205 | static int lmp91000_read_config(struct lmp91000_data *data) |
| 206 | 206 | { |
| 207 | 207 | struct device *dev = data->dev; |
| 208 | − struct device_node *np = dev->of_node; | |
| 209 | 208 | unsigned int reg, val; |
| 210 | 209 | int i, ret; |
| 211 | 210 | |
| 212 | − ret = of_property_read_u32(np, "ti,tia-gain-ohm", &val); | |
| 211 | + ret = device_property_read_u32(dev, "ti,tia-gain-ohm", &val); | |
| 213 | 212 | if (ret) { |
| 214 | − if (!of_property_read_bool(np, "ti,external-tia-resistor")) { | |
| 213 | + if (!device_property_read_bool(dev, "ti,external-tia-resistor")) { | |
| 215 | 214 | dev_err(dev, "no ti,tia-gain-ohm defined and external resistor not specified\n"); |
| 216 | 215 | return ret; |
| 217 | 216 | } |
| @@ -232,7 +231,7 @@ static int lmp91000_read_config(struct lmp91000_data *data) · 14 unmodified lines | ||
| 232 | 231 | return ret; |
| 233 | 232 | } |
| 234 | 233 | |
| 235 | − ret = of_property_read_u32(np, "ti,rload-ohm", &val); | |
| 234 | + ret = device_property_read_u32(dev, "ti,rload-ohm", &val); | |
| 236 | 235 | if (ret) { |
| 237 | 236 | val = 100; |
| 238 | 237 | dev_info(dev, "no ti,rload-ohm defined, default to %d\n", val); |
| @@ -422,7 +421,7 @@ MODULE_DEVICE_TABLE(i2c, lmp91000_id); · 183 unmodified lines | ||
| 422 | 421 | static struct i2c_driver lmp91000_driver = { |
| 423 | 422 | .driver = { |
| 424 | 423 | .name = LMP91000_DRV_NAME, |
| 425 | − .of_match_table = of_match_ptr(lmp91000_of_match), | |
| 424 | + .of_match_table = lmp91000_of_match, | |
| 426 | 425 | }, |
| 427 | 426 | .probe = lmp91000_probe, |
| 428 | 427 | .remove = lmp91000_remove, |
| @@ -139,12 +139,11 @@ static int cros_ec_baro_probe(struct platform_device *pdev) · 138 unmodified lines | ||
| 139 | 139 | |
| 140 | 140 | ret = cros_ec_sensors_core_init(pdev, indio_dev, true, |
| 141 | 141 | cros_ec_sensors_capture, |
| 142 | − cros_ec_sensors_push_data); | |
| 142 | + cros_ec_sensors_push_data, | |
| 143 | + true); | |
| 143 | 144 | if (ret) |
| 144 | 145 | return ret; |
| 145 | 146 | |
| 146 | − iio_buffer_set_attrs(indio_dev->buffer, cros_ec_sensor_fifo_attributes); | |
| 147 | − | |
| 148 | 147 | indio_dev->info = &cros_ec_baro_info; |
| 149 | 148 | state = iio_priv(indio_dev); |
| 150 | 149 | state->core.type = state->core.resp->info.type; |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | |
| 11 | 11 | #include <linux/device.h> |
| 12 | 12 | #include <linux/module.h> |
| 13 | +#include <linux/mod_devicetable.h> | |
| 13 | 14 | #include <linux/i2c.h> |
| 14 | 15 | #include <linux/pm_runtime.h> |
| 15 | 16 | #include <linux/crc8.h> |
| @@ -645,7 +646,7 @@ static struct i2c_driver icp10100_driver = { · 629 unmodified lines | ||
| 645 | 646 | .driver = { |
| 646 | 647 | .name = "icp10100", |
| 647 | 648 | .pm = &icp10100_pm, |
| 648 | − .of_match_table = of_match_ptr(icp10100_of_match), | |
| 649 | + .of_match_table = icp10100_of_match, | |
| 649 | 650 | }, |
| 650 | 651 | .probe = icp10100_probe, |
| 651 | 652 | .id_table = icp10100_id, |
| @@ -14,7 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | #include <linux/delay.h> |
| 15 | 15 | #include <linux/i2c.h> |
| 16 | 16 | #include <linux/module.h> |
| 17 | −#include <linux/of_device.h> | |
| 17 | +#include <linux/mod_devicetable.h> | |
| 18 | 18 | |
| 19 | 19 | #include <asm/unaligned.h> |
| 20 | 20 | |
| @@ -113,14 +113,12 @@ static int ms5611_i2c_remove(struct i2c_client *client) · 92 unmodified lines | ||
| 113 | 113 | return ms5611_remove(i2c_get_clientdata(client)); |
| 114 | 114 | } |
| 115 | 115 | |
| 116 | −#if defined(CONFIG_OF) | |
| 117 | 116 | static const struct of_device_id ms5611_i2c_matches[] = { |
| 118 | 117 | { .compatible = "meas,ms5611" }, |
| 119 | 118 | { .compatible = "meas,ms5607" }, |
| 120 | 119 | { } |
| 121 | 120 | }; |
| 122 | 121 | MODULE_DEVICE_TABLE(of, ms5611_i2c_matches); |
| 123 | −#endif | |
| 124 | 122 | |
| 125 | 123 | static const struct i2c_device_id ms5611_id[] = { |
| 126 | 124 | { "ms5611", MS5611 }, |
| @@ -132,7 +130,7 @@ MODULE_DEVICE_TABLE(i2c, ms5611_id); · 5 unmodified lines | ||
| 132 | 130 | static struct i2c_driver ms5611_driver = { |
| 133 | 131 | .driver = { |
| 134 | 132 | .name = "ms5611", |
| 135 | − .of_match_table = of_match_ptr(ms5611_i2c_matches) | |
| 133 | + .of_match_table = ms5611_i2c_matches, | |
| 136 | 134 | }, |
| 137 | 135 | .id_table = ms5611_id, |
| 138 | 136 | .probe = ms5611_i2c_probe, |
| @@ -9,7 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | #include <linux/delay.h> |
| 10 | 10 | #include <linux/module.h> |
| 11 | 11 | #include <linux/spi/spi.h> |
| 12 | −#include <linux/of_device.h> | |
| 12 | +#include <linux/mod_devicetable.h> | |
| 13 | 13 | |
| 14 | 14 | #include <asm/unaligned.h> |
| 15 | 15 | |
| @@ -115,14 +115,12 @@ static int ms5611_spi_remove(struct spi_device *spi) · 99 unmodified lines | ||
| 115 | 115 | return ms5611_remove(spi_get_drvdata(spi)); |
| 116 | 116 | } |
| 117 | 117 | |
| 118 | −#if defined(CONFIG_OF) | |
| 119 | 118 | static const struct of_device_id ms5611_spi_matches[] = { |
| 120 | 119 | { .compatible = "meas,ms5611" }, |
| 121 | 120 | { .compatible = "meas,ms5607" }, |
| 122 | 121 | { } |
| 123 | 122 | }; |
| 124 | 123 | MODULE_DEVICE_TABLE(of, ms5611_spi_matches); |
| 125 | −#endif | |
| 126 | 124 | |
| 127 | 125 | static const struct spi_device_id ms5611_id[] = { |
| 128 | 126 | { "ms5611", MS5611 }, |
| @@ -134,7 +132,7 @@ MODULE_DEVICE_TABLE(spi, ms5611_id); · 5 unmodified lines | ||
| 134 | 132 | static struct spi_driver ms5611_driver = { |
| 135 | 133 | .driver = { |
| 136 | 134 | .name = "ms5611", |
| 137 | − .of_match_table = of_match_ptr(ms5611_spi_matches) | |
| 135 | + .of_match_table = ms5611_spi_matches | |
| 138 | 136 | }, |
| 139 | 137 | .id_table = ms5611_id, |
| 140 | 138 | .probe = ms5611_spi_probe, |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | #include <linux/kernel.h> |
| 23 | 23 | #include <linux/stat.h> |
| 24 | 24 | #include <linux/module.h> |
| 25 | +#include <linux/mod_devicetable.h> | |
| 25 | 26 | #include <linux/i2c.h> |
| 26 | 27 | #include <linux/iio/iio.h> |
| 27 | 28 | #include <linux/iio/sysfs.h> |
| @@ -192,7 +193,7 @@ static struct i2c_driver ms5637_driver = { · 164 unmodified lines | ||
| 192 | 193 | .id_table = ms5637_id, |
| 193 | 194 | .driver = { |
| 194 | 195 | .name = "ms5637", |
| 195 | − .of_match_table = of_match_ptr(ms5637_of_match), | |
| 196 | + .of_match_table = ms5637_of_match, | |
| 196 | 197 | }, |
| 197 | 198 | }; |
| 198 | 199 | |
| @@ -10,7 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | #include <linux/module.h> |
| 11 | 11 | #include <linux/regmap.h> |
| 12 | 12 | #include <linux/i2c.h> |
| 13 | −#include <linux/of_device.h> | |
| 13 | +#include <linux/mod_devicetable.h> | |
| 14 | 14 | #include "zpa2326.h" |
| 15 | 15 | |
| 16 | 16 | /* |
| @@ -66,18 +66,16 @@ static const struct i2c_device_id zpa2326_i2c_ids[] = { · 49 unmodified lines | ||
| 66 | 66 | }; |
| 67 | 67 | MODULE_DEVICE_TABLE(i2c, zpa2326_i2c_ids); |
| 68 | 68 | |
| 69 | −#if defined(CONFIG_OF) | |
| 70 | 69 | static const struct of_device_id zpa2326_i2c_matches[] = { |
| 71 | 70 | { .compatible = "murata,zpa2326" }, |
| 72 | 71 | { } |
| 73 | 72 | }; |
| 74 | 73 | MODULE_DEVICE_TABLE(of, zpa2326_i2c_matches); |
| 75 | −#endif | |
| 76 | 74 | |
| 77 | 75 | static struct i2c_driver zpa2326_i2c_driver = { |
| 78 | 76 | .driver = { |
| 79 | 77 | .name = "zpa2326-i2c", |
| 80 | − .of_match_table = of_match_ptr(zpa2326_i2c_matches), | |
| 78 | + .of_match_table = zpa2326_i2c_matches, | |
| 81 | 79 | .pm = ZPA2326_PM_OPS, |
| 82 | 80 | }, |
| 83 | 81 | .probe = zpa2326_probe_i2c, |
| @@ -10,7 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | #include <linux/module.h> |
| 11 | 11 | #include <linux/regmap.h> |
| 12 | 12 | #include <linux/spi/spi.h> |
| 13 | −#include <linux/of_device.h> | |
| 13 | +#include <linux/mod_devicetable.h> | |
| 14 | 14 | #include "zpa2326.h" |
| 15 | 15 | |
| 16 | 16 | /* |
| @@ -70,18 +70,16 @@ static const struct spi_device_id zpa2326_spi_ids[] = { · 53 unmodified lines | ||
| 70 | 70 | }; |
| 71 | 71 | MODULE_DEVICE_TABLE(spi, zpa2326_spi_ids); |
| 72 | 72 | |
| 73 | −#if defined(CONFIG_OF) | |
| 74 | 73 | static const struct of_device_id zpa2326_spi_matches[] = { |
| 75 | 74 | { .compatible = "murata,zpa2326" }, |
| 76 | 75 | { } |
| 77 | 76 | }; |
| 78 | 77 | MODULE_DEVICE_TABLE(of, zpa2326_spi_matches); |
| 79 | −#endif | |
| 80 | 78 | |
| 81 | 79 | static struct spi_driver zpa2326_spi_driver = { |
| 82 | 80 | .driver = { |
| 83 | 81 | .name = "zpa2326-spi", |
| 84 | − .of_match_table = of_match_ptr(zpa2326_spi_matches), | |
| 82 | + .of_match_table = zpa2326_spi_matches, | |
| 85 | 83 | .pm = ZPA2326_PM_OPS, |
| 86 | 84 | }, |
| 87 | 85 | .probe = zpa2326_probe_spi, |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | */ |
| 8 | 8 | |
| 9 | 9 | #include <linux/module.h> |
| 10 | +#include <linux/mod_devicetable.h> | |
| 10 | 11 | #include <linux/init.h> |
| 11 | 12 | #include <linux/interrupt.h> |
| 12 | 13 | #include <linux/delay.h> |
| @@ -352,19 +353,19 @@ static void as3935_stop_work(void *data) · 339 unmodified lines | ||
| 352 | 353 | |
| 353 | 354 | static int as3935_probe(struct spi_device *spi) |
| 354 | 355 | { |
| 356 | + struct device *dev = &spi->dev; | |
| 355 | 357 | struct iio_dev *indio_dev; |
| 356 | 358 | struct iio_trigger *trig; |
| 357 | 359 | struct as3935_state *st; |
| 358 | − struct device_node *np = spi->dev.of_node; | |
| 359 | 360 | int ret; |
| 360 | 361 | |
| 361 | 362 | /* Be sure lightning event interrupt is specified */ |
| 362 | 363 | if (!spi->irq) { |
| 363 | − dev_err(&spi->dev, "unable to get event interrupt\n"); | |
| 364 | + dev_err(dev, "unable to get event interrupt\n"); | |
| 364 | 365 | return -EINVAL; |
| 365 | 366 | } |
| 366 | 367 | |
| 367 | − indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); | |
| 368 | + indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); | |
| 368 | 369 | if (!indio_dev) |
| 369 | 370 | return -ENOMEM; |
| 370 | 371 | |
| @@ -374,27 +375,24 @@ static int as3935_probe(struct spi_device *spi) · 3 unmodified lines | ||
| 374 | 375 | spi_set_drvdata(spi, indio_dev); |
| 375 | 376 | mutex_init(&st->lock); |
| 376 | 377 | |
| 377 | − ret = of_property_read_u32(np, | |
| 378 | + ret = device_property_read_u32(dev, | |
| 378 | 379 | "ams,tuning-capacitor-pf", &st->tune_cap); |
| 379 | 380 | if (ret) { |
| 380 | 381 | st->tune_cap = 0; |
| 381 | − dev_warn(&spi->dev, | |
| 382 | − "no tuning-capacitor-pf set, defaulting to %d", | |
| 382 | + dev_warn(dev, "no tuning-capacitor-pf set, defaulting to %d", | |
| 383 | 383 | st->tune_cap); |
| 384 | 384 | } |
| 385 | 385 | |
| 386 | 386 | if (st->tune_cap > MAX_PF_CAP) { |
| 387 | − dev_err(&spi->dev, | |
| 388 | − "wrong tuning-capacitor-pf setting of %d\n", | |
| 387 | + dev_err(dev, "wrong tuning-capacitor-pf setting of %d\n", | |
| 389 | 388 | st->tune_cap); |
| 390 | 389 | return -EINVAL; |
| 391 | 390 | } |
| 392 | 391 | |
| 393 | − ret = of_property_read_u32(np, | |
| 392 | + ret = device_property_read_u32(dev, | |
| 394 | 393 | "ams,nflwdth", &st->nflwdth_reg); |
| 395 | 394 | if (!ret && st->nflwdth_reg > AS3935_NFLWDTH_MASK) { |
| 396 | − dev_err(&spi->dev, | |
| 397 | − "invalid nflwdth setting of %d\n", | |
| 395 | + dev_err(dev, "invalid nflwdth setting of %d\n", | |
| 398 | 396 | st->nflwdth_reg); |
| 399 | 397 | return -EINVAL; |
| 400 | 398 | } |
| @@ -405,7 +403,7 @@ static int as3935_probe(struct spi_device *spi) · 4 unmodified lines | ||
| 405 | 403 | indio_dev->modes = INDIO_DIRECT_MODE; |
| 406 | 404 | indio_dev->info = &as3935_info; |
| 407 | 405 | |
| 408 | − trig = devm_iio_trigger_alloc(&spi->dev, "%s-dev%d", | |
| 406 | + trig = devm_iio_trigger_alloc(dev, "%s-dev%d", | |
| 409 | 407 | indio_dev->name, indio_dev->id); |
| 410 | 408 | |
| 411 | 409 | if (!trig) |
| @@ -417,42 +415,42 @@ static int as3935_probe(struct spi_device *spi) · 5 unmodified lines | ||
| 417 | 415 | iio_trigger_set_drvdata(trig, indio_dev); |
| 418 | 416 | trig->ops = &iio_interrupt_trigger_ops; |
| 419 | 417 | |
| 420 | − ret = devm_iio_trigger_register(&spi->dev, trig); | |
| 418 | + ret = devm_iio_trigger_register(dev, trig); | |
| 421 | 419 | if (ret) { |
| 422 | − dev_err(&spi->dev, "failed to register trigger\n"); | |
| 420 | + dev_err(dev, "failed to register trigger\n"); | |
| 423 | 421 | return ret; |
| 424 | 422 | } |
| 425 | 423 | |
| 426 | − ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, | |
| 424 | + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, | |
| 427 | 425 | iio_pollfunc_store_time, |
| 428 | 426 | as3935_trigger_handler, NULL); |
| 429 | 427 | |
| 430 | 428 | if (ret) { |
| 431 | − dev_err(&spi->dev, "cannot setup iio trigger\n"); | |
| 429 | + dev_err(dev, "cannot setup iio trigger\n"); | |
| 432 | 430 | return ret; |
| 433 | 431 | } |
| 434 | 432 | |
| 435 | 433 | calibrate_as3935(st); |
| 436 | 434 | |
| 437 | 435 | INIT_DELAYED_WORK(&st->work, as3935_event_work); |
| 438 | − ret = devm_add_action(&spi->dev, as3935_stop_work, indio_dev); | |
| 436 | + ret = devm_add_action(dev, as3935_stop_work, indio_dev); | |
| 439 | 437 | if (ret) |
| 440 | 438 | return ret; |
| 441 | 439 | |
| 442 | − ret = devm_request_irq(&spi->dev, spi->irq, | |
| 440 | + ret = devm_request_irq(dev, spi->irq, | |
| 443 | 441 | &as3935_interrupt_handler, |
| 444 | 442 | IRQF_TRIGGER_RISING, |
| 445 | − dev_name(&spi->dev), | |
| 443 | + dev_name(dev), | |
| 446 | 444 | indio_dev); |
| 447 | 445 | |
| 448 | 446 | if (ret) { |
| 449 | − dev_err(&spi->dev, "unable to request irq\n"); | |
| 447 | + dev_err(dev, "unable to request irq\n"); | |
| 450 | 448 | return ret; |
| 451 | 449 | } |
| 452 | 450 | |
| 453 | − ret = devm_iio_device_register(&spi->dev, indio_dev); | |
| 451 | + ret = devm_iio_device_register(dev, indio_dev); | |
| 454 | 452 | if (ret < 0) { |
| 455 | − dev_err(&spi->dev, "unable to register device\n"); | |
| 453 | + dev_err(dev, "unable to register device\n"); | |
| 456 | 454 | return ret; |
| 457 | 455 | } |
| 458 | 456 | return 0; |
| @@ -473,7 +471,7 @@ MODULE_DEVICE_TABLE(spi, as3935_id); · 14 unmodified lines | ||
| 473 | 471 | static struct spi_driver as3935_driver = { |
| 474 | 472 | .driver = { |
| 475 | 473 | .name = "as3935", |
| 476 | − .of_match_table = of_match_ptr(as3935_of_match), | |
| 474 | + .of_match_table = as3935_of_match, | |
| 477 | 475 | .pm = AS3935_PM_OPS, |
| 478 | 476 | }, |
| 479 | 477 | .probe = as3935_probe, |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <linux/i2c.h> |
| 14 | 14 | #include <linux/delay.h> |
| 15 | 15 | #include <linux/module.h> |
| 16 | +#include <linux/mod_devicetable.h> | |
| 16 | 17 | #include <linux/pm_runtime.h> |
| 17 | 18 | #include <linux/iio/iio.h> |
| 18 | 19 | #include <linux/iio/sysfs.h> |
| @@ -360,7 +361,7 @@ static const struct dev_pm_ops lidar_pm_ops = { · 341 unmodified lines | ||
| 360 | 361 | static struct i2c_driver lidar_driver = { |
| 361 | 362 | .driver = { |
| 362 | 363 | .name = LIDAR_DRV_NAME, |
| 363 | − .of_match_table = of_match_ptr(lidar_dt_ids), | |
| 364 | + .of_match_table = lidar_dt_ids, | |
| 364 | 365 | .pm = &lidar_pm_ops, |
| 365 | 366 | }, |
| 366 | 367 | .probe = lidar_probe, |
| @@ -6,19 +6,21 @@ · 5 unmodified lines | ||
| 6 | 6 | * Based on SX9500 driver and Semtech driver using the input framework |
| 7 | 7 | * <https://my.syncplicity.com/share/teouwsim8niiaud/ |
| 8 | 8 | * linux-driver-SX9310_NoSmartHSensing>. |
| 9 | − * Reworked April 2019 by Evan Green <evgreen@chromium.org> | |
| 10 | − * and January 2020 by Daniel Campello <campello@chromium.org> | |
| 9 | + * Reworked in April 2019 by Evan Green <evgreen@chromium.org> | |
| 10 | + * and in January 2020 by Daniel Campello <campello@chromium.org>. | |
| 11 | 11 | */ |
| 12 | 12 | |
| 13 | 13 | #include <linux/acpi.h> |
| 14 | +#include <linux/bitfield.h> | |
| 14 | 15 | #include <linux/delay.h> |
| 15 | 16 | #include <linux/i2c.h> |
| 16 | 17 | #include <linux/irq.h> |
| 17 | 18 | #include <linux/kernel.h> |
| 19 | +#include <linux/mod_devicetable.h> | |
| 18 | 20 | #include <linux/module.h> |
| 19 | −#include <linux/of.h> | |
| 20 | 21 | #include <linux/pm.h> |
| 21 | 22 | #include <linux/regmap.h> |
| 23 | +#include <linux/regulator/consumer.h> | |
| 22 | 24 | #include <linux/slab.h> |
| 23 | 25 | |
| 24 | 26 | #include <linux/iio/buffer.h> |
| @@ -33,45 +35,44 @@ · 8 unmodified lines | ||
| 33 | 35 | #define SX9310_REG_IRQ_SRC 0x00 |
| 34 | 36 | #define SX9310_REG_STAT0 0x01 |
| 35 | 37 | #define SX9310_REG_STAT1 0x02 |
| 38 | +#define SX9310_REG_STAT1_COMPSTAT_MASK GENMASK(3, 0) | |
| 36 | 39 | #define SX9310_REG_IRQ_MSK 0x03 |
| 37 | 40 | #define SX9310_CONVDONE_IRQ BIT(3) |
| 38 | 41 | #define SX9310_FAR_IRQ BIT(5) |
| 39 | 42 | #define SX9310_CLOSE_IRQ BIT(6) |
| 40 | −#define SX9310_EVENT_IRQ (SX9310_FAR_IRQ | \ | |
| 41 | − SX9310_CLOSE_IRQ) | |
| 42 | 43 | #define SX9310_REG_IRQ_FUNC 0x04 |
| 43 | 44 | |
| 44 | 45 | #define SX9310_REG_PROX_CTRL0 0x10 |
| 45 | −#define SX9310_REG_PROX_CTRL0_PROXSTAT2 0x10 | |
| 46 | −#define SX9310_REG_PROX_CTRL0_EN_MASK 0x0F | |
| 46 | +#define SX9310_REG_PROX_CTRL0_SENSOREN_MASK GENMASK(3, 0) | |
| 47 | +#define SX9310_REG_PROX_CTRL0_SCANPERIOD_MASK GENMASK(7, 4) | |
| 48 | +#define SX9310_REG_PROX_CTRL0_SCANPERIOD_15MS 0x01 | |
| 47 | 49 | #define SX9310_REG_PROX_CTRL1 0x11 |
| 48 | 50 | #define SX9310_REG_PROX_CTRL2 0x12 |
| 49 | −#define SX9310_REG_PROX_CTRL2_COMBMODE_ALL 0x80 | |
| 50 | −#define SX9310_REG_PROX_CTRL2_SHIELDEN_DYNAMIC 0x04 | |
| 51 | +#define SX9310_REG_PROX_CTRL2_COMBMODE_CS1_CS2 (0x02 << 6) | |
| 52 | +#define SX9310_REG_PROX_CTRL2_SHIELDEN_DYNAMIC (0x01 << 2) | |
| 51 | 53 | #define SX9310_REG_PROX_CTRL3 0x13 |
| 52 | −#define SX9310_REG_PROX_CTRL3_GAIN0_X8 0x0c | |
| 54 | +#define SX9310_REG_PROX_CTRL3_GAIN0_X8 (0x03 << 2) | |
| 53 | 55 | #define SX9310_REG_PROX_CTRL3_GAIN12_X4 0x02 |
| 54 | 56 | #define SX9310_REG_PROX_CTRL4 0x14 |
| 55 | 57 | #define SX9310_REG_PROX_CTRL4_RESOLUTION_FINEST 0x07 |
| 56 | 58 | #define SX9310_REG_PROX_CTRL5 0x15 |
| 57 | −#define SX9310_REG_PROX_CTRL5_RANGE_SMALL 0xc0 | |
| 58 | −#define SX9310_REG_PROX_CTRL5_STARTUPSENS_CS1 0x04 | |
| 59 | +#define SX9310_REG_PROX_CTRL5_RANGE_SMALL (0x03 << 6) | |
| 60 | +#define SX9310_REG_PROX_CTRL5_STARTUPSENS_CS1 (0x01 << 2) | |
| 59 | 61 | #define SX9310_REG_PROX_CTRL5_RAWFILT_1P25 0x02 |
| 60 | 62 | #define SX9310_REG_PROX_CTRL6 0x16 |
| 61 | −#define SX9310_REG_PROX_CTRL6_COMP_COMMON 0x20 | |
| 63 | +#define SX9310_REG_PROX_CTRL6_AVGTHRESH_DEFAULT 0x20 | |
| 62 | 64 | #define SX9310_REG_PROX_CTRL7 0x17 |
| 63 | −#define SX9310_REG_PROX_CTRL7_AVGNEGFILT_2 0x08 | |
| 65 | +#define SX9310_REG_PROX_CTRL7_AVGNEGFILT_2 (0x01 << 3) | |
| 64 | 66 | #define SX9310_REG_PROX_CTRL7_AVGPOSFILT_512 0x05 |
| 65 | 67 | #define SX9310_REG_PROX_CTRL8 0x18 |
| 66 | 68 | #define SX9310_REG_PROX_CTRL9 0x19 |
| 67 | −#define SX9310_REG_PROX_CTRL8_9_PTHRESH12_28 0x40 | |
| 68 | −#define SX9310_REG_PROX_CTRL8_9_PTHRESH_96 0x88 | |
| 69 | +#define SX9310_REG_PROX_CTRL8_9_PTHRESH_28 (0x08 << 3) | |
| 70 | +#define SX9310_REG_PROX_CTRL8_9_PTHRESH_96 (0x11 << 3) | |
| 69 | 71 | #define SX9310_REG_PROX_CTRL8_9_BODYTHRESH_900 0x03 |
| 70 | 72 | #define SX9310_REG_PROX_CTRL8_9_BODYTHRESH_1500 0x05 |
| 71 | 73 | #define SX9310_REG_PROX_CTRL10 0x1a |
| 72 | −#define SX9310_REG_PROX_CTRL10_HYST_6PCT 0x10 | |
| 73 | −#define SX9310_REG_PROX_CTRL10_CLOSE_DEBOUNCE_8 0x12 | |
| 74 | −#define SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_8 0x03 | |
| 74 | +#define SX9310_REG_PROX_CTRL10_HYST_6PCT (0x01 << 4) | |
| 75 | +#define SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_2 0x01 | |
| 75 | 76 | #define SX9310_REG_PROX_CTRL11 0x1b |
| 76 | 77 | #define SX9310_REG_PROX_CTRL12 0x1c |
| 77 | 78 | #define SX9310_REG_PROX_CTRL13 0x1d |
| @@ -82,8 +83,8 @@ · 4 unmodified lines | ||
| 82 | 83 | #define SX9310_REG_PROX_CTRL18 0x22 |
| 83 | 84 | #define SX9310_REG_PROX_CTRL19 0x23 |
| 84 | 85 | #define SX9310_REG_SAR_CTRL0 0x2a |
| 85 | −#define SX9310_REG_SAR_CTRL0_SARDEB_4_SAMPLES 0x40 | |
| 86 | −#define SX9310_REG_SAR_CTRL0_SARHYST_8 0x10 | |
| 86 | +#define SX9310_REG_SAR_CTRL0_SARDEB_4_SAMPLES (0x02 << 5) | |
| 87 | +#define SX9310_REG_SAR_CTRL0_SARHYST_8 (0x02 << 3) | |
| 87 | 88 | #define SX9310_REG_SAR_CTRL1 0x2b |
| 88 | 89 | /* Each increment of the slope register is 0.0078125. */ |
| 89 | 90 | #define SX9310_REG_SAR_CTRL1_SLOPE(_hnslope) (_hnslope / 78125) |
| @@ -91,39 +92,28 @@ · 1 unmodified line | ||
| 91 | 92 | #define SX9310_REG_SAR_CTRL2_SAROFFSET_DEFAULT 0x3c |
| 92 | 93 | |
| 93 | 94 | #define SX9310_REG_SENSOR_SEL 0x30 |
| 94 | − | |
| 95 | 95 | #define SX9310_REG_USE_MSB 0x31 |
| 96 | 96 | #define SX9310_REG_USE_LSB 0x32 |
| 97 | − | |
| 98 | 97 | #define SX9310_REG_AVG_MSB 0x33 |
| 99 | 98 | #define SX9310_REG_AVG_LSB 0x34 |
| 100 | − | |
| 101 | 99 | #define SX9310_REG_DIFF_MSB 0x35 |
| 102 | 100 | #define SX9310_REG_DIFF_LSB 0x36 |
| 103 | − | |
| 104 | 101 | #define SX9310_REG_OFFSET_MSB 0x37 |
| 105 | 102 | #define SX9310_REG_OFFSET_LSB 0x38 |
| 106 | − | |
| 107 | 103 | #define SX9310_REG_SAR_MSB 0x39 |
| 108 | 104 | #define SX9310_REG_SAR_LSB 0x3a |
| 109 | − | |
| 110 | −#define SX9310_REG_I2CADDR 0x40 | |
| 105 | +#define SX9310_REG_I2C_ADDR 0x40 | |
| 111 | 106 | #define SX9310_REG_PAUSE 0x41 |
| 112 | 107 | #define SX9310_REG_WHOAMI 0x42 |
| 113 | 108 | #define SX9310_WHOAMI_VALUE 0x01 |
| 114 | 109 | #define SX9311_WHOAMI_VALUE 0x02 |
| 115 | − | |
| 116 | 110 | #define SX9310_REG_RESET 0x7f |
| 117 | 111 | #define SX9310_SOFT_RESET 0xde |
| 118 | 112 | |
| 119 | −#define SX9310_SCAN_PERIOD_MASK GENMASK(7, 4) | |
| 120 | −#define SX9310_SCAN_PERIOD_SHIFT 4 | |
| 121 | − | |
| 122 | −#define SX9310_COMPSTAT_MASK GENMASK(3, 0) | |
| 123 | 113 | |
| 124 | 114 | /* 4 hardware channels, as defined in STAT0: COMB, CS2, CS1 and CS0. */ |
| 125 | 115 | #define SX9310_NUM_CHANNELS 4 |
| 126 | −#define SX9310_CHAN_ENABLED_MASK GENMASK(3, 0) | |
| 116 | +static_assert(SX9310_NUM_CHANNELS < BITS_PER_LONG); | |
| 127 | 117 | |
| 128 | 118 | struct sx9310_data { |
| 129 | 119 | /* Serialize access to registers and channel configuration */ |
| @@ -131,20 +121,24 @@ struct sx9310_data { · 1 unmodified line | ||
| 131 | 121 | struct i2c_client *client; |
| 132 | 122 | struct iio_trigger *trig; |
| 133 | 123 | struct regmap *regmap; |
| 124 | + struct regulator_bulk_data supplies[2]; | |
| 134 | 125 | /* |
| 135 | 126 | * Last reading of the proximity status for each channel. |
| 136 | 127 | * We only send an event to user space when this changes. |
| 137 | 128 | */ |
| 138 | − bool prox_stat[SX9310_NUM_CHANNELS]; | |
| 129 | + unsigned long chan_prox_stat; | |
| 139 | 130 | bool trigger_enabled; |
| 140 | − __be16 buffer[SX9310_NUM_CHANNELS + | |
| 141 | − 4]; /* 64-bit data + 64-bit timestamp */ | |
| 131 | + /* Ensure correct alignment of timestamp when present. */ | |
| 132 | + struct { | |
| 133 | + __be16 channels[SX9310_NUM_CHANNELS]; | |
| 134 | + s64 ts __aligned(8); | |
| 135 | + } buffer; | |
| 142 | 136 | /* Remember enabled channels and sample rate during suspend. */ |
| 143 | 137 | unsigned int suspend_ctrl0; |
| 144 | 138 | struct completion completion; |
| 145 | − unsigned int chan_read, chan_event; | |
| 146 | − int channel_users[SX9310_NUM_CHANNELS]; | |
| 147 | − int whoami; | |
| 139 | + unsigned long chan_read; | |
| 140 | + unsigned long chan_event; | |
| 141 | + unsigned int whoami; | |
| 148 | 142 | }; |
| 149 | 143 | |
| 150 | 144 | static const struct iio_event_spec sx9310_events[] = { |
| @@ -251,7 +245,7 @@ static const struct regmap_range sx9310_readable_reg_ranges[] = { · 100 unmodified lines | ||
| 251 | 245 | regmap_reg_range(SX9310_REG_PROX_CTRL0, SX9310_REG_PROX_CTRL19), |
| 252 | 246 | regmap_reg_range(SX9310_REG_SAR_CTRL0, SX9310_REG_SAR_CTRL2), |
| 253 | 247 | regmap_reg_range(SX9310_REG_SENSOR_SEL, SX9310_REG_SAR_LSB), |
| 254 | − regmap_reg_range(SX9310_REG_I2CADDR, SX9310_REG_WHOAMI), | |
| 248 | + regmap_reg_range(SX9310_REG_I2C_ADDR, SX9310_REG_WHOAMI), | |
| 255 | 249 | regmap_reg_range(SX9310_REG_RESET, SX9310_REG_RESET), |
| 256 | 250 | }; |
| 257 | 251 | |
| @@ -285,15 +279,16 @@ static const struct regmap_config sx9310_regmap_config = { · 27 unmodified lines | ||
| 285 | 279 | }; |
| 286 | 280 | |
| 287 | 281 | static int sx9310_update_chan_en(struct sx9310_data *data, |
| 288 | − unsigned int chan_read, | |
| 289 | − unsigned int chan_event) | |
| 282 | + unsigned long chan_read, | |
| 283 | + unsigned long chan_event) | |
| 290 | 284 | { |
| 291 | 285 | int ret; |
| 286 | + unsigned long channels = chan_read | chan_event; | |
| 292 | 287 | |
| 293 | − if ((data->chan_read | data->chan_event) != (chan_read | chan_event)) { | |
| 288 | + if ((data->chan_read | data->chan_event) != channels) { | |
| 294 | 289 | ret = regmap_update_bits(data->regmap, SX9310_REG_PROX_CTRL0, |
| 295 | − SX9310_CHAN_ENABLED_MASK, | |
| 296 | − chan_read | chan_event); | |
| 290 | + SX9310_REG_PROX_CTRL0_SENSOREN_MASK, | |
| 291 | + channels); | |
| 297 | 292 | if (ret) |
| 298 | 293 | return ret; |
| 299 | 294 | } |
| @@ -328,11 +323,15 @@ static int sx9310_put_event_channel(struct sx9310_data *data, int channel) · 28 unmodified lines | ||
| 328 | 323 | |
| 329 | 324 | static int sx9310_enable_irq(struct sx9310_data *data, unsigned int irq) |
| 330 | 325 | { |
| 326 | + if (!data->client->irq) | |
| 327 | + return 0; | |
| 331 | 328 | return regmap_update_bits(data->regmap, SX9310_REG_IRQ_MSK, irq, irq); |
| 332 | 329 | } |
| 333 | 330 | |
| 334 | 331 | static int sx9310_disable_irq(struct sx9310_data *data, unsigned int irq) |
| 335 | 332 | { |
| 333 | + if (!data->client->irq) | |
| 334 | + return 0; | |
| 336 | 335 | return regmap_update_bits(data->regmap, SX9310_REG_IRQ_MSK, irq, 0); |
| 337 | 336 | } |
| 338 | 337 | |
| @@ -342,10 +341,10 @@ static int sx9310_read_prox_data(struct sx9310_data *data, · 3 unmodified lines | ||
| 342 | 341 | int ret; |
| 343 | 342 | |
| 344 | 343 | ret = regmap_write(data->regmap, SX9310_REG_SENSOR_SEL, chan->channel); |
| 345 | − if (ret < 0) | |
| 344 | + if (ret) | |
| 346 | 345 | return ret; |
| 347 | 346 | |
| 348 | − return regmap_bulk_read(data->regmap, chan->address, val, 2); | |
| 347 | + return regmap_bulk_read(data->regmap, chan->address, val, sizeof(*val)); | |
| 349 | 348 | } |
| 350 | 349 | |
| 351 | 350 | /* |
| @@ -358,10 +357,10 @@ static int sx9310_wait_for_sample(struct sx9310_data *data) · 6 unmodified lines | ||
| 358 | 357 | unsigned int val; |
| 359 | 358 | |
| 360 | 359 | ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0, &val); |
| 361 | − if (ret < 0) | |
| 360 | + if (ret) | |
| 362 | 361 | return ret; |
| 363 | 362 | |
| 364 | − val = (val & SX9310_SCAN_PERIOD_MASK) >> SX9310_SCAN_PERIOD_SHIFT; | |
| 363 | + val = FIELD_GET(SX9310_REG_PROX_CTRL0_SCANPERIOD_MASK, val); | |
| 365 | 364 | |
| 366 | 365 | msleep(sx9310_scan_period_table[val]); |
| 367 | 366 | |
| @@ -371,22 +370,22 @@ static int sx9310_wait_for_sample(struct sx9310_data *data) · 3 unmodified lines | ||
| 371 | 370 | static int sx9310_read_proximity(struct sx9310_data *data, |
| 372 | 371 | const struct iio_chan_spec *chan, int *val) |
| 373 | 372 | { |
| 374 | − int ret = 0; | |
| 373 | + int ret; | |
| 375 | 374 | __be16 rawval; |
| 376 | 375 | |
| 377 | 376 | mutex_lock(&data->mutex); |
| 378 | 377 | |
| 379 | 378 | ret = sx9310_get_read_channel(data, chan->channel); |
| 380 | − if (ret < 0) | |
| 379 | + if (ret) | |
| 381 | 380 | goto out; |
| 382 | 381 | |
| 383 | 382 | ret = sx9310_enable_irq(data, SX9310_CONVDONE_IRQ); |
| 384 | − if (ret < 0) | |
| 383 | + if (ret) | |
| 385 | 384 | goto out_put_channel; |
| 386 | 385 | |
| 387 | 386 | mutex_unlock(&data->mutex); |
| 388 | 387 | |
| 389 | − if (data->client->irq > 0) { | |
| 388 | + if (data->client->irq) { | |
| 390 | 389 | ret = wait_for_completion_interruptible(&data->completion); |
| 391 | 390 | reinit_completion(&data->completion); |
| 392 | 391 | } else { |
| @@ -395,22 +394,22 @@ static int sx9310_read_proximity(struct sx9310_data *data, · 2 unmodified lines | ||
| 395 | 394 | |
| 396 | 395 | mutex_lock(&data->mutex); |
| 397 | 396 | |
| 398 | − if (ret < 0) | |
| 397 | + if (ret) | |
| 399 | 398 | goto out_disable_irq; |
| 400 | 399 | |
| 401 | 400 | ret = sx9310_read_prox_data(data, chan, &rawval); |
| 402 | − if (ret < 0) | |
| 401 | + if (ret) | |
| 403 | 402 | goto out_disable_irq; |
| 404 | 403 | |
| 405 | 404 | *val = sign_extend32(be16_to_cpu(rawval), |
| 406 | − (chan->address == SX9310_REG_DIFF_MSB ? 11 : 15)); | |
| 405 | + chan->address == SX9310_REG_DIFF_MSB ? 11 : 15); | |
| 407 | 406 | |
| 408 | 407 | ret = sx9310_disable_irq(data, SX9310_CONVDONE_IRQ); |
| 409 | − if (ret < 0) | |
| 408 | + if (ret) | |
| 410 | 409 | goto out_put_channel; |
| 411 | 410 | |
| 412 | 411 | ret = sx9310_put_read_channel(data, chan->channel); |
| 413 | − if (ret < 0) | |
| 412 | + if (ret) | |
| 414 | 413 | goto out; |
| 415 | 414 | |
| 416 | 415 | mutex_unlock(&data->mutex); |
| @@ -430,12 +429,13 @@ out: · 13 unmodified lines | ||
| 430 | 429 | static int sx9310_read_samp_freq(struct sx9310_data *data, int *val, int *val2) |
| 431 | 430 | { |
| 432 | 431 | unsigned int regval; |
| 433 | − int ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0, ®val); | |
| 432 | + int ret; | |
| 434 | 433 | |
| 435 | − if (ret < 0) | |
| 434 | + ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0, ®val); | |
| 435 | + if (ret) | |
| 436 | 436 | return ret; |
| 437 | 437 | |
| 438 | − regval = (regval & SX9310_SCAN_PERIOD_MASK) >> SX9310_SCAN_PERIOD_SHIFT; | |
| 438 | + regval = FIELD_GET(SX9310_REG_PROX_CTRL0_SCANPERIOD_MASK, regval); | |
| 439 | 439 | *val = sx9310_samp_freq_table[regval].val; |
| 440 | 440 | *val2 = sx9310_samp_freq_table[regval].val2; |
| 441 | 441 | |
| @@ -482,9 +482,10 @@ static int sx9310_set_samp_freq(struct sx9310_data *data, int val, int val2) · 40 unmodified lines | ||
| 482 | 482 | |
| 483 | 483 | mutex_lock(&data->mutex); |
| 484 | 484 | |
| 485 | − ret = regmap_update_bits(data->regmap, SX9310_REG_PROX_CTRL0, | |
| 486 | − SX9310_SCAN_PERIOD_MASK, | |
| 487 | − i << SX9310_SCAN_PERIOD_SHIFT); | |
| 485 | + ret = regmap_update_bits( | |
| 486 | + data->regmap, SX9310_REG_PROX_CTRL0, | |
| 487 | + SX9310_REG_PROX_CTRL0_SCANPERIOD_MASK, | |
| 488 | + FIELD_PREP(SX9310_REG_PROX_CTRL0_SCANPERIOD_MASK, i)); | |
| 488 | 489 | |
| 489 | 490 | mutex_unlock(&data->mutex); |
| 490 | 491 | |
| @@ -515,10 +516,9 @@ static irqreturn_t sx9310_irq_handler(int irq, void *private) · 24 unmodified lines | ||
| 515 | 516 | iio_trigger_poll(data->trig); |
| 516 | 517 | |
| 517 | 518 | /* |
| 518 | − * Even if no event is enabled, we need to wake the thread to | |
| 519 | − * clear the interrupt state by reading SX9310_REG_IRQ_SRC. It | |
| 520 | − * is not possible to do that here because regmap_read takes a | |
| 521 | − * mutex. | |
| 519 | + * Even if no event is enabled, we need to wake the thread to clear the | |
| 520 | + * interrupt state by reading SX9310_REG_IRQ_SRC. | |
| 521 | + * It is not possible to do that here because regmap_read takes a mutex. | |
| 522 | 522 | */ |
| 523 | 523 | return IRQ_WAKE_THREAD; |
| 524 | 524 | } |
| @@ -529,32 +529,32 @@ static void sx9310_push_events(struct iio_dev *indio_dev) · 4 unmodified lines | ||
| 529 | 529 | unsigned int val, chan; |
| 530 | 530 | struct sx9310_data *data = iio_priv(indio_dev); |
| 531 | 531 | s64 timestamp = iio_get_time_ns(indio_dev); |
| 532 | + unsigned long prox_changed; | |
| 532 | 533 | |
| 533 | 534 | /* Read proximity state on all channels */ |
| 534 | 535 | ret = regmap_read(data->regmap, SX9310_REG_STAT0, &val); |
| 535 | − if (ret < 0) { | |
| 536 | + if (ret) { | |
| 536 | 537 | dev_err(&data->client->dev, "i2c transfer error in irq\n"); |
| 537 | 538 | return; |
| 538 | 539 | } |
| 539 | 540 | |
| 540 | − for (chan = 0; chan < SX9310_NUM_CHANNELS; chan++) { | |
| 541 | + /* | |
| 542 | + * Only iterate over channels with changes on proximity status that have | |
| 543 | + * events enabled. | |
| 544 | + */ | |
| 545 | + prox_changed = (data->chan_prox_stat ^ val) & data->chan_event; | |
| 546 | + | |
| 547 | + for_each_set_bit(chan, &prox_changed, SX9310_NUM_CHANNELS) { | |
| 541 | 548 | int dir; |
| 542 | 549 | u64 ev; |
| 543 | − bool new_prox = val & BIT(chan); | |
| 544 | 550 | |
| 545 | − if (!(data->chan_event & BIT(chan))) | |
| 546 | − continue; | |
| 547 | − if (new_prox == data->prox_stat[chan]) | |
| 548 | − /* No change on this channel. */ | |
| 549 | − continue; | |
| 550 | − | |
| 551 | − dir = new_prox ? IIO_EV_DIR_FALLING : IIO_EV_DIR_RISING; | |
| 551 | + dir = (val & BIT(chan)) ? IIO_EV_DIR_FALLING : IIO_EV_DIR_RISING; | |
| 552 | 552 | ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, chan, |
| 553 | 553 | IIO_EV_TYPE_THRESH, dir); |
| 554 | 554 | |
| 555 | 555 | iio_push_event(indio_dev, ev, timestamp); |
| 556 | − data->prox_stat[chan] = new_prox; | |
| 557 | 556 | } |
| 557 | + data->chan_prox_stat = val; | |
| 558 | 558 | } |
| 559 | 559 | |
| 560 | 560 | static irqreturn_t sx9310_irq_thread_handler(int irq, void *private) |
| @@ -567,12 +567,12 @@ static irqreturn_t sx9310_irq_thread_handler(int irq, void *private) · 6 unmodified lines | ||
| 567 | 567 | mutex_lock(&data->mutex); |
| 568 | 568 | |
| 569 | 569 | ret = regmap_read(data->regmap, SX9310_REG_IRQ_SRC, &val); |
| 570 | − if (ret < 0) { | |
| 570 | + if (ret) { | |
| 571 | 571 | dev_err(&data->client->dev, "i2c transfer error in irq\n"); |
| 572 | 572 | goto out; |
| 573 | 573 | } |
| 574 | 574 | |
| 575 | − if (val & SX9310_EVENT_IRQ) | |
| 575 | + if (val & (SX9310_FAR_IRQ | SX9310_CLOSE_IRQ)) | |
| 576 | 576 | sx9310_push_events(indio_dev); |
| 577 | 577 | |
| 578 | 578 | if (val & SX9310_CONVDONE_IRQ) |
| @@ -600,6 +600,7 @@ static int sx9310_write_event_config(struct iio_dev *indio_dev, · 21 unmodified lines | ||
| 600 | 600 | enum iio_event_direction dir, int state) |
| 601 | 601 | { |
| 602 | 602 | struct sx9310_data *data = iio_priv(indio_dev); |
| 603 | + unsigned int eventirq = SX9310_FAR_IRQ | SX9310_CLOSE_IRQ; | |
| 603 | 604 | int ret; |
| 604 | 605 | |
| 605 | 606 | /* If the state hasn't changed, there's nothing to do. */ |
| @@ -609,20 +610,20 @@ static int sx9310_write_event_config(struct iio_dev *indio_dev, · 3 unmodified lines | ||
| 609 | 610 | mutex_lock(&data->mutex); |
| 610 | 611 | if (state) { |
| 611 | 612 | ret = sx9310_get_event_channel(data, chan->channel); |
| 612 | − if (ret < 0) | |
| 613 | + if (ret) | |
| 613 | 614 | goto out_unlock; |
| 614 | 615 | if (!(data->chan_event & ~BIT(chan->channel))) { |
| 615 | − ret = sx9310_enable_irq(data, SX9310_EVENT_IRQ); | |
| 616 | − if (ret < 0) | |
| 616 | + ret = sx9310_enable_irq(data, eventirq); | |
| 617 | + if (ret) | |
| 617 | 618 | sx9310_put_event_channel(data, chan->channel); |
| 618 | 619 | } |
| 619 | 620 | } else { |
| 620 | 621 | ret = sx9310_put_event_channel(data, chan->channel); |
| 621 | − if (ret < 0) | |
| 622 | + if (ret) | |
| 622 | 623 | goto out_unlock; |
| 623 | 624 | if (!data->chan_event) { |
| 624 | − ret = sx9310_disable_irq(data, SX9310_EVENT_IRQ); | |
| 625 | − if (ret < 0) | |
| 625 | + ret = sx9310_disable_irq(data, eventirq); | |
| 626 | + if (ret) | |
| 626 | 627 | sx9310_get_event_channel(data, chan->channel); |
| 627 | 628 | } |
| 628 | 629 | } |
| @@ -634,7 +635,7 @@ out_unlock: · 5 unmodified lines | ||
| 634 | 635 | |
| 635 | 636 | static struct attribute *sx9310_attributes[] = { |
| 636 | 637 | &iio_dev_attr_sampling_frequency_available.dev_attr.attr, |
| 637 | − NULL, | |
| 638 | + NULL | |
| 638 | 639 | }; |
| 639 | 640 | |
| 640 | 641 | static const struct attribute_group sx9310_attribute_group = { |
| @@ -661,7 +662,7 @@ static int sx9310_set_trigger_state(struct iio_trigger *trig, bool state) · 20 unmodified lines | ||
| 661 | 662 | ret = sx9310_enable_irq(data, SX9310_CONVDONE_IRQ); |
| 662 | 663 | else if (!data->chan_read) |
| 663 | 664 | ret = sx9310_disable_irq(data, SX9310_CONVDONE_IRQ); |
| 664 | − if (ret < 0) | |
| 665 | + if (ret) | |
| 665 | 666 | goto out; |
| 666 | 667 | |
| 667 | 668 | data->trigger_enabled = state; |
| @@ -690,13 +691,13 @@ static irqreturn_t sx9310_trigger_handler(int irq, void *private) · 22 unmodified lines | ||
| 690 | 691 | indio_dev->masklength) { |
| 691 | 692 | ret = sx9310_read_prox_data(data, &indio_dev->channels[bit], |
| 692 | 693 | &val); |
| 693 | − if (ret < 0) | |
| 694 | + if (ret) | |
| 694 | 695 | goto out; |
| 695 | 696 | |
| 696 | − data->buffer[i++] = val; | |
| 697 | + data->buffer.channels[i++] = val; | |
| 697 | 698 | } |
| 698 | 699 | |
| 699 | − iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, | |
| 700 | + iio_push_to_buffers_with_timestamp(indio_dev, &data->buffer, | |
| 700 | 701 | pf->timestamp); |
| 701 | 702 | |
| 702 | 703 | out: |
| @@ -710,13 +711,13 @@ out: · 7 unmodified lines | ||
| 710 | 711 | static int sx9310_buffer_preenable(struct iio_dev *indio_dev) |
| 711 | 712 | { |
| 712 | 713 | struct sx9310_data *data = iio_priv(indio_dev); |
| 713 | − unsigned int channels = 0; | |
| 714 | + unsigned long channels = 0; | |
| 714 | 715 | int bit, ret; |
| 715 | 716 | |
| 716 | 717 | mutex_lock(&data->mutex); |
| 717 | 718 | for_each_set_bit(bit, indio_dev->active_scan_mask, |
| 718 | 719 | indio_dev->masklength) |
| 719 | − channels |= BIT(indio_dev->channels[bit].channel); | |
| 720 | + __set_bit(indio_dev->channels[bit].channel, &channels); | |
| 720 | 721 | |
| 721 | 722 | ret = sx9310_update_chan_en(data, channels, data->chan_event); |
| 722 | 723 | mutex_unlock(&data->mutex); |
| @@ -744,89 +745,77 @@ struct sx9310_reg_default { · 21 unmodified lines | ||
| 744 | 745 | u8 def; |
| 745 | 746 | }; |
| 746 | 747 | |
| 747 | −#define SX_INIT(_reg, _def) \ | |
| 748 | − { \ | |
| 749 | − .reg = SX9310_REG_##_reg, \ | |
| 750 | − .def = _def, \ | |
| 751 | − } | |
| 752 | − | |
| 753 | 748 | static const struct sx9310_reg_default sx9310_default_regs[] = { |
| 754 | − SX_INIT(IRQ_MSK, 0x00), | |
| 755 | − SX_INIT(IRQ_FUNC, 0x00), | |
| 749 | + { SX9310_REG_IRQ_MSK, 0x00 }, | |
| 750 | + { SX9310_REG_IRQ_FUNC, 0x00 }, | |
| 756 | 751 | /* |
| 757 | 752 | * The lower 4 bits should not be set as it enable sensors measurements. |
| 758 | 753 | * Turning the detection on before the configuration values are set to |
| 759 | 754 | * good values can cause the device to return erroneous readings. |
| 760 | 755 | */ |
| 761 | − SX_INIT(PROX_CTRL0, SX9310_REG_PROX_CTRL0_PROXSTAT2), | |
| 762 | − SX_INIT(PROX_CTRL1, 0x00), | |
| 763 | − SX_INIT(PROX_CTRL2, SX9310_REG_PROX_CTRL2_COMBMODE_ALL | | |
| 764 | − SX9310_REG_PROX_CTRL2_SHIELDEN_DYNAMIC), | |
| 765 | − SX_INIT(PROX_CTRL3, SX9310_REG_PROX_CTRL3_GAIN0_X8 | | |
| 766 | − SX9310_REG_PROX_CTRL3_GAIN12_X4), | |
| 767 | − SX_INIT(PROX_CTRL4, SX9310_REG_PROX_CTRL4_RESOLUTION_FINEST), | |
| 768 | − SX_INIT(PROX_CTRL5, SX9310_REG_PROX_CTRL5_RANGE_SMALL | | |
| 769 | − SX9310_REG_PROX_CTRL5_STARTUPSENS_CS1 | | |
| 770 | − SX9310_REG_PROX_CTRL5_RAWFILT_1P25), | |
| 771 | − SX_INIT(PROX_CTRL6, SX9310_REG_PROX_CTRL6_COMP_COMMON), | |
| 772 | − SX_INIT(PROX_CTRL7, SX9310_REG_PROX_CTRL7_AVGNEGFILT_2 | | |
| 773 | − SX9310_REG_PROX_CTRL7_AVGPOSFILT_512), | |
| 774 | − SX_INIT(PROX_CTRL8, SX9310_REG_PROX_CTRL8_9_PTHRESH_96 | | |
| 775 | − SX9310_REG_PROX_CTRL8_9_BODYTHRESH_1500), | |
| 776 | − SX_INIT(PROX_CTRL9, SX9310_REG_PROX_CTRL8_9_PTHRESH12_28 | | |
| 777 | − SX9310_REG_PROX_CTRL8_9_BODYTHRESH_900), | |
| 778 | − SX_INIT(PROX_CTRL10, SX9310_REG_PROX_CTRL10_HYST_6PCT | | |
| 779 | − SX9310_REG_PROX_CTRL10_CLOSE_DEBOUNCE_8 | | |
| 780 | − SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_8), | |
| 781 | − SX_INIT(PROX_CTRL11, 0x00), | |
| 782 | − SX_INIT(PROX_CTRL12, 0x00), | |
| 783 | − SX_INIT(PROX_CTRL13, 0x00), | |
| 784 | − SX_INIT(PROX_CTRL14, 0x00), | |
| 785 | − SX_INIT(PROX_CTRL15, 0x00), | |
| 786 | − SX_INIT(PROX_CTRL16, 0x00), | |
| 787 | − SX_INIT(PROX_CTRL17, 0x00), | |
| 788 | − SX_INIT(PROX_CTRL18, 0x00), | |
| 789 | − SX_INIT(PROX_CTRL19, 0x00), | |
| 790 | − SX_INIT(SAR_CTRL0, SX9310_REG_SAR_CTRL0_SARDEB_4_SAMPLES | | |
| 791 | − SX9310_REG_SAR_CTRL0_SARHYST_8), | |
| 792 | − SX_INIT(SAR_CTRL1, SX9310_REG_SAR_CTRL1_SLOPE(10781250)), | |
| 793 | − SX_INIT(SAR_CTRL2, SX9310_REG_SAR_CTRL2_SAROFFSET_DEFAULT), | |
| 756 | + { SX9310_REG_PROX_CTRL0, SX9310_REG_PROX_CTRL0_SCANPERIOD_15MS }, | |
| 757 | + { SX9310_REG_PROX_CTRL1, 0x00 }, | |
| 758 | + { SX9310_REG_PROX_CTRL2, SX9310_REG_PROX_CTRL2_COMBMODE_CS1_CS2 | | |
| 759 | + SX9310_REG_PROX_CTRL2_SHIELDEN_DYNAMIC }, | |
| 760 | + { SX9310_REG_PROX_CTRL3, SX9310_REG_PROX_CTRL3_GAIN0_X8 | | |
| 761 | + SX9310_REG_PROX_CTRL3_GAIN12_X4 }, | |
| 762 | + { SX9310_REG_PROX_CTRL4, SX9310_REG_PROX_CTRL4_RESOLUTION_FINEST }, | |
| 763 | + { SX9310_REG_PROX_CTRL5, SX9310_REG_PROX_CTRL5_RANGE_SMALL | | |
| 764 | + SX9310_REG_PROX_CTRL5_STARTUPSENS_CS1 | | |
| 765 | + SX9310_REG_PROX_CTRL5_RAWFILT_1P25 }, | |
| 766 | + { SX9310_REG_PROX_CTRL6, SX9310_REG_PROX_CTRL6_AVGTHRESH_DEFAULT }, | |
| 767 | + { SX9310_REG_PROX_CTRL7, SX9310_REG_PROX_CTRL7_AVGNEGFILT_2 | | |
| 768 | + SX9310_REG_PROX_CTRL7_AVGPOSFILT_512 }, | |
| 769 | + { SX9310_REG_PROX_CTRL8, SX9310_REG_PROX_CTRL8_9_PTHRESH_96 | | |
| 770 | + SX9310_REG_PROX_CTRL8_9_BODYTHRESH_1500 }, | |
| 771 | + { SX9310_REG_PROX_CTRL9, SX9310_REG_PROX_CTRL8_9_PTHRESH_28 | | |
| 772 | + SX9310_REG_PROX_CTRL8_9_BODYTHRESH_900 }, | |
| 773 | + { SX9310_REG_PROX_CTRL10, SX9310_REG_PROX_CTRL10_HYST_6PCT | | |
| 774 | + SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_2 }, | |
| 775 | + { SX9310_REG_PROX_CTRL11, 0x00 }, | |
| 776 | + { SX9310_REG_PROX_CTRL12, 0x00 }, | |
| 777 | + { SX9310_REG_PROX_CTRL13, 0x00 }, | |
| 778 | + { SX9310_REG_PROX_CTRL14, 0x00 }, | |
| 779 | + { SX9310_REG_PROX_CTRL15, 0x00 }, | |
| 780 | + { SX9310_REG_PROX_CTRL16, 0x00 }, | |
| 781 | + { SX9310_REG_PROX_CTRL17, 0x00 }, | |
| 782 | + { SX9310_REG_PROX_CTRL18, 0x00 }, | |
| 783 | + { SX9310_REG_PROX_CTRL19, 0x00 }, | |
| 784 | + { SX9310_REG_SAR_CTRL0, SX9310_REG_SAR_CTRL0_SARDEB_4_SAMPLES | | |
| 785 | + SX9310_REG_SAR_CTRL0_SARHYST_8 }, | |
| 786 | + { SX9310_REG_SAR_CTRL1, SX9310_REG_SAR_CTRL1_SLOPE(10781250) }, | |
| 787 | + { SX9310_REG_SAR_CTRL2, SX9310_REG_SAR_CTRL2_SAROFFSET_DEFAULT }, | |
| 794 | 788 | }; |
| 795 | 789 | |
| 796 | 790 | /* Activate all channels and perform an initial compensation. */ |
| 797 | 791 | static int sx9310_init_compensation(struct iio_dev *indio_dev) |
| 798 | 792 | { |
| 799 | 793 | struct sx9310_data *data = iio_priv(indio_dev); |
| 800 | − int i, ret; | |
| 794 | + int ret; | |
| 801 | 795 | unsigned int val; |
| 802 | 796 | unsigned int ctrl0; |
| 803 | 797 | |
| 804 | 798 | ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0, &ctrl0); |
| 805 | − if (ret < 0) | |
| 799 | + if (ret) | |
| 806 | 800 | return ret; |
| 807 | 801 | |
| 808 | 802 | /* run the compensation phase on all channels */ |
| 809 | 803 | ret = regmap_write(data->regmap, SX9310_REG_PROX_CTRL0, |
| 810 | − ctrl0 | SX9310_REG_PROX_CTRL0_EN_MASK); | |
| 811 | − if (ret < 0) | |
| 804 | + ctrl0 | SX9310_REG_PROX_CTRL0_SENSOREN_MASK); | |
| 805 | + if (ret) | |
| 812 | 806 | return ret; |
| 813 | 807 | |
| 814 | − for (i = 100; i >= 0; i--) { | |
| 815 | − msleep(20); | |
| 816 | − ret = regmap_read(data->regmap, SX9310_REG_STAT1, &val); | |
| 817 | − if (ret < 0) | |
| 818 | − goto out; | |
| 819 | − if (!(val & SX9310_COMPSTAT_MASK)) | |
| 820 | − break; | |
| 821 | − } | |
| 822 | − | |
| 823 | − if (i < 0) { | |
| 824 | − dev_err(&data->client->dev, | |
| 825 | − "initial compensation timed out: 0x%02x", val); | |
| 826 | − ret = -ETIMEDOUT; | |
| 808 | + ret = regmap_read_poll_timeout(data->regmap, SX9310_REG_STAT1, val, | |
| 809 | + !(val & SX9310_REG_STAT1_COMPSTAT_MASK), | |
| 810 | + 20000, 2000000); | |
| 811 | + if (ret) { | |
| 812 | + if (ret == -ETIMEDOUT) | |
| 813 | + dev_err(&data->client->dev, | |
| 814 | + "initial compensation timed out: 0x%02x\n", | |
| 815 | + val); | |
| 816 | + return ret; | |
| 827 | 817 | } |
| 828 | 818 | |
| 829 | −out: | |
| 830 | 819 | regmap_write(data->regmap, SX9310_REG_PROX_CTRL0, ctrl0); |
| 831 | 820 | return ret; |
| 832 | 821 | } |
| @@ -839,21 +828,21 @@ static int sx9310_init_device(struct iio_dev *indio_dev) · 6 unmodified lines | ||
| 839 | 828 | unsigned int i, val; |
| 840 | 829 | |
| 841 | 830 | ret = regmap_write(data->regmap, SX9310_REG_RESET, SX9310_SOFT_RESET); |
| 842 | − if (ret < 0) | |
| 831 | + if (ret) | |
| 843 | 832 | return ret; |
| 844 | 833 | |
| 845 | 834 | usleep_range(1000, 2000); /* power-up time is ~1ms. */ |
| 846 | 835 | |
| 847 | 836 | /* Clear reset interrupt state by reading SX9310_REG_IRQ_SRC. */ |
| 848 | 837 | ret = regmap_read(data->regmap, SX9310_REG_IRQ_SRC, &val); |
| 849 | − if (ret < 0) | |
| 838 | + if (ret) | |
| 850 | 839 | return ret; |
| 851 | 840 | |
| 852 | 841 | /* Program some sane defaults. */ |
| 853 | 842 | for (i = 0; i < ARRAY_SIZE(sx9310_default_regs); i++) { |
| 854 | 843 | initval = &sx9310_default_regs[i]; |
| 855 | 844 | ret = regmap_write(data->regmap, initval->reg, initval->def); |
| 856 | − if (ret < 0) | |
| 845 | + if (ret) | |
| 857 | 846 | return ret; |
| 858 | 847 | } |
| 859 | 848 | |
| @@ -862,24 +851,15 @@ static int sx9310_init_device(struct iio_dev *indio_dev) · 2 unmodified lines | ||
| 862 | 851 | |
| 863 | 852 | static int sx9310_set_indio_dev_name(struct device *dev, |
| 864 | 853 | struct iio_dev *indio_dev, |
| 865 | − const struct i2c_device_id *id, int whoami) | |
| 854 | + unsigned int whoami) | |
| 866 | 855 | { |
| 867 | − const struct acpi_device_id *acpi_id; | |
| 868 | − | |
| 869 | − /* id will be NULL when enumerated via ACPI */ | |
| 870 | − if (id) { | |
| 871 | − if (id->driver_data != whoami) | |
| 872 | − dev_err(dev, "WHOAMI does not match i2c_device_id: %s", | |
| 873 | − id->name); | |
| 874 | − } else if (ACPI_HANDLE(dev)) { | |
| 875 | − acpi_id = acpi_match_device(dev->driver->acpi_match_table, dev); | |
| 876 | − if (!acpi_id) | |
| 877 | − return -ENODEV; | |
| 878 | − if (acpi_id->driver_data != whoami) | |
| 879 | − dev_err(dev, "WHOAMI does not match acpi_device_id: %s", | |
| 880 | − acpi_id->id); | |
| 881 | − } else | |
| 856 | + unsigned int long ddata; | |
| 857 | + | |
| 858 | + ddata = (uintptr_t)device_get_match_data(dev); | |
| 859 | + if (ddata != whoami) { | |
| 860 | + dev_err(dev, "WHOAMI does not match device data: %u\n", whoami); | |
| 882 | 861 | return -ENODEV; |
| 862 | + } | |
| 883 | 863 | |
| 884 | 864 | switch (whoami) { |
| 885 | 865 | case SX9310_WHOAMI_VALUE: |
| @@ -889,26 +869,35 @@ static int sx9310_set_indio_dev_name(struct device *dev, · 3 unmodified lines | ||
| 889 | 869 | indio_dev->name = "sx9311"; |
| 890 | 870 | break; |
| 891 | 871 | default: |
| 892 | − dev_err(dev, "unexpected WHOAMI response: %u", whoami); | |
| 872 | + dev_err(dev, "unexpected WHOAMI response: %u\n", whoami); | |
| 893 | 873 | return -ENODEV; |
| 894 | 874 | } |
| 895 | 875 | |
| 896 | 876 | return 0; |
| 897 | 877 | } |
| 898 | 878 | |
| 899 | −static int sx9310_probe(struct i2c_client *client, | |
| 900 | − const struct i2c_device_id *id) | |
| 879 | +static void sx9310_regulator_disable(void *_data) | |
| 880 | +{ | |
| 881 | + struct sx9310_data *data = _data; | |
| 882 | + | |
| 883 | + regulator_bulk_disable(ARRAY_SIZE(data->supplies), data->supplies); | |
| 884 | +} | |
| 885 | + | |
| 886 | +static int sx9310_probe(struct i2c_client *client) | |
| 901 | 887 | { |
| 902 | 888 | int ret; |
| 889 | + struct device *dev = &client->dev; | |
| 903 | 890 | struct iio_dev *indio_dev; |
| 904 | 891 | struct sx9310_data *data; |
| 905 | 892 | |
| 906 | − indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); | |
| 907 | − if (indio_dev == NULL) | |
| 893 | + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); | |
| 894 | + if (!indio_dev) | |
| 908 | 895 | return -ENOMEM; |
| 909 | 896 | |
| 910 | 897 | data = iio_priv(indio_dev); |
| 911 | 898 | data->client = client; |
| 899 | + data->supplies[0].supply = "vdd"; | |
| 900 | + data->supplies[1].supply = "svdd"; | |
| 912 | 901 | mutex_init(&data->mutex); |
| 913 | 902 | init_completion(&data->completion); |
| 914 | 903 | |
| @@ -916,19 +905,32 @@ static int sx9310_probe(struct i2c_client *client, · 1 unmodified line | ||
| 916 | 905 | if (IS_ERR(data->regmap)) |
| 917 | 906 | return PTR_ERR(data->regmap); |
| 918 | 907 | |
| 908 | + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(data->supplies), | |
| 909 | + data->supplies); | |
| 910 | + if (ret) | |
| 911 | + return ret; | |
| 912 | + | |
| 913 | + ret = regulator_bulk_enable(ARRAY_SIZE(data->supplies), data->supplies); | |
| 914 | + if (ret) | |
| 915 | + return ret; | |
| 916 | + /* Must wait for Tpor time after initial power up */ | |
| 917 | + usleep_range(1000, 1100); | |
| 918 | + | |
| 919 | + ret = devm_add_action_or_reset(dev, sx9310_regulator_disable, data); | |
| 920 | + if (ret) | |
| 921 | + return ret; | |
| 922 | + | |
| 919 | 923 | ret = regmap_read(data->regmap, SX9310_REG_WHOAMI, &data->whoami); |
| 920 | − if (ret < 0) { | |
| 921 | − dev_err(&client->dev, "error in reading WHOAMI register: %d", | |
| 922 | − ret); | |
| 924 | + if (ret) { | |
| 925 | + dev_err(dev, "error in reading WHOAMI register: %d", ret); | |
| 923 | 926 | return ret; |
| 924 | 927 | } |
| 925 | 928 | |
| 926 | − ret = sx9310_set_indio_dev_name(&client->dev, indio_dev, id, | |
| 927 | − data->whoami); | |
| 928 | − if (ret < 0) | |
| 929 | + ret = sx9310_set_indio_dev_name(dev, indio_dev, data->whoami); | |
| 930 | + if (ret) | |
| 929 | 931 | return ret; |
| 930 | 932 | |
| 931 | − ACPI_COMPANION_SET(&indio_dev->dev, ACPI_COMPANION(&client->dev)); | |
| 933 | + ACPI_COMPANION_SET(&indio_dev->dev, ACPI_COMPANION(dev)); | |
| 932 | 934 | indio_dev->channels = sx9310_channels; |
| 933 | 935 | indio_dev->num_channels = ARRAY_SIZE(sx9310_channels); |
| 934 | 936 | indio_dev->info = &sx9310_info; |
| @@ -936,41 +938,41 @@ static int sx9310_probe(struct i2c_client *client, · 1 unmodified line | ||
| 936 | 938 | i2c_set_clientdata(client, indio_dev); |
| 937 | 939 | |
| 938 | 940 | ret = sx9310_init_device(indio_dev); |
| 939 | − if (ret < 0) | |
| 941 | + if (ret) | |
| 940 | 942 | return ret; |
| 941 | 943 | |
| 942 | 944 | if (client->irq) { |
| 943 | − ret = devm_request_threaded_irq(&client->dev, client->irq, | |
| 945 | + ret = devm_request_threaded_irq(dev, client->irq, | |
| 944 | 946 | sx9310_irq_handler, |
| 945 | 947 | sx9310_irq_thread_handler, |
| 946 | − IRQF_TRIGGER_LOW | IRQF_ONESHOT, | |
| 948 | + IRQF_ONESHOT, | |
| 947 | 949 | "sx9310_event", indio_dev); |
| 948 | − if (ret < 0) | |
| 950 | + if (ret) | |
| 949 | 951 | return ret; |
| 950 | 952 | |
| 951 | − data->trig = | |
| 952 | − devm_iio_trigger_alloc(&client->dev, "%s-dev%d", | |
| 953 | − indio_dev->name, indio_dev->id); | |
| 953 | + data->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", | |
| 954 | + indio_dev->name, | |
| 955 | + indio_dev->id); | |
| 954 | 956 | if (!data->trig) |
| 955 | 957 | return -ENOMEM; |
| 956 | 958 | |
| 957 | − data->trig->dev.parent = &client->dev; | |
| 959 | + data->trig->dev.parent = dev; | |
| 958 | 960 | data->trig->ops = &sx9310_trigger_ops; |
| 959 | 961 | iio_trigger_set_drvdata(data->trig, indio_dev); |
| 960 | 962 | |
| 961 | − ret = devm_iio_trigger_register(&client->dev, data->trig); | |
| 963 | + ret = devm_iio_trigger_register(dev, data->trig); | |
| 962 | 964 | if (ret) |
| 963 | 965 | return ret; |
| 964 | 966 | } |
| 965 | 967 | |
| 966 | − ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev, | |
| 968 | + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, | |
| 967 | 969 | iio_pollfunc_store_time, |
| 968 | 970 | sx9310_trigger_handler, |
| 969 | 971 | &sx9310_buffer_setup_ops); |
| 970 | − if (ret < 0) | |
| 972 | + if (ret) | |
| 971 | 973 | return ret; |
| 972 | 974 | |
| 973 | − return devm_iio_device_register(&client->dev, indio_dev); | |
| 975 | + return devm_iio_device_register(dev, indio_dev); | |
| 974 | 976 | } |
| 975 | 977 | |
| 976 | 978 | static int __maybe_unused sx9310_suspend(struct device *dev) |
| @@ -985,11 +987,10 @@ static int __maybe_unused sx9310_suspend(struct device *dev) · 8 unmodified lines | ||
| 985 | 987 | mutex_lock(&data->mutex); |
| 986 | 988 | ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0, |
| 987 | 989 | &data->suspend_ctrl0); |
| 988 | − | |
| 989 | 990 | if (ret) |
| 990 | 991 | goto out; |
| 991 | 992 | |
| 992 | − ctrl0 = data->suspend_ctrl0 & ~SX9310_REG_PROX_CTRL0_EN_MASK; | |
| 993 | + ctrl0 = data->suspend_ctrl0 & ~SX9310_REG_PROX_CTRL0_SENSOREN_MASK; | |
| 993 | 994 | ret = regmap_write(data->regmap, SX9310_REG_PROX_CTRL0, ctrl0); |
| 994 | 995 | if (ret) |
| 995 | 996 | goto out; |
| @@ -1017,10 +1018,11 @@ static int __maybe_unused sx9310_resume(struct device *dev) · 21 unmodified lines | ||
| 1017 | 1018 | |
| 1018 | 1019 | out: |
| 1019 | 1020 | mutex_unlock(&data->mutex); |
| 1021 | + if (ret) | |
| 1022 | + return ret; | |
| 1020 | 1023 | |
| 1021 | 1024 | enable_irq(data->client->irq); |
| 1022 | − | |
| 1023 | − return ret; | |
| 1025 | + return 0; | |
| 1024 | 1026 | } |
| 1025 | 1027 | |
| 1026 | 1028 | static const struct dev_pm_ops sx9310_pm_ops = { |
| @@ -1030,32 +1032,39 @@ static const struct dev_pm_ops sx9310_pm_ops = { · 3 unmodified lines | ||
| 1030 | 1032 | static const struct acpi_device_id sx9310_acpi_match[] = { |
| 1031 | 1033 | { "STH9310", SX9310_WHOAMI_VALUE }, |
| 1032 | 1034 | { "STH9311", SX9311_WHOAMI_VALUE }, |
| 1033 | − {}, | |
| 1035 | + {} | |
| 1034 | 1036 | }; |
| 1035 | 1037 | MODULE_DEVICE_TABLE(acpi, sx9310_acpi_match); |
| 1036 | 1038 | |
| 1037 | 1039 | static const struct of_device_id sx9310_of_match[] = { |
| 1038 | − { .compatible = "semtech,sx9310" }, | |
| 1039 | − { .compatible = "semtech,sx9311" }, | |
| 1040 | − {}, | |
| 1040 | + { .compatible = "semtech,sx9310", (void *)SX9310_WHOAMI_VALUE }, | |
| 1041 | + { .compatible = "semtech,sx9311", (void *)SX9311_WHOAMI_VALUE }, | |
| 1042 | + {} | |
| 1041 | 1043 | }; |
| 1042 | 1044 | MODULE_DEVICE_TABLE(of, sx9310_of_match); |
| 1043 | 1045 | |
| 1044 | 1046 | static const struct i2c_device_id sx9310_id[] = { |
| 1045 | 1047 | { "sx9310", SX9310_WHOAMI_VALUE }, |
| 1046 | 1048 | { "sx9311", SX9311_WHOAMI_VALUE }, |
| 1047 | − {}, | |
| 1049 | + {} | |
| 1048 | 1050 | }; |
| 1049 | 1051 | MODULE_DEVICE_TABLE(i2c, sx9310_id); |
| 1050 | 1052 | |
| 1051 | 1053 | static struct i2c_driver sx9310_driver = { |
| 1052 | 1054 | .driver = { |
| 1053 | 1055 | .name = "sx9310", |
| 1054 | − .acpi_match_table = ACPI_PTR(sx9310_acpi_match), | |
| 1055 | − .of_match_table = of_match_ptr(sx9310_of_match), | |
| 1056 | + .acpi_match_table = sx9310_acpi_match, | |
| 1057 | + .of_match_table = sx9310_of_match, | |
| 1056 | 1058 | .pm = &sx9310_pm_ops, |
| 1059 | + | |
| 1060 | + /* | |
| 1061 | + * Lots of i2c transfers in probe + over 200 ms waiting in | |
| 1062 | + * sx9310_init_compensation() mean a slow probe; prefer async | |
| 1063 | + * so we don't delay boot if we're builtin to the kernel. | |
| 1064 | + */ | |
| 1065 | + .probe_type = PROBE_PREFER_ASYNCHRONOUS, | |
| 1057 | 1066 | }, |
| 1058 | − .probe = sx9310_probe, | |
| 1067 | + .probe_new = sx9310_probe, | |
| 1059 | 1068 | .id_table = sx9310_id, |
| 1060 | 1069 | }; |
| 1061 | 1070 | module_i2c_driver(sx9310_driver); |
| @@ -4,18 +4,19 @@ · 3 unmodified lines | ||
| 4 | 4 | * |
| 5 | 5 | * Copyright (C) 2016 STMicroelectronics Imaging Division. |
| 6 | 6 | * Copyright (C) 2018 Song Qiang <songqiang1304521@gmail.com> |
| 7 | + * Copyright (C) 2020 Ivan Drobyshevskyi <drobyshevskyi@gmail.com> | |
| 7 | 8 | * |
| 8 | 9 | * Datasheet available at |
| 9 | 10 | * <https://www.st.com/resource/en/datasheet/vl53l0x.pdf> |
| 10 | 11 | * |
| 11 | 12 | * Default 7-bit i2c slave address 0x29. |
| 12 | 13 | * |
| 13 | − * TODO: FIFO buffer, continuous mode, interrupts, range selection, | |
| 14 | − * sensor ID check. | |
| 14 | + * TODO: FIFO buffer, continuous mode, range selection, sensor ID check. | |
| 15 | 15 | */ |
| 16 | 16 | |
| 17 | 17 | #include <linux/delay.h> |
| 18 | 18 | #include <linux/i2c.h> |
| 19 | +#include <linux/interrupt.h> | |
| 19 | 20 | #include <linux/module.h> |
| 20 | 21 | |
| 21 | 22 | #include <linux/iio/iio.h> |
| @@ -29,14 +30,72 @@ · 7 unmodified lines | ||
| 29 | 30 | #define VL_REG_SYSRANGE_MODE_TIMED BIT(2) |
| 30 | 31 | #define VL_REG_SYSRANGE_MODE_HISTOGRAM BIT(3) |
| 31 | 32 | |
| 33 | +#define VL_REG_SYSTEM_INTERRUPT_CONFIG_GPIO 0x0A | |
| 34 | +#define VL_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY BIT(2) | |
| 35 | + | |
| 36 | +#define VL_REG_SYSTEM_INTERRUPT_CLEAR 0x0B | |
| 37 | + | |
| 32 | 38 | #define VL_REG_RESULT_INT_STATUS 0x13 |
| 33 | 39 | #define VL_REG_RESULT_RANGE_STATUS 0x14 |
| 34 | 40 | #define VL_REG_RESULT_RANGE_STATUS_COMPLETE BIT(0) |
| 35 | 41 | |
| 36 | 42 | struct vl53l0x_data { |
| 37 | 43 | struct i2c_client *client; |
| 44 | + struct completion completion; | |
| 38 | 45 | }; |
| 39 | 46 | |
| 47 | +static irqreturn_t vl53l0x_handle_irq(int irq, void *priv) | |
| 48 | +{ | |
| 49 | + struct iio_dev *indio_dev = priv; | |
| 50 | + struct vl53l0x_data *data = iio_priv(indio_dev); | |
| 51 | + | |
| 52 | + complete(&data->completion); | |
| 53 | + | |
| 54 | + return IRQ_HANDLED; | |
| 55 | +} | |
| 56 | + | |
| 57 | +static int vl53l0x_configure_irq(struct i2c_client *client, | |
| 58 | + struct iio_dev *indio_dev) | |
| 59 | +{ | |
| 60 | + struct vl53l0x_data *data = iio_priv(indio_dev); | |
| 61 | + int ret; | |
| 62 | + | |
| 63 | + ret = devm_request_irq(&client->dev, client->irq, vl53l0x_handle_irq, | |
| 64 | + IRQF_TRIGGER_FALLING, indio_dev->name, indio_dev); | |
| 65 | + if (ret) { | |
| 66 | + dev_err(&client->dev, "devm_request_irq error: %d\n", ret); | |
| 67 | + return ret; | |
| 68 | + } | |
| 69 | + | |
| 70 | + ret = i2c_smbus_write_byte_data(data->client, | |
| 71 | + VL_REG_SYSTEM_INTERRUPT_CONFIG_GPIO, | |
| 72 | + VL_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY); | |
| 73 | + if (ret < 0) | |
| 74 | + dev_err(&client->dev, "failed to configure IRQ: %d\n", ret); | |
| 75 | + | |
| 76 | + return ret; | |
| 77 | +} | |
| 78 | + | |
| 79 | +static void vl53l0x_clear_irq(struct vl53l0x_data *data) | |
| 80 | +{ | |
| 81 | + struct device *dev = &data->client->dev; | |
| 82 | + int ret; | |
| 83 | + | |
| 84 | + ret = i2c_smbus_write_byte_data(data->client, | |
| 85 | + VL_REG_SYSTEM_INTERRUPT_CLEAR, 1); | |
| 86 | + if (ret < 0) | |
| 87 | + dev_err(dev, "failed to clear error irq: %d\n", ret); | |
| 88 | + | |
| 89 | + ret = i2c_smbus_write_byte_data(data->client, | |
| 90 | + VL_REG_SYSTEM_INTERRUPT_CLEAR, 0); | |
| 91 | + if (ret < 0) | |
| 92 | + dev_err(dev, "failed to clear range irq: %d\n", ret); | |
| 93 | + | |
| 94 | + ret = i2c_smbus_read_byte_data(data->client, VL_REG_RESULT_INT_STATUS); | |
| 95 | + if (ret < 0 || ret & 0x07) | |
| 96 | + dev_err(dev, "failed to clear irq: %d\n", ret); | |
| 97 | +} | |
| 98 | + | |
| 40 | 99 | static int vl53l0x_read_proximity(struct vl53l0x_data *data, |
| 41 | 100 | const struct iio_chan_spec *chan, |
| 42 | 101 | int *val) |
| @@ -50,19 +109,31 @@ static int vl53l0x_read_proximity(struct vl53l0x_data *data, · 7 unmodified lines | ||
| 50 | 109 | if (ret < 0) |
| 51 | 110 | return ret; |
| 52 | 111 | |
| 53 | − do { | |
| 54 | − ret = i2c_smbus_read_byte_data(client, | |
| 55 | − VL_REG_RESULT_RANGE_STATUS); | |
| 112 | + if (data->client->irq) { | |
| 113 | + reinit_completion(&data->completion); | |
| 114 | + | |
| 115 | + ret = wait_for_completion_timeout(&data->completion, HZ/10); | |
| 56 | 116 | if (ret < 0) |
| 57 | 117 | return ret; |
| 118 | + else if (ret == 0) | |
| 119 | + return -ETIMEDOUT; | |
| 58 | 120 | |
| 59 | − if (ret & VL_REG_RESULT_RANGE_STATUS_COMPLETE) | |
| 60 | − break; | |
| 121 | + vl53l0x_clear_irq(data); | |
| 122 | + } else { | |
| 123 | + do { | |
| 124 | + ret = i2c_smbus_read_byte_data(client, | |
| 125 | + VL_REG_RESULT_RANGE_STATUS); | |
| 126 | + if (ret < 0) | |
| 127 | + return ret; | |
| 61 | 128 | |
| 62 | − usleep_range(1000, 5000); | |
| 63 | − } while (--tries); | |
| 64 | − if (!tries) | |
| 65 | − return -ETIMEDOUT; | |
| 129 | + if (ret & VL_REG_RESULT_RANGE_STATUS_COMPLETE) | |
| 130 | + break; | |
| 131 | + | |
| 132 | + usleep_range(1000, 5000); | |
| 133 | + } while (--tries); | |
| 134 | + if (!tries) | |
| 135 | + return -ETIMEDOUT; | |
| 136 | + } | |
| 66 | 137 | |
| 67 | 138 | ret = i2c_smbus_read_i2c_block_data(client, VL_REG_RESULT_RANGE_STATUS, |
| 68 | 139 | 12, buffer); |
| @@ -140,6 +211,17 @@ static int vl53l0x_probe(struct i2c_client *client) · 71 unmodified lines | ||
| 140 | 211 | indio_dev->num_channels = ARRAY_SIZE(vl53l0x_channels); |
| 141 | 212 | indio_dev->modes = INDIO_DIRECT_MODE; |
| 142 | 213 | |
| 214 | + /* usage of interrupt is optional */ | |
| 215 | + if (client->irq) { | |
| 216 | + int ret; | |
| 217 | + | |
| 218 | + init_completion(&data->completion); | |
| 219 | + | |
| 220 | + ret = vl53l0x_configure_irq(client, indio_dev); | |
| 221 | + if (ret) | |
| 222 | + return ret; | |
| 223 | + } | |
| 224 | + | |
| 143 | 225 | return devm_iio_device_register(&client->dev, indio_dev); |
| 144 | 226 | } |
| 145 | 227 | |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <linux/device.h> |
| 13 | 13 | #include <linux/gpio/consumer.h> |
| 14 | 14 | #include <linux/module.h> |
| 15 | +#include <linux/mod_devicetable.h> | |
| 15 | 16 | #include <linux/mutex.h> |
| 16 | 17 | #include <linux/spi/spi.h> |
| 17 | 18 | #include <linux/sysfs.h> |
| @@ -192,7 +193,7 @@ MODULE_DEVICE_TABLE(spi, ad2s1200_id); · 174 unmodified lines | ||
| 192 | 193 | static struct spi_driver ad2s1200_driver = { |
| 193 | 194 | .driver = { |
| 194 | 195 | .name = DRV_NAME, |
| 195 | − .of_match_table = of_match_ptr(ad2s1200_of_match), | |
| 196 | + .of_match_table = ad2s1200_of_match, | |
| 196 | 197 | }, |
| 197 | 198 | .probe = ad2s1200_probe, |
| 198 | 199 | .id_table = ad2s1200_id, |
| @@ -1285,18 +1285,20 @@ static int ltc2983_parse_dt(struct ltc2983_data *st) · 1284 unmodified lines | ||
| 1285 | 1285 | ret = of_property_read_u32(child, "reg", &sensor.chan); |
| 1286 | 1286 | if (ret) { |
| 1287 | 1287 | dev_err(dev, "reg property must given for child nodes\n"); |
| 1288 | − return ret; | |
| 1288 | + goto put_child; | |
| 1289 | 1289 | } |
| 1290 | 1290 | |
| 1291 | 1291 | /* check if we have a valid channel */ |
| 1292 | 1292 | if (sensor.chan < LTC2983_MIN_CHANNELS_NR || |
| 1293 | 1293 | sensor.chan > LTC2983_MAX_CHANNELS_NR) { |
| 1294 | + ret = -EINVAL; | |
| 1294 | 1295 | dev_err(dev, |
| 1295 | 1296 | "chan:%d must be from 1 to 20\n", sensor.chan); |
| 1296 | − return -EINVAL; | |
| 1297 | + goto put_child; | |
| 1297 | 1298 | } else if (channel_avail_mask & BIT(sensor.chan)) { |
| 1299 | + ret = -EINVAL; | |
| 1298 | 1300 | dev_err(dev, "chan:%d already in use\n", sensor.chan); |
| 1299 | − return -EINVAL; | |
| 1301 | + goto put_child; | |
| 1300 | 1302 | } |
| 1301 | 1303 | |
| 1302 | 1304 | ret = of_property_read_u32(child, "adi,sensor-type", |
| @@ -1304,7 +1306,7 @@ static int ltc2983_parse_dt(struct ltc2983_data *st) · 1 unmodified line | ||
| 1304 | 1306 | if (ret) { |
| 1305 | 1307 | dev_err(dev, |
| 1306 | 1308 | "adi,sensor-type property must given for child nodes\n"); |
| 1307 | − return ret; | |
| 1309 | + goto put_child; | |
| 1308 | 1310 | } |
| 1309 | 1311 | |
| 1310 | 1312 | dev_dbg(dev, "Create new sensor, type %u, chann %u", |
| @@ -1334,13 +1336,15 @@ static int ltc2983_parse_dt(struct ltc2983_data *st) · 23 unmodified lines | ||
| 1334 | 1336 | st->sensors[chan] = ltc2983_adc_new(child, st, &sensor); |
| 1335 | 1337 | } else { |
| 1336 | 1338 | dev_err(dev, "Unknown sensor type %d\n", sensor.type); |
| 1337 | − return -EINVAL; | |
| 1339 | + ret = -EINVAL; | |
| 1340 | + goto put_child; | |
| 1338 | 1341 | } |
| 1339 | 1342 | |
| 1340 | 1343 | if (IS_ERR(st->sensors[chan])) { |
| 1341 | 1344 | dev_err(dev, "Failed to create sensor %ld", |
| 1342 | 1345 | PTR_ERR(st->sensors[chan])); |
| 1343 | − return PTR_ERR(st->sensors[chan]); | |
| 1346 | + ret = PTR_ERR(st->sensors[chan]); | |
| 1347 | + goto put_child; | |
| 1344 | 1348 | } |
| 1345 | 1349 | /* set generic sensor parameters */ |
| 1346 | 1350 | st->sensors[chan]->chan = sensor.chan; |
| @@ -1351,6 +1355,9 @@ static int ltc2983_parse_dt(struct ltc2983_data *st) · 4 unmodified lines | ||
| 1351 | 1355 | } |
| 1352 | 1356 | |
| 1353 | 1357 | return 0; |
| 1358 | +put_child: | |
| 1359 | + of_node_put(child); | |
| 1360 | + return ret; | |
| 1354 | 1361 | } |
| 1355 | 1362 | |
| 1356 | 1363 | static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio) |
| @@ -10,7 +10,9 @@ · 9 unmodified lines | ||
| 10 | 10 | #include <linux/err.h> |
| 11 | 11 | #include <linux/gpio/consumer.h> |
| 12 | 12 | #include <linux/i2c.h> |
| 13 | +#include <linux/iopoll.h> | |
| 13 | 14 | #include <linux/kernel.h> |
| 15 | +#include <linux/limits.h> | |
| 14 | 16 | #include <linux/module.h> |
| 15 | 17 | #include <linux/math64.h> |
| 16 | 18 | #include <linux/of.h> |
| @@ -58,6 +60,8 @@ · 41 unmodified lines | ||
| 58 | 60 | /* Control register address - volatile */ |
| 59 | 61 | #define MLX90632_REG_CONTROL 0x3001 /* Control Register address */ |
| 60 | 62 | #define MLX90632_CFG_PWR_MASK GENMASK(2, 1) /* PowerMode Mask */ |
| 63 | +#define MLX90632_CFG_MTYP_MASK GENMASK(8, 4) /* Meas select Mask */ | |
| 64 | + | |
| 61 | 65 | /* PowerModes statuses */ |
| 62 | 66 | #define MLX90632_PWR_STATUS(ctrl_val) (ctrl_val << 1) |
| 63 | 67 | #define MLX90632_PWR_STATUS_HALT MLX90632_PWR_STATUS(0) /* hold */ |
| @@ -65,6 +69,18 @@ · 1 unmodified line | ||
| 65 | 69 | #define MLX90632_PWR_STATUS_STEP MLX90632_PWR_STATUS(2) /* step */ |
| 66 | 70 | #define MLX90632_PWR_STATUS_CONTINUOUS MLX90632_PWR_STATUS(3) /* continuous*/ |
| 67 | 71 | |
| 72 | +/* Measurement types */ | |
| 73 | +#define MLX90632_MTYP_MEDICAL 0 | |
| 74 | +#define MLX90632_MTYP_EXTENDED 17 | |
| 75 | + | |
| 76 | +/* Measurement type select*/ | |
| 77 | +#define MLX90632_MTYP_STATUS(ctrl_val) (ctrl_val << 4) | |
| 78 | +#define MLX90632_MTYP_STATUS_MEDICAL MLX90632_MTYP_STATUS(MLX90632_MTYP_MEDICAL) | |
| 79 | +#define MLX90632_MTYP_STATUS_EXTENDED MLX90632_MTYP_STATUS(MLX90632_MTYP_EXTENDED) | |
| 80 | + | |
| 81 | +/* I2C command register - volatile */ | |
| 82 | +#define MLX90632_REG_I2C_CMD 0x3005 /* I2C command Register address */ | |
| 83 | + | |
| 68 | 84 | /* Device status register - volatile */ |
| 69 | 85 | #define MLX90632_REG_STATUS 0x3fff /* Device status register */ |
| 70 | 86 | #define MLX90632_STAT_BUSY BIT(10) /* Device busy indicator */ |
| @@ -78,26 +94,53 @@ · 7 unmodified lines | ||
| 78 | 94 | #define MLX90632_RAM_2(meas_num) (MLX90632_ADDR_RAM + 3 * meas_num + 1) |
| 79 | 95 | #define MLX90632_RAM_3(meas_num) (MLX90632_ADDR_RAM + 3 * meas_num + 2) |
| 80 | 96 | |
| 97 | +/* Name important RAM_MEAS channels */ | |
| 98 | +#define MLX90632_RAM_DSP5_EXTENDED_AMBIENT_1 MLX90632_RAM_3(17) | |
| 99 | +#define MLX90632_RAM_DSP5_EXTENDED_AMBIENT_2 MLX90632_RAM_3(18) | |
| 100 | +#define MLX90632_RAM_DSP5_EXTENDED_OBJECT_1 MLX90632_RAM_1(17) | |
| 101 | +#define MLX90632_RAM_DSP5_EXTENDED_OBJECT_2 MLX90632_RAM_2(17) | |
| 102 | +#define MLX90632_RAM_DSP5_EXTENDED_OBJECT_3 MLX90632_RAM_1(18) | |
| 103 | +#define MLX90632_RAM_DSP5_EXTENDED_OBJECT_4 MLX90632_RAM_2(18) | |
| 104 | +#define MLX90632_RAM_DSP5_EXTENDED_OBJECT_5 MLX90632_RAM_1(19) | |
| 105 | +#define MLX90632_RAM_DSP5_EXTENDED_OBJECT_6 MLX90632_RAM_2(19) | |
| 106 | + | |
| 81 | 107 | /* Magic constants */ |
| 82 | 108 | #define MLX90632_ID_MEDICAL 0x0105 /* EEPROM DSPv5 Medical device id */ |
| 83 | 109 | #define MLX90632_ID_CONSUMER 0x0205 /* EEPROM DSPv5 Consumer device id */ |
| 110 | +#define MLX90632_ID_EXTENDED 0x0505 /* EEPROM DSPv5 Extended range device id */ | |
| 111 | +#define MLX90632_ID_MASK GENMASK(14, 0) /* DSP version and device ID in EE_VERSION */ | |
| 84 | 112 | #define MLX90632_DSP_VERSION 5 /* DSP version */ |
| 85 | 113 | #define MLX90632_DSP_MASK GENMASK(7, 0) /* DSP version in EE_VERSION */ |
| 86 | 114 | #define MLX90632_RESET_CMD 0x0006 /* Reset sensor (address or global) */ |
| 87 | −#define MLX90632_REF_12 12LL /**< ResCtrlRef value of Ch 1 or Ch 2 */ | |
| 88 | −#define MLX90632_REF_3 12LL /**< ResCtrlRef value of Channel 3 */ | |
| 89 | −#define MLX90632_MAX_MEAS_NUM 31 /**< Maximum measurements in list */ | |
| 90 | −#define MLX90632_SLEEP_DELAY_MS 3000 /**< Autosleep delay */ | |
| 115 | +#define MLX90632_REF_12 12LL /* ResCtrlRef value of Ch 1 or Ch 2 */ | |
| 116 | +#define MLX90632_REF_3 12LL /* ResCtrlRef value of Channel 3 */ | |
| 117 | +#define MLX90632_MAX_MEAS_NUM 31 /* Maximum measurements in list */ | |
| 118 | +#define MLX90632_SLEEP_DELAY_MS 3000 /* Autosleep delay */ | |
| 119 | +#define MLX90632_EXTENDED_LIMIT 27000 /* Extended mode raw value limit */ | |
| 91 | 120 | |
| 121 | +/** | |
| 122 | + * struct mlx90632_data - private data for the MLX90632 device | |
| 123 | + * @client: I2C client of the device | |
| 124 | + * @lock: Internal mutex for multiple reads for single measurement | |
| 125 | + * @regmap: Regmap of the device | |
| 126 | + * @emissivity: Object emissivity from 0 to 1000 where 1000 = 1. | |
| 127 | + * @mtyp: Measurement type physical sensor configuration for extended range | |
| 128 | + * calculations | |
| 129 | + * @object_ambient_temperature: Ambient temperature at object (might differ of | |
| 130 | + * the ambient temperature of sensor. | |
| 131 | + */ | |
| 92 | 132 | struct mlx90632_data { |
| 93 | 133 | struct i2c_client *client; |
| 94 | − struct mutex lock; /* Multiple reads for single measurement */ | |
| 134 | + struct mutex lock; | |
| 95 | 135 | struct regmap *regmap; |
| 96 | 136 | u16 emissivity; |
| 137 | + u8 mtyp; | |
| 138 | + u32 object_ambient_temperature; | |
| 97 | 139 | }; |
| 98 | 140 | |
| 99 | 141 | static const struct regmap_range mlx90632_volatile_reg_range[] = { |
| 100 | 142 | regmap_reg_range(MLX90632_REG_I2C_ADDR, MLX90632_REG_CONTROL), |
| 143 | + regmap_reg_range(MLX90632_REG_I2C_CMD, MLX90632_REG_I2C_CMD), | |
| 101 | 144 | regmap_reg_range(MLX90632_REG_STATUS, MLX90632_REG_STATUS), |
| 102 | 145 | regmap_reg_range(MLX90632_RAM_1(0), |
| 103 | 146 | MLX90632_RAM_3(MLX90632_MAX_MEAS_NUM)), |
| @@ -113,6 +156,7 @@ static const struct regmap_range mlx90632_read_reg_range[] = { · 9 unmodified lines | ||
| 113 | 156 | regmap_reg_range(MLX90632_EE_CTRL, MLX90632_EE_I2C_ADDR), |
| 114 | 157 | regmap_reg_range(MLX90632_EE_Ha, MLX90632_EE_Hb), |
| 115 | 158 | regmap_reg_range(MLX90632_REG_I2C_ADDR, MLX90632_REG_CONTROL), |
| 159 | + regmap_reg_range(MLX90632_REG_I2C_CMD, MLX90632_REG_I2C_CMD), | |
| 116 | 160 | regmap_reg_range(MLX90632_REG_STATUS, MLX90632_REG_STATUS), |
| 117 | 161 | regmap_reg_range(MLX90632_RAM_1(0), |
| 118 | 162 | MLX90632_RAM_3(MLX90632_MAX_MEAS_NUM)), |
| @@ -173,25 +217,19 @@ static s32 mlx90632_pwr_continuous(struct regmap *regmap) · 54 unmodified lines | ||
| 173 | 217 | */ |
| 174 | 218 | static int mlx90632_perform_measurement(struct mlx90632_data *data) |
| 175 | 219 | { |
| 176 | − int ret, tries = 100; | |
| 177 | 220 | unsigned int reg_status; |
| 221 | + int ret; | |
| 178 | 222 | |
| 179 | 223 | ret = regmap_update_bits(data->regmap, MLX90632_REG_STATUS, |
| 180 | 224 | MLX90632_STAT_DATA_RDY, 0); |
| 181 | 225 | if (ret < 0) |
| 182 | 226 | return ret; |
| 183 | 227 | |
| 184 | − while (tries-- > 0) { | |
| 185 | − ret = regmap_read(data->regmap, MLX90632_REG_STATUS, | |
| 186 | − ®_status); | |
| 187 | − if (ret < 0) | |
| 188 | − return ret; | |
| 189 | − if (reg_status & MLX90632_STAT_DATA_RDY) | |
| 190 | − break; | |
| 191 | − usleep_range(10000, 11000); | |
| 192 | − } | |
| 228 | + ret = regmap_read_poll_timeout(data->regmap, MLX90632_REG_STATUS, reg_status, | |
| 229 | + !(reg_status & MLX90632_STAT_DATA_RDY), 10000, | |
| 230 | + 100 * 10000); | |
| 193 | 231 | |
| 194 | − if (tries < 0) { | |
| 232 | + if (ret < 0) { | |
| 195 | 233 | dev_err(&data->client->dev, "data not ready"); |
| 196 | 234 | return -ETIMEDOUT; |
| 197 | 235 | } |
| @@ -199,6 +237,26 @@ static int mlx90632_perform_measurement(struct mlx90632_data *data) · 1 unmodified line | ||
| 199 | 237 | return (reg_status & MLX90632_STAT_CYCLE_POS) >> 2; |
| 200 | 238 | } |
| 201 | 239 | |
| 240 | +static int mlx90632_set_meas_type(struct regmap *regmap, u8 type) | |
| 241 | +{ | |
| 242 | + int ret; | |
| 243 | + | |
| 244 | + if ((type != MLX90632_MTYP_MEDICAL) && (type != MLX90632_MTYP_EXTENDED)) | |
| 245 | + return -EINVAL; | |
| 246 | + | |
| 247 | + ret = regmap_write(regmap, MLX90632_REG_I2C_CMD, MLX90632_RESET_CMD); | |
| 248 | + if (ret < 0) | |
| 249 | + return ret; | |
| 250 | + | |
| 251 | + ret = regmap_write_bits(regmap, MLX90632_REG_CONTROL, | |
| 252 | + (MLX90632_CFG_MTYP_MASK | MLX90632_CFG_PWR_MASK), | |
| 253 | + (MLX90632_MTYP_STATUS(type) | MLX90632_PWR_STATUS_HALT)); | |
| 254 | + if (ret < 0) | |
| 255 | + return ret; | |
| 256 | + | |
| 257 | + return mlx90632_pwr_continuous(regmap); | |
| 258 | +} | |
| 259 | + | |
| 202 | 260 | static int mlx90632_channel_new_select(int perform_ret, uint8_t *channel_new, |
| 203 | 261 | uint8_t *channel_old) |
| 204 | 262 | { |
| @@ -300,6 +358,97 @@ read_unlock: · 95 unmodified lines | ||
| 300 | 358 | return ret; |
| 301 | 359 | } |
| 302 | 360 | |
| 361 | +static int mlx90632_read_ambient_raw_extended(struct regmap *regmap, | |
| 362 | + s16 *ambient_new_raw, s16 *ambient_old_raw) | |
| 363 | +{ | |
| 364 | + unsigned int read_tmp; | |
| 365 | + int ret; | |
| 366 | + | |
| 367 | + ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_AMBIENT_1, &read_tmp); | |
| 368 | + if (ret < 0) | |
| 369 | + return ret; | |
| 370 | + *ambient_new_raw = (s16)read_tmp; | |
| 371 | + | |
| 372 | + ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_AMBIENT_2, &read_tmp); | |
| 373 | + if (ret < 0) | |
| 374 | + return ret; | |
| 375 | + *ambient_old_raw = (s16)read_tmp; | |
| 376 | + | |
| 377 | + return 0; | |
| 378 | +} | |
| 379 | + | |
| 380 | +static int mlx90632_read_object_raw_extended(struct regmap *regmap, s16 *object_new_raw) | |
| 381 | +{ | |
| 382 | + unsigned int read_tmp; | |
| 383 | + s32 read; | |
| 384 | + int ret; | |
| 385 | + | |
| 386 | + ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_OBJECT_1, &read_tmp); | |
| 387 | + if (ret < 0) | |
| 388 | + return ret; | |
| 389 | + read = (s16)read_tmp; | |
| 390 | + | |
| 391 | + ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_OBJECT_2, &read_tmp); | |
| 392 | + if (ret < 0) | |
| 393 | + return ret; | |
| 394 | + read = read - (s16)read_tmp; | |
| 395 | + | |
| 396 | + ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_OBJECT_3, &read_tmp); | |
| 397 | + if (ret < 0) | |
| 398 | + return ret; | |
| 399 | + read = read - (s16)read_tmp; | |
| 400 | + | |
| 401 | + ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_OBJECT_4, &read_tmp); | |
| 402 | + if (ret < 0) | |
| 403 | + return ret; | |
| 404 | + read = (read + (s16)read_tmp) / 2; | |
| 405 | + | |
| 406 | + ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_OBJECT_5, &read_tmp); | |
| 407 | + if (ret < 0) | |
| 408 | + return ret; | |
| 409 | + read = read + (s16)read_tmp; | |
| 410 | + | |
| 411 | + ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_OBJECT_6, &read_tmp); | |
| 412 | + if (ret < 0) | |
| 413 | + return ret; | |
| 414 | + read = read + (s16)read_tmp; | |
| 415 | + | |
| 416 | + if (read > S16_MAX || read < S16_MIN) | |
| 417 | + return -ERANGE; | |
| 418 | + | |
| 419 | + *object_new_raw = read; | |
| 420 | + | |
| 421 | + return 0; | |
| 422 | +} | |
| 423 | + | |
| 424 | +static int mlx90632_read_all_channel_extended(struct mlx90632_data *data, s16 *object_new_raw, | |
| 425 | + s16 *ambient_new_raw, s16 *ambient_old_raw) | |
| 426 | +{ | |
| 427 | + s32 ret, meas; | |
| 428 | + | |
| 429 | + mutex_lock(&data->lock); | |
| 430 | + ret = mlx90632_set_meas_type(data->regmap, MLX90632_MTYP_EXTENDED); | |
| 431 | + if (ret < 0) | |
| 432 | + goto read_unlock; | |
| 433 | + | |
| 434 | + ret = read_poll_timeout(mlx90632_perform_measurement, meas, meas == 19, | |
| 435 | + 50000, 800000, false, data); | |
| 436 | + if (ret != 0) | |
| 437 | + goto read_unlock; | |
| 438 | + | |
| 439 | + ret = mlx90632_read_object_raw_extended(data->regmap, object_new_raw); | |
| 440 | + if (ret < 0) | |
| 441 | + goto read_unlock; | |
| 442 | + | |
| 443 | + ret = mlx90632_read_ambient_raw_extended(data->regmap, ambient_new_raw, ambient_old_raw); | |
| 444 | + | |
| 445 | +read_unlock: | |
| 446 | + (void) mlx90632_set_meas_type(data->regmap, MLX90632_MTYP_MEDICAL); | |
| 447 | + | |
| 448 | + mutex_unlock(&data->lock); | |
| 449 | + return ret; | |
| 450 | +} | |
| 451 | + | |
| 303 | 452 | static int mlx90632_read_ee_register(struct regmap *regmap, u16 reg_lsb, |
| 304 | 453 | s32 *reg_value) |
| 305 | 454 | { |
| @@ -354,9 +503,23 @@ static s64 mlx90632_preprocess_temp_obj(s16 object_new_raw, s16 object_old_raw, · 48 unmodified lines | ||
| 354 | 503 | return div64_s64((tmp << 19ULL), 1000LL); |
| 355 | 504 | } |
| 356 | 505 | |
| 506 | +static s64 mlx90632_preprocess_temp_obj_extended(s16 object_new_raw, s16 ambient_new_raw, | |
| 507 | + s16 ambient_old_raw, s16 Ka) | |
| 508 | +{ | |
| 509 | + s64 VR_IR, kKa, tmp; | |
| 510 | + | |
| 511 | + kKa = ((s64)Ka * 1000LL) >> 10ULL; | |
| 512 | + VR_IR = (s64)ambient_old_raw * 1000000LL + | |
| 513 | + kKa * div64_s64((s64)ambient_new_raw * 1000LL, | |
| 514 | + MLX90632_REF_3); | |
| 515 | + tmp = div64_s64( | |
| 516 | + div64_s64((s64) object_new_raw * 1000000000000LL, MLX90632_REF_12), | |
| 517 | + VR_IR); | |
| 518 | + return div64_s64(tmp << 19ULL, 1000LL); | |
| 519 | +} | |
| 520 | + | |
| 357 | 521 | static s32 mlx90632_calc_temp_ambient(s16 ambient_new_raw, s16 ambient_old_raw, |
| 358 | − s32 P_T, s32 P_R, s32 P_G, s32 P_O, | |
| 359 | − s16 Gb) | |
| 522 | + s32 P_T, s32 P_R, s32 P_G, s32 P_O, s16 Gb) | |
| 360 | 523 | { |
| 361 | 524 | s64 Asub, Bsub, Ablock, Bblock, Cblock, AMB, sum; |
| 362 | 525 | |
| @@ -374,11 +537,11 @@ static s32 mlx90632_calc_temp_ambient(s16 ambient_new_raw, s16 ambient_old_raw, · 11 unmodified lines | ||
| 374 | 537 | } |
| 375 | 538 | |
| 376 | 539 | static s32 mlx90632_calc_temp_object_iteration(s32 prev_object_temp, s64 object, |
| 377 | − s64 TAdut, s32 Fa, s32 Fb, | |
| 540 | + s64 TAdut, s64 TAdut4, s32 Fa, s32 Fb, | |
| 378 | 541 | s32 Ga, s16 Ha, s16 Hb, |
| 379 | 542 | u16 emissivity) |
| 380 | 543 | { |
| 381 | − s64 calcedKsTO, calcedKsTA, ir_Alpha, TAdut4, Alpha_corr; | |
| 544 | + s64 calcedKsTO, calcedKsTA, ir_Alpha, Alpha_corr; | |
| 382 | 545 | s64 Ha_customer, Hb_customer; |
| 383 | 546 | |
| 384 | 547 | Ha_customer = ((s64)Ha * 1000000LL) >> 14ULL; |
| @@ -393,36 +556,66 @@ static s32 mlx90632_calc_temp_object_iteration(s32 prev_object_temp, s64 object, · 8 unmodified lines | ||
| 393 | 556 | Alpha_corr = emissivity * div64_s64(Alpha_corr, 100000LL); |
| 394 | 557 | Alpha_corr = div64_s64(Alpha_corr, 1000LL); |
| 395 | 558 | ir_Alpha = div64_s64((s64)object * 10000000LL, Alpha_corr); |
| 396 | − TAdut4 = (div64_s64(TAdut, 10000LL) + 27315) * | |
| 397 | − (div64_s64(TAdut, 10000LL) + 27315) * | |
| 398 | − (div64_s64(TAdut, 10000LL) + 27315) * | |
| 399 | − (div64_s64(TAdut, 10000LL) + 27315); | |
| 400 | 559 | |
| 401 | 560 | return (int_sqrt64(int_sqrt64(ir_Alpha * 1000000000000LL + TAdut4)) |
| 402 | 561 | - 27315 - Hb_customer) * 10; |
| 403 | 562 | } |
| 404 | 563 | |
| 564 | +static s64 mlx90632_calc_ta4(s64 TAdut, s64 scale) | |
| 565 | +{ | |
| 566 | + return (div64_s64(TAdut, scale) + 27315) * | |
| 567 | + (div64_s64(TAdut, scale) + 27315) * | |
| 568 | + (div64_s64(TAdut, scale) + 27315) * | |
| 569 | + (div64_s64(TAdut, scale) + 27315); | |
| 570 | +} | |
| 571 | + | |
| 405 | 572 | static s32 mlx90632_calc_temp_object(s64 object, s64 ambient, s32 Ea, s32 Eb, |
| 406 | 573 | s32 Fa, s32 Fb, s32 Ga, s16 Ha, s16 Hb, |
| 407 | 574 | u16 tmp_emi) |
| 408 | 575 | { |
| 409 | − s64 kTA, kTA0, TAdut; | |
| 576 | + s64 kTA, kTA0, TAdut, TAdut4; | |
| 410 | 577 | s64 temp = 25000; |
| 411 | 578 | s8 i; |
| 412 | 579 | |
| 413 | 580 | kTA = (Ea * 1000LL) >> 16LL; |
| 414 | 581 | kTA0 = (Eb * 1000LL) >> 8LL; |
| 415 | 582 | TAdut = div64_s64(((ambient - kTA0) * 1000000LL), kTA) + 25 * 1000000LL; |
| 583 | + TAdut4 = mlx90632_calc_ta4(TAdut, 10000LL); | |
| 416 | 584 | |
| 417 | 585 | /* Iterations of calculation as described in datasheet */ |
| 418 | 586 | for (i = 0; i < 5; ++i) { |
| 419 | − temp = mlx90632_calc_temp_object_iteration(temp, object, TAdut, | |
| 587 | + temp = mlx90632_calc_temp_object_iteration(temp, object, TAdut, TAdut4, | |
| 420 | 588 | Fa, Fb, Ga, Ha, Hb, |
| 421 | 589 | tmp_emi); |
| 422 | 590 | } |
| 423 | 591 | return temp; |
| 424 | 592 | } |
| 425 | 593 | |
| 594 | +static s32 mlx90632_calc_temp_object_extended(s64 object, s64 ambient, s64 reflected, | |
| 595 | + s32 Ea, s32 Eb, s32 Fa, s32 Fb, s32 Ga, | |
| 596 | + s16 Ha, s16 Hb, u16 tmp_emi) | |
| 597 | +{ | |
| 598 | + s64 kTA, kTA0, TAdut, TAdut4, Tr4, TaTr4; | |
| 599 | + s64 temp = 25000; | |
| 600 | + s8 i; | |
| 601 | + | |
| 602 | + kTA = (Ea * 1000LL) >> 16LL; | |
| 603 | + kTA0 = (Eb * 1000LL) >> 8LL; | |
| 604 | + TAdut = div64_s64((ambient - kTA0) * 1000000LL, kTA) + 25 * 1000000LL; | |
| 605 | + Tr4 = mlx90632_calc_ta4(reflected, 10); | |
| 606 | + TAdut4 = mlx90632_calc_ta4(TAdut, 10000LL); | |
| 607 | + TaTr4 = Tr4 - div64_s64(Tr4 - TAdut4, tmp_emi) * 1000; | |
| 608 | + | |
| 609 | + /* Iterations of calculation as described in datasheet */ | |
| 610 | + for (i = 0; i < 5; ++i) { | |
| 611 | + temp = mlx90632_calc_temp_object_iteration(temp, object, TAdut, TaTr4, | |
| 612 | + Fa / 2, Fb, Ga, Ha, Hb, | |
| 613 | + tmp_emi); | |
| 614 | + } | |
| 615 | + | |
| 616 | + return temp; | |
| 617 | +} | |
| 618 | + | |
| 426 | 619 | static int mlx90632_calc_object_dsp105(struct mlx90632_data *data, int *val) |
| 427 | 620 | { |
| 428 | 621 | s32 ret; |
| @@ -470,6 +663,26 @@ static int mlx90632_calc_object_dsp105(struct mlx90632_data *data, int *val) · 41 unmodified lines | ||
| 470 | 663 | if (ret < 0) |
| 471 | 664 | return ret; |
| 472 | 665 | |
| 666 | + if (object_new_raw > MLX90632_EXTENDED_LIMIT && | |
| 667 | + data->mtyp == MLX90632_MTYP_EXTENDED) { | |
| 668 | + ret = mlx90632_read_all_channel_extended(data, &object_new_raw, | |
| 669 | + &ambient_new_raw, &ambient_old_raw); | |
| 670 | + if (ret < 0) | |
| 671 | + return ret; | |
| 672 | + | |
| 673 | + /* Use extended mode calculations */ | |
| 674 | + ambient = mlx90632_preprocess_temp_amb(ambient_new_raw, | |
| 675 | + ambient_old_raw, Gb); | |
| 676 | + object = mlx90632_preprocess_temp_obj_extended(object_new_raw, | |
| 677 | + ambient_new_raw, | |
| 678 | + ambient_old_raw, Ka); | |
| 679 | + *val = mlx90632_calc_temp_object_extended(object, ambient, | |
| 680 | + data->object_ambient_temperature, | |
| 681 | + Ea, Eb, Fa, Fb, Ga, | |
| 682 | + Ha, Hb, data->emissivity); | |
| 683 | + return 0; | |
| 684 | + } | |
| 685 | + | |
| 473 | 686 | ambient = mlx90632_preprocess_temp_amb(ambient_new_raw, |
| 474 | 687 | ambient_old_raw, Gb); |
| 475 | 688 | object = mlx90632_preprocess_temp_obj(object_new_raw, |
| @@ -548,7 +761,9 @@ static int mlx90632_read_raw(struct iio_dev *indio_dev, · 72 unmodified lines | ||
| 548 | 761 | *val2 = data->emissivity * 1000; |
| 549 | 762 | } |
| 550 | 763 | return IIO_VAL_INT_PLUS_MICRO; |
| 551 | − | |
| 764 | + case IIO_CHAN_INFO_CALIBAMBIENT: | |
| 765 | + *val = data->object_ambient_temperature; | |
| 766 | + return IIO_VAL_INT; | |
| 552 | 767 | default: |
| 553 | 768 | return -EINVAL; |
| 554 | 769 | } |
| @@ -568,6 +783,9 @@ static int mlx90632_write_raw(struct iio_dev *indio_dev, · 13 unmodified lines | ||
| 568 | 783 | return -EINVAL; |
| 569 | 784 | data->emissivity = val * 1000 + val2 / 1000; |
| 570 | 785 | return 0; |
| 786 | + case IIO_CHAN_INFO_CALIBAMBIENT: | |
| 787 | + data->object_ambient_temperature = val; | |
| 788 | + return 0; | |
| 571 | 789 | default: |
| 572 | 790 | return -EINVAL; |
| 573 | 791 | } |
| @@ -585,7 +803,7 @@ static const struct iio_chan_spec mlx90632_channels[] = { · 11 unmodified lines | ||
| 585 | 803 | .modified = 1, |
| 586 | 804 | .channel2 = IIO_MOD_TEMP_OBJECT, |
| 587 | 805 | .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | |
| 588 | − BIT(IIO_CHAN_INFO_CALIBEMISSIVITY), | |
| 806 | + BIT(IIO_CHAN_INFO_CALIBEMISSIVITY) | BIT(IIO_CHAN_INFO_CALIBAMBIENT), | |
| 589 | 807 | }, |
| 590 | 808 | }; |
| 591 | 809 | |
| @@ -643,6 +861,7 @@ static int mlx90632_probe(struct i2c_client *client, · 51 unmodified lines | ||
| 643 | 861 | i2c_set_clientdata(client, indio_dev); |
| 644 | 862 | mlx90632->client = client; |
| 645 | 863 | mlx90632->regmap = regmap; |
| 864 | + mlx90632->mtyp = MLX90632_MTYP_MEDICAL; | |
| 646 | 865 | |
| 647 | 866 | mutex_init(&mlx90632->lock); |
| 648 | 867 | indio_dev->name = id->name; |
| @@ -662,15 +881,20 @@ static int mlx90632_probe(struct i2c_client *client, · 13 unmodified lines | ||
| 662 | 881 | dev_err(&client->dev, "read of version failed: %d\n", ret); |
| 663 | 882 | return ret; |
| 664 | 883 | } |
| 884 | + read = read & MLX90632_ID_MASK; | |
| 665 | 885 | if (read == MLX90632_ID_MEDICAL) { |
| 666 | 886 | dev_dbg(&client->dev, |
| 667 | 887 | "Detected Medical EEPROM calibration %x\n", read); |
| 668 | 888 | } else if (read == MLX90632_ID_CONSUMER) { |
| 669 | 889 | dev_dbg(&client->dev, |
| 670 | 890 | "Detected Consumer EEPROM calibration %x\n", read); |
| 891 | + } else if (read == MLX90632_ID_EXTENDED) { | |
| 892 | + dev_dbg(&client->dev, | |
| 893 | + "Detected Extended range EEPROM calibration %x\n", read); | |
| 894 | + mlx90632->mtyp = MLX90632_MTYP_EXTENDED; | |
| 671 | 895 | } else if ((read & MLX90632_DSP_MASK) == MLX90632_DSP_VERSION) { |
| 672 | 896 | dev_dbg(&client->dev, |
| 673 | − "Detected Unknown EEPROM calibration %x\n", read); | |
| 897 | + "Detected Unknown EEPROM calibration %x\n", read); | |
| 674 | 898 | } else { |
| 675 | 899 | dev_err(&client->dev, |
| 676 | 900 | "Wrong DSP version %x (expected %x)\n", |
| @@ -679,6 +903,7 @@ static int mlx90632_probe(struct i2c_client *client, · 2 unmodified lines | ||
| 679 | 903 | } |
| 680 | 904 | |
| 681 | 905 | mlx90632->emissivity = 1000; |
| 906 | + mlx90632->object_ambient_temperature = 25000; /* 25 degrees milliCelsius */ | |
| 682 | 907 | |
| 683 | 908 | pm_runtime_disable(&client->dev); |
| 684 | 909 | ret = pm_runtime_set_active(&client->dev); |
| @@ -20,7 +20,7 @@ · 19 unmodified lines | ||
| 20 | 20 | #include <linux/module.h> |
| 21 | 21 | #include <linux/pm.h> |
| 22 | 22 | #include <linux/bitops.h> |
| 23 | −#include <linux/of.h> | |
| 23 | +#include <linux/mod_devicetable.h> | |
| 24 | 24 | #include <linux/irq.h> |
| 25 | 25 | #include <linux/interrupt.h> |
| 26 | 26 | |
| @@ -578,7 +578,7 @@ MODULE_DEVICE_TABLE(i2c, tmp007_id); · 551 unmodified lines | ||
| 578 | 578 | static struct i2c_driver tmp007_driver = { |
| 579 | 579 | .driver = { |
| 580 | 580 | .name = "tmp007", |
| 581 | − .of_match_table = of_match_ptr(tmp007_of_match), | |
| 581 | + .of_match_table = tmp007_of_match, | |
| 582 | 582 | .pm = &tmp007_pm_ops, |
| 583 | 583 | }, |
| 584 | 584 | .probe = tmp007_probe, |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <linux/device.h> |
| 14 | 14 | #include <linux/mutex.h> |
| 15 | 15 | #include <linux/module.h> |
| 16 | +#include <linux/mod_devicetable.h> | |
| 16 | 17 | #include <linux/init.h> |
| 17 | 18 | #include <linux/kernel.h> |
| 18 | 19 | #include <linux/stat.h> |
| @@ -222,7 +223,7 @@ static struct i2c_driver tsys01_driver = { · 203 unmodified lines | ||
| 222 | 223 | .id_table = tsys01_id, |
| 223 | 224 | .driver = { |
| 224 | 225 | .name = "tsys01", |
| 225 | − .of_match_table = of_match_ptr(tsys01_of_match), | |
| 226 | + .of_match_table = tsys01_of_match, | |
| 226 | 227 | }, |
| 227 | 228 | }; |
| 228 | 229 | |
| @@ -23,4 +23,13 @@ config MOST_USB_HDM · 22 unmodified lines | ||
| 23 | 23 | |
| 24 | 24 | To compile this driver as a module, choose M here: the |
| 25 | 25 | module will be called most_usb. |
| 26 | + | |
| 27 | +config MOST_CDEV | |
| 28 | + tristate "Cdev" | |
| 29 | + | |
| 30 | + help | |
| 31 | + Say Y here if you want to commumicate via character devices. | |
| 32 | + | |
| 33 | + To compile this driver as a module, choose M here: the | |
| 34 | + module will be called most_cdev. | |
| 26 | 35 | endif |
| @@ -4,3 +4,4 @@ most_core-y := core.o \ · 3 unmodified lines | ||
| 4 | 4 | configfs.o |
| 5 | 5 | |
| 6 | 6 | obj-$(CONFIG_MOST_USB_HDM) += most_usb.o |
| 7 | +obj-$(CONFIG_MOST_CDEV) += most_cdev.o | |
File renamed without changes.
| @@ -112,9 +112,10 @@ static int wilc_bus_probe(struct spi_device *spi) · 111 unmodified lines | ||
| 112 | 112 | wilc->dev_irq_num = spi->irq; |
| 113 | 113 | |
| 114 | 114 | wilc->rtc_clk = devm_clk_get(&spi->dev, "rtc_clk"); |
| 115 | − if (PTR_ERR_OR_ZERO(wilc->rtc_clk) == -EPROBE_DEFER) | |
| 115 | + if (PTR_ERR_OR_ZERO(wilc->rtc_clk) == -EPROBE_DEFER) { | |
| 116 | + kfree(spi_priv); | |
| 116 | 117 | return -EPROBE_DEFER; |
| 117 | − else if (!IS_ERR(wilc->rtc_clk)) | |
| 118 | + } else if (!IS_ERR(wilc->rtc_clk)) | |
| 118 | 119 | clk_prepare_enable(wilc->rtc_clk); |
| 119 | 120 | |
| 120 | 121 | return 0; |
| @@ -116,4 +116,6 @@ source "drivers/staging/qlge/Kconfig" · 115 unmodified lines | ||
| 116 | 116 | |
| 117 | 117 | source "drivers/staging/wfx/Kconfig" |
| 118 | 118 | |
| 119 | +source "drivers/staging/hikey9xx/Kconfig" | |
| 120 | + | |
| 119 | 121 | endif # STAGING |
| @@ -48,3 +48,4 @@ obj-$(CONFIG_FIELDBUS_DEV) += fieldbus/ · 47 unmodified lines | ||
| 48 | 48 | obj-$(CONFIG_KPC2000) += kpc2000/ |
| 49 | 49 | obj-$(CONFIG_QLGE) += qlge/ |
| 50 | 50 | obj-$(CONFIG_WFX) += wfx/ |
| 51 | +obj-y += hikey9xx/ | |
| @@ -205,8 +205,8 @@ static int ion_dma_buf_attach(struct dma_buf *dmabuf, · 204 unmodified lines | ||
| 205 | 205 | return 0; |
| 206 | 206 | } |
| 207 | 207 | |
| 208 | −static void ion_dma_buf_detatch(struct dma_buf *dmabuf, | |
| 209 | − struct dma_buf_attachment *attachment) | |
| 208 | +static void ion_dma_buf_detach(struct dma_buf *dmabuf, | |
| 209 | + struct dma_buf_attachment *attachment) | |
| 210 | 210 | { |
| 211 | 211 | struct ion_dma_buf_attachment *a = attachment->priv; |
| 212 | 212 | struct ion_buffer *buffer = dmabuf->priv; |
| @@ -331,7 +331,7 @@ static const struct dma_buf_ops dma_buf_ops = { · 118 unmodified lines | ||
| 331 | 331 | .mmap = ion_mmap, |
| 332 | 332 | .release = ion_dma_buf_release, |
| 333 | 333 | .attach = ion_dma_buf_attach, |
| 334 | − .detach = ion_dma_buf_detatch, | |
| 334 | + .detach = ion_dma_buf_detach, | |
| 335 | 335 | .begin_cpu_access = ion_dma_buf_begin_cpu_access, |
| 336 | 336 | .end_cpu_access = ion_dma_buf_end_cpu_access, |
| 337 | 337 | }; |
| @@ -680,7 +680,7 @@ struct comedi_rangeinfo { · 679 unmodified lines | ||
| 680 | 680 | * value of 1 volt. |
| 681 | 681 | * |
| 682 | 682 | * The only defined flag value is %RF_EXTERNAL (%0x100), indicating that the |
| 683 | − * the range needs to be multiplied by an external reference. | |
| 683 | + * range needs to be multiplied by an external reference. | |
| 684 | 684 | */ |
| 685 | 685 | struct comedi_krange { |
| 686 | 686 | int min; |
| @@ -970,7 +970,7 @@ enum i8254_mode { · 283 unmodified lines | ||
| 970 | 970 | * major reasons exist why this caused major confusion for users: |
| 971 | 971 | * 1) The register values are _NOT_ in user documentation, but rather in |
| 972 | 972 | * arcane locations, such as a few register programming manuals that are |
| 973 | − * increasingly hard to find and the NI MHDDK (comments in in example code). | |
| 973 | + * increasingly hard to find and the NI MHDDK (comments in example code). | |
| 974 | 974 | * There is no one place to find the various valid values of the registers. |
| 975 | 975 | * 2) The register values are _NOT_ completely consistent. There is no way to |
| 976 | 976 | * gain any sense of intuition of which values, or even enums one should use |
| @@ -627,7 +627,7 @@ extern const struct comedi_lrange range_unknown; · 626 unmodified lines | ||
| 627 | 627 | * @range: Array of &struct comedi_krange, one for each range. |
| 628 | 628 | * |
| 629 | 629 | * Each element of @range[] describes the minimum and maximum physical range |
| 630 | − * range and the type of units. Typically, the type of unit is %UNIT_volt | |
| 630 | + * and the type of units. Typically, the type of unit is %UNIT_volt | |
| 631 | 631 | * (i.e. volts) and the minimum and maximum are in millionths of a volt. |
| 632 | 632 | * There may also be a flag that indicates the minimum and maximum are merely |
| 633 | 633 | * scale factors for an unknown, external reference. |
| @@ -544,7 +544,7 @@ static int apci1564_timer_insn_write(struct comedi_device *dev, · 543 unmodified lines | ||
| 544 | 544 | { |
| 545 | 545 | struct apci1564_private *devpriv = dev->private; |
| 546 | 546 | |
| 547 | − /* just write the last last to the reload register */ | |
| 547 | + /* just write the last to the reload register */ | |
| 548 | 548 | if (insn->n) { |
| 549 | 549 | unsigned int val = data[insn->n - 1]; |
| 550 | 550 | |
| @@ -628,7 +628,7 @@ static int apci1564_counter_insn_write(struct comedi_device *dev, · 77 unmodified lines | ||
| 628 | 628 | unsigned int chan = CR_CHAN(insn->chanspec); |
| 629 | 629 | unsigned long iobase = devpriv->counters + APCI1564_COUNTER(chan); |
| 630 | 630 | |
| 631 | − /* just write the last last to the reload register */ | |
| 631 | + /* just write the last to the reload register */ | |
| 632 | 632 | if (insn->n) { |
| 633 | 633 | unsigned int val = data[insn->n - 1]; |
| 634 | 634 | |
| @@ -248,7 +248,7 @@ EXPORT_SYMBOL_GPL(subdev_8255_mm_init); · 247 unmodified lines | ||
| 248 | 248 | * subdev_8255_regbase - get offset of 8255 registers or call-back context |
| 249 | 249 | * @s: comedi subdevice |
| 250 | 250 | * |
| 251 | − * Returns the 'regbase' parameter that was previously passed to to | |
| 251 | + * Returns the 'regbase' parameter that was previously passed to | |
| 252 | 252 | * subdev_8255_init() or subdev_8255_mm_init() to set up the subdevice. |
| 253 | 253 | * Only valid if the subdevice was set up successfully. |
| 254 | 254 | */ |
| @@ -286,7 +286,7 @@ int ni_tio_cmdtest(struct comedi_device *dev, · 285 unmodified lines | ||
| 286 | 286 | * This should be done, but we don't yet know the actual |
| 287 | 287 | * register values. These should be tested and then documented |
| 288 | 288 | * in the ni_route_values/ni_*.csv files, with indication of |
| 289 | − * who/when/which/how these these were tested. | |
| 289 | + * who/when/which/how these were tested. | |
| 290 | 290 | * When at least a e/m/660x series have been tested, this code |
| 291 | 291 | * should be uncommented: |
| 292 | 292 | * |
| @@ -389,7 +389,7 @@ static int pcl726_attach(struct comedi_device *dev, · 388 unmodified lines | ||
| 389 | 389 | } |
| 390 | 390 | |
| 391 | 391 | if (dev->irq) { |
| 392 | − /* Digial Input subdevice - Interrupt support */ | |
| 392 | + /* Digital Input subdevice - Interrupt support */ | |
| 393 | 393 | s = &dev->subdevices[subdev++]; |
| 394 | 394 | dev->read_subdev = s; |
| 395 | 395 | s->type = COMEDI_SUBD_DI; |
| @@ -48,7 +48,7 @@ · 47 unmodified lines | ||
| 48 | 48 | * |
| 49 | 49 | * In the 48-channel version: |
| 50 | 50 | * |
| 51 | − * On subdev 0, the first 24 channels channels are edge-detect channels. | |
| 51 | + * On subdev 0, the first 24 channels are edge-detect channels. | |
| 52 | 52 | * |
| 53 | 53 | * In the 96-channel board you have the following channels that can do edge |
| 54 | 54 | * detection: |
| @@ -164,7 +164,7 @@ static int daqp_clear_events(struct comedi_device *dev, int loops) · 163 unmodified lines | ||
| 164 | 164 | |
| 165 | 165 | /* |
| 166 | 166 | * Reset any pending interrupts (my card has a tendency to require |
| 167 | − * require multiple reads on the status register to achieve this). | |
| 167 | + * multiple reads on the status register to achieve this). | |
| 168 | 168 | */ |
| 169 | 169 | while (--loops) { |
| 170 | 170 | status = inb(dev->iobase + DAQP_STATUS_REG); |
| @@ -667,6 +667,9 @@ static int vmk80xx_find_usb_endpoints(struct comedi_device *dev) · 666 unmodified lines | ||
| 667 | 667 | if (!devpriv->ep_rx || !devpriv->ep_tx) |
| 668 | 668 | return -ENODEV; |
| 669 | 669 | |
| 670 | + if (!usb_endpoint_maxp(devpriv->ep_rx) || !usb_endpoint_maxp(devpriv->ep_tx)) | |
| 671 | + return -EINVAL; | |
| 672 | + | |
| 670 | 673 | return 0; |
| 671 | 674 | } |
| 672 | 675 | |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | config USB_EMXX |
| 3 | 3 | tristate "EMXX USB Function Device Controller" |
| 4 | − depends on USB_GADGET && (ARCH_RENESAS || (ARM && COMPILE_TEST)) | |
| 4 | + depends on USB_GADGET && (ARCH_RENESAS || COMPILE_TEST) | |
| 5 | 5 | help |
| 6 | 6 | The Emma Mobile series of SoCs from Renesas Electronics and |
| 7 | 7 | former NEC Electronics include USB Function hardware. |
| @@ -793,7 +793,7 @@ static int _nbu2ss_out_dma(struct nbu2ss_udc *udc, struct nbu2ss_req *req, · 792 unmodified lines | ||
| 793 | 793 | u32 dmacnt; |
| 794 | 794 | u32 burst = 1; |
| 795 | 795 | u32 data; |
| 796 | − int result = -EINVAL; | |
| 796 | + int result; | |
| 797 | 797 | struct fc_regs __iomem *preg = udc->p_regs; |
| 798 | 798 | |
| 799 | 799 | if (req->dma_flag) |
| @@ -1288,8 +1288,6 @@ static void _nbu2ss_set_endpoint_stall(struct nbu2ss_udc *udc, · 488 unmodified lines | ||
| 1288 | 1288 | |
| 1289 | 1289 | _nbu2ss_bitset(&preg->EP_REGS[num].EP_CONTROL, data); |
| 1290 | 1290 | } else { |
| 1291 | − /* Clear STALL */ | |
| 1292 | − ep->stalled = false; | |
| 1293 | 1291 | if (ep_adrs & USB_DIR_IN) { |
| 1294 | 1292 | _nbu2ss_bitclr(&preg->EP_REGS[num].EP_CONTROL |
| 1295 | 1293 | , EPN_ISTL); |
| @@ -1304,6 +1302,7 @@ static void _nbu2ss_set_endpoint_stall(struct nbu2ss_udc *udc, · 8 unmodified lines | ||
| 1304 | 1302 | , data); |
| 1305 | 1303 | } |
| 1306 | 1304 | |
| 1305 | + /* Clear STALL */ | |
| 1307 | 1306 | ep->stalled = false; |
| 1308 | 1307 | if (ep->halted) { |
| 1309 | 1308 | ep->halted = false; |
| @@ -2164,8 +2163,8 @@ static int _nbu2ss_enable_controller(struct nbu2ss_udc *udc) · 854 unmodified lines | ||
| 2164 | 2163 | |
| 2165 | 2164 | _nbu2ss_writel(&udc->p_regs->AHBSCTR, WAIT_MODE); |
| 2166 | 2165 | |
| 2167 | − _nbu2ss_writel(&udc->p_regs->AHBMCTR, | |
| 2168 | − HBUSREQ_MODE | HTRANS_MODE | WBURST_TYPE); | |
| 2166 | + _nbu2ss_writel(&udc->p_regs->AHBMCTR, | |
| 2167 | + HBUSREQ_MODE | HTRANS_MODE | WBURST_TYPE); | |
| 2169 | 2168 | |
| 2170 | 2169 | while (!(_nbu2ss_readl(&udc->p_regs->EPCTR) & PLL_LOCK)) { |
| 2171 | 2170 | waitcnt++; |
| @@ -2176,7 +2175,7 @@ static int _nbu2ss_enable_controller(struct nbu2ss_udc *udc) · 4 unmodified lines | ||
| 2176 | 2175 | } |
| 2177 | 2176 | } |
| 2178 | 2177 | |
| 2179 | − _nbu2ss_bitset(&udc->p_regs->UTMI_CHARACTER_1, USB_SQUSET); | |
| 2178 | + _nbu2ss_bitset(&udc->p_regs->UTMI_CHARACTER_1, USB_SQUSET); | |
| 2180 | 2179 | |
| 2181 | 2180 | _nbu2ss_bitset(&udc->p_regs->USB_CONTROL, (INT_SEL | SOF_RCV)); |
| 2182 | 2181 | |
| @@ -2593,7 +2592,7 @@ static int nbu2ss_ep_queue(struct usb_ep *_ep, · 410 unmodified lines | ||
| 2593 | 2592 | |
| 2594 | 2593 | if (req->unaligned) { |
| 2595 | 2594 | if (!ep->virt_buf) |
| 2596 | − ep->virt_buf = dma_alloc_coherent(NULL, PAGE_SIZE, | |
| 2595 | + ep->virt_buf = dma_alloc_coherent(udc->dev, PAGE_SIZE, | |
| 2597 | 2596 | &ep->phys_buf, |
| 2598 | 2597 | GFP_ATOMIC | GFP_DMA); |
| 2599 | 2598 | if (ep->epnum > 0) { |
| @@ -3073,8 +3072,8 @@ static int nbu2ss_drv_contest_init(struct platform_device *pdev, · 473 unmodified lines | ||
| 3073 | 3072 | */ |
| 3074 | 3073 | static int nbu2ss_drv_probe(struct platform_device *pdev) |
| 3075 | 3074 | { |
| 3076 | − int status = -ENODEV; | |
| 3077 | − struct nbu2ss_udc *udc; | |
| 3075 | + int status; | |
| 3076 | + struct nbu2ss_udc *udc; | |
| 3078 | 3077 | int irq; |
| 3079 | 3078 | void __iomem *mmio_base; |
| 3080 | 3079 | |
| @@ -3148,7 +3147,7 @@ static int nbu2ss_drv_remove(struct platform_device *pdev) · 67 unmodified lines | ||
| 3148 | 3147 | for (i = 0; i < NUM_ENDPOINTS; i++) { |
| 3149 | 3148 | ep = &udc->ep[i]; |
| 3150 | 3149 | if (ep->virt_buf) |
| 3151 | − dma_free_coherent(NULL, PAGE_SIZE, (void *)ep->virt_buf, | |
| 3150 | + dma_free_coherent(udc->dev, PAGE_SIZE, (void *)ep->virt_buf, | |
| 3152 | 3151 | ep->phys_buf); |
| 3153 | 3152 | } |
| 3154 | 3153 | |
| @@ -9,11 +9,6 @@ · 8 unmodified lines | ||
| 9 | 9 | #define _LINUX_EMXX_H |
| 10 | 10 | |
| 11 | 11 | /*---------------------------------------------------------------------------*/ |
| 12 | −/*----------------- Default undef */ | |
| 13 | −#if 0 | |
| 14 | −#define DEBUG | |
| 15 | −#define UDC_DEBUG_DUMP | |
| 16 | −#endif | |
| 17 | 12 | |
| 18 | 13 | /*----------------- Default define */ |
| 19 | 14 | #define USE_DMA 1 |
| @@ -52,197 +47,163 @@ int vbus_irq; · 32 unmodified lines | ||
| 52 | 47 | #define U2F_ENABLE 1 |
| 53 | 48 | #define U2F_DISABLE 0 |
| 54 | 49 | |
| 55 | −/*------- BIT */ | |
| 56 | −#define BIT00 0x00000001 | |
| 57 | −#define BIT01 0x00000002 | |
| 58 | −#define BIT02 0x00000004 | |
| 59 | −#define BIT03 0x00000008 | |
| 60 | −#define BIT04 0x00000010 | |
| 61 | −#define BIT05 0x00000020 | |
| 62 | −#define BIT06 0x00000040 | |
| 63 | −#define BIT07 0x00000080 | |
| 64 | −#define BIT08 0x00000100 | |
| 65 | −#define BIT09 0x00000200 | |
| 66 | −#define BIT10 0x00000400 | |
| 67 | −#define BIT11 0x00000800 | |
| 68 | −#define BIT12 0x00001000 | |
| 69 | −#define BIT13 0x00002000 | |
| 70 | −#define BIT14 0x00004000 | |
| 71 | −#define BIT15 0x00008000 | |
| 72 | −#define BIT16 0x00010000 | |
| 73 | −#define BIT17 0x00020000 | |
| 74 | −#define BIT18 0x00040000 | |
| 75 | −#define BIT19 0x00080000 | |
| 76 | −#define BIT20 0x00100000 | |
| 77 | −#define BIT21 0x00200000 | |
| 78 | −#define BIT22 0x00400000 | |
| 79 | −#define BIT23 0x00800000 | |
| 80 | −#define BIT24 0x01000000 | |
| 81 | −#define BIT25 0x02000000 | |
| 82 | −#define BIT26 0x04000000 | |
| 83 | −#define BIT27 0x08000000 | |
| 84 | −#define BIT28 0x10000000 | |
| 85 | −#define BIT29 0x20000000 | |
| 86 | −#define BIT30 0x40000000 | |
| 87 | −#define BIT31 0x80000000 | |
| 88 | − | |
| 89 | −#define TEST_FORCE_ENABLE (BIT18 + BIT16) | |
| 90 | − | |
| 91 | −#define INT_SEL BIT10 | |
| 92 | −#define CONSTFS BIT09 | |
| 93 | −#define SOF_RCV BIT08 | |
| 94 | −#define RSUM_IN BIT07 | |
| 95 | −#define SUSPEND BIT06 | |
| 96 | −#define CONF BIT05 | |
| 97 | −#define DEFAULT BIT04 | |
| 98 | −#define CONNECTB BIT03 | |
| 99 | −#define PUE2 BIT02 | |
| 50 | +#define TEST_FORCE_ENABLE (BIT(18) | BIT(16)) | |
| 51 | + | |
| 52 | +#define INT_SEL BIT(10) | |
| 53 | +#define CONSTFS BIT(9) | |
| 54 | +#define SOF_RCV BIT(8) | |
| 55 | +#define RSUM_IN BIT(7) | |
| 56 | +#define SUSPEND BIT(6) | |
| 57 | +#define CONF BIT(5) | |
| 58 | +#define DEFAULT BIT(4) | |
| 59 | +#define CONNECTB BIT(3) | |
| 60 | +#define PUE2 BIT(2) | |
| 100 | 61 | |
| 101 | 62 | #define MAX_TEST_MODE_NUM 0x05 |
| 102 | 63 | #define TEST_MODE_SHIFT 16 |
| 103 | 64 | |
| 104 | 65 | /*------- (0x0004) USB Status Register */ |
| 105 | −#define SPEED_MODE BIT06 | |
| 106 | −#define HIGH_SPEED BIT06 | |
| 66 | +#define SPEED_MODE BIT(6) | |
| 67 | +#define HIGH_SPEED BIT(6) | |
| 107 | 68 | |
| 108 | −#define CONF BIT05 | |
| 109 | −#define DEFAULT BIT04 | |
| 110 | −#define USB_RST BIT03 | |
| 111 | −#define SPND_OUT BIT02 | |
| 112 | −#define RSUM_OUT BIT01 | |
| 69 | +#define CONF BIT(5) | |
| 70 | +#define DEFAULT BIT(4) | |
| 71 | +#define USB_RST BIT(3) | |
| 72 | +#define SPND_OUT BIT(2) | |
| 73 | +#define RSUM_OUT BIT(1) | |
| 113 | 74 | |
| 114 | 75 | /*------- (0x0008) USB Address Register */ |
| 115 | 76 | #define USB_ADDR 0x007F0000 |
| 116 | −#define SOF_STATUS BIT15 | |
| 117 | −#define UFRAME (BIT14 + BIT13 + BIT12) | |
| 77 | +#define SOF_STATUS BIT(15) | |
| 78 | +#define UFRAME (BIT(14) | BIT(13) | BIT(12)) | |
| 118 | 79 | #define FRAME 0x000007FF |
| 119 | 80 | |
| 120 | 81 | #define USB_ADRS_SHIFT 16 |
| 121 | 82 | |
| 122 | 83 | /*------- (0x000C) UTMI Characteristic 1 Register */ |
| 123 | −#define SQUSET (BIT07 + BIT06 + BIT05 + BIT04) | |
| 84 | +#define SQUSET (BIT(7) | BIT(6) | BIT(5) | BIT(4)) | |
| 124 | 85 | |
| 125 | −#define USB_SQUSET (BIT06 + BIT05 + BIT04) | |
| 86 | +#define USB_SQUSET (BIT(6) | BIT(5) | BIT(4)) | |
| 126 | 87 | |
| 127 | 88 | /*------- (0x0010) TEST Control Register */ |
| 128 | −#define FORCEHS BIT02 | |
| 129 | −#define CS_TESTMODEEN BIT01 | |
| 130 | −#define LOOPBACK BIT00 | |
| 89 | +#define FORCEHS BIT(2) | |
| 90 | +#define CS_TESTMODEEN BIT(1) | |
| 91 | +#define LOOPBACK BIT(0) | |
| 131 | 92 | |
| 132 | 93 | /*------- (0x0018) Setup Data 0 Register */ |
| 133 | 94 | /*------- (0x001C) Setup Data 1 Register */ |
| 134 | 95 | |
| 135 | 96 | /*------- (0x0020) USB Interrupt Status Register */ |
| 136 | 97 | #define EPN_INT 0x00FFFF00 |
| 137 | −#define EP15_INT BIT23 | |
| 138 | −#define EP14_INT BIT22 | |
| 139 | −#define EP13_INT BIT21 | |
| 140 | −#define EP12_INT BIT20 | |
| 141 | −#define EP11_INT BIT19 | |
| 142 | −#define EP10_INT BIT18 | |
| 143 | −#define EP9_INT BIT17 | |
| 144 | −#define EP8_INT BIT16 | |
| 145 | −#define EP7_INT BIT15 | |
| 146 | −#define EP6_INT BIT14 | |
| 147 | −#define EP5_INT BIT13 | |
| 148 | −#define EP4_INT BIT12 | |
| 149 | −#define EP3_INT BIT11 | |
| 150 | −#define EP2_INT BIT10 | |
| 151 | −#define EP1_INT BIT09 | |
| 152 | −#define EP0_INT BIT08 | |
| 153 | −#define SPEED_MODE_INT BIT06 | |
| 154 | −#define SOF_ERROR_INT BIT05 | |
| 155 | −#define SOF_INT BIT04 | |
| 156 | −#define USB_RST_INT BIT03 | |
| 157 | −#define SPND_INT BIT02 | |
| 158 | −#define RSUM_INT BIT01 | |
| 98 | +#define EP15_INT BIT(23) | |
| 99 | +#define EP14_INT BIT(22) | |
| 100 | +#define EP13_INT BIT(21) | |
| 101 | +#define EP12_INT BIT(20) | |
| 102 | +#define EP11_INT BIT(19) | |
| 103 | +#define EP10_INT BIT(18) | |
| 104 | +#define EP9_INT BIT(17) | |
| 105 | +#define EP8_INT BIT(16) | |
| 106 | +#define EP7_INT BIT(15) | |
| 107 | +#define EP6_INT BIT(14) | |
| 108 | +#define EP5_INT BIT(13) | |
| 109 | +#define EP4_INT BIT(12) | |
| 110 | +#define EP3_INT BIT(11) | |
| 111 | +#define EP2_INT BIT(10) | |
| 112 | +#define EP1_INT BIT(9) | |
| 113 | +#define EP0_INT BIT(8) | |
| 114 | +#define SPEED_MODE_INT BIT(6) | |
| 115 | +#define SOF_ERROR_INT BIT(5) | |
| 116 | +#define SOF_INT BIT(4) | |
| 117 | +#define USB_RST_INT BIT(3) | |
| 118 | +#define SPND_INT BIT(2) | |
| 119 | +#define RSUM_INT BIT(1) | |
| 159 | 120 | |
| 160 | 121 | #define USB_INT_STA_RW 0x7E |
| 161 | 122 | |
| 162 | 123 | /*------- (0x0024) USB Interrupt Enable Register */ |
| 163 | 124 | #define EP15_0_EN 0x00FFFF00 |
| 164 | −#define EP15_EN BIT23 | |
| 165 | −#define EP14_EN BIT22 | |
| 166 | −#define EP13_EN BIT21 | |
| 167 | −#define EP12_EN BIT20 | |
| 168 | −#define EP11_EN BIT19 | |
| 169 | −#define EP10_EN BIT18 | |
| 170 | −#define EP9_EN BIT17 | |
| 171 | −#define EP8_EN BIT16 | |
| 172 | −#define EP7_EN BIT15 | |
| 173 | −#define EP6_EN BIT14 | |
| 174 | −#define EP5_EN BIT13 | |
| 175 | −#define EP4_EN BIT12 | |
| 176 | −#define EP3_EN BIT11 | |
| 177 | −#define EP2_EN BIT10 | |
| 178 | −#define EP1_EN BIT09 | |
| 179 | −#define EP0_EN BIT08 | |
| 180 | −#define SPEED_MODE_EN BIT06 | |
| 181 | −#define SOF_ERROR_EN BIT05 | |
| 182 | −#define SOF_EN BIT04 | |
| 183 | −#define USB_RST_EN BIT03 | |
| 184 | −#define SPND_EN BIT02 | |
| 185 | −#define RSUM_EN BIT01 | |
| 125 | +#define EP15_EN BIT(23) | |
| 126 | +#define EP14_EN BIT(22) | |
| 127 | +#define EP13_EN BIT(21) | |
| 128 | +#define EP12_EN BIT(20) | |
| 129 | +#define EP11_EN BIT(19) | |
| 130 | +#define EP10_EN BIT(18) | |
| 131 | +#define EP9_EN BIT(17) | |
| 132 | +#define EP8_EN BIT(16) | |
| 133 | +#define EP7_EN BIT(15) | |
| 134 | +#define EP6_EN BIT(14) | |
| 135 | +#define EP5_EN BIT(13) | |
| 136 | +#define EP4_EN BIT(12) | |
| 137 | +#define EP3_EN BIT(11) | |
| 138 | +#define EP2_EN BIT(10) | |
| 139 | +#define EP1_EN BIT(9) | |
| 140 | +#define EP0_EN BIT(8) | |
| 141 | +#define SPEED_MODE_EN BIT(6) | |
| 142 | +#define SOF_ERROR_EN BIT(5) | |
| 143 | +#define SOF_EN BIT(4) | |
| 144 | +#define USB_RST_EN BIT(3) | |
| 145 | +#define SPND_EN BIT(2) | |
| 146 | +#define RSUM_EN BIT(1) | |
| 186 | 147 | |
| 187 | 148 | #define USB_INT_EN_BIT \ |
| 188 | 149 | (EP0_EN | SPEED_MODE_EN | USB_RST_EN | SPND_EN | RSUM_EN) |
| 189 | 150 | |
| 190 | 151 | /*------- (0x0028) EP0 Control Register */ |
| 191 | −#define EP0_STGSEL BIT18 | |
| 192 | −#define EP0_OVERSEL BIT17 | |
| 193 | −#define EP0_AUTO BIT16 | |
| 194 | −#define EP0_PIDCLR BIT09 | |
| 195 | −#define EP0_BCLR BIT08 | |
| 196 | −#define EP0_DEND BIT07 | |
| 197 | −#define EP0_DW (BIT06 + BIT05) | |
| 152 | +#define EP0_STGSEL BIT(18) | |
| 153 | +#define EP0_OVERSEL BIT(17) | |
| 154 | +#define EP0_AUTO BIT(16) | |
| 155 | +#define EP0_PIDCLR BIT(9) | |
| 156 | +#define EP0_BCLR BIT(8) | |
| 157 | +#define EP0_DEND BIT(7) | |
| 158 | +#define EP0_DW (BIT(6) | BIT(5)) | |
| 198 | 159 | #define EP0_DW4 0 |
| 199 | −#define EP0_DW3 (BIT06 + BIT05) | |
| 200 | −#define EP0_DW2 BIT06 | |
| 201 | −#define EP0_DW1 BIT05 | |
| 160 | +#define EP0_DW3 (BIT(6) | BIT(5)) | |
| 161 | +#define EP0_DW2 BIT(6) | |
| 162 | +#define EP0_DW1 BIT(5) | |
| 202 | 163 | |
| 203 | −#define EP0_INAK_EN BIT04 | |
| 204 | −#define EP0_PERR_NAK_CLR BIT03 | |
| 205 | −#define EP0_STL BIT02 | |
| 206 | −#define EP0_INAK BIT01 | |
| 207 | −#define EP0_ONAK BIT00 | |
| 164 | +#define EP0_INAK_EN BIT(4) | |
| 165 | +#define EP0_PERR_NAK_CLR BIT(3) | |
| 166 | +#define EP0_STL BIT(2) | |
| 167 | +#define EP0_INAK BIT(1) | |
| 168 | +#define EP0_ONAK BIT(0) | |
| 208 | 169 | |
| 209 | 170 | /*------- (0x002C) EP0 Status Register */ |
| 210 | −#define EP0_PID BIT18 | |
| 211 | −#define EP0_PERR_NAK BIT17 | |
| 212 | −#define EP0_PERR_NAK_INT BIT16 | |
| 213 | −#define EP0_OUT_NAK_INT BIT15 | |
| 214 | −#define EP0_OUT_NULL BIT14 | |
| 215 | −#define EP0_OUT_FULL BIT13 | |
| 216 | −#define EP0_OUT_EMPTY BIT12 | |
| 217 | −#define EP0_IN_NAK_INT BIT11 | |
| 218 | −#define EP0_IN_DATA BIT10 | |
| 219 | −#define EP0_IN_FULL BIT09 | |
| 220 | −#define EP0_IN_EMPTY BIT08 | |
| 221 | −#define EP0_OUT_NULL_INT BIT07 | |
| 222 | −#define EP0_OUT_OR_INT BIT06 | |
| 223 | −#define EP0_OUT_INT BIT05 | |
| 224 | −#define EP0_IN_INT BIT04 | |
| 225 | −#define EP0_STALL_INT BIT03 | |
| 226 | −#define STG_END_INT BIT02 | |
| 227 | −#define STG_START_INT BIT01 | |
| 228 | −#define SETUP_INT BIT00 | |
| 229 | − | |
| 230 | −#define EP0_STATUS_RW_BIT (BIT16 | BIT15 | BIT11 | 0xFF) | |
| 171 | +#define EP0_PID BIT(18) | |
| 172 | +#define EP0_PERR_NAK BIT(17) | |
| 173 | +#define EP0_PERR_NAK_INT BIT(16) | |
| 174 | +#define EP0_OUT_NAK_INT BIT(15) | |
| 175 | +#define EP0_OUT_NULL BIT(14) | |
| 176 | +#define EP0_OUT_FULL BIT(13) | |
| 177 | +#define EP0_OUT_EMPTY BIT(12) | |
| 178 | +#define EP0_IN_NAK_INT BIT(11) | |
| 179 | +#define EP0_IN_DATA BIT(10) | |
| 180 | +#define EP0_IN_FULL BIT(9) | |
| 181 | +#define EP0_IN_EMPTY BIT(8) | |
| 182 | +#define EP0_OUT_NULL_INT BIT(7) | |
| 183 | +#define EP0_OUT_OR_INT BIT(6) | |
| 184 | +#define EP0_OUT_INT BIT(5) | |
| 185 | +#define EP0_IN_INT BIT(4) | |
| 186 | +#define EP0_STALL_INT BIT(3) | |
| 187 | +#define STG_END_INT BIT(2) | |
| 188 | +#define STG_START_INT BIT(1) | |
| 189 | +#define SETUP_INT BIT(0) | |
| 190 | + | |
| 191 | +#define EP0_STATUS_RW_BIT (BIT(16) | BIT(15) | BIT(11) | 0xFF) | |
| 231 | 192 | |
| 232 | 193 | /*------- (0x0030) EP0 Interrupt Enable Register */ |
| 233 | −#define EP0_PERR_NAK_EN BIT16 | |
| 234 | −#define EP0_OUT_NAK_EN BIT15 | |
| 194 | +#define EP0_PERR_NAK_EN BIT(16) | |
| 195 | +#define EP0_OUT_NAK_EN BIT(15) | |
| 235 | 196 | |
| 236 | −#define EP0_IN_NAK_EN BIT11 | |
| 197 | +#define EP0_IN_NAK_EN BIT(11) | |
| 237 | 198 | |
| 238 | −#define EP0_OUT_NULL_EN BIT07 | |
| 239 | −#define EP0_OUT_OR_EN BIT06 | |
| 240 | −#define EP0_OUT_EN BIT05 | |
| 241 | −#define EP0_IN_EN BIT04 | |
| 242 | −#define EP0_STALL_EN BIT03 | |
| 243 | −#define STG_END_EN BIT02 | |
| 244 | −#define STG_START_EN BIT01 | |
| 245 | −#define SETUP_EN BIT00 | |
| 199 | +#define EP0_OUT_NULL_EN BIT(7) | |
| 200 | +#define EP0_OUT_OR_EN BIT(6) | |
| 201 | +#define EP0_OUT_EN BIT(5) | |
| 202 | +#define EP0_IN_EN BIT(4) | |
| 203 | +#define EP0_STALL_EN BIT(3) | |
| 204 | +#define STG_END_EN BIT(2) | |
| 205 | +#define STG_START_EN BIT(1) | |
| 206 | +#define SETUP_EN BIT(0) | |
| 246 | 207 | |
| 247 | 208 | #define EP0_INT_EN_BIT \ |
| 248 | 209 | (EP0_OUT_OR_EN | EP0_OUT_EN | EP0_IN_EN | STG_END_EN | SETUP_EN) |
| @@ -254,90 +215,90 @@ int vbus_irq; · 5 unmodified lines | ||
| 254 | 215 | /*------- (0x003C) EP0 Write Register */ |
| 255 | 216 | |
| 256 | 217 | /*------- (0x0040:) EPN Control Register */ |
| 257 | −#define EPN_EN BIT31 | |
| 258 | −#define EPN_BUF_TYPE BIT30 | |
| 259 | −#define EPN_BUF_SINGLE BIT30 | |
| 218 | +#define EPN_EN BIT(31) | |
| 219 | +#define EPN_BUF_TYPE BIT(30) | |
| 220 | +#define EPN_BUF_SINGLE BIT(30) | |
| 260 | 221 | |
| 261 | −#define EPN_DIR0 BIT26 | |
| 262 | −#define EPN_MODE (BIT25 + BIT24) | |
| 222 | +#define EPN_DIR0 BIT(26) | |
| 223 | +#define EPN_MODE (BIT(25) | BIT(24)) | |
| 263 | 224 | #define EPN_BULK 0 |
| 264 | −#define EPN_INTERRUPT BIT24 | |
| 265 | −#define EPN_ISO BIT25 | |
| 266 | − | |
| 267 | −#define EPN_OVERSEL BIT17 | |
| 268 | −#define EPN_AUTO BIT16 | |
| 269 | − | |
| 270 | −#define EPN_IPIDCLR BIT11 | |
| 271 | −#define EPN_OPIDCLR BIT10 | |
| 272 | −#define EPN_BCLR BIT09 | |
| 273 | −#define EPN_CBCLR BIT08 | |
| 274 | −#define EPN_DEND BIT07 | |
| 275 | −#define EPN_DW (BIT06 + BIT05) | |
| 225 | +#define EPN_INTERRUPT BIT(24) | |
| 226 | +#define EPN_ISO BIT(25) | |
| 227 | + | |
| 228 | +#define EPN_OVERSEL BIT(17) | |
| 229 | +#define EPN_AUTO BIT(16) | |
| 230 | + | |
| 231 | +#define EPN_IPIDCLR BIT(11) | |
| 232 | +#define EPN_OPIDCLR BIT(10) | |
| 233 | +#define EPN_BCLR BIT(9) | |
| 234 | +#define EPN_CBCLR BIT(8) | |
| 235 | +#define EPN_DEND BIT(7) | |
| 236 | +#define EPN_DW (BIT(6) | BIT(5)) | |
| 276 | 237 | #define EPN_DW4 0 |
| 277 | −#define EPN_DW3 (BIT06 + BIT05) | |
| 278 | −#define EPN_DW2 BIT06 | |
| 279 | −#define EPN_DW1 BIT05 | |
| 238 | +#define EPN_DW3 (BIT(6) | BIT(5)) | |
| 239 | +#define EPN_DW2 BIT(6) | |
| 240 | +#define EPN_DW1 BIT(5) | |
| 280 | 241 | |
| 281 | −#define EPN_OSTL_EN BIT04 | |
| 282 | −#define EPN_ISTL BIT03 | |
| 283 | −#define EPN_OSTL BIT02 | |
| 242 | +#define EPN_OSTL_EN BIT(4) | |
| 243 | +#define EPN_ISTL BIT(3) | |
| 244 | +#define EPN_OSTL BIT(2) | |
| 284 | 245 | |
| 285 | −#define EPN_ONAK BIT00 | |
| 246 | +#define EPN_ONAK BIT(0) | |
| 286 | 247 | |
| 287 | 248 | /*------- (0x0044:) EPN Status Register */ |
| 288 | −#define EPN_ISO_PIDERR BIT29 /* R */ | |
| 289 | −#define EPN_OPID BIT28 /* R */ | |
| 290 | −#define EPN_OUT_NOTKN BIT27 /* R */ | |
| 291 | −#define EPN_ISO_OR BIT26 /* R */ | |
| 292 | − | |
| 293 | −#define EPN_ISO_CRC BIT24 /* R */ | |
| 294 | −#define EPN_OUT_END_INT BIT23 /* RW */ | |
| 295 | −#define EPN_OUT_OR_INT BIT22 /* RW */ | |
| 296 | −#define EPN_OUT_NAK_ERR_INT BIT21 /* RW */ | |
| 297 | −#define EPN_OUT_STALL_INT BIT20 /* RW */ | |
| 298 | −#define EPN_OUT_INT BIT19 /* RW */ | |
| 299 | −#define EPN_OUT_NULL_INT BIT18 /* RW */ | |
| 300 | −#define EPN_OUT_FULL BIT17 /* R */ | |
| 301 | −#define EPN_OUT_EMPTY BIT16 /* R */ | |
| 302 | − | |
| 303 | −#define EPN_IPID BIT10 /* R */ | |
| 304 | −#define EPN_IN_NOTKN BIT09 /* R */ | |
| 305 | −#define EPN_ISO_UR BIT08 /* R */ | |
| 306 | −#define EPN_IN_END_INT BIT07 /* RW */ | |
| 307 | − | |
| 308 | −#define EPN_IN_NAK_ERR_INT BIT05 /* RW */ | |
| 309 | −#define EPN_IN_STALL_INT BIT04 /* RW */ | |
| 310 | −#define EPN_IN_INT BIT03 /* RW */ | |
| 311 | −#define EPN_IN_DATA BIT02 /* R */ | |
| 312 | −#define EPN_IN_FULL BIT01 /* R */ | |
| 313 | −#define EPN_IN_EMPTY BIT00 /* R */ | |
| 249 | +#define EPN_ISO_PIDERR BIT(29) /* R */ | |
| 250 | +#define EPN_OPID BIT(28) /* R */ | |
| 251 | +#define EPN_OUT_NOTKN BIT(27) /* R */ | |
| 252 | +#define EPN_ISO_OR BIT(26) /* R */ | |
| 253 | + | |
| 254 | +#define EPN_ISO_CRC BIT(24) /* R */ | |
| 255 | +#define EPN_OUT_END_INT BIT(23) /* RW */ | |
| 256 | +#define EPN_OUT_OR_INT BIT(22) /* RW */ | |
| 257 | +#define EPN_OUT_NAK_ERR_INT BIT(21) /* RW */ | |
| 258 | +#define EPN_OUT_STALL_INT BIT(20) /* RW */ | |
| 259 | +#define EPN_OUT_INT BIT(19) /* RW */ | |
| 260 | +#define EPN_OUT_NULL_INT BIT(18) /* RW */ | |
| 261 | +#define EPN_OUT_FULL BIT(17) /* R */ | |
| 262 | +#define EPN_OUT_EMPTY BIT(16) /* R */ | |
| 263 | + | |
| 264 | +#define EPN_IPID BIT(10) /* R */ | |
| 265 | +#define EPN_IN_NOTKN BIT(9) /* R */ | |
| 266 | +#define EPN_ISO_UR BIT(8) /* R */ | |
| 267 | +#define EPN_IN_END_INT BIT(7) /* RW */ | |
| 268 | + | |
| 269 | +#define EPN_IN_NAK_ERR_INT BIT(5) /* RW */ | |
| 270 | +#define EPN_IN_STALL_INT BIT(4) /* RW */ | |
| 271 | +#define EPN_IN_INT BIT(3) /* RW */ | |
| 272 | +#define EPN_IN_DATA BIT(2) /* R */ | |
| 273 | +#define EPN_IN_FULL BIT(1) /* R */ | |
| 274 | +#define EPN_IN_EMPTY BIT(0) /* R */ | |
| 314 | 275 | |
| 315 | 276 | #define EPN_INT_EN \ |
| 316 | 277 | (EPN_OUT_END_INT | EPN_OUT_INT | EPN_IN_END_INT | EPN_IN_INT) |
| 317 | 278 | |
| 318 | 279 | /*------- (0x0048:) EPN Interrupt Enable Register */ |
| 319 | −#define EPN_OUT_END_EN BIT23 /* RW */ | |
| 320 | −#define EPN_OUT_OR_EN BIT22 /* RW */ | |
| 321 | −#define EPN_OUT_NAK_ERR_EN BIT21 /* RW */ | |
| 322 | −#define EPN_OUT_STALL_EN BIT20 /* RW */ | |
| 323 | −#define EPN_OUT_EN BIT19 /* RW */ | |
| 324 | −#define EPN_OUT_NULL_EN BIT18 /* RW */ | |
| 280 | +#define EPN_OUT_END_EN BIT(23) /* RW */ | |
| 281 | +#define EPN_OUT_OR_EN BIT(22) /* RW */ | |
| 282 | +#define EPN_OUT_NAK_ERR_EN BIT(21) /* RW */ | |
| 283 | +#define EPN_OUT_STALL_EN BIT(20) /* RW */ | |
| 284 | +#define EPN_OUT_EN BIT(19) /* RW */ | |
| 285 | +#define EPN_OUT_NULL_EN BIT(18) /* RW */ | |
| 325 | 286 | |
| 326 | −#define EPN_IN_END_EN BIT07 /* RW */ | |
| 287 | +#define EPN_IN_END_EN BIT(7) /* RW */ | |
| 327 | 288 | |
| 328 | −#define EPN_IN_NAK_ERR_EN BIT05 /* RW */ | |
| 329 | −#define EPN_IN_STALL_EN BIT04 /* RW */ | |
| 330 | −#define EPN_IN_EN BIT03 /* RW */ | |
| 289 | +#define EPN_IN_NAK_ERR_EN BIT(5) /* RW */ | |
| 290 | +#define EPN_IN_STALL_EN BIT(4) /* RW */ | |
| 291 | +#define EPN_IN_EN BIT(3) /* RW */ | |
| 331 | 292 | |
| 332 | 293 | /*------- (0x004C:) EPN Interrupt Enable Register */ |
| 333 | −#define EPN_STOP_MODE BIT11 | |
| 334 | −#define EPN_DEND_SET BIT10 | |
| 335 | −#define EPN_BURST_SET BIT09 | |
| 336 | −#define EPN_STOP_SET BIT08 | |
| 294 | +#define EPN_STOP_MODE BIT(11) | |
| 295 | +#define EPN_DEND_SET BIT(10) | |
| 296 | +#define EPN_BURST_SET BIT(9) | |
| 297 | +#define EPN_STOP_SET BIT(8) | |
| 337 | 298 | |
| 338 | −#define EPN_DMA_EN BIT04 | |
| 299 | +#define EPN_DMA_EN BIT(4) | |
| 339 | 300 | |
| 340 | −#define EPN_DMAMODE0 BIT00 | |
| 301 | +#define EPN_DMAMODE0 BIT(0) | |
| 341 | 302 | |
| 342 | 303 | /*------- (0x0050:) EPN MaxPacket & BaseAddress Register */ |
| 343 | 304 | #define EPN_BASEAD 0x1FFF0000 |
| @@ -351,62 +312,62 @@ int vbus_irq; · 7 unmodified lines | ||
| 351 | 312 | /*------- (0x005C:) EPN Write Register */ |
| 352 | 313 | |
| 353 | 314 | /*------- (0x1000) AHBSCTR Register */ |
| 354 | −#define WAIT_MODE BIT00 | |
| 315 | +#define WAIT_MODE BIT(0) | |
| 355 | 316 | |
| 356 | 317 | /*------- (0x1004) AHBMCTR Register */ |
| 357 | −#define ARBITER_CTR BIT31 /* RW */ | |
| 358 | −#define MCYCLE_RST BIT12 /* RW */ | |
| 318 | +#define ARBITER_CTR BIT(31) /* RW */ | |
| 319 | +#define MCYCLE_RST BIT(12) /* RW */ | |
| 359 | 320 | |
| 360 | −#define ENDIAN_CTR (BIT09 + BIT08) /* RW */ | |
| 361 | −#define ENDIAN_BYTE_SWAP BIT09 | |
| 321 | +#define ENDIAN_CTR (BIT(9) | BIT(8)) /* RW */ | |
| 322 | +#define ENDIAN_BYTE_SWAP BIT(9) | |
| 362 | 323 | #define ENDIAN_HALF_WORD_SWAP ENDIAN_CTR |
| 363 | 324 | |
| 364 | −#define HBUSREQ_MODE BIT05 /* RW */ | |
| 365 | −#define HTRANS_MODE BIT04 /* RW */ | |
| 325 | +#define HBUSREQ_MODE BIT(5) /* RW */ | |
| 326 | +#define HTRANS_MODE BIT(4) /* RW */ | |
| 366 | 327 | |
| 367 | −#define WBURST_TYPE BIT02 /* RW */ | |
| 368 | −#define BURST_TYPE (BIT01 + BIT00) /* RW */ | |
| 328 | +#define WBURST_TYPE BIT(2) /* RW */ | |
| 329 | +#define BURST_TYPE (BIT(1) | BIT(0)) /* RW */ | |
| 369 | 330 | #define BURST_MAX_16 0 |
| 370 | −#define BURST_MAX_8 BIT00 | |
| 371 | −#define BURST_MAX_4 BIT01 | |
| 331 | +#define BURST_MAX_8 BIT(0) | |
| 332 | +#define BURST_MAX_4 BIT(1) | |
| 372 | 333 | #define BURST_SINGLE BURST_TYPE |
| 373 | 334 | |
| 374 | 335 | /*------- (0x1008) AHBBINT Register */ |
| 375 | 336 | #define DMA_ENDINT 0xFFFE0000 /* RW */ |
| 376 | 337 | |
| 377 | −#define AHB_VBUS_INT BIT13 /* RW */ | |
| 338 | +#define AHB_VBUS_INT BIT(13) /* RW */ | |
| 378 | 339 | |
| 379 | −#define MBUS_ERRINT BIT06 /* RW */ | |
| 340 | +#define MBUS_ERRINT BIT(6) /* RW */ | |
| 380 | 341 | |
| 381 | −#define SBUS_ERRINT0 BIT04 /* RW */ | |
| 342 | +#define SBUS_ERRINT0 BIT(4) /* RW */ | |
| 382 | 343 | #define ERR_MASTER 0x0000000F /* R */ |
| 383 | 344 | |
| 384 | 345 | /*------- (0x100C) AHBBINTEN Register */ |
| 385 | 346 | #define DMA_ENDINTEN 0xFFFE0000 /* RW */ |
| 386 | 347 | |
| 387 | −#define VBUS_INTEN BIT13 /* RW */ | |
| 348 | +#define VBUS_INTEN BIT(13) /* RW */ | |
| 388 | 349 | |
| 389 | −#define MBUS_ERRINTEN BIT06 /* RW */ | |
| 350 | +#define MBUS_ERRINTEN BIT(6) /* RW */ | |
| 390 | 351 | |
| 391 | −#define SBUS_ERRINT0EN BIT04 /* RW */ | |
| 352 | +#define SBUS_ERRINT0EN BIT(4) /* RW */ | |
| 392 | 353 | |
| 393 | 354 | /*------- (0x1010) EPCTR Register */ |
| 394 | −#define DIRPD BIT12 /* RW */ | |
| 355 | +#define DIRPD BIT(12) /* RW */ | |
| 395 | 356 | |
| 396 | −#define VBUS_LEVEL BIT08 /* R */ | |
| 357 | +#define VBUS_LEVEL BIT(8) /* R */ | |
| 397 | 358 | |
| 398 | −#define PLL_RESUME BIT05 /* RW */ | |
| 399 | −#define PLL_LOCK BIT04 /* R */ | |
| 359 | +#define PLL_RESUME BIT(5) /* RW */ | |
| 360 | +#define PLL_LOCK BIT(4) /* R */ | |
| 400 | 361 | |
| 401 | −#define EPC_RST BIT00 /* RW */ | |
| 362 | +#define EPC_RST BIT(0) /* RW */ | |
| 402 | 363 | |
| 403 | 364 | /*------- (0x1014) USBF_EPTEST Register */ |
| 404 | −#define LINESTATE (BIT09 + BIT08) /* R */ | |
| 405 | −#define DM_LEVEL BIT09 /* R */ | |
| 406 | −#define DP_LEVEL BIT08 /* R */ | |
| 365 | +#define LINESTATE (BIT(9) | BIT(8)) /* R */ | |
| 366 | +#define DM_LEVEL BIT(9) /* R */ | |
| 367 | +#define DP_LEVEL BIT(8) /* R */ | |
| 407 | 368 | |
| 408 | −#define PHY_TST BIT01 /* RW */ | |
| 409 | −#define PHY_TSTCLK BIT00 /* RW */ | |
| 369 | +#define PHY_TST BIT(1) /* RW */ | |
| 370 | +#define PHY_TSTCLK BIT(0) /* RW */ | |
| 410 | 371 | |
| 411 | 372 | /*------- (0x1020) USBSSVER Register */ |
| 412 | 373 | #define AHBB_VER 0x00FF0000 /* R */ |
| @@ -420,8 +381,8 @@ int vbus_irq; · 7 unmodified lines | ||
| 420 | 381 | /*------- (0x1110:) EPNDCR1 Register */ |
| 421 | 382 | #define DCR1_EPN_DMACNT 0x00FF0000 /* RW */ |
| 422 | 383 | |
| 423 | −#define DCR1_EPN_DIR0 BIT01 /* RW */ | |
| 424 | −#define DCR1_EPN_REQEN BIT00 /* RW */ | |
| 384 | +#define DCR1_EPN_DIR0 BIT(1) /* RW */ | |
| 385 | +#define DCR1_EPN_REQEN BIT(0) /* RW */ | |
| 425 | 386 | |
| 426 | 387 | /*------- (0x1114:) EPNDCR2 Register */ |
| 427 | 388 | #define DCR2_EPN_LMPKT 0x07FF0000 /* RW */ |
| @@ -12,7 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | static struct { |
| 13 | 13 | enum dpsw_counter id; |
| 14 | 14 | char name[ETH_GSTRING_LEN]; |
| 15 | −} ethsw_ethtool_counters[] = { | |
| 15 | +} dpaa2_switch_ethtool_counters[] = { | |
| 16 | 16 | {DPSW_CNT_ING_FRAME, "rx frames"}, |
| 17 | 17 | {DPSW_CNT_ING_BYTE, "rx bytes"}, |
| 18 | 18 | {DPSW_CNT_ING_FLTR_FRAME, "rx filtered frames"}, |
| @@ -27,10 +27,10 @@ static struct { · 8 unmodified lines | ||
| 27 | 27 | |
| 28 | 28 | }; |
| 29 | 29 | |
| 30 | −#define ETHSW_NUM_COUNTERS ARRAY_SIZE(ethsw_ethtool_counters) | |
| 30 | +#define DPAA2_SWITCH_NUM_COUNTERS ARRAY_SIZE(dpaa2_switch_ethtool_counters) | |
| 31 | 31 | |
| 32 | −static void ethsw_get_drvinfo(struct net_device *netdev, | |
| 33 | − struct ethtool_drvinfo *drvinfo) | |
| 32 | +static void dpaa2_switch_get_drvinfo(struct net_device *netdev, | |
| 33 | + struct ethtool_drvinfo *drvinfo) | |
| 34 | 34 | { |
| 35 | 35 | struct ethsw_port_priv *port_priv = netdev_priv(netdev); |
| 36 | 36 | u16 version_major, version_minor; |
| @@ -53,8 +53,8 @@ static void ethsw_get_drvinfo(struct net_device *netdev, · 16 unmodified lines | ||
| 53 | 53 | } |
| 54 | 54 | |
| 55 | 55 | static int |
| 56 | −ethsw_get_link_ksettings(struct net_device *netdev, | |
| 57 | − struct ethtool_link_ksettings *link_ksettings) | |
| 56 | +dpaa2_switch_get_link_ksettings(struct net_device *netdev, | |
| 57 | + struct ethtool_link_ksettings *link_ksettings) | |
| 58 | 58 | { |
| 59 | 59 | struct ethsw_port_priv *port_priv = netdev_priv(netdev); |
| 60 | 60 | struct dpsw_link_state state = {0}; |
| @@ -84,8 +84,8 @@ out: · 23 unmodified lines | ||
| 84 | 84 | } |
| 85 | 85 | |
| 86 | 86 | static int |
| 87 | −ethsw_set_link_ksettings(struct net_device *netdev, | |
| 88 | − const struct ethtool_link_ksettings *link_ksettings) | |
| 87 | +dpaa2_switch_set_link_ksettings(struct net_device *netdev, | |
| 88 | + const struct ethtool_link_ksettings *link_ksettings) | |
| 89 | 89 | { |
| 90 | 90 | struct ethsw_port_priv *port_priv = netdev_priv(netdev); |
| 91 | 91 | struct ethsw_core *ethsw = port_priv->ethsw_data; |
| @@ -132,55 +132,56 @@ ethsw_set_link_ksettings(struct net_device *netdev, · 40 unmodified lines | ||
| 132 | 132 | return err; |
| 133 | 133 | } |
| 134 | 134 | |
| 135 | −static int ethsw_ethtool_get_sset_count(struct net_device *dev, int sset) | |
| 135 | +static int dpaa2_switch_ethtool_get_sset_count(struct net_device *dev, int sset) | |
| 136 | 136 | { |
| 137 | 137 | switch (sset) { |
| 138 | 138 | case ETH_SS_STATS: |
| 139 | − return ETHSW_NUM_COUNTERS; | |
| 139 | + return DPAA2_SWITCH_NUM_COUNTERS; | |
| 140 | 140 | default: |
| 141 | 141 | return -EOPNOTSUPP; |
| 142 | 142 | } |
| 143 | 143 | } |
| 144 | 144 | |
| 145 | −static void ethsw_ethtool_get_strings(struct net_device *netdev, | |
| 146 | − u32 stringset, u8 *data) | |
| 145 | +static void dpaa2_switch_ethtool_get_strings(struct net_device *netdev, | |
| 146 | + u32 stringset, u8 *data) | |
| 147 | 147 | { |
| 148 | 148 | int i; |
| 149 | 149 | |
| 150 | 150 | switch (stringset) { |
| 151 | 151 | case ETH_SS_STATS: |
| 152 | − for (i = 0; i < ETHSW_NUM_COUNTERS; i++) | |
| 152 | + for (i = 0; i < DPAA2_SWITCH_NUM_COUNTERS; i++) | |
| 153 | 153 | memcpy(data + i * ETH_GSTRING_LEN, |
| 154 | − ethsw_ethtool_counters[i].name, ETH_GSTRING_LEN); | |
| 154 | + dpaa2_switch_ethtool_counters[i].name, | |
| 155 | + ETH_GSTRING_LEN); | |
| 155 | 156 | break; |
| 156 | 157 | } |
| 157 | 158 | } |
| 158 | 159 | |
| 159 | −static void ethsw_ethtool_get_stats(struct net_device *netdev, | |
| 160 | − struct ethtool_stats *stats, | |
| 161 | − u64 *data) | |
| 160 | +static void dpaa2_switch_ethtool_get_stats(struct net_device *netdev, | |
| 161 | + struct ethtool_stats *stats, | |
| 162 | + u64 *data) | |
| 162 | 163 | { |
| 163 | 164 | struct ethsw_port_priv *port_priv = netdev_priv(netdev); |
| 164 | 165 | int i, err; |
| 165 | 166 | |
| 166 | − for (i = 0; i < ETHSW_NUM_COUNTERS; i++) { | |
| 167 | + for (i = 0; i < DPAA2_SWITCH_NUM_COUNTERS; i++) { | |
| 167 | 168 | err = dpsw_if_get_counter(port_priv->ethsw_data->mc_io, 0, |
| 168 | 169 | port_priv->ethsw_data->dpsw_handle, |
| 169 | 170 | port_priv->idx, |
| 170 | − ethsw_ethtool_counters[i].id, | |
| 171 | + dpaa2_switch_ethtool_counters[i].id, | |
| 171 | 172 | &data[i]); |
| 172 | 173 | if (err) |
| 173 | 174 | netdev_err(netdev, "dpsw_if_get_counter[%s] err %d\n", |
| 174 | − ethsw_ethtool_counters[i].name, err); | |
| 175 | + dpaa2_switch_ethtool_counters[i].name, err); | |
| 175 | 176 | } |
| 176 | 177 | } |
| 177 | 178 | |
| 178 | −const struct ethtool_ops ethsw_port_ethtool_ops = { | |
| 179 | − .get_drvinfo = ethsw_get_drvinfo, | |
| 179 | +const struct ethtool_ops dpaa2_switch_port_ethtool_ops = { | |
| 180 | + .get_drvinfo = dpaa2_switch_get_drvinfo, | |
| 180 | 181 | .get_link = ethtool_op_get_link, |
| 181 | − .get_link_ksettings = ethsw_get_link_ksettings, | |
| 182 | − .set_link_ksettings = ethsw_set_link_ksettings, | |
| 183 | − .get_strings = ethsw_ethtool_get_strings, | |
| 184 | − .get_ethtool_stats = ethsw_ethtool_get_stats, | |
| 185 | − .get_sset_count = ethsw_ethtool_get_sset_count, | |
| 182 | + .get_link_ksettings = dpaa2_switch_get_link_ksettings, | |
| 183 | + .set_link_ksettings = dpaa2_switch_set_link_ksettings, | |
| 184 | + .get_strings = dpaa2_switch_ethtool_get_strings, | |
| 185 | + .get_ethtool_stats = dpaa2_switch_ethtool_get_stats, | |
| 186 | + .get_sset_count = dpaa2_switch_ethtool_get_sset_count, | |
| 186 | 187 | }; |
| @@ -24,7 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | |
| 25 | 25 | #define DEFAULT_VLAN_ID 1 |
| 26 | 26 | |
| 27 | −static int ethsw_add_vlan(struct ethsw_core *ethsw, u16 vid) | |
| 27 | +static int dpaa2_switch_add_vlan(struct ethsw_core *ethsw, u16 vid) | |
| 28 | 28 | { |
| 29 | 29 | int err; |
| 30 | 30 | |
| @@ -43,7 +43,7 @@ static int ethsw_add_vlan(struct ethsw_core *ethsw, u16 vid) · 12 unmodified lines | ||
| 43 | 43 | return 0; |
| 44 | 44 | } |
| 45 | 45 | |
| 46 | −static bool ethsw_port_is_up(struct ethsw_port_priv *port_priv) | |
| 46 | +static bool dpaa2_switch_port_is_up(struct ethsw_port_priv *port_priv) | |
| 47 | 47 | { |
| 48 | 48 | struct net_device *netdev = port_priv->netdev; |
| 49 | 49 | struct dpsw_link_state state; |
| @@ -62,7 +62,7 @@ static bool ethsw_port_is_up(struct ethsw_port_priv *port_priv) · 12 unmodified lines | ||
| 62 | 62 | return state.up ? true : false; |
| 63 | 63 | } |
| 64 | 64 | |
| 65 | −static int ethsw_port_set_pvid(struct ethsw_port_priv *port_priv, u16 pvid) | |
| 65 | +static int dpaa2_switch_port_set_pvid(struct ethsw_port_priv *port_priv, u16 pvid) | |
| 66 | 66 | { |
| 67 | 67 | struct ethsw_core *ethsw = port_priv->ethsw_data; |
| 68 | 68 | struct net_device *netdev = port_priv->netdev; |
| @@ -80,7 +80,7 @@ static int ethsw_port_set_pvid(struct ethsw_port_priv *port_priv, u16 pvid) · 11 unmodified lines | ||
| 80 | 80 | tci_cfg.vlan_id = pvid; |
| 81 | 81 | |
| 82 | 82 | /* Interface needs to be down to change PVID */ |
| 83 | − up = ethsw_port_is_up(port_priv); | |
| 83 | + up = dpaa2_switch_port_is_up(port_priv); | |
| 84 | 84 | if (up) { |
| 85 | 85 | err = dpsw_if_disable(ethsw->mc_io, 0, |
| 86 | 86 | ethsw->dpsw_handle, |
| @@ -117,8 +117,8 @@ set_tci_error: · 30 unmodified lines | ||
| 117 | 117 | return err; |
| 118 | 118 | } |
| 119 | 119 | |
| 120 | −static int ethsw_port_add_vlan(struct ethsw_port_priv *port_priv, | |
| 121 | − u16 vid, u16 flags) | |
| 120 | +static int dpaa2_switch_port_add_vlan(struct ethsw_port_priv *port_priv, | |
| 121 | + u16 vid, u16 flags) | |
| 122 | 122 | { |
| 123 | 123 | struct ethsw_core *ethsw = port_priv->ethsw_data; |
| 124 | 124 | struct net_device *netdev = port_priv->netdev; |
| @@ -153,7 +153,7 @@ static int ethsw_port_add_vlan(struct ethsw_port_priv *port_priv, · 28 unmodified lines | ||
| 153 | 153 | } |
| 154 | 154 | |
| 155 | 155 | if (flags & BRIDGE_VLAN_INFO_PVID) { |
| 156 | − err = ethsw_port_set_pvid(port_priv, vid); | |
| 156 | + err = dpaa2_switch_port_set_pvid(port_priv, vid); | |
| 157 | 157 | if (err) |
| 158 | 158 | return err; |
| 159 | 159 | } |
| @@ -161,7 +161,7 @@ static int ethsw_port_add_vlan(struct ethsw_port_priv *port_priv, · 1 unmodified line | ||
| 161 | 161 | return 0; |
| 162 | 162 | } |
| 163 | 163 | |
| 164 | −static int ethsw_set_learning(struct ethsw_core *ethsw, bool enable) | |
| 164 | +static int dpaa2_switch_set_learning(struct ethsw_core *ethsw, bool enable) | |
| 165 | 165 | { |
| 166 | 166 | enum dpsw_fdb_learning_mode learn_mode; |
| 167 | 167 | int err; |
| @@ -182,7 +182,7 @@ static int ethsw_set_learning(struct ethsw_core *ethsw, bool enable) · 14 unmodified lines | ||
| 182 | 182 | return 0; |
| 183 | 183 | } |
| 184 | 184 | |
| 185 | −static int ethsw_port_set_flood(struct ethsw_port_priv *port_priv, bool enable) | |
| 185 | +static int dpaa2_switch_port_set_flood(struct ethsw_port_priv *port_priv, bool enable) | |
| 186 | 186 | { |
| 187 | 187 | int err; |
| 188 | 188 | |
| @@ -199,7 +199,7 @@ static int ethsw_port_set_flood(struct ethsw_port_priv *port_priv, bool enable) · 10 unmodified lines | ||
| 199 | 199 | return 0; |
| 200 | 200 | } |
| 201 | 201 | |
| 202 | −static int ethsw_port_set_stp_state(struct ethsw_port_priv *port_priv, u8 state) | |
| 202 | +static int dpaa2_switch_port_set_stp_state(struct ethsw_port_priv *port_priv, u8 state) | |
| 203 | 203 | { |
| 204 | 204 | struct dpsw_stp_cfg stp_cfg = { |
| 205 | 205 | .state = state, |
| @@ -229,7 +229,7 @@ static int ethsw_port_set_stp_state(struct ethsw_port_priv *port_priv, u8 state) · 23 unmodified lines | ||
| 229 | 229 | return 0; |
| 230 | 230 | } |
| 231 | 231 | |
| 232 | −static int ethsw_dellink_switch(struct ethsw_core *ethsw, u16 vid) | |
| 232 | +static int dpaa2_switch_dellink(struct ethsw_core *ethsw, u16 vid) | |
| 233 | 233 | { |
| 234 | 234 | struct ethsw_port_priv *ppriv_local = NULL; |
| 235 | 235 | int i, err; |
| @@ -252,8 +252,8 @@ static int ethsw_dellink_switch(struct ethsw_core *ethsw, u16 vid) · 16 unmodified lines | ||
| 252 | 252 | return 0; |
| 253 | 253 | } |
| 254 | 254 | |
| 255 | −static int ethsw_port_fdb_add_uc(struct ethsw_port_priv *port_priv, | |
| 256 | − const unsigned char *addr) | |
| 255 | +static int dpaa2_switch_port_fdb_add_uc(struct ethsw_port_priv *port_priv, | |
| 256 | + const unsigned char *addr) | |
| 257 | 257 | { |
| 258 | 258 | struct dpsw_fdb_unicast_cfg entry = {0}; |
| 259 | 259 | int err; |
| @@ -271,8 +271,8 @@ static int ethsw_port_fdb_add_uc(struct ethsw_port_priv *port_priv, · 11 unmodified lines | ||
| 271 | 271 | return err; |
| 272 | 272 | } |
| 273 | 273 | |
| 274 | −static int ethsw_port_fdb_del_uc(struct ethsw_port_priv *port_priv, | |
| 275 | − const unsigned char *addr) | |
| 274 | +static int dpaa2_switch_port_fdb_del_uc(struct ethsw_port_priv *port_priv, | |
| 275 | + const unsigned char *addr) | |
| 276 | 276 | { |
| 277 | 277 | struct dpsw_fdb_unicast_cfg entry = {0}; |
| 278 | 278 | int err; |
| @@ -291,8 +291,8 @@ static int ethsw_port_fdb_del_uc(struct ethsw_port_priv *port_priv, · 12 unmodified lines | ||
| 291 | 291 | return err; |
| 292 | 292 | } |
| 293 | 293 | |
| 294 | −static int ethsw_port_fdb_add_mc(struct ethsw_port_priv *port_priv, | |
| 295 | − const unsigned char *addr) | |
| 294 | +static int dpaa2_switch_port_fdb_add_mc(struct ethsw_port_priv *port_priv, | |
| 295 | + const unsigned char *addr) | |
| 296 | 296 | { |
| 297 | 297 | struct dpsw_fdb_multicast_cfg entry = {0}; |
| 298 | 298 | int err; |
| @@ -312,8 +312,8 @@ static int ethsw_port_fdb_add_mc(struct ethsw_port_priv *port_priv, · 13 unmodified lines | ||
| 312 | 312 | return err; |
| 313 | 313 | } |
| 314 | 314 | |
| 315 | −static int ethsw_port_fdb_del_mc(struct ethsw_port_priv *port_priv, | |
| 316 | − const unsigned char *addr) | |
| 315 | +static int dpaa2_switch_port_fdb_del_mc(struct ethsw_port_priv *port_priv, | |
| 316 | + const unsigned char *addr) | |
| 317 | 317 | { |
| 318 | 318 | struct dpsw_fdb_multicast_cfg entry = {0}; |
| 319 | 319 | int err; |
| @@ -333,33 +333,33 @@ static int ethsw_port_fdb_del_mc(struct ethsw_port_priv *port_priv, · 13 unmodified lines | ||
| 333 | 333 | return err; |
| 334 | 334 | } |
| 335 | 335 | |
| 336 | −static int port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], | |
| 337 | − struct net_device *dev, const unsigned char *addr, | |
| 338 | − u16 vid, u16 flags, | |
| 339 | − struct netlink_ext_ack *extack) | |
| 336 | +static int dpaa2_switch_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], | |
| 337 | + struct net_device *dev, const unsigned char *addr, | |
| 338 | + u16 vid, u16 flags, | |
| 339 | + struct netlink_ext_ack *extack) | |
| 340 | 340 | { |
| 341 | 341 | if (is_unicast_ether_addr(addr)) |
| 342 | − return ethsw_port_fdb_add_uc(netdev_priv(dev), | |
| 343 | − addr); | |
| 342 | + return dpaa2_switch_port_fdb_add_uc(netdev_priv(dev), | |
| 343 | + addr); | |
| 344 | 344 | else |
| 345 | − return ethsw_port_fdb_add_mc(netdev_priv(dev), | |
| 346 | − addr); | |
| 345 | + return dpaa2_switch_port_fdb_add_mc(netdev_priv(dev), | |
| 346 | + addr); | |
| 347 | 347 | } |
| 348 | 348 | |
| 349 | −static int port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], | |
| 350 | − struct net_device *dev, | |
| 351 | − const unsigned char *addr, u16 vid) | |
| 349 | +static int dpaa2_switch_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], | |
| 350 | + struct net_device *dev, | |
| 351 | + const unsigned char *addr, u16 vid) | |
| 352 | 352 | { |
| 353 | 353 | if (is_unicast_ether_addr(addr)) |
| 354 | − return ethsw_port_fdb_del_uc(netdev_priv(dev), | |
| 355 | − addr); | |
| 354 | + return dpaa2_switch_port_fdb_del_uc(netdev_priv(dev), | |
| 355 | + addr); | |
| 356 | 356 | else |
| 357 | − return ethsw_port_fdb_del_mc(netdev_priv(dev), | |
| 358 | − addr); | |
| 357 | + return dpaa2_switch_port_fdb_del_mc(netdev_priv(dev), | |
| 358 | + addr); | |
| 359 | 359 | } |
| 360 | 360 | |
| 361 | −static void port_get_stats(struct net_device *netdev, | |
| 362 | − struct rtnl_link_stats64 *stats) | |
| 361 | +static void dpaa2_switch_port_get_stats(struct net_device *netdev, | |
| 362 | + struct rtnl_link_stats64 *stats) | |
| 363 | 363 | { |
| 364 | 364 | struct ethsw_port_priv *port_priv = netdev_priv(netdev); |
| 365 | 365 | u64 tmp; |
| @@ -424,26 +424,26 @@ error: · 58 unmodified lines | ||
| 424 | 424 | netdev_err(netdev, "dpsw_if_get_counter err %d\n", err); |
| 425 | 425 | } |
| 426 | 426 | |
| 427 | −static bool port_has_offload_stats(const struct net_device *netdev, | |
| 428 | − int attr_id) | |
| 427 | +static bool dpaa2_switch_port_has_offload_stats(const struct net_device *netdev, | |
| 428 | + int attr_id) | |
| 429 | 429 | { |
| 430 | 430 | return (attr_id == IFLA_OFFLOAD_XSTATS_CPU_HIT); |
| 431 | 431 | } |
| 432 | 432 | |
| 433 | −static int port_get_offload_stats(int attr_id, | |
| 434 | − const struct net_device *netdev, | |
| 435 | − void *sp) | |
| 433 | +static int dpaa2_switch_port_get_offload_stats(int attr_id, | |
| 434 | + const struct net_device *netdev, | |
| 435 | + void *sp) | |
| 436 | 436 | { |
| 437 | 437 | switch (attr_id) { |
| 438 | 438 | case IFLA_OFFLOAD_XSTATS_CPU_HIT: |
| 439 | − port_get_stats((struct net_device *)netdev, sp); | |
| 439 | + dpaa2_switch_port_get_stats((struct net_device *)netdev, sp); | |
| 440 | 440 | return 0; |
| 441 | 441 | } |
| 442 | 442 | |
| 443 | 443 | return -EINVAL; |
| 444 | 444 | } |
| 445 | 445 | |
| 446 | −static int port_change_mtu(struct net_device *netdev, int mtu) | |
| 446 | +static int dpaa2_switch_port_change_mtu(struct net_device *netdev, int mtu) | |
| 447 | 447 | { |
| 448 | 448 | struct ethsw_port_priv *port_priv = netdev_priv(netdev); |
| 449 | 449 | int err; |
| @@ -463,7 +463,7 @@ static int port_change_mtu(struct net_device *netdev, int mtu) · 13 unmodified lines | ||
| 463 | 463 | return 0; |
| 464 | 464 | } |
| 465 | 465 | |
| 466 | −static int port_carrier_state_sync(struct net_device *netdev) | |
| 466 | +static int dpaa2_switch_port_carrier_state_sync(struct net_device *netdev) | |
| 467 | 467 | { |
| 468 | 468 | struct ethsw_port_priv *port_priv = netdev_priv(netdev); |
| 469 | 469 | struct dpsw_link_state state; |
| @@ -496,7 +496,7 @@ static int port_carrier_state_sync(struct net_device *netdev) · 26 unmodified lines | ||
| 496 | 496 | return 0; |
| 497 | 497 | } |
| 498 | 498 | |
| 499 | −static int port_open(struct net_device *netdev) | |
| 499 | +static int dpaa2_switch_port_open(struct net_device *netdev) | |
| 500 | 500 | { |
| 501 | 501 | struct ethsw_port_priv *port_priv = netdev_priv(netdev); |
| 502 | 502 | int err; |
| @@ -520,10 +520,10 @@ static int port_open(struct net_device *netdev) · 17 unmodified lines | ||
| 520 | 520 | } |
| 521 | 521 | |
| 522 | 522 | /* sync carrier state */ |
| 523 | − err = port_carrier_state_sync(netdev); | |
| 523 | + err = dpaa2_switch_port_carrier_state_sync(netdev); | |
| 524 | 524 | if (err) { |
| 525 | 525 | netdev_err(netdev, |
| 526 | − "port_carrier_state_sync err %d\n", err); | |
| 526 | + "dpaa2_switch_port_carrier_state_sync err %d\n", err); | |
| 527 | 527 | goto err_carrier_sync; |
| 528 | 528 | } |
| 529 | 529 | |
| @@ -536,7 +536,7 @@ err_carrier_sync: · 6 unmodified lines | ||
| 536 | 536 | return err; |
| 537 | 537 | } |
| 538 | 538 | |
| 539 | −static int port_stop(struct net_device *netdev) | |
| 539 | +static int dpaa2_switch_port_stop(struct net_device *netdev) | |
| 540 | 540 | { |
| 541 | 541 | struct ethsw_port_priv *port_priv = netdev_priv(netdev); |
| 542 | 542 | int err; |
| @@ -552,8 +552,8 @@ static int port_stop(struct net_device *netdev) · 9 unmodified lines | ||
| 552 | 552 | return 0; |
| 553 | 553 | } |
| 554 | 554 | |
| 555 | −static netdev_tx_t port_dropframe(struct sk_buff *skb, | |
| 556 | − struct net_device *netdev) | |
| 555 | +static netdev_tx_t dpaa2_switch_port_dropframe(struct sk_buff *skb, | |
| 556 | + struct net_device *netdev) | |
| 557 | 557 | { |
| 558 | 558 | /* we don't support I/O for now, drop the frame */ |
| 559 | 559 | dev_kfree_skb_any(skb); |
| @@ -561,8 +561,8 @@ static netdev_tx_t port_dropframe(struct sk_buff *skb, · 1 unmodified line | ||
| 561 | 561 | return NETDEV_TX_OK; |
| 562 | 562 | } |
| 563 | 563 | |
| 564 | −static int swdev_get_port_parent_id(struct net_device *dev, | |
| 565 | − struct netdev_phys_item_id *ppid) | |
| 564 | +static int dpaa2_switch_port_parent_id(struct net_device *dev, | |
| 565 | + struct netdev_phys_item_id *ppid) | |
| 566 | 566 | { |
| 567 | 567 | struct ethsw_port_priv *port_priv = netdev_priv(dev); |
| 568 | 568 | |
| @@ -572,8 +572,8 @@ static int swdev_get_port_parent_id(struct net_device *dev, · 3 unmodified lines | ||
| 572 | 572 | return 0; |
| 573 | 573 | } |
| 574 | 574 | |
| 575 | −static int port_get_phys_name(struct net_device *netdev, char *name, | |
| 576 | − size_t len) | |
| 575 | +static int dpaa2_switch_port_get_phys_name(struct net_device *netdev, char *name, | |
| 576 | + size_t len) | |
| 577 | 577 | { |
| 578 | 578 | struct ethsw_port_priv *port_priv = netdev_priv(netdev); |
| 579 | 579 | int err; |
| @@ -592,8 +592,8 @@ struct ethsw_dump_ctx { · 12 unmodified lines | ||
| 592 | 592 | int idx; |
| 593 | 593 | }; |
| 594 | 594 | |
| 595 | −static int ethsw_fdb_do_dump(struct fdb_dump_entry *entry, | |
| 596 | − struct ethsw_dump_ctx *dump) | |
| 595 | +static int dpaa2_switch_fdb_dump_nl(struct fdb_dump_entry *entry, | |
| 596 | + struct ethsw_dump_ctx *dump) | |
| 597 | 597 | { |
| 598 | 598 | int is_dynamic = entry->type & DPSW_FDB_ENTRY_DINAMIC; |
| 599 | 599 | u32 portid = NETLINK_CB(dump->cb->skb).portid; |
| @@ -632,8 +632,8 @@ nla_put_failure: · 32 unmodified lines | ||
| 632 | 632 | return -EMSGSIZE; |
| 633 | 633 | } |
| 634 | 634 | |
| 635 | −static int port_fdb_valid_entry(struct fdb_dump_entry *entry, | |
| 636 | − struct ethsw_port_priv *port_priv) | |
| 635 | +static int dpaa2_switch_port_fdb_valid_entry(struct fdb_dump_entry *entry, | |
| 636 | + struct ethsw_port_priv *port_priv) | |
| 637 | 637 | { |
| 638 | 638 | int idx = port_priv->idx; |
| 639 | 639 | int valid; |
| @@ -646,9 +646,9 @@ static int port_fdb_valid_entry(struct fdb_dump_entry *entry, · 6 unmodified lines | ||
| 646 | 646 | return valid; |
| 647 | 647 | } |
| 648 | 648 | |
| 649 | −static int port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, | |
| 650 | − struct net_device *net_dev, | |
| 651 | − struct net_device *filter_dev, int *idx) | |
| 649 | +static int dpaa2_switch_port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, | |
| 650 | + struct net_device *net_dev, | |
| 651 | + struct net_device *filter_dev, int *idx) | |
| 652 | 652 | { |
| 653 | 653 | struct ethsw_port_priv *port_priv = netdev_priv(net_dev); |
| 654 | 654 | struct ethsw_core *ethsw = port_priv->ethsw_data; |
| @@ -693,10 +693,10 @@ static int port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, · 38 unmodified lines | ||
| 693 | 693 | for (i = 0; i < num_fdb_entries; i++) { |
| 694 | 694 | fdb_entry = fdb_entries[i]; |
| 695 | 695 | |
| 696 | − if (!port_fdb_valid_entry(&fdb_entry, port_priv)) | |
| 696 | + if (!dpaa2_switch_port_fdb_valid_entry(&fdb_entry, port_priv)) | |
| 697 | 697 | continue; |
| 698 | 698 | |
| 699 | − err = ethsw_fdb_do_dump(&fdb_entry, &dump); | |
| 699 | + err = dpaa2_switch_fdb_dump_nl(&fdb_entry, &dump); | |
| 700 | 700 | if (err) |
| 701 | 701 | goto end; |
| 702 | 702 | } |
| @@ -715,7 +715,7 @@ err_map: · 12 unmodified lines | ||
| 715 | 715 | return err; |
| 716 | 716 | } |
| 717 | 717 | |
| 718 | −static int ethsw_port_set_mac_addr(struct ethsw_port_priv *port_priv) | |
| 718 | +static int dpaa2_switch_port_set_mac_addr(struct ethsw_port_priv *port_priv) | |
| 719 | 719 | { |
| 720 | 720 | struct ethsw_core *ethsw = port_priv->ethsw_data; |
| 721 | 721 | struct net_device *net_dev = port_priv->netdev; |
| @@ -755,30 +755,30 @@ static int ethsw_port_set_mac_addr(struct ethsw_port_priv *port_priv) · 33 unmodified lines | ||
| 755 | 755 | return 0; |
| 756 | 756 | } |
| 757 | 757 | |
| 758 | −static const struct net_device_ops ethsw_port_ops = { | |
| 759 | − .ndo_open = port_open, | |
| 760 | − .ndo_stop = port_stop, | |
| 758 | +static const struct net_device_ops dpaa2_switch_port_ops = { | |
| 759 | + .ndo_open = dpaa2_switch_port_open, | |
| 760 | + .ndo_stop = dpaa2_switch_port_stop, | |
| 761 | 761 | |
| 762 | 762 | .ndo_set_mac_address = eth_mac_addr, |
| 763 | − .ndo_get_stats64 = port_get_stats, | |
| 764 | − .ndo_change_mtu = port_change_mtu, | |
| 765 | − .ndo_has_offload_stats = port_has_offload_stats, | |
| 766 | − .ndo_get_offload_stats = port_get_offload_stats, | |
| 767 | − .ndo_fdb_add = port_fdb_add, | |
| 768 | − .ndo_fdb_del = port_fdb_del, | |
| 769 | − .ndo_fdb_dump = port_fdb_dump, | |
| 770 | − | |
| 771 | − .ndo_start_xmit = port_dropframe, | |
| 772 | − .ndo_get_port_parent_id = swdev_get_port_parent_id, | |
| 773 | − .ndo_get_phys_port_name = port_get_phys_name, | |
| 763 | + .ndo_get_stats64 = dpaa2_switch_port_get_stats, | |
| 764 | + .ndo_change_mtu = dpaa2_switch_port_change_mtu, | |
| 765 | + .ndo_has_offload_stats = dpaa2_switch_port_has_offload_stats, | |
| 766 | + .ndo_get_offload_stats = dpaa2_switch_port_get_offload_stats, | |
| 767 | + .ndo_fdb_add = dpaa2_switch_port_fdb_add, | |
| 768 | + .ndo_fdb_del = dpaa2_switch_port_fdb_del, | |
| 769 | + .ndo_fdb_dump = dpaa2_switch_port_fdb_dump, | |
| 770 | + | |
| 771 | + .ndo_start_xmit = dpaa2_switch_port_dropframe, | |
| 772 | + .ndo_get_port_parent_id = dpaa2_switch_port_parent_id, | |
| 773 | + .ndo_get_phys_port_name = dpaa2_switch_port_get_phys_name, | |
| 774 | 774 | }; |
| 775 | 775 | |
| 776 | −static bool ethsw_port_dev_check(const struct net_device *netdev, | |
| 777 | − struct notifier_block *nb) | |
| 776 | +static bool dpaa2_switch_port_dev_check(const struct net_device *netdev, | |
| 777 | + struct notifier_block *nb) | |
| 778 | 778 | { |
| 779 | 779 | struct ethsw_port_priv *port_priv = netdev_priv(netdev); |
| 780 | 780 | |
| 781 | − if (netdev->netdev_ops == ðsw_port_ops && | |
| 781 | + if (netdev->netdev_ops == &dpaa2_switch_port_ops && | |
| 782 | 782 | (!nb || &port_priv->ethsw_data->port_nb == nb || |
| 783 | 783 | &port_priv->ethsw_data->port_switchdev_nb == nb || |
| 784 | 784 | &port_priv->ethsw_data->port_switchdevb_nb == nb)) |
| @@ -787,17 +787,17 @@ static bool ethsw_port_dev_check(const struct net_device *netdev, · 2 unmodified lines | ||
| 787 | 787 | return false; |
| 788 | 788 | } |
| 789 | 789 | |
| 790 | −static void ethsw_links_state_update(struct ethsw_core *ethsw) | |
| 790 | +static void dpaa2_switch_links_state_update(struct ethsw_core *ethsw) | |
| 791 | 791 | { |
| 792 | 792 | int i; |
| 793 | 793 | |
| 794 | 794 | for (i = 0; i < ethsw->sw_attr.num_ifs; i++) { |
| 795 | − port_carrier_state_sync(ethsw->ports[i]->netdev); | |
| 796 | − ethsw_port_set_mac_addr(ethsw->ports[i]); | |
| 795 | + dpaa2_switch_port_carrier_state_sync(ethsw->ports[i]->netdev); | |
| 796 | + dpaa2_switch_port_set_mac_addr(ethsw->ports[i]); | |
| 797 | 797 | } |
| 798 | 798 | } |
| 799 | 799 | |
| 800 | −static irqreturn_t ethsw_irq0_handler_thread(int irq_num, void *arg) | |
| 800 | +static irqreturn_t dpaa2_switch_irq0_handler_thread(int irq_num, void *arg) | |
| 801 | 801 | { |
| 802 | 802 | struct device *dev = (struct device *)arg; |
| 803 | 803 | struct ethsw_core *ethsw = dev_get_drvdata(dev); |
| @@ -819,13 +819,13 @@ static irqreturn_t ethsw_irq0_handler_thread(int irq_num, void *arg) · 15 unmodified lines | ||
| 819 | 819 | } |
| 820 | 820 | |
| 821 | 821 | if (status & DPSW_IRQ_EVENT_LINK_CHANGED) |
| 822 | − ethsw_links_state_update(ethsw); | |
| 822 | + dpaa2_switch_links_state_update(ethsw); | |
| 823 | 823 | |
| 824 | 824 | out: |
| 825 | 825 | return IRQ_HANDLED; |
| 826 | 826 | } |
| 827 | 827 | |
| 828 | −static int ethsw_setup_irqs(struct fsl_mc_device *sw_dev) | |
| 828 | +static int dpaa2_switch_setup_irqs(struct fsl_mc_device *sw_dev) | |
| 829 | 829 | { |
| 830 | 830 | struct device *dev = &sw_dev->dev; |
| 831 | 831 | struct ethsw_core *ethsw = dev_get_drvdata(dev); |
| @@ -855,7 +855,7 @@ static int ethsw_setup_irqs(struct fsl_mc_device *sw_dev) · 23 unmodified lines | ||
| 855 | 855 | |
| 856 | 856 | err = devm_request_threaded_irq(dev, irq->msi_desc->irq, |
| 857 | 857 | NULL, |
| 858 | − ethsw_irq0_handler_thread, | |
| 858 | + dpaa2_switch_irq0_handler_thread, | |
| 859 | 859 | IRQF_NO_SUSPEND | IRQF_ONESHOT, |
| 860 | 860 | dev_name(dev), dev); |
| 861 | 861 | if (err) { |
| @@ -886,7 +886,7 @@ free_irq: · 24 unmodified lines | ||
| 886 | 886 | return err; |
| 887 | 887 | } |
| 888 | 888 | |
| 889 | −static void ethsw_teardown_irqs(struct fsl_mc_device *sw_dev) | |
| 889 | +static void dpaa2_switch_teardown_irqs(struct fsl_mc_device *sw_dev) | |
| 890 | 890 | { |
| 891 | 891 | struct device *dev = &sw_dev->dev; |
| 892 | 892 | struct ethsw_core *ethsw = dev_get_drvdata(dev); |
| @@ -900,21 +900,21 @@ static void ethsw_teardown_irqs(struct fsl_mc_device *sw_dev) · 7 unmodified lines | ||
| 900 | 900 | fsl_mc_free_irqs(sw_dev); |
| 901 | 901 | } |
| 902 | 902 | |
| 903 | −static int port_attr_stp_state_set(struct net_device *netdev, | |
| 904 | − struct switchdev_trans *trans, | |
| 905 | − u8 state) | |
| 903 | +static int dpaa2_switch_port_attr_stp_state_set(struct net_device *netdev, | |
| 904 | + struct switchdev_trans *trans, | |
| 905 | + u8 state) | |
| 906 | 906 | { |
| 907 | 907 | struct ethsw_port_priv *port_priv = netdev_priv(netdev); |
| 908 | 908 | |
| 909 | 909 | if (switchdev_trans_ph_prepare(trans)) |
| 910 | 910 | return 0; |
| 911 | 911 | |
| 912 | − return ethsw_port_set_stp_state(port_priv, state); | |
| 912 | + return dpaa2_switch_port_set_stp_state(port_priv, state); | |
| 913 | 913 | } |
| 914 | 914 | |
| 915 | −static int port_attr_br_flags_pre_set(struct net_device *netdev, | |
| 916 | − struct switchdev_trans *trans, | |
| 917 | − unsigned long flags) | |
| 915 | +static int dpaa2_switch_port_attr_br_flags_pre_set(struct net_device *netdev, | |
| 916 | + struct switchdev_trans *trans, | |
| 917 | + unsigned long flags) | |
| 918 | 918 | { |
| 919 | 919 | if (flags & ~(BR_LEARNING | BR_FLOOD)) |
| 920 | 920 | return -EINVAL; |
| @@ -922,9 +922,9 @@ static int port_attr_br_flags_pre_set(struct net_device *netdev, · 1 unmodified line | ||
| 922 | 922 | return 0; |
| 923 | 923 | } |
| 924 | 924 | |
| 925 | −static int port_attr_br_flags_set(struct net_device *netdev, | |
| 926 | − struct switchdev_trans *trans, | |
| 927 | − unsigned long flags) | |
| 925 | +static int dpaa2_switch_port_attr_br_flags_set(struct net_device *netdev, | |
| 926 | + struct switchdev_trans *trans, | |
| 927 | + unsigned long flags) | |
| 928 | 928 | { |
| 929 | 929 | struct ethsw_port_priv *port_priv = netdev_priv(netdev); |
| 930 | 930 | int err = 0; |
| @@ -933,35 +933,35 @@ static int port_attr_br_flags_set(struct net_device *netdev, · 2 unmodified lines | ||
| 933 | 933 | return 0; |
| 934 | 934 | |
| 935 | 935 | /* Learning is enabled per switch */ |
| 936 | − err = ethsw_set_learning(port_priv->ethsw_data, | |
| 937 | − !!(flags & BR_LEARNING)); | |
| 936 | + err = dpaa2_switch_set_learning(port_priv->ethsw_data, | |
| 937 | + !!(flags & BR_LEARNING)); | |
| 938 | 938 | if (err) |
| 939 | 939 | goto exit; |
| 940 | 940 | |
| 941 | − err = ethsw_port_set_flood(port_priv, !!(flags & BR_FLOOD)); | |
| 941 | + err = dpaa2_switch_port_set_flood(port_priv, !!(flags & BR_FLOOD)); | |
| 942 | 942 | |
| 943 | 943 | exit: |
| 944 | 944 | return err; |
| 945 | 945 | } |
| 946 | 946 | |
| 947 | −static int swdev_port_attr_set(struct net_device *netdev, | |
| 948 | − const struct switchdev_attr *attr, | |
| 949 | − struct switchdev_trans *trans) | |
| 947 | +static int dpaa2_switch_port_attr_set(struct net_device *netdev, | |
| 948 | + const struct switchdev_attr *attr, | |
| 949 | + struct switchdev_trans *trans) | |
| 950 | 950 | { |
| 951 | 951 | int err = 0; |
| 952 | 952 | |
| 953 | 953 | switch (attr->id) { |
| 954 | 954 | case SWITCHDEV_ATTR_ID_PORT_STP_STATE: |
| 955 | − err = port_attr_stp_state_set(netdev, trans, | |
| 956 | − attr->u.stp_state); | |
| 955 | + err = dpaa2_switch_port_attr_stp_state_set(netdev, trans, | |
| 956 | + attr->u.stp_state); | |
| 957 | 957 | break; |
| 958 | 958 | case SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS: |
| 959 | − err = port_attr_br_flags_pre_set(netdev, trans, | |
| 960 | − attr->u.brport_flags); | |
| 959 | + err = dpaa2_switch_port_attr_br_flags_pre_set(netdev, trans, | |
| 960 | + attr->u.brport_flags); | |
| 961 | 961 | break; |
| 962 | 962 | case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS: |
| 963 | − err = port_attr_br_flags_set(netdev, trans, | |
| 964 | − attr->u.brport_flags); | |
| 963 | + err = dpaa2_switch_port_attr_br_flags_set(netdev, trans, | |
| 964 | + attr->u.brport_flags); | |
| 965 | 965 | break; |
| 966 | 966 | case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING: |
| 967 | 967 | /* VLANs are supported by default */ |
| @@ -974,9 +974,9 @@ static int swdev_port_attr_set(struct net_device *netdev, · 6 unmodified lines | ||
| 974 | 974 | return err; |
| 975 | 975 | } |
| 976 | 976 | |
| 977 | −static int port_vlans_add(struct net_device *netdev, | |
| 978 | − const struct switchdev_obj_port_vlan *vlan, | |
| 979 | − struct switchdev_trans *trans) | |
| 977 | +static int dpaa2_switch_port_vlans_add(struct net_device *netdev, | |
| 978 | + const struct switchdev_obj_port_vlan *vlan, | |
| 979 | + struct switchdev_trans *trans) | |
| 980 | 980 | { |
| 981 | 981 | struct ethsw_port_priv *port_priv = netdev_priv(netdev); |
| 982 | 982 | struct ethsw_core *ethsw = port_priv->ethsw_data; |
| @@ -1004,13 +1004,13 @@ static int port_vlans_add(struct net_device *netdev, · 21 unmodified lines | ||
| 1004 | 1004 | for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) { |
| 1005 | 1005 | if (!port_priv->ethsw_data->vlans[vid]) { |
| 1006 | 1006 | /* this is a new VLAN */ |
| 1007 | − err = ethsw_add_vlan(port_priv->ethsw_data, vid); | |
| 1007 | + err = dpaa2_switch_add_vlan(port_priv->ethsw_data, vid); | |
| 1008 | 1008 | if (err) |
| 1009 | 1009 | return err; |
| 1010 | 1010 | |
| 1011 | 1011 | port_priv->ethsw_data->vlans[vid] |= ETHSW_VLAN_GLOBAL; |
| 1012 | 1012 | } |
| 1013 | − err = ethsw_port_add_vlan(port_priv, vid, vlan->flags); | |
| 1013 | + err = dpaa2_switch_port_add_vlan(port_priv, vid, vlan->flags); | |
| 1014 | 1014 | if (err) |
| 1015 | 1015 | break; |
| 1016 | 1016 | } |
| @@ -1018,8 +1018,8 @@ static int port_vlans_add(struct net_device *netdev, · 1 unmodified line | ||
| 1018 | 1018 | return err; |
| 1019 | 1019 | } |
| 1020 | 1020 | |
| 1021 | −static int port_lookup_address(struct net_device *netdev, int is_uc, | |
| 1022 | − const unsigned char *addr) | |
| 1021 | +static int dpaa2_switch_port_lookup_address(struct net_device *netdev, int is_uc, | |
| 1022 | + const unsigned char *addr) | |
| 1023 | 1023 | { |
| 1024 | 1024 | struct netdev_hw_addr_list *list = (is_uc) ? &netdev->uc : &netdev->mc; |
| 1025 | 1025 | struct netdev_hw_addr *ha; |
| @@ -1035,9 +1035,9 @@ static int port_lookup_address(struct net_device *netdev, int is_uc, · 9 unmodified lines | ||
| 1035 | 1035 | return 0; |
| 1036 | 1036 | } |
| 1037 | 1037 | |
| 1038 | −static int port_mdb_add(struct net_device *netdev, | |
| 1039 | − const struct switchdev_obj_port_mdb *mdb, | |
| 1040 | − struct switchdev_trans *trans) | |
| 1038 | +static int dpaa2_switch_port_mdb_add(struct net_device *netdev, | |
| 1039 | + const struct switchdev_obj_port_mdb *mdb, | |
| 1040 | + struct switchdev_trans *trans) | |
| 1041 | 1041 | { |
| 1042 | 1042 | struct ethsw_port_priv *port_priv = netdev_priv(netdev); |
| 1043 | 1043 | int err; |
| @@ -1046,38 +1046,38 @@ static int port_mdb_add(struct net_device *netdev, · 2 unmodified lines | ||
| 1046 | 1046 | return 0; |
| 1047 | 1047 | |
| 1048 | 1048 | /* Check if address is already set on this port */ |
| 1049 | − if (port_lookup_address(netdev, 0, mdb->addr)) | |
| 1049 | + if (dpaa2_switch_port_lookup_address(netdev, 0, mdb->addr)) | |
| 1050 | 1050 | return -EEXIST; |
| 1051 | 1051 | |
| 1052 | − err = ethsw_port_fdb_add_mc(port_priv, mdb->addr); | |
| 1052 | + err = dpaa2_switch_port_fdb_add_mc(port_priv, mdb->addr); | |
| 1053 | 1053 | if (err) |
| 1054 | 1054 | return err; |
| 1055 | 1055 | |
| 1056 | 1056 | err = dev_mc_add(netdev, mdb->addr); |
| 1057 | 1057 | if (err) { |
| 1058 | 1058 | netdev_err(netdev, "dev_mc_add err %d\n", err); |
| 1059 | − ethsw_port_fdb_del_mc(port_priv, mdb->addr); | |
| 1059 | + dpaa2_switch_port_fdb_del_mc(port_priv, mdb->addr); | |
| 1060 | 1060 | } |
| 1061 | 1061 | |
| 1062 | 1062 | return err; |
| 1063 | 1063 | } |
| 1064 | 1064 | |
| 1065 | −static int swdev_port_obj_add(struct net_device *netdev, | |
| 1066 | − const struct switchdev_obj *obj, | |
| 1067 | − struct switchdev_trans *trans) | |
| 1065 | +static int dpaa2_switch_port_obj_add(struct net_device *netdev, | |
| 1066 | + const struct switchdev_obj *obj, | |
| 1067 | + struct switchdev_trans *trans) | |
| 1068 | 1068 | { |
| 1069 | 1069 | int err; |
| 1070 | 1070 | |
| 1071 | 1071 | switch (obj->id) { |
| 1072 | 1072 | case SWITCHDEV_OBJ_ID_PORT_VLAN: |
| 1073 | − err = port_vlans_add(netdev, | |
| 1074 | − SWITCHDEV_OBJ_PORT_VLAN(obj), | |
| 1075 | − trans); | |
| 1073 | + err = dpaa2_switch_port_vlans_add(netdev, | |
| 1074 | + SWITCHDEV_OBJ_PORT_VLAN(obj), | |
| 1075 | + trans); | |
| 1076 | 1076 | break; |
| 1077 | 1077 | case SWITCHDEV_OBJ_ID_PORT_MDB: |
| 1078 | − err = port_mdb_add(netdev, | |
| 1079 | − SWITCHDEV_OBJ_PORT_MDB(obj), | |
| 1080 | − trans); | |
| 1078 | + err = dpaa2_switch_port_mdb_add(netdev, | |
| 1079 | + SWITCHDEV_OBJ_PORT_MDB(obj), | |
| 1080 | + trans); | |
| 1081 | 1081 | break; |
| 1082 | 1082 | default: |
| 1083 | 1083 | err = -EOPNOTSUPP; |
| @@ -1087,7 +1087,7 @@ static int swdev_port_obj_add(struct net_device *netdev, · 3 unmodified lines | ||
| 1087 | 1087 | return err; |
| 1088 | 1088 | } |
| 1089 | 1089 | |
| 1090 | −static int ethsw_port_del_vlan(struct ethsw_port_priv *port_priv, u16 vid) | |
| 1090 | +static int dpaa2_switch_port_del_vlan(struct ethsw_port_priv *port_priv, u16 vid) | |
| 1091 | 1091 | { |
| 1092 | 1092 | struct ethsw_core *ethsw = port_priv->ethsw_data; |
| 1093 | 1093 | struct net_device *netdev = port_priv->netdev; |
| @@ -1098,7 +1098,7 @@ static int ethsw_port_del_vlan(struct ethsw_port_priv *port_priv, u16 vid) · 4 unmodified lines | ||
| 1098 | 1098 | return -ENOENT; |
| 1099 | 1099 | |
| 1100 | 1100 | if (port_priv->vlans[vid] & ETHSW_VLAN_PVID) { |
| 1101 | − err = ethsw_port_set_pvid(port_priv, 0); | |
| 1101 | + err = dpaa2_switch_port_set_pvid(port_priv, 0); | |
| 1102 | 1102 | if (err) |
| 1103 | 1103 | return err; |
| 1104 | 1104 | } |
| @@ -1136,7 +1136,7 @@ static int ethsw_port_del_vlan(struct ethsw_port_priv *port_priv, u16 vid) · 31 unmodified lines | ||
| 1136 | 1136 | |
| 1137 | 1137 | ethsw->vlans[vid] &= ~ETHSW_VLAN_GLOBAL; |
| 1138 | 1138 | |
| 1139 | − err = ethsw_dellink_switch(ethsw, vid); | |
| 1139 | + err = dpaa2_switch_dellink(ethsw, vid); | |
| 1140 | 1140 | if (err) |
| 1141 | 1141 | return err; |
| 1142 | 1142 | } |
| @@ -1144,8 +1144,8 @@ static int ethsw_port_del_vlan(struct ethsw_port_priv *port_priv, u16 vid) · 1 unmodified line | ||
| 1144 | 1144 | return 0; |
| 1145 | 1145 | } |
| 1146 | 1146 | |
| 1147 | −static int port_vlans_del(struct net_device *netdev, | |
| 1148 | − const struct switchdev_obj_port_vlan *vlan) | |
| 1147 | +static int dpaa2_switch_port_vlans_del(struct net_device *netdev, | |
| 1148 | + const struct switchdev_obj_port_vlan *vlan) | |
| 1149 | 1149 | { |
| 1150 | 1150 | struct ethsw_port_priv *port_priv = netdev_priv(netdev); |
| 1151 | 1151 | int vid, err = 0; |
| @@ -1154,7 +1154,7 @@ static int port_vlans_del(struct net_device *netdev, · 2 unmodified lines | ||
| 1154 | 1154 | return -EOPNOTSUPP; |
| 1155 | 1155 | |
| 1156 | 1156 | for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) { |
| 1157 | − err = ethsw_port_del_vlan(port_priv, vid); | |
| 1157 | + err = dpaa2_switch_port_del_vlan(port_priv, vid); | |
| 1158 | 1158 | if (err) |
| 1159 | 1159 | break; |
| 1160 | 1160 | } |
| @@ -1162,16 +1162,16 @@ static int port_vlans_del(struct net_device *netdev, · 1 unmodified line | ||
| 1162 | 1162 | return err; |
| 1163 | 1163 | } |
| 1164 | 1164 | |
| 1165 | −static int port_mdb_del(struct net_device *netdev, | |
| 1166 | − const struct switchdev_obj_port_mdb *mdb) | |
| 1165 | +static int dpaa2_switch_port_mdb_del(struct net_device *netdev, | |
| 1166 | + const struct switchdev_obj_port_mdb *mdb) | |
| 1167 | 1167 | { |
| 1168 | 1168 | struct ethsw_port_priv *port_priv = netdev_priv(netdev); |
| 1169 | 1169 | int err; |
| 1170 | 1170 | |
| 1171 | − if (!port_lookup_address(netdev, 0, mdb->addr)) | |
| 1171 | + if (!dpaa2_switch_port_lookup_address(netdev, 0, mdb->addr)) | |
| 1172 | 1172 | return -ENOENT; |
| 1173 | 1173 | |
| 1174 | − err = ethsw_port_fdb_del_mc(port_priv, mdb->addr); | |
| 1174 | + err = dpaa2_switch_port_fdb_del_mc(port_priv, mdb->addr); | |
| 1175 | 1175 | if (err) |
| 1176 | 1176 | return err; |
| 1177 | 1177 | |
| @@ -1184,17 +1184,17 @@ static int port_mdb_del(struct net_device *netdev, · 6 unmodified lines | ||
| 1184 | 1184 | return err; |
| 1185 | 1185 | } |
| 1186 | 1186 | |
| 1187 | −static int swdev_port_obj_del(struct net_device *netdev, | |
| 1188 | − const struct switchdev_obj *obj) | |
| 1187 | +static int dpaa2_switch_port_obj_del(struct net_device *netdev, | |
| 1188 | + const struct switchdev_obj *obj) | |
| 1189 | 1189 | { |
| 1190 | 1190 | int err; |
| 1191 | 1191 | |
| 1192 | 1192 | switch (obj->id) { |
| 1193 | 1193 | case SWITCHDEV_OBJ_ID_PORT_VLAN: |
| 1194 | − err = port_vlans_del(netdev, SWITCHDEV_OBJ_PORT_VLAN(obj)); | |
| 1194 | + err = dpaa2_switch_port_vlans_del(netdev, SWITCHDEV_OBJ_PORT_VLAN(obj)); | |
| 1195 | 1195 | break; |
| 1196 | 1196 | case SWITCHDEV_OBJ_ID_PORT_MDB: |
| 1197 | − err = port_mdb_del(netdev, SWITCHDEV_OBJ_PORT_MDB(obj)); | |
| 1197 | + err = dpaa2_switch_port_mdb_del(netdev, SWITCHDEV_OBJ_PORT_MDB(obj)); | |
| 1198 | 1198 | break; |
| 1199 | 1199 | default: |
| 1200 | 1200 | err = -EOPNOTSUPP; |
| @@ -1203,23 +1203,22 @@ static int swdev_port_obj_del(struct net_device *netdev, · 2 unmodified lines | ||
| 1203 | 1203 | return err; |
| 1204 | 1204 | } |
| 1205 | 1205 | |
| 1206 | −static int | |
| 1207 | −ethsw_switchdev_port_attr_set_event(struct net_device *netdev, | |
| 1208 | − struct switchdev_notifier_port_attr_info | |
| 1209 | − *port_attr_info) | |
| 1206 | +static int dpaa2_switch_port_attr_set_event(struct net_device *netdev, | |
| 1207 | + struct switchdev_notifier_port_attr_info | |
| 1208 | + *port_attr_info) | |
| 1210 | 1209 | { |
| 1211 | 1210 | int err; |
| 1212 | 1211 | |
| 1213 | − err = swdev_port_attr_set(netdev, port_attr_info->attr, | |
| 1214 | − port_attr_info->trans); | |
| 1212 | + err = dpaa2_switch_port_attr_set(netdev, port_attr_info->attr, | |
| 1213 | + port_attr_info->trans); | |
| 1215 | 1214 | |
| 1216 | 1215 | port_attr_info->handled = true; |
| 1217 | 1216 | return notifier_from_errno(err); |
| 1218 | 1217 | } |
| 1219 | 1218 | |
| 1220 | 1219 | /* For the moment, only flood setting needs to be updated */ |
| 1221 | −static int port_bridge_join(struct net_device *netdev, | |
| 1222 | − struct net_device *upper_dev) | |
| 1220 | +static int dpaa2_switch_port_bridge_join(struct net_device *netdev, | |
| 1221 | + struct net_device *upper_dev) | |
| 1223 | 1222 | { |
| 1224 | 1223 | struct ethsw_port_priv *port_priv = netdev_priv(netdev); |
| 1225 | 1224 | struct ethsw_core *ethsw = port_priv->ethsw_data; |
| @@ -1237,7 +1236,7 @@ static int port_bridge_join(struct net_device *netdev, · 11 unmodified lines | ||
| 1237 | 1236 | } |
| 1238 | 1237 | |
| 1239 | 1238 | netdev_for_each_lower_dev(upper_dev, other_dev, iter) { |
| 1240 | − if (!ethsw_port_dev_check(other_dev, NULL)) | |
| 1239 | + if (!dpaa2_switch_port_dev_check(other_dev, NULL)) | |
| 1241 | 1240 | continue; |
| 1242 | 1241 | |
| 1243 | 1242 | other_port_priv = netdev_priv(other_dev); |
| @@ -1249,35 +1248,35 @@ static int port_bridge_join(struct net_device *netdev, · 5 unmodified lines | ||
| 1249 | 1248 | } |
| 1250 | 1249 | |
| 1251 | 1250 | /* Enable flooding */ |
| 1252 | − err = ethsw_port_set_flood(port_priv, 1); | |
| 1251 | + err = dpaa2_switch_port_set_flood(port_priv, 1); | |
| 1253 | 1252 | if (!err) |
| 1254 | 1253 | port_priv->bridge_dev = upper_dev; |
| 1255 | 1254 | |
| 1256 | 1255 | return err; |
| 1257 | 1256 | } |
| 1258 | 1257 | |
| 1259 | −static int port_bridge_leave(struct net_device *netdev) | |
| 1258 | +static int dpaa2_switch_port_bridge_leave(struct net_device *netdev) | |
| 1260 | 1259 | { |
| 1261 | 1260 | struct ethsw_port_priv *port_priv = netdev_priv(netdev); |
| 1262 | 1261 | int err; |
| 1263 | 1262 | |
| 1264 | 1263 | /* Disable flooding */ |
| 1265 | − err = ethsw_port_set_flood(port_priv, 0); | |
| 1264 | + err = dpaa2_switch_port_set_flood(port_priv, 0); | |
| 1266 | 1265 | if (!err) |
| 1267 | 1266 | port_priv->bridge_dev = NULL; |
| 1268 | 1267 | |
| 1269 | 1268 | return err; |
| 1270 | 1269 | } |
| 1271 | 1270 | |
| 1272 | −static int port_netdevice_event(struct notifier_block *nb, | |
| 1273 | − unsigned long event, void *ptr) | |
| 1271 | +static int dpaa2_switch_port_netdevice_event(struct notifier_block *nb, | |
| 1272 | + unsigned long event, void *ptr) | |
| 1274 | 1273 | { |
| 1275 | 1274 | struct net_device *netdev = netdev_notifier_info_to_dev(ptr); |
| 1276 | 1275 | struct netdev_notifier_changeupper_info *info = ptr; |
| 1277 | 1276 | struct net_device *upper_dev; |
| 1278 | 1277 | int err = 0; |
| 1279 | 1278 | |
| 1280 | − if (!ethsw_port_dev_check(netdev, nb)) | |
| 1279 | + if (!dpaa2_switch_port_dev_check(netdev, nb)) | |
| 1281 | 1280 | return NOTIFY_DONE; |
| 1282 | 1281 | |
| 1283 | 1282 | /* Handle just upper dev link/unlink for the moment */ |
| @@ -1285,9 +1284,9 @@ static int port_netdevice_event(struct notifier_block *nb, · 1 unmodified line | ||
| 1285 | 1284 | upper_dev = info->upper_dev; |
| 1286 | 1285 | if (netif_is_bridge_master(upper_dev)) { |
| 1287 | 1286 | if (info->linking) |
| 1288 | − err = port_bridge_join(netdev, upper_dev); | |
| 1287 | + err = dpaa2_switch_port_bridge_join(netdev, upper_dev); | |
| 1289 | 1288 | else |
| 1290 | − err = port_bridge_leave(netdev); | |
| 1289 | + err = dpaa2_switch_port_bridge_leave(netdev); | |
| 1291 | 1290 | } |
| 1292 | 1291 | } |
| 1293 | 1292 | |
| @@ -1301,7 +1300,7 @@ struct ethsw_switchdev_event_work { · 7 unmodified lines | ||
| 1301 | 1300 | unsigned long event; |
| 1302 | 1301 | }; |
| 1303 | 1302 | |
| 1304 | −static void ethsw_switchdev_event_work(struct work_struct *work) | |
| 1303 | +static void dpaa2_switch_event_work(struct work_struct *work) | |
| 1305 | 1304 | { |
| 1306 | 1305 | struct ethsw_switchdev_event_work *switchdev_work = |
| 1307 | 1306 | container_of(work, struct ethsw_switchdev_event_work, work); |
| @@ -1317,11 +1316,11 @@ static void ethsw_switchdev_event_work(struct work_struct *work) · 9 unmodified lines | ||
| 1317 | 1316 | if (!fdb_info->added_by_user) |
| 1318 | 1317 | break; |
| 1319 | 1318 | if (is_unicast_ether_addr(fdb_info->addr)) |
| 1320 | − err = ethsw_port_fdb_add_uc(netdev_priv(dev), | |
| 1321 | − fdb_info->addr); | |
| 1319 | + err = dpaa2_switch_port_fdb_add_uc(netdev_priv(dev), | |
| 1320 | + fdb_info->addr); | |
| 1322 | 1321 | else |
| 1323 | − err = ethsw_port_fdb_add_mc(netdev_priv(dev), | |
| 1324 | − fdb_info->addr); | |
| 1322 | + err = dpaa2_switch_port_fdb_add_mc(netdev_priv(dev), | |
| 1323 | + fdb_info->addr); | |
| 1325 | 1324 | if (err) |
| 1326 | 1325 | break; |
| 1327 | 1326 | fdb_info->offloaded = true; |
| @@ -1332,9 +1331,9 @@ static void ethsw_switchdev_event_work(struct work_struct *work) · 4 unmodified lines | ||
| 1332 | 1331 | if (!fdb_info->added_by_user) |
| 1333 | 1332 | break; |
| 1334 | 1333 | if (is_unicast_ether_addr(fdb_info->addr)) |
| 1335 | − ethsw_port_fdb_del_uc(netdev_priv(dev), fdb_info->addr); | |
| 1334 | + dpaa2_switch_port_fdb_del_uc(netdev_priv(dev), fdb_info->addr); | |
| 1336 | 1335 | else |
| 1337 | − ethsw_port_fdb_del_mc(netdev_priv(dev), fdb_info->addr); | |
| 1336 | + dpaa2_switch_port_fdb_del_mc(netdev_priv(dev), fdb_info->addr); | |
| 1338 | 1337 | break; |
| 1339 | 1338 | } |
| 1340 | 1339 | |
| @@ -1345,8 +1344,8 @@ static void ethsw_switchdev_event_work(struct work_struct *work) · 4 unmodified lines | ||
| 1345 | 1344 | } |
| 1346 | 1345 | |
| 1347 | 1346 | /* Called under rcu_read_lock() */ |
| 1348 | −static int port_switchdev_event(struct notifier_block *nb, | |
| 1349 | − unsigned long event, void *ptr) | |
| 1347 | +static int dpaa2_switch_port_event(struct notifier_block *nb, | |
| 1348 | + unsigned long event, void *ptr) | |
| 1350 | 1349 | { |
| 1351 | 1350 | struct net_device *dev = switchdev_notifier_info_to_dev(ptr); |
| 1352 | 1351 | struct ethsw_port_priv *port_priv = netdev_priv(dev); |
| @@ -1354,17 +1353,17 @@ static int port_switchdev_event(struct notifier_block *nb, · 1 unmodified line | ||
| 1354 | 1353 | struct switchdev_notifier_fdb_info *fdb_info = ptr; |
| 1355 | 1354 | struct ethsw_core *ethsw = port_priv->ethsw_data; |
| 1356 | 1355 | |
| 1357 | − if (!ethsw_port_dev_check(dev, nb)) | |
| 1356 | + if (!dpaa2_switch_port_dev_check(dev, nb)) | |
| 1358 | 1357 | return NOTIFY_DONE; |
| 1359 | 1358 | |
| 1360 | 1359 | if (event == SWITCHDEV_PORT_ATTR_SET) |
| 1361 | − return ethsw_switchdev_port_attr_set_event(dev, ptr); | |
| 1360 | + return dpaa2_switch_port_attr_set_event(dev, ptr); | |
| 1362 | 1361 | |
| 1363 | 1362 | switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC); |
| 1364 | 1363 | if (!switchdev_work) |
| 1365 | 1364 | return NOTIFY_BAD; |
| 1366 | 1365 | |
| 1367 | − INIT_WORK(&switchdev_work->work, ethsw_switchdev_event_work); | |
| 1366 | + INIT_WORK(&switchdev_work->work, dpaa2_switch_event_work); | |
| 1368 | 1367 | switchdev_work->dev = dev; |
| 1369 | 1368 | switchdev_work->event = event; |
| 1370 | 1369 | |
| @@ -1397,20 +1396,19 @@ err_addr_alloc: · 26 unmodified lines | ||
| 1397 | 1396 | return NOTIFY_BAD; |
| 1398 | 1397 | } |
| 1399 | 1398 | |
| 1400 | −static int | |
| 1401 | −ethsw_switchdev_port_obj_event(unsigned long event, struct net_device *netdev, | |
| 1402 | − struct switchdev_notifier_port_obj_info | |
| 1403 | − *port_obj_info) | |
| 1399 | +static int dpaa2_switch_port_obj_event(unsigned long event, | |
| 1400 | + struct net_device *netdev, | |
| 1401 | + struct switchdev_notifier_port_obj_info *port_obj_info) | |
| 1404 | 1402 | { |
| 1405 | 1403 | int err = -EOPNOTSUPP; |
| 1406 | 1404 | |
| 1407 | 1405 | switch (event) { |
| 1408 | 1406 | case SWITCHDEV_PORT_OBJ_ADD: |
| 1409 | − err = swdev_port_obj_add(netdev, port_obj_info->obj, | |
| 1410 | − port_obj_info->trans); | |
| 1407 | + err = dpaa2_switch_port_obj_add(netdev, port_obj_info->obj, | |
| 1408 | + port_obj_info->trans); | |
| 1411 | 1409 | break; |
| 1412 | 1410 | case SWITCHDEV_PORT_OBJ_DEL: |
| 1413 | − err = swdev_port_obj_del(netdev, port_obj_info->obj); | |
| 1411 | + err = dpaa2_switch_port_obj_del(netdev, port_obj_info->obj); | |
| 1414 | 1412 | break; |
| 1415 | 1413 | } |
| 1416 | 1414 | |
| @@ -1418,45 +1416,45 @@ ethsw_switchdev_port_obj_event(unsigned long event, struct net_device *netdev, · 1 unmodified line | ||
| 1418 | 1416 | return notifier_from_errno(err); |
| 1419 | 1417 | } |
| 1420 | 1418 | |
| 1421 | −static int port_switchdev_blocking_event(struct notifier_block *nb, | |
| 1422 | − unsigned long event, void *ptr) | |
| 1419 | +static int dpaa2_switch_port_blocking_event(struct notifier_block *nb, | |
| 1420 | + unsigned long event, void *ptr) | |
| 1423 | 1421 | { |
| 1424 | 1422 | struct net_device *dev = switchdev_notifier_info_to_dev(ptr); |
| 1425 | 1423 | |
| 1426 | − if (!ethsw_port_dev_check(dev, nb)) | |
| 1424 | + if (!dpaa2_switch_port_dev_check(dev, nb)) | |
| 1427 | 1425 | return NOTIFY_DONE; |
| 1428 | 1426 | |
| 1429 | 1427 | switch (event) { |
| 1430 | 1428 | case SWITCHDEV_PORT_OBJ_ADD: |
| 1431 | 1429 | case SWITCHDEV_PORT_OBJ_DEL: |
| 1432 | − return ethsw_switchdev_port_obj_event(event, dev, ptr); | |
| 1430 | + return dpaa2_switch_port_obj_event(event, dev, ptr); | |
| 1433 | 1431 | case SWITCHDEV_PORT_ATTR_SET: |
| 1434 | − return ethsw_switchdev_port_attr_set_event(dev, ptr); | |
| 1432 | + return dpaa2_switch_port_attr_set_event(dev, ptr); | |
| 1435 | 1433 | } |
| 1436 | 1434 | |
| 1437 | 1435 | return NOTIFY_DONE; |
| 1438 | 1436 | } |
| 1439 | 1437 | |
| 1440 | −static int ethsw_register_notifier(struct device *dev) | |
| 1438 | +static int dpaa2_switch_register_notifier(struct device *dev) | |
| 1441 | 1439 | { |
| 1442 | 1440 | struct ethsw_core *ethsw = dev_get_drvdata(dev); |
| 1443 | 1441 | int err; |
| 1444 | 1442 | |
| 1445 | − ethsw->port_nb.notifier_call = port_netdevice_event; | |
| 1443 | + ethsw->port_nb.notifier_call = dpaa2_switch_port_netdevice_event; | |
| 1446 | 1444 | err = register_netdevice_notifier(ðsw->port_nb); |
| 1447 | 1445 | if (err) { |
| 1448 | 1446 | dev_err(dev, "Failed to register netdev notifier\n"); |
| 1449 | 1447 | return err; |
| 1450 | 1448 | } |
| 1451 | 1449 | |
| 1452 | − ethsw->port_switchdev_nb.notifier_call = port_switchdev_event; | |
| 1450 | + ethsw->port_switchdev_nb.notifier_call = dpaa2_switch_port_event; | |
| 1453 | 1451 | err = register_switchdev_notifier(ðsw->port_switchdev_nb); |
| 1454 | 1452 | if (err) { |
| 1455 | 1453 | dev_err(dev, "Failed to register switchdev notifier\n"); |
| 1456 | 1454 | goto err_switchdev_nb; |
| 1457 | 1455 | } |
| 1458 | 1456 | |
| 1459 | − ethsw->port_switchdevb_nb.notifier_call = port_switchdev_blocking_event; | |
| 1457 | + ethsw->port_switchdevb_nb.notifier_call = dpaa2_switch_port_blocking_event; | |
| 1460 | 1458 | err = register_switchdev_blocking_notifier(ðsw->port_switchdevb_nb); |
| 1461 | 1459 | if (err) { |
| 1462 | 1460 | dev_err(dev, "Failed to register switchdev blocking notifier\n"); |
| @@ -1472,7 +1470,7 @@ err_switchdev_nb: · 9 unmodified lines | ||
| 1472 | 1470 | return err; |
| 1473 | 1471 | } |
| 1474 | 1472 | |
| 1475 | −static void ethsw_detect_features(struct ethsw_core *ethsw) | |
| 1473 | +static void dpaa2_switch_detect_features(struct ethsw_core *ethsw) | |
| 1476 | 1474 | { |
| 1477 | 1475 | ethsw->features = 0; |
| 1478 | 1476 | |
| @@ -1480,7 +1478,7 @@ static void ethsw_detect_features(struct ethsw_core *ethsw) · 1 unmodified line | ||
| 1480 | 1478 | ethsw->features |= ETHSW_FEATURE_MAC_ADDR; |
| 1481 | 1479 | } |
| 1482 | 1480 | |
| 1483 | −static int ethsw_init(struct fsl_mc_device *sw_dev) | |
| 1481 | +static int dpaa2_switch_init(struct fsl_mc_device *sw_dev) | |
| 1484 | 1482 | { |
| 1485 | 1483 | struct device *dev = &sw_dev->dev; |
| 1486 | 1484 | struct ethsw_core *ethsw = dev_get_drvdata(dev); |
| @@ -1523,7 +1521,7 @@ static int ethsw_init(struct fsl_mc_device *sw_dev) · 36 unmodified lines | ||
| 1523 | 1521 | goto err_close; |
| 1524 | 1522 | } |
| 1525 | 1523 | |
| 1526 | − ethsw_detect_features(ethsw); | |
| 1524 | + dpaa2_switch_detect_features(ethsw); | |
| 1527 | 1525 | |
| 1528 | 1526 | err = dpsw_reset(ethsw->mc_io, 0, ethsw->dpsw_handle); |
| 1529 | 1527 | if (err) { |
| @@ -1568,7 +1566,7 @@ static int ethsw_init(struct fsl_mc_device *sw_dev) · 38 unmodified lines | ||
| 1568 | 1566 | goto err_close; |
| 1569 | 1567 | } |
| 1570 | 1568 | |
| 1571 | − err = ethsw_register_notifier(dev); | |
| 1569 | + err = dpaa2_switch_register_notifier(dev); | |
| 1572 | 1570 | if (err) |
| 1573 | 1571 | goto err_destroy_ordered_workqueue; |
| 1574 | 1572 | |
| @@ -1582,7 +1580,7 @@ err_close: · 7 unmodified lines | ||
| 1582 | 1580 | return err; |
| 1583 | 1581 | } |
| 1584 | 1582 | |
| 1585 | −static int ethsw_port_init(struct ethsw_port_priv *port_priv, u16 port) | |
| 1583 | +static int dpaa2_switch_port_init(struct ethsw_port_priv *port_priv, u16 port) | |
| 1586 | 1584 | { |
| 1587 | 1585 | struct net_device *netdev = port_priv->netdev; |
| 1588 | 1586 | struct ethsw_core *ethsw = port_priv->ethsw_data; |
| @@ -1603,7 +1601,7 @@ static int ethsw_port_init(struct ethsw_port_priv *port_priv, u16 port) · 14 unmodified lines | ||
| 1603 | 1601 | return err; |
| 1604 | 1602 | } |
| 1605 | 1603 | |
| 1606 | − err = ethsw_port_set_pvid(port_priv, 0); | |
| 1604 | + err = dpaa2_switch_port_set_pvid(port_priv, 0); | |
| 1607 | 1605 | if (err) |
| 1608 | 1606 | return err; |
| 1609 | 1607 | |
| @@ -1615,7 +1613,7 @@ static int ethsw_port_init(struct ethsw_port_priv *port_priv, u16 port) · 5 unmodified lines | ||
| 1615 | 1613 | return err; |
| 1616 | 1614 | } |
| 1617 | 1615 | |
| 1618 | −static void ethsw_unregister_notifier(struct device *dev) | |
| 1616 | +static void dpaa2_switch_unregister_notifier(struct device *dev) | |
| 1619 | 1617 | { |
| 1620 | 1618 | struct ethsw_core *ethsw = dev_get_drvdata(dev); |
| 1621 | 1619 | struct notifier_block *nb; |
| @@ -1639,20 +1637,20 @@ static void ethsw_unregister_notifier(struct device *dev) · 17 unmodified lines | ||
| 1639 | 1637 | "Failed to unregister netdev notifier (%d)\n", err); |
| 1640 | 1638 | } |
| 1641 | 1639 | |
| 1642 | −static void ethsw_takedown(struct fsl_mc_device *sw_dev) | |
| 1640 | +static void dpaa2_switch_takedown(struct fsl_mc_device *sw_dev) | |
| 1643 | 1641 | { |
| 1644 | 1642 | struct device *dev = &sw_dev->dev; |
| 1645 | 1643 | struct ethsw_core *ethsw = dev_get_drvdata(dev); |
| 1646 | 1644 | int err; |
| 1647 | 1645 | |
| 1648 | − ethsw_unregister_notifier(dev); | |
| 1646 | + dpaa2_switch_unregister_notifier(dev); | |
| 1649 | 1647 | |
| 1650 | 1648 | err = dpsw_close(ethsw->mc_io, 0, ethsw->dpsw_handle); |
| 1651 | 1649 | if (err) |
| 1652 | 1650 | dev_warn(dev, "dpsw_close err %d\n", err); |
| 1653 | 1651 | } |
| 1654 | 1652 | |
| 1655 | −static int ethsw_remove(struct fsl_mc_device *sw_dev) | |
| 1653 | +static int dpaa2_switch_remove(struct fsl_mc_device *sw_dev) | |
| 1656 | 1654 | { |
| 1657 | 1655 | struct ethsw_port_priv *port_priv; |
| 1658 | 1656 | struct ethsw_core *ethsw; |
| @@ -1662,7 +1660,7 @@ static int ethsw_remove(struct fsl_mc_device *sw_dev) · 3 unmodified lines | ||
| 1662 | 1660 | dev = &sw_dev->dev; |
| 1663 | 1661 | ethsw = dev_get_drvdata(dev); |
| 1664 | 1662 | |
| 1665 | − ethsw_teardown_irqs(sw_dev); | |
| 1663 | + dpaa2_switch_teardown_irqs(sw_dev); | |
| 1666 | 1664 | |
| 1667 | 1665 | dpsw_disable(ethsw->mc_io, 0, ethsw->dpsw_handle); |
| 1668 | 1666 | |
| @@ -1673,7 +1671,7 @@ static int ethsw_remove(struct fsl_mc_device *sw_dev) · 4 unmodified lines | ||
| 1673 | 1671 | } |
| 1674 | 1672 | kfree(ethsw->ports); |
| 1675 | 1673 | |
| 1676 | − ethsw_takedown(sw_dev); | |
| 1674 | + dpaa2_switch_takedown(sw_dev); | |
| 1677 | 1675 | |
| 1678 | 1676 | destroy_workqueue(ethsw->workqueue); |
| 1679 | 1677 | |
| @@ -1686,7 +1684,8 @@ static int ethsw_remove(struct fsl_mc_device *sw_dev) · 6 unmodified lines | ||
| 1686 | 1684 | return 0; |
| 1687 | 1685 | } |
| 1688 | 1686 | |
| 1689 | −static int ethsw_probe_port(struct ethsw_core *ethsw, u16 port_idx) | |
| 1687 | +static int dpaa2_switch_probe_port(struct ethsw_core *ethsw, | |
| 1688 | + u16 port_idx) | |
| 1690 | 1689 | { |
| 1691 | 1690 | struct ethsw_port_priv *port_priv; |
| 1692 | 1691 | struct device *dev = ethsw->dev; |
| @@ -1710,18 +1709,18 @@ static int ethsw_probe_port(struct ethsw_core *ethsw, u16 port_idx) · 17 unmodified lines | ||
| 1710 | 1709 | port_priv->flood = true; |
| 1711 | 1710 | |
| 1712 | 1711 | SET_NETDEV_DEV(port_netdev, dev); |
| 1713 | − port_netdev->netdev_ops = ðsw_port_ops; | |
| 1714 | − port_netdev->ethtool_ops = ðsw_port_ethtool_ops; | |
| 1712 | + port_netdev->netdev_ops = &dpaa2_switch_port_ops; | |
| 1713 | + port_netdev->ethtool_ops = &dpaa2_switch_port_ethtool_ops; | |
| 1715 | 1714 | |
| 1716 | 1715 | /* Set MTU limits */ |
| 1717 | 1716 | port_netdev->min_mtu = ETH_MIN_MTU; |
| 1718 | 1717 | port_netdev->max_mtu = ETHSW_MAX_FRAME_LENGTH; |
| 1719 | 1718 | |
| 1720 | − err = ethsw_port_init(port_priv, port_idx); | |
| 1719 | + err = dpaa2_switch_port_init(port_priv, port_idx); | |
| 1721 | 1720 | if (err) |
| 1722 | 1721 | goto err_port_probe; |
| 1723 | 1722 | |
| 1724 | − err = ethsw_port_set_mac_addr(port_priv); | |
| 1723 | + err = dpaa2_switch_port_set_mac_addr(port_priv); | |
| 1725 | 1724 | if (err) |
| 1726 | 1725 | goto err_port_probe; |
| 1727 | 1726 | |
| @@ -1741,7 +1740,7 @@ err_port_probe: · 13 unmodified lines | ||
| 1741 | 1740 | return err; |
| 1742 | 1741 | } |
| 1743 | 1742 | |
| 1744 | −static int ethsw_probe(struct fsl_mc_device *sw_dev) | |
| 1743 | +static int dpaa2_switch_probe(struct fsl_mc_device *sw_dev) | |
| 1745 | 1744 | { |
| 1746 | 1745 | struct device *dev = &sw_dev->dev; |
| 1747 | 1746 | struct ethsw_core *ethsw; |
| @@ -1766,7 +1765,7 @@ static int ethsw_probe(struct fsl_mc_device *sw_dev) · 18 unmodified lines | ||
| 1766 | 1765 | goto err_free_drvdata; |
| 1767 | 1766 | } |
| 1768 | 1767 | |
| 1769 | − err = ethsw_init(sw_dev); | |
| 1768 | + err = dpaa2_switch_init(sw_dev); | |
| 1770 | 1769 | if (err) |
| 1771 | 1770 | goto err_free_cmdport; |
| 1772 | 1771 | |
| @@ -1784,7 +1783,7 @@ static int ethsw_probe(struct fsl_mc_device *sw_dev) · 11 unmodified lines | ||
| 1784 | 1783 | } |
| 1785 | 1784 | |
| 1786 | 1785 | for (i = 0; i < ethsw->sw_attr.num_ifs; i++) { |
| 1787 | − err = ethsw_probe_port(ethsw, i); | |
| 1786 | + err = dpaa2_switch_probe_port(ethsw, i); | |
| 1788 | 1787 | if (err) |
| 1789 | 1788 | goto err_free_ports; |
| 1790 | 1789 | } |
| @@ -1800,7 +1799,7 @@ static int ethsw_probe(struct fsl_mc_device *sw_dev) · 9 unmodified lines | ||
| 1800 | 1799 | dpsw_if_disable(ethsw->mc_io, 0, ethsw->dpsw_handle, i); |
| 1801 | 1800 | |
| 1802 | 1801 | /* Setup IRQs */ |
| 1803 | − err = ethsw_setup_irqs(sw_dev); | |
| 1802 | + err = dpaa2_switch_setup_irqs(sw_dev); | |
| 1804 | 1803 | if (err) |
| 1805 | 1804 | goto err_stop; |
| 1806 | 1805 | |
| @@ -1819,7 +1818,7 @@ err_free_ports: · 12 unmodified lines | ||
| 1819 | 1818 | kfree(ethsw->ports); |
| 1820 | 1819 | |
| 1821 | 1820 | err_takedown: |
| 1822 | − ethsw_takedown(sw_dev); | |
| 1821 | + dpaa2_switch_takedown(sw_dev); | |
| 1823 | 1822 | |
| 1824 | 1823 | err_free_cmdport: |
| 1825 | 1824 | fsl_mc_portal_free(ethsw->mc_io); |
| @@ -1831,26 +1830,26 @@ err_free_drvdata: · 5 unmodified lines | ||
| 1831 | 1830 | return err; |
| 1832 | 1831 | } |
| 1833 | 1832 | |
| 1834 | −static const struct fsl_mc_device_id ethsw_match_id_table[] = { | |
| 1833 | +static const struct fsl_mc_device_id dpaa2_switch_match_id_table[] = { | |
| 1835 | 1834 | { |
| 1836 | 1835 | .vendor = FSL_MC_VENDOR_FREESCALE, |
| 1837 | 1836 | .obj_type = "dpsw", |
| 1838 | 1837 | }, |
| 1839 | 1838 | { .vendor = 0x0 } |
| 1840 | 1839 | }; |
| 1841 | −MODULE_DEVICE_TABLE(fslmc, ethsw_match_id_table); | |
| 1840 | +MODULE_DEVICE_TABLE(fslmc, dpaa2_switch_match_id_table); | |
| 1842 | 1841 | |
| 1843 | −static struct fsl_mc_driver eth_sw_drv = { | |
| 1842 | +static struct fsl_mc_driver dpaa2_switch_drv = { | |
| 1844 | 1843 | .driver = { |
| 1845 | 1844 | .name = KBUILD_MODNAME, |
| 1846 | 1845 | .owner = THIS_MODULE, |
| 1847 | 1846 | }, |
| 1848 | − .probe = ethsw_probe, | |
| 1849 | − .remove = ethsw_remove, | |
| 1850 | − .match_id_table = ethsw_match_id_table | |
| 1847 | + .probe = dpaa2_switch_probe, | |
| 1848 | + .remove = dpaa2_switch_remove, | |
| 1849 | + .match_id_table = dpaa2_switch_match_id_table | |
| 1851 | 1850 | }; |
| 1852 | 1851 | |
| 1853 | −module_fsl_mc_driver(eth_sw_drv); | |
| 1852 | +module_fsl_mc_driver(dpaa2_switch_drv); | |
| 1854 | 1853 | |
| 1855 | 1854 | MODULE_LICENSE("GPL v2"); |
| 1856 | 1855 | MODULE_DESCRIPTION("DPAA2 Ethernet Switch Driver"); |
| @@ -39,7 +39,7 @@ · 38 unmodified lines | ||
| 39 | 39 | |
| 40 | 40 | #define ETHSW_FEATURE_MAC_ADDR BIT(0) |
| 41 | 41 | |
| 42 | −extern const struct ethtool_ops ethsw_port_ethtool_ops; | |
| 42 | +extern const struct ethtool_ops dpaa2_switch_port_ethtool_ops; | |
| 43 | 43 | |
| 44 | 44 | struct ethsw_core; |
| 45 | 45 | |
| @@ -466,7 +466,7 @@ static void fwtty_throttle_port(struct fwtty_port *port) · 465 unmodified lines | ||
| 466 | 466 | * fwtty_do_hangup - wait for ldisc to deliver all pending rx; only then hangup |
| 467 | 467 | * |
| 468 | 468 | * When the remote has finished tx, and all in-flight rx has been received and |
| 469 | − * and pushed to the flip buffer, the remote may close its device. This will | |
| 469 | + * pushed to the flip buffer, the remote may close its device. This will | |
| 470 | 470 | * drop DTR on the remote which will drop carrier here. Typically, the tty is |
| 471 | 471 | * hung up when carrier is dropped or lost. |
| 472 | 472 | * |
| @@ -688,7 +688,7 @@ static struct snd_soc_dai_driver gbaudio_dai[] = { · 687 unmodified lines | ||
| 688 | 688 | .playback = { |
| 689 | 689 | .stream_name = "I2S 0 Playback", |
| 690 | 690 | .rates = SNDRV_PCM_RATE_48000, |
| 691 | − .formats = SNDRV_PCM_FORMAT_S16_LE, | |
| 691 | + .formats = SNDRV_PCM_FMTBIT_S16_LE, | |
| 692 | 692 | .rate_max = 48000, |
| 693 | 693 | .rate_min = 48000, |
| 694 | 694 | .channels_min = 1, |
| @@ -698,7 +698,7 @@ static struct snd_soc_dai_driver gbaudio_dai[] = { · 3 unmodified lines | ||
| 698 | 698 | .capture = { |
| 699 | 699 | .stream_name = "I2S 0 Capture", |
| 700 | 700 | .rates = SNDRV_PCM_RATE_48000, |
| 701 | − .formats = SNDRV_PCM_FORMAT_S16_LE, | |
| 701 | + .formats = SNDRV_PCM_FMTBIT_S16_LE, | |
| 702 | 702 | .rate_max = 48000, |
| 703 | 703 | .rate_min = 48000, |
| 704 | 704 | .channels_min = 1, |
| @@ -219,7 +219,7 @@ static int gb_audio_add_data_connection(struct gbaudio_module_info *gbmodule, · 218 unmodified lines | ||
| 219 | 219 | |
| 220 | 220 | greybus_set_drvdata(bundle, gbmodule); |
| 221 | 221 | dai->id = 0; |
| 222 | − dai->data_cport = connection->intf_cport_id; | |
| 222 | + dai->data_cport = cpu_to_le16(connection->intf_cport_id); | |
| 223 | 223 | dai->connection = connection; |
| 224 | 224 | list_add(&dai->list, &gbmodule->data_list); |
| 225 | 225 | |
| @@ -329,7 +329,7 @@ static int gb_audio_probe(struct gb_bundle *bundle, · 103 unmodified lines | ||
| 329 | 329 | if (ret) { |
| 330 | 330 | dev_err(dev, |
| 331 | 331 | "%d:Error while enabling %d:data connection\n", |
| 332 | − ret, dai->data_cport); | |
| 332 | + ret, le16_to_cpu(dai->data_cport)); | |
| 333 | 333 | goto disable_data_connection; |
| 334 | 334 | } |
| 335 | 335 | } |
| @@ -451,7 +451,7 @@ static int gb_audio_resume(struct device *dev) · 115 unmodified lines | ||
| 451 | 451 | if (ret) { |
| 452 | 452 | dev_err(dev, |
| 453 | 453 | "%d:Error while enabling %d:data connection\n", |
| 454 | − ret, dai->data_cport); | |
| 454 | + ret, le16_to_cpu(dai->data_cport)); | |
| 455 | 455 | return ret; |
| 456 | 456 | } |
| 457 | 457 | } |
| @@ -182,7 +182,7 @@ static int gbcodec_mixer_ctl_info(struct snd_kcontrol *kcontrol, · 181 unmodified lines | ||
| 182 | 182 | /* update uinfo */ |
| 183 | 183 | uinfo->access = data->access; |
| 184 | 184 | uinfo->count = data->vcount; |
| 185 | − uinfo->type = (snd_ctl_elem_type_t)info->type; | |
| 185 | + uinfo->type = (__force snd_ctl_elem_type_t)info->type; | |
| 186 | 186 | |
| 187 | 187 | switch (info->type) { |
| 188 | 188 | case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN: |
| @@ -466,7 +466,7 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol, · 277 unmodified lines | ||
| 466 | 466 | goto exit; |
| 467 | 467 | |
| 468 | 468 | /* update ucontrol */ |
| 469 | − if (gbvalue.value.integer_value[0] != val) { | |
| 469 | + if (le32_to_cpu(gbvalue.value.integer_value[0]) != val) { | |
| 470 | 470 | for (wi = 0; wi < wlist->num_widgets; wi++) { |
| 471 | 471 | widget = wlist->widgets[wi]; |
| 472 | 472 | snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, |
| @@ -689,7 +689,7 @@ static int gbaudio_tplg_create_kcontrol(struct gbaudio_module_info *gb, · 216 unmodified lines | ||
| 689 | 689 | return -ENOMEM; |
| 690 | 690 | ctldata->ctl_id = ctl->id; |
| 691 | 691 | ctldata->data_cport = le16_to_cpu(ctl->data_cport); |
| 692 | − ctldata->access = ctl->access; | |
| 692 | + ctldata->access = le32_to_cpu(ctl->access); | |
| 693 | 693 | ctldata->vcount = ctl->count_values; |
| 694 | 694 | ctldata->info = &ctl->info; |
| 695 | 695 | *kctl = (struct snd_kcontrol_new) |
| @@ -744,10 +744,10 @@ static int gbcodec_enum_dapm_ctl_get(struct snd_kcontrol *kcontrol, · 48 unmodified lines | ||
| 744 | 744 | return ret; |
| 745 | 745 | } |
| 746 | 746 | |
| 747 | − ucontrol->value.enumerated.item[0] = gbvalue.value.enumerated_item[0]; | |
| 747 | + ucontrol->value.enumerated.item[0] = le32_to_cpu(gbvalue.value.enumerated_item[0]); | |
| 748 | 748 | if (e->shift_l != e->shift_r) |
| 749 | 749 | ucontrol->value.enumerated.item[1] = |
| 750 | − gbvalue.value.enumerated_item[1]; | |
| 750 | + le32_to_cpu(gbvalue.value.enumerated_item[1]); | |
| 751 | 751 | |
| 752 | 752 | return 0; |
| 753 | 753 | } |
| @@ -800,11 +800,11 @@ static int gbcodec_enum_dapm_ctl_put(struct snd_kcontrol *kcontrol, · 46 unmodified lines | ||
| 800 | 800 | val = mux << e->shift_l; |
| 801 | 801 | mask = e->mask << e->shift_l; |
| 802 | 802 | |
| 803 | − if (gbvalue.value.enumerated_item[0] != | |
| 803 | + if (le32_to_cpu(gbvalue.value.enumerated_item[0]) != | |
| 804 | 804 | ucontrol->value.enumerated.item[0]) { |
| 805 | 805 | change = 1; |
| 806 | 806 | gbvalue.value.enumerated_item[0] = |
| 807 | − ucontrol->value.enumerated.item[0]; | |
| 807 | + cpu_to_le32(ucontrol->value.enumerated.item[0]); | |
| 808 | 808 | } |
| 809 | 809 | |
| 810 | 810 | if (e->shift_l != e->shift_r) { |
| @@ -812,11 +812,11 @@ static int gbcodec_enum_dapm_ctl_put(struct snd_kcontrol *kcontrol, · 1 unmodified line | ||
| 812 | 812 | return -EINVAL; |
| 813 | 813 | val |= ucontrol->value.enumerated.item[1] << e->shift_r; |
| 814 | 814 | mask |= e->mask << e->shift_r; |
| 815 | − if (gbvalue.value.enumerated_item[1] != | |
| 815 | + if (le32_to_cpu(gbvalue.value.enumerated_item[1]) != | |
| 816 | 816 | ucontrol->value.enumerated.item[1]) { |
| 817 | 817 | change = 1; |
| 818 | 818 | gbvalue.value.enumerated_item[1] = |
| 819 | − ucontrol->value.enumerated.item[1]; | |
| 819 | + cpu_to_le32(ucontrol->value.enumerated.item[1]); | |
| 820 | 820 | } |
| 821 | 821 | } |
| 822 | 822 | |
| @@ -887,7 +887,7 @@ static int gbaudio_tplg_create_mixer_ctl(struct gbaudio_module_info *gb, · 64 unmodified lines | ||
| 887 | 887 | return -ENOMEM; |
| 888 | 888 | ctldata->ctl_id = ctl->id; |
| 889 | 889 | ctldata->data_cport = le16_to_cpu(ctl->data_cport); |
| 890 | − ctldata->access = ctl->access; | |
| 890 | + ctldata->access = le32_to_cpu(ctl->access); | |
| 891 | 891 | ctldata->vcount = ctl->count_values; |
| 892 | 892 | ctldata->info = &ctl->info; |
| 893 | 893 | *kctl = (struct snd_kcontrol_new) |
| @@ -36,9 +36,9 @@ struct gbphy_device_id { · 35 unmodified lines | ||
| 36 | 36 | |
| 37 | 37 | struct gbphy_driver { |
| 38 | 38 | const char *name; |
| 39 | − int (*probe)(struct gbphy_device *, | |
| 39 | + int (*probe)(struct gbphy_device *device, | |
| 40 | 40 | const struct gbphy_device_id *id); |
| 41 | − void (*remove)(struct gbphy_device *); | |
| 41 | + void (*remove)(struct gbphy_device *device); | |
| 42 | 42 | const struct gbphy_device_id *id_table; |
| 43 | 43 | |
| 44 | 44 | struct device_driver driver; |
| @@ -0,0 +1,49 @@ | ||
| 1 | +# SPDX-License-Identifier: GPL-2.0 | |
| 2 | + | |
| 3 | +# to be placed at drivers/phy | |
| 4 | +config PHY_HI3670_USB | |
| 5 | + tristate "hi3670 USB PHY support" | |
| 6 | + depends on (ARCH_HISI && ARM64) || COMPILE_TEST | |
| 7 | + select GENERIC_PHY | |
| 8 | + select MFD_SYSCON | |
| 9 | + help | |
| 10 | + Enable this to support the HISILICON HI3670 USB PHY. | |
| 11 | + | |
| 12 | + To compile this driver as a module, choose M here. | |
| 13 | + | |
| 14 | +# to be placed at drivers/spmi | |
| 15 | +config SPMI_HISI3670 | |
| 16 | + tristate "Hisilicon 3670 SPMI Controller" | |
| 17 | + select IRQ_DOMAIN_HIERARCHY | |
| 18 | + depends on HAS_IOMEM | |
| 19 | + depends on SPMI | |
| 20 | + help | |
| 21 | + If you say yes to this option, support will be included for the | |
| 22 | + built-in SPMI PMIC Arbiter interface on Hisilicon 3670 | |
| 23 | + processors. | |
| 24 | + | |
| 25 | +# to be placed at drivers/mfd | |
| 26 | +config MFD_HI6421_SPMI | |
| 27 | + tristate "HiSilicon Hi6421v600 SPMI PMU/Codec IC" | |
| 28 | + depends on OF | |
| 29 | + depends on SPMI | |
| 30 | + select MFD_CORE | |
| 31 | + help | |
| 32 | + Add support for HiSilicon Hi6421v600 SPMI PMIC. Hi6421 includes | |
| 33 | + multi-functions, such as regulators, RTC, codec, Coulomb counter, | |
| 34 | + etc. | |
| 35 | + | |
| 36 | + This driver includes core APIs _only_. You have to select | |
| 37 | + individual components like voltage regulators under corresponding | |
| 38 | + menus in order to enable them. | |
| 39 | + We communicate with the Hi6421v600 via a SPMI bus. | |
| 40 | + | |
| 41 | +# to be placed at drivers/regulator | |
| 42 | +config REGULATOR_HI6421V600 | |
| 43 | + tristate "HiSilicon Hi6421v600 PMIC voltage regulator support" | |
| 44 | + depends on MFD_HI6421_SPMI && OF | |
| 45 | + depends on REGULATOR | |
| 46 | + help | |
| 47 | + This driver provides support for the voltage regulators on | |
| 48 | + HiSilicon Hi6421v600 PMU / Codec IC. | |
| 49 | + This is used on Kirin 3670 boards, like HiKey 970. | |
| @@ -0,0 +1,7 @@ | ||
| 1 | +# SPDX-License-Identifier: GPL-2.0 | |
| 2 | + | |
| 3 | +obj-$(CONFIG_PHY_HI3670_USB) += phy-hi3670-usb3.o | |
| 4 | + | |
| 5 | +obj-$(CONFIG_SPMI_HISI3670) += hisi-spmi-controller.o | |
| 6 | +obj-$(CONFIG_MFD_HI6421_SPMI) += hi6421-spmi-pmic.o | |
| 7 | +obj-$(CONFIG_REGULATOR_HI6421V600) += hi6421v600-regulator.o | |
| @@ -0,0 +1,5 @@ | ||
| 1 | +ToDo list: | |
| 2 | + | |
| 3 | +- Port other drivers needed by Hikey 960/970; | |
| 4 | +- Test drivers on Hikey 960; | |
| 5 | +- Validate device tree bindings. | |
| @@ -0,0 +1,342 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 2 | +/* | |
| 3 | + * Device driver for regulators in HISI PMIC IC | |
| 4 | + * | |
| 5 | + * Copyright (c) 2013 Linaro Ltd. | |
| 6 | + * Copyright (c) 2011 Hisilicon. | |
| 7 | + * | |
| 8 | + * | |
| 9 | + * This program is free software; you can redistribute it and/or modify | |
| 10 | + * it under the terms of the GNU General Public License version 2 as | |
| 11 | + * published by the Free Software Foundation. | |
| 12 | + * | |
| 13 | + * This program is distributed in the hope that it will be useful, | |
| 14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 16 | + * GNU General Public License for more details. | |
| 17 | + * | |
| 18 | + */ | |
| 19 | + | |
| 20 | +#include <linux/delay.h> | |
| 21 | +#include <linux/device.h> | |
| 22 | +#include <linux/err.h> | |
| 23 | +#include <linux/interrupt.h> | |
| 24 | +#include <linux/io.h> | |
| 25 | +#include <linux/irq.h> | |
| 26 | +#include <linux/mfd/core.h> | |
| 27 | +#include <linux/mfd/hi6421-spmi-pmic.h> | |
| 28 | +#include <linux/module.h> | |
| 29 | +#include <linux/of_address.h> | |
| 30 | +#include <linux/of_device.h> | |
| 31 | +#include <linux/of_gpio.h> | |
| 32 | +#include <linux/of.h> | |
| 33 | +#include <linux/of_irq.h> | |
| 34 | +#include <linux/platform_device.h> | |
| 35 | +#include <linux/slab.h> | |
| 36 | +#include <linux/spmi.h> | |
| 37 | + | |
| 38 | +/* 8-bit register offset in PMIC */ | |
| 39 | +#define HISI_MASK_STATE 0xff | |
| 40 | + | |
| 41 | +#define HISI_IRQ_ARRAY 2 | |
| 42 | +#define HISI_IRQ_NUM (HISI_IRQ_ARRAY * 8) | |
| 43 | + | |
| 44 | +#define SOC_PMIC_IRQ_MASK_0_ADDR 0x0202 | |
| 45 | +#define SOC_PMIC_IRQ0_ADDR 0x0212 | |
| 46 | + | |
| 47 | +#define HISI_IRQ_KEY_NUM 0 | |
| 48 | +#define HISI_IRQ_KEY_VALUE 0xc0 | |
| 49 | +#define HISI_IRQ_KEY_DOWN 7 | |
| 50 | +#define HISI_IRQ_KEY_UP 6 | |
| 51 | + | |
| 52 | +#define HISI_MASK_FIELD 0xFF | |
| 53 | +#define HISI_BITS 8 | |
| 54 | + | |
| 55 | +/*define the first group interrupt register number*/ | |
| 56 | +#define HISI_PMIC_FIRST_GROUP_INT_NUM 2 | |
| 57 | + | |
| 58 | +static const struct mfd_cell hi6421v600_devs[] = { | |
| 59 | + { .name = "hi6421v600-regulator", }, | |
| 60 | +}; | |
| 61 | + | |
| 62 | +/* | |
| 63 | + * The PMIC register is only 8-bit. | |
| 64 | + * Hisilicon SoC use hardware to map PMIC register into SoC mapping. | |
| 65 | + * At here, we are accessing SoC register with 32-bit. | |
| 66 | + */ | |
| 67 | +int hi6421_spmi_pmic_read(struct hi6421_spmi_pmic *pmic, int reg) | |
| 68 | +{ | |
| 69 | + struct spmi_device *pdev; | |
| 70 | + u8 read_value = 0; | |
| 71 | + u32 ret; | |
| 72 | + | |
| 73 | + pdev = to_spmi_device(pmic->dev); | |
| 74 | + if (!pdev) { | |
| 75 | + pr_err("%s: pdev get failed!\n", __func__); | |
| 76 | + return -ENODEV; | |
| 77 | + } | |
| 78 | + | |
| 79 | + ret = spmi_ext_register_readl(pdev, reg, &read_value, 1); | |
| 80 | + if (ret) { | |
| 81 | + pr_err("%s: spmi_ext_register_readl failed!\n", __func__); | |
| 82 | + return ret; | |
| 83 | + } | |
| 84 | + return read_value; | |
| 85 | +} | |
| 86 | +EXPORT_SYMBOL(hi6421_spmi_pmic_read); | |
| 87 | + | |
| 88 | +int hi6421_spmi_pmic_write(struct hi6421_spmi_pmic *pmic, int reg, u32 val) | |
| 89 | +{ | |
| 90 | + struct spmi_device *pdev; | |
| 91 | + u32 ret; | |
| 92 | + | |
| 93 | + pdev = to_spmi_device(pmic->dev); | |
| 94 | + if (!pdev) { | |
| 95 | + pr_err("%s: pdev get failed!\n", __func__); | |
| 96 | + return -ENODEV; | |
| 97 | + } | |
| 98 | + | |
| 99 | + ret = spmi_ext_register_writel(pdev, reg, (unsigned char *)&val, 1); | |
| 100 | + if (ret) | |
| 101 | + pr_err("%s: spmi_ext_register_writel failed!\n", __func__); | |
| 102 | + | |
| 103 | + return ret; | |
| 104 | +} | |
| 105 | +EXPORT_SYMBOL(hi6421_spmi_pmic_write); | |
| 106 | + | |
| 107 | +int hi6421_spmi_pmic_rmw(struct hi6421_spmi_pmic *pmic, int reg, | |
| 108 | + u32 mask, u32 bits) | |
| 109 | +{ | |
| 110 | + unsigned long flags; | |
| 111 | + u32 data; | |
| 112 | + int ret; | |
| 113 | + | |
| 114 | + spin_lock_irqsave(&pmic->lock, flags); | |
| 115 | + data = hi6421_spmi_pmic_read(pmic, reg) & ~mask; | |
| 116 | + data |= mask & bits; | |
| 117 | + ret = hi6421_spmi_pmic_write(pmic, reg, data); | |
| 118 | + spin_unlock_irqrestore(&pmic->lock, flags); | |
| 119 | + | |
| 120 | + return ret; | |
| 121 | +} | |
| 122 | +EXPORT_SYMBOL(hi6421_spmi_pmic_rmw); | |
| 123 | + | |
| 124 | +static irqreturn_t hi6421_spmi_irq_handler(int irq, void *data) | |
| 125 | +{ | |
| 126 | + struct hi6421_spmi_pmic *pmic = (struct hi6421_spmi_pmic *)data; | |
| 127 | + unsigned long pending; | |
| 128 | + int i, offset; | |
| 129 | + | |
| 130 | + for (i = 0; i < HISI_IRQ_ARRAY; i++) { | |
| 131 | + pending = hi6421_spmi_pmic_read(pmic, (i + SOC_PMIC_IRQ0_ADDR)); | |
| 132 | + pending &= HISI_MASK_FIELD; | |
| 133 | + if (pending != 0) | |
| 134 | + pr_debug("pending[%d]=0x%lx\n\r", i, pending); | |
| 135 | + | |
| 136 | + hi6421_spmi_pmic_write(pmic, (i + SOC_PMIC_IRQ0_ADDR), pending); | |
| 137 | + | |
| 138 | + /* solve powerkey order */ | |
| 139 | + if ((i == HISI_IRQ_KEY_NUM) && | |
| 140 | + ((pending & HISI_IRQ_KEY_VALUE) == HISI_IRQ_KEY_VALUE)) { | |
| 141 | + generic_handle_irq(pmic->irqs[HISI_IRQ_KEY_DOWN]); | |
| 142 | + generic_handle_irq(pmic->irqs[HISI_IRQ_KEY_UP]); | |
| 143 | + pending &= (~HISI_IRQ_KEY_VALUE); | |
| 144 | + } | |
| 145 | + | |
| 146 | + if (pending) { | |
| 147 | + for_each_set_bit(offset, &pending, HISI_BITS) | |
| 148 | + generic_handle_irq(pmic->irqs[offset + i * HISI_BITS]); | |
| 149 | + } | |
| 150 | + } | |
| 151 | + | |
| 152 | + return IRQ_HANDLED; | |
| 153 | +} | |
| 154 | + | |
| 155 | +static void hi6421_spmi_irq_mask(struct irq_data *d) | |
| 156 | +{ | |
| 157 | + struct hi6421_spmi_pmic *pmic = irq_data_get_irq_chip_data(d); | |
| 158 | + u32 data, offset; | |
| 159 | + unsigned long flags; | |
| 160 | + | |
| 161 | + offset = (irqd_to_hwirq(d) >> 3); | |
| 162 | + offset += SOC_PMIC_IRQ_MASK_0_ADDR; | |
| 163 | + | |
| 164 | + spin_lock_irqsave(&pmic->lock, flags); | |
| 165 | + data = hi6421_spmi_pmic_read(pmic, offset); | |
| 166 | + data |= (1 << (irqd_to_hwirq(d) & 0x07)); | |
| 167 | + hi6421_spmi_pmic_write(pmic, offset, data); | |
| 168 | + spin_unlock_irqrestore(&pmic->lock, flags); | |
| 169 | +} | |
| 170 | + | |
| 171 | +static void hi6421_spmi_irq_unmask(struct irq_data *d) | |
| 172 | +{ | |
| 173 | + struct hi6421_spmi_pmic *pmic = irq_data_get_irq_chip_data(d); | |
| 174 | + u32 data, offset; | |
| 175 | + unsigned long flags; | |
| 176 | + | |
| 177 | + offset = (irqd_to_hwirq(d) >> 3); | |
| 178 | + offset += SOC_PMIC_IRQ_MASK_0_ADDR; | |
| 179 | + | |
| 180 | + spin_lock_irqsave(&pmic->lock, flags); | |
| 181 | + data = hi6421_spmi_pmic_read(pmic, offset); | |
| 182 | + data &= ~(1 << (irqd_to_hwirq(d) & 0x07)); | |
| 183 | + hi6421_spmi_pmic_write(pmic, offset, data); | |
| 184 | + spin_unlock_irqrestore(&pmic->lock, flags); | |
| 185 | +} | |
| 186 | + | |
| 187 | +static struct irq_chip hi6421_spmi_pmu_irqchip = { | |
| 188 | + .name = "hisi-irq", | |
| 189 | + .irq_mask = hi6421_spmi_irq_mask, | |
| 190 | + .irq_unmask = hi6421_spmi_irq_unmask, | |
| 191 | + .irq_disable = hi6421_spmi_irq_mask, | |
| 192 | + .irq_enable = hi6421_spmi_irq_unmask, | |
| 193 | +}; | |
| 194 | + | |
| 195 | +static int hi6421_spmi_irq_map(struct irq_domain *d, unsigned int virq, | |
| 196 | + irq_hw_number_t hw) | |
| 197 | +{ | |
| 198 | + struct hi6421_spmi_pmic *pmic = d->host_data; | |
| 199 | + | |
| 200 | + irq_set_chip_and_handler_name(virq, &hi6421_spmi_pmu_irqchip, | |
| 201 | + handle_simple_irq, "hisi"); | |
| 202 | + irq_set_chip_data(virq, pmic); | |
| 203 | + irq_set_irq_type(virq, IRQ_TYPE_NONE); | |
| 204 | + | |
| 205 | + return 0; | |
| 206 | +} | |
| 207 | + | |
| 208 | +static const struct irq_domain_ops hi6421_spmi_domain_ops = { | |
| 209 | + .map = hi6421_spmi_irq_map, | |
| 210 | + .xlate = irq_domain_xlate_twocell, | |
| 211 | +}; | |
| 212 | + | |
| 213 | +static void hi6421_spmi_pmic_irq_prc(struct hi6421_spmi_pmic *pmic) | |
| 214 | +{ | |
| 215 | + int i, pending; | |
| 216 | + | |
| 217 | + for (i = 0 ; i < HISI_IRQ_ARRAY; i++) | |
| 218 | + hi6421_spmi_pmic_write(pmic, SOC_PMIC_IRQ_MASK_0_ADDR + i, | |
| 219 | + HISI_MASK_STATE); | |
| 220 | + | |
| 221 | + for (i = 0 ; i < HISI_IRQ_ARRAY; i++) { | |
| 222 | + pending = hi6421_spmi_pmic_read(pmic, SOC_PMIC_IRQ0_ADDR + i); | |
| 223 | + | |
| 224 | + pr_debug("PMU IRQ address value:irq[0x%x] = 0x%x\n", | |
| 225 | + SOC_PMIC_IRQ0_ADDR + i, pending); | |
| 226 | + hi6421_spmi_pmic_write(pmic, SOC_PMIC_IRQ0_ADDR + i, | |
| 227 | + HISI_MASK_STATE); | |
| 228 | + } | |
| 229 | +} | |
| 230 | + | |
| 231 | +static int hi6421_spmi_pmic_probe(struct spmi_device *pdev) | |
| 232 | +{ | |
| 233 | + struct device *dev = &pdev->dev; | |
| 234 | + struct device_node *np = dev->of_node; | |
| 235 | + struct hi6421_spmi_pmic *pmic; | |
| 236 | + unsigned int virq; | |
| 237 | + int ret, i; | |
| 238 | + | |
| 239 | + pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL); | |
| 240 | + if (!pmic) | |
| 241 | + return -ENOMEM; | |
| 242 | + | |
| 243 | + spin_lock_init(&pmic->lock); | |
| 244 | + | |
| 245 | + pmic->dev = dev; | |
| 246 | + | |
| 247 | + pmic->gpio = of_get_gpio(np, 0); | |
| 248 | + if (pmic->gpio < 0) | |
| 249 | + return pmic->gpio; | |
| 250 | + | |
| 251 | + if (!gpio_is_valid(pmic->gpio)) | |
| 252 | + return -EINVAL; | |
| 253 | + | |
| 254 | + ret = devm_gpio_request_one(dev, pmic->gpio, GPIOF_IN, "pmic"); | |
| 255 | + if (ret < 0) { | |
| 256 | + dev_err(dev, "failed to request gpio%d\n", pmic->gpio); | |
| 257 | + return ret; | |
| 258 | + } | |
| 259 | + | |
| 260 | + pmic->irq = gpio_to_irq(pmic->gpio); | |
| 261 | + | |
| 262 | + hi6421_spmi_pmic_irq_prc(pmic); | |
| 263 | + | |
| 264 | + pmic->irqs = devm_kzalloc(dev, HISI_IRQ_NUM * sizeof(int), GFP_KERNEL); | |
| 265 | + if (!pmic->irqs) | |
| 266 | + goto irq_malloc; | |
| 267 | + | |
| 268 | + pmic->domain = irq_domain_add_simple(np, HISI_IRQ_NUM, 0, | |
| 269 | + &hi6421_spmi_domain_ops, pmic); | |
| 270 | + if (!pmic->domain) { | |
| 271 | + dev_err(dev, "failed irq domain add simple!\n"); | |
| 272 | + ret = -ENODEV; | |
| 273 | + goto irq_malloc; | |
| 274 | + } | |
| 275 | + | |
| 276 | + for (i = 0; i < HISI_IRQ_NUM; i++) { | |
| 277 | + virq = irq_create_mapping(pmic->domain, i); | |
| 278 | + if (!virq) { | |
| 279 | + dev_err(dev, "Failed mapping hwirq\n"); | |
| 280 | + ret = -ENOSPC; | |
| 281 | + goto irq_malloc; | |
| 282 | + } | |
| 283 | + pmic->irqs[i] = virq; | |
| 284 | + dev_dbg(dev, "%s: pmic->irqs[%d] = %d\n", | |
| 285 | + __func__, i, pmic->irqs[i]); | |
| 286 | + } | |
| 287 | + | |
| 288 | + ret = request_threaded_irq(pmic->irq, hi6421_spmi_irq_handler, NULL, | |
| 289 | + IRQF_TRIGGER_LOW | IRQF_SHARED | IRQF_NO_SUSPEND, | |
| 290 | + "pmic", pmic); | |
| 291 | + if (ret < 0) { | |
| 292 | + dev_err(dev, "could not claim pmic IRQ: error %d\n", ret); | |
| 293 | + goto irq_malloc; | |
| 294 | + } | |
| 295 | + | |
| 296 | + dev_set_drvdata(&pdev->dev, pmic); | |
| 297 | + | |
| 298 | + /* | |
| 299 | + * The logic below will rely that the pmic is already stored at | |
| 300 | + * drvdata. | |
| 301 | + */ | |
| 302 | + dev_dbg(&pdev->dev, "SPMI-PMIC: adding children for %pOF\n", | |
| 303 | + pdev->dev.of_node); | |
| 304 | + ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, | |
| 305 | + hi6421v600_devs, ARRAY_SIZE(hi6421v600_devs), | |
| 306 | + NULL, 0, NULL); | |
| 307 | + if (!ret) | |
| 308 | + return 0; | |
| 309 | + | |
| 310 | + dev_err(dev, "Failed to add child devices: %d\n", ret); | |
| 311 | + | |
| 312 | +irq_malloc: | |
| 313 | + free_irq(pmic->irq, pmic); | |
| 314 | + | |
| 315 | + return ret; | |
| 316 | +} | |
| 317 | + | |
| 318 | +static void hi6421_spmi_pmic_remove(struct spmi_device *pdev) | |
| 319 | +{ | |
| 320 | + struct hi6421_spmi_pmic *pmic = dev_get_drvdata(&pdev->dev); | |
| 321 | + | |
| 322 | + free_irq(pmic->irq, pmic); | |
| 323 | +} | |
| 324 | + | |
| 325 | +static const struct of_device_id pmic_spmi_id_table[] = { | |
| 326 | + { .compatible = "hisilicon,hi6421-spmi" }, | |
| 327 | + { } | |
| 328 | +}; | |
| 329 | +MODULE_DEVICE_TABLE(of, pmic_spmi_id_table); | |
| 330 | + | |
| 331 | +static struct spmi_driver hi6421_spmi_pmic_driver = { | |
| 332 | + .driver = { | |
| 333 | + .name = "hi6421-spmi-pmic", | |
| 334 | + .of_match_table = pmic_spmi_id_table, | |
| 335 | + }, | |
| 336 | + .probe = hi6421_spmi_pmic_probe, | |
| 337 | + .remove = hi6421_spmi_pmic_remove, | |
| 338 | +}; | |
| 339 | +module_spmi_driver(hi6421_spmi_pmic_driver); | |
| 340 | + | |
| 341 | +MODULE_DESCRIPTION("HiSilicon Hi6421v600 SPMI PMIC driver"); | |
| 342 | +MODULE_LICENSE("GPL v2"); | |
| @@ -0,0 +1,478 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 2 | +/* | |
| 3 | + * Device driver for regulators in Hisi IC | |
| 4 | + * | |
| 5 | + * Copyright (c) 2013 Linaro Ltd. | |
| 6 | + * Copyright (c) 2011 Hisilicon. | |
| 7 | + * | |
| 8 | + * Guodong Xu <guodong.xu@linaro.org> | |
| 9 | + * | |
| 10 | + * This program is free software; you can redistribute it and/or modify | |
| 11 | + * it under the terms of the GNU General Public License version 2 as | |
| 12 | + * published by the Free Software Foundation. | |
| 13 | + * | |
| 14 | + * This program is distributed in the hope that it will be useful, | |
| 15 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 16 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 17 | + * GNU General Public License for more details. | |
| 18 | + */ | |
| 19 | + | |
| 20 | +#include <linux/delay.h> | |
| 21 | +#include <linux/device.h> | |
| 22 | +#include <linux/err.h> | |
| 23 | +#include <linux/io.h> | |
| 24 | +#include <linux/mfd/hi6421-spmi-pmic.h> | |
| 25 | +#include <linux/module.h> | |
| 26 | +#include <linux/of_address.h> | |
| 27 | +#include <linux/of_device.h> | |
| 28 | +#include <linux/of.h> | |
| 29 | +#include <linux/platform_device.h> | |
| 30 | +#include <linux/regmap.h> | |
| 31 | +#include <linux/regulator/driver.h> | |
| 32 | +#include <linux/regulator/machine.h> | |
| 33 | +#include <linux/regulator/of_regulator.h> | |
| 34 | +#include <linux/seq_file.h> | |
| 35 | +#include <linux/slab.h> | |
| 36 | +#include <linux/spmi.h> | |
| 37 | +#include <linux/time.h> | |
| 38 | +#include <linux/uaccess.h> | |
| 39 | + | |
| 40 | +#define rdev_dbg(rdev, fmt, arg...) \ | |
| 41 | + pr_debug("%s: %s: " fmt, (rdev)->desc->name, __func__, ##arg) | |
| 42 | + | |
| 43 | +struct hi6421v600_regulator { | |
| 44 | + struct regulator_desc rdesc; | |
| 45 | + struct hi6421_spmi_pmic *pmic; | |
| 46 | + u32 eco_mode_mask, eco_uA; | |
| 47 | +}; | |
| 48 | + | |
| 49 | +static DEFINE_MUTEX(enable_mutex); | |
| 50 | + | |
| 51 | +/* | |
| 52 | + * helper function to ensure when it returns it is at least 'delay_us' | |
| 53 | + * microseconds after 'since'. | |
| 54 | + */ | |
| 55 | + | |
| 56 | +static int hi6421_spmi_regulator_is_enabled(struct regulator_dev *rdev) | |
| 57 | +{ | |
| 58 | + struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev); | |
| 59 | + struct hi6421_spmi_pmic *pmic = sreg->pmic; | |
| 60 | + u32 reg_val; | |
| 61 | + | |
| 62 | + reg_val = hi6421_spmi_pmic_read(pmic, rdev->desc->enable_reg); | |
| 63 | + | |
| 64 | + rdev_dbg(rdev, | |
| 65 | + "enable_reg=0x%x, val= 0x%x, enable_state=%d\n", | |
| 66 | + rdev->desc->enable_reg, | |
| 67 | + reg_val, (reg_val & rdev->desc->enable_mask)); | |
| 68 | + | |
| 69 | + return ((reg_val & rdev->desc->enable_mask) != 0); | |
| 70 | +} | |
| 71 | + | |
| 72 | +static int hi6421_spmi_regulator_enable(struct regulator_dev *rdev) | |
| 73 | +{ | |
| 74 | + struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev); | |
| 75 | + struct hi6421_spmi_pmic *pmic = sreg->pmic; | |
| 76 | + | |
| 77 | + /* cannot enable more than one regulator at one time */ | |
| 78 | + mutex_lock(&enable_mutex); | |
| 79 | + usleep_range(HISI_REGS_ENA_PROTECT_TIME, | |
| 80 | + HISI_REGS_ENA_PROTECT_TIME + 1000); | |
| 81 | + | |
| 82 | + /* set enable register */ | |
| 83 | + rdev_dbg(rdev, | |
| 84 | + "off_on_delay=%d us, enable_reg=0x%x, enable_mask=0x%x\n", | |
| 85 | + rdev->desc->off_on_delay, rdev->desc->enable_reg, | |
| 86 | + rdev->desc->enable_mask); | |
| 87 | + | |
| 88 | + hi6421_spmi_pmic_rmw(pmic, rdev->desc->enable_reg, | |
| 89 | + rdev->desc->enable_mask, | |
| 90 | + rdev->desc->enable_mask); | |
| 91 | + | |
| 92 | + mutex_unlock(&enable_mutex); | |
| 93 | + | |
| 94 | + return 0; | |
| 95 | +} | |
| 96 | + | |
| 97 | +static int hi6421_spmi_regulator_disable(struct regulator_dev *rdev) | |
| 98 | +{ | |
| 99 | + struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev); | |
| 100 | + struct hi6421_spmi_pmic *pmic = sreg->pmic; | |
| 101 | + | |
| 102 | + /* set enable register to 0 */ | |
| 103 | + rdev_dbg(rdev, "enable_reg=0x%x, enable_mask=0x%x\n", | |
| 104 | + rdev->desc->enable_reg, rdev->desc->enable_mask); | |
| 105 | + | |
| 106 | + hi6421_spmi_pmic_rmw(pmic, rdev->desc->enable_reg, | |
| 107 | + rdev->desc->enable_mask, 0); | |
| 108 | + | |
| 109 | + return 0; | |
| 110 | +} | |
| 111 | + | |
| 112 | +static int hi6421_spmi_regulator_get_voltage_sel(struct regulator_dev *rdev) | |
| 113 | +{ | |
| 114 | + struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev); | |
| 115 | + struct hi6421_spmi_pmic *pmic = sreg->pmic; | |
| 116 | + u32 reg_val, selector; | |
| 117 | + | |
| 118 | + /* get voltage selector */ | |
| 119 | + reg_val = hi6421_spmi_pmic_read(pmic, rdev->desc->vsel_reg); | |
| 120 | + | |
| 121 | + selector = (reg_val & rdev->desc->vsel_mask) >> (ffs(rdev->desc->vsel_mask) - 1); | |
| 122 | + | |
| 123 | + rdev_dbg(rdev, | |
| 124 | + "vsel_reg=0x%x, value=0x%x, entry=0x%x, voltage=%d mV\n", | |
| 125 | + rdev->desc->vsel_reg, reg_val, selector, | |
| 126 | + rdev->desc->ops->list_voltage(rdev, selector) / 1000); | |
| 127 | + | |
| 128 | + return selector; | |
| 129 | +} | |
| 130 | + | |
| 131 | +static int hi6421_spmi_regulator_set_voltage_sel(struct regulator_dev *rdev, | |
| 132 | + unsigned int selector) | |
| 133 | +{ | |
| 134 | + struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev); | |
| 135 | + struct hi6421_spmi_pmic *pmic = sreg->pmic; | |
| 136 | + u32 reg_val; | |
| 137 | + | |
| 138 | + if (unlikely(selector >= rdev->desc->n_voltages)) | |
| 139 | + return -EINVAL; | |
| 140 | + | |
| 141 | + reg_val = selector << (ffs(rdev->desc->vsel_mask) - 1); | |
| 142 | + | |
| 143 | + /* set voltage selector */ | |
| 144 | + rdev_dbg(rdev, | |
| 145 | + "vsel_reg=0x%x, mask=0x%x, value=0x%x, voltage=%d mV\n", | |
| 146 | + rdev->desc->vsel_reg, rdev->desc->vsel_mask, reg_val, | |
| 147 | + rdev->desc->ops->list_voltage(rdev, selector) / 1000); | |
| 148 | + | |
| 149 | + hi6421_spmi_pmic_rmw(pmic, rdev->desc->vsel_reg, | |
| 150 | + rdev->desc->vsel_mask, reg_val); | |
| 151 | + | |
| 152 | + return 0; | |
| 153 | +} | |
| 154 | + | |
| 155 | +static unsigned int hi6421_spmi_regulator_get_mode(struct regulator_dev *rdev) | |
| 156 | +{ | |
| 157 | + struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev); | |
| 158 | + struct hi6421_spmi_pmic *pmic = sreg->pmic; | |
| 159 | + unsigned int mode; | |
| 160 | + u32 reg_val; | |
| 161 | + | |
| 162 | + reg_val = hi6421_spmi_pmic_read(pmic, rdev->desc->enable_reg); | |
| 163 | + | |
| 164 | + if (reg_val & sreg->eco_mode_mask) | |
| 165 | + mode = REGULATOR_MODE_IDLE; | |
| 166 | + else | |
| 167 | + mode = REGULATOR_MODE_NORMAL; | |
| 168 | + | |
| 169 | + rdev_dbg(rdev, | |
| 170 | + "enable_reg=0x%x, eco_mode_mask=0x%x, reg_val=0x%x, %s mode\n", | |
| 171 | + rdev->desc->enable_reg, sreg->eco_mode_mask, reg_val, | |
| 172 | + mode == REGULATOR_MODE_IDLE ? "idle" : "normal"); | |
| 173 | + | |
| 174 | + return mode; | |
| 175 | +} | |
| 176 | + | |
| 177 | +static int hi6421_spmi_regulator_set_mode(struct regulator_dev *rdev, | |
| 178 | + unsigned int mode) | |
| 179 | +{ | |
| 180 | + struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev); | |
| 181 | + struct hi6421_spmi_pmic *pmic = sreg->pmic; | |
| 182 | + u32 val; | |
| 183 | + | |
| 184 | + switch (mode) { | |
| 185 | + case REGULATOR_MODE_NORMAL: | |
| 186 | + val = 0; | |
| 187 | + break; | |
| 188 | + case REGULATOR_MODE_IDLE: | |
| 189 | + val = sreg->eco_mode_mask << (ffs(sreg->eco_mode_mask) - 1); | |
| 190 | + break; | |
| 191 | + default: | |
| 192 | + return -EINVAL; | |
| 193 | + } | |
| 194 | + | |
| 195 | + /* set mode */ | |
| 196 | + rdev_dbg(rdev, "enable_reg=0x%x, eco_mode_mask=0x%x, value=0x%x\n", | |
| 197 | + rdev->desc->enable_reg, sreg->eco_mode_mask, val); | |
| 198 | + | |
| 199 | + hi6421_spmi_pmic_rmw(pmic, rdev->desc->enable_reg, | |
| 200 | + sreg->eco_mode_mask, val); | |
| 201 | + | |
| 202 | + return 0; | |
| 203 | +} | |
| 204 | + | |
| 205 | +static unsigned int | |
| 206 | +hi6421_spmi_regulator_get_optimum_mode(struct regulator_dev *rdev, | |
| 207 | + int input_uV, int output_uV, | |
| 208 | + int load_uA) | |
| 209 | +{ | |
| 210 | + struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev); | |
| 211 | + | |
| 212 | + if (load_uA || ((unsigned int)load_uA > sreg->eco_uA)) | |
| 213 | + return REGULATOR_MODE_NORMAL; | |
| 214 | + | |
| 215 | + return REGULATOR_MODE_IDLE; | |
| 216 | +} | |
| 217 | + | |
| 218 | +static int hi6421_spmi_dt_parse(struct platform_device *pdev, | |
| 219 | + struct hi6421v600_regulator *sreg, | |
| 220 | + struct regulator_desc *rdesc) | |
| 221 | +{ | |
| 222 | + struct device *dev = &pdev->dev; | |
| 223 | + struct device_node *np = dev->of_node; | |
| 224 | + unsigned int *v_table; | |
| 225 | + int ret; | |
| 226 | + | |
| 227 | + ret = of_property_read_u32(np, "reg", &rdesc->enable_reg); | |
| 228 | + if (ret) { | |
| 229 | + dev_err(dev, "missing reg property\n"); | |
| 230 | + return ret; | |
| 231 | + } | |
| 232 | + | |
| 233 | + ret = of_property_read_u32(np, "vsel-reg", &rdesc->vsel_reg); | |
| 234 | + if (ret) { | |
| 235 | + dev_err(dev, "missing vsel-reg property\n"); | |
| 236 | + return ret; | |
| 237 | + } | |
| 238 | + | |
| 239 | + ret = of_property_read_u32(np, "enable-mask", &rdesc->enable_mask); | |
| 240 | + if (ret) { | |
| 241 | + dev_err(dev, "missing enable-mask property\n"); | |
| 242 | + return ret; | |
| 243 | + } | |
| 244 | + | |
| 245 | + /* | |
| 246 | + * Not all regulators work on idle mode | |
| 247 | + */ | |
| 248 | + ret = of_property_read_u32(np, "idle-mode-mask", &sreg->eco_mode_mask); | |
| 249 | + if (ret) { | |
| 250 | + dev_dbg(dev, "LDO doesn't support economy mode.\n"); | |
| 251 | + sreg->eco_mode_mask = 0; | |
| 252 | + sreg->eco_uA = 0; | |
| 253 | + } else { | |
| 254 | + ret = of_property_read_u32(np, "eco-microamp", &sreg->eco_uA); | |
| 255 | + if (ret) { | |
| 256 | + dev_err(dev, "missing eco-microamp property\n"); | |
| 257 | + return ret; | |
| 258 | + } | |
| 259 | + } | |
| 260 | + | |
| 261 | + /* parse .off-on-delay */ | |
| 262 | + ret = of_property_read_u32(np, "off-on-delay-us", | |
| 263 | + &rdesc->off_on_delay); | |
| 264 | + if (ret) { | |
| 265 | + dev_err(dev, "missing off-on-delay-us property\n"); | |
| 266 | + return ret; | |
| 267 | + } | |
| 268 | + | |
| 269 | + /* parse .enable_time */ | |
| 270 | + ret = of_property_read_u32(np, "startup-delay-us", | |
| 271 | + &rdesc->enable_time); | |
| 272 | + if (ret) { | |
| 273 | + dev_err(dev, "missing startup-delay-us property\n"); | |
| 274 | + return ret; | |
| 275 | + } | |
| 276 | + | |
| 277 | + /* FIXME: are there a better value for this? */ | |
| 278 | + rdesc->ramp_delay = rdesc->enable_time; | |
| 279 | + | |
| 280 | + /* parse volt_table */ | |
| 281 | + | |
| 282 | + rdesc->n_voltages = of_property_count_u32_elems(np, "voltage-table"); | |
| 283 | + | |
| 284 | + v_table = devm_kzalloc(dev, sizeof(unsigned int) * rdesc->n_voltages, | |
| 285 | + GFP_KERNEL); | |
| 286 | + if (unlikely(!v_table)) | |
| 287 | + return -ENOMEM; | |
| 288 | + rdesc->volt_table = v_table; | |
| 289 | + | |
| 290 | + ret = of_property_read_u32_array(np, "voltage-table", | |
| 291 | + v_table, rdesc->n_voltages); | |
| 292 | + if (ret) { | |
| 293 | + dev_err(dev, "missing voltage-table property\n"); | |
| 294 | + return ret; | |
| 295 | + } | |
| 296 | + | |
| 297 | + /* | |
| 298 | + * Instead of explicitly requiring a mask for the voltage selector, | |
| 299 | + * as they all start from bit zero (at least on the known LDOs), | |
| 300 | + * just use the number of voltages at the voltage table, getting the | |
| 301 | + * minimal mask that would pick everything. | |
| 302 | + */ | |
| 303 | + rdesc->vsel_mask = (1 << (fls(rdesc->n_voltages) - 1)) - 1; | |
| 304 | + | |
| 305 | + dev_dbg(dev, "voltage selector settings: reg: 0x%x, mask: 0x%x\n", | |
| 306 | + rdesc->vsel_reg, rdesc->vsel_mask); | |
| 307 | + | |
| 308 | + return 0; | |
| 309 | +} | |
| 310 | + | |
| 311 | +static const struct regulator_ops hi6421_spmi_ldo_rops = { | |
| 312 | + .is_enabled = hi6421_spmi_regulator_is_enabled, | |
| 313 | + .enable = hi6421_spmi_regulator_enable, | |
| 314 | + .disable = hi6421_spmi_regulator_disable, | |
| 315 | + .list_voltage = regulator_list_voltage_table, | |
| 316 | + .map_voltage = regulator_map_voltage_iterate, | |
| 317 | + .get_voltage_sel = hi6421_spmi_regulator_get_voltage_sel, | |
| 318 | + .set_voltage_sel = hi6421_spmi_regulator_set_voltage_sel, | |
| 319 | + .get_mode = hi6421_spmi_regulator_get_mode, | |
| 320 | + .set_mode = hi6421_spmi_regulator_set_mode, | |
| 321 | + .get_optimum_mode = hi6421_spmi_regulator_get_optimum_mode, | |
| 322 | +}; | |
| 323 | + | |
| 324 | +static int hi6421_spmi_regulator_probe_ldo(struct platform_device *pdev, | |
| 325 | + struct device_node *np, | |
| 326 | + struct hi6421_spmi_pmic *pmic) | |
| 327 | +{ | |
| 328 | + struct regulation_constraints *constraint; | |
| 329 | + struct regulator_init_data *initdata; | |
| 330 | + struct regulator_config config = { }; | |
| 331 | + struct hi6421v600_regulator *sreg; | |
| 332 | + struct device *dev = &pdev->dev; | |
| 333 | + struct regulator_desc *rdesc; | |
| 334 | + struct regulator_dev *rdev; | |
| 335 | + const char *supplyname; | |
| 336 | + int ret; | |
| 337 | + | |
| 338 | + initdata = of_get_regulator_init_data(dev, np, NULL); | |
| 339 | + if (!initdata) { | |
| 340 | + dev_err(dev, "failed to get regulator data\n"); | |
| 341 | + return -EINVAL; | |
| 342 | + } | |
| 343 | + | |
| 344 | + sreg = devm_kzalloc(dev, sizeof(*sreg), GFP_KERNEL); | |
| 345 | + if (!sreg) | |
| 346 | + return -ENOMEM; | |
| 347 | + | |
| 348 | + sreg->pmic = pmic; | |
| 349 | + rdesc = &sreg->rdesc; | |
| 350 | + | |
| 351 | + rdesc->name = initdata->constraints.name; | |
| 352 | + rdesc->ops = &hi6421_spmi_ldo_rops; | |
| 353 | + rdesc->type = REGULATOR_VOLTAGE; | |
| 354 | + rdesc->min_uV = initdata->constraints.min_uV; | |
| 355 | + | |
| 356 | + supplyname = of_get_property(np, "supply_name", NULL); | |
| 357 | + if (supplyname) | |
| 358 | + initdata->supply_regulator = supplyname; | |
| 359 | + | |
| 360 | + /* parse device tree data for regulator specific */ | |
| 361 | + ret = hi6421_spmi_dt_parse(pdev, sreg, rdesc); | |
| 362 | + if (ret) | |
| 363 | + return ret; | |
| 364 | + | |
| 365 | + /* hisi regulator supports two modes */ | |
| 366 | + constraint = &initdata->constraints; | |
| 367 | + | |
| 368 | + constraint->valid_modes_mask = REGULATOR_MODE_NORMAL; | |
| 369 | + if (sreg->eco_mode_mask) { | |
| 370 | + constraint->valid_modes_mask |= REGULATOR_MODE_IDLE; | |
| 371 | + constraint->valid_ops_mask |= REGULATOR_CHANGE_MODE; | |
| 372 | + } | |
| 373 | + | |
| 374 | + config.dev = &pdev->dev; | |
| 375 | + config.init_data = initdata; | |
| 376 | + config.driver_data = sreg; | |
| 377 | + config.of_node = pdev->dev.of_node; | |
| 378 | + | |
| 379 | + /* register regulator */ | |
| 380 | + rdev = regulator_register(rdesc, &config); | |
| 381 | + if (IS_ERR(rdev)) { | |
| 382 | + dev_err(dev, "failed to register %s\n", | |
| 383 | + rdesc->name); | |
| 384 | + return PTR_ERR(rdev); | |
| 385 | + } | |
| 386 | + | |
| 387 | + rdev_dbg(rdev, "valid_modes_mask: 0x%x, valid_ops_mask: 0x%x\n", | |
| 388 | + constraint->valid_modes_mask, constraint->valid_ops_mask); | |
| 389 | + | |
| 390 | + dev_set_drvdata(dev, rdev); | |
| 391 | + | |
| 392 | + return 0; | |
| 393 | +} | |
| 394 | + | |
| 395 | +static int hi6421_spmi_regulator_probe(struct platform_device *pdev) | |
| 396 | +{ | |
| 397 | + struct device *pmic_dev = pdev->dev.parent; | |
| 398 | + struct device_node *np = pmic_dev->of_node; | |
| 399 | + struct device_node *regulators, *child; | |
| 400 | + struct platform_device *new_pdev; | |
| 401 | + struct hi6421_spmi_pmic *pmic; | |
| 402 | + int ret; | |
| 403 | + | |
| 404 | + /* | |
| 405 | + * This driver is meant to be called by hi6421-spmi-core, | |
| 406 | + * which should first set drvdata. If this doesn't happen, hit | |
| 407 | + * a warn on and return. | |
| 408 | + */ | |
| 409 | + pmic = dev_get_drvdata(pmic_dev); | |
| 410 | + if (WARN_ON(!pmic)) | |
| 411 | + return -ENODEV; | |
| 412 | + | |
| 413 | + regulators = of_get_child_by_name(np, "regulators"); | |
| 414 | + if (!regulators) { | |
| 415 | + dev_err(&pdev->dev, "regulator node not found\n"); | |
| 416 | + return -ENODEV; | |
| 417 | + } | |
| 418 | + | |
| 419 | + /* | |
| 420 | + * Parse all LDO regulator nodes | |
| 421 | + */ | |
| 422 | + for_each_child_of_node(regulators, child) { | |
| 423 | + dev_dbg(&pdev->dev, "adding child %pOF\n", child); | |
| 424 | + | |
| 425 | + new_pdev = platform_device_alloc(child->name, -1); | |
| 426 | + new_pdev->dev.parent = pmic_dev; | |
| 427 | + new_pdev->dev.of_node = of_node_get(child); | |
| 428 | + | |
| 429 | + ret = platform_device_add(new_pdev); | |
| 430 | + if (ret < 0) { | |
| 431 | + platform_device_put(new_pdev); | |
| 432 | + continue; | |
| 433 | + } | |
| 434 | + | |
| 435 | + ret = hi6421_spmi_regulator_probe_ldo(new_pdev, child, pmic); | |
| 436 | + if (ret < 0) | |
| 437 | + platform_device_put(new_pdev); | |
| 438 | + } | |
| 439 | + | |
| 440 | + of_node_put(regulators); | |
| 441 | + | |
| 442 | + return 0; | |
| 443 | +} | |
| 444 | + | |
| 445 | +static int hi6421_spmi_regulator_remove(struct platform_device *pdev) | |
| 446 | +{ | |
| 447 | + struct regulator_dev *rdev = dev_get_drvdata(&pdev->dev); | |
| 448 | + struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev); | |
| 449 | + | |
| 450 | + regulator_unregister(rdev); | |
| 451 | + | |
| 452 | + if (rdev->desc->volt_table) | |
| 453 | + devm_kfree(&pdev->dev, (unsigned int *)rdev->desc->volt_table); | |
| 454 | + | |
| 455 | + kfree(sreg); | |
| 456 | + | |
| 457 | + return 0; | |
| 458 | +} | |
| 459 | + | |
| 460 | +static const struct platform_device_id hi6421v600_regulator_table[] = { | |
| 461 | + { .name = "hi6421v600-regulator" }, | |
| 462 | + {}, | |
| 463 | +}; | |
| 464 | +MODULE_DEVICE_TABLE(platform, hi6421v600_regulator_table); | |
| 465 | + | |
| 466 | +static struct platform_driver hi6421v600_regulator_driver = { | |
| 467 | + .id_table = hi6421v600_regulator_table, | |
| 468 | + .driver = { | |
| 469 | + .name = "hi6421v600-regulator", | |
| 470 | + }, | |
| 471 | + .probe = hi6421_spmi_regulator_probe, | |
| 472 | + .remove = hi6421_spmi_regulator_remove, | |
| 473 | +}; | |
| 474 | +module_platform_driver(hi6421v600_regulator_driver); | |
| 475 | + | |
| 476 | +MODULE_DESCRIPTION("Hi6421v600 regulator driver"); | |
| 477 | +MODULE_LICENSE("GPL v2"); | |
| 478 | + | |
| @@ -0,0 +1,358 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 2 | + | |
| 3 | +#include <linux/delay.h> | |
| 4 | +#include <linux/err.h> | |
| 5 | +#include <linux/interrupt.h> | |
| 6 | +#include <linux/io.h> | |
| 7 | +#include <linux/kernel.h> | |
| 8 | +#include <linux/module.h> | |
| 9 | +#include <linux/of.h> | |
| 10 | +#include <linux/platform_device.h> | |
| 11 | +#include <linux/seq_file.h> | |
| 12 | +#include <linux/slab.h> | |
| 13 | +#include <linux/spmi.h> | |
| 14 | + | |
| 15 | +/* | |
| 16 | + * SPMI register addr | |
| 17 | + */ | |
| 18 | +#define SPMI_CHANNEL_OFFSET 0x0300 | |
| 19 | +#define SPMI_SLAVE_OFFSET 0x20 | |
| 20 | + | |
| 21 | +#define SPMI_APB_SPMI_CMD_BASE_ADDR 0x0100 | |
| 22 | + | |
| 23 | +#define SPMI_APB_SPMI_WDATA0_BASE_ADDR 0x0104 | |
| 24 | +#define SPMI_APB_SPMI_WDATA1_BASE_ADDR 0x0108 | |
| 25 | +#define SPMI_APB_SPMI_WDATA2_BASE_ADDR 0x010c | |
| 26 | +#define SPMI_APB_SPMI_WDATA3_BASE_ADDR 0x0110 | |
| 27 | + | |
| 28 | +#define SPMI_APB_SPMI_STATUS_BASE_ADDR 0x0200 | |
| 29 | + | |
| 30 | +#define SPMI_APB_SPMI_RDATA0_BASE_ADDR 0x0204 | |
| 31 | +#define SPMI_APB_SPMI_RDATA1_BASE_ADDR 0x0208 | |
| 32 | +#define SPMI_APB_SPMI_RDATA2_BASE_ADDR 0x020c | |
| 33 | +#define SPMI_APB_SPMI_RDATA3_BASE_ADDR 0x0210 | |
| 34 | + | |
| 35 | +#define SPMI_PER_DATAREG_BYTE 4 | |
| 36 | +/* | |
| 37 | + * SPMI cmd register | |
| 38 | + */ | |
| 39 | +#define SPMI_APB_SPMI_CMD_EN BIT(31) | |
| 40 | +#define SPMI_APB_SPMI_CMD_TYPE_OFFSET 24 | |
| 41 | +#define SPMI_APB_SPMI_CMD_LENGTH_OFFSET 20 | |
| 42 | +#define SPMI_APB_SPMI_CMD_SLAVEID_OFFSET 16 | |
| 43 | +#define SPMI_APB_SPMI_CMD_ADDR_OFFSET 0 | |
| 44 | + | |
| 45 | +/* Command Opcodes */ | |
| 46 | + | |
| 47 | +enum spmi_controller_cmd_op_code { | |
| 48 | + SPMI_CMD_REG_ZERO_WRITE = 0, | |
| 49 | + SPMI_CMD_REG_WRITE = 1, | |
| 50 | + SPMI_CMD_REG_READ = 2, | |
| 51 | + SPMI_CMD_EXT_REG_WRITE = 3, | |
| 52 | + SPMI_CMD_EXT_REG_READ = 4, | |
| 53 | + SPMI_CMD_EXT_REG_WRITE_L = 5, | |
| 54 | + SPMI_CMD_EXT_REG_READ_L = 6, | |
| 55 | + SPMI_CMD_REG_RESET = 7, | |
| 56 | + SPMI_CMD_REG_SLEEP = 8, | |
| 57 | + SPMI_CMD_REG_SHUTDOWN = 9, | |
| 58 | + SPMI_CMD_REG_WAKEUP = 10, | |
| 59 | +}; | |
| 60 | + | |
| 61 | +/* | |
| 62 | + * SPMI status register | |
| 63 | + */ | |
| 64 | +#define SPMI_APB_TRANS_DONE BIT(0) | |
| 65 | +#define SPMI_APB_TRANS_FAIL BIT(2) | |
| 66 | + | |
| 67 | +/* Command register fields */ | |
| 68 | +#define SPMI_CONTROLLER_CMD_MAX_BYTE_COUNT 16 | |
| 69 | + | |
| 70 | +/* Maximum number of support PMIC peripherals */ | |
| 71 | +#define SPMI_CONTROLLER_TIMEOUT_US 1000 | |
| 72 | +#define SPMI_CONTROLLER_MAX_TRANS_BYTES 16 | |
| 73 | + | |
| 74 | +struct spmi_controller_dev { | |
| 75 | + struct spmi_controller *controller; | |
| 76 | + struct device *dev; | |
| 77 | + void __iomem *base; | |
| 78 | + spinlock_t lock; | |
| 79 | + u32 channel; | |
| 80 | +}; | |
| 81 | + | |
| 82 | +static int spmi_controller_wait_for_done(struct device *dev, | |
| 83 | + struct spmi_controller_dev *ctrl_dev, | |
| 84 | + void __iomem *base, u8 sid, u16 addr) | |
| 85 | +{ | |
| 86 | + u32 timeout = SPMI_CONTROLLER_TIMEOUT_US; | |
| 87 | + u32 status, offset; | |
| 88 | + | |
| 89 | + offset = SPMI_APB_SPMI_STATUS_BASE_ADDR; | |
| 90 | + offset += SPMI_CHANNEL_OFFSET * ctrl_dev->channel + SPMI_SLAVE_OFFSET * sid; | |
| 91 | + | |
| 92 | + do { | |
| 93 | + status = readl(base + offset); | |
| 94 | + | |
| 95 | + if (status & SPMI_APB_TRANS_DONE) { | |
| 96 | + if (status & SPMI_APB_TRANS_FAIL) { | |
| 97 | + dev_err(dev, "%s: transaction failed (0x%x)\n", | |
| 98 | + __func__, status); | |
| 99 | + return -EIO; | |
| 100 | + } | |
| 101 | + dev_dbg(dev, "%s: status 0x%x\n", __func__, status); | |
| 102 | + return 0; | |
| 103 | + } | |
| 104 | + udelay(1); | |
| 105 | + } while (timeout--); | |
| 106 | + | |
| 107 | + dev_err(dev, "%s: timeout, status 0x%x\n", __func__, status); | |
| 108 | + return -ETIMEDOUT; | |
| 109 | +} | |
| 110 | + | |
| 111 | +static int spmi_read_cmd(struct spmi_controller *ctrl, | |
| 112 | + u8 opc, u8 slave_id, u16 slave_addr, u8 *__buf, size_t bc) | |
| 113 | +{ | |
| 114 | + struct spmi_controller_dev *spmi_controller = dev_get_drvdata(&ctrl->dev); | |
| 115 | + u32 chnl_ofst = SPMI_CHANNEL_OFFSET * spmi_controller->channel; | |
| 116 | + unsigned long flags; | |
| 117 | + u8 *buf = __buf; | |
| 118 | + u32 cmd, data; | |
| 119 | + int rc; | |
| 120 | + u8 op_code, i; | |
| 121 | + | |
| 122 | + if (bc > SPMI_CONTROLLER_MAX_TRANS_BYTES) { | |
| 123 | + dev_err(&ctrl->dev, | |
| 124 | + "spmi_controller supports 1..%d bytes per trans, but:%zu requested\n", | |
| 125 | + SPMI_CONTROLLER_MAX_TRANS_BYTES, bc); | |
| 126 | + return -EINVAL; | |
| 127 | + } | |
| 128 | + | |
| 129 | + switch (opc) { | |
| 130 | + case SPMI_CMD_READ: | |
| 131 | + op_code = SPMI_CMD_REG_READ; | |
| 132 | + break; | |
| 133 | + case SPMI_CMD_EXT_READ: | |
| 134 | + op_code = SPMI_CMD_EXT_REG_READ; | |
| 135 | + break; | |
| 136 | + case SPMI_CMD_EXT_READL: | |
| 137 | + op_code = SPMI_CMD_EXT_REG_READ_L; | |
| 138 | + break; | |
| 139 | + default: | |
| 140 | + dev_err(&ctrl->dev, "invalid read cmd 0x%x\n", opc); | |
| 141 | + return -EINVAL; | |
| 142 | + } | |
| 143 | + | |
| 144 | + cmd = SPMI_APB_SPMI_CMD_EN | | |
| 145 | + (op_code << SPMI_APB_SPMI_CMD_TYPE_OFFSET) | | |
| 146 | + ((bc - 1) << SPMI_APB_SPMI_CMD_LENGTH_OFFSET) | | |
| 147 | + ((slave_id & 0xf) << SPMI_APB_SPMI_CMD_SLAVEID_OFFSET) | /* slvid */ | |
| 148 | + ((slave_addr & 0xffff) << SPMI_APB_SPMI_CMD_ADDR_OFFSET); /* slave_addr */ | |
| 149 | + | |
| 150 | + spin_lock_irqsave(&spmi_controller->lock, flags); | |
| 151 | + | |
| 152 | + writel(cmd, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_CMD_BASE_ADDR); | |
| 153 | + | |
| 154 | + rc = spmi_controller_wait_for_done(&ctrl->dev, spmi_controller, | |
| 155 | + spmi_controller->base, slave_id, slave_addr); | |
| 156 | + if (rc) | |
| 157 | + goto done; | |
| 158 | + | |
| 159 | + for (i = 0; bc > i * SPMI_PER_DATAREG_BYTE; i++) { | |
| 160 | + data = readl(spmi_controller->base + chnl_ofst + | |
| 161 | + SPMI_SLAVE_OFFSET * slave_id + | |
| 162 | + SPMI_APB_SPMI_RDATA0_BASE_ADDR + | |
| 163 | + i * SPMI_PER_DATAREG_BYTE); | |
| 164 | + data = be32_to_cpu((__be32)data); | |
| 165 | + if ((bc - i * SPMI_PER_DATAREG_BYTE) >> 2) { | |
| 166 | + memcpy(buf, &data, sizeof(data)); | |
| 167 | + buf += sizeof(data); | |
| 168 | + } else { | |
| 169 | + memcpy(buf, &data, bc % SPMI_PER_DATAREG_BYTE); | |
| 170 | + buf += (bc % SPMI_PER_DATAREG_BYTE); | |
| 171 | + } | |
| 172 | + } | |
| 173 | + | |
| 174 | +done: | |
| 175 | + spin_unlock_irqrestore(&spmi_controller->lock, flags); | |
| 176 | + if (rc) | |
| 177 | + dev_err(&ctrl->dev, | |
| 178 | + "spmi read wait timeout op:0x%x slave_id:%d slave_addr:0x%x bc:%zu\n", | |
| 179 | + opc, slave_id, slave_addr, bc + 1); | |
| 180 | + else | |
| 181 | + dev_dbg(&ctrl->dev, "%s: id:%d slave_addr:0x%x, read value: %*ph\n", | |
| 182 | + __func__, slave_id, slave_addr, (int)bc, __buf); | |
| 183 | + | |
| 184 | + return rc; | |
| 185 | +} | |
| 186 | + | |
| 187 | +static int spmi_write_cmd(struct spmi_controller *ctrl, | |
| 188 | + u8 opc, u8 slave_id, u16 slave_addr, const u8 *__buf, size_t bc) | |
| 189 | +{ | |
| 190 | + struct spmi_controller_dev *spmi_controller = dev_get_drvdata(&ctrl->dev); | |
| 191 | + u32 chnl_ofst = SPMI_CHANNEL_OFFSET * spmi_controller->channel; | |
| 192 | + const u8 *buf = __buf; | |
| 193 | + unsigned long flags; | |
| 194 | + u32 cmd, data; | |
| 195 | + int rc; | |
| 196 | + u8 op_code, i; | |
| 197 | + | |
| 198 | + if (bc > SPMI_CONTROLLER_MAX_TRANS_BYTES) { | |
| 199 | + dev_err(&ctrl->dev, | |
| 200 | + "spmi_controller supports 1..%d bytes per trans, but:%zu requested\n", | |
| 201 | + SPMI_CONTROLLER_MAX_TRANS_BYTES, bc); | |
| 202 | + return -EINVAL; | |
| 203 | + } | |
| 204 | + | |
| 205 | + switch (opc) { | |
| 206 | + case SPMI_CMD_WRITE: | |
| 207 | + op_code = SPMI_CMD_REG_WRITE; | |
| 208 | + break; | |
| 209 | + case SPMI_CMD_EXT_WRITE: | |
| 210 | + op_code = SPMI_CMD_EXT_REG_WRITE; | |
| 211 | + break; | |
| 212 | + case SPMI_CMD_EXT_WRITEL: | |
| 213 | + op_code = SPMI_CMD_EXT_REG_WRITE_L; | |
| 214 | + break; | |
| 215 | + default: | |
| 216 | + dev_err(&ctrl->dev, "invalid write cmd 0x%x\n", opc); | |
| 217 | + return -EINVAL; | |
| 218 | + } | |
| 219 | + | |
| 220 | + cmd = SPMI_APB_SPMI_CMD_EN | | |
| 221 | + (op_code << SPMI_APB_SPMI_CMD_TYPE_OFFSET) | | |
| 222 | + ((bc - 1) << SPMI_APB_SPMI_CMD_LENGTH_OFFSET) | | |
| 223 | + ((slave_id & 0xf) << SPMI_APB_SPMI_CMD_SLAVEID_OFFSET) | | |
| 224 | + ((slave_addr & 0xffff) << SPMI_APB_SPMI_CMD_ADDR_OFFSET); | |
| 225 | + | |
| 226 | + /* Write data to FIFOs */ | |
| 227 | + spin_lock_irqsave(&spmi_controller->lock, flags); | |
| 228 | + | |
| 229 | + for (i = 0; bc > i * SPMI_PER_DATAREG_BYTE; i++) { | |
| 230 | + data = 0; | |
| 231 | + if ((bc - i * SPMI_PER_DATAREG_BYTE) >> 2) { | |
| 232 | + memcpy(&data, buf, sizeof(data)); | |
| 233 | + buf += sizeof(data); | |
| 234 | + } else { | |
| 235 | + memcpy(&data, buf, bc % SPMI_PER_DATAREG_BYTE); | |
| 236 | + buf += (bc % SPMI_PER_DATAREG_BYTE); | |
| 237 | + } | |
| 238 | + | |
| 239 | + writel((u32)cpu_to_be32(data), | |
| 240 | + spmi_controller->base + chnl_ofst + | |
| 241 | + SPMI_APB_SPMI_WDATA0_BASE_ADDR + | |
| 242 | + SPMI_PER_DATAREG_BYTE * i); | |
| 243 | + } | |
| 244 | + | |
| 245 | + /* Start the transaction */ | |
| 246 | + writel(cmd, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_CMD_BASE_ADDR); | |
| 247 | + | |
| 248 | + rc = spmi_controller_wait_for_done(&ctrl->dev, spmi_controller, | |
| 249 | + spmi_controller->base, slave_id, | |
| 250 | + slave_addr); | |
| 251 | + spin_unlock_irqrestore(&spmi_controller->lock, flags); | |
| 252 | + | |
| 253 | + if (rc) | |
| 254 | + dev_err(&ctrl->dev, "spmi write wait timeout op:0x%x slave_id:%d slave_addr:0x%x bc:%zu\n", | |
| 255 | + opc, slave_id, slave_addr, bc); | |
| 256 | + else | |
| 257 | + dev_dbg(&ctrl->dev, "%s: id:%d slave_addr:0x%x, wrote value: %*ph\n", | |
| 258 | + __func__, slave_id, slave_addr, (int)bc, __buf); | |
| 259 | + | |
| 260 | + return rc; | |
| 261 | +} | |
| 262 | + | |
| 263 | +static int spmi_controller_probe(struct platform_device *pdev) | |
| 264 | +{ | |
| 265 | + struct spmi_controller_dev *spmi_controller; | |
| 266 | + struct spmi_controller *ctrl; | |
| 267 | + struct resource *iores; | |
| 268 | + int ret; | |
| 269 | + | |
| 270 | + ctrl = spmi_controller_alloc(&pdev->dev, sizeof(*spmi_controller)); | |
| 271 | + if (!ctrl) { | |
| 272 | + dev_err(&pdev->dev, "can not allocate spmi_controller data\n"); | |
| 273 | + return -ENOMEM; | |
| 274 | + } | |
| 275 | + spmi_controller = spmi_controller_get_drvdata(ctrl); | |
| 276 | + spmi_controller->controller = ctrl; | |
| 277 | + | |
| 278 | + iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 279 | + if (!iores) { | |
| 280 | + dev_err(&pdev->dev, "can not get resource!\n"); | |
| 281 | + return -EINVAL; | |
| 282 | + } | |
| 283 | + | |
| 284 | + spmi_controller->base = devm_ioremap(&pdev->dev, iores->start, | |
| 285 | + resource_size(iores)); | |
| 286 | + if (!spmi_controller->base) { | |
| 287 | + dev_err(&pdev->dev, "can not remap base addr!\n"); | |
| 288 | + return -EADDRNOTAVAIL; | |
| 289 | + } | |
| 290 | + | |
| 291 | + ret = of_property_read_u32(pdev->dev.of_node, "spmi-channel", | |
| 292 | + &spmi_controller->channel); | |
| 293 | + if (ret) { | |
| 294 | + dev_err(&pdev->dev, "can not get channel\n"); | |
| 295 | + return -ENODEV; | |
| 296 | + } | |
| 297 | + | |
| 298 | + platform_set_drvdata(pdev, spmi_controller); | |
| 299 | + dev_set_drvdata(&ctrl->dev, spmi_controller); | |
| 300 | + | |
| 301 | + spin_lock_init(&spmi_controller->lock); | |
| 302 | + | |
| 303 | + ctrl->nr = spmi_controller->channel; | |
| 304 | + ctrl->dev.parent = pdev->dev.parent; | |
| 305 | + ctrl->dev.of_node = of_node_get(pdev->dev.of_node); | |
| 306 | + | |
| 307 | + /* Callbacks */ | |
| 308 | + ctrl->read_cmd = spmi_read_cmd; | |
| 309 | + ctrl->write_cmd = spmi_write_cmd; | |
| 310 | + | |
| 311 | + ret = spmi_controller_add(ctrl); | |
| 312 | + if (ret) | |
| 313 | + dev_err(&pdev->dev, "spmi_add_controller failed with error %d!\n", ret); | |
| 314 | + | |
| 315 | + return ret; | |
| 316 | +} | |
| 317 | + | |
| 318 | +static int spmi_del_controller(struct platform_device *pdev) | |
| 319 | +{ | |
| 320 | + struct spmi_controller *ctrl = platform_get_drvdata(pdev); | |
| 321 | + | |
| 322 | + spmi_controller_remove(ctrl); | |
| 323 | + kfree(ctrl); | |
| 324 | + return 0; | |
| 325 | +} | |
| 326 | + | |
| 327 | +static const struct of_device_id spmi_controller_match_table[] = { | |
| 328 | + { | |
| 329 | + .compatible = "hisilicon,kirin970-spmi-controller", | |
| 330 | + }, | |
| 331 | + {} | |
| 332 | +}; | |
| 333 | +MODULE_DEVICE_TABLE(of, spmi_controller_match_table); | |
| 334 | + | |
| 335 | +static struct platform_driver spmi_controller_driver = { | |
| 336 | + .probe = spmi_controller_probe, | |
| 337 | + .remove = spmi_del_controller, | |
| 338 | + .driver = { | |
| 339 | + .name = "hisi_spmi_controller", | |
| 340 | + .of_match_table = spmi_controller_match_table, | |
| 341 | + }, | |
| 342 | +}; | |
| 343 | + | |
| 344 | +static int __init spmi_controller_init(void) | |
| 345 | +{ | |
| 346 | + return platform_driver_register(&spmi_controller_driver); | |
| 347 | +} | |
| 348 | +postcore_initcall(spmi_controller_init); | |
| 349 | + | |
| 350 | +static void __exit spmi_controller_exit(void) | |
| 351 | +{ | |
| 352 | + platform_driver_unregister(&spmi_controller_driver); | |
| 353 | +} | |
| 354 | +module_exit(spmi_controller_exit); | |
| 355 | + | |
| 356 | +MODULE_LICENSE("GPL v2"); | |
| 357 | +MODULE_VERSION("1.0"); | |
| 358 | +MODULE_ALIAS("platform:spmi_controller"); | |
| @@ -0,0 +1,159 @@ | ||
| 1 | +# SPDX-License-Identifier: GPL-2.0 | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/mfd/hisilicon,hi6421-spmi-pmic.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: HiSilicon 6421v600 SPMI PMIC | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Mauro Carvalho Chehab <mchehab+huawei@kernel.org> | |
| 11 | + | |
| 12 | +description: | | |
| 13 | + HiSilicon 6421v600 should be connected inside a MIPI System Power Management | |
| 14 | + (SPMI) bus. It provides interrupts and power supply. | |
| 15 | + | |
| 16 | + The GPIO and interrupt settings are represented as part of the top-level PMIC | |
| 17 | + node. | |
| 18 | + | |
| 19 | + The SPMI controller part is provided by | |
| 20 | + drivers/staging/hikey9xx/hisilicon,hisi-spmi-controller.yaml. | |
| 21 | + | |
| 22 | +properties: | |
| 23 | + $nodename: | |
| 24 | + pattern: "pmic@[0-9a-f]" | |
| 25 | + | |
| 26 | + compatible: | |
| 27 | + const: hisilicon,hi6421v600-spmi | |
| 28 | + | |
| 29 | + reg: | |
| 30 | + maxItems: 1 | |
| 31 | + | |
| 32 | + '#interrupt-cells': | |
| 33 | + const: 2 | |
| 34 | + | |
| 35 | + interrupt-controller: | |
| 36 | + description: | |
| 37 | + Identify that the PMIC is capable of behaving as an interrupt controller. | |
| 38 | + | |
| 39 | + gpios: | |
| 40 | + maxItems: 1 | |
| 41 | + | |
| 42 | + regulators: | |
| 43 | + type: object | |
| 44 | + | |
| 45 | + properties: | |
| 46 | + '#address-cells': | |
| 47 | + const: 1 | |
| 48 | + | |
| 49 | + '#size-cells': | |
| 50 | + const: 0 | |
| 51 | + | |
| 52 | + patternProperties: | |
| 53 | + '^ldo[0-9]+@[0-9a-f]$': | |
| 54 | + type: object | |
| 55 | + | |
| 56 | + $ref: "/schemas/regulator/regulator.yaml#" | |
| 57 | + | |
| 58 | + properties: | |
| 59 | + reg: | |
| 60 | + description: Enable register. | |
| 61 | + | |
| 62 | + '#address-cells': | |
| 63 | + const: 1 | |
| 64 | + | |
| 65 | + '#size-cells': | |
| 66 | + const: 0 | |
| 67 | + | |
| 68 | + vsel-reg: | |
| 69 | + description: Voltage selector register. | |
| 70 | + | |
| 71 | + enable-mask: | |
| 72 | + description: Bitmask used to enable the regulator. | |
| 73 | + | |
| 74 | + voltage-table: | |
| 75 | + description: Table with the selector items for the voltage regulator. | |
| 76 | + minItems: 2 | |
| 77 | + maxItems: 16 | |
| 78 | + | |
| 79 | + off-on-delay-us: | |
| 80 | + description: Time required for changing state to enabled in microseconds. | |
| 81 | + | |
| 82 | + startup-delay-us: | |
| 83 | + description: Startup time in microseconds. | |
| 84 | + | |
| 85 | + idle-mode-mask: | |
| 86 | + description: Bitmask used to put the regulator on idle mode. | |
| 87 | + | |
| 88 | + eco-microamp: | |
| 89 | + description: Maximum current while on idle mode. | |
| 90 | + | |
| 91 | + required: | |
| 92 | + - reg | |
| 93 | + - vsel-reg | |
| 94 | + - enable-mask | |
| 95 | + - voltage-table | |
| 96 | + - off-on-delay-us | |
| 97 | + - startup-delay-us | |
| 98 | + | |
| 99 | +required: | |
| 100 | + - compatible | |
| 101 | + - reg | |
| 102 | + - regulators | |
| 103 | + | |
| 104 | +examples: | |
| 105 | + - | | |
| 106 | + /* pmic properties */ | |
| 107 | + | |
| 108 | + pmic: pmic@0 { | |
| 109 | + compatible = "hisilicon,hi6421-spmi"; | |
| 110 | + reg = <0 0>; | |
| 111 | + | |
| 112 | + #interrupt-cells = <2>; | |
| 113 | + interrupt-controller; | |
| 114 | + gpios = <&gpio28 0 0>; | |
| 115 | + | |
| 116 | + regulators { | |
| 117 | + #address-cells = <1>; | |
| 118 | + #size-cells = <0>; | |
| 119 | + | |
| 120 | + ldo3: ldo3@16 { | |
| 121 | + reg = <0x16>; | |
| 122 | + vsel-reg = <0x51>; | |
| 123 | + | |
| 124 | + regulator-name = "ldo3"; | |
| 125 | + regulator-min-microvolt = <1500000>; | |
| 126 | + regulator-max-microvolt = <2000000>; | |
| 127 | + regulator-boot-on; | |
| 128 | + | |
| 129 | + enable-mask = <0x01>; | |
| 130 | + | |
| 131 | + voltage-table = <1500000>, <1550000>, <1600000>, <1650000>, | |
| 132 | + <1700000>, <1725000>, <1750000>, <1775000>, | |
| 133 | + <1800000>, <1825000>, <1850000>, <1875000>, | |
| 134 | + <1900000>, <1925000>, <1950000>, <2000000>; | |
| 135 | + off-on-delay-us = <20000>; | |
| 136 | + startup-delay-us = <120>; | |
| 137 | + }; | |
| 138 | + | |
| 139 | + ldo4: ldo4@17 { /* 40 PIN */ | |
| 140 | + reg = <0x17>; | |
| 141 | + vsel-reg = <0x52>; | |
| 142 | + | |
| 143 | + regulator-name = "ldo4"; | |
| 144 | + regulator-min-microvolt = <1725000>; | |
| 145 | + regulator-max-microvolt = <1900000>; | |
| 146 | + regulator-boot-on; | |
| 147 | + | |
| 148 | + enable-mask = <0x01>; | |
| 149 | + idle-mode-mask = <0x10>; | |
| 150 | + eco-microamp = <10000>; | |
| 151 | + | |
| 152 | + hi6421-vsel = <0x52 0x07>; | |
| 153 | + voltage-table = <1725000>, <1750000>, <1775000>, <1800000>, | |
| 154 | + <1825000>, <1850000>, <1875000>, <1900000>; | |
| 155 | + off-on-delay-us = <20000>; | |
| 156 | + startup-delay-us = <120>; | |
| 157 | + }; | |
| 158 | + }; | |
| 159 | + }; | |
| @@ -0,0 +1,62 @@ | ||
| 1 | +# SPDX-License-Identifier: GPL-2.0 | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/spmi/hisilicon,hisi-spmi-controller.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: HiSilicon SPMI controller | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Mauro Carvalho Chehab <mchehab+huawei@kernel.org> | |
| 11 | + | |
| 12 | +description: | | |
| 13 | + The HiSilicon SPMI BUS controller is found on some Kirin-based designs. | |
| 14 | + It is a MIPI System Power Management (SPMI) controller. | |
| 15 | + | |
| 16 | + The PMIC part is provided by | |
| 17 | + drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml. | |
| 18 | + | |
| 19 | +properties: | |
| 20 | + $nodename: | |
| 21 | + pattern: "spmi@[0-9a-f]" | |
| 22 | + | |
| 23 | + compatible: | |
| 24 | + const: hisilicon,kirin970-spmi-controller | |
| 25 | + | |
| 26 | + reg: | |
| 27 | + maxItems: 1 | |
| 28 | + | |
| 29 | + spmi-channel: | |
| 30 | + description: | | |
| 31 | + number of the Kirin 970 SPMI channel where the SPMI devices are connected. | |
| 32 | + | |
| 33 | +required: | |
| 34 | + - compatible | |
| 35 | + - reg | |
| 36 | + - spmi-channel | |
| 37 | + | |
| 38 | +patternProperties: | |
| 39 | + "^pmic@[0-9a-f]$": | |
| 40 | + description: | | |
| 41 | + PMIC properties, which are specific to the used SPMI PMIC device(s). | |
| 42 | + When used in combination with HiSilicon 6421v600, the properties | |
| 43 | + are documented at | |
| 44 | + drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml. | |
| 45 | + | |
| 46 | +examples: | |
| 47 | + - | | |
| 48 | + bus { | |
| 49 | + #address-cells = <2>; | |
| 50 | + #size-cells = <2>; | |
| 51 | + | |
| 52 | + spmi: spmi@fff24000 { | |
| 53 | + compatible = "hisilicon,kirin970-spmi-controller"; | |
| 54 | + status = "ok"; | |
| 55 | + reg = <0x0 0xfff24000 0x0 0x1000>; | |
| 56 | + spmi-channel = <2>; | |
| 57 | + | |
| 58 | + pmic@0 { | |
| 59 | + /* pmic properties */ | |
| 60 | + }; | |
| 61 | + }; | |
| 62 | + }; | |
| @@ -0,0 +1,671 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0-only | |
| 2 | +/* | |
| 3 | + * Phy provider for USB 3.1 controller on HiSilicon Kirin970 platform | |
| 4 | + * | |
| 5 | + * Copyright (C) 2017-2020 Hilisicon Electronics Co., Ltd. | |
| 6 | + * http://www.huawei.com | |
| 7 | + * | |
| 8 | + * Authors: Yu Chen <chenyu56@huawei.com> | |
| 9 | + */ | |
| 10 | + | |
| 11 | +#include <linux/clk.h> | |
| 12 | +#include <linux/kernel.h> | |
| 13 | +#include <linux/mfd/syscon.h> | |
| 14 | +#include <linux/module.h> | |
| 15 | +#include <linux/phy/phy.h> | |
| 16 | +#include <linux/platform_device.h> | |
| 17 | +#include <linux/regmap.h> | |
| 18 | + | |
| 19 | +#define SCTRL_SCDEEPSLEEPED (0x0) | |
| 20 | +#define USB_CLK_SELECTED BIT(20) | |
| 21 | + | |
| 22 | +#define PERI_CRG_PEREN0 (0x00) | |
| 23 | +#define PERI_CRG_PERDIS0 (0x04) | |
| 24 | +#define PERI_CRG_PEREN4 (0x40) | |
| 25 | +#define PERI_CRG_PERDIS4 (0x44) | |
| 26 | +#define PERI_CRG_PERRSTEN4 (0x90) | |
| 27 | +#define PERI_CRG_PERRSTDIS4 (0x94) | |
| 28 | +#define PERI_CRG_ISODIS (0x148) | |
| 29 | +#define PERI_CRG_PEREN6 (0x410) | |
| 30 | +#define PERI_CRG_PERDIS6 (0x414) | |
| 31 | + | |
| 32 | +#define USB_REFCLK_ISO_EN BIT(25) | |
| 33 | + | |
| 34 | +#define GT_CLK_USB2PHY_REF BIT(19) | |
| 35 | + | |
| 36 | +#define PCTRL_PERI_CTRL3 (0x10) | |
| 37 | +#define PCTRL_PERI_CTRL3_MSK_START (16) | |
| 38 | +#define USB_TCXO_EN BIT(1) | |
| 39 | + | |
| 40 | +#define PCTRL_PERI_CTRL24 (0x64) | |
| 41 | +#define SC_CLK_USB3PHY_3MUX1_SEL BIT(25) | |
| 42 | + | |
| 43 | +#define USB3OTG_CTRL0 (0x00) | |
| 44 | +#define USB3OTG_CTRL3 (0x0C) | |
| 45 | +#define USB3OTG_CTRL4 (0x10) | |
| 46 | +#define USB3OTG_CTRL5 (0x14) | |
| 47 | +#define USB3OTG_CTRL7 (0x1C) | |
| 48 | +#define USB_MISC_CFG50 (0x50) | |
| 49 | +#define USB_MISC_CFG54 (0x54) | |
| 50 | +#define USB_MISC_CFG58 (0x58) | |
| 51 | +#define USB_MISC_CFG5C (0x5C) | |
| 52 | +#define USB_MISC_CFGA0 (0xA0) | |
| 53 | +#define TCA_CLK_RST (0x200) | |
| 54 | +#define TCA_INTR_EN (0x204) | |
| 55 | +#define TCA_INTR_STS (0x208) | |
| 56 | +#define TCA_GCFG (0x210) | |
| 57 | +#define TCA_TCPC (0x214) | |
| 58 | +#define TCA_SYSMODE_CFG (0x218) | |
| 59 | +#define TCA_VBUS_CTRL (0x240) | |
| 60 | + | |
| 61 | +#define CTRL0_USB3_VBUSVLD BIT(7) | |
| 62 | +#define CTRL0_USB3_VBUSVLD_SEL BIT(6) | |
| 63 | + | |
| 64 | +#define CTRL3_USB2_VBUSVLDEXT0 BIT(6) | |
| 65 | +#define CTRL3_USB2_VBUSVLDEXTSEL0 BIT(5) | |
| 66 | + | |
| 67 | +#define CTRL5_USB2_SIDDQ BIT(0) | |
| 68 | + | |
| 69 | +#define CTRL7_USB2_REFCLKSEL_MASK (3 << 3) | |
| 70 | +#define CTRL7_USB2_REFCLKSEL_ABB (3 << 3) | |
| 71 | +#define CTRL7_USB2_REFCLKSEL_PAD (2 << 3) | |
| 72 | + | |
| 73 | +#define CFG50_USB3_PHY_TEST_POWERDOWN BIT(23) | |
| 74 | + | |
| 75 | +#define CFG54_USB31PHY_CR_ADDR_MASK (0xFFFF) | |
| 76 | +#define CFG54_USB31PHY_CR_ADDR_SHIFT (16) | |
| 77 | +#define CFG54_USB3PHY_REF_USE_PAD BIT(12) | |
| 78 | +#define CFG54_PHY0_PMA_PWR_STABLE BIT(11) | |
| 79 | +#define CFG54_PHY0_PCS_PWR_STABLE BIT(9) | |
| 80 | +#define CFG54_USB31PHY_CR_ACK BIT(7) | |
| 81 | +#define CFG54_USB31PHY_CR_WR_EN BIT(5) | |
| 82 | +#define CFG54_USB31PHY_CR_SEL BIT(4) | |
| 83 | +#define CFG54_USB31PHY_CR_RD_EN BIT(3) | |
| 84 | +#define CFG54_USB31PHY_CR_CLK BIT(2) | |
| 85 | +#define CFG54_USB3_PHY0_ANA_PWR_EN BIT(1) | |
| 86 | + | |
| 87 | +#define CFG58_USB31PHY_CR_DATA_MASK (0xFFFF) | |
| 88 | +#define CFG58_USB31PHY_CR_DATA_RD_START (16) | |
| 89 | + | |
| 90 | +#define CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN BIT(1) | |
| 91 | + | |
| 92 | +#define CFGA0_VAUX_RESET BIT(9) | |
| 93 | +#define CFGA0_USB31C_RESET BIT(8) | |
| 94 | +#define CFGA0_USB2PHY_REFCLK_SELECT BIT(4) | |
| 95 | +#define CFGA0_USB3PHY_RESET BIT(1) | |
| 96 | +#define CFGA0_USB2PHY_POR BIT(0) | |
| 97 | + | |
| 98 | +#define INTR_EN_XA_TIMEOUT_EVT_EN BIT(1) | |
| 99 | +#define INTR_EN_XA_ACK_EVT_EN BIT(0) | |
| 100 | + | |
| 101 | +#define CLK_RST_TCA_REF_CLK_EN BIT(1) | |
| 102 | +#define CLK_RST_SUSPEND_CLK_EN BIT(0) | |
| 103 | + | |
| 104 | +#define GCFG_ROLE_HSTDEV BIT(4) | |
| 105 | +#define GCFG_OP_MODE (3 << 0) | |
| 106 | +#define GCFG_OP_MODE_CTRL_SYNC_MODE BIT(0) | |
| 107 | + | |
| 108 | +#define TCPC_VALID BIT(4) | |
| 109 | +#define TCPC_LOW_POWER_EN BIT(3) | |
| 110 | +#define TCPC_MUX_CONTROL_MASK (3 << 0) | |
| 111 | +#define TCPC_MUX_CONTROL_USB31 BIT(0) | |
| 112 | + | |
| 113 | +#define SYSMODE_CFG_TYPEC_DISABLE BIT(3) | |
| 114 | + | |
| 115 | +#define VBUS_CTRL_POWERPRESENT_OVERRD (3 << 2) | |
| 116 | +#define VBUS_CTRL_VBUSVALID_OVERRD (3 << 0) | |
| 117 | + | |
| 118 | +#define KIRIN970_USB_DEFAULT_PHY_PARAM (0xFDFEE4) | |
| 119 | +#define KIRIN970_USB_DEFAULT_PHY_VBOOST (0x5) | |
| 120 | + | |
| 121 | +#define TX_VBOOST_LVL_REG (0xf) | |
| 122 | +#define TX_VBOOST_LVL_START (6) | |
| 123 | +#define TX_VBOOST_LVL_ENABLE BIT(9) | |
| 124 | + | |
| 125 | +struct hi3670_priv { | |
| 126 | + struct device *dev; | |
| 127 | + struct regmap *peri_crg; | |
| 128 | + struct regmap *pctrl; | |
| 129 | + struct regmap *sctrl; | |
| 130 | + struct regmap *usb31misc; | |
| 131 | + | |
| 132 | + u32 eye_diagram_param; | |
| 133 | + u32 tx_vboost_lvl; | |
| 134 | + | |
| 135 | + u32 peri_crg_offset; | |
| 136 | + u32 pctrl_offset; | |
| 137 | + u32 usb31misc_offset; | |
| 138 | +}; | |
| 139 | + | |
| 140 | +static int hi3670_phy_cr_clk(struct regmap *usb31misc) | |
| 141 | +{ | |
| 142 | + int ret; | |
| 143 | + | |
| 144 | + /* Clock up */ | |
| 145 | + ret = regmap_update_bits(usb31misc, USB_MISC_CFG54, | |
| 146 | + CFG54_USB31PHY_CR_CLK, CFG54_USB31PHY_CR_CLK); | |
| 147 | + if (ret) | |
| 148 | + return ret; | |
| 149 | + | |
| 150 | + /* Clock down */ | |
| 151 | + ret = regmap_update_bits(usb31misc, USB_MISC_CFG54, | |
| 152 | + CFG54_USB31PHY_CR_CLK, 0); | |
| 153 | + | |
| 154 | + return ret; | |
| 155 | +} | |
| 156 | + | |
| 157 | +static int hi3670_phy_cr_set_sel(struct regmap *usb31misc) | |
| 158 | +{ | |
| 159 | + return regmap_update_bits(usb31misc, USB_MISC_CFG54, | |
| 160 | + CFG54_USB31PHY_CR_SEL, CFG54_USB31PHY_CR_SEL); | |
| 161 | +} | |
| 162 | + | |
| 163 | +static int hi3670_phy_cr_start(struct regmap *usb31misc, int direction) | |
| 164 | +{ | |
| 165 | + int ret; | |
| 166 | + | |
| 167 | + if (direction) | |
| 168 | + ret = regmap_update_bits(usb31misc, USB_MISC_CFG54, | |
| 169 | + CFG54_USB31PHY_CR_WR_EN, | |
| 170 | + CFG54_USB31PHY_CR_WR_EN); | |
| 171 | + else | |
| 172 | + ret = regmap_update_bits(usb31misc, USB_MISC_CFG54, | |
| 173 | + CFG54_USB31PHY_CR_RD_EN, | |
| 174 | + CFG54_USB31PHY_CR_RD_EN); | |
| 175 | + | |
| 176 | + if (ret) | |
| 177 | + return ret; | |
| 178 | + | |
| 179 | + ret = hi3670_phy_cr_clk(usb31misc); | |
| 180 | + if (ret) | |
| 181 | + return ret; | |
| 182 | + | |
| 183 | + ret = regmap_update_bits(usb31misc, USB_MISC_CFG54, | |
| 184 | + CFG54_USB31PHY_CR_RD_EN | CFG54_USB31PHY_CR_WR_EN, 0); | |
| 185 | + | |
| 186 | + return ret; | |
| 187 | +} | |
| 188 | + | |
| 189 | +static int hi3670_phy_cr_wait_ack(struct regmap *usb31misc) | |
| 190 | +{ | |
| 191 | + u32 reg; | |
| 192 | + int retry = 100000; | |
| 193 | + int ret; | |
| 194 | + | |
| 195 | + while (retry-- > 0) { | |
| 196 | + ret = regmap_read(usb31misc, USB_MISC_CFG54, ®); | |
| 197 | + if (ret) | |
| 198 | + return ret; | |
| 199 | + if ((reg & CFG54_USB31PHY_CR_ACK) == CFG54_USB31PHY_CR_ACK) | |
| 200 | + return 0; | |
| 201 | + | |
| 202 | + ret = hi3670_phy_cr_clk(usb31misc); | |
| 203 | + if (ret) | |
| 204 | + return ret; | |
| 205 | + } | |
| 206 | + | |
| 207 | + return -ETIMEDOUT; | |
| 208 | +} | |
| 209 | + | |
| 210 | +static int hi3670_phy_cr_set_addr(struct regmap *usb31misc, u32 addr) | |
| 211 | +{ | |
| 212 | + u32 reg; | |
| 213 | + int ret; | |
| 214 | + | |
| 215 | + ret = regmap_read(usb31misc, USB_MISC_CFG54, ®); | |
| 216 | + if (ret) | |
| 217 | + return ret; | |
| 218 | + | |
| 219 | + reg &= ~(CFG54_USB31PHY_CR_ADDR_MASK << CFG54_USB31PHY_CR_ADDR_SHIFT); | |
| 220 | + reg |= ((addr & CFG54_USB31PHY_CR_ADDR_MASK) << CFG54_USB31PHY_CR_ADDR_SHIFT); | |
| 221 | + ret = regmap_write(usb31misc, USB_MISC_CFG54, reg); | |
| 222 | + | |
| 223 | + return ret; | |
| 224 | +} | |
| 225 | + | |
| 226 | +static int hi3670_phy_cr_read(struct regmap *usb31misc, u32 addr, u32 *val) | |
| 227 | +{ | |
| 228 | + int reg; | |
| 229 | + int i; | |
| 230 | + int ret; | |
| 231 | + | |
| 232 | + for (i = 0; i < 100; i++) { | |
| 233 | + ret = hi3670_phy_cr_clk(usb31misc); | |
| 234 | + if (ret) | |
| 235 | + return ret; | |
| 236 | + } | |
| 237 | + | |
| 238 | + ret = hi3670_phy_cr_set_sel(usb31misc); | |
| 239 | + if (ret) | |
| 240 | + return ret; | |
| 241 | + | |
| 242 | + ret = hi3670_phy_cr_set_addr(usb31misc, addr); | |
| 243 | + if (ret) | |
| 244 | + return ret; | |
| 245 | + | |
| 246 | + ret = hi3670_phy_cr_start(usb31misc, 0); | |
| 247 | + if (ret) | |
| 248 | + return ret; | |
| 249 | + | |
| 250 | + ret = hi3670_phy_cr_wait_ack(usb31misc); | |
| 251 | + if (ret) | |
| 252 | + return ret; | |
| 253 | + | |
| 254 | + ret = regmap_read(usb31misc, USB_MISC_CFG58, ®); | |
| 255 | + if (ret) | |
| 256 | + return ret; | |
| 257 | + | |
| 258 | + *val = (reg >> CFG58_USB31PHY_CR_DATA_RD_START) & | |
| 259 | + CFG58_USB31PHY_CR_DATA_MASK; | |
| 260 | + | |
| 261 | + return 0; | |
| 262 | +} | |
| 263 | + | |
| 264 | +static int hi3670_phy_cr_write(struct regmap *usb31misc, u32 addr, u32 val) | |
| 265 | +{ | |
| 266 | + int i; | |
| 267 | + int ret; | |
| 268 | + | |
| 269 | + for (i = 0; i < 100; i++) { | |
| 270 | + ret = hi3670_phy_cr_clk(usb31misc); | |
| 271 | + if (ret) | |
| 272 | + return ret; | |
| 273 | + } | |
| 274 | + | |
| 275 | + ret = hi3670_phy_cr_set_sel(usb31misc); | |
| 276 | + if (ret) | |
| 277 | + return ret; | |
| 278 | + | |
| 279 | + ret = hi3670_phy_cr_set_addr(usb31misc, addr); | |
| 280 | + if (ret) | |
| 281 | + return ret; | |
| 282 | + | |
| 283 | + ret = regmap_write(usb31misc, USB_MISC_CFG58, | |
| 284 | + val & CFG58_USB31PHY_CR_DATA_MASK); | |
| 285 | + if (ret) | |
| 286 | + return ret; | |
| 287 | + | |
| 288 | + ret = hi3670_phy_cr_start(usb31misc, 1); | |
| 289 | + if (ret) | |
| 290 | + return ret; | |
| 291 | + | |
| 292 | + ret = hi3670_phy_cr_wait_ack(usb31misc); | |
| 293 | + | |
| 294 | + return ret; | |
| 295 | +} | |
| 296 | + | |
| 297 | +static int hi3670_phy_set_params(struct hi3670_priv *priv) | |
| 298 | +{ | |
| 299 | + u32 reg; | |
| 300 | + int ret; | |
| 301 | + int retry = 3; | |
| 302 | + | |
| 303 | + ret = regmap_write(priv->usb31misc, USB3OTG_CTRL4, | |
| 304 | + priv->eye_diagram_param); | |
| 305 | + if (ret) { | |
| 306 | + dev_err(priv->dev, "set USB3OTG_CTRL4 failed\n"); | |
| 307 | + return ret; | |
| 308 | + } | |
| 309 | + | |
| 310 | + while (retry-- > 0) { | |
| 311 | + ret = hi3670_phy_cr_read(priv->usb31misc, | |
| 312 | + TX_VBOOST_LVL_REG, ®); | |
| 313 | + if (!ret) | |
| 314 | + break; | |
| 315 | + | |
| 316 | + if (ret != -ETIMEDOUT) { | |
| 317 | + dev_err(priv->dev, "read TX_VBOOST_LVL_REG failed\n"); | |
| 318 | + return ret; | |
| 319 | + } | |
| 320 | + } | |
| 321 | + if (ret) | |
| 322 | + return ret; | |
| 323 | + | |
| 324 | + reg |= (TX_VBOOST_LVL_ENABLE | (priv->tx_vboost_lvl << TX_VBOOST_LVL_START)); | |
| 325 | + ret = hi3670_phy_cr_write(priv->usb31misc, TX_VBOOST_LVL_REG, reg); | |
| 326 | + if (ret) | |
| 327 | + dev_err(priv->dev, "write TX_VBOOST_LVL_REG failed\n"); | |
| 328 | + | |
| 329 | + return ret; | |
| 330 | +} | |
| 331 | + | |
| 332 | +static int hi3670_is_abbclk_seleted(struct hi3670_priv *priv) | |
| 333 | +{ | |
| 334 | + u32 reg; | |
| 335 | + | |
| 336 | + if (!priv->sctrl) { | |
| 337 | + dev_err(priv->dev, "priv->sctrl is null!\n"); | |
| 338 | + return 1; | |
| 339 | + } | |
| 340 | + | |
| 341 | + if (regmap_read(priv->sctrl, SCTRL_SCDEEPSLEEPED, ®)) { | |
| 342 | + dev_err(priv->dev, "SCTRL_SCDEEPSLEEPED read failed!\n"); | |
| 343 | + return 1; | |
| 344 | + } | |
| 345 | + | |
| 346 | + if ((reg & USB_CLK_SELECTED) == 0) | |
| 347 | + return 1; | |
| 348 | + | |
| 349 | + return 0; | |
| 350 | +} | |
| 351 | + | |
| 352 | +static int hi3670_config_phy_clock(struct hi3670_priv *priv) | |
| 353 | +{ | |
| 354 | + u32 val, mask; | |
| 355 | + int ret; | |
| 356 | + | |
| 357 | + if (hi3670_is_abbclk_seleted(priv)) { | |
| 358 | + /* usb refclk iso disable */ | |
| 359 | + ret = regmap_write(priv->peri_crg, PERI_CRG_ISODIS, | |
| 360 | + USB_REFCLK_ISO_EN); | |
| 361 | + if (ret) | |
| 362 | + goto out; | |
| 363 | + | |
| 364 | + /* enable usb_tcxo_en */ | |
| 365 | + ret = regmap_write(priv->pctrl, PCTRL_PERI_CTRL3, | |
| 366 | + USB_TCXO_EN | | |
| 367 | + (USB_TCXO_EN << PCTRL_PERI_CTRL3_MSK_START)); | |
| 368 | + | |
| 369 | + /* select usbphy clk from abb */ | |
| 370 | + mask = SC_CLK_USB3PHY_3MUX1_SEL; | |
| 371 | + ret = regmap_update_bits(priv->pctrl, | |
| 372 | + PCTRL_PERI_CTRL24, mask, 0); | |
| 373 | + if (ret) | |
| 374 | + goto out; | |
| 375 | + | |
| 376 | + ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, | |
| 377 | + CFGA0_USB2PHY_REFCLK_SELECT, 0); | |
| 378 | + if (ret) | |
| 379 | + goto out; | |
| 380 | + | |
| 381 | + ret = regmap_read(priv->usb31misc, USB3OTG_CTRL7, &val); | |
| 382 | + if (ret) | |
| 383 | + goto out; | |
| 384 | + val &= ~CTRL7_USB2_REFCLKSEL_MASK; | |
| 385 | + val |= CTRL7_USB2_REFCLKSEL_ABB; | |
| 386 | + ret = regmap_write(priv->usb31misc, USB3OTG_CTRL7, val); | |
| 387 | + if (ret) | |
| 388 | + goto out; | |
| 389 | + | |
| 390 | + return 0; | |
| 391 | + } | |
| 392 | + | |
| 393 | + ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG54, | |
| 394 | + CFG54_USB3PHY_REF_USE_PAD, | |
| 395 | + CFG54_USB3PHY_REF_USE_PAD); | |
| 396 | + if (ret) | |
| 397 | + goto out; | |
| 398 | + | |
| 399 | + ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, | |
| 400 | + CFGA0_USB2PHY_REFCLK_SELECT, | |
| 401 | + CFGA0_USB2PHY_REFCLK_SELECT); | |
| 402 | + if (ret) | |
| 403 | + goto out; | |
| 404 | + | |
| 405 | + ret = regmap_read(priv->usb31misc, USB3OTG_CTRL7, &val); | |
| 406 | + if (ret) | |
| 407 | + goto out; | |
| 408 | + val &= ~CTRL7_USB2_REFCLKSEL_MASK; | |
| 409 | + val |= CTRL7_USB2_REFCLKSEL_PAD; | |
| 410 | + ret = regmap_write(priv->usb31misc, USB3OTG_CTRL7, val); | |
| 411 | + if (ret) | |
| 412 | + goto out; | |
| 413 | + | |
| 414 | + ret = regmap_write(priv->peri_crg, | |
| 415 | + PERI_CRG_PEREN6, GT_CLK_USB2PHY_REF); | |
| 416 | + if (ret) | |
| 417 | + goto out; | |
| 418 | + | |
| 419 | + return 0; | |
| 420 | +out: | |
| 421 | + dev_err(priv->dev, "failed to config phy clock ret: %d\n", ret); | |
| 422 | + return ret; | |
| 423 | +} | |
| 424 | + | |
| 425 | +static int hi3670_config_tca(struct hi3670_priv *priv) | |
| 426 | +{ | |
| 427 | + u32 val, mask; | |
| 428 | + int ret; | |
| 429 | + | |
| 430 | + ret = regmap_write(priv->usb31misc, TCA_INTR_STS, 0xffff); | |
| 431 | + if (ret) | |
| 432 | + goto out; | |
| 433 | + | |
| 434 | + ret = regmap_write(priv->usb31misc, TCA_INTR_EN, | |
| 435 | + INTR_EN_XA_TIMEOUT_EVT_EN | INTR_EN_XA_ACK_EVT_EN); | |
| 436 | + if (ret) | |
| 437 | + goto out; | |
| 438 | + | |
| 439 | + mask = CLK_RST_TCA_REF_CLK_EN | CLK_RST_SUSPEND_CLK_EN; | |
| 440 | + ret = regmap_update_bits(priv->usb31misc, TCA_CLK_RST, mask, 0); | |
| 441 | + if (ret) | |
| 442 | + goto out; | |
| 443 | + | |
| 444 | + ret = regmap_update_bits(priv->usb31misc, TCA_GCFG, | |
| 445 | + GCFG_ROLE_HSTDEV | GCFG_OP_MODE, | |
| 446 | + GCFG_ROLE_HSTDEV | GCFG_OP_MODE_CTRL_SYNC_MODE); | |
| 447 | + if (ret) | |
| 448 | + goto out; | |
| 449 | + | |
| 450 | + ret = regmap_update_bits(priv->usb31misc, TCA_SYSMODE_CFG, | |
| 451 | + SYSMODE_CFG_TYPEC_DISABLE, 0); | |
| 452 | + if (ret) | |
| 453 | + goto out; | |
| 454 | + | |
| 455 | + ret = regmap_read(priv->usb31misc, TCA_TCPC, &val); | |
| 456 | + if (ret) | |
| 457 | + goto out; | |
| 458 | + val &= ~(TCPC_VALID | TCPC_LOW_POWER_EN | TCPC_MUX_CONTROL_MASK); | |
| 459 | + val |= (TCPC_VALID | TCPC_MUX_CONTROL_USB31); | |
| 460 | + ret = regmap_write(priv->usb31misc, TCA_TCPC, val); | |
| 461 | + if (ret) | |
| 462 | + goto out; | |
| 463 | + | |
| 464 | + ret = regmap_write(priv->usb31misc, TCA_VBUS_CTRL, | |
| 465 | + VBUS_CTRL_POWERPRESENT_OVERRD | VBUS_CTRL_VBUSVALID_OVERRD); | |
| 466 | + if (ret) | |
| 467 | + goto out; | |
| 468 | + | |
| 469 | + return 0; | |
| 470 | +out: | |
| 471 | + dev_err(priv->dev, "failed to config phy clock ret: %d\n", ret); | |
| 472 | + return ret; | |
| 473 | +} | |
| 474 | + | |
| 475 | +static int hi3670_phy_init(struct phy *phy) | |
| 476 | +{ | |
| 477 | + struct hi3670_priv *priv = phy_get_drvdata(phy); | |
| 478 | + u32 val; | |
| 479 | + int ret; | |
| 480 | + | |
| 481 | + /* assert controller */ | |
| 482 | + val = CFGA0_VAUX_RESET | CFGA0_USB31C_RESET | | |
| 483 | + CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR; | |
| 484 | + ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, 0); | |
| 485 | + if (ret) | |
| 486 | + goto out; | |
| 487 | + | |
| 488 | + ret = hi3670_config_phy_clock(priv); | |
| 489 | + if (ret) | |
| 490 | + goto out; | |
| 491 | + | |
| 492 | + /* Exit from IDDQ mode */ | |
| 493 | + ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL5, | |
| 494 | + CTRL5_USB2_SIDDQ, 0); | |
| 495 | + if (ret) | |
| 496 | + goto out; | |
| 497 | + | |
| 498 | + /* Release USB31 PHY out of TestPowerDown mode */ | |
| 499 | + ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG50, | |
| 500 | + CFG50_USB3_PHY_TEST_POWERDOWN, 0); | |
| 501 | + if (ret) | |
| 502 | + goto out; | |
| 503 | + | |
| 504 | + /* Deassert phy */ | |
| 505 | + val = CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR; | |
| 506 | + ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, val); | |
| 507 | + if (ret) | |
| 508 | + goto out; | |
| 509 | + | |
| 510 | + usleep_range(100, 120); | |
| 511 | + | |
| 512 | + /* Tell the PHY power is stable */ | |
| 513 | + val = CFG54_USB3_PHY0_ANA_PWR_EN | CFG54_PHY0_PCS_PWR_STABLE | | |
| 514 | + CFG54_PHY0_PMA_PWR_STABLE; | |
| 515 | + ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG54, | |
| 516 | + val, val); | |
| 517 | + if (ret) | |
| 518 | + goto out; | |
| 519 | + | |
| 520 | + ret = hi3670_config_tca(priv); | |
| 521 | + if (ret) | |
| 522 | + goto out; | |
| 523 | + | |
| 524 | + /* Enable SSC */ | |
| 525 | + ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG5C, | |
| 526 | + CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN, | |
| 527 | + CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN); | |
| 528 | + if (ret) | |
| 529 | + goto out; | |
| 530 | + | |
| 531 | + /* Deassert controller */ | |
| 532 | + val = CFGA0_VAUX_RESET | CFGA0_USB31C_RESET; | |
| 533 | + ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, val); | |
| 534 | + if (ret) | |
| 535 | + goto out; | |
| 536 | + | |
| 537 | + usleep_range(100, 120); | |
| 538 | + | |
| 539 | + /* Set fake vbus valid signal */ | |
| 540 | + val = CTRL0_USB3_VBUSVLD | CTRL0_USB3_VBUSVLD_SEL; | |
| 541 | + ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL0, val, val); | |
| 542 | + if (ret) | |
| 543 | + goto out; | |
| 544 | + | |
| 545 | + val = CTRL3_USB2_VBUSVLDEXT0 | CTRL3_USB2_VBUSVLDEXTSEL0; | |
| 546 | + ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL3, val, val); | |
| 547 | + if (ret) | |
| 548 | + goto out; | |
| 549 | + | |
| 550 | + usleep_range(100, 120); | |
| 551 | + | |
| 552 | + ret = hi3670_phy_set_params(priv); | |
| 553 | + if (ret) | |
| 554 | + goto out; | |
| 555 | + | |
| 556 | + return 0; | |
| 557 | +out: | |
| 558 | + dev_err(priv->dev, "failed to init phy ret: %d\n", ret); | |
| 559 | + return ret; | |
| 560 | +} | |
| 561 | + | |
| 562 | +static int hi3670_phy_exit(struct phy *phy) | |
| 563 | +{ | |
| 564 | + struct hi3670_priv *priv = phy_get_drvdata(phy); | |
| 565 | + u32 mask; | |
| 566 | + int ret; | |
| 567 | + | |
| 568 | + /* Assert phy */ | |
| 569 | + mask = CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR; | |
| 570 | + ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, mask, 0); | |
| 571 | + if (ret) | |
| 572 | + goto out; | |
| 573 | + | |
| 574 | + if (hi3670_is_abbclk_seleted(priv)) { | |
| 575 | + /* disable usb_tcxo_en */ | |
| 576 | + ret = regmap_write(priv->pctrl, PCTRL_PERI_CTRL3, | |
| 577 | + USB_TCXO_EN << PCTRL_PERI_CTRL3_MSK_START); | |
| 578 | + } else { | |
| 579 | + ret = regmap_write(priv->peri_crg, PERI_CRG_PERDIS6, | |
| 580 | + GT_CLK_USB2PHY_REF); | |
| 581 | + if (ret) | |
| 582 | + goto out; | |
| 583 | + } | |
| 584 | + | |
| 585 | + return 0; | |
| 586 | +out: | |
| 587 | + dev_err(priv->dev, "failed to exit phy ret: %d\n", ret); | |
| 588 | + return ret; | |
| 589 | +} | |
| 590 | + | |
| 591 | +static struct phy_ops hi3670_phy_ops = { | |
| 592 | + .init = hi3670_phy_init, | |
| 593 | + .exit = hi3670_phy_exit, | |
| 594 | + .owner = THIS_MODULE, | |
| 595 | +}; | |
| 596 | + | |
| 597 | +static int hi3670_phy_probe(struct platform_device *pdev) | |
| 598 | +{ | |
| 599 | + struct phy_provider *phy_provider; | |
| 600 | + struct device *dev = &pdev->dev; | |
| 601 | + struct phy *phy; | |
| 602 | + struct hi3670_priv *priv; | |
| 603 | + | |
| 604 | + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | |
| 605 | + if (!priv) | |
| 606 | + return -ENOMEM; | |
| 607 | + | |
| 608 | + priv->dev = dev; | |
| 609 | + priv->peri_crg = syscon_regmap_lookup_by_phandle(dev->of_node, | |
| 610 | + "hisilicon,pericrg-syscon"); | |
| 611 | + if (IS_ERR(priv->peri_crg)) { | |
| 612 | + dev_err(dev, "no hisilicon,pericrg-syscon\n"); | |
| 613 | + return PTR_ERR(priv->peri_crg); | |
| 614 | + } | |
| 615 | + | |
| 616 | + priv->pctrl = syscon_regmap_lookup_by_phandle(dev->of_node, | |
| 617 | + "hisilicon,pctrl-syscon"); | |
| 618 | + if (IS_ERR(priv->pctrl)) { | |
| 619 | + dev_err(dev, "no hisilicon,pctrl-syscon\n"); | |
| 620 | + return PTR_ERR(priv->pctrl); | |
| 621 | + } | |
| 622 | + | |
| 623 | + priv->sctrl = syscon_regmap_lookup_by_phandle(dev->of_node, | |
| 624 | + "hisilicon,sctrl-syscon"); | |
| 625 | + if (IS_ERR(priv->sctrl)) { | |
| 626 | + dev_err(dev, "no hisilicon,sctrl-syscon\n"); | |
| 627 | + return PTR_ERR(priv->sctrl); | |
| 628 | + } | |
| 629 | + | |
| 630 | + /* node of hi3670 phy is a sub-node of usb3_otg_bc */ | |
| 631 | + priv->usb31misc = syscon_node_to_regmap(dev->parent->of_node); | |
| 632 | + if (IS_ERR(priv->usb31misc)) { | |
| 633 | + dev_err(dev, "no hisilicon,usb3-otg-bc-syscon\n"); | |
| 634 | + return PTR_ERR(priv->usb31misc); | |
| 635 | + } | |
| 636 | + | |
| 637 | + if (of_property_read_u32(dev->of_node, "hisilicon,eye-diagram-param", | |
| 638 | + &priv->eye_diagram_param)) | |
| 639 | + priv->eye_diagram_param = KIRIN970_USB_DEFAULT_PHY_PARAM; | |
| 640 | + | |
| 641 | + if (of_property_read_u32(dev->of_node, "hisilicon,tx-vboost-lvl", | |
| 642 | + &priv->tx_vboost_lvl)) | |
| 643 | + priv->tx_vboost_lvl = KIRIN970_USB_DEFAULT_PHY_VBOOST; | |
| 644 | + | |
| 645 | + phy = devm_phy_create(dev, NULL, &hi3670_phy_ops); | |
| 646 | + if (IS_ERR(phy)) | |
| 647 | + return PTR_ERR(phy); | |
| 648 | + | |
| 649 | + phy_set_drvdata(phy, priv); | |
| 650 | + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); | |
| 651 | + return PTR_ERR_OR_ZERO(phy_provider); | |
| 652 | +} | |
| 653 | + | |
| 654 | +static const struct of_device_id hi3670_phy_of_match[] = { | |
| 655 | + { .compatible = "hisilicon,hi3670-usb-phy" }, | |
| 656 | + { }, | |
| 657 | +}; | |
| 658 | +MODULE_DEVICE_TABLE(of, hi3670_phy_of_match); | |
| 659 | + | |
| 660 | +static struct platform_driver hi3670_phy_driver = { | |
| 661 | + .probe = hi3670_phy_probe, | |
| 662 | + .driver = { | |
| 663 | + .name = "hi3670-usb-phy", | |
| 664 | + .of_match_table = hi3670_phy_of_match, | |
| 665 | + } | |
| 666 | +}; | |
| 667 | +module_platform_driver(hi3670_phy_driver); | |
| 668 | + | |
| 669 | +MODULE_AUTHOR("Yu Chen <chenyu56@huawei.com>"); | |
| 670 | +MODULE_LICENSE("GPL v2"); | |
| 671 | +MODULE_DESCRIPTION("Hilisicon Kirin970 USB31 PHY Driver"); | |
| @@ -0,0 +1,72 @@ | ||
| 1 | +# SPDX-License-Identifier: GPL-2.0 | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/phy/hisilicon,hi3670-usb3.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Hisilicon Kirin970 USB PHY | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Mauro Carvalho Chehab <mchehab+huawei@kernel.org> | |
| 11 | +description: |+ | |
| 12 | + Bindings for USB3 PHY on HiSilicon Kirin 970. | |
| 13 | + | |
| 14 | +properties: | |
| 15 | + compatible: | |
| 16 | + const: hisilicon,hi3670-usb-phy | |
| 17 | + | |
| 18 | + "#phy-cells": | |
| 19 | + const: 0 | |
| 20 | + | |
| 21 | + hisilicon,pericrg-syscon: | |
| 22 | + $ref: '/schemas/types.yaml#/definitions/phandle' | |
| 23 | + description: phandle of syscon used to control iso refclk. | |
| 24 | + | |
| 25 | + hisilicon,pctrl-syscon: | |
| 26 | + $ref: '/schemas/types.yaml#/definitions/phandle' | |
| 27 | + description: phandle of syscon used to control usb tcxo. | |
| 28 | + | |
| 29 | + hisilicon,sctrl-syscon: | |
| 30 | + $ref: '/schemas/types.yaml#/definitions/phandle' | |
| 31 | + description: phandle of syscon used to control phy deep sleep. | |
| 32 | + | |
| 33 | + hisilicon,eye-diagram-param: | |
| 34 | + $ref: /schemas/types.yaml#/definitions/uint32 | |
| 35 | + description: Eye diagram for phy. | |
| 36 | + | |
| 37 | + hisilicon,tx-vboost-lvl: | |
| 38 | + $ref: /schemas/types.yaml#/definitions/uint32 | |
| 39 | + description: TX level vboost for phy. | |
| 40 | + | |
| 41 | +required: | |
| 42 | + - compatible | |
| 43 | + - hisilicon,pericrg-syscon | |
| 44 | + - hisilicon,pctrl-syscon | |
| 45 | + - hisilicon,sctrl-syscon | |
| 46 | + - hisilicon,eye-diagram-param | |
| 47 | + - hisilicon,tx-vboost-lvl | |
| 48 | + - "#phy-cells" | |
| 49 | + | |
| 50 | +additionalProperties: false | |
| 51 | + | |
| 52 | +examples: | |
| 53 | + - | | |
| 54 | + bus { | |
| 55 | + #address-cells = <2>; | |
| 56 | + #size-cells = <2>; | |
| 57 | + | |
| 58 | + usb3_otg_bc: usb3_otg_bc@ff200000 { | |
| 59 | + compatible = "syscon", "simple-mfd"; | |
| 60 | + reg = <0x0 0xff200000 0x0 0x1000>; | |
| 61 | + | |
| 62 | + usb_phy { | |
| 63 | + compatible = "hisilicon,hi3670-usb-phy"; | |
| 64 | + #phy-cells = <0>; | |
| 65 | + hisilicon,pericrg-syscon = <&crg_ctrl>; | |
| 66 | + hisilicon,pctrl-syscon = <&pctrl>; | |
| 67 | + hisilicon,sctrl-syscon = <&sctrl>; | |
| 68 | + hisilicon,eye-diagram-param = <0xfdfee4>; | |
| 69 | + hisilicon,tx-vboost-lvl = <0x5>; | |
| 70 | + }; | |
| 71 | + }; | |
| 72 | + }; | |
| @@ -1,41 +0,0 @@ | ||
| 1 | −Kernel driver max517 | |
| 2 | −==================== | |
| 3 | − | |
| 4 | −Supported chips: | |
| 5 | − * Maxim MAX517, MAX518, MAX519 | |
| 6 | − Prefix: 'max517' | |
| 7 | − Datasheet: Publicly available at the Maxim website | |
| 8 | − http://www.maxim-ic.com/ | |
| 9 | − | |
| 10 | −Author: | |
| 11 | − Roland Stigge <stigge@antcom.de> | |
| 12 | − | |
| 13 | −Description | |
| 14 | −----------- | |
| 15 | − | |
| 16 | −The Maxim MAX517/518/519 is an 8-bit DAC on the I2C bus. The following table | |
| 17 | −shows the different feature sets of the variants MAX517, MAX518 and MAX519: | |
| 18 | − | |
| 19 | −Feature MAX517 MAX518 MAX519 | |
| 20 | −-------------------------------------------------------------------------- | |
| 21 | −One output channel X | |
| 22 | −Two output channels X X | |
| 23 | −Simultaneous output updates X X | |
| 24 | −Supply voltage as reference X | |
| 25 | −Separate reference input X | |
| 26 | −Reference input for each DAC X | |
| 27 | − | |
| 28 | −Via the iio sysfs interface, there are three attributes available: out1_raw, | |
| 29 | −out2_raw and out12_raw. With out1_raw and out2_raw, the current output values | |
| 30 | −(0..255) of the DACs can be written to the device. out12_raw can be used to set | |
| 31 | −both output channel values simultaneously. | |
| 32 | − | |
| 33 | −With MAX517, only out1_raw is available. | |
| 34 | − | |
| 35 | −Via out1_scale (and where appropriate, out2_scale), the current scaling factor | |
| 36 | −in mV can be read. | |
| 37 | − | |
| 38 | −When the operating system goes to a power down state, the Power Down function | |
| 39 | −of the chip is activated, reducing the supply current to 4uA. | |
| 40 | − | |
| 41 | −On power-up, the device is in 0V-output state. | |
| @@ -1,74 +0,0 @@ | ||
| 1 | −IIO Device drivers | |
| 2 | − | |
| 3 | −This is not intended to provide a comprehensive guide to writing an | |
| 4 | −IIO device driver. For further information see the drivers within the | |
| 5 | −subsystem. | |
| 6 | − | |
| 7 | −The crucial structure for device drivers in iio is iio_dev. | |
| 8 | − | |
| 9 | −First allocate one using: | |
| 10 | − | |
| 11 | −struct iio_dev *indio_dev = iio_device_alloc(parent, sizeof(struct chip_state)); | |
| 12 | −where chip_state is a structure of local state data for this instance of | |
| 13 | −the chip. | |
| 14 | − | |
| 15 | −That data can be accessed using iio_priv(struct iio_dev *). | |
| 16 | − | |
| 17 | −Then fill in the following: | |
| 18 | − | |
| 19 | −- indio_dev->name | |
| 20 | − Name of the device being driven - made available as the name | |
| 21 | − attribute in sysfs. | |
| 22 | − | |
| 23 | −- indio_dev->info | |
| 24 | − pointer to a structure with elements that tend to be fixed for | |
| 25 | − large sets of different parts supported by a given driver. | |
| 26 | − This contains: | |
| 27 | − * info->event_attrs: | |
| 28 | − Attributes used to enable / disable hardware events. | |
| 29 | − * info->attrs: | |
| 30 | − General device attributes. Typically used for the weird | |
| 31 | − and the wonderful bits not covered by the channel specification. | |
| 32 | − * info->read_raw: | |
| 33 | − Raw data reading function. Used for both raw channel access | |
| 34 | − and for associate parameters such as offsets and scales. | |
| 35 | − * info->write_raw: | |
| 36 | − Raw value writing function. Used for writable device values such | |
| 37 | − as DAC values and calibbias. | |
| 38 | − * info->read_event_config: | |
| 39 | − Typically only set if there are some interrupt lines. This | |
| 40 | − is used to read if an on sensor event detector is enabled. | |
| 41 | − * info->write_event_config: | |
| 42 | − Enable / disable an on sensor event detector. | |
| 43 | − * info->read_event_value: | |
| 44 | − Read value associated with on sensor event detectors. Note that | |
| 45 | − the meaning of the returned value is dependent on the event | |
| 46 | − type. | |
| 47 | − * info->write_event_value: | |
| 48 | − Write the value associated with on sensor event detectors. E.g. | |
| 49 | − a threshold above which an interrupt occurs. Note that the | |
| 50 | − meaning of the value to be set is event type dependent. | |
| 51 | − | |
| 52 | −- indio_dev->modes: | |
| 53 | − Specify whether direct access and / or ring buffer access is supported. | |
| 54 | −- indio_dev->buffer: | |
| 55 | − An optional associated buffer. | |
| 56 | −- indio_dev->pollfunc: | |
| 57 | − Poll function related elements. This controls what occurs when a trigger | |
| 58 | − to which this device is attached sends an event. | |
| 59 | −- indio_dev->channels: | |
| 60 | − Specification of device channels. Most attributes etc. are built | |
| 61 | − from this spec. | |
| 62 | −- indio_dev->num_channels: | |
| 63 | − How many channels are there? | |
| 64 | − | |
| 65 | −Once these are set up, a call to iio_device_register(indio_dev) | |
| 66 | −will register the device with the iio core. | |
| 67 | − | |
| 68 | −Worth noting here is that, if a ring buffer is to be used, it can be | |
| 69 | −allocated prior to registering the device with the iio-core, but must | |
| 70 | −be registered afterwards (otherwise the whole parentage of devices | |
| 71 | −gets confused) | |
| 72 | − | |
| 73 | −On remove, iio_device_unregister(indio_dev) will remove the device from | |
| 74 | −the core, and iio_device_free(indio_dev) will clean up. | |
| @@ -1,57 +0,0 @@ | ||
| 1 | −Overview of IIO | |
| 2 | − | |
| 3 | −The Industrial I/O subsystem is intended to provide support for devices | |
| 4 | −that in some sense are analog to digital converters (ADCs). As many | |
| 5 | −actual devices combine some ADCs with digital to analog converters | |
| 6 | −(DACs) that functionality is also supported. | |
| 7 | − | |
| 8 | −The aim is to fill the gap between the somewhat similar hwmon and | |
| 9 | −input subsystems. Hwmon is very much directed at low sample rate | |
| 10 | −sensors used in applications such as fan speed control and temperature | |
| 11 | −measurement. Input is, as its name suggests focused on input | |
| 12 | −devices. In some cases there is considerable overlap between these and | |
| 13 | −IIO. | |
| 14 | − | |
| 15 | −A typical device falling into this category would be connected via SPI | |
| 16 | −or I2C. | |
| 17 | − | |
| 18 | −Functionality of IIO | |
| 19 | − | |
| 20 | −* Basic device registration and handling. This is very similar to | |
| 21 | −hwmon with simple polled access to device channels via sysfs. | |
| 22 | − | |
| 23 | −* Event chrdevs. These are similar to input in that they provide a | |
| 24 | −route to user space for hardware triggered events. Such events include | |
| 25 | −threshold detectors, free-fall detectors and more complex action | |
| 26 | −detection. The events themselves are currently very simple with | |
| 27 | −merely an event code and a timestamp. Any data associated with the | |
| 28 | −event must be accessed via polling. | |
| 29 | − | |
| 30 | −Note: A given device may have one or more event channel. These events are | |
| 31 | −turned on or off (if possible) via sysfs interfaces. | |
| 32 | − | |
| 33 | −* Hardware buffer support. Some recent sensors have included | |
| 34 | −fifo / ring buffers on the sensor chip. These greatly reduce the load | |
| 35 | −on the host CPU by buffering relatively large numbers of data samples | |
| 36 | −based on an internal sampling clock. Examples include VTI SCA3000 | |
| 37 | −series and Analog Devices ADXL345 accelerometers. Each buffer supports | |
| 38 | −polling to establish when data is available. | |
| 39 | − | |
| 40 | −* Trigger and software buffer support. In many data analysis | |
| 41 | −applications it it useful to be able to capture data based on some | |
| 42 | −external signal (trigger). These triggers might be a data ready | |
| 43 | −signal, a gpio line connected to some external system or an on | |
| 44 | −processor periodic interrupt. A single trigger may initialize data | |
| 45 | −capture or reading from a number of sensors. These triggers are | |
| 46 | −used in IIO to fill software buffers acting in a very similar | |
| 47 | −fashion to the hardware buffers described above. | |
| 48 | − | |
| 49 | −Other documentation: | |
| 50 | − | |
| 51 | −device.txt - elements of a typical device driver. | |
| 52 | − | |
| 53 | −trigger.txt - elements of a typical trigger driver. | |
| 54 | − | |
| 55 | −ring.txt - additional elements required for buffer support. | |
| 56 | − | |
| 57 | −sysfs-bus-iio - abi documentation file. | |
| @@ -1,47 +0,0 @@ | ||
| 1 | −Buffer support within IIO | |
| 2 | − | |
| 3 | −This document is intended as a general overview of the functionality | |
| 4 | −a buffer may supply and how it is specified within IIO. For more | |
| 5 | −specific information on a given buffer implementation, see the | |
| 6 | −comments in the source code. Note that some drivers allow buffer | |
| 7 | −implementation to be selected at compile time via Kconfig options. | |
| 8 | − | |
| 9 | −A given buffer implementation typically embeds a struct | |
| 10 | −iio_ring_buffer and it is a pointer to this that is provided to the | |
| 11 | −IIO core. Access to the embedding structure is typically done via | |
| 12 | −container_of functions. | |
| 13 | − | |
| 14 | −struct iio_ring_buffer contains a struct iio_ring_setup_ops *setup_ops | |
| 15 | −which in turn contains the 4 function pointers | |
| 16 | −(preenable, postenable, predisable and postdisable). | |
| 17 | −These are used to perform device specific steps on either side | |
| 18 | −of the core changing its current mode to indicate that the buffer | |
| 19 | −is enabled or disabled (along with enabling triggering etc. as appropriate). | |
| 20 | − | |
| 21 | −Also in struct iio_ring_buffer is a struct iio_ring_access_funcs. | |
| 22 | −The function pointers within here are used to allow the core to handle | |
| 23 | −as much buffer functionality as possible. Note almost all of these | |
| 24 | −are optional. | |
| 25 | − | |
| 26 | −store_to | |
| 27 | − If possible, push data to the buffer. | |
| 28 | − | |
| 29 | −read_last | |
| 30 | − If possible, get the most recent scan from the buffer (without removal). | |
| 31 | − This provides polling like functionality whilst the ring buffering is in | |
| 32 | − use without a separate read from the device. | |
| 33 | − | |
| 34 | −rip_first_n | |
| 35 | − The primary buffer reading function. Note that it may well not return | |
| 36 | − as much data as requested. | |
| 37 | − | |
| 38 | −request_update | |
| 39 | − If parameters have changed that require reinitialization or configuration of | |
| 40 | − the buffer this will trigger it. | |
| 41 | − | |
| 42 | −set_bytes_per_datum | |
| 43 | − Set the number of bytes for a complete scan. (All samples + timestamp) | |
| 44 | − | |
| 45 | −set_length | |
| 46 | − Set the number of complete scans that may be held by the buffer. | |
| 47 | − | |
| @@ -1,79 +0,0 @@ | ||
| 1 | −What: /sys/bus/iio/devices/device[n]/in_illuminance0[_input|_raw] | |
| 2 | −KernelVersion: 2.6.35 | |
| 3 | −Contact: linux-iio@vger.kernel.org | |
| 4 | −Description: | |
| 5 | − This should return the calculated lux from the light sensor. If | |
| 6 | − it comes back in SI units, it should also include _input else it | |
| 7 | − should include _raw to signify it is not in SI units. | |
| 8 | − | |
| 9 | −What: /sys/.../device[n]/proximity_on_chip_ambient_infrared_suppression | |
| 10 | −KernelVersion: 2.6.37 | |
| 11 | −Contact: linux-iio@vger.kernel.org | |
| 12 | −Description: | |
| 13 | − Hardware dependent mode for an ALS device to calculate the value | |
| 14 | − in proximity mode. When this is enabled, then the device should | |
| 15 | − use a infrared sensor reading to remove infrared noise from the | |
| 16 | − proximity reading. If this is not enabled, the driver can still | |
| 17 | − do this calculation manually by reading the infrared sensor | |
| 18 | − value and doing the negation in sw. | |
| 19 | − | |
| 20 | −What: /sys/bus/iio/devices/device[n]/in_proximity[_input|_raw] | |
| 21 | −KernelVersion: 2.6.37 | |
| 22 | −Contact: linux-iio@vger.kernel.org | |
| 23 | −Description: | |
| 24 | − This property is supported by proximity sensors and should be | |
| 25 | − used to return the value of a reading by the sensor. If this | |
| 26 | − value is returned in SI units, it should also include _input | |
| 27 | − but if it is not, then it should include _raw. | |
| 28 | − | |
| 29 | −What: /sys/bus/iio/devices/device[n]/intensity_infrared[_input|_raw] | |
| 30 | −KernelVersion: 2.6.37 | |
| 31 | −Contact: linux-iio@vger.kernel.org | |
| 32 | −Description: | |
| 33 | − This property is supported by sensors that have an infrared | |
| 34 | − sensing mode. This value should be the output from a reading | |
| 35 | − and if expressed in SI units, should include _input. If this | |
| 36 | − value is not in SI units, then it should include _raw. | |
| 37 | − | |
| 38 | −What: /sys/bus/iio/devices/device[n]/in_illuminance0_target | |
| 39 | −KernelVersion: 2.6.37 | |
| 40 | −Contact: linux-iio@vger.kernel.org | |
| 41 | −Description: | |
| 42 | − This property gets/sets the last known external | |
| 43 | − lux measurement used in/for calibration. | |
| 44 | − | |
| 45 | −What: /sys/bus/iio/devices/device[n]/in_illuminance0_integration_time | |
| 46 | −KernelVersion: 2.6.37 | |
| 47 | −Contact: linux-iio@vger.kernel.org | |
| 48 | −Description: | |
| 49 | − This property gets/sets the sensors ADC analog integration time. | |
| 50 | − | |
| 51 | −What: /sys/bus/iio/devices/device[n]/in_illuminance0_lux_table | |
| 52 | −KernelVersion: 2.6.37 | |
| 53 | −Contact: linux-iio@vger.kernel.org | |
| 54 | −Description: | |
| 55 | − This property gets/sets the table of coefficients | |
| 56 | − used in calculating illuminance in lux. | |
| 57 | − | |
| 58 | −What: /sys/bus/iio/devices/device[n]/in_intensity_clear[_input|_raw] | |
| 59 | −What: /sys/bus/iio/devices/device[n]/in_intensity_red[_input|_raw] | |
| 60 | −What: /sys/bus/iio/devices/device[n]/in_intensity_green[_input|_raw] | |
| 61 | −What: /sys/bus/iio/devices/device[n]/in_intensity_blue[_input|_raw] | |
| 62 | −KernelVersion: 3.6.0 | |
| 63 | −Contact: linux-iio@vger.kernel.org | |
| 64 | −Description: | |
| 65 | − This property is supported by sensors that have a RGBC | |
| 66 | − sensing mode. This value should be the output from a reading | |
| 67 | − and if expressed in SI units, should include _input. If this | |
| 68 | − value is not in SI units (irradiance, uW/mm^2), then it should | |
| 69 | − include _raw. | |
| 70 | − | |
| 71 | −What: /sys/bus/iio/devices/device[n]/in_cct0[_input|_raw] | |
| 72 | −KernelVersion: 3.6.0 | |
| 73 | −Contact: linux-iio@vger.kernel.org | |
| 74 | −Description: | |
| 75 | − This should return the correlated color temperature from the | |
| 76 | − light sensor. If it comes back in SI units, it should also | |
| 77 | − include _input else it should include _raw to signify it is not | |
| 78 | − in SI units. | |
| 79 | − | |
| @@ -1,31 +0,0 @@ | ||
| 1 | −IIO trigger drivers. | |
| 2 | − | |
| 3 | −Many triggers are provided by hardware that will also be registered as | |
| 4 | −an IIO device. Whilst this can create device specific complexities | |
| 5 | −such triggers are registered with the core in the same way as | |
| 6 | −stand-alone triggers. | |
| 7 | − | |
| 8 | −struct iio_trig *trig = iio_trigger_alloc("<trigger format string>", ...); | |
| 9 | − | |
| 10 | −allocates a trigger structure. The key elements to then fill in within | |
| 11 | −a driver are: | |
| 12 | − | |
| 13 | −trig->set_trigger_state: | |
| 14 | − Function that enables / disables the underlying source of the trigger. | |
| 15 | − | |
| 16 | −There is also a | |
| 17 | −trig->alloc_list which is useful for drivers that allocate multiple | |
| 18 | −triggers to keep track of what they have created. | |
| 19 | − | |
| 20 | −When these have been set call: | |
| 21 | − | |
| 22 | −iio_trigger_register(trig); | |
| 23 | − | |
| 24 | −to register the trigger with the core, making it available to trigger | |
| 25 | −consumers. | |
| 26 | − | |
| 27 | −Trigger Consumers | |
| 28 | − | |
| 29 | −Currently triggers are only used for the filling of software | |
| 30 | −buffers and as such any device supporting INDIO_BUFFER_TRIGGERED has the | |
| 31 | −consumer interface automatically created. | |
| @@ -286,35 +286,16 @@ static int adis16203_probe(struct spi_device *spi) · 285 unmodified lines | ||
| 286 | 286 | if (ret) |
| 287 | 287 | return ret; |
| 288 | 288 | |
| 289 | − ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL); | |
| 289 | + ret = devm_adis_setup_buffer_and_trigger(st, indio_dev, NULL); | |
| 290 | 290 | if (ret) |
| 291 | 291 | return ret; |
| 292 | 292 | |
| 293 | 293 | /* Get the device into a sane initial state */ |
| 294 | 294 | ret = adis_initial_startup(st); |
| 295 | 295 | if (ret) |
| 296 | − goto error_cleanup_buffer_trigger; | |
| 297 | − | |
| 298 | − ret = iio_device_register(indio_dev); | |
| 299 | − if (ret) | |
| 300 | − goto error_cleanup_buffer_trigger; | |
| 301 | − | |
| 302 | − return 0; | |
| 303 | − | |
| 304 | −error_cleanup_buffer_trigger: | |
| 305 | − adis_cleanup_buffer_and_trigger(st, indio_dev); | |
| 306 | − return ret; | |
| 307 | −} | |
| 308 | − | |
| 309 | −static int adis16203_remove(struct spi_device *spi) | |
| 310 | −{ | |
| 311 | − struct iio_dev *indio_dev = spi_get_drvdata(spi); | |
| 312 | − struct adis *st = iio_priv(indio_dev); | |
| 313 | − | |
| 314 | − iio_device_unregister(indio_dev); | |
| 315 | − adis_cleanup_buffer_and_trigger(st, indio_dev); | |
| 296 | + return ret; | |
| 316 | 297 | |
| 317 | − return 0; | |
| 298 | + return devm_iio_device_register(&spi->dev, indio_dev); | |
| 318 | 299 | } |
| 319 | 300 | |
| 320 | 301 | static const struct of_device_id adis16203_of_match[] = { |
| @@ -330,7 +311,6 @@ static struct spi_driver adis16203_driver = { · 9 unmodified lines | ||
| 330 | 311 | .of_match_table = adis16203_of_match, |
| 331 | 312 | }, |
| 332 | 313 | .probe = adis16203_probe, |
| 333 | − .remove = adis16203_remove, | |
| 334 | 314 | }; |
| 335 | 315 | module_spi_driver(adis16203_driver); |
| 336 | 316 | |
| @@ -415,35 +415,17 @@ static int adis16240_probe(struct spi_device *spi) · 414 unmodified lines | ||
| 415 | 415 | ret = adis_init(st, indio_dev, spi, &adis16240_data); |
| 416 | 416 | if (ret) |
| 417 | 417 | return ret; |
| 418 | − ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL); | |
| 418 | + ret = devm_adis_setup_buffer_and_trigger(st, indio_dev, NULL); | |
| 419 | 419 | if (ret) |
| 420 | 420 | return ret; |
| 421 | 421 | |
| 422 | 422 | /* Get the device into a sane initial state */ |
| 423 | 423 | ret = adis_initial_startup(st); |
| 424 | 424 | if (ret) |
| 425 | − goto error_cleanup_buffer_trigger; | |
| 426 | − ret = iio_device_register(indio_dev); | |
| 427 | − if (ret) | |
| 428 | − goto error_cleanup_buffer_trigger; | |
| 429 | − return 0; | |
| 430 | − | |
| 431 | −error_cleanup_buffer_trigger: | |
| 432 | − adis_cleanup_buffer_and_trigger(st, indio_dev); | |
| 433 | − return ret; | |
| 434 | −} | |
| 435 | − | |
| 436 | −static int adis16240_remove(struct spi_device *spi) | |
| 437 | −{ | |
| 438 | − struct iio_dev *indio_dev = spi_get_drvdata(spi); | |
| 439 | − struct adis *st = iio_priv(indio_dev); | |
| 440 | − | |
| 441 | − iio_device_unregister(indio_dev); | |
| 442 | − adis_cleanup_buffer_and_trigger(st, indio_dev); | |
| 425 | + return ret; | |
| 443 | 426 | |
| 444 | − return 0; | |
| 427 | + return devm_iio_device_register(&spi->dev, indio_dev); | |
| 445 | 428 | } |
| 446 | − | |
| 447 | 429 | static const struct of_device_id adis16240_of_match[] = { |
| 448 | 430 | { .compatible = "adi,adis16240" }, |
| 449 | 431 | { }, |
| @@ -456,7 +438,6 @@ static struct spi_driver adis16240_driver = { · 6 unmodified lines | ||
| 456 | 438 | .of_match_table = adis16240_of_match, |
| 457 | 439 | }, |
| 458 | 440 | .probe = adis16240_probe, |
| 459 | − .remove = adis16240_remove, | |
| 460 | 441 | }; |
| 461 | 442 | module_spi_driver(adis16240_driver); |
| 462 | 443 | |
| @@ -397,7 +397,6 @@ static int ad9834_probe(struct spi_device *spi) · 396 unmodified lines | ||
| 397 | 397 | struct regulator *reg; |
| 398 | 398 | int ret; |
| 399 | 399 | |
| 400 | − | |
| 401 | 400 | reg = devm_regulator_get(&spi->dev, "avdd"); |
| 402 | 401 | if (IS_ERR(reg)) |
| 403 | 402 | return PTR_ERR(reg); |
| @@ -53,7 +53,7 @@ static int kpc_dma_transfer(struct dev_private_data *priv, · 52 unmodified lines | ||
| 53 | 53 | |
| 54 | 54 | acd = kzalloc(sizeof(*acd), GFP_KERNEL); |
| 55 | 55 | if (!acd) { |
| 56 | − dev_err(&priv->ldev->pldev->dev, "Couldn't kmalloc space for for the aio data\n"); | |
| 56 | + dev_err(&priv->ldev->pldev->dev, "Couldn't kmalloc space for the aio data\n"); | |
| 57 | 57 | return -ENOMEM; |
| 58 | 58 | } |
| 59 | 59 | memset(acd, 0x66, sizeof(struct aio_cb_data)); |
| @@ -69,7 +69,7 @@ static int kpc_dma_transfer(struct dev_private_data *priv, · 9 unmodified lines | ||
| 69 | 69 | acd->user_pages = kcalloc(acd->page_count, sizeof(struct page *), |
| 70 | 70 | GFP_KERNEL); |
| 71 | 71 | if (!acd->user_pages) { |
| 72 | − dev_err(&priv->ldev->pldev->dev, "Couldn't kmalloc space for for the page pointers\n"); | |
| 72 | + dev_err(&priv->ldev->pldev->dev, "Couldn't kmalloc space for the page pointers\n"); | |
| 73 | 73 | rv = -ENOMEM; |
| 74 | 74 | goto err_alloc_userpages; |
| 75 | 75 | } |
| @@ -405,9 +405,9 @@ int ks_wlan_hw_tx(struct ks_wlan_private *priv, void *p, unsigned long size, · 404 unmodified lines | ||
| 405 | 405 | return result; |
| 406 | 406 | } |
| 407 | 407 | |
| 408 | −static void rx_event_task(unsigned long dev) | |
| 408 | +static void rx_event_task(struct tasklet_struct *t) | |
| 409 | 409 | { |
| 410 | − struct ks_wlan_private *priv = (struct ks_wlan_private *)dev; | |
| 410 | + struct ks_wlan_private *priv = from_tasklet(priv, t, rx_bh_task); | |
| 411 | 411 | struct rx_device_buffer *rp; |
| 412 | 412 | |
| 413 | 413 | if (rxq_has_space(priv) && priv->dev_state >= DEVICE_STATE_BOOT) { |
| @@ -618,7 +618,7 @@ static int trx_device_init(struct ks_wlan_private *priv) · 204 unmodified lines | ||
| 618 | 618 | spin_lock_init(&priv->tx_dev.tx_dev_lock); |
| 619 | 619 | spin_lock_init(&priv->rx_dev.rx_dev_lock); |
| 620 | 620 | |
| 621 | − tasklet_init(&priv->rx_bh_task, rx_event_task, (unsigned long)priv); | |
| 621 | + tasklet_setup(&priv->rx_bh_task, rx_event_task); | |
| 622 | 622 | |
| 623 | 623 | return 0; |
| 624 | 624 | } |
| @@ -2205,9 +2205,9 @@ static void hostif_sme_execute(struct ks_wlan_private *priv, int event) · 2204 unmodified lines | ||
| 2205 | 2205 | } |
| 2206 | 2206 | |
| 2207 | 2207 | static |
| 2208 | −void hostif_sme_task(unsigned long dev) | |
| 2208 | +void hostif_sme_task(struct tasklet_struct *t) | |
| 2209 | 2209 | { |
| 2210 | − struct ks_wlan_private *priv = (struct ks_wlan_private *)dev; | |
| 2210 | + struct ks_wlan_private *priv = from_tasklet(priv, t, sme_task); | |
| 2211 | 2211 | |
| 2212 | 2212 | if (priv->dev_state < DEVICE_STATE_BOOT) |
| 2213 | 2213 | return; |
| @@ -2258,7 +2258,7 @@ static inline void hostif_sme_init(struct ks_wlan_private *priv) · 44 unmodified lines | ||
| 2258 | 2258 | priv->sme_i.qtail = 0; |
| 2259 | 2259 | spin_lock_init(&priv->sme_i.sme_spin); |
| 2260 | 2260 | priv->sme_i.sme_flag = 0; |
| 2261 | − tasklet_init(&priv->sme_task, hostif_sme_task, (unsigned long)priv); | |
| 2261 | + tasklet_setup(&priv->sme_task, hostif_sme_task); | |
| 2262 | 2262 | } |
| 2263 | 2263 | |
| 2264 | 2264 | static inline void hostif_wpa_init(struct ks_wlan_private *priv) |
| @@ -19,14 +19,13 @@ · 18 unmodified lines | ||
| 19 | 19 | #include <linux/i2c.h> |
| 20 | 20 | #include <linux/mutex.h> |
| 21 | 21 | #include <linux/delay.h> |
| 22 | −#include <linux/gpio.h> | |
| 22 | +#include <linux/gpio/consumer.h> | |
| 23 | 23 | #include <linux/slab.h> |
| 24 | 24 | |
| 25 | 25 | #include "../include/media/lm3554.h" |
| 26 | 26 | #include <media/v4l2-ctrls.h> |
| 27 | 27 | #include <media/v4l2-device.h> |
| 28 | 28 | #include <linux/acpi.h> |
| 29 | −#include <linux/gpio/consumer.h> | |
| 30 | 29 | #include "../include/linux/atomisp_gmin_platform.h" |
| 31 | 30 | #include "../include/linux/atomisp.h" |
| 32 | 31 | |
| @@ -173,7 +172,7 @@ static void lm3554_flash_off_delay(struct timer_list *t) · 140 unmodified lines | ||
| 173 | 172 | struct lm3554 *flash = from_timer(flash, t, flash_off_delay); |
| 174 | 173 | struct lm3554_platform_data *pdata = flash->pdata; |
| 175 | 174 | |
| 176 | − gpio_set_value(pdata->gpio_strobe, 0); | |
| 175 | + gpiod_set_value(pdata->gpio_strobe, 0); | |
| 177 | 176 | } |
| 178 | 177 | |
| 179 | 178 | static int lm3554_hw_strobe(struct i2c_client *client, bool strobe) |
| @@ -209,7 +208,7 @@ static int lm3554_hw_strobe(struct i2c_client *client, bool strobe) · 29 unmodified lines | ||
| 209 | 208 | * so must strobe off here |
| 210 | 209 | */ |
| 211 | 210 | if (timer_pending) |
| 212 | − gpio_set_value(pdata->gpio_strobe, 0); | |
| 211 | + gpiod_set_value(pdata->gpio_strobe, 0); | |
| 213 | 212 | |
| 214 | 213 | /* Restore flash current settings */ |
| 215 | 214 | ret = lm3554_set_flash(flash); |
| @@ -217,7 +216,7 @@ static int lm3554_hw_strobe(struct i2c_client *client, bool strobe) · 1 unmodified line | ||
| 217 | 216 | goto err; |
| 218 | 217 | |
| 219 | 218 | /* Strobe on Flash */ |
| 220 | − gpio_set_value(pdata->gpio_strobe, 1); | |
| 219 | + gpiod_set_value(pdata->gpio_strobe, 1); | |
| 221 | 220 | |
| 222 | 221 | return 0; |
| 223 | 222 | err: |
| @@ -627,7 +626,7 @@ static int __lm3554_s_power(struct lm3554 *flash, int power) · 403 unmodified lines | ||
| 627 | 626 | int ret; |
| 628 | 627 | |
| 629 | 628 | /*initialize flash driver*/ |
| 630 | − gpio_set_value(pdata->gpio_reset, power); | |
| 629 | + gpiod_set_value(pdata->gpio_reset, power); | |
| 631 | 630 | usleep_range(100, 100 + 1); |
| 632 | 631 | |
| 633 | 632 | if (power) { |
| @@ -766,33 +765,22 @@ static int lm3554_gpio_init(struct i2c_client *client) · 132 unmodified lines | ||
| 766 | 765 | struct lm3554_platform_data *pdata = flash->pdata; |
| 767 | 766 | int ret; |
| 768 | 767 | |
| 769 | − if (!gpio_is_valid(pdata->gpio_reset)) | |
| 768 | + if (!pdata->gpio_reset) | |
| 770 | 769 | return -EINVAL; |
| 771 | 770 | |
| 772 | − ret = gpio_direction_output(pdata->gpio_reset, 0); | |
| 771 | + ret = gpiod_direction_output(pdata->gpio_reset, 0); | |
| 773 | 772 | if (ret < 0) |
| 774 | − goto err_gpio_reset; | |
| 773 | + return ret; | |
| 775 | 774 | dev_info(&client->dev, "flash led reset successfully\n"); |
| 776 | 775 | |
| 777 | − if (!gpio_is_valid(pdata->gpio_strobe)) { | |
| 778 | − ret = -EINVAL; | |
| 779 | − goto err_gpio_dir_reset; | |
| 780 | − } | |
| 776 | + if (!pdata->gpio_strobe) | |
| 777 | + return -EINVAL; | |
| 781 | 778 | |
| 782 | − ret = gpio_direction_output(pdata->gpio_strobe, 0); | |
| 779 | + ret = gpiod_direction_output(pdata->gpio_strobe, 0); | |
| 783 | 780 | if (ret < 0) |
| 784 | − goto err_gpio_strobe; | |
| 781 | + return ret; | |
| 785 | 782 | |
| 786 | 783 | return 0; |
| 787 | − | |
| 788 | −err_gpio_strobe: | |
| 789 | − gpio_free(pdata->gpio_strobe); | |
| 790 | −err_gpio_dir_reset: | |
| 791 | − gpio_direction_output(pdata->gpio_reset, 0); | |
| 792 | −err_gpio_reset: | |
| 793 | − gpio_free(pdata->gpio_reset); | |
| 794 | − | |
| 795 | − return ret; | |
| 796 | 784 | } |
| 797 | 785 | |
| 798 | 786 | static int lm3554_gpio_uninit(struct i2c_client *client) |
| @@ -802,16 +790,14 @@ static int lm3554_gpio_uninit(struct i2c_client *client) · 3 unmodified lines | ||
| 802 | 790 | struct lm3554_platform_data *pdata = flash->pdata; |
| 803 | 791 | int ret; |
| 804 | 792 | |
| 805 | − ret = gpio_direction_output(pdata->gpio_strobe, 0); | |
| 793 | + ret = gpiod_direction_output(pdata->gpio_strobe, 0); | |
| 806 | 794 | if (ret < 0) |
| 807 | 795 | return ret; |
| 808 | 796 | |
| 809 | − ret = gpio_direction_output(pdata->gpio_reset, 0); | |
| 797 | + ret = gpiod_direction_output(pdata->gpio_reset, 0); | |
| 810 | 798 | if (ret < 0) |
| 811 | 799 | return ret; |
| 812 | 800 | |
| 813 | − gpio_free(pdata->gpio_strobe); | |
| 814 | − gpio_free(pdata->gpio_reset); | |
| 815 | 801 | return 0; |
| 816 | 802 | } |
| 817 | 803 | |
| @@ -819,18 +805,18 @@ static void *lm3554_platform_data_func(struct i2c_client *client) · 1 unmodified line | ||
| 819 | 805 | { |
| 820 | 806 | static struct lm3554_platform_data platform_data; |
| 821 | 807 | |
| 822 | − platform_data.gpio_reset = | |
| 823 | − desc_to_gpio(gpiod_get_index(&client->dev, | |
| 824 | − NULL, 2, GPIOD_OUT_LOW)); | |
| 825 | − platform_data.gpio_strobe = | |
| 826 | − desc_to_gpio(gpiod_get_index(&client->dev, | |
| 827 | − NULL, 0, GPIOD_OUT_LOW)); | |
| 828 | − platform_data.gpio_torch = | |
| 829 | − desc_to_gpio(gpiod_get_index(&client->dev, | |
| 830 | − NULL, 1, GPIOD_OUT_LOW)); | |
| 831 | − dev_info(&client->dev, "camera pdata: lm3554: reset: %d strobe %d torch %d\n", | |
| 832 | − platform_data.gpio_reset, platform_data.gpio_strobe, | |
| 833 | − platform_data.gpio_torch); | |
| 808 | + platform_data.gpio_reset = gpiod_get_index(&client->dev, | |
| 809 | + NULL, 2, GPIOD_OUT_LOW); | |
| 810 | + if (IS_ERR(platform_data.gpio_reset)) | |
| 811 | + return ERR_CAST(platform_data.gpio_reset); | |
| 812 | + platform_data.gpio_strobe = gpiod_get_index(&client->dev, | |
| 813 | + NULL, 0, GPIOD_OUT_LOW); | |
| 814 | + if (IS_ERR(platform_data.gpio_strobe)) | |
| 815 | + return ERR_CAST(platform_data.gpio_strobe); | |
| 816 | + platform_data.gpio_torch = gpiod_get_index(&client->dev, | |
| 817 | + NULL, 1, GPIOD_OUT_LOW); | |
| 818 | + if (IS_ERR(platform_data.gpio_torch)) | |
| 819 | + return ERR_CAST(platform_data.gpio_torch); | |
| 834 | 820 | |
| 835 | 821 | /* Set to TX2 mode, then ENVM/TX2 pin is a power amplifier sync input: |
| 836 | 822 | * ENVM/TX pin asserted, flash forced into torch; |
| @@ -857,6 +843,8 @@ static int lm3554_probe(struct i2c_client *client) · 20 unmodified lines | ||
| 857 | 843 | return -ENOMEM; |
| 858 | 844 | |
| 859 | 845 | flash->pdata = lm3554_platform_data_func(client); |
| 846 | + if (IS_ERR(flash->pdata)) | |
| 847 | + return PTR_ERR(flash->pdata); | |
| 860 | 848 | |
| 861 | 849 | v4l2_i2c_subdev_init(&flash->sd, client, &lm3554_ops); |
| 862 | 850 | flash->sd.internal_ops = &lm3554_internal_ops; |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | #ifndef _LM3554_H_ |
| 19 | 19 | #define _LM3554_H_ |
| 20 | 20 | |
| 21 | +#include <linux/gpio/consumer.h> | |
| 21 | 22 | #include <linux/videodev2.h> |
| 22 | 23 | #include <media/v4l2-subdev.h> |
| 23 | 24 | |
| @@ -119,9 +120,9 @@ · 95 unmodified lines | ||
| 119 | 120 | * lm3554_platform_data - Flash controller platform data |
| 120 | 121 | */ |
| 121 | 122 | struct lm3554_platform_data { |
| 122 | − int gpio_torch; | |
| 123 | − int gpio_strobe; | |
| 124 | − int gpio_reset; | |
| 123 | + struct gpio_desc *gpio_torch; | |
| 124 | + struct gpio_desc *gpio_strobe; | |
| 125 | + struct gpio_desc *gpio_reset; | |
| 125 | 126 | |
| 126 | 127 | unsigned int current_limit; |
| 127 | 128 | unsigned int envm_tx2; |
| @@ -36,8 +36,8 @@ int tegra_vde_iommu_map(struct tegra_vde *vde, · 35 unmodified lines | ||
| 36 | 36 | |
| 37 | 37 | addr = iova_dma_addr(&vde->iova, iova); |
| 38 | 38 | |
| 39 | − size = iommu_map_sg(vde->domain, addr, sgt->sgl, sgt->nents, | |
| 40 | − IOMMU_READ | IOMMU_WRITE); | |
| 39 | + size = iommu_map_sgtable(vde->domain, addr, sgt, | |
| 40 | + IOMMU_READ | IOMMU_WRITE); | |
| 41 | 41 | if (!size) { |
| 42 | 42 | __free_iova(&vde->iova, iova); |
| 43 | 43 | return -ENXIO; |
| @@ -18,8 +18,6 @@ menuconfig MOST_COMPONENTS · 17 unmodified lines | ||
| 18 | 18 | |
| 19 | 19 | if MOST_COMPONENTS |
| 20 | 20 | |
| 21 | −source "drivers/staging/most/cdev/Kconfig" | |
| 22 | − | |
| 23 | 21 | source "drivers/staging/most/net/Kconfig" |
| 24 | 22 | |
| 25 | 23 | source "drivers/staging/most/sound/Kconfig" |
| @@ -1,6 +1,5 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | |
| 3 | −obj-$(CONFIG_MOST_CDEV) += cdev/ | |
| 4 | 3 | obj-$(CONFIG_MOST_NET) += net/ |
| 5 | 4 | obj-$(CONFIG_MOST_SOUND) += sound/ |
| 6 | 5 | obj-$(CONFIG_MOST_VIDEO) += video/ |
| @@ -1,13 +0,0 @@ | ||
| 1 | −# SPDX-License-Identifier: GPL-2.0 | |
| 2 | −# | |
| 3 | −# MOST Cdev configuration | |
| 4 | −# | |
| 5 | − | |
| 6 | −config MOST_CDEV | |
| 7 | − tristate "Cdev" | |
| 8 | − | |
| 9 | − help | |
| 10 | − Say Y here if you want to commumicate via character devices. | |
| 11 | − | |
| 12 | − To compile this driver as a module, choose M here: the | |
| 13 | − module will be called most_cdev. | |
| @@ -1,4 +0,0 @@ | ||
| 1 | −# SPDX-License-Identifier: GPL-2.0 | |
| 2 | −obj-$(CONFIG_MOST_CDEV) += most_cdev.o | |
| 3 | − | |
| 4 | −most_cdev-objs := cdev.o | |
| @@ -100,12 +100,12 @@ struct dim2_hdm { · 99 unmodified lines | ||
| 100 | 100 | struct medialb_bus bus; |
| 101 | 101 | void (*on_netinfo)(struct most_interface *most_iface, |
| 102 | 102 | unsigned char link_state, unsigned char *addrs); |
| 103 | − void (*disable_platform)(struct platform_device *); | |
| 103 | + void (*disable_platform)(struct platform_device *pdev); | |
| 104 | 104 | }; |
| 105 | 105 | |
| 106 | 106 | struct dim2_platform_data { |
| 107 | − int (*enable)(struct platform_device *); | |
| 108 | − void (*disable)(struct platform_device *); | |
| 107 | + int (*enable)(struct platform_device *pdev); | |
| 108 | + void (*disable)(struct platform_device *pdev); | |
| 109 | 109 | }; |
| 110 | 110 | |
| 111 | 111 | #define iface_to_hdm(iface) container_of(iface, struct dim2_hdm, most_iface) |
| @@ -533,9 +533,9 @@ static void mtk_hsdma_rx(struct mtk_hsdam_engine *hsdma) · 532 unmodified lines | ||
| 533 | 533 | mtk_hsdma_chan_done(hsdma, chan); |
| 534 | 534 | } |
| 535 | 535 | |
| 536 | −static void mtk_hsdma_tasklet(unsigned long arg) | |
| 536 | +static void mtk_hsdma_tasklet(struct tasklet_struct *t) | |
| 537 | 537 | { |
| 538 | − struct mtk_hsdam_engine *hsdma = (struct mtk_hsdam_engine *)arg; | |
| 538 | + struct mtk_hsdam_engine *hsdma = from_tasklet(hsdma, t, task); | |
| 539 | 539 | |
| 540 | 540 | mtk_hsdma_rx(hsdma); |
| 541 | 541 | mtk_hsdma_tx(hsdma); |
| @@ -670,7 +670,7 @@ static int mtk_hsdma_probe(struct platform_device *pdev) · 128 unmodified lines | ||
| 670 | 670 | if (IS_ERR(base)) |
| 671 | 671 | return PTR_ERR(base); |
| 672 | 672 | hsdma->base = base + HSDMA_BASE_OFFSET; |
| 673 | − tasklet_init(&hsdma->task, mtk_hsdma_tasklet, (unsigned long)hsdma); | |
| 673 | + tasklet_setup(&hsdma->task, mtk_hsdma_tasklet); | |
| 674 | 674 | |
| 675 | 675 | irq = platform_get_irq(pdev, 0); |
| 676 | 676 | if (irq < 0) |
| @@ -1,4 +1,4 @@ | ||
| 1 | 1 | |
| 2 | 2 | - general code review and cleanup |
| 3 | 3 | |
| 4 | −Cc: NeilBrown <neil@brown.name> | |
| 4 | +Cc: NeilBrown <neil@brown.name> | |
| @@ -289,7 +289,7 @@ EXPORT_SYMBOL(nvec_write_async); · 288 unmodified lines | ||
| 289 | 289 | * interrupt handlers. |
| 290 | 290 | * |
| 291 | 291 | * Returns: 0 on success, a negative error code on failure. |
| 292 | − * The response message is returned in @msg. Shall be freed with | |
| 292 | + * The response message is returned in @msg. Shall be freed | |
| 293 | 293 | * with nvec_msg_free() once no longer used. |
| 294 | 294 | * |
| 295 | 295 | */ |
| @@ -1233,8 +1233,7 @@ static int cvmx_usb_fill_tx_hw(struct octeon_hcd *usb, · 1232 unmodified lines | ||
| 1233 | 1233 | cvmx_write64_uint32(csr_address, *ptr++); |
| 1234 | 1234 | cvmx_write64_uint32(csr_address, *ptr++); |
| 1235 | 1235 | cvmx_write64_uint32(csr_address, *ptr++); |
| 1236 | − cvmx_read64_uint64( | |
| 1237 | − CVMX_USBNX_DMA0_INB_CHN0(usb->index)); | |
| 1236 | + cvmx_read64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index)); | |
| 1238 | 1237 | words -= 3; |
| 1239 | 1238 | } |
| 1240 | 1239 | cvmx_write64_uint32(csr_address, *ptr++); |
| @@ -117,9 +117,15 @@ struct pi433_rx_cfg { · 116 unmodified lines | ||
| 117 | 117 | |
| 118 | 118 | /* packet format */ |
| 119 | 119 | enum option_on_off enable_sync; |
| 120 | − enum option_on_off enable_length_byte; /* should be used in combination with sync, only */ | |
| 121 | − enum address_filtering enable_address_filtering; /* operational with sync, only */ | |
| 122 | − enum option_on_off enable_crc; /* only operational, if sync on and fixed length or length byte is used */ | |
| 120 | + | |
| 121 | + /* should be used in combination with sync, only */ | |
| 122 | + enum option_on_off enable_length_byte; | |
| 123 | + | |
| 124 | + /* operational with sync, only */ | |
| 125 | + enum address_filtering enable_address_filtering; | |
| 126 | + | |
| 127 | + /* only operational, if sync on and fixed length or length byte is used */ | |
| 128 | + enum option_on_off enable_crc; | |
| 123 | 129 | |
| 124 | 130 | __u8 sync_length; |
| 125 | 131 | __u8 fixed_message_length; |
| @@ -130,12 +136,16 @@ struct pi433_rx_cfg { · 4 unmodified lines | ||
| 130 | 136 | __u8 broadcast_address; |
| 131 | 137 | }; |
| 132 | 138 | |
| 133 | −#define PI433_IOC_MAGIC 'r' | |
| 139 | +#define PI433_IOC_MAGIC 'r' | |
| 134 | 140 | |
| 135 | −#define PI433_IOC_RD_TX_CFG _IOR(PI433_IOC_MAGIC, PI433_TX_CFG_IOCTL_NR, char[sizeof(struct pi433_tx_cfg)]) | |
| 136 | −#define PI433_IOC_WR_TX_CFG _IOW(PI433_IOC_MAGIC, PI433_TX_CFG_IOCTL_NR, char[sizeof(struct pi433_tx_cfg)]) | |
| 141 | +#define PI433_IOC_RD_TX_CFG \ | |
| 142 | + _IOR(PI433_IOC_MAGIC, PI433_TX_CFG_IOCTL_NR, char[sizeof(struct pi433_tx_cfg)]) | |
| 143 | +#define PI433_IOC_WR_TX_CFG \ | |
| 144 | + _IOW(PI433_IOC_MAGIC, PI433_TX_CFG_IOCTL_NR, char[sizeof(struct pi433_tx_cfg)]) | |
| 137 | 145 | |
| 138 | −#define PI433_IOC_RD_RX_CFG _IOR(PI433_IOC_MAGIC, PI433_RX_CFG_IOCTL_NR, char[sizeof(struct pi433_rx_cfg)]) | |
| 139 | −#define PI433_IOC_WR_RX_CFG _IOW(PI433_IOC_MAGIC, PI433_RX_CFG_IOCTL_NR, char[sizeof(struct pi433_rx_cfg)]) | |
| 146 | +#define PI433_IOC_RD_RX_CFG \ | |
| 147 | + _IOR(PI433_IOC_MAGIC, PI433_RX_CFG_IOCTL_NR, char[sizeof(struct pi433_rx_cfg)]) | |
| 148 | +#define PI433_IOC_WR_RX_CFG \ | |
| 149 | + _IOW(PI433_IOC_MAGIC, PI433_RX_CFG_IOCTL_NR, char[sizeof(struct pi433_rx_cfg)]) | |
| 140 | 150 | |
| 141 | 151 | #endif /* PI433_H */ |
| @@ -2337,21 +2337,21 @@ void ql_dump_hw_cb(struct ql_adapter *qdev, int size, u32 bit, u16 q_id); · 2336 unmodified lines | ||
| 2337 | 2337 | #endif |
| 2338 | 2338 | |
| 2339 | 2339 | #ifdef QL_OB_DUMP |
| 2340 | −void ql_dump_tx_desc(struct tx_buf_desc *tbd); | |
| 2341 | −void ql_dump_ob_mac_iocb(struct ob_mac_iocb_req *ob_mac_iocb); | |
| 2342 | −void ql_dump_ob_mac_rsp(struct ob_mac_iocb_rsp *ob_mac_rsp); | |
| 2343 | −#define QL_DUMP_OB_MAC_IOCB(ob_mac_iocb) ql_dump_ob_mac_iocb(ob_mac_iocb) | |
| 2344 | −#define QL_DUMP_OB_MAC_RSP(ob_mac_rsp) ql_dump_ob_mac_rsp(ob_mac_rsp) | |
| 2340 | +void ql_dump_tx_desc(struct ql_adapter *qdev, struct tx_buf_desc *tbd); | |
| 2341 | +void ql_dump_ob_mac_iocb(struct ql_adapter *qdev, struct ob_mac_iocb_req *ob_mac_iocb); | |
| 2342 | +void ql_dump_ob_mac_rsp(struct ql_adapter *qdev, struct ob_mac_iocb_rsp *ob_mac_rsp); | |
| 2343 | +#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb) ql_dump_ob_mac_iocb(qdev, ob_mac_iocb) | |
| 2344 | +#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp) ql_dump_ob_mac_rsp(qdev, ob_mac_rsp) | |
| 2345 | 2345 | #else |
| 2346 | −#define QL_DUMP_OB_MAC_IOCB(ob_mac_iocb) | |
| 2347 | −#define QL_DUMP_OB_MAC_RSP(ob_mac_rsp) | |
| 2346 | +#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb) | |
| 2347 | +#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp) | |
| 2348 | 2348 | #endif |
| 2349 | 2349 | |
| 2350 | 2350 | #ifdef QL_IB_DUMP |
| 2351 | −void ql_dump_ib_mac_rsp(struct ib_mac_iocb_rsp *ib_mac_rsp); | |
| 2352 | −#define QL_DUMP_IB_MAC_RSP(ib_mac_rsp) ql_dump_ib_mac_rsp(ib_mac_rsp) | |
| 2351 | +void ql_dump_ib_mac_rsp(struct ql_adapter *qdev, struct ib_mac_iocb_rsp *ib_mac_rsp); | |
| 2352 | +#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp) ql_dump_ib_mac_rsp(qdev, ib_mac_rsp) | |
| 2353 | 2353 | #else |
| 2354 | −#define QL_DUMP_IB_MAC_RSP(ib_mac_rsp) | |
| 2354 | +#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp) | |
| 2355 | 2355 | #endif |
| 2356 | 2356 | |
| 2357 | 2357 | #ifdef QL_ALL_DUMP |
| @@ -1431,7 +1431,7 @@ void ql_dump_routing_entries(struct ql_adapter *qdev) · 1430 unmodified lines | ||
| 1431 | 1431 | } |
| 1432 | 1432 | if (value) |
| 1433 | 1433 | netdev_err(qdev->ndev, |
| 1434 | − "%s: Routing Mask %d = 0x%.08x\n", | |
| 1434 | + "Routing Mask %d = 0x%.08x\n", | |
| 1435 | 1435 | i, value); |
| 1436 | 1436 | } |
| 1437 | 1437 | ql_sem_unlock(qdev, SEM_RT_IDX_MASK); |
| @@ -1617,6 +1617,9 @@ void ql_dump_qdev(struct ql_adapter *qdev) · 179 unmodified lines | ||
| 1617 | 1617 | #ifdef QL_CB_DUMP |
| 1618 | 1618 | void ql_dump_wqicb(struct wqicb *wqicb) |
| 1619 | 1619 | { |
| 1620 | + struct tx_ring *tx_ring = container_of(wqicb, struct tx_ring, wqicb); | |
| 1621 | + struct ql_adapter *qdev = tx_ring->qdev; | |
| 1622 | + | |
| 1620 | 1623 | netdev_err(qdev->ndev, "Dumping wqicb stuff...\n"); |
| 1621 | 1624 | netdev_err(qdev->ndev, "wqicb->len = 0x%x\n", le16_to_cpu(wqicb->len)); |
| 1622 | 1625 | netdev_err(qdev->ndev, "wqicb->flags = %x\n", |
| @@ -1632,8 +1635,8 @@ void ql_dump_wqicb(struct wqicb *wqicb) · 9 unmodified lines | ||
| 1632 | 1635 | |
| 1633 | 1636 | void ql_dump_tx_ring(struct tx_ring *tx_ring) |
| 1634 | 1637 | { |
| 1635 | − if (!tx_ring) | |
| 1636 | − return; | |
| 1638 | + struct ql_adapter *qdev = tx_ring->qdev; | |
| 1639 | + | |
| 1637 | 1640 | netdev_err(qdev->ndev, "===================== Dumping tx_ring %d ===============\n", |
| 1638 | 1641 | tx_ring->wq_id); |
| 1639 | 1642 | netdev_err(qdev->ndev, "tx_ring->base = %p\n", tx_ring->wq_base); |
| @@ -1657,6 +1660,8 @@ void ql_dump_tx_ring(struct tx_ring *tx_ring) · 17 unmodified lines | ||
| 1657 | 1660 | void ql_dump_ricb(struct ricb *ricb) |
| 1658 | 1661 | { |
| 1659 | 1662 | int i; |
| 1663 | + struct ql_adapter *qdev = | |
| 1664 | + container_of(ricb, struct ql_adapter, ricb); | |
| 1660 | 1665 | |
| 1661 | 1666 | netdev_err(qdev->ndev, "===================== Dumping ricb ===============\n"); |
| 1662 | 1667 | netdev_err(qdev->ndev, "Dumping ricb stuff...\n"); |
| @@ -1686,6 +1691,9 @@ void ql_dump_ricb(struct ricb *ricb) · 23 unmodified lines | ||
| 1686 | 1691 | |
| 1687 | 1692 | void ql_dump_cqicb(struct cqicb *cqicb) |
| 1688 | 1693 | { |
| 1694 | + struct rx_ring *rx_ring = container_of(cqicb, struct rx_ring, cqicb); | |
| 1695 | + struct ql_adapter *qdev = rx_ring->qdev; | |
| 1696 | + | |
| 1689 | 1697 | netdev_err(qdev->ndev, "Dumping cqicb stuff...\n"); |
| 1690 | 1698 | |
| 1691 | 1699 | netdev_err(qdev->ndev, "cqicb->msix_vect = %d\n", cqicb->msix_vect); |
| @@ -1725,8 +1733,8 @@ static const char *qlge_rx_ring_type_name(struct rx_ring *rx_ring) · 33 unmodified lines | ||
| 1725 | 1733 | |
| 1726 | 1734 | void ql_dump_rx_ring(struct rx_ring *rx_ring) |
| 1727 | 1735 | { |
| 1728 | − if (!rx_ring) | |
| 1729 | − return; | |
| 1736 | + struct ql_adapter *qdev = rx_ring->qdev; | |
| 1737 | + | |
| 1730 | 1738 | netdev_err(qdev->ndev, |
| 1731 | 1739 | "===================== Dumping rx_ring %d ===============\n", |
| 1732 | 1740 | rx_ring->cq_id); |
| @@ -1816,7 +1824,7 @@ fail_it: · 83 unmodified lines | ||
| 1816 | 1824 | #endif |
| 1817 | 1825 | |
| 1818 | 1826 | #ifdef QL_OB_DUMP |
| 1819 | −void ql_dump_tx_desc(struct tx_buf_desc *tbd) | |
| 1827 | +void ql_dump_tx_desc(struct ql_adapter *qdev, struct tx_buf_desc *tbd) | |
| 1820 | 1828 | { |
| 1821 | 1829 | netdev_err(qdev->ndev, "tbd->addr = 0x%llx\n", |
| 1822 | 1830 | le64_to_cpu((u64)tbd->addr)); |
| @@ -1843,7 +1851,7 @@ void ql_dump_tx_desc(struct tx_buf_desc *tbd) · 20 unmodified lines | ||
| 1843 | 1851 | tbd->len & TX_DESC_E ? "E" : "."); |
| 1844 | 1852 | } |
| 1845 | 1853 | |
| 1846 | −void ql_dump_ob_mac_iocb(struct ob_mac_iocb_req *ob_mac_iocb) | |
| 1854 | +void ql_dump_ob_mac_iocb(struct ql_adapter *qdev, struct ob_mac_iocb_req *ob_mac_iocb) | |
| 1847 | 1855 | { |
| 1848 | 1856 | struct ob_mac_tso_iocb_req *ob_mac_tso_iocb = |
| 1849 | 1857 | (struct ob_mac_tso_iocb_req *)ob_mac_iocb; |
| @@ -1886,10 +1894,10 @@ void ql_dump_ob_mac_iocb(struct ob_mac_iocb_req *ob_mac_iocb) · 36 unmodified lines | ||
| 1886 | 1894 | frame_len = le16_to_cpu(ob_mac_iocb->frame_len); |
| 1887 | 1895 | } |
| 1888 | 1896 | tbd = &ob_mac_iocb->tbd[0]; |
| 1889 | − ql_dump_tx_desc(tbd); | |
| 1897 | + ql_dump_tx_desc(qdev, tbd); | |
| 1890 | 1898 | } |
| 1891 | 1899 | |
| 1892 | −void ql_dump_ob_mac_rsp(struct ob_mac_iocb_rsp *ob_mac_rsp) | |
| 1900 | +void ql_dump_ob_mac_rsp(struct ql_adapter *qdev, struct ob_mac_iocb_rsp *ob_mac_rsp) | |
| 1893 | 1901 | { |
| 1894 | 1902 | netdev_err(qdev->ndev, "%s\n", __func__); |
| 1895 | 1903 | netdev_err(qdev->ndev, "opcode = %d\n", ob_mac_rsp->opcode); |
| @@ -1906,7 +1914,7 @@ void ql_dump_ob_mac_rsp(struct ob_mac_iocb_rsp *ob_mac_rsp) · 10 unmodified lines | ||
| 1906 | 1914 | #endif |
| 1907 | 1915 | |
| 1908 | 1916 | #ifdef QL_IB_DUMP |
| 1909 | −void ql_dump_ib_mac_rsp(struct ib_mac_iocb_rsp *ib_mac_rsp) | |
| 1917 | +void ql_dump_ib_mac_rsp(struct ql_adapter *qdev, struct ib_mac_iocb_rsp *ib_mac_rsp) | |
| 1910 | 1918 | { |
| 1911 | 1919 | netdev_err(qdev->ndev, "%s\n", __func__); |
| 1912 | 1920 | netdev_err(qdev->ndev, "opcode = 0x%x\n", ib_mac_rsp->opcode); |
| @@ -1856,7 +1856,7 @@ static void ql_process_mac_split_rx_intr(struct ql_adapter *qdev, · 1855 unmodified lines | ||
| 1856 | 1856 | struct net_device *ndev = qdev->ndev; |
| 1857 | 1857 | struct sk_buff *skb = NULL; |
| 1858 | 1858 | |
| 1859 | − QL_DUMP_IB_MAC_RSP(ib_mac_rsp); | |
| 1859 | + QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp); | |
| 1860 | 1860 | |
| 1861 | 1861 | skb = ql_build_rx_skb(qdev, rx_ring, ib_mac_rsp); |
| 1862 | 1862 | if (unlikely(!skb)) { |
| @@ -1954,7 +1954,7 @@ static unsigned long ql_process_mac_rx_intr(struct ql_adapter *qdev, · 91 unmodified lines | ||
| 1954 | 1954 | ((le16_to_cpu(ib_mac_rsp->vlan_id) & |
| 1955 | 1955 | IB_MAC_IOCB_RSP_VLAN_MASK)) : 0xffff; |
| 1956 | 1956 | |
| 1957 | − QL_DUMP_IB_MAC_RSP(ib_mac_rsp); | |
| 1957 | + QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp); | |
| 1958 | 1958 | |
| 1959 | 1959 | if (ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HV) { |
| 1960 | 1960 | /* The data and headers are split into |
| @@ -2001,7 +2001,7 @@ static void ql_process_mac_tx_intr(struct ql_adapter *qdev, · 40 unmodified lines | ||
| 2001 | 2001 | struct tx_ring *tx_ring; |
| 2002 | 2002 | struct tx_ring_desc *tx_ring_desc; |
| 2003 | 2003 | |
| 2004 | − QL_DUMP_OB_MAC_RSP(mac_rsp); | |
| 2004 | + QL_DUMP_OB_MAC_RSP(qdev, mac_rsp); | |
| 2005 | 2005 | tx_ring = &qdev->tx_ring[mac_rsp->txq_idx]; |
| 2006 | 2006 | tx_ring_desc = &tx_ring->q[mac_rsp->tid]; |
| 2007 | 2007 | ql_unmap_send(qdev, tx_ring_desc, tx_ring_desc->map_cnt); |
| @@ -2079,9 +2079,9 @@ static void ql_process_chip_ae_intr(struct ql_adapter *qdev, · 71 unmodified lines | ||
| 2079 | 2079 | break; |
| 2080 | 2080 | |
| 2081 | 2081 | case PCI_ERR_ANON_BUF_RD: |
| 2082 | − netdev_err(qdev->ndev, "PCI error occurred when reading " | |
| 2083 | − "anonymous buffers from rx_ring %d.\n", | |
| 2084 | − ib_ae_rsp->q_id); | |
| 2082 | + netdev_err(qdev->ndev, | |
| 2083 | + "PCI error occurred when reading anonymous buffers from rx_ring %d.\n", | |
| 2084 | + ib_ae_rsp->q_id); | |
| 2085 | 2085 | ql_queue_asic_error(qdev); |
| 2086 | 2086 | break; |
| 2087 | 2087 | |
| @@ -2415,8 +2415,7 @@ static irqreturn_t qlge_isr(int irq, void *dev_id) · 327 unmodified lines | ||
| 2415 | 2415 | ql_queue_asic_error(qdev); |
| 2416 | 2416 | netdev_err(qdev->ndev, "Got fatal error, STS = %x.\n", var); |
| 2417 | 2417 | var = ql_read32(qdev, ERR_STS); |
| 2418 | − netdev_err(qdev->ndev, "Resetting chip. " | |
| 2419 | − "Error Status Register = 0x%x\n", var); | |
| 2418 | + netdev_err(qdev->ndev, "Resetting chip. Error Status Register = 0x%x\n", var); | |
| 2420 | 2419 | return IRQ_HANDLED; |
| 2421 | 2420 | } |
| 2422 | 2421 | |
| @@ -2593,7 +2592,7 @@ static netdev_tx_t qlge_send(struct sk_buff *skb, struct net_device *ndev) · 170 unmodified lines | ||
| 2593 | 2592 | tx_ring->tx_errors++; |
| 2594 | 2593 | return NETDEV_TX_BUSY; |
| 2595 | 2594 | } |
| 2596 | − QL_DUMP_OB_MAC_IOCB(mac_iocb_ptr); | |
| 2595 | + QL_DUMP_OB_MAC_IOCB(qdev, mac_iocb_ptr); | |
| 2597 | 2596 | tx_ring->prod_idx++; |
| 2598 | 2597 | if (tx_ring->prod_idx == tx_ring->wq_len) |
| 2599 | 2598 | tx_ring->prod_idx = 0; |
| @@ -3739,8 +3738,7 @@ static void ql_display_dev_info(struct net_device *ndev) · 1139 unmodified lines | ||
| 3739 | 3738 | struct ql_adapter *qdev = netdev_priv(ndev); |
| 3740 | 3739 | |
| 3741 | 3740 | netif_info(qdev, probe, qdev->ndev, |
| 3742 | − "Function #%d, Port %d, NIC Roll %d, NIC Rev = %d, " | |
| 3743 | − "XG Roll = %d, XG Rev = %d.\n", | |
| 3741 | + "Function #%d, Port %d, NIC Roll %d, NIC Rev = %d, XG Roll = %d, XG Rev = %d.\n", | |
| 3744 | 3742 | qdev->func, |
| 3745 | 3743 | qdev->port, |
| 3746 | 3744 | qdev->chip_rev_id & 0x0000000f, |
| @@ -117,7 +117,6 @@ int ql_own_firmware(struct ql_adapter *qdev) · 116 unmodified lines | ||
| 117 | 117 | return 1; |
| 118 | 118 | |
| 119 | 119 | return 0; |
| 120 | − | |
| 121 | 120 | } |
| 122 | 121 | |
| 123 | 122 | static int ql_get_mb_sts(struct ql_adapter *qdev, struct mbox_params *mbcp) |
| @@ -240,12 +239,12 @@ static int ql_idc_cmplt_aen(struct ql_adapter *qdev) · 116 unmodified lines | ||
| 240 | 239 | netif_err(qdev, drv, qdev->ndev, |
| 241 | 240 | "Could not read MPI, resetting RISC!\n"); |
| 242 | 241 | ql_queue_fw_error(qdev); |
| 243 | − } else | |
| 242 | + } else { | |
| 244 | 243 | /* Wake up the sleeping mpi_idc_work thread that is |
| 245 | 244 | * waiting for this event. |
| 246 | 245 | */ |
| 247 | 246 | complete(&qdev->ide_completion); |
| 248 | − | |
| 247 | + } | |
| 249 | 248 | return status; |
| 250 | 249 | } |
| 251 | 250 | |
| @@ -347,16 +346,15 @@ static int ql_aen_lost(struct ql_adapter *qdev, struct mbox_params *mbcp) · 95 unmodified lines | ||
| 347 | 346 | mbcp->out_count = 6; |
| 348 | 347 | |
| 349 | 348 | status = ql_get_mb_sts(qdev, mbcp); |
| 350 | − if (status) | |
| 349 | + if (status) { | |
| 351 | 350 | netif_err(qdev, drv, qdev->ndev, "Lost AEN broken!\n"); |
| 352 | − else { | |
| 351 | + } else { | |
| 353 | 352 | int i; |
| 354 | 353 | |
| 355 | 354 | netif_err(qdev, drv, qdev->ndev, "Lost AEN detected.\n"); |
| 356 | 355 | for (i = 0; i < mbcp->out_count; i++) |
| 357 | 356 | netif_err(qdev, drv, qdev->ndev, "mbox_out[%d] = 0x%.08x.\n", |
| 358 | 357 | i, mbcp->mbox_out[i]); |
| 359 | − | |
| 360 | 358 | } |
| 361 | 359 | |
| 362 | 360 | return status; |
| @@ -405,7 +403,6 @@ static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp) · 42 unmodified lines | ||
| 405 | 403 | } |
| 406 | 404 | |
| 407 | 405 | switch (mbcp->mbox_out[0]) { |
| 408 | − | |
| 409 | 406 | /* This case is only active when we arrive here |
| 410 | 407 | * as a result of issuing a mailbox command to |
| 411 | 408 | * the firmware. |
| @@ -998,9 +995,9 @@ int ql_mb_get_led_cfg(struct ql_adapter *qdev) · 586 unmodified lines | ||
| 998 | 995 | netif_err(qdev, drv, qdev->ndev, |
| 999 | 996 | "Failed to get LED Configuration.\n"); |
| 1000 | 997 | status = -EIO; |
| 1001 | − } else | |
| 998 | + } else { | |
| 1002 | 999 | qdev->led_config = mbcp->mbox_out[1]; |
| 1003 | − | |
| 1000 | + } | |
| 1004 | 1001 | return status; |
| 1005 | 1002 | } |
| 1006 | 1003 | |
| @@ -701,9 +701,9 @@ static void gdma_dma_desc_free(struct virt_dma_desc *vdesc) · 700 unmodified lines | ||
| 701 | 701 | kfree(container_of(vdesc, struct gdma_dma_desc, vdesc)); |
| 702 | 702 | } |
| 703 | 703 | |
| 704 | −static void gdma_dma_tasklet(unsigned long arg) | |
| 704 | +static void gdma_dma_tasklet(struct tasklet_struct *t) | |
| 705 | 705 | { |
| 706 | − struct gdma_dma_dev *dma_dev = (struct gdma_dma_dev *)arg; | |
| 706 | + struct gdma_dma_dev *dma_dev = from_tasklet(dma_dev, t, task); | |
| 707 | 707 | struct gdma_dmaengine_chan *chan; |
| 708 | 708 | static unsigned int last_chan; |
| 709 | 709 | unsigned int i, chan_mask; |
| @@ -821,7 +821,7 @@ static int gdma_dma_probe(struct platform_device *pdev) · 111 unmodified lines | ||
| 821 | 821 | if (IS_ERR(base)) |
| 822 | 822 | return PTR_ERR(base); |
| 823 | 823 | dma_dev->base = base; |
| 824 | − tasklet_init(&dma_dev->task, gdma_dma_tasklet, (unsigned long)dma_dev); | |
| 824 | + tasklet_setup(&dma_dev->task, gdma_dma_tasklet); | |
| 825 | 825 | |
| 826 | 826 | irq = platform_get_irq(pdev, 0); |
| 827 | 827 | if (irq < 0) |
| @@ -422,7 +422,7 @@ static void update_bmc_sta(struct adapter *padapter) · 421 unmodified lines | ||
| 422 | 422 | int i, supportRateNum = 0; |
| 423 | 423 | unsigned int tx_ra_bitmap = 0; |
| 424 | 424 | struct mlme_priv *pmlmepriv = &padapter->mlmepriv; |
| 425 | − struct wlan_bssid_ex *pcur_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network; | |
| 425 | + struct wlan_bssid_ex *pcur_network = &pmlmepriv->cur_network.network; | |
| 426 | 426 | struct sta_info *psta = rtw_get_bcmc_stainfo(padapter); |
| 427 | 427 | |
| 428 | 428 | if (psta) { |
| @@ -599,7 +599,7 @@ static void start_bss_network(struct adapter *padapter, u8 *pbuf) · 170 unmodified lines | ||
| 599 | 599 | struct registry_priv *pregpriv = &padapter->registrypriv; |
| 600 | 600 | struct mlme_priv *pmlmepriv = &padapter->mlmepriv; |
| 601 | 601 | struct security_priv *psecuritypriv = &padapter->securitypriv; |
| 602 | − struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network; | |
| 602 | + struct wlan_bssid_ex *pnetwork = &pmlmepriv->cur_network.network; | |
| 603 | 603 | struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; |
| 604 | 604 | struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; |
| 605 | 605 | struct wlan_bssid_ex *pnetwork_mlmeext = &pmlmeinfo->network; |
| @@ -711,7 +711,7 @@ static void start_bss_network(struct adapter *padapter, u8 *pbuf) · 105 unmodified lines | ||
| 711 | 711 | update_wireless_mode(padapter); |
| 712 | 712 | |
| 713 | 713 | /* update capability after cur_wireless_mode updated */ |
| 714 | − update_capinfo(padapter, rtw_get_capability((struct wlan_bssid_ex *)pnetwork)); | |
| 714 | + update_capinfo(padapter, rtw_get_capability(pnetwork)); | |
| 715 | 715 | |
| 716 | 716 | /* let pnetwork_mlmeext == pnetwork_mlme. */ |
| 717 | 717 | memcpy(pnetwork_mlmeext, pnetwork, pnetwork->Length); |
| @@ -745,7 +745,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) · 27 unmodified lines | ||
| 745 | 745 | struct registry_priv *pregistrypriv = &padapter->registrypriv; |
| 746 | 746 | struct security_priv *psecuritypriv = &padapter->securitypriv; |
| 747 | 747 | struct mlme_priv *pmlmepriv = &padapter->mlmepriv; |
| 748 | − struct wlan_bssid_ex *pbss_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network; | |
| 748 | + struct wlan_bssid_ex *pbss_network = &pmlmepriv->cur_network.network; | |
| 749 | 749 | u8 *ie = pbss_network->ies; |
| 750 | 750 | |
| 751 | 751 | /* SSID */ |
| @@ -982,7 +982,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) · 230 unmodified lines | ||
| 982 | 982 | HT_info_handler(padapter, (struct ndis_802_11_var_ie *)pHT_info_ie); |
| 983 | 983 | } |
| 984 | 984 | |
| 985 | − pbss_network->Length = get_wlan_bssid_ex_sz((struct wlan_bssid_ex *)pbss_network); | |
| 985 | + pbss_network->Length = get_wlan_bssid_ex_sz(pbss_network); | |
| 986 | 986 | |
| 987 | 987 | /* issue beacon to start bss network */ |
| 988 | 988 | start_bss_network(padapter, (u8 *)pbss_network); |
| @@ -159,14 +159,16 @@ int rtw_cmd_thread(void *context) · 158 unmodified lines | ||
| 159 | 159 | if (padapter->bDriverStopped || |
| 160 | 160 | padapter->bSurpriseRemoved) { |
| 161 | 161 | DBG_88E("%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n", |
| 162 | − __func__, padapter->bDriverStopped, padapter->bSurpriseRemoved, __LINE__); | |
| 162 | + __func__, padapter->bDriverStopped, | |
| 163 | + padapter->bSurpriseRemoved, __LINE__); | |
| 163 | 164 | break; |
| 164 | 165 | } |
| 165 | 166 | _next: |
| 166 | 167 | if (padapter->bDriverStopped || |
| 167 | 168 | padapter->bSurpriseRemoved) { |
| 168 | 169 | DBG_88E("%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n", |
| 169 | − __func__, padapter->bDriverStopped, padapter->bSurpriseRemoved, __LINE__); | |
| 170 | + __func__, padapter->bDriverStopped, | |
| 171 | + padapter->bSurpriseRemoved, __LINE__); | |
| 170 | 172 | break; |
| 171 | 173 | } |
| 172 | 174 | |
| @@ -195,14 +197,18 @@ _next: · 22 unmodified lines | ||
| 195 | 197 | if (pcmd->cmdcode < ARRAY_SIZE(rtw_cmd_callback)) { |
| 196 | 198 | pcmd_callback = rtw_cmd_callback[pcmd->cmdcode].callback; |
| 197 | 199 | if (!pcmd_callback) { |
| 198 | − RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("mlme_cmd_hdl(): pcmd_callback = 0x%p, cmdcode = 0x%x\n", pcmd_callback, pcmd->cmdcode)); | |
| 200 | + RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, | |
| 201 | + ("mlme_cmd_hdl(): pcmd_callback = 0x%p, cmdcode = 0x%x\n", | |
| 202 | + pcmd_callback, pcmd->cmdcode)); | |
| 199 | 203 | rtw_free_cmd_obj(pcmd); |
| 200 | 204 | } else { |
| 201 | 205 | /* todo: !!! fill rsp_buf to pcmd->rsp if (pcmd->rsp!= NULL) */ |
| 202 | 206 | pcmd_callback(pcmd->padapter, pcmd);/* need consider that free cmd_obj in rtw_cmd_callback */ |
| 203 | 207 | } |
| 204 | 208 | } else { |
| 205 | − RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("%s: cmdcode = 0x%x callback not defined!\n", __func__, pcmd->cmdcode)); | |
| 209 | + RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, | |
| 210 | + ("%s: cmdcode = 0x%x callback not defined!\n", | |
| 211 | + __func__, pcmd->cmdcode)); | |
| 206 | 212 | rtw_free_cmd_obj(pcmd); |
| 207 | 213 | } |
| 208 | 214 | |
| @@ -264,7 +270,8 @@ u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid, · 55 unmodified lines | ||
| 264 | 270 | |
| 265 | 271 | for (i = 0; i < ssid_num && i < RTW_SSID_SCAN_AMOUNT; i++) { |
| 266 | 272 | if (ssid[i].ssid_length) { |
| 267 | − memcpy(&psurveyPara->ssid[i], &ssid[i], sizeof(struct ndis_802_11_ssid)); | |
| 273 | + memcpy(&psurveyPara->ssid[i], &ssid[i], | |
| 274 | + sizeof(struct ndis_802_11_ssid)); | |
| 268 | 275 | psurveyPara->ssid_num++; |
| 269 | 276 | } |
| 270 | 277 | } |
| @@ -276,7 +283,8 @@ u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid, · 5 unmodified lines | ||
| 276 | 283 | |
| 277 | 284 | for (i = 0; i < ch_num && i < RTW_CHANNEL_SCAN_AMOUNT; i++) { |
| 278 | 285 | if (ch[i].hw_value && !(ch[i].flags & RTW_IEEE80211_CHAN_DISABLED)) { |
| 279 | − memcpy(&psurveyPara->ch[i], &ch[i], sizeof(struct rtw_ieee80211_channel)); | |
| 286 | + memcpy(&psurveyPara->ch[i], &ch[i], | |
| 287 | + sizeof(struct rtw_ieee80211_channel)); | |
| 280 | 288 | psurveyPara->ch_num++; |
| 281 | 289 | } |
| 282 | 290 | } |
| @@ -317,9 +325,11 @@ u8 rtw_createbss_cmd(struct adapter *padapter) · 34 unmodified lines | ||
| 317 | 325 | led_control_8188eu(padapter, LED_CTL_START_TO_LINK); |
| 318 | 326 | |
| 319 | 327 | if (pmlmepriv->assoc_ssid.ssid_length == 0) |
| 320 | − RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, (" createbss for Any SSid:%s\n", pmlmepriv->assoc_ssid.ssid)); | |
| 328 | + RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, | |
| 329 | + (" createbss for Any SSid:%s\n", pmlmepriv->assoc_ssid.ssid)); | |
| 321 | 330 | else |
| 322 | − RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, (" createbss for SSid:%s\n", pmlmepriv->assoc_ssid.ssid)); | |
| 331 | + RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, | |
| 332 | + (" createbss for SSid:%s\n", pmlmepriv->assoc_ssid.ssid)); | |
| 323 | 333 | |
| 324 | 334 | pcmd = kzalloc(sizeof(*pcmd), GFP_ATOMIC); |
| 325 | 335 | if (!pcmd) { |
| @@ -330,7 +340,7 @@ u8 rtw_createbss_cmd(struct adapter *padapter) · 4 unmodified lines | ||
| 330 | 340 | INIT_LIST_HEAD(&pcmd->list); |
| 331 | 341 | pcmd->cmdcode = _CreateBss_CMD_; |
| 332 | 342 | pcmd->parmbuf = (unsigned char *)pdev_network; |
| 333 | − pcmd->cmdsz = get_wlan_bssid_ex_sz((struct wlan_bssid_ex *)pdev_network); | |
| 343 | + pcmd->cmdsz = get_wlan_bssid_ex_sz(pdev_network); | |
| 334 | 344 | pcmd->rsp = NULL; |
| 335 | 345 | pcmd->rspsz = 0; |
| 336 | 346 | pdev_network->Length = pcmd->cmdsz; |
| @@ -361,7 +371,8 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) · 24 unmodified lines | ||
| 361 | 371 | if (pmlmepriv->assoc_ssid.ssid_length == 0) |
| 362 | 372 | RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("+Join cmd: Any SSid\n")); |
| 363 | 373 | else |
| 364 | − RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+Join cmd: SSid =[%s]\n", pmlmepriv->assoc_ssid.ssid)); | |
| 374 | + RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, | |
| 375 | + ("+Join cmd: SSid =[%s]\n", pmlmepriv->assoc_ssid.ssid)); | |
| 365 | 376 | |
| 366 | 377 | pcmd = kzalloc(sizeof(*pcmd), GFP_ATOMIC); |
| 367 | 378 | if (!pcmd) { |
| @@ -387,7 +398,7 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) · 19 unmodified lines | ||
| 387 | 398 | } |
| 388 | 399 | } |
| 389 | 400 | |
| 390 | − psecnetwork = (struct wlan_bssid_ex *)&psecuritypriv->sec_bss; | |
| 401 | + psecnetwork = &psecuritypriv->sec_bss; | |
| 391 | 402 | if (!psecnetwork) { |
| 392 | 403 | kfree(pcmd); |
| 393 | 404 | |
| @@ -406,7 +417,8 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) · 12 unmodified lines | ||
| 406 | 417 | psecuritypriv->authenticator_ie[0] = (unsigned char)psecnetwork->ie_length; |
| 407 | 418 | |
| 408 | 419 | if (psecnetwork->ie_length - 12 < 255) |
| 409 | − memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->ies[12], psecnetwork->ie_length - 12); | |
| 420 | + memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->ies[12], | |
| 421 | + psecnetwork->ie_length - 12); | |
| 410 | 422 | else |
| 411 | 423 | memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->ies[12], 255); |
| 412 | 424 | |
| @@ -419,14 +431,19 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) · 6 unmodified lines | ||
| 419 | 431 | if (!pmlmepriv->assoc_by_bssid) |
| 420 | 432 | memcpy(&pmlmepriv->assoc_bssid[0], &pnetwork->network.MacAddress[0], ETH_ALEN); |
| 421 | 433 | |
| 422 | − psecnetwork->ie_length = rtw_restruct_sec_ie(padapter, &pnetwork->network.ies[0], &psecnetwork->ies[0], pnetwork->network.ie_length); | |
| 434 | + psecnetwork->ie_length = rtw_restruct_sec_ie(padapter, &pnetwork->network.ies[0], | |
| 435 | + &psecnetwork->ies[0], | |
| 436 | + pnetwork->network.ie_length); | |
| 423 | 437 | |
| 424 | 438 | pqospriv->qos_option = 0; |
| 425 | 439 | |
| 426 | 440 | if (pregistrypriv->wmm_enable) { |
| 427 | 441 | u32 tmp_len; |
| 428 | 442 | |
| 429 | − tmp_len = rtw_restruct_wmm_ie(padapter, &pnetwork->network.ies[0], &psecnetwork->ies[0], pnetwork->network.ie_length, psecnetwork->ie_length); | |
| 443 | + tmp_len = rtw_restruct_wmm_ie(padapter, &pnetwork->network.ies[0], | |
| 444 | + &psecnetwork->ies[0], | |
| 445 | + pnetwork->network.ie_length, | |
| 446 | + psecnetwork->ie_length); | |
| 430 | 447 | |
| 431 | 448 | if (psecnetwork->ie_length != tmp_len) { |
| 432 | 449 | psecnetwork->ie_length = tmp_len; |
| @@ -448,7 +465,8 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) · 15 unmodified lines | ||
| 448 | 465 | (padapter->securitypriv.dot11PrivacyAlgrthm != _WEP104_) && |
| 449 | 466 | (padapter->securitypriv.dot11PrivacyAlgrthm != _TKIP_)) { |
| 450 | 467 | /* rtw_restructure_ht_ie */ |
| 451 | − rtw_restructure_ht_ie(padapter, &pnetwork->network.ies[0], &psecnetwork->ies[0], | |
| 468 | + rtw_restructure_ht_ie(padapter, &pnetwork->network.ies[0], | |
| 469 | + &psecnetwork->ies[0], | |
| 452 | 470 | pnetwork->network.ie_length, &psecnetwork->ie_length); |
| 453 | 471 | } |
| 454 | 472 | } |
| @@ -573,7 +591,8 @@ u8 rtw_setstakey_cmd(struct adapter *padapter, u8 *psta, u8 unicast_key) · 118 unmodified lines | ||
| 573 | 591 | if (unicast_key) |
| 574 | 592 | memcpy(&psetstakey_para->key, &sta->dot118021x_UncstKey, 16); |
| 575 | 593 | else |
| 576 | − memcpy(&psetstakey_para->key, &psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey, 16); | |
| 594 | + memcpy(&psetstakey_para->key, | |
| 595 | + &psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey, 16); | |
| 577 | 596 | |
| 578 | 597 | /* jeff: set this because at least sw key is ready */ |
| 579 | 598 | padapter->securitypriv.busetkipkey = true; |
| @@ -760,7 +779,8 @@ static void traffic_status_watchdog(struct adapter *padapter) · 180 unmodified lines | ||
| 760 | 779 | pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 100) { |
| 761 | 780 | bBusyTraffic = true; |
| 762 | 781 | |
| 763 | − if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) | |
| 782 | + if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > | |
| 783 | + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) | |
| 764 | 784 | bRxBusyTraffic = true; |
| 765 | 785 | else |
| 766 | 786 | bTxBusyTraffic = true; |
| @@ -771,7 +791,8 @@ static void traffic_status_watchdog(struct adapter *padapter) · 4 unmodified lines | ||
| 771 | 791 | pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 4000) { |
| 772 | 792 | bHigherBusyTraffic = true; |
| 773 | 793 | |
| 774 | − if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) | |
| 794 | + if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > | |
| 795 | + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) | |
| 775 | 796 | bHigherBusyRxTraffic = true; |
| 776 | 797 | else |
| 777 | 798 | bHigherBusyTxTraffic = true; |
| @@ -1127,7 +1148,8 @@ void rtw_survey_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) · 349 unmodified lines | ||
| 1127 | 1148 | } else if (pcmd->res != H2C_SUCCESS) { |
| 1128 | 1149 | mod_timer(&pmlmepriv->scan_to_timer, |
| 1129 | 1150 | jiffies + msecs_to_jiffies(1)); |
| 1130 | − RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\n ********Error: MgntActrtw_set_802_11_bssid_LIST_SCAN Fail ************\n\n.")); | |
| 1151 | + RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, | |
| 1152 | + ("\n ********Error: MgntActrtw_set_802_11_bssid_LIST_SCAN Fail ************\n\n.")); | |
| 1131 | 1153 | } |
| 1132 | 1154 | |
| 1133 | 1155 | /* free cmd */ |
| @@ -1143,7 +1165,8 @@ void rtw_disassoc_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) · 9 unmodified lines | ||
| 1143 | 1165 | set_fwstate(pmlmepriv, _FW_LINKED); |
| 1144 | 1166 | spin_unlock_bh(&pmlmepriv->lock); |
| 1145 | 1167 | |
| 1146 | − RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\n ***Error: disconnect_cmd_callback Fail ***\n.")); | |
| 1168 | + RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, | |
| 1169 | + ("\n ***Error: disconnect_cmd_callback Fail ***\n.")); | |
| 1147 | 1170 | return; |
| 1148 | 1171 | } |
| 1149 | 1172 | |
| @@ -1161,7 +1184,8 @@ void rtw_joinbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) · 11 unmodified lines | ||
| 1161 | 1184 | mod_timer(&pmlmepriv->assoc_timer, |
| 1162 | 1185 | jiffies + msecs_to_jiffies(1)); |
| 1163 | 1186 | } else if (pcmd->res != H2C_SUCCESS) { |
| 1164 | − RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("********Error:rtw_select_and_join_from_scanned_queue Wait Sema Fail ************\n")); | |
| 1187 | + RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, | |
| 1188 | + ("********Error:rtw_select_and_join_from_scanned_queue Wait Sema Fail ************\n")); | |
| 1165 | 1189 | mod_timer(&pmlmepriv->assoc_timer, |
| 1166 | 1190 | jiffies + msecs_to_jiffies(1)); |
| 1167 | 1191 | } |
| @@ -1193,7 +1217,8 @@ void rtw_createbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) · 25 unmodified lines | ||
| 1193 | 1217 | if (!psta) { |
| 1194 | 1218 | psta = rtw_alloc_stainfo(&padapter->stapriv, pnetwork->MacAddress); |
| 1195 | 1219 | if (!psta) { |
| 1196 | − RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nCan't alloc sta_info when createbss_cmd_callback\n")); | |
| 1220 | + RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, | |
| 1221 | + ("\nCan't alloc sta_info when createbss_cmd_callback\n")); | |
| 1197 | 1222 | goto createbss_cmd_fail; |
| 1198 | 1223 | } |
| 1199 | 1224 | } |
| @@ -1205,7 +1230,8 @@ void rtw_createbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) · 5 unmodified lines | ||
| 1205 | 1230 | if (!pwlan) { |
| 1206 | 1231 | pwlan = rtw_get_oldest_wlan_network(&pmlmepriv->scanned_queue); |
| 1207 | 1232 | if (!pwlan) { |
| 1208 | − RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\n Error: can't get pwlan in rtw_joinbss_event_callback\n")); | |
| 1233 | + RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, | |
| 1234 | + ("\n Error: can't get pwlan in rtw_joinbss_event_callback\n")); | |
| 1209 | 1235 | spin_unlock_bh(&pmlmepriv->scanned_queue.lock); |
| 1210 | 1236 | goto createbss_cmd_fail; |
| 1211 | 1237 | } |
| @@ -1242,7 +1268,8 @@ void rtw_setstaKey_cmdrsp_callback(struct adapter *padapter, struct cmd_obj *pc · 30 unmodified lines | ||
| 1242 | 1268 | struct sta_info *psta = rtw_get_stainfo(pstapriv, psetstakey_rsp->addr); |
| 1243 | 1269 | |
| 1244 | 1270 | if (!psta) { |
| 1245 | − RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nERROR: %s => can't get sta_info\n\n", __func__)); | |
| 1271 | + RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, | |
| 1272 | + ("\nERROR: %s => can't get sta_info\n\n", __func__)); | |
| 1246 | 1273 | goto exit; |
| 1247 | 1274 | } |
| 1248 | 1275 | exit: |
| @@ -1258,7 +1285,8 @@ void rtw_setassocsta_cmdrsp_callback(struct adapter *padapter, struct cmd_obj * · 9 unmodified lines | ||
| 1258 | 1285 | struct sta_info *psta = rtw_get_stainfo(pstapriv, passocsta_parm->addr); |
| 1259 | 1286 | |
| 1260 | 1287 | if (!psta) { |
| 1261 | − RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nERROR: %s => can't get sta_info\n\n", __func__)); | |
| 1288 | + RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, | |
| 1289 | + ("\nERROR: %s => can't get sta_info\n\n", __func__)); | |
| 1262 | 1290 | goto exit; |
| 1263 | 1291 | } |
| 1264 | 1292 | |
| @@ -33,7 +33,7 @@ int proc_set_write_reg(struct file *file, const char __user *buffer, · 32 unmodified lines | ||
| 33 | 33 | unsigned long count, void *data) |
| 34 | 34 | { |
| 35 | 35 | struct net_device *dev = data; |
| 36 | − struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); | |
| 36 | + struct adapter *padapter = rtw_netdev_priv(dev); | |
| 37 | 37 | char tmp[32]; |
| 38 | 38 | u32 addr, val, len; |
| 39 | 39 | |
| @@ -75,7 +75,7 @@ int proc_get_read_reg(char *page, char **start, · 35 unmodified lines | ||
| 75 | 75 | int *eof, void *data) |
| 76 | 76 | { |
| 77 | 77 | struct net_device *dev = data; |
| 78 | − struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); | |
| 78 | + struct adapter *padapter = rtw_netdev_priv(dev); | |
| 79 | 79 | |
| 80 | 80 | int len = 0; |
| 81 | 81 | |
| @@ -135,7 +135,7 @@ int proc_get_adapter_state(char *page, char **start, · 53 unmodified lines | ||
| 135 | 135 | int *eof, void *data) |
| 136 | 136 | { |
| 137 | 137 | struct net_device *dev = data; |
| 138 | − struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); | |
| 138 | + struct adapter *padapter = rtw_netdev_priv(dev); | |
| 139 | 139 | int len = 0; |
| 140 | 140 | |
| 141 | 141 | len += scnprintf(page + len, count - len, "bSurpriseRemoved=%d, bDriverStopped=%d\n", |
| @@ -150,7 +150,7 @@ int proc_get_best_channel(char *page, char **start, · 8 unmodified lines | ||
| 150 | 150 | int *eof, void *data) |
| 151 | 151 | { |
| 152 | 152 | struct net_device *dev = data; |
| 153 | − struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); | |
| 153 | + struct adapter *padapter = rtw_netdev_priv(dev); | |
| 154 | 154 | struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; |
| 155 | 155 | int len = 0; |
| 156 | 156 | u32 i, best_channel_24G = 1, index_24G = 0; |
| @@ -1672,8 +1672,8 @@ static int SecIsInPMKIDList(struct adapter *Adapter, u8 *bssid) · 1671 unmodified lines | ||
| 1672 | 1672 | int i = 0; |
| 1673 | 1673 | |
| 1674 | 1674 | do { |
| 1675 | − if ((psecuritypriv->PMKIDList[i].bUsed) && | |
| 1676 | − (!memcmp(psecuritypriv->PMKIDList[i].Bssid, bssid, ETH_ALEN))) | |
| 1675 | + if ((psecuritypriv->PMKIDList[i].used) && | |
| 1676 | + (!memcmp(psecuritypriv->PMKIDList[i].bssid, bssid, ETH_ALEN))) | |
| 1677 | 1677 | break; |
| 1678 | 1678 | } while (++i < NUM_PMKID_CACHE); |
| 1679 | 1679 | |
| @@ -1730,7 +1730,7 @@ int rtw_restruct_sec_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_ · 50 unmodified lines | ||
| 1730 | 1730 | (ndisauthmode == Ndis802_11AuthModeWPAPSK)) |
| 1731 | 1731 | authmode = _WPA_IE_ID_; |
| 1732 | 1732 | else if ((ndisauthmode == Ndis802_11AuthModeWPA2) || |
| 1733 | − (ndisauthmode == Ndis802_11AuthModeWPA2PSK)) | |
| 1733 | + (ndisauthmode == Ndis802_11AuthModeWPA2PSK)) | |
| 1734 | 1734 | authmode = _WPA2_IE_ID_; |
| 1735 | 1735 | else |
| 1736 | 1736 | authmode = 0x0; |
| @@ -1815,7 +1815,7 @@ void rtw_update_registrypriv_dev_network(struct adapter *adapter) · 78 unmodified lines | ||
| 1815 | 1815 | |
| 1816 | 1816 | sz = rtw_generate_ie(pregistrypriv); |
| 1817 | 1817 | pdev_network->ie_length = sz; |
| 1818 | − pdev_network->Length = get_wlan_bssid_ex_sz((struct wlan_bssid_ex *)pdev_network); | |
| 1818 | + pdev_network->Length = get_wlan_bssid_ex_sz(pdev_network); | |
| 1819 | 1819 | |
| 1820 | 1820 | /* notes: translate ie_length & Length after assign the Length to cmdsz in createbss_cmd(); */ |
| 1821 | 1821 | /* pdev_network->ie_length = cpu_to_le32(sz); */ |
| @@ -1894,9 +1894,9 @@ unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie, u8 *out_ · 72 unmodified lines | ||
| 1894 | 1894 | rtw_hal_get_def_var(padapter, HAL_DEF_MAX_RECVBUF_SZ, &max_recvbuf_sz); |
| 1895 | 1895 | |
| 1896 | 1896 | /* |
| 1897 | − ampdu_params_info [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k | |
| 1898 | − ampdu_params_info [4:2]:Min MPDU Start Spacing | |
| 1899 | − */ | |
| 1897 | + * ampdu_params_info [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k | |
| 1898 | + * ampdu_params_info [4:2]:Min MPDU Start Spacing | |
| 1899 | + */ | |
| 1900 | 1900 | |
| 1901 | 1901 | rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor); |
| 1902 | 1902 | ht_cap.ampdu_params_info = max_rx_ampdu_factor & 0x03; |
| @@ -19,9 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | |
| 20 | 20 | static u8 null_addr[ETH_ALEN] = {}; |
| 21 | 21 | |
| 22 | −/************************************************** | |
| 23 | −OUI definitions for the vendor specific IE | |
| 24 | −***************************************************/ | |
| 22 | +/* OUI definitions for the vendor specific IE */ | |
| 25 | 23 | const u8 RTW_WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01}; |
| 26 | 24 | const u8 WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04}; |
| 27 | 25 | static const u8 WMM_OUI[] = {0x00, 0x50, 0xf2, 0x02}; |
| @@ -32,17 +30,13 @@ static const u8 WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01}; · 4 unmodified lines | ||
| 32 | 30 | const u8 WPA_TKIP_CIPHER[4] = {0x00, 0x50, 0xf2, 0x02}; |
| 33 | 31 | const u8 RSN_TKIP_CIPHER[4] = {0x00, 0x0f, 0xac, 0x02}; |
| 34 | 32 | |
| 35 | −/******************************************************** | |
| 36 | −MCS rate definitions | |
| 37 | −*********************************************************/ | |
| 33 | +/* MCS rate definitions */ | |
| 38 | 34 | const u8 MCS_rate_1R[16] = { |
| 39 | 35 | 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, |
| 40 | 36 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
| 41 | 37 | }; |
| 42 | 38 | |
| 43 | −/******************************************************** | |
| 44 | −ChannelPlan definitions | |
| 45 | −*********************************************************/ | |
| 39 | +/* ChannelPlan definitions */ | |
| 46 | 40 | static struct rt_channel_plan_2g RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = { |
| 47 | 41 | {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, /* 0x00, RT_CHANNEL_DOMAIN_2G_WORLD , Passive scan CH 12, 13 */ |
| 48 | 42 | {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, /* 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1 */ |
| @@ -1777,7 +1771,7 @@ static void issue_action_BSSCoexistPacket(struct adapter *padapter) · 1728 unmodified lines | ||
| 1777 | 1771 | |
| 1778 | 1772 | plist = plist->next; |
| 1779 | 1773 | |
| 1780 | − pbss_network = (struct wlan_bssid_ex *)&pnetwork->network; | |
| 1774 | + pbss_network = &pnetwork->network; | |
| 1781 | 1775 | |
| 1782 | 1776 | p = rtw_get_ie(pbss_network->ies + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->ie_length - _FIXED_IE_LENGTH_); |
| 1783 | 1777 | if (!p || len == 0) { /* non-HT */ |
| @@ -2137,7 +2131,7 @@ static u8 collect_bss_info(struct adapter *padapter, · 353 unmodified lines | ||
| 2137 | 2131 | bssid->Configuration.BeaconPeriod = |
| 2138 | 2132 | get_unaligned_le16(rtw_get_beacon_interval_from_ie(bssid->ies)); |
| 2139 | 2133 | |
| 2140 | − val16 = rtw_get_capability((struct wlan_bssid_ex *)bssid); | |
| 2134 | + val16 = rtw_get_capability(bssid); | |
| 2141 | 2135 | |
| 2142 | 2136 | if (val16 & BIT(0)) { |
| 2143 | 2137 | bssid->InfrastructureMode = Ndis802_11Infrastructure; |
| @@ -2183,7 +2177,7 @@ static void start_create_ibss(struct adapter *padapter) · 39 unmodified lines | ||
| 2183 | 2177 | u8 join_type; |
| 2184 | 2178 | struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; |
| 2185 | 2179 | struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; |
| 2186 | − struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network); | |
| 2180 | + struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network; | |
| 2187 | 2181 | |
| 2188 | 2182 | pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig; |
| 2189 | 2183 | pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork); |
| @@ -2192,7 +2186,7 @@ static void start_create_ibss(struct adapter *padapter) · 2 unmodified lines | ||
| 2192 | 2186 | update_wireless_mode(padapter); |
| 2193 | 2187 | |
| 2194 | 2188 | /* update capability */ |
| 2195 | − caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork); | |
| 2189 | + caps = rtw_get_capability(pnetwork); | |
| 2196 | 2190 | update_capinfo(padapter, caps); |
| 2197 | 2191 | if (caps & cap_IBSS) {/* adhoc master */ |
| 2198 | 2192 | val8 = 0xcf; |
| @@ -2234,7 +2228,7 @@ static void start_clnt_join(struct adapter *padapter) · 35 unmodified lines | ||
| 2234 | 2228 | u8 val8; |
| 2235 | 2229 | struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; |
| 2236 | 2230 | struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; |
| 2237 | − struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network); | |
| 2231 | + struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network; | |
| 2238 | 2232 | int beacon_timeout; |
| 2239 | 2233 | |
| 2240 | 2234 | pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig; |
| @@ -2244,7 +2238,7 @@ static void start_clnt_join(struct adapter *padapter) · 3 unmodified lines | ||
| 2244 | 2238 | update_wireless_mode(padapter); |
| 2245 | 2239 | |
| 2246 | 2240 | /* update capability */ |
| 2247 | − caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork); | |
| 2241 | + caps = rtw_get_capability(pnetwork); | |
| 2248 | 2242 | update_capinfo(padapter, caps); |
| 2249 | 2243 | if (caps & cap_ESS) { |
| 2250 | 2244 | Set_MSR(padapter, WIFI_FW_STATION_STATE); |
| @@ -2599,9 +2593,9 @@ static unsigned int OnBeacon(struct adapter *padapter, · 348 unmodified lines | ||
| 2599 | 2593 | if (psta) { |
| 2600 | 2594 | ret = rtw_check_bcn_info(padapter, pframe, len); |
| 2601 | 2595 | if (!ret) { |
| 2602 | − DBG_88E_LEVEL(_drv_info_, "ap has changed, disconnect now\n "); | |
| 2603 | − receive_disconnect(padapter, pmlmeinfo->network.MacAddress, 65535); | |
| 2604 | − return _SUCCESS; | |
| 2596 | + DBG_88E_LEVEL(_drv_info_, "ap has changed, disconnect now\n "); | |
| 2597 | + receive_disconnect(padapter, pmlmeinfo->network.MacAddress, 65535); | |
| 2598 | + return _SUCCESS; | |
| 2605 | 2599 | } |
| 2606 | 2600 | /* update WMM, ERP in the beacon */ |
| 2607 | 2601 | /* todo: the timer is used instead of the number of the beacon received */ |
| @@ -2929,7 +2923,7 @@ static unsigned int OnAssocReq(struct adapter *padapter, · 321 unmodified lines | ||
| 2929 | 2923 | |
| 2930 | 2924 | pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); |
| 2931 | 2925 | if (!pstat) { |
| 2932 | − status = _RSON_CLS2_; | |
| 2926 | + status = WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA; | |
| 2933 | 2927 | goto asoc_class2_error; |
| 2934 | 2928 | } |
| 2935 | 2929 | |
| @@ -2943,7 +2937,7 @@ static unsigned int OnAssocReq(struct adapter *padapter, · 7 unmodified lines | ||
| 2943 | 2937 | /* check if this stat has been successfully authenticated/assocated */ |
| 2944 | 2938 | if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS)) { |
| 2945 | 2939 | if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS)) { |
| 2946 | − status = _RSON_CLS2_; | |
| 2940 | + status = WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA; | |
| 2947 | 2941 | goto asoc_class2_error; |
| 2948 | 2942 | } else { |
| 2949 | 2943 | pstat->state &= (~WIFI_FW_ASSOC_SUCCESS); |
| @@ -2981,7 +2975,7 @@ static unsigned int OnAssocReq(struct adapter *padapter, · 31 unmodified lines | ||
| 2981 | 2975 | status = _STATS_FAILURE_; |
| 2982 | 2976 | } |
| 2983 | 2977 | |
| 2984 | − if (_STATS_SUCCESSFUL_ != status) | |
| 2978 | + if (status != _STATS_SUCCESSFUL_) | |
| 2985 | 2979 | goto OnAssocReqFail; |
| 2986 | 2980 | |
| 2987 | 2981 | /* check if the supported rate is ok */ |
| @@ -3072,7 +3066,7 @@ static unsigned int OnAssocReq(struct adapter *padapter, · 84 unmodified lines | ||
| 3072 | 3066 | wpa_ie_len = 0; |
| 3073 | 3067 | } |
| 3074 | 3068 | |
| 3075 | − if (_STATS_SUCCESSFUL_ != status) | |
| 3069 | + if (status != _STATS_SUCCESSFUL_) | |
| 3076 | 3070 | goto OnAssocReqFail; |
| 3077 | 3071 | |
| 3078 | 3072 | pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS); |
| @@ -3282,7 +3276,7 @@ static unsigned int OnAssocReq(struct adapter *padapter, · 203 unmodified lines | ||
| 3282 | 3276 | spin_unlock_bh(&pstapriv->asoc_list_lock); |
| 3283 | 3277 | |
| 3284 | 3278 | /* now the station is qualified to join our BSS... */ |
| 3285 | − if ((pstat->state & WIFI_FW_ASSOC_SUCCESS) && (_STATS_SUCCESSFUL_ == status)) { | |
| 3279 | + if ((pstat->state & WIFI_FW_ASSOC_SUCCESS) && (status == _STATS_SUCCESSFUL_)) { | |
| 3286 | 3280 | /* 1 bss_cap_update & sta_info_update */ |
| 3287 | 3281 | bss_cap_update_on_sta_join(padapter, pstat); |
| 3288 | 3282 | sta_info_update(padapter, pstat); |
| @@ -3546,12 +3540,12 @@ static unsigned int on_action_spct(struct adapter *padapter, · 257 unmodified lines | ||
| 3546 | 3540 | |
| 3547 | 3541 | action = frame_body[1]; |
| 3548 | 3542 | switch (action) { |
| 3549 | − case RTW_WLAN_ACTION_SPCT_MSR_REQ: | |
| 3550 | − case RTW_WLAN_ACTION_SPCT_MSR_RPRT: | |
| 3551 | − case RTW_WLAN_ACTION_SPCT_TPC_REQ: | |
| 3552 | − case RTW_WLAN_ACTION_SPCT_TPC_RPRT: | |
| 3543 | + case WLAN_ACTION_SPCT_MSR_REQ: | |
| 3544 | + case WLAN_ACTION_SPCT_MSR_RPRT: | |
| 3545 | + case WLAN_ACTION_SPCT_TPC_REQ: | |
| 3546 | + case WLAN_ACTION_SPCT_TPC_RPRT: | |
| 3553 | 3547 | break; |
| 3554 | − case RTW_WLAN_ACTION_SPCT_CHL_SWITCH: | |
| 3548 | + case WLAN_ACTION_SPCT_CHL_SWITCH: | |
| 3555 | 3549 | break; |
| 3556 | 3550 | default: |
| 3557 | 3551 | break; |
| @@ -4199,7 +4193,7 @@ void report_survey_event(struct adapter *padapter, · 641 unmodified lines | ||
| 4199 | 4193 | |
| 4200 | 4194 | psurvey_evt = (struct survey_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); |
| 4201 | 4195 | |
| 4202 | − if (collect_bss_info(padapter, precv_frame, (struct wlan_bssid_ex *)&psurvey_evt->bss) == _FAIL) { | |
| 4196 | + if (collect_bss_info(padapter, precv_frame, &psurvey_evt->bss) == _FAIL) { | |
| 4203 | 4197 | kfree(pcmd_obj); |
| 4204 | 4198 | kfree(pevtcmd); |
| 4205 | 4199 | return; |
| @@ -4857,7 +4851,7 @@ u8 createbss_hdl(struct adapter *padapter, u8 *pbuf) · 651 unmodified lines | ||
| 4857 | 4851 | { |
| 4858 | 4852 | struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; |
| 4859 | 4853 | struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; |
| 4860 | − struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network); | |
| 4854 | + struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network; | |
| 4861 | 4855 | struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf; |
| 4862 | 4856 | |
| 4863 | 4857 | if (pparm->InfrastructureMode == Ndis802_11APMode) { |
| @@ -4919,7 +4913,7 @@ u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf) · 55 unmodified lines | ||
| 4919 | 4913 | struct registry_priv *pregpriv = &padapter->registrypriv; |
| 4920 | 4914 | struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; |
| 4921 | 4915 | struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; |
| 4922 | − struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network); | |
| 4916 | + struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network; | |
| 4923 | 4917 | struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf; |
| 4924 | 4918 | u32 i; |
| 4925 | 4919 | |
| @@ -5030,7 +5024,7 @@ u8 disconnect_hdl(struct adapter *padapter, unsigned char *pbuf) · 104 unmodified lines | ||
| 5030 | 5024 | struct disconnect_parm *param = (struct disconnect_parm *)pbuf; |
| 5031 | 5025 | struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; |
| 5032 | 5026 | struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; |
| 5033 | − struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network); | |
| 5027 | + struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network; | |
| 5034 | 5028 | u8 val8; |
| 5035 | 5029 | |
| 5036 | 5030 | if (is_client_associated_to_ap(padapter)) |
| @@ -84,7 +84,7 @@ static int rtw_hw_resume(struct adapter *padapter) · 83 unmodified lines | ||
| 84 | 84 | pwrpriv->bips_processing = true; |
| 85 | 85 | rtw_reset_drv_sw(padapter); |
| 86 | 86 | |
| 87 | − if (ips_netdrv_open((struct adapter *)rtw_netdev_priv(pnetdev)) != _SUCCESS) { | |
| 87 | + if (ips_netdrv_open(rtw_netdev_priv(pnetdev)) != _SUCCESS) { | |
| 88 | 88 | mutex_unlock(&pwrpriv->mutex_lock); |
| 89 | 89 | goto error_exit; |
| 90 | 90 | } |
| @@ -530,11 +530,11 @@ void rtw_init_pwrctrl_priv(struct adapter *padapter) · 439 unmodified lines | ||
| 530 | 530 | } |
| 531 | 531 | |
| 532 | 532 | /* |
| 533 | −* rtw_pwr_wakeup - Wake the NIC up from: 1)IPS. 2)USB autosuspend | |
| 534 | −* @adapter: pointer to struct adapter structure | |
| 535 | −* @ips_deffer_ms: the ms will prevent from falling into IPS after wakeup | |
| 536 | −* Return _SUCCESS or _FAIL | |
| 537 | −*/ | |
| 533 | + * rtw_pwr_wakeup - Wake the NIC up from: 1)IPS. 2)USB autosuspend | |
| 534 | + * @adapter: pointer to struct adapter structure | |
| 535 | + * @ips_deffer_ms: the ms will prevent from falling into IPS after wakeup | |
| 536 | + * Return _SUCCESS or _FAIL | |
| 537 | + */ | |
| 538 | 538 | |
| 539 | 539 | int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *caller) |
| 540 | 540 | { |
| @@ -142,7 +142,7 @@ void rtw_wep_encrypt(struct adapter *padapter, struct xmit_frame *pxmitframe) · 141 unmodified lines | ||
| 142 | 142 | struct sk_buff *skb; |
| 143 | 143 | struct lib80211_crypto_ops *crypto_ops; |
| 144 | 144 | |
| 145 | − if (pxmitframe->buf_addr == NULL) | |
| 145 | + if (!pxmitframe->buf_addr) | |
| 146 | 146 | return; |
| 147 | 147 | |
| 148 | 148 | if ((pattrib->encrypt != _WEP40_) && (pattrib->encrypt != _WEP104_)) |
| @@ -371,8 +371,6 @@ void rtw_seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len, u8 *mic_cod · 222 unmodified lines | ||
| 371 | 371 | rtw_secgetmic(&micdata, mic_code); |
| 372 | 372 | } |
| 373 | 373 | |
| 374 | − | |
| 375 | − | |
| 376 | 374 | /* macros for extraction/creation of unsigned char/unsigned short values */ |
| 377 | 375 | #define RotR1(v16) ((((v16) >> 1) & 0x7FFF) ^ (((v16) & 1) << 15)) |
| 378 | 376 | #define Lo8(v16) ((u8)((v16) & 0x00FF)) |
| @@ -591,7 +589,7 @@ u32 rtw_tkip_encrypt(struct adapter *padapter, struct xmit_frame *pxmitframe) · 212 unmodified lines | ||
| 591 | 589 | struct xmit_priv *pxmitpriv = &padapter->xmitpriv; |
| 592 | 590 | u32 res = _SUCCESS; |
| 593 | 591 | |
| 594 | − if (pxmitframe->buf_addr == NULL) | |
| 592 | + if (!pxmitframe->buf_addr) | |
| 595 | 593 | return _FAIL; |
| 596 | 594 | |
| 597 | 595 | hw_hdr_offset = TXDESC_SIZE + |
| @@ -604,7 +602,7 @@ u32 rtw_tkip_encrypt(struct adapter *padapter, struct xmit_frame *pxmitframe) · 6 unmodified lines | ||
| 604 | 602 | else |
| 605 | 603 | stainfo = rtw_get_stainfo(&padapter->stapriv, &pattrib->ra[0]); |
| 606 | 604 | |
| 607 | − if (stainfo != NULL) { | |
| 605 | + if (stainfo) { | |
| 608 | 606 | RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("%s: stainfo!= NULL!!!\n", __func__)); |
| 609 | 607 | |
| 610 | 608 | if (is_multicast_ether_addr(pattrib->ra)) |
| @@ -662,7 +660,6 @@ u32 rtw_tkip_decrypt(struct adapter *padapter, struct recv_frame *precvframe) · 51 unmodified lines | ||
| 662 | 660 | u8 crc[4]; |
| 663 | 661 | struct arc4context mycontext; |
| 664 | 662 | int length; |
| 665 | − | |
| 666 | 663 | u8 *pframe, *payload, *iv, *prwskey; |
| 667 | 664 | union pn48 dot11txpn; |
| 668 | 665 | struct sta_info *stainfo; |
| @@ -670,7 +667,6 @@ u32 rtw_tkip_decrypt(struct adapter *padapter, struct recv_frame *precvframe) · 1 unmodified line | ||
| 670 | 667 | struct security_priv *psecuritypriv = &padapter->securitypriv; |
| 671 | 668 | u32 res = _SUCCESS; |
| 672 | 669 | |
| 673 | − | |
| 674 | 670 | pframe = (unsigned char *)precvframe->pkt->data; |
| 675 | 671 | |
| 676 | 672 | /* 4 start to decrypt recvframe */ |
| @@ -726,553 +722,106 @@ exit: · 49 unmodified lines | ||
| 726 | 722 | return res; |
| 727 | 723 | } |
| 728 | 724 | |
| 729 | −/* 3 ===== AES related ===== */ | |
| 730 | − | |
| 731 | − | |
| 732 | −#define MAX_MSG_SIZE 2048 | |
| 733 | −/*****************************/ | |
| 734 | −/******** SBOX Table *********/ | |
| 735 | −/*****************************/ | |
| 736 | − | |
| 737 | −static const u8 sbox_table[256] = { | |
| 738 | − 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, | |
| 739 | − 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, | |
| 740 | − 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, | |
| 741 | − 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, | |
| 742 | − 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, | |
| 743 | − 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, | |
| 744 | − 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, | |
| 745 | − 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, | |
| 746 | − 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, | |
| 747 | − 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, | |
| 748 | − 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, | |
| 749 | − 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, | |
| 750 | − 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, | |
| 751 | − 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, | |
| 752 | − 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, | |
| 753 | − 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, | |
| 754 | − 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, | |
| 755 | − 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, | |
| 756 | − 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, | |
| 757 | − 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, | |
| 758 | − 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, | |
| 759 | − 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, | |
| 760 | − 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, | |
| 761 | − 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, | |
| 762 | − 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, | |
| 763 | − 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, | |
| 764 | − 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, | |
| 765 | − 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, | |
| 766 | − 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, | |
| 767 | − 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, | |
| 768 | − 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, | |
| 769 | − 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 | |
| 770 | −}; | |
| 771 | − | |
| 772 | −/*****************************/ | |
| 773 | −/**** Function Prototypes ****/ | |
| 774 | −/*****************************/ | |
| 775 | − | |
| 776 | −static void bitwise_xor(u8 *ina, u8 *inb, u8 *out); | |
| 777 | −static void construct_mic_iv(u8 *mic_header1, int qc_exists, int a4_exists, u8 *mpdu, uint payload_length, u8 *pn_vector); | |
| 778 | −static void construct_mic_header1(u8 *mic_header1, int header_length, u8 *mpdu); | |
| 779 | −static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, int a4_exists, int qc_exists); | |
| 780 | −static void construct_ctr_preload(u8 *ctr_preload, int a4_exists, int qc_exists, u8 *mpdu, u8 *pn_vector, int c); | |
| 781 | −static void xor_128(u8 *a, u8 *b, u8 *out); | |
| 782 | −static void xor_32(u8 *a, u8 *b, u8 *out); | |
| 783 | −static u8 sbox(u8 a); | |
| 784 | −static void next_key(u8 *key, int round); | |
| 785 | −static void byte_sub(u8 *in, u8 *out); | |
| 786 | −static void shift_row(u8 *in, u8 *out); | |
| 787 | −static void mix_column(u8 *in, u8 *out); | |
| 788 | −static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext); | |
| 789 | − | |
| 790 | −/****************************************/ | |
| 791 | −/* aes128k128d() */ | |
| 792 | −/* Performs a 128 bit AES encrypt with */ | |
| 793 | −/* 128 bit data. */ | |
| 794 | −/****************************************/ | |
| 795 | −static void xor_128(u8 *a, u8 *b, u8 *out) | |
| 796 | −{ | |
| 797 | − int i; | |
| 798 | − | |
| 799 | − for (i = 0; i < 16; i++) | |
| 800 | − out[i] = a[i] ^ b[i]; | |
| 801 | −} | |
| 802 | − | |
| 803 | −static void xor_32(u8 *a, u8 *b, u8 *out) | |
| 804 | −{ | |
| 805 | − int i; | |
| 806 | − | |
| 807 | − for (i = 0; i < 4; i++) | |
| 808 | − out[i] = a[i] ^ b[i]; | |
| 809 | −} | |
| 810 | − | |
| 811 | −static u8 sbox(u8 a) | |
| 725 | +u32 rtw_aes_encrypt(struct adapter *padapter, struct xmit_frame *pxmitframe) | |
| 812 | 726 | { |
| 813 | − return sbox_table[(int)a]; | |
| 814 | −} | |
| 815 | − | |
| 816 | −static void next_key(u8 *key, int round) | |
| 817 | −{ | |
| 818 | − u8 rcon; | |
| 819 | − u8 sbox_key[4]; | |
| 820 | − static const u8 rcon_table[12] = { | |
| 821 | − 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, | |
| 822 | − 0x1b, 0x36, 0x36, 0x36 | |
| 823 | − }; | |
| 824 | − | |
| 825 | − sbox_key[0] = sbox(key[13]); | |
| 826 | − sbox_key[1] = sbox(key[14]); | |
| 827 | − sbox_key[2] = sbox(key[15]); | |
| 828 | − sbox_key[3] = sbox(key[12]); | |
| 829 | − | |
| 830 | − rcon = rcon_table[round]; | |
| 831 | − | |
| 832 | − xor_32(&key[0], sbox_key, &key[0]); | |
| 833 | − key[0] = key[0] ^ rcon; | |
| 834 | − | |
| 835 | − xor_32(&key[4], &key[0], &key[4]); | |
| 836 | − xor_32(&key[8], &key[4], &key[8]); | |
| 837 | − xor_32(&key[12], &key[8], &key[12]); | |
| 838 | −} | |
| 839 | − | |
| 840 | −static void byte_sub(u8 *in, u8 *out) | |
| 841 | −{ | |
| 842 | − int i; | |
| 843 | − | |
| 844 | − for (i = 0; i < 16; i++) | |
| 845 | − out[i] = sbox(in[i]); | |
| 846 | −} | |
| 847 | − | |
| 848 | −static void shift_row(u8 *in, u8 *out) | |
| 849 | −{ | |
| 850 | − out[0] = in[0]; | |
| 851 | − out[1] = in[5]; | |
| 852 | − out[2] = in[10]; | |
| 853 | − out[3] = in[15]; | |
| 854 | − out[4] = in[4]; | |
| 855 | − out[5] = in[9]; | |
| 856 | − out[6] = in[14]; | |
| 857 | − out[7] = in[3]; | |
| 858 | − out[8] = in[8]; | |
| 859 | − out[9] = in[13]; | |
| 860 | − out[10] = in[2]; | |
| 861 | − out[11] = in[7]; | |
| 862 | − out[12] = in[12]; | |
| 863 | − out[13] = in[1]; | |
| 864 | − out[14] = in[6]; | |
| 865 | − out[15] = in[11]; | |
| 866 | −} | |
| 867 | − | |
| 868 | −static void mix_column(u8 *in, u8 *out) | |
| 869 | −{ | |
| 870 | − int i; | |
| 871 | − u8 add1b[4]; | |
| 872 | − u8 add1bf7[4]; | |
| 873 | − u8 rotl[4]; | |
| 874 | − u8 swap_halves[4]; | |
| 875 | − u8 andf7[4]; | |
| 876 | − u8 rotr[4]; | |
| 877 | − u8 temp[4]; | |
| 878 | − u8 tempb[4]; | |
| 879 | − | |
| 880 | − for (i = 0 ; i < 4; i++) { | |
| 881 | − if ((in[i] & 0x80) == 0x80) | |
| 882 | − add1b[i] = 0x1b; | |
| 883 | − else | |
| 884 | − add1b[i] = 0x00; | |
| 885 | − } | |
| 886 | − | |
| 887 | − swap_halves[0] = in[2]; /* Swap halves */ | |
| 888 | − swap_halves[1] = in[3]; | |
| 889 | − swap_halves[2] = in[0]; | |
| 890 | − swap_halves[3] = in[1]; | |
| 891 | − | |
| 892 | − rotl[0] = in[3]; /* Rotate left 8 bits */ | |
| 893 | − rotl[1] = in[0]; | |
| 894 | − rotl[2] = in[1]; | |
| 895 | − rotl[3] = in[2]; | |
| 896 | − | |
653 more lines aren’t shown here.
This diff is large: its 167 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 203 lines aren’t shown here.
This diff is large: its 140 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 1018 lines aren’t shown here.
This diff is large: its 181 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 158 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 220 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 218 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 90 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 127 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 105 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 101 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 118 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 1553 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 126 lines aren’t shown here.
This diff is large: its 99 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 129 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 173 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 476 lines aren’t shown here.
This diff is large: its 190 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 217 lines aren’t shown here.
This diff is large: its 252 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 217 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 116 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 508 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 106 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.