diff options
182 files changed, 6092 insertions, 2506 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index 5c62bfb0f3f5..c20334454dbf 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -40,6 +40,7 @@ Description: buffered samples and events for device X. What: /sys/bus/iio/devices/iio:deviceX/sampling_frequency +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_sampling_frequency What: /sys/bus/iio/devices/iio:deviceX/buffer/sampling_frequency What: /sys/bus/iio/devices/triggerX/sampling_frequency KernelVersion: 2.6.35 @@ -49,12 +50,13 @@ Description: resulting sampling frequency. In many devices this parameter has an effect on input filters etc. rather than simply controlling when the input is sampled. As this - effects data ready triggers, hardware buffers and the sysfs + affects data ready triggers, hardware buffers and the sysfs direct access interfaces, it may be found in any of the - relevant directories. If it effects all of the above + relevant directories. If it affects all of the above then it is to be found in the base device directory. What: /sys/bus/iio/devices/iio:deviceX/sampling_frequency_available +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_sampling_frequency_available What: /sys/bus/iio/devices/iio:deviceX/in_proximity_sampling_frequency_available What: /sys/.../iio:deviceX/buffer/sampling_frequency_available 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 What: /sys/bus/iio/devices/iio:deviceX/in_illuminance_scale What: /sys/bus/iio/devices/iio:deviceX/in_countY_scale What: /sys/bus/iio/devices/iio:deviceX/in_angl_scale +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_x_scale +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_y_scale +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_z_scale KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: @@ -401,21 +406,21 @@ Description: Hardware applied calibration offset (assumed to fix production inaccuracies). -What /sys/bus/iio/devices/iio:deviceX/in_voltageY_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_voltageY_supply_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_voltageY_i_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_voltageY_q_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_voltage_i_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_voltage_q_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_voltage_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_accel_x_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_accel_y_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_accel_z_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_anglvel_x_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_anglvel_y_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_anglvel_z_calibscale -what /sys/bus/iio/devices/iio:deviceX/in_illuminance0_calibscale -what /sys/bus/iio/devices/iio:deviceX/in_proximity0_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_supply_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_i_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_q_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_voltage_i_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_voltage_q_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_voltage_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_accel_x_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_accel_y_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_accel_z_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_x_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_y_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_z_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_illuminance0_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_proximity0_calibscale What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_calibscale What: /sys/bus/iio/devices/iio:deviceX/in_pressure_calibscale What: /sys/bus/iio/devices/iio:deviceX/in_illuminance_calibscale @@ -483,7 +488,8 @@ Description: If a discrete set of scale values is available, they are listed in this attribute. -What /sys/bus/iio/devices/iio:deviceX/out_voltageY_hardwaregain +What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_hardwaregain +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_hardwaregain What: /sys/bus/iio/devices/iio:deviceX/in_intensity_red_hardwaregain What: /sys/bus/iio/devices/iio:deviceX/in_intensity_green_hardwaregain What: /sys/bus/iio/devices/iio:deviceX/in_intensity_blue_hardwaregain @@ -494,6 +500,13 @@ Description: Hardware applied gain factor. If shared across all channels, <type>_hardwaregain is used. +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_hardwaregain_available +KernelVersion: 5.10 +Contact: linux-iio@vger.kernel.org +Description: + Lists all available hardware applied gain factors. Shared across all + channels. + What: /sys/.../in_accel_filter_low_pass_3db_frequency What: /sys/.../in_magn_filter_low_pass_3db_frequency What: /sys/.../in_anglvel_filter_low_pass_3db_frequency @@ -750,9 +763,9 @@ What: /sys/.../events/in_voltageY_raw_thresh_falling_value What: /sys/.../events/in_tempY_raw_thresh_rising_value What: /sys/.../events/in_tempY_raw_thresh_falling_value What: /sys/.../events/in_illuminance0_thresh_falling_value -what: /sys/.../events/in_illuminance0_thresh_rising_value -what: /sys/.../events/in_proximity0_thresh_falling_value -what: /sys/.../events/in_proximity0_thresh_rising_value +What: /sys/.../events/in_illuminance0_thresh_rising_value +What: /sys/.../events/in_proximity0_thresh_falling_value +What: /sys/.../events/in_proximity0_thresh_rising_value What: /sys/.../events/in_illuminance_thresh_rising_value What: /sys/.../events/in_illuminance_thresh_falling_value KernelVersion: 2.6.37 @@ -832,11 +845,11 @@ What: /sys/.../events/in_tempY_thresh_rising_hysteresis What: /sys/.../events/in_tempY_thresh_falling_hysteresis What: /sys/.../events/in_tempY_thresh_either_hysteresis What: /sys/.../events/in_illuminance0_thresh_falling_hysteresis -what: /sys/.../events/in_illuminance0_thresh_rising_hysteresis -what: /sys/.../events/in_illuminance0_thresh_either_hysteresis -what: /sys/.../events/in_proximity0_thresh_falling_hysteresis -what: /sys/.../events/in_proximity0_thresh_rising_hysteresis -what: /sys/.../events/in_proximity0_thresh_either_hysteresis +What: /sys/.../events/in_illuminance0_thresh_rising_hysteresis +What: /sys/.../events/in_illuminance0_thresh_either_hysteresis +What: /sys/.../events/in_proximity0_thresh_falling_hysteresis +What: /sys/.../events/in_proximity0_thresh_rising_hysteresis +What: /sys/.../events/in_proximity0_thresh_either_hysteresis KernelVersion: 3.13 Contact: linux-iio@vger.kernel.org Description: @@ -1013,7 +1026,7 @@ What: /sys/.../events/in_activity_running_thresh_falling_en KernelVersion: 3.19 Contact: linux-iio@vger.kernel.org Description: - Enables or disables activitity events. Depending on direction + Enables or disables activity events. Depending on direction an event is generated when sensor ENTERS or LEAVES a given state. What: /sys/.../events/in_activity_still_thresh_rising_value @@ -1333,6 +1346,7 @@ Description: standardised CIE Erythemal Action Spectrum. UV index values range from 0 (low) to >=11 (extreme). +What: /sys/.../iio:deviceX/in_intensity_integration_time What: /sys/.../iio:deviceX/in_intensity_red_integration_time What: /sys/.../iio:deviceX/in_intensity_green_integration_time What: /sys/.../iio:deviceX/in_intensity_blue_integration_time @@ -1342,7 +1356,8 @@ KernelVersion: 3.12 Contact: linux-iio@vger.kernel.org Description: This attribute is used to get/set the integration time in - seconds. + seconds. If shared across all channels of a given type, + <type>_integration_time is used. What: /sys/.../iio:deviceX/in_velocity_sqrt(x^2+y^2+z^2)_integration_time KernelVersion: 4.0 @@ -1564,6 +1579,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_concentration_ethanol_raw What: /sys/bus/iio/devices/iio:deviceX/in_concentrationX_ethanol_raw What: /sys/bus/iio/devices/iio:deviceX/in_concentration_h2_raw What: /sys/bus/iio/devices/iio:deviceX/in_concentrationX_h2_raw +What: /sys/bus/iio/devices/iio:deviceX/in_concentration_o2_raw +What: /sys/bus/iio/devices/iio:deviceX/in_concentrationX_o2_raw What: /sys/bus/iio/devices/iio:deviceX/in_concentration_voc_raw What: /sys/bus/iio/devices/iio:deviceX/in_concentrationX_voc_raw KernelVersion: 4.3 @@ -1740,3 +1757,12 @@ KernelVersion: 5.5 Contact: linux-iio@vger.kernel.org Description: One of the following thermocouple types: B, E, J, K, N, R, S, T. + +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_x_raw +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_y_raw +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_z_raw +KernelVersion: 5.10 +Contact: linux-iio@vger.kernel.org +Description: + Unscaled light intensity according to CIE 1931/DIN 5033 color space. + Units after application of scale are nano nanowatts per square meter. diff --git a/Documentation/ABI/testing/sysfs-bus-iio-accel-adxl372 b/Documentation/ABI/testing/sysfs-bus-iio-accel-adxl372 new file mode 100644 index 000000000000..47e34f865ca1 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-accel-adxl372 @@ -0,0 +1,7 @@ +What: /sys/bus/iio/devices/triggerX/name = "adxl372-devX-peak" +KernelVersion: +Contact: linux-iio@vger.kernel.org +Description: + The adxl372 accelerometer kernel module provides an additional trigger, + which sets the device in a mode in which it will record only the peak acceleration + sensed over the set period of time in the events sysfs. diff --git a/Documentation/ABI/testing/sysfs-bus-iio-humidity-hdc2010 b/Documentation/ABI/testing/sysfs-bus-iio-humidity-hdc2010 new file mode 100644 index 000000000000..5b78af5f341d --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-humidity-hdc2010 @@ -0,0 +1,9 @@ +What: /sys/bus/iio/devices/iio:deviceX/out_current_heater_raw +What: /sys/bus/iio/devices/iio:deviceX/out_current_heater_raw_available +KernelVersion: 5.3.8 +Contact: linux-iio@vger.kernel.org +Description: + Controls the heater device within the humidity sensor to get + rid of excess condensation. + + Valid control values are 0 = OFF, and 1 = ON. diff --git a/Documentation/devicetree/bindings/iio/adc/lltc,ltc2497.yaml b/Documentation/devicetree/bindings/iio/adc/lltc,ltc2497.yaml new file mode 100644 index 000000000000..6a176f551d75 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/lltc,ltc2497.yaml @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/lltc,ltc2497.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Linear Technology / Analog Devices LTC2497 ADC + +maintainers: + - Michael Hennerich <michael.hennerich@analog.com> + +description: | + 16bit ADC supporting up to 16 single ended or 8 differential inputs. + I2C interface. + +properties: + compatible: + const: + lltc,ltc2497 + + reg: true + vref-supply: true + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - vref-supply + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + adc@76 { + compatible = "lltc,ltc2497"; + reg = <0x76>; + vref-supply = <<c2497_reg>; + #io-channel-cells = <1>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/ltc2497.txt b/Documentation/devicetree/bindings/iio/adc/ltc2497.txt deleted file mode 100644 index a237ed99c0d8..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/ltc2497.txt +++ /dev/null @@ -1,13 +0,0 @@ -* Linear Technology / Analog Devices LTC2497 ADC - -Required properties: - - compatible: Must be "lltc,ltc2497" - - reg: Must contain the ADC I2C address - - vref-supply: The regulator supply for ADC reference voltage - -Example: - ltc2497: adc@76 { - compatible = "lltc,ltc2497"; - reg = <0x76>; - vref-supply = <<c2497_reg>; - }; diff --git a/Documentation/devicetree/bindings/iio/adc/max11100.txt b/Documentation/devicetree/bindings/iio/adc/max11100.txt deleted file mode 100644 index b7f7177b8aca..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/max11100.txt +++ /dev/null @@ -1,18 +0,0 @@ -* Maxim max11100 Analog to Digital Converter (ADC) - -Required properties: - - compatible: Should be "maxim,max11100" - - reg: the adc unit address - - vref-supply: phandle to the regulator that provides reference voltage - -Optional properties: - - spi-max-frequency: SPI maximum frequency - -Example: - -max11100: adc@0 { - compatible = "maxim,max11100"; - reg = <0>; - vref-supply = <&adc0_vref>; - spi-max-frequency = <240000>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/max1118.txt b/Documentation/devicetree/bindings/iio/adc/max1118.txt deleted file mode 100644 index cf33d0b15a6d..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/max1118.txt +++ /dev/null @@ -1,21 +0,0 @@ -* MAX1117/MAX1118/MAX1119 8-bit, dual-channel ADCs - -Required properties: - - compatible: Should be one of - * "maxim,max1117" - * "maxim,max1118" - * "maxim,max1119" - - reg: spi chip select number for the device - - (max1118 only) vref-supply: The regulator supply for ADC reference voltage - -Recommended properties: - - spi-max-frequency: Definition as per - Documentation/devicetree/bindings/spi/spi-bus.txt - -Example: -adc@0 { - compatible = "maxim,max1118"; - reg = <0>; - vref-supply = <&vdd_supply>; - spi-max-frequency = <1000000>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/max9611.txt b/Documentation/devicetree/bindings/iio/adc/max9611.txt deleted file mode 100644 index ab4f43145ae5..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/max9611.txt +++ /dev/null @@ -1,27 +0,0 @@ -* Maxim max9611/max9612 current sense amplifier with 12-bits ADC interface - -Maxim max9611/max9612 is an high-side current sense amplifier with integrated -12-bits ADC communicating over I2c bus. -The device node for this driver shall be a child of a I2c controller. - -Required properties - - compatible: Should be "maxim,max9611" or "maxim,max9612" - - reg: The 7-bits long I2c address of the device - - shunt-resistor-micro-ohms: Value, in micro Ohms, of the current sense shunt - resistor - -Example: - -&i2c4 { - csa: adc@7c { - compatible = "maxim,max9611"; - reg = <0x7c>; - - shunt-resistor-micro-ohms = <5000>; - }; -}; - -This device node describes a current sense amplifier sitting on I2c4 bus -with address 0x7c (read address is 0xf9, write address is 0xf8). -A sense resistor of 0,005 Ohm is installed between RS+ and RS- current-sensing -inputs. diff --git a/Documentation/devicetree/bindings/iio/adc/maxim,max11100.yaml b/Documentation/devicetree/bindings/iio/adc/maxim,max11100.yaml new file mode 100644 index 000000000000..0cf87556ef82 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/maxim,max11100.yaml @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/maxim,max11100.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Maxim MAX11100 ADC + +maintainers: + - Jacopo Mondi <jacopo@jmondi.org> + +description: | + Single channel 16 bit ADC with SPI interface. + +properties: + compatible: + const: maxim,max11100 + + reg: + maxItems: 1 + + vref-supply: + description: External reference, needed to establish input scaling. + + spi-max-frequency: + minimum: 100000 + maximum: 4800000 + +additionalProperties: false + +required: + - compatible + - reg + - vref-supply + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "maxim,max11100"; + reg = <0>; + vref-supply = <&adc_vref>; + spi-max-frequency = <240000>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/maxim,max1118.yaml b/Documentation/devicetree/bindings/iio/adc/maxim,max1118.yaml new file mode 100644 index 000000000000..e948b3e37b0c --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/maxim,max1118.yaml @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/maxim,max1118.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Maxim MAX1118 and similar ADCs + +maintainers: + - Akinobu Mita <akinobu.mita@gmail.com> + +description: | + Dual channel 8bit ADCs. + +properties: + compatible: + enum: + - maxim,max1117 + - maxim,max1118 + - maxim,max1119 + + reg: + maxItems: 1 + + spi-max-frequency: + maximum: 5000000 + + vref-supply: + description: External reference, needed to establish input scaling + +if: + properties: + compatible: + contains: + const: maxim,max1118 +then: + required: + - vref-supply +else: + properties: + vref-supply: false + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "maxim,max1118"; + reg = <0>; + vref-supply = <&adc_vref>; + spi-max-frequency = <1000000>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/maxim,max9611.yaml b/Documentation/devicetree/bindings/iio/adc/maxim,max9611.yaml new file mode 100644 index 000000000000..9475a9e6e920 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/maxim,max9611.yaml @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/maxim,max9611.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Maxim MAX9611 and similar current sense amplifiers with integrated ADCs + +maintainers: + - Jacopo Mondi <jacopo@jmondi.org> + +description: | + These devices combine a high-side current sense amplifier with a 12 bit ADC. + They have an i2c interface. + +properties: + compatible: + enum: + - maxim,max9611 + - maxim,max9612 + + reg: + maxItems: 1 + + shunt-resistor-micro-ohms: + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + Value in micro Ohms of the shunt resistor connected between the RS+ and + RS- inputs, across which the current is measured. Value needed to compute + the scaling of the measured current. + +additionalProperties: false + +required: + - compatible + - reg + - shunt-resistor-micro-ohms + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + adc@7c { + compatible = "maxim,max9611"; + reg = <0x7c>; + shunt-resistor-micro-ohms = <5000>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/mcp320x.txt b/Documentation/devicetree/bindings/iio/adc/mcp320x.txt deleted file mode 100644 index 56373d643f76..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/mcp320x.txt +++ /dev/null @@ -1,57 +0,0 @@ -* Microchip Analog to Digital Converter (ADC) - -The node for this driver must be a child node of a SPI controller, hence -all mandatory properties described in - - Documentation/devicetree/bindings/spi/spi-bus.txt - -must be specified. - -Required properties: - - compatible: Must be one of the following, depending on the - model: - "mcp3001" (DEPRECATED) - "mcp3002" (DEPRECATED) - "mcp3004" (DEPRECATED) - "mcp3008" (DEPRECATED) - "mcp3201" (DEPRECATED) - "mcp3202" (DEPRECATED) - "mcp3204" (DEPRECATED) - "mcp3208" (DEPRECATED) - "mcp3301" (DEPRECATED) - - "microchip,mcp3001" - "microchip,mcp3002" - "microchip,mcp3004" - "microchip,mcp3008" - "microchip,mcp3201" - "microchip,mcp3202" - "microchip,mcp3204" - "microchip,mcp3208" - "microchip,mcp3301" - "microchip,mcp3550-50" - "microchip,mcp3550-60" - "microchip,mcp3551" - "microchip,mcp3553" - - NOTE: The use of the compatibles with no vendor prefix - is deprecated and only listed because old DT use them. - - - spi-cpha, spi-cpol (boolean): - Either SPI mode (0,0) or (1,1) must be used, so specify - none or both of spi-cpha, spi-cpol. The MCP3550/1/3 - is more efficient in mode (1,1) as only 3 instead of - 4 bytes need to be read from the ADC, but not all SPI - masters support it. - - - vref-supply: Phandle to the external reference voltage supply. - -Examples: -spi_controller { - mcp3x0x@0 { - compatible = "microchip,mcp3002"; - reg = <0>; - spi-max-frequency = <1000000>; - vref-supply = <&vref_reg>; - }; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/mcp3422.txt b/Documentation/devicetree/bindings/iio/adc/mcp3422.txt deleted file mode 100644 index 82bcce07255d..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/mcp3422.txt +++ /dev/null @@ -1,19 +0,0 @@ -* Microchip mcp3421/2/3/4/6/7/8 chip family (ADC) - -Required properties: - - compatible: Should be - "microchip,mcp3421" or - "microchip,mcp3422" or - "microchip,mcp3423" or - "microchip,mcp3424" or - "microchip,mcp3425" or - "microchip,mcp3426" or - "microchip,mcp3427" or - "microchip,mcp3428" - - reg: I2C address for the device - -Example: -adc@0 { - compatible = "microchip,mcp3424"; - reg = <0x68>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/microchip,mcp3201.yaml b/Documentation/devicetree/bindings/iio/adc/microchip,mcp3201.yaml new file mode 100644 index 000000000000..cbbac4ce56d6 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/microchip,mcp3201.yaml @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/microchip,mcp3201.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Microchip mcp3201 and similar ADCs + +maintainers: + - Oskar Andero <oskar.andero@gmail.com> + +description: | + Family of simple ADCs with an I2C inteface. + +properties: + compatible: + enum: + - microchip,mcp3001 + - microchip,mcp3002 + - microchip,mcp3004 + - microchip,mcp3008 + - microchip,mcp3201 + - microchip,mcp3202 + - microchip,mcp3204 + - microchip,mcp3208 + - microchip,mcp3301 + - microchip,mcp3550-50 + - microchip,mcp3550-60 + - microchip,mcp3551 + - microchip,mcp3553 + + reg: + maxItems: 1 + + spi-max-frequency: true + spi-cpha: true + spi-cpol: true + + vref-supply: + description: External reference. + + "#io-channel-cells": + const: 1 + +dependencies: + spi-cpol: [ spi-cpha ] + spi-cpha: [ spi-cpol ] + +required: + - compatible + - reg + - vref-supply + +additionalProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "microchip,mcp3002"; + reg = <0>; + vref-supply = <&vref_reg>; + spi-cpha; + spi-cpol; + #io-channel-cells = <1>; + }; + adc@1 { + compatible = "microchip,mcp3002"; + reg = <1>; + vref-supply = <&vref_reg>; + spi-max-frequency = <1500000>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/ti,adc0832.yaml b/Documentation/devicetree/bindings/iio/adc/ti,adc0832.yaml new file mode 100644 index 000000000000..f5a923cc847f --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti,adc0832.yaml @@ -0,0 +1,56 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/ti,adc0832.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments ADC0832 and similar ADCs + +maintainers: + - Akinobu Mita <akinobu.mita@gmail.com> + +description: | + 8 bit ADCs with 1, 2, 4 or 8 inputs for single ended or differential + conversion. + +properties: + compatible: + enum: + - ti,adc0831 + - ti,adc0832 + - ti,adc0834 + - ti,adc0838 + + reg: + maxItems: 1 + + spi-max-frequency: true + + vref-supply: + description: External reference, needed to establish input scaling + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - vref-supply + +additionalProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "ti,adc0832"; + reg = <0>; + vref-supply = <&vdd_supply>; + spi-max-frequency = <200000>; + #io-channel-cells = <1>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/ti,adc108s102.yaml b/Documentation/devicetree/bindings/iio/adc/ti,adc108s102.yaml new file mode 100644 index 000000000000..54955f03df93 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti,adc108s102.yaml @@ -0,0 +1,47 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/ti,adc108s102.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments ADC108S102 and ADC128S102 + +maintainers: + - Bogdan Pricop <bogdan.pricop@emutex.com> + +description: | + Family of 8 channel, 10/12 bit, SPI, single ended ADCs. + +properties: + compatible: + const: + ti,adc108s102 + + reg: true + vref-supply: true + spi-max-frequency: true + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - vref-supply + +additionalProperties: false + +examples: + - | + spi { + #address-cells= <1>; + #size-cells = <0>; + + adc@0 { + compatible = "ti,adc108s102"; + reg = <0>; + vref-supply = <&vdd_supply>; + spi-max-frequency = <1000000>; + #io-channel-cells = <1>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/ti,adc128s052.yaml b/Documentation/devicetree/bindings/iio/adc/ti,adc128s052.yaml new file mode 100644 index 000000000000..d54a0183f024 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti,adc128s052.yaml @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/ti,adc128s052.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments ADC128S052 and similar ADCs + +maintainers: + - Angelo Compagnucci <angelo.compagnucci@gmail.com> + +description: | + Family of 12 bit SPI ADCs with 2 to 8 channels with a range of different + target sample rates. + +properties: + compatible: + enum: + - ti,adc122s021 + - ti,adc122s051 + - ti,adc122s101 + - ti,adc124s021 + - ti,adc124s051 + - ti,adc124s101 + - ti,adc128s052 + + reg: + maxItems: 1 + + spi-max-frequency: true + + vref-supply: true + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - vref-supply + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "ti,adc128s052"; + reg = <0>; + vref-supply = <&vdd_supply>; + spi-max-frequency = <1000000>; + #io-channel-cells = <1>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/ti,adc161s626.yaml b/Documentation/devicetree/bindings/iio/adc/ti,adc161s626.yaml new file mode 100644 index 000000000000..3f4f334d6f73 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti,adc161s626.yaml @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/ti,adc161s626.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments ADC141S626 and ADC161S626 ADCs + +maintainers: + - Matt Ranostay <matt.ranostay@konsulko.com> + +description: | + Single channel 14/16bit differential ADCs + +properties: + compatible: + enum: + - ti,adc141s626 + - ti,adc161s626 + + reg: + maxItems: 1 + + spi-max-frequency: true + + vdda-supply: true + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "ti,adc161s626"; + vdda-supply = <&vdda_fixed>; + reg = <0>; + spi-max-frequency = <4300000>; + #io-channel-cells = <1>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/ti,ads8344.yaml b/Documentation/devicetree/bindings/iio/adc/ti,ads8344.yaml new file mode 100644 index 000000000000..b8c398187d5c --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti,ads8344.yaml @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/ti,ads8344.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments ADS8344 ADC + +maintainers: + - Gregory Clement <gregory.clement@bootlin.com> + +description: | + 16bit 8-channel ADC with single ended inputs. + +properties: + compatible: + const: ti,ads8344 + + reg: + maxItems: 1 + + spi-max-frequency: true + + vref-supply: + description: Supply the 2.5V or 5V reference voltage + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - vref-supply + +additionalProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "ti,ads8344"; + reg = <0>; + vref-supply = <&refin_supply>; + spi-max-frequency = <10000000>; + #io-channel-cells = <1>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/ti,tlc4541.yaml b/Documentation/devicetree/bindings/iio/adc/ti,tlc4541.yaml new file mode 100644 index 000000000000..6c2539b3d707 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti,tlc4541.yaml @@ -0,0 +1,52 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/ti,tlc4541.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments TLC4541 and similar ADCs + +maintainers: + - Phil Reid <preid@electromag.com.au> + +description: | + 14/16bit single channel ADC with SPI interface. + +properties: + compatible: + enum: + - ti,tlc3541 + - ti,tlc4541 + + reg: + maxItems: 1 + + spi-max-frequency: true + + vref-supply: true + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - vref-supply + +additionalProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "ti,tlc4541"; + reg = <0>; + vref-supply = <&vdd_supply>; + spi-max-frequency = <200000>; + #io-channel-cells = <1>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/ti-adc0832.txt b/Documentation/devicetree/bindings/iio/adc/ti-adc0832.txt deleted file mode 100644 index d91130587d01..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/ti-adc0832.txt +++ /dev/null @@ -1,19 +0,0 @@ -* Texas Instruments' ADC0831/ADC0832/ADC0832/ADC0838 - -Required properties: - - compatible: Should be one of - * "ti,adc0831" - * "ti,adc0832" - * "ti,adc0834" - * "ti,adc0838" - - reg: spi chip select number for the device - - vref-supply: The regulator supply for ADC reference voltage - - spi-max-frequency: Max SPI frequency to use (< 400000) - -Example: -adc@0 { - compatible = "ti,adc0832"; - reg = <0>; - vref-supply = <&vdd_supply>; - spi-max-frequency = <200000>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/ti-adc108s102.txt b/Documentation/devicetree/bindings/iio/adc/ti-adc108s102.txt deleted file mode 100644 index bbbbb4a9f58f..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/ti-adc108s102.txt +++ /dev/null @@ -1,18 +0,0 @@ -* Texas Instruments' ADC108S102 and ADC128S102 ADC chip - -Required properties: - - compatible: Should be "ti,adc108s102" - - reg: spi chip select number for the device - - vref-supply: The regulator supply for ADC reference voltage - -Recommended properties: - - spi-max-frequency: Definition as per - Documentation/devicetree/bindings/spi/spi-bus.txt - -Example: -adc@0 { - compatible = "ti,adc108s102"; - reg = <0>; - vref-supply = <&vdd_supply>; - spi-max-frequency = <1000000>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/ti-adc128s052.txt b/Documentation/devicetree/bindings/iio/adc/ti-adc128s052.txt deleted file mode 100644 index c07ce1a3f5c4..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/ti-adc128s052.txt +++ /dev/null @@ -1,25 +0,0 @@ -* Texas Instruments' ADC128S052, ADC122S021 and ADC124S021 ADC chip - -Required properties: - - compatible: Should be one of: - - "ti,adc128s052" - - "ti,adc122s021" - - "ti,adc122s051" - - "ti,adc122s101" - - "ti,adc124s021" - - "ti,adc124s051" - - "ti,adc124s101" - - reg: spi chip select number for the device - - vref-supply: The regulator supply for ADC reference voltage - -Recommended properties: - - spi-max-frequency: Definition as per - Documentation/devicetree/bindings/spi/spi-bus.txt - -Example: -adc@0 { - compatible = "ti,adc128s052"; - reg = <0>; - vref-supply = <&vdd_supply>; - spi-max-frequency = <1000000>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/ti-adc161s626.txt b/Documentation/devicetree/bindings/iio/adc/ti-adc161s626.txt deleted file mode 100644 index 3d25011f0c99..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/ti-adc161s626.txt +++ /dev/null @@ -1,18 +0,0 @@ -* Texas Instruments ADC141S626 and ADC161S626 chips - -Required properties: - - compatible: Should be "ti,adc141s626" or "ti,adc161s626" - - reg: spi chip select number for the device - - vdda-supply: supply voltage to VDDA pin - -Recommended properties: - - spi-max-frequency: Definition as per - Documentation/devicetree/bindings/spi/spi-bus.txt - -Example: -adc@0 { - compatible = "ti,adc161s626"; - vdda-supply = <&vdda_fixed>; - reg = <0>; - spi-max-frequency = <4300000>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/ti-ads8344.txt b/Documentation/devicetree/bindings/iio/adc/ti-ads8344.txt deleted file mode 100644 index e47c3759a82b..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/ti-ads8344.txt +++ /dev/null @@ -1,19 +0,0 @@ -* Texas Instruments ADS8344 A/DC chip - -Required properties: - - compatible: Must be "ti,ads8344" - - reg: SPI chip select number for the device - - vref-supply: phandle to a regulator node that supplies the - reference voltage - -Recommended properties: - - spi-max-frequency: Definition as per - Documentation/devicetree/bindings/spi/spi-bus.txt - -Example: -adc@0 { - compatible = "ti,ads8344"; - reg = <0>; - vref-supply = <&refin_supply>; - spi-max-frequency = <10000000>; -}; diff --git a/Documentation/devicetree/bindings/iio/chemical/atlas,sensor.yaml b/Documentation/devicetree/bindings/iio/chemical/atlas,sensor.yaml index 9a89b34bdd8f..4646deeb6f7b 100644 --- a/Documentation/devicetree/bindings/iio/chemical/atlas,sensor.yaml +++ b/Documentation/devicetree/bindings/iio/chemical/atlas,sensor.yaml @@ -19,6 +19,8 @@ description: | http://www.atlas-scientific.com/_files/_datasheets/_oem/pH_oem_datasheet.pdf http://www.atlas-scientific.com/_files/_datasheets/_oem/RTD_oem_datasheet.pdf http://www.atlas-scientific.com/_files/_datasheets/_probe/EZO_CO2_Datasheet.pdf + https://www.atlas-scientific.com/files/EZO_O2_datasheet.pdf + https://www.atlas-scientific.com/files/EZO_HUM_Datasheet.pdf properties: compatible: @@ -29,6 +31,8 @@ properties: - atlas,ph-sm - atlas,rtd-sm - atlas,co2-ezo + - atlas,o2-ezo + - atlas,hum-ezo reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/iio/dac/lltc,ltc2632.yaml b/Documentation/devicetree/bindings/iio/dac/lltc,ltc2632.yaml new file mode 100644 index 000000000000..edf804d0aca2 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/dac/lltc,ltc2632.yaml @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/iio/dac/lltc,ltc2632.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Linear Technology LTC263x 12-/10-/8-Bit Rail-to-Rail DAC + +maintainers: + - Michael Hennerich <michael.hennerich@analog.com> + +description: | + Bindings for the Linear Technology LTC2632/2634/2636 DAC + Datasheet can be found here: https://www.analog.com/media/en/technical-documentation/data-sheets/LTC263[246].pdf + +properties: + compatible: + enum: + - lltc,ltc2632-l12 + - lltc,ltc2632-l10 + - lltc,ltc2632-l8 + - lltc,ltc2632-h12 + - lltc,ltc2632-h10 + - lltc,ltc2632-h8 + - lltc,ltc2634-l12 + - lltc,ltc2634-l10 + - lltc,ltc2634-l8 + - lltc,ltc2634-h12 + - lltc,ltc2634-h10 + - lltc,ltc2634-h8 + - lltc,ltc2636-l12 + - lltc,ltc2636-l10 + - lltc,ltc2636-l8 + - lltc,ltc2636-h12 + - lltc,ltc2636-h10 + - lltc,ltc2636-h8 + + reg: + maxItems: 1 + + spi-max-frequency: + maximum: 2000000 + + vref-supply: + description: + Phandle to the external reference voltage supply. This should + only be set if there is an external reference voltage connected to the VREF + pin. If the property is not set the internal reference is used. + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + vref: regulator-vref { + compatible = "regulator-fixed"; + regulator-name = "vref-ltc2632"; + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <1250000>; + regulator-always-on; + }; + + spi { + #address-cells = <1>; + #size-cells = <0>; + + dac@0 { + compatible = "lltc,ltc2632"; + reg = <0>; /* CS0 */ + spi-max-frequency = <1000000>; + vref-supply = <&vref>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/dac/ltc2632.txt b/Documentation/devicetree/bindings/iio/dac/ltc2632.txt deleted file mode 100644 index 1ab9570cf219..000000000000 --- a/Documentation/devicetree/bindings/iio/dac/ltc2632.txt +++ /dev/null @@ -1,49 +0,0 @@ -Linear Technology LTC2632/2634/2636 DAC - -Required properties: - - compatible: Has to contain one of the following: - lltc,ltc2632-l12 - lltc,ltc2632-l10 - lltc,ltc2632-l8 - lltc,ltc2632-h12 - lltc,ltc2632-h10 - lltc,ltc2632-h8 - lltc,ltc2634-l12 - lltc,ltc2634-l10 - lltc,ltc2634-l8 - lltc,ltc2634-h12 - lltc,ltc2634-h10 - lltc,ltc2634-h8 - lltc,ltc2636-l12 - lltc,ltc2636-l10 - lltc,ltc2636-l8 - lltc,ltc2636-h12 - lltc,ltc2636-h10 - lltc,ltc2636-h8 - -Property rules described in Documentation/devicetree/bindings/spi/spi-bus.txt -apply. In particular, "reg" and "spi-max-frequency" properties must be given. - -Optional properties: - - vref-supply: Phandle to the external reference voltage supply. This should - only be set if there is an external reference voltage connected to the VREF - pin. If the property is not set the internal reference is used. - -Example: - - vref: regulator-vref { - compatible = "regulator-fixed"; - regulator-name = "vref-ltc2632"; - regulator-min-microvolt = <1250000>; - regulator-max-microvolt = <1250000>; - regulator-always-on; - }; - - spi_master { - dac: ltc2632@0 { - compatible = "lltc,ltc2632-l12"; - reg = <0>; /* CS0 */ - spi-max-frequency = <1000000>; - vref-supply = <&vref>; /* optional */ - }; - }; diff --git a/Documentation/devicetree/bindings/iio/gyroscope/adi,adxrs290.yaml b/Documentation/devicetree/bindings/iio/gyroscope/adi,adxrs290.yaml new file mode 100644 index 000000000000..61adb2c2454b --- /dev/null +++ b/Documentation/devicetree/bindings/iio/gyroscope/adi,adxrs290.yaml @@ -0,0 +1,53 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +# Copyright 2020 Analog Devices Inc. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/gyroscope/adi,adxrs290.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices ADXRS290 Dual-Axis MEMS Gyroscope + +maintainers: + - Nishant Malpani <nish.malpani25@gmail.com> + +description: | + Bindings for the Analog Devices ADXRS290 dual-axis MEMS gyroscope device. + https://www.analog.com/media/en/technical-documentation/data-sheets/ADXRS290.pdf + +properties: + compatible: + const: adi,adxrs290 + + reg: + maxItems: 1 + + spi-max-frequency: + maximum: 5000000 + + spi-cpol: true + + spi-cpha: true + +required: + - compatible + - reg + - spi-max-frequency + - spi-cpol + - spi-cpha + +additionalProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + gyro@0 { + compatible = "adi,adxrs290"; + reg = <0>; + spi-max-frequency = <5000000>; + spi-cpol; + spi-cpha; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/humidity/ti,hdc2010.yaml b/Documentation/devicetree/bindings/iio/humidity/ti,hdc2010.yaml new file mode 100644 index 000000000000..dc870eb2875f --- /dev/null +++ b/Documentation/devicetree/bindings/iio/humidity/ti,hdc2010.yaml @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/humidity/ti,hdc2010.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: HDC2010/HDC2080 humidity and temperature iio sensors + +maintainers: + - Eugene Zaikonnikov <ez@norophonic.com> + +description: | + Relative humidity and tempereature sensors on I2C bus + + Datasheets are available at: + http://www.ti.com/product/HDC2010/datasheet + http://www.ti.com/product/HDC2080/datasheet + +properties: + compatible: + enum: + - ti,hdc2010 + - ti,hdc2080 + + vdd-supply: + maxItems: 1 + + reg: + maxItems: 1 + +required: + - compatible + - reg + +examples: + - | + i2c0 { + #address-cells = <1>; + #size-cells = <0>; + + humidity@40 { + compatible = "ti,hdc2010"; + reg = <0x40>; + }; + }; diff --git a/Documentation/devicetree/bindings/iio/light/ams,as73211.yaml b/Documentation/devicetree/bindings/iio/light/ams,as73211.yaml new file mode 100644 index 000000000000..0e8cd02759b3 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/light/ams,as73211.yaml @@ -0,0 +1,54 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/light/ams,as73211.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: AMS AS73211 JENCOLOR(R) Digital XYZ Sensor + +maintainers: + - Christian Eggers <ceggers@arri.de> + +description: | + XYZ True Color Sensor with I2C Interface + https://ams.com/documents/20143/36005/AS73211_DS000556_3-01.pdf/a65474c0-b302-c2fd-e30a-c98df87616df + +properties: + compatible: + enum: + - ams,as73211 + + reg: + description: + I2C address of the device (0x74...0x77). + maxItems: 1 + + interrupts: + description: + Interrupt specifier for the READY interrupt generated by the device. + maxItems: 1 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + as73211@74 { + compatible = "ams,as73211"; + reg = <0x74>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_color_sensor>; + interrupt-parent = <&gpio2>; + interrupts = <19 IRQ_TYPE_EDGE_RISING>; /* READY */ + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/proximity/semtech,sx9310.yaml b/Documentation/devicetree/bindings/iio/proximity/semtech,sx9310.yaml new file mode 100644 index 000000000000..5739074d3592 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/proximity/semtech,sx9310.yaml @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/proximity/semtech,sx9310.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Semtech's SX9310 capacitive proximity sensor + +maintainers: + - Daniel Campello <campello@chromium.org> + +description: | + Semtech's SX9310/SX9311 capacitive proximity/button solution. + + Specifications about the devices can be found at: + https://www.semtech.com/products/smart-sensing/sar-sensors/sx9310 + +properties: + compatible: + enum: + - semtech,sx9310 + - semtech,sx9311 + + reg: + maxItems: 1 + + interrupts: + description: + The sole interrupt generated by the device used to announce the + preceding reading request has finished and that data is + available or that a close/far proximity event has happened. + maxItems: 1 + + vdd-supply: + description: Main power supply + + svdd-supply: + description: Host interface power supply + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - "#io-channel-cells" + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + i2c { + #address-cells = <1>; + #size-cells = <0>; + proximity@28 { + compatible = "semtech,sx9310"; + reg = <0x28>; + interrupt-parent = <&pio>; + interrupts = <5 IRQ_TYPE_LEVEL_LOW 5>; + vdd-supply = <&pp3300_a>; + svdd-supply = <&pp1800_prox>; + #io-channel-cells = <1>; + }; + }; diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml b/Documentation/devicetree/bindings/trivial-devices.yaml index 4ace8039840a..25cfcc904240 100644 --- a/Documentation/devicetree/bindings/trivial-devices.yaml +++ b/Documentation/devicetree/bindings/trivial-devices.yaml @@ -128,6 +128,22 @@ properties: - mcube,mc3230 # MEMSIC 2-axis 8-bit digital accelerometer - memsic,mxc6225 + # Microchip differential I2C ADC, 1 Channel, 18 bit + - microchip,mcp3421 + # Microchip differential I2C ADC, 2 Channel, 18 bit + - microchip,mcp3422 + # Microchip differential I2C ADC, 2 Channel, 18 bit + - microchip,mcp3423 + # Microchip differential I2C ADC, 4 Channel, 18 bit + - microchip,mcp3424 + # Microchip differential I2C ADC, 1 Channel, 16 bit + - microchip,mcp3425 + # Microchip differential I2C ADC, 2 Channel, 16 bit + - microchip,mcp3426 + # Microchip differential I2C ADC, 2 Channel, 16 bit + - microchip,mcp3427 + # Microchip differential I2C ADC, 4 Channel, 16 bit + - microchip,mcp3428 # Microchip 7-bit Single I2C Digital POT (5k) - microchip,mcp4017-502 # Microchip 7-bit Single I2C Digital POT (10k) diff --git a/MAINTAINERS b/MAINTAINERS index 0d0862b19ce5..311f705d72d4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -943,6 +943,13 @@ S: Supported F: arch/arm64/boot/dts/amd/amd-seattle-xgbe*.dtsi F: drivers/net/ethernet/amd/xgbe/ +AMS AS73211 DRIVER +M: Christian Eggers <ceggers@arri.de> +L: linux-iio@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/iio/light/ams,as73211.yaml +F: drivers/iio/light/as73211.c + ANALOG DEVICES INC AD5686 DRIVER M: Michael Hennerich <Michael.Hennerich@analog.com> L: linux-pm@vger.kernel.org @@ -1108,6 +1115,13 @@ L: linux-media@vger.kernel.org S: Maintained F: drivers/media/i2c/adv7842* +ANALOG DEVICES INC ADXRS290 DRIVER +M: Nishant Malpani <nish.malpani25@gmail.com> +L: linux-iio@vger.kernel.org +S: Supported +F: drivers/iio/gyro/adxrs290.c +F: Documentation/devicetree/bindings/iio/gyroscope/adi,adxrs290.yaml + ANALOG DEVICES INC ASOC CODEC DRIVERS M: Lars-Peter Clausen <lars@metafoo.de> M: Nuno Sá <nuno.sa@analog.com> @@ -7928,6 +7942,12 @@ F: drivers/crypto/hisilicon/sec2/sec_crypto.c F: drivers/crypto/hisilicon/sec2/sec_crypto.h F: drivers/crypto/hisilicon/sec2/sec_main.c +HISILICON STAGING DRIVERS FOR HIKEY 960/970 +M: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +L: devel@driverdev.osuosl.org +S: Maintained +F: drivers/staging/hikey9xx/ + HISILICON TRUE RANDOM NUMBER GENERATOR V2 SUPPORT M: Zaibo Xu <xuzaibo@huawei.com> S: Maintained diff --git a/drivers/iio/accel/adxl372.c b/drivers/iio/accel/adxl372.c index e7e316b75e87..aed2a4930fb0 100644 --- a/drivers/iio/accel/adxl372.c +++ b/drivers/iio/accel/adxl372.c @@ -5,6 +5,7 @@ * Copyright 2018 Analog Devices Inc. */ +#include <linux/bitfield.h> #include <linux/bitops.h> #include <linux/interrupt.h> #include <linux/irq.h> @@ -113,6 +114,11 @@ #define ADXL372_STATUS_1_AWAKE(x) (((x) >> 6) & 0x1) #define ADXL372_STATUS_1_ERR_USR_REGS(x) (((x) >> 7) & 0x1) +/* ADXL372_STATUS_2 */ +#define ADXL372_STATUS_2_INACT(x) (((x) >> 4) & 0x1) +#define ADXL372_STATUS_2_ACT(x) (((x) >> 5) & 0x1) +#define ADXL372_STATUS_2_AC2(x) (((x) >> 6) & 0x1) + /* ADXL372_INT1_MAP */ #define ADXL372_INT1_MAP_DATA_RDY_MSK BIT(0) #define ADXL372_INT1_MAP_DATA_RDY_MODE(x) (((x) & 0x1) << 0) @@ -131,8 +137,17 @@ #define ADXL372_INT1_MAP_LOW_MSK BIT(7) #define ADXL372_INT1_MAP_LOW_MODE(x) (((x) & 0x1) << 7) +/* ADX372_THRESH */ +#define ADXL372_THRESH_VAL_H_MSK GENMASK(10, 3) +#define ADXL372_THRESH_VAL_H_SEL(x) FIELD_GET(ADXL372_THRESH_VAL_H_MSK, x) +#define ADXL372_THRESH_VAL_L_MSK GENMASK(2, 0) +#define ADXL372_THRESH_VAL_L_SEL(x) FIELD_GET(ADXL372_THRESH_VAL_L_MSK, x) + /* The ADXL372 includes a deep, 512 sample FIFO buffer */ #define ADXL372_FIFO_SIZE 512 +#define ADXL372_X_AXIS_EN(x) ((x) & BIT(0)) +#define ADXL372_Y_AXIS_EN(x) ((x) & BIT(1)) +#define ADXL372_Z_AXIS_EN(x) ((x) & BIT(2)) /* * At +/- 200g with 12-bit resolution, scale is computed as: @@ -222,6 +237,20 @@ static const struct adxl372_axis_lookup adxl372_axis_lookup_table[] = { { BIT(0) | BIT(1) | BIT(2), ADXL372_XYZ_FIFO }, }; +static const struct iio_event_spec adxl372_events[] = { + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_RISING, + .mask_separate = BIT(IIO_EV_INFO_VALUE), + .mask_shared_by_all = BIT(IIO_EV_INFO_PERIOD) | BIT(IIO_EV_INFO_ENABLE), + }, { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_FALLING, + .mask_separate = BIT(IIO_EV_INFO_VALUE), + .mask_shared_by_all = BIT(IIO_EV_INFO_PERIOD) | BIT(IIO_EV_INFO_ENABLE), + }, +}; + #define ADXL372_ACCEL_CHANNEL(index, reg, axis) { \ .type = IIO_ACCEL, \ .address = reg, \ @@ -239,6 +268,8 @@ static const struct adxl372_axis_lookup adxl372_axis_lookup_table[] = { .shift = 4, \ .endianness = IIO_BE, \ }, \ + .event_spec = adxl372_events, \ + .num_event_specs = ARRAY_SIZE(adxl372_events) \ } static const struct iio_chan_spec adxl372_channels[] = { @@ -252,8 +283,10 @@ struct adxl372_state { struct device *dev; struct regmap *regmap; struct iio_trigger *dready_trig; + struct iio_trigger *peak_datardy_trig; enum adxl372_fifo_mode fifo_mode; enum adxl372_fifo_format fifo_format; + unsigned int fifo_axis_mask; enum adxl372_op_mode op_mode; enum adxl372_act_proc_mode act_proc_mode; enum adxl372_odr odr; @@ -261,10 +294,12 @@ struct adxl372_state { u32 act_time_ms; u32 inact_time_ms; u8 fifo_set_size; - u8 int1_bitmask; - u8 int2_bitmask; + unsigned long int1_bitmask; + unsigned long int2_bitmask; u16 watermark; __be16 fifo_buf[ADXL372_FIFO_SIZE]; + bool peak_fifo_mode_en; + struct mutex threshold_m; /* lock for threshold */ }; static const unsigned long adxl372_channel_masks[] = { @@ -276,6 +311,46 @@ static const unsigned long adxl372_channel_masks[] = { 0 }; +static ssize_t adxl372_read_threshold_value(struct iio_dev *indio_dev, unsigned int addr, + u16 *threshold) +{ + struct adxl372_state *st = iio_priv(indio_dev); + __be16 raw_regval; + u16 regval; + int ret; + + ret = regmap_bulk_read(st->regmap, addr, &raw_regval, sizeof(raw_regval)); + if (ret < 0) + return ret; + + regval = be16_to_cpu(raw_regval); + regval >>= 5; + + *threshold = regval; + + return 0; +} + +static ssize_t adxl372_write_threshold_value(struct iio_dev *indio_dev, unsigned int addr, + u16 threshold) +{ + struct adxl372_state *st = iio_priv(indio_dev); + int ret; + + mutex_lock(&st->threshold_m); + ret = regmap_write(st->regmap, addr, ADXL372_THRESH_VAL_H_SEL(threshold)); + if (ret < 0) + goto unlock; + + ret = regmap_update_bits(st->regmap, addr + 1, GENMASK(7, 5), + ADXL372_THRESH_VAL_L_SEL(threshold) << 5); + +unlock: + mutex_unlock(&st->threshold_m); + + return ret; +} + static int adxl372_read_axis(struct adxl372_state *st, u8 addr) { __be16 regval; @@ -453,8 +528,8 @@ static int adxl372_set_inactivity_time_ms(struct adxl372_state *st, } static int adxl372_set_interrupts(struct adxl372_state *st, - unsigned char int1_bitmask, - unsigned char int2_bitmask) + unsigned long int1_bitmask, + unsigned long int2_bitmask) { int ret; @@ -523,6 +598,39 @@ static int adxl372_get_status(struct adxl372_state *st, return ret; } +static void adxl372_arrange_axis_data(struct adxl372_state *st, __be16 *sample) +{ + __be16 axis_sample[3]; + int i = 0; + + memset(axis_sample, 0, 3 * sizeof(__be16)); + if (ADXL372_X_AXIS_EN(st->fifo_axis_mask)) + axis_sample[i++] = sample[0]; + if (ADXL372_Y_AXIS_EN(st->fifo_axis_mask)) + axis_sample[i++] = sample[1]; + if (ADXL372_Z_AXIS_EN(st->fifo_axis_mask)) + axis_sample[i++] = sample[2]; + + memcpy(sample, axis_sample, 3 * sizeof(__be16)); +} + +static void adxl372_push_event(struct iio_dev *indio_dev, s64 timestamp, u8 status2) +{ + unsigned int ev_dir = IIO_EV_DIR_NONE; + + if (ADXL372_STATUS_2_ACT(status2)) + ev_dir = IIO_EV_DIR_RISING; + + if (ADXL372_STATUS_2_INACT(status2)) + ev_dir = IIO_EV_DIR_FALLING; + + if (ev_dir != IIO_EV_DIR_NONE) + iio_push_event(indio_dev, + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_X_OR_Y_OR_Z, + IIO_EV_TYPE_THRESH, ev_dir), + timestamp); +} + static irqreturn_t adxl372_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; @@ -536,6 +644,8 @@ static irqreturn_t adxl372_trigger_handler(int irq, void *p) if (ret < 0) goto err; + adxl372_push_event(indio_dev, iio_get_time_ns(indio_dev), status2); + if (st->fifo_mode != ADXL372_FIFO_BYPASSED && ADXL372_STATUS_1_FIFO_FULL(status1)) { /* @@ -554,8 +664,12 @@ static irqreturn_t adxl372_trigger_handler(int irq, void *p) goto err; /* Each sample is 2 bytes */ - for (i = 0; i < fifo_entries; i += st->fifo_set_size) + for (i = 0; i < fifo_entries; i += st->fifo_set_size) { + /* filter peak detection data */ + if (st->peak_fifo_mode_en) + adxl372_arrange_axis_data(st, &st->fifo_buf[i]); iio_push_to_buffers(indio_dev, &st->fifo_buf[i]); + } } err: iio_trigger_notify_done(indio_dev->trig); @@ -723,6 +837,129 @@ static int adxl372_write_raw(struct iio_dev *indio_dev, } } +static int adxl372_read_event_value(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, + enum iio_event_type type, enum iio_event_direction dir, + enum iio_event_info info, int *val, int *val2) +{ + struct adxl372_state *st = iio_priv(indio_dev); + unsigned int addr; + u16 raw_value; + int ret; + + switch (info) { + case IIO_EV_INFO_VALUE: + switch (dir) { + case IIO_EV_DIR_RISING: + addr = ADXL372_X_THRESH_ACT_H + 2 * chan->scan_index; + ret = adxl372_read_threshold_value(indio_dev, addr, &raw_value); + if (ret < 0) + return ret; + *val = raw_value * ADXL372_USCALE; + *val2 = 1000000; + return IIO_VAL_FRACTIONAL; + case IIO_EV_DIR_FALLING: + addr = ADXL372_X_THRESH_INACT_H + 2 * chan->scan_index; + ret = adxl372_read_threshold_value(indio_dev, addr, &raw_value); + if (ret < 0) + return ret; + *val = raw_value * ADXL372_USCALE; + *val2 = 1000000; + return IIO_VAL_FRACTIONAL; + default: + return -EINVAL; + } + case IIO_EV_INFO_PERIOD: + switch (dir) { + case IIO_EV_DIR_RISING: + *val = st->act_time_ms; + *val2 = 1000; + return IIO_VAL_FRACTIONAL; + case IIO_EV_DIR_FALLING: + *val = st->inact_time_ms; + *val2 = 1000; + return IIO_VAL_FRACTIONAL; + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + +static int adxl372_write_event_value(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, + enum iio_event_type type, enum iio_event_direction dir, + enum iio_event_info info, int val, int val2) +{ + struct adxl372_state *st = iio_priv(indio_dev); + unsigned int val_ms; + unsigned int addr; + u16 raw_val; + + switch (info) { + case IIO_EV_INFO_VALUE: + raw_val = DIV_ROUND_UP(val * 1000000, ADXL372_USCALE); + switch (dir) { + case IIO_EV_DIR_RISING: + addr = ADXL372_X_THRESH_ACT_H + 2 * chan->scan_index; + return adxl372_write_threshold_value(indio_dev, addr, raw_val); + case IIO_EV_DIR_FALLING: + addr = ADXL372_X_THRESH_INACT_H + 2 * chan->scan_index; + return adxl372_write_threshold_value(indio_dev, addr, raw_val); + default: + return -EINVAL; + } + case IIO_EV_INFO_PERIOD: + val_ms = val * 1000 + DIV_ROUND_UP(val2, 1000); + switch (dir) { + case IIO_EV_DIR_RISING: + return adxl372_set_activity_time_ms(st, val_ms); + case IIO_EV_DIR_FALLING: + return adxl372_set_inactivity_time_ms(st, val_ms); + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + +static int adxl372_read_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, + enum iio_event_type type, enum iio_event_direction dir) +{ + struct adxl372_state *st = iio_priv(indio_dev); + + switch (dir) { + case IIO_EV_DIR_RISING: + return FIELD_GET(ADXL372_INT1_MAP_ACT_MSK, st->int1_bitmask); + case IIO_EV_DIR_FALLING: + return FIELD_GET(ADXL372_INT1_MAP_INACT_MSK, st->int1_bitmask); + default: + return -EINVAL; + } +} + +static int adxl372_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, + enum iio_event_type type, enum iio_event_direction dir, + int state) +{ + struct adxl372_state *st = iio_priv(indio_dev); + + switch (dir) { + case IIO_EV_DIR_RISING: + set_mask_bits(&st->int1_bitmask, ADXL372_INT1_MAP_ACT_MSK, + ADXL372_INT1_MAP_ACT_MODE(state)); + break; + case IIO_EV_DIR_FALLING: + set_mask_bits(&st->int1_bitmask, ADXL372_INT1_MAP_INACT_MSK, + ADXL372_INT1_MAP_INACT_MODE(state)); + break; + default: + return -EINVAL; + } + + return adxl372_set_interrupts(st, st->int1_bitmask, 0); +} + static ssize_t adxl372_show_filter_freq_avail(struct device *dev, struct device_attribute *attr, char *buf) @@ -795,7 +1032,8 @@ static int adxl372_buffer_postenable(struct iio_dev *indio_dev) unsigned int mask; int i, ret; - ret = adxl372_set_interrupts(st, ADXL372_INT1_MAP_FIFO_FULL_MSK, 0); + st->int1_bitmask |= ADXL372_INT1_MAP_FIFO_FULL_MSK; + ret = adxl372_set_interrupts(st, st->int1_bitmask, 0); if (ret < 0) return ret; @@ -810,13 +1048,22 @@ static int adxl372_buffer_postenable(struct iio_dev *indio_dev) return -EINVAL; st->fifo_format = adxl372_axis_lookup_table[i].fifo_format; + st->fifo_axis_mask = adxl372_axis_lookup_table[i].bits; st->fifo_set_size = bitmap_weight(indio_dev->active_scan_mask, indio_dev->masklength); + + /* Configure the FIFO to store sets of impact event peak. */ + if (st->peak_fifo_mode_en) { + st->fifo_set_size = 3; + st->fifo_format = ADXL372_XYZ_PEAK_FIFO; + } + /* * The 512 FIFO samples can be allotted in several ways, such as: * 170 sample sets of concurrent 3-axis data * 256 sample sets of concurrent 2-axis data (user selectable) * 512 sample sets of single-axis data + * 170 sets of impact event peak (x, y, z) */ if ((st->watermark * st->fifo_set_size) > ADXL372_FIFO_SIZE) st->watermark = (ADXL372_FIFO_SIZE / st->fifo_set_size); @@ -826,7 +1073,8 @@ static int adxl372_buffer_postenable(struct iio_dev *indio_dev) ret = adxl372_configure_fifo(st); if (ret < 0) { st->fifo_mode = ADXL372_FIFO_BYPASSED; - adxl372_set_interrupts(st, 0, 0); + st->int1_bitmask &= ~ADXL372_INT1_MAP_FIFO_FULL_MSK; + adxl372_set_interrupts(st, st->int1_bitmask, 0); return ret; } @@ -837,7 +1085,8 @@ static int adxl372_buffer_predisable(struct iio_dev *indio_dev) { struct adxl372_state *st = iio_priv(indio_dev); - adxl372_set_interrupts(st, 0, 0); + st->int1_bitmask &= ~ADXL372_INT1_MAP_FIFO_FULL_MSK; + adxl372_set_interrupts(st, st->int1_bitmask, 0); st->fifo_mode = ADXL372_FIFO_BYPASSED; adxl372_configure_fifo(st); @@ -854,12 +1103,11 @@ static int adxl372_dready_trig_set_state(struct iio_trigger *trig, { struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); struct adxl372_state *st = iio_priv(indio_dev); - unsigned long int mask = 0; if (state) - mask = ADXL372_INT1_MAP_FIFO_FULL_MSK; + st->int1_bitmask |= ADXL372_INT1_MAP_FIFO_FULL_MSK; - return adxl372_set_interrupts(st, mask, 0); + return adxl372_set_interrupts(st, st->int1_bitmask, 0); } static int adxl372_validate_trigger(struct iio_dev *indio_dev, @@ -867,7 +1115,7 @@ static int adxl372_validate_trigger(struct iio_dev *indio_dev, { struct adxl372_state *st = iio_priv(indio_dev); - if (st->dready_trig != trig) + if (st->dready_trig != trig && st->peak_datardy_trig != trig) return -EINVAL; return 0; @@ -878,6 +1126,25 @@ static const struct iio_trigger_ops adxl372_trigger_ops = { .set_trigger_state = adxl372_dready_trig_set_state, }; +static int adxl372_peak_dready_trig_set_state(struct iio_trigger *trig, + bool state) +{ + struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); + struct adxl372_state *st = iio_priv(indio_dev); + + if (state) + st->int1_bitmask |= ADXL372_INT1_MAP_FIFO_FULL_MSK; + + st->peak_fifo_mode_en = state; + + return adxl372_set_interrupts(st, st->int1_bitmask, 0); +} + +static const struct iio_trigger_ops adxl372_peak_data_trigger_ops = { + .validate_device = &iio_trigger_validate_own_device, + .set_trigger_state = adxl372_peak_dready_trig_set_state, +}; + static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("400 800 1600 3200 6400"); static IIO_DEVICE_ATTR(in_accel_filter_low_pass_3db_frequency_available, 0444, adxl372_show_filter_freq_avail, NULL, 0); @@ -897,6 +1164,10 @@ static const struct iio_info adxl372_info = { .attrs = &adxl372_attrs_group, .read_raw = adxl372_read_raw, .write_raw = adxl372_write_raw, + .read_event_config = adxl372_read_event_config, + .write_event_config = adxl372_write_event_config, + .read_event_value = adxl372_read_event_value, + .write_event_value = adxl372_write_event_value, .debugfs_reg_access = &adxl372_reg_access, .hwfifo_set_watermark = adxl372_set_watermark, }; @@ -925,6 +1196,8 @@ int adxl372_probe(struct device *dev, struct regmap *regmap, st->regmap = regmap; st->irq = irq; + mutex_init(&st->threshold_m); + indio_dev->channels = adxl372_channels; indio_dev->num_channels = ARRAY_SIZE(adxl372_channels); indio_dev->available_scan_masks = adxl372_channel_masks; @@ -955,13 +1228,27 @@ int adxl372_probe(struct device *dev, struct regmap *regmap, if (st->dready_trig == NULL) return -ENOMEM; + st->peak_datardy_trig = devm_iio_trigger_alloc(dev, + "%s-dev%d-peak", + indio_dev->name, + indio_dev->id); + if (!st->peak_datardy_trig) + return -ENOMEM; + st->dready_trig->ops = &adxl372_trigger_ops; + st->peak_datardy_trig->ops = &adxl372_peak_data_trigger_ops; st->dready_trig->dev.parent = dev; + st->peak_datardy_trig->dev.parent = dev; iio_trigger_set_drvdata(st->dready_trig, indio_dev); + iio_trigger_set_drvdata(st->peak_datardy_trig, indio_dev); ret = devm_iio_trigger_register(dev, st->dready_trig); if (ret < 0) return ret; + ret = devm_iio_trigger_register(dev, st->peak_datardy_trig); + if (ret < 0) + return ret; + indio_dev->trig = iio_trigger_get(st->dready_trig); ret = devm_request_threaded_irq(dev, st->irq, diff --git a/drivers/iio/accel/adxl372_i2c.c b/drivers/iio/accel/adxl372_i2c.c index e1affe480c77..9a07ab3d151a 100644 --- a/drivers/iio/accel/adxl372_i2c.c +++ b/drivers/iio/accel/adxl372_i2c.c @@ -6,6 +6,7 @@ */ #include <linux/i2c.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> #include <linux/regmap.h> @@ -46,9 +47,16 @@ static const struct i2c_device_id adxl372_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, adxl372_i2c_id); +static const struct of_device_id adxl372_of_match[] = { + { .compatible = "adi,adxl372" }, + { } +}; +MODULE_DEVICE_TABLE(of, adxl372_of_match); + static struct i2c_driver adxl372_i2c_driver = { .driver = { .name = "adxl372_i2c", + .of_match_table = adxl372_of_match, }, .probe = adxl372_i2c_probe, .id_table = adxl372_i2c_id, diff --git a/drivers/iio/accel/adxl372_spi.c b/drivers/iio/accel/adxl372_spi.c index 3ef7e3a4804e..1f1352fee99a 100644 --- a/drivers/iio/accel/adxl372_spi.c +++ b/drivers/iio/accel/adxl372_spi.c @@ -40,8 +40,8 @@ static const struct spi_device_id adxl372_spi_id[] = { MODULE_DEVICE_TABLE(spi, adxl372_spi_id); static const struct of_device_id adxl372_of_match[] = { - { .compatible = "adi,adxl372" }, - { }, + { .compatible = "adi,adxl372" }, + { } }; MODULE_DEVICE_TABLE(of, adxl372_of_match); diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c index 5b7a467c7b27..448faed001fd 100644 --- a/drivers/iio/accel/bma180.c +++ b/drivers/iio/accel/bma180.c @@ -1000,19 +1000,15 @@ static int bma180_probe(struct i2c_client *client, return ret; data->vdd_supply = devm_regulator_get(dev, "vdd"); - if (IS_ERR(data->vdd_supply)) { - if (PTR_ERR(data->vdd_supply) != -EPROBE_DEFER) - dev_err(dev, "Failed to get vdd regulator %d\n", - (int)PTR_ERR(data->vdd_supply)); - return PTR_ERR(data->vdd_supply); - } + if (IS_ERR(data->vdd_supply)) + return dev_err_probe(dev, PTR_ERR(data->vdd_supply), + "Failed to get vdd regulator\n"); + data->vddio_supply = devm_regulator_get(dev, "vddio"); - if (IS_ERR(data->vddio_supply)) { - if (PTR_ERR(data->vddio_supply) != -EPROBE_DEFER) - dev_err(dev, "Failed to get vddio regulator %d\n", - (int)PTR_ERR(data->vddio_supply)); - return PTR_ERR(data->vddio_supply); - } + if (IS_ERR(data->vddio_supply)) + return dev_err_probe(dev, PTR_ERR(data->vddio_supply), + "Failed to get vddio regulator\n"); + /* Typical voltage 2.4V these are min and max */ ret = regulator_set_voltage(data->vdd_supply, 1620000, 3600000); if (ret) diff --git a/drivers/iio/accel/bma220_spi.c b/drivers/iio/accel/bma220_spi.c index da8b36cc8628..3c9b0c6954e6 100644 --- a/drivers/iio/accel/bma220_spi.c +++ b/drivers/iio/accel/bma220_spi.c @@ -2,16 +2,18 @@ /** * BMA220 Digital triaxial acceleration sensor driver * - * Copyright (c) 2016, Intel Corporation. + * Copyright (c) 2016,2020 Intel Corporation. */ -#include <linux/acpi.h> +#include <linux/bits.h> #include <linux/kernel.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> +#include <linux/spi/spi.h> + #include <linux/iio/buffer.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> -#include <linux/spi/spi.h> #include <linux/iio/trigger_consumer.h> #include <linux/iio/triggered_buffer.h> @@ -23,14 +25,13 @@ #define BMA220_REG_SUSPEND 0x18 #define BMA220_CHIP_ID 0xDD -#define BMA220_READ_MASK 0x80 -#define BMA220_RANGE_MASK 0x03 +#define BMA220_READ_MASK BIT(7) +#define BMA220_RANGE_MASK GENMASK(1, 0) #define BMA220_DATA_SHIFT 2 #define BMA220_SUSPEND_SLEEP 0xFF #define BMA220_SUSPEND_WAKE 0x00 #define BMA220_DEVICE_NAME "bma220" -#define BMA220_SCALE_AVAILABLE "0.623 1.248 2.491 4.983" #define BMA220_ACCEL_CHANNEL(index, reg, axis) { \ .type = IIO_ACCEL, \ @@ -55,19 +56,8 @@ enum bma220_axis { AXIS_Z, }; -static IIO_CONST_ATTR(in_accel_scale_available, BMA220_SCALE_AVAILABLE); - -static struct attribute *bma220_attributes[] = { - &iio_const_attr_in_accel_scale_available.dev_attr.attr, - NULL, -}; - -static const struct attribute_group bma220_attribute_group = { - .attrs = bma220_attributes, -}; - -static const int bma220_scale_table[][4] = { - {0, 623000}, {1, 248000}, {2, 491000}, {4, 983000} +static const int bma220_scale_table[][2] = { + {0, 623000}, {1, 248000}, {2, 491000}, {4, 983000}, }; struct bma220_data { @@ -182,10 +172,26 @@ static int bma220_write_raw(struct iio_dev *indio_dev, return -EINVAL; } +static int bma220_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_SCALE: + *vals = (int *)bma220_scale_table; + *type = IIO_VAL_INT_PLUS_MICRO; + *length = ARRAY_SIZE(bma220_scale_table) * 2; + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } +} + static const struct iio_info bma220_info = { .read_raw = bma220_read_raw, .write_raw = bma220_write_raw, - .attrs = &bma220_attribute_group, + .read_avail = bma220_read_avail, }; static int bma220_init(struct spi_device *spi) @@ -198,10 +204,12 @@ static int bma220_init(struct spi_device *spi) /* Make sure the chip is powered on */ ret = bma220_read_reg(spi, BMA220_REG_SUSPEND); + if (ret == BMA220_SUSPEND_WAKE) + ret = bma220_read_reg(spi, BMA220_REG_SUSPEND); if (ret < 0) return ret; - else if (ret == BMA220_SUSPEND_WAKE) - return bma220_read_reg(spi, BMA220_REG_SUSPEND); + if (ret == BMA220_SUSPEND_WAKE) + return -EBUSY; return 0; } @@ -212,10 +220,12 @@ static int bma220_deinit(struct spi_device *spi) /* Make sure the chip is powered off */ ret = bma220_read_reg(spi, BMA220_REG_SUSPEND); + if (ret == BMA220_SUSPEND_SLEEP) + ret = bma220_read_reg(spi, BMA220_REG_SUSPEND); if (ret < 0) return ret; - else if (ret == BMA220_SUSPEND_SLEEP) - return bma220_read_reg(spi, BMA220_REG_SUSPEND); + if (ret == BMA220_SUSPEND_SLEEP) + return -EBUSY; return 0; } @@ -245,7 +255,7 @@ static int bma220_probe(struct spi_device *spi) indio_dev->available_scan_masks = bma220_accel_scan_masks; ret = bma220_init(data->spi_device); - if (ret < 0) + if (ret) return ret; ret = iio_triggered_buffer_setup(indio_dev, iio_pollfunc_store_time, @@ -278,56 +288,43 @@ static int bma220_remove(struct spi_device *spi) return bma220_deinit(spi); } -#ifdef CONFIG_PM_SLEEP -static int bma220_suspend(struct device *dev) +static __maybe_unused int bma220_suspend(struct device *dev) { - struct bma220_data *data = - iio_priv(spi_get_drvdata(to_spi_device(dev))); + struct bma220_data *data = iio_priv(dev_get_drvdata(dev)); /* The chip can be suspended/woken up by a simple register read. */ return bma220_read_reg(data->spi_device, BMA220_REG_SUSPEND); } -static int bma220_resume(struct device *dev) +static __maybe_unused int bma220_resume(struct device *dev) { - struct bma220_data *data = - iio_priv(spi_get_drvdata(to_spi_device(dev))); + struct bma220_data *data = iio_priv(dev_get_drvdata(dev)); return bma220_read_reg(data->spi_device, BMA220_REG_SUSPEND); } - static SIMPLE_DEV_PM_OPS(bma220_pm_ops, bma220_suspend, bma220_resume); -#define BMA220_PM_OPS (&bma220_pm_ops) -#else -#define BMA220_PM_OPS NULL -#endif - static const struct spi_device_id bma220_spi_id[] = { {"bma220", 0}, {} }; -#ifdef CONFIG_ACPI static const struct acpi_device_id bma220_acpi_id[] = { {"BMA0220", 0}, {} }; - MODULE_DEVICE_TABLE(spi, bma220_spi_id); -#endif static struct spi_driver bma220_driver = { .driver = { .name = "bma220_spi", - .pm = BMA220_PM_OPS, - .acpi_match_table = ACPI_PTR(bma220_acpi_id), + .pm = &bma220_pm_ops, + .acpi_match_table = bma220_acpi_id, }, .probe = bma220_probe, .remove = bma220_remove, .id_table = bma220_spi_id, }; - module_spi_driver(bma220_driver); MODULE_AUTHOR("Tiberiu Breana <tiberiu.a.breana@intel.com>"); diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c index 853febc29488..bf1d2c8afdbd 100644 --- a/drivers/iio/accel/mma8452.c +++ b/drivers/iio/accel/mma8452.c @@ -1543,22 +1543,14 @@ static int mma8452_probe(struct i2c_client *client, data->chip_info = match->data; data->vdd_reg = devm_regulator_get(&client->dev, "vdd"); - if (IS_ERR(data->vdd_reg)) { - if (PTR_ERR(data->vdd_reg) == -EPROBE_DEFER) - return -EPROBE_DEFER; - - dev_err(&client->dev, "failed to get VDD regulator!\n"); - return PTR_ERR(data->vdd_reg); - } + if (IS_ERR(data->vdd_reg)) + return dev_err_probe(&client->dev, PTR_ERR(data->vdd_reg), + "failed to get VDD regulator!\n"); data->vddio_reg = devm_regulator_get(&client->dev, "vddio"); - if (IS_ERR(data->vddio_reg)) { - if (PTR_ERR(data->vddio_reg) == -EPROBE_DEFER) - return -EPROBE_DEFER; - - dev_err(&client->dev, "failed to get VDDIO regulator!\n"); - return PTR_ERR(data->vddio_reg); - } + if (IS_ERR(data->vddio_reg)) + return dev_err_probe(&client->dev, PTR_ERR(data->vddio_reg), + "failed to get VDDIO regulator!\n"); ret = regulator_enable(data->vdd_reg); if (ret) { diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index d94dc800b842..406a4b00fb1f 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -340,7 +340,7 @@ config AXP288_ADC config BCM_IPROC_ADC tristate "Broadcom IPROC ADC driver" - depends on ARCH_BCM_IPROC || COMPILE_TEST + depends on (ARCH_BCM_IPROC && OF) || COMPILE_TEST depends on MFD_SYSCON default ARCH_BCM_CYGNUS help diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c index 86b6b65916ee..9109da2d2e15 100644 --- a/drivers/iio/adc/adi-axi-adc.c +++ b/drivers/iio/adc/adi-axi-adc.c @@ -276,7 +276,7 @@ static struct attribute *adi_axi_adc_attributes[] = { static umode_t axi_adc_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n) { - struct device *dev = container_of(kobj, struct device, kobj); + struct device *dev = kobj_to_dev(kobj); struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct adi_axi_adc_state *st = iio_priv(indio_dev); struct adi_axi_adc_conv *conv = &st->client->conv; diff --git a/drivers/iio/adc/axp20x_adc.c b/drivers/iio/adc/axp20x_adc.c index 798ff2d89691..3e0c0233b431 100644 --- a/drivers/iio/adc/axp20x_adc.c +++ b/drivers/iio/adc/axp20x_adc.c @@ -9,10 +9,10 @@ #include <linux/interrupt.h> #include <linux/io.h> #include <linux/module.h> -#include <linux/of.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> +#include <linux/property.h> #include <linux/regmap.h> #include <linux/thermal.h> @@ -67,7 +67,7 @@ struct axp_data; struct axp20x_adc_iio { struct regmap *regmap; - struct axp_data *data; + const struct axp_data *data; }; enum axp20x_adc_channel_v { @@ -670,15 +670,15 @@ static int axp20x_probe(struct platform_device *pdev) info->regmap = axp20x_dev->regmap; indio_dev->modes = INDIO_DIRECT_MODE; - if (!pdev->dev.of_node) { + if (!dev_fwnode(&pdev->dev)) { const struct platform_device_id *id; id = platform_get_device_id(pdev); - info->data = (struct axp_data *)id->driver_data; + info->data = (const struct axp_data *)id->driver_data; } else { struct device *dev = &pdev->dev; - info->data = (struct axp_data *)of_device_get_match_data(dev); + info->data = device_get_match_data(dev); } indio_dev->name = platform_get_device_id(pdev)->name; @@ -742,7 +742,7 @@ static int axp20x_remove(struct platform_device *pdev) static struct platform_driver axp20x_adc_driver = { .driver = { .name = "axp20x-adc", - .of_match_table = of_match_ptr(axp20x_adc_of_match), + .of_match_table = axp20x_adc_of_match, }, .id_table = axp20x_adc_id_match, .probe = axp20x_probe, diff --git a/drivers/iio/adc/bcm_iproc_adc.c b/drivers/iio/adc/bcm_iproc_adc.c index 936da32faa9d..44e1e53ada72 100644 --- a/drivers/iio/adc/bcm_iproc_adc.c +++ b/drivers/iio/adc/bcm_iproc_adc.c @@ -4,7 +4,7 @@ */ #include <linux/module.h> -#include <linux/of.h> +#include <linux/mod_devicetable.h> #include <linux/io.h> #include <linux/clk.h> #include <linux/mfd/syscon.h> @@ -617,7 +617,7 @@ static struct platform_driver iproc_adc_driver = { .remove = iproc_adc_remove, .driver = { .name = "iproc-static-adc", - .of_match_table = of_match_ptr(iproc_adc_of_match), + .of_match_table = iproc_adc_of_match, }, }; module_platform_driver(iproc_adc_driver); diff --git a/drivers/iio/adc/envelope-detector.c b/drivers/iio/adc/envelope-detector.c index 2a4fd3bb64cf..d73eac36153f 100644 --- a/drivers/iio/adc/envelope-detector.c +++ b/drivers/iio/adc/envelope-detector.c @@ -348,11 +348,9 @@ static int envelope_detector_probe(struct platform_device *pdev) indio_dev->num_channels = 1; env->dac = devm_iio_channel_get(dev, "dac"); - if (IS_ERR(env->dac)) { - if (PTR_ERR(env->dac) != -EPROBE_DEFER) - dev_err(dev, "failed to get dac input channel\n"); - return PTR_ERR(env->dac); - } + if (IS_ERR(env->dac)) + return dev_err_probe(dev, PTR_ERR(env->dac), + "failed to get dac input channel\n"); env->comp_irq = platform_get_irq_byname(pdev, "comp"); if (env->comp_irq < 0) @@ -360,11 +358,9 @@ static int envelope_detector_probe(struct platform_device *pdev) ret = devm_request_irq(dev, env->comp_irq, envelope_detector_comp_isr, 0, "envelope-detector", env); - if (ret) { - if (ret != -EPROBE_DEFER) - dev_err(dev, "failed to request interrupt\n"); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "failed to request interrupt\n"); + env->comp_irq_trigger = irq_get_trigger_type(env->comp_irq); if (env->comp_irq_trigger & IRQF_TRIGGER_RISING) env->comp_irq_trigger_inv |= IRQF_TRIGGER_FALLING; diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c index 7d23b6c33284..20477b249f2a 100644 --- a/drivers/iio/adc/exynos_adc.c +++ b/drivers/iio/adc/exynos_adc.c @@ -844,13 +844,9 @@ static int exynos_adc_probe(struct platform_device *pdev) } info->vdd = devm_regulator_get(&pdev->dev, "vdd"); - if (IS_ERR(info->vdd)) { - if (PTR_ERR(info->vdd) != -EPROBE_DEFER) - dev_err(&pdev->dev, - "failed getting regulator, err = %ld\n", - PTR_ERR(info->vdd)); - return PTR_ERR(info->vdd); - } + if (IS_ERR(info->vdd)) + return dev_err_probe(&pdev->dev, PTR_ERR(info->vdd), + "failed getting regulator"); ret = regulator_enable(info->vdd); if (ret) diff --git a/drivers/iio/adc/ltc2497-core.c b/drivers/iio/adc/ltc2497-core.c index 9b8fd9c32364..2a485c8a1940 100644 --- a/drivers/iio/adc/ltc2497-core.c +++ b/drivers/iio/adc/ltc2497-core.c @@ -180,13 +180,9 @@ int ltc2497core_probe(struct device *dev, struct iio_dev *indio_dev) return ret; ddata->ref = devm_regulator_get(dev, "vref"); - if (IS_ERR(ddata->ref)) { - if (PTR_ERR(ddata->ref) != -EPROBE_DEFER) - dev_err(dev, "Failed to get vref regulator: %pe\n", - ddata->ref); - - return PTR_ERR(ddata->ref); - } + if (IS_ERR(ddata->ref)) + return dev_err_probe(dev, PTR_ERR(ddata->ref), + "Failed to get vref regulator\n"); ret = regulator_enable(ddata->ref); if (ret < 0) { diff --git a/drivers/iio/adc/meson_saradc.c b/drivers/iio/adc/meson_saradc.c index 1a9189ba69ae..95bd187de1cb 100644 --- a/drivers/iio/adc/meson_saradc.c +++ b/drivers/iio/adc/meson_saradc.c @@ -719,11 +719,8 @@ static int meson_sar_adc_temp_sensor_init(struct iio_dev *indio_dev) if (ret == -ENODEV) return 0; - if (ret != -EPROBE_DEFER) - dev_err(indio_dev->dev.parent, - "failed to get temperature_calib cell\n"); - - return ret; + return dev_err_probe(indio_dev->dev.parent, ret, + "failed to get temperature_calib cell\n"); } priv->tsc_regmap = diff --git a/drivers/iio/adc/rcar-gyroadc.c b/drivers/iio/adc/rcar-gyroadc.c index d2c1419e72a0..dcaefc108ff6 100644 --- a/drivers/iio/adc/rcar-gyroadc.c +++ b/drivers/iio/adc/rcar-gyroadc.c @@ -495,12 +495,9 @@ static int rcar_gyroadc_probe(struct platform_device *pdev) return PTR_ERR(priv->regs); priv->clk = devm_clk_get(dev, "fck"); - if (IS_ERR(priv->clk)) { - ret = PTR_ERR(priv->clk); - if (ret != -EPROBE_DEFER) - dev_err(dev, "Failed to get IF clock (ret=%i)\n", ret); - return ret; - } + if (IS_ERR(priv->clk)) + return dev_err_probe(dev, PTR_ERR(priv->clk), + "Failed to get IF clock\n"); ret = rcar_gyroadc_parse_subdevs(indio_dev); if (ret) diff --git a/drivers/iio/adc/stm32-adc-core.c b/drivers/iio/adc/stm32-adc-core.c index 0e2068ec068b..3f27b4817a42 100644 --- a/drivers/iio/adc/stm32-adc-core.c +++ b/drivers/iio/adc/stm32-adc-core.c @@ -582,11 +582,9 @@ static int stm32_adc_core_switches_probe(struct device *dev, priv->syscfg = syscon_regmap_lookup_by_phandle(np, "st,syscfg"); if (IS_ERR(priv->syscfg)) { ret = PTR_ERR(priv->syscfg); - if (ret != -ENODEV) { - if (ret != -EPROBE_DEFER) - dev_err(dev, "Can't probe syscfg: %d\n", ret); - return ret; - } + if (ret != -ENODEV) + return dev_err_probe(dev, ret, "Can't probe syscfg\n"); + priv->syscfg = NULL; } @@ -596,12 +594,9 @@ static int stm32_adc_core_switches_probe(struct device *dev, priv->booster = devm_regulator_get_optional(dev, "booster"); if (IS_ERR(priv->booster)) { ret = PTR_ERR(priv->booster); - if (ret != -ENODEV) { - if (ret != -EPROBE_DEFER) - dev_err(dev, "can't get booster %d\n", - ret); - return ret; - } + if (ret != -ENODEV) + dev_err_probe(dev, ret, "can't get booster\n"); + priv->booster = NULL; } } @@ -612,11 +607,9 @@ static int stm32_adc_core_switches_probe(struct device *dev, priv->vdd = devm_regulator_get_optional(dev, "vdd"); if (IS_ERR(priv->vdd)) { ret = PTR_ERR(priv->vdd); - if (ret != -ENODEV) { - if (ret != -EPROBE_DEFER) - dev_err(dev, "can't get vdd %d\n", ret); - return ret; - } + if (ret != -ENODEV) + return dev_err_probe(dev, ret, "can't get vdd\n"); + priv->vdd = NULL; } } @@ -669,42 +662,24 @@ static int stm32_adc_probe(struct platform_device *pdev) priv->common.phys_base = res->start; priv->vdda = devm_regulator_get(&pdev->dev, "vdda"); - if (IS_ERR(priv->vdda)) { - ret = PTR_ERR(priv->vdda); - if (ret != -EPROBE_DEFER) - dev_err(&pdev->dev, "vdda get failed, %d\n", ret); - return ret; - } + if (IS_ERR(priv->vdda)) + return dev_err_probe(&pdev->dev, PTR_ERR(priv->vdda), + "vdda get failed\n"); priv->vref = devm_regulator_get(&pdev->dev, "vref"); - if (IS_ERR(priv->vref)) { - ret = PTR_ERR(priv->vref); - if (ret != -EPROBE_DEFER) - dev_err(&pdev->dev, "vref get failed, %d\n", ret); - return ret; - } - - priv->aclk = devm_clk_get(&pdev->dev, "adc"); - if (IS_ERR(priv->aclk)) { - ret = PTR_ERR(priv->aclk); - if (ret != -ENOENT) { - if (ret != -EPROBE_DEFER) - dev_err(&pdev->dev, "Can't get 'adc' clock\n"); - return ret; - } - priv->aclk = NULL; - } - - priv->bclk = devm_clk_get(&pdev->dev, "bus"); - if (IS_ERR(priv->bclk)) { - ret = PTR_ERR(priv->bclk); - if (ret != -ENOENT) { - if (ret != -EPROBE_DEFER) - dev_err(&pdev->dev, "Can't get 'bus' clock\n"); - return ret; - } - priv->bclk = NULL; - } + if (IS_ERR(priv->vref)) + return dev_err_probe(&pdev->dev, PTR_ERR(priv->vref), + "vref get failed\n"); + + priv->aclk = devm_clk_get_optional(&pdev->dev, "adc"); + if (IS_ERR(priv->aclk)) + return dev_err_probe(&pdev->dev, PTR_ERR(priv->aclk), + "Can't get 'adc' clock\n"); + + priv->bclk = devm_clk_get_optional(&pdev->dev, "bus"); + if (IS_ERR(priv->bclk)) + return dev_err_probe(&pdev->dev, PTR_ERR(priv->bclk), + "Can't get 'bus' clock\n"); ret = stm32_adc_core_switches_probe(dev, priv); if (ret) diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c index 3eb9ebe8372f..b3f31f147347 100644 --- a/drivers/iio/adc/stm32-adc.c +++ b/drivers/iio/adc/stm32-adc.c @@ -1805,13 +1805,9 @@ static int stm32_adc_dma_request(struct device *dev, struct iio_dev *indio_dev) adc->dma_chan = dma_request_chan(dev, "rx"); if (IS_ERR(adc->dma_chan)) { ret = PTR_ERR(adc->dma_chan); - if (ret != -ENODEV) { - if (ret != -EPROBE_DEFER) - dev_err(dev, - "DMA channel request failed with %d\n", - ret); - return ret; - } + if (ret != -ENODEV) + return dev_err_probe(dev, ret, + "DMA channel request failed with\n"); /* DMA is optional: fall back to IRQ mode */ adc->dma_chan = NULL; diff --git a/drivers/iio/adc/stm32-dfsdm-adc.c b/drivers/iio/adc/stm32-dfsdm-adc.c index 5e10fb4f3704..c7e0109315f8 100644 --- a/drivers/iio/adc/stm32-dfsdm-adc.c +++ b/drivers/iio/adc/stm32-dfsdm-adc.c @@ -1473,13 +1473,9 @@ static int stm32_dfsdm_adc_init(struct device *dev, struct iio_dev *indio_dev) /* Optionally request DMA */ ret = stm32_dfsdm_dma_request(dev, indio_dev); if (ret) { - if (ret != -ENODEV) { - if (ret != -EPROBE_DEFER) - dev_err(dev, - "DMA channel request failed with %d\n", - ret); - return ret; - } + if (ret != -ENODEV) + return dev_err_probe(dev, ret, + "DMA channel request failed with\n"); dev_dbg(dev, "No DMA support\n"); return 0; diff --git a/drivers/iio/adc/stm32-dfsdm-core.c b/drivers/iio/adc/stm32-dfsdm-core.c index 26e2011c5868..0b8bea88b011 100644 --- a/drivers/iio/adc/stm32-dfsdm-core.c +++ b/drivers/iio/adc/stm32-dfsdm-core.c @@ -243,12 +243,9 @@ static int stm32_dfsdm_parse_of(struct platform_device *pdev, * on use case. */ priv->clk = devm_clk_get(&pdev->dev, "dfsdm"); - if (IS_ERR(priv->clk)) { - ret = PTR_ERR(priv->clk); - if (ret != -EPROBE_DEFER) - dev_err(&pdev->dev, "Failed to get clock (%d)\n", ret); - return ret; - } + if (IS_ERR(priv->clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk), + "Failed to get clock\n"); priv->aclk = devm_clk_get(&pdev->dev, "audio"); if (IS_ERR(priv->aclk)) diff --git a/drivers/iio/adc/ti-adc081c.c b/drivers/iio/adc/ti-adc081c.c index cf63983a54d9..b64718daa201 100644 --- a/drivers/iio/adc/ti-adc081c.c +++ b/drivers/iio/adc/ti-adc081c.c @@ -19,7 +19,6 @@ #include <linux/i2c.h> #include <linux/module.h> #include <linux/mod_devicetable.h> -#include <linux/acpi.h> #include <linux/iio/iio.h> #include <linux/iio/buffer.h> @@ -158,17 +157,7 @@ static int adc081c_probe(struct i2c_client *client, if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) return -EOPNOTSUPP; - if (ACPI_COMPANION(&client->dev)) { - const struct acpi_device_id *ad_id; - - ad_id = acpi_match_device(client->dev.driver->acpi_match_table, - &client->dev); - if (!ad_id) - return -ENODEV; - model = &adcxx1c_models[ad_id->driver_data]; - } else { - model = &adcxx1c_models[id->driver_data]; - } + model = &adcxx1c_models[id->driver_data]; iio = devm_iio_device_alloc(&client->dev, sizeof(*adc)); if (!iio) @@ -243,21 +232,10 @@ static const struct of_device_id adc081c_of_match[] = { }; MODULE_DEVICE_TABLE(of, adc081c_of_match); -#ifdef CONFIG_ACPI -static const struct acpi_device_id adc081c_acpi_match[] = { - { "ADC081C", ADC081C }, - { "ADC101C", ADC101C }, - { "ADC121C", ADC121C }, - { } -}; -MODULE_DEVICE_TABLE(acpi, adc081c_acpi_match); -#endif - static struct i2c_driver adc081c_driver = { .driver = { .name = "adc081c", .of_match_table = adc081c_of_match, - .acpi_match_table = ACPI_PTR(adc081c_acpi_match), }, .probe = adc081c_probe, .remove = adc081c_remove, diff --git a/drivers/iio/adc/ti-adc108s102.c b/drivers/iio/adc/ti-adc108s102.c index 9b9b27415c93..183b2245e89b 100644 --- a/drivers/iio/adc/ti-adc108s102.c +++ b/drivers/iio/adc/ti-adc108s102.c @@ -20,6 +20,7 @@ #include <linux/iio/trigger_consumer.h> #include <linux/interrupt.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/property.h> #include <linux/regulator/consumer.h> #include <linux/spi/spi.h> @@ -299,13 +300,11 @@ static int adc108s102_remove(struct spi_device *spi) return 0; } -#ifdef CONFIG_OF static const struct of_device_id adc108s102_of_match[] = { { .compatible = "ti,adc108s102" }, { } }; MODULE_DEVICE_TABLE(of, adc108s102_of_match); -#endif #ifdef CONFIG_ACPI static const struct acpi_device_id adc108s102_acpi_ids[] = { @@ -324,7 +323,7 @@ MODULE_DEVICE_TABLE(spi, adc108s102_id); static struct spi_driver adc108s102_driver = { .driver = { .name = "adc108s102", - .of_match_table = of_match_ptr(adc108s102_of_match), + .of_match_table = adc108s102_of_match, .acpi_match_table = ACPI_PTR(adc108s102_acpi_ids), }, .probe = adc108s102_probe, diff --git a/drivers/iio/adc/ti-adc128s052.c b/drivers/iio/adc/ti-adc128s052.c index e86f55ce093f..3143f35a6509 100644 --- a/drivers/iio/adc/ti-adc128s052.c +++ b/drivers/iio/adc/ti-adc128s052.c @@ -13,6 +13,7 @@ #include <linux/err.h> #include <linux/spi/spi.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/iio/iio.h> #include <linux/property.h> #include <linux/regulator/consumer.h> @@ -220,7 +221,7 @@ MODULE_DEVICE_TABLE(acpi, adc128_acpi_match); static struct spi_driver adc128_driver = { .driver = { .name = "adc128s052", - .of_match_table = of_match_ptr(adc128_of_match), + .of_match_table = adc128_of_match, .acpi_match_table = ACPI_PTR(adc128_acpi_match), }, .probe = adc128_probe, diff --git a/drivers/iio/afe/iio-rescale.c b/drivers/iio/afe/iio-rescale.c index 69c0f277ada0..e42ea2b1707d 100644 --- a/drivers/iio/afe/iio-rescale.c +++ b/drivers/iio/afe/iio-rescale.c @@ -276,11 +276,9 @@ static int rescale_probe(struct platform_device *pdev) int ret; source = devm_iio_channel_get(dev, NULL); - if (IS_ERR(source)) { - if (PTR_ERR(source) != -EPROBE_DEFER) - dev_err(dev, "failed to get source channel\n"); - return PTR_ERR(source); - } + if (IS_ERR(source)) + return dev_err_probe(dev, PTR_ERR(source), + "failed to get source channel\n"); sizeof_ext_info = iio_get_channel_ext_info_count(source); if (sizeof_ext_info) { diff --git a/drivers/iio/amplifiers/Kconfig b/drivers/iio/amplifiers/Kconfig index 9b02c9a2bc8a..5eb1357a9c78 100644 --- a/drivers/iio/amplifiers/Kconfig +++ b/drivers/iio/amplifiers/Kconfig @@ -18,6 +18,7 @@ config AD8366 AD8366 Dual-Digital Variable Gain Amplifier (VGA) ADA4961 BiCMOS RF Digital Gain Amplifier (DGA) ADL5240 Digitally controlled variable gain amplifier (VGA) + HMC1119 0.25 dB LSB, 7-Bit, Silicon Digital Attenuator To compile this driver as a module, choose M here: the module will be called ad8366. diff --git a/drivers/iio/amplifiers/hmc425a.c b/drivers/iio/amplifiers/hmc425a.c index 582708924e4f..9efa692151f0 100644 --- a/drivers/iio/amplifiers/hmc425a.c +++ b/drivers/iio/amplifiers/hmc425a.c @@ -201,12 +201,9 @@ static int hmc425a_probe(struct platform_device *pdev) st->gain = st->chip_info->default_gain; st->gpios = devm_gpiod_get_array(&pdev->dev, "ctrl", GPIOD_OUT_LOW); - if (IS_ERR(st->gpios)) { - ret = PTR_ERR(st->gpios); - if (ret != -EPROBE_DEFER) - dev_err(&pdev->dev, "failed to get gpios\n"); - return ret; - } + if (IS_ERR(st->gpios)) + return dev_err_probe(&pdev->dev, PTR_ERR(st->gpios), + "failed to get gpios\n"); if (st->gpios->ndescs != st->chip_info->num_gpios) { dev_err(&pdev->dev, "%d GPIOs needed to operate\n", diff --git a/drivers/iio/buffer/industrialio-buffer-dmaengine.c b/drivers/iio/buffer/industrialio-buffer-dmaengine.c index 6dedf12b69a4..5789bda0745b 100644 --- a/drivers/iio/buffer/industrialio-buffer-dmaengine.c +++ b/drivers/iio/buffer/industrialio-buffer-dmaengine.c @@ -45,7 +45,8 @@ static struct dmaengine_buffer *iio_buffer_to_dmaengine_buffer( return container_of(buffer, struct dmaengine_buffer, queue.buffer); } -static void iio_dmaengine_buffer_block_done(void *data) +static void iio_dmaengine_buffer_block_done(void *data, + const struct dmaengine_result *result) { struct iio_dma_buffer_block *block = data; unsigned long flags; @@ -53,6 +54,7 @@ static void iio_dmaengine_buffer_block_done(void *data) spin_lock_irqsave(&block->queue->list_lock, flags); list_del(&block->head); spin_unlock_irqrestore(&block->queue->list_lock, flags); + block->bytes_used -= result->residue; iio_dma_buffer_block_done(block); } @@ -74,7 +76,7 @@ static int iio_dmaengine_buffer_submit_block(struct iio_dma_buffer_queue *queue, if (!desc) return -ENOMEM; - desc->callback = iio_dmaengine_buffer_block_done; + desc->callback_result = iio_dmaengine_buffer_block_done; desc->callback_param = block; cookie = dmaengine_submit(desc); diff --git a/drivers/iio/chemical/atlas-ezo-sensor.c b/drivers/iio/chemical/atlas-ezo-sensor.c index 8b72bb012363..b1bacfe3c3ce 100644 --- a/drivers/iio/chemical/atlas-ezo-sensor.c +++ b/drivers/iio/chemical/atlas-ezo-sensor.c @@ -16,10 +16,13 @@ #include <linux/iio/iio.h> #define ATLAS_EZO_DRV_NAME "atlas-ezo-sensor" -#define ATLAS_CO2_INT_TIME_IN_MS 950 +#define ATLAS_INT_TIME_IN_MS 950 +#define ATLAS_INT_HUM_TIME_IN_MS 350 enum { ATLAS_CO2_EZO, + ATLAS_O2_EZO, + ATLAS_HUM_EZO, }; struct atlas_ezo_device { @@ -38,15 +41,37 @@ struct atlas_ezo_data { u8 buffer[8]; }; +#define ATLAS_CONCENTRATION_CHANNEL(_modifier) \ + { \ + .type = IIO_CONCENTRATION, \ + .modified = 1,\ + .channel2 = _modifier, \ + .info_mask_separate = \ + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), \ + .scan_index = 0, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 32, \ + .storagebits = 32, \ + .endianness = IIO_CPU, \ + }, \ + } + static const struct iio_chan_spec atlas_co2_ezo_channels[] = { + ATLAS_CONCENTRATION_CHANNEL(IIO_MOD_CO2), +}; + +static const struct iio_chan_spec atlas_o2_ezo_channels[] = { + ATLAS_CONCENTRATION_CHANNEL(IIO_MOD_O2), +}; + +static const struct iio_chan_spec atlas_hum_ezo_channels[] = { { - .type = IIO_CONCENTRATION, - .modified = 1, - .channel2 = IIO_MOD_CO2, + .type = IIO_HUMIDITYRELATIVE, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), .scan_index = 0, - .scan_type = { + .scan_type = { .sign = 'u', .realbits = 32, .storagebits = 32, @@ -59,10 +84,30 @@ static struct atlas_ezo_device atlas_ezo_devices[] = { [ATLAS_CO2_EZO] = { .channels = atlas_co2_ezo_channels, .num_channels = 1, - .delay = ATLAS_CO2_INT_TIME_IN_MS, + .delay = ATLAS_INT_TIME_IN_MS, + }, + [ATLAS_O2_EZO] = { + .channels = atlas_o2_ezo_channels, + .num_channels = 1, + .delay = ATLAS_INT_TIME_IN_MS, + }, + [ATLAS_HUM_EZO] = { + .channels = atlas_hum_ezo_channels, + .num_channels = 1, + .delay = ATLAS_INT_HUM_TIME_IN_MS, }, }; +static void atlas_ezo_sanitize(char *buf) +{ + char *ptr = strchr(buf, '.'); + + if (!ptr) + return; + + memmove(ptr, ptr + 1, strlen(ptr)); +} + static int atlas_ezo_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -96,6 +141,9 @@ static int atlas_ezo_read_raw(struct iio_dev *indio_dev, return -EBUSY; } + /* removing floating point for fixed number representation */ + atlas_ezo_sanitize(data->buffer + 2); + ret = kstrtol(data->buffer + 1, 10, &tmp); *val = tmp; @@ -105,9 +153,27 @@ static int atlas_ezo_read_raw(struct iio_dev *indio_dev, return ret ? ret : IIO_VAL_INT; } case IIO_CHAN_INFO_SCALE: - *val = 0; - *val2 = 100; /* 0.0001 */ - return IIO_VAL_INT_PLUS_MICRO; + switch (chan->type) { + case IIO_HUMIDITYRELATIVE: + *val = 10; + return IIO_VAL_INT; + case IIO_CONCENTRATION: + break; + default: + return -EINVAL; + } + + /* IIO_CONCENTRATION modifiers */ + switch (chan->channel2) { + case IIO_MOD_CO2: + *val = 0; + *val2 = 100; /* 0.0001 */ + return IIO_VAL_INT_PLUS_MICRO; + case IIO_MOD_O2: + *val = 100; + return IIO_VAL_INT; + } + return -EINVAL; } return 0; @@ -119,12 +185,16 @@ static const struct iio_info atlas_info = { static const struct i2c_device_id atlas_ezo_id[] = { { "atlas-co2-ezo", ATLAS_CO2_EZO }, + { "atlas-o2-ezo", ATLAS_O2_EZO }, + { "atlas-hum-ezo", ATLAS_HUM_EZO }, {} }; MODULE_DEVICE_TABLE(i2c, atlas_ezo_id); static const struct of_device_id atlas_ezo_dt_ids[] = { { .compatible = "atlas,co2-ezo", .data = (void *)ATLAS_CO2_EZO, }, + { .compatible = "atlas,o2-ezo", .data = (void *)ATLAS_O2_EZO, }, + { .compatible = "atlas,hum-ezo", .data = (void *)ATLAS_HUM_EZO, }, {} }; MODULE_DEVICE_TABLE(of, atlas_ezo_dt_ids); diff --git a/drivers/iio/chemical/scd30_core.c b/drivers/iio/chemical/scd30_core.c index eac76972f83e..4d0d798c7cd3 100644 --- a/drivers/iio/chemical/scd30_core.c +++ b/drivers/iio/chemical/scd30_core.c @@ -705,13 +705,8 @@ int scd30_probe(struct device *dev, int irq, const char *name, void *priv, indio_dev->available_scan_masks = scd30_scan_masks; state->vdd = devm_regulator_get(dev, "vdd"); - if (IS_ERR(state->vdd)) { - if (PTR_ERR(state->vdd) == -EPROBE_DEFER) - return -EPROBE_DEFER; - - dev_err(dev, "failed to get regulator\n"); - return PTR_ERR(state->vdd); - } + if (IS_ERR(state->vdd)) + return dev_err_probe(dev, PTR_ERR(state->vdd), "failed to get regulator\n"); ret = regulator_enable(state->vdd); if (ret) diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c index 56cf9344d187..148d9541f517 100644 --- a/drivers/iio/dac/ad5686.c +++ b/drivers/iio/dac/ad5686.c @@ -206,12 +206,12 @@ static const struct iio_chan_spec_ext_info ad5686_ext_info[] = { } #define DECLARE_AD5693_CHANNELS(name, bits, _shift) \ -static struct iio_chan_spec name[] = { \ +static const struct iio_chan_spec name[] = { \ AD5868_CHANNEL(0, 0, bits, _shift), \ } #define DECLARE_AD5686_CHANNELS(name, bits, _shift) \ -static struct iio_chan_spec name[] = { \ +static const struct iio_chan_spec name[] = { \ AD5868_CHANNEL(0, 1, bits, _shift), \ AD5868_CHANNEL(1, 2, bits, _shift), \ AD5868_CHANNEL(2, 4, bits, _shift), \ @@ -219,7 +219,7 @@ static struct iio_chan_spec name[] = { \ } #define DECLARE_AD5676_CHANNELS(name, bits, _shift) \ -static struct iio_chan_spec name[] = { \ +static const struct iio_chan_spec name[] = { \ AD5868_CHANNEL(0, 0, bits, _shift), \ AD5868_CHANNEL(1, 1, bits, _shift), \ AD5868_CHANNEL(2, 2, bits, _shift), \ @@ -231,7 +231,7 @@ static struct iio_chan_spec name[] = { \ } #define DECLARE_AD5679_CHANNELS(name, bits, _shift) \ -static struct iio_chan_spec name[] = { \ +static const struct iio_chan_spec name[] = { \ AD5868_CHANNEL(0, 0, bits, _shift), \ AD5868_CHANNEL(1, 1, bits, _shift), \ AD5868_CHANNEL(2, 2, bits, _shift), \ diff --git a/drivers/iio/dac/ad5686.h b/drivers/iio/dac/ad5686.h index 52009b5eef88..a15f2970577e 100644 --- a/drivers/iio/dac/ad5686.h +++ b/drivers/iio/dac/ad5686.h @@ -104,7 +104,7 @@ typedef int (*ad5686_read_func)(struct ad5686_state *st, u8 addr); struct ad5686_chip_info { u16 int_vref_mv; unsigned int num_channels; - struct iio_chan_spec *channels; + const struct iio_chan_spec *channels; enum ad5686_regmap_type regmap_type; }; diff --git a/drivers/iio/dac/dpot-dac.c b/drivers/iio/dac/dpot-dac.c index 1a9609eda5c5..5d1819448102 100644 --- a/drivers/iio/dac/dpot-dac.c +++ b/drivers/iio/dac/dpot-dac.c @@ -184,18 +184,14 @@ static int dpot_dac_probe(struct platform_device *pdev) indio_dev->num_channels = 1; dac->vref = devm_regulator_get(dev, "vref"); - if (IS_ERR(dac->vref)) { - if (PTR_ERR(dac->vref) != -EPROBE_DEFER) - dev_err(&pdev->dev, "failed to get vref regulator\n"); - return PTR_ERR(dac->vref); - } + if (IS_ERR(dac->vref)) + return dev_err_probe(&pdev->dev, PTR_ERR(dac->vref), + "failed to get vref regulator\n"); dac->dpot = devm_iio_channel_get(dev, "dpot"); - if (IS_ERR(dac->dpot)) { - if (PTR_ERR(dac->dpot) != -EPROBE_DEFER) - dev_err(dev, "failed to get dpot input channel\n"); - return PTR_ERR(dac->dpot); - } + if (IS_ERR(dac->dpot)) + return dev_err_probe(&pdev->dev, PTR_ERR(dac->dpot), + "failed to get dpot input channel\n"); ret = iio_get_channel_type(dac->dpot, &type); if (ret < 0) diff --git a/drivers/iio/dac/stm32-dac-core.c b/drivers/iio/dac/stm32-dac-core.c index 7e5809ba0dee..906436780347 100644 --- a/drivers/iio/dac/stm32-dac-core.c +++ b/drivers/iio/dac/stm32-dac-core.c @@ -150,10 +150,7 @@ static int stm32_dac_probe(struct platform_device *pdev) rst = devm_reset_control_get_optional_exclusive(dev, NULL); if (rst) { if (IS_ERR(rst)) { - ret = PTR_ERR(rst); - if (ret != -EPROBE_DEFER) - dev_err(dev, "reset get failed, %d\n", ret); - + ret = dev_err_probe(dev, PTR_ERR(rst), "reset get failed\n"); goto err_hw_stop; } diff --git a/drivers/iio/dac/ti-dac5571.c b/drivers/iio/dac/ti-dac5571.c index 00fc7db8eb65..d303b19814e7 100644 --- a/drivers/iio/dac/ti-dac5571.c +++ b/drivers/iio/dac/ti-dac5571.c @@ -47,8 +47,8 @@ struct dac5571_data { struct mutex lock; struct regulator *vref; u16 val[4]; - bool powerdown; - u8 powerdown_mode; + bool powerdown[4]; + u8 powerdown_mode[4]; struct dac5571_spec const *spec; int (*dac5571_cmd)(struct dac5571_data *data, int channel, u16 val); int (*dac5571_pwrdwn)(struct dac5571_data *data, int channel, u8 pwrdwn); @@ -125,7 +125,7 @@ static int dac5571_get_powerdown_mode(struct iio_dev *indio_dev, { struct dac5571_data *data = iio_priv(indio_dev); - return data->powerdown_mode; + return data->powerdown_mode[chan->channel]; } static int dac5571_set_powerdown_mode(struct iio_dev *indio_dev, @@ -135,17 +135,17 @@ static int dac5571_set_powerdown_mode(struct iio_dev *indio_dev, struct dac5571_data *data = iio_priv(indio_dev); int ret = 0; - if (data->powerdown_mode == mode) + if (data->powerdown_mode[chan->channel] == mode) return 0; mutex_lock(&data->lock); - if (data->powerdown) { + if (data->powerdown[chan->channel]) { ret = data->dac5571_pwrdwn(data, chan->channel, DAC5571_POWERDOWN(mode)); if (ret) goto out; } - data->powerdown_mode = mode; + data->powerdown_mode[chan->channel] = mode; out: mutex_unlock(&data->lock); @@ -167,7 +167,7 @@ static ssize_t dac5571_read_powerdown(struct iio_dev *indio_dev, { struct dac5571_data *data = iio_priv(indio_dev); - return sprintf(buf, "%d\n", data->powerdown); + return sprintf(buf, "%d\n", data->powerdown[chan->channel]); } static ssize_t dac5571_write_powerdown(struct iio_dev *indio_dev, @@ -183,19 +183,20 @@ static ssize_t dac5571_write_powerdown(struct iio_dev *indio_dev, if (ret) return ret; - if (data->powerdown == powerdown) + if (data->powerdown[chan->channel] == powerdown) return len; mutex_lock(&data->lock); if (powerdown) ret = data->dac5571_pwrdwn(data, chan->channel, - DAC5571_POWERDOWN(data->powerdown_mode)); + DAC5571_POWERDOWN(data->powerdown_mode[chan->channel])); else - ret = data->dac5571_cmd(data, chan->channel, data->val[0]); + ret = data->dac5571_cmd(data, chan->channel, + data->val[chan->channel]); if (ret) goto out; - data->powerdown = powerdown; + data->powerdown[chan->channel] = powerdown; out: mutex_unlock(&data->lock); @@ -209,9 +210,9 @@ static const struct iio_chan_spec_ext_info dac5571_ext_info[] = { .name = "powerdown", .read = dac5571_read_powerdown, .write = dac5571_write_powerdown, - .shared = IIO_SHARED_BY_TYPE, + .shared = IIO_SEPARATE, }, - IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE, &dac5571_powerdown_mode), + IIO_ENUM("powerdown_mode", IIO_SEPARATE, &dac5571_powerdown_mode), IIO_ENUM_AVAILABLE("powerdown_mode", &dac5571_powerdown_mode), {}, }; @@ -276,7 +277,7 @@ static int dac5571_write_raw(struct iio_dev *indio_dev, if (val >= (1 << data->spec->resolution) || val < 0) return -EINVAL; - if (data->powerdown) + if (data->powerdown[chan->channel]) return -EBUSY; mutex_lock(&data->lock); diff --git a/drivers/iio/frequency/ad9523.c b/drivers/iio/frequency/ad9523.c index 334e1d779d6d..bdb0bc3b12dd 100644 --- a/drivers/iio/frequency/ad9523.c +++ b/drivers/iio/frequency/ad9523.c @@ -969,6 +969,13 @@ static int ad9523_setup(struct iio_dev *indio_dev) return 0; } +static void ad9523_reg_disable(void *data) +{ + struct regulator *reg = data; + + regulator_disable(reg); +} + static int ad9523_probe(struct spi_device *spi) { struct ad9523_platform_data *pdata = spi->dev.platform_data; @@ -994,21 +1001,22 @@ static int ad9523_probe(struct spi_device *spi) ret = regulator_enable(st->reg); if (ret) return ret; + + ret = devm_add_action_or_reset(&spi->dev, ad9523_reg_disable, + st->reg); + if (ret) + return ret; } st->pwrdown_gpio = devm_gpiod_get_optional(&spi->dev, "powerdown", GPIOD_OUT_HIGH); - if (IS_ERR(st->pwrdown_gpio)) { - ret = PTR_ERR(st->pwrdown_gpio); - goto error_disable_reg; - } + if (IS_ERR(st->pwrdown_gpio)) + return PTR_ERR(st->pwrdown_gpio); st->reset_gpio = devm_gpiod_get_optional(&spi->dev, "reset", GPIOD_OUT_LOW); - if (IS_ERR(st->reset_gpio)) { - ret = PTR_ERR(st->reset_gpio); - goto error_disable_reg; - } + if (IS_ERR(st->reset_gpio)) + return PTR_ERR(st->reset_gpio); if (st->reset_gpio) { udelay(1); @@ -1017,10 +1025,8 @@ static int ad9523_probe(struct spi_device *spi) st->sync_gpio = devm_gpiod_get_optional(&spi->dev, "sync", GPIOD_OUT_HIGH); - if (IS_ERR(st->sync_gpio)) { - ret = PTR_ERR(st->sync_gpio); - goto error_disable_reg; - } + if (IS_ERR(st->sync_gpio)) + return PTR_ERR(st->sync_gpio); spi_set_drvdata(spi, indio_dev); st->spi = spi; @@ -1035,34 +1041,9 @@ static int ad9523_probe(struct spi_device *spi) ret = ad9523_setup(indio_dev); if (ret < 0) - goto error_disable_reg; - - ret = iio_device_register(indio_dev); - if (ret) - goto error_disable_reg; - - dev_info(&spi->dev, "probed %s\n", indio_dev->name); - - return 0; - -error_disable_reg: - if (!IS_ERR(st->reg)) - regulator_disable(st->reg); - - return ret; -} - -static int ad9523_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct ad9523_state *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - - if (!IS_ERR(st->reg)) - regulator_disable(st->reg); + return ret; - return 0; + return devm_iio_device_register(&spi->dev, indio_dev); } static const struct spi_device_id ad9523_id[] = { @@ -1076,7 +1057,6 @@ static struct spi_driver ad9523_driver = { .name = "ad9523", }, .probe = ad9523_probe, - .remove = ad9523_remove, .id_table = ad9523_id, }; module_spi_driver(ad9523_driver); diff --git a/drivers/iio/gyro/Kconfig b/drivers/iio/gyro/Kconfig index 6daeddf37f60..024a34139875 100644 --- a/drivers/iio/gyro/Kconfig +++ b/drivers/iio/gyro/Kconfig @@ -41,6 +41,16 @@ config ADIS16260 This driver can also be built as a module. If so, the module will be called adis16260. +config ADXRS290 + tristate "Analog Devices ADXRS290 Dual-Axis MEMS Gyroscope SPI driver" + depends on SPI + help + Say yes here to build support for Analog Devices ADXRS290 programmable + digital output gyroscope. + + This driver can also be built as a module. If so, the module will be + called adxrs290. + config ADXRS450 tristate "Analog Devices ADXRS450/3 Digital Output Gyroscope SPI driver" depends on SPI diff --git a/drivers/iio/gyro/Makefile b/drivers/iio/gyro/Makefile index 45cbd5dc644e..0319b397dc3f 100644 --- a/drivers/iio/gyro/Makefile +++ b/drivers/iio/gyro/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_ADIS16080) += adis16080.o obj-$(CONFIG_ADIS16130) += adis16130.o obj-$(CONFIG_ADIS16136) += adis16136.o obj-$(CONFIG_ADIS16260) += adis16260.o +obj-$(CONFIG_ADXRS290) += adxrs290.o obj-$(CONFIG_ADXRS450) += adxrs450.o obj-$(CONFIG_BMG160) += bmg160_core.o obj-$(CONFIG_BMG160_I2C) += bmg160_i2c.o diff --git a/drivers/iio/gyro/adxrs290.c b/drivers/iio/gyro/adxrs290.c new file mode 100644 index 000000000000..ff989536d2fb --- /dev/null +++ b/drivers/iio/gyro/adxrs290.c @@ -0,0 +1,446 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * ADXRS290 SPI Gyroscope Driver + * + * Copyright (C) 2020 Nishant Malpani <nish.malpani25@gmail.com> + * Copyright (C) 2020 Analog Devices, Inc. + */ + +#include <linux/bitfield.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/spi/spi.h> + +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> + +#define ADXRS290_ADI_ID 0xAD +#define ADXRS290_MEMS_ID 0x1D +#define ADXRS290_DEV_ID 0x92 + +#define ADXRS290_REG_ADI_ID 0x00 +#define ADXRS290_REG_MEMS_ID 0x01 +#define ADXRS290_REG_DEV_ID 0x02 +#define ADXRS290_REG_REV_ID 0x03 +#define ADXRS290_REG_SN0 0x04 /* Serial Number Registers, 4 bytes */ +#define ADXRS290_REG_DATAX0 0x08 /* Roll Rate o/p Data Regs, 2 bytes */ +#define ADXRS290_REG_DATAY0 0x0A /* Pitch Rate o/p Data Regs, 2 bytes */ +#define ADXRS290_REG_TEMP0 0x0C +#define ADXRS290_REG_POWER_CTL 0x10 +#define ADXRS290_REG_FILTER 0x11 +#define ADXRS290_REG_DATA_RDY 0x12 + +#define ADXRS290_READ BIT(7) +#define ADXRS290_TSM BIT(0) +#define ADXRS290_MEASUREMENT BIT(1) +#define ADXRS290_SYNC GENMASK(1, 0) +#define ADXRS290_LPF_MASK GENMASK(2, 0) +#define ADXRS290_LPF(x) FIELD_PREP(ADXRS290_LPF_MASK, x) +#define ADXRS290_HPF_MASK GENMASK(7, 4) +#define ADXRS290_HPF(x) FIELD_PREP(ADXRS290_HPF_MASK, x) + +#define ADXRS290_READ_REG(reg) (ADXRS290_READ | (reg)) + +#define ADXRS290_MAX_TRANSITION_TIME_MS 100 + +enum adxrs290_mode { + ADXRS290_MODE_STANDBY, + ADXRS290_MODE_MEASUREMENT, +}; + +struct adxrs290_state { + struct spi_device *spi; + /* Serialize reads and their subsequent processing */ + struct mutex lock; + enum adxrs290_mode mode; + unsigned int lpf_3db_freq_idx; + unsigned int hpf_3db_freq_idx; +}; + +/* + * Available cut-off frequencies of the low pass filter in Hz. + * The integer part and fractional part are represented separately. + */ +static const int adxrs290_lpf_3db_freq_hz_table[][2] = { + [0] = {480, 0}, + [1] = {320, 0}, + [2] = {160, 0}, + [3] = {80, 0}, + [4] = {56, 600000}, + [5] = {40, 0}, + [6] = {28, 300000}, + [7] = {20, 0}, +}; + +/* + * Available cut-off frequencies of the high pass filter in Hz. + * The integer part and fractional part are represented separately. + */ +static const int adxrs290_hpf_3db_freq_hz_table[][2] = { + [0] = {0, 0}, + [1] = {0, 11000}, + [2] = {0, 22000}, + [3] = {0, 44000}, + [4] = {0, 87000}, + [5] = {0, 175000}, + [6] = {0, 350000}, + [7] = {0, 700000}, + [8] = {1, 400000}, + [9] = {2, 800000}, + [10] = {11, 300000}, +}; + +static int adxrs290_get_rate_data(struct iio_dev *indio_dev, const u8 cmd, int *val) +{ + struct adxrs290_state *st = iio_priv(indio_dev); + int ret = 0; + int temp; + + mutex_lock(&st->lock); + temp = spi_w8r16(st->spi, cmd); + if (temp < 0) { + ret = temp; + goto err_unlock; + } + + *val = temp; + +err_unlock: + mutex_unlock(&st->lock); + return ret; +} + +static int adxrs290_get_temp_data(struct iio_dev *indio_dev, int *val) +{ + const u8 cmd = ADXRS290_READ_REG(ADXRS290_REG_TEMP0); + struct adxrs290_state *st = iio_priv(indio_dev); + int ret = 0; + int temp; + + mutex_lock(&st->lock); + temp = spi_w8r16(st->spi, cmd); + if (temp < 0) { + ret = temp; + goto err_unlock; + } + + /* extract lower 12 bits temperature reading */ + *val = temp & 0x0FFF; + +err_unlock: + mutex_unlock(&st->lock); + return ret; +} + +static int adxrs290_get_3db_freq(struct iio_dev *indio_dev, u8 *val, u8 *val2) +{ + const u8 cmd = ADXRS290_READ_REG(ADXRS290_REG_FILTER); + struct adxrs290_state *st = iio_priv(indio_dev); + int ret = 0; + short temp; + + mutex_lock(&st->lock); + temp = spi_w8r8(st->spi, cmd); + if (temp < 0) { + ret = temp; + goto err_unlock; + } + + *val = FIELD_GET(ADXRS290_LPF_MASK, temp); + *val2 = FIELD_GET(ADXRS290_HPF_MASK, temp); + +err_unlock: + mutex_unlock(&st->lock); + return ret; +} + +static int adxrs290_spi_write_reg(struct spi_device *spi, const u8 reg, + const u8 val) +{ + u8 buf[2]; + + buf[0] = reg; + buf[1] = val; + + return spi_write_then_read(spi, buf, ARRAY_SIZE(buf), NULL, 0); +} + +static int adxrs290_find_match(const int (*freq_tbl)[2], const int n, + const int val, const int val2) +{ + int i; + + for (i = 0; i < n; i++) { + if (freq_tbl[i][0] == val && freq_tbl[i][1] == val2) + return i; + } + + return -EINVAL; +} + +static int adxrs290_set_filter_freq(struct iio_dev *indio_dev, + const unsigned int lpf_idx, + const unsigned int hpf_idx) +{ + struct adxrs290_state *st = iio_priv(indio_dev); + u8 val; + + val = ADXRS290_HPF(hpf_idx) | ADXRS290_LPF(lpf_idx); + + return adxrs290_spi_write_reg(st->spi, ADXRS290_REG_FILTER, val); +} + +static int adxrs290_initial_setup(struct iio_dev *indio_dev) +{ + struct adxrs290_state *st = iio_priv(indio_dev); + + st->mode = ADXRS290_MODE_MEASUREMENT; + + return adxrs290_spi_write_reg(st->spi, + ADXRS290_REG_POWER_CTL, + ADXRS290_MEASUREMENT | ADXRS290_TSM); +} + +static int adxrs290_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long mask) +{ + struct adxrs290_state *st = iio_priv(indio_dev); + unsigned int t; + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + switch (chan->type) { + case IIO_ANGL_VEL: + ret = adxrs290_get_rate_data(indio_dev, + ADXRS290_READ_REG(chan->address), + val); + if (ret < 0) + return ret; + + return IIO_VAL_INT; + case IIO_TEMP: + ret = adxrs290_get_temp_data(indio_dev, val); + if (ret < 0) + return ret; + + return IIO_VAL_INT; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_SCALE: + switch (chan->type) { + case IIO_ANGL_VEL: + /* 1 LSB = 0.005 degrees/sec */ + *val = 0; + *val2 = 87266; + return IIO_VAL_INT_PLUS_NANO; + case IIO_TEMP: + /* 1 LSB = 0.1 degrees Celsius */ + *val = 100; + return IIO_VAL_INT; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: + switch (chan->type) { + case IIO_ANGL_VEL: + t = st->lpf_3db_freq_idx; + *val = adxrs290_lpf_3db_freq_hz_table[t][0]; + *val2 = adxrs290_lpf_3db_freq_hz_table[t][1]; + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY: + switch (chan->type) { + case IIO_ANGL_VEL: + t = st->hpf_3db_freq_idx; + *val = adxrs290_hpf_3db_freq_hz_table[t][0]; + *val2 = adxrs290_hpf_3db_freq_hz_table[t][1]; + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } + } + + return -EINVAL; +} + +static int adxrs290_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) +{ + struct adxrs290_state *st = iio_priv(indio_dev); + int lpf_idx, hpf_idx; + + switch (mask) { + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: + lpf_idx = adxrs290_find_match(adxrs290_lpf_3db_freq_hz_table, + ARRAY_SIZE(adxrs290_lpf_3db_freq_hz_table), + val, val2); + if (lpf_idx < 0) + return -EINVAL; + /* caching the updated state of the low-pass filter */ + st->lpf_3db_freq_idx = lpf_idx; + /* retrieving the current state of the high-pass filter */ + hpf_idx = st->hpf_3db_freq_idx; + return adxrs290_set_filter_freq(indio_dev, lpf_idx, hpf_idx); + case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY: + hpf_idx = adxrs290_find_match(adxrs290_hpf_3db_freq_hz_table, + ARRAY_SIZE(adxrs290_hpf_3db_freq_hz_table), + val, val2); + if (hpf_idx < 0) + return -EINVAL; + /* caching the updated state of the high-pass filter */ + st->hpf_3db_freq_idx = hpf_idx; + /* retrieving the current state of the low-pass filter */ + lpf_idx = st->lpf_3db_freq_idx; + return adxrs290_set_filter_freq(indio_dev, lpf_idx, hpf_idx); + } + + return -EINVAL; +} + +static int adxrs290_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: + *vals = (const int *)adxrs290_lpf_3db_freq_hz_table; + *type = IIO_VAL_INT_PLUS_MICRO; + /* Values are stored in a 2D matrix */ + *length = ARRAY_SIZE(adxrs290_lpf_3db_freq_hz_table) * 2; + + return IIO_AVAIL_LIST; + case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY: + *vals = (const int *)adxrs290_hpf_3db_freq_hz_table; + *type = IIO_VAL_INT_PLUS_MICRO; + /* Values are stored in a 2D matrix */ + *length = ARRAY_SIZE(adxrs290_hpf_3db_freq_hz_table) * 2; + + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } +} + +#define ADXRS290_ANGL_VEL_CHANNEL(reg, axis) { \ + .type = IIO_ANGL_VEL, \ + .address = reg, \ + .modified = 1, \ + .channel2 = IIO_MOD_##axis, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | \ + BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY), \ + .info_mask_shared_by_type_available = \ + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | \ + BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY), \ +} + +static const struct iio_chan_spec adxrs290_channels[] = { + ADXRS290_ANGL_VEL_CHANNEL(ADXRS290_REG_DATAX0, X), + ADXRS290_ANGL_VEL_CHANNEL(ADXRS290_REG_DATAY0, Y), + { + .type = IIO_TEMP, + .address = ADXRS290_REG_TEMP0, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), + }, +}; + +static const struct iio_info adxrs290_info = { + .read_raw = &adxrs290_read_raw, + .write_raw = &adxrs290_write_raw, + .read_avail = &adxrs290_read_avail, +}; + +static int adxrs290_probe(struct spi_device *spi) +{ + struct iio_dev *indio_dev; + struct adxrs290_state *st; + u8 val, val2; + int ret; + + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + st = iio_priv(indio_dev); + st->spi = spi; + + indio_dev->name = "adxrs290"; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = adxrs290_channels; + indio_dev->num_channels = ARRAY_SIZE(adxrs290_channels); + indio_dev->info = &adxrs290_info; + + mutex_init(&st->lock); + + val = spi_w8r8(spi, ADXRS290_READ_REG(ADXRS290_REG_ADI_ID)); + if (val != ADXRS290_ADI_ID) { + dev_err(&spi->dev, "Wrong ADI ID 0x%02x\n", val); + return -ENODEV; + } + + val = spi_w8r8(spi, ADXRS290_READ_REG(ADXRS290_REG_MEMS_ID)); + if (val != ADXRS290_MEMS_ID) { + dev_err(&spi->dev, "Wrong MEMS ID 0x%02x\n", val); + return -ENODEV; + } + + val = spi_w8r8(spi, ADXRS290_READ_REG(ADXRS290_REG_DEV_ID)); + if (val != ADXRS290_DEV_ID) { + dev_err(&spi->dev, "Wrong DEV ID 0x%02x\n", val); + return -ENODEV; + } + + /* default mode the gyroscope starts in */ + st->mode = ADXRS290_MODE_STANDBY; + + /* switch to measurement mode and switch on the temperature sensor */ + ret = adxrs290_initial_setup(indio_dev); + if (ret < 0) + return ret; + + /* max transition time to measurement mode */ + msleep(ADXRS290_MAX_TRANSITION_TIME_MS); + + ret = adxrs290_get_3db_freq(indio_dev, &val, &val2); + if (ret < 0) + return ret; + + st->lpf_3db_freq_idx = val; + st->hpf_3db_freq_idx = val2; + + return devm_iio_device_register(&spi->dev, indio_dev); +} + +static const struct of_device_id adxrs290_of_match[] = { + { .compatible = "adi,adxrs290" }, + { } +}; +MODULE_DEVICE_TABLE(of, adxrs290_of_match); + +static struct spi_driver adxrs290_driver = { + .driver = { + .name = "adxrs290", + .of_match_table = adxrs290_of_match, + }, + .probe = adxrs290_probe, +}; +module_spi_driver(adxrs290_driver); + +MODULE_AUTHOR("Nishant Malpani <nish.malpani25@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices ADXRS290 Gyroscope SPI driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/health/max30102.c b/drivers/iio/health/max30102.c index d9b2ed80882a..82f0040400a0 100644 --- a/drivers/iio/health/max30102.c +++ b/drivers/iio/health/max30102.c @@ -2,7 +2,7 @@ /* * max30102.c - Support for MAX30102 heart rate and pulse oximeter sensor * - * Copyright (C) 2017 Matt Ranostay <matt@ranostay.consulting> + * Copyright (C) 2017 Matt Ranostay <matt.ranostay@konsulko.com> * * Support for MAX30105 optical particle sensor * Copyright (C) 2017 Peter Meerwald-Stadler <pmeerw@pmeerw.net> @@ -632,6 +632,6 @@ static struct i2c_driver max30102_driver = { }; module_i2c_driver(max30102_driver); -MODULE_AUTHOR("Matt Ranostay <matt@ranostay.consulting>"); +MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>"); MODULE_DESCRIPTION("MAX30102 heart rate/pulse oximeter and MAX30105 particle sensor driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/iio/humidity/Kconfig b/drivers/iio/humidity/Kconfig index 6c5507a6cd74..6549fcf6db69 100644 --- a/drivers/iio/humidity/Kconfig +++ b/drivers/iio/humidity/Kconfig @@ -38,6 +38,16 @@ config HDC100X To compile this driver as a module, choose M here: the module will be called hdc100x. +config HDC2010 + tristate "TI HDC2010 relative humidity and temperature sensor" + depends on I2C + help + Say yes here to build support for the Texas Instruments + HDC2010 and HDC2080 relative humidity and temperature sensors. + + To compile this driver as a module, choose M here: the module + will be called hdc2010. + config HID_SENSOR_HUMIDITY tristate "HID Environmental humidity sensor" depends on HID_SENSOR_HUB diff --git a/drivers/iio/humidity/Makefile b/drivers/iio/humidity/Makefile index ae4204995017..f19ff3de97c5 100644 --- a/drivers/iio/humidity/Makefile +++ b/drivers/iio/humidity/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_AM2315) += am2315.o obj-$(CONFIG_DHT11) += dht11.o obj-$(CONFIG_HDC100X) += hdc100x.o +obj-$(CONFIG_HDC2010) += hdc2010.o obj-$(CONFIG_HID_SENSOR_HUMIDITY) += hid-sensor-humidity.o hts221-y := hts221_core.o \ diff --git a/drivers/iio/humidity/hdc2010.c b/drivers/iio/humidity/hdc2010.c new file mode 100644 index 000000000000..83f5b9f60780 --- /dev/null +++ b/drivers/iio/humidity/hdc2010.c @@ -0,0 +1,353 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * hdc2010.c - Support for the TI HDC2010 and HDC2080 + * temperature + relative humidity sensors + * + * Copyright (C) 2020 Norphonic AS + * Author: Eugene Zaikonnikov <ez@norphonic.com> + * + * Datasheet: https://www.ti.com/product/HDC2010/datasheet + * Datasheet: https://www.ti.com/product/HDC2080/datasheet + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/i2c.h> +#include <linux/bitops.h> + +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> + +#define HDC2010_REG_TEMP_LOW 0x00 +#define HDC2010_REG_TEMP_HIGH 0x01 +#define HDC2010_REG_HUMIDITY_LOW 0x02 +#define HDC2010_REG_HUMIDITY_HIGH 0x03 +#define HDC2010_REG_INTERRUPT_DRDY 0x04 +#define HDC2010_REG_TEMP_MAX 0x05 +#define HDC2010_REG_HUMIDITY_MAX 0x06 +#define HDC2010_REG_INTERRUPT_EN 0x07 +#define HDC2010_REG_TEMP_OFFSET_ADJ 0x08 +#define HDC2010_REG_HUMIDITY_OFFSET_ADJ 0x09 +#define HDC2010_REG_TEMP_THR_L 0x0a +#define HDC2010_REG_TEMP_THR_H 0x0b +#define HDC2010_REG_RH_THR_L 0x0c +#define HDC2010_REG_RH_THR_H 0x0d +#define HDC2010_REG_RESET_DRDY_INT_CONF 0x0e +#define HDC2010_REG_MEASUREMENT_CONF 0x0f + +#define HDC2010_MEAS_CONF GENMASK(2, 1) +#define HDC2010_MEAS_TRIG BIT(0) +#define HDC2010_HEATER_EN BIT(3) +#define HDC2010_AMM GENMASK(6, 4) + +struct hdc2010_data { + struct i2c_client *client; + struct mutex lock; + u8 measurement_config; + u8 interrupt_config; + u8 drdy_config; +}; + +enum hdc2010_addr_groups { + HDC2010_GROUP_TEMP = 0, + HDC2010_GROUP_HUMIDITY, +}; + +struct hdc2010_reg_record { + unsigned long primary; + unsigned long peak; +}; + +static const struct hdc2010_reg_record hdc2010_reg_translation[] = { + [HDC2010_GROUP_TEMP] = { + .primary = HDC2010_REG_TEMP_LOW, + .peak = HDC2010_REG_TEMP_MAX, + }, + [HDC2010_GROUP_HUMIDITY] = { + .primary = HDC2010_REG_HUMIDITY_LOW, + .peak = HDC2010_REG_HUMIDITY_MAX, + }, +}; + +static IIO_CONST_ATTR(out_current_heater_raw_available, "0 1"); + +static struct attribute *hdc2010_attributes[] = { + &iio_const_attr_out_current_heater_raw_available.dev_attr.attr, + NULL +}; + +static const struct attribute_group hdc2010_attribute_group = { + .attrs = hdc2010_attributes, +}; + +static const struct iio_chan_spec hdc2010_channels[] = { + { + .type = IIO_TEMP, + .address = HDC2010_GROUP_TEMP, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_PEAK) | + BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE), + }, + { + .type = IIO_HUMIDITYRELATIVE, + .address = HDC2010_GROUP_HUMIDITY, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_PEAK) | + BIT(IIO_CHAN_INFO_SCALE), + }, + { + .type = IIO_CURRENT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .extend_name = "heater", + .output = 1, + }, +}; + +static int hdc2010_update_drdy_config(struct hdc2010_data *data, + char mask, char val) +{ + u8 tmp = (~mask & data->drdy_config) | val; + int ret; + + ret = i2c_smbus_write_byte_data(data->client, + HDC2010_REG_RESET_DRDY_INT_CONF, tmp); + if (ret) + return ret; + + data->drdy_config = tmp; + + return 0; +} + +static int hdc2010_get_prim_measurement_word(struct hdc2010_data *data, + struct iio_chan_spec const *chan) +{ + struct i2c_client *client = data->client; + s32 ret; + + ret = i2c_smbus_read_word_data(client, + hdc2010_reg_translation[chan->address].primary); + + if (ret < 0) + dev_err(&client->dev, "Could not read sensor measurement word\n"); + + return ret; +} + +static int hdc2010_get_peak_measurement_byte(struct hdc2010_data *data, + struct iio_chan_spec const *chan) +{ + struct i2c_client *client = data->client; + s32 ret; + + ret = i2c_smbus_read_byte_data(client, + hdc2010_reg_translation[chan->address].peak); + + if (ret < 0) + dev_err(&client->dev, "Could not read sensor measurement byte\n"); + + return ret; +} + +static int hdc2010_get_heater_status(struct hdc2010_data *data) +{ + return !!(data->drdy_config & HDC2010_HEATER_EN); +} + +static int hdc2010_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, + int *val2, long mask) +{ + struct hdc2010_data *data = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_RAW: { + int ret; + + if (chan->type == IIO_CURRENT) { + *val = hdc2010_get_heater_status(data); + return IIO_VAL_INT; + } + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + mutex_lock(&data->lock); + ret = hdc2010_get_prim_measurement_word(data, chan); + mutex_unlock(&data->lock); + iio_device_release_direct_mode(indio_dev); + if (ret < 0) + return ret; + *val = ret; + return IIO_VAL_INT; + } + case IIO_CHAN_INFO_PEAK: { + int ret; + + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + mutex_lock(&data->lock); + ret = hdc2010_get_peak_measurement_byte(data, chan); + mutex_unlock(&data->lock); + iio_device_release_direct_mode(indio_dev); + if (ret < 0) + return ret; + /* Scaling up the value so we can use same offset as RAW */ + *val = ret * 256; + return IIO_VAL_INT; + } + case IIO_CHAN_INFO_SCALE: + *val2 = 65536; + if (chan->type == IIO_TEMP) + *val = 165000; + else + *val = 100000; + return IIO_VAL_FRACTIONAL; + case IIO_CHAN_INFO_OFFSET: + *val = -15887; + *val2 = 515151; + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } +} + +static int hdc2010_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct hdc2010_data *data = iio_priv(indio_dev); + int new, ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + if (chan->type != IIO_CURRENT || val2 != 0) + return -EINVAL; + + switch (val) { + case 1: + new = HDC2010_HEATER_EN; + break; + case 0: + new = 0; + break; + default: + return -EINVAL; + } + + mutex_lock(&data->lock); + ret = hdc2010_update_drdy_config(data, HDC2010_HEATER_EN, new); + mutex_unlock(&data->lock); + return ret; + default: + return -EINVAL; + } +} + +static const struct iio_info hdc2010_info = { + .read_raw = hdc2010_read_raw, + .write_raw = hdc2010_write_raw, + .attrs = &hdc2010_attribute_group, +}; + +static int hdc2010_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct iio_dev *indio_dev; + struct hdc2010_data *data; + u8 tmp; + int ret; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C)) + return -EOPNOTSUPP; + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + data = iio_priv(indio_dev); + i2c_set_clientdata(client, indio_dev); + data->client = client; + mutex_init(&data->lock); + + indio_dev->dev.parent = &client->dev; + /* + * As DEVICE ID register does not differentiate between + * HDC2010 and HDC2080, we have the name hardcoded + */ + indio_dev->name = "hdc2010"; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &hdc2010_info; + + indio_dev->channels = hdc2010_channels; + indio_dev->num_channels = ARRAY_SIZE(hdc2010_channels); + + /* Enable Automatic Measurement Mode at 5Hz */ + ret = hdc2010_update_drdy_config(data, HDC2010_AMM, HDC2010_AMM); + if (ret) + return ret; + + /* + * We enable both temp and humidity measurement. + * However the measurement won't start even in AMM until triggered. + */ + tmp = (data->measurement_config & ~HDC2010_MEAS_CONF) | + HDC2010_MEAS_TRIG; + + ret = i2c_smbus_write_byte_data(client, HDC2010_REG_MEASUREMENT_CONF, tmp); + if (ret) { + dev_warn(&client->dev, "Unable to set up measurement\n"); + if (hdc2010_update_drdy_config(data, HDC2010_AMM, 0)) + dev_warn(&client->dev, "Unable to restore default AMM\n"); + return ret; + } + + data->measurement_config = tmp; + + return iio_device_register(indio_dev); +} + +static int hdc2010_remove(struct i2c_client *client) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct hdc2010_data *data = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + + /* Disable Automatic Measurement Mode */ + if (hdc2010_update_drdy_config(data, HDC2010_AMM, 0)) + dev_warn(&client->dev, "Unable to restore default AMM\n"); + + return 0; +} + +static const struct i2c_device_id hdc2010_id[] = { + { "hdc2010" }, + { "hdc2080" }, + { } +}; +MODULE_DEVICE_TABLE(i2c, hdc2010_id); + +static const struct of_device_id hdc2010_dt_ids[] = { + { .compatible = "ti,hdc2010" }, + { .compatible = "ti,hdc2080" }, + { } +}; +MODULE_DEVICE_TABLE(of, hdc2010_dt_ids); + +static struct i2c_driver hdc2010_driver = { + .driver = { + .name = "hdc2010", + .of_match_table = hdc2010_dt_ids, + }, + .probe = hdc2010_probe, + .remove = hdc2010_remove, + .id_table = hdc2010_id, +}; +module_i2c_driver(hdc2010_driver); + +MODULE_AUTHOR("Eugene Zaikonnikov <ez@norphonic.com>"); +MODULE_DESCRIPTION("TI HDC2010 humidity and temperature sensor driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/iio_core_trigger.h b/drivers/iio/iio_core_trigger.h index 9d1a92cc6480..374816bc3e73 100644 --- a/drivers/iio/iio_core_trigger.h +++ b/drivers/iio/iio_core_trigger.h @@ -30,7 +30,7 @@ int iio_trigger_detach_poll_func(struct iio_trigger *trig, * iio_device_register_trigger_consumer() - set up an iio_dev to use triggers * @indio_dev: iio_dev associated with the device that will consume the trigger **/ -static int iio_device_register_trigger_consumer(struct iio_dev *indio_dev) +static inline int iio_device_register_trigger_consumer(struct iio_dev *indio_dev) { return 0; } @@ -39,7 +39,7 @@ static int iio_device_register_trigger_consumer(struct iio_dev *indio_dev) * iio_device_unregister_trigger_consumer() - reverse the registration process * @indio_dev: iio_dev associated with the device that consumed the trigger **/ -static void iio_device_unregister_trigger_consumer(struct iio_dev *indio_dev) +static inline void iio_device_unregister_trigger_consumer(struct iio_dev *indio_dev) { } diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index 3fee3947f772..18a1898e3e34 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -1475,22 +1475,14 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name, } st->vdd_supply = devm_regulator_get(dev, "vdd"); - if (IS_ERR(st->vdd_supply)) { - if (PTR_ERR(st->vdd_supply) != -EPROBE_DEFER) - dev_err(dev, "Failed to get vdd regulator %d\n", - (int)PTR_ERR(st->vdd_supply)); - - return PTR_ERR(st->vdd_supply); - } + if (IS_ERR(st->vdd_supply)) + return dev_err_probe(dev, PTR_ERR(st->vdd_supply), + "Failed to get vdd regulator\n"); st->vddio_supply = devm_regulator_get(dev, "vddio"); - if (IS_ERR(st->vddio_supply)) { - if (PTR_ERR(st->vddio_supply) != -EPROBE_DEFER) - dev_err(dev, "Failed to get vddio regulator %d\n", - (int)PTR_ERR(st->vddio_supply)); - - return PTR_ERR(st->vddio_supply); - } + if (IS_ERR(st->vddio_supply)) + return dev_err_probe(dev, PTR_ERR(st->vddio_supply), + "Failed to get vddio regulator\n"); result = regulator_enable(st->vdd_supply); if (result) { diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index cdcd16f19500..d882c7f31ba9 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -133,6 +133,7 @@ static const char * const iio_modifier_names[] = { [IIO_MOD_PM10] = "pm10", [IIO_MOD_ETHANOL] = "ethanol", [IIO_MOD_H2] = "h2", + [IIO_MOD_O2] = "o2", }; /* relies on pairs of these shared then separate */ diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig index 182bd18c4bb2..cade6dc0305b 100644 --- a/drivers/iio/light/Kconfig +++ b/drivers/iio/light/Kconfig @@ -86,6 +86,21 @@ config APDS9960 To compile this driver as a module, choose M here: the module will be called apds9960 +config AS73211 + tristate "AMS AS73211 XYZ color sensor" + depends on I2C + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + help + If you say yes here you get support for the AMS AS73211 + JENCOLOR(R) Digital XYZ Sensor. + + For triggered measurements, you will need an additional trigger driver + like IIO_HRTIMER_TRIGGER or IIO_SYSFS_TRIGGER. + + This driver can also be built as a module. If so, the module + will be called as73211. + config BH1750 tristate "ROHM BH1750 ambient light sensor" depends on I2C diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile index d1c8aa30b9a8..ea376deaca54 100644 --- a/drivers/iio/light/Makefile +++ b/drivers/iio/light/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_AL3010) += al3010.o obj-$(CONFIG_AL3320A) += al3320a.o obj-$(CONFIG_APDS9300) += apds9300.o obj-$(CONFIG_APDS9960) += apds9960.o +obj-$(CONFIG_AS73211) += as73211.o obj-$(CONFIG_BH1750) += bh1750.o obj-$(CONFIG_BH1780) += bh1780.o obj-$(CONFIG_CM32181) += cm32181.o diff --git a/drivers/iio/light/as73211.c b/drivers/iio/light/as73211.c new file mode 100644 index 000000000000..b1178dfc1f65 --- /dev/null +++ b/drivers/iio/light/as73211.c @@ -0,0 +1,801 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Support for AMS AS73211 JENCOLOR(R) Digital XYZ Sensor + * + * Author: Christian Eggers <ceggers@arri.de> + * + * Copyright (c) 2020 ARRI Lighting + * + * Color light sensor with 16-bit channels for x, y, z and temperature); + * 7-bit I2C slave address 0x74 .. 0x77. + * + * Datasheet: https://ams.com/documents/20143/36005/AS73211_DS000556_3-01.pdf + */ + +#include <linux/bitfield.h> +#include <linux/completion.h> +#include <linux/delay.h> +#include <linux/i2c.h> +#include <linux/iio/buffer.h> +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/trigger_consumer.h> +#include <linux/iio/triggered_buffer.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/pm.h> + +#define HZ_PER_KHZ 1000 + +#define AS73211_DRV_NAME "as73211" + +/* AS73211 configuration registers */ +#define AS73211_REG_OSR 0x0 +#define AS73211_REG_AGEN 0x2 +#define AS73211_REG_CREG1 0x6 +#define AS73211_REG_CREG2 0x7 +#define AS73211_REG_CREG3 0x8 + +/* AS73211 output register bank */ +#define AS73211_OUT_OSR_STATUS 0 +#define AS73211_OUT_TEMP 1 +#define AS73211_OUT_MRES1 2 +#define AS73211_OUT_MRES2 3 +#define AS73211_OUT_MRES3 4 + +#define AS73211_OSR_SS BIT(7) +#define AS73211_OSR_PD BIT(6) +#define AS73211_OSR_SW_RES BIT(3) +#define AS73211_OSR_DOS_MASK GENMASK(2, 0) +#define AS73211_OSR_DOS_CONFIG FIELD_PREP(AS73211_OSR_DOS_MASK, 0x2) +#define AS73211_OSR_DOS_MEASURE FIELD_PREP(AS73211_OSR_DOS_MASK, 0x3) + +#define AS73211_AGEN_DEVID_MASK GENMASK(7, 4) +#define AS73211_AGEN_DEVID(x) FIELD_PREP(AS73211_AGEN_DEVID_MASK, (x)) +#define AS73211_AGEN_MUT_MASK GENMASK(3, 0) +#define AS73211_AGEN_MUT(x) FIELD_PREP(AS73211_AGEN_MUT_MASK, (x)) + +#define AS73211_CREG1_GAIN_MASK GENMASK(7, 4) +#define AS73211_CREG1_GAIN_1 11 +#define AS73211_CREG1_TIME_MASK GENMASK(3, 0) + +#define AS73211_CREG3_CCLK_MASK GENMASK(1, 0) + +#define AS73211_OSR_STATUS_OUTCONVOF BIT(15) +#define AS73211_OSR_STATUS_MRESOF BIT(14) +#define AS73211_OSR_STATUS_ADCOF BIT(13) +#define AS73211_OSR_STATUS_LDATA BIT(12) +#define AS73211_OSR_STATUS_NDATA BIT(11) +#define AS73211_OSR_STATUS_NOTREADY BIT(10) + +#define AS73211_SAMPLE_FREQ_BASE 1024000 + +#define AS73211_SAMPLE_TIME_NUM 15 +#define AS73211_SAMPLE_TIME_MAX_MS BIT(AS73211_SAMPLE_TIME_NUM - 1) + +/* Available sample frequencies are 1.024MHz multiplied by powers of two. */ +static const int as73211_samp_freq_avail[] = { + AS73211_SAMPLE_FREQ_BASE * 1, + AS73211_SAMPLE_FREQ_BASE * 2, + AS73211_SAMPLE_FREQ_BASE * 4, + AS73211_SAMPLE_FREQ_BASE * 8, +}; + +static const int as73211_hardwaregain_avail[] = { + 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, +}; + +/** + * struct as73211_data - Instance data for one AS73211 + * @client: I2C client. + * @osr: Cached Operational State Register. + * @creg1: Cached Configuration Register 1. + * @creg2: Cached Configuration Register 2. + * @creg3: Cached Configuration Register 3. + * @mutex: Keeps cached registers in sync with the device. + * @completion: Completion to wait for interrupt. + * @int_time_avail: Available integration times (depend on sampling frequency). + */ +struct as73211_data { + struct i2c_client *client; + u8 osr; + u8 creg1; + u8 creg2; + u8 creg3; + struct mutex mutex; + struct completion completion; + int int_time_avail[AS73211_SAMPLE_TIME_NUM * 2]; +}; + +#define AS73211_COLOR_CHANNEL(_color, _si, _addr) { \ + .type = IIO_INTENSITY, \ + .modified = 1, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_type = \ + BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ + BIT(IIO_CHAN_INFO_HARDWAREGAIN) | \ + BIT(IIO_CHAN_INFO_INT_TIME), \ + .info_mask_shared_by_type_available = \ + BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ + BIT(IIO_CHAN_INFO_HARDWAREGAIN) | \ + BIT(IIO_CHAN_INFO_INT_TIME), \ + .channel2 = IIO_MOD_##_color, \ + .address = _addr, \ + .scan_index = _si, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 16, \ + .storagebits = 16, \ + .endianness = IIO_LE, \ + }, \ +} + +#define AS73211_OFFSET_TEMP_INT (-66) +#define AS73211_OFFSET_TEMP_MICRO 900000 +#define AS73211_SCALE_TEMP_INT 0 +#define AS73211_SCALE_TEMP_MICRO 50000 + +#define AS73211_SCALE_X 277071108 /* nW/m^2 */ +#define AS73211_SCALE_Y 298384270 /* nW/m^2 */ +#define AS73211_SCALE_Z 160241927 /* nW/m^2 */ + +/* Channel order MUST match devices result register order */ +#define AS73211_SCAN_INDEX_TEMP 0 +#define AS73211_SCAN_INDEX_X 1 +#define AS73211_SCAN_INDEX_Y 2 +#define AS73211_SCAN_INDEX_Z 3 +#define AS73211_SCAN_INDEX_TS 4 + +#define AS73211_SCAN_MASK_COLOR ( \ + BIT(AS73211_SCAN_INDEX_X) | \ + BIT(AS73211_SCAN_INDEX_Y) | \ + BIT(AS73211_SCAN_INDEX_Z)) + +#define AS73211_SCAN_MASK_ALL ( \ + BIT(AS73211_SCAN_INDEX_TEMP) | \ + AS73211_SCAN_MASK_COLOR) + +static const struct iio_chan_spec as73211_channels[] = { + { + .type = IIO_TEMP, + .info_mask_separate = + BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE), + .address = AS73211_OUT_TEMP, + .scan_index = AS73211_SCAN_INDEX_TEMP, + .scan_type = { + .sign = 'u', + .realbits = 16, + .storagebits = 16, + .endianness = IIO_LE, + } + }, + AS73211_COLOR_CHANNEL(X, AS73211_SCAN_INDEX_X, AS73211_OUT_MRES1), + AS73211_COLOR_CHANNEL(Y, AS73211_SCAN_INDEX_Y, AS73211_OUT_MRES2), + AS73211_COLOR_CHANNEL(Z, AS73211_SCAN_INDEX_Z, AS73211_OUT_MRES3), + IIO_CHAN_SOFT_TIMESTAMP(AS73211_SCAN_INDEX_TS), +}; + +static unsigned int as73211_integration_time_1024cyc(struct as73211_data *data) +{ + /* + * Return integration time in units of 1024 clock cycles. Integration time + * in CREG1 is in powers of 2 (x 1024 cycles). + */ + return BIT(FIELD_GET(AS73211_CREG1_TIME_MASK, data->creg1)); +} + +static unsigned int as73211_integration_time_us(struct as73211_data *data, + unsigned int integration_time_1024cyc) +{ + /* + * f_samp is configured in CREG3 in powers of 2 (x 1.024 MHz) + * t_cycl is configured in CREG1 in powers of 2 (x 1024 cycles) + * t_int_us = 1 / (f_samp) * t_cycl * US_PER_SEC + * = 1 / (2^CREG3_CCLK * 1,024,000) * 2^CREG1_CYCLES * 1,024 * US_PER_SEC + * = 2^(-CREG3_CCLK) * 2^CREG1_CYCLES * 1,000 + * In order to get rid of negative exponents, we extend the "fraction" + * by 2^3 (CREG3_CCLK,max = 3) + * t_int_us = 2^(3-CREG3_CCLK) * 2^CREG1_CYCLES * 125 + */ + return BIT(3 - FIELD_GET(AS73211_CREG3_CCLK_MASK, data->creg3)) * + integration_time_1024cyc * 125; +} + +static void as73211_integration_time_calc_avail(struct as73211_data *data) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(data->int_time_avail) / 2; i++) { + unsigned int time_us = as73211_integration_time_us(data, BIT(i)); + + data->int_time_avail[i * 2 + 0] = time_us / USEC_PER_SEC; + data->int_time_avail[i * 2 + 1] = time_us % USEC_PER_SEC; + } +} + +static unsigned int as73211_gain(struct as73211_data *data) +{ + /* gain can be calculated from CREG1 as 2^(11 - CREG1_GAIN) */ + return BIT(AS73211_CREG1_GAIN_1 - FIELD_GET(AS73211_CREG1_GAIN_MASK, data->creg1)); +} + +/* must be called with as73211_data::mutex held. */ +static int as73211_req_data(struct as73211_data *data) +{ + unsigned int time_us = as73211_integration_time_us(data, + as73211_integration_time_1024cyc(data)); + struct device *dev = &data->client->dev; + union i2c_smbus_data smbus_data; + u16 osr_status; + int ret; + + if (data->client->irq) + reinit_completion(&data->completion); + + /* + * During measurement, there should be no traffic on the i2c bus as the + * electrical noise would disturb the measurement process. + */ + i2c_lock_bus(data->client->adapter, I2C_LOCK_SEGMENT); + + data->osr &= ~AS73211_OSR_DOS_MASK; + data->osr |= AS73211_OSR_DOS_MEASURE | AS73211_OSR_SS; + + smbus_data.byte = data->osr; + ret = __i2c_smbus_xfer(data->client->adapter, data->client->addr, + data->client->flags, I2C_SMBUS_WRITE, + AS73211_REG_OSR, I2C_SMBUS_BYTE_DATA, &smbus_data); + if (ret < 0) { + i2c_unlock_bus(data->client->adapter, I2C_LOCK_SEGMENT); + return ret; + } + + /* + * Reset AS73211_OSR_SS (is self clearing) in order to avoid unintentional + * triggering of further measurements later. + */ + data->osr &= ~AS73211_OSR_SS; + + /* + * Add some extra margin for the timeout. sensor timing is not as precise + * as our one ... + */ + time_us += time_us / 8; + if (data->client->irq) { + ret = wait_for_completion_timeout(&data->completion, usecs_to_jiffies(time_us)); + if (!ret) { + dev_err(dev, "timeout waiting for READY IRQ\n"); + i2c_unlock_bus(data->client->adapter, I2C_LOCK_SEGMENT); + return -ETIMEDOUT; + } + } else { + /* Wait integration time */ + usleep_range(time_us, 2 * time_us); + } + + i2c_unlock_bus(data->client->adapter, I2C_LOCK_SEGMENT); + + ret = i2c_smbus_read_word_data(data->client, AS73211_OUT_OSR_STATUS); + if (ret < 0) + return ret; + + osr_status = ret; + if (osr_status != (AS73211_OSR_DOS_MEASURE | AS73211_OSR_STATUS_NDATA)) { + if (osr_status & AS73211_OSR_SS) { + dev_err(dev, "%s() Measurement has not stopped\n", __func__); + return -ETIME; + } + if (osr_status & AS73211_OSR_STATUS_NOTREADY) { + dev_err(dev, "%s() Data is not ready\n", __func__); + return -ENODATA; + } + if (!(osr_status & AS73211_OSR_STATUS_NDATA)) { + dev_err(dev, "%s() No new data available\n", __func__); + return -ENODATA; + } + if (osr_status & AS73211_OSR_STATUS_LDATA) { + dev_err(dev, "%s() Result buffer overrun\n", __func__); + return -ENOBUFS; + } + if (osr_status & AS73211_OSR_STATUS_ADCOF) { + dev_err(dev, "%s() ADC overflow\n", __func__); + return -EOVERFLOW; + } + if (osr_status & AS73211_OSR_STATUS_MRESOF) { + dev_err(dev, "%s() Measurement result overflow\n", __func__); + return -EOVERFLOW; + } + if (osr_status & AS73211_OSR_STATUS_OUTCONVOF) { + dev_err(dev, "%s() Timer overflow\n", __func__); + return -EOVERFLOW; + } + dev_err(dev, "%s() Unexpected status value\n", __func__); + return -EIO; + } + + return 0; +} + +static int as73211_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct as73211_data *data = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_RAW: { + int ret; + + ret = iio_device_claim_direct_mode(indio_dev); + if (ret < 0) + return ret; + + ret = as73211_req_data(data); + if (ret < 0) { + iio_device_release_direct_mode(indio_dev); + return ret; + } + + ret = i2c_smbus_read_word_data(data->client, chan->address); + iio_device_release_direct_mode(indio_dev); + if (ret < 0) + return ret; + + *val = ret; + return IIO_VAL_INT; + } + case IIO_CHAN_INFO_OFFSET: + *val = AS73211_OFFSET_TEMP_INT; + *val2 = AS73211_OFFSET_TEMP_MICRO; + return IIO_VAL_INT_PLUS_MICRO; + + case IIO_CHAN_INFO_SCALE: + switch (chan->type) { + case IIO_TEMP: + *val = AS73211_SCALE_TEMP_INT; + *val2 = AS73211_SCALE_TEMP_MICRO; + return IIO_VAL_INT_PLUS_MICRO; + + case IIO_INTENSITY: { + unsigned int scale; + + switch (chan->channel2) { + case IIO_MOD_X: + scale = AS73211_SCALE_X; + break; + case IIO_MOD_Y: + scale = AS73211_SCALE_Y; + break; + case IIO_MOD_Z: + scale = AS73211_SCALE_Z; + break; + default: + return -EINVAL; + } + scale /= as73211_gain(data); + scale /= as73211_integration_time_1024cyc(data); + *val = scale; + return IIO_VAL_INT; + + default: + return -EINVAL; + }} + + case IIO_CHAN_INFO_SAMP_FREQ: + /* f_samp is configured in CREG3 in powers of 2 (x 1.024 MHz) */ + *val = BIT(FIELD_GET(AS73211_CREG3_CCLK_MASK, data->creg3)) * + AS73211_SAMPLE_FREQ_BASE; + return IIO_VAL_INT; + + case IIO_CHAN_INFO_HARDWAREGAIN: + *val = as73211_gain(data); + return IIO_VAL_INT; + + case IIO_CHAN_INFO_INT_TIME: { + unsigned int time_us; + + mutex_lock(&data->mutex); + time_us = as73211_integration_time_us(data, as73211_integration_time_1024cyc(data)); + mutex_unlock(&data->mutex); + *val = time_us / USEC_PER_SEC; + *val2 = time_us % USEC_PER_SEC; + return IIO_VAL_INT_PLUS_MICRO; + + default: + return -EINVAL; + }} +} + +static int as73211_read_avail(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, long mask) +{ + struct as73211_data *data = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + *length = ARRAY_SIZE(as73211_samp_freq_avail); + *vals = as73211_samp_freq_avail; + *type = IIO_VAL_INT; + return IIO_AVAIL_LIST; + + case IIO_CHAN_INFO_HARDWAREGAIN: + *length = ARRAY_SIZE(as73211_hardwaregain_avail); + *vals = as73211_hardwaregain_avail; + *type = IIO_VAL_INT; + return IIO_AVAIL_LIST; + + case IIO_CHAN_INFO_INT_TIME: + *length = ARRAY_SIZE(data->int_time_avail); + *vals = data->int_time_avail; + *type = IIO_VAL_INT_PLUS_MICRO; + return IIO_AVAIL_LIST; + + default: + return -EINVAL; + } +} + +static int _as73211_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan __always_unused, + int val, int val2, long mask) +{ + struct as73211_data *data = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: { + int reg_bits, freq_kHz = val / HZ_PER_KHZ; /* 1024, 2048, ... */ + + /* val must be 1024 * 2^x */ + if (val < 0 || (freq_kHz * HZ_PER_KHZ) != val || + !is_power_of_2(freq_kHz) || val2) + return -EINVAL; + + /* f_samp is configured in CREG3 in powers of 2 (x 1.024 MHz (=2^10)) */ + reg_bits = ilog2(freq_kHz) - 10; + if (!FIELD_FIT(AS73211_CREG3_CCLK_MASK, reg_bits)) + return -EINVAL; + + data->creg3 &= ~AS73211_CREG3_CCLK_MASK; + data->creg3 |= FIELD_PREP(AS73211_CREG3_CCLK_MASK, reg_bits); + as73211_integration_time_calc_avail(data); + + ret = i2c_smbus_write_byte_data(data->client, AS73211_REG_CREG3, data->creg3); + if (ret < 0) + return ret; + + return 0; + } + case IIO_CHAN_INFO_HARDWAREGAIN: { + unsigned int reg_bits; + + if (val < 0 || !is_power_of_2(val) || val2) + return -EINVAL; + + /* gain can be calculated from CREG1 as 2^(11 - CREG1_GAIN) */ + reg_bits = AS73211_CREG1_GAIN_1 - ilog2(val); + if (!FIELD_FIT(AS73211_CREG1_GAIN_MASK, reg_bits)) + return -EINVAL; + + data->creg1 &= ~AS73211_CREG1_GAIN_MASK; + data->creg1 |= FIELD_PREP(AS73211_CREG1_GAIN_MASK, reg_bits); + + ret = i2c_smbus_write_byte_data(data->client, AS73211_REG_CREG1, data->creg1); + if (ret < 0) + return ret; + + return 0; + } + case IIO_CHAN_INFO_INT_TIME: { + int val_us = val * USEC_PER_SEC + val2; + int time_ms; + int reg_bits; + + /* f_samp is configured in CREG3 in powers of 2 (x 1.024 MHz) */ + int f_samp_1_024mhz = BIT(FIELD_GET(AS73211_CREG3_CCLK_MASK, data->creg3)); + + /* + * time_ms = time_us * US_PER_MS * f_samp_1_024mhz / MHZ_PER_HZ + * = time_us * f_samp_1_024mhz / 1000 + */ + time_ms = (val_us * f_samp_1_024mhz) / 1000; /* 1 ms, 2 ms, ... (power of two) */ + if (time_ms < 0 || !is_power_of_2(time_ms) || time_ms > AS73211_SAMPLE_TIME_MAX_MS) + return -EINVAL; + + reg_bits = ilog2(time_ms); + if (!FIELD_FIT(AS73211_CREG1_TIME_MASK, reg_bits)) + return -EINVAL; /* not possible due to previous tests */ + + data->creg1 &= ~AS73211_CREG1_TIME_MASK; + data->creg1 |= FIELD_PREP(AS73211_CREG1_TIME_MASK, reg_bits); + + ret = i2c_smbus_write_byte_data(data->client, AS73211_REG_CREG1, data->creg1); + if (ret < 0) + return ret; + + return 0; + + default: + return -EINVAL; + }} +} + +static int as73211_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct as73211_data *data = iio_priv(indio_dev); + int ret; + + mutex_lock(&data->mutex); + + ret = iio_device_claim_direct_mode(indio_dev); + if (ret < 0) + goto error_unlock; + + /* Need to switch to config mode ... */ + if ((data->osr & AS73211_OSR_DOS_MASK) != AS73211_OSR_DOS_CONFIG) { + data->osr &= ~AS73211_OSR_DOS_MASK; + data->osr |= AS73211_OSR_DOS_CONFIG; + + ret = i2c_smbus_write_byte_data(data->client, AS73211_REG_OSR, data->osr); + if (ret < 0) + goto error_release; + } + + ret = _as73211_write_raw(indio_dev, chan, val, val2, mask); + +error_release: + iio_device_release_direct_mode(indio_dev); +error_unlock: + mutex_unlock(&data->mutex); + return ret; +} + +static irqreturn_t as73211_ready_handler(int irq __always_unused, void *priv) +{ + struct as73211_data *data = iio_priv(priv); + + complete(&data->completion); + + return IRQ_HANDLED; +} + +static irqreturn_t as73211_trigger_handler(int irq __always_unused, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct as73211_data *data = iio_priv(indio_dev); + struct { + __le16 chan[4]; + s64 ts __aligned(8); + } scan; + int data_result, ret; + + mutex_lock(&data->mutex); + + data_result = as73211_req_data(data); + if (data_result < 0 && data_result != -EOVERFLOW) + goto done; /* don't push any data for errors other than EOVERFLOW */ + + if (*indio_dev->active_scan_mask == AS73211_SCAN_MASK_ALL) { + /* Optimization for reading all (color + temperature) channels */ + u8 addr = as73211_channels[0].address; + struct i2c_msg msgs[] = { + { + .addr = data->client->addr, + .flags = 0, + .len = 1, + .buf = &addr, + }, + { + .addr = data->client->addr, + .flags = I2C_M_RD, + .len = sizeof(scan.chan), + .buf = (u8 *)&scan.chan, + }, + }; + + ret = i2c_transfer(data->client->adapter, msgs, ARRAY_SIZE(msgs)); + if (ret < 0) + goto done; + } else { + /* Optimization for reading only color channels */ + + /* AS73211 starts reading at address 2 */ + ret = i2c_master_recv(data->client, + (char *)&scan.chan[1], 3 * sizeof(scan.chan[1])); + if (ret < 0) + goto done; + } + + if (data_result) { + /* + * Saturate all channels (in case of overflows). Temperature channel + * is not affected by overflows. + */ + scan.chan[1] = cpu_to_le16(U16_MAX); + scan.chan[2] = cpu_to_le16(U16_MAX); + scan.chan[3] = cpu_to_le16(U16_MAX); + } + + iio_push_to_buffers_with_timestamp(indio_dev, &scan, iio_get_time_ns(indio_dev)); + +done: + mutex_unlock(&data->mutex); + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +static const struct iio_info as73211_info = { + .read_raw = as73211_read_raw, + .read_avail = as73211_read_avail, + .write_raw = as73211_write_raw, +}; + +static int as73211_power(struct iio_dev *indio_dev, bool state) +{ + struct as73211_data *data = iio_priv(indio_dev); + int ret; + + mutex_lock(&data->mutex); + + if (state) + data->osr &= ~AS73211_OSR_PD; + else + data->osr |= AS73211_OSR_PD; + + ret = i2c_smbus_write_byte_data(data->client, AS73211_REG_OSR, data->osr); + + mutex_unlock(&data->mutex); + + if (ret < 0) + return ret; + + return 0; +} + +static void as73211_power_disable(void *data) +{ + struct iio_dev *indio_dev = data; + + as73211_power(indio_dev, false); +} + +static int as73211_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct as73211_data *data; + struct iio_dev *indio_dev; + int ret; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + data = iio_priv(indio_dev); + i2c_set_clientdata(client, indio_dev); + data->client = client; + + mutex_init(&data->mutex); + init_completion(&data->completion); + + indio_dev->info = &as73211_info; + indio_dev->name = AS73211_DRV_NAME; + indio_dev->channels = as73211_channels; + indio_dev->num_channels = ARRAY_SIZE(as73211_channels); + indio_dev->modes = INDIO_DIRECT_MODE; + + ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_OSR); + if (ret < 0) + return ret; + data->osr = ret; + + /* reset device */ + data->osr |= AS73211_OSR_SW_RES; + ret = i2c_smbus_write_byte_data(data->client, AS73211_REG_OSR, data->osr); + if (ret < 0) + return ret; + + ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_OSR); + if (ret < 0) + return ret; + data->osr = ret; + + /* + * Reading AGEN is only possible after reset (AGEN is not available if + * device is in measurement mode). + */ + ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_AGEN); + if (ret < 0) + return ret; + + /* At the time of writing this driver, only DEVID 2 and MUT 1 are known. */ + if ((ret & AS73211_AGEN_DEVID_MASK) != AS73211_AGEN_DEVID(2) || + (ret & AS73211_AGEN_MUT_MASK) != AS73211_AGEN_MUT(1)) + return -ENODEV; + + ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_CREG1); + if (ret < 0) + return ret; + data->creg1 = ret; + + ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_CREG2); + if (ret < 0) + return ret; + data->creg2 = ret; + + ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_CREG3); + if (ret < 0) + return ret; + data->creg3 = ret; + as73211_integration_time_calc_avail(data); + + ret = as73211_power(indio_dev, true); + if (ret < 0) + return ret; + + ret = devm_add_action_or_reset(dev, as73211_power_disable, indio_dev); + if (ret) + return ret; + + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, as73211_trigger_handler, NULL); + if (ret) + return ret; + + if (client->irq) { + ret = devm_request_threaded_irq(&client->dev, client->irq, + NULL, + as73211_ready_handler, + IRQF_ONESHOT, + client->name, indio_dev); + if (ret) + return ret; + } + + return devm_iio_device_register(dev, indio_dev); +} + +static int __maybe_unused as73211_suspend(struct device *dev) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); + + return as73211_power(indio_dev, false); +} + +static int __maybe_unused as73211_resume(struct device *dev) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); + + return as73211_power(indio_dev, true); +} + +static SIMPLE_DEV_PM_OPS(as73211_pm_ops, as73211_suspend, as73211_resume); + +static const struct of_device_id as73211_of_match[] = { + { .compatible = "ams,as73211" }, + { } +}; +MODULE_DEVICE_TABLE(of, as73211_of_match); + +static const struct i2c_device_id as73211_id[] = { + { "as73211", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, as73211_id); + +static struct i2c_driver as73211_driver = { + .driver = { + .name = AS73211_DRV_NAME, + .of_match_table = as73211_of_match, + .pm = &as73211_pm_ops, + }, + .probe_new = as73211_probe, + .id_table = as73211_id, +}; +module_i2c_driver(as73211_driver); + +MODULE_AUTHOR("Christian Eggers <ceggers@arri.de>"); +MODULE_DESCRIPTION("AS73211 XYZ True Color Sensor driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/light/isl29018.c b/drivers/iio/light/isl29018.c index ac8ad0f32689..2689867467a8 100644 --- a/drivers/iio/light/isl29018.c +++ b/drivers/iio/light/isl29018.c @@ -746,12 +746,9 @@ static int isl29018_probe(struct i2c_client *client, chip->suspended = false; chip->vcc_reg = devm_regulator_get(&client->dev, "vcc"); - if (IS_ERR(chip->vcc_reg)) { - err = PTR_ERR(chip->vcc_reg); - if (err != -EPROBE_DEFER) - dev_err(&client->dev, "failed to get VCC regulator!\n"); - return err; - } + if (IS_ERR(chip->vcc_reg)) + return dev_err_probe(&client->dev, PTR_ERR(chip->vcc_reg), + "failed to get VCC regulator!\n"); err = regulator_enable(chip->vcc_reg); if (err) { diff --git a/drivers/iio/light/tsl2772.c b/drivers/iio/light/tsl2772.c index 735399405417..d79205361dfa 100644 --- a/drivers/iio/light/tsl2772.c +++ b/drivers/iio/light/tsl2772.c @@ -1776,14 +1776,8 @@ static int tsl2772_probe(struct i2c_client *clientp, ret = devm_regulator_bulk_get(&clientp->dev, ARRAY_SIZE(chip->supplies), chip->supplies); - if (ret < 0) { - if (ret != -EPROBE_DEFER) - dev_err(&clientp->dev, - "Failed to get regulators: %d\n", - ret); - - return ret; - } + if (ret < 0) + return dev_err_probe(&clientp->dev, ret, "Failed to get regulators\n"); ret = regulator_bulk_enable(ARRAY_SIZE(chip->supplies), chip->supplies); if (ret < 0) { diff --git a/drivers/iio/magnetometer/ak8974.c b/drivers/iio/magnetometer/ak8974.c index cbb44e401c0a..548c686e29d6 100644 --- a/drivers/iio/magnetometer/ak8974.c +++ b/drivers/iio/magnetometer/ak8974.c @@ -843,15 +843,8 @@ static int ak8974_probe(struct i2c_client *i2c, ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(ak8974->regs), ak8974->regs); - if (ret < 0) { - if (ret != -EPROBE_DEFER) - dev_err(&i2c->dev, "cannot get regulators: %d\n", ret); - else - dev_dbg(&i2c->dev, - "regulators unavailable, deferring probe\n"); - - return ret; - } + if (ret < 0) + return dev_err_probe(&i2c->dev, ret, "cannot get regulators\n"); ret = regulator_bulk_enable(ARRAY_SIZE(ak8974->regs), ak8974->regs); if (ret < 0) { diff --git a/drivers/iio/magnetometer/mag3110.c b/drivers/iio/magnetometer/mag3110.c index 4d305a21c379..838b13c8bb3d 100644 --- a/drivers/iio/magnetometer/mag3110.c +++ b/drivers/iio/magnetometer/mag3110.c @@ -476,22 +476,14 @@ static int mag3110_probe(struct i2c_client *client, data = iio_priv(indio_dev); data->vdd_reg = devm_regulator_get(&client->dev, "vdd"); - if (IS_ERR(data->vdd_reg)) { - if (PTR_ERR(data->vdd_reg) == -EPROBE_DEFER) - return -EPROBE_DEFER; - - dev_err(&client->dev, "failed to get VDD regulator!\n"); - return PTR_ERR(data->vdd_reg); - } + if (IS_ERR(data->vdd_reg)) + return dev_err_probe(&client->dev, PTR_ERR(data->vdd_reg), + "failed to get VDD regulator!\n"); data->vddio_reg = devm_regulator_get(&client->dev, "vddio"); - if (IS_ERR(data->vddio_reg)) { - if (PTR_ERR(data->vddio_reg) == -EPROBE_DEFER) - return -EPROBE_DEFER; - - dev_err(&client->dev, "failed to get VDDIO regulator!\n"); - return PTR_ERR(data->vddio_reg); - } + if (IS_ERR(data->vddio_reg)) + return dev_err_probe(&client->dev, PTR_ERR(data->vddio_reg), + "failed to get VDDIO regulator!\n"); ret = regulator_enable(data->vdd_reg); if (ret) { diff --git a/drivers/iio/multiplexer/iio-mux.c b/drivers/iio/multiplexer/iio-mux.c index 6910218fdb00..d54ae5cbe51b 100644 --- a/drivers/iio/multiplexer/iio-mux.c +++ b/drivers/iio/multiplexer/iio-mux.c @@ -354,11 +354,9 @@ static int mux_probe(struct platform_device *pdev) return -ENODEV; parent = devm_iio_channel_get(dev, "parent"); - if (IS_ERR(parent)) { - if (PTR_ERR(parent) != -EPROBE_DEFER) - dev_err(dev, "failed to get parent channel\n"); - return PTR_ERR(parent); - } + if (IS_ERR(parent)) + return dev_err_probe(dev, PTR_ERR(parent), + "failed to get parent channel\n"); sizeof_ext_info = iio_get_channel_ext_info_count(parent); if (sizeof_ext_info) { diff --git a/drivers/iio/proximity/sx9310.c b/drivers/iio/proximity/sx9310.c index dc2e11b43431..9d72d08ab9e7 100644 --- a/drivers/iio/proximity/sx9310.c +++ b/drivers/iio/proximity/sx9310.c @@ -6,19 +6,21 @@ * Based on SX9500 driver and Semtech driver using the input framework * <https://my.syncplicity.com/share/teouwsim8niiaud/ * linux-driver-SX9310_NoSmartHSensing>. - * Reworked April 2019 by Evan Green <evgreen@chromium.org> - * and January 2020 by Daniel Campello <campello@chromium.org> + * Reworked in April 2019 by Evan Green <evgreen@chromium.org> + * and in January 2020 by Daniel Campello <campello@chromium.org>. */ #include <linux/acpi.h> +#include <linux/bitfield.h> #include <linux/delay.h> #include <linux/i2c.h> #include <linux/irq.h> #include <linux/kernel.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of.h> #include <linux/pm.h> #include <linux/regmap.h> +#include <linux/regulator/consumer.h> #include <linux/slab.h> #include <linux/iio/buffer.h> @@ -33,45 +35,44 @@ #define SX9310_REG_IRQ_SRC 0x00 #define SX9310_REG_STAT0 0x01 #define SX9310_REG_STAT1 0x02 +#define SX9310_REG_STAT1_COMPSTAT_MASK GENMASK(3, 0) #define SX9310_REG_IRQ_MSK 0x03 #define SX9310_CONVDONE_IRQ BIT(3) #define SX9310_FAR_IRQ BIT(5) #define SX9310_CLOSE_IRQ BIT(6) -#define SX9310_EVENT_IRQ (SX9310_FAR_IRQ | \ - SX9310_CLOSE_IRQ) #define SX9310_REG_IRQ_FUNC 0x04 #define SX9310_REG_PROX_CTRL0 0x10 -#define SX9310_REG_PROX_CTRL0_PROXSTAT2 0x10 -#define SX9310_REG_PROX_CTRL0_EN_MASK 0x0F +#define SX9310_REG_PROX_CTRL0_SENSOREN_MASK GENMASK(3, 0) +#define SX9310_REG_PROX_CTRL0_SCANPERIOD_MASK GENMASK(7, 4) +#define SX9310_REG_PROX_CTRL0_SCANPERIOD_15MS 0x01 #define SX9310_REG_PROX_CTRL1 0x11 #define SX9310_REG_PROX_CTRL2 0x12 -#define SX9310_REG_PROX_CTRL2_COMBMODE_ALL 0x80 -#define SX9310_REG_PROX_CTRL2_SHIELDEN_DYNAMIC 0x04 +#define SX9310_REG_PROX_CTRL2_COMBMODE_CS1_CS2 (0x02 << 6) +#define SX9310_REG_PROX_CTRL2_SHIELDEN_DYNAMIC (0x01 << 2) #define SX9310_REG_PROX_CTRL3 0x13 -#define SX9310_REG_PROX_CTRL3_GAIN0_X8 0x0c +#define SX9310_REG_PROX_CTRL3_GAIN0_X8 (0x03 << 2) #define SX9310_REG_PROX_CTRL3_GAIN12_X4 0x02 #define SX9310_REG_PROX_CTRL4 0x14 #define SX9310_REG_PROX_CTRL4_RESOLUTION_FINEST 0x07 #define SX9310_REG_PROX_CTRL5 0x15 -#define SX9310_REG_PROX_CTRL5_RANGE_SMALL 0xc0 -#define SX9310_REG_PROX_CTRL5_STARTUPSENS_CS1 0x04 +#define SX9310_REG_PROX_CTRL5_RANGE_SMALL (0x03 << 6) +#define SX9310_REG_PROX_CTRL5_STARTUPSENS_CS1 (0x01 << 2) #define SX9310_REG_PROX_CTRL5_RAWFILT_1P25 0x02 #define SX9310_REG_PROX_CTRL6 0x16 -#define SX9310_REG_PROX_CTRL6_COMP_COMMON 0x20 +#define SX9310_REG_PROX_CTRL6_AVGTHRESH_DEFAULT 0x20 #define SX9310_REG_PROX_CTRL7 0x17 -#define SX9310_REG_PROX_CTRL7_AVGNEGFILT_2 0x08 +#define SX9310_REG_PROX_CTRL7_AVGNEGFILT_2 (0x01 << 3) #define SX9310_REG_PROX_CTRL7_AVGPOSFILT_512 0x05 #define SX9310_REG_PROX_CTRL8 0x18 #define SX9310_REG_PROX_CTRL9 0x19 -#define SX9310_REG_PROX_CTRL8_9_PTHRESH12_28 0x40 -#define SX9310_REG_PROX_CTRL8_9_PTHRESH_96 0x88 +#define SX9310_REG_PROX_CTRL8_9_PTHRESH_28 (0x08 << 3) +#define SX9310_REG_PROX_CTRL8_9_PTHRESH_96 (0x11 << 3) #define SX9310_REG_PROX_CTRL8_9_BODYTHRESH_900 0x03 #define SX9310_REG_PROX_CTRL8_9_BODYTHRESH_1500 0x05 #define SX9310_REG_PROX_CTRL10 0x1a -#define SX9310_REG_PROX_CTRL10_HYST_6PCT 0x10 -#define SX9310_REG_PROX_CTRL10_CLOSE_DEBOUNCE_8 0x12 -#define SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_8 0x03 +#define SX9310_REG_PROX_CTRL10_HYST_6PCT (0x01 << 4) +#define SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_2 0x01 #define SX9310_REG_PROX_CTRL11 0x1b #define SX9310_REG_PROX_CTRL12 0x1c #define SX9310_REG_PROX_CTRL13 0x1d @@ -82,8 +83,8 @@ #define SX9310_REG_PROX_CTRL18 0x22 #define SX9310_REG_PROX_CTRL19 0x23 #define SX9310_REG_SAR_CTRL0 0x2a -#define SX9310_REG_SAR_CTRL0_SARDEB_4_SAMPLES 0x40 -#define SX9310_REG_SAR_CTRL0_SARHYST_8 0x10 +#define SX9310_REG_SAR_CTRL0_SARDEB_4_SAMPLES (0x02 << 5) +#define SX9310_REG_SAR_CTRL0_SARHYST_8 (0x02 << 3) #define SX9310_REG_SAR_CTRL1 0x2b /* Each increment of the slope register is 0.0078125. */ #define SX9310_REG_SAR_CTRL1_SLOPE(_hnslope) (_hnslope / 78125) @@ -91,39 +92,28 @@ #define SX9310_REG_SAR_CTRL2_SAROFFSET_DEFAULT 0x3c #define SX9310_REG_SENSOR_SEL 0x30 - #define SX9310_REG_USE_MSB 0x31 #define SX9310_REG_USE_LSB 0x32 - #define SX9310_REG_AVG_MSB 0x33 #define SX9310_REG_AVG_LSB 0x34 - #define SX9310_REG_DIFF_MSB 0x35 #define SX9310_REG_DIFF_LSB 0x36 - #define SX9310_REG_OFFSET_MSB 0x37 #define SX9310_REG_OFFSET_LSB 0x38 - #define SX9310_REG_SAR_MSB 0x39 #define SX9310_REG_SAR_LSB 0x3a - -#define SX9310_REG_I2CADDR 0x40 +#define SX9310_REG_I2C_ADDR 0x40 #define SX9310_REG_PAUSE 0x41 #define SX9310_REG_WHOAMI 0x42 #define SX9310_WHOAMI_VALUE 0x01 #define SX9311_WHOAMI_VALUE 0x02 - #define SX9310_REG_RESET 0x7f #define SX9310_SOFT_RESET 0xde -#define SX9310_SCAN_PERIOD_MASK GENMASK(7, 4) -#define SX9310_SCAN_PERIOD_SHIFT 4 - -#define SX9310_COMPSTAT_MASK GENMASK(3, 0) /* 4 hardware channels, as defined in STAT0: COMB, CS2, CS1 and CS0. */ #define SX9310_NUM_CHANNELS 4 -#define SX9310_CHAN_ENABLED_MASK GENMASK(3, 0) +static_assert(SX9310_NUM_CHANNELS < BITS_PER_LONG); struct sx9310_data { /* Serialize access to registers and channel configuration */ @@ -131,20 +121,24 @@ struct sx9310_data { struct i2c_client *client; struct iio_trigger *trig; struct regmap *regmap; + struct regulator_bulk_data supplies[2]; /* * Last reading of the proximity status for each channel. * We only send an event to user space when this changes. */ - bool prox_stat[SX9310_NUM_CHANNELS]; + unsigned long chan_prox_stat; bool trigger_enabled; - __be16 buffer[SX9310_NUM_CHANNELS + - 4]; /* 64-bit data + 64-bit timestamp */ + /* Ensure correct alignment of timestamp when present. */ + struct { + __be16 channels[SX9310_NUM_CHANNELS]; + s64 ts __aligned(8); + } buffer; /* Remember enabled channels and sample rate during suspend. */ unsigned int suspend_ctrl0; struct completion completion; - unsigned int chan_read, chan_event; - int channel_users[SX9310_NUM_CHANNELS]; - int whoami; + unsigned long chan_read; + unsigned long chan_event; + unsigned int whoami; }; static const struct iio_event_spec sx9310_events[] = { @@ -251,7 +245,7 @@ static const struct regmap_range sx9310_readable_reg_ranges[] = { regmap_reg_range(SX9310_REG_PROX_CTRL0, SX9310_REG_PROX_CTRL19), regmap_reg_range(SX9310_REG_SAR_CTRL0, SX9310_REG_SAR_CTRL2), regmap_reg_range(SX9310_REG_SENSOR_SEL, SX9310_REG_SAR_LSB), - regmap_reg_range(SX9310_REG_I2CADDR, SX9310_REG_WHOAMI), + regmap_reg_range(SX9310_REG_I2C_ADDR, SX9310_REG_WHOAMI), regmap_reg_range(SX9310_REG_RESET, SX9310_REG_RESET), }; @@ -285,15 +279,16 @@ static const struct regmap_config sx9310_regmap_config = { }; static int sx9310_update_chan_en(struct sx9310_data *data, - unsigned int chan_read, - unsigned int chan_event) + unsigned long chan_read, + unsigned long chan_event) { int ret; + unsigned long channels = chan_read | chan_event; - if ((data->chan_read | data->chan_event) != (chan_read | chan_event)) { + if ((data->chan_read | data->chan_event) != channels) { ret = regmap_update_bits(data->regmap, SX9310_REG_PROX_CTRL0, - SX9310_CHAN_ENABLED_MASK, - chan_read | chan_event); + SX9310_REG_PROX_CTRL0_SENSOREN_MASK, + channels); if (ret) return ret; } @@ -328,11 +323,15 @@ static int sx9310_put_event_channel(struct sx9310_data *data, int channel) static int sx9310_enable_irq(struct sx9310_data *data, unsigned int irq) { + if (!data->client->irq) + return 0; return regmap_update_bits(data->regmap, SX9310_REG_IRQ_MSK, irq, irq); } static int sx9310_disable_irq(struct sx9310_data *data, unsigned int irq) { + if (!data->client->irq) + return 0; return regmap_update_bits(data->regmap, SX9310_REG_IRQ_MSK, irq, 0); } @@ -342,10 +341,10 @@ static int sx9310_read_prox_data(struct sx9310_data *data, int ret; ret = regmap_write(data->regmap, SX9310_REG_SENSOR_SEL, chan->channel); - if (ret < 0) + if (ret) return ret; - return regmap_bulk_read(data->regmap, chan->address, val, 2); + return regmap_bulk_read(data->regmap, chan->address, val, sizeof(*val)); } /* @@ -358,10 +357,10 @@ static int sx9310_wait_for_sample(struct sx9310_data *data) unsigned int val; ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0, &val); - if (ret < 0) + if (ret) return ret; - val = (val & SX9310_SCAN_PERIOD_MASK) >> SX9310_SCAN_PERIOD_SHIFT; + val = FIELD_GET(SX9310_REG_PROX_CTRL0_SCANPERIOD_MASK, val); msleep(sx9310_scan_period_table[val]); @@ -371,22 +370,22 @@ static int sx9310_wait_for_sample(struct sx9310_data *data) static int sx9310_read_proximity(struct sx9310_data *data, const struct iio_chan_spec *chan, int *val) { - int ret = 0; + int ret; __be16 rawval; mutex_lock(&data->mutex); ret = sx9310_get_read_channel(data, chan->channel); - if (ret < 0) + if (ret) goto out; ret = sx9310_enable_irq(data, SX9310_CONVDONE_IRQ); - if (ret < 0) + if (ret) goto out_put_channel; mutex_unlock(&data->mutex); - if (data->client->irq > 0) { + if (data->client->irq) { ret = wait_for_completion_interruptible(&data->completion); reinit_completion(&data->completion); } else { @@ -395,22 +394,22 @@ static int sx9310_read_proximity(struct sx9310_data *data, mutex_lock(&data->mutex); - if (ret < 0) + if (ret) goto out_disable_irq; ret = sx9310_read_prox_data(data, chan, &rawval); - if (ret < 0) + if (ret) goto out_disable_irq; *val = sign_extend32(be16_to_cpu(rawval), - (chan->address == SX9310_REG_DIFF_MSB ? 11 : 15)); + chan->address == SX9310_REG_DIFF_MSB ? 11 : 15); ret = sx9310_disable_irq(data, SX9310_CONVDONE_IRQ); - if (ret < 0) + if (ret) goto out_put_channel; ret = sx9310_put_read_channel(data, chan->channel); - if (ret < 0) + if (ret) goto out; mutex_unlock(&data->mutex); @@ -430,12 +429,13 @@ out: static int sx9310_read_samp_freq(struct sx9310_data *data, int *val, int *val2) { unsigned int regval; - int ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0, ®val); + int ret; - if (ret < 0) + ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0, ®val); + if (ret) return ret; - regval = (regval & SX9310_SCAN_PERIOD_MASK) >> SX9310_SCAN_PERIOD_SHIFT; + regval = FIELD_GET(SX9310_REG_PROX_CTRL0_SCANPERIOD_MASK, regval); *val = sx9310_samp_freq_table[regval].val; *val2 = sx9310_samp_freq_table[regval].val2; @@ -482,9 +482,10 @@ static int sx9310_set_samp_freq(struct sx9310_data *data, int val, int val2) mutex_lock(&data->mutex); - ret = regmap_update_bits(data->regmap, SX9310_REG_PROX_CTRL0, - SX9310_SCAN_PERIOD_MASK, - i << SX9310_SCAN_PERIOD_SHIFT); + ret = regmap_update_bits( + data->regmap, SX9310_REG_PROX_CTRL0, + SX9310_REG_PROX_CTRL0_SCANPERIOD_MASK, + FIELD_PREP(SX9310_REG_PROX_CTRL0_SCANPERIOD_MASK, i)); mutex_unlock(&data->mutex); @@ -515,10 +516,9 @@ static irqreturn_t sx9310_irq_handler(int irq, void *private) iio_trigger_poll(data->trig); /* - * Even if no event is enabled, we need to wake the thread to - * clear the interrupt state by reading SX9310_REG_IRQ_SRC. It - * is not possible to do that here because regmap_read takes a - * mutex. + * Even if no event is enabled, we need to wake the thread to clear the + * interrupt state by reading SX9310_REG_IRQ_SRC. + * It is not possible to do that here because regmap_read takes a mutex. */ return IRQ_WAKE_THREAD; } @@ -529,32 +529,32 @@ static void sx9310_push_events(struct iio_dev *indio_dev) unsigned int val, chan; struct sx9310_data *data = iio_priv(indio_dev); s64 timestamp = iio_get_time_ns(indio_dev); + unsigned long prox_changed; /* Read proximity state on all channels */ ret = regmap_read(data->regmap, SX9310_REG_STAT0, &val); - if (ret < 0) { + if (ret) { dev_err(&data->client->dev, "i2c transfer error in irq\n"); return; } - for (chan = 0; chan < SX9310_NUM_CHANNELS; chan++) { + /* + * Only iterate over channels with changes on proximity status that have + * events enabled. + */ + prox_changed = (data->chan_prox_stat ^ val) & data->chan_event; + + for_each_set_bit(chan, &prox_changed, SX9310_NUM_CHANNELS) { int dir; u64 ev; - bool new_prox = val & BIT(chan); - if (!(data->chan_event & BIT(chan))) - continue; - if (new_prox == data->prox_stat[chan]) - /* No change on this channel. */ - continue; - - dir = new_prox ? IIO_EV_DIR_FALLING : IIO_EV_DIR_RISING; + dir = (val & BIT(chan)) ? IIO_EV_DIR_FALLING : IIO_EV_DIR_RISING; ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, chan, IIO_EV_TYPE_THRESH, dir); iio_push_event(indio_dev, ev, timestamp); - data->prox_stat[chan] = new_prox; } + data->chan_prox_stat = val; } 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) mutex_lock(&data->mutex); ret = regmap_read(data->regmap, SX9310_REG_IRQ_SRC, &val); - if (ret < 0) { + if (ret) { dev_err(&data->client->dev, "i2c transfer error in irq\n"); goto out; } - if (val & SX9310_EVENT_IRQ) + if (val & (SX9310_FAR_IRQ | SX9310_CLOSE_IRQ)) sx9310_push_events(indio_dev); if (val & SX9310_CONVDONE_IRQ) @@ -600,6 +600,7 @@ static int sx9310_write_event_config(struct iio_dev *indio_dev, enum iio_event_direction dir, int state) { struct sx9310_data *data = iio_priv(indio_dev); + unsigned int eventirq = SX9310_FAR_IRQ | SX9310_CLOSE_IRQ; int ret; /* 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, mutex_lock(&data->mutex); if (state) { ret = sx9310_get_event_channel(data, chan->channel); - if (ret < 0) + if (ret) goto out_unlock; if (!(data->chan_event & ~BIT(chan->channel))) { - ret = sx9310_enable_irq(data, SX9310_EVENT_IRQ); - if (ret < 0) + ret = sx9310_enable_irq(data, eventirq); + if (ret) sx9310_put_event_channel(data, chan->channel); } } else { ret = sx9310_put_event_channel(data, chan->channel); - if (ret < 0) + if (ret) goto out_unlock; if (!data->chan_event) { - ret = sx9310_disable_irq(data, SX9310_EVENT_IRQ); - if (ret < 0) + ret = sx9310_disable_irq(data, eventirq); + if (ret) sx9310_get_event_channel(data, chan->channel); } } @@ -634,7 +635,7 @@ out_unlock: static struct attribute *sx9310_attributes[] = { &iio_dev_attr_sampling_frequency_available.dev_attr.attr, - NULL, + NULL }; static const struct attribute_group sx9310_attribute_group = { @@ -661,7 +662,7 @@ static int sx9310_set_trigger_state(struct iio_trigger *trig, bool state) ret = sx9310_enable_irq(data, SX9310_CONVDONE_IRQ); else if (!data->chan_read) ret = sx9310_disable_irq(data, SX9310_CONVDONE_IRQ); - if (ret < 0) + if (ret) goto out; data->trigger_enabled = state; @@ -690,13 +691,13 @@ static irqreturn_t sx9310_trigger_handler(int irq, void *private) indio_dev->masklength) { ret = sx9310_read_prox_data(data, &indio_dev->channels[bit], &val); - if (ret < 0) + if (ret) goto out; - data->buffer[i++] = val; + data->buffer.channels[i++] = val; } - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->buffer, pf->timestamp); out: @@ -710,13 +711,13 @@ out: static int sx9310_buffer_preenable(struct iio_dev *indio_dev) { struct sx9310_data *data = iio_priv(indio_dev); - unsigned int channels = 0; + unsigned long channels = 0; int bit, ret; mutex_lock(&data->mutex); for_each_set_bit(bit, indio_dev->active_scan_mask, indio_dev->masklength) - channels |= BIT(indio_dev->channels[bit].channel); + __set_bit(indio_dev->channels[bit].channel, &channels); ret = sx9310_update_chan_en(data, channels, data->chan_event); mutex_unlock(&data->mutex); @@ -744,89 +745,77 @@ struct sx9310_reg_default { u8 def; }; -#define SX_INIT(_reg, _def) \ - { \ - .reg = SX9310_REG_##_reg, \ - .def = _def, \ - } - static const struct sx9310_reg_default sx9310_default_regs[] = { - SX_INIT(IRQ_MSK, 0x00), - SX_INIT(IRQ_FUNC, 0x00), + { SX9310_REG_IRQ_MSK, 0x00 }, + { SX9310_REG_IRQ_FUNC, 0x00 }, /* * The lower 4 bits should not be set as it enable sensors measurements. * Turning the detection on before the configuration values are set to * good values can cause the device to return erroneous readings. */ - SX_INIT(PROX_CTRL0, SX9310_REG_PROX_CTRL0_PROXSTAT2), - SX_INIT(PROX_CTRL1, 0x00), - SX_INIT(PROX_CTRL2, SX9310_REG_PROX_CTRL2_COMBMODE_ALL | - SX9310_REG_PROX_CTRL2_SHIELDEN_DYNAMIC), - SX_INIT(PROX_CTRL3, SX9310_REG_PROX_CTRL3_GAIN0_X8 | - SX9310_REG_PROX_CTRL3_GAIN12_X4), - SX_INIT(PROX_CTRL4, SX9310_REG_PROX_CTRL4_RESOLUTION_FINEST), - SX_INIT(PROX_CTRL5, SX9310_REG_PROX_CTRL5_RANGE_SMALL | - SX9310_REG_PROX_CTRL5_STARTUPSENS_CS1 | - SX9310_REG_PROX_CTRL5_RAWFILT_1P25), - SX_INIT(PROX_CTRL6, SX9310_REG_PROX_CTRL6_COMP_COMMON), - SX_INIT(PROX_CTRL7, SX9310_REG_PROX_CTRL7_AVGNEGFILT_2 | - SX9310_REG_PROX_CTRL7_AVGPOSFILT_512), - SX_INIT(PROX_CTRL8, SX9310_REG_PROX_CTRL8_9_PTHRESH_96 | - SX9310_REG_PROX_CTRL8_9_BODYTHRESH_1500), - SX_INIT(PROX_CTRL9, SX9310_REG_PROX_CTRL8_9_PTHRESH12_28 | - SX9310_REG_PROX_CTRL8_9_BODYTHRESH_900), - SX_INIT(PROX_CTRL10, SX9310_REG_PROX_CTRL10_HYST_6PCT | - SX9310_REG_PROX_CTRL10_CLOSE_DEBOUNCE_8 | - SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_8), - SX_INIT(PROX_CTRL11, 0x00), - SX_INIT(PROX_CTRL12, 0x00), - SX_INIT(PROX_CTRL13, 0x00), - SX_INIT(PROX_CTRL14, 0x00), - SX_INIT(PROX_CTRL15, 0x00), - SX_INIT(PROX_CTRL16, 0x00), - SX_INIT(PROX_CTRL17, 0x00), - SX_INIT(PROX_CTRL18, 0x00), - SX_INIT(PROX_CTRL19, 0x00), - SX_INIT(SAR_CTRL0, SX9310_REG_SAR_CTRL0_SARDEB_4_SAMPLES | - SX9310_REG_SAR_CTRL0_SARHYST_8), - SX_INIT(SAR_CTRL1, SX9310_REG_SAR_CTRL1_SLOPE(10781250)), - SX_INIT(SAR_CTRL2, SX9310_REG_SAR_CTRL2_SAROFFSET_DEFAULT), + { SX9310_REG_PROX_CTRL0, SX9310_REG_PROX_CTRL0_SCANPERIOD_15MS }, + { SX9310_REG_PROX_CTRL1, 0x00 }, + { SX9310_REG_PROX_CTRL2, SX9310_REG_PROX_CTRL2_COMBMODE_CS1_CS2 | + SX9310_REG_PROX_CTRL2_SHIELDEN_DYNAMIC }, + { SX9310_REG_PROX_CTRL3, SX9310_REG_PROX_CTRL3_GAIN0_X8 | + SX9310_REG_PROX_CTRL3_GAIN12_X4 }, + { SX9310_REG_PROX_CTRL4, SX9310_REG_PROX_CTRL4_RESOLUTION_FINEST }, + { SX9310_REG_PROX_CTRL5, SX9310_REG_PROX_CTRL5_RANGE_SMALL | + SX9310_REG_PROX_CTRL5_STARTUPSENS_CS1 | + SX9310_REG_PROX_CTRL5_RAWFILT_1P25 }, + { SX9310_REG_PROX_CTRL6, SX9310_REG_PROX_CTRL6_AVGTHRESH_DEFAULT }, + { SX9310_REG_PROX_CTRL7, SX9310_REG_PROX_CTRL7_AVGNEGFILT_2 | + SX9310_REG_PROX_CTRL7_AVGPOSFILT_512 }, + { SX9310_REG_PROX_CTRL8, SX9310_REG_PROX_CTRL8_9_PTHRESH_96 | + SX9310_REG_PROX_CTRL8_9_BODYTHRESH_1500 }, + { SX9310_REG_PROX_CTRL9, SX9310_REG_PROX_CTRL8_9_PTHRESH_28 | + SX9310_REG_PROX_CTRL8_9_BODYTHRESH_900 }, + { SX9310_REG_PROX_CTRL10, SX9310_REG_PROX_CTRL10_HYST_6PCT | + SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_2 }, + { SX9310_REG_PROX_CTRL11, 0x00 }, + { SX9310_REG_PROX_CTRL12, 0x00 }, + { SX9310_REG_PROX_CTRL13, 0x00 }, + { SX9310_REG_PROX_CTRL14, 0x00 }, + { SX9310_REG_PROX_CTRL15, 0x00 }, + { SX9310_REG_PROX_CTRL16, 0x00 }, + { SX9310_REG_PROX_CTRL17, 0x00 }, + { SX9310_REG_PROX_CTRL18, 0x00 }, + { SX9310_REG_PROX_CTRL19, 0x00 }, + { SX9310_REG_SAR_CTRL0, SX9310_REG_SAR_CTRL0_SARDEB_4_SAMPLES | + SX9310_REG_SAR_CTRL0_SARHYST_8 }, + { SX9310_REG_SAR_CTRL1, SX9310_REG_SAR_CTRL1_SLOPE(10781250) }, + { SX9310_REG_SAR_CTRL2, SX9310_REG_SAR_CTRL2_SAROFFSET_DEFAULT }, }; /* Activate all channels and perform an initial compensation. */ static int sx9310_init_compensation(struct iio_dev *indio_dev) { struct sx9310_data *data = iio_priv(indio_dev); - int i, ret; + int ret; unsigned int val; unsigned int ctrl0; ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0, &ctrl0); - if (ret < 0) + if (ret) return ret; /* run the compensation phase on all channels */ ret = regmap_write(data->regmap, SX9310_REG_PROX_CTRL0, - ctrl0 | SX9310_REG_PROX_CTRL0_EN_MASK); - if (ret < 0) + ctrl0 | SX9310_REG_PROX_CTRL0_SENSOREN_MASK); + if (ret) return ret; - for (i = 100; i >= 0; i--) { - msleep(20); - ret = regmap_read(data->regmap, SX9310_REG_STAT1, &val); - if (ret < 0) - goto out; - if (!(val & SX9310_COMPSTAT_MASK)) - break; - } - - if (i < 0) { - dev_err(&data->client->dev, - "initial compensation timed out: 0x%02x", val); - ret = -ETIMEDOUT; + ret = regmap_read_poll_timeout(data->regmap, SX9310_REG_STAT1, val, + !(val & SX9310_REG_STAT1_COMPSTAT_MASK), + 20000, 2000000); + if (ret) { + if (ret == -ETIMEDOUT) + dev_err(&data->client->dev, + "initial compensation timed out: 0x%02x\n", + val); + return ret; } -out: regmap_write(data->regmap, SX9310_REG_PROX_CTRL0, ctrl0); return ret; } @@ -839,21 +828,21 @@ static int sx9310_init_device(struct iio_dev *indio_dev) unsigned int i, val; ret = regmap_write(data->regmap, SX9310_REG_RESET, SX9310_SOFT_RESET); - if (ret < 0) + if (ret) return ret; usleep_range(1000, 2000); /* power-up time is ~1ms. */ /* Clear reset interrupt state by reading SX9310_REG_IRQ_SRC. */ ret = regmap_read(data->regmap, SX9310_REG_IRQ_SRC, &val); - if (ret < 0) + if (ret) return ret; /* Program some sane defaults. */ for (i = 0; i < ARRAY_SIZE(sx9310_default_regs); i++) { initval = &sx9310_default_regs[i]; ret = regmap_write(data->regmap, initval->reg, initval->def); - if (ret < 0) + if (ret) return ret; } @@ -862,24 +851,15 @@ static int sx9310_init_device(struct iio_dev *indio_dev) static int sx9310_set_indio_dev_name(struct device *dev, struct iio_dev *indio_dev, - const struct i2c_device_id *id, int whoami) + unsigned int whoami) { - const struct acpi_device_id *acpi_id; - - /* id will be NULL when enumerated via ACPI */ - if (id) { - if (id->driver_data != whoami) - dev_err(dev, "WHOAMI does not match i2c_device_id: %s", - id->name); - } else if (ACPI_HANDLE(dev)) { - acpi_id = acpi_match_device(dev->driver->acpi_match_table, dev); - if (!acpi_id) - return -ENODEV; - if (acpi_id->driver_data != whoami) - dev_err(dev, "WHOAMI does not match acpi_device_id: %s", - acpi_id->id); - } else + unsigned int long ddata; + + ddata = (uintptr_t)device_get_match_data(dev); + if (ddata != whoami) { + dev_err(dev, "WHOAMI does not match device data: %u\n", whoami); return -ENODEV; + } switch (whoami) { case SX9310_WHOAMI_VALUE: @@ -889,26 +869,35 @@ static int sx9310_set_indio_dev_name(struct device *dev, indio_dev->name = "sx9311"; break; default: - dev_err(dev, "unexpected WHOAMI response: %u", whoami); + dev_err(dev, "unexpected WHOAMI response: %u\n", whoami); return -ENODEV; } return 0; } -static int sx9310_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static void sx9310_regulator_disable(void *_data) +{ + struct sx9310_data *data = _data; + + regulator_bulk_disable(ARRAY_SIZE(data->supplies), data->supplies); +} + +static int sx9310_probe(struct i2c_client *client) { int ret; + struct device *dev = &client->dev; struct iio_dev *indio_dev; struct sx9310_data *data; - indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); - if (indio_dev == NULL) + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); + if (!indio_dev) return -ENOMEM; data = iio_priv(indio_dev); data->client = client; + data->supplies[0].supply = "vdd"; + data->supplies[1].supply = "svdd"; mutex_init(&data->mutex); init_completion(&data->completion); @@ -916,19 +905,32 @@ static int sx9310_probe(struct i2c_client *client, if (IS_ERR(data->regmap)) return PTR_ERR(data->regmap); + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(data->supplies), + data->supplies); + if (ret) + return ret; + + ret = regulator_bulk_enable(ARRAY_SIZE(data->supplies), data->supplies); + if (ret) + return ret; + /* Must wait for Tpor time after initial power up */ + usleep_range(1000, 1100); + + ret = devm_add_action_or_reset(dev, sx9310_regulator_disable, data); + if (ret) + return ret; + ret = regmap_read(data->regmap, SX9310_REG_WHOAMI, &data->whoami); - if (ret < 0) { - dev_err(&client->dev, "error in reading WHOAMI register: %d", - ret); + if (ret) { + dev_err(dev, "error in reading WHOAMI register: %d", ret); return ret; } - ret = sx9310_set_indio_dev_name(&client->dev, indio_dev, id, - data->whoami); - if (ret < 0) + ret = sx9310_set_indio_dev_name(dev, indio_dev, data->whoami); + if (ret) return ret; - ACPI_COMPANION_SET(&indio_dev->dev, ACPI_COMPANION(&client->dev)); + ACPI_COMPANION_SET(&indio_dev->dev, ACPI_COMPANION(dev)); indio_dev->channels = sx9310_channels; indio_dev->num_channels = ARRAY_SIZE(sx9310_channels); indio_dev->info = &sx9310_info; @@ -936,41 +938,41 @@ static int sx9310_probe(struct i2c_client *client, i2c_set_clientdata(client, indio_dev); ret = sx9310_init_device(indio_dev); - if (ret < 0) + if (ret) return ret; if (client->irq) { - ret = devm_request_threaded_irq(&client->dev, client->irq, + ret = devm_request_threaded_irq(dev, client->irq, sx9310_irq_handler, sx9310_irq_thread_handler, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, + IRQF_ONESHOT, "sx9310_event", indio_dev); - if (ret < 0) + if (ret) return ret; - data->trig = - devm_iio_trigger_alloc(&client->dev, "%s-dev%d", - indio_dev->name, indio_dev->id); + data->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", + indio_dev->name, + indio_dev->id); if (!data->trig) return -ENOMEM; - data->trig->dev.parent = &client->dev; + data->trig->dev.parent = dev; data->trig->ops = &sx9310_trigger_ops; iio_trigger_set_drvdata(data->trig, indio_dev); - ret = devm_iio_trigger_register(&client->dev, data->trig); + ret = devm_iio_trigger_register(dev, data->trig); if (ret) return ret; } - ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev, + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, iio_pollfunc_store_time, sx9310_trigger_handler, &sx9310_buffer_setup_ops); - if (ret < 0) + if (ret) return ret; - return devm_iio_device_register(&client->dev, indio_dev); + return devm_iio_device_register(dev, indio_dev); } static int __maybe_unused sx9310_suspend(struct device *dev) @@ -985,11 +987,10 @@ static int __maybe_unused sx9310_suspend(struct device *dev) mutex_lock(&data->mutex); ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0, &data->suspend_ctrl0); - if (ret) goto out; - ctrl0 = data->suspend_ctrl0 & ~SX9310_REG_PROX_CTRL0_EN_MASK; + ctrl0 = data->suspend_ctrl0 & ~SX9310_REG_PROX_CTRL0_SENSOREN_MASK; ret = regmap_write(data->regmap, SX9310_REG_PROX_CTRL0, ctrl0); if (ret) goto out; @@ -1017,10 +1018,11 @@ static int __maybe_unused sx9310_resume(struct device *dev) out: mutex_unlock(&data->mutex); + if (ret) + return ret; enable_irq(data->client->irq); - - return ret; + return 0; } static const struct dev_pm_ops sx9310_pm_ops = { @@ -1030,32 +1032,32 @@ static const struct dev_pm_ops sx9310_pm_ops = { static const struct acpi_device_id sx9310_acpi_match[] = { { "STH9310", SX9310_WHOAMI_VALUE }, { "STH9311", SX9311_WHOAMI_VALUE }, - {}, + {} }; MODULE_DEVICE_TABLE(acpi, sx9310_acpi_match); static const struct of_device_id sx9310_of_match[] = { - { .compatible = "semtech,sx9310" }, - { .compatible = "semtech,sx9311" }, - {}, + { .compatible = "semtech,sx9310", (void *)SX9310_WHOAMI_VALUE }, + { .compatible = "semtech,sx9311", (void *)SX9311_WHOAMI_VALUE }, + {} }; MODULE_DEVICE_TABLE(of, sx9310_of_match); static const struct i2c_device_id sx9310_id[] = { { "sx9310", SX9310_WHOAMI_VALUE }, { "sx9311", SX9311_WHOAMI_VALUE }, - {}, + {} }; MODULE_DEVICE_TABLE(i2c, sx9310_id); static struct i2c_driver sx9310_driver = { .driver = { .name = "sx9310", - .acpi_match_table = ACPI_PTR(sx9310_acpi_match), - .of_match_table = of_match_ptr(sx9310_of_match), + .acpi_match_table = sx9310_acpi_match, + .of_match_table = sx9310_of_match, .pm = &sx9310_pm_ops, }, - .probe = sx9310_probe, + .probe_new = sx9310_probe, .id_table = sx9310_id, }; module_i2c_driver(sx9310_driver); diff --git a/drivers/iio/temperature/mlx90632.c b/drivers/iio/temperature/mlx90632.c index 51b812bcff2e..472a7fb20615 100644 --- a/drivers/iio/temperature/mlx90632.c +++ b/drivers/iio/temperature/mlx90632.c @@ -10,7 +10,9 @@ #include <linux/err.h> #include <linux/gpio/consumer.h> #include <linux/i2c.h> +#include <linux/iopoll.h> #include <linux/kernel.h> +#include <linux/limits.h> #include <linux/module.h> #include <linux/math64.h> #include <linux/of.h> @@ -58,6 +60,8 @@ /* Control register address - volatile */ #define MLX90632_REG_CONTROL 0x3001 /* Control Register address */ #define MLX90632_CFG_PWR_MASK GENMASK(2, 1) /* PowerMode Mask */ +#define MLX90632_CFG_MTYP_MASK GENMASK(8, 4) /* Meas select Mask */ + /* PowerModes statuses */ #define MLX90632_PWR_STATUS(ctrl_val) (ctrl_val << 1) #define MLX90632_PWR_STATUS_HALT MLX90632_PWR_STATUS(0) /* hold */ @@ -65,6 +69,18 @@ #define MLX90632_PWR_STATUS_STEP MLX90632_PWR_STATUS(2) /* step */ #define MLX90632_PWR_STATUS_CONTINUOUS MLX90632_PWR_STATUS(3) /* continuous*/ +/* Measurement types */ +#define MLX90632_MTYP_MEDICAL 0 +#define MLX90632_MTYP_EXTENDED 17 + +/* Measurement type select*/ +#define MLX90632_MTYP_STATUS(ctrl_val) (ctrl_val << 4) +#define MLX90632_MTYP_STATUS_MEDICAL MLX90632_MTYP_STATUS(MLX90632_MTYP_MEDICAL) +#define MLX90632_MTYP_STATUS_EXTENDED MLX90632_MTYP_STATUS(MLX90632_MTYP_EXTENDED) + +/* I2C command register - volatile */ +#define MLX90632_REG_I2C_CMD 0x3005 /* I2C command Register address */ + /* Device status register - volatile */ #define MLX90632_REG_STATUS 0x3fff /* Device status register */ #define MLX90632_STAT_BUSY BIT(10) /* Device busy indicator */ @@ -78,26 +94,53 @@ #define MLX90632_RAM_2(meas_num) (MLX90632_ADDR_RAM + 3 * meas_num + 1) #define MLX90632_RAM_3(meas_num) (MLX90632_ADDR_RAM + 3 * meas_num + 2) +/* Name important RAM_MEAS channels */ +#define MLX90632_RAM_DSP5_EXTENDED_AMBIENT_1 MLX90632_RAM_3(17) +#define MLX90632_RAM_DSP5_EXTENDED_AMBIENT_2 MLX90632_RAM_3(18) +#define MLX90632_RAM_DSP5_EXTENDED_OBJECT_1 MLX90632_RAM_1(17) +#define MLX90632_RAM_DSP5_EXTENDED_OBJECT_2 MLX90632_RAM_2(17) +#define MLX90632_RAM_DSP5_EXTENDED_OBJECT_3 MLX90632_RAM_1(18) +#define MLX90632_RAM_DSP5_EXTENDED_OBJECT_4 MLX90632_RAM_2(18) +#define MLX90632_RAM_DSP5_EXTENDED_OBJECT_5 MLX90632_RAM_1(19) +#define MLX90632_RAM_DSP5_EXTENDED_OBJECT_6 MLX90632_RAM_2(19) + /* Magic constants */ #define MLX90632_ID_MEDICAL 0x0105 /* EEPROM DSPv5 Medical device id */ #define MLX90632_ID_CONSUMER 0x0205 /* EEPROM DSPv5 Consumer device id */ +#define MLX90632_ID_EXTENDED 0x0505 /* EEPROM DSPv5 Extended range device id */ +#define MLX90632_ID_MASK GENMASK(14, 0) /* DSP version and device ID in EE_VERSION */ #define MLX90632_DSP_VERSION 5 /* DSP version */ #define MLX90632_DSP_MASK GENMASK(7, 0) /* DSP version in EE_VERSION */ #define MLX90632_RESET_CMD 0x0006 /* Reset sensor (address or global) */ -#define MLX90632_REF_12 12LL /**< ResCtrlRef value of Ch 1 or Ch 2 */ -#define MLX90632_REF_3 12LL /**< ResCtrlRef value of Channel 3 */ -#define MLX90632_MAX_MEAS_NUM 31 /**< Maximum measurements in list */ -#define MLX90632_SLEEP_DELAY_MS 3000 /**< Autosleep delay */ +#define MLX90632_REF_12 12LL /* ResCtrlRef value of Ch 1 or Ch 2 */ +#define MLX90632_REF_3 12LL /* ResCtrlRef value of Channel 3 */ +#define MLX90632_MAX_MEAS_NUM 31 /* Maximum measurements in list */ +#define MLX90632_SLEEP_DELAY_MS 3000 /* Autosleep delay */ +#define MLX90632_EXTENDED_LIMIT 27000 /* Extended mode raw value limit */ +/** + * struct mlx90632_data - private data for the MLX90632 device + * @client: I2C client of the device + * @lock: Internal mutex for multiple reads for single measurement + * @regmap: Regmap of the device + * @emissivity: Object emissivity from 0 to 1000 where 1000 = 1. + * @mtyp: Measurement type physical sensor configuration for extended range + * calculations + * @object_ambient_temperature: Ambient temperature at object (might differ of + * the ambient temperature of sensor. + */ struct mlx90632_data { struct i2c_client *client; - struct mutex lock; /* Multiple reads for single measurement */ + struct mutex lock; struct regmap *regmap; u16 emissivity; + u8 mtyp; + u32 object_ambient_temperature; }; static const struct regmap_range mlx90632_volatile_reg_range[] = { regmap_reg_range(MLX90632_REG_I2C_ADDR, MLX90632_REG_CONTROL), + regmap_reg_range(MLX90632_REG_I2C_CMD, MLX90632_REG_I2C_CMD), regmap_reg_range(MLX90632_REG_STATUS, MLX90632_REG_STATUS), regmap_reg_range(MLX90632_RAM_1(0), MLX90632_RAM_3(MLX90632_MAX_MEAS_NUM)), @@ -113,6 +156,7 @@ static const struct regmap_range mlx90632_read_reg_range[] = { regmap_reg_range(MLX90632_EE_CTRL, MLX90632_EE_I2C_ADDR), regmap_reg_range(MLX90632_EE_Ha, MLX90632_EE_Hb), regmap_reg_range(MLX90632_REG_I2C_ADDR, MLX90632_REG_CONTROL), + regmap_reg_range(MLX90632_REG_I2C_CMD, MLX90632_REG_I2C_CMD), regmap_reg_range(MLX90632_REG_STATUS, MLX90632_REG_STATUS), regmap_reg_range(MLX90632_RAM_1(0), MLX90632_RAM_3(MLX90632_MAX_MEAS_NUM)), @@ -173,25 +217,19 @@ static s32 mlx90632_pwr_continuous(struct regmap *regmap) */ static int mlx90632_perform_measurement(struct mlx90632_data *data) { - int ret, tries = 100; unsigned int reg_status; + int ret; ret = regmap_update_bits(data->regmap, MLX90632_REG_STATUS, MLX90632_STAT_DATA_RDY, 0); if (ret < 0) return ret; - while (tries-- > 0) { - ret = regmap_read(data->regmap, MLX90632_REG_STATUS, - ®_status); - if (ret < 0) - return ret; - if (reg_status & MLX90632_STAT_DATA_RDY) - break; - usleep_range(10000, 11000); - } + ret = regmap_read_poll_timeout(data->regmap, MLX90632_REG_STATUS, reg_status, + !(reg_status & MLX90632_STAT_DATA_RDY), 10000, + 100 * 10000); - if (tries < 0) { + if (ret < 0) { dev_err(&data->client->dev, "data not ready"); return -ETIMEDOUT; } @@ -199,6 +237,26 @@ static int mlx90632_perform_measurement(struct mlx90632_data *data) return (reg_status & MLX90632_STAT_CYCLE_POS) >> 2; } +static int mlx90632_set_meas_type(struct regmap *regmap, u8 type) +{ + int ret; + + if ((type != MLX90632_MTYP_MEDICAL) && (type != MLX90632_MTYP_EXTENDED)) + return -EINVAL; + + ret = regmap_write(regmap, MLX90632_REG_I2C_CMD, MLX90632_RESET_CMD); + if (ret < 0) + return ret; + + ret = regmap_write_bits(regmap, MLX90632_REG_CONTROL, + (MLX90632_CFG_MTYP_MASK | MLX90632_CFG_PWR_MASK), + (MLX90632_MTYP_STATUS(type) | MLX90632_PWR_STATUS_HALT)); + if (ret < 0) + return ret; + + return mlx90632_pwr_continuous(regmap); +} + static int mlx90632_channel_new_select(int perform_ret, uint8_t *channel_new, uint8_t *channel_old) { @@ -300,6 +358,97 @@ read_unlock: return ret; } +static int mlx90632_read_ambient_raw_extended(struct regmap *regmap, + s16 *ambient_new_raw, s16 *ambient_old_raw) +{ + unsigned int read_tmp; + int ret; + + ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_AMBIENT_1, &read_tmp); + if (ret < 0) + return ret; + *ambient_new_raw = (s16)read_tmp; + + ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_AMBIENT_2, &read_tmp); + if (ret < 0) + return ret; + *ambient_old_raw = (s16)read_tmp; + + return 0; +} + +static int mlx90632_read_object_raw_extended(struct regmap *regmap, s16 *object_new_raw) +{ + unsigned int read_tmp; + s32 read; + int ret; + + ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_OBJECT_1, &read_tmp); + if (ret < 0) + return ret; + read = (s16)read_tmp; + + ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_OBJECT_2, &read_tmp); + if (ret < 0) + return ret; + read = read - (s16)read_tmp; + + ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_OBJECT_3, &read_tmp); + if (ret < 0) + return ret; + read = read - (s16)read_tmp; + + ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_OBJECT_4, &read_tmp); + if (ret < 0) + return ret; + read = (read + (s16)read_tmp) / 2; + + ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_OBJECT_5, &read_tmp); + if (ret < 0) + return ret; + read = read + (s16)read_tmp; + + ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_OBJECT_6, &read_tmp); + if (ret < 0) + return ret; + read = read + (s16)read_tmp; + + if (read > S16_MAX || read < S16_MIN) + return -ERANGE; + + *object_new_raw = read; + + return 0; +} + +static int mlx90632_read_all_channel_extended(struct mlx90632_data *data, s16 *object_new_raw, + s16 *ambient_new_raw, s16 *ambient_old_raw) +{ + s32 ret, meas; + + mutex_lock(&data->lock); + ret = mlx90632_set_meas_type(data->regmap, MLX90632_MTYP_EXTENDED); + if (ret < 0) + goto read_unlock; + + ret = read_poll_timeout(mlx90632_perform_measurement, meas, meas == 19, + 50000, 800000, false, data); + if (ret != 0) + goto read_unlock; + + ret = mlx90632_read_object_raw_extended(data->regmap, object_new_raw); + if (ret < 0) + goto read_unlock; + + ret = mlx90632_read_ambient_raw_extended(data->regmap, ambient_new_raw, ambient_old_raw); + +read_unlock: + (void) mlx90632_set_meas_type(data->regmap, MLX90632_MTYP_MEDICAL); + + mutex_unlock(&data->lock); + return ret; +} + static int mlx90632_read_ee_register(struct regmap *regmap, u16 reg_lsb, s32 *reg_value) { @@ -354,9 +503,23 @@ static s64 mlx90632_preprocess_temp_obj(s16 object_new_raw, s16 object_old_raw, return div64_s64((tmp << 19ULL), 1000LL); } +static s64 mlx90632_preprocess_temp_obj_extended(s16 object_new_raw, s16 ambient_new_raw, + s16 ambient_old_raw, s16 Ka) +{ + s64 VR_IR, kKa, tmp; + + kKa = ((s64)Ka * 1000LL) >> 10ULL; + VR_IR = (s64)ambient_old_raw * 1000000LL + + kKa * div64_s64((s64)ambient_new_raw * 1000LL, + MLX90632_REF_3); + tmp = div64_s64( + div64_s64((s64) object_new_raw * 1000000000000LL, MLX90632_REF_12), + VR_IR); + return div64_s64(tmp << 19ULL, 1000LL); +} + static s32 mlx90632_calc_temp_ambient(s16 ambient_new_raw, s16 ambient_old_raw, - s32 P_T, s32 P_R, s32 P_G, s32 P_O, - s16 Gb) + s32 P_T, s32 P_R, s32 P_G, s32 P_O, s16 Gb) { s64 Asub, Bsub, Ablock, Bblock, Cblock, AMB, sum; @@ -374,11 +537,11 @@ static s32 mlx90632_calc_temp_ambient(s16 ambient_new_raw, s16 ambient_old_raw, } static s32 mlx90632_calc_temp_object_iteration(s32 prev_object_temp, s64 object, - s64 TAdut, s32 Fa, s32 Fb, + s64 TAdut, s64 TAdut4, s32 Fa, s32 Fb, s32 Ga, s16 Ha, s16 Hb, u16 emissivity) { - s64 calcedKsTO, calcedKsTA, ir_Alpha, TAdut4, Alpha_corr; + s64 calcedKsTO, calcedKsTA, ir_Alpha, Alpha_corr; s64 Ha_customer, Hb_customer; Ha_customer = ((s64)Ha * 1000000LL) >> 14ULL; @@ -393,36 +556,66 @@ static s32 mlx90632_calc_temp_object_iteration(s32 prev_object_temp, s64 object, Alpha_corr = emissivity * div64_s64(Alpha_corr, 100000LL); Alpha_corr = div64_s64(Alpha_corr, 1000LL); ir_Alpha = div64_s64((s64)object * 10000000LL, Alpha_corr); - TAdut4 = (div64_s64(TAdut, 10000LL) + 27315) * - (div64_s64(TAdut, 10000LL) + 27315) * - (div64_s64(TAdut, 10000LL) + 27315) * - (div64_s64(TAdut, 10000LL) + 27315); return (int_sqrt64(int_sqrt64(ir_Alpha * 1000000000000LL + TAdut4)) - 27315 - Hb_customer) * 10; } +static s64 mlx90632_calc_ta4(s64 TAdut, s64 scale) +{ + return (div64_s64(TAdut, scale) + 27315) * + (div64_s64(TAdut, scale) + 27315) * + (div64_s64(TAdut, scale) + 27315) * + (div64_s64(TAdut, scale) + 27315); +} + static s32 mlx90632_calc_temp_object(s64 object, s64 ambient, s32 Ea, s32 Eb, s32 Fa, s32 Fb, s32 Ga, s16 Ha, s16 Hb, u16 tmp_emi) { - s64 kTA, kTA0, TAdut; + s64 kTA, kTA0, TAdut, TAdut4; s64 temp = 25000; s8 i; kTA = (Ea * 1000LL) >> 16LL; kTA0 = (Eb * 1000LL) >> 8LL; TAdut = div64_s64(((ambient - kTA0) * 1000000LL), kTA) + 25 * 1000000LL; + TAdut4 = mlx90632_calc_ta4(TAdut, 10000LL); /* Iterations of calculation as described in datasheet */ for (i = 0; i < 5; ++i) { - temp = mlx90632_calc_temp_object_iteration(temp, object, TAdut, + temp = mlx90632_calc_temp_object_iteration(temp, object, TAdut, TAdut4, Fa, Fb, Ga, Ha, Hb, tmp_emi); } return temp; } +static s32 mlx90632_calc_temp_object_extended(s64 object, s64 ambient, s64 reflected, + s32 Ea, s32 Eb, s32 Fa, s32 Fb, s32 Ga, + s16 Ha, s16 Hb, u16 tmp_emi) +{ + s64 kTA, kTA0, TAdut, TAdut4, Tr4, TaTr4; + s64 temp = 25000; + s8 i; + + kTA = (Ea * 1000LL) >> 16LL; + kTA0 = (Eb * 1000LL) >> 8LL; + TAdut = div64_s64((ambient - kTA0) * 1000000LL, kTA) + 25 * 1000000LL; + Tr4 = mlx90632_calc_ta4(reflected, 10); + TAdut4 = mlx90632_calc_ta4(TAdut, 10000LL); + TaTr4 = Tr4 - div64_s64(Tr4 - TAdut4, tmp_emi) * 1000; + + /* Iterations of calculation as described in datasheet */ + for (i = 0; i < 5; ++i) { + temp = mlx90632_calc_temp_object_iteration(temp, object, TAdut, TaTr4, + Fa / 2, Fb, Ga, Ha, Hb, + tmp_emi); + } + + return temp; +} + static int mlx90632_calc_object_dsp105(struct mlx90632_data *data, int *val) { s32 ret; @@ -470,6 +663,26 @@ static int mlx90632_calc_object_dsp105(struct mlx90632_data *data, int *val) if (ret < 0) return ret; + if (object_new_raw > MLX90632_EXTENDED_LIMIT && + data->mtyp == MLX90632_MTYP_EXTENDED) { + ret = mlx90632_read_all_channel_extended(data, &object_new_raw, + &ambient_new_raw, &ambient_old_raw); + if (ret < 0) + return ret; + + /* Use extended mode calculations */ + ambient = mlx90632_preprocess_temp_amb(ambient_new_raw, + ambient_old_raw, Gb); + object = mlx90632_preprocess_temp_obj_extended(object_new_raw, + ambient_new_raw, + ambient_old_raw, Ka); + *val = mlx90632_calc_temp_object_extended(object, ambient, + data->object_ambient_temperature, + Ea, Eb, Fa, Fb, Ga, + Ha, Hb, data->emissivity); + return 0; + } + ambient = mlx90632_preprocess_temp_amb(ambient_new_raw, ambient_old_raw, Gb); object = mlx90632_preprocess_temp_obj(object_new_raw, @@ -643,6 +856,7 @@ static int mlx90632_probe(struct i2c_client *client, i2c_set_clientdata(client, indio_dev); mlx90632->client = client; mlx90632->regmap = regmap; + mlx90632->mtyp = MLX90632_MTYP_MEDICAL; mutex_init(&mlx90632->lock); indio_dev->name = id->name; @@ -662,15 +876,20 @@ static int mlx90632_probe(struct i2c_client *client, dev_err(&client->dev, "read of version failed: %d\n", ret); return ret; } + read = read & MLX90632_ID_MASK; if (read == MLX90632_ID_MEDICAL) { dev_dbg(&client->dev, "Detected Medical EEPROM calibration %x\n", read); } else if (read == MLX90632_ID_CONSUMER) { dev_dbg(&client->dev, "Detected Consumer EEPROM calibration %x\n", read); + } else if (read == MLX90632_ID_EXTENDED) { + dev_dbg(&client->dev, + "Detected Extended range EEPROM calibration %x\n", read); + mlx90632->mtyp = MLX90632_MTYP_EXTENDED; } else if ((read & MLX90632_DSP_MASK) == MLX90632_DSP_VERSION) { dev_dbg(&client->dev, - "Detected Unknown EEPROM calibration %x\n", read); + "Detected Unknown EEPROM calibration %x\n", read); } else { dev_err(&client->dev, "Wrong DSP version %x (expected %x)\n", @@ -679,6 +898,7 @@ static int mlx90632_probe(struct i2c_client *client, } mlx90632->emissivity = 1000; + mlx90632->object_ambient_temperature = 25000; /* 25 degrees milliCelsius */ pm_runtime_disable(&client->dev); ret = pm_runtime_set_active(&client->dev); diff --git a/drivers/most/Kconfig b/drivers/most/Kconfig index 60fc0820dad3..ebfe84e69715 100644 --- a/drivers/most/Kconfig +++ b/drivers/most/Kconfig @@ -23,4 +23,13 @@ config MOST_USB_HDM To compile this driver as a module, choose M here: the module will be called most_usb. + +config MOST_CDEV + tristate "Cdev" + + help + Say Y here if you want to commumicate via character devices. + + To compile this driver as a module, choose M here: the + module will be called most_cdev. endif diff --git a/drivers/most/Makefile b/drivers/most/Makefile index 6a3cb9056288..8b53ca46633f 100644 --- a/drivers/most/Makefile +++ b/drivers/most/Makefile @@ -4,3 +4,4 @@ most_core-y := core.o \ configfs.o obj-$(CONFIG_MOST_USB_HDM) += most_usb.o +obj-$(CONFIG_MOST_CDEV) += most_cdev.o diff --git a/drivers/staging/most/cdev/cdev.c b/drivers/most/most_cdev.c index 044880760b58..044880760b58 100644 --- a/drivers/staging/most/cdev/cdev.c +++ b/drivers/most/most_cdev.c diff --git a/drivers/net/wireless/microchip/wilc1000/spi.c b/drivers/net/wireless/microchip/wilc1000/spi.c index 3f19e3f38a39..a18dac0aa6b6 100644 --- a/drivers/net/wireless/microchip/wilc1000/spi.c +++ b/drivers/net/wireless/microchip/wilc1000/spi.c @@ -112,9 +112,10 @@ static int wilc_bus_probe(struct spi_device *spi) wilc->dev_irq_num = spi->irq; wilc->rtc_clk = devm_clk_get(&spi->dev, "rtc_clk"); - if (PTR_ERR_OR_ZERO(wilc->rtc_clk) == -EPROBE_DEFER) + if (PTR_ERR_OR_ZERO(wilc->rtc_clk) == -EPROBE_DEFER) { + kfree(spi_priv); return -EPROBE_DEFER; - else if (!IS_ERR(wilc->rtc_clk)) + } else if (!IS_ERR(wilc->rtc_clk)) clk_prepare_enable(wilc->rtc_clk); return 0; diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index e6c831c6cccc..2d0310448eba 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -116,4 +116,6 @@ source "drivers/staging/qlge/Kconfig" source "drivers/staging/wfx/Kconfig" +source "drivers/staging/hikey9xx/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index a3b1fd0622f9..757a892ab5b9 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -48,3 +48,4 @@ obj-$(CONFIG_FIELDBUS_DEV) += fieldbus/ obj-$(CONFIG_KPC2000) += kpc2000/ obj-$(CONFIG_QLGE) += qlge/ obj-$(CONFIG_WFX) += wfx/ +obj-y += hikey9xx/ diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 3c9f09506ffa..e1fe03ceb7f1 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -205,8 +205,8 @@ static int ion_dma_buf_attach(struct dma_buf *dmabuf, return 0; } -static void ion_dma_buf_detatch(struct dma_buf *dmabuf, - struct dma_buf_attachment *attachment) +static void ion_dma_buf_detach(struct dma_buf *dmabuf, + struct dma_buf_attachment *attachment) { struct ion_dma_buf_attachment *a = attachment->priv; struct ion_buffer *buffer = dmabuf->priv; @@ -331,7 +331,7 @@ static const struct dma_buf_ops dma_buf_ops = { .mmap = ion_mmap, .release = ion_dma_buf_release, .attach = ion_dma_buf_attach, - .detach = ion_dma_buf_detatch, + .detach = ion_dma_buf_detach, .begin_cpu_access = ion_dma_buf_begin_cpu_access, .end_cpu_access = ion_dma_buf_end_cpu_access, }; diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h index 09a940066c0e..b5d00a006dbb 100644 --- a/drivers/staging/comedi/comedi.h +++ b/drivers/staging/comedi/comedi.h @@ -680,7 +680,7 @@ struct comedi_rangeinfo { * value of 1 volt. * * The only defined flag value is %RF_EXTERNAL (%0x100), indicating that the - * the range needs to be multiplied by an external reference. + * range needs to be multiplied by an external reference. */ struct comedi_krange { int min; @@ -970,7 +970,7 @@ enum i8254_mode { * major reasons exist why this caused major confusion for users: * 1) The register values are _NOT_ in user documentation, but rather in * arcane locations, such as a few register programming manuals that are - * increasingly hard to find and the NI MHDDK (comments in in example code). + * increasingly hard to find and the NI MHDDK (comments in example code). * There is no one place to find the various valid values of the registers. * 2) The register values are _NOT_ completely consistent. There is no way to * gain any sense of intuition of which values, or even enums one should use diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 0dff1ac057cd..0e1b95ef9a4d 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -627,7 +627,7 @@ extern const struct comedi_lrange range_unknown; * @range: Array of &struct comedi_krange, one for each range. * * Each element of @range[] describes the minimum and maximum physical range - * range and the type of units. Typically, the type of unit is %UNIT_volt + * and the type of units. Typically, the type of unit is %UNIT_volt * (i.e. volts) and the minimum and maximum are in millionths of a volt. * There may also be a flag that indicates the minimum and maximum are merely * scale factors for an unknown, external reference. diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index fadefcb5c237..06fc7ed96200 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -544,7 +544,7 @@ static int apci1564_timer_insn_write(struct comedi_device *dev, { struct apci1564_private *devpriv = dev->private; - /* just write the last last to the reload register */ + /* just write the last to the reload register */ if (insn->n) { unsigned int val = data[insn->n - 1]; @@ -628,7 +628,7 @@ static int apci1564_counter_insn_write(struct comedi_device *dev, unsigned int chan = CR_CHAN(insn->chanspec); unsigned long iobase = devpriv->counters + APCI1564_COUNTER(chan); - /* just write the last last to the reload register */ + /* just write the last to the reload register */ if (insn->n) { unsigned int val = data[insn->n - 1]; diff --git a/drivers/staging/comedi/drivers/comedi_8255.c b/drivers/staging/comedi/drivers/comedi_8255.c index 3298725b9ba5..b7ca465933ee 100644 --- a/drivers/staging/comedi/drivers/comedi_8255.c +++ b/drivers/staging/comedi/drivers/comedi_8255.c @@ -248,7 +248,7 @@ EXPORT_SYMBOL_GPL(subdev_8255_mm_init); * subdev_8255_regbase - get offset of 8255 registers or call-back context * @s: comedi subdevice * - * Returns the 'regbase' parameter that was previously passed to to + * Returns the 'regbase' parameter that was previously passed to * subdev_8255_init() or subdev_8255_mm_init() to set up the subdevice. * Only valid if the subdevice was set up successfully. */ diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c index 2a9f7e9821a7..ab6d9e8269f3 100644 --- a/drivers/staging/comedi/drivers/ni_tiocmd.c +++ b/drivers/staging/comedi/drivers/ni_tiocmd.c @@ -286,7 +286,7 @@ int ni_tio_cmdtest(struct comedi_device *dev, * This should be done, but we don't yet know the actual * register values. These should be tested and then documented * in the ni_route_values/ni_*.csv files, with indication of - * who/when/which/how these these were tested. + * who/when/which/how these were tested. * When at least a e/m/660x series have been tested, this code * should be uncommented: * diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c index 58b3d07ae907..64eb649c9813 100644 --- a/drivers/staging/comedi/drivers/pcl726.c +++ b/drivers/staging/comedi/drivers/pcl726.c @@ -389,7 +389,7 @@ static int pcl726_attach(struct comedi_device *dev, } if (dev->irq) { - /* Digial Input subdevice - Interrupt support */ + /* Digital Input subdevice - Interrupt support */ s = &dev->subdevices[subdev++]; dev->read_subdev = s; s->type = COMEDI_SUBD_DI; diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index 7e1fc6ffb48c..b299d648a0eb 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -48,7 +48,7 @@ * * In the 48-channel version: * - * On subdev 0, the first 24 channels channels are edge-detect channels. + * On subdev 0, the first 24 channels are edge-detect channels. * * In the 96-channel board you have the following channels that can do edge * detection: diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index 1b1efa4d31f6..fe4408ebf6b3 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -164,7 +164,7 @@ static int daqp_clear_events(struct comedi_device *dev, int loops) /* * Reset any pending interrupts (my card has a tendency to require - * require multiple reads on the status register to achieve this). + * multiple reads on the status register to achieve this). */ while (--loops) { status = inb(dev->iobase + DAQP_STATUS_REG); diff --git a/drivers/staging/emxx_udc/Kconfig b/drivers/staging/emxx_udc/Kconfig index ad1478c53e9e..e7a95b3b6a2f 100644 --- a/drivers/staging/emxx_udc/Kconfig +++ b/drivers/staging/emxx_udc/Kconfig @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 config USB_EMXX tristate "EMXX USB Function Device Controller" - depends on USB_GADGET && (ARCH_RENESAS || (ARM && COMPILE_TEST)) + depends on USB_GADGET && (ARCH_RENESAS || COMPILE_TEST) help The Emma Mobile series of SoCs from Renesas Electronics and former NEC Electronics include USB Function hardware. diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c index 03929b9d3a8b..4ceaf1ead123 100644 --- a/drivers/staging/emxx_udc/emxx_udc.c +++ b/drivers/staging/emxx_udc/emxx_udc.c @@ -793,7 +793,7 @@ static int _nbu2ss_out_dma(struct nbu2ss_udc *udc, struct nbu2ss_req *req, u32 dmacnt; u32 burst = 1; u32 data; - int result = -EINVAL; + int result; struct fc_regs __iomem *preg = udc->p_regs; if (req->dma_flag) @@ -1288,8 +1288,6 @@ static void _nbu2ss_set_endpoint_stall(struct nbu2ss_udc *udc, _nbu2ss_bitset(&preg->EP_REGS[num].EP_CONTROL, data); } else { - /* Clear STALL */ - ep->stalled = false; if (ep_adrs & USB_DIR_IN) { _nbu2ss_bitclr(&preg->EP_REGS[num].EP_CONTROL , EPN_ISTL); @@ -1304,6 +1302,7 @@ static void _nbu2ss_set_endpoint_stall(struct nbu2ss_udc *udc, , data); } + /* Clear STALL */ ep->stalled = false; if (ep->halted) { ep->halted = false; @@ -2593,7 +2592,7 @@ static int nbu2ss_ep_queue(struct usb_ep *_ep, if (req->unaligned) { if (!ep->virt_buf) - ep->virt_buf = dma_alloc_coherent(NULL, PAGE_SIZE, + ep->virt_buf = dma_alloc_coherent(udc->dev, PAGE_SIZE, &ep->phys_buf, GFP_ATOMIC | GFP_DMA); if (ep->epnum > 0) { @@ -3073,8 +3072,8 @@ static int nbu2ss_drv_contest_init(struct platform_device *pdev, */ static int nbu2ss_drv_probe(struct platform_device *pdev) { - int status = -ENODEV; - struct nbu2ss_udc *udc; + int status; + struct nbu2ss_udc *udc; int irq; void __iomem *mmio_base; @@ -3148,7 +3147,7 @@ static int nbu2ss_drv_remove(struct platform_device *pdev) for (i = 0; i < NUM_ENDPOINTS; i++) { ep = &udc->ep[i]; if (ep->virt_buf) - dma_free_coherent(NULL, PAGE_SIZE, (void *)ep->virt_buf, + dma_free_coherent(udc->dev, PAGE_SIZE, (void *)ep->virt_buf, ep->phys_buf); } diff --git a/drivers/staging/emxx_udc/emxx_udc.h b/drivers/staging/emxx_udc/emxx_udc.h index 9c2671cb32f7..bca614d69aca 100644 --- a/drivers/staging/emxx_udc/emxx_udc.h +++ b/drivers/staging/emxx_udc/emxx_udc.h @@ -9,11 +9,6 @@ #define _LINUX_EMXX_H /*---------------------------------------------------------------------------*/ -/*----------------- Default undef */ -#if 0 -#define DEBUG -#define UDC_DEBUG_DUMP -#endif /*----------------- Default define */ #define USE_DMA 1 @@ -52,197 +47,163 @@ int vbus_irq; #define U2F_ENABLE 1 #define U2F_DISABLE 0 -/*------- BIT */ -#define BIT00 0x00000001 -#define BIT01 0x00000002 -#define BIT02 0x00000004 -#define BIT03 0x00000008 -#define BIT04 0x00000010 -#define BIT05 0x00000020 -#define BIT06 0x00000040 -#define BIT07 0x00000080 -#define BIT08 0x00000100 -#define BIT09 0x00000200 -#define BIT10 0x00000400 -#define BIT11 0x00000800 -#define BIT12 0x00001000 -#define BIT13 0x00002000 -#define BIT14 0x00004000 -#define BIT15 0x00008000 -#define BIT16 0x00010000 -#define BIT17 0x00020000 -#define BIT18 0x00040000 -#define BIT19 0x00080000 -#define BIT20 0x00100000 -#define BIT21 0x00200000 -#define BIT22 0x00400000 -#define BIT23 0x00800000 -#define BIT24 0x01000000 -#define BIT25 0x02000000 -#define BIT26 0x04000000 -#define BIT27 0x08000000 -#define BIT28 0x10000000 -#define BIT29 0x20000000 -#define BIT30 0x40000000 -#define BIT31 0x80000000 - -#define TEST_FORCE_ENABLE (BIT18 + BIT16) - -#define INT_SEL BIT10 -#define CONSTFS BIT09 -#define SOF_RCV BIT08 -#define RSUM_IN BIT07 -#define SUSPEND BIT06 -#define CONF BIT05 -#define DEFAULT BIT04 -#define CONNECTB BIT03 -#define PUE2 BIT02 +#define TEST_FORCE_ENABLE (BIT(18) | BIT(16)) + +#define INT_SEL BIT(10) +#define CONSTFS BIT(9) +#define SOF_RCV BIT(8) +#define RSUM_IN BIT(7) +#define SUSPEND BIT(6) +#define CONF BIT(5) +#define DEFAULT BIT(4) +#define CONNECTB BIT(3) +#define PUE2 BIT(2) #define MAX_TEST_MODE_NUM 0x05 #define TEST_MODE_SHIFT 16 /*------- (0x0004) USB Status Register */ -#define SPEED_MODE BIT06 -#define HIGH_SPEED BIT06 +#define SPEED_MODE BIT(6) +#define HIGH_SPEED BIT(6) -#define CONF BIT05 -#define DEFAULT BIT04 -#define USB_RST BIT03 -#define SPND_OUT BIT02 -#define RSUM_OUT BIT01 +#define CONF BIT(5) +#define DEFAULT BIT(4) +#define USB_RST BIT(3) +#define SPND_OUT BIT(2) +#define RSUM_OUT BIT(1) /*------- (0x0008) USB Address Register */ #define USB_ADDR 0x007F0000 -#define SOF_STATUS BIT15 -#define UFRAME (BIT14 + BIT13 + BIT12) +#define SOF_STATUS BIT(15) +#define UFRAME (BIT(14) | BIT(13) | BIT(12)) #define FRAME 0x000007FF #define USB_ADRS_SHIFT 16 /*------- (0x000C) UTMI Characteristic 1 Register */ -#define SQUSET (BIT07 + BIT06 + BIT05 + BIT04) +#define SQUSET (BIT(7) | BIT(6) | BIT(5) | BIT(4)) -#define USB_SQUSET (BIT06 + BIT05 + BIT04) +#define USB_SQUSET (BIT(6) | BIT(5) | BIT(4)) /*------- (0x0010) TEST Control Register */ -#define FORCEHS BIT02 -#define CS_TESTMODEEN BIT01 -#define LOOPBACK BIT00 +#define FORCEHS BIT(2) +#define CS_TESTMODEEN BIT(1) +#define LOOPBACK BIT(0) /*------- (0x0018) Setup Data 0 Register */ /*------- (0x001C) Setup Data 1 Register */ /*------- (0x0020) USB Interrupt Status Register */ #define EPN_INT 0x00FFFF00 -#define EP15_INT BIT23 -#define EP14_INT BIT22 -#define EP13_INT BIT21 -#define EP12_INT BIT20 -#define EP11_INT BIT19 -#define EP10_INT BIT18 -#define EP9_INT BIT17 -#define EP8_INT BIT16 -#define EP7_INT BIT15 -#define EP6_INT BIT14 -#define EP5_INT BIT13 -#define EP4_INT BIT12 -#define EP3_INT BIT11 -#define EP2_INT BIT10 -#define EP1_INT BIT09 -#define EP0_INT BIT08 -#define SPEED_MODE_INT BIT06 -#define SOF_ERROR_INT BIT05 -#define SOF_INT BIT04 -#define USB_RST_INT BIT03 -#define SPND_INT BIT02 -#define RSUM_INT BIT01 +#define EP15_INT BIT(23) +#define EP14_INT BIT(22) +#define EP13_INT BIT(21) +#define EP12_INT BIT(20) +#define EP11_INT BIT(19) +#define EP10_INT BIT(18) +#define EP9_INT BIT(17) +#define EP8_INT BIT(16) +#define EP7_INT BIT(15) +#define EP6_INT BIT(14) +#define EP5_INT BIT(13) +#define EP4_INT BIT(12) +#define EP3_INT BIT(11) +#define EP2_INT BIT(10) +#define EP1_INT BIT(9) +#define EP0_INT BIT(8) +#define SPEED_MODE_INT BIT(6) +#define SOF_ERROR_INT BIT(5) +#define SOF_INT BIT(4) +#define USB_RST_INT BIT(3) +#define SPND_INT BIT(2) +#define RSUM_INT BIT(1) #define USB_INT_STA_RW 0x7E /*------- (0x0024) USB Interrupt Enable Register */ #define EP15_0_EN 0x00FFFF00 -#define EP15_EN BIT23 -#define EP14_EN BIT22 -#define EP13_EN BIT21 -#define EP12_EN BIT20 -#define EP11_EN BIT19 -#define EP10_EN BIT18 -#define EP9_EN BIT17 -#define EP8_EN BIT16 -#define EP7_EN BIT15 -#define EP6_EN BIT14 -#define EP5_EN BIT13 -#define EP4_EN BIT12 -#define EP3_EN BIT11 -#define EP2_EN BIT10 -#define EP1_EN BIT09 -#define EP0_EN BIT08 -#define SPEED_MODE_EN BIT06 -#define SOF_ERROR_EN BIT05 -#define SOF_EN BIT04 -#define USB_RST_EN BIT03 -#define SPND_EN BIT02 -#define RSUM_EN BIT01 +#define EP15_EN BIT(23) +#define EP14_EN BIT(22) +#define EP13_EN BIT(21) +#define EP12_EN BIT(20) +#define EP11_EN BIT(19) +#define EP10_EN BIT(18) +#define EP9_EN BIT(17) +#define EP8_EN BIT(16) +#define EP7_EN BIT(15) +#define EP6_EN BIT(14) +#define EP5_EN BIT(13) +#define EP4_EN BIT(12) +#define EP3_EN BIT(11) +#define EP2_EN BIT(10) +#define EP1_EN BIT(9) +#define EP0_EN BIT(8) +#define SPEED_MODE_EN BIT(6) +#define SOF_ERROR_EN BIT(5) +#define SOF_EN BIT(4) +#define USB_RST_EN BIT(3) +#define SPND_EN BIT(2) +#define RSUM_EN BIT(1) #define USB_INT_EN_BIT \ (EP0_EN | SPEED_MODE_EN | USB_RST_EN | SPND_EN | RSUM_EN) /*------- (0x0028) EP0 Control Register */ -#define EP0_STGSEL BIT18 -#define EP0_OVERSEL BIT17 -#define EP0_AUTO BIT16 -#define EP0_PIDCLR BIT09 -#define EP0_BCLR BIT08 -#define EP0_DEND BIT07 -#define EP0_DW (BIT06 + BIT05) +#define EP0_STGSEL BIT(18) +#define EP0_OVERSEL BIT(17) +#define EP0_AUTO BIT(16) +#define EP0_PIDCLR BIT(9) +#define EP0_BCLR BIT(8) +#define EP0_DEND BIT(7) +#define EP0_DW (BIT(6) | BIT(5)) #define EP0_DW4 0 -#define EP0_DW3 (BIT06 + BIT05) -#define EP0_DW2 BIT06 -#define EP0_DW1 BIT05 +#define EP0_DW3 (BIT(6) | BIT(5)) +#define EP0_DW2 BIT(6) +#define EP0_DW1 BIT(5) -#define EP0_INAK_EN BIT04 -#define EP0_PERR_NAK_CLR BIT03 -#define EP0_STL BIT02 -#define EP0_INAK BIT01 -#define EP0_ONAK BIT00 +#define EP0_INAK_EN BIT(4) +#define EP0_PERR_NAK_CLR BIT(3) +#define EP0_STL BIT(2) +#define EP0_INAK BIT(1) +#define EP0_ONAK BIT(0) /*------- (0x002C) EP0 Status Register */ -#define EP0_PID BIT18 -#define EP0_PERR_NAK BIT17 -#define EP0_PERR_NAK_INT BIT16 -#define EP0_OUT_NAK_INT BIT15 -#define EP0_OUT_NULL BIT14 -#define EP0_OUT_FULL BIT13 -#define EP0_OUT_EMPTY BIT12 -#define EP0_IN_NAK_INT BIT11 -#define EP0_IN_DATA BIT10 -#define EP0_IN_FULL BIT09 -#define EP0_IN_EMPTY BIT08 -#define EP0_OUT_NULL_INT BIT07 -#define EP0_OUT_OR_INT BIT06 -#define EP0_OUT_INT BIT05 -#define EP0_IN_INT BIT04 -#define EP0_STALL_INT BIT03 -#define STG_END_INT BIT02 -#define STG_START_INT BIT01 -#define SETUP_INT BIT00 - -#define EP0_STATUS_RW_BIT (BIT16 | BIT15 | BIT11 | 0xFF) +#define EP0_PID BIT(18) +#define EP0_PERR_NAK BIT(17) +#define EP0_PERR_NAK_INT BIT(16) +#define EP0_OUT_NAK_INT BIT(15) +#define EP0_OUT_NULL BIT(14) +#define EP0_OUT_FULL BIT(13) +#define EP0_OUT_EMPTY BIT(12) +#define EP0_IN_NAK_INT BIT(11) +#define EP0_IN_DATA BIT(10) +#define EP0_IN_FULL BIT(9) +#define EP0_IN_EMPTY BIT(8) +#define EP0_OUT_NULL_INT BIT(7) +#define EP0_OUT_OR_INT BIT(6) +#define EP0_OUT_INT BIT(5) +#define EP0_IN_INT BIT(4) +#define EP0_STALL_INT BIT(3) +#define STG_END_INT BIT(2) +#define STG_START_INT BIT(1) +#define SETUP_INT BIT(0) + +#define EP0_STATUS_RW_BIT (BIT(16) | BIT(15) | BIT(11) | 0xFF) /*------- (0x0030) EP0 Interrupt Enable Register */ -#define EP0_PERR_NAK_EN BIT16 -#define EP0_OUT_NAK_EN BIT15 +#define EP0_PERR_NAK_EN BIT(16) +#define EP0_OUT_NAK_EN BIT(15) -#define EP0_IN_NAK_EN BIT11 +#define EP0_IN_NAK_EN BIT(11) -#define EP0_OUT_NULL_EN BIT07 -#define EP0_OUT_OR_EN BIT06 -#define EP0_OUT_EN BIT05 -#define EP0_IN_EN BIT04 -#define EP0_STALL_EN BIT03 -#define STG_END_EN BIT02 -#define STG_START_EN BIT01 -#define SETUP_EN BIT00 +#define EP0_OUT_NULL_EN BIT(7) +#define EP0_OUT_OR_EN BIT(6) +#define EP0_OUT_EN BIT(5) +#define EP0_IN_EN BIT(4) +#define EP0_STALL_EN BIT(3) +#define STG_END_EN BIT(2) +#define STG_START_EN BIT(1) +#define SETUP_EN BIT(0) #define EP0_INT_EN_BIT \ (EP0_OUT_OR_EN | EP0_OUT_EN | EP0_IN_EN | STG_END_EN | SETUP_EN) @@ -254,90 +215,90 @@ int vbus_irq; /*------- (0x003C) EP0 Write Register */ /*------- (0x0040:) EPN Control Register */ -#define EPN_EN BIT31 -#define EPN_BUF_TYPE BIT30 -#define EPN_BUF_SINGLE BIT30 +#define EPN_EN BIT(31) +#define EPN_BUF_TYPE BIT(30) +#define EPN_BUF_SINGLE BIT(30) -#define EPN_DIR0 BIT26 -#define EPN_MODE (BIT25 + BIT24) +#define EPN_DIR0 BIT(26) +#define EPN_MODE (BIT(25) | BIT(24)) #define EPN_BULK 0 -#define EPN_INTERRUPT BIT24 -#define EPN_ISO BIT25 - -#define EPN_OVERSEL BIT17 -#define EPN_AUTO BIT16 - -#define EPN_IPIDCLR BIT11 -#define EPN_OPIDCLR BIT10 -#define EPN_BCLR BIT09 -#define EPN_CBCLR BIT08 -#define EPN_DEND BIT07 -#define EPN_DW (BIT06 + BIT05) +#define EPN_INTERRUPT BIT(24) +#define EPN_ISO BIT(25) + +#define EPN_OVERSEL BIT(17) +#define EPN_AUTO BIT(16) + +#define EPN_IPIDCLR BIT(11) +#define EPN_OPIDCLR BIT(10) +#define EPN_BCLR BIT(9) +#define EPN_CBCLR BIT(8) +#define EPN_DEND BIT(7) +#define EPN_DW (BIT(6) | BIT(5)) #define EPN_DW4 0 -#define EPN_DW3 (BIT06 + BIT05) -#define EPN_DW2 BIT06 -#define EPN_DW1 BIT05 +#define EPN_DW3 (BIT(6) | BIT(5)) +#define EPN_DW2 BIT(6) +#define EPN_DW1 BIT(5) -#define EPN_OSTL_EN BIT04 -#define EPN_ISTL BIT03 -#define EPN_OSTL BIT02 +#define EPN_OSTL_EN BIT(4) +#define EPN_ISTL BIT(3) +#define EPN_OSTL BIT(2) -#define EPN_ONAK BIT00 +#define EPN_ONAK BIT(0) /*------- (0x0044:) EPN Status Register */ -#define EPN_ISO_PIDERR BIT29 /* R */ -#define EPN_OPID BIT28 /* R */ -#define EPN_OUT_NOTKN BIT27 /* R */ -#define EPN_ISO_OR BIT26 /* R */ - -#define EPN_ISO_CRC BIT24 /* R */ -#define EPN_OUT_END_INT BIT23 /* RW */ -#define EPN_OUT_OR_INT BIT22 /* RW */ -#define EPN_OUT_NAK_ERR_INT BIT21 /* RW */ -#define EPN_OUT_STALL_INT BIT20 /* RW */ -#define EPN_OUT_INT BIT19 /* RW */ -#define EPN_OUT_NULL_INT BIT18 /* RW */ -#define EPN_OUT_FULL BIT17 /* R */ -#define EPN_OUT_EMPTY BIT16 /* R */ - -#define EPN_IPID BIT10 /* R */ -#define EPN_IN_NOTKN BIT09 /* R */ -#define EPN_ISO_UR BIT08 /* R */ -#define EPN_IN_END_INT BIT07 /* RW */ - -#define EPN_IN_NAK_ERR_INT BIT05 /* RW */ -#define EPN_IN_STALL_INT BIT04 /* RW */ -#define EPN_IN_INT BIT03 /* RW */ -#define EPN_IN_DATA BIT02 /* R */ -#define EPN_IN_FULL BIT01 /* R */ -#define EPN_IN_EMPTY BIT00 /* R */ +#define EPN_ISO_PIDERR BIT(29) /* R */ +#define EPN_OPID BIT(28) /* R */ +#define EPN_OUT_NOTKN BIT(27) /* R */ +#define EPN_ISO_OR BIT(26) /* R */ + +#define EPN_ISO_CRC BIT(24) /* R */ +#define EPN_OUT_END_INT BIT(23) /* RW */ +#define EPN_OUT_OR_INT BIT(22) /* RW */ +#define EPN_OUT_NAK_ERR_INT BIT(21) /* RW */ +#define EPN_OUT_STALL_INT BIT(20) /* RW */ +#define EPN_OUT_INT BIT(19) /* RW */ +#define EPN_OUT_NULL_INT BIT(18) /* RW */ +#define EPN_OUT_FULL BIT(17) /* R */ +#define EPN_OUT_EMPTY BIT(16) /* R */ + +#define EPN_IPID BIT(10) /* R */ +#define EPN_IN_NOTKN BIT(9) /* R */ +#define EPN_ISO_UR BIT(8) /* R */ +#define EPN_IN_END_INT BIT(7) /* RW */ + +#define EPN_IN_NAK_ERR_INT BIT(5) /* RW */ +#define EPN_IN_STALL_INT BIT(4) /* RW */ +#define EPN_IN_INT BIT(3) /* RW */ +#define EPN_IN_DATA BIT(2) /* R */ +#define EPN_IN_FULL BIT(1) /* R */ +#define EPN_IN_EMPTY BIT(0) /* R */ #define EPN_INT_EN \ (EPN_OUT_END_INT | EPN_OUT_INT | EPN_IN_END_INT | EPN_IN_INT) /*------- (0x0048:) EPN Interrupt Enable Register */ -#define EPN_OUT_END_EN BIT23 /* RW */ -#define EPN_OUT_OR_EN BIT22 /* RW */ -#define EPN_OUT_NAK_ERR_EN BIT21 /* RW */ -#define EPN_OUT_STALL_EN BIT20 /* RW */ -#define EPN_OUT_EN BIT19 /* RW */ -#define EPN_OUT_NULL_EN BIT18 /* RW */ +#define EPN_OUT_END_EN BIT(23) /* RW */ +#define EPN_OUT_OR_EN BIT(22) /* RW */ +#define EPN_OUT_NAK_ERR_EN BIT(21) /* RW */ +#define EPN_OUT_STALL_EN BIT(20) /* RW */ +#define EPN_OUT_EN BIT(19) /* RW */ +#define EPN_OUT_NULL_EN BIT(18) /* RW */ -#define EPN_IN_END_EN BIT07 /* RW */ +#define EPN_IN_END_EN BIT(7) /* RW */ -#define EPN_IN_NAK_ERR_EN BIT05 /* RW */ -#define EPN_IN_STALL_EN BIT04 /* RW */ -#define EPN_IN_EN BIT03 /* RW */ +#define EPN_IN_NAK_ERR_EN BIT(5) /* RW */ +#define EPN_IN_STALL_EN BIT(4) /* RW */ +#define EPN_IN_EN BIT(3) /* RW */ /*------- (0x004C:) EPN Interrupt Enable Register */ -#define EPN_STOP_MODE BIT11 -#define EPN_DEND_SET BIT10 -#define EPN_BURST_SET BIT09 -#define EPN_STOP_SET BIT08 +#define EPN_STOP_MODE BIT(11) +#define EPN_DEND_SET BIT(10) +#define EPN_BURST_SET BIT(9) +#define EPN_STOP_SET BIT(8) -#define EPN_DMA_EN BIT04 +#define EPN_DMA_EN BIT(4) -#define EPN_DMAMODE0 BIT00 +#define EPN_DMAMODE0 BIT(0) /*------- (0x0050:) EPN MaxPacket & BaseAddress Register */ #define EPN_BASEAD 0x1FFF0000 @@ -351,62 +312,62 @@ int vbus_irq; /*------- (0x005C:) EPN Write Register */ /*------- (0x1000) AHBSCTR Register */ -#define WAIT_MODE BIT00 +#define WAIT_MODE BIT(0) /*------- (0x1004) AHBMCTR Register */ -#define ARBITER_CTR BIT31 /* RW */ -#define MCYCLE_RST BIT12 /* RW */ +#define ARBITER_CTR BIT(31) /* RW */ +#define MCYCLE_RST BIT(12) /* RW */ -#define ENDIAN_CTR (BIT09 + BIT08) /* RW */ -#define ENDIAN_BYTE_SWAP BIT09 +#define ENDIAN_CTR (BIT(9) | BIT(8)) /* RW */ +#define ENDIAN_BYTE_SWAP BIT(9) #define ENDIAN_HALF_WORD_SWAP ENDIAN_CTR -#define HBUSREQ_MODE BIT05 /* RW */ -#define HTRANS_MODE BIT04 /* RW */ +#define HBUSREQ_MODE BIT(5) /* RW */ +#define HTRANS_MODE BIT(4) /* RW */ -#define WBURST_TYPE BIT02 /* RW */ -#define BURST_TYPE (BIT01 + BIT00) /* RW */ +#define WBURST_TYPE BIT(2) /* RW */ +#define BURST_TYPE (BIT(1) | BIT(0)) /* RW */ #define BURST_MAX_16 0 -#define BURST_MAX_8 BIT00 -#define BURST_MAX_4 BIT01 +#define BURST_MAX_8 BIT(0) +#define BURST_MAX_4 BIT(1) #define BURST_SINGLE BURST_TYPE /*------- (0x1008) AHBBINT Register */ #define DMA_ENDINT 0xFFFE0000 /* RW */ -#define AHB_VBUS_INT BIT13 /* RW */ +#define AHB_VBUS_INT BIT(13) /* RW */ -#define MBUS_ERRINT BIT06 /* RW */ +#define MBUS_ERRINT BIT(6) /* RW */ -#define SBUS_ERRINT0 BIT04 /* RW */ +#define SBUS_ERRINT0 BIT(4) /* RW */ #define ERR_MASTER 0x0000000F /* R */ /*------- (0x100C) AHBBINTEN Register */ #define DMA_ENDINTEN 0xFFFE0000 /* RW */ -#define VBUS_INTEN BIT13 /* RW */ +#define VBUS_INTEN BIT(13) /* RW */ -#define MBUS_ERRINTEN BIT06 /* RW */ +#define MBUS_ERRINTEN BIT(6) /* RW */ -#define SBUS_ERRINT0EN BIT04 /* RW */ +#define SBUS_ERRINT0EN BIT(4) /* RW */ /*------- (0x1010) EPCTR Register */ -#define DIRPD BIT12 /* RW */ +#define DIRPD BIT(12) /* RW */ -#define VBUS_LEVEL BIT08 /* R */ +#define VBUS_LEVEL BIT(8) /* R */ -#define PLL_RESUME BIT05 /* RW */ -#define PLL_LOCK BIT04 /* R */ +#define PLL_RESUME BIT(5) /* RW */ +#define PLL_LOCK BIT(4) /* R */ -#define EPC_RST BIT00 /* RW */ +#define EPC_RST BIT(0) /* RW */ /*------- (0x1014) USBF_EPTEST Register */ -#define LINESTATE (BIT09 + BIT08) /* R */ -#define DM_LEVEL BIT09 /* R */ -#define DP_LEVEL BIT08 /* R */ +#define LINESTATE (BIT(9) | BIT(8)) /* R */ +#define DM_LEVEL BIT(9) /* R */ +#define DP_LEVEL BIT(8) /* R */ -#define PHY_TST BIT01 /* RW */ -#define PHY_TSTCLK BIT00 /* RW */ +#define PHY_TST BIT(1) /* RW */ +#define PHY_TSTCLK BIT(0) /* RW */ /*------- (0x1020) USBSSVER Register */ #define AHBB_VER 0x00FF0000 /* R */ @@ -420,8 +381,8 @@ int vbus_irq; /*------- (0x1110:) EPNDCR1 Register */ #define DCR1_EPN_DMACNT 0x00FF0000 /* RW */ -#define DCR1_EPN_DIR0 BIT01 /* RW */ -#define DCR1_EPN_REQEN BIT00 /* RW */ +#define DCR1_EPN_DIR0 BIT(1) /* RW */ +#define DCR1_EPN_REQEN BIT(0) /* RW */ /*------- (0x1114:) EPNDCR2 Register */ #define DCR2_EPN_LMPKT 0x07FF0000 /* RW */ diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c index aec0f19597a9..db83d34cd677 100644 --- a/drivers/staging/fwserial/fwserial.c +++ b/drivers/staging/fwserial/fwserial.c @@ -466,7 +466,7 @@ static void fwtty_throttle_port(struct fwtty_port *port) * fwtty_do_hangup - wait for ldisc to deliver all pending rx; only then hangup * * When the remote has finished tx, and all in-flight rx has been received and - * and pushed to the flip buffer, the remote may close its device. This will + * pushed to the flip buffer, the remote may close its device. This will * drop DTR on the remote which will drop carrier here. Typically, the tty is * hung up when carrier is dropped or lost. * diff --git a/drivers/staging/greybus/gbphy.h b/drivers/staging/greybus/gbphy.h index 087928a586fb..d4a225b76338 100644 --- a/drivers/staging/greybus/gbphy.h +++ b/drivers/staging/greybus/gbphy.h @@ -36,9 +36,9 @@ struct gbphy_device_id { struct gbphy_driver { const char *name; - int (*probe)(struct gbphy_device *, + int (*probe)(struct gbphy_device *device, const struct gbphy_device_id *id); - void (*remove)(struct gbphy_device *); + void (*remove)(struct gbphy_device *device); const struct gbphy_device_id *id_table; struct device_driver driver; diff --git a/drivers/staging/hikey9xx/Kconfig b/drivers/staging/hikey9xx/Kconfig new file mode 100644 index 000000000000..0e97b5b9a56a --- /dev/null +++ b/drivers/staging/hikey9xx/Kconfig @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: GPL-2.0 + +# to be placed at drivers/spmi +config SPMI_HISI3670 + tristate "Hisilicon 3670 SPMI Controller" + select IRQ_DOMAIN_HIERARCHY + depends on HAS_IOMEM + depends on SPMI + help + If you say yes to this option, support will be included for the + built-in SPMI PMIC Arbiter interface on Hisilicon 3670 + processors. + +# to be placed at drivers/mfd +config MFD_HI6421_SPMI + tristate "HiSilicon Hi6421v600 SPMI PMU/Codec IC" + depends on OF + depends on SPMI + select MFD_CORE + help + Add support for HiSilicon Hi6421v600 SPMI PMIC. Hi6421 includes + multi-functions, such as regulators, RTC, codec, Coulomb counter, + etc. + + This driver includes core APIs _only_. You have to select + individual components like voltage regulators under corresponding + menus in order to enable them. + We communicate with the Hi6421v600 via a SPMI bus. + +# to be placed at drivers/regulator +config REGULATOR_HI6421V600 + tristate "HiSilicon Hi6421v600 PMIC voltage regulator support" + depends on MFD_HI6421_SPMI && OF + depends on REGULATOR + help + This driver provides support for the voltage regulators on + HiSilicon Hi6421v600 PMU / Codec IC. + This is used on Kirin 3670 boards, like HiKey 970. diff --git a/drivers/staging/hikey9xx/Makefile b/drivers/staging/hikey9xx/Makefile new file mode 100644 index 000000000000..9371dcc3d35b --- /dev/null +++ b/drivers/staging/hikey9xx/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_SPMI_HISI3670) += hisi-spmi-controller.o +obj-$(CONFIG_MFD_HI6421_SPMI) += hi6421-spmi-pmic.o +obj-$(CONFIG_REGULATOR_HI6421V600) += hi6421v600-regulator.o diff --git a/drivers/staging/hikey9xx/TODO b/drivers/staging/hikey9xx/TODO new file mode 100644 index 000000000000..65e7996a3066 --- /dev/null +++ b/drivers/staging/hikey9xx/TODO @@ -0,0 +1,5 @@ +ToDo list: + +- Port other drivers needed by Hikey 960/970; +- Test drivers on Hikey 960; +- Validate device tree bindings. diff --git a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c new file mode 100644 index 000000000000..64b30d263c8d --- /dev/null +++ b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c @@ -0,0 +1,342 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Device driver for regulators in HISI PMIC IC + * + * Copyright (c) 2013 Linaro Ltd. + * Copyright (c) 2011 Hisilicon. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/irq.h> +#include <linux/mfd/core.h> +#include <linux/mfd/hi6421-spmi-pmic.h> +#include <linux/module.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/of_gpio.h> +#include <linux/of.h> +#include <linux/of_irq.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/spmi.h> + +/* 8-bit register offset in PMIC */ +#define HISI_MASK_STATE 0xff + +#define HISI_IRQ_ARRAY 2 +#define HISI_IRQ_NUM (HISI_IRQ_ARRAY * 8) + +#define SOC_PMIC_IRQ_MASK_0_ADDR 0x0202 +#define SOC_PMIC_IRQ0_ADDR 0x0212 + +#define HISI_IRQ_KEY_NUM 0 +#define HISI_IRQ_KEY_VALUE 0xc0 +#define HISI_IRQ_KEY_DOWN 7 +#define HISI_IRQ_KEY_UP 6 + +#define HISI_MASK_FIELD 0xFF +#define HISI_BITS 8 + +/*define the first group interrupt register number*/ +#define HISI_PMIC_FIRST_GROUP_INT_NUM 2 + +static const struct mfd_cell hi6421v600_devs[] = { + { .name = "hi6421v600-regulator", }, +}; + +/* + * The PMIC register is only 8-bit. + * Hisilicon SoC use hardware to map PMIC register into SoC mapping. + * At here, we are accessing SoC register with 32-bit. + */ +int hi6421_spmi_pmic_read(struct hi6421_spmi_pmic *pmic, int reg) +{ + struct spmi_device *pdev; + u8 read_value = 0; + u32 ret; + + pdev = to_spmi_device(pmic->dev); + if (!pdev) { + pr_err("%s: pdev get failed!\n", __func__); + return -ENODEV; + } + + ret = spmi_ext_register_readl(pdev, reg, &read_value, 1); + if (ret) { + pr_err("%s: spmi_ext_register_readl failed!\n", __func__); + return ret; + } + return read_value; +} +EXPORT_SYMBOL(hi6421_spmi_pmic_read); + +int hi6421_spmi_pmic_write(struct hi6421_spmi_pmic *pmic, int reg, u32 val) +{ + struct spmi_device *pdev; + u32 ret; + + pdev = to_spmi_device(pmic->dev); + if (!pdev) { + pr_err("%s: pdev get failed!\n", __func__); + return -ENODEV; + } + + ret = spmi_ext_register_writel(pdev, reg, (unsigned char *)&val, 1); + if (ret) + pr_err("%s: spmi_ext_register_writel failed!\n", __func__); + + return ret; +} +EXPORT_SYMBOL(hi6421_spmi_pmic_write); + +int hi6421_spmi_pmic_rmw(struct hi6421_spmi_pmic *pmic, int reg, + u32 mask, u32 bits) +{ + unsigned long flags; + u32 data; + int ret; + + spin_lock_irqsave(&pmic->lock, flags); + data = hi6421_spmi_pmic_read(pmic, reg) & ~mask; + data |= mask & bits; + ret = hi6421_spmi_pmic_write(pmic, reg, data); + spin_unlock_irqrestore(&pmic->lock, flags); + + return ret; +} +EXPORT_SYMBOL(hi6421_spmi_pmic_rmw); + +static irqreturn_t hi6421_spmi_irq_handler(int irq, void *data) +{ + struct hi6421_spmi_pmic *pmic = (struct hi6421_spmi_pmic *)data; + unsigned long pending; + int i, offset; + + for (i = 0; i < HISI_IRQ_ARRAY; i++) { + pending = hi6421_spmi_pmic_read(pmic, (i + SOC_PMIC_IRQ0_ADDR)); + pending &= HISI_MASK_FIELD; + if (pending != 0) + pr_debug("pending[%d]=0x%lx\n\r", i, pending); + + hi6421_spmi_pmic_write(pmic, (i + SOC_PMIC_IRQ0_ADDR), pending); + + /* solve powerkey order */ + if ((i == HISI_IRQ_KEY_NUM) && + ((pending & HISI_IRQ_KEY_VALUE) == HISI_IRQ_KEY_VALUE)) { + generic_handle_irq(pmic->irqs[HISI_IRQ_KEY_DOWN]); + generic_handle_irq(pmic->irqs[HISI_IRQ_KEY_UP]); + pending &= (~HISI_IRQ_KEY_VALUE); + } + + if (pending) { + for_each_set_bit(offset, &pending, HISI_BITS) + generic_handle_irq(pmic->irqs[offset + i * HISI_BITS]); + } + } + + return IRQ_HANDLED; +} + +static void hi6421_spmi_irq_mask(struct irq_data *d) +{ + struct hi6421_spmi_pmic *pmic = irq_data_get_irq_chip_data(d); + u32 data, offset; + unsigned long flags; + + offset = (irqd_to_hwirq(d) >> 3); + offset += SOC_PMIC_IRQ_MASK_0_ADDR; + + spin_lock_irqsave(&pmic->lock, flags); + data = hi6421_spmi_pmic_read(pmic, offset); + data |= (1 << (irqd_to_hwirq(d) & 0x07)); + hi6421_spmi_pmic_write(pmic, offset, data); + spin_unlock_irqrestore(&pmic->lock, flags); +} + +static void hi6421_spmi_irq_unmask(struct irq_data *d) +{ + struct hi6421_spmi_pmic *pmic = irq_data_get_irq_chip_data(d); + u32 data, offset; + unsigned long flags; + + offset = (irqd_to_hwirq(d) >> 3); + offset += SOC_PMIC_IRQ_MASK_0_ADDR; + + spin_lock_irqsave(&pmic->lock, flags); + data = hi6421_spmi_pmic_read(pmic, offset); + data &= ~(1 << (irqd_to_hwirq(d) & 0x07)); + hi6421_spmi_pmic_write(pmic, offset, data); + spin_unlock_irqrestore(&pmic->lock, flags); +} + +static struct irq_chip hi6421_spmi_pmu_irqchip = { + .name = "hisi-irq", + .irq_mask = hi6421_spmi_irq_mask, + .irq_unmask = hi6421_spmi_irq_unmask, + .irq_disable = hi6421_spmi_irq_mask, + .irq_enable = hi6421_spmi_irq_unmask, +}; + +static int hi6421_spmi_irq_map(struct irq_domain *d, unsigned int virq, + irq_hw_number_t hw) +{ + struct hi6421_spmi_pmic *pmic = d->host_data; + + irq_set_chip_and_handler_name(virq, &hi6421_spmi_pmu_irqchip, + handle_simple_irq, "hisi"); + irq_set_chip_data(virq, pmic); + irq_set_irq_type(virq, IRQ_TYPE_NONE); + + return 0; +} + +static const struct irq_domain_ops hi6421_spmi_domain_ops = { + .map = hi6421_spmi_irq_map, + .xlate = irq_domain_xlate_twocell, +}; + +static void hi6421_spmi_pmic_irq_prc(struct hi6421_spmi_pmic *pmic) +{ + int i, pending; + + for (i = 0 ; i < HISI_IRQ_ARRAY; i++) + hi6421_spmi_pmic_write(pmic, SOC_PMIC_IRQ_MASK_0_ADDR + i, + HISI_MASK_STATE); + + for (i = 0 ; i < HISI_IRQ_ARRAY; i++) { + pending = hi6421_spmi_pmic_read(pmic, SOC_PMIC_IRQ0_ADDR + i); + + pr_debug("PMU IRQ address value:irq[0x%x] = 0x%x\n", + SOC_PMIC_IRQ0_ADDR + i, pending); + hi6421_spmi_pmic_write(pmic, SOC_PMIC_IRQ0_ADDR + i, + HISI_MASK_STATE); + } +} + +static int hi6421_spmi_pmic_probe(struct spmi_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct hi6421_spmi_pmic *pmic; + unsigned int virq; + int ret, i; + + pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL); + if (!pmic) + return -ENOMEM; + + spin_lock_init(&pmic->lock); + + pmic->dev = dev; + + pmic->gpio = of_get_gpio(np, 0); + if (pmic->gpio < 0) + return pmic->gpio; + + if (!gpio_is_valid(pmic->gpio)) + return -EINVAL; + + ret = devm_gpio_request_one(dev, pmic->gpio, GPIOF_IN, "pmic"); + if (ret < 0) { + dev_err(dev, "failed to request gpio%d\n", pmic->gpio); + return ret; + } + + pmic->irq = gpio_to_irq(pmic->gpio); + + hi6421_spmi_pmic_irq_prc(pmic); + + pmic->irqs = devm_kzalloc(dev, HISI_IRQ_NUM * sizeof(int), GFP_KERNEL); + if (!pmic->irqs) + goto irq_malloc; + + pmic->domain = irq_domain_add_simple(np, HISI_IRQ_NUM, 0, + &hi6421_spmi_domain_ops, pmic); + if (!pmic->domain) { + dev_err(dev, "failed irq domain add simple!\n"); + ret = -ENODEV; + goto irq_malloc; + } + + for (i = 0; i < HISI_IRQ_NUM; i++) { + virq = irq_create_mapping(pmic->domain, i); + if (!virq) { + dev_err(dev, "Failed mapping hwirq\n"); + ret = -ENOSPC; + goto irq_malloc; + } + pmic->irqs[i] = virq; + dev_dbg(dev, "%s: pmic->irqs[%d] = %d\n", + __func__, i, pmic->irqs[i]); + } + + ret = request_threaded_irq(pmic->irq, hi6421_spmi_irq_handler, NULL, + IRQF_TRIGGER_LOW | IRQF_SHARED | IRQF_NO_SUSPEND, + "pmic", pmic); + if (ret < 0) { + dev_err(dev, "could not claim pmic IRQ: error %d\n", ret); + goto irq_malloc; + } + + dev_set_drvdata(&pdev->dev, pmic); + + /* + * The logic below will rely that the pmic is already stored at + * drvdata. + */ + dev_dbg(&pdev->dev, "SPMI-PMIC: adding children for %pOF\n", + pdev->dev.of_node); + ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, + hi6421v600_devs, ARRAY_SIZE(hi6421v600_devs), + NULL, 0, NULL); + if (!ret) + return 0; + + dev_err(dev, "Failed to add child devices: %d\n", ret); + +irq_malloc: + free_irq(pmic->irq, pmic); + + return ret; +} + +static void hi6421_spmi_pmic_remove(struct spmi_device *pdev) +{ + struct hi6421_spmi_pmic *pmic = dev_get_drvdata(&pdev->dev); + + free_irq(pmic->irq, pmic); +} + +static const struct of_device_id pmic_spmi_id_table[] = { + { .compatible = "hisilicon,hi6421-spmi" }, + { } +}; +MODULE_DEVICE_TABLE(of, pmic_spmi_id_table); + +static struct spmi_driver hi6421_spmi_pmic_driver = { + .driver = { + .name = "hi6421-spmi-pmic", + .of_match_table = pmic_spmi_id_table, + }, + .probe = hi6421_spmi_pmic_probe, + .remove = hi6421_spmi_pmic_remove, +}; +module_spmi_driver(hi6421_spmi_pmic_driver); + +MODULE_DESCRIPTION("HiSilicon Hi6421v600 SPMI PMIC driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/hikey9xx/hi6421v600-regulator.c b/drivers/staging/hikey9xx/hi6421v600-regulator.c new file mode 100644 index 000000000000..614b03c9ddfb --- /dev/null +++ b/drivers/staging/hikey9xx/hi6421v600-regulator.c @@ -0,0 +1,478 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Device driver for regulators in Hisi IC + * + * Copyright (c) 2013 Linaro Ltd. + * Copyright (c) 2011 Hisilicon. + * + * Guodong Xu <guodong.xu@linaro.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/mfd/hi6421-spmi-pmic.h> +#include <linux/module.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/regulator/driver.h> +#include <linux/regulator/machine.h> +#include <linux/regulator/of_regulator.h> +#include <linux/seq_file.h> +#include <linux/slab.h> +#include <linux/spmi.h> +#include <linux/time.h> +#include <linux/uaccess.h> + +#define rdev_dbg(rdev, fmt, arg...) \ + pr_debug("%s: %s: " fmt, (rdev)->desc->name, __func__, ##arg) + +struct hi6421v600_regulator { + struct regulator_desc rdesc; + struct hi6421_spmi_pmic *pmic; + u32 eco_mode_mask, eco_uA; +}; + +static DEFINE_MUTEX(enable_mutex); + +/* + * helper function to ensure when it returns it is at least 'delay_us' + * microseconds after 'since'. + */ + +static int hi6421_spmi_regulator_is_enabled(struct regulator_dev *rdev) +{ + struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev); + struct hi6421_spmi_pmic *pmic = sreg->pmic; + u32 reg_val; + + reg_val = hi6421_spmi_pmic_read(pmic, rdev->desc->enable_reg); + + rdev_dbg(rdev, + "enable_reg=0x%x, val= 0x%x, enable_state=%d\n", + rdev->desc->enable_reg, + reg_val, (reg_val & rdev->desc->enable_mask)); + + return ((reg_val & rdev->desc->enable_mask) != 0); +} + +static int hi6421_spmi_regulator_enable(struct regulator_dev *rdev) +{ + struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev); + struct hi6421_spmi_pmic *pmic = sreg->pmic; + + /* cannot enable more than one regulator at one time */ + mutex_lock(&enable_mutex); + usleep_range(HISI_REGS_ENA_PROTECT_TIME, + HISI_REGS_ENA_PROTECT_TIME + 1000); + + /* set enable register */ + rdev_dbg(rdev, + "off_on_delay=%d us, enable_reg=0x%x, enable_mask=0x%x\n", + rdev->desc->off_on_delay, rdev->desc->enable_reg, + rdev->desc->enable_mask); + + hi6421_spmi_pmic_rmw(pmic, rdev->desc->enable_reg, + rdev->desc->enable_mask, + rdev->desc->enable_mask); + + mutex_unlock(&enable_mutex); + + return 0; +} + +static int hi6421_spmi_regulator_disable(struct regulator_dev *rdev) +{ + struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev); + struct hi6421_spmi_pmic *pmic = sreg->pmic; + + /* set enable register to 0 */ + rdev_dbg(rdev, "enable_reg=0x%x, enable_mask=0x%x\n", + rdev->desc->enable_reg, rdev->desc->enable_mask); + + hi6421_spmi_pmic_rmw(pmic, rdev->desc->enable_reg, + rdev->desc->enable_mask, 0); + + return 0; +} + +static int hi6421_spmi_regulator_get_voltage_sel(struct regulator_dev *rdev) +{ + struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev); + struct hi6421_spmi_pmic *pmic = sreg->pmic; + u32 reg_val, selector; + + /* get voltage selector */ + reg_val = hi6421_spmi_pmic_read(pmic, rdev->desc->vsel_reg); + + selector = (reg_val & rdev->desc->vsel_mask) >> (ffs(rdev->desc->vsel_mask) - 1); + + rdev_dbg(rdev, + "vsel_reg=0x%x, value=0x%x, entry=0x%x, voltage=%d mV\n", + rdev->desc->vsel_reg, reg_val, selector, + rdev->desc->ops->list_voltage(rdev, selector) / 1000); + + return selector; +} + +static int hi6421_spmi_regulator_set_voltage_sel(struct regulator_dev *rdev, + unsigned int selector) +{ + struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev); + struct hi6421_spmi_pmic *pmic = sreg->pmic; + u32 reg_val; + + if (unlikely(selector >= rdev->desc->n_voltages)) + return -EINVAL; + + reg_val = selector << (ffs(rdev->desc->vsel_mask) - 1); + + /* set voltage selector */ + rdev_dbg(rdev, + "vsel_reg=0x%x, mask=0x%x, value=0x%x, voltage=%d mV\n", + rdev->desc->vsel_reg, rdev->desc->vsel_mask, reg_val, + rdev->desc->ops->list_voltage(rdev, selector) / 1000); + + hi6421_spmi_pmic_rmw(pmic, rdev->desc->vsel_reg, + rdev->desc->vsel_mask, reg_val); + + return 0; +} + +static unsigned int hi6421_spmi_regulator_get_mode(struct regulator_dev *rdev) +{ + struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev); + struct hi6421_spmi_pmic *pmic = sreg->pmic; + unsigned int mode; + u32 reg_val; + + reg_val = hi6421_spmi_pmic_read(pmic, rdev->desc->enable_reg); + + if (reg_val & sreg->eco_mode_mask) + mode = REGULATOR_MODE_IDLE; + else + mode = REGULATOR_MODE_NORMAL; + + rdev_dbg(rdev, + "enable_reg=0x%x, eco_mode_mask=0x%x, reg_val=0x%x, %s mode\n", + rdev->desc->enable_reg, sreg->eco_mode_mask, reg_val, + mode == REGULATOR_MODE_IDLE ? "idle" : "normal"); + + return mode; +} + +static int hi6421_spmi_regulator_set_mode(struct regulator_dev *rdev, + unsigned int mode) +{ + struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev); + struct hi6421_spmi_pmic *pmic = sreg->pmic; + u32 val; + + switch (mode) { + case REGULATOR_MODE_NORMAL: + val = 0; + break; + case REGULATOR_MODE_IDLE: + val = sreg->eco_mode_mask << (ffs(sreg->eco_mode_mask) - 1); + break; + default: + return -EINVAL; + } + + /* set mode */ + rdev_dbg(rdev, "enable_reg=0x%x, eco_mode_mask=0x%x, value=0x%x\n", + rdev->desc->enable_reg, sreg->eco_mode_mask, val); + + hi6421_spmi_pmic_rmw(pmic, rdev->desc->enable_reg, + sreg->eco_mode_mask, val); + + return 0; +} + +static unsigned int +hi6421_spmi_regulator_get_optimum_mode(struct regulator_dev *rdev, + int input_uV, int output_uV, + int load_uA) +{ + struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev); + + if (load_uA || ((unsigned int)load_uA > sreg->eco_uA)) + return REGULATOR_MODE_NORMAL; + + return REGULATOR_MODE_IDLE; +} + +static int hi6421_spmi_dt_parse(struct platform_device *pdev, + struct hi6421v600_regulator *sreg, + struct regulator_desc *rdesc) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + unsigned int *v_table; + int ret; + + ret = of_property_read_u32(np, "reg", &rdesc->enable_reg); + if (ret) { + dev_err(dev, "missing reg property\n"); + return ret; + } + + ret = of_property_read_u32(np, "vsel-reg", &rdesc->vsel_reg); + if (ret) { + dev_err(dev, "missing vsel-reg property\n"); + return ret; + } + + ret = of_property_read_u32(np, "enable-mask", &rdesc->enable_mask); + if (ret) { + dev_err(dev, "missing enable-mask property\n"); + return ret; + } + + /* + * Not all regulators work on idle mode + */ + ret = of_property_read_u32(np, "idle-mode-mask", &sreg->eco_mode_mask); + if (ret) { + dev_dbg(dev, "LDO doesn't support economy mode.\n"); + sreg->eco_mode_mask = 0; + sreg->eco_uA = 0; + } else { + ret = of_property_read_u32(np, "eco-microamp", &sreg->eco_uA); + if (ret) { + dev_err(dev, "missing eco-microamp property\n"); + return ret; + } + } + + /* parse .off-on-delay */ + ret = of_property_read_u32(np, "off-on-delay-us", + &rdesc->off_on_delay); + if (ret) { + dev_err(dev, "missing off-on-delay-us property\n"); + return ret; + } + + /* parse .enable_time */ + ret = of_property_read_u32(np, "startup-delay-us", + &rdesc->enable_time); + if (ret) { + dev_err(dev, "missing startup-delay-us property\n"); + return ret; + } + + /* FIXME: are there a better value for this? */ + rdesc->ramp_delay = rdesc->enable_time; + + /* parse volt_table */ + + rdesc->n_voltages = of_property_count_u32_elems(np, "voltage-table"); + + v_table = devm_kzalloc(dev, sizeof(unsigned int) * rdesc->n_voltages, + GFP_KERNEL); + if (unlikely(!v_table)) + return -ENOMEM; + rdesc->volt_table = v_table; + + ret = of_property_read_u32_array(np, "voltage-table", + v_table, rdesc->n_voltages); + if (ret) { + dev_err(dev, "missing voltage-table property\n"); + return ret; + } + + /* + * Instead of explicitly requiring a mask for the voltage selector, + * as they all start from bit zero (at least on the known LDOs), + * just use the number of voltages at the voltage table, getting the + * minimal mask that would pick everything. + */ + rdesc->vsel_mask = (1 << (fls(rdesc->n_voltages) - 1)) - 1; + + dev_dbg(dev, "voltage selector settings: reg: 0x%x, mask: 0x%x\n", + rdesc->vsel_reg, rdesc->vsel_mask); + + return 0; +} + +static const struct regulator_ops hi6421_spmi_ldo_rops = { + .is_enabled = hi6421_spmi_regulator_is_enabled, + .enable = hi6421_spmi_regulator_enable, + .disable = hi6421_spmi_regulator_disable, + .list_voltage = regulator_list_voltage_table, + .map_voltage = regulator_map_voltage_iterate, + .get_voltage_sel = hi6421_spmi_regulator_get_voltage_sel, + .set_voltage_sel = hi6421_spmi_regulator_set_voltage_sel, + .get_mode = hi6421_spmi_regulator_get_mode, + .set_mode = hi6421_spmi_regulator_set_mode, + .get_optimum_mode = hi6421_spmi_regulator_get_optimum_mode, +}; + +static int hi6421_spmi_regulator_probe_ldo(struct platform_device *pdev, + struct device_node *np, + struct hi6421_spmi_pmic *pmic) +{ + struct regulation_constraints *constraint; + struct regulator_init_data *initdata; + struct regulator_config config = { }; + struct hi6421v600_regulator *sreg; + struct device *dev = &pdev->dev; + struct regulator_desc *rdesc; + struct regulator_dev *rdev; + const char *supplyname; + int ret; + + initdata = of_get_regulator_init_data(dev, np, NULL); + if (!initdata) { + dev_err(dev, "failed to get regulator data\n"); + return -EINVAL; + } + + sreg = devm_kzalloc(dev, sizeof(*sreg), GFP_KERNEL); + if (!sreg) + return -ENOMEM; + + sreg->pmic = pmic; + rdesc = &sreg->rdesc; + + rdesc->name = initdata->constraints.name; + rdesc->ops = &hi6421_spmi_ldo_rops; + rdesc->type = REGULATOR_VOLTAGE; + rdesc->min_uV = initdata->constraints.min_uV; + + supplyname = of_get_property(np, "supply_name", NULL); + if (supplyname) + initdata->supply_regulator = supplyname; + + /* parse device tree data for regulator specific */ + ret = hi6421_spmi_dt_parse(pdev, sreg, rdesc); + if (ret) + return ret; + + /* hisi regulator supports two modes */ + constraint = &initdata->constraints; + + constraint->valid_modes_mask = REGULATOR_MODE_NORMAL; + if (sreg->eco_mode_mask) { + constraint->valid_modes_mask |= REGULATOR_MODE_IDLE; + constraint->valid_ops_mask |= REGULATOR_CHANGE_MODE; + } + + config.dev = &pdev->dev; + config.init_data = initdata; + config.driver_data = sreg; + config.of_node = pdev->dev.of_node; + + /* register regulator */ + rdev = regulator_register(rdesc, &config); + if (IS_ERR(rdev)) { + dev_err(dev, "failed to register %s\n", + rdesc->name); + return PTR_ERR(rdev); + } + + rdev_dbg(rdev, "valid_modes_mask: 0x%x, valid_ops_mask: 0x%x\n", + constraint->valid_modes_mask, constraint->valid_ops_mask); + + dev_set_drvdata(dev, rdev); + + return 0; +} + +static int hi6421_spmi_regulator_probe(struct platform_device *pdev) +{ + struct device *pmic_dev = pdev->dev.parent; + struct device_node *np = pmic_dev->of_node; + struct device_node *regulators, *child; + struct platform_device *new_pdev; + struct hi6421_spmi_pmic *pmic; + int ret; + + /* + * This driver is meant to be called by hi6421-spmi-core, + * which should first set drvdata. If this doesn't happen, hit + * a warn on and return. + */ + pmic = dev_get_drvdata(pmic_dev); + if (WARN_ON(!pmic)) + return -ENODEV; + + regulators = of_get_child_by_name(np, "regulators"); + if (!regulators) { + dev_err(&pdev->dev, "regulator node not found\n"); + return -ENODEV; + } + + /* + * Parse all LDO regulator nodes + */ + for_each_child_of_node(regulators, child) { + dev_dbg(&pdev->dev, "adding child %pOF\n", child); + + new_pdev = platform_device_alloc(child->name, -1); + new_pdev->dev.parent = pmic_dev; + new_pdev->dev.of_node = of_node_get(child); + + ret = platform_device_add(new_pdev); + if (ret < 0) { + platform_device_put(new_pdev); + continue; + } + + ret = hi6421_spmi_regulator_probe_ldo(new_pdev, child, pmic); + if (ret < 0) + platform_device_put(new_pdev); + } + + of_node_put(regulators); + + return 0; +} + +static int hi6421_spmi_regulator_remove(struct platform_device *pdev) +{ + struct regulator_dev *rdev = dev_get_drvdata(&pdev->dev); + struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev); + + regulator_unregister(rdev); + + if (rdev->desc->volt_table) + devm_kfree(&pdev->dev, (unsigned int *)rdev->desc->volt_table); + + kfree(sreg); + + return 0; +} + +static const struct platform_device_id hi6421v600_regulator_table[] = { + { .name = "hi6421v600-regulator" }, + {}, +}; +MODULE_DEVICE_TABLE(platform, hi6421v600_regulator_table); + +static struct platform_driver hi6421v600_regulator_driver = { + .id_table = hi6421v600_regulator_table, + .driver = { + .name = "hi6421v600-regulator", + }, + .probe = hi6421_spmi_regulator_probe, + .remove = hi6421_spmi_regulator_remove, +}; +module_platform_driver(hi6421v600_regulator_driver); + +MODULE_DESCRIPTION("Hi6421v600 regulator driver"); +MODULE_LICENSE("GPL v2"); + diff --git a/drivers/staging/hikey9xx/hisi-spmi-controller.c b/drivers/staging/hikey9xx/hisi-spmi-controller.c new file mode 100644 index 000000000000..5ffe79f45d9a --- /dev/null +++ b/drivers/staging/hikey9xx/hisi-spmi-controller.c @@ -0,0 +1,357 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/seq_file.h> +#include <linux/slab.h> +#include <linux/spmi.h> + +/* + * SPMI register addr + */ +#define SPMI_CHANNEL_OFFSET 0x0300 +#define SPMI_SLAVE_OFFSET 0x20 + +#define SPMI_APB_SPMI_CMD_BASE_ADDR 0x0100 + +#define SPMI_APB_SPMI_WDATA0_BASE_ADDR 0x0104 +#define SPMI_APB_SPMI_WDATA1_BASE_ADDR 0x0108 +#define SPMI_APB_SPMI_WDATA2_BASE_ADDR 0x010c +#define SPMI_APB_SPMI_WDATA3_BASE_ADDR 0x0110 + +#define SPMI_APB_SPMI_STATUS_BASE_ADDR 0x0200 + +#define SPMI_APB_SPMI_RDATA0_BASE_ADDR 0x0204 +#define SPMI_APB_SPMI_RDATA1_BASE_ADDR 0x0208 +#define SPMI_APB_SPMI_RDATA2_BASE_ADDR 0x020c +#define SPMI_APB_SPMI_RDATA3_BASE_ADDR 0x0210 + +#define SPMI_PER_DATAREG_BYTE 4 +/* + * SPMI cmd register + */ +#define SPMI_APB_SPMI_CMD_EN BIT(31) +#define SPMI_APB_SPMI_CMD_TYPE_OFFSET 24 +#define SPMI_APB_SPMI_CMD_LENGTH_OFFSET 20 +#define SPMI_APB_SPMI_CMD_SLAVEID_OFFSET 16 +#define SPMI_APB_SPMI_CMD_ADDR_OFFSET 0 + +/* Command Opcodes */ + +enum spmi_controller_cmd_op_code { + SPMI_CMD_REG_ZERO_WRITE = 0, + SPMI_CMD_REG_WRITE = 1, + SPMI_CMD_REG_READ = 2, + SPMI_CMD_EXT_REG_WRITE = 3, + SPMI_CMD_EXT_REG_READ = 4, + SPMI_CMD_EXT_REG_WRITE_L = 5, + SPMI_CMD_EXT_REG_READ_L = 6, + SPMI_CMD_REG_RESET = 7, + SPMI_CMD_REG_SLEEP = 8, + SPMI_CMD_REG_SHUTDOWN = 9, + SPMI_CMD_REG_WAKEUP = 10, +}; + +/* + * SPMI status register + */ +#define SPMI_APB_TRANS_DONE BIT(0) +#define SPMI_APB_TRANS_FAIL BIT(2) + +/* Command register fields */ +#define SPMI_CONTROLLER_CMD_MAX_BYTE_COUNT 16 + +/* Maximum number of support PMIC peripherals */ +#define SPMI_CONTROLLER_TIMEOUT_US 1000 +#define SPMI_CONTROLLER_MAX_TRANS_BYTES 16 + +struct spmi_controller_dev { + struct spmi_controller *controller; + struct device *dev; + void __iomem *base; + spinlock_t lock; + u32 channel; +}; + +static int spmi_controller_wait_for_done(struct device *dev, + struct spmi_controller_dev *ctrl_dev, + void __iomem *base, u8 sid, u16 addr) +{ + u32 timeout = SPMI_CONTROLLER_TIMEOUT_US; + u32 status, offset; + + offset = SPMI_APB_SPMI_STATUS_BASE_ADDR; + offset += SPMI_CHANNEL_OFFSET * ctrl_dev->channel + SPMI_SLAVE_OFFSET * sid; + + do { + status = readl(base + offset); + + if (status & SPMI_APB_TRANS_DONE) { + if (status & SPMI_APB_TRANS_FAIL) { + dev_err(dev, "%s: transaction failed (0x%x)\n", + __func__, status); + return -EIO; + } + dev_dbg(dev, "%s: status 0x%x\n", __func__, status); + return 0; + } + udelay(1); + } while (timeout--); + + dev_err(dev, "%s: timeout, status 0x%x\n", __func__, status); + return -ETIMEDOUT; +} + +static int spmi_read_cmd(struct spmi_controller *ctrl, + u8 opc, u8 slave_id, u16 slave_addr, u8 *__buf, size_t bc) +{ + struct spmi_controller_dev *spmi_controller = dev_get_drvdata(&ctrl->dev); + u32 chnl_ofst = SPMI_CHANNEL_OFFSET * spmi_controller->channel; + unsigned long flags; + u8 *buf = __buf; + u32 cmd, data; + int rc; + u8 op_code, i; + + if (bc > SPMI_CONTROLLER_MAX_TRANS_BYTES) { + dev_err(&ctrl->dev, + "spmi_controller supports 1..%d bytes per trans, but:%zu requested\n", + SPMI_CONTROLLER_MAX_TRANS_BYTES, bc); + return -EINVAL; + } + + switch (opc) { + case SPMI_CMD_READ: + op_code = SPMI_CMD_REG_READ; + break; + case SPMI_CMD_EXT_READ: + op_code = SPMI_CMD_EXT_REG_READ; + break; + case SPMI_CMD_EXT_READL: + op_code = SPMI_CMD_EXT_REG_READ_L; + break; + default: + dev_err(&ctrl->dev, "invalid read cmd 0x%x\n", opc); + return -EINVAL; + } + + cmd = SPMI_APB_SPMI_CMD_EN | + (op_code << SPMI_APB_SPMI_CMD_TYPE_OFFSET) | + ((bc - 1) << SPMI_APB_SPMI_CMD_LENGTH_OFFSET) | + ((slave_id & 0xf) << SPMI_APB_SPMI_CMD_SLAVEID_OFFSET) | /* slvid */ + ((slave_addr & 0xffff) << SPMI_APB_SPMI_CMD_ADDR_OFFSET); /* slave_addr */ + + spin_lock_irqsave(&spmi_controller->lock, flags); + + writel(cmd, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_CMD_BASE_ADDR); + + rc = spmi_controller_wait_for_done(&ctrl->dev, spmi_controller, + spmi_controller->base, slave_id, slave_addr); + if (rc) + goto done; + + for (i = 0; bc > i * SPMI_PER_DATAREG_BYTE; i++) { + data = readl(spmi_controller->base + chnl_ofst + + SPMI_SLAVE_OFFSET * slave_id + + SPMI_APB_SPMI_RDATA0_BASE_ADDR + + i * SPMI_PER_DATAREG_BYTE); + data = be32_to_cpu((__be32)data); + if ((bc - i * SPMI_PER_DATAREG_BYTE) >> 2) { + memcpy(buf, &data, sizeof(data)); + buf += sizeof(data); + } else { + memcpy(buf, &data, bc % SPMI_PER_DATAREG_BYTE); + buf += (bc % SPMI_PER_DATAREG_BYTE); + } + } + +done: + spin_unlock_irqrestore(&spmi_controller->lock, flags); + if (rc) + dev_err(&ctrl->dev, + "spmi read wait timeout op:0x%x slave_id:%d slave_addr:0x%x bc:%zu\n", + opc, slave_id, slave_addr, bc + 1); + else + dev_dbg(&ctrl->dev, "%s: id:%d slave_addr:0x%x, read value: %*ph\n", + __func__, slave_id, slave_addr, (int)bc, __buf); + + return rc; +} + +static int spmi_write_cmd(struct spmi_controller *ctrl, + u8 opc, u8 slave_id, u16 slave_addr, const u8 *__buf, size_t bc) +{ + struct spmi_controller_dev *spmi_controller = dev_get_drvdata(&ctrl->dev); + u32 chnl_ofst = SPMI_CHANNEL_OFFSET * spmi_controller->channel; + const u8 *buf = __buf; + unsigned long flags; + u32 cmd, data; + int rc; + u8 op_code, i; + + if (bc > SPMI_CONTROLLER_MAX_TRANS_BYTES) { + dev_err(&ctrl->dev, + "spmi_controller supports 1..%d bytes per trans, but:%zu requested\n", + SPMI_CONTROLLER_MAX_TRANS_BYTES, bc); + return -EINVAL; + } + + switch (opc) { + case SPMI_CMD_WRITE: + op_code = SPMI_CMD_REG_WRITE; + break; + case SPMI_CMD_EXT_WRITE: + op_code = SPMI_CMD_EXT_REG_WRITE; + break; + case SPMI_CMD_EXT_WRITEL: + op_code = SPMI_CMD_EXT_REG_WRITE_L; + break; + default: + dev_err(&ctrl->dev, "invalid write cmd 0x%x\n", opc); + return -EINVAL; + } + + cmd = SPMI_APB_SPMI_CMD_EN | + (op_code << SPMI_APB_SPMI_CMD_TYPE_OFFSET) | + ((bc - 1) << SPMI_APB_SPMI_CMD_LENGTH_OFFSET) | + ((slave_id & 0xf) << SPMI_APB_SPMI_CMD_SLAVEID_OFFSET) | + ((slave_addr & 0xffff) << SPMI_APB_SPMI_CMD_ADDR_OFFSET); + + /* Write data to FIFOs */ + spin_lock_irqsave(&spmi_controller->lock, flags); + + for (i = 0; bc > i * SPMI_PER_DATAREG_BYTE; i++) { + data = 0; + if ((bc - i * SPMI_PER_DATAREG_BYTE) >> 2) { + memcpy(&data, buf, sizeof(data)); + buf += sizeof(data); + } else { + memcpy(&data, buf, bc % SPMI_PER_DATAREG_BYTE); + buf += (bc % SPMI_PER_DATAREG_BYTE); + } + + writel((u32)cpu_to_be32(data), + spmi_controller->base + chnl_ofst + + SPMI_APB_SPMI_WDATA0_BASE_ADDR + + SPMI_PER_DATAREG_BYTE * i); + } + + /* Start the transaction */ + writel(cmd, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_CMD_BASE_ADDR); + + rc = spmi_controller_wait_for_done(&ctrl->dev, spmi_controller, + spmi_controller->base, slave_id, + slave_addr); + spin_unlock_irqrestore(&spmi_controller->lock, flags); + + if (rc) + dev_err(&ctrl->dev, "spmi write wait timeout op:0x%x slave_id:%d slave_addr:0x%x bc:%zu\n", + opc, slave_id, slave_addr, bc); + else + dev_dbg(&ctrl->dev, "%s: id:%d slave_addr:0x%x, wrote value: %*ph\n", + __func__, slave_id, slave_addr, (int)bc, __buf); + + return rc; +} + +static int spmi_controller_probe(struct platform_device *pdev) +{ + struct spmi_controller_dev *spmi_controller; + struct spmi_controller *ctrl; + struct resource *iores; + int ret; + + ctrl = spmi_controller_alloc(&pdev->dev, sizeof(*spmi_controller)); + if (!ctrl) { + dev_err(&pdev->dev, "can not allocate spmi_controller data\n"); + return -ENOMEM; + } + spmi_controller = spmi_controller_get_drvdata(ctrl); + spmi_controller->controller = ctrl; + + iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!iores) { + dev_err(&pdev->dev, "can not get resource!\n"); + return -EINVAL; + } + + spmi_controller->base = ioremap(iores->start, resource_size(iores)); + if (!spmi_controller->base) { + dev_err(&pdev->dev, "can not remap base addr!\n"); + return -EADDRNOTAVAIL; + } + + ret = of_property_read_u32(pdev->dev.of_node, "spmi-channel", + &spmi_controller->channel); + if (ret) { + dev_err(&pdev->dev, "can not get channel\n"); + return -ENODEV; + } + + platform_set_drvdata(pdev, spmi_controller); + dev_set_drvdata(&ctrl->dev, spmi_controller); + + spin_lock_init(&spmi_controller->lock); + + ctrl->nr = spmi_controller->channel; + ctrl->dev.parent = pdev->dev.parent; + ctrl->dev.of_node = of_node_get(pdev->dev.of_node); + + /* Callbacks */ + ctrl->read_cmd = spmi_read_cmd; + ctrl->write_cmd = spmi_write_cmd; + + ret = spmi_controller_add(ctrl); + if (ret) + dev_err(&pdev->dev, "spmi_add_controller failed with error %d!\n", ret); + + return ret; +} + +static int spmi_del_controller(struct platform_device *pdev) +{ + struct spmi_controller *ctrl = platform_get_drvdata(pdev); + + spmi_controller_remove(ctrl); + kfree(ctrl); + return 0; +} + +static const struct of_device_id spmi_controller_match_table[] = { + { + .compatible = "hisilicon,kirin970-spmi-controller", + }, + {} +}; +MODULE_DEVICE_TABLE(of, spmi_controller_match_table); + +static struct platform_driver spmi_controller_driver = { + .probe = spmi_controller_probe, + .remove = spmi_del_controller, + .driver = { + .name = "hisi_spmi_controller", + .of_match_table = spmi_controller_match_table, + }, +}; + +static int __init spmi_controller_init(void) +{ + return platform_driver_register(&spmi_controller_driver); +} +postcore_initcall(spmi_controller_init); + +static void __exit spmi_controller_exit(void) +{ + platform_driver_unregister(&spmi_controller_driver); +} +module_exit(spmi_controller_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_VERSION("1.0"); +MODULE_ALIAS("platform:spmi_controller"); diff --git a/drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml b/drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml new file mode 100644 index 000000000000..80e74c261e05 --- /dev/null +++ b/drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml @@ -0,0 +1,159 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/hisilicon,hi6421-spmi-pmic.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: HiSilicon 6421v600 SPMI PMIC + +maintainers: + - Mauro Carvalho Chehab <mchehab+huawei@kernel.org> + +description: | + HiSilicon 6421v600 should be connected inside a MIPI System Power Management + (SPMI) bus. It provides interrupts and power supply. + + The GPIO and interrupt settings are represented as part of the top-level PMIC + node. + + The SPMI controller part is provided by + drivers/staging/hikey9xx/hisilicon,hisi-spmi-controller.yaml. + +properties: + $nodename: + pattern: "pmic@[0-9a-f]" + + compatible: + const: hisilicon,hi6421v600-spmi + + reg: + maxItems: 1 + + '#interrupt-cells': + const: 2 + + interrupt-controller: + description: + Identify that the PMIC is capable of behaving as an interrupt controller. + + gpios: + maxItems: 1 + + regulators: + type: object + + properties: + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + + patternProperties: + '^ldo[0-9]+@[0-9a-f]$': + type: object + + $ref: "/schemas/regulator/regulator.yaml#" + + properties: + reg: + description: Enable register. + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + + vsel-reg: + description: Voltage selector register. + + enable-mask: + description: Bitmask used to enable the regulator. + + voltage-table: + description: Table with the selector items for the voltage regulator. + minItems: 2 + maxItems: 16 + + off-on-delay-us: + description: Time required for changing state to enabled in microseconds. + + startup-delay-us: + description: Startup time in microseconds. + + idle-mode-mask: + description: Bitmask used to put the regulator on idle mode. + + eco-microamp: + description: Maximum current while on idle mode. + + required: + - reg + - vsel-reg + - enable-mask + - voltage-table + - off-on-delay-us + - startup-delay-us + +required: + - compatible + - reg + - regulators + +examples: + - | + /* pmic properties */ + + pmic: pmic@0 { + compatible = "hisilicon,hi6421-spmi"; + reg = <0 0>; + + #interrupt-cells = <2>; + interrupt-controller; + gpios = <&gpio28 0 0>; + + regulators { + #address-cells = <1>; + #size-cells = <0>; + + ldo3: ldo3@16 { + reg = <0x16>; + vsel-reg = <0x51>; + + regulator-name = "ldo3"; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <2000000>; + regulator-boot-on; + + enable-mask = <0x01>; + + voltage-table = <1500000>, <1550000>, <1600000>, <1650000>, + <1700000>, <1725000>, <1750000>, <1775000>, + <1800000>, <1825000>, <1850000>, <1875000>, + <1900000>, <1925000>, <1950000>, <2000000>; + off-on-delay-us = <20000>; + startup-delay-us = <120>; + }; + + ldo4: ldo4@17 { /* 40 PIN */ + reg = <0x17>; + vsel-reg = <0x52>; + + regulator-name = "ldo4"; + regulator-min-microvolt = <1725000>; + regulator-max-microvolt = <1900000>; + regulator-boot-on; + + enable-mask = <0x01>; + idle-mode-mask = <0x10>; + eco-microamp = <10000>; + + hi6421-vsel = <0x52 0x07>; + voltage-table = <1725000>, <1750000>, <1775000>, <1800000>, + <1825000>, <1850000>, <1875000>, <1900000>; + off-on-delay-us = <20000>; + startup-delay-us = <120>; + }; + }; + }; diff --git a/drivers/staging/hikey9xx/hisilicon,hisi-spmi-controller.yaml b/drivers/staging/hikey9xx/hisilicon,hisi-spmi-controller.yaml new file mode 100644 index 000000000000..f2a56fa4e78e --- /dev/null +++ b/drivers/staging/hikey9xx/hisilicon,hisi-spmi-controller.yaml @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/spmi/hisilicon,hisi-spmi-controller.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: HiSilicon SPMI controller + +maintainers: + - Mauro Carvalho Chehab <mchehab+huawei@kernel.org> + +description: | + The HiSilicon SPMI BUS controller is found on some Kirin-based designs. + It is a MIPI System Power Management (SPMI) controller. + + The PMIC part is provided by + drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml. + +properties: + $nodename: + pattern: "spmi@[0-9a-f]" + + compatible: + const: hisilicon,kirin970-spmi-controller + + reg: + maxItems: 1 + + spmi-channel: + description: | + number of the Kirin 970 SPMI channel where the SPMI devices are connected. + +required: + - compatible + - reg + - spmi-channel + +patternProperties: + "^pmic@[0-9a-f]$": + description: | + PMIC properties, which are specific to the used SPMI PMIC device(s). + When used in combination with HiSilicon 6421v600, the properties + are documented at + drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml. + +examples: + - | + bus { + #address-cells = <2>; + #size-cells = <2>; + + spmi: spmi@fff24000 { + compatible = "hisilicon,kirin970-spmi-controller"; + status = "ok"; + reg = <0x0 0xfff24000 0x0 0x1000>; + spmi-channel = <2>; + + pmic@0 { + /* pmic properties */ + }; + }; + }; diff --git a/drivers/staging/iio/Documentation/overview.txt b/drivers/staging/iio/Documentation/overview.txt index ebdc64f451d7..00409d5dab4e 100644 --- a/drivers/staging/iio/Documentation/overview.txt +++ b/drivers/staging/iio/Documentation/overview.txt @@ -9,7 +9,7 @@ The aim is to fill the gap between the somewhat similar hwmon and input subsystems. Hwmon is very much directed at low sample rate sensors used in applications such as fan speed control and temperature measurement. Input is, as its name suggests focused on input -devices. In some cases there is considerable overlap between these and +devices. In some cases, there is considerable overlap between these and IIO. A typical device falling into this category would be connected via SPI @@ -38,7 +38,7 @@ series and Analog Devices ADXL345 accelerometers. Each buffer supports polling to establish when data is available. * Trigger and software buffer support. In many data analysis -applications it it useful to be able to capture data based on some +applications it is useful to be able to capture data based on some external signal (trigger). These triggers might be a data ready signal, a gpio line connected to some external system or an on processor periodic interrupt. A single trigger may initialize data diff --git a/drivers/staging/iio/frequency/ad9834.c b/drivers/staging/iio/frequency/ad9834.c index 77f77a2b2e05..262c3590e64e 100644 --- a/drivers/staging/iio/frequency/ad9834.c +++ b/drivers/staging/iio/frequency/ad9834.c @@ -397,7 +397,6 @@ static int ad9834_probe(struct spi_device *spi) struct regulator *reg; int ret; - reg = devm_regulator_get(&spi->dev, "avdd"); if (IS_ERR(reg)) return PTR_ERR(reg); diff --git a/drivers/staging/kpc2000/kpc_dma/fileops.c b/drivers/staging/kpc2000/kpc_dma/fileops.c index dd716edd9b1b..e1c7c04f16fe 100644 --- a/drivers/staging/kpc2000/kpc_dma/fileops.c +++ b/drivers/staging/kpc2000/kpc_dma/fileops.c @@ -53,7 +53,7 @@ static int kpc_dma_transfer(struct dev_private_data *priv, acd = kzalloc(sizeof(*acd), GFP_KERNEL); if (!acd) { - dev_err(&priv->ldev->pldev->dev, "Couldn't kmalloc space for for the aio data\n"); + dev_err(&priv->ldev->pldev->dev, "Couldn't kmalloc space for the aio data\n"); return -ENOMEM; } memset(acd, 0x66, sizeof(struct aio_cb_data)); @@ -69,7 +69,7 @@ static int kpc_dma_transfer(struct dev_private_data *priv, acd->user_pages = kcalloc(acd->page_count, sizeof(struct page *), GFP_KERNEL); if (!acd->user_pages) { - dev_err(&priv->ldev->pldev->dev, "Couldn't kmalloc space for for the page pointers\n"); + dev_err(&priv->ldev->pldev->dev, "Couldn't kmalloc space for the page pointers\n"); rv = -ENOMEM; goto err_alloc_userpages; } diff --git a/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c b/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c index 809010af7855..7ca7378b1859 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c @@ -19,14 +19,13 @@ #include <linux/i2c.h> #include <linux/mutex.h> #include <linux/delay.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/slab.h> #include "../include/media/lm3554.h" #include <media/v4l2-ctrls.h> #include <media/v4l2-device.h> #include <linux/acpi.h> -#include <linux/gpio/consumer.h> #include "../include/linux/atomisp_gmin_platform.h" #include "../include/linux/atomisp.h" @@ -173,7 +172,7 @@ static void lm3554_flash_off_delay(struct timer_list *t) struct lm3554 *flash = from_timer(flash, t, flash_off_delay); struct lm3554_platform_data *pdata = flash->pdata; - gpio_set_value(pdata->gpio_strobe, 0); + gpiod_set_value(pdata->gpio_strobe, 0); } 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) * so must strobe off here */ if (timer_pending) - gpio_set_value(pdata->gpio_strobe, 0); + gpiod_set_value(pdata->gpio_strobe, 0); /* Restore flash current settings */ ret = lm3554_set_flash(flash); @@ -217,7 +216,7 @@ static int lm3554_hw_strobe(struct i2c_client *client, bool strobe) goto err; /* Strobe on Flash */ - gpio_set_value(pdata->gpio_strobe, 1); + gpiod_set_value(pdata->gpio_strobe, 1); return 0; err: @@ -627,7 +626,7 @@ static int __lm3554_s_power(struct lm3554 *flash, int power) int ret; /*initialize flash driver*/ - gpio_set_value(pdata->gpio_reset, power); + gpiod_set_value(pdata->gpio_reset, power); usleep_range(100, 100 + 1); if (power) { @@ -766,33 +765,22 @@ static int lm3554_gpio_init(struct i2c_client *client) struct lm3554_platform_data *pdata = flash->pdata; int ret; - if (!gpio_is_valid(pdata->gpio_reset)) + if (!pdata->gpio_reset) return -EINVAL; - ret = gpio_direction_output(pdata->gpio_reset, 0); + ret = gpiod_direction_output(pdata->gpio_reset, 0); if (ret < 0) - goto err_gpio_reset; + return ret; dev_info(&client->dev, "flash led reset successfully\n"); - if (!gpio_is_valid(pdata->gpio_strobe)) { - ret = -EINVAL; - goto err_gpio_dir_reset; - } + if (!pdata->gpio_strobe) + return -EINVAL; - ret = gpio_direction_output(pdata->gpio_strobe, 0); + ret = gpiod_direction_output(pdata->gpio_strobe, 0); if (ret < 0) - goto err_gpio_strobe; + return ret; return 0; - -err_gpio_strobe: - gpio_free(pdata->gpio_strobe); -err_gpio_dir_reset: - gpio_direction_output(pdata->gpio_reset, 0); -err_gpio_reset: - gpio_free(pdata->gpio_reset); - - return ret; } static int lm3554_gpio_uninit(struct i2c_client *client) @@ -802,16 +790,14 @@ static int lm3554_gpio_uninit(struct i2c_client *client) struct lm3554_platform_data *pdata = flash->pdata; int ret; - ret = gpio_direction_output(pdata->gpio_strobe, 0); + ret = gpiod_direction_output(pdata->gpio_strobe, 0); if (ret < 0) return ret; - ret = gpio_direction_output(pdata->gpio_reset, 0); + ret = gpiod_direction_output(pdata->gpio_reset, 0); if (ret < 0) return ret; - gpio_free(pdata->gpio_strobe); - gpio_free(pdata->gpio_reset); return 0; } @@ -819,18 +805,18 @@ static void *lm3554_platform_data_func(struct i2c_client *client) { static struct lm3554_platform_data platform_data; - platform_data.gpio_reset = - desc_to_gpio(gpiod_get_index(&client->dev, - NULL, 2, GPIOD_OUT_LOW)); - platform_data.gpio_strobe = - desc_to_gpio(gpiod_get_index(&client->dev, - NULL, 0, GPIOD_OUT_LOW)); - platform_data.gpio_torch = - desc_to_gpio(gpiod_get_index(&client->dev, - NULL, 1, GPIOD_OUT_LOW)); - dev_info(&client->dev, "camera pdata: lm3554: reset: %d strobe %d torch %d\n", - platform_data.gpio_reset, platform_data.gpio_strobe, - platform_data.gpio_torch); + platform_data.gpio_reset = gpiod_get_index(&client->dev, + NULL, 2, GPIOD_OUT_LOW); + if (IS_ERR(platform_data.gpio_reset)) + return ERR_CAST(platform_data.gpio_reset); + platform_data.gpio_strobe = gpiod_get_index(&client->dev, + NULL, 0, GPIOD_OUT_LOW); + if (IS_ERR(platform_data.gpio_strobe)) + return ERR_CAST(platform_data.gpio_strobe); + platform_data.gpio_torch = gpiod_get_index(&client->dev, + NULL, 1, GPIOD_OUT_LOW); + if (IS_ERR(platform_data.gpio_torch)) + return ERR_CAST(platform_data.gpio_torch); /* Set to TX2 mode, then ENVM/TX2 pin is a power amplifier sync input: * ENVM/TX pin asserted, flash forced into torch; @@ -857,6 +843,8 @@ static int lm3554_probe(struct i2c_client *client) return -ENOMEM; flash->pdata = lm3554_platform_data_func(client); + if (IS_ERR(flash->pdata)) + return PTR_ERR(flash->pdata); v4l2_i2c_subdev_init(&flash->sd, client, &lm3554_ops); flash->sd.internal_ops = &lm3554_internal_ops; diff --git a/drivers/staging/media/atomisp/include/media/lm3554.h b/drivers/staging/media/atomisp/include/media/lm3554.h index 812ce74f0635..711b7d7c9950 100644 --- a/drivers/staging/media/atomisp/include/media/lm3554.h +++ b/drivers/staging/media/atomisp/include/media/lm3554.h @@ -18,6 +18,7 @@ #ifndef _LM3554_H_ #define _LM3554_H_ +#include <linux/gpio/consumer.h> #include <linux/videodev2.h> #include <media/v4l2-subdev.h> @@ -119,9 +120,9 @@ * lm3554_platform_data - Flash controller platform data */ struct lm3554_platform_data { - int gpio_torch; - int gpio_strobe; - int gpio_reset; + struct gpio_desc *gpio_torch; + struct gpio_desc *gpio_strobe; + struct gpio_desc *gpio_reset; unsigned int current_limit; unsigned int envm_tx2; diff --git a/drivers/staging/media/tegra-vde/iommu.c b/drivers/staging/media/tegra-vde/iommu.c index 6af863d92123..adf8dc7ee25c 100644 --- a/drivers/staging/media/tegra-vde/iommu.c +++ b/drivers/staging/media/tegra-vde/iommu.c @@ -36,8 +36,8 @@ int tegra_vde_iommu_map(struct tegra_vde *vde, addr = iova_dma_addr(&vde->iova, iova); - size = iommu_map_sg(vde->domain, addr, sgt->sgl, sgt->nents, - IOMMU_READ | IOMMU_WRITE); + size = iommu_map_sgtable(vde->domain, addr, sgt, + IOMMU_READ | IOMMU_WRITE); if (!size) { __free_iova(&vde->iova, iova); return -ENXIO; diff --git a/drivers/staging/most/Kconfig b/drivers/staging/most/Kconfig index c35fb34fae79..535e6dec3504 100644 --- a/drivers/staging/most/Kconfig +++ b/drivers/staging/most/Kconfig @@ -18,8 +18,6 @@ menuconfig MOST_COMPONENTS if MOST_COMPONENTS -source "drivers/staging/most/cdev/Kconfig" - source "drivers/staging/most/net/Kconfig" source "drivers/staging/most/sound/Kconfig" diff --git a/drivers/staging/most/Makefile b/drivers/staging/most/Makefile index 7c10b84ebac0..be94673209f5 100644 --- a/drivers/staging/most/Makefile +++ b/drivers/staging/most/Makefile @@ -1,6 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_MOST_CDEV) += cdev/ obj-$(CONFIG_MOST_NET) += net/ obj-$(CONFIG_MOST_SOUND) += sound/ obj-$(CONFIG_MOST_VIDEO) += video/ diff --git a/drivers/staging/most/cdev/Kconfig b/drivers/staging/most/cdev/Kconfig deleted file mode 100644 index dab99477858e..000000000000 --- a/drivers/staging/most/cdev/Kconfig +++ /dev/null @@ -1,13 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# MOST Cdev configuration -# - -config MOST_CDEV - tristate "Cdev" - - help - Say Y here if you want to commumicate via character devices. - - To compile this driver as a module, choose M here: the - module will be called most_cdev. diff --git a/drivers/staging/most/cdev/Makefile b/drivers/staging/most/cdev/Makefile deleted file mode 100644 index ef90cd71994a..000000000000 --- a/drivers/staging/most/cdev/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_MOST_CDEV) += most_cdev.o - -most_cdev-objs := cdev.o diff --git a/drivers/staging/most/dim2/dim2.c b/drivers/staging/most/dim2/dim2.c index 509c8012d20b..b34e3c130f53 100644 --- a/drivers/staging/most/dim2/dim2.c +++ b/drivers/staging/most/dim2/dim2.c @@ -100,12 +100,12 @@ struct dim2_hdm { struct medialb_bus bus; void (*on_netinfo)(struct most_interface *most_iface, unsigned char link_state, unsigned char *addrs); - void (*disable_platform)(struct platform_device *); + void (*disable_platform)(struct platform_device *pdev); }; struct dim2_platform_data { - int (*enable)(struct platform_device *); - void (*disable)(struct platform_device *); + int (*enable)(struct platform_device *pdev); + void (*disable)(struct platform_device *pdev); }; #define iface_to_hdm(iface) container_of(iface, struct dim2_hdm, most_iface) diff --git a/drivers/staging/mt7621-pci/TODO b/drivers/staging/mt7621-pci/TODO index ccfd266db4ca..d674a9ac85c1 100644 --- a/drivers/staging/mt7621-pci/TODO +++ b/drivers/staging/mt7621-pci/TODO @@ -1,4 +1,4 @@ - general code review and cleanup -Cc: NeilBrown <neil@brown.name> +Cc: NeilBrown <neil@brown.name> diff --git a/drivers/staging/octeon-usb/octeon-hcd.c b/drivers/staging/octeon-usb/octeon-hcd.c index 61471a19d4e6..e2f8b6b67f75 100644 --- a/drivers/staging/octeon-usb/octeon-hcd.c +++ b/drivers/staging/octeon-usb/octeon-hcd.c @@ -1233,8 +1233,7 @@ static int cvmx_usb_fill_tx_hw(struct octeon_hcd *usb, cvmx_write64_uint32(csr_address, *ptr++); cvmx_write64_uint32(csr_address, *ptr++); cvmx_write64_uint32(csr_address, *ptr++); - cvmx_read64_uint64( - CVMX_USBNX_DMA0_INB_CHN0(usb->index)); + cvmx_read64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index)); words -= 3; } cvmx_write64_uint32(csr_address, *ptr++); diff --git a/drivers/staging/pi433/pi433_if.h b/drivers/staging/pi433/pi433_if.h index 16c5b7fba249..d5c1521192c1 100644 --- a/drivers/staging/pi433/pi433_if.h +++ b/drivers/staging/pi433/pi433_if.h @@ -117,9 +117,15 @@ struct pi433_rx_cfg { /* packet format */ enum option_on_off enable_sync; - enum option_on_off enable_length_byte; /* should be used in combination with sync, only */ - enum address_filtering enable_address_filtering; /* operational with sync, only */ - enum option_on_off enable_crc; /* only operational, if sync on and fixed length or length byte is used */ + + /* should be used in combination with sync, only */ + enum option_on_off enable_length_byte; + + /* operational with sync, only */ + enum address_filtering enable_address_filtering; + + /* only operational, if sync on and fixed length or length byte is used */ + enum option_on_off enable_crc; __u8 sync_length; __u8 fixed_message_length; @@ -130,12 +136,16 @@ struct pi433_rx_cfg { __u8 broadcast_address; }; -#define PI433_IOC_MAGIC 'r' +#define PI433_IOC_MAGIC 'r' -#define PI433_IOC_RD_TX_CFG _IOR(PI433_IOC_MAGIC, PI433_TX_CFG_IOCTL_NR, char[sizeof(struct pi433_tx_cfg)]) -#define PI433_IOC_WR_TX_CFG _IOW(PI433_IOC_MAGIC, PI433_TX_CFG_IOCTL_NR, char[sizeof(struct pi433_tx_cfg)]) +#define PI433_IOC_RD_TX_CFG \ + _IOR(PI433_IOC_MAGIC, PI433_TX_CFG_IOCTL_NR, char[sizeof(struct pi433_tx_cfg)]) +#define PI433_IOC_WR_TX_CFG \ + _IOW(PI433_IOC_MAGIC, PI433_TX_CFG_IOCTL_NR, char[sizeof(struct pi433_tx_cfg)]) -#define PI433_IOC_RD_RX_CFG _IOR(PI433_IOC_MAGIC, PI433_RX_CFG_IOCTL_NR, char[sizeof(struct pi433_rx_cfg)]) -#define PI433_IOC_WR_RX_CFG _IOW(PI433_IOC_MAGIC, PI433_RX_CFG_IOCTL_NR, char[sizeof(struct pi433_rx_cfg)]) +#define PI433_IOC_RD_RX_CFG \ + _IOR(PI433_IOC_MAGIC, PI433_RX_CFG_IOCTL_NR, char[sizeof(struct pi433_rx_cfg)]) +#define PI433_IOC_WR_RX_CFG \ + _IOW(PI433_IOC_MAGIC, PI433_RX_CFG_IOCTL_NR, char[sizeof(struct pi433_rx_cfg)]) #endif /* PI433_H */ diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c index 2028458bea6f..e4c9f5d3bfdd 100644 --- a/drivers/staging/qlge/qlge_main.c +++ b/drivers/staging/qlge/qlge_main.c @@ -2079,9 +2079,9 @@ static void ql_process_chip_ae_intr(struct ql_adapter *qdev, break; case PCI_ERR_ANON_BUF_RD: - netdev_err(qdev->ndev, "PCI error occurred when reading " - "anonymous buffers from rx_ring %d.\n", - ib_ae_rsp->q_id); + netdev_err(qdev->ndev, + "PCI error occurred when reading anonymous buffers from rx_ring %d.\n", + ib_ae_rsp->q_id); ql_queue_asic_error(qdev); break; @@ -2415,8 +2415,7 @@ static irqreturn_t qlge_isr(int irq, void *dev_id) ql_queue_asic_error(qdev); netdev_err(qdev->ndev, "Got fatal error, STS = %x.\n", var); var = ql_read32(qdev, ERR_STS); - netdev_err(qdev->ndev, "Resetting chip. " - "Error Status Register = 0x%x\n", var); + netdev_err(qdev->ndev, "Resetting chip. Error Status Register = 0x%x\n", var); return IRQ_HANDLED; } @@ -3739,8 +3738,7 @@ static void ql_display_dev_info(struct net_device *ndev) struct ql_adapter *qdev = netdev_priv(ndev); netif_info(qdev, probe, qdev->ndev, - "Function #%d, Port %d, NIC Roll %d, NIC Rev = %d, " - "XG Roll = %d, XG Rev = %d.\n", + "Function #%d, Port %d, NIC Roll %d, NIC Rev = %d, XG Roll = %d, XG Rev = %d.\n", qdev->func, qdev->port, qdev->chip_rev_id & 0x0000000f, diff --git a/drivers/staging/qlge/qlge_mpi.c b/drivers/staging/qlge/qlge_mpi.c index e85c6ab538df..143a886080c5 100644 --- a/drivers/staging/qlge/qlge_mpi.c +++ b/drivers/staging/qlge/qlge_mpi.c @@ -117,7 +117,6 @@ int ql_own_firmware(struct ql_adapter *qdev) return 1; return 0; - } 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) netif_err(qdev, drv, qdev->ndev, "Could not read MPI, resetting RISC!\n"); ql_queue_fw_error(qdev); - } else + } else { /* Wake up the sleeping mpi_idc_work thread that is * waiting for this event. */ complete(&qdev->ide_completion); - + } return status; } @@ -347,16 +346,15 @@ static int ql_aen_lost(struct ql_adapter *qdev, struct mbox_params *mbcp) mbcp->out_count = 6; status = ql_get_mb_sts(qdev, mbcp); - if (status) + if (status) { netif_err(qdev, drv, qdev->ndev, "Lost AEN broken!\n"); - else { + } else { int i; netif_err(qdev, drv, qdev->ndev, "Lost AEN detected.\n"); for (i = 0; i < mbcp->out_count; i++) netif_err(qdev, drv, qdev->ndev, "mbox_out[%d] = 0x%.08x.\n", i, mbcp->mbox_out[i]); - } return status; @@ -405,7 +403,6 @@ static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp) } switch (mbcp->mbox_out[0]) { - /* This case is only active when we arrive here * as a result of issuing a mailbox command to * the firmware. @@ -998,9 +995,9 @@ int ql_mb_get_led_cfg(struct ql_adapter *qdev) netif_err(qdev, drv, qdev->ndev, "Failed to get LED Configuration.\n"); status = -EIO; - } else + } else { qdev->led_config = mbcp->mbox_out[1]; - + } return status; } diff --git a/drivers/staging/rtl8188eu/core/rtw_debug.c b/drivers/staging/rtl8188eu/core/rtw_debug.c index fcc8bd1011e1..3c0d20cb9c6a 100644 --- a/drivers/staging/rtl8188eu/core/rtw_debug.c +++ b/drivers/staging/rtl8188eu/core/rtw_debug.c @@ -33,7 +33,7 @@ int proc_set_write_reg(struct file *file, const char __user *buffer, unsigned long count, void *data) { struct net_device *dev = data; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); char tmp[32]; u32 addr, val, len; @@ -75,7 +75,7 @@ int proc_get_read_reg(char *page, char **start, int *eof, void *data) { struct net_device *dev = data; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); int len = 0; @@ -135,7 +135,7 @@ int proc_get_adapter_state(char *page, char **start, int *eof, void *data) { struct net_device *dev = data; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); int len = 0; len += scnprintf(page + len, count - len, "bSurpriseRemoved=%d, bDriverStopped=%d\n", @@ -150,7 +150,7 @@ int proc_get_best_channel(char *page, char **start, int *eof, void *data) { struct net_device *dev = data; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; int len = 0; u32 i, best_channel_24G = 1, index_24G = 0; diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c index 98b1ba2e489f..0eaf81e83ddc 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c @@ -3546,12 +3546,12 @@ static unsigned int on_action_spct(struct adapter *padapter, action = frame_body[1]; switch (action) { - case RTW_WLAN_ACTION_SPCT_MSR_REQ: - case RTW_WLAN_ACTION_SPCT_MSR_RPRT: - case RTW_WLAN_ACTION_SPCT_TPC_REQ: - case RTW_WLAN_ACTION_SPCT_TPC_RPRT: + case WLAN_ACTION_SPCT_MSR_REQ: + case WLAN_ACTION_SPCT_MSR_RPRT: + case WLAN_ACTION_SPCT_TPC_REQ: + case WLAN_ACTION_SPCT_TPC_RPRT: break; - case RTW_WLAN_ACTION_SPCT_CHL_SWITCH: + case WLAN_ACTION_SPCT_CHL_SWITCH: break; default: break; diff --git a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c index 39ca97411fd5..f74753c37a29 100644 --- a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c +++ b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c @@ -84,7 +84,7 @@ static int rtw_hw_resume(struct adapter *padapter) pwrpriv->bips_processing = true; rtw_reset_drv_sw(padapter); - if (ips_netdrv_open((struct adapter *)rtw_netdev_priv(pnetdev)) != _SUCCESS) { + if (ips_netdrv_open(rtw_netdev_priv(pnetdev)) != _SUCCESS) { mutex_unlock(&pwrpriv->mutex_lock); goto error_exit; } diff --git a/drivers/staging/rtl8188eu/include/ieee80211.h b/drivers/staging/rtl8188eu/include/ieee80211.h index 83218e7ec0a9..cb6940d2aeab 100644 --- a/drivers/staging/rtl8188eu/include/ieee80211.h +++ b/drivers/staging/rtl8188eu/include/ieee80211.h @@ -526,16 +526,6 @@ enum rtw_ieee80211_category { RTW_WLAN_CATEGORY_P2P = 0x7f,/* P2P action frames */ }; -/* SPECTRUM_MGMT action code */ -enum rtw_ieee80211_spectrum_mgmt_actioncode { - RTW_WLAN_ACTION_SPCT_MSR_REQ = 0, - RTW_WLAN_ACTION_SPCT_MSR_RPRT = 1, - RTW_WLAN_ACTION_SPCT_TPC_REQ = 2, - RTW_WLAN_ACTION_SPCT_TPC_RPRT = 3, - RTW_WLAN_ACTION_SPCT_CHL_SWITCH = 4, - RTW_WLAN_ACTION_SPCT_EXT_CHL_SWITCH = 5, -}; - enum _PUBLIC_ACTION { ACT_PUBLIC_BSSCOEXIST = 0, /* 20/40 BSS Coexistence */ ACT_PUBLIC_DSE_ENABLE = 1, diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c index 2e83d24fcb09..77ecf4fe8382 100644 --- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c @@ -310,30 +310,30 @@ static char *translate_scan(struct adapter *padapter, static int wpa_set_auth_algs(struct net_device *dev, u32 value) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); int ret = 0; if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) { - DBG_88E("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY and AUTH_ALG_OPEN_SYSTEM [value:0x%x]\n", value); + DBG_88E("%s, AUTH_ALG_SHARED_KEY and AUTH_ALG_OPEN_SYSTEM [value:0x%x]\n", __func__, value); padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch; padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto; } else if (value & AUTH_ALG_SHARED_KEY) { - DBG_88E("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY [value:0x%x]\n", value); + DBG_88E("%s, AUTH_ALG_SHARED_KEY [value:0x%x]\n", __func__, value); padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared; padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared; } else if (value & AUTH_ALG_OPEN_SYSTEM) { - DBG_88E("wpa_set_auth_algs, AUTH_ALG_OPEN_SYSTEM\n"); + DBG_88E("%s, AUTH_ALG_OPEN_SYSTEM\n", __func__); if (padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK) { padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen; padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; } } else if (value & AUTH_ALG_LEAP) { - DBG_88E("wpa_set_auth_algs, AUTH_ALG_LEAP\n"); + DBG_88E("%s, AUTH_ALG_LEAP\n", __func__); } else { - DBG_88E("wpa_set_auth_algs, error!\n"); + DBG_88E("%s, error!\n", __func__); ret = -EINVAL; } return ret; @@ -343,9 +343,9 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, { int ret = 0; u32 wep_key_idx, wep_key_len, wep_total_len; - struct ndis_802_11_wep *pwep = NULL; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct ndis_802_11_wep *pwep = NULL; + struct adapter *padapter = rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct security_priv *psecuritypriv = &padapter->securitypriv; param->u.crypt.err = 0; @@ -367,8 +367,8 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, } if (strcmp(param->u.crypt.alg, "WEP") == 0) { - RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("wpa_set_encryption, crypt.alg = WEP\n")); - DBG_88E("wpa_set_encryption, crypt.alg = WEP\n"); + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("%s, crypt.alg = WEP\n", __func__)); + DBG_88E("%s, crypt.alg = WEP\n", __func__); padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_; @@ -390,7 +390,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, wep_total_len = wep_key_len + offsetof(struct ndis_802_11_wep, KeyMaterial); pwep = (struct ndis_802_11_wep *)rtw_malloc(wep_total_len); if (!pwep) { - RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, (" wpa_set_encryption: pwep allocate fail !!!\n")); + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("%s: pwep allocate fail !!!\n", __func__)); goto exit; } memset(pwep, 0, wep_total_len); @@ -437,11 +437,11 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, psta->ieee8021x_blocked = false; if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) || - (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) + (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; if (param->u.crypt.set_tx == 1) { /* pairwise key */ - memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16)); + memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16)); if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */ memcpy(psta->dot11tkiptxmickey.skey, ¶m->u.crypt.key[16], 8); @@ -453,7 +453,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, rtw_setstakey_cmd(padapter, (unsigned char *)psta, true); } else { /* group key */ - memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16 )); + memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16)); memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey, ¶m->u.crypt.key[16], 8); memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey, ¶m->u.crypt.key[24], 8); padapter->securitypriv.binstallGrpkey = true; @@ -473,7 +473,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, pbcmc_sta->ieee8021x_blocked = false; if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) || - (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) + (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; } } @@ -603,8 +603,8 @@ static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ie } RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, - ("rtw_set_wpa_ie: pairwise_cipher = 0x%08x padapter->securitypriv.ndisencryptstatus =%d padapter->securitypriv.ndisauthtype =%d\n", - pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype)); + ("%s: pairwise_cipher = 0x%08x padapter->securitypriv.ndisencryptstatus =%d padapter->securitypriv.ndisauthtype =%d\n", + __func__, pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype)); exit: kfree(buf); return ret; @@ -616,7 +616,7 @@ static int rtw_wx_get_name(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); u32 ht_ielen = 0; char *p; u8 ht_cap = false; @@ -660,7 +660,7 @@ static int rtw_wx_set_freq(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+rtw_wx_set_freq\n")); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+%s\n", __func__)); return 0; } @@ -668,7 +668,7 @@ static int rtw_wx_get_freq(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; @@ -689,7 +689,7 @@ static int rtw_wx_get_freq(struct net_device *dev, static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a, union iwreq_data *wrqu, char *b) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); enum ndis_802_11_network_infra networkType; int ret = 0; @@ -737,10 +737,10 @@ exit: static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a, union iwreq_data *wrqu, char *b) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, (" rtw_wx_get_mode\n")); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s\n", __func__)); if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) wrqu->mode = IW_MODE_INFRA; @@ -759,7 +759,7 @@ static int rtw_wx_set_pmkid(struct net_device *dev, struct iw_request_info *a, union iwreq_data *wrqu, char *extra) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); u8 j, blInserted = false; int ret = false; struct security_priv *psecuritypriv = &padapter->securitypriv; @@ -769,7 +769,7 @@ static int rtw_wx_set_pmkid(struct net_device *dev, memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN); if (pPMK->cmd == IW_PMKSA_ADD) { - DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n"); + DBG_88E("[%s] IW_PMKSA_ADD!\n", __func__); if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN)) return ret; ret = true; @@ -779,7 +779,7 @@ static int rtw_wx_set_pmkid(struct net_device *dev, for (j = 0; j < NUM_PMKID_CACHE; j++) { if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) { /* BSSID is matched, the same AP => rewrite with new PMKID. */ - DBG_88E("[rtw_wx_set_pmkid] BSSID exists in the PMKList.\n"); + DBG_88E("[%s] BSSID exists in the PMKList.\n", __func__); memcpy(psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN); psecuritypriv->PMKIDList[j].bUsed = true; psecuritypriv->PMKIDIndex = j + 1; @@ -790,8 +790,8 @@ static int rtw_wx_set_pmkid(struct net_device *dev, if (!blInserted) { /* Find a new entry */ - DBG_88E("[rtw_wx_set_pmkid] Use the new entry index = %d for this PMKID.\n", - psecuritypriv->PMKIDIndex); + DBG_88E("[%s] Use the new entry index = %d for this PMKID.\n", + __func__, psecuritypriv->PMKIDIndex); memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN); memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN); @@ -802,7 +802,7 @@ static int rtw_wx_set_pmkid(struct net_device *dev, psecuritypriv->PMKIDIndex = 0; } } else if (pPMK->cmd == IW_PMKSA_REMOVE) { - DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_REMOVE!\n"); + DBG_88E("[%s] IW_PMKSA_REMOVE!\n", __func__); ret = true; for (j = 0; j < NUM_PMKID_CACHE; j++) { if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) { @@ -813,7 +813,7 @@ static int rtw_wx_set_pmkid(struct net_device *dev, } } } else if (pPMK->cmd == IW_PMKSA_FLUSH) { - DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_FLUSH!\n"); + DBG_88E("[%s] IW_PMKSA_FLUSH!\n", __func__); memset(&psecuritypriv->PMKIDList[0], 0x00, sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE); psecuritypriv->PMKIDIndex = 0; ret = true; @@ -836,13 +836,13 @@ static int rtw_wx_get_range(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct iw_range *range = (struct iw_range *)extra; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; u16 val; int i; - RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_range. cmd_code =%x\n", info->cmd)); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s. cmd_code =%x\n", __func__, info->cmd)); wrqu->data.length = sizeof(*range); memset(range, 0, sizeof(*range)); @@ -936,7 +936,7 @@ static int rtw_wx_set_wap(struct net_device *dev, char *extra) { uint ret = 0; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct sockaddr *temp = (struct sockaddr *)awrq; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct list_head *phead; @@ -1001,7 +1001,7 @@ static int rtw_wx_get_wap(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; @@ -1009,7 +1009,7 @@ static int rtw_wx_get_wap(struct net_device *dev, eth_zero_addr(wrqu->ap_addr.sa_data); - RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_wap\n")); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s\n", __func__)); if (check_fwstate(pmlmepriv, _FW_LINKED) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) || @@ -1026,7 +1026,7 @@ static int rtw_wx_set_mlme(struct net_device *dev, { int ret = 0; u16 reason; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct iw_mlme *mlme = (struct iw_mlme *)extra; if (!mlme) @@ -1058,11 +1058,11 @@ static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a, { u8 _status = false; int ret = 0; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct ndis_802_11_ssid ssid[RTW_SSID_SCAN_AMOUNT]; - RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_set_scan\n")); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s\n", __func__)); if (_FAIL == rtw_pwr_wakeup(padapter)) { ret = -1; @@ -1122,7 +1122,7 @@ static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a, spin_unlock_bh(&pmlmepriv->lock); } else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) { - DBG_88E("rtw_wx_set_scan, req->scan_type == IW_SCAN_TYPE_PASSIVE\n"); + DBG_88E("%s, req->scan_type == IW_SCAN_TYPE_PASSIVE\n", __func__); } } else { if (wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE && @@ -1187,7 +1187,7 @@ static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a, union iwreq_data *wrqu, char *extra) { struct list_head *plist, *phead; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct __queue *queue = &pmlmepriv->scanned_queue; struct wlan_network *pnetwork = NULL; @@ -1198,7 +1198,7 @@ static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a, u32 wait_for_surveydone; int wait_status; - RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan\n")); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s\n", __func__)); RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, (" Start of Query SIOCGIWSCAN .\n")); if (padapter->pwrctrlpriv.brfoffbyhw && padapter->bDriverStopped) { @@ -1255,7 +1255,7 @@ static int rtw_wx_set_essid(struct net_device *dev, struct iw_request_info *a, union iwreq_data *wrqu, char *extra) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct __queue *queue = &pmlmepriv->scanned_queue; struct list_head *phead; @@ -1267,7 +1267,7 @@ static int rtw_wx_set_essid(struct net_device *dev, uint ret = 0, len; RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, - ("+rtw_wx_set_essid: fw_state = 0x%08x\n", get_fwstate(pmlmepriv))); + ("+%s: fw_state = 0x%08x\n", __func__, get_fwstate(pmlmepriv))); if (_FAIL == rtw_pwr_wakeup(padapter)) { ret = -1; goto exit; @@ -1301,7 +1301,7 @@ static int rtw_wx_set_essid(struct net_device *dev, memcpy(ndis_ssid.ssid, extra, len); src_ssid = ndis_ssid.ssid; - RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("rtw_wx_set_essid: ssid =[%s]\n", src_ssid)); + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("%s: ssid =[%s]\n", __func__, src_ssid)); spin_lock_bh(&queue->lock); phead = get_list_head(queue); pmlmepriv->pscanned = phead->next; @@ -1314,13 +1314,13 @@ static int rtw_wx_set_essid(struct net_device *dev, dst_ssid = pnetwork->network.ssid.ssid; RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, - ("rtw_wx_set_essid: dst_ssid =%s\n", + ("%s: dst_ssid =%s\n", __func__, pnetwork->network.ssid.ssid)); if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.ssid_length)) && (pnetwork->network.ssid.ssid_length == ndis_ssid.ssid_length)) { RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, - ("rtw_wx_set_essid: find match, set infra mode\n")); + ("%s: find match, set infra mode\n", __func__)); if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode) @@ -1357,11 +1357,11 @@ static int rtw_wx_get_essid(struct net_device *dev, union iwreq_data *wrqu, char *extra) { u32 len; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; - RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_essid\n")); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s\n", __func__)); if ((check_fwstate(pmlmepriv, _FW_LINKED)) || (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))) { @@ -1388,7 +1388,7 @@ static int rtw_wx_set_rate(struct net_device *dev, u32 ratevalue = 0; u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff}; - RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, (" rtw_wx_set_rate\n")); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s\n", __func__)); RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("target_rate = %d, fixed = %d\n", target_rate, fixed)); if (target_rate == -1) { @@ -1462,7 +1462,7 @@ static int rtw_wx_get_rate(struct net_device *dev, { u16 max_rate = 0; - max_rate = rtw_get_cur_max_rate((struct adapter *)rtw_netdev_priv(dev)); + max_rate = rtw_get_cur_max_rate(rtw_netdev_priv(dev)); if (max_rate == 0) return -EPERM; @@ -1477,7 +1477,7 @@ static int rtw_wx_set_rts(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); if (wrqu->rts.disabled) { padapter->registrypriv.rts_thresh = 2347; @@ -1498,7 +1498,7 @@ static int rtw_wx_get_rts(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); DBG_88E("%s, rts_thresh =%d\n", __func__, padapter->registrypriv.rts_thresh); @@ -1513,7 +1513,7 @@ static int rtw_wx_set_frag(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); if (wrqu->frag.disabled) { padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD; @@ -1534,7 +1534,7 @@ static int rtw_wx_get_frag(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); DBG_88E("%s, frag_len =%d\n", __func__, padapter->xmitpriv.frag_len); @@ -1565,10 +1565,10 @@ static int rtw_wx_set_enc(struct net_device *dev, enum ndis_802_11_auth_mode authmode; struct iw_point *erq = &wrqu->encoding; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; - DBG_88E("+rtw_wx_set_enc, flags = 0x%x\n", erq->flags); + DBG_88E("+%s, flags = 0x%x\n", __func__, erq->flags); memset(&wep, 0, sizeof(struct ndis_802_11_wep)); @@ -1594,12 +1594,12 @@ static int rtw_wx_set_enc(struct net_device *dev, } else { keyindex_provided = 0; key = padapter->securitypriv.dot11PrivacyKeyIndex; - DBG_88E("rtw_wx_set_enc, key =%d\n", key); + DBG_88E("%s, key =%d\n", __func__, key); } /* set authentication mode */ if (erq->flags & IW_ENCODE_OPEN) { - DBG_88E("rtw_wx_set_enc():IW_ENCODE_OPEN\n"); + DBG_88E("%s():IW_ENCODE_OPEN\n", __func__); padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; @@ -1607,7 +1607,7 @@ static int rtw_wx_set_enc(struct net_device *dev, authmode = Ndis802_11AuthModeOpen; padapter->securitypriv.ndisauthtype = authmode; } else if (erq->flags & IW_ENCODE_RESTRICTED) { - DBG_88E("rtw_wx_set_enc():IW_ENCODE_RESTRICTED\n"); + DBG_88E("%s():IW_ENCODE_RESTRICTED\n", __func__); padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared; padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_; @@ -1615,7 +1615,7 @@ static int rtw_wx_set_enc(struct net_device *dev, authmode = Ndis802_11AuthModeShared; padapter->securitypriv.ndisauthtype = authmode; } else { - DBG_88E("rtw_wx_set_enc():erq->flags = 0x%x\n", erq->flags); + DBG_88E("%s():erq->flags = 0x%x\n", __func__, erq->flags); padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; @@ -1674,7 +1674,7 @@ static int rtw_wx_get_enc(struct net_device *dev, union iwreq_data *wrqu, char *keybuf) { uint key; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct iw_point *erq = &wrqu->encoding; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; @@ -1749,7 +1749,7 @@ static int rtw_wx_set_gen_ie(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); return rtw_set_wpa_ie(padapter, extra, wrqu->data.length); } @@ -1758,7 +1758,7 @@ static int rtw_wx_set_auth(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct iw_param *param = (struct iw_param *)&wrqu->param; int ret = 0; @@ -1930,7 +1930,7 @@ static int dummy(struct net_device *dev, struct iw_request_info *a, static int wpa_set_param(struct net_device *dev, u8 name, u32 value) { uint ret = 0; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); switch (name) { case IEEE_PARAM_WPA_ENABLED: @@ -1946,7 +1946,7 @@ static int wpa_set_param(struct net_device *dev, u8 name, u32 value) break; } RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, - ("wpa_set_param:padapter->securitypriv.ndisauthtype =%d\n", padapter->securitypriv.ndisauthtype)); + ("%s:padapter->securitypriv.ndisauthtype =%d\n", __func__, padapter->securitypriv.ndisauthtype)); break; case IEEE_PARAM_TKIP_COUNTERMEASURES: break; @@ -1985,7 +1985,7 @@ static int wpa_set_param(struct net_device *dev, u8 name, u32 value) static int wpa_mlme(struct net_device *dev, u32 command, u32 reason) { int ret = 0; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); switch (command) { case IEEE_MLME_STA_DEAUTH: @@ -2022,7 +2022,7 @@ static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p) break; case IEEE_CMD_SET_WPA_IE: - ret = rtw_set_wpa_ie((struct adapter *)rtw_netdev_priv(dev), + ret = rtw_set_wpa_ie(rtw_netdev_priv(dev), (char *)param->u.wpa_ie.data, (u16)param->u.wpa_ie.len); break; @@ -2166,7 +2166,7 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, u32 wep_key_idx, wep_key_len, wep_total_len; struct ndis_802_11_wep *pwep = NULL; struct sta_info *psta = NULL, *pbcmc_sta = NULL; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct security_priv *psecuritypriv = &padapter->securitypriv; struct sta_priv *pstapriv = &padapter->stapriv; @@ -2186,7 +2186,7 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, } else { psta = rtw_get_stainfo(pstapriv, param->sta_addr); if (!psta) { - DBG_88E("rtw_set_encryption(), sta has already been removed or never been added\n"); + DBG_88E("%s(), sta has already been removed or never been added\n", __func__); goto exit; } } @@ -2392,7 +2392,7 @@ exit: static int rtw_set_beacon(struct net_device *dev, struct ieee_param *param, int len) { int ret = 0; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct sta_priv *pstapriv = &padapter->stapriv; unsigned char *pbuf = param->u.bcn_ie.buf; @@ -2417,7 +2417,7 @@ static int rtw_set_beacon(struct net_device *dev, struct ieee_param *param, int static int rtw_hostapd_sta_flush(struct net_device *dev) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); DBG_88E("%s\n", __func__); @@ -2430,11 +2430,11 @@ static int rtw_add_sta(struct net_device *dev, struct ieee_param *param) { int ret = 0; struct sta_info *psta = NULL; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct sta_priv *pstapriv = &padapter->stapriv; - DBG_88E("rtw_add_sta(aid =%d) =%pM\n", param->u.add_sta.aid, (param->sta_addr)); + DBG_88E("%s(aid =%d) =%pM\n", __func__, param->u.add_sta.aid, (param->sta_addr)); if (!check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE))) return -EINVAL; @@ -2483,12 +2483,12 @@ static int rtw_add_sta(struct net_device *dev, struct ieee_param *param) static int rtw_del_sta(struct net_device *dev, struct ieee_param *param) { struct sta_info *psta = NULL; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct sta_priv *pstapriv = &padapter->stapriv; int updated = 0; - DBG_88E("rtw_del_sta =%pM\n", (param->sta_addr)); + DBG_88E("%s =%pM\n", __func__, (param->sta_addr)); if (!check_fwstate(pmlmepriv, _FW_LINKED | WIFI_AP_STATE)) return -EINVAL; @@ -2508,7 +2508,7 @@ static int rtw_del_sta(struct net_device *dev, struct ieee_param *param) associated_clients_update(padapter, updated); psta = NULL; } else { - DBG_88E("rtw_del_sta(), sta has already been removed or never been added\n"); + DBG_88E("%s(), sta has already been removed or never been added\n", __func__); } return 0; @@ -2518,7 +2518,7 @@ static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *par { int ret = 0; struct sta_info *psta = NULL; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct sta_priv *pstapriv = &padapter->stapriv; struct ieee_param_ex *param_ex = (struct ieee_param_ex *)param; @@ -2574,11 +2574,11 @@ static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param) { int ret = 0; struct sta_info *psta = NULL; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct sta_priv *pstapriv = &padapter->stapriv; - DBG_88E("rtw_get_sta_wpaie, sta_addr: %pM\n", (param->sta_addr)); + DBG_88E("%s, sta_addr: %pM\n", __func__, (param->sta_addr)); if (!check_fwstate(pmlmepriv, _FW_LINKED | WIFI_AP_STATE)) return -EINVAL; @@ -2610,7 +2610,7 @@ static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param) static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, int len) { unsigned char wps_oui[4] = {0x0, 0x50, 0xf2, 0x04}; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; int ie_len; @@ -2645,7 +2645,7 @@ static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *param, int len) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; int ie_len; @@ -2674,7 +2674,7 @@ static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *par static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *param, int len) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; int ie_len; @@ -2704,7 +2704,7 @@ static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *par static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param, int len) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; @@ -2728,7 +2728,7 @@ static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param, static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *param, int len) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; if (!check_fwstate(pmlmepriv, WIFI_AP_STATE)) @@ -2742,7 +2742,7 @@ static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *p static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *param, int len) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; if (!check_fwstate(pmlmepriv, WIFI_AP_STATE)) @@ -2756,7 +2756,7 @@ static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *para static int rtw_ioctl_set_macaddr_acl(struct net_device *dev, struct ieee_param *param, int len) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; if (!check_fwstate(pmlmepriv, WIFI_AP_STATE)) @@ -2771,7 +2771,7 @@ static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p) { struct ieee_param *param; int ret = 0; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); /* * this function is expect to call in master mode, which allows no power saving @@ -2853,7 +2853,7 @@ static int rtw_wx_set_priv(struct net_device *dev, int ret = 0; int len = 0; char *ext; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct iw_point *dwrq = (struct iw_point *)awrq; if (dwrq->length == 0) @@ -2971,7 +2971,7 @@ static iw_handler rtw_handlers[] = { static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct iw_statistics *piwstats = &padapter->iwstats; int tmp_level = 0; int tmp_qual = 0; diff --git a/drivers/staging/rtl8188eu/os_dep/os_intfs.c b/drivers/staging/rtl8188eu/os_dep/os_intfs.c index 8907bf6bb7ff..e291df87f620 100644 --- a/drivers/staging/rtl8188eu/os_dep/os_intfs.c +++ b/drivers/staging/rtl8188eu/os_dep/os_intfs.c @@ -187,7 +187,7 @@ static void loadparam(struct adapter *padapter, struct net_device *pnetdev) static int rtw_net_set_mac_address(struct net_device *pnetdev, void *p) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); + struct adapter *padapter = rtw_netdev_priv(pnetdev); struct sockaddr *addr = p; if (!padapter->bup) @@ -198,7 +198,7 @@ static int rtw_net_set_mac_address(struct net_device *pnetdev, void *p) static struct net_device_stats *rtw_net_get_stats(struct net_device *pnetdev) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); + struct adapter *padapter = rtw_netdev_priv(pnetdev); struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct recv_priv *precvpriv = &padapter->recvpriv; @@ -335,7 +335,7 @@ static int rtw_start_drv_threads(struct adapter *padapter) { int err = 0; - RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+rtw_start_drv_threads\n")); + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+%s\n", __func__)); padapter->cmdThread = kthread_run(rtw_cmd_thread, padapter, "RTW_CMD_THREAD"); @@ -350,7 +350,7 @@ static int rtw_start_drv_threads(struct adapter *padapter) void rtw_stop_drv_threads(struct adapter *padapter) { - RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+rtw_stop_drv_threads\n")); + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+%s\n", __func__)); /* Below is to terminate rtw_cmd_thread & event_thread... */ complete(&padapter->cmdpriv.cmd_queue_comp); @@ -433,7 +433,7 @@ u8 rtw_init_drv_sw(struct adapter *padapter) { u8 ret8 = _SUCCESS; - RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+rtw_init_drv_sw\n")); + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+%s\n", __func__)); if ((rtw_init_cmd_priv(&padapter->cmdpriv)) == _FAIL) { RT_TRACE(_module_os_intfs_c_, _drv_err_, ("\n Can't init cmd_priv\n")); @@ -487,27 +487,27 @@ u8 rtw_init_drv_sw(struct adapter *padapter) rtw_hal_sreset_init(padapter); exit: - RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-rtw_init_drv_sw\n")); + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-%s\n", __func__)); return ret8; } void rtw_cancel_all_timer(struct adapter *padapter) { - RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+rtw_cancel_all_timer\n")); + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+%s\n", __func__)); del_timer_sync(&padapter->mlmepriv.assoc_timer); - RT_TRACE(_module_os_intfs_c_, _drv_info_, ("rtw_cancel_all_timer:cancel association timer complete!\n")); + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("%s:cancel association timer complete!\n", __func__)); del_timer_sync(&padapter->mlmepriv.scan_to_timer); - RT_TRACE(_module_os_intfs_c_, _drv_info_, ("rtw_cancel_all_timer:cancel scan_to_timer!\n")); + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("%s:cancel scan_to_timer!\n", __func__)); del_timer_sync(&padapter->mlmepriv.dynamic_chk_timer); - RT_TRACE(_module_os_intfs_c_, _drv_info_, ("rtw_cancel_all_timer:cancel dynamic_chk_timer!\n")); + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("%s:cancel dynamic_chk_timer!\n", __func__)); /* cancel sw led timer */ rtw_hal_sw_led_deinit(padapter); - RT_TRACE(_module_os_intfs_c_, _drv_info_, ("rtw_cancel_all_timer:cancel DeInitSwLeds!\n")); + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("%s:cancel DeInitSwLeds!\n", __func__)); del_timer_sync(&padapter->pwrctrlpriv.pwr_state_check_timer); @@ -516,7 +516,7 @@ void rtw_cancel_all_timer(struct adapter *padapter) u8 rtw_free_drv_sw(struct adapter *padapter) { - RT_TRACE(_module_os_intfs_c_, _drv_info_, ("==>rtw_free_drv_sw")); + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("==>%s", __func__)); free_mlme_ext_priv(&padapter->mlmeextpriv); @@ -530,11 +530,11 @@ u8 rtw_free_drv_sw(struct adapter *padapter) rtw_hal_free_data(padapter); - RT_TRACE(_module_os_intfs_c_, _drv_info_, ("<== rtw_free_drv_sw\n")); + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("<== %s\n", __func__)); mutex_destroy(&padapter->hw_init_mutex); - RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-rtw_free_drv_sw\n")); + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-%s\n", __func__)); return _SUCCESS; } @@ -543,7 +543,7 @@ static int _netdev_open(struct net_device *pnetdev) { uint status; int err; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); + struct adapter *padapter = rtw_netdev_priv(pnetdev); struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+88eu_drv - dev_open\n")); @@ -612,7 +612,7 @@ netdev_open_error: int netdev_open(struct net_device *pnetdev) { int ret; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); + struct adapter *padapter = rtw_netdev_priv(pnetdev); if (mutex_lock_interruptible(&padapter->hw_init_mutex)) return -ERESTARTSYS; @@ -633,7 +633,7 @@ int ips_netdrv_open(struct adapter *padapter) status = rtw_hal_init(padapter); if (status == _FAIL) { - RT_TRACE(_module_os_intfs_c_, _drv_err_, ("ips_netdrv_open(): Can't init h/w!\n")); + RT_TRACE(_module_os_intfs_c_, _drv_err_, ("%s(): Can't init h/w!\n", __func__)); goto netdev_open_error; } @@ -646,7 +646,7 @@ int ips_netdrv_open(struct adapter *padapter) return _SUCCESS; netdev_open_error: - DBG_88E("-ips_netdrv_open - drv_open failure, bup =%d\n", padapter->bup); + DBG_88E("-%s - drv_open failure, bup =%d\n", __func__, padapter->bup); return _FAIL; } @@ -656,14 +656,14 @@ int rtw_ips_pwr_up(struct adapter *padapter) int result; unsigned long start_time = jiffies; - DBG_88E("===> rtw_ips_pwr_up..............\n"); + DBG_88E("===> %s..............\n", __func__); rtw_reset_drv_sw(padapter); result = ips_netdrv_open(padapter); led_control_8188eu(padapter, LED_CTL_NO_LINK); - DBG_88E("<=== rtw_ips_pwr_up.............. in %dms\n", + DBG_88E("<=== %s.............. in %dms\n", __func__, jiffies_to_msecs(jiffies - start_time)); return result; } @@ -672,14 +672,14 @@ void rtw_ips_pwr_down(struct adapter *padapter) { unsigned long start_time = jiffies; - DBG_88E("===> rtw_ips_pwr_down...................\n"); + DBG_88E("===> %s...................\n", __func__); padapter->net_closed = true; led_control_8188eu(padapter, LED_CTL_POWER_OFF); rtw_ips_dev_unload(padapter); - DBG_88E("<=== rtw_ips_pwr_down..................... in %dms\n", + DBG_88E("<=== %s..................... in %dms\n", __func__, jiffies_to_msecs(jiffies - start_time)); } @@ -698,7 +698,7 @@ void rtw_ips_dev_unload(struct adapter *padapter) static int netdev_close(struct net_device *pnetdev) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); + struct adapter *padapter = rtw_netdev_priv(pnetdev); RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+88eu_drv - drv_close\n")); diff --git a/drivers/staging/rtl8188eu/os_dep/rtw_android.c b/drivers/staging/rtl8188eu/os_dep/rtw_android.c index bf86d03820ca..9fe15dbe8133 100644 --- a/drivers/staging/rtl8188eu/os_dep/rtw_android.c +++ b/drivers/staging/rtl8188eu/os_dep/rtw_android.c @@ -76,7 +76,7 @@ int rtw_android_cmdstr_to_num(char *cmdstr) static int rtw_android_get_rssi(struct net_device *net, char *command, int total_len) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(net); + struct adapter *padapter = rtw_netdev_priv(net); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_network *pcur_network = &pmlmepriv->cur_network; int bytes_written = 0; @@ -93,7 +93,7 @@ static int rtw_android_get_rssi(struct net_device *net, char *command, static int rtw_android_get_link_speed(struct net_device *net, char *command, int total_len) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(net); + struct adapter *padapter = rtw_netdev_priv(net); u16 link_speed; link_speed = rtw_get_cur_max_rate(padapter) / 10; @@ -111,7 +111,7 @@ static int rtw_android_get_macaddr(struct net_device *net, char *command, static int android_set_cntry(struct net_device *net, char *command, int total_len) { - struct adapter *adapter = (struct adapter *)rtw_netdev_priv(net); + struct adapter *adapter = rtw_netdev_priv(net); char *country_code = command + strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_COUNTRY]) + 1; int ret; diff --git a/drivers/staging/rtl8188eu/os_dep/usb_intf.c b/drivers/staging/rtl8188eu/os_dep/usb_intf.c index f7f09c0d273f..cbf82f915303 100644 --- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c +++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c @@ -141,7 +141,7 @@ static void usb_dvobj_deinit(struct usb_interface *usb_intf) void usb_intf_stop(struct adapter *padapter) { - RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+usb_intf_stop\n")); + RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+%s\n", __func__)); /* disable_hw_interrupt */ if (!padapter->bSurpriseRemoved) { @@ -159,15 +159,15 @@ void usb_intf_stop(struct adapter *padapter) /* todo:cancel other irps */ - RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-usb_intf_stop\n")); + RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-%s\n", __func__)); } static void rtw_dev_unload(struct adapter *padapter) { - RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_dev_unload\n")); + RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+%s\n", __func__)); if (padapter->bup) { - pr_debug("===> rtw_dev_unload\n"); + pr_debug("===> %s\n", __func__); padapter->bDriverStopped = true; if (padapter->xmitpriv.ack_tx) rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_DRV_STOP); @@ -189,9 +189,9 @@ static void rtw_dev_unload(struct adapter *padapter) ("r871x_dev_unload():padapter->bup == false\n")); } - pr_debug("<=== rtw_dev_unload\n"); + pr_debug("<=== %s\n", __func__); - RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-rtw_dev_unload\n")); + RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-%s\n", __func__)); } static int rtw_suspend(struct usb_interface *pusb_intf, pm_message_t message) @@ -486,7 +486,7 @@ static void rtw_dev_remove(struct usb_interface *pusb_intf) struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf); struct adapter *padapter = dvobj->if1; - pr_debug("+rtw_dev_remove\n"); + pr_debug("+%s\n", __func__); RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+dev_remove()\n")); if (!pusb_intf->unregistering) diff --git a/drivers/staging/rtl8188eu/os_dep/xmit_linux.c b/drivers/staging/rtl8188eu/os_dep/xmit_linux.c index a73313cf6a75..c22ddeb9a56b 100644 --- a/drivers/staging/rtl8188eu/os_dep/xmit_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/xmit_linux.c @@ -164,7 +164,7 @@ static int rtw_mlcst2unicst(struct adapter *padapter, struct sk_buff *skb) int rtw_xmit_entry(struct sk_buff *pkt, struct net_device *pnetdev) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); + struct adapter *padapter = rtw_netdev_priv(pnetdev); struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; s32 res = 0; diff --git a/drivers/staging/rtl8192e/rtllib_tx.c b/drivers/staging/rtl8192e/rtllib_tx.c index 79d7ad7c0a4a..e0d79daca24a 100644 --- a/drivers/staging/rtl8192e/rtllib_tx.c +++ b/drivers/staging/rtl8192e/rtllib_tx.c @@ -859,7 +859,7 @@ static int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) if (ieee->seq_ctrl[0] == 0xFFF) ieee->seq_ctrl[0] = 0; else - ieee->seq_ctrl[0]++; + ieee->seq_ctrl[0]++; } } else { if (unlikely(skb->len < sizeof(struct rtllib_hdr_3addr))) { diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c index 195d963c4fbb..b6fee7230ce0 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c @@ -597,7 +597,7 @@ static void RxReorderIndicatePacket(struct ieee80211_device *ieee, prxbIndicateArray = kmalloc_array(REORDER_WIN_SIZE, sizeof(struct ieee80211_rxb *), - GFP_KERNEL); + GFP_ATOMIC); if (!prxbIndicateArray) return; diff --git a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c index a3ea7ce3e12e..a5790a648a5b 100644 --- a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c @@ -374,20 +374,7 @@ u8 rtw_get_center_ch(u8 channel, u8 chnl_bw, u8 chnl_offset) u8 center_ch = channel; if (chnl_bw == CHANNEL_WIDTH_80) { - if ((channel == 36) || (channel == 40) || (channel == 44) || (channel == 48)) - center_ch = 42; - if ((channel == 52) || (channel == 56) || (channel == 60) || (channel == 64)) - center_ch = 58; - if ((channel == 100) || (channel == 104) || (channel == 108) || (channel == 112)) - center_ch = 106; - if ((channel == 116) || (channel == 120) || (channel == 124) || (channel == 128)) - center_ch = 122; - if ((channel == 132) || (channel == 136) || (channel == 140) || (channel == 144)) - center_ch = 138; - if ((channel == 149) || (channel == 153) || (channel == 157) || (channel == 161)) - center_ch = 155; - else if (channel <= 14) - center_ch = 7; + center_ch = 7; } else if (chnl_bw == CHANNEL_WIDTH_40) { if (chnl_offset == HAL_PRIME_CHNL_OFFSET_LOWER) center_ch = channel + 2; diff --git a/drivers/staging/rtl8723bs/include/osdep_service_linux.h b/drivers/staging/rtl8723bs/include/osdep_service_linux.h index 1710fa3eeb71..4a5bdb93e75d 100644 --- a/drivers/staging/rtl8723bs/include/osdep_service_linux.h +++ b/drivers/staging/rtl8723bs/include/osdep_service_linux.h @@ -129,8 +129,6 @@ static inline void rtw_netif_stop_queue(struct net_device *pnetdev) #define rtw_signal_process(pid, sig) kill_pid(find_vpid((pid)), (sig), 1) -#define rtw_netdev_priv(netdev) (((struct rtw_netdev_priv_indicator *)netdev_priv(netdev))->priv) - #define NDEV_FMT "%s" #define NDEV_ARG(ndev) ndev->name #define ADPT_FMT "%s" @@ -144,6 +142,12 @@ struct rtw_netdev_priv_indicator { void *priv; u32 sizeof_priv; }; + +static inline struct adapter *rtw_netdev_priv(struct net_device *netdev) +{ + return ((struct rtw_netdev_priv_indicator *)netdev_priv(netdev))->priv; +} + struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, void *old_priv); extern struct net_device * rtw_alloc_etherdev(int sizeof_priv); diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c index 2fb80b6eb51d..ea3ae3d38337 100644 --- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c +++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c @@ -2021,7 +2021,7 @@ static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) } leave_ibss: - return 0; + return ret; } static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev, diff --git a/drivers/staging/rtl8723bs/os_dep/sdio_intf.c b/drivers/staging/rtl8723bs/os_dep/sdio_intf.c index 5b1392deb0a7..79b55ec827a4 100644 --- a/drivers/staging/rtl8723bs/os_dep/sdio_intf.c +++ b/drivers/staging/rtl8723bs/os_dep/sdio_intf.c @@ -15,8 +15,7 @@ #define dev_to_sdio_func(d) container_of(d, struct sdio_func, dev) #endif -static const struct sdio_device_id sdio_ids[] = -{ +static const struct sdio_device_id sdio_ids[] = { { SDIO_DEVICE(0x024c, 0x0523), }, { SDIO_DEVICE(0x024c, 0x0525), }, { SDIO_DEVICE(0x024c, 0x0623), }, @@ -132,6 +131,7 @@ static irqreturn_t gpio_hostwakeup_irq_thread(int irq, void *data) static u8 gpio_hostwakeup_alloc_irq(struct adapter *padapter) { int err; + if (oob_irq == 0) { DBG_871X("oob_irq ZERO!\n"); return _FAIL; diff --git a/drivers/staging/rts5208/rtsx_transport.c b/drivers/staging/rts5208/rtsx_transport.c index 0027bcf638ad..909a3e663ef6 100644 --- a/drivers/staging/rts5208/rtsx_transport.c +++ b/drivers/staging/rts5208/rtsx_transport.c @@ -257,8 +257,8 @@ int rtsx_send_cmd(struct rtsx_chip *chip, u8 card, int timeout) spin_unlock_irq(&rtsx->reg_lock); /* Wait for TRANS_OK_INT */ - timeleft = wait_for_completion_interruptible_timeout( - &trans_done, msecs_to_jiffies(timeout)); + timeleft = wait_for_completion_interruptible_timeout(&trans_done, + msecs_to_jiffies(timeout)); if (timeleft <= 0) { dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n", chip->int_reg); @@ -284,8 +284,8 @@ finish_send_cmd: return err; } -static inline void rtsx_add_sg_tbl( - struct rtsx_chip *chip, u32 addr, u32 len, u8 option) +static inline void rtsx_add_sg_tbl(struct rtsx_chip *chip, + u32 addr, u32 len, u8 option) { __le64 *sgb = (__le64 *)(chip->host_sg_tbl_ptr); u64 val = 0; @@ -419,8 +419,8 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, spin_unlock_irq(&rtsx->reg_lock); - timeleft = wait_for_completion_interruptible_timeout( - &trans_done, msecs_to_jiffies(timeout)); + timeleft = wait_for_completion_interruptible_timeout(&trans_done, + msecs_to_jiffies(timeout)); if (timeleft <= 0) { dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n", __func__, __LINE__); @@ -443,8 +443,8 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, if (rtsx->trans_result == TRANS_NOT_READY) { init_completion(&trans_done); spin_unlock_irq(&rtsx->reg_lock); - timeleft = wait_for_completion_interruptible_timeout( - &trans_done, msecs_to_jiffies(timeout)); + timeleft = wait_for_completion_interruptible_timeout(&trans_done, + msecs_to_jiffies(timeout)); if (timeleft <= 0) { dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n", __func__, __LINE__); @@ -563,8 +563,8 @@ static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card, spin_unlock_irq(&rtsx->reg_lock); - timeleft = wait_for_completion_interruptible_timeout( - &trans_done, msecs_to_jiffies(timeout)); + timeleft = wait_for_completion_interruptible_timeout(&trans_done, + msecs_to_jiffies(timeout)); if (timeleft <= 0) { dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n", __func__, __LINE__); @@ -590,8 +590,8 @@ static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card, if (rtsx->trans_result == TRANS_NOT_READY) { init_completion(&trans_done); spin_unlock_irq(&rtsx->reg_lock); - timeleft = wait_for_completion_interruptible_timeout( - &trans_done, msecs_to_jiffies(timeout)); + timeleft = wait_for_completion_interruptible_timeout(&trans_done, + msecs_to_jiffies(timeout)); if (timeleft <= 0) { dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n", __func__, __LINE__); diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c index 84fb585a5739..029f0d09e966 100644 --- a/drivers/staging/sm750fb/sm750.c +++ b/drivers/staging/sm750fb/sm750.c @@ -411,6 +411,7 @@ static int __maybe_unused lynxfb_suspend(struct device *dev) { struct fb_info *info; struct sm750_dev *sm750_dev; + sm750_dev = dev_get_drvdata(dev); console_lock(); @@ -500,7 +501,7 @@ static int lynxfb_ops_check_var(struct fb_var_screeninfo *var, var->height = var->width = -1; var->accel_flags = 0;/* FB_ACCELF_TEXT; */ - /* check if current fb's video memory big enought to hold the onscreen*/ + /* check if current fb's video memory big enough to hold the onscreen*/ request = var->xres_virtual * (var->bits_per_pixel >> 3); /* defaulty crtc->channel go with par->index */ diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 76de1fd568eb..09ab6d6f2429 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -555,7 +555,7 @@ static int device_init_rd0_ring(struct vnt_private *priv) } if (i > 0) - priv->aRD0Ring[i-1].next_desc = cpu_to_le32(priv->rd0_pool_dma); + priv->aRD0Ring[i - 1].next_desc = cpu_to_le32(priv->rd0_pool_dma); priv->pCurrRD[0] = &priv->aRD0Ring[0]; return 0; @@ -596,12 +596,12 @@ static int device_init_rd1_ring(struct vnt_private *priv) goto err_free_rd; } - desc->next = &priv->aRD1Ring[(i+1) % priv->opts.rx_descs1]; + desc->next = &priv->aRD1Ring[(i + 1) % priv->opts.rx_descs1]; desc->next_desc = cpu_to_le32(curr + sizeof(struct vnt_rx_desc)); } if (i > 0) - priv->aRD1Ring[i-1].next_desc = cpu_to_le32(priv->rd1_pool_dma); + priv->aRD1Ring[i - 1].next_desc = cpu_to_le32(priv->rd1_pool_dma); priv->pCurrRD[1] = &priv->aRD1Ring[0]; return 0; diff --git a/drivers/staging/vt6655/mac.h b/drivers/staging/vt6655/mac.h index c7888c4e96f2..6e2bd16ef384 100644 --- a/drivers/staging/vt6655/mac.h +++ b/drivers/staging/vt6655/mac.h @@ -621,7 +621,7 @@ do { \ /* set the chip with current BCN length */ #define MACvSetCurrBCNLength(iobase, wCurrBCNLength) \ - VNSvOutPortW(iobase + MAC_REG_BCNDMACTL+2, \ + VNSvOutPortW(iobase + MAC_REG_BCNDMACTL + 2, \ wCurrBCNLength) #define MACvReadBSSIDAddress(iobase, pbyEtherAddr) \ diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 4778439e8757..477d19314634 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -367,52 +367,52 @@ s_uGetRTSCTSDuration( case RTSDUR_BA_F0: /* RTSDuration_ba_f0 */ uCTSTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck); + uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate - RATE_18M], bNeedAck); else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck); + uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate - RATE_18M], bNeedAck); break; case RTSDUR_AA_F0: /* RTSDuration_aa_f0 */ uCTSTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck); + uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate - RATE_18M], bNeedAck); else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck); + uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate - RATE_18M], bNeedAck); break; case RTSDUR_BA_F1: /* RTSDuration_ba_f1 */ uCTSTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck); + uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate - RATE_18M], bNeedAck); else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck); + uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate - RATE_18M], bNeedAck); break; case RTSDUR_AA_F1: /* RTSDuration_aa_f1 */ uCTSTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck); + uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate - RATE_18M], bNeedAck); else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck); + uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate - RATE_18M], bNeedAck); break; case CTSDUR_BA_F0: /* CTSDuration_ba_f0 */ if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck); + uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate - RATE_18M], bNeedAck); else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck); + uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate - RATE_18M], bNeedAck); break; case CTSDUR_BA_F1: /* CTSDuration_ba_f1 */ if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck); + uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate - RATE_18M], bNeedAck); else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck); + uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate - RATE_18M], bNeedAck); break; diff --git a/drivers/staging/wfx/TODO b/drivers/staging/wfx/TODO index 42bf36d43970..1b4bc2af94b6 100644 --- a/drivers/staging/wfx/TODO +++ b/drivers/staging/wfx/TODO @@ -1,25 +1,6 @@ This is a list of things that need to be done to get this driver out of the staging directory. - - The HIF API is not yet clean enough. - - - The code that check the corectness of received message (in rx_helper()) can - be improved. See: - https://lore.kernel.org/driverdev-devel/2302785.6C7ODC2LYm@pc-42/ - - As suggested by Felix, rate control could be improved following this idea: https://lore.kernel.org/lkml/3099559.gv3Q75KnN1@pc-42/ - - Feature called "secure link" should be either developed (using kernel - crypto API) or dropped. - - - The device allows to filter multicast traffic. The code to support these - filters exists in the driver but it is disabled because it has never been - tested. - - - In wfx_cmd_send(), "async" allow to send command without waiting the reply. - It may help in some situation, but it is not yet used. In add, it may cause - some trouble: - https://lore.kernel.org/driverdev-devel/alpine.DEB.2.21.1910041317381.2992@hadrien/ - So, fix it (by replacing the mutex with a semaphore) or drop it. - diff --git a/drivers/staging/wfx/bh.c b/drivers/staging/wfx/bh.c index 53ae0b5abcdd..72da2f4af49f 100644 --- a/drivers/staging/wfx/bh.c +++ b/drivers/staging/wfx/bh.c @@ -12,31 +12,45 @@ #include "wfx.h" #include "hwio.h" #include "traces.h" -#include "secure_link.h" #include "hif_rx.h" #include "hif_api_cmd.h" static void device_wakeup(struct wfx_dev *wdev) { + int max_retry = 3; + if (!wdev->pdata.gpio_wakeup) return; if (gpiod_get_value_cansleep(wdev->pdata.gpio_wakeup)) return; - gpiod_set_value_cansleep(wdev->pdata.gpio_wakeup, 1); if (wfx_api_older_than(wdev, 1, 4)) { + gpiod_set_value_cansleep(wdev->pdata.gpio_wakeup, 1); if (!completion_done(&wdev->hif.ctrl_ready)) usleep_range(2000, 2500); - } else { + return; + } + for (;;) { + gpiod_set_value_cansleep(wdev->pdata.gpio_wakeup, 1); // completion.h does not provide any function to wait // completion without consume it (a kind of // wait_for_completion_done_timeout()). So we have to emulate // it. if (wait_for_completion_timeout(&wdev->hif.ctrl_ready, - msecs_to_jiffies(2) + 1)) + msecs_to_jiffies(2))) { complete(&wdev->hif.ctrl_ready); - else + return; + } else if (max_retry-- > 0) { + // Older firmwares have a race in sleep/wake-up process. + // Redo the process is sufficient to unfreeze the + // chip. dev_err(wdev->dev, "timeout while wake up chip\n"); + gpiod_set_value_cansleep(wdev->pdata.gpio_wakeup, 0); + usleep_range(2000, 2500); + } else { + dev_err(wdev->dev, "max wake-up retries reached\n"); + return; + } } } @@ -73,20 +87,11 @@ static int rx_helper(struct wfx_dev *wdev, size_t read_len, int *is_cnf) _trace_piggyback(piggyback, false); hif = (struct hif_msg *)skb->data; - WARN(hif->encrypted & 0x1, "unsupported encryption type"); - if (hif->encrypted == 0x2) { - if (WARN(read_len < sizeof(struct hif_sl_msg), "corrupted read")) - goto err; - computed_len = le16_to_cpu(((struct hif_sl_msg *)hif)->len); - computed_len = round_up(computed_len - sizeof(u16), 16); - computed_len += sizeof(struct hif_sl_msg); - computed_len += sizeof(struct hif_sl_tag); - } else { - if (WARN(read_len < sizeof(struct hif_msg), "corrupted read")) - goto err; - computed_len = le16_to_cpu(hif->len); - computed_len = round_up(computed_len, 2); - } + WARN(hif->encrypted & 0x3, "encryption is unsupported"); + if (WARN(read_len < sizeof(struct hif_msg), "corrupted read")) + goto err; + computed_len = le16_to_cpu(hif->len); + computed_len = round_up(computed_len, 2); if (computed_len != read_len) { dev_err(wdev->dev, "inconsistent message length: %zu != %zu\n", computed_len, read_len); @@ -94,16 +99,6 @@ static int rx_helper(struct wfx_dev *wdev, size_t read_len, int *is_cnf) hif, read_len, true); goto err; } - if (hif->encrypted == 0x2) { - if (wfx_sl_decode(wdev, (struct hif_sl_msg *)hif)) { - dev_kfree_skb(skb); - // If frame was a confirmation, expect trouble in next - // exchange. However, it is harmless to fail to decode - // an indication frame, so try to continue. Anyway, - // piggyback is probably correct. - return piggyback; - } - } if (!(hif->id & HIF_ID_IS_INDICATION)) { (*is_cnf)++; @@ -184,23 +179,7 @@ static void tx_helper(struct wfx_dev *wdev, struct hif_msg *hif) hif->seqnum = wdev->hif.tx_seqnum; wdev->hif.tx_seqnum = (wdev->hif.tx_seqnum + 1) % (HIF_COUNTER_MAX + 1); - if (wfx_is_secure_command(wdev, hif->id)) { - len = round_up(len - sizeof(hif->len), 16) + sizeof(hif->len) + - sizeof(struct hif_sl_msg_hdr) + - sizeof(struct hif_sl_tag); - // AES support encryption in-place. However, mac80211 access to - // 802.11 header after frame was sent (to get MAC addresses). - // So, keep origin buffer clear. - data = kmalloc(len, GFP_KERNEL); - if (!data) - goto end; - is_encrypted = true; - ret = wfx_sl_encode(wdev, hif, data); - if (ret) - goto end; - } else { - data = hif; - } + data = hif; WARN(len > wdev->hw_caps.size_inp_ch_buf, "%s: request exceed WFx capability: %zu > %d\n", __func__, len, wdev->hw_caps.size_inp_ch_buf); diff --git a/drivers/staging/wfx/data_rx.c b/drivers/staging/wfx/data_rx.c index 6fb078880742..fe111d0aab63 100644 --- a/drivers/staging/wfx/data_rx.c +++ b/drivers/staging/wfx/data_rx.c @@ -70,10 +70,10 @@ void wfx_rx_cb(struct wfx_vif *wvif, hdr->signal = arg->rcpi_rssi / 2 - 110; hdr->antenna = 0; - if (arg->rx_flags.encryp) + if (arg->encryp) hdr->flag |= RX_FLAG_DECRYPTED; - // Block ack negociation is offloaded by the firmware. However, + // Block ack negotiation is offloaded by the firmware. However, // re-ordering must be done by the mac80211. if (ieee80211_is_action(frame->frame_control) && mgmt->u.action.category == WLAN_CATEGORY_BACK && diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c index 3acf4eb0214d..e2fb770e98fc 100644 --- a/drivers/staging/wfx/data_tx.c +++ b/drivers/staging/wfx/data_tx.c @@ -234,7 +234,7 @@ static void wfx_tx_fixup_rates(struct ieee80211_tx_rate *rates) int i; bool finished; - // Firmware is not able to mix rates with differents flags + // Firmware is not able to mix rates with different flags for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { if (rates[0].flags & IEEE80211_TX_RC_SHORT_GI) rates[i].flags |= IEEE80211_TX_RC_SHORT_GI; @@ -300,23 +300,14 @@ static u8 wfx_tx_get_rate_id(struct wfx_vif *wvif, return rate_id; } -static struct hif_ht_tx_parameters wfx_tx_get_tx_parms(struct wfx_dev *wdev, - struct ieee80211_tx_info *tx_info) +static int wfx_tx_get_frame_format(struct ieee80211_tx_info *tx_info) { - struct ieee80211_tx_rate *rate = &tx_info->driver_rates[0]; - struct hif_ht_tx_parameters ret = { }; - - if (!(rate->flags & IEEE80211_TX_RC_MCS)) - ret.frame_format = HIF_FRAME_FORMAT_NON_HT; - else if (!(rate->flags & IEEE80211_TX_RC_GREEN_FIELD)) - ret.frame_format = HIF_FRAME_FORMAT_MIXED_FORMAT_HT; + if (!(tx_info->driver_rates[0].flags & IEEE80211_TX_RC_MCS)) + return HIF_FRAME_FORMAT_NON_HT; + else if (!(tx_info->driver_rates[0].flags & IEEE80211_TX_RC_GREEN_FIELD)) + return HIF_FRAME_FORMAT_MIXED_FORMAT_HT; else - ret.frame_format = HIF_FRAME_FORMAT_GF_HT_11N; - if (rate->flags & IEEE80211_TX_RC_SHORT_GI) - ret.short_gi = 1; - if (tx_info->flags & IEEE80211_TX_CTL_STBC) - ret.stbc = 0; // FIXME: Not yet supported by firmware? - return ret; + return HIF_FRAME_FORMAT_GF_HT_11N; } static int wfx_tx_get_icv_len(struct ieee80211_key_conf *hw_key) @@ -325,6 +316,8 @@ static int wfx_tx_get_icv_len(struct ieee80211_key_conf *hw_key) if (!hw_key) return 0; + if (hw_key->cipher == WLAN_CIPHER_SUITE_AES_CMAC) + return 0; mic_space = (hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) ? 8 : 0; return hw_key->icv_len + mic_space; } @@ -334,7 +327,6 @@ static int wfx_tx_inner(struct wfx_vif *wvif, struct ieee80211_sta *sta, { struct hif_msg *hif_msg; struct hif_req_tx *req; - struct wfx_tx_priv *tx_priv; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; @@ -348,15 +340,11 @@ static int wfx_tx_inner(struct wfx_vif *wvif, struct ieee80211_sta *sta, // From now tx_info->control is unusable memset(tx_info->rate_driver_data, 0, sizeof(struct wfx_tx_priv)); - // Fill tx_priv - tx_priv = (struct wfx_tx_priv *)tx_info->rate_driver_data; - if (ieee80211_has_protected(hdr->frame_control)) - tx_priv->hw_key = hw_key; // Fill hif_msg WARN(skb_headroom(skb) < wmsg_len, "not enough space in skb"); WARN(offset & 1, "attempt to transmit an unaligned frame"); - skb_put(skb, wfx_tx_get_icv_len(tx_priv->hw_key)); + skb_put(skb, wfx_tx_get_icv_len(hw_key)); skb_push(skb, wmsg_len); memset(skb->data, 0, wmsg_len); hif_msg = (struct hif_msg *)skb->data; @@ -380,14 +368,16 @@ static int wfx_tx_inner(struct wfx_vif *wvif, struct ieee80211_sta *sta, req->packet_id |= IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)) << 16; req->packet_id |= queue_id << 28; - req->data_flags.fc_offset = offset; + req->fc_offset = offset; if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) - req->data_flags.after_dtim = 1; - req->queue_id.peer_sta_id = wfx_tx_get_link_id(wvif, sta, hdr); + req->after_dtim = 1; + req->peer_sta_id = wfx_tx_get_link_id(wvif, sta, hdr); // Queue index are inverted between firmware and Linux - req->queue_id.queue_id = 3 - queue_id; - req->ht_tx_parameters = wfx_tx_get_tx_parms(wvif->wdev, tx_info); - req->tx_flags.retry_policy_index = wfx_tx_get_rate_id(wvif, tx_info); + req->queue_id = 3 - queue_id; + req->retry_policy_index = wfx_tx_get_rate_id(wvif, tx_info); + req->frame_format = wfx_tx_get_frame_format(tx_info); + if (tx_info->driver_rates[0].flags & IEEE80211_TX_RC_SHORT_GI) + req->short_gi = 1; // Auxiliary operations wfx_tx_queues_put(wvif, skb); @@ -439,10 +429,10 @@ static void wfx_skb_dtor(struct wfx_vif *wvif, struct sk_buff *skb) struct hif_req_tx *req = (struct hif_req_tx *)hif->body; unsigned int offset = sizeof(struct hif_msg) + sizeof(struct hif_req_tx) + - req->data_flags.fc_offset; + req->fc_offset; WARN_ON(!wvif); - wfx_tx_policy_put(wvif, req->tx_flags.retry_policy_index); + wfx_tx_policy_put(wvif, req->retry_policy_index); skb_pull(skb, offset); ieee80211_tx_status_irqsafe(wvif->wdev->hw, skb); } @@ -488,7 +478,6 @@ static void wfx_tx_fill_rates(struct wfx_dev *wdev, void wfx_tx_confirm_cb(struct wfx_dev *wdev, const struct hif_cnf_tx *arg) { struct ieee80211_tx_info *tx_info; - const struct wfx_tx_priv *tx_priv; struct wfx_vif *wvif; struct sk_buff *skb; @@ -498,18 +487,15 @@ void wfx_tx_confirm_cb(struct wfx_dev *wdev, const struct hif_cnf_tx *arg) arg->packet_id); return; } + tx_info = IEEE80211_SKB_CB(skb); wvif = wdev_to_wvif(wdev, ((struct hif_msg *)skb->data)->interface); WARN_ON(!wvif); if (!wvif) return; - tx_info = IEEE80211_SKB_CB(skb); - tx_priv = wfx_skb_tx_priv(skb); - _trace_tx_stats(arg, skb, wfx_pending_get_pkt_us_delay(wdev, skb)); - // You can touch to tx_priv, but don't touch to tx_info->status. + // Note that wfx_pending_get_pkt_us_delay() get data from tx_info + _trace_tx_stats(arg, skb, wfx_pending_get_pkt_us_delay(wdev, skb)); wfx_tx_fill_rates(wdev, tx_info, arg); - skb_trim(skb, skb->len - wfx_tx_get_icv_len(tx_priv->hw_key)); - // From now, you can touch to tx_info->status, but do not touch to // tx_priv anymore // FIXME: use ieee80211_tx_info_clear_status() @@ -525,8 +511,7 @@ void wfx_tx_confirm_cb(struct wfx_dev *wdev, const struct hif_cnf_tx *arg) else tx_info->flags |= IEEE80211_TX_STAT_ACK; } else if (arg->status == HIF_STATUS_TX_FAIL_REQUEUE) { - WARN(!arg->tx_result_flags.requeue, - "incoherent status and result_flags"); + WARN(!arg->requeue, "incoherent status and result_flags"); if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) { wvif->after_dtim_tx_allowed = false; // DTIM period elapsed schedule_work(&wvif->update_tim_work); diff --git a/drivers/staging/wfx/data_tx.h b/drivers/staging/wfx/data_tx.h index cff7b9ff99a9..87e1b9b62dbb 100644 --- a/drivers/staging/wfx/data_tx.h +++ b/drivers/staging/wfx/data_tx.h @@ -35,8 +35,7 @@ struct tx_policy_cache { struct wfx_tx_priv { ktime_t xmit_timestamp; - struct ieee80211_key_conf *hw_key; -} __packed; +}; void wfx_tx_policy_init(struct wfx_vif *wvif); void wfx_tx_policy_upload_work(struct work_struct *work); diff --git a/drivers/staging/wfx/debug.c b/drivers/staging/wfx/debug.c index 3f1712b7c919..ae44ffb66e34 100644 --- a/drivers/staging/wfx/debug.c +++ b/drivers/staging/wfx/debug.c @@ -32,7 +32,7 @@ static const struct trace_print_flags wfx_reg_print_map[] = { }; static const char *get_symbol(unsigned long val, - const struct trace_print_flags *symbol_array) + const struct trace_print_flags *symbol_array) { int i; @@ -267,7 +267,7 @@ static ssize_t wfx_send_hif_msg_write(struct file *file, if (count < sizeof(struct hif_msg)) return -EINVAL; - // wfx_cmd_send() chekc that reply buffer is wide enough, but do not + // wfx_cmd_send() checks that reply buffer is wide enough, but does not // return precise length read. User have to know how many bytes should // be read. Filling reply buffer with a memory pattern may help user. memset(context->reply, 0xFF, sizeof(context->reply)); @@ -299,8 +299,8 @@ static ssize_t wfx_send_hif_msg_read(struct file *file, char __user *user_buf, return ret; if (context->ret < 0) return context->ret; - // Be carefull, write() is waiting for a full message while read() - // only return a payload + // Be careful, write() is waiting for a full message while read() + // only returns a payload if (copy_to_user(user_buf, context->reply, count)) return -EFAULT; diff --git a/drivers/staging/wfx/hif_api_cmd.h b/drivers/staging/wfx/hif_api_cmd.h index 21cde19cff75..bdd468800189 100644 --- a/drivers/staging/wfx/hif_api_cmd.h +++ b/drivers/staging/wfx/hif_api_cmd.h @@ -8,9 +8,9 @@ #ifndef WFX_HIF_API_CMD_H #define WFX_HIF_API_CMD_H -#include "hif_api_general.h" +#include <linux/ieee80211.h> -#define HIF_API_SSID_SIZE API_SSID_SIZE +#include "hif_api_general.h" enum hif_requests_ids { HIF_REQ_ID_RESET = 0x0a, @@ -60,21 +60,15 @@ enum hif_indications_ids { HIF_IND_ID_EVENT = 0x85 }; -union hif_commands_ids { - enum hif_requests_ids request; - enum hif_confirmations_ids confirmation; - enum hif_indications_ids indication; -}; - -struct hif_reset_flags { +struct hif_req_reset { u8 reset_stat:1; u8 reset_all_int:1; u8 reserved1:6; u8 reserved2[3]; } __packed; -struct hif_req_reset { - struct hif_reset_flags reset_flags; +struct hif_cnf_reset { + __le32 status; } __packed; struct hif_req_read_mib { @@ -99,52 +93,23 @@ struct hif_cnf_write_mib { __le32 status; } __packed; -struct hif_ie_flags { +struct hif_req_update_ie { u8 beacon:1; u8 probe_resp:1; u8 probe_req:1; u8 reserved1:5; u8 reserved2; -} __packed; - -struct hif_ie_tlv { - u8 type; - u8 length; - u8 data[]; -} __packed; - -struct hif_req_update_ie { - struct hif_ie_flags ie_flags; __le16 num_ies; - struct hif_ie_tlv ie[]; + struct element ie[]; } __packed; struct hif_cnf_update_ie { __le32 status; } __packed; -struct hif_scan_type { - u8 type:1; - u8 mode:1; - u8 reserved:6; -} __packed; - -struct hif_scan_flags { - u8 fbg:1; - u8 reserved1:1; - u8 pre:1; - u8 reserved2:5; -} __packed; - -struct hif_auto_scan_param { - __le16 interval; - u8 reserved; - s8 rssi_thr; -} __packed; - struct hif_ssid_def { __le32 ssid_length; - u8 ssid[HIF_API_SSID_SIZE]; + u8 ssid[IEEE80211_MAX_SSID_LEN]; } __packed; #define HIF_API_MAX_NB_SSIDS 2 @@ -152,10 +117,17 @@ struct hif_ssid_def { struct hif_req_start_scan_alt { u8 band; - struct hif_scan_type scan_type; - struct hif_scan_flags scan_flags; + u8 maintain_current_bss:1; + u8 periodic:1; + u8 reserved1:6; + u8 disallow_ps:1; + u8 reserved2:1; + u8 short_preamble:1; + u8 reserved3:5; u8 max_transmit_rate; - struct hif_auto_scan_param auto_scan_param; + __le16 periodic_interval; + u8 reserved4; + s8 periodic_rssi_thr; u8 num_of_probe_requests; u8 probe_delay; u8 num_of_ssids; @@ -201,53 +173,32 @@ enum hif_frame_format { HIF_FRAME_FORMAT_GF_HT_11N = 0x2 }; -enum hif_stbc { - HIF_STBC_NOT_ALLOWED = 0x0, - HIF_STBC_ALLOWED = 0x1 -}; - -struct hif_queue { +struct hif_req_tx { + // packet_id is not interpreted by the device, so it is not necessary to + // declare it little endian + u32 packet_id; + u8 max_tx_rate; u8 queue_id:2; u8 peer_sta_id:4; - u8 reserved:2; -} __packed; - -struct hif_data_flags { + u8 reserved1:2; u8 more:1; u8 fc_offset:3; u8 after_dtim:1; - u8 reserved:3; -} __packed; - -struct hif_tx_flags { + u8 reserved2:3; u8 start_exp:1; - u8 reserved:3; + u8 reserved3:3; u8 retry_policy_index:4; -} __packed; - -struct hif_ht_tx_parameters { + __le32 reserved4; + __le32 expire_time; u8 frame_format:4; u8 fec_coding:1; u8 short_gi:1; - u8 reserved1:1; + u8 reserved5:1; u8 stbc:1; - u8 reserved2; + u8 reserved6; u8 aggregation:1; - u8 reserved3:7; - u8 reserved4; -} __packed; - -struct hif_req_tx { - // packet_id is not interpreted by the device, so it is not necessary to - // declare it little endian - u32 packet_id; - u8 max_tx_rate; - struct hif_queue queue_id; - struct hif_data_flags data_flags; - struct hif_tx_flags tx_flags; - __le32 reserved; - __le32 expire_time; - struct hif_ht_tx_parameters ht_tx_parameters; + u8 reserved7:7; + u8 reserved8; u8 frame[]; } __packed; @@ -258,15 +209,6 @@ enum hif_qos_ackplcy { HIF_QOS_ACKPLCY_BLCKACK = 0x3 }; -struct hif_tx_result_flags { - u8 aggr:1; - u8 requeue:1; - u8 ack_policy:2; - u8 txop_limit:1; - u8 reserved1:3; - u8 reserved2; -} __packed; - struct hif_cnf_tx { __le32 status; // packet_id is copied from struct hif_req_tx without been interpreted @@ -274,7 +216,12 @@ struct hif_cnf_tx { u32 packet_id; u8 txed_rate; u8 ack_failures; - struct hif_tx_result_flags tx_result_flags; + u8 aggr:1; + u8 requeue:1; + u8 ack_policy:2; + u8 txop_limit:1; + u8 reserved1:3; + u8 reserved2; __le32 media_delay; __le32 tx_queue_delay; } __packed; @@ -282,7 +229,7 @@ struct hif_cnf_tx { struct hif_cnf_multi_transmit { u8 num_tx_confs; u8 reserved[3]; - struct hif_cnf_tx tx_conf_payload[]; + struct hif_cnf_tx tx_conf_payload[]; } __packed; enum hif_ri_flags_encrypt { @@ -293,7 +240,12 @@ enum hif_ri_flags_encrypt { HIF_RI_FLAGS_WAPI_ENCRYPTED = 0x4 }; -struct hif_rx_flags { +struct hif_ind_rx { + __le32 status; + u8 channel_number; + u8 reserved1; + u8 rxed_rate; + u8 rcpi_rssi; u8 encryp:3; u8 in_aggr:1; u8 first_aggr:1; @@ -305,7 +257,7 @@ struct hif_rx_flags { u8 match_ssid:1; u8 match_bssid:1; u8 more:1; - u8 reserved1:1; + u8 reserved2:1; u8 ht:1; u8 stbc:1; u8 match_uc_addr:1; @@ -313,23 +265,13 @@ struct hif_rx_flags { u8 match_bc_addr:1; u8 key_type:1; u8 key_index:4; - u8 reserved2:1; + u8 reserved3:1; u8 peer_sta_id:4; - u8 reserved3:2; - u8 reserved4:1; -} __packed; - -struct hif_ind_rx { - __le32 status; - u8 channel_number; - u8 reserved; - u8 rxed_rate; - u8 rcpi_rssi; - struct hif_rx_flags rx_flags; + u8 reserved4:2; + u8 reserved5:1; u8 frame[]; } __packed; - struct hif_req_edca_queue_params { u8 queue_id; u8 reserved1; @@ -346,28 +288,24 @@ struct hif_cnf_edca_queue_params { __le32 status; } __packed; -struct hif_join_flags { - u8 reserved1:2; - u8 force_no_beacon:1; - u8 force_with_ind:1; - u8 reserved2:4; -} __packed; - struct hif_req_join { u8 infrastructure_bss_mode:1; u8 reserved1:7; u8 band; u8 channel_number; - u8 reserved; + u8 reserved2; u8 bssid[ETH_ALEN]; __le16 atim_window; u8 short_preamble:1; - u8 reserved2:7; + u8 reserved3:7; u8 probe_for_join; - u8 reserved3; - struct hif_join_flags join_flags; + u8 reserved4; + u8 reserved5:2; + u8 force_no_beacon:1; + u8 force_with_ind:1; + u8 reserved6:4; __le32 ssid_length; - u8 ssid[HIF_API_SSID_SIZE]; + u8 ssid[IEEE80211_MAX_SSID_LEN]; __le32 beacon_interval; __le32 basic_rate_set; } __packed; @@ -380,13 +318,9 @@ struct hif_ind_join_complete { __le32 status; } __packed; -struct hif_bss_flags { +struct hif_req_set_bss_params { u8 lost_count_only:1; u8 reserved:7; -} __packed; - -struct hif_req_set_bss_params { - struct hif_bss_flags bss_flags; u8 beacon_lost_count; __le16 aid; __le32 operational_rate_set; @@ -396,14 +330,10 @@ struct hif_cnf_set_bss_params { __le32 status; } __packed; -struct hif_pm_mode { +struct hif_req_set_pm_mode { u8 enter_psm:1; u8 reserved:6; u8 fast_psm:1; -} __packed; - -struct hif_req_set_pm_mode { - struct hif_pm_mode pm_mode; u8 fast_psm_idle_period; u8 ap_psm_change_period; u8 min_auto_ps_poll_period; @@ -419,7 +349,6 @@ struct hif_ind_set_pm_mode_cmpl { u8 reserved[3]; } __packed; - struct hif_req_start { u8 mode; u8 band; @@ -432,7 +361,7 @@ struct hif_req_start { u8 reserved3:7; u8 reserved4; u8 ssid_length; - u8 ssid[HIF_API_SSID_SIZE]; + u8 ssid[IEEE80211_MAX_SSID_LEN]; __le32 basic_rate_set; } __packed; @@ -440,11 +369,6 @@ struct hif_cnf_start { __le32 status; } __packed; -enum hif_beacon { - HIF_BEACON_STOP = 0x0, - HIF_BEACON_START = 0x1 -}; - struct hif_req_beacon_transmit { u8 enable_beaconing; u8 reserved[3]; @@ -457,20 +381,11 @@ struct hif_cnf_beacon_transmit { #define HIF_LINK_ID_MAX 14 #define HIF_LINK_ID_NOT_ASSOCIATED (HIF_LINK_ID_MAX + 1) -enum hif_sta_map_direction { - HIF_STA_MAP = 0x0, - HIF_STA_UNMAP = 0x1 -}; - -struct hif_map_link_flags { - u8 map_direction:1; - u8 mfpc:1; - u8 reserved:6; -} __packed; - struct hif_req_map_link { u8 mac_addr[ETH_ALEN]; - struct hif_map_link_flags map_link_flags; + u8 unmap:1; + u8 mfpc:1; + u8 reserved:6; u8 peer_sta_id; } __packed; @@ -478,16 +393,12 @@ struct hif_cnf_map_link { __le32 status; } __packed; -struct hif_suspend_resume_flags { +struct hif_ind_suspend_resume_tx { u8 resume:1; u8 reserved1:2; u8 bc_mc_only:1; u8 reserved2:4; u8 reserved3; -} __packed; - -struct hif_ind_suspend_resume_tx { - struct hif_suspend_resume_flags suspend_resume_flags; __le16 peer_sta_set; } __packed; @@ -582,25 +493,23 @@ struct hif_igtk_group_key { u8 ipn[HIF_API_IPN_SIZE]; } __packed; -union hif_privacy_key_data { - struct hif_wep_pairwise_key wep_pairwise_key; - struct hif_wep_group_key wep_group_key; - struct hif_tkip_pairwise_key tkip_pairwise_key; - struct hif_tkip_group_key tkip_group_key; - struct hif_aes_pairwise_key aes_pairwise_key; - struct hif_aes_group_key aes_group_key; - struct hif_wapi_pairwise_key wapi_pairwise_key; - struct hif_wapi_group_key wapi_group_key; - struct hif_igtk_group_key igtk_group_key; -}; - struct hif_req_add_key { u8 type; u8 entry_index; u8 int_id:2; u8 reserved1:6; u8 reserved2; - union hif_privacy_key_data key; + union { + struct hif_wep_pairwise_key wep_pairwise_key; + struct hif_wep_group_key wep_group_key; + struct hif_tkip_pairwise_key tkip_pairwise_key; + struct hif_tkip_group_key tkip_group_key; + struct hif_aes_pairwise_key aes_pairwise_key; + struct hif_aes_group_key aes_group_key; + struct hif_wapi_pairwise_key wapi_pairwise_key; + struct hif_wapi_group_key wapi_group_key; + struct hif_igtk_group_key igtk_group_key; + } key; } __packed; struct hif_cnf_add_key { @@ -632,16 +541,13 @@ enum hif_ps_mode_error { HIF_PS_ERROR_AP_NO_DATA_AFTER_TIM = 4 }; -union hif_event_data { - u8 rcpi_rssi; - __le32 ps_mode_error; - __le32 peer_sta_set; -}; - struct hif_ind_event { __le32 event_id; - union hif_event_data event_data; + union { + u8 rcpi_rssi; + __le32 ps_mode_error; + __le32 peer_sta_set; + } event_data; } __packed; - #endif diff --git a/drivers/staging/wfx/hif_api_general.h b/drivers/staging/wfx/hif_api_general.h index dba18a7ae919..9d522bc1aa69 100644 --- a/drivers/staging/wfx/hif_api_general.h +++ b/drivers/staging/wfx/hif_api_general.h @@ -17,8 +17,6 @@ #define __packed __attribute__((__packed__)) #endif -#define API_SSID_SIZE 32 - #define HIF_ID_IS_INDICATION 0x80 #define HIF_COUNTER_MAX 7 @@ -115,32 +113,12 @@ enum hif_api_rate_index { API_RATE_NUM_ENTRIES = 22 }; - enum hif_fw_type { HIF_FW_TYPE_ETF = 0x0, HIF_FW_TYPE_WFM = 0x1, HIF_FW_TYPE_WSM = 0x2 }; -struct hif_capabilities { - u8 link_mode:2; - u8 reserved1:6; - u8 reserved2; - u8 reserved3; - u8 reserved4; -} __packed; - -struct hif_otp_regul_sel_mode_info { - u8 region_sel_mode:4; - u8 reserved:4; -} __packed; - -struct hif_otp_phy_info { - u8 phy1_region:3; - u8 phy0_region:3; - u8 otp_phy_ver:2; -} __packed; - struct hif_ind_startup { // As the others, this struct is interpreted as little endian by the // device. However, this struct is also used by the driver. We prefer to @@ -156,14 +134,21 @@ struct hif_ind_startup { u8 mac_addr[2][ETH_ALEN]; u8 api_version_minor; u8 api_version_major; - struct hif_capabilities capabilities; + u8 link_mode:2; + u8 reserved1:6; + u8 reserved2; + u8 reserved3; + u8 reserved4; u8 firmware_build; u8 firmware_minor; u8 firmware_major; u8 firmware_type; u8 disabled_channel_list[2]; - struct hif_otp_regul_sel_mode_info regul_sel_mode_info; - struct hif_otp_phy_info otp_phy_info; + u8 region_sel_mode:4; + u8 reserved5:4; + u8 phy1_region:3; + u8 phy0_region:3; + u8 otp_phy_ver:2; u32 supported_rate_mask; u8 firmware_label[128]; } __packed; @@ -233,15 +218,12 @@ struct hif_tx_power_loop_info { u8 reserved; } __packed; -union hif_indication_data { - struct hif_rx_stats rx_stats; - struct hif_tx_power_loop_info tx_power_loop_info; - u8 raw_data[1]; -}; - struct hif_ind_generic { - __le32 indication_type; - union hif_indication_data indication_data; + __le32 type; + union { + struct hif_rx_stats rx_stats; + struct hif_tx_power_loop_info tx_power_loop_info; + } data; } __packed; enum hif_error { @@ -262,6 +244,7 @@ enum hif_error { HIF_ERROR_HIF_TX_QUEUE_FULL = 0x0d, HIF_ERROR_HIF_BUS = 0x0f, HIF_ERROR_PDS_TESTFEATURE = 0x10, + HIF_ERROR_SLK_UNCONFIGURED = 0x11, }; struct hif_ind_error { @@ -281,84 +264,4 @@ enum hif_secure_link_state { SEC_LINK_ENFORCED = 0x3 }; -enum hif_sl_encryption_type { - NO_ENCRYPTION = 0, - TX_ENCRYPTION = 1, - RX_ENCRYPTION = 2, - HP_ENCRYPTION = 3 -}; - -struct hif_sl_msg_hdr { - u32 seqnum:30; - u32 encrypted:2; -} __packed; - -struct hif_sl_msg { - struct hif_sl_msg_hdr hdr; - __le16 len; - u8 payload[]; -} __packed; - -#define AES_CCM_TAG_SIZE 16 - -struct hif_sl_tag { - u8 tag[16]; -} __packed; - -enum hif_sl_mac_key_dest { - SL_MAC_KEY_DEST_OTP = 0x78, - SL_MAC_KEY_DEST_RAM = 0x87 -}; - -#define API_KEY_VALUE_SIZE 32 - -struct hif_req_set_sl_mac_key { - u8 otp_or_ram; - u8 key_value[API_KEY_VALUE_SIZE]; -} __packed; - -struct hif_cnf_set_sl_mac_key { - __le32 status; -} __packed; - -enum hif_sl_session_key_alg { - HIF_SL_CURVE25519 = 0x01, - HIF_SL_KDF = 0x02 -}; - -#define API_HOST_PUB_KEY_SIZE 32 -#define API_HOST_PUB_KEY_MAC_SIZE 64 - -struct hif_req_sl_exchange_pub_keys { - u8 algorithm:2; - u8 reserved1:6; - u8 reserved2[3]; - u8 host_pub_key[API_HOST_PUB_KEY_SIZE]; - u8 host_pub_key_mac[API_HOST_PUB_KEY_MAC_SIZE]; -} __packed; - -struct hif_cnf_sl_exchange_pub_keys { - __le32 status; -} __packed; - -#define API_NCP_PUB_KEY_SIZE 32 -#define API_NCP_PUB_KEY_MAC_SIZE 64 - -struct hif_ind_sl_exchange_pub_keys { - __le32 status; - u8 ncp_pub_key[API_NCP_PUB_KEY_SIZE]; - u8 ncp_pub_key_mac[API_NCP_PUB_KEY_MAC_SIZE]; -} __packed; - -struct hif_req_sl_configure { - u8 encr_bmp[32]; - u8 disable_session_key_protection:1; - u8 reserved1:7; - u8 reserved2[3]; -} __packed; - -struct hif_cnf_sl_configure { - __le32 status; -} __packed; - #endif diff --git a/drivers/staging/wfx/hif_api_mib.h b/drivers/staging/wfx/hif_api_mib.h index 6f1434795fa8..55bd399ccdfb 100644 --- a/drivers/staging/wfx/hif_api_mib.h +++ b/drivers/staging/wfx/hif_api_mib.h @@ -82,50 +82,6 @@ struct hif_mib_gl_set_multi_msg { u8 reserved2[3]; } __packed; -enum hif_mac_addr_type { - HIF_MAC_ADDR_A1 = 0x0, - HIF_MAC_ADDR_A2 = 0x1, - HIF_MAC_ADDR_A3 = 0x2 -}; - -struct hif_mib_mac_addr_data_frame_condition { - u8 condition_idx; - u8 address_type; - u8 mac_address[ETH_ALEN]; -} __packed; - -#define HIF_FILTER_UNICAST 0x1 -#define HIF_FILTER_MULTICAST 0x2 -#define HIF_FILTER_BROADCAST 0x4 - -struct hif_mib_uc_mc_bc_data_frame_condition { - u8 condition_idx; - u8 allowed_frames; - u8 reserved[2]; -} __packed; - -struct hif_mib_config_data_filter { - u8 filter_idx; - u8 enable; - u8 reserved1[2]; - u8 eth_type_cond; - u8 port_cond; - u8 magic_cond; - u8 mac_cond; - u8 ipv4_cond; - u8 ipv6_cond; - u8 uc_mc_bc_cond; - u8 reserved2; -} __packed; - -struct hif_mib_set_data_filtering { - u8 invert_matching:1; - u8 reserved1:7; - u8 enable:1; - u8 reserved2:7; - u8 reserved3[2]; -} __packed; - enum hif_arp_ns_frame_treatment { HIF_ARP_NS_FILTERING_DISABLE = 0x0, HIF_ARP_NS_FILTERING_ENABLE = 0x1, @@ -349,7 +305,7 @@ struct hif_mib_set_uapsd_information { __le16 auto_trigger_step; } __packed; -struct hif_mib_tx_rate_retry_policy { +struct hif_tx_rate_retry_policy { u8 policy_index; u8 short_retry_count; u8 long_retry_count; @@ -368,7 +324,7 @@ struct hif_mib_tx_rate_retry_policy { struct hif_mib_set_tx_rate_retry_policy { u8 num_tx_rate_policies; u8 reserved[3]; - struct hif_mib_tx_rate_retry_policy tx_rate_retry_policy[]; + struct hif_tx_rate_retry_policy tx_rate_retry_policy[]; } __packed; struct hif_mib_protected_mgmt_policy { diff --git a/drivers/staging/wfx/hif_rx.c b/drivers/staging/wfx/hif_rx.c index cc7c0cf226ba..b40af86356f1 100644 --- a/drivers/staging/wfx/hif_rx.c +++ b/drivers/staging/wfx/hif_rx.c @@ -15,7 +15,6 @@ #include "bh.h" #include "sta.h" #include "data_rx.h" -#include "secure_link.h" #include "hif_api_cmd.h" static int hif_generic_confirm(struct wfx_dev *wdev, @@ -48,14 +47,7 @@ static int hif_generic_confirm(struct wfx_dev *wdev, } wdev->hif_cmd.ret = status; - if (!wdev->hif_cmd.async) { - complete(&wdev->hif_cmd.done); - } else { - wdev->hif_cmd.buf_send = NULL; - mutex_unlock(&wdev->hif_cmd.lock); - if (cmd != HIF_REQ_ID_SL_EXCHANGE_PUB_KEYS) - mutex_unlock(&wdev->hif_cmd.key_renew_lock); - } + complete(&wdev->hif_cmd.done); return status; } @@ -110,21 +102,6 @@ static int hif_wakeup_indication(struct wfx_dev *wdev, return 0; } -static int hif_keys_indication(struct wfx_dev *wdev, - const struct hif_msg *hif, const void *buf) -{ - const struct hif_ind_sl_exchange_pub_keys *body = buf; - u8 pubkey[API_NCP_PUB_KEY_SIZE]; - - // SL_PUB_KEY_EXCHANGE_STATUS_SUCCESS is used by legacy secure link - if (body->status && body->status != HIF_STATUS_SLK_NEGO_SUCCESS) - dev_warn(wdev->dev, "secure link negociation error\n"); - memcpy(pubkey, body->ncp_pub_key, sizeof(pubkey)); - memreverse(pubkey, sizeof(pubkey)); - wfx_sl_check_pubkey(wdev, pubkey, body->ncp_pub_key_mac); - return 0; -} - static int hif_receive_indication(struct wfx_dev *wdev, const struct hif_msg *hif, const void *buf, struct sk_buff *skb) @@ -221,16 +198,16 @@ static int hif_suspend_resume_indication(struct wfx_dev *wdev, struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface); const struct hif_ind_suspend_resume_tx *body = buf; - if (body->suspend_resume_flags.bc_mc_only) { + if (body->bc_mc_only) { WARN_ON(!wvif); - if (body->suspend_resume_flags.resume) + if (body->resume) wfx_suspend_resume_mc(wvif, STA_NOTIFY_AWAKE); else wfx_suspend_resume_mc(wvif, STA_NOTIFY_SLEEP); } else { WARN(body->peer_sta_set, "misunderstood indication"); WARN(hif->interface != 2, "misunderstood indication"); - if (body->suspend_resume_flags.resume) + if (body->resume) wfx_suspend_hot_dev(wdev, STA_NOTIFY_AWAKE); else wfx_suspend_hot_dev(wdev, STA_NOTIFY_SLEEP); @@ -243,29 +220,28 @@ static int hif_generic_indication(struct wfx_dev *wdev, const struct hif_msg *hif, const void *buf) { const struct hif_ind_generic *body = buf; - int type = le32_to_cpu(body->indication_type); + int type = le32_to_cpu(body->type); switch (type) { case HIF_GENERIC_INDICATION_TYPE_RAW: return 0; case HIF_GENERIC_INDICATION_TYPE_STRING: - dev_info(wdev->dev, "firmware says: %s\n", - (char *)body->indication_data.raw_data); + dev_info(wdev->dev, "firmware says: %s\n", (char *)&body->data); return 0; case HIF_GENERIC_INDICATION_TYPE_RX_STATS: mutex_lock(&wdev->rx_stats_lock); // Older firmware send a generic indication beside RxStats if (!wfx_api_older_than(wdev, 1, 4)) dev_info(wdev->dev, "Rx test ongoing. Temperature: %d°C\n", - body->indication_data.rx_stats.current_temp); - memcpy(&wdev->rx_stats, &body->indication_data.rx_stats, + body->data.rx_stats.current_temp); + memcpy(&wdev->rx_stats, &body->data.rx_stats, sizeof(wdev->rx_stats)); mutex_unlock(&wdev->rx_stats_lock); return 0; case HIF_GENERIC_INDICATION_TYPE_TX_POWER_LOOP_INFO: mutex_lock(&wdev->tx_power_loop_info_lock); memcpy(&wdev->tx_power_loop_info, - &body->indication_data.tx_power_loop_info, + &body->data.tx_power_loop_info, sizeof(wdev->tx_power_loop_info)); mutex_unlock(&wdev->tx_power_loop_info_lock); return 0; @@ -301,6 +277,8 @@ static const struct { "secure link overflow" }, { HIF_ERROR_SLK_WRONG_ENCRYPTION_STATE, "secure link messages list does not match message encryption" }, + { HIF_ERROR_SLK_UNCONFIGURED, + "secure link not yet configured" }, { HIF_ERROR_HIF_BUS_FREQUENCY_TOO_LOW, "bus clock is too slow (<1kHz)" }, { HIF_ERROR_HIF_RX_DATA_TOO_LARGE, @@ -378,7 +356,6 @@ static const struct { { HIF_IND_ID_SET_PM_MODE_CMPL, hif_pm_mode_complete_indication }, { HIF_IND_ID_SCAN_CMPL, hif_scan_complete_indication }, { HIF_IND_ID_SUSPEND_RESUME_TX, hif_suspend_resume_indication }, - { HIF_IND_ID_SL_EXCHANGE_PUB_KEYS, hif_keys_indication }, { HIF_IND_ID_EVENT, hif_event_indication }, { HIF_IND_ID_GENERIC, hif_generic_indication }, { HIF_IND_ID_ERROR, hif_error_indication }, diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c index 5110f9b93762..1bd7f773209c 100644 --- a/drivers/staging/wfx/hif_tx.c +++ b/drivers/staging/wfx/hif_tx.c @@ -20,7 +20,6 @@ void wfx_init_hif_cmd(struct wfx_hif_cmd *hif_cmd) init_completion(&hif_cmd->ready); init_completion(&hif_cmd->done); mutex_init(&hif_cmd->lock); - mutex_init(&hif_cmd->key_renew_lock); } static void wfx_fill_header(struct hif_msg *hif, int if_id, @@ -48,7 +47,7 @@ static void *wfx_alloc_hif(size_t body_len, struct hif_msg **hif) } int wfx_cmd_send(struct wfx_dev *wdev, struct hif_msg *request, - void *reply, size_t reply_len, bool async) + void *reply, size_t reply_len, bool no_reply) { const char *mib_name = ""; const char *mib_sep = ""; @@ -56,15 +55,10 @@ int wfx_cmd_send(struct wfx_dev *wdev, struct hif_msg *request, int vif = request->interface; int ret; - WARN(wdev->hif_cmd.buf_recv && wdev->hif_cmd.async, "API usage error"); - // Do not wait for any reply if chip is frozen if (wdev->chip_frozen) return -ETIMEDOUT; - if (cmd != HIF_REQ_ID_SL_EXCHANGE_PUB_KEYS) - mutex_lock(&wdev->hif_cmd.key_renew_lock); - mutex_lock(&wdev->hif_cmd.lock); WARN(wdev->hif_cmd.buf_send, "data locking error"); @@ -73,14 +67,18 @@ int wfx_cmd_send(struct wfx_dev *wdev, struct hif_msg *request, wdev->hif_cmd.buf_send = request; wdev->hif_cmd.buf_recv = reply; wdev->hif_cmd.len_recv = reply_len; - wdev->hif_cmd.async = async; complete(&wdev->hif_cmd.ready); wfx_bh_request_tx(wdev); - // NOTE: no timeout is catched async is enabled - if (async) + if (no_reply) { + // Chip won't reply. Give enough time to the wq to send the + // buffer. + msleep(100); + wdev->hif_cmd.buf_send = NULL; + mutex_unlock(&wdev->hif_cmd.lock); return 0; + } if (wdev->poll_irq) wfx_bh_poll_irq(wdev); @@ -118,36 +116,25 @@ int wfx_cmd_send(struct wfx_dev *wdev, struct hif_msg *request, "WSM request %s%s%s (%#.2x) on vif %d returned status %d\n", get_hif_name(cmd), mib_sep, mib_name, cmd, vif, ret); - if (cmd != HIF_REQ_ID_SL_EXCHANGE_PUB_KEYS) - mutex_unlock(&wdev->hif_cmd.key_renew_lock); return ret; } // This function is special. After HIF_REQ_ID_SHUT_DOWN, chip won't reply to any -// request anymore. We need to slightly hack struct wfx_hif_cmd for that job. Be -// carefull to only call this funcion during device unregister. +// request anymore. Obviously, only call this function during device unregister. int hif_shutdown(struct wfx_dev *wdev) { int ret; struct hif_msg *hif; - if (wdev->chip_frozen) - return 0; wfx_alloc_hif(0, &hif); if (!hif) return -ENOMEM; wfx_fill_header(hif, -1, HIF_REQ_ID_SHUT_DOWN, 0); ret = wfx_cmd_send(wdev, hif, NULL, 0, true); - // After this command, chip won't reply. Be sure to give enough time to - // bh to send buffer: - msleep(100); - wdev->hif_cmd.buf_send = NULL; if (wdev->pdata.gpio_wakeup) gpiod_set_value(wdev->pdata.gpio_wakeup, 0); else control_reg_write(wdev, 0); - mutex_unlock(&wdev->hif_cmd.lock); - mutex_unlock(&wdev->hif_cmd.key_renew_lock); kfree(hif); return ret; } @@ -177,7 +164,7 @@ int hif_reset(struct wfx_vif *wvif, bool reset_stat) if (!hif) return -ENOMEM; - body->reset_flags.reset_stat = reset_stat; + body->reset_stat = reset_stat; wfx_fill_header(hif, wvif->id, HIF_REQ_ID_RESET, sizeof(*body)); ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false); kfree(hif); @@ -252,8 +239,6 @@ int hif_scan(struct wfx_vif *wvif, struct cfg80211_scan_request *req, WARN(chan_num > HIF_API_MAX_NB_CHANNELS, "invalid params"); WARN(req->n_ssids > HIF_API_MAX_NB_SSIDS, "invalid params"); - compiletime_assert(IEEE80211_MAX_SSID_LEN == HIF_API_SSID_SIZE, - "API inconsistency"); if (!hif) return -ENOMEM; for (i = 0; i < req->n_ssids; i++) { @@ -263,9 +248,8 @@ int hif_scan(struct wfx_vif *wvif, struct cfg80211_scan_request *req, cpu_to_le32(req->ssids[i].ssid_len); } body->num_of_ssids = HIF_API_MAX_NB_SSIDS; - // Background scan is always a good idea - body->scan_type.type = 1; - body->scan_flags.fbg = 1; + body->maintain_current_bss = 1; + body->disallow_ps = 1; body->tx_power_level = cpu_to_le32(req->channels[chan_start_idx]->max_power); body->num_of_channels = chan_num; @@ -446,11 +430,11 @@ int hif_set_pm(struct wfx_vif *wvif, bool ps, int dynamic_ps_timeout) if (!hif) return -ENOMEM; if (ps) { - body->pm_mode.enter_psm = 1; + body->enter_psm = 1; // Firmware does not support more than 128ms body->fast_psm_idle_period = min(dynamic_ps_timeout * 2, 255); if (body->fast_psm_idle_period) - body->pm_mode.fast_psm = 1; + body->fast_psm = 1; } wfx_fill_header(hif, wvif->id, HIF_REQ_ID_SET_PM_MODE, sizeof(*body)); ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false); @@ -499,7 +483,7 @@ int hif_beacon_transmit(struct wfx_vif *wvif, bool enable) return ret; } -int hif_map_link(struct wfx_vif *wvif, u8 *mac_addr, int flags, int sta_id) +int hif_map_link(struct wfx_vif *wvif, bool unmap, u8 *mac_addr, int sta_id, bool mfp) { int ret; struct hif_msg *hif; @@ -509,7 +493,8 @@ int hif_map_link(struct wfx_vif *wvif, u8 *mac_addr, int flags, int sta_id) return -ENOMEM; if (mac_addr) ether_addr_copy(body->mac_addr, mac_addr); - body->map_link_flags = *(struct hif_map_link_flags *)&flags; + body->mfpc = mfp ? 1 : 0; + body->unmap = unmap ? 1 : 0; body->peer_sta_id = sta_id; wfx_fill_header(hif, wvif->id, HIF_REQ_ID_MAP_LINK, sizeof(*body)); ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false); @@ -526,7 +511,7 @@ int hif_update_ie_beacon(struct wfx_vif *wvif, const u8 *ies, size_t ies_len) if (!hif) return -ENOMEM; - body->ie_flags.beacon = 1; + body->beacon = 1; body->num_ies = cpu_to_le16(1); memcpy(body->ie, ies, ies_len); wfx_fill_header(hif, wvif->id, HIF_REQ_ID_UPDATE_IE, buf_len); @@ -534,62 +519,3 @@ int hif_update_ie_beacon(struct wfx_vif *wvif, const u8 *ies, size_t ies_len) kfree(hif); return ret; } - -int hif_sl_send_pub_keys(struct wfx_dev *wdev, - const u8 *pubkey, const u8 *pubkey_hmac) -{ - int ret; - struct hif_msg *hif; - struct hif_req_sl_exchange_pub_keys *body = wfx_alloc_hif(sizeof(*body), - &hif); - - if (!hif) - return -ENOMEM; - body->algorithm = HIF_SL_CURVE25519; - memcpy(body->host_pub_key, pubkey, sizeof(body->host_pub_key)); - memcpy(body->host_pub_key_mac, pubkey_hmac, - sizeof(body->host_pub_key_mac)); - wfx_fill_header(hif, -1, HIF_REQ_ID_SL_EXCHANGE_PUB_KEYS, - sizeof(*body)); - ret = wfx_cmd_send(wdev, hif, NULL, 0, false); - kfree(hif); - // Compatibility with legacy secure link - if (ret == le32_to_cpu(HIF_STATUS_SLK_NEGO_SUCCESS)) - ret = 0; - return ret; -} - -int hif_sl_config(struct wfx_dev *wdev, const unsigned long *bitmap) -{ - int ret; - struct hif_msg *hif; - struct hif_req_sl_configure *body = wfx_alloc_hif(sizeof(*body), &hif); - - if (!hif) - return -ENOMEM; - memcpy(body->encr_bmp, bitmap, sizeof(body->encr_bmp)); - wfx_fill_header(hif, -1, HIF_REQ_ID_SL_CONFIGURE, sizeof(*body)); - ret = wfx_cmd_send(wdev, hif, NULL, 0, false); - kfree(hif); - return ret; -} - -int hif_sl_set_mac_key(struct wfx_dev *wdev, const u8 *slk_key, int destination) -{ - int ret; - struct hif_msg *hif; - struct hif_req_set_sl_mac_key *body = wfx_alloc_hif(sizeof(*body), - &hif); - - if (!hif) - return -ENOMEM; - memcpy(body->key_value, slk_key, sizeof(body->key_value)); - body->otp_or_ram = destination; - wfx_fill_header(hif, -1, HIF_REQ_ID_SET_SL_MAC_KEY, sizeof(*body)); - ret = wfx_cmd_send(wdev, hif, NULL, 0, false); - kfree(hif); - // Compatibility with legacy secure link - if (ret == le32_to_cpu(HIF_STATUS_SLK_SET_KEY_SUCCESS)) - ret = 0; - return ret; -} diff --git a/drivers/staging/wfx/hif_tx.h b/drivers/staging/wfx/hif_tx.h index e1da28aef706..960d5f2fa41c 100644 --- a/drivers/staging/wfx/hif_tx.h +++ b/drivers/staging/wfx/hif_tx.h @@ -20,10 +20,8 @@ struct wfx_vif; struct wfx_hif_cmd { struct mutex lock; - struct mutex key_renew_lock; struct completion ready; struct completion done; - bool async; struct hif_msg *buf_send; void *buf_recv; size_t len_recv; @@ -55,12 +53,8 @@ int hif_set_edca_queue_params(struct wfx_vif *wvif, u16 queue, int hif_start(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf, const struct ieee80211_channel *channel); int hif_beacon_transmit(struct wfx_vif *wvif, bool enable); -int hif_map_link(struct wfx_vif *wvif, u8 *mac_addr, int flags, int sta_id); +int hif_map_link(struct wfx_vif *wvif, + bool unmap, u8 *mac_addr, int sta_id, bool mfp); int hif_update_ie_beacon(struct wfx_vif *wvif, const u8 *ies, size_t ies_len); -int hif_sl_set_mac_key(struct wfx_dev *wdev, - const u8 *slk_key, int destination); -int hif_sl_config(struct wfx_dev *wdev, const unsigned long *bitmap); -int hif_sl_send_pub_keys(struct wfx_dev *wdev, - const u8 *pubkey, const u8 *pubkey_hmac); #endif diff --git a/drivers/staging/wfx/hif_tx_mib.c b/drivers/staging/wfx/hif_tx_mib.c index 05f1e1e98af9..c375b9052a07 100644 --- a/drivers/staging/wfx/hif_tx_mib.c +++ b/drivers/staging/wfx/hif_tx_mib.c @@ -29,7 +29,7 @@ int hif_set_beacon_wakeup_period(struct wfx_vif *wvif, unsigned int dtim_interval, unsigned int listen_interval) { - struct hif_mib_beacon_wake_up_period val = { + struct hif_mib_beacon_wake_up_period arg = { .wakeup_period_min = dtim_interval, .receive_dtim = 0, .wakeup_period_max = listen_interval, @@ -39,7 +39,7 @@ int hif_set_beacon_wakeup_period(struct wfx_vif *wvif, return -EINVAL; return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_BEACON_WAKEUP_PERIOD, - &val, sizeof(val)); + &arg, sizeof(arg)); } int hif_set_rcpi_rssi_threshold(struct wfx_vif *wvif, @@ -92,31 +92,31 @@ int hif_set_macaddr(struct wfx_vif *wvif, u8 *mac) int hif_set_rx_filter(struct wfx_vif *wvif, bool filter_bssid, bool filter_prbreq) { - struct hif_mib_rx_filter val = { }; + struct hif_mib_rx_filter arg = { }; if (filter_bssid) - val.bssid_filter = 1; + arg.bssid_filter = 1; if (!filter_prbreq) - val.fwd_probe_req = 1; + arg.fwd_probe_req = 1; return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_RX_FILTER, - &val, sizeof(val)); + &arg, sizeof(arg)); } int hif_set_beacon_filter_table(struct wfx_vif *wvif, int tbl_len, const struct hif_ie_table_entry *tbl) { int ret; - struct hif_mib_bcn_filter_table *val; - int buf_len = struct_size(val, ie_table, tbl_len); + struct hif_mib_bcn_filter_table *arg; + int buf_len = struct_size(arg, ie_table, tbl_len); - val = kzalloc(buf_len, GFP_KERNEL); - if (!val) + arg = kzalloc(buf_len, GFP_KERNEL); + if (!arg) return -ENOMEM; - val->num_of_info_elmts = cpu_to_le32(tbl_len); - memcpy(val->ie_table, tbl, flex_array_size(val, ie_table, tbl_len)); + arg->num_of_info_elmts = cpu_to_le32(tbl_len); + memcpy(arg->ie_table, tbl, flex_array_size(arg, ie_table, tbl_len)); ret = hif_write_mib(wvif->wdev, wvif->id, - HIF_MIB_ID_BEACON_FILTER_TABLE, val, buf_len); - kfree(val); + HIF_MIB_ID_BEACON_FILTER_TABLE, arg, buf_len); + kfree(arg); return ret; } @@ -134,13 +134,13 @@ int hif_beacon_filter_control(struct wfx_vif *wvif, int hif_set_operational_mode(struct wfx_dev *wdev, enum hif_op_power_mode mode) { - struct hif_mib_gl_operational_power_mode val = { + struct hif_mib_gl_operational_power_mode arg = { .power_mode = mode, .wup_ind_activation = 1, }; return hif_write_mib(wdev, -1, HIF_MIB_ID_GL_OPERATIONAL_POWER_MODE, - &val, sizeof(val)); + &arg, sizeof(arg)); } int hif_set_template_frame(struct wfx_vif *wvif, struct sk_buff *skb, @@ -161,57 +161,46 @@ int hif_set_template_frame(struct wfx_vif *wvif, struct sk_buff *skb, int hif_set_mfp(struct wfx_vif *wvif, bool capable, bool required) { - struct hif_mib_protected_mgmt_policy val = { }; + struct hif_mib_protected_mgmt_policy arg = { }; WARN(required && !capable, "incoherent arguments"); if (capable) { - val.pmf_enable = 1; - val.host_enc_auth_frames = 1; + arg.pmf_enable = 1; + arg.host_enc_auth_frames = 1; } if (!required) - val.unpmf_allowed = 1; + arg.unpmf_allowed = 1; return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_PROTECTED_MGMT_POLICY, - &val, sizeof(val)); + &arg, sizeof(arg)); } int hif_set_block_ack_policy(struct wfx_vif *wvif, u8 tx_tid_policy, u8 rx_tid_policy) { - struct hif_mib_block_ack_policy val = { + struct hif_mib_block_ack_policy arg = { .block_ack_tx_tid_policy = tx_tid_policy, .block_ack_rx_tid_policy = rx_tid_policy, }; return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_BLOCK_ACK_POLICY, - &val, sizeof(val)); + &arg, sizeof(arg)); } -int hif_set_association_mode(struct wfx_vif *wvif, - struct ieee80211_bss_conf *info) +int hif_set_association_mode(struct wfx_vif *wvif, int ampdu_density, + bool greenfield, bool short_preamble) { - struct ieee80211_sta *sta = NULL; - struct hif_mib_set_association_mode val = { + struct hif_mib_set_association_mode arg = { .preambtype_use = 1, .mode = 1, .spacing = 1, - .short_preamble = info->use_short_preamble, + .short_preamble = short_preamble, + .greenfield = greenfield, + .mpdu_start_spacing = ampdu_density, }; - rcu_read_lock(); // protect sta - if (info->bssid && !info->ibss_joined) - sta = ieee80211_find_sta(wvif->vif, info->bssid); - - // FIXME: it is strange to not retrieve all information from bss_info - if (sta && sta->ht_cap.ht_supported) { - val.mpdu_start_spacing = sta->ht_cap.ampdu_density; - if (!(info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)) - val.greenfield = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD); - } - rcu_read_unlock(); - return hif_write_mib(wvif->wdev, wvif->id, - HIF_MIB_ID_SET_ASSOCIATION_MODE, &val, sizeof(val)); + HIF_MIB_ID_SET_ASSOCIATION_MODE, &arg, sizeof(arg)); } int hif_set_tx_rate_retry_policy(struct wfx_vif *wvif, @@ -239,57 +228,6 @@ int hif_set_tx_rate_retry_policy(struct wfx_vif *wvif, return ret; } -int hif_set_mac_addr_condition(struct wfx_vif *wvif, - int idx, const u8 *mac_addr) -{ - struct hif_mib_mac_addr_data_frame_condition val = { - .condition_idx = idx, - .address_type = HIF_MAC_ADDR_A1, - }; - - ether_addr_copy(val.mac_address, mac_addr); - return hif_write_mib(wvif->wdev, wvif->id, - HIF_MIB_ID_MAC_ADDR_DATAFRAME_CONDITION, - &val, sizeof(val)); -} - -int hif_set_uc_mc_bc_condition(struct wfx_vif *wvif, int idx, u8 allowed_frames) -{ - struct hif_mib_uc_mc_bc_data_frame_condition val = { - .condition_idx = idx, - .allowed_frames = allowed_frames, - }; - - return hif_write_mib(wvif->wdev, wvif->id, - HIF_MIB_ID_UC_MC_BC_DATAFRAME_CONDITION, - &val, sizeof(val)); -} - -int hif_set_config_data_filter(struct wfx_vif *wvif, bool enable, int idx, - int mac_filters, int frames_types_filters) -{ - struct hif_mib_config_data_filter val = { - .enable = enable, - .filter_idx = idx, - .mac_cond = mac_filters, - .uc_mc_bc_cond = frames_types_filters, - }; - - return hif_write_mib(wvif->wdev, wvif->id, - HIF_MIB_ID_CONFIG_DATA_FILTER, &val, sizeof(val)); -} - -int hif_set_data_filtering(struct wfx_vif *wvif, bool enable, bool invert) -{ - struct hif_mib_set_data_filtering val = { - .enable = enable, - .invert_matching = invert, - }; - - return hif_write_mib(wvif->wdev, wvif->id, - HIF_MIB_ID_SET_DATA_FILTERING, &val, sizeof(val)); -} - int hif_keep_alive_period(struct wfx_vif *wvif, int period) { struct hif_mib_keep_alive_period arg = { diff --git a/drivers/staging/wfx/hif_tx_mib.h b/drivers/staging/wfx/hif_tx_mib.h index 86683de7de7c..6c25015173cd 100644 --- a/drivers/staging/wfx/hif_tx_mib.h +++ b/drivers/staging/wfx/hif_tx_mib.h @@ -33,17 +33,10 @@ int hif_set_template_frame(struct wfx_vif *wvif, struct sk_buff *skb, int hif_set_mfp(struct wfx_vif *wvif, bool capable, bool required); int hif_set_block_ack_policy(struct wfx_vif *wvif, u8 tx_tid_policy, u8 rx_tid_policy); -int hif_set_association_mode(struct wfx_vif *wvif, - struct ieee80211_bss_conf *info); +int hif_set_association_mode(struct wfx_vif *wvif, int ampdu_density, + bool greenfield, bool short_preamble); int hif_set_tx_rate_retry_policy(struct wfx_vif *wvif, int policy_index, u8 *rates); -int hif_set_mac_addr_condition(struct wfx_vif *wvif, - int idx, const u8 *mac_addr); -int hif_set_uc_mc_bc_condition(struct wfx_vif *wvif, - int idx, u8 allowed_frames); -int hif_set_config_data_filter(struct wfx_vif *wvif, bool enable, int idx, - int mac_filters, int frames_types_filters); -int hif_set_data_filtering(struct wfx_vif *wvif, bool enable, bool invert); int hif_keep_alive_period(struct wfx_vif *wvif, int period); int hif_set_arp_ipv4_filter(struct wfx_vif *wvif, int idx, __be32 *addr); int hif_use_multi_tx_conf(struct wfx_dev *wdev, bool enable); diff --git a/drivers/staging/wfx/key.c b/drivers/staging/wfx/key.c index 5ee2ffc5f935..728e5f8d3b7c 100644 --- a/drivers/staging/wfx/key.c +++ b/drivers/staging/wfx/key.c @@ -171,7 +171,7 @@ static int wfx_add_key(struct wfx_vif *wvif, struct ieee80211_sta *sta, k.int_id = wvif->id; k.entry_index = idx; if (key->cipher == WLAN_CIPHER_SUITE_WEP40 || - key->cipher == WLAN_CIPHER_SUITE_WEP104) { + key->cipher == WLAN_CIPHER_SUITE_WEP104) { if (pairwise) k.type = fill_wep_pair(&k.key.wep_pairwise_key, key, sta->addr); @@ -191,15 +191,15 @@ static int wfx_add_key(struct wfx_vif *wvif, struct ieee80211_sta *sta, else k.type = fill_ccmp_group(&k.key.aes_group_key, key, &seq); - } else if (key->cipher == WLAN_CIPHER_SUITE_SMS4) { + } else if (key->cipher == WLAN_CIPHER_SUITE_SMS4) { if (pairwise) k.type = fill_sms4_pair(&k.key.wapi_pairwise_key, key, sta->addr); else k.type = fill_sms4_group(&k.key.wapi_group_key, key); - } else if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC) { - k.type = fill_aes_cmac_group(&k.key.igtk_group_key, key, - &seq); + } else if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC) { + k.type = fill_aes_cmac_group(&k.key.igtk_group_key, key, &seq); + key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIE; } else { dev_warn(wdev->dev, "unsupported key type %d\n", key->cipher); wfx_free_key(wdev, idx); diff --git a/drivers/staging/wfx/main.c b/drivers/staging/wfx/main.c index 11dfa088fc86..2a9098bad1f5 100644 --- a/drivers/staging/wfx/main.c +++ b/drivers/staging/wfx/main.c @@ -30,7 +30,6 @@ #include "scan.h" #include "debug.h" #include "data_tx.h" -#include "secure_link.h" #include "hif_tx_mib.h" #include "hif_api_cmd.h" @@ -143,7 +142,6 @@ static const struct ieee80211_ops wfx_ops = { .set_rts_threshold = wfx_set_rts_threshold, .set_default_unicast_key = wfx_set_default_unicast_key, .bss_info_changed = wfx_bss_info_changed, - .prepare_multicast = wfx_prepare_multicast, .configure_filter = wfx_configure_filter, .ampdu_action = wfx_ampdu_action, .flush = wfx_flush, @@ -271,8 +269,7 @@ struct wfx_dev *wfx_init_common(struct device *dev, hw->queues = 4; hw->max_rates = 8; hw->max_rate_tries = 8; - hw->extra_tx_headroom = sizeof(struct hif_sl_msg_hdr) + - sizeof(struct hif_msg) + hw->extra_tx_headroom = sizeof(struct hif_msg) + sizeof(struct hif_req_tx) + 4 /* alignment */ + 8 /* TKIP IV */; hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | @@ -282,9 +279,9 @@ struct wfx_dev *wfx_init_common(struct device *dev, NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U; + hw->wiphy->features |= NL80211_FEATURE_AP_SCAN; hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD; - hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; hw->wiphy->max_ap_assoc_sta = HIF_LINK_ID_MAX; hw->wiphy->max_scan_ssids = 2; hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; @@ -309,7 +306,6 @@ struct wfx_dev *wfx_init_common(struct device *dev, return ERR_CAST(wdev->pdata.gpio_wakeup); if (wdev->pdata.gpio_wakeup) gpiod_set_consumer_name(wdev->pdata.gpio_wakeup, "wfx wakeup"); - wfx_sl_fill_pdata(dev, &wdev->pdata); mutex_init(&wdev->conf_mutex); mutex_init(&wdev->rx_stats_lock); @@ -363,9 +359,8 @@ int wfx_probe(struct wfx_dev *wdev) dev_info(wdev->dev, "started firmware %d.%d.%d \"%s\" (API: %d.%d, keyset: %02X, caps: 0x%.8X)\n", wdev->hw_caps.firmware_major, wdev->hw_caps.firmware_minor, wdev->hw_caps.firmware_build, wdev->hw_caps.firmware_label, - wdev->hw_caps.api_version_major, - wdev->hw_caps.api_version_minor, - wdev->keyset, *((u32 *)&wdev->hw_caps.capabilities)); + wdev->hw_caps.api_version_major, wdev->hw_caps.api_version_minor, + wdev->keyset, wdev->hw_caps.link_mode); snprintf(wdev->hw->wiphy->fw_version, sizeof(wdev->hw->wiphy->fw_version), "%d.%d.%d", @@ -381,14 +376,13 @@ int wfx_probe(struct wfx_dev *wdev) goto err0; } - err = wfx_sl_init(wdev); - if (err && wdev->hw_caps.capabilities.link_mode == SEC_LINK_ENFORCED) { + if (wdev->hw_caps.link_mode == SEC_LINK_ENFORCED) { dev_err(wdev->dev, - "chip require secure_link, but can't negociate it\n"); + "chip require secure_link, but can't negotiate it\n"); goto err0; } - if (wdev->hw_caps.regul_sel_mode_info.region_sel_mode) { + if (wdev->hw_caps.region_sel_mode) { wdev->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[11].flags |= IEEE80211_CHAN_NO_IR; wdev->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[12].flags |= IEEE80211_CHAN_NO_IR; wdev->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[13].flags |= IEEE80211_CHAN_DISABLED; @@ -466,7 +460,6 @@ void wfx_release(struct wfx_dev *wdev) hif_shutdown(wdev); wdev->hwbus_ops->irq_unsubscribe(wdev->hwbus_priv); wfx_bh_unregister(wdev); - wfx_sl_deinit(wdev); } static int __init wfx_core_init(void) diff --git a/drivers/staging/wfx/main.h b/drivers/staging/wfx/main.h index c59d375dd3ad..2457cb595b0f 100644 --- a/drivers/staging/wfx/main.h +++ b/drivers/staging/wfx/main.h @@ -19,7 +19,7 @@ struct wfx_dev; struct hwbus_ops; struct wfx_platform_data { - /* Keyset and ".sec" extention will appended to this string */ + /* Keyset and ".sec" extension will be appended to this string */ const char *file_fw; const char *file_pds; struct gpio_desc *gpio_wakeup; diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index e9de19784865..02d4e653d594 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -113,10 +113,6 @@ int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; WARN_ON(hw_req->req.n_channels > HIF_API_MAX_NB_CHANNELS); - - if (vif->type == NL80211_IFTYPE_AP) - return -EOPNOTSUPP; - wvif->scan_req = hw_req; schedule_work(&wvif->scan_work); return 0; diff --git a/drivers/staging/wfx/secure_link.h b/drivers/staging/wfx/secure_link.h deleted file mode 100644 index c3d055b2f8b1..000000000000 --- a/drivers/staging/wfx/secure_link.h +++ /dev/null @@ -1,59 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2019, Silicon Laboratories, Inc. - */ -#ifndef WFX_SECURE_LINK_H -#define WFX_SECURE_LINK_H - -#include <linux/of.h> - -#include "hif_api_general.h" - -struct wfx_dev; - - -struct sl_context { -}; - -static inline bool wfx_is_secure_command(struct wfx_dev *wdev, int cmd_id) -{ - return false; -} - -static inline int wfx_sl_decode(struct wfx_dev *wdev, struct hif_sl_msg *m) -{ - return -EIO; -} - -static inline int wfx_sl_encode(struct wfx_dev *wdev, - const struct hif_msg *input, - struct hif_sl_msg *output) -{ - return -EIO; -} - -static inline int wfx_sl_check_pubkey(struct wfx_dev *wdev, - const u8 *ncp_pubkey, - const u8 *ncp_pubmac) -{ - return -EIO; -} - -static inline void wfx_sl_fill_pdata(struct device *dev, - struct wfx_platform_data *pdata) -{ - if (of_find_property(dev->of_node, "slk_key", NULL)) - dev_err(dev, "secure link is not supported by this driver, ignoring provided key\n"); -} - -static inline int wfx_sl_init(struct wfx_dev *wdev) -{ - return -EIO; -} - -static inline void wfx_sl_deinit(struct wfx_dev *wdev) -{ -} - - -#endif diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 4e30ab17a93d..0d27ca27e48c 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -91,59 +91,12 @@ static void wfx_filter_beacon(struct wfx_vif *wvif, bool filter_beacon) } } -static void wfx_filter_mcast(struct wfx_vif *wvif, bool filter_mcast) -{ - int i; - - // Temporary workaround for filters - hif_set_data_filtering(wvif, false, true); - return; - - if (!filter_mcast) { - hif_set_data_filtering(wvif, false, true); - return; - } - for (i = 0; i < wvif->filter_mcast_count; i++) - hif_set_mac_addr_condition(wvif, i, wvif->filter_mcast_addr[i]); - hif_set_uc_mc_bc_condition(wvif, 0, - HIF_FILTER_UNICAST | HIF_FILTER_BROADCAST); - hif_set_config_data_filter(wvif, true, 0, BIT(1), - BIT(wvif->filter_mcast_count) - 1); - hif_set_data_filtering(wvif, true, true); -} - -u64 wfx_prepare_multicast(struct ieee80211_hw *hw, - struct netdev_hw_addr_list *mc_list) -{ - int i; - struct netdev_hw_addr *ha; - struct wfx_vif *wvif = NULL; - struct wfx_dev *wdev = hw->priv; - int count = netdev_hw_addr_list_count(mc_list); - - while ((wvif = wvif_iterate(wdev, wvif)) != NULL) { - if (count > ARRAY_SIZE(wvif->filter_mcast_addr)) { - wvif->filter_mcast_count = 0; - continue; - } - wvif->filter_mcast_count = count; - - i = 0; - netdev_hw_addr_list_for_each(ha, mc_list) { - ether_addr_copy(wvif->filter_mcast_addr[i], ha->addr); - i++; - } - } - - return 0; -} - void wfx_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, unsigned int *total_flags, u64 unused) { struct wfx_vif *wvif = NULL; struct wfx_dev *wdev = hw->priv; - bool filter_bssid, filter_prbreq, filter_beacon, filter_mcast; + bool filter_bssid, filter_prbreq, filter_beacon; // Notes: // - Probe responses (FIF_BCN_PRBRESP_PROMISC) are never filtered @@ -167,16 +120,6 @@ void wfx_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, filter_beacon = true; wfx_filter_beacon(wvif, filter_beacon); - if (*total_flags & FIF_ALLMULTI) { - filter_mcast = false; - } else if (!wvif->filter_mcast_count) { - dev_dbg(wdev->dev, "disabling unconfigured multicast filter"); - filter_mcast = false; - } else { - filter_mcast = true; - } - wfx_filter_mcast(wvif, filter_mcast); - if (*total_flags & FIF_OTHER_BSS) filter_bssid = false; else @@ -214,7 +157,7 @@ static int wfx_get_ps_timeout(struct wfx_vif *wvif, bool *enable_ps) if (chan0 && chan1 && chan0->hw_value != chan1->hw_value && wvif->vif->type != NL80211_IFTYPE_AP) { // It is necessary to enable powersave if channels - // are differents. + // are different. if (enable_ps) *enable_ps = true; if (wvif->wdev->force_ps_timeout > -1) @@ -323,36 +266,6 @@ void wfx_set_default_unicast_key(struct ieee80211_hw *hw, hif_wep_default_key_id(wvif, idx); } -static void wfx_set_mfp(struct wfx_vif *wvif, - struct cfg80211_bss *bss) -{ - const int pairwise_cipher_suite_count_offset = 8 / sizeof(u16); - const int pairwise_cipher_suite_size = 4 / sizeof(u16); - const int akm_suite_size = 4 / sizeof(u16); - const u16 *ptr = NULL; - bool mfpc = false; - bool mfpr = false; - - /* 802.11w protected mgmt frames */ - - /* retrieve MFPC and MFPR flags from beacon or PBRSP */ - - rcu_read_lock(); - if (bss) - ptr = (const u16 *)ieee80211_bss_get_ie(bss, WLAN_EID_RSN); - - if (ptr) { - ptr += pairwise_cipher_suite_count_offset; - ptr += 1 + pairwise_cipher_suite_size * *ptr; - ptr += 1 + akm_suite_size * *ptr; - mfpr = *ptr & BIT(6); - mfpc = *ptr & BIT(7); - } - rcu_read_unlock(); - - hif_set_mfp(wvif, mfpc, mfpr); -} - void wfx_reset(struct wfx_vif *wvif) { struct wfx_dev *wdev = wvif->wdev; @@ -370,55 +283,6 @@ void wfx_reset(struct wfx_vif *wvif) wfx_update_pm(wvif); } -static void wfx_do_join(struct wfx_vif *wvif) -{ - int ret; - struct ieee80211_bss_conf *conf = &wvif->vif->bss_conf; - struct cfg80211_bss *bss = NULL; - u8 ssid[IEEE80211_MAX_SSID_LEN]; - const u8 *ssidie = NULL; - int ssidlen = 0; - - wfx_tx_lock_flush(wvif->wdev); - - bss = cfg80211_get_bss(wvif->wdev->hw->wiphy, wvif->channel, - conf->bssid, NULL, 0, - IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY); - if (!bss && !conf->ibss_joined) { - wfx_tx_unlock(wvif->wdev); - return; - } - - rcu_read_lock(); // protect ssidie - if (bss) - ssidie = ieee80211_bss_get_ie(bss, WLAN_EID_SSID); - if (ssidie) { - ssidlen = ssidie[1]; - if (ssidlen > IEEE80211_MAX_SSID_LEN) - ssidlen = IEEE80211_MAX_SSID_LEN; - memcpy(ssid, &ssidie[2], ssidlen); - } - rcu_read_unlock(); - - wfx_set_mfp(wvif, bss); - cfg80211_put_bss(wvif->wdev->hw->wiphy, bss); - - wvif->join_in_progress = true; - ret = hif_join(wvif, conf, wvif->channel, ssid, ssidlen); - if (ret) { - ieee80211_connection_loss(wvif->vif); - wfx_reset(wvif); - } else { - /* Due to beacon filtering it is possible that the - * AP's beacon is not known for the mac80211 stack. - * Disable filtering temporary to make sure the stack - * receives at least one - */ - wfx_filter_beacon(wvif, false); - } - wfx_tx_unlock(wvif->wdev); -} - int wfx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { @@ -427,6 +291,9 @@ int wfx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, sta_priv->vif_id = wvif->id; + if (vif->type == NL80211_IFTYPE_STATION) + hif_set_mfp(wvif, sta->mfp, sta->mfp); + // In station mode, the firmware interprets new link-id as a TDLS peer. if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) return 0; @@ -434,7 +301,7 @@ int wfx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, wvif->link_id_map |= BIT(sta_priv->link_id); WARN_ON(!sta_priv->link_id); WARN_ON(sta_priv->link_id >= HIF_LINK_ID_MAX); - hif_map_link(wvif, sta->addr, 0, sta_priv->link_id); + hif_map_link(wvif, false, sta->addr, sta_priv->link_id, sta->mfp); return 0; } @@ -449,7 +316,7 @@ int wfx_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (!sta_priv->link_id) return 0; // FIXME add a mutex? - hif_map_link(wvif, sta->addr, 1, sta_priv->link_id); + hif_map_link(wvif, true, sta->addr, sta_priv->link_id, false); wvif->link_id_map &= ~BIT(sta_priv->link_id); return 0; } @@ -474,6 +341,31 @@ static int wfx_upload_ap_templates(struct wfx_vif *wvif) return 0; } +static void wfx_set_mfp_ap(struct wfx_vif *wvif) +{ + struct sk_buff *skb = ieee80211_beacon_get(wvif->wdev->hw, wvif->vif); + const int ieoffset = offsetof(struct ieee80211_mgmt, u.beacon.variable); + const u16 *ptr = (u16 *)cfg80211_find_ie(WLAN_EID_RSN, + skb->data + ieoffset, + skb->len - ieoffset); + const int pairwise_cipher_suite_count_offset = 8 / sizeof(u16); + const int pairwise_cipher_suite_size = 4 / sizeof(u16); + const int akm_suite_size = 4 / sizeof(u16); + + if (ptr) { + ptr += pairwise_cipher_suite_count_offset; + if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb))) + return; + ptr += 1 + pairwise_cipher_suite_size * *ptr; + if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb))) + return; + ptr += 1 + akm_suite_size * *ptr; + if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb))) + return; + hif_set_mfp(wvif, *ptr & BIT(7), *ptr & BIT(6)); + } +} + int wfx_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; @@ -488,6 +380,7 @@ int wfx_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) ret = hif_start(wvif, &vif->bss_conf, wvif->channel); if (ret > 0) return -EIO; + wfx_set_mfp_ap(wvif); return ret; } @@ -498,11 +391,74 @@ void wfx_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) wfx_reset(wvif); } +static void wfx_join(struct wfx_vif *wvif) +{ + int ret; + struct ieee80211_bss_conf *conf = &wvif->vif->bss_conf; + struct cfg80211_bss *bss = NULL; + u8 ssid[IEEE80211_MAX_SSID_LEN]; + const u8 *ssidie = NULL; + int ssidlen = 0; + + wfx_tx_lock_flush(wvif->wdev); + + bss = cfg80211_get_bss(wvif->wdev->hw->wiphy, wvif->channel, + conf->bssid, NULL, 0, + IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY); + if (!bss && !conf->ibss_joined) { + wfx_tx_unlock(wvif->wdev); + return; + } + + rcu_read_lock(); // protect ssidie + if (bss) + ssidie = ieee80211_bss_get_ie(bss, WLAN_EID_SSID); + if (ssidie) { + ssidlen = ssidie[1]; + if (ssidlen > IEEE80211_MAX_SSID_LEN) + ssidlen = IEEE80211_MAX_SSID_LEN; + memcpy(ssid, &ssidie[2], ssidlen); + } + rcu_read_unlock(); + + cfg80211_put_bss(wvif->wdev->hw->wiphy, bss); + + wvif->join_in_progress = true; + ret = hif_join(wvif, conf, wvif->channel, ssid, ssidlen); + if (ret) { + ieee80211_connection_loss(wvif->vif); + wfx_reset(wvif); + } else { + /* Due to beacon filtering it is possible that the + * AP's beacon is not known for the mac80211 stack. + * Disable filtering temporary to make sure the stack + * receives at least one + */ + wfx_filter_beacon(wvif, false); + } + wfx_tx_unlock(wvif->wdev); +} + static void wfx_join_finalize(struct wfx_vif *wvif, struct ieee80211_bss_conf *info) { + struct ieee80211_sta *sta = NULL; + int ampdu_density = 0; + bool greenfield = false; + + rcu_read_lock(); // protect sta + if (info->bssid && !info->ibss_joined) + sta = ieee80211_find_sta(wvif->vif, info->bssid); + if (sta && sta->ht_cap.ht_supported) + ampdu_density = sta->ht_cap.ampdu_density; + if (sta && sta->ht_cap.ht_supported && + !(info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)) + greenfield = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD); + rcu_read_unlock(); + wvif->join_in_progress = false; - hif_set_association_mode(wvif, info); + hif_set_association_mode(wvif, ampdu_density, greenfield, + info->use_short_preamble); hif_keep_alive_period(wvif, 0); // beacon_loss_count is defined to 7 in net/mac80211/mlme.c. Let's use // the same value. @@ -516,7 +472,7 @@ int wfx_join_ibss(struct ieee80211_hw *hw, struct ieee80211_vif *vif) struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; wfx_upload_ap_templates(wvif); - wfx_do_join(wvif); + wfx_join(wvif); return 0; } @@ -549,32 +505,22 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mutex_lock(&wdev->conf_mutex); - /* TODO: BSS_CHANGED_QOS */ - if (changed & BSS_CHANGED_ARP_FILTER) { - for (i = 0; i < HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES; i++) { - __be32 *arp_addr = &info->arp_addr_list[i]; - - if (info->arp_addr_cnt > HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES) - arp_addr = NULL; - if (i >= info->arp_addr_cnt) - arp_addr = NULL; - hif_set_arp_ipv4_filter(wvif, i, arp_addr); - } - } - if (changed & BSS_CHANGED_BASIC_RATES || changed & BSS_CHANGED_BEACON_INT || changed & BSS_CHANGED_BSSID) { if (vif->type == NL80211_IFTYPE_STATION) - wfx_do_join(wvif); + wfx_join(wvif); } - if (changed & BSS_CHANGED_AP_PROBE_RESP || - changed & BSS_CHANGED_BEACON) - wfx_upload_ap_templates(wvif); - - if (changed & BSS_CHANGED_BEACON_ENABLED) - wfx_enable_beacon(wvif, info->enable_beacon); + if (changed & BSS_CHANGED_ASSOC) { + if (info->assoc || info->ibss_joined) + wfx_join_finalize(wvif, info); + else if (!info->assoc && vif->type == NL80211_IFTYPE_STATION) + wfx_reset(wvif); + else + dev_warn(wdev->dev, "%s: misunderstood change: ASSOC\n", + __func__); + } if (changed & BSS_CHANGED_BEACON_INFO) { if (vif->type != NL80211_IFTYPE_STATION) @@ -587,16 +533,25 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, wfx_filter_beacon(wvif, true); } - if (changed & BSS_CHANGED_ASSOC) { - if (info->assoc || info->ibss_joined) - wfx_join_finalize(wvif, info); - else if (!info->assoc && vif->type == NL80211_IFTYPE_STATION) - wfx_reset(wvif); - else - dev_warn(wdev->dev, "%s: misunderstood change: ASSOC\n", - __func__); + if (changed & BSS_CHANGED_ARP_FILTER) { + for (i = 0; i < HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES; i++) { + __be32 *arp_addr = &info->arp_addr_list[i]; + + if (info->arp_addr_cnt > HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES) + arp_addr = NULL; + if (i >= info->arp_addr_cnt) + arp_addr = NULL; + hif_set_arp_ipv4_filter(wvif, i, arp_addr); + } } + if (changed & BSS_CHANGED_AP_PROBE_RESP || + changed & BSS_CHANGED_BEACON) + wfx_upload_ap_templates(wvif); + + if (changed & BSS_CHANGED_BEACON_ENABLED) + wfx_enable_beacon(wvif, info->enable_beacon); + if (changed & BSS_CHANGED_KEEP_ALIVE) hif_keep_alive_period(wvif, info->max_idle_period * USEC_PER_TU / USEC_PER_MSEC); @@ -682,15 +637,16 @@ int wfx_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_ampdu_params *params) { - /* Aggregation is implemented fully in firmware, - * including block ack negotiation. Do not allow - * mac80211 stack to do anything: it interferes with - * the firmware. - */ - - /* Note that we still need this function stubbed. */ - - return -ENOTSUPP; + // Aggregation is implemented fully in firmware + switch (params->action) { + case IEEE80211_AMPDU_RX_START: + case IEEE80211_AMPDU_RX_STOP: + // Just acknowledge it to enable frame re-ordering + return 0; + default: + // Leave the firmware doing its business for tx aggregation + return -ENOTSUPP; + } } int wfx_add_chanctx(struct ieee80211_hw *hw, @@ -760,17 +716,6 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) return -EOPNOTSUPP; } - for (i = 0; i < ARRAY_SIZE(wdev->vif); i++) { - if (!wdev->vif[i]) { - wdev->vif[i] = vif; - wvif->id = i; - break; - } - } - if (i == ARRAY_SIZE(wdev->vif)) { - mutex_unlock(&wdev->conf_mutex); - return -EOPNOTSUPP; - } // FIXME: prefer use of container_of() to get vif wvif->vif = vif; wvif->wdev = wdev; @@ -787,12 +732,22 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) init_completion(&wvif->scan_complete); INIT_WORK(&wvif->scan_work, wfx_hw_scan_work); - mutex_unlock(&wdev->conf_mutex); + wfx_tx_queues_init(wvif); + wfx_tx_policy_init(wvif); + + for (i = 0; i < ARRAY_SIZE(wdev->vif); i++) { + if (!wdev->vif[i]) { + wdev->vif[i] = vif; + wvif->id = i; + break; + } + } + WARN(i == ARRAY_SIZE(wdev->vif), "try to instantiate more vif than supported"); hif_set_macaddr(wvif, vif->addr); - wfx_tx_queues_init(wvif); - wfx_tx_policy_init(wvif); + mutex_unlock(&wdev->conf_mutex); + wvif = NULL; while ((wvif = wvif_iterate(wdev, wvif)) != NULL) { // Combo mode does not support Block Acks. We can re-enable them @@ -824,6 +779,7 @@ void wfx_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) wvif->vif = NULL; mutex_unlock(&wdev->conf_mutex); + wvif = NULL; while ((wvif = wvif_iterate(wdev, wvif)) != NULL) { // Combo mode does not support Block Acks. We can re-enable them diff --git a/drivers/staging/wfx/sta.h b/drivers/staging/wfx/sta.h index 6b15a64ac9e2..610cfb0fcd02 100644 --- a/drivers/staging/wfx/sta.h +++ b/drivers/staging/wfx/sta.h @@ -25,8 +25,6 @@ int wfx_config(struct ieee80211_hw *hw, u32 changed); int wfx_set_rts_threshold(struct ieee80211_hw *hw, u32 value); void wfx_set_default_unicast_key(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int idx); -u64 wfx_prepare_multicast(struct ieee80211_hw *hw, - struct netdev_hw_addr_list *mc_list); void wfx_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, unsigned int *total_flags, u64 unused); diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index 38e24d7f72f2..56fbfab05651 100644 --- a/drivers/staging/wfx/wfx.h +++ b/drivers/staging/wfx/wfx.h @@ -20,7 +20,6 @@ #include "data_tx.h" #include "main.h" #include "queue.h" -#include "secure_link.h" #include "hif_tx.h" #define USEC_PER_TXOP 32 // see struct ieee80211_tx_queue_params @@ -41,7 +40,6 @@ struct wfx_dev { struct completion firmware_ready; struct hif_ind_startup hw_caps; struct wfx_hif hif; - struct sl_context sl; struct delayed_work cooling_timeout_work; bool poll_irq; bool chip_frozen; @@ -81,9 +79,6 @@ struct wfx_vif { struct work_struct update_tim_work; - int filter_mcast_count; - u8 filter_mcast_addr[8][ETH_ALEN]; - unsigned long uapsd_mask; /* avoid some operations in parallel with scan */ diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c index 7b091c5a2984..4a6813e89916 100644 --- a/drivers/staging/wlan-ng/p80211netdev.c +++ b/drivers/staging/wlan-ng/p80211netdev.c @@ -274,7 +274,7 @@ static void p80211netdev_rx_bh(unsigned long arg) struct sk_buff *skb = NULL; struct net_device *dev = wlandev->netdev; - /* Let's empty our our queue */ + /* Let's empty our queue */ while ((skb = skb_dequeue(&wlandev->nsd_rxq))) { if (wlandev->state == WLAN_DEVICE_OPEN) { if (dev->type != ARPHRD_ETHER) { diff --git a/drivers/staging/wlan-ng/prism2mgmt.c b/drivers/staging/wlan-ng/prism2mgmt.c index a8860d2aee68..a908ff301707 100644 --- a/drivers/staging/wlan-ng/prism2mgmt.c +++ b/drivers/staging/wlan-ng/prism2mgmt.c @@ -228,8 +228,8 @@ int prism2mgmt_scan(struct wlandevice *wlandev, void *msgp) __le16 wordbuf[17]; result = hfa384x_drvr_setconfig16(hw, - HFA384x_RID_CNFROAMINGMODE, - HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM); + HFA384x_RID_CNFROAMINGMODE, + HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM); if (result) { netdev_err(wlandev->netdev, "setconfig(ROAMINGMODE) failed. result=%d\n", @@ -275,8 +275,8 @@ int prism2mgmt_scan(struct wlandevice *wlandev, void *msgp) } /* ibss options */ result = hfa384x_drvr_setconfig16(hw, - HFA384x_RID_CREATEIBSS, - HFA384x_CREATEIBSS_JOINCREATEIBSS); + HFA384x_RID_CREATEIBSS, + HFA384x_CREATEIBSS_JOINCREATEIBSS); if (result) { netdev_err(wlandev->netdev, "Failed to set CREATEIBSS.\n"); @@ -1167,8 +1167,8 @@ int prism2mgmt_wlansniff(struct wlandevice *wlandev, void *msgp) if (hw->presniff_port_type != 0) { word = hw->presniff_port_type; result = hfa384x_drvr_setconfig16(hw, - HFA384x_RID_CNFPORTTYPE, - word); + HFA384x_RID_CNFPORTTYPE, + word); if (result) { netdev_dbg (wlandev->netdev, @@ -1209,8 +1209,8 @@ int prism2mgmt_wlansniff(struct wlandevice *wlandev, void *msgp) } /* Save the wepflags state */ result = hfa384x_drvr_getconfig16(hw, - HFA384x_RID_CNFWEPFLAGS, - &hw->presniff_wepflags); + HFA384x_RID_CNFWEPFLAGS, + &hw->presniff_wepflags); if (result) { netdev_dbg (wlandev->netdev, @@ -1259,8 +1259,8 @@ int prism2mgmt_wlansniff(struct wlandevice *wlandev, void *msgp) /* Set the port type to pIbss */ word = HFA384x_PORTTYPE_PSUEDOIBSS; result = hfa384x_drvr_setconfig16(hw, - HFA384x_RID_CNFPORTTYPE, - word); + HFA384x_RID_CNFPORTTYPE, + word); if (result) { netdev_dbg (wlandev->netdev, @@ -1276,8 +1276,8 @@ int prism2mgmt_wlansniff(struct wlandevice *wlandev, void *msgp) HFA384x_WEPFLAGS_DISABLE_RXCRYPT; result = hfa384x_drvr_setconfig16(hw, - HFA384x_RID_CNFWEPFLAGS, - word); + HFA384x_RID_CNFWEPFLAGS, + word); } if (result) { diff --git a/drivers/staging/wlan-ng/prism2mib.c b/drivers/staging/wlan-ng/prism2mib.c index 7d7d77b04255..875812a391c9 100644 --- a/drivers/staging/wlan-ng/prism2mib.c +++ b/drivers/staging/wlan-ng/prism2mib.c @@ -292,7 +292,7 @@ int prism2mgmt_mibset_mibget(struct wlandevice *wlandev, void *msgp) /* ** Determine if this is a "mibget" or a "mibset". If this is a ** "mibget", then make sure that the MIB may be read. Otherwise, - ** this is a "mibset" so make make sure that the MIB may be written. + ** this is a "mibset" so make sure that the MIB may be written. */ isget = (msg->msgcode == DIDMSG_DOT11REQ_MIBGET); diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c index 8f25496188aa..e6dcb687e7a1 100644 --- a/drivers/staging/wlan-ng/prism2sta.c +++ b/drivers/staging/wlan-ng/prism2sta.c @@ -461,7 +461,7 @@ u32 prism2sta_ifstate(struct wlandevice *wlandev, u32 ifstate) case WLAN_MSD_FWLOAD: wlandev->msdstate = WLAN_MSD_RUNNING_PENDING; /* Initialize the device+driver for full - * operation. Note that this might me an FWLOAD to + * operation. Note that this might me an FWLOAD * to RUNNING transition so we must not do a chip * or board level reset. Note that on failure, * the MSD state is set to HWPRESENT because we @@ -1352,7 +1352,7 @@ void prism2sta_processing_defer(struct work_struct *data) * we get back in range. We should block transmits and * receives in this state. Do we need an indication here? * Probably not since a polling user-mode element would - * get this status from from p2PortStatus(FD40). What about + * get this status from p2PortStatus(FD40). What about * p80211? * Response: * Block Transmits, Ignore receives of data frames diff --git a/include/linux/mfd/hi6421-spmi-pmic.h b/include/linux/mfd/hi6421-spmi-pmic.h new file mode 100644 index 000000000000..2c8896fd852e --- /dev/null +++ b/include/linux/mfd/hi6421-spmi-pmic.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Header file for device driver Hi6421 PMIC + * + * Copyright (c) 2013 Linaro Ltd. + * Copyright (C) 2011 Hisilicon. + * + * Guodong Xu <guodong.xu@linaro.org> + */ + +#ifndef __HISI_PMIC_H +#define __HISI_PMIC_H + +#include <linux/irqdomain.h> + +#define HISI_REGS_ENA_PROTECT_TIME (0) /* in microseconds */ +#define HISI_ECO_MODE_ENABLE (1) +#define HISI_ECO_MODE_DISABLE (0) + +struct hi6421_spmi_pmic { + struct resource *res; + struct device *dev; + void __iomem *regs; + spinlock_t lock; + struct irq_domain *domain; + int irq; + int gpio; + unsigned int *irqs; +}; + +int hi6421_spmi_pmic_read(struct hi6421_spmi_pmic *pmic, int reg); +int hi6421_spmi_pmic_write(struct hi6421_spmi_pmic *pmic, int reg, u32 val); +int hi6421_spmi_pmic_rmw(struct hi6421_spmi_pmic *pmic, int reg, + u32 mask, u32 bits); + +enum hi6421_spmi_pmic_irq_list { + OTMP = 0, + VBUS_CONNECT, + VBUS_DISCONNECT, + ALARMON_R, + HOLD_6S, + HOLD_1S, + POWERKEY_UP, + POWERKEY_DOWN, + OCP_SCP_R, + COUL_R, + SIM0_HPD_R, + SIM0_HPD_F, + SIM1_HPD_R, + SIM1_HPD_F, + PMIC_IRQ_LIST_MAX, +}; +#endif /* __HISI_PMIC_H */ diff --git a/include/linux/platform_data/ad7793.h b/include/linux/platform_data/ad7793.h index 576c7f962c4e..7c697e58f02a 100644 --- a/include/linux/platform_data/ad7793.h +++ b/include/linux/platform_data/ad7793.h @@ -40,7 +40,7 @@ enum ad7793_bias_voltage { * enum ad7793_refsel - AD7793 reference voltage selection * @AD7793_REFSEL_REFIN1: External reference applied between REFIN1(+) * and REFIN1(-). - * @AD7793_REFSEL_REFIN2: External reference applied between REFIN2(+) and + * @AD7793_REFSEL_REFIN2: External reference applied between REFIN2(+) * and REFIN1(-). Only valid for AD7795/AD7796. * @AD7793_REFSEL_INTERNAL: Internal 1.17 V reference. */ diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h index fdd81affca4b..48c13147c0a8 100644 --- a/include/uapi/linux/iio/types.h +++ b/include/uapi/linux/iio/types.h @@ -94,6 +94,7 @@ enum iio_modifier { IIO_MOD_PM10, IIO_MOD_ETHANOL, IIO_MOD_H2, + IIO_MOD_O2, }; enum iio_event_type { diff --git a/tools/iio/iio_event_monitor.c b/tools/iio/iio_event_monitor.c index f115d166c985..bb03859db89d 100644 --- a/tools/iio/iio_event_monitor.c +++ b/tools/iio/iio_event_monitor.c @@ -119,6 +119,7 @@ static const char * const iio_modifier_names[] = { [IIO_MOD_PM2P5] = "pm2p5", [IIO_MOD_PM4] = "pm4", [IIO_MOD_PM10] = "pm10", + [IIO_MOD_O2] = "o2", }; static bool event_is_known(struct iio_event_data *event) @@ -211,6 +212,7 @@ static bool event_is_known(struct iio_event_data *event) case IIO_MOD_PM2P5: case IIO_MOD_PM4: case IIO_MOD_PM10: + case IIO_MOD_O2: break; default: return false; |