diff options
335 files changed, 9603 insertions, 18624 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index 8127a08e366d..864f8efd12e5 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -1554,6 +1554,10 @@ What: /sys/bus/iio/devices/iio:deviceX/in_concentration_raw What: /sys/bus/iio/devices/iio:deviceX/in_concentrationX_raw What: /sys/bus/iio/devices/iio:deviceX/in_concentration_co2_raw What: /sys/bus/iio/devices/iio:deviceX/in_concentrationX_co2_raw +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_voc_raw What: /sys/bus/iio/devices/iio:deviceX/in_concentrationX_voc_raw KernelVersion: 4.3 @@ -1684,4 +1688,19 @@ KernelVersion: 4.18 Contact: linux-iio@vger.kernel.org Description: Raw (unscaled) phase difference reading from channel Y - that can be processed to radians.
\ No newline at end of file + that can be processed to radians. + +What: /sys/bus/iio/devices/iio:deviceX/in_massconcentration_pm1_input +What: /sys/bus/iio/devices/iio:deviceX/in_massconcentrationY_pm1_input +What: /sys/bus/iio/devices/iio:deviceX/in_massconcentration_pm2p5_input +What: /sys/bus/iio/devices/iio:deviceX/in_massconcentrationY_pm2p5_input +What: /sys/bus/iio/devices/iio:deviceX/in_massconcentration_pm4_input +What: /sys/bus/iio/devices/iio:deviceX/in_massconcentrationY_pm4_input +What: /sys/bus/iio/devices/iio:deviceX/in_massconcentration_pm10_input +What: /sys/bus/iio/devices/iio:deviceX/in_massconcentrationY_pm10_input +KernelVersion: 4.22 +Contact: linux-iio@vger.kernel.org +Description: + Mass concentration reading of particulate matter in ug / m3. + pmX consists of particles with aerodynamic diameter less or + equal to X micrometers. diff --git a/Documentation/ABI/testing/sysfs-bus-iio-sps30 b/Documentation/ABI/testing/sysfs-bus-iio-sps30 new file mode 100644 index 000000000000..143df8e89d08 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-sps30 @@ -0,0 +1,28 @@ +What: /sys/bus/iio/devices/iio:deviceX/start_cleaning +Date: December 2018 +KernelVersion: 4.22 +Contact: linux-iio@vger.kernel.org +Description: + Writing 1 starts sensor self cleaning. Internal fan accelerates + to its maximum speed and keeps spinning for about 10 seconds in + order to blow out accumulated dust. + +What: /sys/bus/iio/devices/iio:deviceX/cleaning_period +Date: January 2019 +KernelVersion: 5.1 +Contact: linux-iio@vger.kernel.org +Description: + Sensor is capable of triggering self cleaning periodically. + Period can be changed by writing a new value here. Upon reading + the current one is returned. Units are seconds. + + Writing 0 disables periodical self cleaning entirely. + +What: /sys/bus/iio/devices/iio:deviceX/cleaning_period_available +Date: January 2019 +KernelVersion: 5.1 +Contact: linux-iio@vger.kernel.org +Description: + The range of available values in seconds represented as the + minimum value, the step and the maximum value, all enclosed in + square brackets. diff --git a/Documentation/devicetree/bindings/iio/accel/mma8452.txt b/Documentation/devicetree/bindings/iio/accel/mma8452.txt index 2100e9af379c..e132394375a1 100644 --- a/Documentation/devicetree/bindings/iio/accel/mma8452.txt +++ b/Documentation/devicetree/bindings/iio/accel/mma8452.txt @@ -20,6 +20,10 @@ Optional properties: - interrupt-names: should contain "INT1" and/or "INT2", the accelerometer's interrupt line in use. + - vdd-supply: phandle to the regulator that provides vdd power to the accelerometer. + + - vddio-supply: phandle to the regulator that provides vddio power to the accelerometer. + Example: mma8453fc@1d { diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7606.txt b/Documentation/devicetree/bindings/iio/adc/adi,ad7606.txt new file mode 100644 index 000000000000..d7b6241ca881 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7606.txt @@ -0,0 +1,65 @@ +Analog Devices AD7606 Simultaneous Sampling ADC + +Required properties for the AD7606: + +- compatible: Must be one of + * "adi,ad7605-4" + * "adi,ad7606-8" + * "adi,ad7606-6" + * "adi,ad7606-4" +- reg: SPI chip select number for the device +- spi-max-frequency: Max SPI frequency to use + see: Documentation/devicetree/bindings/spi/spi-bus.txt +- spi-cpha: See Documentation/devicetree/bindings/spi/spi-bus.txt +- avcc-supply: phandle to the Avcc power supply +- interrupts: IRQ line for the ADC + see: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt +- adi,conversion-start-gpios: must be the device tree identifier of the CONVST pin. + This logic input is used to initiate conversions on the analog + input channels. As the line is active high, it should be marked + GPIO_ACTIVE_HIGH. + +Optional properties: + +- reset-gpios: must be the device tree identifier of the RESET pin. If specified, + it will be asserted during driver probe. As the line is active high, + it should be marked GPIO_ACTIVE_HIGH. +- standby-gpios: must be the device tree identifier of the STBY pin. This pin is used + to place the AD7606 into one of two power-down modes, Standby mode or + Shutdown mode. As the line is active low, it should be marked + GPIO_ACTIVE_LOW. +- adi,first-data-gpios: must be the device tree identifier of the FRSTDATA pin. + The FRSTDATA output indicates when the first channel, V1, is + being read back on either the parallel, byte or serial interface. + As the line is active high, it should be marked GPIO_ACTIVE_HIGH. +- adi,range-gpios: must be the device tree identifier of the RANGE pin. The polarity on + this pin determines the input range of the analog input channels. If + this pin is tied to a logic high, the analog input range is ±10V for + all channels. If this pin is tied to a logic low, the analog input range + is ±5V for all channels. As the line is active high, it should be marked + GPIO_ACTIVE_HIGH. +- adi,oversampling-ratio-gpios: must be the device tree identifier of the over-sampling + mode pins. As the line is active high, it should be marked + GPIO_ACTIVE_HIGH. + +Example: + + adc@0 { + compatible = "adi,ad7606-8"; + reg = <0>; + spi-max-frequency = <1000000>; + spi-cpol; + + avcc-supply = <&adc_vref>; + + interrupts = <25 IRQ_TYPE_EDGE_FALLING>; + interrupt-parent = <&gpio>; + + adi,conversion-start-gpios = <&gpio 17 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio 27 GPIO_ACTIVE_HIGH>; + adi,first-data-gpios = <&gpio 22 GPIO_ACTIVE_HIGH>; + adi,oversampling-ratio-gpios = <&gpio 18 GPIO_ACTIVE_HIGH + &gpio 23 GPIO_ACTIVE_HIGH + &gpio 26 GPIO_ACTIVE_HIGH>; + standby-gpios = <&gpio 24 GPIO_ACTIVE_LOW>; + }; diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.txt b/Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.txt new file mode 100644 index 000000000000..9f5b88cf680d --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.txt @@ -0,0 +1,41 @@ +Analog Devices AD7768-1 ADC device driver + +Required properties for the AD7768-1: + +- compatible: Must be "adi,ad7768-1" +- reg: SPI chip select number for the device +- spi-max-frequency: Max SPI frequency to use + see: Documentation/devicetree/bindings/spi/spi-bus.txt +- clocks: phandle to the master clock (mclk) + see: Documentation/devicetree/bindings/clock/clock-bindings.txt +- clock-names: Must be "mclk". +- interrupts: IRQ line for the ADC + see: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt +- vref-supply: vref supply can be used as reference for conversion +- adi,sync-in-gpios: must be the device tree identifier of the SYNC-IN pin. Enables + synchronization of multiple devices that require simultaneous sampling. + A pulse is always required if the configuration is changed in any way, for example + if the filter decimation rate changes. As the line is active low, it should + be marked GPIO_ACTIVE_LOW. + +Optional properties: + + - reset-gpios : GPIO spec for the RESET pin. If specified, it will be asserted during + driver probe. As the line is active low, it should be marked GPIO_ACTIVE_LOW. + +Example: + + adc@0 { + compatible = "adi,ad7768-1"; + reg = <0>; + spi-max-frequency = <2000000>; + spi-cpol; + spi-cpha; + vref-supply = <&adc_vref>; + interrupts = <25 IRQ_TYPE_EDGE_RISING>; + interrupt-parent = <&gpio>; + adi,sync-in-gpios = <&gpio 22 GPIO_ACTIVE_LOW>; + reset-gpios = <&gpio 27 GPIO_ACTIVE_LOW>; + clocks = <&ad7768_mclk>; + clock-names = "mclk"; + }; diff --git a/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.txt b/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.txt index 325090e43ce6..75c775954102 100644 --- a/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.txt +++ b/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.txt @@ -23,6 +23,10 @@ Required properties: - #io-channel-cells: must be 1, see ../iio-bindings.txt Optional properties: +- amlogic,hhi-sysctrl: phandle to the syscon which contains the 5th bit + of the TSC (temperature sensor coefficient) on + Meson8b and Meson8m2 (which used to calibrate the + temperature sensor) - nvmem-cells: phandle to the temperature_calib eFuse cells - nvmem-cell-names: if present (to enable the temperature sensor calibration) this must contain "temperature_calib" diff --git a/Documentation/devicetree/bindings/iio/adc/ingenic,adc.txt b/Documentation/devicetree/bindings/iio/adc/ingenic,adc.txt new file mode 100644 index 000000000000..f01159f20d87 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ingenic,adc.txt @@ -0,0 +1,48 @@ +* Ingenic JZ47xx ADC controller IIO bindings + +Required properties: + +- compatible: Should be one of: + * ingenic,jz4725b-adc + * ingenic,jz4740-adc +- reg: ADC controller registers location and length. +- clocks: phandle to the SoC's ADC clock. +- clock-names: Must be set to "adc". +- #io-channel-cells: Must be set to <1> to indicate channels are selected + by index. + +ADC clients must use the format described in iio-bindings.txt, giving +a phandle and IIO specifier pair ("io-channels") to the ADC controller. + +Example: + +#include <dt-bindings/iio/adc/ingenic,adc.h> + +adc: adc@10070000 { + compatible = "ingenic,jz4740-adc"; + #io-channel-cells = <1>; + + reg = <0x10070000 0x30>; + + clocks = <&cgu JZ4740_CLK_ADC>; + clock-names = "adc"; + + interrupt-parent = <&intc>; + interrupts = <18>; +}; + +adc-keys { + ... + compatible = "adc-keys"; + io-channels = <&adc INGENIC_ADC_AUX>; + io-channel-names = "buttons"; + ... +}; + +battery { + ... + compatible = "ingenic,jz4740-battery"; + io-channels = <&adc INGENIC_ADC_BATTERY>; + io-channel-names = "battery"; + ... +}; diff --git a/Documentation/devicetree/bindings/staging/iio/adc/lpc32xx-adc.txt b/Documentation/devicetree/bindings/iio/adc/lpc32xx-adc.txt index b3629d3a9adf..b3629d3a9adf 100644 --- a/Documentation/devicetree/bindings/staging/iio/adc/lpc32xx-adc.txt +++ b/Documentation/devicetree/bindings/iio/adc/lpc32xx-adc.txt diff --git a/Documentation/devicetree/bindings/iio/adc/nuvoton,npcm-adc.txt b/Documentation/devicetree/bindings/iio/adc/nuvoton,npcm-adc.txt new file mode 100644 index 000000000000..eb939fe77836 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/nuvoton,npcm-adc.txt @@ -0,0 +1,24 @@ +Nuvoton NPCM Analog to Digital Converter (ADC) + +The NPCM ADC is a 10-bit converter for eight channel inputs. + +Required properties: +- compatible: "nuvoton,npcm750-adc" for the NPCM7XX BMC. +- reg: specifies physical base address and size of the registers. +- interrupts: Contain the ADC interrupt with flags for falling edge. + +Optional properties: +- clocks: phandle of ADC reference clock, in case the clock is not + added the ADC will use the default ADC sample rate. +- vref-supply: The regulator supply ADC reference voltage, in case the + vref-supply is not added the ADC will use internal voltage + reference. + +Example: + +adc: adc@f000c000 { + compatible = "nuvoton,npcm750-adc"; + reg = <0xf000c000 0x8>; + interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk NPCM7XX_CLK_ADC>; +}; diff --git a/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.txt b/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.txt index a10c1f89037d..e1fe02f3e3e9 100644 --- a/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.txt +++ b/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.txt @@ -11,11 +11,13 @@ New driver handles the following Required properties: - compatible: Must be "samsung,exynos-adc-v1" - for exynos4412/5250 controllers. + for Exynos5250 controllers. Must be "samsung,exynos-adc-v2" for future controllers. Must be "samsung,exynos3250-adc" for controllers compatible with ADC of Exynos3250. + Must be "samsung,exynos4212-adc" for + controllers compatible with ADC of Exynos4212 and Exynos4412. Must be "samsung,exynos7-adc" for the ADC in Exynos7 and compatibles Must be "samsung,s3c2410-adc" for diff --git a/Documentation/devicetree/bindings/iio/adc/ti-ads124s08.txt b/Documentation/devicetree/bindings/iio/adc/ti-ads124s08.txt new file mode 100644 index 000000000000..ecf807bb32f7 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti-ads124s08.txt @@ -0,0 +1,25 @@ +* Texas Instruments' ads124s08 and ads124s06 ADC chip + +Required properties: + - compatible : + "ti,ads124s08" + "ti,ads124s06" + - reg : spi chip select number for the device + +Recommended properties: + - spi-max-frequency : Definition as per + Documentation/devicetree/bindings/spi/spi-bus.txt + - spi-cpha : Definition as per + Documentation/devicetree/bindings/spi/spi-bus.txt + +Optional properties: + - reset-gpios : GPIO pin used to reset the device. + +Example: +adc@0 { + compatible = "ti,ads124s08"; + reg = <0>; + spi-max-frequency = <1000000>; + spi-cpha; + reset-gpios = <&gpio1 16 GPIO_ACTIVE_LOW>; +}; diff --git a/Documentation/devicetree/bindings/iio/chemical/bme680.txt b/Documentation/devicetree/bindings/iio/chemical/bme680.txt new file mode 100644 index 000000000000..7f3827cfb2ff --- /dev/null +++ b/Documentation/devicetree/bindings/iio/chemical/bme680.txt @@ -0,0 +1,11 @@ +Bosch Sensortec BME680 pressure/temperature/humidity/voc sensors + +Required properties: +- compatible: must be "bosch,bme680" + +Example: + +bme680@76 { + compatible = "bosch,bme680"; + reg = <0x76>; +}; diff --git a/Documentation/devicetree/bindings/iio/chemical/plantower,pms7003.txt b/Documentation/devicetree/bindings/iio/chemical/plantower,pms7003.txt new file mode 100644 index 000000000000..7b5f06f324c8 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/chemical/plantower,pms7003.txt @@ -0,0 +1,20 @@ +* Plantower PMS7003 particulate matter sensor + +Required properties: +- compatible: must be "plantower,pms7003" +- vcc-supply: phandle to the regulator that provides power to the sensor + +Optional properties: +- plantower,set-gpios: phandle to the GPIO connected to the SET line +- reset-gpios: phandle to the GPIO connected to the RESET line + +Refer to serial/slave-device.txt for generic serial attached device bindings. + +Example: + +&uart0 { + air-pollution-sensor { + compatible = "plantower,pms7003"; + vcc-supply = <®_vcc5v0>; + }; +}; diff --git a/Documentation/devicetree/bindings/iio/chemical/sensirion,sgp30.txt b/Documentation/devicetree/bindings/iio/chemical/sensirion,sgp30.txt new file mode 100644 index 000000000000..5844ed58173c --- /dev/null +++ b/Documentation/devicetree/bindings/iio/chemical/sensirion,sgp30.txt @@ -0,0 +1,15 @@ +* Sensirion SGP30/SGPC3 multi-pixel Gas Sensor + +Required properties: + + - compatible: must be one of + "sensirion,sgp30" + "sensirion,sgpc3" + - reg: the I2C address of the sensor + +Example: + +gas@58 { + compatible = "sensirion,sgp30"; + reg = <0x58>; +}; diff --git a/Documentation/devicetree/bindings/iio/chemical/sensirion,sps30.txt b/Documentation/devicetree/bindings/iio/chemical/sensirion,sps30.txt new file mode 100644 index 000000000000..6eee2709b5b6 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/chemical/sensirion,sps30.txt @@ -0,0 +1,12 @@ +* Sensirion SPS30 particulate matter sensor + +Required properties: +- compatible: must be "sensirion,sps30" +- reg: the I2C address of the sensor + +Example: + +sps30@69 { + compatible = "sensirion,sps30"; + reg = <0x69>; +}; diff --git a/Documentation/devicetree/bindings/iio/dac/ti,dac7612.txt b/Documentation/devicetree/bindings/iio/dac/ti,dac7612.txt new file mode 100644 index 000000000000..639c94ed83e9 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/dac/ti,dac7612.txt @@ -0,0 +1,28 @@ +* Texas Instruments Dual, 12-Bit Serial Input Digital-to-Analog Converter + +The DAC7612 is a dual, 12-bit digital-to-analog converter (DAC) with guaranteed +12-bit monotonicity performance over the industrial temperature range. +Is is programmable through an SPI interface. + +The internal DACs are loaded when the LOADDACS pin is pulled down. + +http://www.ti.com/lit/ds/sbas106/sbas106.pdf + +Required Properties: +- compatible: Should be one of: + "ti,dac7612" + "ti,dac7612u" + "ti,dac7612ub" +- reg: Definition as per Documentation/devicetree/bindings/spi/spi-bus.txt + +Optional Properties: +- ti,loaddacs-gpios: GPIO descriptor for the LOADDACS pin. +- spi-*: Definition as per Documentation/devicetree/bindings/spi/spi-bus.txt + +Example: + + dac@1 { + compatible = "ti,dac7612"; + reg = <0x1>; + ti,loaddacs-gpios = <&msmgpio 25 GPIO_ACTIVE_LOW>; + }; diff --git a/Documentation/devicetree/bindings/iio/impedance-analyzer/ad5933.txt b/Documentation/devicetree/bindings/iio/impedance-analyzer/ad5933.txt new file mode 100644 index 000000000000..5ff38728ff91 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/impedance-analyzer/ad5933.txt @@ -0,0 +1,26 @@ +Analog Devices AD5933/AD5934 Impedance Converter, Network Analyzer + +https://www.analog.com/media/en/technical-documentation/data-sheets/AD5933.pdf +https://www.analog.com/media/en/technical-documentation/data-sheets/AD5934.pdf + +Required properties: + - compatible : should be one of + "adi,ad5933" + "adi,ad5934" + - reg : the I2C address. + - vdd-supply : The regulator supply for DVDD, AVDD1 and AVDD2 when they + are connected together. + +Optional properties: +- clocks : external clock reference. +- clock-names : must be "mclk" if clocks is set. + +Example for a I2C device node: + + impedance-analyzer@0d { + compatible = "adi,adxl345"; + reg = <0x0d>; + vdd-supply = <&vdd_supply>; + clocks = <&ref_clk>; + clock-names = "mclk"; + }; diff --git a/Documentation/devicetree/bindings/iio/imu/bmi160.txt b/Documentation/devicetree/bindings/iio/imu/bmi160.txt index 0c1c105fb503..900c169de00f 100644 --- a/Documentation/devicetree/bindings/iio/imu/bmi160.txt +++ b/Documentation/devicetree/bindings/iio/imu/bmi160.txt @@ -9,9 +9,11 @@ Required properties: - spi-max-frequency : set maximum clock frequency (only for SPI) Optional properties: - - interrupts : interrupt mapping for IRQ, must be IRQ_TYPE_LEVEL_LOW + - interrupts : interrupt mapping for IRQ - interrupt-names : set to "INT1" if INT1 pin should be used as interrupt input, set to "INT2" if INT2 pin should be used instead + - drive-open-drain : set if the specified interrupt pin should be configured as + open drain. If not set, defaults to push-pull. Examples: @@ -20,7 +22,7 @@ bmi160@68 { reg = <0x68>; interrupt-parent = <&gpio4>; - interrupts = <12 IRQ_TYPE_LEVEL_LOW>; + interrupts = <12 IRQ_TYPE_EDGE_RISING>; interrupt-names = "INT1"; }; diff --git a/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt b/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt index 6ab9a9d196b0..268bf7568e19 100644 --- a/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt +++ b/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt @@ -11,6 +11,7 @@ Required properties: "invensense,mpu9250" "invensense,mpu9255" "invensense,icm20608" + "invensense,icm20602" - reg : the I2C address of the sensor - interrupts: interrupt mapping for IRQ. It should be configured with flags IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_EDGE_RISING, IRQ_TYPE_LEVEL_LOW or diff --git a/Documentation/devicetree/bindings/iio/light/max44009.txt b/Documentation/devicetree/bindings/iio/light/max44009.txt new file mode 100644 index 000000000000..4a98848e35c0 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/light/max44009.txt @@ -0,0 +1,24 @@ +* MAX44009 Ambient Light Sensor + +Required properties: + +- compatible: should be "maxim,max44009" +- reg: the I2C address of the device (default is <0x4a>) + +Optional properties: + +- interrupts: interrupt mapping for GPIO IRQ. Should be configured with + IRQ_TYPE_EDGE_FALLING. + +Refer to interrupt-controller/interrupts.txt for generic interrupt client +node bindings. + +Example: + +light-sensor@4a { + compatible = "maxim,max44009"; + reg = <0x4a>; + + interrupt-parent = <&gpio1>; + interrupts = <17 IRQ_TYPE_EDGE_FALLING>; +}; diff --git a/Documentation/devicetree/bindings/iio/st-sensors.txt b/Documentation/devicetree/bindings/iio/st-sensors.txt index ddcb95509599..52ee4baec6f0 100644 --- a/Documentation/devicetree/bindings/iio/st-sensors.txt +++ b/Documentation/devicetree/bindings/iio/st-sensors.txt @@ -77,3 +77,4 @@ Pressure sensors: - st,lps22hb-press - st,lps33hw - st,lps35hw +- st,lps22hh diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 542bbf304f13..e604e7f73629 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -310,6 +310,7 @@ phytec PHYTEC Messtechnik GmbH picochip Picochip Ltd pine64 Pine64 pixcir PIXCIR MICROELECTRONICS Co., Ltd +plantower Plantower Co., Ltd plathome Plat'Home Co., Ltd. plda PLDA plx Broadcom Corporation (formerly PLX Technology) diff --git a/MAINTAINERS b/MAINTAINERS index 108f3b1b7a79..060f4ff8da58 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -854,6 +854,22 @@ S: Supported F: drivers/iio/adc/ad7124.c F: Documentation/devicetree/bindings/iio/adc/adi,ad7124.txt +ANALOG DEVICES INC AD7606 DRIVER +M: Stefan Popa <stefan.popa@analog.com> +L: linux-iio@vger.kernel.org +W: http://ez.analog.com/community/linux-device-drivers +S: Supported +F: drivers/iio/adc/ad7606.c +F: Documentation/devicetree/bindings/iio/adc/ad7606.txt + +ANALOG DEVICES INC AD7768-1 DRIVER +M: Stefan Popa <stefan.popa@analog.com> +L: linux-iio@vger.kernel.org +W: http://ez.analog.com/community/linux-device-drivers +S: Supported +F: drivers/iio/adc/ad7768-1.c +F: Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.txt + ANALOG DEVICES INC AD9389B DRIVER M: Hans Verkuil <hans.verkuil@cisco.com> L: linux-media@vger.kernel.org @@ -14619,11 +14635,6 @@ L: linux-wireless@vger.kernel.org S: Supported F: drivers/staging/wilc1000/ -STAGING - XGI Z7,Z9,Z11 PCI DISPLAY DRIVER -M: Arnaud Patard <arnaud.patard@rtp-net.org> -S: Odd Fixes -F: drivers/staging/xgifb/ - STAGING SUBSYSTEM M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git @@ -15218,6 +15229,13 @@ L: alsa-devel@alsa-project.org (moderated for non-subscribers) S: Maintained F: sound/soc/ti/ +Texas Instruments' DAC7612 DAC Driver +M: Ricardo Ribalda <ricardo@ribalda.com> +L: linux-iio@vger.kernel.org +S: Supported +F: drivers/iio/dac/ti-dac7612.c +F: Documentation/devicetree/bindings/iio/dac/ti,dac7612.txt + THANKO'S RAREMONO AM/FM/SW RADIO RECEIVER USB DRIVER M: Hans Verkuil <hverkuil@xs4all.nl> L: linux-media@vger.kernel.org diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index 780f87f72338..f03ed00685ea 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -150,8 +150,8 @@ static int adxl345_read_raw(struct iio_dev *indio_dev, } static int adxl345_write_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int val, int val2, long mask) + struct iio_chan_spec const *chan, + int val, int val2, long mask) { struct adxl345_data *data = iio_priv(indio_dev); s64 n; diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c index 421a0a8a1379..302781126bc6 100644 --- a/drivers/iio/accel/mma8452.c +++ b/drivers/iio/accel/mma8452.c @@ -31,6 +31,7 @@ #include <linux/of_device.h> #include <linux/of_irq.h> #include <linux/pm_runtime.h> +#include <linux/regulator/consumer.h> #define MMA8452_STATUS 0x00 #define MMA8452_STATUS_DRDY (BIT(2) | BIT(1) | BIT(0)) @@ -107,6 +108,8 @@ struct mma8452_data { u8 data_cfg; const struct mma_chip_info *chip_info; int sleep_val; + struct regulator *vdd_reg; + struct regulator *vddio_reg; }; /** @@ -1534,9 +1537,39 @@ static int mma8452_probe(struct i2c_client *client, mutex_init(&data->lock); 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); + } + + 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); + } + + ret = regulator_enable(data->vdd_reg); + if (ret) { + dev_err(&client->dev, "failed to enable VDD regulator!\n"); + return ret; + } + + ret = regulator_enable(data->vddio_reg); + if (ret) { + dev_err(&client->dev, "failed to enable VDDIO regulator!\n"); + goto disable_regulator_vdd; + } + ret = i2c_smbus_read_byte_data(client, MMA8452_WHO_AM_I); if (ret < 0) - return ret; + goto disable_regulators; switch (ret) { case MMA8451_DEVICE_ID: @@ -1549,7 +1582,8 @@ static int mma8452_probe(struct i2c_client *client, break; /* else: fall through */ default: - return -ENODEV; + ret = -ENODEV; + goto disable_regulators; } dev_info(&client->dev, "registering %s accelerometer; ID 0x%x\n", @@ -1566,13 +1600,13 @@ static int mma8452_probe(struct i2c_client *client, ret = mma8452_reset(client); if (ret < 0) - return ret; + goto disable_regulators; data->data_cfg = MMA8452_DATA_CFG_FS_2G; ret = i2c_smbus_write_byte_data(client, MMA8452_DATA_CFG, data->data_cfg); if (ret < 0) - return ret; + goto disable_regulators; /* * By default set transient threshold to max to avoid events if @@ -1581,7 +1615,7 @@ static int mma8452_probe(struct i2c_client *client, ret = i2c_smbus_write_byte_data(client, MMA8452_TRANSIENT_THS, MMA8452_TRANSIENT_THS_MASK); if (ret < 0) - return ret; + goto disable_regulators; if (client->irq) { int irq2; @@ -1595,7 +1629,7 @@ static int mma8452_probe(struct i2c_client *client, MMA8452_CTRL_REG5, data->chip_info->all_events); if (ret < 0) - return ret; + goto disable_regulators; dev_dbg(&client->dev, "using interrupt line INT1\n"); } @@ -1604,11 +1638,11 @@ static int mma8452_probe(struct i2c_client *client, MMA8452_CTRL_REG4, data->chip_info->enabled_events); if (ret < 0) - return ret; + goto disable_regulators; ret = mma8452_trigger_setup(indio_dev); if (ret < 0) - return ret; + goto disable_regulators; } data->ctrl_reg1 = MMA8452_CTRL_ACTIVE | @@ -1661,12 +1695,19 @@ buffer_cleanup: trigger_cleanup: mma8452_trigger_cleanup(indio_dev); +disable_regulators: + regulator_disable(data->vddio_reg); + +disable_regulator_vdd: + regulator_disable(data->vdd_reg); + return ret; } static int mma8452_remove(struct i2c_client *client) { struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct mma8452_data *data = iio_priv(indio_dev); iio_device_unregister(indio_dev); @@ -1678,6 +1719,9 @@ static int mma8452_remove(struct i2c_client *client) mma8452_trigger_cleanup(indio_dev); mma8452_standby(iio_priv(indio_dev)); + regulator_disable(data->vddio_reg); + regulator_disable(data->vdd_reg); + return 0; } @@ -1696,6 +1740,18 @@ static int mma8452_runtime_suspend(struct device *dev) return -EAGAIN; } + ret = regulator_disable(data->vddio_reg); + if (ret) { + dev_err(dev, "failed to disable VDDIO regulator\n"); + return ret; + } + + ret = regulator_disable(data->vdd_reg); + if (ret) { + dev_err(dev, "failed to disable VDD regulator\n"); + return ret; + } + return 0; } @@ -1705,9 +1761,22 @@ static int mma8452_runtime_resume(struct device *dev) struct mma8452_data *data = iio_priv(indio_dev); int ret, sleep_val; + ret = regulator_enable(data->vdd_reg); + if (ret) { + dev_err(dev, "failed to enable VDD regulator\n"); + return ret; + } + + ret = regulator_enable(data->vddio_reg); + if (ret) { + dev_err(dev, "failed to enable VDDIO regulator\n"); + regulator_disable(data->vdd_reg); + return ret; + } + ret = mma8452_active(data); if (ret < 0) - return ret; + goto runtime_resume_failed; ret = mma8452_get_odr_index(data); sleep_val = 1000 / mma8452_samp_freq[ret][0]; @@ -1717,25 +1786,17 @@ static int mma8452_runtime_resume(struct device *dev) msleep_interruptible(sleep_val); return 0; -} -#endif -#ifdef CONFIG_PM_SLEEP -static int mma8452_suspend(struct device *dev) -{ - return mma8452_standby(iio_priv(i2c_get_clientdata( - to_i2c_client(dev)))); -} +runtime_resume_failed: + regulator_disable(data->vddio_reg); + regulator_disable(data->vdd_reg); -static int mma8452_resume(struct device *dev) -{ - return mma8452_active(iio_priv(i2c_get_clientdata( - to_i2c_client(dev)))); + return ret; } #endif static const struct dev_pm_ops mma8452_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(mma8452_suspend, mma8452_resume) + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) SET_RUNTIME_PM_OPS(mma8452_runtime_suspend, mma8452_runtime_resume, NULL) }; diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c index f7b471121508..a3c0916479fa 100644 --- a/drivers/iio/accel/st_accel_core.c +++ b/drivers/iio/accel/st_accel_core.c @@ -11,6 +11,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> +#include <linux/acpi.h> #include <linux/errno.h> #include <linux/types.h> #include <linux/mutex.h> @@ -918,12 +919,167 @@ static const struct iio_trigger_ops st_accel_trigger_ops = { #define ST_ACCEL_TRIGGER_OPS NULL #endif +static const struct iio_mount_matrix * +get_mount_matrix(const struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) +{ + struct st_sensor_data *adata = iio_priv(indio_dev); + + return adata->mount_matrix; +} + +static const struct iio_chan_spec_ext_info mount_matrix_ext_info[] = { + IIO_MOUNT_MATRIX(IIO_SHARED_BY_ALL, get_mount_matrix), + { }, +}; + +/* Read ST-specific _ONT orientation data from ACPI and generate an + * appropriate mount matrix. + */ +static int apply_acpi_orientation(struct iio_dev *indio_dev, + struct iio_chan_spec *channels) +{ +#ifdef CONFIG_ACPI + struct st_sensor_data *adata = iio_priv(indio_dev); + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; + struct acpi_device *adev; + union acpi_object *ont; + union acpi_object *elements; + acpi_status status; + int ret = -EINVAL; + unsigned int val; + int i, j; + int final_ont[3][3] = { { 0 }, }; + + /* For some reason, ST's _ONT translation does not apply directly + * to the data read from the sensor. Another translation must be + * performed first, as described by the matrix below. Perhaps + * ST required this specific translation for the first product + * where the device was mounted? + */ + const int default_ont[3][3] = { + { 0, 1, 0 }, + { -1, 0, 0 }, + { 0, 0, -1 }, + }; + + + adev = ACPI_COMPANION(adata->dev); + if (!adev) + return 0; + + /* Read _ONT data, which should be a package of 6 integers. */ + status = acpi_evaluate_object(adev->handle, "_ONT", NULL, &buffer); + if (status == AE_NOT_FOUND) { + return 0; + } else if (ACPI_FAILURE(status)) { + dev_warn(&indio_dev->dev, "failed to execute _ONT: %d\n", + status); + return status; + } + + ont = buffer.pointer; + if (ont->type != ACPI_TYPE_PACKAGE || ont->package.count != 6) + goto out; + + /* The first 3 integers provide axis order information. + * e.g. 0 1 2 would indicate normal X,Y,Z ordering. + * e.g. 1 0 2 indicates that data arrives in order Y,X,Z. + */ + elements = ont->package.elements; + for (i = 0; i < 3; i++) { + if (elements[i].type != ACPI_TYPE_INTEGER) + goto out; + + val = elements[i].integer.value; + if (val < 0 || val > 2) + goto out; + + /* Avoiding full matrix multiplication, we simply reorder the + * columns in the default_ont matrix according to the + * ordering provided by _ONT. + */ + final_ont[0][i] = default_ont[0][val]; + final_ont[1][i] = default_ont[1][val]; + final_ont[2][i] = default_ont[2][val]; + } + + /* The final 3 integers provide sign flip information. + * 0 means no change, 1 means flip. + * e.g. 0 0 1 means that Z data should be sign-flipped. + * This is applied after the axis reordering from above. + */ + elements += 3; + for (i = 0; i < 3; i++) { + if (elements[i].type != ACPI_TYPE_INTEGER) + goto out; + + val = elements[i].integer.value; + if (val != 0 && val != 1) + goto out; + if (!val) + continue; + + /* Flip the values in the indicated column */ + final_ont[0][i] *= -1; + final_ont[1][i] *= -1; + final_ont[2][i] *= -1; + } + + /* Convert our integer matrix to a string-based iio_mount_matrix */ + adata->mount_matrix = devm_kmalloc(&indio_dev->dev, + sizeof(*adata->mount_matrix), + GFP_KERNEL); + if (!adata->mount_matrix) { + ret = -ENOMEM; + goto out; + } + + for (i = 0; i < 3; i++) { + for (j = 0; j < 3; j++) { + int matrix_val = final_ont[i][j]; + char *str_value; + + switch (matrix_val) { + case -1: + str_value = "-1"; + break; + case 0: + str_value = "0"; + break; + case 1: + str_value = "1"; + break; + default: + goto out; + } + adata->mount_matrix->rotation[i * 3 + j] = str_value; + } + } + + /* Expose the mount matrix via ext_info */ + for (i = 0; i < indio_dev->num_channels; i++) + channels[i].ext_info = mount_matrix_ext_info; + + ret = 0; + dev_info(&indio_dev->dev, "computed mount matrix from ACPI\n"); + +out: + kfree(buffer.pointer); + return ret; +#else /* !CONFIG_ACPI */ + return 0; +#endif +} + int st_accel_common_probe(struct iio_dev *indio_dev) { struct st_sensor_data *adata = iio_priv(indio_dev); struct st_sensors_platform_data *pdata = (struct st_sensors_platform_data *)adata->dev->platform_data; int irq = adata->get_irq_data_ready(indio_dev); + struct iio_chan_spec *channels; + size_t channels_size; int err; indio_dev->modes = INDIO_DIRECT_MODE; @@ -942,9 +1098,22 @@ int st_accel_common_probe(struct iio_dev *indio_dev) adata->num_data_channels = ST_ACCEL_NUMBER_DATA_CHANNELS; adata->multiread_bit = adata->sensor_settings->multi_read_bit; - indio_dev->channels = adata->sensor_settings->ch; indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS; + channels_size = indio_dev->num_channels * sizeof(struct iio_chan_spec); + channels = devm_kmemdup(&indio_dev->dev, + adata->sensor_settings->ch, + channels_size, GFP_KERNEL); + if (!channels) { + err = -ENOMEM; + goto st_accel_power_off; + } + + if (apply_acpi_orientation(indio_dev, channels)) + dev_warn(&indio_dev->dev, + "failed to apply ACPI orientation data: %d\n", err); + + indio_dev->channels = channels; adata->current_fullscale = (struct st_sensor_fullscale_avl *) &adata->sensor_settings->fs.fs_avl[0]; adata->odr = adata->sensor_settings->odr.odr_avl[0].hz; diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 7a3ca4ec0cb7..5debc67df70a 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -57,18 +57,48 @@ config AD7298 module will be called ad7298. config AD7476 - tristate "Analog Devices AD7476 and similar 1-channel ADCs driver" + tristate "Analog Devices AD7476 1-channel ADCs driver and other similar devices from AD an TI" depends on SPI select IIO_BUFFER select IIO_TRIGGERED_BUFFER help - Say yes here to build support for Analog Devices AD7273, AD7274, AD7276, - AD7277, AD7278, AD7475, AD7476, AD7477, AD7478, AD7466, AD7467, AD7468, - AD7495, AD7910, AD7920, AD7920 SPI analog to digital converters (ADC). + Say yes here to build support for the following SPI analog to + digital converters (ADCs): + Analog Devices: AD7273, AD7274, AD7276, AD7277, AD7278, AD7475, + AD7476, AD7477, AD7478, AD7466, AD7467, AD7468, AD7495, AD7910, + AD7920. + Texas Instruments: ADS7866, ADS7867, ADS7868. To compile this driver as a module, choose M here: the module will be called ad7476. +config AD7606 + tristate + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + +config AD7606_IFACE_PARALLEL + tristate "Analog Devices AD7606 ADC driver with parallel interface support" + depends on HAS_IOMEM + select AD7606 + help + Say yes here to build parallel interface support for Analog Devices: + ad7605-4, ad7606, ad7606-6, ad7606-4 analog to digital converters (ADC). + + To compile this driver as a module, choose M here: the + module will be called ad7606_parallel. + +config AD7606_IFACE_SPI + tristate "Analog Devices AD7606 ADC driver with spi interface support" + depends on SPI + select AD7606 + help + Say yes here to build spi interface support for Analog Devices: + ad7605-4, ad7606, ad7606-6, ad7606-4 analog to digital converters (ADC). + + To compile this driver as a module, choose M here: the + module will be called ad7606_spi. + config AD7766 tristate "Analog Devices AD7766/AD7767 ADC driver" depends on SPI_MASTER @@ -81,6 +111,19 @@ config AD7766 To compile this driver as a module, choose M here: the module will be called ad7766. +config AD7768_1 + tristate "Analog Devices AD7768-1 ADC driver" + depends on SPI + select IIO_BUFFER + select IIO_TRIGGER + select IIO_TRIGGERED_BUFFER + help + Say yes here to build support for Analog Devices AD7768-1 SPI + simultaneously sampling sigma-delta analog to digital converter (ADC). + + To compile this driver as a module, choose M here: the module will be + called ad7768-1. + config AD7791 tristate "Analog Devices AD7791 ADC driver" depends on SPI @@ -367,6 +410,15 @@ config INA2XX_ADC Say yes here to build support for TI INA2xx family of Power Monitors. This driver is mutually exclusive with the HWMON version. +config INGENIC_ADC + tristate "Ingenic JZ47xx SoCs ADC driver" + depends on MIPS || COMPILE_TEST + help + Say yes here to build support for the Ingenic JZ47xx SoCs ADC unit. + + This driver can also be built as a module. If so, the module will be + called ingenic_adc. + config IMX7D_ADC tristate "Freescale IMX7D ADC driver" depends on ARCH_MXC || COMPILE_TEST @@ -576,6 +628,16 @@ config NAU7802 To compile this driver as a module, choose M here: the module will be called nau7802. +config NPCM_ADC + tristate "Nuvoton NPCM ADC driver" + depends on ARCH_NPCM || COMPILE_TEST + depends on HAS_IOMEM + help + Say yes here to build support for Nuvoton NPCM ADC. + + This driver can also be built as a module. If so, the module + will be called npcm_adc. + config PALMAS_GPADC tristate "TI Palmas General Purpose ADC" depends on MFD_PALMAS @@ -908,6 +970,16 @@ config TI_ADS8688 This driver can also be built as a module. If so, the module will be called ti-ads8688. +config TI_ADS124S08 + tristate "Texas Instruments ADS124S08" + depends on SPI && OF + help + If you say yes here you get support for Texas Instruments ADS124S08 + and ADS124S06 ADC chips + + This driver can also be built as a module. If so, the module will be + called ti-ads124s08. + config TI_AM335X_ADC tristate "TI's AM335X ADC driver" depends on MFD_TI_AM335X_TSCADC && HAS_DMA diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 07df37f621bd..d50eb47da484 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -11,7 +11,11 @@ obj-$(CONFIG_AD7291) += ad7291.o obj-$(CONFIG_AD7298) += ad7298.o obj-$(CONFIG_AD7923) += ad7923.o obj-$(CONFIG_AD7476) += ad7476.o +obj-$(CONFIG_AD7606_IFACE_PARALLEL) += ad7606_par.o +obj-$(CONFIG_AD7606_IFACE_SPI) += ad7606_spi.o +obj-$(CONFIG_AD7606) += ad7606.o obj-$(CONFIG_AD7766) += ad7766.o +obj-$(CONFIG_AD7768_1) += ad7768-1.o obj-$(CONFIG_AD7791) += ad7791.o obj-$(CONFIG_AD7793) += ad7793.o obj-$(CONFIG_AD7887) += ad7887.o @@ -36,6 +40,7 @@ obj-$(CONFIG_HI8435) += hi8435.o obj-$(CONFIG_HX711) += hx711.o obj-$(CONFIG_IMX7D_ADC) += imx7d_adc.o obj-$(CONFIG_INA2XX_ADC) += ina2xx-adc.o +obj-$(CONFIG_INGENIC_ADC) += ingenic-adc.o obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o obj-$(CONFIG_LPC18XX_ADC) += lpc18xx_adc.o obj-$(CONFIG_LPC32XX_ADC) += lpc32xx_adc.o @@ -55,6 +60,7 @@ obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o obj-$(CONFIG_MESON_SARADC) += meson_saradc.o obj-$(CONFIG_MXS_LRADC_ADC) += mxs-lradc-adc.o obj-$(CONFIG_NAU7802) += nau7802.o +obj-$(CONFIG_NPCM_ADC) += npcm_adc.o obj-$(CONFIG_PALMAS_GPADC) += palmas_gpadc.o obj-$(CONFIG_QCOM_SPMI_ADC5) += qcom-spmi-adc5.o obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o @@ -81,6 +87,7 @@ obj-$(CONFIG_TI_ADC161S626) += ti-adc161s626.o obj-$(CONFIG_TI_ADS1015) += ti-ads1015.o obj-$(CONFIG_TI_ADS7950) += ti-ads7950.o obj-$(CONFIG_TI_ADS8688) += ti-ads8688.o +obj-$(CONFIG_TI_ADS124S08) += ti-ads124s08.o obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o obj-$(CONFIG_TI_TLC4541) += ti-tlc4541.o obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o diff --git a/drivers/iio/adc/ad7476.c b/drivers/iio/adc/ad7476.c index 0549686b9ef8..76747488044b 100644 --- a/drivers/iio/adc/ad7476.c +++ b/drivers/iio/adc/ad7476.c @@ -59,6 +59,9 @@ enum ad7476_supported_device_ids { ID_ADC081S, ID_ADC101S, ID_ADC121S, + ID_ADS7866, + ID_ADS7867, + ID_ADS7868, }; static irqreturn_t ad7476_trigger_handler(int irq, void *p) @@ -157,6 +160,8 @@ static int ad7476_read_raw(struct iio_dev *indio_dev, #define AD7940_CHAN(bits) _AD7476_CHAN((bits), 15 - (bits), \ BIT(IIO_CHAN_INFO_RAW)) #define AD7091R_CHAN(bits) _AD7476_CHAN((bits), 16 - (bits), 0) +#define ADS786X_CHAN(bits) _AD7476_CHAN((bits), 12 - (bits), \ + BIT(IIO_CHAN_INFO_RAW)) static const struct ad7476_chip_info ad7476_chip_info_tbl[] = { [ID_AD7091R] = { @@ -209,6 +214,18 @@ static const struct ad7476_chip_info ad7476_chip_info_tbl[] = { .channel[0] = ADC081S_CHAN(12), .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), }, + [ID_ADS7866] = { + .channel[0] = ADS786X_CHAN(12), + .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), + }, + [ID_ADS7867] = { + .channel[0] = ADS786X_CHAN(10), + .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), + }, + [ID_ADS7868] = { + .channel[0] = ADS786X_CHAN(8), + .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), + }, }; static const struct iio_info ad7476_info = { @@ -314,6 +331,9 @@ static const struct spi_device_id ad7476_id[] = { {"adc081s", ID_ADC081S}, {"adc101s", ID_ADC101S}, {"adc121s", ID_ADC121S}, + {"ads7866", ID_ADS7866}, + {"ads7867", ID_ADS7867}, + {"ads7868", ID_ADS7868}, {} }; MODULE_DEVICE_TABLE(spi, ad7476_id); diff --git a/drivers/staging/iio/adc/ad7606.c b/drivers/iio/adc/ad7606.c index 7308fa8fbb4c..ebb8de03bbce 100644 --- a/drivers/staging/iio/adc/ad7606.c +++ b/drivers/iio/adc/ad7606.c @@ -1,28 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0 /* * AD7606 SPI ADC driver * * Copyright 2011 Analog Devices Inc. - * - * Licensed under the GPL-2. */ -#include <linux/interrupt.h> +#include <linux/delay.h> #include <linux/device.h> -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/sysfs.h> -#include <linux/regulator/consumer.h> #include <linux/err.h> #include <linux/gpio/consumer.h> -#include <linux/delay.h> -#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> #include <linux/module.h> +#include <linux/regulator/consumer.h> +#include <linux/sched.h> +#include <linux/slab.h> +#include <linux/sysfs.h> +#include <linux/util_macros.h> #include <linux/iio/iio.h> -#include <linux/iio/sysfs.h> #include <linux/iio/buffer.h> -#include <linux/iio/trigger_consumer.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/trigger.h> #include <linux/iio/triggered_buffer.h> +#include <linux/iio/trigger_consumer.h> #include "ad7606.h" @@ -30,8 +31,12 @@ * Scales are computed as 5000/32768 and 10000/32768 respectively, * so that when applied to the raw values they provide mV values */ -static const unsigned int scale_avail[2][2] = { - {0, 152588}, {0, 305176} +static const unsigned int scale_avail[2] = { + 152588, 305176 +}; + +static const unsigned int ad7606_oversampling_avail[7] = { + 1, 2, 4, 8, 16, 32, 64, }; static int ad7606_reset(struct ad7606_state *st) @@ -82,36 +87,24 @@ static int ad7606_read_samples(struct ad7606_state *st) static irqreturn_t ad7606_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; - struct ad7606_state *st = iio_priv(pf->indio_dev); - - gpiod_set_value(st->gpio_convst, 1); - - return IRQ_HANDLED; -} - -/** - * ad7606_poll_bh_to_ring() bh of trigger launched polling to ring buffer - * @work_s: the work struct through which this was scheduled - * - * Currently there is no option in this driver to disable the saving of - * timestamps within the ring. - * I think the one copy of this at a time was to avoid problems if the - * trigger was set far too high and the reads then locked up the computer. - **/ -static void ad7606_poll_bh_to_ring(struct work_struct *work_s) -{ - struct ad7606_state *st = container_of(work_s, struct ad7606_state, - poll_work); - struct iio_dev *indio_dev = iio_priv_to_dev(st); + struct iio_dev *indio_dev = pf->indio_dev; + struct ad7606_state *st = iio_priv(indio_dev); int ret; + mutex_lock(&st->lock); + ret = ad7606_read_samples(st); if (ret == 0) iio_push_to_buffers_with_timestamp(indio_dev, st->data, iio_get_time_ns(indio_dev)); - gpiod_set_value(st->gpio_convst, 0); iio_trigger_notify_done(indio_dev->trig); + /* The rising edge of the CONVST signal starts a new conversion. */ + gpiod_set_value(st->gpio_convst, 1); + + mutex_unlock(&st->lock); + + return IRQ_HANDLED; } static int ad7606_scan_direct(struct iio_dev *indio_dev, unsigned int ch) @@ -119,12 +112,13 @@ static int ad7606_scan_direct(struct iio_dev *indio_dev, unsigned int ch) struct ad7606_state *st = iio_priv(indio_dev); int ret; - st->done = false; gpiod_set_value(st->gpio_convst, 1); - - ret = wait_event_interruptible(st->wq_data_avail, st->done); - if (ret) + ret = wait_for_completion_timeout(&st->completion, + msecs_to_jiffies(1000)); + if (!ret) { + ret = -ETIMEDOUT; goto error_ret; + } ret = ad7606_read_samples(st); if (ret == 0) @@ -159,8 +153,8 @@ static int ad7606_read_raw(struct iio_dev *indio_dev, *val = (short)ret; return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: - *val = scale_avail[st->range][0]; - *val2 = scale_avail[st->range][1]; + *val = 0; + *val2 = scale_avail[st->range]; return IIO_VAL_INT_PLUS_MICRO; case IIO_CHAN_INFO_OVERSAMPLING_RATIO: *val = st->oversampling; @@ -176,8 +170,8 @@ static ssize_t in_voltage_scale_available_show(struct device *dev, int i, len = 0; for (i = 0; i < ARRAY_SIZE(scale_avail); i++) - len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%06u ", - scale_avail[i][0], scale_avail[i][1]); + len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ", + scale_avail[i]); buf[len - 1] = '\n'; @@ -186,18 +180,6 @@ static ssize_t in_voltage_scale_available_show(struct device *dev, static IIO_DEVICE_ATTR_RO(in_voltage_scale_available, 0); -static int ad7606_oversampling_get_index(unsigned int val) -{ - unsigned char supported[] = {1, 2, 4, 8, 16, 32, 64}; - int i; - - for (i = 0; i < ARRAY_SIZE(supported); i++) - if (val == supported[i]) - return i; - - return -EINVAL; -} - static int ad7606_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, @@ -206,36 +188,29 @@ static int ad7606_write_raw(struct iio_dev *indio_dev, { struct ad7606_state *st = iio_priv(indio_dev); DECLARE_BITMAP(values, 3); - int ret, i; + int i; switch (mask) { case IIO_CHAN_INFO_SCALE: - ret = -EINVAL; mutex_lock(&st->lock); - for (i = 0; i < ARRAY_SIZE(scale_avail); i++) - if (val2 == scale_avail[i][1]) { - gpiod_set_value(st->gpio_range, i); - st->range = i; - - ret = 0; - break; - } + i = find_closest(val2, scale_avail, ARRAY_SIZE(scale_avail)); + gpiod_set_value(st->gpio_range, i); + st->range = i; mutex_unlock(&st->lock); - return ret; + return 0; case IIO_CHAN_INFO_OVERSAMPLING_RATIO: if (val2) return -EINVAL; - ret = ad7606_oversampling_get_index(val); - if (ret < 0) - return ret; + i = find_closest(val, ad7606_oversampling_avail, + ARRAY_SIZE(ad7606_oversampling_avail)); - values[0] = ret; + values[0] = i; mutex_lock(&st->lock); - gpiod_set_array_value(3, st->gpio_os->desc, st->gpio_os->info, - values); - st->oversampling = val; + gpiod_set_array_value(ARRAY_SIZE(values), st->gpio_os->desc, + st->gpio_os->info, values); + st->oversampling = ad7606_oversampling_avail[i]; mutex_unlock(&st->lock); return 0; @@ -274,8 +249,7 @@ static const struct attribute_group ad7606_attribute_group_range = { .attrs = ad7606_attributes_range, }; -#define AD760X_CHANNEL(num, mask) \ - { \ +#define AD760X_CHANNEL(num, mask) { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ .channel = num, \ @@ -290,7 +264,7 @@ static const struct attribute_group ad7606_attribute_group_range = { .storagebits = 16, \ .endianness = IIO_CPU, \ }, \ - } +} #define AD7605_CHANNEL(num) \ AD760X_CHANNEL(num, 0) @@ -319,9 +293,7 @@ static const struct iio_chan_spec ad7606_channels[] = { }; static const struct ad7606_chip_info ad7606_chip_info_tbl[] = { - /* - * More devices added in future - */ + /* More devices added in future */ [ID_AD7605_4] = { .channels = ad7605_channels, .num_channels = 5, @@ -347,7 +319,7 @@ static int ad7606_request_gpios(struct ad7606_state *st) { struct device *dev = st->dev; - st->gpio_convst = devm_gpiod_get(dev, "conversion-start", + st->gpio_convst = devm_gpiod_get(dev, "adi,conversion-start", GPIOD_OUT_LOW); if (IS_ERR(st->gpio_convst)) return PTR_ERR(st->gpio_convst); @@ -356,7 +328,8 @@ static int ad7606_request_gpios(struct ad7606_state *st) if (IS_ERR(st->gpio_reset)) return PTR_ERR(st->gpio_reset); - st->gpio_range = devm_gpiod_get_optional(dev, "range", GPIOD_OUT_LOW); + st->gpio_range = devm_gpiod_get_optional(dev, "adi,range", + GPIOD_OUT_LOW); if (IS_ERR(st->gpio_range)) return PTR_ERR(st->gpio_range); @@ -365,7 +338,7 @@ static int ad7606_request_gpios(struct ad7606_state *st) if (IS_ERR(st->gpio_standby)) return PTR_ERR(st->gpio_standby); - st->gpio_frstdata = devm_gpiod_get_optional(dev, "first-data", + st->gpio_frstdata = devm_gpiod_get_optional(dev, "adi,first-data", GPIOD_IN); if (IS_ERR(st->gpio_frstdata)) return PTR_ERR(st->gpio_frstdata); @@ -373,13 +346,17 @@ static int ad7606_request_gpios(struct ad7606_state *st) if (!st->chip_info->has_oversampling) return 0; - st->gpio_os = devm_gpiod_get_array_optional(dev, "oversampling-ratio", + st->gpio_os = devm_gpiod_get_array_optional(dev, + "adi,oversampling-ratio", GPIOD_OUT_LOW); return PTR_ERR_OR_ZERO(st->gpio_os); } -/** - * Interrupt handler +/* + * The BUSY signal indicates when conversions are in progress, so when a rising + * edge of CONVST is applied, BUSY goes logic high and transitions low at the + * end of the entire conversion process. The falling edge of the BUSY signal + * triggers this interrupt. */ static irqreturn_t ad7606_interrupt(int irq, void *dev_id) { @@ -387,37 +364,87 @@ static irqreturn_t ad7606_interrupt(int irq, void *dev_id) struct ad7606_state *st = iio_priv(indio_dev); if (iio_buffer_enabled(indio_dev)) { - schedule_work(&st->poll_work); + gpiod_set_value(st->gpio_convst, 0); + iio_trigger_poll_chained(st->trig); } else { - st->done = true; - wake_up_interruptible(&st->wq_data_avail); + complete(&st->completion); } return IRQ_HANDLED; }; +static int ad7606_validate_trigger(struct iio_dev *indio_dev, + struct iio_trigger *trig) +{ + struct ad7606_state *st = iio_priv(indio_dev); + + if (st->trig != trig) + return -EINVAL; + + return 0; +} + +static int ad7606_buffer_postenable(struct iio_dev *indio_dev) +{ + struct ad7606_state *st = iio_priv(indio_dev); + + iio_triggered_buffer_postenable(indio_dev); + gpiod_set_value(st->gpio_convst, 1); + + return 0; +} + +static int ad7606_buffer_predisable(struct iio_dev *indio_dev) +{ + struct ad7606_state *st = iio_priv(indio_dev); + + gpiod_set_value(st->gpio_convst, 0); + + return iio_triggered_buffer_predisable(indio_dev); +} + +static const struct iio_buffer_setup_ops ad7606_buffer_ops = { + .postenable = &ad7606_buffer_postenable, + .predisable = &ad7606_buffer_predisable, +}; + static const struct iio_info ad7606_info_no_os_or_range = { .read_raw = &ad7606_read_raw, + .validate_trigger = &ad7606_validate_trigger, }; static const struct iio_info ad7606_info_os_and_range = { .read_raw = &ad7606_read_raw, .write_raw = &ad7606_write_raw, .attrs = &ad7606_attribute_group_os_and_range, + .validate_trigger = &ad7606_validate_trigger, }; static const struct iio_info ad7606_info_os = { .read_raw = &ad7606_read_raw, .write_raw = &ad7606_write_raw, .attrs = &ad7606_attribute_group_os, + .validate_trigger = &ad7606_validate_trigger, }; static const struct iio_info ad7606_info_range = { .read_raw = &ad7606_read_raw, .write_raw = &ad7606_write_raw, .attrs = &ad7606_attribute_group_range, + .validate_trigger = &ad7606_validate_trigger, +}; + +static const struct iio_trigger_ops ad7606_trigger_ops = { + .validate_device = iio_trigger_validate_own_device, }; +static void ad7606_regulator_disable(void *data) +{ + struct ad7606_state *st = data; + + regulator_disable(st->reg); +} + int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, const char *name, unsigned int id, const struct ad7606_bus_ops *bops) @@ -431,6 +458,7 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, return -ENOMEM; st = iio_priv(indio_dev); + dev_set_drvdata(dev, indio_dev); st->dev = dev; mutex_init(&st->lock); @@ -439,7 +467,6 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, /* tied to logic low, analog input range is +/- 5V */ st->range = 0; st->oversampling = 1; - INIT_WORK(&st->poll_work, &ad7606_poll_bh_to_ring); st->reg = devm_regulator_get(dev, "avcc"); if (IS_ERR(st->reg)) @@ -451,11 +478,15 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, return ret; } + ret = devm_add_action_or_reset(dev, ad7606_regulator_disable, st); + if (ret) + return ret; + st->chip_info = &ad7606_chip_info_tbl[id]; ret = ad7606_request_gpios(st); if (ret) - goto error_disable_reg; + return ret; indio_dev->dev.parent = dev; if (st->gpio_os) { @@ -474,56 +505,45 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, indio_dev->channels = st->chip_info->channels; indio_dev->num_channels = st->chip_info->num_channels; - init_waitqueue_head(&st->wq_data_avail); + init_completion(&st->completion); ret = ad7606_reset(st); if (ret) dev_warn(st->dev, "failed to RESET: no RESET GPIO specified\n"); - ret = request_irq(irq, ad7606_interrupt, IRQF_TRIGGER_FALLING, name, - indio_dev); - if (ret) - goto error_disable_reg; - - ret = iio_triggered_buffer_setup(indio_dev, &ad7606_trigger_handler, - NULL, NULL); - if (ret) - goto error_free_irq; + st->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", + indio_dev->name, indio_dev->id); + if (!st->trig) + return -ENOMEM; - ret = iio_device_register(indio_dev); + st->trig->ops = &ad7606_trigger_ops; + st->trig->dev.parent = dev; + iio_trigger_set_drvdata(st->trig, indio_dev); + ret = devm_iio_trigger_register(dev, st->trig); if (ret) - goto error_unregister_ring; + return ret; - dev_set_drvdata(dev, indio_dev); + indio_dev->trig = iio_trigger_get(st->trig); - return 0; -error_unregister_ring: - iio_triggered_buffer_cleanup(indio_dev); + ret = devm_request_threaded_irq(dev, irq, + NULL, + &ad7606_interrupt, + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + name, indio_dev); + if (ret) + return ret; -error_free_irq: - free_irq(irq, indio_dev); + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, + &iio_pollfunc_store_time, + &ad7606_trigger_handler, + &ad7606_buffer_ops); + if (ret) + return ret; -error_disable_reg: - regulator_disable(st->reg); - return ret; + return devm_iio_device_register(dev, indio_dev); } EXPORT_SYMBOL_GPL(ad7606_probe); -int ad7606_remove(struct device *dev, int irq) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad7606_state *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - iio_triggered_buffer_cleanup(indio_dev); - - free_irq(irq, indio_dev); - regulator_disable(st->reg); - - return 0; -} -EXPORT_SYMBOL_GPL(ad7606_remove); - #ifdef CONFIG_PM_SLEEP static int ad7606_suspend(struct device *dev) diff --git a/drivers/staging/iio/adc/ad7606.h b/drivers/iio/adc/ad7606.h index 86188054b60b..5d12410f68e1 100644 --- a/drivers/staging/iio/adc/ad7606.h +++ b/drivers/iio/adc/ad7606.h @@ -1,9 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * AD7606 ADC driver * * Copyright 2011 Analog Devices Inc. - * - * Licensed under the GPL-2. */ #ifndef IIO_ADC_AD7606_H_ @@ -15,7 +14,6 @@ * @num_channels: number of channels * @has_oversampling: whether the device has oversampling support */ - struct ad7606_chip_info { const struct iio_chan_spec *channels; unsigned int num_channels; @@ -27,13 +25,9 @@ struct ad7606_chip_info { * @dev pointer to kernel device * @chip_info entry in the table of chips that describes this device * @reg regulator info for the the power supply of the device - * @poll_work work struct for continuously reading data from the device - * into an IIO triggered buffer - * @wq_data_avail wait queue struct for buffer mode * @bops bus operations (SPI or parallel) * @range voltage range selection, selects which scale to apply * @oversampling oversampling selection - * @done marks whether reading data is done * @base_address address from where to read data in parallel operation * @lock protect sensor state from concurrent accesses to GPIOs * @gpio_convst GPIO descriptor for conversion start signal (CONVST) @@ -44,19 +38,17 @@ struct ad7606_chip_info { * @gpio_frstdata GPIO descriptor for reading from device when data * is being read on the first channel * @gpio_os GPIO descriptors to control oversampling on the device + * @complete completion to indicate end of conversion + * @trig The IIO trigger associated with the device. * @data buffer for reading data from the device */ - struct ad7606_state { struct device *dev; const struct ad7606_chip_info *chip_info; struct regulator *reg; - struct work_struct poll_work; - wait_queue_head_t wq_data_avail; const struct ad7606_bus_ops *bops; unsigned int range; unsigned int oversampling; - bool done; void __iomem *base_address; struct mutex lock; /* protect sensor state */ @@ -66,6 +58,8 @@ struct ad7606_state { struct gpio_desc *gpio_standby; struct gpio_desc *gpio_frstdata; struct gpio_descs *gpio_os; + struct iio_trigger *trig; + struct completion completion; /* * DMA (thus cache coherency maintenance) requires the @@ -87,7 +81,6 @@ struct ad7606_bus_ops { int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, const char *name, unsigned int id, const struct ad7606_bus_ops *bops); -int ad7606_remove(struct device *dev, int irq); enum ad7606_supported_device_ids { ID_AD7605_4, diff --git a/drivers/staging/iio/adc/ad7606_par.c b/drivers/iio/adc/ad7606_par.c index 8bd86e727b02..1b08028facde 100644 --- a/drivers/staging/iio/adc/ad7606_par.c +++ b/drivers/iio/adc/ad7606_par.c @@ -1,9 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * AD7606 Parallel Interface ADC driver * * Copyright 2011 Analog Devices Inc. - * - * Licensed under the GPL-2. */ #include <linux/module.h> @@ -27,7 +26,7 @@ static int ad7606_par16_read_block(struct device *dev, } static const struct ad7606_bus_ops ad7606_par16_bops = { - .read_block = ad7606_par16_read_block, + .read_block = ad7606_par16_read_block, }; static int ad7606_par8_read_block(struct device *dev, @@ -42,7 +41,7 @@ static int ad7606_par8_read_block(struct device *dev, } static const struct ad7606_bus_ops ad7606_par8_bops = { - .read_block = ad7606_par8_read_block, + .read_block = ad7606_par8_read_block, }; static int ad7606_par_probe(struct platform_device *pdev) @@ -72,40 +71,33 @@ static int ad7606_par_probe(struct platform_device *pdev) &ad7606_par8_bops); } -static int ad7606_par_remove(struct platform_device *pdev) -{ - return ad7606_remove(&pdev->dev, platform_get_irq(pdev, 0)); -} - static const struct platform_device_id ad7606_driver_ids[] = { - { - .name = "ad7605-4", - .driver_data = ID_AD7605_4, - }, { - .name = "ad7606-8", - .driver_data = ID_AD7606_8, - }, { - .name = "ad7606-6", - .driver_data = ID_AD7606_6, - }, { - .name = "ad7606-4", - .driver_data = ID_AD7606_4, - }, + { .name = "ad7605-4", .driver_data = ID_AD7605_4, }, + { .name = "ad7606-4", .driver_data = ID_AD7606_4, }, + { .name = "ad7606-6", .driver_data = ID_AD7606_6, }, + { .name = "ad7606-8", .driver_data = ID_AD7606_8, }, { } }; - MODULE_DEVICE_TABLE(platform, ad7606_driver_ids); +static const struct of_device_id ad7606_of_match[] = { + { .compatible = "adi,ad7605-4" }, + { .compatible = "adi,ad7606-4" }, + { .compatible = "adi,ad7606-6" }, + { .compatible = "adi,ad7606-8" }, + { }, +}; +MODULE_DEVICE_TABLE(of, ad7606_of_match); + static struct platform_driver ad7606_driver = { .probe = ad7606_par_probe, - .remove = ad7606_par_remove, .id_table = ad7606_driver_ids, .driver = { - .name = "ad7606", - .pm = AD7606_PM_OPS, + .name = "ad7606", + .pm = AD7606_PM_OPS, + .of_match_table = ad7606_of_match, }, }; - module_platform_driver(ad7606_driver); MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>"); diff --git a/drivers/staging/iio/adc/ad7606_spi.c b/drivers/iio/adc/ad7606_spi.c index b76ca5a8c059..4fd0ec36a086 100644 --- a/drivers/staging/iio/adc/ad7606_spi.c +++ b/drivers/iio/adc/ad7606_spi.c @@ -1,9 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * AD7606 SPI ADC driver * * Copyright 2011 Analog Devices Inc. - * - * Licensed under the GPL-2. */ #include <linux/module.h> @@ -37,7 +36,7 @@ static int ad7606_spi_read_block(struct device *dev, } static const struct ad7606_bus_ops ad7606_spi_bops = { - .read_block = ad7606_spi_read_block, + .read_block = ad7606_spi_read_block, }; static int ad7606_spi_probe(struct spi_device *spi) @@ -49,28 +48,32 @@ static int ad7606_spi_probe(struct spi_device *spi) &ad7606_spi_bops); } -static int ad7606_spi_remove(struct spi_device *spi) -{ - return ad7606_remove(&spi->dev, spi->irq); -} - -static const struct spi_device_id ad7606_id[] = { - {"ad7605-4", ID_AD7605_4}, - {"ad7606-8", ID_AD7606_8}, - {"ad7606-6", ID_AD7606_6}, - {"ad7606-4", ID_AD7606_4}, +static const struct spi_device_id ad7606_id_table[] = { + { "ad7605-4", ID_AD7605_4 }, + { "ad7606-4", ID_AD7606_4 }, + { "ad7606-6", ID_AD7606_6 }, + { "ad7606-8", ID_AD7606_8 }, {} }; -MODULE_DEVICE_TABLE(spi, ad7606_id); +MODULE_DEVICE_TABLE(spi, ad7606_id_table); + +static const struct of_device_id ad7606_of_match[] = { + { .compatible = "adi,ad7605-4" }, + { .compatible = "adi,ad7606-4" }, + { .compatible = "adi,ad7606-6" }, + { .compatible = "adi,ad7606-8" }, + { }, +}; +MODULE_DEVICE_TABLE(of, ad7606_of_match); static struct spi_driver ad7606_driver = { .driver = { .name = "ad7606", + .of_match_table = ad7606_of_match, .pm = AD7606_PM_OPS, }, .probe = ad7606_spi_probe, - .remove = ad7606_spi_remove, - .id_table = ad7606_id, + .id_table = ad7606_id_table, }; module_spi_driver(ad7606_driver); diff --git a/drivers/iio/adc/ad7768-1.c b/drivers/iio/adc/ad7768-1.c new file mode 100644 index 000000000000..0d132708c429 --- /dev/null +++ b/drivers/iio/adc/ad7768-1.c @@ -0,0 +1,655 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Analog Devices AD7768-1 SPI ADC driver + * + * Copyright 2017 Analog Devices Inc. + */ +#include <linux/bitfield.h> +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/gpio/consumer.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/regulator/consumer.h> +#include <linux/sysfs.h> +#include <linux/spi/spi.h> + +#include <linux/iio/buffer.h> +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/trigger.h> +#include <linux/iio/triggered_buffer.h> +#include <linux/iio/trigger_consumer.h> + +/* AD7768 registers definition */ +#define AD7768_REG_CHIP_TYPE 0x3 +#define AD7768_REG_PROD_ID_L 0x4 +#define AD7768_REG_PROD_ID_H 0x5 +#define AD7768_REG_CHIP_GRADE 0x6 +#define AD7768_REG_SCRATCH_PAD 0x0A +#define AD7768_REG_VENDOR_L 0x0C +#define AD7768_REG_VENDOR_H 0x0D +#define AD7768_REG_INTERFACE_FORMAT 0x14 +#define AD7768_REG_POWER_CLOCK 0x15 +#define AD7768_REG_ANALOG 0x16 +#define AD7768_REG_ANALOG2 0x17 +#define AD7768_REG_CONVERSION 0x18 +#define AD7768_REG_DIGITAL_FILTER 0x19 +#define AD7768_REG_SINC3_DEC_RATE_MSB 0x1A +#define AD7768_REG_SINC3_DEC_RATE_LSB 0x1B +#define AD7768_REG_DUTY_CYCLE_RATIO 0x1C +#define AD7768_REG_SYNC_RESET 0x1D +#define AD7768_REG_GPIO_CONTROL 0x1E +#define AD7768_REG_GPIO_WRITE 0x1F +#define AD7768_REG_GPIO_READ 0x20 +#define AD7768_REG_OFFSET_HI 0x21 +#define AD7768_REG_OFFSET_MID 0x22 +#define AD7768_REG_OFFSET_LO 0x23 +#define AD7768_REG_GAIN_HI 0x24 +#define AD7768_REG_GAIN_MID 0x25 +#define AD7768_REG_GAIN_LO 0x26 +#define AD7768_REG_SPI_DIAG_ENABLE 0x28 +#define AD7768_REG_ADC_DIAG_ENABLE 0x29 +#define AD7768_REG_DIG_DIAG_ENABLE 0x2A +#define AD7768_REG_ADC_DATA 0x2C +#define AD7768_REG_MASTER_STATUS 0x2D +#define AD7768_REG_SPI_DIAG_STATUS 0x2E +#define AD7768_REG_ADC_DIAG_STATUS 0x2F +#define AD7768_REG_DIG_DIAG_STATUS 0x30 +#define AD7768_REG_MCLK_COUNTER 0x31 + +/* AD7768_REG_POWER_CLOCK */ +#define AD7768_PWR_MCLK_DIV_MSK GENMASK(5, 4) +#define AD7768_PWR_MCLK_DIV(x) FIELD_PREP(AD7768_PWR_MCLK_DIV_MSK, x) +#define AD7768_PWR_PWRMODE_MSK GENMASK(1, 0) +#define AD7768_PWR_PWRMODE(x) FIELD_PREP(AD7768_PWR_PWRMODE_MSK, x) + +/* AD7768_REG_DIGITAL_FILTER */ +#define AD7768_DIG_FIL_FIL_MSK GENMASK(6, 4) +#define AD7768_DIG_FIL_FIL(x) FIELD_PREP(AD7768_DIG_FIL_FIL_MSK, x) +#define AD7768_DIG_FIL_DEC_MSK GENMASK(2, 0) +#define AD7768_DIG_FIL_DEC_RATE(x) FIELD_PREP(AD7768_DIG_FIL_DEC_MSK, x) + +/* AD7768_REG_CONVERSION */ +#define AD7768_CONV_MODE_MSK GENMASK(2, 0) +#define AD7768_CONV_MODE(x) FIELD_PREP(AD7768_CONV_MODE_MSK, x) + +#define AD7768_RD_FLAG_MSK(x) (BIT(6) | ((x) & 0x3F)) +#define AD7768_WR_FLAG_MSK(x) ((x) & 0x3F) + +enum ad7768_conv_mode { + AD7768_CONTINUOUS, + AD7768_ONE_SHOT, + AD7768_SINGLE, + AD7768_PERIODIC, + AD7768_STANDBY +}; + +enum ad7768_pwrmode { + AD7768_ECO_MODE = 0, + AD7768_MED_MODE = 2, + AD7768_FAST_MODE = 3 +}; + +enum ad7768_mclk_div { + AD7768_MCLK_DIV_16, + AD7768_MCLK_DIV_8, + AD7768_MCLK_DIV_4, + AD7768_MCLK_DIV_2 +}; + +enum ad7768_dec_rate { + AD7768_DEC_RATE_32 = 0, + AD7768_DEC_RATE_64 = 1, + AD7768_DEC_RATE_128 = 2, + AD7768_DEC_RATE_256 = 3, + AD7768_DEC_RATE_512 = 4, + AD7768_DEC_RATE_1024 = 5, + AD7768_DEC_RATE_8 = 9, + AD7768_DEC_RATE_16 = 10 +}; + +struct ad7768_clk_configuration { + enum ad7768_mclk_div mclk_div; + enum ad7768_dec_rate dec_rate; + unsigned int clk_div; + enum ad7768_pwrmode pwrmode; +}; + +static const struct ad7768_clk_configuration ad7768_clk_config[] = { + { AD7768_MCLK_DIV_2, AD7768_DEC_RATE_8, 16, AD7768_FAST_MODE }, + { AD7768_MCLK_DIV_2, AD7768_DEC_RATE_16, 32, AD7768_FAST_MODE }, + { AD7768_MCLK_DIV_2, AD7768_DEC_RATE_32, 64, AD7768_FAST_MODE }, + { AD7768_MCLK_DIV_2, AD7768_DEC_RATE_64, 128, AD7768_FAST_MODE }, + { AD7768_MCLK_DIV_2, AD7768_DEC_RATE_128, 256, AD7768_FAST_MODE }, + { AD7768_MCLK_DIV_4, AD7768_DEC_RATE_128, 512, AD7768_MED_MODE }, + { AD7768_MCLK_DIV_4, AD7768_DEC_RATE_256, 1024, AD7768_MED_MODE }, + { AD7768_MCLK_DIV_4, AD7768_DEC_RATE_512, 2048, AD7768_MED_MODE }, + { AD7768_MCLK_DIV_4, AD7768_DEC_RATE_1024, 4096, AD7768_MED_MODE }, + { AD7768_MCLK_DIV_8, AD7768_DEC_RATE_1024, 8192, AD7768_MED_MODE }, + { AD7768_MCLK_DIV_16, AD7768_DEC_RATE_1024, 16384, AD7768_ECO_MODE }, +}; + +static const struct iio_chan_spec ad7768_channels[] = { + { + .type = IIO_VOLTAGE, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), + .indexed = 1, + .channel = 0, + .scan_index = 0, + .scan_type = { + .sign = 'u', + .realbits = 24, + .storagebits = 32, + .shift = 8, + .endianness = IIO_BE, + }, + }, +}; + +struct ad7768_state { + struct spi_device *spi; + struct regulator *vref; + struct mutex lock; + struct clk *mclk; + unsigned int mclk_freq; + unsigned int samp_freq; + struct completion completion; + struct iio_trigger *trig; + struct gpio_desc *gpio_sync_in; + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + union { + __be32 d32; + u8 d8[2]; + } data ____cacheline_aligned; +}; + +static int ad7768_spi_reg_read(struct ad7768_state *st, unsigned int addr, + unsigned int len) +{ + unsigned int shift; + int ret; + + shift = 32 - (8 * len); + st->data.d8[0] = AD7768_RD_FLAG_MSK(addr); + + ret = spi_write_then_read(st->spi, st->data.d8, 1, + &st->data.d32, len); + if (ret < 0) + return ret; + + return (be32_to_cpu(st->data.d32) >> shift); +} + +static int ad7768_spi_reg_write(struct ad7768_state *st, + unsigned int addr, + unsigned int val) +{ + st->data.d8[0] = AD7768_WR_FLAG_MSK(addr); + st->data.d8[1] = val & 0xFF; + + return spi_write(st->spi, st->data.d8, 2); +} + +static int ad7768_set_mode(struct ad7768_state *st, + enum ad7768_conv_mode mode) +{ + int regval; + + regval = ad7768_spi_reg_read(st, AD7768_REG_CONVERSION, 1); + if (regval < 0) + return regval; + + regval &= ~AD7768_CONV_MODE_MSK; + regval |= AD7768_CONV_MODE(mode); + + return ad7768_spi_reg_write(st, AD7768_REG_CONVERSION, regval); +} + +static int ad7768_scan_direct(struct iio_dev *indio_dev) +{ + struct ad7768_state *st = iio_priv(indio_dev); + int readval, ret; + + reinit_completion(&st->completion); + + ret = ad7768_set_mode(st, AD7768_ONE_SHOT); + if (ret < 0) + return ret; + + ret = wait_for_completion_timeout(&st->completion, + msecs_to_jiffies(1000)); + if (!ret) + return -ETIMEDOUT; + + readval = ad7768_spi_reg_read(st, AD7768_REG_ADC_DATA, 3); + if (readval < 0) + return readval; + /* + * Any SPI configuration of the AD7768-1 can only be + * performed in continuous conversion mode. + */ + ret = ad7768_set_mode(st, AD7768_CONTINUOUS); + if (ret < 0) + return ret; + + return readval; +} + +static int ad7768_reg_access(struct iio_dev *indio_dev, + unsigned int reg, + unsigned int writeval, + unsigned int *readval) +{ + struct ad7768_state *st = iio_priv(indio_dev); + int ret; + + mutex_lock(&st->lock); + if (readval) { + ret = ad7768_spi_reg_read(st, reg, 1); + if (ret < 0) + goto err_unlock; + *readval = ret; + ret = 0; + } else { + ret = ad7768_spi_reg_write(st, reg, writeval); + } +err_unlock: + mutex_unlock(&st->lock); + + return ret; +} + +static int ad7768_set_dig_fil(struct ad7768_state *st, + enum ad7768_dec_rate dec_rate) +{ + unsigned int mode; + int ret; + + if (dec_rate == AD7768_DEC_RATE_8 || dec_rate == AD7768_DEC_RATE_16) + mode = AD7768_DIG_FIL_FIL(dec_rate); + else + mode = AD7768_DIG_FIL_DEC_RATE(dec_rate); + + ret = ad7768_spi_reg_write(st, AD7768_REG_DIGITAL_FILTER, mode); + if (ret < 0) + return ret; + + /* A sync-in pulse is required every time the filter dec rate changes */ + gpiod_set_value(st->gpio_sync_in, 1); + gpiod_set_value(st->gpio_sync_in, 0); + + return 0; +} + +static int ad7768_set_freq(struct ad7768_state *st, + unsigned int freq) +{ + unsigned int diff_new, diff_old, pwr_mode, i, idx; + int res, ret; + + diff_old = U32_MAX; + idx = 0; + + res = DIV_ROUND_CLOSEST(st->mclk_freq, freq); + + /* Find the closest match for the desired sampling frequency */ + for (i = 0; i < ARRAY_SIZE(ad7768_clk_config); i++) { + diff_new = abs(res - ad7768_clk_config[i].clk_div); + if (diff_new < diff_old) { + diff_old = diff_new; + idx = i; + } + } + + /* + * Set both the mclk_div and pwrmode with a single write to the + * POWER_CLOCK register + */ + pwr_mode = AD7768_PWR_MCLK_DIV(ad7768_clk_config[idx].mclk_div) | + AD7768_PWR_PWRMODE(ad7768_clk_config[idx].pwrmode); + ret = ad7768_spi_reg_write(st, AD7768_REG_POWER_CLOCK, pwr_mode); + if (ret < 0) + return ret; + + ret = ad7768_set_dig_fil(st, ad7768_clk_config[idx].dec_rate); + if (ret < 0) + return ret; + + st->samp_freq = DIV_ROUND_CLOSEST(st->mclk_freq, + ad7768_clk_config[idx].clk_div); + + return 0; +} + +static ssize_t ad7768_sampling_freq_avail(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct ad7768_state *st = iio_priv(indio_dev); + unsigned int freq; + int i, len = 0; + + for (i = 0; i < ARRAY_SIZE(ad7768_clk_config); i++) { + freq = DIV_ROUND_CLOSEST(st->mclk_freq, + ad7768_clk_config[i].clk_div); + len += scnprintf(buf + len, PAGE_SIZE - len, "%d ", freq); + } + + buf[len - 1] = '\n'; + + return len; +} + +static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(ad7768_sampling_freq_avail); + +static int ad7768_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long info) +{ + struct ad7768_state *st = iio_priv(indio_dev); + int scale_uv, ret; + + switch (info) { + case IIO_CHAN_INFO_RAW: + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + + ret = ad7768_scan_direct(indio_dev); + if (ret >= 0) + *val = ret; + + iio_device_release_direct_mode(indio_dev); + if (ret < 0) + return ret; + + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + scale_uv = regulator_get_voltage(st->vref); + if (scale_uv < 0) + return scale_uv; + + *val = (scale_uv * 2) / 1000; + *val2 = chan->scan_type.realbits; + + return IIO_VAL_FRACTIONAL_LOG2; + + case IIO_CHAN_INFO_SAMP_FREQ: + *val = st->samp_freq; + + return IIO_VAL_INT; + } + + return -EINVAL; +} + +static int ad7768_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long info) +{ + struct ad7768_state *st = iio_priv(indio_dev); + + switch (info) { + case IIO_CHAN_INFO_SAMP_FREQ: + return ad7768_set_freq(st, val); + default: + return -EINVAL; + } +} + +static struct attribute *ad7768_attributes[] = { + &iio_dev_attr_sampling_frequency_available.dev_attr.attr, + NULL +}; + +static const struct attribute_group ad7768_group = { + .attrs = ad7768_attributes, +}; + +static const struct iio_info ad7768_info = { + .attrs = &ad7768_group, + .read_raw = &ad7768_read_raw, + .write_raw = &ad7768_write_raw, + .debugfs_reg_access = &ad7768_reg_access, +}; + +static int ad7768_setup(struct ad7768_state *st) +{ + int ret; + + /* + * Two writes to the SPI_RESET[1:0] bits are required to initiate + * a software reset. The bits must first be set to 11, and then + * to 10. When the sequence is detected, the reset occurs. + * See the datasheet, page 70. + */ + ret = ad7768_spi_reg_write(st, AD7768_REG_SYNC_RESET, 0x3); + if (ret) + return ret; + + ret = ad7768_spi_reg_write(st, AD7768_REG_SYNC_RESET, 0x2); + if (ret) + return ret; + + st->gpio_sync_in = devm_gpiod_get(&st->spi->dev, "adi,sync-in", + GPIOD_OUT_LOW); + if (IS_ERR(st->gpio_sync_in)) + return PTR_ERR(st->gpio_sync_in); + + /* Set the default sampling frequency to 32000 kSPS */ + return ad7768_set_freq(st, 32000); +} + +static irqreturn_t ad7768_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct ad7768_state *st = iio_priv(indio_dev); + int ret; + + mutex_lock(&st->lock); + + ret = spi_read(st->spi, &st->data.d32, 3); + if (ret < 0) + goto err_unlock; + + iio_push_to_buffers_with_timestamp(indio_dev, &st->data.d32, + iio_get_time_ns(indio_dev)); + + iio_trigger_notify_done(indio_dev->trig); +err_unlock: + mutex_unlock(&st->lock); + + return IRQ_HANDLED; +} + +static irqreturn_t ad7768_interrupt(int irq, void *dev_id) +{ + struct iio_dev *indio_dev = dev_id; + struct ad7768_state *st = iio_priv(indio_dev); + + if (iio_buffer_enabled(indio_dev)) + iio_trigger_poll(st->trig); + else + complete(&st->completion); + + return IRQ_HANDLED; +}; + +static int ad7768_buffer_postenable(struct iio_dev *indio_dev) +{ + struct ad7768_state *st = iio_priv(indio_dev); + + iio_triggered_buffer_postenable(indio_dev); + /* + * Write a 1 to the LSB of the INTERFACE_FORMAT register to enter + * continuous read mode. Subsequent data reads do not require an + * initial 8-bit write to query the ADC_DATA register. + */ + return ad7768_spi_reg_write(st, AD7768_REG_INTERFACE_FORMAT, 0x01); +} + +static int ad7768_buffer_predisable(struct iio_dev *indio_dev) +{ + struct ad7768_state *st = iio_priv(indio_dev); + int ret; + + /* + * To exit continuous read mode, perform a single read of the ADC_DATA + * reg (0x2C), which allows further configuration of the device. + */ + ret = ad7768_spi_reg_read(st, AD7768_REG_ADC_DATA, 3); + if (ret < 0) + return ret; + + return iio_triggered_buffer_predisable(indio_dev); +} + +static const struct iio_buffer_setup_ops ad7768_buffer_ops = { + .postenable = &ad7768_buffer_postenable, + .predisable = &ad7768_buffer_predisable, +}; + +static const struct iio_trigger_ops ad7768_trigger_ops = { + .validate_device = iio_trigger_validate_own_device, +}; + +static void ad7768_regulator_disable(void *data) +{ + struct ad7768_state *st = data; + + regulator_disable(st->vref); +} + +static void ad7768_clk_disable(void *data) +{ + struct ad7768_state *st = data; + + clk_disable_unprepare(st->mclk); +} + +static int ad7768_probe(struct spi_device *spi) +{ + struct ad7768_state *st; + struct iio_dev *indio_dev; + 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; + + st->vref = devm_regulator_get(&spi->dev, "vref"); + if (IS_ERR(st->vref)) + return PTR_ERR(st->vref); + + ret = regulator_enable(st->vref); + if (ret) { + dev_err(&spi->dev, "Failed to enable specified vref supply\n"); + return ret; + } + + ret = devm_add_action_or_reset(&spi->dev, ad7768_regulator_disable, st); + if (ret) + return ret; + + st->mclk = devm_clk_get(&spi->dev, "mclk"); + if (IS_ERR(st->mclk)) + return PTR_ERR(st->mclk); + + ret = clk_prepare_enable(st->mclk); + if (ret < 0) + return ret; + + ret = devm_add_action_or_reset(&spi->dev, ad7768_clk_disable, st); + if (ret) + return ret; + + st->mclk_freq = clk_get_rate(st->mclk); + + spi_set_drvdata(spi, indio_dev); + mutex_init(&st->lock); + + indio_dev->channels = ad7768_channels; + indio_dev->num_channels = ARRAY_SIZE(ad7768_channels); + indio_dev->dev.parent = &spi->dev; + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->info = &ad7768_info; + indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_TRIGGERED; + + ret = ad7768_setup(st); + if (ret < 0) { + dev_err(&spi->dev, "AD7768 setup failed\n"); + return ret; + } + + st->trig = devm_iio_trigger_alloc(&spi->dev, "%s-dev%d", + indio_dev->name, indio_dev->id); + if (!st->trig) + return -ENOMEM; + + st->trig->ops = &ad7768_trigger_ops; + st->trig->dev.parent = &spi->dev; + iio_trigger_set_drvdata(st->trig, indio_dev); + ret = devm_iio_trigger_register(&spi->dev, st->trig); + if (ret) + return ret; + + indio_dev->trig = iio_trigger_get(st->trig); + + init_completion(&st->completion); + + ret = devm_request_irq(&spi->dev, spi->irq, + &ad7768_interrupt, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + indio_dev->name, indio_dev); + if (ret) + return ret; + + ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, + &iio_pollfunc_store_time, + &ad7768_trigger_handler, + &ad7768_buffer_ops); + if (ret) + return ret; + + return devm_iio_device_register(&spi->dev, indio_dev); +} + +static const struct spi_device_id ad7768_id_table[] = { + { "ad7768-1", 0 }, + {} +}; +MODULE_DEVICE_TABLE(spi, ad7768_id_table); + +static const struct of_device_id ad7768_of_match[] = { + { .compatible = "adi,ad7768-1" }, + { }, +}; +MODULE_DEVICE_TABLE(of, ad7768_of_match); + +static struct spi_driver ad7768_driver = { + .driver = { + .name = "ad7768-1", + .of_match_table = ad7768_of_match, + }, + .probe = ad7768_probe, + .id_table = ad7768_id_table, +}; +module_spi_driver(ad7768_driver); + +MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>"); +MODULE_DESCRIPTION("Analog Devices AD7768-1 ADC driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c index fa2d2b5767f3..1ca2c4d39f87 100644 --- a/drivers/iio/adc/exynos_adc.c +++ b/drivers/iio/adc/exynos_adc.c @@ -115,6 +115,7 @@ #define MAX_ADC_V2_CHANNELS 10 #define MAX_ADC_V1_CHANNELS 8 #define MAX_EXYNOS3250_ADC_CHANNELS 2 +#define MAX_EXYNOS4212_ADC_CHANNELS 4 #define MAX_S5PV210_ADC_CHANNELS 10 /* Bit definitions common for ADC_V1 and ADC_V2 */ @@ -271,6 +272,19 @@ static void exynos_adc_v1_start_conv(struct exynos_adc *info, writel(con1 | ADC_CON_EN_START, ADC_V1_CON(info->regs)); } +/* Exynos4212 and 4412 is like ADCv1 but with four channels only */ +static const struct exynos_adc_data exynos4212_adc_data = { + .num_channels = MAX_EXYNOS4212_ADC_CHANNELS, + .mask = ADC_DATX_MASK, /* 12 bit ADC resolution */ + .needs_adc_phy = true, + .phy_offset = EXYNOS_ADCV1_PHY_OFFSET, + + .init_hw = exynos_adc_v1_init_hw, + .exit_hw = exynos_adc_v1_exit_hw, + .clear_irq = exynos_adc_v1_clear_irq, + .start_conv = exynos_adc_v1_start_conv, +}; + static const struct exynos_adc_data exynos_adc_v1_data = { .num_channels = MAX_ADC_V1_CHANNELS, .mask = ADC_DATX_MASK, /* 12 bit ADC resolution */ @@ -493,6 +507,9 @@ static const struct of_device_id exynos_adc_match[] = { .compatible = "samsung,s5pv210-adc", .data = &exynos_adc_s5pv210_data, }, { + .compatible = "samsung,exynos4212-adc", + .data = &exynos4212_adc_data, + }, { .compatible = "samsung,exynos-adc-v1", .data = &exynos_adc_v1_data, }, { @@ -929,7 +946,7 @@ static int exynos_adc_remove(struct platform_device *pdev) struct iio_dev *indio_dev = platform_get_drvdata(pdev); struct exynos_adc *info = iio_priv(indio_dev); - if (IS_REACHABLE(CONFIG_INPUT)) { + if (IS_REACHABLE(CONFIG_INPUT) && info->input) { free_irq(info->tsirq, info); input_unregister_device(info->input); } diff --git a/drivers/iio/adc/ingenic-adc.c b/drivers/iio/adc/ingenic-adc.c new file mode 100644 index 000000000000..6ee1673deb0d --- /dev/null +++ b/drivers/iio/adc/ingenic-adc.c @@ -0,0 +1,364 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ADC driver for the Ingenic JZ47xx SoCs + * Copyright (c) 2019 Artur Rojek <contact@artur-rojek.eu> + * + * based on drivers/mfd/jz4740-adc.c + */ + +#include <dt-bindings/iio/adc/ingenic,adc.h> +#include <linux/clk.h> +#include <linux/iio/iio.h> +#include <linux/io.h> +#include <linux/iopoll.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/platform_device.h> + +#define JZ_ADC_REG_ENABLE 0x00 +#define JZ_ADC_REG_CFG 0x04 +#define JZ_ADC_REG_CTRL 0x08 +#define JZ_ADC_REG_STATUS 0x0c +#define JZ_ADC_REG_ADTCH 0x18 +#define JZ_ADC_REG_ADBDAT 0x1c +#define JZ_ADC_REG_ADSDAT 0x20 + +#define JZ_ADC_REG_CFG_BAT_MD BIT(4) + +#define JZ_ADC_AUX_VREF 3300 +#define JZ_ADC_AUX_VREF_BITS 12 +#define JZ_ADC_BATTERY_LOW_VREF 2500 +#define JZ_ADC_BATTERY_LOW_VREF_BITS 12 +#define JZ4725B_ADC_BATTERY_HIGH_VREF 7500 +#define JZ4725B_ADC_BATTERY_HIGH_VREF_BITS 10 +#define JZ4740_ADC_BATTERY_HIGH_VREF (7500 * 0.986) +#define JZ4740_ADC_BATTERY_HIGH_VREF_BITS 12 + +struct ingenic_adc_soc_data { + unsigned int battery_high_vref; + unsigned int battery_high_vref_bits; + const int *battery_raw_avail; + size_t battery_raw_avail_size; + const int *battery_scale_avail; + size_t battery_scale_avail_size; +}; + +struct ingenic_adc { + void __iomem *base; + struct clk *clk; + struct mutex lock; + const struct ingenic_adc_soc_data *soc_data; + bool low_vref_mode; +}; + +static void ingenic_adc_set_config(struct ingenic_adc *adc, + uint32_t mask, + uint32_t val) +{ + uint32_t cfg; + + clk_enable(adc->clk); + mutex_lock(&adc->lock); + + cfg = readl(adc->base + JZ_ADC_REG_CFG) & ~mask; + cfg |= val; + writel(cfg, adc->base + JZ_ADC_REG_CFG); + + mutex_unlock(&adc->lock); + clk_disable(adc->clk); +} + +static void ingenic_adc_enable(struct ingenic_adc *adc, + int engine, + bool enabled) +{ + u8 val; + + mutex_lock(&adc->lock); + val = readb(adc->base + JZ_ADC_REG_ENABLE); + + if (enabled) + val |= BIT(engine); + else + val &= ~BIT(engine); + + writeb(val, adc->base + JZ_ADC_REG_ENABLE); + mutex_unlock(&adc->lock); +} + +static int ingenic_adc_capture(struct ingenic_adc *adc, + int engine) +{ + u8 val; + int ret; + + ingenic_adc_enable(adc, engine, true); + ret = readb_poll_timeout(adc->base + JZ_ADC_REG_ENABLE, val, + !(val & BIT(engine)), 250, 1000); + if (ret) + ingenic_adc_enable(adc, engine, false); + + return ret; +} + +static int ingenic_adc_write_raw(struct iio_dev *iio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long m) +{ + struct ingenic_adc *adc = iio_priv(iio_dev); + + switch (m) { + case IIO_CHAN_INFO_SCALE: + switch (chan->channel) { + case INGENIC_ADC_BATTERY: + if (val > JZ_ADC_BATTERY_LOW_VREF) { + ingenic_adc_set_config(adc, + JZ_ADC_REG_CFG_BAT_MD, + 0); + adc->low_vref_mode = false; + } else { + ingenic_adc_set_config(adc, + JZ_ADC_REG_CFG_BAT_MD, + JZ_ADC_REG_CFG_BAT_MD); + adc->low_vref_mode = true; + } + return 0; + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + +static const int jz4725b_adc_battery_raw_avail[] = { + 0, 1, (1 << JZ_ADC_BATTERY_LOW_VREF_BITS) - 1, +}; + +static const int jz4725b_adc_battery_scale_avail[] = { + JZ4725B_ADC_BATTERY_HIGH_VREF, JZ4725B_ADC_BATTERY_HIGH_VREF_BITS, + JZ_ADC_BATTERY_LOW_VREF, JZ_ADC_BATTERY_LOW_VREF_BITS, +}; + +static const int jz4740_adc_battery_raw_avail[] = { + 0, 1, (1 << JZ_ADC_BATTERY_LOW_VREF_BITS) - 1, +}; + +static const int jz4740_adc_battery_scale_avail[] = { + JZ4740_ADC_BATTERY_HIGH_VREF, JZ4740_ADC_BATTERY_HIGH_VREF_BITS, + JZ_ADC_BATTERY_LOW_VREF, JZ_ADC_BATTERY_LOW_VREF_BITS, +}; + +static const struct ingenic_adc_soc_data jz4725b_adc_soc_data = { + .battery_high_vref = JZ4725B_ADC_BATTERY_HIGH_VREF, + .battery_high_vref_bits = JZ4725B_ADC_BATTERY_HIGH_VREF_BITS, + .battery_raw_avail = jz4725b_adc_battery_raw_avail, + .battery_raw_avail_size = ARRAY_SIZE(jz4725b_adc_battery_raw_avail), + .battery_scale_avail = jz4725b_adc_battery_scale_avail, + .battery_scale_avail_size = ARRAY_SIZE(jz4725b_adc_battery_scale_avail), +}; + +static const struct ingenic_adc_soc_data jz4740_adc_soc_data = { + .battery_high_vref = JZ4740_ADC_BATTERY_HIGH_VREF, + .battery_high_vref_bits = JZ4740_ADC_BATTERY_HIGH_VREF_BITS, + .battery_raw_avail = jz4740_adc_battery_raw_avail, + .battery_raw_avail_size = ARRAY_SIZE(jz4740_adc_battery_raw_avail), + .battery_scale_avail = jz4740_adc_battery_scale_avail, + .battery_scale_avail_size = ARRAY_SIZE(jz4740_adc_battery_scale_avail), +}; + +static int ingenic_adc_read_avail(struct iio_dev *iio_dev, + struct iio_chan_spec const *chan, + const int **vals, + int *type, + int *length, + long m) +{ + struct ingenic_adc *adc = iio_priv(iio_dev); + + switch (m) { + case IIO_CHAN_INFO_RAW: + *type = IIO_VAL_INT; + *length = adc->soc_data->battery_raw_avail_size; + *vals = adc->soc_data->battery_raw_avail; + return IIO_AVAIL_RANGE; + case IIO_CHAN_INFO_SCALE: + *type = IIO_VAL_FRACTIONAL_LOG2; + *length = adc->soc_data->battery_scale_avail_size; + *vals = adc->soc_data->battery_scale_avail; + return IIO_AVAIL_LIST; + default: + return -EINVAL; + }; +} + +static int ingenic_adc_read_raw(struct iio_dev *iio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) +{ + struct ingenic_adc *adc = iio_priv(iio_dev); + int ret; + + switch (m) { + case IIO_CHAN_INFO_RAW: + clk_enable(adc->clk); + ret = ingenic_adc_capture(adc, chan->channel); + if (ret) { + clk_disable(adc->clk); + return ret; + } + + switch (chan->channel) { + case INGENIC_ADC_AUX: + *val = readw(adc->base + JZ_ADC_REG_ADSDAT); + break; + case INGENIC_ADC_BATTERY: + *val = readw(adc->base + JZ_ADC_REG_ADBDAT); + break; + } + + clk_disable(adc->clk); + + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + switch (chan->channel) { + case INGENIC_ADC_AUX: + *val = JZ_ADC_AUX_VREF; + *val2 = JZ_ADC_AUX_VREF_BITS; + break; + case INGENIC_ADC_BATTERY: + if (adc->low_vref_mode) { + *val = JZ_ADC_BATTERY_LOW_VREF; + *val2 = JZ_ADC_BATTERY_LOW_VREF_BITS; + } else { + *val = adc->soc_data->battery_high_vref; + *val2 = adc->soc_data->battery_high_vref_bits; + } + break; + } + + return IIO_VAL_FRACTIONAL_LOG2; + default: + return -EINVAL; + } +} + +static void ingenic_adc_clk_cleanup(void *data) +{ + clk_unprepare(data); +} + +static const struct iio_info ingenic_adc_info = { + .write_raw = ingenic_adc_write_raw, + .read_raw = ingenic_adc_read_raw, + .read_avail = ingenic_adc_read_avail, +}; + +static const struct iio_chan_spec ingenic_channels[] = { + { + .extend_name = "aux", + .type = IIO_VOLTAGE, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), + .indexed = 1, + .channel = INGENIC_ADC_AUX, + }, + { + .extend_name = "battery", + .type = IIO_VOLTAGE, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), + .info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), + .indexed = 1, + .channel = INGENIC_ADC_BATTERY, + }, +}; + +static int ingenic_adc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct iio_dev *iio_dev; + struct ingenic_adc *adc; + struct resource *mem_base; + const struct ingenic_adc_soc_data *soc_data; + int ret; + + soc_data = device_get_match_data(dev); + if (!soc_data) + return -EINVAL; + + iio_dev = devm_iio_device_alloc(dev, sizeof(*adc)); + if (!iio_dev) + return -ENOMEM; + + adc = iio_priv(iio_dev); + mutex_init(&adc->lock); + adc->soc_data = soc_data; + + mem_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); + adc->base = devm_ioremap_resource(dev, mem_base); + if (IS_ERR(adc->base)) { + dev_err(dev, "Unable to ioremap mmio resource\n"); + return PTR_ERR(adc->base); + } + + adc->clk = devm_clk_get(dev, "adc"); + if (IS_ERR(adc->clk)) { + dev_err(dev, "Unable to get clock\n"); + return PTR_ERR(adc->clk); + } + + ret = clk_prepare_enable(adc->clk); + if (ret) { + dev_err(dev, "Failed to enable clock\n"); + return ret; + } + + /* Put hardware in a known passive state. */ + writeb(0x00, adc->base + JZ_ADC_REG_ENABLE); + writeb(0xff, adc->base + JZ_ADC_REG_CTRL); + clk_disable(adc->clk); + + ret = devm_add_action_or_reset(dev, ingenic_adc_clk_cleanup, adc->clk); + if (ret) { + dev_err(dev, "Unable to add action\n"); + return ret; + } + + iio_dev->dev.parent = dev; + iio_dev->name = "jz-adc"; + iio_dev->modes = INDIO_DIRECT_MODE; + iio_dev->channels = ingenic_channels; + iio_dev->num_channels = ARRAY_SIZE(ingenic_channels); + iio_dev->info = &ingenic_adc_info; + + ret = devm_iio_device_register(dev, iio_dev); + if (ret) + dev_err(dev, "Unable to register IIO device\n"); + + return ret; +} + +#ifdef CONFIG_OF +static const struct of_device_id ingenic_adc_of_match[] = { + { .compatible = "ingenic,jz4725b-adc", .data = &jz4725b_adc_soc_data, }, + { .compatible = "ingenic,jz4740-adc", .data = &jz4740_adc_soc_data, }, + { }, +}; +MODULE_DEVICE_TABLE(of, ingenic_adc_of_match); +#endif + +static struct platform_driver ingenic_adc_driver = { + .driver = { + .name = "ingenic-adc", + .of_match_table = of_match_ptr(ingenic_adc_of_match), + }, + .probe = ingenic_adc_probe, +}; +module_platform_driver(ingenic_adc_driver); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/adc/lpc32xx_adc.c b/drivers/iio/adc/lpc32xx_adc.c index 20b36690fa4f..e361c1532a75 100644 --- a/drivers/iio/adc/lpc32xx_adc.c +++ b/drivers/iio/adc/lpc32xx_adc.c @@ -1,23 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * lpc32xx_adc.c - Support for ADC in LPC32XX * * 3-channel, 10-bit ADC * * Copyright (C) 2011, 2012 Roland Stigge <stigge@antcom.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <linux/module.h> diff --git a/drivers/iio/adc/meson_saradc.c b/drivers/iio/adc/meson_saradc.c index 729becb2d3d9..f8600fbcdfe3 100644 --- a/drivers/iio/adc/meson_saradc.c +++ b/drivers/iio/adc/meson_saradc.c @@ -26,6 +26,7 @@ #include <linux/platform_device.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> +#include <linux/mfd/syscon.h> #define MESON_SAR_ADC_REG0 0x00 #define MESON_SAR_ADC_REG0_PANEL_DETECT BIT(31) @@ -174,6 +175,9 @@ #define MESON_SAR_ADC_EFUSE_BYTE3_UPPER_ADC_VAL GENMASK(6, 0) #define MESON_SAR_ADC_EFUSE_BYTE3_IS_CALIBRATED BIT(7) +#define MESON_HHI_DPLL_TOP_0 0x318 +#define MESON_HHI_DPLL_TOP_0_TSC_BIT4 BIT(9) + /* for use with IIO_VAL_INT_PLUS_MICRO */ #define MILLION 1000000 @@ -280,6 +284,7 @@ struct meson_sar_adc_priv { struct completion done; int calibbias; int calibscale; + struct regmap *tsc_regmap; bool temperature_sensor_calibrated; u8 temperature_sensor_coefficient; u16 temperature_sensor_adc_val; @@ -727,6 +732,15 @@ static int meson_sar_adc_temp_sensor_init(struct iio_dev *indio_dev) return ret; } + priv->tsc_regmap = + syscon_regmap_lookup_by_phandle(indio_dev->dev.parent->of_node, + "amlogic,hhi-sysctrl"); + if (IS_ERR(priv->tsc_regmap)) { + dev_err(indio_dev->dev.parent, + "failed to get amlogic,hhi-sysctrl regmap\n"); + return PTR_ERR(priv->tsc_regmap); + } + read_len = MESON_SAR_ADC_EFUSE_BYTES; buf = nvmem_cell_read(temperature_calib, &read_len); if (IS_ERR(buf)) { @@ -861,6 +875,22 @@ static int meson_sar_adc_init(struct iio_dev *indio_dev) priv->temperature_sensor_coefficient); regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELTA_10, MESON_SAR_ADC_DELTA_10_TS_C_MASK, regval); + + if (priv->param->temperature_trimming_bits == 5) { + if (priv->temperature_sensor_coefficient & BIT(4)) + regval = MESON_HHI_DPLL_TOP_0_TSC_BIT4; + else + regval = 0; + + /* + * bit [4] (the 5th bit when starting to count at 1) + * of the TSC is located in the HHI register area. + */ + regmap_update_bits(priv->tsc_regmap, + MESON_HHI_DPLL_TOP_0, + MESON_HHI_DPLL_TOP_0_TSC_BIT4, + regval); + } } else { regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELTA_10, MESON_SAR_ADC_DELTA_10_TS_REVE1, 0); @@ -1064,6 +1094,9 @@ static const struct meson_sar_adc_param meson_sar_adc_meson8b_param = { .bandgap_reg = MESON_SAR_ADC_DELTA_10, .regmap_config = &meson_sar_adc_regmap_config_meson8, .resolution = 10, + .temperature_trimming_bits = 5, + .temperature_multiplier = 10, + .temperature_divider = 32, }; static const struct meson_sar_adc_param meson_sar_adc_gxbb_param = { diff --git a/drivers/iio/adc/npcm_adc.c b/drivers/iio/adc/npcm_adc.c new file mode 100644 index 000000000000..9e25bbec9c70 --- /dev/null +++ b/drivers/iio/adc/npcm_adc.c @@ -0,0 +1,335 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2019 Nuvoton Technology corporation. + +#include <linux/clk.h> +#include <linux/device.h> +#include <linux/mfd/syscon.h> +#include <linux/io.h> +#include <linux/iio/iio.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/regulator/consumer.h> +#include <linux/spinlock.h> +#include <linux/uaccess.h> + +struct npcm_adc { + bool int_status; + u32 adc_sample_hz; + struct device *dev; + void __iomem *regs; + struct clk *adc_clk; + wait_queue_head_t wq; + struct regulator *vref; + struct regmap *rst_regmap; +}; + +/* NPCM7xx reset module */ +#define NPCM7XX_IPSRST1_OFFSET 0x020 +#define NPCM7XX_IPSRST1_ADC_RST BIT(27) + +/* ADC registers */ +#define NPCM_ADCCON 0x00 +#define NPCM_ADCDATA 0x04 + +/* ADCCON Register Bits */ +#define NPCM_ADCCON_ADC_INT_EN BIT(21) +#define NPCM_ADCCON_REFSEL BIT(19) +#define NPCM_ADCCON_ADC_INT_ST BIT(18) +#define NPCM_ADCCON_ADC_EN BIT(17) +#define NPCM_ADCCON_ADC_RST BIT(16) +#define NPCM_ADCCON_ADC_CONV BIT(13) + +#define NPCM_ADCCON_CH_MASK GENMASK(27, 24) +#define NPCM_ADCCON_CH(x) ((x) << 24) +#define NPCM_ADCCON_DIV_SHIFT 1 +#define NPCM_ADCCON_DIV_MASK GENMASK(8, 1) +#define NPCM_ADC_DATA_MASK(x) ((x) & GENMASK(9, 0)) + +#define NPCM_ADC_ENABLE (NPCM_ADCCON_ADC_EN | NPCM_ADCCON_ADC_INT_EN) + +/* ADC General Definition */ +#define NPCM_RESOLUTION_BITS 10 +#define NPCM_INT_VREF_MV 2000 + +#define NPCM_ADC_CHAN(ch) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = ch, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ +} + +static const struct iio_chan_spec npcm_adc_iio_channels[] = { + NPCM_ADC_CHAN(0), + NPCM_ADC_CHAN(1), + NPCM_ADC_CHAN(2), + NPCM_ADC_CHAN(3), + NPCM_ADC_CHAN(4), + NPCM_ADC_CHAN(5), + NPCM_ADC_CHAN(6), + NPCM_ADC_CHAN(7), +}; + +static irqreturn_t npcm_adc_isr(int irq, void *data) +{ + u32 regtemp; + struct iio_dev *indio_dev = data; + struct npcm_adc *info = iio_priv(indio_dev); + + regtemp = ioread32(info->regs + NPCM_ADCCON); + if (regtemp & NPCM_ADCCON_ADC_INT_ST) { + iowrite32(regtemp, info->regs + NPCM_ADCCON); + wake_up_interruptible(&info->wq); + info->int_status = true; + } + + return IRQ_HANDLED; +} + +static int npcm_adc_read(struct npcm_adc *info, int *val, u8 channel) +{ + int ret; + u32 regtemp; + + /* Select ADC channel */ + regtemp = ioread32(info->regs + NPCM_ADCCON); + regtemp &= ~NPCM_ADCCON_CH_MASK; + info->int_status = false; + iowrite32(regtemp | NPCM_ADCCON_CH(channel) | + NPCM_ADCCON_ADC_CONV, info->regs + NPCM_ADCCON); + + ret = wait_event_interruptible_timeout(info->wq, info->int_status, + msecs_to_jiffies(10)); + if (ret == 0) { + regtemp = ioread32(info->regs + NPCM_ADCCON); + if ((regtemp & NPCM_ADCCON_ADC_CONV) && info->rst_regmap) { + /* if conversion failed - reset ADC module */ + regmap_write(info->rst_regmap, NPCM7XX_IPSRST1_OFFSET, + NPCM7XX_IPSRST1_ADC_RST); + msleep(100); + regmap_write(info->rst_regmap, NPCM7XX_IPSRST1_OFFSET, + 0x0); + msleep(100); + + /* Enable ADC and start conversion module */ + iowrite32(NPCM_ADC_ENABLE | NPCM_ADCCON_ADC_CONV, + info->regs + NPCM_ADCCON); + dev_err(info->dev, "RESET ADC Complete\n"); + } + return -ETIMEDOUT; + } + if (ret < 0) + return ret; + + *val = NPCM_ADC_DATA_MASK(ioread32(info->regs + NPCM_ADCDATA)); + + return 0; +} + +static int npcm_adc_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, + int *val2, long mask) +{ + int ret; + int vref_uv; + struct npcm_adc *info = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_RAW: + mutex_lock(&indio_dev->mlock); + ret = npcm_adc_read(info, val, chan->channel); + mutex_unlock(&indio_dev->mlock); + if (ret) { + dev_err(info->dev, "NPCM ADC read failed\n"); + return ret; + } + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + if (info->vref) { + vref_uv = regulator_get_voltage(info->vref); + *val = vref_uv / 1000; + } else { + *val = NPCM_INT_VREF_MV; + } + *val2 = NPCM_RESOLUTION_BITS; + return IIO_VAL_FRACTIONAL_LOG2; + case IIO_CHAN_INFO_SAMP_FREQ: + *val = info->adc_sample_hz; + return IIO_VAL_INT; + default: + return -EINVAL; + } + + return 0; +} + +static const struct iio_info npcm_adc_iio_info = { + .read_raw = &npcm_adc_read_raw, +}; + +static const struct of_device_id npcm_adc_match[] = { + { .compatible = "nuvoton,npcm750-adc", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, npcm_adc_match); + +static int npcm_adc_probe(struct platform_device *pdev) +{ + int ret; + int irq; + u32 div; + u32 reg_con; + struct resource *res; + struct npcm_adc *info; + struct iio_dev *indio_dev; + struct device *dev = &pdev->dev; + struct device_node *np = pdev->dev.of_node; + + indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info)); + if (!indio_dev) + return -ENOMEM; + info = iio_priv(indio_dev); + + info->dev = &pdev->dev; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + info->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(info->regs)) + return PTR_ERR(info->regs); + + info->adc_clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(info->adc_clk)) { + dev_warn(&pdev->dev, "ADC clock failed: can't read clk\n"); + return PTR_ERR(info->adc_clk); + } + + /* calculate ADC clock sample rate */ + reg_con = ioread32(info->regs + NPCM_ADCCON); + div = reg_con & NPCM_ADCCON_DIV_MASK; + div = div >> NPCM_ADCCON_DIV_SHIFT; + info->adc_sample_hz = clk_get_rate(info->adc_clk) / ((div + 1) * 2); + + if (of_device_is_compatible(np, "nuvoton,npcm750-adc")) { + info->rst_regmap = syscon_regmap_lookup_by_compatible + ("nuvoton,npcm750-rst"); + if (IS_ERR(info->rst_regmap)) { + dev_err(&pdev->dev, "Failed to find nuvoton,npcm750-rst\n"); + ret = PTR_ERR(info->rst_regmap); + goto err_disable_clk; + } + } + + irq = platform_get_irq(pdev, 0); + if (irq <= 0) { + dev_err(dev, "failed getting interrupt resource\n"); + ret = -EINVAL; + goto err_disable_clk; + } + + ret = devm_request_irq(&pdev->dev, irq, npcm_adc_isr, 0, + "NPCM_ADC", indio_dev); + if (ret < 0) { + dev_err(dev, "failed requesting interrupt\n"); + goto err_disable_clk; + } + + reg_con = ioread32(info->regs + NPCM_ADCCON); + info->vref = devm_regulator_get_optional(&pdev->dev, "vref"); + if (!IS_ERR(info->vref)) { + ret = regulator_enable(info->vref); + if (ret) { + dev_err(&pdev->dev, "Can't enable ADC reference voltage\n"); + goto err_disable_clk; + } + + iowrite32(reg_con & ~NPCM_ADCCON_REFSEL, + info->regs + NPCM_ADCCON); + } else { + /* + * Any error which is not ENODEV indicates the regulator + * has been specified and so is a failure case. + */ + if (PTR_ERR(info->vref) != -ENODEV) { + ret = PTR_ERR(info->vref); + goto err_disable_clk; + } + + /* Use internal reference */ + iowrite32(reg_con | NPCM_ADCCON_REFSEL, + info->regs + NPCM_ADCCON); + } + + init_waitqueue_head(&info->wq); + + reg_con = ioread32(info->regs + NPCM_ADCCON); + reg_con |= NPCM_ADC_ENABLE; + + /* Enable the ADC Module */ + iowrite32(reg_con, info->regs + NPCM_ADCCON); + + /* Start ADC conversion */ + iowrite32(reg_con | NPCM_ADCCON_ADC_CONV, info->regs + NPCM_ADCCON); + + platform_set_drvdata(pdev, indio_dev); + indio_dev->name = dev_name(&pdev->dev); + indio_dev->dev.parent = &pdev->dev; + indio_dev->info = &npcm_adc_iio_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = npcm_adc_iio_channels; + indio_dev->num_channels = ARRAY_SIZE(npcm_adc_iio_channels); + + ret = iio_device_register(indio_dev); + if (ret) { + dev_err(&pdev->dev, "Couldn't register the device.\n"); + goto err_iio_register; + } + + pr_info("NPCM ADC driver probed\n"); + + return 0; + +err_iio_register: + iowrite32(reg_con & ~NPCM_ADCCON_ADC_EN, info->regs + NPCM_ADCCON); + if (!IS_ERR(info->vref)) + regulator_disable(info->vref); +err_disable_clk: + clk_disable_unprepare(info->adc_clk); + + return ret; +} + +static int npcm_adc_remove(struct platform_device *pdev) +{ + struct iio_dev *indio_dev = platform_get_drvdata(pdev); + struct npcm_adc *info = iio_priv(indio_dev); + u32 regtemp; + + iio_device_unregister(indio_dev); + + regtemp = ioread32(info->regs + NPCM_ADCCON); + iowrite32(regtemp & ~NPCM_ADCCON_ADC_EN, info->regs + NPCM_ADCCON); + if (!IS_ERR(info->vref)) + regulator_disable(info->vref); + clk_disable_unprepare(info->adc_clk); + + return 0; +} + +static struct platform_driver npcm_adc_driver = { + .probe = npcm_adc_probe, + .remove = npcm_adc_remove, + .driver = { + .name = "npcm_adc", + .of_match_table = npcm_adc_match, + }, +}; + +module_platform_driver(npcm_adc_driver); + +MODULE_DESCRIPTION("Nuvoton NPCM ADC Driver"); +MODULE_AUTHOR("Tomer Maimon <tomer.maimon@nuvoton.com>"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/adc/ti-ads124s08.c b/drivers/iio/adc/ti-ads124s08.c new file mode 100644 index 000000000000..53f17e4f2f23 --- /dev/null +++ b/drivers/iio/adc/ti-ads124s08.c @@ -0,0 +1,376 @@ +// SPDX-License-Identifier: GPL-2.0 +/* TI ADS124S0X chip family driver + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ + */ + +#include <linux/err.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_gpio.h> +#include <linux/slab.h> +#include <linux/sysfs.h> + +#include <linux/gpio/consumer.h> +#include <linux/spi/spi.h> + +#include <linux/iio/iio.h> +#include <linux/iio/buffer.h> +#include <linux/iio/trigger_consumer.h> +#include <linux/iio/triggered_buffer.h> +#include <linux/iio/sysfs.h> + +/* Commands */ +#define ADS124S08_CMD_NOP 0x00 +#define ADS124S08_CMD_WAKEUP 0x02 +#define ADS124S08_CMD_PWRDWN 0x04 +#define ADS124S08_CMD_RESET 0x06 +#define ADS124S08_CMD_START 0x08 +#define ADS124S08_CMD_STOP 0x0a +#define ADS124S08_CMD_SYOCAL 0x16 +#define ADS124S08_CMD_SYGCAL 0x17 +#define ADS124S08_CMD_SFOCAL 0x19 +#define ADS124S08_CMD_RDATA 0x12 +#define ADS124S08_CMD_RREG 0x20 +#define ADS124S08_CMD_WREG 0x40 + +/* Registers */ +#define ADS124S08_ID_REG 0x00 +#define ADS124S08_STATUS 0x01 +#define ADS124S08_INPUT_MUX 0x02 +#define ADS124S08_PGA 0x03 +#define ADS124S08_DATA_RATE 0x04 +#define ADS124S08_REF 0x05 +#define ADS124S08_IDACMAG 0x06 +#define ADS124S08_IDACMUX 0x07 +#define ADS124S08_VBIAS 0x08 +#define ADS124S08_SYS 0x09 +#define ADS124S08_OFCAL0 0x0a +#define ADS124S08_OFCAL1 0x0b +#define ADS124S08_OFCAL2 0x0c +#define ADS124S08_FSCAL0 0x0d +#define ADS124S08_FSCAL1 0x0e +#define ADS124S08_FSCAL2 0x0f +#define ADS124S08_GPIODAT 0x10 +#define ADS124S08_GPIOCON 0x11 + +/* ADS124S0x common channels */ +#define ADS124S08_AIN0 0x00 +#define ADS124S08_AIN1 0x01 +#define ADS124S08_AIN2 0x02 +#define ADS124S08_AIN3 0x03 +#define ADS124S08_AIN4 0x04 +#define ADS124S08_AIN5 0x05 +#define ADS124S08_AINCOM 0x0c +/* ADS124S08 only channels */ +#define ADS124S08_AIN6 0x06 +#define ADS124S08_AIN7 0x07 +#define ADS124S08_AIN8 0x08 +#define ADS124S08_AIN9 0x09 +#define ADS124S08_AIN10 0x0a +#define ADS124S08_AIN11 0x0b +#define ADS124S08_MAX_CHANNELS 12 + +#define ADS124S08_POS_MUX_SHIFT 0x04 +#define ADS124S08_INT_REF 0x09 + +#define ADS124S08_START_REG_MASK 0x1f +#define ADS124S08_NUM_BYTES_MASK 0x1f + +#define ADS124S08_START_CONV 0x01 +#define ADS124S08_STOP_CONV 0x00 + +enum ads124s_id { + ADS124S08_ID, + ADS124S06_ID, +}; + +struct ads124s_chip_info { + const struct iio_chan_spec *channels; + unsigned int num_channels; +}; + +struct ads124s_private { + const struct ads124s_chip_info *chip_info; + struct gpio_desc *reset_gpio; + struct spi_device *spi; + struct mutex lock; + u8 data[5] ____cacheline_aligned; +}; + +#define ADS124S08_CHAN(index) \ +{ \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = index, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .scan_index = index, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 32, \ + .storagebits = 32, \ + }, \ +} + +static const struct iio_chan_spec ads124s06_channels[] = { + ADS124S08_CHAN(0), + ADS124S08_CHAN(1), + ADS124S08_CHAN(2), + ADS124S08_CHAN(3), + ADS124S08_CHAN(4), + ADS124S08_CHAN(5), +}; + +static const struct iio_chan_spec ads124s08_channels[] = { + ADS124S08_CHAN(0), + ADS124S08_CHAN(1), + ADS124S08_CHAN(2), + ADS124S08_CHAN(3), + ADS124S08_CHAN(4), + ADS124S08_CHAN(5), + ADS124S08_CHAN(6), + ADS124S08_CHAN(7), + ADS124S08_CHAN(8), + ADS124S08_CHAN(9), + ADS124S08_CHAN(10), + ADS124S08_CHAN(11), +}; + +static const struct ads124s_chip_info ads124s_chip_info_tbl[] = { + [ADS124S08_ID] = { + .channels = ads124s08_channels, + .num_channels = ARRAY_SIZE(ads124s08_channels), + }, + [ADS124S06_ID] = { + .channels = ads124s06_channels, + .num_channels = ARRAY_SIZE(ads124s06_channels), + }, +}; + +static int ads124s_write_cmd(struct iio_dev *indio_dev, u8 command) +{ + struct ads124s_private *priv = iio_priv(indio_dev); + + priv->data[0] = command; + + return spi_write(priv->spi, &priv->data[0], 1); +} + +static int ads124s_write_reg(struct iio_dev *indio_dev, u8 reg, u8 data) +{ + struct ads124s_private *priv = iio_priv(indio_dev); + + priv->data[0] = ADS124S08_CMD_WREG | reg; + priv->data[1] = 0x0; + priv->data[2] = data; + + return spi_write(priv->spi, &priv->data[0], 3); +} + +static int ads124s_reset(struct iio_dev *indio_dev) +{ + struct ads124s_private *priv = iio_priv(indio_dev); + + if (priv->reset_gpio) { + gpiod_set_value(priv->reset_gpio, 0); + udelay(200); + gpiod_set_value(priv->reset_gpio, 1); + } else { + return ads124s_write_cmd(indio_dev, ADS124S08_CMD_RESET); + } + + return 0; +}; + +static int ads124s_read(struct iio_dev *indio_dev, unsigned int chan) +{ + struct ads124s_private *priv = iio_priv(indio_dev); + int ret; + u32 tmp; + struct spi_transfer t[] = { + { + .tx_buf = &priv->data[0], + .len = 4, + .cs_change = 1, + }, { + .tx_buf = &priv->data[1], + .rx_buf = &priv->data[1], + .len = 4, + }, + }; + + priv->data[0] = ADS124S08_CMD_RDATA; + memset(&priv->data[1], ADS124S08_CMD_NOP, sizeof(priv->data)); + + ret = spi_sync_transfer(priv->spi, t, ARRAY_SIZE(t)); + if (ret < 0) + return ret; + + tmp = priv->data[2] << 16 | priv->data[3] << 8 | priv->data[4]; + + return tmp; +} + +static int ads124s_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long m) +{ + struct ads124s_private *priv = iio_priv(indio_dev); + int ret; + + mutex_lock(&priv->lock); + switch (m) { + case IIO_CHAN_INFO_RAW: + ret = ads124s_write_reg(indio_dev, ADS124S08_INPUT_MUX, + chan->channel); + if (ret) { + dev_err(&priv->spi->dev, "Set ADC CH failed\n"); + goto out; + } + + ret = ads124s_write_cmd(indio_dev, ADS124S08_START_CONV); + if (ret) { + dev_err(&priv->spi->dev, "Start conversions failed\n"); + goto out; + } + + ret = ads124s_read(indio_dev, chan->channel); + if (ret < 0) { + dev_err(&priv->spi->dev, "Read ADC failed\n"); + goto out; + } + + *val = ret; + + ret = ads124s_write_cmd(indio_dev, ADS124S08_STOP_CONV); + if (ret) { + dev_err(&priv->spi->dev, "Stop conversions failed\n"); + goto out; + } + + ret = IIO_VAL_INT; + break; + default: + ret = -EINVAL; + break; + } +out: + mutex_unlock(&priv->lock); + return ret; +} + +static const struct iio_info ads124s_info = { + .read_raw = &ads124s_read_raw, +}; + +static irqreturn_t ads124s_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct ads124s_private *priv = iio_priv(indio_dev); + u32 buffer[ADS124S08_MAX_CHANNELS + sizeof(s64)/sizeof(u16)]; + int scan_index, j = 0; + int ret; + + for_each_set_bit(scan_index, indio_dev->active_scan_mask, + indio_dev->masklength) { + ret = ads124s_write_reg(indio_dev, ADS124S08_INPUT_MUX, + scan_index); + if (ret) + dev_err(&priv->spi->dev, "Set ADC CH failed\n"); + + ret = ads124s_write_cmd(indio_dev, ADS124S08_START_CONV); + if (ret) + dev_err(&priv->spi->dev, "Start ADC conversions failed\n"); + + buffer[j] = ads124s_read(indio_dev, scan_index); + ret = ads124s_write_cmd(indio_dev, ADS124S08_STOP_CONV); + if (ret) + dev_err(&priv->spi->dev, "Stop ADC conversions failed\n"); + + j++; + } + + iio_push_to_buffers_with_timestamp(indio_dev, buffer, + pf->timestamp); + + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +static int ads124s_probe(struct spi_device *spi) +{ + struct ads124s_private *ads124s_priv; + struct iio_dev *indio_dev; + const struct spi_device_id *spi_id = spi_get_device_id(spi); + int ret; + + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*ads124s_priv)); + if (indio_dev == NULL) + return -ENOMEM; + + ads124s_priv = iio_priv(indio_dev); + + ads124s_priv->reset_gpio = devm_gpiod_get_optional(&spi->dev, + "reset", GPIOD_OUT_LOW); + if (IS_ERR(ads124s_priv->reset_gpio)) + dev_info(&spi->dev, "Reset GPIO not defined\n"); + + ads124s_priv->chip_info = &ads124s_chip_info_tbl[spi_id->driver_data]; + + spi_set_drvdata(spi, indio_dev); + + ads124s_priv->spi = spi; + + indio_dev->name = spi_id->name; + indio_dev->dev.parent = &spi->dev; + indio_dev->dev.of_node = spi->dev.of_node; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = ads124s_priv->chip_info->channels; + indio_dev->num_channels = ads124s_priv->chip_info->num_channels; + indio_dev->info = &ads124s_info; + + mutex_init(&ads124s_priv->lock); + + ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, NULL, + ads124s_trigger_handler, NULL); + if (ret) { + dev_err(&spi->dev, "iio triggered buffer setup failed\n"); + return ret; + } + + ads124s_reset(indio_dev); + + return devm_iio_device_register(&spi->dev, indio_dev); +} + +static const struct spi_device_id ads124s_id[] = { + { "ads124s06", ADS124S06_ID }, + { "ads124s08", ADS124S08_ID }, + { } +}; +MODULE_DEVICE_TABLE(spi, ads124s_id); + +static const struct of_device_id ads124s_of_table[] = { + { .compatible = "ti,ads124s06" }, + { .compatible = "ti,ads124s08" }, + { }, +}; +MODULE_DEVICE_TABLE(of, ads124s_of_table); + +static struct spi_driver ads124s_driver = { + .driver = { + .name = "ads124s08", + .of_match_table = ads124s_of_table, + }, + .probe = ads124s_probe, + .id_table = ads124s_id, +}; +module_spi_driver(ads124s_driver); + +MODULE_AUTHOR("Dan Murphy <dmuprhy@ti.com>"); +MODULE_DESCRIPTION("TI TI_ADS12S0X ADC"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/adc/xilinx-xadc-core.c b/drivers/iio/adc/xilinx-xadc-core.c index 3f6be5ac049a..b13c61539d46 100644 --- a/drivers/iio/adc/xilinx-xadc-core.c +++ b/drivers/iio/adc/xilinx-xadc-core.c @@ -1273,8 +1273,10 @@ static int xadc_probe(struct platform_device *pdev) xadc->threshold[i] = 0xffff; else xadc->threshold[i] = 0; - xadc_write_adc_reg(xadc, XADC_REG_THRESHOLD(i), + ret = xadc_write_adc_reg(xadc, XADC_REG_THRESHOLD(i), xadc->threshold[i]); + if (ret) + goto err_free_irq; } /* Go to non-buffered mode */ diff --git a/drivers/iio/chemical/Kconfig b/drivers/iio/chemical/Kconfig index b8e005be4f87..d5d146e9e372 100644 --- a/drivers/iio/chemical/Kconfig +++ b/drivers/iio/chemical/Kconfig @@ -61,6 +61,27 @@ config IAQCORE iAQ-Core Continuous/Pulsed VOC (Volatile Organic Compounds) sensors +config PMS7003 + tristate "Plantower PMS7003 particulate matter sensor" + depends on SERIAL_DEV_BUS + help + Say Y here to build support for the Plantower PMS7003 particulate + matter sensor. + + To compile this driver as a module, choose M here: the module will + be called pms7003. + +config SPS30 + tristate "SPS30 particulate matter sensor" + depends on I2C + select CRC8 + help + Say Y here to build support for the Sensirion SPS30 particulate + matter sensor. + + To compile this driver as a module, choose M here: the module will + be called sps30. + config VZ89X tristate "SGX Sensortech MiCS VZ89X VOC sensor" depends on I2C diff --git a/drivers/iio/chemical/Makefile b/drivers/iio/chemical/Makefile index 2f4c4ba4d781..f5d1365acb49 100644 --- a/drivers/iio/chemical/Makefile +++ b/drivers/iio/chemical/Makefile @@ -9,4 +9,7 @@ obj-$(CONFIG_BME680_I2C) += bme680_i2c.o obj-$(CONFIG_BME680_SPI) += bme680_spi.o obj-$(CONFIG_CCS811) += ccs811.o obj-$(CONFIG_IAQCORE) += ams-iaq-core.o +obj-$(CONFIG_PMS7003) += pms7003.o +obj-$(CONFIG_SENSIRION_SGP30) += sgp30.o +obj-$(CONFIG_SPS30) += sps30.o obj-$(CONFIG_VZ89X) += vz89x.o diff --git a/drivers/iio/chemical/bme680_i2c.c b/drivers/iio/chemical/bme680_i2c.c index 06d4be539d2e..b2f805b6b36a 100644 --- a/drivers/iio/chemical/bme680_i2c.c +++ b/drivers/iio/chemical/bme680_i2c.c @@ -70,10 +70,17 @@ static const struct acpi_device_id bme680_acpi_match[] = { }; MODULE_DEVICE_TABLE(acpi, bme680_acpi_match); +static const struct of_device_id bme680_of_i2c_match[] = { + { .compatible = "bosch,bme680", }, + {}, +}; +MODULE_DEVICE_TABLE(of, bme680_of_i2c_match); + static struct i2c_driver bme680_i2c_driver = { .driver = { .name = "bme680_i2c", .acpi_match_table = ACPI_PTR(bme680_acpi_match), + .of_match_table = bme680_of_i2c_match, }, .probe = bme680_i2c_probe, .id_table = bme680_i2c_id, diff --git a/drivers/iio/chemical/bme680_spi.c b/drivers/iio/chemical/bme680_spi.c index c9fb05e8d0b9..d0b7bdd3f066 100644 --- a/drivers/iio/chemical/bme680_spi.c +++ b/drivers/iio/chemical/bme680_spi.c @@ -6,6 +6,7 @@ */ #include <linux/acpi.h> #include <linux/module.h> +#include <linux/of.h> #include <linux/regmap.h> #include <linux/spi/spi.h> @@ -110,10 +111,17 @@ static const struct acpi_device_id bme680_acpi_match[] = { }; MODULE_DEVICE_TABLE(acpi, bme680_acpi_match); +static const struct of_device_id bme680_of_spi_match[] = { + { .compatible = "bosch,bme680", }, + {}, +}; +MODULE_DEVICE_TABLE(of, bme680_of_spi_match); + static struct spi_driver bme680_spi_driver = { .driver = { .name = "bme680_spi", .acpi_match_table = ACPI_PTR(bme680_acpi_match), + .of_match_table = bme680_of_spi_match, }, .probe = bme680_spi_probe, .id_table = bme680_spi_id, diff --git a/drivers/iio/chemical/pms7003.c b/drivers/iio/chemical/pms7003.c new file mode 100644 index 000000000000..db8e7b2327b3 --- /dev/null +++ b/drivers/iio/chemical/pms7003.c @@ -0,0 +1,340 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Plantower PMS7003 particulate matter sensor driver + * + * Copyright (c) Tomasz Duszynski <tduszyns@gmail.com> + */ + +#include <asm/unaligned.h> +#include <linux/completion.h> +#include <linux/device.h> +#include <linux/errno.h> +#include <linux/iio/buffer.h> +#include <linux/iio/iio.h> +#include <linux/iio/trigger_consumer.h> +#include <linux/iio/triggered_buffer.h> +#include <linux/jiffies.h> +#include <linux/kernel.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/serdev.h> + +#define PMS7003_DRIVER_NAME "pms7003" + +#define PMS7003_MAGIC 0x424d +/* last 2 data bytes hold frame checksum */ +#define PMS7003_MAX_DATA_LENGTH 28 +#define PMS7003_CHECKSUM_LENGTH 2 +#define PMS7003_PM10_OFFSET 10 +#define PMS7003_PM2P5_OFFSET 8 +#define PMS7003_PM1_OFFSET 6 + +#define PMS7003_TIMEOUT msecs_to_jiffies(6000) +#define PMS7003_CMD_LENGTH 7 +#define PMS7003_PM_MAX 1000 +#define PMS7003_PM_MIN 0 + +enum { + PM1, + PM2P5, + PM10, +}; + +enum pms7003_cmd { + CMD_WAKEUP, + CMD_ENTER_PASSIVE_MODE, + CMD_READ_PASSIVE, + CMD_SLEEP, +}; + +/* + * commands have following format: + * + * +------+------+-----+------+-----+-----------+-----------+ + * | 0x42 | 0x4d | cmd | 0x00 | arg | cksum msb | cksum lsb | + * +------+------+-----+------+-----+-----------+-----------+ + */ +static const u8 pms7003_cmd_tbl[][PMS7003_CMD_LENGTH] = { + [CMD_WAKEUP] = { 0x42, 0x4d, 0xe4, 0x00, 0x01, 0x01, 0x74 }, + [CMD_ENTER_PASSIVE_MODE] = { 0x42, 0x4d, 0xe1, 0x00, 0x00, 0x01, 0x70 }, + [CMD_READ_PASSIVE] = { 0x42, 0x4d, 0xe2, 0x00, 0x00, 0x01, 0x71 }, + [CMD_SLEEP] = { 0x42, 0x4d, 0xe4, 0x00, 0x00, 0x01, 0x73 }, +}; + +struct pms7003_frame { + u8 data[PMS7003_MAX_DATA_LENGTH]; + u16 expected_length; + u16 length; +}; + +struct pms7003_state { + struct serdev_device *serdev; + struct pms7003_frame frame; + struct completion frame_ready; + struct mutex lock; /* must be held whenever state gets touched */ +}; + +static int pms7003_do_cmd(struct pms7003_state *state, enum pms7003_cmd cmd) +{ + int ret; + + ret = serdev_device_write(state->serdev, pms7003_cmd_tbl[cmd], + PMS7003_CMD_LENGTH, PMS7003_TIMEOUT); + if (ret < PMS7003_CMD_LENGTH) + return ret < 0 ? ret : -EIO; + + ret = wait_for_completion_interruptible_timeout(&state->frame_ready, + PMS7003_TIMEOUT); + if (!ret) + ret = -ETIMEDOUT; + + return ret < 0 ? ret : 0; +} + +static u16 pms7003_get_pm(const u8 *data) +{ + return clamp_val(get_unaligned_be16(data), + PMS7003_PM_MIN, PMS7003_PM_MAX); +} + +static irqreturn_t pms7003_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct pms7003_state *state = iio_priv(indio_dev); + struct pms7003_frame *frame = &state->frame; + u16 data[3 + 1 + 4]; /* PM1, PM2P5, PM10, padding, timestamp */ + int ret; + + mutex_lock(&state->lock); + ret = pms7003_do_cmd(state, CMD_READ_PASSIVE); + if (ret) { + mutex_unlock(&state->lock); + goto err; + } + + data[PM1] = pms7003_get_pm(frame->data + PMS7003_PM1_OFFSET); + data[PM2P5] = pms7003_get_pm(frame->data + PMS7003_PM2P5_OFFSET); + data[PM10] = pms7003_get_pm(frame->data + PMS7003_PM10_OFFSET); + mutex_unlock(&state->lock); + + iio_push_to_buffers_with_timestamp(indio_dev, data, + iio_get_time_ns(indio_dev)); +err: + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +static int pms7003_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct pms7003_state *state = iio_priv(indio_dev); + struct pms7003_frame *frame = &state->frame; + int ret; + + switch (mask) { + case IIO_CHAN_INFO_PROCESSED: + switch (chan->type) { + case IIO_MASSCONCENTRATION: + mutex_lock(&state->lock); + ret = pms7003_do_cmd(state, CMD_READ_PASSIVE); + if (ret) { + mutex_unlock(&state->lock); + return ret; + } + + *val = pms7003_get_pm(frame->data + chan->address); + mutex_unlock(&state->lock); + + return IIO_VAL_INT; + default: + return -EINVAL; + } + } + + return -EINVAL; +} + +static const struct iio_info pms7003_info = { + .read_raw = pms7003_read_raw, +}; + +#define PMS7003_CHAN(_index, _mod, _addr) { \ + .type = IIO_MASSCONCENTRATION, \ + .modified = 1, \ + .channel2 = IIO_MOD_ ## _mod, \ + .address = _addr, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \ + .scan_index = _index, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 10, \ + .storagebits = 16, \ + .endianness = IIO_CPU, \ + }, \ +} + +static const struct iio_chan_spec pms7003_channels[] = { + PMS7003_CHAN(0, PM1, PMS7003_PM1_OFFSET), + PMS7003_CHAN(1, PM2P5, PMS7003_PM2P5_OFFSET), + PMS7003_CHAN(2, PM10, PMS7003_PM10_OFFSET), + IIO_CHAN_SOFT_TIMESTAMP(3), +}; + +static u16 pms7003_calc_checksum(struct pms7003_frame *frame) +{ + u16 checksum = (PMS7003_MAGIC >> 8) + (u8)(PMS7003_MAGIC & 0xff) + + (frame->length >> 8) + (u8)frame->length; + int i; + + for (i = 0; i < frame->length - PMS7003_CHECKSUM_LENGTH; i++) + checksum += frame->data[i]; + + return checksum; +} + +static bool pms7003_frame_is_okay(struct pms7003_frame *frame) +{ + int offset = frame->length - PMS7003_CHECKSUM_LENGTH; + u16 checksum = get_unaligned_be16(frame->data + offset); + + return checksum == pms7003_calc_checksum(frame); +} + +static int pms7003_receive_buf(struct serdev_device *serdev, + const unsigned char *buf, size_t size) +{ + struct iio_dev *indio_dev = serdev_device_get_drvdata(serdev); + struct pms7003_state *state = iio_priv(indio_dev); + struct pms7003_frame *frame = &state->frame; + int num; + + if (!frame->expected_length) { + u16 magic; + + /* wait for SOF and data length */ + if (size < 4) + return 0; + + magic = get_unaligned_be16(buf); + if (magic != PMS7003_MAGIC) + return 2; + + num = get_unaligned_be16(buf + 2); + if (num <= PMS7003_MAX_DATA_LENGTH) { + frame->expected_length = num; + frame->length = 0; + } + + return 4; + } + + num = min(size, (size_t)(frame->expected_length - frame->length)); + memcpy(frame->data + frame->length, buf, num); + frame->length += num; + + if (frame->length == frame->expected_length) { + if (pms7003_frame_is_okay(frame)) + complete(&state->frame_ready); + + frame->expected_length = 0; + } + + return num; +} + +static const struct serdev_device_ops pms7003_serdev_ops = { + .receive_buf = pms7003_receive_buf, + .write_wakeup = serdev_device_write_wakeup, +}; + +static void pms7003_stop(void *data) +{ + struct pms7003_state *state = data; + + pms7003_do_cmd(state, CMD_SLEEP); +} + +static const unsigned long pms7003_scan_masks[] = { 0x07, 0x00 }; + +static int pms7003_probe(struct serdev_device *serdev) +{ + struct pms7003_state *state; + struct iio_dev *indio_dev; + int ret; + + indio_dev = devm_iio_device_alloc(&serdev->dev, sizeof(*state)); + if (!indio_dev) + return -ENOMEM; + + state = iio_priv(indio_dev); + serdev_device_set_drvdata(serdev, indio_dev); + state->serdev = serdev; + indio_dev->dev.parent = &serdev->dev; + indio_dev->info = &pms7003_info; + indio_dev->name = PMS7003_DRIVER_NAME; + indio_dev->channels = pms7003_channels, + indio_dev->num_channels = ARRAY_SIZE(pms7003_channels); + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->available_scan_masks = pms7003_scan_masks; + + mutex_init(&state->lock); + init_completion(&state->frame_ready); + + serdev_device_set_client_ops(serdev, &pms7003_serdev_ops); + ret = devm_serdev_device_open(&serdev->dev, serdev); + if (ret) + return ret; + + serdev_device_set_baudrate(serdev, 9600); + serdev_device_set_flow_control(serdev, false); + + ret = serdev_device_set_parity(serdev, SERDEV_PARITY_NONE); + if (ret) + return ret; + + ret = pms7003_do_cmd(state, CMD_WAKEUP); + if (ret) { + dev_err(&serdev->dev, "failed to wakeup sensor\n"); + return ret; + } + + ret = pms7003_do_cmd(state, CMD_ENTER_PASSIVE_MODE); + if (ret) { + dev_err(&serdev->dev, "failed to enter passive mode\n"); + return ret; + } + + ret = devm_add_action_or_reset(&serdev->dev, pms7003_stop, state); + if (ret) + return ret; + + ret = devm_iio_triggered_buffer_setup(&serdev->dev, indio_dev, NULL, + pms7003_trigger_handler, NULL); + if (ret) + return ret; + + return devm_iio_device_register(&serdev->dev, indio_dev); +} + +static const struct of_device_id pms7003_of_match[] = { + { .compatible = "plantower,pms7003" }, + { } +}; +MODULE_DEVICE_TABLE(of, pms7003_of_match); + +static struct serdev_device_driver pms7003_driver = { + .driver = { + .name = PMS7003_DRIVER_NAME, + .of_match_table = pms7003_of_match, + }, + .probe = pms7003_probe, +}; +module_serdev_device_driver(pms7003_driver); + +MODULE_AUTHOR("Tomasz Duszynski <tduszyns@gmail.com>"); +MODULE_DESCRIPTION("Plantower PMS7003 particulate matter sensor driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/chemical/sgp30.c b/drivers/iio/chemical/sgp30.c new file mode 100644 index 000000000000..8cc8fe5e356d --- /dev/null +++ b/drivers/iio/chemical/sgp30.c @@ -0,0 +1,591 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * sgp30.c - Support for Sensirion SGP Gas Sensors + * + * Copyright (C) 2018 Andreas Brauchli <andreas.brauchli@sensirion.com> + * + * I2C slave address: 0x58 + * + * Datasheets: + * https://www.sensirion.com/file/datasheet_sgp30 + * https://www.sensirion.com/file/datasheet_sgpc3 + * + * TODO: + * - baseline support + * - humidity compensation + * - power mode switching (SGPC3) + */ + +#include <linux/crc8.h> +#include <linux/delay.h> +#include <linux/kthread.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/i2c.h> +#include <linux/of_device.h> +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> + +#define SGP_WORD_LEN 2 +#define SGP_CRC8_POLYNOMIAL 0x31 +#define SGP_CRC8_INIT 0xff +#define SGP_CRC8_LEN 1 +#define SGP_CMD(cmd_word) cpu_to_be16(cmd_word) +#define SGP_CMD_DURATION_US 12000 +#define SGP_MEASUREMENT_DURATION_US 50000 +#define SGP_CMD_LEN SGP_WORD_LEN +#define SGP_CMD_MAX_BUF_SIZE (SGP_CMD_LEN + 2 * SGP_WORD_LEN) +#define SGP_MEASUREMENT_LEN 2 +#define SGP30_MEASURE_INTERVAL_HZ 1 +#define SGPC3_MEASURE_INTERVAL_HZ 2 +#define SGP_VERS_PRODUCT(data) ((((data)->feature_set) & 0xf000) >> 12) +#define SGP_VERS_RESERVED(data) ((((data)->feature_set) & 0x0800) >> 11) +#define SGP_VERS_GEN(data) ((((data)->feature_set) & 0x0600) >> 9) +#define SGP_VERS_ENG_BIT(data) ((((data)->feature_set) & 0x0100) >> 8) +#define SGP_VERS_MAJOR(data) ((((data)->feature_set) & 0x00e0) >> 5) +#define SGP_VERS_MINOR(data) (((data)->feature_set) & 0x001f) + +DECLARE_CRC8_TABLE(sgp_crc8_table); + +enum sgp_product_id { + SGP30 = 0, + SGPC3, +}; + +enum sgp30_channel_idx { + SGP30_IAQ_TVOC_IDX = 0, + SGP30_IAQ_CO2EQ_IDX, + SGP30_SIG_ETOH_IDX, + SGP30_SIG_H2_IDX, +}; + +enum sgpc3_channel_idx { + SGPC3_IAQ_TVOC_IDX = 10, + SGPC3_SIG_ETOH_IDX, +}; + +enum sgp_cmd { + SGP_CMD_IAQ_INIT = SGP_CMD(0x2003), + SGP_CMD_IAQ_MEASURE = SGP_CMD(0x2008), + SGP_CMD_GET_FEATURE_SET = SGP_CMD(0x202f), + SGP_CMD_GET_SERIAL_ID = SGP_CMD(0x3682), + + SGP30_CMD_MEASURE_SIGNAL = SGP_CMD(0x2050), + + SGPC3_CMD_MEASURE_RAW = SGP_CMD(0x2046), +}; + +struct sgp_version { + u8 major; + u8 minor; +}; + +struct sgp_crc_word { + __be16 value; + u8 crc8; +} __attribute__((__packed__)); + +union sgp_reading { + u8 start; + struct sgp_crc_word raw_words[4]; +}; + +enum _iaq_buffer_state { + IAQ_BUFFER_EMPTY = 0, + IAQ_BUFFER_DEFAULT_VALS, + IAQ_BUFFER_VALID, +}; + +struct sgp_data { + struct i2c_client *client; + struct task_struct *iaq_thread; + struct mutex data_lock; + unsigned long iaq_init_start_jiffies; + unsigned long iaq_defval_skip_jiffies; + u16 product_id; + u16 feature_set; + unsigned long measure_interval_jiffies; + enum sgp_cmd iaq_init_cmd; + enum sgp_cmd measure_iaq_cmd; + enum sgp_cmd measure_gas_signals_cmd; + union sgp_reading buffer; + union sgp_reading iaq_buffer; + enum _iaq_buffer_state iaq_buffer_state; +}; + +struct sgp_device { + const struct iio_chan_spec *channels; + int num_channels; +}; + +static const struct sgp_version supported_versions_sgp30[] = { + { + .major = 1, + .minor = 0, + }, +}; + +static const struct sgp_version supported_versions_sgpc3[] = { + { + .major = 0, + .minor = 4, + }, +}; + +static const struct iio_chan_spec sgp30_channels[] = { + { + .type = IIO_CONCENTRATION, + .channel2 = IIO_MOD_VOC, + .modified = 1, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), + .address = SGP30_IAQ_TVOC_IDX, + }, + { + .type = IIO_CONCENTRATION, + .channel2 = IIO_MOD_CO2, + .modified = 1, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), + .address = SGP30_IAQ_CO2EQ_IDX, + }, + { + .type = IIO_CONCENTRATION, + .channel2 = IIO_MOD_ETHANOL, + .modified = 1, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .address = SGP30_SIG_ETOH_IDX, + }, + { + .type = IIO_CONCENTRATION, + .channel2 = IIO_MOD_H2, + .modified = 1, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .address = SGP30_SIG_H2_IDX, + }, +}; + +static const struct iio_chan_spec sgpc3_channels[] = { + { + .type = IIO_CONCENTRATION, + .channel2 = IIO_MOD_VOC, + .modified = 1, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), + .address = SGPC3_IAQ_TVOC_IDX, + }, + { + .type = IIO_CONCENTRATION, + .channel2 = IIO_MOD_ETHANOL, + .modified = 1, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .address = SGPC3_SIG_ETOH_IDX, + }, +}; + +static const struct sgp_device sgp_devices[] = { + [SGP30] = { + .channels = sgp30_channels, + .num_channels = ARRAY_SIZE(sgp30_channels), + }, + [SGPC3] = { + .channels = sgpc3_channels, + .num_channels = ARRAY_SIZE(sgpc3_channels), + }, +}; + +/** + * sgp_verify_buffer() - verify the checksums of the data buffer words + * + * @data: SGP data + * @buf: Raw data buffer + * @word_count: Num data words stored in the buffer, excluding CRC bytes + * + * Return: 0 on success, negative error otherwise. + */ +static int sgp_verify_buffer(const struct sgp_data *data, + union sgp_reading *buf, size_t word_count) +{ + size_t size = word_count * (SGP_WORD_LEN + SGP_CRC8_LEN); + int i; + u8 crc; + u8 *data_buf = &buf->start; + + for (i = 0; i < size; i += SGP_WORD_LEN + SGP_CRC8_LEN) { + crc = crc8(sgp_crc8_table, &data_buf[i], SGP_WORD_LEN, + SGP_CRC8_INIT); + if (crc != data_buf[i + SGP_WORD_LEN]) { + dev_err(&data->client->dev, "CRC error\n"); + return -EIO; + } + } + + return 0; +} + +/** + * sgp_read_cmd() - reads data from sensor after issuing a command + * The caller must hold data->data_lock for the duration of the call. + * @data: SGP data + * @cmd: SGP Command to issue + * @buf: Raw data buffer to use + * @word_count: Num words to read, excluding CRC bytes + * + * Return: 0 on success, negative error otherwise. + */ +static int sgp_read_cmd(struct sgp_data *data, enum sgp_cmd cmd, + union sgp_reading *buf, size_t word_count, + unsigned long duration_us) +{ + int ret; + struct i2c_client *client = data->client; + size_t size = word_count * (SGP_WORD_LEN + SGP_CRC8_LEN); + u8 *data_buf; + + ret = i2c_master_send(client, (const char *)&cmd, SGP_CMD_LEN); + if (ret != SGP_CMD_LEN) + return -EIO; + usleep_range(duration_us, duration_us + 1000); + + if (word_count == 0) + return 0; + + data_buf = &buf->start; + ret = i2c_master_recv(client, data_buf, size); + if (ret < 0) + return ret; + if (ret != size) + return -EIO; + + return sgp_verify_buffer(data, buf, word_count); +} + +/** + * sgp_measure_iaq() - measure and retrieve IAQ values from sensor + * The caller must hold data->data_lock for the duration of the call. + * @data: SGP data + * + * Return: 0 on success, -EBUSY on default values, negative error + * otherwise. + */ + +static int sgp_measure_iaq(struct sgp_data *data) +{ + int ret; + /* data contains default values */ + bool default_vals = !time_after(jiffies, data->iaq_init_start_jiffies + + data->iaq_defval_skip_jiffies); + + ret = sgp_read_cmd(data, data->measure_iaq_cmd, &data->iaq_buffer, + SGP_MEASUREMENT_LEN, SGP_MEASUREMENT_DURATION_US); + if (ret < 0) + return ret; + + data->iaq_buffer_state = IAQ_BUFFER_DEFAULT_VALS; + + if (default_vals) + return -EBUSY; + + data->iaq_buffer_state = IAQ_BUFFER_VALID; + + return 0; +} + +static void sgp_iaq_thread_sleep_until(const struct sgp_data *data, + unsigned long sleep_jiffies) +{ + const long IAQ_POLL = 50000; + + while (!time_after(jiffies, sleep_jiffies)) { + usleep_range(IAQ_POLL, IAQ_POLL + 10000); + if (kthread_should_stop() || data->iaq_init_start_jiffies == 0) + return; + } +} + +static int sgp_iaq_threadfn(void *p) +{ + struct sgp_data *data = (struct sgp_data *)p; + unsigned long next_update_jiffies; + int ret; + + while (!kthread_should_stop()) { + mutex_lock(&data->data_lock); + if (data->iaq_init_start_jiffies == 0) { + ret = sgp_read_cmd(data, data->iaq_init_cmd, NULL, 0, + SGP_CMD_DURATION_US); + if (ret < 0) + goto unlock_sleep_continue; + data->iaq_init_start_jiffies = jiffies; + } + + ret = sgp_measure_iaq(data); + if (ret && ret != -EBUSY) { + dev_warn(&data->client->dev, + "IAQ measurement error [%d]\n", ret); + } +unlock_sleep_continue: + next_update_jiffies = jiffies + data->measure_interval_jiffies; + mutex_unlock(&data->data_lock); + sgp_iaq_thread_sleep_until(data, next_update_jiffies); + } + + return 0; +} + +static int sgp_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, + int *val2, long mask) +{ + struct sgp_data *data = iio_priv(indio_dev); + struct sgp_crc_word *words; + int ret; + + switch (mask) { + case IIO_CHAN_INFO_PROCESSED: + mutex_lock(&data->data_lock); + if (data->iaq_buffer_state != IAQ_BUFFER_VALID) { + mutex_unlock(&data->data_lock); + return -EBUSY; + } + words = data->iaq_buffer.raw_words; + switch (chan->address) { + case SGP30_IAQ_TVOC_IDX: + case SGPC3_IAQ_TVOC_IDX: + *val = 0; + *val2 = be16_to_cpu(words[1].value); + ret = IIO_VAL_INT_PLUS_NANO; + break; + case SGP30_IAQ_CO2EQ_IDX: + *val = 0; + *val2 = be16_to_cpu(words[0].value); + ret = IIO_VAL_INT_PLUS_MICRO; + break; + default: + ret = -EINVAL; + break; + } + mutex_unlock(&data->data_lock); + break; + case IIO_CHAN_INFO_RAW: + mutex_lock(&data->data_lock); + if (chan->address == SGPC3_SIG_ETOH_IDX) { + if (data->iaq_buffer_state == IAQ_BUFFER_EMPTY) + ret = -EBUSY; + else + ret = 0; + words = data->iaq_buffer.raw_words; + } else { + ret = sgp_read_cmd(data, data->measure_gas_signals_cmd, + &data->buffer, SGP_MEASUREMENT_LEN, + SGP_MEASUREMENT_DURATION_US); + words = data->buffer.raw_words; + } + if (ret) { + mutex_unlock(&data->data_lock); + return ret; + } + + switch (chan->address) { + case SGP30_SIG_ETOH_IDX: + *val = be16_to_cpu(words[1].value); + ret = IIO_VAL_INT; + break; + case SGPC3_SIG_ETOH_IDX: + case SGP30_SIG_H2_IDX: + *val = be16_to_cpu(words[0].value); + ret = IIO_VAL_INT; + break; + default: + ret = -EINVAL; + break; + } + mutex_unlock(&data->data_lock); + break; + default: + return -EINVAL; + } + + return ret; +} + +static int sgp_check_compat(struct sgp_data *data, + unsigned int product_id) +{ + const struct sgp_version *supported_versions; + u16 ix, num_fs; + u16 product, generation, major, minor; + + /* driver does not match product */ + generation = SGP_VERS_GEN(data); + if (generation != 0) { + dev_err(&data->client->dev, + "incompatible product generation %d != 0", generation); + return -ENODEV; + } + + product = SGP_VERS_PRODUCT(data); + if (product != product_id) { + dev_err(&data->client->dev, + "sensor reports a different product: 0x%04hx\n", + product); + return -ENODEV; + } + + if (SGP_VERS_RESERVED(data)) + dev_warn(&data->client->dev, "reserved bit is set\n"); + + /* engineering samples are not supported: no interface guarantees */ + if (SGP_VERS_ENG_BIT(data)) + return -ENODEV; + + switch (product) { + case SGP30: + supported_versions = supported_versions_sgp30; + num_fs = ARRAY_SIZE(supported_versions_sgp30); + break; + case SGPC3: + supported_versions = supported_versions_sgpc3; + num_fs = ARRAY_SIZE(supported_versions_sgpc3); + break; + default: + return -ENODEV; + } + + major = SGP_VERS_MAJOR(data); + minor = SGP_VERS_MINOR(data); + for (ix = 0; ix < num_fs; ix++) { + if (major == supported_versions[ix].major && + minor >= supported_versions[ix].minor) + return 0; + } + dev_err(&data->client->dev, "unsupported sgp version: %d.%d\n", + major, minor); + + return -ENODEV; +} + +static void sgp_init(struct sgp_data *data) +{ + data->iaq_init_cmd = SGP_CMD_IAQ_INIT; + data->iaq_init_start_jiffies = 0; + data->iaq_buffer_state = IAQ_BUFFER_EMPTY; + switch (SGP_VERS_PRODUCT(data)) { + case SGP30: + data->measure_interval_jiffies = SGP30_MEASURE_INTERVAL_HZ * HZ; + data->measure_iaq_cmd = SGP_CMD_IAQ_MEASURE; + data->measure_gas_signals_cmd = SGP30_CMD_MEASURE_SIGNAL; + data->product_id = SGP30; + data->iaq_defval_skip_jiffies = 15 * HZ; + break; + case SGPC3: + data->measure_interval_jiffies = SGPC3_MEASURE_INTERVAL_HZ * HZ; + data->measure_iaq_cmd = SGPC3_CMD_MEASURE_RAW; + data->measure_gas_signals_cmd = SGPC3_CMD_MEASURE_RAW; + data->product_id = SGPC3; + data->iaq_defval_skip_jiffies = + 43 * data->measure_interval_jiffies; + break; + }; +} + +static const struct iio_info sgp_info = { + .read_raw = sgp_read_raw, +}; + +static const struct of_device_id sgp_dt_ids[] = { + { .compatible = "sensirion,sgp30", .data = (void *)SGP30 }, + { .compatible = "sensirion,sgpc3", .data = (void *)SGPC3 }, + { } +}; + +static int sgp_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct iio_dev *indio_dev; + struct sgp_data *data; + const struct of_device_id *of_id; + unsigned long product_id; + int ret; + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + of_id = of_match_device(sgp_dt_ids, &client->dev); + if (of_id) + product_id = (unsigned long)of_id->data; + else + product_id = id->driver_data; + + data = iio_priv(indio_dev); + i2c_set_clientdata(client, indio_dev); + data->client = client; + crc8_populate_msb(sgp_crc8_table, SGP_CRC8_POLYNOMIAL); + mutex_init(&data->data_lock); + + /* get feature set version and write it to client data */ + ret = sgp_read_cmd(data, SGP_CMD_GET_FEATURE_SET, &data->buffer, 1, + SGP_CMD_DURATION_US); + if (ret < 0) + return ret; + + data->feature_set = be16_to_cpu(data->buffer.raw_words[0].value); + + ret = sgp_check_compat(data, product_id); + if (ret) + return ret; + + indio_dev->dev.parent = &client->dev; + indio_dev->info = &sgp_info; + indio_dev->name = id->name; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = sgp_devices[product_id].channels; + indio_dev->num_channels = sgp_devices[product_id].num_channels; + + sgp_init(data); + + ret = devm_iio_device_register(&client->dev, indio_dev); + if (ret) { + dev_err(&client->dev, "failed to register iio device\n"); + return ret; + } + + data->iaq_thread = kthread_run(sgp_iaq_threadfn, data, + "%s-iaq", data->client->name); + + return 0; +} + +static int sgp_remove(struct i2c_client *client) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct sgp_data *data = iio_priv(indio_dev); + + if (data->iaq_thread) + kthread_stop(data->iaq_thread); + + return 0; +} + +static const struct i2c_device_id sgp_id[] = { + { "sgp30", SGP30 }, + { "sgpc3", SGPC3 }, + { } +}; + +MODULE_DEVICE_TABLE(i2c, sgp_id); +MODULE_DEVICE_TABLE(of, sgp_dt_ids); + +static struct i2c_driver sgp_driver = { + .driver = { + .name = "sgp30", + .of_match_table = of_match_ptr(sgp_dt_ids), + }, + .probe = sgp_probe, + .remove = sgp_remove, + .id_table = sgp_id, +}; +module_i2c_driver(sgp_driver); + +MODULE_AUTHOR("Andreas Brauchli <andreas.brauchli@sensirion.com>"); +MODULE_AUTHOR("Pascal Sachs <pascal.sachs@sensirion.com>"); +MODULE_DESCRIPTION("Sensirion SGP gas sensors"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/chemical/sps30.c b/drivers/iio/chemical/sps30.c new file mode 100644 index 000000000000..edbb956e81e8 --- /dev/null +++ b/drivers/iio/chemical/sps30.c @@ -0,0 +1,548 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Sensirion SPS30 particulate matter sensor driver + * + * Copyright (c) Tomasz Duszynski <tduszyns@gmail.com> + * + * I2C slave address: 0x69 + */ + +#include <asm/unaligned.h> +#include <linux/crc8.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/kernel.h> +#include <linux/module.h> + +#define SPS30_CRC8_POLYNOMIAL 0x31 +/* max number of bytes needed to store PM measurements or serial string */ +#define SPS30_MAX_READ_SIZE 48 +/* sensor measures reliably up to 3000 ug / m3 */ +#define SPS30_MAX_PM 3000 +/* minimum and maximum self cleaning periods in seconds */ +#define SPS30_AUTO_CLEANING_PERIOD_MIN 0 +#define SPS30_AUTO_CLEANING_PERIOD_MAX 604800 + +/* SPS30 commands */ +#define SPS30_START_MEAS 0x0010 +#define SPS30_STOP_MEAS 0x0104 +#define SPS30_RESET 0xd304 +#define SPS30_READ_DATA_READY_FLAG 0x0202 +#define SPS30_READ_DATA 0x0300 +#define SPS30_READ_SERIAL 0xd033 +#define SPS30_START_FAN_CLEANING 0x5607 +#define SPS30_AUTO_CLEANING_PERIOD 0x8004 +/* not a sensor command per se, used only to distinguish write from read */ +#define SPS30_READ_AUTO_CLEANING_PERIOD 0x8005 + +enum { + PM1, + PM2P5, + PM4, + PM10, +}; + +enum { + RESET, + MEASURING, +}; + +struct sps30_state { + struct i2c_client *client; + /* + * Guards against concurrent access to sensor registers. + * Must be held whenever sequence of commands is to be executed. + */ + struct mutex lock; + int state; +}; + +DECLARE_CRC8_TABLE(sps30_crc8_table); + +static int sps30_write_then_read(struct sps30_state *state, u8 *txbuf, + int txsize, u8 *rxbuf, int rxsize) +{ + int ret; + + /* + * Sensor does not support repeated start so instead of + * sending two i2c messages in a row we just send one by one. + */ + ret = i2c_master_send(state->client, txbuf, txsize); + if (ret != txsize) + return ret < 0 ? ret : -EIO; + + if (!rxbuf) + return 0; + + ret = i2c_master_recv(state->client, rxbuf, rxsize); + if (ret != rxsize) + return ret < 0 ? ret : -EIO; + + return 0; +} + +static int sps30_do_cmd(struct sps30_state *state, u16 cmd, u8 *data, int size) +{ + /* + * Internally sensor stores measurements in a following manner: + * + * PM1: upper two bytes, crc8, lower two bytes, crc8 + * PM2P5: upper two bytes, crc8, lower two bytes, crc8 + * PM4: upper two bytes, crc8, lower two bytes, crc8 + * PM10: upper two bytes, crc8, lower two bytes, crc8 + * + * What follows next are number concentration measurements and + * typical particle size measurement which we omit. + */ + u8 buf[SPS30_MAX_READ_SIZE] = { cmd >> 8, cmd }; + int i, ret = 0; + + switch (cmd) { + case SPS30_START_MEAS: + buf[2] = 0x03; + buf[3] = 0x00; + buf[4] = crc8(sps30_crc8_table, &buf[2], 2, CRC8_INIT_VALUE); + ret = sps30_write_then_read(state, buf, 5, NULL, 0); + break; + case SPS30_STOP_MEAS: + case SPS30_RESET: + case SPS30_START_FAN_CLEANING: + ret = sps30_write_then_read(state, buf, 2, NULL, 0); + break; + case SPS30_READ_AUTO_CLEANING_PERIOD: + buf[0] = SPS30_AUTO_CLEANING_PERIOD >> 8; + buf[1] = (u8)SPS30_AUTO_CLEANING_PERIOD; + /* fall through */ + case SPS30_READ_DATA_READY_FLAG: + case SPS30_READ_DATA: + case SPS30_READ_SERIAL: + /* every two data bytes are checksummed */ + size += size / 2; + ret = sps30_write_then_read(state, buf, 2, buf, size); + break; + case SPS30_AUTO_CLEANING_PERIOD: + buf[2] = data[0]; + buf[3] = data[1]; + buf[4] = crc8(sps30_crc8_table, &buf[2], 2, CRC8_INIT_VALUE); + buf[5] = data[2]; + buf[6] = data[3]; + buf[7] = crc8(sps30_crc8_table, &buf[5], 2, CRC8_INIT_VALUE); + ret = sps30_write_then_read(state, buf, 8, NULL, 0); + break; + } + + if (ret) + return ret; + + /* validate received data and strip off crc bytes */ + for (i = 0; i < size; i += 3) { + u8 crc = crc8(sps30_crc8_table, &buf[i], 2, CRC8_INIT_VALUE); + + if (crc != buf[i + 2]) { + dev_err(&state->client->dev, + "data integrity check failed\n"); + return -EIO; + } + + *data++ = buf[i]; + *data++ = buf[i + 1]; + } + + return 0; +} + +static s32 sps30_float_to_int_clamped(const u8 *fp) +{ + int val = get_unaligned_be32(fp); + int mantissa = val & GENMASK(22, 0); + /* this is fine since passed float is always non-negative */ + int exp = val >> 23; + int fraction, shift; + + /* special case 0 */ + if (!exp && !mantissa) + return 0; + + exp -= 127; + if (exp < 0) { + /* return values ranging from 1 to 99 */ + return ((((1 << 23) + mantissa) * 100) >> 23) >> (-exp); + } + + /* return values ranging from 100 to 300000 */ + shift = 23 - exp; + val = (1 << exp) + (mantissa >> shift); + if (val >= SPS30_MAX_PM) + return SPS30_MAX_PM * 100; + + fraction = mantissa & GENMASK(shift - 1, 0); + + return val * 100 + ((fraction * 100) >> shift); +} + +static int sps30_do_meas(struct sps30_state *state, s32 *data, int size) +{ + int i, ret, tries = 5; + u8 tmp[16]; + + if (state->state == RESET) { + ret = sps30_do_cmd(state, SPS30_START_MEAS, NULL, 0); + if (ret) + return ret; + + state->state = MEASURING; + } + + while (tries--) { + ret = sps30_do_cmd(state, SPS30_READ_DATA_READY_FLAG, tmp, 2); + if (ret) + return -EIO; + + /* new measurements ready to be read */ + if (tmp[1] == 1) + break; + + msleep_interruptible(300); + } + + if (tries == -1) + return -ETIMEDOUT; + + ret = sps30_do_cmd(state, SPS30_READ_DATA, tmp, sizeof(int) * size); + if (ret) + return ret; + + for (i = 0; i < size; i++) + data[i] = sps30_float_to_int_clamped(&tmp[4 * i]); + + return 0; +} + +static irqreturn_t sps30_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct sps30_state *state = iio_priv(indio_dev); + int ret; + s32 data[4 + 2]; /* PM1, PM2P5, PM4, PM10, timestamp */ + + mutex_lock(&state->lock); + ret = sps30_do_meas(state, data, 4); + mutex_unlock(&state->lock); + if (ret) + goto err; + + iio_push_to_buffers_with_timestamp(indio_dev, data, + iio_get_time_ns(indio_dev)); +err: + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +static int sps30_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct sps30_state *state = iio_priv(indio_dev); + int data[4], ret = -EINVAL; + + switch (mask) { + case IIO_CHAN_INFO_PROCESSED: + switch (chan->type) { + case IIO_MASSCONCENTRATION: + mutex_lock(&state->lock); + /* read up to the number of bytes actually needed */ + switch (chan->channel2) { + case IIO_MOD_PM1: + ret = sps30_do_meas(state, data, 1); + break; + case IIO_MOD_PM2P5: + ret = sps30_do_meas(state, data, 2); + break; + case IIO_MOD_PM4: + ret = sps30_do_meas(state, data, 3); + break; + case IIO_MOD_PM10: + ret = sps30_do_meas(state, data, 4); + break; + } + mutex_unlock(&state->lock); + if (ret) + return ret; + + *val = data[chan->address] / 100; + *val2 = (data[chan->address] % 100) * 10000; + + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_SCALE: + switch (chan->type) { + case IIO_MASSCONCENTRATION: + switch (chan->channel2) { + case IIO_MOD_PM1: + case IIO_MOD_PM2P5: + case IIO_MOD_PM4: + case IIO_MOD_PM10: + *val = 0; + *val2 = 10000; + + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } + default: + return -EINVAL; + } + } + + return -EINVAL; +} + +static int sps30_do_cmd_reset(struct sps30_state *state) +{ + int ret; + + ret = sps30_do_cmd(state, SPS30_RESET, NULL, 0); + msleep(300); + /* + * Power-on-reset causes sensor to produce some glitch on i2c bus and + * some controllers end up in error state. Recover simply by placing + * some data on the bus, for example STOP_MEAS command, which + * is NOP in this case. + */ + sps30_do_cmd(state, SPS30_STOP_MEAS, NULL, 0); + state->state = RESET; + + return ret; +} + +static ssize_t start_cleaning_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct sps30_state *state = iio_priv(indio_dev); + int val, ret; + + if (kstrtoint(buf, 0, &val) || val != 1) + return -EINVAL; + + mutex_lock(&state->lock); + ret = sps30_do_cmd(state, SPS30_START_FAN_CLEANING, NULL, 0); + mutex_unlock(&state->lock); + if (ret) + return ret; + + return len; +} + +static ssize_t cleaning_period_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct sps30_state *state = iio_priv(indio_dev); + u8 tmp[4]; + int ret; + + mutex_lock(&state->lock); + ret = sps30_do_cmd(state, SPS30_READ_AUTO_CLEANING_PERIOD, tmp, 4); + mutex_unlock(&state->lock); + if (ret) + return ret; + + return sprintf(buf, "%d\n", get_unaligned_be32(tmp)); +} + +static ssize_t cleaning_period_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct sps30_state *state = iio_priv(indio_dev); + int val, ret; + u8 tmp[4]; + + if (kstrtoint(buf, 0, &val)) + return -EINVAL; + + if ((val < SPS30_AUTO_CLEANING_PERIOD_MIN) || + (val > SPS30_AUTO_CLEANING_PERIOD_MAX)) + return -EINVAL; + + put_unaligned_be32(val, tmp); + + mutex_lock(&state->lock); + ret = sps30_do_cmd(state, SPS30_AUTO_CLEANING_PERIOD, tmp, 0); + if (ret) { + mutex_unlock(&state->lock); + return ret; + } + + msleep(20); + + /* + * sensor requires reset in order to return up to date self cleaning + * period + */ + ret = sps30_do_cmd_reset(state); + if (ret) + dev_warn(dev, + "period changed but reads will return the old value\n"); + + mutex_unlock(&state->lock); + + return len; +} + +static ssize_t cleaning_period_available_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "[%d %d %d]\n", + SPS30_AUTO_CLEANING_PERIOD_MIN, 1, + SPS30_AUTO_CLEANING_PERIOD_MAX); +} + +static IIO_DEVICE_ATTR_WO(start_cleaning, 0); +static IIO_DEVICE_ATTR_RW(cleaning_period, 0); +static IIO_DEVICE_ATTR_RO(cleaning_period_available, 0); + +static struct attribute *sps30_attrs[] = { + &iio_dev_attr_start_cleaning.dev_attr.attr, + &iio_dev_attr_cleaning_period.dev_attr.attr, + &iio_dev_attr_cleaning_period_available.dev_attr.attr, + NULL +}; + +static const struct attribute_group sps30_attr_group = { + .attrs = sps30_attrs, +}; + +static const struct iio_info sps30_info = { + .attrs = &sps30_attr_group, + .read_raw = sps30_read_raw, +}; + +#define SPS30_CHAN(_index, _mod) { \ + .type = IIO_MASSCONCENTRATION, \ + .modified = 1, \ + .channel2 = IIO_MOD_ ## _mod, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ + .address = _mod, \ + .scan_index = _index, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 19, \ + .storagebits = 32, \ + .endianness = IIO_CPU, \ + }, \ +} + +static const struct iio_chan_spec sps30_channels[] = { + SPS30_CHAN(0, PM1), + SPS30_CHAN(1, PM2P5), + SPS30_CHAN(2, PM4), + SPS30_CHAN(3, PM10), + IIO_CHAN_SOFT_TIMESTAMP(4), +}; + +static void sps30_stop_meas(void *data) +{ + struct sps30_state *state = data; + + sps30_do_cmd(state, SPS30_STOP_MEAS, NULL, 0); +} + +static const unsigned long sps30_scan_masks[] = { 0x0f, 0x00 }; + +static int sps30_probe(struct i2c_client *client) +{ + struct iio_dev *indio_dev; + struct sps30_state *state; + u8 buf[32]; + int ret; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + return -EOPNOTSUPP; + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*state)); + if (!indio_dev) + return -ENOMEM; + + state = iio_priv(indio_dev); + i2c_set_clientdata(client, indio_dev); + state->client = client; + state->state = RESET; + indio_dev->dev.parent = &client->dev; + indio_dev->info = &sps30_info; + indio_dev->name = client->name; + indio_dev->channels = sps30_channels; + indio_dev->num_channels = ARRAY_SIZE(sps30_channels); + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->available_scan_masks = sps30_scan_masks; + + mutex_init(&state->lock); + crc8_populate_msb(sps30_crc8_table, SPS30_CRC8_POLYNOMIAL); + + ret = sps30_do_cmd_reset(state); + if (ret) { + dev_err(&client->dev, "failed to reset device\n"); + return ret; + } + + ret = sps30_do_cmd(state, SPS30_READ_SERIAL, buf, sizeof(buf)); + if (ret) { + dev_err(&client->dev, "failed to read serial number\n"); + return ret; + } + /* returned serial number is already NUL terminated */ + dev_info(&client->dev, "serial number: %s\n", buf); + + ret = devm_add_action_or_reset(&client->dev, sps30_stop_meas, state); + if (ret) + return ret; + + ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev, NULL, + sps30_trigger_handler, NULL); + if (ret) + return ret; + + return devm_iio_device_register(&client->dev, indio_dev); +} + +static const struct i2c_device_id sps30_id[] = { + { "sps30" }, + { } +}; +MODULE_DEVICE_TABLE(i2c, sps30_id); + +static const struct of_device_id sps30_of_match[] = { + { .compatible = "sensirion,sps30" }, + { } +}; +MODULE_DEVICE_TABLE(of, sps30_of_match); + +static struct i2c_driver sps30_driver = { + .driver = { + .name = "sps30", + .of_match_table = sps30_of_match, + }, + .id_table = sps30_id, + .probe_new = sps30_probe, +}; +module_i2c_driver(sps30_driver); + +MODULE_AUTHOR("Tomasz Duszynski <tduszyns@gmail.com>"); +MODULE_DESCRIPTION("Sensirion SPS30 particulate matter sensor driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index 851b61eaf3da..fbef9107acad 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig @@ -148,9 +148,9 @@ config AD5686_SPI depends on SPI select AD5686 help - Say yes here to build support for Analog Devices AD5672R, AD5676, - AD5676R, AD5684, AD5684R, AD5684R, AD5685R, AD5686, AD5686R. - Voltage Output Digital to Analog Converter. + Say yes here to build support for Analog Devices AD5672R, AD5674R, + AD5676, AD5676R, AD5679R, AD5684, AD5684R, AD5684R, AD5685R, AD5686, + AD5686R Voltage Output Digital to Analog Converter. To compile this driver as a module, choose M here: the module will be called ad5686. @@ -375,6 +375,16 @@ config TI_DAC7311 If compiled as a module, it will be called ti-dac7311. +config TI_DAC7612 + tristate "Texas Instruments 12-bit 2-channel DAC driver" + depends on SPI_MASTER && GPIOLIB + help + Driver for the Texas Instruments DAC7612, DAC7612U, DAC7612UB + The driver hand drive the load pin automatically, otherwise + it needs to be toggled manually. + + If compiled as a module, it will be called ti-dac7612. + config VF610_DAC tristate "Vybrid vf610 DAC driver" depends on OF diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile index f0a37c93de8e..1369fa1d2f0e 100644 --- a/drivers/iio/dac/Makefile +++ b/drivers/iio/dac/Makefile @@ -41,4 +41,5 @@ obj-$(CONFIG_STM32_DAC) += stm32-dac.o obj-$(CONFIG_TI_DAC082S085) += ti-dac082s085.o obj-$(CONFIG_TI_DAC5571) += ti-dac5571.o obj-$(CONFIG_TI_DAC7311) += ti-dac7311.o +obj-$(CONFIG_TI_DAC7612) += ti-dac7612.o obj-$(CONFIG_VF610_DAC) += vf610_dac.o diff --git a/drivers/iio/dac/ad5686-spi.c b/drivers/iio/dac/ad5686-spi.c index 665fa6bd9ced..0188ded5137c 100644 --- a/drivers/iio/dac/ad5686-spi.c +++ b/drivers/iio/dac/ad5686-spi.c @@ -1,7 +1,8 @@ -// SPDX-License-Identifier: GPL-2.0+ +// SPDX-License-Identifier: GPL-2.0 /* - * AD5672R, AD5676, AD5676R, AD5681R, AD5682R, AD5683, AD5683R, - * AD5684, AD5684R, AD5685R, AD5686, AD5686R + * AD5672R, AD5674R, AD5676, AD5676R, AD5679R, + * AD5681R, AD5682R, AD5683, AD5683R, AD5684, + * AD5684R, AD5685R, AD5686, AD5686R * Digital to analog converters driver * * Copyright 2018 Analog Devices Inc. @@ -102,8 +103,10 @@ static int ad5686_spi_remove(struct spi_device *spi) static const struct spi_device_id ad5686_spi_id[] = { {"ad5310r", ID_AD5310R}, {"ad5672r", ID_AD5672R}, + {"ad5674r", ID_AD5674R}, {"ad5676", ID_AD5676}, {"ad5676r", ID_AD5676R}, + {"ad5679r", ID_AD5679R}, {"ad5681r", ID_AD5681R}, {"ad5682r", ID_AD5682R}, {"ad5683", ID_AD5683}, diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c index a332b93ca2c4..e06b29c565b9 100644 --- a/drivers/iio/dac/ad5686.c +++ b/drivers/iio/dac/ad5686.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +// SPDX-License-Identifier: GPL-2.0 /* * AD5686R, AD5685R, AD5684R Digital to analog converters driver * @@ -71,7 +71,7 @@ static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev, int ret; struct ad5686_state *st = iio_priv(indio_dev); unsigned int val, ref_bit_msk; - u8 shift; + u8 shift, address = 0; ret = strtobool(buf, &readin); if (ret) @@ -94,6 +94,9 @@ static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev, case AD5686_REGMAP: shift = 0; ref_bit_msk = 0; + /* AD5674R/AD5679R have 16 channels and 2 powerdown registers */ + if (chan->channel > 0x7) + address = 0x8; break; case AD5693_REGMAP: shift = 13; @@ -107,7 +110,8 @@ static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev, if (!st->use_internal_vref) val |= ref_bit_msk; - ret = st->write(st, AD5686_CMD_POWERDOWN_DAC, 0, val); + ret = st->write(st, AD5686_CMD_POWERDOWN_DAC, + address, val >> (address * 2)); return ret ? ret : len; } @@ -226,10 +230,32 @@ static struct iio_chan_spec name[] = { \ AD5868_CHANNEL(7, 7, bits, _shift), \ } +#define DECLARE_AD5679_CHANNELS(name, bits, _shift) \ +static struct iio_chan_spec name[] = { \ + AD5868_CHANNEL(0, 0, bits, _shift), \ + AD5868_CHANNEL(1, 1, bits, _shift), \ + AD5868_CHANNEL(2, 2, bits, _shift), \ + AD5868_CHANNEL(3, 3, bits, _shift), \ + AD5868_CHANNEL(4, 4, bits, _shift), \ + AD5868_CHANNEL(5, 5, bits, _shift), \ + AD5868_CHANNEL(6, 6, bits, _shift), \ + AD5868_CHANNEL(7, 7, bits, _shift), \ + AD5868_CHANNEL(8, 8, bits, _shift), \ + AD5868_CHANNEL(9, 9, bits, _shift), \ + AD5868_CHANNEL(10, 10, bits, _shift), \ + AD5868_CHANNEL(11, 11, bits, _shift), \ + AD5868_CHANNEL(12, 12, bits, _shift), \ + AD5868_CHANNEL(13, 13, bits, _shift), \ + AD5868_CHANNEL(14, 14, bits, _shift), \ + AD5868_CHANNEL(15, 15, bits, _shift), \ +} + DECLARE_AD5693_CHANNELS(ad5310r_channels, 10, 2); DECLARE_AD5693_CHANNELS(ad5311r_channels, 10, 6); DECLARE_AD5676_CHANNELS(ad5672_channels, 12, 4); +DECLARE_AD5679_CHANNELS(ad5674r_channels, 12, 4); DECLARE_AD5676_CHANNELS(ad5676_channels, 16, 0); +DECLARE_AD5679_CHANNELS(ad5679r_channels, 16, 0); DECLARE_AD5686_CHANNELS(ad5684_channels, 12, 4); DECLARE_AD5686_CHANNELS(ad5685r_channels, 14, 2); DECLARE_AD5686_CHANNELS(ad5686_channels, 16, 0); @@ -262,6 +288,12 @@ static const struct ad5686_chip_info ad5686_chip_info_tbl[] = { .num_channels = 8, .regmap_type = AD5686_REGMAP, }, + [ID_AD5674R] = { + .channels = ad5674r_channels, + .int_vref_mv = 2500, + .num_channels = 16, + .regmap_type = AD5686_REGMAP, + }, [ID_AD5675R] = { .channels = ad5676_channels, .int_vref_mv = 2500, @@ -279,6 +311,12 @@ static const struct ad5686_chip_info ad5686_chip_info_tbl[] = { .num_channels = 8, .regmap_type = AD5686_REGMAP, }, + [ID_AD5679R] = { + .channels = ad5679r_channels, + .int_vref_mv = 2500, + .num_channels = 16, + .regmap_type = AD5686_REGMAP, + }, [ID_AD5681R] = { .channels = ad5691r_channels, .int_vref_mv = 2500, diff --git a/drivers/iio/dac/ad5686.h b/drivers/iio/dac/ad5686.h index 19f6917d4738..70a779939ddb 100644 --- a/drivers/iio/dac/ad5686.h +++ b/drivers/iio/dac/ad5686.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This file is part of AD5686 DAC driver * @@ -54,9 +54,11 @@ enum ad5686_supported_device_ids { ID_AD5311R, ID_AD5671R, ID_AD5672R, + ID_AD5674R, ID_AD5675R, ID_AD5676, ID_AD5676R, + ID_AD5679R, ID_AD5681R, ID_AD5682R, ID_AD5683, diff --git a/drivers/iio/dac/ad5696-i2c.c b/drivers/iio/dac/ad5696-i2c.c index 7350d9806a11..ccf794caef43 100644 --- a/drivers/iio/dac/ad5696-i2c.c +++ b/drivers/iio/dac/ad5696-i2c.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +// SPDX-License-Identifier: GPL-2.0 /* * AD5671R, AD5675R, AD5691R, AD5692R, AD5693, AD5693R, * AD5694, AD5694R, AD5695R, AD5696, AD5696R diff --git a/drivers/iio/dac/ad5758.c b/drivers/iio/dac/ad5758.c index ef41f12bf262..2bdf1b0aee06 100644 --- a/drivers/iio/dac/ad5758.c +++ b/drivers/iio/dac/ad5758.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +// SPDX-License-Identifier: GPL-2.0 /* * AD5758 Digital to analog converters driver * diff --git a/drivers/iio/dac/ti-dac7612.c b/drivers/iio/dac/ti-dac7612.c new file mode 100644 index 000000000000..c46805144dd4 --- /dev/null +++ b/drivers/iio/dac/ti-dac7612.c @@ -0,0 +1,184 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * DAC7612 Dual, 12-Bit Serial input Digital-to-Analog Converter + * + * Copyright 2019 Qtechnology A/S + * 2019 Ricardo Ribalda <ricardo@ribalda.com> + * + * Licensed under the GPL-2. + */ +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/spi/spi.h> +#include <linux/gpio/consumer.h> +#include <linux/iio/iio.h> + +#define DAC7612_RESOLUTION 12 +#define DAC7612_ADDRESS 4 +#define DAC7612_START 5 + +struct dac7612 { + struct spi_device *spi; + struct gpio_desc *loaddacs; + uint16_t cache[2]; + + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + uint8_t data[2] ____cacheline_aligned; +}; + +static int dac7612_cmd_single(struct dac7612 *priv, int channel, u16 val) +{ + int ret; + + priv->data[0] = BIT(DAC7612_START) | (channel << DAC7612_ADDRESS); + priv->data[0] |= val >> 8; + priv->data[1] = val & 0xff; + + priv->cache[channel] = val; + + ret = spi_write(priv->spi, priv->data, sizeof(priv->data)); + if (ret) + return ret; + + gpiod_set_value(priv->loaddacs, 1); + gpiod_set_value(priv->loaddacs, 0); + + return 0; +} + +#define dac7612_CHANNEL(chan, name) { \ + .type = IIO_VOLTAGE, \ + .channel = (chan), \ + .indexed = 1, \ + .output = 1, \ + .datasheet_name = name, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ +} + +static const struct iio_chan_spec dac7612_channels[] = { + dac7612_CHANNEL(0, "OUTA"), + dac7612_CHANNEL(1, "OUTB"), +}; + +static int dac7612_read_raw(struct iio_dev *iio_dev, + const struct iio_chan_spec *chan, + int *val, int *val2, long mask) +{ + struct dac7612 *priv; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + priv = iio_priv(iio_dev); + *val = priv->cache[chan->channel]; + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + *val = 1; + return IIO_VAL_INT; + + default: + return -EINVAL; + } +} + +static int dac7612_write_raw(struct iio_dev *iio_dev, + const struct iio_chan_spec *chan, + int val, int val2, long mask) +{ + struct dac7612 *priv = iio_priv(iio_dev); + int ret; + + if (mask != IIO_CHAN_INFO_RAW) + return -EINVAL; + + if ((val >= BIT(DAC7612_RESOLUTION)) || val < 0 || val2) + return -EINVAL; + + if (val == priv->cache[chan->channel]) + return 0; + + mutex_lock(&iio_dev->mlock); + ret = dac7612_cmd_single(priv, chan->channel, val); + mutex_unlock(&iio_dev->mlock); + + return ret; +} + +static const struct iio_info dac7612_info = { + .read_raw = dac7612_read_raw, + .write_raw = dac7612_write_raw, +}; + +static int dac7612_probe(struct spi_device *spi) +{ + struct iio_dev *iio_dev; + struct dac7612 *priv; + int i; + int ret; + + iio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*priv)); + if (!iio_dev) + return -ENOMEM; + + priv = iio_priv(iio_dev); + /* + * LOADDACS pin can be controlled by the driver or externally. + * When controlled by the driver, the DAC value is updated after + * every write. + * When the driver does not control the PIN, the user or an external + * event can change the value of all DACs by pulsing down the LOADDACs + * pin. + */ + priv->loaddacs = devm_gpiod_get_optional(&spi->dev, "ti,loaddacs", + GPIOD_OUT_LOW); + if (IS_ERR(priv->loaddacs)) + return PTR_ERR(priv->loaddacs); + priv->spi = spi; + spi_set_drvdata(spi, iio_dev); + iio_dev->dev.parent = &spi->dev; + iio_dev->info = &dac7612_info; + iio_dev->modes = INDIO_DIRECT_MODE; + iio_dev->channels = dac7612_channels; + iio_dev->num_channels = ARRAY_SIZE(priv->cache); + iio_dev->name = spi_get_device_id(spi)->name; + + for (i = 0; i < ARRAY_SIZE(priv->cache); i++) { + ret = dac7612_cmd_single(priv, i, 0); + if (ret) + return ret; + } + + return devm_iio_device_register(&spi->dev, iio_dev); +} + +static const struct spi_device_id dac7612_id[] = { + {"ti-dac7612"}, + {} +}; +MODULE_DEVICE_TABLE(spi, dac7612_id); + +static const struct of_device_id dac7612_of_match[] = { + { .compatible = "ti,dac7612" }, + { .compatible = "ti,dac7612u" }, + { .compatible = "ti,dac7612ub" }, + { }, +}; +MODULE_DEVICE_TABLE(of, dac7612_of_match); + +static struct spi_driver dac7612_driver = { + .driver = { + .name = "ti-dac7612", + .of_match_table = dac7612_of_match, + }, + .probe = dac7612_probe, + .id_table = dac7612_id, +}; +module_spi_driver(dac7612_driver); + +MODULE_AUTHOR("Ricardo Ribalda <ricardo@ribalda.com>"); +MODULE_DESCRIPTION("Texas Instruments DAC7612 DAC driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/frequency/ad9523.c b/drivers/iio/frequency/ad9523.c index f3f94fbdd20a..3f9be69499ec 100644 --- a/drivers/iio/frequency/ad9523.c +++ b/drivers/iio/frequency/ad9523.c @@ -943,11 +943,14 @@ static int ad9523_setup(struct iio_dev *indio_dev) } } - for_each_clear_bit(i, &active_mask, AD9523_NUM_CHAN) - ad9523_write(indio_dev, + for_each_clear_bit(i, &active_mask, AD9523_NUM_CHAN) { + ret = ad9523_write(indio_dev, AD9523_CHANNEL_CLOCK_DIST(i), AD9523_CLK_DIST_DRIVER_MODE(TRISTATE) | AD9523_CLK_DIST_PWR_DOWN_EN); + if (ret < 0) + return ret; + } ret = ad9523_write(indio_dev, AD9523_POWER_DOWN_CTRL, 0); if (ret < 0) diff --git a/drivers/iio/imu/bmi160/bmi160.h b/drivers/iio/imu/bmi160/bmi160.h index 2351049d930b..621f5309d735 100644 --- a/drivers/iio/imu/bmi160/bmi160.h +++ b/drivers/iio/imu/bmi160/bmi160.h @@ -2,9 +2,20 @@ #ifndef BMI160_H_ #define BMI160_H_ +#include <linux/iio/iio.h> + +struct bmi160_data { + struct regmap *regmap; + struct iio_trigger *trig; +}; + extern const struct regmap_config bmi160_regmap_config; int bmi160_core_probe(struct device *dev, struct regmap *regmap, const char *name, bool use_spi); +int bmi160_enable_irq(struct regmap *regmap, bool enable); + +int bmi160_probe_trigger(struct iio_dev *indio_dev, int irq, u32 irq_type); + #endif /* BMI160_H_ */ diff --git a/drivers/iio/imu/bmi160/bmi160_core.c b/drivers/iio/imu/bmi160/bmi160_core.c index b10330b0f93f..6af65d6f1d28 100644 --- a/drivers/iio/imu/bmi160/bmi160_core.c +++ b/drivers/iio/imu/bmi160/bmi160_core.c @@ -1,26 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0 /* * BMI160 - Bosch IMU (accel, gyro plus external magnetometer) * * Copyright (c) 2016, Intel Corporation. - * - * This file is subject to the terms and conditions of version 2 of - * the GNU General Public License. See the file COPYING in the main - * directory of this archive for more details. + * Copyright (c) 2019, Martin Kelly. * * IIO core driver for BMI160, with support for I2C/SPI busses * - * TODO: magnetometer, interrupts, hardware FIFO + * TODO: magnetometer, hardware FIFO */ #include <linux/module.h> #include <linux/regmap.h> #include <linux/acpi.h> #include <linux/delay.h> +#include <linux/irq.h> +#include <linux/of_irq.h> #include <linux/iio/iio.h> #include <linux/iio/triggered_buffer.h> #include <linux/iio/trigger_consumer.h> #include <linux/iio/buffer.h> #include <linux/iio/sysfs.h> +#include <linux/iio/trigger.h> #include "bmi160.h" @@ -64,8 +65,32 @@ #define BMI160_CMD_GYRO_PM_FAST_STARTUP 0x17 #define BMI160_CMD_SOFTRESET 0xB6 +#define BMI160_REG_INT_EN 0x51 +#define BMI160_DRDY_INT_EN BIT(4) + +#define BMI160_REG_INT_OUT_CTRL 0x53 +#define BMI160_INT_OUT_CTRL_MASK 0x0f +#define BMI160_INT1_OUT_CTRL_SHIFT 0 +#define BMI160_INT2_OUT_CTRL_SHIFT 4 +#define BMI160_EDGE_TRIGGERED BIT(0) +#define BMI160_ACTIVE_HIGH BIT(1) +#define BMI160_OPEN_DRAIN BIT(2) +#define BMI160_OUTPUT_EN BIT(3) + +#define BMI160_REG_INT_LATCH 0x54 +#define BMI160_INT1_LATCH_MASK BIT(4) +#define BMI160_INT2_LATCH_MASK BIT(5) + +/* INT1 and INT2 are in the opposite order as in INT_OUT_CTRL! */ +#define BMI160_REG_INT_MAP 0x56 +#define BMI160_INT1_MAP_DRDY_EN 0x80 +#define BMI160_INT2_MAP_DRDY_EN 0x08 + #define BMI160_REG_DUMMY 0x7F +#define BMI160_NORMAL_WRITE_USLEEP 2 +#define BMI160_SUSPENDED_WRITE_USLEEP 450 + #define BMI160_ACCEL_PMU_MIN_USLEEP 3800 #define BMI160_GYRO_PMU_MIN_USLEEP 80000 #define BMI160_SOFTRESET_USLEEP 1000 @@ -108,8 +133,9 @@ enum bmi160_sensor_type { BMI160_NUM_SENSORS /* must be last */ }; -struct bmi160_data { - struct regmap *regmap; +enum bmi160_int_pin { + BMI160_PIN_INT1, + BMI160_PIN_INT2 }; const struct regmap_config bmi160_regmap_config = { @@ -273,7 +299,7 @@ int bmi160_set_mode(struct bmi160_data *data, enum bmi160_sensor_type t, cmd = bmi160_regs[t].pmu_cmd_suspend; ret = regmap_write(data->regmap, BMI160_REG_CMD, cmd); - if (ret < 0) + if (ret) return ret; usleep_range(bmi160_pmu_time[t], bmi160_pmu_time[t] + 1000); @@ -305,7 +331,7 @@ int bmi160_get_scale(struct bmi160_data *data, enum bmi160_sensor_type t, int i, ret, val; ret = regmap_read(data->regmap, bmi160_regs[t].range, &val); - if (ret < 0) + if (ret) return ret; for (i = 0; i < bmi160_scale_table[t].num; i++) @@ -328,7 +354,7 @@ static int bmi160_get_data(struct bmi160_data *data, int chan_type, reg = bmi160_regs[t].data + (axis - IIO_MOD_X) * sizeof(sample); ret = regmap_bulk_read(data->regmap, reg, &sample, sizeof(sample)); - if (ret < 0) + if (ret) return ret; *val = sign_extend32(le16_to_cpu(sample), 15); @@ -362,7 +388,7 @@ static int bmi160_get_odr(struct bmi160_data *data, enum bmi160_sensor_type t, int i, val, ret; ret = regmap_read(data->regmap, bmi160_regs[t].config, &val); - if (ret < 0) + if (ret) return ret; val &= bmi160_regs[t].config_odr_mask; @@ -394,13 +420,12 @@ static irqreturn_t bmi160_trigger_handler(int irq, void *p) indio_dev->masklength) { ret = regmap_bulk_read(data->regmap, base + i * sizeof(sample), &sample, sizeof(sample)); - if (ret < 0) + if (ret) goto done; buf[j++] = sample; } - iio_push_to_buffers_with_timestamp(indio_dev, buf, - iio_get_time_ns(indio_dev)); + iio_push_to_buffers_with_timestamp(indio_dev, buf, pf->timestamp); done: iio_trigger_notify_done(indio_dev->trig); return IRQ_HANDLED; @@ -416,18 +441,18 @@ static int bmi160_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: ret = bmi160_get_data(data, chan->type, chan->channel2, val); - if (ret < 0) + if (ret) return ret; return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: *val = 0; ret = bmi160_get_scale(data, bmi160_to_sensor(chan->type), val2); - return ret < 0 ? ret : IIO_VAL_INT_PLUS_MICRO; + return ret ? ret : IIO_VAL_INT_PLUS_MICRO; case IIO_CHAN_INFO_SAMP_FREQ: ret = bmi160_get_odr(data, bmi160_to_sensor(chan->type), val, val2); - return ret < 0 ? ret : IIO_VAL_INT_PLUS_MICRO; + return ret ? ret : IIO_VAL_INT_PLUS_MICRO; default: return -EINVAL; } @@ -498,6 +523,186 @@ static const char *bmi160_match_acpi_device(struct device *dev) return dev_name(dev); } +static int bmi160_write_conf_reg(struct regmap *regmap, unsigned int reg, + unsigned int mask, unsigned int bits, + unsigned int write_usleep) +{ + int ret; + unsigned int val; + + ret = regmap_read(regmap, reg, &val); + if (ret) + return ret; + + val = (val & ~mask) | bits; + + ret = regmap_write(regmap, reg, val); + if (ret) + return ret; + + /* + * We need to wait after writing before we can write again. See the + * datasheet, page 93. + */ + usleep_range(write_usleep, write_usleep + 1000); + + return 0; +} + +static int bmi160_config_pin(struct regmap *regmap, enum bmi160_int_pin pin, + bool open_drain, u8 irq_mask, + unsigned long write_usleep) +{ + int ret; + struct device *dev = regmap_get_device(regmap); + u8 int_out_ctrl_shift; + u8 int_latch_mask; + u8 int_map_mask; + u8 int_out_ctrl_mask; + u8 int_out_ctrl_bits; + const char *pin_name; + + switch (pin) { + case BMI160_PIN_INT1: + int_out_ctrl_shift = BMI160_INT1_OUT_CTRL_SHIFT; + int_latch_mask = BMI160_INT1_LATCH_MASK; + int_map_mask = BMI160_INT1_MAP_DRDY_EN; + break; + case BMI160_PIN_INT2: + int_out_ctrl_shift = BMI160_INT2_OUT_CTRL_SHIFT; + int_latch_mask = BMI160_INT2_LATCH_MASK; + int_map_mask = BMI160_INT2_MAP_DRDY_EN; + break; + } + int_out_ctrl_mask = BMI160_INT_OUT_CTRL_MASK << int_out_ctrl_shift; + + /* + * Enable the requested pin with the right settings: + * - Push-pull/open-drain + * - Active low/high + * - Edge/level triggered + */ + int_out_ctrl_bits = BMI160_OUTPUT_EN; + if (open_drain) + /* Default is push-pull. */ + int_out_ctrl_bits |= BMI160_OPEN_DRAIN; + int_out_ctrl_bits |= irq_mask; + int_out_ctrl_bits <<= int_out_ctrl_shift; + + ret = bmi160_write_conf_reg(regmap, BMI160_REG_INT_OUT_CTRL, + int_out_ctrl_mask, int_out_ctrl_bits, + write_usleep); + if (ret) + return ret; + + /* Set the pin to input mode with no latching. */ + ret = bmi160_write_conf_reg(regmap, BMI160_REG_INT_LATCH, + int_latch_mask, int_latch_mask, + write_usleep); + if (ret) + return ret; + + /* Map interrupts to the requested pin. */ + ret = bmi160_write_conf_reg(regmap, BMI160_REG_INT_MAP, + int_map_mask, int_map_mask, + write_usleep); + if (ret) { + switch (pin) { + case BMI160_PIN_INT1: + pin_name = "INT1"; + break; + case BMI160_PIN_INT2: + pin_name = "INT2"; + break; + } + dev_err(dev, "Failed to configure %s IRQ pin", pin_name); + } + + return ret; +} + +int bmi160_enable_irq(struct regmap *regmap, bool enable) +{ + unsigned int enable_bit = 0; + + if (enable) + enable_bit = BMI160_DRDY_INT_EN; + + return bmi160_write_conf_reg(regmap, BMI160_REG_INT_EN, + BMI160_DRDY_INT_EN, enable_bit, + BMI160_NORMAL_WRITE_USLEEP); +} +EXPORT_SYMBOL(bmi160_enable_irq); + +static int bmi160_get_irq(struct device_node *of_node, enum bmi160_int_pin *pin) +{ + int irq; + + /* Use INT1 if possible, otherwise fall back to INT2. */ + irq = of_irq_get_byname(of_node, "INT1"); + if (irq > 0) { + *pin = BMI160_PIN_INT1; + return irq; + } + + irq = of_irq_get_byname(of_node, "INT2"); + if (irq > 0) + *pin = BMI160_PIN_INT2; + + return irq; +} + +static int bmi160_config_device_irq(struct iio_dev *indio_dev, int irq_type, + enum bmi160_int_pin pin) +{ + bool open_drain; + u8 irq_mask; + struct bmi160_data *data = iio_priv(indio_dev); + struct device *dev = regmap_get_device(data->regmap); + + /* Level-triggered, active-low is the default if we set all zeroes. */ + if (irq_type == IRQF_TRIGGER_RISING) + irq_mask = BMI160_ACTIVE_HIGH | BMI160_EDGE_TRIGGERED; + else if (irq_type == IRQF_TRIGGER_FALLING) + irq_mask = BMI160_EDGE_TRIGGERED; + else if (irq_type == IRQF_TRIGGER_HIGH) + irq_mask = BMI160_ACTIVE_HIGH; + else if (irq_type == IRQF_TRIGGER_LOW) + irq_mask = 0; + else { + dev_err(&indio_dev->dev, + "Invalid interrupt type 0x%x specified\n", irq_type); + return -EINVAL; + } + + open_drain = of_property_read_bool(dev->of_node, "drive-open-drain"); + + return bmi160_config_pin(data->regmap, pin, open_drain, irq_mask, + BMI160_NORMAL_WRITE_USLEEP); +} + +static int bmi160_setup_irq(struct iio_dev *indio_dev, int irq, + enum bmi160_int_pin pin) +{ + struct irq_data *desc; + u32 irq_type; + int ret; + + desc = irq_get_irq_data(irq); + if (!desc) { + dev_err(&indio_dev->dev, "Could not find IRQ %d\n", irq); + return -EINVAL; + } + + irq_type = irqd_get_trigger_type(desc); + + ret = bmi160_config_device_irq(indio_dev, irq_type, pin); + if (ret) + return ret; + + return bmi160_probe_trigger(indio_dev, irq, irq_type); +} + static int bmi160_chip_init(struct bmi160_data *data, bool use_spi) { int ret; @@ -505,7 +710,7 @@ static int bmi160_chip_init(struct bmi160_data *data, bool use_spi) struct device *dev = regmap_get_device(data->regmap); ret = regmap_write(data->regmap, BMI160_REG_CMD, BMI160_CMD_SOFTRESET); - if (ret < 0) + if (ret) return ret; usleep_range(BMI160_SOFTRESET_USLEEP, BMI160_SOFTRESET_USLEEP + 1); @@ -516,12 +721,12 @@ static int bmi160_chip_init(struct bmi160_data *data, bool use_spi) */ if (use_spi) { ret = regmap_read(data->regmap, BMI160_REG_DUMMY, &val); - if (ret < 0) + if (ret) return ret; } ret = regmap_read(data->regmap, BMI160_REG_CHIP_ID, &val); - if (ret < 0) { + if (ret) { dev_err(dev, "Error reading chip id\n"); return ret; } @@ -532,16 +737,59 @@ static int bmi160_chip_init(struct bmi160_data *data, bool use_spi) } ret = bmi160_set_mode(data, BMI160_ACCEL, true); - if (ret < 0) + if (ret) return ret; ret = bmi160_set_mode(data, BMI160_GYRO, true); - if (ret < 0) + if (ret) return ret; return 0; } +static int bmi160_data_rdy_trigger_set_state(struct iio_trigger *trig, + bool enable) +{ + struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); + struct bmi160_data *data = iio_priv(indio_dev); + + return bmi160_enable_irq(data->regmap, enable); +} + +static const struct iio_trigger_ops bmi160_trigger_ops = { + .set_trigger_state = &bmi160_data_rdy_trigger_set_state, +}; + +int bmi160_probe_trigger(struct iio_dev *indio_dev, int irq, u32 irq_type) +{ + struct bmi160_data *data = iio_priv(indio_dev); + int ret; + + data->trig = devm_iio_trigger_alloc(&indio_dev->dev, "%s-dev%d", + indio_dev->name, indio_dev->id); + + if (data->trig == NULL) + return -ENOMEM; + + ret = devm_request_irq(&indio_dev->dev, irq, + &iio_trigger_generic_data_rdy_poll, + irq_type, "bmi160", data->trig); + if (ret) + return ret; + + data->trig->dev.parent = regmap_get_device(data->regmap); + data->trig->ops = &bmi160_trigger_ops; + iio_trigger_set_drvdata(data->trig, indio_dev); + + ret = devm_iio_trigger_register(&indio_dev->dev, data->trig); + if (ret) + return ret; + + indio_dev->trig = iio_trigger_get(data->trig); + + return 0; +} + static void bmi160_chip_uninit(void *data) { struct bmi160_data *bmi_data = data; @@ -555,6 +803,8 @@ int bmi160_core_probe(struct device *dev, struct regmap *regmap, { struct iio_dev *indio_dev; struct bmi160_data *data; + int irq; + enum bmi160_int_pin int_pin; int ret; indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); @@ -566,11 +816,11 @@ int bmi160_core_probe(struct device *dev, struct regmap *regmap, data->regmap = regmap; ret = bmi160_chip_init(data, use_spi); - if (ret < 0) + if (ret) return ret; ret = devm_add_action_or_reset(dev, bmi160_chip_uninit, data); - if (ret < 0) + if (ret) return ret; if (!name && ACPI_HANDLE(dev)) @@ -583,16 +833,23 @@ int bmi160_core_probe(struct device *dev, struct regmap *regmap, indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &bmi160_info; - ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, + iio_pollfunc_store_time, bmi160_trigger_handler, NULL); - if (ret < 0) + if (ret) return ret; - ret = devm_iio_device_register(dev, indio_dev); - if (ret < 0) - return ret; + irq = bmi160_get_irq(dev->of_node, &int_pin); + if (irq > 0) { + ret = bmi160_setup_irq(indio_dev, irq, int_pin); + if (ret) + dev_err(&indio_dev->dev, "Failed to setup IRQ %d\n", + irq); + } else { + dev_info(&indio_dev->dev, "Not setting up IRQ trigger\n"); + } - return 0; + return devm_iio_device_register(dev, indio_dev); } EXPORT_SYMBOL_GPL(bmi160_core_probe); diff --git a/drivers/iio/imu/bmi160/bmi160_i2c.c b/drivers/iio/imu/bmi160/bmi160_i2c.c index 5b1f7e6af651..e36f5e82d400 100644 --- a/drivers/iio/imu/bmi160/bmi160_i2c.c +++ b/drivers/iio/imu/bmi160/bmi160_i2c.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * BMI160 - Bosch IMU, I2C bits * * Copyright (c) 2016, Intel Corporation. * - * This file is subject to the terms and conditions of version 2 of - * the GNU General Public License. See the file COPYING in the main - * directory of this archive for more details. - * * 7-bit I2C slave address is: * - 0x68 if SDO is pulled to GND * - 0x69 if SDO is pulled to VDDIO diff --git a/drivers/iio/imu/bmi160/bmi160_spi.c b/drivers/iio/imu/bmi160/bmi160_spi.c index e521ad14eeac..c19e3df35559 100644 --- a/drivers/iio/imu/bmi160/bmi160_spi.c +++ b/drivers/iio/imu/bmi160/bmi160_spi.c @@ -1,11 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * BMI160 - Bosch IMU, SPI bits * * Copyright (c) 2016, Intel Corporation. * - * This file is subject to the terms and conditions of version 2 of - * the GNU General Public License. See the file COPYING in the main - * directory of this archive for more details. */ #include <linux/acpi.h> #include <linux/module.h> diff --git a/drivers/iio/imu/inv_mpu6050/Kconfig b/drivers/iio/imu/inv_mpu6050/Kconfig index 5483b2ea754d..d2fe9dbddda7 100644 --- a/drivers/iio/imu/inv_mpu6050/Kconfig +++ b/drivers/iio/imu/inv_mpu6050/Kconfig @@ -13,8 +13,8 @@ config INV_MPU6050_I2C select INV_MPU6050_IIO select REGMAP_I2C help - This driver supports the Invensense MPU6050/6500/9150 and ICM20608 - motion tracking devices over I2C. + This driver supports the Invensense MPU6050/6500/9150 and + ICM20608/20602 motion tracking devices over I2C. This driver can be built as a module. The module will be called inv-mpu6050-i2c. @@ -24,7 +24,7 @@ config INV_MPU6050_SPI select INV_MPU6050_IIO select REGMAP_SPI help - This driver supports the Invensense MPU6050/6500/9150 and ICM20608 - motion tracking devices over SPI. + This driver supports the Invensense MPU6050/6500/9150 and + ICM20608/20602 motion tracking devices over SPI. This driver can be built as a module. The module will be called inv-mpu6050-spi. diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index 1e428c196a82..650de0fefb7b 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -38,6 +38,29 @@ static const int gyro_scale_6050[] = {133090, 266181, 532362, 1064724}; */ static const int accel_scale[] = {598, 1196, 2392, 4785}; +static const struct inv_mpu6050_reg_map reg_set_icm20602 = { + .sample_rate_div = INV_MPU6050_REG_SAMPLE_RATE_DIV, + .lpf = INV_MPU6050_REG_CONFIG, + .accel_lpf = INV_MPU6500_REG_ACCEL_CONFIG_2, + .user_ctrl = INV_MPU6050_REG_USER_CTRL, + .fifo_en = INV_MPU6050_REG_FIFO_EN, + .gyro_config = INV_MPU6050_REG_GYRO_CONFIG, + .accl_config = INV_MPU6050_REG_ACCEL_CONFIG, + .fifo_count_h = INV_MPU6050_REG_FIFO_COUNT_H, + .fifo_r_w = INV_MPU6050_REG_FIFO_R_W, + .raw_gyro = INV_MPU6050_REG_RAW_GYRO, + .raw_accl = INV_MPU6050_REG_RAW_ACCEL, + .temperature = INV_MPU6050_REG_TEMPERATURE, + .int_enable = INV_MPU6050_REG_INT_ENABLE, + .int_status = INV_MPU6050_REG_INT_STATUS, + .pwr_mgmt_1 = INV_MPU6050_REG_PWR_MGMT_1, + .pwr_mgmt_2 = INV_MPU6050_REG_PWR_MGMT_2, + .int_pin_cfg = INV_MPU6050_REG_INT_PIN_CFG, + .accl_offset = INV_MPU6500_REG_ACCEL_OFFSET, + .gyro_offset = INV_MPU6050_REG_GYRO_OFFSET, + .i2c_if = INV_ICM20602_REG_I2C_IF, +}; + static const struct inv_mpu6050_reg_map reg_set_6500 = { .sample_rate_div = INV_MPU6050_REG_SAMPLE_RATE_DIV, .lpf = INV_MPU6050_REG_CONFIG, @@ -58,6 +81,7 @@ static const struct inv_mpu6050_reg_map reg_set_6500 = { .int_pin_cfg = INV_MPU6050_REG_INT_PIN_CFG, .accl_offset = INV_MPU6500_REG_ACCEL_OFFSET, .gyro_offset = INV_MPU6050_REG_GYRO_OFFSET, + .i2c_if = 0, }; static const struct inv_mpu6050_reg_map reg_set_6050 = { @@ -78,6 +102,7 @@ static const struct inv_mpu6050_reg_map reg_set_6050 = { .int_pin_cfg = INV_MPU6050_REG_INT_PIN_CFG, .accl_offset = INV_MPU6050_REG_ACCEL_OFFSET, .gyro_offset = INV_MPU6050_REG_GYRO_OFFSET, + .i2c_if = 0, }; static const struct inv_mpu6050_chip_config chip_config_6050 = { @@ -140,6 +165,12 @@ static const struct inv_mpu6050_hw hw_info[] = { .reg = ®_set_6500, .config = &chip_config_6050, }, + { + .whoami = INV_ICM20602_WHOAMI_VALUE, + .name = "ICM20602", + .reg = ®_set_icm20602, + .config = &chip_config_6050, + }, }; int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en, u32 mask) diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c index dd758e3d403d..e46eb4ddea21 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c @@ -127,6 +127,7 @@ static int inv_mpu_probe(struct i2c_client *client, st = iio_priv(dev_get_drvdata(&client->dev)); switch (st->chip_type) { case INV_ICM20608: + case INV_ICM20602: /* no i2c auxiliary bus on the chip */ break; default: @@ -179,6 +180,7 @@ static const struct i2c_device_id inv_mpu_id[] = { {"mpu9250", INV_MPU9250}, {"mpu9255", INV_MPU9255}, {"icm20608", INV_ICM20608}, + {"icm20602", INV_ICM20602}, {} }; @@ -213,6 +215,10 @@ static const struct of_device_id inv_of_match[] = { .compatible = "invensense,icm20608", .data = (void *)INV_ICM20608 }, + { + .compatible = "invensense,icm20602", + .data = (void *)INV_ICM20602 + }, { } }; MODULE_DEVICE_TABLE(of, inv_of_match); diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h index 6bcc11fc1b88..325afd9f5f61 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h @@ -44,6 +44,7 @@ * @int_pin_cfg; Controls interrupt pin configuration. * @accl_offset: Controls the accelerometer calibration offset. * @gyro_offset: Controls the gyroscope calibration offset. + * @i2c_if: Controls the i2c interface */ struct inv_mpu6050_reg_map { u8 sample_rate_div; @@ -65,6 +66,7 @@ struct inv_mpu6050_reg_map { u8 int_pin_cfg; u8 accl_offset; u8 gyro_offset; + u8 i2c_if; }; /*device enum */ @@ -77,6 +79,7 @@ enum inv_devices { INV_MPU9250, INV_MPU9255, INV_ICM20608, + INV_ICM20602, INV_NUM_PARTS }; @@ -195,6 +198,10 @@ struct inv_mpu6050_state { #define INV_MPU6050_BIT_PWR_ACCL_STBY 0x38 #define INV_MPU6050_BIT_PWR_GYRO_STBY 0x07 +/* ICM20602 register */ +#define INV_ICM20602_REG_I2C_IF 0x70 +#define INV_ICM20602_BIT_I2C_IF_DIS 0x40 + #define INV_MPU6050_REG_FIFO_COUNT_H 0x72 #define INV_MPU6050_REG_FIFO_R_W 0x74 @@ -261,6 +268,7 @@ struct inv_mpu6050_state { #define INV_MPU9255_WHOAMI_VALUE 0x73 #define INV_MPU6515_WHOAMI_VALUE 0x74 #define INV_ICM20608_WHOAMI_VALUE 0xAF +#define INV_ICM20602_WHOAMI_VALUE 0x12 /* scan element definition */ enum inv_mpu6050_scan { diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c index 227f50afff22..a112c3f45f74 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c @@ -31,9 +31,14 @@ static int inv_mpu_i2c_disable(struct iio_dev *indio_dev) if (ret) return ret; - st->chip_config.user_ctrl |= INV_MPU6050_BIT_I2C_IF_DIS; - ret = regmap_write(st->map, st->reg->user_ctrl, - st->chip_config.user_ctrl); + if (st->reg->i2c_if) { + ret = regmap_write(st->map, st->reg->i2c_if, + INV_ICM20602_BIT_I2C_IF_DIS); + } else { + st->chip_config.user_ctrl |= INV_MPU6050_BIT_I2C_IF_DIS; + ret = regmap_write(st->map, st->reg->user_ctrl, + st->chip_config.user_ctrl); + } if (ret) { inv_mpu6050_set_power_itg(st, false); return ret; @@ -81,6 +86,7 @@ static const struct spi_device_id inv_mpu_id[] = { {"mpu9250", INV_MPU9250}, {"mpu9255", INV_MPU9255}, {"icm20608", INV_ICM20608}, + {"icm20602", INV_ICM20602}, {} }; diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c index 8e47dccdd40f..66fbcd94642d 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c @@ -105,12 +105,10 @@ static void st_lsm6dsx_shub_wait_complete(struct st_lsm6dsx_hw *hw) static int st_lsm6dsx_shub_read_reg(struct st_lsm6dsx_hw *hw, u8 addr, u8 *data, int len) { - const struct st_lsm6dsx_shub_settings *hub_settings; int err; mutex_lock(&hw->page_lock); - hub_settings = &hw->settings->shub_settings; err = st_lsm6dsx_set_page(hw, true); if (err < 0) goto out; diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 4f5cd9f60870..4700fd5d8c90 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -87,6 +87,7 @@ static const char * const iio_chan_type_name_spec[] = { [IIO_GRAVITY] = "gravity", [IIO_POSITIONRELATIVE] = "positionrelative", [IIO_PHASE] = "phase", + [IIO_MASSCONCENTRATION] = "massconcentration", }; static const char * const iio_modifier_names[] = { @@ -127,6 +128,10 @@ static const char * const iio_modifier_names[] = { [IIO_MOD_Q] = "q", [IIO_MOD_CO2] = "co2", [IIO_MOD_VOC] = "voc", + [IIO_MOD_PM1] = "pm1", + [IIO_MOD_PM2P5] = "pm2p5", + [IIO_MOD_PM4] = "pm4", + [IIO_MOD_PM10] = "pm10", }; /* relies on pairs of these shared then separate */ diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig index 36f458433480..5190eacfeb0a 100644 --- a/drivers/iio/light/Kconfig +++ b/drivers/iio/light/Kconfig @@ -299,6 +299,16 @@ config MAX44000 To compile this driver as a module, choose M here: the module will be called max44000. +config MAX44009 + tristate "MAX44009 Ambient Light Sensor" + depends on I2C + help + Say Y here if you want to build support for Maxim Integrated's + MAX44009 ambient light sensor device. + + To compile this driver as a module, choose M here: + the module will be called max44009. + config OPT3001 tristate "Texas Instruments OPT3001 Light Sensor" depends on I2C diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile index 286bf3975372..e40794fbb435 100644 --- a/drivers/iio/light/Makefile +++ b/drivers/iio/light/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_SENSORS_LM3533) += lm3533-als.o obj-$(CONFIG_LTR501) += ltr501.o obj-$(CONFIG_LV0104CS) += lv0104cs.o obj-$(CONFIG_MAX44000) += max44000.o +obj-$(CONFIG_MAX44009) += max44009.o obj-$(CONFIG_OPT3001) += opt3001.o obj-$(CONFIG_PA12203001) += pa12203001.o obj-$(CONFIG_RPR0521) += rpr0521.o diff --git a/drivers/iio/light/isl29018.c b/drivers/iio/light/isl29018.c index b45400f8fef4..846df4dce48c 100644 --- a/drivers/iio/light/isl29018.c +++ b/drivers/iio/light/isl29018.c @@ -23,6 +23,7 @@ #include <linux/mutex.h> #include <linux/delay.h> #include <linux/regmap.h> +#include <linux/regulator/consumer.h> #include <linux/slab.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> @@ -95,6 +96,7 @@ struct isl29018_chip { struct isl29018_scale scale; int prox_scheme; bool suspended; + struct regulator *vcc_reg; }; static int isl29018_set_integration_time(struct isl29018_chip *chip, @@ -708,6 +710,16 @@ static const char *isl29018_match_acpi_device(struct device *dev, int *data) return dev_name(dev); } +static void isl29018_disable_regulator_action(void *_data) +{ + struct isl29018_chip *chip = _data; + int err; + + err = regulator_disable(chip->vcc_reg); + if (err) + pr_err("failed to disable isl29018's VCC regulator!\n"); +} + static int isl29018_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -742,6 +754,27 @@ static int isl29018_probe(struct i2c_client *client, chip->scale = isl29018_scales[chip->int_time][0]; 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; + } + + err = regulator_enable(chip->vcc_reg); + if (err) { + dev_err(&client->dev, "failed to enable VCC regulator!\n"); + return err; + } + + err = devm_add_action_or_reset(&client->dev, isl29018_disable_regulator_action, + chip); + if (err) { + dev_err(&client->dev, "failed to setup regulator cleanup action!\n"); + return err; + } + chip->regmap = devm_regmap_init_i2c(client, isl29018_chip_info_tbl[dev_id].regmap_cfg); if (IS_ERR(chip->regmap)) { @@ -768,6 +801,7 @@ static int isl29018_probe(struct i2c_client *client, static int isl29018_suspend(struct device *dev) { struct isl29018_chip *chip = iio_priv(dev_get_drvdata(dev)); + int ret; mutex_lock(&chip->lock); @@ -777,10 +811,13 @@ static int isl29018_suspend(struct device *dev) * So we do not have much to do here. */ chip->suspended = true; + ret = regulator_disable(chip->vcc_reg); + if (ret) + dev_err(dev, "failed to disable VCC regulator\n"); mutex_unlock(&chip->lock); - return 0; + return ret; } static int isl29018_resume(struct device *dev) @@ -790,6 +827,13 @@ static int isl29018_resume(struct device *dev) mutex_lock(&chip->lock); + err = regulator_enable(chip->vcc_reg); + if (err) { + dev_err(dev, "failed to enable VCC regulator\n"); + mutex_unlock(&chip->lock); + return err; + } + err = isl29018_chip_init(chip); if (!err) chip->suspended = false; diff --git a/drivers/iio/light/max44009.c b/drivers/iio/light/max44009.c new file mode 100644 index 000000000000..00ba15499638 --- /dev/null +++ b/drivers/iio/light/max44009.c @@ -0,0 +1,555 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * max44009.c - Support for MAX44009 Ambient Light Sensor + * + * Copyright (c) 2019 Robert Eshleman <bobbyeshleman@gmail.com> + * + * Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX44009.pdf + * + * TODO: Support continuous mode and configuring from manual mode to + * automatic mode. + * + * Default I2C address: 0x4a + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/bits.h> +#include <linux/i2c.h> +#include <linux/iio/events.h> +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/util_macros.h> + +#define MAX44009_DRV_NAME "max44009" + +/* Registers in datasheet order */ +#define MAX44009_REG_INT_STATUS 0x0 +#define MAX44009_REG_INT_EN 0x1 +#define MAX44009_REG_CFG 0x2 +#define MAX44009_REG_LUX_HI 0x3 +#define MAX44009_REG_LUX_LO 0x4 +#define MAX44009_REG_UPPER_THR 0x5 +#define MAX44009_REG_LOWER_THR 0x6 +#define MAX44009_REG_THR_TIMER 0x7 + +#define MAX44009_CFG_TIM_MASK GENMASK(2, 0) +#define MAX44009_CFG_MAN_MODE_MASK BIT(6) + +/* The maximum rising threshold for the max44009 */ +#define MAX44009_MAXIMUM_THRESHOLD 7520256 + +#define MAX44009_THRESH_EXP_MASK (0xf << 4) +#define MAX44009_THRESH_EXP_RSHIFT 4 +#define MAX44009_THRESH_MANT_LSHIFT 4 +#define MAX44009_THRESH_MANT_MASK 0xf + +#define MAX44009_UPPER_THR_MINIMUM 15 + +/* The max44009 always scales raw readings by 0.045 and is non-configurable */ +#define MAX44009_SCALE_NUMERATOR 45 +#define MAX44009_SCALE_DENOMINATOR 1000 + +/* The fixed-point fractional multiplier for de-scaling threshold values */ +#define MAX44009_FRACT_MULT 1000000 + +static const u32 max44009_int_time_ns_array[] = { + 800000000, + 400000000, + 200000000, + 100000000, + 50000000, /* Manual mode only */ + 25000000, /* Manual mode only */ + 12500000, /* Manual mode only */ + 6250000, /* Manual mode only */ +}; + +static const char max44009_int_time_str[] = + "0.8 " + "0.4 " + "0.2 " + "0.1 " + "0.05 " + "0.025 " + "0.0125 " + "0.00625"; + +struct max44009_data { + struct i2c_client *client; + struct mutex lock; +}; + +static const struct iio_event_spec max44009_event_spec[] = { + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_RISING, + .mask_separate = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_ENABLE), + }, + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_FALLING, + .mask_separate = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_ENABLE), + }, +}; + +static const struct iio_chan_spec max44009_channels[] = { + { + .type = IIO_LIGHT, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | + BIT(IIO_CHAN_INFO_INT_TIME), + .event_spec = max44009_event_spec, + .num_event_specs = ARRAY_SIZE(max44009_event_spec), + }, +}; + +static int max44009_read_int_time(struct max44009_data *data) +{ + + int ret = i2c_smbus_read_byte_data(data->client, MAX44009_REG_CFG); + + if (ret < 0) + return ret; + + return max44009_int_time_ns_array[ret & MAX44009_CFG_TIM_MASK]; +} + +static int max44009_write_int_time(struct max44009_data *data, + int val, int val2) +{ + struct i2c_client *client = data->client; + int ret, int_time, config; + s64 ns; + + ns = val * NSEC_PER_SEC + val2; + int_time = find_closest_descending( + ns, + max44009_int_time_ns_array, + ARRAY_SIZE(max44009_int_time_ns_array)); + + ret = i2c_smbus_read_byte_data(client, MAX44009_REG_CFG); + if (ret < 0) + return ret; + + config = ret; + config &= int_time; + + /* + * To set the integration time, the device must also be in manual + * mode. + */ + config |= MAX44009_CFG_MAN_MODE_MASK; + + return i2c_smbus_write_byte_data(client, MAX44009_REG_CFG, config); +} + +static int max44009_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int val, + int val2, long mask) +{ + struct max44009_data *data = iio_priv(indio_dev); + int ret; + + if (mask == IIO_CHAN_INFO_INT_TIME && chan->type == IIO_LIGHT) { + mutex_lock(&data->lock); + ret = max44009_write_int_time(data, val, val2); + mutex_unlock(&data->lock); + return ret; + } + return -EINVAL; +} + +static int max44009_write_raw_get_fmt(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + long mask) +{ + return IIO_VAL_INT_PLUS_NANO; +} + +static int max44009_lux_raw(u8 hi, u8 lo) +{ + int mantissa; + int exponent; + + /* + * The mantissa consists of the low nibble of the Lux High Byte + * and the low nibble of the Lux Low Byte. + */ + mantissa = ((hi & 0xf) << 4) | (lo & 0xf); + + /* The exponent byte is just the upper nibble of the Lux High Byte */ + exponent = (hi >> 4) & 0xf; + + /* + * The exponent value is base 2 to the power of the raw exponent byte. + */ + exponent = 1 << exponent; + + return exponent * mantissa; +} + +#define MAX44009_READ_LUX_XFER_LEN (4) + +static int max44009_read_lux_raw(struct max44009_data *data) +{ + int ret; + u8 hireg = MAX44009_REG_LUX_HI; + u8 loreg = MAX44009_REG_LUX_LO; + u8 lo = 0; + u8 hi = 0; + + struct i2c_msg msgs[] = { + { + .addr = data->client->addr, + .flags = 0, + .len = sizeof(hireg), + .buf = &hireg, + }, + { + .addr = data->client->addr, + .flags = I2C_M_RD, + .len = sizeof(hi), + .buf = &hi, + }, + { + .addr = data->client->addr, + .flags = 0, + .len = sizeof(loreg), + .buf = &loreg, + }, + { + .addr = data->client->addr, + .flags = I2C_M_RD, + .len = sizeof(lo), + .buf = &lo, + } + }; + + /* + * Use i2c_transfer instead of smbus read because i2c_transfer + * does NOT use a stop bit between address write and data read. + * Using a stop bit causes disjoint upper/lower byte reads and + * reduces accuracy. + */ + ret = i2c_transfer(data->client->adapter, + msgs, MAX44009_READ_LUX_XFER_LEN); + + if (ret != MAX44009_READ_LUX_XFER_LEN) + return -EIO; + + return max44009_lux_raw(hi, lo); +} + +static int max44009_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, + int *val2, long mask) +{ + struct max44009_data *data = iio_priv(indio_dev); + int lux_raw; + int ret; + + switch (mask) { + case IIO_CHAN_INFO_PROCESSED: + switch (chan->type) { + case IIO_LIGHT: + ret = max44009_read_lux_raw(data); + if (ret < 0) + return ret; + lux_raw = ret; + + *val = lux_raw * MAX44009_SCALE_NUMERATOR; + *val2 = MAX44009_SCALE_DENOMINATOR; + return IIO_VAL_FRACTIONAL; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_INT_TIME: + switch (chan->type) { + case IIO_LIGHT: + ret = max44009_read_int_time(data); + if (ret < 0) + return ret; + + *val2 = ret; + *val = 0; + return IIO_VAL_INT_PLUS_NANO; + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + +static IIO_CONST_ATTR(illuminance_integration_time_available, + max44009_int_time_str); + +static struct attribute *max44009_attributes[] = { + &iio_const_attr_illuminance_integration_time_available.dev_attr.attr, + NULL, +}; + +static const struct attribute_group max44009_attribute_group = { + .attrs = max44009_attributes, +}; + +static int max44009_threshold_byte_from_fraction(int integral, int fractional) +{ + int mantissa, exp; + + if ((integral <= 0 && fractional <= 0) || + integral > MAX44009_MAXIMUM_THRESHOLD || + (integral == MAX44009_MAXIMUM_THRESHOLD && fractional != 0)) + return -EINVAL; + + /* Reverse scaling of fixed-point integral */ + mantissa = integral * MAX44009_SCALE_DENOMINATOR; + mantissa /= MAX44009_SCALE_NUMERATOR; + + /* Reverse scaling of fixed-point fractional */ + mantissa += fractional / MAX44009_FRACT_MULT * + (MAX44009_SCALE_DENOMINATOR / MAX44009_SCALE_NUMERATOR); + + for (exp = 0; mantissa > 0xff; exp++) + mantissa >>= 1; + + mantissa >>= 4; + mantissa &= 0xf; + exp <<= 4; + + return exp | mantissa; +} + +static int max44009_get_thr_reg(enum iio_event_direction dir) +{ + switch (dir) { + case IIO_EV_DIR_RISING: + return MAX44009_REG_UPPER_THR; + case IIO_EV_DIR_FALLING: + return MAX44009_REG_LOWER_THR; + default: + return -EINVAL; + } +} + +static int max44009_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 max44009_data *data = iio_priv(indio_dev); + int reg, threshold; + + if (info != IIO_EV_INFO_VALUE || chan->type != IIO_LIGHT) + return -EINVAL; + + threshold = max44009_threshold_byte_from_fraction(val, val2); + if (threshold < 0) + return threshold; + + reg = max44009_get_thr_reg(dir); + if (reg < 0) + return reg; + + return i2c_smbus_write_byte_data(data->client, reg, threshold); +} + +static int max44009_read_threshold(struct iio_dev *indio_dev, + enum iio_event_direction dir) +{ + struct max44009_data *data = iio_priv(indio_dev); + int byte, reg; + int mantissa, exponent; + + reg = max44009_get_thr_reg(dir); + if (reg < 0) + return reg; + + byte = i2c_smbus_read_byte_data(data->client, reg); + if (byte < 0) + return byte; + + mantissa = byte & MAX44009_THRESH_MANT_MASK; + mantissa <<= MAX44009_THRESH_MANT_LSHIFT; + + /* + * To get the upper threshold, always adds the minimum upper threshold + * value to the shifted byte value (see datasheet). + */ + if (dir == IIO_EV_DIR_RISING) + mantissa += MAX44009_UPPER_THR_MINIMUM; + + /* + * Exponent is base 2 to the power of the threshold exponent byte + * value + */ + exponent = byte & MAX44009_THRESH_EXP_MASK; + exponent >>= MAX44009_THRESH_EXP_RSHIFT; + + return (1 << exponent) * mantissa; +} + +static int max44009_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) +{ + int ret; + int threshold; + + if (chan->type != IIO_LIGHT || type != IIO_EV_TYPE_THRESH) + return -EINVAL; + + ret = max44009_read_threshold(indio_dev, dir); + if (ret < 0) + return ret; + threshold = ret; + + *val = threshold * MAX44009_SCALE_NUMERATOR; + *val2 = MAX44009_SCALE_DENOMINATOR; + + return IIO_VAL_FRACTIONAL; +} + +static int max44009_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 max44009_data *data = iio_priv(indio_dev); + int ret; + + if (chan->type != IIO_LIGHT || type != IIO_EV_TYPE_THRESH) + return -EINVAL; + + ret = i2c_smbus_write_byte_data(data->client, + MAX44009_REG_INT_EN, state); + if (ret < 0) + return ret; + + /* + * Set device to trigger interrupt immediately upon exceeding + * the threshold limit. + */ + return i2c_smbus_write_byte_data(data->client, + MAX44009_REG_THR_TIMER, 0); +} + +static int max44009_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 max44009_data *data = iio_priv(indio_dev); + + if (chan->type != IIO_LIGHT || type != IIO_EV_TYPE_THRESH) + return -EINVAL; + + return i2c_smbus_read_byte_data(data->client, MAX44009_REG_INT_EN); +} + +static const struct iio_info max44009_info = { + .read_raw = max44009_read_raw, + .write_raw = max44009_write_raw, + .write_raw_get_fmt = max44009_write_raw_get_fmt, + .read_event_value = max44009_read_event_value, + .read_event_config = max44009_read_event_config, + .write_event_value = max44009_write_event_value, + .write_event_config = max44009_write_event_config, + .attrs = &max44009_attribute_group, +}; + +static irqreturn_t max44009_threaded_irq_handler(int irq, void *p) +{ + struct iio_dev *indio_dev = p; + struct max44009_data *data = iio_priv(indio_dev); + int ret; + + ret = i2c_smbus_read_byte_data(data->client, MAX44009_REG_INT_STATUS); + if (ret) { + iio_push_event(indio_dev, + IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_EITHER), + iio_get_time_ns(indio_dev)); + + return IRQ_HANDLED; + } + + return IRQ_NONE; +} + +static int max44009_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct max44009_data *data; + struct iio_dev *indio_dev; + int ret; + + 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; + indio_dev->dev.parent = &client->dev; + indio_dev->info = &max44009_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->name = MAX44009_DRV_NAME; + indio_dev->channels = max44009_channels; + indio_dev->num_channels = ARRAY_SIZE(max44009_channels); + mutex_init(&data->lock); + + /* Clear any stale interrupt bit */ + ret = i2c_smbus_read_byte_data(client, MAX44009_REG_CFG); + if (ret < 0) + return ret; + + if (client->irq > 0) { + ret = devm_request_threaded_irq(&client->dev, client->irq, + NULL, + max44009_threaded_irq_handler, + IRQF_TRIGGER_FALLING | + IRQF_ONESHOT | IRQF_SHARED, + "max44009_event", + indio_dev); + if (ret < 0) + return ret; + } + + return devm_iio_device_register(&client->dev, indio_dev); +} + +static const struct i2c_device_id max44009_id[] = { + { "max44009", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, max44009_id); + +static struct i2c_driver max44009_driver = { + .driver = { + .name = MAX44009_DRV_NAME, + }, + .probe = max44009_probe, + .id_table = max44009_id, +}; +module_i2c_driver(max44009_driver); + +static const struct of_device_id max44009_of_match[] = { + { .compatible = "maxim,max44009" }, + { } +}; +MODULE_DEVICE_TABLE(of, max44009_of_match); + +MODULE_AUTHOR("Robert Eshleman <bobbyeshleman@gmail.com>"); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("MAX44009 ambient light sensor driver"); diff --git a/drivers/iio/magnetometer/mag3110.c b/drivers/iio/magnetometer/mag3110.c index f063355480ba..dd990cdb04a8 100644 --- a/drivers/iio/magnetometer/mag3110.c +++ b/drivers/iio/magnetometer/mag3110.c @@ -20,6 +20,7 @@ #include <linux/iio/buffer.h> #include <linux/iio/triggered_buffer.h> #include <linux/delay.h> +#include <linux/regulator/consumer.h> #define MAG3110_STATUS 0x00 #define MAG3110_OUT_X 0x01 /* MSB first */ @@ -56,6 +57,8 @@ struct mag3110_data { struct mutex lock; u8 ctrl_reg1; int sleep_val; + struct regulator *vdd_reg; + struct regulator *vddio_reg; }; static int mag3110_request(struct mag3110_data *data) @@ -469,17 +472,50 @@ static int mag3110_probe(struct i2c_client *client, struct iio_dev *indio_dev; int ret; - ret = i2c_smbus_read_byte_data(client, MAG3110_WHO_AM_I); - if (ret < 0) - return ret; - if (ret != MAG3110_DEVICE_ID) - return -ENODEV; - indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); if (!indio_dev) return -ENOMEM; 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); + } + + 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); + } + + ret = regulator_enable(data->vdd_reg); + if (ret) { + dev_err(&client->dev, "failed to enable VDD regulator!\n"); + return ret; + } + + ret = regulator_enable(data->vddio_reg); + if (ret) { + dev_err(&client->dev, "failed to enable VDDIO regulator!\n"); + goto disable_regulator_vdd; + } + + ret = i2c_smbus_read_byte_data(client, MAG3110_WHO_AM_I); + if (ret < 0) + goto disable_regulators; + if (ret != MAG3110_DEVICE_ID) { + ret = -ENODEV; + goto disable_regulators; + } + data->client = client; mutex_init(&data->lock); @@ -499,7 +535,7 @@ static int mag3110_probe(struct i2c_client *client, ret = mag3110_change_config(data, MAG3110_CTRL_REG1, data->ctrl_reg1); if (ret < 0) - return ret; + goto disable_regulators; ret = i2c_smbus_write_byte_data(client, MAG3110_CTRL_REG2, MAG3110_CTRL_AUTO_MRST_EN); @@ -520,16 +556,24 @@ buffer_cleanup: iio_triggered_buffer_cleanup(indio_dev); standby_on_error: mag3110_standby(iio_priv(indio_dev)); +disable_regulators: + regulator_disable(data->vddio_reg); +disable_regulator_vdd: + regulator_disable(data->vdd_reg); + return ret; } static int mag3110_remove(struct i2c_client *client) { struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct mag3110_data *data = iio_priv(indio_dev); iio_device_unregister(indio_dev); iio_triggered_buffer_cleanup(indio_dev); mag3110_standby(iio_priv(indio_dev)); + regulator_disable(data->vddio_reg); + regulator_disable(data->vdd_reg); return 0; } @@ -537,14 +581,48 @@ static int mag3110_remove(struct i2c_client *client) #ifdef CONFIG_PM_SLEEP static int mag3110_suspend(struct device *dev) { - return mag3110_standby(iio_priv(i2c_get_clientdata( + struct mag3110_data *data = iio_priv(i2c_get_clientdata( + to_i2c_client(dev))); + int ret; + + ret = mag3110_standby(iio_priv(i2c_get_clientdata( to_i2c_client(dev)))); + if (ret) + return ret; + + ret = regulator_disable(data->vddio_reg); + if (ret) { + dev_err(dev, "failed to disable VDDIO regulator\n"); + return ret; + } + + ret = regulator_disable(data->vdd_reg); + if (ret) { + dev_err(dev, "failed to disable VDD regulator\n"); + return ret; + } + + return 0; } static int mag3110_resume(struct device *dev) { struct mag3110_data *data = iio_priv(i2c_get_clientdata( to_i2c_client(dev))); + int ret; + + ret = regulator_enable(data->vdd_reg); + if (ret) { + dev_err(dev, "failed to enable VDD regulator\n"); + return ret; + } + + ret = regulator_enable(data->vddio_reg); + if (ret) { + dev_err(dev, "failed to enable VDDIO regulator\n"); + regulator_disable(data->vdd_reg); + return ret; + } return i2c_smbus_write_byte_data(data->client, MAG3110_CTRL_REG1, data->ctrl_reg1); diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig index eaa7cfcb4c2a..efeb89f3df71 100644 --- a/drivers/iio/pressure/Kconfig +++ b/drivers/iio/pressure/Kconfig @@ -165,7 +165,7 @@ config IIO_ST_PRESS select IIO_TRIGGERED_BUFFER if (IIO_BUFFER) help Say yes here to build support for STMicroelectronics pressure - sensors: LPS001WP, LPS25H, LPS331AP, LPS22HB. + sensors: LPS001WP, LPS25H, LPS331AP, LPS22HB, LPS22HH. This driver can also be built as a module. If so, these modules will be created: diff --git a/drivers/iio/pressure/st_pressure.h b/drivers/iio/pressure/st_pressure.h index e67eb0d971bf..57946605f3ba 100644 --- a/drivers/iio/pressure/st_pressure.h +++ b/drivers/iio/pressure/st_pressure.h @@ -21,6 +21,7 @@ enum st_press_type { LPS22HB, LPS33HW, LPS35HW, + LPS22HH, ST_PRESS_MAX, }; @@ -30,6 +31,7 @@ enum st_press_type { #define LPS22HB_PRESS_DEV_NAME "lps22hb" #define LPS33HW_PRESS_DEV_NAME "lps33hw" #define LPS35HW_PRESS_DEV_NAME "lps35hw" +#define LPS22HH_PRESS_DEV_NAME "lps22hh" /** * struct st_sensors_platform_data - default press platform data diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c index 4ddb6cf7d401..38dcdb7c000e 100644 --- a/drivers/iio/pressure/st_pressure_core.c +++ b/drivers/iio/pressure/st_pressure_core.c @@ -492,6 +492,75 @@ static const struct st_sensor_settings st_press_sensors_settings[] = { .multi_read_bit = false, .bootime = 2, }, + { + /* + * CUSTOM VALUES FOR LPS22HH SENSOR + * See LPS22HH datasheet: + * http://www2.st.com/resource/en/datasheet/lps22hh.pdf + */ + .wai = 0xb3, + .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS, + .sensors_supported = { + [0] = LPS22HH_PRESS_DEV_NAME, + }, + .ch = (struct iio_chan_spec *)st_press_lps22hb_channels, + .num_ch = ARRAY_SIZE(st_press_lps22hb_channels), + .odr = { + .addr = 0x10, + .mask = 0x70, + .odr_avl = { + { .hz = 1, .value = 0x01 }, + { .hz = 10, .value = 0x02 }, + { .hz = 25, .value = 0x03 }, + { .hz = 50, .value = 0x04 }, + { .hz = 75, .value = 0x05 }, + { .hz = 100, .value = 0x06 }, + { .hz = 200, .value = 0x07 }, + }, + }, + .pw = { + .addr = 0x10, + .mask = 0x70, + .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE, + }, + .fs = { + .fs_avl = { + /* + * Pressure and temperature sensitivity values + * as defined in table 3 of LPS22HH datasheet. + */ + [0] = { + .num = ST_PRESS_FS_AVL_1260MB, + .gain = ST_PRESS_KPASCAL_NANO_SCALE, + .gain2 = ST_PRESS_LPS22HB_LSB_PER_CELSIUS, + }, + }, + }, + .bdu = { + .addr = 0x10, + .mask = BIT(1), + }, + .drdy_irq = { + .int1 = { + .addr = 0x12, + .mask = BIT(2), + .addr_od = 0x11, + .mask_od = BIT(5), + }, + .addr_ihl = 0x11, + .mask_ihl = BIT(6), + .stat_drdy = { + .addr = ST_SENSORS_DEFAULT_STAT_ADDR, + .mask = 0x03, + }, + }, + .sim = { + .addr = 0x10, + .value = BIT(0), + }, + .multi_read_bit = false, + .bootime = 2, + }, }; static int st_press_write_raw(struct iio_dev *indio_dev, diff --git a/drivers/iio/pressure/st_pressure_i2c.c b/drivers/iio/pressure/st_pressure_i2c.c index 2026a1012012..a60849dd4ea7 100644 --- a/drivers/iio/pressure/st_pressure_i2c.c +++ b/drivers/iio/pressure/st_pressure_i2c.c @@ -45,6 +45,10 @@ static const struct of_device_id st_press_of_match[] = { .compatible = "st,lps35hw", .data = LPS35HW_PRESS_DEV_NAME, }, + { + .compatible = "st,lps22hh", + .data = LPS22HH_PRESS_DEV_NAME, + }, {}, }; MODULE_DEVICE_TABLE(of, st_press_of_match); @@ -69,6 +73,7 @@ static const struct i2c_device_id st_press_id_table[] = { { LPS22HB_PRESS_DEV_NAME, LPS22HB }, { LPS33HW_PRESS_DEV_NAME, LPS33HW }, { LPS35HW_PRESS_DEV_NAME, LPS35HW }, + { LPS22HH_PRESS_DEV_NAME, LPS22HH }, {}, }; MODULE_DEVICE_TABLE(i2c, st_press_id_table); diff --git a/drivers/iio/pressure/st_pressure_spi.c b/drivers/iio/pressure/st_pressure_spi.c index 9a3441b128e7..79a12ed46e54 100644 --- a/drivers/iio/pressure/st_pressure_spi.c +++ b/drivers/iio/pressure/st_pressure_spi.c @@ -49,6 +49,10 @@ static const struct of_device_id st_press_of_match[] = { .compatible = "st,lps35hw", .data = LPS35HW_PRESS_DEV_NAME, }, + { + .compatible = "st,lps22hh", + .data = LPS22HH_PRESS_DEV_NAME, + }, {}, }; MODULE_DEVICE_TABLE(of, st_press_of_match); @@ -93,6 +97,7 @@ static const struct spi_device_id st_press_id_table[] = { { LPS22HB_PRESS_DEV_NAME }, { LPS33HW_PRESS_DEV_NAME }, { LPS35HW_PRESS_DEV_NAME }, + { LPS22HH_PRESS_DEV_NAME }, {}, }; MODULE_DEVICE_TABLE(spi, st_press_id_table); diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index e4f608815c05..c0901b96cfe4 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -56,8 +56,6 @@ source "drivers/staging/iio/Kconfig" source "drivers/staging/sm750fb/Kconfig" -source "drivers/staging/xgifb/Kconfig" - source "drivers/staging/emxx_udc/Kconfig" source "drivers/staging/speakup/Kconfig" @@ -104,12 +102,16 @@ source "drivers/staging/pi433/Kconfig" source "drivers/staging/mt7621-pci/Kconfig" +source "drivers/staging/mt7621-pci-phy/Kconfig" + source "drivers/staging/mt7621-pinctrl/Kconfig" source "drivers/staging/mt7621-spi/Kconfig" source "drivers/staging/mt7621-dma/Kconfig" +source "drivers/staging/ralink-gdma/Kconfig" + source "drivers/staging/mt7621-mmc/Kconfig" source "drivers/staging/mt7621-eth/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 5868631e8f1b..57c6bce13ff4 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -20,7 +20,6 @@ obj-$(CONFIG_VT6656) += vt6656/ obj-$(CONFIG_VME_BUS) += vme/ obj-$(CONFIG_IIO) += iio/ obj-$(CONFIG_FB_SM750) += sm750fb/ -obj-$(CONFIG_FB_XGI) += xgifb/ obj-$(CONFIG_USB_EMXX) += emxx_udc/ obj-$(CONFIG_SPEAKUP) += speakup/ obj-$(CONFIG_MFD_NVEC) += nvec/ @@ -41,12 +40,14 @@ obj-$(CONFIG_GREYBUS) += greybus/ obj-$(CONFIG_BCM2835_VCHIQ) += vc04_services/ obj-$(CONFIG_DRM_VBOXVIDEO) += vboxvideo/ obj-$(CONFIG_PI433) += pi433/ -obj-$(CONFIG_SOC_MT7621) += mt7621-pci/ -obj-$(CONFIG_SOC_MT7621) += mt7621-pinctrl/ -obj-$(CONFIG_SOC_MT7621) += mt7621-spi/ +obj-$(CONFIG_PCI_MT7621) += mt7621-pci/ +obj-$(CONFIG_PCI_MT7621_PHY) += mt7621-pci-phy/ +obj-$(CONFIG_PINCTRL_RT2880) += mt7621-pinctrl/ +obj-$(CONFIG_SPI_MT7621) += mt7621-spi/ obj-$(CONFIG_SOC_MT7621) += mt7621-dma/ -obj-$(CONFIG_SOC_MT7621) += mt7621-mmc/ -obj-$(CONFIG_SOC_MT7621) += mt7621-eth/ +obj-$(CONFIG_DMA_RALINK) += ralink-gdma/ +obj-$(CONFIG_MTK_MMC) += mt7621-mmc/ +obj-$(CONFIG_NET_MEDIATEK_SOC_STAGING) += mt7621-eth/ obj-$(CONFIG_SOC_MT7621) += mt7621-dts/ obj-$(CONFIG_STAGING_GASKET_FRAMEWORK) += gasket/ obj-$(CONFIG_XIL_AXIS_FIFO) += axis-fifo/ diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index 90a8a9f1ac7d..74d497d39c5a 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c @@ -75,6 +75,9 @@ struct ashmem_range { /* LRU list of unpinned pages, protected by ashmem_mutex */ static LIST_HEAD(ashmem_lru_list); +static atomic_t ashmem_shrink_inflight = ATOMIC_INIT(0); +static DECLARE_WAIT_QUEUE_HEAD(ashmem_shrink_wait); + /* * long lru_count - The count of pages on our LRU list. * @@ -126,7 +129,8 @@ static inline bool page_range_in_range(struct ashmem_range *range, page_range_subsumes_range(range, start, end); } -static inline bool range_before_page(struct ashmem_range *range, size_t page) +static inline bool range_before_page(struct ashmem_range *range, + size_t page) { return range->pgend < page; } @@ -168,19 +172,15 @@ static inline void lru_del(struct ashmem_range *range) * @end: The ending page (inclusive) * * This function is protected by ashmem_mutex. - * - * Return: 0 if successful, or -ENOMEM if there is an error */ -static int range_alloc(struct ashmem_area *asma, - struct ashmem_range *prev_range, unsigned int purged, - size_t start, size_t end) +static void range_alloc(struct ashmem_area *asma, + struct ashmem_range *prev_range, unsigned int purged, + size_t start, size_t end, + struct ashmem_range **new_range) { - struct ashmem_range *range; - - range = kmem_cache_zalloc(ashmem_range_cachep, GFP_KERNEL); - if (!range) - return -ENOMEM; + struct ashmem_range *range = *new_range; + *new_range = NULL; range->asma = asma; range->pgstart = start; range->pgend = end; @@ -190,8 +190,6 @@ static int range_alloc(struct ashmem_area *asma, if (range_on_lru(range)) lru_add(range); - - return 0; } /** @@ -438,7 +436,6 @@ out: static unsigned long ashmem_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) { - struct ashmem_range *range, *next; unsigned long freed = 0; /* We might recurse into filesystem code, so bail out if necessary */ @@ -448,21 +445,33 @@ ashmem_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) if (!mutex_trylock(&ashmem_mutex)) return -1; - list_for_each_entry_safe(range, next, &ashmem_lru_list, lru) { + while (!list_empty(&ashmem_lru_list)) { + struct ashmem_range *range = + list_first_entry(&ashmem_lru_list, typeof(*range), lru); loff_t start = range->pgstart * PAGE_SIZE; loff_t end = (range->pgend + 1) * PAGE_SIZE; + struct file *f = range->asma->file; - range->asma->file->f_op->fallocate(range->asma->file, - FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, - start, end - start); + get_file(f); + atomic_inc(&ashmem_shrink_inflight); range->purged = ASHMEM_WAS_PURGED; lru_del(range); freed += range_size(range); + mutex_unlock(&ashmem_mutex); + f->f_op->fallocate(f, + FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, + start, end - start); + fput(f); + if (atomic_dec_and_test(&ashmem_shrink_inflight)) + wake_up_all(&ashmem_shrink_wait); + if (!mutex_trylock(&ashmem_mutex)) + goto out; if (--sc->nr_to_scan <= 0) break; } mutex_unlock(&ashmem_mutex); +out: return freed; } @@ -582,7 +591,8 @@ static int get_name(struct ashmem_area *asma, void __user *name) * * Caller must hold ashmem_mutex. */ -static int ashmem_pin(struct ashmem_area *asma, size_t pgstart, size_t pgend) +static int ashmem_pin(struct ashmem_area *asma, size_t pgstart, size_t pgend, + struct ashmem_range **new_range) { struct ashmem_range *range, *next; int ret = ASHMEM_NOT_PURGED; @@ -635,7 +645,7 @@ static int ashmem_pin(struct ashmem_area *asma, size_t pgstart, size_t pgend) * second half and adjust the first chunk's endpoint. */ range_alloc(asma, range, range->purged, - pgend + 1, range->pgend); + pgend + 1, range->pgend, new_range); range_shrink(range, range->pgstart, pgstart - 1); break; } @@ -649,7 +659,8 @@ static int ashmem_pin(struct ashmem_area *asma, size_t pgstart, size_t pgend) * * Caller must hold ashmem_mutex. */ -static int ashmem_unpin(struct ashmem_area *asma, size_t pgstart, size_t pgend) +static int ashmem_unpin(struct ashmem_area *asma, size_t pgstart, size_t pgend, + struct ashmem_range **new_range) { struct ashmem_range *range, *next; unsigned int purged = ASHMEM_NOT_PURGED; @@ -675,7 +686,8 @@ restart: } } - return range_alloc(asma, range, purged, pgstart, pgend); + range_alloc(asma, range, purged, pgstart, pgend, new_range); + return 0; } /* @@ -708,11 +720,19 @@ static int ashmem_pin_unpin(struct ashmem_area *asma, unsigned long cmd, struct ashmem_pin pin; size_t pgstart, pgend; int ret = -EINVAL; + struct ashmem_range *range = NULL; if (copy_from_user(&pin, p, sizeof(pin))) return -EFAULT; + if (cmd == ASHMEM_PIN || cmd == ASHMEM_UNPIN) { + range = kmem_cache_zalloc(ashmem_range_cachep, GFP_KERNEL); + if (!range) + return -ENOMEM; + } + mutex_lock(&ashmem_mutex); + wait_event(ashmem_shrink_wait, !atomic_read(&ashmem_shrink_inflight)); if (!asma->file) goto out_unlock; @@ -735,10 +755,10 @@ static int ashmem_pin_unpin(struct ashmem_area *asma, unsigned long cmd, switch (cmd) { case ASHMEM_PIN: - ret = ashmem_pin(asma, pgstart, pgend); + ret = ashmem_pin(asma, pgstart, pgend, &range); break; case ASHMEM_UNPIN: - ret = ashmem_unpin(asma, pgstart, pgend); + ret = ashmem_unpin(asma, pgstart, pgend, &range); break; case ASHMEM_GET_PIN_STATUS: ret = ashmem_get_pin_status(asma, pgstart, pgend); @@ -747,6 +767,8 @@ static int ashmem_pin_unpin(struct ashmem_area *asma, unsigned long cmd, out_unlock: mutex_unlock(&ashmem_mutex); + if (range) + kmem_cache_free(ashmem_range_cachep, range); return ret; } diff --git a/drivers/staging/android/ion/Makefile b/drivers/staging/android/ion/Makefile index bb30bf8774a0..17f3a7569e3d 100644 --- a/drivers/staging/android/ion/Makefile +++ b/drivers/staging/android/ion/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_ION) += ion.o ion-ioctl.o ion_heap.o +obj-$(CONFIG_ION) += ion.o ion_heap.o obj-$(CONFIG_ION_SYSTEM_HEAP) += ion_system_heap.o ion_page_pool.o obj-$(CONFIG_ION_CARVEOUT_HEAP) += ion_carveout_heap.o obj-$(CONFIG_ION_CHUNK_HEAP) += ion_chunk_heap.o diff --git a/drivers/staging/android/ion/ion-ioctl.c b/drivers/staging/android/ion/ion-ioctl.c deleted file mode 100644 index a8d3cc412fb9..000000000000 --- a/drivers/staging/android/ion/ion-ioctl.c +++ /dev/null @@ -1,98 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (C) 2011 Google, Inc. - */ - -#include <linux/kernel.h> -#include <linux/file.h> -#include <linux/fs.h> -#include <linux/uaccess.h> - -#include "ion.h" - -union ion_ioctl_arg { - struct ion_allocation_data allocation; - struct ion_heap_query query; -}; - -static int validate_ioctl_arg(unsigned int cmd, union ion_ioctl_arg *arg) -{ - switch (cmd) { - case ION_IOC_HEAP_QUERY: - if (arg->query.reserved0 || - arg->query.reserved1 || - arg->query.reserved2) - return -EINVAL; - break; - default: - break; - } - - return 0; -} - -/* fix up the cases where the ioctl direction bits are incorrect */ -static unsigned int ion_ioctl_dir(unsigned int cmd) -{ - switch (cmd) { - default: - return _IOC_DIR(cmd); - } -} - -long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - int ret = 0; - unsigned int dir; - union ion_ioctl_arg data; - - dir = ion_ioctl_dir(cmd); - - if (_IOC_SIZE(cmd) > sizeof(data)) - return -EINVAL; - - /* - * The copy_from_user is unconditional here for both read and write - * to do the validate. If there is no write for the ioctl, the - * buffer is cleared - */ - if (copy_from_user(&data, (void __user *)arg, _IOC_SIZE(cmd))) - return -EFAULT; - - ret = validate_ioctl_arg(cmd, &data); - if (ret) { - pr_warn_once("%s: ioctl validate failed\n", __func__); - return ret; - } - - if (!(dir & _IOC_WRITE)) - memset(&data, 0, sizeof(data)); - - switch (cmd) { - case ION_IOC_ALLOC: - { - int fd; - - fd = ion_alloc(data.allocation.len, - data.allocation.heap_id_mask, - data.allocation.flags); - if (fd < 0) - return fd; - - data.allocation.fd = fd; - - break; - } - case ION_IOC_HEAP_QUERY: - ret = ion_query_heaps(&data.query); - break; - default: - return -ENOTTY; - } - - if (dir & _IOC_READ) { - if (copy_to_user((void __user *)arg, &data, _IOC_SIZE(cmd))) - return -EFAULT; - } - return ret; -} diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 6f5afab7c1a1..92c2914239e3 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -1,11 +1,10 @@ // SPDX-License-Identifier: GPL-2.0 /* - * drivers/staging/android/ion/ion.c + * ION Memory Allocator * * Copyright (C) 2011 Google, Inc. */ -#include <linux/anon_inodes.h> #include <linux/debugfs.h> #include <linux/device.h> #include <linux/dma-buf.h> @@ -14,10 +13,8 @@ #include <linux/file.h> #include <linux/freezer.h> #include <linux/fs.h> -#include <linux/idr.h> #include <linux/kthread.h> #include <linux/list.h> -#include <linux/memblock.h> #include <linux/miscdevice.h> #include <linux/mm.h> #include <linux/mm_types.h> @@ -390,7 +387,7 @@ static const struct dma_buf_ops dma_buf_ops = { .unmap = ion_dma_buf_kunmap, }; -int ion_alloc(size_t len, unsigned int heap_id_mask, unsigned int flags) +static int ion_alloc(size_t len, unsigned int heap_id_mask, unsigned int flags) { struct ion_device *dev = internal_dev; struct ion_buffer *buffer = NULL; @@ -447,7 +444,7 @@ int ion_alloc(size_t len, unsigned int heap_id_mask, unsigned int flags) return fd; } -int ion_query_heaps(struct ion_heap_query *query) +static int ion_query_heaps(struct ion_heap_query *query) { struct ion_device *dev = internal_dev; struct ion_heap_data __user *buffer = u64_to_user_ptr(query->heaps); @@ -492,6 +489,81 @@ out: return ret; } +union ion_ioctl_arg { + struct ion_allocation_data allocation; + struct ion_heap_query query; +}; + +static int validate_ioctl_arg(unsigned int cmd, union ion_ioctl_arg *arg) +{ + switch (cmd) { + case ION_IOC_HEAP_QUERY: + if (arg->query.reserved0 || + arg->query.reserved1 || + arg->query.reserved2) + return -EINVAL; + break; + default: + break; + } + + return 0; +} + +static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + int ret = 0; + union ion_ioctl_arg data; + + if (_IOC_SIZE(cmd) > sizeof(data)) + return -EINVAL; + + /* + * The copy_from_user is unconditional here for both read and write + * to do the validate. If there is no write for the ioctl, the + * buffer is cleared + */ + if (copy_from_user(&data, (void __user *)arg, _IOC_SIZE(cmd))) + return -EFAULT; + + ret = validate_ioctl_arg(cmd, &data); + if (ret) { + pr_warn_once("%s: ioctl validate failed\n", __func__); + return ret; + } + + if (!(_IOC_DIR(cmd) & _IOC_WRITE)) + memset(&data, 0, sizeof(data)); + + switch (cmd) { + case ION_IOC_ALLOC: + { + int fd; + + fd = ion_alloc(data.allocation.len, + data.allocation.heap_id_mask, + data.allocation.flags); + if (fd < 0) + return fd; + + data.allocation.fd = fd; + + break; + } + case ION_IOC_HEAP_QUERY: + ret = ion_query_heaps(&data.query); + break; + default: + return -ENOTTY; + } + + if (_IOC_DIR(cmd) & _IOC_READ) { + if (copy_to_user((void __user *)arg, &data, _IOC_SIZE(cmd))) + return -EFAULT; + } + return ret; +} + static const struct file_operations ion_fops = { .owner = THIS_MODULE, .unlocked_ioctl = ion_ioctl, diff --git a/drivers/staging/android/ion/ion.h b/drivers/staging/android/ion/ion.h index 47b594cf1ac9..e291299fd35f 100644 --- a/drivers/staging/android/ion/ion.h +++ b/drivers/staging/android/ion/ion.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * drivers/staging/android/ion/ion.h + * ION Memory Allocator kernel interface header * * Copyright (C) 2011 Google, Inc. */ @@ -22,32 +22,9 @@ #include "../uapi/ion.h" /** - * struct ion_platform_heap - defines a heap in the given platform - * @type: type of the heap from ion_heap_type enum - * @id: unique identifier for heap. When allocating higher numb ers - * will be allocated from first. At allocation these are passed - * as a bit mask and therefore can not exceed ION_NUM_HEAP_IDS. - * @name: used for debug purposes - * @base: base address of heap in physical memory if applicable - * @size: size of the heap in bytes if applicable - * @priv: private info passed from the board file - * - * Provided by the board file. - */ -struct ion_platform_heap { - enum ion_heap_type type; - unsigned int id; - const char *name; - phys_addr_t base; - size_t size; - phys_addr_t align; - void *priv; -}; - -/** * struct ion_buffer - metadata for a particular buffer - * @ref: reference count * @node: node in the ion_device buffers tree + * @list: element in list of deferred freeable buffers * @dev: back pointer to the ion_device * @heap: back pointer to the heap the buffer came from * @flags: buffer specific flags @@ -58,7 +35,8 @@ struct ion_platform_heap { * @lock: protects the buffers cnt fields * @kmap_cnt: number of times the buffer is mapped to the kernel * @vaddr: the kernel mapping if kmap_cnt is not zero - * @sg_table: the sg table for the buffer if dmap_cnt is not zero + * @sg_table: the sg table for the buffer + * @attachments: list of devices attached to this buffer */ struct ion_buffer { union { @@ -174,12 +152,16 @@ struct ion_heap { unsigned long flags; unsigned int id; const char *name; + + /* deferred free support */ struct shrinker shrinker; struct list_head free_list; size_t free_list_size; spinlock_t free_lock; wait_queue_head_t waitqueue; struct task_struct *task; + + /* heap statistics */ u64 num_of_buffers; u64 num_of_alloc_bytes; u64 alloc_bytes_wm; @@ -205,10 +187,6 @@ int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, int ion_heap_buffer_zero(struct ion_buffer *buffer); int ion_heap_pages_zero(struct page *page, size_t size, pgprot_t pgprot); -int ion_alloc(size_t len, - unsigned int heap_id_mask, - unsigned int flags); - /** * ion_heap_init_shrinker * @heap: the heap @@ -330,8 +308,4 @@ void ion_page_pool_free(struct ion_page_pool *pool, struct page *page); int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask, int nr_to_scan); -long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); - -int ion_query_heaps(struct ion_heap_query *query); - #endif /* _ION_H */ diff --git a/drivers/staging/android/ion/ion_carveout_heap.c b/drivers/staging/android/ion/ion_carveout_heap.c index e129237a0417..bb9d614767a2 100644 --- a/drivers/staging/android/ion/ion_carveout_heap.c +++ b/drivers/staging/android/ion/ion_carveout_heap.c @@ -1,10 +1,10 @@ // SPDX-License-Identifier: GPL-2.0 /* - * drivers/staging/android/ion/ion_carveout_heap.c + * ION Memory Allocator carveout heap helper * * Copyright (C) 2011 Google, Inc. */ -#include <linux/spinlock.h> + #include <linux/dma-mapping.h> #include <linux/err.h> #include <linux/genalloc.h> @@ -12,7 +12,7 @@ #include <linux/mm.h> #include <linux/scatterlist.h> #include <linux/slab.h> -#include <linux/vmalloc.h> + #include "ion.h" #define ION_CARVEOUT_ALLOCATE_FAIL -1 @@ -20,7 +20,6 @@ struct ion_carveout_heap { struct ion_heap heap; struct gen_pool *pool; - phys_addr_t base; }; static phys_addr_t ion_carveout_allocate(struct ion_heap *heap, @@ -44,6 +43,7 @@ static void ion_carveout_free(struct ion_heap *heap, phys_addr_t addr, if (addr == ION_CARVEOUT_ALLOCATE_FAIL) return; + gen_pool_free(carveout_heap->pool, addr, size); } @@ -103,17 +103,14 @@ static struct ion_heap_ops carveout_heap_ops = { .unmap_kernel = ion_heap_unmap_kernel, }; -struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *heap_data) +struct ion_heap *ion_carveout_heap_create(phys_addr_t base, size_t size) { struct ion_carveout_heap *carveout_heap; int ret; struct page *page; - size_t size; - - page = pfn_to_page(PFN_DOWN(heap_data->base)); - size = heap_data->size; + page = pfn_to_page(PFN_DOWN(base)); ret = ion_heap_pages_zero(page, size, pgprot_writecombine(PAGE_KERNEL)); if (ret) return ERR_PTR(ret); @@ -127,9 +124,7 @@ struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *heap_data) kfree(carveout_heap); return ERR_PTR(-ENOMEM); } - carveout_heap->base = heap_data->base; - gen_pool_add(carveout_heap->pool, carveout_heap->base, heap_data->size, - -1); + gen_pool_add(carveout_heap->pool, base, size, -1); carveout_heap->heap.ops = &carveout_heap_ops; carveout_heap->heap.type = ION_HEAP_TYPE_CARVEOUT; carveout_heap->heap.flags = ION_HEAP_FLAG_DEFER_FREE; diff --git a/drivers/staging/android/ion/ion_chunk_heap.c b/drivers/staging/android/ion/ion_chunk_heap.c index 159d72f5bc42..3cdde9c1a717 100644 --- a/drivers/staging/android/ion/ion_chunk_heap.c +++ b/drivers/staging/android/ion/ion_chunk_heap.c @@ -1,23 +1,22 @@ // SPDX-License-Identifier: GPL-2.0 /* - * drivers/staging/android/ion/ion_chunk_heap.c + * ION memory allocator chunk heap helper * * Copyright (C) 2012 Google, Inc. */ + #include <linux/dma-mapping.h> #include <linux/err.h> #include <linux/genalloc.h> -#include <linux/io.h> #include <linux/mm.h> #include <linux/scatterlist.h> #include <linux/slab.h> -#include <linux/vmalloc.h> + #include "ion.h" struct ion_chunk_heap { struct ion_heap heap; struct gen_pool *pool; - phys_addr_t base; unsigned long chunk_size; unsigned long size; unsigned long allocated; @@ -108,16 +107,13 @@ static struct ion_heap_ops chunk_heap_ops = { .unmap_kernel = ion_heap_unmap_kernel, }; -struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data) +struct ion_heap *ion_chunk_heap_create(phys_addr_t base, size_t size, size_t chunk_size) { struct ion_chunk_heap *chunk_heap; int ret; struct page *page; - size_t size; - - page = pfn_to_page(PFN_DOWN(heap_data->base)); - size = heap_data->size; + page = pfn_to_page(PFN_DOWN(base)); ret = ion_heap_pages_zero(page, size, pgprot_writecombine(PAGE_KERNEL)); if (ret) return ERR_PTR(ret); @@ -126,23 +122,21 @@ struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data) if (!chunk_heap) return ERR_PTR(-ENOMEM); - chunk_heap->chunk_size = (unsigned long)heap_data->priv; + chunk_heap->chunk_size = chunk_size; chunk_heap->pool = gen_pool_create(get_order(chunk_heap->chunk_size) + PAGE_SHIFT, -1); if (!chunk_heap->pool) { ret = -ENOMEM; goto error_gen_pool_create; } - chunk_heap->base = heap_data->base; - chunk_heap->size = heap_data->size; + chunk_heap->size = size; chunk_heap->allocated = 0; - gen_pool_add(chunk_heap->pool, chunk_heap->base, heap_data->size, -1); + gen_pool_add(chunk_heap->pool, base, size, -1); chunk_heap->heap.ops = &chunk_heap_ops; chunk_heap->heap.type = ION_HEAP_TYPE_CHUNK; chunk_heap->heap.flags = ION_HEAP_FLAG_DEFER_FREE; - pr_debug("%s: base %pa size %zu\n", __func__, - &chunk_heap->base, heap_data->size); + pr_debug("%s: base %pa size %zu\n", __func__, &base, size); return &chunk_heap->heap; @@ -150,4 +144,3 @@ error_gen_pool_create: kfree(chunk_heap); return ERR_PTR(ret); } - diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c index 3fafd013d80a..bf65e67ef9d8 100644 --- a/drivers/staging/android/ion/ion_cma_heap.c +++ b/drivers/staging/android/ion/ion_cma_heap.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * drivers/staging/android/ion/ion_cma_heap.c + * ION Memory Allocator CMA heap exporter * * Copyright (C) Linaro 2012 * Author: <benjamin.gaignard@linaro.org> for ST-Ericsson. @@ -111,10 +111,6 @@ static struct ion_heap *__ion_cma_heap_create(struct cma *cma) return ERR_PTR(-ENOMEM); cma_heap->heap.ops = &ion_cma_ops; - /* - * get device from private heaps data, later it will be - * used to make the link with reserved CMA memory - */ cma_heap->cma = cma; cma_heap->heap.type = ION_HEAP_TYPE_DMA; return &cma_heap->heap; diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c index 31db510018a9..473b465724f1 100644 --- a/drivers/staging/android/ion/ion_heap.c +++ b/drivers/staging/android/ion/ion_heap.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * drivers/staging/android/ion/ion_heap.c + * ION Memory Allocator generic heap helpers * * Copyright (C) 2011 Google, Inc. */ @@ -14,6 +14,7 @@ #include <uapi/linux/sched/types.h> #include <linux/scatterlist.h> #include <linux/vmalloc.h> + #include "ion.h" void *ion_heap_map_kernel(struct ion_heap *heap, @@ -92,6 +93,7 @@ int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, if (addr >= vma->vm_end) return 0; } + return 0; } @@ -254,6 +256,7 @@ int ion_heap_init_deferred_free(struct ion_heap *heap) return PTR_ERR_OR_ZERO(heap->task); } sched_setscheduler(heap->task, SCHED_IDLE, ¶m); + return 0; } @@ -265,8 +268,10 @@ static unsigned long ion_heap_shrink_count(struct shrinker *shrinker, int total = 0; total = ion_heap_freelist_size(heap) / PAGE_SIZE; + if (heap->ops->shrink) total += heap->ops->shrink(heap, sc->gfp_mask, 0); + return total; } @@ -295,6 +300,7 @@ static unsigned long ion_heap_shrink_scan(struct shrinker *shrinker, if (heap->ops->shrink) freed += heap->ops->shrink(heap, sc->gfp_mask, to_scan); + return freed; } diff --git a/drivers/staging/android/ion/ion_page_pool.c b/drivers/staging/android/ion/ion_page_pool.c index 0d2a95957ee8..fd4995fb676e 100644 --- a/drivers/staging/android/ion/ion_page_pool.c +++ b/drivers/staging/android/ion/ion_page_pool.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * drivers/staging/android/ion/ion_mem_pool.c + * ION Memory Allocator page pool helpers * * Copyright (C) 2011 Google, Inc. */ diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index 0383f7548d48..aa8d8425be25 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * drivers/staging/android/ion/ion_system_heap.c + * ION Memory Allocator system heap exporter * * Copyright (C) 2011 Google, Inc. */ @@ -13,6 +13,7 @@ #include <linux/scatterlist.h> #include <linux/slab.h> #include <linux/vmalloc.h> + #include "ion.h" #define NUM_ORDERS ARRAY_SIZE(orders) @@ -223,10 +224,10 @@ static void ion_system_heap_destroy_pools(struct ion_page_pool **pools) static int ion_system_heap_create_pools(struct ion_page_pool **pools) { int i; - gfp_t gfp_flags = low_order_gfp_flags; for (i = 0; i < NUM_ORDERS; i++) { struct ion_page_pool *pool; + gfp_t gfp_flags = low_order_gfp_flags; if (orders[i] > 4) gfp_flags = high_order_gfp_flags; @@ -236,6 +237,7 @@ static int ion_system_heap_create_pools(struct ion_page_pool **pools) goto err_create_pool; pools[i] = pool; } + return 0; err_create_pool: @@ -274,6 +276,7 @@ static int ion_system_heap_create(void) heap->name = "ion_system_heap"; ion_device_add_heap(heap); + return 0; } device_initcall(ion_system_heap_create); @@ -355,6 +358,7 @@ static struct ion_heap *__ion_system_contig_heap_create(void) heap->ops = &kmalloc_ops; heap->type = ION_HEAP_TYPE_SYSTEM_CONTIG; heap->name = "ion_system_contig_heap"; + return heap; } @@ -367,7 +371,7 @@ static int ion_system_contig_heap_create(void) return PTR_ERR(heap); ion_device_add_heap(heap); + return 0; } device_initcall(ion_system_contig_heap_create); - diff --git a/drivers/staging/android/uapi/ion.h b/drivers/staging/android/uapi/ion.h index 5d7009884c13..46c93fcb46d6 100644 --- a/drivers/staging/android/uapi/ion.h +++ b/drivers/staging/android/uapi/ion.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * drivers/staging/android/uapi/ion.h * diff --git a/drivers/staging/android/vsoc.c b/drivers/staging/android/vsoc.c index 22571abcaa4e..8a75bd27c413 100644 --- a/drivers/staging/android/vsoc.c +++ b/drivers/staging/android/vsoc.c @@ -29,7 +29,6 @@ #include <linux/syscalls.h> #include <linux/uaccess.h> #include <linux/interrupt.h> -#include <linux/mutex.h> #include <linux/cdev.h> #include <linux/file.h> #include "uapi/vsoc_shm.h" diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 5d2fcbfe02af..0caae4a5c471 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -1605,9 +1605,8 @@ static int do_insn_ioctl(struct comedi_device *dev, unsigned int n_data = MIN_SAMPLES; int ret = 0; - if (copy_from_user(&insn, arg, sizeof(insn))) { + if (copy_from_user(&insn, arg, sizeof(insn))) return -EFAULT; - } n_data = max(n_data, insn.n); diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index 4e72a0778086..a9d052bfda38 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -252,9 +252,9 @@ static int cb_pcimdas_di_insn_bits(struct comedi_device *dev, } static int cb_pcimdas_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct cb_pcimdas_private *devpriv = dev->private; diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index e70a461e723f..405573e927cf 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -656,6 +656,7 @@ static int ni_660x_set_pfi_routing(struct comedi_device *dev, case NI_660X_PFI_OUTPUT_DIO: if (chan > 31) return -EINVAL; + break; default: return -EINVAL; } diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index b9a0dc6eac44..4bdef87d5dd7 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -49,116 +49,117 @@ /* defines for the PCI-DIO-32HS */ -#define Window_Address 4 /* W */ -#define Interrupt_And_Window_Status 4 /* R */ -#define IntStatus1 BIT(0) -#define IntStatus2 BIT(1) -#define WindowAddressStatus_mask 0x7c - -#define Master_DMA_And_Interrupt_Control 5 /* W */ -#define InterruptLine(x) ((x) & 3) -#define OpenInt BIT(2) -#define Group_Status 5 /* R */ -#define DataLeft BIT(0) -#define Req BIT(2) -#define StopTrig BIT(3) - -#define Group_1_Flags 6 /* R */ -#define Group_2_Flags 7 /* R */ -#define TransferReady BIT(0) -#define CountExpired BIT(1) -#define Waited BIT(5) -#define PrimaryTC BIT(6) -#define SecondaryTC BIT(7) +#define WINDOW_ADDRESS 4 /* W */ +#define INTERRUPT_AND_WINDOW_STATUS 4 /* R */ +#define INT_STATUS_1 BIT(0) +#define INT_STATUS_2 BIT(1) +#define WINDOW_ADDRESS_STATUS_MASK 0x7c + +#define MASTER_DMA_AND_INTERRUPT_CONTROL 5 /* W */ +#define INTERRUPT_LINE(x) ((x) & 3) +#define OPEN_INT BIT(2) +#define GROUP_STATUS 5 /* R */ +#define DATA_LEFT BIT(0) +#define REQ BIT(2) +#define STOP_TRIG BIT(3) + +#define GROUP_1_FLAGS 6 /* R */ +#define GROUP_2_FLAGS 7 /* R */ +#define TRANSFER_READY BIT(0) +#define COUNT_EXPIRED BIT(1) +#define WAITED BIT(5) +#define PRIMARY_TC BIT(6) +#define SECONDARY_TC BIT(7) /* #define SerialRose */ /* #define ReqRose */ /* #define Paused */ -#define Group_1_First_Clear 6 /* W */ -#define Group_2_First_Clear 7 /* W */ -#define ClearWaited BIT(3) -#define ClearPrimaryTC BIT(4) -#define ClearSecondaryTC BIT(5) -#define DMAReset BIT(6) -#define FIFOReset BIT(7) -#define ClearAll 0xf8 - -#define Group_1_FIFO 8 /* W */ -#define Group_2_FIFO 12 /* W */ - -#define Transfer_Count 20 -#define Chip_ID_D 24 -#define Chip_ID_I 25 -#define Chip_ID_O 26 -#define Chip_Version 27 -#define Port_IO(x) (28 + (x)) -#define Port_Pin_Directions(x) (32 + (x)) -#define Port_Pin_Mask(x) (36 + (x)) -#define Port_Pin_Polarities(x) (40 + (x)) - -#define Master_Clock_Routing 45 -#define RTSIClocking(x) (((x) & 3) << 4) - -#define Group_1_Second_Clear 46 /* W */ -#define Group_2_Second_Clear 47 /* W */ -#define ClearExpired BIT(0) - -#define Port_Pattern(x) (48 + (x)) - -#define Data_Path 64 -#define FIFOEnableA BIT(0) -#define FIFOEnableB BIT(1) -#define FIFOEnableC BIT(2) -#define FIFOEnableD BIT(3) -#define Funneling(x) (((x) & 3) << 4) -#define GroupDirection BIT(7) - -#define Protocol_Register_1 65 -#define OpMode Protocol_Register_1 -#define RunMode(x) ((x) & 7) -#define Numbered BIT(3) - -#define Protocol_Register_2 66 -#define ClockReg Protocol_Register_2 -#define ClockLine(x) (((x) & 3) << 5) -#define InvertStopTrig BIT(7) -#define DataLatching(x) (((x) & 3) << 5) - -#define Protocol_Register_3 67 -#define Sequence Protocol_Register_3 - -#define Protocol_Register_14 68 /* 16 bit */ -#define ClockSpeed Protocol_Register_14 - -#define Protocol_Register_4 70 -#define ReqReg Protocol_Register_4 -#define ReqConditioning(x) (((x) & 7) << 3) - -#define Protocol_Register_5 71 -#define BlockMode Protocol_Register_5 +#define GROUP_1_FIRST_CLEAR 6 /* W */ +#define GROUP_2_FIRST_CLEAR 7 /* W */ +#define CLEAR_WAITED BIT(3) +#define CLEAR_PRIMARY_TC BIT(4) +#define CLEAR_SECONDARY_TC BIT(5) +#define DMA_RESET BIT(6) +#define FIFO_RESET BIT(7) +#define CLEAR_ALL 0xf8 + +#define GROUP_1_FIFO 8 /* W */ +#define GROUP_2_FIFO 12 /* W */ + +#define TRANSFER_COUNT 20 +#define CHIP_ID_D 24 +#define CHIP_ID_I 25 +#define CHIP_ID_O 26 +#define CHIP_VERSION 27 +#define PORT_IO(x) (28 + (x)) +#define PORT_PIN_DIRECTIONS(x) (32 + (x)) +#define PORT_PIN_MASK(x) (36 + (x)) +#define PORT_PIN_POLARITIES(x) (40 + (x)) + +#define MASTER_CLOCK_ROUTING 45 +#define RTSI_CLOCKING(x) (((x) & 3) << 4) + +#define GROUP_1_SECOND_CLEAR 46 /* W */ +#define GROUP_2_SECOND_CLEAR 47 /* W */ +#define CLEAR_EXPIRED BIT(0) + +#define PORT_PATTERN(x) (48 + (x)) + +#define DATA_PATH 64 +#define FIFO_ENABLE_A BIT(0) +#define FIFO_ENABLE_B BIT(1) +#define FIFO_ENABLE_C BIT(2) +#define FIFO_ENABLE_D BIT(3) +#define FUNNELING(x) (((x) & 3) << 4) +#define GROUP_DIRECTION BIT(7) + +#define PROTOCOL_REGISTER_1 65 +#define OP_MODE PROTOCOL_REGISTER_1 +#define RUN_MODE(x) ((x) & 7) +#define NUMBERED BIT(3) + +#define PROTOCOL_REGISTER_2 66 +#define CLOCK_REG PROTOCOL_REGISTER_2 +#define CLOCK_LINE(x) (((x) & 3) << 5) +#define INVERT_STOP_TRIG BIT(7) +#define DATA_LATCHING(x) (((x) & 3) << 5) + +#define PROTOCOL_REGISTER_3 67 +#define SEQUENCE PROTOCOL_REGISTER_3 + +#define PROTOCOL_REGISTER_14 68 /* 16 bit */ +#define CLOCK_SPEED PROTOCOL_REGISTER_14 + +#define PROTOCOL_REGISTER_4 70 +#define REQ_REG PROTOCOL_REGISTER_4 +#define REQ_CONDITIONING(x) (((x) & 7) << 3) + +#define PROTOCOL_REGISTER_5 71 +#define BLOCK_MODE PROTOCOL_REGISTER_5 #define FIFO_Control 72 -#define ReadyLevel(x) ((x) & 7) - -#define Protocol_Register_6 73 -#define LinePolarities Protocol_Register_6 -#define InvertAck BIT(0) -#define InvertReq BIT(1) -#define InvertClock BIT(2) -#define InvertSerial BIT(3) -#define OpenAck BIT(4) -#define OpenClock BIT(5) - -#define Protocol_Register_7 74 -#define AckSer Protocol_Register_7 -#define AckLine(x) (((x) & 3) << 2) -#define ExchangePins BIT(7) - -#define Interrupt_Control 75 - /* bits same as flags */ - -#define DMA_Line_Control_Group1 76 -#define DMA_Line_Control_Group2 108 +#define READY_LEVEL(x) ((x) & 7) + +#define PROTOCOL_REGISTER_6 73 +#define LINE_POLARITIES PROTOCOL_REGISTER_6 +#define INVERT_ACK BIT(0) +#define INVERT_REQ BIT(1) +#define INVERT_CLOCK BIT(2) +#define INVERT_SERIAL BIT(3) +#define OPEN_ACK BIT(4) +#define OPEN_CLOCK BIT(5) + +#define PROTOCOL_REGISTER_7 74 +#define ACK_SER PROTOCOL_REGISTER_7 +#define ACK_LINE(x) (((x) & 3) << 2) +#define EXCHANGE_PINS BIT(7) + +#define INTERRUPT_CONTROL 75 +/* bits same as flags */ + +#define DMA_LINE_CONTROL_GROUP1 76 +#define DMA_LINE_CONTROL_GROUP2 108 + /* channel zero is none */ static inline unsigned int primary_DMAChannel_bits(unsigned int channel) { @@ -170,41 +171,41 @@ static inline unsigned int secondary_DMAChannel_bits(unsigned int channel) return (channel << 2) & 0xc; } -#define Transfer_Size_Control 77 -#define TransferWidth(x) ((x) & 3) -#define TransferLength(x) (((x) & 3) << 3) -#define RequireRLevel BIT(5) +#define TRANSFER_SIZE_CONTROL 77 +#define TRANSFER_WIDTH(x) ((x) & 3) +#define TRANSFER_LENGTH(x) (((x) & 3) << 3) +#define REQUIRE_R_LEVEL BIT(5) -#define Protocol_Register_15 79 -#define DAQOptions Protocol_Register_15 -#define StartSource(x) ((x) & 0x3) -#define InvertStart BIT(2) -#define StopSource(x) (((x) & 0x3) << 3) -#define ReqStart BIT(6) -#define PreStart BIT(7) +#define PROTOCOL_REGISTER_15 79 +#define DAQ_OPTIONS PROTOCOL_REGISTER_15 +#define START_SOURCE(x) ((x) & 0x3) +#define INVERT_START BIT(2) +#define STOP_SOURCE(x) (((x) & 0x3) << 3) +#define REQ_START BIT(6) +#define PRE_START BIT(7) -#define Pattern_Detection 81 -#define DetectionMethod BIT(0) -#define InvertMatch BIT(1) -#define IE_Pattern_Detection BIT(2) +#define PATTERN_DETECTION 81 +#define DETECTION_METHOD BIT(0) +#define INVERT_MATCH BIT(1) +#define IE_PATTERN_DETECTION BIT(2) -#define Protocol_Register_9 82 -#define ReqDelay Protocol_Register_9 +#define PROTOCOL_REGISTER_9 82 +#define REQ_DELAY PROTOCOL_REGISTER_9 -#define Protocol_Register_10 83 -#define ReqNotDelay Protocol_Register_10 +#define PROTOCOL_REGISTER_10 83 +#define REQ_NOT_DELAY PROTOCOL_REGISTER_10 -#define Protocol_Register_11 84 -#define AckDelay Protocol_Register_11 +#define PROTOCOL_REGISTER_11 84 +#define ACK_DELAY PROTOCOL_REGISTER_11 -#define Protocol_Register_12 85 -#define AckNotDelay Protocol_Register_12 +#define PROTOCOL_REGISTER_12 85 +#define ACK_NOT_DELAY PROTOCOL_REGISTER_12 -#define Protocol_Register_13 86 -#define Data1Delay Protocol_Register_13 +#define PROTOCOL_REGISTER_13 86 +#define DATA_1_DELAY PROTOCOL_REGISTER_13 -#define Protocol_Register_8 88 /* 32 bit */ -#define StartDelay Protocol_Register_8 +#define PROTOCOL_REGISTER_8 88 /* 32 bit */ +#define START_DELAY PROTOCOL_REGISTER_8 /* Firmware files for PCI-6524 */ #define FW_PCI_6534_MAIN "ni6534a.bin" @@ -246,9 +247,10 @@ enum FPGA_Control_Bits { #define TIMER_BASE 50 /* nanoseconds */ #ifdef USE_DMA -#define IntEn (CountExpired | Waited | PrimaryTC | SecondaryTC) +#define INT_EN (COUNT_EXPIRED | WAITED | PRIMARY_TC | SECONDARY_TC) #else -#define IntEn (TransferReady | CountExpired | Waited | PrimaryTC | SecondaryTC) +#define INT_EN (TRANSFER_READY | COUNT_EXPIRED | WAITED \ + | PRIMARY_TC | SECONDARY_TC) #endif enum nidio_boardid { @@ -283,7 +285,7 @@ struct nidio96_private { struct mite *mite; int boardtype; int dio; - unsigned short OpModeBits; + unsigned short OP_MODEBits; struct mite_channel *di_mite_chan; struct mite_ring *di_mite_ring; spinlock_t mite_channel_lock; @@ -307,7 +309,7 @@ static int ni_pcidio_request_di_mite_channel(struct comedi_device *dev) devpriv->di_mite_chan->dir = COMEDI_INPUT; writeb(primary_DMAChannel_bits(devpriv->di_mite_chan->channel) | secondary_DMAChannel_bits(devpriv->di_mite_chan->channel), - dev->mmio + DMA_Line_Control_Group1); + dev->mmio + DMA_LINE_CONTROL_GROUP1); mmiowb(); spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); return 0; @@ -324,7 +326,7 @@ static void ni_pcidio_release_di_mite_channel(struct comedi_device *dev) devpriv->di_mite_chan = NULL; writeb(primary_DMAChannel_bits(0) | secondary_DMAChannel_bits(0), - dev->mmio + DMA_Line_Control_Group1); + dev->mmio + DMA_LINE_CONTROL_GROUP1); mmiowb(); } spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); @@ -391,8 +393,8 @@ static irqreturn_t nidio_interrupt(int irq, void *d) /* Lock to avoid race with comedi_poll */ spin_lock(&dev->spinlock); - status = readb(dev->mmio + Interrupt_And_Window_Status); - flags = readb(dev->mmio + Group_1_Flags); + status = readb(dev->mmio + INTERRUPT_AND_WINDOW_STATUS); + flags = readb(dev->mmio + GROUP_1_FLAGS); spin_lock(&devpriv->mite_channel_lock); if (devpriv->di_mite_chan) { @@ -401,63 +403,63 @@ static irqreturn_t nidio_interrupt(int irq, void *d) } spin_unlock(&devpriv->mite_channel_lock); - while (status & DataLeft) { + while (status & DATA_LEFT) { work++; if (work > 20) { dev_dbg(dev->class_dev, "too much work in interrupt\n"); writeb(0x00, - dev->mmio + Master_DMA_And_Interrupt_Control); + dev->mmio + MASTER_DMA_AND_INTERRUPT_CONTROL); break; } - flags &= IntEn; + flags &= INT_EN; - if (flags & TransferReady) { - while (flags & TransferReady) { + if (flags & TRANSFER_READY) { + while (flags & TRANSFER_READY) { work++; if (work > 100) { dev_dbg(dev->class_dev, "too much work in interrupt\n"); writeb(0x00, dev->mmio + - Master_DMA_And_Interrupt_Control + MASTER_DMA_AND_INTERRUPT_CONTROL ); goto out; } - auxdata = readl(dev->mmio + Group_1_FIFO); + auxdata = readl(dev->mmio + GROUP_1_FIFO); comedi_buf_write_samples(s, &auxdata, 1); - flags = readb(dev->mmio + Group_1_Flags); + flags = readb(dev->mmio + GROUP_1_FLAGS); } } - if (flags & CountExpired) { - writeb(ClearExpired, dev->mmio + Group_1_Second_Clear); + if (flags & COUNT_EXPIRED) { + writeb(CLEAR_EXPIRED, dev->mmio + GROUP_1_SECOND_CLEAR); async->events |= COMEDI_CB_EOA; - writeb(0x00, dev->mmio + OpMode); + writeb(0x00, dev->mmio + OP_MODE); break; - } else if (flags & Waited) { - writeb(ClearWaited, dev->mmio + Group_1_First_Clear); + } else if (flags & WAITED) { + writeb(CLEAR_WAITED, dev->mmio + GROUP_1_FIRST_CLEAR); async->events |= COMEDI_CB_ERROR; break; - } else if (flags & PrimaryTC) { - writeb(ClearPrimaryTC, - dev->mmio + Group_1_First_Clear); + } else if (flags & PRIMARY_TC) { + writeb(CLEAR_PRIMARY_TC, + dev->mmio + GROUP_1_FIRST_CLEAR); async->events |= COMEDI_CB_EOA; - } else if (flags & SecondaryTC) { - writeb(ClearSecondaryTC, - dev->mmio + Group_1_First_Clear); + } else if (flags & SECONDARY_TC) { + writeb(CLEAR_SECONDARY_TC, + dev->mmio + GROUP_1_FIRST_CLEAR); async->events |= COMEDI_CB_EOA; } - flags = readb(dev->mmio + Group_1_Flags); - status = readb(dev->mmio + Interrupt_And_Window_Status); + flags = readb(dev->mmio + GROUP_1_FLAGS); + status = readb(dev->mmio + INTERRUPT_AND_WINDOW_STATUS); } out: comedi_handle_events(dev, s); #if 0 if (!tag) - writeb(0x03, dev->mmio + Master_DMA_And_Interrupt_Control); + writeb(0x03, dev->mmio + MASTER_DMA_AND_INTERRUPT_CONTROL); #endif spin_unlock(&dev->spinlock); @@ -484,7 +486,7 @@ static int ni_pcidio_insn_config(struct comedi_device *dev, if (ret) return ret; - writel(s->io_bits, dev->mmio + Port_Pin_Directions(0)); + writel(s->io_bits, dev->mmio + PORT_PIN_DIRECTIONS(0)); return insn->n; } @@ -495,9 +497,9 @@ static int ni_pcidio_insn_bits(struct comedi_device *dev, unsigned int *data) { if (comedi_dio_update_state(s, data)) - writel(s->state, dev->mmio + Port_IO(0)); + writel(s->state, dev->mmio + PORT_IO(0)); - data[1] = readl(dev->mmio + Port_IO(0)); + data[1] = readl(dev->mmio + PORT_IO(0)); return insn->n; } @@ -609,7 +611,7 @@ static int ni_pcidio_inttrig(struct comedi_device *dev, if (trig_num != cmd->start_arg) return -EINVAL; - writeb(devpriv->OpModeBits, dev->mmio + OpMode); + writeb(devpriv->OP_MODEBits, dev->mmio + OP_MODE); s->async->inttrig = NULL; return 1; @@ -621,78 +623,78 @@ static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) struct comedi_cmd *cmd = &s->async->cmd; /* XXX configure ports for input */ - writel(0x0000, dev->mmio + Port_Pin_Directions(0)); + writel(0x0000, dev->mmio + PORT_PIN_DIRECTIONS(0)); if (1) { /* enable fifos A B C D */ - writeb(0x0f, dev->mmio + Data_Path); + writeb(0x0f, dev->mmio + DATA_PATH); /* set transfer width a 32 bits */ - writeb(TransferWidth(0) | TransferLength(0), - dev->mmio + Transfer_Size_Control); + writeb(TRANSFER_WIDTH(0) | TRANSFER_LENGTH(0), + dev->mmio + TRANSFER_SIZE_CONTROL); } else { - writeb(0x03, dev->mmio + Data_Path); - writeb(TransferWidth(3) | TransferLength(0), - dev->mmio + Transfer_Size_Control); + writeb(0x03, dev->mmio + DATA_PATH); + writeb(TRANSFER_WIDTH(3) | TRANSFER_LENGTH(0), + dev->mmio + TRANSFER_SIZE_CONTROL); } /* protocol configuration */ if (cmd->scan_begin_src == TRIG_TIMER) { /* page 4-5, "input with internal REQs" */ - writeb(0, dev->mmio + OpMode); - writeb(0x00, dev->mmio + ClockReg); - writeb(1, dev->mmio + Sequence); - writeb(0x04, dev->mmio + ReqReg); - writeb(4, dev->mmio + BlockMode); - writeb(3, dev->mmio + LinePolarities); - writeb(0xc0, dev->mmio + AckSer); + writeb(0, dev->mmio + OP_MODE); + writeb(0x00, dev->mmio + CLOCK_REG); + writeb(1, dev->mmio + SEQUENCE); + writeb(0x04, dev->mmio + REQ_REG); + writeb(4, dev->mmio + BLOCK_MODE); + writeb(3, dev->mmio + LINE_POLARITIES); + writeb(0xc0, dev->mmio + ACK_SER); writel(ni_pcidio_ns_to_timer(&cmd->scan_begin_arg, CMDF_ROUND_NEAREST), - dev->mmio + StartDelay); - writeb(1, dev->mmio + ReqDelay); - writeb(1, dev->mmio + ReqNotDelay); - writeb(1, dev->mmio + AckDelay); - writeb(0x0b, dev->mmio + AckNotDelay); - writeb(0x01, dev->mmio + Data1Delay); + dev->mmio + START_DELAY); + writeb(1, dev->mmio + REQ_DELAY); + writeb(1, dev->mmio + REQ_NOT_DELAY); + writeb(1, dev->mmio + ACK_DELAY); + writeb(0x0b, dev->mmio + ACK_NOT_DELAY); + writeb(0x01, dev->mmio + DATA_1_DELAY); /* * manual, page 4-5: - * ClockSpeed comment is incorrectly listed on DAQOptions + * CLOCK_SPEED comment is incorrectly listed on DAQ_OPTIONS */ - writew(0, dev->mmio + ClockSpeed); - writeb(0, dev->mmio + DAQOptions); + writew(0, dev->mmio + CLOCK_SPEED); + writeb(0, dev->mmio + DAQ_OPTIONS); } else { /* TRIG_EXT */ /* page 4-5, "input with external REQs" */ - writeb(0, dev->mmio + OpMode); - writeb(0x00, dev->mmio + ClockReg); - writeb(0, dev->mmio + Sequence); - writeb(0x00, dev->mmio + ReqReg); - writeb(4, dev->mmio + BlockMode); + writeb(0, dev->mmio + OP_MODE); + writeb(0x00, dev->mmio + CLOCK_REG); + writeb(0, dev->mmio + SEQUENCE); + writeb(0x00, dev->mmio + REQ_REG); + writeb(4, dev->mmio + BLOCK_MODE); if (!(cmd->scan_begin_arg & CR_INVERT)) /* Leading Edge */ - writeb(0, dev->mmio + LinePolarities); + writeb(0, dev->mmio + LINE_POLARITIES); else /* Trailing Edge */ - writeb(2, dev->mmio + LinePolarities); - writeb(0x00, dev->mmio + AckSer); - writel(1, dev->mmio + StartDelay); - writeb(1, dev->mmio + ReqDelay); - writeb(1, dev->mmio + ReqNotDelay); - writeb(1, dev->mmio + AckDelay); - writeb(0x0C, dev->mmio + AckNotDelay); - writeb(0x10, dev->mmio + Data1Delay); - writew(0, dev->mmio + ClockSpeed); - writeb(0x60, dev->mmio + DAQOptions); + writeb(2, dev->mmio + LINE_POLARITIES); + writeb(0x00, dev->mmio + ACK_SER); + writel(1, dev->mmio + START_DELAY); + writeb(1, dev->mmio + REQ_DELAY); + writeb(1, dev->mmio + REQ_NOT_DELAY); + writeb(1, dev->mmio + ACK_DELAY); + writeb(0x0C, dev->mmio + ACK_NOT_DELAY); + writeb(0x10, dev->mmio + DATA_1_DELAY); + writew(0, dev->mmio + CLOCK_SPEED); + writeb(0x60, dev->mmio + DAQ_OPTIONS); } if (cmd->stop_src == TRIG_COUNT) { writel(cmd->stop_arg, - dev->mmio + Transfer_Count); + dev->mmio + TRANSFER_COUNT); } else { /* XXX */ } #ifdef USE_DMA - writeb(ClearPrimaryTC | ClearSecondaryTC, - dev->mmio + Group_1_First_Clear); + writeb(CLEAR_PRIMARY_TC | CLEAR_SECONDARY_TC, + dev->mmio + GROUP_1_FIRST_CLEAR); { int retval = setup_mite_dma(dev, s); @@ -701,25 +703,25 @@ static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) return retval; } #else - writeb(0x00, dev->mmio + DMA_Line_Control_Group1); + writeb(0x00, dev->mmio + DMA_LINE_CONTROL_GROUP1); #endif - writeb(0x00, dev->mmio + DMA_Line_Control_Group2); + writeb(0x00, dev->mmio + DMA_LINE_CONTROL_GROUP2); /* clear and enable interrupts */ - writeb(0xff, dev->mmio + Group_1_First_Clear); - /* writeb(ClearExpired, dev->mmio+Group_1_Second_Clear); */ + writeb(0xff, dev->mmio + GROUP_1_FIRST_CLEAR); + /* writeb(CLEAR_EXPIRED, dev->mmio+GROUP_1_SECOND_CLEAR); */ - writeb(IntEn, dev->mmio + Interrupt_Control); - writeb(0x03, dev->mmio + Master_DMA_And_Interrupt_Control); + writeb(INT_EN, dev->mmio + INTERRUPT_CONTROL); + writeb(0x03, dev->mmio + MASTER_DMA_AND_INTERRUPT_CONTROL); if (cmd->stop_src == TRIG_NONE) { - devpriv->OpModeBits = DataLatching(0) | RunMode(7); + devpriv->OP_MODEBits = DATA_LATCHING(0) | RUN_MODE(7); } else { /* TRIG_TIMER */ - devpriv->OpModeBits = Numbered | RunMode(7); + devpriv->OP_MODEBits = NUMBERED | RUN_MODE(7); } if (cmd->start_src == TRIG_NOW) { /* start */ - writeb(devpriv->OpModeBits, dev->mmio + OpMode); + writeb(devpriv->OP_MODEBits, dev->mmio + OP_MODE); s->async->inttrig = NULL; } else { /* TRIG_INT */ @@ -732,7 +734,7 @@ static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int ni_pcidio_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { - writeb(0x00, dev->mmio + Master_DMA_And_Interrupt_Control); + writeb(0x00, dev->mmio + MASTER_DMA_AND_INTERRUPT_CONTROL); ni_pcidio_release_di_mite_channel(dev); return 0; @@ -869,12 +871,12 @@ static int pci_6534_upload_firmware(struct comedi_device *dev) static void nidio_reset_board(struct comedi_device *dev) { - writel(0, dev->mmio + Port_IO(0)); - writel(0, dev->mmio + Port_Pin_Directions(0)); - writel(0, dev->mmio + Port_Pin_Mask(0)); + writel(0, dev->mmio + PORT_IO(0)); + writel(0, dev->mmio + PORT_PIN_DIRECTIONS(0)); + writel(0, dev->mmio + PORT_PIN_MASK(0)); /* disable interrupts on board */ - writeb(0, dev->mmio + Master_DMA_And_Interrupt_Control); + writeb(0, dev->mmio + MASTER_DMA_AND_INTERRUPT_CONTROL); } static int nidio_auto_attach(struct comedi_device *dev, @@ -925,7 +927,7 @@ static int nidio_auto_attach(struct comedi_device *dev, return ret; dev_info(dev->class_dev, "%s rev=%d\n", dev->board_name, - readb(dev->mmio + Chip_Version)); + readb(dev->mmio + CHIP_VERSION)); s = &dev->subdevices[0]; diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c index 0eb388c0e1f0..048cb35723ad 100644 --- a/drivers/staging/comedi/drivers/ni_tio.c +++ b/drivers/staging/comedi/drivers/ni_tio.c @@ -224,13 +224,16 @@ static void ni_tio_set_bits_transient(struct ni_gpct *counter, unsigned int transient) { struct ni_gpct_device *counter_dev = counter->counter_dev; + unsigned int chip = counter->chip_index; unsigned long flags; - if (reg < NITIO_NUM_REGS) { + if (reg < NITIO_NUM_REGS && chip < counter_dev->num_chips) { + unsigned int *regs = counter_dev->regs[chip]; + spin_lock_irqsave(&counter_dev->regs_lock, flags); - counter_dev->regs[reg] &= ~mask; - counter_dev->regs[reg] |= (value & mask); - ni_tio_write(counter, counter_dev->regs[reg] | transient, reg); + regs[reg] &= ~mask; + regs[reg] |= (value & mask); + ni_tio_write(counter, regs[reg] | transient, reg); mmiowb(); spin_unlock_irqrestore(&counter_dev->regs_lock, flags); } @@ -267,12 +270,13 @@ unsigned int ni_tio_get_soft_copy(const struct ni_gpct *counter, enum ni_gpct_register reg) { struct ni_gpct_device *counter_dev = counter->counter_dev; + unsigned int chip = counter->chip_index; unsigned int value = 0; unsigned long flags; - if (reg < NITIO_NUM_REGS) { + if (reg < NITIO_NUM_REGS && chip < counter_dev->num_chips) { spin_lock_irqsave(&counter_dev->regs_lock, flags); - value = counter_dev->regs[reg]; + value = counter_dev->regs[chip][reg]; spin_unlock_irqrestore(&counter_dev->regs_lock, flags); } return value; @@ -302,6 +306,7 @@ static int ni_m_series_clock_src_select(const struct ni_gpct *counter, { struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned int cidx = counter->counter_index; + unsigned int chip = counter->chip_index; unsigned int second_gate_reg = NITIO_GATE2_REG(cidx); unsigned int clock_source = 0; unsigned int src; @@ -318,7 +323,7 @@ static int ni_m_series_clock_src_select(const struct ni_gpct *counter, clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS; break; case NI_M_TIMEBASE_3_CLK: - if (counter_dev->regs[second_gate_reg] & GI_SRC_SUBSEL) + if (counter_dev->regs[chip][second_gate_reg] & GI_SRC_SUBSEL) clock_source = NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS; else @@ -328,7 +333,7 @@ static int ni_m_series_clock_src_select(const struct ni_gpct *counter, clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS; break; case NI_M_NEXT_GATE_CLK: - if (counter_dev->regs[second_gate_reg] & GI_SRC_SUBSEL) + if (counter_dev->regs[chip][second_gate_reg] & GI_SRC_SUBSEL) clock_source = NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS; else clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS; @@ -721,6 +726,7 @@ static void ni_tio_set_source_subselect(struct ni_gpct *counter, { struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned int cidx = counter->counter_index; + unsigned int chip = counter->chip_index; unsigned int second_gate_reg = NITIO_GATE2_REG(cidx); if (counter_dev->variant != ni_gpct_variant_m_series) @@ -729,18 +735,18 @@ static void ni_tio_set_source_subselect(struct ni_gpct *counter, /* Gi_Source_Subselect is zero */ case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS: case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS: - counter_dev->regs[second_gate_reg] &= ~GI_SRC_SUBSEL; + counter_dev->regs[chip][second_gate_reg] &= ~GI_SRC_SUBSEL; break; /* Gi_Source_Subselect is one */ case NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS: case NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS: - counter_dev->regs[second_gate_reg] |= GI_SRC_SUBSEL; + counter_dev->regs[chip][second_gate_reg] |= GI_SRC_SUBSEL; break; /* Gi_Source_Subselect doesn't matter */ default: return; } - ni_tio_write(counter, counter_dev->regs[second_gate_reg], + ni_tio_write(counter, counter_dev->regs[chip][second_gate_reg], second_gate_reg); } @@ -1116,6 +1122,7 @@ static int ni_tio_set_other_src(struct ni_gpct *counter, unsigned int index, { struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned int cidx = counter->counter_index; + unsigned int chip = counter->chip_index; unsigned int abz_reg, shift, mask; if (counter_dev->variant != ni_gpct_variant_m_series) @@ -1141,9 +1148,9 @@ static int ni_tio_set_other_src(struct ni_gpct *counter, unsigned int index, if (source > 0x1f) source = 0x1f; /* Disable gate */ - counter_dev->regs[abz_reg] &= ~mask; - counter_dev->regs[abz_reg] |= (source << shift) & mask; - ni_tio_write(counter, counter_dev->regs[abz_reg], abz_reg); + counter_dev->regs[chip][abz_reg] &= ~mask; + counter_dev->regs[chip][abz_reg] |= (source << shift) & mask; + ni_tio_write(counter, counter_dev->regs[chip][abz_reg], abz_reg); return 0; } @@ -1632,6 +1639,7 @@ int ni_tio_insn_read(struct comedi_device *dev, struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned int channel = CR_CHAN(insn->chanspec); unsigned int cidx = counter->counter_index; + unsigned int chip = counter->chip_index; int i; for (i = 0; i < insn->n; i++) { @@ -1640,10 +1648,12 @@ int ni_tio_insn_read(struct comedi_device *dev, data[i] = ni_tio_read_sw_save_reg(dev, s); break; case 1: - data[i] = counter_dev->regs[NITIO_LOADA_REG(cidx)]; + data[i] = + counter_dev->regs[chip][NITIO_LOADA_REG(cidx)]; break; case 2: - data[i] = counter_dev->regs[NITIO_LOADB_REG(cidx)]; + data[i] = + counter_dev->regs[chip][NITIO_LOADB_REG(cidx)]; break; } } @@ -1670,6 +1680,7 @@ int ni_tio_insn_write(struct comedi_device *dev, struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned int channel = CR_CHAN(insn->chanspec); unsigned int cidx = counter->counter_index; + unsigned int chip = counter->chip_index; unsigned int load_reg; if (insn->n < 1) @@ -1690,14 +1701,15 @@ int ni_tio_insn_write(struct comedi_device *dev, ni_tio_set_bits_transient(counter, NITIO_CMD_REG(cidx), 0, 0, GI_LOAD); /* restore load reg */ - ni_tio_write(counter, counter_dev->regs[load_reg], load_reg); + ni_tio_write(counter, counter_dev->regs[chip][load_reg], + load_reg); break; case 1: - counter_dev->regs[NITIO_LOADA_REG(cidx)] = data[0]; + counter_dev->regs[chip][NITIO_LOADA_REG(cidx)] = data[0]; ni_tio_write(counter, data[0], NITIO_LOADA_REG(cidx)); break; case 2: - counter_dev->regs[NITIO_LOADB_REG(cidx)] = data[0]; + counter_dev->regs[chip][NITIO_LOADB_REG(cidx)] = data[0]; ni_tio_write(counter, data[0], NITIO_LOADB_REG(cidx)); break; default: @@ -1711,11 +1723,12 @@ void ni_tio_init_counter(struct ni_gpct *counter) { struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned int cidx = counter->counter_index; + unsigned int chip = counter->chip_index; ni_tio_reset_count_and_disarm(counter); /* initialize counter registers */ - counter_dev->regs[NITIO_AUTO_INC_REG(cidx)] = 0x0; + counter_dev->regs[chip][NITIO_AUTO_INC_REG(cidx)] = 0x0; ni_tio_write(counter, 0x0, NITIO_AUTO_INC_REG(cidx)); ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), @@ -1723,10 +1736,10 @@ void ni_tio_init_counter(struct ni_gpct *counter) ni_tio_set_bits(counter, NITIO_MODE_REG(cidx), ~0, 0); - counter_dev->regs[NITIO_LOADA_REG(cidx)] = 0x0; + counter_dev->regs[chip][NITIO_LOADA_REG(cidx)] = 0x0; ni_tio_write(counter, 0x0, NITIO_LOADA_REG(cidx)); - counter_dev->regs[NITIO_LOADB_REG(cidx)] = 0x0; + counter_dev->regs[chip][NITIO_LOADB_REG(cidx)] = 0x0; ni_tio_write(counter, 0x0, NITIO_LOADB_REG(cidx)); ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), ~0, 0); @@ -1735,7 +1748,7 @@ void ni_tio_init_counter(struct ni_gpct *counter) ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx), ~0, 0); if (ni_tio_has_gate2_registers(counter_dev)) { - counter_dev->regs[NITIO_GATE2_REG(cidx)] = 0x0; + counter_dev->regs[chip][NITIO_GATE2_REG(cidx)] = 0x0; ni_tio_write(counter, 0x0, NITIO_GATE2_REG(cidx)); } @@ -1776,9 +1789,16 @@ ni_gpct_device_construct(struct comedi_device *dev, spin_lock_init(&counter_dev->regs_lock); + counter_dev->num_counters = num_counters; + counter_dev->num_chips = DIV_ROUND_UP(num_counters, counters_per_chip); + counter_dev->counters = kcalloc(num_counters, sizeof(*counter), GFP_KERNEL); - if (!counter_dev->counters) { + counter_dev->regs = kcalloc(counter_dev->num_chips, + sizeof(*counter_dev->regs), GFP_KERNEL); + if (!counter_dev->regs || !counter_dev->counters) { + kfree(counter_dev->regs); + kfree(counter_dev->counters); kfree(counter_dev); return NULL; } @@ -1790,8 +1810,6 @@ ni_gpct_device_construct(struct comedi_device *dev, counter->counter_index = i % counters_per_chip; spin_lock_init(&counter->lock); } - counter_dev->num_counters = num_counters; - counter_dev->counters_per_chip = counters_per_chip; return counter_dev; } @@ -1801,6 +1819,7 @@ void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev) { if (!counter_dev) return; + kfree(counter_dev->regs); kfree(counter_dev->counters); kfree(counter_dev); } diff --git a/drivers/staging/comedi/drivers/ni_tio.h b/drivers/staging/comedi/drivers/ni_tio.h index 1e85d0a53715..e7b05718df9b 100644 --- a/drivers/staging/comedi/drivers/ni_tio.h +++ b/drivers/staging/comedi/drivers/ni_tio.h @@ -107,8 +107,8 @@ struct ni_gpct_device { enum ni_gpct_variant variant; struct ni_gpct *counters; unsigned int num_counters; - unsigned int counters_per_chip; - unsigned int regs[NITIO_NUM_REGS]; + unsigned int num_chips; + unsigned int (*regs)[NITIO_NUM_REGS]; /* [num_chips][NITIO_NUM_REGS] */ spinlock_t regs_lock; /* protects 'regs' */ const struct ni_route_tables *routing_tables; /* link to routes */ }; diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index e18c0723b760..0d54f394dbd2 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -61,7 +61,7 @@ #define USBDUXFASTSUB_CPUCS 0xE600 /* - * max lenghth of the transfer-buffer for software upload + * max length of the transfer-buffer for software upload */ #define TB_LEN 0x2000 diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c index 8e8f57c4f029..a913d40f0801 100644 --- a/drivers/staging/emxx_udc/emxx_udc.c +++ b/drivers/staging/emxx_udc/emxx_udc.c @@ -27,7 +27,7 @@ #include <linux/usb/gadget.h> #include <linux/irq.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include "emxx_udc.h" @@ -2220,7 +2220,7 @@ static inline void _nbu2ss_check_vbus(struct nbu2ss_udc *udc) mdelay(VBUS_CHATTERING_MDELAY); /* wait (ms) */ /* VBUS ON Check*/ - reg_dt = gpio_get_value(VBUS_VALUE); + reg_dt = gpiod_get_value(vbus_gpio); if (reg_dt == 0) { udc->linux_suspended = 0; @@ -2247,7 +2247,7 @@ static inline void _nbu2ss_check_vbus(struct nbu2ss_udc *udc) } } else { mdelay(5); /* wait (5ms) */ - reg_dt = gpio_get_value(VBUS_VALUE); + reg_dt = gpiod_get_value(vbus_gpio); if (reg_dt == 0) return; @@ -2311,7 +2311,7 @@ static inline void _nbu2ss_int_usb_suspend(struct nbu2ss_udc *udc) u32 reg_dt; if (udc->usb_suspended == 0) { - reg_dt = gpio_get_value(VBUS_VALUE); + reg_dt = gpiod_get_value(vbus_gpio); if (reg_dt == 0) return; @@ -2351,7 +2351,7 @@ static irqreturn_t _nbu2ss_udc_irq(int irq, void *_udc) struct nbu2ss_udc *udc = (struct nbu2ss_udc *)_udc; struct fc_regs __iomem *preg = udc->p_regs; - if (gpio_get_value(VBUS_VALUE) == 0) { + if (gpiod_get_value(vbus_gpio) == 0) { _nbu2ss_writel(&preg->USB_INT_STA, ~USB_INT_STA_RW); _nbu2ss_writel(&preg->USB_INT_ENA, 0); return IRQ_HANDLED; @@ -2360,7 +2360,7 @@ static irqreturn_t _nbu2ss_udc_irq(int irq, void *_udc) spin_lock(&udc->lock); for (;;) { - if (gpio_get_value(VBUS_VALUE) == 0) { + if (gpiod_get_value(vbus_gpio) == 0) { _nbu2ss_writel(&preg->USB_INT_STA, ~USB_INT_STA_RW); _nbu2ss_writel(&preg->USB_INT_ENA, 0); status = 0; @@ -2750,7 +2750,7 @@ static int nbu2ss_ep_fifo_status(struct usb_ep *_ep) preg = udc->p_regs; - data = gpio_get_value(VBUS_VALUE); + data = gpiod_get_value(vbus_gpio); if (data == 0) return -EINVAL; @@ -2790,7 +2790,7 @@ static void nbu2ss_ep_fifo_flush(struct usb_ep *_ep) return; } - data = gpio_get_value(VBUS_VALUE); + data = gpiod_get_value(vbus_gpio); if (data == 0) return; @@ -2832,7 +2832,7 @@ static int nbu2ss_gad_get_frame(struct usb_gadget *pgadget) } udc = container_of(pgadget, struct nbu2ss_udc, gadget); - data = gpio_get_value(VBUS_VALUE); + data = gpiod_get_value(vbus_gpio); if (data == 0) return -EINVAL; @@ -2854,7 +2854,7 @@ static int nbu2ss_gad_wakeup(struct usb_gadget *pgadget) udc = container_of(pgadget, struct nbu2ss_udc, gadget); - data = gpio_get_value(VBUS_VALUE); + data = gpiod_get_value(vbus_gpio); if (data == 0) { dev_warn(&pgadget->dev, "VBUS LEVEL = %d\n", data); return -EINVAL; @@ -3119,12 +3119,13 @@ static int nbu2ss_drv_probe(struct platform_device *pdev) } /* VBUS Interrupt */ - irq_set_irq_type(INT_VBUS, IRQ_TYPE_EDGE_BOTH); - status = request_irq(INT_VBUS, + vbus_irq = gpiod_to_irq(vbus_gpio); + irq_set_irq_type(vbus_irq, IRQ_TYPE_EDGE_BOTH); + status = request_irq(vbus_irq, _nbu2ss_vbus_irq, IRQF_SHARED, driver_name, udc); if (status != 0) { - dev_err(udc->dev, "request_irq(INT_VBUS) failed\n"); + dev_err(udc->dev, "request_irq(vbus_irq) failed\n"); return status; } @@ -3160,7 +3161,7 @@ static int nbu2ss_drv_remove(struct platform_device *pdev) } /* Interrupt Handler - Release */ - free_irq(INT_VBUS, udc); + free_irq(vbus_irq, udc); return 0; } @@ -3201,7 +3202,7 @@ static int nbu2ss_drv_resume(struct platform_device *pdev) if (!udc) return 0; - data = gpio_get_value(VBUS_VALUE); + data = gpiod_get_value(vbus_gpio); if (data) { udc->vbus_active = 1; udc->devstate = USB_STATE_POWERED; diff --git a/drivers/staging/emxx_udc/emxx_udc.h b/drivers/staging/emxx_udc/emxx_udc.h index e28a74da9633..b8c3dee5626c 100644 --- a/drivers/staging/emxx_udc/emxx_udc.h +++ b/drivers/staging/emxx_udc/emxx_udc.h @@ -30,6 +30,8 @@ /* below hacked up for staging integration */ #define GPIO_VBUS 0 /* GPIO_P153 on KZM9D */ #define INT_VBUS 0 /* IRQ for GPIO_P153 */ +struct gpio_desc *vbus_gpio; +int vbus_irq; /*------------ Board dependence(Wait) */ diff --git a/drivers/staging/erofs/Documentation/filesystems/erofs.txt b/drivers/staging/erofs/Documentation/filesystems/erofs.txt new file mode 100644 index 000000000000..961ec4da7705 --- /dev/null +++ b/drivers/staging/erofs/Documentation/filesystems/erofs.txt @@ -0,0 +1,208 @@ +Overview +======== + +EROFS file-system stands for Enhanced Read-Only File System. Different +from other read-only file systems, it aims to be designed for flexibility, +scalability, but be kept simple and high performance. + +It is designed as a better filesystem solution for the following scenarios: + - read-only storage media or + + - part of a fully trusted read-only solution, which means it needs to be + immutable and bit-for-bit identical to the official golden image for + their releases due to security and other considerations and + + - hope to save some extra storage space with guaranteed end-to-end performance + by using reduced metadata and transparent file compression, especially + for those embedded devices with limited memory (ex, smartphone); + +Here is the main features of EROFS: + - Little endian on-disk design; + + - Currently 4KB block size (nobh) and therefore maximum 16TB address space; + + - Metadata & data could be mixed by design; + + - 2 inode versions for different requirements: + v1 v2 + Inode metadata size: 32 bytes 64 bytes + Max file size: 4 GB 16 EB (also limited by max. vol size) + Max uids/gids: 65536 4294967296 + File creation time: no yes (64 + 32-bit timestamp) + Max hardlinks: 65536 4294967296 + Metadata reserved: 4 bytes 14 bytes + + - Support extended attributes (xattrs) as an option; + + - Support xattr inline and tail-end data inline for all files; + + - Support POSIX.1e ACLs by using xattrs; + + - Support transparent file compression as an option: + LZ4 algorithm with 4 KB fixed-output compression for high performance; + +The following git tree provides the file system user-space tools under +development (ex, formatting tool mkfs.erofs): +>> git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs-utils.git + +Bugs and patches are welcome, please kindly help us and send to the following +linux-erofs mailing list: +>> linux-erofs mailing list <linux-erofs@lists.ozlabs.org> + +Note that EROFS is still working in progress as a Linux staging driver, +Cc the staging mailing list as well is highly recommended: +>> Linux Driver Project Developer List <devel@driverdev.osuosl.org> + +Mount options +============= + +fault_injection=%d Enable fault injection in all supported types with + specified injection rate. Supported injection type: + Type_Name Type_Value + FAULT_KMALLOC 0x000000001 +(no)user_xattr Setup Extended User Attributes. Note: xattr is enabled + by default if CONFIG_EROFS_FS_XATTR is selected. +(no)acl Setup POSIX Access Control List. Note: acl is enabled + by default if CONFIG_EROFS_FS_POSIX_ACL is selected. + +On-disk details +=============== + +Summary +------- +Different from other read-only file systems, an EROFS volume is designed +to be as simple as possible: + + |-> aligned with the block size + ____________________________________________________________ + | |SB| | ... | Metadata | ... | Data | Metadata | ... | Data | + |_|__|_|_____|__________|_____|______|__________|_____|______| + 0 +1K + +All data areas should be aligned with the block size, but metadata areas +may not. All metadatas can be now observed in two different spaces (views): + 1. Inode metadata space + Each valid inode should be aligned with an inode slot, which is a fixed + value (32 bytes) and designed to be kept in line with v1 inode size. + + Each inode can be directly found with the following formula: + inode offset = meta_blkaddr * block_size + 32 * nid + + |-> aligned with 8B + |-> followed closely + + meta_blkaddr blocks |-> another slot + _____________________________________________________________________ + | ... | inode | xattrs | extents | data inline | ... | inode ... + |________|_______|(optional)|(optional)|__(optional)_|_____|__________ + |-> aligned with the inode slot size + . . + . . + . . + . . + . . + . . + .____________________________________________________|-> aligned with 4B + | xattr_ibody_header | shared xattrs | inline xattrs | + |____________________|_______________|_______________| + |-> 12 bytes <-|->x * 4 bytes<-| . + . . . + . . . + . . . + ._______________________________.______________________. + | id | id | id | id | ... | id | ent | ... | ent| ... | + |____|____|____|____|______|____|_____|_____|____|_____| + |-> aligned with 4B + |-> aligned with 4B + + Inode could be 32 or 64 bytes, which can be distinguished from a common + field which all inode versions have -- i_advise: + + __________________ __________________ + | i_advise | | i_advise | + |__________________| |__________________| + | ... | | ... | + | | | | + |__________________| 32 bytes | | + | | + |__________________| 64 bytes + + Xattrs, extents, data inline are followed by the corresponding inode with + proper alignes, and they could be optional for different data mappings, + _currently_ there are totally 3 valid data mappings supported: + + 1) flat file data without data inline (no extent); + 2) fixed-output size data compression (must have extents); + 3) flat file data with tail-end data inline (no extent); + + The size of the optional xattrs is indicated by i_xattr_count in inode + header. Large xattrs or xattrs shared by many different files can be + stored in shared xattrs metadata rather than inlined right after inode. + + 2. Shared xattrs metadata space + Shared xattrs space is similar to the above inode space, started with + a specific block indicated by xattr_blkaddr, organized one by one with + proper align. + + Each share xattr can also be directly found by the following formula: + xattr offset = xattr_blkaddr * block_size + 4 * xattr_id + + |-> aligned by 4 bytes + + xattr_blkaddr blocks |-> aligned with 4 bytes + _________________________________________________________________________ + | ... | xattr_entry | xattr data | ... | xattr_entry | xattr data ... + |________|_____________|_____________|_____|______________|_______________ + +Directories +----------- +All directories are now organized in a compact on-disk format. Note that +each directory block is divided into index and name areas in order to support +random file lookup, and all directory entries are _strictly_ recorded in +alphabetical order in order to support improved prefix binary search +algorithm (could refer to the related source code). + + ___________________________ + / | + / ______________|________________ + / / | nameoff1 | nameoffN-1 + ____________.______________._______________v________________v__________ +| dirent | dirent | ... | dirent | filename | filename | ... | filename | +|___.0___|____1___|_____|___N-1__|____0_____|____1_____|_____|___N-1____| + \ ^ + \ | * could have + \ | trailing '\0' + \________________________| nameoff0 + + Directory block + +Note that apart from the offset of the first filename, nameoff0 also indicates +the total number of directory entries in this block since it is no need to +introduce another on-disk field at all. + +Compression +----------- +Currently, EROFS supports 4KB fixed-output clustersize transparent file +compression, as illustrated below: + + |---- Variant-Length Extent ----|-------- VLE --------|----- VLE ----- + clusterofs clusterofs clusterofs + | | | logical data +_________v_______________________________v_____________________v_______________ +... | . | | . | | . | ... +____|____.________|_____________|________.____|_____________|__.__________|____ + |-> cluster <-|-> cluster <-|-> cluster <-|-> cluster <-|-> cluster <-| + size size size size size + . . . . + . . . . + . . . . + _______._____________._____________._____________._____________________ + ... | | | | ... physical data + _______|_____________|_____________|_____________|_____________________ + |-> cluster <-|-> cluster <-|-> cluster <-| + size size size + +Currently each on-disk physical cluster can contain 4KB (un)compressed data +at most. For each logical cluster, there is a corresponding on-disk index to +describe its cluster type, physical cluster address, etc. + +See "struct z_erofs_vle_decompressed_index" in erofs_fs.h for more details. + diff --git a/drivers/staging/erofs/Makefile b/drivers/staging/erofs/Makefile index c91b65223f99..38ab344a285e 100644 --- a/drivers/staging/erofs/Makefile +++ b/drivers/staging/erofs/Makefile @@ -6,7 +6,7 @@ ccflags-y += -Wall -DEROFS_VERSION=\"$(EROFS_VERSION)\" obj-$(CONFIG_EROFS_FS) += erofs.o # staging requirement: to be self-contained in its own directory -ccflags-y += -I$(src)/include +ccflags-y += -I $(srctree)/$(src)/include erofs-objs := super.o inode.o data.o namei.o dir.o utils.o erofs-$(CONFIG_EROFS_FS_XATTR) += xattr.o erofs-$(CONFIG_EROFS_FS_ZIP) += unzip_vle.o unzip_vle_lz4.o diff --git a/drivers/staging/erofs/data.c b/drivers/staging/erofs/data.c index 5a55f0bfdfbb..9c471f08ffd4 100644 --- a/drivers/staging/erofs/data.c +++ b/drivers/staging/erofs/data.c @@ -165,43 +165,16 @@ err_out: return err; } -#ifdef CONFIG_EROFS_FS_ZIP -extern int z_erofs_map_blocks_iter(struct inode *, - struct erofs_map_blocks *, - struct page **, int); -#endif - -int erofs_map_blocks_iter(struct inode *inode, - struct erofs_map_blocks *map, - struct page **mpage_ret, int flags) -{ - /* by default, reading raw data never use erofs_map_blocks_iter */ - if (unlikely(!is_inode_layout_compression(inode))) { - if (*mpage_ret) - put_page(*mpage_ret); - *mpage_ret = NULL; - - return erofs_map_blocks(inode, map, flags); - } - -#ifdef CONFIG_EROFS_FS_ZIP - return z_erofs_map_blocks_iter(inode, map, mpage_ret, flags); -#else - /* data compression is not available */ - return -ENOTSUPP; -#endif -} - int erofs_map_blocks(struct inode *inode, struct erofs_map_blocks *map, int flags) { if (unlikely(is_inode_layout_compression(inode))) { - struct page *mpage = NULL; - int err; + int err = z_erofs_map_blocks_iter(inode, map, flags); - err = erofs_map_blocks_iter(inode, map, &mpage, flags); - if (mpage) - put_page(mpage); + if (map->mpage) { + put_page(map->mpage); + map->mpage = NULL; + } return err; } return erofs_map_blocks_flatmode(inode, map, flags); diff --git a/drivers/staging/erofs/dir.c b/drivers/staging/erofs/dir.c index 833f052f79d0..829f7b12e0dc 100644 --- a/drivers/staging/erofs/dir.c +++ b/drivers/staging/erofs/dir.c @@ -24,8 +24,8 @@ static const unsigned char erofs_filetype_table[EROFS_FT_MAX] = { }; static int erofs_fill_dentries(struct dir_context *ctx, - void *dentry_blk, unsigned int *ofs, - unsigned int nameoff, unsigned int maxsize) + void *dentry_blk, unsigned int *ofs, + unsigned int nameoff, unsigned int maxsize) { struct erofs_dirent *de = dentry_blk; const struct erofs_dirent *end = dentry_blk + nameoff; @@ -98,15 +98,14 @@ static int erofs_readdir(struct file *f, struct dir_context *ctx) if (IS_ERR(dentry_page)) continue; - lock_page(dentry_page); de = (struct erofs_dirent *)kmap(dentry_page); nameoff = le16_to_cpu(de->nameoff); if (unlikely(nameoff < sizeof(struct erofs_dirent) || - nameoff >= PAGE_SIZE)) { + nameoff >= PAGE_SIZE)) { errln("%s, invalid de[0].nameoff %u", - __func__, nameoff); + __func__, nameoff); err = -EIO; goto skip_this; @@ -128,7 +127,6 @@ static int erofs_readdir(struct file *f, struct dir_context *ctx) skip_this: kunmap(dentry_page); - unlock_page(dentry_page); put_page(dentry_page); ctx->pos = blknr_to_addr(i) + ofs; @@ -144,6 +142,6 @@ skip_this: const struct file_operations erofs_dir_fops = { .llseek = generic_file_llseek, .read = generic_read_dir, - .iterate = erofs_readdir, + .iterate_shared = erofs_readdir, }; diff --git a/drivers/staging/erofs/inode.c b/drivers/staging/erofs/inode.c index d7fbf5f4600f..924b8dfc7a8f 100644 --- a/drivers/staging/erofs/inode.c +++ b/drivers/staging/erofs/inode.c @@ -184,32 +184,18 @@ static int fill_inode(struct inode *inode, int isdir) if (!err) { /* setup the new inode */ if (S_ISREG(inode->i_mode)) { -#ifdef CONFIG_EROFS_FS_XATTR - if (vi->xattr_isize) - inode->i_op = &erofs_generic_xattr_iops; -#endif + inode->i_op = &erofs_generic_iops; inode->i_fop = &generic_ro_fops; } else if (S_ISDIR(inode->i_mode)) { - inode->i_op = -#ifdef CONFIG_EROFS_FS_XATTR - vi->xattr_isize ? &erofs_dir_xattr_iops : -#endif - &erofs_dir_iops; + inode->i_op = &erofs_dir_iops; inode->i_fop = &erofs_dir_fops; } else if (S_ISLNK(inode->i_mode)) { /* by default, page_get_link is used for symlink */ - inode->i_op = -#ifdef CONFIG_EROFS_FS_XATTR - &erofs_symlink_xattr_iops, -#else - &page_symlink_inode_operations; -#endif + inode->i_op = &erofs_symlink_iops; inode_nohighmem(inode); } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { -#ifdef CONFIG_EROFS_FS_XATTR - inode->i_op = &erofs_special_inode_operations; -#endif + inode->i_op = &erofs_generic_iops; init_special_inode(inode, inode->i_mode, inode->i_rdev); } else { err = -EIO; @@ -297,23 +283,26 @@ struct inode *erofs_iget(struct super_block *sb, return inode; } +const struct inode_operations erofs_generic_iops = { #ifdef CONFIG_EROFS_FS_XATTR -const struct inode_operations erofs_generic_xattr_iops = { .listxattr = erofs_listxattr, +#endif + .get_acl = erofs_get_acl, }; -const struct inode_operations erofs_symlink_xattr_iops = { +const struct inode_operations erofs_symlink_iops = { .get_link = page_get_link, +#ifdef CONFIG_EROFS_FS_XATTR .listxattr = erofs_listxattr, +#endif + .get_acl = erofs_get_acl, }; -const struct inode_operations erofs_special_inode_operations = { - .listxattr = erofs_listxattr, -}; - -const struct inode_operations erofs_fast_symlink_xattr_iops = { +const struct inode_operations erofs_fast_symlink_iops = { .get_link = simple_get_link, +#ifdef CONFIG_EROFS_FS_XATTR .listxattr = erofs_listxattr, -}; #endif + .get_acl = erofs_get_acl, +}; diff --git a/drivers/staging/erofs/internal.h b/drivers/staging/erofs/internal.h index e049d00c087a..e3bfde00c7d2 100644 --- a/drivers/staging/erofs/internal.h +++ b/drivers/staging/erofs/internal.h @@ -252,47 +252,20 @@ static inline int erofs_wait_on_workgroup_freezed(struct erofs_workgroup *grp) } #endif -static inline bool erofs_workgroup_get(struct erofs_workgroup *grp, int *ocnt) -{ - int o; - -repeat: - o = erofs_wait_on_workgroup_freezed(grp); - - if (unlikely(o <= 0)) - return -1; - - if (unlikely(atomic_cmpxchg(&grp->refcount, o, o + 1) != o)) - goto repeat; - - *ocnt = o; - return 0; -} - -#define __erofs_workgroup_get(grp) atomic_inc(&(grp)->refcount) -#define __erofs_workgroup_put(grp) atomic_dec(&(grp)->refcount) - -extern int erofs_workgroup_put(struct erofs_workgroup *grp); - -extern struct erofs_workgroup *erofs_find_workgroup( - struct super_block *sb, pgoff_t index, bool *tag); - -extern int erofs_register_workgroup(struct super_block *sb, - struct erofs_workgroup *grp, bool tag); - -extern unsigned long erofs_shrink_workstation(struct erofs_sb_info *sbi, - unsigned long nr_shrink, bool cleanup); - -static inline void erofs_workstation_cleanup_all(struct super_block *sb) -{ - erofs_shrink_workstation(EROFS_SB(sb), ~0UL, true); -} +int erofs_workgroup_put(struct erofs_workgroup *grp); +struct erofs_workgroup *erofs_find_workgroup(struct super_block *sb, + pgoff_t index, bool *tag); +int erofs_register_workgroup(struct super_block *sb, + struct erofs_workgroup *grp, bool tag); +unsigned long erofs_shrink_workstation(struct erofs_sb_info *sbi, + unsigned long nr_shrink, bool cleanup); +void erofs_workgroup_free_rcu(struct erofs_workgroup *grp); #ifdef EROFS_FS_HAS_MANAGED_CACHE -extern int erofs_try_to_free_all_cached_pages(struct erofs_sb_info *sbi, - struct erofs_workgroup *egrp); -extern int erofs_try_to_free_cached_page(struct address_space *mapping, - struct page *page); +int erofs_try_to_free_all_cached_pages(struct erofs_sb_info *sbi, + struct erofs_workgroup *egrp); +int erofs_try_to_free_cached_page(struct address_space *mapping, + struct page *page); #define MNGD_MAPPING(sbi) ((sbi)->managed_cache->i_mapping) #else @@ -354,12 +327,17 @@ static inline erofs_off_t iloc(struct erofs_sb_info *sbi, erofs_nid_t nid) return blknr_to_addr(sbi->meta_blkaddr) + (nid << sbi->islotbits); } -#define inode_set_inited_xattr(inode) (EROFS_V(inode)->flags |= 1) -#define inode_has_inited_xattr(inode) (EROFS_V(inode)->flags & 1) +/* atomic flag definitions */ +#define EROFS_V_EA_INITED_BIT 0 + +/* bitlock definitions (arranged in reverse order) */ +#define EROFS_V_BL_XATTR_BIT (BITS_PER_LONG - 1) struct erofs_vnode { erofs_nid_t nid; - unsigned int flags; + + /* atomic flags (including bitlocks) */ + unsigned long flags; unsigned char data_mapping_mode; /* inline size in bytes */ @@ -412,8 +390,6 @@ static inline bool is_inode_layout_inline(struct inode *inode) } extern const struct super_operations erofs_sops; -extern const struct inode_operations erofs_dir_iops; -extern const struct file_operations erofs_dir_fops; extern const struct address_space_operations erofs_raw_access_aops; #ifdef CONFIG_EROFS_FS_ZIP @@ -461,11 +437,26 @@ struct erofs_map_blocks { u64 m_plen, m_llen; unsigned int m_flags; + + struct page *mpage; }; /* Flags used by erofs_map_blocks() */ #define EROFS_GET_BLOCKS_RAW 0x0001 +#ifdef CONFIG_EROFS_FS_ZIP +int z_erofs_map_blocks_iter(struct inode *inode, + struct erofs_map_blocks *map, + int flags); +#else +static inline int z_erofs_map_blocks_iter(struct inode *inode, + struct erofs_map_blocks *map, + int flags) +{ + return -ENOTSUPP; +} +#endif + /* data.c */ static inline struct bio * erofs_grab_bio(struct super_block *sb, @@ -506,8 +497,8 @@ static inline void __submit_bio(struct bio *bio, unsigned op, unsigned op_flags) #define EROFS_IO_MAX_RETRIES_NOFAIL CONFIG_EROFS_FS_IO_MAX_RETRIES #endif -extern struct page *__erofs_get_meta_page(struct super_block *sb, - erofs_blk_t blkaddr, bool prio, bool nofail); +struct page *__erofs_get_meta_page(struct super_block *sb, erofs_blk_t blkaddr, + bool prio, bool nofail); static inline struct page *erofs_get_meta_page(struct super_block *sb, erofs_blk_t blkaddr, bool prio) @@ -521,15 +512,7 @@ static inline struct page *erofs_get_meta_page_nofail(struct super_block *sb, return __erofs_get_meta_page(sb, blkaddr, prio, true); } -extern int erofs_map_blocks(struct inode *, struct erofs_map_blocks *, int); -extern int erofs_map_blocks_iter(struct inode *, struct erofs_map_blocks *, - struct page **, int); - -struct erofs_map_blocks_iter { - struct erofs_map_blocks map; - struct page *mpage; -}; - +int erofs_map_blocks(struct inode *, struct erofs_map_blocks *, int); static inline struct page * erofs_get_inline_page(struct inode *inode, @@ -549,41 +532,31 @@ static inline unsigned long erofs_inode_hash(erofs_nid_t nid) #endif } -extern struct inode *erofs_iget(struct super_block *sb, - erofs_nid_t nid, bool dir); - -/* dir.c */ -int erofs_namei(struct inode *dir, struct qstr *name, - erofs_nid_t *nid, unsigned *d_type); - -#ifdef CONFIG_EROFS_FS_XATTR -/* xattr.c */ -extern const struct xattr_handler *erofs_xattr_handlers[]; - -/* symlink and special inode */ -extern const struct inode_operations erofs_symlink_xattr_iops; -extern const struct inode_operations erofs_fast_symlink_xattr_iops; -extern const struct inode_operations erofs_special_inode_operations; -#endif +extern const struct inode_operations erofs_generic_iops; +extern const struct inode_operations erofs_symlink_iops; +extern const struct inode_operations erofs_fast_symlink_iops; static inline void set_inode_fast_symlink(struct inode *inode) { -#ifdef CONFIG_EROFS_FS_XATTR - inode->i_op = &erofs_fast_symlink_xattr_iops; -#else - inode->i_op = &simple_symlink_inode_operations; -#endif + inode->i_op = &erofs_fast_symlink_iops; } static inline bool is_inode_fast_symlink(struct inode *inode) { -#ifdef CONFIG_EROFS_FS_XATTR - return inode->i_op == &erofs_fast_symlink_xattr_iops; -#else - return inode->i_op == &simple_symlink_inode_operations; -#endif + return inode->i_op == &erofs_fast_symlink_iops; } +struct inode *erofs_iget(struct super_block *sb, erofs_nid_t nid, bool dir); + +/* namei.c */ +extern const struct inode_operations erofs_dir_iops; + +int erofs_namei(struct inode *dir, struct qstr *name, + erofs_nid_t *nid, unsigned int *d_type); + +/* dir.c */ +extern const struct file_operations erofs_dir_fops; + static inline void *erofs_vmap(struct page **pages, unsigned int count) { #ifdef CONFIG_EROFS_FS_USE_VM_MAP_RAM @@ -612,15 +585,11 @@ static inline void erofs_vunmap(const void *mem, unsigned int count) } /* utils.c */ -extern struct page *erofs_allocpage(struct list_head *pool, gfp_t gfp); - -extern void erofs_register_super(struct super_block *sb); -extern void erofs_unregister_super(struct super_block *sb); +extern struct shrinker erofs_shrinker_info; -extern unsigned long erofs_shrink_count(struct shrinker *shrink, - struct shrink_control *sc); -extern unsigned long erofs_shrink_scan(struct shrinker *shrink, - struct shrink_control *sc); +struct page *erofs_allocpage(struct list_head *pool, gfp_t gfp); +void erofs_register_super(struct super_block *sb); +void erofs_unregister_super(struct super_block *sb); #ifndef lru_to_page #define lru_to_page(head) (list_entry((head)->prev, struct page, lru)) diff --git a/drivers/staging/erofs/namei.c b/drivers/staging/erofs/namei.c index 5596c52e246d..3f4fa52c10fa 100644 --- a/drivers/staging/erofs/namei.c +++ b/drivers/staging/erofs/namei.c @@ -15,74 +15,77 @@ #include <trace/events/erofs.h> -/* based on the value of qn->len is accurate */ -static inline int dirnamecmp(struct qstr *qn, - struct qstr *qd, unsigned int *matched) +struct erofs_qstr { + const unsigned char *name; + const unsigned char *end; +}; + +/* based on the end of qn is accurate and it must have the trailing '\0' */ +static inline int dirnamecmp(const struct erofs_qstr *qn, + const struct erofs_qstr *qd, + unsigned int *matched) { - unsigned int i = *matched, len = min(qn->len, qd->len); -loop: - if (unlikely(i >= len)) { - *matched = i; - if (qn->len < qd->len) { - /* - * actually (qn->len == qd->len) - * when qd->name[i] == '\0' - */ - return qd->name[i] == '\0' ? 0 : -1; + unsigned int i = *matched; + + /* + * on-disk error, let's only BUG_ON in the debugging mode. + * otherwise, it will return 1 to just skip the invalid name + * and go on (in consideration of the lookup performance). + */ + DBG_BUGON(qd->name > qd->end); + + /* qd could not have trailing '\0' */ + /* However it is absolutely safe if < qd->end */ + while (qd->name + i < qd->end && qd->name[i] != '\0') { + if (qn->name[i] != qd->name[i]) { + *matched = i; + return qn->name[i] > qd->name[i] ? 1 : -1; } - return (qn->len > qd->len); - } - - if (qn->name[i] != qd->name[i]) { - *matched = i; - return qn->name[i] > qd->name[i] ? 1 : -1; + ++i; } - - ++i; - goto loop; + *matched = i; + /* See comments in __d_alloc on the terminating NUL character */ + return qn->name[i] == '\0' ? 0 : 1; } -static struct erofs_dirent *find_target_dirent( - struct qstr *name, - u8 *data, int maxsize) +#define nameoff_from_disk(off, sz) (le16_to_cpu(off) & ((sz) - 1)) + +static struct erofs_dirent *find_target_dirent(struct erofs_qstr *name, + u8 *data, + unsigned int dirblksize, + const int ndirents) { - unsigned int ndirents, head, back; + int head, back; unsigned int startprfx, endprfx; struct erofs_dirent *const de = (struct erofs_dirent *)data; - /* make sure that maxsize is valid */ - BUG_ON(maxsize < sizeof(struct erofs_dirent)); - - ndirents = le16_to_cpu(de->nameoff) / sizeof(*de); - - /* corrupted dir (may be unnecessary...) */ - BUG_ON(!ndirents); - - head = 0; + /* since the 1st dirent has been evaluated previously */ + head = 1; back = ndirents - 1; startprfx = endprfx = 0; while (head <= back) { - unsigned int mid = head + (back - head) / 2; - unsigned int nameoff = le16_to_cpu(de[mid].nameoff); + const int mid = head + (back - head) / 2; + const int nameoff = nameoff_from_disk(de[mid].nameoff, + dirblksize); unsigned int matched = min(startprfx, endprfx); - - struct qstr dname = QSTR_INIT(data + nameoff, - unlikely(mid >= ndirents - 1) ? - maxsize - nameoff : - le16_to_cpu(de[mid + 1].nameoff) - nameoff); + struct erofs_qstr dname = { + .name = data + nameoff, + .end = unlikely(mid >= ndirents - 1) ? + data + dirblksize : + data + nameoff_from_disk(de[mid + 1].nameoff, + dirblksize) + }; /* string comparison without already matched prefix */ int ret = dirnamecmp(name, &dname, &matched); - if (unlikely(!ret)) + if (unlikely(!ret)) { return de + mid; - else if (ret > 0) { + } else if (ret > 0) { head = mid + 1; startprfx = matched; - } else if (unlikely(mid < 1)) /* fix "mid" overflow */ - break; - else { + } else { back = mid - 1; endprfx = matched; } @@ -91,12 +94,12 @@ static struct erofs_dirent *find_target_dirent( return ERR_PTR(-ENOENT); } -static struct page *find_target_block_classic( - struct inode *dir, - struct qstr *name, int *_diff) +static struct page *find_target_block_classic(struct inode *dir, + struct erofs_qstr *name, + int *_ndirents) { unsigned int startprfx, endprfx; - unsigned int head, back; + int head, back; struct address_space *const mapping = dir->i_mapping; struct page *candidate = ERR_PTR(-ENOENT); @@ -105,89 +108,97 @@ static struct page *find_target_block_classic( back = inode_datablocks(dir) - 1; while (head <= back) { - unsigned int mid = head + (back - head) / 2; + const int mid = head + (back - head) / 2; struct page *page = read_mapping_page(mapping, mid, NULL); - if (IS_ERR(page)) { -exact_out: - if (!IS_ERR(candidate)) /* valid candidate */ - put_page(candidate); - return page; - } else { - int diff; - unsigned int ndirents, matched; - struct qstr dname; + if (!IS_ERR(page)) { struct erofs_dirent *de = kmap_atomic(page); - unsigned int nameoff = le16_to_cpu(de->nameoff); - - ndirents = nameoff / sizeof(*de); + const int nameoff = nameoff_from_disk(de->nameoff, + EROFS_BLKSIZ); + const int ndirents = nameoff / sizeof(*de); + int diff; + unsigned int matched; + struct erofs_qstr dname; - /* corrupted dir (should have one entry at least) */ - BUG_ON(!ndirents || nameoff > PAGE_SIZE); + if (unlikely(!ndirents)) { + DBG_BUGON(1); + kunmap_atomic(de); + put_page(page); + page = ERR_PTR(-EIO); + goto out; + } matched = min(startprfx, endprfx); dname.name = (u8 *)de + nameoff; - dname.len = ndirents == 1 ? - /* since the rest of the last page is 0 */ - EROFS_BLKSIZ - nameoff - : le16_to_cpu(de[1].nameoff) - nameoff; + if (ndirents == 1) + dname.end = (u8 *)de + EROFS_BLKSIZ; + else + dname.end = (u8 *)de + + nameoff_from_disk(de[1].nameoff, + EROFS_BLKSIZ); /* string comparison without already matched prefix */ diff = dirnamecmp(name, &dname, &matched); kunmap_atomic(de); if (unlikely(!diff)) { - *_diff = 0; - goto exact_out; + *_ndirents = 0; + goto out; } else if (diff > 0) { head = mid + 1; startprfx = matched; - if (likely(!IS_ERR(candidate))) + if (!IS_ERR(candidate)) put_page(candidate); candidate = page; + *_ndirents = ndirents; } else { put_page(page); - if (unlikely(mid < 1)) /* fix "mid" overflow */ - break; - back = mid - 1; endprfx = matched; } + continue; } +out: /* free if the candidate is valid */ + if (!IS_ERR(candidate)) + put_page(candidate); + return page; } - *_diff = 1; return candidate; } int erofs_namei(struct inode *dir, - struct qstr *name, - erofs_nid_t *nid, unsigned int *d_type) + struct qstr *name, + erofs_nid_t *nid, unsigned int *d_type) { - int diff; + int ndirents; struct page *page; - u8 *data; + void *data; struct erofs_dirent *de; + struct erofs_qstr qn; if (unlikely(!dir->i_size)) return -ENOENT; - diff = 1; - page = find_target_block_classic(dir, name, &diff); + qn.name = name->name; + qn.end = name->name + name->len; + + ndirents = 0; + page = find_target_block_classic(dir, &qn, &ndirents); - if (unlikely(IS_ERR(page))) + if (IS_ERR(page)) return PTR_ERR(page); data = kmap_atomic(page); /* the target page has been mapped */ - de = likely(diff) ? - /* since the rest of the last page is 0 */ - find_target_dirent(name, data, EROFS_BLKSIZ) : - (struct erofs_dirent *)data; + if (ndirents) + de = find_target_dirent(&qn, data, EROFS_BLKSIZ, ndirents); + else + de = (struct erofs_dirent *)data; - if (likely(!IS_ERR(de))) { + if (!IS_ERR(de)) { *nid = le64_to_cpu(de->nid); *d_type = de->file_type; } @@ -235,12 +246,9 @@ static struct dentry *erofs_lookup(struct inode *dir, const struct inode_operations erofs_dir_iops = { .lookup = erofs_lookup, -}; - -const struct inode_operations erofs_dir_xattr_iops = { - .lookup = erofs_lookup, #ifdef CONFIG_EROFS_FS_XATTR .listxattr = erofs_listxattr, #endif + .get_acl = erofs_get_acl, }; diff --git a/drivers/staging/erofs/super.c b/drivers/staging/erofs/super.c index 1c2eb69682ef..15c784fba879 100644 --- a/drivers/staging/erofs/super.c +++ b/drivers/staging/erofs/super.c @@ -16,6 +16,7 @@ #include <linux/parser.h> #include <linux/seq_file.h> #include "internal.h" +#include "xattr.h" #define CREATE_TRACE_POINTS #include <trace/events/erofs.h> @@ -397,6 +398,11 @@ static int erofs_read_super(struct super_block *sb, if (!silent) infoln("root inode @ nid %llu", ROOT_NID(sbi)); + if (test_opt(sbi, POSIX_ACL)) + sb->s_flags |= SB_POSIXACL; + else + sb->s_flags &= ~SB_POSIXACL; + #ifdef CONFIG_EROFS_FS_ZIP INIT_RADIX_TREE(&sbi->workstn_tree, GFP_ATOMIC); #endif @@ -420,13 +426,14 @@ static int erofs_read_super(struct super_block *sb, errln("rootino(nid %llu) is not a directory(i_mode %o)", ROOT_NID(sbi), inode->i_mode); err = -EINVAL; - goto err_isdir; + iput(inode); + goto err_iget; } sb->s_root = d_make_root(inode); if (sb->s_root == NULL) { err = -ENOMEM; - goto err_makeroot; + goto err_iget; } /* save the device name to sbi */ @@ -452,10 +459,6 @@ static int erofs_read_super(struct super_block *sb, */ err_devname: dput(sb->s_root); -err_makeroot: -err_isdir: - if (sb->s_root == NULL) - iput(inode); err_iget: #ifdef EROFS_FS_HAS_MANAGED_CACHE iput(sbi->managed_cache); @@ -493,7 +496,8 @@ static void erofs_put_super(struct super_block *sb) mutex_lock(&sbi->umount_mutex); #ifdef CONFIG_EROFS_FS_ZIP - erofs_workstation_cleanup_all(sb); + /* clean up the compression space of this sb */ + erofs_shrink_workstation(EROFS_SB(sb), ~0UL, true); #endif erofs_unregister_super(sb); @@ -537,12 +541,6 @@ static void erofs_kill_sb(struct super_block *sb) kill_block_super(sb); } -static struct shrinker erofs_shrinker_info = { - .scan_objects = erofs_shrink_scan, - .count_objects = erofs_shrink_count, - .seeks = DEFAULT_SEEKS, -}; - static struct file_system_type erofs_fs_type = { .owner = THIS_MODULE, .name = "erofs", @@ -653,6 +651,11 @@ static int erofs_remount(struct super_block *sb, int *flags, char *data) if (err) goto out; + if (test_opt(sbi, POSIX_ACL)) + sb->s_flags |= SB_POSIXACL; + else + sb->s_flags &= ~SB_POSIXACL; + *flags |= SB_RDONLY; return 0; out: diff --git a/drivers/staging/erofs/unzip_vle.c b/drivers/staging/erofs/unzip_vle.c index 4ac1099a39c6..02f34a83147d 100644 --- a/drivers/staging/erofs/unzip_vle.c +++ b/drivers/staging/erofs/unzip_vle.c @@ -107,15 +107,30 @@ enum z_erofs_vle_work_role { Z_EROFS_VLE_WORK_SECONDARY, Z_EROFS_VLE_WORK_PRIMARY, /* - * The current work has at least been linked with the following - * processed chained works, which means if the processing page - * is the tail partial page of the work, the current work can - * safely use the whole page, as illustrated below: - * +--------------+-------------------------------------------+ - * | tail page | head page (of the previous work) | - * +--------------+-------------------------------------------+ - * /\ which belongs to the current work - * [ (*) this page can be used for the current work itself. ] + * The current work was the tail of an exist chain, and the previous + * processed chained works are all decided to be hooked up to it. + * A new chain should be created for the remaining unprocessed works, + * therefore different from Z_EROFS_VLE_WORK_PRIMARY_FOLLOWED, + * the next work cannot reuse the whole page in the following scenario: + * ________________________________________________________________ + * | tail (partial) page | head (partial) page | + * | (belongs to the next work) | (belongs to the current work) | + * |_______PRIMARY_FOLLOWED_______|________PRIMARY_HOOKED___________| + */ + Z_EROFS_VLE_WORK_PRIMARY_HOOKED, + /* + * The current work has been linked with the processed chained works, + * and could be also linked with the potential remaining works, which + * means if the processing page is the tail partial page of the work, + * the current work can safely use the whole page (since the next work + * is under control) for in-place decompression, as illustrated below: + * ________________________________________________________________ + * | tail (partial) page | head (partial) page | + * | (of the current work) | (of the previous work) | + * | PRIMARY_FOLLOWED or | | + * |_____PRIMARY_HOOKED____|____________PRIMARY_FOLLOWED____________| + * + * [ (*) the above page can be used for the current work itself. ] */ Z_EROFS_VLE_WORK_PRIMARY_FOLLOWED, Z_EROFS_VLE_WORK_MAX @@ -238,14 +253,9 @@ int erofs_try_to_free_cached_page(struct address_space *mapping, { struct erofs_sb_info *const sbi = EROFS_SB(mapping->host->i_sb); const unsigned int clusterpages = erofs_clusterpages(sbi); - - struct z_erofs_vle_workgroup *grp; + struct z_erofs_vle_workgroup *const grp = (void *)page_private(page); int ret = 0; /* 0 - busy */ - /* prevent the workgroup from being freed */ - rcu_read_lock(); - grp = (void *)page_private(page); - if (erofs_workgroup_try_to_freeze(&grp->obj, 1)) { unsigned int i; @@ -257,12 +267,11 @@ int erofs_try_to_free_cached_page(struct address_space *mapping, } } erofs_workgroup_unfreeze(&grp->obj, 1); - } - rcu_read_unlock(); - if (ret) { - ClearPagePrivate(page); - put_page(page); + if (ret) { + ClearPagePrivate(page); + put_page(page); + } } return ret; } @@ -315,10 +324,10 @@ static int z_erofs_vle_work_add_page( return ret ? 0 : -EAGAIN; } -static inline bool try_to_claim_workgroup( - struct z_erofs_vle_workgroup *grp, - z_erofs_vle_owned_workgrp_t *owned_head, - bool *hosted) +static enum z_erofs_vle_work_role +try_to_claim_workgroup(struct z_erofs_vle_workgroup *grp, + z_erofs_vle_owned_workgrp_t *owned_head, + bool *hosted) { DBG_BUGON(*hosted == true); @@ -332,6 +341,9 @@ retry: *owned_head = &grp->next; *hosted = true; + /* lucky, I am the followee :) */ + return Z_EROFS_VLE_WORK_PRIMARY_FOLLOWED; + } else if (grp->next == Z_EROFS_VLE_WORKGRP_TAIL) { /* * type 2, link to the end of a existing open chain, @@ -341,12 +353,11 @@ retry: if (cmpxchg(&grp->next, Z_EROFS_VLE_WORKGRP_TAIL, *owned_head) != Z_EROFS_VLE_WORKGRP_TAIL) goto retry; - *owned_head = Z_EROFS_VLE_WORKGRP_TAIL; - } else - return false; /* :( better luck next time */ + return Z_EROFS_VLE_WORK_PRIMARY_HOOKED; + } - return true; /* lucky, I am the followee :) */ + return Z_EROFS_VLE_WORK_PRIMARY; /* :( better luck next time */ } struct z_erofs_vle_work_finder { @@ -424,12 +435,9 @@ z_erofs_vle_work_lookup(const struct z_erofs_vle_work_finder *f) *f->hosted = false; if (!primary) *f->role = Z_EROFS_VLE_WORK_SECONDARY; - /* claim the workgroup if possible */ - else if (try_to_claim_workgroup(grp, f->owned_head, f->hosted)) - *f->role = Z_EROFS_VLE_WORK_PRIMARY_FOLLOWED; - else - *f->role = Z_EROFS_VLE_WORK_PRIMARY; - + else /* claim the workgroup if possible */ + *f->role = try_to_claim_workgroup(grp, f->owned_head, + f->hosted); return work; } @@ -493,6 +501,9 @@ z_erofs_vle_work_register(const struct z_erofs_vle_work_finder *f, return work; } +#define builder_is_hooked(builder) \ + ((builder)->role >= Z_EROFS_VLE_WORK_PRIMARY_HOOKED) + #define builder_is_followed(builder) \ ((builder)->role >= Z_EROFS_VLE_WORK_PRIMARY_FOLLOWED) @@ -539,7 +550,7 @@ repeat: if (unlikely(work == ERR_PTR(-EAGAIN))) goto repeat; - if (unlikely(IS_ERR(work))) + if (IS_ERR(work)) return PTR_ERR(work); got_it: z_erofs_pagevec_ctor_init(&builder->vector, @@ -589,7 +600,7 @@ static void __z_erofs_vle_work_release(struct z_erofs_vle_workgroup *grp, erofs_workgroup_put(&grp->obj); } -void z_erofs_vle_work_release(struct z_erofs_vle_work *work) +static void z_erofs_vle_work_release(struct z_erofs_vle_work *work) { struct z_erofs_vle_workgroup *grp = z_erofs_vle_work_workgroup(work, true); @@ -636,7 +647,7 @@ struct z_erofs_vle_frontend { struct inode *const inode; struct z_erofs_vle_work_builder builder; - struct erofs_map_blocks_iter m_iter; + struct erofs_map_blocks map; z_erofs_vle_owned_workgrp_t owned_head; @@ -647,8 +658,9 @@ struct z_erofs_vle_frontend { #define VLE_FRONTEND_INIT(__i) { \ .inode = __i, \ - .m_iter = { \ - { .m_llen = 0, .m_plen = 0 }, \ + .map = { \ + .m_llen = 0, \ + .m_plen = 0, \ .mpage = NULL \ }, \ .builder = VLE_WORK_BUILDER_INIT(), \ @@ -681,12 +693,11 @@ static int z_erofs_do_read_page(struct z_erofs_vle_frontend *fe, { struct super_block *const sb = fe->inode->i_sb; struct erofs_sb_info *const sbi __maybe_unused = EROFS_SB(sb); - struct erofs_map_blocks_iter *const m = &fe->m_iter; - struct erofs_map_blocks *const map = &m->map; + struct erofs_map_blocks *const map = &fe->map; struct z_erofs_vle_work_builder *const builder = &fe->builder; const loff_t offset = page_offset(page); - bool tight = builder_is_followed(builder); + bool tight = builder_is_hooked(builder); struct z_erofs_vle_work *work = builder->work; enum z_erofs_cache_alloctype cache_strategy; @@ -704,8 +715,12 @@ repeat: /* lucky, within the range of the current map_blocks */ if (offset + cur >= map->m_la && - offset + cur < map->m_la + map->m_llen) + offset + cur < map->m_la + map->m_llen) { + /* didn't get a valid unzip work previously (very rare) */ + if (!builder->work) + goto restart_now; goto hitted; + } /* go ahead the next map_blocks */ debugln("%s: [out-of-range] pos %llu", __func__, offset + cur); @@ -715,10 +730,11 @@ repeat: map->m_la = offset + cur; map->m_llen = 0; - err = erofs_map_blocks_iter(fe->inode, map, &m->mpage, 0); + err = z_erofs_map_blocks_iter(fe->inode, map, 0); if (unlikely(err)) goto err_out; +restart_now: if (unlikely(!(map->m_flags & EROFS_MAP_MAPPED))) goto hitted; @@ -740,7 +756,7 @@ repeat: map->m_plen / PAGE_SIZE, cache_strategy, page_pool, GFP_KERNEL); - tight &= builder_is_followed(builder); + tight &= builder_is_hooked(builder); work = builder->work; hitted: cur = end - min_t(unsigned int, offset + end - map->m_la, end); @@ -755,6 +771,9 @@ hitted: (tight ? Z_EROFS_PAGE_TYPE_EXCLUSIVE : Z_EROFS_VLE_PAGE_TYPE_TAIL_SHARED)); + if (cur) + tight &= builder_is_followed(builder); + retry: err = z_erofs_vle_work_add_page(builder, page, page_type); /* should allocate an additional staging page for pagevec */ @@ -992,11 +1011,10 @@ repeat: if (llen > grp->llen) llen = grp->llen; - err = z_erofs_vle_unzip_fast_percpu(compressed_pages, - clusterpages, pages, llen, work->pageofs, - z_erofs_onlinepage_endio); + err = z_erofs_vle_unzip_fast_percpu(compressed_pages, clusterpages, + pages, llen, work->pageofs); if (err != -ENOTSUPP) - goto out_percpu; + goto out; if (sparsemem_pages >= nr_pages) goto skip_allocpage; @@ -1017,8 +1035,25 @@ skip_allocpage: erofs_vunmap(vout, nr_pages); out: + /* must handle all compressed pages before endding pages */ + for (i = 0; i < clusterpages; ++i) { + page = compressed_pages[i]; + +#ifdef EROFS_FS_HAS_MANAGED_CACHE + if (page->mapping == MNGD_MAPPING(sbi)) + continue; +#endif + /* recycle all individual staging pages */ + (void)z_erofs_gather_if_stagingpage(page_pool, page); + + WRITE_ONCE(compressed_pages[i], NULL); + } + for (i = 0; i < nr_pages; ++i) { page = pages[i]; + if (!page) + continue; + DBG_BUGON(!page->mapping); /* recycle all individual staging pages */ @@ -1031,20 +1066,6 @@ out: z_erofs_onlinepage_endio(page); } -out_percpu: - for (i = 0; i < clusterpages; ++i) { - page = compressed_pages[i]; - -#ifdef EROFS_FS_HAS_MANAGED_CACHE - if (page->mapping == MNGD_MAPPING(sbi)) - continue; -#endif - /* recycle all individual staging pages */ - (void)z_erofs_gather_if_stagingpage(page_pool, page); - - WRITE_ONCE(compressed_pages[i], NULL); - } - if (pages == z_pagemap_global) mutex_unlock(&z_pagemap_global_lock); else if (unlikely(pages != pages_onstack)) @@ -1484,8 +1505,8 @@ static int z_erofs_vle_normalaccess_readpage(struct file *file, z_erofs_submit_and_unzip(&f, &pagepool, true); out: - if (f.m_iter.mpage) - put_page(f.m_iter.mpage); + if (f.map.mpage) + put_page(f.map.mpage); /* clean up the remaining free pages */ put_pages_list(&pagepool); @@ -1555,8 +1576,8 @@ static int z_erofs_vle_normalaccess_readpages(struct file *filp, z_erofs_submit_and_unzip(&f, &pagepool, sync); - if (f.m_iter.mpage) - put_page(f.m_iter.mpage); + if (f.map.mpage) + put_page(f.map.mpage); /* clean up the remaining free pages */ put_pages_list(&pagepool); @@ -1701,14 +1722,14 @@ vle_get_logical_extent_head(const struct vle_map_blocks_iter_ctx *ctx, int z_erofs_map_blocks_iter(struct inode *inode, struct erofs_map_blocks *map, - struct page **mpage_ret, int flags) + int flags) { void *kaddr; const struct vle_map_blocks_iter_ctx ctx = { .inode = inode, .sb = inode->i_sb, .clusterbits = EROFS_I_SB(inode)->clusterbits, - .mpage_ret = mpage_ret, + .mpage_ret = &map->mpage, .kaddr_ret = &kaddr }; const unsigned int clustersize = 1 << ctx.clusterbits; @@ -1722,7 +1743,7 @@ int z_erofs_map_blocks_iter(struct inode *inode, /* initialize `pblk' to keep gcc from printing foolish warnings */ erofs_blk_t mblk, pblk = 0; - struct page *mpage = *mpage_ret; + struct page *mpage = map->mpage; struct z_erofs_vle_decompressed_index *di; unsigned int cluster_type, logical_cluster_ofs; int err = 0; @@ -1758,7 +1779,7 @@ int z_erofs_map_blocks_iter(struct inode *inode, err = PTR_ERR(mpage); goto out; } - *mpage_ret = mpage; + map->mpage = mpage; } else { lock_page(mpage); DBG_BUGON(!PageUptodate(mpage)); @@ -1818,7 +1839,7 @@ int z_erofs_map_blocks_iter(struct inode *inode, /* get the correspoinding first chunk */ err = vle_get_logical_extent_head(&ctx, lcn, &ofs, &pblk, &map->m_flags); - mpage = *mpage_ret; + mpage = map->mpage; if (unlikely(err)) { if (mpage) diff --git a/drivers/staging/erofs/unzip_vle.h b/drivers/staging/erofs/unzip_vle.h index 5a4e1b62c0d1..517e5ce8c5e9 100644 --- a/drivers/staging/erofs/unzip_vle.h +++ b/drivers/staging/erofs/unzip_vle.h @@ -212,18 +212,17 @@ static inline void z_erofs_onlinepage_endio(struct page *page) #define Z_EROFS_VLE_VMAP_GLOBAL_PAGES 2048 /* unzip_vle_lz4.c */ -extern int z_erofs_vle_plain_copy(struct page **compressed_pages, - unsigned clusterpages, struct page **pages, - unsigned nr_pages, unsigned short pageofs); - -extern int z_erofs_vle_unzip_fast_percpu(struct page **compressed_pages, - unsigned clusterpages, struct page **pages, - unsigned outlen, unsigned short pageofs, - void (*endio)(struct page *)); - -extern int z_erofs_vle_unzip_vmap(struct page **compressed_pages, - unsigned clusterpages, void *vaddr, unsigned llen, - unsigned short pageofs, bool overlapped); +int z_erofs_vle_plain_copy(struct page **compressed_pages, + unsigned int clusterpages, struct page **pages, + unsigned int nr_pages, unsigned short pageofs); +int z_erofs_vle_unzip_fast_percpu(struct page **compressed_pages, + unsigned int clusterpages, + struct page **pages, unsigned int outlen, + unsigned short pageofs); +int z_erofs_vle_unzip_vmap(struct page **compressed_pages, + unsigned int clusterpages, + void *vaddr, unsigned int llen, + unsigned short pageofs, bool overlapped); #endif diff --git a/drivers/staging/erofs/unzip_vle_lz4.c b/drivers/staging/erofs/unzip_vle_lz4.c index 52797bd89da1..48b263a2731a 100644 --- a/drivers/staging/erofs/unzip_vle_lz4.c +++ b/drivers/staging/erofs/unzip_vle_lz4.c @@ -13,7 +13,7 @@ #include "unzip_vle.h" #include <linux/lz4.h> -int z_erofs_unzip_lz4(void *in, void *out, size_t inlen, size_t outlen) +static int z_erofs_unzip_lz4(void *in, void *out, size_t inlen, size_t outlen) { int ret = LZ4_decompress_safe_partial(in, out, inlen, outlen, outlen); @@ -125,8 +125,7 @@ int z_erofs_vle_unzip_fast_percpu(struct page **compressed_pages, unsigned int clusterpages, struct page **pages, unsigned int outlen, - unsigned short pageofs, - void (*endio)(struct page *)) + unsigned short pageofs) { void *vin, *vout; unsigned int nr_pages, i, j; @@ -148,19 +147,16 @@ int z_erofs_vle_unzip_fast_percpu(struct page **compressed_pages, ret = z_erofs_unzip_lz4(vin, vout + pageofs, clusterpages * PAGE_SIZE, outlen); - if (ret >= 0) { - outlen = ret; - ret = 0; - } + if (ret < 0) + goto out; + ret = 0; for (i = 0; i < nr_pages; ++i) { j = min((unsigned int)PAGE_SIZE - pageofs, outlen); if (pages[i]) { - if (ret < 0) { - SetPageError(pages[i]); - } else if (clusterpages == 1 && - pages[i] == compressed_pages[0]) { + if (clusterpages == 1 && + pages[i] == compressed_pages[0]) { memcpy(vin + pageofs, vout + pageofs, j); } else { void *dst = kmap_atomic(pages[i]); @@ -168,12 +164,13 @@ int z_erofs_vle_unzip_fast_percpu(struct page **compressed_pages, memcpy(dst + pageofs, vout + pageofs, j); kunmap_atomic(dst); } - endio(pages[i]); } vout += PAGE_SIZE; outlen -= j; pageofs = 0; } + +out: preempt_enable(); if (clusterpages == 1) diff --git a/drivers/staging/erofs/utils.c b/drivers/staging/erofs/utils.c index b535898ca753..5f61f99f4c10 100644 --- a/drivers/staging/erofs/utils.c +++ b/drivers/staging/erofs/utils.c @@ -31,13 +31,32 @@ struct page *erofs_allocpage(struct list_head *pool, gfp_t gfp) static atomic_long_t erofs_global_shrink_cnt; #ifdef CONFIG_EROFS_FS_ZIP +#define __erofs_workgroup_get(grp) atomic_inc(&(grp)->refcount) +#define __erofs_workgroup_put(grp) atomic_dec(&(grp)->refcount) -struct erofs_workgroup *erofs_find_workgroup( - struct super_block *sb, pgoff_t index, bool *tag) +static int erofs_workgroup_get(struct erofs_workgroup *grp) +{ + int o; + +repeat: + o = erofs_wait_on_workgroup_freezed(grp); + if (unlikely(o <= 0)) + return -1; + + if (unlikely(atomic_cmpxchg(&grp->refcount, o, o + 1) != o)) + goto repeat; + + /* decrease refcount paired by erofs_workgroup_put */ + if (unlikely(o == 1)) + atomic_long_dec(&erofs_global_shrink_cnt); + return 0; +} + +struct erofs_workgroup *erofs_find_workgroup(struct super_block *sb, + pgoff_t index, bool *tag) { struct erofs_sb_info *sbi = EROFS_SB(sb); struct erofs_workgroup *grp; - int oldcount; repeat: rcu_read_lock(); @@ -46,15 +65,12 @@ repeat: *tag = xa_pointer_tag(grp); grp = xa_untag_pointer(grp); - if (erofs_workgroup_get(grp, &oldcount)) { + if (erofs_workgroup_get(grp)) { /* prefer to relax rcu read side */ rcu_read_unlock(); goto repeat; } - /* decrease refcount added by erofs_workgroup_put */ - if (unlikely(oldcount == 1)) - atomic_long_dec(&erofs_global_shrink_cnt); DBG_BUGON(index != grp->index); } rcu_read_unlock(); @@ -104,8 +120,6 @@ int erofs_register_workgroup(struct super_block *sb, return err; } -extern void erofs_workgroup_free_rcu(struct erofs_workgroup *grp); - static void __erofs_workgroup_free(struct erofs_workgroup *grp) { atomic_long_dec(&erofs_global_shrink_cnt); @@ -131,9 +145,9 @@ static void erofs_workgroup_unfreeze_final(struct erofs_workgroup *grp) __erofs_workgroup_free(grp); } -bool erofs_try_to_release_workgroup(struct erofs_sb_info *sbi, - struct erofs_workgroup *grp, - bool cleanup) +static bool erofs_try_to_release_workgroup(struct erofs_sb_info *sbi, + struct erofs_workgroup *grp, + bool cleanup) { /* * for managed cache enabled, the refcount of workgroups @@ -172,9 +186,9 @@ bool erofs_try_to_release_workgroup(struct erofs_sb_info *sbi, #else /* for nocache case, no customized reclaim path at all */ -bool erofs_try_to_release_workgroup(struct erofs_sb_info *sbi, - struct erofs_workgroup *grp, - bool cleanup) +static bool erofs_try_to_release_workgroup(struct erofs_sb_info *sbi, + struct erofs_workgroup *grp, + bool cleanup) { int cnt = atomic_read(&grp->refcount); @@ -256,14 +270,14 @@ void erofs_unregister_super(struct super_block *sb) spin_unlock(&erofs_sb_list_lock); } -unsigned long erofs_shrink_count(struct shrinker *shrink, - struct shrink_control *sc) +static unsigned long erofs_shrink_count(struct shrinker *shrink, + struct shrink_control *sc) { return atomic_long_read(&erofs_global_shrink_cnt); } -unsigned long erofs_shrink_scan(struct shrinker *shrink, - struct shrink_control *sc) +static unsigned long erofs_shrink_scan(struct shrinker *shrink, + struct shrink_control *sc) { struct erofs_sb_info *sbi; struct list_head *p; @@ -319,3 +333,9 @@ unsigned long erofs_shrink_scan(struct shrinker *shrink, return freed; } +struct shrinker erofs_shrinker_info = { + .scan_objects = erofs_shrink_scan, + .count_objects = erofs_shrink_count, + .seeks = DEFAULT_SEEKS, +}; + diff --git a/drivers/staging/erofs/xattr.c b/drivers/staging/erofs/xattr.c index 80dca6a4adbe..f716ab0446e5 100644 --- a/drivers/staging/erofs/xattr.c +++ b/drivers/staging/erofs/xattr.c @@ -44,19 +44,48 @@ static inline void xattr_iter_end_final(struct xattr_iter *it) static int init_inode_xattrs(struct inode *inode) { + struct erofs_vnode *const vi = EROFS_V(inode); struct xattr_iter it; unsigned int i; struct erofs_xattr_ibody_header *ih; struct super_block *sb; struct erofs_sb_info *sbi; - struct erofs_vnode *vi; bool atomic_map; + int ret = 0; - if (likely(inode_has_inited_xattr(inode))) + /* the most case is that xattrs of this inode are initialized. */ + if (test_bit(EROFS_V_EA_INITED_BIT, &vi->flags)) return 0; - vi = EROFS_V(inode); - BUG_ON(!vi->xattr_isize); + if (wait_on_bit_lock(&vi->flags, EROFS_V_BL_XATTR_BIT, TASK_KILLABLE)) + return -ERESTARTSYS; + + /* someone has initialized xattrs for us? */ + if (test_bit(EROFS_V_EA_INITED_BIT, &vi->flags)) + goto out_unlock; + + /* + * bypass all xattr operations if ->xattr_isize is not greater than + * sizeof(struct erofs_xattr_ibody_header), in detail: + * 1) it is not enough to contain erofs_xattr_ibody_header then + * ->xattr_isize should be 0 (it means no xattr); + * 2) it is just to contain erofs_xattr_ibody_header, which is on-disk + * undefined right now (maybe use later with some new sb feature). + */ + if (vi->xattr_isize == sizeof(struct erofs_xattr_ibody_header)) { + errln("xattr_isize %d of nid %llu is not supported yet", + vi->xattr_isize, vi->nid); + ret = -ENOTSUPP; + goto out_unlock; + } else if (vi->xattr_isize < sizeof(struct erofs_xattr_ibody_header)) { + if (unlikely(vi->xattr_isize)) { + DBG_BUGON(1); + ret = -EIO; + goto out_unlock; /* xattr ondisk layout error */ + } + ret = -ENOATTR; + goto out_unlock; + } sb = inode->i_sb; sbi = EROFS_SB(sb); @@ -64,8 +93,10 @@ static int init_inode_xattrs(struct inode *inode) it.ofs = erofs_blkoff(iloc(sbi, vi->nid) + vi->inode_isize); it.page = erofs_get_inline_page(inode, it.blkaddr); - if (IS_ERR(it.page)) - return PTR_ERR(it.page); + if (IS_ERR(it.page)) { + ret = PTR_ERR(it.page); + goto out_unlock; + } /* read in shared xattr array (non-atomic, see kmalloc below) */ it.kaddr = kmap(it.page); @@ -78,7 +109,8 @@ static int init_inode_xattrs(struct inode *inode) sizeof(uint), GFP_KERNEL); if (vi->xattr_shared_xattrs == NULL) { xattr_iter_end(&it, atomic_map); - return -ENOMEM; + ret = -ENOMEM; + goto out_unlock; } /* let's skip ibody header */ @@ -92,8 +124,12 @@ static int init_inode_xattrs(struct inode *inode) it.page = erofs_get_meta_page(sb, ++it.blkaddr, S_ISDIR(inode->i_mode)); - if (IS_ERR(it.page)) - return PTR_ERR(it.page); + if (IS_ERR(it.page)) { + kfree(vi->xattr_shared_xattrs); + vi->xattr_shared_xattrs = NULL; + ret = PTR_ERR(it.page); + goto out_unlock; + } it.kaddr = kmap_atomic(it.page); atomic_map = true; @@ -105,8 +141,11 @@ static int init_inode_xattrs(struct inode *inode) } xattr_iter_end(&it, atomic_map); - inode_set_inited_xattr(inode); - return 0; + set_bit(EROFS_V_EA_INITED_BIT, &vi->flags); + +out_unlock: + clear_and_wake_up_bit(EROFS_V_BL_XATTR_BIT, &vi->flags); + return ret; } /* @@ -117,10 +156,12 @@ static int init_inode_xattrs(struct inode *inode) * and need to be handled */ struct xattr_iter_handlers { - int (*entry)(struct xattr_iter *, struct erofs_xattr_entry *); - int (*name)(struct xattr_iter *, unsigned int, char *, unsigned int); - int (*alloc_buffer)(struct xattr_iter *, unsigned int); - void (*value)(struct xattr_iter *, unsigned int, char *, unsigned int); + int (*entry)(struct xattr_iter *_it, struct erofs_xattr_entry *entry); + int (*name)(struct xattr_iter *_it, unsigned int processed, char *buf, + unsigned int len); + int (*alloc_buffer)(struct xattr_iter *_it, unsigned int value_sz); + void (*value)(struct xattr_iter *_it, unsigned int processed, char *buf, + unsigned int len); }; static inline int xattr_iter_fixup(struct xattr_iter *it) @@ -422,7 +463,6 @@ static int erofs_xattr_generic_get(const struct xattr_handler *handler, struct dentry *unused, struct inode *inode, const char *name, void *buffer, size_t size) { - struct erofs_vnode *const vi = EROFS_V(inode); struct erofs_sb_info *const sbi = EROFS_I_SB(inode); switch (handler->flags) { @@ -440,9 +480,6 @@ static int erofs_xattr_generic_get(const struct xattr_handler *handler, return -EINVAL; } - if (!vi->xattr_isize) - return -ENOATTR; - return erofs_getxattr(inode, handler->flags, name, buffer, size); } @@ -503,8 +540,7 @@ static int xattr_entrylist(struct xattr_iter *_it, if (h == NULL || (h->list != NULL && !h->list(it->dentry))) return 1; - /* Note that at least one of 'prefix' and 'name' should be non-NULL */ - prefix = h->prefix != NULL ? h->prefix : h->name; + prefix = xattr_prefix(h); prefix_len = strlen(prefix); if (it->buffer == NULL) { @@ -627,3 +663,40 @@ ssize_t erofs_listxattr(struct dentry *dentry, return shared_listxattr(&it); } +#ifdef CONFIG_EROFS_FS_POSIX_ACL +struct posix_acl *erofs_get_acl(struct inode *inode, int type) +{ + struct posix_acl *acl; + int prefix, rc; + char *value = NULL; + + switch (type) { + case ACL_TYPE_ACCESS: + prefix = EROFS_XATTR_INDEX_POSIX_ACL_ACCESS; + break; + case ACL_TYPE_DEFAULT: + prefix = EROFS_XATTR_INDEX_POSIX_ACL_DEFAULT; + break; + default: + return ERR_PTR(-EINVAL); + } + + rc = erofs_getxattr(inode, prefix, "", NULL, 0); + if (rc > 0) { + value = kmalloc(rc, GFP_KERNEL); + if (!value) + return ERR_PTR(-ENOMEM); + rc = erofs_getxattr(inode, prefix, "", value, rc); + } + + if (rc == -ENOATTR) + acl = NULL; + else if (rc < 0) + acl = ERR_PTR(rc); + else + acl = posix_acl_from_xattr(&init_user_ns, value, rc); + kfree(value); + return acl; +} +#endif + diff --git a/drivers/staging/erofs/xattr.h b/drivers/staging/erofs/xattr.h index 0c7379282fc5..35ba5ac2139a 100644 --- a/drivers/staging/erofs/xattr.h +++ b/drivers/staging/erofs/xattr.h @@ -68,9 +68,7 @@ static const struct xattr_handler *xattr_handler_map[] = { } #ifdef CONFIG_EROFS_FS_XATTR - -extern const struct inode_operations erofs_generic_xattr_iops; -extern const struct inode_operations erofs_dir_xattr_iops; +extern const struct xattr_handler *erofs_xattr_handlers[]; int erofs_getxattr(struct inode *, int, const char *, void *, size_t); ssize_t erofs_listxattr(struct dentry *, char *, size_t); @@ -89,5 +87,11 @@ static ssize_t __maybe_unused erofs_listxattr(struct dentry *dentry, } #endif +#ifdef CONFIG_EROFS_FS_POSIX_ACL +struct posix_acl *erofs_get_acl(struct inode *inode, int type); +#else +#define erofs_get_acl (NULL) +#endif + #endif diff --git a/drivers/staging/fbtft/fb_agm1264k-fl.c b/drivers/staging/fbtft/fb_agm1264k-fl.c index f6f30f5bf15a..8f27bd8da17d 100644 --- a/drivers/staging/fbtft/fb_agm1264k-fl.c +++ b/drivers/staging/fbtft/fb_agm1264k-fl.c @@ -8,7 +8,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include <linux/slab.h> @@ -79,14 +79,14 @@ static int init_display(struct fbtft_par *par) static void reset(struct fbtft_par *par) { - if (par->gpio.reset == -1) + if (!par->gpio.reset) return; dev_dbg(par->info->device, "%s()\n", __func__); - gpio_set_value(par->gpio.reset, 0); + gpiod_set_value(par->gpio.reset, 0); udelay(20); - gpio_set_value(par->gpio.reset, 1); + gpiod_set_value(par->gpio.reset, 1); mdelay(120); } @@ -98,30 +98,30 @@ static int verify_gpios(struct fbtft_par *par) dev_dbg(par->info->device, "%s()\n", __func__); - if (par->EPIN < 0) { + if (!par->EPIN) { dev_err(par->info->device, "Missing info about 'wr' (aka E) gpio. Aborting.\n"); return -EINVAL; } for (i = 0; i < 8; ++i) { - if (par->gpio.db[i] < 0) { + if (!par->gpio.db[i]) { dev_err(par->info->device, "Missing info about 'db[%i]' gpio. Aborting.\n", i); return -EINVAL; } } - if (par->CS0 < 0) { + if (!par->CS0) { dev_err(par->info->device, "Missing info about 'cs0' gpio. Aborting.\n"); return -EINVAL; } - if (par->CS1 < 0) { + if (!par->CS1) { dev_err(par->info->device, "Missing info about 'cs1' gpio. Aborting.\n"); return -EINVAL; } - if (par->RW < 0) { + if (!par->RW) { dev_err(par->info->device, "Missing info about 'rw' gpio. Aborting.\n"); return -EINVAL; @@ -139,22 +139,22 @@ request_gpios_match(struct fbtft_par *par, const struct fbtft_gpio *gpio) if (strcasecmp(gpio->name, "wr") == 0) { /* left ks0108 E pin */ par->EPIN = gpio->gpio; - return GPIOF_OUT_INIT_LOW; + return GPIOD_OUT_LOW; } else if (strcasecmp(gpio->name, "cs0") == 0) { /* left ks0108 controller pin */ par->CS0 = gpio->gpio; - return GPIOF_OUT_INIT_HIGH; + return GPIOD_OUT_HIGH; } else if (strcasecmp(gpio->name, "cs1") == 0) { /* right ks0108 controller pin */ par->CS1 = gpio->gpio; - return GPIOF_OUT_INIT_HIGH; + return GPIOD_OUT_HIGH; } /* if write (rw = 0) e(1->0) perform write */ /* if read (rw = 1) e(0->1) set data on D0-7*/ else if (strcasecmp(gpio->name, "rw") == 0) { par->RW = gpio->gpio; - return GPIOF_OUT_INIT_LOW; + return GPIOD_OUT_LOW; } return FBTFT_GPIO_NO_MATCH; @@ -194,15 +194,15 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...) /* select chip */ if (*buf) { /* cs1 */ - gpio_set_value(par->CS0, 1); - gpio_set_value(par->CS1, 0); + gpiod_set_value(par->CS0, 1); + gpiod_set_value(par->CS1, 0); } else { /* cs0 */ - gpio_set_value(par->CS0, 0); - gpio_set_value(par->CS1, 1); + gpiod_set_value(par->CS0, 0); + gpiod_set_value(par->CS1, 1); } - gpio_set_value(par->RS, 0); /* RS->0 (command mode) */ + gpiod_set_value(par->RS, 0); /* RS->0 (command mode) */ len--; if (len) { @@ -364,7 +364,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) write_reg(par, 0x00, (0x17 << 3) | (u8)y); /* write bitmap */ - gpio_set_value(par->RS, 1); /* RS->1 (data mode) */ + gpiod_set_value(par->RS, 1); /* RS->1 (data mode) */ ret = par->fbtftops.write(par, buf, len); if (ret < 0) dev_err(par->info->device, @@ -387,7 +387,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) write_reg(par, 0x01, (0x17 << 3) | (u8)y); /* write bitmap */ - gpio_set_value(par->RS, 1); /* RS->1 (data mode) */ + gpiod_set_value(par->RS, 1); /* RS->1 (data mode) */ par->fbtftops.write(par, buf, len); if (ret < 0) dev_err(par->info->device, @@ -397,8 +397,8 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) } kfree(convert_buf); - gpio_set_value(par->CS0, 1); - gpio_set_value(par->CS1, 1); + gpiod_set_value(par->CS0, 1); + gpiod_set_value(par->CS1, 1); return ret; } @@ -408,7 +408,7 @@ static int write(struct fbtft_par *par, void *buf, size_t len) fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len, "%s(len=%d): ", __func__, len); - gpio_set_value(par->RW, 0); /* set write mode */ + gpiod_set_value(par->RW, 0); /* set write mode */ while (len--) { u8 i, data; @@ -417,12 +417,12 @@ static int write(struct fbtft_par *par, void *buf, size_t len) /* set data bus */ for (i = 0; i < 8; ++i) - gpio_set_value(par->gpio.db[i], data & (1 << i)); + gpiod_set_value(par->gpio.db[i], data & (1 << i)); /* set E */ - gpio_set_value(par->EPIN, 1); + gpiod_set_value(par->EPIN, 1); udelay(5); /* unset E - write */ - gpio_set_value(par->EPIN, 0); + gpiod_set_value(par->EPIN, 0); udelay(1); } diff --git a/drivers/staging/fbtft/fb_bd663474.c b/drivers/staging/fbtft/fb_bd663474.c index a58c514f4721..b6c6d66e4eb1 100644 --- a/drivers/staging/fbtft/fb_bd663474.c +++ b/drivers/staging/fbtft/fb_bd663474.c @@ -12,7 +12,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include "fbtft.h" @@ -24,8 +24,8 @@ static int init_display(struct fbtft_par *par) { - if (par->gpio.cs != -1) - gpio_set_value(par->gpio.cs, 0); /* Activate chip */ + if (!par->gpio.cs) + gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ par->fbtftops.reset(par); diff --git a/drivers/staging/fbtft/fb_ili9163.c b/drivers/staging/fbtft/fb_ili9163.c index 86e140244aab..d609a2b67db9 100644 --- a/drivers/staging/fbtft/fb_ili9163.c +++ b/drivers/staging/fbtft/fb_ili9163.c @@ -11,7 +11,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include <video/mipi_display.h> @@ -77,8 +77,8 @@ static int init_display(struct fbtft_par *par) { par->fbtftops.reset(par); - if (par->gpio.cs != -1) - gpio_set_value(par->gpio.cs, 0); /* Activate chip */ + if (!par->gpio.cs) + gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ write_reg(par, MIPI_DCS_SOFT_RESET); /* software reset */ mdelay(500); diff --git a/drivers/staging/fbtft/fb_ili9320.c b/drivers/staging/fbtft/fb_ili9320.c index 740c0acbecd8..ea6e001288ce 100644 --- a/drivers/staging/fbtft/fb_ili9320.c +++ b/drivers/staging/fbtft/fb_ili9320.c @@ -8,7 +8,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/spi/spi.h> #include <linux/delay.h> diff --git a/drivers/staging/fbtft/fb_ili9325.c b/drivers/staging/fbtft/fb_ili9325.c index 2cf75f2e03e2..b090e7ab6fdd 100644 --- a/drivers/staging/fbtft/fb_ili9325.c +++ b/drivers/staging/fbtft/fb_ili9325.c @@ -10,7 +10,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include "fbtft.h" @@ -85,8 +85,8 @@ static int init_display(struct fbtft_par *par) { par->fbtftops.reset(par); - if (par->gpio.cs != -1) - gpio_set_value(par->gpio.cs, 0); /* Activate chip */ + if (!par->gpio.cs) + gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ bt &= 0x07; vc &= 0x07; diff --git a/drivers/staging/fbtft/fb_ili9340.c b/drivers/staging/fbtft/fb_ili9340.c index 430f21e50f4d..415183c7054a 100644 --- a/drivers/staging/fbtft/fb_ili9340.c +++ b/drivers/staging/fbtft/fb_ili9340.c @@ -8,7 +8,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include <video/mipi_display.h> diff --git a/drivers/staging/fbtft/fb_pcd8544.c b/drivers/staging/fbtft/fb_pcd8544.c index 32172f8f79f0..ad49973ad594 100644 --- a/drivers/staging/fbtft/fb_pcd8544.c +++ b/drivers/staging/fbtft/fb_pcd8544.c @@ -11,7 +11,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/spi/spi.h> #include <linux/delay.h> @@ -119,7 +119,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) } /* Write data */ - gpio_set_value(par->gpio.dc, 1); + gpiod_set_value(par->gpio.dc, 1); ret = par->fbtftops.write(par, par->txbuf.buf, 6 * 84); if (ret < 0) dev_err(par->info->device, "write failed and returned: %d\n", diff --git a/drivers/staging/fbtft/fb_ra8875.c b/drivers/staging/fbtft/fb_ra8875.c index 5d3b76ca74d8..70b37fc7fb66 100644 --- a/drivers/staging/fbtft/fb_ra8875.c +++ b/drivers/staging/fbtft/fb_ra8875.c @@ -9,7 +9,7 @@ #include <linux/init.h> #include <linux/delay.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include "fbtft.h" #define DRVNAME "fb_ra8875" @@ -39,7 +39,7 @@ static int write_spi(struct fbtft_par *par, void *buf, size_t len) static int init_display(struct fbtft_par *par) { - gpio_set_value(par->gpio.dc, 1); + gpiod_set_value(par->gpio.dc, 1); fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__); diff --git a/drivers/staging/fbtft/fb_s6d1121.c b/drivers/staging/fbtft/fb_s6d1121.c index aa716f33420a..b3d0701880fe 100644 --- a/drivers/staging/fbtft/fb_s6d1121.c +++ b/drivers/staging/fbtft/fb_s6d1121.c @@ -12,7 +12,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include "fbtft.h" @@ -29,8 +29,8 @@ static int init_display(struct fbtft_par *par) { par->fbtftops.reset(par); - if (par->gpio.cs != -1) - gpio_set_value(par->gpio.cs, 0); /* Activate chip */ + if (!par->gpio.cs) + gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ /* Initialization sequence from Lib_UTFT */ diff --git a/drivers/staging/fbtft/fb_sh1106.c b/drivers/staging/fbtft/fb_sh1106.c index 00096f8d249a..6f7249493ea3 100644 --- a/drivers/staging/fbtft/fb_sh1106.c +++ b/drivers/staging/fbtft/fb_sh1106.c @@ -9,7 +9,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include "fbtft.h" diff --git a/drivers/staging/fbtft/fb_ssd1289.c b/drivers/staging/fbtft/fb_ssd1289.c index c9b18b3ba4ab..bbf75f795234 100644 --- a/drivers/staging/fbtft/fb_ssd1289.c +++ b/drivers/staging/fbtft/fb_ssd1289.c @@ -10,7 +10,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include "fbtft.h" @@ -28,8 +28,8 @@ static int init_display(struct fbtft_par *par) { par->fbtftops.reset(par); - if (par->gpio.cs != -1) - gpio_set_value(par->gpio.cs, 0); /* Activate chip */ + if (!par->gpio.cs) + gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ write_reg(par, 0x00, 0x0001); write_reg(par, 0x03, 0xA8A4); diff --git a/drivers/staging/fbtft/fb_ssd1305.c b/drivers/staging/fbtft/fb_ssd1305.c index 3515888d94c9..020fe48fed0b 100644 --- a/drivers/staging/fbtft/fb_ssd1305.c +++ b/drivers/staging/fbtft/fb_ssd1305.c @@ -8,7 +8,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include "fbtft.h" @@ -168,7 +168,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) } /* Write data */ - gpio_set_value(par->gpio.dc, 1); + gpiod_set_value(par->gpio.dc, 1); ret = par->fbtftops.write(par, par->txbuf.buf, par->info->var.xres * par->info->var.yres / 8); diff --git a/drivers/staging/fbtft/fb_ssd1306.c b/drivers/staging/fbtft/fb_ssd1306.c index 50172ddd94ae..d7c5e2e0eee9 100644 --- a/drivers/staging/fbtft/fb_ssd1306.c +++ b/drivers/staging/fbtft/fb_ssd1306.c @@ -8,7 +8,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include "fbtft.h" @@ -190,7 +190,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) } /* Write data */ - gpio_set_value(par->gpio.dc, 1); + gpiod_set_value(par->gpio.dc, 1); ret = par->fbtftops.write(par, par->txbuf.buf, xres * yres / 8); if (ret < 0) dev_err(par->info->device, "write failed and returned: %d\n", diff --git a/drivers/staging/fbtft/fb_ssd1325.c b/drivers/staging/fbtft/fb_ssd1325.c index f974f7fc4d79..8a3140d41d8b 100644 --- a/drivers/staging/fbtft/fb_ssd1325.c +++ b/drivers/staging/fbtft/fb_ssd1325.c @@ -6,7 +6,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include "fbtft.h" @@ -35,7 +35,7 @@ static int init_display(struct fbtft_par *par) { par->fbtftops.reset(par); - gpio_set_value(par->gpio.cs, 0); + gpiod_set_value(par->gpio.cs, 0); write_reg(par, 0xb3); write_reg(par, 0xf0); @@ -155,7 +155,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) } } - gpio_set_value(par->gpio.dc, 1); + gpiod_set_value(par->gpio.dc, 1); /* Write data */ ret = par->fbtftops.write(par, par->txbuf.buf, diff --git a/drivers/staging/fbtft/fb_ssd1331.c b/drivers/staging/fbtft/fb_ssd1331.c index 0b614c84822e..9f54fe28d511 100644 --- a/drivers/staging/fbtft/fb_ssd1331.c +++ b/drivers/staging/fbtft/fb_ssd1331.c @@ -2,7 +2,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/spi/spi.h> #include <linux/delay.h> @@ -80,8 +80,8 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...) va_start(args, len); *buf = (u8)va_arg(args, unsigned int); - if (par->gpio.dc != -1) - gpio_set_value(par->gpio.dc, 0); + if (!par->gpio.dc) + gpiod_set_value(par->gpio.dc, 0); ret = par->fbtftops.write(par, par->buf, sizeof(u8)); if (ret < 0) { va_end(args); @@ -103,8 +103,8 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...) return; } } - if (par->gpio.dc != -1) - gpio_set_value(par->gpio.dc, 1); + if (!par->gpio.dc) + gpiod_set_value(par->gpio.dc, 1); va_end(args); } diff --git a/drivers/staging/fbtft/fb_ssd1351.c b/drivers/staging/fbtft/fb_ssd1351.c index 3da091b4d297..9ac78ce30619 100644 --- a/drivers/staging/fbtft/fb_ssd1351.c +++ b/drivers/staging/fbtft/fb_ssd1351.c @@ -2,7 +2,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/spi/spi.h> #include <linux/delay.h> @@ -164,7 +164,7 @@ static int set_gamma(struct fbtft_par *par, u32 *curves) static int blank(struct fbtft_par *par, bool on) { fbtft_par_dbg(DEBUG_BLANK, par, "(%s=%s)\n", - __func__, on ? "true" : "false"); + __func__, on ? "true" : "false"); if (on) write_reg(par, 0xAE); else diff --git a/drivers/staging/fbtft/fb_tinylcd.c b/drivers/staging/fbtft/fb_tinylcd.c index e463b0ddf16d..9469248f2c50 100644 --- a/drivers/staging/fbtft/fb_tinylcd.c +++ b/drivers/staging/fbtft/fb_tinylcd.c @@ -38,7 +38,7 @@ static int init_display(struct fbtft_par *par) write_reg(par, 0xE5, 0x00); write_reg(par, 0xF0, 0x36, 0xA5, 0x53); write_reg(par, 0xE0, 0x00, 0x35, 0x33, 0x00, 0x00, 0x00, - 0x00, 0x35, 0x33, 0x00, 0x00, 0x00); + 0x00, 0x35, 0x33, 0x00, 0x00, 0x00); write_reg(par, MIPI_DCS_SET_PIXEL_FORMAT, 0x55); write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE); udelay(250); diff --git a/drivers/staging/fbtft/fb_tls8204.c b/drivers/staging/fbtft/fb_tls8204.c index 277b6ed9c725..bec6dd0ffb01 100644 --- a/drivers/staging/fbtft/fb_tls8204.c +++ b/drivers/staging/fbtft/fb_tls8204.c @@ -12,7 +12,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/spi/spi.h> #include <linux/delay.h> @@ -94,7 +94,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) /* The display is 102x68 but the LCD is 84x48. * Set the write pointer at the start of each row. */ - gpio_set_value(par->gpio.dc, 0); + gpiod_set_value(par->gpio.dc, 0); write_reg(par, 0x80 | 0); write_reg(par, 0x40 | y); @@ -109,7 +109,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) *buf++ = ch; } /* Write the row */ - gpio_set_value(par->gpio.dc, 1); + gpiod_set_value(par->gpio.dc, 1); ret = par->fbtftops.write(par, par->txbuf.buf, WIDTH); if (ret < 0) { dev_err(par->info->device, diff --git a/drivers/staging/fbtft/fb_uc1611.c b/drivers/staging/fbtft/fb_uc1611.c index dfaf8bc70f73..65681d0fe200 100644 --- a/drivers/staging/fbtft/fb_uc1611.c +++ b/drivers/staging/fbtft/fb_uc1611.c @@ -10,7 +10,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/spi/spi.h> #include <linux/delay.h> @@ -251,7 +251,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) } break; } - gpio_set_value(par->gpio.dc, 1); + gpiod_set_value(par->gpio.dc, 1); /* Write data */ ret = par->fbtftops.write(par, par->txbuf.buf, len / 2); diff --git a/drivers/staging/fbtft/fb_uc1701.c b/drivers/staging/fbtft/fb_uc1701.c index 0a3531d6eb39..e4ccc73868a7 100644 --- a/drivers/staging/fbtft/fb_uc1701.c +++ b/drivers/staging/fbtft/fb_uc1701.c @@ -11,7 +11,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/spi/spi.h> #include <linux/delay.h> @@ -136,9 +136,9 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) write_reg(par, LCD_PAGE_ADDRESS | (u8)y); write_reg(par, 0x00); write_reg(par, LCD_COL_ADDRESS); - gpio_set_value(par->gpio.dc, 1); + gpiod_set_value(par->gpio.dc, 1); ret = par->fbtftops.write(par, par->txbuf.buf, WIDTH); - gpio_set_value(par->gpio.dc, 0); + gpiod_set_value(par->gpio.dc, 0); } if (ret < 0) diff --git a/drivers/staging/fbtft/fb_upd161704.c b/drivers/staging/fbtft/fb_upd161704.c index acc425fdf34e..564a38e34440 100644 --- a/drivers/staging/fbtft/fb_upd161704.c +++ b/drivers/staging/fbtft/fb_upd161704.c @@ -12,7 +12,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include "fbtft.h" @@ -26,8 +26,8 @@ static int init_display(struct fbtft_par *par) { par->fbtftops.reset(par); - if (par->gpio.cs != -1) - gpio_set_value(par->gpio.cs, 0); /* Activate chip */ + if (!par->gpio.cs) + gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ /* Initialization sequence from Lib_UTFT */ diff --git a/drivers/staging/fbtft/fb_watterott.c b/drivers/staging/fbtft/fb_watterott.c index e77178157f1b..0a5206d28da4 100644 --- a/drivers/staging/fbtft/fb_watterott.c +++ b/drivers/staging/fbtft/fb_watterott.c @@ -8,7 +8,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include "fbtft.h" @@ -213,7 +213,7 @@ static int set_var(struct fbtft_par *par) static int verify_gpios(struct fbtft_par *par) { - if (par->gpio.reset < 0) { + if (!par->gpio.reset) { dev_err(par->info->device, "Missing 'reset' gpio. Aborting.\n"); return -EINVAL; } diff --git a/drivers/staging/fbtft/fbtft-bus.c b/drivers/staging/fbtft/fbtft-bus.c index 8ce1ff9b6c2a..2ea814d0dca5 100644 --- a/drivers/staging/fbtft/fbtft-bus.c +++ b/drivers/staging/fbtft/fbtft-bus.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include <linux/export.h> #include <linux/errno.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/spi/spi.h> #include "fbtft.h" @@ -135,8 +135,8 @@ int fbtft_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) remain = len / 2; vmem16 = (u16 *)(par->info->screen_buffer + offset); - if (par->gpio.dc != -1) - gpio_set_value(par->gpio.dc, 1); + if (!par->gpio.dc) + gpiod_set_value(par->gpio.dc, 1); /* non buffered write */ if (!par->txbuf.buf) diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c index a2df02d97a8e..9b07badf4c6c 100644 --- a/drivers/staging/fbtft/fbtft-core.c +++ b/drivers/staging/fbtft/fbtft-core.c @@ -16,7 +16,7 @@ #include <linux/slab.h> #include <linux/init.h> #include <linux/fb.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/spi/spi.h> #include <linux/delay.h> #include <linux/uaccess.h> @@ -24,7 +24,6 @@ #include <linux/platform_device.h> #include <linux/spinlock.h> #include <linux/of.h> -#include <linux/of_gpio.h> #include <video/mipi_display.h> #include "fbtft.h" @@ -38,8 +37,8 @@ int fbtft_write_buf_dc(struct fbtft_par *par, void *buf, size_t len, int dc) { int ret; - if (gpio_is_valid(par->gpio.dc)) - gpio_set_value(par->gpio.dc, dc); + if (par->gpio.dc) + gpiod_set_value(par->gpio.dc, dc); ret = par->fbtftops.write(par, buf, len); if (ret < 0) @@ -71,127 +70,26 @@ void fbtft_dbg_hex(const struct device *dev, int groupsize, } EXPORT_SYMBOL(fbtft_dbg_hex); -static unsigned long fbtft_request_gpios_match(struct fbtft_par *par, - const struct fbtft_gpio *gpio) -{ - int ret; - unsigned int val; - - fbtft_par_dbg(DEBUG_REQUEST_GPIOS_MATCH, par, "%s('%s')\n", - __func__, gpio->name); - - if (strcasecmp(gpio->name, "reset") == 0) { - par->gpio.reset = gpio->gpio; - return GPIOF_OUT_INIT_HIGH; - } else if (strcasecmp(gpio->name, "dc") == 0) { - par->gpio.dc = gpio->gpio; - return GPIOF_OUT_INIT_LOW; - } else if (strcasecmp(gpio->name, "cs") == 0) { - par->gpio.cs = gpio->gpio; - return GPIOF_OUT_INIT_HIGH; - } else if (strcasecmp(gpio->name, "wr") == 0) { - par->gpio.wr = gpio->gpio; - return GPIOF_OUT_INIT_HIGH; - } else if (strcasecmp(gpio->name, "rd") == 0) { - par->gpio.rd = gpio->gpio; - return GPIOF_OUT_INIT_HIGH; - } else if (strcasecmp(gpio->name, "latch") == 0) { - par->gpio.latch = gpio->gpio; - return GPIOF_OUT_INIT_LOW; - } else if (gpio->name[0] == 'd' && gpio->name[1] == 'b') { - ret = kstrtouint(&gpio->name[2], 10, &val); - if (ret == 0 && val < 16) { - par->gpio.db[val] = gpio->gpio; - return GPIOF_OUT_INIT_LOW; - } - } else if (strcasecmp(gpio->name, "led") == 0) { - par->gpio.led[0] = gpio->gpio; - return GPIOF_OUT_INIT_LOW; - } else if (strcasecmp(gpio->name, "led_") == 0) { - par->gpio.led[0] = gpio->gpio; - return GPIOF_OUT_INIT_HIGH; - } - - return FBTFT_GPIO_NO_MATCH; -} - -static int fbtft_request_gpios(struct fbtft_par *par) -{ - struct fbtft_platform_data *pdata = par->pdata; - const struct fbtft_gpio *gpio; - unsigned long flags; - int ret; - - if (!(pdata && pdata->gpios)) - return 0; - - gpio = pdata->gpios; - while (gpio->name[0]) { - flags = FBTFT_GPIO_NO_MATCH; - /* if driver provides match function, try it first, - * if no match use our own - */ - if (par->fbtftops.request_gpios_match) - flags = par->fbtftops.request_gpios_match(par, gpio); - if (flags == FBTFT_GPIO_NO_MATCH) - flags = fbtft_request_gpios_match(par, gpio); - if (flags != FBTFT_GPIO_NO_MATCH) { - ret = devm_gpio_request_one(par->info->device, - gpio->gpio, flags, - par->info->device->driver->name); - if (ret < 0) { - dev_err(par->info->device, - "%s: gpio_request_one('%s'=%d) failed with %d\n", - __func__, gpio->name, - gpio->gpio, ret); - return ret; - } - fbtft_par_dbg(DEBUG_REQUEST_GPIOS, par, - "%s: '%s' = GPIO%d\n", - __func__, gpio->name, gpio->gpio); - } - gpio++; - } - - return 0; -} - #ifdef CONFIG_OF static int fbtft_request_one_gpio(struct fbtft_par *par, - const char *name, int index, int *gpiop) + const char *name, int index, + struct gpio_desc **gpiop) { struct device *dev = par->info->device; struct device_node *node = dev->of_node; - int gpio, flags, ret = 0; - enum of_gpio_flags of_flags; + int ret = 0; if (of_find_property(node, name, NULL)) { - gpio = of_get_named_gpio_flags(node, name, index, &of_flags); - if (gpio == -ENOENT) - return 0; - if (gpio == -EPROBE_DEFER) - return gpio; - if (gpio < 0) { - dev_err(dev, - "failed to get '%s' from DT\n", name); - return gpio; - } - - /* active low translates to initially low */ - flags = (of_flags & OF_GPIO_ACTIVE_LOW) ? GPIOF_OUT_INIT_LOW : - GPIOF_OUT_INIT_HIGH; - ret = devm_gpio_request_one(dev, gpio, flags, - dev->driver->name); - if (ret) { + *gpiop = devm_gpiod_get_index(dev, dev->driver->name, index, + GPIOD_OUT_HIGH); + if (IS_ERR(*gpiop)) { + ret = PTR_ERR(*gpiop); dev_err(dev, - "gpio_request_one('%s'=%d) failed with %d\n", - name, gpio, ret); + "Failed to request %s GPIO:%d\n", name, ret); return ret; } - if (gpiop) - *gpiop = gpio; - fbtft_par_dbg(DEBUG_REQUEST_GPIOS, par, "%s: '%s' = GPIO%d\n", - __func__, name, gpio); + fbtft_par_dbg(DEBUG_REQUEST_GPIOS, par, "%s: '%s' GPIO\n", + __func__, name); } return ret; @@ -254,9 +152,9 @@ static int fbtft_backlight_update_status(struct backlight_device *bd) if ((bd->props.power == FB_BLANK_UNBLANK) && (bd->props.fb_blank == FB_BLANK_UNBLANK)) - gpio_set_value(par->gpio.led[0], polarity); + gpiod_set_value(par->gpio.led[0], polarity); else - gpio_set_value(par->gpio.led[0], !polarity); + gpiod_set_value(par->gpio.led[0], !polarity); return 0; } @@ -286,7 +184,7 @@ void fbtft_register_backlight(struct fbtft_par *par) struct backlight_device *bd; struct backlight_properties bl_props = { 0, }; - if (par->gpio.led[0] == -1) { + if (!par->gpio.led[0]) { fbtft_par_dbg(DEBUG_BACKLIGHT, par, "%s(): led pin not set, exiting.\n", __func__); return; @@ -295,7 +193,7 @@ void fbtft_register_backlight(struct fbtft_par *par) bl_props.type = BACKLIGHT_RAW; /* Assume backlight is off, get polarity from current state of pin */ bl_props.power = FB_BLANK_POWERDOWN; - if (!gpio_get_value(par->gpio.led[0])) + if (!gpiod_get_value(par->gpio.led[0])) par->polarity = true; bd = backlight_device_register(dev_driver_string(par->info->device), @@ -333,12 +231,12 @@ static void fbtft_set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, static void fbtft_reset(struct fbtft_par *par) { - if (par->gpio.reset == -1) + if (!par->gpio.reset) return; fbtft_par_dbg(DEBUG_RESET, par, "%s()\n", __func__); - gpio_set_value_cansleep(par->gpio.reset, 0); + gpiod_set_value_cansleep(par->gpio.reset, 0); usleep_range(20, 40); - gpio_set_value_cansleep(par->gpio.reset, 1); + gpiod_set_value_cansleep(par->gpio.reset, 1); msleep(120); } @@ -538,9 +436,9 @@ static unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf) return chan << bf->offset; } -static int fbtft_fb_setcolreg(unsigned int regno, unsigned int red, unsigned int green, - unsigned int blue, unsigned int transp, - struct fb_info *info) +static int fbtft_fb_setcolreg(unsigned int regno, unsigned int red, + unsigned int green, unsigned int blue, + unsigned int transp, struct fb_info *info) { unsigned int val; int ret = 1; @@ -663,7 +561,7 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display, int txbuflen = display->txbuflen; unsigned int bpp = display->bpp; unsigned int fps = display->fps; - int vmem_size, i; + int vmem_size; const s16 *init_sequence = display->init_sequence; char *gamma = display->gamma; u32 *gamma_curves = NULL; @@ -841,19 +739,6 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display, par->txbuf.len = txbuflen; } - /* Initialize gpios to disabled */ - par->gpio.reset = -1; - par->gpio.dc = -1; - par->gpio.rd = -1; - par->gpio.wr = -1; - par->gpio.cs = -1; - par->gpio.latch = -1; - for (i = 0; i < 16; i++) { - par->gpio.db[i] = -1; - par->gpio.led[i] = -1; - par->gpio.aux[i] = -1; - } - /* default fbtft operations */ par->fbtftops.write = fbtft_write_spi; par->fbtftops.read = fbtft_read_spi; @@ -863,7 +748,6 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display, par->fbtftops.reset = fbtft_reset; par->fbtftops.mkdirty = fbtft_mkdirty; par->fbtftops.update_display = fbtft_update_display; - par->fbtftops.request_gpios = fbtft_request_gpios; if (display->backlight) par->fbtftops.register_backlight = fbtft_register_backlight; @@ -1035,8 +919,8 @@ static int fbtft_init_display_dt(struct fbtft_par *par) return -EINVAL; par->fbtftops.reset(par); - if (par->gpio.cs != -1) - gpio_set_value(par->gpio.cs, 0); /* Activate chip */ + if (!par->gpio.cs) + gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ while (p) { if (val & FBTFT_OF_INIT_CMD) { @@ -1126,8 +1010,8 @@ int fbtft_init_display(struct fbtft_par *par) } par->fbtftops.reset(par); - if (par->gpio.cs != -1) - gpio_set_value(par->gpio.cs, 0); /* Activate chip */ + if (!par->gpio.cs) + gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ i = 0; while (i < FBTFT_MAX_INIT_SEQUENCE) { @@ -1227,7 +1111,7 @@ static int fbtft_verify_gpios(struct fbtft_par *par) fbtft_par_dbg(DEBUG_VERIFY_GPIOS, par, "%s()\n", __func__); if (pdata->display.buswidth != 9 && par->startbyte == 0 && - par->gpio.dc < 0) { + !par->gpio.dc) { dev_err(par->info->device, "Missing info about 'dc' gpio. Aborting.\n"); return -EINVAL; @@ -1236,12 +1120,12 @@ static int fbtft_verify_gpios(struct fbtft_par *par) if (!par->pdev) return 0; - if (par->gpio.wr < 0) { + if (!par->gpio.wr) { dev_err(par->info->device, "Missing 'wr' gpio. Aborting.\n"); return -EINVAL; } for (i = 0; i < pdata->display.buswidth; i++) { - if (par->gpio.db[i] < 0) { + if (!par->gpio.db[i]) { dev_err(par->info->device, "Missing 'db%02d' gpio. Aborting.\n", i); return -EINVAL; diff --git a/drivers/staging/fbtft/fbtft-io.c b/drivers/staging/fbtft/fbtft-io.c index b5051d3d46a6..38cdad6203ea 100644 --- a/drivers/staging/fbtft/fbtft-io.c +++ b/drivers/staging/fbtft/fbtft-io.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include <linux/export.h> #include <linux/errno.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/spi/spi.h> #include "fbtft.h" @@ -142,30 +142,30 @@ int fbtft_write_gpio8_wr(struct fbtft_par *par, void *buf, size_t len) data = *(u8 *)buf; /* Start writing by pulling down /WR */ - gpio_set_value(par->gpio.wr, 0); + gpiod_set_value(par->gpio.wr, 0); /* Set data */ #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO if (data == prev_data) { - gpio_set_value(par->gpio.wr, 0); /* used as delay */ + gpiod_set_value(par->gpio.wr, 0); /* used as delay */ } else { for (i = 0; i < 8; i++) { if ((data & 1) != (prev_data & 1)) - gpio_set_value(par->gpio.db[i], - data & 1); + gpiod_set_value(par->gpio.db[i], + data & 1); data >>= 1; prev_data >>= 1; } } #else for (i = 0; i < 8; i++) { - gpio_set_value(par->gpio.db[i], data & 1); + gpiod_set_value(par->gpio.db[i], data & 1); data >>= 1; } #endif /* Pullup /WR */ - gpio_set_value(par->gpio.wr, 1); + gpiod_set_value(par->gpio.wr, 1); #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO prev_data = *(u8 *)buf; @@ -192,30 +192,30 @@ int fbtft_write_gpio16_wr(struct fbtft_par *par, void *buf, size_t len) data = *(u16 *)buf; /* Start writing by pulling down /WR */ - gpio_set_value(par->gpio.wr, 0); + gpiod_set_value(par->gpio.wr, 0); /* Set data */ #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO if (data == prev_data) { - gpio_set_value(par->gpio.wr, 0); /* used as delay */ + gpiod_set_value(par->gpio.wr, 0); /* used as delay */ } else { for (i = 0; i < 16; i++) { if ((data & 1) != (prev_data & 1)) - gpio_set_value(par->gpio.db[i], - data & 1); + gpiod_set_value(par->gpio.db[i], + data & 1); data >>= 1; prev_data >>= 1; } } #else for (i = 0; i < 16; i++) { - gpio_set_value(par->gpio.db[i], data & 1); + gpiod_set_value(par->gpio.db[i], data & 1); data >>= 1; } #endif /* Pullup /WR */ - gpio_set_value(par->gpio.wr, 1); + gpiod_set_value(par->gpio.wr, 1); #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO prev_data = *(u16 *)buf; diff --git a/drivers/staging/fbtft/fbtft.h b/drivers/staging/fbtft/fbtft.h index ac427baa464a..7fdd3b0851ef 100644 --- a/drivers/staging/fbtft/fbtft.h +++ b/drivers/staging/fbtft/fbtft.h @@ -27,7 +27,7 @@ */ struct fbtft_gpio { char name[FBTFT_GPIO_NAME_SIZE]; - unsigned int gpio; + struct gpio_desc *gpio; }; struct fbtft_par; @@ -134,7 +134,6 @@ struct fbtft_display { */ struct fbtft_platform_data { struct fbtft_display display; - const struct fbtft_gpio *gpios; unsigned int rotate; bool bgr; unsigned int fps; @@ -207,15 +206,15 @@ struct fbtft_par { unsigned int dirty_lines_start; unsigned int dirty_lines_end; struct { - int reset; - int dc; - int rd; - int wr; - int latch; - int cs; - int db[16]; - int led[16]; - int aux[16]; + struct gpio_desc *reset; + struct gpio_desc *dc; + struct gpio_desc *rd; + struct gpio_desc *wr; + struct gpio_desc *latch; + struct gpio_desc *cs; + struct gpio_desc *db[16]; + struct gpio_desc *led[16]; + struct gpio_desc *aux[16]; } gpio; const s16 *init_sequence; struct { diff --git a/drivers/staging/fbtft/fbtft_device.c b/drivers/staging/fbtft/fbtft_device.c index 046f9d355ecb..5f6cd0816d58 100644 --- a/drivers/staging/fbtft/fbtft_device.c +++ b/drivers/staging/fbtft/fbtft_device.c @@ -8,7 +8,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/spi/spi.h> #include <video/mipi_display.h> @@ -45,11 +45,6 @@ static int mode = -1; module_param(mode, int, 0000); MODULE_PARM_DESC(mode, "SPI mode (override device default)"); -static char *gpios; -module_param(gpios, charp, 0000); -MODULE_PARM_DESC(gpios, - "List of gpios. Comma separated with the form: reset:23,dc:24 (when overriding the default, all gpios must be specified)"); - static unsigned int fps; module_param(fps, uint, 0000); MODULE_PARM_DESC(fps, "Frames per second (override driver default)"); @@ -101,7 +96,7 @@ MODULE_PARM_DESC(debug, static unsigned int verbose = 3; module_param(verbose, uint, 0000); MODULE_PARM_DESC(verbose, - "0 silent, >0 show gpios, >1 show devices, >2 show devices before (default=3)"); + "0 silent, >1 show devices, >2 show devices before (default=3)"); struct fbtft_device_display { char *name; @@ -279,12 +274,6 @@ static struct fbtft_device_display displays[] = { .buswidth = 8, .backlight = 1, }, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - { "led", 18 }, - {}, - }, .gamma = ADAFRUIT18_GAMMA, } } @@ -302,12 +291,6 @@ static struct fbtft_device_display displays[] = { adafruit18_green_tab_set_addr_win, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - { "led", 18 }, - {}, - }, .gamma = ADAFRUIT18_GAMMA, } } @@ -323,11 +306,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "led", 23 }, - {}, - }, } } }, { @@ -342,12 +320,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - { "led", 18 }, - {}, - }, } } }, { @@ -362,12 +334,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - { "led", 18 }, - {}, - }, } } }, { @@ -380,11 +346,6 @@ static struct fbtft_device_display displays[] = { .display = { .buswidth = 8, }, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - {}, - }, } } }, { @@ -399,12 +360,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, .init_sequence = cberry28_init_sequence, }, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 22 }, - { "led", 18 }, - {}, - }, .gamma = CBERRY28_GAMMA, } } @@ -420,9 +375,6 @@ static struct fbtft_device_display displays[] = { .buswidth = 8, .backlight = FBTFT_ONBOARD_BACKLIGHT, }, - .gpios = (const struct fbtft_gpio []) { - {}, - }, }, } } @@ -437,11 +389,6 @@ static struct fbtft_device_display displays[] = { .buswidth = 8, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 13 }, - { "dc", 6 }, - {}, - }, } } }, { @@ -458,11 +405,6 @@ static struct fbtft_device_display displays[] = { .height = 272, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - {}, - }, } } }, { @@ -479,11 +421,6 @@ static struct fbtft_device_display displays[] = { .height = 480, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - {}, - }, } } }, { @@ -496,10 +433,6 @@ static struct fbtft_device_display displays[] = { .display = { .buswidth = 8, }, - .gpios = (const struct fbtft_gpio []) { - { "dc", 24 }, - {}, - }, } } }, { @@ -512,9 +445,6 @@ static struct fbtft_device_display displays[] = { .display = { .buswidth = 9, }, - .gpios = (const struct fbtft_gpio []) { - {}, - }, } } }, { @@ -523,13 +453,6 @@ static struct fbtft_device_display displays[] = { .modalias = "flexfb", .max_speed_hz = 32000000, .mode = SPI_MODE_0, - .platform_data = &(struct fbtft_platform_data) { - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - {}, - }, - } } }, { .name = "flexpfb", @@ -538,24 +461,6 @@ static struct fbtft_device_display displays[] = { .id = 0, .dev = { .release = fbtft_device_pdev_release, - .platform_data = &(struct fbtft_platform_data) { - .gpios = (const struct fbtft_gpio []) { - { "reset", 17 }, - { "dc", 1 }, - { "wr", 0 }, - { "cs", 21 }, - { "db00", 9 }, - { "db01", 11 }, - { "db02", 18 }, - { "db03", 23 }, - { "db04", 24 }, - { "db05", 25 }, - { "db06", 8 }, - { "db07", 7 }, - { "led", 4 }, - {}, - }, - }, } } }, { @@ -570,11 +475,6 @@ static struct fbtft_device_display displays[] = { .backlight = FBTFT_ONBOARD_BACKLIGHT, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 24 }, - { "dc", 25 }, - {}, - }, } } }, { @@ -588,12 +488,6 @@ static struct fbtft_device_display displays[] = { .buswidth = 8, .backlight = 1, }, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - { "led", 23 }, - {}, - }, } } }, { @@ -609,11 +503,6 @@ static struct fbtft_device_display displays[] = { }, .startbyte = 0x70, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "led", 18 }, - {}, - }, } } }, { @@ -631,11 +520,6 @@ static struct fbtft_device_display displays[] = { .startbyte = 0x70, .bgr = true, .fps = 50, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "led", 18 }, - {}, - }, .gamma = HY28B_GAMMA, } } @@ -652,12 +536,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - { "led", 22 }, - {}, - }, } } }, { @@ -673,22 +551,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = false, - .gpios = (const struct fbtft_gpio []) { - /* Wiring for LCD adapter kit */ - { "reset", 7 }, - { "dc", 0 }, /* rev 2: 2 */ - { "wr", 1 }, /* rev 2: 3 */ - { "cs", 8 }, - { "db00", 17 }, - { "db01", 18 }, - { "db02", 21 }, /* rev 2: 27 */ - { "db03", 22 }, - { "db04", 23 }, - { "db05", 24 }, - { "db06", 25 }, - { "db07", 4 }, - {} - }, }, } } @@ -705,9 +567,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - {}, - }, }, } } @@ -723,11 +582,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - {}, - }, } } }, { @@ -743,12 +597,6 @@ static struct fbtft_device_display displays[] = { }, .startbyte = 0x70, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - { "led", 18 }, - {}, - }, } } }, { @@ -763,11 +611,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "led", 18 }, - {}, - }, } } }, { @@ -777,10 +620,6 @@ static struct fbtft_device_display displays[] = { .max_speed_hz = 4000000, .mode = SPI_MODE_3, .platform_data = &(struct fbtft_platform_data) { - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - {}, - }, } } }, { @@ -793,12 +632,6 @@ static struct fbtft_device_display displays[] = { .display = { .buswidth = 8, }, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - { "led", 23 }, - {}, - }, } } }, { @@ -811,12 +644,6 @@ static struct fbtft_device_display displays[] = { .display = { .buswidth = 8, }, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - { "led", 23 }, - {}, - }, } } }, { @@ -831,9 +658,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - {}, - }, } } }, { @@ -849,12 +673,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - { "led", 22 }, - {}, - }, } } }, { @@ -871,10 +689,6 @@ static struct fbtft_device_display displays[] = { .init_sequence = pitft_init_sequence, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "dc", 25 }, - {}, - }, } } }, { @@ -888,11 +702,6 @@ static struct fbtft_device_display displays[] = { .buswidth = 8, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 24 }, - { "dc", 25 }, - {}, - }, .gamma = PIOLED_GAMMA } } @@ -908,12 +717,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 23 }, - { "dc", 24 }, - { "led", 18 }, - {}, - }, } } }, { @@ -928,12 +731,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - { "led", 23 }, - {}, - }, } } }, { @@ -946,11 +743,6 @@ static struct fbtft_device_display displays[] = { .display = { .buswidth = 8, }, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - {}, - }, } } }, { @@ -968,9 +760,6 @@ static struct fbtft_device_display displays[] = { .fbtftops.write = write_gpio16_wr_slow, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - {}, - }, }, }, } @@ -988,9 +777,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - {}, - }, }, }, } @@ -1010,9 +796,6 @@ static struct fbtft_device_display displays[] = { fbtft_write_gpio16_wr_latched, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - {}, - }, }, }, } @@ -1028,11 +811,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - {}, - }, } } }, { @@ -1044,9 +822,6 @@ static struct fbtft_device_display displays[] = { .chip_select = 0, .mode = SPI_MODE_0, .platform_data = &(struct fbtft_platform_data) { - .gpios = (const struct fbtft_gpio []) { - {}, - }, } } }, { @@ -1059,11 +834,6 @@ static struct fbtft_device_display displays[] = { .display = { .buswidth = 8, }, - .gpios = (const struct fbtft_gpio []) { - { "reset", 24 }, - { "dc", 25 }, - {}, - }, } } }, { @@ -1078,12 +848,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - { "led", 18 }, - {}, - }, } } }, { @@ -1098,12 +862,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - { "led", 18 }, - {}, - }, } } }, { @@ -1118,12 +876,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 15 }, - { "dc", 25 }, - { "led_", 18 }, - {}, - }, } } }, { @@ -1138,12 +890,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 15 }, - { "dc", 25 }, - { "led_", 18 }, - {}, - }, } } }, { @@ -1156,11 +902,6 @@ static struct fbtft_device_display displays[] = { .display = { .buswidth = 8, }, - .gpios = (const struct fbtft_gpio []) { - { "reset", 24 }, - { "dc", 25 }, - {}, - }, } } }, { @@ -1177,11 +918,6 @@ static struct fbtft_device_display displays[] = { waveshare32b_init_sequence, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 27 }, - { "dc", 22 }, - {}, - }, } } }, { @@ -1194,11 +930,6 @@ static struct fbtft_device_display displays[] = { .display = { .buswidth = 8, }, - .gpios = (const struct fbtft_gpio []) { - { "reset", 24 }, - { "dc", 25 }, - {}, - }, } } }, { @@ -1211,9 +942,6 @@ static struct fbtft_device_display displays[] = { .max_speed_hz = 0, .mode = SPI_MODE_0, .platform_data = &(struct fbtft_platform_data) { - .gpios = (const struct fbtft_gpio []) { - {}, - }, } }, .pdev = &(struct platform_device) { @@ -1222,9 +950,6 @@ static struct fbtft_device_display displays[] = { .dev = { .release = fbtft_device_pdev_release, .platform_data = &(struct fbtft_platform_data) { - .gpios = (const struct fbtft_gpio []) { - {}, - }, }, }, }, @@ -1246,30 +971,30 @@ static int write_gpio16_wr_slow(struct fbtft_par *par, void *buf, size_t len) data = *(u16 *)buf; /* Start writing by pulling down /WR */ - gpio_set_value(par->gpio.wr, 0); + gpiod_set_value(par->gpio.wr, 0); /* Set data */ #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO if (data == prev_data) { - gpio_set_value(par->gpio.wr, 0); /* used as delay */ + gpiod_set_value(par->gpio.wr, 0); /* used as delay */ } else { for (i = 0; i < 16; i++) { if ((data & 1) != (prev_data & 1)) - gpio_set_value(par->gpio.db[i], - data & 1); + gpiod_set_value(par->gpio.db[i], + data & 1); data >>= 1; prev_data >>= 1; } } #else for (i = 0; i < 16; i++) { - gpio_set_value(par->gpio.db[i], data & 1); + gpiod_set_value(par->gpio.db[i], data & 1); data >>= 1; } #endif /* Pullup /WR */ - gpio_set_value(par->gpio.wr, 1); + gpiod_set_value(par->gpio.wr, 1); #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO prev_data = *(u16 *)buf; @@ -1289,9 +1014,6 @@ static void adafruit18_green_tab_set_addr_win(struct fbtft_par *par, write_reg(par, 0x2C); } -/* used if gpios parameter is present */ -static struct fbtft_gpio fbtft_device_param_gpios[MAX_GPIOS + 1] = { }; - static void fbtft_device_pdev_release(struct device *dev) { /* Needed to silence this message: @@ -1382,11 +1104,8 @@ static int __init fbtft_device_init(void) { struct spi_board_info *spi = NULL; struct fbtft_platform_data *pdata; - const struct fbtft_gpio *gpio = NULL; - char *p_gpio, *p_name, *p_num; bool found = false; int i = 0; - long val; int ret = 0; if (!name) { @@ -1404,38 +1123,6 @@ static int __init fbtft_device_init(void) return -EINVAL; } - /* parse module parameter: gpios */ - while ((p_gpio = strsep(&gpios, ","))) { - if (!strchr(p_gpio, ':')) { - pr_err("error: missing ':' in gpios parameter: %s\n", - p_gpio); - return -EINVAL; - } - p_num = p_gpio; - p_name = strsep(&p_num, ":"); - if (!p_name || !p_num) { - pr_err("something bad happened parsing gpios parameter: %s\n", - p_gpio); - return -EINVAL; - } - ret = kstrtol(p_num, 10, &val); - if (ret) { - pr_err("could not parse number in gpios parameter: %s:%s\n", - p_name, p_num); - return -EINVAL; - } - strncpy(fbtft_device_param_gpios[i].name, p_name, - FBTFT_GPIO_NAME_SIZE - 1); - fbtft_device_param_gpios[i++].gpio = (int)val; - if (i == MAX_GPIOS) { - pr_err("gpios parameter: exceeded max array size: %d\n", - MAX_GPIOS); - return -EINVAL; - } - } - if (fbtft_device_param_gpios[0].name[0]) - gpio = fbtft_device_param_gpios; - if (verbose > 2) { pr_spi_devices(); /* print list of registered SPI devices */ pr_p_devices(); /* print list of 'fb' platform devices */ @@ -1516,8 +1203,6 @@ static int __init fbtft_device_init(void) pdata->txbuflen = txbuflen; if (init_num) pdata->display.init_sequence = init; - if (gpio) - pdata->gpios = gpio; if (custom) { pdata->display.width = width; pdata->display.height = height; @@ -1549,19 +1234,6 @@ static int __init fbtft_device_init(void) return -EINVAL; } - if (verbose && pdata && pdata->gpios) { - gpio = pdata->gpios; - pr_info("GPIOS used by '%s':\n", name); - found = false; - while (verbose && gpio->name[0]) { - pr_info("'%s' = GPIO%d\n", gpio->name, gpio->gpio); - gpio++; - found = true; - } - if (!found) - pr_info("(none)\n"); - } - if (spi_device && (verbose > 1)) pr_spi_devices(); if (p_device && (verbose > 1)) diff --git a/drivers/staging/fbtft/flexfb.c b/drivers/staging/fbtft/flexfb.c index 2af474469e7d..c5fa59105a43 100644 --- a/drivers/staging/fbtft/flexfb.c +++ b/drivers/staging/fbtft/flexfb.c @@ -9,7 +9,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/vmalloc.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/spi/spi.h> #include <linux/delay.h> @@ -521,7 +521,7 @@ static int flexfb_verify_gpios_dc(struct fbtft_par *par) { fbtft_par_dbg(DEBUG_VERIFY_GPIOS, par, "%s()\n", __func__); - if (par->gpio.dc < 0) { + if (!par->gpio.dc) { dev_err(par->info->device, "Missing info about 'dc' gpio. Aborting.\n"); return -EINVAL; @@ -537,22 +537,22 @@ static int flexfb_verify_gpios_db(struct fbtft_par *par) fbtft_par_dbg(DEBUG_VERIFY_GPIOS, par, "%s()\n", __func__); - if (par->gpio.dc < 0) { + if (!par->gpio.dc) { dev_err(par->info->device, "Missing info about 'dc' gpio. Aborting.\n"); return -EINVAL; } - if (par->gpio.wr < 0) { + if (!par->gpio.wr) { dev_err(par->info->device, "Missing info about 'wr' gpio. Aborting.\n"); return -EINVAL; } - if (latched && (par->gpio.latch < 0)) { + if (latched && !par->gpio.latch) { dev_err(par->info->device, "Missing info about 'latch' gpio. Aborting.\n"); return -EINVAL; } if (latched) num_db = buswidth / 2; for (i = 0; i < num_db; i++) { - if (par->gpio.db[i] < 0) { + if (!par->gpio.db[i]) { dev_err(par->info->device, "Missing info about 'db%02d' gpio. Aborting.\n", i); diff --git a/drivers/staging/fsl-dpaa2/ethsw/dpsw-cmd.h b/drivers/staging/fsl-dpaa2/ethsw/dpsw-cmd.h index da744f2b0ee6..14b974defa3a 100644 --- a/drivers/staging/fsl-dpaa2/ethsw/dpsw-cmd.h +++ b/drivers/staging/fsl-dpaa2/ethsw/dpsw-cmd.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright 2014-2016 Freescale Semiconductor Inc. * Copyright 2017-2018 NXP diff --git a/drivers/staging/fsl-dpaa2/ethsw/dpsw.h b/drivers/staging/fsl-dpaa2/ethsw/dpsw.h index db43fa3782b8..25635259ce44 100644 --- a/drivers/staging/fsl-dpaa2/ethsw/dpsw.h +++ b/drivers/staging/fsl-dpaa2/ethsw/dpsw.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright 2014-2016 Freescale Semiconductor Inc. * Copyright 2017-2018 NXP diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.h b/drivers/staging/fsl-dpaa2/ethsw/ethsw.h index 069c99bfba74..c48783680a05 100644 --- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.h +++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* * DPAA2 Ethernet Switch declarations * diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c index 3e416f5bbcba..a1b90ea7fcb8 100644 --- a/drivers/staging/fwserial/fwserial.c +++ b/drivers/staging/fwserial/fwserial.c @@ -1213,6 +1213,7 @@ static int get_serial_info(struct tty_struct *tty, struct serial_struct *ss) { struct fwtty_port *port = tty->driver_data; + mutex_lock(&port->port.mutex); ss->type = PORT_UNKNOWN; ss->line = port->port.tty->index; diff --git a/drivers/staging/gasket/gasket_interrupt.c b/drivers/staging/gasket/gasket_interrupt.c index ad5657d213f0..ff61b782df30 100644 --- a/drivers/staging/gasket/gasket_interrupt.c +++ b/drivers/staging/gasket/gasket_interrupt.c @@ -9,7 +9,6 @@ #include <linux/device.h> #include <linux/interrupt.h> #include <linux/printk.h> -#include <linux/version.h> #ifdef GASKET_KERNEL_TRACE_SUPPORT #define CREATE_TRACE_POINTS #include <trace/events/gasket_interrupt.h> diff --git a/drivers/staging/goldfish/goldfish_audio.c b/drivers/staging/goldfish/goldfish_audio.c index d4520490cf6d..24a738238f9f 100644 --- a/drivers/staging/goldfish/goldfish_audio.c +++ b/drivers/staging/goldfish/goldfish_audio.c @@ -4,16 +4,6 @@ * * Copyright (C) 2007 Google, Inc. * Copyright (C) 2012 Intel, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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/module.h> diff --git a/drivers/staging/greybus/Kconfig b/drivers/staging/greybus/Kconfig index ab096bcef98c..b571e4e8060b 100644 --- a/drivers/staging/greybus/Kconfig +++ b/drivers/staging/greybus/Kconfig @@ -148,6 +148,7 @@ if GREYBUS_BRIDGED_PHY config GREYBUS_GPIO tristate "Greybus GPIO Bridged PHY driver" depends on GPIOLIB + select GPIOLIB_IRQCHIP ---help--- Select this option if you have a device that follows the Greybus GPIO Bridged PHY Class specification. diff --git a/drivers/staging/greybus/TODO b/drivers/staging/greybus/TODO index 3b90a5711998..31f1f2cb401c 100644 --- a/drivers/staging/greybus/TODO +++ b/drivers/staging/greybus/TODO @@ -1,5 +1,3 @@ * Convert all uses of the old GPIO API from <linux/gpio.h> to the GPIO descriptor API in <linux/gpio/consumer.h> and look up GPIO lines from device tree or ACPI. -* Convert the GPIO driver to use the GPIO irqchip library - GPIOLIB_IRQCHIP instead of reimplementing the same. diff --git a/drivers/staging/greybus/arche-apb-ctrl.c b/drivers/staging/greybus/arche-apb-ctrl.c index be5ffed90bcf..bbf3ba744fc4 100644 --- a/drivers/staging/greybus/arche-apb-ctrl.c +++ b/drivers/staging/greybus/arche-apb-ctrl.c @@ -8,9 +8,8 @@ #include <linux/clk.h> #include <linux/delay.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/interrupt.h> -#include <linux/of_gpio.h> #include <linux/of_irq.h> #include <linux/module.h> #include <linux/pinctrl/consumer.h> @@ -24,12 +23,12 @@ static void apb_bootret_deassert(struct device *dev); struct arche_apb_ctrl_drvdata { /* Control GPIO signals to and from AP <=> AP Bridges */ - int resetn_gpio; - int boot_ret_gpio; - int pwroff_gpio; - int wake_in_gpio; - int wake_out_gpio; - int pwrdn_gpio; + struct gpio_desc *resetn; + struct gpio_desc *boot_ret; + struct gpio_desc *pwroff; + struct gpio_desc *wake_in; + struct gpio_desc *wake_out; + struct gpio_desc *pwrdn; enum arche_platform_state state; bool init_disabled; @@ -37,28 +36,28 @@ struct arche_apb_ctrl_drvdata { struct regulator *vcore; struct regulator *vio; - int clk_en_gpio; + struct gpio_desc *clk_en; struct clk *clk; struct pinctrl *pinctrl; struct pinctrl_state *pin_default; /* V2: SPI Bus control */ - int spi_en_gpio; + struct gpio_desc *spi_en; bool spi_en_polarity_high; }; /* * Note that these low level api's are active high */ -static inline void deassert_reset(unsigned int gpio) +static inline void deassert_reset(struct gpio_desc *gpio) { - gpio_set_value(gpio, 1); + gpiod_set_raw_value(gpio, 1); } -static inline void assert_reset(unsigned int gpio) +static inline void assert_reset(struct gpio_desc *gpio) { - gpio_set_value(gpio, 0); + gpiod_set_raw_value(gpio, 0); } /* @@ -75,11 +74,10 @@ static int coldboot_seq(struct platform_device *pdev) return 0; /* Hold APB in reset state */ - assert_reset(apb->resetn_gpio); + assert_reset(apb->resetn); - if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && - gpio_is_valid(apb->spi_en_gpio)) - devm_gpio_free(dev, apb->spi_en_gpio); + if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && apb->spi_en) + devm_gpiod_put(dev, apb->spi_en); /* Enable power to APB */ if (!IS_ERR(apb->vcore)) { @@ -101,13 +99,13 @@ static int coldboot_seq(struct platform_device *pdev) apb_bootret_deassert(dev); /* On DB3 clock was not mandatory */ - if (gpio_is_valid(apb->clk_en_gpio)) - gpio_set_value(apb->clk_en_gpio, 1); + if (apb->clk_en) + gpiod_set_value(apb->clk_en, 1); usleep_range(100, 200); /* deassert reset to APB : Active-low signal */ - deassert_reset(apb->resetn_gpio); + deassert_reset(apb->resetn); apb->state = ARCHE_PLATFORM_STATE_ACTIVE; @@ -136,25 +134,25 @@ static int fw_flashing_seq(struct platform_device *pdev) return ret; } - if (gpio_is_valid(apb->spi_en_gpio)) { + if (apb->spi_en) { unsigned long flags; if (apb->spi_en_polarity_high) - flags = GPIOF_OUT_INIT_HIGH; + flags = GPIOD_OUT_HIGH; else - flags = GPIOF_OUT_INIT_LOW; + flags = GPIOD_OUT_LOW; - ret = devm_gpio_request_one(dev, apb->spi_en_gpio, - flags, "apb_spi_en"); - if (ret) { - dev_err(dev, "Failed requesting SPI bus en gpio %d\n", - apb->spi_en_gpio); + apb->spi_en = devm_gpiod_get(dev, "spi-en", flags); + if (IS_ERR(apb->spi_en)) { + ret = PTR_ERR(apb->spi_en); + dev_err(dev, "Failed requesting SPI bus en GPIO: %d\n", + ret); return ret; } } /* for flashing device should be in reset state */ - assert_reset(apb->resetn_gpio); + assert_reset(apb->resetn); apb->state = ARCHE_PLATFORM_STATE_FW_FLASHING; return 0; @@ -176,9 +174,8 @@ static int standby_boot_seq(struct platform_device *pdev) apb->state == ARCHE_PLATFORM_STATE_OFF) return 0; - if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && - gpio_is_valid(apb->spi_en_gpio)) - devm_gpio_free(dev, apb->spi_en_gpio); + if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && apb->spi_en) + devm_gpiod_put(dev, apb->spi_en); /* * As per WDM spec, do nothing @@ -201,13 +198,12 @@ static void poweroff_seq(struct platform_device *pdev) if (apb->init_disabled || apb->state == ARCHE_PLATFORM_STATE_OFF) return; - if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && - gpio_is_valid(apb->spi_en_gpio)) - devm_gpio_free(dev, apb->spi_en_gpio); + if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && apb->spi_en) + devm_gpiod_put(dev, apb->spi_en); /* disable the clock */ - if (gpio_is_valid(apb->clk_en_gpio)) - gpio_set_value(apb->clk_en_gpio, 0); + if (apb->clk_en) + gpiod_set_value(apb->clk_en, 0); if (!IS_ERR(apb->vcore) && regulator_is_enabled(apb->vcore) > 0) regulator_disable(apb->vcore); @@ -216,7 +212,7 @@ static void poweroff_seq(struct platform_device *pdev) regulator_disable(apb->vio); /* As part of exit, put APB back in reset state */ - assert_reset(apb->resetn_gpio); + assert_reset(apb->resetn); apb->state = ARCHE_PLATFORM_STATE_OFF; /* TODO: May have to send an event to SVC about this exit */ @@ -226,7 +222,7 @@ static void apb_bootret_deassert(struct device *dev) { struct arche_apb_ctrl_drvdata *apb = dev_get_drvdata(dev); - gpio_set_value(apb->boot_ret_gpio, 0); + gpiod_set_value(apb->boot_ret, 0); } int apb_ctrl_coldboot(struct device *dev) @@ -322,66 +318,44 @@ static int apb_ctrl_get_devtree_data(struct platform_device *pdev, struct arche_apb_ctrl_drvdata *apb) { struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; int ret; - apb->resetn_gpio = of_get_named_gpio(np, "reset-gpios", 0); - if (apb->resetn_gpio < 0) { - dev_err(dev, "failed to get reset gpio\n"); - return apb->resetn_gpio; - } - ret = devm_gpio_request_one(dev, apb->resetn_gpio, - GPIOF_OUT_INIT_LOW, "apb-reset"); - if (ret) { - dev_err(dev, "Failed requesting reset gpio %d\n", - apb->resetn_gpio); + apb->resetn = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(apb->resetn)) { + ret = PTR_ERR(apb->resetn); + dev_err(dev, "Failed requesting reset GPIO: %d\n", ret); return ret; } - apb->boot_ret_gpio = of_get_named_gpio(np, "boot-ret-gpios", 0); - if (apb->boot_ret_gpio < 0) { - dev_err(dev, "failed to get boot retention gpio\n"); - return apb->boot_ret_gpio; - } - ret = devm_gpio_request_one(dev, apb->boot_ret_gpio, - GPIOF_OUT_INIT_LOW, "boot retention"); - if (ret) { - dev_err(dev, "Failed requesting bootret gpio %d\n", - apb->boot_ret_gpio); + apb->boot_ret = devm_gpiod_get(dev, "boot-ret", GPIOD_OUT_LOW); + if (IS_ERR(apb->boot_ret)) { + ret = PTR_ERR(apb->boot_ret); + dev_err(dev, "Failed requesting bootret GPIO: %d\n", ret); return ret; } /* It's not mandatory to support power management interface */ - apb->pwroff_gpio = of_get_named_gpio(np, "pwr-off-gpios", 0); - if (apb->pwroff_gpio < 0) { - dev_err(dev, "failed to get power off gpio\n"); - return apb->pwroff_gpio; - } - ret = devm_gpio_request_one(dev, apb->pwroff_gpio, - GPIOF_IN, "pwroff_n"); - if (ret) { - dev_err(dev, "Failed requesting pwroff_n gpio %d\n", - apb->pwroff_gpio); + apb->pwroff = devm_gpiod_get_optional(dev, "pwr-off", GPIOD_IN); + if (IS_ERR(apb->pwroff)) { + ret = PTR_ERR(apb->pwroff); + dev_err(dev, "Failed requesting pwroff_n GPIO: %d\n", ret); return ret; } /* Do not make clock mandatory as of now (for DB3) */ - apb->clk_en_gpio = of_get_named_gpio(np, "clock-en-gpio", 0); - if (apb->clk_en_gpio < 0) { - dev_warn(dev, "failed to get clock en gpio\n"); - } else if (gpio_is_valid(apb->clk_en_gpio)) { - ret = devm_gpio_request_one(dev, apb->clk_en_gpio, - GPIOF_OUT_INIT_LOW, "apb_clk_en"); - if (ret) { - dev_warn(dev, "Failed requesting APB clock en gpio %d\n", - apb->clk_en_gpio); - return ret; - } + apb->clk_en = devm_gpiod_get_optional(dev, "clock-en", GPIOD_OUT_LOW); + if (IS_ERR(apb->clk_en)) { + ret = PTR_ERR(apb->clk_en); + dev_err(dev, "Failed requesting APB clock en GPIO: %d\n", ret); + return ret; } - apb->pwrdn_gpio = of_get_named_gpio(np, "pwr-down-gpios", 0); - if (apb->pwrdn_gpio < 0) - dev_warn(dev, "failed to get power down gpio\n"); + apb->pwrdn = devm_gpiod_get(dev, "pwr-down", GPIOD_OUT_LOW); + if (IS_ERR(apb->pwrdn)) { + ret = PTR_ERR(apb->pwrdn); + dev_warn(dev, "Failed requesting power down GPIO: %d\n", ret); + return ret; + } /* Regulators are optional, as we may have fixed supply coming in */ apb->vcore = devm_regulator_get(dev, "vcore"); @@ -404,12 +378,8 @@ static int apb_ctrl_get_devtree_data(struct platform_device *pdev, } /* Only applicable for platform >= V2 */ - apb->spi_en_gpio = of_get_named_gpio(np, "spi-en-gpio", 0); - if (apb->spi_en_gpio >= 0) { - if (of_property_read_bool(pdev->dev.of_node, - "spi-en-active-high")) - apb->spi_en_polarity_high = true; - } + if (of_property_read_bool(pdev->dev.of_node, "gb,spi-en-active-high")) + apb->spi_en_polarity_high = true; return 0; } diff --git a/drivers/staging/greybus/arche-platform.c b/drivers/staging/greybus/arche-platform.c index 4c36e88766e7..6eb842040c22 100644 --- a/drivers/staging/greybus/arche-platform.c +++ b/drivers/staging/greybus/arche-platform.c @@ -8,10 +8,9 @@ #include <linux/clk.h> #include <linux/delay.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/init.h> #include <linux/module.h> -#include <linux/of_gpio.h> #include <linux/of_platform.h> #include <linux/pinctrl/consumer.h> #include <linux/platform_device.h> @@ -45,14 +44,14 @@ enum svc_wakedetect_state { struct arche_platform_drvdata { /* Control GPIO signals to and from AP <=> SVC */ - int svc_reset_gpio; + struct gpio_desc *svc_reset; bool is_reset_act_hi; - int svc_sysboot_gpio; - int wake_detect_gpio; /* bi-dir,maps to WAKE_MOD & WAKE_FRAME signals */ + struct gpio_desc *svc_sysboot; + struct gpio_desc *wake_detect; /* bi-dir,maps to WAKE_MOD & WAKE_FRAME signals */ enum arche_platform_state state; - int svc_refclk_req; + struct gpio_desc *svc_refclk_req; struct clk *svc_ref_clk; struct pinctrl *pinctrl; @@ -85,9 +84,9 @@ static void arche_platform_set_wake_detect_state( arche_pdata->wake_detect_state = state; } -static inline void svc_reset_onoff(unsigned int gpio, bool onoff) +static inline void svc_reset_onoff(struct gpio_desc *gpio, bool onoff) { - gpio_set_value(gpio, onoff); + gpiod_set_raw_value(gpio, onoff); } static int apb_cold_boot(struct device *dev, void *data) @@ -116,7 +115,6 @@ static int apb_poweroff(struct device *dev, void *data) static void arche_platform_wd_irq_en(struct arche_platform_drvdata *arche_pdata) { /* Enable interrupt here, to read event back from SVC */ - gpio_direction_input(arche_pdata->wake_detect_gpio); enable_irq(arche_pdata->wake_detect_irq); } @@ -160,7 +158,7 @@ static irqreturn_t arche_platform_wd_irq(int irq, void *devid) spin_lock_irqsave(&arche_pdata->wake_lock, flags); - if (gpio_get_value(arche_pdata->wake_detect_gpio)) { + if (gpiod_get_value(arche_pdata->wake_detect)) { /* wake/detect rising */ /* @@ -224,10 +222,9 @@ arche_platform_coldboot_seq(struct arche_platform_drvdata *arche_pdata) dev_info(arche_pdata->dev, "Booting from cold boot state\n"); - svc_reset_onoff(arche_pdata->svc_reset_gpio, - arche_pdata->is_reset_act_hi); + svc_reset_onoff(arche_pdata->svc_reset, arche_pdata->is_reset_act_hi); - gpio_set_value(arche_pdata->svc_sysboot_gpio, 0); + gpiod_set_value(arche_pdata->svc_sysboot, 0); usleep_range(100, 200); ret = clk_prepare_enable(arche_pdata->svc_ref_clk); @@ -238,8 +235,7 @@ arche_platform_coldboot_seq(struct arche_platform_drvdata *arche_pdata) } /* bring SVC out of reset */ - svc_reset_onoff(arche_pdata->svc_reset_gpio, - !arche_pdata->is_reset_act_hi); + svc_reset_onoff(arche_pdata->svc_reset, !arche_pdata->is_reset_act_hi); arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_ACTIVE); @@ -259,10 +255,9 @@ arche_platform_fw_flashing_seq(struct arche_platform_drvdata *arche_pdata) dev_info(arche_pdata->dev, "Switching to FW flashing state\n"); - svc_reset_onoff(arche_pdata->svc_reset_gpio, - arche_pdata->is_reset_act_hi); + svc_reset_onoff(arche_pdata->svc_reset, arche_pdata->is_reset_act_hi); - gpio_set_value(arche_pdata->svc_sysboot_gpio, 1); + gpiod_set_value(arche_pdata->svc_sysboot, 1); usleep_range(100, 200); @@ -273,8 +268,7 @@ arche_platform_fw_flashing_seq(struct arche_platform_drvdata *arche_pdata) return ret; } - svc_reset_onoff(arche_pdata->svc_reset_gpio, - !arche_pdata->is_reset_act_hi); + svc_reset_onoff(arche_pdata->svc_reset, !arche_pdata->is_reset_act_hi); arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_FW_FLASHING); @@ -305,8 +299,7 @@ arche_platform_poweroff_seq(struct arche_platform_drvdata *arche_pdata) clk_disable_unprepare(arche_pdata->svc_ref_clk); /* As part of exit, put APB back in reset state */ - svc_reset_onoff(arche_pdata->svc_reset_gpio, - arche_pdata->is_reset_act_hi); + svc_reset_onoff(arche_pdata->svc_reset, arche_pdata->is_reset_act_hi); arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_OFF); } @@ -435,6 +428,7 @@ static int arche_platform_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; int ret; + unsigned int flags; arche_pdata = devm_kzalloc(&pdev->dev, sizeof(*arche_pdata), GFP_KERNEL); @@ -444,61 +438,33 @@ static int arche_platform_probe(struct platform_device *pdev) /* setup svc reset gpio */ arche_pdata->is_reset_act_hi = of_property_read_bool(np, "svc,reset-active-high"); - arche_pdata->svc_reset_gpio = of_get_named_gpio(np, - "svc,reset-gpio", - 0); - if (!gpio_is_valid(arche_pdata->svc_reset_gpio)) { - dev_err(dev, "failed to get reset-gpio\n"); - return arche_pdata->svc_reset_gpio; - } - ret = devm_gpio_request(dev, arche_pdata->svc_reset_gpio, "svc-reset"); - if (ret) { - dev_err(dev, "failed to request svc-reset gpio:%d\n", ret); - return ret; - } - ret = gpio_direction_output(arche_pdata->svc_reset_gpio, - arche_pdata->is_reset_act_hi); - if (ret) { - dev_err(dev, "failed to set svc-reset gpio dir:%d\n", ret); + if (arche_pdata->is_reset_act_hi) + flags = GPIOD_OUT_HIGH; + else + flags = GPIOD_OUT_LOW; + + arche_pdata->svc_reset = devm_gpiod_get(dev, "svc,reset", flags); + if (IS_ERR(arche_pdata->svc_reset)) { + ret = PTR_ERR(arche_pdata->svc_reset); + dev_err(dev, "failed to request svc-reset GPIO: %d\n", ret); return ret; } arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_OFF); - arche_pdata->svc_sysboot_gpio = of_get_named_gpio(np, - "svc,sysboot-gpio", - 0); - if (!gpio_is_valid(arche_pdata->svc_sysboot_gpio)) { - dev_err(dev, "failed to get sysboot gpio\n"); - return arche_pdata->svc_sysboot_gpio; - } - ret = devm_gpio_request(dev, arche_pdata->svc_sysboot_gpio, "sysboot0"); - if (ret) { - dev_err(dev, "failed to request sysboot0 gpio:%d\n", ret); - return ret; - } - ret = gpio_direction_output(arche_pdata->svc_sysboot_gpio, 0); - if (ret) { - dev_err(dev, "failed to set svc-reset gpio dir:%d\n", ret); + arche_pdata->svc_sysboot = devm_gpiod_get(dev, "svc,sysboot", + GPIOD_OUT_LOW); + if (IS_ERR(arche_pdata->svc_sysboot)) { + ret = PTR_ERR(arche_pdata->svc_sysboot); + dev_err(dev, "failed to request sysboot0 GPIO: %d\n", ret); return ret; } /* setup the clock request gpio first */ - arche_pdata->svc_refclk_req = of_get_named_gpio(np, - "svc,refclk-req-gpio", - 0); - if (!gpio_is_valid(arche_pdata->svc_refclk_req)) { - dev_err(dev, "failed to get svc clock-req gpio\n"); - return arche_pdata->svc_refclk_req; - } - ret = devm_gpio_request(dev, arche_pdata->svc_refclk_req, - "svc-clk-req"); - if (ret) { - dev_err(dev, "failed to request svc-clk-req gpio: %d\n", ret); - return ret; - } - ret = gpio_direction_input(arche_pdata->svc_refclk_req); - if (ret) { - dev_err(dev, "failed to set svc-clk-req gpio dir :%d\n", ret); + arche_pdata->svc_refclk_req = devm_gpiod_get(dev, "svc,refclk-req", + GPIOD_IN); + if (IS_ERR(arche_pdata->svc_refclk_req)) { + ret = PTR_ERR(arche_pdata->svc_refclk_req); + dev_err(dev, "failed to request svc-clk-req GPIO: %d\n", ret); return ret; } @@ -515,19 +481,11 @@ static int arche_platform_probe(struct platform_device *pdev) arche_pdata->num_apbs = of_get_child_count(np); dev_dbg(dev, "Number of APB's available - %d\n", arche_pdata->num_apbs); - arche_pdata->wake_detect_gpio = of_get_named_gpio(np, - "svc,wake-detect-gpio", - 0); - if (arche_pdata->wake_detect_gpio < 0) { - dev_err(dev, "failed to get wake detect gpio\n"); - return arche_pdata->wake_detect_gpio; - } - - ret = devm_gpio_request(dev, arche_pdata->wake_detect_gpio, - "wake detect"); - if (ret) { - dev_err(dev, "Failed requesting wake_detect gpio %d\n", - arche_pdata->wake_detect_gpio); + arche_pdata->wake_detect = devm_gpiod_get(dev, "svc,wake-detect", + GPIOD_IN); + if (IS_ERR(arche_pdata->wake_detect)) { + ret = PTR_ERR(arche_pdata->wake_detect); + dev_err(dev, "Failed requesting wake_detect GPIO: %d\n", ret); return ret; } @@ -538,7 +496,7 @@ static int arche_platform_probe(struct platform_device *pdev) spin_lock_init(&arche_pdata->wake_lock); mutex_init(&arche_pdata->platform_state_mutex); arche_pdata->wake_detect_irq = - gpio_to_irq(arche_pdata->wake_detect_gpio); + gpiod_to_irq(arche_pdata->wake_detect); ret = devm_request_threaded_irq(dev, arche_pdata->wake_detect_irq, arche_platform_wd_irq, diff --git a/drivers/staging/greybus/audio_topology.c b/drivers/staging/greybus/audio_topology.c index 8bcbc3c4588c..4ac30accf226 100644 --- a/drivers/staging/greybus/audio_topology.c +++ b/drivers/staging/greybus/audio_topology.c @@ -923,7 +923,6 @@ static int gbaudio_tplg_create_wcontrol(struct gbaudio_module_info *gb, break; default: return -EINVAL; - } dev_dbg(gb->dev, "%s:%d DAPM control created, ret:%d\n", ctl->name, diff --git a/drivers/staging/greybus/bundle.c b/drivers/staging/greybus/bundle.c index 81c018da1248..e97b2b87ba47 100644 --- a/drivers/staging/greybus/bundle.c +++ b/drivers/staging/greybus/bundle.c @@ -65,7 +65,7 @@ static struct attribute *bundle_attrs[] = { ATTRIBUTE_GROUPS(bundle); static struct gb_bundle *gb_bundle_find(struct gb_interface *intf, - u8 bundle_id) + u8 bundle_id) { struct gb_bundle *bundle; diff --git a/drivers/staging/greybus/connection.h b/drivers/staging/greybus/connection.h index 8deeb1d5f008..5ca3befc0636 100644 --- a/drivers/staging/greybus/connection.h +++ b/drivers/staging/greybus/connection.h @@ -88,7 +88,7 @@ void gb_connection_mode_switch_prepare(struct gb_connection *connection); void gb_connection_mode_switch_complete(struct gb_connection *connection); void greybus_data_rcvd(struct gb_host_device *hd, u16 cport_id, - u8 *data, size_t length); + u8 *data, size_t length); void gb_connection_latency_tag_enable(struct gb_connection *connection); void gb_connection_latency_tag_disable(struct gb_connection *connection); diff --git a/drivers/staging/greybus/control.c b/drivers/staging/greybus/control.c index ffa41d31896d..a9e8b6036cac 100644 --- a/drivers/staging/greybus/control.c +++ b/drivers/staging/greybus/control.c @@ -15,7 +15,6 @@ #define GB_CONTROL_VERSION_MAJOR 0 #define GB_CONTROL_VERSION_MINOR 1 - static int gb_control_get_version(struct gb_control *control) { struct gb_interface *intf = control->connection->intf; diff --git a/drivers/staging/greybus/core.c b/drivers/staging/greybus/core.c index 412337daf45c..d6b0d49130c0 100644 --- a/drivers/staging/greybus/core.c +++ b/drivers/staging/greybus/core.c @@ -266,7 +266,7 @@ static int greybus_remove(struct device *dev) } int greybus_register_driver(struct greybus_driver *driver, struct module *owner, - const char *mod_name) + const char *mod_name) { int retval; diff --git a/drivers/staging/greybus/gpio.c b/drivers/staging/greybus/gpio.c index e110681e6f86..3151004d26fb 100644 --- a/drivers/staging/greybus/gpio.c +++ b/drivers/staging/greybus/gpio.c @@ -9,9 +9,9 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> -#include <linux/gpio.h> #include <linux/irq.h> #include <linux/irqdomain.h> +#include <linux/gpio/driver.h> #include <linux/mutex.h> #include "greybus.h" @@ -39,11 +39,6 @@ struct gb_gpio_controller { struct gpio_chip chip; struct irq_chip irqc; - struct irq_chip *irqchip; - struct irq_domain *irqdomain; - unsigned int irq_base; - irq_flow_handler_t irq_handler; - unsigned int irq_default_type; struct mutex irq_lock; }; #define gpio_chip_to_gb_gpio_controller(chip) \ @@ -391,7 +386,7 @@ static int gb_gpio_request_handler(struct gb_operation *op) return -EINVAL; } - irq = irq_find_mapping(ggc->irqdomain, event->which); + irq = irq_find_mapping(ggc->chip.irq.domain, event->which); if (!irq) { dev_err(dev, "failed to find IRQ\n"); return -EINVAL; @@ -506,135 +501,6 @@ static int gb_gpio_controller_setup(struct gb_gpio_controller *ggc) return ret; } -/** - * gb_gpio_irq_map() - maps an IRQ into a GB gpio irqchip - * @d: the irqdomain used by this irqchip - * @irq: the global irq number used by this GB gpio irqchip irq - * @hwirq: the local IRQ/GPIO line offset on this GB gpio - * - * This function will set up the mapping for a certain IRQ line on a - * GB gpio by assigning the GB gpio as chip data, and using the irqchip - * stored inside the GB gpio. - */ -static int gb_gpio_irq_map(struct irq_domain *domain, unsigned int irq, - irq_hw_number_t hwirq) -{ - struct gpio_chip *chip = domain->host_data; - struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); - - irq_set_chip_data(irq, ggc); - irq_set_chip_and_handler(irq, ggc->irqchip, ggc->irq_handler); - irq_set_noprobe(irq); - /* - * No set-up of the hardware will happen if IRQ_TYPE_NONE - * is passed as default type. - */ - if (ggc->irq_default_type != IRQ_TYPE_NONE) - irq_set_irq_type(irq, ggc->irq_default_type); - - return 0; -} - -static void gb_gpio_irq_unmap(struct irq_domain *d, unsigned int irq) -{ - irq_set_chip_and_handler(irq, NULL, NULL); - irq_set_chip_data(irq, NULL); -} - -static const struct irq_domain_ops gb_gpio_domain_ops = { - .map = gb_gpio_irq_map, - .unmap = gb_gpio_irq_unmap, -}; - -/** - * gb_gpio_irqchip_remove() - removes an irqchip added to a gb_gpio_controller - * @ggc: the gb_gpio_controller to remove the irqchip from - * - * This is called only from gb_gpio_remove() - */ -static void gb_gpio_irqchip_remove(struct gb_gpio_controller *ggc) -{ - unsigned int offset; - - /* Remove all IRQ mappings and delete the domain */ - if (ggc->irqdomain) { - for (offset = 0; offset < (ggc->line_max + 1); offset++) - irq_dispose_mapping(irq_find_mapping(ggc->irqdomain, - offset)); - irq_domain_remove(ggc->irqdomain); - } - - if (ggc->irqchip) - ggc->irqchip = NULL; -} - -/** - * gb_gpio_irqchip_add() - adds an irqchip to a gpio chip - * @chip: the gpio chip to add the irqchip to - * @irqchip: the irqchip to add to the adapter - * @first_irq: if not dynamically assigned, the base (first) IRQ to - * allocate gpio irqs from - * @handler: the irq handler to use (often a predefined irq core function) - * @type: the default type for IRQs on this irqchip, pass IRQ_TYPE_NONE - * to have the core avoid setting up any default type in the hardware. - * - * This function closely associates a certain irqchip with a certain - * gpio chip, providing an irq domain to translate the local IRQs to - * global irqs, and making sure that the gpio chip - * is passed as chip data to all related functions. Driver callbacks - * need to use container_of() to get their local state containers back - * from the gpio chip passed as chip data. An irqdomain will be stored - * in the gpio chip that shall be used by the driver to handle IRQ number - * translation. The gpio chip will need to be initialized and registered - * before calling this function. - */ -static int gb_gpio_irqchip_add(struct gpio_chip *chip, - struct irq_chip *irqchip, - unsigned int first_irq, - irq_flow_handler_t handler, - unsigned int type) -{ - struct gb_gpio_controller *ggc; - unsigned int offset; - unsigned int irq_base; - - if (!chip || !irqchip) - return -EINVAL; - - ggc = gpio_chip_to_gb_gpio_controller(chip); - - ggc->irqchip = irqchip; - ggc->irq_handler = handler; - ggc->irq_default_type = type; - ggc->irqdomain = irq_domain_add_simple(NULL, - ggc->line_max + 1, first_irq, - &gb_gpio_domain_ops, chip); - if (!ggc->irqdomain) { - ggc->irqchip = NULL; - return -EINVAL; - } - - /* - * Prepare the mapping since the irqchip shall be orthogonal to - * any gpio calls. If the first_irq was zero, this is - * necessary to allocate descriptors for all IRQs. - */ - for (offset = 0; offset < (ggc->line_max + 1); offset++) { - irq_base = irq_create_mapping(ggc->irqdomain, offset); - if (offset == 0) - ggc->irq_base = irq_base; - } - - return 0; -} - -static int gb_gpio_to_irq(struct gpio_chip *chip, unsigned int offset) -{ - struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); - - return irq_find_mapping(ggc->irqdomain, offset); -} - static int gb_gpio_probe(struct gbphy_device *gbphy_dev, const struct gbphy_device_id *id) { @@ -694,7 +560,6 @@ static int gb_gpio_probe(struct gbphy_device *gbphy_dev, gpio->get = gb_gpio_get; gpio->set = gb_gpio_set; gpio->set_config = gb_gpio_set_config; - gpio->to_irq = gb_gpio_to_irq; gpio->base = -1; /* Allocate base dynamically */ gpio->ngpio = ggc->line_max + 1; gpio->can_sleep = true; @@ -703,24 +568,24 @@ static int gb_gpio_probe(struct gbphy_device *gbphy_dev, if (ret) goto exit_line_free; - ret = gb_gpio_irqchip_add(gpio, irqc, 0, - handle_level_irq, IRQ_TYPE_NONE); + ret = gpiochip_add(gpio); if (ret) { - dev_err(&gbphy_dev->dev, "failed to add irq chip: %d\n", ret); + dev_err(&gbphy_dev->dev, "failed to add gpio chip: %d\n", ret); goto exit_line_free; } - ret = gpiochip_add(gpio); + ret = gpiochip_irqchip_add(gpio, irqc, 0, handle_level_irq, + IRQ_TYPE_NONE); if (ret) { - dev_err(&gbphy_dev->dev, "failed to add gpio chip: %d\n", ret); - goto exit_gpio_irqchip_remove; + dev_err(&gbphy_dev->dev, "failed to add irq chip: %d\n", ret); + goto exit_gpiochip_remove; } gbphy_runtime_put_autosuspend(gbphy_dev); return 0; -exit_gpio_irqchip_remove: - gb_gpio_irqchip_remove(ggc); +exit_gpiochip_remove: + gpiochip_remove(gpio); exit_line_free: kfree(ggc->lines); exit_connection_disable: @@ -744,7 +609,6 @@ static void gb_gpio_remove(struct gbphy_device *gbphy_dev) gb_connection_disable_rx(connection); gpiochip_remove(&ggc->chip); - gb_gpio_irqchip_remove(ggc); gb_connection_disable(connection); gb_connection_destroy(connection); kfree(ggc->lines); diff --git a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c index fa8b27e091a2..3e154562c64d 100644 --- a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c +++ b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c @@ -1,14 +1,4 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ +// SPDX-License-Identifier: GPL-2.0+ #include <linux/kernel.h> #include <linux/init.h> diff --git a/drivers/staging/gs_fpgaboot/gs_fpgaboot.h b/drivers/staging/gs_fpgaboot/gs_fpgaboot.h index 986e841f6b5e..5cf12c14cca4 100644 --- a/drivers/staging/gs_fpgaboot/gs_fpgaboot.h +++ b/drivers/staging/gs_fpgaboot/gs_fpgaboot.h @@ -1,14 +1,4 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ +/* SPDX-License-Identifier: GPL-2.0+ */ #include <linux/firmware.h> diff --git a/drivers/staging/gs_fpgaboot/io.c b/drivers/staging/gs_fpgaboot/io.c index 83a13ca7259a..80903ec36b76 100644 --- a/drivers/staging/gs_fpgaboot/io.c +++ b/drivers/staging/gs_fpgaboot/io.c @@ -1,15 +1,4 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ +// SPDX-License-Identifier: GPL-2.0+ #include <linux/kernel.h> #include <linux/init.h> @@ -50,8 +39,7 @@ int xl_supported_prog_bus_width(enum wbus bus_bytes) case bus_2byte: break; default: - pr_err("unsupported program bus width %d\n", - bus_bytes); + pr_err("unsupported program bus width %d\n", bus_bytes); return 0; } diff --git a/drivers/staging/gs_fpgaboot/io.h b/drivers/staging/gs_fpgaboot/io.h index bc5d99cbda8f..9bd86a92e90f 100644 --- a/drivers/staging/gs_fpgaboot/io.h +++ b/drivers/staging/gs_fpgaboot/io.h @@ -1,14 +1,4 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ +/* SPDX-License-Identifier: GPL-2.0+ */ #define GPDIR 0 #define GPCFG 4 /* open drain or not */ diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index fc23059f1673..7a93d3a5c113 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -3,40 +3,6 @@ # menu "Analog to digital converters" -config AD7606 - tristate "Analog Devices AD7606 ADC driver" - depends on GPIOLIB || COMPILE_TEST - depends on HAS_IOMEM - select IIO_BUFFER - select IIO_TRIGGERED_BUFFER - help - Say yes here to build support for Analog Devices: - ad7605-4, ad7606, ad7606-6, ad7606-4 analog to digital converters (ADC). - - To compile this driver as a module, choose M here: the - module will be called ad7606. - -config AD7606_IFACE_PARALLEL - tristate "parallel interface support" - depends on AD7606 - help - Say yes here to include parallel interface support on the AD7606 - ADC driver. - - To compile this driver as a module, choose M here: the - module will be called ad7606_parallel. - -config AD7606_IFACE_SPI - tristate "spi interface support" - depends on AD7606 - depends on SPI - help - Say yes here to include parallel interface support on the AD7606 - ADC driver. - - To compile this driver as a module, choose M here: the - module will be called ad7606_spi. - config AD7780 tristate "Analog Devices AD7780 and similar ADCs driver" depends on SPI diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index ebe83c1ad362..7a421088ff82 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -3,10 +3,6 @@ # Makefile for industrial I/O ADC drivers # -obj-$(CONFIG_AD7606_IFACE_PARALLEL) += ad7606_par.o -obj-$(CONFIG_AD7606_IFACE_SPI) += ad7606_spi.o -obj-$(CONFIG_AD7606) += ad7606.o - obj-$(CONFIG_AD7780) += ad7780.o obj-$(CONFIG_AD7816) += ad7816.o obj-$(CONFIG_AD7192) += ad7192.o diff --git a/drivers/staging/iio/adc/ad7280a.c b/drivers/staging/iio/adc/ad7280a.c index 14f6a3ced060..d9df12665176 100644 --- a/drivers/staging/iio/adc/ad7280a.c +++ b/drivers/staging/iio/adc/ad7280a.c @@ -97,6 +97,10 @@ #define AD7280A_NUM_CH (AD7280A_AUX_ADC_6 - \ AD7280A_CELL_VOLTAGE_1 + 1) +#define AD7280A_CALC_VOLTAGE_CHAN_NUM(d, c) ((d * AD7280A_CELLS_PER_DEV) + c) +#define AD7280A_CALC_TEMP_CHAN_NUM(d, c) ((d * AD7280A_CELLS_PER_DEV) + \ + c - AD7280A_CELLS_PER_DEV) + #define AD7280A_DEVADDR_MASTER 0 #define AD7280A_DEVADDR_ALL 0x1F /* 5-bit device address is sent LSB first */ @@ -496,72 +500,171 @@ static const struct attribute_group ad7280_attrs_group = { .attrs = ad7280_attributes, }; +static void ad7280_voltage_channel_init(struct iio_chan_spec *chan, int i) +{ + chan->type = IIO_VOLTAGE; + chan->differential = 1; + chan->channel = i; + chan->channel2 = chan->channel + 1; +} + +static void ad7280_temp_channel_init(struct iio_chan_spec *chan, int i) +{ + chan->type = IIO_TEMP; + chan->channel = i; +} + +static void ad7280_common_fields_init(struct iio_chan_spec *chan, int addr, + int cnt) +{ + chan->indexed = 1; + chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW); + chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE); + chan->address = addr; + chan->scan_index = cnt; + chan->scan_type.sign = 'u'; + chan->scan_type.realbits = 12; + chan->scan_type.storagebits = 32; +} + +static void ad7280_total_voltage_channel_init(struct iio_chan_spec *chan, + int cnt, int dev) +{ + chan->type = IIO_VOLTAGE; + chan->differential = 1; + chan->channel = 0; + chan->channel2 = dev * AD7280A_CELLS_PER_DEV; + chan->address = AD7280A_ALL_CELLS; + chan->indexed = 1; + chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW); + chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE); + chan->scan_index = cnt; + chan->scan_type.sign = 'u'; + chan->scan_type.realbits = 32; + chan->scan_type.storagebits = 32; +} + +static void ad7280_timestamp_channel_init(struct iio_chan_spec *chan, int cnt) +{ + chan->type = IIO_TIMESTAMP; + chan->channel = -1; + chan->scan_index = cnt; + chan->scan_type.sign = 's'; + chan->scan_type.realbits = 64; + chan->scan_type.storagebits = 64; +} + +static void ad7280_init_dev_channels(struct ad7280_state *st, int dev, int *cnt) +{ + int addr, ch, i; + struct iio_chan_spec *chan; + + for (ch = AD7280A_CELL_VOLTAGE_1; ch <= AD7280A_AUX_ADC_6; ch++) { + chan = &st->channels[*cnt]; + + if (ch < AD7280A_AUX_ADC_1) { + i = AD7280A_CALC_VOLTAGE_CHAN_NUM(dev, ch); + ad7280_voltage_channel_init(chan, i); + } else { + i = AD7280A_CALC_TEMP_CHAN_NUM(dev, ch); + ad7280_temp_channel_init(chan, i); + } + + addr = ad7280a_devaddr(dev) << 8 | ch; + ad7280_common_fields_init(chan, addr, *cnt); + + (*cnt)++; + } +} + static int ad7280_channel_init(struct ad7280_state *st) { - int dev, ch, cnt; + int dev, cnt = 0; st->channels = devm_kcalloc(&st->spi->dev, (st->slave_num + 1) * 12 + 2, sizeof(*st->channels), GFP_KERNEL); if (!st->channels) return -ENOMEM; - for (dev = 0, cnt = 0; dev <= st->slave_num; dev++) - for (ch = AD7280A_CELL_VOLTAGE_1; ch <= AD7280A_AUX_ADC_6; - ch++, cnt++) { - if (ch < AD7280A_AUX_ADC_1) { - st->channels[cnt].type = IIO_VOLTAGE; - st->channels[cnt].differential = 1; - st->channels[cnt].channel = (dev * 6) + ch; - st->channels[cnt].channel2 = - st->channels[cnt].channel + 1; - } else { - st->channels[cnt].type = IIO_TEMP; - st->channels[cnt].channel = (dev * 6) + ch - 6; - } - st->channels[cnt].indexed = 1; - st->channels[cnt].info_mask_separate = - BIT(IIO_CHAN_INFO_RAW); - st->channels[cnt].info_mask_shared_by_type = - BIT(IIO_CHAN_INFO_SCALE); - st->channels[cnt].address = - ad7280a_devaddr(dev) << 8 | ch; - st->channels[cnt].scan_index = cnt; - st->channels[cnt].scan_type.sign = 'u'; - st->channels[cnt].scan_type.realbits = 12; - st->channels[cnt].scan_type.storagebits = 32; - st->channels[cnt].scan_type.shift = 0; - } + for (dev = 0; dev <= st->slave_num; dev++) + ad7280_init_dev_channels(st, dev, &cnt); - st->channels[cnt].type = IIO_VOLTAGE; - st->channels[cnt].differential = 1; - st->channels[cnt].channel = 0; - st->channels[cnt].channel2 = dev * 6; - st->channels[cnt].address = AD7280A_ALL_CELLS; - st->channels[cnt].indexed = 1; - st->channels[cnt].info_mask_separate = BIT(IIO_CHAN_INFO_RAW); - st->channels[cnt].info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE); - st->channels[cnt].scan_index = cnt; - st->channels[cnt].scan_type.sign = 'u'; - st->channels[cnt].scan_type.realbits = 32; - st->channels[cnt].scan_type.storagebits = 32; - st->channels[cnt].scan_type.shift = 0; + ad7280_total_voltage_channel_init(&st->channels[cnt], cnt, dev); cnt++; - st->channels[cnt].type = IIO_TIMESTAMP; - st->channels[cnt].channel = -1; - st->channels[cnt].scan_index = cnt; - st->channels[cnt].scan_type.sign = 's'; - st->channels[cnt].scan_type.realbits = 64; - st->channels[cnt].scan_type.storagebits = 64; - st->channels[cnt].scan_type.shift = 0; + ad7280_timestamp_channel_init(&st->channels[cnt], cnt); return cnt + 1; } -static int ad7280_attr_init(struct ad7280_state *st) +static int ad7280_balance_switch_attr_init(struct iio_dev_attr *attr, + struct device *dev, int addr, int i) { - int dev, ch, cnt; - unsigned int index; + attr->address = addr; + attr->dev_attr.attr.mode = 0644; + attr->dev_attr.show = ad7280_show_balance_sw; + attr->dev_attr.store = ad7280_store_balance_sw; + attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, + "in%d-in%d_balance_switch_en", + i, i + 1); + if (!attr->dev_attr.attr.name) + return -ENOMEM; + + return 0; +} + +static int ad7280_balance_timer_attr_init(struct iio_dev_attr *attr, + struct device *dev, int addr, int i) +{ + attr->address = addr; + attr->dev_attr.attr.mode = 0644; + attr->dev_attr.show = ad7280_show_balance_timer; + attr->dev_attr.store = ad7280_store_balance_timer; + attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, + "in%d-in%d_balance_timer", + i, i + 1); + if (!attr->dev_attr.attr.name) + return -ENOMEM; + + return 0; +} + +static int ad7280_init_dev_attrs(struct ad7280_state *st, int dev, int *cnt) +{ + int addr, ch, i, ret; struct iio_dev_attr *iio_attr; + struct device *sdev = &st->spi->dev; + + for (ch = AD7280A_CELL_VOLTAGE_1; ch <= AD7280A_CELL_VOLTAGE_6; ch++) { + iio_attr = &st->iio_attr[*cnt]; + addr = ad7280a_devaddr(dev) << 8 | ch; + i = dev * AD7280A_CELLS_PER_DEV + ch; + + ret = ad7280_balance_switch_attr_init(iio_attr, sdev, addr, i); + if (ret < 0) + return ret; + + ad7280_attributes[*cnt] = &iio_attr->dev_attr.attr; + + (*cnt)++; + iio_attr = &st->iio_attr[*cnt]; + addr = ad7280a_devaddr(dev) << 8 | (AD7280A_CB1_TIMER + ch); + + ret = ad7280_balance_timer_attr_init(iio_attr, sdev, addr, i); + if (ret < 0) + return ret; + + ad7280_attributes[*cnt] = &iio_attr->dev_attr.attr; + (*cnt)++; + } + + ad7280_attributes[*cnt] = NULL; + + return 0; +} + +static int ad7280_attr_init(struct ad7280_state *st) +{ + int dev, cnt = 0, ret; st->iio_attr = devm_kcalloc(&st->spi->dev, 2, sizeof(*st->iio_attr) * (st->slave_num + 1) * AD7280A_CELLS_PER_DEV, @@ -569,41 +672,11 @@ static int ad7280_attr_init(struct ad7280_state *st) if (!st->iio_attr) return -ENOMEM; - for (dev = 0, cnt = 0; dev <= st->slave_num; dev++) - for (ch = AD7280A_CELL_VOLTAGE_1; ch <= AD7280A_CELL_VOLTAGE_6; - ch++, cnt++) { - iio_attr = &st->iio_attr[cnt]; - index = dev * AD7280A_CELLS_PER_DEV + ch; - iio_attr->address = ad7280a_devaddr(dev) << 8 | ch; - iio_attr->dev_attr.attr.mode = 0644; - iio_attr->dev_attr.show = ad7280_show_balance_sw; - iio_attr->dev_attr.store = ad7280_store_balance_sw; - iio_attr->dev_attr.attr.name = - devm_kasprintf(&st->spi->dev, GFP_KERNEL, - "in%d-in%d_balance_switch_en", - index, index + 1); - if (!iio_attr->dev_attr.attr.name) - return -ENOMEM; - - ad7280_attributes[cnt] = &iio_attr->dev_attr.attr; - cnt++; - iio_attr = &st->iio_attr[cnt]; - iio_attr->address = ad7280a_devaddr(dev) << 8 | - (AD7280A_CB1_TIMER + ch); - iio_attr->dev_attr.attr.mode = 0644; - iio_attr->dev_attr.show = ad7280_show_balance_timer; - iio_attr->dev_attr.store = ad7280_store_balance_timer; - iio_attr->dev_attr.attr.name = - devm_kasprintf(&st->spi->dev, GFP_KERNEL, - "in%d-in%d_balance_timer", - index, index + 1); - if (!iio_attr->dev_attr.attr.name) - return -ENOMEM; - - ad7280_attributes[cnt] = &iio_attr->dev_attr.attr; - } - - ad7280_attributes[cnt] = NULL; + for (dev = 0; dev <= st->slave_num; dev++) { + ret = ad7280_init_dev_attrs(st, dev, &cnt); + if (ret < 0) + return ret; + } return 0; } diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c index 5209651a1b25..ee50e7296795 100644 --- a/drivers/staging/iio/adc/ad7816.c +++ b/drivers/staging/iio/adc/ad7816.c @@ -65,7 +65,7 @@ enum ad7816_type { static int ad7816_spi_read(struct ad7816_chip_info *chip, u16 *data) { struct spi_device *spi_dev = chip->spi_dev; - int ret = 0; + int ret; __be16 buf; gpiod_set_value(chip->rdwr_pin, 1); @@ -106,7 +106,7 @@ static int ad7816_spi_read(struct ad7816_chip_info *chip, u16 *data) static int ad7816_spi_write(struct ad7816_chip_info *chip, u8 data) { struct spi_device *spi_dev = chip->spi_dev; - int ret = 0; + int ret; gpiod_set_value(chip->rdwr_pin, 1); gpiod_set_value(chip->rdwr_pin, 0); @@ -354,8 +354,7 @@ static int ad7816_probe(struct spi_device *spi_dev) { struct ad7816_chip_info *chip; struct iio_dev *indio_dev; - int ret = 0; - int i; + int i, ret; indio_dev = devm_iio_device_alloc(&spi_dev->dev, sizeof(*chip)); if (!indio_dev) diff --git a/drivers/staging/iio/addac/adt7316-i2c.c b/drivers/staging/iio/addac/adt7316-i2c.c index 2d51bd425662..0f26bc38edc6 100644 --- a/drivers/staging/iio/addac/adt7316-i2c.c +++ b/drivers/staging/iio/addac/adt7316-i2c.c @@ -43,7 +43,7 @@ static int adt7316_i2c_read(void *client, u8 reg, u8 *data) static int adt7316_i2c_write(void *client, u8 reg, u8 data) { struct i2c_client *cl = client; - int ret = 0; + int ret; ret = i2c_smbus_write_byte_data(cl, reg, data); if (ret < 0) @@ -55,7 +55,7 @@ static int adt7316_i2c_write(void *client, u8 reg, u8 data) static int adt7316_i2c_multi_read(void *client, u8 reg, u8 count, u8 *data) { struct i2c_client *cl = client; - int i, ret = 0; + int i, ret; if (count > ADT7316_REG_MAX_ADDR) count = ADT7316_REG_MAX_ADDR; @@ -74,7 +74,7 @@ static int adt7316_i2c_multi_read(void *client, u8 reg, u8 count, u8 *data) static int adt7316_i2c_multi_write(void *client, u8 reg, u8 count, u8 *data) { struct i2c_client *cl = client; - int i, ret = 0; + int i, ret; if (count > ADT7316_REG_MAX_ADDR) count = ADT7316_REG_MAX_ADDR; diff --git a/drivers/staging/iio/addac/adt7316-spi.c b/drivers/staging/iio/addac/adt7316-spi.c index e75827e326a6..8294b9c1e3c2 100644 --- a/drivers/staging/iio/addac/adt7316-spi.c +++ b/drivers/staging/iio/addac/adt7316-spi.c @@ -27,7 +27,7 @@ static int adt7316_spi_multi_read(void *client, u8 reg, u8 count, u8 *data) { struct spi_device *spi_dev = client; u8 cmd[2]; - int ret = 0; + int ret; if (count > ADT7316_REG_MAX_ADDR) count = ADT7316_REG_MAX_ADDR; @@ -56,7 +56,7 @@ static int adt7316_spi_multi_write(void *client, u8 reg, u8 count, u8 *data) { struct spi_device *spi_dev = client; u8 buf[ADT7316_REG_MAX_ADDR + 2]; - int i, ret = 0; + int i, ret; if (count > ADT7316_REG_MAX_ADDR) count = ADT7316_REG_MAX_ADDR; diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c index dc93e85808e0..6f7891b567b9 100644 --- a/drivers/staging/iio/addac/adt7316.c +++ b/drivers/staging/iio/addac/adt7316.c @@ -47,6 +47,8 @@ #define ADT7516_MSB_AIN3 0xA #define ADT7516_MSB_AIN4 0xB #define ADT7316_DA_DATA_BASE 0x10 +#define ADT7316_DA_10_BIT_LSB_SHIFT 6 +#define ADT7316_DA_12_BIT_LSB_SHIFT 4 #define ADT7316_DA_MSB_DATA_REGS 4 #define ADT7316_LSB_DAC_A 0x10 #define ADT7316_MSB_DAC_A 0x11 @@ -59,8 +61,8 @@ #define ADT7316_CONFIG1 0x18 #define ADT7316_CONFIG2 0x19 #define ADT7316_CONFIG3 0x1A -#define ADT7316_LDAC_CONFIG 0x1B -#define ADT7316_DAC_CONFIG 0x1C +#define ADT7316_DAC_CONFIG 0x1B +#define ADT7316_LDAC_CONFIG 0x1C #define ADT7316_INT_MASK1 0x1D #define ADT7316_INT_MASK2 0x1E #define ADT7316_IN_TEMP_OFFSET 0x1F @@ -117,7 +119,7 @@ */ #define ADT7316_ADCLK_22_5 0x1 #define ADT7316_DA_HIGH_RESOLUTION 0x2 -#define ADT7316_DA_EN_VIA_DAC_LDCA 0x4 +#define ADT7316_DA_EN_VIA_DAC_LDAC 0x8 #define ADT7516_AIN_IN_VREF 0x10 #define ADT7316_EN_IN_TEMP_PROP_DACA 0x20 #define ADT7316_EN_EX_TEMP_PROP_DACB 0x40 @@ -127,6 +129,7 @@ */ #define ADT7316_DA_2VREF_CH_MASK 0xF #define ADT7316_DA_EN_MODE_MASK 0x30 +#define ADT7316_DA_EN_MODE_SHIFT 4 #define ADT7316_DA_EN_MODE_SINGLE 0x00 #define ADT7316_DA_EN_MODE_AB_CD 0x10 #define ADT7316_DA_EN_MODE_ABCD 0x20 @@ -632,9 +635,7 @@ static ssize_t adt7316_show_da_high_resolution(struct device *dev, struct adt7316_chip_info *chip = iio_priv(dev_info); if (chip->config3 & ADT7316_DA_HIGH_RESOLUTION) { - if (chip->id == ID_ADT7316 || chip->id == ID_ADT7516) - return sprintf(buf, "1 (12 bits)\n"); - if (chip->id == ID_ADT7317 || chip->id == ID_ADT7517) + if (chip->id != ID_ADT7318 && chip->id != ID_ADT7519) return sprintf(buf, "1 (10 bits)\n"); } @@ -651,17 +652,12 @@ static ssize_t adt7316_store_da_high_resolution(struct device *dev, u8 config3; int ret; - chip->dac_bits = 8; + if (chip->id == ID_ADT7318 || chip->id == ID_ADT7519) + return -EPERM; - if (buf[0] == '1') { - config3 = chip->config3 | ADT7316_DA_HIGH_RESOLUTION; - if (chip->id == ID_ADT7316 || chip->id == ID_ADT7516) - chip->dac_bits = 12; - else if (chip->id == ID_ADT7317 || chip->id == ID_ADT7517) - chip->dac_bits = 10; - } else { - config3 = chip->config3 & (~ADT7316_DA_HIGH_RESOLUTION); - } + config3 = chip->config3 & (~ADT7316_DA_HIGH_RESOLUTION); + if (buf[0] == '1') + config3 |= ADT7316_DA_HIGH_RESOLUTION; ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, config3); if (ret) @@ -851,7 +847,7 @@ static ssize_t adt7316_show_DAC_update_mode(struct device *dev, struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); - if (!(chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA)) + if (!(chip->config3 & ADT7316_DA_EN_VIA_DAC_LDAC)) return sprintf(buf, "manual\n"); switch (chip->dac_config & ADT7316_DA_EN_MODE_MASK) { @@ -880,15 +876,15 @@ static ssize_t adt7316_store_DAC_update_mode(struct device *dev, u8 data; int ret; - if (!(chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA)) + if (!(chip->config3 & ADT7316_DA_EN_VIA_DAC_LDAC)) return -EPERM; ret = kstrtou8(buf, 10, &data); - if (ret || data > ADT7316_DA_EN_MODE_MASK) + if (ret || data > (ADT7316_DA_EN_MODE_MASK >> ADT7316_DA_EN_MODE_SHIFT)) return -EINVAL; dac_config = chip->dac_config & (~ADT7316_DA_EN_MODE_MASK); - dac_config |= data; + dac_config |= data << ADT7316_DA_EN_MODE_SHIFT; ret = chip->bus.write(chip->bus.client, ADT7316_DAC_CONFIG, dac_config); if (ret) @@ -911,7 +907,7 @@ static ssize_t adt7316_show_all_DAC_update_modes(struct device *dev, struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); - if (chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA) + if (chip->config3 & ADT7316_DA_EN_VIA_DAC_LDAC) return sprintf(buf, "0 - auto at any MSB DAC writing\n" "1 - auto at MSB DAC AB and CD writing\n" "2 - auto at MSB DAC ABCD writing\n" @@ -933,7 +929,7 @@ static ssize_t adt7316_store_update_DAC(struct device *dev, u8 data; int ret; - if (chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA) { + if (chip->config3 & ADT7316_DA_EN_VIA_DAC_LDAC) { if ((chip->dac_config & ADT7316_DA_EN_MODE_MASK) != ADT7316_DA_EN_MODE_LDAC) return -EPERM; @@ -969,9 +965,6 @@ static ssize_t adt7316_show_DA_AB_Vref_bypass(struct device *dev, struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); - if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) - return -EPERM; - return sprintf(buf, "%d\n", !!(chip->dac_config & ADT7316_VREF_BYPASS_DAC_AB)); } @@ -986,9 +979,6 @@ static ssize_t adt7316_store_DA_AB_Vref_bypass(struct device *dev, u8 dac_config; int ret; - if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) - return -EPERM; - dac_config = chip->dac_config & (~ADT7316_VREF_BYPASS_DAC_AB); if (buf[0] == '1') dac_config |= ADT7316_VREF_BYPASS_DAC_AB; @@ -1014,9 +1004,6 @@ static ssize_t adt7316_show_DA_CD_Vref_bypass(struct device *dev, struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); - if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) - return -EPERM; - return sprintf(buf, "%d\n", !!(chip->dac_config & ADT7316_VREF_BYPASS_DAC_CD)); } @@ -1031,9 +1018,6 @@ static ssize_t adt7316_store_DA_CD_Vref_bypass(struct device *dev, u8 dac_config; int ret; - if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) - return -EPERM; - dac_config = chip->dac_config & (~ADT7316_VREF_BYPASS_DAC_CD); if (buf[0] == '1') dac_config |= ADT7316_VREF_BYPASS_DAC_CD; @@ -1061,10 +1045,10 @@ static ssize_t adt7316_show_DAC_internal_Vref(struct device *dev, if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) return sprintf(buf, "0x%x\n", - (chip->dac_config & ADT7516_DAC_IN_VREF_MASK) >> + (chip->ldac_config & ADT7516_DAC_IN_VREF_MASK) >> ADT7516_DAC_IN_VREF_OFFSET); return sprintf(buf, "%d\n", - !!(chip->dac_config & ADT7316_DAC_IN_VREF)); + !!(chip->ldac_config & ADT7316_DAC_IN_VREF)); } static ssize_t adt7316_store_DAC_internal_Vref(struct device *dev, @@ -1086,7 +1070,7 @@ static ssize_t adt7316_store_DAC_internal_Vref(struct device *dev, ldac_config = chip->ldac_config & (~ADT7516_DAC_IN_VREF_MASK); if (data & 0x1) ldac_config |= ADT7516_DAC_AB_IN_VREF; - else if (data & 0x2) + if (data & 0x2) ldac_config |= ADT7516_DAC_CD_IN_VREF; } else { ret = kstrtou8(buf, 16, &data); @@ -1410,7 +1394,7 @@ static IIO_DEVICE_ATTR(ex_analog_temp_offset, 0644, static ssize_t adt7316_show_DAC(struct adt7316_chip_info *chip, int channel, char *buf) { - u16 data; + u16 data = 0; u8 msb, lsb, offset; int ret; @@ -1435,7 +1419,11 @@ static ssize_t adt7316_show_DAC(struct adt7316_chip_info *chip, if (ret) return -EIO; - data = (msb << offset) + (lsb & ((1 << offset) - 1)); + if (chip->dac_bits == 12) + data = lsb >> ADT7316_DA_12_BIT_LSB_SHIFT; + else if (chip->dac_bits == 10) + data = lsb >> ADT7316_DA_10_BIT_LSB_SHIFT; + data |= msb << offset; return sprintf(buf, "%d\n", data); } @@ -1443,7 +1431,7 @@ static ssize_t adt7316_show_DAC(struct adt7316_chip_info *chip, static ssize_t adt7316_store_DAC(struct adt7316_chip_info *chip, int channel, const char *buf, size_t len) { - u8 msb, lsb, offset; + u8 msb, lsb, lsb_reg, offset; u16 data; int ret; @@ -1461,9 +1449,13 @@ static ssize_t adt7316_store_DAC(struct adt7316_chip_info *chip, return -EINVAL; if (chip->dac_bits > 8) { - lsb = data & (1 << offset); + lsb = data & ((1 << offset) - 1); + if (chip->dac_bits == 12) + lsb_reg = lsb << ADT7316_DA_12_BIT_LSB_SHIFT; + else + lsb_reg = lsb << ADT7316_DA_10_BIT_LSB_SHIFT; ret = chip->bus.write(chip->bus.client, - ADT7316_DA_DATA_BASE + channel * 2, lsb); + ADT7316_DA_DATA_BASE + channel * 2, lsb_reg); if (ret) return -EIO; } @@ -1710,8 +1702,6 @@ static struct attribute *adt7516_attributes[] = { &iio_dev_attr_DAC_update_mode.dev_attr.attr, &iio_dev_attr_all_DAC_update_modes.dev_attr.attr, &iio_dev_attr_update_DAC.dev_attr.attr, - &iio_dev_attr_DA_AB_Vref_bypass.dev_attr.attr, - &iio_dev_attr_DA_CD_Vref_bypass.dev_attr.attr, &iio_dev_attr_DAC_internal_Vref.dev_attr.attr, &iio_dev_attr_VDD.dev_attr.attr, &iio_dev_attr_in_temp.dev_attr.attr, @@ -1809,6 +1799,43 @@ static irqreturn_t adt7316_event_handler(int irq, void *private) return IRQ_HANDLED; } +static int adt7316_setup_irq(struct iio_dev *indio_dev) +{ + struct adt7316_chip_info *chip = iio_priv(indio_dev); + int irq_type, ret; + + irq_type = irqd_get_trigger_type(irq_get_irq_data(chip->bus.irq)); + + switch (irq_type) { + case IRQF_TRIGGER_HIGH: + case IRQF_TRIGGER_RISING: + break; + case IRQF_TRIGGER_LOW: + case IRQF_TRIGGER_FALLING: + break; + default: + dev_info(&indio_dev->dev, "mode %d unsupported, using IRQF_TRIGGER_LOW\n", + irq_type); + irq_type = IRQF_TRIGGER_LOW; + break; + } + + ret = devm_request_threaded_irq(&indio_dev->dev, chip->bus.irq, + NULL, adt7316_event_handler, + irq_type | IRQF_ONESHOT, + indio_dev->name, indio_dev); + if (ret) { + dev_err(&indio_dev->dev, "failed to request irq %d\n", + chip->bus.irq); + return ret; + } + + if (irq_type & IRQF_TRIGGER_HIGH) + chip->config1 |= ADT7316_INT_POLARITY; + + return 0; +} + /* * Show mask of enabled interrupts in Hex. */ @@ -2103,9 +2130,7 @@ int adt7316_probe(struct device *dev, struct adt7316_bus *bus, { struct adt7316_chip_info *chip; struct iio_dev *indio_dev; - unsigned short *adt7316_platform_data = dev->platform_data; - int irq_type = IRQF_TRIGGER_LOW; - int ret = 0; + int ret; indio_dev = devm_iio_device_alloc(dev, sizeof(*chip)); if (!indio_dev) @@ -2123,6 +2148,13 @@ int adt7316_probe(struct device *dev, struct adt7316_bus *bus, else return -ENODEV; + if (chip->id == ID_ADT7316 || chip->id == ID_ADT7516) + chip->dac_bits = 12; + else if (chip->id == ID_ADT7317 || chip->id == ID_ADT7517) + chip->dac_bits = 10; + else + chip->dac_bits = 8; + chip->ldac_pin = devm_gpiod_get_optional(dev, "adi,ldac", GPIOD_OUT_LOW); if (IS_ERR(chip->ldac_pin)) { ret = PTR_ERR(chip->ldac_pin); @@ -2130,8 +2162,8 @@ int adt7316_probe(struct device *dev, struct adt7316_bus *bus, return ret; } - if (chip->ldac_pin) { - chip->config3 |= ADT7316_DA_EN_VIA_DAC_LDCA; + if (!chip->ldac_pin) { + chip->config3 |= ADT7316_DA_EN_VIA_DAC_LDAC; if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) chip->config1 |= ADT7516_SEL_AIN3; } @@ -2148,20 +2180,9 @@ int adt7316_probe(struct device *dev, struct adt7316_bus *bus, indio_dev->modes = INDIO_DIRECT_MODE; if (chip->bus.irq > 0) { - if (adt7316_platform_data[0]) - irq_type = adt7316_platform_data[0]; - - ret = devm_request_threaded_irq(dev, chip->bus.irq, - NULL, - adt7316_event_handler, - irq_type | IRQF_ONESHOT, - indio_dev->name, - indio_dev); + ret = adt7316_setup_irq(indio_dev); if (ret) return ret; - - if (irq_type & IRQF_TRIGGER_HIGH) - chip->config1 |= ADT7316_INT_POLARITY; } ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, chip->config1); diff --git a/drivers/staging/iio/cdc/Kconfig b/drivers/staging/iio/cdc/Kconfig index 80211df8c577..b97478e7cbd0 100644 --- a/drivers/staging/iio/cdc/Kconfig +++ b/drivers/staging/iio/cdc/Kconfig @@ -13,16 +13,6 @@ config AD7150 To compile this driver as a module, choose M here: the module will be called ad7150. -config AD7152 - tristate "Analog Devices ad7152/3 capacitive sensor driver" - depends on I2C - help - Say yes here to build support for Analog Devices capacitive sensors. - (ad7152, ad7153) Provides direct access via sysfs. - - To compile this driver as a module, choose M here: the - module will be called ad7152. - config AD7746 tristate "Analog Devices AD7745, AD7746 AD7747 capacitive sensor driver" depends on I2C diff --git a/drivers/staging/iio/cdc/Makefile b/drivers/staging/iio/cdc/Makefile index a5fbabf5c8bf..1466bc31f244 100644 --- a/drivers/staging/iio/cdc/Makefile +++ b/drivers/staging/iio/cdc/Makefile @@ -3,5 +3,4 @@ # obj-$(CONFIG_AD7150) += ad7150.o -obj-$(CONFIG_AD7152) += ad7152.o obj-$(CONFIG_AD7746) += ad7746.o diff --git a/drivers/staging/iio/cdc/ad7152.c b/drivers/staging/iio/cdc/ad7152.c deleted file mode 100644 index 25f51db05d2d..000000000000 --- a/drivers/staging/iio/cdc/ad7152.c +++ /dev/null @@ -1,552 +0,0 @@ -/* - * AD7152 capacitive sensor driver supporting AD7152/3 - * - * Copyright 2010-2011a Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#include <linux/interrupt.h> -#include <linux/device.h> -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/sysfs.h> -#include <linux/i2c.h> -#include <linux/module.h> -#include <linux/delay.h> - -#include <linux/iio/iio.h> -#include <linux/iio/sysfs.h> - -/* - * TODO: Check compliance of calibbias with abi (units) - */ -/* - * AD7152 registers definition - */ - -#define AD7152_REG_STATUS 0 -#define AD7152_REG_CH1_DATA_HIGH 1 -#define AD7152_REG_CH2_DATA_HIGH 3 -#define AD7152_REG_CH1_OFFS_HIGH 5 -#define AD7152_REG_CH2_OFFS_HIGH 7 -#define AD7152_REG_CH1_GAIN_HIGH 9 -#define AD7152_REG_CH1_SETUP 11 -#define AD7152_REG_CH2_GAIN_HIGH 12 -#define AD7152_REG_CH2_SETUP 14 -#define AD7152_REG_CFG 15 -#define AD7152_REG_RESEVERD 16 -#define AD7152_REG_CAPDAC_POS 17 -#define AD7152_REG_CAPDAC_NEG 18 -#define AD7152_REG_CFG2 26 - -/* Status Register Bit Designations (AD7152_REG_STATUS) */ -#define AD7152_STATUS_RDY1 BIT(0) -#define AD7152_STATUS_RDY2 BIT(1) -#define AD7152_STATUS_C1C2 BIT(2) -#define AD7152_STATUS_PWDN BIT(7) - -/* Setup Register Bit Designations (AD7152_REG_CHx_SETUP) */ -#define AD7152_SETUP_CAPDIFF BIT(5) -#define AD7152_SETUP_RANGE_2pF (0 << 6) -#define AD7152_SETUP_RANGE_0_5pF (1 << 6) -#define AD7152_SETUP_RANGE_1pF (2 << 6) -#define AD7152_SETUP_RANGE_4pF (3 << 6) -#define AD7152_SETUP_RANGE(x) ((x) << 6) - -/* Config Register Bit Designations (AD7152_REG_CFG) */ -#define AD7152_CONF_CH2EN BIT(3) -#define AD7152_CONF_CH1EN BIT(4) -#define AD7152_CONF_MODE_IDLE (0 << 0) -#define AD7152_CONF_MODE_CONT_CONV (1 << 0) -#define AD7152_CONF_MODE_SINGLE_CONV (2 << 0) -#define AD7152_CONF_MODE_OFFS_CAL (5 << 0) -#define AD7152_CONF_MODE_GAIN_CAL (6 << 0) - -/* Capdac Register Bit Designations (AD7152_REG_CAPDAC_XXX) */ -#define AD7152_CAPDAC_DACEN BIT(7) -#define AD7152_CAPDAC_DACP(x) ((x) & 0x1F) - -/* CFG2 Register Bit Designations (AD7152_REG_CFG2) */ -#define AD7152_CFG2_OSR(x) (((x) & 0x3) << 4) - -enum { - AD7152_DATA, - AD7152_OFFS, - AD7152_GAIN, - AD7152_SETUP -}; - -/* - * struct ad7152_chip_info - chip specific information - */ - -struct ad7152_chip_info { - struct i2c_client *client; - /* - * Capacitive channel digital filter setup; - * conversion time/update rate setup per channel - */ - u8 filter_rate_setup; - u8 setup[2]; - struct mutex state_lock; /* protect hardware state */ -}; - -static inline ssize_t ad7152_start_calib(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len, - u8 regval) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ad7152_chip_info *chip = iio_priv(indio_dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - bool doit; - int ret, timeout = 10; - - ret = strtobool(buf, &doit); - if (ret < 0) - return ret; - - if (!doit) - return 0; - - if (this_attr->address == 0) - regval |= AD7152_CONF_CH1EN; - else - regval |= AD7152_CONF_CH2EN; - - mutex_lock(&chip->state_lock); - ret = i2c_smbus_write_byte_data(chip->client, AD7152_REG_CFG, regval); - if (ret < 0) - goto unlock; - - do { - mdelay(20); - ret = i2c_smbus_read_byte_data(chip->client, AD7152_REG_CFG); - if (ret < 0) - goto unlock; - - } while ((ret == regval) && timeout--); - - mutex_unlock(&chip->state_lock); - return len; - -unlock: - mutex_unlock(&chip->state_lock); - return ret; -} - -static ssize_t ad7152_start_offset_calib(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - return ad7152_start_calib(dev, attr, buf, len, - AD7152_CONF_MODE_OFFS_CAL); -} - -static ssize_t ad7152_start_gain_calib(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - return ad7152_start_calib(dev, attr, buf, len, - AD7152_CONF_MODE_GAIN_CAL); -} - -static IIO_DEVICE_ATTR(in_capacitance0_calibbias_calibration, - 0200, NULL, ad7152_start_offset_calib, 0); -static IIO_DEVICE_ATTR(in_capacitance1_calibbias_calibration, - 0200, NULL, ad7152_start_offset_calib, 1); -static IIO_DEVICE_ATTR(in_capacitance0_calibscale_calibration, - 0200, NULL, ad7152_start_gain_calib, 0); -static IIO_DEVICE_ATTR(in_capacitance1_calibscale_calibration, - 0200, NULL, ad7152_start_gain_calib, 1); - -/* Values are Update Rate (Hz), Conversion Time (ms) + 1*/ -static const unsigned char ad7152_filter_rate_table[][2] = { - {200, 5 + 1}, {50, 20 + 1}, {20, 50 + 1}, {17, 60 + 1}, -}; - -static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("200 50 20 17"); - -static IIO_CONST_ATTR(in_capacitance_scale_available, - "0.000061050 0.000030525 0.000015263 0.000007631"); - -static struct attribute *ad7152_attributes[] = { - &iio_dev_attr_in_capacitance0_calibbias_calibration.dev_attr.attr, - &iio_dev_attr_in_capacitance1_calibbias_calibration.dev_attr.attr, - &iio_dev_attr_in_capacitance0_calibscale_calibration.dev_attr.attr, - &iio_dev_attr_in_capacitance1_calibscale_calibration.dev_attr.attr, - &iio_const_attr_in_capacitance_scale_available.dev_attr.attr, - &iio_const_attr_sampling_frequency_available.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ad7152_attribute_group = { - .attrs = ad7152_attributes, -}; - -static const u8 ad7152_addresses[][4] = { - { AD7152_REG_CH1_DATA_HIGH, AD7152_REG_CH1_OFFS_HIGH, - AD7152_REG_CH1_GAIN_HIGH, AD7152_REG_CH1_SETUP }, - { AD7152_REG_CH2_DATA_HIGH, AD7152_REG_CH2_OFFS_HIGH, - AD7152_REG_CH2_GAIN_HIGH, AD7152_REG_CH2_SETUP }, -}; - -/* Values are nano relative to pf base. */ -static const int ad7152_scale_table[] = { - 30525, 7631, 15263, 61050 -}; - -/** - * read_raw handler for IIO_CHAN_INFO_SAMP_FREQ - * - * lock must be held - **/ -static int ad7152_read_raw_samp_freq(struct device *dev, int *val) -{ - struct ad7152_chip_info *chip = iio_priv(dev_to_iio_dev(dev)); - - *val = ad7152_filter_rate_table[chip->filter_rate_setup][0]; - - return 0; -} - -/** - * write_raw handler for IIO_CHAN_INFO_SAMP_FREQ - * - * lock must be held - **/ -static int ad7152_write_raw_samp_freq(struct device *dev, int val) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ad7152_chip_info *chip = iio_priv(indio_dev); - int ret, i; - - for (i = 0; i < ARRAY_SIZE(ad7152_filter_rate_table); i++) - if (val >= ad7152_filter_rate_table[i][0]) - break; - - if (i >= ARRAY_SIZE(ad7152_filter_rate_table)) - i = ARRAY_SIZE(ad7152_filter_rate_table) - 1; - - ret = i2c_smbus_write_byte_data(chip->client, - AD7152_REG_CFG2, AD7152_CFG2_OSR(i)); - if (ret < 0) - return ret; - - chip->filter_rate_setup = i; - - return ret; -} - -static int ad7152_write_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int val, - int val2, - long mask) -{ - struct ad7152_chip_info *chip = iio_priv(indio_dev); - int ret, i; - - mutex_lock(&chip->state_lock); - - switch (mask) { - case IIO_CHAN_INFO_CALIBSCALE: - if (val != 1) { - ret = -EINVAL; - goto out; - } - - val = (val2 * 1024) / 15625; - - ret = i2c_smbus_write_word_data(chip->client, - ad7152_addresses[chan->channel][AD7152_GAIN], - swab16(val)); - if (ret < 0) - goto out; - - ret = 0; - break; - - case IIO_CHAN_INFO_CALIBBIAS: - if ((val < 0) | (val > 0xFFFF)) { - ret = -EINVAL; - goto out; - } - ret = i2c_smbus_write_word_data(chip->client, - ad7152_addresses[chan->channel][AD7152_OFFS], - swab16(val)); - if (ret < 0) - goto out; - - ret = 0; - break; - case IIO_CHAN_INFO_SCALE: - if (val) { - ret = -EINVAL; - goto out; - } - for (i = 0; i < ARRAY_SIZE(ad7152_scale_table); i++) - if (val2 == ad7152_scale_table[i]) - break; - - chip->setup[chan->channel] &= ~AD7152_SETUP_RANGE_4pF; - chip->setup[chan->channel] |= AD7152_SETUP_RANGE(i); - - ret = i2c_smbus_write_byte_data(chip->client, - ad7152_addresses[chan->channel][AD7152_SETUP], - chip->setup[chan->channel]); - if (ret < 0) - goto out; - - ret = 0; - break; - case IIO_CHAN_INFO_SAMP_FREQ: - if (val2) { - ret = -EINVAL; - goto out; - } - ret = ad7152_write_raw_samp_freq(&indio_dev->dev, val); - if (ret < 0) - goto out; - - ret = 0; - break; - default: - ret = -EINVAL; - } - -out: - mutex_unlock(&chip->state_lock); - return ret; -} - -static int ad7152_read_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int *val, int *val2, - long mask) -{ - struct ad7152_chip_info *chip = iio_priv(indio_dev); - int ret; - u8 regval = 0; - - mutex_lock(&chip->state_lock); - - switch (mask) { - case IIO_CHAN_INFO_RAW: - /* First set whether in differential mode */ - - regval = chip->setup[chan->channel]; - - if (chan->differential) - chip->setup[chan->channel] |= AD7152_SETUP_CAPDIFF; - else - chip->setup[chan->channel] &= ~AD7152_SETUP_CAPDIFF; - - if (regval != chip->setup[chan->channel]) { - ret = i2c_smbus_write_byte_data(chip->client, - ad7152_addresses[chan->channel][AD7152_SETUP], - chip->setup[chan->channel]); - if (ret < 0) - goto out; - } - /* Make sure the channel is enabled */ - if (chan->channel == 0) - regval = AD7152_CONF_CH1EN; - else - regval = AD7152_CONF_CH2EN; - - /* Trigger a single read */ - regval |= AD7152_CONF_MODE_SINGLE_CONV; - ret = i2c_smbus_write_byte_data(chip->client, AD7152_REG_CFG, - regval); - if (ret < 0) - goto out; - - msleep(ad7152_filter_rate_table[chip->filter_rate_setup][1]); - /* Now read the actual register */ - ret = i2c_smbus_read_word_data(chip->client, - ad7152_addresses[chan->channel][AD7152_DATA]); - if (ret < 0) - goto out; - *val = swab16(ret); - - if (chan->differential) - *val -= 0x8000; - - ret = IIO_VAL_INT; - break; - case IIO_CHAN_INFO_CALIBSCALE: - - ret = i2c_smbus_read_word_data(chip->client, - ad7152_addresses[chan->channel][AD7152_GAIN]); - if (ret < 0) - goto out; - /* 1 + gain_val / 2^16 */ - *val = 1; - *val2 = (15625 * swab16(ret)) / 1024; - - ret = IIO_VAL_INT_PLUS_MICRO; - break; - case IIO_CHAN_INFO_CALIBBIAS: - ret = i2c_smbus_read_word_data(chip->client, - ad7152_addresses[chan->channel][AD7152_OFFS]); - if (ret < 0) - goto out; - *val = swab16(ret); - - ret = IIO_VAL_INT; - break; - case IIO_CHAN_INFO_SCALE: - ret = i2c_smbus_read_byte_data(chip->client, - ad7152_addresses[chan->channel][AD7152_SETUP]); - if (ret < 0) - goto out; - *val = 0; - *val2 = ad7152_scale_table[ret >> 6]; - - ret = IIO_VAL_INT_PLUS_NANO; - break; - case IIO_CHAN_INFO_SAMP_FREQ: - ret = ad7152_read_raw_samp_freq(&indio_dev->dev, val); - if (ret < 0) - goto out; - - ret = IIO_VAL_INT; - break; - default: - ret = -EINVAL; - } -out: - mutex_unlock(&chip->state_lock); - return ret; -} - -static int ad7152_write_raw_get_fmt(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - long mask) -{ - switch (mask) { - case IIO_CHAN_INFO_SCALE: - return IIO_VAL_INT_PLUS_NANO; - default: - return IIO_VAL_INT_PLUS_MICRO; - } -} - -static const struct iio_info ad7152_info = { - .attrs = &ad7152_attribute_group, - .read_raw = ad7152_read_raw, - .write_raw = ad7152_write_raw, - .write_raw_get_fmt = ad7152_write_raw_get_fmt, -}; - -static const struct iio_chan_spec ad7152_channels[] = { - { - .type = IIO_CAPACITANCE, - .indexed = 1, - .channel = 0, - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | - BIT(IIO_CHAN_INFO_CALIBSCALE) | - BIT(IIO_CHAN_INFO_CALIBBIAS) | - BIT(IIO_CHAN_INFO_SCALE), - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), - }, { - .type = IIO_CAPACITANCE, - .differential = 1, - .indexed = 1, - .channel = 0, - .channel2 = 2, - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | - BIT(IIO_CHAN_INFO_CALIBSCALE) | - BIT(IIO_CHAN_INFO_CALIBBIAS) | - BIT(IIO_CHAN_INFO_SCALE), - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), - }, { - .type = IIO_CAPACITANCE, - .indexed = 1, - .channel = 1, - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | - BIT(IIO_CHAN_INFO_CALIBSCALE) | - BIT(IIO_CHAN_INFO_CALIBBIAS) | - BIT(IIO_CHAN_INFO_SCALE), - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), - }, { - .type = IIO_CAPACITANCE, - .differential = 1, - .indexed = 1, - .channel = 1, - .channel2 = 3, - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | - BIT(IIO_CHAN_INFO_CALIBSCALE) | - BIT(IIO_CHAN_INFO_CALIBBIAS) | - BIT(IIO_CHAN_INFO_SCALE), - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), - } -}; - -/* - * device probe and remove - */ - -static int ad7152_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - int ret = 0; - struct ad7152_chip_info *chip; - struct iio_dev *indio_dev; - - indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip)); - if (!indio_dev) - return -ENOMEM; - chip = iio_priv(indio_dev); - /* this is only used for device removal purposes */ - i2c_set_clientdata(client, indio_dev); - - chip->client = client; - mutex_init(&chip->state_lock); - - /* Establish that the iio_dev is a child of the i2c device */ - indio_dev->name = id->name; - indio_dev->dev.parent = &client->dev; - indio_dev->info = &ad7152_info; - indio_dev->channels = ad7152_channels; - if (id->driver_data == 0) - indio_dev->num_channels = ARRAY_SIZE(ad7152_channels); - else - indio_dev->num_channels = 2; - indio_dev->num_channels = ARRAY_SIZE(ad7152_channels); - indio_dev->modes = INDIO_DIRECT_MODE; - - ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev); - if (ret) - return ret; - - dev_err(&client->dev, "%s capacitive sensor registered\n", id->name); - - return 0; -} - -static const struct i2c_device_id ad7152_id[] = { - { "ad7152", 0 }, - { "ad7153", 1 }, - {} -}; - -MODULE_DEVICE_TABLE(i2c, ad7152_id); - -static struct i2c_driver ad7152_driver = { - .driver = { - .name = KBUILD_MODNAME, - }, - .probe = ad7152_probe, - .id_table = ad7152_id, -}; -module_i2c_driver(ad7152_driver); - -MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); -MODULE_DESCRIPTION("Analog Devices AD7152/3 capacitive sensor driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/frequency/ad9834.c b/drivers/staging/iio/frequency/ad9834.c index 1e977014fe5f..0b0287503fb4 100644 --- a/drivers/staging/iio/frequency/ad9834.c +++ b/drivers/staging/iio/frequency/ad9834.c @@ -6,6 +6,7 @@ * Licensed under the GPL-2. */ +#include <linux/clk.h> #include <linux/interrupt.h> #include <linux/workqueue.h> #include <linux/device.h> @@ -71,7 +72,7 @@ struct ad9834_state { struct spi_device *spi; struct regulator *reg; - unsigned int mclk; + struct clk *mclk; unsigned short control; unsigned short devid; struct spi_transfer xfer; @@ -110,12 +111,15 @@ static unsigned int ad9834_calc_freqreg(unsigned long mclk, unsigned long fout) static int ad9834_write_frequency(struct ad9834_state *st, unsigned long addr, unsigned long fout) { + unsigned long clk_freq; unsigned long regval; - if (fout > (st->mclk / 2)) + clk_freq = clk_get_rate(st->mclk); + + if (fout > (clk_freq / 2)) return -EINVAL; - regval = ad9834_calc_freqreg(st->mclk, fout); + regval = ad9834_calc_freqreg(clk_freq, fout); st->freq_data[0] = cpu_to_be16(addr | (regval & RES_MASK(AD9834_FREQ_BITS / 2))); @@ -389,16 +393,11 @@ static const struct iio_info ad9833_info = { static int ad9834_probe(struct spi_device *spi) { - struct ad9834_platform_data *pdata = dev_get_platdata(&spi->dev); struct ad9834_state *st; struct iio_dev *indio_dev; struct regulator *reg; int ret; - if (!pdata) { - dev_dbg(&spi->dev, "no platform data?\n"); - return -ENODEV; - } reg = devm_regulator_get(&spi->dev, "avdd"); if (IS_ERR(reg)) @@ -418,7 +417,14 @@ static int ad9834_probe(struct spi_device *spi) spi_set_drvdata(spi, indio_dev); st = iio_priv(indio_dev); mutex_init(&st->lock); - st->mclk = pdata->mclk; + st->mclk = devm_clk_get(&spi->dev, NULL); + + ret = clk_prepare_enable(st->mclk); + if (ret) { + dev_err(&spi->dev, "Failed to enable master clock\n"); + goto error_disable_reg; + } + st->spi = spi; st->devid = spi_get_device_id(spi)->driver_data; st->reg = reg; @@ -454,42 +460,41 @@ static int ad9834_probe(struct spi_device *spi) spi_message_add_tail(&st->freq_xfer[1], &st->freq_msg); st->control = AD9834_B28 | AD9834_RESET; + st->control |= AD9834_DIV2; - if (!pdata->en_div2) - st->control |= AD9834_DIV2; - - if (!pdata->en_signbit_msb_out && (st->devid == ID_AD9834)) + if (st->devid == ID_AD9834) st->control |= AD9834_SIGN_PIB; st->data = cpu_to_be16(AD9834_REG_CMD | st->control); ret = spi_sync(st->spi, &st->msg); if (ret) { dev_err(&spi->dev, "device init failed\n"); - goto error_disable_reg; + goto error_clock_unprepare; } - ret = ad9834_write_frequency(st, AD9834_REG_FREQ0, pdata->freq0); + ret = ad9834_write_frequency(st, AD9834_REG_FREQ0, 1000000); if (ret) - goto error_disable_reg; + goto error_clock_unprepare; - ret = ad9834_write_frequency(st, AD9834_REG_FREQ1, pdata->freq1); + ret = ad9834_write_frequency(st, AD9834_REG_FREQ1, 5000000); if (ret) - goto error_disable_reg; + goto error_clock_unprepare; - ret = ad9834_write_phase(st, AD9834_REG_PHASE0, pdata->phase0); + ret = ad9834_write_phase(st, AD9834_REG_PHASE0, 512); if (ret) - goto error_disable_reg; + goto error_clock_unprepare; - ret = ad9834_write_phase(st, AD9834_REG_PHASE1, pdata->phase1); + ret = ad9834_write_phase(st, AD9834_REG_PHASE1, 1024); if (ret) - goto error_disable_reg; + goto error_clock_unprepare; ret = iio_device_register(indio_dev); if (ret) - goto error_disable_reg; + goto error_clock_unprepare; return 0; - +error_clock_unprepare: + clk_disable_unprepare(st->mclk); error_disable_reg: regulator_disable(reg); @@ -502,6 +507,7 @@ static int ad9834_remove(struct spi_device *spi) struct ad9834_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); + clk_disable_unprepare(st->mclk); regulator_disable(st->reg); return 0; diff --git a/drivers/staging/iio/frequency/ad9834.h b/drivers/staging/iio/frequency/ad9834.h index ae620f38eb49..da7e83ceedad 100644 --- a/drivers/staging/iio/frequency/ad9834.h +++ b/drivers/staging/iio/frequency/ad9834.h @@ -8,32 +8,4 @@ #ifndef IIO_DDS_AD9834_H_ #define IIO_DDS_AD9834_H_ -/* - * TODO: struct ad7887_platform_data needs to go into include/linux/iio - */ - -/** - * struct ad9834_platform_data - platform specific information - * @mclk: master clock in Hz - * @freq0: power up freq0 tuning word in Hz - * @freq1: power up freq1 tuning word in Hz - * @phase0: power up phase0 value [0..4095] correlates with 0..2PI - * @phase1: power up phase1 value [0..4095] correlates with 0..2PI - * @en_div2: digital output/2 is passed to the SIGN BIT OUT pin - * @en_signbit_msb_out: the MSB (or MSB/2) of the DAC data is connected to the - * SIGN BIT OUT pin. en_div2 controls whether it is the MSB - * or MSB/2 that is output. if en_signbit_msb_out=false, - * the on-board comparator is connected to SIGN BIT OUT - */ - -struct ad9834_platform_data { - unsigned int mclk; - unsigned int freq0; - unsigned int freq1; - unsigned short phase0; - unsigned short phase1; - bool en_div2; - bool en_signbit_msb_out; -}; - #endif /* IIO_DDS_AD9834_H_ */ diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index 9e52384f5370..3134295f014f 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -16,6 +16,7 @@ #include <linux/err.h> #include <linux/delay.h> #include <linux/module.h> +#include <linux/clk.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> @@ -82,21 +83,10 @@ #define AD5933_POLL_TIME_ms 10 #define AD5933_INIT_EXCITATION_TIME_ms 100 -/** - * struct ad5933_platform_data - platform specific data - * @ext_clk_hz: the external clock frequency in Hz, if not set - * the driver uses the internal clock (16.776 MHz) - * @vref_mv: the external reference voltage in millivolt - */ - -struct ad5933_platform_data { - unsigned long ext_clk_hz; - unsigned short vref_mv; -}; - struct ad5933_state { struct i2c_client *client; struct regulator *reg; + struct clk *mclk; struct delayed_work work; struct mutex lock; /* Protect sensor state */ unsigned long mclk_hz; @@ -112,10 +102,6 @@ struct ad5933_state { unsigned int poll_time_jiffies; }; -static struct ad5933_platform_data ad5933_default_pdata = { - .vref_mv = 3300, -}; - #define AD5933_CHANNEL(_type, _extend_name, _info_mask_separate, _address, \ _scan_index, _realbits) { \ .type = (_type), \ @@ -691,10 +677,10 @@ static void ad5933_work(struct work_struct *work) static int ad5933_probe(struct i2c_client *client, const struct i2c_device_id *id) { - int ret, voltage_uv = 0; - struct ad5933_platform_data *pdata = dev_get_platdata(&client->dev); + int ret; struct ad5933_state *st; struct iio_dev *indio_dev; + unsigned long ext_clk_hz = 0; indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st)); if (!indio_dev) @@ -706,9 +692,6 @@ static int ad5933_probe(struct i2c_client *client, mutex_init(&st->lock); - if (!pdata) - pdata = &ad5933_default_pdata; - st->reg = devm_regulator_get(&client->dev, "vdd"); if (IS_ERR(st->reg)) return PTR_ERR(st->reg); @@ -718,15 +701,28 @@ static int ad5933_probe(struct i2c_client *client, dev_err(&client->dev, "Failed to enable specified VDD supply\n"); return ret; } - voltage_uv = regulator_get_voltage(st->reg); + ret = regulator_get_voltage(st->reg); - if (voltage_uv) - st->vref_mv = voltage_uv / 1000; - else - st->vref_mv = pdata->vref_mv; + if (ret < 0) + goto error_disable_reg; + + st->vref_mv = ret / 1000; + + st->mclk = devm_clk_get(&client->dev, "mclk"); + if (IS_ERR(st->mclk) && PTR_ERR(st->mclk) != -ENOENT) { + ret = PTR_ERR(st->mclk); + goto error_disable_reg; + } - if (pdata->ext_clk_hz) { - st->mclk_hz = pdata->ext_clk_hz; + if (!IS_ERR(st->mclk)) { + ret = clk_prepare_enable(st->mclk); + if (ret < 0) + goto error_disable_reg; + ext_clk_hz = clk_get_rate(st->mclk); + } + + if (ext_clk_hz) { + st->mclk_hz = ext_clk_hz; st->ctrl_lb = AD5933_CTRL_EXT_SYSCLK; } else { st->mclk_hz = AD5933_INT_OSC_FREQ_Hz; @@ -746,7 +742,7 @@ static int ad5933_probe(struct i2c_client *client, ret = ad5933_register_ring_funcs_and_init(indio_dev); if (ret) - goto error_disable_reg; + goto error_disable_mclk; ret = ad5933_setup(st); if (ret) @@ -760,6 +756,8 @@ static int ad5933_probe(struct i2c_client *client, error_unreg_ring: iio_kfifo_free(indio_dev->buffer); +error_disable_mclk: + clk_disable_unprepare(st->mclk); error_disable_reg: regulator_disable(st->reg); @@ -774,6 +772,7 @@ static int ad5933_remove(struct i2c_client *client) iio_device_unregister(indio_dev); iio_kfifo_free(indio_dev->buffer); regulator_disable(st->reg); + clk_disable_unprepare(st->mclk); return 0; } diff --git a/drivers/staging/ks7010/Makefile b/drivers/staging/ks7010/Makefile index 07dc16cc86f5..412e2105a3a5 100644 --- a/drivers/staging/ks7010/Makefile +++ b/drivers/staging/ks7010/Makefile @@ -1,3 +1,3 @@ obj-$(CONFIG_KS7010) += ks7010.o -ks7010-y := michael_mic.o ks_hostif.o ks_wlan_net.o ks7010_sdio.o +ks7010-y := ks_hostif.o ks_wlan_net.o ks7010_sdio.o diff --git a/drivers/staging/ks7010/TODO b/drivers/staging/ks7010/TODO index d393ca58e231..87a6dac4890d 100644 --- a/drivers/staging/ks7010/TODO +++ b/drivers/staging/ks7010/TODO @@ -27,8 +27,6 @@ Now the TODOs: - fix the 'card removal' event when card is inserted when booting - check what other upstream wireless mechanisms can be used instead of the custom ones here -- replace custom Michael MIC implementation with the kernel - implementation. This task is only required for a *clean* WEXT interface. Please send any patches to: Greg Kroah-Hartman <gregkh@linuxfoundation.org> diff --git a/drivers/staging/ks7010/ks_hostif.c b/drivers/staging/ks7010/ks_hostif.c index 065bce193fac..06ebea0be118 100644 --- a/drivers/staging/ks7010/ks_hostif.c +++ b/drivers/staging/ks7010/ks_hostif.c @@ -6,15 +6,18 @@ * Copyright (C) 2009 Renesas Technology Corp. */ +#include <crypto/hash.h> #include <linux/circ_buf.h> #include <linux/if_arp.h> #include <net/iw_handler.h> #include <uapi/linux/llc.h> #include "eap_packet.h" #include "ks_wlan.h" -#include "michael_mic.h" #include "ks_hostif.h" +#define MICHAEL_MIC_KEY_LEN 8 +#define MICHAEL_MIC_LEN 8 + static inline void inc_smeqhead(struct ks_wlan_private *priv) { priv->sme_i.qhead = (priv->sme_i.qhead + 1) % SME_EVENT_BUFF_SIZE; @@ -35,7 +38,7 @@ static inline u8 get_byte(struct ks_wlan_private *priv) { u8 data; - data = *(priv->rxp)++; + data = *priv->rxp++; /* length check in advance ! */ --(priv->rx_size); return data; @@ -171,7 +174,7 @@ int get_current_ap(struct ks_wlan_private *priv, struct link_ap_info *ap_info) "- rate_set_size=%d\n", ap->bssid[0], ap->bssid[1], ap->bssid[2], ap->bssid[3], ap->bssid[4], ap->bssid[5], - &(ap->ssid.body[0]), + &ap->ssid.body[0], ap->rate_set.body[0], ap->rate_set.body[1], ap->rate_set.body[2], ap->rate_set.body[3], ap->rate_set.body[4], ap->rate_set.body[5], @@ -191,6 +194,68 @@ static u8 read_ie(unsigned char *bp, u8 max, u8 *body) return size; } +static int +michael_mic(u8 *key, u8 *data, unsigned int len, u8 priority, u8 *result) +{ + u8 pad_data[4] = { priority, 0, 0, 0 }; + struct crypto_shash *tfm = NULL; + struct shash_desc *desc = NULL; + int ret; + + tfm = crypto_alloc_shash("michael_mic", 0, 0); + if (IS_ERR(tfm)) { + ret = PTR_ERR(tfm); + goto err; + } + + ret = crypto_shash_setkey(tfm, key, MICHAEL_MIC_KEY_LEN); + if (ret < 0) + goto err_free_tfm; + + desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(tfm), GFP_KERNEL); + if (!desc) { + ret = -ENOMEM; + goto err_free_tfm; + } + + desc->tfm = tfm; + desc->flags = 0; + + ret = crypto_shash_init(desc); + if (ret < 0) + goto err_free_desc; + + // Compute the MIC value + /* + * IEEE802.11i page 47 + * Figure 43g TKIP MIC processing format + * +--+--+--------+--+----+--+--+--+--+--+--+--+--+ + * |6 |6 |1 |3 |M |1 |1 |1 |1 |1 |1 |1 |1 | Octet + * +--+--+--------+--+----+--+--+--+--+--+--+--+--+ + * |DA|SA|Priority|0 |Data|M0|M1|M2|M3|M4|M5|M6|M7| + * +--+--+--------+--+----+--+--+--+--+--+--+--+--+ + */ + + ret = crypto_shash_update(desc, data, 12); + if (ret < 0) + goto err_free_desc; + + ret = crypto_shash_update(desc, pad_data, 4); + if (ret < 0) + goto err_free_desc; + + ret = crypto_shash_finup(desc, data + 12, len - 12, result); + +err_free_desc: + kzfree(desc); + +err_free_tfm: + crypto_free_shash(tfm); + +err: + return ret; +} + static int get_ap_information(struct ks_wlan_private *priv, struct ap_info *ap_info, struct local_ap *ap) @@ -273,11 +338,11 @@ int hostif_data_indication_wpa(struct ks_wlan_private *priv, { struct ether_hdr *eth_hdr; unsigned short eth_proto; - unsigned char recv_mic[8]; + unsigned char recv_mic[MICHAEL_MIC_LEN]; char buf[128]; unsigned long now; struct mic_failure *mic_failure; - struct michael_mic michael_mic; + u8 mic[MICHAEL_MIC_LEN]; union iwreq_data wrqu; unsigned int key_index = auth_type - 1; struct wpa_key *key = &priv->wpa.key[key_index]; @@ -300,14 +365,20 @@ int hostif_data_indication_wpa(struct ks_wlan_private *priv, netdev_dbg(priv->net_dev, "TKIP: protocol=%04X: size=%u\n", eth_proto, priv->rx_size); /* MIC save */ - memcpy(&recv_mic[0], (priv->rxp) + ((priv->rx_size) - 8), 8); - priv->rx_size = priv->rx_size - 8; + memcpy(&recv_mic[0], + (priv->rxp) + ((priv->rx_size) - sizeof(recv_mic)), + sizeof(recv_mic)); + priv->rx_size = priv->rx_size - sizeof(recv_mic); if (auth_type > 0 && auth_type < 4) { /* auth_type check */ - michael_mic_function(&michael_mic, key->rx_mic_key, - priv->rxp, priv->rx_size, - 0, michael_mic.result); + int ret; + + ret = michael_mic(key->rx_mic_key, + priv->rxp, priv->rx_size, + 0, mic); + if (ret < 0) + return ret; } - if (memcmp(michael_mic.result, recv_mic, 8) != 0) { + if (memcmp(mic, recv_mic, sizeof(mic)) != 0) { now = jiffies; mic_failure = &priv->wpa.mic_failure; /* MIC FAILURE */ @@ -730,9 +801,9 @@ void hostif_scan_indication(struct ks_wlan_private *priv) priv->scan_ind_count++; if (priv->scan_ind_count < LOCAL_APLIST_MAX + 1) { netdev_dbg(priv->net_dev, " scan_ind_count=%d :: aplist.size=%d\n", - priv->scan_ind_count, priv->aplist.size); + priv->scan_ind_count, priv->aplist.size); get_ap_information(priv, (struct ap_info *)(priv->rxp), - &(priv->aplist.ap[priv->scan_ind_count - 1])); + &priv->aplist.ap[priv->scan_ind_count - 1]); priv->aplist.size = priv->scan_ind_count; } else { netdev_dbg(priv->net_dev, " count over :: scan_ind_count=%d\n", @@ -1002,7 +1073,6 @@ int hostif_data_request(struct ks_wlan_private *priv, struct sk_buff *skb) int result = 0; unsigned short eth_proto; struct ether_hdr *eth_hdr; - struct michael_mic michael_mic; unsigned short keyinfo = 0; struct ieee802_1x_hdr *aa1x_hdr; struct wpa_eapol_key *eap_key; @@ -1109,17 +1179,20 @@ int hostif_data_request(struct ks_wlan_private *priv, struct sk_buff *skb) pp->auth_type = cpu_to_le16(TYPE_AUTH); } else { if (priv->wpa.pairwise_suite == IW_AUTH_CIPHER_TKIP) { - michael_mic_function(&michael_mic, - priv->wpa.key[0].tx_mic_key, - &pp->data[0], skb_len, - 0, michael_mic.result); - memcpy(p, michael_mic.result, 8); - length += 8; - skb_len += 8; - p += 8; + u8 mic[MICHAEL_MIC_LEN]; + + ret = michael_mic(priv->wpa.key[0].tx_mic_key, + &pp->data[0], skb_len, + 0, mic); + if (ret < 0) + goto err_kfree; + + memcpy(p, mic, sizeof(mic)); + length += sizeof(mic); + skb_len += sizeof(mic); + p += sizeof(mic); pp->auth_type = cpu_to_le16(TYPE_DATA); - } else if (priv->wpa.pairwise_suite == IW_AUTH_CIPHER_CCMP) { pp->auth_type = diff --git a/drivers/staging/ks7010/ks_wlan_net.c b/drivers/staging/ks7010/ks_wlan_net.c index dc5459ae0b51..3cffc8be6656 100644 --- a/drivers/staging/ks7010/ks_wlan_net.c +++ b/drivers/staging/ks7010/ks_wlan_net.c @@ -182,7 +182,7 @@ static int ks_wlan_set_freq(struct net_device *dev, /* for SLEEP MODE */ /* If setting by frequency, convert to a channel */ if ((fwrq->freq.e == 1) && - (fwrq->freq.m >= (int)2.412e8) && (fwrq->freq.m <= (int)2.487e8)) { + (fwrq->freq.m >= 241200000) && (fwrq->freq.m <= 248700000)) { int f = fwrq->freq.m / 100000; int c = 0; diff --git a/drivers/staging/ks7010/michael_mic.c b/drivers/staging/ks7010/michael_mic.c deleted file mode 100644 index 3acd79615f98..000000000000 --- a/drivers/staging/ks7010/michael_mic.c +++ /dev/null @@ -1,127 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Driver for KeyStream wireless LAN - * - * Copyright (C) 2005-2008 KeyStream Corp. - * Copyright (C) 2009 Renesas Technology Corp. - */ - -#include <asm/unaligned.h> -#include <linux/bitops.h> -#include <linux/string.h> -#include "michael_mic.h" - -// Reset the state to the empty message. -static inline void michael_clear(struct michael_mic *mic) -{ - mic->l = mic->k0; - mic->r = mic->k1; - mic->m_bytes = 0; -} - -static void michael_init(struct michael_mic *mic, u8 *key) -{ - // Set the key - mic->k0 = get_unaligned_le32(key); - mic->k1 = get_unaligned_le32(key + 4); - - //clear(); - michael_clear(mic); -} - -static inline void michael_block(struct michael_mic *mic) -{ - mic->r ^= rol32(mic->l, 17); - mic->l += mic->r; - mic->r ^= ((mic->l & 0xff00ff00) >> 8) | - ((mic->l & 0x00ff00ff) << 8); - mic->l += mic->r; - mic->r ^= rol32(mic->l, 3); - mic->l += mic->r; - mic->r ^= ror32(mic->l, 2); - mic->l += mic->r; -} - -static void michael_append(struct michael_mic *mic, u8 *src, int bytes) -{ - int addlen; - - if (mic->m_bytes) { - addlen = 4 - mic->m_bytes; - if (addlen > bytes) - addlen = bytes; - memcpy(&mic->m[mic->m_bytes], src, addlen); - mic->m_bytes += addlen; - src += addlen; - bytes -= addlen; - - if (mic->m_bytes < 4) - return; - - mic->l ^= get_unaligned_le32(mic->m); - michael_block(mic); - mic->m_bytes = 0; - } - - while (bytes >= 4) { - mic->l ^= get_unaligned_le32(src); - michael_block(mic); - src += 4; - bytes -= 4; - } - - if (bytes > 0) { - mic->m_bytes = bytes; - memcpy(mic->m, src, bytes); - } -} - -static void michael_get_mic(struct michael_mic *mic, u8 *dst) -{ - u8 *data = mic->m; - - switch (mic->m_bytes) { - case 0: - mic->l ^= 0x5a; - break; - case 1: - mic->l ^= data[0] | 0x5a00; - break; - case 2: - mic->l ^= data[0] | (data[1] << 8) | 0x5a0000; - break; - case 3: - mic->l ^= data[0] | (data[1] << 8) | (data[2] << 16) | - 0x5a000000; - break; - } - michael_block(mic); - michael_block(mic); - // The appendByte function has already computed the result. - put_unaligned_le32(mic->l, dst); - put_unaligned_le32(mic->r, dst + 4); - - // Reset to the empty message. - michael_clear(mic); -} - -void michael_mic_function(struct michael_mic *mic, u8 *key, - u8 *data, unsigned int len, u8 priority, u8 *result) -{ - u8 pad_data[4] = { priority, 0, 0, 0 }; - // Compute the MIC value - /* - * IEEE802.11i page 47 - * Figure 43g TKIP MIC processing format - * +--+--+--------+--+----+--+--+--+--+--+--+--+--+ - * |6 |6 |1 |3 |M |1 |1 |1 |1 |1 |1 |1 |1 | Octet - * +--+--+--------+--+----+--+--+--+--+--+--+--+--+ - * |DA|SA|Priority|0 |Data|M0|M1|M2|M3|M4|M5|M6|M7| - * +--+--+--------+--+----+--+--+--+--+--+--+--+--+ - */ - michael_init(mic, key); - michael_append(mic, data, 12); /* |DA|SA| */ - michael_append(mic, pad_data, 4); /* |Priority|0|0|0| */ - michael_append(mic, data + 12, len - 12); /* |Data| */ - michael_get_mic(mic, result); -} diff --git a/drivers/staging/ks7010/michael_mic.h b/drivers/staging/ks7010/michael_mic.h deleted file mode 100644 index f0ac164b999b..000000000000 --- a/drivers/staging/ks7010/michael_mic.h +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Driver for KeyStream wireless LAN - * - * Copyright (C) 2005-2008 KeyStream Corp. - * Copyright (C) 2009 Renesas Technology Corp. - */ - -/* MichaelMIC routine define */ -struct michael_mic { - u32 k0; // Key - u32 k1; // Key - u32 l; // Current state - u32 r; // Current state - u8 m[4]; // Message accumulator (single word) - int m_bytes; // # bytes in M - u8 result[8]; -}; - -void michael_mic_function(struct michael_mic *mic, u8 *key, - u8 *data, unsigned int len, u8 priority, u8 *result); diff --git a/drivers/staging/media/davinci_vpfe/Makefile b/drivers/staging/media/davinci_vpfe/Makefile index 9c57042c877d..9268e507f791 100644 --- a/drivers/staging/media/davinci_vpfe/Makefile +++ b/drivers/staging/media/davinci_vpfe/Makefile @@ -6,5 +6,5 @@ davinci-vfpe-objs := \ # Allow building it with COMPILE_TEST on other archs ifndef CONFIG_ARCH_DAVINCI -ccflags-y += -Iarch/arm/mach-davinci/include/ +ccflags-y += -I $(srctree)/arch/arm/mach-davinci/include/ endif diff --git a/drivers/staging/most/Makefile b/drivers/staging/most/Makefile index f8bcf488ecf2..c7662f65f6db 100644 --- a/drivers/staging/most/Makefile +++ b/drivers/staging/most/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_MOST) += most_core.o most_core-y := core.o -ccflags-y += -Idrivers/staging/ +ccflags-y += -I $(srctree)/drivers/staging/ obj-$(CONFIG_MOST_CDEV) += cdev/ obj-$(CONFIG_MOST_NET) += net/ diff --git a/drivers/staging/most/cdev/Makefile b/drivers/staging/most/cdev/Makefile index afb9870eb50f..21b0bd72c01d 100644 --- a/drivers/staging/most/cdev/Makefile +++ b/drivers/staging/most/cdev/Makefile @@ -1,4 +1,4 @@ obj-$(CONFIG_MOST_CDEV) += most_cdev.o most_cdev-objs := cdev.o -ccflags-y += -Idrivers/staging/ +ccflags-y += -I $(srctree)/drivers/staging/ diff --git a/drivers/staging/most/cdev/cdev.c b/drivers/staging/most/cdev/cdev.c index ea64aabda94e..f2b347cda8b7 100644 --- a/drivers/staging/most/cdev/cdev.c +++ b/drivers/staging/most/cdev/cdev.c @@ -453,7 +453,9 @@ static int comp_probe(struct most_interface *iface, int channel_id, c->devno = MKDEV(comp.major, current_minor); cdev_init(&c->cdev, &channel_fops); c->cdev.owner = THIS_MODULE; - cdev_add(&c->cdev, c->devno, 1); + retval = cdev_add(&c->cdev, c->devno, 1); + if (retval < 0) + goto err_free_c; c->iface = iface; c->cfg = cfg; c->channel_id = channel_id; @@ -485,6 +487,7 @@ err_free_kfifo_and_del_list: list_del(&c->list); err_del_cdev_and_free_channel: cdev_del(&c->cdev); +err_free_c: kfree(c); err_remove_ida: ida_simple_remove(&comp.minor_id, current_minor); diff --git a/drivers/staging/most/dim2/Makefile b/drivers/staging/most/dim2/Makefile index 66676f5907ee..6d15f045a767 100644 --- a/drivers/staging/most/dim2/Makefile +++ b/drivers/staging/most/dim2/Makefile @@ -1,4 +1,4 @@ obj-$(CONFIG_MOST_DIM2) += most_dim2.o most_dim2-objs := dim2.o hal.o sysfs.o -ccflags-y += -Idrivers/staging/ +ccflags-y += -I $(srctree)/drivers/staging/ diff --git a/drivers/staging/most/i2c/Makefile b/drivers/staging/most/i2c/Makefile index a7d094c1e1c2..c032fea979b3 100644 --- a/drivers/staging/most/i2c/Makefile +++ b/drivers/staging/most/i2c/Makefile @@ -1,4 +1,4 @@ obj-$(CONFIG_MOST_I2C) += most_i2c.o most_i2c-objs := i2c.o -ccflags-y += -Idrivers/staging/ +ccflags-y += -I $(srctree)/drivers/staging/ diff --git a/drivers/staging/most/net/Makefile b/drivers/staging/most/net/Makefile index 54500aa77be8..820faec6b296 100644 --- a/drivers/staging/most/net/Makefile +++ b/drivers/staging/most/net/Makefile @@ -1,4 +1,4 @@ obj-$(CONFIG_MOST_NET) += most_net.o most_net-objs := net.o -ccflags-y += -Idrivers/staging/ +ccflags-y += -I $(srctree)/drivers/staging/ diff --git a/drivers/staging/most/sound/Makefile b/drivers/staging/most/sound/Makefile index eee8774e38cb..5bb55bb108fb 100644 --- a/drivers/staging/most/sound/Makefile +++ b/drivers/staging/most/sound/Makefile @@ -1,4 +1,4 @@ obj-$(CONFIG_MOST_SOUND) += most_sound.o most_sound-objs := sound.o -ccflags-y += -Idrivers/staging/ +ccflags-y += -I $(srctree)/drivers/staging/ diff --git a/drivers/staging/most/usb/Makefile b/drivers/staging/most/usb/Makefile index 18d28cba4fbf..910cd08bad7c 100644 --- a/drivers/staging/most/usb/Makefile +++ b/drivers/staging/most/usb/Makefile @@ -1,4 +1,4 @@ obj-$(CONFIG_MOST_USB) += most_usb.o most_usb-objs := usb.o -ccflags-y += -Idrivers/staging/ +ccflags-y += -I $(srctree)/drivers/staging/ diff --git a/drivers/staging/most/video/Makefile b/drivers/staging/most/video/Makefile index 1c8e520e02a2..c6e01b6ecfe6 100644 --- a/drivers/staging/most/video/Makefile +++ b/drivers/staging/most/video/Makefile @@ -1,4 +1,4 @@ obj-$(CONFIG_MOST_VIDEO) += most_video.o most_video-objs := video.o -ccflags-y += -Idrivers/staging/ +ccflags-y += -I $(srctree)/drivers/staging/ diff --git a/drivers/staging/mt7621-dma/Kconfig b/drivers/staging/mt7621-dma/Kconfig index 2423c40099d1..b6e48a682c44 100644 --- a/drivers/staging/mt7621-dma/Kconfig +++ b/drivers/staging/mt7621-dma/Kconfig @@ -1,9 +1,3 @@ -config DMA_RALINK - tristate "RALINK DMA support" - depends on RALINK && !SOC_RT288X - select DMA_ENGINE - select DMA_VIRTUAL_CHANNELS - config MTK_HSDMA tristate "MTK HSDMA support" depends on RALINK && SOC_MT7621 diff --git a/drivers/staging/mt7621-dma/Makefile b/drivers/staging/mt7621-dma/Makefile index d3152d45cf45..c9e3e1619ab0 100644 --- a/drivers/staging/mt7621-dma/Makefile +++ b/drivers/staging/mt7621-dma/Makefile @@ -1,4 +1,3 @@ -obj-$(CONFIG_DMA_RALINK) += ralink-gdma.o obj-$(CONFIG_MTK_HSDMA) += mtk-hsdma.o ccflags-y += -I$(srctree)/drivers/dma diff --git a/drivers/staging/mt7621-dma/mtk-hsdma.c b/drivers/staging/mt7621-dma/mtk-hsdma.c index d67a2504adb1..97571f1d697b 100644 --- a/drivers/staging/mt7621-dma/mtk-hsdma.c +++ b/drivers/staging/mt7621-dma/mtk-hsdma.c @@ -1,12 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2015, Michael Lee <igvtee@gmail.com> * MTK HSDMA support - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * */ #include <linux/dmaengine.h> @@ -191,7 +186,7 @@ static inline u32 mtk_hsdma_read(struct mtk_hsdam_engine *hsdma, u32 reg) } static inline void mtk_hsdma_write(struct mtk_hsdam_engine *hsdma, - unsigned reg, u32 val) + unsigned int reg, u32 val) { writel(val, hsdma->base + reg); } @@ -242,7 +237,7 @@ static void hsdma_dump_desc(struct mtk_hsdam_engine *hsdma, int i; dev_dbg(hsdma->ddev.dev, "tx idx: %d, rx idx: %d\n", - chan->tx_idx, chan->rx_idx); + chan->tx_idx, chan->rx_idx); for (i = 0; i < HSDMA_DESCS_NUM; i++) { tx_desc = &chan->tx_ring[i]; diff --git a/drivers/staging/mt7621-dts/gbpc1.dts b/drivers/staging/mt7621-dts/gbpc1.dts index 6a1699ce9455..b73385540216 100644 --- a/drivers/staging/mt7621-dts/gbpc1.dts +++ b/drivers/staging/mt7621-dts/gbpc1.dts @@ -136,8 +136,8 @@ &pinctrl { state_default: pinctrl0 { gpio { - ralink,group = "wdt", "rgmii2", "uart3"; - ralink,function = "gpio"; + groups = "wdt", "rgmii2", "uart3"; + function = "gpio"; }; }; }; diff --git a/drivers/staging/mt7621-dts/mt7621.dtsi b/drivers/staging/mt7621-dts/mt7621.dtsi index 71f069d59ad8..6aff3680ce4b 100644 --- a/drivers/staging/mt7621-dts/mt7621.dtsi +++ b/drivers/staging/mt7621-dts/mt7621.dtsi @@ -204,82 +204,82 @@ i2c_pins: i2c0 { i2c0 { - group = "i2c"; + groups = "i2c"; function = "i2c"; }; }; spi_pins: spi0 { spi0 { - group = "spi"; + groups = "spi"; function = "spi"; }; }; uart1_pins: uart1 { uart1 { - group = "uart1"; + groups = "uart1"; function = "uart1"; }; }; uart2_pins: uart2 { uart2 { - group = "uart2"; + groups = "uart2"; function = "uart2"; }; }; uart3_pins: uart3 { uart3 { - group = "uart3"; + groups = "uart3"; function = "uart3"; }; }; rgmii1_pins: rgmii1 { rgmii1 { - group = "rgmii1"; + groups = "rgmii1"; function = "rgmii1"; }; }; rgmii2_pins: rgmii2 { rgmii2 { - group = "rgmii2"; + groups = "rgmii2"; function = "rgmii2"; }; }; mdio_pins: mdio0 { mdio0 { - group = "mdio"; + groups = "mdio"; function = "mdio"; }; }; pcie_pins: pcie0 { pcie0 { - group = "pcie"; + groups = "pcie"; function = "pcie rst"; }; }; nand_pins: nand0 { spi-nand { - group = "spi"; + groups = "spi"; function = "nand1"; }; sdhci-nand { - group = "sdhci"; + groups = "sdhci"; function = "nand2"; }; }; sdhci_pins: sdhci0 { sdhci0 { - group = "sdhci"; + groups = "sdhci"; function = "sdhci"; }; }; @@ -420,10 +420,12 @@ status = "disabled"; - resets = <&rstctrl 24 &rstctrl 25 &rstctrl 26>; - reset-names = "pcie0", "pcie1", "pcie2"; + resets = <&rstctrl 23 &rstctrl 24 &rstctrl 25 &rstctrl 26>; + reset-names = "pcie", "pcie0", "pcie1", "pcie2"; clocks = <&clkctrl 24 &clkctrl 25 &clkctrl 26>; clock-names = "pcie0", "pcie1", "pcie2"; + phys = <&pcie0_port>, <&pcie1_port>, <&pcie2_port>; + phy-names = "pcie-phy0", "pcie-phy1", "pcie-phy2"; pcie@0,0 { reg = <0x0000 0 0 0 0>; @@ -449,4 +451,33 @@ bus-range = <0x00 0xff>; }; }; + + pcie0_phy: pcie-phy@1e149000 { + compatible = "mediatek,mt7621-pci-phy"; + reg = <0x1e149000 0x0700>; + #address-cells = <1>; + #size-cells = <0>; + + pcie0_port: pcie-phy@0 { + reg = <0>; + #phy-cells = <0>; + }; + + pcie1_port: pcie-phy@1 { + reg = <1>; + #phy-cells = <0>; + }; + }; + + pcie1_phy: pcie-phy@1e14a000 { + compatible = "mediatek,mt7621-pci-phy"; + reg = <0x1e14a000 0x0700>; + #address-cells = <1>; + #size-cells = <0>; + + pcie2_port: pcie-phy@0 { + reg = <0>; + #phy-cells = <0>; + }; + }; }; diff --git a/drivers/staging/mt7621-eth/ethtool.c b/drivers/staging/mt7621-eth/ethtool.c index 40a7d47be913..8c4228e2c987 100644 --- a/drivers/staging/mt7621-eth/ethtool.c +++ b/drivers/staging/mt7621-eth/ethtool.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License diff --git a/drivers/staging/mt7621-eth/ethtool.h b/drivers/staging/mt7621-eth/ethtool.h index 40b4cf011660..0071469aea6c 100644 --- a/drivers/staging/mt7621-eth/ethtool.h +++ b/drivers/staging/mt7621-eth/ethtool.h @@ -1,12 +1,5 @@ -/* This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * 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. - * +/* SPDX-License-Identifier: GPL-2.0 */ +/* * Copyright (C) 2009-2016 John Crispin <blogic@openwrt.org> * Copyright (C) 2009-2016 Felix Fietkau <nbd@openwrt.org> * Copyright (C) 2013-2016 Michael Lee <igvtee@gmail.com> diff --git a/drivers/staging/mt7621-mmc/Kconfig b/drivers/staging/mt7621-mmc/Kconfig index c6dfe8c637dc..1eb79cd6e22f 100644 --- a/drivers/staging/mt7621-mmc/Kconfig +++ b/drivers/staging/mt7621-mmc/Kconfig @@ -1,6 +1,6 @@ config MTK_MMC tristate "MTK SD/MMC" - depends on !MTD_NAND_RALINK && MMC + depends on RALINK && MMC config MTK_AEE_KDUMP bool "MTK AEE KDUMP" diff --git a/drivers/staging/mt7621-mmc/dbg.c b/drivers/staging/mt7621-mmc/dbg.c index eabe0595978b..c7c091fa1da0 100644 --- a/drivers/staging/mt7621-mmc/dbg.c +++ b/drivers/staging/mt7621-mmc/dbg.c @@ -36,7 +36,6 @@ * Inc. */ -#include <linux/version.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/kthread.h> diff --git a/drivers/staging/mt7621-mmc/mt6575_sd.h b/drivers/staging/mt7621-mmc/mt6575_sd.h index 4e287c140acb..038a484a9476 100644 --- a/drivers/staging/mt7621-mmc/mt6575_sd.h +++ b/drivers/staging/mt7621-mmc/mt6575_sd.h @@ -363,7 +363,7 @@ enum { #define MSDC_CKGEN_MSDC_DLY_SEL (0x1F << 10) #define MSDC_INT_DAT_LATCH_CK_SEL (0x7 << 7) #define MSDC_CKGEN_MSDC_CK_SEL (0x1 << 6) -#define CARD_READY_FOR_DATA (1 << 8) +#define CARD_READY_FOR_DATA BIT(8) #define CARD_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /*--------------------------------------------------------------------------*/ diff --git a/drivers/staging/mt7621-pci-phy/Kconfig b/drivers/staging/mt7621-pci-phy/Kconfig new file mode 100644 index 000000000000..b9f6ab784ee8 --- /dev/null +++ b/drivers/staging/mt7621-pci-phy/Kconfig @@ -0,0 +1,7 @@ +config PCI_MT7621_PHY + tristate "MediaTek MT7621 PCI PHY Driver" + depends on RALINK && OF + select GENERIC_PHY + help + Say 'Y' here to add support for MediaTek MT7621 PCI PHY driver, + diff --git a/drivers/staging/mt7621-pci-phy/Makefile b/drivers/staging/mt7621-pci-phy/Makefile new file mode 100644 index 000000000000..a970056f05c1 --- /dev/null +++ b/drivers/staging/mt7621-pci-phy/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_PCI_MT7621_PHY) += pci-mt7621-phy.o diff --git a/drivers/staging/mt7621-pci-phy/TODO b/drivers/staging/mt7621-pci-phy/TODO new file mode 100644 index 000000000000..a255e8f753eb --- /dev/null +++ b/drivers/staging/mt7621-pci-phy/TODO @@ -0,0 +1,4 @@ + +- general code review and cleanup + +Cc: NeilBrown <neil@brown.name> and Sergio Paracuellos <sergio.paracuellos@gmail.com> diff --git a/drivers/staging/mt7621-pci-phy/mediatek,mt7621-pci-phy.txt b/drivers/staging/mt7621-pci-phy/mediatek,mt7621-pci-phy.txt new file mode 100644 index 000000000000..33a8a698bdd0 --- /dev/null +++ b/drivers/staging/mt7621-pci-phy/mediatek,mt7621-pci-phy.txt @@ -0,0 +1,54 @@ +Mediatek Mt7621 PCIe PHY + +Required properties: +- compatible: must be "mediatek,mt7621-pci-phy" +- reg: base address and length of the PCIe PHY block +- #address-cells: must be 1 +- #size-cells: must be 0 + +Each PCIe PHY should be represented by a child node + +Required properties For the child node: +- reg: the PHY ID +0 - PCIe RC 0 +1 - PCIe RC 1 +- #phy-cells: must be 0 + +Example: + pcie0_phy: pcie-phy@1a149000 { + compatible = "mediatek,mt7621-pci-phy"; + reg = <0x1a149000 0x0700>; + #address-cells = <1>; + #size-cells = <0>; + + pcie0_port: pcie-phy@0 { + reg = <0>; + #phy-cells = <0>; + }; + + pcie1_port: pcie-phy@1 { + reg = <1>; + #phy-cells = <0>; + }; + }; + + pcie1_phy: pcie-phy@1a14a000 { + compatible = "mediatek,mt7621-pci-phy"; + reg = <0x1a14a000 0x0700>; + #address-cells = <1>; + #size-cells = <0>; + + pcie2_port: pcie-phy@0 { + reg = <0>; + #phy-cells = <0>; + }; + }; + + /* users of the PCIe phy */ + + pcie: pcie@1e140000 { + ... + ... + phys = <&pcie0_port>, <&pcie1_port>, <&pcie2_port>; + phy-names = "pcie-phy0", "pcie-phy1", "pcie-phy2"; + };
\ No newline at end of file diff --git a/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c b/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c new file mode 100644 index 000000000000..d3ca2f019112 --- /dev/null +++ b/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c @@ -0,0 +1,387 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Mediatek MT7621 PCI PHY Driver + * Author: Sergio Paracuellos <sergio.paracuellos@gmail.com> + */ + +#include <dt-bindings/phy/phy.h> +#include <linux/bitops.h> +#include <linux/module.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/phy/phy.h> +#include <linux/platform_device.h> +#include <mt7621.h> +#include <ralink_regs.h> + +#define RALINK_CLKCFG1 0x30 +#define CHIP_REV_MT7621_E2 0x0101 + +#define PCIE_PORT_CLK_EN(x) BIT(24 + (x)) + +#define RG_PE1_PIPE_REG 0x02c +#define RG_PE1_PIPE_RST BIT(12) +#define RG_PE1_PIPE_CMD_FRC BIT(4) + +#define RG_P0_TO_P1_WIDTH 0x100 +#define RG_PE1_H_LCDDS_REG 0x49c +#define RG_PE1_H_LCDDS_PCW GENMASK(30, 0) +#define RG_PE1_H_LCDDS_PCW_VAL(x) ((0x7fffffff & (x)) << 0) + +#define RG_PE1_FRC_H_XTAL_REG 0x400 +#define RG_PE1_FRC_H_XTAL_TYPE BIT(8) +#define RG_PE1_H_XTAL_TYPE GENMASK(10, 9) +#define RG_PE1_H_XTAL_TYPE_VAL(x) ((0x3 & (x)) << 9) + +#define RG_PE1_FRC_PHY_REG 0x000 +#define RG_PE1_FRC_PHY_EN BIT(4) +#define RG_PE1_PHY_EN BIT(5) + +#define RG_PE1_H_PLL_REG 0x490 +#define RG_PE1_H_PLL_BC GENMASK(23, 22) +#define RG_PE1_H_PLL_BC_VAL(x) ((0x3 & (x)) << 22) +#define RG_PE1_H_PLL_BP GENMASK(21, 18) +#define RG_PE1_H_PLL_BP_VAL(x) ((0xf & (x)) << 18) +#define RG_PE1_H_PLL_IR GENMASK(15, 12) +#define RG_PE1_H_PLL_IR_VAL(x) ((0xf & (x)) << 12) +#define RG_PE1_H_PLL_IC GENMASK(11, 8) +#define RG_PE1_H_PLL_IC_VAL(x) ((0xf & (x)) << 8) +#define RG_PE1_H_PLL_PREDIV GENMASK(7, 6) +#define RG_PE1_H_PLL_PREDIV_VAL(x) ((0x3 & (x)) << 6) +#define RG_PE1_PLL_DIVEN GENMASK(3, 1) +#define RG_PE1_PLL_DIVEN_VAL(x) ((0x7 & (x)) << 1) + +#define RG_PE1_H_PLL_FBKSEL_REG 0x4bc +#define RG_PE1_H_PLL_FBKSEL GENMASK(5, 4) +#define RG_PE1_H_PLL_FBKSEL_VAL(x) ((0x3 & (x)) << 4) + +#define RG_PE1_H_LCDDS_SSC_PRD_REG 0x4a4 +#define RG_PE1_H_LCDDS_SSC_PRD GENMASK(15, 0) +#define RG_PE1_H_LCDDS_SSC_PRD_VAL(x) ((0xffff & (x)) << 0) + +#define RG_PE1_H_LCDDS_SSC_DELTA_REG 0x4a8 +#define RG_PE1_H_LCDDS_SSC_DELTA GENMASK(11, 0) +#define RG_PE1_H_LCDDS_SSC_DELTA_VAL(x) ((0xfff & (x)) << 0) +#define RG_PE1_H_LCDDS_SSC_DELTA1 GENMASK(27, 16) +#define RG_PE1_H_LCDDS_SSC_DELTA1_VAL(x) ((0xff & (x)) << 16) + +#define RG_PE1_LCDDS_CLK_PH_INV_REG 0x4a0 +#define RG_PE1_LCDDS_CLK_PH_INV BIT(5) + +#define RG_PE1_H_PLL_BR_REG 0x4ac +#define RG_PE1_H_PLL_BR GENMASK(18, 16) +#define RG_PE1_H_PLL_BR_VAL(x) ((0x7 & (x)) << 16) + +#define RG_PE1_MSTCKDIV_REG 0x414 +#define RG_PE1_MSTCKDIV GENMASK(7, 6) +#define RG_PE1_MSTCKDIV_VAL(x) ((0x3 & (x)) << 6) + +#define RG_PE1_FRC_MSTCKDIV BIT(5) + +/** + * struct mt7621_pci_phy_instance - Mt7621 Pcie PHY device + * @phy: pointer to the kernel PHY device + * @port_base: base register + * @index: internal ID to identify the Mt7621 PCIe PHY + */ +struct mt7621_pci_phy_instance { + struct phy *phy; + void __iomem *port_base; + u32 index; +}; + +/** + * struct mt7621_pci_phy - Mt7621 Pcie PHY core + * @dev: pointer to device + * @phys: pointer to Mt7621 PHY device + * @nphys: number of PHY devices for this core + */ +struct mt7621_pci_phy { + struct device *dev; + struct mt7621_pci_phy_instance **phys; + int nphys; +}; + +static inline u32 phy_read(struct mt7621_pci_phy_instance *instance, u32 reg) +{ + return readl(instance->port_base + reg); +} + +static inline void phy_write(struct mt7621_pci_phy_instance *instance, + u32 val, u32 reg) +{ + writel(val, instance->port_base + reg); +} + +static void mt7621_bypass_pipe_rst(struct mt7621_pci_phy *phy, + struct mt7621_pci_phy_instance *instance) +{ + u32 offset = (instance->index != 1) ? + RG_PE1_PIPE_REG : RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH; + u32 reg; + + reg = phy_read(instance, offset); + reg &= ~(RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC); + reg |= (RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC); + phy_write(instance, reg, offset); +} + +static void mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy, + struct mt7621_pci_phy_instance *instance) +{ + struct device *dev = phy->dev; + u32 reg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0); + u32 offset; + u32 val; + + reg = (reg >> 6) & 0x7; + /* Set PCIe Port PHY to disable SSC */ + /* Debug Xtal Type */ + val = phy_read(instance, RG_PE1_FRC_H_XTAL_REG); + val &= ~(RG_PE1_FRC_H_XTAL_TYPE | RG_PE1_H_XTAL_TYPE); + val |= RG_PE1_FRC_H_XTAL_TYPE; + val |= RG_PE1_H_XTAL_TYPE_VAL(0x00); + phy_write(instance, val, RG_PE1_FRC_H_XTAL_REG); + + /* disable port */ + offset = (instance->index != 1) ? + RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH; + val = phy_read(instance, offset); + val &= ~(RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN); + val |= RG_PE1_FRC_PHY_EN; + phy_write(instance, val, offset); + + /* Set Pre-divider ratio (for host mode) */ + val = phy_read(instance, RG_PE1_H_PLL_REG); + val &= ~(RG_PE1_H_PLL_PREDIV); + + if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */ + val |= RG_PE1_H_PLL_PREDIV_VAL(0x01); + phy_write(instance, val, RG_PE1_H_PLL_REG); + dev_info(dev, "Xtal is 40MHz\n"); + } else { /* 25MHz | 20MHz Xtal */ + val |= RG_PE1_H_PLL_PREDIV_VAL(0x00); + phy_write(instance, val, RG_PE1_H_PLL_REG); + if (reg >= 6) { + dev_info(dev, "Xtal is 25MHz\n"); + + /* Select feedback clock */ + val = phy_read(instance, RG_PE1_H_PLL_FBKSEL_REG); + val &= ~(RG_PE1_H_PLL_FBKSEL); + val |= RG_PE1_H_PLL_FBKSEL_VAL(0x01); + phy_write(instance, val, RG_PE1_H_PLL_FBKSEL_REG); + + /* DDS NCPO PCW (for host mode) */ + val = phy_read(instance, RG_PE1_H_LCDDS_SSC_PRD_REG); + val &= ~(RG_PE1_H_LCDDS_SSC_PRD); + val |= RG_PE1_H_LCDDS_SSC_PRD_VAL(0x18000000); + phy_write(instance, val, RG_PE1_H_LCDDS_SSC_PRD_REG); + + /* DDS SSC dither period control */ + val = phy_read(instance, RG_PE1_H_LCDDS_SSC_PRD_REG); + val &= ~(RG_PE1_H_LCDDS_SSC_PRD); + val |= RG_PE1_H_LCDDS_SSC_PRD_VAL(0x18d); + phy_write(instance, val, RG_PE1_H_LCDDS_SSC_PRD_REG); + + /* DDS SSC dither amplitude control */ + val = phy_read(instance, RG_PE1_H_LCDDS_SSC_DELTA_REG); + val &= ~(RG_PE1_H_LCDDS_SSC_DELTA | + RG_PE1_H_LCDDS_SSC_DELTA1); + val |= RG_PE1_H_LCDDS_SSC_DELTA_VAL(0x4a); + val |= RG_PE1_H_LCDDS_SSC_DELTA1_VAL(0x4a); + phy_write(instance, val, RG_PE1_H_LCDDS_SSC_DELTA_REG); + } else { + dev_info(dev, "Xtal is 20MHz\n"); + } + } + + /* DDS clock inversion */ + val = phy_read(instance, RG_PE1_LCDDS_CLK_PH_INV_REG); + val &= ~(RG_PE1_LCDDS_CLK_PH_INV); + val |= RG_PE1_LCDDS_CLK_PH_INV; + phy_write(instance, val, RG_PE1_LCDDS_CLK_PH_INV_REG); + + /* Set PLL bits */ + val = phy_read(instance, RG_PE1_H_PLL_REG); + val &= ~(RG_PE1_H_PLL_BC | RG_PE1_H_PLL_BP | RG_PE1_H_PLL_IR | + RG_PE1_H_PLL_IC | RG_PE1_PLL_DIVEN); + val |= RG_PE1_H_PLL_BC_VAL(0x02); + val |= RG_PE1_H_PLL_BP_VAL(0x06); + val |= RG_PE1_H_PLL_IR_VAL(0x02); + val |= RG_PE1_H_PLL_IC_VAL(0x01); + val |= RG_PE1_PLL_DIVEN_VAL(0x02); + phy_write(instance, val, RG_PE1_H_PLL_REG); + + val = phy_read(instance, RG_PE1_H_PLL_BR_REG); + val &= ~(RG_PE1_H_PLL_BR); + val |= RG_PE1_H_PLL_BR_VAL(0x00); + phy_write(instance, val, RG_PE1_H_PLL_BR_REG); + + if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */ + /* set force mode enable of da_pe1_mstckdiv */ + val = phy_read(instance, RG_PE1_MSTCKDIV_REG); + val &= ~(RG_PE1_MSTCKDIV | RG_PE1_FRC_MSTCKDIV); + val |= (RG_PE1_MSTCKDIV_VAL(0x01) | RG_PE1_FRC_MSTCKDIV); + phy_write(instance, val, RG_PE1_MSTCKDIV_REG); + } +} + +static int mt7621_pci_phy_init(struct phy *phy) +{ + struct mt7621_pci_phy_instance *instance = phy_get_drvdata(phy); + struct mt7621_pci_phy *mphy = dev_get_drvdata(phy->dev.parent); + u32 chip_rev_id = rt_sysc_r32(SYSC_REG_CHIP_REV); + + if ((chip_rev_id & 0xFFFF) == CHIP_REV_MT7621_E2) + mt7621_bypass_pipe_rst(mphy, instance); + + mt7621_set_phy_for_ssc(mphy, instance); + + return 0; +} + +static int mt7621_pci_phy_power_on(struct phy *phy) +{ + struct mt7621_pci_phy_instance *instance = phy_get_drvdata(phy); + u32 offset = (instance->index != 1) ? + RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH; + u32 val; + + /* Enable PHY and disable force mode */ + val = phy_read(instance, offset); + val &= ~(RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN); + val |= (RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN); + phy_write(instance, val, offset); + + return 0; +} + +static int mt7621_pci_phy_power_off(struct phy *phy) +{ + struct mt7621_pci_phy_instance *instance = phy_get_drvdata(phy); + u32 offset = (instance->index != 1) ? + RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH; + u32 val; + + /* Disable PHY */ + val = phy_read(instance, offset); + val &= ~(RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN); + val |= RG_PE1_FRC_PHY_EN; + phy_write(instance, val, offset); + + return 0; +} + +static int mt7621_pci_phy_exit(struct phy *phy) +{ + struct mt7621_pci_phy_instance *instance = phy_get_drvdata(phy); + + rt_sysc_m32(PCIE_PORT_CLK_EN(instance->index), 0, RALINK_CLKCFG1); + + return 0; +} + +static const struct phy_ops mt7621_pci_phy_ops = { + .init = mt7621_pci_phy_init, + .exit = mt7621_pci_phy_exit, + .power_on = mt7621_pci_phy_power_on, + .power_off = mt7621_pci_phy_power_off, + .owner = THIS_MODULE, +}; + +static int mt7621_pci_phy_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct device_node *child_np; + struct phy_provider *provider; + struct mt7621_pci_phy *phy; + struct resource res; + int port, ret; + void __iomem *port_base; + + phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); + if (!phy) + return -ENOMEM; + + phy->nphys = of_get_child_count(np); + phy->phys = devm_kcalloc(dev, phy->nphys, + sizeof(*phy->phys), GFP_KERNEL); + if (!phy->phys) + return -ENOMEM; + + phy->dev = dev; + platform_set_drvdata(pdev, phy); + + ret = of_address_to_resource(np, 0, &res); + if (ret) { + dev_err(dev, "failed to get address resource(id-%d)\n", port); + return ret; + } + + port_base = devm_ioremap_resource(dev, &res); + if (IS_ERR(port_base)) { + dev_err(dev, "failed to remap phy regs\n"); + return PTR_ERR(port_base); + } + + port = 0; + for_each_child_of_node(np, child_np) { + struct mt7621_pci_phy_instance *instance; + struct phy *pphy; + + instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL); + if (!instance) { + ret = -ENOMEM; + goto put_child; + } + + phy->phys[port] = instance; + + pphy = devm_phy_create(dev, child_np, &mt7621_pci_phy_ops); + if (IS_ERR(phy)) { + dev_err(dev, "failed to create phy\n"); + ret = PTR_ERR(phy); + goto put_child; + } + + instance->port_base = port_base; + instance->phy = pphy; + instance->index = port; + phy_set_drvdata(pphy, instance); + port++; + } + + provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); + + return PTR_ERR_OR_ZERO(provider); + +put_child: + of_node_put(child_np); + return ret; +} + +static const struct of_device_id mt7621_pci_phy_ids[] = { + { .compatible = "mediatek,mt7621-pci-phy" }, + {}, +}; +MODULE_DEVICE_TABLE(of, mt7621_pci_ids); + +static struct platform_driver mt7621_pci_phy_driver = { + .probe = mt7621_pci_phy_probe, + .driver = { + .name = "mt7621-pci-phy", + .of_match_table = of_match_ptr(mt7621_pci_phy_ids), + }, +}; + +static int __init mt7621_pci_phy_drv_init(void) +{ + return platform_driver_register(&mt7621_pci_phy_driver); +} + +module_init(mt7621_pci_phy_drv_init); + +MODULE_AUTHOR("Sergio Paracuellos <sergio.paracuellos@gmail.com>"); +MODULE_DESCRIPTION("MediaTek MT7621 PCIe PHY driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/mt7621-pci/Makefile b/drivers/staging/mt7621-pci/Makefile index 607b84bedcc3..d4655a726b61 100644 --- a/drivers/staging/mt7621-pci/Makefile +++ b/drivers/staging/mt7621-pci/Makefile @@ -1 +1 @@ -obj-$(CONFIG_SOC_MT7621) += pci-mt7621.o +obj-$(CONFIG_PCI_MT7621) += pci-mt7621.o diff --git a/drivers/staging/mt7621-pci/TODO b/drivers/staging/mt7621-pci/TODO index cf30f629b9fd..ccfd266db4ca 100644 --- a/drivers/staging/mt7621-pci/TODO +++ b/drivers/staging/mt7621-pci/TODO @@ -1,12 +1,4 @@ - general code review and cleanup -- can this be converted to not require PCI_DRIVERS_LEGACY ?? - The irq returned by pcibios_map_irq is a "hwirq" (hardware irq number) - and pci_assign_irq() assigns this directly to dev->irq, which - expects a "virq" (virtual irq number). These numbers are different - on MIPS. There is a gross hack to make it work on one - specific platform, so it can be tested. -- Should this be merged with arch/mips/pci/pci-mt7620.c ?? -- ensure device-tree requirements are documented Cc: NeilBrown <neil@brown.name> diff --git a/drivers/staging/mt7621-pci/pci-mt7621.c b/drivers/staging/mt7621-pci/pci-mt7621.c index 31310b6fb7db..379ae780c691 100644 --- a/drivers/staging/mt7621-pci/pci-mt7621.c +++ b/drivers/staging/mt7621-pci/pci-mt7621.c @@ -25,6 +25,7 @@ #include <linux/of_pci.h> #include <linux/of_platform.h> #include <linux/pci.h> +#include <linux/phy/phy.h> #include <linux/platform_device.h> #include <linux/reset.h> #include <mt7621.h> @@ -34,13 +35,8 @@ /* sysctl */ #define MT7621_CHIP_REV_ID 0x0c -#define RALINK_CLKCFG1 0x30 -#define RALINK_RSTCTRL 0x34 #define CHIP_REV_MT7621_E2 0x0101 -/* RALINK_RSTCTRL bits */ -#define RALINK_PCIE_RST BIT(23) - /* MediaTek specific configuration registers */ #define PCIE_FTS_NUM 0x70c #define PCIE_FTS_NUM_MASK GENMASK(15, 8) @@ -90,81 +86,16 @@ #define PCIE_CLK_GEN_EN BIT(31) #define PCIE_CLK_GEN_DIS 0 -#define PCIE_CLK_GEN1_DIS GENMASK(30,24) +#define PCIE_CLK_GEN1_DIS GENMASK(30, 24) #define PCIE_CLK_GEN1_EN (BIT(27) | BIT(25)) -#define RALINK_PCI_IO_MAP_BASE 0x1e160000 #define MEMORY_BASE 0x0 -/* pcie phy related macros */ -#define RALINK_PCIEPHY_P0P1_CTL_OFFSET 0x9000 -#define RALINK_PCIEPHY_P2_CTL_OFFSET 0xA000 - -#define RG_P0_TO_P1_WIDTH 0x100 - -#define RG_PE1_PIPE_REG 0x02c -#define RG_PE1_PIPE_RST BIT(12) -#define RG_PE1_PIPE_CMD_FRC BIT(4) - -#define RG_PE1_H_LCDDS_REG 0x49c -#define RG_PE1_H_LCDDS_PCW GENMASK(30, 0) -#define RG_PE1_H_LCDDS_PCW_VAL(x) ((0x7fffffff & (x)) << 0) - -#define RG_PE1_FRC_H_XTAL_REG 0x400 -#define RG_PE1_FRC_H_XTAL_TYPE BIT(8) -#define RG_PE1_H_XTAL_TYPE GENMASK(10, 9) -#define RG_PE1_H_XTAL_TYPE_VAL(x) ((0x3 & (x)) << 9) - -#define RG_PE1_FRC_PHY_REG 0x000 -#define RG_PE1_FRC_PHY_EN BIT(4) -#define RG_PE1_PHY_EN BIT(5) - -#define RG_PE1_H_PLL_REG 0x490 -#define RG_PE1_H_PLL_BC GENMASK(23, 22) -#define RG_PE1_H_PLL_BC_VAL(x) ((0x3 & (x)) << 22) -#define RG_PE1_H_PLL_BP GENMASK(21, 18) -#define RG_PE1_H_PLL_BP_VAL(x) ((0xf & (x)) << 18) -#define RG_PE1_H_PLL_IR GENMASK(15, 12) -#define RG_PE1_H_PLL_IR_VAL(x) ((0xf & (x)) << 12) -#define RG_PE1_H_PLL_IC GENMASK(11, 8) -#define RG_PE1_H_PLL_IC_VAL(x) ((0xf & (x)) << 8) -#define RG_PE1_H_PLL_PREDIV GENMASK(7, 6) -#define RG_PE1_H_PLL_PREDIV_VAL(x) ((0x3 & (x)) << 6) -#define RG_PE1_PLL_DIVEN GENMASK(3, 1) -#define RG_PE1_PLL_DIVEN_VAL(x) ((0x7 & (x)) << 1) - -#define RG_PE1_H_PLL_FBKSEL_REG 0x4bc -#define RG_PE1_H_PLL_FBKSEL GENMASK(5, 4) -#define RG_PE1_H_PLL_FBKSEL_VAL(x) ((0x3 & (x)) << 4) - -#define RG_PE1_H_LCDDS_SSC_PRD_REG 0x4a4 -#define RG_PE1_H_LCDDS_SSC_PRD GENMASK(15, 0) -#define RG_PE1_H_LCDDS_SSC_PRD_VAL(x) ((0xffff & (x)) << 0) - -#define RG_PE1_H_LCDDS_SSC_DELTA_REG 0x4a8 -#define RG_PE1_H_LCDDS_SSC_DELTA GENMASK(11, 0) -#define RG_PE1_H_LCDDS_SSC_DELTA_VAL(x) ((0xfff & (x)) << 0) -#define RG_PE1_H_LCDDS_SSC_DELTA1 GENMASK(27, 16) -#define RG_PE1_H_LCDDS_SSC_DELTA1_VAL(x) ((0xff & (x)) << 16) - -#define RG_PE1_LCDDS_CLK_PH_INV_REG 0x4a0 -#define RG_PE1_LCDDS_CLK_PH_INV BIT(5) - -#define RG_PE1_H_PLL_BR_REG 0x4ac -#define RG_PE1_H_PLL_BR GENMASK(18, 16) -#define RG_PE1_H_PLL_BR_VAL(x) ((0x7 & (x)) << 16) - -#define RG_PE1_MSTCKDIV_REG 0x414 -#define RG_PE1_MSTCKDIV GENMASK(7, 6) -#define RG_PE1_MSTCKDIV_VAL(x) ((0x3 & (x)) << 6) - -#define RG_PE1_FRC_MSTCKDIV BIT(5) - /** * struct mt7621_pcie_port - PCIe port information * @base: I/O mapped register base * @list: port list * @pcie: pointer to PCIe host info - * @phy_reg_offset: offset to related phy registers + * @phy: pointer to PHY control block * @pcie_rst: pointer to port reset control * @slot: port slot * @enabled: indicates if port is enabled @@ -173,7 +104,7 @@ struct mt7621_pcie_port { void __iomem *base; struct list_head list; struct mt7621_pcie *pcie; - u32 phy_reg_offset; + struct phy *phy; struct reset_control *pcie_rst; u32 slot; bool enabled; @@ -188,6 +119,7 @@ struct mt7621_pcie_port { * @offset: IO / Memory offset * @dev: Pointer to PCIe device * @ports: pointer to PCIe port information + * @rst: pointer to pcie reset */ struct mt7621_pcie { void __iomem *base; @@ -200,6 +132,7 @@ struct mt7621_pcie { resource_size_t io; } offset; struct list_head ports; + struct reset_control *rst; }; static inline u32 pcie_read(struct mt7621_pcie *pcie, u32 reg) @@ -265,150 +198,6 @@ static void write_config(struct mt7621_pcie *pcie, unsigned int dev, pcie_write(pcie, val, RALINK_PCI_CONFIG_DATA); } -static void bypass_pipe_rst(struct mt7621_pcie_port *port) -{ - struct mt7621_pcie *pcie = port->pcie; - u32 phy_offset = port->phy_reg_offset; - u32 offset = (port->slot != 1) ? - phy_offset + RG_PE1_PIPE_REG : - phy_offset + RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH; - u32 reg = pcie_read(pcie, offset); - - reg &= ~(RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC); - reg |= (RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC); - pcie_write(pcie, reg, offset); -} - -static void set_phy_for_ssc(struct mt7621_pcie_port *port) -{ - struct mt7621_pcie *pcie = port->pcie; - struct device *dev = pcie->dev; - u32 phy_offset = port->phy_reg_offset; - u32 reg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0); - u32 offset; - u32 val; - - reg = (reg >> 6) & 0x7; - /* Set PCIe Port PHY to disable SSC */ - /* Debug Xtal Type */ - offset = phy_offset + RG_PE1_FRC_H_XTAL_REG; - val = pcie_read(pcie, offset); - val &= ~(RG_PE1_FRC_H_XTAL_TYPE | RG_PE1_H_XTAL_TYPE); - val |= RG_PE1_FRC_H_XTAL_TYPE; - val |= RG_PE1_H_XTAL_TYPE_VAL(0x00); - pcie_write(pcie, val, offset); - - /* disable port */ - offset = (port->slot != 1) ? - phy_offset + RG_PE1_FRC_PHY_REG : - phy_offset + RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH; - val = pcie_read(pcie, offset); - val &= ~(RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN); - val |= RG_PE1_FRC_PHY_EN; - pcie_write(pcie, val, offset); - - /* Set Pre-divider ratio (for host mode) */ - offset = phy_offset + RG_PE1_H_PLL_REG; - val = pcie_read(pcie, offset); - val &= ~(RG_PE1_H_PLL_PREDIV); - - if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */ - val |= RG_PE1_H_PLL_PREDIV_VAL(0x01); - pcie_write(pcie, val, offset); - dev_info(dev, "Xtal is 40MHz\n"); - } else { /* 25MHz | 20MHz Xtal */ - val |= RG_PE1_H_PLL_PREDIV_VAL(0x00); - pcie_write(pcie, val, offset); - if (reg >= 6) { - dev_info(dev, "Xtal is 25MHz\n"); - - /* Select feedback clock */ - offset = phy_offset + RG_PE1_H_PLL_FBKSEL_REG; - val = pcie_read(pcie, offset); - val &= ~(RG_PE1_H_PLL_FBKSEL); - val |= RG_PE1_H_PLL_FBKSEL_VAL(0x01); - pcie_write(pcie, val, offset); - - /* DDS NCPO PCW (for host mode) */ - offset = phy_offset + RG_PE1_H_LCDDS_SSC_PRD_REG; - val = pcie_read(pcie, offset); - val &= ~(RG_PE1_H_LCDDS_SSC_PRD); - val |= RG_PE1_H_LCDDS_SSC_PRD_VAL(0x18000000); - pcie_write(pcie, val, offset); - - /* DDS SSC dither period control */ - offset = phy_offset + RG_PE1_H_LCDDS_SSC_PRD_REG; - val = pcie_read(pcie, offset); - val &= ~(RG_PE1_H_LCDDS_SSC_PRD); - val |= RG_PE1_H_LCDDS_SSC_PRD_VAL(0x18d); - pcie_write(pcie, val, offset); - - /* DDS SSC dither amplitude control */ - offset = phy_offset + RG_PE1_H_LCDDS_SSC_DELTA_REG; - val = pcie_read(pcie, offset); - val &= ~(RG_PE1_H_LCDDS_SSC_DELTA | - RG_PE1_H_LCDDS_SSC_DELTA1); - val |= RG_PE1_H_LCDDS_SSC_DELTA_VAL(0x4a); - val |= RG_PE1_H_LCDDS_SSC_DELTA1_VAL(0x4a); - pcie_write(pcie, val, offset); - } else { - dev_info(dev, "Xtal is 20MHz\n"); - } - } - - /* DDS clock inversion */ - offset = phy_offset + RG_PE1_LCDDS_CLK_PH_INV_REG; - val = pcie_read(pcie, offset); - val &= ~(RG_PE1_LCDDS_CLK_PH_INV); - val |= RG_PE1_LCDDS_CLK_PH_INV; - pcie_write(pcie, val, offset); - - /* Set PLL bits */ - offset = phy_offset + RG_PE1_H_PLL_REG; - val = pcie_read(pcie, offset); - val &= ~(RG_PE1_H_PLL_BC | RG_PE1_H_PLL_BP | RG_PE1_H_PLL_IR | - RG_PE1_H_PLL_IC | RG_PE1_PLL_DIVEN); - val |= RG_PE1_H_PLL_BC_VAL(0x02); - val |= RG_PE1_H_PLL_BP_VAL(0x06); - val |= RG_PE1_H_PLL_IR_VAL(0x02); - val |= RG_PE1_H_PLL_IC_VAL(0x01); - val |= RG_PE1_PLL_DIVEN_VAL(0x02); - pcie_write(pcie, val, offset); - - offset = phy_offset + RG_PE1_H_PLL_BR_REG; - val = pcie_read(pcie, offset); - val &= ~(RG_PE1_H_PLL_BR); - val |= RG_PE1_H_PLL_BR_VAL(0x00); - pcie_write(pcie, val, offset); - - if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */ - /* set force mode enable of da_pe1_mstckdiv */ - offset = phy_offset + RG_PE1_MSTCKDIV_REG; - val = pcie_read(pcie, offset); - val &= ~(RG_PE1_MSTCKDIV | RG_PE1_FRC_MSTCKDIV); - val |= (RG_PE1_MSTCKDIV_VAL(0x01) | RG_PE1_FRC_MSTCKDIV); - pcie_write(pcie, val, offset); - } - - /* Enable PHY and disable force mode */ - offset = (port->slot != 1) ? - phy_offset + RG_PE1_FRC_PHY_REG : - phy_offset + RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH; - val = pcie_read(pcie, offset); - val &= ~(RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN); - val |= (RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN); - pcie_write(pcie, val, offset); -} - -static void mt7621_enable_phy(struct mt7621_pcie_port *port) -{ - u32 chip_rev_id = rt_sysc_r32(MT7621_CHIP_REV_ID); - - if ((chip_rev_id & 0xFFFF) == CHIP_REV_MT7621_E2) - bypass_pipe_rst(port); - set_phy_for_ssc(port); -} - static inline void mt7621_control_assert(struct mt7621_pcie_port *port) { u32 chip_rev_id = rt_sysc_r32(MT7621_CHIP_REV_ID); @@ -510,7 +299,7 @@ static int mt7621_pcie_parse_port(struct mt7621_pcie *pcie, struct device *dev = pcie->dev; struct device_node *pnode = dev->of_node; struct resource regs; - char name[6]; + char name[10]; int err; port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL); @@ -534,11 +323,13 @@ static int mt7621_pcie_parse_port(struct mt7621_pcie *pcie, return PTR_ERR(port->pcie_rst); } + snprintf(name, sizeof(name), "pcie-phy%d", slot); + port->phy = devm_phy_get(dev, name); + if (IS_ERR(port->phy)) + return PTR_ERR(port->phy); + port->slot = slot; port->pcie = pcie; - port->phy_reg_offset = (slot != 2) ? - RALINK_PCIEPHY_P0P1_CTL_OFFSET : - RALINK_PCIEPHY_P2_CTL_OFFSET; INIT_LIST_HEAD(&port->list); list_add_tail(&port->list, &pcie->ports); @@ -563,6 +354,12 @@ static int mt7621_pcie_parse_dt(struct mt7621_pcie *pcie) if (IS_ERR(pcie->base)) return PTR_ERR(pcie->base); + pcie->rst = devm_reset_control_get_exclusive(dev, "pcie"); + if (PTR_ERR(pcie->rst) == -EPROBE_DEFER) { + dev_err(dev, "failed to get pcie reset control\n"); + return PTR_ERR(pcie->rst); + } + for_each_available_child_of_node(node, child) { int slot; @@ -588,6 +385,7 @@ static int mt7621_pcie_init_port(struct mt7621_pcie_port *port) struct device *dev = pcie->dev; u32 slot = port->slot; u32 val = 0; + int err; /* * Any MT7621 Ralink pcie controller that doesn't have 0x0101 at @@ -598,18 +396,36 @@ static int mt7621_pcie_init_port(struct mt7621_pcie_port *port) val = read_config(pcie, slot, PCIE_FTS_NUM); dev_info(dev, "Port %d N_FTS = %x\n", (unsigned int)val, slot); + err = phy_init(port->phy); + if (err) { + dev_err(dev, "failed to initialize port%d phy\n", slot); + goto err_phy_init; + } + + err = phy_power_on(port->phy); + if (err) { + dev_err(dev, "failed to power on port%d phy\n", slot); + goto err_phy_on; + } + if ((pcie_port_read(port, RALINK_PCI_STATUS) & PCIE_PORT_LINKUP) == 0) { dev_err(dev, "pcie%d no card, disable it (RST & CLK)\n", slot); mt7621_control_assert(port); - rt_sysc_m32(PCIE_PORT_CLK_EN(slot), 0, RALINK_CLKCFG1); port->enabled = false; - } else { - port->enabled = true; + err = -ENODEV; + goto err_no_link_up; } - mt7621_enable_phy(port); + port->enabled = true; return 0; + +err_no_link_up: + phy_power_off(port->phy); +err_phy_on: + phy_exit(port->phy); +err_phy_init: + return err; } static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie) @@ -628,13 +444,13 @@ static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie) } } - rt_sysc_m32(0, RALINK_PCIE_RST, RALINK_RSTCTRL); + reset_control_assert(pcie->rst); rt_sysc_m32(0x30, 2 << 4, SYSC_REG_SYSTEM_CONFIG1); rt_sysc_m32(PCIE_CLK_GEN_EN, PCIE_CLK_GEN_DIS, RALINK_PCIE_CLK_GEN); rt_sysc_m32(PCIE_CLK_GEN1_DIS, PCIE_CLK_GEN1_EN, RALINK_PCIE_CLK_GEN1); rt_sysc_m32(PCIE_CLK_GEN_DIS, PCIE_CLK_GEN_EN, RALINK_PCIE_CLK_GEN); msleep(50); - rt_sysc_m32(RALINK_PCIE_RST, 0, RALINK_RSTCTRL); + reset_control_deassert(pcie->rst); } static int mt7621_pcie_enable_port(struct mt7621_pcie_port *port) @@ -690,7 +506,7 @@ static void mt7621_pcie_enable_ports(struct mt7621_pcie *pcie) list_for_each_entry(port, &pcie->ports, list) { if (port->enabled) { - if (!mt7621_pcie_enable_port(port)) { + if (mt7621_pcie_enable_port(port)) { dev_err(dev, "de-assert port %d PERST_N\n", port->slot); continue; @@ -701,8 +517,9 @@ static void mt7621_pcie_enable_ports(struct mt7621_pcie *pcie) } for (slot = 0; slot < num_slots_enabled; slot++) { - val = read_config(pcie, slot, 0x4); - write_config(pcie, slot, 0x4, val | 0x4); + val = read_config(pcie, slot, PCI_COMMAND); + val |= PCI_COMMAND_MASTER; + write_config(pcie, slot, PCI_COMMAND, val); /* configure RC FTS number to 250 when it leaves L0s */ val = read_config(pcie, slot, PCIE_FTS_NUM); val &= ~PCIE_FTS_NUM_MASK; @@ -714,7 +531,7 @@ static void mt7621_pcie_enable_ports(struct mt7621_pcie *pcie) static int mt7621_pcie_init_virtual_bridges(struct mt7621_pcie *pcie) { u32 pcie_link_status = 0; - u32 val= 0; + u32 val = 0; struct mt7621_pcie_port *port; list_for_each_entry(port, &pcie->ports, list) { @@ -728,15 +545,15 @@ static int mt7621_pcie_init_virtual_bridges(struct mt7621_pcie *pcie) return -1; /* - * pcie(2/1/0) link status pcie2_num pcie1_num pcie0_num - * 3'b000 x x x - * 3'b001 x x 0 - * 3'b010 x 0 x - * 3'b011 x 1 0 - * 3'b100 0 x x - * 3'b101 1 x 0 - * 3'b110 1 0 x - * 3'b111 2 1 0 + * pcie(2/1/0) link status pcie2_num pcie1_num pcie0_num + * 3'b000 x x x + * 3'b001 x x 0 + * 3'b010 x 0 x + * 3'b011 x 1 0 + * 3'b100 0 x x + * 3'b101 1 x 0 + * 3'b110 1 0 x + * 3'b111 2 1 0 */ switch (pcie_link_status) { case 2: @@ -848,9 +665,6 @@ static int mt7621_pci_probe(struct platform_device *pdev) return 0; } - pcie_write(pcie, 0xffffffff, RALINK_PCI_MEMBASE); - pcie_write(pcie, RALINK_PCI_IO_MAP_BASE, RALINK_PCI_IOBASE); - mt7621_pcie_enable_ports(pcie); err = mt7621_pci_parse_request_of_pci_ranges(pcie); diff --git a/drivers/staging/mt7621-pinctrl/Kconfig b/drivers/staging/mt7621-pinctrl/Kconfig index 37cf9c3273be..fc3612711307 100644 --- a/drivers/staging/mt7621-pinctrl/Kconfig +++ b/drivers/staging/mt7621-pinctrl/Kconfig @@ -2,3 +2,4 @@ config PINCTRL_RT2880 bool "RT2800 pinctrl driver for RALINK/Mediatek SOCs" depends on RALINK select PINMUX + select GENERIC_PINCONF diff --git a/drivers/staging/mt7621-pinctrl/pinctrl-rt2880.c b/drivers/staging/mt7621-pinctrl/pinctrl-rt2880.c index aa98fbb17013..9b52d44abef1 100644 --- a/drivers/staging/mt7621-pinctrl/pinctrl-rt2880.c +++ b/drivers/staging/mt7621-pinctrl/pinctrl-rt2880.c @@ -11,6 +11,7 @@ #include <linux/of.h> #include <linux/pinctrl/pinctrl.h> #include <linux/pinctrl/pinconf.h> +#include <linux/pinctrl/pinconf-generic.h> #include <linux/pinctrl/pinmux.h> #include <linux/pinctrl/consumer.h> #include <linux/pinctrl/machine.h> @@ -73,48 +74,12 @@ static int rt2880_get_group_pins(struct pinctrl_dev *pctrldev, return 0; } -static int rt2880_pinctrl_dt_node_to_map(struct pinctrl_dev *pctrldev, - struct device_node *np_config, - struct pinctrl_map **map, - unsigned int *num_maps) -{ - struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev); - struct property *prop; - const char *function_name, *group_name; - int ret; - int ngroups = 0; - unsigned int reserved_maps = 0; - - for_each_node_with_property(np_config, "group") - ngroups++; - - *map = NULL; - ret = pinctrl_utils_reserve_map(pctrldev, map, &reserved_maps, - num_maps, ngroups); - if (ret) { - dev_err(p->dev, "can't reserve map: %d\n", ret); - return ret; - } - - of_property_for_each_string(np_config, "group", prop, group_name) { - ret = pinctrl_utils_add_map_mux(pctrldev, map, &reserved_maps, - num_maps, group_name, - function_name); - if (ret) { - dev_err(p->dev, "can't add map: %d\n", ret); - return ret; - } - } - - return 0; -} - static const struct pinctrl_ops rt2880_pctrl_ops = { .get_groups_count = rt2880_get_group_count, .get_group_name = rt2880_get_group_name, .get_group_pins = rt2880_get_group_pins, - .dt_node_to_map = rt2880_pinctrl_dt_node_to_map, - .dt_free_map = pinctrl_utils_free_map, + .dt_node_to_map = pinconf_generic_dt_node_to_map_all, + .dt_free_map = pinconf_generic_dt_free_map, }; static int rt2880_pmx_func_count(struct pinctrl_dev *pctrldev) @@ -385,7 +350,6 @@ static int rt2880_pinmux_probe(struct platform_device *pdev) for_each_compatible_node(np, NULL, "ralink,rt2880-gpio") { const __be32 *ngpio, *gpiobase; struct pinctrl_gpio_range *range; - char *name; if (!of_device_is_available(np)) continue; @@ -397,9 +361,10 @@ static int rt2880_pinmux_probe(struct platform_device *pdev) return -EINVAL; } - range = devm_kzalloc(p->dev, sizeof(*range) + 4, GFP_KERNEL); - range->name = name = (char *) &range[1]; - sprintf(name, "pio"); + range = devm_kzalloc(p->dev, sizeof(*range), GFP_KERNEL); + if (!range) + return -ENOMEM; + range->name = "pio"; range->npins = __be32_to_cpu(*ngpio); range->base = __be32_to_cpu(*gpiobase); range->pin_base = range->base; diff --git a/drivers/staging/mt7621-spi/spi-mt7621.c b/drivers/staging/mt7621-spi/spi-mt7621.c index 513b6e79b985..b509f9fe3346 100644 --- a/drivers/staging/mt7621-spi/spi-mt7621.c +++ b/drivers/staging/mt7621-spi/spi-mt7621.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * spi-mt7621.c -- MediaTek MT7621 SPI controller driver * @@ -8,34 +9,23 @@ * Some parts are based on spi-orion.c: * Author: Shadi Ammouri <shadi@marvell.com> * Copyright (C) 2007-2008 Marvell Ltd. - * - * 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. */ -#include <linux/init.h> -#include <linux/module.h> #include <linux/clk.h> -#include <linux/err.h> #include <linux/delay.h> #include <linux/io.h> +#include <linux/module.h> +#include <linux/of_device.h> #include <linux/reset.h> #include <linux/spi/spi.h> -#include <linux/of_device.h> -#include <linux/platform_device.h> -#include <linux/swab.h> - -#include <ralink_regs.h> -#define SPI_BPW_MASK(bits) BIT((bits) - 1) +#define DRIVER_NAME "spi-mt7621" -#define DRIVER_NAME "spi-mt7621" /* in usec */ -#define RALINK_SPI_WAIT_MAX_LOOP 2000 +#define RALINK_SPI_WAIT_MAX_LOOP 2000 /* SPISTAT register bit field */ -#define SPISTAT_BUSY BIT(0) +#define SPISTAT_BUSY BIT(0) #define MT7621_SPI_TRANS 0x00 #define SPITRANS_BUSY BIT(16) @@ -46,17 +36,21 @@ #define SPI_CTL_TX_RX_CNT_MASK 0xff #define SPI_CTL_START BIT(8) -#define MT7621_SPI_POLAR 0x38 #define MT7621_SPI_MASTER 0x28 +#define MASTER_MORE_BUFMODE BIT(2) +#define MASTER_FULL_DUPLEX BIT(10) +#define MASTER_RS_CLK_SEL GENMASK(27, 16) +#define MASTER_RS_CLK_SEL_SHIFT 16 +#define MASTER_RS_SLAVE_SEL GENMASK(31, 29) + #define MT7621_SPI_MOREBUF 0x2c +#define MT7621_SPI_POLAR 0x38 #define MT7621_SPI_SPACE 0x3c #define MT7621_CPHA BIT(5) #define MT7621_CPOL BIT(4) #define MT7621_LSB_FIRST BIT(3) -struct mt7621_spi; - struct mt7621_spi { struct spi_master *master; void __iomem *base; @@ -87,9 +81,13 @@ static void mt7621_spi_reset(struct mt7621_spi *rs) { u32 master = mt7621_spi_read(rs, MT7621_SPI_MASTER); - master |= 7 << 29; - master |= 1 << 2; - master &= ~(1 << 10); + /* + * Select SPI device 7, enable "more buffer mode" and disable + * full-duplex (only half-duplex really works on this chip + * reliably) + */ + master |= MASTER_RS_SLAVE_SEL | MASTER_MORE_BUFMODE; + master &= ~MASTER_FULL_DUPLEX; mt7621_spi_write(rs, MT7621_SPI_MASTER, master); rs->pending_write = 0; @@ -125,18 +123,18 @@ static int mt7621_spi_prepare(struct spi_device *spi, unsigned int speed) rate = 2; reg = mt7621_spi_read(rs, MT7621_SPI_MASTER); - reg &= ~(0xfff << 16); - reg |= (rate - 2) << 16; + reg &= ~MASTER_RS_CLK_SEL; + reg |= (rate - 2) << MASTER_RS_CLK_SEL_SHIFT; rs->speed = speed; reg &= ~MT7621_LSB_FIRST; if (spi->mode & SPI_LSB_FIRST) reg |= MT7621_LSB_FIRST; - /* This SPI controller seems to be tested on SPI flash only - * and some bits are swizzled under other SPI modes probably - * due to incorrect wiring inside the silicon. Only mode 0 - * works correctly. + /* + * This SPI controller seems to be tested on SPI flash only and some + * bits are swizzled under other SPI modes probably due to incorrect + * wiring inside the silicon. Only mode 0 works correctly. */ reg &= ~(MT7621_CPHA | MT7621_CPOL); @@ -165,9 +163,10 @@ static inline int mt7621_spi_wait_till_ready(struct mt7621_spi *rs) static void mt7621_spi_read_half_duplex(struct mt7621_spi *rs, int rx_len, u8 *buf) { - /* Combine with any pending write, and perform one or - * more half-duplex transactions reading 'len' bytes. - * Data to be written is already in MT7621_SPI_DATA* + /* + * Combine with any pending write, and perform one or more half-duplex + * transactions reading 'len' bytes. Data to be written is already in + * MT7621_SPI_DATA. */ int tx_len = rs->pending_write; @@ -197,6 +196,7 @@ static void mt7621_spi_read_half_duplex(struct mt7621_spi *rs, *buf++ = val & 0xff; val >>= 8; } + rx_len -= i; } } @@ -290,6 +290,7 @@ static int mt7621_spi_transfer_one_message(struct spi_master *master, mt7621_spi_flush(rs); mt7621_spi_set_cs(spi, 0); + msg_done: m->status = status; spi_finalize_current_message(master); @@ -330,6 +331,7 @@ static int mt7621_spi_probe(struct platform_device *pdev) int status = 0; struct clk *clk; struct mt7621_spi_ops *ops; + int ret; match = of_match_device(mt7621_spi_match, &pdev->dev); if (!match) @@ -353,7 +355,7 @@ static int mt7621_spi_probe(struct platform_device *pdev) return status; master = spi_alloc_master(&pdev->dev, sizeof(*rs)); - if (master == NULL) { + if (!master) { dev_info(&pdev->dev, "master allocation failed\n"); return -ENOMEM; } @@ -377,7 +379,11 @@ static int mt7621_spi_probe(struct platform_device *pdev) rs->pending_write = 0; dev_info(&pdev->dev, "sys_freq: %u\n", rs->sys_freq); - device_reset(&pdev->dev); + ret = device_reset(&pdev->dev); + if (ret) { + dev_err(&pdev->dev, "SPI reset failed!\n"); + return ret; + } mt7621_spi_reset(rs); diff --git a/drivers/staging/netlogic/Kconfig b/drivers/staging/netlogic/Kconfig index d660de51b541..c25a00dd2d5f 100644 --- a/drivers/staging/netlogic/Kconfig +++ b/drivers/staging/netlogic/Kconfig @@ -2,6 +2,6 @@ config NETLOGIC_XLR_NET tristate "Netlogic XLR/XLS network device" depends on CPU_XLR select PHYLIB - ---help--- + help This driver support Netlogic XLR/XLS on chip gigabit Ethernet. diff --git a/drivers/staging/netlogic/platform_net.c b/drivers/staging/netlogic/platform_net.c index abf4c71ee66b..8be9d0b0c22c 100644 --- a/drivers/staging/netlogic/platform_net.c +++ b/drivers/staging/netlogic/platform_net.c @@ -1,36 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) /* * Copyright (c) 2003-2012 Broadcom Corporation * All Rights Reserved - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * 1. Redistributions of source code must retain the above copyright - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the Broadcom - * license below: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include <linux/device.h> @@ -107,8 +78,9 @@ static struct platform_device *gmac_controller2_init(void *gmac0_addr) .dev.platform_data = &ndata1, }; - gmac4_addr = ioremap(CPHYSADDR( - nlm_mmio_base(NETLOGIC_IO_GMAC_4_OFFSET)), 0xfff); + gmac4_addr = + ioremap(CPHYSADDR(nlm_mmio_base(NETLOGIC_IO_GMAC_4_OFFSET)), + 0xfff); ndata1.serdes_addr = gmac4_addr; ndata1.pcs_addr = gmac4_addr; ndata1.mii_addr = gmac0_addr; @@ -134,8 +106,9 @@ static void xls_gmac_init(void) { int mac; struct platform_device *xlr_net_dev1; - void __iomem *gmac0_addr = ioremap(CPHYSADDR( - nlm_mmio_base(NETLOGIC_IO_GMAC_0_OFFSET)), 0xfff); + void __iomem *gmac0_addr = + ioremap(CPHYSADDR(nlm_mmio_base(NETLOGIC_IO_GMAC_0_OFFSET)), + 0xfff); static struct xlr_net_data ndata0 = { .rfr_station = FMN_STNID_GMACRFR_0, @@ -153,8 +126,9 @@ static void xls_gmac_init(void) ndata0.mii_addr = gmac0_addr; /* Passing GPIO base for serdes init. Only needed on sgmii ports */ - gpio_addr = ioremap(CPHYSADDR( - nlm_mmio_base(NETLOGIC_IO_GPIO_OFFSET)), 0xfff); + gpio_addr = + ioremap(CPHYSADDR(nlm_mmio_base(NETLOGIC_IO_GPIO_OFFSET)), + 0xfff); ndata0.gpio_addr = gpio_addr; ndata0.cpu_mask = nlm_current_node()->coremask; @@ -214,8 +188,9 @@ static void xlr_gmac_init(void) .id = 0, .dev.platform_data = &ndata0, }; - ndata0.mii_addr = ioremap(CPHYSADDR( - nlm_mmio_base(NETLOGIC_IO_GMAC_0_OFFSET)), 0xfff); + ndata0.mii_addr = + ioremap(CPHYSADDR(nlm_mmio_base(NETLOGIC_IO_GMAC_0_OFFSET)), + 0xfff); ndata0.cpu_mask = nlm_current_node()->coremask; diff --git a/drivers/staging/netlogic/platform_net.h b/drivers/staging/netlogic/platform_net.h index e1b27f649590..f152d84099a2 100644 --- a/drivers/staging/netlogic/platform_net.h +++ b/drivers/staging/netlogic/platform_net.h @@ -1,35 +1,7 @@ -/* +/* SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) + * * Copyright (c) 2003-2012 Broadcom Corporation * All Rights Reserved - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the Broadcom - * license below: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #define PORTS_PER_CONTROLLER 4 diff --git a/drivers/staging/netlogic/xlr_net.c b/drivers/staging/netlogic/xlr_net.c index 4e6611e4c59b..8554fcf4321b 100644 --- a/drivers/staging/netlogic/xlr_net.c +++ b/drivers/staging/netlogic/xlr_net.c @@ -1,36 +1,9 @@ +// SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) /* * Copyright (c) 2003-2012 Broadcom Corporation * All Rights Reserved - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the Broadcom - * license below: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + #include <linux/phy.h> #include <linux/delay.h> #include <linux/netdevice.h> diff --git a/drivers/staging/netlogic/xlr_net.h b/drivers/staging/netlogic/xlr_net.h index f76e16cfd15d..518ea809b8fa 100644 --- a/drivers/staging/netlogic/xlr_net.h +++ b/drivers/staging/netlogic/xlr_net.h @@ -1,36 +1,9 @@ -/* +/* SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) + * * Copyright (c) 2003-2012 Broadcom Corporation * All Rights Reserved - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the Broadcom - * license below: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /* #define MAC_SPLIT_MODE */ #define MAC_SPACING 0x400 diff --git a/drivers/staging/octeon-usb/octeon-hcd.h b/drivers/staging/octeon-usb/octeon-hcd.h index 769c36cf6614..ae7ae50071ae 100644 --- a/drivers/staging/octeon-usb/octeon-hcd.h +++ b/drivers/staging/octeon-usb/octeon-hcd.h @@ -1797,7 +1797,7 @@ union cvmx_usbnx_usbp_ctl_status { * This is a test signal. When the USB Core is * powered up (not in Susned Mode), an automatic * tester can use this to disable phy_clock and - * free_clk, then re-eanable them with an aligned + * free_clk, then re-enable them with an aligned * phase. * '1': The phy_clk and free_clk outputs are * disabled. "0": The phy_clock and free_clk outputs diff --git a/drivers/staging/ralink-gdma/Kconfig b/drivers/staging/ralink-gdma/Kconfig new file mode 100644 index 000000000000..a12b2c672d48 --- /dev/null +++ b/drivers/staging/ralink-gdma/Kconfig @@ -0,0 +1,6 @@ +config DMA_RALINK + tristate "RALINK DMA support" + depends on RALINK && !SOC_RT288X + select DMA_ENGINE + select DMA_VIRTUAL_CHANNELS + diff --git a/drivers/staging/ralink-gdma/Makefile b/drivers/staging/ralink-gdma/Makefile new file mode 100644 index 000000000000..5d917e0729bb --- /dev/null +++ b/drivers/staging/ralink-gdma/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_DMA_RALINK) += ralink-gdma.o + +ccflags-y += -I$(srctree)/drivers/dma diff --git a/drivers/staging/mt7621-dma/ralink-gdma.c b/drivers/staging/ralink-gdma/ralink-gdma.c index 792a63bd55d4..d78042eba6dd 100644 --- a/drivers/staging/mt7621-dma/ralink-gdma.c +++ b/drivers/staging/ralink-gdma/ralink-gdma.c @@ -821,9 +821,9 @@ static int gdma_dma_probe(struct platform_device *pdev) return -EINVAL; data = (struct gdma_data *) match->data; - dma_dev = devm_kzalloc(&pdev->dev, sizeof(*dma_dev) + - (sizeof(struct gdma_dmaengine_chan) * data->chancnt), - GFP_KERNEL); + dma_dev = devm_kzalloc(&pdev->dev, + struct_size(dma_dev, chan, data->chancnt), + GFP_KERNEL); if (!dma_dev) { dev_err(&pdev->dev, "alloc dma device failed\n"); return -EINVAL; diff --git a/drivers/staging/rtl8188eu/core/rtw_ap.c b/drivers/staging/rtl8188eu/core/rtw_ap.c index 1f232ba6651c..94c9d9f8ee5c 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ap.c +++ b/drivers/staging/rtl8188eu/core/rtw_ap.c @@ -82,7 +82,7 @@ static void update_BCNTIM(struct adapter *padapter) /* calculate head_len */ offset = _FIXED_IE_LENGTH_; - offset += pnetwork_mlmeext->Ssid.SsidLength + 2; + offset += pnetwork_mlmeext->ssid.ssid_length + 2; /* get supported rates len */ p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, @@ -785,9 +785,9 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) /* SSID */ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SSID_IE_, &ie_len, (pbss_network->ie_length - _BEACON_IE_OFFSET_)); if (p && ie_len > 0) { - memset(&pbss_network->Ssid, 0, sizeof(struct ndis_802_11_ssid)); - memcpy(pbss_network->Ssid.Ssid, (p + 2), ie_len); - pbss_network->Ssid.SsidLength = ie_len; + memset(&pbss_network->ssid, 0, sizeof(struct ndis_802_11_ssid)); + memcpy(pbss_network->ssid.ssid, (p + 2), ie_len); + pbss_network->ssid.ssid_length = ie_len; } /* channel */ diff --git a/drivers/staging/rtl8188eu/core/rtw_cmd.c b/drivers/staging/rtl8188eu/core/rtw_cmd.c index 407f65cf7150..83a2e58aef53 100644 --- a/drivers/staging/rtl8188eu/core/rtw_cmd.c +++ b/drivers/staging/rtl8188eu/core/rtw_cmd.c @@ -263,7 +263,7 @@ u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid, int i; for (i = 0; i < ssid_num && i < RTW_SSID_SCAN_AMOUNT; i++) { - if (ssid[i].SsidLength) { + if (ssid[i].ssid_length) { memcpy(&psurveyPara->ssid[i], &ssid[i], sizeof(struct ndis_802_11_ssid)); psurveyPara->ssid_num++; } @@ -316,10 +316,10 @@ u8 rtw_createbss_cmd(struct adapter *padapter) led_control_8188eu(padapter, LED_CTL_START_TO_LINK); - if (pmlmepriv->assoc_ssid.SsidLength == 0) - RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, (" createbss for Any SSid:%s\n", pmlmepriv->assoc_ssid.Ssid)); + if (pmlmepriv->assoc_ssid.ssid_length == 0) + RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, (" createbss for Any SSid:%s\n", pmlmepriv->assoc_ssid.ssid)); else - RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, (" createbss for SSid:%s\n", pmlmepriv->assoc_ssid.Ssid)); + RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, (" createbss for SSid:%s\n", pmlmepriv->assoc_ssid.ssid)); pcmd = kzalloc(sizeof(*pcmd), GFP_ATOMIC); if (!pcmd) { @@ -358,10 +358,10 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) led_control_8188eu(padapter, LED_CTL_START_TO_LINK); - if (pmlmepriv->assoc_ssid.SsidLength == 0) + if (pmlmepriv->assoc_ssid.ssid_length == 0) RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("+Join cmd: Any SSid\n")); else - RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+Join cmd: SSid =[%s]\n", pmlmepriv->assoc_ssid.Ssid)); + RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+Join cmd: SSid =[%s]\n", pmlmepriv->assoc_ssid.ssid)); pcmd = kzalloc(sizeof(*pcmd), GFP_ATOMIC); if (!pcmd) { diff --git a/drivers/staging/rtl8188eu/core/rtw_efuse.c b/drivers/staging/rtl8188eu/core/rtw_efuse.c index b7be71f904ed..51c3dd6d7ffb 100644 --- a/drivers/staging/rtl8188eu/core/rtw_efuse.c +++ b/drivers/staging/rtl8188eu/core/rtw_efuse.c @@ -88,7 +88,9 @@ efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8 *pbuf) if (!efuseTbl) return; - tmp = kzalloc(EFUSE_MAX_SECTION_88E * (sizeof(void *) + EFUSE_MAX_WORD_UNIT * sizeof(u16)), GFP_KERNEL); + tmp = kcalloc(EFUSE_MAX_SECTION_88E, + sizeof(void *) + EFUSE_MAX_WORD_UNIT * sizeof(u16), + GFP_KERNEL); if (!tmp) { DBG_88E("%s: alloc eFuseWord fail!\n", __func__); goto eFuseWord_failed; diff --git a/drivers/staging/rtl8188eu/core/rtw_ieee80211.c b/drivers/staging/rtl8188eu/core/rtw_ieee80211.c index 5c4ff81987bd..094e8e78f0e8 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ieee80211.c +++ b/drivers/staging/rtl8188eu/core/rtw_ieee80211.c @@ -234,7 +234,7 @@ int rtw_generate_ie(struct registry_priv *pregistrypriv) ie += 2; /* SSID */ - ie = rtw_set_ie(ie, _SSID_IE_, pdev_network->Ssid.SsidLength, pdev_network->Ssid.Ssid, &sz); + ie = rtw_set_ie(ie, _SSID_IE_, pdev_network->ssid.ssid_length, pdev_network->ssid.ssid, &sz); /* supported rates */ if (pregistrypriv->wireless_mode == WIRELESS_11ABGN) { @@ -927,7 +927,7 @@ static int rtw_get_cipher_info(struct wlan_network *pnetwork) if (pbuf && (wpa_ielen > 0)) { RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s: wpa_ielen: %d", __func__, wpa_ielen)); - if (_SUCCESS == rtw_parse_wpa_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is8021x)) { + if (rtw_parse_wpa_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is8021x) == _SUCCESS) { pnetwork->BcnInfo.pairwise_cipher = pairwise_cipher; pnetwork->BcnInfo.group_cipher = group_cipher; pnetwork->BcnInfo.is_8021x = is8021x; @@ -940,7 +940,7 @@ static int rtw_get_cipher_info(struct wlan_network *pnetwork) if (pbuf && (wpa_ielen > 0)) { RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("get RSN IE\n")); - if (_SUCCESS == rtw_parse_wpa2_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is8021x)) { + if (rtw_parse_wpa2_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is8021x) == _SUCCESS) { RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("get RSN IE OK!!!\n")); pnetwork->BcnInfo.pairwise_cipher = pairwise_cipher; pnetwork->BcnInfo.group_cipher = group_cipher; @@ -975,9 +975,9 @@ void rtw_get_bcn_info(struct wlan_network *pnetwork) pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_OPENSYS; } rtw_get_sec_ie(pnetwork->network.ies, pnetwork->network.ie_length, NULL, &rsn_len, NULL, &wpa_len); - RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s: ssid =%s\n", __func__, pnetwork->network.Ssid.Ssid)); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s: ssid =%s\n", __func__, pnetwork->network.ssid.ssid)); RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s: wpa_len =%d rsn_len =%d\n", __func__, wpa_len, rsn_len)); - RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s: ssid =%s\n", __func__, pnetwork->network.Ssid.Ssid)); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s: ssid =%s\n", __func__, pnetwork->network.ssid.ssid)); RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s: wpa_len =%d rsn_len =%d\n", __func__, wpa_len, rsn_len)); if (rsn_len > 0) { diff --git a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c index 0b3eb0b40975..7d56767cdff6 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c +++ b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c @@ -77,7 +77,7 @@ u8 rtw_do_join(struct adapter *padapter) pibss = padapter->registrypriv.dev_network.MacAddress; - memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid)); + memcpy(&pdev_network->ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid)); rtw_update_registrypriv_dev_network(padapter); @@ -208,7 +208,7 @@ u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid) struct wlan_network *pnetwork = &pmlmepriv->cur_network; DBG_88E_LEVEL(_drv_info_, "set ssid [%s] fw_state=0x%08x\n", - ssid->Ssid, get_fwstate(pmlmepriv)); + ssid->ssid, get_fwstate(pmlmepriv)); if (!padapter->hw_init_completed) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, @@ -229,8 +229,8 @@ u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid) RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_ssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n")); - if (pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength && - !memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength)) { + if (pmlmepriv->assoc_ssid.ssid_length == ssid->ssid_length && + !memcmp(&pmlmepriv->assoc_ssid.ssid, ssid->ssid, ssid->ssid_length)) { if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("Set SSID is the same ssid, fw_state = 0x%08x\n", @@ -257,8 +257,8 @@ u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid) } } else { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("Set SSID not the same ssid\n")); - RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_ssid =[%s] len = 0x%x\n", ssid->Ssid, (unsigned int)ssid->SsidLength)); - RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("assoc_ssid =[%s] len = 0x%x\n", pmlmepriv->assoc_ssid.Ssid, (unsigned int)pmlmepriv->assoc_ssid.SsidLength)); + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_ssid =[%s] len = 0x%x\n", ssid->ssid, (unsigned int)ssid->ssid_length)); + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("assoc_ssid =[%s] len = 0x%x\n", pmlmepriv->assoc_ssid.ssid, (unsigned int)pmlmepriv->assoc_ssid.ssid_length)); rtw_disassoc_cmd(padapter, 0, true); diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme.c b/drivers/staging/rtl8188eu/core/rtw_mlme.c index 714f7a70ed64..ca0cf8a86671 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme.c @@ -300,8 +300,8 @@ int rtw_is_same_ibss(struct adapter *adapter, struct wlan_network *pnetwork) static int is_same_ess(struct wlan_bssid_ex *a, struct wlan_bssid_ex *b) { - return (a->Ssid.SsidLength == b->Ssid.SsidLength) && - !memcmp(a->Ssid.Ssid, b->Ssid.Ssid, a->Ssid.SsidLength); + return (a->ssid.ssid_length == b->ssid.ssid_length) && + !memcmp(a->ssid.ssid, b->ssid.ssid, a->ssid.ssid_length); } int is_same_network(struct wlan_bssid_ex *src, struct wlan_bssid_ex *dst) @@ -315,9 +315,9 @@ int is_same_network(struct wlan_bssid_ex *src, struct wlan_bssid_ex *dst) s_cap = le16_to_cpu(le_scap); d_cap = le16_to_cpu(le_dcap); - return ((src->Ssid.SsidLength == dst->Ssid.SsidLength) && + return ((src->ssid.ssid_length == dst->ssid.ssid_length) && (!memcmp(src->MacAddress, dst->MacAddress, ETH_ALEN)) && - (!memcmp(src->Ssid.Ssid, dst->Ssid.Ssid, src->Ssid.SsidLength)) && + (!memcmp(src->ssid.ssid, dst->ssid.ssid, src->ssid.ssid_length)) && ((s_cap & WLAN_CAPABILITY_IBSS) == (d_cap & WLAN_CAPABILITY_IBSS)) && ((s_cap & WLAN_CAPABILITY_ESS) == @@ -558,7 +558,7 @@ void rtw_survey_event_callback(struct adapter *adapter, u8 *pbuf) pnetwork = (struct wlan_bssid_ex *)pbuf; RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, - ("%s, ssid=%s\n", __func__, pnetwork->Ssid.Ssid)); + ("%s, ssid=%s\n", __func__, pnetwork->ssid.ssid)); len = get_wlan_bssid_ex_sz(pnetwork); if (len > (sizeof(struct wlan_bssid_ex))) { @@ -587,8 +587,8 @@ void rtw_survey_event_callback(struct adapter *adapter, u8 *pbuf) /* lock pmlmepriv->lock when you accessing network_q */ if (!check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { - if (pnetwork->Ssid.Ssid[0] == 0) - pnetwork->Ssid.SsidLength = 0; + if (pnetwork->ssid.ssid[0] == 0) + pnetwork->ssid.ssid_length = 0; rtw_add_network(adapter, pnetwork); } @@ -636,7 +636,7 @@ void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf) RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("switching to adhoc master\n")); - memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid)); + memcpy(&pdev_network->ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid)); rtw_update_registrypriv_dev_network(adapter); rtw_generate_random_ibss(pibss); @@ -741,7 +741,7 @@ void rtw_free_assoc_resources_locked(struct adapter *adapter) RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+rtw_free_assoc_resources\n")); RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("tgt_network->network.MacAddress=%pM ssid=%s\n", - tgt_network->network.MacAddress, tgt_network->network.Ssid.Ssid)); + tgt_network->network.MacAddress, tgt_network->network.ssid.ssid)); if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_AP_STATE)) { struct sta_info *psta; @@ -975,10 +975,10 @@ void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf) rtw_get_encrypt_decrypt_from_registrypriv(adapter); - if (pmlmepriv->assoc_ssid.SsidLength == 0) + if (pmlmepriv->assoc_ssid.ssid_length == 0) RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("@@@@@ joinbss event call back for Any SSid\n")); else - RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("@@@@@ rtw_joinbss_event_callback for SSid:%s\n", pmlmepriv->assoc_ssid.Ssid)); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("@@@@@ rtw_joinbss_event_callback for SSid:%s\n", pmlmepriv->assoc_ssid.ssid)); the_same_macaddr = !memcmp(pnetwork->network.MacAddress, cur_network->network.MacAddress, ETH_ALEN); @@ -1279,7 +1279,7 @@ void rtw_stadel_event_callback(struct adapter *adapter, u8 *pbuf) memcpy(pdev_network, &tgt_network->network, get_wlan_bssid_ex_sz(&tgt_network->network)); - memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid)); + memcpy(&pdev_network->ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid)); rtw_update_registrypriv_dev_network(adapter); @@ -1422,9 +1422,9 @@ static int rtw_check_join_candidate(struct mlme_priv *pmlmepriv } /* check ssid, if needed */ - if (pmlmepriv->assoc_ssid.SsidLength) { - if (competitor->network.Ssid.SsidLength != pmlmepriv->assoc_ssid.SsidLength || - memcmp(competitor->network.Ssid.Ssid, pmlmepriv->assoc_ssid.Ssid, pmlmepriv->assoc_ssid.SsidLength)) + if (pmlmepriv->assoc_ssid.ssid_length) { + if (competitor->network.ssid.ssid_length != pmlmepriv->assoc_ssid.ssid_length || + memcmp(competitor->network.ssid.ssid, pmlmepriv->assoc_ssid.ssid, pmlmepriv->assoc_ssid.ssid_length)) goto exit; } @@ -1445,8 +1445,8 @@ static int rtw_check_join_candidate(struct mlme_priv *pmlmepriv if (updated) { DBG_88E("[by_bssid:%u][assoc_ssid:%s]new candidate: %s(%pM rssi:%d\n", pmlmepriv->assoc_by_bssid, - pmlmepriv->assoc_ssid.Ssid, - (*candidate)->network.Ssid.Ssid, + pmlmepriv->assoc_ssid.ssid, + (*candidate)->network.ssid.ssid, (*candidate)->network.MacAddress, (int)(*candidate)->network.Rssi); DBG_88E("[to_roaming:%u]\n", pmlmepriv->to_roaming); @@ -1493,7 +1493,7 @@ int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv) goto exit; } else { DBG_88E("%s: candidate: %s(%pM ch:%u)\n", __func__, - candidate->network.Ssid.Ssid, candidate->network.MacAddress, + candidate->network.ssid.ssid, candidate->network.MacAddress, candidate->network.Configuration.DSConfig); } @@ -1772,7 +1772,7 @@ void rtw_init_registrypriv_dev_network(struct adapter *adapter) memcpy(pdev_network->MacAddress, myhwaddr, ETH_ALEN); - memcpy(&pdev_network->Ssid, &pregistrypriv->ssid, sizeof(struct ndis_802_11_ssid)); + memcpy(&pdev_network->ssid, &pregistrypriv->ssid, sizeof(struct ndis_802_11_ssid)); pdev_network->Configuration.Length = sizeof(struct ndis_802_11_config); pdev_network->Configuration.BeaconPeriod = 100; @@ -2049,9 +2049,9 @@ void _rtw_roaming(struct adapter *padapter, struct wlan_network *tgt_network) if (pmlmepriv->to_roaming > 0) { DBG_88E("roaming from %s(%pM length:%d\n", - pnetwork->network.Ssid.Ssid, pnetwork->network.MacAddress, - pnetwork->network.Ssid.SsidLength); - memcpy(&pmlmepriv->assoc_ssid, &pnetwork->network.Ssid, sizeof(struct ndis_802_11_ssid)); + pnetwork->network.ssid.ssid, pnetwork->network.MacAddress, + pnetwork->network.ssid.ssid_length); + memcpy(&pmlmepriv->assoc_ssid, &pnetwork->network.ssid, sizeof(struct ndis_802_11_ssid)); pmlmepriv->assoc_by_bssid = false; diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c index 7a36661ebbed..8f28aefbe6f9 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c @@ -402,7 +402,7 @@ static void issue_beacon(struct adapter *padapter, int timeout_ms) pattrib->pktlen += 2; /* SSID */ - pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen); + pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->ssid.ssid_length, cur_network->ssid.ssid, &pattrib->pktlen); /* supported rates... */ rate_len = rtw_get_rateset_len(cur_network->SupportedRates); @@ -562,7 +562,7 @@ static void issue_probersp(struct adapter *padapter, unsigned char *da) /* below for ad-hoc mode */ /* SSID */ - pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen); + pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->ssid.ssid_length, cur_network->ssid.ssid, &pattrib->pktlen); /* supported rates... */ rate_len = rtw_get_rateset_len(cur_network->SupportedRates); @@ -652,7 +652,7 @@ static int issue_probereq(struct adapter *padapter, pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr); if (pssid) - pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &pattrib->pktlen); + pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->ssid_length, pssid->ssid, &pattrib->pktlen); else pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pattrib->pktlen); @@ -1059,7 +1059,7 @@ static void issue_assocreq(struct adapter *padapter) pattrib->pktlen += 2; /* SSID */ - pframe = rtw_set_ie(pframe, _SSID_IE_, pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &pattrib->pktlen); + pframe = rtw_set_ie(pframe, _SSID_IE_, pmlmeinfo->network.ssid.ssid_length, pmlmeinfo->network.ssid.ssid, &pattrib->pktlen); /* supported rate & extended supported rate */ @@ -1929,7 +1929,7 @@ static void site_survey(struct adapter *padapter) int i; for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) { - if (pmlmeext->sitesurvey_res.ssid[i].SsidLength) { + if (pmlmeext->sitesurvey_res.ssid[i].ssid_length) { /* todo: to issue two probe req??? */ issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), @@ -2071,10 +2071,10 @@ static u8 collect_bss_info(struct adapter *padapter, DBG_88E("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len); return _FAIL; } - memcpy(bssid->Ssid.Ssid, (p + 2), len); - bssid->Ssid.SsidLength = len; + memcpy(bssid->ssid.ssid, (p + 2), len); + bssid->ssid.ssid_length = len; } else { - bssid->Ssid.SsidLength = 0; + bssid->ssid.ssid_length = 0; } memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX); @@ -2526,7 +2526,7 @@ static unsigned int OnProbeReq(struct adapter *padapter, /* check (wildcard) SSID */ if (p) { - if ((ielen != 0 && memcmp((void *)(p+2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength)) || + if ((ielen != 0 && memcmp((void *)(p+2), (void *)cur->ssid.ssid, cur->ssid.ssid_length)) || (ielen == 0 && pmlmeinfo->hidden_ssid_mode)) return _SUCCESS; @@ -2975,10 +2975,10 @@ static unsigned int OnAssocReq(struct adapter *padapter, goto OnAssocReqFail; } else { /* check if ssid match */ - if (memcmp((void *)(p+2), cur->Ssid.Ssid, cur->Ssid.SsidLength)) + if (memcmp((void *)(p+2), cur->ssid.ssid, cur->ssid.ssid_length)) status = _STATS_FAILURE_; - if (ie_len != cur->Ssid.SsidLength) + if (ie_len != cur->ssid.ssid_length) status = _STATS_FAILURE_; } @@ -4658,7 +4658,7 @@ void linked_status_chk(struct adapter *padapter) } if (rx_chk != _SUCCESS) - issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 3, 1); + issue_probereq_ex(padapter, &pmlmeinfo->network.ssid, psta->hwaddr, 3, 1); if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) || rx_chk != _SUCCESS) { tx_chk = issue_nulldata(padapter, psta->hwaddr, 0, 3, 1); @@ -4674,15 +4674,15 @@ void linked_status_chk(struct adapter *padapter) if (rx_chk != _SUCCESS) { if (pmlmeext->retry == 0) { issue_probereq(padapter, - &pmlmeinfo->network.Ssid, + &pmlmeinfo->network.ssid, pmlmeinfo->network.MacAddress, false); issue_probereq(padapter, - &pmlmeinfo->network.Ssid, + &pmlmeinfo->network.ssid, pmlmeinfo->network.MacAddress, false); issue_probereq(padapter, - &pmlmeinfo->network.Ssid, + &pmlmeinfo->network.ssid, pmlmeinfo->network.MacAddress, false); } @@ -5136,11 +5136,11 @@ u8 sitesurvey_cmd_hdl(struct adapter *padapter, u8 *pbuf) pmlmeext->sitesurvey_res.channel_idx = 0; for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) { - if (pparm->ssid[i].SsidLength) { - memcpy(pmlmeext->sitesurvey_res.ssid[i].Ssid, pparm->ssid[i].Ssid, IW_ESSID_MAX_SIZE); - pmlmeext->sitesurvey_res.ssid[i].SsidLength = pparm->ssid[i].SsidLength; + if (pparm->ssid[i].ssid_length) { + memcpy(pmlmeext->sitesurvey_res.ssid[i].ssid, pparm->ssid[i].ssid, IW_ESSID_MAX_SIZE); + pmlmeext->sitesurvey_res.ssid[i].ssid_length = pparm->ssid[i].ssid_length; } else { - pmlmeext->sitesurvey_res.ssid[i].SsidLength = 0; + pmlmeext->sitesurvey_res.ssid[i].ssid_length = 0; } } diff --git a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c index 5f9c9de1f1da..4480deef95a1 100644 --- a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c @@ -935,17 +935,17 @@ int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len) if (ssid_len > NDIS_802_11_LENGTH_SSID) ssid_len = 0; } - memcpy(bssid->Ssid.Ssid, (p + 2), ssid_len); - bssid->Ssid.SsidLength = ssid_len; + memcpy(bssid->ssid.ssid, (p + 2), ssid_len); + bssid->ssid.ssid_length = ssid_len; - RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s bssid.Ssid.Ssid:%s bssid.Ssid.SsidLength:%d " - "cur_network->network.Ssid.Ssid:%s len:%d\n", __func__, bssid->Ssid.Ssid, - bssid->Ssid.SsidLength, cur_network->network.Ssid.Ssid, - cur_network->network.Ssid.SsidLength)); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s bssid.ssid.ssid:%s bssid.ssid.ssid_length:%d " + "cur_network->network.ssid.ssid:%s len:%d\n", __func__, bssid->ssid.ssid, + bssid->ssid.ssid_length, cur_network->network.ssid.ssid, + cur_network->network.ssid.ssid_length)); - if (memcmp(bssid->Ssid.Ssid, cur_network->network.Ssid.Ssid, 32) || - bssid->Ssid.SsidLength != cur_network->network.Ssid.SsidLength) { - if (bssid->Ssid.Ssid[0] != '\0' && bssid->Ssid.SsidLength != 0) { /* not hidden ssid */ + if (memcmp(bssid->ssid.ssid, cur_network->network.ssid.ssid, 32) || + bssid->ssid.ssid_length != cur_network->network.ssid.ssid_length) { + if (bssid->ssid.ssid[0] != '\0' && bssid->ssid.ssid_length != 0) { /* not hidden ssid */ DBG_88E("%s(), SSID is not match return FAIL\n", __func__); goto _mismatch; } diff --git a/drivers/staging/rtl8188eu/core/rtw_xmit.c b/drivers/staging/rtl8188eu/core/rtw_xmit.c index 3b1ccd138c3f..1723a47a96b4 100644 --- a/drivers/staging/rtl8188eu/core/rtw_xmit.c +++ b/drivers/staging/rtl8188eu/core/rtw_xmit.c @@ -626,7 +626,7 @@ static s32 xmitframe_addmic(struct adapter *padapter, struct xmit_frame *pxmitfr if (pframe[1] & 2) /* From Ds == 1 */ rtw_secmicappend(&micdata, &pframe[24], 6); else - rtw_secmicappend(&micdata, &pframe[10], 6); + rtw_secmicappend(&micdata, &pframe[10], 6); } else { /* ToDS == 0 */ rtw_secmicappend(&micdata, &pframe[4], 6); /* DA */ if (pframe[1] & 2) /* From Ds == 1 */ diff --git a/drivers/staging/rtl8188eu/hal/odm.c b/drivers/staging/rtl8188eu/hal/odm.c index 1165ee278536..ba3c3e5a8216 100644 --- a/drivers/staging/rtl8188eu/hal/odm.c +++ b/drivers/staging/rtl8188eu/hal/odm.c @@ -209,17 +209,8 @@ void ODM_DMWatchdog(struct odm_dm_struct *pDM_Odm) void ODM_CmnInfoPtrArrayHook(struct odm_dm_struct *pDM_Odm, enum odm_common_info_def CmnInfo, u16 Index, void *pValue) { - /* Hook call by reference pointer. */ - switch (CmnInfo) { - /* Dynamic call by reference pointer. */ - case ODM_CMNINFO_STA_STATUS: + if (CmnInfo == ODM_CMNINFO_STA_STATUS) pDM_Odm->pODM_StaInfo[Index] = (struct sta_info *)pValue; - break; - /* To remove the compiler warning, must add an empty default statement to handle the other values. */ - default: - /* do nothing */ - break; - } } void odm_CommonInfoSelfInit(struct odm_dm_struct *pDM_Odm) diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c b/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c index 7022221136f6..47352f210c0b 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c @@ -22,7 +22,7 @@ static u8 _is_fw_read_cmd_down(struct adapter *adapt, u8 msgbox_num) { u8 read_down = false; - int retry_cnts = 100; + int retry_cnts = 100; u8 valid; @@ -118,7 +118,6 @@ exit: void rtw_hal_add_ra_tid(struct adapter *pAdapter, u32 bitmap, u8 arg, u8 rssi_level) { struct odm_dm_struct *odmpriv = &pAdapter->HalData->odmpriv; - u8 macid, init_rate, raid, shortGIrate = false; macid = arg&0x1f; @@ -211,9 +210,9 @@ static void ConstructBeacon(struct adapter *adapt, u8 *pframe, u32 *pLength) struct ieee80211_hdr *pwlanhdr; __le16 *fctrl; u32 rate_len, pktlen; - struct mlme_ext_priv *pmlmeext = &(adapt->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network); + struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; + struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; pwlanhdr = (struct ieee80211_hdr *)pframe; @@ -222,7 +221,7 @@ static void ConstructBeacon(struct adapter *adapt, u8 *pframe, u32 *pLength) *(fctrl) = 0; ether_addr_copy(pwlanhdr->addr1, bc_addr); - ether_addr_copy(pwlanhdr->addr2, myid(&(adapt->eeprompriv))); + ether_addr_copy(pwlanhdr->addr2, myid(&adapt->eeprompriv)); ether_addr_copy(pwlanhdr->addr3, cur_network->MacAddress); SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/); @@ -257,7 +256,7 @@ static void ConstructBeacon(struct adapter *adapt, u8 *pframe, u32 *pLength) /* below for ad-hoc mode */ /* SSID */ - pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen); + pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->ssid.ssid_length, cur_network->ssid.ssid, &pktlen); /* supported rates... */ rate_len = rtw_get_rateset_len(cur_network->SupportedRates); @@ -294,10 +293,10 @@ _ConstructBeacon: static void ConstructPSPoll(struct adapter *adapt, u8 *pframe, u32 *pLength) { struct ieee80211_hdr *pwlanhdr; - struct mlme_ext_priv *pmlmeext = &(adapt->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; __le16 *fctrl; - struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network); + struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network; pwlanhdr = (struct ieee80211_hdr *)pframe; @@ -314,7 +313,7 @@ static void ConstructPSPoll(struct adapter *adapt, u8 *pframe, u32 *pLength) ether_addr_copy(pwlanhdr->addr1, pnetwork->MacAddress); /* TA. */ - ether_addr_copy(pwlanhdr->addr2, myid(&(adapt->eeprompriv))); + ether_addr_copy(pwlanhdr->addr2, myid(&adapt->eeprompriv)); *pLength = 16; } @@ -331,10 +330,10 @@ static void ConstructNullFunctionData(struct adapter *adapt, u8 *pframe, __le16 *fctrl; u32 pktlen; struct mlme_priv *pmlmepriv = &adapt->mlmepriv; - struct wlan_network *cur_network = &pmlmepriv->cur_network; - struct mlme_ext_priv *pmlmeext = &(adapt->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network); + struct wlan_network *cur_network = &pmlmepriv->cur_network; + struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; + struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network; pwlanhdr = (struct ieee80211_hdr *)pframe; @@ -347,19 +346,19 @@ static void ConstructNullFunctionData(struct adapter *adapt, u8 *pframe, case Ndis802_11Infrastructure: SetToDs(fctrl); ether_addr_copy(pwlanhdr->addr1, pnetwork->MacAddress); - ether_addr_copy(pwlanhdr->addr2, myid(&(adapt->eeprompriv))); + ether_addr_copy(pwlanhdr->addr2, myid(&adapt->eeprompriv)); ether_addr_copy(pwlanhdr->addr3, StaAddr); break; case Ndis802_11APMode: SetFrDs(fctrl); ether_addr_copy(pwlanhdr->addr1, StaAddr); ether_addr_copy(pwlanhdr->addr2, pnetwork->MacAddress); - ether_addr_copy(pwlanhdr->addr3, myid(&(adapt->eeprompriv))); + ether_addr_copy(pwlanhdr->addr3, myid(&adapt->eeprompriv)); break; case Ndis802_11IBSS: default: ether_addr_copy(pwlanhdr->addr1, StaAddr); - ether_addr_copy(pwlanhdr->addr2, myid(&(adapt->eeprompriv))); + ether_addr_copy(pwlanhdr->addr2, myid(&adapt->eeprompriv)); ether_addr_copy(pwlanhdr->addr3, pnetwork->MacAddress); break; } @@ -391,13 +390,13 @@ static void ConstructProbeRsp(struct adapter *adapt, u8 *pframe, u32 *pLength, u __le16 *fctrl; u8 *mac, *bssid; u32 pktlen; - struct mlme_ext_priv *pmlmeext = &(adapt->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network); + struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; + struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; pwlanhdr = (struct ieee80211_hdr *)pframe; - mac = myid(&(adapt->eeprompriv)); + mac = myid(&adapt->eeprompriv); bssid = cur_network->MacAddress; fctrl = &pwlanhdr->frame_control; @@ -434,11 +433,11 @@ static void ConstructProbeRsp(struct adapter *adapt, u8 *pframe, u32 *pLength, u /* 2009.10.15 by tynli. */ static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished) { - struct xmit_frame *pmgntframe; - struct pkt_attrib *pattrib; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; struct xmit_priv *pxmitpriv; struct mlme_ext_priv *pmlmeext; - struct mlme_ext_info *pmlmeinfo; + struct mlme_ext_info *pmlmeinfo; u32 BeaconLength = 0, ProbeRspLength = 0, PSPollLength; u32 NullDataLength, QosNullLength; u8 *ReservedPagePacket; @@ -458,7 +457,7 @@ static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished) pxmitpriv = &adapt->xmitpriv; pmlmeext = &adapt->mlmeextpriv; pmlmeinfo = &pmlmeext->mlmext_info; - pnetwork = &(pmlmeinfo->network); + pnetwork = &pmlmeinfo->network; TxDescLen = TXDESC_SIZE; PageNum = 0; @@ -476,7 +475,7 @@ static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished) PageNum += PageNeed; adapt->HalData->FwRsvdPageStartOffset = PageNum; - BufIndex += PageNeed*128; + BufIndex += PageNeed * 128; /* 3 (2) ps-poll *1 page */ RsvdPageLoc.LocPsPoll = PageNum; @@ -486,7 +485,7 @@ static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished) PageNeed = (u8)PageNum_128(TxDescLen + PSPollLength); PageNum += PageNeed; - BufIndex += PageNeed*128; + BufIndex += PageNeed * 128; /* 3 (3) null data * 1 page */ RsvdPageLoc.LocNullData = PageNum; @@ -496,7 +495,7 @@ static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished) PageNeed = (u8)PageNum_128(TxDescLen + NullDataLength); PageNum += PageNeed; - BufIndex += PageNeed*128; + BufIndex += PageNeed * 128; /* 3 (4) probe response * 1page */ RsvdPageLoc.LocProbeRsp = PageNum; @@ -506,7 +505,7 @@ static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished) PageNeed = (u8)PageNum_128(TxDescLen + ProbeRspLength); PageNum += PageNeed; - BufIndex += PageNeed*128; + BufIndex += PageNeed * 128; /* 3 (5) Qos null data */ RsvdPageLoc.LocQosNull = PageNum; @@ -542,10 +541,10 @@ exit: void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus) { struct hal_data_8188e *haldata = adapt->HalData; - struct mlme_ext_priv *pmlmeext = &(adapt->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - bool bSendBeacon = false; - bool bcn_valid = false; + struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; + bool bSendBeacon = false; + bool bcn_valid = false; u8 DLBcnCount = 0; u32 poll = 0; diff --git a/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c b/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c index a72e069269b8..9e5f23392d58 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c @@ -440,14 +440,14 @@ bool rtl8188eu_xmitframe_complete(struct adapter *adapt, RT_TRACE(_module_rtl8192c_xmit_c_, _drv_info_, ("+xmitframe_complete\n")); pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv); - if (pxmitbuf == NULL) + if (!pxmitbuf) return false; /* 3 1. pick up first frame */ rtw_free_xmitframe(pxmitpriv, pxmitframe); pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry); - if (pxmitframe == NULL) { + if (!pxmitframe) { /* no more xmit frame, release xmit buffer */ rtw_free_xmitbuf(pxmitpriv, pxmitbuf); return false; diff --git a/drivers/staging/rtl8188eu/include/odm.h b/drivers/staging/rtl8188eu/include/odm.h index 947481de9cb1..8245cea2feef 100644 --- a/drivers/staging/rtl8188eu/include/odm.h +++ b/drivers/staging/rtl8188eu/include/odm.h @@ -1045,7 +1045,6 @@ extern u8 CCKSwingTable_Ch14[CCK_TABLE_SIZE][8]; void ODM_RF_Saving(struct odm_dm_struct *pDM_Odm, u8 bForceInNormal); void ODM_TXPowerTrackingCheck(struct odm_dm_struct *pDM_Odm); -void odm_DIGbyRSSI_LPS(struct odm_dm_struct *pDM_Odm); void ODM_Write_CCK_CCA_Thres(struct odm_dm_struct *pDM_Odm, u8 CurCCK_CCAThres); bool ODM_RAStateCheck(struct odm_dm_struct *pDM_Odm, s32 RSSI, bool bForceUpdate, u8 *pRATRState); diff --git a/drivers/staging/rtl8188eu/include/odm_hwconfig.h b/drivers/staging/rtl8188eu/include/odm_hwconfig.h index 8cef32dc6350..2cd8a47a3673 100644 --- a/drivers/staging/rtl8188eu/include/odm_hwconfig.h +++ b/drivers/staging/rtl8188eu/include/odm_hwconfig.h @@ -93,18 +93,9 @@ struct phy_status_rpt { #endif }; -void odm_Init_RSSIForDM(struct odm_dm_struct *pDM_Odm); - void ODM_PhyStatusQuery(struct odm_dm_struct *pDM_Odm, struct odm_phy_status_info *pPhyInfo, u8 *pPhyStatus, struct odm_per_pkt_info *pPktinfo); -void ODM_MacStatusQuery(struct odm_dm_struct *pDM_Odm, - u8 *pMacStatus, - u8 MacID, - bool bPacketMatchBSSID, - bool bPacketToSelf, - bool bPacketBeacon); - #endif diff --git a/drivers/staging/rtl8188eu/include/wifi.h b/drivers/staging/rtl8188eu/include/wifi.h index 0664d5f30a96..5e91b9428c16 100644 --- a/drivers/staging/rtl8188eu/include/wifi.h +++ b/drivers/staging/rtl8188eu/include/wifi.h @@ -791,18 +791,6 @@ enum ht_cap_ampdu_factor { #define WPS_CM_SW_DISPLAY_P 0x2008 #define WPS_CM_LCD_DISPLAY_P 0x4008 -#define P2P_PRIVATE_IOCTL_SET_LEN 64 - -enum P2P_PROTO_WK_ID { - P2P_FIND_PHASE_WK = 0, - P2P_RESTORE_STATE_WK = 1, - P2P_PRE_TX_PROVDISC_PROCESS_WK = 2, - P2P_PRE_TX_NEGOREQ_PROCESS_WK = 3, - P2P_PRE_TX_INVITEREQ_PROCESS_WK = 4, - P2P_AP_P2P_CH_SWITCH_PROCESS_WK = 5, - P2P_RO_CH_WK = 6, -}; - /* =====================WFD Section===================== */ /* For Wi-Fi Display */ #define WFD_ATTR_DEVICE_INFO 0x00 diff --git a/drivers/staging/rtl8188eu/include/wlan_bssdef.h b/drivers/staging/rtl8188eu/include/wlan_bssdef.h index 5e13a6ddf083..8462c9c2fd39 100644 --- a/drivers/staging/rtl8188eu/include/wlan_bssdef.h +++ b/drivers/staging/rtl8188eu/include/wlan_bssdef.h @@ -17,8 +17,8 @@ #define NDIS_802_11_RSSI long /* in dBm */ struct ndis_802_11_ssid { - u32 SsidLength; - u8 Ssid[32]; + u32 ssid_length; + u8 ssid[32]; }; enum NDIS_802_11_NETWORK_TYPE { @@ -180,7 +180,7 @@ struct wlan_bssid_ex { u32 Length; unsigned char MacAddress[ETH_ALEN]; u8 Reserved[2];/* 0]: IS beacon frame */ - struct ndis_802_11_ssid Ssid; + struct ndis_802_11_ssid ssid; u32 Privacy; NDIS_802_11_RSSI Rssi;/* in dBM,raw data ,get from PHY) */ enum NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c index efaa1c779f4b..eaa4adb32a0d 100644 --- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c @@ -116,8 +116,8 @@ static char *translate_scan(struct adapter *padapter, /* Add the ESSID */ iwe.cmd = SIOCGIWESSID; iwe.u.data.flags = 1; - iwe.u.data.length = min_t(u16, pnetwork->network.Ssid.SsidLength, 32); - start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid); + iwe.u.data.length = min_t(u16, pnetwork->network.ssid.ssid_length, 32); + start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.ssid.ssid); /* parsing HT_CAP_IE */ p = rtw_get_ie(&pnetwork->network.ies[12], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.ie_length-12); @@ -195,7 +195,7 @@ static char *translate_scan(struct adapter *padapter, else iwe.u.data.flags = IW_ENCODE_DISABLED; iwe.u.data.length = 0; - start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid); + start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.ssid.ssid); /*Add basic and extended rates */ max_rate = 0; @@ -235,7 +235,7 @@ static char *translate_scan(struct adapter *padapter, u8 *p; rtw_get_sec_ie(pnetwork->network.ies, pnetwork->network.ie_length, rsn_ie, &rsn_len, wpa_ie, &wpa_len); - RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan: ssid =%s\n", pnetwork->network.Ssid.Ssid)); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan: ssid =%s\n", pnetwork->network.ssid.ssid)); RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan: wpa_len =%d rsn_len =%d\n", wpa_len, rsn_len)); if (wpa_len > 0) { @@ -1124,8 +1124,8 @@ static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a, int len = min_t(int, req->essid_len, IW_ESSID_MAX_SIZE); - memcpy(ssid[0].Ssid, req->essid, len); - ssid[0].SsidLength = len; + memcpy(ssid[0].ssid, req->essid, len); + ssid[0].ssid_length = len; DBG_88E("IW_SCAN_THIS_ESSID, ssid =%s, len =%d\n", req->essid, req->essid_len); @@ -1158,8 +1158,8 @@ static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a, } sec_len = *(pos++); len -= 1; if (sec_len > 0 && sec_len <= len) { - ssid[ssid_index].SsidLength = sec_len; - memcpy(ssid[ssid_index].Ssid, pos, ssid[ssid_index].SsidLength); + ssid[ssid_index].ssid_length = sec_len; + memcpy(ssid[ssid_index].ssid, pos, ssid[ssid_index].ssid_length); ssid_index++; } pos += sec_len; @@ -1310,9 +1310,9 @@ static int rtw_wx_set_essid(struct net_device *dev, DBG_88E("ssid =%s, len =%d\n", extra, wrqu->essid.length); memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid)); - ndis_ssid.SsidLength = len; - memcpy(ndis_ssid.Ssid, extra, len); - src_ssid = ndis_ssid.Ssid; + ndis_ssid.ssid_length = len; + 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)); spin_lock_bh(&queue->lock); @@ -1324,14 +1324,14 @@ static int rtw_wx_set_essid(struct net_device *dev, pmlmepriv->pscanned = pmlmepriv->pscanned->next; - dst_ssid = pnetwork->network.Ssid.Ssid; + dst_ssid = pnetwork->network.ssid.ssid; RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("rtw_wx_set_essid: dst_ssid =%s\n", - pnetwork->network.Ssid.Ssid)); + pnetwork->network.ssid.ssid)); - if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength)) && - (pnetwork->network.Ssid.SsidLength == ndis_ssid.SsidLength)) { + 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")); @@ -1378,8 +1378,8 @@ static int rtw_wx_get_essid(struct net_device *dev, if ((check_fwstate(pmlmepriv, _FW_LINKED)) || (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))) { - len = pcur_bss->Ssid.SsidLength; - memcpy(extra, pcur_bss->Ssid.Ssid, len); + len = pcur_bss->ssid.ssid_length; + memcpy(extra, pcur_bss->ssid.ssid, len); } else { len = 0; *extra = 0; diff --git a/drivers/staging/rtl8188eu/os_dep/mlme_linux.c b/drivers/staging/rtl8188eu/os_dep/mlme_linux.c index d5ceb3beabbc..9db11b16cb93 100644 --- a/drivers/staging/rtl8188eu/os_dep/mlme_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/mlme_linux.c @@ -13,7 +13,7 @@ void rtw_init_mlme_timer(struct adapter *padapter) { - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; timer_setup(&pmlmepriv->assoc_timer, _rtw_join_timeout_handler, 0); timer_setup(&pmlmepriv->scan_to_timer, rtw_scan_timeout_handler, 0); @@ -36,34 +36,38 @@ static struct rt_pmkid_list backup_pmkid[NUM_PMKID_CACHE]; void rtw_reset_securitypriv(struct adapter *adapter) { - u8 backup_index = 0; - u8 backup_counter = 0x00; - u32 backup_time = 0; - - if (adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { - /* 802.1x */ - /* We have to backup the PMK information for WiFi PMK Caching test item. */ - /* Backup the btkip_countermeasure information. */ - /* When the countermeasure is trigger, the driver have to disconnect with AP for 60 seconds. */ - memcpy(&backup_pmkid[0], &adapter->securitypriv.PMKIDList[0], sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE); - backup_index = adapter->securitypriv.PMKIDIndex; - backup_counter = adapter->securitypriv.btkip_countermeasure; - backup_time = adapter->securitypriv.btkip_countermeasure_time; - memset((unsigned char *)&adapter->securitypriv, 0, sizeof(struct security_priv)); - - /* Restore the PMK information to securitypriv structure for the following connection. */ - memcpy(&adapter->securitypriv.PMKIDList[0], - &backup_pmkid[0], - sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE); - adapter->securitypriv.PMKIDIndex = backup_index; - adapter->securitypriv.btkip_countermeasure = backup_counter; - adapter->securitypriv.btkip_countermeasure_time = backup_time; - adapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen; - adapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled; + u8 backup_index; + u8 backup_counter; + u32 backup_time; + struct security_priv *psec_priv = &adapter->securitypriv; + + if (psec_priv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { + /* 802.1x + * We have to backup the PMK information for WiFi PMK Caching + * test item. Backup the btkip_countermeasure information. When + * the countermeasure is trigger, the driver have to disconnect + * with AP for 60 seconds. + */ + memcpy(backup_pmkid, psec_priv->PMKIDList, + sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE); + backup_index = psec_priv->PMKIDIndex; + backup_counter = psec_priv->btkip_countermeasure; + backup_time = psec_priv->btkip_countermeasure_time; + + memset(psec_priv, 0, sizeof(*psec_priv)); + + /* Restore the PMK information to securitypriv structure + * for the following connection. + */ + memcpy(psec_priv->PMKIDList, backup_pmkid, + sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE); + psec_priv->PMKIDIndex = backup_index; + psec_priv->btkip_countermeasure = backup_counter; + psec_priv->btkip_countermeasure_time = backup_time; + psec_priv->ndisauthtype = Ndis802_11AuthModeOpen; + psec_priv->ndisencryptstatus = Ndis802_11WEPDisabled; } else { /* reset values in securitypriv */ - struct security_priv *psec_priv = &adapter->securitypriv; - psec_priv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; psec_priv->dot11PrivacyAlgrthm = _NO_PRIVACY_; psec_priv->dot11PrivacyKeyIndex = 0; @@ -76,15 +80,16 @@ void rtw_reset_securitypriv(struct adapter *adapter) void rtw_os_indicate_disconnect(struct adapter *adapter) { - netif_carrier_off(adapter->pnetdev); /* Do it first for tx broadcast pkt after disconnection issue! */ + /* Do it first for tx broadcast pkt after disconnection issue! */ + netif_carrier_off(adapter->pnetdev); rtw_indicate_wx_disassoc_event(adapter); rtw_reset_securitypriv(adapter); } void rtw_report_sec_ie(struct adapter *adapter, u8 authmode, u8 *sec_ie) { - uint len; - u8 *buff, *p, i; + uint len; + u8 *buff, *p, i; union iwreq_data wrqu; RT_TRACE(_module_mlme_osdep_c_, _drv_info_, @@ -99,14 +104,13 @@ void rtw_report_sec_ie(struct adapter *adapter, u8 authmode, u8 *sec_ie) memset(buff, 0, IW_CUSTOM_MAX); p = buff; p += sprintf(p, "ASSOCINFO(ReqIEs ="); - len = sec_ie[1]+2; + len = sec_ie[1] + 2; len = min_t(uint, len, IW_CUSTOM_MAX); for (i = 0; i < len; i++) p += sprintf(p, "%02x", sec_ie[i]); p += sprintf(p, ")"); memset(&wrqu, 0, sizeof(wrqu)); - wrqu.data.length = p-buff; - wrqu.data.length = min_t(__u16, wrqu.data.length, IW_CUSTOM_MAX); + wrqu.data.length = min_t(__u16, p - buff, IW_CUSTOM_MAX); wireless_send_event(adapter->pnetdev, IWEVCUSTOM, &wrqu, buff); kfree(buff); } @@ -119,7 +123,7 @@ void init_addba_retry_timer(struct adapter *padapter, struct sta_info *psta) void init_mlme_ext_timer(struct adapter *padapter) { - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; timer_setup(&pmlmeext->survey_timer, survey_timer_hdl, 0); timer_setup(&pmlmeext->link_timer, link_timer_hdl, 0); diff --git a/drivers/staging/rtl8188eu/os_dep/os_intfs.c b/drivers/staging/rtl8188eu/os_dep/os_intfs.c index abcce2240f15..8dde5a40e253 100644 --- a/drivers/staging/rtl8188eu/os_dep/os_intfs.c +++ b/drivers/staging/rtl8188eu/os_dep/os_intfs.c @@ -137,12 +137,12 @@ static int netdev_close(struct net_device *pnetdev); static void loadparam(struct adapter *padapter, struct net_device *pnetdev) { - struct registry_priv *registry_par = &padapter->registrypriv; + struct registry_priv *registry_par = &padapter->registrypriv; GlobalDebugLevel = rtw_debug; - memcpy(registry_par->ssid.Ssid, "ANY", 3); - registry_par->ssid.SsidLength = 3; + memcpy(registry_par->ssid.ssid, "ANY", 3); + registry_par->ssid.ssid_length = 3; registry_par->channel = (u8)rtw_channel; registry_par->wireless_mode = (u8)rtw_wireless_mode; @@ -198,8 +198,8 @@ 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 xmit_priv *pxmitpriv = &(padapter->xmitpriv); - struct recv_priv *precvpriv = &(padapter->recvpriv); + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct recv_priv *precvpriv = &padapter->recvpriv; padapter->stats.tx_packets = pxmitpriv->tx_pkts; padapter->stats.rx_packets = precvpriv->rx_pkts; @@ -248,7 +248,7 @@ static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb, struct net_device *sb_dev, select_queue_fallback_t fallback) { - struct adapter *padapter = rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; skb->priority = rtw_classify8021d(skb); @@ -263,15 +263,15 @@ u16 rtw_recv_select_queue(struct sk_buff *skb) { struct iphdr *piphdr; unsigned int dscp; - __be16 eth_type; + __be16 eth_type; u32 priority; u8 *pdata = skb->data; - memcpy(ð_type, pdata+(ETH_ALEN<<1), 2); + memcpy(ð_type, pdata + (ETH_ALEN << 1), 2); switch (eth_type) { case htons(ETH_P_IP): - piphdr = (struct iphdr *)(pdata+ETH_HLEN); + piphdr = (struct iphdr *)(pdata + ETH_HLEN); dscp = piphdr->tos & 0xfc; priority = dscp >> 5; break; @@ -286,7 +286,7 @@ static const struct net_device_ops rtw_netdev_ops = { .ndo_open = netdev_open, .ndo_stop = netdev_close, .ndo_start_xmit = rtw_xmit_entry, - .ndo_select_queue = rtw_select_queue, + .ndo_select_queue = rtw_select_queue, .ndo_set_mac_address = rtw_net_set_mac_address, .ndo_get_stats = rtw_net_get_stats, .ndo_do_ioctl = rtw_ioctl, @@ -323,7 +323,7 @@ struct net_device *rtw_init_netdev(struct adapter *old_padapter) padapter->pnetdev = pnetdev; DBG_88E("register rtw_netdev_ops to netdev_ops\n"); pnetdev->netdev_ops = &rtw_netdev_ops; - pnetdev->watchdog_timeo = HZ*3; /* 3 second timeout */ + pnetdev->watchdog_timeo = HZ * 3; /* 3 second timeout */ pnetdev->wireless_handlers = (struct iw_handler_def *)&rtw_handlers_def; loadparam(padapter, pnetdev); @@ -361,7 +361,7 @@ void rtw_stop_drv_threads(struct adapter *padapter) static u8 rtw_init_default_value(struct adapter *padapter) { struct registry_priv *pregistrypriv = &padapter->registrypriv; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct security_priv *psecuritypriv = &padapter->securitypriv; @@ -431,7 +431,7 @@ u8 rtw_reset_drv_sw(struct adapter *padapter) u8 rtw_init_drv_sw(struct adapter *padapter) { - u8 ret8 = _SUCCESS; + u8 ret8 = _SUCCESS; RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+rtw_init_drv_sw\n")); diff --git a/drivers/staging/rtl8188eu/os_dep/rtw_android.c b/drivers/staging/rtl8188eu/os_dep/rtw_android.c index 2ea2af3286bc..7a090615dcbc 100644 --- a/drivers/staging/rtl8188eu/os_dep/rtw_android.c +++ b/drivers/staging/rtl8188eu/os_dep/rtw_android.c @@ -84,7 +84,7 @@ static int rtw_android_get_rssi(struct net_device *net, char *command, if (check_fwstate(pmlmepriv, _FW_LINKED)) { bytes_written += snprintf(&command[bytes_written], total_len, "%s rssi %d", - pcur_network->network.Ssid.Ssid, + pcur_network->network.ssid.ssid, padapter->recvpriv.rssi); } return bytes_written; diff --git a/drivers/staging/rtl8188eu/os_dep/usb_intf.c b/drivers/staging/rtl8188eu/os_dep/usb_intf.c index dfee6985efa6..664d93a7f90d 100644 --- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c +++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c @@ -228,10 +228,10 @@ static int rtw_suspend(struct usb_interface *pusb_intf, pm_message_t message) check_fwstate(pmlmepriv, _FW_LINKED)) { pr_debug("%s:%d %s(%pM), length:%d assoc_ssid.length:%d\n", __func__, __LINE__, - pmlmepriv->cur_network.network.Ssid.Ssid, + pmlmepriv->cur_network.network.ssid.ssid, pmlmepriv->cur_network.network.MacAddress, - pmlmepriv->cur_network.network.Ssid.SsidLength, - pmlmepriv->assoc_ssid.SsidLength); + pmlmepriv->cur_network.network.ssid.ssid_length, + pmlmepriv->assoc_ssid.ssid_length); pmlmepriv->to_roaming = 1; } diff --git a/drivers/staging/rtl8192e/dot11d.c b/drivers/staging/rtl8192e/dot11d.c index a1c096124683..68f53013cb95 100644 --- a/drivers/staging/rtl8192e/dot11d.c +++ b/drivers/staging/rtl8192e/dot11d.c @@ -15,11 +15,11 @@ #include "dot11d.h" struct channel_list { - u8 Channel[32]; - u8 Len; + u8 channel[32]; + u8 len; }; -static struct channel_list ChannelPlan[] = { +static struct channel_list channel_array[] = { {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 24}, {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, @@ -44,130 +44,130 @@ static struct channel_list ChannelPlan[] = { void dot11d_init(struct rtllib_device *ieee) { - struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(ieee); + struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(ieee); - pDot11dInfo->bEnabled = false; + dot11d_info->enabled = false; - pDot11dInfo->State = DOT11D_STATE_NONE; - pDot11dInfo->CountryIeLen = 0; - memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER + 1); - memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER + 1); + dot11d_info->state = DOT11D_STATE_NONE; + dot11d_info->country_len = 0; + memset(dot11d_info->channel_map, 0, MAX_CHANNEL_NUMBER + 1); + memset(dot11d_info->max_tx_power_list, 0xFF, MAX_CHANNEL_NUMBER + 1); RESET_CIE_WATCHDOG(ieee); } EXPORT_SYMBOL(dot11d_init); -void Dot11d_Channelmap(u8 channel_plan, struct rtllib_device *ieee) +void dot11d_channel_map(u8 channel_plan, struct rtllib_device *ieee) { int i, max_chan = 14, min_chan = 1; - ieee->bGlobalDomain = false; + ieee->global_domain = false; - if (ChannelPlan[channel_plan].Len != 0) { + if (channel_array[channel_plan].len != 0) { memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map)); - for (i = 0; i < ChannelPlan[channel_plan].Len; i++) { - if (ChannelPlan[channel_plan].Channel[i] < min_chan || - ChannelPlan[channel_plan].Channel[i] > max_chan) + for (i = 0; i < channel_array[channel_plan].len; i++) { + if (channel_array[channel_plan].channel[i] < min_chan || + channel_array[channel_plan].channel[i] > max_chan) break; - GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan - [channel_plan].Channel[i]] = 1; + GET_DOT11D_INFO(ieee)->channel_map[channel_array + [channel_plan].channel[i]] = 1; } } switch (channel_plan) { case COUNTRY_CODE_GLOBAL_DOMAIN: - ieee->bGlobalDomain = true; + ieee->global_domain = true; for (i = 12; i <= 14; i++) GET_DOT11D_INFO(ieee)->channel_map[i] = 2; - ieee->IbssStartChnl = 10; + ieee->bss_start_channel = 10; ieee->ibss_maxjoin_chal = 11; break; case COUNTRY_CODE_WORLD_WIDE_13: for (i = 12; i <= 13; i++) GET_DOT11D_INFO(ieee)->channel_map[i] = 2; - ieee->IbssStartChnl = 10; + ieee->bss_start_channel = 10; ieee->ibss_maxjoin_chal = 11; break; default: - ieee->IbssStartChnl = 1; + ieee->bss_start_channel = 1; ieee->ibss_maxjoin_chal = 14; break; } } -EXPORT_SYMBOL(Dot11d_Channelmap); +EXPORT_SYMBOL(dot11d_channel_map); -void Dot11d_Reset(struct rtllib_device *ieee) +void dot11d_reset(struct rtllib_device *ieee) { - struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(ieee); + struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(ieee); u32 i; - memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER + 1); - memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER + 1); + memset(dot11d_info->channel_map, 0, MAX_CHANNEL_NUMBER + 1); + memset(dot11d_info->max_tx_power_list, 0xFF, MAX_CHANNEL_NUMBER + 1); for (i = 1; i <= 11; i++) - (pDot11dInfo->channel_map)[i] = 1; + (dot11d_info->channel_map)[i] = 1; for (i = 12; i <= 14; i++) - (pDot11dInfo->channel_map)[i] = 2; - pDot11dInfo->State = DOT11D_STATE_NONE; - pDot11dInfo->CountryIeLen = 0; + (dot11d_info->channel_map)[i] = 2; + dot11d_info->state = DOT11D_STATE_NONE; + dot11d_info->country_len = 0; RESET_CIE_WATCHDOG(ieee); } -void Dot11d_UpdateCountryIe(struct rtllib_device *dev, u8 *pTaddr, - u16 CoutryIeLen, u8 *pCoutryIe) +void dot11d_update_country(struct rtllib_device *dev, u8 *address, + u16 country_len, u8 *country) { - struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev); - u8 i, j, NumTriples, MaxChnlNum; - struct chnl_txpow_triple *pTriple; - - memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER + 1); - memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER + 1); - MaxChnlNum = 0; - NumTriples = (CoutryIeLen - 3) / 3; - pTriple = (struct chnl_txpow_triple *)(pCoutryIe + 3); - for (i = 0; i < NumTriples; i++) { - if (MaxChnlNum >= pTriple->FirstChnl) { + struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(dev); + u8 i, j, number_of_triples, max_channel_number; + struct chnl_txpow_triple *triple; + + memset(dot11d_info->channel_map, 0, MAX_CHANNEL_NUMBER + 1); + memset(dot11d_info->max_tx_power_list, 0xFF, MAX_CHANNEL_NUMBER + 1); + max_channel_number = 0; + number_of_triples = (country_len - 3) / 3; + triple = (struct chnl_txpow_triple *)(country + 3); + for (i = 0; i < number_of_triples; i++) { + if (max_channel_number >= triple->first_channel) { netdev_info(dev->dev, "%s: Invalid country IE, skip it......1\n", __func__); return; } - if (MAX_CHANNEL_NUMBER < (pTriple->FirstChnl + - pTriple->NumChnls)) { + if (MAX_CHANNEL_NUMBER < (triple->first_channel + + triple->num_channels)) { netdev_info(dev->dev, "%s: Invalid country IE, skip it......2\n", __func__); return; } - for (j = 0; j < pTriple->NumChnls; j++) { - pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1; - pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = - pTriple->MaxTxPowerInDbm; - MaxChnlNum = pTriple->FirstChnl + j; + for (j = 0; j < triple->num_channels; j++) { + dot11d_info->channel_map[triple->first_channel + j] = 1; + dot11d_info->max_tx_power_list[triple->first_channel + j] = + triple->max_tx_power; + max_channel_number = triple->first_channel + j; } - pTriple = (struct chnl_txpow_triple *)((u8 *)pTriple + 3); + triple = (struct chnl_txpow_triple *)((u8 *)triple + 3); } - UPDATE_CIE_SRC(dev, pTaddr); + UPDATE_CIE_SRC(dev, address); - pDot11dInfo->CountryIeLen = CoutryIeLen; - memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe, CoutryIeLen); - pDot11dInfo->State = DOT11D_STATE_LEARNED; + dot11d_info->country_len = country_len; + memcpy(dot11d_info->country_buffer, country, country_len); + dot11d_info->state = DOT11D_STATE_LEARNED; } -void DOT11D_ScanComplete(struct rtllib_device *dev) +void dot11d_scan_complete(struct rtllib_device *dev) { - struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev); + struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(dev); - switch (pDot11dInfo->State) { + switch (dot11d_info->state) { case DOT11D_STATE_LEARNED: - pDot11dInfo->State = DOT11D_STATE_DONE; + dot11d_info->state = DOT11D_STATE_DONE; break; case DOT11D_STATE_DONE: - Dot11d_Reset(dev); + dot11d_reset(dev); break; case DOT11D_STATE_NONE: break; diff --git a/drivers/staging/rtl8192e/dot11d.h b/drivers/staging/rtl8192e/dot11d.h index 7fa3c4d963c4..6d2b93acfa43 100644 --- a/drivers/staging/rtl8192e/dot11d.h +++ b/drivers/staging/rtl8192e/dot11d.h @@ -1,14 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************** * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. * - * 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. - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * * Contact Information: * wlanfae <wlanfae@realtek.com> ******************************************************************************/ @@ -18,9 +11,9 @@ #include "rtllib.h" struct chnl_txpow_triple { - u8 FirstChnl; - u8 NumChnls; - u8 MaxTxPowerInDbm; + u8 first_channel; + u8 num_channels; + u8 max_tx_power; }; enum dot11d_state { @@ -30,62 +23,62 @@ enum dot11d_state { }; /** - * struct rt_dot11d_info * @CountryIeLen: value greater than 0 if - * @CountryIeBuf contains valid country information element. + * struct rt_dot11d_info * @country_len: value greater than 0 if + * @country_buffer contains valid country information element. * @channel_map: holds channel values * 0 - invalid, * 1 - valid (active scan), * 2 - valid (passive scan) - * @CountryIeSrcAddr - Source AP of the country IE + * @country_src_addr - Source AP of the country IE */ struct rt_dot11d_info { - bool bEnabled; + bool enabled; - u16 CountryIeLen; - u8 CountryIeBuf[MAX_IE_LEN]; - u8 CountryIeSrcAddr[6]; - u8 CountryIeWatchdog; + u16 country_len; + u8 country_buffer[MAX_IE_LEN]; + u8 country_src_addr[6]; + u8 country_watchdog; u8 channel_map[MAX_CHANNEL_NUMBER + 1]; - u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER + 1]; + u8 max_tx_power_list[MAX_CHANNEL_NUMBER + 1]; - enum dot11d_state State; + enum dot11d_state state; }; -static inline void cpMacAddr(unsigned char *des, unsigned char *src) +static inline void copy_mac_addr(unsigned char *des, unsigned char *src) { memcpy(des, src, 6); } -#define GET_DOT11D_INFO(__pIeeeDev) \ - ((struct rt_dot11d_info *)((__pIeeeDev)->pDot11dInfo)) +#define GET_DOT11D_INFO(__ieee_dev) \ + ((struct rt_dot11d_info *)((__ieee_dev)->dot11d_info)) -#define IS_DOT11D_ENABLE(__pIeeeDev) \ - (GET_DOT11D_INFO(__pIeeeDev)->bEnabled) -#define IS_COUNTRY_IE_VALID(__pIeeeDev) \ - (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0) +#define IS_DOT11D_ENABLE(__ieee_dev) \ + (GET_DOT11D_INFO(__ieee_dev)->enabled) +#define IS_COUNTRY_IE_VALID(__ieee_dev) \ + (GET_DOT11D_INFO(__ieee_dev)->country_len > 0) -#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) \ +#define IS_EQUAL_CIE_SRC(__ieee_dev, __address) \ ether_addr_equal_unaligned( \ - GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) -#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) \ - cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) + GET_DOT11D_INFO(__ieee_dev)->country_src_addr, __address) +#define UPDATE_CIE_SRC(__ieee_dev, __address) \ + copy_mac_addr(GET_DOT11D_INFO(__ieee_dev)->country_src_addr, __address) -#define GET_CIE_WATCHDOG(__pIeeeDev) \ - (GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog) -static inline void RESET_CIE_WATCHDOG(struct rtllib_device *__pIeeeDev) +#define GET_CIE_WATCHDOG(__ieee_dev) \ + (GET_DOT11D_INFO(__ieee_dev)->country_watchdog) +static inline void RESET_CIE_WATCHDOG(struct rtllib_device *__ieee_dev) { - GET_CIE_WATCHDOG(__pIeeeDev) = 0; + GET_CIE_WATCHDOG(__ieee_dev) = 0; } -#define UPDATE_CIE_WATCHDOG(__pIeeeDev) (++GET_CIE_WATCHDOG(__pIeeeDev)) +#define UPDATE_CIE_WATCHDOG(__ieee_dev) (++GET_CIE_WATCHDOG(__ieee_dev)) void dot11d_init(struct rtllib_device *dev); -void Dot11d_Channelmap(u8 channel_plan, struct rtllib_device *ieee); -void Dot11d_Reset(struct rtllib_device *dev); -void Dot11d_UpdateCountryIe(struct rtllib_device *dev, u8 *pTaddr, - u16 CoutryIeLen, u8 *pCoutryIe); -void DOT11D_ScanComplete(struct rtllib_device *dev); +void dot11d_channel_map(u8 channel_plan, struct rtllib_device *ieee); +void dot11d_reset(struct rtllib_device *dev); +void dot11d_update_country(struct rtllib_device *dev, u8 *address, + u16 country_len, u8 *country); +void dot11d_scan_complete(struct rtllib_device *dev); #endif diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c index 1c6ed5b2a6f9..19bb04b3f097 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c @@ -660,9 +660,9 @@ static void _rtl92e_hwconfig(struct net_device *dev) case WIRELESS_MODE_AUTO: case WIRELESS_MODE_N_24G: regBwOpMode = BW_OPMODE_20MHZ; - regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | - RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; - regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | + RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; + regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; break; case WIRELESS_MODE_N_5G: regBwOpMode = BW_OPMODE_5G; @@ -961,7 +961,7 @@ static void _rtl92e_net_update(struct net_device *dev) net = &priv->rtllib->current_network; rtl92e_config_rate(dev, &rate_config); priv->dot11CurrentPreambleMode = PREAMBLE_AUTO; - priv->basic_rate = rate_config &= 0x15f; + priv->basic_rate = rate_config &= 0x15f; rtl92e_writew(dev, BSSIDR, *(u16 *)net->bssid); rtl92e_writel(dev, BSSIDR + 2, *(u32 *)(net->bssid + 2)); diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 96f265eee007..253f1911a3f4 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -436,7 +436,7 @@ static int _rtl92e_qos_handle_probe_response(struct r8192_priv *priv, network->qos_data.param_count)) { network->qos_data.old_param_count = network->qos_data.param_count; - priv->rtllib->wmm_acm = network->qos_data.wmm_acm; + priv->rtllib->wmm_acm = network->qos_data.wmm_acm; schedule_work(&priv->qos_activate); RT_TRACE(COMP_QOS, "QoS parameters change call qos_activate\n"); @@ -1049,7 +1049,7 @@ static short _rtl92e_get_channel_map(struct net_device *dev) } RT_TRACE(COMP_INIT, "Channel plan is %d\n", priv->ChannelPlan); dot11d_init(priv->rtllib); - Dot11d_Channelmap(priv->ChannelPlan, priv->rtllib); + dot11d_channel_map(priv->ChannelPlan, priv->rtllib); for (i = 1; i <= 11; i++) (priv->rtllib->active_channel_map)[i] = 1; (priv->rtllib->active_channel_map)[12] = 2; @@ -1573,7 +1573,7 @@ static void _rtl92e_free_rx_ring(struct net_device *dev) pci_unmap_single(priv->pdev, *((dma_addr_t *)skb->cb), priv->rxbuffersize, PCI_DMA_FROMDEVICE); - kfree_skb(skb); + kfree_skb(skb); } pci_free_consistent(priv->pdev, @@ -1728,8 +1728,7 @@ static short _rtl92e_tx(struct net_device *dev, struct sk_buff *skb) MAX_DEV_ADDR_SIZE); struct tx_desc *pdesc = NULL; struct rtllib_hdr_1addr *header = NULL; - u16 fc = 0, type = 0, stype = 0; - bool multi_addr = false, broad_addr = false, uni_addr = false; + u16 fc = 0, type = 0; u8 *pda_addr = NULL; int idx; u32 fwinfo_size = 0; @@ -1747,22 +1746,14 @@ static short _rtl92e_tx(struct net_device *dev, struct sk_buff *skb) header = (struct rtllib_hdr_1addr *)(((u8 *)skb->data) + fwinfo_size); fc = le16_to_cpu(header->frame_ctl); type = WLAN_FC_GET_TYPE(fc); - stype = WLAN_FC_GET_STYPE(fc); pda_addr = header->addr1; if (is_broadcast_ether_addr(pda_addr)) - broad_addr = true; + priv->stats.txbytesbroadcast += skb->len - fwinfo_size; else if (is_multicast_ether_addr(pda_addr)) - multi_addr = true; - else - uni_addr = true; - - if (uni_addr) - priv->stats.txbytesunicast += skb->len - fwinfo_size; - else if (multi_addr) priv->stats.txbytesmulticast += skb->len - fwinfo_size; else - priv->stats.txbytesbroadcast += skb->len - fwinfo_size; + priv->stats.txbytesunicast += skb->len - fwinfo_size; spin_lock_irqsave(&priv->irq_th_lock, flags); ring = &priv->tx_ring[tcb_desc->queue_index]; @@ -2515,7 +2506,7 @@ static int _rtl92e_pci_probe(struct pci_dev *pdev, if (dev_alloc_name(dev, ifname) < 0) { RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n"); - dev_alloc_name(dev, ifname); + dev_alloc_name(dev, ifname); } RT_TRACE(COMP_INIT, "Driver probe completed1\n"); diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c index 9bf95bd0ad13..157bcee34067 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c @@ -996,7 +996,7 @@ static void _rtl92e_dm_check_tx_power_tracking_tssi(struct net_device *dev) tx_power_track_counter++; - if (tx_power_track_counter >= 180) { + if (tx_power_track_counter >= 180) { schedule_delayed_work(&priv->txpower_tracking_wq, 0); tx_power_track_counter = 0; } diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c index 843e874b8a06..44e06cba7b7b 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c @@ -738,7 +738,7 @@ static int _rtl92e_wx_set_enc(struct net_device *dev, else if (wrqu->encoding.length == 0xd) { ieee->pairwise_key_type = KEY_TYPE_WEP104; - rtl92e_enable_hw_security_config(dev); + rtl92e_enable_hw_security_config(dev); rtl92e_set_key(dev, key_idx, key_idx, KEY_TYPE_WEP104, zero_addr[key_idx], 0, hwkey); rtl92e_set_swcam(dev, key_idx, key_idx, KEY_TYPE_WEP104, @@ -1049,9 +1049,9 @@ static int _rtl92e_wx_set_promisc_mode(struct net_device *dev, (bPromiscuousOn) ? (true) : (false); ieee->IntelPromiscuousModeInfo.bFilterSourceStationFrame = (bFilterSourceStationFrame) ? (true) : (false); - (bPromiscuousOn) ? - (rtllib_EnableIntelPromiscuousMode(dev, false)) : - (rtllib_DisableIntelPromiscuousMode(dev, false)); + (bPromiscuousOn) ? + (rtllib_EnableIntelPromiscuousMode(dev, false)) : + (rtllib_DisableIntelPromiscuousMode(dev, false)); netdev_info(dev, "=======>%s(), on = %d, filter src sta = %d\n", diff --git a/drivers/staging/rtl8192e/rtl819x_BAProc.c b/drivers/staging/rtl8192e/rtl819x_BAProc.c index 687dbb04ed2e..2d330d2bbf6d 100644 --- a/drivers/staging/rtl8192e/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192e/rtl819x_BAProc.c @@ -139,7 +139,7 @@ static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst, { union delba_param_set DelbaParamSet; struct sk_buff *skb = NULL; - struct rtllib_hdr_3addr *Delba = NULL; + struct rtllib_hdr_3addr *Delba = NULL; u8 *tag = NULL; u16 len = 6 + ieee->tx_headroom; @@ -316,7 +316,7 @@ OnADDBAReq_Fail: int rtllib_rx_ADDBARsp(struct rtllib_device *ieee, struct sk_buff *skb) { - struct rtllib_hdr_3addr *rsp = NULL; + struct rtllib_hdr_3addr *rsp = NULL; struct ba_record *pPendingBA, *pAdmittedBA; struct tx_ts_record *pTS = NULL; u8 *dst = NULL, *pDialogToken = NULL, *tag = NULL; @@ -420,7 +420,7 @@ OnADDBARsp_Reject: int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb) { - struct rtllib_hdr_3addr *delba = NULL; + struct rtllib_hdr_3addr *delba = NULL; union delba_param_set *pDelBaParamSet = NULL; u8 *dst = NULL; diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index c01474a6db1e..61ebd12831c3 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -1560,11 +1560,11 @@ struct rtllib_device { u16 scan_watch_dog; /* map of allowed channels. 0 is dummy */ - void *pDot11dInfo; - bool bGlobalDomain; + void *dot11d_info; + bool global_domain; u8 active_channel_map[MAX_CHANNEL_NUMBER+1]; - u8 IbssStartChnl; + u8 bss_start_channel; u8 ibss_maxjoin_chal; int rate; /* current rate */ diff --git a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c index f38f1f74fcd6..55da8c9dfe50 100644 --- a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c +++ b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c @@ -285,7 +285,7 @@ static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK, static int rtllib_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) { struct rtllib_tkip_data *tkey = priv; - int len; + int len; u8 *pos; struct rtllib_hdr_4addr *hdr; struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c index fa580ce1cf43..debc2e40af00 100644 --- a/drivers/staging/rtl8192e/rtllib_rx.c +++ b/drivers/staging/rtl8192e/rtllib_rx.c @@ -913,7 +913,7 @@ static size_t rtllib_rx_get_hdrlen(struct rtllib_device *ieee, rx_stats->bContainHTC = true; } - if (RTLLIB_QOS_HAS_SEQ(fc)) + if (RTLLIB_QOS_HAS_SEQ(fc)) rx_stats->bIsQosData = true; return hdrlen; @@ -1812,7 +1812,7 @@ static inline void rtllib_extract_country_ie( netdev_info(ieee->dev, "Received beacon ContryIE, SSID: <%s>\n", network->ssid); - Dot11d_UpdateCountryIe(ieee, addr2, + dot11d_update_country(ieee, addr2, info_element->len, info_element->data); } diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index 287d0c11fa38..ee275857868f 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -564,7 +564,7 @@ out: if (ieee->state >= RTLLIB_LINKED) { if (IS_DOT11D_ENABLE(ieee)) - DOT11D_ScanComplete(ieee); + dot11d_scan_complete(ieee); } mutex_unlock(&ieee->scan_mutex); @@ -623,7 +623,7 @@ static void rtllib_softmac_scan_wq(void *data) out: if (IS_DOT11D_ENABLE(ieee)) - DOT11D_ScanComplete(ieee); + dot11d_scan_complete(ieee); ieee->current_network.channel = last_channel; out1: @@ -1688,8 +1688,8 @@ inline void rtllib_softmac_new_net(struct rtllib_device *ieee, ieee->current_network.ssid_len); tmp_ssid_len = ieee->current_network.ssid_len; } - memcpy(&ieee->current_network, net, - sizeof(ieee->current_network)); + memcpy(&ieee->current_network, net, + sizeof(ieee->current_network)); if (!ssidbroad) { memcpy(ieee->current_network.ssid, tmp_ssid, tmp_ssid_len); @@ -2627,7 +2627,7 @@ static void rtllib_start_ibss_wq(void *data) /* the network definitively is not here.. create a new cell */ if (ieee->state == RTLLIB_NOLINK) { netdev_info(ieee->dev, "creating new IBSS cell\n"); - ieee->current_network.channel = ieee->IbssStartChnl; + ieee->current_network.channel = ieee->bss_start_channel; if (!ieee->wap_set) eth_random_addr(ieee->current_network.bssid); @@ -2719,7 +2719,7 @@ static void rtllib_start_bss(struct rtllib_device *ieee) unsigned long flags; if (IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee)) { - if (!ieee->bGlobalDomain) + if (!ieee->global_domain) return; } /* check if we have already found the net we @@ -2759,7 +2759,7 @@ void rtllib_disassociate(struct rtllib_device *ieee) if (ieee->data_hard_stop) ieee->data_hard_stop(ieee->dev); if (IS_DOT11D_ENABLE(ieee)) - Dot11d_Reset(ieee); + dot11d_reset(ieee); ieee->state = RTLLIB_NOLINK; ieee->is_set_key = false; ieee->wap_set = 0; @@ -2974,8 +2974,8 @@ void rtllib_softmac_init(struct rtllib_device *ieee) ieee->state = RTLLIB_NOLINK; for (i = 0; i < 5; i++) ieee->seq_ctrl[i] = 0; - ieee->pDot11dInfo = kzalloc(sizeof(struct rt_dot11d_info), GFP_ATOMIC); - if (!ieee->pDot11dInfo) + ieee->dot11d_info = kzalloc(sizeof(struct rt_dot11d_info), GFP_ATOMIC); + if (!ieee->dot11d_info) netdev_err(ieee->dev, "Can't alloc memory for DOT11D\n"); ieee->LinkDetectInfo.SlotIndex = 0; ieee->LinkDetectInfo.SlotNum = 2; @@ -3049,8 +3049,8 @@ void rtllib_softmac_init(struct rtllib_device *ieee) void rtllib_softmac_free(struct rtllib_device *ieee) { mutex_lock(&ieee->wx_mutex); - kfree(ieee->pDot11dInfo); - ieee->pDot11dInfo = NULL; + kfree(ieee->dot11d_info); + ieee->dot11d_info = NULL; del_timer_sync(&ieee->associate_timer); cancel_delayed_work_sync(&ieee->associate_retry_wq); diff --git a/drivers/staging/rtl8192e/rtllib_wx.c b/drivers/staging/rtl8192e/rtllib_wx.c index 74d4d2df3eb3..4f4904a300e0 100644 --- a/drivers/staging/rtl8192e/rtllib_wx.c +++ b/drivers/staging/rtl8192e/rtllib_wx.c @@ -541,8 +541,8 @@ int rtllib_wx_set_encode_ext(struct rtllib_device *ieee, if (idx < 1 || idx > NUM_WEP_KEYS) return -EINVAL; idx--; - } else{ - idx = ieee->crypt_info.tx_keyidx; + } else { + idx = ieee->crypt_info.tx_keyidx; } if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { crypt = &ieee->crypt_info.crypt[idx]; diff --git a/drivers/staging/rtl8192u/Makefile b/drivers/staging/rtl8192u/Makefile index 3022728a364c..dcd51bf4aed3 100644 --- a/drivers/staging/rtl8192u/Makefile +++ b/drivers/staging/rtl8192u/Makefile @@ -7,7 +7,7 @@ ccflags-y += -O2 ccflags-y += -DCONFIG_FORCE_HARD_FLOAT=y ccflags-y += -DJACKSON_NEW_8187 -DJACKSON_NEW_RX ccflags-y += -DTHOMAS_BEACON -DTHOMAS_TASKLET -DTHOMAS_SKB -DTHOMAS_TURBO -ccflags-y += -Idrivers/staging/rtl8192u/ieee80211 +ccflags-y += -I $(srctree)/$(src)/ieee80211 r8192u_usb-y := r8192U_core.o r8180_93cx6.o r8192U_wx.o \ r8190_rtl8256.o r819xU_phy.o r819xU_firmware.o \ diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index 0ac0bbf7d923..f1eaab337dca 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -4957,20 +4957,18 @@ static void rtl8192_usb_disconnect(struct usb_interface *intf) struct net_device *dev = usb_get_intfdata(intf); struct r8192_priv *priv = ieee80211_priv(dev); - if (dev) { - unregister_netdev(dev); - - RT_TRACE(COMP_DOWN, - "=============>wlan driver to be removed\n"); - rtl8192_proc_remove_one(dev); - - rtl8192_down(dev); - kfree(priv->pFirmware); - priv->pFirmware = NULL; - rtl8192_usb_deleteendpoints(dev); - usleep_range(10000, 11000); - } + unregister_netdev(dev); + + RT_TRACE(COMP_DOWN, "=============>wlan driver to be removed\n"); + rtl8192_proc_remove_one(dev); + + rtl8192_down(dev); + kfree(priv->pFirmware); + priv->pFirmware = NULL; + rtl8192_usb_deleteendpoints(dev); + usleep_range(10000, 11000); free_ieee80211(dev); + RT_TRACE(COMP_DOWN, "wlan driver removed\n"); } diff --git a/drivers/staging/rtl8712/ieee80211.c b/drivers/staging/rtl8712/ieee80211.c index bb4f56a5fb01..2eae11dd6b42 100644 --- a/drivers/staging/rtl8712/ieee80211.c +++ b/drivers/staging/rtl8712/ieee80211.c @@ -408,7 +408,7 @@ int r8712_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen) match = true; break; } - cnt += in_ie[cnt + 1] + 2; /* goto next */ + cnt += in_ie[cnt + 1] + 2; /* goto next */ } return match; } diff --git a/drivers/staging/rtl8712/rtl8712_efuse.c b/drivers/staging/rtl8712/rtl8712_efuse.c index 8bc45ffd3029..39eb74374d0b 100644 --- a/drivers/staging/rtl8712/rtl8712_efuse.c +++ b/drivers/staging/rtl8712/rtl8712_efuse.c @@ -358,7 +358,7 @@ u8 r8712_efuse_pg_packet_write(struct _adapter *padapter, const u8 offset, u8 pg_header = 0; u16 efuse_addr = 0, curr_size = 0; u8 efuse_data, target_word_cnts = 0; - static int repeat_times; + int repeat_times; int sub_repeat; u8 bResult = true; diff --git a/drivers/staging/rtl8712/rtl8712_led.c b/drivers/staging/rtl8712/rtl8712_led.c index 5b1004b2df47..07fcf9b9b811 100644 --- a/drivers/staging/rtl8712/rtl8712_led.c +++ b/drivers/staging/rtl8712/rtl8712_led.c @@ -939,7 +939,7 @@ static void SwLedControlMode1(struct _adapter *padapter, } if (pLed->bLedLinkBlinkInProgress) { del_timer(&pLed->BlinkTimer); - pLed->bLedLinkBlinkInProgress = false; + pLed->bLedLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress) { del_timer(&pLed->BlinkTimer); @@ -991,7 +991,7 @@ static void SwLedControlMode1(struct _adapter *padapter, } if (pLed->bLedLinkBlinkInProgress) { del_timer(&pLed->BlinkTimer); - pLed->bLedLinkBlinkInProgress = false; + pLed->bLedLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress) { del_timer(&pLed->BlinkTimer); @@ -1018,7 +1018,7 @@ static void SwLedControlMode1(struct _adapter *padapter, } if (pLed->bLedLinkBlinkInProgress) { del_timer(&pLed->BlinkTimer); - pLed->bLedLinkBlinkInProgress = false; + pLed->bLedLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress) { del_timer(&pLed->BlinkTimer); diff --git a/drivers/staging/rtl8712/rtl871x_mlme.c b/drivers/staging/rtl8712/rtl871x_mlme.c index 986a1d526918..3f17ef6f7e39 100644 --- a/drivers/staging/rtl8712/rtl871x_mlme.c +++ b/drivers/staging/rtl8712/rtl871x_mlme.c @@ -259,7 +259,7 @@ int r8712_is_same_ibss(struct _adapter *adapter, struct wlan_network *pnetwork) static int is_same_network(struct wlan_bssid_ex *src, struct wlan_bssid_ex *dst) { - u16 s_cap, d_cap; + u16 s_cap, d_cap; memcpy((u8 *)&s_cap, r8712_get_capability_from_ie(src->IEs), 2); memcpy((u8 *)&d_cap, r8712_get_capability_from_ie(dst->IEs), 2); diff --git a/drivers/staging/rtl8712/rtl871x_recv.c b/drivers/staging/rtl8712/rtl871x_recv.c index f10896df094b..28f736913292 100644 --- a/drivers/staging/rtl8712/rtl871x_recv.c +++ b/drivers/staging/rtl8712/rtl871x_recv.c @@ -54,7 +54,7 @@ sint _r8712_init_recv_priv(struct recv_priv *precvpriv, sint i; union recv_frame *precvframe; - memset((unsigned char *)precvpriv, 0, sizeof(struct recv_priv)); + memset((unsigned char *)precvpriv, 0, sizeof(struct recv_priv)); spin_lock_init(&precvpriv->lock); _init_queue(&precvpriv->free_recv_queue); _init_queue(&precvpriv->recv_pending_queue); @@ -325,7 +325,7 @@ static sint sta2sta_data_frame(struct _adapter *adapter, */ if (memcmp(pattrib->bssid, pattrib->src, ETH_ALEN)) return _FAIL; - sta_addr = pattrib->bssid; + sta_addr = pattrib->bssid; } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { if (bmcast) { /* For AP mode, if DA == MCAST, then BSSID should @@ -404,7 +404,7 @@ static sint ap2sta_data_frame(struct _adapter *adapter, if (bmcast) *psta = r8712_get_bcmc_stainfo(adapter); else - *psta = r8712_get_stainfo(pstapriv, pattrib->bssid); + *psta = r8712_get_stainfo(pstapriv, pattrib->bssid); if (*psta == NULL) return _FAIL; } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) && diff --git a/drivers/staging/rtl8712/rtl871x_sta_mgt.c b/drivers/staging/rtl8712/rtl871x_sta_mgt.c index 9648ee15b40e..7c30b9e68e70 100644 --- a/drivers/staging/rtl8712/rtl871x_sta_mgt.c +++ b/drivers/staging/rtl8712/rtl871x_sta_mgt.c @@ -25,7 +25,7 @@ static void _init_stainfo(struct sta_info *psta) { memset((u8 *)psta, 0, sizeof(struct sta_info)); - spin_lock_init(&psta->lock); + spin_lock_init(&psta->lock); INIT_LIST_HEAD(&psta->list); INIT_LIST_HEAD(&psta->hash_list); _r8712_init_sta_xmit_priv(&psta->sta_xmitpriv); diff --git a/drivers/staging/rtl8712/rtl871x_xmit.c b/drivers/staging/rtl8712/rtl871x_xmit.c index 5c7dc9c6f76b..7c8857409916 100644 --- a/drivers/staging/rtl8712/rtl871x_xmit.c +++ b/drivers/staging/rtl8712/rtl871x_xmit.c @@ -193,8 +193,8 @@ sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, pattrib->ether_type = ntohs(etherhdr.h_proto); -{ - /*If driver xmit ARP packet, driver can set ps mode to initial + /* + * If driver xmit ARP packet, driver can set ps mode to initial * setting. It stands for getting DHCP or fix IP. */ if (pattrib->ether_type == 0x0806) { @@ -206,7 +206,7 @@ sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, padapter->registrypriv.smart_ps); } } -} + memcpy(pattrib->dst, ðerhdr.h_dest, ETH_ALEN); memcpy(pattrib->src, ðerhdr.h_source, ETH_ALEN); pattrib->pctrl = 0; @@ -949,7 +949,7 @@ static void alloc_hwxmits(struct _adapter *padapter) pxmitpriv->vo_txqueue.head = 0; hwxmits[1] .phwtxqueue = &pxmitpriv->vo_txqueue; hwxmits[1] .sta_queue = &pxmitpriv->vo_pending; - pxmitpriv->vi_txqueue.head = 0; + pxmitpriv->vi_txqueue.head = 0; hwxmits[2] .phwtxqueue = &pxmitpriv->vi_txqueue; hwxmits[2] .sta_queue = &pxmitpriv->vi_pending; pxmitpriv->bk_txqueue.head = 0; diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c index 92d75d7c51ae..005010de9997 100644 --- a/drivers/staging/rtl8712/usb_intf.c +++ b/drivers/staging/rtl8712/usb_intf.c @@ -196,10 +196,6 @@ static int r871x_suspend(struct usb_interface *pusb_intf, pm_message_t state) struct _adapter *padapter = netdev_priv(pnetdev); netdev_info(pnetdev, "Suspending...\n"); - if (!pnetdev || !netif_running(pnetdev)) { - netdev_info(pnetdev, "Unable to suspend\n"); - return 0; - } padapter->bSuspended = true; rtl871x_intf_stop(padapter); if (pnetdev->netdev_ops->ndo_stop) @@ -221,10 +217,6 @@ static int r871x_resume(struct usb_interface *pusb_intf) struct _adapter *padapter = netdev_priv(pnetdev); netdev_info(pnetdev, "Resuming...\n"); - if (!pnetdev || !netif_running(pnetdev)) { - netdev_info(pnetdev, "Unable to resume\n"); - return 0; - } netif_device_attach(pnetdev); if (pnetdev->netdev_ops->ndo_open) pnetdev->netdev_ops->ndo_open(pnetdev); @@ -232,13 +224,6 @@ static int r871x_resume(struct usb_interface *pusb_intf) rtl871x_intf_resume(padapter); return 0; } - -static int r871x_reset_resume(struct usb_interface *pusb_intf) -{ - /* dummy routine */ - return 0; -} - #endif static struct drv_priv drvpriv = { @@ -249,7 +234,6 @@ static struct drv_priv drvpriv = { #ifdef CONFIG_PM .r871xu_drv.suspend = r871x_suspend, .r871xu_drv.resume = r871x_resume, - .r871xu_drv.reset_resume = r871x_reset_resume, #endif }; diff --git a/drivers/staging/rtl8723bs/core/rtw_cmd.c b/drivers/staging/rtl8723bs/core/rtw_cmd.c index ea2c187e56bd..91520ca3bbad 100644 --- a/drivers/staging/rtl8723bs/core/rtw_cmd.c +++ b/drivers/staging/rtl8723bs/core/rtw_cmd.c @@ -835,14 +835,6 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) } psecnetwork = (struct wlan_bssid_ex *)&psecuritypriv->sec_bss; - if (psecnetwork == NULL) { - kfree(pcmd); - res = _FAIL; - - RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("rtw_joinbss_cmd :psecnetwork == NULL!!!\n")); - - goto exit; - } memset(psecnetwork, 0, t_len); diff --git a/drivers/staging/rtl8723bs/core/rtw_xmit.c b/drivers/staging/rtl8723bs/core/rtw_xmit.c index 625e67f39889..094d61bcb469 100644 --- a/drivers/staging/rtl8723bs/core/rtw_xmit.c +++ b/drivers/staging/rtl8723bs/core/rtw_xmit.c @@ -2389,7 +2389,7 @@ sint xmitframe_enqueue_for_sleeping_sta(struct adapter *padapter, struct xmit_fr if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == false) { DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_fwstate); - return ret; + return ret; } /* if (pattrib->psta) diff --git a/drivers/staging/rtl8723bs/include/drv_types.h b/drivers/staging/rtl8723bs/include/drv_types.h index 062fda9962be..bafb2c30e7fb 100644 --- a/drivers/staging/rtl8723bs/include/drv_types.h +++ b/drivers/staging/rtl8723bs/include/drv_types.h @@ -65,7 +65,6 @@ enum _NIC_VERSION { #include <rtw_event.h> #include <rtw_mlme_ext.h> #include <rtw_ap.h> -#include <rtw_efuse.h> #include <rtw_version.h> #include <rtw_odm.h> diff --git a/drivers/staging/rtlwifi/Kconfig b/drivers/staging/rtlwifi/Kconfig index 7b4276f5c41f..28286a87a601 100644 --- a/drivers/staging/rtlwifi/Kconfig +++ b/drivers/staging/rtlwifi/Kconfig @@ -2,7 +2,7 @@ config R8822BE tristate "Realtek RTL8822BE Wireless Network Adapter" depends on PCI && MAC80211 && m select FW_LOADER - ---help--- + help This is the staging driver for Realtek RTL8822BE 802.11ac PCIe wireless network adapters. diff --git a/drivers/staging/rtlwifi/efuse.c b/drivers/staging/rtlwifi/efuse.c index abb0f720cf21..a7c9e186f2b2 100644 --- a/drivers/staging/rtlwifi/efuse.c +++ b/drivers/staging/rtlwifi/efuse.c @@ -919,7 +919,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct pgpkt_struct target_pkt; u8 write_state = PG_STATE_HEADER; - int continual = true, dataempty = true, result = true; + int continual = true, result = true; u16 efuse_addr = 0; u8 efuse_data; u8 target_word_cnts = 0; @@ -946,7 +946,6 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, while (continual && (efuse_addr < (EFUSE_MAX_SIZE - rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN]))) { if (write_state == PG_STATE_HEADER) { - dataempty = true; badworden = 0x0F; RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, "efuse PG_STATE_HEADER\n"); @@ -1182,13 +1181,12 @@ static u16 efuse_get_current_size(struct ieee80211_hw *hw) { int continual = true; u16 efuse_addr = 0; - u8 hoffset, hworden; + u8 hworden; u8 efuse_data, word_cnts; while (continual && efuse_one_byte_read(hw, efuse_addr, &efuse_data) && (efuse_addr < EFUSE_MAX_SIZE)) { if (efuse_data != 0xFF) { - hoffset = (efuse_data >> 4) & 0x0F; hworden = efuse_data & 0x0F; word_cnts = efuse_calculate_word_cnts(hworden); efuse_addr = efuse_addr + (word_cnts * 2) + 1; diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_func_88xx.c b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_func_88xx.c index 53f55f129a76..ddbeff8224ab 100644 --- a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_func_88xx.c +++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_func_88xx.c @@ -2466,8 +2466,11 @@ halmac_parse_psd_data_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf, segment_size = (u8)PSD_DATA_GET_SEGMENT_SIZE(c2h_buf); psd_set->data_size = total_size; - if (!psd_set->data) + if (!psd_set->data) { psd_set->data = kzalloc(psd_set->data_size, GFP_KERNEL); + if (!psd_set->data) + return HALMAC_RET_MALLOC_FAIL; + } if (segment_id == 0) psd_set->segment_size = segment_size; diff --git a/drivers/staging/rtlwifi/pci.h b/drivers/staging/rtlwifi/pci.h index 7535ac24bfbb..0e55baec95a8 100644 --- a/drivers/staging/rtlwifi/pci.h +++ b/drivers/staging/rtlwifi/pci.h @@ -205,7 +205,8 @@ struct rtl_pci { /*Bcn control register setting */ u32 reg_bcn_ctrl_val; - /*ASPM*/ u8 const_pci_aspm; + /*ASPM*/ + u8 const_pci_aspm; u8 const_amdpci_aspm; u8 const_hwsw_rfoff_d3; u8 const_support_pciaspm; diff --git a/drivers/staging/rtlwifi/phydm/phydm_rainfo.c b/drivers/staging/rtlwifi/phydm/phydm_rainfo.c index b46791a727c7..ed740a93c8b6 100644 --- a/drivers/staging/rtlwifi/phydm/phydm_rainfo.c +++ b/drivers/staging/rtlwifi/phydm/phydm_rainfo.c @@ -124,7 +124,7 @@ void odm_c2h_ra_para_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len) ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", "VHT_EN =", cmd_buf[4]); ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", - "Hightest rate =", cmd_buf[5]); + "Highest rate =", cmd_buf[5]); ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n", "Lowest rate =", cmd_buf[6]); ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n", diff --git a/drivers/staging/rtlwifi/rtl8822be/fw.c b/drivers/staging/rtlwifi/rtl8822be/fw.c index a40396614814..f061dd1382aa 100644 --- a/drivers/staging/rtlwifi/rtl8822be/fw.c +++ b/drivers/staging/rtlwifi/rtl8822be/fw.c @@ -486,6 +486,8 @@ bool rtl8822b_halmac_cb_write_data_h2c(struct rtl_priv *rtlpriv, u8 *buf, /* without GFP_DMA, pci_map_single() may not work */ skb = __netdev_alloc_skb(NULL, size, GFP_ATOMIC | GFP_DMA); + if (!skb) + return false; memcpy((u8 *)skb_put(skb, size), buf, size); return _rtl8822be_send_bcn_or_cmd_packet(rtlpriv->hw, skb, H2C_QUEUE); diff --git a/drivers/staging/rts5208/ms.c b/drivers/staging/rts5208/ms.c index e43f92080c20..1128eec3bd08 100644 --- a/drivers/staging/rts5208/ms.c +++ b/drivers/staging/rts5208/ms.c @@ -1665,7 +1665,10 @@ static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, return STATUS_FAIL; } - ms_read_extra_data(chip, old_blk, i, extra, MS_EXTRA_SIZE); + retval = ms_read_extra_data(chip, old_blk, i, extra, + MS_EXTRA_SIZE); + if (retval != STATUS_SUCCESS) + return STATUS_FAIL; retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6); diff --git a/drivers/staging/rts5208/sd.c b/drivers/staging/rts5208/sd.c index 2c47ae613ea1..c256a2398651 100644 --- a/drivers/staging/rts5208/sd.c +++ b/drivers/staging/rts5208/sd.c @@ -4437,7 +4437,12 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) rtsx_init_cmd(chip); rtsx_add_cmd(chip, CHECK_REG_CMD, 0xFD30, 0x02, 0x02); - rtsx_send_cmd(chip, SD_CARD, 250); + retval = rtsx_send_cmd(chip, SD_CARD, 250); + if (retval < 0) { + write_err = true; + rtsx_clear_sd_error(chip); + goto sd_execute_write_cmd_failed; + } retval = sd_update_lock_status(chip); if (retval != STATUS_SUCCESS) { diff --git a/drivers/staging/sm750fb/ddk750_display.c b/drivers/staging/sm750fb/ddk750_display.c index 1273e7d18925..f38051eedb6c 100644 --- a/drivers/staging/sm750fb/ddk750_display.c +++ b/drivers/staging/sm750fb/ddk750_display.c @@ -5,7 +5,7 @@ #include "ddk750_power.h" #include "ddk750_dvi.h" -static void setDisplayControl(int ctrl, int disp_state) +static void set_display_control(int ctrl, int disp_state) { /* state != 0 means turn on both timing & plane en_bit */ unsigned long reg, val, reserved; @@ -137,12 +137,12 @@ void ddk750_setLogicalDispOut(enum disp_output output) if (output & PRI_TP_USAGE) { /* set primary timing and plane en_bit */ - setDisplayControl(0, (output & PRI_TP_MASK) >> PRI_TP_OFFSET); + set_display_control(0, (output & PRI_TP_MASK) >> PRI_TP_OFFSET); } if (output & SEC_TP_USAGE) { /* set secondary timing and plane en_bit*/ - setDisplayControl(1, (output & SEC_TP_MASK) >> SEC_TP_OFFSET); + set_display_control(1, (output & SEC_TP_MASK) >> SEC_TP_OFFSET); } if (output & PNL_SEQ_USAGE) { diff --git a/drivers/staging/speakup/Kconfig b/drivers/staging/speakup/Kconfig index efd6f4560d3e..d8ec780f7741 100644 --- a/drivers/staging/speakup/Kconfig +++ b/drivers/staging/speakup/Kconfig @@ -3,7 +3,7 @@ menu "Speakup console speech" config SPEAKUP depends on VT tristate "Speakup core" - ---help--- + help This is the Speakup screen reader. Think of it as a video console for blind people. If built in to the kernel, it can speak everything on the text console from @@ -43,7 +43,7 @@ config SPEAKUP if SPEAKUP config SPEAKUP_SYNTH_ACNTSA tristate "Accent SA synthesizer support" - ---help--- + help This is the Speakup driver for the Accent SA synthesizer. You can say y to build it into the kernel, or m to build it as a module. See the configuration @@ -52,7 +52,7 @@ config SPEAKUP_SYNTH_ACNTSA config SPEAKUP_SYNTH_ACNTPC tristate "Accent PC synthesizer support" depends on ISA || COMPILE_TEST - ---help--- + help This is the Speakup driver for the accent pc synthesizer. You can say y to build it into the kernel, or m to build it as a module. See the configuration @@ -60,7 +60,7 @@ config SPEAKUP_SYNTH_ACNTPC config SPEAKUP_SYNTH_APOLLO tristate "Apollo II synthesizer support" - ---help--- + help This is the Speakup driver for the Apollo II synthesizer. You can say y to build it into the kernel, or m to build it as a module. See the configuration @@ -68,7 +68,7 @@ config SPEAKUP_SYNTH_APOLLO config SPEAKUP_SYNTH_AUDPTR tristate "Audapter synthesizer support" - ---help--- + help This is the Speakup driver for the Audapter synthesizer. You can say y to build it into the kernel, or m to build it as a module. See the configuration help on the @@ -76,7 +76,7 @@ config SPEAKUP_SYNTH_AUDPTR config SPEAKUP_SYNTH_BNS tristate "Braille 'n' Speak synthesizer support" - ---help--- + help This is the Speakup driver for the Braille 'n' Speak synthesizer. You can say y to build it into the kernel, or m to build it as a module. See the configuration @@ -84,7 +84,7 @@ config SPEAKUP_SYNTH_BNS config SPEAKUP_SYNTH_DECTLK tristate "DECtalk Express synthesizer support" - ---help--- + help This is the Speakup driver for the DecTalk Express synthesizer. You can say y to build it into the kernel, @@ -93,7 +93,7 @@ config SPEAKUP_SYNTH_DECTLK config SPEAKUP_SYNTH_DECEXT tristate "DECtalk External (old) synthesizer support" - ---help--- + help This is the Speakup driver for the DecTalk External (old) synthesizer. You can say y to build it into the @@ -105,7 +105,7 @@ config SPEAKUP_SYNTH_DECPC depends on m depends on ISA || COMPILE_TEST tristate "DECtalk PC (big ISA card) synthesizer support" - ---help--- + help This is the Speakup driver for the DecTalk PC (full length ISA) synthesizer. You can say m to build it as @@ -127,7 +127,7 @@ config SPEAKUP_SYNTH_DECPC config SPEAKUP_SYNTH_DTLK tristate "DoubleTalk PC synthesizer support" depends on ISA || COMPILE_TEST - ---help--- + help This is the Speakup driver for the internal DoubleTalk PC synthesizer. You can say y to build it into the @@ -138,7 +138,7 @@ config SPEAKUP_SYNTH_DTLK config SPEAKUP_SYNTH_KEYPC tristate "Keynote Gold PC synthesizer support" depends on ISA || COMPILE_TEST - ---help--- + help This is the Speakup driver for the Keynote Gold PC synthesizer. You can say y to build it into the @@ -148,7 +148,7 @@ config SPEAKUP_SYNTH_KEYPC config SPEAKUP_SYNTH_LTLK tristate "DoubleTalk LT/LiteTalk synthesizer support" ----help--- +help This is the Speakup driver for the LiteTalk/DoubleTalk LT synthesizer. You can say y to build it into the @@ -158,7 +158,7 @@ config SPEAKUP_SYNTH_LTLK config SPEAKUP_SYNTH_SOFT tristate "Userspace software synthesizer support" - ---help--- + help This is the software synthesizer device node. It will register a device /dev/softsynth which midware programs @@ -169,7 +169,7 @@ config SPEAKUP_SYNTH_SOFT config SPEAKUP_SYNTH_SPKOUT tristate "Speak Out synthesizer support" - ---help--- + help This is the Speakup driver for the Speakout synthesizer. You can say y to build it into the kernel, or m to @@ -178,7 +178,7 @@ config SPEAKUP_SYNTH_SPKOUT config SPEAKUP_SYNTH_TXPRT tristate "Transport synthesizer support" - ---help--- + help This is the Speakup driver for the Transport synthesizer. You can say y to build it into the kernel, @@ -187,7 +187,7 @@ config SPEAKUP_SYNTH_TXPRT config SPEAKUP_SYNTH_DUMMY tristate "Dummy synthesizer driver (for testing)" - ---help--- + help This is a dummy Speakup driver for plugging a mere serial terminal. This is handy if you want to test speakup but diff --git a/drivers/staging/speakup/kobjects.c b/drivers/staging/speakup/kobjects.c index 2e36d872662c..11c704b27c3c 100644 --- a/drivers/staging/speakup/kobjects.c +++ b/drivers/staging/speakup/kobjects.c @@ -154,6 +154,7 @@ static ssize_t chars_chartab_store(struct kobject *kobj, continue; } + /* Do not replace with kstrtoul: here we need temp to be updated */ index = simple_strtoul(cp, &temp, 10); if (index > 255) { rejected++; @@ -787,6 +788,7 @@ static ssize_t message_store_helper(const char *buf, size_t count, continue; } + /* Do not replace with kstrtoul: here we need temp to be updated */ index = simple_strtoul(cp, &temp, 10); while ((temp < linefeed) && (*temp == ' ' || *temp == '\t')) diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c index 869f40ebf1a7..b6a65b0c1896 100644 --- a/drivers/staging/speakup/main.c +++ b/drivers/staging/speakup/main.c @@ -901,7 +901,8 @@ static int get_sentence_buf(struct vc_data *vc, int read_punc) while (start < end) { sentbuf[bn][i] = get_char(vc, (u_short *)start, &tmp); if (i > 0) { - if (sentbuf[bn][i] == SPACE && sentbuf[bn][i - 1] == '.' && + if (sentbuf[bn][i] == SPACE && + sentbuf[bn][i - 1] == '.' && numsentences[bn] < 9) { /* Sentence Marker */ numsentences[bn]++; @@ -1235,7 +1236,8 @@ int spk_set_key_info(const u_char *key_info, u_char *k_buffer) key_data_len = (states + 1) * (num_keys + 1); if (key_data_len + SHIFT_TBL_SIZE + 4 >= sizeof(spk_key_buf)) { pr_debug("too many key_infos (%d over %u)\n", - key_data_len + SHIFT_TBL_SIZE + 4, (unsigned int)(sizeof(spk_key_buf))); + key_data_len + SHIFT_TBL_SIZE + 4, + (unsigned int)(sizeof(spk_key_buf))); return -EINVAL; } memset(k_buffer, 0, SHIFT_TBL_SIZE); @@ -1249,8 +1251,8 @@ int spk_set_key_info(const u_char *key_info, u_char *k_buffer) for (i = 1; i <= states; i++) { ch = *cp1++; if (ch >= SHIFT_TBL_SIZE) { - pr_debug("(%d) not valid shift state (max_allowed = %d)\n", ch, - SHIFT_TBL_SIZE); + pr_debug("(%d) not valid shift state (max_allowed = %d)\n", + ch, SHIFT_TBL_SIZE); return -EINVAL; } spk_shift_table[ch] = i; @@ -1258,7 +1260,8 @@ int spk_set_key_info(const u_char *key_info, u_char *k_buffer) keymap_flags = *cp1++; while ((ch = *cp1)) { if (ch >= MAX_KEY) { - pr_debug("(%d), not valid key, (max_allowed = %d)\n", ch, MAX_KEY); + pr_debug("(%d), not valid key, (max_allowed = %d)\n", + ch, MAX_KEY); return -EINVAL; } spk_our_keys[ch] = cp1; @@ -1979,6 +1982,7 @@ oops: return 1; } + /* Do not replace with kstrtoul: here we need cp to be updated */ goto_pos = simple_strtoul(goto_buf, &cp, 10); if (*cp == 'x') { diff --git a/drivers/staging/speakup/speakup_decext.c b/drivers/staging/speakup/speakup_decext.c index 3741c0fcf5bb..ddbb7e97d118 100644 --- a/drivers/staging/speakup/speakup_decext.c +++ b/drivers/staging/speakup/speakup_decext.c @@ -192,7 +192,8 @@ static void do_catch_up(struct spk_synth *synth) synth->io_ops->synth_out(synth, PROCSPEECH); if (time_after_eq(jiffies, jiff_max)) { if (!in_escape) - synth->io_ops->synth_out(synth, PROCSPEECH); + synth->io_ops->synth_out(synth, + PROCSPEECH); spin_lock_irqsave(&speakup_info.spinlock, flags); jiffy_delta_val = jiffy_delta->u.n.value; diff --git a/drivers/staging/speakup/speakup_dectlk.c b/drivers/staging/speakup/speakup_dectlk.c index a144f28ee1a8..dccb4ea29d37 100644 --- a/drivers/staging/speakup/speakup_dectlk.c +++ b/drivers/staging/speakup/speakup_dectlk.c @@ -260,7 +260,8 @@ static void do_catch_up(struct spk_synth *synth) synth->io_ops->synth_out(synth, PROCSPEECH); if (time_after_eq(jiffies, jiff_max)) { if (!in_escape) - synth->io_ops->synth_out(synth, PROCSPEECH); + synth->io_ops->synth_out(synth, + PROCSPEECH); spin_lock_irqsave(&speakup_info.spinlock, flags); jiffy_delta_val = jiffy_delta->u.n.value; diff --git a/drivers/staging/speakup/speakup_soft.c b/drivers/staging/speakup/speakup_soft.c index 947c79532e10..edff6ce85655 100644 --- a/drivers/staging/speakup/speakup_soft.c +++ b/drivers/staging/speakup/speakup_soft.c @@ -12,7 +12,9 @@ #include <linux/unistd.h> #include <linux/miscdevice.h> /* for misc_register, and SYNTH_MINOR */ #include <linux/poll.h> /* for poll_wait() */ -#include <linux/sched/signal.h> /* schedule(), signal_pending(), TASK_INTERRUPTIBLE */ + +/* schedule(), signal_pending(), TASK_INTERRUPTIBLE */ +#include <linux/sched/signal.h> #include "spk_priv.h" #include "speakup.h" diff --git a/drivers/staging/speakup/spk_priv_keyinfo.h b/drivers/staging/speakup/spk_priv_keyinfo.h index cc99fcd1bc6e..1f789bd1c678 100644 --- a/drivers/staging/speakup/spk_priv_keyinfo.h +++ b/drivers/staging/speakup/spk_priv_keyinfo.h @@ -61,11 +61,16 @@ #define SPEAKUP_HELP 0x2d #define TOGGLE_CURSORING 0x2e #define READ_ALL_DOC 0x2f -#define SPKUP_MAX_FUNC 0x30 /* one greater than the last func handler */ + +/* one greater than the last func handler */ +#define SPKUP_MAX_FUNC 0x30 + #define SPK_KEY 0x80 #define FIRST_EDIT_BITS 0x22 #define FIRST_SET_VAR SPELL_DELAY -#define VAR_START 0x40 /* increase if adding more than 0x3f functions */ + +/* increase if adding more than 0x3f functions */ +#define VAR_START 0x40 /* keys for setting variables, must be ordered same as the enum for var_ids */ /* with dec being even and inc being 1 greater */ diff --git a/drivers/staging/speakup/spk_ttyio.c b/drivers/staging/speakup/spk_ttyio.c index 005de0024dd4..0057eb980bec 100644 --- a/drivers/staging/speakup/spk_ttyio.c +++ b/drivers/staging/speakup/spk_ttyio.c @@ -128,7 +128,8 @@ struct spk_io_ops spk_ttyio_ops = { }; EXPORT_SYMBOL_GPL(spk_ttyio_ops); -static inline void get_termios(struct tty_struct *tty, struct ktermios *out_termios) +static inline void get_termios(struct tty_struct *tty, + struct ktermios *out_termios) { down_read(&tty->termios_rwsem); *out_termios = tty->termios; @@ -167,8 +168,9 @@ static int spk_ttyio_initialise_ldisc(struct spk_synth *synth) tmp_termios.c_cflag |= CRTSCTS; tty_set_termios(tty, &tmp_termios); /* - * check c_cflag to see if it's updated as tty_set_termios may not return - * error even when no tty bits are changed by the request. + * check c_cflag to see if it's updated as tty_set_termios + * may not return error even when no tty bits are + * changed by the request. */ get_termios(tty, &tmp_termios); if (!(tmp_termios.c_cflag & CRTSCTS)) @@ -207,10 +209,11 @@ static int spk_ttyio_out(struct spk_synth *in_synth, const char ch) /* No room */ return 0; if (ret < 0) { - pr_warn("%s: I/O error, deactivating speakup\n", in_synth->long_name); - /* No synth any more, so nobody will restart TTYs, and we thus - * need to do it ourselves. Now that there is no synth we can - * let application flood anyway + pr_warn("%s: I/O error, deactivating speakup\n", + in_synth->long_name); + /* No synth any more, so nobody will restart TTYs, + * and we thus need to do it ourselves. Now that there + * is no synth we can let application flood anyway */ in_synth->alive = 0; speakup_start_ttys(); @@ -371,7 +374,8 @@ const char *spk_ttyio_synth_immediate(struct spk_synth *synth, const char *buff) while ((ch = *buff)) { if (ch == '\n') ch = synth->procspeech; - if (tty_write_room(speakup_tty) < 1 || !synth->io_ops->synth_out(synth, ch)) + if (tty_write_room(speakup_tty) < 1 || + !synth->io_ops->synth_out(synth, ch)) return buff; buff++; } diff --git a/drivers/staging/speakup/varhandlers.c b/drivers/staging/speakup/varhandlers.c index 1b545152cc49..5741d1cb6227 100644 --- a/drivers/staging/speakup/varhandlers.c +++ b/drivers/staging/speakup/varhandlers.c @@ -238,7 +238,8 @@ int spk_set_num_var(int input, struct st_var_header *var, int how) if (!var_data->u.n.out_str) sprintf(cp, var_data->u.n.synth_fmt, (int)val); else - sprintf(cp, var_data->u.n.synth_fmt, var_data->u.n.out_str[val]); + sprintf(cp, var_data->u.n.synth_fmt, + var_data->u.n.out_str[val]); synth_printf("%s", cp); return 0; } @@ -328,6 +329,7 @@ char *spk_s2uchar(char *start, char *dest) { int val; + /* Do not replace with kstrtoul: here we need start to be updated */ val = simple_strtoul(skip_spaces(start), &start, 10); if (*start == ',') start++; diff --git a/drivers/staging/unisys/visorhba/Makefile b/drivers/staging/unisys/visorhba/Makefile index a8a8e0e0fb09..97e48757944a 100644 --- a/drivers/staging/unisys/visorhba/Makefile +++ b/drivers/staging/unisys/visorhba/Makefile @@ -6,5 +6,4 @@ obj-$(CONFIG_UNISYS_VISORHBA) += visorhba.o visorhba-y := visorhba_main.o -ccflags-y += -Idrivers/staging/unisys/include - +ccflags-y += -I $(srctree)/$(src)/../include diff --git a/drivers/staging/unisys/visornic/Makefile b/drivers/staging/unisys/visornic/Makefile index 439e95e03300..336a746f793b 100644 --- a/drivers/staging/unisys/visornic/Makefile +++ b/drivers/staging/unisys/visornic/Makefile @@ -6,5 +6,4 @@ obj-$(CONFIG_UNISYS_VISORNIC) += visornic.o visornic-y := visornic_main.o -ccflags-y += -Idrivers/staging/unisys/include - +ccflags-y += -I $(srctree)/$(src)/../include diff --git a/drivers/staging/unisys/visornic/visornic_main.c b/drivers/staging/unisys/visornic/visornic_main.c index 5eeb4b93b45b..1c1a470d2e50 100644 --- a/drivers/staging/unisys/visornic/visornic_main.c +++ b/drivers/staging/unisys/visornic/visornic_main.c @@ -896,9 +896,7 @@ static netdev_tx_t visornic_xmit(struct sk_buff *skb, struct net_device *netdev) ((skb_end_pointer(skb) - skb->data) >= ETH_MIN_PACKET_SIZE)) { /* pad the packet out to minimum size */ padlen = ETH_MIN_PACKET_SIZE - len; - memset(&skb->data[len], 0, padlen); - skb->tail += padlen; - skb->len += padlen; + skb_put_zero(skb, padlen); len += padlen; firstfraglen += padlen; } diff --git a/drivers/staging/vc04_services/bcm2835-audio/Makefile b/drivers/staging/vc04_services/bcm2835-audio/Makefile index d7b88d164d15..536bd0c11ddb 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/Makefile +++ b/drivers/staging/vc04_services/bcm2835-audio/Makefile @@ -1,5 +1,4 @@ obj-$(CONFIG_SND_BCM2835) += snd-bcm2835.o snd-bcm2835-objs := bcm2835.o bcm2835-ctl.o bcm2835-pcm.o bcm2835-vchiq.o -ccflags-y += -Idrivers/staging/vc04_services -D__VCCOREVER__=0x04000000 - +ccflags-y += -I $(srctree)/$(src)/.. -D__VCCOREVER__=0x04000000 diff --git a/drivers/staging/vc04_services/bcm2835-camera/Makefile b/drivers/staging/vc04_services/bcm2835-camera/Makefile index 2a4565e682d8..472f21e1f2a1 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/Makefile +++ b/drivers/staging/vc04_services/bcm2835-camera/Makefile @@ -7,5 +7,5 @@ bcm2835-v4l2-$(CONFIG_VIDEO_BCM2835) := \ obj-$(CONFIG_VIDEO_BCM2835) += bcm2835-v4l2.o ccflags-y += \ - -Idrivers/staging/vc04_services \ + -I $(srctree)/$(src)/.. \ -D__VCCOREVER__=0x04000000 diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index b5ba0c76fb43..b4cdc0b7fee7 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -1704,13 +1704,9 @@ static const unsigned short awcFrameTime[MAX_RATE] = { * Return Value: FrameTime * */ -unsigned int -BBuGetFrameTime( - unsigned char byPreambleType, - unsigned char byPktType, - unsigned int cbFrameLength, - unsigned short wRate -) +unsigned int BBuGetFrameTime(unsigned char byPreambleType, + unsigned char byPktType, + unsigned int cbFrameLength, unsigned short wRate) { unsigned int uFrameTime; unsigned int uPreamble; diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h index 30d9e9d20a39..0cc2e07829c5 100644 --- a/drivers/staging/vt6655/baseband.h +++ b/drivers/staging/vt6655/baseband.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index 52e9e6b90b56..6ecbe925026d 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -60,14 +60,9 @@ static const unsigned short cwRXBCNTSFOff[MAX_RATE] = { /*--------------------- Static Functions --------------------------*/ -static -void -s_vCalculateOFDMRParameter( - unsigned char byRate, - u8 bb_type, - unsigned char *pbyTxRate, - unsigned char *pbyRsvTime -); +static void s_vCalculateOFDMRParameter(unsigned char byRate, u8 bb_type, + unsigned char *pbyTxRate, + unsigned char *pbyRsvTime); /*--------------------- Export Functions --------------------------*/ @@ -506,10 +501,7 @@ bool CARDbRadioPowerOn(struct vnt_private *priv) return bResult; } -void -CARDvSafeResetTx( - struct vnt_private *priv -) +void CARDvSafeResetTx(struct vnt_private *priv) { unsigned int uu; struct vnt_tx_desc *pCurrTD; diff --git a/drivers/staging/vt6655/card.h b/drivers/staging/vt6655/card.h index 5884fd56153e..d71022aa3f86 100644 --- a/drivers/staging/vt6655/card.h +++ b/drivers/staging/vt6655/card.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index c9097e7367d8..b370985b58a1 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -805,12 +805,12 @@ static bool device_alloc_rx_buf(struct vnt_private *priv, } static void device_free_rx_buf(struct vnt_private *priv, - struct vnt_rx_desc *rd) + struct vnt_rx_desc *rd) { struct vnt_rd_info *rd_info = rd->rd_info; dma_unmap_single(&priv->pcid->dev, rd_info->skb_dma, - priv->rx_buf_sz, DMA_FROM_DEVICE); + priv->rx_buf_sz, DMA_FROM_DEVICE); dev_kfree_skb(rd_info->skb); } diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c index 91dede54cc1f..dcd933a6b66e 100644 --- a/drivers/staging/vt6656/key.c +++ b/drivers/staging/vt6656/key.c @@ -63,17 +63,19 @@ static int vnt_set_keymode(struct ieee80211_hw *hw, u8 *mac_addr, } switch (key_type) { - /* fallthrough */ case VNT_KEY_DEFAULTKEY: /* default key last entry */ entry = MAX_KEY_TABLE - 1; key->hw_key_idx = entry; + /* fall through */ case VNT_KEY_ALLGROUP: key_mode |= VNT_KEY_ALLGROUP; if (onfly_latch) key_mode |= VNT_KEY_ONFLY_ALL; + /* fall through */ case VNT_KEY_GROUP_ADDRESS: key_mode |= mode; + /* fall through */ case VNT_KEY_GROUP: key_mode |= (mode << 4); key_mode |= VNT_KEY_GROUP; diff --git a/drivers/staging/vt6656/mac.h b/drivers/staging/vt6656/mac.h index 94e700fcd0b6..3fd87f95c524 100644 --- a/drivers/staging/vt6656/mac.h +++ b/drivers/staging/vt6656/mac.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. diff --git a/drivers/staging/wilc1000/Makefile b/drivers/staging/wilc1000/Makefile index 72a4daa05fdb..2ad3feed9725 100644 --- a/drivers/staging/wilc1000/Makefile +++ b/drivers/staging/wilc1000/Makefile @@ -4,7 +4,7 @@ obj-$(CONFIG_WILC1000) += wilc1000.o ccflags-y += -DFIRMWARE_1002=\"atmel/wilc1002_firmware.bin\" \ -DFIRMWARE_1003=\"atmel/wilc1003_firmware.bin\" -wilc1000-objs := wilc_wfi_cfgoperations.o linux_wlan.o linux_mon.o \ +wilc1000-objs := wilc_wfi_cfgoperations.o wilc_netdev.o wilc_mon.o \ host_interface.o wilc_wlan_cfg.o wilc_wlan.o obj-$(CONFIG_WILC1000_SDIO) += wilc1000-sdio.o diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 3d0badc34825..4dd9a20f6a0b 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -6,25 +6,23 @@ #include "wilc_wfi_netdevice.h" -#define HOST_IF_SCAN_TIMEOUT 4000 -#define HOST_IF_CONNECT_TIMEOUT 9500 +#define WILC_HIF_SCAN_TIMEOUT_MS 4000 +#define WILC_HIF_CONNECT_TIMEOUT_MS 9500 -#define FALSE_FRMWR_CHANNEL 100 +#define WILC_FALSE_FRMWR_CHANNEL 100 +#define WILC_MAX_RATES_SUPPORTED 12 -#define REAL_JOIN_REQ 0 - -struct rcvd_async_info { - u8 *buffer; - u32 len; +struct wilc_rcvd_mac_info { + u8 status; }; -struct set_multicast { - bool enabled; +struct wilc_set_multicast { + u32 enabled; u32 cnt; u8 *mc_list; }; -struct del_all_sta { +struct wilc_del_all_sta { u8 assoc_sta; u8 mac[WILC_MAX_NUM_STA][ETH_ALEN]; }; @@ -71,16 +69,16 @@ struct wilc_gtk_key { u8 key[0]; } __packed; -union message_body { - struct rcvd_net_info net_info; - struct rcvd_async_info async_info; - struct set_multicast multicast_info; - struct remain_ch remain_on_ch; +union wilc_message_body { + struct wilc_rcvd_net_info net_info; + struct wilc_rcvd_mac_info mac_info; + struct wilc_set_multicast mc_info; + struct wilc_remain_ch remain_on_ch; char *data; }; struct host_if_msg { - union message_body body; + union wilc_message_body body; struct wilc_vif *vif; struct work_struct work; void (*fn)(struct work_struct *ws); @@ -88,37 +86,50 @@ struct host_if_msg { bool is_sync; }; -struct join_bss_param { - enum bss_types bss_type; +struct wilc_noa_opp_enable { + u8 ct_window; + u8 cnt; + __le32 duration; + __le32 interval; + __le32 start_time; +} __packed; + +struct wilc_noa_opp_disable { + u8 cnt; + __le32 duration; + __le32 interval; + __le32 start_time; +} __packed; + +struct wilc_join_bss_param { + char ssid[IEEE80211_MAX_SSID_LEN]; + u8 ssid_terminator; + u8 bss_type; + u8 ch; + __le16 cap_info; + u8 sa[ETH_ALEN]; + u8 bssid[ETH_ALEN]; + __le16 beacon_period; u8 dtim_period; - u16 beacon_period; - u16 cap_info; - u8 bssid[6]; - char ssid[MAX_SSID_LEN]; - u8 ssid_len; - u8 supp_rates[MAX_RATES_SUPPORTED + 1]; - u8 ht_capable; + u8 supp_rates[WILC_MAX_RATES_SUPPORTED + 1]; u8 wmm_cap; u8 uapsd_cap; - bool rsn_found; + u8 ht_capable; + u8 rsn_found; u8 rsn_grp_policy; u8 mode_802_11i; - u8 rsn_pcip_policy[3]; - u8 rsn_auth_policy[3]; + u8 p_suites[3]; + u8 akm_suites[3]; u8 rsn_cap[2]; - u32 tsf; u8 noa_enabled; - u8 opp_enabled; - u8 ct_window; - u8 cnt; + __le32 tsf_lo; u8 idx; - u8 duration[4]; - u8 interval[4]; - u8 start_time[4]; -}; - -static struct host_if_drv *terminated_handle; -static struct mutex hif_deinit_lock; + u8 opp_enabled; + union { + struct wilc_noa_opp_disable opp_dis; + struct wilc_noa_opp_enable opp_en; + }; +} __packed; /* 'msg' should be free by the caller for syc */ static struct host_if_msg* @@ -185,7 +196,7 @@ static int handle_scan_done(struct wilc_vif *vif, enum scan_event evt) u8 abort_running_scan; struct wid wid; struct host_if_drv *hif_drv = vif->hif_drv; - struct user_scan_req *scan_req; + struct wilc_user_scan_req *scan_req; if (evt == SCAN_EVENT_ABORTED) { abort_running_scan = 1; @@ -210,7 +221,7 @@ static int handle_scan_done(struct wilc_vif *vif, enum scan_event evt) scan_req = &hif_drv->usr_scan_req; if (scan_req->scan_result) { - scan_req->scan_result(evt, NULL, scan_req->arg, NULL); + scan_req->scan_result(evt, NULL, scan_req->arg); scan_req->scan_result = NULL; } @@ -218,9 +229,10 @@ static int handle_scan_done(struct wilc_vif *vif, enum scan_event evt) } int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type, - u8 *ch_freq_list, u8 ch_list_len, const u8 *ies, - size_t ies_len, wilc_scan_result scan_result, void *user_arg, - struct hidden_network *hidden_net) + u8 *ch_freq_list, u8 ch_list_len, const u8 *ies, size_t ies_len, + void (*scan_result_fn)(enum scan_event, + struct wilc_rcvd_net_info *, void *), + void *user_arg, struct wilc_probe_ssid *search) { int result = 0; struct wid wid_list[5]; @@ -228,7 +240,7 @@ int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type, u32 i; u8 *buffer; u8 valuesize = 0; - u8 *hdn_ntwk_wid_val = NULL; + u8 *search_ssid_vals = NULL; struct host_if_drv *hif_drv = vif->hif_drv; if (hif_drv->hif_state >= HOST_IF_SCANNING && @@ -246,26 +258,24 @@ int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type, hif_drv->usr_scan_req.ch_cnt = 0; - if (hidden_net) { - wid_list[index].id = WID_SSID_PROBE_REQ; - wid_list[index].type = WID_STR; - - for (i = 0; i < hidden_net->n_ssids; i++) - valuesize += ((hidden_net->net_info[i].ssid_len) + 1); - hdn_ntwk_wid_val = kmalloc(valuesize + 1, GFP_KERNEL); - wid_list[index].val = hdn_ntwk_wid_val; - if (wid_list[index].val) { + if (search) { + for (i = 0; i < search->n_ssids; i++) + valuesize += ((search->ssid_info[i].ssid_len) + 1); + search_ssid_vals = kmalloc(valuesize + 1, GFP_KERNEL); + if (search_ssid_vals) { + wid_list[index].id = WID_SSID_PROBE_REQ; + wid_list[index].type = WID_STR; + wid_list[index].val = search_ssid_vals; buffer = wid_list[index].val; - *buffer++ = hidden_net->n_ssids; + *buffer++ = search->n_ssids; - for (i = 0; i < hidden_net->n_ssids; i++) { - *buffer++ = hidden_net->net_info[i].ssid_len; - memcpy(buffer, hidden_net->net_info[i].ssid, - hidden_net->net_info[i].ssid_len); - buffer += hidden_net->net_info[i].ssid_len; + for (i = 0; i < search->n_ssids; i++) { + *buffer++ = search->ssid_info[i].ssid_len; + memcpy(buffer, search->ssid_info[i].ssid, + search->ssid_info[i].ssid_len); + buffer += search->ssid_info[i].ssid_len; } - wid_list[index].size = (s32)(valuesize + 1); index++; } @@ -311,16 +321,16 @@ int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type, goto error; } - hif_drv->usr_scan_req.scan_result = scan_result; + hif_drv->usr_scan_req.scan_result = scan_result_fn; hif_drv->usr_scan_req.arg = user_arg; hif_drv->scan_timer_vif = vif; mod_timer(&hif_drv->scan_timer, - jiffies + msecs_to_jiffies(HOST_IF_SCAN_TIMEOUT)); + jiffies + msecs_to_jiffies(WILC_HIF_SCAN_TIMEOUT_MS)); error: - if (hidden_net) { - kfree(hidden_net->net_info); - kfree(hdn_ntwk_wid_val); + if (search) { + kfree(search->ssid_info); + kfree(search_ssid_vals); } return result; @@ -329,35 +339,16 @@ error: static int wilc_send_connect_wid(struct wilc_vif *vif) { int result = 0; - struct wid wid_list[8]; - u32 wid_cnt = 0, dummyval = 0; - u8 *cur_byte = NULL; + struct wid wid_list[4]; + u32 wid_cnt = 0; struct host_if_drv *hif_drv = vif->hif_drv; - struct user_conn_req *conn_attr = &hif_drv->usr_conn_req; - struct join_bss_param *bss_param = hif_drv->usr_conn_req.param; - - wid_list[wid_cnt].id = WID_SUCCESS_FRAME_COUNT; - wid_list[wid_cnt].type = WID_INT; - wid_list[wid_cnt].size = sizeof(u32); - wid_list[wid_cnt].val = (s8 *)(&(dummyval)); - wid_cnt++; - - wid_list[wid_cnt].id = WID_RECEIVED_FRAGMENT_COUNT; - wid_list[wid_cnt].type = WID_INT; - wid_list[wid_cnt].size = sizeof(u32); - wid_list[wid_cnt].val = (s8 *)(&(dummyval)); - wid_cnt++; - - wid_list[wid_cnt].id = WID_FAILED_COUNT; - wid_list[wid_cnt].type = WID_INT; - wid_list[wid_cnt].size = sizeof(u32); - wid_list[wid_cnt].val = (s8 *)(&(dummyval)); - wid_cnt++; + struct wilc_conn_info *conn_attr = &hif_drv->conn_info; + struct wilc_join_bss_param *bss_param = conn_attr->param; wid_list[wid_cnt].id = WID_INFO_ELEMENT_ASSOCIATE; wid_list[wid_cnt].type = WID_BIN_DATA; - wid_list[wid_cnt].val = conn_attr->ies; - wid_list[wid_cnt].size = conn_attr->ies_len; + wid_list[wid_cnt].val = conn_attr->req_ies; + wid_list[wid_cnt].size = conn_attr->req_ies_len; wid_cnt++; wid_list[wid_cnt].id = WID_11I_MODE; @@ -374,97 +365,8 @@ static int wilc_send_connect_wid(struct wilc_vif *vif) wid_list[wid_cnt].id = WID_JOIN_REQ_EXTENDED; wid_list[wid_cnt].type = WID_STR; - wid_list[wid_cnt].size = 112; - wid_list[wid_cnt].val = kmalloc(wid_list[wid_cnt].size, GFP_KERNEL); - - if (!wid_list[wid_cnt].val) { - result = -EFAULT; - goto error; - } - - cur_byte = wid_list[wid_cnt].val; - - if (conn_attr->ssid) { - memcpy(cur_byte, conn_attr->ssid, conn_attr->ssid_len); - cur_byte[conn_attr->ssid_len] = '\0'; - } - cur_byte += MAX_SSID_LEN; - *(cur_byte++) = WILC_FW_BSS_TYPE_INFRA; - - if (conn_attr->ch >= 1 && conn_attr->ch <= 14) { - *(cur_byte++) = conn_attr->ch; - } else { - netdev_err(vif->ndev, "Channel out of range\n"); - *(cur_byte++) = 0xFF; - } - put_unaligned_le16(bss_param->cap_info, cur_byte); - cur_byte += 2; - - if (conn_attr->bssid) - memcpy(cur_byte, conn_attr->bssid, 6); - cur_byte += 6; - - if (conn_attr->bssid) - memcpy(cur_byte, conn_attr->bssid, 6); - cur_byte += 6; - - put_unaligned_le16(bss_param->beacon_period, cur_byte); - cur_byte += 2; - *(cur_byte++) = bss_param->dtim_period; - - memcpy(cur_byte, bss_param->supp_rates, MAX_RATES_SUPPORTED + 1); - cur_byte += (MAX_RATES_SUPPORTED + 1); - - *(cur_byte++) = bss_param->wmm_cap; - *(cur_byte++) = bss_param->uapsd_cap; - - *(cur_byte++) = bss_param->ht_capable; - conn_attr->ht_capable = bss_param->ht_capable; - - *(cur_byte++) = bss_param->rsn_found; - *(cur_byte++) = bss_param->rsn_grp_policy; - *(cur_byte++) = bss_param->mode_802_11i; - - memcpy(cur_byte, bss_param->rsn_pcip_policy, - sizeof(bss_param->rsn_pcip_policy)); - cur_byte += sizeof(bss_param->rsn_pcip_policy); - - memcpy(cur_byte, bss_param->rsn_auth_policy, - sizeof(bss_param->rsn_auth_policy)); - cur_byte += sizeof(bss_param->rsn_auth_policy); - - memcpy(cur_byte, bss_param->rsn_cap, sizeof(bss_param->rsn_cap)); - cur_byte += sizeof(bss_param->rsn_cap); - - *(cur_byte++) = REAL_JOIN_REQ; - *(cur_byte++) = bss_param->noa_enabled; - - if (bss_param->noa_enabled) { - put_unaligned_le32(bss_param->tsf, cur_byte); - cur_byte += 4; - - *(cur_byte++) = bss_param->opp_enabled; - *(cur_byte++) = bss_param->idx; - - if (bss_param->opp_enabled) - *(cur_byte++) = bss_param->ct_window; - - *(cur_byte++) = bss_param->cnt; - - memcpy(cur_byte, bss_param->duration, - sizeof(bss_param->duration)); - cur_byte += sizeof(bss_param->duration); - - memcpy(cur_byte, bss_param->interval, - sizeof(bss_param->interval)); - cur_byte += sizeof(bss_param->interval); - - memcpy(cur_byte, bss_param->start_time, - sizeof(bss_param->start_time)); - cur_byte += sizeof(bss_param->start_time); - } - - cur_byte = wid_list[wid_cnt].val; + wid_list[wid_cnt].size = sizeof(*bss_param); + wid_list[wid_cnt].val = (u8 *)bss_param; wid_cnt++; result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list, @@ -472,25 +374,17 @@ static int wilc_send_connect_wid(struct wilc_vif *vif) wilc_get_vif_idx(vif)); if (result) { netdev_err(vif->ndev, "failed to send config packet\n"); - kfree(cur_byte); goto error; } else { hif_drv->hif_state = HOST_IF_WAITING_CONN_RESP; } - kfree(cur_byte); return 0; error: - kfree(conn_attr->bssid); - conn_attr->bssid = NULL; - - kfree(conn_attr->ssid); - conn_attr->ssid = NULL; - - kfree(conn_attr->ies); - conn_attr->ies = NULL; + kfree(conn_attr->req_ies); + conn_attr->req_ies = NULL; return result; } @@ -500,7 +394,6 @@ static void handle_connect_timeout(struct work_struct *work) struct host_if_msg *msg = container_of(work, struct host_if_msg, work); struct wilc_vif *vif = msg->vif; int result; - struct connect_info info; struct wid wid; u16 dummy_reason_code = 0; struct host_if_drv *hif_drv = vif->hif_drv; @@ -512,31 +405,11 @@ static void handle_connect_timeout(struct work_struct *work) hif_drv->hif_state = HOST_IF_IDLE; - memset(&info, 0, sizeof(struct connect_info)); + if (hif_drv->conn_info.conn_result) { + hif_drv->conn_info.conn_result(CONN_DISCONN_EVENT_CONN_RESP, + WILC_MAC_STATUS_DISCONNECTED, + hif_drv->conn_info.arg); - if (hif_drv->usr_conn_req.conn_result) { - if (hif_drv->usr_conn_req.bssid) { - memcpy(info.bssid, - hif_drv->usr_conn_req.bssid, 6); - } - - if (hif_drv->usr_conn_req.ies) { - info.req_ies_len = hif_drv->usr_conn_req.ies_len; - info.req_ies = kmemdup(hif_drv->usr_conn_req.ies, - hif_drv->usr_conn_req.ies_len, - GFP_KERNEL); - if (!info.req_ies) - goto out; - } - - hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_CONN_RESP, - &info, - WILC_MAC_STATUS_DISCONNECTED, - NULL, - hif_drv->usr_conn_req.arg); - - kfree(info.req_ies); - info.req_ies = NULL; } else { netdev_err(vif->ndev, "%s: conn_result is NULL\n", __func__); } @@ -551,346 +424,174 @@ static void handle_connect_timeout(struct work_struct *work) if (result) netdev_err(vif->ndev, "Failed to send disconnect\n"); - hif_drv->usr_conn_req.ssid_len = 0; - kfree(hif_drv->usr_conn_req.ssid); - hif_drv->usr_conn_req.ssid = NULL; - kfree(hif_drv->usr_conn_req.bssid); - hif_drv->usr_conn_req.bssid = NULL; - hif_drv->usr_conn_req.ies_len = 0; - kfree(hif_drv->usr_conn_req.ies); - hif_drv->usr_conn_req.ies = NULL; + hif_drv->conn_info.req_ies_len = 0; + kfree(hif_drv->conn_info.req_ies); + hif_drv->conn_info.req_ies = NULL; out: kfree(msg); } -static void host_int_fill_join_bss_param(struct join_bss_param *param, u8 *ies, - u16 *out_index, u8 *pcipher_tc, - u8 *auth_total_cnt, u32 tsf_lo, - u8 *rates_no) +void *wilc_parse_join_bss_param(struct cfg80211_bss *bss, + struct cfg80211_crypto_settings *crypto) { - u8 ext_rates_no; - u16 offset; - u8 pcipher_cnt; - u8 auth_cnt; - u8 i, j; - u16 index = *out_index; - - if (ies[index] == WLAN_EID_SUPP_RATES) { - *rates_no = ies[index + 1]; - param->supp_rates[0] = *rates_no; - index += 2; - - for (i = 0; i < *rates_no; i++) - param->supp_rates[i + 1] = ies[index + i]; - - index += *rates_no; - } else if (ies[index] == WLAN_EID_EXT_SUPP_RATES) { - ext_rates_no = ies[index + 1]; - if (ext_rates_no > (MAX_RATES_SUPPORTED - *rates_no)) - param->supp_rates[0] = MAX_RATES_SUPPORTED; - else - param->supp_rates[0] += ext_rates_no; - index += 2; - for (i = 0; i < (param->supp_rates[0] - *rates_no); i++) - param->supp_rates[*rates_no + i + 1] = ies[index + i]; - - index += ext_rates_no; - } else if (ies[index] == WLAN_EID_HT_CAPABILITY) { - param->ht_capable = true; - index += ies[index + 1] + 2; - } else if ((ies[index] == WLAN_EID_VENDOR_SPECIFIC) && - (ies[index + 2] == 0x00) && (ies[index + 3] == 0x50) && - (ies[index + 4] == 0xF2) && (ies[index + 5] == 0x02) && - ((ies[index + 6] == 0x00) || (ies[index + 6] == 0x01)) && - (ies[index + 7] == 0x01)) { - param->wmm_cap = true; - - if (ies[index + 8] & BIT(7)) - param->uapsd_cap = true; - index += ies[index + 1] + 2; - } else if ((ies[index] == WLAN_EID_VENDOR_SPECIFIC) && - (ies[index + 2] == 0x50) && (ies[index + 3] == 0x6f) && - (ies[index + 4] == 0x9a) && - (ies[index + 5] == 0x09) && (ies[index + 6] == 0x0c)) { - u16 p2p_cnt; - - param->tsf = tsf_lo; - param->noa_enabled = 1; - param->idx = ies[index + 9]; - - if (ies[index + 10] & BIT(7)) { - param->opp_enabled = 1; - param->ct_window = ies[index + 10]; - } else { - param->opp_enabled = 0; - } - - param->cnt = ies[index + 11]; - p2p_cnt = index + 12; - - memcpy(param->duration, ies + p2p_cnt, 4); - p2p_cnt += 4; - - memcpy(param->interval, ies + p2p_cnt, 4); - p2p_cnt += 4; - - memcpy(param->start_time, ies + p2p_cnt, 4); - - index += ies[index + 1] + 2; - } else if ((ies[index] == WLAN_EID_RSN) || - ((ies[index] == WLAN_EID_VENDOR_SPECIFIC) && - (ies[index + 2] == 0x00) && - (ies[index + 3] == 0x50) && (ies[index + 4] == 0xF2) && - (ies[index + 5] == 0x01))) { - u16 rsn_idx = index; - - if (ies[rsn_idx] == WLAN_EID_RSN) { - param->mode_802_11i = 2; - } else { - if (param->mode_802_11i == 0) - param->mode_802_11i = 1; - rsn_idx += 4; - } - - rsn_idx += 7; - param->rsn_grp_policy = ies[rsn_idx]; - rsn_idx++; - offset = ies[rsn_idx] * 4; - pcipher_cnt = (ies[rsn_idx] > 3) ? 3 : ies[rsn_idx]; - rsn_idx += 2; - - i = *pcipher_tc; - j = 0; - for (; i < (pcipher_cnt + *pcipher_tc) && i < 3; i++, j++) { - u8 *policy = ¶m->rsn_pcip_policy[i]; - - *policy = ies[rsn_idx + ((j + 1) * 4) - 1]; - } - - *pcipher_tc += pcipher_cnt; - rsn_idx += offset; - - offset = ies[rsn_idx] * 4; - - auth_cnt = (ies[rsn_idx] > 3) ? 3 : ies[rsn_idx]; - rsn_idx += 2; - i = *auth_total_cnt; - j = 0; - for (; i < (*auth_total_cnt + auth_cnt); i++, j++) { - u8 *policy = ¶m->rsn_auth_policy[i]; - - *policy = ies[rsn_idx + ((j + 1) * 4) - 1]; - } - - *auth_total_cnt += auth_cnt; - rsn_idx += offset; - - if (ies[index] == WLAN_EID_RSN) { - param->rsn_cap[0] = ies[rsn_idx]; - param->rsn_cap[1] = ies[rsn_idx + 1]; - rsn_idx += 2; - } - param->rsn_found = true; - index += ies[index + 1] + 2; - } else { - index += ies[index + 1] + 2; - } - - *out_index = index; -} - -static void *host_int_parse_join_bss_param(struct network_info *info) -{ - struct join_bss_param *param; - u16 index = 0; - u8 rates_no = 0; - u8 pcipher_total_cnt = 0; - u8 auth_total_cnt = 0; + struct wilc_join_bss_param *param; + struct ieee80211_p2p_noa_attr noa_attr; + u8 rates_len = 0; + const u8 *tim_elm, *ssid_elm, *rates_ie, *supp_rates_ie; + const u8 *ht_ie, *wpa_ie, *wmm_ie, *rsn_ie; + int ret; + const struct cfg80211_bss_ies *ies = rcu_dereference(bss->ies); param = kzalloc(sizeof(*param), GFP_KERNEL); if (!param) return NULL; - param->dtim_period = info->dtim_period; - param->beacon_period = info->beacon_period; - param->cap_info = info->cap_info; - memcpy(param->bssid, info->bssid, 6); - memcpy((u8 *)param->ssid, info->ssid, info->ssid_len + 1); - param->ssid_len = info->ssid_len; - memset(param->rsn_pcip_policy, 0xFF, 3); - memset(param->rsn_auth_policy, 0xFF, 3); - - while (index < info->ies_len) - host_int_fill_join_bss_param(param, info->ies, &index, - &pcipher_total_cnt, - &auth_total_cnt, info->tsf_lo, - &rates_no); - - return (void *)param; -} - -static inline u8 *get_bssid(struct ieee80211_mgmt *mgmt) -{ - if (ieee80211_has_fromds(mgmt->frame_control)) - return mgmt->sa; - else if (ieee80211_has_tods(mgmt->frame_control)) - return mgmt->da; - else - return mgmt->bssid; -} + param->beacon_period = cpu_to_le16(bss->beacon_interval); + param->cap_info = cpu_to_le16(bss->capability); + param->bss_type = WILC_FW_BSS_TYPE_INFRA; + param->ch = ieee80211_frequency_to_channel(bss->channel->center_freq); + ether_addr_copy(param->bssid, bss->bssid); -static s32 wilc_parse_network_info(u8 *msg_buffer, - struct network_info **ret_network_info) -{ - struct network_info *info; - struct ieee80211_mgmt *mgt; - u8 *wid_val, *msa, *ies; - u16 wid_len, rx_len, ies_len; - u8 msg_type; - size_t offset; - const u8 *ch_elm, *tim_elm, *ssid_elm; - - msg_type = msg_buffer[0]; - if ('N' != msg_type) - return -EFAULT; + ssid_elm = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len); + if (ssid_elm) { + if (ssid_elm[1] <= IEEE80211_MAX_SSID_LEN) + memcpy(param->ssid, ssid_elm + 2, ssid_elm[1]); + } - wid_len = get_unaligned_le16(&msg_buffer[6]); - wid_val = &msg_buffer[8]; + tim_elm = cfg80211_find_ie(WLAN_EID_TIM, ies->data, ies->len); + if (tim_elm && tim_elm[1] >= 2) + param->dtim_period = tim_elm[3]; - info = kzalloc(sizeof(*info), GFP_KERNEL); - if (!info) - return -ENOMEM; + memset(param->p_suites, 0xFF, 3); + memset(param->akm_suites, 0xFF, 3); - info->rssi = wid_val[0]; + rates_ie = cfg80211_find_ie(WLAN_EID_SUPP_RATES, ies->data, ies->len); + if (rates_ie) { + rates_len = rates_ie[1]; + param->supp_rates[0] = rates_len; + memcpy(¶m->supp_rates[1], rates_ie + 2, rates_len); + } - msa = &wid_val[1]; - mgt = (struct ieee80211_mgmt *)&wid_val[1]; - rx_len = wid_len - 1; + supp_rates_ie = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, ies->data, + ies->len); + if (supp_rates_ie) { + if (supp_rates_ie[1] > (WILC_MAX_RATES_SUPPORTED - rates_len)) + param->supp_rates[0] = WILC_MAX_RATES_SUPPORTED; + else + param->supp_rates[0] += supp_rates_ie[1]; - if (ieee80211_is_probe_resp(mgt->frame_control)) { - info->cap_info = le16_to_cpu(mgt->u.probe_resp.capab_info); - info->beacon_period = le16_to_cpu(mgt->u.probe_resp.beacon_int); - info->tsf = le64_to_cpu(mgt->u.probe_resp.timestamp); - info->tsf_lo = (u32)info->tsf; - offset = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); - } else if (ieee80211_is_beacon(mgt->frame_control)) { - info->cap_info = le16_to_cpu(mgt->u.beacon.capab_info); - info->beacon_period = le16_to_cpu(mgt->u.beacon.beacon_int); - info->tsf = le64_to_cpu(mgt->u.beacon.timestamp); - info->tsf_lo = (u32)info->tsf; - offset = offsetof(struct ieee80211_mgmt, u.beacon.variable); - } else { - /* only process probe response and beacon frame */ - kfree(info); - return -EIO; + memcpy(¶m->supp_rates[rates_len + 1], supp_rates_ie + 2, + (param->supp_rates[0] - rates_len)); } - ether_addr_copy(info->bssid, get_bssid(mgt)); + ht_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ies->data, ies->len); + if (ht_ie) + param->ht_capable = true; - ies = mgt->u.beacon.variable; - ies_len = rx_len - offset; - if (ies_len <= 0) { - kfree(info); - return -EIO; + ret = cfg80211_get_p2p_attr(ies->data, ies->len, + IEEE80211_P2P_ATTR_ABSENCE_NOTICE, + (u8 *)&noa_attr, sizeof(noa_attr)); + if (ret > 0) { + param->tsf_lo = cpu_to_le32(ies->tsf); + param->noa_enabled = 1; + param->idx = noa_attr.index; + if (noa_attr.oppps_ctwindow & IEEE80211_P2P_OPPPS_ENABLE_BIT) { + param->opp_enabled = 1; + param->opp_en.ct_window = noa_attr.oppps_ctwindow; + param->opp_en.cnt = noa_attr.desc[0].count; + param->opp_en.duration = noa_attr.desc[0].duration; + param->opp_en.interval = noa_attr.desc[0].interval; + param->opp_en.start_time = noa_attr.desc[0].start_time; + } else { + param->opp_enabled = 0; + param->opp_dis.cnt = noa_attr.desc[0].count; + param->opp_dis.duration = noa_attr.desc[0].duration; + param->opp_dis.interval = noa_attr.desc[0].interval; + param->opp_dis.start_time = noa_attr.desc[0].start_time; + } + } + wmm_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, + WLAN_OUI_TYPE_MICROSOFT_WMM, + ies->data, ies->len); + if (wmm_ie) { + struct ieee80211_wmm_param_ie *ie; + + ie = (struct ieee80211_wmm_param_ie *)wmm_ie; + if ((ie->oui_subtype == 0 || ie->oui_subtype == 1) && + ie->version == 1) { + param->wmm_cap = true; + if (ie->qos_info & BIT(7)) + param->uapsd_cap = true; + } } - info->ies = kmemdup(ies, ies_len, GFP_KERNEL); - if (!info->ies) { - kfree(info); - return -ENOMEM; + wpa_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, + WLAN_OUI_TYPE_MICROSOFT_WPA, + ies->data, ies->len); + if (wpa_ie) { + param->mode_802_11i = 1; + param->rsn_found = true; } - info->ies_len = ies_len; + rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, ies->data, ies->len); + if (rsn_ie) { + int offset = 8; - ssid_elm = cfg80211_find_ie(WLAN_EID_SSID, ies, ies_len); - if (ssid_elm) { - info->ssid_len = ssid_elm[1]; - if (info->ssid_len <= IEEE80211_MAX_SSID_LEN) - memcpy(info->ssid, ssid_elm + 2, info->ssid_len); - else - info->ssid_len = 0; + param->mode_802_11i = 2; + param->rsn_found = true; + //extract RSN capabilities + offset += (rsn_ie[offset] * 4) + 2; + offset += (rsn_ie[offset] * 4) + 2; + memcpy(param->rsn_cap, &rsn_ie[offset], 2); } - ch_elm = cfg80211_find_ie(WLAN_EID_DS_PARAMS, ies, ies_len); - if (ch_elm && ch_elm[1] > 0) - info->ch = ch_elm[2]; + if (param->rsn_found) { + int i; - tim_elm = cfg80211_find_ie(WLAN_EID_TIM, ies, ies_len); - if (tim_elm && tim_elm[1] >= 2) - info->dtim_period = tim_elm[3]; + param->rsn_grp_policy = crypto->cipher_group & 0xFF; + for (i = 0; i < crypto->n_ciphers_pairwise && i < 3; i++) + param->p_suites[i] = crypto->ciphers_pairwise[i] & 0xFF; - *ret_network_info = info; + for (i = 0; i < crypto->n_akm_suites && i < 3; i++) + param->akm_suites[i] = crypto->akm_suites[i] & 0xFF; + } - return 0; + return (void *)param; } static void handle_rcvd_ntwrk_info(struct work_struct *work) { struct host_if_msg *msg = container_of(work, struct host_if_msg, work); - struct wilc_vif *vif = msg->vif; - struct rcvd_net_info *rcvd_info = &msg->body.net_info; - u32 i; - bool found; - struct network_info *info = NULL; - void *params; - struct host_if_drv *hif_drv = vif->hif_drv; - struct user_scan_req *scan_req = &hif_drv->usr_scan_req; - - found = true; + struct wilc_rcvd_net_info *rcvd_info = &msg->body.net_info; + struct wilc_user_scan_req *scan_req = &msg->vif->hif_drv->usr_scan_req; + const u8 *ch_elm; + u8 *ies; + int ies_len; + size_t offset; - if (!scan_req->scan_result) + if (ieee80211_is_probe_resp(rcvd_info->mgmt->frame_control)) + offset = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); + else if (ieee80211_is_beacon(rcvd_info->mgmt->frame_control)) + offset = offsetof(struct ieee80211_mgmt, u.beacon.variable); + else goto done; - wilc_parse_network_info(rcvd_info->buffer, &info); - if (!info || !scan_req->scan_result) { - netdev_err(vif->ndev, "%s: info or scan result NULL\n", - __func__); + ies = rcvd_info->mgmt->u.beacon.variable; + ies_len = rcvd_info->frame_len - offset; + if (ies_len <= 0) goto done; - } - - for (i = 0; i < scan_req->ch_cnt; i++) { - if (memcmp(scan_req->net_info[i].bssid, info->bssid, 6) == 0) { - if (info->rssi <= scan_req->net_info[i].rssi) { - goto done; - } else { - scan_req->net_info[i].rssi = info->rssi; - found = false; - break; - } - } - } - - if (found) { - if (scan_req->ch_cnt < MAX_NUM_SCANNED_NETWORKS) { - scan_req->net_info[scan_req->ch_cnt].rssi = info->rssi; - - memcpy(scan_req->net_info[scan_req->ch_cnt].bssid, - info->bssid, 6); - - scan_req->ch_cnt++; - info->new_network = true; - params = host_int_parse_join_bss_param(info); + ch_elm = cfg80211_find_ie(WLAN_EID_DS_PARAMS, ies, ies_len); + if (ch_elm && ch_elm[1] > 0) + rcvd_info->ch = ch_elm[2]; - scan_req->scan_result(SCAN_EVENT_NETWORK_FOUND, info, - scan_req->arg, params); - } - } else { - info->new_network = false; - scan_req->scan_result(SCAN_EVENT_NETWORK_FOUND, info, - scan_req->arg, NULL); - } + if (scan_req->scan_result) + scan_req->scan_result(SCAN_EVENT_NETWORK_FOUND, rcvd_info, + scan_req->arg); done: - kfree(rcvd_info->buffer); - rcvd_info->buffer = NULL; - - if (info) { - kfree(info->ies); - kfree(info); - } - + kfree(rcvd_info->mgmt); kfree(msg); } @@ -918,20 +619,8 @@ static void host_int_get_assoc_res_info(struct wilc_vif *vif, *rcvd_assoc_resp_info_len = wid.size; } -static inline void host_int_free_user_conn_req(struct host_if_drv *hif_drv) -{ - hif_drv->usr_conn_req.ssid_len = 0; - kfree(hif_drv->usr_conn_req.ssid); - hif_drv->usr_conn_req.ssid = NULL; - kfree(hif_drv->usr_conn_req.bssid); - hif_drv->usr_conn_req.bssid = NULL; - hif_drv->usr_conn_req.ies_len = 0; - kfree(hif_drv->usr_conn_req.ies); - hif_drv->usr_conn_req.ies = NULL; -} - static s32 wilc_parse_assoc_resp_info(u8 *buffer, u32 buffer_len, - struct connect_info *ret_conn_info) + struct wilc_conn_info *ret_conn_info) { u8 *ies; u16 ies_len; @@ -955,10 +644,8 @@ static s32 wilc_parse_assoc_resp_info(u8 *buffer, u32 buffer_len, static inline void host_int_parse_assoc_resp_info(struct wilc_vif *vif, u8 mac_status) { - struct connect_info conn_info; struct host_if_drv *hif_drv = vif->hif_drv; - - memset(&conn_info, 0, sizeof(struct connect_info)); + struct wilc_conn_info *conn_info = &hif_drv->conn_info; if (mac_status == WILC_MAC_STATUS_CONNECTED) { u32 assoc_resp_info_len; @@ -974,7 +661,7 @@ static inline void host_int_parse_assoc_resp_info(struct wilc_vif *vif, err = wilc_parse_assoc_resp_info(hif_drv->assoc_resp, assoc_resp_info_len, - &conn_info); + conn_info); if (err) netdev_err(vif->ndev, "wilc_parse_assoc_resp_info() returned error %d\n", @@ -982,31 +669,13 @@ static inline void host_int_parse_assoc_resp_info(struct wilc_vif *vif, } } - if (hif_drv->usr_conn_req.bssid) { - memcpy(conn_info.bssid, hif_drv->usr_conn_req.bssid, 6); - - if (mac_status == WILC_MAC_STATUS_CONNECTED && - conn_info.status == WLAN_STATUS_SUCCESS) { - memcpy(hif_drv->assoc_bssid, - hif_drv->usr_conn_req.bssid, ETH_ALEN); - } - } - - if (hif_drv->usr_conn_req.ies) { - conn_info.req_ies = kmemdup(hif_drv->usr_conn_req.ies, - hif_drv->usr_conn_req.ies_len, - GFP_KERNEL); - if (conn_info.req_ies) - conn_info.req_ies_len = hif_drv->usr_conn_req.ies_len; - } - del_timer(&hif_drv->connect_timer); - hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_CONN_RESP, - &conn_info, mac_status, NULL, - hif_drv->usr_conn_req.arg); + conn_info->conn_result(CONN_DISCONN_EVENT_CONN_RESP, mac_status, + hif_drv->conn_info.arg); if (mac_status == WILC_MAC_STATUS_CONNECTED && - conn_info.status == WLAN_STATUS_SUCCESS) { + conn_info->status == WLAN_STATUS_SUCCESS) { + ether_addr_copy(hif_drv->assoc_bssid, conn_info->bssid); wilc_set_power_mgmt(vif, 0, 0); hif_drv->hif_state = HOST_IF_CONNECTED; @@ -1018,44 +687,39 @@ static inline void host_int_parse_assoc_resp_info(struct wilc_vif *vif, hif_drv->hif_state = HOST_IF_IDLE; } - kfree(conn_info.resp_ies); - conn_info.resp_ies = NULL; + kfree(conn_info->resp_ies); + conn_info->resp_ies = NULL; + conn_info->resp_ies_len = 0; - kfree(conn_info.req_ies); - conn_info.req_ies = NULL; - host_int_free_user_conn_req(hif_drv); + kfree(conn_info->req_ies); + conn_info->req_ies = NULL; + conn_info->req_ies_len = 0; } static inline void host_int_handle_disconnect(struct wilc_vif *vif) { - struct disconnect_info disconn_info; struct host_if_drv *hif_drv = vif->hif_drv; - wilc_connect_result conn_result = hif_drv->usr_conn_req.conn_result; - - memset(&disconn_info, 0, sizeof(struct disconnect_info)); if (hif_drv->usr_scan_req.scan_result) { del_timer(&hif_drv->scan_timer); handle_scan_done(vif, SCAN_EVENT_ABORTED); } - disconn_info.reason = 0; - disconn_info.ie = NULL; - disconn_info.ie_len = 0; - - if (conn_result) { + if (hif_drv->conn_info.conn_result) { vif->obtaining_ip = false; wilc_set_power_mgmt(vif, 0, 0); - conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF, NULL, 0, - &disconn_info, hif_drv->usr_conn_req.arg); + hif_drv->conn_info.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF, + 0, hif_drv->conn_info.arg); } else { netdev_err(vif->ndev, "%s: conn_result is NULL\n", __func__); } eth_zero_addr(hif_drv->assoc_bssid); - host_int_free_user_conn_req(hif_drv); + hif_drv->conn_info.req_ies_len = 0; + kfree(hif_drv->conn_info.req_ies); + hif_drv->conn_info.req_ies = NULL; hif_drv->hif_state = HOST_IF_IDLE; } @@ -1063,55 +727,30 @@ static void handle_rcvd_gnrl_async_info(struct work_struct *work) { struct host_if_msg *msg = container_of(work, struct host_if_msg, work); struct wilc_vif *vif = msg->vif; - struct rcvd_async_info *rcvd_info = &msg->body.async_info; - u8 msg_type; - u8 mac_status; + struct wilc_rcvd_mac_info *mac_info = &msg->body.mac_info; struct host_if_drv *hif_drv = vif->hif_drv; - if (!rcvd_info->buffer) { - netdev_err(vif->ndev, "%s: buffer is NULL\n", __func__); - goto free_msg; - } - if (!hif_drv) { netdev_err(vif->ndev, "%s: hif driver is NULL\n", __func__); - goto free_rcvd_info; + goto free_msg; } - if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP || - hif_drv->hif_state == HOST_IF_CONNECTED || - hif_drv->usr_scan_req.scan_result) { - if (!hif_drv->usr_conn_req.conn_result) { - netdev_err(vif->ndev, "%s: conn_result is NULL\n", - __func__); - goto free_rcvd_info; - } - - msg_type = rcvd_info->buffer[0]; - - if ('I' != msg_type) { - netdev_err(vif->ndev, "Received Message incorrect.\n"); - goto free_rcvd_info; - } + if (!hif_drv->conn_info.conn_result) { + netdev_err(vif->ndev, "%s: conn_result is NULL\n", __func__); + goto free_msg; + } - mac_status = rcvd_info->buffer[7]; - if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) { - host_int_parse_assoc_resp_info(vif, mac_status); - } else if ((mac_status == WILC_MAC_STATUS_DISCONNECTED) && - (hif_drv->hif_state == HOST_IF_CONNECTED)) { + if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) { + host_int_parse_assoc_resp_info(vif, mac_info->status); + } else if (mac_info->status == WILC_MAC_STATUS_DISCONNECTED) { + if (hif_drv->hif_state == HOST_IF_CONNECTED) { host_int_handle_disconnect(vif); - } else if ((mac_status == WILC_MAC_STATUS_DISCONNECTED) && - (hif_drv->usr_scan_req.scan_result)) { + } else if (hif_drv->usr_scan_req.scan_result) { del_timer(&hif_drv->scan_timer); - if (hif_drv->usr_scan_req.scan_result) - handle_scan_done(vif, SCAN_EVENT_ABORTED); + handle_scan_done(vif, SCAN_EVENT_ABORTED); } } -free_rcvd_info: - kfree(rcvd_info->buffer); - rcvd_info->buffer = NULL; - free_msg: kfree(msg); } @@ -1120,9 +759,8 @@ int wilc_disconnect(struct wilc_vif *vif) { struct wid wid; struct host_if_drv *hif_drv = vif->hif_drv; - struct disconnect_info disconn_info; - struct user_scan_req *scan_req; - struct user_conn_req *conn_req; + struct wilc_user_scan_req *scan_req; + struct wilc_conn_info *conn_info; int result; u16 dummy_reason_code = 0; @@ -1141,27 +779,21 @@ int wilc_disconnect(struct wilc_vif *vif) return result; } - memset(&disconn_info, 0, sizeof(struct disconnect_info)); - - disconn_info.reason = 0; - disconn_info.ie = NULL; - disconn_info.ie_len = 0; scan_req = &hif_drv->usr_scan_req; - conn_req = &hif_drv->usr_conn_req; + conn_info = &hif_drv->conn_info; if (scan_req->scan_result) { del_timer(&hif_drv->scan_timer); - scan_req->scan_result(SCAN_EVENT_ABORTED, NULL, scan_req->arg, - NULL); + scan_req->scan_result(SCAN_EVENT_ABORTED, NULL, scan_req->arg); scan_req->scan_result = NULL; } - if (conn_req->conn_result) { + if (conn_info->conn_result) { if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) del_timer(&hif_drv->connect_timer); - conn_req->conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF, NULL, - 0, &disconn_info, conn_req->arg); + conn_info->conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF, 0, + conn_info->arg); } else { netdev_err(vif->ndev, "%s: conn_result is NULL\n", __func__); } @@ -1170,14 +802,9 @@ int wilc_disconnect(struct wilc_vif *vif) eth_zero_addr(hif_drv->assoc_bssid); - conn_req->ssid_len = 0; - kfree(conn_req->ssid); - conn_req->ssid = NULL; - kfree(conn_req->bssid); - conn_req->bssid = NULL; - conn_req->ies_len = 0; - kfree(conn_req->ies); - conn_req->ies = NULL; + conn_info->req_ies_len = 0; + kfree(conn_info->req_ies); + conn_info->req_ies = NULL; return 0; } @@ -1285,47 +912,29 @@ static void wilc_hif_pack_sta_param(u8 *cur_byte, const u8 *mac, } static int handle_remain_on_chan(struct wilc_vif *vif, - struct remain_ch *hif_remain_ch) + struct wilc_remain_ch *hif_remain_ch) { int result; u8 remain_on_chan_flag; struct wid wid; struct host_if_drv *hif_drv = vif->hif_drv; - if (!hif_drv->remain_on_ch_pending) { - hif_drv->remain_on_ch.arg = hif_remain_ch->arg; - hif_drv->remain_on_ch.expired = hif_remain_ch->expired; - hif_drv->remain_on_ch.ready = hif_remain_ch->ready; - hif_drv->remain_on_ch.ch = hif_remain_ch->ch; - hif_drv->remain_on_ch.id = hif_remain_ch->id; - } else { - hif_remain_ch->ch = hif_drv->remain_on_ch.ch; - } + if (hif_drv->usr_scan_req.scan_result) + return -EBUSY; - if (hif_drv->usr_scan_req.scan_result) { - hif_drv->remain_on_ch_pending = 1; - result = -EBUSY; - goto error; - } - if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) { - result = -EBUSY; - goto error; - } + if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) + return -EBUSY; - if (vif->obtaining_ip || vif->connecting) { - result = -EBUSY; - goto error; - } + if (vif->obtaining_ip || vif->connecting) + return -EBUSY; remain_on_chan_flag = true; wid.id = WID_REMAIN_ON_CHAN; wid.type = WID_STR; wid.size = 2; wid.val = kmalloc(wid.size, GFP_KERNEL); - if (!wid.val) { - result = -ENOMEM; - goto error; - } + if (!wid.val) + return -ENOMEM; wid.val[0] = remain_on_chan_flag; wid.val[1] = (s8)hif_remain_ch->ch; @@ -1333,28 +942,23 @@ static int handle_remain_on_chan(struct wilc_vif *vif, result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); kfree(wid.val); - if (result != 0) - netdev_err(vif->ndev, "Failed to set remain on channel\n"); + if (result) + return -EBUSY; -error: + hif_drv->remain_on_ch.arg = hif_remain_ch->arg; + hif_drv->remain_on_ch.expired = hif_remain_ch->expired; + hif_drv->remain_on_ch.ch = hif_remain_ch->ch; + hif_drv->remain_on_ch.cookie = hif_remain_ch->cookie; hif_drv->remain_on_ch_timer_vif = vif; - mod_timer(&hif_drv->remain_on_ch_timer, - jiffies + msecs_to_jiffies(hif_remain_ch->duration)); - - if (hif_drv->remain_on_ch.ready) - hif_drv->remain_on_ch.ready(hif_drv->remain_on_ch.arg); - - if (hif_drv->remain_on_ch_pending) - hif_drv->remain_on_ch_pending = 0; - return result; + return 0; } static void handle_listen_state_expired(struct work_struct *work) { struct host_if_msg *msg = container_of(work, struct host_if_msg, work); struct wilc_vif *vif = msg->vif; - struct remain_ch *hif_remain_ch = &msg->body.remain_on_ch; + struct wilc_remain_ch *hif_remain_ch = &msg->body.remain_on_ch; u8 remain_on_chan_flag; struct wid wid; int result; @@ -1372,7 +976,7 @@ static void handle_listen_state_expired(struct work_struct *work) goto free_msg; wid.val[0] = remain_on_chan_flag; - wid.val[1] = FALSE_FRMWR_CHANNEL; + wid.val[1] = WILC_FALSE_FRMWR_CHANNEL; result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); @@ -1384,7 +988,7 @@ static void handle_listen_state_expired(struct work_struct *work) if (hif_drv->remain_on_ch.expired) { hif_drv->remain_on_ch.expired(hif_drv->remain_on_ch.arg, - hif_remain_ch->id); + hif_remain_ch->cookie); } } else { netdev_dbg(vif->ndev, "Not in listen state\n"); @@ -1408,7 +1012,7 @@ static void listen_timer_cb(struct timer_list *t) if (IS_ERR(msg)) return; - msg->body.remain_on_ch.id = vif->hif_drv->remain_on_ch.id; + msg->body.remain_on_ch.cookie = vif->hif_drv->remain_on_ch.cookie; result = wilc_enqueue_work(msg); if (result) { @@ -1421,32 +1025,27 @@ static void handle_set_mcast_filter(struct work_struct *work) { struct host_if_msg *msg = container_of(work, struct host_if_msg, work); struct wilc_vif *vif = msg->vif; - struct set_multicast *hif_set_mc = &msg->body.multicast_info; + struct wilc_set_multicast *set_mc = &msg->body.mc_info; int result; struct wid wid; u8 *cur_byte; wid.id = WID_SETUP_MULTICAST_FILTER; wid.type = WID_BIN; - wid.size = sizeof(struct set_multicast) + (hif_set_mc->cnt * ETH_ALEN); + wid.size = sizeof(struct wilc_set_multicast) + (set_mc->cnt * ETH_ALEN); wid.val = kmalloc(wid.size, GFP_KERNEL); if (!wid.val) goto error; cur_byte = wid.val; - *cur_byte++ = (hif_set_mc->enabled & 0xFF); - *cur_byte++ = 0; - *cur_byte++ = 0; - *cur_byte++ = 0; + put_unaligned_le32(set_mc->enabled, cur_byte); + cur_byte += 4; - *cur_byte++ = (hif_set_mc->cnt & 0xFF); - *cur_byte++ = ((hif_set_mc->cnt >> 8) & 0xFF); - *cur_byte++ = ((hif_set_mc->cnt >> 16) & 0xFF); - *cur_byte++ = ((hif_set_mc->cnt >> 24) & 0xFF); + put_unaligned_le32(set_mc->cnt, cur_byte); + cur_byte += 4; - if (hif_set_mc->cnt > 0 && hif_set_mc->mc_list) - memcpy(cur_byte, hif_set_mc->mc_list, - ((hif_set_mc->cnt) * ETH_ALEN)); + if (set_mc->cnt > 0 && set_mc->mc_list) + memcpy(cur_byte, set_mc->mc_list, set_mc->cnt * ETH_ALEN); result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); @@ -1454,7 +1053,7 @@ static void handle_set_mcast_filter(struct work_struct *work) netdev_err(vif->ndev, "Failed to send setup multicast\n"); error: - kfree(hif_set_mc->mc_list); + kfree(set_mc->mc_list); kfree(wid.val); kfree(msg); } @@ -1479,9 +1078,6 @@ static void handle_scan_complete(struct work_struct *work) handle_scan_done(msg->vif, SCAN_EVENT_DONE); - if (msg->vif->hif_drv->remain_on_ch_pending) - handle_remain_on_chan(msg->vif, - &msg->vif->hif_drv->remain_on_ch); kfree(msg); } @@ -1629,7 +1225,7 @@ int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len, u8 mode, u8 cipher_mode, u8 index) { int result = 0; - u8 t_key_len = ptk_key_len + RX_MIC_KEY_LEN + TX_MIC_KEY_LEN; + u8 t_key_len = ptk_key_len + WILC_RX_MIC_KEY_LEN + WILC_TX_MIC_KEY_LEN; if (mode == WILC_AP_MODE) { struct wid wid_list[2]; @@ -1651,11 +1247,11 @@ int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len, if (rx_mic) memcpy(&key_buf->key[ptk_key_len], rx_mic, - RX_MIC_KEY_LEN); + WILC_RX_MIC_KEY_LEN); if (tx_mic) - memcpy(&key_buf->key[ptk_key_len + RX_MIC_KEY_LEN], - tx_mic, TX_MIC_KEY_LEN); + memcpy(&key_buf->key[ptk_key_len + WILC_RX_MIC_KEY_LEN], + tx_mic, WILC_TX_MIC_KEY_LEN); wid_list[1].id = WID_ADD_PTK; wid_list[1].type = WID_STR; @@ -1679,11 +1275,11 @@ int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len, if (rx_mic) memcpy(&key_buf->key[ptk_key_len], rx_mic, - RX_MIC_KEY_LEN); + WILC_RX_MIC_KEY_LEN); if (tx_mic) - memcpy(&key_buf->key[ptk_key_len + RX_MIC_KEY_LEN], - tx_mic, TX_MIC_KEY_LEN); + memcpy(&key_buf->key[ptk_key_len + WILC_RX_MIC_KEY_LEN], + tx_mic, WILC_TX_MIC_KEY_LEN); wid.id = WID_ADD_PTK; wid.type = WID_STR; @@ -1704,7 +1300,7 @@ int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len, { int result = 0; struct wilc_gtk_key *gtk_key; - int t_key_len = gtk_key_len + RX_MIC_KEY_LEN + TX_MIC_KEY_LEN; + int t_key_len = gtk_key_len + WILC_RX_MIC_KEY_LEN + WILC_TX_MIC_KEY_LEN; gtk_key = kzalloc(sizeof(*gtk_key) + t_key_len, GFP_KERNEL); if (!gtk_key) @@ -1722,11 +1318,11 @@ int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len, memcpy(>k_key->key[0], rx_gtk, gtk_key_len); if (rx_mic) - memcpy(>k_key->key[gtk_key_len], rx_mic, RX_MIC_KEY_LEN); + memcpy(>k_key->key[gtk_key_len], rx_mic, WILC_RX_MIC_KEY_LEN); if (tx_mic) - memcpy(>k_key->key[gtk_key_len + RX_MIC_KEY_LEN], - tx_mic, TX_MIC_KEY_LEN); + memcpy(>k_key->key[gtk_key_len + WILC_RX_MIC_KEY_LEN], + tx_mic, WILC_TX_MIC_KEY_LEN); if (mode == WILC_AP_MODE) { struct wid wid_list[2]; @@ -1793,61 +1389,22 @@ int wilc_get_mac_address(struct wilc_vif *vif, u8 *mac_addr) return result; } -int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, const u8 *ssid, - size_t ssid_len, const u8 *ies, size_t ies_len, - wilc_connect_result connect_result, void *user_arg, - u8 security, enum authtype auth_type, - u8 channel, void *join_params) +int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, const u8 *ies, + size_t ies_len) { int result; struct host_if_drv *hif_drv = vif->hif_drv; - struct user_conn_req *con_info = &hif_drv->usr_conn_req; + struct wilc_conn_info *conn_info = &hif_drv->conn_info; - if (!hif_drv || !connect_result) { - netdev_err(vif->ndev, - "%s: hif driver or connect result is NULL", - __func__); - return -EFAULT; - } - - if (!join_params) { - netdev_err(vif->ndev, "%s: joinparams is NULL\n", __func__); - return -EFAULT; - } - - if (hif_drv->usr_scan_req.scan_result) { - netdev_err(vif->ndev, "%s: Scan in progress\n", __func__); - return -EBUSY; - } - - con_info->security = security; - con_info->auth_type = auth_type; - con_info->ch = channel; - con_info->conn_result = connect_result; - con_info->arg = user_arg; - con_info->param = join_params; - - if (bssid) { - con_info->bssid = kmemdup(bssid, 6, GFP_KERNEL); - if (!con_info->bssid) - return -ENOMEM; - } - - if (ssid) { - con_info->ssid_len = ssid_len; - con_info->ssid = kmemdup(ssid, ssid_len, GFP_KERNEL); - if (!con_info->ssid) { - result = -ENOMEM; - goto free_bssid; - } - } + if (bssid) + ether_addr_copy(conn_info->bssid, bssid); if (ies) { - con_info->ies_len = ies_len; - con_info->ies = kmemdup(ies, ies_len, GFP_KERNEL); - if (!con_info->ies) { + conn_info->req_ies_len = ies_len; + conn_info->req_ies = kmemdup(ies, ies_len, GFP_KERNEL); + if (!conn_info->req_ies) { result = -ENOMEM; - goto free_ssid; + return result; } } @@ -1857,18 +1414,12 @@ int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, const u8 *ssid, hif_drv->connect_timer_vif = vif; mod_timer(&hif_drv->connect_timer, - jiffies + msecs_to_jiffies(HOST_IF_CONNECT_TIMEOUT)); + jiffies + msecs_to_jiffies(WILC_HIF_CONNECT_TIMEOUT_MS)); return 0; free_ies: - kfree(con_info->ies); - -free_ssid: - kfree(con_info->ssid); - -free_bssid: - kfree(con_info->bssid); + kfree(conn_info->req_ies); return result; } @@ -1899,6 +1450,9 @@ int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode, int result; struct wilc_drv_handler drv; + if (!hif_drv) + return -EFAULT; + wid.id = WID_SET_DRV_HANDLER; wid.type = WID_STR; wid.size = sizeof(drv); @@ -1991,7 +1545,7 @@ int wilc_get_rssi(struct wilc_vif *vif, s8 *rssi_level) return result; } -int wilc_get_stats_async(struct wilc_vif *vif, struct rf_info *stats) +static int wilc_get_stats_async(struct wilc_vif *vif, struct rf_info *stats) { int result; struct host_if_msg *msg; @@ -2090,7 +1644,7 @@ int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) vif->obtaining_ip = false; if (wilc->clients_count == 0) - mutex_init(&hif_deinit_lock); + mutex_init(&wilc->deinit_lock); timer_setup(&vif->periodic_rssi, get_periodic_rssi, 0); mod_timer(&vif->periodic_rssi, jiffies + msecs_to_jiffies(5000)); @@ -2118,9 +1672,7 @@ int wilc_deinit(struct wilc_vif *vif) return -EFAULT; } - mutex_lock(&hif_deinit_lock); - - terminated_handle = hif_drv; + mutex_lock(&vif->wilc->deinit_lock); del_timer_sync(&hif_drv->scan_timer); del_timer_sync(&hif_drv->connect_timer); @@ -2131,18 +1683,16 @@ int wilc_deinit(struct wilc_vif *vif) if (hif_drv->usr_scan_req.scan_result) { hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED, NULL, - hif_drv->usr_scan_req.arg, - NULL); + hif_drv->usr_scan_req.arg); hif_drv->usr_scan_req.scan_result = NULL; } hif_drv->hif_state = HOST_IF_IDLE; kfree(hif_drv); - + vif->hif_drv = NULL; vif->wilc->clients_count--; - terminated_handle = NULL; - mutex_unlock(&hif_deinit_lock); + mutex_unlock(&vif->wilc->deinit_lock); return result; } @@ -2154,16 +1704,13 @@ void wilc_network_info_received(struct wilc *wilc, u8 *buffer, u32 length) struct host_if_drv *hif_drv; struct wilc_vif *vif; - id = buffer[length - 4]; - id |= (buffer[length - 3] << 8); - id |= (buffer[length - 2] << 16); - id |= (buffer[length - 1] << 24); + id = get_unaligned_le32(&buffer[length - 4]); vif = wilc_get_vif_from_idx(wilc, id); if (!vif) return; hif_drv = vif->hif_drv; - if (!hif_drv || hif_drv == terminated_handle) { + if (!hif_drv) { netdev_err(vif->ndev, "driver not init[%p]\n", hif_drv); return; } @@ -2172,9 +1719,12 @@ void wilc_network_info_received(struct wilc *wilc, u8 *buffer, u32 length) if (IS_ERR(msg)) return; - msg->body.net_info.len = length; - msg->body.net_info.buffer = kmemdup(buffer, length, GFP_KERNEL); - if (!msg->body.net_info.buffer) { + msg->body.net_info.frame_len = get_unaligned_le16(&buffer[6]) - 1; + msg->body.net_info.rssi = buffer[8]; + msg->body.net_info.mgmt = kmemdup(&buffer[9], + msg->body.net_info.frame_len, + GFP_KERNEL); + if (!msg->body.net_info.mgmt) { kfree(msg); return; } @@ -2182,7 +1732,7 @@ void wilc_network_info_received(struct wilc *wilc, u8 *buffer, u32 length) result = wilc_enqueue_work(msg); if (result) { netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__); - kfree(msg->body.net_info.buffer); + kfree(msg->body.net_info.mgmt); kfree(msg); } } @@ -2195,53 +1745,42 @@ void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *buffer, u32 length) struct host_if_drv *hif_drv; struct wilc_vif *vif; - mutex_lock(&hif_deinit_lock); + mutex_lock(&wilc->deinit_lock); - id = buffer[length - 4]; - id |= (buffer[length - 3] << 8); - id |= (buffer[length - 2] << 16); - id |= (buffer[length - 1] << 24); + id = get_unaligned_le32(&buffer[length - 4]); vif = wilc_get_vif_from_idx(wilc, id); if (!vif) { - mutex_unlock(&hif_deinit_lock); + mutex_unlock(&wilc->deinit_lock); return; } hif_drv = vif->hif_drv; - if (!hif_drv || hif_drv == terminated_handle) { - mutex_unlock(&hif_deinit_lock); + if (!hif_drv) { + mutex_unlock(&wilc->deinit_lock); return; } - if (!hif_drv->usr_conn_req.conn_result) { + if (!hif_drv->conn_info.conn_result) { netdev_err(vif->ndev, "%s: conn_result is NULL\n", __func__); - mutex_unlock(&hif_deinit_lock); + mutex_unlock(&wilc->deinit_lock); return; } msg = wilc_alloc_work(vif, handle_rcvd_gnrl_async_info, false); if (IS_ERR(msg)) { - mutex_unlock(&hif_deinit_lock); - return; - } - - msg->body.async_info.len = length; - msg->body.async_info.buffer = kmemdup(buffer, length, GFP_KERNEL); - if (!msg->body.async_info.buffer) { - kfree(msg); - mutex_unlock(&hif_deinit_lock); + mutex_unlock(&wilc->deinit_lock); return; } + msg->body.mac_info.status = buffer[7]; result = wilc_enqueue_work(msg); if (result) { netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__); - kfree(msg->body.async_info.buffer); kfree(msg); } - mutex_unlock(&hif_deinit_lock); + mutex_unlock(&wilc->deinit_lock); } void wilc_scan_complete_received(struct wilc *wilc, u8 *buffer, u32 length) @@ -2251,16 +1790,13 @@ void wilc_scan_complete_received(struct wilc *wilc, u8 *buffer, u32 length) struct host_if_drv *hif_drv; struct wilc_vif *vif; - id = buffer[length - 4]; - id |= buffer[length - 3] << 8; - id |= buffer[length - 2] << 16; - id |= buffer[length - 1] << 24; + id = get_unaligned_le32(&buffer[length - 4]); vif = wilc_get_vif_from_idx(wilc, id); if (!vif) return; hif_drv = vif->hif_drv; - if (!hif_drv || hif_drv == terminated_handle) + if (!hif_drv) return; if (hif_drv->usr_scan_req.scan_result) { @@ -2279,21 +1815,19 @@ void wilc_scan_complete_received(struct wilc *wilc, u8 *buffer, u32 length) } } -int wilc_remain_on_channel(struct wilc_vif *vif, u32 session_id, +int wilc_remain_on_channel(struct wilc_vif *vif, u64 cookie, u32 duration, u16 chan, - wilc_remain_on_chan_expired expired, - wilc_remain_on_chan_ready ready, + void (*expired)(void *, u64), void *user_arg) { - struct remain_ch roc; + struct wilc_remain_ch roc; int result; roc.ch = chan; roc.expired = expired; - roc.ready = ready; roc.arg = user_arg; roc.duration = duration; - roc.id = session_id; + roc.cookie = cookie; result = handle_remain_on_chan(vif, &roc); if (result) netdev_err(vif->ndev, "%s: failed to set remain on channel\n", @@ -2302,7 +1836,7 @@ int wilc_remain_on_channel(struct wilc_vif *vif, u32 session_id, return result; } -int wilc_listen_state_expired(struct wilc_vif *vif, u32 session_id) +int wilc_listen_state_expired(struct wilc_vif *vif, u64 cookie) { int result; struct host_if_msg *msg; @@ -2319,7 +1853,7 @@ int wilc_listen_state_expired(struct wilc_vif *vif, u32 session_id) if (IS_ERR(msg)) return PTR_ERR(msg); - msg->body.remain_on_ch.id = session_id; + msg->body.remain_on_ch.cookie = cookie; result = wilc_enqueue_work(msg); if (result) { @@ -2484,7 +2018,7 @@ int wilc_del_allstation(struct wilc_vif *vif, u8 mac_addr[][ETH_ALEN]) int result; int i; u8 assoc_sta = 0; - struct del_all_sta del_sta; + struct wilc_del_all_sta del_sta; memset(&del_sta, 0x0, sizeof(del_sta)); for (i = 0; i < WILC_MAX_NUM_STA; i++) { @@ -2563,7 +2097,7 @@ int wilc_set_power_mgmt(struct wilc_vif *vif, bool enabled, u32 timeout) return result; } -int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled, u32 count, +int wilc_setup_multicast_filter(struct wilc_vif *vif, u32 enabled, u32 count, u8 *mc_list) { int result; @@ -2573,9 +2107,9 @@ int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled, u32 count, if (IS_ERR(msg)) return PTR_ERR(msg); - msg->body.multicast_info.enabled = enabled; - msg->body.multicast_info.cnt = count; - msg->body.multicast_info.mc_list = mc_list; + msg->body.mc_info.enabled = enabled; + msg->body.mc_info.cnt = count; + msg->body.mc_info.mc_list = mc_list; result = wilc_enqueue_work(msg); if (result) { diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 9b396a79b144..678e62312215 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -18,19 +18,16 @@ enum { }; #define WILC_MAX_NUM_STA 9 -#define MAX_NUM_SCANNED_NETWORKS 100 -#define MAX_NUM_SCANNED_NETWORKS_SHADOW 130 +#define WILC_MAX_NUM_SCANNED_CH 14 #define WILC_MAX_NUM_PROBED_SSID 10 -#define TX_MIC_KEY_LEN 8 -#define RX_MIC_KEY_LEN 8 +#define WILC_TX_MIC_KEY_LEN 8 +#define WILC_RX_MIC_KEY_LEN 8 #define WILC_MAX_NUM_PMKIDS 16 #define WILC_ADD_STA_LENGTH 40 #define WILC_NUM_CONCURRENT_IFC 2 -#define NUM_RSSI 5 - enum { WILC_SET_CFG = 0, WILC_GET_CFG @@ -38,48 +35,6 @@ enum { #define WILC_MAX_ASSOC_RESP_FRAME_SIZE 256 -struct rssi_history_buffer { - bool full; - u8 index; - s8 samples[NUM_RSSI]; -}; - -struct network_info { - s8 rssi; - u16 cap_info; - u8 ssid[MAX_SSID_LEN]; - u8 ssid_len; - u8 bssid[6]; - u16 beacon_period; - u8 dtim_period; - u8 ch; - unsigned long time_scan_cached; - unsigned long time_scan; - bool new_network; - u8 found; - u32 tsf_lo; - u8 *ies; - u16 ies_len; - void *join_params; - struct rssi_history_buffer rssi_history; - u64 tsf; -}; - -struct connect_info { - u8 bssid[6]; - u8 *req_ies; - size_t req_ies_len; - u8 *resp_ies; - u16 resp_ies_len; - u16 status; -}; - -struct disconnect_info { - u16 reason; - u8 *ie; - size_t ie_len; -}; - struct assoc_resp { __le16 capab_info; __le16 status_code; @@ -129,11 +84,6 @@ enum cfg_param { WILC_CFG_PARAM_RTS_THRESHOLD = BIT(3) }; -struct found_net_info { - u8 bssid[6]; - s8 rssi; -}; - enum scan_event { SCAN_EVENT_NETWORK_FOUND = 0, SCAN_EVENT_DONE = 1, @@ -147,72 +97,71 @@ enum conn_event { CONN_DISCONN_EVENT_FORCE_32BIT = 0xFFFFFFFF }; -typedef void (*wilc_scan_result)(enum scan_event, struct network_info *, - void *, void *); - -typedef void (*wilc_connect_result)(enum conn_event, - struct connect_info *, - u8, - struct disconnect_info *, - void *); +enum { + WILC_HIF_SDIO = 0, + WILC_HIF_SPI = BIT(0) +}; -typedef void (*wilc_remain_on_chan_expired)(void *, u32); -typedef void (*wilc_remain_on_chan_ready)(void *); +enum { + WILC_MAC_STATUS_INIT = -1, + WILC_MAC_STATUS_DISCONNECTED = 0, + WILC_MAC_STATUS_CONNECTED = 1 +}; -struct rcvd_net_info { - u8 *buffer; - u32 len; +struct wilc_rcvd_net_info { + s8 rssi; + u8 ch; + u16 frame_len; + struct ieee80211_mgmt *mgmt; }; -struct hidden_net_info { - u8 *ssid; +struct wilc_probe_ssid_info { u8 ssid_len; + u8 *ssid; }; -struct hidden_network { - struct hidden_net_info *net_info; +struct wilc_probe_ssid { + struct wilc_probe_ssid_info *ssid_info; u8 n_ssids; + u32 size; }; -struct user_scan_req { - wilc_scan_result scan_result; +struct wilc_user_scan_req { + void (*scan_result)(enum scan_event evt, + struct wilc_rcvd_net_info *info, void *priv); void *arg; u32 ch_cnt; - struct found_net_info net_info[MAX_NUM_SCANNED_NETWORKS]; }; -struct user_conn_req { - u8 *bssid; - u8 *ssid; +struct wilc_conn_info { + u8 bssid[ETH_ALEN]; u8 security; enum authtype auth_type; - size_t ssid_len; - u8 *ies; - size_t ies_len; - wilc_connect_result conn_result; - bool ht_capable; u8 ch; + u8 *req_ies; + size_t req_ies_len; + u8 *resp_ies; + u16 resp_ies_len; + u16 status; + void (*conn_result)(enum conn_event evt, u8 status, void *priv_data); void *arg; void *param; }; -struct remain_ch { +struct wilc_remain_ch { u16 ch; u32 duration; - wilc_remain_on_chan_expired expired; - wilc_remain_on_chan_ready ready; + void (*expired)(void *priv, u64 cookie); void *arg; - u32 id; + u32 cookie; }; struct wilc; struct host_if_drv { - struct user_scan_req usr_scan_req; - struct user_conn_req usr_conn_req; - struct remain_ch remain_on_ch; - u8 remain_on_ch_pending; + struct wilc_user_scan_req usr_scan_req; + struct wilc_conn_info conn_info; + struct wilc_remain_ch remain_on_ch; u64 p2p_timeout; - u8 p2p_connect; enum host_if_state hif_state; @@ -232,17 +181,6 @@ struct host_if_drv { u8 assoc_resp[WILC_MAX_ASSOC_RESP_FRAME_SIZE]; }; -struct add_sta_param { - u8 bssid[ETH_ALEN]; - u16 aid; - u8 rates_len; - const u8 *rates; - bool ht_supported; - struct ieee80211_ht_cap ht_capa; - u16 flags_mask; - u16 flags_set; -}; - struct wilc_vif; int wilc_remove_wep_key(struct wilc_vif *vif, u8 index); int wilc_set_wep_default_keyid(struct wilc_vif *vif, u8 index); @@ -261,18 +199,16 @@ int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len, u8 cipher_mode); int wilc_set_pmkid_info(struct wilc_vif *vif, struct wilc_pmkid_attr *pmkid); int wilc_get_mac_address(struct wilc_vif *vif, u8 *mac_addr); -int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, const u8 *ssid, - size_t ssid_len, const u8 *ies, size_t ies_len, - wilc_connect_result connect_result, void *user_arg, - u8 security, enum authtype auth_type, - u8 channel, void *join_params); +int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, const u8 *ies, + size_t ies_len); int wilc_disconnect(struct wilc_vif *vif); int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel); int wilc_get_rssi(struct wilc_vif *vif, s8 *rssi_level); int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type, - u8 *ch_freq_list, u8 ch_list_len, const u8 *ies, - size_t ies_len, wilc_scan_result scan_result, void *user_arg, - struct hidden_network *hidden_network); + u8 *ch_freq_list, u8 ch_list_len, const u8 *ies, size_t ies_len, + void (*scan_result_fn)(enum scan_event, + struct wilc_rcvd_net_info *, void *), + void *user_arg, struct wilc_probe_ssid *search); int wilc_hif_set_cfg(struct wilc_vif *vif, struct cfg_param_attr *cfg_param); int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler); @@ -287,14 +223,13 @@ int wilc_del_station(struct wilc_vif *vif, const u8 *mac_addr); int wilc_edit_station(struct wilc_vif *vif, const u8 *mac, struct station_parameters *params); int wilc_set_power_mgmt(struct wilc_vif *vif, bool enabled, u32 timeout); -int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled, u32 count, +int wilc_setup_multicast_filter(struct wilc_vif *vif, u32 enabled, u32 count, u8 *mc_list); -int wilc_remain_on_channel(struct wilc_vif *vif, u32 session_id, +int wilc_remain_on_channel(struct wilc_vif *vif, u64 cookie, u32 duration, u16 chan, - wilc_remain_on_chan_expired expired, - wilc_remain_on_chan_ready ready, + void (*expired)(void *, u64), void *user_arg); -int wilc_listen_state_expired(struct wilc_vif *vif, u32 session_id); +int wilc_listen_state_expired(struct wilc_vif *vif, u64 cookie); void wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg); int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode, u8 ifc_id); @@ -307,4 +242,6 @@ int wilc_get_tx_power(struct wilc_vif *vif, u8 *tx_power); void wilc_scan_complete_received(struct wilc *wilc, u8 *buffer, u32 length); void wilc_network_info_received(struct wilc *wilc, u8 *buffer, u32 length); void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *buffer, u32 length); +void *wilc_parse_join_bss_param(struct cfg80211_bss *bss, + struct cfg80211_crypto_settings *crypto); #endif diff --git a/drivers/staging/wilc1000/linux_mon.c b/drivers/staging/wilc1000/wilc_mon.c index a63446818eac..9fe19a3e1dd4 100644 --- a/drivers/staging/wilc1000/linux_mon.c +++ b/drivers/staging/wilc1000/wilc_mon.c @@ -18,28 +18,20 @@ struct wilc_wfi_radiotap_cb_hdr { u16 tx_flags; } __packed; -static struct net_device *wilc_wfi_mon; /* global monitor netdev */ - -static u8 srcadd[6]; -static u8 bssid[6]; - -#define IEEE80211_RADIOTAP_F_TX_RTS 0x0004 /* used rts/cts handshake */ -#define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001 /* failed due to excessive*/ - #define TX_RADIOTAP_PRESENT ((1 << IEEE80211_RADIOTAP_RATE) | \ (1 << IEEE80211_RADIOTAP_TX_FLAGS)) -void wilc_wfi_monitor_rx(u8 *buff, u32 size) +void wilc_wfi_monitor_rx(struct net_device *mon_dev, u8 *buff, u32 size) { u32 header, pkt_offset; struct sk_buff *skb = NULL; struct wilc_wfi_radiotap_hdr *hdr; struct wilc_wfi_radiotap_cb_hdr *cb_hdr; - if (!wilc_wfi_mon) + if (!mon_dev) return; - if (!netif_running(wilc_wfi_mon)) + if (!netif_running(mon_dev)) return; /* Get WILC header */ @@ -94,7 +86,7 @@ void wilc_wfi_monitor_rx(u8 *buff, u32 size) hdr->rate = 5; } - skb->dev = wilc_wfi_mon; + skb->dev = mon_dev; skb_reset_mac_header(skb); skb->ip_summed = CHECKSUM_UNNECESSARY; skb->pkt_type = PACKET_OTHERHOST; @@ -155,13 +147,13 @@ static netdev_tx_t wilc_wfi_mon_xmit(struct sk_buff *skb, struct wilc_wfi_mon_priv *mon_priv; struct sk_buff *skb2; struct wilc_wfi_radiotap_cb_hdr *cb_hdr; + u8 srcadd[ETH_ALEN]; + u8 bssid[ETH_ALEN]; - if (!wilc_wfi_mon) - return -EFAULT; - - mon_priv = netdev_priv(wilc_wfi_mon); + mon_priv = netdev_priv(dev); if (!mon_priv) return -EFAULT; + rtap_len = ieee80211_get_radiotap_len(skb->data); if (skb->len < rtap_len) return -1; @@ -187,7 +179,7 @@ static netdev_tx_t wilc_wfi_mon_xmit(struct sk_buff *skb, cb_hdr->rate = 5; cb_hdr->tx_flags = 0x0004; - skb2->dev = wilc_wfi_mon; + skb2->dev = dev; skb_reset_mac_header(skb2); skb2->ip_summed = CHECKSUM_UNNECESSARY; skb2->pkt_type = PACKET_OTHERHOST; @@ -200,8 +192,8 @@ static netdev_tx_t wilc_wfi_mon_xmit(struct sk_buff *skb, } skb->dev = mon_priv->real_ndev; - memcpy(srcadd, &skb->data[10], 6); - memcpy(bssid, &skb->data[16], 6); + ether_addr_copy(srcadd, &skb->data[10]); + ether_addr_copy(bssid, &skb->data[16]); /* * Identify if data or mgmt packet, if source address and bssid * fields are equal send it to mgmt frames handler @@ -223,51 +215,44 @@ static const struct net_device_ops wilc_wfi_netdev_ops = { }; -struct net_device *wilc_wfi_init_mon_interface(const char *name, +struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl, + const char *name, struct net_device *real_dev) { struct wilc_wfi_mon_priv *priv; /*If monitor interface is already initialized, return it*/ - if (wilc_wfi_mon) - return wilc_wfi_mon; + if (wl->monitor_dev) + return wl->monitor_dev; - wilc_wfi_mon = alloc_etherdev(sizeof(struct wilc_wfi_mon_priv)); - if (!wilc_wfi_mon) + wl->monitor_dev = alloc_etherdev(sizeof(struct wilc_wfi_mon_priv)); + if (!wl->monitor_dev) return NULL; - wilc_wfi_mon->type = ARPHRD_IEEE80211_RADIOTAP; - strncpy(wilc_wfi_mon->name, name, IFNAMSIZ); - wilc_wfi_mon->name[IFNAMSIZ - 1] = 0; - wilc_wfi_mon->netdev_ops = &wilc_wfi_netdev_ops; - if (register_netdevice(wilc_wfi_mon)) { + wl->monitor_dev->type = ARPHRD_IEEE80211_RADIOTAP; + strncpy(wl->monitor_dev->name, name, IFNAMSIZ); + wl->monitor_dev->name[IFNAMSIZ - 1] = 0; + wl->monitor_dev->netdev_ops = &wilc_wfi_netdev_ops; + + if (register_netdevice(wl->monitor_dev)) { netdev_err(real_dev, "register_netdevice failed\n"); return NULL; } - priv = netdev_priv(wilc_wfi_mon); + priv = netdev_priv(wl->monitor_dev); if (!priv) return NULL; priv->real_ndev = real_dev; - return wilc_wfi_mon; + return wl->monitor_dev; } -void wilc_wfi_deinit_mon_interface(void) +void wilc_wfi_deinit_mon_interface(struct wilc *wl) { - bool rollback_lock = false; - - if (wilc_wfi_mon) { - if (rtnl_is_locked()) { - rtnl_unlock(); - rollback_lock = true; - } - unregister_netdev(wilc_wfi_mon); + if (!wl->monitor_dev) + return; - if (rollback_lock) { - rtnl_lock(); - rollback_lock = false; - } - wilc_wfi_mon = NULL; - } + unregister_netdev(wl->monitor_dev); + free_netdev(wl->monitor_dev); + wl->monitor_dev = NULL; } diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/wilc_netdev.c index 721689048648..1787154ee088 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/wilc_netdev.c @@ -12,86 +12,7 @@ #include "wilc_wfi_cfgoperations.h" -static int dev_state_ev_handler(struct notifier_block *this, - unsigned long event, void *ptr) -{ - struct in_ifaddr *dev_iface = ptr; - struct wilc_priv *priv; - struct host_if_drv *hif_drv; - struct net_device *dev; - u8 *ip_addr_buf; - struct wilc_vif *vif; - u8 null_ip[4] = {0}; - char wlan_dev_name[5] = "wlan0"; - - if (!dev_iface || !dev_iface->ifa_dev || !dev_iface->ifa_dev->dev) - return NOTIFY_DONE; - - if (memcmp(dev_iface->ifa_label, "wlan0", 5) && - memcmp(dev_iface->ifa_label, "p2p0", 4)) - return NOTIFY_DONE; - - dev = (struct net_device *)dev_iface->ifa_dev->dev; - if (!dev->ieee80211_ptr || !dev->ieee80211_ptr->wiphy) - return NOTIFY_DONE; - - priv = wiphy_priv(dev->ieee80211_ptr->wiphy); - if (!priv) - return NOTIFY_DONE; - - hif_drv = (struct host_if_drv *)priv->hif_drv; - vif = netdev_priv(dev); - if (!vif || !hif_drv) - return NOTIFY_DONE; - - switch (event) { - case NETDEV_UP: - if (vif->iftype == WILC_STATION_MODE || - vif->iftype == WILC_CLIENT_MODE) { - hif_drv->ifc_up = 1; - vif->obtaining_ip = false; - del_timer(&vif->during_ip_timer); - } - - if (vif->wilc->enable_ps) - wilc_set_power_mgmt(vif, 1, 0); - - netdev_dbg(dev, "[%s] Up IP\n", dev_iface->ifa_label); - - ip_addr_buf = (char *)&dev_iface->ifa_address; - netdev_dbg(dev, "IP add=%d:%d:%d:%d\n", - ip_addr_buf[0], ip_addr_buf[1], - ip_addr_buf[2], ip_addr_buf[3]); - - break; - - case NETDEV_DOWN: - if (vif->iftype == WILC_STATION_MODE || - vif->iftype == WILC_CLIENT_MODE) { - hif_drv->ifc_up = 0; - vif->obtaining_ip = false; - } - - if (memcmp(dev_iface->ifa_label, wlan_dev_name, 5) == 0) - wilc_set_power_mgmt(vif, 0, 0); - - wilc_resolve_disconnect_aberration(vif); - - netdev_dbg(dev, "[%s] Down IP\n", dev_iface->ifa_label); - - ip_addr_buf = null_ip; - netdev_dbg(dev, "IP add=%d:%d:%d:%d\n", - ip_addr_buf[0], ip_addr_buf[1], - ip_addr_buf[2], ip_addr_buf[3]); - - break; - - default: - break; - } - - return NOTIFY_DONE; -} +#define WILC_MULTICAST_TABLE_SIZE 8 static irqreturn_t isr_uh_routine(int irq, void *user_data) { @@ -198,7 +119,11 @@ void wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid, u8 mode) { struct wilc_vif *vif = netdev_priv(wilc_netdev); - memcpy(vif->bssid, bssid, 6); + if (bssid) + ether_addr_copy(vif->bssid, bssid); + else + eth_zero_addr(vif->bssid); + vif->mode = mode; } @@ -214,7 +139,7 @@ int wilc_wlan_get_num_conn_ifcs(struct wilc *wilc) return ret_val; } -static int linux_wlan_txq_task(void *vp) +static int wilc_txq_task(void *vp) { int ret; u32 txq_count; @@ -236,9 +161,11 @@ static int linux_wlan_txq_task(void *vp) do { ret = wilc_wlan_handle_txq(dev, &txq_count); if (txq_count < FLOW_CONTROL_LOWER_THRESHOLD) { - if (netif_queue_stopped(wl->vif[0]->ndev)) + if (wl->vif[0]->mac_opened && + netif_queue_stopped(wl->vif[0]->ndev)) netif_wake_queue(wl->vif[0]->ndev); - if (netif_queue_stopped(wl->vif[1]->ndev)) + if (wl->vif[1]->mac_opened && + netif_queue_stopped(wl->vif[1]->ndev)) netif_wake_queue(wl->vif[1]->ndev); } } while (ret == -ENOBUFS && !wl->close); @@ -275,7 +202,7 @@ fail: return ret; } -static int linux_wlan_start_firmware(struct net_device *dev) +static int wilc_start_firmware(struct net_device *dev) { struct wilc_vif *vif = netdev_priv(dev); struct wilc *wilc = vif->wilc; @@ -316,204 +243,169 @@ static int wilc1000_firmware_download(struct net_device *dev) return 0; } -static int linux_wlan_init_test_config(struct net_device *dev, - struct wilc_vif *vif) +static int wilc_init_fw_config(struct net_device *dev, struct wilc_vif *vif) { - unsigned char c_val[64]; - struct wilc *wilc = vif->wilc; struct wilc_priv *priv; struct host_if_drv *hif_drv; + u8 b; + u16 hw; + u32 w; netdev_dbg(dev, "Start configuring Firmware\n"); priv = wiphy_priv(dev->ieee80211_ptr->wiphy); hif_drv = (struct host_if_drv *)priv->hif_drv; netdev_dbg(dev, "Host = %p\n", hif_drv); - wilc_get_chipid(wilc, false); - - *(int *)c_val = 1; - - if (!wilc_wlan_cfg_set(vif, 1, WID_SET_DRV_HANDLER, c_val, 4, 0, 0)) - goto fail; - - c_val[0] = 0; - if (!wilc_wlan_cfg_set(vif, 0, WID_PC_TEST_MODE, c_val, 1, 0, 0)) - goto fail; - c_val[0] = WILC_FW_BSS_TYPE_INFRA; - if (!wilc_wlan_cfg_set(vif, 0, WID_BSS_TYPE, c_val, 1, 0, 0)) - goto fail; - - c_val[0] = WILC_FW_TX_RATE_AUTO; - if (!wilc_wlan_cfg_set(vif, 0, WID_CURRENT_TX_RATE, c_val, 1, 0, 0)) - goto fail; - - c_val[0] = WILC_FW_OPER_MODE_G_MIXED_11B_2; - if (!wilc_wlan_cfg_set(vif, 0, WID_11G_OPERATING_MODE, c_val, 1, 0, - 0)) - goto fail; - - c_val[0] = 1; - if (!wilc_wlan_cfg_set(vif, 0, WID_CURRENT_CHANNEL, c_val, 1, 0, 0)) - goto fail; - - c_val[0] = WILC_FW_PREAMBLE_SHORT; - if (!wilc_wlan_cfg_set(vif, 0, WID_PREAMBLE, c_val, 1, 0, 0)) + w = vif->iftype; + cpu_to_le32s(&w); + if (!wilc_wlan_cfg_set(vif, 1, WID_SET_OPERATION_MODE, (u8 *)&w, 4, + 0, 0)) goto fail; - c_val[0] = WILC_FW_11N_PROT_AUTO; - if (!wilc_wlan_cfg_set(vif, 0, WID_11N_PROT_MECH, c_val, 1, 0, 0)) + b = WILC_FW_BSS_TYPE_INFRA; + if (!wilc_wlan_cfg_set(vif, 0, WID_BSS_TYPE, &b, 1, 0, 0)) goto fail; - c_val[0] = WILC_FW_ACTIVE_SCAN; - if (!wilc_wlan_cfg_set(vif, 0, WID_SCAN_TYPE, c_val, 1, 0, 0)) + b = WILC_FW_TX_RATE_AUTO; + if (!wilc_wlan_cfg_set(vif, 0, WID_CURRENT_TX_RATE, &b, 1, 0, 0)) goto fail; - c_val[0] = WILC_FW_SITE_SURVEY_OFF; - if (!wilc_wlan_cfg_set(vif, 0, WID_SITE_SURVEY, c_val, 1, 0, 0)) + b = WILC_FW_OPER_MODE_G_MIXED_11B_2; + if (!wilc_wlan_cfg_set(vif, 0, WID_11G_OPERATING_MODE, &b, 1, 0, 0)) goto fail; - *((int *)c_val) = 0xffff; - if (!wilc_wlan_cfg_set(vif, 0, WID_RTS_THRESHOLD, c_val, 2, 0, 0)) + b = WILC_FW_PREAMBLE_SHORT; + if (!wilc_wlan_cfg_set(vif, 0, WID_PREAMBLE, &b, 1, 0, 0)) goto fail; - *((int *)c_val) = 2346; - if (!wilc_wlan_cfg_set(vif, 0, WID_FRAG_THRESHOLD, c_val, 2, 0, 0)) + b = WILC_FW_11N_PROT_AUTO; + if (!wilc_wlan_cfg_set(vif, 0, WID_11N_PROT_MECH, &b, 1, 0, 0)) goto fail; - c_val[0] = 0; - if (!wilc_wlan_cfg_set(vif, 0, WID_BCAST_SSID, c_val, 1, 0, 0)) + b = WILC_FW_ACTIVE_SCAN; + if (!wilc_wlan_cfg_set(vif, 0, WID_SCAN_TYPE, &b, 1, 0, 0)) goto fail; - c_val[0] = 1; - if (!wilc_wlan_cfg_set(vif, 0, WID_QOS_ENABLE, c_val, 1, 0, 0)) + b = WILC_FW_SITE_SURVEY_OFF; + if (!wilc_wlan_cfg_set(vif, 0, WID_SITE_SURVEY, &b, 1, 0, 0)) goto fail; - c_val[0] = WILC_FW_NO_POWERSAVE; - if (!wilc_wlan_cfg_set(vif, 0, WID_POWER_MANAGEMENT, c_val, 1, 0, 0)) + hw = 0xffff; + cpu_to_le16s(&hw); + if (!wilc_wlan_cfg_set(vif, 0, WID_RTS_THRESHOLD, (u8 *)&hw, 2, 0, 0)) goto fail; - c_val[0] = WILC_FW_SEC_NO; - if (!wilc_wlan_cfg_set(vif, 0, WID_11I_MODE, c_val, 1, 0, 0)) + hw = 2346; + cpu_to_le16s(&hw); + if (!wilc_wlan_cfg_set(vif, 0, WID_FRAG_THRESHOLD, (u8 *)&hw, 2, 0, 0)) goto fail; - c_val[0] = WILC_FW_AUTH_OPEN_SYSTEM; - if (!wilc_wlan_cfg_set(vif, 0, WID_AUTH_TYPE, c_val, 1, 0, 0)) + b = 0; + if (!wilc_wlan_cfg_set(vif, 0, WID_BCAST_SSID, &b, 1, 0, 0)) goto fail; - strcpy(c_val, "123456790abcdef1234567890"); - if (!wilc_wlan_cfg_set(vif, 0, WID_WEP_KEY_VALUE, c_val, - (strlen(c_val) + 1), 0, 0)) + b = 1; + if (!wilc_wlan_cfg_set(vif, 0, WID_QOS_ENABLE, &b, 1, 0, 0)) goto fail; - strcpy(c_val, "12345678"); - if (!wilc_wlan_cfg_set(vif, 0, WID_11I_PSK, c_val, (strlen(c_val)), 0, - 0)) + b = WILC_FW_NO_POWERSAVE; + if (!wilc_wlan_cfg_set(vif, 0, WID_POWER_MANAGEMENT, &b, 1, 0, 0)) goto fail; - strcpy(c_val, "password"); - if (!wilc_wlan_cfg_set(vif, 0, WID_1X_KEY, c_val, (strlen(c_val) + 1), - 0, 0)) + b = WILC_FW_SEC_NO; + if (!wilc_wlan_cfg_set(vif, 0, WID_11I_MODE, &b, 1, 0, 0)) goto fail; - c_val[0] = 192; - c_val[1] = 168; - c_val[2] = 1; - c_val[3] = 112; - if (!wilc_wlan_cfg_set(vif, 0, WID_1X_SERV_ADDR, c_val, 4, 0, 0)) + b = WILC_FW_AUTH_OPEN_SYSTEM; + if (!wilc_wlan_cfg_set(vif, 0, WID_AUTH_TYPE, &b, 1, 0, 0)) goto fail; - c_val[0] = 3; - if (!wilc_wlan_cfg_set(vif, 0, WID_LISTEN_INTERVAL, c_val, 1, 0, 0)) + b = 3; + if (!wilc_wlan_cfg_set(vif, 0, WID_LISTEN_INTERVAL, &b, 1, 0, 0)) goto fail; - c_val[0] = 3; - if (!wilc_wlan_cfg_set(vif, 0, WID_DTIM_PERIOD, c_val, 1, 0, 0)) + b = 3; + if (!wilc_wlan_cfg_set(vif, 0, WID_DTIM_PERIOD, &b, 1, 0, 0)) goto fail; - c_val[0] = WILC_FW_ACK_POLICY_NORMAL; - if (!wilc_wlan_cfg_set(vif, 0, WID_ACK_POLICY, c_val, 1, 0, 0)) + b = WILC_FW_ACK_POLICY_NORMAL; + if (!wilc_wlan_cfg_set(vif, 0, WID_ACK_POLICY, &b, 1, 0, 0)) goto fail; - c_val[0] = 0; - if (!wilc_wlan_cfg_set(vif, 0, WID_USER_CONTROL_ON_TX_POWER, c_val, 1, + b = 0; + if (!wilc_wlan_cfg_set(vif, 0, WID_USER_CONTROL_ON_TX_POWER, &b, 1, 0, 0)) goto fail; - c_val[0] = 48; - if (!wilc_wlan_cfg_set(vif, 0, WID_TX_POWER_LEVEL_11A, c_val, 1, 0, - 0)) + b = 48; + if (!wilc_wlan_cfg_set(vif, 0, WID_TX_POWER_LEVEL_11A, &b, 1, 0, 0)) goto fail; - c_val[0] = 28; - if (!wilc_wlan_cfg_set(vif, 0, WID_TX_POWER_LEVEL_11B, c_val, 1, 0, - 0)) + b = 28; + if (!wilc_wlan_cfg_set(vif, 0, WID_TX_POWER_LEVEL_11B, &b, 1, 0, 0)) goto fail; - *((int *)c_val) = 100; - if (!wilc_wlan_cfg_set(vif, 0, WID_BEACON_INTERVAL, c_val, 2, 0, 0)) + hw = 100; + cpu_to_le16s(&hw); + if (!wilc_wlan_cfg_set(vif, 0, WID_BEACON_INTERVAL, (u8 *)&hw, 2, 0, 0)) goto fail; - c_val[0] = WILC_FW_REKEY_POLICY_DISABLE; - if (!wilc_wlan_cfg_set(vif, 0, WID_REKEY_POLICY, c_val, 1, 0, 0)) + b = WILC_FW_REKEY_POLICY_DISABLE; + if (!wilc_wlan_cfg_set(vif, 0, WID_REKEY_POLICY, &b, 1, 0, 0)) goto fail; - *((int *)c_val) = 84600; - if (!wilc_wlan_cfg_set(vif, 0, WID_REKEY_PERIOD, c_val, 4, 0, 0)) + w = 84600; + cpu_to_le32s(&w); + if (!wilc_wlan_cfg_set(vif, 0, WID_REKEY_PERIOD, (u8 *)&w, 4, 0, 0)) goto fail; - *((int *)c_val) = 500; - if (!wilc_wlan_cfg_set(vif, 0, WID_REKEY_PACKET_COUNT, c_val, 4, 0, + w = 500; + cpu_to_le32s(&w); + if (!wilc_wlan_cfg_set(vif, 0, WID_REKEY_PACKET_COUNT, (u8 *)&w, 4, 0, 0)) goto fail; - c_val[0] = 1; - if (!wilc_wlan_cfg_set(vif, 0, WID_SHORT_SLOT_ALLOWED, c_val, 1, 0, + b = 1; + if (!wilc_wlan_cfg_set(vif, 0, WID_SHORT_SLOT_ALLOWED, &b, 1, 0, 0)) goto fail; - c_val[0] = WILC_FW_ERP_PROT_SELF_CTS; - if (!wilc_wlan_cfg_set(vif, 0, WID_11N_ERP_PROT_TYPE, c_val, 1, 0, 0)) + b = WILC_FW_ERP_PROT_SELF_CTS; + if (!wilc_wlan_cfg_set(vif, 0, WID_11N_ERP_PROT_TYPE, &b, 1, 0, 0)) goto fail; - c_val[0] = 1; - if (!wilc_wlan_cfg_set(vif, 0, WID_11N_ENABLE, c_val, 1, 0, 0)) + b = 1; + if (!wilc_wlan_cfg_set(vif, 0, WID_11N_ENABLE, &b, 1, 0, 0)) goto fail; - c_val[0] = WILC_FW_11N_OP_MODE_HT_MIXED; - if (!wilc_wlan_cfg_set(vif, 0, WID_11N_OPERATING_MODE, c_val, 1, 0, - 0)) + b = WILC_FW_11N_OP_MODE_HT_MIXED; + if (!wilc_wlan_cfg_set(vif, 0, WID_11N_OPERATING_MODE, &b, 1, 0, 0)) goto fail; - c_val[0] = 1; - if (!wilc_wlan_cfg_set(vif, 0, WID_11N_TXOP_PROT_DISABLE, c_val, 1, 0, - 0)) + b = 1; + if (!wilc_wlan_cfg_set(vif, 0, WID_11N_TXOP_PROT_DISABLE, &b, 1, 0, 0)) goto fail; - c_val[0] = WILC_FW_OBBS_NONHT_DETECT_PROTECT_REPORT; - if (!wilc_wlan_cfg_set(vif, 0, WID_11N_OBSS_NONHT_DETECTION, c_val, 1, + b = WILC_FW_OBBS_NONHT_DETECT_PROTECT_REPORT; + if (!wilc_wlan_cfg_set(vif, 0, WID_11N_OBSS_NONHT_DETECTION, &b, 1, 0, 0)) goto fail; - c_val[0] = WILC_FW_HT_PROT_RTS_CTS_NONHT; - if (!wilc_wlan_cfg_set(vif, 0, WID_11N_HT_PROT_TYPE, c_val, 1, 0, 0)) + b = WILC_FW_HT_PROT_RTS_CTS_NONHT; + if (!wilc_wlan_cfg_set(vif, 0, WID_11N_HT_PROT_TYPE, &b, 1, 0, 0)) goto fail; - c_val[0] = 0; - if (!wilc_wlan_cfg_set(vif, 0, WID_11N_RIFS_PROT_ENABLE, c_val, 1, 0, + b = 0; + if (!wilc_wlan_cfg_set(vif, 0, WID_11N_RIFS_PROT_ENABLE, &b, 1, 0, 0)) goto fail; - c_val[0] = WILC_FW_SMPS_MODE_MIMO; - if (!wilc_wlan_cfg_set(vif, 0, WID_11N_SMPS_MODE, c_val, 1, 0, 0)) - goto fail; - - c_val[0] = 7; - if (!wilc_wlan_cfg_set(vif, 0, WID_11N_CURRENT_TX_MCS, c_val, 1, 0, - 0)) + b = 7; + if (!wilc_wlan_cfg_set(vif, 0, WID_11N_CURRENT_TX_MCS, &b, 1, 0, 0)) goto fail; - c_val[0] = 1; - if (!wilc_wlan_cfg_set(vif, 0, WID_11N_IMMEDIATE_BA_ENABLED, c_val, 1, + b = 1; + if (!wilc_wlan_cfg_set(vif, 0, WID_11N_IMMEDIATE_BA_ENABLED, &b, 1, 1, 1)) goto fail; @@ -609,7 +501,7 @@ static int wlan_initialize_threads(struct net_device *dev) struct wilc_vif *vif = netdev_priv(dev); struct wilc *wilc = vif->wilc; - wilc->txq_thread = kthread_run(linux_wlan_txq_task, (void *)dev, + wilc->txq_thread = kthread_run(wilc_txq_task, (void *)dev, "K_TXQ_TASK"); if (IS_ERR(wilc->txq_thread)) { netdev_err(dev, "couldn't create TXQ thread\n"); @@ -667,7 +559,7 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif) goto fail_irq_enable; } - ret = linux_wlan_start_firmware(dev); + ret = wilc_start_firmware(dev); if (ret < 0) { ret = -EIO; goto fail_irq_enable; @@ -683,7 +575,7 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif) firmware_ver[size] = '\0'; netdev_dbg(dev, "Firmware Ver = %s\n", firmware_ver); } - ret = linux_wlan_init_test_config(dev, vif); + ret = wilc_init_fw_config(dev, vif); if (ret < 0) { netdev_err(dev, "Failed to configure firmware\n"); @@ -807,12 +699,12 @@ static void wilc_set_multicast_list(struct net_device *dev) if (dev->flags & IFF_ALLMULTI || dev->mc.count > WILC_MULTICAST_TABLE_SIZE) { - wilc_setup_multicast_filter(vif, false, 0, NULL); + wilc_setup_multicast_filter(vif, 0, 0, NULL); return; } if (dev->mc.count == 0) { - wilc_setup_multicast_filter(vif, true, 0, NULL); + wilc_setup_multicast_filter(vif, 1, 0, NULL); return; } @@ -829,11 +721,11 @@ static void wilc_set_multicast_list(struct net_device *dev) cur_mc += ETH_ALEN; } - if (wilc_setup_multicast_filter(vif, true, dev->mc.count, mc_list)) + if (wilc_setup_multicast_filter(vif, 1, dev->mc.count, mc_list)) kfree(mc_list); } -static void linux_wlan_tx_complete(void *priv, int status) +static void wilc_tx_complete(void *priv, int status) { struct tx_complete_data *pv_data = priv; @@ -847,9 +739,6 @@ netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev) struct wilc *wilc = vif->wilc; struct tx_complete_data *tx_data = NULL; int queue_count; - char *udp_buf; - struct iphdr *ih; - struct ethhdr *eth_h; if (skb->dev != ndev) { netdev_err(ndev, "Packet not destined to this device\n"); @@ -867,28 +756,18 @@ netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev) tx_data->size = skb->len; tx_data->skb = skb; - eth_h = (struct ethhdr *)(skb->data); - if (eth_h->h_proto == cpu_to_be16(0x8e88)) - netdev_dbg(ndev, "EAPOL transmitted\n"); - - ih = (struct iphdr *)(skb->data + sizeof(struct ethhdr)); - - udp_buf = (char *)ih + sizeof(struct iphdr); - if ((udp_buf[1] == 68 && udp_buf[3] == 67) || - (udp_buf[1] == 67 && udp_buf[3] == 68)) - netdev_dbg(ndev, "DHCP Message transmitted, type:%x %x %x\n", - udp_buf[248], udp_buf[249], udp_buf[250]); - vif->netstats.tx_packets++; vif->netstats.tx_bytes += tx_data->size; tx_data->bssid = wilc->vif[vif->idx]->bssid; queue_count = wilc_wlan_txq_add_net_pkt(ndev, (void *)tx_data, tx_data->buff, tx_data->size, - linux_wlan_tx_complete); + wilc_tx_complete); if (queue_count > FLOW_CONTROL_UPPER_THRESHOLD) { - netif_stop_queue(wilc->vif[0]->ndev); - netif_stop_queue(wilc->vif[1]->ndev); + if (wilc->vif[0]->mac_opened) + netif_stop_queue(wilc->vif[0]->ndev); + if (wilc->vif[1]->mac_opened) + netif_stop_queue(wilc->vif[1]->ndev); } return 0; @@ -916,7 +795,6 @@ static int wilc_mac_close(struct net_device *ndev) netdev_dbg(ndev, "Deinitializing wilc1000\n"); wl->close = 1; wilc_wlan_deinitialize(ndev); - wilc_wfi_deinit_mon_interface(); } vif->mac_opened = 0; @@ -924,7 +802,8 @@ static int wilc_mac_close(struct net_device *ndev) return 0; } -void wilc_frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset) +void wilc_frmw_to_host(struct wilc *wilc, u8 *buff, u32 size, + u32 pkt_offset) { unsigned int frame_len = 0; int stats; @@ -972,7 +851,7 @@ void wilc_wfi_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size) for (i = 0; i < wilc->vif_num; i++) { vif = netdev_priv(wilc->vif[i]->ndev); if (vif->monitor_flag) { - wilc_wfi_monitor_rx(buff, size); + wilc_wfi_monitor_rx(wilc->monitor_dev, buff, size); return; } } @@ -983,6 +862,76 @@ void wilc_wfi_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size) wilc_wfi_p2p_rx(wilc->vif[1]->ndev, buff, size); } +static const struct net_device_ops wilc_netdev_ops = { + .ndo_init = mac_init_fn, + .ndo_open = wilc_mac_open, + .ndo_stop = wilc_mac_close, + .ndo_start_xmit = wilc_mac_xmit, + .ndo_get_stats = mac_stats, + .ndo_set_rx_mode = wilc_set_multicast_list, +}; + +static int dev_state_ev_handler(struct notifier_block *this, + unsigned long event, void *ptr) +{ + struct in_ifaddr *dev_iface = ptr; + struct wilc_priv *priv; + struct host_if_drv *hif_drv; + struct net_device *dev; + struct wilc_vif *vif; + + if (!dev_iface || !dev_iface->ifa_dev || !dev_iface->ifa_dev->dev) + return NOTIFY_DONE; + + dev = (struct net_device *)dev_iface->ifa_dev->dev; + if (dev->netdev_ops != &wilc_netdev_ops) + return NOTIFY_DONE; + + if (!dev->ieee80211_ptr || !dev->ieee80211_ptr->wiphy) + return NOTIFY_DONE; + + priv = wiphy_priv(dev->ieee80211_ptr->wiphy); + if (!priv) + return NOTIFY_DONE; + + hif_drv = (struct host_if_drv *)priv->hif_drv; + vif = netdev_priv(dev); + if (!vif || !hif_drv) + return NOTIFY_DONE; + + switch (event) { + case NETDEV_UP: + if (vif->iftype == WILC_STATION_MODE || + vif->iftype == WILC_CLIENT_MODE) { + hif_drv->ifc_up = 1; + vif->obtaining_ip = false; + del_timer(&vif->during_ip_timer); + } + + if (vif->wilc->enable_ps) + wilc_set_power_mgmt(vif, 1, 0); + + break; + + case NETDEV_DOWN: + if (vif->iftype == WILC_STATION_MODE || + vif->iftype == WILC_CLIENT_MODE) { + hif_drv->ifc_up = 0; + vif->obtaining_ip = false; + wilc_set_power_mgmt(vif, 0, 0); + } + + wilc_resolve_disconnect_aberration(vif); + + break; + + default: + break; + } + + return NOTIFY_DONE; +} + static struct notifier_block g_dev_notifier = { .notifier_call = dev_state_ev_handler }; @@ -1002,19 +951,15 @@ void wilc_netdev_cleanup(struct wilc *wilc) wilc->firmware = NULL; } - if (wilc->vif[0]->ndev || wilc->vif[1]->ndev) { - for (i = 0; i < WILC_NUM_CONCURRENT_IFC; i++) - if (wilc->vif[i]->ndev) - if (wilc->vif[i]->mac_opened) - wilc_mac_close(wilc->vif[i]->ndev); - - for (i = 0; i < WILC_NUM_CONCURRENT_IFC; i++) { + for (i = 0; i < WILC_NUM_CONCURRENT_IFC; i++) { + if (wilc->vif[i] && wilc->vif[i]->ndev) { unregister_netdev(wilc->vif[i]->ndev); wilc_free_wiphy(wilc->vif[i]->ndev); free_netdev(wilc->vif[i]->ndev); } } + wilc_wfi_deinit_mon_interface(wilc); flush_workqueue(wilc->hif_workqueue); destroy_workqueue(wilc->hif_workqueue); wilc_wlan_cfg_deinit(wilc); @@ -1023,15 +968,6 @@ void wilc_netdev_cleanup(struct wilc *wilc) } EXPORT_SYMBOL_GPL(wilc_netdev_cleanup); -static const struct net_device_ops wilc_netdev_ops = { - .ndo_init = mac_init_fn, - .ndo_open = wilc_mac_open, - .ndo_stop = wilc_mac_close, - .ndo_start_xmit = wilc_mac_xmit, - .ndo_get_stats = mac_stats, - .ndo_set_rx_mode = wilc_set_multicast_list, -}; - int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, const struct wilc_hif_func *ops) { @@ -1086,8 +1022,8 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, vif->wilc = *wilc; vif->ndev = ndev; wl->vif[i] = vif; - wl->vif_num = i; - vif->idx = wl->vif_num; + wl->vif_num = i + 1; + vif->idx = i; ndev->netdev_ops = &wilc_netdev_ops; diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index e2f739fef21c..b789c57d7e80 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -51,10 +51,6 @@ struct sdio_cmd53 { static const struct wilc_hif_func wilc_hif_sdio; -static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data); -static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data); -static int sdio_init(struct wilc *wilc, bool resume); - static void wilc_sdio_interrupt(struct sdio_func *func) { sdio_release_host(func); @@ -121,8 +117,8 @@ static int wilc_sdio_cmd53(struct wilc *wilc, struct sdio_cmd53 *cmd) return ret; } -static int linux_sdio_probe(struct sdio_func *func, - const struct sdio_device_id *id) +static int wilc_sdio_probe(struct sdio_func *func, + const struct sdio_device_id *id) { struct wilc *wilc; int ret; @@ -160,7 +156,7 @@ static int linux_sdio_probe(struct sdio_func *func, return 0; } -static void linux_sdio_remove(struct sdio_func *func) +static void wilc_sdio_remove(struct sdio_func *func) { struct wilc *wilc = sdio_get_drvdata(func); @@ -170,7 +166,7 @@ static void linux_sdio_remove(struct sdio_func *func) wilc_netdev_cleanup(wilc); } -static int sdio_reset(struct wilc *wilc) +static int wilc_sdio_reset(struct wilc *wilc) { struct sdio_cmd52 cmd; int ret; @@ -205,7 +201,7 @@ static int wilc_sdio_suspend(struct device *dev) chip_allow_sleep(wilc); } - ret = sdio_reset(wilc); + ret = wilc_sdio_reset(wilc); if (ret) { dev_err(&func->dev, "Fail reset sdio\n"); return ret; @@ -215,50 +211,6 @@ static int wilc_sdio_suspend(struct device *dev) return 0; } -static int wilc_sdio_resume(struct device *dev) -{ - struct sdio_func *func = dev_to_sdio_func(dev); - struct wilc *wilc = sdio_get_drvdata(func); - - dev_info(dev, "sdio resume\n"); - sdio_release_host(func); - chip_wakeup(wilc); - sdio_init(wilc, true); - - if (wilc->suspend_event) - host_wakeup_notify(wilc); - - chip_allow_sleep(wilc); - - return 0; -} - -static const struct of_device_id wilc_of_match[] = { - { .compatible = "microchip,wilc1000-sdio", }, - { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(of, wilc_of_match); - -static const struct dev_pm_ops wilc_sdio_pm_ops = { - .suspend = wilc_sdio_suspend, - .resume = wilc_sdio_resume, -}; - -static struct sdio_driver wilc_sdio_driver = { - .name = SDIO_MODALIAS, - .id_table = wilc_sdio_ids, - .probe = linux_sdio_probe, - .remove = linux_sdio_remove, - .drv = { - .pm = &wilc_sdio_pm_ops, - .of_match_table = wilc_of_match, - } -}; -module_driver(wilc_sdio_driver, - sdio_register_driver, - sdio_unregister_driver); -MODULE_LICENSE("GPL"); - static int wilc_sdio_enable_interrupt(struct wilc *dev) { struct sdio_func *func = container_of(dev->dev, struct sdio_func, dev); @@ -293,7 +245,7 @@ static void wilc_sdio_disable_interrupt(struct wilc *dev) * ********************************************/ -static int sdio_set_func0_csa_address(struct wilc *wilc, u32 adr) +static int wilc_sdio_set_func0_csa_address(struct wilc *wilc, u32 adr) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct sdio_cmd52 cmd; @@ -334,7 +286,7 @@ fail: return 0; } -static int sdio_set_func0_block_size(struct wilc *wilc, u32 block_size) +static int wilc_sdio_set_func0_block_size(struct wilc *wilc, u32 block_size) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct sdio_cmd52 cmd; @@ -370,7 +322,7 @@ fail: * ********************************************/ -static int sdio_set_func1_block_size(struct wilc *wilc, u32 block_size) +static int wilc_sdio_set_func1_block_size(struct wilc *wilc, u32 block_size) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct sdio_cmd52 cmd; @@ -404,7 +356,7 @@ fail: * Sdio interfaces * ********************************************/ -static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data) +static int wilc_sdio_write_reg(struct wilc *wilc, u32 addr, u32 data) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; @@ -432,7 +384,7 @@ static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data) /** * set the AHB address **/ - if (!sdio_set_func0_csa_address(wilc, addr)) + if (!wilc_sdio_set_func0_csa_address(wilc, addr)) goto fail; cmd.read_write = 1; @@ -458,7 +410,7 @@ fail: return 0; } -static int sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) +static int wilc_sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; @@ -507,7 +459,7 @@ static int sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) cmd.buffer = buf; cmd.block_size = block_size; if (addr > 0) { - if (!sdio_set_func0_csa_address(wilc, addr)) + if (!wilc_sdio_set_func0_csa_address(wilc, addr)) goto fail; } ret = wilc_sdio_cmd53(wilc, &cmd); @@ -530,7 +482,7 @@ static int sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) cmd.block_size = block_size; if (addr > 0) { - if (!sdio_set_func0_csa_address(wilc, addr)) + if (!wilc_sdio_set_func0_csa_address(wilc, addr)) goto fail; } ret = wilc_sdio_cmd53(wilc, &cmd); @@ -548,7 +500,7 @@ fail: return 0; } -static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data) +static int wilc_sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; @@ -571,7 +523,7 @@ static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data) } else { struct sdio_cmd53 cmd; - if (!sdio_set_func0_csa_address(wilc, addr)) + if (!wilc_sdio_set_func0_csa_address(wilc, addr)) goto fail; cmd.read_write = 0; @@ -600,7 +552,7 @@ fail: return 0; } -static int sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) +static int wilc_sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; @@ -649,7 +601,7 @@ static int sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) cmd.buffer = buf; cmd.block_size = block_size; if (addr > 0) { - if (!sdio_set_func0_csa_address(wilc, addr)) + if (!wilc_sdio_set_func0_csa_address(wilc, addr)) goto fail; } ret = wilc_sdio_cmd53(wilc, &cmd); @@ -672,7 +624,7 @@ static int sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) cmd.block_size = block_size; if (addr > 0) { - if (!sdio_set_func0_csa_address(wilc, addr)) + if (!wilc_sdio_set_func0_csa_address(wilc, addr)) goto fail; } ret = wilc_sdio_cmd53(wilc, &cmd); @@ -696,12 +648,12 @@ fail: * ********************************************/ -static int sdio_deinit(struct wilc *wilc) +static int wilc_sdio_deinit(struct wilc *wilc) { return 1; } -static int sdio_init(struct wilc *wilc, bool resume) +static int wilc_sdio_init(struct wilc *wilc, bool resume) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; @@ -729,7 +681,7 @@ static int sdio_init(struct wilc *wilc, bool resume) /** * function 0 block size **/ - if (!sdio_set_func0_block_size(wilc, WILC_SDIO_BLOCK_SIZE)) { + if (!wilc_sdio_set_func0_block_size(wilc, WILC_SDIO_BLOCK_SIZE)) { dev_err(&func->dev, "Fail cmd 52, set func 0 block size...\n"); goto fail; } @@ -778,7 +730,7 @@ static int sdio_init(struct wilc *wilc, bool resume) /** * func 1 is ready, set func 1 block size **/ - if (!sdio_set_func1_block_size(wilc, WILC_SDIO_BLOCK_SIZE)) { + if (!wilc_sdio_set_func1_block_size(wilc, WILC_SDIO_BLOCK_SIZE)) { dev_err(&func->dev, "Fail set func 1 block size...\n"); goto fail; } @@ -801,7 +753,7 @@ static int sdio_init(struct wilc *wilc, bool resume) * make sure can read back chip id correctly **/ if (!resume) { - if (!sdio_read_reg(wilc, 0x1000, &chipid)) { + if (!wilc_sdio_read_reg(wilc, 0x1000, &chipid)) { dev_err(&func->dev, "Fail cmd read chip id...\n"); goto fail; } @@ -821,7 +773,7 @@ fail: return 0; } -static int sdio_read_size(struct wilc *wilc, u32 *size) +static int wilc_sdio_read_size(struct wilc *wilc, u32 *size) { u32 tmp; struct sdio_cmd52 cmd; @@ -846,14 +798,14 @@ static int sdio_read_size(struct wilc *wilc, u32 *size) return 1; } -static int sdio_read_int(struct wilc *wilc, u32 *int_status) +static int wilc_sdio_read_int(struct wilc *wilc, u32 *int_status) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; u32 tmp; struct sdio_cmd52 cmd; - sdio_read_size(wilc, &tmp); + wilc_sdio_read_size(wilc, &tmp); /** * Read IRQ flags @@ -905,7 +857,7 @@ static int sdio_read_int(struct wilc *wilc, u32 *int_status) return 1; } -static int sdio_clear_int_ext(struct wilc *wilc, u32 val) +static int wilc_sdio_clear_int_ext(struct wilc *wilc, u32 val) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; @@ -1030,7 +982,7 @@ fail: return 0; } -static int sdio_sync_ext(struct wilc *wilc, int nint) +static int wilc_sdio_sync_ext(struct wilc *wilc, int nint) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; @@ -1051,13 +1003,13 @@ static int sdio_sync_ext(struct wilc *wilc, int nint) /** * Disable power sequencer **/ - if (!sdio_read_reg(wilc, WILC_MISC, ®)) { + if (!wilc_sdio_read_reg(wilc, WILC_MISC, ®)) { dev_err(&func->dev, "Failed read misc reg...\n"); return 0; } reg &= ~BIT(8); - if (!sdio_write_reg(wilc, WILC_MISC, reg)) { + if (!wilc_sdio_write_reg(wilc, WILC_MISC, reg)) { dev_err(&func->dev, "Failed write misc reg...\n"); return 0; } @@ -1069,14 +1021,14 @@ static int sdio_sync_ext(struct wilc *wilc, int nint) /** * interrupt pin mux select **/ - ret = sdio_read_reg(wilc, WILC_PIN_MUX_0, ®); + ret = wilc_sdio_read_reg(wilc, WILC_PIN_MUX_0, ®); if (!ret) { dev_err(&func->dev, "Failed read reg (%08x)...\n", WILC_PIN_MUX_0); return 0; } reg |= BIT(8); - ret = sdio_write_reg(wilc, WILC_PIN_MUX_0, reg); + ret = wilc_sdio_write_reg(wilc, WILC_PIN_MUX_0, reg); if (!ret) { dev_err(&func->dev, "Failed write reg (%08x)...\n", WILC_PIN_MUX_0); @@ -1086,7 +1038,7 @@ static int sdio_sync_ext(struct wilc *wilc, int nint) /** * interrupt enable **/ - ret = sdio_read_reg(wilc, WILC_INTR_ENABLE, ®); + ret = wilc_sdio_read_reg(wilc, WILC_INTR_ENABLE, ®); if (!ret) { dev_err(&func->dev, "Failed read reg (%08x)...\n", WILC_INTR_ENABLE); @@ -1095,14 +1047,14 @@ static int sdio_sync_ext(struct wilc *wilc, int nint) for (i = 0; (i < 5) && (nint > 0); i++, nint--) reg |= BIT((27 + i)); - ret = sdio_write_reg(wilc, WILC_INTR_ENABLE, reg); + ret = wilc_sdio_write_reg(wilc, WILC_INTR_ENABLE, reg); if (!ret) { dev_err(&func->dev, "Failed write reg (%08x)...\n", WILC_INTR_ENABLE); return 0; } if (nint) { - ret = sdio_read_reg(wilc, WILC_INTR2_ENABLE, ®); + ret = wilc_sdio_read_reg(wilc, WILC_INTR2_ENABLE, ®); if (!ret) { dev_err(&func->dev, "Failed read reg (%08x)...\n", @@ -1113,7 +1065,7 @@ static int sdio_sync_ext(struct wilc *wilc, int nint) for (i = 0; (i < 3) && (nint > 0); i++, nint--) reg |= BIT(i); - ret = sdio_read_reg(wilc, WILC_INTR2_ENABLE, ®); + ret = wilc_sdio_read_reg(wilc, WILC_INTR2_ENABLE, ®); if (!ret) { dev_err(&func->dev, "Failed write reg (%08x)...\n", @@ -1127,19 +1079,62 @@ static int sdio_sync_ext(struct wilc *wilc, int nint) /* Global sdio HIF function table */ static const struct wilc_hif_func wilc_hif_sdio = { - .hif_init = sdio_init, - .hif_deinit = sdio_deinit, - .hif_read_reg = sdio_read_reg, - .hif_write_reg = sdio_write_reg, - .hif_block_rx = sdio_read, - .hif_block_tx = sdio_write, - .hif_read_int = sdio_read_int, - .hif_clear_int_ext = sdio_clear_int_ext, - .hif_read_size = sdio_read_size, - .hif_block_tx_ext = sdio_write, - .hif_block_rx_ext = sdio_read, - .hif_sync_ext = sdio_sync_ext, + .hif_init = wilc_sdio_init, + .hif_deinit = wilc_sdio_deinit, + .hif_read_reg = wilc_sdio_read_reg, + .hif_write_reg = wilc_sdio_write_reg, + .hif_block_rx = wilc_sdio_read, + .hif_block_tx = wilc_sdio_write, + .hif_read_int = wilc_sdio_read_int, + .hif_clear_int_ext = wilc_sdio_clear_int_ext, + .hif_read_size = wilc_sdio_read_size, + .hif_block_tx_ext = wilc_sdio_write, + .hif_block_rx_ext = wilc_sdio_read, + .hif_sync_ext = wilc_sdio_sync_ext, .enable_interrupt = wilc_sdio_enable_interrupt, .disable_interrupt = wilc_sdio_disable_interrupt, }; +static int wilc_sdio_resume(struct device *dev) +{ + struct sdio_func *func = dev_to_sdio_func(dev); + struct wilc *wilc = sdio_get_drvdata(func); + + dev_info(dev, "sdio resume\n"); + sdio_release_host(func); + chip_wakeup(wilc); + wilc_sdio_init(wilc, true); + + if (wilc->suspend_event) + host_wakeup_notify(wilc); + + chip_allow_sleep(wilc); + + return 0; +} + +static const struct of_device_id wilc_of_match[] = { + { .compatible = "microchip,wilc1000-sdio", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, wilc_of_match); + +static const struct dev_pm_ops wilc_sdio_pm_ops = { + .suspend = wilc_sdio_suspend, + .resume = wilc_sdio_resume, +}; + +static struct sdio_driver wilc_sdio_driver = { + .name = SDIO_MODALIAS, + .id_table = wilc_sdio_ids, + .probe = wilc_sdio_probe, + .remove = wilc_sdio_remove, + .drv = { + .pm = &wilc_sdio_pm_ops, + .of_match_table = wilc_of_match, + } +}; +module_driver(wilc_sdio_driver, + sdio_register_driver, + sdio_unregister_driver); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index 153e120eff00..4a1be9e60d74 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -814,7 +814,7 @@ static int wilc_spi_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) * ********************************************/ -static int _wilc_spi_deinit(struct wilc *wilc) +static int wilc_spi_deinit(struct wilc *wilc) { /* * TODO: @@ -1122,7 +1122,7 @@ static int wilc_spi_sync_ext(struct wilc *wilc, int nint) /* Global spi HIF function table */ static const struct wilc_hif_func wilc_hif_spi = { .hif_init = wilc_spi_init, - .hif_deinit = _wilc_spi_deinit, + .hif_deinit = wilc_spi_deinit, .hif_read_reg = wilc_spi_read_reg, .hif_write_reg = wilc_spi_write_reg, .hif_block_rx = wilc_spi_read, diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index ac47dda510e0..5e7a4676324e 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -27,10 +27,7 @@ #define GAS_INITIAL_REQ 0x0a #define GAS_INITIAL_RSP 0x0b -#define INVALID_CHANNEL 0 - -#define nl80211_SCAN_RESULT_EXPIRE (3 * HZ) -#define SCAN_RESULT_EXPIRE (40 * HZ) +#define WILC_INVALID_CHANNEL 0 static const struct ieee80211_txrx_stypes wilc_wfi_cfg80211_mgmt_types[NUM_NL80211_IFTYPES] = { @@ -65,124 +62,15 @@ static const struct wiphy_wowlan_support wowlan_support = { .flags = WIPHY_WOWLAN_ANY }; -struct p2p_mgmt_data { +struct wilc_p2p_mgmt_data { int size; u8 *buff; }; -static u8 wlan_channel = INVALID_CHANNEL; -static u8 curr_channel; -static u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09}; -static u8 p2p_vendor_spec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03}; - -#define AGING_TIME (9 * 1000) -#define DURING_IP_TIME_OUT 15000 - -static void clear_shadow_scan(struct wilc_priv *priv) -{ - int i; - - for (i = 0; i < priv->scanned_cnt; i++) { - kfree(priv->scanned_shadow[i].ies); - priv->scanned_shadow[i].ies = NULL; - - kfree(priv->scanned_shadow[i].join_params); - priv->scanned_shadow[i].join_params = NULL; - } - priv->scanned_cnt = 0; -} - -static u32 get_rssi_avg(struct network_info *network_info) -{ - u8 i; - int rssi_v = 0; - u8 num_rssi = (network_info->rssi_history.full) ? - NUM_RSSI : (network_info->rssi_history.index); - - for (i = 0; i < num_rssi; i++) - rssi_v += network_info->rssi_history.samples[i]; - - rssi_v /= num_rssi; - return rssi_v; -} - -static void refresh_scan(struct wilc_priv *priv, bool direct_scan) -{ - struct wiphy *wiphy = priv->dev->ieee80211_ptr->wiphy; - int i; - - for (i = 0; i < priv->scanned_cnt; i++) { - struct network_info *network_info; - s32 freq; - struct ieee80211_channel *channel; - int rssi; - struct cfg80211_bss *bss; - - network_info = &priv->scanned_shadow[i]; - - if (!memcmp("DIRECT-", network_info->ssid, 7) && !direct_scan) - continue; - - freq = ieee80211_channel_to_frequency((s32)network_info->ch, - NL80211_BAND_2GHZ); - channel = ieee80211_get_channel(wiphy, freq); - rssi = get_rssi_avg(network_info); - bss = cfg80211_inform_bss(wiphy, - channel, - CFG80211_BSS_FTYPE_UNKNOWN, - network_info->bssid, - network_info->tsf, - network_info->cap_info, - network_info->beacon_period, - (const u8 *)network_info->ies, - (size_t)network_info->ies_len, - (s32)rssi * 100, - GFP_KERNEL); - cfg80211_put_bss(wiphy, bss); - } -} - -static void reset_shadow_found(struct wilc_priv *priv) -{ - int i; - - for (i = 0; i < priv->scanned_cnt; i++) - priv->scanned_shadow[i].found = 0; -} - -static void update_scan_time(struct wilc_priv *priv) -{ - int i; - - for (i = 0; i < priv->scanned_cnt; i++) - priv->scanned_shadow[i].time_scan = jiffies; -} - -static void remove_network_from_shadow(struct timer_list *t) -{ - struct wilc_priv *priv = from_timer(priv, t, aging_timer); - unsigned long now = jiffies; - int i, j; - - for (i = 0; i < priv->scanned_cnt; i++) { - if (!time_after(now, priv->scanned_shadow[i].time_scan + - (unsigned long)(SCAN_RESULT_EXPIRE))) - continue; - kfree(priv->scanned_shadow[i].ies); - priv->scanned_shadow[i].ies = NULL; - - kfree(priv->scanned_shadow[i].join_params); +static const u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09}; +static const u8 p2p_vendor_spec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03}; - for (j = i; (j < priv->scanned_cnt - 1); j++) - priv->scanned_shadow[j] = priv->scanned_shadow[j + 1]; - - priv->scanned_cnt--; - } - - if (priv->scanned_cnt != 0) - mod_timer(&priv->aging_timer, - jiffies + msecs_to_jiffies(AGING_TIME)); -} +#define WILC_IP_TIMEOUT_MS 15000 static void clear_during_ip(struct timer_list *t) { @@ -191,151 +79,36 @@ static void clear_during_ip(struct timer_list *t) vif->obtaining_ip = false; } -static int is_network_in_shadow(struct network_info *nw_info, - struct wilc_priv *priv) -{ - int state = -1; - int i; - - if (priv->scanned_cnt == 0) { - mod_timer(&priv->aging_timer, - jiffies + msecs_to_jiffies(AGING_TIME)); - state = -1; - } else { - for (i = 0; i < priv->scanned_cnt; i++) { - if (memcmp(priv->scanned_shadow[i].bssid, - nw_info->bssid, 6) == 0) { - state = i; - break; - } - } - } - return state; -} - -static void add_network_to_shadow(struct network_info *nw_info, - struct wilc_priv *priv, void *join_params) -{ - int ap_found = is_network_in_shadow(nw_info, priv); - u32 ap_index = 0; - u8 rssi_index = 0; - struct network_info *shadow_nw_info; - - if (priv->scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW) - return; - - if (ap_found == -1) { - ap_index = priv->scanned_cnt; - priv->scanned_cnt++; - } else { - ap_index = ap_found; - } - shadow_nw_info = &priv->scanned_shadow[ap_index]; - rssi_index = shadow_nw_info->rssi_history.index; - shadow_nw_info->rssi_history.samples[rssi_index++] = nw_info->rssi; - if (rssi_index == NUM_RSSI) { - rssi_index = 0; - shadow_nw_info->rssi_history.full = true; - } - shadow_nw_info->rssi_history.index = rssi_index; - shadow_nw_info->rssi = nw_info->rssi; - shadow_nw_info->cap_info = nw_info->cap_info; - shadow_nw_info->ssid_len = nw_info->ssid_len; - memcpy(shadow_nw_info->ssid, nw_info->ssid, nw_info->ssid_len); - memcpy(shadow_nw_info->bssid, nw_info->bssid, ETH_ALEN); - shadow_nw_info->beacon_period = nw_info->beacon_period; - shadow_nw_info->dtim_period = nw_info->dtim_period; - shadow_nw_info->ch = nw_info->ch; - shadow_nw_info->tsf = nw_info->tsf; - if (ap_found != -1) - kfree(shadow_nw_info->ies); - shadow_nw_info->ies = kmemdup(nw_info->ies, nw_info->ies_len, - GFP_KERNEL); - if (shadow_nw_info->ies) - shadow_nw_info->ies_len = nw_info->ies_len; - else - shadow_nw_info->ies_len = 0; - shadow_nw_info->time_scan = jiffies; - shadow_nw_info->time_scan_cached = jiffies; - shadow_nw_info->found = 1; - if (ap_found != -1) - kfree(shadow_nw_info->join_params); - shadow_nw_info->join_params = join_params; -} - static void cfg_scan_result(enum scan_event scan_event, - struct network_info *network_info, - void *user_void, void *join_params) + struct wilc_rcvd_net_info *info, void *user_void) { - struct wilc_priv *priv; - struct wiphy *wiphy; - s32 freq; - struct ieee80211_channel *channel; - struct cfg80211_bss *bss = NULL; + struct wilc_priv *priv = user_void; - priv = user_void; if (!priv->cfg_scanning) return; if (scan_event == SCAN_EVENT_NETWORK_FOUND) { - wiphy = priv->dev->ieee80211_ptr->wiphy; - - if (!wiphy || !network_info) - return; + s32 freq; + struct ieee80211_channel *channel; + struct cfg80211_bss *bss; + struct wiphy *wiphy = priv->dev->ieee80211_ptr->wiphy; - if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC && - (((s32)network_info->rssi * 100) < 0 || - ((s32)network_info->rssi * 100) > 100)) + if (!wiphy || !info) return; - freq = ieee80211_channel_to_frequency((s32)network_info->ch, + freq = ieee80211_channel_to_frequency((s32)info->ch, NL80211_BAND_2GHZ); channel = ieee80211_get_channel(wiphy, freq); - if (!channel) return; - if (network_info->new_network) { - if (priv->rcvd_ch_cnt >= MAX_NUM_SCANNED_NETWORKS) - return; - - priv->rcvd_ch_cnt++; - - add_network_to_shadow(network_info, priv, join_params); - - if (memcmp("DIRECT-", network_info->ssid, 7)) - return; - - bss = cfg80211_inform_bss(wiphy, - channel, - CFG80211_BSS_FTYPE_UNKNOWN, - network_info->bssid, - network_info->tsf, - network_info->cap_info, - network_info->beacon_period, - (const u8 *)network_info->ies, - (size_t)network_info->ies_len, - (s32)network_info->rssi * 100, - GFP_KERNEL); + bss = cfg80211_inform_bss_frame(wiphy, channel, info->mgmt, + info->frame_len, + (s32)info->rssi * 100, + GFP_KERNEL); + if (!bss) cfg80211_put_bss(wiphy, bss); - } else { - u32 i; - - for (i = 0; i < priv->rcvd_ch_cnt; i++) { - if (memcmp(priv->scanned_shadow[i].bssid, - network_info->bssid, 6) == 0) - break; - } - - if (i >= priv->rcvd_ch_cnt) - return; - - priv->scanned_shadow[i].rssi = network_info->rssi; - priv->scanned_shadow[i].time_scan = jiffies; - } } else if (scan_event == SCAN_EVENT_DONE) { - refresh_scan(priv, false); - mutex_lock(&priv->scan_req_lock); if (priv->scan_req) { @@ -344,7 +117,6 @@ static void cfg_scan_result(enum scan_event scan_event, }; cfg80211_scan_done(priv->scan_req, &info); - priv->rcvd_ch_cnt = 0; priv->cfg_scanning = false; priv->scan_req = NULL; } @@ -357,9 +129,6 @@ static void cfg_scan_result(enum scan_event scan_event, .aborted = false, }; - update_scan_time(priv); - refresh_scan(priv, false); - cfg80211_scan_done(priv->scan_req, &info); priv->cfg_scanning = false; priv->scan_req = NULL; @@ -368,21 +137,7 @@ static void cfg_scan_result(enum scan_event scan_event, } } -static inline bool wilc_cfg_scan_time_expired(struct wilc_priv *priv, int i) -{ - unsigned long now = jiffies; - - if (time_after(now, priv->scanned_shadow[i].time_scan_cached + - (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) - return true; - else - return false; -} - -static void cfg_connect_result(enum conn_event conn_disconn_evt, - struct connect_info *conn_info, - u8 mac_status, - struct disconnect_info *disconn_info, +static void cfg_connect_result(enum conn_event conn_disconn_evt, u8 mac_status, void *priv_data) { struct wilc_priv *priv = priv_data; @@ -390,49 +145,28 @@ static void cfg_connect_result(enum conn_event conn_disconn_evt, struct wilc_vif *vif = netdev_priv(dev); struct wilc *wl = vif->wilc; struct host_if_drv *wfi_drv = priv->hif_drv; - u8 null_bssid[ETH_ALEN] = {0}; + struct wilc_conn_info *conn_info = &wfi_drv->conn_info; vif->connecting = false; if (conn_disconn_evt == CONN_DISCONN_EVENT_CONN_RESP) { - u16 connect_status; - - connect_status = conn_info->status; + u16 connect_status = conn_info->status; if (mac_status == WILC_MAC_STATUS_DISCONNECTED && - conn_info->status == WLAN_STATUS_SUCCESS) { + connect_status == WLAN_STATUS_SUCCESS) { connect_status = WLAN_STATUS_UNSPECIFIED_FAILURE; - wilc_wlan_set_bssid(priv->dev, null_bssid, - WILC_STATION_MODE); + wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE); - if (!wfi_drv->p2p_connect) - wlan_channel = INVALID_CHANNEL; + if (vif->iftype != WILC_CLIENT_MODE) + wl->sta_ch = WILC_INVALID_CHANNEL; netdev_err(dev, "Unspecified failure\n"); } - if (connect_status == WLAN_STATUS_SUCCESS) { - bool scan_refresh = false; - u32 i; - + if (connect_status == WLAN_STATUS_SUCCESS) memcpy(priv->associated_bss, conn_info->bssid, ETH_ALEN); - for (i = 0; i < priv->scanned_cnt; i++) { - if (memcmp(priv->scanned_shadow[i].bssid, - conn_info->bssid, - ETH_ALEN) == 0) { - if (wilc_cfg_scan_time_expired(priv, i)) - scan_refresh = true; - - break; - } - } - - if (scan_refresh) - refresh_scan(priv, true); - } - cfg80211_connect_result(dev, conn_info->bssid, conn_info->req_ies, conn_info->req_ies_len, @@ -440,23 +174,24 @@ static void cfg_connect_result(enum conn_event conn_disconn_evt, conn_info->resp_ies_len, connect_status, GFP_KERNEL); } else if (conn_disconn_evt == CONN_DISCONN_EVENT_DISCONN_NOTIF) { + u16 reason = 0; + vif->obtaining_ip = false; priv->p2p.local_random = 0x01; priv->p2p.recv_random = 0x00; priv->p2p.is_wilc_ie = false; eth_zero_addr(priv->associated_bss); - wilc_wlan_set_bssid(priv->dev, null_bssid, WILC_STATION_MODE); + wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE); + + if (vif->iftype != WILC_CLIENT_MODE) + wl->sta_ch = WILC_INVALID_CHANNEL; - if (!wfi_drv->p2p_connect) - wlan_channel = INVALID_CHANNEL; if (wfi_drv->ifc_up && dev == wl->vif[1]->ndev) - disconn_info->reason = 3; + reason = 3; else if (!wfi_drv->ifc_up && dev == wl->vif[1]->ndev) - disconn_info->reason = 1; + reason = 1; - cfg80211_disconnected(dev, disconn_info->reason, - disconn_info->ie, disconn_info->ie_len, - false, GFP_KERNEL); + cfg80211_disconnected(dev, reason, NULL, 0, false, GFP_KERNEL); } } @@ -470,7 +205,7 @@ static int set_channel(struct wiphy *wiphy, channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq); - curr_channel = channelnum; + vif->wilc->op_ch = channelnum; result = wilc_set_mac_chnl_num(vif, channelnum); if (result != 0) @@ -481,22 +216,23 @@ static int set_channel(struct wiphy *wiphy, static inline int wilc_wfi_cfg_alloc_fill_ssid(struct cfg80211_scan_request *request, - struct hidden_network *ntwk) + struct wilc_probe_ssid *search) { int i; int slot_id = 0; - ntwk->net_info = kcalloc(request->n_ssids, sizeof(*ntwk->net_info), - GFP_KERNEL); - if (!ntwk->net_info) + search->ssid_info = kcalloc(request->n_ssids, + sizeof(*search->ssid_info), GFP_KERNEL); + if (!search->ssid_info) goto out; - ntwk->n_ssids = request->n_ssids; + search->n_ssids = request->n_ssids; for (i = 0; i < request->n_ssids; i++) { if (request->ssids[i].ssid_len > 0) { - struct hidden_net_info *info = &ntwk->net_info[slot_id]; + struct wilc_probe_ssid_info *info; + info = &search->ssid_info[slot_id]; info->ssid = kmemdup(request->ssids[i].ssid, request->ssids[i].ssid_len, GFP_KERNEL); @@ -506,7 +242,7 @@ wilc_wfi_cfg_alloc_fill_ssid(struct cfg80211_scan_request *request, info->ssid_len = request->ssids[i].ssid_len; slot_id++; } else { - ntwk->n_ssids -= 1; + search->n_ssids -= 1; } } return 0; @@ -514,9 +250,9 @@ wilc_wfi_cfg_alloc_fill_ssid(struct cfg80211_scan_request *request, out_free: for (i = 0; i < slot_id; i++) - kfree(ntwk->net_info[i].ssid); + kfree(search->ssid_info[i].ssid); - kfree(ntwk->net_info); + kfree(search->ssid_info); out: return -ENOMEM; @@ -528,46 +264,41 @@ static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) struct wilc_vif *vif = netdev_priv(priv->dev); u32 i; int ret = 0; - u8 scan_ch_list[MAX_NUM_SCANNED_NETWORKS]; - struct hidden_network hidden_ntwk; - - priv->scan_req = request; + u8 scan_ch_list[WILC_MAX_NUM_SCANNED_CH]; + struct wilc_probe_ssid probe_ssid; - priv->rcvd_ch_cnt = 0; - - reset_shadow_found(priv); + if (request->n_channels > WILC_MAX_NUM_SCANNED_CH) { + netdev_err(priv->dev, "Requested scanned channels over\n"); + return -EINVAL; + } + priv->scan_req = request; priv->cfg_scanning = true; - if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) { - for (i = 0; i < request->n_channels; i++) { - u16 freq = request->channels[i]->center_freq; + for (i = 0; i < request->n_channels; i++) { + u16 freq = request->channels[i]->center_freq; - scan_ch_list[i] = ieee80211_frequency_to_channel(freq); - } - - if (request->n_ssids >= 1) { - if (wilc_wfi_cfg_alloc_fill_ssid(request, - &hidden_ntwk)) { - ret = -ENOMEM; - goto out; - } + scan_ch_list[i] = ieee80211_frequency_to_channel(freq); + } - ret = wilc_scan(vif, WILC_FW_USER_SCAN, - WILC_FW_ACTIVE_SCAN, scan_ch_list, - request->n_channels, - (const u8 *)request->ie, - request->ie_len, cfg_scan_result, - (void *)priv, &hidden_ntwk); - } else { - ret = wilc_scan(vif, WILC_FW_USER_SCAN, - WILC_FW_ACTIVE_SCAN, scan_ch_list, - request->n_channels, - (const u8 *)request->ie, - request->ie_len, cfg_scan_result, - (void *)priv, NULL); + if (request->n_ssids >= 1) { + if (wilc_wfi_cfg_alloc_fill_ssid(request, &probe_ssid)) { + ret = -ENOMEM; + goto out; } + + ret = wilc_scan(vif, WILC_FW_USER_SCAN, + WILC_FW_ACTIVE_SCAN, scan_ch_list, + request->n_channels, + (const u8 *)request->ie, + request->ie_len, cfg_scan_result, + (void *)priv, &probe_ssid); } else { - netdev_err(priv->dev, "Requested scanned channels over\n"); + ret = wilc_scan(vif, WILC_FW_USER_SCAN, + WILC_FW_ACTIVE_SCAN, scan_ch_list, + request->n_channels, + (const u8 *)request->ie, + request->ie_len, cfg_scan_result, + (void *)priv, NULL); } out: @@ -585,54 +316,17 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, struct wilc_priv *priv = wiphy_priv(wiphy); struct wilc_vif *vif = netdev_priv(priv->dev); struct host_if_drv *wfi_drv = priv->hif_drv; - struct network_info *nw_info; int ret; u32 i; - u32 sel_bssi_idx = UINT_MAX; u8 security = WILC_FW_SEC_NO; enum authtype auth_type = WILC_FW_AUTH_ANY; u32 cipher_group; + struct cfg80211_bss *bss; + void *join_params; + u8 ch; vif->connecting = true; - if (!(strncmp(sme->ssid, "DIRECT-", 7))) - wfi_drv->p2p_connect = 1; - else - wfi_drv->p2p_connect = 0; - - for (i = 0; i < priv->scanned_cnt; i++) { - if (sme->ssid_len == priv->scanned_shadow[i].ssid_len && - memcmp(priv->scanned_shadow[i].ssid, - sme->ssid, - sme->ssid_len) == 0) { - if (!sme->bssid) { - if (sel_bssi_idx == UINT_MAX || - priv->scanned_shadow[i].rssi > - priv->scanned_shadow[sel_bssi_idx].rssi) - sel_bssi_idx = i; - } else { - if (memcmp(priv->scanned_shadow[i].bssid, - sme->bssid, - ETH_ALEN) == 0) { - sel_bssi_idx = i; - break; - } - } - } - } - - if (sel_bssi_idx < priv->scanned_cnt) { - nw_info = &priv->scanned_shadow[sel_bssi_idx]; - } else { - ret = -ENOENT; - goto out_error; - } - - if (ether_addr_equal_unaligned(vif->bssid, nw_info->bssid)) { - ret = -EALREADY; - goto out_error; - } - memset(priv->wep_key, 0, sizeof(priv->wep_key)); memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len)); @@ -706,31 +400,65 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, auth_type = WILC_FW_AUTH_IEEE8021; } - curr_channel = nw_info->ch; + if (wfi_drv->usr_scan_req.scan_result) { + netdev_err(vif->ndev, "%s: Scan in progress\n", __func__); + ret = -EBUSY; + goto out_error; + } - if (!wfi_drv->p2p_connect) - wlan_channel = nw_info->ch; + bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, sme->ssid, + sme->ssid_len, IEEE80211_BSS_TYPE_ANY, + IEEE80211_PRIVACY(sme->privacy)); + if (!bss) { + ret = -EINVAL; + goto out_error; + } - wilc_wlan_set_bssid(dev, nw_info->bssid, WILC_STATION_MODE); + if (ether_addr_equal_unaligned(vif->bssid, bss->bssid)) { + ret = -EALREADY; + goto out_put_bss; + } - ret = wilc_set_join_req(vif, nw_info->bssid, sme->ssid, - sme->ssid_len, sme->ie, sme->ie_len, - cfg_connect_result, (void *)priv, - security, auth_type, - nw_info->ch, - nw_info->join_params); - if (ret) { - u8 null_bssid[ETH_ALEN] = {0}; + join_params = wilc_parse_join_bss_param(bss, &sme->crypto); + if (!join_params) { + netdev_err(dev, "%s: failed to construct join param\n", + __func__); + ret = -EINVAL; + goto out_put_bss; + } + + ch = ieee80211_frequency_to_channel(bss->channel->center_freq); + vif->wilc->op_ch = ch; + if (vif->iftype != WILC_CLIENT_MODE) + vif->wilc->sta_ch = ch; + + wilc_wlan_set_bssid(dev, bss->bssid, WILC_STATION_MODE); + wfi_drv->conn_info.security = security; + wfi_drv->conn_info.auth_type = auth_type; + wfi_drv->conn_info.ch = ch; + wfi_drv->conn_info.conn_result = cfg_connect_result; + wfi_drv->conn_info.arg = priv; + wfi_drv->conn_info.param = join_params; + + ret = wilc_set_join_req(vif, bss->bssid, sme->ie, sme->ie_len); + if (ret) { netdev_err(dev, "wilc_set_join_req(): Error\n"); ret = -ENOENT; - if (!wfi_drv->p2p_connect) - wlan_channel = INVALID_CHANNEL; - wilc_wlan_set_bssid(dev, null_bssid, WILC_STATION_MODE); - goto out_error; - } + if (vif->iftype != WILC_CLIENT_MODE) + vif->wilc->sta_ch = WILC_INVALID_CHANNEL; + wilc_wlan_set_bssid(dev, NULL, WILC_STATION_MODE); + wfi_drv->conn_info.conn_result = NULL; + kfree(join_params); + goto out_put_bss; + } + kfree(join_params); + cfg80211_put_bss(wiphy, bss); return 0; +out_put_bss: + cfg80211_put_bss(wiphy, bss); + out_error: vif->connecting = false; return ret; @@ -742,9 +470,7 @@ static int disconnect(struct wiphy *wiphy, struct net_device *dev, struct wilc_priv *priv = wiphy_priv(wiphy); struct wilc_vif *vif = netdev_priv(priv->dev); struct wilc *wilc = vif->wilc; - struct host_if_drv *wfi_drv; int ret; - u8 null_bssid[ETH_ALEN] = {0}; vif->connecting = false; @@ -757,15 +483,14 @@ static int disconnect(struct wiphy *wiphy, struct net_device *dev, return 0; } - wfi_drv = (struct host_if_drv *)priv->hif_drv; - if (!wfi_drv->p2p_connect) - wlan_channel = INVALID_CHANNEL; - wilc_wlan_set_bssid(priv->dev, null_bssid, WILC_STATION_MODE); + if (vif->iftype != WILC_CLIENT_MODE) + wilc->sta_ch = WILC_INVALID_CHANNEL; + wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE); priv->p2p.local_random = 0x01; priv->p2p.recv_random = 0x00; priv->p2p.is_wilc_ie = false; - wfi_drv->p2p_timeout = 0; + priv->hif_drv->p2p_timeout = 0; ret = wilc_disconnect(vif); if (ret != 0) { @@ -1210,7 +935,7 @@ static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) } static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u8 ch_list_attr_idx, - u8 op_ch_attr_idx) + u8 op_ch_attr_idx, u8 sta_ch) { int i = 0; int j = 0; @@ -1221,7 +946,7 @@ static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u8 ch_list_attr_idx, for (i = ch_list_attr_idx + 3; i < limit; i++) { if (buf[i] == 0x51) { for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) - buf[j] = wlan_channel; + buf[j] = sta_ch; break; } } @@ -1229,11 +954,11 @@ static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u8 ch_list_attr_idx, if (op_ch_attr_idx) { buf[op_ch_attr_idx + 6] = 0x51; - buf[op_ch_attr_idx + 7] = wlan_channel; + buf[op_ch_attr_idx + 7] = sta_ch; } } -static void wilc_wfi_cfg_parse_rx_action(u8 *buf, u32 len) +static void wilc_wfi_cfg_parse_rx_action(u8 *buf, u32 len, u8 sta_ch) { u32 index = 0; u8 op_channel_attr_index = 0; @@ -1249,13 +974,13 @@ static void wilc_wfi_cfg_parse_rx_action(u8 *buf, u32 len) op_channel_attr_index = index; index += buf[index + 1] + 3; } - if (wlan_channel != INVALID_CHANNEL) + if (sta_ch != WILC_INVALID_CHANNEL) wilc_wfi_cfg_parse_ch_attr(buf, channel_list_attr_index, - op_channel_attr_index); + op_channel_attr_index, sta_ch); } static void wilc_wfi_cfg_parse_tx_action(u8 *buf, u32 len, bool oper_ch, - u8 iftype) + u8 iftype, u8 sta_ch) { u32 index = 0; u8 op_channel_attr_index = 0; @@ -1274,9 +999,9 @@ static void wilc_wfi_cfg_parse_tx_action(u8 *buf, u32 len, bool oper_ch, op_channel_attr_index = index; index += buf[index + 1] + 3; } - if (wlan_channel != INVALID_CHANNEL && oper_ch) + if (sta_ch != WILC_INVALID_CHANNEL && oper_ch) wilc_wfi_cfg_parse_ch_attr(buf, channel_list_attr_index, - op_channel_attr_index); + op_channel_attr_index, sta_ch); } static void wilc_wfi_cfg_parse_rx_vendor_spec(struct wilc_priv *priv, u8 *buff, @@ -1311,7 +1036,8 @@ static void wilc_wfi_cfg_parse_rx_vendor_spec(struct wilc_priv *priv, u8 *buff, if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) { wilc_wfi_cfg_parse_rx_action(&buff[i + 6], - size - (i + 6)); + size - (i + 6), + vif->wilc->sta_ch); break; } } @@ -1322,6 +1048,8 @@ void wilc_wfi_p2p_rx(struct net_device *dev, u8 *buff, u32 size) { struct wilc_priv *priv = wiphy_priv(dev->ieee80211_ptr->wiphy); struct host_if_drv *wfi_drv = priv->hif_drv; + struct wilc_vif *vif = netdev_priv(dev); + struct wilc *wl = vif->wilc; u32 header, pkt_offset; s32 freq; __le16 fc; @@ -1342,7 +1070,7 @@ void wilc_wfi_p2p_rx(struct net_device *dev, u8 *buff, u32 size) return; } - freq = ieee80211_channel_to_frequency(curr_channel, NL80211_BAND_2GHZ); + freq = ieee80211_channel_to_frequency(wl->op_ch, NL80211_BAND_2GHZ); fc = ((struct ieee80211_hdr *)buff)->frame_control; if (!ieee80211_is_action(fc)) { @@ -1387,33 +1115,18 @@ void wilc_wfi_p2p_rx(struct net_device *dev, u8 *buff, u32 size) static void wilc_wfi_mgmt_tx_complete(void *priv, int status) { - struct p2p_mgmt_data *pv_data = priv; + struct wilc_p2p_mgmt_data *pv_data = priv; kfree(pv_data->buff); kfree(pv_data); } -static void wilc_wfi_remain_on_channel_ready(void *priv_data) -{ - struct wilc_priv *priv; - - priv = priv_data; - - priv->p2p_listen_state = true; - - cfg80211_ready_on_channel(priv->wdev, - priv->remain_on_ch_params.listen_cookie, - priv->remain_on_ch_params.listen_ch, - priv->remain_on_ch_params.listen_duration, - GFP_KERNEL); -} - -static void wilc_wfi_remain_on_channel_expired(void *data, u32 session_id) +static void wilc_wfi_remain_on_channel_expired(void *data, u64 cookie) { struct wilc_priv *priv = data; struct wilc_wfi_p2p_listen_params *params = &priv->remain_on_ch_params; - if (session_id != params->listen_session_id) + if (cookie != params->listen_cookie) return; priv->p2p_listen_state = false; @@ -1430,24 +1143,36 @@ static int remain_on_channel(struct wiphy *wiphy, int ret = 0; struct wilc_priv *priv = wiphy_priv(wiphy); struct wilc_vif *vif = netdev_priv(priv->dev); + u64 id; if (wdev->iftype == NL80211_IFTYPE_AP) { netdev_dbg(vif->ndev, "Required while in AP mode\n"); return ret; } - curr_channel = chan->hw_value; + id = ++priv->inc_roc_cookie; + if (id == 0) + id = ++priv->inc_roc_cookie; + + ret = wilc_remain_on_channel(vif, id, duration, chan->hw_value, + wilc_wfi_remain_on_channel_expired, + (void *)priv); + if (ret) + return ret; + + vif->wilc->op_ch = chan->hw_value; priv->remain_on_ch_params.listen_ch = chan; - priv->remain_on_ch_params.listen_cookie = *cookie; + priv->remain_on_ch_params.listen_cookie = id; + *cookie = id; + priv->p2p_listen_state = true; priv->remain_on_ch_params.listen_duration = duration; - priv->remain_on_ch_params.listen_session_id++; - return wilc_remain_on_channel(vif, - priv->remain_on_ch_params.listen_session_id, - duration, chan->hw_value, - wilc_wfi_remain_on_channel_expired, - wilc_wfi_remain_on_channel_ready, (void *)priv); + cfg80211_ready_on_channel(wdev, *cookie, chan, duration, GFP_KERNEL); + mod_timer(&vif->hif_drv->remain_on_ch_timer, + jiffies + msecs_to_jiffies(duration)); + + return ret; } static int cancel_remain_on_channel(struct wiphy *wiphy, @@ -1457,12 +1182,14 @@ static int cancel_remain_on_channel(struct wiphy *wiphy, struct wilc_priv *priv = wiphy_priv(wiphy); struct wilc_vif *vif = netdev_priv(priv->dev); - return wilc_listen_state_expired(vif, - priv->remain_on_ch_params.listen_session_id); + if (cookie != priv->remain_on_ch_params.listen_cookie) + return -ENOENT; + + return wilc_listen_state_expired(vif, cookie); } static void wilc_wfi_cfg_tx_vendor_spec(struct wilc_priv *priv, - struct p2p_mgmt_data *mgmt_tx, + struct wilc_p2p_mgmt_data *mgmt_tx, struct cfg80211_mgmt_tx_params *params, u8 iftype, u32 buf_len) { @@ -1470,6 +1197,7 @@ static void wilc_wfi_cfg_tx_vendor_spec(struct wilc_priv *priv, size_t len = params->len; u32 i; u8 subtype = buf[P2P_PUB_ACTION_SUBTYPE]; + struct wilc_vif *vif = netdev_priv(priv->dev); if (subtype == GO_NEG_REQ || subtype == GO_NEG_RSP) { if (priv->p2p.local_random == 1 && @@ -1494,7 +1222,8 @@ static void wilc_wfi_cfg_tx_vendor_spec(struct wilc_priv *priv, oper_ch = true; wilc_wfi_cfg_parse_tx_action(tx_buff, len - (i + 6), - oper_ch, iftype); + oper_ch, iftype, + vif->wilc->sta_ch); break; } @@ -1520,14 +1249,14 @@ static int mgmt_tx(struct wiphy *wiphy, const u8 *buf = params->buf; size_t len = params->len; const struct ieee80211_mgmt *mgmt; - struct p2p_mgmt_data *mgmt_tx; + struct wilc_p2p_mgmt_data *mgmt_tx; struct wilc_priv *priv = wiphy_priv(wiphy); struct host_if_drv *wfi_drv = priv->hif_drv; struct wilc_vif *vif = netdev_priv(wdev->netdev); u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(priv->p2p.local_random); int ret = 0; - *cookie = (unsigned long)buf; + *cookie = prandom_u32(); priv->tx_cookie = *cookie; mgmt = (const struct ieee80211_mgmt *)buf; @@ -1552,7 +1281,7 @@ static int mgmt_tx(struct wiphy *wiphy, if (ieee80211_is_probe_resp(mgmt->frame_control)) { wilc_set_mac_chnl_num(vif, chan->hw_value); - curr_channel = chan->hw_value; + vif->wilc->op_ch = chan->hw_value; goto out_txq_add_pkt; } @@ -1563,7 +1292,7 @@ static int mgmt_tx(struct wiphy *wiphy, if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC || buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) { wilc_set_mac_chnl_num(vif, chan->hw_value); - curr_channel = chan->hw_value; + vif->wilc->op_ch = chan->hw_value; } switch (buf[ACTION_SUBTYPE_ID]) { case GAS_INITIAL_REQ: @@ -1755,7 +1484,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, case NL80211_IFTYPE_P2P_GO: vif->obtaining_ip = true; mod_timer(&vif->during_ip_timer, - jiffies + msecs_to_jiffies(DURING_IP_TIME_OUT)); + jiffies + msecs_to_jiffies(WILC_IP_TIMEOUT_MS)); wilc_set_operation_mode(vif, WILC_AP_MODE); dev->ieee80211_ptr->iftype = type; priv->wdev->iftype = type; @@ -1805,9 +1534,8 @@ static int stop_ap(struct wiphy *wiphy, struct net_device *dev) int ret; struct wilc_priv *priv = wiphy_priv(wiphy); struct wilc_vif *vif = netdev_priv(priv->dev); - u8 null_bssid[ETH_ALEN] = {0}; - wilc_wlan_set_bssid(dev, null_bssid, WILC_AP_MODE); + wilc_wlan_set_bssid(dev, NULL, WILC_AP_MODE); ret = wilc_del_beacon(vif); @@ -1884,7 +1612,8 @@ static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy, struct net_device *new_ifc; if (type == NL80211_IFTYPE_MONITOR) { - new_ifc = wilc_wfi_init_mon_interface(name, vif->ndev); + new_ifc = wilc_wfi_init_mon_interface(vif->wilc, name, + vif->ndev); if (new_ifc) { vif = netdev_priv(priv->wdev->netdev); vif->monitor_flag = 1; @@ -2102,7 +1831,6 @@ int wilc_init_host_int(struct net_device *net) struct wilc_priv *priv = wdev_priv(net->ieee80211_ptr); struct wilc_vif *vif = netdev_priv(priv->dev); - timer_setup(&priv->aging_timer, remove_network_from_shadow, 0); timer_setup(&vif->during_ip_timer, clear_during_ip, 0); priv->p2p_listen_state = false; @@ -2126,8 +1854,6 @@ void wilc_deinit_host_int(struct net_device *net) mutex_destroy(&priv->scan_req_lock); ret = wilc_deinit(vif); - del_timer_sync(&priv->aging_timer); - clear_shadow_scan(priv); del_timer_sync(&vif->during_ip_timer); if (ret) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h index 4812c8e2c79b..31dfa1f141f1 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h @@ -13,9 +13,10 @@ struct wireless_dev *wilc_create_wiphy(struct net_device *net, void wilc_free_wiphy(struct net_device *net); void wilc_deinit_host_int(struct net_device *net); int wilc_init_host_int(struct net_device *net); -void wilc_wfi_monitor_rx(u8 *buff, u32 size); -void wilc_wfi_deinit_mon_interface(void); -struct net_device *wilc_wfi_init_mon_interface(const char *name, +void wilc_wfi_monitor_rx(struct net_device *mon_dev, u8 *buff, u32 size); +void wilc_wfi_deinit_mon_interface(struct wilc *wl); +struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl, + const char *name, struct net_device *real_dev); void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, u16 frame_type, bool reg); diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index c6685c0c238b..df00762487c0 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -65,7 +65,6 @@ struct wilc_wfi_p2p_listen_params { struct ieee80211_channel *listen_ch; u32 listen_duration; u64 listen_cookie; - u32 listen_session_id; }; struct wilc_p2p_var { @@ -137,7 +136,6 @@ struct wilc_priv { u64 tx_cookie; bool cfg_scanning; - u32 rcvd_ch_cnt; u8 associated_bss[ETH_ALEN]; struct sta_info assoc_stainfo; @@ -155,8 +153,6 @@ struct wilc_priv { /* mutexes */ struct mutex scan_req_lock; bool p2p_listen_state; - struct timer_list aging_timer; - struct network_info scanned_shadow[MAX_NUM_SCANNED_NETWORKS_SHADOW]; int scanned_cnt; struct wilc_p2p_var p2p; @@ -164,6 +160,7 @@ struct wilc_priv { struct ieee80211_rate bitrates[ARRAY_SIZE(wilc_bitrates)]; struct ieee80211_supported_band band; u32 cipher_suites[ARRAY_SIZE(wilc_cipher_suites)]; + u64 inc_roc_cookie; }; struct frame_reg { @@ -251,7 +248,7 @@ struct wilc { struct mutex cfg_cmd_lock; struct wilc_cfg_frame cfg_frame; u32 cfg_frame_offset; - int cfg_seq_no; + u8 cfg_seq_no; u8 *rx_buffer; u32 rx_buffer_offset; @@ -273,13 +270,18 @@ struct wilc { enum chip_ps_states chip_ps_state; struct wilc_cfg cfg; void *bus_data; + struct net_device *monitor_dev; + /* deinit lock */ + struct mutex deinit_lock; + u8 sta_ch; + u8 op_ch; }; struct wilc_wfi_mon_priv { struct net_device *real_ndev; }; -void wilc_frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset); +void wilc_frmw_to_host(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset); void wilc_mac_indicate(struct wilc *wilc); void wilc_netdev_cleanup(struct wilc *wilc); int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 489e5a5038f8..c2389695fe20 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -274,7 +274,8 @@ static int wilc_wlan_txq_add_cfg_pkt(struct wilc_vif *vif, u8 *buffer, } int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, - u32 buffer_size, wilc_tx_complete_func_t func) + u32 buffer_size, + void (*tx_complete_fn)(void *, int)) { struct txq_entry_t *tqe; struct wilc_vif *vif = netdev_priv(dev); @@ -292,7 +293,7 @@ int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, tqe->type = WILC_NET_PKT; tqe->buffer = buffer; tqe->buffer_size = buffer_size; - tqe->tx_complete_func = func; + tqe->tx_complete_func = tx_complete_fn; tqe->priv = priv; tqe->ack_idx = NOT_TCP_ACK; @@ -303,7 +304,8 @@ int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, } int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, - u32 buffer_size, wilc_tx_complete_func_t func) + u32 buffer_size, + void (*tx_complete_fn)(void *, int)) { struct txq_entry_t *tqe; struct wilc_vif *vif = netdev_priv(dev); @@ -321,7 +323,7 @@ int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, tqe->type = WILC_MGMT_PKT; tqe->buffer = buffer; tqe->buffer_size = buffer_size; - tqe->tx_complete_func = func; + tqe->tx_complete_func = tx_complete_fn; tqe->priv = priv; tqe->ack_idx = NOT_TCP_ACK; wilc_wlan_txq_add_to_tail(dev, tqe); @@ -521,7 +523,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) if (vmm_sz & 0x3) vmm_sz = (vmm_sz + 4) & ~0x3; - if ((sum + vmm_sz) > LINUX_TX_SIZE) + if ((sum + vmm_sz) > WILC_TX_BUFF_SIZE) break; vmm_table[i] = vmm_sz / 4; @@ -715,9 +717,8 @@ static void wilc_wlan_handle_rx_buff(struct wilc *wilc, u8 *buffer, int size) } else { if (!is_cfg_packet) { if (pkt_len > 0) { - wilc_frmw_to_linux(wilc, buff_ptr, - pkt_len, - pkt_offset); + wilc_frmw_to_host(wilc, buff_ptr, + pkt_len, pkt_offset); } } else { struct wilc_cfg_rsp rsp; @@ -809,7 +810,7 @@ static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status) if (size <= 0) return; - if (LINUX_RX_SIZE - offset < size) + if (WILC_RX_BUFF_SIZE - offset < size) offset = 0; buffer = &wilc->rx_buffer[offset]; @@ -1092,24 +1093,19 @@ static int wilc_wlan_cfg_commit(struct wilc_vif *vif, int type, { struct wilc *wilc = vif->wilc; struct wilc_cfg_frame *cfg = &wilc->cfg_frame; - int total_len = wilc->cfg_frame_offset + 4 + DRIVER_HANDLER_SIZE; - int seq_no = wilc->cfg_seq_no % 256; - int driver_handler = (u32)drv_handler; + int t_len = wilc->cfg_frame_offset + sizeof(struct wilc_cfg_cmd_hdr); if (type == WILC_CFG_SET) - cfg->wid_header[0] = 'W'; + cfg->hdr.cmd_type = 'W'; else - cfg->wid_header[0] = 'Q'; - cfg->wid_header[1] = seq_no; - cfg->wid_header[2] = (u8)total_len; - cfg->wid_header[3] = (u8)(total_len >> 8); - cfg->wid_header[4] = (u8)driver_handler; - cfg->wid_header[5] = (u8)(driver_handler >> 8); - cfg->wid_header[6] = (u8)(driver_handler >> 16); - cfg->wid_header[7] = (u8)(driver_handler >> 24); - wilc->cfg_seq_no = seq_no; - - if (!wilc_wlan_txq_add_cfg_pkt(vif, &cfg->wid_header[0], total_len)) + cfg->hdr.cmd_type = 'Q'; + + cfg->hdr.seq_no = wilc->cfg_seq_no % 256; + cfg->hdr.total_len = cpu_to_le16(t_len); + cfg->hdr.driver_handler = cpu_to_le32(drv_handler); + wilc->cfg_seq_no = cfg->hdr.seq_no; + + if (!wilc_wlan_txq_add_cfg_pkt(vif, (u8 *)&cfg->hdr, t_len)) return -1; return 0; @@ -1144,7 +1140,7 @@ int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u16 wid, u8 *buffer, ret_size = 0; if (!wait_for_completion_timeout(&wilc->cfg_event, - msecs_to_jiffies(CFG_PKTS_TIMEOUT))) { + WILC_CFG_PKTS_TIMEOUT)) { netdev_dbg(vif->ndev, "%s: Timed Out\n", __func__); ret_size = 0; } @@ -1182,7 +1178,7 @@ int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u16 wid, int commit, ret_size = 0; if (!wait_for_completion_timeout(&wilc->cfg_event, - msecs_to_jiffies(CFG_PKTS_TIMEOUT))) { + WILC_CFG_PKTS_TIMEOUT)) { netdev_dbg(vif->ndev, "%s: Timed Out\n", __func__); ret_size = 0; } @@ -1317,7 +1313,7 @@ int wilc_wlan_init(struct net_device *dev) } if (!wilc->tx_buffer) - wilc->tx_buffer = kmalloc(LINUX_TX_SIZE, GFP_KERNEL); + wilc->tx_buffer = kmalloc(WILC_TX_BUFF_SIZE, GFP_KERNEL); if (!wilc->tx_buffer) { ret = -ENOBUFS; @@ -1325,7 +1321,7 @@ int wilc_wlan_init(struct net_device *dev) } if (!wilc->rx_buffer) - wilc->rx_buffer = kmalloc(LINUX_RX_SIZE, GFP_KERNEL); + wilc->rx_buffer = kmalloc(WILC_RX_BUFF_SIZE, GFP_KERNEL); if (!wilc->rx_buffer) { ret = -ENOBUFS; diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index 27667131de1a..1a27f62589a2 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -14,7 +14,6 @@ * Mac eth header length * ********************************************/ -#define DRIVER_HANDLER_SIZE 4 #define MAX_MAC_HDR_LEN 26 /* QOS_MAC_HDR_LEN */ #define SUB_MSDU_HEADER_LENGTH 14 #define SNAP_HDR_LEN 8 @@ -132,8 +131,8 @@ #define WILC_PLL_TO_SPI 2 #define ABORT_INT BIT(31) -#define LINUX_RX_SIZE (96 * 1024) -#define LINUX_TX_SIZE (64 * 1024) +#define WILC_RX_BUFF_SIZE (96 * 1024) +#define WILC_TX_BUFF_SIZE (64 * 1024) #define MODALIAS "WILC_SPI" #define GPIO_NUM 0x44 @@ -197,7 +196,7 @@ #define ENABLE_RX_VMM (SEL_VMM_TBL1 | EN_VMM) #define ENABLE_TX_VMM (SEL_VMM_TBL0 | EN_VMM) /*time for expiring the completion of cfg packets*/ -#define CFG_PKTS_TIMEOUT 2000 +#define WILC_CFG_PKTS_TIMEOUT msecs_to_jiffies(2000) #define IS_MANAGMEMENT 0x100 #define IS_MANAGMEMENT_CALLBACK 0x080 @@ -249,16 +248,30 @@ struct wilc_hif_func { void (*disable_interrupt)(struct wilc *nic); }; -#define MAX_CFG_FRAME_SIZE 1468 +#define WILC_MAX_CFG_FRAME_SIZE 1468 + +struct tx_complete_data { + int size; + void *buff; + u8 *bssid; + struct sk_buff *skb; +}; + +struct wilc_cfg_cmd_hdr { + u8 cmd_type; + u8 seq_no; + __le16 total_len; + __le32 driver_handler; +}; struct wilc_cfg_frame { - u8 wid_header[8]; - u8 frame[MAX_CFG_FRAME_SIZE]; + struct wilc_cfg_cmd_hdr hdr; + u8 frame[WILC_MAX_CFG_FRAME_SIZE]; }; struct wilc_cfg_rsp { - int type; - u32 seq_no; + u8 type; + u8 seq_no; }; struct wilc; @@ -269,7 +282,8 @@ int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer, int wilc_wlan_start(struct wilc *wilc); int wilc_wlan_stop(struct wilc *wilc); int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, - u32 buffer_size, wilc_tx_complete_func_t func); + u32 buffer_size, + void (*tx_complete_fn)(void *, int)); int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count); void wilc_handle_isr(struct wilc *wilc); void wilc_wlan_cleanup(struct net_device *dev); @@ -280,7 +294,7 @@ int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u16 wid, int commit, int wilc_wlan_cfg_get_val(struct wilc *wl, u16 wid, u8 *buffer, u32 buffer_size); int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, - u32 buffer_size, wilc_tx_complete_func_t func); + u32 buffer_size, void (*func)(void *, int)); void wilc_chip_sleep_manually(struct wilc *wilc); void wilc_enable_tcp_ack_filter(struct wilc_vif *vif, bool value); @@ -294,4 +308,6 @@ void chip_allow_sleep(struct wilc *wilc); void chip_wakeup(struct wilc *wilc); int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids, u32 count, u32 drv); +int wilc_wlan_init(struct net_device *dev); +u32 wilc_get_chipid(struct wilc *wilc, bool update); #endif diff --git a/drivers/staging/wilc1000/wilc_wlan_cfg.c b/drivers/staging/wilc1000/wilc_wlan_cfg.c index 8390766358da..9dc5de4eb08d 100644 --- a/drivers/staging/wilc1000/wilc_wlan_cfg.c +++ b/drivers/staging/wilc1000/wilc_wlan_cfg.c @@ -54,7 +54,7 @@ static int wilc_wlan_cfg_set_byte(u8 *frame, u32 offset, u16 id, u8 val8) { u8 *buf; - if ((offset + 4) >= MAX_CFG_FRAME_SIZE) + if ((offset + 4) >= WILC_MAX_CFG_FRAME_SIZE) return 0; buf = &frame[offset]; @@ -71,7 +71,7 @@ static int wilc_wlan_cfg_set_hword(u8 *frame, u32 offset, u16 id, u16 val16) { u8 *buf; - if ((offset + 5) >= MAX_CFG_FRAME_SIZE) + if ((offset + 5) >= WILC_MAX_CFG_FRAME_SIZE) return 0; buf = &frame[offset]; @@ -90,7 +90,7 @@ static int wilc_wlan_cfg_set_word(u8 *frame, u32 offset, u16 id, u32 val32) { u8 *buf; - if ((offset + 7) >= MAX_CFG_FRAME_SIZE) + if ((offset + 7) >= WILC_MAX_CFG_FRAME_SIZE) return 0; buf = &frame[offset]; @@ -112,7 +112,7 @@ static int wilc_wlan_cfg_set_str(u8 *frame, u32 offset, u16 id, u8 *str, { u8 *buf; - if ((offset + size + 4) >= MAX_CFG_FRAME_SIZE) + if ((offset + size + 4) >= WILC_MAX_CFG_FRAME_SIZE) return 0; buf = &frame[offset]; @@ -134,7 +134,7 @@ static int wilc_wlan_cfg_set_bin(u8 *frame, u32 offset, u16 id, u8 *b, u32 size) u32 i; u8 checksum = 0; - if ((offset + size + 5) >= MAX_CFG_FRAME_SIZE) + if ((offset + size + 5) >= WILC_MAX_CFG_FRAME_SIZE) return 0; buf = &frame[offset]; @@ -168,7 +168,7 @@ static void wilc_wlan_parse_response_frame(struct wilc *wl, u8 *info, int size) while (size > 0) { i = 0; - wid = info[0] | (info[1] << 8); + wid = get_unaligned_le16(info); switch (GET_WID_TYPE(wid)) { case WID_CHAR: @@ -187,12 +187,13 @@ static void wilc_wlan_parse_response_frame(struct wilc *wl, u8 *info, int size) case WID_SHORT: do { - if (wl->cfg.hw[i].id == WID_NIL) + struct wilc_cfg_hword *hw = &wl->cfg.hw[i]; + + if (hw->id == WID_NIL) break; - if (wl->cfg.hw[i].id == wid) { - wl->cfg.hw[i].val = (info[4] | - (info[5] << 8)); + if (hw->id == wid) { + hw->val = get_unaligned_le16(&info[4]); break; } i++; @@ -202,14 +203,13 @@ static void wilc_wlan_parse_response_frame(struct wilc *wl, u8 *info, int size) case WID_INT: do { - if (wl->cfg.w[i].id == WID_NIL) + struct wilc_cfg_word *w = &wl->cfg.w[i]; + + if (w->id == WID_NIL) break; - if (wl->cfg.w[i].id == wid) { - wl->cfg.w[i].val = (info[4] | - (info[5] << 8) | - (info[6] << 16) | - (info[7] << 24)); + if (w->id == wid) { + w->val = get_unaligned_le32(&info[4]); break; } i++; @@ -244,7 +244,7 @@ static void wilc_wlan_parse_info_frame(struct wilc *wl, u8 *info) { u32 wid, len; - wid = info[0] | (info[1] << 8); + wid = get_unaligned_le16(info); len = info[2]; @@ -309,7 +309,7 @@ int wilc_wlan_cfg_get_wid(u8 *frame, u32 offset, u16 id) { u8 *buf; - if ((offset + 2) >= MAX_CFG_FRAME_SIZE) + if ((offset + 2) >= WILC_MAX_CFG_FRAME_SIZE) return 0; buf = &frame[offset]; @@ -371,8 +371,7 @@ int wilc_wlan_cfg_get_wid_value(struct wilc *wl, u16 wid, u8 *buffer, break; if (id == wid) { - u32 size = (wl->cfg.s[i].str[0] | - (wl->cfg.s[i].str[1] << 8)); + u16 size = get_unaligned_le16(wl->cfg.s[i].str); if (buffer_size >= size) { memcpy(buffer, &wl->cfg.s[i].str[2], diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h b/drivers/staging/wilc1000/wilc_wlan_if.h index e2310d860291..b15de36e32e0 100644 --- a/drivers/staging/wilc1000/wilc_wlan_if.h +++ b/drivers/staging/wilc1000/wilc_wlan_if.h @@ -11,44 +11,9 @@ /******************************************** * - * Host Interface Defines - * - ********************************************/ - -enum { - WILC_HIF_SDIO = 0, - WILC_HIF_SPI = BIT(0) -}; - -/******************************************** - * - * Wlan Interface Defines - * - ********************************************/ - -enum { - WILC_MAC_STATUS_INIT = -1, - WILC_MAC_STATUS_DISCONNECTED = 0, - WILC_MAC_STATUS_CONNECTED = 1 -}; - -struct tx_complete_data { - int size; - void *buff; - u8 *bssid; - struct sk_buff *skb; -}; - -typedef void (*wilc_tx_complete_func_t)(void *, int); - -/******************************************** - * * Wlan Configuration ID * ********************************************/ -#define WILC_MULTICAST_TABLE_SIZE 8 -#define MAX_SSID_LEN 33 -#define MAX_RATES_SUPPORTED 12 enum bss_types { WILC_FW_BSS_TYPE_INFRA = 0, @@ -689,7 +654,6 @@ enum { WID_TX_POWER_LEVEL_11N = 0x00B1, /* Custom Character WID list */ - WID_PC_TEST_MODE = 0x00C8, /* SCAN Complete notification WID*/ WID_SCAN_COMPLETE = 0x00C9, @@ -836,8 +800,4 @@ enum { WID_MAX = 0xFFFF }; -struct wilc; -int wilc_wlan_init(struct net_device *dev); -u32 wilc_get_chipid(struct wilc *wilc, bool update); - #endif diff --git a/drivers/staging/wlan-ng/Kconfig b/drivers/staging/wlan-ng/Kconfig index 426d4efbabc3..97238018b315 100644 --- a/drivers/staging/wlan-ng/Kconfig +++ b/drivers/staging/wlan-ng/Kconfig @@ -4,7 +4,7 @@ config PRISM2_USB select WIRELESS_EXT select WEXT_PRIV default n - ---help--- + help This is the wlan-ng prism 2.5/3 USB driver for a wide range of old USB wireless devices. diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c index e5d7def1f366..8a862f718d5c 100644 --- a/drivers/staging/wlan-ng/cfg80211.c +++ b/drivers/staging/wlan-ng/cfg80211.c @@ -70,7 +70,8 @@ static int prism2_result2err(int prism2_result) return err; } -static int prism2_domibset_uint32(struct wlandevice *wlandev, u32 did, u32 data) +static int prism2_domibset_uint32(struct wlandevice *wlandev, + u32 did, u32 data) { struct p80211msg_dot11req_mibset msg; struct p80211item_uint32 *mibitem = diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c index bb572b7fdfee..94800c007162 100644 --- a/drivers/staging/wlan-ng/prism2fw.c +++ b/drivers/staging/wlan-ng/prism2fw.c @@ -556,10 +556,9 @@ static int mkimage(struct imgchunk *clist, unsigned int *ccnt) /* Allocate buffer space for chunks */ for (i = 0; i < *ccnt; i++) { clist[i].data = kzalloc(clist[i].len, GFP_KERNEL); - if (!clist[i].data) { - pr_err("failed to allocate image space, exiting.\n"); + if (!clist[i].data) return 1; - } + pr_debug("chunk[%d]: addr=0x%06x len=%d\n", i, clist[i].addr, clist[i].len); } diff --git a/drivers/staging/xgifb/Kconfig b/drivers/staging/xgifb/Kconfig deleted file mode 100644 index bb0ca5974ea0..000000000000 --- a/drivers/staging/xgifb/Kconfig +++ /dev/null @@ -1,11 +0,0 @@ -config FB_XGI - tristate "XGI display support" - depends on FB && PCI - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This driver supports notebooks with XGI Z7,Z9,Z11 PCI chips. - Say Y if you have such a graphics card. - To compile this driver as a module, choose M here: the - module will be called xgifb.ko diff --git a/drivers/staging/xgifb/Makefile b/drivers/staging/xgifb/Makefile deleted file mode 100644 index 964a843c4521..000000000000 --- a/drivers/staging/xgifb/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -obj-$(CONFIG_FB_XGI) += xgifb.o - -xgifb-y := XGI_main_26.o vb_init.o vb_setmode.o - diff --git a/drivers/staging/xgifb/TODO b/drivers/staging/xgifb/TODO deleted file mode 100644 index 7eb99140a399..000000000000 --- a/drivers/staging/xgifb/TODO +++ /dev/null @@ -1,13 +0,0 @@ -This drivers still needs a lot of work. I can list all cleanups to do but it's -going to be long. So, I'm writing "cleanups" and not the list. - -Arnaud - -TODO: -- clean ups -- sort out dup ids with SiS driver -- remove useless/wrong/unused code... -- get rid of non-linux related stuff - -Please send patches to: -Arnaud Patard <arnaud.patard@rtp-net.org> diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h deleted file mode 100644 index e19a8291cb2a..000000000000 --- a/drivers/staging/xgifb/XGI_main.h +++ /dev/null @@ -1,365 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _XGIFB_MAIN -#define _XGIFB_MAIN -/* ------------------- Constant Definitions ------------------------- */ -#include "XGIfb.h" -#include "vb_def.h" - -#define PCI_DEVICE_ID_XGI_42 0x042 -#define PCI_DEVICE_ID_XGI_27 0x027 - -static const struct pci_device_id xgifb_pci_table[] = { - {PCI_DEVICE(PCI_VENDOR_ID_XGI, PCI_DEVICE_ID_XGI_20)}, - {PCI_DEVICE(PCI_VENDOR_ID_XGI, PCI_DEVICE_ID_XGI_27)}, - {PCI_DEVICE(PCI_VENDOR_ID_XGI, PCI_DEVICE_ID_XGI_40)}, - {PCI_DEVICE(PCI_VENDOR_ID_XGI, PCI_DEVICE_ID_XGI_42)}, - {0} -}; - -MODULE_DEVICE_TABLE(pci, xgifb_pci_table); - -#define IND_XGI_SCRATCH_REG_CR30 0x30 /* CRs */ -#define IND_XGI_SCRATCH_REG_CR31 0x31 -#define IND_XGI_SCRATCH_REG_CR32 0x32 -#define IND_XGI_SCRATCH_REG_CR33 0x33 -#define IND_XGI_LCD_PANEL 0x36 -#define IND_XGI_SCRATCH_REG_CR37 0x37 - -#define XGI_DRAM_SIZE_MASK 0xF0 /*SR14 */ -#define XGI_DRAM_SIZE_1MB 0x00 -#define XGI_DRAM_SIZE_2MB 0x01 -#define XGI_DRAM_SIZE_4MB 0x02 -#define XGI_DRAM_SIZE_8MB 0x03 -#define XGI_DRAM_SIZE_16MB 0x04 -#define XGI_DRAM_SIZE_32MB 0x05 -#define XGI_DRAM_SIZE_64MB 0x06 -#define XGI_DRAM_SIZE_128MB 0x07 -#define XGI_DRAM_SIZE_256MB 0x08 - -/* ------------------- Global Variables ----------------------------- */ - -/* display status */ -static int XGIfb_crt1off; -static int XGIfb_forcecrt1 = -1; - -/* global flags */ -static int XGIfb_tvmode; -static int enable_dstn; -static int XGIfb_ypan = -1; - -/* TW: CRT2 type (for overriding autodetection) */ -static int XGIfb_crt2type = -1; -/* PR: Tv plug type (for overriding autodetection) */ -static int XGIfb_tvplug = -1; - -#define MD_XGI315 1 - -/* mode table */ -static const struct _XGIbios_mode { - u8 mode_no; - u16 vesa_mode_no_1; /* "XGI defined" VESA mode number */ - u16 vesa_mode_no_2; /* Real VESA mode numbers */ - u16 xres; - u16 yres; - u16 bpp; - u8 chipset; -} XGIbios_mode[] = { - { 0x56, 0x0000, 0x0000, 320, 240, 16, MD_XGI315 }, - { 0x5A, 0x0000, 0x0000, 320, 480, 8, MD_XGI315 }, - { 0x5B, 0x0000, 0x0000, 320, 480, 16, MD_XGI315 }, - { 0x2E, 0x0101, 0x0101, 640, 480, 8, MD_XGI315 }, - { 0x44, 0x0111, 0x0111, 640, 480, 16, MD_XGI315 }, - { 0x62, 0x013a, 0x0112, 640, 480, 32, MD_XGI315 }, - { 0x31, 0x0000, 0x0000, 720, 480, 8, MD_XGI315 }, - { 0x33, 0x0000, 0x0000, 720, 480, 16, MD_XGI315 }, - { 0x35, 0x0000, 0x0000, 720, 480, 32, MD_XGI315 }, - { 0x32, 0x0000, 0x0000, 720, 576, 8, MD_XGI315 }, - { 0x34, 0x0000, 0x0000, 720, 576, 16, MD_XGI315 }, - { 0x36, 0x0000, 0x0000, 720, 576, 32, MD_XGI315 }, - { 0x36, 0x0000, 0x0000, 720, 576, 32, MD_XGI315 }, - { 0x70, 0x0000, 0x0000, 800, 480, 8, MD_XGI315 }, - { 0x7a, 0x0000, 0x0000, 800, 480, 16, MD_XGI315 }, - { 0x76, 0x0000, 0x0000, 800, 480, 32, MD_XGI315 }, - { 0x30, 0x0103, 0x0103, 800, 600, 8, MD_XGI315 }, -#define DEFAULT_MODE 17 /* index for 800x600x16 */ - { 0x47, 0x0114, 0x0114, 800, 600, 16, MD_XGI315 }, - { 0x63, 0x013b, 0x0115, 800, 600, 32, MD_XGI315 }, - { 0x71, 0x0000, 0x0000, 1024, 576, 8, MD_XGI315 }, - { 0x74, 0x0000, 0x0000, 1024, 576, 16, MD_XGI315 }, - { 0x77, 0x0000, 0x0000, 1024, 576, 32, MD_XGI315 }, - { 0x77, 0x0000, 0x0000, 1024, 576, 32, MD_XGI315 }, - { 0x20, 0x0000, 0x0000, 1024, 600, 8, }, - { 0x21, 0x0000, 0x0000, 1024, 600, 16, }, - { 0x22, 0x0000, 0x0000, 1024, 600, 32, }, - { 0x38, 0x0105, 0x0105, 1024, 768, 8, MD_XGI315 }, - { 0x4A, 0x0117, 0x0117, 1024, 768, 16, MD_XGI315 }, - { 0x64, 0x013c, 0x0118, 1024, 768, 32, MD_XGI315 }, - { 0x64, 0x013c, 0x0118, 1024, 768, 32, MD_XGI315 }, - { 0x23, 0x0000, 0x0000, 1152, 768, 8, }, - { 0x24, 0x0000, 0x0000, 1152, 768, 16, }, - { 0x25, 0x0000, 0x0000, 1152, 768, 32, }, - { 0x79, 0x0000, 0x0000, 1280, 720, 8, MD_XGI315 }, - { 0x75, 0x0000, 0x0000, 1280, 720, 16, MD_XGI315 }, - { 0x78, 0x0000, 0x0000, 1280, 720, 32, MD_XGI315 }, - { 0x23, 0x0000, 0x0000, 1280, 768, 8, MD_XGI315 }, - { 0x24, 0x0000, 0x0000, 1280, 768, 16, MD_XGI315 }, - { 0x25, 0x0000, 0x0000, 1280, 768, 32, MD_XGI315 }, - { 0x7C, 0x0000, 0x0000, 1280, 960, 8, MD_XGI315 }, - { 0x7D, 0x0000, 0x0000, 1280, 960, 16, MD_XGI315 }, - { 0x7E, 0x0000, 0x0000, 1280, 960, 32, MD_XGI315 }, - { 0x3A, 0x0107, 0x0107, 1280, 1024, 8, MD_XGI315 }, - { 0x4D, 0x011a, 0x011a, 1280, 1024, 16, MD_XGI315 }, - { 0x65, 0x013d, 0x011b, 1280, 1024, 32, MD_XGI315 }, - { 0x26, 0x0000, 0x0000, 1400, 1050, 8, MD_XGI315 }, - { 0x27, 0x0000, 0x0000, 1400, 1050, 16, MD_XGI315 }, - { 0x28, 0x0000, 0x0000, 1400, 1050, 32, MD_XGI315 }, - { 0x3C, 0x0130, 0x011c, 1600, 1200, 8, MD_XGI315 }, - { 0x3D, 0x0131, 0x011e, 1600, 1200, 16, MD_XGI315 }, - { 0x66, 0x013e, 0x011f, 1600, 1200, 32, MD_XGI315 }, - { 0x68, 0x013f, 0x0000, 1920, 1440, 8, MD_XGI315 }, - { 0x69, 0x0140, 0x0000, 1920, 1440, 16, MD_XGI315 }, - { 0x6B, 0x0141, 0x0000, 1920, 1440, 32, MD_XGI315 }, - { 0x6c, 0x0000, 0x0000, 2048, 1536, 8, MD_XGI315 }, - { 0x6d, 0x0000, 0x0000, 2048, 1536, 16, MD_XGI315 }, - { 0x6e, 0x0000, 0x0000, 2048, 1536, 32, MD_XGI315 }, - { 0 }, -}; - -static const unsigned short XGI310paneltype[] = { - LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024, - LCD_640x480, LCD_1024x600, LCD_1152x864, LCD_1280x960, - LCD_1152x768, LCD_1400x1050, LCD_1280x768, LCD_1600x1200, - LCD_1024x768, LCD_1024x768, LCD_1024x768}; - -static const struct _XGI_crt2type { - char name[10]; - int type_no; - int tvplug_no; -} XGI_crt2type[] = { - {"NONE", 0, -1}, - {"LCD", XGIFB_DISP_LCD, -1}, - {"TV", XGIFB_DISP_TV, -1}, - {"VGA", XGIFB_DISP_CRT, -1}, - {"SVIDEO", XGIFB_DISP_TV, TVPLUG_SVIDEO}, - {"COMPOSITE", XGIFB_DISP_TV, TVPLUG_COMPOSITE}, - {"SCART", XGIFB_DISP_TV, TVPLUG_SCART}, - {"none", 0, -1}, - {"lcd", XGIFB_DISP_LCD, -1}, - {"tv", XGIFB_DISP_TV, -1}, - {"vga", XGIFB_DISP_CRT, -1}, - {"svideo", XGIFB_DISP_TV, TVPLUG_SVIDEO}, - {"composite", XGIFB_DISP_TV, TVPLUG_COMPOSITE}, - {"scart", XGIFB_DISP_TV, TVPLUG_SCART}, - {"\0", -1, -1} -}; - -/* TV standard */ -static const struct _XGI_tvtype { - char name[6]; - int type_no; -} XGI_tvtype[] = { - {"PAL", 1}, - {"NTSC", 2}, - {"pal", 1}, - {"ntsc", 2}, - {"\0", -1} -}; - -static const struct _XGI_vrate { - u16 idx; - u16 xres; - u16 yres; - u16 refresh; -} XGIfb_vrate[] = { - {1, 640, 480, 60}, {2, 640, 480, 72}, - {3, 640, 480, 75}, {4, 640, 480, 85}, - - {5, 640, 480, 100}, {6, 640, 480, 120}, - {7, 640, 480, 160}, {8, 640, 480, 200}, - - {1, 720, 480, 60}, - {1, 720, 576, 58}, - {1, 800, 480, 60}, {2, 800, 480, 75}, {3, 800, 480, 85}, - {1, 800, 600, 60}, {2, 800, 600, 72}, {3, 800, 600, 75}, - {4, 800, 600, 85}, {5, 800, 600, 100}, - {6, 800, 600, 120}, {7, 800, 600, 160}, - - {1, 1024, 768, 60}, {2, 1024, 768, 70}, {3, 1024, 768, 75}, - {4, 1024, 768, 85}, {5, 1024, 768, 100}, {6, 1024, 768, 120}, - {1, 1024, 576, 60}, {2, 1024, 576, 75}, {3, 1024, 576, 85}, - {1, 1024, 600, 60}, - {1, 1152, 768, 60}, - {1, 1280, 720, 60}, {2, 1280, 720, 75}, {3, 1280, 720, 85}, - {1, 1280, 768, 60}, - {1, 1280, 1024, 60}, {2, 1280, 1024, 75}, {3, 1280, 1024, 85}, - {1, 1280, 960, 70}, - {1, 1400, 1050, 60}, - {1, 1600, 1200, 60}, {2, 1600, 1200, 65}, - {3, 1600, 1200, 70}, {4, 1600, 1200, 75}, - - {5, 1600, 1200, 85}, {6, 1600, 1200, 100}, - {7, 1600, 1200, 120}, - - {1, 1920, 1440, 60}, {2, 1920, 1440, 65}, - {3, 1920, 1440, 70}, {4, 1920, 1440, 75}, - - {5, 1920, 1440, 85}, {6, 1920, 1440, 100}, - {1, 2048, 1536, 60}, {2, 2048, 1536, 65}, - {3, 2048, 1536, 70}, {4, 2048, 1536, 75}, - - {5, 2048, 1536, 85}, - {0, 0, 0, 0} -}; - -static const struct _XGI_TV_filter { - u8 filter[9][4]; -} XGI_TV_filter[] = { - { { {0x00, 0x00, 0x00, 0x40}, /* NTSCFilter_0 */ - {0x00, 0xE0, 0x10, 0x60}, - {0x00, 0xEE, 0x10, 0x44}, - {0x00, 0xF4, 0x10, 0x38}, - {0xF8, 0xF4, 0x18, 0x38}, - {0xFC, 0xFB, 0x14, 0x2A}, - {0x00, 0x00, 0x10, 0x20}, - {0x00, 0x04, 0x10, 0x18}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* NTSCFilter_1 */ - {0x00, 0xE0, 0x10, 0x60}, - {0x00, 0xEE, 0x10, 0x44}, - {0x00, 0xF4, 0x10, 0x38}, - {0xF8, 0xF4, 0x18, 0x38}, - {0xFC, 0xFB, 0x14, 0x2A}, - {0x00, 0x00, 0x10, 0x20}, - {0x00, 0x04, 0x10, 0x18}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* NTSCFilter_2 */ - {0xF5, 0xEE, 0x1B, 0x44}, - {0xF8, 0xF4, 0x18, 0x38}, - {0xEB, 0x04, 0x25, 0x18}, - {0xF1, 0x05, 0x1F, 0x16}, - {0xF6, 0x06, 0x1A, 0x14}, - {0xFA, 0x06, 0x16, 0x14}, - {0x00, 0x04, 0x10, 0x18}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* NTSCFilter_3 */ - {0xF1, 0x04, 0x1F, 0x18}, - {0xEE, 0x0D, 0x22, 0x06}, - {0xF7, 0x06, 0x19, 0x14}, - {0xF4, 0x0B, 0x1C, 0x0A}, - {0xFA, 0x07, 0x16, 0x12}, - {0xF9, 0x0A, 0x17, 0x0C}, - {0x00, 0x07, 0x10, 0x12}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* NTSCFilter_4 */ - {0x00, 0xE0, 0x10, 0x60}, - {0x00, 0xEE, 0x10, 0x44}, - {0x00, 0xF4, 0x10, 0x38}, - {0xF8, 0xF4, 0x18, 0x38}, - {0xFC, 0xFB, 0x14, 0x2A}, - {0x00, 0x00, 0x10, 0x20}, - {0x00, 0x04, 0x10, 0x18}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* NTSCFilter_5 */ - {0xF5, 0xEE, 0x1B, 0x44}, - {0xF8, 0xF4, 0x18, 0x38}, - {0xEB, 0x04, 0x25, 0x18}, - {0xF1, 0x05, 0x1F, 0x16}, - {0xF6, 0x06, 0x1A, 0x14}, - {0xFA, 0x06, 0x16, 0x14}, - {0x00, 0x04, 0x10, 0x18}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* NTSCFilter_6 */ - {0xEB, 0x04, 0x25, 0x18}, - {0xE7, 0x0E, 0x29, 0x04}, - {0xEE, 0x0C, 0x22, 0x08}, - {0xF6, 0x0B, 0x1A, 0x0A}, - {0xF9, 0x0A, 0x17, 0x0C}, - {0xFC, 0x0A, 0x14, 0x0C}, - {0x00, 0x08, 0x10, 0x10}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* NTSCFilter_7 */ - {0xEC, 0x02, 0x24, 0x1C}, - {0xF2, 0x04, 0x1E, 0x18}, - {0xEB, 0x15, 0x25, 0xF6}, - {0xF4, 0x10, 0x1C, 0x00}, - {0xF8, 0x0F, 0x18, 0x02}, - {0x00, 0x04, 0x10, 0x18}, - {0x01, 0x06, 0x0F, 0x14}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* PALFilter_0 */ - {0x00, 0xE0, 0x10, 0x60}, - {0x00, 0xEE, 0x10, 0x44}, - {0x00, 0xF4, 0x10, 0x38}, - {0xF8, 0xF4, 0x18, 0x38}, - {0xFC, 0xFB, 0x14, 0x2A}, - {0x00, 0x00, 0x10, 0x20}, - {0x00, 0x04, 0x10, 0x18}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* PALFilter_1 */ - {0x00, 0xE0, 0x10, 0x60}, - {0x00, 0xEE, 0x10, 0x44}, - {0x00, 0xF4, 0x10, 0x38}, - {0xF8, 0xF4, 0x18, 0x38}, - {0xFC, 0xFB, 0x14, 0x2A}, - {0x00, 0x00, 0x10, 0x20}, - {0x00, 0x04, 0x10, 0x18}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* PALFilter_2 */ - {0xF5, 0xEE, 0x1B, 0x44}, - {0xF8, 0xF4, 0x18, 0x38}, - {0xF1, 0xF7, 0x01, 0x32}, - {0xF5, 0xFB, 0x1B, 0x2A}, - {0xF9, 0xFF, 0x17, 0x22}, - {0xFB, 0x01, 0x15, 0x1E}, - {0x00, 0x04, 0x10, 0x18}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* PALFilter_3 */ - {0xF5, 0xFB, 0x1B, 0x2A}, - {0xEE, 0xFE, 0x22, 0x24}, - {0xF3, 0x00, 0x1D, 0x20}, - {0xF9, 0x03, 0x17, 0x1A}, - {0xFB, 0x02, 0x14, 0x1E}, - {0xFB, 0x04, 0x15, 0x18}, - {0x00, 0x06, 0x10, 0x14}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* PALFilter_4 */ - {0x00, 0xE0, 0x10, 0x60}, - {0x00, 0xEE, 0x10, 0x44}, - {0x00, 0xF4, 0x10, 0x38}, - {0xF8, 0xF4, 0x18, 0x38}, - {0xFC, 0xFB, 0x14, 0x2A}, - {0x00, 0x00, 0x10, 0x20}, - {0x00, 0x04, 0x10, 0x18}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* PALFilter_5 */ - {0xF5, 0xEE, 0x1B, 0x44}, - {0xF8, 0xF4, 0x18, 0x38}, - {0xF1, 0xF7, 0x1F, 0x32}, - {0xF5, 0xFB, 0x1B, 0x2A}, - {0xF9, 0xFF, 0x17, 0x22}, - {0xFB, 0x01, 0x15, 0x1E}, - {0x00, 0x04, 0x10, 0x18}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* PALFilter_6 */ - {0xF5, 0xEE, 0x1B, 0x2A}, - {0xEE, 0xFE, 0x22, 0x24}, - {0xF3, 0x00, 0x1D, 0x20}, - {0xF9, 0x03, 0x17, 0x1A}, - {0xFB, 0x02, 0x14, 0x1E}, - {0xFB, 0x04, 0x15, 0x18}, - {0x00, 0x06, 0x10, 0x14}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* PALFilter_7 */ - {0xF5, 0xEE, 0x1B, 0x44}, - {0xF8, 0xF4, 0x18, 0x38}, - {0xFC, 0xFB, 0x14, 0x2A}, - {0xEB, 0x05, 0x25, 0x16}, - {0xF1, 0x05, 0x1F, 0x16}, - {0xFA, 0x07, 0x16, 0x12}, - {0x00, 0x07, 0x10, 0x12}, - {0xFF, 0xFF, 0xFF, 0xFF} } } -}; - -static int filter = -1; - -#endif diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c deleted file mode 100644 index 217c6bb82c0d..000000000000 --- a/drivers/staging/xgifb/XGI_main_26.c +++ /dev/null @@ -1,2084 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * XG20, XG21, XG40, XG42 frame buffer device - * for Linux kernels 2.5.x, 2.6.x - * Base on TW's sis fbdev code. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/sizes.h> -#include <linux/module.h> -#include <linux/pci.h> - -#include "XGI_main.h" -#include "vb_init.h" -#include "vb_util.h" -#include "vb_setmode.h" - -#define Index_CR_GPIO_Reg1 0x48 -#define Index_CR_GPIO_Reg3 0x4a - -#define GPIOG_EN BIT(6) -#define GPIOG_READ BIT(1) - -static char *forcecrt2type; -static char *mode; -static int vesa = -1; -static unsigned int refresh_rate; - -/* -------------------- Macro definitions ---------------------------- */ - -#ifdef DEBUG -static void dumpVGAReg(struct xgifb_video_info *xgifb_info) -{ - struct vb_device_info *vb = &xgifb_info->dev_info; - u8 i, reg; - - xgifb_reg_set(vb->P3c4, 0x05, 0x86); - - for (i = 0; i < 0x4f; i++) { - reg = xgifb_reg_get(vb->P3c4, i); - pr_debug("o 3c4 %x\n", i); - pr_debug("i 3c5 => %x\n", reg); - } - - for (i = 0; i < 0xF0; i++) { - reg = xgifb_reg_get(vb->P3d4, i); - pr_debug("o 3d4 %x\n", i); - pr_debug("i 3d5 => %x\n", reg); - } -} -#else -static inline void dumpVGAReg(struct xgifb_video_info *xgifb_info) -{ -} -#endif - -/* --------------- Hardware Access Routines -------------------------- */ - -static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr, - struct xgi_hw_device_info *HwDeviceExtension, - unsigned char modeno) -{ - unsigned short ModeNo = modeno; - unsigned short ModeIdIndex = 0, ClockIndex = 0; - unsigned short RefreshRateTableIndex = 0; - - InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr); - - XGI_SearchModeID(ModeNo, &ModeIdIndex); - - RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, - ModeIdIndex, XGI_Pr); - - ClockIndex = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; - - return XGI_VCLKData[ClockIndex].CLOCK * 1000; -} - -static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr, - struct xgi_hw_device_info *HwDeviceExtension, - unsigned char modeno, u32 *left_margin, - u32 *right_margin, u32 *upper_margin, - u32 *lower_margin, u32 *hsync_len, - u32 *vsync_len, u32 *sync, u32 *vmode) -{ - unsigned short ModeNo = modeno; - unsigned short ModeIdIndex, index = 0; - unsigned short RefreshRateTableIndex = 0; - - unsigned short VRE, VBE, VRS, VDE; - unsigned short HRE, HBE, HRS, HDE; - unsigned char sr_data, cr_data, cr_data2; - int B, C, D, F, temp, j; - - InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr); - if (!XGI_SearchModeID(ModeNo, &ModeIdIndex)) - return 0; - RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, - ModeIdIndex, XGI_Pr); - index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - - sr_data = XGI_CRT1Table[index].CR[5]; - - HDE = XGI330_RefIndex[RefreshRateTableIndex].XRes >> 3; - - cr_data = XGI_CRT1Table[index].CR[3]; - - /* Horizontal retrace (=sync) start */ - HRS = (cr_data & 0xff) | ((unsigned short)(sr_data & 0xC0) << 2); - F = HRS - HDE - 3; - - sr_data = XGI_CRT1Table[index].CR[6]; - - cr_data = XGI_CRT1Table[index].CR[2]; - - cr_data2 = XGI_CRT1Table[index].CR[4]; - - /* Horizontal blank end */ - HBE = (cr_data & 0x1f) | ((unsigned short)(cr_data2 & 0x80) >> 2) - | ((unsigned short)(sr_data & 0x03) << 6); - - /* Horizontal retrace (=sync) end */ - HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3); - - temp = HBE - ((HDE - 1) & 255); - B = (temp > 0) ? temp : (temp + 256); - - temp = HRE - ((HDE + F + 3) & 63); - C = (temp > 0) ? temp : (temp + 64); - - D = B - F - C; - - *left_margin = D * 8; - *right_margin = F * 8; - *hsync_len = C * 8; - - sr_data = XGI_CRT1Table[index].CR[14]; - - cr_data2 = XGI_CRT1Table[index].CR[9]; - - VDE = XGI330_RefIndex[RefreshRateTableIndex].YRes; - - cr_data = XGI_CRT1Table[index].CR[10]; - - /* Vertical retrace (=sync) start */ - VRS = (cr_data & 0xff) | ((unsigned short)(cr_data2 & 0x04) << 6) - | ((unsigned short)(cr_data2 & 0x80) << 2) - | ((unsigned short)(sr_data & 0x08) << 7); - F = VRS + 1 - VDE; - - cr_data = XGI_CRT1Table[index].CR[13]; - - /* Vertical blank end */ - VBE = (cr_data & 0xff) | ((unsigned short)(sr_data & 0x10) << 4); - temp = VBE - ((VDE - 1) & 511); - B = (temp > 0) ? temp : (temp + 512); - - cr_data = XGI_CRT1Table[index].CR[11]; - - /* Vertical retrace (=sync) end */ - VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1); - temp = VRE - ((VDE + F - 1) & 31); - C = (temp > 0) ? temp : (temp + 32); - - D = B - F - C; - - *upper_margin = D; - *lower_margin = F; - *vsync_len = C; - - if (XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000) - *sync &= ~FB_SYNC_VERT_HIGH_ACT; - else - *sync |= FB_SYNC_VERT_HIGH_ACT; - - if (XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000) - *sync &= ~FB_SYNC_HOR_HIGH_ACT; - else - *sync |= FB_SYNC_HOR_HIGH_ACT; - - *vmode = FB_VMODE_NONINTERLACED; - if (XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080) { - *vmode = FB_VMODE_INTERLACED; - } else { - j = 0; - while (XGI330_EModeIDTable[j].Ext_ModeID != 0xff) { - if (XGI330_EModeIDTable[j].Ext_ModeID == - XGI330_RefIndex[RefreshRateTableIndex].ModeID) { - if (XGI330_EModeIDTable[j].Ext_ModeFlag & - DoubleScanMode) { - *vmode = FB_VMODE_DOUBLE; - } - break; - } - j++; - } - } - - return 1; -} - -void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr) -{ - XGI_Pr->P3c4 = BaseAddr + 0x14; - XGI_Pr->P3d4 = BaseAddr + 0x24; - XGI_Pr->P3c0 = BaseAddr + 0x10; - XGI_Pr->P3ce = BaseAddr + 0x1e; - XGI_Pr->P3c2 = BaseAddr + 0x12; - XGI_Pr->P3cc = BaseAddr + 0x1c; - XGI_Pr->P3ca = BaseAddr + 0x1a; - XGI_Pr->P3c6 = BaseAddr + 0x16; - XGI_Pr->P3c7 = BaseAddr + 0x17; - XGI_Pr->P3c8 = BaseAddr + 0x18; - XGI_Pr->P3c9 = BaseAddr + 0x19; - XGI_Pr->P3da = BaseAddr + 0x2A; - XGI_Pr->Part0Port = BaseAddr + XGI_CRT2_PORT_00; - /* Digital video interface registers (LCD) */ - XGI_Pr->Part1Port = BaseAddr + SIS_CRT2_PORT_04; - /* 301 TV Encoder registers */ - XGI_Pr->Part2Port = BaseAddr + SIS_CRT2_PORT_10; - /* 301 Macrovision registers */ - XGI_Pr->Part3Port = BaseAddr + SIS_CRT2_PORT_12; - /* 301 VGA2 (and LCD) registers */ - XGI_Pr->Part4Port = BaseAddr + SIS_CRT2_PORT_14; - /* 301 palette address port registers */ - XGI_Pr->Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2; -} - -/* ------------------ Internal helper routines ----------------- */ - -static int XGIfb_GetXG21DefaultLVDSModeIdx(struct xgifb_video_info *xgifb_info) -{ - int i = 0; - - while ((XGIbios_mode[i].mode_no != 0) && - (XGIbios_mode[i].xres <= xgifb_info->lvds_data.LVDSHDE)) { - if ((XGIbios_mode[i].xres == xgifb_info->lvds_data.LVDSHDE) && - (XGIbios_mode[i].yres == xgifb_info->lvds_data.LVDSVDE) && - (XGIbios_mode[i].bpp == 8)) { - return i; - } - i++; - } - - return -1; -} - -static void XGIfb_search_mode(struct xgifb_video_info *xgifb_info, - const char *name) -{ - unsigned int xres; - unsigned int yres; - unsigned int bpp; - int i; - - if (sscanf(name, "%ux%ux%u", &xres, &yres, &bpp) != 3) - goto invalid_mode; - - if (bpp == 24) - bpp = 32; /* That's for people who mix up color and fb depth. */ - - for (i = 0; XGIbios_mode[i].mode_no != 0; i++) - if (XGIbios_mode[i].xres == xres && - XGIbios_mode[i].yres == yres && - XGIbios_mode[i].bpp == bpp) { - xgifb_info->mode_idx = i; - return; - } -invalid_mode: - pr_info("Invalid mode '%s'\n", name); -} - -static void XGIfb_search_vesamode(struct xgifb_video_info *xgifb_info, - unsigned int vesamode) -{ - int i = 0; - - if (vesamode == 0) - goto invalid; - - vesamode &= 0x1dff; /* Clean VESA mode number from other flags */ - - while (XGIbios_mode[i].mode_no != 0) { - if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode) || - (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) { - xgifb_info->mode_idx = i; - return; - } - i++; - } - -invalid: - pr_info("Invalid VESA mode 0x%x'\n", vesamode); -} - -static int XGIfb_validate_mode(struct xgifb_video_info *xgifb_info, int myindex) -{ - u16 xres, yres; - struct xgi_hw_device_info *hw_info = &xgifb_info->hw_info; - unsigned long required_mem; - - if (xgifb_info->chip == XG21) { - if (xgifb_info->display2 == XGIFB_DISP_LCD) { - xres = xgifb_info->lvds_data.LVDSHDE; - yres = xgifb_info->lvds_data.LVDSVDE; - if (XGIbios_mode[myindex].xres > xres) - return -1; - if (XGIbios_mode[myindex].yres > yres) - return -1; - if ((XGIbios_mode[myindex].xres < xres) && - (XGIbios_mode[myindex].yres < yres)) { - if (XGIbios_mode[myindex].bpp > 8) - return -1; - } - } - goto check_memory; - } - - /* FIXME: for now, all is valid on XG27 */ - if (xgifb_info->chip == XG27) - goto check_memory; - - if (!(XGIbios_mode[myindex].chipset & MD_XGI315)) - return -1; - - switch (xgifb_info->display2) { - case XGIFB_DISP_LCD: - switch (hw_info->ulCRT2LCDType) { - case LCD_640x480: - xres = 640; - yres = 480; - break; - case LCD_800x600: - xres = 800; - yres = 600; - break; - case LCD_1024x600: - xres = 1024; - yres = 600; - break; - case LCD_1024x768: - xres = 1024; - yres = 768; - break; - case LCD_1152x768: - xres = 1152; - yres = 768; - break; - case LCD_1280x960: - xres = 1280; - yres = 960; - break; - case LCD_1280x768: - xres = 1280; - yres = 768; - break; - case LCD_1280x1024: - xres = 1280; - yres = 1024; - break; - case LCD_1400x1050: - xres = 1400; - yres = 1050; - break; - case LCD_1600x1200: - xres = 1600; - yres = 1200; - break; - default: - xres = 0; - yres = 0; - break; - } - if (XGIbios_mode[myindex].xres > xres) - return -1; - if (XGIbios_mode[myindex].yres > yres) - return -1; - if ((hw_info->ulExternalChip == 0x01) || /* LVDS */ - (hw_info->ulExternalChip == 0x05)) { /* LVDS+Chrontel */ - switch (XGIbios_mode[myindex].xres) { - case 512: - if (XGIbios_mode[myindex].yres != 512) - return -1; - if (hw_info->ulCRT2LCDType == LCD_1024x600) - return -1; - break; - case 640: - if ((XGIbios_mode[myindex].yres != 400) && - (XGIbios_mode[myindex].yres != 480)) - return -1; - break; - case 800: - if (XGIbios_mode[myindex].yres != 600) - return -1; - break; - case 1024: - if ((XGIbios_mode[myindex].yres != 600) && - (XGIbios_mode[myindex].yres != 768)) - return -1; - if ((XGIbios_mode[myindex].yres == 600) && - (hw_info->ulCRT2LCDType != LCD_1024x600)) - return -1; - break; - case 1152: - if ((XGIbios_mode[myindex].yres) != 768) - return -1; - if (hw_info->ulCRT2LCDType != LCD_1152x768) - return -1; - break; - case 1280: - if ((XGIbios_mode[myindex].yres != 768) && - (XGIbios_mode[myindex].yres != 1024)) - return -1; - if ((XGIbios_mode[myindex].yres == 768) && - (hw_info->ulCRT2LCDType != LCD_1280x768)) - return -1; - break; - case 1400: - if (XGIbios_mode[myindex].yres != 1050) - return -1; - break; - case 1600: - if (XGIbios_mode[myindex].yres != 1200) - return -1; - break; - default: - return -1; - } - } else { - switch (XGIbios_mode[myindex].xres) { - case 512: - if (XGIbios_mode[myindex].yres != 512) - return -1; - break; - case 640: - if ((XGIbios_mode[myindex].yres != 400) && - (XGIbios_mode[myindex].yres != 480)) - return -1; - break; - case 800: - if (XGIbios_mode[myindex].yres != 600) - return -1; - break; - case 1024: - if (XGIbios_mode[myindex].yres != 768) - return -1; - break; - case 1280: - if ((XGIbios_mode[myindex].yres != 960) && - (XGIbios_mode[myindex].yres != 1024)) - return -1; - if (XGIbios_mode[myindex].yres == 960) { - if (hw_info->ulCRT2LCDType == - LCD_1400x1050) - return -1; - } - break; - case 1400: - if (XGIbios_mode[myindex].yres != 1050) - return -1; - break; - case 1600: - if (XGIbios_mode[myindex].yres != 1200) - return -1; - break; - default: - return -1; - } - } - break; - case XGIFB_DISP_TV: - switch (XGIbios_mode[myindex].xres) { - case 512: - case 640: - case 800: - break; - case 720: - if (xgifb_info->TV_type == TVMODE_NTSC) { - if (XGIbios_mode[myindex].yres != 480) - return -1; - } else if (xgifb_info->TV_type == TVMODE_PAL) { - if (XGIbios_mode[myindex].yres != 576) - return -1; - } - /* LVDS/CHRONTEL does not support 720 */ - if (xgifb_info->hasVB == HASVB_LVDS_CHRONTEL || - xgifb_info->hasVB == HASVB_CHRONTEL) { - return -1; - } - break; - case 1024: - if (xgifb_info->TV_type == TVMODE_NTSC) { - if (XGIbios_mode[myindex].bpp == 32) - return -1; - } - break; - default: - return -1; - } - break; - case XGIFB_DISP_CRT: - if (XGIbios_mode[myindex].xres > 1280) - return -1; - break; - case XGIFB_DISP_NONE: - break; - } - -check_memory: - required_mem = XGIbios_mode[myindex].xres * XGIbios_mode[myindex].yres * - XGIbios_mode[myindex].bpp / 8; - if (required_mem > xgifb_info->video_size) - return -1; - return myindex; -} - -static void XGIfb_search_crt2type(const char *name) -{ - int i = 0; - - if (!name) - return; - - while (XGI_crt2type[i].type_no != -1) { - if (!strcmp(name, XGI_crt2type[i].name)) { - XGIfb_crt2type = XGI_crt2type[i].type_no; - XGIfb_tvplug = XGI_crt2type[i].tvplug_no; - break; - } - i++; - } - if (XGIfb_crt2type < 0) - pr_info("Invalid CRT2 type: %s\n", name); -} - -static u8 XGIfb_search_refresh_rate(struct xgifb_video_info *xgifb_info, - unsigned int rate) -{ - u16 xres, yres; - int i = 0; - - xres = XGIbios_mode[xgifb_info->mode_idx].xres; - yres = XGIbios_mode[xgifb_info->mode_idx].yres; - - xgifb_info->rate_idx = 0; - - while (XGIfb_vrate[i].idx != 0 && XGIfb_vrate[i].xres <= xres) { - /* Skip values with xres or yres less than specified */ - if ((XGIfb_vrate[i].yres != yres) || - (XGIfb_vrate[i].xres != xres)) { - i++; - continue; - } - if (XGIfb_vrate[i].refresh == rate) { - xgifb_info->rate_idx = XGIfb_vrate[i].idx; - break; - } else if (XGIfb_vrate[i].refresh > rate) { - if (XGIfb_vrate[i].refresh - rate <= 3) { - pr_debug("Adjusting rate from %d up to %d\n", - rate, XGIfb_vrate[i].refresh); - xgifb_info->rate_idx = XGIfb_vrate[i].idx; - xgifb_info->refresh_rate = - XGIfb_vrate[i].refresh; - } else if ((XGIfb_vrate[i].idx != 1) && - (rate - XGIfb_vrate[i - 1].refresh <= 2)) { - pr_debug("Adjusting rate from %d down to %d\n", - rate, XGIfb_vrate[i - 1].refresh); - xgifb_info->rate_idx = XGIfb_vrate[i - 1].idx; - xgifb_info->refresh_rate = - XGIfb_vrate[i - 1].refresh; - } - break; - } else if (rate - XGIfb_vrate[i].refresh <= 2) { - pr_debug("Adjusting rate from %d down to %d\n", - rate, XGIfb_vrate[i].refresh); - xgifb_info->rate_idx = XGIfb_vrate[i].idx; - break; - } - i++; - } - - if (xgifb_info->rate_idx > 0) - return xgifb_info->rate_idx; - pr_info("Unsupported rate %d for %dx%d\n", - rate, xres, yres); - return 0; -} - -static void XGIfb_search_tvstd(const char *name) -{ - int i = 0; - - if (!name) - return; - - while (XGI_tvtype[i].type_no != -1) { - if (!strcmp(name, XGI_tvtype[i].name)) { - XGIfb_tvmode = XGI_tvtype[i].type_no; - break; - } - i++; - } -} - -/* ----------- FBDev related routines for all series ----------- */ - -static void XGIfb_bpp_to_var(struct xgifb_video_info *xgifb_info, - struct fb_var_screeninfo *var) -{ - switch (var->bits_per_pixel) { - case 8: - var->red.offset = 0; - var->green.offset = 0; - var->blue.offset = 0; - var->red.length = 6; - var->green.length = 6; - var->blue.length = 6; - xgifb_info->video_cmap_len = 256; - break; - case 16: - var->red.offset = 11; - var->red.length = 5; - var->green.offset = 5; - var->green.length = 6; - var->blue.offset = 0; - var->blue.length = 5; - var->transp.offset = 0; - var->transp.length = 0; - xgifb_info->video_cmap_len = 16; - break; - case 32: - var->red.offset = 16; - var->red.length = 8; - var->green.offset = 8; - var->green.length = 8; - var->blue.offset = 0; - var->blue.length = 8; - var->transp.offset = 24; - var->transp.length = 8; - xgifb_info->video_cmap_len = 16; - break; - } -} - -/* --------------------- SetMode routines ------------------------- */ - -static void XGIfb_pre_setmode(struct xgifb_video_info *xgifb_info) -{ - struct vb_device_info *vb = &xgifb_info->dev_info; - u8 cr30 = 0, cr31 = 0; - - cr31 = xgifb_reg_get(vb->P3d4, 0x31); - cr31 &= ~0x60; - - switch (xgifb_info->display2) { - case XGIFB_DISP_CRT: - cr30 = SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE; - cr31 |= SIS_DRIVER_MODE; - break; - case XGIFB_DISP_LCD: - cr30 = SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE; - cr31 |= SIS_DRIVER_MODE; - break; - case XGIFB_DISP_TV: - if (xgifb_info->TV_type == TVMODE_HIVISION) - cr30 = SIS_VB_OUTPUT_HIVISION - | SIS_SIMULTANEOUS_VIEW_ENABLE; - else if (xgifb_info->TV_plug == TVPLUG_SVIDEO) - cr30 = SIS_VB_OUTPUT_SVIDEO - | SIS_SIMULTANEOUS_VIEW_ENABLE; - else if (xgifb_info->TV_plug == TVPLUG_COMPOSITE) - cr30 = SIS_VB_OUTPUT_COMPOSITE - | SIS_SIMULTANEOUS_VIEW_ENABLE; - else if (xgifb_info->TV_plug == TVPLUG_SCART) - cr30 = SIS_VB_OUTPUT_SCART - | SIS_SIMULTANEOUS_VIEW_ENABLE; - cr31 |= SIS_DRIVER_MODE; - - if (XGIfb_tvmode == 1 || xgifb_info->TV_type == TVMODE_PAL) - cr31 |= 0x01; - else - cr31 &= ~0x01; - break; - default: /* disable CRT2 */ - cr30 = 0x00; - cr31 |= (SIS_DRIVER_MODE | SIS_VB_OUTPUT_DISABLE); - } - - xgifb_reg_set(vb->P3d4, IND_XGI_SCRATCH_REG_CR30, cr30); - xgifb_reg_set(vb->P3d4, IND_XGI_SCRATCH_REG_CR31, cr31); - xgifb_reg_set(vb->P3d4, IND_XGI_SCRATCH_REG_CR33, - (xgifb_info->rate_idx & 0x0F)); -} - -static void XGIfb_post_setmode(struct xgifb_video_info *xgifb_info) -{ - struct vb_device_info *vb = &xgifb_info->dev_info; - u8 reg; - unsigned char doit = 1; - - if (xgifb_info->video_bpp == 8) { - /* - * We can't switch off CRT1 on LVDS/Chrontel - * in 8bpp Modes - */ - if ((xgifb_info->hasVB == HASVB_LVDS) || - (xgifb_info->hasVB == HASVB_LVDS_CHRONTEL)) { - doit = 0; - } - /* - * We can't switch off CRT1 on 301B-DH - * in 8bpp Modes if using LCD - */ - if (xgifb_info->display2 == XGIFB_DISP_LCD) - doit = 0; - } - - /* We can't switch off CRT1 if bridge is in slave mode */ - if (xgifb_info->hasVB != HASVB_NONE) { - reg = xgifb_reg_get(vb->Part1Port, 0x00); - - if ((reg & 0x50) == 0x10) - doit = 0; - - } else { - XGIfb_crt1off = 0; - } - - reg = xgifb_reg_get(vb->P3d4, 0x17); - if ((XGIfb_crt1off) && (doit)) - reg &= ~0x80; - else - reg |= 0x80; - xgifb_reg_set(vb->P3d4, 0x17, reg); - - xgifb_reg_and(vb->P3c4, IND_SIS_RAMDAC_CONTROL, ~0x04); - - if (xgifb_info->display2 == XGIFB_DISP_TV && - xgifb_info->hasVB == HASVB_301) { - reg = xgifb_reg_get(vb->Part4Port, 0x01); - - if (reg < 0xB0) { /* Set filter for XGI301 */ - int filter_tb; - - switch (xgifb_info->video_width) { - case 320: - filter_tb = (xgifb_info->TV_type == - TVMODE_NTSC) ? 4 : 12; - break; - case 640: - filter_tb = (xgifb_info->TV_type == - TVMODE_NTSC) ? 5 : 13; - break; - case 720: - filter_tb = (xgifb_info->TV_type == - TVMODE_NTSC) ? 6 : 14; - break; - case 800: - filter_tb = (xgifb_info->TV_type == - TVMODE_NTSC) ? 7 : 15; - break; - default: - filter_tb = 0; - filter = -1; - break; - } - xgifb_reg_or(vb->Part1Port, SIS_CRT2_WENABLE_315, 0x01); - - if (xgifb_info->TV_type == TVMODE_NTSC) { - xgifb_reg_and(vb->Part2Port, 0x3a, 0x1f); - - if (xgifb_info->TV_plug == TVPLUG_SVIDEO) { - xgifb_reg_and(vb->Part2Port, 0x30, 0xdf); - - } else if (xgifb_info->TV_plug - == TVPLUG_COMPOSITE) { - xgifb_reg_or(vb->Part2Port, 0x30, 0x20); - - switch (xgifb_info->video_width) { - case 640: - xgifb_reg_set(vb->Part2Port, - 0x35, - 0xEB); - xgifb_reg_set(vb->Part2Port, - 0x36, - 0x04); - xgifb_reg_set(vb->Part2Port, - 0x37, - 0x25); - xgifb_reg_set(vb->Part2Port, - 0x38, - 0x18); - break; - case 720: - xgifb_reg_set(vb->Part2Port, - 0x35, - 0xEE); - xgifb_reg_set(vb->Part2Port, - 0x36, - 0x0C); - xgifb_reg_set(vb->Part2Port, - 0x37, - 0x22); - xgifb_reg_set(vb->Part2Port, - 0x38, - 0x08); - break; - case 800: - xgifb_reg_set(vb->Part2Port, - 0x35, - 0xEB); - xgifb_reg_set(vb->Part2Port, - 0x36, - 0x15); - xgifb_reg_set(vb->Part2Port, - 0x37, - 0x25); - xgifb_reg_set(vb->Part2Port, - 0x38, - 0xF6); - break; - } - } - - } else if (xgifb_info->TV_type == TVMODE_PAL) { - xgifb_reg_and(vb->Part2Port, 0x3A, 0x1F); - - if (xgifb_info->TV_plug == TVPLUG_SVIDEO) { - xgifb_reg_and(vb->Part2Port, 0x30, 0xDF); - - } else if (xgifb_info->TV_plug - == TVPLUG_COMPOSITE) { - xgifb_reg_or(vb->Part2Port, 0x30, 0x20); - - switch (xgifb_info->video_width) { - case 640: - xgifb_reg_set(vb->Part2Port, - 0x35, - 0xF1); - xgifb_reg_set(vb->Part2Port, - 0x36, - 0xF7); - xgifb_reg_set(vb->Part2Port, - 0x37, - 0x1F); - xgifb_reg_set(vb->Part2Port, - 0x38, - 0x32); - break; - case 720: - xgifb_reg_set(vb->Part2Port, - 0x35, - 0xF3); - xgifb_reg_set(vb->Part2Port, - 0x36, - 0x00); - xgifb_reg_set(vb->Part2Port, - 0x37, - 0x1D); - xgifb_reg_set(vb->Part2Port, - 0x38, - 0x20); - break; - case 800: - xgifb_reg_set(vb->Part2Port, - 0x35, - 0xFC); - xgifb_reg_set(vb->Part2Port, - 0x36, - 0xFB); - xgifb_reg_set(vb->Part2Port, - 0x37, - 0x14); - xgifb_reg_set(vb->Part2Port, - 0x38, - 0x2A); - break; - } - } - } - - if ((filter >= 0) && (filter <= 7)) { - const u8 *f = XGI_TV_filter[filter_tb].filter[filter]; - - pr_debug("FilterTable[%d]-%d: %*ph\n", - filter_tb, filter, 4, f); - xgifb_reg_set(vb->Part2Port, 0x35, f[0]); - xgifb_reg_set(vb->Part2Port, 0x36, f[1]); - xgifb_reg_set(vb->Part2Port, 0x37, f[2]); - xgifb_reg_set(vb->Part2Port, 0x38, f[3]); - } - } - } -} - -static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, - struct fb_info *info) -{ - struct xgifb_video_info *xgifb_info = info->par; - struct vb_device_info *vb = &xgifb_info->dev_info; - struct xgi_hw_device_info *hw_info = &xgifb_info->hw_info; - unsigned int htotal = var->left_margin + var->xres + var->right_margin - + var->hsync_len; - unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin - + var->vsync_len; -#if defined(__BIG_ENDIAN) - u8 cr_data; -#endif - unsigned int drate = 0, hrate = 0; - int found_mode = 0; - int old_mode; - - info->var.xres_virtual = var->xres_virtual; - info->var.yres_virtual = var->yres_virtual; - info->var.bits_per_pixel = var->bits_per_pixel; - - if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) - vtotal <<= 1; - else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) - vtotal <<= 2; - - if (!htotal || !vtotal) { - pr_debug("Invalid 'var' information\n"); - return -EINVAL; - } - pr_debug("var->pixclock=%d, htotal=%d, vtotal=%d\n", - var->pixclock, htotal, vtotal); - - if (var->pixclock) { - drate = 1000000000 / var->pixclock; - hrate = (drate * 1000) / htotal; - xgifb_info->refresh_rate = (unsigned int)(hrate * 2 - / vtotal); - } else { - xgifb_info->refresh_rate = 60; - } - - pr_debug("Change mode to %dx%dx%d-%dHz\n", - var->xres, var->yres, var->bits_per_pixel, - xgifb_info->refresh_rate); - - old_mode = xgifb_info->mode_idx; - xgifb_info->mode_idx = 0; - - while ((XGIbios_mode[xgifb_info->mode_idx].mode_no != 0) && - (XGIbios_mode[xgifb_info->mode_idx].xres <= var->xres)) { - if ((XGIbios_mode[xgifb_info->mode_idx].xres == var->xres) && - (XGIbios_mode[xgifb_info->mode_idx].yres == var->yres) && - (XGIbios_mode[xgifb_info->mode_idx].bpp - == var->bits_per_pixel)) { - found_mode = 1; - break; - } - xgifb_info->mode_idx++; - } - - if (found_mode) - xgifb_info->mode_idx = XGIfb_validate_mode(xgifb_info, - xgifb_info->mode_idx); - else - xgifb_info->mode_idx = -1; - - if (xgifb_info->mode_idx < 0) { - pr_err("Mode %dx%dx%d not supported\n", - var->xres, var->yres, var->bits_per_pixel); - xgifb_info->mode_idx = old_mode; - return -EINVAL; - } - - if (XGIfb_search_refresh_rate(xgifb_info, - xgifb_info->refresh_rate) == 0) { - xgifb_info->rate_idx = 1; - xgifb_info->refresh_rate = 60; - } - - if (isactive) { - XGIfb_pre_setmode(xgifb_info); - if (XGISetModeNew(xgifb_info, hw_info, - XGIbios_mode[xgifb_info->mode_idx].mode_no) - == 0) { - pr_err("Setting mode[0x%x] failed\n", - XGIbios_mode[xgifb_info->mode_idx].mode_no); - return -EINVAL; - } - info->fix.line_length = (info->var.xres_virtual - * info->var.bits_per_pixel) >> 6; - - xgifb_reg_set(vb->P3c4, IND_SIS_PASSWORD, SIS_PASSWORD); - - xgifb_reg_set(vb->P3d4, 0x13, (info->fix.line_length & 0x00ff)); - xgifb_reg_set(vb->P3c4, 0x0E, - (info->fix.line_length & 0xff00) >> 8); - - XGIfb_post_setmode(xgifb_info); - - pr_debug("Set new mode: %dx%dx%d-%d\n", - XGIbios_mode[xgifb_info->mode_idx].xres, - XGIbios_mode[xgifb_info->mode_idx].yres, - XGIbios_mode[xgifb_info->mode_idx].bpp, - xgifb_info->refresh_rate); - - xgifb_info->video_bpp = XGIbios_mode[xgifb_info->mode_idx].bpp; - xgifb_info->video_vwidth = info->var.xres_virtual; - xgifb_info->video_width = - XGIbios_mode[xgifb_info->mode_idx].xres; - xgifb_info->video_vheight = info->var.yres_virtual; - xgifb_info->video_height = - XGIbios_mode[xgifb_info->mode_idx].yres; - xgifb_info->org_x = 0; - xgifb_info->org_y = 0; - xgifb_info->video_linelength = info->var.xres_virtual - * (xgifb_info->video_bpp >> 3); - switch (xgifb_info->video_bpp) { - case 8: - xgifb_info->DstColor = 0x0000; - xgifb_info->XGI310_AccelDepth = 0x00000000; - xgifb_info->video_cmap_len = 256; -#if defined(__BIG_ENDIAN) - cr_data = xgifb_reg_get(vb->P3d4, 0x4D); - xgifb_reg_set(vb->P3d4, 0x4D, (cr_data & 0xE0)); -#endif - break; - case 16: - xgifb_info->DstColor = 0x8000; - xgifb_info->XGI310_AccelDepth = 0x00010000; -#if defined(__BIG_ENDIAN) - cr_data = xgifb_reg_get(vb->P3d4, 0x4D); - xgifb_reg_set(vb->P3d4, 0x4D, ((cr_data & 0xE0) | 0x0B)); -#endif - xgifb_info->video_cmap_len = 16; - break; - case 32: - xgifb_info->DstColor = 0xC000; - xgifb_info->XGI310_AccelDepth = 0x00020000; - xgifb_info->video_cmap_len = 16; -#if defined(__BIG_ENDIAN) - cr_data = xgifb_reg_get(vb->P3d4, 0x4D); - xgifb_reg_set(vb->P3d4, 0x4D, ((cr_data & 0xE0) | 0x15)); -#endif - break; - default: - xgifb_info->video_cmap_len = 16; - pr_err("Unsupported depth %d\n", - xgifb_info->video_bpp); - break; - } - } - XGIfb_bpp_to_var(xgifb_info, var); /* update ARGB info */ - - dumpVGAReg(xgifb_info); - return 0; -} - -static int XGIfb_pan_var(struct fb_var_screeninfo *var, struct fb_info *info) -{ - struct xgifb_video_info *xgifb_info = info->par; - struct vb_device_info *vb = &xgifb_info->dev_info; - unsigned int base; - - base = var->yoffset * info->var.xres_virtual + var->xoffset; - - /* calculate base bpp dep. */ - switch (info->var.bits_per_pixel) { - case 16: - base >>= 1; - break; - case 32: - break; - case 8: - default: - base >>= 2; - break; - } - - xgifb_reg_set(vb->P3c4, IND_SIS_PASSWORD, SIS_PASSWORD); - - xgifb_reg_set(vb->P3d4, 0x0D, base & 0xFF); - xgifb_reg_set(vb->P3d4, 0x0C, (base >> 8) & 0xFF); - xgifb_reg_set(vb->P3c4, 0x0D, (base >> 16) & 0xFF); - xgifb_reg_set(vb->P3c4, 0x37, (base >> 24) & 0x03); - xgifb_reg_and_or(vb->P3c4, 0x37, 0xDF, (base >> 21) & 0x04); - - if (xgifb_info->display2 != XGIFB_DISP_NONE) { - xgifb_reg_or(vb->Part1Port, SIS_CRT2_WENABLE_315, 0x01); - xgifb_reg_set(vb->Part1Port, 0x06, (base & 0xFF)); - xgifb_reg_set(vb->Part1Port, 0x05, ((base >> 8) & 0xFF)); - xgifb_reg_set(vb->Part1Port, 0x04, ((base >> 16) & 0xFF)); - xgifb_reg_and_or(vb->Part1Port, 0x02, 0x7F, - ((base >> 24) & 0x01) << 7); - } - return 0; -} - -static int XGIfb_open(struct fb_info *info, int user) -{ - return 0; -} - -static int XGIfb_release(struct fb_info *info, int user) -{ - return 0; -} - -/* similar to sisfb_get_cmap_len */ -static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var) -{ - return (var->bits_per_pixel == 8) ? 256 : 16; -} - -static int XGIfb_setcolreg(unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue, - unsigned int transp, struct fb_info *info) -{ - struct xgifb_video_info *xgifb_info = info->par; - struct vb_device_info *vb = &xgifb_info->dev_info; - - if (regno >= XGIfb_get_cmap_len(&info->var)) - return 1; - - switch (info->var.bits_per_pixel) { - case 8: - outb(regno, vb->P3c8); - outb((red >> 10), vb->P3c9); - outb((green >> 10), vb->P3c9); - outb((blue >> 10), vb->P3c9); - if (xgifb_info->display2 != XGIFB_DISP_NONE) { - outb(regno, vb->Part5Port); - outb((red >> 8), (vb->Part5Port + 1)); - outb((green >> 8), (vb->Part5Port + 1)); - outb((blue >> 8), (vb->Part5Port + 1)); - } - break; - case 16: - ((u32 *)(info->pseudo_palette))[regno] = ((red & 0xf800)) - | ((green & 0xfc00) >> 5) | ((blue & 0xf800) - >> 11); - break; - case 32: - red >>= 8; - green >>= 8; - blue >>= 8; - ((u32 *)(info->pseudo_palette))[regno] = (red << 16) | (green - << 8) | (blue); - break; - } - return 0; -} - -/* ----------- FBDev related routines for all series ---------- */ - -static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con, - struct fb_info *info) -{ - struct xgifb_video_info *xgifb_info = info->par; - - memset(fix, 0, sizeof(struct fb_fix_screeninfo)); - - strncpy(fix->id, "XGI", sizeof(fix->id) - 1); - - /* if register_framebuffer has been called, we must lock */ - if (atomic_read(&info->count)) - mutex_lock(&info->mm_lock); - - fix->smem_start = xgifb_info->video_base; - fix->smem_len = xgifb_info->video_size; - - /* if register_framebuffer has been called, we can unlock */ - if (atomic_read(&info->count)) - mutex_unlock(&info->mm_lock); - - fix->type = FB_TYPE_PACKED_PIXELS; - fix->type_aux = 0; - if (xgifb_info->video_bpp == 8) - fix->visual = FB_VISUAL_PSEUDOCOLOR; - else - fix->visual = FB_VISUAL_DIRECTCOLOR; - fix->xpanstep = 0; - if (XGIfb_ypan) - fix->ypanstep = 1; - fix->ywrapstep = 0; - fix->line_length = xgifb_info->video_linelength; - fix->mmio_start = xgifb_info->mmio_base; - fix->mmio_len = xgifb_info->mmio_size; - fix->accel = FB_ACCEL_SIS_XABRE; - - return 0; -} - -static int XGIfb_set_par(struct fb_info *info) -{ - int err; - - err = XGIfb_do_set_var(&info->var, 1, info); - if (err) - return err; - XGIfb_get_fix(&info->fix, -1, info); - return 0; -} - -static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) -{ - struct xgifb_video_info *xgifb_info = info->par; - unsigned int htotal = var->left_margin + var->xres + var->right_margin - + var->hsync_len; - unsigned int vtotal = 0; - unsigned int drate = 0, hrate = 0; - int found_mode = 0; - int search_idx; - - if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) { - vtotal = var->upper_margin + var->yres + var->lower_margin - + var->vsync_len; - vtotal <<= 1; - } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) { - vtotal = var->upper_margin + var->yres + var->lower_margin - + var->vsync_len; - vtotal <<= 2; - } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) { - vtotal = var->upper_margin + (var->yres / 2) - + var->lower_margin + var->vsync_len; - } else - vtotal = var->upper_margin + var->yres + var->lower_margin - + var->vsync_len; - - if (!(htotal) || !(vtotal)) { - pr_debug("No valid timing data\n"); - return -EINVAL; - } - - if (var->pixclock && htotal && vtotal) { - drate = 1000000000 / var->pixclock; - hrate = (drate * 1000) / htotal; - xgifb_info->refresh_rate = - (unsigned int)(hrate * 2 / vtotal); - pr_debug( - "%s: pixclock = %d ,htotal=%d, vtotal=%d\n" - "%s: drate=%d, hrate=%d, refresh_rate=%d\n", - __func__, var->pixclock, htotal, vtotal, - __func__, drate, hrate, xgifb_info->refresh_rate); - } else { - xgifb_info->refresh_rate = 60; - } - - search_idx = 0; - while ((XGIbios_mode[search_idx].mode_no != 0) && - (XGIbios_mode[search_idx].xres <= var->xres)) { - if ((XGIbios_mode[search_idx].xres == var->xres) && - (XGIbios_mode[search_idx].yres == var->yres) && - (XGIbios_mode[search_idx].bpp == var->bits_per_pixel)) { - if (XGIfb_validate_mode(xgifb_info, search_idx) > 0) { - found_mode = 1; - break; - } - } - search_idx++; - } - - if (!found_mode) { - pr_err("%dx%dx%d is no valid mode\n", - var->xres, var->yres, var->bits_per_pixel); - search_idx = 0; - while (XGIbios_mode[search_idx].mode_no != 0) { - if ((var->xres <= XGIbios_mode[search_idx].xres) && - (var->yres <= XGIbios_mode[search_idx].yres) && - (var->bits_per_pixel == - XGIbios_mode[search_idx].bpp)) { - if (XGIfb_validate_mode(xgifb_info, - search_idx) > 0) { - found_mode = 1; - break; - } - } - search_idx++; - } - if (found_mode) { - var->xres = XGIbios_mode[search_idx].xres; - var->yres = XGIbios_mode[search_idx].yres; - pr_debug("Adapted to mode %dx%dx%d\n", - var->xres, var->yres, var->bits_per_pixel); - - } else { - pr_err("Failed to find similar mode to %dx%dx%d\n", - var->xres, var->yres, var->bits_per_pixel); - return -EINVAL; - } - } - - /* Adapt RGB settings */ - XGIfb_bpp_to_var(xgifb_info, var); - - if (!XGIfb_ypan) { - if (var->xres != var->xres_virtual) - var->xres_virtual = var->xres; - if (var->yres != var->yres_virtual) - var->yres_virtual = var->yres; - } - - /* Truncate offsets to maximum if too high */ - if (var->xoffset > var->xres_virtual - var->xres) - var->xoffset = var->xres_virtual - var->xres - 1; - - if (var->yoffset > var->yres_virtual - var->yres) - var->yoffset = var->yres_virtual - var->yres - 1; - - /* Set everything else to 0 */ - var->red.msb_right = 0; - var->green.msb_right = 0; - var->blue.msb_right = 0; - var->transp.offset = 0; - var->transp.length = 0; - var->transp.msb_right = 0; - - return 0; -} - -static int XGIfb_pan_display(struct fb_var_screeninfo *var, - struct fb_info *info) -{ - int err; - - if (var->xoffset > (info->var.xres_virtual - info->var.xres)) - return -EINVAL; - if (var->yoffset > (info->var.yres_virtual - info->var.yres)) - return -EINVAL; - - if (var->vmode & FB_VMODE_YWRAP) { - if (var->yoffset >= info->var.yres_virtual || var->xoffset) - return -EINVAL; - } else if (var->xoffset + info->var.xres > info->var.xres_virtual || - var->yoffset + info->var.yres > info->var.yres_virtual) { - return -EINVAL; - } - err = XGIfb_pan_var(var, info); - if (err < 0) - return err; - - info->var.xoffset = var->xoffset; - info->var.yoffset = var->yoffset; - if (var->vmode & FB_VMODE_YWRAP) - info->var.vmode |= FB_VMODE_YWRAP; - else - info->var.vmode &= ~FB_VMODE_YWRAP; - - return 0; -} - -static int XGIfb_blank(int blank, struct fb_info *info) -{ - struct xgifb_video_info *xgifb_info = info->par; - struct vb_device_info *vb = &xgifb_info->dev_info; - u8 reg; - - reg = xgifb_reg_get(vb->P3d4, 0x17); - - if (blank > 0) - reg &= 0x7f; - else - reg |= 0x80; - - xgifb_reg_set(vb->P3d4, 0x17, reg); - xgifb_reg_set(vb->P3c4, 0x00, 0x01); /* Synchronous Reset */ - xgifb_reg_set(vb->P3c4, 0x00, 0x03); /* End Reset */ - return 0; -} - -static struct fb_ops XGIfb_ops = { - .owner = THIS_MODULE, - .fb_open = XGIfb_open, - .fb_release = XGIfb_release, - .fb_check_var = XGIfb_check_var, - .fb_set_par = XGIfb_set_par, - .fb_setcolreg = XGIfb_setcolreg, - .fb_pan_display = XGIfb_pan_display, - .fb_blank = XGIfb_blank, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, -}; - -/* ---------------- Chip generation dependent routines ---------------- */ - -/* for XGI 315/550/650/740/330 */ - -static int XGIfb_get_dram_size(struct xgifb_video_info *xgifb_info) -{ - struct vb_device_info *vb = &xgifb_info->dev_info; - u8 ChannelNum, tmp; - u8 reg = 0; - - /* xorg driver sets 32MB * 1 channel */ - if (xgifb_info->chip == XG27) - xgifb_reg_set(vb->P3c4, IND_SIS_DRAM_SIZE, 0x51); - - reg = xgifb_reg_get(vb->P3c4, IND_SIS_DRAM_SIZE); - if (!reg) - return -1; - - switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) { - case XGI_DRAM_SIZE_1MB: - xgifb_info->video_size = 0x100000; - break; - case XGI_DRAM_SIZE_2MB: - xgifb_info->video_size = 0x200000; - break; - case XGI_DRAM_SIZE_4MB: - xgifb_info->video_size = 0x400000; - break; - case XGI_DRAM_SIZE_8MB: - xgifb_info->video_size = 0x800000; - break; - case XGI_DRAM_SIZE_16MB: - xgifb_info->video_size = 0x1000000; - break; - case XGI_DRAM_SIZE_32MB: - xgifb_info->video_size = 0x2000000; - break; - case XGI_DRAM_SIZE_64MB: - xgifb_info->video_size = 0x4000000; - break; - case XGI_DRAM_SIZE_128MB: - xgifb_info->video_size = 0x8000000; - break; - case XGI_DRAM_SIZE_256MB: - xgifb_info->video_size = 0x10000000; - break; - default: - return -1; - } - - tmp = (reg & 0x0c) >> 2; - switch (xgifb_info->chip) { - case XG20: - case XG21: - case XG27: - ChannelNum = 1; - break; - - case XG42: - if (reg & 0x04) - ChannelNum = 2; - else - ChannelNum = 1; - break; - - case XG40: - default: - if (tmp == 2) - ChannelNum = 2; - else if (tmp == 3) - ChannelNum = 3; - else - ChannelNum = 1; - break; - } - - xgifb_info->video_size = xgifb_info->video_size * ChannelNum; - - pr_info("SR14=%x DramSzie %x ChannelNum %x\n", - reg, xgifb_info->video_size, ChannelNum); - return 0; -} - -static void XGIfb_detect_VB(struct xgifb_video_info *xgifb_info) -{ - struct vb_device_info *vb = &xgifb_info->dev_info; - u8 cr32, temp = 0; - - xgifb_info->TV_plug = 0; - xgifb_info->TV_type = 0; - - cr32 = xgifb_reg_get(vb->P3d4, IND_XGI_SCRATCH_REG_CR32); - - if ((cr32 & SIS_CRT1) && !XGIfb_crt1off) { - XGIfb_crt1off = 0; - } else { - if (cr32 & 0x5F) - XGIfb_crt1off = 1; - else - XGIfb_crt1off = 0; - } - - if (!xgifb_info->display2_force) { - if (cr32 & SIS_VB_TV) - xgifb_info->display2 = XGIFB_DISP_TV; - else if (cr32 & SIS_VB_LCD) - xgifb_info->display2 = XGIFB_DISP_LCD; - else if (cr32 & SIS_VB_CRT2) - xgifb_info->display2 = XGIFB_DISP_CRT; - else - xgifb_info->display2 = XGIFB_DISP_NONE; - } - - if (XGIfb_tvplug != -1) { - /* Override with option */ - xgifb_info->TV_plug = XGIfb_tvplug; - } else if (cr32 & SIS_VB_HIVISION) { - xgifb_info->TV_type = TVMODE_HIVISION; - xgifb_info->TV_plug = TVPLUG_SVIDEO; - } else if (cr32 & SIS_VB_SVIDEO) { - xgifb_info->TV_plug = TVPLUG_SVIDEO; - } else if (cr32 & SIS_VB_COMPOSITE) { - xgifb_info->TV_plug = TVPLUG_COMPOSITE; - } else if (cr32 & SIS_VB_SCART) { - xgifb_info->TV_plug = TVPLUG_SCART; - } - - if (xgifb_info->TV_type == 0) { - temp = xgifb_reg_get(vb->P3d4, 0x38); - if (temp & 0x10) - xgifb_info->TV_type = TVMODE_PAL; - else - xgifb_info->TV_type = TVMODE_NTSC; - } - - /* Copy forceCRT1 option to CRT1off if option is given */ - if (XGIfb_forcecrt1 != -1) { - if (XGIfb_forcecrt1) - XGIfb_crt1off = 0; - else - XGIfb_crt1off = 1; - } -} - -static bool XGIfb_has_VB(struct xgifb_video_info *xgifb_info) -{ - u8 vb_chipid; - - vb_chipid = xgifb_reg_get(xgifb_info->dev_info.Part4Port, 0x00); - switch (vb_chipid) { - case 0x01: - xgifb_info->hasVB = HASVB_301; - break; - case 0x02: - xgifb_info->hasVB = HASVB_302; - break; - default: - xgifb_info->hasVB = HASVB_NONE; - return false; - } - return true; -} - -static void XGIfb_get_VB_type(struct xgifb_video_info *xgifb_info) -{ - u8 reg; - - if (!XGIfb_has_VB(xgifb_info)) { - reg = xgifb_reg_get(xgifb_info->dev_info.P3d4, - IND_XGI_SCRATCH_REG_CR37); - switch ((reg & SIS_EXTERNAL_CHIP_MASK) >> 1) { - case SIS_EXTERNAL_CHIP_LVDS: - xgifb_info->hasVB = HASVB_LVDS; - break; - case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL: - xgifb_info->hasVB = HASVB_LVDS_CHRONTEL; - break; - default: - break; - } - } -} - -static int __init xgifb_optval(char *fullopt, int validx) -{ - unsigned long lres; - - if (kstrtoul(fullopt + validx, 0, &lres) < 0 || lres > INT_MAX) { - pr_err("Invalid value for option: %s\n", fullopt); - return 0; - } - return lres; -} - -static int __init XGIfb_setup(char *options) -{ - char *this_opt; - - if (!options || !*options) - return 0; - - pr_info("Options: %s\n", options); - - while ((this_opt = strsep(&options, ",")) != NULL) { - if (!*this_opt) - continue; - - if (!strncmp(this_opt, "mode:", 5)) { - mode = this_opt + 5; - } else if (!strncmp(this_opt, "vesa:", 5)) { - vesa = xgifb_optval(this_opt, 5); - } else if (!strncmp(this_opt, "vrate:", 6)) { - refresh_rate = xgifb_optval(this_opt, 6); - } else if (!strncmp(this_opt, "rate:", 5)) { - refresh_rate = xgifb_optval(this_opt, 5); - } else if (!strncmp(this_opt, "crt1off", 7)) { - XGIfb_crt1off = 1; - } else if (!strncmp(this_opt, "filter:", 7)) { - filter = xgifb_optval(this_opt, 7); - } else if (!strncmp(this_opt, "forcecrt2type:", 14)) { - XGIfb_search_crt2type(this_opt + 14); - } else if (!strncmp(this_opt, "forcecrt1:", 10)) { - XGIfb_forcecrt1 = xgifb_optval(this_opt, 10); - } else if (!strncmp(this_opt, "tvmode:", 7)) { - XGIfb_search_tvstd(this_opt + 7); - } else if (!strncmp(this_opt, "tvstandard:", 11)) { - XGIfb_search_tvstd(this_opt + 7); - } else if (!strncmp(this_opt, "dstn", 4)) { - enable_dstn = 1; - /* DSTN overrules forcecrt2type */ - XGIfb_crt2type = XGIFB_DISP_LCD; - } else if (!strncmp(this_opt, "noypan", 6)) { - XGIfb_ypan = 0; - } else { - mode = this_opt; - } - } - return 0; -} - -static int xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - u8 reg, reg1; - u8 CR48, CR38; - int ret; - struct fb_info *fb_info; - struct xgifb_video_info *xgifb_info; - struct vb_device_info *vb; - struct xgi_hw_device_info *hw_info; - unsigned long video_size_max; - - fb_info = framebuffer_alloc(sizeof(*xgifb_info), &pdev->dev); - if (!fb_info) - return -ENOMEM; - - xgifb_info = fb_info->par; - vb = &xgifb_info->dev_info; - hw_info = &xgifb_info->hw_info; - xgifb_info->fb_info = fb_info; - xgifb_info->chip_id = pdev->device; - pci_read_config_byte(pdev, - PCI_REVISION_ID, - &xgifb_info->revision_id); - hw_info->jChipRevision = xgifb_info->revision_id; - - xgifb_info->pcibus = pdev->bus->number; - xgifb_info->pcislot = PCI_SLOT(pdev->devfn); - xgifb_info->pcifunc = PCI_FUNC(pdev->devfn); - xgifb_info->subsysvendor = pdev->subsystem_vendor; - xgifb_info->subsysdevice = pdev->subsystem_device; - - video_size_max = pci_resource_len(pdev, 0); - xgifb_info->video_base = pci_resource_start(pdev, 0); - xgifb_info->mmio_base = pci_resource_start(pdev, 1); - xgifb_info->mmio_size = pci_resource_len(pdev, 1); - xgifb_info->vga_base = pci_resource_start(pdev, 2) + 0x30; - dev_info(&pdev->dev, "Relocate IO address: %llx [%08lx]\n", - (u64)pci_resource_start(pdev, 2), - xgifb_info->vga_base); - - if (pci_enable_device(pdev)) { - ret = -EIO; - goto error; - } - - if (XGIfb_crt2type != -1) { - xgifb_info->display2 = XGIfb_crt2type; - xgifb_info->display2_force = true; - } - - XGIRegInit(vb, xgifb_info->vga_base); - - xgifb_reg_set(vb->P3c4, - IND_SIS_PASSWORD, SIS_PASSWORD); - reg1 = xgifb_reg_get(vb->P3c4, IND_SIS_PASSWORD); - - if (reg1 != 0xa1) { /* I/O error */ - dev_err(&pdev->dev, "I/O error\n"); - ret = -EIO; - goto error_disable; - } - - switch (xgifb_info->chip_id) { - case PCI_DEVICE_ID_XGI_20: - xgifb_reg_or(vb->P3d4, - Index_CR_GPIO_Reg3, GPIOG_EN); - CR48 = xgifb_reg_get(vb->P3d4, - Index_CR_GPIO_Reg1); - if (CR48 & GPIOG_READ) - xgifb_info->chip = XG21; - else - xgifb_info->chip = XG20; - break; - case PCI_DEVICE_ID_XGI_40: - xgifb_info->chip = XG40; - break; - case PCI_DEVICE_ID_XGI_42: - xgifb_info->chip = XG42; - break; - case PCI_DEVICE_ID_XGI_27: - xgifb_info->chip = XG27; - break; - default: - ret = -ENODEV; - goto error_disable; - } - - dev_info(&pdev->dev, "chipid = %x\n", xgifb_info->chip); - hw_info->jChipType = xgifb_info->chip; - - if (XGIfb_get_dram_size(xgifb_info)) { - xgifb_info->video_size = min_t(unsigned long, video_size_max, - SZ_16M); - } else if (xgifb_info->video_size > video_size_max) { - xgifb_info->video_size = video_size_max; - } - - /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */ - xgifb_reg_or(vb->P3c4, - IND_SIS_PCI_ADDRESS_SET, - (SIS_PCI_ADDR_ENABLE | SIS_MEM_MAP_IO_ENABLE)); - /* Enable 2D accelerator engine */ - xgifb_reg_or(vb->P3c4, - IND_SIS_MODULE_ENABLE, SIS_ENABLE_2D); - - hw_info->ulVideoMemorySize = xgifb_info->video_size; - - if (!request_mem_region(xgifb_info->video_base, - xgifb_info->video_size, - "XGIfb FB")) { - dev_err(&pdev->dev, "Unable request memory size %x\n", - xgifb_info->video_size); - dev_err(&pdev->dev, - "Fatal error: Unable to reserve frame buffer memory. Is there another framebuffer driver active?\n"); - ret = -ENODEV; - goto error_disable; - } - - if (!request_mem_region(xgifb_info->mmio_base, - xgifb_info->mmio_size, - "XGIfb MMIO")) { - dev_err(&pdev->dev, - "Fatal error: Unable to reserve MMIO region\n"); - ret = -ENODEV; - goto error_0; - } - - xgifb_info->video_vbase = - ioremap_wc(xgifb_info->video_base, xgifb_info->video_size); - hw_info->pjVideoMemoryAddress = - ioremap_wc(xgifb_info->video_base, xgifb_info->video_size); - xgifb_info->mmio_vbase = ioremap(xgifb_info->mmio_base, - xgifb_info->mmio_size); - - dev_info(&pdev->dev, - "Framebuffer at 0x%llx, mapped to 0x%p, size %dk\n", - (u64)xgifb_info->video_base, - xgifb_info->video_vbase, - xgifb_info->video_size / 1024); - - dev_info(&pdev->dev, - "MMIO at 0x%llx, mapped to 0x%p, size %ldk\n", - (u64)xgifb_info->mmio_base, xgifb_info->mmio_vbase, - xgifb_info->mmio_size / 1024); - - pci_set_drvdata(pdev, xgifb_info); - if (!XGIInitNew(pdev)) - dev_err(&pdev->dev, "XGIInitNew() failed!\n"); - - xgifb_info->mtrr = -1; - - xgifb_info->hasVB = HASVB_NONE; - if ((xgifb_info->chip == XG20) || - (xgifb_info->chip == XG27)) { - xgifb_info->hasVB = HASVB_NONE; - } else if (xgifb_info->chip == XG21) { - CR38 = xgifb_reg_get(vb->P3d4, 0x38); - if ((CR38 & 0xE0) == 0xC0) - xgifb_info->display2 = XGIFB_DISP_LCD; - else if ((CR38 & 0xE0) == 0x60) - xgifb_info->hasVB = HASVB_CHRONTEL; - else - xgifb_info->hasVB = HASVB_NONE; - } else { - XGIfb_get_VB_type(xgifb_info); - } - - hw_info->ujVBChipID = VB_CHIP_UNKNOWN; - - hw_info->ulExternalChip = 0; - - switch (xgifb_info->hasVB) { - case HASVB_301: - reg = xgifb_reg_get(vb->Part4Port, 0x01); - if (reg >= 0xE0) { - hw_info->ujVBChipID = VB_CHIP_302LV; - dev_info(&pdev->dev, - "XGI302LV bridge detected (revision 0x%02x)\n", - reg); - } else if (reg >= 0xD0) { - hw_info->ujVBChipID = VB_CHIP_301LV; - dev_info(&pdev->dev, - "XGI301LV bridge detected (revision 0x%02x)\n", - reg); - } else { - hw_info->ujVBChipID = VB_CHIP_301; - dev_info(&pdev->dev, "XGI301 bridge detected\n"); - } - break; - case HASVB_302: - reg = xgifb_reg_get(vb->Part4Port, 0x01); - if (reg >= 0xE0) { - hw_info->ujVBChipID = VB_CHIP_302LV; - dev_info(&pdev->dev, - "XGI302LV bridge detected (revision 0x%02x)\n", - reg); - } else if (reg >= 0xD0) { - hw_info->ujVBChipID = VB_CHIP_301LV; - dev_info(&pdev->dev, - "XGI302LV bridge detected (revision 0x%02x)\n", - reg); - } else if (reg >= 0xB0) { - reg1 = xgifb_reg_get(vb->Part4Port, - 0x23); - - hw_info->ujVBChipID = VB_CHIP_302B; - - } else { - hw_info->ujVBChipID = VB_CHIP_302; - dev_info(&pdev->dev, "XGI302 bridge detected\n"); - } - break; - case HASVB_LVDS: - hw_info->ulExternalChip = 0x1; - dev_info(&pdev->dev, "LVDS transmitter detected\n"); - break; - case HASVB_TRUMPION: - hw_info->ulExternalChip = 0x2; - dev_info(&pdev->dev, "Trumpion Zurac LVDS scaler detected\n"); - break; - case HASVB_CHRONTEL: - hw_info->ulExternalChip = 0x4; - dev_info(&pdev->dev, "Chrontel TV encoder detected\n"); - break; - case HASVB_LVDS_CHRONTEL: - hw_info->ulExternalChip = 0x5; - dev_info(&pdev->dev, - "LVDS transmitter and Chrontel TV encoder detected\n"); - break; - default: - dev_info(&pdev->dev, "No or unknown bridge type detected\n"); - break; - } - - if (xgifb_info->hasVB != HASVB_NONE) - XGIfb_detect_VB(xgifb_info); - else if (xgifb_info->chip != XG21) - xgifb_info->display2 = XGIFB_DISP_NONE; - - if (xgifb_info->display2 == XGIFB_DISP_LCD) { - if (!enable_dstn) { - reg = xgifb_reg_get(vb->P3d4, - IND_XGI_LCD_PANEL); - reg &= 0x0f; - hw_info->ulCRT2LCDType = XGI310paneltype[reg]; - } - } - - xgifb_info->mode_idx = -1; - - if (mode) - XGIfb_search_mode(xgifb_info, mode); - else if (vesa != -1) - XGIfb_search_vesamode(xgifb_info, vesa); - - if (xgifb_info->mode_idx >= 0) - xgifb_info->mode_idx = - XGIfb_validate_mode(xgifb_info, xgifb_info->mode_idx); - - if (xgifb_info->mode_idx < 0) { - if (xgifb_info->display2 == XGIFB_DISP_LCD && - xgifb_info->chip == XG21) - xgifb_info->mode_idx = - XGIfb_GetXG21DefaultLVDSModeIdx(xgifb_info); - else - xgifb_info->mode_idx = DEFAULT_MODE; - } - - if (xgifb_info->mode_idx < 0) { - dev_err(&pdev->dev, "No supported video mode found\n"); - ret = -EINVAL; - goto error_1; - } - - /* set default refresh rate */ - xgifb_info->refresh_rate = refresh_rate; - if (xgifb_info->refresh_rate == 0) - xgifb_info->refresh_rate = 60; - if (XGIfb_search_refresh_rate(xgifb_info, xgifb_info->refresh_rate) == 0) { - xgifb_info->rate_idx = 1; - xgifb_info->refresh_rate = 60; - } - - xgifb_info->video_bpp = XGIbios_mode[xgifb_info->mode_idx].bpp; - xgifb_info->video_vwidth = - xgifb_info->video_width = - XGIbios_mode[xgifb_info->mode_idx].xres; - xgifb_info->video_vheight = - xgifb_info->video_height = - XGIbios_mode[xgifb_info->mode_idx].yres; - xgifb_info->org_x = 0; - xgifb_info->org_y = 0; - xgifb_info->video_linelength = - xgifb_info->video_width * - (xgifb_info->video_bpp >> 3); - switch (xgifb_info->video_bpp) { - case 8: - xgifb_info->DstColor = 0x0000; - xgifb_info->XGI310_AccelDepth = 0x00000000; - xgifb_info->video_cmap_len = 256; - break; - case 16: - xgifb_info->DstColor = 0x8000; - xgifb_info->XGI310_AccelDepth = 0x00010000; - xgifb_info->video_cmap_len = 16; - break; - case 32: - xgifb_info->DstColor = 0xC000; - xgifb_info->XGI310_AccelDepth = 0x00020000; - xgifb_info->video_cmap_len = 16; - break; - default: - xgifb_info->video_cmap_len = 16; - pr_info("Unsupported depth %d\n", - xgifb_info->video_bpp); - break; - } - - pr_info("Default mode is %dx%dx%d (%dHz)\n", - xgifb_info->video_width, xgifb_info->video_height, - xgifb_info->video_bpp, xgifb_info->refresh_rate); - - fb_info->var.red.length = 8; - fb_info->var.green.length = 8; - fb_info->var.blue.length = 8; - fb_info->var.activate = FB_ACTIVATE_NOW; - fb_info->var.height = -1; - fb_info->var.width = -1; - fb_info->var.vmode = FB_VMODE_NONINTERLACED; - fb_info->var.xres = xgifb_info->video_width; - fb_info->var.xres_virtual = xgifb_info->video_width; - fb_info->var.yres = xgifb_info->video_height; - fb_info->var.yres_virtual = xgifb_info->video_height; - fb_info->var.bits_per_pixel = xgifb_info->video_bpp; - - XGIfb_bpp_to_var(xgifb_info, &fb_info->var); - - fb_info->var.pixclock = (u32)(1000000000 / XGIfb_mode_rate_to_dclock - (vb, hw_info, - XGIbios_mode[xgifb_info->mode_idx].mode_no)); - - if (XGIfb_mode_rate_to_ddata(vb, hw_info, - XGIbios_mode[xgifb_info->mode_idx].mode_no, - &fb_info->var.left_margin, - &fb_info->var.right_margin, - &fb_info->var.upper_margin, - &fb_info->var.lower_margin, - &fb_info->var.hsync_len, - &fb_info->var.vsync_len, - &fb_info->var.sync, - &fb_info->var.vmode)) { - if ((fb_info->var.vmode & FB_VMODE_MASK) == - FB_VMODE_INTERLACED) { - fb_info->var.yres <<= 1; - fb_info->var.yres_virtual <<= 1; - } else if ((fb_info->var.vmode & FB_VMODE_MASK) == - FB_VMODE_DOUBLE) { - fb_info->var.pixclock >>= 1; - fb_info->var.yres >>= 1; - fb_info->var.yres_virtual >>= 1; - } - } - - fb_info->flags = FBINFO_FLAG_DEFAULT; - fb_info->screen_base = xgifb_info->video_vbase; - fb_info->fbops = &XGIfb_ops; - XGIfb_get_fix(&fb_info->fix, -1, fb_info); - fb_info->pseudo_palette = xgifb_info->pseudo_palette; - - fb_alloc_cmap(&fb_info->cmap, 256, 0); - - xgifb_info->mtrr = arch_phys_wc_add(xgifb_info->video_base, - xgifb_info->video_size); - - if (register_framebuffer(fb_info) < 0) { - ret = -EINVAL; - goto error_mtrr; - } - - dumpVGAReg(xgifb_info); - - return 0; - -error_mtrr: - arch_phys_wc_del(xgifb_info->mtrr); -error_1: - iounmap(xgifb_info->mmio_vbase); - iounmap(xgifb_info->video_vbase); - release_mem_region(xgifb_info->mmio_base, xgifb_info->mmio_size); -error_0: - release_mem_region(xgifb_info->video_base, xgifb_info->video_size); -error_disable: - pci_disable_device(pdev); -error: - framebuffer_release(fb_info); - return ret; -} - -/* -------------------- PCI DEVICE HANDLING -------------------- */ - -static void xgifb_remove(struct pci_dev *pdev) -{ - struct xgifb_video_info *xgifb_info = pci_get_drvdata(pdev); - struct fb_info *fb_info = xgifb_info->fb_info; - - unregister_framebuffer(fb_info); - arch_phys_wc_del(xgifb_info->mtrr); - iounmap(xgifb_info->mmio_vbase); - iounmap(xgifb_info->video_vbase); - release_mem_region(xgifb_info->mmio_base, xgifb_info->mmio_size); - release_mem_region(xgifb_info->video_base, xgifb_info->video_size); - pci_disable_device(pdev); - framebuffer_release(fb_info); -} - -static struct pci_driver xgifb_driver = { - .name = "xgifb", - .id_table = xgifb_pci_table, - .probe = xgifb_probe, - .remove = xgifb_remove -}; - -/* -------------------- MODULE -------------------- */ - -module_param(mode, charp, 0000); -MODULE_PARM_DESC(mode, - "Selects the desired default display mode in the format XxYxDepth (eg. 1024x768x16)."); - -module_param(forcecrt2type, charp, 0000); -MODULE_PARM_DESC(forcecrt2type, - "Force the second display output type. Possible values are NONE, LCD, TV, VGA, SVIDEO or COMPOSITE."); - -module_param(vesa, int, 0000); -MODULE_PARM_DESC(vesa, - "Selects the desired default display mode by VESA mode number (eg. 0x117)."); - -module_param(filter, int, 0000); -MODULE_PARM_DESC(filter, - "Selects TV flicker filter type (only for systems with a SiS301 video bridge). Possible values 0-7. Default: [no filter])."); - -static int __init xgifb_init(void) -{ - char *option = NULL; - - if (forcecrt2type) - XGIfb_search_crt2type(forcecrt2type); - if (fb_get_options("xgifb", &option)) - return -ENODEV; - XGIfb_setup(option); - - return pci_register_driver(&xgifb_driver); -} - -static void __exit xgifb_remove_module(void) -{ - pci_unregister_driver(&xgifb_driver); - pr_debug("Module unloaded\n"); -} - -MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("XGITECH , Others"); -module_init(xgifb_init); -module_exit(xgifb_remove_module); diff --git a/drivers/staging/xgifb/XGIfb.h b/drivers/staging/xgifb/XGIfb.h deleted file mode 100644 index 982c676c16c6..000000000000 --- a/drivers/staging/xgifb/XGIfb.h +++ /dev/null @@ -1,109 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _LINUX_XGIFB -#define _LINUX_XGIFB -#include "vgatypes.h" -#include "vb_struct.h" - -enum xgifb_display_type { - XGIFB_DISP_NONE = 0, - XGIFB_DISP_CRT, - XGIFB_DISP_LCD, - XGIFB_DISP_TV, -}; - -#define HASVB_NONE 0x00 -#define HASVB_301 0x01 -#define HASVB_LVDS 0x02 -#define HASVB_TRUMPION 0x04 -#define HASVB_LVDS_CHRONTEL 0x10 -#define HASVB_302 0x20 -#define HASVB_CHRONTEL 0x80 - -enum XGI_CHIP_TYPE { - XG40 = 32, - XG42, - XG20 = 48, - XG21, - XG27, -}; - -enum xgi_tvtype { - TVMODE_NTSC = 0, - TVMODE_PAL, - TVMODE_HIVISION, - TVTYPE_PALM, - TVTYPE_PALN, - TVTYPE_NTSCJ, - TVMODE_TOTAL -}; - -enum xgi_tv_plug { - TVPLUG_UNKNOWN = 0, - TVPLUG_COMPOSITE = 1, - TVPLUG_SVIDEO = 2, - TVPLUG_COMPOSITE_AND_SVIDEO = 3, - TVPLUG_SCART = 4, - TVPLUG_YPBPR_525i = 5, - TVPLUG_YPBPR_525P = 6, - TVPLUG_YPBPR_750P = 7, - TVPLUG_YPBPR_1080i = 8, - TVPLUG_TOTAL -}; - -struct xgifb_video_info { - struct fb_info *fb_info; - struct xgi_hw_device_info hw_info; - struct vb_device_info dev_info; - - int mode_idx; - int rate_idx; - - u32 pseudo_palette[17]; - - int chip_id; - unsigned int video_size; - phys_addr_t video_base; - void __iomem *video_vbase; - phys_addr_t mmio_base; - unsigned long mmio_size; - void __iomem *mmio_vbase; - unsigned long vga_base; - int mtrr; - - int video_bpp; - int video_cmap_len; - int video_width; - int video_height; - int video_vwidth; - int video_vheight; - int org_x; - int org_y; - int video_linelength; - unsigned int refresh_rate; - - enum xgifb_display_type display2; /* the second display output type */ - bool display2_force; - unsigned char hasVB; - unsigned char TV_type; - unsigned char TV_plug; - - struct XGI21_LVDSCapStruct lvds_data; - - enum XGI_CHIP_TYPE chip; - unsigned char revision_id; - - unsigned short DstColor; - unsigned long XGI310_AccelDepth; - unsigned long CommandReg; - - unsigned int pcibus; - unsigned int pcislot; - unsigned int pcifunc; - - unsigned short subsysvendor; - unsigned short subsysdevice; - - char reserved[236]; -}; - -#endif diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h deleted file mode 100644 index 0311e2682d27..000000000000 --- a/drivers/staging/xgifb/vb_def.h +++ /dev/null @@ -1,257 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _VB_DEF_ -#define _VB_DEF_ -#include "../../video/fbdev/sis/initdef.h" - -#define VB_XGI301C 0x0020 /* for 301C */ - -#define SupportCRT2in301C 0x0100 /* for 301C */ -#define SetCHTVOverScan 0x8000 - -#define PanelResInfo 0x1F /* CR36 Panel Type/LCDResInfo */ -#define Panel_1024x768x75 0x22 -#define Panel_1280x1024x75 0x23 - -#define PanelRef60Hz 0x00 -#define PanelRef75Hz 0x20 - -#define YPbPr525iVCLK 0x03B -#define YPbPr525iVCLK_2 0x03A - -#define XGI_CRT2_PORT_00 (0x00 - 0x030) - -#define SupportAllCRT2 0x0078 -#define NoSupportTV 0x0070 -#define NoSupportHiVisionTV 0x0060 -#define NoSupportLCD 0x0058 - -/* -------------- SetMode Stack/Scratch */ -#define XGI_SetCRT2ToLCDA 0x0100 -#define SetCRT2ToDualEdge 0x8000 - -#define ReserveTVOption 0x0008 - -#define SetTVLowResolution 0x0400 -#define TVSimuMode 0x0800 -#define RPLLDIV2XO 0x1000 -#define NTSC1024x768 0x2000 -#define SetTVLockMode 0x4000 - -#define XGI_LCDVESATiming 0x0001 /* LCD Info/CR37 */ -#define XGI_EnableLVDSDDA 0x0002 -#define EnableScalingLCD 0x0008 -#define SetPWDEnable 0x0004 -#define SetLCDtoNonExpanding 0x0010 -#define SetLCDDualLink 0x0100 -#define SetLCDLowResolution 0x0200 - -/* LCD Capability shampoo */ -#define DefaultLCDCap 0x80ea -#define EnableLCD24bpp 0x0004 /* default */ -#define LCDPolarity 0x00c0 /* default: SyncNN */ -#define XGI_LCDDualLink 0x0100 -#define EnableSpectrum 0x0200 -#define PWDEnable 0x0400 -#define EnableVBCLKDRVLOW 0x4000 -#define EnablePLLSPLOW 0x8000 - -#define AVIDEOSense 0x01 /* CR32 */ -#define SVIDEOSense 0x02 -#define SCARTSense 0x04 -#define LCDSense 0x08 -#define Monitor2Sense 0x10 -#define Monitor1Sense 0x20 -#define HiTVSense 0x40 - -#define YPbPrSense 0x80 /* NEW SCRATCH */ - -#define TVSense 0xc7 - -#define YPbPrMode 0xe0 -#define YPbPrMode525i 0x00 -#define YPbPrMode525p 0x20 -#define YPbPrMode750p 0x40 -#define YPbPrMode1080i 0x60 - -#define ScalingLCD 0x08 - -#define SetYPbPr 0x04 - -/* ---------------------- VUMA Information */ -#define DisplayDeviceFromCMOS 0x10 - -/* ---------------------- HK Evnet Definition */ -#define XGI_ModeSwitchStatus 0xf0 -#define ActiveCRT1 0x10 -#define ActiveLCD 0x0020 -#define ActiveTV 0x40 -#define ActiveCRT2 0x80 - -#define ActiveAVideo 0x01 -#define ActiveSVideo 0x02 -#define ActiveSCART 0x04 -#define ActiveHiTV 0x08 -#define ActiveYPbPr 0x10 - -#define NTSC1024x768HT 1908 - -#define YPbPrTV525iHT 1716 /* YPbPr */ -#define YPbPrTV525iVT 525 -#define YPbPrTV525pHT 1716 -#define YPbPrTV525pVT 525 -#define YPbPrTV750pHT 1650 -#define YPbPrTV750pVT 750 - -#define VCLK25_175 0x00 -#define VCLK28_322 0x01 -#define VCLK31_5 0x02 -#define VCLK36 0x03 -#define VCLK43_163 0x05 -#define VCLK44_9 0x06 -#define VCLK49_5 0x07 -#define VCLK50 0x08 -#define VCLK52_406 0x09 -#define VCLK56_25 0x0A -#define VCLK68_179 0x0D -#define VCLK72_852 0x0E -#define VCLK75 0x0F -#define VCLK78_75 0x11 -#define VCLK79_411 0x12 -#define VCLK83_95 0x13 -#define VCLK86_6 0x15 -#define VCLK94_5 0x16 -#define VCLK113_309 0x1B -#define VCLK116_406 0x1C -#define VCLK135_5 0x1E -#define VCLK139_054 0x1F -#define VCLK157_5 0x20 -#define VCLK162 0x21 -#define VCLK175 0x22 -#define VCLK189 0x23 -#define VCLK202_5 0x25 -#define VCLK229_5 0x26 -#define VCLK234 0x27 -#define VCLK254_817 0x29 -#define VCLK266_952 0x2B -#define VCLK269_655 0x2C -#define VCLK277_015 0x2E -#define VCLK291_132 0x30 -#define VCLK291_766 0x31 -#define VCLK315_195 0x33 -#define VCLK323_586 0x34 -#define VCLK330_615 0x35 -#define VCLK340_477 0x37 -#define VCLK375_847 0x38 -#define VCLK388_631 0x39 -#define VCLK125_999 0x51 -#define VCLK148_5 0x52 -#define VCLK217_325 0x55 -#define XGI_YPbPr750pVCLK 0x57 - -#define VCLK39_77 0x40 -#define YPbPr525pVCLK 0x3A -#define NTSC1024VCLK 0x41 -#define VCLK35_2 0x49 /* ; 800x480 */ -#define VCLK122_61 0x4A -#define VCLK80_350 0x4B -#define VCLK107_385 0x4C - -#define RES320x200 0x00 -#define RES320x240 0x01 -#define RES400x300 0x02 -#define RES512x384 0x03 -#define RES640x400 0x04 -#define RES640x480x60 0x05 -#define RES640x480x72 0x06 -#define RES640x480x75 0x07 -#define RES640x480x85 0x08 -#define RES640x480x100 0x09 -#define RES640x480x120 0x0A -#define RES640x480x160 0x0B -#define RES640x480x200 0x0C -#define RES800x600x56 0x0D -#define RES800x600x60 0x0E -#define RES800x600x72 0x0F -#define RES800x600x75 0x10 -#define RES800x600x85 0x11 -#define RES800x600x100 0x12 -#define RES800x600x120 0x13 -#define RES800x600x160 0x14 -#define RES1024x768x43 0x15 -#define RES1024x768x60 0x16 -#define RES1024x768x70 0x17 -#define RES1024x768x75 0x18 -#define RES1024x768x85 0x19 -#define RES1024x768x100 0x1A -#define RES1024x768x120 0x1B -#define RES1280x1024x43 0x1C -#define RES1280x1024x60 0x1D -#define RES1280x1024x75 0x1E -#define RES1280x1024x85 0x1F -#define RES1600x1200x60 0x20 -#define RES1600x1200x65 0x21 -#define RES1600x1200x70 0x22 -#define RES1600x1200x75 0x23 -#define RES1600x1200x85 0x24 -#define RES1600x1200x100 0x25 -#define RES1600x1200x120 0x26 -#define RES1920x1440x60 0x27 -#define RES1920x1440x65 0x28 -#define RES1920x1440x70 0x29 -#define RES1920x1440x75 0x2A -#define RES1920x1440x85 0x2B -#define RES1920x1440x100 0x2C -#define RES2048x1536x60 0x2D -#define RES2048x1536x65 0x2E -#define RES2048x1536x70 0x2F -#define RES2048x1536x75 0x30 -#define RES2048x1536x85 0x31 -#define RES800x480x60 0x32 -#define RES800x480x75 0x33 -#define RES800x480x85 0x34 -#define RES1024x576x60 0x35 -#define RES1024x576x75 0x36 -#define RES1024x576x85 0x37 -#define RES1280x720x60 0x38 -#define RES1280x720x75 0x39 -#define RES1280x720x85 0x3A -#define RES1280x960x60 0x3B -#define RES720x480x60 0x3C -#define RES720x576x56 0x3D -#define RES856x480x79I 0x3E -#define RES856x480x60 0x3F -#define RES1280x768x60 0x40 -#define RES1400x1050x60 0x41 -#define RES1152x864x60 0x42 -#define RES1152x864x75 0x43 -#define RES1024x768x160 0x44 -#define RES1280x960x75 0x45 -#define RES1280x960x85 0x46 -#define RES1280x960x120 0x47 - -#define XG27_CR8F 0x0C -#define XG27_SR36 0x30 -#define XG27_SR40 0x04 -#define XG27_SR41 0x00 -#define XG40_CRCF 0x13 -#define XGI330_CRT2Data_1_2 0 -#define XGI330_CRT2Data_4_D 0 -#define XGI330_CRT2Data_4_E 0 -#define XGI330_CRT2Data_4_10 0x80 -#define XGI330_SR07 0x18 -#define XGI330_SR1F 0 -#define XGI330_SR23 0xf6 -#define XGI330_SR24 0x0d -#define XGI330_SR31 0xc0 -#define XGI330_SR32 0x11 -#define XGI330_SR33 0 - -extern const struct XGI_ExtStruct XGI330_EModeIDTable[]; -extern const struct XGI_Ext2Struct XGI330_RefIndex[]; -extern const struct XGI_CRT1TableStruct XGI_CRT1Table[]; -extern const struct XGI_ECLKDataStruct XGI340_ECLKData[]; -extern const struct SiS_VCLKData XGI_VCLKData[]; -extern const unsigned char XGI340_CR6B[][4]; -extern const unsigned char XGI340_AGPReg[]; - -#endif diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c deleted file mode 100644 index ac1c815a3c5e..000000000000 --- a/drivers/staging/xgifb/vb_init.c +++ /dev/null @@ -1,1367 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include <linux/delay.h> -#include <linux/vmalloc.h> - -#include "XGIfb.h" -#include "vb_def.h" -#include "vb_util.h" -#include "vb_setmode.h" -#include "vb_init.h" -static const unsigned short XGINew_DDRDRAM_TYPE340[4][2] = { - { 16, 0x45}, - { 8, 0x35}, - { 4, 0x31}, - { 2, 0x21} }; - -static const unsigned short XGINew_DDRDRAM_TYPE20[12][2] = { - { 128, 0x5D}, - { 64, 0x59}, - { 64, 0x4D}, - { 32, 0x55}, - { 32, 0x49}, - { 32, 0x3D}, - { 16, 0x51}, - { 16, 0x45}, - { 16, 0x39}, - { 8, 0x41}, - { 8, 0x35}, - { 4, 0x31} }; - -#define XGIFB_ROM_SIZE 65536 - -static unsigned char -XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned char data, temp; - - if (HwDeviceExtension->jChipType < XG20) { - data = xgifb_reg_get(pVBInfo->P3c4, 0x39) & 0x02; - if (data == 0) - data = (xgifb_reg_get(pVBInfo->P3c4, 0x3A) & - 0x02) >> 1; - return data; - } else if (HwDeviceExtension->jChipType == XG27) { - temp = xgifb_reg_get(pVBInfo->P3c4, 0x3B); - /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */ - if (((temp & 0x88) == 0x80) || ((temp & 0x88) == 0x08)) - data = 0; /* DDR */ - else - data = 1; /* DDRII */ - return data; - } else if (HwDeviceExtension->jChipType == XG21) { - /* Independent GPIO control */ - xgifb_reg_and(pVBInfo->P3d4, 0xB4, ~0x02); - usleep_range(800, 1800); - xgifb_reg_or(pVBInfo->P3d4, 0x4A, 0x80); /* Enable GPIOH read */ - /* GPIOF 0:DVI 1:DVO */ - data = xgifb_reg_get(pVBInfo->P3d4, 0x48); - /* - * HOTPLUG_SUPPORT - * for current XG20 & XG21, GPIOH is floating, driver will - * fix DDR temporarily - */ - /* DVI read GPIOH */ - data &= 0x01; /* 1=DDRII, 0=DDR */ - /* ~HOTPLUG_SUPPORT */ - xgifb_reg_or(pVBInfo->P3d4, 0xB4, 0x02); - return data; - } - data = xgifb_reg_get(pVBInfo->P3d4, 0x97) & 0x01; - - if (data == 1) - data++; - - return data; -} - -static void XGINew_DDR1x_MRS_340(unsigned long P3c4, - struct vb_device_info *pVBInfo) -{ - xgifb_reg_set(P3c4, 0x18, 0x01); - xgifb_reg_set(P3c4, 0x19, 0x20); - xgifb_reg_set(P3c4, 0x16, 0x00); - xgifb_reg_set(P3c4, 0x16, 0x80); - - usleep_range(3, 1003); - xgifb_reg_set(P3c4, 0x18, 0x00); - xgifb_reg_set(P3c4, 0x19, 0x20); - xgifb_reg_set(P3c4, 0x16, 0x00); - xgifb_reg_set(P3c4, 0x16, 0x80); - - usleep_range(60, 1060); - xgifb_reg_set(P3c4, 0x18, pVBInfo->SR18[pVBInfo->ram_type]); /* SR18 */ - xgifb_reg_set(P3c4, 0x19, 0x01); - xgifb_reg_set(P3c4, 0x16, 0x03); - xgifb_reg_set(P3c4, 0x16, 0x83); - usleep_range(1, 1001); - xgifb_reg_set(P3c4, 0x1B, 0x03); - usleep_range(500, 1500); - xgifb_reg_set(P3c4, 0x18, pVBInfo->SR18[pVBInfo->ram_type]); /* SR18 */ - xgifb_reg_set(P3c4, 0x19, 0x00); - xgifb_reg_set(P3c4, 0x16, 0x03); - xgifb_reg_set(P3c4, 0x16, 0x83); - xgifb_reg_set(P3c4, 0x1B, 0x00); -} - -static void XGINew_SetMemoryClock(struct vb_device_info *pVBInfo) -{ - xgifb_reg_set(pVBInfo->P3c4, - 0x28, - pVBInfo->MCLKData[pVBInfo->ram_type].SR28); - xgifb_reg_set(pVBInfo->P3c4, - 0x29, - pVBInfo->MCLKData[pVBInfo->ram_type].SR29); - xgifb_reg_set(pVBInfo->P3c4, - 0x2A, - pVBInfo->MCLKData[pVBInfo->ram_type].SR2A); - - xgifb_reg_set(pVBInfo->P3c4, - 0x2E, - XGI340_ECLKData[pVBInfo->ram_type].SR2E); - xgifb_reg_set(pVBInfo->P3c4, - 0x2F, - XGI340_ECLKData[pVBInfo->ram_type].SR2F); - xgifb_reg_set(pVBInfo->P3c4, - 0x30, - XGI340_ECLKData[pVBInfo->ram_type].SR30); -} - -static void XGINew_DDRII_Bootup_XG27( - struct xgi_hw_device_info *HwDeviceExtension, - unsigned long P3c4, struct vb_device_info *pVBInfo) -{ - unsigned long P3d4 = P3c4 + 0x10; - - pVBInfo->ram_type = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo); - XGINew_SetMemoryClock(pVBInfo); - - /* Set Double Frequency */ - xgifb_reg_set(P3d4, 0x97, pVBInfo->XGINew_CR97); /* CR97 */ - - usleep_range(200, 1200); - - xgifb_reg_set(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS2 */ - xgifb_reg_set(P3c4, 0x19, 0x80); /* Set SR19 */ - xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */ - usleep_range(15, 1015); - xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */ - usleep_range(15, 1015); - - xgifb_reg_set(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS3 */ - xgifb_reg_set(P3c4, 0x19, 0xC0); /* Set SR19 */ - xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */ - usleep_range(15, 1015); - xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */ - usleep_range(15, 1015); - - xgifb_reg_set(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS1 */ - xgifb_reg_set(P3c4, 0x19, 0x40); /* Set SR19 */ - xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */ - usleep_range(30, 1030); - xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */ - usleep_range(15, 1015); - - xgifb_reg_set(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Enable */ - xgifb_reg_set(P3c4, 0x19, 0x0A); /* Set SR19 */ - xgifb_reg_set(P3c4, 0x16, 0x00); /* Set SR16 */ - usleep_range(30, 1030); - xgifb_reg_set(P3c4, 0x16, 0x00); /* Set SR16 */ - xgifb_reg_set(P3c4, 0x16, 0x80); /* Set SR16 */ - - xgifb_reg_set(P3c4, 0x1B, 0x04); /* Set SR1B */ - usleep_range(60, 1060); - xgifb_reg_set(P3c4, 0x1B, 0x00); /* Set SR1B */ - - xgifb_reg_set(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Reset */ - xgifb_reg_set(P3c4, 0x19, 0x08); /* Set SR19 */ - xgifb_reg_set(P3c4, 0x16, 0x00); /* Set SR16 */ - - usleep_range(30, 1030); - xgifb_reg_set(P3c4, 0x16, 0x83); /* Set SR16 */ - usleep_range(15, 1015); - - xgifb_reg_set(P3c4, 0x18, 0x80); /* Set SR18 */ /* MRS, ODT */ - xgifb_reg_set(P3c4, 0x19, 0x46); /* Set SR19 */ - xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */ - usleep_range(30, 1030); - xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */ - usleep_range(15, 1015); - - xgifb_reg_set(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS */ - xgifb_reg_set(P3c4, 0x19, 0x40); /* Set SR19 */ - xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */ - usleep_range(30, 1030); - xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */ - usleep_range(15, 1015); - - /* Set SR1B refresh control 000:close; 010:open */ - xgifb_reg_set(P3c4, 0x1B, 0x04); - usleep_range(200, 1200); -} - -static void XGINew_DDR2_MRS_XG20(struct xgi_hw_device_info *HwDeviceExtension, - unsigned long P3c4, - struct vb_device_info *pVBInfo) -{ - unsigned long P3d4 = P3c4 + 0x10; - - pVBInfo->ram_type = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo); - XGINew_SetMemoryClock(pVBInfo); - - xgifb_reg_set(P3d4, 0x97, 0x11); /* CR97 */ - - usleep_range(200, 1200); - xgifb_reg_set(P3c4, 0x18, 0x00); /* EMRS2 */ - xgifb_reg_set(P3c4, 0x19, 0x80); - xgifb_reg_set(P3c4, 0x16, 0x05); - xgifb_reg_set(P3c4, 0x16, 0x85); - - xgifb_reg_set(P3c4, 0x18, 0x00); /* EMRS3 */ - xgifb_reg_set(P3c4, 0x19, 0xC0); - xgifb_reg_set(P3c4, 0x16, 0x05); - xgifb_reg_set(P3c4, 0x16, 0x85); - - xgifb_reg_set(P3c4, 0x18, 0x00); /* EMRS1 */ - xgifb_reg_set(P3c4, 0x19, 0x40); - xgifb_reg_set(P3c4, 0x16, 0x05); - xgifb_reg_set(P3c4, 0x16, 0x85); - - xgifb_reg_set(P3c4, 0x18, 0x42); /* MRS1 */ - xgifb_reg_set(P3c4, 0x19, 0x02); - xgifb_reg_set(P3c4, 0x16, 0x05); - xgifb_reg_set(P3c4, 0x16, 0x85); - - usleep_range(15, 1015); - xgifb_reg_set(P3c4, 0x1B, 0x04); /* SR1B */ - usleep_range(30, 1030); - xgifb_reg_set(P3c4, 0x1B, 0x00); /* SR1B */ - usleep_range(100, 1100); - - xgifb_reg_set(P3c4, 0x18, 0x42); /* MRS1 */ - xgifb_reg_set(P3c4, 0x19, 0x00); - xgifb_reg_set(P3c4, 0x16, 0x05); - xgifb_reg_set(P3c4, 0x16, 0x85); - - usleep_range(200, 1200); -} - -static void XGINew_DDR1x_MRS_XG20(unsigned long P3c4, - struct vb_device_info *pVBInfo) -{ - xgifb_reg_set(P3c4, 0x18, 0x01); - xgifb_reg_set(P3c4, 0x19, 0x40); - xgifb_reg_set(P3c4, 0x16, 0x00); - xgifb_reg_set(P3c4, 0x16, 0x80); - usleep_range(60, 1060); - - xgifb_reg_set(P3c4, 0x18, 0x00); - xgifb_reg_set(P3c4, 0x19, 0x40); - xgifb_reg_set(P3c4, 0x16, 0x00); - xgifb_reg_set(P3c4, 0x16, 0x80); - usleep_range(60, 1060); - xgifb_reg_set(P3c4, 0x18, pVBInfo->SR18[pVBInfo->ram_type]); /* SR18 */ - xgifb_reg_set(P3c4, 0x19, 0x01); - xgifb_reg_set(P3c4, 0x16, 0x03); - xgifb_reg_set(P3c4, 0x16, 0x83); - usleep_range(1, 1001); - xgifb_reg_set(P3c4, 0x1B, 0x03); - usleep_range(500, 1500); - xgifb_reg_set(P3c4, 0x18, pVBInfo->SR18[pVBInfo->ram_type]); /* SR18 */ - xgifb_reg_set(P3c4, 0x19, 0x00); - xgifb_reg_set(P3c4, 0x16, 0x03); - xgifb_reg_set(P3c4, 0x16, 0x83); - xgifb_reg_set(P3c4, 0x1B, 0x00); -} - -static void XGINew_DDR1x_DefaultRegister( - struct xgi_hw_device_info *HwDeviceExtension, - unsigned long Port, struct vb_device_info *pVBInfo) -{ - unsigned long P3d4 = Port, P3c4 = Port - 0x10; - - if (HwDeviceExtension->jChipType >= XG20) { - XGINew_SetMemoryClock(pVBInfo); - xgifb_reg_set(P3d4, - 0x82, - pVBInfo->CR40[11][pVBInfo->ram_type]); /* CR82 */ - xgifb_reg_set(P3d4, - 0x85, - pVBInfo->CR40[12][pVBInfo->ram_type]); /* CR85 */ - xgifb_reg_set(P3d4, - 0x86, - pVBInfo->CR40[13][pVBInfo->ram_type]); /* CR86 */ - - xgifb_reg_set(P3d4, 0x98, 0x01); - xgifb_reg_set(P3d4, 0x9A, 0x02); - - XGINew_DDR1x_MRS_XG20(P3c4, pVBInfo); - } else { - XGINew_SetMemoryClock(pVBInfo); - - switch (HwDeviceExtension->jChipType) { - case XG42: - /* CR82 */ - xgifb_reg_set(P3d4, - 0x82, - pVBInfo->CR40[11][pVBInfo->ram_type]); - /* CR85 */ - xgifb_reg_set(P3d4, - 0x85, - pVBInfo->CR40[12][pVBInfo->ram_type]); - /* CR86 */ - xgifb_reg_set(P3d4, - 0x86, - pVBInfo->CR40[13][pVBInfo->ram_type]); - break; - default: - xgifb_reg_set(P3d4, 0x82, 0x88); - xgifb_reg_set(P3d4, 0x86, 0x00); - /* Insert read command for delay */ - xgifb_reg_get(P3d4, 0x86); - xgifb_reg_set(P3d4, 0x86, 0x88); - xgifb_reg_get(P3d4, 0x86); - xgifb_reg_set(P3d4, - 0x86, - pVBInfo->CR40[13][pVBInfo->ram_type]); - xgifb_reg_set(P3d4, 0x82, 0x77); - xgifb_reg_set(P3d4, 0x85, 0x00); - - /* Insert read command for delay */ - xgifb_reg_get(P3d4, 0x85); - xgifb_reg_set(P3d4, 0x85, 0x88); - - /* Insert read command for delay */ - xgifb_reg_get(P3d4, 0x85); - /* CR85 */ - xgifb_reg_set(P3d4, - 0x85, - pVBInfo->CR40[12][pVBInfo->ram_type]); - /* CR82 */ - xgifb_reg_set(P3d4, - 0x82, - pVBInfo->CR40[11][pVBInfo->ram_type]); - break; - } - - xgifb_reg_set(P3d4, 0x97, 0x00); - xgifb_reg_set(P3d4, 0x98, 0x01); - xgifb_reg_set(P3d4, 0x9A, 0x02); - XGINew_DDR1x_MRS_340(P3c4, pVBInfo); - } -} - -static void XGINew_DDR2_DefaultRegister( - struct xgi_hw_device_info *HwDeviceExtension, - unsigned long Port, struct vb_device_info *pVBInfo) -{ - unsigned long P3d4 = Port, P3c4 = Port - 0x10; - /* - * keep following setting sequence, each setting in - * the same reg insert idle - */ - xgifb_reg_set(P3d4, 0x82, 0x77); - xgifb_reg_set(P3d4, 0x86, 0x00); - xgifb_reg_get(P3d4, 0x86); /* Insert read command for delay */ - xgifb_reg_set(P3d4, 0x86, 0x88); - xgifb_reg_get(P3d4, 0x86); /* Insert read command for delay */ - /* CR86 */ - xgifb_reg_set(P3d4, 0x86, pVBInfo->CR40[13][pVBInfo->ram_type]); - xgifb_reg_set(P3d4, 0x82, 0x77); - xgifb_reg_set(P3d4, 0x85, 0x00); - xgifb_reg_get(P3d4, 0x85); /* Insert read command for delay */ - xgifb_reg_set(P3d4, 0x85, 0x88); - xgifb_reg_get(P3d4, 0x85); /* Insert read command for delay */ - xgifb_reg_set(P3d4, - 0x85, - pVBInfo->CR40[12][pVBInfo->ram_type]); /* CR85 */ - if (HwDeviceExtension->jChipType == XG27) - /* CR82 */ - xgifb_reg_set(P3d4, 0x82, pVBInfo->CR40[11][pVBInfo->ram_type]); - else - xgifb_reg_set(P3d4, 0x82, 0xA8); /* CR82 */ - - xgifb_reg_set(P3d4, 0x98, 0x01); - xgifb_reg_set(P3d4, 0x9A, 0x02); - if (HwDeviceExtension->jChipType == XG27) - XGINew_DDRII_Bootup_XG27(HwDeviceExtension, P3c4, pVBInfo); - else - XGINew_DDR2_MRS_XG20(HwDeviceExtension, P3c4, pVBInfo); -} - -static void XGI_SetDRAM_Helper(unsigned long P3d4, u8 seed, u8 temp2, u8 reg, - u8 shift_factor, u8 mask1, u8 mask2) -{ - u8 j; - - for (j = 0; j < 4; j++) { - temp2 |= (((seed >> (2 * j)) & 0x03) << shift_factor); - xgifb_reg_set(P3d4, reg, temp2); - xgifb_reg_get(P3d4, reg); - temp2 &= mask1; - temp2 += mask2; - } -} - -static void XGINew_SetDRAMDefaultRegister340( - struct xgi_hw_device_info *HwDeviceExtension, - unsigned long Port, struct vb_device_info *pVBInfo) -{ - unsigned char temp, temp1, temp2, temp3, j, k; - - unsigned long P3d4 = Port, P3c4 = Port - 0x10; - - xgifb_reg_set(P3d4, 0x6D, pVBInfo->CR40[8][pVBInfo->ram_type]); - xgifb_reg_set(P3d4, 0x68, pVBInfo->CR40[5][pVBInfo->ram_type]); - xgifb_reg_set(P3d4, 0x69, pVBInfo->CR40[6][pVBInfo->ram_type]); - xgifb_reg_set(P3d4, 0x6A, pVBInfo->CR40[7][pVBInfo->ram_type]); - - /* CR6B DQS fine tune delay */ - temp = 0xaa; - XGI_SetDRAM_Helper(P3d4, temp, 0, 0x6B, 2, 0xF0, 0x10); - - /* CR6E DQM fine tune delay */ - XGI_SetDRAM_Helper(P3d4, 0, 0, 0x6E, 2, 0xF0, 0x10); - - temp3 = 0; - for (k = 0; k < 4; k++) { - /* CR6E_D[1:0] select channel */ - xgifb_reg_and_or(P3d4, 0x6E, 0xFC, temp3); - XGI_SetDRAM_Helper(P3d4, 0, 0, 0x6F, 0, 0xF8, 0x08); - temp3 += 0x01; - } - - xgifb_reg_set(P3d4, - 0x80, - pVBInfo->CR40[9][pVBInfo->ram_type]); /* CR80 */ - xgifb_reg_set(P3d4, - 0x81, - pVBInfo->CR40[10][pVBInfo->ram_type]); /* CR81 */ - - temp2 = 0x80; - /* CR89 terminator type select */ - XGI_SetDRAM_Helper(P3d4, 0, temp2, 0x89, 0, 0xF0, 0x10); - - temp = 0; - temp1 = temp & 0x03; - temp2 |= temp1; - xgifb_reg_set(P3d4, 0x89, temp2); - - temp = pVBInfo->CR40[3][pVBInfo->ram_type]; - temp1 = temp & 0x0F; - temp2 = (temp >> 4) & 0x07; - temp3 = temp & 0x80; - xgifb_reg_set(P3d4, 0x45, temp1); /* CR45 */ - xgifb_reg_set(P3d4, 0x99, temp2); /* CR99 */ - xgifb_reg_or(P3d4, 0x40, temp3); /* CR40_D[7] */ - xgifb_reg_set(P3d4, - 0x41, - pVBInfo->CR40[0][pVBInfo->ram_type]); /* CR41 */ - - if (HwDeviceExtension->jChipType == XG27) - xgifb_reg_set(P3d4, 0x8F, XG27_CR8F); /* CR8F */ - - for (j = 0; j <= 6; j++) /* CR90 - CR96 */ - xgifb_reg_set(P3d4, (0x90 + j), - pVBInfo->CR40[14 + j][pVBInfo->ram_type]); - - for (j = 0; j <= 2; j++) /* CRC3 - CRC5 */ - xgifb_reg_set(P3d4, (0xC3 + j), - pVBInfo->CR40[21 + j][pVBInfo->ram_type]); - - for (j = 0; j < 2; j++) /* CR8A - CR8B */ - xgifb_reg_set(P3d4, (0x8A + j), - pVBInfo->CR40[1 + j][pVBInfo->ram_type]); - - if (HwDeviceExtension->jChipType == XG42) - xgifb_reg_set(P3d4, 0x8C, 0x87); - - xgifb_reg_set(P3d4, - 0x59, - pVBInfo->CR40[4][pVBInfo->ram_type]); /* CR59 */ - - xgifb_reg_set(P3d4, 0x83, 0x09); /* CR83 */ - xgifb_reg_set(P3d4, 0x87, 0x00); /* CR87 */ - xgifb_reg_set(P3d4, 0xCF, XG40_CRCF); /* CRCF */ - if (pVBInfo->ram_type) { - xgifb_reg_set(P3c4, 0x17, 0x80); /* SR17 DDRII */ - if (HwDeviceExtension->jChipType == XG27) - xgifb_reg_set(P3c4, 0x17, 0x02); /* SR17 DDRII */ - - } else { - xgifb_reg_set(P3c4, 0x17, 0x00); /* SR17 DDR */ - } - xgifb_reg_set(P3c4, 0x1A, 0x87); /* SR1A */ - - temp = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo); - if (temp == 0) { - XGINew_DDR1x_DefaultRegister(HwDeviceExtension, P3d4, pVBInfo); - } else { - xgifb_reg_set(P3d4, 0xB0, 0x80); /* DDRII Dual frequency mode */ - XGINew_DDR2_DefaultRegister(HwDeviceExtension, P3d4, pVBInfo); - } - xgifb_reg_set(P3c4, 0x1B, 0x03); /* SR1B */ -} - -static unsigned short XGINew_SetDRAMSize20Reg( - unsigned short dram_size, - struct vb_device_info *pVBInfo) -{ - unsigned short data = 0, memsize = 0; - int RankSize; - unsigned char ChannelNo; - - RankSize = dram_size * pVBInfo->ram_bus / 8; - data = xgifb_reg_get(pVBInfo->P3c4, 0x13); - data &= 0x80; - - if (data == 0x80) - RankSize *= 2; - - data = 0; - - if (pVBInfo->ram_channel == 3) - ChannelNo = 4; - else - ChannelNo = pVBInfo->ram_channel; - - if (ChannelNo * RankSize <= 256) { - while ((RankSize >>= 1) > 0) - data += 0x10; - - memsize = data >> 4; - - /* Fix DRAM Sizing Error */ - xgifb_reg_set(pVBInfo->P3c4, - 0x14, - (xgifb_reg_get(pVBInfo->P3c4, 0x14) & 0x0F) | - (data & 0xF0)); - usleep_range(15, 1015); - } - return memsize; -} - -static int XGINew_ReadWriteRest(unsigned short StopAddr, - unsigned short StartAddr, - struct vb_device_info *pVBInfo) -{ - int i; - unsigned long Position = 0; - void __iomem *fbaddr = pVBInfo->FBAddr; - - writel(Position, fbaddr + Position); - - for (i = StartAddr; i <= StopAddr; i++) { - Position = 1 << i; - writel(Position, fbaddr + Position); - } - - /* Fix #1759 Memory Size error in Multi-Adapter. */ - usleep_range(500, 1500); - - Position = 0; - - if (readl(fbaddr + Position) != Position) - return 0; - - for (i = StartAddr; i <= StopAddr; i++) { - Position = 1 << i; - if (readl(fbaddr + Position) != Position) - return 0; - } - return 1; -} - -static unsigned char XGINew_CheckFrequence(struct vb_device_info *pVBInfo) -{ - unsigned char data; - - data = xgifb_reg_get(pVBInfo->P3d4, 0x97); - - if ((data & 0x10) == 0) { - data = xgifb_reg_get(pVBInfo->P3c4, 0x39); - return (data & 0x02) >> 1; - } - return data & 0x01; -} - -static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned char data; - - switch (HwDeviceExtension->jChipType) { - case XG20: - case XG21: - data = xgifb_reg_get(pVBInfo->P3d4, 0x97); - data = data & 0x01; - pVBInfo->ram_channel = 1; /* XG20 "JUST" one channel */ - - if (data == 0) { /* Single_32_16 */ - - if ((HwDeviceExtension->ulVideoMemorySize - 1) - > 0x1000000) { - pVBInfo->ram_bus = 32; /* 32 bits */ - /* 22bit + 2 rank + 32bit */ - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x52); - usleep_range(15, 1015); - - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; - - if ((HwDeviceExtension->ulVideoMemorySize - 1) > - 0x800000) { - /* 22bit + 1 rank + 32bit */ - xgifb_reg_set(pVBInfo->P3c4, - 0x13, - 0x31); - xgifb_reg_set(pVBInfo->P3c4, - 0x14, - 0x42); - usleep_range(15, 1015); - - if (XGINew_ReadWriteRest(23, - 23, - pVBInfo) == 1) - return; - } - } - - if ((HwDeviceExtension->ulVideoMemorySize - 1) > - 0x800000) { - pVBInfo->ram_bus = 16; /* 16 bits */ - /* 22bit + 2 rank + 16bit */ - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x41); - usleep_range(15, 1015); - - if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1) - return; - xgifb_reg_set(pVBInfo->P3c4, - 0x13, - 0x31); - usleep_range(15, 1015); - } - - } else { /* Dual_16_8 */ - if ((HwDeviceExtension->ulVideoMemorySize - 1) > - 0x800000) { - pVBInfo->ram_bus = 16; /* 16 bits */ - /* (0x31:12x8x2) 22bit + 2 rank */ - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1); - /* 0x41:16Mx16 bit */ - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x41); - usleep_range(15, 1015); - - if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1) - return; - - if ((HwDeviceExtension->ulVideoMemorySize - 1) > - 0x400000) { - /* (0x31:12x8x2) 22bit + 1 rank */ - xgifb_reg_set(pVBInfo->P3c4, - 0x13, - 0x31); - /* 0x31:8Mx16 bit */ - xgifb_reg_set(pVBInfo->P3c4, - 0x14, - 0x31); - usleep_range(15, 1015); - - if (XGINew_ReadWriteRest(22, - 22, - pVBInfo) == 1) - return; - } - } - - if ((HwDeviceExtension->ulVideoMemorySize - 1) > - 0x400000) { - pVBInfo->ram_bus = 8; /* 8 bits */ - /* (0x31:12x8x2) 22bit + 2 rank */ - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1); - /* 0x30:8Mx8 bit */ - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x30); - usleep_range(15, 1015); - - if (XGINew_ReadWriteRest(22, 21, pVBInfo) == 1) - return; - - /* (0x31:12x8x2) 22bit + 1 rank */ - xgifb_reg_set(pVBInfo->P3c4, - 0x13, - 0x31); - usleep_range(15, 1015); - } - } - break; - - case XG27: - pVBInfo->ram_bus = 16; /* 16 bits */ - pVBInfo->ram_channel = 1; /* Single channel */ - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x51); /* 32Mx16 bit */ - break; - case XG42: - /* - * XG42 SR14 D[3] Reserve - * D[2] = 1, Dual Channel - * = 0, Single Channel - * - * It's Different from Other XG40 Series. - */ - if (XGINew_CheckFrequence(pVBInfo) == 1) { /* DDRII, DDR2x */ - pVBInfo->ram_bus = 32; /* 32 bits */ - pVBInfo->ram_channel = 2; /* 2 Channel */ - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x44); - - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; - - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x34); - if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1) - return; - - pVBInfo->ram_channel = 1; /* Single Channel */ - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x40); - - if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1) - return; - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x30); - } else { /* DDR */ - pVBInfo->ram_bus = 64; /* 64 bits */ - pVBInfo->ram_channel = 1; /* 1 channels */ - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x52); - - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x42); - } - - break; - - default: /* XG40 */ - - if (XGINew_CheckFrequence(pVBInfo) == 1) { /* DDRII */ - pVBInfo->ram_bus = 32; /* 32 bits */ - pVBInfo->ram_channel = 3; - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x4C); - - if (XGINew_ReadWriteRest(25, 23, pVBInfo) == 1) - return; - - pVBInfo->ram_channel = 2; /* 2 channels */ - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x48); - - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; - - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x3C); - - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) { - pVBInfo->ram_channel = 3; /* 4 channels */ - } else { - pVBInfo->ram_channel = 2; /* 2 channels */ - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x38); - } - } else { /* DDR */ - pVBInfo->ram_bus = 64; /* 64 bits */ - pVBInfo->ram_channel = 2; /* 2 channels */ - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x5A); - - if (XGINew_ReadWriteRest(25, 24, pVBInfo) == 1) - return; - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x4A); - } - break; - } -} - -static int XGINew_DDRSizing340(struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - u8 i, size; - unsigned short memsize, start_addr; - const unsigned short (*dram_table)[2]; - - xgifb_reg_set(pVBInfo->P3c4, 0x15, 0x00); /* noninterleaving */ - xgifb_reg_set(pVBInfo->P3c4, 0x1C, 0x00); /* nontiling */ - XGINew_CheckChannel(HwDeviceExtension, pVBInfo); - - if (HwDeviceExtension->jChipType >= XG20) { - dram_table = XGINew_DDRDRAM_TYPE20; - size = ARRAY_SIZE(XGINew_DDRDRAM_TYPE20); - start_addr = 5; - } else { - dram_table = XGINew_DDRDRAM_TYPE340; - size = ARRAY_SIZE(XGINew_DDRDRAM_TYPE340); - start_addr = 9; - } - - for (i = 0; i < size; i++) { - /* SetDRAMSizingType */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x13, 0x80, dram_table[i][1]); - usleep_range(50, 1050); /* should delay 50 ns */ - - memsize = XGINew_SetDRAMSize20Reg(dram_table[i][0], pVBInfo); - - if (memsize == 0) - continue; - - memsize += (pVBInfo->ram_channel - 2) + 20; - if ((HwDeviceExtension->ulVideoMemorySize - 1) < - (unsigned long)(1 << memsize)) - continue; - - if (XGINew_ReadWriteRest(memsize, start_addr, pVBInfo) == 1) - return 1; - } - return 0; -} - -static void XGINew_SetDRAMSize_340(struct xgifb_video_info *xgifb_info, - struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short data; - - pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress; - - XGISetModeNew(xgifb_info, HwDeviceExtension, 0x2e); - - data = xgifb_reg_get(pVBInfo->P3c4, 0x21); - /* disable read cache */ - xgifb_reg_set(pVBInfo->P3c4, 0x21, (unsigned short)(data & 0xDF)); - XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo); - - XGINew_DDRSizing340(HwDeviceExtension, pVBInfo); - data = xgifb_reg_get(pVBInfo->P3c4, 0x21); - /* enable read cache */ - xgifb_reg_set(pVBInfo->P3c4, 0x21, (unsigned short)(data | 0x20)); -} - -static u8 *xgifb_copy_rom(struct pci_dev *dev, size_t *rom_size) -{ - void __iomem *rom_address; - u8 *rom_copy; - - rom_address = pci_map_rom(dev, rom_size); - if (!rom_address) - return NULL; - - rom_copy = vzalloc(XGIFB_ROM_SIZE); - if (!rom_copy) - goto done; - - *rom_size = min_t(size_t, *rom_size, XGIFB_ROM_SIZE); - memcpy_fromio(rom_copy, rom_address, *rom_size); - -done: - pci_unmap_rom(dev, rom_address); - return rom_copy; -} - -static bool xgifb_read_vbios(struct pci_dev *pdev) -{ - struct xgifb_video_info *xgifb_info = pci_get_drvdata(pdev); - u8 *vbios; - unsigned long i; - unsigned char j; - struct XGI21_LVDSCapStruct *lvds; - size_t vbios_size; - int entry; - - vbios = xgifb_copy_rom(pdev, &vbios_size); - if (!vbios) { - dev_err(&pdev->dev, "Video BIOS not available\n"); - return false; - } - if (vbios_size <= 0x65) - goto error; - /* - * The user can ignore the LVDS bit in the BIOS and force the display - * type. - */ - if (!(vbios[0x65] & 0x1) && - (!xgifb_info->display2_force || - xgifb_info->display2 != XGIFB_DISP_LCD)) { - vfree(vbios); - return false; - } - if (vbios_size <= 0x317) - goto error; - i = vbios[0x316] | (vbios[0x317] << 8); - if (vbios_size <= i - 1) - goto error; - j = vbios[i - 1]; - if (j == 0) - goto error; - if (j == 0xff) - j = 1; - - /* Read the LVDS table index scratch register set by the BIOS. */ - - entry = xgifb_reg_get(xgifb_info->dev_info.P3d4, 0x36); - if (entry >= j) - entry = 0; - i += entry * 25; - lvds = &xgifb_info->lvds_data; - if (vbios_size <= i + 24) - goto error; - lvds->LVDS_Capability = vbios[i] | (vbios[i + 1] << 8); - lvds->LVDSHT = vbios[i + 2] | (vbios[i + 3] << 8); - lvds->LVDSVT = vbios[i + 4] | (vbios[i + 5] << 8); - lvds->LVDSHDE = vbios[i + 6] | (vbios[i + 7] << 8); - lvds->LVDSVDE = vbios[i + 8] | (vbios[i + 9] << 8); - lvds->LVDSHFP = vbios[i + 10] | (vbios[i + 11] << 8); - lvds->LVDSVFP = vbios[i + 12] | (vbios[i + 13] << 8); - lvds->LVDSHSYNC = vbios[i + 14] | (vbios[i + 15] << 8); - lvds->LVDSVSYNC = vbios[i + 16] | (vbios[i + 17] << 8); - lvds->VCLKData1 = vbios[i + 18]; - lvds->VCLKData2 = vbios[i + 19]; - lvds->PSC_S1 = vbios[i + 20]; - lvds->PSC_S2 = vbios[i + 21]; - lvds->PSC_S3 = vbios[i + 22]; - lvds->PSC_S4 = vbios[i + 23]; - lvds->PSC_S5 = vbios[i + 24]; - vfree(vbios); - return true; -error: - dev_err(&pdev->dev, "Video BIOS corrupted\n"); - vfree(vbios); - return false; -} - -static void XGINew_ChkSenseStatus(struct vb_device_info *pVBInfo) -{ - unsigned short tempbx = 0, temp, tempcx, CR3CData; - - temp = xgifb_reg_get(pVBInfo->P3d4, 0x32); - - if (temp & Monitor1Sense) - tempbx |= ActiveCRT1; - if (temp & LCDSense) - tempbx |= ActiveLCD; - if (temp & Monitor2Sense) - tempbx |= ActiveCRT2; - if (temp & TVSense) { - tempbx |= ActiveTV; - if (temp & AVIDEOSense) - tempbx |= (ActiveAVideo << 8); - if (temp & SVIDEOSense) - tempbx |= (ActiveSVideo << 8); - if (temp & SCARTSense) - tempbx |= (ActiveSCART << 8); - if (temp & HiTVSense) - tempbx |= (ActiveHiTV << 8); - if (temp & YPbPrSense) - tempbx |= (ActiveYPbPr << 8); - } - - tempcx = xgifb_reg_get(pVBInfo->P3d4, 0x3d); - tempcx |= (xgifb_reg_get(pVBInfo->P3d4, 0x3e) << 8); - - if (tempbx & tempcx) { - CR3CData = xgifb_reg_get(pVBInfo->P3d4, 0x3c); - if (!(CR3CData & DisplayDeviceFromCMOS)) - tempcx = 0x1FF0; - } else { - tempcx = 0x1FF0; - } - - tempbx &= tempcx; - xgifb_reg_set(pVBInfo->P3d4, 0x3d, (tempbx & 0x00FF)); - xgifb_reg_set(pVBInfo->P3d4, 0x3e, ((tempbx & 0xFF00) >> 8)); -} - -static void XGINew_SetModeScratch(struct vb_device_info *pVBInfo) -{ - unsigned short temp, tempcl = 0, tempch = 0, CR31Data, CR38Data; - - temp = xgifb_reg_get(pVBInfo->P3d4, 0x3d); - temp |= xgifb_reg_get(pVBInfo->P3d4, 0x3e) << 8; - temp |= (xgifb_reg_get(pVBInfo->P3d4, 0x31) & (DriverMode >> 8)) << 8; - - if (pVBInfo->IF_DEF_CRT2Monitor == 1) { - if (temp & ActiveCRT2) - tempcl = SetCRT2ToRAMDAC; - } - - if (temp & ActiveLCD) { - tempcl |= SetCRT2ToLCD; - if (temp & DriverMode) { - if (temp & ActiveTV) { - tempch = SetToLCDA | EnableDualEdge; - temp ^= SetCRT2ToLCD; - - if ((temp >> 8) & ActiveAVideo) - tempcl |= SetCRT2ToAVIDEO; - if ((temp >> 8) & ActiveSVideo) - tempcl |= SetCRT2ToSVIDEO; - if ((temp >> 8) & ActiveSCART) - tempcl |= SetCRT2ToSCART; - - if (pVBInfo->IF_DEF_HiVision == 1) { - if ((temp >> 8) & ActiveHiTV) - tempcl |= SetCRT2ToHiVision; - } - - if (pVBInfo->IF_DEF_YPbPr == 1) { - if ((temp >> 8) & ActiveYPbPr) - tempch |= SetYPbPr; - } - } - } - } else { - if ((temp >> 8) & ActiveAVideo) - tempcl |= SetCRT2ToAVIDEO; - if ((temp >> 8) & ActiveSVideo) - tempcl |= SetCRT2ToSVIDEO; - if ((temp >> 8) & ActiveSCART) - tempcl |= SetCRT2ToSCART; - - if (pVBInfo->IF_DEF_HiVision == 1) { - if ((temp >> 8) & ActiveHiTV) - tempcl |= SetCRT2ToHiVision; - } - - if (pVBInfo->IF_DEF_YPbPr == 1) { - if ((temp >> 8) & ActiveYPbPr) - tempch |= SetYPbPr; - } - } - - tempcl |= SetSimuScanMode; - if ((!(temp & ActiveCRT1)) && ((temp & ActiveLCD) || - (temp & ActiveTV) || - (temp & ActiveCRT2))) - tempcl ^= (SetSimuScanMode | SwitchCRT2); - if ((temp & ActiveLCD) && (temp & ActiveTV)) - tempcl ^= (SetSimuScanMode | SwitchCRT2); - xgifb_reg_set(pVBInfo->P3d4, 0x30, tempcl); - - CR31Data = xgifb_reg_get(pVBInfo->P3d4, 0x31); - CR31Data &= ~(SetNotSimuMode >> 8); - if (!(temp & ActiveCRT1)) - CR31Data |= (SetNotSimuMode >> 8); - CR31Data &= ~(DisableCRT2Display >> 8); - if (!((temp & ActiveLCD) || (temp & ActiveTV) || (temp & ActiveCRT2))) - CR31Data |= (DisableCRT2Display >> 8); - xgifb_reg_set(pVBInfo->P3d4, 0x31, CR31Data); - - CR38Data = xgifb_reg_get(pVBInfo->P3d4, 0x38); - CR38Data &= ~SetYPbPr; - CR38Data |= tempch; - xgifb_reg_set(pVBInfo->P3d4, 0x38, CR38Data); -} - -static unsigned short XGINew_SenseLCD(struct xgi_hw_device_info - *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short temp = HwDeviceExtension->ulCRT2LCDType; - - switch (HwDeviceExtension->ulCRT2LCDType) { - case LCD_640x480: - case LCD_1024x600: - case LCD_1152x864: - case LCD_1280x960: - case LCD_1152x768: - case LCD_1920x1440: - case LCD_2048x1536: - temp = 0; /* overwrite used ulCRT2LCDType */ - break; - case LCD_UNKNOWN: /* unknown lcd, do nothing */ - return 0; - } - xgifb_reg_and_or(pVBInfo->P3d4, 0x36, 0xF0, temp); - return 1; -} - -static void XGINew_GetXG21Sense(struct pci_dev *pdev, - struct vb_device_info *pVBInfo) -{ - struct xgifb_video_info *xgifb_info = pci_get_drvdata(pdev); - unsigned char Temp; - - if (xgifb_read_vbios(pdev)) { /* For XG21 LVDS */ - xgifb_reg_or(pVBInfo->P3d4, 0x32, LCDSense); - /* LVDS on chip */ - xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0); - } else { - /* Enable GPIOA/B read */ - xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x03, 0x03); - Temp = xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0xC0; - if (Temp == 0xC0) { /* DVI & DVO GPIOA/B pull high */ - XGINew_SenseLCD(&xgifb_info->hw_info, pVBInfo); - xgifb_reg_or(pVBInfo->P3d4, 0x32, LCDSense); - /* Enable read GPIOF */ - xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x20, 0x20); - if (xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0x04) - Temp = 0xA0; /* Only DVO on chip */ - else - Temp = 0x80; /* TMDS on chip */ - xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, Temp); - /* Disable read GPIOF */ - xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x20); - } - } -} - -static void XGINew_GetXG27Sense(struct vb_device_info *pVBInfo) -{ - unsigned char Temp, bCR4A; - - bCR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); - /* Enable GPIOA/B/C read */ - xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x07, 0x07); - Temp = xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0x07; - xgifb_reg_set(pVBInfo->P3d4, 0x4A, bCR4A); - - if (Temp <= 0x02) { - /* LVDS setting */ - xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0); - xgifb_reg_set(pVBInfo->P3d4, 0x30, 0x21); - } else { - /* TMDS/DVO setting */ - xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xA0); - } - xgifb_reg_or(pVBInfo->P3d4, 0x32, LCDSense); -} - -static unsigned char GetXG21FPBits(struct vb_device_info *pVBInfo) -{ - unsigned char CR38, CR4A, temp; - - CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); - /* enable GPIOE read */ - xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x10, 0x10); - CR38 = xgifb_reg_get(pVBInfo->P3d4, 0x38); - temp = 0; - if ((CR38 & 0xE0) > 0x80) { - temp = xgifb_reg_get(pVBInfo->P3d4, 0x48); - temp &= 0x08; - temp >>= 3; - } - - xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A); - - return temp; -} - -static unsigned char GetXG27FPBits(struct vb_device_info *pVBInfo) -{ - unsigned char CR4A, temp; - - CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); - /* enable GPIOA/B/C read */ - xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x03, 0x03); - temp = xgifb_reg_get(pVBInfo->P3d4, 0x48); - if (temp > 2) - temp = ((temp & 0x04) >> 1) | ((~temp) & 0x01); - - xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A); - - return temp; -} - -static bool xgifb_bridge_is_on(struct vb_device_info *vb_info) -{ - u8 flag; - - flag = xgifb_reg_get(vb_info->Part4Port, 0x00); - return flag == 1 || flag == 2; -} - -unsigned char XGIInitNew(struct pci_dev *pdev) -{ - struct xgifb_video_info *xgifb_info = pci_get_drvdata(pdev); - struct xgi_hw_device_info *HwDeviceExtension = &xgifb_info->hw_info; - struct vb_device_info VBINF; - struct vb_device_info *pVBInfo = &VBINF; - unsigned char i, temp = 0, temp1; - - pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress; - - if (!pVBInfo->FBAddr) { - dev_dbg(&pdev->dev, "pVBInfo->FBAddr == 0\n"); - return 0; - } - - XGIRegInit(pVBInfo, xgifb_info->vga_base); - - outb(0x67, pVBInfo->P3c2); - - InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo); - - /* Openkey */ - xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86); - - /* GetXG21Sense (GPIO) */ - if (HwDeviceExtension->jChipType == XG21) - XGINew_GetXG21Sense(pdev, pVBInfo); - - if (HwDeviceExtension->jChipType == XG27) - XGINew_GetXG27Sense(pVBInfo); - - /* Reset Extended register */ - - for (i = 0x06; i < 0x20; i++) - xgifb_reg_set(pVBInfo->P3c4, i, 0); - - for (i = 0x21; i <= 0x27; i++) - xgifb_reg_set(pVBInfo->P3c4, i, 0); - - for (i = 0x31; i <= 0x3B; i++) - xgifb_reg_set(pVBInfo->P3c4, i, 0); - - /* Auto over driver for XG42 */ - if (HwDeviceExtension->jChipType == XG42) - xgifb_reg_set(pVBInfo->P3c4, 0x3B, 0xC0); - - for (i = 0x79; i <= 0x7C; i++) - xgifb_reg_set(pVBInfo->P3d4, i, 0); - - if (HwDeviceExtension->jChipType >= XG20) - xgifb_reg_set(pVBInfo->P3d4, 0x97, pVBInfo->XGINew_CR97); - - /* SetDefExt1Regs begin */ - xgifb_reg_set(pVBInfo->P3c4, 0x07, XGI330_SR07); - if (HwDeviceExtension->jChipType == XG27) { - xgifb_reg_set(pVBInfo->P3c4, 0x40, XG27_SR40); - xgifb_reg_set(pVBInfo->P3c4, 0x41, XG27_SR41); - } - xgifb_reg_set(pVBInfo->P3c4, 0x11, 0x0F); - xgifb_reg_set(pVBInfo->P3c4, 0x1F, XGI330_SR1F); - /* Frame buffer can read/write SR20 */ - xgifb_reg_set(pVBInfo->P3c4, 0x20, 0xA0); - /* H/W request for slow corner chip */ - xgifb_reg_set(pVBInfo->P3c4, 0x36, 0x70); - if (HwDeviceExtension->jChipType == XG27) - xgifb_reg_set(pVBInfo->P3c4, 0x36, XG27_SR36); - - if (HwDeviceExtension->jChipType < XG20) { - u32 Temp; - - /* Set AGP customize registers (in SetDefAGPRegs) Start */ - for (i = 0x47; i <= 0x4C; i++) - xgifb_reg_set(pVBInfo->P3d4, - i, - XGI340_AGPReg[i - 0x47]); - - for (i = 0x70; i <= 0x71; i++) - xgifb_reg_set(pVBInfo->P3d4, - i, - XGI340_AGPReg[6 + i - 0x70]); - - for (i = 0x74; i <= 0x77; i++) - xgifb_reg_set(pVBInfo->P3d4, - i, - XGI340_AGPReg[8 + i - 0x74]); - - pci_read_config_dword(pdev, 0x50, &Temp); - Temp >>= 20; - Temp &= 0xF; - - if (Temp == 1) - xgifb_reg_set(pVBInfo->P3d4, 0x48, 0x20); /* CR48 */ - } /* != XG20 */ - - /* Set PCI */ - xgifb_reg_set(pVBInfo->P3c4, 0x23, XGI330_SR23); - xgifb_reg_set(pVBInfo->P3c4, 0x24, XGI330_SR24); - xgifb_reg_set(pVBInfo->P3c4, 0x25, 0); - - if (HwDeviceExtension->jChipType < XG20) { - /* Set VB */ - XGI_UnLockCRT2(pVBInfo); - /* disable VideoCapture */ - xgifb_reg_and_or(pVBInfo->Part0Port, 0x3F, 0xEF, 0x00); - xgifb_reg_set(pVBInfo->Part1Port, 0x00, 0x00); - /* chk if BCLK>=100MHz */ - temp1 = xgifb_reg_get(pVBInfo->P3d4, 0x7B); - - xgifb_reg_set(pVBInfo->Part1Port, - 0x02, XGI330_CRT2Data_1_2); - - xgifb_reg_set(pVBInfo->Part1Port, 0x2E, 0x08); /* use VB */ - } /* != XG20 */ - - xgifb_reg_set(pVBInfo->P3c4, 0x27, 0x1F); - - if ((HwDeviceExtension->jChipType == XG42) && - XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo) != 0) { - /* Not DDR */ - xgifb_reg_set(pVBInfo->P3c4, - 0x31, - (XGI330_SR31 & 0x3F) | 0x40); - xgifb_reg_set(pVBInfo->P3c4, - 0x32, - (XGI330_SR32 & 0xFC) | 0x01); - } else { - xgifb_reg_set(pVBInfo->P3c4, 0x31, XGI330_SR31); - xgifb_reg_set(pVBInfo->P3c4, 0x32, XGI330_SR32); - } - xgifb_reg_set(pVBInfo->P3c4, 0x33, XGI330_SR33); - - if (HwDeviceExtension->jChipType < XG20) { - if (xgifb_bridge_is_on(pVBInfo)) { - xgifb_reg_set(pVBInfo->Part2Port, 0x00, 0x1C); - xgifb_reg_set(pVBInfo->Part4Port, - 0x0D, XGI330_CRT2Data_4_D); - xgifb_reg_set(pVBInfo->Part4Port, - 0x0E, XGI330_CRT2Data_4_E); - xgifb_reg_set(pVBInfo->Part4Port, - 0x10, XGI330_CRT2Data_4_10); - xgifb_reg_set(pVBInfo->Part4Port, 0x0F, 0x3F); - XGI_LockCRT2(pVBInfo); - } - } /* != XG20 */ - - XGI_SenseCRT1(pVBInfo); - - if (HwDeviceExtension->jChipType == XG21) { - xgifb_reg_and_or(pVBInfo->P3d4, - 0x32, - ~Monitor1Sense, - Monitor1Sense); /* Z9 default has CRT */ - temp = GetXG21FPBits(pVBInfo); - xgifb_reg_and_or(pVBInfo->P3d4, 0x37, ~0x01, temp); - } - if (HwDeviceExtension->jChipType == XG27) { - xgifb_reg_and_or(pVBInfo->P3d4, - 0x32, - ~Monitor1Sense, - Monitor1Sense); /* Z9 default has CRT */ - temp = GetXG27FPBits(pVBInfo); - xgifb_reg_and_or(pVBInfo->P3d4, 0x37, ~0x03, temp); - } - - pVBInfo->ram_type = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo); - - XGINew_SetDRAMDefaultRegister340(HwDeviceExtension, - pVBInfo->P3d4, - pVBInfo); - - XGINew_SetDRAMSize_340(xgifb_info, HwDeviceExtension, pVBInfo); - - xgifb_reg_set(pVBInfo->P3c4, 0x22, 0xfa); - xgifb_reg_set(pVBInfo->P3c4, 0x21, 0xa3); - - XGINew_ChkSenseStatus(pVBInfo); - XGINew_SetModeScratch(pVBInfo); - - xgifb_reg_set(pVBInfo->P3d4, 0x8c, 0x87); - - return 1; -} /* end of init */ diff --git a/drivers/staging/xgifb/vb_init.h b/drivers/staging/xgifb/vb_init.h deleted file mode 100644 index 2f8a70133ebd..000000000000 --- a/drivers/staging/xgifb/vb_init.h +++ /dev/null @@ -1,6 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _VBINIT_ -#define _VBINIT_ -unsigned char XGIInitNew(struct pci_dev *pdev); -void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr); -#endif diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c deleted file mode 100644 index 3782f8641bf2..000000000000 --- a/drivers/staging/xgifb/vb_setmode.c +++ /dev/null @@ -1,5528 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include <linux/delay.h> -#include "XGIfb.h" - -#include "vb_def.h" -#include "vb_init.h" -#include "vb_util.h" -#include "vb_table.h" -#include "vb_setmode.h" - -#define IndexMask 0xff -#define TVCLKBASE_315_25 (TVCLKBASE_315 + 25) - -static const unsigned short XGINew_VGA_DAC[] = { - 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15, - 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F, - 0x00, 0x05, 0x08, 0x0B, 0x0E, 0x11, 0x14, 0x18, - 0x1C, 0x20, 0x24, 0x28, 0x2D, 0x32, 0x38, 0x3F, - 0x00, 0x10, 0x1F, 0x2F, 0x3F, 0x1F, 0x27, 0x2F, - 0x37, 0x3F, 0x2D, 0x31, 0x36, 0x3A, 0x3F, 0x00, - 0x07, 0x0E, 0x15, 0x1C, 0x0E, 0x11, 0x15, 0x18, - 0x1C, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x00, 0x04, - 0x08, 0x0C, 0x10, 0x08, 0x0A, 0x0C, 0x0E, 0x10, - 0x0B, 0x0C, 0x0D, 0x0F, 0x10}; - -void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) -{ - pVBInfo->MCLKData = XGI340New_MCLKData; - - pVBInfo->LCDResInfo = 0; - pVBInfo->LCDTypeInfo = 0; - pVBInfo->LCDInfo = 0; - pVBInfo->VBInfo = 0; - pVBInfo->TVInfo = 0; - - pVBInfo->SR18 = XGI340_SR18; - pVBInfo->CR40 = XGI340_cr41; - - if (ChipType < XG20) - XGI_GetVBType(pVBInfo); - - /* 310 customization related */ - if ((pVBInfo->VBType & VB_SIS301LV) || (pVBInfo->VBType & VB_SIS302LV)) - pVBInfo->LCDCapList = XGI_LCDDLCapList; - else - pVBInfo->LCDCapList = XGI_LCDCapList; - - if (ChipType >= XG20) - pVBInfo->XGINew_CR97 = 0x10; - - if (ChipType == XG27) { - unsigned char temp; - - pVBInfo->MCLKData = XGI27New_MCLKData; - pVBInfo->CR40 = XGI27_cr41; - pVBInfo->XGINew_CR97 = 0xc1; - pVBInfo->SR18 = XG27_SR18; - - /* Z11m DDR */ - temp = xgifb_reg_get(pVBInfo->P3c4, 0x3B); - /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */ - if (((temp & 0x88) == 0x80) || ((temp & 0x88) == 0x08)) - pVBInfo->XGINew_CR97 = 0x80; - } -} - -static void XGI_SetSeqRegs(struct vb_device_info *pVBInfo) -{ - unsigned char SRdata, i; - - xgifb_reg_set(pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */ - - for (i = 0; i < 4; i++) { - /* Get SR1,2,3,4 from file */ - /* SR1 is with screen off 0x20 */ - SRdata = XGI330_StandTable.SR[i]; - /* Set SR 1 2 3 4 */ - xgifb_reg_set(pVBInfo->P3c4, i + 1, SRdata); - } -} - -static void XGI_SetCRTCRegs(struct vb_device_info *pVBInfo) -{ - unsigned char CRTCdata; - unsigned short i; - - CRTCdata = xgifb_reg_get(pVBInfo->P3d4, 0x11); - CRTCdata &= 0x7f; - xgifb_reg_set(pVBInfo->P3d4, 0x11, CRTCdata); /* Unlock CRTC */ - - for (i = 0; i <= 0x18; i++) { - /* Get CRTC from file */ - CRTCdata = XGI330_StandTable.CRTC[i]; - xgifb_reg_set(pVBInfo->P3d4, i, CRTCdata); /* Set CRTC(3d4) */ - } -} - -static void XGI_SetATTRegs(unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned char ARdata; - unsigned short i, modeflag; - - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - - for (i = 0; i <= 0x13; i++) { - ARdata = XGI330_StandTable.ATTR[i]; - - if ((modeflag & Charx8Dot) && i == 0x13) { /* ifndef Dot9 */ - if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { - ARdata = 0; - } else if ((pVBInfo->VBInfo & - (SetCRT2ToTV | SetCRT2ToLCD)) && - (pVBInfo->VBInfo & SetInSlaveMode)) { - ARdata = 0; - } - } - - inb(pVBInfo->P3da); /* reset 3da */ - outb(i, pVBInfo->P3c0); /* set index */ - outb(ARdata, pVBInfo->P3c0); /* set data */ - } - - inb(pVBInfo->P3da); /* reset 3da */ - outb(0x14, pVBInfo->P3c0); /* set index */ - outb(0x00, pVBInfo->P3c0); /* set data */ - inb(pVBInfo->P3da); /* Enable Attribute */ - outb(0x20, pVBInfo->P3c0); -} - -static void XGI_SetGRCRegs(struct vb_device_info *pVBInfo) -{ - unsigned char GRdata; - unsigned short i; - - for (i = 0; i <= 0x08; i++) { - /* Get GR from file */ - GRdata = XGI330_StandTable.GRC[i]; - xgifb_reg_set(pVBInfo->P3ce, i, GRdata); /* Set GR(3ce) */ - } - - if (pVBInfo->ModeType > ModeVGA) { - GRdata = xgifb_reg_get(pVBInfo->P3ce, 0x05); - GRdata &= 0xBF; /* 256 color disable */ - xgifb_reg_set(pVBInfo->P3ce, 0x05, GRdata); - } -} - -static void XGI_ClearExt1Regs(struct vb_device_info *pVBInfo) -{ - unsigned short i; - - for (i = 0x0A; i <= 0x0E; i++) - xgifb_reg_set(pVBInfo->P3c4, i, 0x00); /* Clear SR0A-SR0E */ -} - -static unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo) -{ - xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, 0x20); - xgifb_reg_set(pVBInfo->P3c4, 0x2B, XGI_VCLKData[0].SR2B); - xgifb_reg_set(pVBInfo->P3c4, 0x2C, XGI_VCLKData[0].SR2C); - - xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, 0x10); - xgifb_reg_set(pVBInfo->P3c4, 0x2B, XGI_VCLKData[1].SR2B); - xgifb_reg_set(pVBInfo->P3c4, 0x2C, XGI_VCLKData[1].SR2C); - - xgifb_reg_and(pVBInfo->P3c4, 0x31, ~0x30); - return 0; -} - -static unsigned char XGI_AjustCRT2Rate(unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - unsigned short *i, - struct vb_device_info *pVBInfo) -{ - unsigned short tempax, tempbx, resinfo, modeflag, infoflag; - - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - tempbx = XGI330_RefIndex[RefreshRateTableIndex + (*i)].ModeID; - tempax = 0; - - if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) { - tempax |= SupportRAMDAC2; - - if (pVBInfo->VBType & VB_XGI301C) - tempax |= SupportCRT2in301C; - } - - /* 301b */ - if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { - tempax |= SupportLCD; - - if (pVBInfo->LCDResInfo != Panel_1280x1024 && - pVBInfo->LCDResInfo != Panel_1280x960 && - (pVBInfo->LCDInfo & LCDNonExpanding) && - resinfo >= 9) - return 0; - } - - if (pVBInfo->VBInfo & SetCRT2ToHiVision) { /* for HiTV */ - tempax |= SupportHiVision; - if ((pVBInfo->VBInfo & SetInSlaveMode) && - ((resinfo == 4) || - (resinfo == 3 && (pVBInfo->SetFlag & TVSimuMode)) || - (resinfo > 7))) - return 0; - } else if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO | SetCRT2ToSVIDEO | - SetCRT2ToSCART | SetCRT2ToYPbPr525750 | - SetCRT2ToHiVision)) { - tempax |= SupportTV; - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV | - VB_SIS302LV | VB_XGI301C)) - tempax |= SupportTV1024; - - if (!(pVBInfo->VBInfo & TVSetPAL) && - (modeflag & NoSupportSimuTV) && - (pVBInfo->VBInfo & SetInSlaveMode) && - !(pVBInfo->VBInfo & SetNotSimuMode)) - return 0; - } - - for (; XGI330_RefIndex[RefreshRateTableIndex + (*i)].ModeID == - tempbx; (*i)--) { - infoflag = XGI330_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag; - if (infoflag & tempax) - return 1; - - if ((*i) == 0) - break; - } - - for ((*i) = 0;; (*i)++) { - infoflag = XGI330_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag; - if (XGI330_RefIndex[RefreshRateTableIndex + (*i)].ModeID - != tempbx) { - return 0; - } - - if (infoflag & tempax) - return 1; - } - return 1; -} - -static void XGI_SetSync(unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short sync, temp; - - /* di+0x00 */ - sync = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8; - sync &= 0xC0; - temp = 0x2F; - temp |= sync; - outb(temp, pVBInfo->P3c2); /* Set Misc(3c2) */ -} - -static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo, - struct xgi_hw_device_info *HwDeviceExtension) -{ - unsigned char data, data1, pushax; - unsigned short i, j; - - /* unlock cr0-7 */ - data = xgifb_reg_get(pVBInfo->P3d4, 0x11); - data &= 0x7F; - xgifb_reg_set(pVBInfo->P3d4, 0x11, data); - - data = pVBInfo->TimingH.data[0]; - xgifb_reg_set(pVBInfo->P3d4, 0, data); - - for (i = 0x01; i <= 0x04; i++) { - data = pVBInfo->TimingH.data[i]; - xgifb_reg_set(pVBInfo->P3d4, (unsigned short)(i + 1), data); - } - - for (i = 0x05; i <= 0x06; i++) { - data = pVBInfo->TimingH.data[i]; - xgifb_reg_set(pVBInfo->P3c4, (unsigned short)(i + 6), data); - } - - j = xgifb_reg_get(pVBInfo->P3c4, 0x0e); - j &= 0x1F; - data = pVBInfo->TimingH.data[7]; - data &= 0xE0; - data |= j; - xgifb_reg_set(pVBInfo->P3c4, 0x0e, data); - - if (HwDeviceExtension->jChipType >= XG20) { - data = xgifb_reg_get(pVBInfo->P3d4, 0x04); - data = data - 1; - xgifb_reg_set(pVBInfo->P3d4, 0x04, data); - data = xgifb_reg_get(pVBInfo->P3d4, 0x05); - data1 = data; - data1 &= 0xE0; - data &= 0x1F; - if (data == 0) { - pushax = data; - data = xgifb_reg_get(pVBInfo->P3c4, 0x0c); - data &= 0xFB; - xgifb_reg_set(pVBInfo->P3c4, 0x0c, data); - data = pushax; - } - data = data - 1; - data |= data1; - xgifb_reg_set(pVBInfo->P3d4, 0x05, data); - data = xgifb_reg_get(pVBInfo->P3c4, 0x0e); - data >>= 5; - data = data + 3; - if (data > 7) - data = data - 7; - data <<= 5; - xgifb_reg_and_or(pVBInfo->P3c4, 0x0e, ~0xE0, data); - } -} - -static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned char data; - unsigned short i, j; - - for (i = 0x00; i <= 0x01; i++) { - data = pVBInfo->TimingV.data[i]; - xgifb_reg_set(pVBInfo->P3d4, (unsigned short)(i + 6), data); - } - - for (i = 0x02; i <= 0x03; i++) { - data = pVBInfo->TimingV.data[i]; - xgifb_reg_set(pVBInfo->P3d4, (unsigned short)(i + 0x0e), data); - } - - for (i = 0x04; i <= 0x05; i++) { - data = pVBInfo->TimingV.data[i]; - xgifb_reg_set(pVBInfo->P3d4, (unsigned short)(i + 0x11), data); - } - - j = xgifb_reg_get(pVBInfo->P3c4, 0x0a); - j &= 0xC0; - data = pVBInfo->TimingV.data[6]; - data &= 0x3F; - data |= j; - xgifb_reg_set(pVBInfo->P3c4, 0x0a, data); - - data = pVBInfo->TimingV.data[6]; - data &= 0x80; - data >>= 2; - - i = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - i &= DoubleScanMode; - if (i) - data |= 0x80; - - j = xgifb_reg_get(pVBInfo->P3d4, 0x09); - j &= 0x5F; - data |= j; - xgifb_reg_set(pVBInfo->P3d4, 0x09, data); -} - -static void XGI_SetCRT1CRTC(unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo, - struct xgi_hw_device_info *HwDeviceExtension) -{ - unsigned char index, data; - unsigned short i; - - /* Get index */ - index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - index = index & IndexMask; - - data = xgifb_reg_get(pVBInfo->P3d4, 0x11); - data &= 0x7F; - xgifb_reg_set(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */ - - for (i = 0; i < 8; i++) - pVBInfo->TimingH.data[i] - = XGI_CRT1Table[index].CR[i]; - - for (i = 0; i < 7; i++) - pVBInfo->TimingV.data[i] - = XGI_CRT1Table[index].CR[i + 8]; - - XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension); - - XGI_SetCRT1Timing_V(ModeIdIndex, pVBInfo); - - if (pVBInfo->ModeType > 0x03) - xgifb_reg_set(pVBInfo->P3d4, 0x14, 0x4F); -} - -/* - * Function : XGI_SetXG21CRTC - * Input : Stand or enhance CRTC table - * Output : Fill CRT Hsync/Vsync to SR2E/SR2F/SR30/SR33/SR34/SR3F - * Description : Set LCD timing - */ -static void XGI_SetXG21CRTC(unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned char index, Tempax, Tempbx, Tempcx, Tempdx; - unsigned short Temp1, Temp2, Temp3; - - index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - /* Tempax: CR4 HRS */ - Tempax = XGI_CRT1Table[index].CR[3]; - Tempcx = Tempax; /* Tempcx: HRS */ - /* SR2E[7:0]->HRS */ - xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax); - - Tempdx = XGI_CRT1Table[index].CR[5]; /* SRB */ - Tempdx &= 0xC0; /* Tempdx[7:6]: SRB[7:6] */ - Temp1 = Tempdx; /* Temp1[7:6]: HRS[9:8] */ - Temp1 <<= 2; /* Temp1[9:8]: HRS[9:8] */ - Temp1 |= Tempax; /* Temp1[9:0]: HRS[9:0] */ - - Tempax = XGI_CRT1Table[index].CR[4]; /* CR5 HRE */ - Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */ - - Tempbx = XGI_CRT1Table[index].CR[6]; /* SRC */ - Tempbx &= 0x04; /* Tempbx[2]: HRE[5] */ - Tempbx <<= 3; /* Tempbx[5]: HRE[5] */ - Tempax |= Tempbx; /* Tempax[5:0]: HRE[5:0] */ - - Temp2 = Temp1 & 0x3C0; /* Temp2[9:6]: HRS[9:6] */ - Temp2 |= Tempax; /* Temp2[9:0]: HRE[9:0] */ - - Tempcx &= 0x3F; /* Tempcx[5:0]: HRS[5:0] */ - if (Tempax < Tempcx) /* HRE < HRS */ - Temp2 |= 0x40; /* Temp2 + 0x40 */ - - Temp2 &= 0xFF; - Tempax = (unsigned char)Temp2; /* Tempax: HRE[7:0] */ - Tempax <<= 2; /* Tempax[7:2]: HRE[5:0] */ - Tempdx >>= 6; /* Tempdx[7:6]->[1:0] HRS[9:8] */ - Tempax |= Tempdx; /* HRE[5:0]HRS[9:8] */ - /* SR2F D[7:2]->HRE, D[1:0]->HRS */ - xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax); - xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00); - - /* CR10 VRS */ - Tempax = XGI_CRT1Table[index].CR[10]; - Tempbx = Tempax; /* Tempbx: VRS */ - Tempax &= 0x01; /* Tempax[0]: VRS[0] */ - xgifb_reg_or(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS[0] */ - /* CR7[2][7] VRE */ - Tempax = XGI_CRT1Table[index].CR[9]; - Tempcx = Tempbx >> 1; /* Tempcx[6:0]: VRS[7:1] */ - Tempdx = Tempax & 0x04; /* Tempdx[2]: CR7[2] */ - Tempdx <<= 5; /* Tempdx[7]: VRS[8] */ - Tempcx |= Tempdx; /* Tempcx[7:0]: VRS[8:1] */ - xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempcx); /* SR34[8:1]->VRS */ - - Temp1 = Tempdx; /* Temp1[7]: Tempdx[7] */ - Temp1 <<= 1; /* Temp1[8]: VRS[8] */ - Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */ - Tempax &= 0x80; - Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */ - Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */ - /* Tempax: SRA */ - Tempax = XGI_CRT1Table[index].CR[14]; - Tempax &= 0x08; /* Tempax[3]: VRS[3] */ - Temp2 = Tempax; - Temp2 <<= 7; /* Temp2[10]: VRS[10] */ - Temp1 |= Temp2; /* Temp1[10:0]: VRS[10:0] */ - - /* Tempax: CR11 VRE */ - Tempax = XGI_CRT1Table[index].CR[11]; - Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */ - /* Tempbx: SRA */ - Tempbx = XGI_CRT1Table[index].CR[14]; - Tempbx &= 0x20; /* Tempbx[5]: VRE[5] */ - Tempbx >>= 1; /* Tempbx[4]: VRE[4] */ - Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */ - Temp2 = Temp1 & 0x7E0; /* Temp2[10:5]: VRS[10:5] */ - Temp2 |= Tempax; /* Temp2[10:5]: VRE[10:5] */ - - Temp3 = Temp1 & 0x1F; /* Temp3[4:0]: VRS[4:0] */ - if (Tempax < Temp3) /* VRE < VRS */ - Temp2 |= 0x20; /* VRE + 0x20 */ - - Temp2 &= 0xFF; - Tempax = (unsigned char)Temp2; /* Tempax: VRE[7:0] */ - Tempax <<= 2; /* Tempax[7:0]; VRE[5:0]00 */ - Temp1 &= 0x600; /* Temp1[10:9]: VRS[10:9] */ - Temp1 >>= 9; /* Temp1[1:0]: VRS[10:9] */ - Tempbx = (unsigned char)Temp1; - Tempax |= Tempbx; /* Tempax[7:0]: VRE[5:0]VRS[10:9] */ - Tempax &= 0x7F; - /* SR3F D[7:2]->VRE D[1:0]->VRS */ - xgifb_reg_set(pVBInfo->P3c4, 0x3F, Tempax); -} - -static void XGI_SetXG27CRTC(unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short index, Tempax, Tempbx, Tempcx; - - index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - /* Tempax: CR4 HRS */ - Tempax = XGI_CRT1Table[index].CR[3]; - Tempbx = Tempax; /* Tempbx: HRS[7:0] */ - /* SR2E[7:0]->HRS */ - xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax); - - /* SR0B */ - Tempax = XGI_CRT1Table[index].CR[5]; - Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8] */ - Tempbx |= Tempax << 2; /* Tempbx: HRS[9:0] */ - - Tempax = XGI_CRT1Table[index].CR[4]; /* CR5 HRE */ - Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */ - Tempcx = Tempax; /* Tempcx: HRE[4:0] */ - - Tempax = XGI_CRT1Table[index].CR[6]; /* SRC */ - Tempax &= 0x04; /* Tempax[2]: HRE[5] */ - Tempax <<= 3; /* Tempax[5]: HRE[5] */ - Tempcx |= Tempax; /* Tempcx[5:0]: HRE[5:0] */ - - Tempbx = Tempbx & 0x3C0; /* Tempbx[9:6]: HRS[9:6] */ - Tempbx |= Tempcx; /* Tempbx: HRS[9:6]HRE[5:0] */ - - /* Tempax: CR4 HRS */ - Tempax = XGI_CRT1Table[index].CR[3]; - Tempax &= 0x3F; /* Tempax: HRS[5:0] */ - if (Tempcx <= Tempax) /* HRE[5:0] < HRS[5:0] */ - Tempbx += 0x40; /* Tempbx= Tempbx + 0x40 : HRE[9:0]*/ - - Tempax = XGI_CRT1Table[index].CR[5]; /* SR0B */ - Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/ - Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/ - Tempax |= (Tempbx << 2) & 0xFF; /* Tempax[7:2]: HRE[5:0] */ - /* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */ - xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax); - xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00); - - /* CR10 VRS */ - Tempax = XGI_CRT1Table[index].CR[10]; - /* SR34[7:0]->VRS[7:0] */ - xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempax); - - Tempcx = Tempax; /* Tempcx <= VRS[7:0] */ - /* CR7[7][2] VRS[9][8] */ - Tempax = XGI_CRT1Table[index].CR[9]; - Tempbx = Tempax; /* Tempbx <= CR07[7:0] */ - Tempax = Tempax & 0x04; /* Tempax[2]: CR7[2]: VRS[8] */ - Tempax >>= 2; /* Tempax[0]: VRS[8] */ - /* SR35[0]: VRS[8] */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x01, Tempax); - Tempcx |= Tempax << 8; /* Tempcx <= VRS[8:0] */ - Tempcx |= (Tempbx & 0x80) << 2; /* Tempcx <= VRS[9:0] */ - /* Tempax: SR0A */ - Tempax = XGI_CRT1Table[index].CR[14]; - Tempax &= 0x08; /* SR0A[3] VRS[10] */ - Tempcx |= Tempax << 7; /* Tempcx <= VRS[10:0] */ - - /* Tempax: CR11 VRE */ - Tempax = XGI_CRT1Table[index].CR[11]; - Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */ - /* Tempbx: SR0A */ - Tempbx = XGI_CRT1Table[index].CR[14]; - Tempbx &= 0x20; /* Tempbx[5]: SR0A[5]: VRE[4] */ - Tempbx >>= 1; /* Tempbx[4]: VRE[4] */ - Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */ - Tempbx = Tempcx; /* Tempbx: VRS[10:0] */ - Tempbx &= 0x7E0; /* Tempbx[10:5]: VRS[10:5] */ - Tempbx |= Tempax; /* Tempbx: VRS[10:5]VRE[4:0] */ - - if (Tempbx <= Tempcx) /* VRE <= VRS */ - Tempbx |= 0x20; /* VRE + 0x20 */ - - /* Tempax: Tempax[7:0]; VRE[5:0]00 */ - Tempax = (Tempbx << 2) & 0xFF; - /* SR3F[7:2]:VRE[5:0] */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax); - Tempax = Tempcx >> 8; - /* SR35[2:0]:VRS[10:8] */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x07, Tempax); -} - -static void XGI_SetXG27FPBits(struct vb_device_info *pVBInfo) -{ - unsigned char temp; - - /* D[1:0] 01: 18bit, 00: dual 12, 10: single 24 */ - temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); - temp = (temp & 3) << 6; - /* SR06[7]0: dual 12/1: single 24 [6] 18bit Dither <= 0 h/w recommend */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0xc0, temp & 0x80); - /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: 24bits */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80); -} - -static void xgifb_set_lcd(int chip_id, - struct vb_device_info *pVBInfo, - unsigned short RefreshRateTableIndex) -{ - unsigned short temp; - - xgifb_reg_set(pVBInfo->P3d4, 0x2E, 0x00); - xgifb_reg_set(pVBInfo->P3d4, 0x2F, 0x00); - xgifb_reg_set(pVBInfo->P3d4, 0x46, 0x00); - xgifb_reg_set(pVBInfo->P3d4, 0x47, 0x00); - - if (chip_id == XG27) { - temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); - if ((temp & 0x03) == 0) { /* dual 12 */ - xgifb_reg_set(pVBInfo->P3d4, 0x46, 0x13); - xgifb_reg_set(pVBInfo->P3d4, 0x47, 0x13); - } - } - - if (chip_id == XG27) { - XGI_SetXG27FPBits(pVBInfo); - } else { - temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); - if (temp & 0x01) { - /* 18 bits FP */ - xgifb_reg_or(pVBInfo->P3c4, 0x06, 0x40); - xgifb_reg_or(pVBInfo->P3c4, 0x09, 0x40); - } - } - - xgifb_reg_or(pVBInfo->P3c4, 0x1E, 0x01); /* Negative blank polarity */ - - xgifb_reg_and(pVBInfo->P3c4, 0x30, ~0x20); /* Hsync polarity */ - xgifb_reg_and(pVBInfo->P3c4, 0x35, ~0x80); /* Vsync polarity */ - - temp = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; - if (temp & 0x4000) { - /* Hsync polarity */ - xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20); - } - if (temp & 0x8000) { - /* Vsync polarity */ - xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80); - } -} - -/* - * Function : XGI_UpdateXG21CRTC - * Input : - * Output : CRT1 CRTC - * Description : Modify CRT1 Hsync/Vsync to fix LCD mode timing - */ -static void XGI_UpdateXG21CRTC(unsigned short ModeNo, - struct vb_device_info *pVBInfo, - unsigned short RefreshRateTableIndex) -{ - int index = -1; - - xgifb_reg_and(pVBInfo->P3d4, 0x11, 0x7F); /* Unlock CR0~7 */ - if (ModeNo == 0x2E && - (XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC == - RES640x480x60)) - index = 12; - else if (ModeNo == 0x2E && - (XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC == - RES640x480x72)) - index = 13; - else if (ModeNo == 0x2F) - index = 14; - else if (ModeNo == 0x50) - index = 15; - else if (ModeNo == 0x59) - index = 16; - - if (index != -1) { - xgifb_reg_set(pVBInfo->P3d4, 0x02, - XGI_UpdateCRT1Table[index].CR02); - xgifb_reg_set(pVBInfo->P3d4, 0x03, - XGI_UpdateCRT1Table[index].CR03); - xgifb_reg_set(pVBInfo->P3d4, 0x15, - XGI_UpdateCRT1Table[index].CR15); - xgifb_reg_set(pVBInfo->P3d4, 0x16, - XGI_UpdateCRT1Table[index].CR16); - } -} - -static void XGI_SetCRT1DE(unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short resindex, tempax, tempbx, tempcx, temp, modeflag; - - unsigned char data; - - resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - tempax = XGI330_ModeResInfo[resindex].HTotal; - tempbx = XGI330_ModeResInfo[resindex].VTotal; - - if (modeflag & HalfDCLK) - tempax >>= 1; - - if (modeflag & HalfDCLK) - tempax <<= 1; - - temp = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; - - if (temp & InterlaceMode) - tempbx >>= 1; - - if (modeflag & DoubleScanMode) - tempbx <<= 1; - - tempcx = 8; - - tempax /= tempcx; - tempax -= 1; - tempbx -= 1; - tempcx = tempax; - temp = xgifb_reg_get(pVBInfo->P3d4, 0x11); - data = xgifb_reg_get(pVBInfo->P3d4, 0x11); - data &= 0x7F; - xgifb_reg_set(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */ - xgifb_reg_set(pVBInfo->P3d4, 0x01, (unsigned short)(tempcx & 0xff)); - xgifb_reg_and_or(pVBInfo->P3d4, 0x0b, ~0x0c, - (unsigned short)((tempcx & 0x0ff00) >> 10)); - xgifb_reg_set(pVBInfo->P3d4, 0x12, (unsigned short)(tempbx & 0xff)); - tempax = 0; - tempbx >>= 8; - - if (tempbx & 0x01) - tempax |= 0x02; - - if (tempbx & 0x02) - tempax |= 0x40; - - xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x42, tempax); - data = xgifb_reg_get(pVBInfo->P3d4, 0x07); - tempax = 0; - - if (tempbx & 0x04) - tempax |= 0x02; - - xgifb_reg_and_or(pVBInfo->P3d4, 0x0a, ~0x02, tempax); - xgifb_reg_set(pVBInfo->P3d4, 0x11, temp); -} - -static void XGI_SetCRT1Offset(unsigned short ModeNo, - unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short temp, ah, al, temp2, i, DisplayUnit; - - /* GetOffset */ - temp = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeInfo; - temp >>= 8; - temp = XGI330_ScreenOffset[temp]; - - temp2 = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; - temp2 &= InterlaceMode; - - if (temp2) - temp <<= 1; - - temp2 = pVBInfo->ModeType - ModeEGA; - - switch (temp2) { - case 0: - temp2 = 1; - break; - case 1: - temp2 = 2; - break; - case 2: - temp2 = 4; - break; - case 3: - temp2 = 4; - break; - case 4: - temp2 = 6; - break; - case 5: - temp2 = 8; - break; - default: - break; - } - - if ((ModeNo >= 0x26) && (ModeNo <= 0x28)) - temp = temp * temp2 + temp2 / 2; - else - temp *= temp2; - - /* SetOffset */ - DisplayUnit = temp; - temp2 = temp; - temp >>= 8; /* ah */ - temp &= 0x0F; - i = xgifb_reg_get(pVBInfo->P3c4, 0x0E); - i &= 0xF0; - i |= temp; - xgifb_reg_set(pVBInfo->P3c4, 0x0E, i); - - temp = (unsigned char)temp2; - temp &= 0xFF; /* al */ - xgifb_reg_set(pVBInfo->P3d4, 0x13, temp); - - /* SetDisplayUnit */ - temp2 = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; - temp2 &= InterlaceMode; - if (temp2) - DisplayUnit >>= 1; - - DisplayUnit <<= 5; - ah = (DisplayUnit & 0xff00) >> 8; - al = DisplayUnit & 0x00ff; - if (al == 0) - ah += 1; - else - ah += 2; - - if (HwDeviceExtension->jChipType >= XG20) - if ((ModeNo == 0x4A) | (ModeNo == 0x49)) - ah -= 1; - - xgifb_reg_set(pVBInfo->P3c4, 0x10, ah); -} - -static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short VCLKIndex, modeflag; - - /* si+Ext_ResInfo */ - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - - if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { /* 301b */ - if (pVBInfo->LCDResInfo != Panel_1024x768) - /* LCDXlat2VCLK */ - VCLKIndex = VCLK108_2_315 + 5; - else - VCLKIndex = VCLK65_315 + 2; /* LCDXlat1VCLK */ - } else if (pVBInfo->VBInfo & SetCRT2ToHiVision) { - if (pVBInfo->SetFlag & RPLLDIV2XO) - VCLKIndex = TVCLKBASE_315_25 + HiTVVCLKDIV2; - else - VCLKIndex = TVCLKBASE_315_25 + HiTVVCLK; - - if (pVBInfo->SetFlag & TVSimuMode) { - if (modeflag & Charx8Dot) - VCLKIndex = TVCLKBASE_315_25 + HiTVSimuVCLK; - else - VCLKIndex = TVCLKBASE_315_25 + HiTVTextVCLK; - } - - /* 301lv */ - if (pVBInfo->VBType & VB_SIS301LV) { - if (pVBInfo->SetFlag & RPLLDIV2XO) - VCLKIndex = YPbPr525iVCLK_2; - else - VCLKIndex = YPbPr525iVCLK; - } - } else if (pVBInfo->VBInfo & SetCRT2ToTV) { - if (pVBInfo->SetFlag & RPLLDIV2XO) - VCLKIndex = TVCLKBASE_315_25 + TVVCLKDIV2; - else - VCLKIndex = TVCLKBASE_315_25 + TVVCLK; - } else { /* for CRT2 */ - /* di+Ext_CRTVCLK */ - VCLKIndex = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; - VCLKIndex &= IndexMask; - } - - return VCLKIndex; -} - -static void XGI_SetCRT1VCLK(unsigned short ModeIdIndex, - struct xgi_hw_device_info *HwDeviceExtension, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned char index, data; - unsigned short vclkindex; - - if ((pVBInfo->IF_DEF_LVDS == 0) && - (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV | - VB_SIS302LV | VB_XGI301C)) && - (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) { - vclkindex = XGI_GetVCLK2Ptr(ModeIdIndex, RefreshRateTableIndex, - pVBInfo); - data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF; - xgifb_reg_set(pVBInfo->P3c4, 0x31, data); - data = XGI_VBVCLKData[vclkindex].Part4_A; - xgifb_reg_set(pVBInfo->P3c4, 0x2B, data); - data = XGI_VBVCLKData[vclkindex].Part4_B; - xgifb_reg_set(pVBInfo->P3c4, 0x2C, data); - xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01); - } else { - index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; - data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF; - xgifb_reg_set(pVBInfo->P3c4, 0x31, data); - xgifb_reg_set(pVBInfo->P3c4, 0x2B, XGI_VCLKData[index].SR2B); - xgifb_reg_set(pVBInfo->P3c4, 0x2C, XGI_VCLKData[index].SR2C); - xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01); - } - - if (HwDeviceExtension->jChipType >= XG20) { - if (XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag & - HalfDCLK) { - data = xgifb_reg_get(pVBInfo->P3c4, 0x2B); - xgifb_reg_set(pVBInfo->P3c4, 0x2B, data); - data = xgifb_reg_get(pVBInfo->P3c4, 0x2C); - index = data; - index &= 0xE0; - data &= 0x1F; - data <<= 1; - data += 1; - data |= index; - xgifb_reg_set(pVBInfo->P3c4, 0x2C, data); - } - } -} - -static void XGI_SetXG21FPBits(struct vb_device_info *pVBInfo) -{ - unsigned char temp; - - temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); /* D[0] 1: 18bit */ - temp = (temp & 1) << 6; - /* SR06[6] 18bit Dither */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x40, temp); - /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: dual 12bits */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80); -} - -static void XGI_SetCRT1FIFO(struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short data; - - data = xgifb_reg_get(pVBInfo->P3c4, 0x3D); - data &= 0xfe; - xgifb_reg_set(pVBInfo->P3c4, 0x3D, data); /* disable auto-threshold */ - - xgifb_reg_set(pVBInfo->P3c4, 0x08, 0x34); - data = xgifb_reg_get(pVBInfo->P3c4, 0x09); - data &= 0xC0; - xgifb_reg_set(pVBInfo->P3c4, 0x09, data | 0x30); - data = xgifb_reg_get(pVBInfo->P3c4, 0x3D); - data |= 0x01; - xgifb_reg_set(pVBInfo->P3c4, 0x3D, data); - - if (HwDeviceExtension->jChipType == XG21) - XGI_SetXG21FPBits(pVBInfo); /* Fix SR9[7:6] can't read back */ -} - -static void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short data, data2 = 0; - short VCLK; - - unsigned char index; - - index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; - index &= IndexMask; - VCLK = XGI_VCLKData[index].CLOCK; - - data = xgifb_reg_get(pVBInfo->P3c4, 0x32); - data &= 0xf3; - if (VCLK >= 200) - data |= 0x0c; /* VCLK > 200 */ - - if (HwDeviceExtension->jChipType >= XG20) - data &= ~0x04; /* 2 pixel mode */ - - xgifb_reg_set(pVBInfo->P3c4, 0x32, data); - - if (HwDeviceExtension->jChipType < XG20) { - data = xgifb_reg_get(pVBInfo->P3c4, 0x1F); - data &= 0xE7; - if (VCLK < 200) - data |= 0x10; - xgifb_reg_set(pVBInfo->P3c4, 0x1F, data); - } - - data2 = 0x00; - - xgifb_reg_and_or(pVBInfo->P3c4, 0x07, 0xFC, data2); - if (HwDeviceExtension->jChipType >= XG27) - xgifb_reg_and_or(pVBInfo->P3c4, 0x40, 0xFC, data2 & 0x03); -} - -static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, - unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short data, data2, data3, infoflag = 0, modeflag, resindex, - xres; - - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - infoflag = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; - - if (xgifb_reg_get(pVBInfo->P3d4, 0x31) & 0x01) - xgifb_reg_and_or(pVBInfo->P3c4, 0x1F, 0x3F, 0x00); - - data = infoflag; - data2 = 0; - data2 |= 0x02; - data3 = pVBInfo->ModeType - ModeVGA; - data3 <<= 2; - data2 |= data3; - data &= InterlaceMode; - - if (data) - data2 |= 0x20; - - xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x3F, data2); - resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */ - - data = 0x0000; - if (infoflag & InterlaceMode) { - if (xres == 1024) - data = 0x0035; - else if (xres == 1280) - data = 0x0048; - } - - xgifb_reg_and_or(pVBInfo->P3d4, 0x19, 0xFF, data); - xgifb_reg_and_or(pVBInfo->P3d4, 0x19, 0xFC, 0); - - if (modeflag & HalfDCLK) - xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xF7, 0x08); - - data2 = 0; - - if (modeflag & LineCompareOff) - data2 |= 0x08; - - xgifb_reg_and_or(pVBInfo->P3c4, 0x0F, ~0x48, data2); - data = 0x60; - data = data ^ 0x60; - data = data ^ 0xA0; - xgifb_reg_and_or(pVBInfo->P3c4, 0x21, 0x1F, data); - - XGI_SetVCLKState(HwDeviceExtension, RefreshRateTableIndex, pVBInfo); - - data = xgifb_reg_get(pVBInfo->P3d4, 0x31); - - if (HwDeviceExtension->jChipType == XG27) { - if (data & 0x40) - data = 0x2c; - else - data = 0x6c; - xgifb_reg_set(pVBInfo->P3d4, 0x52, data); - xgifb_reg_or(pVBInfo->P3d4, 0x51, 0x10); - } else if (HwDeviceExtension->jChipType >= XG20) { - if (data & 0x40) - data = 0x33; - else - data = 0x73; - xgifb_reg_set(pVBInfo->P3d4, 0x52, data); - xgifb_reg_set(pVBInfo->P3d4, 0x51, 0x02); - } else { - if (data & 0x40) - data = 0x2c; - else - data = 0x6c; - xgifb_reg_set(pVBInfo->P3d4, 0x52, data); - } -} - -static void XGI_WriteDAC(unsigned short dl, - unsigned short ah, - unsigned short al, - unsigned short dh, - struct vb_device_info *pVBInfo) -{ - unsigned short bh, bl; - - bh = ah; - bl = al; - - if (dl != 0) { - swap(bh, dh); - if (dl == 1) - swap(bl, dh); - else - swap(bl, bh); - } - outb((unsigned short)dh, pVBInfo->P3c9); - outb((unsigned short)bh, pVBInfo->P3c9); - outb((unsigned short)bl, pVBInfo->P3c9); -} - -static void XGI_LoadDAC(struct vb_device_info *pVBInfo) -{ - unsigned short data, data2, i, k, m, n, o, si, di, bx, dl, al, ah, dh; - const unsigned short *table = XGINew_VGA_DAC; - - outb(0xFF, pVBInfo->P3c6); - outb(0x00, pVBInfo->P3c8); - - for (i = 0; i < 16; i++) { - data = table[i]; - - for (k = 0; k < 3; k++) { - data2 = 0; - - if (data & 0x01) - data2 = 0x2A; - - if (data & 0x02) - data2 += 0x15; - - outb(data2, pVBInfo->P3c9); - data >>= 2; - } - } - - for (i = 16; i < 32; i++) { - data = table[i]; - - for (k = 0; k < 3; k++) - outb(data, pVBInfo->P3c9); - } - - si = 32; - - for (m = 0; m < 9; m++) { - di = si; - bx = si + 0x04; - dl = 0; - - for (n = 0; n < 3; n++) { - for (o = 0; o < 5; o++) { - dh = table[si]; - ah = table[di]; - al = table[bx]; - si++; - XGI_WriteDAC(dl, ah, al, dh, pVBInfo); - } - - si -= 2; - - for (o = 0; o < 3; o++) { - dh = table[bx]; - ah = table[di]; - al = table[si]; - si--; - XGI_WriteDAC(dl, ah, al, dh, pVBInfo); - } - - dl++; - } - - si += 5; - } -} - -static void XGI_GetLVDSResInfo(unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short resindex, xres, yres, modeflag; - - /* si+Ext_ResInfo */ - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - - /* si+Ext_ResInfo */ - resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - - xres = XGI330_ModeResInfo[resindex].HTotal; - yres = XGI330_ModeResInfo[resindex].VTotal; - - if (modeflag & HalfDCLK) - xres <<= 1; - - if (modeflag & DoubleScanMode) - yres <<= 1; - - if (xres == 720) - xres = 640; - - pVBInfo->VGAHDE = xres; - pVBInfo->HDE = xres; - pVBInfo->VGAVDE = yres; - pVBInfo->VDE = yres; -} - -static void const *XGI_GetLcdPtr(struct XGI330_LCDDataTablStruct const *table, - unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short i, tempdx, tempbx, modeflag; - - tempbx = 0; - - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - - i = 0; - - while (table[i].PANELID != 0xff) { - tempdx = pVBInfo->LCDResInfo; - if (tempbx & 0x0080) { /* OEMUtil */ - tempbx &= ~0x0080; - tempdx = pVBInfo->LCDTypeInfo; - } - - if (pVBInfo->LCDInfo & EnableScalingLCD) - tempdx &= ~PanelResInfo; - - if (table[i].PANELID == tempdx) { - tempbx = table[i].MASK; - tempdx = pVBInfo->LCDInfo; - - if (modeflag & HalfDCLK) - tempdx |= SetLCDLowResolution; - - tempbx &= tempdx; - if (tempbx == table[i].CAP) - break; - } - i++; - } - - return table[i].DATAPTR; -} - -static struct SiS_TVData const *XGI_GetTVPtr( - unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short i, tempdx, tempal, modeflag; - - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - tempal = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; - tempal = tempal & 0x3f; - tempdx = pVBInfo->TVInfo; - - if (pVBInfo->VBInfo & SetInSlaveMode) - tempdx = tempdx | SetTVLockMode; - - if (modeflag & HalfDCLK) - tempdx = tempdx | SetTVLowResolution; - - i = 0; - - while (XGI_TVDataTable[i].MASK != 0xffff) { - if ((tempdx & XGI_TVDataTable[i].MASK) == - XGI_TVDataTable[i].CAP) - break; - i++; - } - - return &XGI_TVDataTable[i].DATAPTR[tempal]; -} - -static void XGI_GetLVDSData(unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - struct SiS_LVDSData const *LCDPtr; - - if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))) - return; - - LCDPtr = XGI_GetLcdPtr(XGI_EPLLCDDataPtr, ModeIdIndex, pVBInfo); - pVBInfo->VGAHT = LCDPtr->VGAHT; - pVBInfo->VGAVT = LCDPtr->VGAVT; - pVBInfo->HT = LCDPtr->LCDHT; - pVBInfo->VT = LCDPtr->LCDVT; - - if (pVBInfo->LCDInfo & (SetLCDtoNonExpanding | EnableScalingLCD)) - return; - - if ((pVBInfo->LCDResInfo == Panel_1024x768) || - (pVBInfo->LCDResInfo == Panel_1024x768x75)) { - pVBInfo->HDE = 1024; - pVBInfo->VDE = 768; - } else if ((pVBInfo->LCDResInfo == Panel_1280x1024) || - (pVBInfo->LCDResInfo == Panel_1280x1024x75)) { - pVBInfo->HDE = 1280; - pVBInfo->VDE = 1024; - } else if (pVBInfo->LCDResInfo == Panel_1400x1050) { - pVBInfo->HDE = 1400; - pVBInfo->VDE = 1050; - } else { - pVBInfo->HDE = 1600; - pVBInfo->VDE = 1200; - } -} - -static void XGI_ModCRT1Regs(unsigned short ModeIdIndex, - struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short i; - struct XGI_LVDSCRT1HDataStruct const *LCDPtr = NULL; - struct XGI_LVDSCRT1VDataStruct const *LCDPtr1 = NULL; - - if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { - LCDPtr = XGI_GetLcdPtr(xgifb_epllcd_crt1_h, ModeIdIndex, - pVBInfo); - - for (i = 0; i < 8; i++) - pVBInfo->TimingH.data[i] = LCDPtr[0].Reg[i]; - } - - XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension); - - if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { - LCDPtr1 = XGI_GetLcdPtr(xgifb_epllcd_crt1_v, ModeIdIndex, - pVBInfo); - for (i = 0; i < 7; i++) - pVBInfo->TimingV.data[i] = LCDPtr1[0].Reg[i]; - } - - XGI_SetCRT1Timing_V(ModeIdIndex, pVBInfo); -} - -static unsigned short XGI_GetLCDCapPtr(struct vb_device_info *pVBInfo) -{ - unsigned char tempal, tempah, tempbl, i; - - tempah = xgifb_reg_get(pVBInfo->P3d4, 0x36); - tempal = tempah & 0x0F; - tempah = tempah & 0xF0; - i = 0; - tempbl = pVBInfo->LCDCapList[i].LCD_ID; - - while (tempbl != 0xFF) { - if (tempbl & 0x80) { /* OEMUtil */ - tempal = tempah; - tempbl = tempbl & ~(0x80); - } - - if (tempal == tempbl) - break; - - i++; - - tempbl = pVBInfo->LCDCapList[i].LCD_ID; - } - - return i; -} - -static unsigned short XGI_GetLCDCapPtr1(struct vb_device_info *pVBInfo) -{ - unsigned short tempah, tempal, tempbl, i; - - tempal = pVBInfo->LCDResInfo; - tempah = pVBInfo->LCDTypeInfo; - - i = 0; - tempbl = pVBInfo->LCDCapList[i].LCD_ID; - - while (tempbl != 0xFF) { - if ((tempbl & 0x80) && (tempbl != 0x80)) { - tempal = tempah; - tempbl &= ~0x80; - } - - if (tempal == tempbl) - break; - - i++; - tempbl = pVBInfo->LCDCapList[i].LCD_ID; - } - - if (tempbl == 0xFF) { - pVBInfo->LCDResInfo = Panel_1024x768; - pVBInfo->LCDTypeInfo = 0; - i = 0; - } - - return i; -} - -static void XGI_GetLCDSync(unsigned short *HSyncWidth, - unsigned short *VSyncWidth, - struct vb_device_info *pVBInfo) -{ - unsigned short Index; - - Index = XGI_GetLCDCapPtr(pVBInfo); - *HSyncWidth = pVBInfo->LCDCapList[Index].LCD_HSyncWidth; - *VSyncWidth = pVBInfo->LCDCapList[Index].LCD_VSyncWidth; -} - -static void XGI_SetLVDSRegs(unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short tempbx, tempax, tempcx, tempdx, push1, push2, modeflag; - unsigned long temp, temp1, temp2, temp3, push3; - struct XGI330_LCDDataDesStruct2 const *LCDPtr1 = NULL; - - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - LCDPtr1 = XGI_GetLcdPtr(XGI_EPLLCDDesDataPtr, ModeIdIndex, pVBInfo); - - XGI_GetLCDSync(&tempax, &tempbx, pVBInfo); - push1 = tempbx; - push2 = tempax; - - /* GetLCDResInfo */ - if ((pVBInfo->LCDResInfo == Panel_1024x768) || - (pVBInfo->LCDResInfo == Panel_1024x768x75)) { - tempax = 1024; - tempbx = 768; - } else if ((pVBInfo->LCDResInfo == Panel_1280x1024) || - (pVBInfo->LCDResInfo == Panel_1280x1024x75)) { - tempax = 1280; - tempbx = 1024; - } else if (pVBInfo->LCDResInfo == Panel_1400x1050) { - tempax = 1400; - tempbx = 1050; - } else { - tempax = 1600; - tempbx = 1200; - } - - if (pVBInfo->LCDInfo & SetLCDtoNonExpanding) { - pVBInfo->HDE = tempax; - pVBInfo->VDE = tempbx; - pVBInfo->VGAHDE = tempax; - pVBInfo->VGAVDE = tempbx; - } - - tempax = pVBInfo->HT; - - tempbx = LCDPtr1->LCDHDES; - - tempcx = pVBInfo->HDE; - tempbx = tempbx & 0x0fff; - tempcx += tempbx; - - if (tempcx >= tempax) - tempcx -= tempax; - - xgifb_reg_set(pVBInfo->Part1Port, 0x1A, tempbx & 0x07); - - tempcx >>= 3; - tempbx >>= 3; - - xgifb_reg_set(pVBInfo->Part1Port, 0x16, - (unsigned short)(tempbx & 0xff)); - xgifb_reg_set(pVBInfo->Part1Port, 0x17, - (unsigned short)(tempcx & 0xff)); - - tempax = pVBInfo->HT; - - tempbx = LCDPtr1->LCDHRS; - - tempcx = push2; - - if (pVBInfo->LCDInfo & EnableScalingLCD) - tempcx = LCDPtr1->LCDHSync; - - tempcx += tempbx; - - if (tempcx >= tempax) - tempcx -= tempax; - - tempax = tempbx & 0x07; - tempax >>= 5; - tempcx >>= 3; - tempbx >>= 3; - - tempcx &= 0x1f; - tempax |= tempcx; - - xgifb_reg_set(pVBInfo->Part1Port, 0x15, tempax); - xgifb_reg_set(pVBInfo->Part1Port, 0x14, - (unsigned short)(tempbx & 0xff)); - - tempax = pVBInfo->VT; - tempbx = LCDPtr1->LCDVDES; - tempcx = pVBInfo->VDE; - - tempbx = tempbx & 0x0fff; - tempcx += tempbx; - if (tempcx >= tempax) - tempcx -= tempax; - - xgifb_reg_set(pVBInfo->Part1Port, 0x1b, - (unsigned short)(tempbx & 0xff)); - xgifb_reg_set(pVBInfo->Part1Port, 0x1c, - (unsigned short)(tempcx & 0xff)); - - tempbx = (tempbx >> 8) & 0x07; - tempcx = (tempcx >> 8) & 0x07; - - xgifb_reg_set(pVBInfo->Part1Port, 0x1d, - (unsigned short)((tempcx << 3) | tempbx)); - - tempax = pVBInfo->VT; - tempbx = LCDPtr1->LCDVRS; - - tempcx = push1; - - if (pVBInfo->LCDInfo & EnableScalingLCD) - tempcx = LCDPtr1->LCDVSync; - - tempcx += tempbx; - if (tempcx >= tempax) - tempcx -= tempax; - - xgifb_reg_set(pVBInfo->Part1Port, 0x18, - (unsigned short)(tempbx & 0xff)); - xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, ~0x0f, - (unsigned short)(tempcx & 0x0f)); - - tempax = ((tempbx >> 8) & 0x07) << 3; - - tempbx = pVBInfo->VGAVDE; - if (tempbx != pVBInfo->VDE) - tempax |= 0x40; - - if (pVBInfo->LCDInfo & XGI_EnableLVDSDDA) - tempax |= 0x40; - - xgifb_reg_and_or(pVBInfo->Part1Port, 0x1a, 0x07, tempax); - - tempbx = pVBInfo->VDE; - tempax = pVBInfo->VGAVDE; - - temp = tempax; /* 0430 ylshieh */ - temp1 = (temp << 18) / tempbx; - - tempdx = (unsigned short)((temp << 18) % tempbx); - - if (tempdx != 0) - temp1 += 1; - - temp2 = temp1; - push3 = temp2; - - xgifb_reg_set(pVBInfo->Part1Port, 0x37, (unsigned short)(temp2 & 0xff)); - xgifb_reg_set(pVBInfo->Part1Port, 0x36, (unsigned short)((temp2 >> 8) & 0xff)); - - tempbx = (unsigned short)(temp2 >> 16); - tempax = tempbx & 0x03; - - tempbx = pVBInfo->VGAVDE; - if (tempbx == pVBInfo->VDE) - tempax |= 0x04; - - xgifb_reg_set(pVBInfo->Part1Port, 0x35, tempax); - - if (pVBInfo->VBType & VB_XGI301C) { - temp2 = push3; - xgifb_reg_set(pVBInfo->Part4Port, - 0x3c, - (unsigned short)(temp2 & 0xff)); - xgifb_reg_set(pVBInfo->Part4Port, - 0x3b, - (unsigned short)((temp2 >> 8) & - 0xff)); - tempbx = (unsigned short)(temp2 >> 16); - xgifb_reg_and_or(pVBInfo->Part4Port, 0x3a, ~0xc0, - (unsigned short)((tempbx & 0xff) << 6)); - - tempcx = pVBInfo->VGAVDE; - if (tempcx == pVBInfo->VDE) - xgifb_reg_and_or(pVBInfo->Part4Port, 0x30, ~0x0c, 0x00); - else - xgifb_reg_and_or(pVBInfo->Part4Port, 0x30, ~0x0c, 0x08); - } - - tempcx = pVBInfo->VGAHDE; - tempbx = pVBInfo->HDE; - - temp1 = tempcx << 16; - - tempax = (unsigned short)(temp1 / tempbx); - - if ((tempbx & 0xffff) == (tempcx & 0xffff)) - tempax = 65535; - - temp3 = tempax; - temp1 = pVBInfo->VGAHDE << 16; - - temp1 /= temp3; - temp3 <<= 16; - temp1 -= 1; - - temp3 = (temp3 & 0xffff0000) + (temp1 & 0xffff); - - tempax = (unsigned short)(temp3 & 0xff); - xgifb_reg_set(pVBInfo->Part1Port, 0x1f, tempax); - - temp1 = pVBInfo->VGAVDE << 18; - temp1 = temp1 / push3; - tempbx = (unsigned short)(temp1 & 0xffff); - - if (pVBInfo->LCDResInfo == Panel_1024x768) - tempbx -= 1; - - tempax = ((tempbx >> 8) & 0xff) << 3; - tempax |= (unsigned short)((temp3 >> 8) & 0x07); - xgifb_reg_set(pVBInfo->Part1Port, 0x20, - (unsigned short)(tempax & 0xff)); - xgifb_reg_set(pVBInfo->Part1Port, 0x21, - (unsigned short)(tempbx & 0xff)); - - temp3 >>= 16; - - if (modeflag & HalfDCLK) - temp3 >>= 1; - - xgifb_reg_set(pVBInfo->Part1Port, 0x22, - (unsigned short)((temp3 >> 8) & 0xff)); - xgifb_reg_set(pVBInfo->Part1Port, 0x23, - (unsigned short)(temp3 & 0xff)); -} - -/* - * Function : XGI_GETLCDVCLKPtr - * Input : - * Output : al -> VCLK Index - * Description : - */ -static void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1, - struct vb_device_info *pVBInfo) -{ - unsigned short index; - - if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { - index = XGI_GetLCDCapPtr1(pVBInfo); - - if (pVBInfo->VBInfo & SetCRT2ToLCD) { /* LCDB */ - *di_0 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData1; - *di_1 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData2; - } else { /* LCDA */ - *di_0 = pVBInfo->LCDCapList[index].LCDA_VCLKData1; - *di_1 = pVBInfo->LCDCapList[index].LCDA_VCLKData2; - } - } -} - -static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex, - unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short index, modeflag; - unsigned char tempal; - - /* si+Ext_ResInfo */ - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - - if ((pVBInfo->SetFlag & ProgrammingCRT2) && - !(pVBInfo->LCDInfo & EnableScalingLCD)) { /* {LCDA/LCDB} */ - index = XGI_GetLCDCapPtr(pVBInfo); - tempal = pVBInfo->LCDCapList[index].LCD_VCLK; - - if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) - return tempal; - - /* {TV} */ - if (pVBInfo->VBType & - (VB_SIS301B | - VB_SIS302B | - VB_SIS301LV | - VB_SIS302LV | - VB_XGI301C)) { - if (pVBInfo->VBInfo & SetCRT2ToHiVision) { - tempal = TVCLKBASE_315 + HiTVVCLKDIV2; - if (!(pVBInfo->TVInfo & RPLLDIV2XO)) - tempal = TVCLKBASE_315 + HiTVVCLK; - if (pVBInfo->TVInfo & TVSimuMode) { - tempal = TVCLKBASE_315 + HiTVSimuVCLK; - if (!(modeflag & Charx8Dot)) - tempal = TVCLKBASE_315 + - HiTVTextVCLK; - } - return tempal; - } - - if (pVBInfo->TVInfo & TVSetYPbPr750p) - return XGI_YPbPr750pVCLK; - - if (pVBInfo->TVInfo & TVSetYPbPr525p) - return YPbPr525pVCLK; - - tempal = NTSC1024VCLK; - - if (!(pVBInfo->TVInfo & NTSC1024x768)) { - tempal = TVCLKBASE_315 + TVVCLKDIV2; - if (!(pVBInfo->TVInfo & RPLLDIV2XO)) - tempal = TVCLKBASE_315 + TVVCLK; - } - - if (pVBInfo->VBInfo & SetCRT2ToTV) - return tempal; - } - } /* {End of VB} */ - - inb((pVBInfo->P3ca + 0x02)); - return XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; -} - -static void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0, - unsigned char *di_1, struct vb_device_info *pVBInfo) -{ - if (pVBInfo->VBType & (VB_SIS301 | VB_SIS301B | VB_SIS302B - | VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) { - if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) && - (pVBInfo->SetFlag & ProgrammingCRT2)) { - *di_0 = XGI_VBVCLKData[tempal].Part4_A; - *di_1 = XGI_VBVCLKData[tempal].Part4_B; - } - } else { - *di_0 = XGI_VCLKData[tempal].SR2B; - *di_1 = XGI_VCLKData[tempal].SR2C; - } -} - -static void XGI_SetCRT2ECLK(unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned char di_0, di_1, tempal; - int i; - - tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeIdIndex, pVBInfo); - XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo); - XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo); - - for (i = 0; i < 4; i++) { - xgifb_reg_and_or(pVBInfo->P3d4, 0x31, ~0x30, - (unsigned short)(0x10 * i)); - if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) && - !(pVBInfo->VBInfo & SetInSlaveMode)) { - xgifb_reg_set(pVBInfo->P3c4, 0x2e, di_0); - xgifb_reg_set(pVBInfo->P3c4, 0x2f, di_1); - } else { - xgifb_reg_set(pVBInfo->P3c4, 0x2b, di_0); - xgifb_reg_set(pVBInfo->P3c4, 0x2c, di_1); - } - } -} - -static void XGI_UpdateModeInfo(struct vb_device_info *pVBInfo) -{ - unsigned short tempcl, tempch, temp, tempbl, tempax; - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) { - tempcl = 0; - tempch = 0; - temp = xgifb_reg_get(pVBInfo->P3c4, 0x01); - - if (!(temp & 0x20)) { - temp = xgifb_reg_get(pVBInfo->P3d4, 0x17); - if (temp & 0x80) { - temp = xgifb_reg_get(pVBInfo->P3d4, 0x53); - if (!(temp & 0x40)) - tempcl |= ActiveCRT1; - } - } - - temp = xgifb_reg_get(pVBInfo->Part1Port, 0x2e); - temp &= 0x0f; - - if (!(temp == 0x08)) { - /* Check ChannelA */ - tempax = xgifb_reg_get(pVBInfo->Part1Port, 0x13); - if (tempax & 0x04) - tempcl = tempcl | ActiveLCD; - - temp &= 0x05; - - if (!(tempcl & ActiveLCD)) { - if (temp == 0x01) - tempcl |= ActiveCRT2; - } - - if (temp == 0x04) - tempcl |= ActiveLCD; - - if (temp == 0x05) { - temp = xgifb_reg_get(pVBInfo->Part2Port, 0x00); - - if (!(temp & 0x08)) - tempch |= ActiveAVideo; - - if (!(temp & 0x04)) - tempch |= ActiveSVideo; - - if (temp & 0x02) - tempch |= ActiveSCART; - - if (pVBInfo->VBInfo & SetCRT2ToHiVision) { - if (temp & 0x01) - tempch |= ActiveHiTV; - } - - if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) { - temp = xgifb_reg_get( - pVBInfo->Part2Port, - 0x4d); - - if (temp & 0x10) - tempch |= ActiveYPbPr; - } - - if (tempch != 0) - tempcl |= ActiveTV; - } - } - - temp = xgifb_reg_get(pVBInfo->P3d4, 0x3d); - if (tempcl & ActiveLCD) { - if ((pVBInfo->SetFlag & ReserveTVOption)) { - if (temp & ActiveTV) - tempcl |= ActiveTV; - } - } - temp = tempcl; - tempbl = ~XGI_ModeSwitchStatus; - xgifb_reg_and_or(pVBInfo->P3d4, 0x3d, tempbl, temp); - - if (!(pVBInfo->SetFlag & ReserveTVOption)) - xgifb_reg_set(pVBInfo->P3d4, 0x3e, tempch); - } -} - -void XGI_GetVBType(struct vb_device_info *pVBInfo) -{ - unsigned short flag, tempbx, tempah; - - tempbx = VB_SIS302B; - flag = xgifb_reg_get(pVBInfo->Part4Port, 0x00); - if (flag == 0x02) - goto finish; - - tempbx = VB_SIS301; - flag = xgifb_reg_get(pVBInfo->Part4Port, 0x01); - if (flag < 0xB0) - goto finish; - - tempbx = VB_SIS301B; - if (flag < 0xC0) - goto bigger_than_0xB0; - - tempbx = VB_XGI301C; - if (flag < 0xD0) - goto bigger_than_0xB0; - - tempbx = VB_SIS301LV; - if (flag < 0xE0) - goto bigger_than_0xB0; - - tempbx = VB_SIS302LV; - tempah = xgifb_reg_get(pVBInfo->Part4Port, 0x39); - if (tempah != 0xFF) - tempbx = VB_XGI301C; - -bigger_than_0xB0: - if (tempbx & (VB_SIS301B | VB_SIS302B)) { - flag = xgifb_reg_get(pVBInfo->Part4Port, 0x23); - if (!(flag & 0x02)) - tempbx = tempbx | VB_NoLCD; - } - -finish: - pVBInfo->VBType = tempbx; -} - -static void XGI_GetVBInfo(unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short tempax, push, tempbx, temp, modeflag; - - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - pVBInfo->SetFlag = 0; - pVBInfo->ModeType = modeflag & ModeTypeMask; - tempbx = 0; - - if (!(pVBInfo->VBType & 0xFFFF)) - return; - - /* Check Display Device */ - temp = xgifb_reg_get(pVBInfo->P3d4, 0x30); - tempbx = tempbx | temp; - temp = xgifb_reg_get(pVBInfo->P3d4, 0x31); - push = temp; - push <<= 8; - tempax = temp << 8; - tempbx = tempbx | tempax; - temp = SetCRT2ToDualEdge | SetCRT2ToYPbPr525750 | XGI_SetCRT2ToLCDA - | SetInSlaveMode | DisableCRT2Display; - temp = 0xFFFF ^ temp; - tempbx &= temp; - - temp = xgifb_reg_get(pVBInfo->P3d4, 0x38); - - if (pVBInfo->VBType & (VB_SIS302B | VB_SIS301LV | VB_SIS302LV | - VB_XGI301C)) { - if (temp & EnableDualEdge) { - tempbx |= SetCRT2ToDualEdge; - if (temp & SetToLCDA) - tempbx |= XGI_SetCRT2ToLCDA; - } - } - - if (pVBInfo->VBType & (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) { - if (temp & SetYPbPr) { - /* shampoo add for new scratch */ - temp = xgifb_reg_get(pVBInfo->P3d4, 0x35); - temp &= YPbPrMode; - tempbx |= SetCRT2ToHiVision; - - if (temp != YPbPrMode1080i) { - tempbx &= ~SetCRT2ToHiVision; - tempbx |= SetCRT2ToYPbPr525750; - } - } - } - - tempax = push; /* restore CR31 */ - - temp = 0x09FC; - - if (!(tempbx & temp)) { - tempax |= DisableCRT2Display; - tempbx = 0; - } - - if (!(pVBInfo->VBType & VB_NoLCD)) { - if (tempbx & XGI_SetCRT2ToLCDA) { - if (tempbx & SetSimuScanMode) - tempbx &= (~(SetCRT2ToLCD | SetCRT2ToRAMDAC | - SwitchCRT2)); - else - tempbx &= (~(SetCRT2ToLCD | SetCRT2ToRAMDAC | - SetCRT2ToTV | SwitchCRT2)); - } - } - - /* shampoo add */ - /* for driver abnormal */ - if (!(tempbx & (SwitchCRT2 | SetSimuScanMode))) { - if (tempbx & SetCRT2ToRAMDAC) { - tempbx &= (0xFF00 | SetCRT2ToRAMDAC | - SwitchCRT2 | SetSimuScanMode); - tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750)); - } - } - - if (!(pVBInfo->VBType & VB_NoLCD)) { - if (tempbx & SetCRT2ToLCD) { - tempbx &= (0xFF00 | SetCRT2ToLCD | SwitchCRT2 | - SetSimuScanMode); - tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750)); - } - } - - if (tempbx & SetCRT2ToSCART) { - tempbx &= (0xFF00 | SetCRT2ToSCART | SwitchCRT2 | - SetSimuScanMode); - tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750)); - } - - if (tempbx & SetCRT2ToYPbPr525750) - tempbx &= (0xFF00 | SwitchCRT2 | SetSimuScanMode); - - if (tempbx & SetCRT2ToHiVision) - tempbx &= (0xFF00 | SetCRT2ToHiVision | SwitchCRT2 | - SetSimuScanMode); - - if (tempax & DisableCRT2Display) { /* Set Display Device Info */ - if (!(tempbx & (SwitchCRT2 | SetSimuScanMode))) - tempbx = DisableCRT2Display; - } - - if (!(tempbx & DisableCRT2Display)) { - if (!(tempbx & DriverMode) || !(modeflag & CRT2Mode)) { - if (!(tempbx & XGI_SetCRT2ToLCDA)) - tempbx |= (SetInSlaveMode | SetSimuScanMode); - } - - /* LCD+TV can't support in slave mode - * (Force LCDA+TV->LCDB) - */ - if ((tempbx & SetInSlaveMode) && (tempbx & XGI_SetCRT2ToLCDA)) { - tempbx ^= (SetCRT2ToLCD | XGI_SetCRT2ToLCDA | - SetCRT2ToDualEdge); - pVBInfo->SetFlag |= ReserveTVOption; - } - } - - pVBInfo->VBInfo = tempbx; -} - -static void XGI_GetTVInfo(unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short tempbx = 0, resinfo = 0, modeflag, index1; - - if (pVBInfo->VBInfo & SetCRT2ToTV) { - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - - tempbx = xgifb_reg_get(pVBInfo->P3d4, 0x35); - if (tempbx & TVSetPAL) { - tempbx &= (SetCHTVOverScan | - TVSetPALM | - TVSetPALN | - TVSetPAL); - if (tempbx & TVSetPALM) - /* set to NTSC if PAL-M */ - tempbx &= ~TVSetPAL; - } else { - tempbx &= (SetCHTVOverScan | - TVSetNTSCJ | - TVSetPAL); - } - - if (pVBInfo->VBInfo & SetCRT2ToSCART) - tempbx |= TVSetPAL; - - if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) { - index1 = xgifb_reg_get(pVBInfo->P3d4, 0x35); - index1 &= YPbPrMode; - - if (index1 == YPbPrMode525i) - tempbx |= TVSetYPbPr525i; - - if (index1 == YPbPrMode525p) - tempbx = tempbx | TVSetYPbPr525p; - if (index1 == YPbPrMode750p) - tempbx = tempbx | TVSetYPbPr750p; - } - - if (pVBInfo->VBInfo & SetCRT2ToHiVision) - tempbx = tempbx | TVSetHiVision | TVSetPAL; - - if ((pVBInfo->VBInfo & SetInSlaveMode) && - (!(pVBInfo->VBInfo & SetNotSimuMode))) - tempbx |= TVSimuMode; - - if (!(tempbx & TVSetPAL) && (modeflag > 13) && (resinfo == 8)) { - /* NTSC 1024x768, */ - tempbx |= NTSC1024x768; - } - - tempbx |= RPLLDIV2XO; - - if (pVBInfo->VBInfo & SetCRT2ToHiVision) { - if (pVBInfo->VBInfo & SetInSlaveMode) - tempbx &= (~RPLLDIV2XO); - } else if (tempbx & (TVSetYPbPr525p | TVSetYPbPr750p)) { - tempbx &= (~RPLLDIV2XO); - } else if (!(pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | - VB_SIS301LV | VB_SIS302LV | - VB_XGI301C))) { - if (tempbx & TVSimuMode) - tempbx &= (~RPLLDIV2XO); - } - } - pVBInfo->TVInfo = tempbx; -} - -static unsigned char XGI_GetLCDInfo(unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short temp, tempax, tempbx, resinfo = 0, LCDIdIndex; - - pVBInfo->LCDResInfo = 0; - pVBInfo->LCDTypeInfo = 0; - pVBInfo->LCDInfo = 0; - - /* si+Ext_ResInfo */ - resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - temp = xgifb_reg_get(pVBInfo->P3d4, 0x36); /* Get LCD Res.Info */ - tempbx = temp & 0x0F; - - if (tempbx == 0) - tempbx = Panel_1024x768; /* default */ - - /* LCD75 */ - if ((tempbx == Panel_1024x768) || (tempbx == Panel_1280x1024)) { - if (pVBInfo->VBInfo & DriverMode) { - tempax = xgifb_reg_get(pVBInfo->P3d4, 0x33); - if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) - tempax &= 0x0F; - else - tempax >>= 4; - - if ((resinfo == 6) || (resinfo == 9)) { - if (tempax >= 3) - tempbx |= PanelRef75Hz; - } else if ((resinfo == 7) || (resinfo == 8)) { - if (tempax >= 4) - tempbx |= PanelRef75Hz; - } - } - } - - pVBInfo->LCDResInfo = tempbx; - - /* End of LCD75 */ - - if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))) - return 0; - - tempbx = 0; - - temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); - - temp &= (ScalingLCD | LCDNonExpanding | LCDSyncBit | SetPWDEnable); - - tempbx |= temp; - - LCDIdIndex = XGI_GetLCDCapPtr1(pVBInfo); - - tempax = pVBInfo->LCDCapList[LCDIdIndex].LCD_Capability; - - if (((pVBInfo->VBType & VB_SIS302LV) || - (pVBInfo->VBType & VB_XGI301C)) && (tempax & XGI_LCDDualLink)) - tempbx |= SetLCDDualLink; - - if ((pVBInfo->LCDResInfo == Panel_1400x1050) && - (pVBInfo->VBInfo & SetCRT2ToLCD) && (resinfo == 9) && - !(tempbx & EnableScalingLCD)) - /* - * set to center in 1280x1024 LCDB - * for Panel_1400x1050 - */ - tempbx |= SetLCDtoNonExpanding; - - if (pVBInfo->VBInfo & SetInSlaveMode) { - if (pVBInfo->VBInfo & SetNotSimuMode) - tempbx |= XGI_LCDVESATiming; - } else { - tempbx |= XGI_LCDVESATiming; - } - - pVBInfo->LCDInfo = tempbx; - - return 1; -} - -unsigned char XGI_SearchModeID(unsigned short ModeNo, - unsigned short *ModeIdIndex) -{ - for (*ModeIdIndex = 0;; (*ModeIdIndex)++) { - if (XGI330_EModeIDTable[*ModeIdIndex].Ext_ModeID == ModeNo) - break; - if (XGI330_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF) - return 0; - } - - return 1; -} - -static unsigned char XG21GPIODataTransfer(unsigned char ujDate) -{ - unsigned char ujRet = 0; - unsigned char i = 0; - - for (i = 0; i < 8; i++) { - ujRet <<= 1; - ujRet |= (ujDate >> i) & 1; - } - - return ujRet; -} - -/* - * output - * bl[5] : LVDS signal - * bl[1] : LVDS backlight - * bl[0] : LVDS VDD - */ -static unsigned char XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo) -{ - unsigned char CR4A, temp; - - CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); - xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x23); /* enable GPIO write */ - - temp = xgifb_reg_get(pVBInfo->P3d4, 0x48); - - temp = XG21GPIODataTransfer(temp); - temp &= 0x23; - xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A); - return temp; -} - -/* - * output - * bl[5] : LVDS signal - * bl[1] : LVDS backlight - * bl[0] : LVDS VDD - */ -static unsigned char XGI_XG27GetPSCValue(struct vb_device_info *pVBInfo) -{ - unsigned char CR4A, CRB4, temp; - - CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); - xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x0C); /* enable GPIO write */ - - temp = xgifb_reg_get(pVBInfo->P3d4, 0x48); - - temp &= 0x0C; - temp >>= 2; - xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A); - CRB4 = xgifb_reg_get(pVBInfo->P3d4, 0xB4); - temp |= ((CRB4 & 0x04) << 3); - return temp; -} - -/* - * input - * bl[5] : 1;LVDS signal on - * bl[1] : 1;LVDS backlight on - * bl[0] : 1:LVDS VDD on - * bh: 100000b : clear bit 5, to set bit5 - * 000010b : clear bit 1, to set bit1 - * 000001b : clear bit 0, to set bit0 - */ -static void XGI_XG21BLSignalVDD(unsigned short tempbh, unsigned short tempbl, - struct vb_device_info *pVBInfo) -{ - unsigned char CR4A, temp; - - CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); - tempbh &= 0x23; - tempbl &= 0x23; - xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */ - - if (tempbh & 0x20) { - temp = (tempbl >> 4) & 0x02; - - /* CR B4[1] */ - xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp); - } - - temp = xgifb_reg_get(pVBInfo->P3d4, 0x48); - - temp = XG21GPIODataTransfer(temp); - temp &= ~tempbh; - temp |= tempbl; - xgifb_reg_set(pVBInfo->P3d4, 0x48, temp); -} - -static void XGI_XG27BLSignalVDD(unsigned short tempbh, unsigned short tempbl, - struct vb_device_info *pVBInfo) -{ - unsigned char CR4A, temp; - unsigned short tempbh0, tempbl0; - - tempbh0 = tempbh; - tempbl0 = tempbl; - tempbh0 &= 0x20; - tempbl0 &= 0x20; - tempbh0 >>= 3; - tempbl0 >>= 3; - - if (tempbh & 0x20) { - temp = (tempbl >> 4) & 0x02; - - /* CR B4[1] */ - xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp); - } - xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~tempbh0, tempbl0); - - CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); - tempbh &= 0x03; - tempbl &= 0x03; - tempbh <<= 2; - tempbl <<= 2; /* GPIOC,GPIOD */ - xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */ - xgifb_reg_and_or(pVBInfo->P3d4, 0x48, ~tempbh, tempbl); -} - -static void XGI_DisplayOn(struct xgifb_video_info *xgifb_info, - struct xgi_hw_device_info *pXGIHWDE, - struct vb_device_info *pVBInfo) -{ - xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xDF, 0x00); - if (pXGIHWDE->jChipType == XG21) { - if (pVBInfo->IF_DEF_LVDS == 1) { - if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x1)) { - /* LVDS VDD on */ - XGI_XG21BLSignalVDD(0x01, 0x01, pVBInfo); - mdelay(xgifb_info->lvds_data.PSC_S2); - } - if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x20)) - /* LVDS signal on */ - XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo); - mdelay(xgifb_info->lvds_data.PSC_S3); - /* LVDS backlight on */ - XGI_XG21BLSignalVDD(0x02, 0x02, pVBInfo); - } else { - /* DVO/DVI signal on */ - XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo); - } - } - - if (pXGIHWDE->jChipType == XG27) { - if (pVBInfo->IF_DEF_LVDS == 1) { - if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x1)) { - /* LVDS VDD on */ - XGI_XG27BLSignalVDD(0x01, 0x01, pVBInfo); - mdelay(xgifb_info->lvds_data.PSC_S2); - } - if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x20)) - /* LVDS signal on */ - XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo); - mdelay(xgifb_info->lvds_data.PSC_S3); - /* LVDS backlight on */ - XGI_XG27BLSignalVDD(0x02, 0x02, pVBInfo); - } else { - /* DVO/DVI signal on */ - XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo); - } - } -} - -void XGI_DisplayOff(struct xgifb_video_info *xgifb_info, - struct xgi_hw_device_info *pXGIHWDE, - struct vb_device_info *pVBInfo) -{ - if (pXGIHWDE->jChipType == XG21) { - if (pVBInfo->IF_DEF_LVDS == 1) { - /* LVDS backlight off */ - XGI_XG21BLSignalVDD(0x02, 0x00, pVBInfo); - mdelay(xgifb_info->lvds_data.PSC_S3); - } else { - /* DVO/DVI signal off */ - XGI_XG21BLSignalVDD(0x20, 0x00, pVBInfo); - } - } - - if (pXGIHWDE->jChipType == XG27) { - if ((XGI_XG27GetPSCValue(pVBInfo) & 0x2)) { - /* LVDS backlight off */ - XGI_XG27BLSignalVDD(0x02, 0x00, pVBInfo); - mdelay(xgifb_info->lvds_data.PSC_S3); - } - - if (pVBInfo->IF_DEF_LVDS == 0) { - /* DVO/DVI signal off */ - XGI_XG27BLSignalVDD(0x20, 0x00, pVBInfo); - } - } - - xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xDF, 0x20); -} - -static void XGI_WaitDisply(struct vb_device_info *pVBInfo) -{ - while ((inb(pVBInfo->P3da) & 0x01)) - break; - - while (!(inb(pVBInfo->P3da) & 0x01)) - break; -} - -static void XGI_AutoThreshold(struct vb_device_info *pVBInfo) -{ - xgifb_reg_or(pVBInfo->Part1Port, 0x01, 0x40); -} - -static void XGI_SaveCRT2Info(unsigned short ModeNo, - struct vb_device_info *pVBInfo) -{ - unsigned short temp1, temp2; - - /* reserve CR34 for CRT1 Mode No */ - xgifb_reg_set(pVBInfo->P3d4, 0x34, ModeNo); - temp1 = (pVBInfo->VBInfo & SetInSlaveMode) >> 8; - temp2 = ~(SetInSlaveMode >> 8); - xgifb_reg_and_or(pVBInfo->P3d4, 0x31, temp2, temp1); -} - -static void XGI_GetCRT2ResInfo(unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short xres, yres, modeflag, resindex; - - resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */ - yres = XGI330_ModeResInfo[resindex].VTotal; /* yres->bx */ - /* si+St_ModeFlag */ - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - - if (modeflag & HalfDCLK) - xres *= 2; - - if (modeflag & DoubleScanMode) - yres *= 2; - - if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) - goto exit; - - if (pVBInfo->LCDResInfo == Panel_1600x1200) { - if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) { - if (yres == 1024) - yres = 1056; - } - } - - if (pVBInfo->LCDResInfo == Panel_1280x1024) { - if (yres == 400) - yres = 405; - else if (yres == 350) - yres = 360; - - if (pVBInfo->LCDInfo & XGI_LCDVESATiming) { - if (yres == 360) - yres = 375; - } - } - - if (pVBInfo->LCDResInfo == Panel_1024x768) { - if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) { - if (!(pVBInfo->LCDInfo & LCDNonExpanding)) { - if (yres == 350) - yres = 357; - else if (yres == 400) - yres = 420; - else if (yres == 480) - yres = 525; - } - } - } - - if (xres == 720) - xres = 640; - -exit: - pVBInfo->VGAHDE = xres; - pVBInfo->HDE = xres; - pVBInfo->VGAVDE = yres; - pVBInfo->VDE = yres; -} - -static unsigned char XGI_IsLCDDualLink(struct vb_device_info *pVBInfo) -{ - if ((pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) && - (pVBInfo->LCDInfo & SetLCDDualLink)) /* shampoo0129 */ - return 1; - - return 0; -} - -static void XGI_GetRAMDAC2DATA(unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short tempax, tempbx, temp1, temp2, modeflag = 0, tempcx, - CRT1Index; - - pVBInfo->RVBHCMAX = 1; - pVBInfo->RVBHCFACT = 1; - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - CRT1Index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - CRT1Index &= IndexMask; - temp1 = (unsigned short)XGI_CRT1Table[CRT1Index].CR[0]; - temp2 = (unsigned short)XGI_CRT1Table[CRT1Index].CR[5]; - tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8); - tempbx = (unsigned short)XGI_CRT1Table[CRT1Index].CR[8]; - tempcx = (unsigned short)XGI_CRT1Table[CRT1Index].CR[14] << 8; - tempcx &= 0x0100; - tempcx <<= 2; - tempbx |= tempcx; - temp1 = (unsigned short)XGI_CRT1Table[CRT1Index].CR[9]; - - if (temp1 & 0x01) - tempbx |= 0x0100; - - if (temp1 & 0x20) - tempbx |= 0x0200; - tempax += 5; - - if (modeflag & Charx8Dot) - tempax *= 8; - else - tempax *= 9; - - pVBInfo->VGAHT = tempax; - pVBInfo->HT = tempax; - tempbx++; - pVBInfo->VGAVT = tempbx; - pVBInfo->VT = tempbx; -} - -static void XGI_GetCRT2Data(unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short tempax = 0, tempbx = 0, modeflag, resinfo; - - struct SiS_LCDData const *LCDPtr = NULL; - - /* si+Ext_ResInfo */ - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - pVBInfo->NewFlickerMode = 0; - pVBInfo->RVBHRS = 50; - - if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) { - XGI_GetRAMDAC2DATA(ModeIdIndex, RefreshRateTableIndex, pVBInfo); - return; - } - - if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { - LCDPtr = XGI_GetLcdPtr(XGI_LCDDataTable, ModeIdIndex, - pVBInfo); - - pVBInfo->RVBHCMAX = LCDPtr->RVBHCMAX; - pVBInfo->RVBHCFACT = LCDPtr->RVBHCFACT; - pVBInfo->VGAHT = LCDPtr->VGAHT; - pVBInfo->VGAVT = LCDPtr->VGAVT; - pVBInfo->HT = LCDPtr->LCDHT; - pVBInfo->VT = LCDPtr->LCDVT; - - if (pVBInfo->LCDResInfo == Panel_1024x768) { - tempax = 1024; - tempbx = 768; - - if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) { - if (pVBInfo->VGAVDE == 357) - tempbx = 527; - else if (pVBInfo->VGAVDE == 420) - tempbx = 620; - else if (pVBInfo->VGAVDE == 525) - tempbx = 775; - else if (pVBInfo->VGAVDE == 600) - tempbx = 775; - } - } else if (pVBInfo->LCDResInfo == Panel_1024x768x75) { - tempax = 1024; - tempbx = 768; - } else if (pVBInfo->LCDResInfo == Panel_1280x1024) { - tempax = 1280; - if (pVBInfo->VGAVDE == 360) - tempbx = 768; - else if (pVBInfo->VGAVDE == 375) - tempbx = 800; - else if (pVBInfo->VGAVDE == 405) - tempbx = 864; - else - tempbx = 1024; - } else if (pVBInfo->LCDResInfo == Panel_1280x1024x75) { - tempax = 1280; - tempbx = 1024; - } else if (pVBInfo->LCDResInfo == Panel_1280x960) { - tempax = 1280; - if (pVBInfo->VGAVDE == 350) - tempbx = 700; - else if (pVBInfo->VGAVDE == 400) - tempbx = 800; - else if (pVBInfo->VGAVDE == 1024) - tempbx = 960; - else - tempbx = 960; - } else if (pVBInfo->LCDResInfo == Panel_1400x1050) { - tempax = 1400; - tempbx = 1050; - - if (pVBInfo->VGAVDE == 1024) { - tempax = 1280; - tempbx = 1024; - } - } else if (pVBInfo->LCDResInfo == Panel_1600x1200) { - tempax = 1600; - tempbx = 1200; /* alan 10/14/2003 */ - if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) { - if (pVBInfo->VGAVDE == 350) - tempbx = 875; - else if (pVBInfo->VGAVDE == 400) - tempbx = 1000; - } - } - - if (pVBInfo->LCDInfo & LCDNonExpanding) { - tempax = pVBInfo->VGAHDE; - tempbx = pVBInfo->VGAVDE; - } - - pVBInfo->HDE = tempax; - pVBInfo->VDE = tempbx; - return; - } - - if (pVBInfo->VBInfo & (SetCRT2ToTV)) { - struct SiS_TVData const *TVPtr; - - TVPtr = XGI_GetTVPtr(ModeIdIndex, RefreshRateTableIndex, - pVBInfo); - - pVBInfo->RVBHCMAX = TVPtr->RVBHCMAX; - pVBInfo->RVBHCFACT = TVPtr->RVBHCFACT; - pVBInfo->VGAHT = TVPtr->VGAHT; - pVBInfo->VGAVT = TVPtr->VGAVT; - pVBInfo->HDE = TVPtr->TVHDE; - pVBInfo->VDE = TVPtr->TVVDE; - pVBInfo->RVBHRS = TVPtr->RVBHRS; - pVBInfo->NewFlickerMode = TVPtr->FlickerMode; - - if (pVBInfo->VBInfo & SetCRT2ToHiVision) { - if (resinfo == 0x08) - pVBInfo->NewFlickerMode = 0x40; - else if (resinfo == 0x09) - pVBInfo->NewFlickerMode = 0x40; - else if (resinfo == 0x12) - pVBInfo->NewFlickerMode = 0x40; - - if (pVBInfo->VGAVDE == 350) - pVBInfo->TVInfo |= TVSimuMode; - - tempax = ExtHiTVHT; - tempbx = ExtHiTVVT; - - if (pVBInfo->VBInfo & SetInSlaveMode) { - if (pVBInfo->TVInfo & TVSimuMode) { - tempax = StHiTVHT; - tempbx = StHiTVVT; - - if (!(modeflag & Charx8Dot)) { - tempax = StHiTextTVHT; - tempbx = StHiTextTVVT; - } - } - } - } else if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) { - if (pVBInfo->TVInfo & TVSetYPbPr750p) { - tempax = YPbPrTV750pHT; /* Ext750pTVHT */ - tempbx = YPbPrTV750pVT; /* Ext750pTVVT */ - } - - if (pVBInfo->TVInfo & TVSetYPbPr525p) { - tempax = YPbPrTV525pHT; /* Ext525pTVHT */ - tempbx = YPbPrTV525pVT; /* Ext525pTVVT */ - } else if (pVBInfo->TVInfo & TVSetYPbPr525i) { - tempax = YPbPrTV525iHT; /* Ext525iTVHT */ - tempbx = YPbPrTV525iVT; /* Ext525iTVVT */ - if (pVBInfo->TVInfo & NTSC1024x768) - tempax = NTSC1024x768HT; - } - } else { - tempax = PALHT; - tempbx = PALVT; - if (!(pVBInfo->TVInfo & TVSetPAL)) { - tempax = NTSCHT; - tempbx = NTSCVT; - if (pVBInfo->TVInfo & NTSC1024x768) - tempax = NTSC1024x768HT; - } - } - - pVBInfo->HT = tempax; - pVBInfo->VT = tempbx; - } -} - -static void XGI_SetCRT2VCLK(unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned char di_0, di_1, tempal; - - tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeIdIndex, pVBInfo); - XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo); - XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo); - - if (pVBInfo->VBType & VB_SIS301) { /* shampoo 0129 */ - /* 301 */ - xgifb_reg_set(pVBInfo->Part4Port, 0x0A, 0x10); - xgifb_reg_set(pVBInfo->Part4Port, 0x0B, di_1); - xgifb_reg_set(pVBInfo->Part4Port, 0x0A, di_0); - } else { /* 301b/302b/301lv/302lv */ - xgifb_reg_set(pVBInfo->Part4Port, 0x0A, di_0); - xgifb_reg_set(pVBInfo->Part4Port, 0x0B, di_1); - } - - xgifb_reg_set(pVBInfo->Part4Port, 0x00, 0x12); - - if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) - xgifb_reg_or(pVBInfo->Part4Port, 0x12, 0x28); - else - xgifb_reg_or(pVBInfo->Part4Port, 0x12, 0x08); -} - -static unsigned short XGI_GetColorDepth(unsigned short ModeIdIndex) -{ - unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 }; - short index; - unsigned short modeflag; - - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - index = (modeflag & ModeTypeMask) - ModeEGA; - - if (index < 0) - index = 0; - - return ColorDepth[index]; -} - -static unsigned short XGI_GetOffset(unsigned short ModeNo, - unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex) -{ - unsigned short temp, colordepth, modeinfo, index, infoflag, - ColorDepth[] = { 0x01, 0x02, 0x04 }; - - modeinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeInfo; - infoflag = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; - - index = (modeinfo >> 8) & 0xFF; - - temp = XGI330_ScreenOffset[index]; - - if (infoflag & InterlaceMode) - temp <<= 1; - - colordepth = XGI_GetColorDepth(ModeIdIndex); - - if ((ModeNo >= 0x7C) && (ModeNo <= 0x7E)) { - temp = ModeNo - 0x7C; - colordepth = ColorDepth[temp]; - temp = 0x6B; - if (infoflag & InterlaceMode) - temp <<= 1; - } - return temp * colordepth; -} - -static void XGI_SetCRT2Offset(unsigned short ModeNo, - unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short offset; - unsigned char temp; - - if (pVBInfo->VBInfo & SetInSlaveMode) - return; - - offset = XGI_GetOffset(ModeNo, ModeIdIndex, RefreshRateTableIndex); - temp = (unsigned char)(offset & 0xFF); - xgifb_reg_set(pVBInfo->Part1Port, 0x07, temp); - temp = (unsigned char)((offset & 0xFF00) >> 8); - xgifb_reg_set(pVBInfo->Part1Port, 0x09, temp); - temp = (unsigned char)(((offset >> 3) & 0xFF) + 1); - xgifb_reg_set(pVBInfo->Part1Port, 0x03, temp); -} - -static void XGI_SetCRT2FIFO(struct vb_device_info *pVBInfo) -{ - /* threshold high ,disable auto threshold */ - xgifb_reg_set(pVBInfo->Part1Port, 0x01, 0x3B); - /* threshold low default 04h */ - xgifb_reg_and_or(pVBInfo->Part1Port, 0x02, ~(0x3F), 0x04); -} - -static void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - u8 tempcx; - - XGI_SetCRT2Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); - XGI_SetCRT2FIFO(pVBInfo); - - for (tempcx = 4; tempcx < 7; tempcx++) - xgifb_reg_set(pVBInfo->Part1Port, tempcx, 0x0); - - xgifb_reg_set(pVBInfo->Part1Port, 0x50, 0x00); - xgifb_reg_set(pVBInfo->Part1Port, 0x02, 0x44); /* temp 0206 */ -} - -static void XGI_SetGroup1(unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short temp = 0, tempax = 0, tempbx = 0, tempcx = 0, - pushbx = 0, CRT1Index, modeflag; - - CRT1Index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - CRT1Index &= IndexMask; - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - - /* bainy change table name */ - if (modeflag & HalfDCLK) { - /* BTVGA2HT 0x08,0x09 */ - temp = (pVBInfo->VGAHT / 2 - 1) & 0x0FF; - xgifb_reg_set(pVBInfo->Part1Port, 0x08, temp); - temp = (((pVBInfo->VGAHT / 2 - 1) & 0xFF00) >> 8) << 4; - xgifb_reg_and_or(pVBInfo->Part1Port, 0x09, ~0x0F0, temp); - /* BTVGA2HDEE 0x0A,0x0C */ - temp = (pVBInfo->VGAHDE / 2 + 16) & 0x0FF; - xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp); - tempcx = ((pVBInfo->VGAHT - pVBInfo->VGAHDE) / 2) >> 2; - pushbx = pVBInfo->VGAHDE / 2 + 16; - tempcx >>= 1; - tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */ - tempcx += tempbx; - - if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) { - tempbx = XGI_CRT1Table[CRT1Index].CR[4]; - tempbx |= ((XGI_CRT1Table[CRT1Index].CR[14] & - 0xC0) << 2); - tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */ - tempcx = XGI_CRT1Table[CRT1Index].CR[5]; - tempcx &= 0x1F; - temp = XGI_CRT1Table[CRT1Index].CR[15]; - temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */ - tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */ - } - - tempbx += 4; - tempcx += 4; - - if (tempcx > (pVBInfo->VGAHT / 2)) - tempcx = pVBInfo->VGAHT / 2; - - temp = tempbx & 0x00FF; - - xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp); - } else { - temp = (pVBInfo->VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */ - xgifb_reg_set(pVBInfo->Part1Port, 0x08, temp); - temp = (((pVBInfo->VGAHT - 1) & 0xFF00) >> 8) << 4; - xgifb_reg_and_or(pVBInfo->Part1Port, 0x09, ~0x0F0, temp); - /* BTVGA2HDEE 0x0A,0x0C */ - temp = (pVBInfo->VGAHDE + 16) & 0x0FF; - xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp); - tempcx = (pVBInfo->VGAHT - pVBInfo->VGAHDE) >> 2; /* cx */ - pushbx = pVBInfo->VGAHDE + 16; - tempcx >>= 1; - tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */ - tempcx += tempbx; - - if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) { - tempbx = XGI_CRT1Table[CRT1Index].CR[3]; - tempbx |= ((XGI_CRT1Table[CRT1Index].CR[5] & - 0xC0) << 2); - tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */ - tempcx = XGI_CRT1Table[CRT1Index].CR[4]; - tempcx &= 0x1F; - temp = XGI_CRT1Table[CRT1Index].CR[6]; - temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */ - tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */ - tempbx += 16; - tempcx += 16; - } - - if (tempcx > pVBInfo->VGAHT) - tempcx = pVBInfo->VGAHT; - - temp = tempbx & 0x00FF; - xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp); - } - - tempax = (tempax & 0x00FF) | (tempbx & 0xFF00); - tempbx = pushbx; - tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4); - tempax |= (tempbx & 0xFF00); - temp = (tempax & 0xFF00) >> 8; - xgifb_reg_set(pVBInfo->Part1Port, 0x0C, temp); - temp = tempcx & 0x00FF; - xgifb_reg_set(pVBInfo->Part1Port, 0x0D, temp); - tempcx = pVBInfo->VGAVT - 1; - temp = tempcx & 0x00FF; - - xgifb_reg_set(pVBInfo->Part1Port, 0x0E, temp); - tempbx = pVBInfo->VGAVDE - 1; - temp = tempbx & 0x00FF; - xgifb_reg_set(pVBInfo->Part1Port, 0x0F, temp); - temp = ((tempbx & 0xFF00) << 3) >> 8; - temp |= ((tempcx & 0xFF00) >> 8); - xgifb_reg_set(pVBInfo->Part1Port, 0x12, temp); - - /* BTVGA2VRS 0x10,0x11 */ - tempbx = (pVBInfo->VGAVT + pVBInfo->VGAVDE) >> 1; - /* BTVGA2VRE 0x11 */ - tempcx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) >> 4) + tempbx + 1; - - if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) { - tempbx = XGI_CRT1Table[CRT1Index].CR[10]; - temp = XGI_CRT1Table[CRT1Index].CR[9]; - - if (temp & 0x04) - tempbx |= 0x0100; - - if (temp & 0x080) - tempbx |= 0x0200; - - temp = XGI_CRT1Table[CRT1Index].CR[14]; - - if (temp & 0x08) - tempbx |= 0x0400; - - temp = XGI_CRT1Table[CRT1Index].CR[11]; - tempcx = (tempcx & 0xFF00) | (temp & 0x00FF); - } - - temp = tempbx & 0x00FF; - xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp); - temp = ((tempbx & 0xFF00) >> 8) << 4; - temp = (tempcx & 0x000F) | (temp); - xgifb_reg_set(pVBInfo->Part1Port, 0x11, temp); - tempax = 0; - - if (modeflag & DoubleScanMode) - tempax |= 0x80; - - if (modeflag & HalfDCLK) - tempax |= 0x40; - - xgifb_reg_and_or(pVBInfo->Part1Port, 0x2C, ~0x0C0, tempax); -} - -static unsigned short XGI_GetVGAHT2(struct vb_device_info *pVBInfo) -{ - unsigned long tempax, tempbx; - - tempbx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) * pVBInfo->RVBHCMAX) - & 0xFFFF; - tempax = (pVBInfo->VT - pVBInfo->VDE) * pVBInfo->RVBHCFACT; - tempax = (tempax * pVBInfo->HT) / tempbx; - - return (unsigned short)tempax; -} - -static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short push1, push2, tempax, tempbx = 0, tempcx, temp, resinfo, - modeflag; - - /* si+Ext_ResInfo */ - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - - if (!(pVBInfo->VBInfo & SetInSlaveMode)) - return; - - temp = 0xFF; /* set MAX HT */ - xgifb_reg_set(pVBInfo->Part1Port, 0x03, temp); - tempcx = 0x08; - - if (pVBInfo->VBType & (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) - modeflag |= Charx8Dot; - - tempax = pVBInfo->VGAHDE; /* 0x04 Horizontal Display End */ - - if (modeflag & HalfDCLK) - tempax >>= 1; - - tempax = (tempax / tempcx) - 1; - tempbx |= ((tempax & 0x00FF) << 8); - temp = tempax & 0x00FF; - xgifb_reg_set(pVBInfo->Part1Port, 0x04, temp); - - temp = (tempbx & 0xFF00) >> 8; - - if (pVBInfo->VBInfo & SetCRT2ToTV) { - if (!(pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C))) - temp += 2; - - if ((pVBInfo->VBInfo & SetCRT2ToHiVision) && - !(pVBInfo->VBType & VB_SIS301LV) && (resinfo == 7)) - temp -= 2; - } - - /* 0x05 Horizontal Display Start */ - xgifb_reg_set(pVBInfo->Part1Port, 0x05, temp); - /* 0x06 Horizontal Blank end */ - xgifb_reg_set(pVBInfo->Part1Port, 0x06, 0x03); - - if (!(pVBInfo->VBInfo & DisableCRT2Display)) { /* 030226 bainy */ - if (pVBInfo->VBInfo & SetCRT2ToTV) - tempax = pVBInfo->VGAHT; - else - tempax = XGI_GetVGAHT2(pVBInfo); - } - - if (tempax >= pVBInfo->VGAHT) - tempax = pVBInfo->VGAHT; - - if (modeflag & HalfDCLK) - tempax >>= 1; - - tempax = (tempax / tempcx) - 5; - tempcx = tempax; /* 20030401 0x07 horizontal Retrace Start */ - if (pVBInfo->VBInfo & SetCRT2ToHiVision) { - temp = (tempbx & 0x00FF) - 1; - if (!(modeflag & HalfDCLK)) { - temp -= 6; - if (pVBInfo->TVInfo & TVSimuMode) { - temp -= 4; - temp -= 10; - } - } - } else { - tempbx = (tempbx & 0xFF00) >> 8; - tempcx = (tempcx + tempbx) >> 1; - temp = (tempcx & 0x00FF) + 2; - - if (pVBInfo->VBInfo & SetCRT2ToTV) { - temp -= 1; - if (!(modeflag & HalfDCLK)) { - if ((modeflag & Charx8Dot)) { - temp += 4; - if (pVBInfo->VGAHDE >= 800) - temp -= 6; - } - } - } else if (!(modeflag & HalfDCLK)) { - temp -= 4; - if (pVBInfo->LCDResInfo != Panel_1280x960 && - pVBInfo->VGAHDE >= 800) { - temp -= 7; - if (pVBInfo->VGAHDE >= 1280 && - pVBInfo->LCDResInfo != Panel_1280x960 && - (pVBInfo->LCDInfo & LCDNonExpanding)) - temp += 28; - } - } - } - - /* 0x07 Horizontal Retrace Start */ - xgifb_reg_set(pVBInfo->Part1Port, 0x07, temp); - /* 0x08 Horizontal Retrace End */ - xgifb_reg_set(pVBInfo->Part1Port, 0x08, 0); - - if (pVBInfo->VBInfo & SetCRT2ToTV) { - if (pVBInfo->TVInfo & TVSimuMode) { - if (ModeNo == 0x50) { - if (pVBInfo->TVInfo == SetNTSCTV) { - xgifb_reg_set(pVBInfo->Part1Port, - 0x07, 0x30); - xgifb_reg_set(pVBInfo->Part1Port, - 0x08, 0x03); - } else { - xgifb_reg_set(pVBInfo->Part1Port, - 0x07, 0x2f); - xgifb_reg_set(pVBInfo->Part1Port, - 0x08, 0x02); - } - } - } - } - - xgifb_reg_set(pVBInfo->Part1Port, 0x18, 0x03); /* 0x18 SR0B */ - xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0xF0, 0x00); - xgifb_reg_set(pVBInfo->Part1Port, 0x09, 0xFF); /* 0x09 Set Max VT */ - - tempbx = pVBInfo->VGAVT; - push1 = tempbx; - tempcx = 0x121; - tempbx = pVBInfo->VGAVDE; /* 0x0E Vertical Display End */ - - if (tempbx == 357) - tempbx = 350; - if (tempbx == 360) - tempbx = 350; - if (tempbx == 375) - tempbx = 350; - if (tempbx == 405) - tempbx = 400; - if (tempbx == 525) - tempbx = 480; - - push2 = tempbx; - - if (pVBInfo->VBInfo & SetCRT2ToLCD) { - if (pVBInfo->LCDResInfo == Panel_1024x768) { - if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) { - if (tempbx == 350) - tempbx += 5; - if (tempbx == 480) - tempbx += 5; - } - } - } - tempbx--; - tempbx--; - temp = tempbx & 0x00FF; - /* 0x10 vertical Blank Start */ - xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp); - tempbx = push2; - tempbx--; - temp = tempbx & 0x00FF; - xgifb_reg_set(pVBInfo->Part1Port, 0x0E, temp); - - if (tempbx & 0x0100) - tempcx |= 0x0002; - - tempax = 0x000B; - - if (modeflag & DoubleScanMode) - tempax |= 0x08000; - - if (tempbx & 0x0200) - tempcx |= 0x0040; - - temp = (tempax & 0xFF00) >> 8; - xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp); - - if (tempbx & 0x0400) - tempcx |= 0x0600; - - /* 0x11 Vertical Blank End */ - xgifb_reg_set(pVBInfo->Part1Port, 0x11, 0x00); - - tempax = push1; - tempax -= tempbx; /* 0x0C Vertical Retrace Start */ - tempax >>= 2; - push1 = tempax; /* push ax */ - - if (resinfo != 0x09) { - tempax <<= 1; - tempbx += tempax; - } - - if (pVBInfo->VBInfo & SetCRT2ToHiVision) { - if ((pVBInfo->VBType & VB_SIS301LV) && - !(pVBInfo->TVInfo & TVSetHiVision)) { - if ((pVBInfo->TVInfo & TVSimuMode) && - (pVBInfo->TVInfo & TVSetPAL)) { - if (!(pVBInfo->VBType & VB_SIS301LV) || - !(pVBInfo->TVInfo & - (TVSetYPbPr525p | - TVSetYPbPr750p | - TVSetHiVision))) - tempbx += 40; - } - } else { - tempbx -= 10; - } - } else if (pVBInfo->TVInfo & TVSimuMode) { - if (pVBInfo->TVInfo & TVSetPAL) { - if (pVBInfo->VBType & VB_SIS301LV) { - if (!(pVBInfo->TVInfo & - (TVSetYPbPr525p | - TVSetYPbPr750p | - TVSetHiVision))) - tempbx += 40; - } else { - tempbx += 40; - } - } - } - tempax = push1; - tempax >>= 2; - tempax++; - tempax += tempbx; - push1 = tempax; /* push ax */ - - if ((pVBInfo->TVInfo & TVSetPAL)) { - if (tempbx <= 513) { - if (tempax >= 513) - tempbx = 513; - } - } - - temp = tempbx & 0x00FF; - xgifb_reg_set(pVBInfo->Part1Port, 0x0C, temp); - tempbx--; - temp = tempbx & 0x00FF; - xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp); - - if (tempbx & 0x0100) - tempcx |= 0x0008; - - if (tempbx & 0x0200) - xgifb_reg_and_or(pVBInfo->Part1Port, 0x0B, 0x0FF, 0x20); - - tempbx++; - - if (tempbx & 0x0100) - tempcx |= 0x0004; - - if (tempbx & 0x0200) - tempcx |= 0x0080; - - if (tempbx & 0x0400) - tempcx |= 0x0C00; - - tempbx = push1; /* pop ax */ - temp = tempbx & 0x00FF; - temp &= 0x0F; - /* 0x0D vertical Retrace End */ - xgifb_reg_set(pVBInfo->Part1Port, 0x0D, temp); - - if (tempbx & 0x0010) - tempcx |= 0x2000; - - temp = tempcx & 0x00FF; - xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp); /* 0x0A CR07 */ - temp = (tempcx & 0x0FF00) >> 8; - xgifb_reg_set(pVBInfo->Part1Port, 0x17, temp); /* 0x17 SR0A */ - tempax = modeflag; - temp = (tempax & 0xFF00) >> 8; - - temp = (temp >> 1) & 0x09; - - if (pVBInfo->VBType & (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) - temp |= 0x01; - - xgifb_reg_set(pVBInfo->Part1Port, 0x16, temp); /* 0x16 SR01 */ - xgifb_reg_set(pVBInfo->Part1Port, 0x0F, 0); /* 0x0F CR14 */ - xgifb_reg_set(pVBInfo->Part1Port, 0x12, 0); /* 0x12 CR17 */ - - if (pVBInfo->LCDInfo & LCDRGB18Bit) - temp = 0x80; - else - temp = 0x00; - - xgifb_reg_set(pVBInfo->Part1Port, 0x1A, temp); /* 0x1A SR0E */ -} - -static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short i, j, tempax, tempbx, tempcx, temp, push1, push2, - modeflag; - unsigned char const *TimingPoint; - - unsigned long longtemp, tempeax, tempebx, temp2, tempecx; - - /* si+Ext_ResInfo */ - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - - tempax = 0; - - if (!(pVBInfo->VBInfo & SetCRT2ToAVIDEO)) - tempax |= 0x0800; - - if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO)) - tempax |= 0x0400; - - if (pVBInfo->VBInfo & SetCRT2ToSCART) - tempax |= 0x0200; - - if (!(pVBInfo->TVInfo & TVSetPAL)) - tempax |= 0x1000; - - if (pVBInfo->VBInfo & SetCRT2ToHiVision) - tempax |= 0x0100; - - if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p)) - tempax &= 0xfe00; - - tempax = (tempax & 0xff00) >> 8; - - xgifb_reg_set(pVBInfo->Part2Port, 0x0, tempax); - TimingPoint = XGI330_NTSCTiming; - - if (pVBInfo->TVInfo & TVSetPAL) - TimingPoint = XGI330_PALTiming; - - if (pVBInfo->VBInfo & SetCRT2ToHiVision) { - TimingPoint = XGI330_HiTVExtTiming; - - if (pVBInfo->VBInfo & SetInSlaveMode) - TimingPoint = XGI330_HiTVSt2Timing; - - if (pVBInfo->SetFlag & TVSimuMode) - TimingPoint = XGI330_HiTVSt1Timing; - - if (!(modeflag & Charx8Dot)) - TimingPoint = XGI330_HiTVTextTiming; - } - - if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) { - if (pVBInfo->TVInfo & TVSetYPbPr525i) - TimingPoint = XGI330_YPbPr525iTiming; - - if (pVBInfo->TVInfo & TVSetYPbPr525p) - TimingPoint = XGI330_YPbPr525pTiming; - - if (pVBInfo->TVInfo & TVSetYPbPr750p) - TimingPoint = XGI330_YPbPr750pTiming; - } - - for (i = 0x01, j = 0; i <= 0x2D; i++, j++) - xgifb_reg_set(pVBInfo->Part2Port, i, TimingPoint[j]); - - for (i = 0x39; i <= 0x45; i++, j++) - /* di->temp2[j] */ - xgifb_reg_set(pVBInfo->Part2Port, i, TimingPoint[j]); - - if (pVBInfo->VBInfo & SetCRT2ToTV) - xgifb_reg_and_or(pVBInfo->Part2Port, 0x3A, 0x1F, 0x00); - - temp = pVBInfo->NewFlickerMode; - temp &= 0x80; - xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0xFF, temp); - - if (pVBInfo->TVInfo & TVSetPAL) - tempax = 520; - else - tempax = 440; - - if (pVBInfo->VDE <= tempax) { - tempax -= pVBInfo->VDE; - tempax >>= 2; - tempax = (tempax & 0x00FF) | ((tempax & 0x00FF) << 8); - push1 = tempax; - temp = (tempax & 0xFF00) >> 8; - temp += (unsigned short)TimingPoint[0]; - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) { - if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO - | SetCRT2ToSVIDEO | SetCRT2ToSCART - | SetCRT2ToYPbPr525750)) { - tempcx = pVBInfo->VGAHDE; - if (tempcx >= 1024) { - temp = 0x17; /* NTSC */ - if (pVBInfo->TVInfo & TVSetPAL) - temp = 0x19; /* PAL */ - } - } - } - - xgifb_reg_set(pVBInfo->Part2Port, 0x01, temp); - tempax = push1; - temp = (tempax & 0xFF00) >> 8; - temp += TimingPoint[1]; - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) { - if ((pVBInfo->VBInfo & (SetCRT2ToAVIDEO - | SetCRT2ToSVIDEO | SetCRT2ToSCART - | SetCRT2ToYPbPr525750))) { - tempcx = pVBInfo->VGAHDE; - if (tempcx >= 1024) { - temp = 0x1D; /* NTSC */ - if (pVBInfo->TVInfo & TVSetPAL) - temp = 0x52; /* PAL */ - } - } - } - xgifb_reg_set(pVBInfo->Part2Port, 0x02, temp); - } - - /* 301b */ - tempcx = pVBInfo->HT; - - if (XGI_IsLCDDualLink(pVBInfo)) - tempcx >>= 1; - - tempcx -= 2; - temp = tempcx & 0x00FF; - xgifb_reg_set(pVBInfo->Part2Port, 0x1B, temp); - - temp = (tempcx & 0xFF00) >> 8; - xgifb_reg_and_or(pVBInfo->Part2Port, 0x1D, ~0x0F, temp); - - tempcx = pVBInfo->HT >> 1; - push1 = tempcx; /* push cx */ - tempcx += 7; - - if (pVBInfo->VBInfo & SetCRT2ToHiVision) - tempcx -= 4; - - temp = tempcx & 0x00FF; - temp <<= 4; - xgifb_reg_and_or(pVBInfo->Part2Port, 0x22, 0x0F, temp); - - tempbx = TimingPoint[j] | ((TimingPoint[j + 1]) << 8); - tempbx += tempcx; - push2 = tempbx; - temp = tempbx & 0x00FF; - xgifb_reg_set(pVBInfo->Part2Port, 0x24, temp); - temp = (tempbx & 0xFF00) >> 8; - temp <<= 4; - xgifb_reg_and_or(pVBInfo->Part2Port, 0x25, 0x0F, temp); - - tempbx = push2; - tempbx = tempbx + 8; - if (pVBInfo->VBInfo & SetCRT2ToHiVision) { - tempbx = tempbx - 4; - tempcx = tempbx; - } - - temp = (tempbx & 0x00FF) << 4; - xgifb_reg_and_or(pVBInfo->Part2Port, 0x29, 0x0F, temp); - - j += 2; - tempcx += (TimingPoint[j] | ((TimingPoint[j + 1]) << 8)); - temp = tempcx & 0x00FF; - xgifb_reg_set(pVBInfo->Part2Port, 0x27, temp); - temp = ((tempcx & 0xFF00) >> 8) << 4; - xgifb_reg_and_or(pVBInfo->Part2Port, 0x28, 0x0F, temp); - - tempcx += 8; - if (pVBInfo->VBInfo & SetCRT2ToHiVision) - tempcx -= 4; - - temp = tempcx & 0xFF; - temp <<= 4; - xgifb_reg_and_or(pVBInfo->Part2Port, 0x2A, 0x0F, temp); - - tempcx = push1; /* pop cx */ - j += 2; - temp = TimingPoint[j] | ((TimingPoint[j + 1]) << 8); - tempcx -= temp; - temp = tempcx & 0x00FF; - temp <<= 4; - xgifb_reg_and_or(pVBInfo->Part2Port, 0x2D, 0x0F, temp); - - tempcx -= 11; - - if (!(pVBInfo->VBInfo & SetCRT2ToTV)) { - tempax = XGI_GetVGAHT2(pVBInfo); - tempcx = tempax - 1; - } - temp = tempcx & 0x00FF; - xgifb_reg_set(pVBInfo->Part2Port, 0x2E, temp); - - tempbx = pVBInfo->VDE; - - if (pVBInfo->VGAVDE == 360) - tempbx = 746; - if (pVBInfo->VGAVDE == 375) - tempbx = 746; - if (pVBInfo->VGAVDE == 405) - tempbx = 853; - - if (pVBInfo->VBInfo & SetCRT2ToTV) { - if (pVBInfo->VBType & - (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) { - if (!(pVBInfo->TVInfo & - (TVSetYPbPr525p | TVSetYPbPr750p))) - tempbx >>= 1; - } else { - tempbx >>= 1; - } - } - - tempbx -= 2; - temp = tempbx & 0x00FF; - - if (pVBInfo->VBInfo & SetCRT2ToHiVision) { - if (pVBInfo->VBType & VB_SIS301LV) { - if (pVBInfo->TVInfo & TVSetHiVision) { - if (pVBInfo->VBInfo & SetInSlaveMode) { - if (ModeNo == 0x2f) - temp += 1; - } - } - } else if (pVBInfo->VBInfo & SetInSlaveMode) { - if (ModeNo == 0x2f) - temp += 1; - } - } - - xgifb_reg_set(pVBInfo->Part2Port, 0x2F, temp); - - temp = (tempcx & 0xFF00) >> 8; - temp |= ((tempbx & 0xFF00) >> 8) << 6; - - if (!(pVBInfo->VBInfo & SetCRT2ToHiVision)) { - if (pVBInfo->VBType & VB_SIS301LV) { - if (pVBInfo->TVInfo & TVSetHiVision) { - temp |= 0x10; - - if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO)) - temp |= 0x20; - } - } else { - temp |= 0x10; - if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO)) - temp |= 0x20; - } - } - - xgifb_reg_set(pVBInfo->Part2Port, 0x30, temp); - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) { /* TV gatingno */ - tempbx = pVBInfo->VDE; - tempcx = tempbx - 2; - - if (pVBInfo->VBInfo & SetCRT2ToTV) { - if (!(pVBInfo->TVInfo & (TVSetYPbPr525p - | TVSetYPbPr750p))) - tempbx >>= 1; - } - - if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) { - temp = 0; - if (tempcx & 0x0400) - temp |= 0x20; - - if (tempbx & 0x0400) - temp |= 0x40; - - xgifb_reg_set(pVBInfo->Part4Port, 0x10, temp); - } - - temp = (((tempbx - 3) & 0x0300) >> 8) << 5; - xgifb_reg_set(pVBInfo->Part2Port, 0x46, temp); - temp = (tempbx - 3) & 0x00FF; - xgifb_reg_set(pVBInfo->Part2Port, 0x47, temp); - } - - tempbx = tempbx & 0x00FF; - - if (!(modeflag & HalfDCLK)) { - tempcx = pVBInfo->VGAHDE; - if (tempcx >= pVBInfo->HDE) { - tempbx |= 0x2000; - tempax &= 0x00FF; - } - } - - tempcx = 0x0101; - - if (pVBInfo->VBInfo & SetCRT2ToTV) { /* 301b */ - if (pVBInfo->VGAHDE >= 1024) { - tempcx = 0x1920; - if (pVBInfo->VGAHDE >= 1280) { - tempcx = 0x1420; - tempbx = tempbx & 0xDFFF; - } - } - } - - if (!(tempbx & 0x2000)) { - if (modeflag & HalfDCLK) - tempcx = (tempcx & 0xFF00) | ((tempcx & 0x00FF) << 1); - - push1 = tempbx; - tempeax = pVBInfo->VGAHDE; - tempebx = (tempcx & 0xFF00) >> 8; - longtemp = tempeax * tempebx; - tempecx = tempcx & 0x00FF; - longtemp = longtemp / tempecx; - - /* 301b */ - tempecx = 8 * 1024; - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) { - tempecx = tempecx * 8; - } - - longtemp = longtemp * tempecx; - tempecx = pVBInfo->HDE; - temp2 = longtemp % tempecx; - tempeax = longtemp / tempecx; - if (temp2 != 0) - tempeax += 1; - - tempax = (unsigned short)tempeax; - - /* 301b */ - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) { - tempcx = ((tempax & 0xFF00) >> 5) >> 8; - } - /* end 301b */ - - tempbx = push1; - tempbx = (unsigned short)(((tempeax & 0x0000FF00) & 0x1F00) - | (tempbx & 0x00FF)); - tempax = (unsigned short)(((tempeax & 0x000000FF) << 8) - | (tempax & 0x00FF)); - temp = (tempax & 0xFF00) >> 8; - } else { - temp = (tempax & 0x00FF) >> 8; - } - - xgifb_reg_set(pVBInfo->Part2Port, 0x44, temp); - temp = (tempbx & 0xFF00) >> 8; - xgifb_reg_and_or(pVBInfo->Part2Port, 0x45, ~0x03F, temp); - temp = tempcx & 0x00FF; - - if (tempbx & 0x2000) - temp = 0; - - if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) - temp |= 0x18; - - xgifb_reg_and_or(pVBInfo->Part2Port, 0x46, ~0x1F, temp); - if (pVBInfo->TVInfo & TVSetPAL) { - tempbx = 0x0382; - tempcx = 0x007e; - } else { - tempbx = 0x0369; - tempcx = 0x0061; - } - - temp = tempbx & 0x00FF; - xgifb_reg_set(pVBInfo->Part2Port, 0x4b, temp); - temp = tempcx & 0x00FF; - xgifb_reg_set(pVBInfo->Part2Port, 0x4c, temp); - - temp = ((tempcx & 0xFF00) >> 8) & 0x03; - temp <<= 2; - temp |= ((tempbx & 0xFF00) >> 8) & 0x03; - - if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) { - temp |= 0x10; - - if (pVBInfo->TVInfo & TVSetYPbPr525p) - temp |= 0x20; - - if (pVBInfo->TVInfo & TVSetYPbPr750p) - temp |= 0x60; - } - - xgifb_reg_set(pVBInfo->Part2Port, 0x4d, temp); - temp = xgifb_reg_get(pVBInfo->Part2Port, 0x43); /* 301b change */ - xgifb_reg_set(pVBInfo->Part2Port, 0x43, (unsigned short)(temp - 3)); - - if (!(pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p))) { - if (pVBInfo->TVInfo & NTSC1024x768) { - TimingPoint = XGI_NTSC1024AdjTime; - for (i = 0x1c, j = 0; i <= 0x30; i++, j++) { - xgifb_reg_set(pVBInfo->Part2Port, i, - TimingPoint[j]); - } - xgifb_reg_set(pVBInfo->Part2Port, 0x43, 0x72); - } - } - - /* Modify for 301C PALM Support */ - if (pVBInfo->VBType & VB_XGI301C) { - if (pVBInfo->TVInfo & TVSetPALM) - xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x08, - 0x08); /* PALM Mode */ - } - - if (pVBInfo->TVInfo & TVSetPALM) { - tempax = xgifb_reg_get(pVBInfo->Part2Port, 0x01); - tempax--; - xgifb_reg_and(pVBInfo->Part2Port, 0x01, tempax); - - xgifb_reg_and(pVBInfo->Part2Port, 0x00, 0xEF); - } - - if (pVBInfo->VBInfo & SetCRT2ToHiVision) { - if (!(pVBInfo->VBInfo & SetInSlaveMode)) - xgifb_reg_set(pVBInfo->Part2Port, 0x0B, 0x00); - } -} - -static void XGI_SetLCDRegs(unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short pushbx, tempax, tempbx, tempcx, temp, tempah, - tempbh, tempch; - - struct XGI_LCDDesStruct const *LCDBDesPtr = NULL; - - /* si+Ext_ResInfo */ - if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) - return; - - tempbx = pVBInfo->HDE; /* RHACTE=HDE-1 */ - - if (XGI_IsLCDDualLink(pVBInfo)) - tempbx >>= 1; - - tempbx -= 1; - temp = tempbx & 0x00FF; - xgifb_reg_set(pVBInfo->Part2Port, 0x2C, temp); - temp = (tempbx & 0xFF00) >> 8; - temp <<= 4; - xgifb_reg_and_or(pVBInfo->Part2Port, 0x2B, 0x0F, temp); - temp = 0x01; - - xgifb_reg_set(pVBInfo->Part2Port, 0x0B, temp); - tempbx = pVBInfo->VDE; /* RTVACTEO=(VDE-1)&0xFF */ - tempbx--; - temp = tempbx & 0x00FF; - xgifb_reg_set(pVBInfo->Part2Port, 0x03, temp); - temp = ((tempbx & 0xFF00) >> 8) & 0x07; - xgifb_reg_and_or(pVBInfo->Part2Port, 0x0C, ~0x07, temp); - - tempcx = pVBInfo->VT - 1; - temp = tempcx & 0x00FF; /* RVTVT=VT-1 */ - xgifb_reg_set(pVBInfo->Part2Port, 0x19, temp); - temp = (tempcx & 0xFF00) >> 8; - temp <<= 5; - xgifb_reg_set(pVBInfo->Part2Port, 0x1A, temp); - xgifb_reg_and_or(pVBInfo->Part2Port, 0x09, 0xF0, 0x00); - xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0xF0, 0x00); - xgifb_reg_and_or(pVBInfo->Part2Port, 0x17, 0xFB, 0x00); - xgifb_reg_and_or(pVBInfo->Part2Port, 0x18, 0xDF, 0x00); - - /* Customized LCDB Does not add */ - if ((pVBInfo->VBType & VB_SIS301LV) || (pVBInfo->VBType & VB_SIS302LV)) - LCDBDesPtr = XGI_GetLcdPtr(xgifb_lcddldes, ModeIdIndex, - pVBInfo); - else - LCDBDesPtr = XGI_GetLcdPtr(XGI_LCDDesDataTable, ModeIdIndex, - pVBInfo); - - tempah = pVBInfo->LCDResInfo; - tempah &= PanelResInfo; - - if ((tempah == Panel_1024x768) || (tempah == Panel_1024x768x75)) { - tempbx = 1024; - tempcx = 768; - } else if ((tempah == Panel_1280x1024) || - (tempah == Panel_1280x1024x75)) { - tempbx = 1280; - tempcx = 1024; - } else if (tempah == Panel_1400x1050) { - tempbx = 1400; - tempcx = 1050; - } else { - tempbx = 1600; - tempcx = 1200; - } - - if (pVBInfo->LCDInfo & EnableScalingLCD) { - tempbx = pVBInfo->HDE; - tempcx = pVBInfo->VDE; - } - - pushbx = tempbx; - tempax = pVBInfo->VT; - pVBInfo->LCDHDES = LCDBDesPtr->LCDHDES; - pVBInfo->LCDHRS = LCDBDesPtr->LCDHRS; - pVBInfo->LCDVDES = LCDBDesPtr->LCDVDES; - pVBInfo->LCDVRS = LCDBDesPtr->LCDVRS; - tempbx = pVBInfo->LCDVDES; - tempcx += tempbx; - - if (tempcx >= tempax) - tempcx -= tempax; /* lcdvdes */ - - temp = tempbx & 0x00FF; /* RVEQ1EQ=lcdvdes */ - xgifb_reg_set(pVBInfo->Part2Port, 0x05, temp); - temp = tempcx & 0x00FF; - xgifb_reg_set(pVBInfo->Part2Port, 0x06, temp); - tempch = ((tempcx & 0xFF00) >> 8) & 0x07; - tempbh = ((tempbx & 0xFF00) >> 8) & 0x07; - tempah = tempch; - tempah <<= 3; - tempah |= tempbh; - xgifb_reg_set(pVBInfo->Part2Port, 0x02, tempah); - - /* getlcdsync() */ - XGI_GetLCDSync(&tempax, &tempbx, pVBInfo); - tempcx = tempbx; - tempax = pVBInfo->VT; - tempbx = pVBInfo->LCDVRS; - - tempcx += tempbx; - if (tempcx >= tempax) - tempcx -= tempax; - - temp = tempbx & 0x00FF; /* RTVACTEE=lcdvrs */ - xgifb_reg_set(pVBInfo->Part2Port, 0x04, temp); - temp = (tempbx & 0xFF00) >> 8; - temp <<= 4; - temp |= (tempcx & 0x000F); - xgifb_reg_set(pVBInfo->Part2Port, 0x01, temp); - tempcx = pushbx; - tempax = pVBInfo->HT; - tempbx = pVBInfo->LCDHDES; - tempbx &= 0x0FFF; - - if (XGI_IsLCDDualLink(pVBInfo)) { - tempax >>= 1; - tempbx >>= 1; - tempcx >>= 1; - } - - if (pVBInfo->VBType & VB_SIS302LV) - tempbx += 1; - - if (pVBInfo->VBType & VB_XGI301C) /* tap4 */ - tempbx += 1; - - tempcx += tempbx; - - if (tempcx >= tempax) - tempcx -= tempax; - - temp = tempbx & 0x00FF; - xgifb_reg_set(pVBInfo->Part2Port, 0x1F, temp); /* RHBLKE=lcdhdes */ - temp = ((tempbx & 0xFF00) >> 8) << 4; - xgifb_reg_set(pVBInfo->Part2Port, 0x20, temp); - temp = tempcx & 0x00FF; - xgifb_reg_set(pVBInfo->Part2Port, 0x23, temp); /* RHEQPLE=lcdhdee */ - temp = (tempcx & 0xFF00) >> 8; - xgifb_reg_set(pVBInfo->Part2Port, 0x25, temp); - - XGI_GetLCDSync(&tempax, &tempbx, pVBInfo); - tempcx = tempax; - tempax = pVBInfo->HT; - tempbx = pVBInfo->LCDHRS; - if (XGI_IsLCDDualLink(pVBInfo)) { - tempax >>= 1; - tempbx >>= 1; - tempcx >>= 1; - } - - if (pVBInfo->VBType & VB_SIS302LV) - tempbx += 1; - - tempcx += tempbx; - - if (tempcx >= tempax) - tempcx -= tempax; - - temp = tempbx & 0x00FF; /* RHBURSTS=lcdhrs */ - xgifb_reg_set(pVBInfo->Part2Port, 0x1C, temp); - - temp = (tempbx & 0xFF00) >> 8; - temp <<= 4; - xgifb_reg_and_or(pVBInfo->Part2Port, 0x1D, ~0x0F0, temp); - temp = tempcx & 0x00FF; /* RHSYEXP2S=lcdhre */ - xgifb_reg_set(pVBInfo->Part2Port, 0x21, temp); - - if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) { - if (pVBInfo->VGAVDE == 525) { - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B - | VB_SIS301LV | VB_SIS302LV - | VB_XGI301C)) - temp = 0xC6; - else - temp = 0xC4; - - xgifb_reg_set(pVBInfo->Part2Port, 0x2f, temp); - xgifb_reg_set(pVBInfo->Part2Port, 0x30, 0xB3); - } - - if (pVBInfo->VGAVDE == 420) { - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B - | VB_SIS301LV | VB_SIS302LV - | VB_XGI301C)) - temp = 0x4F; - else - temp = 0x4E; - xgifb_reg_set(pVBInfo->Part2Port, 0x2f, temp); - } - } -} - -/* - * Function : XGI_GetTap4Ptr - * Input : - * Output : di -> Tap4 Reg. Setting Pointer - * Description : - */ -static struct XGI301C_Tap4TimingStruct const -*XGI_GetTap4Ptr(unsigned short tempcx, struct vb_device_info *pVBInfo) -{ - unsigned short tempax, tempbx, i; - struct XGI301C_Tap4TimingStruct const *Tap4TimingPtr; - - if (tempcx == 0) { - tempax = pVBInfo->VGAHDE; - tempbx = pVBInfo->HDE; - } else { - tempax = pVBInfo->VGAVDE; - tempbx = pVBInfo->VDE; - } - - if (tempax <= tempbx) - return &xgifb_tap4_timing[0]; - Tap4TimingPtr = xgifb_ntsc_525_tap4_timing; /* NTSC */ - - if (pVBInfo->TVInfo & TVSetPAL) - Tap4TimingPtr = PALTap4Timing; - - if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) { - if ((pVBInfo->TVInfo & TVSetYPbPr525i) || - (pVBInfo->TVInfo & TVSetYPbPr525p)) - Tap4TimingPtr = xgifb_ntsc_525_tap4_timing; - if (pVBInfo->TVInfo & TVSetYPbPr750p) - Tap4TimingPtr = YPbPr750pTap4Timing; - } - - if (pVBInfo->VBInfo & SetCRT2ToHiVision) - Tap4TimingPtr = xgifb_tap4_timing; - - i = 0; - while (Tap4TimingPtr[i].DE != 0xFFFF) { - if (Tap4TimingPtr[i].DE == tempax) - break; - i++; - } - return &Tap4TimingPtr[i]; -} - -static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo) -{ - unsigned short i, j; - struct XGI301C_Tap4TimingStruct const *Tap4TimingPtr; - - if (!(pVBInfo->VBType & VB_XGI301C)) - return; - - Tap4TimingPtr = XGI_GetTap4Ptr(0, pVBInfo); /* Set Horizontal Scaling */ - for (i = 0x80, j = 0; i <= 0xBF; i++, j++) - xgifb_reg_set(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]); - - if ((pVBInfo->VBInfo & SetCRT2ToTV) && - !(pVBInfo->VBInfo & SetCRT2ToHiVision)) { - /* Set Vertical Scaling */ - Tap4TimingPtr = XGI_GetTap4Ptr(1, pVBInfo); - for (i = 0xC0, j = 0; i < 0xFF; i++, j++) - xgifb_reg_set(pVBInfo->Part2Port, - i, - Tap4TimingPtr->Reg[j]); - } - - if ((pVBInfo->VBInfo & SetCRT2ToTV) && - !(pVBInfo->VBInfo & SetCRT2ToHiVision)) - /* Enable V.Scaling */ - xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x14, 0x04); - else - /* Enable H.Scaling */ - xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x14, 0x10); -} - -static void XGI_SetGroup3(unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short i; - unsigned char const *tempdi; - unsigned short modeflag; - - /* si+Ext_ResInfo */ - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - - xgifb_reg_set(pVBInfo->Part3Port, 0x00, 0x00); - if (pVBInfo->TVInfo & TVSetPAL) { - xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xFA); - xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xC8); - } else { - xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xF5); - xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xB7); - } - - if (!(pVBInfo->VBInfo & SetCRT2ToTV)) - return; - - if (pVBInfo->TVInfo & TVSetPALM) { - xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xFA); - xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xC8); - xgifb_reg_set(pVBInfo->Part3Port, 0x3D, 0xA8); - } - - if ((pVBInfo->VBInfo & SetCRT2ToHiVision) || (pVBInfo->VBInfo - & SetCRT2ToYPbPr525750)) { - if (pVBInfo->TVInfo & TVSetYPbPr525i) - return; - - tempdi = XGI330_HiTVGroup3Data; - if (pVBInfo->SetFlag & TVSimuMode) { - tempdi = XGI330_HiTVGroup3Simu; - if (!(modeflag & Charx8Dot)) - tempdi = XGI330_HiTVGroup3Text; - } - - if (pVBInfo->TVInfo & TVSetYPbPr525p) - tempdi = XGI330_Ren525pGroup3; - - if (pVBInfo->TVInfo & TVSetYPbPr750p) - tempdi = XGI330_Ren750pGroup3; - - for (i = 0; i <= 0x3E; i++) - xgifb_reg_set(pVBInfo->Part3Port, i, tempdi[i]); - - if (pVBInfo->VBType & VB_XGI301C) { /* Marcovision */ - if (pVBInfo->TVInfo & TVSetYPbPr525p) - xgifb_reg_set(pVBInfo->Part3Port, 0x28, 0x3f); - } - } -} - -static void XGI_SetGroup4(unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short tempax, tempcx, tempbx, modeflag, temp, temp2; - - unsigned long tempebx, tempeax, templong; - - /* si+Ext_ResInfo */ - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - temp = pVBInfo->RVBHCFACT; - xgifb_reg_set(pVBInfo->Part4Port, 0x13, temp); - - tempbx = pVBInfo->RVBHCMAX; - temp = tempbx & 0x00FF; - xgifb_reg_set(pVBInfo->Part4Port, 0x14, temp); - temp2 = ((tempbx & 0xFF00) >> 8) << 7; - tempcx = pVBInfo->VGAHT - 1; - temp = tempcx & 0x00FF; - xgifb_reg_set(pVBInfo->Part4Port, 0x16, temp); - - temp = ((tempcx & 0xFF00) >> 8) << 3; - temp2 |= temp; - - tempcx = pVBInfo->VGAVT - 1; - if (!(pVBInfo->VBInfo & SetCRT2ToTV)) - tempcx -= 5; - - temp = tempcx & 0x00FF; - xgifb_reg_set(pVBInfo->Part4Port, 0x17, temp); - temp = temp2 | ((tempcx & 0xFF00) >> 8); - xgifb_reg_set(pVBInfo->Part4Port, 0x15, temp); - xgifb_reg_or(pVBInfo->Part4Port, 0x0D, 0x08); - tempcx = pVBInfo->VBInfo; - tempbx = pVBInfo->VGAHDE; - - if (modeflag & HalfDCLK) - tempbx >>= 1; - - if (XGI_IsLCDDualLink(pVBInfo)) - tempbx >>= 1; - - if (tempcx & SetCRT2ToHiVision) { - temp = 0; - if (tempbx <= 1024) - temp = 0xA0; - if (tempbx == 1280) - temp = 0xC0; - } else if (tempcx & SetCRT2ToTV) { - temp = 0xA0; - if (tempbx <= 800) - temp = 0x80; - } else { - temp = 0x80; - if (pVBInfo->VBInfo & SetCRT2ToLCD) { - temp = 0; - if (tempbx > 800) - temp = 0x60; - } - } - - if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p)) { - temp = 0x00; - if (pVBInfo->VGAHDE == 1280) - temp = 0x40; - if (pVBInfo->VGAHDE == 1024) - temp = 0x20; - } - xgifb_reg_and_or(pVBInfo->Part4Port, 0x0E, ~0xEF, temp); - - tempebx = pVBInfo->VDE; - - tempcx = pVBInfo->RVBHRS; - temp = tempcx & 0x00FF; - xgifb_reg_set(pVBInfo->Part4Port, 0x18, temp); - - tempeax = pVBInfo->VGAVDE; - tempcx |= 0x04000; - - if (tempeax <= tempebx) { - tempcx = tempcx & (~0x4000); - tempeax = pVBInfo->VGAVDE; - } else { - tempeax -= tempebx; - } - - templong = (tempeax * 256 * 1024) % tempebx; - tempeax = (tempeax * 256 * 1024) / tempebx; - tempebx = tempeax; - - if (templong != 0) - tempebx++; - - temp = (unsigned short)(tempebx & 0x000000FF); - xgifb_reg_set(pVBInfo->Part4Port, 0x1B, temp); - - temp = (unsigned short)((tempebx & 0x0000FF00) >> 8); - xgifb_reg_set(pVBInfo->Part4Port, 0x1A, temp); - tempbx = (unsigned short)(tempebx >> 16); - temp = tempbx & 0x00FF; - temp <<= 4; - temp |= ((tempcx & 0xFF00) >> 8); - xgifb_reg_set(pVBInfo->Part4Port, 0x19, temp); - - /* 301b */ - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) { - temp = 0x0028; - xgifb_reg_set(pVBInfo->Part4Port, 0x1C, temp); - tempax = pVBInfo->VGAHDE; - if (modeflag & HalfDCLK) - tempax >>= 1; - - if (XGI_IsLCDDualLink(pVBInfo)) - tempax >>= 1; - - if (pVBInfo->VBInfo & SetCRT2ToLCD) { - if (tempax > 800) - tempax -= 800; - } else if (pVBInfo->VGAHDE > 800) { - if (pVBInfo->VGAHDE == 1024) - tempax = (tempax * 25 / 32) - 1; - else - tempax = (tempax * 20 / 32) - 1; - } - tempax -= 1; - - temp = (tempax & 0xFF00) >> 8; - temp = (temp & 0x0003) << 4; - xgifb_reg_set(pVBInfo->Part4Port, 0x1E, temp); - temp = tempax & 0x00FF; - xgifb_reg_set(pVBInfo->Part4Port, 0x1D, temp); - - if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVision)) { - if (pVBInfo->VGAHDE > 800) - xgifb_reg_or(pVBInfo->Part4Port, 0x1E, 0x08); - } - temp = 0x0036; - - if (pVBInfo->VBInfo & SetCRT2ToTV) { - if (!(pVBInfo->TVInfo & (NTSC1024x768 - | TVSetYPbPr525p | TVSetYPbPr750p - | TVSetHiVision))) { - temp |= 0x0001; - if ((pVBInfo->VBInfo & SetInSlaveMode) && - !(pVBInfo->TVInfo & TVSimuMode)) - temp &= (~0x0001); - } - } - - xgifb_reg_and_or(pVBInfo->Part4Port, 0x1F, 0x00C0, temp); - tempbx = pVBInfo->HT; - if (XGI_IsLCDDualLink(pVBInfo)) - tempbx >>= 1; - tempbx = (tempbx >> 1) - 2; - temp = ((tempbx & 0x0700) >> 8) << 3; - xgifb_reg_and_or(pVBInfo->Part4Port, 0x21, 0x00C0, temp); - temp = tempbx & 0x00FF; - xgifb_reg_set(pVBInfo->Part4Port, 0x22, temp); - } - /* end 301b */ - - XGI_SetCRT2VCLK(ModeIdIndex, RefreshRateTableIndex, pVBInfo); -} - -static void XGINew_EnableCRT2(struct vb_device_info *pVBInfo) -{ - xgifb_reg_and_or(pVBInfo->P3c4, 0x1E, 0xFF, 0x20); -} - -static void XGI_SetGroup5(struct vb_device_info *pVBInfo) -{ - if (pVBInfo->ModeType == ModeVGA) { - if (!(pVBInfo->VBInfo & (SetInSlaveMode | LoadDACFlag - | DisableCRT2Display))) { - XGINew_EnableCRT2(pVBInfo); - } - } -} - -static void XGI_DisableGatingCRT(struct vb_device_info *pVBInfo) -{ - xgifb_reg_and_or(pVBInfo->P3d4, 0x63, 0xBF, 0x00); -} - -static unsigned char XGI_XG21CheckLVDSMode(struct xgifb_video_info *xgifb_info, - unsigned short ModeNo, - unsigned short ModeIdIndex) -{ - unsigned short xres, yres, colordepth, modeflag, resindex; - - resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */ - yres = XGI330_ModeResInfo[resindex].VTotal; /* yres->bx */ - /* si+St_ModeFlag */ - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - - if (!(modeflag & Charx8Dot)) { - xres /= 9; - xres *= 8; - } - - if ((ModeNo > 0x13) && (modeflag & HalfDCLK)) - xres *= 2; - - if ((ModeNo > 0x13) && (modeflag & DoubleScanMode)) - yres *= 2; - - if (xres > xgifb_info->lvds_data.LVDSHDE) - return 0; - - if (yres > xgifb_info->lvds_data.LVDSVDE) - return 0; - - if (xres != xgifb_info->lvds_data.LVDSHDE || - yres != xgifb_info->lvds_data.LVDSVDE) { - colordepth = XGI_GetColorDepth(ModeIdIndex); - if (colordepth > 2) - return 0; - } - return 1; -} - -static void xgifb_set_lvds(struct xgifb_video_info *xgifb_info, - int chip_id, - unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned char temp, Miscdata; - unsigned short xres, yres, modeflag, resindex; - unsigned short LVDSHT, LVDSHBS, LVDSHRS, LVDSHRE, LVDSHBE; - unsigned short LVDSVT, LVDSVBS, LVDSVRS, LVDSVRE, LVDSVBE; - unsigned short value; - - temp = (unsigned char)((xgifb_info->lvds_data.LVDS_Capability & - (LCDPolarity << 8)) >> 8); - temp &= LCDPolarity; - Miscdata = inb(pVBInfo->P3cc); - - outb((Miscdata & 0x3F) | temp, pVBInfo->P3c2); - - temp = xgifb_info->lvds_data.LVDS_Capability & LCDPolarity; - /* SR35[7] FP VSync polarity */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x80, temp & 0x80); - /* SR30[5] FP HSync polarity */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x30, ~0x20, (temp & 0x40) >> 1); - - if (chip_id == XG27) - XGI_SetXG27FPBits(pVBInfo); - else - XGI_SetXG21FPBits(pVBInfo); - - resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */ - yres = XGI330_ModeResInfo[resindex].VTotal; /* yres->bx */ - /* si+St_ModeFlag */ - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - - if (!(modeflag & Charx8Dot)) - xres = xres * 8 / 9; - - LVDSHT = xgifb_info->lvds_data.LVDSHT; - - LVDSHBS = xres + (xgifb_info->lvds_data.LVDSHDE - xres) / 2; - - if (LVDSHBS > LVDSHT) - LVDSHBS -= LVDSHT; - - LVDSHRS = LVDSHBS + xgifb_info->lvds_data.LVDSHFP; - if (LVDSHRS > LVDSHT) - LVDSHRS -= LVDSHT; - - LVDSHRE = LVDSHRS + xgifb_info->lvds_data.LVDSHSYNC; - if (LVDSHRE > LVDSHT) - LVDSHRE -= LVDSHT; - - LVDSHBE = LVDSHBS + LVDSHT - xgifb_info->lvds_data.LVDSHDE; - - LVDSVT = xgifb_info->lvds_data.LVDSVT; - - LVDSVBS = yres + (xgifb_info->lvds_data.LVDSVDE - yres) / 2; - if (modeflag & DoubleScanMode) - LVDSVBS += yres / 2; - - if (LVDSVBS > LVDSVT) - LVDSVBS -= LVDSVT; - - LVDSVRS = LVDSVBS + xgifb_info->lvds_data.LVDSVFP; - if (LVDSVRS > LVDSVT) - LVDSVRS -= LVDSVT; - - LVDSVRE = LVDSVRS + xgifb_info->lvds_data.LVDSVSYNC; - if (LVDSVRE > LVDSVT) - LVDSVRE -= LVDSVT; - - LVDSVBE = LVDSVBS + LVDSVT - xgifb_info->lvds_data.LVDSVDE; - - temp = xgifb_reg_get(pVBInfo->P3d4, 0x11); - xgifb_reg_set(pVBInfo->P3d4, 0x11, temp & 0x7f); /* Unlock CRTC */ - - if (!(modeflag & Charx8Dot)) - xgifb_reg_or(pVBInfo->P3c4, 0x1, 0x1); - - /* HT SR0B[1:0] CR00 */ - value = (LVDSHT >> 3) - 5; - xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0x03, (value & 0x300) >> 8); - xgifb_reg_set(pVBInfo->P3d4, 0x0, (value & 0xFF)); - - /* HBS SR0B[5:4] CR02 */ - value = (LVDSHBS >> 3) - 1; - xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0x30, (value & 0x300) >> 4); - xgifb_reg_set(pVBInfo->P3d4, 0x2, (value & 0xFF)); - - /* HBE SR0C[1:0] CR05[7] CR03[4:0] */ - value = (LVDSHBE >> 3) - 1; - xgifb_reg_and_or(pVBInfo->P3c4, 0x0C, ~0x03, (value & 0xC0) >> 6); - xgifb_reg_and_or(pVBInfo->P3d4, 0x05, ~0x80, (value & 0x20) << 2); - xgifb_reg_and_or(pVBInfo->P3d4, 0x03, ~0x1F, value & 0x1F); - - /* HRS SR0B[7:6] CR04 */ - value = (LVDSHRS >> 3) + 2; - xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0xC0, (value & 0x300) >> 2); - xgifb_reg_set(pVBInfo->P3d4, 0x4, (value & 0xFF)); - - /* Panel HRS SR2F[1:0] SR2E[7:0] */ - value--; - xgifb_reg_and_or(pVBInfo->P3c4, 0x2F, ~0x03, (value & 0x300) >> 8); - xgifb_reg_set(pVBInfo->P3c4, 0x2E, (value & 0xFF)); - - /* HRE SR0C[2] CR05[4:0] */ - value = (LVDSHRE >> 3) + 2; - xgifb_reg_and_or(pVBInfo->P3c4, 0x0C, ~0x04, (value & 0x20) >> 3); - xgifb_reg_and_or(pVBInfo->P3d4, 0x05, ~0x1F, value & 0x1F); - - /* Panel HRE SR2F[7:2] */ - value--; - xgifb_reg_and_or(pVBInfo->P3c4, 0x2F, ~0xFC, value << 2); - - /* VT SR0A[0] CR07[5][0] CR06 */ - value = LVDSVT - 2; - xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x01, (value & 0x400) >> 10); - xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x20, (value & 0x200) >> 4); - xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x01, (value & 0x100) >> 8); - xgifb_reg_set(pVBInfo->P3d4, 0x06, (value & 0xFF)); - - /* VBS SR0A[2] CR09[5] CR07[3] CR15 */ - value = LVDSVBS - 1; - xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x04, (value & 0x400) >> 8); - xgifb_reg_and_or(pVBInfo->P3d4, 0x09, ~0x20, (value & 0x200) >> 4); - xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x08, (value & 0x100) >> 5); - xgifb_reg_set(pVBInfo->P3d4, 0x15, (value & 0xFF)); - - /* VBE SR0A[4] CR16 */ - value = LVDSVBE - 1; - xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x10, (value & 0x100) >> 4); - xgifb_reg_set(pVBInfo->P3d4, 0x16, (value & 0xFF)); - - /* VRS SR0A[3] CR7[7][2] CR10 */ - value = LVDSVRS - 1; - xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x08, (value & 0x400) >> 7); - xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x80, (value & 0x200) >> 2); - xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x04, (value & 0x100) >> 6); - xgifb_reg_set(pVBInfo->P3d4, 0x10, (value & 0xFF)); - - if (chip_id == XG27) { - /* Panel VRS SR35[2:0] SR34[7:0] */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x07, - (value & 0x700) >> 8); - xgifb_reg_set(pVBInfo->P3c4, 0x34, value & 0xFF); - } else { - /* Panel VRS SR3F[1:0] SR34[7:0] SR33[0] */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0x03, - (value & 0x600) >> 9); - xgifb_reg_set(pVBInfo->P3c4, 0x34, (value >> 1) & 0xFF); - xgifb_reg_and_or(pVBInfo->P3d4, 0x33, ~0x01, value & 0x01); - } - - /* VRE SR0A[5] CR11[3:0] */ - value = LVDSVRE - 1; - xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x20, (value & 0x10) << 1); - xgifb_reg_and_or(pVBInfo->P3d4, 0x11, ~0x0F, value & 0x0F); - - /* Panel VRE SR3F[7:2] */ - if (chip_id == XG27) - xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, - (value << 2) & 0xFC); - else - /* SR3F[7] has to be 0, h/w bug */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, - (value << 2) & 0x7C); - - for (temp = 0, value = 0; temp < 3; temp++) { - xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, value); - xgifb_reg_set(pVBInfo->P3c4, - 0x2B, xgifb_info->lvds_data.VCLKData1); - xgifb_reg_set(pVBInfo->P3c4, - 0x2C, xgifb_info->lvds_data.VCLKData2); - value += 0x10; - } - - if (!(modeflag & Charx8Dot)) { - inb(pVBInfo->P3da); /* reset 3da */ - outb(0x13, pVBInfo->P3c0); /* set index */ - /* set data, panning = 0, shift left 1 dot*/ - outb(0x00, pVBInfo->P3c0); - - inb(pVBInfo->P3da); /* Enable Attribute */ - outb(0x20, pVBInfo->P3c0); - - inb(pVBInfo->P3da); /* reset 3da */ - } -} - -/* - * Function : XGI_IsLCDON - * Input : - * Output : 0 : Skip PSC Control - * 1: Disable PSC - * Description : - */ -static unsigned char XGI_IsLCDON(struct vb_device_info *pVBInfo) -{ - unsigned short tempax; - - tempax = pVBInfo->VBInfo; - if (tempax & SetCRT2ToDualEdge) - return 0; - else if (tempax & (DisableCRT2Display | SwitchCRT2 | SetSimuScanMode)) - return 1; - - return 0; -} - -static void XGI_DisableBridge(struct xgifb_video_info *xgifb_info, - struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short tempah = 0; - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) { - tempah = 0x3F; - if (!(pVBInfo->VBInfo & - (DisableCRT2Display | SetSimuScanMode))) { - if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { - if (pVBInfo->VBInfo & SetCRT2ToDualEdge) - tempah = 0x7F; /* Disable Channel A */ - } - } - - /* disable part4_1f */ - xgifb_reg_and(pVBInfo->Part4Port, 0x1F, tempah); - - if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) { - if (((pVBInfo->VBInfo & - (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))) || - (XGI_IsLCDON(pVBInfo))) - /* LVDS Driver power down */ - xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x80); - } - - if (pVBInfo->VBInfo & (DisableCRT2Display | XGI_SetCRT2ToLCDA | - SetSimuScanMode)) - XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo); - - if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) - /* Power down */ - xgifb_reg_and(pVBInfo->Part1Port, 0x1e, 0xdf); - - /* disable TV as primary VGA swap */ - xgifb_reg_and(pVBInfo->P3c4, 0x32, 0xdf); - - if ((pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToDualEdge))) - xgifb_reg_and(pVBInfo->Part2Port, 0x00, 0xdf); - - if ((pVBInfo->VBInfo & - (DisableCRT2Display | SetSimuScanMode)) || - (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) && - (pVBInfo->VBInfo & - (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV)))) - xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80); - - if ((pVBInfo->VBInfo & - (DisableCRT2Display | SetSimuScanMode)) || - (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) || - (pVBInfo->VBInfo & - (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))) { - /* save Part1 index 0 */ - tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x00); - /* BTDAC = 1, avoid VB reset */ - xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x10); - /* disable CRT2 */ - xgifb_reg_and(pVBInfo->Part1Port, 0x1E, 0xDF); - /* restore Part1 index 0 */ - xgifb_reg_set(pVBInfo->Part1Port, 0x00, tempah); - } - } else { /* {301} */ - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) { - xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80); - /* Disable CRT2 */ - xgifb_reg_and(pVBInfo->Part1Port, 0x1E, 0xDF); - /* Disable TV asPrimary VGA swap */ - xgifb_reg_and(pVBInfo->P3c4, 0x32, 0xDF); - } - - if (pVBInfo->VBInfo & (DisableCRT2Display | XGI_SetCRT2ToLCDA - | SetSimuScanMode)) - XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo); - } -} - -/* - * Function : XGI_GetTVPtrIndex - * Input : - * Output : - * Description : bx 0 : ExtNTSC - * 1 : StNTSC - * 2 : ExtPAL - * 3 : StPAL - * 4 : ExtHiTV - * 5 : StHiTV - * 6 : Ext525i - * 7 : St525i - * 8 : Ext525p - * 9 : St525p - * A : Ext750p - * B : St750p - */ -static unsigned short XGI_GetTVPtrIndex(struct vb_device_info *pVBInfo) -{ - unsigned short tempbx = 0; - - if (pVBInfo->TVInfo & TVSetPAL) - tempbx = 2; - if (pVBInfo->TVInfo & TVSetHiVision) - tempbx = 4; - if (pVBInfo->TVInfo & TVSetYPbPr525i) - tempbx = 6; - if (pVBInfo->TVInfo & TVSetYPbPr525p) - tempbx = 8; - if (pVBInfo->TVInfo & TVSetYPbPr750p) - tempbx = 10; - if (pVBInfo->TVInfo & TVSimuMode) - tempbx++; - - return tempbx; -} - -/* - * Function : XGI_GetTVPtrIndex2 - * Input : - * Output : bx 0 : NTSC - * 1 : PAL - * 2 : PALM - * 3 : PALN - * 4 : NTSC1024x768 - * 5 : PAL-M 1024x768 - * 6-7: reserved - * cl 0 : YFilter1 - * 1 : YFilter2 - * ch 0 : 301A - * 1 : 301B/302B/301LV/302LV - * Description : - */ -static void XGI_GetTVPtrIndex2(unsigned short *tempbx, - unsigned char *tempcl, - unsigned char *tempch, - struct vb_device_info *pVBInfo) -{ - *tempbx = 0; - *tempcl = 0; - *tempch = 0; - - if (pVBInfo->TVInfo & TVSetPAL) - *tempbx = 1; - - if (pVBInfo->TVInfo & TVSetPALM) - *tempbx = 2; - - if (pVBInfo->TVInfo & TVSetPALN) - *tempbx = 3; - - if (pVBInfo->TVInfo & NTSC1024x768) { - *tempbx = 4; - if (pVBInfo->TVInfo & TVSetPALM) - *tempbx = 5; - } - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) { - if (!(pVBInfo->VBInfo & SetInSlaveMode) || (pVBInfo->TVInfo - & TVSimuMode)) { - *tempbx += 8; - *tempcl += 1; - } - } - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) - (*tempch)++; -} - -static void XGI_SetDelayComp(struct vb_device_info *pVBInfo) -{ - unsigned char tempah, tempbl, tempbh; - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) { - if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA - | SetCRT2ToTV | SetCRT2ToRAMDAC)) { - tempbh = 0; - tempbl = XGI301TVDelay; - - if (pVBInfo->VBInfo & SetCRT2ToDualEdge) - tempbl >>= 4; - if (pVBInfo->VBInfo & - (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { - tempbh = XGI301LCDDelay; - - if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) - tempbl = tempbh; - } - - tempbl &= 0x0F; - tempbh &= 0xF0; - tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x2D); - - if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD - | SetCRT2ToTV)) { /* Channel B */ - tempah &= 0xF0; - tempah |= tempbl; - } - - if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { - /* Channel A */ - tempah &= 0x0F; - tempah |= tempbh; - } - xgifb_reg_set(pVBInfo->Part1Port, 0x2D, tempah); - } - } -} - -static void XGI_SetLCDCap_A(unsigned short tempcx, - struct vb_device_info *pVBInfo) -{ - unsigned short temp; - - temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); - - if (temp & LCDRGB18Bit) { - xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0x0F, - /* Enable Dither */ - (unsigned short)(0x20 | (tempcx & 0x00C0))); - xgifb_reg_and_or(pVBInfo->Part1Port, 0x1A, 0x7F, 0x80); - } else { - xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0x0F, - (unsigned short)(0x30 | (tempcx & 0x00C0))); - xgifb_reg_and_or(pVBInfo->Part1Port, 0x1A, 0x7F, 0x00); - } -} - -/* - * Function : XGI_SetLCDCap_B - * Input : cx -> LCD Capability - * Output : - * Description : - */ -static void XGI_SetLCDCap_B(unsigned short tempcx, - struct vb_device_info *pVBInfo) -{ - if (tempcx & EnableLCD24bpp) { /* 24bits */ - xgifb_reg_and_or(pVBInfo->Part2Port, 0x1A, 0xE0, - (unsigned short)(((tempcx & 0x00ff) >> 6) | 0x0c)); - } else { - xgifb_reg_and_or(pVBInfo->Part2Port, 0x1A, 0xE0, - (unsigned short)(((tempcx & 0x00ff) >> 6) | 0x18)); - /* Enable Dither */ - } -} - -static void XGI_LongWait(struct vb_device_info *pVBInfo) -{ - unsigned short i; - - i = xgifb_reg_get(pVBInfo->P3c4, 0x1F); - - if (!(i & 0xC0)) { - for (i = 0; i < 0xFFFF; i++) { - if (!(inb(pVBInfo->P3da) & 0x08)) - break; - } - - for (i = 0; i < 0xFFFF; i++) { - if ((inb(pVBInfo->P3da) & 0x08)) - break; - } - } -} - -static void SetSpectrum(struct vb_device_info *pVBInfo) -{ - unsigned short index; - - index = XGI_GetLCDCapPtr(pVBInfo); - - /* disable down spectrum D[4] */ - xgifb_reg_and(pVBInfo->Part4Port, 0x30, 0x8F); - XGI_LongWait(pVBInfo); - xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x20); /* reset spectrum */ - XGI_LongWait(pVBInfo); - - xgifb_reg_set(pVBInfo->Part4Port, 0x31, - pVBInfo->LCDCapList[index].Spectrum_31); - xgifb_reg_set(pVBInfo->Part4Port, 0x32, - pVBInfo->LCDCapList[index].Spectrum_32); - xgifb_reg_set(pVBInfo->Part4Port, 0x33, - pVBInfo->LCDCapList[index].Spectrum_33); - xgifb_reg_set(pVBInfo->Part4Port, 0x34, - pVBInfo->LCDCapList[index].Spectrum_34); - XGI_LongWait(pVBInfo); - xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x40); /* enable spectrum */ -} - -static void XGI_SetLCDCap(struct vb_device_info *pVBInfo) -{ - unsigned short tempcx; - - tempcx = pVBInfo->LCDCapList[XGI_GetLCDCapPtr(pVBInfo)].LCD_Capability; - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV | - VB_SIS302LV | VB_XGI301C)) { - if (pVBInfo->VBType & - (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) { - /* Set 301LV Capability */ - xgifb_reg_set(pVBInfo->Part4Port, 0x24, - (unsigned char)(tempcx & 0x1F)); - } - /* VB Driving */ - xgifb_reg_and_or(pVBInfo->Part4Port, 0x0D, - ~((EnableVBCLKDRVLOW | EnablePLLSPLOW) >> 8), - (unsigned short)((tempcx & (EnableVBCLKDRVLOW | - EnablePLLSPLOW)) >> 8)); - - if (pVBInfo->VBInfo & SetCRT2ToLCD) - XGI_SetLCDCap_B(tempcx, pVBInfo); - else if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) - XGI_SetLCDCap_A(tempcx, pVBInfo); - - if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) { - if (tempcx & EnableSpectrum) - SetSpectrum(pVBInfo); - } - } else { - /* LVDS,CH7017 */ - XGI_SetLCDCap_A(tempcx, pVBInfo); - } -} - -/* - * Function : XGI_SetAntiFlicker - * Input : - * Output : - * Description : Set TV Customized Param. - */ -static void XGI_SetAntiFlicker(struct vb_device_info *pVBInfo) -{ - unsigned short tempbx; - - unsigned char tempah; - - if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p)) - return; - - tempbx = XGI_GetTVPtrIndex(pVBInfo); - tempbx &= 0xFE; - tempah = TVAntiFlickList[tempbx]; - tempah <<= 4; - - xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0x8F, tempah); -} - -static void XGI_SetEdgeEnhance(struct vb_device_info *pVBInfo) -{ - unsigned short tempbx; - - unsigned char tempah; - - tempbx = XGI_GetTVPtrIndex(pVBInfo); - tempbx &= 0xFE; - tempah = TVEdgeList[tempbx]; - tempah <<= 5; - - xgifb_reg_and_or(pVBInfo->Part2Port, 0x3A, 0x1F, tempah); -} - -static void XGI_SetPhaseIncr(struct vb_device_info *pVBInfo) -{ - unsigned short tempbx; - - unsigned char tempcl, tempch; - - unsigned long tempData; - - XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */ - tempData = TVPhaseList[tempbx]; - - xgifb_reg_set(pVBInfo->Part2Port, 0x31, (unsigned short)(tempData - & 0x000000FF)); - xgifb_reg_set(pVBInfo->Part2Port, 0x32, (unsigned short)((tempData - & 0x0000FF00) >> 8)); - xgifb_reg_set(pVBInfo->Part2Port, 0x33, (unsigned short)((tempData - & 0x00FF0000) >> 16)); - xgifb_reg_set(pVBInfo->Part2Port, 0x34, (unsigned short)((tempData - & 0xFF000000) >> 24)); -} - -static void XGI_SetYFilter(unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short tempbx, index; - unsigned char const *filterPtr; - unsigned char tempcl, tempch, tempal; - - XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */ - - switch (tempbx) { - case 0x00: - case 0x04: - filterPtr = NTSCYFilter1; - break; - - case 0x01: - filterPtr = PALYFilter1; - break; - - case 0x02: - case 0x05: - case 0x0D: - case 0x03: - filterPtr = xgifb_palmn_yfilter1; - break; - - case 0x08: - case 0x0C: - case 0x0A: - case 0x0B: - case 0x09: - filterPtr = xgifb_yfilter2; - break; - - default: - return; - } - - tempal = XGI330_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex; - if (tempcl == 0) - index = tempal * 4; - else - index = tempal * 7; - - if ((tempcl == 0) && (tempch == 1)) { - xgifb_reg_set(pVBInfo->Part2Port, 0x35, 0); - xgifb_reg_set(pVBInfo->Part2Port, 0x36, 0); - xgifb_reg_set(pVBInfo->Part2Port, 0x37, 0); - xgifb_reg_set(pVBInfo->Part2Port, 0x38, filterPtr[index++]); - } else { - xgifb_reg_set(pVBInfo->Part2Port, 0x35, filterPtr[index++]); - xgifb_reg_set(pVBInfo->Part2Port, 0x36, filterPtr[index++]); - xgifb_reg_set(pVBInfo->Part2Port, 0x37, filterPtr[index++]); - xgifb_reg_set(pVBInfo->Part2Port, 0x38, filterPtr[index++]); - } - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) { - xgifb_reg_set(pVBInfo->Part2Port, 0x48, filterPtr[index++]); - xgifb_reg_set(pVBInfo->Part2Port, 0x49, filterPtr[index++]); - xgifb_reg_set(pVBInfo->Part2Port, 0x4A, filterPtr[index++]); - } -} - -/* - * Function : XGI_OEM310Setting - * Input : - * Output : - * Description : Customized Param. for 301 - */ -static void XGI_OEM310Setting(unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - XGI_SetDelayComp(pVBInfo); - - if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) - XGI_SetLCDCap(pVBInfo); - - if (pVBInfo->VBInfo & SetCRT2ToTV) { - XGI_SetPhaseIncr(pVBInfo); - XGI_SetYFilter(ModeIdIndex, pVBInfo); - XGI_SetAntiFlicker(pVBInfo); - - if (pVBInfo->VBType & VB_SIS301) - XGI_SetEdgeEnhance(pVBInfo); - } -} - -/* - * Function : XGI_SetCRT2ModeRegs - * Input : - * Output : - * Description : Origin code for crt2group - */ -static void XGI_SetCRT2ModeRegs(struct vb_device_info *pVBInfo) -{ - unsigned short tempbl; - short tempcl; - - unsigned char tempah; - - tempah = 0; - if (!(pVBInfo->VBInfo & DisableCRT2Display)) { - tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x00); - tempah &= ~0x10; /* BTRAMDAC */ - tempah |= 0x40; /* BTRAM */ - - if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV - | SetCRT2ToLCD)) { - tempah = 0x40; /* BTDRAM */ - tempcl = pVBInfo->ModeType; - tempcl -= ModeVGA; - if (tempcl >= 0) { - /* BT Color */ - tempah = 0x008 >> tempcl; - if (tempah == 0) - tempah = 1; - tempah |= 0x040; - } - if (pVBInfo->VBInfo & SetInSlaveMode) - tempah ^= 0x50; /* BTDAC */ - } - } - - xgifb_reg_set(pVBInfo->Part1Port, 0x00, tempah); - tempah = 0x08; - tempbl = 0xf0; - - if (pVBInfo->VBInfo & DisableCRT2Display) - goto reg_and_or; - - tempah = 0x00; - tempbl = 0xff; - - if (!(pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | - SetCRT2ToLCD | XGI_SetCRT2ToLCDA))) - goto reg_and_or; - - if ((pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) && - (!(pVBInfo->VBInfo & SetSimuScanMode))) { - tempbl &= 0xf7; - tempah |= 0x01; - goto reg_and_or; - } - - if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { - tempbl &= 0xf7; - tempah |= 0x01; - } - - if (!(pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD))) - goto reg_and_or; - - tempbl &= 0xf8; - tempah = 0x01; - - if (!(pVBInfo->VBInfo & SetInSlaveMode)) - tempah |= 0x02; - - if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) { - tempah = tempah ^ 0x05; - if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) - tempah = tempah ^ 0x01; - } - - if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge)) - tempah |= 0x08; - -reg_and_or: - xgifb_reg_and_or(pVBInfo->Part1Port, 0x2e, tempbl, tempah); - - if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD - | XGI_SetCRT2ToLCDA)) { - tempah &= (~0x08); - if ((pVBInfo->ModeType == ModeVGA) && !(pVBInfo->VBInfo - & SetInSlaveMode)) { - tempah |= 0x010; - } - tempah |= 0x080; - - if (pVBInfo->VBInfo & SetCRT2ToTV) { - tempah |= 0x020; - if (pVBInfo->VBInfo & DriverMode) - tempah = tempah ^ 0x20; - } - - xgifb_reg_and_or(pVBInfo->Part4Port, 0x0D, ~0x0BF, tempah); - tempah = 0; - - if (pVBInfo->LCDInfo & SetLCDDualLink) - tempah |= 0x40; - - if (pVBInfo->VBInfo & SetCRT2ToTV) { - if (pVBInfo->TVInfo & RPLLDIV2XO) - tempah |= 0x40; - } - - if ((pVBInfo->LCDResInfo == Panel_1280x1024) || - (pVBInfo->LCDResInfo == Panel_1280x1024x75)) - tempah |= 0x80; - - if (pVBInfo->LCDResInfo == Panel_1280x960) - tempah |= 0x80; - - xgifb_reg_set(pVBInfo->Part4Port, 0x0C, tempah); - } - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) { - tempah = 0; - tempbl = 0xfb; - - if (pVBInfo->VBInfo & SetCRT2ToDualEdge) { - tempbl = 0xff; - if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) - tempah |= 0x04; /* shampoo 0129 */ - } - - xgifb_reg_and_or(pVBInfo->Part1Port, 0x13, tempbl, tempah); - tempah = 0x00; - tempbl = 0xcf; - if (!(pVBInfo->VBInfo & DisableCRT2Display)) { - if (pVBInfo->VBInfo & SetCRT2ToDualEdge) - tempah |= 0x30; - } - - xgifb_reg_and_or(pVBInfo->Part1Port, 0x2c, tempbl, tempah); - tempah = 0; - tempbl = 0x3f; - - if (!(pVBInfo->VBInfo & DisableCRT2Display)) { - if (pVBInfo->VBInfo & SetCRT2ToDualEdge) - tempah |= 0xc0; - } - xgifb_reg_and_or(pVBInfo->Part4Port, 0x21, tempbl, tempah); - } - - tempah = 0; - tempbl = 0x7f; - if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) { - tempbl = 0xff; - if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge)) - tempah |= 0x80; - } - - xgifb_reg_and_or(pVBInfo->Part4Port, 0x23, tempbl, tempah); - - if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) { - if (pVBInfo->LCDInfo & SetLCDDualLink) { - xgifb_reg_or(pVBInfo->Part4Port, 0x27, 0x20); - xgifb_reg_or(pVBInfo->Part4Port, 0x34, 0x10); - } - } -} - -void XGI_UnLockCRT2(struct vb_device_info *pVBInfo) -{ - xgifb_reg_and_or(pVBInfo->Part1Port, 0x2f, 0xFF, 0x01); -} - -void XGI_LockCRT2(struct vb_device_info *pVBInfo) -{ - xgifb_reg_and_or(pVBInfo->Part1Port, 0x2F, 0xFE, 0x00); -} - -unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE, - unsigned short ModeNo, - unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - static const u8 LCDARefreshIndex[] = { - 0x00, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x00 }; - - unsigned short RefreshRateTableIndex, i, index, temp; - - index = xgifb_reg_get(pVBInfo->P3d4, 0x33); - index >>= pVBInfo->SelectCRT2Rate; - index &= 0x0F; - - if (pVBInfo->LCDInfo & LCDNonExpanding) - index = 0; - - if (index > 0) - index--; - - if (pVBInfo->SetFlag & ProgrammingCRT2) { - if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { - temp = LCDARefreshIndex[pVBInfo->LCDResInfo & 0x07]; - - if (index > temp) - index = temp; - } - } - - RefreshRateTableIndex = XGI330_EModeIDTable[ModeIdIndex].REFindex; - ModeNo = XGI330_RefIndex[RefreshRateTableIndex].ModeID; - if (pXGIHWDE->jChipType >= XG20) { /* for XG20, XG21, XG27 */ - if ((XGI330_RefIndex[RefreshRateTableIndex].XRes == 800) && - (XGI330_RefIndex[RefreshRateTableIndex].YRes == 600)) { - index++; - } - /* do the similar adjustment like XGISearchCRT1Rate() */ - if ((XGI330_RefIndex[RefreshRateTableIndex].XRes == 1024) && - (XGI330_RefIndex[RefreshRateTableIndex].YRes == 768)) { - index++; - } - if ((XGI330_RefIndex[RefreshRateTableIndex].XRes == 1280) && - (XGI330_RefIndex[RefreshRateTableIndex].YRes == 1024)) { - index++; - } - } - - i = 0; - do { - if (XGI330_RefIndex[RefreshRateTableIndex + i].ModeID != ModeNo) - break; - temp = XGI330_RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag; - temp &= ModeTypeMask; - if (temp < pVBInfo->ModeType) - break; - i++; - index--; - - } while (index != 0xFFFF); - if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) { - if (pVBInfo->VBInfo & SetInSlaveMode) { - temp = XGI330_RefIndex[RefreshRateTableIndex + i - 1].Ext_InfoFlag; - if (temp & InterlaceMode) - i++; - } - } - i--; - if ((pVBInfo->SetFlag & ProgrammingCRT2)) { - temp = XGI_AjustCRT2Rate(ModeIdIndex, RefreshRateTableIndex, - &i, pVBInfo); - } - return RefreshRateTableIndex + i; -} - -static void XGI_SetLCDAGroup(unsigned short ModeNo, unsigned short ModeIdIndex, - struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short RefreshRateTableIndex; - - pVBInfo->SetFlag |= ProgrammingCRT2; - RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, - ModeIdIndex, pVBInfo); - XGI_GetLVDSResInfo(ModeIdIndex, pVBInfo); - XGI_GetLVDSData(ModeIdIndex, pVBInfo); - XGI_ModCRT1Regs(ModeIdIndex, HwDeviceExtension, pVBInfo); - XGI_SetLVDSRegs(ModeIdIndex, pVBInfo); - XGI_SetCRT2ECLK(ModeIdIndex, RefreshRateTableIndex, pVBInfo); -} - -static unsigned char XGI_SetCRT2Group301(unsigned short ModeNo, - struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short ModeIdIndex, RefreshRateTableIndex; - - pVBInfo->SetFlag |= ProgrammingCRT2; - XGI_SearchModeID(ModeNo, &ModeIdIndex); - pVBInfo->SelectCRT2Rate = 4; - RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, - ModeIdIndex, pVBInfo); - XGI_SaveCRT2Info(ModeNo, pVBInfo); - XGI_GetCRT2ResInfo(ModeIdIndex, pVBInfo); - XGI_GetCRT2Data(ModeIdIndex, RefreshRateTableIndex, pVBInfo); - XGI_PreSetGroup1(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); - XGI_SetGroup1(ModeIdIndex, RefreshRateTableIndex, pVBInfo); - XGI_SetLockRegs(ModeNo, ModeIdIndex, pVBInfo); - XGI_SetGroup2(ModeNo, ModeIdIndex, pVBInfo); - XGI_SetLCDRegs(ModeIdIndex, pVBInfo); - XGI_SetTap4Regs(pVBInfo); - XGI_SetGroup3(ModeIdIndex, pVBInfo); - XGI_SetGroup4(ModeIdIndex, RefreshRateTableIndex, pVBInfo); - XGI_SetCRT2VCLK(ModeIdIndex, RefreshRateTableIndex, pVBInfo); - XGI_SetGroup5(pVBInfo); - XGI_AutoThreshold(pVBInfo); - return 1; -} - -void XGI_SenseCRT1(struct vb_device_info *pVBInfo) -{ - unsigned char CRTCData[17] = { 0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, - 0x0B, 0x3E, 0xE9, 0x0B, 0xDF, 0xE7, 0x04, 0x00, 0x00, - 0x05, 0x00 }; - - unsigned char SR01 = 0, SR1F = 0, SR07 = 0, SR06 = 0; - - unsigned char CR17, CR63, SR31; - unsigned short temp; - - int i; - - xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86); - - /* to fix XG42 single LCD sense to CRT+LCD */ - xgifb_reg_set(pVBInfo->P3d4, 0x57, 0x4A); - xgifb_reg_set(pVBInfo->P3d4, 0x53, (xgifb_reg_get( - pVBInfo->P3d4, 0x53) | 0x02)); - - SR31 = xgifb_reg_get(pVBInfo->P3c4, 0x31); - CR63 = xgifb_reg_get(pVBInfo->P3d4, 0x63); - SR01 = xgifb_reg_get(pVBInfo->P3c4, 0x01); - - xgifb_reg_set(pVBInfo->P3c4, 0x01, (unsigned char)(SR01 & 0xDF)); - xgifb_reg_set(pVBInfo->P3d4, 0x63, (unsigned char)(CR63 & 0xBF)); - - CR17 = xgifb_reg_get(pVBInfo->P3d4, 0x17); - xgifb_reg_set(pVBInfo->P3d4, 0x17, (unsigned char)(CR17 | 0x80)); - - SR1F = xgifb_reg_get(pVBInfo->P3c4, 0x1F); - xgifb_reg_set(pVBInfo->P3c4, 0x1F, (unsigned char)(SR1F | 0x04)); - - SR07 = xgifb_reg_get(pVBInfo->P3c4, 0x07); - xgifb_reg_set(pVBInfo->P3c4, 0x07, (unsigned char)(SR07 & 0xFB)); - SR06 = xgifb_reg_get(pVBInfo->P3c4, 0x06); - xgifb_reg_set(pVBInfo->P3c4, 0x06, (unsigned char)(SR06 & 0xC3)); - - xgifb_reg_set(pVBInfo->P3d4, 0x11, 0x00); - - for (i = 0; i < 8; i++) - xgifb_reg_set(pVBInfo->P3d4, (unsigned short)i, CRTCData[i]); - - for (i = 8; i < 11; i++) - xgifb_reg_set(pVBInfo->P3d4, (unsigned short)(i + 8), - CRTCData[i]); - - for (i = 11; i < 13; i++) - xgifb_reg_set(pVBInfo->P3d4, (unsigned short)(i + 4), - CRTCData[i]); - - for (i = 13; i < 16; i++) - xgifb_reg_set(pVBInfo->P3c4, (unsigned short)(i - 3), - CRTCData[i]); - - xgifb_reg_set(pVBInfo->P3c4, 0x0E, (unsigned char)(CRTCData[16] - & 0xE0)); - - xgifb_reg_set(pVBInfo->P3c4, 0x31, 0x00); - xgifb_reg_set(pVBInfo->P3c4, 0x2B, 0x1B); - xgifb_reg_set(pVBInfo->P3c4, 0x2C, 0xE1); - - outb(0x00, pVBInfo->P3c8); - - for (i = 0; i < 256 * 3; i++) - outb(0x0F, (pVBInfo->P3c8 + 1)); /* DAC_TEST_PARMS */ - - mdelay(1); - - XGI_WaitDisply(pVBInfo); - temp = inb(pVBInfo->P3c2); - - if (temp & 0x10) - xgifb_reg_and_or(pVBInfo->P3d4, 0x32, 0xDF, 0x20); - else - xgifb_reg_and_or(pVBInfo->P3d4, 0x32, 0xDF, 0x00); - - /* avoid display something, set BLACK DAC if not restore DAC */ - outb(0x00, pVBInfo->P3c8); - - for (i = 0; i < 256 * 3; i++) - outb(0, (pVBInfo->P3c8 + 1)); - - xgifb_reg_set(pVBInfo->P3c4, 0x01, SR01); - xgifb_reg_set(pVBInfo->P3d4, 0x63, CR63); - xgifb_reg_set(pVBInfo->P3c4, 0x31, SR31); - - xgifb_reg_set(pVBInfo->P3d4, 0x53, (xgifb_reg_get( - pVBInfo->P3d4, 0x53) & 0xFD)); - xgifb_reg_set(pVBInfo->P3c4, 0x1F, (unsigned char)SR1F); -} - -static void XGI_EnableBridge(struct xgifb_video_info *xgifb_info, - struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short tempah; - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) { - if (pVBInfo->VBInfo & SetCRT2ToDualEdge) - /* Power on */ - xgifb_reg_set(pVBInfo->Part1Port, 0x1E, 0x20); - - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV | - SetCRT2ToRAMDAC)) { - tempah = xgifb_reg_get(pVBInfo->P3c4, 0x32); - tempah &= 0xDF; - if (pVBInfo->VBInfo & SetInSlaveMode) { - if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) - tempah |= 0x20; - } - xgifb_reg_set(pVBInfo->P3c4, 0x32, tempah); - xgifb_reg_or(pVBInfo->P3c4, 0x1E, 0x20); - - tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x2E); - - if (!(tempah & 0x80)) - xgifb_reg_or(pVBInfo->Part1Port, 0x2E, 0x80); - xgifb_reg_and(pVBInfo->Part1Port, 0x00, 0x7F); - } - - if (!(pVBInfo->VBInfo & DisableCRT2Display)) { - xgifb_reg_and_or(pVBInfo->Part2Port, 0x00, ~0xE0, - 0x20); /* shampoo 0129 */ - if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) { - if (pVBInfo->VBInfo & - (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) - /* LVDS PLL power on */ - xgifb_reg_and(pVBInfo->Part4Port, 0x2A, - 0x7F); - /* LVDS Driver power on */ - xgifb_reg_and(pVBInfo->Part4Port, 0x30, 0x7F); - } - } - - tempah = 0x00; - - if (!(pVBInfo->VBInfo & DisableCRT2Display)) { - tempah = 0xc0; - - if (!(pVBInfo->VBInfo & SetSimuScanMode) && - (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) && - (pVBInfo->VBInfo & SetCRT2ToDualEdge)) { - tempah = tempah & 0x40; - if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) - tempah = tempah ^ 0xC0; - } - } - - /* EnablePart4_1F */ - xgifb_reg_or(pVBInfo->Part4Port, 0x1F, tempah); - - XGI_DisableGatingCRT(pVBInfo); - XGI_DisplayOn(xgifb_info, HwDeviceExtension, pVBInfo); - } /* 301 */ - else { /* LVDS */ - if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD - | XGI_SetCRT2ToLCDA)) - /* enable CRT2 */ - xgifb_reg_or(pVBInfo->Part1Port, 0x1E, 0x20); - - tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x2E); - if (!(tempah & 0x80)) - xgifb_reg_or(pVBInfo->Part1Port, 0x2E, 0x80); - - xgifb_reg_and(pVBInfo->Part1Port, 0x00, 0x7F); - XGI_DisplayOn(xgifb_info, HwDeviceExtension, pVBInfo); - } /* End of VB */ -} - -static void XGI_SetCRT1Group(struct xgifb_video_info *xgifb_info, - struct xgi_hw_device_info *HwDeviceExtension, - unsigned short ModeNo, unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short RefreshRateTableIndex, temp; - - XGI_SetSeqRegs(pVBInfo); - outb(XGI330_StandTable.MISC, pVBInfo->P3c2); - XGI_SetCRTCRegs(pVBInfo); - XGI_SetATTRegs(ModeIdIndex, pVBInfo); - XGI_SetGRCRegs(pVBInfo); - XGI_ClearExt1Regs(pVBInfo); - - if (HwDeviceExtension->jChipType == XG27) { - if (pVBInfo->IF_DEF_LVDS == 0) - XGI_SetDefaultVCLK(pVBInfo); - } - - temp = ~ProgrammingCRT2; - pVBInfo->SetFlag &= temp; - pVBInfo->SelectCRT2Rate = 0; - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) { - if (pVBInfo->VBInfo & (SetSimuScanMode | XGI_SetCRT2ToLCDA - | SetInSlaveMode)) { - pVBInfo->SetFlag |= ProgrammingCRT2; - } - } - - RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, - ModeIdIndex, pVBInfo); - if (RefreshRateTableIndex != 0xFFFF) { - XGI_SetSync(RefreshRateTableIndex, pVBInfo); - XGI_SetCRT1CRTC(ModeIdIndex, RefreshRateTableIndex, - pVBInfo, HwDeviceExtension); - XGI_SetCRT1DE(ModeIdIndex, RefreshRateTableIndex, pVBInfo); - XGI_SetCRT1Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex, - HwDeviceExtension, pVBInfo); - XGI_SetCRT1VCLK(ModeIdIndex, HwDeviceExtension, - RefreshRateTableIndex, pVBInfo); - } - - if (HwDeviceExtension->jChipType >= XG21) { - temp = xgifb_reg_get(pVBInfo->P3d4, 0x38); - if (temp & 0xA0) { - if (HwDeviceExtension->jChipType == XG27) - XGI_SetXG27CRTC(RefreshRateTableIndex, pVBInfo); - else - XGI_SetXG21CRTC(RefreshRateTableIndex, pVBInfo); - - XGI_UpdateXG21CRTC(ModeNo, pVBInfo, - RefreshRateTableIndex); - - xgifb_set_lcd(HwDeviceExtension->jChipType, - pVBInfo, RefreshRateTableIndex); - - if (pVBInfo->IF_DEF_LVDS == 1) - xgifb_set_lvds(xgifb_info, - HwDeviceExtension->jChipType, - ModeIdIndex, pVBInfo); - } - } - - pVBInfo->SetFlag &= (~ProgrammingCRT2); - XGI_SetCRT1FIFO(HwDeviceExtension, pVBInfo); - XGI_SetCRT1ModeRegs(HwDeviceExtension, ModeIdIndex, - RefreshRateTableIndex, pVBInfo); - XGI_LoadDAC(pVBInfo); -} - -unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info, - struct xgi_hw_device_info *HwDeviceExtension, - unsigned short ModeNo) -{ - unsigned short ModeIdIndex; - struct vb_device_info VBINF; - struct vb_device_info *pVBInfo = &VBINF; - - pVBInfo->IF_DEF_LVDS = 0; - - if (HwDeviceExtension->jChipType >= XG20) - pVBInfo->VBType = 0; /* set VBType default 0 */ - - XGIRegInit(pVBInfo, xgifb_info->vga_base); - - /* for x86 Linux, XG21 LVDS */ - if (HwDeviceExtension->jChipType == XG21) { - if ((xgifb_reg_get(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0) - pVBInfo->IF_DEF_LVDS = 1; - } - if (HwDeviceExtension->jChipType == XG27) { - if ((xgifb_reg_get(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0) { - if (xgifb_reg_get(pVBInfo->P3d4, 0x30) & 0x20) - pVBInfo->IF_DEF_LVDS = 1; - } - } - - InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo); - if (ModeNo & 0x80) - ModeNo = ModeNo & 0x7F; - xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86); - - if (HwDeviceExtension->jChipType < XG20) - XGI_UnLockCRT2(pVBInfo); - - XGI_SearchModeID(ModeNo, &ModeIdIndex); - - if (HwDeviceExtension->jChipType < XG20) { - XGI_GetVBInfo(ModeIdIndex, pVBInfo); - XGI_GetTVInfo(ModeIdIndex, pVBInfo); - XGI_GetLCDInfo(ModeIdIndex, pVBInfo); - XGI_DisableBridge(xgifb_info, HwDeviceExtension, pVBInfo); - - if (pVBInfo->VBInfo & (SetSimuScanMode | XGI_SetCRT2ToLCDA) || - !(pVBInfo->VBInfo & SwitchCRT2)) { - XGI_SetCRT1Group(xgifb_info, HwDeviceExtension, ModeNo, - ModeIdIndex, pVBInfo); - - if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { - XGI_SetLCDAGroup(ModeNo, ModeIdIndex, - HwDeviceExtension, pVBInfo); - } - } - - if (pVBInfo->VBInfo & (SetSimuScanMode | SwitchCRT2)) { - switch (HwDeviceExtension->ujVBChipID) { - case VB_CHIP_301: /* fall through */ - case VB_CHIP_302: - /* add for CRT2 */ - XGI_SetCRT2Group301(ModeNo, HwDeviceExtension, - pVBInfo); - break; - - default: - break; - } - } - - XGI_SetCRT2ModeRegs(pVBInfo); - XGI_OEM310Setting(ModeIdIndex, pVBInfo); /* 0212 */ - XGI_EnableBridge(xgifb_info, HwDeviceExtension, pVBInfo); - } /* !XG20 */ - else { - if (pVBInfo->IF_DEF_LVDS == 1) - if (!XGI_XG21CheckLVDSMode(xgifb_info, ModeNo, - ModeIdIndex)) - return 0; - - pVBInfo->ModeType = - XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag - & ModeTypeMask; - - pVBInfo->SetFlag = 0; - pVBInfo->VBInfo = DisableCRT2Display; - - XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo); - - XGI_SetCRT1Group(xgifb_info, HwDeviceExtension, ModeNo, - ModeIdIndex, pVBInfo); - - XGI_DisplayOn(xgifb_info, HwDeviceExtension, pVBInfo); - } - - XGI_UpdateModeInfo(pVBInfo); - - if (HwDeviceExtension->jChipType < XG20) - XGI_LockCRT2(pVBInfo); - - return 1; -} diff --git a/drivers/staging/xgifb/vb_setmode.h b/drivers/staging/xgifb/vb_setmode.h deleted file mode 100644 index 5904ed1f2686..000000000000 --- a/drivers/staging/xgifb/vb_setmode.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _VBSETMODE_ -#define _VBSETMODE_ - -void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo); -void XGI_UnLockCRT2(struct vb_device_info *pVBInfo); -void XGI_LockCRT2(struct vb_device_info *pVBInfo); -void XGI_DisplayOff(struct xgifb_video_info *xgifb_info, - struct xgi_hw_device_info *pXGIHWDE, - struct vb_device_info *pVBInfo); -void XGI_GetVBType(struct vb_device_info *pVBInfo); -void XGI_SenseCRT1(struct vb_device_info *pVBInfo); -unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info, - struct xgi_hw_device_info *HwDeviceExtension, - unsigned short ModeNo); - -unsigned char XGI_SearchModeID(unsigned short ModeNo, - unsigned short *ModeIdIndex); -unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE, - unsigned short ModeNo, - unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo); - -#endif diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h deleted file mode 100644 index e256f72f6d8a..000000000000 --- a/drivers/staging/xgifb/vb_struct.h +++ /dev/null @@ -1,165 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _VB_STRUCT_ -#define _VB_STRUCT_ -#include "../../video/fbdev/sis/vstruct.h" - -struct XGI_LVDSCRT1HDataStruct { - unsigned char Reg[8]; -}; - -struct XGI_LVDSCRT1VDataStruct { - unsigned char Reg[7]; -}; - -struct XGI_ExtStruct { - unsigned char Ext_ModeID; - unsigned short Ext_ModeFlag; - unsigned short Ext_ModeInfo; - unsigned char Ext_RESINFO; - unsigned char VB_ExtTVYFilterIndex; - unsigned char REFindex; -}; - -struct XGI_Ext2Struct { - unsigned short Ext_InfoFlag; - unsigned char Ext_CRT1CRTC; - unsigned char Ext_CRTVCLK; - unsigned char Ext_CRT2CRTC; - unsigned char Ext_CRT2CRTC2; - unsigned char ModeID; - unsigned short XRes; - unsigned short YRes; -}; - -struct XGI_ECLKDataStruct { - unsigned char SR2E, SR2F, SR30; - unsigned short CLOCK; -}; - -/*add for new UNIVGABIOS*/ -struct XGI_LCDDesStruct { - unsigned short LCDHDES; - unsigned short LCDHRS; - unsigned short LCDVDES; - unsigned short LCDVRS; -}; - -struct XGI330_LCDDataDesStruct2 { - unsigned short LCDHDES; - unsigned short LCDHRS; - unsigned short LCDVDES; - unsigned short LCDVRS; - unsigned short LCDHSync; - unsigned short LCDVSync; -}; - -struct XGI330_LCDDataTablStruct { - unsigned char PANELID; - unsigned short MASK; - unsigned short CAP; - void const *DATAPTR; -}; - -struct XGI330_TVDataTablStruct { - unsigned short MASK; - unsigned short CAP; - struct SiS_TVData const *DATAPTR; -}; - -struct XGI_TimingHStruct { - unsigned char data[8]; -}; - -struct XGI_TimingVStruct { - unsigned char data[7]; -}; - -struct XGI_XG21CRT1Struct { - unsigned char ModeID, CR02, CR03, CR15, CR16; -}; - -struct XGI330_LCDCapStruct { - unsigned char LCD_ID; - unsigned short LCD_Capability; - unsigned char LCD_HSyncWidth; - unsigned char LCD_VSyncWidth; - unsigned char LCD_VCLK; - unsigned char LCDA_VCLKData1; - unsigned char LCDA_VCLKData2; - unsigned char LCUCHAR_VCLKData1; - unsigned char LCUCHAR_VCLKData2; - unsigned char Spectrum_31; - unsigned char Spectrum_32; - unsigned char Spectrum_33; - unsigned char Spectrum_34; -}; - -struct XGI21_LVDSCapStruct { - unsigned short LVDS_Capability; - unsigned short LVDSHT; - unsigned short LVDSVT; - unsigned short LVDSHDE; - unsigned short LVDSVDE; - unsigned short LVDSHFP; - unsigned short LVDSVFP; - unsigned short LVDSHSYNC; - unsigned short LVDSVSYNC; - unsigned char VCLKData1; - unsigned char VCLKData2; - unsigned char PSC_S1; /* Duration between CPL on and signal on */ - unsigned char PSC_S2; /* Duration signal on and Vdd on */ - unsigned char PSC_S3; /* Duration between CPL off and signal off */ - unsigned char PSC_S4; /* Duration signal off and Vdd off */ - unsigned char PSC_S5; -}; - -struct XGI_CRT1TableStruct { - unsigned char CR[16]; -}; - -struct XGI301C_Tap4TimingStruct { - unsigned short DE; - unsigned char Reg[64]; /* C0-FF */ -}; - -struct vb_device_info { - unsigned long P3c4, P3d4, P3c0, P3ce, P3c2, P3cc; - unsigned long P3ca, P3c6, P3c7, P3c8, P3c9, P3da; - unsigned long Part0Port, Part1Port, Part2Port; - unsigned long Part3Port, Part4Port, Part5Port; - unsigned short RVBHCFACT, RVBHCMAX, RVBHRS; - unsigned short VGAVT, VGAHT, VGAVDE, VGAHDE; - unsigned short VT, HT, VDE, HDE; - unsigned short LCDHRS, LCDVRS, LCDHDES, LCDVDES; - - unsigned short ModeType; - unsigned short IF_DEF_LVDS; - unsigned short IF_DEF_CRT2Monitor; - unsigned short IF_DEF_YPbPr; - unsigned short IF_DEF_HiVision; - unsigned short LCDResInfo, LCDTypeInfo, VBType;/*301b*/ - unsigned short VBInfo, TVInfo, LCDInfo; - unsigned short SetFlag; - unsigned short NewFlickerMode; - unsigned short SelectCRT2Rate; - - void __iomem *FBAddr; - - unsigned char const *SR18; - unsigned char const (*CR40)[3]; - - struct SiS_MCLKData const *MCLKData; - - unsigned char XGINew_CR97; - - struct XGI330_LCDCapStruct const *LCDCapList; - - struct XGI_TimingHStruct TimingH; - struct XGI_TimingVStruct TimingV; - - int ram_type; - int ram_channel; - int ram_bus; -}; /* _struct vb_device_info */ - -#endif /* _VB_STRUCT_ */ diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h deleted file mode 100644 index 42ecf7fe6766..000000000000 --- a/drivers/staging/xgifb/vb_table.h +++ /dev/null @@ -1,2513 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _VB_TABLE_ -#define _VB_TABLE_ -static const struct SiS_MCLKData XGI340New_MCLKData[] = { - {0x16, 0x01, 0x01, 166}, - {0x19, 0x02, 0x01, 124}, - {0x7C, 0x08, 0x01, 200}, -}; - -static const struct SiS_MCLKData XGI27New_MCLKData[] = { - {0x5c, 0x23, 0x01, 166}, - {0x19, 0x02, 0x01, 124}, - {0x7C, 0x08, 0x80, 200}, -}; - -const struct XGI_ECLKDataStruct XGI340_ECLKData[] = { - {0x5c, 0x23, 0x01, 166}, - {0x55, 0x84, 0x01, 123}, - {0x7C, 0x08, 0x01, 200}, -}; - -static const unsigned char XG27_SR18[3] = { - 0x32, 0x32, 0x42 /* SR18 */ -}; - -static const unsigned char XGI340_SR18[3] = { - 0x31, 0x42, 0x42 /* SR18 */ -}; - -static const unsigned char XGI340_cr41[24][3] = { - {0x20, 0x50, 0x60}, /* 0 CR41 */ - {0xc4, 0x40, 0x84}, /* 1 CR8A */ - {0xc4, 0x40, 0x84}, /* 2 CR8B */ - {0xb5, 0xa4, 0xa4}, - {0xf0, 0xf0, 0xf0}, - {0x90, 0x90, 0x24}, /* 5 CR68 */ - {0x77, 0x77, 0x44}, /* 6 CR69 */ - {0x77, 0x77, 0x44}, /* 7 CR6A */ - {0xff, 0xff, 0xff}, /* 8 CR6D */ - {0x55, 0x55, 0x55}, /* 9 CR80 */ - {0x00, 0x00, 0x00}, /* 10 CR81 */ - {0x88, 0xa8, 0x48}, /* 11 CR82 */ - {0x44, 0x44, 0x77}, /* 12 CR85 */ - {0x48, 0x48, 0x88}, /* 13 CR86 */ - {0x54, 0x54, 0x44}, /* 14 CR90 */ - {0x54, 0x54, 0x44}, /* 15 CR91 */ - {0x0a, 0x0a, 0x07}, /* 16 CR92 */ - {0x44, 0x44, 0x44}, /* 17 CR93 */ - {0x10, 0x10, 0x0A}, /* 18 CR94 */ - {0x11, 0x11, 0x0a}, /* 19 CR95 */ - {0x05, 0x05, 0x05}, /* 20 CR96 */ - {0xf0, 0xf0, 0xf0}, /* 21 CRC3 */ - {0x05, 0x00, 0x02}, /* 22 CRC4 */ - {0x00, 0x00, 0x00} /* 23 CRC5 */ -}; - -static const unsigned char XGI27_cr41[24][3] = { - {0x20, 0x40, 0x60}, /* 0 CR41 */ - {0xC4, 0x40, 0x84}, /* 1 CR8A */ - {0xC4, 0x40, 0x84}, /* 2 CR8B */ - {0xB3, 0x13, 0xa4}, /* 3 CR40[7], - * CR99[2:0], - * CR45[3:0] - */ - {0xf0, 0xf5, 0xf0}, /* 4 CR59 */ - {0x90, 0x90, 0x24}, /* 5 CR68 */ - {0x77, 0x67, 0x44}, /* 6 CR69 */ - {0x77, 0x77, 0x44}, /* 7 CR6A */ - {0xff, 0xff, 0xff}, /* 8 CR6D */ - {0x55, 0x55, 0x55}, /* 9 CR80 */ - {0x00, 0x00, 0x00}, /* 10 CR81 */ - {0x88, 0xcc, 0x48}, /* 11 CR82 */ - {0x44, 0x88, 0x77}, /* 12 CR85 */ - {0x48, 0x88, 0x88}, /* 13 CR86 */ - {0x54, 0x32, 0x44}, /* 14 CR90 */ - {0x54, 0x33, 0x44}, /* 15 CR91 */ - {0x0a, 0x07, 0x07}, /* 16 CR92 */ - {0x44, 0x63, 0x44}, /* 17 CR93 */ - {0x10, 0x14, 0x0A}, /* 18 CR94 */ - {0x11, 0x0B, 0x0C}, /* 19 CR95 */ - {0x05, 0x22, 0x05}, /* 20 CR96 */ - {0xf0, 0xf0, 0x00}, /* 21 CRC3 */ - {0x05, 0x00, 0x02}, /* 22 CRC4 */ - {0x00, 0x00, 0x00} /* 23 CRC5 */ -}; - -/* CR47,CR48,CR49,CR4A,CR4B,CR4C,CR70,CR71,CR74,CR75,CR76,CR77 */ -const unsigned char XGI340_AGPReg[12] = { - 0x28, 0x23, 0x00, 0x20, 0x00, 0x20, - 0x00, 0x05, 0xd0, 0x10, 0x10, 0x00 -}; - -const struct XGI_ExtStruct XGI330_EModeIDTable[] = { - {0x2e, 0x0a1b, 0x0306, 0x06, 0x05, 0x06}, - {0x2f, 0x0a1b, 0x0305, 0x05, 0x05, 0x05}, - {0x30, 0x2a1b, 0x0407, 0x07, 0x07, 0x0e}, - {0x31, 0x0a1b, 0x030d, 0x0d, 0x06, 0x3d}, - {0x32, 0x0a1b, 0x0a0e, 0x0e, 0x06, 0x3e}, - {0x33, 0x0a1d, 0x0a0d, 0x0d, 0x06, 0x3d}, - {0x34, 0x2a1d, 0x0a0e, 0x0e, 0x06, 0x3e}, - {0x35, 0x0a1f, 0x0a0d, 0x0d, 0x06, 0x3d}, - {0x36, 0x2a1f, 0x0a0e, 0x0e, 0x06, 0x3e}, - {0x38, 0x0a1b, 0x0508, 0x08, 0x00, 0x16}, - {0x3a, 0x0e3b, 0x0609, 0x09, 0x00, 0x1e}, - {0x3c, 0x0e3b, 0x070a, 0x0a, 0x00, 0x22}, /* mode 1600x1200 - * add CRT2MODE [2003/10/07] - */ - {0x3d, 0x0e7d, 0x070a, 0x0a, 0x00, 0x22}, /* mode 1600x1200 - * add CRT2MODE - */ - {0x40, 0x9a1c, 0x0000, 0x00, 0x04, 0x00}, - {0x41, 0x9a1d, 0x0000, 0x00, 0x04, 0x00}, - {0x43, 0x0a1c, 0x0306, 0x06, 0x05, 0x06}, - {0x44, 0x0a1d, 0x0306, 0x06, 0x05, 0x06}, - {0x46, 0x2a1c, 0x0407, 0x07, 0x07, 0x0e}, - {0x47, 0x2a1d, 0x0407, 0x07, 0x07, 0x0e}, - {0x49, 0x0a3c, 0x0508, 0x08, 0x00, 0x16}, - {0x4a, 0x0a3d, 0x0508, 0x08, 0x00, 0x16}, - {0x4c, 0x0e7c, 0x0609, 0x09, 0x00, 0x1e}, - {0x4d, 0x0e7d, 0x0609, 0x09, 0x00, 0x1e}, - {0x50, 0x9a1b, 0x0001, 0x01, 0x04, 0x02}, - {0x51, 0xba1b, 0x0103, 0x03, 0x07, 0x03}, - {0x52, 0x9a1b, 0x0204, 0x04, 0x00, 0x04}, - {0x56, 0x9a1d, 0x0001, 0x01, 0x04, 0x02}, - {0x57, 0xba1d, 0x0103, 0x03, 0x07, 0x03}, - {0x58, 0x9a1d, 0x0204, 0x04, 0x00, 0x04}, - {0x59, 0x9a1b, 0x0000, 0x00, 0x04, 0x00}, - {0x5A, 0x021b, 0x0014, 0x01, 0x04, 0x3f}, - {0x5B, 0x0a1d, 0x0014, 0x01, 0x04, 0x3f}, - {0x5d, 0x0a1d, 0x0305, 0x05, 0x07, 0x05}, - {0x62, 0x0a3f, 0x0306, 0x06, 0x05, 0x06}, - {0x63, 0x2a3f, 0x0407, 0x07, 0x07, 0x0e}, - {0x64, 0x0a7f, 0x0508, 0x08, 0x00, 0x16}, - {0x65, 0x0eff, 0x0609, 0x09, 0x00, 0x1e}, - {0x66, 0x0eff, 0x070a, 0x0a, 0x00, 0x22}, /* mode 1600x1200 - * add CRT2MODE - */ - {0x68, 0x067b, 0x080b, 0x0b, 0x00, 0x29}, - {0x69, 0x06fd, 0x080b, 0x0b, 0x00, 0x29}, - {0x6b, 0x07ff, 0x080b, 0x0b, 0x00, 0x29}, - {0x6c, 0x067b, 0x090c, 0x0c, 0x00, 0x2f}, - {0x6d, 0x06fd, 0x090c, 0x0c, 0x00, 0x2f}, - {0x6e, 0x07ff, 0x090c, 0x0c, 0x00, 0x2f}, - {0x70, 0x2a1b, 0x0410, 0x10, 0x07, 0x34}, - {0x71, 0x0a1b, 0x0511, 0x11, 0x00, 0x37}, - {0x74, 0x0a1d, 0x0511, 0x11, 0x00, 0x37}, - {0x75, 0x0a3d, 0x0612, 0x12, 0x00, 0x3a}, - {0x76, 0x2a1f, 0x0410, 0x10, 0x07, 0x34}, - {0x77, 0x0a1f, 0x0511, 0x11, 0x00, 0x37}, - {0x78, 0x0a3f, 0x0612, 0x12, 0x00, 0x3a}, - {0x79, 0x0a3b, 0x0612, 0x12, 0x00, 0x3a}, - {0x7a, 0x2a1d, 0x0410, 0x10, 0x07, 0x34}, - {0x7b, 0x0e3b, 0x060f, 0x0f, 0x00, 0x1d}, - {0x7c, 0x0e7d, 0x060f, 0x0f, 0x00, 0x1d}, - {0x7d, 0x0eff, 0x060f, 0x0f, 0x00, 0x1d}, - {0x20, 0x0e3b, 0x0D16, 0x16, 0x00, 0x43}, - {0x21, 0x0e7d, 0x0D16, 0x16, 0x00, 0x43}, - {0x22, 0x0eff, 0x0D16, 0x16, 0x00, 0x43}, - {0x23, 0x0e3b, 0x0614, 0x14, 0x00, 0x41}, - {0x24, 0x0e7d, 0x0614, 0x14, 0x00, 0x41}, - {0x25, 0x0eff, 0x0614, 0x14, 0x00, 0x41}, - {0x26, 0x063b, 0x0c15, 0x15, 0x00, 0x42}, - {0x27, 0x067d, 0x0c15, 0x15, 0x00, 0x42}, - {0x28, 0x06ff, 0x0c15, 0x15, 0x00, 0x42}, - {0xff, 0x0000, 0x0000, 0x00, 0x00, 0x00} -}; - -static const struct SiS_StandTable_S XGI330_StandTable = { -/* ExtVGATable */ - 0x00, 0x00, 0x00, 0x0000, - {0x21, 0x0f, 0x00, 0x0e}, /* 0x21 = 0x01 | (0x20 = screen off) */ - 0x23, - {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xea, 0x8c, 0xdf, 0x28, 0x40, 0xe7, 0x04, 0xa3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x01, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, - 0xff} -}; - -static const struct XGI_XG21CRT1Struct XGI_UpdateCRT1Table[] = { - {0x01, 0x27, 0x91, 0x8f, 0xc0}, /* 00 */ - {0x03, 0x4f, 0x83, 0x8f, 0xc0}, /* 01 */ - {0x05, 0x27, 0x91, 0x8f, 0xc0}, /* 02 */ - {0x06, 0x4f, 0x83, 0x8f, 0xc0}, /* 03 */ - {0x07, 0x4f, 0x83, 0x8f, 0xc0}, /* 04 */ - {0x0d, 0x27, 0x91, 0x8f, 0xc0}, /* 05 */ - {0x0e, 0x4f, 0x83, 0x8f, 0xc0}, /* 06 */ - {0x0f, 0x4f, 0x83, 0x5d, 0xc0}, /* 07 */ - {0x10, 0x4f, 0x83, 0x5d, 0xc0}, /* 08 */ - {0x11, 0x4f, 0x83, 0xdf, 0x0c}, /* 09 */ - {0x12, 0x4f, 0x83, 0xdf, 0x0c}, /* 10 */ - {0x13, 0x4f, 0x83, 0x8f, 0xc0}, /* 11 */ - {0x2e, 0x4f, 0x83, 0xdf, 0x0c}, /* 12 */ - {0x2e, 0x4f, 0x87, 0xdf, 0xc0}, /* 13 */ - {0x2f, 0x4f, 0x83, 0x8f, 0xc0}, /* 14 */ - {0x50, 0x27, 0x91, 0xdf, 0x0c}, /* 15 */ - {0x59, 0x27, 0x91, 0x8f, 0xc0} /* 16 */ -}; - -const struct XGI_CRT1TableStruct XGI_CRT1Table[] = { - { {0x2d, 0x28, 0x90, 0x2c, 0x90, 0x00, 0x04, 0x00, - 0xbf, 0x1f, 0x9c, 0x8e, 0x96, 0xb9, 0x30} }, /* 0x0 */ - { {0x2d, 0x28, 0x90, 0x2c, 0x90, 0x00, 0x04, 0x00, - 0x0b, 0x3e, 0xe9, 0x8b, 0xe7, 0x04, 0x00} }, /* 0x1 */ - { {0x3D, 0x31, 0x81, 0x37, 0x1F, 0x00, 0x05, 0x00, - 0x72, 0xF0, 0x58, 0x8C, 0x57, 0x73, 0xA0} }, /* 0x2 */ - { {0x4F, 0x3F, 0x93, 0x45, 0x0D, 0x00, 0x01, 0x00, - 0x24, 0xF5, 0x02, 0x88, 0xFF, 0x25, 0x90} }, /* 0x3 */ - { {0x5F, 0x50, 0x82, 0x55, 0x81, 0x00, 0x05, 0x00, - 0xBF, 0x1F, 0x9C, 0x8E, 0x96, 0xB9, 0x30} }, /* 0x4 */ - { {0x5F, 0x50, 0x82, 0x55, 0x81, 0x00, 0x05, 0x00, - 0x0B, 0x3E, 0xE9, 0x8B, 0xE7, 0x04, 0x00} }, /* 0x5 */ - { {0x63, 0x50, 0x86, 0x56, 0x9B, 0x00, 0x01, 0x00, - 0x06, 0x3E, 0xE8, 0x8B, 0xE7, 0xFF, 0x10} }, /* 0x6 */ - { {0x64, 0x4F, 0x88, 0x55, 0x9D, 0x00, 0x01, 0x00, - 0xF2, 0x1F, 0xE0, 0x83, 0xDF, 0xF3, 0x10} }, /* 0x7 */ - { {0x63, 0x4F, 0x87, 0x5A, 0x81, 0x00, 0x05, 0x00, - 0xFB, 0x1F, 0xE0, 0x83, 0xDF, 0xFC, 0x10} }, /* 0x8 */ - { {0x65, 0x4F, 0x89, 0x58, 0x80, 0x00, 0x05, 0x60, - 0xFB, 0x1F, 0xE0, 0x83, 0xDF, 0xFC, 0x80} }, /* 0x9 */ - { {0x65, 0x4F, 0x89, 0x58, 0x80, 0x00, 0x05, 0x60, - 0x01, 0x3E, 0xE0, 0x83, 0xDF, 0x02, 0x80} }, /* 0xa */ - { {0x67, 0x4F, 0x8B, 0x58, 0x81, 0x00, 0x05, 0x60, - 0x0D, 0x3E, 0xE0, 0x83, 0xDF, 0x0E, 0x90} }, /* 0xb */ - { {0x65, 0x4F, 0x89, 0x57, 0x9F, 0x00, 0x01, 0x00, - 0xFB, 0x1F, 0xE6, 0x8A, 0xDF, 0xFC, 0x10} }, /* 0xc */ - /* 0D (800x600,56Hz) */ - { {0x7B, 0x63, 0x9F, 0x6A, 0x93, 0x00, 0x05, 0x00, - /* (VCLK 36.0MHz) */ - 0x6F, 0xF0, 0x58, 0x8A, 0x57, 0x70, 0xA0} }, - /* 0E (800x600,60Hz) */ - { {0x7F, 0x63, 0x83, 0x6C, 0x1C, 0x00, 0x06, 0x00, - /* (VCLK 40.0MHz) */ - 0x72, 0xF0, 0x58, 0x8C, 0x57, 0x73, 0xA0} }, - /* 0F (800x600,72Hz) */ - { {0x7D, 0x63, 0x81, 0x6E, 0x1D, 0x00, 0x06, 0x00, - /* (VCLK 50.0MHz) */ - 0x98, 0xF0, 0x7C, 0x82, 0x57, 0x99, 0x80} }, - /* 10 (800x600,75Hz) */ - { {0x7F, 0x63, 0x83, 0x69, 0x13, 0x00, 0x06, 0x00, - /* (VCLK 49.5MHz) */ - 0x6F, 0xF0, 0x58, 0x8B, 0x57, 0x70, 0xA0} }, - /* 11 (800x600,85Hz) */ - { {0x7E, 0x63, 0x82, 0x6B, 0x13, 0x00, 0x06, 0x00, - /* (VCLK 56.25MHz) */ - 0x75, 0xF0, 0x58, 0x8B, 0x57, 0x76, 0xA0} }, - /* 12 (800x600,100Hz) */ - { {0x81, 0x63, 0x85, 0x6D, 0x18, 0x00, 0x06, 0x60, - /* (VCLK 75.8MHz) */ - 0x7A, 0xF0, 0x58, 0x8B, 0x57, 0x7B, 0xA0} }, - /* 13 (800x600,120Hz) */ - { {0x83, 0x63, 0x87, 0x6E, 0x19, 0x00, 0x06, 0x60, - /* (VCLK 79.411MHz) */ - 0x81, 0xF0, 0x58, 0x8B, 0x57, 0x82, 0xA0} }, - /* 14 (800x600,160Hz) */ - { {0x85, 0x63, 0x89, 0x6F, 0x1A, 0x00, 0x06, 0x60, - /* (VCLK 105.822MHz) */ - 0x91, 0xF0, 0x58, 0x8B, 0x57, 0x92, 0xA0} }, - { {0x99, 0x7F, 0x9D, 0x84, 0x1A, 0x00, 0x02, 0x00, - 0x96, 0x1F, 0x7F, 0x83, 0x7F, 0x97, 0x10} }, /* 0x15 */ - { {0xA3, 0x7F, 0x87, 0x86, 0x97, 0x00, 0x02, 0x00, - 0x24, 0xF5, 0x02, 0x88, 0xFF, 0x25, 0x90} }, /* 0x16 */ - { {0xA1, 0x7F, 0x85, 0x86, 0x97, 0x00, 0x02, 0x00, - 0x24, 0xF5, 0x02, 0x88, 0xFF, 0x25, 0x90} }, /* 0x17 */ - { {0x9F, 0x7F, 0x83, 0x85, 0x91, 0x00, 0x02, 0x00, - 0x1E, 0xF5, 0x00, 0x83, 0xFF, 0x1F, 0x90} }, /* 0x18 */ - { {0xA7, 0x7F, 0x8B, 0x89, 0x95, 0x00, 0x02, 0x00, - 0x26, 0xF5, 0x00, 0x83, 0xFF, 0x27, 0x90} }, /* 0x19 */ - { {0xA9, 0x7F, 0x8D, 0x8C, 0x9A, 0x00, 0x02, 0x62, - 0x2C, 0xF5, 0x00, 0x83, 0xFF, 0x2D, 0x14} }, /* 0x1a */ - { {0xAB, 0x7F, 0x8F, 0x8D, 0x9B, 0x00, 0x02, 0x62, - 0x35, 0xF5, 0x00, 0x83, 0xFF, 0x36, 0x14} }, /* 0x1b */ - { {0xCF, 0x9F, 0x93, 0xB2, 0x01, 0x00, 0x03, 0x00, - 0x14, 0xBA, 0x00, 0x83, 0xFF, 0x15, 0x00} }, /* 0x1c */ - { {0xCE, 0x9F, 0x92, 0xA9, 0x17, 0x00, 0x07, 0x00, - 0x28, 0x5A, 0x00, 0x83, 0xFF, 0x29, 0x89} }, /* 0x1d */ - { {0xCE, 0x9F, 0x92, 0xA5, 0x17, 0x00, 0x07, 0x00, - 0x28, 0x5A, 0x00, 0x83, 0xFF, 0x29, 0x89} }, /* 0x1e */ - { {0xD3, 0x9F, 0x97, 0xAB, 0x1F, 0x00, 0x07, 0x00, - 0x2E, 0x5A, 0x00, 0x83, 0xFF, 0x2F, 0x89} }, /* 0x1f */ - { {0x09, 0xC7, 0x8D, 0xD3, 0x0B, 0x01, 0x04, 0x00, - 0xE0, 0x10, 0xB0, 0x83, 0xAF, 0xE1, 0x2F} }, /* 0x20 */ - { {0x09, 0xC7, 0x8D, 0xD3, 0x0B, 0x01, 0x04, 0x00, - 0xE0, 0x10, 0xB0, 0x83, 0xAF, 0xE1, 0x2F} }, /* 0x21 */ - { {0x09, 0xC7, 0x8D, 0xD3, 0x0B, 0x01, 0x04, 0x00, - 0xE0, 0x10, 0xB0, 0x83, 0xAF, 0xE1, 0x2F} }, /* 0x22 */ - { {0x09, 0xC7, 0x8D, 0xD3, 0x0B, 0x01, 0x04, 0x00, - 0xE0, 0x10, 0xB0, 0x83, 0xAF, 0xE1, 0x2F} }, /* 0x23 */ - { {0x09, 0xC7, 0x8D, 0xD3, 0x0B, 0x01, 0x04, 0x00, - 0xE0, 0x10, 0xB0, 0x83, 0xAF, 0xE1, 0x2F} }, /* 0x24 */ - { {0x09, 0xC7, 0x8D, 0xD3, 0x0B, 0x01, 0x04, 0x00, - 0xE0, 0x10, 0xB0, 0x83, 0xAF, 0xE1, 0x2F} }, /* 0x25 */ - { {0x09, 0xC7, 0x8D, 0xD3, 0x0B, 0x01, 0x04, 0x00, - 0xE0, 0x10, 0xB0, 0x83, 0xAF, 0xE1, 0x2F} }, /* 0x26 */ - { {0x40, 0xEF, 0x84, 0x03, 0x1D, 0x41, 0x01, 0x00, - 0xDA, 0x1F, 0xA0, 0x83, 0x9F, 0xDB, 0x1F} }, /* 0x27 */ - { {0x43, 0xEF, 0x87, 0x06, 0x00, 0x41, 0x05, 0x62, - 0xD4, 0x1F, 0xA0, 0x83, 0x9F, 0xD5, 0x9F} }, /* 0x28 */ - { {0x45, 0xEF, 0x89, 0x07, 0x01, 0x41, 0x05, 0x62, - 0xD9, 0x1F, 0xA0, 0x83, 0x9F, 0xDA, 0x9F} }, /* 0x29 */ - { {0x40, 0xEF, 0x84, 0x03, 0x1D, 0x41, 0x01, 0x00, - 0xDA, 0x1F, 0xA0, 0x83, 0x9F, 0xDB, 0x1F} }, /* 0x2a */ - { {0x40, 0xEF, 0x84, 0x03, 0x1D, 0x41, 0x01, 0x00, - 0xDA, 0x1F, 0xA0, 0x83, 0x9F, 0xDB, 0x1F} }, /* 0x2b */ - { {0x40, 0xEF, 0x84, 0x03, 0x1D, 0x41, 0x01, 0x00, - 0xDA, 0x1F, 0xA0, 0x83, 0x9F, 0xDB, 0x1F} }, /* 0x2c */ - { {0x59, 0xFF, 0x9D, 0x17, 0x13, 0x41, 0x05, 0x44, - 0x33, 0xBA, 0x00, 0x83, 0xFF, 0x34, 0x0F} }, /* 0x2d */ - { {0x5B, 0xFF, 0x9F, 0x18, 0x14, 0x41, 0x05, 0x44, - 0x38, 0xBA, 0x00, 0x83, 0xFF, 0x39, 0x0F} }, /* 0x2e */ - { {0x5B, 0xFF, 0x9F, 0x18, 0x14, 0x41, 0x05, 0x44, - 0x3D, 0xBA, 0x00, 0x83, 0xFF, 0x3E, 0x0F} }, /* 0x2f */ - { {0x5D, 0xFF, 0x81, 0x19, 0x95, 0x41, 0x05, 0x44, - 0x41, 0xBA, 0x00, 0x84, 0xFF, 0x42, 0x0F} }, /* 0x30 */ - { {0x55, 0xFF, 0x99, 0x0D, 0x0C, 0x41, 0x05, 0x00, - 0x3E, 0xBA, 0x00, 0x84, 0xFF, 0x3F, 0x0F} }, /* 0x31 */ - { {0x7F, 0x63, 0x83, 0x6C, 0x1C, 0x00, 0x06, 0x00, - 0x72, 0xBA, 0x27, 0x8B, 0xDF, 0x73, 0x80} }, /* 0x32 */ - { {0x7F, 0x63, 0x83, 0x69, 0x13, 0x00, 0x06, 0x00, - 0x6F, 0xBA, 0x26, 0x89, 0xDF, 0x6F, 0x80} }, /* 0x33 */ - { {0x7F, 0x63, 0x82, 0x6B, 0x13, 0x00, 0x06, 0x00, - 0x75, 0xBA, 0x29, 0x8C, 0xDF, 0x75, 0x80} }, /* 0x34 */ - { {0xA3, 0x7F, 0x87, 0x86, 0x97, 0x00, 0x02, 0x00, - 0x24, 0xF1, 0xAF, 0x85, 0x3F, 0x25, 0xB0} }, /* 0x35 */ - { {0x9F, 0x7F, 0x83, 0x85, 0x91, 0x00, 0x02, 0x00, - 0x1E, 0xF1, 0xAD, 0x81, 0x3F, 0x1F, 0xB0} }, /* 0x36 */ - { {0xA7, 0x7F, 0x88, 0x89, 0x15, 0x00, 0x02, 0x00, - 0x26, 0xF1, 0xB1, 0x85, 0x3F, 0x27, 0xB0} }, /* 0x37 */ - { {0xCE, 0x9F, 0x92, 0xA9, 0x17, 0x00, 0x07, 0x00, - 0x28, 0xC4, 0x7A, 0x8E, 0xCF, 0x29, 0xA1} }, /* 0x38 */ - { {0xCE, 0x9F, 0x92, 0xA5, 0x17, 0x00, 0x07, 0x00, - 0x28, 0xD4, 0x7A, 0x8E, 0xCF, 0x29, 0xA1} }, /* 0x39 */ - { {0xD3, 0x9F, 0x97, 0xAB, 0x1F, 0x00, 0x07, 0x00, - 0x2E, 0xD4, 0x7D, 0x81, 0xCF, 0x2F, 0xA1} }, /* 0x3a */ - { {0xDC, 0x9F, 0x00, 0xAB, 0x19, 0x00, 0x07, 0x00, - 0xE6, 0xEF, 0xC0, 0xC3, 0xBF, 0xE7, 0x90} }, /* 0x3b */ - { {0x6B, 0x59, 0x8F, 0x5E, 0x8C, 0x00, 0x05, 0x00, - 0x0B, 0x3E, 0xE9, 0x8B, 0xE7, 0x04, 0x00} }, /* 0x3c */ - { {0x7B, 0x63, 0x9F, 0x6A, 0x93, 0x00, 0x05, 0x00, - 0x6F, 0xF0, 0x58, 0x8A, 0x57, 0x70, 0xA0} }, /* 0x3d */ - { {0x86, 0x6A, 0x8a, 0x74, 0x06, 0x00, 0x02, 0x00, - 0x8c, 0x15, 0x4f, 0x83, 0xef, 0x8d, 0x30} }, /* 0x3e */ - { {0x81, 0x6A, 0x85, 0x70, 0x00, 0x00, 0x02, 0x00, - 0x0f, 0x3e, 0xeb, 0x8e, 0xdf, 0x10, 0x00} }, /* 0x3f */ - { {0xCE, 0x9F, 0x92, 0xA9, 0x17, 0x00, 0x07, 0x00, - 0x20, 0xF5, 0x03, 0x88, 0xFF, 0x21, 0x90} }, /* 0x40 */ - { {0xE6, 0xAE, 0x8A, 0xBD, 0x90, 0x00, 0x03, 0x00, - 0x3D, 0x10, 0x1A, 0x8D, 0x19, 0x3E, 0x2F} }, /* 0x41 */ - { {0xB9, 0x8F, 0x9D, 0x9B, 0x8A, 0x00, 0x06, 0x00, - 0x7D, 0xFF, 0x60, 0x83, 0x5F, 0x7E, 0x90} }, /* 0x42 */ - { {0xC3, 0x8F, 0x87, 0x9B, 0x0B, 0x00, 0x07, 0x00, - 0x82, 0xFF, 0x60, 0x83, 0x5F, 0x83, 0x90} }, /* 0x43 */ - { {0xAD, 0x7F, 0x91, 0x8E, 0x9C, 0x00, 0x02, 0x82, - 0x49, 0xF5, 0x00, 0x83, 0xFF, 0x4A, 0x90} }, /* 0x44 */ - { {0xCD, 0x9F, 0x91, 0xA7, 0x19, 0x00, 0x07, 0x60, - 0xE6, 0xFF, 0xC0, 0x83, 0xBF, 0xE7, 0x90} }, /* 0x45 */ - { {0xD3, 0x9F, 0x97, 0xAB, 0x1F, 0x00, 0x07, 0x60, - 0xF1, 0xFF, 0xC0, 0x83, 0xBF, 0xF2, 0x90} }, /* 0x46 */ - { {0xD7, 0x9F, 0x9B, 0xAC, 0x1E, 0x00, 0x07, 0x00, - 0x03, 0xDE, 0xC0, 0x84, 0xBF, 0x04, 0x90} } /* 0x47 */ -}; - -/*add for new UNIVGABIOS*/ -static const struct SiS_LCDData XGI_StLCD1024x768Data[] = { - {62, 25, 800, 546, 1344, 806}, - {32, 15, 930, 546, 1344, 806}, - {62, 25, 800, 546, 1344, 806}, /*chiawenfordot9->dot8*/ - {104, 45, 945, 496, 1344, 806}, - {62, 25, 800, 546, 1344, 806}, - {31, 18, 1008, 624, 1344, 806}, - {1, 1, 1344, 806, 1344, 806} -}; - -static const struct SiS_LCDData XGI_ExtLCD1024x768Data[] = { - {42, 25, 1536, 419, 1344, 806}, - {48, 25, 1536, 369, 1344, 806}, - {42, 25, 1536, 419, 1344, 806}, - {48, 25, 1536, 369, 1344, 806}, - {12, 5, 896, 500, 1344, 806}, - {42, 25, 1024, 625, 1344, 806}, - {1, 1, 1344, 806, 1344, 806}, - {12, 5, 896, 500, 1344, 806}, - {42, 25, 1024, 625, 1344, 806}, - {1, 1, 1344, 806, 1344, 806}, - {12, 5, 896, 500, 1344, 806}, - {42, 25, 1024, 625, 1344, 806}, - {1, 1, 1344, 806, 1344, 806} -}; - -static const struct SiS_LCDData XGI_CetLCD1024x768Data[] = { - {1, 1, 1344, 806, 1344, 806}, /* ; 00 (320x200,320x400, - * 640x200,640x400) - */ - {1, 1, 1344, 806, 1344, 806}, /* 01 (320x350,640x350) */ - {1, 1, 1344, 806, 1344, 806}, /* 02 (360x400,720x400) */ - {1, 1, 1344, 806, 1344, 806}, /* 03 (720x350) */ - {1, 1, 1344, 806, 1344, 806}, /* 04 (640x480x60Hz) */ - {1, 1, 1344, 806, 1344, 806}, /* 05 (800x600x60Hz) */ - {1, 1, 1344, 806, 1344, 806} /* 06 (1024x768x60Hz) */ -}; - -static const struct SiS_LCDData XGI_StLCD1280x1024Data[] = { - {22, 5, 800, 510, 1650, 1088}, - {22, 5, 800, 510, 1650, 1088}, - {176, 45, 900, 510, 1650, 1088}, - {176, 45, 900, 510, 1650, 1088}, - {22, 5, 800, 510, 1650, 1088}, - {13, 5, 1024, 675, 1560, 1152}, - {16, 9, 1266, 804, 1688, 1072}, - {1, 1, 1688, 1066, 1688, 1066} -}; - -static const struct SiS_LCDData XGI_ExtLCD1280x1024Data[] = { - {211, 60, 1024, 501, 1688, 1066}, - {211, 60, 1024, 508, 1688, 1066}, - {211, 60, 1024, 501, 1688, 1066}, - {211, 60, 1024, 508, 1688, 1066}, - {211, 60, 1024, 500, 1688, 1066}, - {211, 75, 1024, 625, 1688, 1066}, - {211, 120, 1280, 798, 1688, 1066}, - {1, 1, 1688, 1066, 1688, 1066} -}; - -static const struct SiS_LCDData XGI_CetLCD1280x1024Data[] = { - {1, 1, 1688, 1066, 1688, 1066}, /* 00 (320x200,320x400, - * 640x200,640x400) - */ - {1, 1, 1688, 1066, 1688, 1066}, /* 01 (320x350,640x350) */ - {1, 1, 1688, 1066, 1688, 1066}, /* 02 (360x400,720x400) */ - {1, 1, 1688, 1066, 1688, 1066}, /* 03 (720x350) */ - {1, 1, 1688, 1066, 1688, 1066}, /* 04 (640x480x60Hz) */ - {1, 1, 1688, 1066, 1688, 1066}, /* 05 (800x600x60Hz) */ - {1, 1, 1688, 1066, 1688, 1066}, /* 06 (1024x768x60Hz) */ - {1, 1, 1688, 1066, 1688, 1066}, /* 07 (1280x1024x60Hz) */ - {1, 1, 1688, 1066, 1688, 1066} /* 08 (1400x1050x60Hz) */ -}; - -static const struct SiS_LCDData xgifb_lcd_1400x1050[] = { - {211, 100, 2100, 408, 1688, 1066}, /* 00 (320x200,320x400, - * 640x200,640x400) - */ - {211, 64, 1536, 358, 1688, 1066}, /* 01 (320x350,640x350) */ - {211, 100, 2100, 408, 1688, 1066}, /* 02 (360x400,720x400) */ - {211, 64, 1536, 358, 1688, 1066}, /* 03 (720x350) */ - {211, 48, 840, 488, 1688, 1066}, /* 04 (640x480x60Hz) */ - {211, 72, 1008, 609, 1688, 1066}, /* 05 (800x600x60Hz) */ - {211, 128, 1400, 776, 1688, 1066}, /* 06 (1024x768x60Hz) */ - {1, 1, 1688, 1066, 1688, 1066}, /* 07 (1280x1024x60Hz - * w/o Scaling) - */ - {1, 1, 1688, 1066, 1688, 1066} /* 08 (1400x1050x60Hz) */ -}; - -static const struct SiS_LCDData XGI_ExtLCD1600x1200Data[] = { - {4, 1, 1620, 420, 2160, 1250}, /* 00 (320x200,320x400, - * 640x200,640x400) - */ - {27, 7, 1920, 375, 2160, 1250}, /* 01 (320x350,640x350) */ - {4, 1, 1620, 420, 2160, 1250}, /* 02 (360x400,720x400)*/ - {27, 7, 1920, 375, 2160, 1250}, /* 03 (720x350) */ - {27, 4, 800, 500, 2160, 1250}, /* 04 (640x480x60Hz) */ - {4, 1, 1080, 625, 2160, 1250}, /* 05 (800x600x60Hz) */ - {5, 2, 1350, 800, 2160, 1250}, /* 06 (1024x768x60Hz) */ - {27, 16, 1500, 1064, 2160, 1250}, /* 07 (1280x1024x60Hz) */ - {9, 7, 1920, 1106, 2160, 1250}, /* 08 (1400x1050x60Hz) */ - {1, 1, 2160, 1250, 2160, 1250} /* 09 (1600x1200x60Hz) ;302lv */ -}; - -static const struct SiS_LCDData XGI_StLCD1600x1200Data[] = { - {27, 4, 800, 500, 2160, 1250}, /* 00 (320x200,320x400, - * 640x200,640x400) - */ - {27, 4, 800, 500, 2160, 1250}, /* 01 (320x350,640x350) */ - {27, 4, 800, 500, 2160, 1250}, /* 02 (360x400,720x400) */ - {27, 4, 800, 500, 2160, 1250}, /* 03 (720x350) */ - {27, 4, 800, 500, 2160, 1250}, /* 04 (320x240,640x480) */ - {4, 1, 1080, 625, 2160, 1250}, /* 05 (400x300,800x600) */ - {5, 2, 1350, 800, 2160, 1250}, /* 06 (512x384,1024x768) */ - {135, 88, 1600, 1100, 2160, 1250}, /* 07 (1280x1024) */ - {1, 1, 1800, 1500, 2160, 1250}, /* 08 (1400x1050) */ - {1, 1, 2160, 1250, 2160, 1250} /* 09 (1600x1200) */ -}; - -#define XGI_CetLCD1400x1050Data XGI_CetLCD1280x1024Data - -static const struct SiS_LCDData XGI_NoScalingData[] = { - {1, 1, 800, 449, 800, 449}, - {1, 1, 800, 449, 800, 449}, - {1, 1, 900, 449, 900, 449}, - {1, 1, 900, 449, 900, 449}, - {1, 1, 800, 525, 800, 525}, - {1, 1, 1056, 628, 1056, 628}, - {1, 1, 1344, 806, 1344, 806}, - {1, 1, 1688, 1066, 1688, 1066} -}; - -static const struct SiS_LCDData XGI_ExtLCD1024x768x75Data[] = { - {42, 25, 1536, 419, 1344, 806}, /* ; 00 (320x200,320x400, - * 640x200,640x400) - */ - {48, 25, 1536, 369, 1344, 806}, /* ; 01 (320x350,640x350) */ - {42, 25, 1536, 419, 1344, 806}, /* ; 02 (360x400,720x400) */ - {48, 25, 1536, 369, 1344, 806}, /* ; 03 (720x350) */ - {8, 5, 1312, 500, 1312, 800}, /* ; 04 (640x480x75Hz) */ - {41, 25, 1024, 625, 1312, 800}, /* ; 05 (800x600x75Hz) */ - {1, 1, 1312, 800, 1312, 800} /* ; 06 (1024x768x75Hz) */ -}; - -static const struct SiS_LCDData XGI_CetLCD1024x768x75Data[] = { - {1, 1, 1312, 800, 1312, 800}, /* ; 00 (320x200,320x400, - * 640x200,640x400) - */ - {1, 1, 1312, 800, 1312, 800}, /* ; 01 (320x350,640x350) */ - {1, 1, 1312, 800, 1312, 800}, /* ; 02 (360x400,720x400) */ - {1, 1, 1312, 800, 1312, 800}, /* ; 03 (720x350) */ - {1, 1, 1312, 800, 1312, 800}, /* ; 04 (640x480x75Hz) */ - {1, 1, 1312, 800, 1312, 800}, /* ; 05 (800x600x75Hz) */ - {1, 1, 1312, 800, 1312, 800} /* ; 06 (1024x768x75Hz) */ -}; - -static const struct SiS_LCDData xgifb_lcd_1280x1024x75[] = { - {211, 60, 1024, 501, 1688, 1066}, /* ; 00 (320x200,320x400, - * 640x200,640x400) - */ - {211, 60, 1024, 508, 1688, 1066}, /* ; 01 (320x350,640x350) */ - {211, 60, 1024, 501, 1688, 1066}, /* ; 02 (360x400,720x400) */ - {211, 60, 1024, 508, 1688, 1066}, /* ; 03 (720x350) */ - {211, 45, 768, 498, 1688, 1066}, /* ; 04 (640x480x75Hz) */ - {211, 75, 1024, 625, 1688, 1066}, /* ; 05 (800x600x75Hz) */ - {211, 120, 1280, 798, 1688, 1066}, /* ; 06 (1024x768x75Hz) */ - {1, 1, 1688, 1066, 1688, 1066} /* ; 07 (1280x1024x75Hz) */ -}; - -#define XGI_CetLCD1280x1024x75Data XGI_CetLCD1280x1024Data - -static const struct SiS_LCDData XGI_NoScalingDatax75[] = { - {1, 1, 800, 449, 800, 449}, /* ; 00 (320x200, 320x400, - * 640x200, 640x400) - */ - {1, 1, 800, 449, 800, 449}, /* ; 01 (320x350, 640x350) */ - {1, 1, 900, 449, 900, 449}, /* ; 02 (360x400, 720x400) */ - {1, 1, 900, 449, 900, 449}, /* ; 03 (720x350) */ - {1, 1, 840, 500, 840, 500}, /* ; 04 (640x480x75Hz) */ - {1, 1, 1056, 625, 1056, 625}, /* ; 05 (800x600x75Hz) */ - {1, 1, 1312, 800, 1312, 800}, /* ; 06 (1024x768x75Hz) */ - {1, 1, 1688, 1066, 1688, 1066}, /* ; 07 (1280x1024x75Hz) */ - {1, 1, 1688, 1066, 1688, 1066}, /* ; 08 (1400x1050x75Hz)*/ - {1, 1, 2160, 1250, 2160, 1250}, /* ; 09 (1600x1200x75Hz) */ - {1, 1, 1688, 806, 1688, 806} /* ; 0A (1280x768x75Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_ExtLCDDes1024x768Data[] = { - {9, 1057, 0, 771}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {9, 1057, 0, 771}, /* ; 01 (320x350,640x350) */ - {9, 1057, 0, 771}, /* ; 02 (360x400,720x400) */ - {9, 1057, 0, 771}, /* ; 03 (720x350) */ - {9, 1057, 0, 771}, /* ; 04 (640x480x60Hz) */ - {9, 1057, 0, 771}, /* ; 05 (800x600x60Hz) */ - {9, 1057, 805, 770} /* ; 06 (1024x768x60Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_StLCDDes1024x768Data[] = { - {9, 1057, 737, 703}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {9, 1057, 686, 651}, /* ; 01 (320x350,640x350) */ - {9, 1057, 737, 703}, /* ; 02 (360x400,720x400) */ - {9, 1057, 686, 651}, /* ; 03 (720x350) */ - {9, 1057, 776, 741}, /* ; 04 (640x480x60Hz) */ - {9, 1057, 0, 771}, /* ; 05 (800x600x60Hz) */ - {9, 1057, 805, 770} /* ; 06 (1024x768x60Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_CetLCDDes1024x768Data[] = { - {1152, 856, 622, 587}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {1152, 856, 597, 562}, /* ; 01 (320x350,640x350) */ - {1152, 856, 622, 587}, /* ; 02 (360x400,720x400) */ - {1152, 856, 597, 562}, /* ; 03 (720x350) */ - {1152, 856, 662, 627}, /* ; 04 (640x480x60Hz) */ - {1232, 936, 722, 687}, /* ; 05 (800x600x60Hz) */ - {0, 1048, 805, 770} /* ; 06 (1024x768x60Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_ExtLCDDLDes1280x1024Data[] = { - {18, 1346, 981, 940}, /* 00 (320x200,320x400,640x200,640x400) */ - {18, 1346, 926, 865}, /* 01 (320x350,640x350) */ - {18, 1346, 981, 940}, /* 02 (360x400,720x400) */ - {18, 1346, 926, 865}, /* 03 (720x350) */ - {18, 1346, 0, 1025}, /* 04 (640x480x60Hz) */ - {18, 1346, 0, 1025}, /* 05 (800x600x60Hz) */ - {18, 1346, 1065, 1024}, /* 06 (1024x768x60Hz) */ - {18, 1346, 1065, 1024} /* 07 (1280x1024x60Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_StLCDDLDes1280x1024Data[] = { - {18, 1346, 970, 907}, /* 00 (320x200,320x400,640x200,640x400) */ - {18, 1346, 917, 854}, /* 01 (320x350,640x350) */ - {18, 1346, 970, 907}, /* 02 (360x400,720x400) */ - {18, 1346, 917, 854}, /* 03 (720x350) */ - {18, 1346, 0, 1025}, /* 04 (640x480x60Hz) */ - {18, 1346, 0, 1025}, /* 05 (800x600x60Hz) */ - {18, 1346, 1065, 1024}, /* 06 (1024x768x60Hz) */ - {18, 1346, 1065, 1024} /* 07 (1280x1024x60Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_CetLCDDLDes1280x1024Data[] = { - {1368, 1008, 752, 711}, /* 00 (320x200,320x400,640x200,640x400) */ - {1368, 1008, 729, 688}, /* 01 (320x350,640x350) */ - {1368, 1008, 752, 711}, /* 02 (360x400,720x400) */ - {1368, 1008, 729, 688}, /* 03 (720x350) */ - {1368, 1008, 794, 753}, /* 04 (640x480x60Hz) */ - {1448, 1068, 854, 813}, /* 05 (800x600x60Hz) */ - {1560, 1200, 938, 897}, /* 06 (1024x768x60Hz) */ - {18, 1346, 1065, 1024} /* 07 (1280x1024x60Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_ExtLCDDes1280x1024Data[] = { - {9, 1337, 981, 940}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {9, 1337, 926, 884}, /* ; 01 (320x350,640x350) alan, 2003/09/30 */ - {9, 1337, 981, 940}, /* ; 02 (360x400,720x400) */ - {9, 1337, 926, 884}, /* ; 03 (720x350) alan, 2003/09/30 */ - {9, 1337, 0, 1025}, /* ; 04 (640x480x60Hz) */ - {9, 1337, 0, 1025}, /* ; 05 (800x600x60Hz) */ - {9, 1337, 1065, 1024}, /* ; 06 (1024x768x60Hz) */ - {9, 1337, 1065, 1024} /* ; 07 (1280x1024x60Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_StLCDDes1280x1024Data[] = { - {9, 1337, 970, 907}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {9, 1337, 917, 854}, /* ; 01 (320x350,640x350) */ - {9, 1337, 970, 907}, /* ; 02 (360x400,720x400) */ - {9, 1337, 917, 854}, /* ; 03 (720x350) */ - {9, 1337, 0, 1025}, /* ; 04 (640x480x60Hz) */ - {9, 1337, 0, 1025}, /* ; 05 (800x600x60Hz) */ - {9, 1337, 1065, 1024}, /* ; 06 (1024x768x60Hz) */ - {9, 1337, 1065, 1024} /* ; 07 (1280x1024x60Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_CetLCDDes1280x1024Data[] = { - {1368, 1008, 752, 711}, /* 00 (320x200,320x400,640x200,640x400) */ - {1368, 1008, 729, 688}, /* 01 (320x350,640x350) */ - {1368, 1008, 752, 711}, /* 02 (360x400,720x400) */ - {1368, 1008, 729, 688}, /* 03 (720x350) */ - {1368, 1008, 794, 753}, /* 04 (640x480x60Hz) */ - {1448, 1068, 854, 813}, /* 05 (800x600x60Hz) */ - {1560, 1200, 938, 897}, /* 06 (1024x768x60Hz) */ - {9, 1337, 1065, 1024} /* 07 (1280x1024x60Hz) */ -}; - -static const struct XGI_LCDDesStruct xgifb_lcddldes_1400x1050[] = { - {18, 1464, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */ - {18, 1464, 0, 1051}, /* 01 (320x350,640x350) */ - {18, 1464, 0, 1051}, /* 02 (360x400,720x400) */ - {18, 1464, 0, 1051}, /* 03 (720x350) */ - {18, 1464, 0, 1051}, /* 04 (640x480x60Hz) */ - {18, 1464, 0, 1051}, /* 05 (800x600x60Hz) */ - {18, 1464, 0, 1051}, /* 06 (1024x768x60Hz) */ - {1646, 1406, 1053, 1038}, /* 07 (1280x1024x60Hz) */ - {18, 1464, 0, 1051} /* 08 (1400x1050x60Hz) */ -}; - -static const struct XGI_LCDDesStruct xgifb_lcddes_1400x1050[] = { - {9, 1455, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */ - {9, 1455, 0, 1051}, /* 01 (320x350,640x350) */ - {9, 1455, 0, 1051}, /* 02 (360x400,720x400) */ - {9, 1455, 0, 1051}, /* 03 (720x350) */ - {9, 1455, 0, 1051}, /* 04 (640x480x60Hz) */ - {9, 1455, 0, 1051}, /* 05 (800x600x60Hz) */ - {9, 1455, 0, 1051}, /* 06 (1024x768x60Hz) */ - {1637, 1397, 1053, 1038}, /* 07 (1280x1024x60Hz) */ - {9, 1455, 0, 1051} /* 08 (1400x1050x60Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_CetLCDDes1400x1050Data[] = { - {1308, 1068, 781, 766}, /* 00 (320x200,320x400,640x200,640x400) */ - {1308, 1068, 781, 766}, /* 01 (320x350,640x350) */ - {1308, 1068, 781, 766}, /* 02 (360x400,720x400) */ - {1308, 1068, 781, 766}, /* 03 (720x350) */ - {1308, 1068, 781, 766}, /* 04 (640x480x60Hz) */ - {1388, 1148, 841, 826}, /* 05 (800x600x60Hz) */ - {1490, 1250, 925, 910}, /* 06 (1024x768x60Hz) */ - {1646, 1406, 1053, 1038}, /* 07 (1280x1024x60Hz) */ - {18, 1464, 0, 1051} /* 08 (1400x1050x60Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_CetLCDDes1400x1050Data2[] = { - {0, 1448, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */ - {0, 1448, 0, 1051}, /* 01 (320x350,640x350) */ - {0, 1448, 0, 1051}, /* 02 (360x400,720x400) */ - {0, 1448, 0, 1051}, /* 03 (720x350) */ - {0, 1448, 0, 1051} /* 04 (640x480x60Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_ExtLCDDLDes1600x1200Data[] = { - {18, 1682, 0, 1201}, /* 00 (320x200,320x400,640x200,640x400) */ - {18, 1682, 0, 1201}, /* 01 (320x350,640x350) */ - {18, 1682, 0, 1201}, /* 02 (360x400,720x400) */ - {18, 1682, 0, 1201}, /* 03 (720x350) */ - {18, 1682, 0, 1201}, /* 04 (640x480x60Hz) */ - {18, 1682, 0, 1201}, /* 05 (800x600x60Hz) */ - {18, 1682, 0, 1201}, /* 06 (1024x768x60Hz) */ - {18, 1682, 0, 1201}, /* 07 (1280x1024x60Hz) */ - {18, 1682, 0, 1201}, /* 08 (1400x1050x60Hz) */ - {18, 1682, 0, 1201} /* 09 (1600x1200x60Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_StLCDDLDes1600x1200Data[] = { - {18, 1682, 1150, 1101}, /* 00 (320x200,320x400,640x200,640x400) */ - {18, 1682, 1083, 1034}, /* 01 (320x350,640x350) */ - {18, 1682, 1150, 1101}, /* 02 (360x400,720x400) */ - {18, 1682, 1083, 1034}, /* 03 (720x350) */ - {18, 1682, 0, 1201}, /* 04 (640x480x60Hz) */ - {18, 1682, 0, 1201}, /* 05 (800x600x60Hz) */ - {18, 1682, 0, 1201}, /* 06 (1024x768x60Hz) */ - {18, 1682, 1232, 1183}, /* 07 (1280x1024x60Hz) */ - {18, 1682, 0, 1201}, /* 08 (1400x1050x60Hz) */ - {18, 1682, 0, 1201} /* 09 (1600x1200x60Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_ExtLCDDes1600x1200Data[] = { - {9, 1673, 0, 1201}, /* 00 (320x200,320x400,640x200,640x400) */ - {9, 1673, 0, 1201}, /* 01 (320x350,640x350) */ - {9, 1673, 0, 1201}, /* 02 (360x400,720x400) */ - {9, 1673, 0, 1201}, /* 03 (720x350) */ - {9, 1673, 0, 1201}, /* 04 (640x480x60Hz) */ - {9, 1673, 0, 1201}, /* 05 (800x600x60Hz) */ - {9, 1673, 0, 1201}, /* 06 (1024x768x60Hz) */ - {9, 1673, 0, 1201}, /* 07 (1280x1024x60Hz) */ - {9, 1673, 0, 1201}, /* 08 (1400x1050x60Hz) */ - {9, 1673, 0, 1201} /* 09 (1600x1200x60Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_StLCDDes1600x1200Data[] = { - {9, 1673, 1150, 1101}, /* 00 (320x200,320x400,640x200,640x400) */ - {9, 1673, 1083, 1034}, /* 01 (320x350,640x350) */ - {9, 1673, 1150, 1101}, /* 02 (360x400,720x400) */ - {9, 1673, 1083, 1034}, /* 03 (720x350) */ - {9, 1673, 0, 1201}, /* 04 (640x480x60Hz) */ - {9, 1673, 0, 1201}, /* 05 (800x600x60Hz) */ - {9, 1673, 0, 1201}, /* 06 (1024x768x60Hz) */ - {9, 1673, 1232, 1183}, /* 07 (1280x1024x60Hz) */ - {9, 1673, 0, 1201}, /* 08 (1400x1050x60Hz) */ - {9, 1673, 0, 1201} /* 09 (1600x1200x60Hz) */ -}; - -static const struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesData[] = { - {9, 657, 448, 405, 96, 2}, /* 00 (320x200,320x400, - * 640x200,640x400) - */ - {9, 657, 448, 355, 96, 2}, /* 01 (320x350,640x350) */ - {9, 657, 448, 405, 96, 2}, /* 02 (360x400,720x400) */ - {9, 657, 448, 355, 96, 2}, /* 03 (720x350) */ - {9, 657, 1, 483, 96, 2}, /* 04 (640x480x60Hz) */ - {9, 849, 627, 600, 128, 4}, /* 05 (800x600x60Hz) */ - {9, 1057, 805, 770, 0136, 6}, /* 06 (1024x768x60Hz) */ - {9, 1337, 0, 1025, 112, 3}, /* 07 (1280x1024x60Hz) */ - {9, 1457, 0, 1051, 112, 3}, /* 08 (1400x1050x60Hz)*/ - {9, 1673, 0, 1201, 192, 3}, /* 09 (1600x1200x60Hz) */ - {9, 1337, 0, 771, 112, 6} /* 0A (1280x768x60Hz) */ -}; - -/* ;;1024x768x75Hz */ -static const struct XGI_LCDDesStruct xgifb_lcddes_1024x768x75[] = { - {9, 1049, 0, 769}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {9, 1049, 0, 769}, /* ; 01 (320x350,640x350) */ - {9, 1049, 0, 769}, /* ; 02 (360x400,720x400) */ - {9, 1049, 0, 769}, /* ; 03 (720x350) */ - {9, 1049, 0, 769}, /* ; 04 (640x480x75Hz) */ - {9, 1049, 0, 769}, /* ; 05 (800x600x75Hz) */ - {9, 1049, 0, 769} /* ; 06 (1024x768x75Hz) */ -}; - -/* ;;1024x768x75Hz */ -static const struct XGI_LCDDesStruct XGI_CetLCDDes1024x768x75Data[] = { - {1152, 856, 622, 587}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {1152, 856, 597, 562}, /* ; 01 (320x350,640x350) */ - {1192, 896, 622, 587}, /* ; 02 (360x400,720x400) */ - {1192, 896, 597, 562}, /* ; 03 (720x350) */ - {1129, 857, 656, 625}, /* ; 04 (640x480x75Hz) */ - {1209, 937, 716, 685}, /* ; 05 (800x600x75Hz) */ - {9, 1049, 0, 769} /* ; 06 (1024x768x75Hz) */ -}; - -/* ;;1280x1024x75Hz */ -static const struct XGI_LCDDesStruct xgifb_lcddldes_1280x1024x75[] = { - {18, 1314, 0, 1025}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {18, 1314, 0, 1025}, /* ; 01 (320x350,640x350) */ - {18, 1314, 0, 1025}, /* ; 02 (360x400,720x400) */ - {18, 1314, 0, 1025}, /* ; 03 (720x350) */ - {18, 1314, 0, 1025}, /* ; 04 (640x480x60Hz) */ - {18, 1314, 0, 1025}, /* ; 05 (800x600x60Hz) */ - {18, 1314, 0, 1025}, /* ; 06 (1024x768x60Hz) */ - {18, 1314, 0, 1025} /* ; 07 (1280x1024x60Hz) */ -}; - -/* 1280x1024x75Hz */ -static const struct XGI_LCDDesStruct XGI_CetLCDDLDes1280x1024x75Data[] = { - {1368, 1008, 752, 711}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {1368, 1008, 729, 688}, /* ; 01 (320x350,640x350) */ - {1408, 1048, 752, 711}, /* ; 02 (360x400,720x400) */ - {1408, 1048, 729, 688}, /* ; 03 (720x350) */ - {1377, 985, 794, 753}, /* ; 04 (640x480x75Hz) */ - {1457, 1065, 854, 813}, /* ; 05 (800x600x75Hz) */ - {1569, 1177, 938, 897}, /* ; 06 (1024x768x75Hz) */ - {18, 1314, 0, 1025} /* ; 07 (1280x1024x75Hz) */ -}; - -/* ;;1280x1024x75Hz */ -static const struct XGI_LCDDesStruct xgifb_lcddes_1280x1024x75[] = { - {9, 1305, 0, 1025}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {9, 1305, 0, 1025}, /* ; 01 (320x350,640x350) */ - {9, 1305, 0, 1025}, /* ; 02 (360x400,720x400) */ - {9, 1305, 0, 1025}, /* ; 03 (720x350) */ - {9, 1305, 0, 1025}, /* ; 04 (640x480x60Hz) */ - {9, 1305, 0, 1025}, /* ; 05 (800x600x60Hz) */ - {9, 1305, 0, 1025}, /* ; 06 (1024x768x60Hz) */ - {9, 1305, 0, 1025} /* ; 07 (1280x1024x60Hz) */ -}; - -/* 1280x1024x75Hz */ -static const struct XGI_LCDDesStruct XGI_CetLCDDes1280x1024x75Data[] = { - {1368, 1008, 752, 711}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {1368, 1008, 729, 688}, /* ; 01 (320x350,640x350) */ - {1408, 1048, 752, 711}, /* ; 02 (360x400,720x400) */ - {1408, 1048, 729, 688}, /* ; 03 (720x350) */ - {1377, 985, 794, 753}, /* ; 04 (640x480x75Hz) */ - {1457, 1065, 854, 813}, /* ; 05 (800x600x75Hz) */ - {1569, 1177, 938, 897}, /* ; 06 (1024x768x75Hz) */ - {9, 1305, 0, 1025} /* ; 07 (1280x1024x75Hz) */ -}; - -/* Scaling LCD 75Hz */ -static const struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesDatax75[] = { - {9, 657, 448, 405, 96, 2}, /* ; 00 (320x200,320x400, - * 640x200,640x400) - */ - {9, 657, 448, 355, 96, 2}, /* ; 01 (320x350,640x350) */ - {9, 738, 448, 405, 108, 2}, /* ; 02 (360x400,720x400) */ - {9, 738, 448, 355, 108, 2}, /* ; 03 (720x350) */ - {9, 665, 0, 481, 64, 3}, /* ; 04 (640x480x75Hz) */ - {9, 825, 0, 601, 80, 3}, /* ; 05 (800x600x75Hz) */ - {9, 1049, 0, 769, 96, 3}, /* ; 06 (1024x768x75Hz) */ - {9, 1305, 0, 1025, 144, 3}, /* ; 07 (1280x1024x75Hz) */ - {9, 1457, 0, 1051, 112, 3}, /* ; 08 (1400x1050x60Hz)*/ - {9, 1673, 0, 1201, 192, 3}, /* ; 09 (1600x1200x75Hz) */ - {9, 1337, 0, 771, 112, 6} /* ; 0A (1280x768x60Hz) */ -}; - -static const struct SiS_TVData XGI_StPALData[] = { - {1, 1, 864, 525, 1270, 400, 100, 0, 760}, - {1, 1, 864, 525, 1270, 350, 100, 0, 760}, - {1, 1, 864, 525, 1270, 400, 0, 0, 720}, - {1, 1, 864, 525, 1270, 350, 0, 0, 720}, - {1, 1, 864, 525, 1270, 480, 50, 0, 760}, - {1, 1, 864, 525, 1270, 600, 50, 0, 0} -}; - -static const struct SiS_TVData XGI_ExtPALData[] = { - {2, 1, 1080, 463, 1270, 500, 50, 0, 50}, - {15, 7, 1152, 413, 1270, 500, 50, 0, 50}, - {2, 1, 1080, 463, 1270, 500, 50, 0, 50}, - {15, 7, 1152, 413, 1270, 500, 50, 0, 50}, - {2, 1, 900, 543, 1270, 500, 0, 0, 50}, - {4, 3, 1080, 663, 1270, 500, 438, 0, 438}, - {1, 1, 1125, 831, 1270, 500, 686, 0, 686}, /*301b*/ - {3, 2, 1080, 619, 1270, 540, 438, 0, 438} -}; - -static const struct SiS_TVData XGI_StNTSCData[] = { - {1, 1, 858, 525, 1270, 400, 50, 0, 760}, - {1, 1, 858, 525, 1270, 350, 50, 0, 640}, - {1, 1, 858, 525, 1270, 400, 0, 0, 720}, - {1, 1, 858, 525, 1270, 350, 0, 0, 720}, - {1, 1, 858, 525, 1270, 480, 0, 0, 760} -}; - -static const struct SiS_TVData XGI_ExtNTSCData[] = { - {9, 5, 1001, 453, 1270, 420, 171, 0, 171}, - {12, 5, 858, 403, 1270, 420, 171, 0, 171}, - {9, 5, 1001, 453, 1270, 420, 171, 0, 171}, - {12, 5, 858, 403, 1270, 420, 171, 0, 171}, - {143, 80, 836, 523, 1270, 420, 224, 0, 0}, - {143, 120, 1008, 643, 1270, 420, 0, 1, 0}, - {1, 1, 1120, 821, 1516, 420, 0, 1, 0}, /*301b*/ - {2, 1, 858, 503, 1584, 480, 0, 1, 0}, - {3, 2, 1001, 533, 1270, 420, 0, 0, 0} -}; - -static const struct SiS_TVData XGI_St1HiTVData[] = { - {1, 1, 892, 563, 690, 800, 0, 0, 0}, /* 00 (320x200,320x400, - * 640x200,640x400) - */ - {1, 1, 892, 563, 690, 700, 0, 0, 0}, /* 01 (320x350,640x350) */ - {1, 1, 1000, 563, 785, 800, 0, 0, 0}, /* 02 (360x400,720x400) */ - {1, 1, 1000, 563, 785, 700, 0, 0, 0}, /* 03 (720x350) */ - {1, 1, 892, 563, 690, 960, 0, 0, 0}, /* 04 (320x240,640x480) */ - {8, 5, 1050, 683, 1648, 960, 0x150, 1, 0} /* 05 (400x300,800x600) */ -}; - -static const struct SiS_TVData XGI_St2HiTVData[] = { - {3, 1, 840, 483, 1648, 960, 0x032, 0, 0}, /* 00 (320x200,320x400, - * 640x200,640x400) - */ - {1, 1, 892, 563, 690, 700, 0, 0, 0}, /* 01 (320x350,640x350) */ - {3, 1, 840, 483, 1648, 960, 0x032, 0, 0}, /* 02 (360x400,720x400) */ - {1, 1, 1000, 563, 785, 700, 0, 0, 0}, /* 03 (720x350) */ - {5, 2, 840, 563, 1648, 960, 0x08D, 1, 0}, /* 04 (320x240,640x480) */ - {8, 5, 1050, 683, 1648, 960, 0x17C, 1, 0} /* 05 (400x300,800x600) */ -}; - -static const struct SiS_TVData XGI_ExtHiTVData[] = { - {6, 1, 840, 563, 1632, 960, 0, 0, 0}, /* 00 (320x200,320x400, - * 640x200,640x400) - */ - {3, 1, 960, 563, 1632, 960, 0, 0, 0}, /* 01 (320x350,640x350) */ - {3, 1, 840, 483, 1632, 960, 0, 0, 0}, /* 02 (360x400,720x400) */ - {3, 1, 960, 563, 1632, 960, 0, 0, 0}, /* 03 (720x350) */ - {5, 1, 840, 563, 1648, 960, 0x166, 1, 0}, /* 04 (320x240,640x480) */ - {16, 5, 1050, 683, 1648, 960, 0x143, 1, 0}, /* 05 (400x300,800x600) */ - {25, 12, 1260, 851, 1648, 960, 0x032, 0, 0}, /* 06 (512x384,1024x768)*/ - {5, 4, 1575, 1124, 1648, 960, 0x128, 0, 0}, /* 07 (1280x1024) */ - {4, 1, 1050, 563, 1548, 960, 0x143, 1, 0}, /* 08 (800x480) */ - {5, 2, 1400, 659, 1648, 960, 0x032, 0, 0}, /* 09 (1024x576) */ - {8, 5, 1750, 803, 1648, 960, 0x128, 0, 0} /* 0A (1280x720) */ -}; - -static const struct SiS_TVData XGI_ExtYPbPr525iData[] = { - { 9, 5, 1001, 453, 1270, 420, 171, 0, 171}, - { 12, 5, 858, 403, 1270, 420, 171, 0, 171}, - { 9, 5, 1001, 453, 1270, 420, 171, 0, 171}, - { 12, 5, 858, 403, 1270, 420, 171, 0, 171}, - {143, 80, 836, 523, 1250, 420, 224, 0, 0}, - {143, 120, 1008, 643, 1250, 420, 0, 1, 0}, - { 1, 1, 1120, 821, 1516, 420, 0, 1, 0}, /*301b*/ - { 2, 1, 858, 503, 1584, 480, 0, 1, 0}, - { 3, 2, 1001, 533, 1250, 420, 0, 0, 0} -}; - -static const struct SiS_TVData XGI_StYPbPr525iData[] = { - {1, 1, 858, 525, 1270, 400, 50, 0, 760}, - {1, 1, 858, 525, 1270, 350, 50, 0, 640}, - {1, 1, 858, 525, 1270, 400, 0, 0, 720}, - {1, 1, 858, 525, 1270, 350, 0, 0, 720}, - {1, 1, 858, 525, 1270, 480, 0, 0, 760}, -}; - -static const struct SiS_TVData XGI_ExtYPbPr525pData[] = { - { 9, 5, 1001, 453, 1270, 420, 171, 0, 171}, - { 12, 5, 858, 403, 1270, 420, 171, 0, 171}, - { 9, 5, 1001, 453, 1270, 420, 171, 0, 171}, - { 12, 5, 858, 403, 1270, 420, 171, 0, 171}, - {143, 80, 836, 523, 1270, 420, 224, 0, 0}, - {143, 120, 1008, 643, 1270, 420, 0, 1, 0}, - { 1, 1, 1120, 821, 1516, 420, 0, 1, 0}, /*301b*/ - { 2, 1, 858, 503, 1584, 480, 0, 1, 0}, - { 3, 2, 1001, 533, 1270, 420, 0, 0, 0} -}; - -static const struct SiS_TVData XGI_StYPbPr525pData[] = { - {1, 1, 1716, 525, 1270, 400, 50, 0, 760}, - {1, 1, 1716, 525, 1270, 350, 50, 0, 640}, - {1, 1, 1716, 525, 1270, 400, 0, 0, 720}, - {1, 1, 1716, 525, 1270, 350, 0, 0, 720}, - {1, 1, 1716, 525, 1270, 480, 0, 0, 760}, -}; - -static const struct SiS_TVData XGI_ExtYPbPr750pData[] = { - { 3, 1, 935, 470, 1130, 680, 50, 0, 0}, /* 00 (320x200,320x400, - * 640x200,640x400) - */ - {24, 7, 935, 420, 1130, 680, 50, 0, 0}, /* 01 (320x350,640x350) */ - { 3, 1, 935, 470, 1130, 680, 50, 0, 0}, /* 02 (360x400,720x400) */ - {24, 7, 935, 420, 1130, 680, 50, 0, 0}, /* 03 (720x350) */ - { 2, 1, 1100, 590, 1130, 640, 50, 0, 0}, /* 04 (320x240,640x480) */ - { 3, 2, 1210, 690, 1130, 660, 50, 0, 0}, /* 05 (400x300,800x600) */ - { 1, 1, 1375, 878, 1130, 640, 638, 0, 0}, /* 06 (1024x768) */ - { 2, 1, 858, 503, 1130, 480, 0, 1, 0}, /* 07 (720x480) */ - { 5, 4, 1815, 570, 1130, 660, 50, 0, 0}, - { 5, 3, 1100, 686, 1130, 640, 50, 1, 0}, - {10, 9, 1320, 830, 1130, 640, 50, 0, 0} -}; - -static const struct SiS_TVData XGI_StYPbPr750pData[] = { - {1, 1, 1650, 750, 1280, 400, 50, 0, 760}, - {1, 1, 1650, 750, 1280, 350, 50, 0, 640}, - {1, 1, 1650, 750, 1280, 400, 0, 0, 720}, - {1, 1, 1650, 750, 1280, 350, 0, 0, 720}, - {1, 1, 1650, 750, 1280, 480, 0, 0, 760}, -}; - -static const unsigned char XGI330_NTSCTiming[] = { - 0x17, 0x1d, 0x03, 0x09, 0x05, 0x06, 0x0c, 0x0c, - 0x94, 0x49, 0x01, 0x0a, 0x06, 0x0d, 0x04, 0x0a, - 0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x1b, - 0x0c, 0x50, 0x00, 0x97, 0x00, 0xda, 0x4a, 0x17, - 0x7d, 0x05, 0x4b, 0x00, 0x00, 0xe2, 0x00, 0x02, - 0x03, 0x0a, 0x65, 0x9d, 0x08, 0x92, 0x8f, 0x40, - 0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x50, - 0x00, 0x40, 0x44, 0x00, 0xdb, 0x02, 0x3b, 0x00 -}; - -static const unsigned char XGI330_PALTiming[] = { - 0x21, 0x5A, 0x35, 0x6e, 0x04, 0x38, 0x3d, 0x70, - 0x94, 0x49, 0x01, 0x12, 0x06, 0x3e, 0x35, 0x6d, - 0x06, 0x14, 0x3e, 0x35, 0x6d, 0x00, 0x45, 0x2b, - 0x70, 0x50, 0x00, 0x9b, 0x00, 0xd9, 0x5d, 0x17, - 0x7d, 0x05, 0x45, 0x00, 0x00, 0xe8, 0x00, 0x02, - 0x0d, 0x00, 0x68, 0xb0, 0x0b, 0x92, 0x8f, 0x40, - 0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x63, - 0x00, 0x40, 0x3e, 0x00, 0xe1, 0x02, 0x28, 0x00 -}; - -static const unsigned char XGI330_HiTVExtTiming[] = { - 0x2D, 0x60, 0x2C, 0x5F, 0x08, 0x31, 0x3A, 0x64, - 0x28, 0x02, 0x01, 0x3D, 0x06, 0x3E, 0x35, 0x6D, - 0x06, 0x14, 0x3E, 0x35, 0x6D, 0x00, 0xC5, 0x3F, - 0x64, 0x90, 0x33, 0x8C, 0x18, 0x36, 0x3E, 0x13, - 0x2A, 0xDE, 0x2A, 0x44, 0x40, 0x2A, 0x44, 0x40, - 0x8E, 0x8E, 0x82, 0x07, 0x0B, - 0x92, 0x0F, 0x40, 0x60, 0x80, 0x14, 0x90, 0x8C, - 0x60, 0x14, 0x3D, 0x63, 0x4F, - 0x27, 0x00, 0xfc, 0xff, 0x6a, 0x00 -}; - -static const unsigned char XGI330_HiTVSt1Timing[] = { - 0x32, 0x65, 0x2C, 0x5F, 0x08, 0x31, 0x3A, 0x65, - 0x28, 0x02, 0x01, 0x3D, 0x06, 0x3E, 0x35, 0x6D, - 0x06, 0x14, 0x3E, 0x35, 0x6D, 0x00, 0xC5, 0x3F, - 0x65, 0x90, 0x7B, 0xA8, 0x03, 0xF0, 0x87, 0x03, - 0x11, 0x15, 0x11, 0xCF, 0x10, 0x11, 0xCF, 0x10, - 0x35, 0x35, 0x3B, 0x69, 0x1D, - 0x92, 0x0F, 0x40, 0x60, 0x80, 0x14, 0x90, 0x8C, - 0x60, 0x04, 0x86, 0xAF, 0x5D, - 0x0E, 0x00, 0xfc, 0xff, 0x2d, 0x00 -}; - -static const unsigned char XGI330_HiTVSt2Timing[] = { - 0x32, 0x65, 0x2C, 0x5F, 0x08, 0x31, 0x3A, 0x64, - 0x28, 0x02, 0x01, 0x3D, 0x06, 0x3E, 0x35, 0x6D, - 0x06, 0x14, 0x3E, 0x35, 0x6D, 0x00, 0xC5, 0x3F, - 0x64, 0x90, 0x33, 0x8C, 0x18, 0x36, 0x3E, 0x13, - 0x2A, 0xDE, 0x2A, 0x44, 0x40, 0x2A, 0x44, 0x40, - 0x8E, 0x8E, 0x82, 0x07, 0x0B, - 0x92, 0x0F, 0x40, 0x60, 0x80, 0x14, 0x90, 0x8C, - 0x60, 0x14, 0x3D, 0x63, 0x4F, - 0x27, 0x00, 0xFC, 0xff, 0x6a, 0x00 -}; - -static const unsigned char XGI330_HiTVTextTiming[] = { - 0x32, 0x65, 0x2C, 0x5F, 0x08, 0x31, 0x3A, 0x65, - 0x28, 0x02, 0x01, 0x3D, 0x06, 0x3E, 0x35, 0x6D, - 0x06, 0x14, 0x3E, 0x35, 0x6D, 0x00, 0xC5, 0x3F, - 0x65, 0x90, 0xE7, 0xBC, 0x03, 0x0C, 0x97, 0x03, - 0x14, 0x78, 0x14, 0x08, 0x20, 0x14, 0x08, 0x20, - 0xC8, 0xC8, 0x3B, 0xD2, 0x26, - 0x92, 0x0F, 0x40, 0x60, 0x80, 0x14, 0x90, 0x8C, - 0x60, 0x04, 0x96, 0x72, 0x5C, - 0x11, 0x00, 0xFC, 0xFF, 0x32, 0x00 -}; - -static const unsigned char XGI330_YPbPr750pTiming[] = { - 0x30, 0x1d, 0xe8, 0x09, 0x09, 0xed, 0x0c, 0x0c, - 0x98, 0x0a, 0x01, 0x0c, 0x06, 0x0d, 0x04, 0x0a, - 0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f, - 0xed, 0x50, 0x70, 0x9f, 0x16, 0x59, 0x60, 0x13, - 0x27, 0x0b, 0x27, 0xfc, 0x30, 0x27, 0x1c, 0xb0, - 0x4b, 0x4b, 0x6f, 0x2f, 0x63, - 0x92, 0x0F, 0x40, 0x60, 0x80, 0x14, 0x90, 0x8C, - 0x60, 0x14, 0x73, 0x00, 0x40, - 0x11, 0x00, 0xfc, 0xff, 0x32, 0x00 -}; - -static const unsigned char XGI330_YPbPr525pTiming[] = { - 0x3E, 0x11, 0x06, 0x09, 0x0b, 0x0c, 0x0c, 0x0c, - 0x98, 0x0a, 0x01, 0x0d, 0x06, 0x0d, 0x04, 0x0a, - 0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f, - 0x0c, 0x50, 0xb2, 0x9f, 0x16, 0x59, 0x4f, 0x13, - 0xad, 0x11, 0xad, 0x1d, 0x40, 0x8a, 0x3d, 0xb8, - 0x51, 0x5e, 0x60, 0x49, 0x7d, - 0x92, 0x0F, 0x40, 0x60, 0x80, 0x14, 0x90, 0x8C, - 0x60, 0x14, 0x4B, 0x43, 0x41, - 0x11, 0x00, 0xFC, 0xFF, 0x32, 0x00 -}; - -static const unsigned char XGI330_YPbPr525iTiming[] = { - 0x1B, 0x21, 0x03, 0x09, 0x05, 0x06, 0x0C, 0x0C, - 0x94, 0x49, 0x01, 0x0A, 0x06, 0x0D, 0x04, 0x0A, - 0x06, 0x14, 0x0D, 0x04, 0x0A, 0x00, 0x85, 0x1B, - 0x0C, 0x50, 0x00, 0x97, 0x00, 0xDA, 0x4A, 0x17, - 0x7D, 0x05, 0x4B, 0x00, 0x00, 0xE2, 0x00, 0x02, - 0x03, 0x0A, 0x65, 0x9D, 0x08, - 0x92, 0x8F, 0x40, 0x60, 0x80, 0x14, 0x90, 0x8C, - 0x60, 0x14, 0x4B, 0x00, 0x40, - 0x44, 0x00, 0xDB, 0x02, 0x3B, 0x00 -}; - -static const unsigned char XGI330_HiTVGroup3Data[] = { - 0x00, 0x1A, 0x22, 0x63, 0x62, 0x22, 0x08, 0x5F, - 0x05, 0x21, 0xB2, 0xB2, 0x55, 0x77, 0x2A, 0xA6, - 0x25, 0x2F, 0x47, 0xFA, 0xC8, 0xFF, 0x8E, 0x20, - 0x8C, 0x6E, 0x60, 0x2E, 0x58, 0x48, 0x72, 0x44, - 0x56, 0x36, 0x4F, 0x6E, 0x3F, 0x80, 0x00, 0x80, - 0x4F, 0x7F, 0x03, 0xA8, 0x7D, 0x20, 0x1A, 0xA9, - 0x14, 0x05, 0x03, 0x7E, 0x64, 0x31, 0x14, 0x75, - 0x18, 0x05, 0x18, 0x05, 0x4C, 0xA8, 0x01 -}; - -static const unsigned char XGI330_HiTVGroup3Simu[] = { - 0x00, 0x1A, 0x22, 0x63, 0x62, 0x22, 0x08, 0x95, - 0xDB, 0x20, 0xB8, 0xB8, 0x55, 0x47, 0x2A, 0xA6, - 0x25, 0x2F, 0x47, 0xFA, 0xC8, 0xFF, 0x8E, 0x20, - 0x8C, 0x6E, 0x60, 0x15, 0x26, 0xD3, 0xE4, 0x11, - 0x56, 0x36, 0x4F, 0x6E, 0x3F, 0x80, 0x00, 0x80, - 0x67, 0x36, 0x01, 0x47, 0x0E, 0x10, 0xBE, 0xB4, - 0x01, 0x05, 0x03, 0x7E, 0x65, 0x31, 0x14, 0x75, - 0x18, 0x05, 0x18, 0x05, 0x4C, 0xA8, 0x01 -}; - -static const unsigned char XGI330_HiTVGroup3Text[] = { - 0x00, 0x1A, 0x22, 0x63, 0x62, 0x22, 0x08, 0xA7, - 0xF5, 0x20, 0xCE, 0xCE, 0x55, 0x47, 0x2A, 0xA6, - 0x25, 0x2F, 0x47, 0xFA, 0xC8, 0xFF, 0x8E, 0x20, - 0x8C, 0x6E, 0x60, 0x18, 0x2C, 0x0C, 0x20, 0x22, - 0x56, 0x36, 0x4F, 0x6E, 0x3F, 0x80, 0x00, 0x80, - 0x93, 0x3C, 0x01, 0x50, 0x2F, 0x10, 0xF4, 0xCA, - 0x01, 0x05, 0x03, 0x7E, 0x65, 0x31, 0x14, 0x75, - 0x18, 0x05, 0x18, 0x05, 0x4C, 0xA8, 0x01 -}; - -static const unsigned char XGI330_Ren525pGroup3[] = { - 0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x13, - 0xB1, 0x41, 0x62, 0x62, 0xFF, 0xF4, 0x45, 0xa6, - 0x25, 0x2F, 0x67, 0xF6, 0xbf, 0xFF, 0x8E, 0x20, - 0xAC, 0xDA, 0x60, 0xFe, 0x6A, 0x9A, 0x06, 0x10, - 0xd1, 0x04, 0x18, 0x0a, 0xFF, 0x80, 0x00, 0x80, - 0x3c, 0x77, 0x00, 0xEF, 0xE0, 0x10, 0xB0, 0xE0, - 0x10, 0x4F, 0x0F, 0x0F, 0x05, 0x0F, 0x08, 0x6E, - 0x1a, 0x1F, 0x25, 0x2a, 0x4C, 0xAA, 0x01 -}; - -static const unsigned char XGI330_Ren750pGroup3[] = { - 0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x7a, - 0x54, 0x41, 0xE7, 0xE7, 0xFF, 0xF4, 0x45, 0xa6, - 0x25, 0x2F, 0x67, 0xF6, 0xbf, 0xFF, 0x8E, 0x20, - 0xAC, 0x6A, 0x60, 0x2b, 0x52, 0xCD, 0x61, 0x10, - 0x51, 0x04, 0x18, 0x0a, 0x1F, 0x80, 0x00, 0x80, - 0xFF, 0xA4, 0x04, 0x2B, 0x94, 0x21, 0x72, 0x94, - 0x26, 0x05, 0x01, 0x0F, 0xed, 0x0F, 0x0A, 0x64, - 0x18, 0x1D, 0x23, 0x28, 0x4C, 0xAA, 0x01 -}; - -static const struct SiS_LVDSData XGI_LVDS1024x768Data_1[] = { - { 960, 438, 1344, 806}, /* 00 (320x200,320x400,640x200,640x400) */ - { 960, 388, 1344, 806}, /* 01 (320x350,640x350) */ - {1040, 438, 1344, 806}, /* 02 (360x400,720x400) */ - {1040, 388, 1344, 806}, /* 03 (720x350) */ - { 960, 518, 1344, 806}, /* 04 (320x240,640x480) */ - {1120, 638, 1344, 806}, /* 05 (400x300,800x600) */ - {1344, 806, 1344, 806} /* 06 (512x384,1024x768) */ -}; - -static const struct SiS_LVDSData XGI_LVDS1024x768Data_2[] = { - {1344, 806, 1344, 806}, - {1344, 806, 1344, 806}, - {1344, 806, 1344, 806}, - {1344, 806, 1344, 806}, - {1344, 806, 1344, 806}, - {1344, 806, 1344, 806}, - {1344, 806, 1344, 806}, - {800, 449, 1280, 801}, - {800, 525, 1280, 813} -}; - -static const struct SiS_LVDSData XGI_LVDS1280x1024Data_1[] = { - {1048, 442, 1688, 1066}, - {1048, 392, 1688, 1066}, - {1048, 442, 1688, 1066}, - {1048, 392, 1688, 1066}, - {1048, 522, 1688, 1066}, - {1208, 642, 1688, 1066}, - {1432, 810, 1688, 1066}, - {1688, 1066, 1688, 1066} -}; - -#define XGI_LVDS1280x1024Data_2 XGI_LVDS1024x768Data_2 - -static const struct SiS_LVDSData XGI_LVDS1400x1050Data_1[] = { - {928, 416, 1688, 1066}, - {928, 366, 1688, 1066}, - {928, 416, 1688, 1066}, - {928, 366, 1688, 1066}, - {928, 496, 1688, 1066}, - {1088, 616, 1688, 1066}, - {1312, 784, 1688, 1066}, - {1568, 1040, 1688, 1066}, - {1688, 1066, 1688, 1066} -}; - -static const struct SiS_LVDSData XGI_LVDS1400x1050Data_2[] = { - {1688, 1066, 1688, 1066}, - {1688, 1066, 1688, 1066}, - {1688, 1066, 1688, 1066}, - {1688, 1066, 1688, 1066}, - {1688, 1066, 1688, 1066}, - {1688, 1066, 1688, 1066}, - {1688, 1066, 1688, 1066}, - {1688, 1066, 1688, 1066}, - {1688, 1066, 1688, 1066} -}; - -/* ;;[ycchen] 12/05/02 LCDHTxLCDVT=2048x1320 */ -static const struct SiS_LVDSData XGI_LVDS1600x1200Data_1[] = { - {1088, 520, 2048, 1320}, /* 00 (320x200,320x400,640x200,640x400) */ - {1088, 470, 2048, 1320}, /* 01 (320x350,640x350) */ - {1088, 520, 2048, 1320}, /* 02 (360x400,720x400) */ - {1088, 470, 2048, 1320}, /* 03 (720x350) */ - {1088, 600, 2048, 1320}, /* 04 (320x240,640x480) */ - {1248, 720, 2048, 1320}, /* 05 (400x300,800x600) */ - {1472, 888, 2048, 1320}, /* 06 (512x384,1024x768) */ - {1728, 1144, 2048, 1320}, /* 07 (640x512,1280x1024) */ - {1848, 1170, 2048, 1320}, /* 08 (1400x1050) */ - {2048, 1320, 2048, 1320} /* 09 (1600x1200) */ -}; - -static const struct SiS_LVDSData XGI_LVDSNoScalingData[] = { - { 800, 449, 800, 449}, /* 00 (320x200,320x400,640x200,640x400) */ - { 800, 449, 800, 449}, /* 01 (320x350,640x350) */ - { 800, 449, 800, 449}, /* 02 (360x400,720x400) */ - { 800, 449, 800, 449}, /* 03 (720x350) */ - { 800, 525, 800, 525}, /* 04 (640x480x60Hz) */ - {1056, 628, 1056, 628}, /* 05 (800x600x60Hz) */ - {1344, 806, 1344, 806}, /* 06 (1024x768x60Hz) */ - {1688, 1066, 1688, 1066}, /* 07 (1280x1024x60Hz) */ - {1688, 1066, 1688, 1066}, /* 08 (1400x1050x60Hz) */ - {2160, 1250, 2160, 1250}, /* 09 (1600x1200x60Hz) */ - {1688, 806, 1688, 806} /* 0A (1280x768x60Hz) */ -}; - -static const struct SiS_LVDSData XGI_LVDS1024x768Data_1x75[] = { - { 960, 438, 1312, 800}, /* 00 (320x200,320x400,640x200,640x400) */ - { 960, 388, 1312, 800}, /* 01 (320x350,640x350) */ - {1040, 438, 1312, 800}, /* 02 (360x400,720x400) */ - {1040, 388, 1312, 800}, /* 03 (720x350) */ - { 928, 512, 1312, 800}, /* 04 (320x240,640x480) */ - {1088, 632, 1312, 800}, /* 05 (400x300,800x600) */ - {1312, 800, 1312, 800}, /* 06 (512x384,1024x768) */ -}; - -static const struct SiS_LVDSData XGI_LVDS1024x768Data_2x75[] = { - {1312, 800, 1312, 800}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {1312, 800, 1312, 800}, /* ; 01 (320x350,640x350) */ - {1312, 800, 1312, 800}, /* ; 02 (360x400,720x400) */ - {1312, 800, 1312, 800}, /* ; 03 (720x350) */ - {1312, 800, 1312, 800}, /* ; 04 (320x240,640x480) */ - {1312, 800, 1312, 800}, /* ; 05 (400x300,800x600) */ - {1312, 800, 1312, 800}, /* ; 06 (512x384,1024x768) */ -}; - -static const struct SiS_LVDSData XGI_LVDS1280x1024Data_1x75[] = { - {1048, 442, 1688, 1066 }, /* ; 00 (320x200,320x400,640x200,640x400) */ - {1048, 392, 1688, 1066 }, /* ; 01 (320x350,640x350) */ - {1128, 442, 1688, 1066 }, /* ; 02 (360x400,720x400) */ - {1128, 392, 1688, 1066 }, /* ; 03 (720x350) */ - {1048, 522, 1688, 1066 }, /* ; 04 (320x240,640x480) */ - {1208, 642, 1688, 1066 }, /* ; 05 (400x300,800x600) */ - {1432, 810, 1688, 1066 }, /* ; 06 (512x384,1024x768) */ - {1688, 1066, 1688, 1066 }, /* ; 06; 07 (640x512,1280x1024) */ -}; - -static const struct SiS_LVDSData XGI_LVDS1280x1024Data_2x75[] = { - {1688, 1066, 1688, 1066 }, /* ; 00 (320x200,320x400,640x200,640x400) */ - {1688, 1066, 1688, 1066 }, /* ; 01 (320x350,640x350) */ - {1688, 1066, 1688, 1066 }, /* ; 02 (360x400,720x400) */ - {1688, 1066, 1688, 1066 }, /* ; 03 (720x350) */ - {1688, 1066, 1688, 1066 }, /* ; 04 (320x240,640x480) */ - {1688, 1066, 1688, 1066 }, /* ; 05 (400x300,800x600) */ - {1688, 1066, 1688, 1066 }, /* ; 06 (512x384,1024x768) */ - {1688, 1066, 1688, 1066 }, /* ; 06; 07 (640x512,1280x1024) */ -}; - -static const struct SiS_LVDSData XGI_LVDSNoScalingDatax75[] = { - { 800, 449, 800, 449}, /* ; 00 (320x200,320x400,640x200,640x400) */ - { 800, 449, 800, 449}, /* ; 01 (320x350,640x350) */ - { 900, 449, 900, 449}, /* ; 02 (360x400,720x400) */ - { 900, 449, 900, 449}, /* ; 03 (720x350) */ - { 800, 500, 800, 500}, /* ; 04 (640x480x75Hz) */ - {1056, 625, 1056, 625}, /* ; 05 (800x600x75Hz) */ - {1312, 800, 1312, 800}, /* ; 06 (1024x768x75Hz) */ - {1688, 1066, 1688, 1066}, /* ; 07 (1280x1024x75Hz) */ - {1688, 1066, 1688, 1066}, /* ; 08 (1400x1050x75Hz) - * ;;[ycchen] 12/19/02 - */ - {2160, 1250, 2160, 1250}, /* ; 09 (1600x1200x75Hz) */ - {1688, 806, 1688, 806}, /* ; 0A (1280x768x75Hz) */ -}; - -static const struct SiS_LVDSData XGI_LVDS1024x768Des_1[] = { - {0, 1048, 0, 771}, /* 00 (320x200,320x400,640x200,640x400) */ - {0, 1048, 0, 771}, /* 01 (320x350,640x350) */ - {0, 1048, 0, 771}, /* 02 (360x400,720x400) */ - {0, 1048, 0, 771}, /* 03 (720x350) */ - {0, 1048, 0, 771}, /* 04 (640x480x60Hz) */ - {0, 1048, 0, 771}, /* 05 (800x600x60Hz) */ - {0, 1048, 805, 770} /* 06 (1024x768x60Hz) */ -}; - -static const struct SiS_LVDSData XGI_LVDS1024x768Des_2[] = { - {1142, 856, 622, 587}, /* 00 (320x200,320x400,640x200,640x400) */ - {1142, 856, 597, 562}, /* 01 (320x350,640x350) */ - {1142, 856, 622, 587}, /* 02 (360x400,720x400) */ - {1142, 856, 597, 562}, /* 03 (720x350) */ - {1142, 1048, 722, 687}, /* 04 (640x480x60Hz) */ - {1232, 936, 722, 687}, /* 05 (800x600x60Hz) */ - { 0, 1048, 805, 771} /* 06 (1024x768x60Hz) */ -}; - -static const struct SiS_LVDSData XGI_LVDS1024x768Des_3[] = { - {320, 24, 622, 587}, /* 00 (320x200,320x400,640x200,640x400) */ - {320, 24, 597, 562}, /* 01 (320x350,640x350) */ - {320, 24, 622, 587}, /* 02 (360x400,720x400) */ - {320, 24, 597, 562}, /* 03 (720x350) */ - {320, 24, 722, 687} /* 04 (640x480x60Hz) */ -}; - -static const struct SiS_LVDSData XGI_LVDS1280x1024Des_1[] = { - {0, 1328, 0, 1025}, /* 00 (320x200,320x400,640x200,640x400) */ - {0, 1328, 0, 1025}, /* 01 (320x350,640x350) */ - {0, 1328, 0, 1025}, /* 02 (360x400,720x400) */ - {0, 1328, 0, 1025}, /* 03 (720x350) */ - {0, 1328, 0, 1025}, /* 04 (640x480x60Hz) */ - {0, 1328, 0, 1025}, /* 05 (800x600x60Hz) */ - {0, 1328, 0, 1025}, /* 06 (1024x768x60Hz) */ - {0, 1328, 1065, 1024} /* 07 (1280x1024x60Hz) */ -}; - - /* The Display setting for DE Mode Panel */ -static const struct SiS_LVDSData XGI_LVDS1280x1024Des_2[] = { - {1368, 1008, 752, 711}, /* 00 (320x200,320x400,640x200,640x400) */ - {1368, 1008, 729, 688}, /* 01 (320x350,640x350) */ - {1408, 1048, 752, 711}, /* 02 (360x400,720x400) */ - {1408, 1048, 729, 688}, /* 03 (720x350) */ - {1368, 1008, 794, 753}, /* 04 (640x480x60Hz) */ - {1448, 1068, 854, 813}, /* 05 (800x600x60Hz) */ - {1560, 1200, 938, 897}, /* 06 (1024x768x60Hz) */ - {0000, 1328, 0, 1025} /* 07 (1280x1024x60Hz) */ -}; - -static const struct SiS_LVDSData XGI_LVDS1400x1050Des_1[] = { - {0, 1448, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */ - {0, 1448, 0, 1051}, /* 01 (320x350,640x350) */ - {0, 1448, 0, 1051}, /* 02 (360x400,720x400) */ - {0, 1448, 0, 1051}, /* 03 (720x350) */ - {0, 1448, 0, 1051}, /* 04 (640x480x60Hz) */ - {0, 1448, 0, 1051}, /* 05 (800x600x60Hz) */ - {0, 1448, 0, 1051}, /* 06 (1024x768x60Hz) */ - {0, 1448, 0, 1051}, /* 07 (1280x1024x60Hz) */ - {0, 1448, 0, 1051} /* 08 (1400x1050x60Hz) */ -}; - -static const struct SiS_LVDSData XGI_LVDS1400x1050Des_2[] = { - {1308, 1068, 781, 766}, /* 00 (320x200,320x400,640x200,640x400) */ - {1308, 1068, 781, 766}, /* 01 (320x350,640x350) */ - {1308, 1068, 781, 766}, /* 02 (360x400,720x400) */ - {1308, 1068, 781, 766}, /* 03 (720x350) */ - {1308, 1068, 781, 766}, /* 04 (640x480x60Hz) */ - {1388, 1148, 841, 826}, /* 05 (800x600x60Hz) */ - {1490, 1250, 925, 910}, /* 06 (1024x768x60Hz) */ - {1608, 1368, 1053, 1038}, /* 07 (1280x1024x60Hz) */ - { 0, 1448, 0, 1051} /* 08 (1400x1050x60Hz) */ -}; - -static const struct SiS_LVDSData XGI_LVDS1600x1200Des_1[] = { - {0, 1664, 0, 1201}, /* 00 (320x200,320x400,640x200,640x400) */ - {0, 1664, 0, 1201}, /* 01 (320x350,640x350) */ - {0, 1664, 0, 1201}, /* 02 (360x400,720x400) */ - {0, 1664, 0, 1201}, /* 03 (720x350) */ - {0, 1664, 0, 1201}, /* 04 (640x480x60Hz) */ - {0, 1664, 0, 1201}, /* 05 (800x600x60Hz) */ - {0, 1664, 0, 1201}, /* 06 (1024x768x60Hz) */ - {0, 1664, 0, 1201}, /* 07 (1280x1024x60Hz) */ - {0, 1664, 0, 1201}, /* 08 (1400x1050x60Hz) */ - {0, 1664, 0, 1201} /* 09 (1600x1200x60Hz) */ -}; - -static const struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesData[] = { - {0, 648, 448, 405, 96, 2}, /* 00 (320x200,320x400, - * 640x200,640x400) - */ - {0, 648, 448, 355, 96, 2}, /* 01 (320x350,640x350) */ - {0, 648, 448, 405, 96, 2}, /* 02 (360x400,720x400) */ - {0, 648, 448, 355, 96, 2}, /* 03 (720x350) */ - {0, 648, 1, 483, 96, 2}, /* 04 (640x480x60Hz) */ - {0, 840, 627, 600, 128, 4}, /* 05 (800x600x60Hz) */ - {0, 1048, 805, 770, 136, 6}, /* 06 (1024x768x60Hz) */ - {0, 1328, 0, 1025, 112, 3}, /* 07 (1280x1024x60Hz) */ - {0, 1438, 0, 1051, 112, 3}, /* 08 (1400x1050x60Hz)*/ - {0, 1664, 0, 1201, 192, 3}, /* 09 (1600x1200x60Hz) */ - {0, 1328, 0, 0771, 112, 6} /* 0A (1280x768x60Hz) */ -}; - -/* ; 1024x768 Full-screen */ -static const struct SiS_LVDSData XGI_LVDS1024x768Des_1x75[] = { - {0, 1040, 0, 769}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {0, 1040, 0, 769}, /* ; 01 (320x350,640x350) */ - {0, 1040, 0, 769}, /* ; 02 (360x400,720x400) */ - {0, 1040, 0, 769}, /* ; 03 (720x350) */ - {0, 1040, 0, 769}, /* ; 04 (640x480x75Hz) */ - {0, 1040, 0, 769}, /* ; 05 (800x600x75Hz) */ - {0, 1040, 0, 769} /* ; 06 (1024x768x75Hz) */ -}; - -/* ; 1024x768 center-screen (Enh. Mode) */ -static const struct SiS_LVDSData XGI_LVDS1024x768Des_2x75[] = { - {1142, 856, 622, 587}, /* 00 (320x200,320x400,640x200,640x400) */ - {1142, 856, 597, 562}, /* 01 (320x350,640x350) */ - {1142, 856, 622, 587}, /* 02 (360x400,720x400) */ - {1142, 856, 597, 562}, /* 03 (720x350) */ - {1142, 1048, 722, 687}, /* 04 (640x480x60Hz) */ - {1232, 936, 722, 687}, /* 05 (800x600x60Hz) */ - { 0, 1048, 805, 771} /* 06 (1024x768x60Hz) */ -}; - -/* ; 1024x768 center-screen (St.Mode) */ -static const struct SiS_LVDSData XGI_LVDS1024x768Des_3x75[] = { - {320, 24, 622, 587}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {320, 24, 597, 562}, /* ; 01 (320x350,640x350) */ - {320, 24, 622, 587}, /* ; 02 (360x400,720x400) */ - {320, 24, 597, 562}, /* ; 03 (720x350) */ - {320, 24, 722, 687} /* ; 04 (640x480x60Hz) */ -}; - -static const struct SiS_LVDSData XGI_LVDS1280x1024Des_1x75[] = { - {0, 1296, 0, 1025}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {0, 1296, 0, 1025}, /* ; 01 (320x350,640x350) */ - {0, 1296, 0, 1025}, /* ; 02 (360x400,720x400) */ - {0, 1296, 0, 1025}, /* ; 03 (720x350) */ - {0, 1296, 0, 1025}, /* ; 04 (640x480x75Hz) */ - {0, 1296, 0, 1025}, /* ; 05 (800x600x75Hz) */ - {0, 1296, 0, 1025}, /* ; 06 (1024x768x75Hz) */ - {0, 1296, 0, 1025} /* ; 07 (1280x1024x75Hz) */ -}; - -/* The Display setting for DE Mode Panel */ -/* Set DE as default */ -static const struct SiS_LVDSData XGI_LVDS1280x1024Des_2x75[] = { - {1368, 976, 752, 711}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {1368, 976, 729, 688}, /* ; 01 (320x350,640x350) */ - {1408, 976, 752, 711}, /* ; 02 (360x400,720x400) */ - {1408, 976, 729, 688}, /* ; 03 (720x350) */ - {1368, 976, 794, 753}, /* ; 04 (640x480x75Hz) */ - {1448, 1036, 854, 813}, /* ; 05 (800x600x75Hz) */ - {1560, 1168, 938, 897}, /* ; 06 (1024x768x75Hz) */ - { 0, 1296, 0, 1025} /* ; 07 (1280x1024x75Hz) */ -}; - -/* Scaling LCD 75Hz */ -static const struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesDatax75[] = { - {0, 648, 448, 405, 96, 2}, /* ; 00 (320x200,320x400, - * 640x200,640x400) - */ - {0, 648, 448, 355, 96, 2}, /* ; 01 (320x350,640x350) */ - {0, 729, 448, 405, 108, 2}, /* ; 02 (360x400,720x400) */ - {0, 729, 448, 355, 108, 2}, /* ; 03 (720x350) */ - {0, 656, 0, 481, 64, 3}, /* ; 04 (640x480x75Hz) */ - {0, 816, 0, 601, 80, 3}, /* ; 05 (800x600x75Hz) */ - {0, 1040, 0, 769, 96, 3}, /* ; 06 (1024x768x75Hz) */ - {0, 1296, 0, 1025, 144, 3}, /* ; 07 (1280x1024x75Hz) */ - {0, 1448, 0, 1051, 112, 3}, /* ; 08 (1400x1050x75Hz) */ - {0, 1664, 0, 1201, 192, 3}, /* ; 09 (1600x1200x75Hz) */ - {0, 1328, 0, 771, 112, 6} /* ; 0A (1280x768x75Hz) */ -}; - -/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_H[] = { - { {0x4B, 0x27, 0x8F, 0x32, 0x1B, 0x00, 0x45, 0x00} }, /* 00 (320x) */ - { {0x4B, 0x27, 0x8F, 0x2B, 0x03, 0x00, 0x44, 0x00} }, /* 01 (360x) */ - { {0x55, 0x31, 0x99, 0x46, 0x1D, 0x00, 0x55, 0x00} }, /* 02 (400x) */ - { {0x63, 0x3F, 0x87, 0x4A, 0x93, 0x00, 0x01, 0x00} }, /* 03 (512x) */ - { {0x73, 0x4F, 0x97, 0x55, 0x86, 0x00, 0x05, 0x00} }, /* 04 (640x) */ - { {0x73, 0x4F, 0x97, 0x55, 0x86, 0x00, 0x05, 0x00} }, /* 05 (720x) */ - { {0x87, 0x63, 0x8B, 0x69, 0x1A, 0x00, 0x26, 0x00} }, /* 06 (800x) */ - { {0xA3, 0x7F, 0x87, 0x86, 0x97, 0x00, 0x02, 0x00} } /* 07 (1024x) */ -}; - -/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_H[] = { - { {0x56, 0x27, 0x9A, 0x30, 0x1E, 0x00, 0x05, 0x00 } }, /* 00 (320x) */ - { {0x56, 0x27, 0x9A, 0x30, 0x1E, 0x00, 0x05, 0x00 } }, /* 01 (360x) */ - { {0x60, 0x31, 0x84, 0x3A, 0x88, 0x00, 0x01, 0x00 } }, /* 02 (400x) */ - { {0x6E, 0x3F, 0x92, 0x48, 0x96, 0x00, 0x01, 0x00 } }, /* 03 (512x) */ - { {0x7E, 0x4F, 0x82, 0x58, 0x06, 0x00, 0x06, 0x00 } }, /* 04 (640x) */ - { {0x7E, 0x4F, 0x82, 0x58, 0x06, 0x00, 0x06, 0x00 } }, /* 05 (720x) */ - { {0x92, 0x63, 0x96, 0x6C, 0x1A, 0x00, 0x06, 0x00 } }, /* 06 (800x) */ - { {0xAE, 0x7F, 0x92, 0x88, 0x96, 0x00, 0x02, 0x00 } }, /* 07 (1024x) */ - { {0xCE, 0x9F, 0x92, 0xA8, 0x16, 0x00, 0x07, 0x00 } } /* 08 (1280x) */ -}; - -/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_H[] = { - { {0x63, 0x27, 0x87, 0x3B, 0x8C, 0x00, 0x01, 0x00} }, /* 00 (320x) */ - { {0x63, 0x27, 0x87, 0x3B, 0x8C, 0x00, 0x01, 0x00} }, /* 01 (360x) */ - { {0x63, 0x31, 0x87, 0x3D, 0x8E, 0x00, 0x01, 0x00} }, /* 02 (400x) */ - { {0x63, 0x3F, 0x87, 0x45, 0x96, 0x00, 0x01, 0x00} }, /* 03 (512x) */ - { {0xA3, 0x4F, 0x87, 0x6E, 0x9F, 0x00, 0x06, 0x00} }, /* 04 (640x) */ - { {0xA3, 0x4F, 0x87, 0x6E, 0x9F, 0x00, 0x06, 0x00} }, /* 05 (720x) */ - { {0xA3, 0x63, 0x87, 0x78, 0x89, 0x00, 0x02, 0x00} }, /* 06 (800x) */ - { {0xA3, 0x7F, 0x87, 0x86, 0x97, 0x00, 0x02, 0x00} } /* 07 (1024x) */ -}; - -/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_H[] = { - { {0x7E, 0x3B, 0x9A, 0x44, 0x12, 0x00, 0x01, 0x00} }, /* 00 (320x) */ - { {0x7E, 0x3B, 0x9A, 0x44, 0x12, 0x00, 0x01, 0x00} }, /* 01 (360x) */ - { {0x7E, 0x40, 0x84, 0x49, 0x91, 0x00, 0x01, 0x00} }, /* 02 (400x) */ - { {0x7E, 0x47, 0x93, 0x50, 0x9E, 0x00, 0x01, 0x00} }, /* 03 (512x) */ - { {0xCE, 0x77, 0x8A, 0x80, 0x8E, 0x00, 0x02, 0x00} }, /* 04 (640x) */ - { {0xCE, 0x77, 0x8A, 0x80, 0x8E, 0x00, 0x02, 0x00} }, /* 05 (720x) */ - { {0xCE, 0x81, 0x94, 0x8A, 0x98, 0x00, 0x02, 0x00} }, /* 06 (800x) */ - { {0xCE, 0x8F, 0x82, 0x98, 0x06, 0x00, 0x07, 0x00} }, /* 07 (1024x) */ - { {0xCE, 0x9F, 0x92, 0xA8, 0x16, 0x00, 0x07, 0x00} } /* 08 (1280x) */ -}; - -/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_1_H[] = { - { {0x47, 0x27, 0x8B, 0x2C, 0x1A, 0x00, 0x05, 0x00} }, /* 00 (320x) */ - { {0x47, 0x27, 0x8B, 0x30, 0x1E, 0x00, 0x05, 0x00} }, /* 01 (360x) */ - { {0x51, 0x31, 0x95, 0x36, 0x04, 0x00, 0x01, 0x00} }, /* 02 (400x) */ - { {0x5F, 0x3F, 0x83, 0x44, 0x92, 0x00, 0x01, 0x00} }, /* 03 (512x) */ - { {0x6F, 0x4F, 0x93, 0x54, 0x82, 0x00, 0x05, 0x00} }, /* 04 (640x) */ - { {0x6F, 0x4F, 0x93, 0x54, 0x82, 0x00, 0x05, 0x00} }, /* 05 (720x) */ - { {0x83, 0x63, 0x87, 0x68, 0x16, 0x00, 0x06, 0x00} }, /* 06 (800x) */ - { {0x9F, 0x7F, 0x83, 0x84, 0x92, 0x00, 0x02, 0x00} }, /* 07 (1024x) */ - { {0xBF, 0x9F, 0x83, 0xA4, 0x12, 0x00, 0x07, 0x00} }, /* 08 (1280x) */ - { {0xCE, 0xAE, 0x92, 0xB3, 0x01, 0x00, 0x03, 0x00} } /* 09 (1400x) */ -}; - -/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_2_H[] = { - { {0x76, 0x3F, 0x83, 0x45, 0x8C, 0x00, 0x41, 0x00} }, /* 00 (320x) */ - { {0x76, 0x3F, 0x83, 0x45, 0x8C, 0x00, 0x41, 0x00} }, /* 01 (360x) */ - { {0x76, 0x31, 0x9A, 0x48, 0x9F, 0x00, 0x41, 0x00} }, /* 02 (400x) */ - { {0x76, 0x3F, 0x9A, 0x4F, 0x96, 0x00, 0x41, 0x00} }, /* 03 (512x) */ - { {0xCE, 0x7E, 0x82, 0x87, 0x9E, 0x00, 0x02, 0x00} }, /* 04 (640x) */ - { {0xCE, 0x7E, 0x82, 0x87, 0x9E, 0x00, 0x02, 0x00} }, /* 05 (720x) */ - { {0xCE, 0x63, 0x92, 0x96, 0x04, 0x00, 0x07, 0x00} }, /* 06 (800x) */ - { {0xCE, 0x7F, 0x92, 0xA4, 0x12, 0x00, 0x07, 0x00} }, /* 07 (1024x) */ - { {0xCE, 0x9F, 0x92, 0xB4, 0x02, 0x00, 0x03, 0x00} }, /* 08 (1280x) */ - { {0xCE, 0xAE, 0x92, 0xBC, 0x0A, 0x00, 0x03, 0x00} } /* 09 (1400x) */ -}; - -/* ;302lv channelA [ycchen] 12/05/02 LCDHT=2048 */ -/* ; CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11600x1200_1_H[] = { - { {0x5B, 0x27, 0x9F, 0x32, 0x0A, 0x00, 0x01, 0x00} }, /* 00 (320x) */ - { {0x5B, 0x27, 0x9F, 0x32, 0x0A, 0x00, 0x01, 0x00} }, /* 01 (360x) */ - { {0x65, 0x31, 0x89, 0x3C, 0x94, 0x00, 0x01, 0x00} }, /* 02 (400x) */ - { {0x73, 0x3F, 0x97, 0x4A, 0x82, 0x00, 0x05, 0x00} }, /* 03 (512x) */ - { {0x83, 0x4F, 0x87, 0x51, 0x09, 0x00, 0x06, 0x00} }, /* 04 (640x) */ - { {0x83, 0x4F, 0x87, 0x51, 0x09, 0x00, 0x06, 0x00} }, /* 05 (720x) */ - { {0x97, 0x63, 0x9B, 0x65, 0x1D, 0x00, 0x06, 0xF0} }, /* 06 (800x) */ - { {0xB3, 0x7F, 0x97, 0x81, 0x99, 0x00, 0x02, 0x00} }, /* 07 (1024x) */ - { {0xD3, 0x9F, 0x97, 0xA1, 0x19, 0x00, 0x07, 0x00} }, /* 08 (1280x) */ - { {0xE2, 0xAE, 0x86, 0xB9, 0x91, 0x00, 0x03, 0x00} }, /* 09 (1400x) */ - { {0xFB, 0xC7, 0x9F, 0xC9, 0x81, 0x00, 0x07, 0x00} } /* 0A (1600x) */ -}; - -/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */ -static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_V[] = { - { {0x97, 0x1F, 0x60, 0x87, 0x5D, 0x83, 0x10} }, /* 00 (x350) */ - { {0xB4, 0x1F, 0x92, 0x89, 0x8F, 0xB5, 0x30} }, /* 01 (x400) */ - { {0x04, 0x3E, 0xE2, 0x89, 0xDF, 0x05, 0x00} }, /* 02 (x480) */ - { {0x7C, 0xF0, 0x5A, 0x8F, 0x57, 0x7D, 0xA0} }, /* 03 (x600) */ - { {0x24, 0xF5, 0x02, 0x88, 0xFF, 0x25, 0x90} } /* 04 (x768) */ -}; - -/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */ -static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_V[] = { - { {0x24, 0xBB, 0x31, 0x87, 0x5D, 0x25, 0x30} }, /* 00 (x350) */ - { {0x24, 0xBB, 0x4A, 0x80, 0x8F, 0x25, 0x30} }, /* 01 (x400) */ - { {0x24, 0xBB, 0x72, 0x88, 0xDF, 0x25, 0x30} }, /* 02 (x480) */ - { {0x24, 0xF1, 0xAE, 0x84, 0x57, 0x25, 0xB0} }, /* 03 (x600) */ - { {0x24, 0xF5, 0x02, 0x88, 0xFF, 0x25, 0x90} } /* 04 (x768) */ -}; - -/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */ -static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_V[] = { - { {0x86, 0x1F, 0x5E, 0x82, 0x5D, 0x87, 0x00} }, /* 00 (x350) */ - { {0xB8, 0x1F, 0x90, 0x84, 0x8F, 0xB9, 0x30} }, /* 01 (x400) */ - { {0x08, 0x3E, 0xE0, 0x84, 0xDF, 0x09, 0x00} }, /* 02 (x480) */ - { {0x80, 0xF0, 0x58, 0x8C, 0x57, 0x81, 0xA0} }, /* 03 (x600) */ - { {0x28, 0xF5, 0x00, 0x84, 0xFF, 0x29, 0x90} }, /* 04 (x768) */ - { {0x28, 0x5A, 0x13, 0x87, 0xFF, 0x29, 0xA9} } /* 05 (x1024) */ -}; - -/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */ -static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_V[] = { - { {0x28, 0xD2, 0xAF, 0x83, 0xAE, 0xD8, 0xA1} }, /* 00 (x350) */ - { {0x28, 0xD2, 0xC8, 0x8C, 0xC7, 0xF2, 0x81} }, /* 01 (x400) */ - { {0x28, 0xD2, 0xF0, 0x84, 0xEF, 0x1A, 0xB1} }, /* 02 (x480) */ - { {0x28, 0xDE, 0x2C, 0x8F, 0x2B, 0x56, 0x91} }, /* 03 (x600) */ - { {0x28, 0xDE, 0x80, 0x83, 0x7F, 0xAA, 0x91} }, /* 04 (x768) */ - { {0x28, 0x5A, 0x13, 0x87, 0xFF, 0x29, 0xA9} } /* 05 (x1024) */ -}; - -/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */ -static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_1_V[] = { - { {0x6C, 0x1F, 0x60, 0x84, 0x5D, 0x6D, 0x10} }, /* 00 (x350) */ - { {0x9E, 0x1F, 0x93, 0x86, 0x8F, 0x9F, 0x30} }, /* 01 (x400) */ - { {0xEE, 0x1F, 0xE2, 0x86, 0xDF, 0xEF, 0x10} }, /* 02 (x480) */ - { {0x66, 0xF0, 0x5A, 0x8e, 0x57, 0x67, 0xA0} }, /* 03 (x600) */ - { {0x0E, 0xF5, 0x02, 0x86, 0xFF, 0x0F, 0x90} }, /* 04 (x768) */ - { {0x0E, 0x5A, 0x02, 0x86, 0xFF, 0x0F, 0x89} }, /* 05 (x1024) */ - { {0x28, 0x10, 0x1A, 0x80, 0x19, 0x29, 0x0F} } /* 06 (x1050) */ -}; - -/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */ -static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_2_V[] = { - { {0x28, 0x92, 0xB6, 0x83, 0xB5, 0xCF, 0x81} }, /* 00 (x350) */ - { {0x28, 0x92, 0xD5, 0x82, 0xD4, 0xEE, 0x81} }, /* 01 (x400) */ - { {0x28, 0x92, 0xFD, 0x8A, 0xFC, 0x16, 0xB1} }, /* 02 (x480) */ - { {0x28, 0xD4, 0x39, 0x86, 0x57, 0x29, 0x81} }, /* 03 (x600) */ - { {0x28, 0xD4, 0x8D, 0x9A, 0xFF, 0x29, 0xA1} }, /* 04 (x768) */ - { {0x28, 0x5A, 0x0D, 0x9A, 0xFF, 0x29, 0xA9} }, /* 05 (x1024) */ - { {0x28, 0x10, 0x1A, 0x87, 0x19, 0x29, 0x8F} } /* 06 (x1050) */ -}; - -/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */ -static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11600x1200_1_V[] = { - { {0xd4, 0x1F, 0x81, 0x84, 0x5D, 0xd5, 0x10} }, /* 00 (x350) */ - { {0x06, 0x3e, 0xb3, 0x86, 0x8F, 0x07, 0x20} }, /* 01 (x400) */ - { {0x56, 0xba, 0x03, 0x86, 0xDF, 0x57, 0x00} }, /* 02 (x480) */ - { {0xce, 0xF0, 0x7b, 0x8e, 0x57, 0xcf, 0xa0} }, /* 03 (x600) */ - { {0x76, 0xF5, 0x23, 0x86, 0xFF, 0x77, 0x90} }, /* 04 (x768) */ - { {0x76, 0x5A, 0x23, 0x86, 0xFF, 0x77, 0x89} }, /* 05 (x1024) */ - { {0x90, 0x10, 0x1A, 0x8E, 0x19, 0x91, 0x2F} }, /* 06 (x1050) */ - { {0x26, 0x11, 0xd3, 0x86, 0xaF, 0x27, 0x3f} } /* 07 (x1200) */ -}; - -/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_Hx75[] = { - { {0x4B, 0x27, 0x8F, 0x32, 0x1B, 0x00, 0x45, 0x00} },/* ; 00 (320x) */ - { {0x4B, 0x27, 0x8F, 0x2B, 0x03, 0x00, 0x44, 0x00} },/* ; 01 (360x) */ - { {0x55, 0x31, 0x99, 0x46, 0x1D, 0x00, 0x55, 0x00} },/* ; 02 (400x) */ - { {0x63, 0x3F, 0x87, 0x4A, 0x93, 0x00, 0x01, 0x00} },/* ; 03 (512x) */ - { {0x6F, 0x4F, 0x93, 0x54, 0x80, 0x00, 0x05, 0x00} },/* ; 04 (640x) */ - { {0x6F, 0x4F, 0x93, 0x54, 0x80, 0x00, 0x05, 0x00} },/* ; 05 (720x) */ - { {0x83, 0x63, 0x87, 0x68, 0x14, 0x00, 0x26, 0x00} },/* ; 06 (800x) */ - { {0x9F, 0x7F, 0x83, 0x85, 0x91, 0x00, 0x02, 0x00} } /* ; 07 (1024x) */ -}; - -/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */ -static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_Vx75[] = { - { {0x97, 0x1F, 0x60, 0x87, 0x5D, 0x83, 0x10} },/* ; 00 (x350) */ - { {0xB4, 0x1F, 0x92, 0x89, 0x8F, 0xB5, 0x30} },/* ; 01 (x400) */ - { {0xFE, 0x1F, 0xE0, 0x84, 0xDF, 0xFF, 0x10} },/* ; 02 (x480) */ - { {0x76, 0xF0, 0x58, 0x8C, 0x57, 0x77, 0xA0} },/* ; 03 (x600) */ - { {0x1E, 0xF5, 0x00, 0x83, 0xFF, 0x1F, 0x90} } /* ; 04 (x768) */ -}; - -/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_Hx75[] = { - { {0x63, 0x27, 0x87, 0x3B, 0x8C, 0x00, 0x01, 0x00} },/* ; 00 (320x) */ - { {0x63, 0x27, 0x87, 0x3B, 0x8C, 0x00, 0x01, 0x00} },/* ; 01 (360x) */ - { {0x63, 0x31, 0x87, 0x3D, 0x8E, 0x00, 0x01, 0x00} },/* ; 02 (400x) */ - { {0x63, 0x3F, 0x87, 0x45, 0x96, 0x00, 0x01, 0x00} },/* ; 03 (512x) */ - { {0xA3, 0x4F, 0x87, 0x6E, 0x9F, 0x00, 0x06, 0x00} },/* ; 04 (640x) */ - { {0xA3, 0x4F, 0x87, 0x6E, 0x9F, 0x00, 0x06, 0x00} },/* ; 05 (720x) */ - { {0xA3, 0x63, 0x87, 0x78, 0x89, 0x00, 0x02, 0x00} },/* ; 06 (800x) */ - { {0xA3, 0x7F, 0x87, 0x86, 0x97, 0x00, 0x02, 0x00} } /* ; 07 (1024x) */ -}; - -/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */ -static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_Vx75[] = { - { {0x24, 0xBB, 0x31, 0x87, 0x5D, 0x25, 0x30} },/* ; 00 (x350) */ - { {0x24, 0xBB, 0x4A, 0x80, 0x8F, 0x25, 0x30} },/* ; 01 (x400) */ - { {0x24, 0xBB, 0x72, 0x88, 0xDF, 0x25, 0x30} },/* ; 02 (x480) */ - { {0x24, 0xF1, 0xAE, 0x84, 0x57, 0x25, 0xB0} },/* ; 03 (x600) */ - { {0x24, 0xF5, 0x02, 0x88, 0xFF, 0x25, 0x90} } /* ; 04 (x768) */ -}; - -/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_Hx75[] = { - { {0x56, 0x27, 0x9A, 0x30, 0x1E, 0x00, 0x05, 0x00} },/* ; 00 (320x) */ - { {0x56, 0x27, 0x9A, 0x30, 0x1E, 0x00, 0x05, 0x00} },/* ; 01 (360x) */ - { {0x60, 0x31, 0x84, 0x3A, 0x88, 0x00, 0x01, 0x00} },/* ; 02 (400x) */ - { {0x6E, 0x3F, 0x92, 0x48, 0x96, 0x00, 0x01, 0x00} },/* ; 03 (512x) */ - { {0x7E, 0x4F, 0x82, 0x54, 0x06, 0x00, 0x06, 0x00} },/* ; 04 (640x) */ - { {0x7E, 0x4F, 0x82, 0x54, 0x06, 0x00, 0x06, 0x00} },/* ; 05 (720x) */ - { {0x92, 0x63, 0x96, 0x68, 0x1A, 0x00, 0x06, 0x00} },/* ; 06 (800x) */ - { {0xAE, 0x7F, 0x92, 0x84, 0x96, 0x00, 0x02, 0x00} },/* ; 07 (1024x) */ - { {0xCE, 0x9F, 0x92, 0xA5, 0x17, 0x00, 0x07, 0x00} } /* ; 08 (1280x) */ -}; - -/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */ -static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_Vx75[] = { - { {0x86, 0xD1, 0xBC, 0x80, 0xBB, 0xE5, 0x00} },/* ; 00 (x350) */ - { {0xB8, 0x1F, 0x90, 0x84, 0x8F, 0xB9, 0x30} },/* ; 01 (x400) */ - { {0x08, 0x3E, 0xE0, 0x84, 0xDF, 0x09, 0x00} },/* ; 02 (x480) */ - { {0x80, 0xF0, 0x58, 0x8C, 0x57, 0x81, 0xA0} },/* ; 03 (x600) */ - { {0x28, 0xF5, 0x00, 0x84, 0xFF, 0x29, 0x90} },/* ; 04 (x768) */ - { {0x28, 0x5A, 0x13, 0x87, 0xFF, 0x29, 0xA9} } /* ; 05 (x1024) */ -}; - -/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_Hx75[] = { - { {0x7E, 0x3B, 0x9A, 0x44, 0x12, 0x00, 0x01, 0x00} },/* ; 00 (320x) */ - { {0x7E, 0x3B, 0x9A, 0x44, 0x12, 0x00, 0x01, 0x00} },/* ; 01 (360x) */ - { {0x7E, 0x40, 0x84, 0x49, 0x91, 0x00, 0x01, 0x00} },/* ; 02 (400x) */ - { {0x7E, 0x47, 0x93, 0x50, 0x9E, 0x00, 0x01, 0x00} },/* ; 03 (512x) */ - { {0xCE, 0x77, 0x8A, 0x80, 0x8E, 0x00, 0x02, 0x00} },/* ; 04 (640x) */ - { {0xCE, 0x77, 0x8A, 0x80, 0x8E, 0x00, 0x02, 0x00} },/* ; 05 (720x) */ - { {0xCE, 0x81, 0x94, 0x8A, 0x98, 0x00, 0x02, 0x00} },/* ; 06 (800x) */ - { {0xCE, 0x8F, 0x82, 0x98, 0x06, 0x00, 0x07, 0x00} },/* ; 07 (1024x) */ - { {0xCE, 0x9F, 0x92, 0xA8, 0x16, 0x00, 0x07, 0x00} } /* ; 08 (1280x) */ -}; - -/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */ -static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_Vx75[] = { - { {0x28, 0xD2, 0xAF, 0x83, 0xAE, 0xD8, 0xA1} },/* ; 00 (x350) */ - { {0x28, 0xD2, 0xC8, 0x8C, 0xC7, 0xF2, 0x81} },/* ; 01 (x400) */ - { {0x28, 0xD2, 0xF0, 0x84, 0xEF, 0x1A, 0xB1} },/* ; 02 (x480) */ - { {0x28, 0xDE, 0x2C, 0x8F, 0x2B, 0x56, 0x91} },/* ; 03 (x600) */ - { {0x28, 0xDE, 0x80, 0x83, 0x7F, 0xAA, 0x91} },/* ; 04 (x768) */ - { {0x28, 0x5A, 0x13, 0x87, 0xFF, 0x29, 0xA9} } /* ; 05 (x1024) */ -}; - -/*add for new UNIVGABIOS*/ -static const struct XGI330_LCDDataTablStruct XGI_LCDDataTable[] = { - {Panel_1024x768, 0x0019, 0x0001, XGI_ExtLCD1024x768Data }, - {Panel_1024x768, 0x0019, 0x0000, XGI_StLCD1024x768Data }, - {Panel_1024x768, 0x0018, 0x0010, XGI_CetLCD1024x768Data }, - {Panel_1280x1024, 0x0019, 0x0001, XGI_ExtLCD1280x1024Data }, - {Panel_1280x1024, 0x0019, 0x0000, XGI_StLCD1280x1024Data }, - {Panel_1280x1024, 0x0018, 0x0010, XGI_CetLCD1280x1024Data }, - {Panel_1400x1050, 0x0019, 0x0001, xgifb_lcd_1400x1050 }, - {Panel_1400x1050, 0x0019, 0x0000, xgifb_lcd_1400x1050 }, - {Panel_1400x1050, 0x0018, 0x0010, XGI_CetLCD1400x1050Data }, - {Panel_1600x1200, 0x0019, 0x0001, XGI_ExtLCD1600x1200Data }, - {Panel_1600x1200, 0x0019, 0x0000, XGI_StLCD1600x1200Data }, - {PanelRef60Hz, 0x0008, 0x0008, XGI_NoScalingData }, - {Panel_1024x768x75, 0x0019, 0x0001, XGI_ExtLCD1024x768x75Data }, - {Panel_1024x768x75, 0x0019, 0x0000, XGI_ExtLCD1024x768x75Data }, - {Panel_1024x768x75, 0x0018, 0x0010, XGI_CetLCD1024x768x75Data }, - {Panel_1280x1024x75, 0x0019, 0x0001, xgifb_lcd_1280x1024x75 }, - {Panel_1280x1024x75, 0x0019, 0x0000, xgifb_lcd_1280x1024x75 }, - {Panel_1280x1024x75, 0x0018, 0x0010, XGI_CetLCD1280x1024x75Data }, - {PanelRef75Hz, 0x0008, 0x0008, XGI_NoScalingDatax75 }, - {0xFF, 0x0000, 0x0000, NULL } /* End of table */ -}; - -static const struct XGI330_LCDDataTablStruct XGI_LCDDesDataTable[] = { - {Panel_1024x768, 0x0019, 0x0001, XGI_ExtLCDDes1024x768Data }, - {Panel_1024x768, 0x0019, 0x0000, XGI_StLCDDes1024x768Data }, - {Panel_1024x768, 0x0018, 0x0010, XGI_CetLCDDes1024x768Data }, - {Panel_1280x1024, 0x0019, 0x0001, XGI_ExtLCDDes1280x1024Data }, - {Panel_1280x1024, 0x0019, 0x0000, XGI_StLCDDes1280x1024Data }, - {Panel_1280x1024, 0x0018, 0x0010, XGI_CetLCDDes1280x1024Data }, - {Panel_1400x1050, 0x0019, 0x0001, xgifb_lcddes_1400x1050 }, - {Panel_1400x1050, 0x0019, 0x0000, xgifb_lcddes_1400x1050 }, - {Panel_1400x1050, 0x0418, 0x0010, XGI_CetLCDDes1400x1050Data }, - {Panel_1400x1050, 0x0418, 0x0410, XGI_CetLCDDes1400x1050Data2 }, - {Panel_1600x1200, 0x0019, 0x0001, XGI_ExtLCDDes1600x1200Data }, - {Panel_1600x1200, 0x0019, 0x0000, XGI_StLCDDes1600x1200Data }, - {PanelRef60Hz, 0x0008, 0x0008, XGI_NoScalingDesData }, - {Panel_1024x768x75, 0x0019, 0x0001, xgifb_lcddes_1024x768x75 }, - {Panel_1024x768x75, 0x0019, 0x0000, xgifb_lcddes_1024x768x75 }, - {Panel_1024x768x75, 0x0018, 0x0010, XGI_CetLCDDes1024x768x75Data }, - {Panel_1280x1024x75, 0x0019, 0x0001, xgifb_lcddes_1280x1024x75 }, - {Panel_1280x1024x75, 0x0019, 0x0000, xgifb_lcddes_1280x1024x75 }, - {Panel_1280x1024x75, 0x0018, 0x0010, XGI_CetLCDDes1280x1024x75Data }, - {PanelRef75Hz, 0x0008, 0x0008, XGI_NoScalingDesDatax75 }, - {0xFF, 0x0000, 0x0000, NULL } -}; - -static const struct XGI330_LCDDataTablStruct xgifb_lcddldes[] = { - {Panel_1024x768, 0x0019, 0x0001, XGI_ExtLCDDes1024x768Data }, - {Panel_1024x768, 0x0019, 0x0000, XGI_StLCDDes1024x768Data }, - {Panel_1024x768, 0x0018, 0x0010, XGI_CetLCDDes1024x768Data }, - {Panel_1280x1024, 0x0019, 0x0001, XGI_ExtLCDDLDes1280x1024Data }, - {Panel_1280x1024, 0x0019, 0x0000, XGI_StLCDDLDes1280x1024Data }, - {Panel_1280x1024, 0x0018, 0x0010, XGI_CetLCDDLDes1280x1024Data }, - {Panel_1400x1050, 0x0019, 0x0001, xgifb_lcddldes_1400x1050 }, - {Panel_1400x1050, 0x0019, 0x0000, xgifb_lcddldes_1400x1050 }, - {Panel_1400x1050, 0x0418, 0x0010, XGI_CetLCDDes1400x1050Data }, - {Panel_1400x1050, 0x0418, 0x0410, XGI_CetLCDDes1400x1050Data2 }, - {Panel_1600x1200, 0x0019, 0x0001, XGI_ExtLCDDLDes1600x1200Data }, - {Panel_1600x1200, 0x0019, 0x0000, XGI_StLCDDLDes1600x1200Data }, - {PanelRef60Hz, 0x0008, 0x0008, XGI_NoScalingDesData }, - {Panel_1024x768x75, 0x0019, 0x0001, xgifb_lcddes_1024x768x75 }, - {Panel_1024x768x75, 0x0019, 0x0000, xgifb_lcddes_1024x768x75 }, - {Panel_1024x768x75, 0x0018, 0x0010, XGI_CetLCDDes1024x768x75Data }, - {Panel_1280x1024x75, 0x0019, 0x0001, xgifb_lcddldes_1280x1024x75 }, - {Panel_1280x1024x75, 0x0019, 0x0000, xgifb_lcddldes_1280x1024x75 }, - {Panel_1280x1024x75, 0x0018, 0x0010, XGI_CetLCDDLDes1280x1024x75Data }, - {PanelRef75Hz, 0x0008, 0x0008, XGI_NoScalingDesDatax75 }, - {0xFF, 0x0000, 0x0000, NULL } -}; - -static const struct XGI330_LCDDataTablStruct xgifb_epllcd_crt1_h[] = { - {Panel_1024x768, 0x0018, 0x0000, XGI_LVDSCRT11024x768_1_H }, - {Panel_1024x768, 0x0018, 0x0010, XGI_LVDSCRT11024x768_2_H }, - {Panel_1280x1024, 0x0018, 0x0000, XGI_LVDSCRT11280x1024_1_H }, - {Panel_1280x1024, 0x0018, 0x0010, XGI_LVDSCRT11280x1024_2_H }, - {Panel_1400x1050, 0x0018, 0x0000, XGI_LVDSCRT11400x1050_1_H }, - {Panel_1400x1050, 0x0018, 0x0010, XGI_LVDSCRT11400x1050_2_H }, - {Panel_1600x1200, 0x0018, 0x0000, XGI_LVDSCRT11600x1200_1_H }, - {Panel_1024x768x75, 0x0018, 0x0000, XGI_LVDSCRT11024x768_1_Hx75 }, - {Panel_1024x768x75, 0x0018, 0x0010, XGI_LVDSCRT11024x768_2_Hx75 }, - {Panel_1280x1024x75, 0x0018, 0x0000, XGI_LVDSCRT11280x1024_1_Hx75 }, - {Panel_1280x1024x75, 0x0018, 0x0010, XGI_LVDSCRT11280x1024_2_Hx75 }, - {0xFF, 0x0000, 0x0000, NULL } -}; - -static const struct XGI330_LCDDataTablStruct xgifb_epllcd_crt1_v[] = { - {Panel_1024x768, 0x0018, 0x0000, XGI_LVDSCRT11024x768_1_V }, - {Panel_1024x768, 0x0018, 0x0010, XGI_LVDSCRT11024x768_2_V }, - {Panel_1280x1024, 0x0018, 0x0000, XGI_LVDSCRT11280x1024_1_V }, - {Panel_1280x1024, 0x0018, 0x0010, XGI_LVDSCRT11280x1024_2_V }, - {Panel_1400x1050, 0x0018, 0x0000, XGI_LVDSCRT11400x1050_1_V }, - {Panel_1400x1050, 0x0018, 0x0010, XGI_LVDSCRT11400x1050_2_V }, - {Panel_1600x1200, 0x0018, 0x0000, XGI_LVDSCRT11600x1200_1_V }, - {Panel_1024x768x75, 0x0018, 0x0000, XGI_LVDSCRT11024x768_1_Vx75 }, - {Panel_1024x768x75, 0x0018, 0x0010, XGI_LVDSCRT11024x768_2_Vx75 }, - {Panel_1280x1024x75, 0x0018, 0x0000, XGI_LVDSCRT11280x1024_1_Vx75 }, - {Panel_1280x1024x75, 0x0018, 0x0010, XGI_LVDSCRT11280x1024_2_Vx75 }, - {0xFF, 0x0000, 0x0000, NULL } -}; - -static const struct XGI330_LCDDataTablStruct XGI_EPLLCDDataPtr[] = { - {Panel_1024x768, 0x0018, 0x0000, XGI_LVDS1024x768Data_1 }, - {Panel_1024x768, 0x0018, 0x0010, XGI_LVDS1024x768Data_2 }, - {Panel_1280x1024, 0x0018, 0x0000, XGI_LVDS1280x1024Data_1 }, - {Panel_1280x1024, 0x0018, 0x0010, XGI_LVDS1280x1024Data_2 }, - {Panel_1400x1050, 0x0018, 0x0000, XGI_LVDS1400x1050Data_1 }, - {Panel_1400x1050, 0x0018, 0x0010, XGI_LVDS1400x1050Data_2 }, - {Panel_1600x1200, 0x0018, 0x0000, XGI_LVDS1600x1200Data_1 }, - {PanelRef60Hz, 0x0008, 0x0008, XGI_LVDSNoScalingData }, - {Panel_1024x768x75, 0x0018, 0x0000, XGI_LVDS1024x768Data_1x75 }, - {Panel_1024x768x75, 0x0018, 0x0010, XGI_LVDS1024x768Data_2x75 }, - {Panel_1280x1024x75, 0x0018, 0x0000, XGI_LVDS1280x1024Data_1x75 }, - {Panel_1280x1024x75, 0x0018, 0x0010, XGI_LVDS1280x1024Data_2x75 }, - {PanelRef75Hz, 0x0008, 0x0008, XGI_LVDSNoScalingDatax75 }, - {0xFF, 0x0000, 0x0000, NULL } -}; - -static const struct XGI330_LCDDataTablStruct XGI_EPLLCDDesDataPtr[] = { - {Panel_1024x768, 0x0018, 0x0000, XGI_LVDS1024x768Des_1 }, - {Panel_1024x768, 0x0618, 0x0410, XGI_LVDS1024x768Des_3 }, - {Panel_1024x768, 0x0018, 0x0010, XGI_LVDS1024x768Des_2 }, - {Panel_1280x1024, 0x0018, 0x0000, XGI_LVDS1280x1024Des_1 }, - {Panel_1280x1024, 0x0018, 0x0010, XGI_LVDS1280x1024Des_2 }, - {Panel_1400x1050, 0x0018, 0x0000, XGI_LVDS1400x1050Des_1 }, - {Panel_1400x1050, 0x0018, 0x0010, XGI_LVDS1400x1050Des_2 }, - {Panel_1600x1200, 0x0018, 0x0000, XGI_LVDS1600x1200Des_1 }, - {PanelRef60Hz, 0x0008, 0x0008, XGI_LVDSNoScalingDesData }, - {Panel_1024x768x75, 0x0018, 0x0000, XGI_LVDS1024x768Des_1x75 }, - {Panel_1024x768x75, 0x0618, 0x0410, XGI_LVDS1024x768Des_3x75 }, - {Panel_1024x768x75, 0x0018, 0x0010, XGI_LVDS1024x768Des_2x75 }, - {Panel_1280x1024x75, 0x0018, 0x0000, XGI_LVDS1280x1024Des_1x75 }, - {Panel_1280x1024x75, 0x0018, 0x0010, XGI_LVDS1280x1024Des_2x75 }, - {PanelRef75Hz, 0x0008, 0x0008, XGI_LVDSNoScalingDesDatax75 }, - {0xFF, 0x0000, 0x0000, NULL } -}; - -static const struct XGI330_TVDataTablStruct XGI_TVDataTable[] = { - {0x09E1, 0x0001, XGI_ExtPALData}, - {0x09E1, 0x0000, XGI_ExtNTSCData}, - {0x09E1, 0x0801, XGI_StPALData}, - {0x09E1, 0x0800, XGI_StNTSCData}, - {0x49E0, 0x0100, XGI_ExtHiTVData}, - {0x49E0, 0x4100, XGI_St2HiTVData}, - {0x49E0, 0x4900, XGI_St1HiTVData}, - {0x09E0, 0x0020, XGI_ExtYPbPr525iData}, - {0x09E0, 0x0040, XGI_ExtYPbPr525pData}, - {0x09E0, 0x0080, XGI_ExtYPbPr750pData}, - {0x09E0, 0x0820, XGI_StYPbPr525iData}, - {0x09E0, 0x0840, XGI_StYPbPr525pData}, - {0x09E0, 0x0880, XGI_StYPbPr750pData}, - {0xffff, 0x0000, XGI_ExtNTSCData}, -}; - -/* Dual link only */ -static const struct XGI330_LCDCapStruct XGI_LCDDLCapList[] = { -/* LCDCap1024x768 */ - {Panel_1024x768, DefaultLCDCap, 0x88, 0x06, VCLK65_315, - 0x6C, 0xC3, 0x35, 0x62, - 0x0A, 0xC0, 0x28, 0x10}, -/* LCDCap1280x1024 */ - {Panel_1280x1024, XGI_LCDDualLink + DefaultLCDCap, - 0x70, 0x03, VCLK108_2_315, - 0x70, 0x44, 0xF8, 0x2F, - 0x0A, 0xC0, 0x30, 0x10}, -/* LCDCap1400x1050 */ - {Panel_1400x1050, XGI_LCDDualLink + DefaultLCDCap, - 0x70, 0x03, VCLK108_2_315, - 0x70, 0x44, 0xF8, 0x2F, - 0x0A, 0xC0, 0x30, 0x10}, -/* LCDCap1600x1200 */ - {Panel_1600x1200, XGI_LCDDualLink + DefaultLCDCap, - 0xC0, 0x03, VCLK162, - 0x43, 0x22, 0x70, 0x24, - 0x0A, 0xC0, 0x30, 0x10}, -/* LCDCap1024x768x75 */ - {Panel_1024x768x75, DefaultLCDCap, 0x60, 0, VCLK78_75, - 0x2B, 0x61, 0x2B, 0x61, - 0x0A, 0xC0, 0x28, 0x10}, -/* LCDCap1280x1024x75 */ - {Panel_1280x1024x75, XGI_LCDDualLink + DefaultLCDCap, - 0x90, 0x03, VCLK135_5, - 0x54, 0x42, 0x4A, 0x61, - 0x0A, 0xC0, 0x30, 0x10}, -/* LCDCapDefault */ - {0xFF, DefaultLCDCap, 0x88, 0x06, VCLK65_315, - 0x6C, 0xC3, 0x35, 0x62, - 0x0A, 0xC0, 0x28, 0x10} -}; - -static const struct XGI330_LCDCapStruct XGI_LCDCapList[] = { -/* LCDCap1024x768 */ - {Panel_1024x768, DefaultLCDCap, 0x88, 0x06, VCLK65_315, - 0x6C, 0xC3, 0x35, 0x62, - 0x0A, 0xC0, 0x28, 0x10}, -/* LCDCap1280x1024 */ - {Panel_1280x1024, DefaultLCDCap, - 0x70, 0x03, VCLK108_2_315, - 0x70, 0x44, 0xF8, 0x2F, - 0x0A, 0xC0, 0x30, 0x10}, -/* LCDCap1400x1050 */ - {Panel_1400x1050, DefaultLCDCap, - 0x70, 0x03, VCLK108_2_315, - 0x70, 0x44, 0xF8, 0x2F, - 0x0A, 0xC0, 0x30, 0x10}, -/* LCDCap1600x1200 */ - {Panel_1600x1200, DefaultLCDCap, - 0xC0, 0x03, VCLK162, - 0x5A, 0x23, 0x5A, 0x23, - 0x0A, 0xC0, 0x30, 0x10}, -/* LCDCap1024x768x75 */ - {Panel_1024x768x75, DefaultLCDCap, 0x60, 0, VCLK78_75, - 0x2B, 0x61, 0x2B, 0x61, - 0x0A, 0xC0, 0x28, 0x10}, -/* LCDCap1280x1024x75 */ - {Panel_1280x1024x75, DefaultLCDCap, - 0x90, 0x03, VCLK135_5, - 0x54, 0x42, 0x4A, 0x61, - 0x0A, 0xC0, 0x30, 0x10}, -/* LCDCapDefault */ - {0xFF, DefaultLCDCap, 0x88, 0x06, VCLK65_315, - 0x6C, 0xC3, 0x35, 0x62, - 0x0A, 0xC0, 0x28, 0x10} -}; - -const struct XGI_Ext2Struct XGI330_RefIndex[] = { - {Mode32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175, - 0x00, 0x10, 0x59, 320, 200},/* 00 */ - {Mode32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175, - 0x00, 0x10, 0x00, 320, 400},/* 01 */ - {Mode32Bpp + SupportAllCRT2 + SyncNN, RES320x240, VCLK25_175, - 0x04, 0x20, 0x50, 320, 240},/* 02 */ - {Mode32Bpp + SupportAllCRT2 + SyncPP, RES400x300, VCLK40, - 0x05, 0x32, 0x51, 400, 300},/* 03 */ - {Mode32Bpp + NoSupportTV + SyncNN + SupportTV1024, RES512x384, - VCLK65_315, 0x06, 0x43, 0x52, 512, 384},/* 04 */ - {Mode32Bpp + SupportAllCRT2 + SyncPN, RES640x400, VCLK25_175, - 0x00, 0x14, 0x2f, 640, 400},/* 05 */ - {Mode32Bpp + SupportAllCRT2 + SyncNN, RES640x480x60, VCLK25_175, - 0x04, 0x24, 0x2e, 640, 480},/* 06 640x480x60Hz (LCD 640x480x60z) */ - {Mode32Bpp + NoSupportHiVisionTV + SyncNN, RES640x480x72, VCLK31_5, - 0x04, 0x24, 0x2e, 640, 480},/* 07 640x480x72Hz (LCD 640x480x70Hz) */ - {Mode32Bpp + NoSupportHiVisionTV + SyncNN, RES640x480x75, VCLK31_5, - 0x47, 0x24, 0x2e, 640, 480},/* 08 640x480x75Hz (LCD 640x480x75Hz) */ - {Mode32Bpp + SupportRAMDAC2 + SyncNN, RES640x480x85, VCLK36, - 0x8A, 0x24, 0x2e, 640, 480},/* 09 640x480x85Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES640x480x100, VCLK43_163, - 0x00, 0x24, 0x2e, 640, 480},/* 0a 640x480x100Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES640x480x120, VCLK52_406, - 0x00, 0x24, 0x2e, 640, 480},/* 0b 640x480x120Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES640x480x160, VCLK72_852, - 0x00, 0x24, 0x2e, 640, 480},/* 0c 640x480x160Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncNN, RES640x480x200, VCLK86_6, - 0x00, 0x24, 0x2e, 640, 480},/* 0d 640x480x200Hz */ - {Mode32Bpp + NoSupportLCD + SyncPP, RES800x600x56, VCLK36, - 0x05, 0x36, 0x6a, 800, 600},/* 0e 800x600x56Hz */ - {Mode32Bpp + NoSupportTV + SyncPP, RES800x600x60, VCLK40, - 0x05, 0x36, 0x6a, 800, 600},/* 0f 800x600x60Hz (LCD 800x600x60Hz) */ - {Mode32Bpp + NoSupportHiVisionTV + SyncPP, RES800x600x72, VCLK50, - 0x48, 0x36, 0x6a, 800, 600},/* 10 800x600x72Hz (LCD 800x600x70Hz) */ - {Mode32Bpp + NoSupportHiVisionTV + SyncPP, RES800x600x75, VCLK49_5, - 0x8B, 0x36, 0x6a, 800, 600},/* 11 800x600x75Hz (LCD 800x600x75Hz) */ - {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES800x600x85, VCLK56_25, - 0x00, 0x36, 0x6a, 800, 600},/* 12 800x600x85Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES800x600x100, VCLK68_179, - 0x00, 0x36, 0x6a, 800, 600},/* 13 800x600x100Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES800x600x120, VCLK83_95, - 0x00, 0x36, 0x6a, 800, 600},/* 14 800x600x120Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES800x600x160, VCLK116_406, - 0x00, 0x36, 0x6a, 800, 600},/* 15 800x600x160Hz */ - {Mode32Bpp + InterlaceMode + SyncPP, RES1024x768x43, VCLK44_9, - 0x00, 0x47, 0x37, 1024, 768},/* 16 1024x768x43Hz */ - /* 17 1024x768x60Hz (LCD 1024x768x60Hz) */ - {Mode32Bpp + NoSupportTV + SyncNN + SupportTV1024, RES1024x768x60, - VCLK65_315, 0x06, 0x47, 0x37, 1024, 768}, - {Mode32Bpp + NoSupportHiVisionTV + SyncNN, RES1024x768x70, VCLK75, - 0x49, 0x47, 0x37, 1024, 768},/* 18 1024x768x70Hz (LCD 1024x768x70Hz) */ - {Mode32Bpp + NoSupportHiVisionTV + SyncPP, RES1024x768x75, VCLK78_75, - 0x00, 0x47, 0x37, 1024, 768},/* 19 1024x768x75Hz (LCD 1024x768x75Hz) */ - {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1024x768x85, VCLK94_5, - 0x8C, 0x47, 0x37, 1024, 768},/* 1a 1024x768x85Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES1024x768x100, VCLK113_309, - 0x00, 0x47, 0x37, 1024, 768},/* 1b 1024x768x100Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES1024x768x120, VCLK139_054, - 0x00, 0x47, 0x37, 1024, 768},/* 1c 1024x768x120Hz */ - {Mode32Bpp + SupportLCD + SyncPP, RES1280x960x60, VCLK108_2_315, - 0x08, 0x58, 0x7b, 1280, 960},/* 1d 1280x960x60Hz */ - {Mode32Bpp + InterlaceMode + SyncPP, RES1280x1024x43, VCLK78_75, - 0x00, 0x58, 0x3a, 1280, 1024},/* 1e 1280x1024x43Hz */ - {Mode32Bpp + NoSupportTV + SyncPP, RES1280x1024x60, VCLK108_2_315, - 0x07, 0x58, 0x3a, 1280, 1024},/*1f 1280x1024x60Hz (LCD 1280x1024x60Hz)*/ - {Mode32Bpp + NoSupportTV + SyncPP, RES1280x1024x75, VCLK135_5, - 0x00, 0x58, 0x3a, 1280, 1024},/*20 1280x1024x75Hz (LCD 1280x1024x75Hz)*/ - {Mode32Bpp + SyncPP, RES1280x1024x85, VCLK157_5, - 0x00, 0x58, 0x3a, 1280, 1024},/* 21 1280x1024x85Hz */ - /* 22 1600x1200x60Hz */ - {Mode32Bpp + SupportLCD + SyncPP + SupportCRT2in301C, - RES1600x1200x60, VCLK162, 0x09, 0x7A, 0x3c, 1600, 1200}, - {Mode32Bpp + SyncPP + SupportCRT2in301C, RES1600x1200x65, VCLK175, - 0x00, 0x69, 0x3c, 1600, 1200},/* 23 1600x1200x65Hz */ - {Mode32Bpp + SyncPP + SupportCRT2in301C, RES1600x1200x70, VCLK189, - 0x00, 0x69, 0x3c, 1600, 1200},/* 24 1600x1200x70Hz */ - {Mode32Bpp + SyncPP + SupportCRT2in301C, RES1600x1200x75, VCLK202_5, - 0x00, 0x69, 0x3c, 1600, 1200},/* 25 1600x1200x75Hz */ - {Mode32Bpp + SyncPP, RES1600x1200x85, VCLK229_5, - 0x00, 0x69, 0x3c, 1600, 1200},/* 26 1600x1200x85Hz */ - {Mode32Bpp + SyncPP, RES1600x1200x100, VCLK269_655, - 0x00, 0x69, 0x3c, 1600, 1200},/* 27 1600x1200x100Hz */ - {Mode32Bpp + SyncPP, RES1600x1200x120, VCLK323_586, - 0x00, 0x69, 0x3c, 1600, 1200},/* 28 1600x1200x120Hz */ - {Mode32Bpp + SupportLCD + SyncNP, RES1920x1440x60, VCLK234, - 0x00, 0x00, 0x68, 1920, 1440},/* 29 1920x1440x60Hz */ - {Mode32Bpp + SyncPN, RES1920x1440x65, VCLK254_817, - 0x00, 0x00, 0x68, 1920, 1440},/* 2a 1920x1440x65Hz */ - {Mode32Bpp + SyncPN, RES1920x1440x70, VCLK277_015, - 0x00, 0x00, 0x68, 1920, 1440},/* 2b 1920x1440x70Hz */ - {Mode32Bpp + SyncPN, RES1920x1440x75, VCLK291_132, - 0x00, 0x00, 0x68, 1920, 1440},/* 2c 1920x1440x75Hz */ - {Mode32Bpp + SyncPN, RES1920x1440x85, VCLK330_615, - 0x00, 0x00, 0x68, 1920, 1440},/* 2d 1920x1440x85Hz */ - {Mode16Bpp + SyncPN, RES1920x1440x100, VCLK388_631, - 0x00, 0x00, 0x68, 1920, 1440},/* 2e 1920x1440x100Hz */ - {Mode32Bpp + SupportLCD + SyncPN, RES2048x1536x60, VCLK266_952, - 0x00, 0x00, 0x6c, 2048, 1536},/* 2f 2048x1536x60Hz */ - {Mode32Bpp + SyncPN, RES2048x1536x65, VCLK291_766, - 0x00, 0x00, 0x6c, 2048, 1536},/* 30 2048x1536x65Hz */ - {Mode32Bpp + SyncPN, RES2048x1536x70, VCLK315_195, - 0x00, 0x00, 0x6c, 2048, 1536},/* 31 2048x1536x70Hz */ - {Mode32Bpp + SyncPN, RES2048x1536x75, VCLK340_477, - 0x00, 0x00, 0x6c, 2048, 1536},/* 32 2048x1536x75Hz */ - {Mode16Bpp + SyncPN, RES2048x1536x85, VCLK375_847, - 0x00, 0x00, 0x6c, 2048, 1536},/* 33 2048x1536x85Hz */ - {Mode32Bpp + SupportHiVision + SupportRAMDAC2 + - SyncPP + SupportYPbPr750p, RES800x480x60, VCLK39_77, - 0x08, 0x00, 0x70, 800, 480},/* 34 800x480x60Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES800x480x75, VCLK49_5, - 0x08, 0x00, 0x70, 800, 480},/* 35 800x480x75Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES800x480x85, VCLK56_25, - 0x08, 0x00, 0x70, 800, 480},/* 36 800x480x85Hz */ - {Mode32Bpp + SupportHiVision + SupportRAMDAC2 + - SyncPP + SupportYPbPr750p, RES1024x576x60, VCLK65_315, - 0x09, 0x00, 0x71, 1024, 576},/* 37 1024x576x60Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1024x576x75, VCLK78_75, - 0x09, 0x00, 0x71, 1024, 576},/* 38 1024x576x75Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1024x576x85, VCLK94_5, - 0x09, 0x00, 0x71, 1024, 576},/* 39 1024x576x85Hz */ - {Mode32Bpp + SupportHiVision + SupportRAMDAC2 + - SyncPP + SupportYPbPr750p, RES1280x720x60, VCLK108_2_315, - 0x0A, 0x00, 0x75, 1280, 720},/* 3a 1280x720x60Hz*/ - {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1280x720x75, VCLK135_5, - 0x0A, 0x00, 0x75, 1280, 720},/* 3b 1280x720x75Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1280x720x85, VCLK157_5, - 0x0A, 0x00, 0x75, 1280, 720},/* 3c 1280x720x85Hz */ - {Mode32Bpp + SupportTV + SyncNN, RES720x480x60, VCLK28_322, - 0x06, 0x00, 0x31, 720, 480},/* 3d 720x480x60Hz */ - {Mode32Bpp + SupportTV + SyncPP, RES720x576x56, VCLK36, - 0x06, 0x00, 0x32, 720, 576},/* 3e 720x576x56Hz */ - {Mode32Bpp + InterlaceMode + NoSupportLCD + SyncPP, RES856x480x79I, - VCLK35_2, 0x00, 0x00, 0x00, 856, 480},/* 3f 856x480x79I */ - {Mode32Bpp + NoSupportLCD + SyncNN, RES856x480x60, VCLK35_2, - 0x00, 0x00, 0x00, 856, 480},/* 40 856x480x60Hz */ - {Mode32Bpp + NoSupportHiVisionTV + SyncPP, RES1280x768x60, - VCLK79_411, 0x08, 0x48, 0x23, 1280, 768},/* 41 1280x768x60Hz */ - {Mode32Bpp + NoSupportHiVisionTV + SyncPP, RES1400x1050x60, - VCLK122_61, 0x08, 0x69, 0x26, 1400, 1050},/* 42 1400x1050x60Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1152x864x60, VCLK80_350, - 0x37, 0x00, 0x20, 1152, 864},/* 43 1152x864x60Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1152x864x75, VCLK107_385, - 0x37, 0x00, 0x20, 1152, 864},/* 44 1152x864x75Hz */ - {Mode32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP, RES1280x960x75, - VCLK125_999, 0x3A, 0x88, 0x7b, 1280, 960},/* 45 1280x960x75Hz */ - {Mode32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP, RES1280x960x85, - VCLK148_5, 0x0A, 0x88, 0x7b, 1280, 960},/* 46 1280x960x85Hz */ - {Mode32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP, RES1280x960x120, - VCLK217_325, 0x3A, 0x88, 0x7b, 1280, 960},/* 47 1280x960x120Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES1024x768x160, VCLK139_054, - 0x30, 0x47, 0x37, 1024, 768},/* 48 1024x768x160Hz */ -}; - -static const unsigned char XGI330_ScreenOffset[] = { - 0x14, 0x19, 0x20, 0x28, 0x32, 0x40, - 0x50, 0x64, 0x78, 0x80, 0x2d, 0x35, - 0x57, 0x48 -}; - -static const struct SiS_ModeResInfo_S XGI330_ModeResInfo[] = { - { 320, 200, 8, 8}, - { 320, 240, 8, 8}, - { 320, 400, 8, 8}, - { 400, 300, 8, 8}, - { 512, 384, 8, 8}, - { 640, 400, 8, 16}, - { 640, 480, 8, 16}, - { 800, 600, 8, 16}, - {1024, 768, 8, 16}, - {1280, 1024, 8, 16}, - {1600, 1200, 8, 16}, - {1920, 1440, 8, 16}, - {2048, 1536, 8, 16}, - { 720, 480, 8, 16}, - { 720, 576, 8, 16}, - {1280, 960, 8, 16}, - { 800, 480, 8, 16}, - {1024, 576, 8, 16}, - {1280, 720, 8, 16}, - { 856, 480, 8, 16}, - {1280, 768, 8, 16}, - {1400, 1050, 8, 16}, - {1152, 864, 8, 16} -}; - -const struct SiS_VCLKData XGI_VCLKData[] = { - /* SR2B,SR2C,SR2D */ - {0x1B, 0xE1, 25}, /* 00 (25.175MHz) */ - {0x4E, 0xE4, 28}, /* 01 (28.322MHz) */ - {0x57, 0xE4, 31}, /* 02 (31.500MHz) */ - {0xC3, 0xC8, 36}, /* 03 (36.000MHz) */ - {0x42, 0xE2, 40}, /* 04 (40.000MHz) */ - {0xFE, 0xCD, 43}, /* 05 (43.163MHz) */ - {0x5D, 0xC4, 44}, /* 06 (44.900MHz) */ - {0x52, 0xE2, 49}, /* 07 (49.500MHz) */ - {0x53, 0xE2, 50}, /* 08 (50.000MHz) */ - {0x74, 0x67, 52}, /* 09 (52.406MHz) */ - {0x6D, 0x66, 56}, /* 0A (56.250MHz) */ - {0x6C, 0xC3, 65}, /* 0B (65.000MHz) */ - {0x46, 0x44, 67}, /* 0C (67.765MHz) */ - {0xB1, 0x46, 68}, /* 0D (68.179MHz) */ - {0xD3, 0x4A, 72}, /* 0E (72.852MHz) */ - {0x29, 0x61, 75}, /* 0F (75.000MHz) */ - {0x6E, 0x46, 76}, /* 10 (75.800MHz) */ - {0x2B, 0x61, 78}, /* 11 (78.750MHz) */ - {0x31, 0x42, 79}, /* 12 (79.411MHz) */ - {0xAB, 0x44, 83}, /* 13 (83.950MHz) */ - {0x46, 0x25, 84}, /* 14 (84.800MHz) */ - {0x78, 0x29, 86}, /* 15 (86.600MHz) */ - {0x62, 0x44, 94}, /* 16 (94.500MHz) */ - {0x2B, 0x41, 104}, /* 17 (104.998MHz) */ - {0x3A, 0x23, 105}, /* 18 (105.882MHz) */ - {0x70, 0x44, 108}, /* 19 (107.862MHz) */ - {0x3C, 0x23, 109}, /* 1A (109.175MHz) */ - {0x5E, 0x43, 113}, /* 1B (113.309MHz) */ - {0xBC, 0x44, 116}, /* 1C (116.406MHz) */ - {0xE0, 0x46, 132}, /* 1D (132.258MHz) */ - {0x54, 0x42, 135}, /* 1E (135.500MHz) */ - {0x9C, 0x22, 139}, /* 1F (139.275MHz) */ - {0x41, 0x22, 157}, /* 20 (157.500MHz) */ - {0x70, 0x24, 162}, /* 21 (161.793MHz) */ - {0x30, 0x21, 175}, /* 22 (175.000MHz) */ - {0x4E, 0x22, 189}, /* 23 (188.520MHz) */ - {0xDE, 0x26, 194}, /* 24 (194.400MHz) */ - {0x62, 0x06, 202}, /* 25 (202.500MHz) */ - {0x3F, 0x03, 229}, /* 26 (229.500MHz) */ - {0xB8, 0x06, 234}, /* 27 (233.178MHz) */ - {0x34, 0x02, 253}, /* 28 (252.699MHz) */ - {0x58, 0x04, 255}, /* 29 (254.817MHz) */ - {0x24, 0x01, 265}, /* 2A (265.728MHz) */ - {0x9B, 0x02, 267}, /* 2B (266.952MHz) */ - {0x70, 0x05, 270}, /* 2C (269.65567MHz) */ - {0x25, 0x01, 272}, /* 2D (272.04199MHz) */ - {0x9C, 0x02, 277}, /* 2E (277.015MHz) */ - {0x27, 0x01, 286}, /* 2F (286.359985MHz) */ - {0xB3, 0x04, 291}, /* 30 (291.13266MHz) */ - {0xBC, 0x05, 292}, /* 31 (291.766MHz) */ - {0xF6, 0x0A, 310}, /* 32 (309.789459MHz) */ - {0x95, 0x01, 315}, /* 33 (315.195MHz) */ - {0xF0, 0x09, 324}, /* 34 (323.586792MHz) */ - {0xFE, 0x0A, 331}, /* 35 (330.615631MHz) */ - {0xF3, 0x09, 332}, /* 36 (332.177612MHz) */ - {0x5E, 0x03, 340}, /* 37 (340.477MHz) */ - {0xE8, 0x07, 376}, /* 38 (375.847504MHz) */ - {0xDE, 0x06, 389}, /* 39 (388.631439MHz) */ - {0x52, 0x2A, 54}, /* 3A (54.000MHz) */ - {0x52, 0x6A, 27}, /* 3B (27.000MHz) */ - {0x62, 0x24, 70}, /* 3C (70.874991MHz) */ - {0x62, 0x64, 70}, /* 3D (70.1048912MHz) */ - {0xA8, 0x4C, 30}, /* 3E (30.1048912MHz) */ - {0x20, 0x26, 33}, /* 3F (33.7499957MHz) */ - {0x31, 0xc2, 39}, /* 40 (39.77MHz) */ - {0x11, 0x21, 30}, /* 41 (30MHz) }// NTSC 1024X768 */ - {0x2E, 0x48, 25}, /* 42 (25.175MHz) }// ScaleLCD */ - {0x24, 0x46, 25}, /* 43 (25.175MHz) */ - {0x26, 0x64, 28}, /* 44 (28.322MHz) */ - {0x37, 0x64, 40}, /* 45 (40.000MHz) */ - {0xA1, 0x42, 108}, /* 46 (95.000MHz) }// QVGA */ - {0x37, 0x61, 100}, /* 47 (100.00MHz) */ - {0x78, 0x27, 108}, /* 48 (108.200MHz) */ - {0xBF, 0xC8, 35}, /* 49 (35.2MHz) */ - {0x66, 0x43, 123}, /* 4A (122.61Mhz) */ - {0x2C, 0x61, 80}, /* 4B (80.350Mhz) */ - {0x3B, 0x61, 108}, /* 4C (107.385Mhz) */ - {0x69, 0x61, 191}, /* 4D (190.96MHz ) */ - {0x4F, 0x22, 192}, /* 4E (192.069MHz) */ - {0x28, 0x26, 322}, /* 4F (322.273MHz) */ - {0x5C, 0x6B, 27}, /* 50 (27.74HMz) */ - {0x57, 0x24, 126}, /* 51 (125.999MHz) */ - {0x5C, 0x42, 148}, /* 52 (148.5MHz) */ - {0x42, 0x61, 120}, /* 53 (120.839MHz) */ - {0x62, 0x61, 178}, /* 54 (178.992MHz) */ - {0x59, 0x22, 217}, /* 55 (217.325MHz) */ - {0x29, 0x01, 300}, /* 56 (299.505Mhz) */ - {0x52, 0x63, 74}, /* 57 (74.25MHz) */ - {0xFF, 0x00, 0} /* End mark */ -}; - -static const struct SiS_VBVCLKData XGI_VBVCLKData[] = { - {0x1B, 0xE1, 25}, /* 00 (25.175MHz) */ - {0x4E, 0xE4, 28}, /* 01 (28.322MHz) */ - {0x57, 0xE4, 31}, /* 02 (31.500MHz) */ - {0xC3, 0xC8, 36}, /* 03 (36.000MHz) */ - {0x42, 0x47, 40}, /* 04 (40.000MHz) */ - {0xFE, 0xCD, 43}, /* 05 (43.163MHz) */ - {0x5D, 0xC4, 44}, /* 06 (44.900MHz) */ - {0x52, 0x47, 49}, /* 07 (49.500MHz) */ - {0x53, 0x47, 50}, /* 08 (50.000MHz) */ - {0x74, 0x67, 52}, /* 09 (52.406MHz) */ - {0x6D, 0x66, 56}, /* 0A (56.250MHz) */ - {0x35, 0x62, 65}, /* 0B (65.000MHz) */ - {0x46, 0x44, 67}, /* 0C (67.765MHz) */ - {0xB1, 0x46, 68}, /* 0D (68.179MHz) */ - {0xD3, 0x4A, 72}, /* 0E (72.852MHz) */ - {0x29, 0x61, 75}, /* 0F (75.000MHz) */ - {0x6D, 0x46, 75}, /* 10 (75.800MHz) */ - {0x41, 0x43, 78}, /* 11 (78.750MHz) */ - {0x31, 0x42, 79}, /* 12 (79.411MHz) */ - {0xAB, 0x44, 83}, /* 13 (83.950MHz) */ - {0x46, 0x25, 84}, /* 14 (84.800MHz) */ - {0x78, 0x29, 86}, /* 15 (86.600MHz) */ - {0x62, 0x44, 94}, /* 16 (94.500MHz) */ - {0x2B, 0x22, 104}, /* 17 (104.998MHz) */ - {0x49, 0x24, 105}, /* 18 (105.882MHz) */ - {0xF8, 0x2F, 108}, /* 19 (108.279MHz) */ - {0x3C, 0x23, 109}, /* 1A (109.175MHz) */ - {0x5E, 0x43, 113}, /* 1B (113.309MHz) */ - {0xBC, 0x44, 116}, /* 1C (116.406MHz) */ - {0xE0, 0x46, 132}, /* 1D (132.258MHz) */ - {0xD4, 0x28, 135}, /* 1E (135.220MHz) */ - {0xEA, 0x2A, 139}, /* 1F (139.275MHz) */ - {0x41, 0x22, 157}, /* 20 (157.500MHz) */ - {0x70, 0x24, 162}, /* 21 (161.793MHz) */ - {0x30, 0x21, 175}, /* 22 (175.000MHz) */ - {0x4E, 0x22, 189}, /* 23 (188.520MHz) */ - {0xDE, 0x26, 194}, /* 24 (194.400MHz) */ - {0x70, 0x07, 202}, /* 25 (202.500MHz) */ - {0x3F, 0x03, 229}, /* 26 (229.500MHz) */ - {0xB8, 0x06, 234}, /* 27 (233.178MHz) */ - {0x34, 0x02, 253}, /* 28 (252.699997 MHz) */ - {0x58, 0x04, 255}, /* 29 (254.817MHz) */ - {0x24, 0x01, 265}, /* 2A (265.728MHz) */ - {0x9B, 0x02, 267}, /* 2B (266.952MHz) */ - {0x70, 0x05, 270}, /* 2C (269.65567 MHz) */ - {0x25, 0x01, 272}, /* 2D (272.041992 MHz) */ - {0x9C, 0x02, 277}, /* 2E (277.015MHz) */ - {0x27, 0x01, 286}, /* 2F (286.359985 MHz) */ - {0x3C, 0x02, 291}, /* 30 (291.132660 MHz) */ - {0xEF, 0x0A, 292}, /* 31 (291.766MHz) */ - {0xF6, 0x0A, 310}, /* 32 (309.789459 MHz) */ - {0x95, 0x01, 315}, /* 33 (315.195MHz) */ - {0xF0, 0x09, 324}, /* 34 (323.586792 MHz) */ - {0xFE, 0x0A, 331}, /* 35 (330.615631 MHz) */ - {0xF3, 0x09, 332}, /* 36 (332.177612 MHz) */ - {0xEA, 0x08, 340}, /* 37 (340.477MHz) */ - {0xE8, 0x07, 376}, /* 38 (375.847504 MHz) */ - {0xDE, 0x06, 389}, /* 39 (388.631439 MHz) */ - {0x52, 0x2A, 54}, /* 3A (54.000MHz) */ - {0x52, 0x6A, 27}, /* 3B (27.000MHz) */ - {0x62, 0x24, 70}, /* 3C (70.874991MHz) */ - {0x62, 0x64, 70}, /* 3D (70.1048912MHz) */ - {0xA8, 0x4C, 30}, /* 3E (30.1048912MHz) */ - {0x20, 0x26, 33}, /* 3F (33.7499957MHz) */ - {0x31, 0xc2, 39}, /* 40 (39.77MHz) */ - {0x11, 0x21, 30}, /* 41 (30MHz) }// NTSC 1024X768 */ - {0x2E, 0x48, 25}, /* 42 (25.175MHz) }// ScaleLCD */ - {0x24, 0x46, 25}, /* 43 (25.175MHz) */ - {0x26, 0x64, 28}, /* 44 (28.322MHz) */ - {0x37, 0x64, 40}, /* 45 (40.000MHz) */ - {0xA1, 0x42, 108}, /* 46 (95.000MHz) }// QVGA */ - {0x37, 0x61, 100}, /* 47 (100.00MHz) */ - {0x78, 0x27, 108}, /* 48 (108.200MHz) */ - {0xBF, 0xC8, 35 }, /* 49 (35.2MHz) */ - {0x66, 0x43, 123}, /* 4A (122.61Mhz) */ - {0x2C, 0x61, 80 }, /* 4B (80.350Mhz) */ - {0x3B, 0x61, 108}, /* 4C (107.385Mhz) */ - {0x69, 0x61, 191}, /* 4D (190.96MHz ) */ - {0x4F, 0x22, 192}, /* 4E (192.069MHz) */ - {0x28, 0x26, 322}, /* 4F (322.273MHz) */ - {0x5C, 0x6B, 27}, /* 50 (27.74HMz) */ - {0x57, 0x24, 126}, /* 51 (125.999MHz) */ - {0x5C, 0x42, 148}, /* 52 (148.5MHz) */ - {0x42, 0x61, 120}, /* 53 (120.839MHz) */ - {0x62, 0x61, 178}, /* 54 (178.992MHz) */ - {0x59, 0x22, 217}, /* 55 (217.325MHz) */ - {0x29, 0x01, 300}, /* 56 (299.505Mhz) */ - {0x52, 0x63, 74}, /* 57 (74.25MHz) */ - {0xFF, 0x00, 0} /* End mark */ -}; - -#define XGI301TVDelay 0x22 -#define XGI301LCDDelay 0x12 - -static const unsigned char TVAntiFlickList[] = {/* NTSCAntiFlicker */ - 0x04, /* ; 0 Adaptive */ - 0x00, /* ; 1 new anti-flicker ? */ - - 0x04, /* ; 0 Adaptive */ - 0x08, /* ; 1 new anti-flicker ? */ - - 0x04, /* ; 0 ? */ - 0x00 /* ; 1 new anti-flicker ? */ -}; - -static const unsigned char TVEdgeList[] = { - 0x00, /* ; 0 NTSC No Edge enhance */ - 0x04, /* ; 1 NTSC Adaptive Edge enhance */ - 0x00, /* ; 0 PAL No Edge enhance */ - 0x04, /* ; 1 PAL Adaptive Edge enhance */ - 0x00, /* ; 0 HiTV */ - 0x00 /* ; 1 HiTV */ -}; - -static const unsigned long TVPhaseList[] = { - 0x08BAED21, /* ; 0 NTSC phase */ - 0x00E3052A, /* ; 1 PAL phase */ - 0x9B2EE421, /* ; 2 PAL-M phase */ - 0xBA3EF421, /* ; 3 PAL-N phase */ - 0xA7A28B1E, /* ; 4 NTSC 1024x768 */ - 0xE00A831E, /* ; 5 PAL-M 1024x768 */ - 0x00000000, /* ; 6 reserved */ - 0x00000000, /* ; 7 reserved */ - 0xD67BF021, /* ; 8 NTSC phase */ - 0xE986092A, /* ; 9 PAL phase */ - 0xA4EFE621, /* ; A PAL-M phase */ - 0x4694F621, /* ; B PAL-N phase */ - 0x8BDE711C, /* ; C NTSC 1024x768 */ - 0xE00A831E /* ; D PAL-M 1024x768 */ -}; - -static const unsigned char NTSCYFilter1[] = { - 0x00, 0xF4, 0x10, 0x38, /* 0 : 320x text mode */ - 0x00, 0xF4, 0x10, 0x38, /* 1 : 360x text mode */ - 0xEB, 0x04, 0x25, 0x18, /* 2 : 640x text mode */ - 0xF1, 0x04, 0x1F, 0x18, /* 3 : 720x text mode */ - 0x00, 0xF4, 0x10, 0x38, /* 4 : 320x gra. mode */ - 0xEB, 0x04, 0x25, 0x18, /* 5 : 640x gra. mode */ - 0xEB, 0x15, 0x25, 0xF6 /* 6 : 800x gra. mode */ -}; - -static const unsigned char PALYFilter1[] = { - 0x00, 0xF4, 0x10, 0x38, /* 0 : 320x text mode */ - 0x00, 0xF4, 0x10, 0x38, /* 1 : 360x text mode */ - 0xF1, 0xF7, 0x1F, 0x32, /* 2 : 640x text mode */ - 0xF3, 0x00, 0x1D, 0x20, /* 3 : 720x text mode */ - 0x00, 0xF4, 0x10, 0x38, /* 4 : 320x gra. mode */ - 0xF1, 0xF7, 0x1F, 0x32, /* 5 : 640x gra. mode */ - 0xFC, 0xFB, 0x14, 0x2A /* 6 : 800x gra. mode */ -}; - -static const unsigned char xgifb_palmn_yfilter1[] = { - 0x00, 0xF4, 0x10, 0x38, /* 0 : 320x text mode */ - 0x00, 0xF4, 0x10, 0x38, /* 1 : 360x text mode */ - 0xEB, 0x04, 0x10, 0x18, /* 2 : 640x text mode */ - 0xF7, 0x06, 0x19, 0x14, /* 3 : 720x text mode */ - 0x00, 0xF4, 0x10, 0x38, /* 4 : 320x gra. mode */ - 0xEB, 0x04, 0x25, 0x18, /* 5 : 640x gra. mode */ - 0xEB, 0x15, 0x25, 0xF6, /* 6 : 800x gra. mode */ - 0xFF, 0xFF, 0xFF, 0xFF /* End of Table */ -}; - -static const unsigned char xgifb_yfilter2[] = { - 0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 0 : 320x text mode */ - 0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C, /* 1 : 360x text mode */ - 0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 2 : 640x text mode */ - 0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C, /* 3 : 720x text mode */ - 0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 4 : 320x gra. mode */ - 0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 5 : 640x gra. mode */ - 0x01, 0x01, 0xFC, 0xF8, 0x08, 0x26, 0x38, /* 6 : 800x gra. mode */ - 0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0x22, 0x28 /* 7 : 1024xgra. mode */ -}; - -static const unsigned char XGI_NTSC1024AdjTime[] = { - 0xa7, 0x07, 0xf2, 0x6e, 0x17, 0x8b, 0x73, 0x53, - 0x13, 0x40, 0x34, 0xF4, 0x63, 0xBB, 0xCC, 0x7A, - 0x58, 0xe4, 0x73, 0xd0, 0x13 -}; - -static const struct XGI301C_Tap4TimingStruct xgifb_tap4_timing[] = { - {0, { - 0x00, 0x20, 0x00, 0x00, 0x7F, 0x20, 0x02, 0x7F, /* ; C0-C7 */ - 0x7D, 0x20, 0x04, 0x7F, 0x7D, 0x1F, 0x06, 0x7E, /* ; C8-CF */ - 0x7C, 0x1D, 0x09, 0x7E, 0x7C, 0x1B, 0x0B, 0x7E, /* ; D0-D7 */ - 0x7C, 0x19, 0x0E, 0x7D, 0x7C, 0x17, 0x11, 0x7C, /* ; D8-DF */ - 0x7C, 0x14, 0x14, 0x7C, 0x7C, 0x11, 0x17, 0x7C, /* ; E0-E7 */ - 0x7D, 0x0E, 0x19, 0x7C, 0x7E, 0x0B, 0x1B, 0x7C, /* ; EA-EF */ - 0x7E, 0x09, 0x1D, 0x7C, 0x7F, 0x06, 0x1F, 0x7C, /* ; F0-F7 */ - 0x7F, 0x04, 0x20, 0x7D, 0x00, 0x02, 0x20, 0x7E /* ; F8-FF */ - } - } -}; - -static const struct XGI301C_Tap4TimingStruct PALTap4Timing[] = { - {600, { - 0x05, 0x19, 0x05, 0x7D, 0x03, 0x19, 0x06, 0x7E, /* ; C0-C7 */ - 0x02, 0x19, 0x08, 0x7D, 0x01, 0x18, 0x0A, 0x7D, /* ; C8-CF */ - 0x00, 0x18, 0x0C, 0x7C, 0x7F, 0x17, 0x0E, 0x7C, /* ; D0-D7 */ - 0x7E, 0x16, 0x0F, 0x7D, 0x7E, 0x14, 0x11, 0x7D, /* ; D8-DF */ - 0x7D, 0x13, 0x13, 0x7D, 0x7D, 0x11, 0x14, 0x7E, /* ; E0-E7 */ - 0x7D, 0x0F, 0x16, 0x7E, 0x7D, 0x0E, 0x17, 0x7E, /* ; EA-EF */ - 0x7D, 0x0C, 0x18, 0x7F, 0x7D, 0x0A, 0x18, 0x01, /* ; F0-F7 */ - 0x7D, 0x08, 0x19, 0x02, 0x7D, 0x06, 0x19, 0x04 /* ; F8-FF */ - } - }, - {768, { - 0x08, 0x12, 0x08, 0x7E, 0x07, 0x12, 0x09, 0x7E, /* ; C0-C7 */ - 0x06, 0x12, 0x0A, 0x7E, 0x05, 0x11, 0x0B, 0x7F, /* ; C8-CF */ - 0x04, 0x11, 0x0C, 0x7F, 0x03, 0x11, 0x0C, 0x00, /* ; D0-D7 */ - 0x03, 0x10, 0x0D, 0x00, 0x02, 0x0F, 0x0E, 0x01, /* ; D8-DF */ - 0x01, 0x0F, 0x0F, 0x01, 0x01, 0x0E, 0x0F, 0x02, /* ; E0-E7 */ - 0x00, 0x0D, 0x10, 0x03, 0x7F, 0x0C, 0x11, 0x04, /* ; EA-EF */ - 0x7F, 0x0C, 0x11, 0x04, 0x7F, 0x0B, 0x11, 0x05, /* ; F0-F7 */ - 0x7E, 0x0A, 0x12, 0x06, 0x7E, 0x09, 0x12, 0x07 /* ; F8-FF */ - } - }, - {0xFFFF, { - 0x04, 0x1A, 0x04, 0x7E, 0x02, 0x1B, 0x05, 0x7E, /* ; C0-C7 */ - 0x01, 0x1A, 0x07, 0x7E, 0x00, 0x1A, 0x09, 0x7D, /* ; C8-CF */ - 0x7F, 0x19, 0x0B, 0x7D, 0x7E, 0x18, 0x0D, 0x7D, /* ; D0-D7 */ - 0x7D, 0x17, 0x10, 0x7C, 0x7D, 0x15, 0x12, 0x7C, /* ; D8-DF */ - 0x7C, 0x14, 0x14, 0x7C, 0x7C, 0x12, 0x15, 0x7D, /* ; E0-E7 */ - 0x7C, 0x10, 0x17, 0x7D, 0x7C, 0x0D, 0x18, 0x7F, /* ; EA-EF */ - 0x7D, 0x0B, 0x19, 0x7F, 0x7D, 0x09, 0x1A, 0x00, /* ; F0-F7 */ - 0x7D, 0x07, 0x1A, 0x02, 0x7E, 0x05, 0x1B, 0x02 /* ; F8-FF */ - } - } -}; - -static const struct XGI301C_Tap4TimingStruct xgifb_ntsc_525_tap4_timing[] = { - {480, { - 0x04, 0x1A, 0x04, 0x7E, 0x03, 0x1A, 0x06, 0x7D, /* ; C0-C7 */ - 0x01, 0x1A, 0x08, 0x7D, 0x00, 0x19, 0x0A, 0x7D, /* ; C8-CF */ - 0x7F, 0x19, 0x0C, 0x7C, 0x7E, 0x18, 0x0E, 0x7C, /* ; D0-D7 */ - 0x7E, 0x17, 0x10, 0x7B, 0x7D, 0x15, 0x12, 0x7C, /* ; D8-DF */ - 0x7D, 0x13, 0x13, 0x7D, 0x7C, 0x12, 0x15, 0x7D, /* ; E0-E7 */ - 0x7C, 0x10, 0x17, 0x7D, 0x7C, 0x0E, 0x18, 0x7E, /* ; EA-EF */ - 0x7D, 0x0C, 0x19, 0x7E, 0x7D, 0x0A, 0x19, 0x00, /* ; F0-F7 */ - 0x7D, 0x08, 0x1A, 0x01, 0x7E, 0x06, 0x1A, 0x02 /* ; F8-FF */ - } - }, - {600, { - 0x07, 0x14, 0x07, 0x7E, 0x06, 0x14, 0x09, 0x7D, /* ; C0-C7 */ - 0x05, 0x14, 0x0A, 0x7D, 0x04, 0x13, 0x0B, 0x7E, /* ; C8-CF */ - 0x03, 0x13, 0x0C, 0x7E, 0x02, 0x12, 0x0D, 0x7F, /* ; D0-D7 */ - 0x01, 0x12, 0x0E, 0x7F, 0x01, 0x11, 0x0F, 0x7F, /* ; D8-DF */ - 0x01, 0x10, 0x10, 0x00, 0x7F, 0x0F, 0x11, 0x01, /* ; E0-E7 */ - 0x7F, 0x0E, 0x12, 0x01, 0x7E, 0x0D, 0x12, 0x03, /* ; EA-EF */ - 0x7E, 0x0C, 0x13, 0x03, 0x7E, 0x0B, 0x13, 0x04, /* ; F0-F7 */ - 0x7E, 0x0A, 0x14, 0x04, 0x7D, 0x09, 0x14, 0x06 /* ; F8-FF */ - } - }, - {0xFFFF, { - 0x09, 0x0F, 0x09, 0x7F, 0x08, 0x0F, 0x09, 0x00, /* ; C0-C7 */ - 0x07, 0x0F, 0x0A, 0x00, 0x06, 0x0F, 0x0A, 0x01, /* ; C8-CF */ - 0x06, 0x0E, 0x0B, 0x01, 0x05, 0x0E, 0x0B, 0x02, /* ; D0-D7 */ - 0x04, 0x0E, 0x0C, 0x02, 0x04, 0x0D, 0x0C, 0x03, /* ; D8-DF */ - 0x03, 0x0D, 0x0D, 0x03, 0x02, 0x0C, 0x0D, 0x05, /* ; E0-E7 */ - 0x02, 0x0C, 0x0E, 0x04, 0x01, 0x0B, 0x0E, 0x06, /* ; EA-EF */ - 0x01, 0x0B, 0x0E, 0x06, 0x00, 0x0A, 0x0F, 0x07, /* ; F0-F7 */ - 0x00, 0x0A, 0x0F, 0x07, 0x00, 0x09, 0x0F, 0x08 /* ; F8-FF */ - } - } -}; - -static const struct XGI301C_Tap4TimingStruct YPbPr750pTap4Timing[] = { - {0xFFFF, { - 0x05, 0x19, 0x05, 0x7D, 0x03, 0x19, 0x06, 0x7E, /* ; C0-C7 */ - 0x02, 0x19, 0x08, 0x7D, 0x01, 0x18, 0x0A, 0x7D, /* ; C8-CF */ - 0x00, 0x18, 0x0C, 0x7C, 0x7F, 0x17, 0x0E, 0x7C, /* ; D0-D7 */ - 0x7E, 0x16, 0x0F, 0x7D, 0x7E, 0x14, 0x11, 0x7D, /* ; D8-DF */ - 0x7D, 0x13, 0x13, 0x7D, 0x7D, 0x11, 0x14, 0x7E, /* ; E0-E7 */ - 0x7D, 0x0F, 0x16, 0x7E, 0x7D, 0x0E, 0x17, 0x7E, /* ; EA-EF */ - 0x7D, 0x0C, 0x18, 0x7F, 0x7D, 0x0A, 0x18, 0x01, /* ; F0-F7 */ - 0x7D, 0x08, 0x19, 0x02, 0x7D, 0x06, 0x19, 0x04 /* F8-FF */ - } - } -}; -#endif diff --git a/drivers/staging/xgifb/vb_util.h b/drivers/staging/xgifb/vb_util.h deleted file mode 100644 index 0f6d5aac04f6..000000000000 --- a/drivers/staging/xgifb/vb_util.h +++ /dev/null @@ -1,46 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _VBUTIL_ -#define _VBUTIL_ -static inline void xgifb_reg_set(unsigned long port, u8 index, u8 data) -{ - outb(index, port); - outb(data, port + 1); -} - -static inline u8 xgifb_reg_get(unsigned long port, u8 index) -{ - outb(index, port); - return inb(port + 1); -} - -static inline void xgifb_reg_and_or(unsigned long port, u8 index, - unsigned int data_and, unsigned int data_or) -{ - u8 temp; - - temp = xgifb_reg_get(port, index); - temp = (u8)((temp & data_and) | data_or); - xgifb_reg_set(port, index, temp); -} - -static inline void xgifb_reg_and(unsigned long port, u8 index, - unsigned int data_and) -{ - u8 temp; - - temp = xgifb_reg_get(port, index); - temp = (u8)(temp & data_and); - xgifb_reg_set(port, index, temp); -} - -static inline void xgifb_reg_or(unsigned long port, u8 index, - unsigned int data_or) -{ - u8 temp; - - temp = xgifb_reg_get(port, index); - temp |= data_or; - xgifb_reg_set(port, index, temp); -} -#endif - diff --git a/drivers/staging/xgifb/vgatypes.h b/drivers/staging/xgifb/vgatypes.h deleted file mode 100644 index 22919f2368d5..000000000000 --- a/drivers/staging/xgifb/vgatypes.h +++ /dev/null @@ -1,51 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _VGATYPES_ -#define _VGATYPES_ - -#include <linux/fb.h> /* for struct fb_var_screeninfo for sis.h */ -#include "../../video/fbdev/sis/vgatypes.h" -#include "../../video/fbdev/sis/sis.h" /* for LCD_TYPE */ - -enum XGI_VB_CHIP_TYPE { - VB_CHIP_Legacy = 0, - VB_CHIP_301, - VB_CHIP_301B, - VB_CHIP_301LV, - VB_CHIP_302, - VB_CHIP_302B, - VB_CHIP_302LV, - VB_CHIP_301C, - VB_CHIP_302ELV, - VB_CHIP_UNKNOWN, /* other video bridge or no video bridge */ - MAX_VB_CHIP -}; - -struct xgi_hw_device_info { - unsigned long ulExternalChip; /* NO VB or other video bridge*/ - /* if ujVBChipID = VB_CHIP_UNKNOWN, */ - - void __iomem *pjVideoMemoryAddress;/* base virtual memory address */ - /* of Linear VGA memory */ - - unsigned long ulVideoMemorySize; /* size, in bytes, of the - * memory on the board - */ - - unsigned char jChipType; /* Used to Identify Graphics Chip */ - /* defined in the data structure type */ - /* "XGI_CHIP_TYPE" */ - - unsigned char jChipRevision; /* Used to Identify Graphics - * Chip Revision - */ - - unsigned char ujVBChipID; /* the ID of video bridge */ - /* defined in the data structure type */ - /* "XGI_VB_CHIP_TYPE" */ - - unsigned long ulCRT2LCDType; /* defined in the data structure type */ -}; - -/* Additional IOCTL for communication xgifb <> X driver */ -/* If changing this, xgifb.h must also be changed (for xgifb) */ -#endif diff --git a/include/dt-bindings/iio/adc/ingenic,adc.h b/include/dt-bindings/iio/adc/ingenic,adc.h new file mode 100644 index 000000000000..82706b2706ac --- /dev/null +++ b/include/dt-bindings/iio/adc/ingenic,adc.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _DT_BINDINGS_IIO_ADC_INGENIC_ADC_H +#define _DT_BINDINGS_IIO_ADC_INGENIC_ADC_H + +/* ADC channel idx. */ +#define INGENIC_ADC_AUX 0 +#define INGENIC_ADC_BATTERY 1 + +#endif diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h index 8092b8e7f37e..45e9667f0a8c 100644 --- a/include/linux/iio/common/st_sensors.h +++ b/include/linux/iio/common/st_sensors.h @@ -260,6 +260,7 @@ struct st_sensor_settings { struct st_sensor_data { struct device *dev; struct iio_trigger *trig; + struct iio_mount_matrix *mount_matrix; struct st_sensor_settings *sensor_settings; struct st_sensor_fullscale_avl *current_fullscale; struct regulator *vdd; diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h index 92baabc103ac..fdd81affca4b 100644 --- a/include/uapi/linux/iio/types.h +++ b/include/uapi/linux/iio/types.h @@ -46,6 +46,7 @@ enum iio_chan_type { IIO_GRAVITY, IIO_POSITIONRELATIVE, IIO_PHASE, + IIO_MASSCONCENTRATION, }; enum iio_modifier { @@ -87,6 +88,12 @@ enum iio_modifier { IIO_MOD_VOC, IIO_MOD_LIGHT_UV, IIO_MOD_LIGHT_DUV, + IIO_MOD_PM1, + IIO_MOD_PM2P5, + IIO_MOD_PM4, + IIO_MOD_PM10, + IIO_MOD_ETHANOL, + IIO_MOD_H2, }; enum iio_event_type { diff --git a/tools/iio/iio_event_monitor.c b/tools/iio/iio_event_monitor.c index ac2de6b7e89f..7bf9bde28bcc 100644 --- a/tools/iio/iio_event_monitor.c +++ b/tools/iio/iio_event_monitor.c @@ -60,6 +60,7 @@ static const char * const iio_chan_type_name_spec[] = { [IIO_GRAVITY] = "gravity", [IIO_POSITIONRELATIVE] = "positionrelative", [IIO_PHASE] = "phase", + [IIO_MASSCONCENTRATION] = "massconcentration", }; static const char * const iio_ev_type_text[] = { @@ -114,7 +115,13 @@ static const char * const iio_modifier_names[] = { [IIO_MOD_I] = "i", [IIO_MOD_Q] = "q", [IIO_MOD_CO2] = "co2", + [IIO_MOD_ETHANOL] = "ethanol", + [IIO_MOD_H2] = "h2", [IIO_MOD_VOC] = "voc", + [IIO_MOD_PM1] = "pm1", + [IIO_MOD_PM2P5] = "pm2p5", + [IIO_MOD_PM4] = "pm4", + [IIO_MOD_PM10] = "pm10", }; static bool event_is_known(struct iio_event_data *event) @@ -156,6 +163,7 @@ static bool event_is_known(struct iio_event_data *event) case IIO_GRAVITY: case IIO_POSITIONRELATIVE: case IIO_PHASE: + case IIO_MASSCONCENTRATION: break; default: return false; @@ -199,7 +207,13 @@ static bool event_is_known(struct iio_event_data *event) case IIO_MOD_I: case IIO_MOD_Q: case IIO_MOD_CO2: + case IIO_MOD_ETHANOL: + case IIO_MOD_H2: case IIO_MOD_VOC: + case IIO_MOD_PM1: + case IIO_MOD_PM2P5: + case IIO_MOD_PM4: + case IIO_MOD_PM10: break; default: return false; |