diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-07 03:29:27 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-07 03:29:27 +0300 |
commit | e266ca36da7de45b64b05698e98e04b578a88888 (patch) | |
tree | fc9ab60b687a41aedb69c713e239354444259167 | |
parent | e0f0ae838a25464179d37f355d763f9ec139fc15 (diff) | |
parent | 1f08c4a54b7cb62ed6450808c37d06c907f1a2dd (diff) | |
download | linux-e266ca36da7de45b64b05698e98e04b578a88888.tar.xz |
Merge tag 'staging-5.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging/IIO updates from Greg KH:
"Here is the big staging/iio driver pull request for 5.1-rc1.
Lots of good IIO driver updates and cleanups in here as always.
Combined with the removal of the xgifb driver, we have a net "loss" of
over 9000 lines in the pull request, always a nice thing.
As the outreachy application process is currently happening, there are
loads of tiny checkpatch cleanup fixes all over the staging tree,
which accounts for the majority of the fixups"
* tag 'staging-5.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (341 commits)
staging: mt7621-dma: remove license boilerplate text
staging: mt7621-dma: add SPDX GPL-2.0+ license identifier
Staging: ks7010: Replace typecast to int
Staging: vt6655: Align a static function declaration
staging: speakup: fix line over 80 characters.
staging: mt7621-eth: Remove license boilerplate text
staging: mt7621-eth: Add SPDX license identifier
staging: ks7010: removed custom Michael MIC implementation.
staging: rtl8192e: Fix space and suspect issue
Staging: vt6655: Modify comment style of SPDX License Identifier
Staging: vt6655: Modify comment style for SPDX-License-Identifier
Staging: vt6655: Align a function declaration
Staging: vt6655: Alignment of function declaration
staging: rtl8712: Fix indentation issue
staging: wilc1000: fix incorrent type in initializer
staging: rtl8188eu: remove unused P2P_PRIVATE_IOCTL_SET_LEN
staging: rtl8188eu: remove unused enum P2P_PROTO_WK_ID
staging: rtl8723bs: Remove duplicated include from drv_types.h
Staging: vt6655: Alignment should match open parenthesis
staging: erofs: fix mis-acted TAIL merging behavior
...
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; |