diff --git a/patch/kernel/archive/rockchip64-6.1/add-board-Z28-PRO-as-link-to-Rock64.patch b/patch/kernel/archive/rockchip64-6.1/add-board-Z28-PRO-as-link-to-Rock64.patch deleted file mode 100644 index f2b23f8b7d4e..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/add-board-Z28-PRO-as-link-to-Rock64.patch +++ /dev/null @@ -1,22 +0,0 @@ -From d1fb54e1292f2896fc7e485ee13ef2a8a7e87bb5 Mon Sep 17 00:00:00 2001 -From: Igor Pecovnik -Date: Sat, 14 Nov 2020 18:47:08 +0100 -Subject: [PATCH] Add Z28 PRO as link to Rock64 - -Signed-off-by: Igor Pecovnik ---- - arch/arm64/boot/dts/rockchip/rk3328-z28pro.dts | 1 + - 1 file changed, 1 insertion(+) - create mode 120000 arch/arm64/boot/dts/rockchip/rk3328-z28pro.dts - -diff --git a/arch/arm64/boot/dts/rockchip/rk3328-z28pro.dts b/arch/arm64/boot/dts/rockchip/rk3328-z28pro.dts -new file mode 120000 -index 000000000..69752a370 ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3328-z28pro.dts -@@ -0,0 +1 @@ -+rk3328-rock64.dts -\ No newline at end of file --- -Created with Armbian build tools https://github.com/armbian/build - diff --git a/patch/kernel/archive/rockchip64-6.1/add-board-fine3399-dts.patch b/patch/kernel/archive/rockchip64-6.1/add-board-fine3399-dts.patch deleted file mode 100644 index e2eb19924fe1..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/add-board-fine3399-dts.patch +++ /dev/null @@ -1,802 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-fine3399.dts b/arch/arm64/boot/dts/rockchip/rk3399-fine3399.dts -new file mode 100644 ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3399-fine3399.dts -@@ -0,0 +1,797 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+ -+/dts-v1/; -+#include -+#include -+#include -+#include "rk3399.dtsi" -+#include "rk3399-opp.dtsi" -+ -+ -+/ { -+ model = "Rockchip Fine3399"; -+ compatible = "rockchip,fine3399", "rockchip,rk3399"; -+ -+ aliases { -+ mmc0 = &sdio0; -+ mmc1 = &sdmmc; -+ mmc2 = &sdhci; -+ }; -+ -+ chosen { -+ stdout-path = "serial2:1500000n8"; -+ }; -+ -+ clkin_gmac: external-gmac-clock { -+ compatible = "fixed-clock"; -+ clock-frequency = <125000000>; -+ clock-output-names = "clkin_gmac"; -+ #clock-cells = <0>; -+ }; -+ -+ dc_12v: dc-12v { -+ compatible = "regulator-fixed"; -+ regulator-name = "dc_12v"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <12000000>; -+ regulator-max-microvolt = <12000000>; -+ }; -+ -+ sdio_pwrseq: sdio-pwrseq { -+ compatible = "mmc-pwrseq-simple"; -+ clocks = <&rk808 1>; -+ clock-names = "ext_clock"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&wifi_reg_on_h>; -+ reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; // bsp -+ }; -+ -+ /* switched by pmic_sleep */ -+ vcc1v8_s3: vcca1v8_s3: vcc1v8-s3 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc1v8_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ vin-supply = <&vcc_1v8>; -+ }; -+ -+ vcc3v3_sys: vcc3v3_pcie: vcc3v3_bl: vcc3v3-sys { // sch -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc3v3_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&dc_12v>; -+ }; -+ -+ vcc_sys: vcc-sys { // sch -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&dc_12v>; -+ }; -+ -+ vcc_phy: vcc-phy-regulator { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vcc_phy_h>; -+ regulator-name = "vcc_phy"; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ vdd_log: vdd-log { -+ compatible = "pwm-regulator"; -+ pwms = <&pwm2 0 25000 1>; -+ regulator-name = "vdd_log"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <800000>; -+ regulator-max-microvolt = <1400000>; -+ vin-supply = <&vcc_sys>; -+ }; -+ -+ leds: gpio-leds { -+ compatible = "gpio-leds"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&user_led2>; -+ -+ user_led2 { -+ label = "blue:work_led"; -+ gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_LOW>; // sch -+ linux,default-trigger = "heartbeat"; -+ }; -+ }; -+ -+ gpio-keys { -+ compatible = "gpio-keys"; -+ autorepeat; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&power_key>; -+ -+ power { -+ debounce-interval = <100>; -+ gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>; // bsp -+ label = "GPIO Key Power"; -+ linux,code = ; -+ wakeup-source; -+ }; -+ }; -+ -+ fan0: pwm-fan { -+ compatible = "pwm-fan"; -+ cooling-levels = <0 150 200 255>; -+ #cooling-cells = <2>; -+ fan-supply = <&vcc_sys>; -+ pwms = <&pwm1 0 40000 0>; -+ }; -+ -+ // pwm3 -+ ir-receiver { -+ compatible = "gpio-ir-receiver"; -+ gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_LOW>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&ir_int>; -+ }; -+ -+ adc-keys { -+ compatible = "adc-keys"; -+ io-channels = <&saradc 1>; -+ io-channel-names = "buttons"; -+ keyup-threshold-microvolt = <1750000>; -+ poll-interval = <100>; -+ -+ recovery { -+ label = "Recovery"; -+ linux,code = ; // ?? -+ press-threshold-microvolt = <0>; -+ }; -+ }; -+ -+}; -+ -+&cpu_l0 { -+ cpu-supply = <&vdd_cpu_l>; -+}; -+ -+&cpu_l1 { -+ cpu-supply = <&vdd_cpu_l>; -+}; -+ -+&cpu_l2 { -+ cpu-supply = <&vdd_cpu_l>; -+}; -+ -+&cpu_l3 { -+ cpu-supply = <&vdd_cpu_l>; -+}; -+ -+&cpu_b0 { -+ cpu-supply = <&vdd_cpu_b>; -+}; -+ -+&cpu_b1 { -+ cpu-supply = <&vdd_cpu_b>; -+}; -+ -+&gpu { -+ mali-supply = <&vdd_gpu>; -+ status = "okay"; -+}; -+ -+&cpu_thermal { -+ trips { -+ cpu_hot: cpu_hot { -+ hysteresis = <10000>; -+ temperature = <55000>; -+ type = "active"; -+ }; -+ }; -+ -+ cooling-maps { -+ map2 { -+ cooling-device = -+ <&fan0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; -+ trip = <&cpu_hot>; -+ }; -+ }; -+}; -+ -+&emmc_phy { -+ status = "okay"; -+}; -+ -+&gmac { -+ assigned-clocks = <&cru SCLK_RMII_SRC>; -+ assigned-clock-parents = <&clkin_gmac>; -+ clock_in_out = "input"; -+ phy-supply = <&vcc_phy>; -+ phy-mode = "rgmii"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&rgmii_pins>; -+ snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; // bsp -+ snps,reset-active-low; -+ snps,reset-delays-us = <0 10000 50000>; -+ tx_delay = <0x28>; -+ rx_delay = <0x11>; -+ status = "okay"; -+}; -+ -+&hdmi { -+ ddc-i2c-bus = <&i2c3>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hdmi_cec>; -+ status = "okay"; -+}; -+ -+&hdmi_sound { -+ status = "okay"; -+}; -+ -+&i2c0 { -+ clock-frequency = <400000>; -+ i2c-scl-rising-time-ns = <168>; -+ i2c-scl-falling-time-ns = <4>; -+ status = "okay"; -+ -+ rk808: pmic@1b { -+ compatible = "rockchip,rk808"; -+ reg = <0x1b>; -+ interrupt-parent = <&gpio1>; -+ interrupts = ; -+ #clock-cells = <1>; -+ clock-output-names = "xin32k", "rk808-clkout2"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pmic_int_l &pmic_dvs2>; -+ rockchip,system-power-controller; -+ wakeup-source; -+ -+ vcc1-supply = <&vcc3v3_sys>; -+ vcc2-supply = <&vcc3v3_sys>; -+ vcc3-supply = <&vcc3v3_sys>; -+ vcc4-supply = <&vcc3v3_sys>; -+ vcc6-supply = <&vcc3v3_sys>; -+ vcc7-supply = <&vcc3v3_sys>; -+ vcc8-supply = <&vcc3v3_sys>; -+ vcc9-supply = <&vcc3v3_sys>; -+ vcc10-supply = <&vcc3v3_sys>; -+ vcc11-supply = <&vcc3v3_sys>; -+ vcc12-supply = <&vcc3v3_sys>; -+ vddio-supply = <&vcc1v8_pmu>; -+ -+ regulators { -+ vdd_center: DCDC_REG1 { -+ regulator-name = "vdd_center"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <750000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-ramp-delay = <6001>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_cpu_l: DCDC_REG2 { -+ regulator-name = "vdd_cpu_l"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <750000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-ramp-delay = <6001>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_ddr: DCDC_REG3 { -+ regulator-name = "vcc_ddr"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vcc_1v8: DCDC_REG4 { -+ regulator-name = "vcc_1v8"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vcc1v8_dvp: LDO_REG1 { -+ regulator-name = "vcc1v8_dvp"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc3v0_tp: LDO_REG2 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3000000>; -+ regulator-max-microvolt = <3000000>; -+ regulator-name = "vcc3v0_tp"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc1v8_pmu: LDO_REG3 { -+ regulator-name = "vcc1v8_pmu"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vcc_sd: LDO_REG4 { -+ regulator-name = "vcc_sd"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3300000>; -+ }; -+ }; -+ -+ vcca3v0_codec: LDO_REG5 { -+ regulator-name = "vcca3v0_codec"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3000000>; -+ regulator-max-microvolt = <3000000>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_1v5: LDO_REG6 { -+ regulator-name = "vcc_1v5"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1500000>; -+ regulator-max-microvolt = <1500000>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1500000>; -+ }; -+ }; -+ -+ vcca1v8_codec: LDO_REG7 { -+ regulator-name = "vcca1v8_codec"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_3v0: LDO_REG8 { -+ regulator-name = "vcc_3v0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3000000>; -+ regulator-max-microvolt = <3000000>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3000000>; -+ }; -+ }; -+ -+ vcc3v3_s3: SWITCH_REG1 { -+ regulator-name = "vcc3v3_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc3v3_s0: SWITCH_REG2 { -+ regulator-name = "vcc3v3_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ }; -+ }; -+ -+ vdd_cpu_b: regulator@40 { -+ compatible = "silergy,syr827"; -+ reg = <0x40>; -+ fcs,suspend-voltage-selector = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&cpu_b_sleep>; -+ regulator-name = "vdd_cpu_b"; -+ regulator-min-microvolt = <712500>; -+ regulator-max-microvolt = <1500000>; -+ regulator-ramp-delay = <1000>; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&vcc_sys>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_gpu: regulator@41 { -+ compatible = "silergy,syr828"; -+ reg = <0x41>; -+ fcs,suspend-voltage-selector = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&gpu_sleep>; -+ regulator-name = "vdd_gpu"; -+ regulator-min-microvolt = <712500>; -+ regulator-max-microvolt = <1500000>; -+ regulator-ramp-delay = <1000>; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&vcc_sys>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+}; -+ -+// Used for HDMI -+&i2c3 { -+ i2c-scl-rising-time-ns = <450>; -+ i2c-scl-falling-time-ns = <15>; -+ status = "okay"; -+}; -+ -+// HDMI sound -+&i2s2 { -+ #sound-dai-cells = <0>; -+ status = "okay"; -+}; -+ -+&io_domains { -+ status = "okay"; -+ -+ bt656-supply = <&vcc_3v0>; -+ audio-supply = <&vcca1v8_codec>; -+ sdmmc-supply = <&vcc_sd>; -+ gpio1830-supply = <&vcc_3v0>; -+}; -+ -+&pmu_io_domains { -+ status = "okay"; -+ pmu1830-supply = <&vcc_1v8>; -+}; -+ -+&pcie_phy { -+ status = "okay"; -+}; -+ -+&pcie0 { -+ ep-gpios = <&gpio4 RK_PD3 GPIO_ACTIVE_HIGH>; // sch -+ max-link-speed = <2>; -+ num-lanes = <2>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie_clkreqn_cpm>; -+ status = "okay"; -+}; -+ -+&pinctrl { -+ pmic { -+ cpu_b_sleep: cpu-b-sleep { -+ rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ -+ gpu_sleep: gpu-sleep { -+ rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ -+ pmic_int_l: pmic-int-l { -+ rockchip,pins = <1 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ -+ pmic_dvs2: pmic-dvs2 { -+ rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>; // bsp -+ }; -+ }; -+ -+ sdio-pwrseq { -+ wifi_reg_on_h: wifi-reg-on-h { -+ rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ wifi { -+ wifi_host_wake_l: wifi-host-wake-l { -+ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ bt { -+ bt_enable_h: bt-enable-h { -+ rockchip,pins = <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ bt_host_wake_l: bt-host-wake-l { -+ rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ -+ bt_wake_l: bt-wake-l { -+ rockchip,pins = <2 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ gmac { -+ vcc_phy_h: vcc-phy-h { -+ rockchip,pins = <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ -+ leds { -+ user_led2: user_led2 { -+ rockchip,pins = -+ <2 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ ir { -+ ir_int: ir-int { -+ rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ buttons { -+ power_key: power_key { -+ rockchip,pins = -+ <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+}; -+/* -+// TFT -+&pwm0 { -+ status = "okay"; -+}; -+*/ -+// FAN -+&pwm1 { -+ status = "okay"; -+}; -+ -+&pwm2 { -+ status = "okay"; -+}; -+ -+&saradc { -+ vref-supply = <&vcca1v8_s3>; -+ status = "okay"; -+}; -+ -+&sdio0 { -+ bus-width = <4>; -+ cap-sd-highspeed; -+ cap-sdio-irq; -+ clock-frequency = <50000000>; -+ disable-wp; -+ keep-power-in-suspend; -+ max-frequency = <50000000>; -+ mmc-pwrseq = <&sdio_pwrseq>; -+ non-removable; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>; -+ sd-uhs-sdr104; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ brcmf: wifi@1 { -+ reg = <1>; -+ compatible = "brcm,bcm4329-fmac"; -+ interrupt-parent = <&gpio0>; -+ interrupts = ; -+ interrupt-names = "host-wake"; -+ brcm,drive-strength = <5>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&wifi_host_wake_l>; -+ }; -+}; -+ -+&sdmmc { -+ bus-width = <4>; -+ cap-sd-highspeed; -+ cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; // bsp -+ clock-frequency = <150000000>; -+ disable-wp; -+ sd-uhs-sdr104; -+ max-frequency = <150000000>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; -+ vqmmc-supply = <&vcc_sd>; -+ status = "okay"; -+}; -+ -+&sdhci { -+ bus-width = <8>; -+ mmc-hs400-1_8v; -+ mmc-hs400-enhanced-strobe; -+ keep-power-in-suspend; -+ non-removable; -+ status = "okay"; -+}; -+/* -+&spi1 { -+ status = "okay"; -+ -+ norflash: flash@0 { -+ compatible = "jedec,spi-nor"; -+ reg = <0>; -+ spi-max-frequency = <50000000>; -+ }; -+}; -+*/ -+/* -+&spi2 { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi2_clk &spi2_tx &spi2_cs0>; -+ -+ panel@0 { -+ compatible = "sitronix,st7789v"; -+ reg = <0>; -+ // backlight = <&pwm0>; -+ dc-gpios = <&gpio4 RK_PD5 GPIO_ACTIVE_HIGH>; -+ reset-gpios = <&gpio4 RK_PD1 GPIO_ACTIVE_LOW>; -+ led-gpios = <&gpio4 RK_PC2 GPIO_ACTIVE_HIGH>; -+ spi-max-frequency = <15000000>; -+ spi-cs-high; -+ status = "okay"; -+ }; -+}; -+*/ -+&tcphy0 { -+ status = "okay"; -+}; -+ -+&tcphy1 { -+ status = "okay"; -+}; -+ -+&tsadc { -+ /* tshut mode 0:CRU 1:GPIO */ -+ rockchip,hw-tshut-mode = <1>; -+ /* tshut polarity 0:LOW 1:HIGH */ -+ rockchip,hw-tshut-polarity = <1>; -+ status = "okay"; -+}; -+ -+&u2phy0 { -+ status = "okay"; -+ -+ u2phy0_otg: otg-port { -+ status = "okay"; -+ }; -+ -+ u2phy0_host: host-port { -+ status = "okay"; -+ }; -+}; -+ -+&u2phy1 { -+ status = "okay"; -+ -+ u2phy1_otg: otg-port { -+ status = "okay"; -+ }; -+ -+ u2phy1_host: host-port { -+ status = "okay"; -+ }; -+}; -+ -+&uart0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; -+ status = "okay"; -+ -+ bluetooth { -+ compatible = "brcm,bcm43438-bt"; -+ clocks = <&rk808 1>; -+ clock-names = "lpo"; -+ device-wakeup-gpios = <&gpio2 RK_PD2 GPIO_ACTIVE_HIGH>; -+ host-wakeup-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>; -+ shutdown-gpios = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>; -+ max-speed = <4000000>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&bt_host_wake_l &bt_wake_l &bt_enable_h>; -+ vbat-supply = <&vcc3v3_sys>; -+ vddio-supply = <&vcc_1v8>; -+ }; -+}; -+ -+// Debug TTL -+&uart2 { -+ status = "okay"; -+}; -+ -+&usb_host0_ehci { -+ status = "okay"; -+}; -+ -+&usb_host0_ohci { -+ status = "okay"; -+}; -+ -+&usb_host1_ehci { -+ status = "okay"; -+}; -+ -+&usb_host1_ohci { -+ status = "okay"; -+}; -+ -+&usbdrd3_0 { -+ status = "okay"; -+}; -+ -+&usbdrd_dwc3_0 { -+ status = "okay"; -+ dr_mode = "host"; -+}; -+ -+&usbdrd3_1 { -+ status = "okay"; -+}; -+ -+&usbdrd_dwc3_1 { -+ status = "okay"; -+ dr_mode = "host"; -+}; -+ -+&vopb { -+ status = "okay"; -+}; -+ -+&vopb_mmu { -+ status = "okay"; -+}; -+ -+&vopl { -+ status = "okay"; -+}; -+ -+&vopl_mmu { -+ status = "okay"; -+}; -+ -+&iep_mmu { -+ status = "okay"; -+}; diff --git a/patch/kernel/archive/rockchip64-6.1/add-board-h96-tvbox-3566.patch b/patch/kernel/archive/rockchip64-6.1/add-board-h96-tvbox-3566.patch deleted file mode 100644 index 50b8ba9e9155..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/add-board-h96-tvbox-3566.patch +++ /dev/null @@ -1,796 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile -index 8c15593c0..2e861a2ea 100644 ---- a/arch/arm64/boot/dts/rockchip/Makefile -+++ b/arch/arm64/boot/dts/rockchip/Makefile -@@ -69,6 +69,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-a.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-b.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-roc-pc.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-soquartz-cm4.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-h96-tvbox.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-bpi-r2-pro.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-v10.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-rock-3a.dtb -diff --git a/arch/arm64/boot/dts/rockchip/rk3566-h96-tvbox.dts b/arch/arm64/boot/dts/rockchip/rk3566-h96-tvbox.dts -new file mode 100644 -index 000000000..6a53d23a5 ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3566-h96-tvbox.dts -@@ -0,0 +1,579 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Copyright (c) 2024 hqnicolas -+ */ -+ -+/dts-v1/; -+ -+#include -+#include -+#include -+#include -+#include "rk3566.dtsi" -+ -+/ { -+ model = "h96 TVbox 3566"; -+ compatible = "h96-TVbox,rk3566", "rockchip,rk3566"; -+ -+ aliases { -+ ethernet0 = &gmac1; -+ mmc0 = &sdmmc0; -+ mmc1 = &sdhci; -+ mmc2 = &sdmmc1; -+ }; -+ -+ chosen: chosen { -+ stdout-path = "serial2:1500000n8"; -+ }; -+ -+ vcc5v0_in: vcc5v0_in { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v0_in"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ }; -+ -+ gmac1_clkin: external-gmac1-clock { -+ compatible = "fixed-clock"; -+ clock-frequency = <125000000>; -+ clock-output-names = "gmac1_clkin"; -+ #clock-cells = <0>; -+ }; -+ -+ hdmi-con { -+ compatible = "hdmi-connector"; -+ type = "a"; -+ -+ port { -+ hdmi_con_in: endpoint { -+ remote-endpoint = <&hdmi_out_con>; -+ }; -+ }; -+ }; -+ -+ ir-receiver { -+ compatible = "gpio-ir-receiver"; -+ gpios = <&gpio0 RK_PC2 GPIO_ACTIVE_LOW>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&ir_receiver_pin>; -+ }; -+ -+ spdif_dit: spdif-dit { -+ compatible = "linux,spdif-dit"; -+ #sound-dai-cells = <0>; -+ }; -+ -+ spdif_sound: spdif-sound { -+ compatible = "simple-audio-card"; -+ simple-audio-card,name = "SPDIF"; -+ -+ simple-audio-card,cpu { -+ sound-dai = <&spdif>; -+ }; -+ -+ simple-audio-card,codec { -+ sound-dai = <&spdif_dit>; -+ }; -+ }; -+ -+ vcc3v3_sys: vcc3v3-sys { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc3v3_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ vcc5v0_sys: vcc5v0_sys { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v0_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc5v0_in>; -+ }; -+ -+ vcc5v0_host: vcc5v0-host-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v0_host"; -+ enable-active-high; -+ gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vcc5v0_host_en>; -+ regulator-always-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ vcc5v0_otg: vcc5v0-otg-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v0_otg"; -+ enable-active-high; -+ gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vcc5v0_otg_en>; -+ regulator-always-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ vcc3v3_pcie_p: vcc3v3-pcie-p-regulator { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio0 RK_PC4 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie_enable_h>; -+ regulator-name = "vcc3v3_pcie_p"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&vcc_3v3>; -+ }; -+ -+ leds { -+ compatible = "gpio-leds"; -+ -+ led_status: led-status { -+ label = "led-status"; -+ gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "heartbeat"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&led_status_enable_h>; -+ }; -+ -+ led_power: led-power { -+ label = "led-power"; -+ gpios = <&gpio0 RK_PD3 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "default-on"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&led_power_enable_h>; -+ }; -+ }; -+ -+ vbus: vbus-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vbus"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ }; -+ -+ sdio_pwrseq: sdio-pwrseq { -+ status = "okay"; -+ compatible = "mmc-pwrseq-simple"; -+ clocks = <&rk809 1>; -+ clock-names = "ext_clock"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&wifi_enable_h>; -+ reset-gpios = <&gpio2 RK_PB1 GPIO_ACTIVE_LOW>; -+ post-power-on-delay-ms = <100>; -+ }; -+ -+ rk809_sound: rk809-sound { -+ status = "okay"; -+ compatible = "simple-audio-card"; -+ simple-audio-card,format = "i2s"; -+ simple-audio-card,name = "rockchip,rk809-codec"; -+ simple-audio-card,mclk-fs = <256>; -+ -+ simple-audio-card,cpu { -+ sound-dai = <&i2s1_8ch>; -+ }; -+ simple-audio-card,codec { -+ sound-dai = <&rk809_codec>; -+ }; -+ }; -+ -+ rk_headset: rk-headset { -+ compatible = "rockchip_headset"; -+ headset_gpio = <&gpio2 RK_PD2 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hp_det>; -+ io-channels = <&saradc 2>; //HP_HOOK pin -+ }; -+}; -+ -+&combphy1 { -+ status = "okay"; -+}; -+ -+&combphy2 { -+ status = "okay"; -+}; -+ -+&cpu0 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu1 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu2 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu3 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&gmac1 { -+ assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru SCLK_GMAC1>; -+ assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru SCLK_GMAC1>, <&gmac1_clkin>; -+ clock_in_out = "input"; -+ phy-supply = <&vcc_3v3>; -+ phy-mode = "rgmii"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&gmac1m0_miim -+ &gmac1m0_tx_bus2 -+ &gmac1m0_rx_bus2 -+ &gmac1m0_rgmii_clk -+ &gmac1m0_clkinout -+ &gmac1m0_rgmii_bus>; -+ snps,reset-gpio = <&gpio0 RK_PB7 GPIO_ACTIVE_LOW>; -+ snps,reset-active-low; -+ /* Reset time is 20ms, 100ms for rtl8211f, also works well here */ -+ snps,reset-delays-us = <0 20000 100000>; -+ tx_delay = <0x41>; -+ rx_delay = <0x2e>; -+ phy-handle = <&rgmii_phy1>; -+ status = "okay"; -+}; -+ -+&hdmi { -+ assigned-clocks = <&cru CLK_HDMI_CEC>; -+ assigned-clock-rates = <32768>; -+ avdd-0v9-supply = <&vdda0v9_image>; -+ avdd-1v8-supply = <&vcca1v8_image>; -+ status = "okay"; -+}; -+ -+&hdmi_in { -+ hdmi_in_vp0: endpoint { -+ remote-endpoint = <&vp0_out_hdmi>; -+ }; -+}; -+ -+&hdmi_out { -+ hdmi_out_con: endpoint { -+ remote-endpoint = <&hdmi_con_in>; -+ }; -+}; -+ -+&hdmi_sound { -+ status = "okay"; -+}; -+ -+&gpu { -+ mali-supply = <&vdd_gpu>; -+ status = "okay"; -+}; -+ -+&i2c0 { -+ status = "okay"; -+ -+ vdd_cpu: regulator@1c { -+ compatible = "tcs,tcs4525"; -+ reg = <0x1c>; -+ fcs,suspend-voltage-selector = <1>; -+ regulator-name = "vdd_cpu"; -+ regulator-min-microvolt = <800000>; -+ regulator-max-microvolt = <1150000>; -+ regulator-ramp-delay = <2300>; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&vcc5v0_sys>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ rk809: pmic@20 { -+ compatible = "rockchip,rk809"; -+ reg = <0x20>; -+ interrupt-parent = <&gpio0>; -+ interrupts = ; -+ #clock-cells = <1>; -+ #sound-dai-cells = <0>; -+ clock-output-names = "rk808-clkout1", "rk808-clkout2"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pmic_int_l>; -+ rockchip,system-power-controller; -+ wakeup-source; -+ -+ vcc1-supply = <&vcc3v3_sys>; -+ vcc2-supply = <&vcc3v3_sys>; -+ vcc3-supply = <&vcc3v3_sys>; -+ vcc4-supply = <&vcc3v3_sys>; -+ vcc5-supply = <&vcc3v3_sys>; -+ vcc6-supply = <&vcc3v3_sys>; -+ vcc7-supply = <&vcc3v3_sys>; -+ vcc8-supply = <&vcc3v3_sys>; -+ vcc9-supply = <&vcc3v3_sys>; -+ -+ regulators { -+ vdd_logic: DCDC_REG1 { -+ regulator-name = "vdd_logic"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <500000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-init-microvolt = <900000>; -+ regulator-ramp-delay = <6001>; -+ regulator-initial-mode = <0x2>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_gpu: DCDC_REG2 { -+ regulator-name = "vdd_gpu"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <500000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-init-microvolt = <900000>; -+ regulator-ramp-delay = <6001>; -+ regulator-initial-mode = <0x2>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_ddr: DCDC_REG3 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-initial-mode = <0x2>; -+ regulator-name = "vcc_ddr"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vdd_npu: DCDC_REG4 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <500000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-init-microvolt = <900000>; -+ regulator-initial-mode = <0x2>; -+ regulator-name = "vdd_npu"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdda0v9_image: LDO_REG1 { -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ regulator-name = "vdda0v9_image"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdda_0v9: LDO_REG2 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ regulator-name = "vdda_0v9"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdda0v9_pmu: LDO_REG3 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ regulator-name = "vdda0v9_pmu"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <900000>; -+ }; -+ }; -+ -+ vccio_acodec: LDO_REG4 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-name = "vccio_acodec"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vccio_sd: LDO_REG5 { -+ regulator-name = "vccio_sd"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc3v3_pmu: LDO_REG6 { -+ regulator-name = "vcc3v3_pmu"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3300000>; -+ }; -+ }; -+ -+ vcca_1v8: LDO_REG7 { -+ regulator-name = "vcca_1v8"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcca1v8_pmu: LDO_REG8 { -+ regulator-name = "vcca1v8_pmu"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vcca1v8_image: LDO_REG9 { -+ regulator-name = "vcca1v8_image"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_1v8: DCDC_REG5 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-name = "vcc_1v8"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_3v3: SWITCH_REG1 { -+ regulator-name = "vcc_3v3"; -+ regulator-always-on; -+ regulator-boot-on; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc3v3_sd: SWITCH_REG2 { -+ regulator-name = "vcc3v3_sd"; -+ regulator-always-on; -+ regulator-boot-on; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ }; -+ -+ rk809_codec: codec { -+ mic-in-differential; -+ }; -+ }; -+ }; -+ -+&i2s0_8ch { -+ status = "okay"; -+}; -+ -+&i2s1_8ch { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s1m0_sclktx -+ &i2s1m0_lrcktx -+ &i2s1m0_sdi0 -+ &i2s1m0_sdo0>; -+ rockchip,trcm-sync-tx-only; -+}; -+ -+&mdio1 { -+ rgmii_phy1: ethernet-phy@0 { -+ compatible = "ethernet-phy-ieee802.3-c22"; -+ reg = <0>; -+ status = "okay"; -+ }; -+}; -+ -+&pcie2x1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie_reset_h>; -+ reset-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>; -+ vpcie3v3-supply = <&vcc3v3_pcie_p>; -+ status = "disabled"; -+}; -+ -+&pinctrl { -+ sdio-pwrseq { -+ wifi_enable_h: wifi-enable-h { -+ rockchip,pins = <2 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ wireless-wlan { -+ wifi_host_wake_irq: wifi-host-wake-irq { -+ rockchip,pins = <2 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ bt { -+ bt_enable_h: bt-enable-h { -+ rockchip,pins = <2 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ bt_host_wake_l: bt-host-wake-l { -+ rockchip,pins = <2 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ bt_wake_l: bt-wake-l { -+ rockchip,pins = <2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ pmic { -+ pmic_int_l: pmic-int-l { -+ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ -+ usb { -+ vcc5v0_host_en: vcc5v0-host-en { -+ rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ vcc5v0_otg_en: vcc5v0-otg-en { -+ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ pcie { -+ pcie_enable_h: pcie-enable-h { -+ rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ pcie_reset_h: pcie-reset-h { -+ rockchip,pins = <1 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ ir-receiver { -+ ir_receiver_pin: ir-receiver-pin { -+ rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ leds { -+ led_status_enable_h: led-status-enable-h { -+ rockchip,pins = <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ led_power_enable_h: led_power_enable_h { -+ rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ headphone { -+ hp_det: hp-det { -+ rockchip,pins = <2 RK_PD2 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+}; -+ -+&pmu_io_domains { -+ pmuio1-supply = <&vcc3v3_pmu>; -+ pmuio2-supply = <&vcc3v3_pmu>; -+ vccio1-supply = <&vccio_acodec>; -+ vccio2-supply = <&vcc_1v8>; -+ vccio3-supply = <&vccio_sd>; -+ vccio4-supply = <&vcc_1v8>; -+ vccio5-supply = <&vcc_3v3>; -+ vccio6-supply = <&vcc_1v8>; -+ vccio7-supply = <&vcc_3v3>; -+ status = "okay"; -+}; -+ -+&saradc { -+ vref-supply = <&vcca_1v8>; -+ status = "okay"; -+}; -+ -+&sata2 { -+ status = "disabled"; -+}; -+ -+&sdhci { -+ bus-width = <8>; -+ mmc-hs200-1_8v; -+ non-removable; -+ vmmc-supply = <&vcc_3v3>; -+ vqmmc-supply = <&vcc_1v8>; -+ status = "okay"; -+}; -+ -+&sdmmc0 { -+ bus-width = <4>; -+ cap-sd-highspeed; -+ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; -+ disable-wp; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>; -+ sd-uhs-sdr104; -+ vmmc-supply = <&vcc3v3_sd>; -+ vqmmc-supply = <&vccio_sd>; -+ status = "okay"; -+}; -+ -+&sdmmc1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ bus-width = <4>; -+ cap-sd-highspeed; -+ cap-sdio-irq; -+ disable-wp; -+ keep-power-in-suspend; -+ mmc-pwrseq = <&sdio_pwrseq>; -+ non-removable; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_cmd &sdmmc1_clk>; -+ sd-uhs-sdr50; -+ supports-sdio; -+ status = "okay"; -+ vmmc-supply = <&vcc3v3_sys>; -+ vqmmc-supply = <&vcca1v8_pmu>; -+ -+ brcmf: wifi@1 { -+ compatible = "brcm,bcm4329-fmac"; -+ reg = <1>; -+ interrupt-parent = <&gpio2>; -+ interrupts = ; -+ interrupt-names = "host-wake"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&wifi_host_wake_irq>; -+ }; -+}; -+ -+&tsadc { -+ status = "okay"; -+}; -+ -+&uart1 { -+ pinctrl-names = "default"; -+ dma-names = "tx", "rx"; -+ pinctrl-0 = <&uart1m0_xfer &uart1m0_ctsn &uart1m0_rtsn>; -+ status = "okay"; -+ uart-has-rtscts; -+ -+ bluetooth { -+ compatible = "brcm,bcm43438-bt"; -+ clocks = <&rk809 1>; -+ clock-names = "lpo"; -+ device-wake-gpios = <&gpio2 RK_PC1 GPIO_ACTIVE_HIGH>; -+ host-wake-gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>; -+ shutdown-gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>; -+ max-speed = <3000000>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&bt_host_wake_l &bt_wake_l &bt_enable_h>; -+ vbat-supply = <&vcc3v3_sys>; -+ vddio-supply = <&vcca1v8_pmu>; -+ }; -+}; -+ -+&uart2 { -+ status = "okay"; -+}; -+ -+&usb_host0_xhci { -+ dr_mode = "host"; -+ status = "okay"; -+}; -+ -+&usb2phy0 { -+ status = "okay"; -+}; -+ -+&usb2phy0_host { -+ status = "okay"; -+}; -+ -+&usb2phy0_otg { -+ status = "okay"; -+}; -+ -+&usb_host1_xhci { -+ status = "okay"; -+}; -+ -+&usb2phy1 { -+ status = "okay"; -+}; -+ -+&usb2phy1_host { -+ status = "okay"; -+}; -+ -+&usb2phy1_otg { -+ status = "okay"; -+}; -+ -+&vop { -+ assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>; -+ assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>; -+ status = "okay"; -+}; -+ -+&vpu { -+ status = "okay"; -+}; -+ -+&vop_mmu { -+ status = "okay"; -+}; -+ -+&vp0 { -+ vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { -+ reg = ; -+ remote-endpoint = <&hdmi_in_vp0>; -+ }; -+}; - diff --git a/patch/kernel/archive/rockchip64-6.1/add-board-helios64.patch b/patch/kernel/archive/rockchip64-6.1/add-board-helios64.patch deleted file mode 100644 index b0c86559fab1..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/add-board-helios64.patch +++ /dev/null @@ -1,1175 +0,0 @@ -From 8f81af6941883fdc1d238d85bf282c2a61ffa349 Mon Sep 17 00:00:00 2001 -From: Aditya Prayoga -Date: Tue, 15 Sep 2020 20:04:22 +0700 -Subject: [PATCH] Add board Helios64 - -Signed-off-by: Aditya Prayoga ---- - .../boot/dts/rockchip/rk3399-kobol-helios64.dts | 1084 +++++++++++++++++ - 2 files changed, 1085 insertions(+) - create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts - -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts -new file mode 100644 -index 000000000..fae17f416 ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts -@@ -0,0 +1,1154 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Copyright (c) 2020 Aditya Prayoga (aditya@kobol.io) -+ */ -+ -+/dts-v1/; -+#include -+#include -+#include -+#include -+#include "rk3399.dtsi" -+#include "rk3399-opp.dtsi" -+ -+/ { -+ model = "Helios64"; -+ compatible = "kobol,helios64", "rockchip,rk3399"; -+ -+ adc-keys { -+ compatible = "adc-keys"; -+ io-channels = <&saradc 1>; -+ io-channel-names = "buttons"; -+ keyup-threshold-microvolt = <1800000>; -+ poll-interval = <100>; -+ -+ user2-button { -+ label = "User Button 2"; -+ linux,code = ; -+ press-threshold-microvolt = <100000>; -+ }; -+ }; -+ -+ beeper: beeper { -+ compatible = "gpio-beeper"; -+ gpios = <&gpio4 RK_PD3 GPIO_ACTIVE_HIGH>; -+ }; -+ -+ clkin_gmac: external-gmac-clock { -+ compatible = "fixed-clock"; -+ clock-frequency = <125000000>; -+ clock-output-names = "clkin_gmac"; -+ #clock-cells = <0>; -+ }; -+ -+ vcc12v_dcin: vcc12v-dcin { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc12v_dcin"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <12000000>; -+ regulator-max-microvolt = <12000000>; -+ }; -+ -+ vcc12v_dcin_bkup: vcc12v-dcin-bkup { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc12v_dcin_bkup"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <12000000>; -+ regulator-max-microvolt = <12000000>; -+ vin-supply = <&vcc12v_dcin>; -+ }; -+ -+ vcc12v_hdd: vcc12v-hdd { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc12v_hdd"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <12000000>; -+ regulator-max-microvolt = <12000000>; -+ vin-supply = <&vcc12v_dcin_bkup>; -+ }; -+ -+ /* switched by pmic_sleep */ -+ vcc1v8_sys_s0: vcc1v8-sys-s0 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc1v8_sys_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ vin-supply = <&vcc1v8_sys_s3>; -+ }; -+ -+ vcc0v9_s3: vcc0v9-s3 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc0v9_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ vin-supply = <&vcc3v3_sys_s3>; -+ }; -+ -+ avdd_0v9_s0: avdd-0v9-s0 { -+ compatible = "regulator-fixed"; -+ regulator-name = "avdd_0v9_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ vin-supply = <&vcc1v8_sys_s3>; -+ }; -+ -+ avdd_1v8_s0: avdd-1v8-s0 { -+ compatible = "regulator-fixed"; -+ regulator-name = "avdd_1v8_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ vin-supply = <&vcc3v3_sys_s3>; -+ }; -+ -+ pcie_power: pcie-power { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio1 RK_PD0 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie_pwr_en>; -+ regulator-name = "pcie_power"; -+ regulator-boot-on; -+ startup-delay-us = <10000>; -+ vin-supply = <&vcc5v0_perdev>; -+ }; -+ -+ vcc3v3_sys_s3: vcc_lan: vcc3v3-sys-s3 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc3v3_sys_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&vcc5v0_sys>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vcc3v0_sd: vcc3v0-sd { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc3v0_sd"; -+ regulator-boot-on; -+ regulator-min-microvolt = <3000000>; -+ regulator-max-microvolt = <3000000>; -+ vin-supply = <&vcc3v3_sys_s3>; -+ }; -+ -+ vcc5v0_usb: vcc5v0-usb { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio1 RK_PC6 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vcc5v0_usb_en>; -+ regulator-name = "vcc5v0_usb"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc5v0_perdev>; -+ }; -+ -+ vcc5v0_typec: vcc5v0-typec-regulator { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio1 RK_PA3 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&fusb0_vbus_en>; -+ regulator-name = "vcc5v0_typec"; -+ vin-supply = <&vcc5v0_usb>; -+ }; -+ -+ vcc5v0_perdev: vcc5v0-perdev { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v0_perdev"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc12v_dcin_bkup>; -+ }; -+ -+ vcc5v0_hdd: vcc5v0-hdd { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v0_hdd"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc12v_dcin_bkup>; -+ }; -+ -+ vcc5v0_sys: vcc5v0-sys { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v0_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc12v_dcin_bkup>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vdd_log: vdd-log { -+ compatible = "pwm-regulator"; -+ pwms = <&pwm2 0 25000 1>; -+ pwm-supply = <&vcc5v0_sys>; -+ regulator-name = "vdd_log"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <830000>; -+ regulator-max-microvolt = <1400000>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <900000>; -+ }; -+ }; -+ -+ power_hdd_a: power-hdd-a { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hdd_a_power>; -+ regulator-name = "power_hdd_a"; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ power_hdd_b: power-hdd-b { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio1 RK_PA1 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hdd_b_power>; -+ regulator-name = "power_hdd_b"; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ usblan_power: usblan-power { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio1 RK_PC7 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&usb_lan_en>; -+ regulator-name = "usblan_power"; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&vcc5v0_usb>; -+ }; -+ -+ fan1: p7-fan { -+ compatible = "pwm-fan"; -+ pwms = <&pwm0 0 40000 0>; -+ cooling-min-state = <0>; -+ cooling-max-state = <3>; -+ #cooling-cells = <2>; -+ cooling-levels = <0 80 170 255>; -+ }; -+ -+ fan2: p6-fan { -+ compatible = "pwm-fan"; -+ pwms = <&pwm1 0 40000 0>; -+ cooling-min-state = <0>; -+ cooling-max-state = <3>; -+ #cooling-cells = <2>; -+ cooling-levels = <0 80 170 255>; -+ }; -+ -+ gpio-charger { -+ compatible = "gpio-charger"; -+ charger-type = "mains"; -+ gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; -+ charge-status-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&ac_present_ap>, <&charger_status>; -+ }; -+ -+ gpio-keys { -+ compatible = "gpio-keys"; -+ autorepeat; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pwrbtn>, <&user1btn>, <&wake_on_lan>; -+ -+ power { -+ debounce-interval = <100>; -+ gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>; -+ label = "Power"; -+ linux,code = ; -+ wakeup-source; -+ }; -+ -+ user1-button { -+ debounce-interval = <100>; -+ gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_LOW>; -+ label = "User Button 1"; -+ linux,code = ; -+ wakeup-source; -+ }; -+ }; -+ -+ hdmi_dp_sound: hdmi-dp-sound { -+ status = "okay"; -+ compatible = "rockchip,rk3399-hdmi-dp"; -+ rockchip,cpu = <&i2s2>; -+ rockchip,codec = <&cdn_dp>; -+ }; -+ -+ io_leds: io-gpio-leds { -+ status = "okay"; -+ compatible = "gpio-leds"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&network_act>, <&usb3_act>, -+ <&sata_act>, <&sata_err_led>; -+ -+ network { -+ label = "helios64:blue:net"; -+ gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "netdev"; -+ default-state = "off"; -+ }; -+ -+ sata { -+ label = "helios64:blue:hdd-status"; -+ gpios = <&gpio4 RK_PD4 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "disk-activity"; -+ default-state = "off"; -+ }; -+ -+ sata_err1 { -+ label = "helios64:red:ata1-err"; -+ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_HIGH>; -+ default-state = "keep"; -+ }; -+ -+ sata_err2 { -+ label = "helios64:red:ata2-err"; -+ gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_HIGH>; -+ default-state = "keep"; -+ }; -+ -+ sata_err3 { -+ label = "helios64:red:ata3-err"; -+ gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_HIGH>; -+ default-state = "keep"; -+ }; -+ -+ sata_err4 { -+ label = "helios64:red:ata4-err"; -+ gpios = <&gpio2 RK_PA5 GPIO_ACTIVE_HIGH>; -+ default-state = "keep"; -+ }; -+ -+ sata_err5 { -+ label = "helios64:red:ata5-err"; -+ gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_HIGH>; -+ default-state = "keep"; -+ }; -+ -+ usb3 { -+ label = "helios64:blue:usb3"; -+ gpios = <&gpio0 RK_PB3 GPIO_ACTIVE_HIGH>; -+ trigger-sources = <&int_hub_port1>, -+ <&int_hub_port2>, -+ <&int_hub_port3>; -+ linux,default-trigger = "usbport"; -+ default-state = "off"; -+ }; -+ }; -+ -+ pwmleds { -+ compatible = "pwm-leds"; -+ status = "okay"; -+ -+ power-led { -+ label = "helios64:blue:power-status"; -+ pwms = <&pwm3 0 2000000000 0>; -+ max-brightness = <255>; -+ }; -+ }; -+ -+ system_leds: system-gpio-leds { -+ status = "okay"; -+ compatible = "gpio-leds"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&system_led>; -+ -+ status-led { -+ label = "helios64::status"; -+ gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "none"; -+ default-state = "on"; -+ mode = <0x23>; -+ }; -+ -+ fault-led { -+ label = "helios64:red:fault"; -+ gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "panic"; -+ default-state = "keep"; -+ mode = <0x23>; -+ }; -+ }; -+}; -+ -+&cdn_dp { -+ status = "okay"; -+ extcon = <&fusb0>; -+ phys = <&tcphy0_dp>; -+}; -+ -+&cpu_l0 { -+ cpu-supply = <&vdd_cpu_l>; -+}; -+ -+&cpu_l1 { -+ cpu-supply = <&vdd_cpu_l>; -+}; -+ -+&cpu_l2 { -+ cpu-supply = <&vdd_cpu_l>; -+}; -+ -+&cpu_l3 { -+ cpu-supply = <&vdd_cpu_l>; -+}; -+ -+&cpu_b0 { -+ cpu-supply = <&vdd_cpu_b>; -+}; -+ -+&cpu_b1 { -+ cpu-supply = <&vdd_cpu_b>; -+}; -+ -+&emmc_phy { -+ status = "okay"; -+}; -+ -+&gmac { -+ assigned-clocks = <&cru SCLK_RMII_SRC>; -+ assigned-clock-parents = <&clkin_gmac>; -+ clock_in_out = "input"; -+ phy-supply = <&vcc_lan>; -+ phy-mode = "rgmii"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&rgmii_pins &rgmii_phy_reset>; -+ snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; -+ snps,reset-active-low; -+ snps,reset-delays-us = <0 10000 50000>; -+ tx_delay = <0x28>; -+ rx_delay = <0x20>; -+ status = "okay"; -+}; -+ -+&gpu { -+ mali-supply = <&vdd_gpu>; -+ status = "okay"; -+}; -+ -+&i2c0 { -+ clock-frequency = <400000>; -+ i2c-scl-rising-time-ns = <168>; -+ i2c-scl-falling-time-ns = <4>; -+ status = "okay"; -+ -+ rk808: pmic@1b { -+ compatible = "rockchip,rk808"; -+ reg = <0x1b>; -+ #clock-cells = <1>; -+ clock-output-names = "xin32k", "rk808-clkout2"; -+ interrupt-parent = <&gpio0>; -+ interrupts = <10 IRQ_TYPE_LEVEL_LOW>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pmic_int_l>; -+ rockchip,system-power-controller; -+ wakeup-source; -+ -+ vcc1-supply = <&vcc5v0_sys>; -+ vcc2-supply = <&vcc5v0_sys>; -+ vcc3-supply = <&vcc5v0_sys>; -+ vcc4-supply = <&vcc5v0_sys>; -+ vcc6-supply = <&vcc5v0_sys>; -+ vcc7-supply = <&vcc5v0_sys>; -+ vcc8-supply = <&vcc3v3_sys_s3>; -+ vcc9-supply = <&vcc5v0_sys>; -+ vcc10-supply = <&vcc5v0_sys>; -+ vcc11-supply = <&vcc5v0_sys>; -+ vcc12-supply = <&vcc3v3_sys_s3>; -+ vddio-supply = <&vcc3v0_s3>; -+ -+ regulators { -+ vdd_center: DCDC_REG1 { -+ regulator-name = "vdd_center"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <800000>; -+ regulator-max-microvolt = <1000000>; -+ regulator-ramp-delay = <6001>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <950000>; -+ }; -+ }; -+ -+ vdd_cpu_l: DCDC_REG2 { -+ regulator-name = "vdd_cpu_l"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <750000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-ramp-delay = <6001>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_ddr_s3: DCDC_REG3 { -+ regulator-name = "vcc_ddr_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vcc1v8_sys_s3: DCDC_REG4 { -+ regulator-name = "vcc1v8_sys_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ /* not used */ -+ vcc1v8_dvp: LDO_REG1 { -+ regulator-name = "vcc1v8_dvp"; -+ }; -+ -+ /* not used */ -+ vcc3v0_touch: LDO_REG2 { -+ regulator-name = "vcc3v0_touch"; -+ }; -+ -+ vcc1v8_s3: LDO_REG3 { -+ regulator-name = "vcc1v8_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vcc_sdio_s0: LDO_REG4 { -+ regulator-name = "vcc_sdio_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3000000>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3000000>; -+ }; -+ }; -+ -+ /* not used */ -+ vcca3v0_codec: LDO_REG5 { -+ regulator-name = "vcca3v0_codec"; -+ }; -+ -+ vcc1v5_s3: LDO_REG6 { -+ regulator-name = "vcc1v5_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1500000>; -+ regulator-max-microvolt = <1500000>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1500000>; -+ }; -+ }; -+ -+ /* not used */ -+ vcca1v8_codec: LDO_REG7 { -+ regulator-name = "vcca1v8_codec"; -+ }; -+ -+ vcc3v0_s3: LDO_REG8 { -+ regulator-name = "vcc3v0_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3000000>; -+ regulator-max-microvolt = <3000000>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3000000>; -+ }; -+ }; -+ -+ vcc3v3_sys_s0: SWITCH_REG1 { -+ regulator-name = "vcc3v3_sys_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ /* not used */ -+ vcc3v3_s0: SWITCH_REG2 { -+ regulator-name = "vcc3v3_s0"; -+ }; -+ }; -+ }; -+ -+ vdd_cpu_b: regulator@40 { -+ compatible = "silergy,syr827"; -+ reg = <0x40>; -+ fcs,suspend-voltage-selector = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vsel1_gpio>; -+ regulator-name = "vdd_cpu_b"; -+ regulator-min-microvolt = <712500>; -+ regulator-max-microvolt = <1500000>; -+ regulator-ramp-delay = <40000>; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&vcc5v0_sys>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_gpu: regulator@41 { -+ compatible = "silergy,syr828"; -+ reg = <0x41>; -+ fcs,suspend-voltage-selector = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vsel2_gpio>; -+ regulator-name = "vdd_gpu"; -+ regulator-min-microvolt = <712500>; -+ regulator-max-microvolt = <1500000>; -+ regulator-ramp-delay = <1000>; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&vcc5v0_sys>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+}; -+ -+&i2c2 { -+ clock-frequency = <400000>; -+ i2c-scl-rising-time-ns = <160>; -+ i2c-scl-falling-time-ns = <30>; -+ status = "okay"; -+ -+ gpio-expander@20 { -+ compatible = "nxp,pca9555"; -+ reg = <0x20>; -+ gpio-controller; -+ #gpio-cells = <2>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pca0_pins>; -+ interrupt-parent = <&gpio0>; -+ interrupts = <9 IRQ_TYPE_EDGE_FALLING>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ vcc-supply = <&vcc3v3_sys_s3>; -+ }; -+ -+ temp@4c { -+ compatible = "national,lm75"; -+ reg = <0x4c>; -+ }; -+}; -+ -+&i2c4 { -+ clock-frequency = <400000>; -+ i2c-scl-rising-time-ns = <160>; -+ i2c-scl-falling-time-ns = <30>; -+ status = "okay"; -+ -+ fusb0: typec-portc@22 { -+ compatible = "fcs,fusb302"; -+ reg = <0x22>; -+ interrupt-parent = <&gpio1>; -+ interrupts = ; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&fusb0_int>; -+ vbus-supply = <&vcc5v0_typec>; -+ -+ connector { -+ compatible = "usb-c-connector"; -+ label = "USB-C"; -+ power-role = "dual"; -+ data-role = "dual"; -+ try-power-role = "sink"; -+ source-pdos = ; -+ sink-pdos = ; -+ op-sink-microwatt = <5000000>; -+ -+ extcon-cables = <1 2 5 6 9 10 12 44>; -+ typec-altmodes = <0xff01 1 0x001c0000 1>; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ port@0 { -+ reg = <0>; -+ usb_con_hs: endpoint { -+ remote-endpoint = <&u2phy0_typec_hs>; -+ }; -+ }; -+ port@1 { -+ reg = <1>; -+ usb_con_ss: endpoint { -+ remote-endpoint = <&tcphy0_typec_ss>; -+ }; -+ }; -+ port@2 { -+ reg = <2>; -+ usb_con_sbu: endpoint { -+ remote-endpoint = <&tcphy0_typec_dp>; -+ }; -+ }; -+ }; -+ }; -+ }; -+}; -+ -+/* I2C on UEXT */ -+&i2c7 { -+ status = "okay"; -+}; -+ -+/* External I2C */ -+&i2c8 { -+ status = "okay"; -+}; -+ -+&i2s2 { -+ #sound-dai-cells = <0>; -+ status = "okay"; -+}; -+ -+&io_domains { -+ status = "okay"; -+ bt656-supply = <&vcc1v8_sys_s0>; -+ audio-supply = <&vcc1v8_sys_s0>; -+ sdmmc-supply = <&vcc_sdio_s0>; -+ gpio1830-supply = <&vcc3v0_s3>; -+}; -+ -+&pcie0 { -+ ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>; -+ num-lanes = <2>; -+ max-link-speed = <2>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie_prst &pcie_clkreqn_cpm>; -+ vpcie12v-supply = <&vcc12v_dcin>; -+ vpcie3v3-supply = <&pcie_power>; -+ vpcie1v8-supply = <&avdd_1v8_s0>; -+ vpcie0v9-supply = <&avdd_0v9_s0>; -+ status = "okay"; -+}; -+ -+&pcie_phy { -+ status = "okay"; -+}; -+ -+&pinctrl { -+ buttons { -+ pwrbtn: pwrbtn { -+ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ -+ user1btn: usr1btn { -+ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ charger { -+ ac_present_ap: ac-present-ap { -+ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ charger_status: charger-status { -+ rockchip,pins = <2 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ fan { -+ fan1_sense: fan1-sense { -+ rockchip,pins = <4 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ fan2_sense: fan2-sense { -+ rockchip,pins = <4 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ fusb30x { -+ fusb0_int: fusb0-int { -+ rockchip,pins = -+ <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ -+ fusb0_vbus_en: fusb0-vbus-en { -+ rockchip,pins = -+ <1 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ -+ gmac { -+ rgmii_phy_reset: rgmii-phy-reset { -+ rockchip,pins = -+ <3 RK_PB7 RK_FUNC_GPIO &pcfg_output_low>; -+ }; -+ }; -+ -+ leds { -+ network_act: network-act { -+ rockchip,pins = -+ <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ -+ usb3_act: usb3-act { -+ rockchip,pins = -+ <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ -+ sata_act: sata-act { -+ rockchip,pins = -+ <4 RK_PD4 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ -+ system_led: sys-led { -+ rockchip,pins = -+ <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_down>, -+ <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ -+ sata_err_led: sata-err-led { -+ rockchip,pins = -+ <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_down>, -+ <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_down>, -+ <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_down>, -+ <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_down>, -+ <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ }; -+ -+ misc { -+ pca0_pins: pca0-pins { -+ rockchip,pins = -+ <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ wake_on_lan: wake-on-lan { -+ rockchip,pins = -+ <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ pcie { -+ pcie_prst: pcie-prst { -+ rockchip,pins = -+ <2 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ pcie_pwr_en: pcie-pwr-en { -+ rockchip,pins = -+ <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ pmic { -+ pmic_int_l: pmic-int-l { -+ rockchip,pins = -+ <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ -+ vsel1_gpio: vsel1-gpio { -+ rockchip,pins = -+ <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ -+ vsel2_gpio: vsel2-gpio { -+ rockchip,pins = -+ <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ }; -+ -+ power { -+ hdd_a_power: hdd-a-power { -+ rockchip,pins = -+ <1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ hdd_b_power: hdd-b-power { -+ rockchip,pins = -+ <1 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ vcc5v0_usb_en: vcc5v0-usb-en { -+ rockchip,pins = -+ <1 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ sdmmc0_pwr_h: sdmmc0-pwr-h { -+ rockchip,pins = -+ <0 RK_PA1 RK_FUNC_GPIO &pcfg_output_high>; -+ }; -+ -+ usb_lan_en: usb-lan-en { -+ rockchip,pins = -+ <1 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+}; -+ -+&pmu_io_domains { -+ pmu1830-supply = <&vcc3v0_s3>; -+ status = "okay"; -+}; -+ -+&pwm0 { -+ status = "okay"; -+}; -+ -+&pwm1 { -+ status = "okay"; -+}; -+ -+&pwm2 { -+ status = "okay"; -+}; -+ -+&pwm3 { -+ status = "okay"; -+}; -+ -+&saradc { -+ vref-supply = <&vcc1v8_s3>; -+ status = "okay"; -+}; -+ -+&sdhci { -+ assigned-clock-rates = <150000000>; -+ bus-width = <8>; -+ mmc-hs200-1_8v; -+ // hs400 is broken on Helios64 since 5.10.60 -+ // mmc-hs400-1_8v; -+ // mmc-hs400-enhanced-strobe; -+ supports-emmc; -+ non-removable; -+ disable-wp; -+ status = "okay"; -+ vqmmc-supply = <&vcc1v8_sys_s0>; -+}; -+ -+&sdmmc { -+ bus-width = <4>; -+ cap-sd-highspeed; -+ cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; // TODO: verify what needs to be done to use implicit CD definition -+ disable-wp; -+ sd-uhs-sdr104; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; -+ vmmc-supply = <&vcc3v0_sd>; -+ vqmmc-supply = <&vcc_sdio_s0>; -+ status = "okay"; -+}; -+ -+&spi1 { -+ status = "okay"; -+}; -+ -+/* UEXT connector */ -+&spi2 { -+ status = "okay"; -+}; -+ -+&spi5 { -+ status = "okay"; -+}; -+ -+&tcphy0 { -+ extcon = <&fusb0>; -+ status = "okay"; -+}; -+ -+&tcphy0_dp { -+ port { -+ tcphy0_typec_dp: endpoint { -+ remote-endpoint = <&usb_con_sbu>; -+ }; -+ }; -+}; -+ -+&tcphy0_usb3 { -+ port { -+ tcphy0_typec_ss: endpoint { -+ remote-endpoint = <&usb_con_ss>; -+ }; -+ }; -+}; -+ -+&tcphy1 { -+ status = "okay"; -+}; -+ -+&tsadc { -+ /* tshut mode 0:CRU 1:GPIO */ -+ rockchip,hw-tshut-mode = <1>; -+ /* tshut polarity 0:LOW 1:HIGH */ -+ rockchip,hw-tshut-polarity = <1>; -+ status = "okay"; -+}; -+ -+&u2phy0 { -+ status = "okay"; -+ -+ u2phy0_otg: otg-port { -+ status = "okay"; -+ }; -+ -+ u2phy0_host: host-port { -+ phy-supply = <&vcc5v0_usb>; -+ status = "okay"; -+ }; -+ -+ port { -+ u2phy0_typec_hs: endpoint { -+ remote-endpoint = <&usb_con_hs>; -+ }; -+ }; -+}; -+ -+&u2phy1 { -+ status = "okay"; -+ -+ u2phy1_otg: otg-port { -+ status = "okay"; -+ }; -+}; -+ -+&uart0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_xfer>; -+ status = "okay"; -+}; -+ -+&uart2 { -+ status = "okay"; -+}; -+ -+&usb_host0_ehci { -+ status = "okay"; -+}; -+ -+&usb_host0_ohci { -+ status = "okay"; -+}; -+ -+&usbdrd3_0 { -+ status = "okay"; -+}; -+ -+&usbdrd_dwc3_0 { -+ status = "okay"; -+ dr_mode = "otg"; -+}; -+ -+&usbdrd3_1 { -+ status = "okay"; -+}; -+ -+&usbdrd_dwc3_1 { -+ status = "okay"; -+ dr_mode = "host"; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ int_hub: hub@1 { -+ compatible = "usb2109,0815"; -+ reg = <1>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ int_hub_port1: port@1 { -+ reg = <1>; -+ #trigger-source-cells = <0>; -+ }; -+ -+ int_hub_port2: port@2 { -+ reg = <2>; -+ #trigger-source-cells = <0>; -+ }; -+ -+ int_hub_port3: port@3 { -+ reg = <3>; -+ #trigger-source-cells = <0>; -+ }; -+ -+ usb_lan: device@4 { -+ compatible = "usbbda,8156"; -+ reg = <4>; -+ -+ #address-cells = <2>; -+ #size-cells = <0>; -+ -+ interface@0 { /* interface 0 of configuration 1 */ -+ compatible = "usbbda,8156.config1.0"; -+ reg = <0 1>; -+ }; -+ }; -+ }; -+}; -+ -+&vopb { -+ status = "okay"; -+}; -+ -+&vopb_mmu { -+ status = "okay"; -+}; -+ -+&vopl { -+ status = "okay"; -+}; -+ -+&vopl_mmu { -+ status = "okay"; -+}; -\ No newline at end of file --- -Created with Armbian build tools https://github.com/armbian/build - diff --git a/patch/kernel/archive/rockchip64-6.1/add-board-jp-tvbox-3566.patch b/patch/kernel/archive/rockchip64-6.1/add-board-jp-tvbox-3566.patch deleted file mode 100644 index 74dc56ebfe5d..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/add-board-jp-tvbox-3566.patch +++ /dev/null @@ -1,597 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile -index 8c15593c0..2e861a2ea 100644 ---- a/arch/arm64/boot/dts/rockchip/Makefile -+++ b/arch/arm64/boot/dts/rockchip/Makefile -@@ -69,6 +69,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-a.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-b.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-roc-pc.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-soquartz-cm4.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-jp-tvbox.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-bpi-r2-pro.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-v10.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-rock-3a.dtb -diff --git a/arch/arm64/boot/dts/rockchip/rk3566-jp-tvbox.dts b/arch/arm64/boot/dts/rockchip/rk3566-jp-tvbox.dts -new file mode 100644 -index 000000000..6a53d23a5 ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3566-jp-tvbox.dts -@@ -0,0 +1,579 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Copyright (c) 2023 tdleiyao -+ */ -+ -+/dts-v1/; -+ -+#include -+#include -+#include -+#include -+#include "rk3566.dtsi" -+ -+/ { -+ model = "JP TVbox 3566"; -+ compatible = "JP-TVbox,rk3566", "rockchip,rk3566"; -+ -+ aliases { -+ ethernet0 = &gmac1; -+ mmc0 = &sdhci; -+ mmc1 = &sdmmc1; -+ }; -+ -+ chosen: chosen { -+ stdout-path = "serial2:1500000n8"; -+ }; -+ -+ hdmi-con { -+ compatible = "hdmi-connector"; -+ type = "a"; -+ -+ port { -+ hdmi_con_in: endpoint { -+ remote-endpoint = <&hdmi_out_con>; -+ }; -+ }; -+ }; -+ -+ gmac1_clkin: external-gmac1-clock { -+ compatible = "fixed-clock"; -+ clock-frequency = <125000000>; -+ clock-output-names = "gmac1_clkin"; -+ #clock-cells = <0>; -+ }; -+ -+ leds { -+ compatible = "gpio-leds"; -+ -+ led_status: led-status { -+ label = "led-status"; -+ gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "heartbeat"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&led_status_enable_h>; -+ }; -+ }; -+ -+ vbus: vbus-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vbus"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ }; -+ -+ vcc5v0_sys: vcc5v0-sys-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v0_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vbus>; -+ }; -+ -+ vcc3v3_sys: vcc3v3-sys-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc3v3_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ sdio_pwrseq: sdio-pwrseq { -+ status = "okay"; -+ compatible = "mmc-pwrseq-simple"; -+ clocks = <&rk809 1>; -+ clock-names = "ext_clock"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&wifi_enable_h>; -+ reset-gpios = <&gpio2 RK_PB1 GPIO_ACTIVE_LOW>; -+ post-power-on-delay-ms = <100>; -+ }; -+ -+ wireless_wlan: wireless-wlan { -+ compatible = "wlan-platdata"; -+ rockchip,grf = <&grf>; -+ wifi_chip_type = "ap6398s"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&wifi_host_wake_irq>; -+ WIFI,host_wake_irq = <&gpio2 RK_PB2 GPIO_ACTIVE_HIGH>; -+ status = "okay"; -+ }; -+ -+}; -+ -+&combphy1 { -+ status = "okay"; -+}; -+ -+&combphy2 { -+ status = "okay"; -+}; -+ -+&cpu0 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu1 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu2 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu3 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&gpu { -+ mali-supply = <&vdd_gpu>; -+ status = "okay"; -+}; -+ -+&gmac1 { -+ assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru SCLK_GMAC1>; -+ assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru SCLK_GMAC1>, <&gmac1_clkin>; -+ clock_in_out = "input"; -+ phy-supply = <&vcc_3v3>; -+ phy-mode = "rgmii"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&gmac1m0_miim -+ &gmac1m0_tx_bus2 -+ &gmac1m0_rx_bus2 -+ &gmac1m0_rgmii_clk -+ &gmac1m0_clkinout -+ &gmac1m0_rgmii_bus>; -+ snps,reset-gpio = <&gpio3 RK_PA1 GPIO_ACTIVE_LOW>; -+ snps,reset-active-low; -+ /* Reset time is 20ms, 100ms for rtl8211f, also works well here */ -+ snps,reset-delays-us = <0 20000 100000>; -+ tx_delay = <0x41>; -+ rx_delay = <0x2e>; -+ phy-handle = <&rgmii_phy1>; -+ status = "okay"; -+}; -+ -+&mdio1 { -+ rgmii_phy1: ethernet-phy@0 { -+ compatible = "ethernet-phy-ieee802.3-c22"; -+ reg = <0>; -+ status = "okay"; -+ }; -+}; -+ -+&hdmi { -+ avdd-0v9-supply = <&vdda0v9_image>; -+ avdd-1v8-supply = <&vcca1v8_image>; -+ status = "okay"; -+}; -+ -+&hdmi_in { -+ hdmi_in_vp0: endpoint { -+ remote-endpoint = <&vp0_out_hdmi>; -+ }; -+}; -+ -+&hdmi_out { -+ hdmi_out_con: endpoint { -+ remote-endpoint = <&hdmi_con_in>; -+ }; -+}; -+ -+&hdmi_sound { -+ status = "okay"; -+}; -+ -+&i2c0 { -+ status = "okay"; -+ -+ vdd_cpu: regulator@1c { -+ compatible = "tcs,tcs4525"; -+ reg = <0x1c>; -+ fcs,suspend-voltage-selector = <1>; -+ regulator-name = "vdd_cpu"; -+ regulator-min-microvolt = <800000>; -+ regulator-max-microvolt = <1150000>; -+ regulator-ramp-delay = <2300>; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&vcc5v0_sys>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ rk809: pmic@20 { -+ compatible = "rockchip,rk809"; -+ reg = <0x20>; -+ interrupt-parent = <&gpio0>; -+ interrupts = ; -+ #clock-cells = <1>; -+ clock-output-names = "rk808-clkout1", "rk808-clkout2"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pmic_int_l>; -+ rockchip,system-power-controller; -+ wakeup-source; -+ -+ vcc1-supply = <&vcc3v3_sys>; -+ vcc2-supply = <&vcc3v3_sys>; -+ vcc3-supply = <&vcc3v3_sys>; -+ vcc4-supply = <&vcc3v3_sys>; -+ vcc5-supply = <&vcc3v3_sys>; -+ vcc6-supply = <&vcc3v3_sys>; -+ vcc7-supply = <&vcc3v3_sys>; -+ vcc8-supply = <&vcc3v3_sys>; -+ vcc9-supply = <&vcc3v3_sys>; -+ -+ regulators { -+ vdd_logic: DCDC_REG1 { -+ regulator-name = "vdd_logic"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <500000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-init-microvolt = <900000>; -+ regulator-ramp-delay = <6001>; -+ regulator-initial-mode = <0x2>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_gpu: DCDC_REG2 { -+ regulator-name = "vdd_gpu"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <500000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-init-microvolt = <900000>; -+ regulator-ramp-delay = <6001>; -+ regulator-initial-mode = <0x2>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_ddr: DCDC_REG3 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-initial-mode = <0x2>; -+ regulator-name = "vcc_ddr"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vdd_npu: DCDC_REG4 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <500000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-init-microvolt = <900000>; -+ regulator-initial-mode = <0x2>; -+ regulator-name = "vdd_npu"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_1v8: DCDC_REG5 { -+ regulator-name = "vcc_1v8"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdda0v9_image: LDO_REG1 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ regulator-name = "vdda0v9_image"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdda_0v9: LDO_REG2 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ regulator-name = "vdda_0v9"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdda0v9_pmu: LDO_REG3 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ regulator-name = "vdda0v9_pmu"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <900000>; -+ }; -+ }; -+ -+ vccio_acodec: LDO_REG4 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-name = "vccio_acodec"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vccio_sd: LDO_REG5 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-name = "vccio_sd"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc3v3_pmu: LDO_REG6 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-name = "vcc3v3_pmu"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3300000>; -+ }; -+ }; -+ -+ vcca_1v8: LDO_REG7 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-name = "vcca_1v8"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcca1v8_pmu: LDO_REG8 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-name = "vcca1v8_pmu"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vcca1v8_image: LDO_REG9 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-name = "vcca1v8_image"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_3v3: SWITCH_REG1 { -+ regulator-name = "vcc_3v3"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc3v3_sd: SWITCH_REG2 { -+ regulator-name = "vcc3v3_sd"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ }; -+ }; -+}; -+ -+&pinctrl { -+ -+ pmic { -+ pmic_int_l: pmic-int-l { -+ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ -+ sdio-pwrseq { -+ wifi_enable_h: wifi-enable-h { -+ rockchip,pins = <2 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ wireless-wlan { -+ wifi_host_wake_irq: wifi-host-wake-irq { -+ rockchip,pins = <2 RK_PB2 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ }; -+ -+ bt { -+ bt_enable_h: bt-enable-h { -+ rockchip,pins = <2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ bt_host_wake_l: bt-host-wake-l { -+ rockchip,pins = <2 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ bt_wake_l: bt-wake-l { -+ rockchip,pins = <2 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ leds { -+ led_status_enable_h: led-status-enable-h { -+ rockchip,pins = <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+}; -+ -+&pmu_io_domains { -+ pmuio1-supply = <&vcc3v3_pmu>; -+ pmuio2-supply = <&vcc3v3_pmu>; -+ vccio1-supply = <&vccio_acodec>; -+ vccio3-supply = <&vccio_sd>; -+ vccio4-supply = <&vcc_1v8>; -+ vccio5-supply = <&vcc_3v3>; -+ vccio6-supply = <&vcc_1v8>; -+ vccio7-supply = <&vcc_3v3>; -+ status = "okay"; -+}; -+ -+&saradc { -+ vref-supply = <&vcca_1v8>; -+ status = "okay"; -+}; -+ -+&sata2 { -+ status = "okay"; -+}; -+ -+&sdhci { -+ bus-width = <8>; -+ mmc-hs200-1_8v; -+ non-removable; -+ vmmc-supply = <&vcc_3v3>; -+ vqmmc-supply = <&vcc_1v8>; -+ status = "okay"; -+}; -+ -+&sdmmc1 { -+ supports-sdio; -+ bus-width = <4>; -+ disable-wp; -+ cap-sd-highspeed; -+ cap-sdio-irq; -+ keep-power-in-suspend; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_cmd &sdmmc1_clk>; -+ non-removable; -+ mmc-pwrseq = <&sdio_pwrseq>; -+ status = "okay"; -+ -+}; -+ -+&tsadc { -+ status = "okay"; -+}; -+ -+&uart1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart1m0_xfer &uart1m0_ctsn &uart1m0_rtsn>; -+ status = "okay"; -+ -+ bluetooth { -+ compatible = "brcm,bcm43438-bt"; -+ clocks = <&rk809 1>; -+ clock-names = "lpo"; -+ device-wakeup-gpios = <&gpio2 RK_PC1 GPIO_ACTIVE_HIGH>; -+ host-wakeup-gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>; -+ shutdown-gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>; -+ max-speed = <1500000>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&bt_host_wake_l &bt_wake_l &bt_enable_h>; -+ vbat-supply = <&vcc3v3_sys>; -+ vddio-supply = <&vcca1v8_pmu>; -+ }; -+}; -+ -+&uart2 { -+ status = "okay"; -+}; -+ -+&usb_host0_xhci { -+ dr_mode = "host"; -+ status = "okay"; -+}; -+ -+&usb2phy0 { -+ status = "okay"; -+}; -+ -+&usb2phy0_host { -+ status = "okay"; -+}; -+ -+&usb2phy0_otg { -+ status = "okay"; -+}; -+ -+&usb_host1_xhci { -+ status = "okay"; -+}; -+ -+&usb2phy1 { -+ status = "okay"; -+}; -+ -+&usb2phy1_host { -+ status = "okay"; -+}; -+ -+&usb2phy1_otg { -+ status = "okay"; -+}; -+ -+&vop { -+ assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>; -+ assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>; -+ status = "okay"; -+}; -+ -+&vop_mmu { -+ status = "okay"; -+}; -+ -+&vp0 { -+ vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { -+ reg = ; -+ remote-endpoint = <&hdmi_in_vp0>; -+ }; -+}; diff --git a/patch/kernel/archive/rockchip64-6.1/add-board-nanopi-m4v2.patch b/patch/kernel/archive/rockchip64-6.1/add-board-nanopi-m4v2.patch deleted file mode 100644 index b845b3c46c76..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/add-board-nanopi-m4v2.patch +++ /dev/null @@ -1,84 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-m4v2.dts b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-m4v2.dts -new file mode 100644 -index 000000000..60358ab8c ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-m4v2.dts -@@ -0,0 +1,78 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * FriendlyElec NanoPi M4V2 board device tree source -+ * -+ * Copyright (c) 2018 FriendlyElec Computer Tech. Co., Ltd. -+ * (http://www.friendlyarm.com) -+ * -+ * Copyright (c) 2018 Collabora Ltd. -+ * Copyright (c) 2019 Arm Ltd. -+ */ -+ -+/dts-v1/; -+#include "rk3399-nanopi4.dtsi" -+ -+/ { -+ model = "FriendlyElec NanoPi M4 Ver2.0"; -+ compatible = "friendlyarm,nanopi-m4", "rockchip,rk3399"; -+ -+ vdd_5v: vdd-5v { -+ compatible = "regulator-fixed"; -+ regulator-name = "vdd_5v"; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ vcc5v0_core: vcc5v0-core { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v0_core"; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&vdd_5v>; -+ }; -+ -+ vcc5v0_usb1: vcc5v0-usb1 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v0_usb1"; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ vcc5v0_usb2: vcc5v0-usb2 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v0_usb2"; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ vdd_log: vdd-log { -+ compatible = "pwm-regulator"; -+ pwms = <&pwm2 0 25000 1>; -+ regulator-name = "vdd_log"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <800000>; -+ regulator-max-microvolt = <1400000>; -+ regulator-init-microvolt = <900000>; -+ vin-supply = <&vcc5v0_core>; -+ }; -+}; -+ -+&vcc3v3_sys { -+ vin-supply = <&vcc5v0_core>; -+}; -+ -+&u2phy0_host { -+ phy-supply = <&vcc5v0_usb1>; -+}; -+ -+&u2phy1_host { -+ phy-supply = <&vcc5v0_usb2>; -+}; -+ -+&vbus_typec { -+ regulator-always-on; -+ vin-supply = <&vdd_5v>; -+}; diff --git a/patch/kernel/archive/rockchip64-6.1/add-board-nanopi-neo3-with-enabled-I2S-and-spdif.patch b/patch/kernel/archive/rockchip64-6.1/add-board-nanopi-neo3-with-enabled-I2S-and-spdif.patch deleted file mode 100644 index 7c12aa098e4f..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/add-board-nanopi-neo3-with-enabled-I2S-and-spdif.patch +++ /dev/null @@ -1,211 +0,0 @@ -From 3d8e4be5ff1783dffc6cad7d69f06366e0eb5d6c Mon Sep 17 00:00:00 2001 -From: Igor Pecovnik -Date: Mon, 7 Sep 2020 21:21:55 +0200 -Subject: [PATCH] Add Nanopi Neo3 with enabled I2S and spdif - -Signed-off-by: Igor Pecovnik ---- -diff --git a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-neo3-rev02.dts b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-neo3-rev02.dts -new file mode 100644 -index 000000000..bf0a625fe ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-neo3-rev02.dts -@@ -0,0 +1,195 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Copyright (c) 2019 FriendlyElec Computer Tech. Co., Ltd. -+ * (http://www.friendlyarm.com) -+ */ -+ -+/dts-v1/; -+#include -+#include "rk3328-nanopi-r2s.dts" -+ -+/ { -+ model = "FriendlyElec NanoPi NEO3"; -+ compatible = "friendlyelec,nanopi-neo3", "rockchip,rk3328"; -+ -+ gpio-keys { -+ compatible = "gpio-keys"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ autorepeat; -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&gpio_key1>; -+ -+ button@0 { -+ gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_LOW>; -+ label = "reset"; -+ linux,code = ; -+ linux,input-type = <1>; -+ gpio-key,wakeup = <1>; -+ debounce-interval = <100>; -+ }; -+ }; -+ -+ i2s-sound { -+ compatible = "simple-audio-card"; -+ simple-audio-card,format = "i2s"; -+ simple-audio-card,mclk-fs = <256>; -+ simple-audio-card,name = "I2S Out"; -+ status = "okay"; -+ -+ simple-audio-card,cpu { -+ sound-dai = <&i2s1>; -+ }; -+ -+ simple-audio-card,codec { -+ sound-dai = <&pcm5102>; -+ }; -+ }; -+ -+ pcm5102: pcm510x { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm5102a"; -+ pcm510x,format = "i2s"; -+ }; -+ -+ sound-spdif { -+ compatible = "simple-audio-card"; -+ simple-audio-card,name = "SPDIF"; -+ simple-audio-card,cpu { -+ sound-dai = <&spdif>; -+ }; -+ simple-audio-card,codec { -+ sound-dai = <&spdif_out>; -+ }; -+ }; -+ -+ spdif_out: spdif-out { -+ compatible = "linux,spdif-dit"; -+ #sound-dai-cells = <0>; -+ }; -+ -+ vcc_rtl8153: vcc-rtl8153-regulator { -+ compatible = "regulator-fixed"; -+ gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&usb30_en_drv>; -+ regulator-always-on; -+ regulator-name = "vcc_rtl8153"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ off-on-delay-us = <5000>; -+ enable-active-high; -+ }; -+}; -+ -+&mach { -+ hwrev = <2>; -+ model = "NanoPi NEO3"; -+}; -+ -+&i2s1 { -+ rockchip,playback-channels = <2>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s1_mclk -+ &i2s1_sclk -+ &i2s1_lrcktx -+ &i2s1_lrckrx -+ &i2s1_sdo -+ &i2s1_sdi>; -+ status = "okay"; -+}; -+ -+&spdif { -+ status = "okay"; -+ pinctrl-0 = <&spdifm0_tx>; -+}; -+ -+&emmc { -+ status = "disabled"; -+}; -+ -+&i2c0 { -+ status = "okay"; -+}; -+ -+&leds { -+ status = "okay"; -+ -+}; -+ -+&leds_gpio { -+ rockchip,pins = -+ <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; -+}; -+ -+&pwm2 { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-1 = <&pwm2_sleep_pin>; -+ status = "okay"; -+}; -+ -+&rk805 { -+ interrupt-parent = <&gpio1>; -+ interrupts = ; -+}; -+ -+&vccio_sd { -+ status = "okay"; -+}; -+ -+&io_domains { -+ vccio3-supply = <&vccio_sd>; -+}; -+ -+&sdmmc { -+ vqmmc-supply = <&vccio_sd>; -+ max-frequency = <150000000>; -+ sd-uhs-sdr50; -+ sd-uhs-sdr104; -+ status = "okay"; -+}; -+ -+&sdmmc_ext { -+ status = "disabled"; -+}; -+ -+&sdio_pwrseq { -+ status = "disabled"; -+}; -+ -+&pinctrl { -+ pmic { -+ pmic_int_l: pmic-int-l { -+ rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ -+ pwm { -+ pwm2_sleep_pin: pwm2-sleep-pin { -+ rockchip,pins = <2 RK_PA6 RK_FUNC_GPIO &pcfg_output_low>; -+ }; -+ }; -+ -+ rockchip-key { -+ gpio_key1: gpio-key1 { -+ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ usb { -+ otg_vbus_drv: otg-vbus-drv { -+ rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ usb30_en_drv: usb30-en-drv { -+ rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+}; -+ -+&uart1{ -+ status = "okay"; -+ pinctl-0 = <&uart1_xfer>; -+}; -+ --- -Created with Armbian build tools https://github.com/armbian/build - diff --git a/patch/kernel/archive/rockchip64-6.1/add-board-nanopi-r2c.patch b/patch/kernel/archive/rockchip64-6.1/add-board-nanopi-r2c.patch deleted file mode 100644 index 298be847c114..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/add-board-nanopi-r2c.patch +++ /dev/null @@ -1,95 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2-rev06.dts b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2-rev06.dts -new file mode 100644 -index 000000000000..6322f59939b8 ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2-rev06.dts -@@ -0,0 +1,89 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Copyright (c) 2021 FriendlyElec Computer Tech. Co., Ltd. -+ * (http://www.friendlyarm.com) -+ */ -+ -+/dts-v1/; -+ -+#include "rk3328-nanopi-r2-rev00.dts" -+ -+/ { -+ model = "FriendlyElec NanoPi R2C"; -+ compatible = "friendlyelec,nanopi-r2", "rockchip,rk3328"; -+}; -+ -+&mach { -+ hwrev = <6>; -+ model = "NanoPi R2C"; -+}; -+ -+&rgmiim1_pins { -+ rockchip,pins = -+ /* mac_txclk */ -+ <1 RK_PB4 2 &pcfg_pull_none_8ma>, -+ /* mac_rxclk */ -+ <1 RK_PB5 2 &pcfg_pull_none>, -+ /* mac_mdio */ -+ <1 RK_PC3 2 &pcfg_pull_none_2ma>, -+ /* mac_txen */ -+ <1 RK_PD1 2 &pcfg_pull_none_8ma>, -+ /* mac_clk */ -+ <1 RK_PC5 2 &pcfg_pull_none_2ma>, -+ /* mac_rxdv */ -+ <1 RK_PC6 2 &pcfg_pull_none>, -+ /* mac_mdc */ -+ <1 RK_PC7 2 &pcfg_pull_none_2ma>, -+ /* mac_rxd1 */ -+ <1 RK_PB2 2 &pcfg_pull_none>, -+ /* mac_rxd0 */ -+ <1 RK_PB3 2 &pcfg_pull_none>, -+ /* mac_txd1 */ -+ <1 RK_PB0 2 &pcfg_pull_none_8ma>, -+ /* mac_txd0 */ -+ <1 RK_PB1 2 &pcfg_pull_none_8ma>, -+ /* mac_rxd3 */ -+ <1 RK_PB6 2 &pcfg_pull_none>, -+ /* mac_rxd2 */ -+ <1 RK_PB7 2 &pcfg_pull_none>, -+ /* mac_txd3 */ -+ <1 RK_PC0 2 &pcfg_pull_none_8ma>, -+ /* mac_txd2 */ -+ <1 RK_PC1 2 &pcfg_pull_none_8ma>, -+ -+ /* mac_txclk */ -+ <0 RK_PB0 1 &pcfg_pull_none>, -+ /* mac_txen */ -+ <0 RK_PB4 1 &pcfg_pull_none>, -+ /* mac_clk */ -+ <0 RK_PD0 1 &pcfg_pull_none>, -+ /* mac_txd1 */ -+ <0 RK_PC0 1 &pcfg_pull_none>, -+ /* mac_txd0 */ -+ <0 RK_PC1 1 &pcfg_pull_none>, -+ /* mac_txd3 */ -+ <0 RK_PC7 1 &pcfg_pull_none>, -+ /* mac_txd2 */ -+ <0 RK_PC6 1 &pcfg_pull_none>; -+}; -+ -+/delete-node/ &rtl8211e; -+ -+&gmac2io { -+ phy-handle = <ðphy3>; -+ snps,reset-delays-us = <0 15000 50000>; -+ tx_delay = <0x22>; -+ rx_delay = <0x12>; -+ mdio { -+ -+ ethphy3: ethernet-phy@3 { -+ compatible = "ethernet-phy-id0000.011a", -+ "ethernet-phy-ieee802.3-c22"; -+ reg = <3>; -+ interrupt-parent = <&gpio2>; -+ interrupts = ; -+ //reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; -+ keep-clkout-on; -+ }; -+ }; -+}; diff --git a/patch/kernel/archive/rockchip64-6.1/add-board-nanopi-r2s.patch b/patch/kernel/archive/rockchip64-6.1/add-board-nanopi-r2s.patch deleted file mode 100644 index 9a8cad381342..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/add-board-nanopi-r2s.patch +++ /dev/null @@ -1,914 +0,0 @@ -From f051544daa4dd8039b30f9a10ee509a65ba26147 Mon Sep 17 00:00:00 2001 -From: Paolo Sabatino -Date: Sat, 7 Jan 2023 11:59:47 +0000 -Subject: [PATCH] rockchip64: consolidate nanopi r2s device trees - ---- - .../dts/rockchip/rk3328-nanopi-r2-rev00.dts | 126 +++++ - .../dts/rockchip/rk3328-nanopi-r2-rev20.dts | 39 ++ - .../boot/dts/rockchip/rk3328-nanopi-r2s.dts | 493 ++++++++++++------ - 3 files changed, 490 insertions(+), 168 deletions(-) - create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2-rev00.dts - create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2-rev20.dts - -diff --git a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2-rev00.dts b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2-rev00.dts -new file mode 100644 -index 00000000000..8ba95189c03 ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2-rev00.dts -@@ -0,0 +1,126 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Copyright (c) 2019 FriendlyElec Computer Tech. Co., Ltd. -+ * (http://www.friendlyarm.com) -+ */ -+ -+/dts-v1/; -+#include -+#include "rk3328-nanopi-r2s.dts" -+ -+/ { -+ model = "FriendlyElec NanoPi R2S"; -+ compatible = "friendlyelec,nanopi-r2", "rockchip,rk3328"; -+ -+ gpio-keys { -+ compatible = "gpio-keys"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ autorepeat; -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&gpio_key1>; -+ -+ button@0 { -+ gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_LOW>; -+ label = "reset"; -+ linux,code = ; -+ linux,input-type = <1>; -+ gpio-key,wakeup = <1>; -+ debounce-interval = <100>; -+ }; -+ }; -+ -+ vcc_rtl8153: vcc-rtl8153-regulator { -+ compatible = "regulator-fixed"; -+ gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&usb30_en_drv>; -+ regulator-always-on; -+ regulator-name = "vcc_rtl8153"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ off-on-delay-us = <5000>; -+ enable-active-high; -+ }; -+}; -+ -+&mach { -+ hwrev = <0>; -+ model = "NanoPi R2S"; -+}; -+ -+&emmc { -+ status = "disabled"; -+}; -+ -+&i2c0 { -+ status = "okay"; -+}; -+ -+&leds { -+ status = "okay"; -+ -+ led@2 { -+ gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>; -+ label = "lan_led"; -+ }; -+ -+ led@3 { -+ gpios = <&gpio2 RK_PC2 GPIO_ACTIVE_HIGH>; -+ label = "wan_led"; -+ }; -+}; -+ -+&rk805 { -+ interrupt-parent = <&gpio1>; -+ interrupts = ; -+}; -+ -+&vccio_sd { -+ status = "okay"; -+}; -+ -+&io_domains { -+ vccio3-supply = <&vccio_sd>; -+}; -+ -+&sdmmc { -+ vqmmc-supply = <&vccio_sd>; -+ max-frequency = <150000000>; -+ sd-uhs-sdr50; -+ sd-uhs-sdr104; -+ status = "okay"; -+}; -+ -+&sdmmc_ext { -+ status = "disabled"; -+}; -+ -+&sdio_pwrseq { -+ status = "disabled"; -+}; -+ -+&pinctrl { -+ pmic { -+ pmic_int_l: pmic-int-l { -+ rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ -+ rockchip-key { -+ gpio_key1: gpio-key1 { -+ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ usb { -+ otg_vbus_drv: otg-vbus-drv { -+ rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ usb30_en_drv: usb30-en-drv { -+ rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2-rev20.dts b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2-rev20.dts -new file mode 100644 -index 00000000000..ad327ca5685 ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2-rev20.dts -@@ -0,0 +1,39 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Copyright (c) 2019 FriendlyElec Computer Tech. Co., Ltd. -+ * (http://www.friendlyarm.com) -+ */ -+ -+/dts-v1/; -+#include "rk3328-nanopi-r2s.dts" -+ -+/ { -+ model = "FriendlyElec NanoPi R2"; -+ compatible = "friendlyelec,nanopi-r2", "rockchip,rk3328"; -+}; -+ -+&mach { -+ hwrev = <0x20>; -+ model = "NanoPi R2"; -+}; -+ -+&gmac2io { -+ pinctrl-0 = <&rgmiim1_pins>, <&phy_intb>, <&phy_rstb>; -+}; -+ -+&rtl8211e { -+ interrupt-parent = <&gpio1>; -+ interrupts = ; -+}; -+ -+&pinctrl { -+ phy { -+ phy_intb: phy-intb { -+ rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ phy_rstb: phy-rstb { -+ rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts -index 1445b879ac7..7fff7ef89d9 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts -@@ -1,118 +1,166 @@ - // SPDX-License-Identifier: (GPL-2.0+ OR MIT) - /* -- * Copyright (c) 2020 David Bauer -+ * Copyright (c) 2018 FriendlyElec Computer Tech. Co., Ltd. -+ * (http://www.friendlyarm.com) -+ * -+ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd - */ - - /dts-v1/; -- --#include --#include -+#include "rk3328-dram-default-timing.dtsi" - #include "rk3328.dtsi" - - / { -- model = "FriendlyElec NanoPi R2S"; -- compatible = "friendlyarm,nanopi-r2s", "rockchip,rk3328"; -+ model = "FriendlyElec boards based on Rockchip RK3328"; -+ compatible = "friendlyelec,nanopi-r2", -+ "rockchip,rk3328"; - - aliases { -- ethernet1 = &rtl8153; -- mmc0 = &sdmmc; -+ ethernet1 = &r8153; - }; - - chosen { -+ bootargs = "swiotlb=1 coherent_pool=1m consoleblank=0"; - stdout-path = "serial2:1500000n8"; - }; - -- gmac_clk: gmac-clock { -+ gmac_clkin: external-gmac-clock { - compatible = "fixed-clock"; - clock-frequency = <125000000>; - clock-output-names = "gmac_clkin"; - #clock-cells = <0>; - }; - -- keys { -- compatible = "gpio-keys"; -- pinctrl-0 = <&reset_button_pin>; -- pinctrl-names = "default"; -- -- key-reset { -- label = "reset"; -- gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_LOW>; -- linux,code = ; -- debounce-interval = <50>; -- }; -+ mach: board { -+ compatible = "friendlyelec,board"; -+ machine = "NANOPI-R2"; -+ hwrev = <255>; -+ model = "NanoPi R2 Series"; -+ nvmem-cells = <&efuse_id>, <&efuse_cpu_version>; -+ nvmem-cell-names = "id", "cpu-version"; - }; - -- leds { -+ leds: gpio-leds { - compatible = "gpio-leds"; -- pinctrl-0 = <&lan_led_pin>, <&sys_led_pin>, <&wan_led_pin>; - pinctrl-names = "default"; -+ pinctrl-0 =<&leds_gpio>; -+ status = "disabled"; - -- lan_led: led-0 { -- gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>; -- label = "nanopi-r2s:green:lan"; -- }; -- -- sys_led: led-1 { -+ led@1 { - gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; -- label = "nanopi-r2s:red:sys"; -- default-state = "on"; -- }; -- -- wan_led: led-2 { -- gpios = <&gpio2 RK_PC2 GPIO_ACTIVE_HIGH>; -- label = "nanopi-r2s:green:wan"; -+ label = "status_led"; -+ linux,default-trigger = "heartbeat"; -+ linux,default-trigger-delay-ms = <0>; - }; - }; - -- vcc_io_sdio: sdmmcio-regulator { -- compatible = "regulator-gpio"; -- enable-active-high; -- gpios = <&gpio1 RK_PD4 GPIO_ACTIVE_HIGH>; -- pinctrl-0 = <&sdio_vcc_pin>; -+ sdio_pwrseq: sdio-pwrseq { -+ compatible = "mmc-pwrseq-simple"; -+ clocks = <&rk805 1>; -+ clock-names = "ext_clock"; - pinctrl-names = "default"; -- regulator-name = "vcc_io_sdio"; -- regulator-always-on; -- regulator-min-microvolt = <1800000>; -- regulator-max-microvolt = <3300000>; -- regulator-settling-time-us = <5000>; -- regulator-type = "voltage"; -- startup-delay-us = <2000>; -- states = <1800000 0x1>, -- <3300000 0x0>; -- vin-supply = <&vcc_io_33>; -+ pinctrl-0 = <&wifi_enable_h>; -+ -+ /* -+ * On the module itself this is one of these (depending -+ * on the actual card populated): -+ * - SDIO_RESET_L_WL_REG_ON -+ * - PDN (power down when low) -+ */ -+ reset-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>; -+ }; -+ -+ sdmmc_ext: dwmmc@ff5f0000 { -+ compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc"; -+ reg = <0x0 0xff5f0000 0x0 0x4000>; -+ clock-freq-min-max = <400000 150000000>; -+ clocks = <&cru HCLK_SDMMC_EXT>, <&cru SCLK_SDMMC_EXT>, -+ <&cru SCLK_SDMMC_EXT_DRV>, <&cru SCLK_SDMMC_EXT_SAMPLE>; -+ clock-names = "biu", "ciu", "ciu-drv", "ciu-sample"; -+ fifo-depth = <0x100>; -+ interrupts = ; -+ status = "disabled"; - }; - - vcc_sd: sdmmc-regulator { - compatible = "regulator-fixed"; -- gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>; -- pinctrl-0 = <&sdmmc0m1_pin>; -+ gpio = <&gpio0 30 GPIO_ACTIVE_LOW>; - pinctrl-names = "default"; -- regulator-name = "vcc_sd"; -+ pinctrl-0 = <&sdmmc0m1_pin>; - regulator-boot-on; -+ regulator-name = "vcc_sd"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; -- vin-supply = <&vcc_io_33>; -+ vin-supply = <&vcc_io>; - }; - -- vdd_5v: vdd-5v { -+ vccio_sd: sdmmcio-regulator { -+ compatible = "regulator-gpio"; -+ gpios = <&gpio1 RK_PD4 GPIO_ACTIVE_HIGH>; -+ states = <1800000 0x1 -+ 3300000 0x0>; -+ regulator-name = "vccio_sd"; -+ regulator-type = "voltage"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ vin-supply = <&vcc_io>; -+ startup-delay-us = <2000>; -+ regulator-settling-time-us = <5000>; -+ enable-active-high; -+ status = "disabled"; -+ }; -+ -+ vcc_sys: vcc-sys { - compatible = "regulator-fixed"; -- regulator-name = "vdd_5v"; -+ regulator-name = "vcc_sys"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - }; - -- vdd_5v_lan: vdd-5v-lan { -+ vcc_phy: vcc-phy-regulator { - compatible = "regulator-fixed"; -- enable-active-high; -- gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>; -- pinctrl-0 = <&lan_vdd_pin>; -- pinctrl-names = "default"; -- regulator-name = "vdd_5v_lan"; -+ regulator-name = "vcc_phy"; - regulator-always-on; - regulator-boot-on; -- vin-supply = <&vdd_5v>; -+ }; -+ -+ vcc_host_vbus: host-vbus-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc_host_vbus"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ }; -+ -+ /delete-node/ dmc-opp-table; -+ -+ dmc_opp_table: dmc_opp_table { -+ compatible = "operating-points-v2"; -+ -+ opp-786000000 { -+ opp-hz = /bits/ 64 <786000000>; -+ opp-microvolt = <1075000 1075000 1200000>; -+ }; -+ opp-798000000 { -+ opp-hz = /bits/ 64 <798000000>; -+ opp-microvolt = <1075000 1075000 1200000>; -+ }; -+ opp-840000000 { -+ opp-hz = /bits/ 64 <840000000>; -+ opp-microvolt = <1075000 1075000 1200000>; -+ }; -+ opp-924000000 { -+ opp-hz = /bits/ 64 <924000000>; -+ opp-microvolt = <1100000 1100000 1200000>; -+ }; -+ opp-1056000000 { -+ opp-hz = /bits/ 64 <1056000000>; -+ opp-microvolt = <1175000 1175000 1200000>; -+ }; - }; - }; - -@@ -120,34 +168,57 @@ &cpu0 { - cpu-supply = <&vdd_arm>; - }; - --&cpu1 { -- cpu-supply = <&vdd_arm>; -+&dfi { -+ status = "okay"; - }; - --&cpu2 { -- cpu-supply = <&vdd_arm>; -+&dmc { -+ center-supply = <&vdd_logic>; -+ ddr_timing = <&ddr_timing>; -+ status = "okay"; - }; - --&cpu3 { -- cpu-supply = <&vdd_arm>; -+&emmc { -+ bus-width = <8>; -+ cap-mmc-highspeed; -+ max-frequency = <150000000>; -+ mmc-hs200-1_8v; -+ no-sd; -+ non-removable; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; -+ vmmc-supply = <&vcc_io>; -+ vqmmc-supply = <&vcc18_emmc>; -+ status = "okay"; - }; - --&display_subsystem { -+&gmac2phy { -+ phy-supply = <&vcc_phy>; -+ clock_in_out = "output"; -+ assigned-clocks = <&cru SCLK_MAC2PHY_SRC>; -+ assigned-clock-rate = <50000000>; -+ assigned-clocks = <&cru SCLK_MAC2PHY>; -+ assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>; - status = "disabled"; - }; - - &gmac2io { - assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; -- assigned-clock-parents = <&gmac_clk>, <&gmac_clk>; -+ assigned-clock-parents = <&gmac_clkin>, <&gmac_clkin>; - clock_in_out = "input"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&rgmiim1_pins>; - phy-handle = <&rtl8211e>; - phy-mode = "rgmii"; -- phy-supply = <&vcc_io_33>; -- pinctrl-0 = <&rgmiim1_pins>; -- pinctrl-names = "default"; -- rx_delay = <0x18>; -+ phy-supply = <&vcc_phy>; -+ snps,reset-active-low; -+ snps,reset-delays-us = <0 10000 30000>; -+ snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; - snps,aal; -+ snps,rxpbl = <0x4>; -+ snps,txpbl = <0x4>; - tx_delay = <0x24>; -+ rx_delay = <0x18>; - status = "okay"; - - mdio { -@@ -155,13 +226,11 @@ mdio { - #address-cells = <1>; - #size-cells = <0>; - -- rtl8211e: ethernet-phy@1 { -- reg = <1>; -- pinctrl-0 = <ð_phy_reset_pin>; -- pinctrl-names = "default"; -+ rtl8211e: phy@0 { -+ reg = <0>; - reset-assert-us = <10000>; -- reset-deassert-us = <50000>; -- reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; -+ reset-deassert-us = <30000>; -+ /* reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; */ - }; - }; - }; -@@ -169,36 +238,35 @@ rtl8211e: ethernet-phy@1 { - &i2c1 { - status = "okay"; - -- rk805: pmic@18 { -+ rk805: rk805@18 { - compatible = "rockchip,rk805"; - reg = <0x18>; -- interrupt-parent = <&gpio1>; -- interrupts = <24 IRQ_TYPE_LEVEL_LOW>; -+ interrupt-parent = <&gpio2>; -+ interrupts = <6 IRQ_TYPE_LEVEL_LOW>; - #clock-cells = <1>; - clock-output-names = "xin32k", "rk805-clkout2"; - gpio-controller; - #gpio-cells = <2>; -- pinctrl-0 = <&pmic_int_l>; - pinctrl-names = "default"; -+ pinctrl-0 = <&pmic_int_l>; - rockchip,system-power-controller; - wakeup-source; - -- vcc1-supply = <&vdd_5v>; -- vcc2-supply = <&vdd_5v>; -- vcc3-supply = <&vdd_5v>; -- vcc4-supply = <&vdd_5v>; -- vcc5-supply = <&vcc_io_33>; -- vcc6-supply = <&vdd_5v>; -+ vcc1-supply = <&vcc_sys>; -+ vcc2-supply = <&vcc_sys>; -+ vcc3-supply = <&vcc_sys>; -+ vcc4-supply = <&vcc_sys>; -+ vcc5-supply = <&vcc_io>; -+ vcc6-supply = <&vcc_io>; - - regulators { -- vdd_log: DCDC_REG1 { -- regulator-name = "vdd_log"; -- regulator-always-on; -- regulator-boot-on; -+ vdd_logic: DCDC_REG1 { -+ regulator-name = "vdd_logic"; -+ regulator-init-microvolt = <1075000>; - regulator-min-microvolt = <712500>; - regulator-max-microvolt = <1450000>; -- regulator-ramp-delay = <12500>; -- -+ regulator-always-on; -+ regulator-boot-on; - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <1000000>; -@@ -207,12 +275,11 @@ regulator-state-mem { - - vdd_arm: DCDC_REG2 { - regulator-name = "vdd_arm"; -- regulator-always-on; -- regulator-boot-on; -+ regulator-init-microvolt = <1225000>; - regulator-min-microvolt = <712500>; - regulator-max-microvolt = <1450000>; -- regulator-ramp-delay = <12500>; -- -+ regulator-always-on; -+ regulator-boot-on; - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <950000>; -@@ -223,19 +290,17 @@ vcc_ddr: DCDC_REG3 { - regulator-name = "vcc_ddr"; - regulator-always-on; - regulator-boot-on; -- - regulator-state-mem { - regulator-on-in-suspend; - }; - }; - -- vcc_io_33: DCDC_REG4 { -- regulator-name = "vcc_io_33"; -- regulator-always-on; -- regulator-boot-on; -+ vcc_io: DCDC_REG4 { -+ regulator-name = "vcc_io"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; -- -+ regulator-always-on; -+ regulator-boot-on; - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <3300000>; -@@ -244,11 +309,10 @@ regulator-state-mem { - - vcc_18: LDO_REG1 { - regulator-name = "vcc_18"; -- regulator-always-on; -- regulator-boot-on; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; -- -+ regulator-always-on; -+ regulator-boot-on; - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <1800000>; -@@ -257,11 +321,10 @@ regulator-state-mem { - - vcc18_emmc: LDO_REG2 { - regulator-name = "vcc18_emmc"; -- regulator-always-on; -- regulator-boot-on; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; -- -+ regulator-always-on; -+ regulator-boot-on; - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <1800000>; -@@ -270,11 +333,10 @@ regulator-state-mem { - - vdd_10: LDO_REG3 { - regulator-name = "vdd_10"; -- regulator-always-on; -- regulator-boot-on; - regulator-min-microvolt = <1000000>; - regulator-max-microvolt = <1000000>; -- -+ regulator-always-on; -+ regulator-boot-on; - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <1000000>; -@@ -285,84 +347,183 @@ regulator-state-mem { - }; - - &io_domains { -- pmuio-supply = <&vcc_io_33>; -- vccio1-supply = <&vcc_io_33>; -- vccio2-supply = <&vcc18_emmc>; -- vccio3-supply = <&vcc_io_sdio>; -- vccio4-supply = <&vcc_18>; -- vccio5-supply = <&vcc_io_33>; -- vccio6-supply = <&vcc_io_33>; - status = "okay"; -+ -+ vccio1-supply = <&vcc_io>; -+ vccio2-supply = <&vcc18_emmc>; -+ vccio3-supply = <&vcc_io>; -+ vccio4-supply = <&vcc_io>; -+ vccio5-supply = <&vcc_io>; -+ vccio6-supply = <&vcc_18>; -+ pmuio-supply = <&vcc_io>; - }; - - &pinctrl { -- button { -- reset_button_pin: reset-button-pin { -- rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; -+ pmic { -+ pmic_int_l: pmic-int-l { -+ rockchip,pins = <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; - }; - }; - -- gmac2io { -- eth_phy_reset_pin: eth-phy-reset-pin { -- rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>; -+ sdio-pwrseq { -+ wifi_enable_h: wifi-enable-h { -+ rockchip,pins = <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; - -- leds { -- lan_led_pin: lan-led-pin { -- rockchip,pins = <2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; -+ sdmmc0 { -+ sdmmc0_clk: sdmmc0-clk { -+ rockchip,pins = <1 RK_PA6 1 &pcfg_pull_none_4ma>; - }; - -- sys_led_pin: sys-led-pin { -- rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; -+ sdmmc0_cmd: sdmmc0-cmd { -+ rockchip,pins = <1 RK_PA4 1 &pcfg_pull_up_4ma>; - }; - -- wan_led_pin: wan-led-pin { -- rockchip,pins = <2 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; -+ sdmmc0_dectn: sdmmc0-dectn { -+ rockchip,pins = <1 RK_PA5 1 &pcfg_pull_up_4ma>; -+ }; -+ -+ sdmmc0_bus4: sdmmc0-bus4 { -+ rockchip,pins = -+ <1 RK_PA0 1 &pcfg_pull_up_4ma>, -+ <1 RK_PA1 1 &pcfg_pull_up_4ma>, -+ <1 RK_PA2 1 &pcfg_pull_up_4ma>, -+ <1 RK_PA3 1 &pcfg_pull_up_4ma>; - }; - }; - -- lan { -- lan_vdd_pin: lan-vdd-pin { -- rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; -+ sdmmc0ext { -+ sdmmc0ext_clk: sdmmc0ext-clk { -+ rockchip,pins = <3 RK_PA2 3 &pcfg_pull_none_2ma>; -+ }; -+ -+ sdmmc0ext_cmd: sdmmc0ext-cmd { -+ rockchip,pins = <3 RK_PA0 3 &pcfg_pull_up_2ma>; -+ }; -+ -+ sdmmc0ext_bus4: sdmmc0ext-bus4 { -+ rockchip,pins = -+ <3 RK_PA4 3 &pcfg_pull_up_2ma>, -+ <3 RK_PA5 3 &pcfg_pull_up_2ma>, -+ <3 RK_PA6 3 &pcfg_pull_up_2ma>, -+ <3 RK_PA7 3 &pcfg_pull_up_2ma>; - }; - }; - -- pmic { -- pmic_int_l: pmic-int-l { -- rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>; -+ gmac-1 { -+ rgmiim1_pins: rgmiim1-pins { -+ rockchip,pins = -+ /* mac_txclk */ -+ <1 RK_PB4 2 &pcfg_pull_none_4ma>, -+ /* mac_rxclk */ -+ <1 RK_PB5 2 &pcfg_pull_none>, -+ /* mac_mdio */ -+ <1 RK_PC3 2 &pcfg_pull_none_2ma>, -+ /* mac_txen */ -+ <1 RK_PD1 2 &pcfg_pull_none_4ma>, -+ /* mac_clk */ -+ <1 RK_PC5 2 &pcfg_pull_none_2ma>, -+ /* mac_rxdv */ -+ <1 RK_PC6 2 &pcfg_pull_none>, -+ /* mac_mdc */ -+ <1 RK_PC7 2 &pcfg_pull_none_2ma>, -+ /* mac_rxd1 */ -+ <1 RK_PB2 2 &pcfg_pull_none>, -+ /* mac_rxd0 */ -+ <1 RK_PB3 2 &pcfg_pull_none>, -+ /* mac_txd1 */ -+ <1 RK_PB0 2 &pcfg_pull_none_4ma>, -+ /* mac_txd0 */ -+ <1 RK_PB1 2 &pcfg_pull_none_4ma>, -+ /* mac_rxd3 */ -+ <1 RK_PB6 2 &pcfg_pull_none>, -+ /* mac_rxd2 */ -+ <1 RK_PB7 2 &pcfg_pull_none>, -+ /* mac_txd3 */ -+ <1 RK_PC0 2 &pcfg_pull_none_4ma>, -+ /* mac_txd2 */ -+ <1 RK_PC1 2 &pcfg_pull_none_4ma>, -+ -+ /* mac_txclk */ -+ <0 RK_PB0 1 &pcfg_pull_none>, -+ /* mac_txen */ -+ <0 RK_PB4 1 &pcfg_pull_none>, -+ /* mac_clk */ -+ <0 RK_PD0 1 &pcfg_pull_none>, -+ /* mac_txd1 */ -+ <0 RK_PC0 1 &pcfg_pull_none>, -+ /* mac_txd0 */ -+ <0 RK_PC1 1 &pcfg_pull_none>, -+ /* mac_txd3 */ -+ <0 RK_PC7 1 &pcfg_pull_none>, -+ /* mac_txd2 */ -+ <0 RK_PC6 1 &pcfg_pull_none>; - }; - }; - -- sd { -- sdio_vcc_pin: sdio-vcc-pin { -- rockchip,pins = <1 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>; -+ usb { -+ host_vbus_drv: host-vbus-drv { -+ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ otg_vbus_drv: otg-vbus-drv { -+ rockchip,pins = <3 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; -+ -+ gpio-leds { -+ leds_gpio: leds-gpio { -+ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; - }; - --&pwm2 { -+&sdmmc { -+ bus-width = <4>; -+ cap-mmc-highspeed; -+ cap-sd-highspeed; -+ disable-wp; -+ max-frequency = <150000000>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; -+ vmmc-supply = <&vcc_sd>; - status = "okay"; - }; - --&sdmmc { -+&sdmmc_ext { - bus-width = <4>; - cap-sd-highspeed; -+ cap-sdio-irq; - disable-wp; -- pinctrl-0 = <&sdmmc0_clk>, <&sdmmc0_cmd>, <&sdmmc0_dectn>, <&sdmmc0_bus4>; -+ keep-power-in-suspend; -+ max-frequency = <100000000>; -+ mmc-pwrseq = <&sdio_pwrseq>; -+ non-removable; -+ num-slots = <1>; - pinctrl-names = "default"; -- sd-uhs-sdr12; -- sd-uhs-sdr25; -- sd-uhs-sdr50; -+ pinctrl-0 = <&sdmmc0ext_clk &sdmmc0ext_cmd &sdmmc0ext_bus4>; -+ rockchip,default-sample-phase = <120>; -+ supports-sdio; - sd-uhs-sdr104; -- vmmc-supply = <&vcc_sd>; -- vqmmc-supply = <&vcc_io_sdio>; -+ #address-cells = <1>; -+ #size-cells = <0>; - status = "okay"; -+ -+ brcmf: bcrmf@1 { -+ reg = <1>; -+ compatible = "brcm,bcm4329-fmac"; -+ interrupt-parent = <&gpio1>; -+ interrupts = ; -+ interrupt-names = "host-wake"; -+ }; - }; - - &tsadc { -- rockchip,hw-tshut-mode = <0>; -- rockchip,hw-tshut-polarity = <0>; -+ status = "okay"; -+}; -+ -+&uart2 { - status = "okay"; - }; - -@@ -378,13 +539,16 @@ &u2phy_otg { - status = "okay"; - }; - --&uart2 { -+&usb20_otg { - status = "okay"; - }; - --&usb20_otg { -+&usb_host0_ehci { -+ status = "okay"; -+}; -+ -+&usb_host0_ohci { - status = "okay"; -- dr_mode = "host"; - }; - - &usbdrd3 { -@@ -393,17 +557,10 @@ &usbdrd3 { - #address-cells = <1>; - #size-cells = <0>; - -- /* Second port is for USB 3.0 */ -- rtl8153: device@2 { -+ r8153: device@2 { - compatible = "usbbda,8153"; - reg = <2>; -+ realtek,led-data = <0x87>; -+ local-mac-address = [00 00 00 00 00 00]; - }; - }; -- --&usb_host0_ehci { -- status = "okay"; --}; -- --&usb_host0_ohci { -- status = "okay"; --}; - --- -2.34.1 - diff --git a/patch/kernel/archive/rockchip64-6.1/add-board-nanopi-r4se.patch b/patch/kernel/archive/rockchip64-6.1/add-board-nanopi-r4se.patch deleted file mode 100644 index 21a2e8d993a6..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/add-board-nanopi-r4se.patch +++ /dev/null @@ -1,35 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile -index 52def0cf2..cc1d8ec30 100644 ---- a/arch/arm64/boot/dts/rockchip/Makefile -+++ b/arch/arm64/boot/dts/rockchip/Makefile -@@ -42,6 +60,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopi-m4b.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopi-neo4.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopi-r4s.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopi-r4s-enterprise.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopi-r4se.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-orangepi.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-pinebook-pro.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-pinephone-pro.dtb -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4se.dts b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4se.dts -new file mode 100644 -index 000000000..a15620a73 ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4se.dts -@@ -0,0 +1,17 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+ -+/dts-v1/; -+#include "rk3399-nanopi-r4s-enterprise.dts" -+ -+/ { -+ model = "FriendlyElec NanoPi R4SE"; -+ compatible = "friendlyarm,nanopi-r4se", "rockchip,rk3399"; -+}; -+ -+&emmc_phy { -+ status = "okay"; -+}; -+ -+&sdhci { -+ status = "okay"; -+}; diff --git a/patch/kernel/archive/rockchip64-6.1/add-board-orangepi-4-lts.patch b/patch/kernel/archive/rockchip64-6.1/add-board-orangepi-4-lts.patch deleted file mode 100644 index 753dfd6e7283..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/add-board-orangepi-4-lts.patch +++ /dev/null @@ -1,1322 +0,0 @@ -From 4af18a7595fc0bf36b91867217ac1bfbb7e5503f Mon Sep 17 00:00:00 2001 -From: Paolo Sabatino -Date: Sun, 21 May 2023 17:35:55 +0200 -Subject: [PATCH] rk3399: add Orange Pi 4 LTS device tree - ---- - .../dts/rockchip/rk3399-orangepi-4-lts.dts | 1244 +++++++++++++++++ - 1 file changed, 1244 insertions(+) - create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-orangepi-4-lts.dts - -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-orangepi-4-lts.dts b/arch/arm64/boot/dts/rockchip/rk3399-orangepi-4-lts.dts -new file mode 100644 -index 000000000000..6d6bee12a453 ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3399-orangepi-4-lts.dts -@@ -0,0 +1,1304 @@ -+/* -+ * SPDX-License-Identifier: (GPL-2.0+ or MIT) -+ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd. -+ * Copyright (c) 2018 Akash Gajjar -+ * Copyright (c) 2020-2022 Armbian (chwe17, piter75, jock) -+ * -+ */ -+ -+/dts-v1/; -+#include -+#include -+#include -+#include -+#include -+#include "rk3399.dtsi" -+#include "rk3399-opp.dtsi" -+ -+/ { -+ model = "OrangePi 4 LTS"; -+ compatible = "xunlong,orangepi-4-lts", "rockchip,rk3399"; -+ -+ chosen { -+ stdout-path = "serial2:1500000n8"; -+ }; -+ -+ aliases { -+ spi1 = &spi1; -+ }; -+ -+ clkin_gmac: external-gmac-clock { -+ compatible = "fixed-clock"; -+ clock-frequency = <125000000>; -+ clock-output-names = "clkin_gmac"; -+ #clock-cells = <0>; -+ }; -+ -+ vcc_sys: vcc-sys { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ vcc5v0_sys: vcc5v0-sys { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v0_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc_sys>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ usb_vbus: usb-vbus { -+ compatible = "regulator-fixed"; -+ regulator-name = "usb_vbus"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc5v0_sys>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ usb3_vbus: usb3-vbus { -+ compatible = "regulator-fixed"; -+ regulator-name = "usb3_vbus"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc5v0_sys>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vbus_typec: vbus-typec { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio2 RK_PB4 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vcc5v0_typec_en>; -+ regulator-name = "vbus-5v"; -+ regulator-always-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc5v0_sys>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ /* 0.9 V supply, over PMIC -+ vcc_0v9: vcc-0v9 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc_0v9"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ vin-supply = <&vcc3v3_sys>; -+ } -+ */ -+ -+ vcc3v0_sd: vcc3v0-sd { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc_pwr>; -+ regulator-name = "vcc3v0_sd"; -+ regulator-always-on; -+ regulator-min-microvolt = <3000000>; -+ regulator-max-microvolt = <3000000>; -+ vin-supply = <&vcc3v3_sys>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc3v3_pcie: vcc3v3-pcie-regulator { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie_drv>; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-name = "vcc3v3_pcie"; -+ }; -+ -+ vcc3v3_sys: vcc3v3-sys { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc3v3_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&vcc_sys>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vdd_log: vdd-log { -+ compatible = "pwm-regulator"; -+ pwms = <&pwm2 0 25000 1>; -+ regulator-name = "vdd_log"; -+ regulator-min-microvolt = <800000>; -+ regulator-max-microvolt = <1400000>; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&vcc3v3_sys>; -+ }; -+ -+ es8316c_card: es8316c-card { -+ compatible = "simple-audio-card"; -+ -+ simple-audio-card,format = "i2s"; -+ simple-audio-card,name = "rockchip-es8316c"; -+ simple-audio-card,mclk-fs = <256>; -+ simple-audio-card,hp-det-gpio = <&gpio4 RK_PD4 GPIO_ACTIVE_HIGH>; -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hp_det>; -+ -+ simple-audio-card,widgets = -+ "Microphone", "Mic Jack", -+ "Headphone", "Headphones"; -+ -+ simple-audio-card,routing = -+ "MIC1", "Mic Jack", -+ "Headphones", "HPOL", -+ "Headphones", "HPOR"; -+ -+ simple-audio-card,cpu { -+ sound-dai = <&i2s0>; -+ }; -+ -+ simple-audio-card,codec { -+ sound-dai = <&es8316c_codec>; -+ }; -+ -+ }; -+ -+ hdmi-sound { -+ compatible = "simple-audio-card"; -+ simple-audio-card,format = "i2s"; -+ simple-audio-card,mclk-fs = <256>; -+ simple-audio-card,name = "hdmi-sound"; -+ status = "okay"; -+ -+ simple-audio-card,cpu { -+ sound-dai = <&i2s2>; -+ }; -+ -+ simple-audio-card,codec { -+ sound-dai = <&hdmi>; -+ }; -+ }; -+ -+ spdif-sound { -+ status = "disable"; -+ compatible = "simple-audio-card"; -+ simple-audio-card,name = "ROCKCHIP,SPDIF"; -+ simple-audio-card,cpu { -+ sound-dai = <&spdif>; -+ }; -+ simple-audio-card,codec { -+ sound-dai = <&spdif_out>; -+ }; -+ }; -+ -+ spdif_out: spdif-out { -+ status = "disable"; -+ compatible = "linux,spdif-dit"; -+ #sound-dai-cells = <0>; -+ }; -+ -+ pwm_bl: backlight { -+ status = "disable"; -+ compatible = "pwm-backlight"; -+ pwms = <&pwm0 0 25000 0>; -+ brightness-levels = < -+ 0 1 2 3 4 5 6 7 -+ 8 9 10 11 12 13 14 15 -+ 16 17 18 19 20 21 22 23 -+ 24 25 26 27 28 29 30 31 -+ 32 33 34 35 36 37 38 39 -+ 40 41 42 43 44 45 46 47 -+ 48 49 50 51 52 53 54 55 -+ 56 57 58 59 60 61 62 63 -+ 64 65 66 67 68 69 70 71 -+ 72 73 74 75 76 77 78 79 -+ 80 81 82 83 84 85 86 87 -+ 88 89 90 91 92 93 94 95 -+ 96 97 98 99 100 101 102 103 -+ 104 105 106 107 108 109 110 111 -+ 112 113 114 115 116 117 118 119 -+ 120 121 122 123 124 125 126 127 -+ 128 129 130 131 132 133 134 135 -+ 136 137 138 139 140 141 142 143 -+ 144 145 146 147 148 149 150 151 -+ 152 153 154 155 156 157 158 159 -+ 160 161 162 163 164 165 166 167 -+ 168 169 170 171 172 173 174 175 -+ 176 177 178 179 180 181 182 183 -+ 184 185 186 187 188 189 190 191 -+ 192 193 194 195 196 197 198 199 -+ 200 201 202 203 204 205 206 207 -+ 208 209 210 211 212 213 214 215 -+ 216 217 218 219 220 221 222 223 -+ 224 225 226 227 228 229 230 231 -+ 232 233 234 235 236 237 238 239 -+ 240 241 242 243 244 245 246 247 -+ 248 249 250 251 252 253 254 255>; -+ default-brightness-level = <200>; -+ }; -+ -+ gpio-keys { -+ compatible = "gpio-keys"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ autorepeat; -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&power_key>; -+ -+ button@0 { -+ gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>; -+ linux,code = ; -+ label = "GPIO Key Power"; -+ linux,input-type = <1>; -+ gpio-key,wakeup = <1>; -+ debounce-interval = <100>; -+ }; -+ }; -+ -+ adc-keys { -+ compatible = "adc-keys"; -+ io-channels = <&saradc 1>; -+ io-channel-names = "buttons"; -+ poll-interval = <100>; -+ keyup-threshold-microvolt = <1800000>; -+ -+ button-up { -+ label = "Volume Up"; -+ linux,code = ; -+ press-threshold-microvolt = <100000>; -+ }; -+ -+ button-down { -+ label = "Volume Down"; -+ linux,code = ; -+ press-threshold-microvolt = <300000>; -+ }; -+ }; -+ -+ leds: gpio-leds { -+ compatible = "gpio-leds"; -+ pinctrl-names = "default"; -+ pinctrl-0 =<&leds_gpio>; -+ -+ led@1 { -+ gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>; -+ label = "status_led"; -+ linux,default-trigger = "heartbeat"; -+ linux,default-trigger-delay-ms = <0>; -+ }; -+ }; -+ -+ sdio_pwrseq: sdio-pwrseq { -+ compatible = "mmc-pwrseq-simple"; -+ clocks = <&rk808 1>; -+ clock-names = "ext_clock"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&wifi_enable_h>; -+ -+ /* -+ * On the module itself this is one of these (depending -+ * on the actual card populated): -+ * - SDIO_RESET_L_WL_REG_ON -+ * - PDN (power down when low) -+ */ -+ reset-gpios = <&gpio0 10 GPIO_ACTIVE_LOW>; /* GPIO0_B2 */ -+ }; -+ -+ unisoc_uwe_bsp: uwe-bsp { -+ compatible = "unisoc,uwe_bsp"; -+ //wl-reg-on = <&gpio0 10 GPIO_ACTIVE_HIGH>; // handled by sdio-pwrseq -+ bt-reg-on = <&gpio0 9 GPIO_ACTIVE_HIGH>; -+ wl-wake-host-gpio = <&gpio0 3 GPIO_ACTIVE_HIGH>; -+ bt-wake-host-gpio = <&gpio0 4 GPIO_ACTIVE_HIGH>; -+ sdio-ext-int-gpio = <&gpio3 30 GPIO_ACTIVE_HIGH>; -+ unisoc,btwf-file-name = "/lib/firmware/uwe5622/wcnmodem-38222.bin"; -+ data-irq; -+ blksz-512; -+ keep-power-on; -+ status = "okay"; -+ }; -+ -+ sprd-wlan { -+ compatible = "sprd,uwe5622-wifi"; -+ status = "okay"; -+ }; -+ -+ sprd-mtty { -+ compatible = "sprd,mtty"; -+ sprd,name = "ttyBT"; -+ status = "okay"; -+ }; -+ -+ dmc_opp_table: dmc_opp_table { -+ compatible = "operating-points-v2"; -+ -+ opp00 { -+ opp-hz = /bits/ 64 <328000000>; -+ opp-microvolt = <900000>; -+ }; -+ -+ opp01 { -+ opp-hz = /bits/ 64 <416000000>; -+ opp-microvolt = <900000>; -+ }; -+ -+ opp02 { -+ opp-hz = /bits/ 64 <666000000>; -+ opp-microvolt = <900000>; -+ }; -+ -+ }; -+ -+}; -+ -+&cpu_l0 { -+ cpu-supply = <&vdd_cpu_l>; -+}; -+ -+&cpu_l1 { -+ cpu-supply = <&vdd_cpu_l>; -+}; -+ -+&cpu_l2 { -+ cpu-supply = <&vdd_cpu_l>; -+}; -+ -+&cpu_l3 { -+ cpu-supply = <&vdd_cpu_l>; -+}; -+ -+&cpu_b0 { -+ cpu-supply = <&vdd_cpu_b>; -+}; -+ -+&cpu_b1 { -+ cpu-supply = <&vdd_cpu_b>; -+}; -+ -+&gpu { -+ status = "okay"; -+ mali-supply = <&vdd_gpu>; -+}; -+ -+&gmac { -+ assigned-clocks = <&cru SCLK_RMII_SRC>; -+ assigned-clock-parents = <&clkin_gmac>; -+ clock_in_out = "input"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&rgmii_pins>; -+ phy-mode = "rgmii"; -+ phy-supply = <&vcc3v3_s3>; -+ snps,reset-active-low; -+ snps,reset-delays-us = <0 10000 50000>; -+ snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; -+ tx_delay = <0x28>; -+ rx_delay = <0x11>; -+ status = "okay"; -+}; -+ -+&spi1 { -+ status = "disable"; -+ pinctrl-names = "default", "sleep"; -+ pinctrl-1 = <&spi1_gpio>; -+ -+ spidev0: spidev@0 { -+ compatible = "rockchip,spidev"; -+ reg = <0>; -+ spi-max-frequency = <10000000>; -+ status = "okay"; -+ }; -+}; -+ -+&uart0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; -+ status = "okay"; -+}; -+ -+&uart2 { -+ status = "okay"; -+}; -+ -+&vopb { -+ status = "okay"; -+}; -+ -+&vopb_mmu { -+ status = "okay"; -+}; -+ -+&vopl { -+ status = "okay"; -+}; -+ -+&vopl_mmu { -+ status = "okay"; -+}; -+ -+&vpu { -+ status = "okay"; -+}; -+ -+&rga { -+ status = "okay"; -+}; -+ -+&cdn_dp { -+ status = "okay"; -+ extcon = <&fusb0>; -+ phys = <&tcphy0_dp>; -+}; -+ -+&hdmi { -+ /* remove the hdmi_i2c_xfer */ -+ pinctrl-0 = <&hdmi_cec>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ #sound-dai-cells = <0>; -+ status = "okay"; -+ ddc-i2c-bus = <&i2c7>; -+}; -+ -+&i2c0 { -+ clock-frequency = <400000>; -+ i2c-scl-rising-time-ns = <160>; -+ i2c-scl-falling-time-ns = <30>; -+ status = "okay"; -+ -+ rk808: pmic@1b { -+ compatible = "rockchip,rk808"; -+ reg = <0x1b>; -+ interrupt-parent = <&gpio2>; -+ interrupts = ; -+ #clock-cells = <1>; -+ clock-output-names = "xin32k", "rk808-clkout2"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pmic_int_l>; -+ rockchip,system-power-controller; -+ wakeup-source; -+ -+ vcc1-supply = <&vcc3v3_sys>; -+ vcc2-supply = <&vcc3v3_sys>; -+ vcc3-supply = <&vcc3v3_sys>; -+ vcc4-supply = <&vcc3v3_sys>; -+ vcc6-supply = <&vcc3v3_sys>; -+ vcc7-supply = <&vcc3v3_sys>; -+ vcc8-supply = <&vcc3v3_sys>; -+ vcc9-supply = <&vcc3v3_sys>; -+ vcc10-supply = <&vcc3v3_sys>; -+ vcc11-supply = <&vcc3v3_sys>; -+ vcc12-supply = <&vcc3v3_sys>; -+ vcc13-supply = <&vcc3v3_sys>; -+ vcc14-supply = <&vcc3v3_sys>; -+ vddio-supply = <&vcc_3v0>; -+ -+ regulators { -+ vdd_center: DCDC_REG1 { -+ regulator-name = "vdd_center"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <750000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-ramp-delay = <6001>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_cpu_l: DCDC_REG2 { -+ regulator-name = "vdd_cpu_l"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <750000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-ramp-delay = <6001>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_ddr: DCDC_REG3 { -+ regulator-name = "vcc_ddr"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vcc1v8: vcc1v8_s3: vcca1v8_s3: DCDC_REG4 { -+ regulator-name = "vcc1v8"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vcc1v8_dvp: LDO_REG1 { -+ regulator-name = "vcc1v8_dvp"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc3v0_touch: LDO_REG2 { -+ regulator-name = "vcc3v0_touch"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3000000>; -+ regulator-max-microvolt = <3000000>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc1v8_pmu: LDO_REG3 { -+ regulator-name = "vcc1v8_pmu"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vcc_sdio: LDO_REG4 { -+ regulator-name = "vcc_sdio"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3000000>; -+ regulator-init-microvolt = <3000000>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3000000>; -+ }; -+ }; -+ -+ vcca3v0_codec: LDO_REG5 { -+ regulator-name = "vcca3v0_codec"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3000000>; -+ regulator-max-microvolt = <3000000>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_1v5: LDO_REG6 { -+ regulator-name = "vcc_1v5"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1500000>; -+ regulator-max-microvolt = <1500000>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1500000>; -+ }; -+ }; -+ -+ vcca1v8_codec: LDO_REG7 { -+ regulator-name = "vcca1v8_codec"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_3v0: LDO_REG8 { -+ regulator-name = "vcc_3v0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3000000>; -+ regulator-max-microvolt = <3000000>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3000000>; -+ }; -+ }; -+ -+ vcc3v3_s3: vcc_lan: SWITCH_REG1 { -+ regulator-name = "vcc3v3_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc3v3_s0: SWITCH_REG2 { -+ regulator-name = "vcc3v3_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ }; -+ }; -+ -+ vdd_cpu_b: regulator@40 { -+ compatible = "silergy,syr827"; -+ reg = <0x40>; -+ fcs,suspend-voltage-selector = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vsel1_gpio>; -+ vsel-gpios = <&gpio1 RK_PC1 GPIO_ACTIVE_HIGH>; -+ regulator-compatible = "fan53555-reg"; -+ regulator-name = "vdd_cpu_b"; -+ regulator-min-microvolt = <712500>; -+ regulator-max-microvolt = <1500000>; -+ regulator-ramp-delay = <1000>; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&vcc3v3_sys>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_gpu: regulator@41 { -+ compatible = "silergy,syr828"; -+ reg = <0x41>; -+ fcs,suspend-voltage-selector = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vsel2_gpio>; -+ vsel-gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_HIGH>; -+ regulator-compatible = "fan53555-reg"; -+ regulator-name = "vdd_gpu"; -+ regulator-min-microvolt = <712500>; -+ regulator-max-microvolt = <1500000>; -+ regulator-ramp-delay = <1000>; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&vcc3v3_sys>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+}; -+ -+&i2c1 { -+ clock-frequency = <200000>; -+ i2c-scl-rising-time-ns = <300>; -+ i2c-scl-falling-time-ns = <15>; -+ status = "okay"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ es8316c_codec: es8316c@11 { -+ #sound-dai-cells = <0>; -+ compatible = "everest,es8316"; -+ reg = <17>; -+ clocks = <&cru SCLK_I2S_8CH_OUT>; -+ clock-names = "mclk"; -+ //pinctrl-names = "default"; -+ //pinctrl-0 = <&i2s_8ch_mclk>; -+ status = "okay"; -+ }; -+ -+}; -+ -+&i2c3 { -+ status = "okay"; -+}; -+ -+&i2c4 { -+ status = "okay"; -+ i2c-scl-rising-time-ns = <160>; -+ i2c-scl-falling-time-ns = <30>; -+ clock-frequency = <400000>; -+ -+ fusb0: fusb30x@22 { -+ compatible = "fcs,fusb302"; -+ reg = <0x22>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&fusb0_int>; -+ interrupt-parent = <&gpio1>; -+ interrupts = ; -+ vbus-supply = <&vbus_typec>; -+ status = "okay"; -+ -+ connector { -+ compatible = "usb-c-connector"; -+ data-role = "dual"; -+ label = "USB-C"; -+ op-sink-microwatt = <1000000>; -+ power-role = "dual"; -+ sink-pdos = -+ ; -+ source-pdos = -+ ; -+ try-power-role = "sink"; -+ -+ extcon-cables = <1 2 5 6 9 10 12 44>; -+ typec-altmodes = <0xff01 1 0x001c0000 1>; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ port@0 { -+ reg = <0>; -+ -+ usbc_hs: endpoint { -+ remote-endpoint = -+ <&u2phy0_typec_hs>; -+ }; -+ }; -+ -+ port@1 { -+ reg = <1>; -+ -+ usbc_ss: endpoint { -+ remote-endpoint = -+ <&tcphy0_typec_ss>; -+ }; -+ }; -+ -+ port@2 { -+ reg = <2>; -+ -+ usbc_dp: endpoint { -+ remote-endpoint = -+ <&tcphy0_typec_dp>; -+ }; -+ }; -+ }; -+ }; -+ -+ }; -+ -+ ft5x06_ts@38 { -+ compatible = "edt,edt-ft5x06", "ft5x06"; -+ reg = <0x38>; -+ interrupt-parent = <&gpio1>; -+ interrupts = <20 IRQ_TYPE_EDGE_FALLING>; -+ status = "okay"; -+ }; -+ -+}; -+ -+&i2c7 { -+ status = "okay"; -+}; -+ -+&spdif { -+ status = "disable"; -+ pinctrl-0 = <&spdif_bus>; -+ i2c-scl-rising-time-ns = <450>; -+ i2c-scl-falling-time-ns = <15>; -+ #sound-dai-cells = <0>; -+}; -+ -+&i2s0 { -+ rockchip,i2s-broken-burst-len; -+ assigned-clocks = <&cru SCLK_I2SOUT_SRC>; -+ assigned-clock-parents = <&cru SCLK_I2S0_8CH>; -+ resets = <&cru SRST_I2S0_8CH>, <&cru SRST_H_I2S0_8CH>; -+ reset-names = "reset-m", "reset-h"; -+ rockchip,playback-channels = <2>; -+ rockchip,capture-channels = <2>; -+ status = "okay"; -+ #sound-dai-cells = <0>; -+}; -+ -+&i2s2 { -+ #sound-dai-cells = <0>; -+ status = "okay"; -+}; -+ -+&io_domains { -+ status = "okay"; -+ -+ bt656-supply = <&vcc1v8_dvp>; /* bt656_gpio2ab_ms */ -+ audio-supply = <&vcca1v8_codec>; /* audio_gpio3d4a_ms */ -+ sdmmc-supply = <&vcc_sdio>; /* sdmmc_gpio4b_ms */ -+ gpio1830-supply = <&vcc_3v0>; /* gpio1833_gpio4cd_ms */ -+}; -+ -+&pmu_io_domains { -+ status = "okay"; -+ pmu1830-supply = <&vcc_3v0>; -+}; -+ -+&pcie_phy { -+ status = "okay"; -+ assigned-clocks = <&cru SCLK_PCIEPHY_REF>; -+ assigned-clock-parents = <&cru SCLK_PCIEPHY_REF100M>; -+ assigned-clock-rates = <100000000>; -+}; -+ -+&pcie0 { -+ status = "okay"; -+ ep-gpios = <&gpio2 4 GPIO_ACTIVE_HIGH>; -+ num-lanes = <4>; -+ max-link-speed = <1>; -+}; -+ -+&pwm_bl { -+ status = "okay"; -+}; -+ -+&pwm0 { -+ status = "okay"; -+}; -+ -+&pwm1 { -+ status = "okay"; -+}; -+ -+&pwm2 { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pwm2_pin_pull_down>; -+}; -+ -+&saradc { -+ status = "okay"; -+ vref-supply = <&vcca1v8_s3>; /* TBD */ -+}; -+ -+&sdhci { -+ bus-width = <8>; -+ mmc-hs400-1_8v; -+ supports-emmc; -+ non-removable; -+ keep-power-in-suspend; -+ mmc-hs400-enhanced-strobe; -+ status = "okay"; -+}; -+ -+&emmc_phy { -+ status = "okay"; -+}; -+ -+&sdio0 { -+ clock-frequency = <150000000>; -+ max-frequency = <150000000>; -+ supports-sdio; -+ bus-width = <4>; -+ disable-wp; -+ cap-sd-highspeed; -+ cap-sdio-irq; -+ keep-power-in-suspend; -+ mmc-pwrseq = <&sdio_pwrseq>; -+ non-removable; -+ num-slots = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>; -+ sd-uhs-sdr104; -+ status = "okay"; -+}; -+ -+&sdmmc { -+ bus-width = <4>; -+ cap-sd-highspeed; -+ cap-mmc-highspeed; -+ cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; -+ cd-debounce-delay-ms = <500>; -+ disable-wp; -+ max-frequency = <150000000>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc_cd>; -+ sd-uhs-sdr104; -+ vmmc-supply = <&vcc3v0_sd>; -+ vqmmc-supply = <&vcc_sdio>; -+ status = "okay"; -+}; -+ -+&tsadc { -+ /* tshut mode 0:CRU 1:GPIO */ -+ rockchip,hw-tshut-mode = <1>; -+ /* tshut polarity 0:LOW 1:HIGH */ -+ rockchip,hw-tshut-polarity = <1>; -+ status = "okay"; -+}; -+ -+&tcphy0 { -+ extcon = <&fusb0>; -+ status = "okay"; -+}; -+ -+&tcphy0_dp { -+ port { -+ tcphy0_typec_dp: endpoint { -+ remote-endpoint = <&usbc_dp>; -+ }; -+ }; -+}; -+ -+&tcphy0_usb3 { -+ port { -+ tcphy0_typec_ss: endpoint { -+ remote-endpoint = <&usbc_ss>; -+ }; -+ }; -+}; -+ -+&tcphy1 { -+ status = "okay"; -+}; -+ -+&u2phy0 { -+ status = "okay"; -+ -+ u2phy0_otg: otg-port { -+ status = "okay"; -+ }; -+ -+ u2phy0_host: host-port { -+ phy-supply = <&usb3_vbus>; -+ status = "okay"; -+ }; -+ -+ port { -+ u2phy0_typec_hs: endpoint { -+ remote-endpoint = <&usbc_hs>; -+ }; -+ }; -+ -+}; -+ -+&u2phy1 { -+ status = "okay"; -+ -+ u2phy1_otg: otg-port { -+ status = "okay"; -+ }; -+ -+ u2phy1_host: host-port { -+ phy-supply = <&usb_vbus>; -+ status = "okay"; -+ }; -+}; -+ -+&usbdrd3_0 { -+ status = "okay"; -+ extcon = <&fusb0>; -+}; -+ -+&usbdrd3_1 { -+ status = "okay"; -+}; -+ -+&usbdrd_dwc3_0 { -+ status = "okay"; -+}; -+ -+&usbdrd_dwc3_1 { -+ status = "okay"; -+ dr_mode = "host"; -+}; -+ -+&usb_host0_ehci { -+ status = "okay"; -+}; -+ -+&usb_host0_ohci { -+ status = "okay"; -+}; -+ -+&usb_host1_ehci { -+ status = "okay"; -+}; -+ -+&usb_host1_ohci { -+ status = "okay"; -+}; -+ -+&sdmmc_bus4 { -+ rockchip,pins = -+ <4 RK_PB0 1 &pcfg_pull_up_12ma>, -+ <4 RK_PB1 1 &pcfg_pull_up_12ma>, -+ <4 RK_PB2 1 &pcfg_pull_up_12ma>, -+ <4 RK_PB3 1 &pcfg_pull_up_12ma>; -+}; -+ -+&sdmmc_cmd { -+ rockchip,pins = -+ <4 RK_PB5 1 &pcfg_pull_up_12ma>; -+}; -+ -+&pinctrl { -+ -+ pcfg_pull_up_12ma: pcfg-pull-up-12ma { -+ bias-pull-up; -+ drive-strength = <12>; -+ }; -+ -+ pcie { -+ pcie_drv: pcie-drv { -+ rockchip,pins = -+ <1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ hdmi { -+ /delete-node/ hdmi-i2c-xfer; -+ }; -+ -+ i2s0 { -+ i2s_8ch_mclk: i2s-8ch-mclk { -+ rockchip,pins = <4 RK_PA0 1 &pcfg_pull_none>; -+ }; -+ }; -+ -+ pmic { -+ pmic_int_l: pmic-int-l { -+ rockchip,pins = <2 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ -+ vsel1_gpio: vsel1-gpio { -+ rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ -+ vsel2_gpio: vsel2-gpio { -+ rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ }; -+ -+ usb-typec { -+ vcc5v0_typec_en: vcc5v0_typec_en { -+ rockchip,pins = <2 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ -+ fusb30x { -+ fusb0_int: fusb0-int { -+ rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ -+ sdio-pwrseq { -+ wifi_enable_h: wifi-enable-h { -+ rockchip,pins = <0 10 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ wireless-bluetooth { -+ uart0_gpios: uart0-gpios { -+ rockchip,pins = <2 19 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ rockchip-key { -+ power_key: power-key { -+ rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ -+ headphone { -+ hp_det: hp-det { -+ rockchip,pins = <4 28 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ -+ gpio-leds { -+ leds_gpio: leds-gpio { -+ rockchip,pins = <0 11 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ cam_pins { -+ cif_clkout_a: cif-clkout-a { -+ rockchip,pins = <2 11 3 &pcfg_pull_none>; -+ }; -+ -+ cif_clkout_a_sleep: cif-clkout-a-sleep { -+ rockchip,pins = <2 11 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ cam0_default_pins: cam0-default-pins { -+ rockchip,pins = -+ <4 27 0 &pcfg_pull_down>, -+ <2 11 3 &pcfg_pull_none>; -+ }; -+ -+ cam0_sleep_pins: cam0-sleep-pins { -+ rockchip,pins = -+ <4 27 3 &pcfg_pull_none>, -+ <2 11 0 &pcfg_pull_none>; -+ }; -+ -+ cam1_default_pins: cam1-default-pins { -+ rockchip,pins = -+ <0 12 RK_FUNC_GPIO &pcfg_pull_down>, -+ <0 8 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ spi1 { -+ spi1_gpio: spi1-gpio { -+ rockchip,pins = -+ <1 7 RK_FUNC_GPIO &pcfg_output_low>, -+ <1 8 RK_FUNC_GPIO &pcfg_output_low>, -+ <1 9 RK_FUNC_GPIO &pcfg_output_low>, -+ <1 10 RK_FUNC_GPIO &pcfg_output_low>; -+ }; -+ }; -+ -+ bt { -+ bt_host_wake: bt-host-wake { -+ rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ bt_reset: bt-reset { -+ rockchip,pins = <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ bt_wake: bt-wake { -+ rockchip,pins = <2 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+}; -+ -+&hdmi_in_vopb { -+ status = "okay"; -+}; -+ -+&hdmi_in_vopl { -+ status = "disable"; -+}; -+ -+&dp_in_vopb { -+ status = "disable"; -+}; -+&dp_in_vopl { -+ status = "okay"; -+}; -+ -+&dmc { -+ #cooling-cells = <2>; /* min followed by max */ -+ -+ status = "okay"; -+ center-supply = <&vdd_log>; -+ operating-points-v2 = <&dmc_opp_table>; -+ -+ rockchip,pd-idle-ns = <160>; -+ rockchip,sr-idle-ns = <10240>; -+ rockchip,sr-mc-gate-idle-ns = <40960>; -+ rockchip,srpd-lite-idle-ns = <61440>; -+ rockchip,standby-idle-ns = <81920>; -+ -+ rockchip,ddr3_odt_dis_freq = <666000000>; -+ rockchip,lpddr3_odt_dis_freq = <666000000>; -+ rockchip,lpddr4_odt_dis_freq = <666000000>; -+ -+ rockchip,sr-mc-gate-idle-dis-freq-hz = <1000000000>; -+ rockchip,srpd-lite-idle-dis-freq-hz = <0>; -+ rockchip,standby-idle-dis-freq-hz = <928000000>; -+ -+}; -+ -+&dfi { -+ status = "okay"; -+}; -+ -+/* -+ * Redefine some parameters for the thermal trip points for Opi4 LTS. -+ * First of all, the Soc does not like getting over 90°C. My sample -+ * froze at 94.4°C, so we lower the critical temprature to 90°C, hopefully -+ * giving enough room for safe reboot of the device. -+ * Big cores are getting throttled a bit when reaching 82°C, then at 85°C -+ * we aggressively throttle all the cores and even the memory controller. -+ * The GPU is handled by existing trip points in the base device tree, here -+ * we just set the same critical temperature as CPU. -+ */ -+&cpu_alert0 { -+ temperature = <82000>; -+}; -+ -+&cpu_alert1 { -+ temperature = <85000>; -+}; -+ -+&cpu_crit { -+ temperatue = <90000>; -+}; -+ -+&gpu_crit { -+ temperatue = <90000>; -+}; -+ -+&cpu_thermal { -+ -+ cooling-maps { -+ -+ map0 { -+ trip = <&cpu_alert0>; -+ cooling-device = -+ <&cpu_b0 THERMAL_NO_LIMIT 3>, -+ <&cpu_b1 THERMAL_NO_LIMIT 3>; -+ }; -+ -+ map1 { -+ trip = <&cpu_alert1>; -+ cooling-device = -+ <&cpu_l0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -+ <&cpu_l1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -+ <&cpu_l2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -+ <&cpu_l3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -+ <&cpu_b0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -+ <&cpu_b1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; -+ }; -+ -+ map2 { -+ trip = <&cpu_alert1>; -+ cooling-device = -+ <&dmc THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; -+ }; -+ -+ }; -+ -+}; --- -2.34.1 diff --git a/patch/kernel/archive/rockchip64-6.1/add-board-orangepi-4.patch b/patch/kernel/archive/rockchip64-6.1/add-board-orangepi-4.patch deleted file mode 100644 index 71660d9bc41c..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/add-board-orangepi-4.patch +++ /dev/null @@ -1,1200 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-orangepi-4.dts b/arch/arm64/boot/dts/rockchip/rk3399-orangepi-4.dts -new file mode 100644 -index 00000000000..9efe2513944 ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3399-orangepi-4.dts -@@ -0,0 +1,1194 @@ -+/* -+ * SPDX-License-Identifier: (GPL-2.0+ or MIT) -+ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd. -+ * Copyright (c) 2018 Akash Gajjar -+ * Copyright (c) 2020 Armbian (chwe17, piter75) -+ * -+ */ -+ -+/dts-v1/; -+#include -+#include -+#include -+//#include -+#include "rk3399.dtsi" -+#include "rk3399-opp.dtsi" -+ -+/ { -+ model = "OrangePi 4"; -+ compatible = "xunlong,orangepi-4", "rockchip,rk3399"; -+ -+ chosen { -+ stdout-path = "serial2:1500000n8"; -+ }; -+ -+ aliases { -+ spi1 = &spi1; -+ }; -+ -+ clkin_gmac: external-gmac-clock { -+ compatible = "fixed-clock"; -+ clock-frequency = <125000000>; -+ clock-output-names = "clkin_gmac"; -+ #clock-cells = <0>; -+ }; -+ -+ usb_vbus: usb-vbus { -+ compatible = "regulator-fixed"; -+ regulator-name = "usb_vbus"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc5v0_sys>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ usb3_vbus: usb3-vbus { -+ compatible = "regulator-fixed"; -+ regulator-name = "usb3_vbus"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc5v0_sys>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vbus_typec: vbus-typec { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio2 RK_PB4 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vcc5v0_typec_en>; -+ regulator-name = "vbus_typec"; -+ regulator-always-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc5v0_sys>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ /* 0.9 V supply, over PMIC -+ vcc_0v9: vcc-0v9 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc_0v9"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ vin-supply = <&vcc3v3_sys>; -+ } -+ */ -+ -+ vcc3v0_sd: vcc3v0-sd { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc0_pwr_h>; -+ regulator-name = "vcc3v0_sd"; -+ regulator-always-on; -+ regulator-min-microvolt = <3000000>; -+ regulator-max-microvolt = <3000000>; -+ vin-supply = <&vcc3v3_sys>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc3v3_pcie: vcc3v3-pcie-regulator { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie_drv>; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-name = "vcc3v3_pcie"; -+ }; -+ -+ vcc3v3_sys: vcc3v3-sys { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc3v3_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&vcc_sys>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vcc5v0_sys: vcc5v0-sys { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v0_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc_sys>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vcc_sys: vcc-sys { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ vdd_log: vdd-log { -+ compatible = "pwm-regulator"; -+ pwms = <&pwm2 0 25000 1>; -+ regulator-name = "vdd_log"; -+ regulator-min-microvolt = <800000>; -+ regulator-max-microvolt = <1400000>; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&vcc3v3_sys>; -+ }; -+ -+ rt5651_card: rt5651-sound { -+ status = "okay"; -+ compatible = "simple-audio-card"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hp_det>; -+ -+ simple-audio-card,name = "realtek,rt5651-codec"; -+ simple-audio-card,format = "i2s"; -+ simple-audio-card,mclk-fs = <256>; -+ simple-audio-card,hp-det-gpio = <&gpio4 28 GPIO_ACTIVE_HIGH>; -+ -+ simple-audio-card,widgets = -+ "Microphone", "Mic Jack", -+ "Headphone", "Headphone Jack"; -+ simple-audio-card,routing = -+ "Mic Jack", "micbias1", -+ "IN2P", "Mic Jack", -+ "IN3P", "Mic Jack", -+ "Headphone Jack", "HPOL", -+ "Headphone Jack", "HPOR"; -+ -+ simple-audio-card,cpu { -+ sound-dai = <&i2s1>; -+ }; -+ simple-audio-card,codec { -+ sound-dai = <&rt5651>; -+ }; -+ }; -+ -+ dw_hdmi_audio: dw-hdmi-audio { -+ status = "disable"; -+ compatible = "rockchip,dw-hdmi-audio"; -+ #sound-dai-cells = <0>; -+ }; -+ -+ hdmi_sound: hdmi-sound { -+ status = "okay"; -+ }; -+ -+ hdmi_dp_sound: hdmi-dp-sound { -+ status = "okay"; -+ compatible = "rockchip,rk3399-hdmi-dp"; -+ rockchip,cpu = <&i2s2>; -+ rockchip,codec = <&hdmi>, <&cdn_dp>; -+ }; -+ -+ spdif-sound { -+ status = "disable"; -+ compatible = "simple-audio-card"; -+ simple-audio-card,name = "ROCKCHIP,SPDIF"; -+ simple-audio-card,cpu { -+ sound-dai = <&spdif>; -+ }; -+ simple-audio-card,codec { -+ sound-dai = <&spdif_out>; -+ }; -+ }; -+ -+ spdif_out: spdif-out { -+ status = "disable"; -+ compatible = "linux,spdif-dit"; -+ #sound-dai-cells = <0>; -+ }; -+ -+ pwm_bl: backlight { -+ status = "disable"; -+ compatible = "pwm-backlight"; -+ pwms = <&pwm0 0 25000 0>; -+ brightness-levels = < -+ 0 1 2 3 4 5 6 7 -+ 8 9 10 11 12 13 14 15 -+ 16 17 18 19 20 21 22 23 -+ 24 25 26 27 28 29 30 31 -+ 32 33 34 35 36 37 38 39 -+ 40 41 42 43 44 45 46 47 -+ 48 49 50 51 52 53 54 55 -+ 56 57 58 59 60 61 62 63 -+ 64 65 66 67 68 69 70 71 -+ 72 73 74 75 76 77 78 79 -+ 80 81 82 83 84 85 86 87 -+ 88 89 90 91 92 93 94 95 -+ 96 97 98 99 100 101 102 103 -+ 104 105 106 107 108 109 110 111 -+ 112 113 114 115 116 117 118 119 -+ 120 121 122 123 124 125 126 127 -+ 128 129 130 131 132 133 134 135 -+ 136 137 138 139 140 141 142 143 -+ 144 145 146 147 148 149 150 151 -+ 152 153 154 155 156 157 158 159 -+ 160 161 162 163 164 165 166 167 -+ 168 169 170 171 172 173 174 175 -+ 176 177 178 179 180 181 182 183 -+ 184 185 186 187 188 189 190 191 -+ 192 193 194 195 196 197 198 199 -+ 200 201 202 203 204 205 206 207 -+ 208 209 210 211 212 213 214 215 -+ 216 217 218 219 220 221 222 223 -+ 224 225 226 227 228 229 230 231 -+ 232 233 234 235 236 237 238 239 -+ 240 241 242 243 244 245 246 247 -+ 248 249 250 251 252 253 254 255>; -+ default-brightness-level = <200>; -+ }; -+ -+ gpio-keys { -+ compatible = "gpio-keys"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ autorepeat; -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&power_key>; -+ -+ button@0 { -+ gpios = <&gpio0 5 GPIO_ACTIVE_LOW>; -+ linux,code = ; -+ label = "GPIO Key Power"; -+ linux,input-type = <1>; -+ gpio-key,wakeup = <1>; -+ debounce-interval = <100>; -+ }; -+ }; -+ -+ adc-keys { -+ compatible = "adc-keys"; -+ io-channels = <&saradc 1>; -+ io-channel-names = "buttons"; -+ poll-interval = <100>; -+ keyup-threshold-microvolt = <1800000>; -+ -+ button-up { -+ label = "Volume Up"; -+ linux,code = ; -+ press-threshold-microvolt = <100000>; -+ }; -+ -+ button-down { -+ label = "Volume Down"; -+ linux,code = ; -+ press-threshold-microvolt = <300000>; -+ }; -+ }; -+ -+ leds: gpio-leds { -+ compatible = "gpio-leds"; -+ pinctrl-names = "default"; -+ pinctrl-0 =<&leds_gpio>; -+ -+ led@1 { -+ gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>; -+ label = "status_led"; -+ linux,default-trigger = "heartbeat"; -+ linux,default-trigger-delay-ms = <0>; -+ }; -+ }; -+ -+ sdio_pwrseq: sdio-pwrseq { -+ compatible = "mmc-pwrseq-simple"; -+ clocks = <&rk808 1>; -+ clock-names = "ext_clock"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&wifi_enable_h>; -+ -+ /* -+ * On the module itself this is one of these (depending -+ * on the actual card populated): -+ * - SDIO_RESET_L_WL_REG_ON -+ * - PDN (power down when low) -+ */ -+ reset-gpios = <&gpio0 10 GPIO_ACTIVE_LOW>; /* GPIO0_B2 */ -+ }; -+}; -+ -+&cpu_l0 { -+ cpu-supply = <&vdd_cpu_l>; -+}; -+ -+&cpu_l1 { -+ cpu-supply = <&vdd_cpu_l>; -+}; -+ -+&cpu_l2 { -+ cpu-supply = <&vdd_cpu_l>; -+}; -+ -+&cpu_l3 { -+ cpu-supply = <&vdd_cpu_l>; -+}; -+ -+&cpu_b0 { -+ cpu-supply = <&vdd_cpu_b>; -+}; -+ -+&cpu_b1 { -+ cpu-supply = <&vdd_cpu_b>; -+}; -+ -+&gpu { -+ status = "okay"; -+ mali-supply = <&vdd_gpu>; -+}; -+ -+&gmac { -+ assigned-clocks = <&cru SCLK_RMII_SRC>; -+ assigned-clock-parents = <&clkin_gmac>; -+ clock_in_out = "input"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&rgmii_pins>; -+ phy-mode = "rgmii"; -+ phy-supply = <&vcc3v3_s3>; -+ snps,reset-active-low; -+ snps,reset-delays-us = <0 10000 50000>; -+ snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; -+ tx_delay = <0x28>; -+ rx_delay = <0x11>; -+ status = "okay"; -+}; -+ -+&spi1 { -+ status = "disable"; -+ pinctrl-names = "default", "sleep"; -+ pinctrl-1 = <&spi1_gpio>; -+ -+ spidev0: spidev@0 { -+ compatible = "rockchip,spidev"; -+ reg = <0>; -+ spi-max-frequency = <10000000>; -+ status = "okay"; -+ }; -+}; -+/* -+&spi1 { -+ status = "okay"; -+ max-freq = <48000000>; -+ spidev@00 { -+ compatible = "linux,spidev"; -+ reg = <0x00>; -+ spi-max-frequency = <48000000>; -+ }; -+}; -+*/ -+ -+&uart0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; -+ status = "okay"; -+ -+ bluetooth { -+ compatible = "brcm,bcm4345c5"; -+ clocks = <&rk808 1>; -+ clock-names = "lpo"; -+ device-wakeup-gpios = <&gpio2 RK_PD2 GPIO_ACTIVE_HIGH>; -+ host-wakeup-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>; -+ shutdown-gpios = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>; -+ max-speed = <1500000>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&bt_host_wake &bt_wake &bt_reset>; -+ }; -+ -+}; -+ -+&uart2 { -+ status = "okay"; -+}; -+ -+&vopb { -+ status = "okay"; -+}; -+ -+&vopb_mmu { -+ status = "okay"; -+}; -+ -+&vopl { -+ status = "okay"; -+}; -+ -+&vopl_mmu { -+ status = "okay"; -+}; -+ -+&vpu { -+ status = "okay"; -+ /* 0 means ion, 1 means drm */ -+ //allocator = <0>; -+}; -+ -+&rga { -+ status = "disabled"; -+}; -+ -+&cdn_dp { -+ status = "okay"; -+ extcon = <&fusb0>; -+ phys = <&tcphy0_dp>; -+}; -+ -+&hdmi { -+ /* remove the hdmi_i2c_xfer */ -+ pinctrl-0 = <&hdmi_cec>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ #sound-dai-cells = <0>; -+ status = "okay"; -+ ddc-i2c-bus = <&i2c7>; -+ rockchip,defaultmode = <16>; /* CEA 1920x1080@60Hz */ -+}; -+ -+&i2c0 { -+ clock-frequency = <400000>; -+ i2c-scl-rising-time-ns = <160>; -+ i2c-scl-falling-time-ns = <30>; -+ status = "okay"; -+ -+ rk808: pmic@1b { -+ compatible = "rockchip,rk808"; -+ reg = <0x1b>; -+ interrupt-parent = <&gpio1>; -+ interrupts = <21 IRQ_TYPE_LEVEL_LOW>; -+ #clock-cells = <1>; -+ clock-output-names = "xin32k", "rk808-clkout2"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pmic_int_l>; -+ rockchip,system-power-controller; -+ wakeup-source; -+ -+ vcc1-supply = <&vcc3v3_sys>; -+ vcc2-supply = <&vcc3v3_sys>; -+ vcc3-supply = <&vcc3v3_sys>; -+ vcc4-supply = <&vcc3v3_sys>; -+ vcc6-supply = <&vcc3v3_sys>; -+ vcc7-supply = <&vcc3v3_sys>; -+ vcc8-supply = <&vcc3v3_sys>; -+ vcc9-supply = <&vcc3v3_sys>; -+ vcc10-supply = <&vcc3v3_sys>; -+ vcc11-supply = <&vcc3v3_sys>; -+ vcc12-supply = <&vcc3v3_sys>; -+ vcc13-supply = <&vcc3v3_sys>; -+ vcc14-supply = <&vcc3v3_sys>; -+ vddio-supply = <&vcc_3v0>; -+ -+ regulators { -+ vdd_center: DCDC_REG1 { -+ regulator-name = "vdd_center"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <750000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-ramp-delay = <6001>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_cpu_l: DCDC_REG2 { -+ regulator-name = "vdd_cpu_l"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <750000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-ramp-delay = <6001>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_ddr: DCDC_REG3 { -+ regulator-name = "vcc_ddr"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vcc1v8: vcc1v8_s3: vcca1v8_s3: DCDC_REG4 { -+ regulator-name = "vcc1v8"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vcc1v8_dvp: LDO_REG1 { -+ regulator-name = "vcc1v8_dvp"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc3v0_touch: LDO_REG2 { -+ regulator-name = "vcc3v0_touch"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3000000>; -+ regulator-max-microvolt = <3000000>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc1v8_pmu: LDO_REG3 { -+ regulator-name = "vcc1v8_pmu"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vcc_sdio: LDO_REG4 { -+ regulator-name = "vcc_sdio"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3000000>; -+ regulator-init-microvolt = <3000000>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3000000>; -+ }; -+ }; -+ -+ vcca3v0_codec: LDO_REG5 { -+ regulator-name = "vcca3v0_codec"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3000000>; -+ regulator-max-microvolt = <3000000>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_1v5: LDO_REG6 { -+ regulator-name = "vcc_1v5"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1500000>; -+ regulator-max-microvolt = <1500000>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1500000>; -+ }; -+ }; -+ -+ vcca1v8_codec: LDO_REG7 { -+ regulator-name = "vcca1v8_codec"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_3v0: LDO_REG8 { -+ regulator-name = "vcc_3v0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3000000>; -+ regulator-max-microvolt = <3000000>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3000000>; -+ }; -+ }; -+ -+ vcc3v3_s3: vcc_lan: SWITCH_REG1 { -+ regulator-name = "vcc3v3_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc3v3_s0: SWITCH_REG2 { -+ regulator-name = "vcc3v3_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ }; -+ }; -+ -+ vdd_cpu_b: regulator@40 { -+ compatible = "silergy,syr827"; -+ reg = <0x40>; -+ fcs,suspend-voltage-selector = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vsel1_gpio>; -+ vsel-gpios = <&gpio1 RK_PC1 GPIO_ACTIVE_HIGH>; -+ regulator-compatible = "fan53555-reg"; -+ regulator-name = "vdd_cpu_b"; -+ regulator-min-microvolt = <712500>; -+ regulator-max-microvolt = <1500000>; -+ regulator-ramp-delay = <1000>; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&vcc3v3_sys>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_gpu: regulator@41 { -+ compatible = "silergy,syr828"; -+ reg = <0x41>; -+ fcs,suspend-voltage-selector = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vsel2_gpio>; -+ vsel-gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_HIGH>; -+ regulator-compatible = "fan53555-reg"; -+ regulator-name = "vdd_gpu"; -+ regulator-min-microvolt = <712500>; -+ regulator-max-microvolt = <1500000>; -+ regulator-ramp-delay = <1000>; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&vcc3v3_sys>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+}; -+ -+&i2c1 { -+ status = "okay"; -+ i2c-scl-rising-time-ns = <300>; -+ i2c-scl-falling-time-ns = <15>; -+ clock-frequency = <200000>; -+ -+ rt5651: rt5651@1a { -+ #sound-dai-cells = <0>; -+ compatible = "realtek,rt5651"; -+ reg = <0x1a>; -+ clocks = <&cru SCLK_I2S_8CH_OUT>; -+ clock-names = "mclk"; -+ status = "okay"; -+ }; -+}; -+ -+&i2c3 { -+ status = "okay"; -+}; -+ -+&i2c4 { -+ status = "okay"; -+ i2c-scl-rising-time-ns = <160>; -+ i2c-scl-falling-time-ns = <30>; -+ clock-frequency = <400000>; -+ -+ fusb0: fusb30x@22 { -+ compatible = "fcs,fusb302"; -+ reg = <0x22>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&fusb0_int>; -+ interrupt-parent = <&gpio1>; -+ interrupts = ; -+ vbus-supply = <&vbus_typec>; -+ status = "okay"; -+ -+ connector { -+ compatible = "usb-c-connector"; -+ data-role = "dual"; -+ label = "USB-C"; -+ op-sink-microwatt = <1000000>; -+ power-role = "dual"; -+ sink-pdos = -+ ; -+ source-pdos = -+ ; -+ try-power-role = "sink"; -+ -+ extcon-cables = <1 2 5 6 9 10 12 44>; -+ typec-altmodes = <0xff01 1 0x001c0000 1>; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ port@0 { -+ reg = <0>; -+ -+ usbc_hs: endpoint { -+ remote-endpoint = -+ <&u2phy0_typec_hs>; -+ }; -+ }; -+ -+ port@1 { -+ reg = <1>; -+ -+ usbc_ss: endpoint { -+ remote-endpoint = -+ <&tcphy0_typec_ss>; -+ }; -+ }; -+ -+ port@2 { -+ reg = <2>; -+ -+ usbc_dp: endpoint { -+ remote-endpoint = -+ <&tcphy0_typec_dp>; -+ }; -+ }; -+ }; -+ }; -+ -+ }; -+ -+ ft5x06_ts@38 { -+ compatible = "edt,edt-ft5x06", "ft5x06"; -+ reg = <0x38>; -+ interrupt-parent = <&gpio1>; -+ interrupts = <20 IRQ_TYPE_EDGE_FALLING>; -+ status = "okay"; -+ }; -+ -+ /* -+ onewire_ts@2f { -+ compatible = "onewire"; -+ reg = <0x2f>; -+ interrupt-parent = <&gpio1>; -+ interrupts = <20 IRQ_TYPE_EDGE_FALLING>; -+ }; */ -+}; -+ -+&i2c7 { -+ status = "okay"; -+}; -+ -+&spdif { -+ status = "disable"; -+ pinctrl-0 = <&spdif_bus>; -+ i2c-scl-rising-time-ns = <450>; -+ i2c-scl-falling-time-ns = <15>; -+ #sound-dai-cells = <0>; -+}; -+ -+&i2s1 { -+ assigned-clocks = <&cru SCLK_I2SOUT_SRC>; -+ assigned-clock-parents = <&cru SCLK_I2S1_8CH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s_8ch_mclk>,<&i2s1_2ch_bus>; -+ rockchip,playback-channels = <2>; -+ rockchip,capture-channels = <2>; -+ #sound-dai-cells = <0>; -+ status = "okay"; -+}; -+/* -+&i2s0 { -+ assigned-clocks = <&cru SCLK_I2S1_DIV>; -+ assigned-clock-parents = <&cru PLL_GPLL>; -+};*/ -+ -+&i2s2 { -+ #sound-dai-cells = <0>; -+ status = "okay"; -+}; -+ -+&io_domains { -+ status = "okay"; -+ -+ bt656-supply = <&vcc1v8_dvp>; /* bt656_gpio2ab_ms */ -+ audio-supply = <&vcca1v8_codec>; /* audio_gpio3d4a_ms */ -+ sdmmc-supply = <&vcc_sdio>; /* sdmmc_gpio4b_ms */ -+ gpio1830-supply = <&vcc_3v0>; /* gpio1833_gpio4cd_ms */ -+}; -+ -+&pmu_io_domains { -+ status = "okay"; -+ pmu1830-supply = <&vcc_3v0>; -+}; -+ -+&pcie_phy { -+ status = "okay"; -+ assigned-clocks = <&cru SCLK_PCIEPHY_REF>; -+ assigned-clock-parents = <&cru SCLK_PCIEPHY_REF100M>; -+ assigned-clock-rates = <100000000>; -+}; -+ -+&pcie0 { -+ status = "okay"; -+ ep-gpios = <&gpio2 4 GPIO_ACTIVE_HIGH>; -+ num-lanes = <4>; -+ max-link-speed = <1>; -+}; -+ -+&pwm_bl { -+ status = "okay"; -+}; -+ -+&pwm0 { -+ status = "okay"; -+}; -+ -+&pwm1 { -+ status = "okay"; -+}; -+ -+&pwm2 { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pwm2_pin_pull_down>; -+}; -+ -+&saradc { -+ status = "okay"; -+ vref-supply = <&vcca1v8_s3>; /* TBD */ -+}; -+ -+&sdhci { -+ bus-width = <8>; -+ mmc-hs400-1_8v; -+ supports-emmc; -+ non-removable; -+ keep-power-in-suspend; -+ mmc-hs400-enhanced-strobe; -+ status = "okay"; -+}; -+ -+&emmc_phy { -+ status = "okay"; -+}; -+ -+&sdio0 { -+ clock-frequency = <50000000>; -+ clock-freq-min-max = <200000 50000000>; -+ supports-sdio; -+ bus-width = <4>; -+ disable-wp; -+ cap-sd-highspeed; -+ cap-sdio-irq; -+ keep-power-in-suspend; -+ mmc-pwrseq = <&sdio_pwrseq>; -+ non-removable; -+ num-slots = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>; -+ sd-uhs-sdr104; -+ status = "okay"; -+}; -+ -+&sdmmc { -+ bus-width = <4>; -+ cap-sd-highspeed; -+ cap-mmc-highspeed; -+ cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; -+ disable-wp; -+ max-frequency = <150000000>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc0_det_l>; -+// sd-uhs-sdr104; -+ vmmc-supply = <&vcc3v0_sd>; -+ vqmmc-supply = <&vcc_sdio>; -+ status = "okay"; -+}; -+ -+&tsadc { -+ /* tshut mode 0:CRU 1:GPIO */ -+ rockchip,hw-tshut-mode = <1>; -+ /* tshut polarity 0:LOW 1:HIGH */ -+ rockchip,hw-tshut-polarity = <1>; -+ status = "okay"; -+}; -+ -+&tcphy0 { -+ extcon = <&fusb0>; -+ status = "okay"; -+}; -+ -+&tcphy0_dp { -+ port { -+ tcphy0_typec_dp: endpoint { -+ remote-endpoint = <&usbc_dp>; -+ }; -+ }; -+}; -+ -+&tcphy0_usb3 { -+ port { -+ tcphy0_typec_ss: endpoint { -+ remote-endpoint = <&usbc_ss>; -+ }; -+ }; -+}; -+ -+&tcphy1 { -+ status = "okay"; -+}; -+ -+&u2phy0 { -+ status = "okay"; -+ -+ u2phy0_otg: otg-port { -+ status = "okay"; -+ }; -+ -+ u2phy0_host: host-port { -+ phy-supply = <&usb3_vbus>; -+ status = "okay"; -+ }; -+ -+ port { -+ u2phy0_typec_hs: endpoint { -+ remote-endpoint = <&usbc_hs>; -+ }; -+ }; -+}; -+ -+&u2phy1 { -+ status = "okay"; -+ -+ u2phy1_otg: otg-port { -+ status = "okay"; -+ }; -+ -+ u2phy1_host: host-port { -+ phy-supply = <&usb_vbus>; -+ status = "okay"; -+ }; -+}; -+ -+&usbdrd3_0 { -+ status = "okay"; -+ extcon = <&fusb0>; -+}; -+ -+&usbdrd3_1 { -+ status = "okay"; -+}; -+ -+&usbdrd_dwc3_0 { -+ status = "okay"; -+}; -+ -+&usbdrd_dwc3_1 { -+ status = "okay"; -+ dr_mode = "host"; -+}; -+ -+&usb_host0_ehci { -+ status = "okay"; -+}; -+ -+&usb_host0_ohci { -+ status = "okay"; -+}; -+ -+&usb_host1_ehci { -+ status = "okay"; -+}; -+ -+&usb_host1_ohci { -+ status = "okay"; -+}; -+ -+&pinctrl { -+ pcie { -+ pcie_drv: pcie-drv { -+ rockchip,pins = -+ <1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ hdmi { -+ /delete-node/ hdmi-i2c-xfer; -+ }; -+ -+ i2s1 { -+ i2s_8ch_mclk: i2s-8ch-mclk { -+ rockchip,pins = <4 RK_PA0 1 &pcfg_pull_none>; -+ }; -+ }; -+ -+ pmic { -+ pmic_int_l: pmic-int-l { -+ rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ -+ vsel1_gpio: vsel1-gpio { -+ rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ -+ vsel2_gpio: vsel2-gpio { -+ rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ }; -+ -+ sdmmc { -+ sdmmc0_det_l: sdmmc0-det-l { -+ rockchip,pins = <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ -+ sdmmc0_pwr_h: sdmmc0-pwr-h { -+ rockchip,pins = <0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ -+ usb-typec { -+ vcc5v0_typec_en: vcc5v0_typec_en { -+ rockchip,pins = <2 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ -+ fusb30x { -+ fusb0_int: fusb0-int { -+ rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ -+ sdio-pwrseq { -+ wifi_enable_h: wifi-enable-h { -+ rockchip,pins = <0 10 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ wireless-bluetooth { -+ uart0_gpios: uart0-gpios { -+ rockchip,pins = <2 19 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ rockchip-key { -+ power_key: power-key { -+ rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ -+ headphone { -+ hp_det: hp-det { -+ rockchip,pins = <4 28 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ -+ gpio-leds { -+ leds_gpio: leds-gpio { -+ rockchip,pins = <0 11 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ cam_pins { -+ cif_clkout_a: cif-clkout-a { -+ rockchip,pins = <2 11 3 &pcfg_pull_none>; -+ }; -+ -+ cif_clkout_a_sleep: cif-clkout-a-sleep { -+ rockchip,pins = <2 11 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ cam0_default_pins: cam0-default-pins { -+ rockchip,pins = -+ <4 27 0 &pcfg_pull_down>, -+ <2 11 3 &pcfg_pull_none>; -+ }; -+ cam0_sleep_pins: cam0-sleep-pins { -+ rockchip,pins = -+ <4 27 3 &pcfg_pull_none>, -+ <2 11 0 &pcfg_pull_none>; -+ }; -+ -+ cam1_default_pins: cam1-default-pins { -+ rockchip,pins = -+ <0 12 RK_FUNC_GPIO &pcfg_pull_down>, -+ <0 8 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ spi1 { -+ spi1_gpio: spi1-gpio { -+ rockchip,pins = -+ <1 7 RK_FUNC_GPIO &pcfg_output_low>, -+ <1 8 RK_FUNC_GPIO &pcfg_output_low>, -+ <1 9 RK_FUNC_GPIO &pcfg_output_low>, -+ <1 10 RK_FUNC_GPIO &pcfg_output_low>; -+ }; -+ }; -+ -+ bt { -+ bt_host_wake: bt-host-wake { -+ rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ bt_reset: bt-reset { -+ rockchip,pins = <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ bt_wake: bt-wake { -+ rockchip,pins = <2 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+}; -+ -+&hdmi_in_vopb { -+ status = "okay"; -+}; -+ -+&hdmi_in_vopl { -+ status = "disable"; -+}; -+ -+&dp_in_vopb { -+ status = "disable"; -+}; -+&dp_in_vopl { -+ status = "okay"; -+}; -+ diff --git a/patch/kernel/archive/rockchip64-6.1/add-board-orangepi-r1-plus-lts.patch b/patch/kernel/archive/rockchip64-6.1/add-board-orangepi-r1-plus-lts.patch deleted file mode 100644 index 4d5ebc9d201a..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/add-board-orangepi-r1-plus-lts.patch +++ /dev/null @@ -1,466 +0,0 @@ -From c163dea909a2900a78ad8041de42b6509c8e3910 Mon Sep 17 00:00:00 2001 -From: schwar3kat -Date: Mon, 30 Jan 2023 18:48:33 +1300 -Subject: [PATCH] add-board-orangepi-r1-plus-lts.patch - -Signed-off-by: schwar3kat ---- - .../rockchip/rk3328-orangepi-r1-plus-lts.dts | 446 ++++++++++++++++++ - 1 file changed, 446 insertions(+) - create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts - -diff --git a/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts -new file mode 100644 -index 000000000..2bc432168 ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts -@@ -0,0 +1,446 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* Copyright (c) 2020 David Bauer -+ * Copyright (c) 2020 Shenzhen Xunlong Software CO.,Limited -+ * Copyright (c) 2021 AmadeusGhost -+ * Revised for Orange Pi R1 Plus LTS (c) 2022 schwar3kat -+ * Based on Orange Pi R1 plus -+ */ -+ -+/dts-v1/; -+ -+#include -+#include -+#include "rk3328.dtsi" -+ -+/ { -+ model = "Xunlong Orange Pi R1 Plus LTS"; -+ compatible = "xunlong,orangepi-r1-plus-lts", "rockchip,rk3328"; -+ -+ aliases { -+ ethernet1 = &rtl8153; -+ mmc0 = &sdmmc; -+ }; -+ -+ chosen { -+ stdout-path = "serial2:1500000n8"; -+ }; -+ -+ gmac_clk: gmac-clock { -+ compatible = "fixed-clock"; -+ clock-frequency = <125000000>; -+ clock-output-names = "gmac_clkin"; -+ #clock-cells = <0>; -+ }; -+ -+ keys { -+ compatible = "gpio-keys"; -+ pinctrl-0 = <&reset_button_pin>; -+ pinctrl-names = "default"; -+ -+ reset { -+ label = "reset"; -+ gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_LOW>; -+ linux,code = ; -+ debounce-interval = <50>; -+ }; -+ }; -+ -+ leds { -+ compatible = "gpio-leds"; -+ pinctrl-0 = <&lan_led_pin>, <&sys_led_pin>, <&wan_led_pin>; -+ pinctrl-names = "default"; -+ -+ lan_led: led-0 { -+ gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>; -+ label = "orangepi-r1-plus-lts:green:lan"; -+ }; -+ -+ sys_led: led-1 { -+ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; -+ label = "orangepi-r1-plus-lts:red:status"; -+ linux,default-trigger = "heartbeat"; -+ }; -+ -+ wan_led: led-2 { -+ gpios = <&gpio2 RK_PC2 GPIO_ACTIVE_HIGH>; -+ label = "orangepi-r1-plus-lts:green:wan"; -+ }; -+ }; -+ -+ vcc_io_sdio: sdmmcio-regulator { -+ compatible = "regulator-gpio"; -+ enable-active-high; -+ gpios = <&gpio1 RK_PD4 GPIO_ACTIVE_HIGH>; -+ pinctrl-0 = <&sdio_vcc_pin>; -+ pinctrl-names = "default"; -+ regulator-name = "vcc_io_sdio"; -+ regulator-always-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-settling-time-us = <5000>; -+ regulator-type = "voltage"; -+ startup-delay-us = <2000>; -+ states = <1800000 0x1>, -+ <3300000 0x0>; -+ vin-supply = <&vcc_io_33>; -+ }; -+ -+ vcc_sd: sdmmc-regulator { -+ compatible = "regulator-fixed"; -+ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>; -+ pinctrl-0 = <&sdmmc0m1_pin>; -+ pinctrl-names = "default"; -+ regulator-name = "vcc_sd"; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&vcc_io_33>; -+ }; -+ -+ vdd_5v: vdd-5v { -+ compatible = "regulator-fixed"; -+ regulator-name = "vdd_5v"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ }; -+ -+ vdd_5v_lan: vdd-5v-lan { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>; -+ pinctrl-0 = <&lan_vdd_pin>; -+ pinctrl-names = "default"; -+ regulator-name = "vdd_5v_lan"; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&vdd_5v>; -+ }; -+}; -+ -+&cpu0 { -+ cpu-supply = <&vdd_arm>; -+}; -+ -+&cpu1 { -+ cpu-supply = <&vdd_arm>; -+}; -+ -+&cpu2 { -+ cpu-supply = <&vdd_arm>; -+}; -+ -+&cpu3 { -+ cpu-supply = <&vdd_arm>; -+}; -+ -+&display_subsystem { -+ status = "disabled"; -+}; -+ -+&gmac2io { -+ assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; -+ assigned-clock-parents = <&gmac_clk>, <&gmac_clk>; -+ clock_in_out = "input"; -+ phy-mode = "rgmii"; -+ phy-supply = <&vcc_io_33>; -+ pinctrl-0 = <&rgmiim1_pins>; -+ pinctrl-names = "default"; -+ snps,aal; -+ status = "okay"; -+ phy-handle = <&yt8531c>; -+ tx_delay = <0x19>; -+ rx_delay = <0x05>; -+ -+ mdio { -+ compatible = "snps,dwmac-mdio"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ yt8531c: ethernet-phy@0 { -+ compatible = "ethernet-phy-id4f51.e91b", -+ "ethernet-phy-ieee802.3-c22"; -+ reg = <0>; -+ pinctrl-0 = <ð_phy_reset_pin>; -+ pinctrl-names = "default"; -+ reset-assert-us = <15000>; -+ reset-deassert-us = <50000>; -+ reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; -+ }; -+ }; -+}; -+ -+&i2c1 { -+ status = "okay"; -+ -+ rk805: pmic@18 { -+ compatible = "rockchip,rk805"; -+ reg = <0x18>; -+ interrupt-parent = <&gpio1>; -+ interrupts = <24 IRQ_TYPE_LEVEL_LOW>; -+ #clock-cells = <1>; -+ clock-output-names = "xin32k", "rk805-clkout2"; -+ gpio-controller; -+ #gpio-cells = <2>; -+ pinctrl-0 = <&pmic_int_l>; -+ pinctrl-names = "default"; -+ rockchip,system-power-controller; -+ wakeup-source; -+ -+ vcc1-supply = <&vdd_5v>; -+ vcc2-supply = <&vdd_5v>; -+ vcc3-supply = <&vdd_5v>; -+ vcc4-supply = <&vdd_5v>; -+ vcc5-supply = <&vcc_io_33>; -+ vcc6-supply = <&vdd_5v>; -+ -+ regulators { -+ vdd_log: DCDC_REG1 { -+ regulator-name = "vdd_log"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <712500>; -+ regulator-max-microvolt = <1450000>; -+ regulator-ramp-delay = <12500>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1000000>; -+ }; -+ }; -+ -+ vdd_arm: DCDC_REG2 { -+ regulator-name = "vdd_arm"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <712500>; -+ regulator-max-microvolt = <1450000>; -+ regulator-ramp-delay = <12500>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <950000>; -+ }; -+ }; -+ -+ vcc_ddr: DCDC_REG3 { -+ regulator-name = "vcc_ddr"; -+ regulator-always-on; -+ regulator-boot-on; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vcc_io_33: DCDC_REG4 { -+ regulator-name = "vcc_io_33"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3300000>; -+ }; -+ }; -+ -+ vcc_18: LDO_REG1 { -+ regulator-name = "vcc_18"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vcc18_emmc: LDO_REG2 { -+ regulator-name = "vcc18_emmc"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vdd_10: LDO_REG3 { -+ regulator-name = "vdd_10"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1000000>; -+ regulator-max-microvolt = <1000000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1000000>; -+ }; -+ }; -+ }; -+ }; -+}; -+ -+&io_domains { -+ pmuio-supply = <&vcc_io_33>; -+ vccio1-supply = <&vcc_io_33>; -+ vccio2-supply = <&vcc18_emmc>; -+ vccio3-supply = <&vcc_io_sdio>; -+ vccio4-supply = <&vcc_18>; -+ vccio5-supply = <&vcc_io_33>; -+ vccio6-supply = <&vcc_io_33>; -+ status = "okay"; -+}; -+ -+&pinctrl { -+ button { -+ reset_button_pin: reset-button-pin { -+ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ gmac2io { -+ eth_phy_reset_pin: eth-phy-reset-pin { -+ rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ }; -+ -+ leds { -+ lan_led_pin: lan-led-pin { -+ rockchip,pins = <2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ sys_led_pin: sys-led-pin { -+ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ wan_led_pin: wan-led-pin { -+ rockchip,pins = <2 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ lan { -+ lan_vdd_pin: lan-vdd-pin { -+ rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ pmic { -+ pmic_int_l: pmic-int-l { -+ rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ -+ sd { -+ sdio_vcc_pin: sdio-vcc-pin { -+ rockchip,pins = <1 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+}; -+ -+&pwm2 { -+ status = "okay"; -+}; -+ -+&sdmmc { -+ bus-width = <4>; -+ cap-sd-highspeed; -+ disable-wp; -+ pinctrl-0 = <&sdmmc0_clk>, <&sdmmc0_cmd>, <&sdmmc0_dectn>, <&sdmmc0_bus4>; -+ pinctrl-names = "default"; -+ sd-uhs-sdr12; -+ sd-uhs-sdr25; -+ sd-uhs-sdr50; -+ sd-uhs-sdr104; -+ vmmc-supply = <&vcc_sd>; -+ vqmmc-supply = <&vcc_io_sdio>; -+ status = "okay"; -+}; -+ -+&tsadc { -+ rockchip,hw-tshut-mode = <0>; -+ rockchip,hw-tshut-polarity = <0>; -+ status = "okay"; -+}; -+ -+&u2phy { -+ status = "okay"; -+}; -+ -+&u2phy_host { -+ status = "okay"; -+}; -+ -+&u2phy_otg { -+ status = "okay"; -+}; -+ -+&uart2 { -+ status = "okay"; -+}; -+ -+&usb20_otg { -+ status = "okay"; -+ dr_mode = "host"; -+}; -+ -+&usbdrd3 { -+ dr_mode = "host"; -+ status = "okay"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ snps,xhci-trb-ent-quirk; -+ -+ /* Second port is for USB 3.0 */ -+ rtl8153: device@2 { -+ compatible = "usbbda,8153"; -+ reg = <2>; -+ realtek,led-data = <0x87>; -+ }; -+}; -+ -+&usb_host0_ehci { -+ status = "okay"; -+}; -+ -+&usb_host0_ohci { -+ status = "okay"; -+}; -+ -+&spi0 { -+ max-freq = <48000000>; -+ status = "okay"; -+ -+ flash@0 { -+ compatible = "jedec,spi-nor"; -+ reg = <0>; -+ spi-max-frequency = <10000000>; -+ }; -+}; -+ -+&uart1 { -+ status = "okay"; -+}; -+ -+&dmc_opp_table { -+ opp-798000000 { -+ status = "disabled"; -+ }; -+ opp-840000000 { -+ status = "disabled"; -+ }; -+ opp-924000000 { -+ status = "disabled"; -+ }; -+ opp-1056000000 { -+ status = "disabled"; -+ }; -+}; --- -Created with Armbian build tools https://github.com/armbian/build - diff --git a/patch/kernel/archive/rockchip64-6.1/add-board-orangepi-r1-plus.patch b/patch/kernel/archive/rockchip64-6.1/add-board-orangepi-r1-plus.patch deleted file mode 100644 index 4a0ce3715c4f..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/add-board-orangepi-r1-plus.patch +++ /dev/null @@ -1,416 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dts b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dts -new file mode 100644 -index 000000000..2ee07d15a ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dts -@@ -0,0 +1,410 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+ -+/dts-v1/; -+ -+#include -+#include -+#include "rk3328-dram-default-timing.dtsi" -+#include "rk3328.dtsi" -+ -+/ { -+ model = "Xunlong Orange Pi R1 Plus"; -+ compatible = "xunlong,orangepi-r1-plus", "rockchip,rk3328"; -+ -+ aliases { -+ ethernet1 = &rtl8153; -+ mmc0 = &sdmmc; -+ }; -+ -+ chosen { -+ stdout-path = "serial2:1500000n8"; -+ }; -+ -+ gmac_clk: gmac-clock { -+ compatible = "fixed-clock"; -+ clock-frequency = <125000000>; -+ clock-output-names = "gmac_clkin"; -+ #clock-cells = <0>; -+ }; -+ -+ leds { -+ compatible = "gpio-leds"; -+ pinctrl-0 = <&lan_led_pin>, <&sys_led_pin>, <&wan_led_pin>; -+ pinctrl-names = "default"; -+ -+ lan_led: led-0 { -+ gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>; -+ label = "orangepi-r1-plus:green:lan"; -+ }; -+ -+ sys_led: led-1 { -+ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; -+ label = "orangepi-r1-plus:red:status"; -+ linux,default-trigger = "heartbeat"; -+ }; -+ -+ wan_led: led-2 { -+ gpios = <&gpio2 RK_PC2 GPIO_ACTIVE_HIGH>; -+ label = "orangepi-r1-plus:green:wan"; -+ }; -+ }; -+ -+ vcc_sd: sdmmc-regulator { -+ compatible = "regulator-fixed"; -+ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>; -+ pinctrl-0 = <&sdmmc0m1_pin>; -+ pinctrl-names = "default"; -+ regulator-name = "vcc_sd"; -+ regulator-boot-on; -+ vin-supply = <&vcc_io_33>; -+ }; -+ -+ vdd_5v: vdd-5v { -+ compatible = "regulator-fixed"; -+ regulator-name = "vdd_5v"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ }; -+ -+ vdd_5v_lan: vdd-5v-lan { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>; -+ pinctrl-0 = <&lan_vdd_pin>; -+ pinctrl-names = "default"; -+ regulator-name = "vdd_5v_lan"; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&vdd_5v>; -+ }; -+ -+ /delete-node/ dmc-opp-table; -+ -+ dmc_opp_table: dmc_opp_table { -+ compatible = "operating-points-v2"; -+ -+ opp-786000000 { -+ opp-hz = /bits/ 64 <786000000>; -+ opp-microvolt = <1075000 1075000 1200000>; -+ }; -+ opp-798000000 { -+ opp-hz = /bits/ 64 <798000000>; -+ opp-microvolt = <1075000 1075000 1200000>; -+ }; -+ opp-840000000 { -+ opp-hz = /bits/ 64 <840000000>; -+ opp-microvolt = <1075000 1075000 1200000>; -+ }; -+ opp-924000000 { -+ opp-hz = /bits/ 64 <924000000>; -+ opp-microvolt = <1100000 1100000 1200000>; -+ }; -+ opp-1056000000 { -+ opp-hz = /bits/ 64 <1056000000>; -+ opp-microvolt = <1175000 1175000 1200000>; -+ }; -+ }; -+}; -+ -+&cpu0 { -+ cpu-supply = <&vdd_arm>; -+}; -+ -+&cpu1 { -+ cpu-supply = <&vdd_arm>; -+}; -+ -+&cpu2 { -+ cpu-supply = <&vdd_arm>; -+}; -+ -+&cpu3 { -+ cpu-supply = <&vdd_arm>; -+}; -+ -+&dfi { -+ status = "okay"; -+}; -+ -+&dmc { -+ center-supply = <&vdd_log>; -+ ddr_timing = <&ddr_timing>; -+ status = "okay"; -+}; -+ -+&display_subsystem { -+ status = "disabled"; -+}; -+ -+&gmac2io { -+ assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; -+ assigned-clock-parents = <&gmac_clk>, <&gmac_clk>; -+ clock_in_out = "input"; -+ phy-handle = <&rtl8211e>; -+ phy-mode = "rgmii"; -+ phy-supply = <&vcc_io_33>; -+ pinctrl-0 = <&rgmiim1_pins>; -+ pinctrl-names = "default"; -+ snps,aal; -+ rx_delay = <0x18>; -+ tx_delay = <0x24>; -+ status = "okay"; -+ -+ mdio { -+ compatible = "snps,dwmac-mdio"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ rtl8211e: ethernet-phy@1 { -+ reg = <1>; -+ pinctrl-0 = <ð_phy_reset_pin>; -+ pinctrl-names = "default"; -+ reset-assert-us = <10000>; -+ reset-deassert-us = <50000>; -+ reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; -+ }; -+ }; -+}; -+ -+&i2c0 { -+ status = "okay"; -+}; -+ -+&i2c1 { -+ status = "okay"; -+ -+ rk805: pmic@18 { -+ compatible = "rockchip,rk805"; -+ reg = <0x18>; -+ interrupt-parent = <&gpio1>; -+ interrupts = <24 IRQ_TYPE_LEVEL_LOW>; -+ #clock-cells = <1>; -+ clock-output-names = "xin32k", "rk805-clkout2"; -+ gpio-controller; -+ #gpio-cells = <2>; -+ pinctrl-0 = <&pmic_int_l>; -+ pinctrl-names = "default"; -+ rockchip,system-power-controller; -+ wakeup-source; -+ -+ vcc1-supply = <&vdd_5v>; -+ vcc2-supply = <&vdd_5v>; -+ vcc3-supply = <&vdd_5v>; -+ vcc4-supply = <&vdd_5v>; -+ vcc5-supply = <&vcc_io_33>; -+ vcc6-supply = <&vdd_5v>; -+ -+ regulators { -+ vdd_log: DCDC_REG1 { -+ regulator-name = "vdd_log"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-init-microvolt = <1075000>; -+ regulator-min-microvolt = <712500>; -+ regulator-max-microvolt = <1450000>; -+ regulator-ramp-delay = <12500>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1000000>; -+ }; -+ }; -+ -+ vdd_arm: DCDC_REG2 { -+ regulator-name = "vdd_arm"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-init-microvolt = <1225000>; -+ regulator-min-microvolt = <712500>; -+ regulator-max-microvolt = <1450000>; -+ regulator-ramp-delay = <12500>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <950000>; -+ }; -+ }; -+ -+ vcc_ddr: DCDC_REG3 { -+ regulator-name = "vcc_ddr"; -+ regulator-always-on; -+ regulator-boot-on; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vcc_io_33: DCDC_REG4 { -+ regulator-name = "vcc_io_33"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3300000>; -+ }; -+ }; -+ -+ vcc_18: LDO_REG1 { -+ regulator-name = "vcc_18"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vcc18_emmc: LDO_REG2 { -+ regulator-name = "vcc18_emmc"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vdd_10: LDO_REG3 { -+ regulator-name = "vdd_10"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1000000>; -+ regulator-max-microvolt = <1000000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1000000>; -+ }; -+ }; -+ }; -+ }; -+}; -+ -+&io_domains { -+ pmuio-supply = <&vcc_io_33>; -+ vccio1-supply = <&vcc_io_33>; -+ vccio2-supply = <&vcc18_emmc>; -+ vccio3-supply = <&vcc_io_33>; -+ vccio4-supply = <&vcc_io_33>; -+ vccio5-supply = <&vcc_io_33>; -+ vccio6-supply = <&vcc_io_33>; -+ status = "okay"; -+}; -+ -+&pinctrl { -+ gmac2io { -+ eth_phy_reset_pin: eth-phy-reset-pin { -+ rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ }; -+ -+ leds { -+ lan_led_pin: lan-led-pin { -+ rockchip,pins = <2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ sys_led_pin: sys-led-pin { -+ rockchip,pins = <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ wan_led_pin: wan-led-pin { -+ rockchip,pins = <2 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ lan { -+ lan_vdd_pin: lan-vdd-pin { -+ rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ pmic { -+ pmic_int_l: pmic-int-l { -+ rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+}; -+ -+&pwm2 { -+ status = "okay"; -+}; -+ -+&sdmmc { -+ bus-width = <4>; -+ cap-sd-highspeed; -+ disable-wp; -+ pinctrl-0 = <&sdmmc0_clk>, <&sdmmc0_cmd>, <&sdmmc0_dectn>, <&sdmmc0_bus4>; -+ pinctrl-names = "default"; -+ vmmc-supply = <&vcc_sd>; -+ status = "okay"; -+}; -+ -+&spi0 { -+ status = "okay"; -+ -+ flash@0 { -+ compatible = "jedec,spi-nor"; -+ reg = <0>; -+ spi-max-frequency = <50000000>; -+ }; -+}; -+ -+&tsadc { -+ rockchip,hw-tshut-mode = <0>; -+ rockchip,hw-tshut-polarity = <0>; -+ status = "okay"; -+}; -+ -+&u2phy { -+ status = "okay"; -+}; -+ -+&u2phy_host { -+ status = "okay"; -+}; -+ -+&u2phy_otg { -+ status = "okay"; -+}; -+ -+&uart2 { -+ status = "okay"; -+}; -+ -+&usb20_otg { -+ status = "okay"; -+ dr_mode = "host"; -+}; -+ -+&usbdrd3 { -+ dr_mode = "host"; -+ status = "okay"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ rtl8153: device@2 { -+ compatible = "usbbda,8153"; -+ reg = <2>; -+ realtek,led-data = <0x87>; -+ }; -+}; -+ -+&usb_host0_ehci { -+ status = "okay"; -+}; -+ -+&usb_host0_ohci { -+ status = "okay"; -+}; diff --git a/patch/kernel/archive/rockchip64-6.1/add-board-panther-x2.patch b/patch/kernel/archive/rockchip64-6.1/add-board-panther-x2.patch deleted file mode 100644 index 4f3c7baab474..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/add-board-panther-x2.patch +++ /dev/null @@ -1,597 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile -index 8c15593c0..4c4e0ca32 100644 ---- a/arch/arm64/boot/dts/rockchip/Makefile -+++ b/arch/arm64/boot/dts/rockchip/Makefile -@@ -63,6 +63,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire-excavator.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399pro-rock-pi-n10.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-anbernic-rg353p.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-anbernic-rg503.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-panther-x2.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-pinenote-v1.1.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-pinenote-v1.2.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-a.dtb -diff --git a/arch/arm64/boot/dts/rockchip/rk3566-panther-x2.dts b/arch/arm64/boot/dts/rockchip/rk3566-panther-x2.dts -new file mode 100755 -index 000000000..02ba4c624 ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3566-panther-x2.dts -@@ -0,0 +1,579 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Copyright (c) 2023 tdleiyao -+ */ -+ -+/dts-v1/; -+ -+#include -+#include -+#include -+#include "rk3566.dtsi" -+ -+/ { -+ model = "Panther X2"; -+ compatible = "panther,x2", "rockchip,rk3566"; -+ -+ aliases { -+ ethernet0 = &gmac1; -+ mmc0 = &sdmmc0; -+ mmc1 = &sdhci; -+ mmc2 = &sdmmc1; -+ }; -+ -+ chosen: chosen { -+ stdout-path = "serial2:1500000n8"; -+ }; -+ -+ gmac1_clkin: external-gmac1-clock { -+ compatible = "fixed-clock"; -+ clock-frequency = <125000000>; -+ clock-output-names = "gmac1_clkin"; -+ #clock-cells = <0>; -+ }; -+ -+ leds { -+ compatible = "gpio-leds"; -+ //Corresponds to the actual order -+ led_pwr: led-pwr { -+ label = "led-pwr"; -+ default-state = "on"; -+ gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&led_pwr_enable_h>; -+ retain-state-suspended; -+ status = "okay"; -+ }; -+ -+ led_wifi: led-wifi { -+ label = "led-wifi"; -+ default-state = "off"; -+ gpios = <&gpio0 RK_PD6 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&led_wifi_enable_h>; -+ retain-state-suspended; -+ status = "okay"; -+ }; -+ -+ led_eth: led-eth { -+ label = "led-eth"; -+ default-state = "off"; -+ gpios = <&gpio0 RK_PD5 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&led_eth_enable_h>; -+ retain-state-suspended; -+ status = "okay"; -+ }; -+ -+ led_status: led-status { -+ label = "led-status"; -+ default-state = "on"; -+ gpios = <&gpio0 RK_PD3 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "heartbeat"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&led_status_enable_h>; -+ retain-state-suspended; -+ status = "okay"; -+ }; -+ }; -+ -+ vbus: vbus-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vbus"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ }; -+ -+ vcc5v0_sys: vcc5v0-sys-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v0_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vbus>; -+ }; -+ -+ vcc3v3_sys: vcc3v3-sys-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc3v3_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ sdio_pwrseq: sdio-pwrseq { -+ status = "okay"; -+ compatible = "mmc-pwrseq-simple"; -+ clocks = <&rk809 1>; -+ clock-names = "ext_clock"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&wifi_enable_h>; -+ reset-gpios = <&gpio2 RK_PB1 GPIO_ACTIVE_LOW>; -+ post-power-on-delay-ms = <100>; -+ }; -+ -+ wireless_wlan: wireless-wlan { -+ compatible = "wlan-platdata"; -+ rockchip,grf = <&grf>; -+ wifi_chip_type = "ap6236"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&wifi_host_wake_irq>; -+ WIFI,host_wake_irq = <&gpio2 RK_PB2 GPIO_ACTIVE_HIGH>; -+ status = "okay"; -+ }; -+ -+}; -+ -+&cpu0 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu1 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu2 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu3 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&gpu { -+ mali-supply = <&vdd_gpu>; -+ status = "okay"; -+}; -+ -+&gmac1 { -+ assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru SCLK_GMAC1>; -+ assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru SCLK_GMAC1>, <&gmac1_clkin>; -+ clock_in_out = "input"; -+ phy-supply = <&vcc_3v3>; -+ phy-mode = "rgmii"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&gmac1m0_miim -+ &gmac1m0_tx_bus2 -+ &gmac1m0_rx_bus2 -+ &gmac1m0_rgmii_clk -+ &gmac1m0_clkinout -+ &gmac1m0_rgmii_bus>; -+ snps,reset-gpio = <&gpio3 RK_PA1 GPIO_ACTIVE_LOW>; -+ snps,reset-active-low; -+ /* Reset time is 20ms, 100ms for rtl8211f, also works well here */ -+ snps,reset-delays-us = <0 20000 100000>; -+ tx_delay = <0x30>; -+ rx_delay = <0x10>; -+ phy-handle = <&rgmii_phy1>; -+ status = "okay"; -+}; -+&mdio1 { -+ rgmii_phy1: ethernet-phy@0 { -+ compatible = "ethernet-phy-ieee802.3-c22"; -+ reg = <0>; -+ status = "okay"; -+ }; -+}; -+ -+&i2c0 { -+ status = "okay"; -+ -+ vdd_cpu: regulator@1c { -+ compatible = "tcs,tcs4525"; -+ reg = <0x1c>; -+ fcs,suspend-voltage-selector = <1>; -+ regulator-name = "vdd_cpu"; -+ regulator-min-microvolt = <800000>; -+ regulator-max-microvolt = <1150000>; -+ regulator-ramp-delay = <2300>; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&vcc5v0_sys>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ rk809: pmic@20 { -+ compatible = "rockchip,rk809"; -+ reg = <0x20>; -+ interrupt-parent = <&gpio0>; -+ interrupts = ; -+ #clock-cells = <1>; -+ clock-output-names = "rk808-clkout1", "rk808-clkout2"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pmic_int_l>; -+ rockchip,system-power-controller; -+ wakeup-source; -+ -+ vcc1-supply = <&vcc3v3_sys>; -+ vcc2-supply = <&vcc3v3_sys>; -+ vcc3-supply = <&vcc3v3_sys>; -+ vcc4-supply = <&vcc3v3_sys>; -+ vcc5-supply = <&vcc3v3_sys>; -+ vcc6-supply = <&vcc3v3_sys>; -+ vcc7-supply = <&vcc3v3_sys>; -+ vcc8-supply = <&vcc3v3_sys>; -+ vcc9-supply = <&vcc3v3_sys>; -+ -+ regulators { -+ vdd_logic: DCDC_REG1 { -+ regulator-name = "vdd_logic"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <500000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-init-microvolt = <900000>; -+ regulator-ramp-delay = <6001>; -+ regulator-initial-mode = <0x2>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <900000>; -+ }; -+ }; -+ -+ vdd_gpu: DCDC_REG2 { -+ regulator-name = "vdd_gpu"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <500000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-init-microvolt = <900000>; -+ regulator-ramp-delay = <6001>; -+ regulator-initial-mode = <0x2>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_ddr: DCDC_REG3 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-initial-mode = <0x2>; -+ regulator-name = "vcc_ddr"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vdd_npu: DCDC_REG4 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <500000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-init-microvolt = <900000>; -+ regulator-initial-mode = <0x2>; -+ regulator-name = "vdd_npu"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_1v8: DCDC_REG5 { -+ regulator-name = "vcc_1v8"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vdda0v9_image: LDO_REG1 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ regulator-name = "vdda0v9_image"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <900000>; -+ }; -+ }; -+ -+ vdda_0v9: LDO_REG2 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ regulator-name = "vdda_0v9"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdda0v9_pmu: LDO_REG3 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ regulator-name = "vdda0v9_pmu"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <900000>; -+ }; -+ }; -+ -+ vccio_acodec: LDO_REG4 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-name = "vccio_acodec"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vccio_sd: LDO_REG5 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-name = "vccio_sd"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc3v3_pmu: LDO_REG6 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-name = "vcc3v3_pmu"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3300000>; -+ }; -+ }; -+ -+ vcca_1v8: LDO_REG7 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-name = "vcca_1v8"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcca1v8_pmu: LDO_REG8 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-name = "vcca1v8_pmu"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcca1v8_image: LDO_REG9 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-name = "vcca1v8_image"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_3v3: SWITCH_REG1 { -+ regulator-name = "vcc_3v3"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc3v3_sd: SWITCH_REG2 { -+ regulator-name = "vcc3v3_sd"; -+ status = "disabled"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ }; -+ }; -+}; -+ -+&i2s1_8ch { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s1m1_sclktx &i2s1m1_sclkrx -+ &i2s1m1_lrcktx &i2s1m1_lrckrx -+ &i2s1m1_sdi0 &i2s1m1_sdi1 -+ &i2s1m1_sdi2 &i2s1m1_sdi3 -+ &i2s1m1_sdo0 &i2s1m1_sdo1 -+ &i2s1m1_sdo2 &i2s1m1_sdo3>; -+ status = "disabled"; -+}; -+ -+&pinctrl { -+ sdio-pwrseq { -+ wifi_enable_h: wifi-enable-h { -+ rockchip,pins = <2 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ wireless-wlan { -+ wifi_host_wake_irq: wifi-host-wake-irq { -+ rockchip,pins = <2 RK_PB2 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ }; -+ -+ bt { -+ bt_enable_h: bt-enable-h { -+ rockchip,pins = <2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ bt_host_wake_l: bt-host-wake-l { -+ rockchip,pins = <2 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ bt_wake_l: bt-wake-l { -+ rockchip,pins = <2 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ leds { -+ led_pwr_enable_h: led-pwr-enable-h { -+ rockchip,pins = <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ led_wifi_enable_h: led-wifi-enable-h { -+ rockchip,pins = <0 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ led_eth_enable_h: led-eth-enable-h { -+ rockchip,pins = <0 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ led_status_enable_h: led-status-enable-h { -+ rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ pmic { -+ pmic_int_l: pmic-int-l { -+ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ -+}; -+ -+&pmu_io_domains { -+ pmuio1-supply = <&vcc3v3_pmu>; -+ pmuio2-supply = <&vcc3v3_pmu>; -+ vccio1-supply = <&vcc_3v3>; -+ vccio2-supply = <&vcc_1v8>; -+ vccio3-supply = <&vccio_sd>; -+ vccio4-supply = <&vcc_1v8>; -+ vccio5-supply = <&vcc_3v3>; -+ vccio6-supply = <&vcc_3v3>; -+ vccio7-supply = <&vcc_3v3>; -+ status = "okay"; -+}; -+ -+&saradc { -+ vref-supply = <&vcca_1v8>; -+ status = "okay"; -+}; -+ -+&sdhci { -+ bus-width = <8>; -+ mmc-hs200-1_8v; -+ non-removable; -+ vmmc-supply = <&vcc_3v3>; -+ vqmmc-supply = <&vcc_1v8>; -+ status = "okay"; -+}; -+ -+&sdmmc0 { -+ broken-cd; -+ bus-width = <4>; -+ cap-sd-highspeed; -+ disable-wp; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>; -+ vqmmc-supply = <&vccio_sd>; -+ status = "okay"; -+}; -+ -+&sdmmc1 { -+ supports-sdio; -+ bus-width = <4>; -+ disable-wp; -+ cap-sd-highspeed; -+ cap-sdio-irq; -+ keep-power-in-suspend; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_cmd &sdmmc1_clk>; -+ non-removable; -+ mmc-pwrseq = <&sdio_pwrseq>; -+ status = "okay"; -+ -+}; -+ -+&tsadc { -+ status = "okay"; -+}; -+ -+&uart1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart1m0_xfer &uart1m0_ctsn &uart1m0_rtsn>; -+ status = "okay"; -+ -+ bluetooth { -+ compatible = "brcm,bcm43438-bt"; -+ clocks = <&rk809 1>; -+ clock-names = "lpo"; -+ device-wakeup-gpios = <&gpio2 RK_PC1 GPIO_ACTIVE_HIGH>; -+ host-wakeup-gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>; -+ shutdown-gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>; -+ max-speed = <1500000>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&bt_host_wake_l &bt_wake_l &bt_enable_h>; -+ vbat-supply = <&vcc3v3_sys>; -+ vddio-supply = <&vcca1v8_pmu>; -+ }; -+}; -+ -+&uart2 { -+ status = "okay"; -+}; -+ -+&usb_host0_xhci { -+ dr_mode = "host"; -+ status = "okay"; -+}; -+ -+&usb_host0_ohci { -+ status = "okay"; -+}; -+ -+&usb_host1_ehci { -+ status = "okay"; -+}; -+ -+&usb2phy0 { -+ status = "okay"; -+}; -+ -+&usb2phy0_host { -+ status = "okay"; -+}; -+ -+&usb2phy0_otg { -+ status = "okay"; -+}; diff --git a/patch/kernel/archive/rockchip64-6.1/add-board-radxa-e25.patch b/patch/kernel/archive/rockchip64-6.1/add-board-radxa-e25.patch deleted file mode 100644 index 04473a90b092..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/add-board-radxa-e25.patch +++ /dev/null @@ -1,680 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile ---- a/arch/arm64/boot/dts/rockchip/Makefile (revision 4c1c8a78a1bfc84404d088c5a34dd3625f6b3f40) -+++ b/arch/arm64/boot/dts/rockchip/Makefile (revision a45c446e458e82465be126710c57677c6237d914) -@@ -92,6 +92,7 @@ - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-soquartz-cm4.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-bpi-r2-pro.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-v10.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-radxa-e25.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-rock-3a.dtb - - subdir-y := $(dts-dirs) overlay -diff --git a/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi b/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi -new file mode 100644 ---- /dev/null (revision a45c446e458e82465be126710c57677c6237d914) -+++ b/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi (revision a45c446e458e82465be126710c57677c6237d914) -@@ -0,0 +1,429 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+ -+#include -+#include -+#include -+#include "rk3568.dtsi" -+ -+/ { -+ compatible = "radxa,cm3i", "rockchip,rk3568"; -+ -+ aliases { -+ mmc0 = &sdhci; -+ }; -+ -+ chosen { -+ stdout-path = "serial2:115200n8"; -+ }; -+ -+ gpio-leds { -+ compatible = "gpio-leds"; -+ -+ led_user: led-0 { -+ gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>; -+ function = LED_FUNCTION_HEARTBEAT; -+ color = ; -+ linux,default-trigger = "heartbeat"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&led_user_en>; -+ }; -+ }; -+ -+ pcie30_avdd0v9: pcie30-avdd0v9-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "pcie30_avdd0v9"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ vin-supply = <&vcc3v3_sys>; -+ }; -+ -+ pcie30_avdd1v8: pcie30-avdd1v8-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "pcie30_avdd1v8"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ vin-supply = <&vcc3v3_sys>; -+ }; -+ -+ vcc3v3_sys: vcc3v3-sys-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc3v3_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&vcc5v_input>; -+ }; -+ -+ vcc5v0_sys: vcc5v0-sys-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v0_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc5v_input>; -+ }; -+ -+ /* labeled +5v_input in schematic */ -+ vcc5v_input: vcc5v-input-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v_input"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ }; -+}; -+ -+&combphy0 { -+ status = "okay"; -+}; -+ -+&combphy1 { -+ status = "okay"; -+}; -+ -+&combphy2 { -+ status = "okay"; -+}; -+ -+&cpu0 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu1 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu2 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu3 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&display_subsystem { -+ status = "disabled"; -+}; -+ -+&gpu { -+ mali-supply = <&vdd_gpu>; -+ status = "okay"; -+}; -+ -+&i2c0 { -+ status = "okay"; -+ -+ vdd_cpu: regulator@1c { -+ compatible = "tcs,tcs4525"; -+ reg = <0x1c>; -+ fcs,suspend-voltage-selector = <1>; -+ regulator-name = "vdd_cpu"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <800000>; -+ regulator-max-microvolt = <1150000>; -+ regulator-ramp-delay = <2300>; -+ vin-supply = <&vcc5v_input>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ rk809: pmic@20 { -+ compatible = "rockchip,rk809"; -+ reg = <0x20>; -+ interrupt-parent = <&gpio0>; -+ interrupts = ; -+ #clock-cells = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pmic_int>; -+ rockchip,system-power-controller; -+ wakeup-source; -+ -+ vcc1-supply = <&vcc3v3_sys>; -+ vcc2-supply = <&vcc3v3_sys>; -+ vcc3-supply = <&vcc3v3_sys>; -+ vcc4-supply = <&vcc3v3_sys>; -+ vcc5-supply = <&vcc3v3_sys>; -+ vcc6-supply = <&vcc3v3_sys>; -+ vcc7-supply = <&vcc3v3_sys>; -+ vcc8-supply = <&vcc3v3_sys>; -+ vcc9-supply = <&vcc3v3_sys>; -+ -+ regulators { -+ vdd_logic: DCDC_REG1 { -+ regulator-name = "vdd_logic"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-init-microvolt = <900000>; -+ regulator-initial-mode = <0x2>; -+ regulator-min-microvolt = <500000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-ramp-delay = <6001>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_gpu: DCDC_REG2 { -+ regulator-name = "vdd_gpu"; -+ regulator-always-on; -+ regulator-init-microvolt = <900000>; -+ regulator-initial-mode = <0x2>; -+ regulator-min-microvolt = <500000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-ramp-delay = <6001>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_ddr: DCDC_REG3 { -+ regulator-name = "vcc_ddr"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-initial-mode = <0x2>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vdd_npu: DCDC_REG4 { -+ regulator-name = "vdd_npu"; -+ regulator-init-microvolt = <900000>; -+ regulator-initial-mode = <0x2>; -+ regulator-min-microvolt = <500000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-ramp-delay = <6001>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_1v8: DCDC_REG5 { -+ regulator-name = "vcc_1v8"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdda0v9_image: LDO_REG1 { -+ regulator-name = "vdda0v9_image"; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdda_0v9: LDO_REG2 { -+ regulator-name = "vdda_0v9"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdda0v9_pmu: LDO_REG3 { -+ regulator-name = "vdda0v9_pmu"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <900000>; -+ }; -+ }; -+ -+ vccio_acodec: LDO_REG4 { -+ regulator-name = "vccio_acodec"; -+ regulator-always-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vccio_sd: LDO_REG5 { -+ regulator-name = "vccio_sd"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc3v3_pmu: LDO_REG6 { -+ regulator-name = "vcc3v3_pmu"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3300000>; -+ }; -+ }; -+ -+ vcca_1v8: LDO_REG7 { -+ regulator-name = "vcca_1v8"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcca1v8_pmu: LDO_REG8 { -+ regulator-name = "vcca1v8_pmu"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vcca1v8_image: LDO_REG9 { -+ regulator-name = "vcca1v8_image"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_3v3: SWITCH_REG1 { -+ regulator-name = "vcc_3v3"; -+ regulator-always-on; -+ regulator-boot-on; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc3v3_sd: SWITCH_REG2 { -+ regulator-name = "vcc3v3_sd"; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ }; -+ }; -+}; -+ -+&pinctrl { -+ leds { -+ led_user_en: led_user_en { -+ rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ pmic { -+ pmic_int: pmic_int { -+ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+}; -+ -+&pmu_io_domains { -+ pmuio1-supply = <&vcc3v3_pmu>; -+ pmuio2-supply = <&vcc3v3_pmu>; -+ vccio1-supply = <&vccio_acodec>; -+ vccio2-supply = <&vcc_1v8>; -+ vccio3-supply = <&vccio_sd>; -+ vccio4-supply = <&vcc_1v8>; -+ vccio5-supply = <&vcc_3v3>; -+ vccio6-supply = <&vcc_1v8>; -+ vccio7-supply = <&vcc_3v3>; -+ status = "okay"; -+}; -+ -+&saradc { -+ vref-supply = <&vcca_1v8>; -+ status = "okay"; -+}; -+ -+&sdhci { -+ bus-width = <8>; -+ max-frequency = <200000000>; -+ non-removable; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>; -+ vmmc-supply = <&vcc_3v3>; -+ vqmmc-supply = <&vcc_1v8>; -+ status = "okay"; -+}; -+ -+ -+ -+&sfc { -+ status = "okay"; -+ flash@0 { -+ compatible = "jedec,spi-nor"; -+ reg = <0>; -+ spi-max-frequency = <108000000>; -+ spi-rx-bus-width = <2>; -+ spi-tx-bus-width = <2>; -+ }; -+}; -+ -+&tsadc { -+ rockchip,hw-tshut-mode = <1>; -+ rockchip,hw-tshut-polarity = <0>; -+ status = "okay"; -+}; -+ -+&uart2 { -+ status = "okay"; -+}; -+ -+&usb2phy0 { -+ status = "okay"; -+}; -+ -+&usb2phy1 { -+ status = "okay"; -+}; -+ -+&usb_host0_xhci { -+ extcon = <&usb2phy0>; -+ dr_mode = "host"; -+}; -diff --git a/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts b/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts -new file mode 100644 ---- /dev/null (revision a45c446e458e82465be126710c57677c6237d914) -+++ b/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts (revision a45c446e458e82465be126710c57677c6237d914) -@@ -0,0 +1,230 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+ -+/dts-v1/; -+#include "rk3568-radxa-cm3i.dtsi" -+ -+/ { -+ model = "Radxa E25 Carrier Board"; -+ compatible = "radxa,e25", "radxa,cm3i", "rockchip,rk3568"; -+ -+ aliases { -+ mmc1 = &sdmmc0; -+ }; -+ -+ pwm-leds { -+ compatible = "pwm-leds-multicolor"; -+ -+ multi-led { -+ color = ; -+ max-brightness = <255>; -+ -+ led-red { -+ color = ; -+ pwms = <&pwm1 0 1000000 0>; -+ }; -+ -+ led-green { -+ color = ; -+ pwms = <&pwm2 0 1000000 0>; -+ }; -+ -+ led-blue { -+ color = ; -+ pwms = <&pwm12 0 1000000 0>; -+ }; -+ }; -+ }; -+ -+ vbus_typec: vbus-typec-regulator { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vbus_typec_en>; -+ regulator-name = "vbus_typec"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ vcc3v3_minipcie: vcc3v3-minipcie-regulator { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio3 RK_PA7 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&minipcie_enable_h>; -+ regulator-name = "vcc3v3_minipcie"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ vcc3v3_ngff: vcc3v3-ngff-regulator { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&ngffpcie_enable_h>; -+ regulator-name = "vcc3v3_ngff"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ /* actually fed by vcc5v0_sys, dependent -+ * on pi6c clock generator -+ */ -+ vcc3v3_pcie30x1: vcc3v3-pcie30x1-regulator { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie30x1_enable_h>; -+ regulator-name = "vcc3v3_pcie30x1"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&vcc3v3_pi6c_05>; -+ }; -+ -+ vcc3v3_pi6c_05: vcc3v3-pi6c-05-regulator { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpios = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie_enable_h>; -+ regulator-name = "vcc3v3_pcie"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+}; -+ -+&pcie2x1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie20_reset_h>; -+ reset-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>; -+ vpcie3v3-supply = <&vcc3v3_pi6c_05>; -+ status = "okay"; -+}; -+ -+&pcie30phy { -+ data-lanes = <1 2>; -+ status = "okay"; -+}; -+ -+&pcie3x1 { -+ num-lanes = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie30x1m0_pins>; -+ reset-gpios = <&gpio0 RK_PC3 GPIO_ACTIVE_HIGH>; -+ vpcie3v3-supply = <&vcc3v3_pcie30x1>; -+ status = "okay"; -+}; -+ -+&pcie3x2 { -+ num-lanes = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie30x2_reset_h>; -+ reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>; -+ vpcie3v3-supply = <&vcc3v3_pi6c_05>; -+ status = "okay"; -+}; -+ -+&pinctrl { -+ pcie { -+ pcie20_reset_h: pcie20-reset-h { -+ rockchip,pins = <1 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ pcie30x1_enable_h: pcie30x1-enable-h { -+ rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ pcie30x2_reset_h: pcie30x2-reset-h { -+ rockchip,pins = <2 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ pcie_enable_h: pcie-enable-h { -+ rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ usb { -+ minipcie_enable_h: minipcie-enable-h { -+ rockchip,pins = <3 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ ngffpcie_enable_h: ngffpcie-enable-h { -+ rockchip,pins = <0 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ vbus_typec_en: vbus_typec_en { -+ rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+}; -+ -+&pwm1 { -+ status = "okay"; -+}; -+ -+&pwm2 { -+ status = "okay"; -+}; -+ -+&pwm12 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pwm12m1_pins>; -+ status = "okay"; -+}; -+ -+&sdmmc0 { -+ bus-width = <4>; -+ cap-sd-highspeed; -+ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; -+ /* Also used in pcie30x1_clkreqnm0 */ -+ disable-wp; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd>; -+ sd-uhs-sdr50; -+ vmmc-supply = <&vcc3v3_sd>; -+ vqmmc-supply = <&vccio_sd>; -+ status = "okay"; -+}; -+ -+&usb_host0_ehci { -+ status = "okay"; -+}; -+ -+&usb_host0_ohci { -+ status = "okay"; -+}; -+ -+&usb_host0_xhci { -+ extcon = <&usb2phy0>; -+ dr_mode = "host"; -+ status = "okay"; -+}; -+ -+&usb_host1_ehci { -+ status = "okay"; -+}; -+ -+&usb_host1_ohci { -+ status = "okay"; -+}; -+ -+&usb2phy0_otg { -+ phy-supply = <&vbus_typec>; -+ status = "okay"; -+}; -+ -+&usb2phy1_host { -+ phy-supply = <&vcc3v3_minipcie>; -+ status = "okay"; -+}; -+ -+&usb2phy1_otg { -+ phy-supply = <&vcc3v3_ngff>; -+ status = "okay"; -+}; diff --git a/patch/kernel/archive/rockchip64-6.1/add-board-rk3328-roc-pc.patch b/patch/kernel/archive/rockchip64-6.1/add-board-rk3328-roc-pc.patch deleted file mode 100644 index e1a06c53a2fa..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/add-board-rk3328-roc-pc.patch +++ /dev/null @@ -1,536 +0,0 @@ -From df33a68c3fdf58fd87f0599bcc49e7f09cf916ba Mon Sep 17 00:00:00 2001 -From: Paolo Sabatino -Date: Tue, 12 Oct 2021 19:34:29 +0000 -Subject: [PATCH] enable dmc for rk3328-roc-pc - ---- - .../arm64/boot/dts/rockchip/rk3328-roc-pc.dts | 529 ++++++++++++++++++ - 1 file changed, 529 insertions(+) - create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-roc-pc.dts - -diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-pc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-pc.dts -new file mode 100644 -index 000000000..08d77c694 ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-pc.dts -@@ -0,0 +1,517 @@ -+/* -+ * SPDX-License-Identifier: (GPL-2.0+ or MIT) -+ * Copyright (c) 2016 Fuzhou Rockchip Electronics Co., Ltd -+ */ -+ -+/dts-v1/; -+#include "rk3328-roc-pc-dram-timing.dtsi" -+#include "rk3328.dtsi" -+#include -+ -+/ { -+ model = "Firefly roc-rk3328-pc"; -+ compatible = "firefly,roc-rk3328-pc", "rockchip,rk3328"; -+ -+ aliases { -+ mmc0 = &sdmmc; -+ mmc1 = &emmc; /* MMC boot device */ -+ }; -+ -+ gmac_clkin: external-gmac-clock { -+ compatible = "fixed-clock"; -+ clock-frequency = <125000000>; -+ clock-output-names = "gmac_clkin"; -+ #clock-cells = <0>; -+ }; -+ -+ sound { -+ compatible = "simple-audio-card"; -+ simple-audio-card,format = "i2s"; -+ simple-audio-card,mclk-fs = <256>; -+ simple-audio-card,name = "rockchip,rk3328"; -+ simple-audio-card,cpu { -+ sound-dai = <&i2s1>; -+ }; -+ simple-audio-card,codec { -+ sound-dai = <&codec>; -+ }; -+ }; -+ -+ hdmi-sound { -+ compatible = "simple-audio-card"; -+ simple-audio-card,format = "i2s"; -+ simple-audio-card,mclk-fs = <128>; -+ simple-audio-card,name = "rockchip,hdmi"; -+ simple-audio-card,cpu { -+ sound-dai = <&i2s0>; -+ }; -+ simple-audio-card,codec { -+ sound-dai = <&hdmi>; -+ }; -+ }; -+ -+ vcc_host_5v: vcc-host-5v-regulator { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&usb30_host_drv>; -+ regulator-name = "vcc_host_5v"; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&vcc_sys>; -+ }; -+ -+ vcc_host1_5v: vcc_otg_5v: vcc-host1-5v-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc_phy"; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ vcc_phy: vcc-phy-regulator { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&usb20_host_drv>; -+ regulator-name = "vcc_host1_5v"; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&vcc_sys>; -+ }; -+ -+ vcc_sd: sdmmc-regulator { -+ compatible = "regulator-fixed"; -+ gpio = <&gpio0 30 GPIO_ACTIVE_LOW>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc0m1_pin>; -+ regulator-name = "vcc_sd"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&vcc_io>; -+ }; -+ -+ vcc_sys: vcc-sys { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ }; -+ -+ xin32k: xin32k { -+ compatible = "fixed-clock"; -+ clock-frequency = <32768>; -+ clock-output-names = "xin32k"; -+ #clock-cells = <0>; -+ }; -+ -+ leds { -+ compatible = "gpio-leds"; -+ -+ power_led: led-0 { -+ label = "firefly:blue:power"; -+ linux,default-trigger = "heartbeat"; -+ gpios = <&rk805 1 GPIO_ACTIVE_LOW>; -+ default-state = "on"; -+ mode = <0x23>; -+ }; -+ -+ user_led: led-1 { -+ label = "firefly:yellow:user"; -+ linux,default-trigger = "mmc1"; -+ gpios = <&rk805 0 GPIO_ACTIVE_LOW>; -+ default-state = "off"; -+ mode = <0x05>; -+ }; -+ }; -+ -+ /delete-node/ dmc-opp-table; -+ dmc_opp_table: dmc-opp-table { -+ compatible = "operating-points-v2"; -+ -+ opp-786000000 { -+ opp-hz = /bits/ 64 <786000000>; -+ opp-microvolt = <1075000 1075000 1200000>; -+ }; -+ opp-798000000 { -+ opp-hz = /bits/ 64 <798000000>; -+ opp-microvolt = <1075000 1075000 1200000>; -+ }; -+ opp-840000000 { -+ opp-hz = /bits/ 64 <840000000>; -+ opp-microvolt = <1075000 1075000 1200000>; -+ }; -+ opp-924000000 { -+ status = "disabled"; // unstable -+ opp-hz = /bits/ 64 <924000000>; -+ opp-microvolt = <1100000 1100000 1200000>; -+ }; -+ }; -+}; -+ -+&dfi { -+ status = "okay"; -+}; -+ -+&dmc { -+ center-supply = <&vdd_logic>; -+ ddr_timing = <&ddr_timing>; -+ status = "okay"; -+}; -+ -+&io_domains { -+ status = "okay"; -+ -+ vccio1-supply = <&vcc_io>; -+ vccio2-supply = <&vcc_18emmc>; -+ vccio3-supply = <&vcc_io>; -+ vccio4-supply = <&vcc_io>; -+ vccio5-supply = <&vcc_io>; -+ vccio6-supply = <&vcc_io>; -+ pmuio-supply = <&vcc_io>; -+}; -+ -+&cpu0 { -+ cpu-supply = <&vdd_arm>; -+}; -+ -+&gpu { -+ status = "okay"; -+ mali-supply = <&vdd_logic>; -+}; -+ -+&gmac2phy { -+ phy-supply = <&vcc_phy>; -+ clock_in_out = "output"; -+ assigned-clocks = <&cru SCLK_MAC2PHY_SRC>; -+ assigned-clock-rate = <50000000>; -+ assigned-clocks = <&cru SCLK_MAC2PHY>; -+ assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>; -+ status = "disabled"; -+}; -+ -+&gmac2io { -+ phy-supply = <&vcc_io>; -+ phy-mode = "rgmii"; -+ clock_in_out = "input"; -+ snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; -+ snps,reset-active-low; -+ snps,reset-delays-us = <0 10000 50000>; -+ assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; -+ assigned-clock-parents = <&gmac_clkin>, <&gmac_clkin>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&rgmiim1_pins>; -+ snps,aal; -+ snps,rxpbl = <0x4>; -+ snps,txpbl = <0x4>; -+ tx_delay = <0x24>; -+ rx_delay = <0x18>; -+ status = "okay"; -+}; -+ -+&display_subsystem { -+ status = "okay"; -+}; -+ -+&hdmi { -+ #sound-dai-cells = <0>; -+ ddc-i2c-scl-high-time-ns = <9625>; -+ ddc-i2c-scl-low-time-ns = <10000>; -+ status = "okay"; -+}; -+ -+&hdmiphy { -+ status = "okay"; -+}; -+ -+&hdmi_sound { -+ status = "okay"; -+}; -+ -+/*&h265e { -+ status = "okay"; -+}; -+ -+&vdec { -+ status = "okay"; -+}; -+ -+&vepu { -+ status = "okay"; -+};*/ -+ -+&vop { -+ status = "okay"; -+}; -+ -+&vop_mmu { -+ status = "okay"; -+}; -+ -+/*&vpu_service { -+ status = "okay"; -+};*/ -+ -+&i2s0 { -+ #sound-dai-cells = <0>; -+ rockchip,bclk-fs = <128>; -+ status = "okay"; -+}; -+ -+&i2s1 { -+ #sound-dai-cells = <0>; -+ status = "okay"; -+}; -+ -+&codec { -+ #sound-dai-cells = <0>; -+ status = "okay"; -+}; -+ -+&emmc { -+ bus-width = <8>; -+ cap-mmc-highspeed; -+ mmc-hs200-1_8v; -+ supports-emmc; -+ disable-wp; -+ non-removable; -+ num-slots = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; -+ status = "okay"; -+}; -+ -+&sdmmc { -+ bus-width = <4>; -+ cap-mmc-highspeed; -+ cap-sd-highspeed; -+ disable-wp; -+ max-frequency = <150000000>; -+ num-slots = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; -+ supports-sd; -+ status = "okay"; -+ vmmc-supply = <&vcc_sd>; -+}; -+ -+&i2c1 { -+ status = "okay"; -+ -+ rk805: rk805@18 { -+ compatible = "rockchip,rk805"; -+ status = "okay"; -+ reg = <0x18>; -+ interrupt-parent = <&gpio2>; -+ interrupts = <24 IRQ_TYPE_LEVEL_LOW>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pmic_int_l>; -+ rockchip,system-power-controller; -+ wakeup-source; -+ gpio-controller; -+ #gpio-cells = <2>; -+ #clock-cells = <1>; -+ clock-output-names = "xin32k", "rk805-clkout2"; -+ -+ vcc1-supply = <&vcc_sys>; -+ vcc2-supply = <&vcc_sys>; -+ vcc3-supply = <&vcc_sys>; -+ vcc4-supply = <&vcc_sys>; -+ vcc5-supply = <&vcc_io>; -+ vcc6-supply = <&vcc_io>; -+ -+ rtc { -+ status = "okay"; -+ }; -+ -+ pwrkey { -+ status = "okay"; -+ }; -+ -+ gpio { -+ status = "okay"; -+ }; -+ -+ regulators { -+ compatible = "rk805-regulator"; -+ status = "okay"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ vdd_logic: DCDC_REG1 { -+ regulator-name = "vdd_logic"; -+ regulator-min-microvolt = <712500>; -+ regulator-max-microvolt = <1450000>; -+ regulator-ramp-delay = <12500>; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1000000>; -+ }; -+ }; -+ -+ vdd_arm: DCDC_REG2 { -+ regulator-name = "vdd_arm"; -+ regulator-min-microvolt = <712500>; -+ regulator-max-microvolt = <1450000>; -+ regulator-ramp-delay = <12500>; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <950000>; -+ }; -+ }; -+ -+ vcc_ddr: DCDC_REG3 { -+ regulator-name = "vcc_ddr"; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vcc_io: DCDC_REG4 { -+ regulator-name = "vcc_io"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3300000>; -+ }; -+ }; -+ -+ vdd_18: LDO_REG1 { -+ regulator-name = "vdd_18"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vcc_18emmc: LDO_REG2 { -+ regulator-name = "vcc_18emmc"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vdd_11: LDO_REG3 { -+ regulator-name = "vdd_11"; -+ regulator-min-microvolt = <1100000>; -+ regulator-max-microvolt = <1100000>; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1100000>; -+ }; -+ }; -+ }; -+ }; -+}; -+ -+&pinctrl { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&clk_32k_out>; -+ -+ clk_32k { -+ clk_32k_out: clk-32k-out { -+ rockchip,pins = -+ <1 RK_PD4 1 &pcfg_pull_none>; -+ }; -+ }; -+ -+ pmic { -+ pmic_int_l: pmic-int-l { -+ rockchip,pins = -+ <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; /* gpio2_a6 */ -+ }; -+ }; -+ -+ sdio-pwrseq { -+ wifi_enable_h: wifi-enable-h { -+ rockchip,pins = <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>, -+ <3 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none_4ma>, -+ <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>, -+ <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ usb2 { -+ usb20_host_drv: usb20-host-drv { -+ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ usb3 { -+ usb30_host_drv: usb30-host-drv { -+ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+}; -+ -+&u2phy { -+ status = "okay"; -+}; -+ -+&u2phy_host { -+ status = "okay"; -+}; -+ -+&u2phy_otg { -+ status = "okay"; -+}; -+ -+&uart2 { -+ status = "okay"; -+}; -+ -+&usb20_otg { -+ dr_mode = "host"; -+ status = "okay"; -+}; -+ -+&usb_host0_ehci { -+ status = "okay"; -+}; -+ -+&usb_host0_ohci { -+ status = "okay"; -+}; -+ -+&usbdrd3 { -+ dr_mode = "host"; -+ status = "okay"; -+}; -+ -+&wdt { -+ status = "okay"; -+}; -+ -+&saradc { -+ status = "okay"; -+ vref-supply = <&vdd_18>; -+}; -+ -+&tsadc { -+ status = "okay"; -+ rockchip,hw-tshut-mode = <1>; /* tshut mode 0:CRU 1:GPIO */ -+ rockchip,hw-tshut-polarity = <1>; /* tshut polarity 0:LOW 1:HIGH */ -+}; --- -2.30.2 - diff --git a/patch/kernel/archive/rockchip64-6.1/add-board-rock-pi-4c-plus.patch b/patch/kernel/archive/rockchip64-6.1/add-board-rock-pi-4c-plus.patch deleted file mode 100644 index c95ab0061e58..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/add-board-rock-pi-4c-plus.patch +++ /dev/null @@ -1,738 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile -index 7eb135a5143f..1574279e61e8 100644 ---- a/arch/arm64/boot/dts/rockchip/Makefile -+++ b/arch/arm64/boot/dts/rockchip/Makefile -@@ -39,6 +39,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-roc-pc-mezzanine.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-pi-4a.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-pi-4b.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-pi-4c.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-pi-4c-plus.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock960.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rockpro64-v2.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rockpro64.dtb -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c-plus.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c-plus.dts -new file mode 100644 -index 000000000000..9fc8d5baba54 ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c-plus.dts -@@ -0,0 +1,720 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Copyright (c) 2022 Fuzhou Rockchip Electronics Co., Ltd -+ * Copyright (c) 2022 Radxa Limited -+ */ -+ -+/dts-v1/; -+#include -+#include -+#include "rk3399.dtsi" -+#include "rk3399-opp.dtsi" -+ -+/ { -+ model = "Radxa ROCK Pi 4C+"; -+ compatible = "radxa,rockpi4c-plus", "radxa,rockpi4", "rockchip,rk3399"; -+ -+ aliases { -+ mmc0 = &sdmmc; -+ mmc1 = &sdhci; -+ mmc2 = &sdio0; -+ }; -+ -+ chosen { -+ stdout-path = "serial2:1500000n8"; -+ }; -+ -+ clkin_gmac: external-gmac-clock { -+ compatible = "fixed-clock"; -+ clock-frequency = <125000000>; -+ clock-output-names = "clkin_gmac"; -+ #clock-cells = <0>; -+ }; -+ -+ vcc_lan: vcc3v3-phy-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc_lan"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc5v0_sys: vcc-sys { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v0_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ }; -+ -+ vbus_host: vbus-host { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio3 RK_PD6 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&usb1_en_oc>; -+ regulator-name = "vbus_host"; /* HOST-5V */ -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&vcc5v0_usb2>; -+ }; -+ -+ vcc5v0_typec: vcc5v0-typec-regulator { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio1 RK_PA3 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vcc5v0_typec_en>; -+ regulator-name = "vcc5v0_typec"; -+ regulator-always-on; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ virtual_pd: virtual-pd { -+ status = "disabled"; -+ compatible = "linux,extcon-pd-virtual"; -+ /* 0: positive, 1: negative*/ -+ vpd,init-flip = <0>; -+ /* 0: u2, 1: u3*/ -+ vpd,init-ss = <1>; -+ /* 0: dfp, 1: ufp, 2: dp 3: dp/ufp */ -+ vpd,init-mode = <2>; -+ hpd-gpios = <&gpio4 25 GPIO_ACTIVE_LOW>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hpd_en>; -+ dp-pwr-supply = <&vcc3v3_sys>; -+ }; -+ -+ vcc_0v9: vcc-0v9 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc_0v9"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ vin-supply = <&vcc3v3_sys>; -+ }; -+ -+ vcc3v3_pcie: vcc3v3-pcie-regulator { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie_drv>; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-name = "vcc3v3_pcie"; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ sdio_pwrseq: sdio-pwrseq { -+ compatible = "mmc-pwrseq-simple"; -+ clocks = <&rk809 1>; -+ clock-names = "ext_clock"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&wifi_enable_h>; -+ -+ /* -+ * On the module itself this is one of these (depending -+ * on the actual card populated): -+ * - SDIO_RESET_L_WL_REG_ON -+ * - PDN (power down when low) -+ */ -+ reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; -+ }; -+ -+ wireless_wlan: wireless-wlan { -+ compatible = "wlan-platdata"; -+ rockchip,grf = <&grf>; -+ wifi_chip_type = "ap6256"; -+ sdio_vref = <1800>; -+ WIFI,host_wake_irq = <&gpio0 RK_PA3 GPIO_ACTIVE_HIGH>; -+ status = "okay"; -+ }; -+ -+ gpio-leds { -+ compatible = "gpio-leds"; -+ status = "okay"; -+ -+ user-led1 { -+ gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_LOW>; -+ linux,default-trigger = "default-on"; -+ default-state = "on"; -+ }; -+ -+ user-led2 { -+ gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "heartbeat"; -+ default-state = "on"; -+ }; -+ }; -+}; -+ -+&cdn_dp { -+ extcon = <&virtual_pd>; -+ status = "disabled"; -+}; -+ -+&cpu_l0 { -+ cpu-supply = <&vdd_cpu_l>; -+}; -+ -+&cpu_l1 { -+ cpu-supply = <&vdd_cpu_l>; -+}; -+ -+&cpu_l2 { -+ cpu-supply = <&vdd_cpu_l>; -+}; -+ -+&cpu_l3 { -+ cpu-supply = <&vdd_cpu_l>; -+}; -+ -+&cpu_b0 { -+ cpu-supply = <&vdd_cpu_b>; -+}; -+ -+&cpu_b1 { -+ cpu-supply = <&vdd_cpu_b>; -+}; -+ -+&gmac { -+ assigned-clocks = <&cru SCLK_RMII_SRC>; -+ assigned-clock-parents = <&clkin_gmac>; -+ clock_in_out = "input"; -+ phy-supply = <&vcc_lan>; -+ phy-mode = "rgmii"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&rgmii_pins>; -+ snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; -+ snps,reset-active-low; -+ snps,reset-delays-us = <0 10000 50000>; -+ tx_delay = <0x28>; -+ rx_delay = <0x11>; -+ status = "okay"; -+}; -+ -+&i2c0 { -+ status = "okay"; -+ i2c-scl-falling-time-ns = <30>; -+ i2c-scl-rising-time-ns = <180>; -+ clock-frequency = <400000>; -+ -+ rk809: pmic@20 { -+ compatible = "rockchip,rk809"; -+ reg = <0x20>; -+ interrupt-parent = <&gpio1>; -+ interrupts = ; -+ #clock-cells = <1>; -+ clock-output-names = "rk808-clkout1", "rk808-clkout2"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pmic_int_l>; -+ rockchip,system-power-controller; -+ wakeup-source; -+ -+ vcc1-supply = <&vcc5v0_sys>; -+ vcc2-supply = <&vcc5v0_sys>; -+ vcc3-supply = <&vcc5v0_sys>; -+ vcc4-supply = <&vcc5v0_sys>; -+ vcc5-supply = <&vcc_buck5>; -+ vcc6-supply = <&vcc_buck5>; -+ vcc7-supply = <&vcc5v0_sys>; -+ vcc8-supply = <&vcc3v3_sys>; -+ vcc9-supply = <&vcc5v0_sys>; -+ -+ regulators { -+ vdd_log: DCDC_REG1 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <750000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-initial-mode = <0x2>; -+ regulator-name = "vdd_log"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ regulator-suspend-microvolt = <900000>; -+ }; -+ }; -+ -+ vdd_cpu_l: DCDC_REG2 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <750000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-ramp-delay = <6001>; -+ regulator-initial-mode = <0x2>; -+ regulator-name = "vdd_cpu_l"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_ddr: DCDC_REG3 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-name = "vcc_ddr"; -+ regulator-initial-mode = <0x2>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vcc3v3_sys: DCDC_REG4 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-initial-mode = <0x2>; -+ regulator-name = "vcc3v3_sys"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3300000>; -+ }; -+ }; -+ -+ vcc_buck5: DCDC_REG5 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-name = "vcc_buck5"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3300000>; -+ }; -+ }; -+ -+ vcca_0v9: LDO_REG1 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ regulator-name = "vcca_0v9"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_1v8: LDO_REG2 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-name = "vcc_1v8"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vcc0v9_soc: LDO_REG3 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ -+ regulator-name = "vcc0v9_soc"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <900000>; -+ }; -+ }; -+ -+ vcca_1v8: LDO_REG4 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1850000>; -+ regulator-max-microvolt = <1850000>; -+ -+ regulator-name = "vcca_1v8"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_mipi: LDO_REG5 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1500000>; -+ regulator-max-microvolt = <1500000>; -+ -+ regulator-name = "vcc_mipi"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_1v5: LDO_REG6 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1500000>; -+ regulator-max-microvolt = <1500000>; -+ -+ regulator-name = "vcc_1v5"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_3v0: LDO_REG7 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3000000>; -+ regulator-max-microvolt = <3000000>; -+ -+ regulator-name = "vcc_3v0"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vccio_sd: LDO_REG8 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ -+ regulator-name = "vccio_sd"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_cam: LDO_REG9 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ -+ regulator-name = "vcc_cam"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc5v0_usb2: SWITCH_REG1 { -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ -+ regulator-name = "vcc5v0_usb2.0"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <5000000>; -+ }; -+ }; -+ -+ lcd_3v3: SWITCH_REG2 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ -+ regulator-name = "lcd_3v3"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ }; -+ }; -+ -+ vdd_cpu_b: syr827@40 { -+ compatible = "silergy,syr827"; -+ reg = <0x40>; -+ regulator-compatible = "fan53555-reg"; -+ pinctrl-0 = <&vsel1_gpio>; -+ vsel-gpios = <&gpio1 RK_PC1 GPIO_ACTIVE_HIGH>; -+ regulator-name = "vdd_cpu_b"; -+ regulator-min-microvolt = <712500>; -+ regulator-max-microvolt = <1500000>; -+ regulator-ramp-delay = <1000>; -+ fcs,suspend-voltage-selector = <1>; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&vcc5v0_sys>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_gpu: syr828@41 { -+ compatible = "silergy,syr828"; -+ reg = <0x41>; -+ regulator-compatible = "fan53555-reg"; -+ pinctrl-0 = <&vsel2_gpio>; -+ vsel-gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_HIGH>; -+ regulator-name = "vdd_gpu"; -+ regulator-min-microvolt = <712500>; -+ regulator-max-microvolt = <1500000>; -+ regulator-ramp-delay = <1000>; -+ fcs,suspend-voltage-selector = <1>; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&vcc5v0_sys>; -+ regulator-initial-mode = <1>; /* 1:force PWM 2:auto */ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+}; -+ -+&io_domains { -+ status = "okay"; -+ -+ bt656-supply = <&vcc_3v0>; -+ audio-supply = <&vcca_1v8>; -+ sdmmc-supply = <&vccio_sd>; -+ gpio1830-supply = <&vcc_3v0>; -+}; -+ -+&pmu_io_domains { -+ status = "okay"; -+ -+ pmu1830-supply = <&vcc_3v0>; -+}; -+ -+&sdmmc { -+ bus-width = <4>; -+ cap-mmc-highspeed; -+ cap-sd-highspeed; -+ card-detect-delay = <800>; -+ disable-wp; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc_clk &sdmmc_cd &sdmmc_cmd &sdmmc_bus4>; -+ vqmmc-supply = <&vccio_sd>; -+ status = "okay"; -+}; -+ -+&sdio0 { -+ max-frequency = <200000000>; -+ supports-sdio; -+ bus-width = <4>; -+ disable-wp; -+ cap-sd-highspeed; -+ cap-sdio-irq; -+ keep-power-in-suspend; -+ mmc-pwrseq = <&sdio_pwrseq>; -+ non-removable; -+ num-slots = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>; -+ sd-uhs-sdr104; -+ status = "okay"; -+}; -+ -+&emmc_phy { -+ status = "okay"; -+}; -+ -+&sdhci { -+ bus-width = <8>; -+ mmc-hs400-1_8v; -+ mmc-hs400-enhanced-strobe; -+ non-removable; -+ status = "okay"; -+}; -+ -+&tcphy0 { -+ status = "okay"; -+}; -+ -+&tcphy1 { -+ status = "okay"; -+}; -+ -+&u2phy0 { -+ status = "okay"; -+ -+ u2phy0_otg: otg-port { -+ status = "okay"; -+ }; -+ -+ u2phy0_host: host-port { -+ phy-supply = <&vbus_host>; -+ status = "okay"; -+ }; -+}; -+ -+&u2phy1 { -+ status = "okay"; -+ -+ u2phy1_otg: otg-port { -+ status = "okay"; -+ }; -+ -+ u2phy1_host: host-port { -+ phy-supply = <&vbus_host>; -+ status = "okay"; -+ }; -+}; -+ -+&uart0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; -+}; -+ -+&uart2 { -+ status = "okay"; -+}; -+ -+&usb_host0_ehci { -+ status = "okay"; -+}; -+ -+&usb_host0_ohci { -+ status = "okay"; -+}; -+ -+&usb_host1_ehci { -+ status = "okay"; -+}; -+ -+&usb_host1_ohci { -+ status = "okay"; -+}; -+ -+&usbdrd3_0 { -+ status = "okay"; -+}; -+ -+&usbdrd_dwc3_0 { -+ status = "okay"; -+ extcon = <&u2phy0>; -+ dr_mode = "otg"; -+}; -+ -+&usbdrd3_1 { -+ status = "okay"; -+}; -+ -+&usbdrd_dwc3_1 { -+ status = "okay"; -+ dr_mode = "host"; -+}; -+ -+&vopb { -+ status = "okay"; -+}; -+ -+&vopb_mmu { -+ status = "okay"; -+}; -+ -+&vopl { -+ status = "okay"; -+}; -+ -+&vopl_mmu { -+ status = "okay"; -+}; -+ -+&hdmi { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hdmi_i2c_xfer>, <&hdmi_cec>; -+ status = "okay"; -+}; -+ -+&hdmi_sound { -+ status = "okay"; -+}; -+ -+&hdmi_in_vopb { -+ status = "okay"; -+}; -+ -+&hdmi_in_vopl { -+ status = "okay"; -+}; -+ -+&i2c1 { -+ i2c-scl-rising-time-ns = <450>; -+ i2c-scl-falling-time-ns = <15>; -+ status = "okay"; -+}; -+ -+&pcie_phy { -+ status = "okay"; -+}; -+ -+&pcie0 { -+ ep-gpios = <&gpio4 RK_PD3 GPIO_ACTIVE_HIGH>; -+ num-lanes = <4>; -+ pinctrl-0 = <&pcie_clkreqnb_cpm>; -+ pinctrl-names = "default"; -+ vpcie0v9-supply = <&vcc_0v9>; -+ vpcie1v8-supply = <&vcc_1v8>; -+ vpcie3v3-supply = <&vcc3v3_pcie>; -+ status = "okay"; -+}; -+ -+&pinctrl { -+ hpd { -+ hpd_en: hpd-en { -+ rockchip,pins = <4 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ pmic { -+ pmic_int_l: pmic-int-l { -+ rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ -+ vsel1_gpio: vsel1-gpio { -+ rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ -+ vsel2_gpio: vsel2-gpio { -+ rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ }; -+ -+ sdmmc { -+ sdmmc_bus4: sdmmc-bus4 { -+ rockchip,pins = <4 8 1 &pcfg_pull_up_8ma>, -+ <4 9 1 &pcfg_pull_up_8ma>, -+ <4 10 1 &pcfg_pull_up_8ma>, -+ <4 11 1 &pcfg_pull_up_8ma>; -+ }; -+ -+ sdmmc_clk: sdmmc-clk { -+ rockchip,pins = <4 12 1 &pcfg_pull_none_18ma>; -+ }; -+ -+ sdmmc_cmd: sdmmc-cmd { -+ rockchip,pins = <4 13 1 &pcfg_pull_up_8ma>; -+ }; -+ }; -+ -+ usb-typec { -+ vcc5v0_typec_en: vcc5v0-typec-en { -+ rockchip,pins = <1 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ -+ vbus_host { -+ usb1_en_oc: usb1-en-oc { -+ rockchip,pins = <3 RK_PD6 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ -+ pcie { -+ pcie_drv: pcie-drv { -+ rockchip,pins = -+ <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ sdio-pwrseq { -+ wifi_enable_h: wifi-enable-h { -+ rockchip,pins = -+ <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+}; diff --git a/patch/kernel/archive/rockchip64-6.1/add-board-sakurapi-rk3308b.patch b/patch/kernel/archive/rockchip64-6.1/add-board-sakurapi-rk3308b.patch deleted file mode 100644 index 34cb390f0a07..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/add-board-sakurapi-rk3308b.patch +++ /dev/null @@ -1,264 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Chiyuki Akatsuki <17957399+TheSnowfield@users.noreply.github.com> -Date: Mon, 15 Apr 2024 10:49:53 +0000 -Subject: Patching kernel rockchip64 files - arch/arm64/boot/dts/rockchip/Makefile - arch/arm64/boot/dts/rockchip/rk3308-sakurapi-rk3308b.dts - -Signed-off-by: Chiyuki Akatsuki <17957399+TheSnowfield@users.noreply.github.com> ---- - arch/arm64/boot/dts/rockchip/Makefile | 1 + - arch/arm64/boot/dts/rockchip/rk3308-sakurapi-rk3308b.dts | 226 ++++++++++ - 2 files changed, 227 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile -index e1363f980f6b..924c4fe2008d 100644 ---- a/arch/arm64/boot/dts/rockchip/Makefile -+++ b/arch/arm64/boot/dts/rockchip/Makefile -@@ -22,10 +22,11 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-engicam-px30-core-ctouch2.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-engicam-px30-core-ctouch2-of10.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-engicam-px30-core-edimm2.2.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-evb.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-roc-cc.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-rock-pi-s.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-sakurapi-rk3308b.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3318-a95x-z2.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-odroid-go2.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-a1.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2s.dtb -diff --git a/arch/arm64/boot/dts/rockchip/rk3308-sakurapi-rk3308b.dts b/arch/arm64/boot/dts/rockchip/rk3308-sakurapi-rk3308b.dts -new file mode 100644 -index 000000000000..7d942a8f5e54 ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3308-sakurapi-rk3308b.dts -@@ -0,0 +1,226 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Copyright (c) 2019 Akash Gajjar -+ * Copyright (c) 2019 Jagan Teki -+ * Copyright (C) 2024 Chiyuki Akatsuki -+ */ -+ -+/dts-v1/; -+#include "rk3308.dtsi" -+ -+/ { -+ model = "Sakura Pi RK3308B"; -+ compatible = "rockchip,rk3308"; -+ -+ chosen { -+ stdout-path = "serial2:1500000n8"; -+ }; -+ -+ sdio_pwrseq: sdio-pwrseq { -+ compatible = "mmc-pwrseq-simple"; -+ pinctrl-0 = <&wifi_enable_h>; -+ pinctrl-names = "default"; -+ /* -+ * On the module itself this is one of these (depending -+ * on the actual card populated): -+ * - SDIO_RESET_L_WL_REG_ON -+ * - PDN (power down when low) -+ */ -+ reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; -+ }; -+ -+ vcc5v0_sys: vcc5v0-sys { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v0_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ }; -+ -+ vdd_core: vdd-core { -+ compatible = "pwm-regulator"; -+ pwms = <&pwm0 0 5000 1>; -+ regulator-name = "vdd_core"; -+ regulator-min-microvolt = <827000>; -+ regulator-max-microvolt = <1340000>; -+ regulator-init-microvolt = <1015000>; -+ regulator-settling-time-up-us = <250>; -+ regulator-always-on; -+ regulator-boot-on; -+ pwm-supply = <&vcc5v0_sys>; -+ }; -+ -+ vdd_log: vdd-log { -+ compatible = "regulator-fixed"; -+ regulator-name = "vdd_log"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1050000>; -+ regulator-max-microvolt = <1050000>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ vcc_ddr: vcc-ddr { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc_ddr"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1500000>; -+ regulator-max-microvolt = <1500000>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ vcc_1v8: vcc-1v8 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc_1v8"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ vin-supply = <&vcc_io>; -+ }; -+ -+ vcc_io: vcc-io { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc_io"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ vcc_phy: vcc-phy-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc_phy"; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ vcc5v0_otg: vcc5v0-otg { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v0_otg"; -+ regulator-always-on; -+ gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; -+ enable-active-high; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&otg_vbus_drv>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+}; -+ -+&cpu0 { -+ cpu-supply = <&vdd_core>; -+}; -+ -+&emmc { -+ bus-width = <8>; -+ cap-mmc-highspeed; -+ non-removable; -+ status = "okay"; -+}; -+ -+&i2c1 { -+ status = "okay"; -+}; -+ -+&sdmmc { -+ cap-mmc-highspeed; -+ cap-sd-highspeed; -+ disable-wp; -+ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_det &sdmmc_bus4>; -+ card-detect-delay = <800>; -+ status = "okay"; -+}; -+ -+&sdio { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cap-sd-highspeed; -+ cap-sdio-irq; -+ keep-power-in-suspend; -+ mmc-pwrseq = <&sdio_pwrseq>; -+ non-removable; -+ no-mmc; -+ status = "okay"; -+ -+ brcmf: wifi@1 { -+ compatible = "brcm,bcm43455-fmac"; -+ reg = <1>; -+ interrupt-parent = <&gpio0>; -+ interrupts = ; -+ interrupt-names = "host-wake"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&wifi_host_wake>; -+ }; -+}; -+ -+&spi2 { -+ status = "okay"; -+ max-freq = <10000000>; -+}; -+ -+&pinctrl { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&rtc_32k>; -+ -+ usb { -+ otg_vbus_drv: otg-vbus-drv { -+ rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ sdio-pwrseq { -+ wifi_enable_h: wifi-enable-h { -+ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ wifi { -+ wifi_host_wake: wifi-host-wake { -+ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ }; -+}; -+ -+&pwm0 { -+ status = "okay"; -+ pinctrl-0 = <&pwm0_pin_pull_down>; -+}; -+ -+&saradc { -+ vref-supply = <&vcc_1v8>; -+ status = "okay"; -+}; -+ -+&uart2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart2m0_xfer>; -+ status = "okay"; -+}; -+ -+&usb20_otg { -+ status = "okay"; -+}; -+ -+&u2phy { -+ status = "okay"; -+}; -+ -+&u2phy_otg { -+ status = "okay"; -+}; -+ -+&u2phy_host { -+ state = "okay"; -+}; -+ -+&usb_host_ehci { -+ status = "okay"; -+}; -+ -+&usb_host_ohci{ -+ status = "okay"; -+}; -+ --- -Created with Armbian build tools https://github.com/armbian/build - diff --git a/patch/kernel/archive/rockchip64-6.1/add-board-tinker-board-2.patch b/patch/kernel/archive/rockchip64-6.1/add-board-tinker-board-2.patch deleted file mode 100644 index 325ab919d856..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/add-board-tinker-board-2.patch +++ /dev/null @@ -1,771 +0,0 @@ -From 98250da85549f89a889424926d3552f4abd09a1f Mon Sep 17 00:00:00 2001 -From: tonymac32 -Date: Tue, 2 Mar 2021 15:50:01 -0500 -Subject: [PATCH] Patching something - -Signed-off-by: tonymac32 ---- - .../boot/dts/rockchip/rk3399-tinker-2.dts | 613 ++++++++++++++++++ - 1 files changed, 613 insertions(+) - create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-tinker-2.dts - -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-tinker-2.dts b/arch/arm64/boot/dts/rockchip/rk3399-tinker-2.dts -new file mode 100644 -index 000000000..dc337bee0 ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3399-tinker-2.dts -@@ -0,0 +1,751 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Copyright (c) 2016 Fuzhou Rockchip Electronics Co., Ltd -+ * Copyright (c) 2021 Thomas McKahan -+ */ -+ -+/dts-v1/; -+#include -+#include -+#include "rk3399.dtsi" -+#include "rk3399-op1-opp.dtsi" -+ -+/ { -+ model = "Asus Tinker Board 2/2S"; -+ compatible = "rockchip,rk3399-evb", "rockchip,rk3399"; -+ -+ chosen { -+ stdout-path = "serial2:1500000n8"; -+ }; -+ -+ board_info: board-info { -+ compatible = "board-info"; -+ -+ hw-id0 = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>; -+ hw-id1 = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>; -+ hw-id2 = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>; -+ -+ pid-id0 = <&gpio2 RK_PA5 GPIO_ACTIVE_HIGH>; -+ pid-id1 = <&gpio2 RK_PA3 GPIO_ACTIVE_HIGH>; -+ pid-id2 = <&gpio2 RK_PA2 GPIO_ACTIVE_HIGH>; -+ -+ ddr-id1 = <&gpio4 RK_PA4 GPIO_ACTIVE_HIGH>; -+ ddr-id2 = <&gpio4 RK_PA0 GPIO_ACTIVE_HIGH>; -+ -+ pmic-reset = <&gpio1 RK_PA6 GPIO_ACTIVE_HIGH>; -+ }; -+ -+ clkin_gmac: external-gmac-clock { -+ compatible = "fixed-clock"; -+ clock-frequency = <125000000>; -+ clock-output-names = "clkin_gmac"; -+ #clock-cells = <0>; -+ }; -+ -+ gpio-leds { -+ compatible = "gpio-leds"; -+ -+ pwr-led { -+ gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "default-on"; -+ retain-state-suspended = <1>; -+ }; -+ -+ act-led { -+ gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger="mmc0"; -+ }; -+ -+ rsv-led { -+ gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger="heartbeat"; -+ }; -+ }; -+ -+ vcc_lcd: vcc-lcd { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc_lcd"; -+ gpio = <&gpio4 30 GPIO_ACTIVE_HIGH>; -+ startup-delay-us = <20000>; -+ enable-active-high; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ vcc3v3_sys: vcc3v3-sys { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc3v3_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ }; -+ -+ vcc5v0_host: vcc5v0-host-regulator { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio4 RK_PD1 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vcc5v0_host_en>; -+ regulator-name = "vcc5v0_host"; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ vcc5v0_sys: vcc5v0-sys { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v0_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ }; -+ -+ vcc_phy: vcc-phy-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc_phy"; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ vbus_typec: vbus-5vout { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio1 RK_PA3 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vcc5v0_typec0_en_pin>; -+ regulator-name = "vbus_5vout"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc5v0_sys>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_log: vdd-log { -+ compatible = "pwm-regulator"; -+ pwms = <&pwm2 0 25000 1>; -+ regulator-name = "vdd_log"; -+ regulator-min-microvolt = <800000>; -+ regulator-max-microvolt = <1400000>; -+ regulator-always-on; -+ regulator-boot-on; -+ -+ /* for rockchip boot on */ -+ rockchip,pwm_id= <2>; -+ rockchip,pwm_voltage = <900000>; -+ }; -+ -+ xin32k: xin32k { -+ compatible = "fixed-clock"; -+ clock-frequency = <32768>; -+ clock-output-names = "xin32k"; -+ #clock-cells = <0>; -+ }; -+}; -+ -+&cdn_dp { -+ status = "okay"; -+ extcon = <&fusb0>; -+}; -+ -+&cpu_l0 { -+ cpu-supply = <&vdd_cpu_l>; -+}; -+ -+&cpu_l1 { -+ cpu-supply = <&vdd_cpu_l>; -+}; -+ -+&cpu_l2 { -+ cpu-supply = <&vdd_cpu_l>; -+}; -+ -+&cpu_l3 { -+ cpu-supply = <&vdd_cpu_l>; -+}; -+ -+&cpu_b0 { -+ cpu-supply = <&vdd_cpu_b>; -+}; -+ -+&cpu_b1 { -+ cpu-supply = <&vdd_cpu_b>; -+}; -+ -+&emmc_phy { -+ status = "okay"; -+}; -+ -+&gmac { -+ assigned-clocks = <&cru SCLK_RMII_SRC>; -+ assigned-clock-parents = <&cru SCLK_MAC>; -+ clock_in_out = "input"; -+ assigned-clock-rates = <125000000>; -+ phy-supply = <&vcc_phy>; -+ phy-mode = "rgmii"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&rgmii_pins>; -+ snps,reset-gpio = <&gpio3 15 GPIO_ACTIVE_LOW>; -+ snps,reset-active-low; -+ snps,reset-delays-us = <0 16000 72000>; -+ tx_delay = <0x25>; -+ rx_delay = <0x20>; -+ wakeup-enable = "0"; -+ status = "okay"; -+}; -+&gpu { -+ mali-supply = <&vdd_gpu>; -+ status = "okay"; -+}; -+ -+&hdmi { -+ ddc-i2c-bus = <&i2c3>; -+ status = "okay"; -+}; -+ -+&hdmi_sound { -+ status = "okay"; -+}; -+ -+&i2c0 { -+ status = "okay"; -+ -+ rk808: pmic@1b { -+ compatible = "rockchip,rk808"; -+ reg = <0x1b>; -+ interrupt-parent = <&gpio1>; -+ interrupts = <18 IRQ_TYPE_LEVEL_LOW>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pmic_int_l>; -+ rockchip,system-power-controller; -+ wakeup-source; -+ #clock-cells = <1>; -+ clock-output-names = "rk808-clkout1", "rk808-clkout2"; -+ -+ vcc1-supply = <&vcc3v3_sys>; -+ vcc2-supply = <&vcc3v3_sys>; -+ vcc3-supply = <&vcc3v3_sys>; -+ vcc4-supply = <&vcc3v3_sys>; -+ vcc6-supply = <&vcc3v3_sys>; -+ vcc7-supply = <&vcc3v3_sys>; -+ vcc8-supply = <&vcc3v3_sys>; -+ vcc9-supply = <&vcc3v3_sys>; -+ vcc10-supply = <&vcc3v3_sys>; -+ vcc11-supply = <&vcc3v3_sys>; -+ vcc12-supply = <&vcc3v3_sys>; -+ vddio-supply = <&vcc1v8_pmu>; -+ -+ regulators { -+ vdd_center: DCDC_REG1 { -+ regulator-name = "vdd_center"; -+ regulator-min-microvolt = <750000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-ramp-delay = <6001>; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <900000>; -+ }; -+ }; -+ -+ vdd_cpu_l: DCDC_REG2 { -+ regulator-name = "vdd_cpu_l"; -+ regulator-min-microvolt = <750000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-ramp-delay = <6001>; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_ddr: DCDC_REG3 { -+ regulator-name = "vcc_ddr"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vcc_1v8: DCDC_REG4 { -+ regulator-name = "vcc_1v8"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vcc3v3_dsi: LDO_REG1 { -+ regulator-name = "vcc3v3_dsi"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcca1v8_hdmi: LDO_REG2 { -+ regulator-name = "vcca1v8_hdmi"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc1v8_pmu: LDO_REG3 { -+ regulator-name = "vcc1v8_pmu"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vccio_sd: LDO_REG4 { -+ regulator-name = "vccio_sd"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3000000>; -+ }; -+ }; -+ -+ vcc3v3_csi: LDO_REG5 { -+ regulator-name = "vcc3v3_csi"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_1v5: LDO_REG6 { -+ regulator-name = "vcc_1v5"; -+ regulator-min-microvolt = <1500000>; -+ regulator-max-microvolt = <1500000>; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1500000>; -+ }; -+ }; -+ -+ vcca0v9_hdmi: LDO_REG7 { -+ regulator-name = "vcca0v9_hdmi"; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_3v0: LDO_REG8 { -+ regulator-name = "vcc_3v0"; -+ regulator-min-microvolt = <3000000>; -+ regulator-max-microvolt = <3000000>; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3000000>; -+ }; -+ }; -+ -+ vcc3v3_s3: SWITCH_REG1 { -+ regulator-name = "vcc3v3_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vcc3v3_s0: SWITCH_REG2 { -+ regulator-name = "vcc3v3_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ }; -+ }; -+ -+ vdd_cpu_b: vdd_cpu_b@60 { -+ compatible = "fcs,fan53200"; -+ reg = <0x60>; -+ vin-supply = <&vcc5v0_sys>; -+ regulator-compatible = "fan53555-regulator"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vsel1_gpio>; -+ vsel-gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>; -+ regulator-name = "vdd_cpu_b"; -+ regulator-min-microvolt = <800000>; -+ regulator-max-microvolt = <1250000>; -+ regulator-ramp-delay = <1000>; -+ fcs,suspend-voltage-selector = <1>; -+ regulator-always-on; -+ regulator-boot-on; -+ status = "okay"; -+ -+ regulator-initial-state = <3>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+}; -+ -+&i2c3 { -+ status = "okay"; -+}; -+ -+&i2c4 { -+ -+ status = "okay"; -+ i2c-scl-rising-time-ns = <475>; -+ i2c-scl-falling-time-ns = <26>; -+ fusb0: fusb30x@22 { -+ compatible = "fcs,fusb302"; -+ reg = <0x22>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&fusb0_int>; -+ interrupt-parent = <&gpio1>; -+ interrupts = ; -+ vbus-supply = <&vbus_typec>; -+ status = "okay"; -+ -+ connector { -+ compatible = "usb-c-connector"; -+ data-role = "dual"; -+ label = "USB-C"; -+ op-sink-microwatt = <1000000>; -+ power-role = "dual"; -+ sink-pdos = -+ ; -+ source-pdos = -+ ; -+ try-power-role = "sink"; -+ -+ extcon-cables = <1 2 5 6 9 10 12 44>; -+ typec-altmodes = <0xff01 1 0x001c0000 1>; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ port@0 { -+ reg = <0>; -+ -+ usbc_hs: endpoint { -+ remote-endpoint = -+ <&u2phy0_typec_hs>; -+ }; -+ }; -+ -+ port@1 { -+ reg = <1>; -+ -+ usbc_ss: endpoint { -+ remote-endpoint = -+ <&tcphy0_typec_ss>; -+ }; -+ }; -+ -+ port@2 { -+ reg = <2>; -+ -+ usbc_dp: endpoint { -+ remote-endpoint = -+ <&tcphy0_typec_dp>; -+ }; -+ }; -+ }; -+ }; -+ -+ -+ -+ -+ }; -+ -+ vdd_gpu: vdd_gpu@60 { -+ compatible = "fcs,fan53200"; -+ reg = <0x60>; -+ vin-supply = <&vcc5v0_sys>; -+ regulator-compatible = "fan53555-regulator"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vsel2_gpio>; -+ vsel-gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>; -+ regulator-name = "vdd_gpu"; -+ regulator-min-microvolt = <800000>; -+ regulator-max-microvolt = <1200000>; -+ regulator-ramp-delay = <1000>; -+ fcs,suspend-voltage-selector = <1>; -+ regulator-always-on; -+ regulator-boot-on; -+ status = "okay"; -+ -+ regulator-initial-state = <3>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+}; -+ -+&i2c8 { -+ -+ m24c08: m24c08@50 { -+ compatible = "atmel,24c08"; -+ reg = <0x50>; -+ }; -+}; -+ -+&i2s0 { -+ rockchip,playback-channels = <8>; -+ rockchip,capture-channels = <8>; -+ status = "okay"; -+}; -+ -+&i2s2 { -+ status = "okay"; -+}; -+ -+&pcie_phy { -+ status = "okay"; -+}; -+ -+&pcie0 { -+ ep-gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>; -+ num-lanes = <4>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie_clkreqn_cpm>; -+ status = "okay"; -+}; -+ -+&pwm0 { -+ status = "disabled"; -+}; -+ -+&pwm2 { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pwm2_pin_pull_down>; -+}; -+ -+&pwm3 { -+ status = "disabled"; -+}; -+ -+&saradc { -+ status = "okay"; -+}; -+ -+&sdhci { -+ bus-width = <8>; -+ mmc-hs200-1_8v; -+ supports-emmc; -+ //mmc-hs400-enhanced-strobe; -+ non-removable; -+ keep-power-in-suspend; -+ status = "okay"; -+}; -+ -+&sdmmc { -+ clock-frequency = <150000000>; -+ clock-freq-min-max = <100000 150000000>; -+ supports-sd; -+ bus-width = <4>; -+ cap-mmc-highspeed; -+ cap-sd-highspeed; -+ disable-wp; -+ num-slots = <1>; -+ //sd-uhs-sdr104; -+ vmmc-supply = <&vcc3v3_s3>; -+ vqmmc-supply = <&vccio_sd>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; -+ status = "okay"; -+}; -+ -+&tcphy0 { -+ extcon = <&fusb0>; -+ status = "okay"; -+}; -+ -+&tcphy0_dp { -+ port { -+ tcphy0_typec_dp: endpoint { -+ remote-endpoint = <&usbc_dp>; -+ }; -+ }; -+}; -+ -+&tcphy0_usb3 { -+ port { -+ tcphy0_typec_ss: endpoint { -+ remote-endpoint = <&usbc_ss>; -+ }; -+ }; -+}; -+ -+&tcphy1 { -+ status = "okay"; -+}; -+ -+&tsadc { -+ /* tshut mode 0:CRU 1:GPIO */ -+ rockchip,hw-tshut-mode = <1>; -+ /* tshut polarity 0:LOW 1:HIGH */ -+ rockchip,hw-tshut-polarity = <1>; -+ status = "okay"; -+}; -+ -+&u2phy0 { -+ status = "okay"; -+ -+ u2phy0_otg: otg-port { -+ status = "okay"; -+ }; -+ -+ u2phy0_host: host-port { -+ phy-supply = <&vcc5v0_host>; -+ status = "okay"; -+ }; -+ -+ port { -+ u2phy0_typec_hs: endpoint { -+ remote-endpoint = <&usbc_hs>; -+ }; -+ }; -+}; -+ -+&u2phy1 { -+ status = "okay"; -+ -+ u2phy1_otg: otg-port { -+ status = "okay"; -+ }; -+ -+ u2phy1_host: host-port { -+ phy-supply = <&vcc5v0_host>; -+ status = "okay"; -+ }; -+}; -+ -+&usbdrd3_0 { -+ status = "okay"; -+}; -+ -+&usbdrd_dwc3_0 { -+ status = "okay"; -+ dr_mode = "host"; -+}; -+ -+&usbdrd3_1 { -+ status = "okay"; -+}; -+ -+&usbdrd_dwc3_1 { -+ status = "okay"; -+ dr_mode = "host"; -+}; -+ -+&uart2 { -+ status = "okay"; -+}; -+ -+&usb_host0_ehci { -+ status = "okay"; -+}; -+ -+&usb_host0_ohci { -+ status = "okay"; -+}; -+ -+&usb_host1_ehci { -+ status = "okay"; -+}; -+ -+&usb_host1_ohci { -+ status = "okay"; -+}; -+ -+&pinctrl { -+ -+ pmic { -+ pmic_int_l: pmic-int-l { -+ rockchip,pins = -+ <1 18 RK_FUNC_GPIO &pcfg_pull_up>, -+ <0 9 RK_FUNC_GPIO &pcfg_pull_none>; /* GPIO0_B1 */ -+ }; -+ vsel1_gpio: vsel1-gpio { -+ rockchip,pins = -+ <1 17 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ vsel2_gpio: vsel2-gpio { -+ rockchip,pins = -+ <1 14 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ }; -+ -+ usb2 { -+ vcc5v0_host_en: vcc5v0-host-en { -+ rockchip,pins = -+ <4 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ usb-typec { -+ vcc5v0_typec0_en_pin: vcc5v0-typec0-en-pin { -+ rockchip,pins = <1 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ -+ fusb30x { -+ fusb0_int: fusb0-int { -+ rockchip,pins = <1 2 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+}; -+ -+&vopl { -+ status = "okay"; -+}; -+ -+&vopl_mmu { -+ status = "okay"; -+}; -+ -+&vopb { -+ status = "okay"; -+}; -+ -+&vopb_mmu { -+ status = "okay"; -+}; --- -Created with Armbian build tools https://github.com/armbian/build - diff --git a/patch/kernel/archive/rockchip64-6.1/add-board-tvbox-rk3318.patch b/patch/kernel/archive/rockchip64-6.1/add-board-tvbox-rk3318.patch deleted file mode 100644 index eb6797086b88..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/add-board-tvbox-rk3318.patch +++ /dev/null @@ -1,1060 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/rk3318-dram-default-timing.dtsi b/arch/arm64/boot/dts/rockchip/rk3318-dram-default-timing.dtsi -new file mode 100644 -index 000000000..31a28d829 ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3318-dram-default-timing.dtsi -@@ -0,0 +1,311 @@ -+/* -+ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd -+ * -+ * This file is dual-licensed: you can use it either under the terms -+ * of the GPL or the X11 license, at your option. Note that this dual -+ * licensing only applies to this file, and not this project as a -+ * whole. -+ * -+ * a) This library 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 library 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. -+ * -+ * Or, alternatively, -+ * -+ * b) Permission is hereby granted, free of charge, to any person -+ * obtaining a copy of this software and associated documentation -+ * files (the "Software"), to deal in the Software without -+ * restriction, including without limitation the rights to use, -+ * copy, modify, merge, publish, distribute, sublicense, and/or -+ * sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following -+ * conditions: -+ * -+ * The above copyright notice and this permission notice shall be -+ * included in all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+#include -+#include -+ -+/ { -+ ddr_timing: ddr_timing { -+ compatible = "rockchip,ddr-timing"; -+ ddr3_speed_bin = ; -+ ddr4_speed_bin = ; -+ pd_idle = <0>; -+ sr_idle = <0>; -+ sr_mc_gate_idle = <0>; -+ srpd_lite_idle = <0>; -+ standby_idle = <0>; -+ -+ auto_pd_dis_freq = <1066>; -+ auto_sr_dis_freq = <800>; -+ ddr3_dll_dis_freq = <300>; -+ ddr4_dll_dis_freq = <625>; -+ phy_dll_dis_freq = <400>; -+ -+ ddr3_odt_dis_freq = <100>; -+ phy_ddr3_odt_dis_freq = <100>; -+ ddr3_drv = ; -+ ddr3_odt = ; -+ phy_ddr3_ca_drv = ; -+ phy_ddr3_ck_drv = ; -+ phy_ddr3_dq_drv = ; -+ phy_ddr3_odt = ; -+ -+ lpddr3_odt_dis_freq = <666>; -+ phy_lpddr3_odt_dis_freq = <666>; -+ lpddr3_drv = ; -+ lpddr3_odt = ; -+ phy_lpddr3_ca_drv = ; -+ phy_lpddr3_ck_drv = ; -+ phy_lpddr3_dq_drv = ; -+ phy_lpddr3_odt = ; -+ -+ lpddr4_odt_dis_freq = <800>; -+ phy_lpddr4_odt_dis_freq = <800>; -+ lpddr4_drv = ; -+ lpddr4_dq_odt = ; -+ lpddr4_ca_odt = ; -+ phy_lpddr4_ca_drv = ; -+ phy_lpddr4_ck_cs_drv = ; -+ phy_lpddr4_dq_drv = ; -+ phy_lpddr4_odt = ; -+ -+ ddr4_odt_dis_freq = <666>; -+ phy_ddr4_odt_dis_freq = <666>; -+ ddr4_drv = ; -+ ddr4_odt = ; -+ phy_ddr4_ca_drv = ; -+ phy_ddr4_ck_drv = ; -+ phy_ddr4_dq_drv = ; -+ phy_ddr4_odt = ; -+ -+ /* CA de-skew, one step is 47.8ps, range 0-15 */ -+ ddr3a1_ddr4a9_de-skew = <2>; -+ ddr3a0_ddr4a10_de-skew = <3>; -+ ddr3a3_ddr4a6_de-skew = <3>; -+ ddr3a2_ddr4a4_de-skew = <2>; -+ ddr3a5_ddr4a8_de-skew = <3>; -+ ddr3a4_ddr4a5_de-skew = <2>; -+ ddr3a7_ddr4a11_de-skew = <3>; -+ ddr3a6_ddr4a7_de-skew = <2>; -+ ddr3a9_ddr4a0_de-skew = <2>; -+ ddr3a8_ddr4a13_de-skew = <1>; -+ ddr3a11_ddr4a3_de-skew = <2>; -+ ddr3a10_ddr4cs0_de-skew = <2>; -+ ddr3a13_ddr4a2_de-skew = <1>; -+ ddr3a12_ddr4ba1_de-skew = <2>; -+ ddr3a15_ddr4odt0_de-skew = <3>; -+ ddr3a14_ddr4a1_de-skew = <2>; -+ ddr3ba1_ddr4a15_de-skew = <2>; -+ ddr3ba0_ddr4bg0_de-skew = <4>; -+ ddr3ras_ddr4cke_de-skew = <4>; -+ ddr3ba2_ddr4ba0_de-skew = <3>; -+ ddr3we_ddr4bg1_de-skew = <2>; -+ ddr3cas_ddr4a12_de-skew = <2>; -+ ddr3ckn_ddr4ckn_de-skew = <11>; -+ ddr3ckp_ddr4ckp_de-skew = <11>; -+ ddr3cke_ddr4a16_de-skew = <2>; -+ ddr3odt0_ddr4a14_de-skew = <4>; -+ ddr3cs0_ddr4act_de-skew = <4>; -+ ddr3reset_ddr4reset_de-skew = <7>; -+ ddr3cs1_ddr4cs1_de-skew = <7>; -+ ddr3odt1_ddr4odt1_de-skew = <7>; -+ -+ /* DATA de-skew -+ * RX one step is 25.1ps, range 0-15 -+ * TX one step is 47.8ps, range 0-15 -+ */ -+ cs0_dm0_rx_de-skew = <12>; -+ cs0_dm0_tx_de-skew = <10>; -+ cs0_dq0_rx_de-skew = <12>; -+ cs0_dq0_tx_de-skew = <10>; -+ cs0_dq1_rx_de-skew = <12>; -+ cs0_dq1_tx_de-skew = <10>; -+ cs0_dq2_rx_de-skew = <12>; -+ cs0_dq2_tx_de-skew = <10>; -+ cs0_dq3_rx_de-skew = <12>; -+ cs0_dq3_tx_de-skew = <10>; -+ cs0_dq4_rx_de-skew = <12>; -+ cs0_dq4_tx_de-skew = <10>; -+ cs0_dq5_rx_de-skew = <12>; -+ cs0_dq5_tx_de-skew = <10>; -+ cs0_dq6_rx_de-skew = <12>; -+ cs0_dq6_tx_de-skew = <10>; -+ cs0_dq7_rx_de-skew = <12>; -+ cs0_dq7_tx_de-skew = <10>; -+ cs0_dqs0_rx_de-skew = <10>; -+ cs0_dqs0p_tx_de-skew = <12>; -+ cs0_dqs0n_tx_de-skew = <12>; -+ -+ cs0_dm1_rx_de-skew = <10>; -+ cs0_dm1_tx_de-skew = <8>; -+ cs0_dq8_rx_de-skew = <10>; -+ cs0_dq8_tx_de-skew = <8>; -+ cs0_dq9_rx_de-skew = <10>; -+ cs0_dq9_tx_de-skew = <8>; -+ cs0_dq10_rx_de-skew = <10>; -+ cs0_dq10_tx_de-skew = <8>; -+ cs0_dq11_rx_de-skew = <10>; -+ cs0_dq11_tx_de-skew = <8>; -+ cs0_dq12_rx_de-skew = <10>; -+ cs0_dq12_tx_de-skew = <8>; -+ cs0_dq13_rx_de-skew = <10>; -+ cs0_dq13_tx_de-skew = <8>; -+ cs0_dq14_rx_de-skew = <10>; -+ cs0_dq14_tx_de-skew = <8>; -+ cs0_dq15_rx_de-skew = <10>; -+ cs0_dq15_tx_de-skew = <8>; -+ cs0_dqs1_rx_de-skew = <9>; -+ cs0_dqs1p_tx_de-skew = <10>; -+ cs0_dqs1n_tx_de-skew = <10>; -+ -+ cs0_dm2_rx_de-skew = <10>; -+ cs0_dm2_tx_de-skew = <9>; -+ cs0_dq16_rx_de-skew = <10>; -+ cs0_dq16_tx_de-skew = <9>; -+ cs0_dq17_rx_de-skew = <10>; -+ cs0_dq17_tx_de-skew = <9>; -+ cs0_dq18_rx_de-skew = <10>; -+ cs0_dq18_tx_de-skew = <9>; -+ cs0_dq19_rx_de-skew = <10>; -+ cs0_dq19_tx_de-skew = <9>; -+ cs0_dq20_rx_de-skew = <10>; -+ cs0_dq20_tx_de-skew = <9>; -+ cs0_dq21_rx_de-skew = <10>; -+ cs0_dq21_tx_de-skew = <9>; -+ cs0_dq22_rx_de-skew = <10>; -+ cs0_dq22_tx_de-skew = <9>; -+ cs0_dq23_rx_de-skew = <10>; -+ cs0_dq23_tx_de-skew = <9>; -+ cs0_dqs2_rx_de-skew = <9>; -+ cs0_dqs2p_tx_de-skew = <11>; -+ cs0_dqs2n_tx_de-skew = <11>; -+ -+ cs0_dm3_rx_de-skew = <7>; -+ cs0_dm3_tx_de-skew = <7>; -+ cs0_dq24_rx_de-skew = <7>; -+ cs0_dq24_tx_de-skew = <7>; -+ cs0_dq25_rx_de-skew = <7>; -+ cs0_dq25_tx_de-skew = <7>; -+ cs0_dq26_rx_de-skew = <7>; -+ cs0_dq26_tx_de-skew = <7>; -+ cs0_dq27_rx_de-skew = <7>; -+ cs0_dq27_tx_de-skew = <7>; -+ cs0_dq28_rx_de-skew = <7>; -+ cs0_dq28_tx_de-skew = <7>; -+ cs0_dq29_rx_de-skew = <7>; -+ cs0_dq29_tx_de-skew = <7>; -+ cs0_dq30_rx_de-skew = <7>; -+ cs0_dq30_tx_de-skew = <7>; -+ cs0_dq31_rx_de-skew = <7>; -+ cs0_dq31_tx_de-skew = <7>; -+ cs0_dqs3_rx_de-skew = <7>; -+ cs0_dqs3p_tx_de-skew = <10>; -+ cs0_dqs3n_tx_de-skew = <10>; -+ -+ cs1_dm0_rx_de-skew = <7>; -+ cs1_dm0_tx_de-skew = <8>; -+ cs1_dq0_rx_de-skew = <7>; -+ cs1_dq0_tx_de-skew = <8>; -+ cs1_dq1_rx_de-skew = <7>; -+ cs1_dq1_tx_de-skew = <8>; -+ cs1_dq2_rx_de-skew = <7>; -+ cs1_dq2_tx_de-skew = <8>; -+ cs1_dq3_rx_de-skew = <7>; -+ cs1_dq3_tx_de-skew = <8>; -+ cs1_dq4_rx_de-skew = <7>; -+ cs1_dq4_tx_de-skew = <8>; -+ cs1_dq5_rx_de-skew = <7>; -+ cs1_dq5_tx_de-skew = <8>; -+ cs1_dq6_rx_de-skew = <7>; -+ cs1_dq6_tx_de-skew = <8>; -+ cs1_dq7_rx_de-skew = <7>; -+ cs1_dq7_tx_de-skew = <8>; -+ cs1_dqs0_rx_de-skew = <6>; -+ cs1_dqs0p_tx_de-skew = <9>; -+ cs1_dqs0n_tx_de-skew = <9>; -+ -+ cs1_dm1_rx_de-skew = <7>; -+ cs1_dm1_tx_de-skew = <7>; -+ cs1_dq8_rx_de-skew = <7>; -+ cs1_dq8_tx_de-skew = <8>; -+ cs1_dq9_rx_de-skew = <7>; -+ cs1_dq9_tx_de-skew = <7>; -+ cs1_dq10_rx_de-skew = <7>; -+ cs1_dq10_tx_de-skew = <8>; -+ cs1_dq11_rx_de-skew = <7>; -+ cs1_dq11_tx_de-skew = <7>; -+ cs1_dq12_rx_de-skew = <7>; -+ cs1_dq12_tx_de-skew = <8>; -+ cs1_dq13_rx_de-skew = <7>; -+ cs1_dq13_tx_de-skew = <7>; -+ cs1_dq14_rx_de-skew = <7>; -+ cs1_dq14_tx_de-skew = <8>; -+ cs1_dq15_rx_de-skew = <7>; -+ cs1_dq15_tx_de-skew = <7>; -+ cs1_dqs1_rx_de-skew = <7>; -+ cs1_dqs1p_tx_de-skew = <9>; -+ cs1_dqs1n_tx_de-skew = <9>; -+ -+ cs1_dm2_rx_de-skew = <7>; -+ cs1_dm2_tx_de-skew = <8>; -+ cs1_dq16_rx_de-skew = <7>; -+ cs1_dq16_tx_de-skew = <8>; -+ cs1_dq17_rx_de-skew = <7>; -+ cs1_dq17_tx_de-skew = <8>; -+ cs1_dq18_rx_de-skew = <7>; -+ cs1_dq18_tx_de-skew = <8>; -+ cs1_dq19_rx_de-skew = <7>; -+ cs1_dq19_tx_de-skew = <8>; -+ cs1_dq20_rx_de-skew = <7>; -+ cs1_dq20_tx_de-skew = <8>; -+ cs1_dq21_rx_de-skew = <7>; -+ cs1_dq21_tx_de-skew = <8>; -+ cs1_dq22_rx_de-skew = <7>; -+ cs1_dq22_tx_de-skew = <8>; -+ cs1_dq23_rx_de-skew = <7>; -+ cs1_dq23_tx_de-skew = <8>; -+ cs1_dqs2_rx_de-skew = <6>; -+ cs1_dqs2p_tx_de-skew = <9>; -+ cs1_dqs2n_tx_de-skew = <9>; -+ -+ cs1_dm3_rx_de-skew = <7>; -+ cs1_dm3_tx_de-skew = <7>; -+ cs1_dq24_rx_de-skew = <7>; -+ cs1_dq24_tx_de-skew = <8>; -+ cs1_dq25_rx_de-skew = <7>; -+ cs1_dq25_tx_de-skew = <7>; -+ cs1_dq26_rx_de-skew = <7>; -+ cs1_dq26_tx_de-skew = <7>; -+ cs1_dq27_rx_de-skew = <7>; -+ cs1_dq27_tx_de-skew = <7>; -+ cs1_dq28_rx_de-skew = <7>; -+ cs1_dq28_tx_de-skew = <7>; -+ cs1_dq29_rx_de-skew = <7>; -+ cs1_dq29_tx_de-skew = <7>; -+ cs1_dq30_rx_de-skew = <7>; -+ cs1_dq30_tx_de-skew = <7>; -+ cs1_dq31_rx_de-skew = <7>; -+ cs1_dq31_tx_de-skew = <7>; -+ cs1_dqs3_rx_de-skew = <7>; -+ cs1_dqs3p_tx_de-skew = <9>; -+ cs1_dqs3n_tx_de-skew = <9>; -+ }; -+}; - -diff --git a/arch/arm64/boot/dts/rockchip/rk3318-box.dts b/arch/arm64/boot/dts/rockchip/rk3318-box.dts -new file mode 100644 -index 00000000000..28acf1fe127 ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3318-box.dts -@@ -0,0 +1,736 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Copyright (c) 2020 Paolo Sabatino -+ */ -+ -+/dts-v1/; -+#include "dt-bindings/pwm/pwm.h" -+#include "dt-bindings/input/input.h" -+#include "rk3328.dtsi" -+#include "rk3318-dram-default-timing.dtsi" -+ -+/ { -+ model = "Rockchip RK3318 BOX"; -+ compatible = "rockchip,rk3318-box", "rockchip,rk3328-box", "rockchip,rk3328"; -+ -+ aliases { -+ mmc0 = &sdmmc; -+ mmc1 = &sdio; -+ mmc2 = &emmc; -+ mmc3 = &sdmmc_ext; -+ mmc4 = &sdio_ext; -+ }; -+ -+ /delete-node/ opp-table-0; -+ /delete-node/ gpu-opp-table; -+ -+ cpu0_opp_table: opp_table0 { -+ compatible = "operating-points-v2"; -+ opp-shared; -+ -+ opp-600000000 { -+ opp-hz = /bits/ 64 <600000000>; -+ opp-microvolt = <950000>; -+ clock-latency-ns = <40000>; -+ opp-suspend; -+ }; -+ opp-816000000 { -+ opp-hz = /bits/ 64 <816000000>; -+ opp-microvolt = <1000000>; -+ clock-latency-ns = <40000>; -+ }; -+ opp-1008000000 { -+ opp-hz = /bits/ 64 <1008000000>; -+ opp-microvolt = <1100000>; -+ clock-latency-ns = <40000>; -+ }; -+ opp-1200000000 { -+ opp-hz = /bits/ 64 <1200000000>; -+ opp-microvolt = <1200000>; -+ clock-latency-ns = <40000>; -+ status = "disabled"; -+ }; -+ opp-1296000000 { -+ opp-hz = /bits/ 64 <1296000000>; -+ opp-microvolt = <1275000>; -+ clock-latency-ns = <40000>; -+ status = "disabled"; -+ }; -+ }; -+ -+ gpu_opp_table: gpu-opp-table { -+ compatible = "operating-points-v2"; -+ -+ opp-200000000 { -+ opp-hz = /bits/ 64 <200000000>; -+ opp-microvolt = <1000000 950000 1200000>; -+ }; -+ -+ opp-300000000 { -+ opp-hz = /bits/ 64 <300000000>; -+ opp-microvolt = <1050000 950000 1200000>; -+ }; -+ -+ opp-400000000 { -+ opp-hz = /bits/ 64 <400000000>; -+ opp-microvolt = <1050000 950000 1200000>; -+ }; -+ -+ opp-500000000 { -+ opp-hz = /bits/ 64 <500000000>; -+ opp-microvolt = <1100000 950000 1200000>; -+ }; -+ }; -+ -+ chosen { -+ stdout-path = "serial2:1500000n8"; -+ }; -+ -+ adc_keys: adc-keys { -+ -+ compatible = "adc-keys"; -+ io-channels = <&saradc 0>; -+ io-channel-names = "buttons"; -+ keyup-threshold-microvolt = <1800000>; -+ poll-interval = <100>; -+ -+ recovery { -+ label = "recovery"; -+ linux,code = ; -+ press-threshold-microvolt = <17000>; -+ }; -+ -+ }; -+ -+ xin32k: xin32k { -+ compatible = "fixed-clock"; -+ clock-frequency = <32768>; -+ clock-output-names = "xin32k"; -+ #clock-cells = <0>; -+ }; -+ -+ gmac_clkin: gmac-clkin { -+ compatible = "fixed-clock"; -+ clock-frequency = <125000000>; -+ clock-output-names = "gmac_clkin"; -+ #clock-cells = <0x00>; -+ }; -+ -+ regulators { -+ compatible = "simple-bus"; -+ #address-cells = <0x01>; -+ #size-cells = <0x00>; -+ -+ vcc_18: regulator@0 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vccio_1v8"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+ }; -+ -+ vcc_io: regulator@1 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vccio_3v3"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ }; -+ }; -+ -+ vcc_phy: vcc-phy-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc_phy"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ vcc_sys: vcc-sys { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ }; -+ -+ vcc_sd: sdmmc-regulator { -+ compatible = "regulator-fixed"; -+ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc0m1_pin>; -+ regulator-name = "vcc_sd"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&vcc_io>; -+ }; -+ -+ /* -+ * USB3 vbus -+ */ -+ vcc_host_vbus: vcc-host-vbus { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&usb30_host_drv>; -+ regulator-name = "vcc_host_vbus"; -+ regulator-always-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc_sys>; -+ }; -+ -+ /* -+ * USB2 OTG vbus -+ */ -+ vcc_otg_vbus: vcc-otg-vbus { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&usb20_host_drv>; -+ regulator-name = "vcc_otg_vbus"; -+ regulator-always-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc_sys>; -+ }; -+ -+ vdd_arm: vdd-arm { -+ compatible = "pwm-regulator"; -+ pwms = <&pwm0 0 5000 PWM_POLARITY_INVERTED>; -+ pwm-supply = <&vcc_sys>; -+ regulator-name = "vdd_arm"; -+ regulator-min-microvolt = <950000>; -+ regulator-max-microvolt = <1400000>; -+ regulator-ramp-delay = <12500>; -+ regulator-settling-time-up-us = <250>; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ vdd_logic: vdd-log { -+ compatible = "pwm-regulator"; -+ pwms = <&pwm1 0 5000 PWM_POLARITY_INVERTED>; -+ pwm-supply = <&vcc_sys>; -+ regulator-name = "vdd_log"; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <1300000>; -+ regulator-ramp-delay = <12500>; -+ regulator-settling-time-up-us = <250>; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ gpio_led: gpio-leds { -+ compatible = "gpio-leds"; -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&working_led>; -+ -+ working { -+ gpios = <&gpio2 RK_PC7 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "timer"; -+ default-state = "on"; -+ }; -+ -+ }; -+ -+ ir-receiver { -+ compatible = "gpio-ir-receiver"; -+ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; -+ pinctrl-0 = <&ir_int>; -+ pinctrl-names = "default"; -+ }; -+ -+ sdio_pwrseq: sdio-pwrseq { -+ compatible = "mmc-pwrseq-simple"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&wifi_enable_h>; -+ -+ /* -+ * On the module itself this is one of these (depending -+ * on the actual card populated): -+ * - SDIO_RESET_L_WL_REG_ON -+ * - PDN (power down when low) -+ */ -+ reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; -+ }; -+ -+ /* -+ wireless-bluetooth { -+ compatible = "bluetooth-platdata"; -+ uart_rts_gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_LOW>; -+ pinctrl-names = "default", "rts_gpio"; -+ pinctrl-0 = <&uart0_rts>; -+ pinctrl-1 = <&uart0_rts_gpio>; -+ BT,power_gpio = <&gpio1 RK_PC5 GPIO_ACTIVE_HIGH>; -+ BT,wake_host_irq = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>; -+ }; -+ -+ wireless-wlan { -+ compatible = "wlan-platdata"; -+ rockchip,grf = <&grf>; -+ wifi_chip_type = "ap6330"; -+ sdio_vref = <1800>; -+ WIFI,host_wake_irq = <&gpio1 RK_PC3 GPIO_ACTIVE_HIGH>; -+ }; -+ */ -+ -+ fd628_dev { -+ compatible = "fd628_dev"; -+ fd628_gpio_clk = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>; -+ fd628_gpio_dat = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>; -+ status = "okay"; -+ }; -+ -+ analog-sound { -+ compatible = "simple-audio-card"; -+ simple-audio-card,format = "i2s"; -+ simple-audio-card,mclk-fs = <256>; -+ simple-audio-card,name = "ANALOG"; -+ -+ simple-audio-card,cpu { -+ sound-dai = <&i2s1>; -+ }; -+ -+ simple-audio-card,codec { -+ sound-dai = <&codec>; -+ }; -+ }; -+ -+ hdmi-sound { -+ compatible = "simple-audio-card"; -+ simple-audio-card,format = "i2s"; -+ simple-audio-card,mclk-fs = <128>; -+ simple-audio-card,name = "HDMI"; -+ -+ simple-audio-card,cpu { -+ sound-dai = <&i2s0>; -+ }; -+ -+ simple-audio-card,codec { -+ sound-dai = <&hdmi>; -+ }; -+ }; -+ -+ /* -+ * This node is a duplicate of sdmmc_ext: most common board do not use sdmmc_ext -+ * controller, so it is left unused. Some other boards use it as sdio controller -+ * for wifi and some others use it as sdcard controller. -+ * To handle the most critical situation, the controller will be configured as -+ * sdcard controller by default. An overlay can be set to disable the sdmmc_ext -+ * node and enable this sdio_ext in case wifi chips are attached to this. -+ */ -+ sdio_ext: mmc@ff5f0000 { -+ compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc"; -+ reg = <0x0 0xff5f0000 0x0 0x4000>; -+ interrupts = ; -+ clocks = <&cru HCLK_SDMMC_EXT>, <&cru SCLK_SDMMC_EXT>, -+ <&cru SCLK_SDMMC_EXT_DRV>, <&cru SCLK_SDMMC_EXT_SAMPLE>; -+ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; -+ fifo-depth = <0x100>; -+ max-frequency = <150000000>; -+ resets = <&cru SRST_SDMMCEXT>; -+ reset-names = "reset"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ bus-width = <4>; -+ cap-sd-highspeed; -+ cap-sdio-irq; -+ disable-wp; -+ keep-power-in-suspend; -+ mmc-pwrseq = <>; -+ non-removable; -+ num-slots = <1>; -+ pinctrl-0 = <&sdmmc0ext_cmd &sdmmc0ext_clk &sdmmc0ext_bus4>; -+ pinctrl-names = "default"; -+ supports-sdio; -+ status = "disabled"; -+ }; -+ -+}; -+ -+&dfi { -+ status = "okay"; -+}; -+ -+&dmc { -+ center-supply = <&vdd_logic>; -+ ddr_timing = <&ddr_timing>; -+ status = "disabled"; -+}; -+ -+&codec { -+ status = "okay"; -+ mute-gpios = <&grf_gpio 0 GPIO_ACTIVE_LOW>; -+}; -+ -+&cpu0 { -+ cpu-supply = <&vdd_arm>; -+}; -+ -+&cpu1 { -+ cpu-supply = <&vdd_arm>; -+}; -+ -+&cpu2 { -+ cpu-supply = <&vdd_arm>; -+}; -+ -+&cpu3 { -+ cpu-supply = <&vdd_arm>; -+}; -+ -+&display_subsystem { -+ status = "okay"; -+}; -+ -+&emmc { -+ -+ supports-emmc; -+ no-sdio; -+ no-sd; -+ cap-mmc-highspeed; -+ disable-wp; -+ non-removable; -+ bus-width = <8>; -+ num-slots = <0x01>; -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; -+ -+ vmmc-supply = <&vcc_io>; -+ vqmmc-supply = <&vcc_18>; -+ -+ status = "okay"; -+}; -+ -+&sdmmc { -+ bus-width = <4>; -+ cap-mmc-highspeed; -+ cap-sd-highspeed; -+ card-detect-delay = <500>; -+ cd-gpios = <&gpio1 RK_PA5 GPIO_ACTIVE_LOW>; -+ disable-wp; -+ no-sdio; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; -+ supports-sd; -+ status = "okay"; -+ vmmc-supply = <&vcc_sd>; -+}; -+ -+&sdio { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ bus-width = <4>; -+ cap-sd-highspeed; -+ cap-sdio-irq; -+ disable-wp; -+ keep-power-in-suspend; -+ mmc-pwrseq = <&sdio_pwrseq>; -+ non-removable; -+ num-slots = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_cmd &sdmmc1_clk>; -+ supports-sdio; -+ status = "okay"; -+}; -+ -+/* -+ * sdmmc_ext is configured as sdcard controller and enabled by default. -+ * In this way boards which have the sdcard attached to sdmmc_ext will work -+ * by default. In case the controller is not attached to anything, the -+ * kernel will just autodetect and give up. -+ */ -+&sdmmc_ext { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ bus-width = <4>; -+ cap-mmc-highspeed; -+ cap-sd-highspeed; -+ card-detect-delay = <500>; -+ cd-gpios = <&gpio3 RK_PA1 GPIO_ACTIVE_LOW>; -+ disable-wp; -+ no-sdio; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc0ext_clk &sdmmc0ext_cmd &sdmmc0ext_dectn &sdmmc0ext_bus4>; -+ supports-sd; -+ status = "okay"; -+ vmmc-supply = <&vcc_sd>; -+}; -+ -+&gmac2phy { -+ phy-supply = <&vcc_phy>; -+ -+ phy-mode = "rmii"; -+ -+ clock_in_out = "output"; -+ assigned-clocks = <&cru SCLK_MAC2PHY>; -+ assigned-clock-rate = <50000000>; -+ assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>; -+ tx_delay = <0x30>; -+ rx_delay = <0x10>; -+ -+ status = "okay"; -+ -+}; -+ -+&gpu { -+ status = "okay"; -+ mali-supply = <&vdd_logic>; -+}; -+ -+/* -+&h265e { -+ status = "okay"; -+}; -+*/ -+ -+&h265e_mmu { -+ status = "okay"; -+}; -+ -+&hdmi { -+ status = "okay"; -+}; -+ -+&spdif { -+ pinctrl-0 = <&spdifm0_tx>; -+ status = "okay"; -+}; -+ -+&spdif_out { -+ status = "okay"; -+}; -+ -+&spdif_sound { -+ status = "okay"; -+}; -+ -+&hdmiphy { -+ status = "okay"; -+}; -+ -+&i2s0 { -+ status = "okay"; -+}; -+ -+&i2s1 { -+ status = "okay"; -+}; -+ -+&io_domains { -+ status = "okay"; -+ -+ vccio1-supply = <&vcc_io>; -+ vccio2-supply = <&vcc_18>; -+ vccio3-supply = <&vcc_io>; -+ vccio4-supply = <&vcc_18>; -+ vccio5-supply = <&vcc_io>; -+ vccio6-supply = <&vcc_io>; -+ pmuio-supply = <&vcc_io>; -+}; -+ -+&pinctrl { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&clk_32k_out>; -+ -+ clk_32k { -+ clk_32k_out: clk-32k-out { -+ rockchip,pins = <1 RK_PD4 1 &pcfg_pull_none>; -+ }; -+ }; -+ -+ leds { -+ working_led: working-led { -+ rockchip,pins = <2 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none_2ma>; -+ }; -+ }; -+ -+ ir { -+ ir_int: ir-int { -+ rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ pmic { -+ pmic_int_l: pmic-int-l { -+ rockchip,pins = <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ -+ sdio-pwrseq { -+ wifi_enable_h: wifi-enable-h { -+ rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none_4ma>;/*, -+ <1 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none_4ma>;*/ -+ }; -+ }; -+ -+ usb2 { -+ usb20_host_drv: usb20-host-drv { -+ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ usb3 { -+ usb30_host_drv: usb30-host-drv { -+ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ wireless-wlan { -+ -+ /* -+ * SDIO host wake interrupt on YX_RK3328 board (sdio is attached to -+ * regular mmc controller mmc@ff510000) -+ */ -+ sdio_host_wake: sdio-host-wake { -+ rockchip,pins = <1 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ /* -+ * SDIO host wake interrupt on X88_PRO_B board (sdio is attached to -+ * alternative mmc controller mmc@ff5f0000) -+ */ -+ sdio_host_wake_ext: sdio-host-wake-ext { -+ rockchip,pins = <3 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ }; -+ -+}; -+ -+/* -+&vdec { -+ status = "okay"; -+ vcodec-supply = <&vdd_logic>; -+}; -+*/ -+ -+&vdec_mmu { -+ status = "okay"; -+}; -+ -+&threshold { -+ temperature = <80000>; /* millicelsius */ -+}; -+ -+&target { -+ temperature = <95000>; /* millicelsius */ -+}; -+ -+&soc_crit { -+ temperature = <100000>; /* millicelsius */ -+}; -+ -+&tsadc { -+ rockchip,hw-tshut-mode = <0>; -+ rockchip,hw-tshut-polarity = <0>; -+ status = "okay"; -+}; -+ -+&uart0 { -+ -+ status = "okay"; -+ -+}; -+ -+&uart2 { -+ /delete-property/ dmas; -+ /delete-property/ dma-names; -+ -+ status = "okay"; -+}; -+ -+&u2phy { -+ status = "okay"; -+ -+ u2phy_host: host-port { -+ status = "okay"; -+ }; -+ -+ u2phy_otg: otg-port { -+ status = "okay"; -+ }; -+}; -+ -+&usb20_otg { -+ dr_mode = "host"; -+ status = "okay"; -+}; -+ -+&usb_host0_ehci { -+ status = "okay"; -+}; -+ -+&usb_host0_ohci { -+ status = "okay"; -+}; -+ -+&usbdrd3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ dr_mode = "host"; -+ status = "okay"; -+}; -+ -+&vop { -+ status = "okay"; -+}; -+ -+&vop_mmu { -+ status = "okay"; -+}; -+ -+&vpu { -+ status = "okay"; -+ vcodec-supply = <&vdd_logic>; -+}; -+ -+&vpu_mmu { -+ status = "okay"; -+}; -+ -+/* -+&vepu { -+ status = "okay"; -+}; -+*/ -+ -+&vepu_mmu { -+ status = "okay"; -+}; -+ -+&saradc { -+ vref-supply = <&vcc_18>; -+ status = "okay"; -+}; -+ -+/* -+&rga { -+ status = "okay"; -+}; -+*/ -+ -+&pwm0 { -+ status = "okay"; -+}; -+ -+&pwm1 { -+ status = "okay"; -+}; -+ -+&hdmi_sound { -+ status = "okay"; -+}; -+ -+&analog_sound { -+ status = "okay"; -+}; diff --git a/patch/kernel/archive/rockchip64-6.1/add-board-xiaobao-nas-dts.patch b/patch/kernel/archive/rockchip64-6.1/add-board-xiaobao-nas-dts.patch deleted file mode 100644 index a82ffbdd2b5c..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/add-board-xiaobao-nas-dts.patch +++ /dev/null @@ -1,779 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-xiaobao-nas.dts b/arch/arm64/boot/dts/rockchip/rk3399-xiaobao-nas.dts -new file mode 100644 ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3399-xiaobao-nas.dts -@@ -0,0 +1,774 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+ -+/dts-v1/; -+#include -+#include -+#include -+#include "rk3399.dtsi" -+#include "rk3399-opp.dtsi" -+ -+/ { -+ model = "Codinge Xiaobao NAS"; -+ compatible = "codinge,xiaobao-nas", "rockchip,rk3399"; -+ -+ aliases { -+ mmc0 = &sdmmc; -+ mmc1 = &sdhci; -+ mmc2 = &sdio0; -+ }; -+ -+ chosen { -+ stdout-path = "serial2:1500000n8"; -+ }; -+ -+ clkin_gmac: external-gmac-clock { -+ compatible = "fixed-clock"; -+ clock-frequency = <125000000>; -+ clock-output-names = "clkin_gmac"; -+ #clock-cells = <0>; -+ }; -+ -+ sdio_pwrseq: sdio-pwrseq { -+ compatible = "mmc-pwrseq-simple"; -+ clocks = <&rk808 1>; -+ clock-names = "ext_clock"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&wifi_enable_h>; -+ reset-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_LOW>; -+ }; -+ -+ vcc_dc: vcc-dc { -+ compatible = "regulator-fixed"; -+ regulator-name = "dc_12v"; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ vcc_12v: vcc-12v { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc_12v"; -+ regulator-always-on; -+ regulator-min-microvolt = <12000000>; -+ regulator-max-microvolt = <12000000>; -+ }; -+ -+ vcc5v0_sys: vcc5v0-sys { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v0_sys"; -+ regulator-always-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ }; -+ -+ vcc1v8_s3: vcc1v8-s3 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc1v8_s3"; -+ regulator-always-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ vin-supply = <&vcc_1v8>; -+ }; -+ -+ vcc3v3_sys: vcc3v3-sys { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc3v3_sys"; -+ regulator-always-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ }; -+ -+ vcc5v0_host: vcc5v0-host-regulator { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio1 RK_PD0 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vcc5v0_host_en>; -+ regulator-name = "vcc5v0_host"; -+ }; -+ -+ vcc_sd: vcc-sd { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc_sd"; -+ enable-active-high; -+ gpio = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vcc_sd_h>; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ }; -+ -+ vcc5v0_typec: vcc5v0-typec { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio4 RK_PD4 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vcc5v0_typec_en>; -+ regulator-name = "vcc5v0_typec"; -+ regulator-always-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc_12v>; -+ }; -+ -+ vcc3v3_pcie: vcc3v3-pcie-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc3v3_pcie"; -+ enable-active-high; -+ gpio = <&gpio4 RK_PD6 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie_pwr_en>; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&vcc3v3_sys>; -+ }; -+ -+ vcc_lan: vcc3v3-phy-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc_lan"; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ adc-keys { -+ compatible = "adc-keys"; -+ io-channels = <&saradc 1>; -+ io-channel-names = "buttons"; -+ keyup-threshold-microvolt = <1800000>; -+ poll-interval = <100>; -+ -+ recovery { -+ label = "Recovery"; -+ linux,code = <0x168>; -+ press-threshold-microvolt = <18000>; -+ }; -+ }; -+ -+ gpio-leds { -+ compatible = "gpio-leds"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&leds_pins>; -+ -+ led1: system-led1 { -+ gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; -+ label = "system_led1"; -+ retain-state-suspended; -+ default-state = "on"; -+ }; -+ -+ led2: system-led2 { -+ gpios = <&gpio2 RK_PA5 GPIO_ACTIVE_HIGH>; -+ label = "system_led2"; -+ retain-state-suspended; -+ default-state = "off"; -+ }; -+ }; -+ -+ pwm-fan { -+ compatible = "pwm-fan"; -+ pwms = <&pwm1 0 50000 0>; -+ }; -+}; -+ -+&cpu_l0 { -+ cpu-supply = <&vdd_cpu_l>; -+}; -+ -+&cpu_l1 { -+ cpu-supply = <&vdd_cpu_l>; -+}; -+ -+&cpu_l2 { -+ cpu-supply = <&vdd_cpu_l>; -+}; -+ -+&cpu_l3 { -+ cpu-supply = <&vdd_cpu_l>; -+}; -+ -+&cpu_b0 { -+ cpu-supply = <&vdd_cpu_b>; -+}; -+ -+&cpu_b1 { -+ cpu-supply = <&vdd_cpu_b>; -+}; -+ -+&emmc_phy { -+ status = "okay"; -+}; -+ -+&gmac { -+ assigned-clocks = <&cru SCLK_RMII_SRC>; -+ assigned-clock-parents = <&clkin_gmac>; -+ clock_in_out = "input"; -+ phy-supply = <&vcc_lan>; -+ phy-mode = "rgmii"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&rgmii_pins>; -+ snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; -+ snps,reset-active-low; -+ snps,reset-delays-us = <0 10000 50000>; -+ tx_delay = <0x28>; -+ rx_delay = <0x11>; -+ status = "okay"; -+}; -+ -+&gpu { -+ mali-supply = <&vdd_gpu>; -+ status = "okay"; -+}; -+ -+&hdmi { -+ ddc-i2c-bus = <&i2c3>; -+ ddc-i2c-scl-high-time-ns = <9625>; -+ ddc-i2c-scl-low-time-ns = <10000>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hdmi_cec>; -+ status = "okay"; -+}; -+ -+&hdmi_sound { -+ status = "okay"; -+}; -+ -+&i2c0 { -+ clock-frequency = <400000>; -+ i2c-scl-rising-time-ns = <168>; -+ i2c-scl-falling-time-ns = <4>; -+ status = "okay"; -+ -+ rk808: pmic@1b { -+ compatible = "rockchip,rk808"; -+ reg = <0x1b>; -+ interrupt-parent = <&gpio1>; -+ interrupts = <21 IRQ_TYPE_LEVEL_LOW>; -+ #clock-cells = <1>; -+ clock-output-names = "xin32k", "rk808-clkout2"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pmic_int_l>; -+ rockchip,system-power-controller; -+ wakeup-source; -+ -+ vcc1-supply = <&vcc3v3_sys>; -+ vcc2-supply = <&vcc3v3_sys>; -+ vcc3-supply = <&vcc3v3_sys>; -+ vcc4-supply = <&vcc3v3_sys>; -+ vcc6-supply = <&vcc3v3_sys>; -+ vcc7-supply = <&vcc3v3_sys>; -+ vcc8-supply = <&vcc3v3_sys>; -+ vcc9-supply = <&vcc3v3_sys>; -+ vcc10-supply = <&vcc3v3_sys>; -+ vcc11-supply = <&vcc3v3_sys>; -+ vcc12-supply = <&vcc3v3_sys>; -+ vddio-supply = <&vcc_3v0>; -+ -+ regulators { -+ vdd_center: DCDC_REG1 { -+ regulator-name = "vdd_center"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <750000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-ramp-delay = <6001>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_cpu_l: DCDC_REG2 { -+ regulator-name = "vdd_cpu_l"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <750000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-ramp-delay = <6001>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_ddr: DCDC_REG3 { -+ regulator-name = "vcc_ddr"; -+ regulator-always-on; -+ regulator-boot-on; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vcc_1v8: DCDC_REG4 { -+ regulator-name = "vcc_1v8"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vcc1v8_dvp: LDO_REG1 { -+ regulator-name = "vcc1v8_dvp"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vcca_1v8: LDO_REG2 { -+ regulator-name = "vcca_1v8"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vcc1v8_pmupll: LDO_REG3 { -+ regulator-name = "vcc1v8_pmupll"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vcc_sdio: LDO_REG4 { -+ regulator-name = "vcc_sdio"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3000000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3000000>; -+ }; -+ }; -+ -+ vcca3v0_codec: LDO_REG5 { -+ regulator-name = "vcca3v0_codec"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3000000>; -+ regulator-max-microvolt = <3000000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3000000>; -+ }; -+ }; -+ -+ vcc_1v5: LDO_REG6 { -+ regulator-name = "vcc_1v5"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1500000>; -+ regulator-max-microvolt = <1500000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1500000>; -+ }; -+ }; -+ -+ vcca1v8_codec: LDO_REG7 { -+ regulator-name = "vcca1v8_codec"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vcc_3v0: LDO_REG8 { -+ regulator-name = "vcc_3v0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3000000>; -+ regulator-max-microvolt = <3000000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3000000>; -+ }; -+ }; -+ -+ vcc3v3_s3: SWITCH_REG1 { -+ regulator-name = "vcc3v3_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc3v3_s0: SWITCH_REG2 { -+ regulator-name = "vcc3v3_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ }; -+ }; -+ -+ vdd_cpu_b: regulator@40 { -+ compatible = "silergy,syr827"; -+ reg = <0x40>; -+ fcs,suspend-voltage-selector = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vsel1_pin>; -+ regulator-name = "vdd_cpu_b"; -+ regulator-min-microvolt = <712500>; -+ regulator-max-microvolt = <1500000>; -+ regulator-ramp-delay = <1000>; -+ regulator-always-on; -+ regulator-boot-on; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_gpu: regulator@41 { -+ compatible = "silergy,syr828"; -+ reg = <0x41>; -+ fcs,suspend-voltage-selector = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vsel2_pin>; -+ regulator-name = "vdd_gpu"; -+ regulator-min-microvolt = <712500>; -+ regulator-max-microvolt = <1500000>; -+ regulator-ramp-delay = <1000>; -+ regulator-always-on; -+ regulator-boot-on; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ hym8563@51 { -+ compatible = "haoyu,hym8563"; -+ reg = <0x51>; -+ #clock-cells = <0>; -+ clock-frequency = <32768>; -+ clock-output-names = "xin32k"; -+ }; -+}; -+ -+&i2c3 { -+ i2c-scl-rising-time-ns = <450>; -+ i2c-scl-falling-time-ns = <15>; -+ status = "okay"; -+}; -+ -+&i2c4 { -+ clock-frequency = <400000>; -+ i2c-scl-rising-time-ns = <160>; -+ i2c-scl-falling-time-ns = <30>; -+ status = "okay"; -+ -+ typec-portc@22 { -+ compatible = "fcs,fusb302"; -+ reg = <0x22>; -+ interrupt-parent = <&gpio1>; -+ interrupts = ; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&fusb0_int>; -+ vbus-supply = <&vcc5v0_typec>; -+ }; -+}; -+ -+&i2s0 { -+ rockchip,capture-channels = <8>; -+ rockchip,playback-channels = <8>; -+ status = "okay"; -+}; -+ -+&i2s1 { -+ rockchip,capture-channels = <2>; -+ rockchip,playback-channels = <2>; -+ status = "okay"; -+}; -+ -+&i2s2 { -+ status = "okay"; -+}; -+ -+&io_domains { -+ status = "okay"; -+ -+ bt656-supply = <&vcc_3v0>; -+ audio-supply = <&vcca1v8_codec>; -+ sdmmc-supply = <&vcc_sdio>; -+ gpio1830-supply = <&vcc_3v0>; -+}; -+ -+&pcie_phy { -+ status = "okay"; -+ drive-impedance-ohm = <50>; -+}; -+ -+&pcie0 { -+ ep-gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_HIGH>; -+ num-lanes = <4>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie_clkreqnb_cpm &fn8274_en_h>; -+ status = "okay"; -+}; -+ -+&pmu_io_domains { -+ status = "okay"; -+ -+ pmu1830-supply = <&vcc_3v0>; -+}; -+ -+&pinctrl { -+ pcie { -+ fn8274_en_h: fn8274-en-h { -+ rockchip,pins = <4 RK_PD1 RK_FUNC_GPIO &pcfg_output_high>, -+ <4 RK_PD5 RK_FUNC_GPIO &pcfg_output_high>, -+ <1 RK_PC7 RK_FUNC_GPIO &pcfg_output_high>; -+ }; -+ -+ pcie_pwr_en: pcie-pwr-en { -+ rockchip,pins = <4 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ pmic { -+ pmic_int_l: pmic-int-l { -+ rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ -+ vsel1_pin: vsel1-pin { -+ rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ -+ vsel2_pin: vsel2-pin { -+ rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ }; -+ -+ usb2 { -+ vcc5v0_host_en: vcc5v0-host-en { -+ rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ vcc5v0_typec_en: vcc5v0-typec-en { -+ rockchip,pins = <4 RK_PD4 RK_FUNC_GPIO &pcfg_output_high>; -+ }; -+ }; -+ -+ vcc_sd { -+ vcc_sd_h: vcc-sd-h { -+ rockchip,pins = <0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ -+ fusb30x { -+ fusb0_int: fusb0-int { -+ rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ -+ sdio-pwrseq { -+ wifi_enable_h: wifi-enable-h { -+ rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ leds { -+ leds_pins: leds-pins { -+ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, -+ <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+}; -+ -+&pwm1 { -+ status = "okay"; -+}; -+ -+&saradc { -+ status = "okay"; -+}; -+ -+&sdio0 { -+ bus-width = <4>; -+ clock-frequency = <50000000>; -+ cap-sdio-irq; -+ cap-sd-highspeed; -+ keep-power-in-suspend; -+ mmc-pwrseq = <&sdio_pwrseq>; -+ non-removable; -+ num-slots = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>; -+ sd-uhs-sdr104; -+ status = "okay"; -+}; -+ -+&sdmmc { -+ bus-width = <4>; -+ cap-mmc-highspeed; -+ cap-sd-highspeed; -+ cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; -+ disable-wp; -+ max-frequency = <150000000>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc_clk &sdmmc_cd &sdmmc_cmd &sdmmc_bus4>; -+ vmmc-supply = <&vcc_sd>; -+ vqmmc-supply = <&vcc_sdio>; -+ status = "okay"; -+}; -+ -+&sdhci { -+ bus-width = <8>; -+ mmc-hs400-1_8v; -+ mmc-hs400-enhanced-strobe; -+ non-removable; -+ status = "okay"; -+}; -+ -+&spi1 { -+ status = "okay"; -+ -+ flash@0 { -+ compatible = "jedec,spi-nor"; -+ reg = <0x00>; -+ spi-max-frequency = <10000000>; -+ }; -+}; -+ -+&tcphy0 { -+ status = "okay"; -+}; -+ -+&tcphy1 { -+ status = "okay"; -+}; -+ -+&tsadc { -+ status = "okay"; -+ -+ /* tshut mode 0:CRU 1:GPIO */ -+ rockchip,hw-tshut-mode = <1>; -+ /* tshut polarity 0:LOW 1:HIGH */ -+ rockchip,hw-tshut-polarity = <1>; -+}; -+ -+&u2phy0 { -+ status = "okay"; -+}; -+ -+&u2phy0_otg { -+ status = "okay"; -+}; -+ -+&u2phy0_host { -+ phy-supply = <&vcc5v0_host>; -+ status = "okay"; -+}; -+ -+&u2phy1 { -+ status = "okay"; -+}; -+ -+&u2phy1_otg { -+ status = "okay"; -+}; -+ -+&u2phy1_host { -+ phy-supply = <&vcc5v0_host>; -+ status = "okay"; -+}; -+ -+&uart0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; -+ status = "okay"; -+}; -+ -+&uart2 { -+ status = "okay"; -+}; -+ -+&usb_host0_ehci { -+ status = "okay"; -+}; -+ -+&usb_host0_ohci { -+ status = "okay"; -+}; -+ -+&usb_host1_ehci { -+ status = "okay"; -+}; -+ -+&usb_host1_ohci { -+ status = "okay"; -+}; -+ -+&usbdrd3_0 { -+ status = "okay"; -+}; -+ -+&usbdrd_dwc3_0 { -+ status = "okay"; -+ dr_mode = "host"; -+}; -+ -+&usbdrd3_1 { -+ status = "okay"; -+}; -+ -+&usbdrd_dwc3_1 { -+ status = "okay"; -+ dr_mode = "host"; -+}; -+ -+&vopb { -+ status = "okay"; -+}; -+ -+&vopb_mmu { -+ status = "okay"; -+}; -+ -+&vopl { -+ status = "okay"; -+}; -+ -+&vopl_mmu { -+ status = "okay"; -+}; diff --git a/patch/kernel/archive/rockchip64-6.1/add-boards-to-dts-makefile.patch b/patch/kernel/archive/rockchip64-6.1/add-boards-to-dts-makefile.patch deleted file mode 100644 index 3e53e5873f56..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/add-boards-to-dts-makefile.patch +++ /dev/null @@ -1,27 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile -index 26661c7b7..1462ed38b 100644 ---- a/arch/arm64/boot/dts/rockchip/Makefile -+++ b/arch/arm64/boot/dts/rockchip/Makefile -@@ -1,4 +1,22 @@ - # SPDX-License-Identifier: GPL-2.0 -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-roc-pc.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock-pi-e.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3318-box.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-neo3-rev02.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2-rev00.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2-rev06.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2-rev20.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-orangepi-r1-plus.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-orangepi-r1-plus-lts.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-z28pro.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-kobol-helios64.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopi-m4v2.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopi-r4s.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-orangepi-4.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-orangepi-4-lts.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-roc-pc-plus.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-pi-4.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-tinker-2.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-evb.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-engicam-px30-core-ctouch2.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-engicam-px30-core-ctouch2-of10.dtb diff --git a/patch/kernel/archive/rockchip64-6.1/add-driver-for-Motorcomm-YT85xx+PHYs.patch b/patch/kernel/archive/rockchip64-6.1/add-driver-for-Motorcomm-YT85xx+PHYs.patch deleted file mode 100644 index dc98bcf6d502..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/add-driver-for-Motorcomm-YT85xx+PHYs.patch +++ /dev/null @@ -1,2202 +0,0 @@ -From 3b60e97e8cf8a1ae78ec68a2fed37cd763675e56 Mon Sep 17 00:00:00 2001 -From: baiywt -Date: Fri, 18 Feb 2022 16:38:43 +0800 -Subject: [PATCH] Add yt8531c support. -Adapted from orangepi-xunlong/openwrt - 600-Add-yt8531c-support.patch by schwar3kat ---- - drivers/net/phy/Kconfig | 5 + - drivers/net/phy/motorcomm.c | 1540 +++++++++++++++++++++++++++++++++ - drivers/net/phy/yt8614-phy.h | 491 +++++++++++ - include/linux/motorcomm_phy.h | 119 +++ - 5 files changed, 2156 insertions(+) - create mode 100644 drivers/net/phy/motorcomm.c - create mode 100644 drivers/net/phy/yt8614-phy.h - create mode 100644 include/linux/motorcomm_phy.h - -diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig -index ce030fcb1..ff4861847 100644 ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -297,6 +297,11 @@ config MICROSEMI_PHY - help - Currently supports VSC8514, VSC8530, VSC8531, VSC8540 and VSC8541 PHYs - -+config MOTORCOMM_PHY -+ tristate "Motorcomm PHYs" -+ help -+ Supports the YT8010, YT8510, YT8511, YT8512 YT8521 YT8531 PHYs. -+ - config NATIONAL_PHY - tristate "National Semiconductor PHYs" - help -diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c -new file mode 100644 -index 000000000..74eef3dfa ---- /dev/null -+++ b/drivers/net/phy/motorcomm.c -@@ -0,0 +1,1540 @@ -+/* -+ * drivers/net/phy/motorcomm.c -+ * -+ * Driver for Motorcomm PHYs -+ * -+ * Author: Leilei Zhao -+ * -+ * Copyright (c) 2019 Motorcomm, Inc. -+ * -+ * 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. -+ * -+ * Support : Motorcomm Phys: -+ * Giga phys: yt8511, yt8521 -+ * 100/10 Phys : yt8512, yt8512b, yt8510 -+ * Automotive 100Mb Phys : yt8010 -+ * Automotive 100/10 hyper range Phys: yt8510 -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifndef LINUX_VERSION_CODE -+#include -+#else -+#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) -+#endif -+/*for wol, 20210604*/ -+#include -+ -+#include "yt8614-phy.h" -+ -+/**** configuration section begin ***********/ -+ -+/* if system depends on ethernet packet to restore from sleep, please define this macro to 1 -+ * otherwise, define it to 0. -+ */ -+#define SYS_WAKEUP_BASED_ON_ETH_PKT 1 -+ -+/* to enable system WOL of phy, please define this macro to 1 -+ * otherwise, define it to 0. -+ */ -+#define YTPHY_ENABLE_WOL 0 -+ -+/* some GMAC need clock input from PHY, for eg., 125M, please enable this macro -+ * by degault, it is set to 0 -+ * NOTE: this macro will need macro SYS_WAKEUP_BASED_ON_ETH_PKT to set to 1 -+ */ -+#define GMAC_CLOCK_INPUT_NEEDED 1 -+ -+ -+#define YT8521_PHY_MODE_FIBER 1 //fiber mode only -+#define YT8521_PHY_MODE_UTP 2 //utp mode only -+#define YT8521_PHY_MODE_POLL 3 //fiber and utp, poll mode -+ -+/* please make choice according to system design -+ * for Fiber only system, please define YT8521_PHY_MODE_CURR 1 -+ * for UTP only system, please define YT8521_PHY_MODE_CURR 2 -+ * for combo system, please define YT8521_PHY_MODE_CURR 3 -+ */ -+#define YT8521_PHY_MODE_CURR 3 -+ -+/**** configuration section end ***********/ -+ -+ -+/* no need to change below */ -+ -+#if (YTPHY_ENABLE_WOL) -+#undef SYS_WAKEUP_BASED_ON_ETH_PKT -+#define SYS_WAKEUP_BASED_ON_ETH_PKT 1 -+#endif -+ -+/* workaround for 8521 fiber 100m mode */ -+static int link_mode_8521 = 0; //0: no link; 1: utp; 32: fiber. traced that 1000m fiber uses 32. -+static int link_mode_8614[4] = {0}; //0: no link; 1: utp; 32: fiber. traced that 1000m fiber uses 32. -+ -+/* for multiple port phy, base phy address */ -+static unsigned int yt_mport_base_phy_addr = 0xff; //0xff: invalid; for 8618 -+static unsigned int yt_mport_base_phy_addr_8614 = 0xff; //0xff: invalid; -+ -+int phy_yt8531_led_fixup(struct mii_bus *bus, int addr); -+int yt8511_config_out_125m(struct mii_bus *bus, int phy_id); -+ -+#if ( LINUX_VERSION_CODE > KERNEL_VERSION(5,0,0) ) -+int genphy_config_init(struct phy_device *phydev) -+{ -+ int ret; -+ -+ printk (KERN_INFO "yzhang..read phyaddr=%d, phyid=%08x\n",phydev->mdio.addr, phydev->phy_id); -+ -+ if(phydev->phy_id == 0x4f51e91b) -+ { -+ printk (KERN_INFO "yzhang..get YT8511, abt to set 125m clk out, phyaddr=%d, phyid=%08x\n",phydev->mdio.addr, phydev->phy_id); -+ ret = yt8511_config_out_125m(phydev->mdio.bus, phydev->mdio.addr); -+ printk (KERN_INFO "yzhang..8511 set 125m clk out, reg=%#04x\n",phydev->mdio.bus->read(phydev->mdio.bus,phydev->mdio.addr,0x1f)/*double check as delay*/); -+ if (ret<0) -+ printk (KERN_INFO "yzhang..failed to set 125m clk out, ret=%d\n",ret); -+ -+ phy_yt8531_led_fixup(phydev->mdio.bus, phydev->mdio.addr); -+ } -+ return genphy_read_abilities(phydev); -+} -+#endif -+ -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+static int ytphy_config_init(struct phy_device *phydev) -+{ -+ return 0; -+} -+#endif -+ -+static int ytphy_read_ext(struct phy_device *phydev, u32 regnum) -+{ -+ int ret; -+ int val; -+ -+ ret = phy_write(phydev, REG_DEBUG_ADDR_OFFSET, regnum); -+ if (ret < 0) -+ return ret; -+ -+ val = phy_read(phydev, REG_DEBUG_DATA); -+ -+ return val; -+} -+ -+static int ytphy_write_ext(struct phy_device *phydev, u32 regnum, u16 val) -+{ -+ int ret; -+ -+ ret = phy_write(phydev, REG_DEBUG_ADDR_OFFSET, regnum); -+ if (ret < 0) -+ return ret; -+ -+ ret = phy_write(phydev, REG_DEBUG_DATA, val); -+ -+ return ret; -+} -+ -+static int yt8010_config_aneg(struct phy_device *phydev) -+{ -+ phydev->speed = SPEED_100; -+ return 0; -+} -+ -+static int yt8512_clk_init(struct phy_device *phydev) -+{ -+ int ret; -+ int val; -+ -+ val = ytphy_read_ext(phydev, YT8512_EXTREG_AFE_PLL); -+ if (val < 0) -+ return val; -+ -+ val |= YT8512_CONFIG_PLL_REFCLK_SEL_EN; -+ -+ ret = ytphy_write_ext(phydev, YT8512_EXTREG_AFE_PLL, val); -+ if (ret < 0) -+ return ret; -+ -+ val = ytphy_read_ext(phydev, YT8512_EXTREG_EXTEND_COMBO); -+ if (val < 0) -+ return val; -+ -+ val |= YT8512_CONTROL1_RMII_EN; -+ -+ ret = ytphy_write_ext(phydev, YT8512_EXTREG_EXTEND_COMBO, val); -+ if (ret < 0) -+ return ret; -+ -+ val = phy_read(phydev, MII_BMCR); -+ if (val < 0) -+ return val; -+ -+ val |= YT_SOFTWARE_RESET; -+ ret = phy_write(phydev, MII_BMCR, val); -+ -+ return ret; -+} -+ -+static int yt8512_led_init(struct phy_device *phydev) -+{ -+ int ret; -+ int val; -+ int mask; -+ -+ val = ytphy_read_ext(phydev, YT8512_EXTREG_LED0); -+ if (val < 0) -+ return val; -+ -+ val |= YT8512_LED0_ACT_BLK_IND; -+ -+ mask = YT8512_LED0_DIS_LED_AN_TRY | YT8512_LED0_BT_BLK_EN | -+ YT8512_LED0_HT_BLK_EN | YT8512_LED0_COL_BLK_EN | -+ YT8512_LED0_BT_ON_EN; -+ val &= ~mask; -+ -+ ret = ytphy_write_ext(phydev, YT8512_EXTREG_LED0, val); -+ if (ret < 0) -+ return ret; -+ -+ val = ytphy_read_ext(phydev, YT8512_EXTREG_LED1); -+ if (val < 0) -+ return val; -+ -+ val |= YT8512_LED1_BT_ON_EN; -+ -+ mask = YT8512_LED1_TXACT_BLK_EN | YT8512_LED1_RXACT_BLK_EN; -+ val &= ~mask; -+ -+ ret = ytphy_write_ext(phydev, YT8512_LED1_BT_ON_EN, val); -+ -+ return ret; -+} -+ -+static int yt8512_config_init(struct phy_device *phydev) -+{ -+ int ret; -+ int val; -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+ ret = ytphy_config_init(phydev); -+#else -+ ret = genphy_config_init(phydev); -+#endif -+ if (ret < 0) -+ return ret; -+ -+ ret = yt8512_clk_init(phydev); -+ if (ret < 0) -+ return ret; -+ -+ ret = yt8512_led_init(phydev); -+ -+ /* disable auto sleep */ -+ val = ytphy_read_ext(phydev, YT8512_EXTREG_SLEEP_CONTROL1); -+ if (val < 0) -+ return val; -+ -+ val &= (~BIT(YT8512_EN_SLEEP_SW_BIT)); -+ -+ ret = ytphy_write_ext(phydev, YT8512_EXTREG_SLEEP_CONTROL1, val); -+ if (ret < 0) -+ return ret; -+ -+ return ret; -+} -+ -+static int yt8512_read_status(struct phy_device *phydev) -+{ -+ int ret; -+ int val; -+ int speed, speed_mode, duplex; -+ -+ ret = genphy_update_link(phydev); -+ if (ret) -+ return ret; -+ -+ val = phy_read(phydev, REG_PHY_SPEC_STATUS); -+ if (val < 0) -+ return val; -+ -+ duplex = (val & YT8512_DUPLEX) >> YT8512_DUPLEX_BIT; -+ speed_mode = (val & YT8512_SPEED_MODE) >> YT8512_SPEED_MODE_BIT; -+ switch (speed_mode) { -+ case 0: -+ speed = SPEED_10; -+ break; -+ case 1: -+ speed = SPEED_100; -+ break; -+ case 2: -+ case 3: -+ default: -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+ speed = -1; -+#else -+ speed = SPEED_UNKNOWN; -+#endif -+ break; -+ } -+ -+ phydev->speed = speed; -+ phydev->duplex = duplex; -+ -+ return 0; -+} -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+#else -+#if 0 -+int yt8521_soft_reset(struct phy_device *phydev) -+{ -+ int ret; -+ -+ ytphy_write_ext(phydev, 0xa000, 0); -+ ret = genphy_soft_reset(phydev); -+ if (ret < 0) -+ return ret; -+ -+ ytphy_write_ext(phydev, 0xa000, 2); -+ ret = genphy_soft_reset(phydev); -+ if (ret < 0) { -+ ytphy_write_ext(phydev, 0xa000, 0); -+ return ret; -+ } -+ -+ return 0; -+} -+#else -+/* qingsong feedback 2 genphy_soft_reset will cause problem. -+ * and this is the reduction version -+ */ -+int yt8521_soft_reset(struct phy_device *phydev) -+{ -+ int ret, val; -+ -+ val = ytphy_read_ext(phydev, 0xa001); -+ ytphy_write_ext(phydev, 0xa001, (val & ~0x8000)); -+ -+ ret = genphy_soft_reset(phydev); -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+#endif -+ -+#endif -+ -+#if GMAC_CLOCK_INPUT_NEEDED -+static int ytphy_mii_rd_ext(struct mii_bus *bus, int phy_id, u32 regnum) -+{ -+ int ret; -+ int val; -+ -+ ret = bus->write(bus, phy_id, REG_DEBUG_ADDR_OFFSET, regnum); -+ if (ret < 0) -+ return ret; -+ -+ val = bus->read(bus, phy_id, REG_DEBUG_DATA); -+ -+ return val; -+} -+ -+static int ytphy_mii_wr_ext(struct mii_bus *bus, int phy_id, u32 regnum, u16 val) -+{ -+ int ret; -+ -+ ret = bus->write(bus, phy_id, REG_DEBUG_ADDR_OFFSET, regnum); -+ if (ret < 0) -+ return ret; -+ -+ ret = bus->write(bus, phy_id, REG_DEBUG_DATA, val); -+ -+ return ret; -+} -+ -+int yt8511_config_dis_txdelay(struct mii_bus *bus, int phy_id) -+{ -+ int ret; -+ int val; -+ -+ /* disable auto sleep */ -+ val = ytphy_mii_rd_ext(bus, phy_id, 0x27); -+ if (val < 0) -+ return val; -+ -+ val &= (~BIT(15)); -+ -+ ret = ytphy_mii_wr_ext(bus, phy_id, 0x27, val); -+ if (ret < 0) -+ return ret; -+ -+ /* enable RXC clock when no wire plug */ -+ val = ytphy_mii_rd_ext(bus, phy_id, 0xc); -+ if (val < 0) -+ return val; -+ -+ /* ext reg 0xc b[7:4] -+ Tx Delay time = 150ps * N - 250ps -+ */ -+ val &= ~(0xf << 4); -+ ret = ytphy_mii_wr_ext(bus, phy_id, 0xc, val); -+ printk("yt8511_config_dis_txdelay..phy txdelay, val=%#08x\n",val); -+ -+ return ret; -+} -+ -+int phy_yt8531_led_fixup(struct mii_bus *bus, int addr) -+{ -+ printk("%s in\n", __func__); -+ -+ ytphy_mii_wr_ext(bus, addr, 0xa00d, 0x670); -+ ytphy_mii_wr_ext(bus, addr, 0xa00e, 0x2070); -+ ytphy_mii_wr_ext(bus, addr, 0xa00f, 0x7e); -+ -+ return 0; -+} -+ -+int yt8511_config_out_125m(struct mii_bus *bus, int addr) -+{ -+ int ret; -+ int val; -+ -+ mdelay(50); -+ ret = ytphy_mii_wr_ext(bus, addr, 0xa012, 0xd0); -+ -+ mdelay(100); -+ val = ytphy_mii_rd_ext(bus, addr, 0xa012); -+ -+ if(val != 0xd0) -+ { -+ printk("yt8511_config_out_125m error\n"); -+ return -1; -+ } -+ -+ /* disable auto sleep */ -+ val = ytphy_mii_rd_ext(bus, addr, 0x27); -+ if (val < 0) -+ return val; -+ -+ val &= (~BIT(15)); -+ -+ ret = ytphy_mii_wr_ext(bus, addr, 0x27, val); -+ if (ret < 0) -+ return ret; -+ -+ /* enable RXC clock when no wire plug */ -+ val = ytphy_mii_rd_ext(bus, addr, 0xc); -+ if (val < 0) -+ return val; -+ -+ /* ext reg 0xc.b[2:1] -+ 00-----25M from pll; -+ 01---- 25M from xtl;(default) -+ 10-----62.5M from pll; -+ 11----125M from pll(here set to this value) -+ */ -+ val |= (3 << 1); -+ ret = ytphy_mii_wr_ext(bus, addr, 0xc, val); -+ printk("yt8511_config_out_125m, phy clk out, val=%#08x\n",val); -+ -+#if 0 -+ /* for customer, please enable it based on demand. -+ * configure to master -+ */ -+ val = bus->read(bus, phy_id, 0x9/*master/slave config reg*/); -+ val |= (0x3<<11); //to be manual config and force to be master -+ ret = bus->write(bus, phy_id, 0x9, val); //take effect until phy soft reset -+ if (ret < 0) -+ return ret; -+ -+ printk("yt8511_config_out_125m, phy to be master, val=%#08x\n",val); -+#endif -+ -+ return ret; -+} -+ -+EXPORT_SYMBOL(yt8511_config_out_125m); -+ -+static int yt8511_config_init(struct phy_device *phydev) -+{ -+ int ret; -+ -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+ ret = ytphy_config_init(phydev); -+#else -+ ret = genphy_config_init(phydev); -+#endif -+ -+ return ret; -+} -+#endif /*GMAC_CLOCK_INPUT_NEEDED*/ -+ -+#if (YTPHY_ENABLE_WOL) -+static int ytphy_switch_reg_space(struct phy_device *phydev, int space) -+{ -+ int ret; -+ -+ if (space == YTPHY_REG_SPACE_UTP){ -+ ret = ytphy_write_ext(phydev, 0xa000, 0); -+ }else{ -+ ret = ytphy_write_ext(phydev, 0xa000, 2); -+ } -+ -+ return ret; -+} -+ -+static int ytphy_wol_en_cfg(struct phy_device *phydev, ytphy_wol_cfg_t wol_cfg) -+{ -+ int ret=0; -+ int val=0; -+ -+ val = ytphy_read_ext(phydev, YTPHY_WOL_CFG_REG); -+ if (val < 0) -+ return val; -+ -+ if(wol_cfg.enable) { -+ val |= YTPHY_WOL_CFG_EN; -+ -+ if(wol_cfg.type == YTPHY_WOL_TYPE_LEVEL) { -+ val &= ~YTPHY_WOL_CFG_TYPE; -+ val &= ~YTPHY_WOL_CFG_INTR_SEL; -+ } else if(wol_cfg.type == YTPHY_WOL_TYPE_PULSE) { -+ val |= YTPHY_WOL_CFG_TYPE; -+ val |= YTPHY_WOL_CFG_INTR_SEL; -+ -+ if(wol_cfg.width == YTPHY_WOL_WIDTH_84MS) { -+ val &= ~YTPHY_WOL_CFG_WIDTH1; -+ val &= ~YTPHY_WOL_CFG_WIDTH2; -+ } else if(wol_cfg.width == YTPHY_WOL_WIDTH_168MS) { -+ val |= YTPHY_WOL_CFG_WIDTH1; -+ val &= ~YTPHY_WOL_CFG_WIDTH2; -+ } else if(wol_cfg.width == YTPHY_WOL_WIDTH_336MS) { -+ val &= ~YTPHY_WOL_CFG_WIDTH1; -+ val |= YTPHY_WOL_CFG_WIDTH2; -+ } else if(wol_cfg.width == YTPHY_WOL_WIDTH_672MS) { -+ val |= YTPHY_WOL_CFG_WIDTH1; -+ val |= YTPHY_WOL_CFG_WIDTH2; -+ } -+ } -+ } else { -+ val &= ~YTPHY_WOL_CFG_EN; -+ val &= ~YTPHY_WOL_CFG_INTR_SEL; -+ } -+ -+ ret = ytphy_write_ext(phydev, YTPHY_WOL_CFG_REG, val); -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+static void ytphy_get_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol) -+{ -+ int val = 0; -+ -+ wol->supported = WAKE_MAGIC; -+ wol->wolopts = 0; -+ -+ val = ytphy_read_ext(phydev, YTPHY_WOL_CFG_REG); -+ if (val < 0) -+ return; -+ -+ if (val & YTPHY_WOL_CFG_EN) -+ wol->wolopts |= WAKE_MAGIC; -+ -+ return; -+} -+ -+static int ytphy_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol) -+{ -+ int ret, pre_page, val; -+ ytphy_wol_cfg_t wol_cfg; -+ struct net_device *p_attached_dev = phydev->attached_dev; -+ -+ memset(&wol_cfg,0,sizeof(ytphy_wol_cfg_t)); -+ pre_page = ytphy_read_ext(phydev, 0xa000); -+ if (pre_page < 0) -+ return pre_page; -+ -+ /* Switch to phy UTP page */ -+ ret = ytphy_switch_reg_space(phydev, YTPHY_REG_SPACE_UTP); -+ if (ret < 0) -+ return ret; -+ -+ if (wol->wolopts & WAKE_MAGIC) { -+ -+ /* Enable the WOL interrupt */ -+ val = phy_read(phydev, YTPHY_UTP_INTR_REG); -+ val |= YTPHY_WOL_INTR; -+ ret = phy_write(phydev, YTPHY_UTP_INTR_REG, val); -+ if (ret < 0) -+ return ret; -+ -+ /* Set the WOL config */ -+ wol_cfg.enable = 1; //enable -+ wol_cfg.type= YTPHY_WOL_TYPE_PULSE; -+ wol_cfg.width= YTPHY_WOL_WIDTH_672MS; -+ ret = ytphy_wol_en_cfg(phydev, wol_cfg); -+ if (ret < 0) -+ return ret; -+ -+ /* Store the device address for the magic packet */ -+ ret = ytphy_write_ext(phydev, YTPHY_MAGIC_PACKET_MAC_ADDR2, -+ ((p_attached_dev->dev_addr[0] << 8) | -+ p_attached_dev->dev_addr[1])); -+ if (ret < 0) -+ return ret; -+ ret = ytphy_write_ext(phydev, YTPHY_MAGIC_PACKET_MAC_ADDR1, -+ ((p_attached_dev->dev_addr[2] << 8) | -+ p_attached_dev->dev_addr[3])); -+ if (ret < 0) -+ return ret; -+ ret = ytphy_write_ext(phydev, YTPHY_MAGIC_PACKET_MAC_ADDR0, -+ ((p_attached_dev->dev_addr[4] << 8) | -+ p_attached_dev->dev_addr[5])); -+ if (ret < 0) -+ return ret; -+ } else { -+ wol_cfg.enable = 0; //disable -+ wol_cfg.type= YTPHY_WOL_TYPE_MAX; -+ wol_cfg.width= YTPHY_WOL_WIDTH_MAX; -+ ret = ytphy_wol_en_cfg(phydev, wol_cfg); -+ if (ret < 0) -+ return ret; -+ } -+ -+ /* Recover to previous register space page */ -+ ret = ytphy_switch_reg_space(phydev, pre_page); -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+#endif /*(YTPHY_ENABLE_WOL)*/ -+ -+static int yt8521_config_init(struct phy_device *phydev) -+{ -+ int ret; -+ int val; -+ -+ phydev->irq = PHY_POLL; -+ -+ ytphy_write_ext(phydev, 0xa000, 0); -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+ ret = ytphy_config_init(phydev); -+#else -+ ret = genphy_config_init(phydev); -+#endif -+ if (ret < 0) -+ return ret; -+ -+ /* disable auto sleep */ -+ val = ytphy_read_ext(phydev, YT8521_EXTREG_SLEEP_CONTROL1); -+ if (val < 0) -+ return val; -+ -+ val &= (~BIT(YT8521_EN_SLEEP_SW_BIT)); -+ -+ ret = ytphy_write_ext(phydev, YT8521_EXTREG_SLEEP_CONTROL1, val); -+ if (ret < 0) -+ return ret; -+ -+ /* enable RXC clock when no wire plug */ -+ ret = ytphy_write_ext(phydev, 0xa000, 0); -+ if (ret < 0) -+ return ret; -+ -+ val = ytphy_read_ext(phydev, 0xc); -+ if (val < 0) -+ return val; -+ val &= ~(1 << 12); -+ ret = ytphy_write_ext(phydev, 0xc, val); -+ if (ret < 0) -+ return ret; -+ -+ printk (KERN_INFO "yt8521_config_init, 8521 init call out.\n"); -+ return ret; -+} -+ -+/* -+ * for fiber mode, there is no 10M speed mode and -+ * this function is for this purpose. -+ */ -+static int yt8521_adjust_status(struct phy_device *phydev, int val, int is_utp) -+{ -+ int speed_mode, duplex; -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+ int speed = -1; -+#else -+ int speed = SPEED_UNKNOWN; -+#endif -+ -+ duplex = (val & YT8512_DUPLEX) >> YT8521_DUPLEX_BIT; -+ speed_mode = (val & YT8521_SPEED_MODE) >> YT8521_SPEED_MODE_BIT; -+ switch (speed_mode) { -+ case 0: -+ if (is_utp) -+ speed = SPEED_10; -+ break; -+ case 1: -+ speed = SPEED_100; -+ break; -+ case 2: -+ speed = SPEED_1000; -+ break; -+ case 3: -+ break; -+ default: -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+ speed = -1; -+#else -+ speed = SPEED_UNKNOWN; -+#endif -+ break; -+ } -+ -+ phydev->speed = speed; -+ phydev->duplex = duplex; -+ //printk (KERN_INFO "yt8521_adjust_status call out,regval=0x%04x,mode=%s,speed=%dm...\n", val,is_utp?"utp":"fiber", phydev->speed); -+ -+ return 0; -+} -+ -+/* -+ * for fiber mode, when speed is 100M, there is no definition for autonegotiation, and -+ * this function handles this case and return 1 per linux kernel's polling. -+ */ -+int yt8521_aneg_done (struct phy_device *phydev) -+{ -+ -+ //printk("yt8521_aneg_done callin,speed=%dm,linkmoded=%d\n", phydev->speed,link_mode_8521); -+ -+ if((32 == link_mode_8521) && (SPEED_100 == phydev->speed)) -+ { -+ return 1/*link_mode_8521*/; -+ } -+ -+#if ( LINUX_VERSION_CODE > KERNEL_VERSION(3,11,0) ) -+ return genphy_aneg_done(phydev); -+#else -+ return 1; -+#endif -+} -+ -+static int yt8521_read_status(struct phy_device *phydev) -+{ -+ int ret; -+ volatile int val, yt8521_fiber_latch_val, yt8521_fiber_curr_val; -+ volatile int link; -+ int link_utp = 0, link_fiber = 0; -+ -+#if (YT8521_PHY_MODE_CURR != YT8521_PHY_MODE_FIBER) -+ /* reading UTP */ -+ ret = ytphy_write_ext(phydev, 0xa000, 0); -+ if (ret < 0) -+ return ret; -+ -+ val = phy_read(phydev, REG_PHY_SPEC_STATUS); -+ if (val < 0) -+ return val; -+ -+ link = val & (BIT(YT8521_LINK_STATUS_BIT)); -+ if (link) { -+ link_utp = 1; -+ link_mode_8521 = 1; -+ yt8521_adjust_status(phydev, val, 1); -+ } else { -+ link_utp = 0; -+ } -+#endif //(YT8521_PHY_MODE_CURR != YT8521_PHY_MODE_FIBER) -+ -+#if (YT8521_PHY_MODE_CURR != YT8521_PHY_MODE_UTP) -+ /* reading Fiber */ -+ ret = ytphy_write_ext(phydev, 0xa000, 2); -+ if (ret < 0) -+ return ret; -+ -+ val = phy_read(phydev, REG_PHY_SPEC_STATUS); -+ if (val < 0) -+ return val; -+ -+ //note: below debug information is used to check multiple PHy ports. -+ //printk (KERN_INFO "yt8521_read_status, fiber status=%04x,macbase=0x%08lx\n", val,(unsigned long)phydev->attached_dev); -+ -+ /* for fiber, from 1000m to 100m, there is not link down from 0x11, and check reg 1 to identify such case -+ * this is important for Linux kernel for that, missing linkdown event will cause problem. -+ */ -+ yt8521_fiber_latch_val = phy_read(phydev, MII_BMSR); -+ yt8521_fiber_curr_val = phy_read(phydev, MII_BMSR); -+ link = val & (BIT(YT8521_LINK_STATUS_BIT)); -+ if((link) && (yt8521_fiber_latch_val != yt8521_fiber_curr_val)) -+ { -+ link = 0; -+ printk (KERN_INFO "yt8521_read_status, fiber link down detect,latch=%04x,curr=%04x\n", yt8521_fiber_latch_val,yt8521_fiber_curr_val); -+ } -+ -+ if (link) { -+ link_fiber = 1; -+ yt8521_adjust_status(phydev, val, 0); -+ link_mode_8521 = 32; //fiber mode -+ -+ -+ } else { -+ link_fiber = 0; -+ } -+#endif //(YT8521_PHY_MODE_CURR != YT8521_PHY_MODE_UTP) -+ -+ if (link_utp || link_fiber) { -+ phydev->link = 1; -+ } else { -+ phydev->link = 0; -+ link_mode_8521 = 0; -+ } -+ -+#if (YT8521_PHY_MODE_CURR != YT8521_PHY_MODE_FIBER) -+ if (link_utp) { -+ ytphy_write_ext(phydev, 0xa000, 0); -+ } -+#endif -+ -+ //printk (KERN_INFO "yzhang..8521 read status call out,link=%d,linkmode=%d\n", phydev->link, link_mode_8521 ); -+ return 0; -+} -+ -+int yt8521_suspend(struct phy_device *phydev) -+{ -+#if !(SYS_WAKEUP_BASED_ON_ETH_PKT) -+ int value; -+ -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+ mutex_lock(&phydev->lock); -+#else -+ /* no need lock in 4.19 */ -+#endif -+ -+ ytphy_write_ext(phydev, 0xa000, 0); -+ value = phy_read(phydev, MII_BMCR); -+ phy_write(phydev, MII_BMCR, value | BMCR_PDOWN); -+ -+ ytphy_write_ext(phydev, 0xa000, 2); -+ value = phy_read(phydev, MII_BMCR); -+ phy_write(phydev, MII_BMCR, value | BMCR_PDOWN); -+ -+ ytphy_write_ext(phydev, 0xa000, 0); -+ -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+ mutex_unlock(&phydev->lock); -+#else -+ /* no need lock/unlock in 4.19 */ -+#endif -+#endif /*!(SYS_WAKEUP_BASED_ON_ETH_PKT)*/ -+ -+ return 0; -+} -+ -+int yt8521_resume(struct phy_device *phydev) -+{ -+#if !(SYS_WAKEUP_BASED_ON_ETH_PKT) -+ int value; -+ int ret; -+ -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+ mutex_lock(&phydev->lock); -+#else -+ /* no need lock/unlock in 4.19 */ -+#endif -+ -+ ytphy_write_ext(phydev, 0xa000, 0); -+ value = phy_read(phydev, MII_BMCR); -+ phy_write(phydev, MII_BMCR, value & ~BMCR_PDOWN); -+ -+ /* disable auto sleep */ -+ value = ytphy_read_ext(phydev, YT8521_EXTREG_SLEEP_CONTROL1); -+ if (value < 0) -+ return value; -+ -+ value &= (~BIT(YT8521_EN_SLEEP_SW_BIT)); -+ ret = ytphy_write_ext(phydev, YT8521_EXTREG_SLEEP_CONTROL1, value); -+ if (ret < 0) -+ return ret; -+ -+ /* enable RXC clock when no wire plug */ -+ value = ytphy_read_ext(phydev, 0xc); -+ if (value < 0) -+ return value; -+ value &= ~(1 << 12); -+ ret = ytphy_write_ext(phydev, 0xc, value); -+ if (ret < 0) -+ return ret; -+ -+ ytphy_write_ext(phydev, 0xa000, 2); -+ value = phy_read(phydev, MII_BMCR); -+ phy_write(phydev, MII_BMCR, value & ~BMCR_PDOWN); -+ -+#if (YT8521_PHY_MODE_CURR != YT8521_PHY_MODE_FIBER) -+ ytphy_write_ext(phydev, 0xa000, 0); -+#endif -+ -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+ mutex_unlock(&phydev->lock); -+#else -+ /* no need lock/unlock in 4.19 */ -+#endif -+#endif /*!(SYS_WAKEUP_BASED_ON_ETH_PKT)*/ -+ -+ return 0; -+} -+ -+ -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+#else -+int yt8618_soft_reset(struct phy_device *phydev) -+{ -+ int ret; -+ -+ ytphy_write_ext(phydev, 0xa000, 0); -+ ret = genphy_soft_reset(phydev); -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+int yt8614_soft_reset(struct phy_device *phydev) -+{ -+ int ret; -+ -+ /* utp */ -+ ytphy_write_ext(phydev, 0xa000, 0); -+ ret = genphy_soft_reset(phydev); -+ if (ret < 0) -+ return ret; -+ -+ /* qsgmii */ -+ ytphy_write_ext(phydev, 0xa000, 2); -+ ret = genphy_soft_reset(phydev); -+ if (ret < 0) { -+ ytphy_write_ext(phydev, 0xa000, 0); //back to utp mode -+ return ret; -+ } -+ -+ /* sgmii */ -+ ytphy_write_ext(phydev, 0xa000, 3); -+ ret = genphy_soft_reset(phydev); -+ if (ret < 0) { -+ ytphy_write_ext(phydev, 0xa000, 0); //back to utp mode -+ return ret; -+ } -+ -+ return 0; -+} -+ -+#endif -+ -+static int yt8618_config_init(struct phy_device *phydev) -+{ -+ int ret; -+ int val; -+ -+ phydev->irq = PHY_POLL; -+ -+ if(0xff == yt_mport_base_phy_addr) -+ /* by default, we think the first phy should be the base phy addr. for mul */ -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+ { -+ yt_mport_base_phy_addr = phydev->addr; -+ }else if (yt_mport_base_phy_addr > phydev->addr) { -+ printk (KERN_INFO "yzhang..8618 init, phy address mismatch, base=%d, cur=%d\n", yt_mport_base_phy_addr, phydev->addr); -+ } -+#else -+ { -+ yt_mport_base_phy_addr = phydev->mdio.addr; -+ }else if (yt_mport_base_phy_addr > phydev->mdio.addr) { -+ printk (KERN_INFO "yzhang..8618 init, phy address mismatch, base=%d, cur=%d\n", yt_mport_base_phy_addr, phydev->mdio.addr); -+ } -+#endif -+ -+ ytphy_write_ext(phydev, 0xa000, 0); -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+ ret = ytphy_config_init(phydev); -+#else -+ ret = genphy_config_init(phydev); -+#endif -+ if (ret < 0) -+ return ret; -+ -+ /* for utp to optimize signal */ -+ ret = ytphy_write_ext(phydev, 0x41, 0x33); -+ if (ret < 0) -+ return ret; -+ ret = ytphy_write_ext(phydev, 0x42, 0x66); -+ if (ret < 0) -+ return ret; -+ ret = ytphy_write_ext(phydev, 0x43, 0xaa); -+ if (ret < 0) -+ return ret; -+ ret = ytphy_write_ext(phydev, 0x44, 0xd0d); -+ if (ret < 0) -+ return ret; -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+ if((phydev->addr > yt_mport_base_phy_addr) && ((2 == phydev->addr - yt_mport_base_phy_addr) || (5 == phydev->addr - yt_mport_base_phy_addr))) -+#else -+ if((phydev->mdio.addr > yt_mport_base_phy_addr) && ((2 == phydev->mdio.addr - yt_mport_base_phy_addr) || (5 == phydev->mdio.addr - yt_mport_base_phy_addr))) -+#endif -+ { -+ ret = ytphy_write_ext(phydev, 0x44, 0x2929); -+ if (ret < 0) -+ return ret; -+ } -+ -+ val = phy_read(phydev, MII_BMCR); -+ phy_write(phydev, MII_BMCR, val | BMCR_RESET); -+ -+ printk (KERN_INFO "yt8618_config_init call out.\n"); -+ return ret; -+} -+ -+static int yt8614_config_init(struct phy_device *phydev) -+{ -+ int ret = 0; -+ -+ phydev->irq = PHY_POLL; -+ -+ if(0xff == yt_mport_base_phy_addr_8614) -+ /* by default, we think the first phy should be the base phy addr. for mul */ -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+ { -+ yt_mport_base_phy_addr_8614 = (unsigned int)phydev->addr; -+ }else if (yt_mport_base_phy_addr_8614 > (unsigned int)phydev->addr) { -+ printk (KERN_INFO "yzhang..8618 init, phy address mismatch, base=%u, cur=%d\n", yt_mport_base_phy_addr_8614, phydev->addr); -+ } -+#else -+ { -+ yt_mport_base_phy_addr_8614 = (unsigned int)phydev->mdio.addr; -+ }else if (yt_mport_base_phy_addr_8614 > (unsigned int)phydev->mdio.addr) { -+ printk (KERN_INFO "yzhang..8618 init, phy address mismatch, base=%u, cur=%d\n", yt_mport_base_phy_addr_8614, phydev->mdio.addr); -+ } -+#endif -+ return ret; -+} -+ -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+#define yt8614_get_port_from_phydev(phydev) ((0xff == yt_mport_base_phy_addr_8614) && (yt_mport_base_phy_addr_8614 <= (phydev)->addr) ? 0 : (unsigned int)((phydev)->addr) - yt_mport_base_phy_addr_8614) -+#else -+#define yt8614_get_port_from_phydev(phydev) ((0xff == yt_mport_base_phy_addr_8614) && (yt_mport_base_phy_addr_8614 <= (phydev)->mdio.addr) ? 0 : (unsigned int)((phydev)->mdio.addr) - yt_mport_base_phy_addr_8614) -+#endif -+ -+int yt8618_aneg_done (struct phy_device *phydev) -+{ -+ -+ return genphy_aneg_done(phydev); -+} -+ -+int yt8614_aneg_done (struct phy_device *phydev) -+{ -+ int port = yt8614_get_port_from_phydev(phydev); -+ -+ /*it should be used for 8614 fiber*/ -+ if((32 == link_mode_8614[port]) && (SPEED_100 == phydev->speed)) -+ { -+ return 1; -+ } -+ -+ return genphy_aneg_done(phydev); -+} -+ -+static int yt8614_read_status(struct phy_device *phydev) -+{ -+ //int i; -+ int ret; -+ volatile int val, yt8614_fiber_latch_val, yt8614_fiber_curr_val; -+ volatile int link; -+ int link_utp = 0, link_fiber = 0; -+ int port = yt8614_get_port_from_phydev(phydev); -+ -+#if (YT8614_PHY_MODE_CURR != YT8521_PHY_MODE_FIBER) -+ /* switch to utp and reading regs */ -+ ret = ytphy_write_ext(phydev, 0xa000, 0); -+ if (ret < 0) -+ return ret; -+ -+ val = phy_read(phydev, REG_PHY_SPEC_STATUS); -+ if (val < 0) -+ return val; -+ -+ link = val & (BIT(YT8521_LINK_STATUS_BIT)); -+ if (link) { -+ link_utp = 1; -+ // here is same as 8521 and re-use the function; -+ yt8521_adjust_status(phydev, val, 1); -+ } else { -+ link_utp = 0; -+ } -+#endif //(YT8614_PHY_MODE_CURR != YT8521_PHY_MODE_FIBER) -+ -+#if (YT8614_PHY_MODE_CURR != YT8521_PHY_MODE_UTP) -+ /* reading Fiber/sgmii */ -+ ret = ytphy_write_ext(phydev, 0xa000, 3); -+ if (ret < 0) -+ return ret; -+ -+ val = phy_read(phydev, REG_PHY_SPEC_STATUS); -+ if (val < 0) -+ return val; -+ -+ //printk (KERN_INFO "yzhang..8614 read fiber status=%04x,macbase=0x%08lx\n", val,(unsigned long)phydev->attached_dev); -+ -+ /* for fiber, from 1000m to 100m, there is not link down from 0x11, and check reg 1 to identify such case */ -+ yt8614_fiber_latch_val = phy_read(phydev, MII_BMSR); -+ yt8614_fiber_curr_val = phy_read(phydev, MII_BMSR); -+ link = val & (BIT(YT8521_LINK_STATUS_BIT)); -+ if((link) && (yt8614_fiber_latch_val != yt8614_fiber_curr_val)) -+ { -+ link = 0; -+ printk (KERN_INFO "yt8614_read_status, fiber link down detect,latch=%04x,curr=%04x\n", yt8614_fiber_latch_val,yt8614_fiber_curr_val); -+ } -+ -+ if (link) { -+ link_fiber = 1; -+ yt8521_adjust_status(phydev, val, 0); -+ link_mode_8614[port] = 32; //fiber mode -+ -+ -+ } else { -+ link_fiber = 0; -+ } -+#endif //(YT8521_PHY_MODE_CURR != YT8521_PHY_MODE_UTP) -+ -+ if (link_utp || link_fiber) { -+ phydev->link = 1; -+ } else { -+ phydev->link = 0; -+ link_mode_8614[port] = 0; -+ } -+ -+#if (YT8614_PHY_MODE_CURR != YT8521_PHY_MODE_FIBER) -+ if (link_utp) { -+ ytphy_write_ext(phydev, 0xa000, 0); -+ } -+#endif -+ //printk (KERN_INFO "yt8614_read_status call out,link=%d,linkmode=%d\n", phydev->link, link_mode_8614[port] ); -+ -+ return 0; -+} -+ -+static int yt8618_read_status(struct phy_device *phydev) -+{ -+ int ret; -+ volatile int val; //maybe for 8614 yt8521_fiber_latch_val, yt8521_fiber_curr_val; -+ volatile int link; -+ int link_utp = 0, link_fiber = 0; -+ -+ /* switch to utp and reading regs */ -+ ret = ytphy_write_ext(phydev, 0xa000, 0); -+ if (ret < 0) -+ return ret; -+ -+ val = phy_read(phydev, REG_PHY_SPEC_STATUS); -+ if (val < 0) -+ return val; -+ -+ link = val & (BIT(YT8521_LINK_STATUS_BIT)); -+ if (link) { -+ link_utp = 1; -+ yt8521_adjust_status(phydev, val, 1); -+ } else { -+ link_utp = 0; -+ } -+ -+ if (link_utp || link_fiber) { -+ phydev->link = 1; -+ } else { -+ phydev->link = 0; -+ } -+ -+ return 0; -+} -+ -+int yt8618_suspend(struct phy_device *phydev) -+{ -+#if !(SYS_WAKEUP_BASED_ON_ETH_PKT) -+ int value; -+ -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+ mutex_lock(&phydev->lock); -+#else -+ /* no need lock in 4.19 */ -+#endif -+ -+ ytphy_write_ext(phydev, 0xa000, 0); -+ value = phy_read(phydev, MII_BMCR); -+ phy_write(phydev, MII_BMCR, value | BMCR_PDOWN); -+ -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+ mutex_unlock(&phydev->lock); -+#else -+ /* no need lock/unlock in 4.19 */ -+#endif -+#endif /*!(SYS_WAKEUP_BASED_ON_ETH_PKT)*/ -+ -+ return 0; -+} -+ -+int yt8618_resume(struct phy_device *phydev) -+{ -+#if !(SYS_WAKEUP_BASED_ON_ETH_PKT) -+ int value; -+ -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+ mutex_lock(&phydev->lock); -+#else -+ /* no need lock/unlock in 4.19 */ -+#endif -+ -+ ytphy_write_ext(phydev, 0xa000, 0); -+ value = phy_read(phydev, MII_BMCR); -+ phy_write(phydev, MII_BMCR, value & ~BMCR_PDOWN); -+ -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+ mutex_unlock(&phydev->lock); -+#else -+ /* no need lock/unlock in 4.19 */ -+#endif -+#endif /*!(SYS_WAKEUP_BASED_ON_ETH_PKT)*/ -+ -+ return 0; -+} -+ -+int yt8614_suspend(struct phy_device *phydev) -+{ -+#if !(SYS_WAKEUP_BASED_ON_ETH_PKT) -+ int value; -+ -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+ mutex_lock(&phydev->lock); -+#else -+ /* no need lock in 4.19 */ -+#endif -+ -+ ytphy_write_ext(phydev, 0xa000, 0); -+ value = phy_read(phydev, MII_BMCR); -+ phy_write(phydev, MII_BMCR, value | BMCR_PDOWN); -+ -+ ytphy_write_ext(phydev, 0xa000, 3); -+ value = phy_read(phydev, MII_BMCR); -+ phy_write(phydev, MII_BMCR, value | BMCR_PDOWN); -+ -+ ytphy_write_ext(phydev, 0xa000, 0); -+ -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+ mutex_unlock(&phydev->lock); -+#else -+ /* no need lock/unlock in 4.19 */ -+#endif -+#endif /*!(SYS_WAKEUP_BASED_ON_ETH_PKT)*/ -+ -+ return 0; -+} -+ -+int yt8614_resume(struct phy_device *phydev) -+{ -+#if !(SYS_WAKEUP_BASED_ON_ETH_PKT) -+ int value; -+ -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+ mutex_lock(&phydev->lock); -+#else -+ /* no need lock/unlock in 4.19 */ -+#endif -+ -+ ytphy_write_ext(phydev, 0xa000, 0); -+ value = phy_read(phydev, MII_BMCR); -+ phy_write(phydev, MII_BMCR, value & ~BMCR_PDOWN); -+ -+ ytphy_write_ext(phydev, 0xa000, 3); -+ value = phy_read(phydev, MII_BMCR); -+ phy_write(phydev, MII_BMCR, value & ~BMCR_PDOWN); -+ -+ ytphy_write_ext(phydev, 0xa000, 0); -+ -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+ mutex_unlock(&phydev->lock); -+#else -+ /* no need lock/unlock in 4.19 */ -+#endif -+#endif /*!(SYS_WAKEUP_BASED_ON_ETH_PKT)*/ -+ -+ return 0; -+} -+ -+ -+static struct phy_driver ytphy_drvs[] = { -+ { -+ .phy_id = PHY_ID_YT8010, -+ .name = "YT8010 Automotive Ethernet", -+ .phy_id_mask = MOTORCOMM_PHY_ID_MASK, -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) ) -+ .features = PHY_BASIC_FEATURES, -+ .flags = PHY_HAS_INTERRUPT, -+#endif -+ .config_aneg = yt8010_config_aneg, -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+ .config_init = ytphy_config_init, -+#else -+ .config_init = genphy_config_init, -+#endif -+ .read_status = genphy_read_status, -+ }, { -+ .phy_id = PHY_ID_YT8510, -+ .name = "YT8510 100/10Mb Ethernet", -+ .phy_id_mask = MOTORCOMM_PHY_ID_MASK, -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) ) -+ .features = PHY_BASIC_FEATURES, -+ .flags = PHY_HAS_INTERRUPT, -+#endif -+ .config_aneg = genphy_config_aneg, -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+ .config_init = ytphy_config_init, -+#else -+ .config_init = genphy_config_init, -+#endif -+ .read_status = genphy_read_status, -+ }, { -+ .phy_id = PHY_ID_YT8511, -+ .name = "YT8511 Gigabit Ethernet", -+ .phy_id_mask = MOTORCOMM_PHY_ID_MASK, -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) ) -+ .features = PHY_GBIT_FEATURES, -+ .flags = PHY_HAS_INTERRUPT, -+#endif -+ .config_aneg = genphy_config_aneg, -+#if GMAC_CLOCK_INPUT_NEEDED -+ .config_init = yt8511_config_init, -+#else -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+ .config_init = ytphy_config_init, -+#else -+ .config_init = genphy_config_init, -+#endif -+#endif -+ .read_status = genphy_read_status, -+ .suspend = genphy_suspend, -+ .resume = genphy_resume, -+ }, { -+ .phy_id = PHY_ID_YT8512, -+ .name = "YT8512 Ethernet", -+ .phy_id_mask = MOTORCOMM_PHY_ID_MASK, -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) ) -+ .features = PHY_BASIC_FEATURES, -+ .flags = PHY_HAS_INTERRUPT, -+#endif -+ .config_aneg = genphy_config_aneg, -+ .config_init = yt8512_config_init, -+ .read_status = yt8512_read_status, -+ .suspend = genphy_suspend, -+ .resume = genphy_resume, -+ }, { -+ .phy_id = PHY_ID_YT8512B, -+ .name = "YT8512B Ethernet", -+ .phy_id_mask = MOTORCOMM_PHY_ID_MASK, -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) ) -+ .features = PHY_BASIC_FEATURES, -+ .flags = PHY_HAS_INTERRUPT, -+#endif -+ .config_aneg = genphy_config_aneg, -+ .config_init = yt8512_config_init, -+ .read_status = yt8512_read_status, -+ .suspend = genphy_suspend, -+ .resume = genphy_resume, -+ }, { -+ .phy_id = PHY_ID_YT8521, -+ .name = "YT8521 Ethernet", -+ .phy_id_mask = MOTORCOMM_PHY_ID_MASK, -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) ) -+ .features = PHY_BASIC_FEATURES | PHY_GBIT_FEATURES, -+#endif -+ .flags = PHY_POLL, -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+#else -+ .soft_reset = yt8521_soft_reset, -+#endif -+ .config_aneg = genphy_config_aneg, -+#if ( LINUX_VERSION_CODE > KERNEL_VERSION(3,11,0) ) -+ .aneg_done = yt8521_aneg_done, -+#endif -+ .config_init = yt8521_config_init, -+ .read_status = yt8521_read_status, -+ .suspend = yt8521_suspend, -+ .resume = yt8521_resume, -+#if (YTPHY_ENABLE_WOL) -+ .get_wol = &ytphy_get_wol, -+ .set_wol = &ytphy_set_wol, -+#endif -+ },{ -+ /* same as 8521 */ -+ .phy_id = PHY_ID_YT8531S, -+ .name = "YT8531S Ethernet", -+ .phy_id_mask = MOTORCOMM_PHY_ID_MASK, -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) ) -+ .features = PHY_BASIC_FEATURES | PHY_GBIT_FEATURES, -+#endif -+ .flags = PHY_POLL, -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+#else -+ .soft_reset = yt8521_soft_reset, -+#endif -+ .config_aneg = genphy_config_aneg, -+#if ( LINUX_VERSION_CODE > KERNEL_VERSION(3,11,0) ) -+ .aneg_done = yt8521_aneg_done, -+#endif -+ .config_init = yt8521_config_init, -+ .read_status = yt8521_read_status, -+ .suspend = yt8521_suspend, -+ .resume = yt8521_resume, -+#if (YTPHY_ENABLE_WOL) -+ .get_wol = &ytphy_get_wol, -+ .set_wol = &ytphy_set_wol, -+#endif -+ }, { -+ /* same as 8511 */ -+ .phy_id = PHY_ID_YT8531, -+ .name = "YT8531 Gigabit Ethernet", -+ .phy_id_mask = MOTORCOMM_PHY_ID_MASK, -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) ) -+ .features = PHY_BASIC_FEATURES | PHY_GBIT_FEATURES, -+ .flags = PHY_HAS_INTERRUPT, -+#endif -+ .config_aneg = genphy_config_aneg, -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+ .config_init = ytphy_config_init, -+#else -+ .config_init = genphy_config_init, -+#endif -+ .read_status = genphy_read_status, -+ .suspend = genphy_suspend, -+ .resume = genphy_resume, -+#if (YTPHY_ENABLE_WOL) -+ .get_wol = &ytphy_get_wol, -+ .set_wol = &ytphy_set_wol, -+#endif -+ }, { -+ .phy_id = PHY_ID_YT8618, -+ .name = "YT8618 Ethernet", -+ .phy_id_mask = MOTORCOMM_MPHY_ID_MASK, -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) ) -+ .features = PHY_BASIC_FEATURES | PHY_GBIT_FEATURES, -+#endif -+ .flags = PHY_POLL, -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+#else -+ .soft_reset = yt8618_soft_reset, -+#endif -+ .config_aneg = genphy_config_aneg, -+#if ( LINUX_VERSION_CODE > KERNEL_VERSION(3,11,0) ) -+ .aneg_done = yt8618_aneg_done, -+#endif -+ .config_init = yt8618_config_init, -+ .read_status = yt8618_read_status, -+ .suspend = yt8618_suspend, -+ .resume = yt8618_resume, -+ }, { -+ .phy_id = PHY_ID_YT8614, -+ .name = "YT8614 Ethernet", -+ .phy_id_mask = MOTORCOMM_MPHY_ID_MASK_8614, -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) ) -+ .features = PHY_BASIC_FEATURES | PHY_GBIT_FEATURES, -+#endif -+ .flags = PHY_POLL, -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+#else -+ .soft_reset = yt8614_soft_reset, -+#endif -+ .config_aneg = genphy_config_aneg, -+#if ( LINUX_VERSION_CODE > KERNEL_VERSION(3,11,0) ) -+ .aneg_done = yt8614_aneg_done, -+#endif -+ .config_init = yt8614_config_init, -+ .read_status = yt8614_read_status, -+ .suspend = yt8614_suspend, -+ .resume = yt8614_resume, -+ }, -+}; -+ -+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) -+static int ytphy_drivers_register(struct phy_driver* phy_drvs, int size) -+{ -+ int i, j; -+ int ret; -+ -+ for (i = 0; i < size; i++) { -+ ret = phy_driver_register(&phy_drvs[i]); -+ if (ret) -+ goto err; -+ } -+ -+ return 0; -+ -+err: -+ for (j = 0; j < i; j++) -+ phy_driver_unregister(&phy_drvs[j]); -+ -+ return ret; -+} -+ -+static void ytphy_drivers_unregister(struct phy_driver* phy_drvs, int size) -+{ -+ int i; -+ -+ for (i = 0; i < size; i++) { -+ phy_driver_unregister(&phy_drvs[i]); -+ } -+} -+ -+static int __init ytphy_init(void) -+{ -+ printk("motorcomm phy register\n"); -+ return ytphy_drivers_register(ytphy_drvs, ARRAY_SIZE(ytphy_drvs)); -+} -+ -+static void __exit ytphy_exit(void) -+{ -+ printk("motorcomm phy unregister\n"); -+ ytphy_drivers_unregister(ytphy_drvs, ARRAY_SIZE(ytphy_drvs)); -+} -+ -+module_init(ytphy_init); -+module_exit(ytphy_exit); -+#else -+/* for linux 4.x */ -+module_phy_driver(ytphy_drvs); -+#endif -+ -+MODULE_DESCRIPTION("Motorcomm PHY driver"); -+MODULE_AUTHOR("Leilei Zhao"); -+MODULE_LICENSE("GPL"); -+ -+static struct mdio_device_id __maybe_unused motorcomm_tbl[] = { -+ { PHY_ID_YT8010, MOTORCOMM_PHY_ID_MASK }, -+ { PHY_ID_YT8510, MOTORCOMM_PHY_ID_MASK }, -+ { PHY_ID_YT8511, MOTORCOMM_PHY_ID_MASK }, -+ { PHY_ID_YT8512, MOTORCOMM_PHY_ID_MASK }, -+ { PHY_ID_YT8512B, MOTORCOMM_PHY_ID_MASK }, -+ { PHY_ID_YT8521, MOTORCOMM_PHY_ID_MASK }, -+ { PHY_ID_YT8531S, MOTORCOMM_PHY_ID_8531_MASK }, -+ { PHY_ID_YT8531, MOTORCOMM_PHY_ID_8531_MASK }, -+ { PHY_ID_YT8618, MOTORCOMM_MPHY_ID_MASK }, -+ { PHY_ID_YT8614, MOTORCOMM_MPHY_ID_MASK_8614 }, -+ { } -+}; -+ -+MODULE_DEVICE_TABLE(mdio, motorcomm_tbl); -+ -+ -diff --git a/drivers/net/phy/yt8614-phy.h b/drivers/net/phy/yt8614-phy.h -new file mode 100644 -index 000000000..56a398338 ---- /dev/null -+++ b/drivers/net/phy/yt8614-phy.h -@@ -0,0 +1,491 @@ -+#ifndef _PHY_H_ -+#define _PHY_H_ -+ -+ -+/* configuration for driver */ -+ -+#define YT8614_MAX_LPORT_ID 3 -+ -+#define YT8614_PHY_MODE_FIBER 1 //fiber mode only -+#define YT8614_PHY_MODE_UTP 2 //utp mode only -+#define YT8614_PHY_MODE_POLL 3 //fiber and utp, poll mode -+ -+/* please make choice according to system design -+ * for Fiber only system, please define YT8614_PHY_MODE_CURR 1 -+ * for UTP only system, please define YT8614_PHY_MODE_CURR 2 -+ * for combo system, please define YT8614_PHY_MODE_CURR 3 -+ */ -+#define YT8614_PHY_MODE_CURR 3 -+ -+ -+ -+/* pls dont modify below lines */ -+ -+#define PHY_ID_YT8614 0x4F51E899 //serdes -+#define MOTORCOMM_MPHY_ID_MASK_8614 0xffffffff -+ -+#ifndef BOOL -+#define BOOL unsigned int -+#endif -+ -+#ifndef FALSE -+#define FALSE 0 -+#endif -+ -+#ifndef TRUE -+#define TRUE 1 -+#endif -+ -+#ifndef SPEED_1000M -+#define SPEED_1000M 2 -+#endif -+#ifndef SPEED_100M -+#define SPEED_100M 1 -+#endif -+#ifndef SPEED_10M -+#define SPEED_10M 0 -+#endif -+ -+#ifndef SPEED_UNKNOWN -+#define SPEED_UNKNOWN 0xffff -+#endif -+ -+#ifndef DUPLEX_FULL -+#define DUPLEX_FULL 1 -+#endif -+#ifndef DUPLEX_HALF -+#define DUPLEX_HALF 0 -+#endif -+ -+#ifndef BIT -+#define BIT(n) (0x1<<(n)) -+#endif -+#ifndef s32 -+typedef int s32; -+typedef unsigned int u32; -+typedef unsigned short u16; -+typedef unsigned char u8; -+#endif -+ -+#ifndef REG_PHY_SPEC_STATUS -+#define REG_PHY_SPEC_STATUS 0x11 -+#define REG_DEBUG_ADDR_OFFSET 0x1e -+#define REG_DEBUG_DATA 0x1f -+#endif -+ -+/**********YT8614************************************************/ -+ -+#define YT8614_SMI_SEL_PHY 0x0 -+#define YT8614_SMI_SEL_SDS_QSGMII 0x02 -+#define YT8614_SMI_SEL_SDS_SGMII 0x03 -+ -+/* yt8614 register type */ -+#define YT8614_TYPE_COMMON 0x01 -+#define YT8614_TYPE_UTP_MII 0x02 -+#define YT8614_TYPE_UTP_EXT 0x03 -+#define YT8614_TYPE_LDS_MII 0x04 -+#define YT8614_TYPE_UTP_MMD 0x05 -+#define YT8614_TYPE_SDS_QSGMII_MII 0x06 -+#define YT8614_TYPE_SDS_SGMII_MII 0x07 -+#define YT8614_TYPE_SDS_QSGMII_EXT 0x08 -+#define YT8614_TYPE_SDS_SGMII_EXT 0x09 -+ -+/* YT8614 extended common register */ -+#define YT8614_REG_COM_SMI_MUX 0xA000 -+#define YT8614_REG_COM_SLED_CFG0 0xA001 -+#define YT8614_REG_COM_PHY_ID 0xA002 -+#define YT8614_REG_COM_CHIP_VER 0xA003 -+#define YT8614_REG_COM_SLED_CFG 0xA004 -+#define YT8614_REG_COM_MODE_CHG_RESET 0xA005 -+#define YT8614_REG_COM_SYNCE0_CFG 0xA006 -+#define YT8614_REG_COM_CHIP_MODE 0xA007 -+ -+#define YT8614_REG_COM_HIDE_SPEED 0xA009 -+ -+#define YT8614_REG_COM_SYNCE1_CFG 0xA00E -+ -+#define YT8614_REG_COM_HIDE_FIBER_MODE 0xA019 -+ -+ -+#define YT8614_REG_COM_HIDE_SEL1 0xA054 -+#define YT8614_REG_COM_HIDE_LED_CFG2 0xB8 -+#define YT8614_REG_COM_HIDE_LED_CFG3 0xB9 -+#define YT8614_REG_COM_HIDE_LED_CFG5 0xBB -+ -+#define YT8614_REG_COM_HIDE_LED_CFG4 0xBA //not used currently -+ -+#if 0 -+#define YT8614_REG_COM_HIDE_LED12_CFG 0xA060 //not used currently -+#define YT8614_REG_COM_HIDE_LED13_CFG 0xA061 -+#define YT8614_REG_COM_HIDE_LED14_CFG 0xA062 -+#define YT8614_REG_COM_HIDE_LED15_CFG 0xA063 -+#define YT8614_REG_COM_HIDE_LED16_CFG 0xA064 -+#define YT8614_REG_COM_HIDE_LED17_CFG 0xA065 -+#define YT8614_REG_COM_HIDE_LED18_CFG 0xA066 -+#define YT8614_REG_COM_HIDE_LED19_CFG 0xA067 -+#define YT8614_REG_COM_HIDE_LED20_CFG 0xA068 -+#define YT8614_REG_COM_HIDE_LED21_CFG 0xA069 -+#define YT8614_REG_COM_HIDE_LED22_CFG 0xA06A -+#define YT8614_REG_COM_HIDE_LED23_CFG 0xA06B -+#define YT8614_REG_COM_HIDE_LED24_CFG 0xA06C -+#define YT8614_REG_COM_HIDE_LED25_CFG 0xA06D -+#define YT8614_REG_COM_HIDE_LED26_CFG 0xA06E -+#define YT8614_REG_COM_HIDE_LED27_CFG 0xA06F -+#endif -+ -+#define YT8614_REG_COM_HIDE_LED28_CFG 0xA070 -+#define YT8614_REG_COM_HIDE_LED29_CFG 0xA071 -+#define YT8614_REG_COM_HIDE_LED30_CFG 0xA072 -+#define YT8614_REG_COM_HIDE_LED31_CFG 0xA073 -+#define YT8614_REG_COM_HIDE_LED32_CFG 0xA074 -+#define YT8614_REG_COM_HIDE_LED33_CFG 0xA075 -+#define YT8614_REG_COM_HIDE_LED34_CFG 0xA076 -+#define YT8614_REG_COM_HIDE_LED35_CFG 0xA077 -+ -+#define YT8614_REG_COM_PKG_CFG0 0xA0A0 -+#define YT8614_REG_COM_PKG_CFG1 0xA0A1 -+#define YT8614_REG_COM_PKG_CFG2 0xA0A2 -+#define YT8614_REG_COM_PKG_RX_VALID0 0xA0A3 -+#define YT8614_REG_COM_PKG_RX_VALID1 0xA0A4 -+#define YT8614_REG_COM_PKG_RX_OS0 0xA0A5 -+#define YT8614_REG_COM_PKG_RX_OS1 0xA0A6 -+#define YT8614_REG_COM_PKG_RX_US0 0xA0A7 -+#define YT8614_REG_COM_PKG_RX_US1 0xA0A8 -+#define YT8614_REG_COM_PKG_RX_ERR 0xA0A9 -+#define YT8614_REG_COM_PKG_RX_OS_BAD 0xA0AA -+#define YT8614_REG_COM_PKG_RX_FRAG 0xA0AB -+#define YT8614_REG_COM_PKG_RX_NOSFD 0xA0AC -+#define YT8614_REG_COM_PKG_TX_VALID0 0xA0AD -+#define YT8614_REG_COM_PKG_TX_VALID1 0xA0AE -+#define YT8614_REG_COM_PKG_TX_OS0 0xA0AF -+ -+#define YT8614_REG_COM_PKG_TX_OS1 0xA0B0 -+#define YT8614_REG_COM_PKG_TX_US0 0xA0B1 -+#define YT8614_REG_COM_PKG_TX_US1 0xA0B2 -+#define YT8614_REG_COM_PKG_TX_ERR 0xA0B3 -+#define YT8614_REG_COM_PKG_TX_OS_BAD 0xA0B4 -+#define YT8614_REG_COM_PKG_TX_FRAG 0xA0B5 -+#define YT8614_REG_COM_PKG_TX_NOSFD 0xA0B6 -+#define YT8614_REG_COM_PKG_CFG3 0xA0B7 -+#define YT8614_REG_COM_PKG_AZ_CFG 0xA0B8 -+#define YT8614_REG_COM_PKG_DA_SA_CFG3 0xA0B9 -+ -+#define YT8614_REG_COM_MANU_HW_RESET 0xA0C0 -+ -+/* YT8614 UTP MII register: same as generic phy register definitions */ -+#define REG_MII_BMCR 0x00 /* Basic mode control register */ -+#define REG_MII_BMSR 0x01 /* Basic mode status register */ -+#define REG_MII_PHYSID1 0x02 /* PHYS ID 1 */ -+#define REG_MII_PHYSID2 0x03 /* PHYS ID 2 */ -+#define REG_MII_ADVERTISE 0x04 /* Advertisement control reg */ -+#define REG_MII_LPA 0x05 /* Link partner ability reg */ -+#define REG_MII_EXPANSION 0x06 /* Expansion register */ -+#define REG_MII_NEXT_PAGE 0x07 /* Next page register */ -+#define REG_MII_LPR_NEXT_PAGE 0x08 /* LPR next page register */ -+#define REG_MII_CTRL1000 0x09 /* 1000BASE-T control */ -+#define REG_MII_STAT1000 0x0A /* 1000BASE-T status */ -+ -+#define REG_MII_MMD_CTRL 0x0D /* MMD access control register */ -+#define REG_MII_MMD_DATA 0x0E /* MMD access data register */ -+ -+#define REG_MII_ESTATUS 0x0F /* Extended Status */ -+#define REG_MII_SPEC_CTRL 0x10 /* PHY specific func control */ -+#define REG_MII_SPEC_STATUS 0x11 /* PHY specific status */ -+#define REG_MII_INT_MASK 0x12 /* Interrupt mask register */ -+#define REG_MII_INT_STATUS 0x13 /* Interrupt status register */ -+#define REG_MII_DOWNG_CTRL 0x14 /* Speed auto downgrade control*/ -+#define REG_MII_RERRCOUNTER 0x15 /* Receive error counter */ -+ -+#define REG_MII_EXT_ADDR 0x1E /* Extended reg's address */ -+#define REG_MII_EXT_DATA 0x1F /* Extended reg's date */ -+ -+#ifndef MII_BMSR -+#define MII_BMSR REG_MII_BMSR -+#endif -+ -+#ifndef YT8614_SPEED_MODE_BIT -+#define YT8614_SPEED_MODE 0xc000 -+#define YT8614_DUPLEX 0x2000 -+#define YT8614_SPEED_MODE_BIT 14 -+#define YT8614_DUPLEX_BIT 13 -+#define YT8614_LINK_STATUS_BIT 10 -+ -+#endif -+ -+#define YT8614_REG_COM_HIDE_SPEED_CMB_PRI 0x2000 -+ -+/* YT8614 UTP MMD register */ -+#define YT8614_REG_UTP_MMD_CTRL1 0x00 /* PCS control 1 register */ -+#define YT8614_REG_UTP_MMD_STATUS1 0x01 /* PCS status 1 register */ -+#define YT8614_REG_UTP_MMD_EEE_CTRL 0x14 /* EEE control and capability */ -+#define YT8614_REG_UTP_MMD_EEE_WK_ERR_CNT 0x16 /* EEE wake error counter */ -+#define YT8614_REG_UTP_MMD_EEE_LOCAL_ABI 0x3C /* local device EEE ability */ -+#define YT8614_REG_UTP_MMD_EEE_LP_ABI 0x3D /* link partner EEE ability */ -+#define YT8614_REG_UTP_MMD_EEE_AUTONEG_RES 0x8000 /* autoneg result of EEE */ -+ -+/* YT8614 UTP EXT register */ -+#define YT8614_REG_UTP_EXT_LPBK 0x0A -+#define YT8614_REG_UTP_EXT_SLEEP_CTRL1 0x27 -+#define YT8614_REG_UTP_EXT_DEBUG_MON1 0x5A -+#define YT8614_REG_UTP_EXT_DEBUG_MON2 0x5B -+#define YT8614_REG_UTP_EXT_DEBUG_MON3 0x5C -+#define YT8614_REG_UTP_EXT_DEBUG_MON4 0x5D -+ -+/* YT8614 SDS(1.25G/5G) MII register: same as YT8521S */ -+#define REG_SDS_BMCR 0x00 /* Basic mode control register */ -+#define REG_SDS_BMSR 0x01 /* Basic mode status register */ -+#define REG_SDS_PHYSID1 0x02 /* PHYS ID 1 */ -+#define REG_SDS_PHYSID2 0x03 /* PHYS ID 2 */ -+#define REG_SDS_ADVERTISE 0x04 /* Advertisement control reg */ -+#define REG_SDS_LPA 0x05 /* Link partner ability reg */ -+#define REG_SDS_EXPANSION 0x06 /* Expansion register */ -+#define REG_SDS_NEXT_PAGE 0x07 /* Next page register */ -+#define REG_SDS_LPR_NEXT_PAGE 0x08 /* LPR next page register */ -+ -+#define REG_SDS_ESTATUS 0x0F /* Extended Status */ -+#define REG_SDS_SPEC_STATUS 0x11 /* SDS specific status */ -+ -+#define REG_SDS_100FX_CFG 0x14 /* 100fx cfg */ -+#define REG_SDS_RERRCOUNTER 0x15 /* Receive error counter */ -+#define REG_SDS_LINT_FAIL_CNT 0x16 /* Lint fail counter mon */ -+ -+/* YT8614 SDS(5G) EXT register */ -+#define YT8614_REG_QSGMII_EXT_ANA_DIG_CFG 0x02 /* sds analog digital interface cfg */ -+#define YT8614_REG_QSGMII_EXT_PRBS_CFG1 0x05 /* sds prbs cfg1 */ -+#define YT8614_REG_QSGMII_EXT_PRBS_CFG2_1 0x06 /* sds prbs cfg2 */ -+#define YT8614_REG_QSGMII_EXT_PRBS_CFG2_2 0x07 /* sds prbs cfg2 */ -+#define YT8614_REG_QSGMII_EXT_PRBS_MON1 0x08 /* sds prbs mon1 */ -+#define YT8614_REG_QSGMII_EXT_PRBS_MON2 0x09 /* sds prbs mon2 */ -+#define YT8614_REG_QSGMII_EXT_PRBS_MON3 0x0A /* sds prbs mon3 */ -+#define YT8614_REG_QSGMII_EXT_PRBS_MON4 0x0B /* sds prbs mon4 */ -+#define YT8614_REG_QSGMII_EXT_PRBS_MON5 0x0C /* sds prbs mon5 */ -+#define YT8614_REG_QSGMII_EXT_ANA_CFG2 0xA1 /* Analog cfg2 */ -+ -+/* YT8614 SDS(1.25G) EXT register */ -+#define YT8614_REG_SGMII_EXT_PRBS_CFG1 0x05 /* sds prbs cfg1 */ -+#define YT8614_REG_SGMII_EXT_PRBS_CFG2 0x06 /* sds prbs cfg2 */ -+#define YT8614_REG_SGMII_EXT_PRBS_MON1 0x08 /* sds prbs mon1 */ -+#define YT8614_REG_SGMII_EXT_PRBS_MON2 0x09 /* sds prbs mon2 */ -+#define YT8614_REG_SGMII_EXT_PRBS_MON3 0x0A /* sds prbs mon3 */ -+#define YT8614_REG_SGMII_EXT_PRBS_MON4 0x0B /* sds prbs mon4 */ -+#define YT8614_REG_SGMII_EXT_PRBS_MON5 0x0C /* sds prbs mon5 */ -+#define YT8614_REG_SGMII_EXT_ANA_CFG2 0xA1 /* Analog cfg2 */ -+#define YT8614_REG_SGMII_EXT_HIDE_AUTO_SEN 0xA5 /* Fiber auto sensing */ -+ -+//////////////////////////////////////////////////////////////////// -+#define YT8614_MMD_DEV_ADDR1 0x1 -+#define YT8614_MMD_DEV_ADDR3 0x3 -+#define YT8614_MMD_DEV_ADDR7 0x7 -+#define YT8614_MMD_DEV_ADDR_NONE 0xFF -+ -+/**********YT8521S************************************************/ -+/* Basic mode control register(0x00) */ -+#define BMCR_RESV 0x003f /* Unused... */ -+#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */ -+#define BMCR_CTST 0x0080 /* Collision test */ -+#define BMCR_FULLDPLX 0x0100 /* Full duplex */ -+#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */ -+#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */ -+#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */ -+#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */ -+#define BMCR_SPEED100 0x2000 /* Select 100Mbps */ -+#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */ -+#define BMCR_RESET 0x8000 /* Reset the DP83840 */ -+ -+/* Basic mode status register(0x01) */ -+#define BMSR_ERCAP 0x0001 /* Ext-reg capability */ -+#define BMSR_JCD 0x0002 /* Jabber detected */ -+#define BMSR_LSTATUS 0x0004 /* Link status */ -+#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */ -+#define BMSR_RFAULT 0x0010 /* Remote fault detected */ -+#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */ -+#define BMSR_RESV 0x00c0 /* Unused... */ -+#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */ -+#define BMSR_100HALF2 0x0200 /* Can do 100BASE-T2 HDX */ -+#define BMSR_100FULL2 0x0400 /* Can do 100BASE-T2 FDX */ -+#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */ -+#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */ -+#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */ -+#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */ -+#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */ -+ -+/* Advertisement control register(0x04) */ -+#define ADVERTISE_SLCT 0x001f /* Selector bits */ -+#define ADVERTISE_CSMA 0x0001 /* Only selector supported */ -+#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */ -+#define ADVERTISE_1000XFULL 0x0020 /* Try for 1000BASE-X full-duplex */ -+#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */ -+#define ADVERTISE_1000XHALF 0x0040 /* Try for 1000BASE-X half-duplex */ -+#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */ -+#define ADVERTISE_1000XPAUSE 0x0080 /* Try for 1000BASE-X pause */ -+#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */ -+#define ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */ -+#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */ -+#define ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */ -+#define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymetric pause */ -+#define ADVERTISE_RESV 0x1000 /* Unused... */ -+#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */ -+#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */ -+#define ADVERTISE_NPAGE 0x8000 /* Next page bit */ -+ -+#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | ADVERTISE_CSMA) -+#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \ -+ ADVERTISE_100HALF | ADVERTISE_100FULL) -+ -+/* Link partner ability register(0x05) */ -+#define LPA_SLCT 0x001f /* Same as advertise selector */ -+#define LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */ -+#define LPA_1000XFULL 0x0020 /* Can do 1000BASE-X full-duplex */ -+#define LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */ -+#define LPA_1000XHALF 0x0040 /* Can do 1000BASE-X half-duplex */ -+#define LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */ -+#define LPA_1000XPAUSE 0x0080 /* Can do 1000BASE-X pause */ -+#define LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */ -+#define LPA_1000XPAUSE_ASYM 0x0100 /* Can do 1000BASE-X pause asym */ -+#define LPA_100BASE4 0x0200 /* Can do 100mbps 4k packets */ -+#define LPA_PAUSE_CAP 0x0400 /* Can pause */ -+#define LPA_PAUSE_ASYM 0x0800 /* Can pause asymetrically */ -+#define LPA_RESV 0x1000 /* Unused... */ -+#define LPA_RFAULT 0x2000 /* Link partner faulted */ -+#define LPA_LPACK 0x4000 /* Link partner acked us */ -+#define LPA_NPAGE 0x8000 /* Next page bit */ -+ -+/* 1000BASE-T Control register(0x09) */ -+#define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */ -+#define ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */ -+#define CTL1000_AS_MASTER 0x0800 -+#define CTL1000_ENABLE_MASTER 0x1000 -+ -+/* 1000BASE-T Status register(0x0A) */ -+#define LPA_1000LOCALRXOK 0x2000 /* Link partner local receiver status */ -+#define LPA_1000REMRXOK 0x1000 /* Link partner remote receiver status */ -+#define LPA_1000FULL 0x0800 /* Link partner 1000BASE-T full duplex */ -+#define LPA_1000HALF 0x0400 /* Link partner 1000BASE-T half duplex */ -+ -+/**********YT8614************************************************/ -+/* Basic mode control register(0x00) */ -+#define FIBER_BMCR_RESV 0x001f /* b[4:0] Unused... */ -+#define FIBER_BMCR_EN_UNIDIR 0x0020 /* b[5] Valid when bit 0.12 is zero and bit 0.8 is one */ -+#define FIBER_BMCR_SPEED1000 0x0040 /* b[6] MSB of Speed (1000) */ -+#define FIBER_BMCR_CTST 0x0080 /* b[7] Collision test */ -+#define FIBER_BMCR_DUPLEX_MODE 0x0100 /* b[8] Duplex mode */ -+#define FIBER_BMCR_ANRESTART 0x0200 /* b[9] Auto negotiation restart */ -+#define FIBER_BMCR_ISOLATE 0x0400 /* b[10] Isolate phy from RGMII/SGMII/FIBER */ -+#define FIBER_BMCR_PDOWN 0x0800 /* b[11] 1: Power down */ -+#define FIBER_BMCR_ANENABLE 0x1000 /* b[12] Enable auto negotiation */ -+#define FIBER_BMCR_SPEED100 0x2000 /* b[13] LSB of Speed (100) */ -+#define FIBER_BMCR_LOOPBACK 0x4000 /* b[14] Internal loopback control */ -+#define FIBER_BMCR_RESET 0x8000 /* b[15] PHY Software Reset(self-clear) */ -+ -+/* Sds specific status register(0x11) */ -+#define FIBER_SSR_ERCAP 0x0001 /* b[0] realtime syncstatus */ -+#define FIBER_SSR_XMIT 0x000E /* b[3:1] realtime transmit statemachine. -+ 001: Xmit Idle; -+ 010: Xmit Config; -+ 100: Xmit Data. */ -+#define FIBER_SSR_SER_MODE_CFG 0x0030 /* b[5:4] realtime serdes working mode. -+ 00: SG_MAC; -+ 01: SG_PHY; -+ 10: FIB_1000; -+ 11: FIB_100. */ -+#define FIBER_SSR_EN_FLOWCTRL_TX 0x0040 /* b[6] realtime en_flowctrl_tx */ -+#define FIBER_SSR_EN_FLOWCTRL_RX 0x0080 /* b[7] realtime en_flowctrl_rx */ -+#define FIBER_SSR_DUPLEX_ERROR 0x0100 /* b[8] realtime deplex error */ -+#define FIBER_SSR_RX_LPI_ACTIVE 0x0200 /* b[9] rx lpi is active */ -+#define FIBER_SSR_LSTATUS 0x0400 /* b[10] Link status real-time */ -+#define FIBER_SSR_PAUSE 0x1800 /* b[12:11] Pause to mac */ -+#define FIBER_SSR_DUPLEX 0x2000 /* b[13] This status bit is valid only when bit10 is 1. -+ 1: full duplex -+ 0: half duplex */ -+#define FIBER_SSR_SPEED_MODE 0xC000 /* b[15:14] These status bits are valid only when bit10 is 1. -+ 10---1000M -+ 01---100M */ -+ -+/* SLED cfg0 (ext 0xA001) */ -+#define FIBER_SLED_CFG0_EN_CTRL 0x00FF /* b[7:0] Control to enable the eight ports' SLED */ -+#define FIBER_SLED_CFG0_BIT_MASK 0x0700 /* b[10:8] 1: enable the pin output */ -+#define FIBER_SLED_CFG0_ACT_LOW 0x0800 /* b[11] control SLED's polarity. 1: active low; 0: active high */ -+#define FIBER_SLED_CFG0_MANU_ST 0x7000 /* b[14:12] SLEDs' manul status, corresponding to each port's 3 SLEDs */ -+#define FIBER_SLED_CFG0_MANU_EN 0x8000 /* b[15] to control serial LEDs status manually */ -+ -+/**********YT8614************************************************/ -+/* Fiber auto sensing(sgmii ext 0xA5) */ -+#define FIBER_AUTO_SEN_ENABLE 0x8000 /* b[15] Enable fiber auto sensing */ -+ -+/* Fiber force speed(common ext 0xA009) */ -+#define FIBER_FORCE_1000M 0x0001 /* b[0] 1:1000BX 0:100FX */ -+ -+#ifndef NULL -+#define NULL 0 -+#endif -+ -+/* errno */ -+enum ytphy_8614_errno_e -+{ -+ SYS_E_NONE, -+ SYS_E_PARAM, -+ SYS_E_MAX -+}; -+ -+/* errno */ -+enum ytphy_8614_combo_speed_e -+{ -+ YT8614_COMBO_FIBER_1000M, -+ YT8614_COMBO_FIBER_100M, -+ YT8614_COMBO_UTP_ONLY, -+ YT8614_COMBO_SPEED_MAX -+}; -+ -+/* definition for porting */ -+/* phy registers access */ -+typedef struct -+{ -+ u16 reg; /* the offset of the phy internal address */ -+ u16 val; /* the value of the register */ -+ u8 regType; /* register type */ -+} phy_data_s; -+ -+/* for porting use. -+ * pls over-write member function read/write for mdio access -+ */ -+typedef struct phy_info_str -+{ -+#if 0 -+ struct phy_device *phydev; -+ int mdio_base; -+#endif -+ unsigned int lport; -+ unsigned int bus_id; -+ unsigned int phy_addr; -+ -+ s32 (*read)(struct phy_info_str *info, phy_data_s *param); -+ s32 (*write)(struct phy_info_str *info, phy_data_s *param); -+}phy_info_s; -+ -+/* get phy access method */ -+s32 yt8614_read_reg(struct phy_info_str *info, phy_data_s *param); -+s32 yt8614_write_reg(struct phy_info_str *info, phy_data_s *param); -+s32 yt8614_phy_soft_reset(u32 lport); -+s32 yt8614_phy_init(u32 lport); -+s32 yt8614_fiber_enable(u32 lport, BOOL enable); -+s32 yt8614_utp_enable(u32 lport, BOOL enable); -+s32 yt8614_fiber_unidirection_set(u32 lport, int speed, BOOL enable); -+s32 yt8614_fiber_autosensing_set(u32 lport, BOOL enable); -+s32 yt8614_fiber_speed_set(u32 lport, int fiber_speed); -+s32 yt8614_qsgmii_autoneg_set(u32 lport, BOOL enable); -+s32 yt8614_sgmii_autoneg_set(u32 lport, BOOL enable); -+s32 yt8614_qsgmii_sgmii_link_status_get(u32 lport, BOOL *enable, BOOL if_qsgmii); -+int yt8614_combo_media_priority_set (u32 lport, int fiber); -+int yt8614_combo_media_priority_get (u32 lport, int *fiber); -+s32 yt8614_utp_autoneg_set(u32 lport, BOOL enable); -+s32 yt8614_utp_autoneg_get(u32 lport, BOOL *enable); -+s32 yt8614_utp_autoneg_ability_set(u32 lport, unsigned int cap_mask); -+s32 yt8614_utp_autoneg_ability_get(u32 lport, unsigned int *cap_mask); -+s32 yt8614_utp_force_duplex_set(u32 lport, BOOL full); -+s32 yt8614_utp_force_duplex_get(u32 lport, BOOL *full); -+s32 yt8614_utp_force_speed_set(u32 lport, unsigned int speed); -+s32 yt8614_utp_force_speed_get(u32 lport, unsigned int *speed); -+int yt8614_autoneg_done_get (u32 lport, int speed, int *aneg); -+int yt8614_media_status_get(u32 lport, int* speed, int* duplex, int* ret_link, int *media); -+ -+#endif -diff --git a/include/linux/motorcomm_phy.h b/include/linux/motorcomm_phy.h -new file mode 100644 -index 000000000..9e01fc205 ---- /dev/null -+++ b/include/linux/motorcomm_phy.h -@@ -0,0 +1,119 @@ -+/* -+ * include/linux/motorcomm_phy.h -+ * -+ * Motorcomm PHY IDs -+ * -+ * 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. -+ * -+ */ -+ -+#ifndef _MOTORCOMM_PHY_H -+#define _MOTORCOMM_PHY_H -+ -+#define MOTORCOMM_PHY_ID_MASK 0x00000fff -+#define MOTORCOMM_PHY_ID_8531_MASK 0xffffffff -+#define MOTORCOMM_MPHY_ID_MASK 0x0000ffff -+ -+#define PHY_ID_YT8010 0x00000309 -+#define PHY_ID_YT8510 0x00000109 -+#define PHY_ID_YT8511 0x0000010a -+#define PHY_ID_YT8512 0x00000118 -+#define PHY_ID_YT8512B 0x00000128 -+#define PHY_ID_YT8521 0x0000011a -+#define PHY_ID_YT8531S 0x4f51e91a -+#define PHY_ID_YT8531 0x4f51e91b -+//#define PHY_ID_YT8614 0x0000e899 -+#define PHY_ID_YT8618 0x0000e889 -+ -+#define REG_PHY_SPEC_STATUS 0x11 -+#define REG_DEBUG_ADDR_OFFSET 0x1e -+#define REG_DEBUG_DATA 0x1f -+ -+#define YT8512_EXTREG_AFE_PLL 0x50 -+#define YT8512_EXTREG_EXTEND_COMBO 0x4000 -+#define YT8512_EXTREG_LED0 0x40c0 -+#define YT8512_EXTREG_LED1 0x40c3 -+ -+#define YT8512_EXTREG_SLEEP_CONTROL1 0x2027 -+ -+#define YT_SOFTWARE_RESET 0x8000 -+ -+#define YT8512_CONFIG_PLL_REFCLK_SEL_EN 0x0040 -+#define YT8512_CONTROL1_RMII_EN 0x0001 -+#define YT8512_LED0_ACT_BLK_IND 0x1000 -+#define YT8512_LED0_DIS_LED_AN_TRY 0x0001 -+#define YT8512_LED0_BT_BLK_EN 0x0002 -+#define YT8512_LED0_HT_BLK_EN 0x0004 -+#define YT8512_LED0_COL_BLK_EN 0x0008 -+#define YT8512_LED0_BT_ON_EN 0x0010 -+#define YT8512_LED1_BT_ON_EN 0x0010 -+#define YT8512_LED1_TXACT_BLK_EN 0x0100 -+#define YT8512_LED1_RXACT_BLK_EN 0x0200 -+#define YT8512_SPEED_MODE 0xc000 -+#define YT8512_DUPLEX 0x2000 -+ -+#define YT8512_SPEED_MODE_BIT 14 -+#define YT8512_DUPLEX_BIT 13 -+#define YT8512_EN_SLEEP_SW_BIT 15 -+ -+#define YT8521_EXTREG_SLEEP_CONTROL1 0x27 -+#define YT8521_EN_SLEEP_SW_BIT 15 -+ -+#define YT8521_SPEED_MODE 0xc000 -+#define YT8521_DUPLEX 0x2000 -+#define YT8521_SPEED_MODE_BIT 14 -+#define YT8521_DUPLEX_BIT 13 -+#define YT8521_LINK_STATUS_BIT 10 -+ -+/* based on yt8521 wol config register */ -+#define YTPHY_UTP_INTR_REG 0x12 -+/* WOL Event Interrupt Enable */ -+#define YTPHY_WOL_INTR BIT(6) -+ -+/* Magic Packet MAC address registers */ -+#define YTPHY_MAGIC_PACKET_MAC_ADDR2 0xa007 -+#define YTPHY_MAGIC_PACKET_MAC_ADDR1 0xa008 -+#define YTPHY_MAGIC_PACKET_MAC_ADDR0 0xa009 -+ -+#define YTPHY_WOL_CFG_REG 0xa00a -+#define YTPHY_WOL_CFG_TYPE BIT(0) /* WOL TYPE */ -+#define YTPHY_WOL_CFG_EN BIT(3) /* WOL Enable */ -+#define YTPHY_WOL_CFG_INTR_SEL BIT(6) /* WOL Event Interrupt Enable */ -+#define YTPHY_WOL_CFG_WIDTH1 BIT(1) /* WOL Pulse Width */ -+#define YTPHY_WOL_CFG_WIDTH2 BIT(2) -+ -+#define YTPHY_REG_SPACE_UTP 0 -+#define YTPHY_REG_SPACE_FIBER 2 -+ -+enum ytphy_wol_type_e -+{ -+ YTPHY_WOL_TYPE_LEVEL, -+ YTPHY_WOL_TYPE_PULSE, -+ YTPHY_WOL_TYPE_MAX -+}; -+typedef enum ytphy_wol_type_e ytphy_wol_type_t; -+ -+enum ytphy_wol_width_e -+{ -+ YTPHY_WOL_WIDTH_84MS, -+ YTPHY_WOL_WIDTH_168MS, -+ YTPHY_WOL_WIDTH_336MS, -+ YTPHY_WOL_WIDTH_672MS, -+ YTPHY_WOL_WIDTH_MAX -+}; -+typedef enum ytphy_wol_width_e ytphy_wol_width_t; -+ -+struct ytphy_wol_cfg_s -+{ -+ int enable; -+ int type; -+ int width; -+}; -+typedef struct ytphy_wol_cfg_s ytphy_wol_cfg_t; -+ -+#endif /* _MOTORCOMM_PHY_H */ -+ -+ --- -2.25.1 - diff --git a/patch/kernel/archive/rockchip64-6.1/add-maker-friendlyarm.patch b/patch/kernel/archive/rockchip64-6.1/add-maker-friendlyarm.patch deleted file mode 100644 index f48596bc5637..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/add-maker-friendlyarm.patch +++ /dev/null @@ -1,211 +0,0 @@ -From 2fc2cbaaaf0dcebdeffa6e87bbc9ad843a5470dd Mon Sep 17 00:00:00 2001 -From: hmz007 -Date: Sat, 11 Jan 2020 19:35:03 +0800 -Subject: [PATCH] soc: friendlyelec: Add board info driver - -Change-Id: I122adb4f99c816b5c177f16392fb2df9c10a47be -Signed-off-by: hmz007 ---- - drivers/soc/Kconfig | 1 + - drivers/soc/Makefile | 1 + - drivers/soc/friendlyelec/Kconfig | 11 ++ - drivers/soc/friendlyelec/Makefile | 1 + - drivers/soc/friendlyelec/board.c | 143 ++++++++++++++++++ - 8 files changed, 161 insertions(+) - create mode 100644 drivers/soc/friendlyelec/Kconfig - create mode 100644 drivers/soc/friendlyelec/Makefile - create mode 100644 drivers/soc/friendlyelec/board.c - -diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig -index 833e04a7835c..9ddbd976395d 100644 ---- a/drivers/soc/Kconfig -+++ b/drivers/soc/Kconfig -@@ -21,5 +21,6 @@ source "drivers/soc/ux500/Kconfig" - source "drivers/soc/ux500/Kconfig" - source "drivers/soc/versatile/Kconfig" - source "drivers/soc/xilinx/Kconfig" -+source "drivers/soc/friendlyelec/Kconfig" - - endmenu -diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile -index f678e4d9e..cfc815a7e 100644 ---- a/drivers/soc/Makefile -+++ b/drivers/soc/Makefile -@@ -29,3 +29,4 @@ obj-y += ti/ - obj-$(CONFIG_ARCH_U8500) += ux500/ - obj-$(CONFIG_PLAT_VERSATILE) += versatile/ - obj-y += xilinx/ -+obj-$(CONFIG_VENDOR_FRIENDLYELEC) += friendlyelec/ -diff --git a/drivers/soc/friendlyelec/Kconfig b/drivers/soc/friendlyelec/Kconfig -new file mode 100644 -index 000000000000..9e21c663e6c8 ---- /dev/null -+++ b/drivers/soc/friendlyelec/Kconfig -@@ -0,0 +1,11 @@ -+# -+# Machine drivers -+# -+ -+if ARCH_ROCKCHIP -+ -+config VENDOR_FRIENDLYELEC -+ bool "FriendlyElec board based on RK33XX SoCs" -+ default n -+ -+endif -diff --git a/drivers/soc/friendlyelec/Makefile b/drivers/soc/friendlyelec/Makefile -new file mode 100644 -index 000000000000..870542f05177 ---- /dev/null -+++ b/drivers/soc/friendlyelec/Makefile -@@ -0,0 +1 @@ -+obj-$(CONFIG_VENDOR_FRIENDLYELEC) += board.o -diff --git a/drivers/soc/friendlyelec/board.c b/drivers/soc/friendlyelec/board.c -new file mode 100644 -index 000000000000..886a8e1f7dc0 ---- /dev/null -+++ b/drivers/soc/friendlyelec/board.c -@@ -0,0 +1,143 @@ -+/* -+ * Copyright (C) Guangzhou FriendlyELEC Computer Tech. Co., Ltd. -+ * (http://www.friendlyarm.com) -+ * -+ * 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, you can access it online at -+ * http://www.gnu.org/licenses/gpl-2.0.html. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define BOARD_MANF "FriendlyELEC Computer Tech. Co., Ltd." -+ -+static const char *board_mach; -+static const char *board_name; -+static u32 board_rev; -+static u32 board_serial_high, board_serial_low; -+ -+static ssize_t board_sys_info_show(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ char *s = buf; -+ -+ s += sprintf(s, "Hardware\t: %s\n", board_mach); -+ s += sprintf(s, "Revision\t: %04x\n", board_rev); -+ s += sprintf(s, "Serial\t\t: %08x%08x\n", -+ board_serial_high, board_serial_low); -+ s += sprintf(s, "\nModel\t\t: %s\n", board_name); -+ s += sprintf(s, "Manufacturer\t: %s\n", BOARD_MANF); -+ -+ return (s - buf); -+} -+ -+static struct device_attribute board_attr_info = -+ __ATTR(info, S_IRUGO, board_sys_info_show, NULL); -+ -+static int rockchip_cpuinfo_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct nvmem_cell *cell; -+ unsigned char *efuse_buf, buf[16]; -+ size_t len; -+ int i; -+ -+ cell = nvmem_cell_get(dev, "id"); -+ if (IS_ERR(cell)) { -+ dev_err(dev, "failed to get id cell: %ld\n", PTR_ERR(cell)); -+ return PTR_ERR(cell); -+ } -+ -+ efuse_buf = nvmem_cell_read(cell, &len); -+ nvmem_cell_put(cell); -+ -+ if (len != 16) { -+ kfree(efuse_buf); -+ dev_err(dev, "invalid id len: %zu\n", len); -+ return -EINVAL; -+ } -+ -+ for (i = 0; i < 8; i++) { -+ buf[i] = efuse_buf[1 + (i << 1)]; -+ buf[i + 8] = efuse_buf[i << 1]; -+ } -+ -+ kfree(efuse_buf); -+ -+ board_serial_low = crc32(0, buf, 8); -+ board_serial_high = crc32(board_serial_low, buf + 8, 8); -+ -+ dev_info(dev, "Serial\t\t: %08x%08x\n", -+ board_serial_high, board_serial_low); -+ -+ return 0; -+} -+ -+static int board_sys_probe(struct platform_device *pdev) -+{ -+ struct device_node *np = pdev->dev.of_node; -+ struct device_node *root; -+ -+ root = of_find_node_by_path("/"); -+ -+ of_property_read_u32(np, "hwrev", &board_rev); -+ -+ if (of_property_read_string(np, "machine", &board_mach)) -+ of_property_read_string(root, "compatible", &board_mach); -+ -+ if (of_property_read_string(np, "model", &board_name)) -+ of_property_read_string(root, "model", &board_name); -+ -+ of_node_put(root); -+ -+ rockchip_cpuinfo_probe(pdev); -+ -+ device_create_file(&pdev->dev, &board_attr_info); -+ -+ return 0; -+} -+ -+static const struct of_device_id board_sys_of_match[] = { -+ { .compatible = "friendlyelec,board" }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, board_sys_of_match); -+ -+static struct platform_driver board_sys_driver = { -+ .probe = board_sys_probe, -+ .driver = { -+ .name = "friendlyelec-board", -+ .of_match_table = board_sys_of_match, -+ }, -+}; -+ -+static int __init board_sys_init(void) -+{ -+ return platform_driver_register(&board_sys_driver); -+} -+late_initcall(board_sys_init); -+ -+MODULE_AUTHOR("support@friendlyarm.com"); -+MODULE_DESCRIPTION("FriendlyElec NanoPi Series Machine Driver"); -+MODULE_LICENSE("GPL v2"); diff --git a/patch/kernel/archive/rockchip64-6.1/board-helios64-dts-fix-stability-issues.patch b/patch/kernel/archive/rockchip64-6.1/board-helios64-dts-fix-stability-issues.patch deleted file mode 100644 index bc64c1a7050a..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-helios64-dts-fix-stability-issues.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts -index e666bd5ae..df1fc943b 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts -@@ -478,6 +478,7 @@ rk808: pmic@1b { - pinctrl-names = "default"; - pinctrl-0 = <&pmic_int_l>; - rockchip,system-power-controller; -+ max-buck-steps-per-change = <4>; - wakeup-source; - - vcc1-supply = <&vcc5v0_sys>; diff --git a/patch/kernel/archive/rockchip64-6.1/board-helios64-remove-overclock.patch b/patch/kernel/archive/rockchip64-6.1/board-helios64-remove-overclock.patch deleted file mode 100644 index c99b7fa1d132..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-helios64-remove-overclock.patch +++ /dev/null @@ -1,32 +0,0 @@ -From aca2e1df74ae43ddaa3870b31a6eba129148bdcf Mon Sep 17 00:00:00 2001 -From: Aditya Prayoga -Date: Mon, 7 Sep 2020 20:29:43 +0700 -Subject: [PATCH] Remove overclock from helios64 - -Signed-off-by: Aditya Prayoga ---- - arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts -index ba8ff5d4c..c065ba82d 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts -@@ -1078,4 +1078,12 @@ - - &vopl_mmu { - status = "okay"; --}; -\ No newline at end of file -+}; -+ -+&cluster0_opp { -+ /delete-node/ opp06; -+}; -+ -+&cluster1_opp { -+ /delete-node/ opp08; -+}; --- -Created with Armbian build tools https://github.com/armbian/build - diff --git a/patch/kernel/archive/rockchip64-6.1/board-helios64-remove-pcie-ep-gpios.patch b/patch/kernel/archive/rockchip64-6.1/board-helios64-remove-pcie-ep-gpios.patch deleted file mode 100644 index d7a94963dd6d..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-helios64-remove-pcie-ep-gpios.patch +++ /dev/null @@ -1,25 +0,0 @@ -From e7e9a3a959927094d59b67f46ecc1c5d50190ce8 Mon Sep 17 00:00:00 2001 -From: Aditya Prayoga -Date: Tue, 15 Sep 2020 13:42:02 +0700 -Subject: [PATCH] Remove PCIE ep-gpios from Helios64 - -Signed-off-by: Aditya Prayoga ---- - arch/arm64/boot/dts/rockchip/rk3399-helios64.dts | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts -index c065ba82d..002c93912 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts -@@ -721,7 +721,6 @@ - }; - - &pcie0 { -- ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>; - num-lanes = <2>; - max-link-speed = <2>; - pinctrl-names = "default"; --- -Created with Armbian build tools https://github.com/armbian/build - diff --git a/patch/kernel/archive/rockchip64-6.1/board-nanopc-t4-add-typec-dp.patch b/patch/kernel/archive/rockchip64-6.1/board-nanopc-t4-add-typec-dp.patch deleted file mode 100644 index 2fea7d1ed1b4..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-nanopc-t4-add-typec-dp.patch +++ /dev/null @@ -1,147 +0,0 @@ -From 5b697589bfd64a14ef1c991cffb5179ccb6cf880 Mon Sep 17 00:00:00 2001 -From: tonymac32 -Date: Wed, 17 Feb 2021 00:54:00 -0500 -Subject: [PATCH] Patching something - -Signed-off-by: tonymac32 ---- - .../boot/dts/rockchip/rk3399-nanopc-t4.dts | 100 +++++++++++++++++++ - 1 file changed, 98 insertions(+), 12 deletions(-) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts b/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts -index e0d75617b..68f1a06fa 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts -@@ -9,6 +9,7 @@ - */ - - /dts-v1/; -+#include - #include "rk3399-nanopi4.dtsi" - - / { -@@ -66,6 +67,12 @@ fan: pwm-fan { - }; - }; - -+&cdn_dp { -+ status = "okay"; -+ extcon = <&fusb0>; -+ phys = <&tcphy0_dp>; -+}; -+ - &cpu_thermal { - trips { - cpu_warm: cpu_warm { -@@ -94,6 +101,50 @@ map3 { - }; - }; - -+&fusb0 { -+ -+ connector { -+ compatible = "usb-c-connector"; -+ label = "USB-C"; -+ power-role = "dual"; -+ data-role = "dual"; -+ try-power-role = "sink"; -+ source-pdos = ; -+ sink-pdos = ; -+ op-sink-microwatt = <5000000>; -+ -+ extcon-cables = <1 2 5 6 9 10 12 44>; -+ typec-altmodes = <0xff01 1 0x001c0000 1>; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ port@0 { -+ reg = <0>; -+ usb_con_hs: endpoint { -+ remote-endpoint = -+ <&u2phy0_typec_hs>; -+ }; -+ }; -+ port@1 { -+ reg = <1>; -+ -+ usb_con_ss: endpoint { -+ remote-endpoint = -+ <&tcphy0_typec_ss>; -+ }; -+ }; -+ port@2 { -+ reg = <2>; -+ usb_con_dp: endpoint { -+ remote-endpoint = -+ <&tcphy0_typec_dp>; -+ }; -+ }; -+ }; -+ }; -+}; -+ - &pcie0 { - num-lanes = <4>; - vpcie3v3-supply = <&vcc3v3_sys>; -@@ -113,12 +164,57 @@ &sdhci { - mmc-hs400-enhanced-strobe; - }; - -+&tcphy0 { -+ extcon = <&fusb0>; -+ status = "okay"; -+}; -+ -+&tcphy0_dp { -+ port { -+ tcphy0_typec_dp: endpoint { -+ remote-endpoint = <&usb_con_dp>; -+ }; -+ }; -+}; -+ -+&tcphy0_usb3 { -+ port { -+ tcphy0_typec_ss: endpoint { -+ remote-endpoint = <&usb_con_ss>; -+ }; -+ }; -+}; -+ -+&u2phy0 { -+ extcon = <&fusb0>; -+}; -+ - &u2phy0_host { - phy-supply = <&vcc5v0_host0>; -+ status = "okay"; -+}; -+ -+&u2phy0_otg { -+ status = "okay"; -+ -+ port { -+ u2phy0_typec_hs: endpoint { -+ remote-endpoint = <&usb_con_hs>; -+ }; -+ }; - }; - - &u2phy1_host { - phy-supply = <&vcc5v0_host0>; -+ status = "okay"; -+}; -+ -+&u2phy1_otg { -+ status = "okay"; -+}; -+ -+&usbdrd_dwc3_0 { -+ extcon = <&fusb0>; - }; - - &vcc5v0_sys { --- -Created with Armbian build tools https://github.com/armbian/build - diff --git a/patch/kernel/archive/rockchip64-6.1/board-nanopi-m4v2-dts-add-sound-card.patch b/patch/kernel/archive/rockchip64-6.1/board-nanopi-m4v2-dts-add-sound-card.patch deleted file mode 100644 index fb22a748ac30..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-nanopi-m4v2-dts-add-sound-card.patch +++ /dev/null @@ -1,106 +0,0 @@ -diff -u a/arch/arm64/boot/dts/rockchip/rk3399-nanopi4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-nanopi4.dtsi ---- a/arch/arm64/boot/dts/rockchip/rk3399-nanopi4.dtsi 2019-10-17 23:47:33.000000000 +0300 -+++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi4.dtsi 2019-10-27 22:34:55.988303874 +0300 -@@ -105,6 +105,27 @@ - }; - }; - -+ rt5651-sound { -+ compatible = "simple-audio-card"; -+ simple-audio-card,name = "realtek,rt5651-codec"; -+ simple-audio-card,format = "i2s"; -+ simple-audio-card,mclk-fs = <256>; -+ simple-audio-card,widgets = -+ "Microphone", "Mic Jack", -+ "Headphone", "Headphone Jack"; -+ simple-audio-card,routing = -+ "Mic Jack", "micbias1", -+ "IN1P", "Mic Jack", -+ "Headphone Jack", "HPOL", -+ "Headphone Jack", "HPOR"; -+ simple-audio-card,cpu { -+ sound-dai = <&i2s1>; -+ }; -+ simple-audio-card,codec { -+ sound-dai = <&rt5651>; -+ }; -+ }; -+ - sdio_pwrseq: sdio-pwrseq { - compatible = "mmc-pwrseq-simple"; - clocks = <&rk808 1>; -@@ -184,6 +205,10 @@ - status = "okay"; - }; - -+&hdmi_sound { -+ status = "okay"; -+}; -+ - &i2c0 { - clock-frequency = <400000>; - i2c-scl-rising-time-ns = <160>; -@@ -432,6 +457,16 @@ - i2c-scl-rising-time-ns = <150>; - i2c-scl-falling-time-ns = <30>; - status = "okay"; -+ -+ rt5651: rt5651@1a { -+ compatible = "realtek,rt5651"; -+ reg = <0x1a>; -+ clocks = <&cru SCLK_I2S_8CH_OUT>; -+ clock-names = "mclk"; -+ hp-det-gpio = <&gpio4 RK_PC4 GPIO_ACTIVE_LOW>; -+ // spk-con-gpio = <&gpio0 RK_PB3 GPIO_ACTIVE_HIGH>; -+ #sound-dai-cells = <0>; -+ }; - }; - - &i2c2 { -@@ -459,6 +494,16 @@ - status = "okay"; - }; - -+&i2s1 { -+ rockchip,playback-channels = <8>; -+ rockchip,capture-channels = <8>; -+ status = "okay"; -+}; -+ -+&i2s2 { -+ status = "okay"; -+}; -+ - &io_domains { - bt656-supply = <&vcc_1v8>; - audio-supply = <&vcca1v8_codec>; -@@ -724,3 +769,9 @@ - &vopl_mmu { - status = "okay"; - }; -+ -+&spdif { -+ i2c-scl-rising-time-ns = <450>; -+ i2c-scl-falling-time-ns = <15>; -+ status = "okay"; -+}; -diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig -index b43657e6e..fb75c425e 100644 ---- a/sound/soc/rockchip/Kconfig -+++ b/sound/soc/rockchip/Kconfig -@@ -53,6 +53,15 @@ config SND_SOC_ROCKCHIP_RT5645 - Say Y or M here if you want to add support for SoC audio on Rockchip - boards using the RT5645/RT5650 codec, such as Veyron. - -+config SND_SOC_ROCKCHIP_RT5651 -+ tristate "ASoC support for Rockchip boards using a RT5651 codec" -+ depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && HAVE_CLK -+ select SND_SOC_ROCKCHIP_I2S -+ select SND_SOC_RT5651 -+ help -+ Say Y or M here if you want to add support for SoC audio on Rockchip -+ boards using the RT5651 codec, such as FriendlyARM's Nano{Pi,PC} family. -+ - config SND_SOC_RK3288_HDMI_ANALOG - tristate "ASoC support multiple codecs for Rockchip RK3288 boards" - depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP diff --git a/patch/kernel/archive/rockchip64-6.1/board-nanopi-m4v2-dts-ethernet-tweak.patch b/patch/kernel/archive/rockchip64-6.1/board-nanopi-m4v2-dts-ethernet-tweak.patch deleted file mode 100644 index bb2cef90f27b..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-nanopi-m4v2-dts-ethernet-tweak.patch +++ /dev/null @@ -1,15 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-m4v2.dts b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-m4v2.dts -index 60358ab8c..057045ca3 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-m4v2.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-m4v2.dts -@@ -48,6 +48,10 @@ - }; - }; - -+&gmac { -+ rx_delay = <0x16>; -+}; -+ - &vcc3v3_sys { - vin-supply = <&vcc5v0_core>; - }; diff --git a/patch/kernel/archive/rockchip64-6.1/board-nanopi-m4v2-dts-fix-stability-issues.patch b/patch/kernel/archive/rockchip64-6.1/board-nanopi-m4v2-dts-fix-stability-issues.patch deleted file mode 100644 index d66655564357..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-nanopi-m4v2-dts-fix-stability-issues.patch +++ /dev/null @@ -1,29 +0,0 @@ -By default rk808's buck regulators switch voltage in multiple 100mV jumps. -This seems to be too much for NanoPi M4V2 and makes it unstable. - -Shortening the steps to 50mV (4 multiple of base buck step which is 12.5mV) -makes the NanoPi M4V2 stable. -Tested with multiple hours of running memtester without a single failure. - -Signed-off-by: Piotr Szczepanik - -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-m4v2.dts b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-m4v2.dts -index 2dcaf497c..094440ce3 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-m4v2.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-m4v2.dts -@@ -64,6 +64,10 @@ &gmac { - rx_delay = <0x16>; - }; - -+&rk808 { -+ max-buck-steps-per-change = <4>; -+}; -+ - &vcc3v3_sys { - vin-supply = <&vcc5v0_core>; - }; -@@ -80,3 +84,4 @@ &vbus_typec { - regulator-always-on; - vin-supply = <&vdd_5v>; - }; -+ diff --git a/patch/kernel/archive/rockchip64-6.1/board-nanopi-r4s-pwmfan.patch b/patch/kernel/archive/rockchip64-6.1/board-nanopi-r4s-pwmfan.patch deleted file mode 100644 index 39c0fac193d1..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-nanopi-r4s-pwmfan.patch +++ /dev/null @@ -1,50 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts -index fe5b52610..a73767594 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts -@@ -60,10 +60,45 @@ vdd_5v: vdd-5v { - compatible = "regulator-fixed"; - regulator-name = "vdd_5v"; - regulator-always-on; - regulator-boot-on; - }; -+ -+ fan: pwm-fan { -+ compatible = "pwm-fan"; -+ cooling-levels = <0 18 102 170 255>; -+ fan-supply = <&vdd_5v>; -+ pwms = <&pwm1 0 50000 0>; -+ }; -+}; -+ -+&cpu_thermal { -+ trips { -+ cpu_warm: cpu_warm { -+ temperature = <55000>; -+ hysteresis = <2000>; -+ type = "active"; -+ }; -+ -+ cpu_hot: cpu_hot { -+ temperature = <65000>; -+ hysteresis = <2000>; -+ type = "active"; -+ }; -+ }; -+ -+ cooling-maps { -+ map2 { -+ trip = <&cpu_warm>; -+ cooling-device = <&fan THERMAL_NO_LIMIT 1>; -+ }; -+ -+ map3 { -+ trip = <&cpu_hot>; -+ cooling-device = <&fan 2 THERMAL_NO_LIMIT>; -+ }; -+ }; - }; - - &emmc_phy { - status = "disabled"; - }; diff --git a/patch/kernel/archive/rockchip64-6.1/board-pbp-add-dp-alt-mode.patch b/patch/kernel/archive/rockchip64-6.1/board-pbp-add-dp-alt-mode.patch deleted file mode 100644 index a16591876024..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-pbp-add-dp-alt-mode.patch +++ /dev/null @@ -1,42 +0,0 @@ -From bf597a6d9be2dbf6b6efcae9863e019d8deda0d2 Mon Sep 17 00:00:00 2001 -From: Paolo Sabatino -Date: Sun, 7 May 2023 11:06:35 +0200 -Subject: [PATCH 2/3] add missing extcon props for usb3-type c - ---- - arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts b/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts -index 194e48c755f6..50a17619712a 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts -@@ -432,6 +432,7 @@ edp_out_panel: endpoint@0 { - - &emmc_phy { - status = "okay"; -+ extcon = <&fusb0>; - }; - - &gpu { -@@ -716,6 +717,9 @@ connector { - ; - try-power-role = "sink"; - -+ extcon-cables = <1 2 5 6 9 10 12 44>; -+ typec-altmodes = <0xff01 1 0x001c0000 1>; -+ - ports { - #address-cells = <1>; - #size-cells = <0>; -@@ -982,6 +986,7 @@ spiflash: flash@0 { - }; - - &tcphy0 { -+ extcon = <&fusb0>; - status = "okay"; - }; - --- -2.34.1 - diff --git a/patch/kernel/archive/rockchip64-6.1/board-rk3328-roc-cc-dts-enable-dmc.patch b/patch/kernel/archive/rockchip64-6.1/board-rk3328-roc-cc-dts-enable-dmc.patch deleted file mode 100644 index fd7f49e49d66..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rk3328-roc-cc-dts-enable-dmc.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 36934c54b2c8f882b8c4700a69f8b91b5bf4811a Mon Sep 17 00:00:00 2001 -From: Paolo Sabatino -Date: Tue, 12 Oct 2021 18:31:28 +0000 -Subject: [PATCH] enable roc-cc dmc - ---- - .../arm64/boot/dts/rockchip/rk3328-roc-cc.dts | 38 +++++++++++++++++++ - 1 file changed, 38 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts -index daa9a0c60..dc6583be5 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts -@@ -4,6 +4,7 @@ - */ - - /dts-v1/; -+#include "rk3328-dram-renegade-timing.dtsi" - #include "rk3328.dtsi" - - / { -@@ -14,6 +15,32 @@ chosen { - stdout-path = "serial2:1500000n8"; - }; - -+ /delete-node/ dmc-opp-table; -+ dmc_opp_table: dmc-opp-table { -+ compatible = "operating-points-v2"; -+ -+ opp-786000000 { -+ opp-hz = /bits/ 64 <786000000>; -+ opp-microvolt = <1075000 1075000 12000000>; -+ }; -+ opp-798000000 { -+ opp-hz = /bits/ 64 <798000000>; -+ opp-microvolt = <1075000 1075000 12000000>; -+ }; -+ opp-840000000 { -+ opp-hz = /bits/ 64 <840000000>; -+ opp-microvolt = <1075000 1075000 12000000>; -+ }; -+ opp-924000000 { -+ opp-hz = /bits/ 64 <924000000>; -+ opp-microvolt = <1100000 1100000 12000000>; -+ }; -+ opp-1068000000 { -+ opp-hz = /bits/ 64 <1068000000>; -+ opp-microvolt = <1175000 1175000 12000000>; -+ }; -+ }; -+ - gmac_clkin: external-gmac-clock { - compatible = "fixed-clock"; - clock-frequency = <125000000>; -@@ -104,6 +131,17 @@ user_led: led-1 { - }; - }; - -+&dfi { -+ status = "okay"; -+}; -+ -+&dmc { -+ center-supply = <&vdd_logic>; -+ ddr_timing = <&ddr_timing>; -+ status = "okay"; -+}; -+ -+ - &cpu0 { - cpu-supply = <&vdd_arm>; - }; --- -2.30.2 - diff --git a/patch/kernel/archive/rockchip64-6.1/board-rk3328-roc-cc-dts-ram-profile.patch b/patch/kernel/archive/rockchip64-6.1/board-rk3328-roc-cc-dts-ram-profile.patch deleted file mode 100644 index 4a86a4eadb0a..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rk3328-roc-cc-dts-ram-profile.patch +++ /dev/null @@ -1,331 +0,0 @@ -From 036c59ebd2265236880bb156e995af55249726b1 Mon Sep 17 00:00:00 2001 -From: tonymac32 -Date: Wed, 7 Oct 2020 23:39:54 -0400 -Subject: [PATCH] board-rk3328-roc-cc-adjust-DMC-opps - -Signed-off-by: tonymac32 ---- - .../rockchip/rk3328-dram-renegade-timing.dtsi | 311 ++++++++++++++++++ - 1 file changed, 311 insertions(+), 0 deletion(-) - create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-dram-renegade-timing.dtsi - -diff --git a/arch/arm64/boot/dts/rockchip/rk3328-dram-renegade-timing.dtsi b/arch/arm64/boot/dts/rockchip/rk3328-dram-renegade-timing.dtsi -new file mode 100644 -index 000000000..303428153 ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3328-dram-renegade-timing.dtsi -@@ -0,0 +1,311 @@ -+/* -+ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd -+ * -+ * This file is dual-licensed: you can use it either under the terms -+ * of the GPL or the X11 license, at your option. Note that this dual -+ * licensing only applies to this file, and not this project as a -+ * whole. -+ * -+ * a) This library 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 library 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. -+ * -+ * Or, alternatively, -+ * -+ * b) Permission is hereby granted, free of charge, to any person -+ * obtaining a copy of this software and associated documentation -+ * files (the "Software"), to deal in the Software without -+ * restriction, including without limitation the rights to use, -+ * copy, modify, merge, publish, distribute, sublicense, and/or -+ * sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following -+ * conditions: -+ * -+ * The above copyright notice and this permission notice shall be -+ * included in all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+#include -+#include -+ -+/ { -+ ddr_timing: ddr_timing { -+ compatible = "rockchip,ddr-timing"; -+ ddr3_speed_bin = ; -+ ddr4_speed_bin = ; -+ pd_idle = <0>; -+ sr_idle = <0>; -+ sr_mc_gate_idle = <0>; -+ srpd_lite_idle = <0>; -+ standby_idle = <0>; -+ -+ auto_pd_dis_freq = <1066>; -+ auto_sr_dis_freq = <800>; -+ ddr3_dll_dis_freq = <300>; -+ ddr4_dll_dis_freq = <625>; -+ phy_dll_dis_freq = <400>; -+ -+ ddr3_odt_dis_freq = <100>; -+ phy_ddr3_odt_dis_freq = <100>; -+ ddr3_drv = ; -+ ddr3_odt = ; -+ phy_ddr3_ca_drv = ; -+ phy_ddr3_ck_drv = ; -+ phy_ddr3_dq_drv = ; -+ phy_ddr3_odt = ; -+ -+ lpddr3_odt_dis_freq = <666>; -+ phy_lpddr3_odt_dis_freq = <666>; -+ lpddr3_drv = ; -+ lpddr3_odt = ; -+ phy_lpddr3_ca_drv = ; -+ phy_lpddr3_ck_drv = ; -+ phy_lpddr3_dq_drv = ; -+ phy_lpddr3_odt = ; -+ -+ lpddr4_odt_dis_freq = <800>; -+ phy_lpddr4_odt_dis_freq = <800>; -+ lpddr4_drv = ; -+ lpddr4_dq_odt = ; -+ lpddr4_ca_odt = ; -+ phy_lpddr4_ca_drv = ; -+ phy_lpddr4_ck_cs_drv = ; -+ phy_lpddr4_dq_drv = ; -+ phy_lpddr4_odt = ; -+ -+ ddr4_odt_dis_freq = <666>; -+ phy_ddr4_odt_dis_freq = <666>; -+ ddr4_drv = ; -+ ddr4_odt = ; -+ phy_ddr4_ca_drv = ; -+ phy_ddr4_ck_drv = ; -+ phy_ddr4_dq_drv = ; -+ phy_ddr4_odt = ; -+ -+ /* CA de-skew, one step is 47.8ps, range 0-15 */ -+ ddr3a1_ddr4a9_de-skew = <0>; -+ ddr3a0_ddr4a10_de-skew = <0>; -+ ddr3a3_ddr4a6_de-skew = <1>; -+ ddr3a2_ddr4a4_de-skew = <1>; -+ ddr3a5_ddr4a8_de-skew = <0>; -+ ddr3a4_ddr4a5_de-skew = <2>; -+ ddr3a7_ddr4a11_de-skew = <0>; -+ ddr3a6_ddr4a7_de-skew = <2>; -+ ddr3a9_ddr4a0_de-skew = <1>; -+ ddr3a8_ddr4a13_de-skew = <0>; -+ ddr3a11_ddr4a3_de-skew = <2>; -+ ddr3a10_ddr4cs0_de-skew = <0>; -+ ddr3a13_ddr4a2_de-skew = <1>; -+ ddr3a12_ddr4ba1_de-skew = <0>; -+ ddr3a15_ddr4odt0_de-skew = <0>; -+ ddr3a14_ddr4a1_de-skew = <1>; -+ ddr3ba1_ddr4a15_de-skew = <0>; -+ ddr3ba0_ddr4bg0_de-skew = <0>; -+ ddr3ras_ddr4cke_de-skew = <0>; -+ ddr3ba2_ddr4ba0_de-skew = <1>; -+ ddr3we_ddr4bg1_de-skew = <1>; -+ ddr3cas_ddr4a12_de-skew = <0>; -+ ddr3ckn_ddr4ckn_de-skew = <5>; -+ ddr3ckp_ddr4ckp_de-skew = <5>; -+ ddr3cke_ddr4a16_de-skew = <1>; -+ ddr3odt0_ddr4a14_de-skew = <0>; -+ ddr3cs0_ddr4act_de-skew = <1>; -+ ddr3reset_ddr4reset_de-skew = <0>; -+ ddr3cs1_ddr4cs1_de-skew = <0>; -+ ddr3odt1_ddr4odt1_de-skew = <0>; -+ -+ /* DATA de-skew -+ * RX one step is 25.1ps, range 0-15 -+ * TX one step is 47.8ps, range 0-15 -+ */ -+ cs0_dm0_rx_de-skew = <7>; -+ cs0_dm0_tx_de-skew = <8>; -+ cs0_dq0_rx_de-skew = <7>; -+ cs0_dq0_tx_de-skew = <8>; -+ cs0_dq1_rx_de-skew = <7>; -+ cs0_dq1_tx_de-skew = <8>; -+ cs0_dq2_rx_de-skew = <7>; -+ cs0_dq2_tx_de-skew = <8>; -+ cs0_dq3_rx_de-skew = <7>; -+ cs0_dq3_tx_de-skew = <8>; -+ cs0_dq4_rx_de-skew = <7>; -+ cs0_dq4_tx_de-skew = <8>; -+ cs0_dq5_rx_de-skew = <7>; -+ cs0_dq5_tx_de-skew = <8>; -+ cs0_dq6_rx_de-skew = <7>; -+ cs0_dq6_tx_de-skew = <8>; -+ cs0_dq7_rx_de-skew = <7>; -+ cs0_dq7_tx_de-skew = <8>; -+ cs0_dqs0_rx_de-skew = <6>; -+ cs0_dqs0p_tx_de-skew = <9>; -+ cs0_dqs0n_tx_de-skew = <9>; -+ -+ cs0_dm1_rx_de-skew = <7>; -+ cs0_dm1_tx_de-skew = <7>; -+ cs0_dq8_rx_de-skew = <7>; -+ cs0_dq8_tx_de-skew = <8>; -+ cs0_dq9_rx_de-skew = <7>; -+ cs0_dq9_tx_de-skew = <7>; -+ cs0_dq10_rx_de-skew = <7>; -+ cs0_dq10_tx_de-skew = <8>; -+ cs0_dq11_rx_de-skew = <7>; -+ cs0_dq11_tx_de-skew = <7>; -+ cs0_dq12_rx_de-skew = <7>; -+ cs0_dq12_tx_de-skew = <8>; -+ cs0_dq13_rx_de-skew = <7>; -+ cs0_dq13_tx_de-skew = <7>; -+ cs0_dq14_rx_de-skew = <7>; -+ cs0_dq14_tx_de-skew = <8>; -+ cs0_dq15_rx_de-skew = <7>; -+ cs0_dq15_tx_de-skew = <7>; -+ cs0_dqs1_rx_de-skew = <7>; -+ cs0_dqs1p_tx_de-skew = <9>; -+ cs0_dqs1n_tx_de-skew = <9>; -+ -+ cs0_dm2_rx_de-skew = <7>; -+ cs0_dm2_tx_de-skew = <8>; -+ cs0_dq16_rx_de-skew = <7>; -+ cs0_dq16_tx_de-skew = <8>; -+ cs0_dq17_rx_de-skew = <7>; -+ cs0_dq17_tx_de-skew = <8>; -+ cs0_dq18_rx_de-skew = <7>; -+ cs0_dq18_tx_de-skew = <8>; -+ cs0_dq19_rx_de-skew = <7>; -+ cs0_dq19_tx_de-skew = <8>; -+ cs0_dq20_rx_de-skew = <7>; -+ cs0_dq20_tx_de-skew = <8>; -+ cs0_dq21_rx_de-skew = <7>; -+ cs0_dq21_tx_de-skew = <8>; -+ cs0_dq22_rx_de-skew = <7>; -+ cs0_dq22_tx_de-skew = <8>; -+ cs0_dq23_rx_de-skew = <7>; -+ cs0_dq23_tx_de-skew = <8>; -+ cs0_dqs2_rx_de-skew = <6>; -+ cs0_dqs2p_tx_de-skew = <9>; -+ cs0_dqs2n_tx_de-skew = <9>; -+ -+ cs0_dm3_rx_de-skew = <7>; -+ cs0_dm3_tx_de-skew = <7>; -+ cs0_dq24_rx_de-skew = <7>; -+ cs0_dq24_tx_de-skew = <8>; -+ cs0_dq25_rx_de-skew = <7>; -+ cs0_dq25_tx_de-skew = <7>; -+ cs0_dq26_rx_de-skew = <7>; -+ cs0_dq26_tx_de-skew = <7>; -+ cs0_dq27_rx_de-skew = <7>; -+ cs0_dq27_tx_de-skew = <7>; -+ cs0_dq28_rx_de-skew = <7>; -+ cs0_dq28_tx_de-skew = <7>; -+ cs0_dq29_rx_de-skew = <7>; -+ cs0_dq29_tx_de-skew = <7>; -+ cs0_dq30_rx_de-skew = <7>; -+ cs0_dq30_tx_de-skew = <7>; -+ cs0_dq31_rx_de-skew = <7>; -+ cs0_dq31_tx_de-skew = <7>; -+ cs0_dqs3_rx_de-skew = <7>; -+ cs0_dqs3p_tx_de-skew = <9>; -+ cs0_dqs3n_tx_de-skew = <9>; -+ -+ cs1_dm0_rx_de-skew = <7>; -+ cs1_dm0_tx_de-skew = <8>; -+ cs1_dq0_rx_de-skew = <7>; -+ cs1_dq0_tx_de-skew = <8>; -+ cs1_dq1_rx_de-skew = <7>; -+ cs1_dq1_tx_de-skew = <8>; -+ cs1_dq2_rx_de-skew = <7>; -+ cs1_dq2_tx_de-skew = <8>; -+ cs1_dq3_rx_de-skew = <7>; -+ cs1_dq3_tx_de-skew = <8>; -+ cs1_dq4_rx_de-skew = <7>; -+ cs1_dq4_tx_de-skew = <8>; -+ cs1_dq5_rx_de-skew = <7>; -+ cs1_dq5_tx_de-skew = <8>; -+ cs1_dq6_rx_de-skew = <7>; -+ cs1_dq6_tx_de-skew = <8>; -+ cs1_dq7_rx_de-skew = <7>; -+ cs1_dq7_tx_de-skew = <8>; -+ cs1_dqs0_rx_de-skew = <6>; -+ cs1_dqs0p_tx_de-skew = <9>; -+ cs1_dqs0n_tx_de-skew = <9>; -+ -+ cs1_dm1_rx_de-skew = <7>; -+ cs1_dm1_tx_de-skew = <7>; -+ cs1_dq8_rx_de-skew = <7>; -+ cs1_dq8_tx_de-skew = <8>; -+ cs1_dq9_rx_de-skew = <7>; -+ cs1_dq9_tx_de-skew = <7>; -+ cs1_dq10_rx_de-skew = <7>; -+ cs1_dq10_tx_de-skew = <8>; -+ cs1_dq11_rx_de-skew = <7>; -+ cs1_dq11_tx_de-skew = <7>; -+ cs1_dq12_rx_de-skew = <7>; -+ cs1_dq12_tx_de-skew = <8>; -+ cs1_dq13_rx_de-skew = <7>; -+ cs1_dq13_tx_de-skew = <7>; -+ cs1_dq14_rx_de-skew = <7>; -+ cs1_dq14_tx_de-skew = <8>; -+ cs1_dq15_rx_de-skew = <7>; -+ cs1_dq15_tx_de-skew = <7>; -+ cs1_dqs1_rx_de-skew = <7>; -+ cs1_dqs1p_tx_de-skew = <9>; -+ cs1_dqs1n_tx_de-skew = <9>; -+ -+ cs1_dm2_rx_de-skew = <7>; -+ cs1_dm2_tx_de-skew = <8>; -+ cs1_dq16_rx_de-skew = <7>; -+ cs1_dq16_tx_de-skew = <8>; -+ cs1_dq17_rx_de-skew = <7>; -+ cs1_dq17_tx_de-skew = <8>; -+ cs1_dq18_rx_de-skew = <7>; -+ cs1_dq18_tx_de-skew = <8>; -+ cs1_dq19_rx_de-skew = <7>; -+ cs1_dq19_tx_de-skew = <8>; -+ cs1_dq20_rx_de-skew = <7>; -+ cs1_dq20_tx_de-skew = <8>; -+ cs1_dq21_rx_de-skew = <7>; -+ cs1_dq21_tx_de-skew = <8>; -+ cs1_dq22_rx_de-skew = <7>; -+ cs1_dq22_tx_de-skew = <8>; -+ cs1_dq23_rx_de-skew = <7>; -+ cs1_dq23_tx_de-skew = <8>; -+ cs1_dqs2_rx_de-skew = <6>; -+ cs1_dqs2p_tx_de-skew = <9>; -+ cs1_dqs2n_tx_de-skew = <9>; -+ -+ cs1_dm3_rx_de-skew = <7>; -+ cs1_dm3_tx_de-skew = <7>; -+ cs1_dq24_rx_de-skew = <7>; -+ cs1_dq24_tx_de-skew = <8>; -+ cs1_dq25_rx_de-skew = <7>; -+ cs1_dq25_tx_de-skew = <7>; -+ cs1_dq26_rx_de-skew = <7>; -+ cs1_dq26_tx_de-skew = <7>; -+ cs1_dq27_rx_de-skew = <7>; -+ cs1_dq27_tx_de-skew = <7>; -+ cs1_dq28_rx_de-skew = <7>; -+ cs1_dq28_tx_de-skew = <7>; -+ cs1_dq29_rx_de-skew = <7>; -+ cs1_dq29_tx_de-skew = <7>; -+ cs1_dq30_rx_de-skew = <7>; -+ cs1_dq30_tx_de-skew = <7>; -+ cs1_dq31_rx_de-skew = <7>; -+ cs1_dq31_tx_de-skew = <7>; -+ cs1_dqs3_rx_de-skew = <7>; -+ cs1_dqs3p_tx_de-skew = <9>; -+ cs1_dqs3n_tx_de-skew = <9>; -+ }; -+}; --- -Created with Armbian build tools https://github.com/armbian/build - diff --git a/patch/kernel/archive/rockchip64-6.1/board-rk3328-roc-pc-dts-ram-profile.patch b/patch/kernel/archive/rockchip64-6.1/board-rk3328-roc-pc-dts-ram-profile.patch deleted file mode 100644 index 58e7f4e8c38d..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rk3328-roc-pc-dts-ram-profile.patch +++ /dev/null @@ -1,229 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-pc-dram-timing.dtsi b/arch/arm64/boot/dts/rockchip/rk3328-roc-pc-dram-timing.dtsi -new file mode 100644 -index 000000000000..0ea270539a23 ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-pc-dram-timing.dtsi -@@ -0,0 +1,223 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd -+ * -+ */ -+#include -+#include -+ -+/ { -+ ddr_timing: ddr_timing { -+ /* CA de-skew, one step is 47.8ps, range 0-15 */ -+ ddr3a1_ddr4a9_de-skew = <0>; -+ ddr3a0_ddr4a10_de-skew = <0>; -+ ddr3a3_ddr4a6_de-skew = <1>; -+ ddr3a2_ddr4a4_de-skew = <1>; -+ ddr3a5_ddr4a8_de-skew = <0>; -+ ddr3a4_ddr4a5_de-skew = <2>; -+ ddr3a7_ddr4a11_de-skew = <0>; -+ ddr3a6_ddr4a7_de-skew = <2>; -+ ddr3a9_ddr4a0_de-skew = <1>; -+ ddr3a8_ddr4a13_de-skew = <0>; -+ ddr3a11_ddr4a3_de-skew = <2>; -+ ddr3a10_ddr4cs0_de-skew = <0>; -+ ddr3a13_ddr4a2_de-skew = <1>; -+ ddr3a12_ddr4ba1_de-skew = <0>; -+ ddr3a15_ddr4odt0_de-skew = <0>; -+ ddr3a14_ddr4a1_de-skew = <1>; -+ ddr3ba1_ddr4a15_de-skew = <0>; -+ ddr3ba0_ddr4bg0_de-skew = <0>; -+ ddr3ras_ddr4cke_de-skew = <0>; -+ ddr3ba2_ddr4ba0_de-skew = <1>; -+ ddr3we_ddr4bg1_de-skew = <1>; -+ ddr3cas_ddr4a12_de-skew = <0>; -+ ddr3ckn_ddr4ckn_de-skew = <5>; -+ ddr3ckp_ddr4ckp_de-skew = <5>; -+ ddr3cke_ddr4a16_de-skew = <1>; -+ ddr3odt0_ddr4a14_de-skew = <0>; -+ ddr3cs0_ddr4act_de-skew = <1>; -+ ddr3reset_ddr4reset_de-skew = <0>; -+ ddr3cs1_ddr4cs1_de-skew = <0>; -+ ddr3odt1_ddr4odt1_de-skew = <0>; -+ -+ /* DATA de-skew -+ * RX one step is 25.1ps, range 0-15 -+ * TX one step is 47.8ps, range 0-15 -+ */ -+ cs0_dm0_rx_de-skew = <7>; -+ cs0_dm0_tx_de-skew = <8>; -+ cs0_dq0_rx_de-skew = <7>; -+ cs0_dq0_tx_de-skew = <8>; -+ cs0_dq1_rx_de-skew = <7>; -+ cs0_dq1_tx_de-skew = <8>; -+ cs0_dq2_rx_de-skew = <7>; -+ cs0_dq2_tx_de-skew = <8>; -+ cs0_dq3_rx_de-skew = <7>; -+ cs0_dq3_tx_de-skew = <8>; -+ cs0_dq4_rx_de-skew = <7>; -+ cs0_dq4_tx_de-skew = <8>; -+ cs0_dq5_rx_de-skew = <7>; -+ cs0_dq5_tx_de-skew = <8>; -+ cs0_dq6_rx_de-skew = <7>; -+ cs0_dq6_tx_de-skew = <8>; -+ cs0_dq7_rx_de-skew = <7>; -+ cs0_dq7_tx_de-skew = <8>; -+ cs0_dqs0_rx_de-skew = <6>; -+ cs0_dqs0p_tx_de-skew = <9>; -+ cs0_dqs0n_tx_de-skew = <9>; -+ -+ cs0_dm1_rx_de-skew = <7>; -+ cs0_dm1_tx_de-skew = <7>; -+ cs0_dq8_rx_de-skew = <7>; -+ cs0_dq8_tx_de-skew = <8>; -+ cs0_dq9_rx_de-skew = <7>; -+ cs0_dq9_tx_de-skew = <7>; -+ cs0_dq10_rx_de-skew = <7>; -+ cs0_dq10_tx_de-skew = <8>; -+ cs0_dq11_rx_de-skew = <7>; -+ cs0_dq11_tx_de-skew = <7>; -+ cs0_dq12_rx_de-skew = <7>; -+ cs0_dq12_tx_de-skew = <8>; -+ cs0_dq13_rx_de-skew = <7>; -+ cs0_dq13_tx_de-skew = <7>; -+ cs0_dq14_rx_de-skew = <7>; -+ cs0_dq14_tx_de-skew = <8>; -+ cs0_dq15_rx_de-skew = <7>; -+ cs0_dq15_tx_de-skew = <7>; -+ cs0_dqs1_rx_de-skew = <7>; -+ cs0_dqs1p_tx_de-skew = <9>; -+ cs0_dqs1n_tx_de-skew = <9>; -+ -+ cs0_dm2_rx_de-skew = <7>; -+ cs0_dm2_tx_de-skew = <8>; -+ cs0_dq16_rx_de-skew = <7>; -+ cs0_dq16_tx_de-skew = <8>; -+ cs0_dq17_rx_de-skew = <7>; -+ cs0_dq17_tx_de-skew = <8>; -+ cs0_dq18_rx_de-skew = <7>; -+ cs0_dq18_tx_de-skew = <8>; -+ cs0_dq19_rx_de-skew = <7>; -+ cs0_dq19_tx_de-skew = <8>; -+ cs0_dq20_rx_de-skew = <7>; -+ cs0_dq20_tx_de-skew = <8>; -+ cs0_dq21_rx_de-skew = <7>; -+ cs0_dq21_tx_de-skew = <8>; -+ cs0_dq22_rx_de-skew = <7>; -+ cs0_dq22_tx_de-skew = <8>; -+ cs0_dq23_rx_de-skew = <7>; -+ cs0_dq23_tx_de-skew = <8>; -+ cs0_dqs2_rx_de-skew = <6>; -+ cs0_dqs2p_tx_de-skew = <9>; -+ cs0_dqs2n_tx_de-skew = <9>; -+ -+ cs0_dm3_rx_de-skew = <7>; -+ cs0_dm3_tx_de-skew = <7>; -+ cs0_dq24_rx_de-skew = <7>; -+ cs0_dq24_tx_de-skew = <8>; -+ cs0_dq25_rx_de-skew = <7>; -+ cs0_dq25_tx_de-skew = <7>; -+ cs0_dq26_rx_de-skew = <7>; -+ cs0_dq26_tx_de-skew = <7>; -+ cs0_dq27_rx_de-skew = <7>; -+ cs0_dq27_tx_de-skew = <7>; -+ cs0_dq28_rx_de-skew = <7>; -+ cs0_dq28_tx_de-skew = <7>; -+ cs0_dq29_rx_de-skew = <7>; -+ cs0_dq29_tx_de-skew = <7>; -+ cs0_dq30_rx_de-skew = <7>; -+ cs0_dq30_tx_de-skew = <7>; -+ cs0_dq31_rx_de-skew = <7>; -+ cs0_dq31_tx_de-skew = <7>; -+ cs0_dqs3_rx_de-skew = <7>; -+ cs0_dqs3p_tx_de-skew = <9>; -+ cs0_dqs3n_tx_de-skew = <9>; -+ -+ cs1_dm0_rx_de-skew = <7>; -+ cs1_dm0_tx_de-skew = <8>; -+ cs1_dq0_rx_de-skew = <7>; -+ cs1_dq0_tx_de-skew = <8>; -+ cs1_dq1_rx_de-skew = <7>; -+ cs1_dq1_tx_de-skew = <8>; -+ cs1_dq2_rx_de-skew = <7>; -+ cs1_dq2_tx_de-skew = <8>; -+ cs1_dq3_rx_de-skew = <7>; -+ cs1_dq3_tx_de-skew = <8>; -+ cs1_dq4_rx_de-skew = <7>; -+ cs1_dq4_tx_de-skew = <8>; -+ cs1_dq5_rx_de-skew = <7>; -+ cs1_dq5_tx_de-skew = <8>; -+ cs1_dq6_rx_de-skew = <7>; -+ cs1_dq6_tx_de-skew = <8>; -+ cs1_dq7_rx_de-skew = <7>; -+ cs1_dq7_tx_de-skew = <8>; -+ cs1_dqs0_rx_de-skew = <6>; -+ cs1_dqs0p_tx_de-skew = <9>; -+ cs1_dqs0n_tx_de-skew = <9>; -+ -+ cs1_dm1_rx_de-skew = <7>; -+ cs1_dm1_tx_de-skew = <7>; -+ cs1_dq8_rx_de-skew = <7>; -+ cs1_dq8_tx_de-skew = <8>; -+ cs1_dq9_rx_de-skew = <7>; -+ cs1_dq9_tx_de-skew = <7>; -+ cs1_dq10_rx_de-skew = <7>; -+ cs1_dq10_tx_de-skew = <8>; -+ cs1_dq11_rx_de-skew = <7>; -+ cs1_dq11_tx_de-skew = <7>; -+ cs1_dq12_rx_de-skew = <7>; -+ cs1_dq12_tx_de-skew = <8>; -+ cs1_dq13_rx_de-skew = <7>; -+ cs1_dq13_tx_de-skew = <7>; -+ cs1_dq14_rx_de-skew = <7>; -+ cs1_dq14_tx_de-skew = <8>; -+ cs1_dq15_rx_de-skew = <7>; -+ cs1_dq15_tx_de-skew = <7>; -+ cs1_dqs1_rx_de-skew = <7>; -+ cs1_dqs1p_tx_de-skew = <9>; -+ cs1_dqs1n_tx_de-skew = <9>; -+ -+ cs1_dm2_rx_de-skew = <7>; -+ cs1_dm2_tx_de-skew = <8>; -+ cs1_dq16_rx_de-skew = <7>; -+ cs1_dq16_tx_de-skew = <8>; -+ cs1_dq17_rx_de-skew = <7>; -+ cs1_dq17_tx_de-skew = <8>; -+ cs1_dq18_rx_de-skew = <7>; -+ cs1_dq18_tx_de-skew = <8>; -+ cs1_dq19_rx_de-skew = <7>; -+ cs1_dq19_tx_de-skew = <8>; -+ cs1_dq20_rx_de-skew = <7>; -+ cs1_dq20_tx_de-skew = <8>; -+ cs1_dq21_rx_de-skew = <7>; -+ cs1_dq21_tx_de-skew = <8>; -+ cs1_dq22_rx_de-skew = <7>; -+ cs1_dq22_tx_de-skew = <8>; -+ cs1_dq23_rx_de-skew = <7>; -+ cs1_dq23_tx_de-skew = <8>; -+ cs1_dqs2_rx_de-skew = <6>; -+ cs1_dqs2p_tx_de-skew = <9>; -+ cs1_dqs2n_tx_de-skew = <9>; -+ -+ cs1_dm3_rx_de-skew = <7>; -+ cs1_dm3_tx_de-skew = <7>; -+ cs1_dq24_rx_de-skew = <7>; -+ cs1_dq24_tx_de-skew = <8>; -+ cs1_dq25_rx_de-skew = <7>; -+ cs1_dq25_tx_de-skew = <7>; -+ cs1_dq26_rx_de-skew = <7>; -+ cs1_dq26_tx_de-skew = <7>; -+ cs1_dq27_rx_de-skew = <7>; -+ cs1_dq27_tx_de-skew = <7>; -+ cs1_dq28_rx_de-skew = <7>; -+ cs1_dq28_tx_de-skew = <7>; -+ cs1_dq29_rx_de-skew = <7>; -+ cs1_dq29_tx_de-skew = <7>; -+ cs1_dq30_rx_de-skew = <7>; -+ cs1_dq30_tx_de-skew = <7>; -+ cs1_dq31_rx_de-skew = <7>; -+ cs1_dq31_tx_de-skew = <7>; -+ cs1_dqs3_rx_de-skew = <7>; -+ cs1_dqs3p_tx_de-skew = <9>; -+ cs1_dqs3n_tx_de-skew = <9>; -+ }; -+}; diff --git a/patch/kernel/archive/rockchip64-6.1/board-rock3a-cec.patch b/patch/kernel/archive/rockchip64-6.1/board-rock3a-cec.patch deleted file mode 100644 index 707fd53b4f98..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rock3a-cec.patch +++ /dev/null @@ -1,63 +0,0 @@ -From: Jonas Karlman -Subject: [PATCH 1/2] arm64: dts: rockchip: assign rate to clk_rtc_32k on - rk356x -Date: Tue, 10 Jan 2023 22:55:50 +0000 (UTC) - -clk_rtc_32k and its child clock clk_hdmi_cec detauls to a rate of 24 MHz -and not to 32 kHz on RK356x. - -Fix this by assigning clk_rtc_32k a rate of 32768, also assign the parent -to clk_rtc32k_frac. - -Signed-off-by: Jonas Karlman ---- - arch/arm64/boot/dts/rockchip/rk356x.dtsi | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi -index 5706c3e24f0a..e319699f5e39 100644 ---- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi -@@ -422,8 +422,9 @@ cru: clock-controller@fdd20000 { - clock-names = "xin24m"; - #clock-cells = <1>; - #reset-cells = <1>; -- assigned-clocks = <&cru PLL_GPLL>, <&pmucru PLL_PPLL>; -- assigned-clock-rates = <1200000000>, <200000000>; -+ assigned-clocks = <&pmucru CLK_RTC_32K>, <&cru PLL_GPLL>, <&pmucru PLL_PPLL>; -+ assigned-clock-rates = <32768>, <1200000000>, <200000000>; -+ assigned-clock-parents = <&pmucru CLK_RTC32K_FRAC>; - rockchip,grf = <&grf>; - }; - - -From: Jonas Karlman -Subject: [PATCH 2/2] arm64: dts: rockchip: fix hdmi cec on rock-3a -Date: Tue, 10 Jan 2023 22:55:58 +0000 (UTC) - -HDMI CEC is configured to select HDMITX_CEC_M0 function of GPIO0_C7 by -default in rk356x.dtsi. On Radxa ROCK 3 Model A it is routed to -HDMITX_CEC_M1 according to board schematic [1]. - -Fix HDMI CEC by overriding pinctrl in hdmi node to select HDMITX_CEC_M1. - -[1] https://dl.radxa.com/rock3/docs/hw/3a/ROCK-3A-V1.3-SCH.pdf - -Signed-off-by: Jonas Karlman ---- - arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts -index a1c5fdf7d68f..c9cded3d2f1b 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts -@@ -279,6 +279,7 @@ &gpu { - &hdmi { - avdd-0v9-supply = <&vdda0v9_image>; - avdd-1v8-supply = <&vcca1v8_image>; -+ pinctrl-0 = <&hdmitx_scl &hdmitx_sda &hdmitxm1_cec>; - status = "okay"; - }; - ---- diff --git a/patch/kernel/archive/rockchip64-6.1/board-rock3a-emmc-sfc.patch b/patch/kernel/archive/rockchip64-6.1/board-rock3a-emmc-sfc.patch deleted file mode 100644 index f2603aa58b31..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rock3a-emmc-sfc.patch +++ /dev/null @@ -1,65 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts -index 0813c0c5abde..c6f97a06c370 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts -@@ -48,6 +48,15 @@ - }; - }; - -+ sdio_pwrseq: sdio-pwrseq { -+ compatible = "mmc-pwrseq-simple"; -+ clocks = <&rk809 1>; -+ clock-names = "ext_clock"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&wifi_enable_h>; -+ reset-gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_LOW>; -+ }; -+ - vcc12v_dcin: vcc12v-dcin { - compatible = "regulator-fixed"; - regulator-name = "vcc12v_dcin"; -@@ -454,6 +463,12 @@ - rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; -+ -+ sdio-pwrseq { -+ wifi_enable_h: wifi-enable-h { -+ rockchip,pins = <3 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; - }; - - &pmu_io_domains { -@@ -498,6 +513,31 @@ - status = "okay"; - }; - -+&sdmmc2 { -+ bus-width = <4>; -+ cap-sd-highspeed; -+ cap-sdio-irq; -+ disable-wp; -+ keep-power-in-suspend; -+ mmc-pwrseq = <&sdio_pwrseq>; -+ non-removable; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc2m0_bus4 &sdmmc2m0_cmd &sdmmc2m0_clk>; -+ sd-uhs-sdr104; -+ status = "okay"; -+}; -+ -+&sfc { -+ status = "okay"; -+ flash@0 { -+ compatible = "jedec,spi-nor"; -+ reg = <0>; -+ spi-max-frequency = <108000000>; -+ spi-rx-bus-width = <2>; -+ spi-tx-bus-width = <2>; -+ }; -+}; -+ - &tsadc { - rockchip,hw-tshut-mode = <1>; - rockchip,hw-tshut-polarity = <0>; diff --git a/patch/kernel/archive/rockchip64-6.1/board-rock3a-gmac1.patch b/patch/kernel/archive/rockchip64-6.1/board-rock3a-gmac1.patch deleted file mode 100644 index 7ba74a0be64f..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rock3a-gmac1.patch +++ /dev/null @@ -1,64 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts -index 0813c0c5abde..b7ca6e390646 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts -@@ -20,6 +20,13 @@ - stdout-path = "serial2:1500000n8"; - }; - -+ gmac1_clkin: external-gmac1-clock { -+ compatible = "fixed-clock"; -+ clock-frequency = <125000000>; -+ clock-output-names = "gmac1_clkin"; -+ #clock-cells = <0>; -+ }; -+ - leds { - compatible = "gpio-leds"; - -@@ -146,18 +153,28 @@ - }; - - &gmac1 { -+ snps,reset-gpio = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>; -+ snps,reset-active-low; -+ /* Reset time is 20ms, 100ms for rtl8211f */ -+ snps,reset-delays-us = <0 20000 100000>; -+ - assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>; -- assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>; -- assigned-clock-rates = <0>, <125000000>; -- clock_in_out = "output"; -+ assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&gmac1_clkin>; -+ clock_in_out = "input"; - phy-handle = <&rgmii_phy1>; -- phy-mode = "rgmii-id"; -+ phy-mode = "rgmii"; -+ - pinctrl-names = "default"; - pinctrl-0 = <&gmac1m1_miim - &gmac1m1_tx_bus2 - &gmac1m1_rx_bus2 - &gmac1m1_rgmii_clk -- &gmac1m1_rgmii_bus>; -+ &gmac1m1_rgmii_bus -+ &gmac1m1_clkinout>; -+ -+ tx_delay = <0x4f>; -+ rx_delay = <0x26>; -+ - status = "okay"; - }; - -@@ -415,11 +432,6 @@ - rgmii_phy1: ethernet-phy@0 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <0x0>; -- pinctrl-names = "default"; -- pinctrl-0 = <ð_phy_rst>; -- reset-assert-us = <20000>; -- reset-deassert-us = <100000>; -- reset-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>; - }; - }; - diff --git a/patch/kernel/archive/rockchip64-6.1/board-rock3a-pcie.patch b/patch/kernel/archive/rockchip64-6.1/board-rock3a-pcie.patch deleted file mode 100644 index 8319a826a2ca..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rock3a-pcie.patch +++ /dev/null @@ -1,62 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts -index 8adf672709e8bf..c1fa917083ba64 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts -@@ -67,6 +67,37 @@ - regulator-boot-on; - }; - -+ pcie30_avdd0v9: pcie30-avdd0v9-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "pcie30_avdd0v9"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ vin-supply = <&vcc3v3_sys>; -+ }; -+ -+ pcie30_avdd1v8: pcie30-avdd1v8-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "pcie30_avdd1v8"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ vin-supply = <&vcc3v3_sys>; -+ }; -+ -+ /* pi6c pcie clock generator */ -+ vcc3v3_pi6c_03: vcc3v3-pi6c-03-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc3v3_pi6c_03"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ - vcc3v3_pcie: vcc3v3-pcie-regulator { - compatible = "regulator-fixed"; - enable-active-high; -@@ -546,6 +577,19 @@ - status = "okay"; - }; - -+&pcie30phy { -+ phy-supply = <&vcc3v3_pi6c_03>; -+ status = "okay"; -+}; -+ -+&pcie3x2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie30x2m1_pins>; -+ reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>; -+ vpcie3v3-supply = <&vcc3v3_pcie>; -+ status = "okay"; -+}; -+ - &pinctrl { - cam { - vcc_cam_en: vcc_cam_en { diff --git a/patch/kernel/archive/rockchip64-6.1/board-rock3a-usb3.patch b/patch/kernel/archive/rockchip64-6.1/board-rock3a-usb3.patch deleted file mode 100644 index fa1083c16c1f..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rock3a-usb3.patch +++ /dev/null @@ -1,61 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts -index 0813c0c5abde..478d077d2929 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts -@@ -75,16 +75,6 @@ - vin-supply = <&vcc12v_dcin>; - }; - -- vcc5v0_usb: vcc5v0-usb { -- compatible = "regulator-fixed"; -- regulator-name = "vcc5v0_usb"; -- regulator-always-on; -- regulator-boot-on; -- regulator-min-microvolt = <5000000>; -- regulator-max-microvolt = <5000000>; -- vin-supply = <&vcc12v_dcin>; -- }; -- - vcc5v0_usb_host: vcc5v0-usb-host { - compatible = "regulator-fixed"; - enable-active-high; -@@ -94,7 +84,8 @@ - regulator-name = "vcc5v0_usb_host"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; -- vin-supply = <&vcc5v0_usb>; -+ regulator-always-on; -+ regulator-boot-on; - }; - - vcc5v0_usb_hub: vcc5v0-usb-hub-regulator { -@@ -105,7 +96,6 @@ - pinctrl-0 = <&vcc5v0_usb_hub_en>; - regulator-name = "vcc5v0_usb_hub"; - regulator-always-on; -- vin-supply = <&vcc5v0_usb>; - }; - - vcc5v0_usb_otg: vcc5v0-usb-otg-regulator { -@@ -117,7 +107,8 @@ - regulator-name = "vcc5v0_usb_otg"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; -- vin-supply = <&vcc5v0_usb>; -+ regulator-always-on; -+ regulator-boot-on; - }; - }; - -diff --git a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts -index 0813c0c5abde..d3a10616f3f5 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts -@@ -518,6 +518,7 @@ - - &usb_host0_xhci { - extcon = <&usb2phy0>; -+ dr_mode = "host"; - status = "okay"; - }; - diff --git a/patch/kernel/archive/rockchip64-6.1/board-rock64-mail-supply.patch b/patch/kernel/archive/rockchip64-6.1/board-rock64-mail-supply.patch deleted file mode 100644 index 70134e5d81a8..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rock64-mail-supply.patch +++ /dev/null @@ -1,47 +0,0 @@ -From d0950717ad74ea4c85ccf7bc205b8545758de1df Mon Sep 17 00:00:00 2001 -From: tonymac32 -Date: Sun, 8 Aug 2021 11:49:27 -0400 -Subject: [PATCH] board_rock64_mali-usb-supply - -Signed-off-by: tonymac32 ---- - arch/arm64/boot/dts/rockchip/rk3328-rock64.dts | 16 +++++----------- - 1 file changed, 5 insertions(+), 11 deletions(-) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts -index b5f5513c6..df51ade34 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts -@@ -43,17 +43,6 @@ vcc_host_5v: vcc-host-5v-regulator { - vin-supply = <&vcc_sys>; - }; - -- vcc_host1_5v: vcc_otg_5v: vcc-host1-5v-regulator { -- compatible = "regulator-fixed"; -- gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; -- pinctrl-names = "default"; -- pinctrl-0 = <&usb20_host_drv>; -- regulator-name = "vcc_host1_5v"; -- regulator-always-on; -- regulator-boot-on; -- vin-supply = <&vcc_sys>; -- }; -- - vcc_sys: vcc-sys { - compatible = "regulator-fixed"; - regulator-name = "vcc_sys"; -@@ -143,6 +132,11 @@ &emmc { - status = "okay"; - }; - -+&gpu { -+ status = "okay"; -+ mali-supply = <&vdd_logic>; -+}; -+ - &gmac2io { - assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; - assigned-clock-parents = <&gmac_clkin>, <&gmac_clkin>; --- -Created with Armbian build tools https://github.com/armbian/build - diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpi3-enable-dmc.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpi3-enable-dmc.patch deleted file mode 100644 index 2fd006e7f321..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpi3-enable-dmc.patch +++ /dev/null @@ -1,22 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts -index 018a3a5075c..9b3453cece8 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts -@@ -15,6 +15,7 @@ - #include - - #include "rk3328.dtsi" -+#include "rk3328-dram-default-timing.dtsi" - - / { - model = "Radxa ROCK Pi E"; -@@ -388,3 +389,9 @@ &usbdrd3 { - &usb_host0_ehci { - status = "okay"; - }; -+ -+&dmc { -+ status = "okay"; -+ center-supply = <&vdd_log>; -+ ddr_timing = <&ddr_timing>; -+}; diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpi4-0003-arm64-dts-pcie.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpi4-0003-arm64-dts-pcie.patch deleted file mode 100644 index 714a941df296..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpi4-0003-arm64-dts-pcie.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 6ddfa2aa5d8f662487d2a0feaa1c551c174b72e8 Mon Sep 17 00:00:00 2001 -From: Paolo Sabatino -Date: Sun, 7 May 2023 11:03:10 +0200 -Subject: [PATCH 1/3] pci-express dts patching for rockpi 4 - ---- - arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi -index 6ec65b460e20..776f8ad05640 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi -@@ -113,6 +113,8 @@ vcc3v3_pcie: vcc3v3-pcie-regulator { - regulator-name = "vcc3v3_pcie"; - regulator-always-on; - regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; - vin-supply = <&vcc5v0_sys>; - }; - -@@ -528,9 +530,11 @@ &pcie0 { - num-lanes = <4>; - pinctrl-0 = <&pcie_clkreqnb_cpm>; - pinctrl-names = "default"; -+ vpcie12v-supply = <&vcc12v_dcin>; - vpcie0v9-supply = <&vcc_0v9>; - vpcie1v8-supply = <&vcc_1v8>; - vpcie3v3-supply = <&vcc3v3_pcie>; -+ bus-scan-delay-ms = <1500>; - status = "okay"; - }; - --- -2.34.1 - diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpi4-Add-DT-link-for-backward-compatibility.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpi4-Add-DT-link-for-backward-compatibility.patch deleted file mode 100644 index d7627c6e9d80..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpi4-Add-DT-link-for-backward-compatibility.patch +++ /dev/null @@ -1,22 +0,0 @@ -From e3ffe88f90644eddd0fa6ee8c9f324d54c3b7c39 Mon Sep 17 00:00:00 2001 -From: Igor Pecovnik -Date: Tue, 4 Aug 2020 19:35:47 +0200 -Subject: [PATCH] Add DT link for backward compatibility - -Signed-off-by: Igor Pecovnik ---- - arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts | 1 + - 2 files changed, 2 insertions(+) - create mode 120000 arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts - -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts -new file mode 120000 -index 000000000..07e8a11b0 ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts -@@ -0,0 +1 @@ -+rk3399-rock-pi-4b.dts -\ No newline at end of file --- -Created with Armbian build tools https://github.com/armbian/build - diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpi4c-add-minidp.patch.WIP b/patch/kernel/archive/rockchip64-6.1/board-rockpi4c-add-minidp.patch.WIP deleted file mode 100644 index 6e403f0fc9fb..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpi4c-add-minidp.patch.WIP +++ /dev/null @@ -1,28 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c.dts -index 4c7ebb1c5d2d..19a648add355 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c.dts -@@ -11,6 +11,22 @@ - / { - model = "Radxa ROCK Pi 4C"; - compatible = "radxa,rockpi4c", "radxa,rockpi4", "rockchip,rk3399"; -+ -+ virtual_pd: virtual-pd { -+ compatible = "linux,extcon-usbc-virtual-pd"; -+ det-gpios = <&gpio4 RK_PD1 GPIO_ACTIVE_LOW>; /* DP_HPD */ -+ vpd-data-role = "display-port"; -+ vpd-super-speed; -+ }; -+}; -+ -+&cdn_dp { -+ extcon = <&virtual_pd>; -+ status = "okay"; -+}; -+ -+&tcphy0 { -+ extcon = <&virtual_pd>; - }; - - &sdio0 { - diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0001-arm64-dts.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpis-0001-arm64-dts.patch deleted file mode 100644 index 92a9d0c2688d..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0001-arm64-dts.patch +++ /dev/null @@ -1,377 +0,0 @@ ---- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts 2022-12-19 16:47:52.770160260 -0800 -+++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts 2022-12-19 17:53:42.503756590 -0800 -@@ -2,6 +2,7 @@ - /* - * Copyright (c) 2019 Akash Gajjar - * Copyright (c) 2019 Jagan Teki -+ * Revised: 2022 Brent Roman - */ - - /dts-v1/; -@@ -11,12 +12,6 @@ - model = "Radxa ROCK Pi S"; - compatible = "radxa,rockpis", "rockchip,rk3308"; - -- aliases { -- ethernet0 = &gmac; -- mmc0 = &emmc; -- mmc1 = &sdmmc; -- }; -- - chosen { - stdout-path = "serial0:1500000n8"; - }; -@@ -27,44 +22,102 @@ - pinctrl-0 = <&green_led_gio>, <&heartbeat_led_gpio>; - - green-led { -- default-state = "on"; -- gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>; - label = "rockpis:green:power"; -+ gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-on"; -+ default-state = "on"; - }; - - blue-led { -- default-state = "on"; -- gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; - label = "rockpis:blue:user"; -+ gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "heartbeat"; -+ default-state = "on"; - }; - }; - -+ codec: acodec-sound { -+ compatible = "simple-audio-card"; -+ simple-audio-card,format = "i2s"; -+ simple-audio-card,name = "rockchip,rk3308-acodec"; -+ simple-audio-card,mclk-fs = <256>; -+ simple-audio-card,codec-hp-det; -+ simple-audio-card,widgets = -+ "Headphone", "Headphones"; -+ simple-audio-card,cpu { -+ sound-dai = <&i2s_8ch_2>; -+ }; -+ simple-audio-card,codec { -+ sound-dai = <&acodec>; -+ }; -+ }; -+ -+ sound { -+ compatible = "simple-audio-card"; -+ simple-audio-card,format = "i2s"; -+ simple-audio-card,mclk-fs = <256>; -+ simple-audio-card,name = "i2s_8ch_0"; -+ -+ simple-audio-card,dai-link@1 { -+ format = "i2s"; -+ cpu { -+ sound-dai = <&i2s_8ch_0>; -+ }; -+ -+ codec { -+ sound-dai = <&pcm5102a>; -+ }; -+ }; -+ }; -+ -+ pcm5102a: pcm5102a { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm5102a"; -+ pcm510x,format = "i2s"; -+ }; -+ - sdio_pwrseq: sdio-pwrseq { - compatible = "mmc-pwrseq-simple"; - pinctrl-0 = <&wifi_enable_h>; - pinctrl-names = "default"; -+ /* -+ * On the module itself this is one of these (depending -+ * on the actual card populated): -+ * - SDIO_RESET_L_WL_REG_ON -+ * - PDN (power down when low) -+ */ - reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; - }; - -- vcc_1v8: vcc-1v8 { -+ vcc5v0_sys: vcc5v0-sys { - compatible = "regulator-fixed"; -- regulator-name = "vcc_1v8"; -+ regulator-name = "vcc5v0_sys"; - regulator-always-on; - regulator-boot-on; -- regulator-min-microvolt = <1800000>; -- regulator-max-microvolt = <1800000>; -- vin-supply = <&vcc_io>; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; - }; - -- vcc_io: vcc-io { -+ vdd_core: vdd-core { -+ compatible = "pwm-regulator"; -+ pwms = <&pwm0 0 5000 1>; -+ regulator-name = "vdd_core"; -+ regulator-min-microvolt = <827000>; -+ regulator-max-microvolt = <1340000>; -+ regulator-init-microvolt = <1015000>; -+ regulator-settling-time-up-us = <250>; -+ regulator-always-on; -+ regulator-boot-on; -+ pwm-supply = <&vcc5v0_sys>; -+ }; -+ -+ vdd_log: vdd-log { - compatible = "regulator-fixed"; -- regulator-name = "vcc_io"; -+ regulator-name = "vdd_log"; - regulator-always-on; - regulator-boot-on; -- regulator-min-microvolt = <3300000>; -- regulator-max-microvolt = <3300000>; -+ regulator-min-microvolt = <1050000>; -+ regulator-max-microvolt = <1050000>; - vin-supply = <&vcc5v0_sys>; - }; - -@@ -78,50 +131,50 @@ - vin-supply = <&vcc5v0_sys>; - }; - -- vcc5v0_otg: vcc5v0-otg { -+ vcc_1v8: vcc-1v8 { - compatible = "regulator-fixed"; -- enable-active-high; -- gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; -- pinctrl-names = "default"; -- pinctrl-0 = <&otg_vbus_drv>; -- regulator-name = "vcc5v0_otg"; -+ regulator-name = "vcc_1v8"; - regulator-always-on; -- vin-supply = <&vcc5v0_sys>; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ vin-supply = <&vcc_io>; - }; - -- vcc5v0_sys: vcc5v0-sys { -+ vcc_io: vcc-io { - compatible = "regulator-fixed"; -- regulator-name = "vcc5v0_sys"; -+ regulator-name = "vcc_io"; - regulator-always-on; - regulator-boot-on; -- regulator-min-microvolt = <5000000>; -- regulator-max-microvolt = <5000000>; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&vcc5v0_sys>; - }; - -- vdd_core: vdd-core { -- compatible = "pwm-regulator"; -- pwms = <&pwm0 0 5000 1>; -- pwm-supply = <&vcc5v0_sys>; -- regulator-name = "vdd_core"; -- regulator-min-microvolt = <827000>; -- regulator-max-microvolt = <1340000>; -- regulator-init-microvolt = <1015000>; -- regulator-settling-time-up-us = <250>; -+ vcc_phy: vcc-phy-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc_phy"; - regulator-always-on; - regulator-boot-on; - }; - -- vdd_log: vdd-log { -+ vcc5v0_otg: vcc5v0-otg { - compatible = "regulator-fixed"; -- regulator-name = "vdd_log"; -+ regulator-name = "vcc5v0_otg"; - regulator-always-on; -- regulator-boot-on; -- regulator-min-microvolt = <1050000>; -- regulator-max-microvolt = <1050000>; -+ gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; -+ enable-active-high; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&otg_vbus_drv>; - vin-supply = <&vcc5v0_sys>; - }; - }; - -+&acodec { -+ status = "okay"; -+ #sound-dai-cells = <0>; -+}; -+ - &cpu0 { - cpu-supply = <&vdd_core>; - }; -@@ -129,23 +182,60 @@ - &emmc { - bus-width = <4>; - cap-mmc-highspeed; -- mmc-hs200-1_8v; - non-removable; -- vmmc-supply = <&vcc_io>; - status = "okay"; - }; - -+&sdmmc { -+ cap-mmc-highspeed; -+ cap-sd-highspeed; -+ disable-wp; -+ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_det &sdmmc_bus4>; -+ card-detect-delay = <800>; -+ status = "okay"; -+}; -+ -+&sdio { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cap-sd-highspeed; -+ cap-sdio-irq; -+ keep-power-in-suspend; -+ mmc-pwrseq = <&sdio_pwrseq>; -+ non-removable; -+ no-mmc; -+ status = "okay"; -+ -+ rtl8723ds: wifi@1 { -+ interrupt-parent = <&gpio0>; -+ interrupts = ; -+ interrupt-names = "host-wake"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&wifi_host_wake>; -+ }; -+}; -+ - &gmac { -+ phy-supply = <&vcc_phy>; - clock_in_out = "output"; -- phy-supply = <&vcc_io>; -+ assigned-clocks = <&cru SCLK_MAC>; -+ assigned-clock-parents = <&cru SCLK_MAC_SRC>; - snps,reset-gpio = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; - snps,reset-active-low; - snps,reset-delays-us = <0 50000 50000>; - status = "okay"; - }; - --&i2c1 { -+&i2s_8ch_0 { -+ assigned-clocks = <&cru SCLK_I2S0_8CH_RX>; -+ assigned-clock-parents = <&cru SCLK_I2S0_8CH_TX_MUX>; -+ rockchip,clk-trcm = <1>; -+ #sound-dai-cells = <0>; -+}; -+ -+&i2s_8ch_2 { - status = "okay"; -+ #sound-dai-cells = <0>; - }; - - &pinctrl { -@@ -172,7 +262,9 @@ - wifi_enable_h: wifi-enable-h { - rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; - }; -+ }; - -+ wifi { - wifi_host_wake: wifi-host-wake { - rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_down>; - }; -@@ -189,42 +281,29 @@ - status = "okay"; - }; - --&sdio { -- #address-cells = <1>; -- #size-cells = <0>; -- cap-sd-highspeed; -- cap-sdio-irq; -- keep-power-in-suspend; -- max-frequency = <1000000>; -- mmc-pwrseq = <&sdio_pwrseq>; -- non-removable; -- sd-uhs-sdr104; -+&tsadc { -+ rockchip,hw-tshut-mode = <0>; /* 0:CRU */ -+ rockchip,hw-tshut-polarity = <1>; /* 1:HIGH */ - status = "okay"; - }; - --&sdmmc { -- cap-sd-highspeed; -+&i2c1 { - status = "okay"; - }; - --&u2phy { -- status = "okay"; -- -- u2phy_host: host-port { -- phy-supply = <&vcc5v0_otg>; -- status = "okay"; -- }; -- -- u2phy_otg: otg-port { -- phy-supply = <&vcc5v0_otg>; -- status = "okay"; -- }; -+&spi2 { -+// status = "okay"; //conflicts with UART2 -+ max-freq = <10000000>; - }; - - &uart0 { - status = "okay"; - }; - -+&uart2 { -+ status = "okay"; -+}; -+ - &uart4 { - status = "okay"; - -@@ -235,19 +314,27 @@ - }; - }; - --&usb_host_ehci { -+&u2phy { - status = "okay"; -+ -+ u2phy_host: host-port { -+ phy-supply = <&vcc5v0_otg>; -+ status = "okay"; -+ }; -+ -+ u2phy_otg: otg-port { -+ status = "okay"; -+ }; - }; - --&usb_host_ohci { -+&usb20_otg { - status = "okay"; - }; - --&usb20_otg { -- dr_mode = "peripheral"; -+&usb_host_ehci { - status = "okay"; - }; - --&wdt { -+&usb_host_ohci{ - status = "okay"; - }; diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0005-arm64-dts-rk3308-Add-gmac-node-at-dtsi-level.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpis-0005-arm64-dts-rk3308-Add-gmac-node-at-dtsi-level.patch deleted file mode 100644 index 4f2022f6e50a..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0005-arm64-dts-rk3308-Add-gmac-node-at-dtsi-level.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 359945b9f0c743846405b49513cc72606f5e781c Mon Sep 17 00:00:00 2001 -From: ashthespy -Date: Thu, 16 Jan 2020 21:13:09 +0100 -Subject: [PATCH 05/23] arm64: dts: rk3308: Add mac node at dtsi level - ---- - arch/arm64/boot/dts/rockchip/rk3308.dtsi | 23 +++++++++++++++++++++++ - 1 file changed, 23 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3308.dtsi b/arch/arm64/boot/dts/rockchip/rk3308.dtsi -index 8bdc66c62975..26af951be980 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3308.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3308.dtsi -@@ -24,6 +24,7 @@ aliases { - i2c1 = &i2c1; - i2c2 = &i2c2; - i2c3 = &i2c3; -+ ethernet0 = &gmac; - serial0 = &uart0; - serial1 = &uart1; - serial2 = &uart2; --- -2.25.1 diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0007-arm64-dts-rockchip-add-cpu-s-thermal-config-for-rk33.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpis-0007-arm64-dts-rockchip-add-cpu-s-thermal-config-for-rk33.patch deleted file mode 100644 index d7d695817341..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0007-arm64-dts-rockchip-add-cpu-s-thermal-config-for-rk33.patch +++ /dev/null @@ -1,87 +0,0 @@ -From f7c671915084c850d4a068ebc2c91068de0d3ff2 Mon Sep 17 00:00:00 2001 -From: ashthespy -Date: Fri, 17 Jan 2020 15:57:53 +0100 -Subject: [PATCH 07/23] arm64: dts: rockchip: add cpu's thermal config for - rk3308 - ---- - arch/arm64/boot/dts/rockchip/rk3308.dtsi | 64 ++++++++++++++++++++++++ - 1 file changed, 64 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3308.dtsi b/arch/arm64/boot/dts/rockchip/rk3308.dtsi -index 26af951be980..d2613ec774c1 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3308.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3308.dtsi -@@ -517,6 +517,70 @@ - status = "disabled"; - }; - -+ thermal_zones: thermal-zones { -+ -+ soc_thermal: soc-thermal { -+ polling-delay-passive = <20>; -+ polling-delay = <1000>; -+ sustainable-power = <300>; -+ -+ thermal-sensors = <&tsadc 1>; -+ -+ trips { -+ threshold: trip-point-0 { -+ temperature = <70000>; -+ hysteresis = <2000>; -+ type = "passive"; -+ }; -+ target: trip-point-1 { -+ temperature = <85000>; -+ hysteresis = <2000>; -+ type = "passive"; -+ }; -+ soc_crit: soc-crit { -+ temperature = <115000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ }; -+ -+ cooling-maps { -+ map0 { -+ trip = <&target>; -+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; -+ contribution = <4096>; -+ }; -+ }; -+ -+ }; -+ -+ logic_thermal: logic-thermal { -+ polling-delay-passive = <100>; /* milliseconds */ -+ polling-delay = <1000>; /* milliseconds */ -+ -+ thermal-sensors = <&tsadc 0>; -+ }; -+ }; -+ -+ tsadc: tsadc@ff1f0000 { -+ compatible = "rockchip,rk3308-tsadc"; -+ reg = <0x0 0xff1f0000 0x0 0x100>; -+ interrupts = ; -+ rockchip,grf = <&grf>; -+ clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>; -+ clock-names = "tsadc", "apb_pclk"; -+ assigned-clocks = <&cru SCLK_TSADC>; -+ assigned-clock-rates = <50000>; -+ resets = <&cru SRST_TSADC>; -+ reset-names = "tsadc-apb"; -+ pinctrl-names = "gpio", "otpout"; -+ pinctrl-0 = <&tsadc_otp_pin>; -+ pinctrl-1 = <&tsadc_otp_out>; -+ #thermal-sensor-cells = <1>; -+ rockchip,hw-tshut-temp = <120000>; -+ status = "disabled"; -+ }; -+ - dmac0: dma-controller@ff2c0000 { - compatible = "arm,pl330", "arm,primecell"; - reg = <0x0 0xff2c0000 0x0 0x4000>; --- -2.25.1 diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0008-thermal-rockchip-add-tsadc-support-for-rk3308.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpis-0008-thermal-rockchip-add-tsadc-support-for-rk3308.patch deleted file mode 100644 index 79cbf86849ef..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0008-thermal-rockchip-add-tsadc-support-for-rk3308.patch +++ /dev/null @@ -1,72 +0,0 @@ -From a231e9c68e5f5e6cf5a82a40828cfd1df4ad1f3e Mon Sep 17 00:00:00 2001 -From: Rocky Hao -Date: Fri, 9 Mar 2018 17:36:39 +0800 -Subject: [PATCH] thermal: rockchip: add tsadc support for rk3308 - -Change-Id: Ibf1782ca471c8ad4b14d6fd64eeb123181903adc -Signed-off-by: Rocky Hao ---- - .../bindings/thermal/rockchip-thermal.yaml | 1 + - drivers/thermal/rockchip_thermal.c | 28 +++++++++++++++++++ - 2 files changed, 29 insertions(+) - -diff --git a/Documentation/devicetree/bindings/thermal/rockchip-thermal.yaml b/Documentation/devicetree/bindings/thermal/rockchip-thermal.yaml -index c6aac9bcacf1..3a0a9556680e 100644 ---- a/Documentation/devicetree/bindings/thermal/rockchip-thermal.yaml -+++ b/Documentation/devicetree/bindings/thermal/rockchip-thermal.yaml -@@ -15,6 +15,7 @@ - - rockchip,px30-tsadc - - rockchip,rk3228-tsadc - - rockchip,rk3288-tsadc -+ - rockchip,rk3308-tsadc - - rockchip,rk3328-tsadc - - rockchip,rk3368-tsadc - - rockchip,rk3399-tsadc -diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c -index 343c2f5c5a25..d4d66724535a 100644 ---- a/drivers/thermal/rockchip_thermal.c -+++ b/drivers/thermal/rockchip_thermal.c -@@ -821,6 +821,30 @@ static void rk_tsadcv2_tshut_mode(int chn, void __iomem *regs, - writel_relaxed(val, regs + TSADCV2_INT_EN); - } - -+static const struct rockchip_tsadc_chip rk3308_tsadc_data = { -+ .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */ -+ .chn_id[SENSOR_GPU] = 1, /* gpu sensor is channel 1 */ -+ .chn_num = 2, /* 2 channels for tsadc */ -+ -+ .tshut_mode = TSHUT_MODE_CRU, /* default TSHUT via CRU */ -+ .tshut_temp = 95000, -+ -+ .initialize = rk_tsadcv4_initialize, -+ .irq_ack = rk_tsadcv3_irq_ack, -+ .control = rk_tsadcv3_control, -+ .get_temp = rk_tsadcv2_get_temp, -+ .set_alarm_temp = rk_tsadcv2_alarm_temp, -+ .set_tshut_temp = rk_tsadcv2_tshut_temp, -+ .set_tshut_mode = rk_tsadcv2_tshut_mode, -+ -+ .table = { -+ .id = rk3328_code_table, -+ .length = ARRAY_SIZE(rk3328_code_table), -+ .data_mask = TSADCV2_DATA_MASK, -+ .mode = ADC_INCREMENT, -+ }, -+}; -+ - static const struct rockchip_tsadc_chip px30_tsadc_data = { - .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */ - .chn_id[SENSOR_GPU] = 1, /* gpu sensor is channel 1 */ -@@ -1032,6 +1056,10 @@ static const struct of_device_id of_rockchip_thermal_match[] = { - .compatible = "rockchip,rk3288-tsadc", - .data = (void *)&rk3288_tsadc_data, - }, -+ { -+ .compatible = "rockchip,rk3308-tsadc", -+ .data = (void *)&rk3308_tsadc_data, -+ }, - { - .compatible = "rockchip,rk3328-tsadc", - .data = (void *)&rk3328_tsadc_data, --- -2.25.1 diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0010-arm64-dts-rockchip-add-i2s_8ch-for-rk3308.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpis-0010-arm64-dts-rockchip-add-i2s_8ch-for-rk3308.patch deleted file mode 100644 index ccee6bbfdbc8..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0010-arm64-dts-rockchip-add-i2s_8ch-for-rk3308.patch +++ /dev/null @@ -1,126 +0,0 @@ -From 3169742f1483d5340bedff8b2f35a210bad5f3ca Mon Sep 17 00:00:00 2001 -From: ashthespy -Date: Fri, 17 Jan 2020 16:22:13 +0100 -Subject: [PATCH 10/23] arm64: dts: rockchip: add i2s_8ch for rk3308 - ---- - arch/arm64/boot/dts/rockchip/rk3308.dtsi | 105 ++++++++++++++++++++++- - 1 file changed, 104 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3308.dtsi b/arch/arm64/boot/dts/rockchip/rk3308.dtsi -index d2613ec774c1..37ffedb99a2d 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3308.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3308.dtsi -@@ -605,6 +605,109 @@ dmac1: dma-controller@ff2d0000 { - }; - }; - -+ i2s_8ch_0: i2s@ff300000 { -+ compatible = "rockchip,rk3308-i2s-tdm"; -+ reg = <0x0 0xff300000 0x0 0x1000>; -+ interrupts = ; -+ clocks = <&cru SCLK_I2S0_8CH_TX>, <&cru SCLK_I2S0_8CH_RX>, <&cru HCLK_I2S0_8CH>, -+ <&cru SCLK_I2S0_8CH_TX_SRC>, -+ <&cru SCLK_I2S0_8CH_RX_SRC>, -+ <&cru PLL_VPLL0>, -+ <&cru PLL_VPLL1>; -+ clock-names = "mclk_tx", "mclk_rx", "hclk", -+ "mclk_tx_src", "mclk_rx_src", -+ "mclk_root0", "mclk_root1"; -+ dmas = <&dmac1 0>, <&dmac1 1>; -+ dma-names = "tx", "rx"; -+ resets = <&cru SRST_I2S0_8CH_TX_M>, <&cru SRST_I2S0_8CH_RX_M>; -+ reset-names = "tx-m", "rx-m"; -+ rockchip,cru = <&cru>; -+ rockchip,grf = <&grf>; -+ rockchip,mclk-calibrate; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s_8ch_0_sclktx -+ &i2s_8ch_0_sclkrx -+ &i2s_8ch_0_lrcktx -+ &i2s_8ch_0_lrckrx -+ &i2s_8ch_0_sdi0 -+ &i2s_8ch_0_sdi1 -+ &i2s_8ch_0_sdi2 -+ &i2s_8ch_0_sdi3 -+ &i2s_8ch_0_sdo0 -+ &i2s_8ch_0_sdo1 -+ &i2s_8ch_0_sdo2 -+ &i2s_8ch_0_sdo3 -+ &i2s_8ch_0_mclk>; -+ status = "disabled"; -+ }; -+ -+ i2s_8ch_1: i2s@ff310000 { -+ compatible = "rockchip,rk3308-i2s-tdm"; -+ reg = <0x0 0xff310000 0x0 0x1000>; -+ interrupts = ; -+ clocks = <&cru SCLK_I2S1_8CH_TX>, <&cru SCLK_I2S1_8CH_RX>, <&cru HCLK_I2S1_8CH>, -+ <&cru SCLK_I2S1_8CH_TX_SRC>, -+ <&cru SCLK_I2S1_8CH_RX_SRC>, -+ <&cru PLL_VPLL0>, -+ <&cru PLL_VPLL1>; -+ clock-names = "mclk_tx", "mclk_rx", "hclk", -+ "mclk_tx_src", "mclk_rx_src", -+ "mclk_root0", "mclk_root1"; -+ dmas = <&dmac1 2>, <&dmac1 3>; -+ dma-names = "tx", "rx"; -+ resets = <&cru SRST_I2S1_8CH_TX_M>, <&cru SRST_I2S1_8CH_RX_M>; -+ reset-names = "tx-m", "rx-m"; -+ rockchip,cru = <&cru>; -+ rockchip,grf = <&grf>; -+ rockchip,mclk-calibrate; -+ rockchip,io-multiplex; -+ status = "disabled"; -+ }; -+ -+ i2s_8ch_2: i2s@ff320000 { -+ compatible = "rockchip,rk3308-i2s-tdm"; -+ reg = <0x0 0xff320000 0x0 0x1000>; -+ interrupts = ; -+ clocks = <&cru SCLK_I2S2_8CH_TX>, <&cru SCLK_I2S2_8CH_RX>, <&cru HCLK_I2S2_8CH>, -+ <&cru SCLK_I2S2_8CH_TX_SRC>, -+ <&cru SCLK_I2S2_8CH_RX_SRC>, -+ <&cru PLL_VPLL0>, -+ <&cru PLL_VPLL1>; -+ clock-names = "mclk_tx", "mclk_rx", "hclk", -+ "mclk_tx_src", "mclk_rx_src", -+ "mclk_root0", "mclk_root1"; -+ dmas = <&dmac1 4>, <&dmac1 5>; -+ dma-names = "tx", "rx"; -+ resets = <&cru SRST_I2S2_8CH_TX_M>, <&cru SRST_I2S2_8CH_RX_M>; -+ reset-names = "tx-m", "rx-m"; -+ rockchip,cru = <&cru>; -+ rockchip,grf = <&grf>; -+ rockchip,mclk-calibrate; -+ status = "disabled"; -+ }; -+ -+ i2s_8ch_3: i2s@ff330000 { -+ compatible = "rockchip,rk3308-i2s-tdm"; -+ reg = <0x0 0xff330000 0x0 0x1000>; -+ interrupts = ; -+ clocks = <&cru SCLK_I2S3_8CH_TX>, <&cru SCLK_I2S3_8CH_RX>, <&cru HCLK_I2S3_8CH>, -+ <&cru SCLK_I2S3_8CH_TX_SRC>, -+ <&cru SCLK_I2S3_8CH_RX_SRC>, -+ <&cru PLL_VPLL0>, -+ <&cru PLL_VPLL1>; -+ clock-names = "mclk_tx", "mclk_rx", "hclk", -+ "mclk_tx_src", "mclk_rx_src", -+ "mclk_root0", "mclk_root1"; -+ dmas = <&dmac1 7>; -+ dma-names = "rx"; -+ resets = <&cru SRST_I2S3_8CH_TX_M>, <&cru SRST_I2S3_8CH_RX_M>; -+ reset-names = "tx-m", "rx-m"; -+ rockchip,cru = <&cru>; -+ rockchip,grf = <&grf>; -+ rockchip,mclk-calibrate; -+ status = "disabled"; -+ }; -+ - i2s_2ch_0: i2s@ff350000 { - compatible = "rockchip,rk3308-i2s", "rockchip,rk3066-i2s"; - reg = <0x0 0xff350000 0x0 0x1000>; --- -2.25.1 - diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0012-arm64-dts-rk3308-Add-rk-timer-rtc.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpis-0012-arm64-dts-rk3308-Add-rk-timer-rtc.patch deleted file mode 100644 index 48bd9bc2677c..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0012-arm64-dts-rk3308-Add-rk-timer-rtc.patch +++ /dev/null @@ -1,41 +0,0 @@ -From e329bfefd00a9210b45278acf42fc639c3c54c24 Mon Sep 17 00:00:00 2001 -From: ashthespy -Date: Fri, 17 Jan 2020 17:12:51 +0100 -Subject: [PATCH 12/23] arm64: dts: rk3308: Add rk-timer-rtc - ---- - arch/arm64/boot/dts/rockchip/rk3308.dtsi | 11 ++++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3308.dtsi b/arch/arm64/boot/dts/rockchip/rk3308.dtsi -index 37ffedb99a2d..c711c248ce29 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3308.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3308.dtsi -@@ -502,6 +502,15 @@ rktimer: rktimer@ff1a0000 { - clock-names = "pclk", "timer"; - }; - -+ rk_timer_rtc: rk-timer-rtc@ff1a0020 { -+ compatible = "rockchip,rk3308-timer-rtc"; -+ reg = <0x0 0xff1a0020 0x0 0x20>; -+ interrupts = ; -+ clocks = <&cru PCLK_TIMER>, <&cru SCLK_TIMER1>; -+ clock-names = "pclk", "timer"; -+ status = "disabled"; -+ }; -+ - saradc: saradc@ff1e0000 { - compatible = "rockchip,rk3308-saradc", "rockchip,rk3399-saradc"; - reg = <0x0 0xff1e0000 0x0 0x100>; -@@ -707,7 +716,7 @@ i2s_8ch_3: i2s@ff330000 { - rockchip,mclk-calibrate; - status = "disabled"; - }; -- -+ - i2s_2ch_0: i2s@ff350000 { - compatible = "rockchip,rk3308-i2s", "rockchip,rk3066-i2s"; - reg = <0x0 0xff350000 0x0 0x1000>; --- -2.25.1 - diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0018-ASoC-codecs-Add-RK3308-internal-codec-driver.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpis-0018-ASoC-codecs-Add-RK3308-internal-codec-driver.patch deleted file mode 100644 index 48e190ad7b40..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0018-ASoC-codecs-Add-RK3308-internal-codec-driver.patch +++ /dev/null @@ -1,2640 +0,0 @@ -From b9d097610177b7117a09ea74ed00476a2105f169 Mon Sep 17 00:00:00 2001 -From: Xing Zheng -Date: Sun, 11 Mar 2018 11:37:28 +0800 -Subject: [PATCH] ASoC: codecs: Add RK3308 internal codec driver - -This adds support for the RK3308 audio codec. - -Change-Id: Ieccdebaa27f4a46f6de9406046a6e02e20398013 -Signed-off-by: Xing Zheng ---- - sound/soc/codecs/Kconfig | 5 + - sound/soc/codecs/Makefile | 2 + - sound/soc/codecs/rk3308_codec.c | 1604 +++++++++++++++++++++++++++++++ - sound/soc/codecs/rk3308_codec.h | 960 ++++++++++++++++++ - 4 files changed, 2571 insertions(+) - create mode 100644 sound/soc/codecs/rk3308_codec.c - create mode 100644 sound/soc/codecs/rk3308_codec.h - -diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig -index 030f500f3bc8..1f4675a59014 100644 ---- a/sound/soc/codecs/Kconfig -+++ b/sound/soc/codecs/Kconfig -@@ -144,6 +144,7 @@ config SND_SOC_ALL_CODECS - imply SND_SOC_PCM5102A - imply SND_SOC_PCM512x_I2C - imply SND_SOC_PCM512x_SPI -+ imply SND_SOC_RK3308 - imply SND_SOC_RK3328 - imply SND_SOC_RT274 - imply SND_SOC_RT286 -@@ -931,6 +932,10 @@ config SND_SOC_PCM512x_SPI - select SND_SOC_PCM512x - select REGMAP_SPI - -+config SND_SOC_RK3308 -+ select REGMAP_MMIO -+ tristate "Rockchip RK3308 CODEC" -+ - config SND_SOC_RK3328 - tristate "Rockchip RK3328 audio CODEC" - select REGMAP_MMIO -diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile -index ddfd07071925..9a35df4862dc 100644 ---- a/sound/soc/codecs/Makefile -+++ b/sound/soc/codecs/Makefile -@@ -148,6 +148,7 @@ snd-soc-pcm5102a-objs := pcm5102a.o - snd-soc-pcm512x-objs := pcm512x.o - snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o - snd-soc-pcm512x-spi-objs := pcm512x-spi.o -+snd-soc-rk3308-objs := rk3308_codec.o - snd-soc-rk3328-objs := rk3328_codec.o - snd-soc-rl6231-objs := rl6231.o - snd-soc-rl6347a-objs := rl6347a.o -@@ -437,6 +438,7 @@ obj-$(CONFIG_SND_SOC_PCM5102A) += snd-soc-pcm5102a.o - obj-$(CONFIG_SND_SOC_PCM512x) += snd-soc-pcm512x.o - obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o - obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o -+obj-$(CONFIG_SND_SOC_RK3308) += snd-soc-rk3308.o - obj-$(CONFIG_SND_SOC_RK3328) += snd-soc-rk3328.o - obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o - obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o -diff --git a/sound/soc/codecs/rk3308_codec.c b/sound/soc/codecs/rk3308_codec.c -new file mode 100644 -index 000000000000..106f09738dd0 ---- /dev/null -+++ b/sound/soc/codecs/rk3308_codec.c -@@ -0,0 +1,1604 @@ -+/* -+ * rk3308_codec.c -- RK3308 ALSA Soc Audio Driver -+ * -+ * Copyright (c) 2018, Fuzhou Rockchip Electronics Co., Ltd All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope 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, see . -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "rk3308_codec.h" -+ -+struct rk3308_codec_priv { -+ const struct device *plat_dev; -+ struct device dev; -+ struct reset_control *reset; -+ struct regmap *regmap; -+ struct clk *pclk; -+ struct gpio_desc *spk_ctl_gpio; -+ int adc_ch; /* To select ADCs for channel */ -+ int adc_ch0_using_linein; -+}; -+ -+static const DECLARE_TLV_DB_SCALE(rk3308_codec_alc_agc_ch_gain_tlv, -+ -1800, 150, 2850); -+static const DECLARE_TLV_DB_SCALE(rk3308_codec_alc_agc_ch_max_gain_tlv, -+ -1350, 600, 2850); -+static const DECLARE_TLV_DB_SCALE(rk3308_codec_alc_agc_ch_min_gain_tlv, -+ -1800, 600, 2400); -+static const DECLARE_TLV_DB_SCALE(rk3308_codec_adc_mic_gain_tlv, -+ 0, 600, 3000); -+static const DECLARE_TLV_DB_SCALE(rk3308_codec_adc_alc_gain_tlv, -+ -1800, 150, 2850); -+static const DECLARE_TLV_DB_SCALE(rk3308_codec_dac_gain_tlv, -+ 0, 150, 600); -+static const DECLARE_TLV_DB_SCALE(rk3308_codec_dac_hpout_gain_tlv, -+ -3900, 150, 600); -+static const DECLARE_TLV_DB_SCALE(rk3308_codec_dac_hpmix_gain_tlv, -+ -600, 600, 0); -+ -+static const struct snd_kcontrol_new rk3308_codec_dapm_controls[] = { -+ /* ALC AGC Channel*/ -+ SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 0 Volume", -+ RK3308_ALC_L_DIG_CON03(0), -+ RK3308_ALC_R_DIG_CON03(0), -+ RK3308_AGC_PGA_GAIN_SFT, -+ RK3308_AGC_PGA_GAIN_NDB_18, -+ RK3308_AGC_PGA_GAIN_PDB_28_5, -+ 0, rk3308_codec_alc_agc_ch_gain_tlv), -+ SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 1 Volume", -+ RK3308_ALC_L_DIG_CON03(1), -+ RK3308_ALC_R_DIG_CON03(1), -+ RK3308_AGC_PGA_GAIN_SFT, -+ RK3308_AGC_PGA_GAIN_NDB_18, -+ RK3308_AGC_PGA_GAIN_PDB_28_5, -+ 0, rk3308_codec_alc_agc_ch_gain_tlv), -+ SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 2 Volume", -+ RK3308_ALC_L_DIG_CON03(2), -+ RK3308_ALC_R_DIG_CON03(2), -+ RK3308_AGC_PGA_GAIN_SFT, -+ RK3308_AGC_PGA_GAIN_NDB_18, -+ RK3308_AGC_PGA_GAIN_PDB_28_5, -+ 0, rk3308_codec_alc_agc_ch_gain_tlv), -+ SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 3 Volume", -+ RK3308_ALC_L_DIG_CON03(3), -+ RK3308_ALC_R_DIG_CON03(3), -+ RK3308_AGC_PGA_GAIN_SFT, -+ RK3308_AGC_PGA_GAIN_NDB_18, -+ RK3308_AGC_PGA_GAIN_PDB_28_5, -+ 0, rk3308_codec_alc_agc_ch_gain_tlv), -+ -+ /* ALC AGC MAX */ -+ SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 0 Max Volume", -+ RK3308_ALC_L_DIG_CON09(0), -+ RK3308_ALC_R_DIG_CON09(0), -+ RK3308_AGC_MAX_GAIN_PGA_SFT, -+ RK3308_AGC_MAX_GAIN_PGA_NDB_13_5, -+ RK3308_AGC_MAX_GAIN_PGA_PDB_28_5, -+ 0, rk3308_codec_alc_agc_ch_max_gain_tlv), -+ SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 1 Max Volume", -+ RK3308_ALC_L_DIG_CON09(1), -+ RK3308_ALC_R_DIG_CON09(1), -+ RK3308_AGC_MAX_GAIN_PGA_SFT, -+ RK3308_AGC_MAX_GAIN_PGA_NDB_13_5, -+ RK3308_AGC_MAX_GAIN_PGA_PDB_28_5, -+ 0, rk3308_codec_alc_agc_ch_max_gain_tlv), -+ SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 2 Max Volume", -+ RK3308_ALC_L_DIG_CON09(2), -+ RK3308_ALC_R_DIG_CON09(2), -+ RK3308_AGC_MAX_GAIN_PGA_SFT, -+ RK3308_AGC_MAX_GAIN_PGA_NDB_13_5, -+ RK3308_AGC_MAX_GAIN_PGA_PDB_28_5, -+ 0, rk3308_codec_alc_agc_ch_max_gain_tlv), -+ SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 3 Max Volume", -+ RK3308_ALC_L_DIG_CON09(3), -+ RK3308_ALC_R_DIG_CON09(3), -+ RK3308_AGC_MAX_GAIN_PGA_SFT, -+ RK3308_AGC_MAX_GAIN_PGA_NDB_13_5, -+ RK3308_AGC_MAX_GAIN_PGA_PDB_28_5, -+ 0, rk3308_codec_alc_agc_ch_max_gain_tlv), -+ -+ /* ALC AGC MIN */ -+ SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 0 Min Volume", -+ RK3308_ALC_L_DIG_CON09(0), -+ RK3308_ALC_R_DIG_CON09(0), -+ RK3308_AGC_MIN_GAIN_PGA_SFT, -+ RK3308_AGC_MIN_GAIN_PGA_NDB_18, -+ RK3308_AGC_MIN_GAIN_PGA_PDB_24, -+ 0, rk3308_codec_alc_agc_ch_min_gain_tlv), -+ SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 1 Min Volume", -+ RK3308_ALC_L_DIG_CON09(1), -+ RK3308_ALC_R_DIG_CON09(1), -+ RK3308_AGC_MIN_GAIN_PGA_SFT, -+ RK3308_AGC_MIN_GAIN_PGA_NDB_18, -+ RK3308_AGC_MIN_GAIN_PGA_PDB_24, -+ 0, rk3308_codec_alc_agc_ch_min_gain_tlv), -+ SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 2 Min Volume", -+ RK3308_ALC_L_DIG_CON09(2), -+ RK3308_ALC_R_DIG_CON09(2), -+ RK3308_AGC_MIN_GAIN_PGA_SFT, -+ RK3308_AGC_MIN_GAIN_PGA_NDB_18, -+ RK3308_AGC_MIN_GAIN_PGA_PDB_24, -+ 0, rk3308_codec_alc_agc_ch_min_gain_tlv), -+ SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 3 Min Volume", -+ RK3308_ALC_L_DIG_CON09(3), -+ RK3308_ALC_R_DIG_CON09(3), -+ RK3308_AGC_MIN_GAIN_PGA_SFT, -+ RK3308_AGC_MIN_GAIN_PGA_NDB_18, -+ RK3308_AGC_MIN_GAIN_PGA_PDB_24, -+ 0, rk3308_codec_alc_agc_ch_min_gain_tlv), -+ -+ /* ADC MIC */ -+ SOC_SINGLE_RANGE_TLV("ADC MIC Channel 0 Left Volume", -+ RK3308_ADC_ANA_CON01(0), -+ RK3308_ADC_CH1_MIC_GAIN_SFT, -+ RK3308_ADC_CH1_MIC_GAIN_0DB, -+ RK3308_ADC_CH1_MIC_GAIN_30DB, -+ 0, rk3308_codec_adc_mic_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("ADC MIC Channel 0 Right Volume", -+ RK3308_ADC_ANA_CON01(0), -+ RK3308_ADC_CH2_MIC_GAIN_SFT, -+ RK3308_ADC_CH2_MIC_GAIN_0DB, -+ RK3308_ADC_CH2_MIC_GAIN_30DB, -+ 0, rk3308_codec_adc_mic_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("ADC MIC Channel 1 Left Volume", -+ RK3308_ADC_ANA_CON01(1), -+ RK3308_ADC_CH1_MIC_GAIN_SFT, -+ RK3308_ADC_CH1_MIC_GAIN_0DB, -+ RK3308_ADC_CH1_MIC_GAIN_30DB, -+ 0, rk3308_codec_adc_mic_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("ADC MIC Channel 1 Right Volume", -+ RK3308_ADC_ANA_CON01(1), -+ RK3308_ADC_CH2_MIC_GAIN_SFT, -+ RK3308_ADC_CH2_MIC_GAIN_0DB, -+ RK3308_ADC_CH2_MIC_GAIN_30DB, -+ 0, rk3308_codec_adc_mic_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("ADC MIC Channel 2 Left Volume", -+ RK3308_ADC_ANA_CON01(2), -+ RK3308_ADC_CH1_MIC_GAIN_SFT, -+ RK3308_ADC_CH1_MIC_GAIN_0DB, -+ RK3308_ADC_CH1_MIC_GAIN_30DB, -+ 0, rk3308_codec_adc_mic_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("ADC MIC Channel 2 Right Volume", -+ RK3308_ADC_ANA_CON01(2), -+ RK3308_ADC_CH2_MIC_GAIN_SFT, -+ RK3308_ADC_CH2_MIC_GAIN_0DB, -+ RK3308_ADC_CH2_MIC_GAIN_30DB, -+ 0, rk3308_codec_adc_mic_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("ADC MIC Channel 3 Left Volume", -+ RK3308_ADC_ANA_CON01(3), -+ RK3308_ADC_CH1_MIC_GAIN_SFT, -+ RK3308_ADC_CH1_MIC_GAIN_0DB, -+ RK3308_ADC_CH1_MIC_GAIN_30DB, -+ 0, rk3308_codec_adc_mic_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("ADC MIC Channel 3 Right Volume", -+ RK3308_ADC_ANA_CON01(3), -+ RK3308_ADC_CH2_MIC_GAIN_SFT, -+ RK3308_ADC_CH2_MIC_GAIN_0DB, -+ RK3308_ADC_CH2_MIC_GAIN_30DB, -+ 0, rk3308_codec_adc_mic_gain_tlv), -+ -+ /* ADC ALC */ -+ SOC_SINGLE_RANGE_TLV("ADC ALC Channel 0 Left Volume", -+ RK3308_ADC_ANA_CON03(0), -+ RK3308_ADC_CH1_ALC_GAIN_SFT, -+ RK3308_ADC_CH1_ALC_GAIN_NDB_18, -+ RK3308_ADC_CH1_ALC_GAIN_PDB_28_5, -+ 0, rk3308_codec_adc_alc_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("ADC ALC Channel 0 Right Volume", -+ RK3308_ADC_ANA_CON04(0), -+ RK3308_ADC_CH2_ALC_GAIN_SFT, -+ RK3308_ADC_CH2_ALC_GAIN_NDB_18, -+ RK3308_ADC_CH2_ALC_GAIN_PDB_28_5, -+ 0, rk3308_codec_adc_alc_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("ADC ALC Channel 1 Left Volume", -+ RK3308_ADC_ANA_CON03(1), -+ RK3308_ADC_CH1_ALC_GAIN_SFT, -+ RK3308_ADC_CH1_ALC_GAIN_NDB_18, -+ RK3308_ADC_CH1_ALC_GAIN_PDB_28_5, -+ 0, rk3308_codec_adc_alc_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("ADC ALC Channel 1 Right Volume", -+ RK3308_ADC_ANA_CON04(1), -+ RK3308_ADC_CH2_ALC_GAIN_SFT, -+ RK3308_ADC_CH2_ALC_GAIN_NDB_18, -+ RK3308_ADC_CH2_ALC_GAIN_PDB_28_5, -+ 0, rk3308_codec_adc_alc_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("ADC ALC Channel 2 Left Volume", -+ RK3308_ADC_ANA_CON03(2), -+ RK3308_ADC_CH1_ALC_GAIN_SFT, -+ RK3308_ADC_CH1_ALC_GAIN_NDB_18, -+ RK3308_ADC_CH1_ALC_GAIN_PDB_28_5, -+ 0, rk3308_codec_adc_alc_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("ADC ALC Channel 2 Right Volume", -+ RK3308_ADC_ANA_CON04(2), -+ RK3308_ADC_CH2_ALC_GAIN_SFT, -+ RK3308_ADC_CH2_ALC_GAIN_NDB_18, -+ RK3308_ADC_CH2_ALC_GAIN_PDB_28_5, -+ 0, rk3308_codec_adc_alc_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("ADC ALC Channel 3 Left Volume", -+ RK3308_ADC_ANA_CON03(3), -+ RK3308_ADC_CH1_ALC_GAIN_SFT, -+ RK3308_ADC_CH1_ALC_GAIN_NDB_18, -+ RK3308_ADC_CH1_ALC_GAIN_PDB_28_5, -+ 0, rk3308_codec_adc_alc_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("ADC ALC Channel 3 Right Volume", -+ RK3308_ADC_ANA_CON04(3), -+ RK3308_ADC_CH2_ALC_GAIN_SFT, -+ RK3308_ADC_CH2_ALC_GAIN_NDB_18, -+ RK3308_ADC_CH2_ALC_GAIN_PDB_28_5, -+ 0, rk3308_codec_adc_alc_gain_tlv), -+ -+ /* DAC */ -+ SOC_SINGLE_RANGE_TLV("DAC Left Volume", -+ RK3308_DAC_ANA_CON04, -+ RK3308_DAC_L_GAIN_SFT, -+ RK3308_DAC_L_GAIN_0DB, -+ RK3308_DAC_L_GAIN_PDB_6, -+ 0, rk3308_codec_dac_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("DAC Right Volume", -+ RK3308_DAC_ANA_CON04, -+ RK3308_DAC_R_GAIN_SFT, -+ RK3308_DAC_R_GAIN_0DB, -+ RK3308_DAC_R_GAIN_PDB_6, -+ 0, rk3308_codec_dac_gain_tlv), -+ -+ /* DAC HPOUT */ -+ SOC_SINGLE_RANGE_TLV("DAC HPOUT Left Volume", -+ RK3308_DAC_ANA_CON05, -+ RK3308_DAC_L_HPOUT_GAIN_SFT, -+ RK3308_DAC_L_HPOUT_GAIN_NDB_39, -+ RK3308_DAC_L_HPOUT_GAIN_PDB_6, -+ 0, rk3308_codec_dac_hpout_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("DAC HPOUT Right Volume", -+ RK3308_DAC_ANA_CON06, -+ RK3308_DAC_R_HPOUT_GAIN_SFT, -+ RK3308_DAC_R_HPOUT_GAIN_NDB_39, -+ RK3308_DAC_R_HPOUT_GAIN_PDB_6, -+ 0, rk3308_codec_dac_hpout_gain_tlv), -+ -+ /* DAC HPMIX */ -+ SOC_SINGLE_RANGE_TLV("DAC HPMIX Left Volume", -+ RK3308_DAC_ANA_CON05, -+ RK3308_DAC_L_HPMIX_GAIN_SFT, -+ RK3308_DAC_L_HPMIX_GAIN_NDB_6, -+ RK3308_DAC_L_HPMIX_GAIN_0DB, -+ 0, rk3308_codec_dac_hpmix_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("DAC HPMIX Right Volume", -+ RK3308_DAC_ANA_CON05, -+ RK3308_DAC_R_HPMIX_GAIN_SFT, -+ RK3308_DAC_R_HPMIX_GAIN_NDB_6, -+ RK3308_DAC_R_HPMIX_GAIN_0DB, -+ 0, rk3308_codec_dac_hpmix_gain_tlv), -+}; -+ -+static void rk3308_speaker_ctl(struct rk3308_codec_priv *rk3308, int on) -+{ -+ gpiod_direction_output(rk3308->spk_ctl_gpio, on); -+} -+ -+static int rk3308_codec_reset(struct snd_soc_codec *codec) -+{ -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ -+ reset_control_assert(rk3308->reset); -+ usleep_range(200, 300); /* estimated value */ -+ reset_control_deassert(rk3308->reset); -+ -+ regmap_write(rk3308->regmap, RK3308_GLB_CON, 0x00); -+ usleep_range(200, 300); /* estimated value */ -+ regmap_write(rk3308->regmap, RK3308_GLB_CON, -+ RK3308_SYS_WORK | -+ RK3308_DAC_DIG_WORK | -+ RK3308_ADC_DIG_WORK); -+ -+ return 0; -+} -+ -+static int rk3308_set_bias_level(struct snd_soc_codec *codec, -+ enum snd_soc_bias_level level) -+{ -+ switch (level) { -+ case SND_SOC_BIAS_ON: -+ break; -+ -+ case SND_SOC_BIAS_PREPARE: -+ break; -+ -+ case SND_SOC_BIAS_STANDBY: -+ case SND_SOC_BIAS_OFF: -+ break; -+ } -+ -+ snd_soc_codec_force_bias_level(codec, level); -+ -+ return 0; -+} -+ -+static int rk3308_set_dai_fmt(struct snd_soc_dai *codec_dai, -+ unsigned int fmt) -+{ -+ struct snd_soc_codec *codec = codec_dai->codec; -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ unsigned int adc_aif1 = 0, adc_aif2 = 0, dac_aif1 = 0, dac_aif2 = 0; -+ int ch = rk3308->adc_ch; -+ -+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { -+ case SND_SOC_DAIFMT_CBS_CFS: -+ adc_aif2 |= RK3308_ADC_IO_MODE_SLAVE; -+ adc_aif2 |= RK3308_ADC_MODE_SLAVE; -+ dac_aif2 |= RK3308_DAC_IO_MODE_SLAVE; -+ dac_aif2 |= RK3308_DAC_MODE_SLAVE; -+ break; -+ case SND_SOC_DAIFMT_CBM_CFM: -+ adc_aif2 |= RK3308_ADC_IO_MODE_MASTER; -+ adc_aif2 |= RK3308_ADC_MODE_MASTER; -+ dac_aif2 |= RK3308_DAC_IO_MODE_MASTER; -+ dac_aif2 |= RK3308_DAC_MODE_MASTER; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { -+ case SND_SOC_DAIFMT_DSP_A: -+ adc_aif1 |= RK3308_ADC_I2S_MODE_PCM; -+ dac_aif1 |= RK3308_DAC_I2S_MODE_PCM; -+ break; -+ case SND_SOC_DAIFMT_I2S: -+ adc_aif1 |= RK3308_ADC_I2S_MODE_I2S; -+ dac_aif1 |= RK3308_DAC_I2S_MODE_I2S; -+ break; -+ case SND_SOC_DAIFMT_RIGHT_J: -+ adc_aif1 |= RK3308_ADC_I2S_MODE_RJ; -+ dac_aif1 |= RK3308_DAC_I2S_MODE_RJ; -+ break; -+ case SND_SOC_DAIFMT_LEFT_J: -+ adc_aif1 |= RK3308_ADC_I2S_MODE_RJ; -+ dac_aif1 |= RK3308_DAC_I2S_MODE_LJ; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { -+ case SND_SOC_DAIFMT_NB_NF: -+ adc_aif1 |= RK3308_ADC_I2S_LRC_POL_NORMAL; -+ adc_aif2 |= RK3308_ADC_I2S_BIT_CLK_POL_NORMAL; -+ dac_aif1 |= RK3308_DAC_I2S_LRC_POL_NORMAL; -+ dac_aif2 |= RK3308_DAC_I2S_BIT_CLK_POL_NORMAL; -+ break; -+ case SND_SOC_DAIFMT_IB_IF: -+ adc_aif1 |= RK3308_ADC_I2S_LRC_POL_REVERSAL; -+ adc_aif2 |= RK3308_ADC_I2S_BIT_CLK_POL_REVERSAL; -+ dac_aif1 |= RK3308_DAC_I2S_LRC_POL_REVERSAL; -+ dac_aif2 |= RK3308_DAC_I2S_BIT_CLK_POL_REVERSAL; -+ break; -+ case SND_SOC_DAIFMT_IB_NF: -+ adc_aif1 |= RK3308_ADC_I2S_LRC_POL_NORMAL; -+ adc_aif2 |= RK3308_ADC_I2S_BIT_CLK_POL_REVERSAL; -+ dac_aif1 |= RK3308_DAC_I2S_LRC_POL_NORMAL; -+ dac_aif2 |= RK3308_DAC_I2S_BIT_CLK_POL_REVERSAL; -+ break; -+ case SND_SOC_DAIFMT_NB_IF: -+ adc_aif1 |= RK3308_ADC_I2S_LRC_POL_REVERSAL; -+ adc_aif2 |= RK3308_ADC_I2S_BIT_CLK_POL_NORMAL; -+ dac_aif1 |= RK3308_DAC_I2S_LRC_POL_REVERSAL; -+ dac_aif2 |= RK3308_DAC_I2S_BIT_CLK_POL_NORMAL; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON01(ch), -+ RK3308_ADC_I2S_LRC_POL_MSK | -+ RK3308_ADC_I2S_MODE_MSK, -+ adc_aif1); -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON02(ch), -+ RK3308_ADC_IO_MODE_MSK | -+ RK3308_ADC_MODE_MSK | -+ RK3308_ADC_I2S_BIT_CLK_POL_MSK, -+ adc_aif2); -+ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON01, -+ RK3308_DAC_I2S_LRC_POL_MSK | -+ RK3308_DAC_I2S_MODE_MSK, -+ dac_aif1); -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON02, -+ RK3308_DAC_IO_MODE_MSK | -+ RK3308_DAC_MODE_MSK | -+ RK3308_DAC_I2S_BIT_CLK_POL_MSK, -+ dac_aif2); -+ -+ return 0; -+} -+ -+static int rk3308_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params, -+ struct snd_soc_dai *dai) -+{ -+ struct snd_soc_codec *codec = dai->codec; -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ unsigned int adc_aif1 = 0, adc_aif2 = 0, dac_aif1 = 0, dac_aif2 = 0; -+ int ch = rk3308->adc_ch; -+ -+ switch (params_format(params)) { -+ case SNDRV_PCM_FORMAT_S16_LE: -+ adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_16BITS; -+ dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_16BITS; -+ break; -+ case SNDRV_PCM_FORMAT_S20_3LE: -+ adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_20BITS; -+ dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_20BITS; -+ break; -+ case SNDRV_PCM_FORMAT_S24_LE: -+ adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_24BITS; -+ dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_24BITS; -+ break; -+ case SNDRV_PCM_FORMAT_S32_LE: -+ adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_32BITS; -+ dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_32BITS; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ switch (params_channels(params)) { -+ case 1: -+ adc_aif1 |= RK3308_ADC_I2S_MONO; -+ break; -+ case 2: -+ adc_aif1 |= RK3308_ADC_I2S_STEREO; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ adc_aif1 |= RK3308_ADC_I2S_LR_NORMAL; -+ adc_aif2 |= RK3308_ADC_I2S_WORK; -+ dac_aif1 |= RK3308_DAC_I2S_LR_NORMAL; -+ dac_aif2 |= RK3308_DAC_I2S_WORK; -+ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON01(ch), -+ RK3308_ADC_I2S_VALID_LEN_MSK | -+ RK3308_ADC_I2S_LR_MSK | -+ RK3308_ADC_I2S_TYPE_MSK, -+ adc_aif1); -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON02(ch), -+ RK3308_ADC_I2S_MSK, -+ adc_aif2); -+ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON01, -+ RK3308_DAC_I2S_VALID_LEN_MSK | -+ RK3308_DAC_I2S_LR_MSK, -+ dac_aif1); -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON02, -+ RK3308_DAC_I2S_MSK, -+ dac_aif2); -+ -+ return 0; -+} -+ -+static int rk3308_digital_mute(struct snd_soc_dai *dai, int mute) -+{ -+ return 0; -+} -+ -+static int rk3308_codec_dac_enable(struct rk3308_codec_priv *rk3308) -+{ -+ /* Step 01 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON00, -+ RK3308_DAC_CURRENT_MSK, -+ RK3308_DAC_CURRENT_EN); -+ -+ /* Step 02 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01, -+ RK3308_DAC_BUF_REF_L_MSK | -+ RK3308_DAC_BUF_REF_R_MSK, -+ RK3308_DAC_BUF_REF_L_EN | -+ RK3308_DAC_BUF_REF_R_EN); -+ -+ /* Step 03 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01, -+ RK3308_DAC_POP_SOUND_L_MSK | -+ RK3308_DAC_POP_SOUND_R_MSK, -+ RK3308_DAC_POP_SOUND_L_WORK | -+ RK3308_DAC_POP_SOUND_R_WORK); -+ -+ /* Step 04 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON13, -+ RK3308_DAC_L_HPMIX_EN | RK3308_DAC_R_HPMIX_EN, -+ RK3308_DAC_L_HPMIX_EN | RK3308_DAC_R_HPMIX_EN); -+ -+ /* Step 05 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON13, -+ RK3308_DAC_L_HPMIX_WORK | RK3308_DAC_R_HPMIX_WORK, -+ RK3308_DAC_L_HPMIX_WORK | RK3308_DAC_R_HPMIX_WORK); -+ -+ /* Step 06 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04, -+ RK3308_DAC_L_LINEOUT_EN | RK3308_DAC_R_LINEOUT_EN, -+ RK3308_DAC_L_LINEOUT_EN | RK3308_DAC_R_LINEOUT_EN); -+ -+ /* Step 07 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03, -+ RK3308_DAC_L_HPOUT_EN | RK3308_DAC_R_HPOUT_EN, -+ RK3308_DAC_L_HPOUT_EN | RK3308_DAC_R_HPOUT_EN); -+ -+ /* Step 08 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03, -+ RK3308_DAC_L_HPOUT_WORK | RK3308_DAC_R_HPOUT_WORK, -+ RK3308_DAC_L_HPOUT_WORK | RK3308_DAC_R_HPOUT_WORK); -+ -+ /* Step 09 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02, -+ RK3308_DAC_L_REF_EN | RK3308_DAC_R_REF_EN, -+ RK3308_DAC_L_REF_EN | RK3308_DAC_R_REF_EN); -+ -+ /* Step 10 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02, -+ RK3308_DAC_L_CLK_EN | RK3308_DAC_R_CLK_EN, -+ RK3308_DAC_L_CLK_EN | RK3308_DAC_R_CLK_EN); -+ -+ /* Step 11 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02, -+ RK3308_DAC_L_DAC_EN | RK3308_DAC_R_DAC_EN, -+ RK3308_DAC_L_DAC_EN | RK3308_DAC_R_DAC_EN); -+ -+ /* Step 12 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02, -+ RK3308_DAC_L_DAC_WORK | RK3308_DAC_R_DAC_WORK, -+ RK3308_DAC_L_DAC_WORK | RK3308_DAC_R_DAC_WORK); -+ -+ /* Step 13 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON12, -+ RK3308_DAC_L_HPMIX_SEL_MSK | -+ RK3308_DAC_R_HPMIX_SEL_MSK, -+ RK3308_DAC_L_HPMIX_I2S | -+ RK3308_DAC_R_HPMIX_I2S); -+ -+ /* Step 14 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON13, -+ RK3308_DAC_L_HPMIX_UNMUTE | -+ RK3308_DAC_R_HPMIX_UNMUTE, -+ RK3308_DAC_L_HPMIX_UNMUTE | -+ RK3308_DAC_R_HPMIX_UNMUTE); -+ -+ /* Step 15 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON12, -+ RK3308_DAC_L_HPMIX_GAIN_MSK | -+ RK3308_DAC_R_HPMIX_GAIN_MSK, -+ RK3308_DAC_L_HPMIX_GAIN_0DB | -+ RK3308_DAC_R_HPMIX_GAIN_0DB); -+ -+ /* Step 16 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03, -+ RK3308_DAC_L_HPOUT_UNMUTE | -+ RK3308_DAC_R_HPOUT_UNMUTE, -+ RK3308_DAC_L_HPOUT_UNMUTE | -+ RK3308_DAC_R_HPOUT_UNMUTE); -+ -+ /* Step 17 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04, -+ RK3308_DAC_L_LINEOUT_UNMUTE | -+ RK3308_DAC_R_LINEOUT_UNMUTE, -+ RK3308_DAC_L_LINEOUT_UNMUTE | -+ RK3308_DAC_R_LINEOUT_UNMUTE); -+ -+ /* Step 18 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON05, -+ RK3308_DAC_L_HPOUT_GAIN_MSK, -+ RK3308_DAC_L_HPOUT_GAIN_0DB); -+ -+ /* Step 18 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON06, -+ RK3308_DAC_R_HPOUT_GAIN_MSK, -+ RK3308_DAC_R_HPOUT_GAIN_0DB); -+ -+ /* Step 19 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04, -+ RK3308_DAC_L_GAIN_MSK | RK3308_DAC_R_GAIN_MSK, -+ RK3308_DAC_L_GAIN_0DB | RK3308_DAC_R_GAIN_0DB); -+ -+ return 0; -+} -+ -+static int rk3308_codec_dac_disable(struct rk3308_codec_priv *rk3308) -+{ -+ /* Step 01 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04, -+ RK3308_DAC_L_GAIN_MSK | RK3308_DAC_R_GAIN_MSK, -+ RK3308_DAC_L_GAIN_0DB | RK3308_DAC_R_GAIN_0DB); -+ -+ /* -+ * Step 02 -+ * -+ * Note1. In the step2, adjusting the register step by step to the -+ * appropriate value and taking 20ms as time step -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON05, -+ RK3308_DAC_L_HPOUT_GAIN_MSK, -+ RK3308_DAC_L_HPOUT_GAIN_NDB_39); -+ -+ /* Step 02 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON06, -+ RK3308_DAC_R_HPOUT_GAIN_MSK, -+ RK3308_DAC_R_HPOUT_GAIN_NDB_39); -+ -+ /* Step 03 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON13, -+ RK3308_DAC_L_HPMIX_UNMUTE | -+ RK3308_DAC_R_HPMIX_UNMUTE, -+ RK3308_DAC_L_HPMIX_MUTE | -+ RK3308_DAC_R_HPMIX_MUTE); -+ -+ /* Step 04 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON12, -+ RK3308_DAC_L_HPMIX_SEL_MSK | -+ RK3308_DAC_R_HPMIX_SEL_MSK, -+ RK3308_DAC_L_HPMIX_NONE | -+ RK3308_DAC_R_HPMIX_NONE); -+ -+ /* Step 05 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03, -+ RK3308_DAC_L_HPOUT_UNMUTE | -+ RK3308_DAC_R_HPOUT_UNMUTE, -+ RK3308_DAC_L_HPOUT_MUTE | -+ RK3308_DAC_R_HPOUT_MUTE); -+ -+ /* Step 06 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02, -+ RK3308_DAC_L_DAC_WORK | RK3308_DAC_R_DAC_WORK, -+ RK3308_DAC_L_DAC_INIT | RK3308_DAC_R_DAC_INIT); -+ -+ /* Step 07 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03, -+ RK3308_DAC_L_HPOUT_EN | RK3308_DAC_R_HPOUT_EN, -+ RK3308_DAC_L_HPOUT_DIS | RK3308_DAC_R_HPOUT_DIS); -+ -+ /* Step 08 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04, -+ RK3308_DAC_L_LINEOUT_UNMUTE | -+ RK3308_DAC_R_LINEOUT_UNMUTE, -+ RK3308_DAC_L_LINEOUT_MUTE | -+ RK3308_DAC_R_LINEOUT_MUTE); -+ -+ /* Step 09 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04, -+ RK3308_DAC_L_LINEOUT_EN | RK3308_DAC_R_LINEOUT_EN, -+ RK3308_DAC_L_LINEOUT_DIS | RK3308_DAC_R_LINEOUT_DIS); -+ -+ /* Step 10 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON13, -+ RK3308_DAC_L_HPMIX_EN | RK3308_DAC_R_HPMIX_EN, -+ RK3308_DAC_L_HPMIX_DIS | RK3308_DAC_R_HPMIX_DIS); -+ -+ /* Step 11 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02, -+ RK3308_DAC_L_DAC_EN | RK3308_DAC_R_DAC_EN, -+ RK3308_DAC_L_DAC_DIS | RK3308_DAC_R_DAC_DIS); -+ -+ /* Step 12 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02, -+ RK3308_DAC_L_CLK_EN | RK3308_DAC_R_CLK_EN, -+ RK3308_DAC_L_CLK_DIS | RK3308_DAC_R_CLK_DIS); -+ -+ /* Step 13 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02, -+ RK3308_DAC_L_REF_EN | RK3308_DAC_R_REF_EN, -+ RK3308_DAC_L_REF_DIS | RK3308_DAC_R_REF_DIS); -+ -+ /* Step 14 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01, -+ RK3308_DAC_POP_SOUND_L_MSK | -+ RK3308_DAC_POP_SOUND_R_MSK, -+ RK3308_DAC_POP_SOUND_L_INIT | -+ RK3308_DAC_POP_SOUND_R_INIT); -+ -+ /* Step 15 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01, -+ RK3308_DAC_BUF_REF_L_EN | RK3308_DAC_BUF_REF_R_EN, -+ RK3308_DAC_BUF_REF_L_DIS | RK3308_DAC_BUF_REF_R_DIS); -+ -+ /* Step 16 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON00, -+ RK3308_DAC_CURRENT_EN, -+ RK3308_DAC_CURRENT_DIS); -+ -+ /* Step 17 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03, -+ RK3308_DAC_L_HPOUT_WORK | RK3308_DAC_R_HPOUT_WORK, -+ RK3308_DAC_L_HPOUT_INIT | RK3308_DAC_R_HPOUT_INIT); -+ -+ /* Step 18 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON13, -+ RK3308_DAC_L_HPMIX_WORK | RK3308_DAC_R_HPMIX_WORK, -+ RK3308_DAC_L_HPMIX_INIT | RK3308_DAC_R_HPMIX_INIT); -+ -+ /* Step 19 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON12, -+ RK3308_DAC_L_HPMIX_GAIN_MSK | -+ RK3308_DAC_R_HPMIX_GAIN_MSK, -+ RK3308_DAC_L_HPMIX_GAIN_NDB_6 | -+ RK3308_DAC_R_HPMIX_GAIN_NDB_6); -+ -+ /* -+ * Note2. If the ACODEC_DAC_ANA_CON12[7] or ACODEC_DAC_ANA_CON12[3] -+ * is set to 0x1, add the steps from the section Disable DAC -+ * Configuration Standard Usage Flow after complete the step 19 -+ */ -+ -+ return 0; -+} -+ -+static int rk3308_codec_power_on(struct snd_soc_codec *codec) -+{ -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ -+ /* 1. Supply the power of digital part and reset the Audio Codec */ -+ /* Do nothing */ -+ -+ /* -+ * 2. Configure ACODEC_DAC_ANA_CON1[1:0] and ACODEC_DAC_ANA_CON1[5:4] -+ * to 0x1, to setup dc voltage of the DAC channel output -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01, -+ RK3308_DAC_POP_SOUND_L_MSK, RK3308_DAC_POP_SOUND_L_INIT); -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01, -+ RK3308_DAC_POP_SOUND_R_MSK, RK3308_DAC_POP_SOUND_R_INIT); -+ -+ /* -+ * 3. Configure the register ACODEC_ADC_ANA_CON10[6:0] to 0x1 -+ * -+ * Note: Only the reg (ADC_ANA_CON10+0x0)[6:0] represent the control -+ * signal to select current to pre-charge/dis_charge -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), -+ RK3308_ADC_CURRENT_CHARGE_MSK, RK3308_ADC_SEL_I_64(1)); -+ -+ /* 4. Supply the power of the analog part(AVDD,AVDDRV) */ -+ -+ /* -+ * 5. Configure the register ACODEC_ADC_ANA_CON10[7] to 0x1 to setup -+ * reference voltage -+ * -+ * Note: Only the reg (ADC_ANA_CON10+0x0)[7] represent the enable -+ * signal of reference voltage module -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), -+ RK3308_ADC_REF_EN, RK3308_ADC_REF_EN); -+ -+ /* -+ * 6. Change the register ACODEC_ADC_ANA_CON10[6:0] from the 0x1 to -+ * 0x7f step by step or configure the ACODEC_ADC_ANA_CON10[6:0] to -+ * 0x7f directly. The suggestion slot time of the step is 20ms. -+ */ -+ mdelay(20); -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), -+ RK3308_ADC_CURRENT_CHARGE_MSK, -+ RK3308_ADC_DONT_SEL_ALL); -+ -+ /* 7. Wait until the voltage of VCM keeps stable at the AVDD/2 */ -+ usleep_range(200, 300); /* estimated value */ -+ -+ /* -+ * 8. Configure the register ACODEC_ADC_ANA_CON10[6:0] to the -+ * appropriate value(expect 0x0) for reducing power. -+ */ -+ -+ /* TODO: choose an appropriate charge value */ -+ -+ return 0; -+} -+ -+static int rk3308_codec_power_off(struct snd_soc_codec *codec) -+{ -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ -+ /* -+ * 1. Keep the power on and disable the DAC and ADC path according to -+ * the section power on configuration standard usage flow. -+ */ -+ -+ /* 2. Configure the register ACODEC_ADC_ANA_CON10[6:0] to 0x1 */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), -+ RK3308_ADC_CURRENT_CHARGE_MSK, RK3308_ADC_SEL_I_64(1)); -+ -+ /* 3. Configure the register ACODEC_ADC_ANA_CON10[7] to 0x0 */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), -+ RK3308_ADC_REF_EN, RK3308_ADC_REF_DIS); -+ -+ /* -+ * 4.Change the register ACODEC_ADC_ANA_CON10[6:0] from the 0x1 to 0x7f -+ * step by step or configure the ACODEC_ADC_ANA_CON10[6:0] to 0x7f -+ * directly. The suggestion slot time of the step is 20ms -+ */ -+ mdelay(20); -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), -+ RK3308_ADC_CURRENT_CHARGE_MSK, -+ RK3308_ADC_DONT_SEL_ALL); -+ -+ /* 5. Wait until the voltage of VCM keeps stable at the AGND */ -+ usleep_range(200, 300); /* estimated value */ -+ -+ /* 6. Power off the analog power supply */ -+ /* 7. Power off the digital power supply */ -+ -+ /* Do something via hardware */ -+ -+ return 0; -+} -+ -+static int check_micbias(int micbias) -+{ -+ switch (micbias) { -+ case RK3308_ADC_MICBIAS_VOLT_0_85: -+ case RK3308_ADC_MICBIAS_VOLT_0_8: -+ case RK3308_ADC_MICBIAS_VOLT_0_75: -+ case RK3308_ADC_MICBIAS_VOLT_0_7: -+ case RK3308_ADC_MICBIAS_VOLT_0_65: -+ case RK3308_ADC_MICBIAS_VOLT_0_6: -+ case RK3308_ADC_MICBIAS_VOLT_0_55: -+ case RK3308_ADC_MICBIAS_VOLT_0_5: -+ return 0; -+ } -+ -+ return -EINVAL; -+} -+ -+static int rk3308_codec_micbias_enable(struct rk3308_codec_priv *rk3308, -+ int micbias) -+{ -+ int ch = rk3308->adc_ch; -+ int ret; -+ -+ if (ch != 1 && ch != 2) { -+ dev_err(rk3308->plat_dev, -+ "%s: currnet ch: %d, only ch1/2 control MICBIAS1/2\n", -+ __func__, ch); -+ return -EINVAL; -+ } -+ -+ /* 1. Power up the ACODEC and keep the AVDDH stable */ -+ -+ /* 2. Configure ACODEC_ADC_ANA_CON7[2:0] to the certain value */ -+ ret = check_micbias(micbias); -+ if (ret < 0) { -+ dev_err(rk3308->plat_dev, "This is an invalid micbias: %d\n", -+ micbias); -+ return ret; -+ } -+ -+ /* -+ * Note: Only the reg (ADC_ANA_CON7+0x0)[2:0] represent the level range -+ * control signal of MICBIAS voltage -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(0), -+ RK3308_ADC_LEVEL_RANGE_MICBIAS_MSK, -+ micbias); -+ -+ /* 3. Wait until the VCMH keep stable */ -+ usleep_range(200, 300); /* estimated value */ -+ -+ /* 4. Configure ACODEC_ADC_ANA_CON8[4] to 0x1 */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON08(ch), -+ RK3308_ADC_MICBIAS_CURRENT_MSK, -+ RK3308_ADC_MICBIAS_CURRENT_EN); -+ -+ /* -+ * 5. Configure the (ADC_ANA_CON7+0x40)[3] or (ADC_ANA_CON7+0x80)[3] -+ * to 0x1. -+ * (ADC_ANA_CON7+0x40)[3] used to control the MICBIAS1, and -+ * (ADC_ANA_CON7+0x80)[3] used to control the MICBIAS2 -+ */ -+ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(ch), -+ RK3308_ADC_MIC_BIAS_BUF_EN, -+ RK3308_ADC_MIC_BIAS_BUF_EN); -+ -+ return 0; -+} -+ -+static int rk3308_codec_micbias_disable(struct rk3308_codec_priv *rk3308) -+{ -+ int ch = rk3308->adc_ch; -+ -+ if (ch != 1 && ch != 2) { -+ dev_err(rk3308->plat_dev, -+ "%s: currnet ch: %d, only ch1/2 control MICBIAS1/2\n", -+ __func__, ch); -+ return -EINVAL; -+ } -+ -+ /* 1. Enable the MICBIAS and keep the Audio Codec stable */ -+ /* Do nothing */ -+ -+ /* -+ * 2. Configure the (ADC_ANA_CON7+0x40)[3] or -+ * (ADC_ANA_CON7+0x80)[3] to 0x0 -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(ch), -+ RK3308_ADC_MIC_BIAS_BUF_EN, -+ RK3308_ADC_MIC_BIAS_BUF_DIS); -+ -+ /* 3. Configure ACODEC_ADC_ANA_CON8[4] to 0x0 */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON08(ch), -+ RK3308_ADC_MICBIAS_CURRENT_MSK, -+ RK3308_ADC_MICBIAS_CURRENT_DIS); -+ -+ return 0; -+} -+ -+static int rk3308_codec_alc_enable(struct rk3308_codec_priv *rk3308) -+{ -+ int ch = rk3308->adc_ch; -+ -+ /* -+ * 1. Set he max level and min level of the ALC need to control. -+ * -+ * These values are estimated -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON05(ch), -+ RK3308_AGC_LO_8BITS_AGC_MIN_MSK, -+ 0x16); -+ regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON05(ch), -+ RK3308_AGC_HI_8BITS_AGC_MIN_MSK, -+ 0x40); -+ -+ regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON05(ch), -+ RK3308_AGC_LO_8BITS_AGC_MAX_MSK, -+ 0x26); -+ regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON05(ch), -+ RK3308_AGC_HI_8BITS_AGC_MAX_MSK, -+ 0x40); -+ -+ /* -+ * 2. Set ACODEC_ALC_DIG_CON4[2:0] according to the sample rate -+ * -+ * By default is 44.1KHz for sample. -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON04(ch), -+ RK3308_AGC_APPROX_RATE_MSK, -+ RK3308_AGC_APPROX_RATE_44_1K); -+ regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON04(ch), -+ RK3308_AGC_APPROX_RATE_MSK, -+ RK3308_AGC_APPROX_RATE_44_1K); -+ -+ /* 3. Set ACODEC_ALC_DIG_CON9[6] to 0x1, to enable the ALC module */ -+ regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON09(ch), -+ RK3308_AGC_FUNC_SEL_MSK, -+ RK3308_AGC_FUNC_SEL_EN); -+ regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON09(ch), -+ RK3308_AGC_FUNC_SEL_MSK, -+ RK3308_AGC_FUNC_SEL_EN); -+ -+ /* -+ * 4. Set ACODEC_ADC_ANA_CON11[1:0], (ACODEC_ADC_ANA_CON11+0x40)[1:0], -+ * (ACODEC_ADC_ANA_CON11+0x80)[1:0] and (ACODEC_ADC_ANA_CON11+0xc0)[1:0] -+ * to 0x3, to enable the ALC module to control the gain of PGA. -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON11(ch), -+ RK3308_ADC_ALCL_CON_GAIN_PGAL_MSK | -+ RK3308_ADC_ALCR_CON_GAIN_PGAR_MSK, -+ RK3308_ADC_ALCL_CON_GAIN_PGAL_EN | -+ RK3308_ADC_ALCR_CON_GAIN_PGAR_EN); -+ -+ /* -+ * 5.Observe the current ALC output gain by reading -+ * ACODEC_ALC_DIG_CON12[4:0] -+ * -+ * The default GAIN is 0x0c -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON12(ch), -+ RK3308_AGC_GAIN_MSK, -+ 0x0c); -+ regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON12(ch), -+ RK3308_AGC_GAIN_MSK, -+ 0x0c); -+ -+ return 0; -+} -+ -+static int rk3308_codec_alc_disable(struct rk3308_codec_priv *rk3308) -+{ -+ int ch = rk3308->adc_ch; -+ -+ /* -+ * 1. Set ACODEC_ALC_DIG_CON9[6] to 0x0, to disable the ALC module, -+ * then the ALC output gain will keep to the last value -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON09(ch), -+ RK3308_AGC_FUNC_SEL_MSK, -+ RK3308_AGC_FUNC_SEL_DIS); -+ regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON09(ch), -+ RK3308_AGC_FUNC_SEL_MSK, -+ RK3308_AGC_FUNC_SEL_DIS); -+ -+ /* -+ * 2. Set ACODEC_ADC_ANA_CON11[1:0], (ACODEC_ADC_ANA_CON11+0x40)[1:0], -+ * (ACODEC_ADC_ANA_CON11+0x80)[1:0] and (ACODEC_ADC_ANA_CON11+0xc0)[1:0] -+ * to 0x0, to disable the ALC module to control the gain of PGA. -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON11(ch), -+ RK3308_ADC_ALCL_CON_GAIN_PGAL_MSK | -+ RK3308_ADC_ALCR_CON_GAIN_PGAR_MSK, -+ RK3308_ADC_ALCL_CON_GAIN_PGAL_DIS | -+ RK3308_ADC_ALCR_CON_GAIN_PGAR_DIS); -+ -+ return 0; -+} -+ -+static int rk3308_codec_adc_ana_enable(struct rk3308_codec_priv *rk3308) -+{ -+ unsigned int adc_aif1 = 0, adc_aif2 = 0; -+ unsigned int agc_func_en; -+ int ch = rk3308->adc_ch; -+ -+ /* -+ * 1. Set the ACODEC_ADC_ANA_CON7[7:6] and ACODEC_ADC_ANA_CON7[5:4], -+ * to select the line-in or microphone as input of ADC -+ * -+ * Note1. Please ignore the step1 for enabling ADC3, ADC4, ADC5, -+ * ADC6, ADC7, and ADC8 -+ */ -+ if (ch == 0) { -+ if (rk3308->adc_ch0_using_linein) { -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(ch), -+ RK3308_ADC_CH1_IN_SEL_MSK, -+ RK3308_ADC_CH1_IN_LINEIN); -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(ch), -+ RK3308_ADC_CH2_IN_SEL_MSK, -+ RK3308_ADC_CH2_IN_LINEIN); -+ } else { -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(ch), -+ RK3308_ADC_CH1_IN_SEL_MSK, -+ RK3308_ADC_CH1_IN_MIC); -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(ch), -+ RK3308_ADC_CH2_IN_SEL_MSK, -+ RK3308_ADC_CH2_IN_MIC); -+ } -+ } -+ -+ /* -+ * 2. Set ACODEC_ADC_ANA_CON0[7:0] to 0xff, to end the mute station -+ * of ADC, to enable the MIC module, to enable the reference voltage -+ * buffer, and to end the initialization of MIC -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON00(ch), -+ RK3308_ADC_CH1_CH2_MIC_ALL_MSK, -+ RK3308_ADC_CH1_CH2_MIC_ALL); -+ -+ /* -+ * 3. Set ACODEC_ADC_ANA_CON6[0] to 0x1, to enable the current source -+ * of audio -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON06(ch), -+ RK3308_ADC_CURRENT_MSK, -+ RK3308_ADC_CURRENT_EN); -+ -+ /* -+ * 4. Set ACODEC_ADC_ANA_CON2[7:0] to 0x77, to enable the ALC module, -+ * to enable the zero-crossing detection function, and to end the -+ * initialization of ALC -+ * -+ * Note2. Please set ACODEC_ADC_ANA_CON2[7:0] to 0x33 in step4 -+ * if the AGC function is closed -+ */ -+ -+ adc_aif1 = RK3308_ADC_CH1_ALC_EN | RK3308_ADC_CH1_ALC_WORK; -+ regmap_read(rk3308->regmap, RK3308_ALC_L_DIG_CON09(ch), &agc_func_en); -+ if (agc_func_en & RK3308_AGC_FUNC_SEL_EN) -+ adc_aif1 |= RK3308_ADC_CH1_ZEROCROSS_DET_EN; -+ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON02(ch), -+ RK3308_ADC_CH1_ALC_ZC_MSK, -+ adc_aif1); -+ -+ adc_aif2 = RK3308_ADC_CH2_ALC_EN | RK3308_ADC_CH2_ALC_WORK; -+ regmap_read(rk3308->regmap, RK3308_ALC_L_DIG_CON09(ch), &agc_func_en); -+ if (agc_func_en & RK3308_AGC_FUNC_SEL_EN) -+ adc_aif2 |= RK3308_ADC_CH2_ZEROCROSS_DET_EN; -+ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON02(ch), -+ RK3308_ADC_CH2_ALC_ZC_MSK, -+ adc_aif2); -+ -+ /* -+ * 5. Set ACODEC_ADC_ANA_CON5[7:0] to 0x77, to enable the clock and -+ * ADC module, and to end the initialization of ADC -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON05(ch), -+ RK3308_ADC_CH1_ADC_CLK_MSK, -+ RK3308_ADC_CH1_CLK_EN | -+ RK3308_ADC_CH1_ADC_EN | -+ RK3308_ADC_CH1_ADC_WORK); -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON05(ch), -+ RK3308_ADC_CH2_ADC_CLK_MSK, -+ RK3308_ADC_CH2_CLK_EN | -+ RK3308_ADC_CH2_ADC_EN | -+ RK3308_ADC_CH2_ADC_WORK); -+ -+ /* -+ * 6. Set ACODEC_ADC_ANA_CON1[5:4] and ACODEC_ADC_ANA_CON1[1:0], -+ * to select the gain of the MIC -+ * -+ * By default is 0db. -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON05(ch), -+ RK3308_ADC_CH1_MIC_GAIN_MSK, -+ RK3308_ADC_CH1_MIC_GAIN_0DB); -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON05(ch), -+ RK3308_ADC_CH2_MIC_GAIN_MSK, -+ RK3308_ADC_CH2_MIC_GAIN_0DB); -+ -+ /* -+ * 7.Set ACODEC_ADC_ANA_CON3[4:0] and ACODEC_ADC_ANA_CON4[3:0] to -+ * select the gain of ALC -+ * -+ * By default is 0db. -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON03(ch), -+ RK3308_ADC_CH1_ALC_GAIN_MSK, -+ RK3308_ADC_CH1_ALC_GAIN_0DB); -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON04(ch), -+ RK3308_ADC_CH2_ALC_GAIN_MSK, -+ RK3308_ADC_CH2_ALC_GAIN_0DB); -+ -+ /* 8.Begin recording */ -+ -+ return 0; -+} -+ -+static int rk3308_codec_adc_ana_disable(struct rk3308_codec_priv *rk3308) -+{ -+ int ch = rk3308->adc_ch; -+ -+ /* -+ * 1. Set ACODEC_ADC_ANA_CON2[7:0] to 0x0, to disable the ALC module, -+ * to disable the zero-crossing detection function, and to begin the -+ * initialization of ALC -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON02(ch), -+ RK3308_ADC_CH1_ALC_ZC_MSK, -+ 0); -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON02(ch), -+ RK3308_ADC_CH2_ALC_ZC_MSK, -+ 0); -+ -+ /* -+ * 2. Set ACODEC_ADC_ANA_CON5[7:0] to 0x0, to disable the clock and -+ * ADC module, and to begin the initialization of ADC -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON05(ch), -+ RK3308_ADC_CH1_ADC_CLK_MSK, -+ 0); -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON05(ch), -+ RK3308_ADC_CH2_ADC_CLK_MSK, -+ 0); -+ -+ /* -+ * 3. Set ACODEC_ADC_ANA_CON0[7:0] to 0x88, to disable the MIC module, -+ * to disable the reference voltage buffer, and to begin the -+ * initialization of MIC -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON00(ch), -+ RK3308_ADC_CH1_CH2_MIC_ALL_MSK, -+ RK3308_ADC_CH1_MIC_UNMUTE | -+ RK3308_ADC_CH2_MIC_UNMUTE); -+ -+ /* -+ * 4. Set ACODEC_ADC_ANA_CON6[0] to 0x0, to disable the current -+ * source of audio -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON06(ch), -+ RK3308_ADC_CURRENT_MSK, -+ RK3308_ADC_CURRENT_DIS); -+ -+ return 0; -+} -+ -+static int rk3308_codec_open_capture(struct snd_soc_codec *codec) -+{ -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ -+ rk3308_codec_alc_enable(rk3308); -+ rk3308_codec_adc_ana_enable(rk3308); -+ -+ return 0; -+} -+ -+static int rk3308_codec_close_capture(struct snd_soc_codec *codec) -+{ -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ -+ rk3308_codec_alc_disable(rk3308); -+ rk3308_codec_adc_ana_disable(rk3308); -+ -+ return 0; -+} -+ -+static int rk3308_codec_open_playback(struct snd_soc_codec *codec) -+{ -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ -+ rk3308_codec_dac_enable(rk3308); -+ rk3308_speaker_ctl(rk3308, 1); -+ -+ return 0; -+} -+ -+static int rk3308_codec_close_playback(struct snd_soc_codec *codec) -+{ -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ -+ rk3308_speaker_ctl(rk3308, 0); -+ rk3308_codec_dac_disable(rk3308); -+ -+ return 0; -+} -+ -+static int rk3308_pcm_startup(struct snd_pcm_substream *substream, -+ struct snd_soc_dai *dai) -+{ -+ struct snd_soc_codec *codec = dai->codec; -+ int ret = 0; -+ -+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) -+ ret = rk3308_codec_open_playback(codec); -+ else -+ ret = rk3308_codec_open_capture(codec); -+ -+ return ret; -+} -+ -+static void rk3308_pcm_shutdown(struct snd_pcm_substream *substream, -+ struct snd_soc_dai *dai) -+{ -+ struct snd_soc_codec *codec = dai->codec; -+ -+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) -+ rk3308_codec_close_playback(codec); -+ else -+ rk3308_codec_close_capture(codec); -+} -+ -+static struct snd_soc_dai_ops rk3308_dai_ops = { -+ .hw_params = rk3308_hw_params, -+ .set_fmt = rk3308_set_dai_fmt, -+ .digital_mute = rk3308_digital_mute, -+ .startup = rk3308_pcm_startup, -+ .shutdown = rk3308_pcm_shutdown, -+}; -+ -+static struct snd_soc_dai_driver rk3308_dai[] = { -+ { -+ .name = "rk3308-hifi", -+ .id = RK3308_HIFI, -+ .playback = { -+ .stream_name = "HiFi Playback", -+ .channels_min = 2, -+ .channels_max = 2, -+ .rates = SNDRV_PCM_RATE_8000_96000, -+ .formats = (SNDRV_PCM_FMTBIT_S16_LE | -+ SNDRV_PCM_FMTBIT_S20_3LE | -+ SNDRV_PCM_FMTBIT_S24_LE | -+ SNDRV_PCM_FMTBIT_S32_LE), -+ }, -+ .capture = { -+ .stream_name = "HiFi Capture", -+ .channels_min = 1, -+ .channels_max = 8, -+ .rates = SNDRV_PCM_RATE_8000_96000, -+ .formats = (SNDRV_PCM_FMTBIT_S16_LE | -+ SNDRV_PCM_FMTBIT_S20_3LE | -+ SNDRV_PCM_FMTBIT_S24_LE | -+ SNDRV_PCM_FMTBIT_S32_LE), -+ }, -+ .ops = &rk3308_dai_ops, -+ }, -+}; -+ -+static int rk3308_suspend(struct snd_soc_codec *codec) -+{ -+ rk3308_set_bias_level(codec, SND_SOC_BIAS_OFF); -+ -+ return 0; -+} -+ -+static int rk3308_resume(struct snd_soc_codec *codec) -+{ -+ rk3308_set_bias_level(codec, SND_SOC_BIAS_STANDBY); -+ -+ return 0; -+} -+ -+static int rk3308_probe(struct snd_soc_codec *codec) -+{ -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ -+ rk3308_codec_reset(codec); -+ rk3308_codec_power_on(codec); -+ -+ rk3308_codec_micbias_enable(rk3308, RK3308_ADC_MICBIAS_VOLT_0_7); -+ -+ return 0; -+} -+ -+static int rk3308_remove(struct snd_soc_codec *codec) -+{ -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ -+ rk3308_speaker_ctl(rk3308, 0); -+ rk3308_codec_micbias_disable(rk3308); -+ rk3308_codec_power_off(codec); -+ -+ return 0; -+} -+ -+static struct snd_soc_codec_driver soc_codec_dev_rk3308 = { -+ .probe = rk3308_probe, -+ .remove = rk3308_remove, -+ .suspend = rk3308_suspend, -+ .resume = rk3308_resume, -+ .set_bias_level = rk3308_set_bias_level, -+ .controls = rk3308_codec_dapm_controls, -+ .num_controls = ARRAY_SIZE(rk3308_codec_dapm_controls), -+}; -+ -+static const struct reg_default rk3308_codec_reg_defaults[] = { -+ { RK3308_GLB_CON, 0x07 }, -+}; -+ -+static bool rk3308_codec_write_read_reg(struct device *dev, unsigned int reg) -+{ -+ /* All registers can be read / write */ -+ return true; -+} -+ -+static bool rk3308_codec_volatile_reg(struct device *dev, unsigned int reg) -+{ -+ switch (reg) { -+ case RK3308_GLB_CON: -+ return true; -+ default: -+ return false; -+ } -+} -+ -+static const struct regmap_config rk3308_codec_regmap_config = { -+ .reg_bits = 32, -+ .reg_stride = 4, -+ .val_bits = 32, -+ .max_register = RK3308_DAC_ANA_CON13, -+ .writeable_reg = rk3308_codec_write_read_reg, -+ .readable_reg = rk3308_codec_write_read_reg, -+ .volatile_reg = rk3308_codec_volatile_reg, -+ .reg_defaults = rk3308_codec_reg_defaults, -+ .num_reg_defaults = ARRAY_SIZE(rk3308_codec_reg_defaults), -+ .cache_type = REGCACHE_FLAT, -+}; -+ -+static ssize_t adc_ch_show(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct rk3308_codec_priv *rk3308 = -+ container_of(dev, struct rk3308_codec_priv, dev); -+ -+ return sprintf(buf, "adc_ch: %d\n", rk3308->adc_ch); -+} -+ -+static ssize_t adc_ch_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct rk3308_codec_priv *rk3308 = -+ container_of(dev, struct rk3308_codec_priv, dev); -+ unsigned long ch; -+ int ret = kstrtoul(buf, 10, &ch); -+ -+ if (ret < 0 || ch > 4) { -+ dev_err(dev, "Invalid ch: %ld, ret: %d\n", ch, ret); -+ return -EINVAL; -+ } -+ -+ rk3308->adc_ch = ch; -+ -+ dev_info(dev, "Store ch: %d\n", rk3308->adc_ch); -+ -+ return count; -+} -+ -+static const struct device_attribute adc_ch_attrs[] = { -+ __ATTR(adc_ch, 0644, adc_ch_show, adc_ch_store), -+}; -+ -+static void rk3308_codec_device_release(struct device *dev) -+{ -+ /* Do nothing */ -+} -+ -+static int rk3308_codec_sysfs_init(struct platform_device *pdev, -+ struct rk3308_codec_priv *rk3308) -+{ -+ struct device *dev = &rk3308->dev; -+ int i; -+ -+ dev->release = rk3308_codec_device_release; -+ dev->parent = &pdev->dev; -+ set_dev_node(dev, dev_to_node(&pdev->dev)); -+ dev_set_name(dev, "rk3308-acodec-dev"); -+ -+ if (device_register(dev)) { -+ dev_err(&pdev->dev, -+ "Register 'rk3308-acodec-dev' failed\n"); -+ dev->parent = NULL; -+ return -ENOMEM; -+ } -+ -+ for (i = 0; i < ARRAY_SIZE(adc_ch_attrs); i++) { -+ if (device_create_file(dev, &adc_ch_attrs[i])) { -+ dev_err(&pdev->dev, -+ "Create 'rk3308-acodec-dev' attr failed\n"); -+ device_unregister(dev); -+ return -ENOMEM; -+ } -+ } -+ -+ return 0; -+} -+ -+static int rk3308_platform_probe(struct platform_device *pdev) -+{ -+ struct device_node *np = pdev->dev.of_node; -+ struct rk3308_codec_priv *rk3308; -+ struct resource *res; -+ void __iomem *base; -+ int ret = 0; -+ struct regmap *grf; -+ -+ grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); -+ if (IS_ERR(grf)) { -+ dev_err(&pdev->dev, -+ "Missing 'rockchip,grf' property\n"); -+ return PTR_ERR(grf); -+ } -+ -+ rk3308 = devm_kzalloc(&pdev->dev, sizeof(*rk3308), GFP_KERNEL); -+ if (!rk3308) -+ return -ENOMEM; -+ -+ ret = rk3308_codec_sysfs_init(pdev, rk3308); -+ if (ret < 0) { -+ dev_err(&pdev->dev, "Sysfs init failed\n"); -+ return ret; -+ } -+ -+ rk3308->plat_dev = &pdev->dev; -+ -+ rk3308->reset = devm_reset_control_get(&pdev->dev, "acodec-reset"); -+ if (IS_ERR(rk3308->reset)) { -+ ret = PTR_ERR(rk3308->reset); -+ if (ret != -ENOENT) -+ return ret; -+ -+ dev_dbg(&pdev->dev, "No reset control found\n"); -+ rk3308->reset = NULL; -+ } -+ -+ /* GPIO0_A5 control speaker on RK3308 EVB */ -+ rk3308->spk_ctl_gpio = devm_gpiod_get_optional(&pdev->dev, "spk_ctl", -+ GPIOD_OUT_HIGH); -+ if (IS_ERR(rk3308->spk_ctl_gpio)) { -+ ret = PTR_ERR(rk3308->spk_ctl_gpio); -+ dev_err(&pdev->dev, "Unable to claim gpio spk_ctl\n"); -+ return ret; -+ } -+ -+ rk3308->pclk = devm_clk_get(&pdev->dev, "acodec"); -+ if (IS_ERR(rk3308->pclk)) { -+ dev_err(&pdev->dev, "Can't get acodec pclk\n"); -+ return PTR_ERR(rk3308->pclk); -+ } -+ -+ ret = clk_prepare_enable(rk3308->pclk); -+ if (ret < 0) { -+ dev_err(&pdev->dev, "Failed to enable acodec pclk: %d\n", ret); -+ return ret; -+ } -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ base = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(base)) { -+ ret = PTR_ERR(base); -+ dev_err(&pdev->dev, "Failed to ioremap resource\n"); -+ goto failed; -+ } -+ -+ rk3308->regmap = devm_regmap_init_mmio(&pdev->dev, base, -+ &rk3308_codec_regmap_config); -+ if (IS_ERR(rk3308->regmap)) { -+ ret = PTR_ERR(rk3308->regmap); -+ dev_err(&pdev->dev, "Failed to regmap mmio\n"); -+ goto failed; -+ } -+ -+ platform_set_drvdata(pdev, rk3308); -+ -+ ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_rk3308, -+ rk3308_dai, ARRAY_SIZE(rk3308_dai)); -+ if (ret < 0) { -+ dev_err(&pdev->dev, "Failed to register codec: %d\n", ret); -+ goto failed; -+ } -+ -+ return ret; -+ -+failed: -+ clk_disable_unprepare(rk3308->pclk); -+ -+ return ret; -+} -+ -+static int rk3308_platform_remove(struct platform_device *pdev) -+{ -+ struct rk3308_codec_priv *rk3308 = -+ (struct rk3308_codec_priv *)platform_get_drvdata(pdev); -+ -+ clk_disable_unprepare(rk3308->pclk); -+ snd_soc_unregister_codec(&pdev->dev); -+ -+ return 0; -+} -+ -+static const struct of_device_id rk3308codec_of_match[] = { -+ { .compatible = "rockchip,rk3308-codec", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, rk3308codec_of_match); -+ -+static struct platform_driver rk3308_codec_driver = { -+ .driver = { -+ .name = "rk3308-acodec", -+ .of_match_table = of_match_ptr(rk3308codec_of_match), -+ }, -+ .probe = rk3308_platform_probe, -+ .remove = rk3308_platform_remove, -+}; -+module_platform_driver(rk3308_codec_driver); -+ -+MODULE_AUTHOR("Xing Zheng "); -+MODULE_DESCRIPTION("ASoC RK3308 Codec Driver"); -+MODULE_LICENSE("GPL v2"); -diff --git a/sound/soc/codecs/rk3308_codec.h b/sound/soc/codecs/rk3308_codec.h -new file mode 100644 -index 000000000000..6cfa69157785 ---- /dev/null -+++ b/sound/soc/codecs/rk3308_codec.h -@@ -0,0 +1,960 @@ -+/* -+ * rk3308_codec.h -- RK3308 ALSA Soc Audio Driver -+ * -+ * Copyright (c) 2018, Fuzhou Rockchip Electronics Co., Ltd All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope 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, see . -+ * -+ */ -+ -+#ifndef __RK3308_CODEC_H__ -+#define __RK3308_CODEC_H__ -+ -+#define ACODEC_RESET_CTL 0x00 /* REG 0x00 */ -+ -+/* ADC DIGITAL REGISTERS */ -+#define ACODEC_ADC_I2S_CTL0 0x04 /* REG 0x01 */ -+#define ACODEC_ADC_I2S_CTL1 0x08 /* REG 0x02 */ -+#define ACODEC_ADC_BIST_MODE_SEL 0x0c /* REG 0x03 */ -+/* Resevred REG 0x04 ~ 0x06 */ -+#define ACODEC_ADC_DATA_PATH 0x1c /* REG 0x07 */ -+/* Resevred REG 0x08 ~ 0x0f */ -+ -+/* REG 0x10 ~ 0x1c are used to configure AGC of Left channel (ALC1) */ -+#define ACODEC_ADC_PGA_AGC_L_CTL0 0x40 /* REG 0x10 */ -+#define ACODEC_ADC_PGA_AGC_L_CTL1 0x44 /* REG 0x11 */ -+#define ACODEC_ADC_PGA_AGC_L_CTL2 0x48 /* REG 0x12 */ -+#define ACODEC_ADC_PGA_AGC_L_CTL3 0x4c /* REG 0x13 */ -+#define ACODEC_ADC_PGA_AGC_L_CTL4 0x50 /* REG 0x14 */ -+#define ACODEC_ADC_PGA_AGC_L_LO_MAX 0x54 /* REG 0x15 */ -+#define ACODEC_ADC_PGA_AGC_L_HI_MAX 0x58 /* REG 0x16 */ -+#define ACODEC_ADC_PGA_AGC_L_LO_MIN 0x5c /* REG 0x17 */ -+#define ACODEC_ADC_PGA_AGC_L_HI_MIN 0x60 /* REG 0x18 */ -+#define ACODEC_ADC_PGA_AGC_L_CTL5 0x64 /* REG 0x19 */ -+/* Resevred REG 0x1a ~ 0x1b */ -+#define ACODEC_ADC_AGC_L_RO_GAIN 0x70 /* REG 0x1c */ -+ -+/* REG 0x20 ~ 0x2c are used to configure AGC of Right channel (ALC2) */ -+#define ACODEC_ADC_PGA_AGC_R_CTL0 0x80 /* REG 0x20 */ -+#define ACODEC_ADC_PGA_AGC_R_CTL1 0x84 /* REG 0x21 */ -+#define ACODEC_ADC_PGA_AGC_R_CTL2 0x88 /* REG 0x22 */ -+#define ACODEC_ADC_PGA_AGC_R_CTL3 0x8c /* REG 0x23 */ -+#define ACODEC_ADC_PGA_AGC_R_CTL4 0x90 /* REG 0x24 */ -+#define ACODEC_ADC_PGA_AGC_R_LO_MAX 0x94 /* REG 0x25 */ -+#define ACODEC_ADC_PGA_AGC_R_HI_MAX 0x98 /* REG 0x26 */ -+#define ACODEC_ADC_PGA_AGC_R_LO_MIN 0x9c /* REG 0x27 */ -+#define ACODEC_ADC_PGA_AGC_R_HI_MIN 0xa0 /* REG 0x28 */ -+#define ACODEC_ADC_PGA_AGC_R_CTL5 0xa4 /* REG 0x29 */ -+/* Resevred REG 0x2a ~ 0x2b */ -+#define ACODEC_ADC_AGC_R_RO_GAIN 0xb0 /* REG 0x2c */ -+ -+/* DAC DIGITAL REGISTERS */ -+#define ACODEC_DAC_I2S_CTL0 0x04 /* REG 0x01 */ -+#define ACODEC_DAC_I2S_CTL1 0x08 /* REG 0x02 */ -+#define ACODEC_DAC_BIST_MODE_SEL 0x0c /* REG 0x03 */ -+/* Resevred REG 0x04 */ -+#define ACODEC_DAC_DATA_SEL 0x14 /* REG 0x05 */ -+/* Resevred REG 0x06 ~ 0x09 */ -+#define ACODEC_DAC_DATA_HI 0x28 /* REG 0x0a */ -+#define ACODEC_DAC_DATA_LO 0x2c /* REG 0x0b */ -+/* Resevred REG 0x0c ~ 0x0f */ -+ -+/* ADC ANALOG REGISTERS */ -+#define ACODEC_ADC_ANA_MIC_CTL 0x00 /* REG 0x00 */ -+#define ACODEC_ADC_ANA_MIC_GAIN 0x04 /* REG 0x01 */ -+#define ACODEC_ADC_ANA_ALC_CTL 0x08 /* REG 0x02 */ -+#define ACODEC_ADC_ANA_ALC_GAIN1 0x0c /* REG 0x03 */ -+#define ACODEC_ADC_ANA_ALC_GAIN2 0x10 /* REG 0x04 */ -+#define ACODEC_ADC_ANA_CTL0 0x14 /* REG 0x05 */ -+#define ACODEC_ADC_ANA_CTL1 0x18 /* REG 0x06 */ -+#define ACODEC_ADC_ANA_CTL2 0x1c /* REG 0x07 */ -+#define ACODEC_ADC_ANA_CTL3 0x20 /* REG 0x08 */ -+/* Resevred REG 0x09 */ -+#define ACODEC_ADC_ANA_CTL4 0x28 /* REG 0x0a */ -+#define ACODEC_ADC_ANA_ALC_PGA 0x2c /* REG 0x0b */ -+/* Resevred REG 0x0c ~ 0x0f */ -+ -+/* DAC ANALOG REGISTERS */ -+#define ACODEC_DAC_ANA_CTL0 0x00 /* REG 0x00 */ -+#define ACODEC_DAC_ANA_POP_VOLT 0x04 /* REG 0x01 */ -+#define ACODEC_DAC_ANA_CTL1 0x08 /* REG 0x02 */ -+#define ACODEC_DAC_ANA_HPOUT 0x0c /* REG 0x03 */ -+#define ACODEC_DAC_ANA_LINEOUT 0x10 /* REG 0x04 */ -+#define ACODEC_DAC_ANA_L_HPOUT_GAIN 0x14 /* REG 0x05 */ -+#define ACODEC_DAC_ANA_R_HPOUT_GAIN 0x18 /* REG 0x06 */ -+/* Resevred REG 0x07 ~ 0x0b */ -+#define ACODEC_DAC_ANA_HPMIX_CTL0 0x30 /* REG 0x0c */ -+#define ACODEC_DAC_ANA_HPMIX_CTL1 0x34 /* REG 0x0d */ -+/* Resevred REG 0x0e ~ 0x0f */ -+ -+/* -+ * These registers are referenced by codec driver -+ */ -+ -+#define RK3308_GLB_CON ACODEC_RESET_CTL -+ -+/* ADC DIGITAL REGISTERS */ -+ -+/* -+ * The ADC chanel are 0 ~ 3, that control: -+ * -+ * CH0: left_0(ADC1) and right_0(ADC2) -+ * CH1: left_1(ADC3) and right_1(ADC4) -+ * CH2: left_2(ADC5) and right_2(ADC6) -+ * CH3: left_3(ADC7) and right_3(ADC8) -+ */ -+#define RK3308_ADC_DIG_OFFSET(ch) ((ch & 0x3) * 0xc0 + 0x0) -+ -+#define RK3308_ADC_DIG_CON01(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_I2S_CTL0) -+#define RK3308_ADC_DIG_CON02(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_I2S_CTL1) -+#define RK3308_ADC_DIG_CON03(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_BIST_MODE_SEL) -+#define RK3308_ADC_DIG_CON07(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_DATA_PATH) -+ -+#define RK3308_ALC_L_DIG_CON00(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_L_CTL0) -+#define RK3308_ALC_L_DIG_CON01(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_L_CTL1) -+#define RK3308_ALC_L_DIG_CON02(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_L_CTL2) -+#define RK3308_ALC_L_DIG_CON03(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_L_CTL3) -+#define RK3308_ALC_L_DIG_CON04(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_L_CTL4) -+#define RK3308_ALC_L_DIG_CON05(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_L_LO_MAX) -+#define RK3308_ALC_L_DIG_CON06(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_L_HI_MAX) -+#define RK3308_ALC_L_DIG_CON07(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_L_LO_MIN) -+#define RK3308_ALC_L_DIG_CON08(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_L_HI_MIN) -+#define RK3308_ALC_L_DIG_CON09(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_L_CTL5) -+#define RK3308_ALC_L_DIG_CON12(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_AGC_L_RO_GAIN) -+ -+#define RK3308_ALC_R_DIG_CON00(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_R_CTL0) -+#define RK3308_ALC_R_DIG_CON01(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_R_CTL1) -+#define RK3308_ALC_R_DIG_CON02(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_R_CTL2) -+#define RK3308_ALC_R_DIG_CON03(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_R_CTL3) -+#define RK3308_ALC_R_DIG_CON04(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_R_CTL4) -+#define RK3308_ALC_R_DIG_CON05(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_R_LO_MAX) -+#define RK3308_ALC_R_DIG_CON06(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_R_HI_MAX) -+#define RK3308_ALC_R_DIG_CON07(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_R_LO_MIN) -+#define RK3308_ALC_R_DIG_CON08(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_R_HI_MIN) -+#define RK3308_ALC_R_DIG_CON09(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_R_CTL5) -+#define RK3308_ALC_R_DIG_CON12(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_AGC_R_RO_GAIN) -+ -+/* DAC DIGITAL REGISTERS */ -+#define RK3308_DAC_DIG_OFFSET 0x300 -+ -+#define RK3308_DAC_DIG_CON01 (RK3308_DAC_DIG_OFFSET + ACODEC_DAC_I2S_CTL0) -+#define RK3308_DAC_DIG_CON02 (RK3308_DAC_DIG_OFFSET + ACODEC_DAC_I2S_CTL1) -+#define RK3308_DAC_DIG_CON03 (RK3308_DAC_DIG_OFFSET + ACODEC_DAC_BIST_MODE_SEL) -+#define RK3308_DAC_DIG_CON05 (RK3308_DAC_DIG_OFFSET + ACODEC_DAC_DATA_SEL) -+#define RK3308_DAC_DIG_CON10 (RK3308_DAC_DIG_OFFSET + ACODEC_DAC_DATA_HI) -+#define RK3308_DAC_DIG_CON11 (RK3308_DAC_DIG_OFFSET + ACODEC_DAC_DATA_LO) -+ -+/* ADC ANALOG REGISTERS */ -+/* -+ * The ADC chanel are 0 ~ 3, that control: -+ * -+ * CH0: left_0(ADC1) and right_0(ADC2) -+ * CH1: left_1(ADC3) and right_1(ADC4) -+ * CH2: left_2(ADC5) and right_2(ADC6) -+ * CH3: left_3(ADC7) and right_3(ADC8) -+ */ -+#define RK3308_ADC_ANA_OFFSET(ch) ((ch & 0x3) * 0x40 + 0x340) -+ -+#define RK3308_ADC_ANA_CON00(ch) (RK3308_ADC_ANA_OFFSET(ch) + ACODEC_ADC_ANA_MIC_CTL) -+#define RK3308_ADC_ANA_CON01(ch) (RK3308_ADC_ANA_OFFSET(ch) + ACODEC_ADC_ANA_MIC_GAIN) -+#define RK3308_ADC_ANA_CON02(ch) (RK3308_ADC_ANA_OFFSET(ch) + ACODEC_ADC_ANA_ALC_CTL) -+#define RK3308_ADC_ANA_CON03(ch) (RK3308_ADC_ANA_OFFSET(ch) + ACODEC_ADC_ANA_ALC_GAIN1) -+#define RK3308_ADC_ANA_CON04(ch) (RK3308_ADC_ANA_OFFSET(ch) + ACODEC_ADC_ANA_ALC_GAIN2) -+#define RK3308_ADC_ANA_CON05(ch) (RK3308_ADC_ANA_OFFSET(ch) + ACODEC_ADC_ANA_CTL0) -+#define RK3308_ADC_ANA_CON06(ch) (RK3308_ADC_ANA_OFFSET(ch) + ACODEC_ADC_ANA_CTL1) -+#define RK3308_ADC_ANA_CON07(ch) (RK3308_ADC_ANA_OFFSET(ch) + ACODEC_ADC_ANA_CTL2) -+#define RK3308_ADC_ANA_CON08(ch) (RK3308_ADC_ANA_OFFSET(ch) + ACODEC_ADC_ANA_CTL3) -+#define RK3308_ADC_ANA_CON10(ch) (RK3308_ADC_ANA_OFFSET(ch) + ACODEC_ADC_ANA_CTL4) -+#define RK3308_ADC_ANA_CON11(ch) (RK3308_ADC_ANA_OFFSET(ch) + ACODEC_ADC_ANA_ALC_PGA) -+ -+/* DAC ANALOG REGISTERS */ -+#define RK3308_DAC_ANA_OFFSET 0x440 -+ -+#define RK3308_DAC_ANA_CON00 (RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_CTL0) -+#define RK3308_DAC_ANA_CON01 (RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_POP_VOLT) -+#define RK3308_DAC_ANA_CON02 (RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_CTL1) -+#define RK3308_DAC_ANA_CON03 (RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_HPOUT) -+#define RK3308_DAC_ANA_CON04 (RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_LINEOUT) -+#define RK3308_DAC_ANA_CON05 (RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_L_HPOUT_GAIN) -+#define RK3308_DAC_ANA_CON06 (RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_R_HPOUT_GAIN) -+#define RK3308_DAC_ANA_CON12 (RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_HPMIX_CTL0) -+#define RK3308_DAC_ANA_CON13 (RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_HPMIX_CTL1) -+ -+/* -+ * These are the bits for registers -+ */ -+ -+/* RK3308_GLB_CON - REG: 0x0000 */ -+#define RK3308_ADC_BIST_WORK (1 << 7) -+#define RK3308_ADC_BIST_RESET (0 << 7) -+#define RK3308_DAC_BIST_WORK (1 << 6) -+#define RK3308_DAC_BIST_RESET (0 << 6) -+#define RK3308_CODEC_RST_MSK (0x7 << 0) -+#define RK3308_ADC_DIG_WORK (1 << 2) -+#define RK3308_ADC_DIG_RESET (0 << 2) -+#define RK3308_DAC_DIG_WORK (1 << 1) -+#define RK3308_DAC_DIG_RESET (0 << 1) -+#define RK3308_SYS_WORK (1 << 0) -+#define RK3308_SYS_RESET (0 << 0) -+ -+/* RK3308_ADC_DIG_CON01 - REG: 0x0004 */ -+#define RK3308_ADC_I2S_LRC_POL_MSK (1 << 0) -+#define RK3308_ADC_I2S_LRC_POL_REVERSAL (1 << 0) -+#define RK3308_ADC_I2S_LRC_POL_NORMAL (0 << 0) -+#define RK3308_ADC_I2S_VALID_LEN_SFT 5 -+#define RK3308_ADC_I2S_VALID_LEN_MSK (0x3 << RK3308_ADC_I2S_VALID_LEN_SFT) -+#define RK3308_ADC_I2S_VALID_LEN_32BITS (0x3 << RK3308_ADC_I2S_VALID_LEN_SFT) -+#define RK3308_ADC_I2S_VALID_LEN_24BITS (0x2 << RK3308_ADC_I2S_VALID_LEN_SFT) -+#define RK3308_ADC_I2S_VALID_LEN_20BITS (0x1 << RK3308_ADC_I2S_VALID_LEN_SFT) -+#define RK3308_ADC_I2S_VALID_LEN_16BITS (0x0 << RK3308_ADC_I2S_VALID_LEN_SFT) -+#define RK3308_ADC_I2S_MODE_SFT 3 -+#define RK3308_ADC_I2S_MODE_MSK (0x3 << RK3308_ADC_I2S_MODE_SFT) -+#define RK3308_ADC_I2S_MODE_PCM (0x3 << RK3308_ADC_I2S_MODE_SFT) -+#define RK3308_ADC_I2S_MODE_I2S (0x2 << RK3308_ADC_I2S_MODE_SFT) -+#define RK3308_ADC_I2S_MODE_LJ (0x1 << RK3308_ADC_I2S_MODE_SFT) -+#define RK3308_ADC_I2S_MODE_RJ (0x0 << RK3308_ADC_I2S_MODE_SFT) -+#define RK3308_ADC_I2S_LR_MSK (1 << 1) -+#define RK3308_ADC_I2S_LR_SWAP (1 << 1) -+#define RK3308_ADC_I2S_LR_NORMAL (0 << 1) -+#define RK3308_ADC_I2S_TYPE_MSK (1 << 0) -+#define RK3308_ADC_I2S_MONO (1 << 0) -+#define RK3308_ADC_I2S_STEREO (0 << 0) -+ -+/* RK3308_ADC_DIG_CON02 - REG: 0x0008 */ -+#define RK3308_ADC_IO_MODE_MSK (1 << 5) -+#define RK3308_ADC_IO_MODE_MASTER (1 << 5) -+#define RK3308_ADC_IO_MODE_SLAVE (0 << 5) -+#define RK3308_ADC_MODE_MSK (1 << 4) -+#define RK3308_ADC_MODE_MASTER (1 << 4) -+#define RK3308_ADC_MODE_SLAVE (0 << 4) -+#define RK3308_ADC_I2S_FRAME_LEN_SFT 2 -+#define RK3308_ADC_I2S_FRAME_LEN_MSK (0x3 << RK3308_ADC_I2S_FRAME_LEN_SFT) -+#define RK3308_ADC_I2S_FRAME_32BITS (0x3 << RK3308_ADC_I2S_FRAME_LEN_SFT) -+#define RK3308_ADC_I2S_FRAME_24BITS (0x2 << RK3308_ADC_I2S_FRAME_LEN_SFT) -+#define RK3308_ADC_I2S_FRAME_20BITS (0x1 << RK3308_ADC_I2S_FRAME_LEN_SFT) -+#define RK3308_ADC_I2S_FRAME_16BITS (0x0 << RK3308_ADC_I2S_FRAME_LEN_SFT) -+#define RK3308_ADC_I2S_MSK (0x1 << 1) -+#define RK3308_ADC_I2S_WORK (0x1 << 1) -+#define RK3308_ADC_I2S_RESET (0x0 << 1) -+#define RK3308_ADC_I2S_BIT_CLK_POL_MSK (0x1 << 0) -+#define RK3308_ADC_I2S_BIT_CLK_POL_REVERSAL (0x1 << 0) -+#define RK3308_ADC_I2S_BIT_CLK_POL_NORMAL (0x0 << 0) -+ -+/* RK3308_ADC_DIG_CON03 - REG: 0x000c */ -+#define RK3308_ADC_L_CH_BIST_SFT 2 -+#define RK3308_ADC_L_CH_BIST_MSK (0x3 << RK3308_ADC_L_CH_BIST_SFT) -+#define RK3308_ADC_L_CH_BIST_LEFT (0x3 << RK3308_ADC_L_CH_BIST_SFT) /* normal mode */ -+#define RK3308_ADC_L_CH_BIST_SINE (0x2 << RK3308_ADC_L_CH_BIST_SFT) -+#define RK3308_ADC_L_CH_BIST_CUBE (0x1 << RK3308_ADC_L_CH_BIST_SFT) -+#define RK3308_ADC_L_CH_BIST_RIGHT (0x0 << RK3308_ADC_L_CH_BIST_SFT) /* normal mode */ -+#define RK3308_ADC_R_CH_BIST_SFT 0 -+#define RK3308_ADC_R_CH_BIST_MSK (0x3 << RK3308_ADC_R_CH_BIST_SFT) -+#define RK3308_ADC_R_CH_BIST_LEFT (0x3 << RK3308_ADC_R_CH_BIST_SFT) /* normal mode */ -+#define RK3308_ADC_R_CH_BIST_SINE (0x2 << RK3308_ADC_R_CH_BIST_SFT) -+#define RK3308_ADC_R_CH_BIST_CUBE (0x1 << RK3308_ADC_R_CH_BIST_SFT) -+#define RK3308_ADC_R_CH_BIST_RIGHT (0x0 << RK3308_ADC_R_CH_BIST_SFT) /* normal mode */ -+ -+/* RK3308_ADC_DIG_CON07 - REG: 0x001c */ -+#define RK3308_ADCL_DATA_SFT 4 -+#define RK3308_ADCL_DATA(x) (x << RK3308_ADCL_DATA_SFT) -+#define RK3308_ADCR_DATA_SFT 2 -+#define RK3308_ADCR_DATA(x) (x << RK3308_ADCR_DATA_SFT) -+#define RK3308_ADCL_DATA_SEL_ADCL (0x1 << 1) -+#define RK3308_ADCL_DATA_SEL_NORMAL (0x0 << 1) -+#define RK3308_ADCR_DATA_SEL_ADCR (0x1 << 0) -+#define RK3308_ADCR_DATA_SEL_NORMAL (0x0 << 0) -+ -+/* -+ * RK3308_ALC_L_DIG_CON00 - REG: 0x0040 + ch * 0xc0 -+ * RK3308_ALC_R_DIG_CON00 - REG: 0x0080 + ch * 0xc0 -+ */ -+#define RK3308_GAIN_ATTACK_JACK (0x1 << 6) -+#define RK3308_GAIN_ATTACK_NORMAL (0x0 << 6) -+#define RK3308_CTRL_GEN_SFT 4 -+#define RK3308_CTRL_GEN_MSK (0x3 << RK3308_ALC_CTRL_GEN_SFT) -+#define RK3308_CTRL_GEN_JACK3 (0x3 << RK3308_ALC_CTRL_GEN_SFT) -+#define RK3308_CTRL_GEN_JACK2 (0x2 << RK3308_ALC_CTRL_GEN_SFT) -+#define RK3308_CTRL_GEN_JACK1 (0x1 << RK3308_ALC_CTRL_GEN_SFT) -+#define RK3308_CTRL_GEN_NORMAL (0x0 << RK3308_ALC_CTRL_GEN_SFT) -+#define RK3308_AGC_HOLD_TIME_SFT 0 -+#define RK3308_AGC_HOLD_TIME_MSK (0xf << RK3308_AGC_HOLD_TIME_SFT) -+#define RK3308_AGC_HOLD_TIME_1S (0xa << RK3308_AGC_HOLD_TIME_SFT) -+#define RK3308_AGC_HOLD_TIME_512MS (0x9 << RK3308_AGC_HOLD_TIME_SFT) -+#define RK3308_AGC_HOLD_TIME_256MS (0x8 << RK3308_AGC_HOLD_TIME_SFT) -+#define RK3308_AGC_HOLD_TIME_128MS (0x7 << RK3308_AGC_HOLD_TIME_SFT) -+#define RK3308_AGC_HOLD_TIME_64MS (0x6 << RK3308_AGC_HOLD_TIME_SFT) -+#define RK3308_AGC_HOLD_TIME_32MS (0x5 << RK3308_AGC_HOLD_TIME_SFT) -+#define RK3308_AGC_HOLD_TIME_16MS (0x4 << RK3308_AGC_HOLD_TIME_SFT) -+#define RK3308_AGC_HOLD_TIME_8MS (0x3 << RK3308_AGC_HOLD_TIME_SFT) -+#define RK3308_AGC_HOLD_TIME_4MS (0x2 << RK3308_AGC_HOLD_TIME_SFT) -+#define RK3308_AGC_HOLD_TIME_2MS (0x1 << RK3308_AGC_HOLD_TIME_SFT) -+#define RK3308_AGC_HOLD_TIME_0MS (0x0 << RK3308_AGC_HOLD_TIME_SFT) -+ -+/* -+ * RK3308_ALC_L_DIG_CON01 - REG: 0x0044 + ch * 0xc0 -+ * RK3308_ALC_R_DIG_CON01 - REG: 0x0084 + ch * 0xc0 -+ */ -+#define RK3308_AGC_DECAY_TIME_SFT 4 -+/* Normal mode (reg_agc_mode = 0) */ -+#define RK3308_AGC_DECAY_NORMAL_MSK (0xf << RK3308_AGC_DECAY_TIME_SFT) -+#define RK3308_AGC_DECAY_NORMAL_512MS (0xa << RK3308_AGC_DECAY_TIME_SFT) -+#define RK3308_AGC_DECAY_NORMAL_256MS (0x9 << RK3308_AGC_DECAY_TIME_SFT) -+#define RK3308_AGC_DECAY_NORMAL_128MS (0x8 << RK3308_AGC_DECAY_TIME_SFT) -+#define RK3308_AGC_DECAY_NORMAL_64MS (0x7 << RK3308_AGC_DECAY_TIME_SFT) -+#define RK3308_AGC_DECAY_NORMAL_32MS (0x6 << RK3308_AGC_DECAY_TIME_SFT) -+#define RK3308_AGC_DECAY_NORMAL_16MS (0x5 << RK3308_AGC_DECAY_TIME_SFT) -+#define RK3308_AGC_DECAY_NORMAL_8MS (0x4 << RK3308_AGC_DECAY_TIME_SFT) -+#define RK3308_AGC_DECAY_NORMAL_4MS (0x3 << RK3308_AGC_DECAY_TIME_SFT) -+#define RK3308_AGC_DECAY_NORMAL_2MS (0x2 << RK3308_AGC_DECAY_TIME_SFT) -+#define RK3308_AGC_DECAY_NORMAL_1MS (0x1 << RK3308_AGC_DECAY_TIME_SFT) -+#define RK3308_AGC_DECAY_NORMAL_0MS (0x0 << RK3308_AGC_DECAY_TIME_SFT) -+/* Limiter mode (reg_agc_mode = 1) */ -+#define RK3308_AGC_DECAY_LIMITER_MSK (0xf << RK3308_AGC_DECAY_TIME_SFT) -+#define RK3308_AGC_DECAY_LIMITER_128MS (0xa << RK3308_AGC_DECAY_TIME_SFT) -+#define RK3308_AGC_DECAY_LIMITER_64MS (0x9 << RK3308_AGC_DECAY_TIME_SFT) -+#define RK3308_AGC_DECAY_LIMITER_32MS (0x8 << RK3308_AGC_DECAY_TIME_SFT) -+#define RK3308_AGC_DECAY_LIMITER_16MS (0x7 << RK3308_AGC_DECAY_TIME_SFT) -+#define RK3308_AGC_DECAY_LIMITER_8MS (0x6 << RK3308_AGC_DECAY_TIME_SFT) -+#define RK3308_AGC_DECAY_LIMITER_4MS (0x5 << RK3308_AGC_DECAY_TIME_SFT) -+#define RK3308_AGC_DECAY_LIMITER_2MS (0x4 << RK3308_AGC_DECAY_TIME_SFT) -+#define RK3308_AGC_DECAY_LIMITER_1MS (0x3 << RK3308_AGC_DECAY_TIME_SFT) -+#define RK3308_AGC_DECAY_LIMITER_500US (0x2 << RK3308_AGC_DECAY_TIME_SFT) -+#define RK3308_AGC_DECAY_LIMITER_250US (0x1 << RK3308_AGC_DECAY_TIME_SFT) -+#define RK3308_AGC_DECAY_LIMITER_125US (0x0 << RK3308_AGC_DECAY_TIME_SFT) -+ -+#define RK3308_AGC_ATTACK_TIME_SFT 0 -+/* Normal mode (reg_agc_mode = 0) */ -+#define RK3308_AGC_ATTACK_NORMAL_MSK (0xf << RK3308_AGC_ATTACK_TIME_SFT) -+#define RK3308_AGC_ATTACK_NORMAL_128MS (0xa << RK3308_AGC_ATTACK_TIME_SFT) -+#define RK3308_AGC_ATTACK_NORMAL_64MS (0x9 << RK3308_AGC_ATTACK_TIME_SFT) -+#define RK3308_AGC_ATTACK_NORMAL_32MS (0x8 << RK3308_AGC_ATTACK_TIME_SFT) -+#define RK3308_AGC_ATTACK_NORMAL_16MS (0x7 << RK3308_AGC_ATTACK_TIME_SFT) -+#define RK3308_AGC_ATTACK_NORMAL_8MS (0x6 << RK3308_AGC_ATTACK_TIME_SFT) -+#define RK3308_AGC_ATTACK_NORMAL_4MS (0x5 << RK3308_AGC_ATTACK_TIME_SFT) -+#define RK3308_AGC_ATTACK_NORMAL_2MS (0x4 << RK3308_AGC_ATTACK_TIME_SFT) -+#define RK3308_AGC_ATTACK_NORMAL_1MS (0x3 << RK3308_AGC_ATTACK_TIME_SFT) -+#define RK3308_AGC_ATTACK_NORMAL_500US (0x2 << RK3308_AGC_ATTACK_TIME_SFT) -+#define RK3308_AGC_ATTACK_NORMAL_250US (0x1 << RK3308_AGC_ATTACK_TIME_SFT) -+#define RK3308_AGC_ATTACK_NORMAL_125US (0x0 << RK3308_AGC_ATTACK_TIME_SFT) -+/* Limiter mode (reg_agc_mode = 1) */ -+#define RK3308_AGC_ATTACK_LIMITER_MSK (0xf << RK3308_AGC_ATTACK_TIME_SFT) -+#define RK3308_AGC_ATTACK_LIMITER_32MS (0xa << RK3308_AGC_ATTACK_TIME_SFT) -+#define RK3308_AGC_ATTACK_LIMITER_16MS (0x9 << RK3308_AGC_ATTACK_TIME_SFT) -+#define RK3308_AGC_ATTACK_LIMITER_8MS (0x8 << RK3308_AGC_ATTACK_TIME_SFT) -+#define RK3308_AGC_ATTACK_LIMITER_4MS (0x7 << RK3308_AGC_ATTACK_TIME_SFT) -+#define RK3308_AGC_ATTACK_LIMITER_2MS (0x6 << RK3308_AGC_ATTACK_TIME_SFT) -+#define RK3308_AGC_ATTACK_LIMITER_1MS (0x5 << RK3308_AGC_ATTACK_TIME_SFT) -+#define RK3308_AGC_ATTACK_LIMITER_500US (0x4 << RK3308_AGC_ATTACK_TIME_SFT) -+#define RK3308_AGC_ATTACK_LIMITER_250US (0x3 << RK3308_AGC_ATTACK_TIME_SFT) -+#define RK3308_AGC_ATTACK_LIMITER_125US (0x2 << RK3308_AGC_ATTACK_TIME_SFT) -+#define RK3308_AGC_ATTACK_LIMITER_64US (0x1 << RK3308_AGC_ATTACK_TIME_SFT) -+#define RK3308_AGC_ATTACK_LIMITER_32US (0x0 << RK3308_AGC_ATTACK_TIME_SFT) -+ -+/* -+ * RK3308_ALC_L_DIG_CON02 - REG: 0x0048 + ch * 0xc0 -+ * RK3308_ALC_R_DIG_CON02 - REG: 0x0088 + ch * 0xc0 -+ */ -+#define RK3308_AGC_MODE_LIMITER (0x1 << 7) -+#define RK3308_AGC_MODE_NORMAL (0x0 << 7) -+#define RK3308_AGC_ZERO_CRO_EN (0x1 << 6) -+#define RK3308_AGC_ZERO_CRO_DIS (0x0 << 6) -+#define RK3308_AGC_AMP_RECOVER_GAIN (0x1 << 5) -+#define RK3308_AGC_AMP_RECOVER_LVOL (0x0 << 5) -+#define RK3308_AGC_FAST_DEC_EN (0x1 << 4) -+#define RK3308_AGC_FAST_DEC_DIS (0x0 << 4) -+#define RK3308_AGC_NOISE_GATE_EN (0x1 << 3) -+#define RK3308_AGC_NOISE_GATE_DIS (0x0 << 3) -+#define RK3308_AGC_NOISE_GATE_THRESH_SFT 0 -+#define RK3308_AGC_NOISE_GATE_THRESH_MSK (0x7 << RK3308_AGC_NOISE_GATE_THRESH_SFT) -+#define RK3308_AGC_NOISE_GATE_THRESH_N81DB (0x7 << RK3308_AGC_NOISE_GATE_THRESH_SFT) -+#define RK3308_AGC_NOISE_GATE_THRESH_N75DB (0x6 << RK3308_AGC_NOISE_GATE_THRESH_SFT) -+#define RK3308_AGC_NOISE_GATE_THRESH_N69DB (0x5 << RK3308_AGC_NOISE_GATE_THRESH_SFT) -+#define RK3308_AGC_NOISE_GATE_THRESH_N63DB (0x4 << RK3308_AGC_NOISE_GATE_THRESH_SFT) -+#define RK3308_AGC_NOISE_GATE_THRESH_N57DB (0x3 << RK3308_AGC_NOISE_GATE_THRESH_SFT) -+#define RK3308_AGC_NOISE_GATE_THRESH_N51DB (0x2 << RK3308_AGC_NOISE_GATE_THRESH_SFT) -+#define RK3308_AGC_NOISE_GATE_THRESH_N45DB (0x1 << RK3308_AGC_NOISE_GATE_THRESH_SFT) -+#define RK3308_AGC_NOISE_GATE_THRESH_N39DB (0x0 << RK3308_AGC_NOISE_GATE_THRESH_SFT) -+ -+/* -+ * RK3308_ALC_L_DIG_CON03 - REG: 0x004c + ch * 0xc0 -+ * RK3308_ALC_R_DIG_CON03 - REG: 0x008c + ch * 0xc0 -+ */ -+#define RK3308_AGC_PGA_ZERO_CRO_EN (0x1 << 5) -+#define RK3308_AGC_PGA_ZERO_CRO_DIS (0x0 << 5) -+#define RK3308_AGC_PGA_GAIN_SFT 0 -+#define RK3308_AGC_PGA_GAIN_MSK (0x1f << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_PDB_28_5 (0x1f << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_PDB_27 (0x1e << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_PDB_25_5 (0x1d << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_PDB_24 (0x1c << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_PDB_22_5 (0x1b << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_PDB_21 (0x1a << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_PDB_19_5 (0x19 << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_PDB_18 (0x18 << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_PDB_16_5 (0x17 << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_PDB_15 (0x16 << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_PDB_13_5 (0x15 << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_PDB_12 (0x14 << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_PDB_10_5 (0x13 << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_PDB_9 (0x12 << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_PDB_7_5 (0x11 << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_PDB_6 (0x10 << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_PDB_4_5 (0x0f << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_PDB_3 (0x0e << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_PDB_1_5 (0x0d << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_0DB (0x0c << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_NDB_1_5 (0x0b << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_NDB_3 (0x0a << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_NDB_4_5 (0x09 << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_NDB_6 (0x08 << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_NDB_7_5 (0x07 << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_NDB_9 (0x06 << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_NDB_10_5 (0x05 << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_NDB_12 (0x04 << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_NDB_13_5 (0x03 << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_NDB_15 (0x02 << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_NDB_16_5 (0x01 << RK3308_AGC_PGA_GAIN_SFT) -+#define RK3308_AGC_PGA_GAIN_NDB_18 (0x00 << RK3308_AGC_PGA_GAIN_SFT) -+ -+/* -+ * RK3308_ALC_L_DIG_CON04 - REG: 0x0050 + ch * 0xc0 -+ * RK3308_ALC_R_DIG_CON04 - REG: 0x0090 + ch * 0xc0 -+ */ -+#define RK3308_AGC_SLOW_CLK_EN (0x1 << 3) -+#define RK3308_AGC_SLOW_CLK_DIS (0x0 << 3) -+#define RK3308_AGC_APPROX_RATE_SFT 0 -+#define RK3308_AGC_APPROX_RATE_MSK (0x7 << RK3308_AGC_APPROX_RATE_SFT) -+#define RK3308_AGC_APPROX_RATE_8K (0x7 << RK3308_AGC_APPROX_RATE_SFT) -+#define RK3308_AGC_APPROX_RATE_12K (0x6 << RK3308_AGC_APPROX_RATE_SFT) -+#define RK3308_AGC_APPROX_RATE_16K (0x5 << RK3308_AGC_APPROX_RATE_SFT) -+#define RK3308_AGC_APPROX_RATE_24K (0x4 << RK3308_AGC_APPROX_RATE_SFT) -+#define RK3308_AGC_APPROX_RATE_32K (0x3 << RK3308_AGC_APPROX_RATE_SFT) -+#define RK3308_AGC_APPROX_RATE_44_1K (0x2 << RK3308_AGC_APPROX_RATE_SFT) -+#define RK3308_AGC_APPROX_RATE_48K (0x1 << RK3308_AGC_APPROX_RATE_SFT) -+#define RK3308_AGC_APPROX_RATE_96K (0x0 << RK3308_AGC_APPROX_RATE_SFT) -+ -+/* -+ * RK3308_ALC_L_DIG_CON05 - REG: 0x0054 + ch * 0xc0 -+ * RK3308_ALC_R_DIG_CON05 - REG: 0x0094 + ch * 0xc0 -+ */ -+#define RK3308_AGC_LO_8BITS_AGC_MAX_MSK 0xff -+ -+/* -+ * RK3308_ALC_L_DIG_CON06 - REG: 0x0058 + ch * 0xc0 -+ * RK3308_ALC_R_DIG_CON06 - REG: 0x0098 + ch * 0xc0 -+ */ -+#define RK3308_AGC_HI_8BITS_AGC_MAX_MSK 0xff -+ -+/* -+ * RK3308_ALC_L_DIG_CON07 - REG: 0x005c + ch * 0xc0 -+ * RK3308_ALC_R_DIG_CON07 - REG: 0x009c + ch * 0xc0 -+ */ -+#define RK3308_AGC_LO_8BITS_AGC_MIN_MSK 0xff -+ -+/* -+ * RK3308_ALC_L_DIG_CON08 - REG: 0x0060 + ch * 0xc0 -+ * RK3308_ALC_R_DIG_CON08 - REG: 0x00a0 + ch * 0xc0 -+ */ -+#define RK3308_AGC_HI_8BITS_AGC_MIN_MSK 0xff -+ -+/* -+ * RK3308_ALC_L_DIG_CON09 - REG: 0x0064 + ch * 0xc0 -+ * RK3308_ALC_R_DIG_CON09 - REG: 0x00a4 + ch * 0xc0 -+ */ -+#define RK3308_AGC_FUNC_SEL_MSK (0x1 << 6) -+#define RK3308_AGC_FUNC_SEL_EN (0x1 << 6) -+#define RK3308_AGC_FUNC_SEL_DIS (0x0 << 6) -+#define RK3308_AGC_MAX_GAIN_PGA_SFT 3 -+#define RK3308_AGC_MAX_GAIN_PGA_MSK (0x7 << RK3308_AGC_MAX_GAIN_PGA_SFT) -+#define RK3308_AGC_MAX_GAIN_PGA_PDB_28_5 (0x7 << RK3308_AGC_MAX_GAIN_PGA_SFT) -+#define RK3308_AGC_MAX_GAIN_PGA_PDB_22_5 (0x6 << RK3308_AGC_MAX_GAIN_PGA_SFT) -+#define RK3308_AGC_MAX_GAIN_PGA_PDB_16_5 (0x5 << RK3308_AGC_MAX_GAIN_PGA_SFT) -+#define RK3308_AGC_MAX_GAIN_PGA_PDB_10_5 (0x4 << RK3308_AGC_MAX_GAIN_PGA_SFT) -+#define RK3308_AGC_MAX_GAIN_PGA_PDB_4_5 (0x3 << RK3308_AGC_MAX_GAIN_PGA_SFT) -+#define RK3308_AGC_MAX_GAIN_PGA_NDB_1_5 (0x2 << RK3308_AGC_MAX_GAIN_PGA_SFT) -+#define RK3308_AGC_MAX_GAIN_PGA_NDB_7_5 (0x1 << RK3308_AGC_MAX_GAIN_PGA_SFT) -+#define RK3308_AGC_MAX_GAIN_PGA_NDB_13_5 (0x0 << RK3308_AGC_MAX_GAIN_PGA_SFT) -+#define RK3308_AGC_MIN_GAIN_PGA_SFT 0 -+#define RK3308_AGC_MIN_GAIN_PGA_MSK (0x7 << RK3308_AGC_MIN_GAIN_PGA_SFT) -+#define RK3308_AGC_MIN_GAIN_PGA_PDB_24 (0x7 << RK3308_AGC_MIN_GAIN_PGA_SFT) -+#define RK3308_AGC_MIN_GAIN_PGA_PDB_18 (0x6 << RK3308_AGC_MIN_GAIN_PGA_SFT) -+#define RK3308_AGC_MIN_GAIN_PGA_PDB_12 (0x5 << RK3308_AGC_MIN_GAIN_PGA_SFT) -+#define RK3308_AGC_MIN_GAIN_PGA_PDB_6 (0x4 << RK3308_AGC_MIN_GAIN_PGA_SFT) -+#define RK3308_AGC_MIN_GAIN_PGA_0DB (0x3 << RK3308_AGC_MIN_GAIN_PGA_SFT) -+#define RK3308_AGC_MIN_GAIN_PGA_NDB_6 (0x2 << RK3308_AGC_MIN_GAIN_PGA_SFT) -+#define RK3308_AGC_MIN_GAIN_PGA_NDB_12 (0x1 << RK3308_AGC_MIN_GAIN_PGA_SFT) -+#define RK3308_AGC_MIN_GAIN_PGA_NDB_18 (0x0 << RK3308_AGC_MIN_GAIN_PGA_SFT) -+ -+/* -+ * RK3308_ALC_L_DIG_CON12 - REG: 0x0068 + ch * 0xc0 -+ * RK3308_ALC_R_DIG_CON12 - REG: 0x00a8 + ch * 0xc0 -+ */ -+#define RK3308_AGC_GAIN_MSK 0x1f -+ -+/* RK3308_DAC_DIG_CON01 - REG: 0x0304 */ -+#define RK3308_DAC_I2S_LRC_POL_MSK (0x1 << 7) -+#define RK3308_DAC_I2S_LRC_POL_REVERSAL (0x1 << 7) -+#define RK3308_DAC_I2S_LRC_POL_NORMAL (0x0 << 7) -+#define RK3308_DAC_I2S_VALID_LEN_SFT 5 -+#define RK3308_DAC_I2S_VALID_LEN_MSK (0x3 << RK3308_DAC_I2S_VALID_LEN_SFT) -+#define RK3308_DAC_I2S_VALID_LEN_32BITS (0x3 << RK3308_DAC_I2S_VALID_LEN_SFT) -+#define RK3308_DAC_I2S_VALID_LEN_24BITS (0x2 << RK3308_DAC_I2S_VALID_LEN_SFT) -+#define RK3308_DAC_I2S_VALID_LEN_20BITS (0x1 << RK3308_DAC_I2S_VALID_LEN_SFT) -+#define RK3308_DAC_I2S_VALID_LEN_16BITS (0x0 << RK3308_DAC_I2S_VALID_LEN_SFT) -+#define RK3308_DAC_I2S_MODE_SFT 3 -+#define RK3308_DAC_I2S_MODE_MSK (0x3 << RK3308_DAC_I2S_MODE_SFT) -+#define RK3308_DAC_I2S_MODE_PCM (0x3 << RK3308_DAC_I2S_MODE_SFT) -+#define RK3308_DAC_I2S_MODE_I2S (0x2 << RK3308_DAC_I2S_MODE_SFT) -+#define RK3308_DAC_I2S_MODE_LJ (0x1 << RK3308_DAC_I2S_MODE_SFT) -+#define RK3308_DAC_I2S_MODE_RJ (0x0 << RK3308_DAC_I2S_MODE_SFT) -+#define RK3308_DAC_I2S_LR_MSK (0x1 << 2) -+#define RK3308_DAC_I2S_LR_SWAP (0x1 << 2) -+#define RK3308_DAC_I2S_LR_NORMAL (0x0 << 2) -+ -+/* RK3308_DAC_DIG_CON02 - REG: 0x0308 */ -+#define RK3308_DAC_IO_MODE_MSK (0x1 << 5) -+#define RK3308_DAC_IO_MODE_MASTER (0x1 << 5) -+#define RK3308_DAC_IO_MODE_SLAVE (0x0 << 5) -+#define RK3308_DAC_MODE_MSK (0x1 << 4) -+#define RK3308_DAC_MODE_MASTER (0x1 << 4) -+#define RK3308_DAC_MODE_SLAVE (0x0 << 4) -+#define RK3308_DAC_I2S_FRAME_LEN_SFT 2 -+#define RK3308_DAC_I2S_FRAME_LEN_MSK (0x3 << RK3308_DAC_I2S_FRAME_LEN_SFT) -+#define RK3308_DAC_I2S_FRAME_32BITS (0x3 << RK3308_DAC_I2S_FRAME_LEN_SFT) -+#define RK3308_DAC_I2S_FRAME_24BITS (0x2 << RK3308_DAC_I2S_FRAME_LEN_SFT) -+#define RK3308_DAC_I2S_FRAME_20BITS (0x1 << RK3308_DAC_I2S_FRAME_LEN_SFT) -+#define RK3308_DAC_I2S_FRAME_16BITS (0x0 << RK3308_DAC_I2S_FRAME_LEN_SFT) -+#define RK3308_DAC_I2S_MSK (0x1 << 1) -+#define RK3308_DAC_I2S_WORK (0x1 << 1) -+#define RK3308_DAC_I2S_RESET (0x0 << 1) -+#define RK3308_DAC_I2S_BIT_CLK_POL_MSK (0x1 << 0) -+#define RK3308_DAC_I2S_BIT_CLK_POL_REVERSAL (0x1 << 0) -+#define RK3308_DAC_I2S_BIT_CLK_POL_NORMAL (0x0 << 0) -+ -+/* RK3308_DAC_DIG_CON03 - REG: 0x030C */ -+#define RK3308_DAC_L_CH_BIST_SFT 2 -+#define RK3308_DAC_L_CH_BIST_MSK (0x3 << RK3308_DAC_L_CH_BIST_SFT) -+#define RK3308_DAC_L_CH_BIST_LEFT (0x3 << RK3308_DAC_L_CH_BIST_SFT) /* normal mode */ -+#define RK3308_DAC_L_CH_BIST_CUBE (0x2 << RK3308_DAC_L_CH_BIST_SFT) -+#define RK3308_DAC_L_CH_BIST_SINE (0x1 << RK3308_DAC_L_CH_BIST_SFT) -+#define RK3308_DAC_L_CH_BIST_RIGHT (0x0 << RK3308_DAC_L_CH_BIST_SFT) /* normal mode */ -+#define RK3308_DAC_R_CH_BIST_SFT 0 -+#define RK3308_DAC_R_CH_BIST_MSK (0x3 << RK3308_DAC_R_CH_BIST_SFT) -+#define RK3308_DAC_R_CH_BIST_LEFT (0x3 << RK3308_DAC_R_CH_BIST_SFT) /* normal mode */ -+#define RK3308_DAC_R_CH_BIST_CUBE (0x2 << RK3308_DAC_R_CH_BIST_SFT) -+#define RK3308_DAC_R_CH_BIST_SINE (0x1 << RK3308_DAC_R_CH_BIST_SFT) -+#define RK3308_DAC_R_CH_BIST_RIGHT (0x0 << RK3308_DAC_R_CH_BIST_SFT) /* normal mode */ -+ -+/* RK3308_DAC_DIG_CON05 - REG: 0x0314 */ -+#define RK3308_DAC_L_REG_CTL_INDATA (0x1 << 2) -+#define RK3308_DAC_L_NORMAL_DATA (0x0 << 2) -+#define RK3308_DAC_R_REG_CTL_INDATA (0x1 << 1) -+#define RK3308_DAC_R_NORMAL_DATA (0x0 << 1) -+ -+/* RK3308_DAC_DIG_CON10 - REG: 0x0328 */ -+#define RK3308_DAC_DATA_HI4(x) (x & 0xf) /* Need to RK3308_DAC_x_REG_CTL_INDATA */ -+ -+/* RK3308_DAC_DIG_CON11 - REG: 0x032c */ -+#define RK3308_DAC_DATA_LO8(x) (x & 0xff) /* Need to RK3308_DAC_x_REG_CTL_INDATA */ -+ -+/* RK3308_ADC_ANA_CON00 - REG: 0x0340 */ -+#define RK3308_ADC_CH1_CH2_MIC_ALL_MSK (0xff << 0) -+#define RK3308_ADC_CH1_CH2_MIC_ALL 0xff -+#define RK3308_ADC_CH2_MIC_UNMUTE (0x1 << 7) -+#define RK3308_ADC_CH2_MIC_MUTE (0x0 << 7) -+#define RK3308_ADC_CH2_MIC_WORK (0x1 << 6) -+#define RK3308_ADC_CH2_MIC_INIT (0x0 << 6) -+#define RK3308_ADC_CH2_MIC_EN (0x1 << 5) -+#define RK3308_ADC_CH2_MIC_DIS (0x0 << 5) -+#define RK3308_ADC_CH2_BUF_REF_EN (0x1 << 4) -+#define RK3308_ADC_CH2_BUF_REF_DIS (0x0 << 4) -+#define RK3308_ADC_CH1_MIC_UNMUTE (0x1 << 3) -+#define RK3308_ADC_CH1_MIC_MUTE (0x0 << 3) -+#define RK3308_ADC_CH1_MIC_WORK (0x1 << 2) -+#define RK3308_ADC_CH1_MIC_INIT (0x0 << 2) -+#define RK3308_ADC_CH1_MIC_EN (0x1 << 1) -+#define RK3308_ADC_CH1_MIC_DIS (0x0 << 1) -+#define RK3308_ADC_CH1_BUF_REF_EN (0x1 << 0) -+#define RK3308_ADC_CH1_BUF_REF_DIS (0x0 << 0) -+ -+/* RK3308_ADC_ANA_CON01 - REG: 0x0344 */ -+#define RK3308_ADC_CH2_MIC_GAIN_SFT 4 -+#define RK3308_ADC_CH2_MIC_GAIN_MSK (0x3 << RK3308_ADC_CH2_MIC_GAIN_SFT) -+#define RK3308_ADC_CH2_MIC_GAIN_30DB (0x3 << RK3308_ADC_CH2_MIC_GAIN_SFT) -+#define RK3308_ADC_CH2_MIC_GAIN_20DB (0x2 << RK3308_ADC_CH2_MIC_GAIN_SFT) -+#define RK3308_ADC_CH2_MIC_GAIN_6DB (0x1 << RK3308_ADC_CH2_MIC_GAIN_SFT) -+#define RK3308_ADC_CH2_MIC_GAIN_0DB (0x0 << RK3308_ADC_CH2_MIC_GAIN_SFT) -+#define RK3308_ADC_CH1_MIC_GAIN_SFT 0 -+#define RK3308_ADC_CH1_MIC_GAIN_MSK (0x3 << RK3308_ADC_CH1_MIC_GAIN_SFT) -+#define RK3308_ADC_CH1_MIC_GAIN_30DB (0x3 << RK3308_ADC_CH1_MIC_GAIN_SFT) -+#define RK3308_ADC_CH1_MIC_GAIN_20DB (0x2 << RK3308_ADC_CH1_MIC_GAIN_SFT) -+#define RK3308_ADC_CH1_MIC_GAIN_6DB (0x1 << RK3308_ADC_CH1_MIC_GAIN_SFT) -+#define RK3308_ADC_CH1_MIC_GAIN_0DB (0x0 << RK3308_ADC_CH1_MIC_GAIN_SFT) -+ -+/* RK3308_ADC_ANA_CON02 - REG: 0x0348 */ -+#define RK3308_ADC_CH2_ALC_ZC_MSK (0x7 << 4) -+#define RK3308_ADC_CH2_ZEROCROSS_DET_EN (0x1 << 6) -+#define RK3308_ADC_CH2_ZEROCROSS_DET_DIS (0x0 << 6) -+#define RK3308_ADC_CH2_ALC_WORK (0x1 << 5) -+#define RK3308_ADC_CH2_ALC_INIT (0x0 << 5) -+#define RK3308_ADC_CH2_ALC_EN (0x1 << 4) -+#define RK3308_ADC_CH2_ALC_DIS (0x0 << 4) -+ -+#define RK3308_ADC_CH1_ALC_ZC_MSK (0x7 << 0) -+#define RK3308_ADC_CH1_ZEROCROSS_DET_EN (0x1 << 2) -+#define RK3308_ADC_CH1_ZEROCROSS_DET_DIS (0x0 << 2) -+#define RK3308_ADC_CH1_ALC_WORK (0x1 << 1) -+#define RK3308_ADC_CH1_ALC_INIT (0x0 << 1) -+#define RK3308_ADC_CH1_ALC_EN (0x1 << 0) -+#define RK3308_ADC_CH1_ALC_DIS (0x0 << 0) -+ -+/* RK3308_ADC_ANA_CON03 - REG: 0x034c */ -+#define RK3308_ADC_CH1_ALC_GAIN_SFT 0 -+#define RK3308_ADC_CH1_ALC_GAIN_MSK (0x1f << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_PDB_28_5 (0x1f << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_PDB_27 (0x1e << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_PDB_25_5 (0x1d << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_PDB_24 (0x1c << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_PDB_22_5 (0x1b << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_PDB_21 (0x1a << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_PDB_19_5 (0x19 << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_PDB_18 (0x18 << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_PDB_16_5 (0x17 << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_PDB_15 (0x16 << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_PDB_13_5 (0x15 << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_PDB_12 (0x14 << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_PDB_10_5 (0x13 << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_PDB_9 (0x12 << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_PDB_7_5 (0x11 << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_PDB_6 (0x10 << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_PDB_4_5 (0x0f << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_PDB_3 (0x0e << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_PDB_1_5 (0x0d << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_0DB (0x0c << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_NDB_1_5 (0x0b << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_NDB_3 (0x0a << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_NDB_4_5 (0x09 << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_NDB_6 (0x08 << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_NDB_7_5 (0x07 << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_NDB_9 (0x06 << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_NDB_10_5 (0x05 << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_NDB_12 (0x04 << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_NDB_13_5 (0x03 << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_NDB_15 (0x02 << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_NDB_16_5 (0x01 << RK3308_ADC_CH1_ALC_GAIN_SFT) -+#define RK3308_ADC_CH1_ALC_GAIN_NDB_18 (0x00 << RK3308_ADC_CH1_ALC_GAIN_SFT) -+ -+/* RK3308_ADC_ANA_CON04 - REG: 0x0350 */ -+#define RK3308_ADC_CH2_ALC_GAIN_SFT 0 -+#define RK3308_ADC_CH2_ALC_GAIN_MSK (0x1f << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_PDB_28_5 (0x1f << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_PDB_27 (0x1e << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_PDB_25_5 (0x1d << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_PDB_24 (0x1c << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_PDB_22_5 (0x1b << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_PDB_21 (0x1a << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_PDB_19_5 (0x19 << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_PDB_18 (0x18 << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_PDB_16_5 (0x17 << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_PDB_15 (0x16 << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_PDB_13_5 (0x15 << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_PDB_12 (0x14 << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_PDB_10_5 (0x13 << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_PDB_9 (0x12 << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_PDB_7_5 (0x11 << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_PDB_6 (0x10 << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_PDB_4_5 (0x0f << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_PDB_3 (0x0e << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_PDB_1_5 (0x0d << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_0DB (0x0c << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_NDB_1_5 (0x0b << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_NDB_3 (0x0a << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_NDB_4_5 (0x09 << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_NDB_6 (0x08 << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_NDB_7_5 (0x07 << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_NDB_9 (0x06 << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_NDB_10_5 (0x05 << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_NDB_12 (0x04 << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_NDB_13_5 (0x03 << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_NDB_15 (0x02 << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_NDB_16_5 (0x01 << RK3308_ADC_CH2_ALC_GAIN_SFT) -+#define RK3308_ADC_CH2_ALC_GAIN_NDB_18 (0x00 << RK3308_ADC_CH2_ALC_GAIN_SFT) -+ -+/* RK3308_ADC_ANA_CON05 - REG: 0x0354 */ -+#define RK3308_ADC_CH2_ADC_CLK_MSK (0x7 << 4) -+#define RK3308_ADC_CH2_ADC_WORK (0x1 << 6) -+#define RK3308_ADC_CH2_ADC_INIT (0x0 << 6) -+#define RK3308_ADC_CH2_ADC_EN (0x1 << 5) -+#define RK3308_ADC_CH2_ADC_DIS (0x0 << 5) -+#define RK3308_ADC_CH2_CLK_EN (0x1 << 4) -+#define RK3308_ADC_CH2_CLK_DIS (0x0 << 4) -+ -+#define RK3308_ADC_CH1_ADC_CLK_MSK (0x7 << 0) -+#define RK3308_ADC_CH1_ADC_WORK (0x1 << 2) -+#define RK3308_ADC_CH1_ADC_INIT (0x0 << 2) -+#define RK3308_ADC_CH1_ADC_EN (0x1 << 1) -+#define RK3308_ADC_CH1_ADC_DIS (0x0 << 1) -+#define RK3308_ADC_CH1_CLK_EN (0x1 << 0) -+#define RK3308_ADC_CH1_CLK_DIS (0x0 << 0) -+ -+/* RK3308_ADC_ANA_CON06 - REG: 0x0358 */ -+#define RK3308_ADC_CURRENT_MSK (0x1 << 0) -+#define RK3308_ADC_CURRENT_EN (0x1 << 0) -+#define RK3308_ADC_CURRENT_DIS (0x0 << 0) -+ -+/* RK3308_ADC_ANA_CON07 - REG: 0x035c */ -+/* Note: The register configuration is only valid for ADC2 */ -+#define RK3308_ADC_CH2_IN_SEL_SFT 6 -+#define RK3308_ADC_CH2_IN_SEL_MSK (0x3 << RK3308_ADC_CH2_IN_SEL_SFT) -+#define RK3308_ADC_CH2_IN_LINEIN_MIC (0x3 << RK3308_ADC_CH2_IN_SEL_SFT) -+#define RK3308_ADC_CH2_IN_LINEIN (0x2 << RK3308_ADC_CH2_IN_SEL_SFT) -+#define RK3308_ADC_CH2_IN_MIC (0x1 << RK3308_ADC_CH2_IN_SEL_SFT) -+#define RK3308_ADC_CH2_IN_NONE (0x0 << RK3308_ADC_CH2_IN_SEL_SFT) -+/* Note: The register configuration is only valid for ADC1 */ -+#define RK3308_ADC_CH1_IN_SEL_SFT 4 -+#define RK3308_ADC_CH1_IN_SEL_MSK (0x3 << RK3308_ADC_CH1_IN_SEL_SFT) -+#define RK3308_ADC_CH1_IN_LINEIN_MIC (0x3 << RK3308_ADC_CH1_IN_SEL_SFT) -+#define RK3308_ADC_CH1_IN_LINEIN (0x2 << RK3308_ADC_CH1_IN_SEL_SFT) -+#define RK3308_ADC_CH1_IN_MIC (0x1 << RK3308_ADC_CH1_IN_SEL_SFT) -+#define RK3308_ADC_CH1_IN_NONE (0x0 << RK3308_ADC_CH1_IN_SEL_SFT) -+ -+#define RK3308_ADC_MIC_BIAS_BUF_EN (0x1 << 3) -+#define RK3308_ADC_MIC_BIAS_BUF_DIS (0x0 << 3) -+#define RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT 0 -+#define RK3308_ADC_LEVEL_RANGE_MICBIAS_MSK (0x7 << RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT) -+#define RK3308_ADC_MICBIAS_VOLT_0_85 (0x7 << RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT) -+#define RK3308_ADC_MICBIAS_VOLT_0_8 (0x6 << RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT) -+#define RK3308_ADC_MICBIAS_VOLT_0_75 (0x5 << RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT) -+#define RK3308_ADC_MICBIAS_VOLT_0_7 (0x4 << RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT) -+#define RK3308_ADC_MICBIAS_VOLT_0_65 (0x3 << RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT) -+#define RK3308_ADC_MICBIAS_VOLT_0_6 (0x2 << RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT) -+#define RK3308_ADC_MICBIAS_VOLT_0_55 (0x1 << RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT) -+#define RK3308_ADC_MICBIAS_VOLT_0_5 (0x0 << RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT) -+ -+/* RK3308_ADC_ANA_CON08 - REG: 0x0360 */ -+#define RK3308_ADC_MICBIAS_CURRENT_MSK (0x1 << 4) -+#define RK3308_ADC_MICBIAS_CURRENT_EN (0x1 << 4) -+#define RK3308_ADC_MICBIAS_CURRENT_DIS (0x0 << 4) -+ -+/* RK3308_ADC_ANA_CON10 - REG: 0x0368 */ -+#define RK3308_ADC_REF_EN (0x1 << 7) -+#define RK3308_ADC_REF_DIS (0x0 << 7) -+#define RK3308_ADC_CURRENT_CHARGE_SFT 0 -+#define RK3308_ADC_CURRENT_CHARGE_MSK (0x7f << RK3308_ADC_CURRENT_CHARGE_SFT) -+#define RK3308_ADC_DONT_SEL_ALL (0x7f << RK3308_ADC_CURRENT_CHARGE_SFT) -+/* -+ * 0: Choose the current I -+ * 1: Don't choose the current I -+ */ -+#define RK3308_ADC_SEL_I_1(x) ((x & 0x1) << 6) -+#define RK3308_ADC_SEL_I_2(x) ((x & 0x1) << 5) -+#define RK3308_ADC_SEL_I_4(x) ((x & 0x1) << 4) -+#define RK3308_ADC_SEL_I_8(x) ((x & 0x1) << 3) -+#define RK3308_ADC_SEL_I_16(x) ((x & 0x1) << 2) -+#define RK3308_ADC_SEL_I_32(x) ((x & 0x1) << 1) -+#define RK3308_ADC_SEL_I_64(x) ((x & 0x1) << 0) -+ -+/* RK3308_ADC_ANA_CON11 - REG: 0x036c */ -+#define RK3308_ADC_ALCR_CON_GAIN_PGAR_MSK (0x1 << 1) -+#define RK3308_ADC_ALCR_CON_GAIN_PGAR_EN (0x1 << 1) -+#define RK3308_ADC_ALCR_CON_GAIN_PGAR_DIS (0x0 << 1) -+#define RK3308_ADC_ALCL_CON_GAIN_PGAL_MSK (0x1 << 0) -+#define RK3308_ADC_ALCL_CON_GAIN_PGAL_EN (0x1 << 0) -+#define RK3308_ADC_ALCL_CON_GAIN_PGAL_DIS (0x0 << 0) -+ -+/* RK3308_DAC_ANA_CON00 - REG: 0x0440 */ -+#define RK3308_DAC_HEADPHONE_DET_EN (0x1 << 1) -+#define RK3308_DAC_HEADPHONE_DET_DIS (0x0 << 1) -+#define RK3308_DAC_CURRENT_MSK (0x1 << 0) -+#define RK3308_DAC_CURRENT_EN (0x1 << 0) -+#define RK3308_DAC_CURRENT_DIS (0x0 << 0) -+ -+/* RK3308_DAC_ANA_CON01 - REG: 0x0444 */ -+#define RK3308_DAC_BUF_REF_R_MSK (0x1 << 6) -+#define RK3308_DAC_BUF_REF_R_EN (0x1 << 6) -+#define RK3308_DAC_BUF_REF_R_DIS (0x0 << 6) -+#define RK3308_DAC_POP_SOUND_R_SFT 4 -+#define RK3308_DAC_POP_SOUND_R_MSK (0x3 << RK3308_DAC_POP_SOUND_R_SFT) -+#define RK3308_DAC_POP_SOUND_R_WORK (0x2 << RK3308_DAC_POP_SOUND_R_SFT) -+#define RK3308_DAC_POP_SOUND_R_INIT (0x1 << RK3308_DAC_POP_SOUND_R_SFT) -+#define RK3308_DAC_BUF_REF_L_MSK (0x1 << 2) -+#define RK3308_DAC_BUF_REF_L_EN (0x1 << 2) -+#define RK3308_DAC_BUF_REF_L_DIS (0x0 << 2) -+#define RK3308_DAC_POP_SOUND_L_SFT 0 -+#define RK3308_DAC_POP_SOUND_L_MSK (0x3 << RK3308_DAC_POP_SOUND_L_SFT) -+#define RK3308_DAC_POP_SOUND_L_WORK (0x2 << RK3308_DAC_POP_SOUND_L_SFT) -+#define RK3308_DAC_POP_SOUND_L_INIT (0x1 << RK3308_DAC_POP_SOUND_L_SFT) -+ -+/* RK3308_DAC_ANA_CON02 - REG: 0x0448 */ -+#define RK3308_DAC_R_DAC_WORK (0x1 << 7) -+#define RK3308_DAC_R_DAC_INIT (0x0 << 7) -+#define RK3308_DAC_R_DAC_EN (0x1 << 6) -+#define RK3308_DAC_R_DAC_DIS (0x0 << 6) -+#define RK3308_DAC_R_CLK_EN (0x1 << 5) -+#define RK3308_DAC_R_CLK_DIS (0x0 << 5) -+#define RK3308_DAC_R_REF_EN (0x1 << 4) -+#define RK3308_DAC_R_REF_DIS (0x0 << 4) -+#define RK3308_DAC_L_DAC_WORK (0x1 << 3) -+#define RK3308_DAC_L_DAC_INIT (0x0 << 3) -+#define RK3308_DAC_L_DAC_EN (0x1 << 2) -+#define RK3308_DAC_L_DAC_DIS (0x0 << 2) -+#define RK3308_DAC_L_CLK_EN (0x1 << 1) -+#define RK3308_DAC_L_CLK_DIS (0x0 << 1) -+#define RK3308_DAC_L_REF_EN (0x1 << 0) -+#define RK3308_DAC_L_REF_DIS (0x0 << 0) -+ -+/* RK3308_DAC_ANA_CON03 - REG: 0x044c */ -+#define RK3308_DAC_R_HPOUT_WORK (0x1 << 6) -+#define RK3308_DAC_R_HPOUT_INIT (0x0 << 6) -+#define RK3308_DAC_R_HPOUT_EN (0x1 << 5) -+#define RK3308_DAC_R_HPOUT_DIS (0x0 << 5) -+#define RK3308_DAC_R_HPOUT_UNMUTE (0x1 << 4) -+#define RK3308_DAC_R_HPOUT_MUTE (0x0 << 4) -+#define RK3308_DAC_L_HPOUT_WORK (0x1 << 2) -+#define RK3308_DAC_L_HPOUT_INIT (0x0 << 2) -+#define RK3308_DAC_L_HPOUT_EN (0x1 << 1) -+#define RK3308_DAC_L_HPOUT_DIS (0x0 << 1) -+#define RK3308_DAC_L_HPOUT_UNMUTE (0x1 << 0) -+#define RK3308_DAC_L_HPOUT_MUTE (0x0 << 0) -+ -+/* RK3308_DAC_ANA_CON04 - REG: 0x0450 */ -+#define RK3308_DAC_R_GAIN_SFT 6 -+#define RK3308_DAC_R_GAIN_MSK (0x3 << RK3308_DAC_R_GAIN_SFT) -+#define RK3308_DAC_R_GAIN_0DB (0x3 << RK3308_DAC_R_GAIN_SFT) -+#define RK3308_DAC_R_GAIN_PDB_1_5 (0x2 << RK3308_DAC_R_GAIN_SFT) -+#define RK3308_DAC_R_GAIN_PDB_3 (0x1 << RK3308_DAC_R_GAIN_SFT) -+#define RK3308_DAC_R_GAIN_PDB_6 (0x0 << RK3308_DAC_R_GAIN_SFT) -+#define RK3308_DAC_R_LINEOUT_UNMUTE (0x1 << 5) -+#define RK3308_DAC_R_LINEOUT_MUTE (0x0 << 5) -+#define RK3308_DAC_R_LINEOUT_EN (0x1 << 4) -+#define RK3308_DAC_R_LINEOUT_DIS (0x0 << 4) -+#define RK3308_DAC_L_GAIN_SFT 2 -+#define RK3308_DAC_L_GAIN_MSK (0x3 << RK3308_DAC_L_GAIN_SFT) -+#define RK3308_DAC_L_GAIN_0DB (0x3 << RK3308_DAC_L_GAIN_SFT) -+#define RK3308_DAC_L_GAIN_PDB_1_5 (0x2 << RK3308_DAC_L_GAIN_SFT) -+#define RK3308_DAC_L_GAIN_PDB_3 (0x1 << RK3308_DAC_L_GAIN_SFT) -+#define RK3308_DAC_L_GAIN_PDB_6 (0x0 << RK3308_DAC_L_GAIN_SFT) -+#define RK3308_DAC_L_LINEOUT_UNMUTE (0x1 << 1) -+#define RK3308_DAC_L_LINEOUT_MUTE (0x0 << 1) -+#define RK3308_DAC_L_LINEOUT_EN (0x1 << 0) -+#define RK3308_DAC_L_LINEOUT_DIS (0x0 << 0) -+ -+/* RK3308_DAC_ANA_CON05 - REG: 0x0454, step is 1.5db */ -+#define RK3308_DAC_L_HPOUT_GAIN_SFT 0 -+#define RK3308_DAC_L_HPOUT_GAIN_MSK (0x1f << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_PDB_6 (0x1e << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_PDB_4_5 (0x1d << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_PDB_3 (0x1c << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_PDB_1_5 (0x1b << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_0DB (0x1a << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_NDB_1_5 (0x19 << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_NDB_3 (0x18 << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_NDB_4_5 (0x17 << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_NDB_6 (0x16 << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_NDB_7_5 (0x15 << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_NDB_9 (0x14 << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_NDB_10_5 (0x13 << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_NDB_12 (0x12 << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_NDB_13_5 (0x11 << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_NDB_15 (0x10 << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_NDB_16_5 (0x0f << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_NDB_18 (0x0e << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_NDB_19_5 (0x0d << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_NDB_21 (0x0c << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_NDB_22_5 (0x0b << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_NDB_24 (0x0a << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_NDB_25_5 (0x09 << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_NDB_27 (0x08 << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_NDB_28_5 (0x07 << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_NDB_30 (0x06 << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_NDB_31_5 (0x05 << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_NDB_33 (0x04 << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_NDB_34_5 (0x03 << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_NDB_36 (0x02 << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_NDB_37_5 (0x01 << RK3308_DAC_L_HPOUT_GAIN_SFT) -+#define RK3308_DAC_L_HPOUT_GAIN_NDB_39 (0x00 << RK3308_DAC_L_HPOUT_GAIN_SFT) -+ -+/* RK3308_DAC_ANA_CON06 - REG: 0x0458, step is 1.5db */ -+#define RK3308_DAC_R_HPOUT_GAIN_SFT 0 -+#define RK3308_DAC_R_HPOUT_GAIN_MSK (0x1f << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_PDB_6 (0x1e << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_PDB_4_5 (0x1d << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_PDB_3 (0x1c << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_PDB_1_5 (0x1b << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_0DB (0x1a << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_NDB_1_5 (0x19 << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_NDB_3 (0x18 << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_NDB_4_5 (0x17 << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_NDB_6 (0x16 << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_NDB_7_5 (0x15 << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_NDB_9 (0x14 << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_NDB_10_5 (0x13 << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_NDB_12 (0x12 << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_NDB_13_5 (0x11 << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_NDB_15 (0x10 << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_NDB_16_5 (0x0f << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_NDB_18 (0x0e << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_NDB_19_5 (0x0d << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_NDB_21 (0x0c << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_NDB_22_5 (0x0b << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_NDB_24 (0x0a << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_NDB_25_5 (0x09 << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_NDB_27 (0x08 << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_NDB_28_5 (0x07 << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_NDB_30 (0x06 << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_NDB_31_5 (0x05 << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_NDB_33 (0x04 << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_NDB_34_5 (0x03 << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_NDB_36 (0x02 << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_NDB_37_5 (0x01 << RK3308_DAC_R_HPOUT_GAIN_SFT) -+#define RK3308_DAC_R_HPOUT_GAIN_NDB_39 (0x00 << RK3308_DAC_R_HPOUT_GAIN_SFT) -+ -+/* RK3308_DAC_ANA_CON12 - REG: 0x0470 */ -+#define RK3308_DAC_R_HPMIX_SEL_SFT 6 -+#define RK3308_DAC_R_HPMIX_SEL_MSK (0x3 << RK3308_DAC_R_HPMIX_SEL_SFT) -+#define RK3308_DAC_R_HPMIX_LINEIN_I2S (0x3 << RK3308_DAC_R_HPMIX_SEL_SFT) -+#define RK3308_DAC_R_HPMIX_LINEIN (0x2 << RK3308_DAC_R_HPMIX_SEL_SFT) -+#define RK3308_DAC_R_HPMIX_I2S (0x1 << RK3308_DAC_R_HPMIX_SEL_SFT) -+#define RK3308_DAC_R_HPMIX_NONE (0x0 << RK3308_DAC_R_HPMIX_SEL_SFT) -+#define RK3308_DAC_R_HPMIX_GAIN_SFT 4 -+#define RK3308_DAC_R_HPMIX_GAIN_MSK (0x3 << RK3308_DAC_R_HPMIX_GAIN_SFT) -+#define RK3308_DAC_R_HPMIX_GAIN_0DB (0x2 << RK3308_DAC_R_HPMIX_GAIN_SFT) -+#define RK3308_DAC_R_HPMIX_GAIN_NDB_6 (0x1 << RK3308_DAC_R_HPMIX_GAIN_SFT) -+#define RK3308_DAC_L_HPMIX_SEL_SFT 2 -+#define RK3308_DAC_L_HPMIX_SEL_MSK (0x3 << RK3308_DAC_L_HPMIX_SEL_SFT) -+#define RK3308_DAC_L_HPMIX_LINEIN_I2S (0x3 << RK3308_DAC_L_HPMIX_SEL_SFT) -+#define RK3308_DAC_L_HPMIX_LINEIN (0x2 << RK3308_DAC_L_HPMIX_SEL_SFT) -+#define RK3308_DAC_L_HPMIX_I2S (0x1 << RK3308_DAC_L_HPMIX_SEL_SFT) -+#define RK3308_DAC_L_HPMIX_NONE (0x0 << RK3308_DAC_L_HPMIX_SEL_SFT) -+#define RK3308_DAC_L_HPMIX_GAIN_SFT 0 -+#define RK3308_DAC_L_HPMIX_GAIN_MSK (0x3 << RK3308_DAC_L_HPMIX_GAIN_SFT) -+#define RK3308_DAC_L_HPMIX_GAIN_0DB (0x2 << RK3308_DAC_L_HPMIX_GAIN_SFT) -+#define RK3308_DAC_L_HPMIX_GAIN_NDB_6 (0x1 << RK3308_DAC_L_HPMIX_GAIN_SFT) -+ -+/* RK3308_DAC_ANA_CON13 - REG: 0x0474 */ -+#define RK3308_DAC_R_HPMIX_UNMUTE (0x1 << 6) -+#define RK3308_DAC_R_HPMIX_MUTE (0x0 << 6) -+#define RK3308_DAC_R_HPMIX_WORK (0x1 << 5) -+#define RK3308_DAC_R_HPMIX_INIT (0x0 << 5) -+#define RK3308_DAC_R_HPMIX_EN (0x1 << 4) -+#define RK3308_DAC_R_HPMIX_DIS (0x0 << 4) -+#define RK3308_DAC_L_HPMIX_UNMUTE (0x1 << 2) -+#define RK3308_DAC_L_HPMIX_MUTE (0x0 << 2) -+#define RK3308_DAC_L_HPMIX_WORK (0x1 << 1) -+#define RK3308_DAC_L_HPMIX_INIT (0x0 << 1) -+#define RK3308_DAC_L_HPMIX_EN (0x1 << 0) -+#define RK3308_DAC_L_HPMIX_DIS (0x0 << 0) -+ -+#define RK3308_HIFI 0x0 -+ -+#endif /* __RK3308_CODEC_H__ */ --- -2.25.1 - diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0019-Sync-rk3308_codec-to-BSP-tree.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpis-0019-Sync-rk3308_codec-to-BSP-tree.patch deleted file mode 100644 index 0cb108633d5a..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0019-Sync-rk3308_codec-to-BSP-tree.patch +++ /dev/null @@ -1,6740 +0,0 @@ -From 26d61ff64d9a61425d017846db61e9a06de07286 Mon Sep 17 00:00:00 2001 -From: ashthespy -Date: Mon, 3 Feb 2020 17:13:59 +0100 -Subject: [PATCH 19/23] Sync `rk3308_codec` to BSP tree - ---- - .../bindings/sound/rockchip,rk3308-codec.txt | 78 + - sound/soc/codecs/rk3308_codec.c | 5687 ++++++++++++++--- - sound/soc/codecs/rk3308_codec.h | 217 +- - sound/soc/codecs/rk3308_codec_provider.h | 28 + - 4 files changed, 4894 insertions(+), 1116 deletions(-) - create mode 100644 Documentation/devicetree/bindings/sound/rockchip,rk3308-codec.txt - create mode 100644 sound/soc/codecs/rk3308_codec_provider.h - -diff --git a/Documentation/devicetree/bindings/sound/rockchip,rk3308-codec.txt b/Documentation/devicetree/bindings/sound/rockchip,rk3308-codec.txt -new file mode 100644 -index 000000000000..e20bbd73e37e ---- /dev/null -+++ b/Documentation/devicetree/bindings/sound/rockchip,rk3308-codec.txt -@@ -0,0 +1,78 @@ -+* Rockchip RK3308 Internal Codec -+ -+Required properties: -+ -+- compatible: "rockchip,rk3308-codec" -+- reg: The physical base address of the controller and length of memory -+ mapped region. -+- rockchip,grf: The phandle of the syscon node for GRF register. -+- clocks: A list of phandle + clock-specifer pairs, one for each entry in -+ clock-names. -+- clock-names: It should be "acodec". -+- resets : Must contain an entry for each entry in reset-names. -+- reset-names : Must include the following entries: "acodec-reset". -+ -+Optional properties: -+- rockchip,enable-all-adcs: This is a boolean type property, that shows whether -+ force enable all of ADCs. The following shows the relationship between grps -+ and ADC: -+ * grp 0 -- select ADC1 / ADC2 -+ * grp 1 -- select ADC3 / ADC4 -+ * grp 2 -- select ADC5 / ADC6 -+ * grp 3 -- select ADC7 / ADC8 -+ If the property is not used, the enabled ADC groups refer to needed channels -+ via configure hw_params. -+ -+- rockchip,adc-grps-route: This is a variable length array, that shows the -+ mapping route of ACODEC sdo to I2S sdi. By default, they are one-to-one -+ mapping: -+ * sdi_0 <-- sdo_0 -+ * sdi_1 <-- sdo_1 -+ * sdi_2 <-- sdo_2 -+ * sdi_3 <-- sdo_3 -+ If you would like to change the route mapping like this: -+ * sdi_0 <-- sdo_3 -+ * sdi_1 <-- sdo_0 -+ * sdi_2 <-- sdo_2 -+ * sdi_3 <-- sdo_1 -+ You need to add the property on dts: -+ - rockchip,adc-grps-route = <3 0 2 1>; -+ -+- rockchip,delay-loopback-handle-ms: This property points out that the delay for -+ handling ADC after enable PAs during loopback. -+- rockchip,delay-start-play-ms: This property points out the delay ms of start -+ playback according to different amplifier performance. -+- rockchip,en-always-grps: This property will keep the needed ADCs enabled -+ always after enabling once. -+- rockchip,loopback-grp: It points out the ADC group which is the loopback used. -+- rockchip,no-deep-low-power: The codec will not enter deep low power mode -+ during suspend. -+- rockchip,no-hp-det: If there is no headphone on boards, we don't need to -+ enable headphone detection. -+- rockchip,micbias1: Using internal micbias1 supply which are from codec. -+- rockchip,micbias2: Using internal micbias2 supply which are from codec. -+- rockchip,hp-jack-reversed;: To detect headphone via the reversed jack. -+- hp-ctl-gpios: The gpio of head phone controller. -+- pa-drv-gpios: The gpio of poweramplifier controller -+- rockchip,delay-pa-drv-ms: This property points out that the delay for -+ power on amplifier -+- spk-ctl-gpios: The gpio of speak controller. -+- micbias-en-gpios: The GPIO to enable external micbias. -+- vmicbias-supply: The phandle to the regulator to handle external micbias. -+ -+Example for rk3308 internal codec: -+ -+acodec: acodec@ff560000 { -+ compatible = "rockchip,rk3308-codec"; -+ reg = <0x0 0xff560000 0x0 0x10000>; -+ rockchip,grf = <&grf>; -+ clocks = <&cru PCLK_ACODEC>; -+ clock-names = "acodec"; -+ resets = <&cru SRST_ACODEC_P>; -+ reset-names = "acodec-reset"; -+ rockchip,loopback-grp = <0>; -+ hp-ctl-gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; -+ pa-drv-gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>; -+ spk-ctl-gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>; -+ status = "okay"; -+}; -diff --git a/sound/soc/codecs/rk3308_codec.c b/sound/soc/codecs/rk3308_codec.c -index 106f09738dd0..815e22fc346c 100644 ---- a/sound/soc/codecs/rk3308_codec.c -+++ b/sound/soc/codecs/rk3308_codec.c -@@ -29,1420 +29,4699 @@ - #include - #include - #include -+#include - #include - #include - #include - #include - #include - #include -+#include - #include - #include -+#include - #include - #include - - #include "rk3308_codec.h" -+#include "rk3308_codec_provider.h" -+ -+#if defined(CONFIG_DEBUG_FS) -+#include -+#include -+#include -+#endif -+ -+#define CODEC_DRV_NAME "rk3308-acodec" -+ -+#define ADC_GRP_SKIP_MAGIC 0x1001 -+#define ADC_LR_GROUP_MAX 4 -+#define ADC_STABLE_MS 200 -+#define DEBUG_POP_ALWAYS 0 -+#define HPDET_POLL_MS 2000 -+#define NOT_USED 255 -+#define LOOPBACK_HANDLE_MS 100 -+#define PA_DRV_MS 5 -+ -+#define GRF_SOC_CON1 0x304 -+#define GRF_CHIP_ID 0x800 -+#define GRF_I2S2_8CH_SDI_SFT 0 -+#define GRF_I2S3_4CH_SDI_SFT 8 -+#define GRF_I2S1_2CH_SDI_SFT 12 -+ -+#define GRF_I2S2_8CH_SDI_R_MSK(i, v) ((v >> (i * 2 + GRF_I2S2_8CH_SDI_SFT)) & 0x3) -+#define GRF_I2S2_8CH_SDI_W_MSK(i) (0x3 << (i * 2 + GRF_I2S2_8CH_SDI_SFT + 16)) -+#define GRF_I2S2_8CH_SDI(i, v) (((v & 0x3) << (i * 2 + GRF_I2S2_8CH_SDI_SFT)) |\ -+ GRF_I2S2_8CH_SDI_W_MSK(i)) -+ -+#define GRF_I2S3_4CH_SDI_W_MSK(i) (0x3 << (i * 2 + GRF_I2S3_4CH_SDI_SFT + 16)) -+#define GRF_I2S3_4CH_SDI(i, v) (((v & 0x3) << (i * 2 + GRF_I2S3_4CH_SDI_SFT)) |\ -+ GRF_I2S3_4CH_SDI_W_MSK(i)) -+ -+#define GRF_I2S1_2CH_SDI_W_MSK (0x3 << (GRF_I2S1_2CH_SDI_SFT + 16)) -+#define GRF_I2S1_2CH_SDI(v) (((v & 0x3) << GRF_I2S1_2CH_SDI_SFT) |\ -+ GRF_I2S1_2CH_SDI_W_MSK) -+ -+#define DETECT_GRF_ACODEC_HPDET_COUNTER 0x0030 -+#define DETECT_GRF_ACODEC_HPDET_CON 0x0034 -+#define DETECT_GRF_ACODEC_HPDET_STATUS 0x0038 -+#define DETECT_GRF_ACODEC_HPDET_STATUS_CLR 0x003c -+ -+/* 200ms based on pclk is 100MHz */ -+#define DEFAULT_HPDET_COUNT 20000000 -+#define HPDET_NEG_IRQ_SFT 1 -+#define HPDET_POS_IRQ_SFT 0 -+#define HPDET_BOTH_NEG_POS ((1 << HPDET_NEG_IRQ_SFT) |\ -+ (1 << HPDET_POS_IRQ_SFT)) -+ -+#define ACODEC_VERSION_A 0xa -+#define ACODEC_VERSION_B 0xb -+ -+enum { -+ ACODEC_TO_I2S2_8CH = 0, -+ ACODEC_TO_I2S3_4CH, -+ ACODEC_TO_I2S1_2CH, -+}; -+ -+enum { -+ ADC_GRP0_MICIN = 0, -+ ADC_GRP0_LINEIN -+}; -+ -+enum { -+ ADC_TYPE_NORMAL = 0, -+ ADC_TYPE_LOOPBACK, -+ ADC_TYPE_DBG, -+ ADC_TYPE_ALL, -+}; -+ -+enum { -+ DAC_LINEOUT = 0, -+ DAC_HPOUT = 1, -+ DAC_LINEOUT_HPOUT = 11, -+}; -+ -+enum { -+ EXT_MICBIAS_NONE = 0, -+ EXT_MICBIAS_FUNC1, /* enable external micbias via GPIO */ -+ EXT_MICBIAS_FUNC2, /* enable external micbias via regulator */ -+}; -+ -+enum { -+ PATH_IDLE = 0, -+ PATH_BUSY, -+}; -+ -+enum { -+ PM_NORMAL = 0, -+ PM_LLP_DOWN, /* light low power down */ -+ PM_LLP_UP, -+ PM_DLP_DOWN, /* deep low power down */ -+ PM_DLP_UP, -+ PM_DLP_DOWN2, -+ PM_DLP_UP2, -+}; - - struct rk3308_codec_priv { - const struct device *plat_dev; - struct device dev; - struct reset_control *reset; - struct regmap *regmap; -+ struct regmap *grf; -+ struct regmap *detect_grf; - struct clk *pclk; -+ struct clk *mclk_rx; -+ struct clk *mclk_tx; -+ struct gpio_desc *micbias_en_gpio; -+ struct gpio_desc *hp_ctl_gpio; - struct gpio_desc *spk_ctl_gpio; -- int adc_ch; /* To select ADCs for channel */ -- int adc_ch0_using_linein; -+ struct gpio_desc *pa_drv_gpio; -+ struct snd_soc_codec *codec; -+ struct snd_soc_jack *hpdet_jack; -+ struct regulator *vcc_micbias; -+ u32 codec_ver; -+ -+ /* -+ * To select ADCs for groups: -+ * -+ * grp 0 -- select ADC1 / ADC2 -+ * grp 1 -- select ADC3 / ADC4 -+ * grp 2 -- select ADC5 / ADC6 -+ * grp 3 -- select ADC7 / ADC8 -+ */ -+ u32 used_adc_grps; -+ /* The ADC group which is used for loop back */ -+ u32 loopback_grp; -+ u32 cur_dbg_grp; -+ u32 en_always_grps[ADC_LR_GROUP_MAX]; -+ u32 en_always_grps_num; -+ u32 skip_grps[ADC_LR_GROUP_MAX]; -+ u32 i2s_sdis[ADC_LR_GROUP_MAX]; -+ u32 to_i2s_grps; -+ u32 delay_loopback_handle_ms; -+ u32 delay_start_play_ms; -+ u32 delay_pa_drv_ms; -+ u32 micbias_num; -+ u32 micbias_volt; -+ int which_i2s; -+ int irq; -+ int adc_grp0_using_linein; -+ int adc_zerocross; -+ /* 0: line out, 1: hp out, 11: lineout and hpout */ -+ int dac_output; -+ int dac_path_state; -+ -+ int ext_micbias; -+ int pm_state; -+ -+ /* AGC L/R Off/on */ -+ unsigned int agc_l[ADC_LR_GROUP_MAX]; -+ unsigned int agc_r[ADC_LR_GROUP_MAX]; -+ -+ /* AGC L/R Approximate Sample Rate */ -+ unsigned int agc_asr_l[ADC_LR_GROUP_MAX]; -+ unsigned int agc_asr_r[ADC_LR_GROUP_MAX]; -+ -+ /* ADC MIC Mute/Work */ -+ unsigned int mic_mute_l[ADC_LR_GROUP_MAX]; -+ unsigned int mic_mute_r[ADC_LR_GROUP_MAX]; -+ -+ /* For the high pass filter */ -+ unsigned int hpf_cutoff[ADC_LR_GROUP_MAX]; -+ -+ /* Only hpout do fade-in and fade-out */ -+ unsigned int hpout_l_dgain; -+ unsigned int hpout_r_dgain; -+ -+ bool adc_grps_endisable[ADC_LR_GROUP_MAX]; -+ bool dac_endisable; -+ bool enable_all_adcs; -+ bool enable_micbias; -+ bool micbias1; -+ bool micbias2; -+ bool hp_jack_reversed; -+ bool hp_plugged; -+ bool loopback_dacs_enabled; -+ bool no_deep_low_power; -+ bool no_hp_det; -+ struct delayed_work hpdet_work; -+ struct delayed_work loopback_work; -+ -+#if defined(CONFIG_DEBUG_FS) -+ struct dentry *dbg_codec; -+#endif - }; - --static const DECLARE_TLV_DB_SCALE(rk3308_codec_alc_agc_ch_gain_tlv, -+static const DECLARE_TLV_DB_SCALE(rk3308_codec_alc_agc_grp_gain_tlv, - -1800, 150, 2850); --static const DECLARE_TLV_DB_SCALE(rk3308_codec_alc_agc_ch_max_gain_tlv, -+static const DECLARE_TLV_DB_SCALE(rk3308_codec_alc_agc_grp_max_gain_tlv, - -1350, 600, 2850); --static const DECLARE_TLV_DB_SCALE(rk3308_codec_alc_agc_ch_min_gain_tlv, -+static const DECLARE_TLV_DB_SCALE(rk3308_codec_alc_agc_grp_min_gain_tlv, - -1800, 600, 2400); --static const DECLARE_TLV_DB_SCALE(rk3308_codec_adc_mic_gain_tlv, -- 0, 600, 3000); - static const DECLARE_TLV_DB_SCALE(rk3308_codec_adc_alc_gain_tlv, - -1800, 150, 2850); --static const DECLARE_TLV_DB_SCALE(rk3308_codec_dac_gain_tlv, -- 0, 150, 600); -+static const DECLARE_TLV_DB_SCALE(rk3308_codec_dac_lineout_gain_tlv, -+ -600, 150, 0); - static const DECLARE_TLV_DB_SCALE(rk3308_codec_dac_hpout_gain_tlv, - -3900, 150, 600); - static const DECLARE_TLV_DB_SCALE(rk3308_codec_dac_hpmix_gain_tlv, - -600, 600, 0); - -+static const DECLARE_TLV_DB_RANGE(rk3308_codec_adc_mic_gain_tlv_a, -+ 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), -+ 3, 3, TLV_DB_SCALE_ITEM(2000, 0, 0), -+); -+ -+static const DECLARE_TLV_DB_RANGE(rk3308_codec_adc_mic_gain_tlv_b, -+ 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), -+ 1, 1, TLV_DB_SCALE_ITEM(660, 0, 0), -+ 2, 2, TLV_DB_SCALE_ITEM(1300, 0, 0), -+ 3, 3, TLV_DB_SCALE_ITEM(2000, 0, 0), -+); -+ -+static bool handle_loopback(struct rk3308_codec_priv *rk3308); -+ -+static int check_micbias(int micbias); -+ -+static int rk3308_codec_micbias_enable(struct rk3308_codec_priv *rk3308, -+ int micbias); -+static int rk3308_codec_micbias_disable(struct rk3308_codec_priv *rk3308); -+ -+static int rk3308_codec_hpout_l_get_tlv(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol); -+static int rk3308_codec_hpout_l_put_tlv(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol); -+static int rk3308_codec_hpout_r_get_tlv(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol); -+static int rk3308_codec_hpout_r_put_tlv(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol); -+static int rk3308_codec_hpf_get(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol); -+static int rk3308_codec_hpf_put(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol); -+static int rk3308_codec_agc_get(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol); -+static int rk3308_codec_agc_put(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol); -+static int rk3308_codec_agc_asr_get(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol); -+static int rk3308_codec_agc_asr_put(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol); -+static int rk3308_codec_mic_mute_get(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol); -+static int rk3308_codec_mic_mute_put(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol); -+static int rk3308_codec_mic_gain_get(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol); -+static int rk3308_codec_mic_gain_put(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol); -+static int rk3308_codec_micbias_volts_get(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol); -+static int rk3308_codec_micbias_volts_put(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol); -+static int rk3308_codec_main_micbias_get(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol); -+static int rk3308_codec_main_micbias_put(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol); -+ -+static const char *offon_text[2] = { -+ [0] = "Off", -+ [1] = "On", -+}; -+ -+static const char *mute_text[2] = { -+ [0] = "Work", -+ [1] = "Mute", -+}; -+ -+/* ADC MICBIAS Volt */ -+#define MICBIAS_VOLT_NUM 8 -+ -+#define MICBIAS_VREFx0_5 0 -+#define MICBIAS_VREFx0_55 1 -+#define MICBIAS_VREFx0_6 2 -+#define MICBIAS_VREFx0_65 3 -+#define MICBIAS_VREFx0_7 4 -+#define MICBIAS_VREFx0_75 5 -+#define MICBIAS_VREFx0_8 6 -+#define MICBIAS_VREFx0_85 7 -+ -+static const char *micbias_volts_enum_array[MICBIAS_VOLT_NUM] = { -+ [MICBIAS_VREFx0_5] = "VREFx0_5", -+ [MICBIAS_VREFx0_55] = "VREFx0_55", -+ [MICBIAS_VREFx0_6] = "VREFx0_6", -+ [MICBIAS_VREFx0_65] = "VREFx0_65", -+ [MICBIAS_VREFx0_7] = "VREFx0_7", -+ [MICBIAS_VREFx0_75] = "VREFx0_75", -+ [MICBIAS_VREFx0_8] = "VREFx0_8", -+ [MICBIAS_VREFx0_85] = "VREFx0_85", -+}; -+ -+static const struct soc_enum rk3308_micbias_volts_enum_array[] = { -+ SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(micbias_volts_enum_array), micbias_volts_enum_array), -+}; -+ -+/* ADC MICBIAS1 and MICBIAS2 Main Switch */ -+static const struct soc_enum rk3308_main_micbias_enum_array[] = { -+ SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(offon_text), offon_text), -+}; -+ -+static const struct soc_enum rk3308_hpf_enum_array[] = { -+ SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(offon_text), offon_text), -+ SOC_ENUM_SINGLE(1, 0, ARRAY_SIZE(offon_text), offon_text), -+ SOC_ENUM_SINGLE(2, 0, ARRAY_SIZE(offon_text), offon_text), -+ SOC_ENUM_SINGLE(3, 0, ARRAY_SIZE(offon_text), offon_text), -+}; -+ -+/* ALC AGC Switch */ -+static const struct soc_enum rk3308_agc_enum_array[] = { -+ SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(offon_text), offon_text), -+ SOC_ENUM_SINGLE(0, 1, ARRAY_SIZE(offon_text), offon_text), -+ SOC_ENUM_SINGLE(1, 0, ARRAY_SIZE(offon_text), offon_text), -+ SOC_ENUM_SINGLE(1, 1, ARRAY_SIZE(offon_text), offon_text), -+ SOC_ENUM_SINGLE(2, 0, ARRAY_SIZE(offon_text), offon_text), -+ SOC_ENUM_SINGLE(2, 1, ARRAY_SIZE(offon_text), offon_text), -+ SOC_ENUM_SINGLE(3, 0, ARRAY_SIZE(offon_text), offon_text), -+ SOC_ENUM_SINGLE(3, 1, ARRAY_SIZE(offon_text), offon_text), -+}; -+ -+/* ADC MIC Mute/Work Switch */ -+static const struct soc_enum rk3308_mic_mute_enum_array[] = { -+ SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(mute_text), mute_text), -+ SOC_ENUM_SINGLE(0, 1, ARRAY_SIZE(mute_text), mute_text), -+ SOC_ENUM_SINGLE(1, 0, ARRAY_SIZE(mute_text), mute_text), -+ SOC_ENUM_SINGLE(1, 1, ARRAY_SIZE(mute_text), mute_text), -+ SOC_ENUM_SINGLE(2, 0, ARRAY_SIZE(mute_text), mute_text), -+ SOC_ENUM_SINGLE(2, 1, ARRAY_SIZE(mute_text), mute_text), -+ SOC_ENUM_SINGLE(3, 0, ARRAY_SIZE(mute_text), mute_text), -+ SOC_ENUM_SINGLE(3, 1, ARRAY_SIZE(mute_text), mute_text), -+}; -+ -+/* ALC AGC Approximate Sample Rate */ -+#define AGC_ASR_NUM 8 -+ -+#define AGC_ASR_96KHZ 0 -+#define AGC_ASR_48KHZ 1 -+#define AGC_ASR_44_1KHZ 2 -+#define AGC_ASR_32KHZ 3 -+#define AGC_ASR_24KHZ 4 -+#define AGC_ASR_16KHZ 5 -+#define AGC_ASR_12KHZ 6 -+#define AGC_ASR_8KHZ 7 -+ -+static const char *agc_asr_text[AGC_ASR_NUM] = { -+ [AGC_ASR_96KHZ] = "96KHz", -+ [AGC_ASR_48KHZ] = "48KHz", -+ [AGC_ASR_44_1KHZ] = "44.1KHz", -+ [AGC_ASR_32KHZ] = "32KHz", -+ [AGC_ASR_24KHZ] = "24KHz", -+ [AGC_ASR_16KHZ] = "16KHz", -+ [AGC_ASR_12KHZ] = "12KHz", -+ [AGC_ASR_8KHZ] = "8KHz", -+}; -+ -+static const struct soc_enum rk3308_agc_asr_enum_array[] = { -+ SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(agc_asr_text), agc_asr_text), -+ SOC_ENUM_SINGLE(0, 1, ARRAY_SIZE(agc_asr_text), agc_asr_text), -+ SOC_ENUM_SINGLE(1, 0, ARRAY_SIZE(agc_asr_text), agc_asr_text), -+ SOC_ENUM_SINGLE(1, 1, ARRAY_SIZE(agc_asr_text), agc_asr_text), -+ SOC_ENUM_SINGLE(2, 0, ARRAY_SIZE(agc_asr_text), agc_asr_text), -+ SOC_ENUM_SINGLE(2, 1, ARRAY_SIZE(agc_asr_text), agc_asr_text), -+ SOC_ENUM_SINGLE(3, 0, ARRAY_SIZE(agc_asr_text), agc_asr_text), -+ SOC_ENUM_SINGLE(3, 1, ARRAY_SIZE(agc_asr_text), agc_asr_text), -+}; -+ -+static const struct snd_kcontrol_new mic_gains_a[] = { -+ /* ADC MIC */ -+ SOC_SINGLE_EXT_TLV("ADC MIC Group 0 Left Volume", -+ RK3308_ADC_ANA_CON01(0), -+ RK3308_ADC_CH1_MIC_GAIN_SFT, -+ RK3308_ADC_CH1_MIC_GAIN_MAX, -+ 0, -+ rk3308_codec_mic_gain_get, -+ rk3308_codec_mic_gain_put, -+ rk3308_codec_adc_mic_gain_tlv_a), -+ SOC_SINGLE_EXT_TLV("ADC MIC Group 0 Right Volume", -+ RK3308_ADC_ANA_CON01(0), -+ RK3308_ADC_CH2_MIC_GAIN_SFT, -+ RK3308_ADC_CH2_MIC_GAIN_MAX, -+ 0, -+ rk3308_codec_mic_gain_get, -+ rk3308_codec_mic_gain_put, -+ rk3308_codec_adc_mic_gain_tlv_a), -+ SOC_SINGLE_EXT_TLV("ADC MIC Group 1 Left Volume", -+ RK3308_ADC_ANA_CON01(1), -+ RK3308_ADC_CH1_MIC_GAIN_SFT, -+ RK3308_ADC_CH1_MIC_GAIN_MAX, -+ 0, -+ rk3308_codec_mic_gain_get, -+ rk3308_codec_mic_gain_put, -+ rk3308_codec_adc_mic_gain_tlv_a), -+ SOC_SINGLE_EXT_TLV("ADC MIC Group 1 Right Volume", -+ RK3308_ADC_ANA_CON01(1), -+ RK3308_ADC_CH2_MIC_GAIN_SFT, -+ RK3308_ADC_CH2_MIC_GAIN_MAX, -+ 0, -+ rk3308_codec_mic_gain_get, -+ rk3308_codec_mic_gain_put, -+ rk3308_codec_adc_mic_gain_tlv_a), -+ SOC_SINGLE_EXT_TLV("ADC MIC Group 2 Left Volume", -+ RK3308_ADC_ANA_CON01(2), -+ RK3308_ADC_CH1_MIC_GAIN_SFT, -+ RK3308_ADC_CH1_MIC_GAIN_MAX, -+ 0, -+ rk3308_codec_mic_gain_get, -+ rk3308_codec_mic_gain_put, -+ rk3308_codec_adc_mic_gain_tlv_a), -+ SOC_SINGLE_EXT_TLV("ADC MIC Group 2 Right Volume", -+ RK3308_ADC_ANA_CON01(2), -+ RK3308_ADC_CH2_MIC_GAIN_SFT, -+ RK3308_ADC_CH2_MIC_GAIN_MAX, -+ 0, -+ rk3308_codec_mic_gain_get, -+ rk3308_codec_mic_gain_put, -+ rk3308_codec_adc_mic_gain_tlv_a), -+ SOC_SINGLE_EXT_TLV("ADC MIC Group 3 Left Volume", -+ RK3308_ADC_ANA_CON01(3), -+ RK3308_ADC_CH1_MIC_GAIN_SFT, -+ RK3308_ADC_CH1_MIC_GAIN_MAX, -+ 0, -+ rk3308_codec_mic_gain_get, -+ rk3308_codec_mic_gain_put, -+ rk3308_codec_adc_mic_gain_tlv_a), -+ SOC_SINGLE_EXT_TLV("ADC MIC Group 3 Right Volume", -+ RK3308_ADC_ANA_CON01(3), -+ RK3308_ADC_CH2_MIC_GAIN_SFT, -+ RK3308_ADC_CH2_MIC_GAIN_MAX, -+ 0, -+ rk3308_codec_mic_gain_get, -+ rk3308_codec_mic_gain_put, -+ rk3308_codec_adc_mic_gain_tlv_a), -+}; -+ -+static const struct snd_kcontrol_new mic_gains_b[] = { -+ /* ADC MIC */ -+ SOC_SINGLE_EXT_TLV("ADC MIC Group 0 Left Volume", -+ RK3308_ADC_ANA_CON01(0), -+ RK3308_ADC_CH1_MIC_GAIN_SFT, -+ RK3308_ADC_CH1_MIC_GAIN_MAX, -+ 0, -+ rk3308_codec_mic_gain_get, -+ rk3308_codec_mic_gain_put, -+ rk3308_codec_adc_mic_gain_tlv_b), -+ SOC_SINGLE_EXT_TLV("ADC MIC Group 0 Right Volume", -+ RK3308_ADC_ANA_CON01(0), -+ RK3308_ADC_CH2_MIC_GAIN_SFT, -+ RK3308_ADC_CH2_MIC_GAIN_MAX, -+ 0, -+ rk3308_codec_mic_gain_get, -+ rk3308_codec_mic_gain_put, -+ rk3308_codec_adc_mic_gain_tlv_b), -+ SOC_SINGLE_EXT_TLV("ADC MIC Group 1 Left Volume", -+ RK3308_ADC_ANA_CON01(1), -+ RK3308_ADC_CH1_MIC_GAIN_SFT, -+ RK3308_ADC_CH1_MIC_GAIN_MAX, -+ 0, -+ rk3308_codec_mic_gain_get, -+ rk3308_codec_mic_gain_put, -+ rk3308_codec_adc_mic_gain_tlv_b), -+ SOC_SINGLE_EXT_TLV("ADC MIC Group 1 Right Volume", -+ RK3308_ADC_ANA_CON01(1), -+ RK3308_ADC_CH2_MIC_GAIN_SFT, -+ RK3308_ADC_CH2_MIC_GAIN_MAX, -+ 0, -+ rk3308_codec_mic_gain_get, -+ rk3308_codec_mic_gain_put, -+ rk3308_codec_adc_mic_gain_tlv_b), -+ SOC_SINGLE_EXT_TLV("ADC MIC Group 2 Left Volume", -+ RK3308_ADC_ANA_CON01(2), -+ RK3308_ADC_CH1_MIC_GAIN_SFT, -+ RK3308_ADC_CH1_MIC_GAIN_MAX, -+ 0, -+ rk3308_codec_mic_gain_get, -+ rk3308_codec_mic_gain_put, -+ rk3308_codec_adc_mic_gain_tlv_b), -+ SOC_SINGLE_EXT_TLV("ADC MIC Group 2 Right Volume", -+ RK3308_ADC_ANA_CON01(2), -+ RK3308_ADC_CH2_MIC_GAIN_SFT, -+ RK3308_ADC_CH2_MIC_GAIN_MAX, -+ 0, -+ rk3308_codec_mic_gain_get, -+ rk3308_codec_mic_gain_put, -+ rk3308_codec_adc_mic_gain_tlv_b), -+ SOC_SINGLE_EXT_TLV("ADC MIC Group 3 Left Volume", -+ RK3308_ADC_ANA_CON01(3), -+ RK3308_ADC_CH1_MIC_GAIN_SFT, -+ RK3308_ADC_CH1_MIC_GAIN_MAX, -+ 0, -+ rk3308_codec_mic_gain_get, -+ rk3308_codec_mic_gain_put, -+ rk3308_codec_adc_mic_gain_tlv_b), -+ SOC_SINGLE_EXT_TLV("ADC MIC Group 3 Right Volume", -+ RK3308_ADC_ANA_CON01(3), -+ RK3308_ADC_CH2_MIC_GAIN_SFT, -+ RK3308_ADC_CH2_MIC_GAIN_MAX, -+ 0, -+ rk3308_codec_mic_gain_get, -+ rk3308_codec_mic_gain_put, -+ rk3308_codec_adc_mic_gain_tlv_b), -+}; -+ - static const struct snd_kcontrol_new rk3308_codec_dapm_controls[] = { -- /* ALC AGC Channel*/ -- SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 0 Volume", -+ /* ALC AGC Group */ -+ SOC_SINGLE_RANGE_TLV("ALC AGC Group 0 Left Volume", - RK3308_ALC_L_DIG_CON03(0), -+ RK3308_AGC_PGA_GAIN_SFT, -+ RK3308_AGC_PGA_GAIN_MIN, -+ RK3308_AGC_PGA_GAIN_MAX, -+ 0, rk3308_codec_alc_agc_grp_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("ALC AGC Group 0 Right Volume", - RK3308_ALC_R_DIG_CON03(0), - RK3308_AGC_PGA_GAIN_SFT, -- RK3308_AGC_PGA_GAIN_NDB_18, -- RK3308_AGC_PGA_GAIN_PDB_28_5, -- 0, rk3308_codec_alc_agc_ch_gain_tlv), -- SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 1 Volume", -+ RK3308_AGC_PGA_GAIN_MIN, -+ RK3308_AGC_PGA_GAIN_MAX, -+ 0, rk3308_codec_alc_agc_grp_gain_tlv), -+ -+ SOC_SINGLE_RANGE_TLV("ALC AGC Group 1 Left Volume", - RK3308_ALC_L_DIG_CON03(1), -+ RK3308_AGC_PGA_GAIN_SFT, -+ RK3308_AGC_PGA_GAIN_MIN, -+ RK3308_AGC_PGA_GAIN_MAX, -+ 0, rk3308_codec_alc_agc_grp_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("ALC AGC Group 1 Right Volume", - RK3308_ALC_R_DIG_CON03(1), - RK3308_AGC_PGA_GAIN_SFT, -- RK3308_AGC_PGA_GAIN_NDB_18, -- RK3308_AGC_PGA_GAIN_PDB_28_5, -- 0, rk3308_codec_alc_agc_ch_gain_tlv), -- SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 2 Volume", -+ RK3308_AGC_PGA_GAIN_MIN, -+ RK3308_AGC_PGA_GAIN_MAX, -+ 0, rk3308_codec_alc_agc_grp_gain_tlv), -+ -+ SOC_SINGLE_RANGE_TLV("ALC AGC Group 2 Left Volume", - RK3308_ALC_L_DIG_CON03(2), -+ RK3308_AGC_PGA_GAIN_SFT, -+ RK3308_AGC_PGA_GAIN_MIN, -+ RK3308_AGC_PGA_GAIN_MAX, -+ 0, rk3308_codec_alc_agc_grp_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("ALC AGC Group 2 Right Volume", - RK3308_ALC_R_DIG_CON03(2), - RK3308_AGC_PGA_GAIN_SFT, -- RK3308_AGC_PGA_GAIN_NDB_18, -- RK3308_AGC_PGA_GAIN_PDB_28_5, -- 0, rk3308_codec_alc_agc_ch_gain_tlv), -- SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 3 Volume", -+ RK3308_AGC_PGA_GAIN_MIN, -+ RK3308_AGC_PGA_GAIN_MAX, -+ 0, rk3308_codec_alc_agc_grp_gain_tlv), -+ -+ SOC_SINGLE_RANGE_TLV("ALC AGC Group 3 Left Volume", - RK3308_ALC_L_DIG_CON03(3), -+ RK3308_AGC_PGA_GAIN_SFT, -+ RK3308_AGC_PGA_GAIN_MIN, -+ RK3308_AGC_PGA_GAIN_MAX, -+ 0, rk3308_codec_alc_agc_grp_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("ALC AGC Group 3 Right Volume", - RK3308_ALC_R_DIG_CON03(3), - RK3308_AGC_PGA_GAIN_SFT, -- RK3308_AGC_PGA_GAIN_NDB_18, -- RK3308_AGC_PGA_GAIN_PDB_28_5, -- 0, rk3308_codec_alc_agc_ch_gain_tlv), -+ RK3308_AGC_PGA_GAIN_MIN, -+ RK3308_AGC_PGA_GAIN_MAX, -+ 0, rk3308_codec_alc_agc_grp_gain_tlv), - - /* ALC AGC MAX */ -- SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 0 Max Volume", -+ SOC_SINGLE_RANGE_TLV("ALC AGC Group 0 Left Max Volume", - RK3308_ALC_L_DIG_CON09(0), -+ RK3308_AGC_MAX_GAIN_PGA_SFT, -+ RK3308_AGC_MAX_GAIN_PGA_MIN, -+ RK3308_AGC_MAX_GAIN_PGA_MAX, -+ 0, rk3308_codec_alc_agc_grp_max_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("ALC AGC Group 0 Right Max Volume", - RK3308_ALC_R_DIG_CON09(0), - RK3308_AGC_MAX_GAIN_PGA_SFT, -- RK3308_AGC_MAX_GAIN_PGA_NDB_13_5, -- RK3308_AGC_MAX_GAIN_PGA_PDB_28_5, -- 0, rk3308_codec_alc_agc_ch_max_gain_tlv), -- SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 1 Max Volume", -+ RK3308_AGC_MAX_GAIN_PGA_MIN, -+ RK3308_AGC_MAX_GAIN_PGA_MAX, -+ 0, rk3308_codec_alc_agc_grp_max_gain_tlv), -+ -+ SOC_SINGLE_RANGE_TLV("ALC AGC Group 1 Left Max Volume", - RK3308_ALC_L_DIG_CON09(1), -+ RK3308_AGC_MAX_GAIN_PGA_SFT, -+ RK3308_AGC_MAX_GAIN_PGA_MIN, -+ RK3308_AGC_MAX_GAIN_PGA_MAX, -+ 0, rk3308_codec_alc_agc_grp_max_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("ALC AGC Group 1 Right Max Volume", - RK3308_ALC_R_DIG_CON09(1), - RK3308_AGC_MAX_GAIN_PGA_SFT, -- RK3308_AGC_MAX_GAIN_PGA_NDB_13_5, -- RK3308_AGC_MAX_GAIN_PGA_PDB_28_5, -- 0, rk3308_codec_alc_agc_ch_max_gain_tlv), -- SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 2 Max Volume", -+ RK3308_AGC_MAX_GAIN_PGA_MIN, -+ RK3308_AGC_MAX_GAIN_PGA_MAX, -+ 0, rk3308_codec_alc_agc_grp_max_gain_tlv), -+ -+ SOC_SINGLE_RANGE_TLV("ALC AGC Group 2 Left Max Volume", - RK3308_ALC_L_DIG_CON09(2), -+ RK3308_AGC_MAX_GAIN_PGA_SFT, -+ RK3308_AGC_MAX_GAIN_PGA_MIN, -+ RK3308_AGC_MAX_GAIN_PGA_MAX, -+ 0, rk3308_codec_alc_agc_grp_max_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("ALC AGC Group 2 Right Max Volume", - RK3308_ALC_R_DIG_CON09(2), - RK3308_AGC_MAX_GAIN_PGA_SFT, -- RK3308_AGC_MAX_GAIN_PGA_NDB_13_5, -- RK3308_AGC_MAX_GAIN_PGA_PDB_28_5, -- 0, rk3308_codec_alc_agc_ch_max_gain_tlv), -- SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 3 Max Volume", -+ RK3308_AGC_MAX_GAIN_PGA_MIN, -+ RK3308_AGC_MAX_GAIN_PGA_MAX, -+ 0, rk3308_codec_alc_agc_grp_max_gain_tlv), -+ -+ SOC_SINGLE_RANGE_TLV("ALC AGC Group 3 Left Max Volume", - RK3308_ALC_L_DIG_CON09(3), -+ RK3308_AGC_MAX_GAIN_PGA_SFT, -+ RK3308_AGC_MAX_GAIN_PGA_MIN, -+ RK3308_AGC_MAX_GAIN_PGA_MAX, -+ 0, rk3308_codec_alc_agc_grp_max_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("ALC AGC Group 3 Right Max Volume", - RK3308_ALC_R_DIG_CON09(3), - RK3308_AGC_MAX_GAIN_PGA_SFT, -- RK3308_AGC_MAX_GAIN_PGA_NDB_13_5, -- RK3308_AGC_MAX_GAIN_PGA_PDB_28_5, -- 0, rk3308_codec_alc_agc_ch_max_gain_tlv), -+ RK3308_AGC_MAX_GAIN_PGA_MIN, -+ RK3308_AGC_MAX_GAIN_PGA_MAX, -+ 0, rk3308_codec_alc_agc_grp_max_gain_tlv), - - /* ALC AGC MIN */ -- SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 0 Min Volume", -+ SOC_SINGLE_RANGE_TLV("ALC AGC Group 0 Left Min Volume", - RK3308_ALC_L_DIG_CON09(0), -+ RK3308_AGC_MIN_GAIN_PGA_SFT, -+ RK3308_AGC_MIN_GAIN_PGA_MIN, -+ RK3308_AGC_MIN_GAIN_PGA_MAX, -+ 0, rk3308_codec_alc_agc_grp_min_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("ALC AGC Group 0 Right Min Volume", - RK3308_ALC_R_DIG_CON09(0), - RK3308_AGC_MIN_GAIN_PGA_SFT, -- RK3308_AGC_MIN_GAIN_PGA_NDB_18, -- RK3308_AGC_MIN_GAIN_PGA_PDB_24, -- 0, rk3308_codec_alc_agc_ch_min_gain_tlv), -- SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 1 Min Volume", -+ RK3308_AGC_MIN_GAIN_PGA_MIN, -+ RK3308_AGC_MIN_GAIN_PGA_MAX, -+ 0, rk3308_codec_alc_agc_grp_min_gain_tlv), -+ -+ SOC_SINGLE_RANGE_TLV("ALC AGC Group 1 Left Min Volume", - RK3308_ALC_L_DIG_CON09(1), -+ RK3308_AGC_MIN_GAIN_PGA_SFT, -+ RK3308_AGC_MIN_GAIN_PGA_MIN, -+ RK3308_AGC_MIN_GAIN_PGA_MAX, -+ 0, rk3308_codec_alc_agc_grp_min_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("ALC AGC Group 1 Right Min Volume", - RK3308_ALC_R_DIG_CON09(1), - RK3308_AGC_MIN_GAIN_PGA_SFT, -- RK3308_AGC_MIN_GAIN_PGA_NDB_18, -- RK3308_AGC_MIN_GAIN_PGA_PDB_24, -- 0, rk3308_codec_alc_agc_ch_min_gain_tlv), -- SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 2 Min Volume", -+ RK3308_AGC_MIN_GAIN_PGA_MIN, -+ RK3308_AGC_MIN_GAIN_PGA_MAX, -+ 0, rk3308_codec_alc_agc_grp_min_gain_tlv), -+ -+ SOC_SINGLE_RANGE_TLV("ALC AGC Group 2 Left Min Volume", - RK3308_ALC_L_DIG_CON09(2), -+ RK3308_AGC_MIN_GAIN_PGA_SFT, -+ RK3308_AGC_MIN_GAIN_PGA_MIN, -+ RK3308_AGC_MIN_GAIN_PGA_MAX, -+ 0, rk3308_codec_alc_agc_grp_min_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("ALC AGC Group 2 Right Min Volume", - RK3308_ALC_R_DIG_CON09(2), - RK3308_AGC_MIN_GAIN_PGA_SFT, -- RK3308_AGC_MIN_GAIN_PGA_NDB_18, -- RK3308_AGC_MIN_GAIN_PGA_PDB_24, -- 0, rk3308_codec_alc_agc_ch_min_gain_tlv), -- SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 3 Min Volume", -+ RK3308_AGC_MIN_GAIN_PGA_MIN, -+ RK3308_AGC_MIN_GAIN_PGA_MAX, -+ 0, rk3308_codec_alc_agc_grp_min_gain_tlv), -+ -+ SOC_SINGLE_RANGE_TLV("ALC AGC Group 3 Left Min Volume", - RK3308_ALC_L_DIG_CON09(3), -+ RK3308_AGC_MIN_GAIN_PGA_SFT, -+ RK3308_AGC_MIN_GAIN_PGA_MIN, -+ RK3308_AGC_MIN_GAIN_PGA_MAX, -+ 0, rk3308_codec_alc_agc_grp_min_gain_tlv), -+ SOC_SINGLE_RANGE_TLV("ALC AGC Group 3 Right Min Volume", - RK3308_ALC_R_DIG_CON09(3), - RK3308_AGC_MIN_GAIN_PGA_SFT, -- RK3308_AGC_MIN_GAIN_PGA_NDB_18, -- RK3308_AGC_MIN_GAIN_PGA_PDB_24, -- 0, rk3308_codec_alc_agc_ch_min_gain_tlv), -- -- /* ADC MIC */ -- SOC_SINGLE_RANGE_TLV("ADC MIC Channel 0 Left Volume", -- RK3308_ADC_ANA_CON01(0), -- RK3308_ADC_CH1_MIC_GAIN_SFT, -- RK3308_ADC_CH1_MIC_GAIN_0DB, -- RK3308_ADC_CH1_MIC_GAIN_30DB, -- 0, rk3308_codec_adc_mic_gain_tlv), -- SOC_SINGLE_RANGE_TLV("ADC MIC Channel 0 Right Volume", -- RK3308_ADC_ANA_CON01(0), -- RK3308_ADC_CH2_MIC_GAIN_SFT, -- RK3308_ADC_CH2_MIC_GAIN_0DB, -- RK3308_ADC_CH2_MIC_GAIN_30DB, -- 0, rk3308_codec_adc_mic_gain_tlv), -- SOC_SINGLE_RANGE_TLV("ADC MIC Channel 1 Left Volume", -- RK3308_ADC_ANA_CON01(1), -- RK3308_ADC_CH1_MIC_GAIN_SFT, -- RK3308_ADC_CH1_MIC_GAIN_0DB, -- RK3308_ADC_CH1_MIC_GAIN_30DB, -- 0, rk3308_codec_adc_mic_gain_tlv), -- SOC_SINGLE_RANGE_TLV("ADC MIC Channel 1 Right Volume", -- RK3308_ADC_ANA_CON01(1), -- RK3308_ADC_CH2_MIC_GAIN_SFT, -- RK3308_ADC_CH2_MIC_GAIN_0DB, -- RK3308_ADC_CH2_MIC_GAIN_30DB, -- 0, rk3308_codec_adc_mic_gain_tlv), -- SOC_SINGLE_RANGE_TLV("ADC MIC Channel 2 Left Volume", -- RK3308_ADC_ANA_CON01(2), -- RK3308_ADC_CH1_MIC_GAIN_SFT, -- RK3308_ADC_CH1_MIC_GAIN_0DB, -- RK3308_ADC_CH1_MIC_GAIN_30DB, -- 0, rk3308_codec_adc_mic_gain_tlv), -- SOC_SINGLE_RANGE_TLV("ADC MIC Channel 2 Right Volume", -- RK3308_ADC_ANA_CON01(2), -- RK3308_ADC_CH2_MIC_GAIN_SFT, -- RK3308_ADC_CH2_MIC_GAIN_0DB, -- RK3308_ADC_CH2_MIC_GAIN_30DB, -- 0, rk3308_codec_adc_mic_gain_tlv), -- SOC_SINGLE_RANGE_TLV("ADC MIC Channel 3 Left Volume", -- RK3308_ADC_ANA_CON01(3), -- RK3308_ADC_CH1_MIC_GAIN_SFT, -- RK3308_ADC_CH1_MIC_GAIN_0DB, -- RK3308_ADC_CH1_MIC_GAIN_30DB, -- 0, rk3308_codec_adc_mic_gain_tlv), -- SOC_SINGLE_RANGE_TLV("ADC MIC Channel 3 Right Volume", -- RK3308_ADC_ANA_CON01(3), -- RK3308_ADC_CH2_MIC_GAIN_SFT, -- RK3308_ADC_CH2_MIC_GAIN_0DB, -- RK3308_ADC_CH2_MIC_GAIN_30DB, -- 0, rk3308_codec_adc_mic_gain_tlv), -+ RK3308_AGC_MIN_GAIN_PGA_MIN, -+ RK3308_AGC_MIN_GAIN_PGA_MAX, -+ 0, rk3308_codec_alc_agc_grp_min_gain_tlv), -+ -+ /* ALC AGC Switch */ -+ SOC_ENUM_EXT("ALC AGC Group 0 Left Switch", rk3308_agc_enum_array[0], -+ rk3308_codec_agc_get, rk3308_codec_agc_put), -+ SOC_ENUM_EXT("ALC AGC Group 0 Right Switch", rk3308_agc_enum_array[1], -+ rk3308_codec_agc_get, rk3308_codec_agc_put), -+ SOC_ENUM_EXT("ALC AGC Group 1 Left Switch", rk3308_agc_enum_array[2], -+ rk3308_codec_agc_get, rk3308_codec_agc_put), -+ SOC_ENUM_EXT("ALC AGC Group 1 Right Switch", rk3308_agc_enum_array[3], -+ rk3308_codec_agc_get, rk3308_codec_agc_put), -+ SOC_ENUM_EXT("ALC AGC Group 2 Left Switch", rk3308_agc_enum_array[4], -+ rk3308_codec_agc_get, rk3308_codec_agc_put), -+ SOC_ENUM_EXT("ALC AGC Group 2 Right Switch", rk3308_agc_enum_array[5], -+ rk3308_codec_agc_get, rk3308_codec_agc_put), -+ SOC_ENUM_EXT("ALC AGC Group 3 Left Switch", rk3308_agc_enum_array[6], -+ rk3308_codec_agc_get, rk3308_codec_agc_put), -+ SOC_ENUM_EXT("ALC AGC Group 3 Right Switch", rk3308_agc_enum_array[7], -+ rk3308_codec_agc_get, rk3308_codec_agc_put), -+ -+ /* ALC AGC Approximate Sample Rate */ -+ SOC_ENUM_EXT("AGC Group 0 Left Approximate Sample Rate", rk3308_agc_asr_enum_array[0], -+ rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put), -+ SOC_ENUM_EXT("AGC Group 0 Right Approximate Sample Rate", rk3308_agc_asr_enum_array[1], -+ rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put), -+ SOC_ENUM_EXT("AGC Group 1 Left Approximate Sample Rate", rk3308_agc_asr_enum_array[2], -+ rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put), -+ SOC_ENUM_EXT("AGC Group 1 Right Approximate Sample Rate", rk3308_agc_asr_enum_array[3], -+ rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put), -+ SOC_ENUM_EXT("AGC Group 2 Left Approximate Sample Rate", rk3308_agc_asr_enum_array[4], -+ rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put), -+ SOC_ENUM_EXT("AGC Group 2 Right Approximate Sample Rate", rk3308_agc_asr_enum_array[5], -+ rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put), -+ SOC_ENUM_EXT("AGC Group 3 Left Approximate Sample Rate", rk3308_agc_asr_enum_array[6], -+ rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put), -+ SOC_ENUM_EXT("AGC Group 3 Right Approximate Sample Rate", rk3308_agc_asr_enum_array[7], -+ rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put), -+ -+ /* ADC MICBIAS Voltage */ -+ SOC_ENUM_EXT("ADC MICBIAS Voltage", rk3308_micbias_volts_enum_array[0], -+ rk3308_codec_micbias_volts_get, rk3308_codec_micbias_volts_put), -+ -+ /* ADC Main MICBIAS Switch */ -+ SOC_ENUM_EXT("ADC Main MICBIAS", rk3308_main_micbias_enum_array[0], -+ rk3308_codec_main_micbias_get, rk3308_codec_main_micbias_put), -+ -+ /* ADC MICBIAS1 and MICBIAS2 Switch */ -+ SOC_SINGLE("ADC MICBIAS1", RK3308_ADC_ANA_CON07(1), -+ RK3308_ADC_MIC_BIAS_BUF_SFT, 1, 0), -+ SOC_SINGLE("ADC MICBIAS2", RK3308_ADC_ANA_CON07(2), -+ RK3308_ADC_MIC_BIAS_BUF_SFT, 1, 0), -+ -+ /* ADC MIC Mute/Work Switch */ -+ SOC_ENUM_EXT("ADC MIC Group 0 Left Switch", rk3308_mic_mute_enum_array[0], -+ rk3308_codec_mic_mute_get, rk3308_codec_mic_mute_put), -+ SOC_ENUM_EXT("ADC MIC Group 0 Right Switch", rk3308_mic_mute_enum_array[1], -+ rk3308_codec_mic_mute_get, rk3308_codec_mic_mute_put), -+ SOC_ENUM_EXT("ADC MIC Group 1 Left Switch", rk3308_mic_mute_enum_array[2], -+ rk3308_codec_mic_mute_get, rk3308_codec_mic_mute_put), -+ SOC_ENUM_EXT("ADC MIC Group 1 Right Switch", rk3308_mic_mute_enum_array[3], -+ rk3308_codec_mic_mute_get, rk3308_codec_mic_mute_put), -+ SOC_ENUM_EXT("ADC MIC Group 2 Left Switch", rk3308_mic_mute_enum_array[4], -+ rk3308_codec_mic_mute_get, rk3308_codec_mic_mute_put), -+ SOC_ENUM_EXT("ADC MIC Group 2 Right Switch", rk3308_mic_mute_enum_array[5], -+ rk3308_codec_mic_mute_get, rk3308_codec_mic_mute_put), -+ SOC_ENUM_EXT("ADC MIC Group 3 Left Switch", rk3308_mic_mute_enum_array[6], -+ rk3308_codec_mic_mute_get, rk3308_codec_mic_mute_put), -+ SOC_ENUM_EXT("ADC MIC Group 3 Right Switch", rk3308_mic_mute_enum_array[7], -+ rk3308_codec_mic_mute_get, rk3308_codec_mic_mute_put), - - /* ADC ALC */ -- SOC_SINGLE_RANGE_TLV("ADC ALC Channel 0 Left Volume", -+ SOC_SINGLE_RANGE_TLV("ADC ALC Group 0 Left Volume", - RK3308_ADC_ANA_CON03(0), - RK3308_ADC_CH1_ALC_GAIN_SFT, -- RK3308_ADC_CH1_ALC_GAIN_NDB_18, -- RK3308_ADC_CH1_ALC_GAIN_PDB_28_5, -+ RK3308_ADC_CH1_ALC_GAIN_MIN, -+ RK3308_ADC_CH1_ALC_GAIN_MAX, - 0, rk3308_codec_adc_alc_gain_tlv), -- SOC_SINGLE_RANGE_TLV("ADC ALC Channel 0 Right Volume", -+ SOC_SINGLE_RANGE_TLV("ADC ALC Group 0 Right Volume", - RK3308_ADC_ANA_CON04(0), - RK3308_ADC_CH2_ALC_GAIN_SFT, -- RK3308_ADC_CH2_ALC_GAIN_NDB_18, -- RK3308_ADC_CH2_ALC_GAIN_PDB_28_5, -+ RK3308_ADC_CH2_ALC_GAIN_MIN, -+ RK3308_ADC_CH2_ALC_GAIN_MAX, - 0, rk3308_codec_adc_alc_gain_tlv), -- SOC_SINGLE_RANGE_TLV("ADC ALC Channel 1 Left Volume", -+ SOC_SINGLE_RANGE_TLV("ADC ALC Group 1 Left Volume", - RK3308_ADC_ANA_CON03(1), - RK3308_ADC_CH1_ALC_GAIN_SFT, -- RK3308_ADC_CH1_ALC_GAIN_NDB_18, -- RK3308_ADC_CH1_ALC_GAIN_PDB_28_5, -+ RK3308_ADC_CH1_ALC_GAIN_MIN, -+ RK3308_ADC_CH1_ALC_GAIN_MAX, - 0, rk3308_codec_adc_alc_gain_tlv), -- SOC_SINGLE_RANGE_TLV("ADC ALC Channel 1 Right Volume", -+ SOC_SINGLE_RANGE_TLV("ADC ALC Group 1 Right Volume", - RK3308_ADC_ANA_CON04(1), - RK3308_ADC_CH2_ALC_GAIN_SFT, -- RK3308_ADC_CH2_ALC_GAIN_NDB_18, -- RK3308_ADC_CH2_ALC_GAIN_PDB_28_5, -+ RK3308_ADC_CH2_ALC_GAIN_MIN, -+ RK3308_ADC_CH2_ALC_GAIN_MAX, - 0, rk3308_codec_adc_alc_gain_tlv), -- SOC_SINGLE_RANGE_TLV("ADC ALC Channel 2 Left Volume", -+ SOC_SINGLE_RANGE_TLV("ADC ALC Group 2 Left Volume", - RK3308_ADC_ANA_CON03(2), - RK3308_ADC_CH1_ALC_GAIN_SFT, -- RK3308_ADC_CH1_ALC_GAIN_NDB_18, -- RK3308_ADC_CH1_ALC_GAIN_PDB_28_5, -+ RK3308_ADC_CH1_ALC_GAIN_MIN, -+ RK3308_ADC_CH1_ALC_GAIN_MAX, - 0, rk3308_codec_adc_alc_gain_tlv), -- SOC_SINGLE_RANGE_TLV("ADC ALC Channel 2 Right Volume", -+ SOC_SINGLE_RANGE_TLV("ADC ALC Group 2 Right Volume", - RK3308_ADC_ANA_CON04(2), - RK3308_ADC_CH2_ALC_GAIN_SFT, -- RK3308_ADC_CH2_ALC_GAIN_NDB_18, -- RK3308_ADC_CH2_ALC_GAIN_PDB_28_5, -+ RK3308_ADC_CH2_ALC_GAIN_MIN, -+ RK3308_ADC_CH2_ALC_GAIN_MAX, - 0, rk3308_codec_adc_alc_gain_tlv), -- SOC_SINGLE_RANGE_TLV("ADC ALC Channel 3 Left Volume", -+ SOC_SINGLE_RANGE_TLV("ADC ALC Group 3 Left Volume", - RK3308_ADC_ANA_CON03(3), - RK3308_ADC_CH1_ALC_GAIN_SFT, -- RK3308_ADC_CH1_ALC_GAIN_NDB_18, -- RK3308_ADC_CH1_ALC_GAIN_PDB_28_5, -+ RK3308_ADC_CH1_ALC_GAIN_MIN, -+ RK3308_ADC_CH1_ALC_GAIN_MAX, - 0, rk3308_codec_adc_alc_gain_tlv), -- SOC_SINGLE_RANGE_TLV("ADC ALC Channel 3 Right Volume", -+ SOC_SINGLE_RANGE_TLV("ADC ALC Group 3 Right Volume", - RK3308_ADC_ANA_CON04(3), - RK3308_ADC_CH2_ALC_GAIN_SFT, -- RK3308_ADC_CH2_ALC_GAIN_NDB_18, -- RK3308_ADC_CH2_ALC_GAIN_PDB_28_5, -+ RK3308_ADC_CH2_ALC_GAIN_MIN, -+ RK3308_ADC_CH2_ALC_GAIN_MAX, - 0, rk3308_codec_adc_alc_gain_tlv), - -- /* DAC */ -- SOC_SINGLE_RANGE_TLV("DAC Left Volume", -- RK3308_DAC_ANA_CON04, -- RK3308_DAC_L_GAIN_SFT, -- RK3308_DAC_L_GAIN_0DB, -- RK3308_DAC_L_GAIN_PDB_6, -- 0, rk3308_codec_dac_gain_tlv), -- SOC_SINGLE_RANGE_TLV("DAC Right Volume", -- RK3308_DAC_ANA_CON04, -- RK3308_DAC_R_GAIN_SFT, -- RK3308_DAC_R_GAIN_0DB, -- RK3308_DAC_R_GAIN_PDB_6, -- 0, rk3308_codec_dac_gain_tlv), -+ /* ADC High Pass Filter */ -+ SOC_ENUM_EXT("ADC Group 0 HPF Cut-off", rk3308_hpf_enum_array[0], -+ rk3308_codec_hpf_get, rk3308_codec_hpf_put), -+ SOC_ENUM_EXT("ADC Group 1 HPF Cut-off", rk3308_hpf_enum_array[1], -+ rk3308_codec_hpf_get, rk3308_codec_hpf_put), -+ SOC_ENUM_EXT("ADC Group 2 HPF Cut-off", rk3308_hpf_enum_array[2], -+ rk3308_codec_hpf_get, rk3308_codec_hpf_put), -+ SOC_ENUM_EXT("ADC Group 3 HPF Cut-off", rk3308_hpf_enum_array[3], -+ rk3308_codec_hpf_get, rk3308_codec_hpf_put), -+ -+ /* DAC LINEOUT */ -+ SOC_SINGLE_TLV("DAC LINEOUT Left Volume", -+ RK3308_DAC_ANA_CON04, -+ RK3308_DAC_L_LINEOUT_GAIN_SFT, -+ RK3308_DAC_L_LINEOUT_GAIN_MAX, -+ 0, rk3308_codec_dac_lineout_gain_tlv), -+ SOC_SINGLE_TLV("DAC LINEOUT Right Volume", -+ RK3308_DAC_ANA_CON04, -+ RK3308_DAC_R_LINEOUT_GAIN_SFT, -+ RK3308_DAC_R_LINEOUT_GAIN_MAX, -+ 0, rk3308_codec_dac_lineout_gain_tlv), - - /* DAC HPOUT */ -- SOC_SINGLE_RANGE_TLV("DAC HPOUT Left Volume", -- RK3308_DAC_ANA_CON05, -- RK3308_DAC_L_HPOUT_GAIN_SFT, -- RK3308_DAC_L_HPOUT_GAIN_NDB_39, -- RK3308_DAC_L_HPOUT_GAIN_PDB_6, -- 0, rk3308_codec_dac_hpout_gain_tlv), -- SOC_SINGLE_RANGE_TLV("DAC HPOUT Right Volume", -- RK3308_DAC_ANA_CON06, -- RK3308_DAC_R_HPOUT_GAIN_SFT, -- RK3308_DAC_R_HPOUT_GAIN_NDB_39, -- RK3308_DAC_R_HPOUT_GAIN_PDB_6, -- 0, rk3308_codec_dac_hpout_gain_tlv), -+ SOC_SINGLE_EXT_TLV("DAC HPOUT Left Volume", -+ RK3308_DAC_ANA_CON05, -+ RK3308_DAC_L_HPOUT_GAIN_SFT, -+ RK3308_DAC_L_HPOUT_GAIN_MAX, -+ 0, -+ rk3308_codec_hpout_l_get_tlv, -+ rk3308_codec_hpout_l_put_tlv, -+ rk3308_codec_dac_hpout_gain_tlv), -+ SOC_SINGLE_EXT_TLV("DAC HPOUT Right Volume", -+ RK3308_DAC_ANA_CON06, -+ RK3308_DAC_R_HPOUT_GAIN_SFT, -+ RK3308_DAC_R_HPOUT_GAIN_MAX, -+ 0, -+ rk3308_codec_hpout_r_get_tlv, -+ rk3308_codec_hpout_r_put_tlv, -+ rk3308_codec_dac_hpout_gain_tlv), - - /* DAC HPMIX */ - SOC_SINGLE_RANGE_TLV("DAC HPMIX Left Volume", -- RK3308_DAC_ANA_CON05, -+ RK3308_DAC_ANA_CON12, - RK3308_DAC_L_HPMIX_GAIN_SFT, -- RK3308_DAC_L_HPMIX_GAIN_NDB_6, -- RK3308_DAC_L_HPMIX_GAIN_0DB, -+ RK3308_DAC_L_HPMIX_GAIN_MIN, -+ RK3308_DAC_L_HPMIX_GAIN_MAX, - 0, rk3308_codec_dac_hpmix_gain_tlv), - SOC_SINGLE_RANGE_TLV("DAC HPMIX Right Volume", -- RK3308_DAC_ANA_CON05, -+ RK3308_DAC_ANA_CON12, - RK3308_DAC_R_HPMIX_GAIN_SFT, -- RK3308_DAC_R_HPMIX_GAIN_NDB_6, -- RK3308_DAC_R_HPMIX_GAIN_0DB, -+ RK3308_DAC_R_HPMIX_GAIN_MIN, -+ RK3308_DAC_R_HPMIX_GAIN_MAX, - 0, rk3308_codec_dac_hpmix_gain_tlv), - }; - --static void rk3308_speaker_ctl(struct rk3308_codec_priv *rk3308, int on) -+static int rk3308_codec_agc_get(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) - { -- gpiod_direction_output(rk3308->spk_ctl_gpio, on); -+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; -+ -+ if (e->reg < 0 || e->reg > ADC_LR_GROUP_MAX - 1) { -+ dev_err(rk3308->plat_dev, -+ "%s: Invalid ADC grp: %d\n", __func__, e->reg); -+ return -EINVAL; -+ } -+ -+ if (e->shift_l) -+ ucontrol->value.integer.value[0] = rk3308->agc_r[e->reg]; -+ else -+ ucontrol->value.integer.value[0] = rk3308->agc_l[e->reg]; -+ -+ return 0; - } - --static int rk3308_codec_reset(struct snd_soc_codec *codec) -+static int rk3308_codec_agc_put(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) - { -+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; -+ unsigned int value = ucontrol->value.integer.value[0]; -+ int grp = e->reg; - -- reset_control_assert(rk3308->reset); -- usleep_range(200, 300); /* estimated value */ -- reset_control_deassert(rk3308->reset); -+ if (e->reg < 0 || e->reg > ADC_LR_GROUP_MAX - 1) { -+ dev_err(rk3308->plat_dev, -+ "%s: Invalid ADC grp: %d\n", __func__, e->reg); -+ return -EINVAL; -+ } - -- regmap_write(rk3308->regmap, RK3308_GLB_CON, 0x00); -- usleep_range(200, 300); /* estimated value */ -- regmap_write(rk3308->regmap, RK3308_GLB_CON, -- RK3308_SYS_WORK | -- RK3308_DAC_DIG_WORK | -- RK3308_ADC_DIG_WORK); -+ if (value) { -+ /* ALC AGC On */ -+ if (e->shift_l) { -+ /* ALC AGC Right On */ -+ regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON09(grp), -+ RK3308_AGC_FUNC_SEL_MSK, -+ RK3308_AGC_FUNC_SEL_EN); -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON11(grp), -+ RK3308_ADC_ALCR_CON_GAIN_PGAR_MSK, -+ RK3308_ADC_ALCR_CON_GAIN_PGAR_EN); -+ -+ rk3308->agc_r[e->reg] = 1; -+ } else { -+ /* ALC AGC Left On */ -+ regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON09(grp), -+ RK3308_AGC_FUNC_SEL_MSK, -+ RK3308_AGC_FUNC_SEL_EN); -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON11(grp), -+ RK3308_ADC_ALCL_CON_GAIN_PGAL_MSK, -+ RK3308_ADC_ALCL_CON_GAIN_PGAL_EN); -+ -+ rk3308->agc_l[e->reg] = 1; -+ } -+ } else { -+ /* ALC AGC Off */ -+ if (e->shift_l) { -+ /* ALC AGC Right Off */ -+ regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON09(grp), -+ RK3308_AGC_FUNC_SEL_MSK, -+ RK3308_AGC_FUNC_SEL_DIS); -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON11(grp), -+ RK3308_ADC_ALCR_CON_GAIN_PGAR_MSK, -+ RK3308_ADC_ALCR_CON_GAIN_PGAR_DIS); -+ -+ rk3308->agc_r[e->reg] = 0; -+ } else { -+ /* ALC AGC Left Off */ -+ regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON09(grp), -+ RK3308_AGC_FUNC_SEL_MSK, -+ RK3308_AGC_FUNC_SEL_DIS); -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON11(grp), -+ RK3308_ADC_ALCL_CON_GAIN_PGAL_MSK, -+ RK3308_ADC_ALCL_CON_GAIN_PGAL_DIS); -+ -+ rk3308->agc_l[e->reg] = 0; -+ } -+ } - - return 0; - } - --static int rk3308_set_bias_level(struct snd_soc_codec *codec, -- enum snd_soc_bias_level level) -+static int rk3308_codec_agc_asr_get(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) - { -- switch (level) { -- case SND_SOC_BIAS_ON: -- break; -- -- case SND_SOC_BIAS_PREPARE: -- break; -+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; -+ unsigned int value; -+ int grp = e->reg; - -- case SND_SOC_BIAS_STANDBY: -- case SND_SOC_BIAS_OFF: -- break; -+ if (e->reg < 0 || e->reg > ADC_LR_GROUP_MAX - 1) { -+ dev_err(rk3308->plat_dev, -+ "%s: Invalid ADC grp: %d\n", __func__, e->reg); -+ return -EINVAL; - } - -- snd_soc_codec_force_bias_level(codec, level); -+ if (e->shift_l) { -+ regmap_read(rk3308->regmap, RK3308_ALC_R_DIG_CON04(grp), &value); -+ rk3308->agc_asr_r[e->reg] = value >> RK3308_AGC_APPROX_RATE_SFT; -+ ucontrol->value.integer.value[0] = rk3308->agc_asr_r[e->reg]; -+ } else { -+ regmap_read(rk3308->regmap, RK3308_ALC_L_DIG_CON04(grp), &value); -+ rk3308->agc_asr_l[e->reg] = value >> RK3308_AGC_APPROX_RATE_SFT; -+ ucontrol->value.integer.value[0] = rk3308->agc_asr_l[e->reg]; -+ } - - return 0; - } - --static int rk3308_set_dai_fmt(struct snd_soc_dai *codec_dai, -- unsigned int fmt) -+static int rk3308_codec_agc_asr_put(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) - { -- struct snd_soc_codec *codec = codec_dai->codec; -+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -- unsigned int adc_aif1 = 0, adc_aif2 = 0, dac_aif1 = 0, dac_aif2 = 0; -- int ch = rk3308->adc_ch; -+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; -+ unsigned int value; -+ int grp = e->reg; - -- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { -- case SND_SOC_DAIFMT_CBS_CFS: -- adc_aif2 |= RK3308_ADC_IO_MODE_SLAVE; -- adc_aif2 |= RK3308_ADC_MODE_SLAVE; -- dac_aif2 |= RK3308_DAC_IO_MODE_SLAVE; -- dac_aif2 |= RK3308_DAC_MODE_SLAVE; -- break; -- case SND_SOC_DAIFMT_CBM_CFM: -- adc_aif2 |= RK3308_ADC_IO_MODE_MASTER; -- adc_aif2 |= RK3308_ADC_MODE_MASTER; -- dac_aif2 |= RK3308_DAC_IO_MODE_MASTER; -- dac_aif2 |= RK3308_DAC_MODE_MASTER; -- break; -- default: -+ if (e->reg < 0 || e->reg > ADC_LR_GROUP_MAX - 1) { -+ dev_err(rk3308->plat_dev, -+ "%s: Invalid ADC grp: %d\n", __func__, e->reg); - return -EINVAL; - } - -- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { -- case SND_SOC_DAIFMT_DSP_A: -- adc_aif1 |= RK3308_ADC_I2S_MODE_PCM; -- dac_aif1 |= RK3308_DAC_I2S_MODE_PCM; -- break; -- case SND_SOC_DAIFMT_I2S: -- adc_aif1 |= RK3308_ADC_I2S_MODE_I2S; -- dac_aif1 |= RK3308_DAC_I2S_MODE_I2S; -- break; -- case SND_SOC_DAIFMT_RIGHT_J: -- adc_aif1 |= RK3308_ADC_I2S_MODE_RJ; -- dac_aif1 |= RK3308_DAC_I2S_MODE_RJ; -- break; -- case SND_SOC_DAIFMT_LEFT_J: -- adc_aif1 |= RK3308_ADC_I2S_MODE_RJ; -- dac_aif1 |= RK3308_DAC_I2S_MODE_LJ; -- break; -- default: -- return -EINVAL; -+ value = ucontrol->value.integer.value[0] << RK3308_AGC_APPROX_RATE_SFT; -+ -+ if (e->shift_l) { -+ /* ALC AGC Right Approximate Sample Rate */ -+ regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON04(grp), -+ RK3308_AGC_APPROX_RATE_MSK, -+ value); -+ rk3308->agc_asr_r[e->reg] = ucontrol->value.integer.value[0]; -+ } else { -+ /* ALC AGC Left Approximate Sample Rate */ -+ regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON04(grp), -+ RK3308_AGC_APPROX_RATE_MSK, -+ value); -+ rk3308->agc_asr_l[e->reg] = ucontrol->value.integer.value[0]; - } - -- switch (fmt & SND_SOC_DAIFMT_INV_MASK) { -- case SND_SOC_DAIFMT_NB_NF: -- adc_aif1 |= RK3308_ADC_I2S_LRC_POL_NORMAL; -- adc_aif2 |= RK3308_ADC_I2S_BIT_CLK_POL_NORMAL; -- dac_aif1 |= RK3308_DAC_I2S_LRC_POL_NORMAL; -- dac_aif2 |= RK3308_DAC_I2S_BIT_CLK_POL_NORMAL; -- break; -- case SND_SOC_DAIFMT_IB_IF: -- adc_aif1 |= RK3308_ADC_I2S_LRC_POL_REVERSAL; -- adc_aif2 |= RK3308_ADC_I2S_BIT_CLK_POL_REVERSAL; -- dac_aif1 |= RK3308_DAC_I2S_LRC_POL_REVERSAL; -- dac_aif2 |= RK3308_DAC_I2S_BIT_CLK_POL_REVERSAL; -- break; -- case SND_SOC_DAIFMT_IB_NF: -- adc_aif1 |= RK3308_ADC_I2S_LRC_POL_NORMAL; -- adc_aif2 |= RK3308_ADC_I2S_BIT_CLK_POL_REVERSAL; -- dac_aif1 |= RK3308_DAC_I2S_LRC_POL_NORMAL; -- dac_aif2 |= RK3308_DAC_I2S_BIT_CLK_POL_REVERSAL; -- break; -- case SND_SOC_DAIFMT_NB_IF: -- adc_aif1 |= RK3308_ADC_I2S_LRC_POL_REVERSAL; -- adc_aif2 |= RK3308_ADC_I2S_BIT_CLK_POL_NORMAL; -- dac_aif1 |= RK3308_DAC_I2S_LRC_POL_REVERSAL; -- dac_aif2 |= RK3308_DAC_I2S_BIT_CLK_POL_NORMAL; -- break; -- default: -+ return 0; -+} -+ -+static int rk3308_codec_mic_mute_get(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) -+{ -+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; -+ unsigned int value; -+ int grp = e->reg; -+ -+ if (e->reg < 0 || e->reg > ADC_LR_GROUP_MAX - 1) { -+ dev_err(rk3308->plat_dev, -+ "%s: Invalid ADC grp: %d\n", __func__, e->reg); - return -EINVAL; - } - -- regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON01(ch), -- RK3308_ADC_I2S_LRC_POL_MSK | -- RK3308_ADC_I2S_MODE_MSK, -- adc_aif1); -- regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON02(ch), -- RK3308_ADC_IO_MODE_MSK | -- RK3308_ADC_MODE_MSK | -- RK3308_ADC_I2S_BIT_CLK_POL_MSK, -- adc_aif2); -- -- regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON01, -- RK3308_DAC_I2S_LRC_POL_MSK | -- RK3308_DAC_I2S_MODE_MSK, -- dac_aif1); -- regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON02, -- RK3308_DAC_IO_MODE_MSK | -- RK3308_DAC_MODE_MSK | -- RK3308_DAC_I2S_BIT_CLK_POL_MSK, -- dac_aif2); -+ if (e->shift_l) { -+ /* ADC MIC Right Mute/Work Infos */ -+ regmap_read(rk3308->regmap, RK3308_ADC_DIG_CON03(grp), &value); -+ rk3308->mic_mute_r[e->reg] = (value & RK3308_ADC_R_CH_BIST_SINE) >> -+ RK3308_ADC_R_CH_BIST_SFT; -+ ucontrol->value.integer.value[0] = rk3308->mic_mute_r[e->reg]; -+ } else { -+ /* ADC MIC Left Mute/Work Infos */ -+ regmap_read(rk3308->regmap, RK3308_ADC_DIG_CON03(grp), &value); -+ rk3308->mic_mute_l[e->reg] = (value & RK3308_ADC_L_CH_BIST_SINE) >> -+ RK3308_ADC_L_CH_BIST_SFT; -+ ucontrol->value.integer.value[0] = rk3308->mic_mute_l[e->reg]; -+ } - - return 0; - } - --static int rk3308_hw_params(struct snd_pcm_substream *substream, -- struct snd_pcm_hw_params *params, -- struct snd_soc_dai *dai) -+static int rk3308_codec_mic_mute_put(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) - { -- struct snd_soc_codec *codec = dai->codec; -+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -- unsigned int adc_aif1 = 0, adc_aif2 = 0, dac_aif1 = 0, dac_aif2 = 0; -- int ch = rk3308->adc_ch; -+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; -+ unsigned int value; -+ int grp = e->reg; - -- switch (params_format(params)) { -- case SNDRV_PCM_FORMAT_S16_LE: -- adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_16BITS; -- dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_16BITS; -- break; -- case SNDRV_PCM_FORMAT_S20_3LE: -- adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_20BITS; -- dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_20BITS; -- break; -- case SNDRV_PCM_FORMAT_S24_LE: -- adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_24BITS; -- dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_24BITS; -- break; -- case SNDRV_PCM_FORMAT_S32_LE: -- adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_32BITS; -- dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_32BITS; -- break; -- default: -+ if (e->reg < 0 || e->reg > ADC_LR_GROUP_MAX - 1) { -+ dev_err(rk3308->plat_dev, -+ "%s: Invalid ADC grp: %d\n", __func__, e->reg); - return -EINVAL; - } - -- switch (params_channels(params)) { -- case 1: -- adc_aif1 |= RK3308_ADC_I2S_MONO; -- break; -- case 2: -- adc_aif1 |= RK3308_ADC_I2S_STEREO; -- break; -- default: -- return -EINVAL; -+ if (e->shift_l) { -+ /* ADC MIC Right Mute/Work Configuration */ -+ value = ucontrol->value.integer.value[0] << RK3308_ADC_R_CH_BIST_SFT; -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON03(grp), -+ RK3308_ADC_R_CH_BIST_SINE, -+ value); -+ rk3308->mic_mute_r[e->reg] = ucontrol->value.integer.value[0]; -+ } else { -+ /* ADC MIC Left Mute/Work Configuration */ -+ value = ucontrol->value.integer.value[0] << RK3308_ADC_L_CH_BIST_SFT; -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON03(grp), -+ RK3308_ADC_L_CH_BIST_SINE, -+ value); -+ rk3308->mic_mute_l[e->reg] = ucontrol->value.integer.value[0]; - } - -- adc_aif1 |= RK3308_ADC_I2S_LR_NORMAL; -- adc_aif2 |= RK3308_ADC_I2S_WORK; -- dac_aif1 |= RK3308_DAC_I2S_LR_NORMAL; -- dac_aif2 |= RK3308_DAC_I2S_WORK; -+ return 0; -+} - -- regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON01(ch), -- RK3308_ADC_I2S_VALID_LEN_MSK | -- RK3308_ADC_I2S_LR_MSK | -- RK3308_ADC_I2S_TYPE_MSK, -- adc_aif1); -- regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON02(ch), -- RK3308_ADC_I2S_MSK, -- adc_aif2); -+static int rk3308_codec_micbias_volts_get(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) -+{ -+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); - -- regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON01, -- RK3308_DAC_I2S_VALID_LEN_MSK | -- RK3308_DAC_I2S_LR_MSK, -- dac_aif1); -- regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON02, -- RK3308_DAC_I2S_MSK, -- dac_aif2); -+ ucontrol->value.integer.value[0] = rk3308->micbias_volt; - - return 0; - } - --static int rk3308_digital_mute(struct snd_soc_dai *dai, int mute) -+static int rk3308_codec_micbias_volts_put(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) - { -+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ unsigned int volt = ucontrol->value.integer.value[0]; -+ int ret; -+ -+ ret = check_micbias(volt); -+ if (ret < 0) { -+ dev_err(rk3308->plat_dev, "The invalid micbias volt: %d\n", -+ volt); -+ return ret; -+ } -+ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(0), -+ RK3308_ADC_LEVEL_RANGE_MICBIAS_MSK, -+ volt); -+ -+ rk3308->micbias_volt = volt; -+ - return 0; - } - --static int rk3308_codec_dac_enable(struct rk3308_codec_priv *rk3308) -+static int rk3308_codec_main_micbias_get(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) - { -- /* Step 01 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON00, -- RK3308_DAC_CURRENT_MSK, -- RK3308_DAC_CURRENT_EN); -- -- /* Step 02 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01, -- RK3308_DAC_BUF_REF_L_MSK | -- RK3308_DAC_BUF_REF_R_MSK, -- RK3308_DAC_BUF_REF_L_EN | -- RK3308_DAC_BUF_REF_R_EN); -+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); - -- /* Step 03 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01, -- RK3308_DAC_POP_SOUND_L_MSK | -- RK3308_DAC_POP_SOUND_R_MSK, -- RK3308_DAC_POP_SOUND_L_WORK | -- RK3308_DAC_POP_SOUND_R_WORK); -+ ucontrol->value.integer.value[0] = rk3308->enable_micbias; - -- /* Step 04 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON13, -- RK3308_DAC_L_HPMIX_EN | RK3308_DAC_R_HPMIX_EN, -- RK3308_DAC_L_HPMIX_EN | RK3308_DAC_R_HPMIX_EN); -+ return 0; -+} - -- /* Step 05 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON13, -- RK3308_DAC_L_HPMIX_WORK | RK3308_DAC_R_HPMIX_WORK, -- RK3308_DAC_L_HPMIX_WORK | RK3308_DAC_R_HPMIX_WORK); -+static int rk3308_codec_main_micbias_put(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) -+{ -+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ unsigned int on = ucontrol->value.integer.value[0]; -+ -+ if (on) { -+ if (!rk3308->enable_micbias) -+ rk3308_codec_micbias_enable(rk3308, rk3308->micbias_volt); -+ } else { -+ if (rk3308->enable_micbias) -+ rk3308_codec_micbias_disable(rk3308); -+ } - -- /* Step 06 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04, -- RK3308_DAC_L_LINEOUT_EN | RK3308_DAC_R_LINEOUT_EN, -- RK3308_DAC_L_LINEOUT_EN | RK3308_DAC_R_LINEOUT_EN); -+ return 0; -+} - -- /* Step 07 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03, -- RK3308_DAC_L_HPOUT_EN | RK3308_DAC_R_HPOUT_EN, -- RK3308_DAC_L_HPOUT_EN | RK3308_DAC_R_HPOUT_EN); -+static int rk3308_codec_mic_gain_get(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) -+{ -+ return snd_soc_get_volsw_range(kcontrol, ucontrol); -+} - -- /* Step 08 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03, -- RK3308_DAC_L_HPOUT_WORK | RK3308_DAC_R_HPOUT_WORK, -- RK3308_DAC_L_HPOUT_WORK | RK3308_DAC_R_HPOUT_WORK); -+static int rk3308_codec_mic_gain_put(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) -+{ -+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ unsigned int gain = ucontrol->value.integer.value[0]; - -- /* Step 09 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02, -- RK3308_DAC_L_REF_EN | RK3308_DAC_R_REF_EN, -- RK3308_DAC_L_REF_EN | RK3308_DAC_R_REF_EN); -+ if (gain > RK3308_ADC_CH1_MIC_GAIN_MAX) { -+ dev_err(rk3308->plat_dev, "%s: invalid mic gain: %d\n", -+ __func__, gain); -+ return -EINVAL; -+ } - -- /* Step 10 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02, -- RK3308_DAC_L_CLK_EN | RK3308_DAC_R_CLK_EN, -- RK3308_DAC_L_CLK_EN | RK3308_DAC_R_CLK_EN); -+ if (rk3308->codec_ver == ACODEC_VERSION_A) { -+ /* -+ * From the TRM, there are only suupport 0dB(gain==0) and -+ * 20dB(gain==3) on the codec version A. -+ */ -+ if (!(gain == 0 || gain == RK3308_ADC_CH1_MIC_GAIN_MAX)) { -+ dev_err(rk3308->plat_dev, -+ "version A doesn't supported: %d, expect: 0,%d\n", -+ gain, RK3308_ADC_CH1_MIC_GAIN_MAX); -+ return 0; -+ } -+ } - -- /* Step 11 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02, -- RK3308_DAC_L_DAC_EN | RK3308_DAC_R_DAC_EN, -- RK3308_DAC_L_DAC_EN | RK3308_DAC_R_DAC_EN); -+ return snd_soc_put_volsw_range(kcontrol, ucontrol); -+} - -- /* Step 12 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02, -- RK3308_DAC_L_DAC_WORK | RK3308_DAC_R_DAC_WORK, -- RK3308_DAC_L_DAC_WORK | RK3308_DAC_R_DAC_WORK); -+static int rk3308_codec_hpf_get(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) -+{ -+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; -+ unsigned int value; - -- /* Step 13 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON12, -- RK3308_DAC_L_HPMIX_SEL_MSK | -- RK3308_DAC_R_HPMIX_SEL_MSK, -- RK3308_DAC_L_HPMIX_I2S | -- RK3308_DAC_R_HPMIX_I2S); -+ if (e->reg < 0 || e->reg > ADC_LR_GROUP_MAX - 1) { -+ dev_err(rk3308->plat_dev, -+ "%s: Invalid ADC grp: %d\n", __func__, e->reg); -+ return -EINVAL; -+ } - -- /* Step 14 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON13, -- RK3308_DAC_L_HPMIX_UNMUTE | -- RK3308_DAC_R_HPMIX_UNMUTE, -- RK3308_DAC_L_HPMIX_UNMUTE | -- RK3308_DAC_R_HPMIX_UNMUTE); -+ regmap_read(rk3308->regmap, RK3308_ADC_DIG_CON04(e->reg), &value); -+ if (value & RK3308_ADC_HPF_PATH_MSK) -+ rk3308->hpf_cutoff[e->reg] = 0; -+ else -+ rk3308->hpf_cutoff[e->reg] = 1; - -- /* Step 15 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON12, -- RK3308_DAC_L_HPMIX_GAIN_MSK | -- RK3308_DAC_R_HPMIX_GAIN_MSK, -- RK3308_DAC_L_HPMIX_GAIN_0DB | -- RK3308_DAC_R_HPMIX_GAIN_0DB); -+ ucontrol->value.integer.value[0] = rk3308->hpf_cutoff[e->reg]; - -- /* Step 16 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03, -- RK3308_DAC_L_HPOUT_UNMUTE | -- RK3308_DAC_R_HPOUT_UNMUTE, -- RK3308_DAC_L_HPOUT_UNMUTE | -- RK3308_DAC_R_HPOUT_UNMUTE); -+ return 0; -+} - -- /* Step 17 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04, -- RK3308_DAC_L_LINEOUT_UNMUTE | -- RK3308_DAC_R_LINEOUT_UNMUTE, -- RK3308_DAC_L_LINEOUT_UNMUTE | -- RK3308_DAC_R_LINEOUT_UNMUTE); -+static int rk3308_codec_hpf_put(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) -+{ -+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; -+ unsigned int value = ucontrol->value.integer.value[0]; - -- /* Step 18 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON05, -- RK3308_DAC_L_HPOUT_GAIN_MSK, -- RK3308_DAC_L_HPOUT_GAIN_0DB); -+ if (e->reg < 0 || e->reg > ADC_LR_GROUP_MAX - 1) { -+ dev_err(rk3308->plat_dev, -+ "%s: Invalid ADC grp: %d\n", __func__, e->reg); -+ return -EINVAL; -+ } - -- /* Step 18 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON06, -- RK3308_DAC_R_HPOUT_GAIN_MSK, -- RK3308_DAC_R_HPOUT_GAIN_0DB); -+ if (value) { -+ /* Enable high pass filter for ADCs */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON04(e->reg), -+ RK3308_ADC_HPF_PATH_MSK, -+ RK3308_ADC_HPF_PATH_EN); -+ } else { -+ /* Disable high pass filter for ADCs. */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON04(e->reg), -+ RK3308_ADC_HPF_PATH_MSK, -+ RK3308_ADC_HPF_PATH_DIS); -+ } - -- /* Step 19 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04, -- RK3308_DAC_L_GAIN_MSK | RK3308_DAC_R_GAIN_MSK, -- RK3308_DAC_L_GAIN_0DB | RK3308_DAC_R_GAIN_0DB); -+ rk3308->hpf_cutoff[e->reg] = value; - - return 0; - } - --static int rk3308_codec_dac_disable(struct rk3308_codec_priv *rk3308) -+static int rk3308_codec_hpout_l_get_tlv(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) - { -- /* Step 01 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04, -- RK3308_DAC_L_GAIN_MSK | RK3308_DAC_R_GAIN_MSK, -- RK3308_DAC_L_GAIN_0DB | RK3308_DAC_R_GAIN_0DB); -- -- /* -- * Step 02 -- * -- * Note1. In the step2, adjusting the register step by step to the -- * appropriate value and taking 20ms as time step -- */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON05, -- RK3308_DAC_L_HPOUT_GAIN_MSK, -- RK3308_DAC_L_HPOUT_GAIN_NDB_39); -- -- /* Step 02 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON06, -- RK3308_DAC_R_HPOUT_GAIN_MSK, -- RK3308_DAC_R_HPOUT_GAIN_NDB_39); -+ return snd_soc_get_volsw_range(kcontrol, ucontrol); -+} - -- /* Step 03 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON13, -- RK3308_DAC_L_HPMIX_UNMUTE | -- RK3308_DAC_R_HPMIX_UNMUTE, -- RK3308_DAC_L_HPMIX_MUTE | -- RK3308_DAC_R_HPMIX_MUTE); -+static int rk3308_codec_hpout_l_put_tlv(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) -+{ -+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ unsigned int dgain = ucontrol->value.integer.value[0]; - -- /* Step 04 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON12, -- RK3308_DAC_L_HPMIX_SEL_MSK | -- RK3308_DAC_R_HPMIX_SEL_MSK, -- RK3308_DAC_L_HPMIX_NONE | -- RK3308_DAC_R_HPMIX_NONE); -+ if (dgain > RK3308_DAC_L_HPOUT_GAIN_MAX) { -+ dev_err(rk3308->plat_dev, "%s: invalid l_dgain: %d\n", -+ __func__, dgain); -+ return -EINVAL; -+ } - -- /* Step 05 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03, -- RK3308_DAC_L_HPOUT_UNMUTE | -- RK3308_DAC_R_HPOUT_UNMUTE, -- RK3308_DAC_L_HPOUT_MUTE | -- RK3308_DAC_R_HPOUT_MUTE); -+ rk3308->hpout_l_dgain = dgain; - -- /* Step 06 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02, -- RK3308_DAC_L_DAC_WORK | RK3308_DAC_R_DAC_WORK, -- RK3308_DAC_L_DAC_INIT | RK3308_DAC_R_DAC_INIT); -+ return snd_soc_put_volsw_range(kcontrol, ucontrol); -+} - -- /* Step 07 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03, -- RK3308_DAC_L_HPOUT_EN | RK3308_DAC_R_HPOUT_EN, -- RK3308_DAC_L_HPOUT_DIS | RK3308_DAC_R_HPOUT_DIS); -+static int rk3308_codec_hpout_r_get_tlv(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) -+{ -+ return snd_soc_get_volsw_range(kcontrol, ucontrol); -+} - -- /* Step 08 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04, -- RK3308_DAC_L_LINEOUT_UNMUTE | -- RK3308_DAC_R_LINEOUT_UNMUTE, -- RK3308_DAC_L_LINEOUT_MUTE | -- RK3308_DAC_R_LINEOUT_MUTE); -+static int rk3308_codec_hpout_r_put_tlv(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) -+{ -+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ unsigned int dgain = ucontrol->value.integer.value[0]; - -- /* Step 09 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04, -- RK3308_DAC_L_LINEOUT_EN | RK3308_DAC_R_LINEOUT_EN, -- RK3308_DAC_L_LINEOUT_DIS | RK3308_DAC_R_LINEOUT_DIS); -+ if (dgain > RK3308_DAC_R_HPOUT_GAIN_MAX) { -+ dev_err(rk3308->plat_dev, "%s: invalid r_dgain: %d\n", -+ __func__, dgain); -+ return -EINVAL; -+ } - -- /* Step 10 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON13, -- RK3308_DAC_L_HPMIX_EN | RK3308_DAC_R_HPMIX_EN, -- RK3308_DAC_L_HPMIX_DIS | RK3308_DAC_R_HPMIX_DIS); -+ rk3308->hpout_r_dgain = dgain; - -- /* Step 11 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02, -- RK3308_DAC_L_DAC_EN | RK3308_DAC_R_DAC_EN, -- RK3308_DAC_L_DAC_DIS | RK3308_DAC_R_DAC_DIS); -+ return snd_soc_put_volsw_range(kcontrol, ucontrol); -+} - -- /* Step 12 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02, -- RK3308_DAC_L_CLK_EN | RK3308_DAC_R_CLK_EN, -- RK3308_DAC_L_CLK_DIS | RK3308_DAC_R_CLK_DIS); -+static u32 to_mapped_grp(struct rk3308_codec_priv *rk3308, int idx) -+{ -+ return rk3308->i2s_sdis[idx]; -+} - -- /* Step 13 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02, -- RK3308_DAC_L_REF_EN | RK3308_DAC_R_REF_EN, -- RK3308_DAC_L_REF_DIS | RK3308_DAC_R_REF_DIS); -+static bool adc_for_each_grp(struct rk3308_codec_priv *rk3308, -+ int type, int idx, u32 *grp) -+{ -+ if (type == ADC_TYPE_NORMAL) { -+ u32 mapped_grp = to_mapped_grp(rk3308, idx); -+ int max_grps; -+ -+ if (rk3308->enable_all_adcs) -+ max_grps = ADC_LR_GROUP_MAX; -+ else -+ max_grps = rk3308->used_adc_grps; -+ -+ if (idx >= max_grps) -+ return false; -+ -+ if ((!rk3308->loopback_dacs_enabled) && -+ handle_loopback(rk3308) && -+ rk3308->loopback_grp == mapped_grp) { -+ /* -+ * Ths loopback DACs are closed, and specify the -+ * loopback ADCs. -+ */ -+ *grp = ADC_GRP_SKIP_MAGIC; -+ } else if (rk3308->en_always_grps_num && -+ rk3308->skip_grps[mapped_grp]) { -+ /* To set the skip flag if the ADC GRP is enabled. */ -+ *grp = ADC_GRP_SKIP_MAGIC; -+ } else { -+ *grp = mapped_grp; -+ } - -- /* Step 14 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01, -- RK3308_DAC_POP_SOUND_L_MSK | -- RK3308_DAC_POP_SOUND_R_MSK, -- RK3308_DAC_POP_SOUND_L_INIT | -- RK3308_DAC_POP_SOUND_R_INIT); -+ dev_dbg(rk3308->plat_dev, -+ "ADC_TYPE_NORMAL, idx: %d, mapped_grp: %d, get grp: %d,\n", -+ idx, mapped_grp, *grp); -+ } else if (type == ADC_TYPE_ALL) { -+ if (idx >= ADC_LR_GROUP_MAX) -+ return false; -+ -+ *grp = idx; -+ dev_dbg(rk3308->plat_dev, -+ "ADC_TYPE_ALL, idx: %d, get grp: %d\n", -+ idx, *grp); -+ } else if (type == ADC_TYPE_DBG) { -+ if (idx >= ADC_LR_GROUP_MAX) -+ return false; -+ -+ if (idx == (int)rk3308->cur_dbg_grp) -+ *grp = idx; -+ else -+ *grp = ADC_GRP_SKIP_MAGIC; -+ -+ dev_dbg(rk3308->plat_dev, -+ "ADC_TYPE_DBG, idx: %d, get grp: %d\n", -+ idx, *grp); -+ } else { -+ if (idx >= 1) -+ return false; -+ -+ *grp = rk3308->loopback_grp; -+ dev_dbg(rk3308->plat_dev, -+ "ADC_TYPE_LOOPBACK, idx: %d, get grp: %d\n", -+ idx, *grp); -+ } - -- /* Step 15 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01, -- RK3308_DAC_BUF_REF_L_EN | RK3308_DAC_BUF_REF_R_EN, -- RK3308_DAC_BUF_REF_L_DIS | RK3308_DAC_BUF_REF_R_DIS); -+ return true; -+} - -- /* Step 16 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON00, -- RK3308_DAC_CURRENT_EN, -- RK3308_DAC_CURRENT_DIS); -+static int rk3308_codec_get_dac_path_state(struct rk3308_codec_priv *rk3308) -+{ -+ return rk3308->dac_path_state; -+} - -- /* Step 17 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03, -- RK3308_DAC_L_HPOUT_WORK | RK3308_DAC_R_HPOUT_WORK, -- RK3308_DAC_L_HPOUT_INIT | RK3308_DAC_R_HPOUT_INIT); -+static void rk3308_codec_set_dac_path_state(struct rk3308_codec_priv *rk3308, -+ int state) -+{ -+ rk3308->dac_path_state = state; -+} - -- /* Step 18 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON13, -- RK3308_DAC_L_HPMIX_WORK | RK3308_DAC_R_HPMIX_WORK, -- RK3308_DAC_L_HPMIX_INIT | RK3308_DAC_R_HPMIX_INIT); -+static void rk3308_headphone_ctl(struct rk3308_codec_priv *rk3308, int on) -+{ -+ if (rk3308->hp_ctl_gpio) -+ gpiod_direction_output(rk3308->hp_ctl_gpio, on); -+} - -- /* Step 19 */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON12, -- RK3308_DAC_L_HPMIX_GAIN_MSK | -- RK3308_DAC_R_HPMIX_GAIN_MSK, -- RK3308_DAC_L_HPMIX_GAIN_NDB_6 | -- RK3308_DAC_R_HPMIX_GAIN_NDB_6); -+static void rk3308_speaker_ctl(struct rk3308_codec_priv *rk3308, int on) -+{ -+ if (on) { -+ if (rk3308->pa_drv_gpio) { -+ gpiod_direction_output(rk3308->pa_drv_gpio, on); -+ msleep(rk3308->delay_pa_drv_ms); -+ } - -- /* -- * Note2. If the ACODEC_DAC_ANA_CON12[7] or ACODEC_DAC_ANA_CON12[3] -- * is set to 0x1, add the steps from the section Disable DAC -- * Configuration Standard Usage Flow after complete the step 19 -- */ -+ if (rk3308->spk_ctl_gpio) -+ gpiod_direction_output(rk3308->spk_ctl_gpio, on); -+ } else { -+ if (rk3308->spk_ctl_gpio) -+ gpiod_direction_output(rk3308->spk_ctl_gpio, on); - -- return 0; -+ if (rk3308->pa_drv_gpio) { -+ msleep(rk3308->delay_pa_drv_ms); -+ gpiod_direction_output(rk3308->pa_drv_gpio, on); -+ } -+ } - } - --static int rk3308_codec_power_on(struct snd_soc_codec *codec) -+static int rk3308_codec_reset(struct snd_soc_codec *codec) - { - struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); - -- /* 1. Supply the power of digital part and reset the Audio Codec */ -- /* Do nothing */ -+ reset_control_assert(rk3308->reset); -+ usleep_range(2000, 2500); /* estimated value */ -+ reset_control_deassert(rk3308->reset); - -- /* -- * 2. Configure ACODEC_DAC_ANA_CON1[1:0] and ACODEC_DAC_ANA_CON1[5:4] -- * to 0x1, to setup dc voltage of the DAC channel output -- */ -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01, -- RK3308_DAC_POP_SOUND_L_MSK, RK3308_DAC_POP_SOUND_L_INIT); -- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01, -- RK3308_DAC_POP_SOUND_R_MSK, RK3308_DAC_POP_SOUND_R_INIT); -+ regmap_write(rk3308->regmap, RK3308_GLB_CON, 0x00); -+ usleep_range(200, 300); /* estimated value */ -+ regmap_write(rk3308->regmap, RK3308_GLB_CON, -+ RK3308_SYS_WORK | -+ RK3308_DAC_DIG_WORK | -+ RK3308_ADC_DIG_WORK); - -- /* -- * 3. Configure the register ACODEC_ADC_ANA_CON10[6:0] to 0x1 -- * -- * Note: Only the reg (ADC_ANA_CON10+0x0)[6:0] represent the control -- * signal to select current to pre-charge/dis_charge -- */ -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), -- RK3308_ADC_CURRENT_CHARGE_MSK, RK3308_ADC_SEL_I_64(1)); -+ return 0; -+} - -- /* 4. Supply the power of the analog part(AVDD,AVDDRV) */ -+static int rk3308_codec_adc_dig_reset(struct rk3308_codec_priv *rk3308) -+{ -+ regmap_update_bits(rk3308->regmap, RK3308_GLB_CON, -+ RK3308_ADC_DIG_WORK, -+ RK3308_ADC_DIG_RESET); -+ udelay(50); -+ regmap_update_bits(rk3308->regmap, RK3308_GLB_CON, -+ RK3308_ADC_DIG_WORK, -+ RK3308_ADC_DIG_WORK); - -- /* -- * 5. Configure the register ACODEC_ADC_ANA_CON10[7] to 0x1 to setup -- * reference voltage -- * -- * Note: Only the reg (ADC_ANA_CON10+0x0)[7] represent the enable -- * signal of reference voltage module -- */ -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), -- RK3308_ADC_REF_EN, RK3308_ADC_REF_EN); -+ return 0; -+} - -- /* -- * 6. Change the register ACODEC_ADC_ANA_CON10[6:0] from the 0x1 to -- * 0x7f step by step or configure the ACODEC_ADC_ANA_CON10[6:0] to -- * 0x7f directly. The suggestion slot time of the step is 20ms. -- */ -- mdelay(20); -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), -- RK3308_ADC_CURRENT_CHARGE_MSK, -- RK3308_ADC_DONT_SEL_ALL); -+static int rk3308_codec_dac_dig_reset(struct rk3308_codec_priv *rk3308) -+{ -+ regmap_update_bits(rk3308->regmap, RK3308_GLB_CON, -+ RK3308_DAC_DIG_WORK, -+ RK3308_DAC_DIG_RESET); -+ udelay(50); -+ regmap_update_bits(rk3308->regmap, RK3308_GLB_CON, -+ RK3308_DAC_DIG_WORK, -+ RK3308_DAC_DIG_WORK); - -- /* 7. Wait until the voltage of VCM keeps stable at the AVDD/2 */ -- usleep_range(200, 300); /* estimated value */ -+ return 0; -+} - -- /* -- * 8. Configure the register ACODEC_ADC_ANA_CON10[6:0] to the -- * appropriate value(expect 0x0) for reducing power. -- */ -+static int rk3308_set_bias_level(struct snd_soc_codec *codec, -+ enum snd_soc_bias_level level) -+{ -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); - -- /* TODO: choose an appropriate charge value */ -+ switch (level) { -+ case SND_SOC_BIAS_ON: -+ break; -+ case SND_SOC_BIAS_PREPARE: -+ break; -+ case SND_SOC_BIAS_STANDBY: -+ regcache_cache_only(rk3308->regmap, false); -+ regcache_sync(rk3308->regmap); -+ break; -+ case SND_SOC_BIAS_OFF: -+ break; -+ } - - return 0; - } - --static int rk3308_codec_power_off(struct snd_soc_codec *codec) -+static int rk3308_set_dai_fmt(struct snd_soc_dai *codec_dai, -+ unsigned int fmt) - { -+ struct snd_soc_codec *codec = codec_dai->codec; - struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ unsigned int adc_aif1 = 0, adc_aif2 = 0, dac_aif1 = 0, dac_aif2 = 0; -+ int idx, grp, is_master; -+ int type = ADC_TYPE_ALL; -+ -+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { -+ case SND_SOC_DAIFMT_CBS_CFS: -+ adc_aif2 |= RK3308_ADC_IO_MODE_SLAVE; -+ adc_aif2 |= RK3308_ADC_MODE_SLAVE; -+ dac_aif2 |= RK3308_DAC_IO_MODE_SLAVE; -+ dac_aif2 |= RK3308_DAC_MODE_SLAVE; -+ is_master = 0; -+ break; -+ case SND_SOC_DAIFMT_CBM_CFM: -+ adc_aif2 |= RK3308_ADC_IO_MODE_MASTER; -+ adc_aif2 |= RK3308_ADC_MODE_MASTER; -+ dac_aif2 |= RK3308_DAC_IO_MODE_MASTER; -+ dac_aif2 |= RK3308_DAC_MODE_MASTER; -+ is_master = 1; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { -+ case SND_SOC_DAIFMT_DSP_A: -+ adc_aif1 |= RK3308_ADC_I2S_MODE_PCM; -+ dac_aif1 |= RK3308_DAC_I2S_MODE_PCM; -+ break; -+ case SND_SOC_DAIFMT_I2S: -+ adc_aif1 |= RK3308_ADC_I2S_MODE_I2S; -+ dac_aif1 |= RK3308_DAC_I2S_MODE_I2S; -+ break; -+ case SND_SOC_DAIFMT_RIGHT_J: -+ adc_aif1 |= RK3308_ADC_I2S_MODE_RJ; -+ dac_aif1 |= RK3308_DAC_I2S_MODE_RJ; -+ break; -+ case SND_SOC_DAIFMT_LEFT_J: -+ adc_aif1 |= RK3308_ADC_I2S_MODE_LJ; -+ dac_aif1 |= RK3308_DAC_I2S_MODE_LJ; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { -+ case SND_SOC_DAIFMT_NB_NF: -+ adc_aif1 |= RK3308_ADC_I2S_LRC_POL_NORMAL; -+ adc_aif2 |= RK3308_ADC_I2S_BIT_CLK_POL_NORMAL; -+ dac_aif1 |= RK3308_DAC_I2S_LRC_POL_NORMAL; -+ dac_aif2 |= RK3308_DAC_I2S_BIT_CLK_POL_NORMAL; -+ break; -+ case SND_SOC_DAIFMT_IB_IF: -+ adc_aif1 |= RK3308_ADC_I2S_LRC_POL_REVERSAL; -+ adc_aif2 |= RK3308_ADC_I2S_BIT_CLK_POL_REVERSAL; -+ dac_aif1 |= RK3308_DAC_I2S_LRC_POL_REVERSAL; -+ dac_aif2 |= RK3308_DAC_I2S_BIT_CLK_POL_REVERSAL; -+ break; -+ case SND_SOC_DAIFMT_IB_NF: -+ adc_aif1 |= RK3308_ADC_I2S_LRC_POL_NORMAL; -+ adc_aif2 |= RK3308_ADC_I2S_BIT_CLK_POL_REVERSAL; -+ dac_aif1 |= RK3308_DAC_I2S_LRC_POL_NORMAL; -+ dac_aif2 |= RK3308_DAC_I2S_BIT_CLK_POL_REVERSAL; -+ break; -+ case SND_SOC_DAIFMT_NB_IF: -+ adc_aif1 |= RK3308_ADC_I2S_LRC_POL_REVERSAL; -+ adc_aif2 |= RK3308_ADC_I2S_BIT_CLK_POL_NORMAL; -+ dac_aif1 |= RK3308_DAC_I2S_LRC_POL_REVERSAL; -+ dac_aif2 |= RK3308_DAC_I2S_BIT_CLK_POL_NORMAL; -+ break; -+ default: -+ return -EINVAL; -+ } - - /* -- * 1. Keep the power on and disable the DAC and ADC path according to -- * the section power on configuration standard usage flow. -+ * Hold ADC Digital registers start at master mode -+ * -+ * There are 8 ADCs and use the same SCLK and LRCK internal for master -+ * mode, We need to make sure that they are in effect at the same time, -+ * otherwise they will cause the abnormal clocks. - */ -+ if (is_master) -+ regmap_update_bits(rk3308->regmap, RK3308_GLB_CON, -+ RK3308_ADC_DIG_WORK, -+ RK3308_ADC_DIG_RESET); -+ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON01(grp), -+ RK3308_ADC_I2S_LRC_POL_MSK | -+ RK3308_ADC_I2S_MODE_MSK, -+ adc_aif1); -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON02(grp), -+ RK3308_ADC_IO_MODE_MSK | -+ RK3308_ADC_MODE_MSK | -+ RK3308_ADC_I2S_BIT_CLK_POL_MSK, -+ adc_aif2); -+ } - -- /* 2. Configure the register ACODEC_ADC_ANA_CON10[6:0] to 0x1 */ -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), -- RK3308_ADC_CURRENT_CHARGE_MSK, RK3308_ADC_SEL_I_64(1)); -+ /* Hold ADC Digital registers end at master mode */ -+ if (is_master) -+ regmap_update_bits(rk3308->regmap, RK3308_GLB_CON, -+ RK3308_ADC_DIG_WORK, -+ RK3308_ADC_DIG_WORK); - -- /* 3. Configure the register ACODEC_ADC_ANA_CON10[7] to 0x0 */ -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), -- RK3308_ADC_REF_EN, RK3308_ADC_REF_DIS); -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON01, -+ RK3308_DAC_I2S_LRC_POL_MSK | -+ RK3308_DAC_I2S_MODE_MSK, -+ dac_aif1); -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON02, -+ RK3308_DAC_IO_MODE_MSK | -+ RK3308_DAC_MODE_MSK | -+ RK3308_DAC_I2S_BIT_CLK_POL_MSK, -+ dac_aif2); -+ -+ return 0; -+} -+ -+static int rk3308_codec_dac_dig_config(struct rk3308_codec_priv *rk3308, -+ struct snd_pcm_hw_params *params) -+{ -+ unsigned int dac_aif1 = 0, dac_aif2 = 0; -+ -+ /* Clear the status of DAC DIG Digital reigisters */ -+ rk3308_codec_dac_dig_reset(rk3308); -+ -+ switch (params_format(params)) { -+ case SNDRV_PCM_FORMAT_S16_LE: -+ dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_16BITS; -+ break; -+ case SNDRV_PCM_FORMAT_S20_3LE: -+ dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_20BITS; -+ break; -+ case SNDRV_PCM_FORMAT_S24_LE: -+ dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_24BITS; -+ break; -+ case SNDRV_PCM_FORMAT_S32_LE: -+ dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_32BITS; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ dac_aif1 |= RK3308_DAC_I2S_LR_NORMAL; -+ dac_aif2 |= RK3308_DAC_I2S_WORK; -+ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON01, -+ RK3308_DAC_I2S_VALID_LEN_MSK | -+ RK3308_DAC_I2S_LR_MSK, -+ dac_aif1); -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON02, -+ RK3308_DAC_I2S_MSK, -+ dac_aif2); -+ -+ return 0; -+} -+ -+static int rk3308_codec_adc_dig_config(struct rk3308_codec_priv *rk3308, -+ struct snd_pcm_hw_params *params) -+{ -+ unsigned int adc_aif1 = 0, adc_aif2 = 0; -+ int type = ADC_TYPE_NORMAL; -+ int idx, grp; -+ -+ /* Clear the status of ADC DIG Digital reigisters */ -+ rk3308_codec_adc_dig_reset(rk3308); -+ -+ switch (params_format(params)) { -+ case SNDRV_PCM_FORMAT_S16_LE: -+ adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_16BITS; -+ break; -+ case SNDRV_PCM_FORMAT_S20_3LE: -+ adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_20BITS; -+ break; -+ case SNDRV_PCM_FORMAT_S24_LE: -+ adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_24BITS; -+ break; -+ case SNDRV_PCM_FORMAT_S32_LE: -+ adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_32BITS; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ switch (params_channels(params)) { -+ case 1: -+ adc_aif1 |= RK3308_ADC_I2S_MONO; -+ break; -+ case 2: -+ case 4: -+ case 6: -+ case 8: -+ adc_aif1 |= RK3308_ADC_I2S_STEREO; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ adc_aif1 |= RK3308_ADC_I2S_LR_NORMAL; -+ adc_aif2 |= RK3308_ADC_I2S_WORK; -+ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON01(grp), -+ RK3308_ADC_I2S_VALID_LEN_MSK | -+ RK3308_ADC_I2S_LR_MSK | -+ RK3308_ADC_I2S_TYPE_MSK, -+ adc_aif1); -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON02(grp), -+ RK3308_ADC_I2S_MSK, -+ adc_aif2); -+ } -+ -+ return 0; -+} -+ -+static int rk3308_codec_update_adc_grps(struct rk3308_codec_priv *rk3308, -+ struct snd_pcm_hw_params *params) -+{ -+ switch (params_channels(params)) { -+ case 1: -+ rk3308->used_adc_grps = 1; -+ break; -+ case 2: -+ case 4: -+ case 6: -+ case 8: -+ rk3308->used_adc_grps = params_channels(params) / 2; -+ break; -+ default: -+ dev_err(rk3308->plat_dev, "Invalid channels: %d\n", -+ params_channels(params)); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int rk3308_mute_stream(struct snd_soc_dai *dai, int mute, int stream) -+{ -+ struct snd_soc_codec *codec = dai->codec; -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ -+ if (stream == SNDRV_PCM_STREAM_PLAYBACK) { -+ int dgain; -+ -+ if (mute) { -+ for (dgain = 0x2; dgain <= 0x7; dgain++) { -+ /* -+ * Keep the max -> min digital CIC interpolation -+ * filter gain step by step. -+ * -+ * loud: 0x2; whisper: 0x7 -+ */ -+ regmap_update_bits(rk3308->regmap, -+ RK3308_DAC_DIG_CON04, -+ RK3308_DAC_CIC_IF_GAIN_MSK, -+ dgain); -+ usleep_range(200, 300); /* estimated value */ -+ } -+ -+#if !DEBUG_POP_ALWAYS -+ rk3308_headphone_ctl(rk3308, 0); -+ rk3308_speaker_ctl(rk3308, 0); -+#endif -+ } else { -+#if !DEBUG_POP_ALWAYS -+ if (rk3308->dac_output == DAC_LINEOUT) -+ rk3308_speaker_ctl(rk3308, 1); -+ else if (rk3308->dac_output == DAC_HPOUT) -+ rk3308_headphone_ctl(rk3308, 1); -+ -+ if (rk3308->delay_start_play_ms) -+ msleep(rk3308->delay_start_play_ms); -+#endif -+ for (dgain = 0x7; dgain >= 0x2; dgain--) { -+ /* -+ * Keep the min -> max digital CIC interpolation -+ * filter gain step by step -+ * -+ * loud: 0x2; whisper: 0x7 -+ */ -+ regmap_update_bits(rk3308->regmap, -+ RK3308_DAC_DIG_CON04, -+ RK3308_DAC_CIC_IF_GAIN_MSK, -+ dgain); -+ usleep_range(200, 300); /* estimated value */ -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+static int rk3308_codec_digital_fadein(struct rk3308_codec_priv *rk3308) -+{ -+ unsigned int dgain, dgain_ref; -+ -+ if (rk3308->hpout_l_dgain != rk3308->hpout_r_dgain) { -+ pr_warn("HPOUT l_dgain: 0x%x != r_dgain: 0x%x\n", -+ rk3308->hpout_l_dgain, rk3308->hpout_r_dgain); -+ dgain_ref = min(rk3308->hpout_l_dgain, rk3308->hpout_r_dgain); -+ } else { -+ dgain_ref = rk3308->hpout_l_dgain; -+ } - - /* -- * 4.Change the register ACODEC_ADC_ANA_CON10[6:0] from the 0x1 to 0x7f -- * step by step or configure the ACODEC_ADC_ANA_CON10[6:0] to 0x7f -- * directly. The suggestion slot time of the step is 20ms -+ * We'd better change the gain of the left and right channels -+ * at the same time to avoid different listening - */ -- mdelay(20); -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), -- RK3308_ADC_CURRENT_CHARGE_MSK, -- RK3308_ADC_DONT_SEL_ALL); -+ for (dgain = RK3308_DAC_L_HPOUT_GAIN_NDB_39; -+ dgain <= dgain_ref; dgain++) { -+ /* Step 02 decrease dgains for de-pop */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON05, -+ RK3308_DAC_L_HPOUT_GAIN_MSK, -+ dgain); -+ -+ /* Step 02 decrease dgains for de-pop */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON06, -+ RK3308_DAC_R_HPOUT_GAIN_MSK, -+ dgain); -+ } -+ -+ return 0; -+} -+ -+static int rk3308_codec_digital_fadeout(struct rk3308_codec_priv *rk3308) -+{ -+ unsigned int l_dgain, r_dgain; -+ -+ /* -+ * Note. In the step2, adjusting the register step by step to -+ * the appropriate value and taking 20ms as time step -+ */ -+ regmap_read(rk3308->regmap, RK3308_DAC_ANA_CON05, &l_dgain); -+ l_dgain &= RK3308_DAC_L_HPOUT_GAIN_MSK; -+ -+ regmap_read(rk3308->regmap, RK3308_DAC_ANA_CON06, &r_dgain); -+ r_dgain &= RK3308_DAC_R_HPOUT_GAIN_MSK; -+ -+ if (l_dgain != r_dgain) { -+ pr_warn("HPOUT l_dgain: 0x%x != r_dgain: 0x%x\n", -+ l_dgain, r_dgain); -+ l_dgain = min(l_dgain, r_dgain); -+ } -+ -+ /* -+ * We'd better change the gain of the left and right channels -+ * at the same time to avoid different listening -+ */ -+ while (l_dgain >= RK3308_DAC_L_HPOUT_GAIN_NDB_39) { -+ /* Step 02 decrease dgains for de-pop */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON05, -+ RK3308_DAC_L_HPOUT_GAIN_MSK, -+ l_dgain); -+ -+ /* Step 02 decrease dgains for de-pop */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON06, -+ RK3308_DAC_R_HPOUT_GAIN_MSK, -+ l_dgain); -+ -+ usleep_range(200, 300); /* estimated value */ -+ -+ if (l_dgain == RK3308_DAC_L_HPOUT_GAIN_NDB_39) -+ break; -+ -+ l_dgain--; -+ } -+ -+ return 0; -+} -+ -+static int rk3308_codec_dac_lineout_enable(struct rk3308_codec_priv *rk3308) -+{ -+ if (rk3308->codec_ver == ACODEC_VERSION_B) { -+ /* Step 04 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON15, -+ RK3308_DAC_LINEOUT_POP_SOUND_L_MSK | -+ RK3308_DAC_LINEOUT_POP_SOUND_R_MSK, -+ RK3308_DAC_L_SEL_DC_FROM_INTERNAL | -+ RK3308_DAC_R_SEL_DC_FROM_INTERNAL); -+ } -+ -+ /* Step 07 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04, -+ RK3308_DAC_L_LINEOUT_EN | -+ RK3308_DAC_R_LINEOUT_EN, -+ RK3308_DAC_L_LINEOUT_EN | -+ RK3308_DAC_R_LINEOUT_EN); -+ -+ udelay(20); -+ -+ if (rk3308->codec_ver == ACODEC_VERSION_B) { -+ /* Step 10 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON15, -+ RK3308_DAC_LINEOUT_POP_SOUND_L_MSK | -+ RK3308_DAC_LINEOUT_POP_SOUND_R_MSK, -+ RK3308_DAC_L_SEL_LINEOUT_FROM_INTERNAL | -+ RK3308_DAC_R_SEL_LINEOUT_FROM_INTERNAL); -+ -+ udelay(20); -+ } -+ -+ /* Step 19 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04, -+ RK3308_DAC_L_LINEOUT_UNMUTE | -+ RK3308_DAC_R_LINEOUT_UNMUTE, -+ RK3308_DAC_L_LINEOUT_UNMUTE | -+ RK3308_DAC_R_LINEOUT_UNMUTE); -+ udelay(20); -+ -+ return 0; -+} -+ -+static int rk3308_codec_dac_lineout_disable(struct rk3308_codec_priv *rk3308) -+{ -+ /* Step 08 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04, -+ RK3308_DAC_L_LINEOUT_UNMUTE | -+ RK3308_DAC_R_LINEOUT_UNMUTE, -+ RK3308_DAC_L_LINEOUT_MUTE | -+ RK3308_DAC_R_LINEOUT_MUTE); -+ -+ /* Step 09 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04, -+ RK3308_DAC_L_LINEOUT_EN | -+ RK3308_DAC_R_LINEOUT_EN, -+ RK3308_DAC_L_LINEOUT_DIS | -+ RK3308_DAC_R_LINEOUT_DIS); -+ -+ return 0; -+} -+ -+static int rk3308_codec_dac_hpout_enable(struct rk3308_codec_priv *rk3308) -+{ -+ /* Step 03 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01, -+ RK3308_DAC_HPOUT_POP_SOUND_L_MSK | -+ RK3308_DAC_HPOUT_POP_SOUND_R_MSK, -+ RK3308_DAC_HPOUT_POP_SOUND_L_WORK | -+ RK3308_DAC_HPOUT_POP_SOUND_R_WORK); -+ -+ udelay(20); -+ -+ /* Step 07 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03, -+ RK3308_DAC_L_HPOUT_EN | -+ RK3308_DAC_R_HPOUT_EN, -+ RK3308_DAC_L_HPOUT_EN | -+ RK3308_DAC_R_HPOUT_EN); -+ -+ udelay(20); -+ -+ /* Step 08 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03, -+ RK3308_DAC_L_HPOUT_WORK | -+ RK3308_DAC_R_HPOUT_WORK, -+ RK3308_DAC_L_HPOUT_WORK | -+ RK3308_DAC_R_HPOUT_WORK); -+ -+ udelay(20); -+ -+ /* Step 16 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03, -+ RK3308_DAC_L_HPOUT_UNMUTE | -+ RK3308_DAC_R_HPOUT_UNMUTE, -+ RK3308_DAC_L_HPOUT_UNMUTE | -+ RK3308_DAC_R_HPOUT_UNMUTE); -+ -+ udelay(20); -+ -+ return 0; -+} -+ -+static int rk3308_codec_dac_hpout_disable(struct rk3308_codec_priv *rk3308) -+{ -+ /* Step 03 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01, -+ RK3308_DAC_HPOUT_POP_SOUND_L_MSK | -+ RK3308_DAC_HPOUT_POP_SOUND_R_MSK, -+ RK3308_DAC_HPOUT_POP_SOUND_L_INIT | -+ RK3308_DAC_HPOUT_POP_SOUND_R_INIT); -+ -+ /* Step 07 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03, -+ RK3308_DAC_L_HPOUT_EN | -+ RK3308_DAC_R_HPOUT_EN, -+ RK3308_DAC_L_HPOUT_DIS | -+ RK3308_DAC_R_HPOUT_DIS); -+ -+ /* Step 08 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03, -+ RK3308_DAC_L_HPOUT_WORK | -+ RK3308_DAC_R_HPOUT_WORK, -+ RK3308_DAC_L_HPOUT_INIT | -+ RK3308_DAC_R_HPOUT_INIT); -+ -+ /* Step 16 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03, -+ RK3308_DAC_L_HPOUT_UNMUTE | -+ RK3308_DAC_R_HPOUT_UNMUTE, -+ RK3308_DAC_L_HPOUT_MUTE | -+ RK3308_DAC_R_HPOUT_MUTE); -+ -+ return 0; -+} -+ -+static int rk3308_codec_dac_switch(struct rk3308_codec_priv *rk3308, -+ int dac_output) -+{ int ret = 0; -+ -+ if (rk3308->dac_output == dac_output) { -+ dev_info(rk3308->plat_dev, -+ "Don't need to change dac_output: %d\n", dac_output); -+ goto out; -+ } -+ -+ switch (dac_output) { -+ case DAC_LINEOUT: -+ case DAC_HPOUT: -+ case DAC_LINEOUT_HPOUT: -+ break; -+ default: -+ dev_err(rk3308->plat_dev, "Unknown value: %d\n", dac_output); -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ if (rk3308_codec_get_dac_path_state(rk3308) == PATH_BUSY) { -+ /* -+ * We can only switch the audio path to LINEOUT or HPOUT on -+ * codec during playbacking, otherwise, just update the -+ * dac_output flag. -+ */ -+ switch (dac_output) { -+ case DAC_LINEOUT: -+ rk3308_headphone_ctl(rk3308, 0); -+ rk3308_speaker_ctl(rk3308, 1); -+ rk3308_codec_dac_hpout_disable(rk3308); -+ rk3308_codec_dac_lineout_enable(rk3308); -+ break; -+ case DAC_HPOUT: -+ rk3308_speaker_ctl(rk3308, 0); -+ rk3308_headphone_ctl(rk3308, 1); -+ rk3308_codec_dac_lineout_disable(rk3308); -+ rk3308_codec_dac_hpout_enable(rk3308); -+ break; -+ case DAC_LINEOUT_HPOUT: -+ rk3308_speaker_ctl(rk3308, 1); -+ rk3308_headphone_ctl(rk3308, 1); -+ rk3308_codec_dac_lineout_enable(rk3308); -+ rk3308_codec_dac_hpout_enable(rk3308); -+ break; -+ default: -+ break; -+ } -+ } -+ -+ rk3308->dac_output = dac_output; -+out: -+ dev_dbg(rk3308->plat_dev, "switch dac_output to: %d\n", -+ rk3308->dac_output); -+ -+ return ret; -+} -+ -+static int rk3308_codec_dac_enable(struct rk3308_codec_priv *rk3308) -+{ -+ /* -+ * Note1. If the ACODEC_DAC_ANA_CON12[6] or ACODEC_DAC_ANA_CON12[2] -+ * is set to 0x1, ignoring the step9~12. -+ */ -+ -+ /* -+ * Note2. If the ACODEC_ DAC_ANA_CON12[7] or ACODEC_DAC_ANA_CON12[3] -+ * is set to 0x1, the ADC0 or ADC1 should be enabled firstly, and -+ * please refer to Enable ADC Configuration Standard Usage Flow(expect -+ * step7~step9,step14). -+ */ -+ -+ /* -+ * Note3. If no opening the line out, ignoring the step6, step17 and -+ * step19. -+ */ -+ -+ /* -+ * Note4. If no opening the headphone out, ignoring the step3,step7~8, -+ * step16 and step18. -+ */ -+ -+ /* -+ * Note5. In the step18, adjust the register step by step to the -+ * appropriate value and taking 10ms as one time step -+ */ -+ -+ /* -+ * 1. Set the ACODEC_DAC_ANA_CON0[0] to 0x1, to enable the current -+ * source of DAC -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON00, -+ RK3308_DAC_CURRENT_MSK, -+ RK3308_DAC_CURRENT_EN); -+ -+ udelay(20); -+ -+ /* -+ * 2. Set the ACODEC_DAC_ANA_CON1[6] and ACODEC_DAC_ANA_CON1[2] to 0x1, -+ * to enable the reference voltage buffer -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01, -+ RK3308_DAC_BUF_REF_L_MSK | -+ RK3308_DAC_BUF_REF_R_MSK, -+ RK3308_DAC_BUF_REF_L_EN | -+ RK3308_DAC_BUF_REF_R_EN); -+ -+ /* Waiting the stable reference voltage */ -+ mdelay(1); -+ -+ if (rk3308->dac_output == DAC_HPOUT || -+ rk3308->dac_output == DAC_LINEOUT_HPOUT) { -+ /* Step 03 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01, -+ RK3308_DAC_HPOUT_POP_SOUND_L_MSK | -+ RK3308_DAC_HPOUT_POP_SOUND_R_MSK, -+ RK3308_DAC_HPOUT_POP_SOUND_L_WORK | -+ RK3308_DAC_HPOUT_POP_SOUND_R_WORK); -+ -+ udelay(20); -+ } -+ -+ if (rk3308->codec_ver == ACODEC_VERSION_B && -+ (rk3308->dac_output == DAC_LINEOUT || -+ rk3308->dac_output == DAC_LINEOUT_HPOUT)) { -+ /* Step 04 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON15, -+ RK3308_DAC_LINEOUT_POP_SOUND_L_MSK | -+ RK3308_DAC_LINEOUT_POP_SOUND_R_MSK, -+ RK3308_DAC_L_SEL_DC_FROM_INTERNAL | -+ RK3308_DAC_R_SEL_DC_FROM_INTERNAL); -+ -+ udelay(20); -+ } -+ -+ /* Step 05 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON13, -+ RK3308_DAC_L_HPMIX_EN | -+ RK3308_DAC_R_HPMIX_EN, -+ RK3308_DAC_L_HPMIX_EN | -+ RK3308_DAC_R_HPMIX_EN); -+ -+ /* Waiting the stable HPMIX */ -+ mdelay(1); -+ -+ /* Step 06. Reset HPMIX and recover HPMIX gains */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON13, -+ RK3308_DAC_L_HPMIX_WORK | -+ RK3308_DAC_R_HPMIX_WORK, -+ RK3308_DAC_L_HPMIX_INIT | -+ RK3308_DAC_R_HPMIX_INIT); -+ udelay(50); -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON13, -+ RK3308_DAC_L_HPMIX_WORK | -+ RK3308_DAC_R_HPMIX_WORK, -+ RK3308_DAC_L_HPMIX_WORK | -+ RK3308_DAC_R_HPMIX_WORK); -+ -+ udelay(20); -+ -+ if (rk3308->dac_output == DAC_LINEOUT || -+ rk3308->dac_output == DAC_LINEOUT_HPOUT) { -+ /* Step 07 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04, -+ RK3308_DAC_L_LINEOUT_EN | -+ RK3308_DAC_R_LINEOUT_EN, -+ RK3308_DAC_L_LINEOUT_EN | -+ RK3308_DAC_R_LINEOUT_EN); -+ -+ udelay(20); -+ } -+ -+ if (rk3308->dac_output == DAC_HPOUT || -+ rk3308->dac_output == DAC_LINEOUT_HPOUT) { -+ /* Step 08 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03, -+ RK3308_DAC_L_HPOUT_EN | -+ RK3308_DAC_R_HPOUT_EN, -+ RK3308_DAC_L_HPOUT_EN | -+ RK3308_DAC_R_HPOUT_EN); -+ -+ udelay(20); -+ -+ /* Step 09 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03, -+ RK3308_DAC_L_HPOUT_WORK | -+ RK3308_DAC_R_HPOUT_WORK, -+ RK3308_DAC_L_HPOUT_WORK | -+ RK3308_DAC_R_HPOUT_WORK); -+ -+ udelay(20); -+ } -+ -+ if (rk3308->codec_ver == ACODEC_VERSION_B) { -+ /* Step 10 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON15, -+ RK3308_DAC_LINEOUT_POP_SOUND_L_MSK | -+ RK3308_DAC_LINEOUT_POP_SOUND_R_MSK, -+ RK3308_DAC_L_SEL_LINEOUT_FROM_INTERNAL | -+ RK3308_DAC_R_SEL_LINEOUT_FROM_INTERNAL); -+ -+ udelay(20); -+ } -+ -+ /* Step 11 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02, -+ RK3308_DAC_L_REF_EN | -+ RK3308_DAC_R_REF_EN, -+ RK3308_DAC_L_REF_EN | -+ RK3308_DAC_R_REF_EN); -+ -+ udelay(20); -+ -+ /* Step 12 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02, -+ RK3308_DAC_L_CLK_EN | -+ RK3308_DAC_R_CLK_EN, -+ RK3308_DAC_L_CLK_EN | -+ RK3308_DAC_R_CLK_EN); -+ -+ udelay(20); -+ -+ /* Step 13 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02, -+ RK3308_DAC_L_DAC_EN | -+ RK3308_DAC_R_DAC_EN, -+ RK3308_DAC_L_DAC_EN | -+ RK3308_DAC_R_DAC_EN); -+ -+ udelay(20); -+ -+ /* Step 14 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02, -+ RK3308_DAC_L_DAC_WORK | -+ RK3308_DAC_R_DAC_WORK, -+ RK3308_DAC_L_DAC_WORK | -+ RK3308_DAC_R_DAC_WORK); -+ -+ udelay(20); -+ -+ /* Step 15 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON12, -+ RK3308_DAC_L_HPMIX_SEL_MSK | -+ RK3308_DAC_R_HPMIX_SEL_MSK, -+ RK3308_DAC_L_HPMIX_I2S | -+ RK3308_DAC_R_HPMIX_I2S); -+ -+ udelay(20); -+ -+ /* Step 16 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON13, -+ RK3308_DAC_L_HPMIX_UNMUTE | -+ RK3308_DAC_R_HPMIX_UNMUTE, -+ RK3308_DAC_L_HPMIX_UNMUTE | -+ RK3308_DAC_R_HPMIX_UNMUTE); -+ -+ udelay(20); -+ -+ /* Step 17: Put configuration HPMIX Gain to DAPM */ -+ -+ if (rk3308->dac_output == DAC_HPOUT || -+ rk3308->dac_output == DAC_LINEOUT_HPOUT) { -+ /* Step 18 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03, -+ RK3308_DAC_L_HPOUT_UNMUTE | -+ RK3308_DAC_R_HPOUT_UNMUTE, -+ RK3308_DAC_L_HPOUT_UNMUTE | -+ RK3308_DAC_R_HPOUT_UNMUTE); -+ -+ udelay(20); -+ } -+ -+ if (rk3308->dac_output == DAC_LINEOUT || -+ rk3308->dac_output == DAC_LINEOUT_HPOUT) { -+ /* Step 19 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04, -+ RK3308_DAC_L_LINEOUT_UNMUTE | -+ RK3308_DAC_R_LINEOUT_UNMUTE, -+ RK3308_DAC_L_LINEOUT_UNMUTE | -+ RK3308_DAC_R_LINEOUT_UNMUTE); -+ udelay(20); -+ } -+ -+ /* Step 20, put configuration HPOUT gain to DAPM control */ -+ /* Step 21, put configuration LINEOUT gain to DAPM control */ -+ -+ if (rk3308->dac_output == DAC_HPOUT || -+ rk3308->dac_output == DAC_LINEOUT_HPOUT) { -+ /* Just for HPOUT */ -+ rk3308_codec_digital_fadein(rk3308); -+ } -+ -+ rk3308->dac_endisable = true; -+ -+ /* TODO: TRY TO TEST DRIVE STRENGTH */ -+ -+ return 0; -+} -+ -+static int rk3308_codec_dac_disable(struct rk3308_codec_priv *rk3308) -+{ -+ /* -+ * Step 00 skipped. Keep the DAC channel work and input the mute signal. -+ */ -+ -+ /* Step 01 skipped. May set the min gain for LINEOUT. */ -+ -+ /* Step 02 skipped. May set the min gain for HPOUT. */ -+ -+ if (rk3308->dac_output == DAC_HPOUT || -+ rk3308->dac_output == DAC_LINEOUT_HPOUT) { -+ /* Just for HPOUT */ -+ rk3308_codec_digital_fadeout(rk3308); -+ } -+ -+ /* Step 03 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON13, -+ RK3308_DAC_L_HPMIX_UNMUTE | -+ RK3308_DAC_R_HPMIX_UNMUTE, -+ RK3308_DAC_L_HPMIX_UNMUTE | -+ RK3308_DAC_R_HPMIX_UNMUTE); -+ -+ /* Step 04 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON12, -+ RK3308_DAC_L_HPMIX_SEL_MSK | -+ RK3308_DAC_R_HPMIX_SEL_MSK, -+ RK3308_DAC_L_HPMIX_NONE | -+ RK3308_DAC_R_HPMIX_NONE); -+ /* Step 05 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03, -+ RK3308_DAC_L_HPOUT_UNMUTE | -+ RK3308_DAC_R_HPOUT_UNMUTE, -+ RK3308_DAC_L_HPOUT_MUTE | -+ RK3308_DAC_R_HPOUT_MUTE); -+ -+ /* Step 06 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02, -+ RK3308_DAC_L_DAC_WORK | -+ RK3308_DAC_R_DAC_WORK, -+ RK3308_DAC_L_DAC_INIT | -+ RK3308_DAC_R_DAC_INIT); -+ -+ /* Step 07 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03, -+ RK3308_DAC_L_HPOUT_EN | -+ RK3308_DAC_R_HPOUT_EN, -+ RK3308_DAC_L_HPOUT_DIS | -+ RK3308_DAC_R_HPOUT_DIS); -+ -+ /* Step 08 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04, -+ RK3308_DAC_L_LINEOUT_UNMUTE | -+ RK3308_DAC_R_LINEOUT_UNMUTE, -+ RK3308_DAC_L_LINEOUT_MUTE | -+ RK3308_DAC_R_LINEOUT_MUTE); -+ -+ /* Step 09 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04, -+ RK3308_DAC_L_LINEOUT_EN | -+ RK3308_DAC_R_LINEOUT_EN, -+ RK3308_DAC_L_LINEOUT_DIS | -+ RK3308_DAC_R_LINEOUT_DIS); -+ -+ /* Step 10 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON13, -+ RK3308_DAC_L_HPMIX_EN | -+ RK3308_DAC_R_HPMIX_EN, -+ RK3308_DAC_L_HPMIX_DIS | -+ RK3308_DAC_R_HPMIX_DIS); -+ -+ /* Step 11 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02, -+ RK3308_DAC_L_DAC_EN | -+ RK3308_DAC_R_DAC_EN, -+ RK3308_DAC_L_DAC_DIS | -+ RK3308_DAC_R_DAC_DIS); -+ -+ /* Step 12 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02, -+ RK3308_DAC_L_CLK_EN | -+ RK3308_DAC_R_CLK_EN, -+ RK3308_DAC_L_CLK_DIS | -+ RK3308_DAC_R_CLK_DIS); -+ -+ /* Step 13 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02, -+ RK3308_DAC_L_REF_EN | -+ RK3308_DAC_R_REF_EN, -+ RK3308_DAC_L_REF_DIS | -+ RK3308_DAC_R_REF_DIS); -+ -+ /* Step 14 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01, -+ RK3308_DAC_HPOUT_POP_SOUND_L_MSK | -+ RK3308_DAC_HPOUT_POP_SOUND_R_MSK, -+ RK3308_DAC_HPOUT_POP_SOUND_L_INIT | -+ RK3308_DAC_HPOUT_POP_SOUND_R_INIT); -+ -+ /* Step 15 */ -+ if (rk3308->codec_ver == ACODEC_VERSION_B && -+ (rk3308->dac_output == DAC_LINEOUT || -+ rk3308->dac_output == DAC_LINEOUT_HPOUT)) { -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON15, -+ RK3308_DAC_LINEOUT_POP_SOUND_L_MSK | -+ RK3308_DAC_LINEOUT_POP_SOUND_R_MSK, -+ RK3308_DAC_L_SEL_DC_FROM_VCM | -+ RK3308_DAC_R_SEL_DC_FROM_VCM); -+ } -+ -+ /* Step 16 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01, -+ RK3308_DAC_BUF_REF_L_EN | -+ RK3308_DAC_BUF_REF_R_EN, -+ RK3308_DAC_BUF_REF_L_DIS | -+ RK3308_DAC_BUF_REF_R_DIS); -+ -+ /* Step 17 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON00, -+ RK3308_DAC_CURRENT_EN, -+ RK3308_DAC_CURRENT_DIS); -+ -+ /* Step 18 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03, -+ RK3308_DAC_L_HPOUT_WORK | -+ RK3308_DAC_R_HPOUT_WORK, -+ RK3308_DAC_L_HPOUT_INIT | -+ RK3308_DAC_R_HPOUT_INIT); -+ -+ /* Step 19 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON13, -+ RK3308_DAC_L_HPMIX_WORK | -+ RK3308_DAC_R_HPMIX_WORK, -+ RK3308_DAC_L_HPMIX_WORK | -+ RK3308_DAC_R_HPMIX_WORK); -+ -+ /* Step 20 skipped, may set the min gain for HPOUT. */ -+ -+ /* -+ * Note2. If the ACODEC_DAC_ANA_CON12[7] or ACODEC_DAC_ANA_CON12[3] -+ * is set to 0x1, add the steps from the section Disable ADC -+ * Configuration Standard Usage Flow after complete the step 19 -+ * -+ * IF USING LINE-IN -+ * rk3308_codec_adc_ana_disable(rk3308, type); -+ */ -+ -+ rk3308->dac_endisable = false; -+ -+ return 0; -+} -+ -+static int rk3308_codec_power_on(struct rk3308_codec_priv *rk3308) -+{ -+ unsigned int v; -+ -+ /* 0. Supply the power of digital part and reset the Audio Codec */ -+ /* Do nothing */ -+ -+ /* -+ * 1. Configure ACODEC_DAC_ANA_CON1[1:0] and ACODEC_DAC_ANA_CON1[5:4] -+ * to 0x1, to setup dc voltage of the DAC channel output. -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01, -+ RK3308_DAC_HPOUT_POP_SOUND_L_MSK, -+ RK3308_DAC_HPOUT_POP_SOUND_L_INIT); -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01, -+ RK3308_DAC_HPOUT_POP_SOUND_R_MSK, -+ RK3308_DAC_HPOUT_POP_SOUND_R_INIT); -+ -+ if (rk3308->codec_ver == ACODEC_VERSION_B) { -+ /* -+ * 2. Configure ACODEC_DAC_ANA_CON15[1:0] and -+ * ACODEC_DAC_ANA_CON15[5:4] to 0x1, to setup dc voltage of -+ * the DAC channel output. -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON15, -+ RK3308_DAC_LINEOUT_POP_SOUND_L_MSK, -+ RK3308_DAC_L_SEL_DC_FROM_VCM); -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON15, -+ RK3308_DAC_LINEOUT_POP_SOUND_R_MSK, -+ RK3308_DAC_R_SEL_DC_FROM_VCM); -+ } -+ -+ /* -+ * 3. Configure the register ACODEC_ADC_ANA_CON10[3:0] to 7’b000_0001. -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), -+ RK3308_ADC_CURRENT_CHARGE_MSK, -+ RK3308_ADC_SEL_I(0x1)); -+ -+ if (rk3308->codec_ver == ACODEC_VERSION_B) { -+ /* -+ * 4. Configure the register ACODEC_ADC_ANA_CON14[3:0] to -+ * 4’b0001. -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON14, -+ RK3308_DAC_CURRENT_CHARGE_MSK, -+ RK3308_DAC_SEL_I(0x1)); -+ } -+ -+ /* 5. Supply the power of the analog part(AVDD,AVDDRV) */ -+ -+ /* -+ * 6. Configure the register ACODEC_ADC_ANA_CON10[7] to 0x1 to setup -+ * reference voltage -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), -+ RK3308_ADC_REF_EN, RK3308_ADC_REF_EN); -+ -+ if (rk3308->codec_ver == ACODEC_VERSION_B) { -+ /* -+ * 7. Configure the register ACODEC_ADC_ANA_CON14[4] to 0x1 to -+ * setup reference voltage -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON14, -+ RK3308_DAC_VCM_LINEOUT_EN, -+ RK3308_DAC_VCM_LINEOUT_EN); -+ } -+ -+ /* -+ * 8. Change the register ACODEC_ADC_ANA_CON10[6:0] from the 0x1 to -+ * 0x7f step by step or configure the ACODEC_ADC_ANA_CON10[6:0] to -+ * 0x7f directly. Here the slot time of the step is 200us. -+ */ -+ for (v = 0x1; v <= 0x7f; v++) { -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), -+ RK3308_ADC_CURRENT_CHARGE_MSK, -+ v); -+ udelay(200); -+ } -+ -+ if (rk3308->codec_ver == ACODEC_VERSION_B) { -+ /* -+ * 9. Change the register ACODEC_ADC_ANA_CON14[3:0] from the 0x1 -+ * to 0xf step by step or configure the -+ * ACODEC_ADC_ANA_CON14[3:0] to 0xf directly. Here the slot -+ * time of the step is 200us. -+ */ -+ for (v = 0x1; v <= 0xf; v++) { -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON14, -+ RK3308_DAC_CURRENT_CHARGE_MSK, -+ v); -+ udelay(200); -+ } -+ } -+ -+ /* 10. Wait until the voltage of VCM keeps stable at the AVDD/2 */ -+ msleep(20); /* estimated value */ -+ -+ /* -+ * 11. Configure the register ACODEC_ADC_ANA_CON10[6:0] to the -+ * appropriate value(expect 0x0) for reducing power. -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), -+ RK3308_ADC_CURRENT_CHARGE_MSK, 0x7c); -+ -+ if (rk3308->codec_ver == ACODEC_VERSION_B) { -+ /* -+ * 12. Configure the register ACODEC_DAC_ANA_CON14[6:0] to the -+ * appropriate value(expect 0x0) for reducing power. -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON14, -+ RK3308_DAC_CURRENT_CHARGE_MSK, 0xf); -+ } -+ -+ return 0; -+} -+ -+static int rk3308_codec_power_off(struct rk3308_codec_priv *rk3308) -+{ -+ unsigned int v; -+ -+ /* -+ * 0. Keep the power on and disable the DAC and ADC path according to -+ * the section power on configuration standard usage flow. -+ */ -+ -+ /* -+ * 1. Configure the register ACODEC_ADC_ANA_CON10[6:0] to 7’b000_0001. -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), -+ RK3308_ADC_CURRENT_CHARGE_MSK, -+ RK3308_ADC_SEL_I(0x1)); -+ -+ if (rk3308->codec_ver == ACODEC_VERSION_B) { -+ /* -+ * 2. Configure the register ACODEC_DAC_ANA_CON14[3:0] to -+ * 4’b0001. -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON14, -+ RK3308_DAC_CURRENT_CHARGE_MSK, -+ RK3308_DAC_SEL_I(0x1)); -+ } -+ -+ /* 3. Configure the register ACODEC_ADC_ANA_CON10[7] to 0x0 */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), -+ RK3308_ADC_REF_EN, -+ RK3308_ADC_REF_DIS); -+ -+ if (rk3308->codec_ver == ACODEC_VERSION_B) { -+ /* 4. Configure the register ACODEC_DAC_ANA_CON14[7] to 0x0 */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON14, -+ RK3308_DAC_VCM_LINEOUT_EN, -+ RK3308_DAC_VCM_LINEOUT_DIS); -+ } -+ -+ /* -+ * 5. Change the register ACODEC_ADC_ANA_CON10[6:0] from the 0x1 to 0x7f -+ * step by step or configure the ACODEC_ADC_ANA_CON10[6:0] to 0x7f -+ * directly. Here the slot time of the step is 200us. -+ */ -+ for (v = 0x1; v <= 0x7f; v++) { -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), -+ RK3308_ADC_CURRENT_CHARGE_MSK, -+ v); -+ udelay(200); -+ } -+ -+ if (rk3308->codec_ver == ACODEC_VERSION_B) { -+ /* -+ * 6. Change the register ACODEC_DAC_ANA_CON14[3:0] from the 0x1 -+ * to 0xf step by step or configure the -+ * ACODEC_DAC_ANA_CON14[3:0] to 0xf directly. Here the slot -+ * time of the step is 200us. -+ */ -+ for (v = 0x1; v <= 0x7f; v++) { -+ regmap_update_bits(rk3308->regmap, -+ RK3308_ADC_ANA_CON10(0), -+ RK3308_ADC_CURRENT_CHARGE_MSK, -+ v); -+ udelay(200); -+ } -+ } -+ -+ /* 7. Wait until the voltage of VCM keeps stable at the AGND */ -+ msleep(20); /* estimated value */ -+ -+ /* 8. Power off the analog power supply */ -+ /* 9. Power off the digital power supply */ -+ -+ /* Do something via hardware */ -+ -+ return 0; -+} -+ -+static int rk3308_codec_headset_detect_enable(struct rk3308_codec_priv *rk3308) -+{ -+ /* -+ * Set ACODEC_DAC_ANA_CON0[1] to 0x1, to enable the headset insert -+ * detection -+ * -+ * Note. When the voltage of PAD HPDET> 8*AVDD/9, the output value of -+ * the pin_hpdet will be set to 0x1 and assert a interrupt -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON00, -+ RK3308_DAC_HEADPHONE_DET_MSK, -+ RK3308_DAC_HEADPHONE_DET_EN); -+ -+ return 0; -+} -+ -+static int rk3308_codec_headset_detect_disable(struct rk3308_codec_priv *rk3308) -+{ -+ /* -+ * Set ACODEC_DAC_ANA_CON0[1] to 0x0, to disable the headset insert -+ * detection -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON00, -+ RK3308_DAC_HEADPHONE_DET_MSK, -+ RK3308_DAC_HEADPHONE_DET_DIS); -+ -+ return 0; -+} -+ -+static int rk3308_codec_check_i2s_sdis(struct rk3308_codec_priv *rk3308, -+ int num) -+{ -+ int i, j, ret = 0; -+ -+ switch (num) { -+ case 1: -+ rk3308->which_i2s = ACODEC_TO_I2S1_2CH; -+ break; -+ case 2: -+ rk3308->which_i2s = ACODEC_TO_I2S3_4CH; -+ break; -+ case 4: -+ rk3308->which_i2s = ACODEC_TO_I2S2_8CH; -+ break; -+ default: -+ dev_err(rk3308->plat_dev, "Invalid i2s sdis num: %d\n", num); -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ for (i = 0; i < num; i++) { -+ if (rk3308->i2s_sdis[i] > ADC_LR_GROUP_MAX - 1) { -+ dev_err(rk3308->plat_dev, -+ "i2s_sdis[%d]: %d is overflow\n", -+ i, rk3308->i2s_sdis[i]); -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ for (j = 0; j < num; j++) { -+ if (i == j) -+ continue; -+ -+ if (rk3308->i2s_sdis[i] == rk3308->i2s_sdis[j]) { -+ dev_err(rk3308->plat_dev, -+ "Invalid i2s_sdis: [%d]%d == [%d]%d\n", -+ i, rk3308->i2s_sdis[i], -+ j, rk3308->i2s_sdis[j]); -+ ret = -EINVAL; -+ goto err; -+ } -+ } -+ } -+ -+err: -+ return ret; -+} -+ -+static int rk3308_codec_adc_grps_route_config(struct rk3308_codec_priv *rk3308) -+{ -+ int idx = 0; -+ -+ if (rk3308->which_i2s == ACODEC_TO_I2S2_8CH) { -+ for (idx = 0; idx < rk3308->to_i2s_grps; idx++) { -+ regmap_write(rk3308->grf, GRF_SOC_CON1, -+ GRF_I2S2_8CH_SDI(idx, rk3308->i2s_sdis[idx])); -+ } -+ } else if (rk3308->which_i2s == ACODEC_TO_I2S3_4CH) { -+ for (idx = 0; idx < rk3308->to_i2s_grps; idx++) { -+ regmap_write(rk3308->grf, GRF_SOC_CON1, -+ GRF_I2S3_4CH_SDI(idx, rk3308->i2s_sdis[idx])); -+ } -+ } else if (rk3308->which_i2s == ACODEC_TO_I2S1_2CH) { -+ regmap_write(rk3308->grf, GRF_SOC_CON1, -+ GRF_I2S1_2CH_SDI(rk3308->i2s_sdis[idx])); -+ } -+ -+ return 0; -+} -+ -+/* Put default one-to-one mapping */ -+static int rk3308_codec_adc_grps_route_default(struct rk3308_codec_priv *rk3308) -+{ -+ unsigned int idx; -+ -+ /* -+ * The GRF values may be kept the previous status after hot reboot, -+ * if the property 'rockchip,adc-grps-route' is not set, we need to -+ * recover default the order of sdi/sdo for i2s2_8ch/i2s3_8ch/i2s1_2ch. -+ */ -+ regmap_write(rk3308->grf, GRF_SOC_CON1, -+ GRF_I2S1_2CH_SDI(0)); -+ -+ for (idx = 0; idx < 2; idx++) { -+ regmap_write(rk3308->grf, GRF_SOC_CON1, -+ GRF_I2S3_4CH_SDI(idx, idx)); -+ } -+ -+ /* Using i2s2_8ch by default. */ -+ rk3308->which_i2s = ACODEC_TO_I2S2_8CH; -+ rk3308->to_i2s_grps = ADC_LR_GROUP_MAX; -+ -+ for (idx = 0; idx < ADC_LR_GROUP_MAX; idx++) { -+ rk3308->i2s_sdis[idx] = idx; -+ regmap_write(rk3308->grf, GRF_SOC_CON1, -+ GRF_I2S2_8CH_SDI(idx, idx)); -+ } -+ -+ return 0; -+} -+ -+static int rk3308_codec_adc_grps_route(struct rk3308_codec_priv *rk3308, -+ struct device_node *np) -+{ -+ int num, ret; -+ -+ num = of_count_phandle_with_args(np, "rockchip,adc-grps-route", NULL); -+ if (num < 0) { -+ if (num == -ENOENT) { -+ /* Not use 'rockchip,adc-grps-route' property here */ -+ rk3308_codec_adc_grps_route_default(rk3308); -+ ret = 0; -+ } else { -+ dev_err(rk3308->plat_dev, -+ "Failed to read 'rockchip,adc-grps-route' num: %d\n", -+ num); -+ ret = num; -+ } -+ return ret; -+ } -+ -+ ret = of_property_read_u32_array(np, "rockchip,adc-grps-route", -+ rk3308->i2s_sdis, num); -+ if (ret < 0) { -+ dev_err(rk3308->plat_dev, -+ "Failed to read 'rockchip,adc-grps-route': %d\n", -+ ret); -+ return ret; -+ } -+ -+ ret = rk3308_codec_check_i2s_sdis(rk3308, num); -+ if (ret < 0) { -+ dev_err(rk3308->plat_dev, -+ "Failed to check i2s_sdis: %d\n", ret); -+ return ret; -+ } -+ -+ rk3308->to_i2s_grps = num; -+ -+ rk3308_codec_adc_grps_route_config(rk3308); -+ -+ return 0; -+} -+ -+static int check_micbias(int micbias) -+{ -+ switch (micbias) { -+ case RK3308_ADC_MICBIAS_VOLT_0_85: -+ case RK3308_ADC_MICBIAS_VOLT_0_8: -+ case RK3308_ADC_MICBIAS_VOLT_0_75: -+ case RK3308_ADC_MICBIAS_VOLT_0_7: -+ case RK3308_ADC_MICBIAS_VOLT_0_65: -+ case RK3308_ADC_MICBIAS_VOLT_0_6: -+ case RK3308_ADC_MICBIAS_VOLT_0_55: -+ case RK3308_ADC_MICBIAS_VOLT_0_5: -+ return 0; -+ } -+ -+ return -EINVAL; -+} -+ -+static bool handle_loopback(struct rk3308_codec_priv *rk3308) -+{ -+ /* The version B doesn't need to handle loopback. */ -+ if (rk3308->codec_ver == ACODEC_VERSION_B) -+ return false; -+ -+ switch (rk3308->loopback_grp) { -+ case 0: -+ case 1: -+ case 2: -+ case 3: -+ return true; -+ } -+ -+ return false; -+} -+ -+static bool has_en_always_grps(struct rk3308_codec_priv *rk3308) -+{ -+ int idx; -+ -+ if (rk3308->en_always_grps_num) { -+ for (idx = 0; idx < ADC_LR_GROUP_MAX; idx++) { -+ if (rk3308->en_always_grps[idx] >= 0 && -+ rk3308->en_always_grps[idx] <= ADC_LR_GROUP_MAX - 1) -+ return true; -+ } -+ } -+ -+ return false; -+} -+ -+static int rk3308_codec_micbias_enable(struct rk3308_codec_priv *rk3308, -+ int micbias) -+{ -+ int ret; -+ -+ if (rk3308->ext_micbias != EXT_MICBIAS_NONE) -+ return 0; -+ -+ /* 0. Power up the ACODEC and keep the AVDDH stable */ -+ -+ /* Step 1. Configure ACODEC_ADC_ANA_CON7[2:0] to the certain value */ -+ ret = check_micbias(micbias); -+ if (ret < 0) { -+ dev_err(rk3308->plat_dev, "This is an invalid micbias: %d\n", -+ micbias); -+ return ret; -+ } -+ -+ /* -+ * Note: Only the reg (ADC_ANA_CON7+0x0)[2:0] represent the level range -+ * control signal of MICBIAS voltage -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(0), -+ RK3308_ADC_LEVEL_RANGE_MICBIAS_MSK, -+ micbias); -+ -+ /* Step 2. Wait until the VCMH keep stable */ -+ msleep(20); /* estimated value */ -+ -+ /* -+ * Step 3. Configure ACODEC_ADC_ANA_CON8[4] to 0x1 -+ * -+ * Note: Only the reg (ADC_ANA_CON8+0x0)[4] represent the enable -+ * signal of current source for MICBIAS -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON08(0), -+ RK3308_ADC_MICBIAS_CURRENT_MSK, -+ RK3308_ADC_MICBIAS_CURRENT_EN); -+ -+ /* -+ * Step 4. Configure the (ADC_ANA_CON7+0x40)[3] or -+ * (ADC_ANA_CON7+0x80)[3] to 0x1. -+ * -+ * (ADC_ANA_CON7+0x40)[3] used to control the MICBIAS1, and -+ * (ADC_ANA_CON7+0x80)[3] used to control the MICBIAS2 -+ */ -+ if (rk3308->micbias1) -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(1), -+ RK3308_ADC_MIC_BIAS_BUF_EN, -+ RK3308_ADC_MIC_BIAS_BUF_EN); -+ -+ if (rk3308->micbias2) -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(2), -+ RK3308_ADC_MIC_BIAS_BUF_EN, -+ RK3308_ADC_MIC_BIAS_BUF_EN); -+ -+ /* waiting micbias stabled*/ -+ mdelay(50); -+ -+ rk3308->enable_micbias = true; -+ -+ return 0; -+} -+ -+static int rk3308_codec_micbias_disable(struct rk3308_codec_priv *rk3308) -+{ -+ if (rk3308->ext_micbias != EXT_MICBIAS_NONE) -+ return 0; -+ -+ /* Step 0. Enable the MICBIAS and keep the Audio Codec stable */ -+ /* Do nothing */ -+ -+ /* -+ * Step 1. Configure the (ADC_ANA_CON7+0x40)[3] or -+ * (ADC_ANA_CON7+0x80)[3] to 0x0 -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(1), -+ RK3308_ADC_MIC_BIAS_BUF_EN, -+ RK3308_ADC_MIC_BIAS_BUF_DIS); -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(2), -+ RK3308_ADC_MIC_BIAS_BUF_EN, -+ RK3308_ADC_MIC_BIAS_BUF_DIS); -+ -+ /* -+ * Step 2. Configure ACODEC_ADC_ANA_CON8[4] to 0x0 -+ * -+ * Note: Only the reg (ADC_ANA_CON8+0x0)[4] represent the enable -+ * signal of current source for MICBIAS -+ */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON08(0), -+ RK3308_ADC_MICBIAS_CURRENT_MSK, -+ RK3308_ADC_MICBIAS_CURRENT_DIS); -+ -+ rk3308->enable_micbias = false; -+ -+ return 0; -+} -+ -+static int rk3308_codec_adc_reinit_mics(struct rk3308_codec_priv *rk3308, -+ int type) -+{ -+ int idx, grp; -+ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ /* vendor step 1 */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON05(grp), -+ RK3308_ADC_CH1_ADC_WORK | -+ RK3308_ADC_CH2_ADC_WORK, -+ RK3308_ADC_CH1_ADC_INIT | -+ RK3308_ADC_CH2_ADC_INIT); -+ } -+ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ /* vendor step 2 */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON02(grp), -+ RK3308_ADC_CH1_ALC_WORK | -+ RK3308_ADC_CH2_ALC_WORK, -+ RK3308_ADC_CH1_ALC_INIT | -+ RK3308_ADC_CH2_ALC_INIT); -+ } -+ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ /* vendor step 3 */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON00(grp), -+ RK3308_ADC_CH1_MIC_WORK | -+ RK3308_ADC_CH2_MIC_WORK, -+ RK3308_ADC_CH1_MIC_INIT | -+ RK3308_ADC_CH2_MIC_INIT); -+ } -+ -+ usleep_range(200, 250); /* estimated value */ -+ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ /* vendor step 1 */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON05(grp), -+ RK3308_ADC_CH1_ADC_WORK | -+ RK3308_ADC_CH2_ADC_WORK, -+ RK3308_ADC_CH1_ADC_WORK | -+ RK3308_ADC_CH2_ADC_WORK); -+ } -+ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ /* vendor step 2 */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON02(grp), -+ RK3308_ADC_CH1_ALC_WORK | -+ RK3308_ADC_CH2_ALC_WORK, -+ RK3308_ADC_CH1_ALC_WORK | -+ RK3308_ADC_CH2_ALC_WORK); -+ } -+ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ /* vendor step 3 */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON00(grp), -+ RK3308_ADC_CH1_MIC_WORK | -+ RK3308_ADC_CH2_MIC_WORK, -+ RK3308_ADC_CH1_MIC_WORK | -+ RK3308_ADC_CH2_MIC_WORK); -+ } -+ -+ return 0; -+} -+ -+static int rk3308_codec_adc_ana_enable(struct rk3308_codec_priv *rk3308, -+ int type) -+{ -+ unsigned int agc_func_en; -+ int idx, grp; -+ -+ /* -+ * 1. Set the ACODEC_ADC_ANA_CON7[7:6] and ACODEC_ADC_ANA_CON7[5:4], -+ * to select the line-in or microphone as input of ADC -+ * -+ * Note1. Please ignore the step1 for enabling ADC3, ADC4, ADC5, -+ * ADC6, ADC7, and ADC8 -+ */ -+ if (rk3308->adc_grp0_using_linein) { -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(0), -+ RK3308_ADC_CH1_IN_SEL_MSK | -+ RK3308_ADC_CH2_IN_SEL_MSK, -+ RK3308_ADC_CH1_IN_LINEIN | -+ RK3308_ADC_CH2_IN_LINEIN); -+ -+ /* Keep other ADCs as MIC-IN */ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ /* The groups without line-in are >= 1 */ -+ if (grp < 1 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ regmap_update_bits(rk3308->regmap, -+ RK3308_ADC_ANA_CON07(grp), -+ RK3308_ADC_CH1_IN_SEL_MSK | -+ RK3308_ADC_CH2_IN_SEL_MSK, -+ RK3308_ADC_CH1_IN_MIC | -+ RK3308_ADC_CH2_IN_MIC); -+ } -+ } else { -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ regmap_update_bits(rk3308->regmap, -+ RK3308_ADC_ANA_CON07(grp), -+ RK3308_ADC_CH1_IN_SEL_MSK | -+ RK3308_ADC_CH2_IN_SEL_MSK, -+ RK3308_ADC_CH1_IN_MIC | -+ RK3308_ADC_CH2_IN_MIC); -+ } -+ } -+ -+ /* -+ * 2. Set ACODEC_ADC_ANA_CON0[7] and [3] to 0x1, to end the mute station -+ * of ADC, to enable the MIC module, to enable the reference voltage -+ * buffer, and to end the initialization of MIC -+ */ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON00(grp), -+ RK3308_ADC_CH1_MIC_UNMUTE | -+ RK3308_ADC_CH2_MIC_UNMUTE, -+ RK3308_ADC_CH1_MIC_UNMUTE | -+ RK3308_ADC_CH2_MIC_UNMUTE); -+ } -+ -+ /* -+ * 3. Set ACODEC_ADC_ANA_CON6[0] to 0x1, to enable the current source -+ * of audio -+ */ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON06(grp), -+ RK3308_ADC_CURRENT_MSK, -+ RK3308_ADC_CURRENT_EN); -+ } -+ -+ /* -+ * This is mainly used for BIST mode that wait ADCs are stable. -+ * -+ * By tested results, the type delay is >40us, but we need to leave -+ * enough delay margin. -+ */ -+ usleep_range(400, 500); -+ -+ /* vendor step 4*/ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON00(grp), -+ RK3308_ADC_CH1_BUF_REF_EN | -+ RK3308_ADC_CH2_BUF_REF_EN, -+ RK3308_ADC_CH1_BUF_REF_EN | -+ RK3308_ADC_CH2_BUF_REF_EN); -+ } -+ -+ /* vendor step 5 */ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON00(grp), -+ RK3308_ADC_CH1_MIC_EN | -+ RK3308_ADC_CH2_MIC_EN, -+ RK3308_ADC_CH1_MIC_EN | -+ RK3308_ADC_CH2_MIC_EN); -+ } -+ -+ /* vendor step 6 */ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON02(grp), -+ RK3308_ADC_CH1_ALC_EN | -+ RK3308_ADC_CH2_ALC_EN, -+ RK3308_ADC_CH1_ALC_EN | -+ RK3308_ADC_CH2_ALC_EN); -+ } -+ -+ /* vendor step 7 */ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON05(grp), -+ RK3308_ADC_CH1_CLK_EN | -+ RK3308_ADC_CH2_CLK_EN, -+ RK3308_ADC_CH1_CLK_EN | -+ RK3308_ADC_CH2_CLK_EN); -+ } -+ -+ /* vendor step 8 */ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON05(grp), -+ RK3308_ADC_CH1_ADC_EN | -+ RK3308_ADC_CH2_ADC_EN, -+ RK3308_ADC_CH1_ADC_EN | -+ RK3308_ADC_CH2_ADC_EN); -+ } -+ -+ /* vendor step 9 */ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON05(grp), -+ RK3308_ADC_CH1_ADC_WORK | -+ RK3308_ADC_CH2_ADC_WORK, -+ RK3308_ADC_CH1_ADC_WORK | -+ RK3308_ADC_CH2_ADC_WORK); -+ } -+ -+ /* vendor step 10 */ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON02(grp), -+ RK3308_ADC_CH1_ALC_WORK | -+ RK3308_ADC_CH2_ALC_WORK, -+ RK3308_ADC_CH1_ALC_WORK | -+ RK3308_ADC_CH2_ALC_WORK); -+ } -+ -+ /* vendor step 11 */ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON00(grp), -+ RK3308_ADC_CH1_MIC_WORK | -+ RK3308_ADC_CH2_MIC_WORK, -+ RK3308_ADC_CH1_MIC_WORK | -+ RK3308_ADC_CH2_MIC_WORK); -+ } -+ -+ /* vendor step 12 */ -+ -+ /* vendor step 13 */ -+ -+ /* vendor step 14 */ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ regmap_read(rk3308->regmap, RK3308_ALC_L_DIG_CON09(grp), -+ &agc_func_en); -+ if (rk3308->adc_zerocross || -+ agc_func_en & RK3308_AGC_FUNC_SEL_EN) { -+ regmap_update_bits(rk3308->regmap, -+ RK3308_ADC_ANA_CON02(grp), -+ RK3308_ADC_CH1_ZEROCROSS_DET_EN, -+ RK3308_ADC_CH1_ZEROCROSS_DET_EN); -+ } -+ regmap_read(rk3308->regmap, RK3308_ALC_R_DIG_CON09(grp), -+ &agc_func_en); -+ if (rk3308->adc_zerocross || -+ agc_func_en & RK3308_AGC_FUNC_SEL_EN) { -+ regmap_update_bits(rk3308->regmap, -+ RK3308_ADC_ANA_CON02(grp), -+ RK3308_ADC_CH2_ZEROCROSS_DET_EN, -+ RK3308_ADC_CH2_ZEROCROSS_DET_EN); -+ } -+ } -+ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ rk3308->adc_grps_endisable[grp] = true; -+ } -+ -+ return 0; -+} -+ -+static int rk3308_codec_adc_ana_disable(struct rk3308_codec_priv *rk3308, -+ int type) -+{ -+ int idx, grp; -+ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ /* vendor step 1 */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON02(grp), -+ RK3308_ADC_CH1_ZEROCROSS_DET_EN | -+ RK3308_ADC_CH2_ZEROCROSS_DET_EN, -+ RK3308_ADC_CH1_ZEROCROSS_DET_DIS | -+ RK3308_ADC_CH2_ZEROCROSS_DET_DIS); -+ } -+ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ /* vendor step 2 */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON05(grp), -+ RK3308_ADC_CH1_ADC_EN | -+ RK3308_ADC_CH2_ADC_EN, -+ RK3308_ADC_CH1_ADC_DIS | -+ RK3308_ADC_CH2_ADC_DIS); -+ } -+ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ /* vendor step 3 */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON05(grp), -+ RK3308_ADC_CH1_CLK_EN | -+ RK3308_ADC_CH2_CLK_EN, -+ RK3308_ADC_CH1_CLK_DIS | -+ RK3308_ADC_CH2_CLK_DIS); -+ } -+ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ /* vendor step 4 */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON02(grp), -+ RK3308_ADC_CH1_ALC_EN | -+ RK3308_ADC_CH2_ALC_EN, -+ RK3308_ADC_CH1_ALC_DIS | -+ RK3308_ADC_CH2_ALC_DIS); -+ } -+ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ /* vendor step 5 */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON00(grp), -+ RK3308_ADC_CH1_MIC_EN | -+ RK3308_ADC_CH2_MIC_EN, -+ RK3308_ADC_CH1_MIC_DIS | -+ RK3308_ADC_CH2_MIC_DIS); -+ } -+ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ /* vendor step 6 */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON00(grp), -+ RK3308_ADC_CH1_BUF_REF_EN | -+ RK3308_ADC_CH2_BUF_REF_EN, -+ RK3308_ADC_CH1_BUF_REF_DIS | -+ RK3308_ADC_CH2_BUF_REF_DIS); -+ } -+ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ /* vendor step 7 */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON06(grp), -+ RK3308_ADC_CURRENT_MSK, -+ RK3308_ADC_CURRENT_DIS); -+ } -+ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ /* vendor step 8 */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON05(grp), -+ RK3308_ADC_CH1_ADC_WORK | -+ RK3308_ADC_CH2_ADC_WORK, -+ RK3308_ADC_CH1_ADC_INIT | -+ RK3308_ADC_CH2_ADC_INIT); -+ } -+ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ /* vendor step 9 */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON02(grp), -+ RK3308_ADC_CH1_ALC_WORK | -+ RK3308_ADC_CH2_ALC_WORK, -+ RK3308_ADC_CH1_ALC_INIT | -+ RK3308_ADC_CH2_ALC_INIT); -+ } -+ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ /* vendor step 10 */ -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON00(grp), -+ RK3308_ADC_CH1_MIC_WORK | -+ RK3308_ADC_CH2_MIC_WORK, -+ RK3308_ADC_CH1_MIC_INIT | -+ RK3308_ADC_CH2_MIC_INIT); -+ } -+ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ rk3308->adc_grps_endisable[grp] = false; -+ } -+ -+ return 0; -+} -+ -+static int rk3308_codec_open_capture(struct rk3308_codec_priv *rk3308) -+{ -+ int idx, grp = 0; -+ int type = ADC_TYPE_NORMAL; -+ -+ rk3308_codec_adc_ana_enable(rk3308, type); -+ rk3308_codec_adc_reinit_mics(rk3308, type); -+ -+ if (rk3308->adc_grp0_using_linein) { -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON03(0), -+ RK3308_ADC_L_CH_BIST_MSK, -+ RK3308_ADC_L_CH_NORMAL_RIGHT); -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON03(0), -+ RK3308_ADC_R_CH_BIST_MSK, -+ RK3308_ADC_R_CH_NORMAL_LEFT); -+ } else { -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (handle_loopback(rk3308) && -+ idx == rk3308->loopback_grp && -+ grp == ADC_GRP_SKIP_MAGIC) { -+ /* -+ * Switch to dummy BIST mode (BIST keep reset -+ * now) to keep the zero input data in I2S bus. -+ * -+ * It may cause the glitch if we hold the ADC -+ * digtital i2s module in codec. -+ * -+ * Then, the grp which is set from loopback_grp. -+ */ -+ regmap_update_bits(rk3308->regmap, -+ RK3308_ADC_DIG_CON03(rk3308->loopback_grp), -+ RK3308_ADC_L_CH_BIST_MSK, -+ RK3308_ADC_L_CH_BIST_SINE); -+ regmap_update_bits(rk3308->regmap, -+ RK3308_ADC_DIG_CON03(rk3308->loopback_grp), -+ RK3308_ADC_R_CH_BIST_MSK, -+ RK3308_ADC_R_CH_BIST_SINE); -+ } else { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ regmap_update_bits(rk3308->regmap, -+ RK3308_ADC_DIG_CON03(grp), -+ RK3308_ADC_L_CH_BIST_MSK, -+ RK3308_ADC_L_CH_NORMAL_LEFT); -+ regmap_update_bits(rk3308->regmap, -+ RK3308_ADC_DIG_CON03(grp), -+ RK3308_ADC_R_CH_BIST_MSK, -+ RK3308_ADC_R_CH_NORMAL_RIGHT); -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+static void rk3308_codec_adc_mclk_disable(struct rk3308_codec_priv *rk3308) -+{ -+ regmap_update_bits(rk3308->regmap, RK3308_GLB_CON, -+ RK3308_ADC_MCLK_MSK, -+ RK3308_ADC_MCLK_DIS); -+} -+ -+static void rk3308_codec_adc_mclk_enable(struct rk3308_codec_priv *rk3308) -+{ -+ regmap_update_bits(rk3308->regmap, RK3308_GLB_CON, -+ RK3308_ADC_MCLK_MSK, -+ RK3308_ADC_MCLK_EN); -+ udelay(20); -+} -+ -+static void rk3308_codec_dac_mclk_disable(struct rk3308_codec_priv *rk3308) -+{ -+ regmap_update_bits(rk3308->regmap, RK3308_GLB_CON, -+ RK3308_DAC_MCLK_MSK, -+ RK3308_DAC_MCLK_DIS); -+} -+ -+static void rk3308_codec_dac_mclk_enable(struct rk3308_codec_priv *rk3308) -+{ -+ regmap_update_bits(rk3308->regmap, RK3308_GLB_CON, -+ RK3308_DAC_MCLK_MSK, -+ RK3308_DAC_MCLK_EN); -+ udelay(20); -+} -+ -+static int rk3308_codec_open_dbg_capture(struct rk3308_codec_priv *rk3308) -+{ -+ rk3308_codec_adc_ana_enable(rk3308, ADC_TYPE_DBG); -+ -+ return 0; -+} -+ -+static int rk3308_codec_close_dbg_capture(struct rk3308_codec_priv *rk3308) -+{ -+ rk3308_codec_adc_ana_disable(rk3308, ADC_TYPE_DBG); -+ -+ return 0; -+} -+ -+static int rk3308_codec_close_all_capture(struct rk3308_codec_priv *rk3308) -+{ -+ rk3308_codec_adc_ana_disable(rk3308, ADC_TYPE_ALL); -+ -+ return 0; -+} -+ -+static int rk3308_codec_close_capture(struct rk3308_codec_priv *rk3308) -+{ -+ rk3308_codec_adc_ana_disable(rk3308, ADC_TYPE_NORMAL); -+ -+ return 0; -+} -+ -+static int rk3308_codec_open_playback(struct rk3308_codec_priv *rk3308) -+{ -+ rk3308_codec_dac_enable(rk3308); -+ -+ return 0; -+} -+ -+static int rk3308_codec_close_playback(struct rk3308_codec_priv *rk3308) -+{ -+ rk3308_codec_dac_disable(rk3308); -+ -+ return 0; -+} -+ -+static int rk3308_codec_llp_down(struct rk3308_codec_priv *rk3308) -+{ -+ rk3308_codec_adc_mclk_disable(rk3308); -+ rk3308_codec_dac_mclk_disable(rk3308); -+ -+ return 0; -+} -+ -+static int rk3308_codec_llp_up(struct rk3308_codec_priv *rk3308) -+{ -+ rk3308_codec_adc_mclk_enable(rk3308); -+ rk3308_codec_dac_mclk_enable(rk3308); -+ -+ return 0; -+} -+ -+static int rk3308_codec_dlp_down(struct rk3308_codec_priv *rk3308) -+{ -+ rk3308_codec_micbias_disable(rk3308); -+ rk3308_codec_power_off(rk3308); -+ -+ return 0; -+} -+ -+static int rk3308_codec_dlp_up(struct rk3308_codec_priv *rk3308) -+{ -+ rk3308_codec_power_on(rk3308); -+ rk3308_codec_micbias_enable(rk3308, rk3308->micbias_volt); -+ -+ return 0; -+} -+ -+/* Just used for debug and trace power state */ -+static void rk3308_codec_set_pm_state(struct rk3308_codec_priv *rk3308, -+ int pm_state) -+{ -+ int ret; -+ -+ switch (pm_state) { -+ case PM_LLP_DOWN: -+ rk3308_codec_llp_down(rk3308); -+ break; -+ case PM_LLP_UP: -+ rk3308_codec_llp_up(rk3308); -+ break; -+ case PM_DLP_DOWN: -+ rk3308_codec_dlp_down(rk3308); -+ break; -+ case PM_DLP_UP: -+ rk3308_codec_dlp_up(rk3308); -+ break; -+ case PM_DLP_DOWN2: -+ clk_disable_unprepare(rk3308->mclk_rx); -+ clk_disable_unprepare(rk3308->mclk_tx); -+ clk_disable_unprepare(rk3308->pclk); -+ break; -+ case PM_DLP_UP2: -+ ret = clk_prepare_enable(rk3308->pclk); -+ if (ret < 0) { -+ dev_err(rk3308->plat_dev, -+ "Failed to enable acodec pclk: %d\n", ret); -+ goto err; -+ } -+ -+ ret = clk_prepare_enable(rk3308->mclk_rx); -+ if (ret < 0) { -+ dev_err(rk3308->plat_dev, -+ "Failed to enable i2s mclk_rx: %d\n", ret); -+ goto err; -+ } -+ -+ ret = clk_prepare_enable(rk3308->mclk_tx); -+ if (ret < 0) { -+ dev_err(rk3308->plat_dev, -+ "Failed to enable i2s mclk_tx: %d\n", ret); -+ goto err; -+ } -+ break; -+ default: -+ dev_err(rk3308->plat_dev, "Invalid pm_state: %d\n", pm_state); -+ goto err; -+ } -+ -+ rk3308->pm_state = pm_state; -+ -+err: -+ return; -+} -+ -+static void rk3308_codec_update_adcs_status(struct rk3308_codec_priv *rk3308, -+ int state) -+{ -+ int idx, grp; -+ -+ /* Update skip_grps flags if the ADCs need to be enabled always. */ -+ if (state == PATH_BUSY) { -+ for (idx = 0; idx < rk3308->used_adc_grps; idx++) { -+ u32 mapped_grp = to_mapped_grp(rk3308, idx); -+ -+ for (grp = 0; grp < rk3308->en_always_grps_num; grp++) { -+ u32 en_always_grp = rk3308->en_always_grps[grp]; -+ -+ if (mapped_grp == en_always_grp) -+ rk3308->skip_grps[en_always_grp] = 1; -+ } -+ } -+ } -+} -+ -+static int rk3308_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params, -+ struct snd_soc_dai *dai) -+{ -+ struct snd_soc_codec *codec = dai->codec; -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct snd_pcm_str *playback_str = -+ &substream->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK]; -+ int type = ADC_TYPE_LOOPBACK; -+ int idx, grp; -+ int ret; -+ -+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { -+ /* DAC only supports 2 channels */ -+ rk3308_codec_dac_mclk_enable(rk3308); -+ rk3308_codec_open_playback(rk3308); -+ rk3308_codec_dac_dig_config(rk3308, params); -+ rk3308_codec_set_dac_path_state(rk3308, PATH_BUSY); -+ } else { -+ if (rk3308->micbias_num && -+ !rk3308->enable_micbias) -+ rk3308_codec_micbias_enable(rk3308, rk3308->micbias_volt); -+ -+ rk3308_codec_adc_mclk_enable(rk3308); -+ ret = rk3308_codec_update_adc_grps(rk3308, params); -+ if (ret < 0) -+ return ret; -+ -+ if (handle_loopback(rk3308)) { -+ if (rk3308->micbias_num && -+ (params_channels(params) == 2) && -+ to_mapped_grp(rk3308, 0) == rk3308->loopback_grp) -+ rk3308_codec_micbias_disable(rk3308); -+ -+ /* Check the DACs are opened */ -+ if (playback_str->substream_opened) { -+ rk3308->loopback_dacs_enabled = true; -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ regmap_update_bits(rk3308->regmap, -+ RK3308_ADC_DIG_CON03(grp), -+ RK3308_ADC_L_CH_BIST_MSK, -+ RK3308_ADC_L_CH_NORMAL_LEFT); -+ regmap_update_bits(rk3308->regmap, -+ RK3308_ADC_DIG_CON03(grp), -+ RK3308_ADC_R_CH_BIST_MSK, -+ RK3308_ADC_R_CH_NORMAL_RIGHT); -+ } -+ } else { -+ rk3308->loopback_dacs_enabled = false; -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ regmap_update_bits(rk3308->regmap, -+ RK3308_ADC_DIG_CON03(grp), -+ RK3308_ADC_L_CH_BIST_MSK, -+ RK3308_ADC_L_CH_BIST_SINE); -+ regmap_update_bits(rk3308->regmap, -+ RK3308_ADC_DIG_CON03(grp), -+ RK3308_ADC_R_CH_BIST_MSK, -+ RK3308_ADC_R_CH_BIST_SINE); -+ } -+ } -+ } -+ -+ rk3308_codec_open_capture(rk3308); -+ rk3308_codec_adc_dig_config(rk3308, params); -+ rk3308_codec_update_adcs_status(rk3308, PATH_BUSY); -+ } -+ -+ return 0; -+} -+ -+static int rk3308_pcm_trigger(struct snd_pcm_substream *substream, -+ int cmd, struct snd_soc_dai *dai) -+{ -+ struct snd_soc_codec *codec = dai->codec; -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ int type = ADC_TYPE_LOOPBACK; -+ int idx, grp; -+ -+ if (handle_loopback(rk3308) && -+ rk3308->dac_output == DAC_LINEOUT && -+ substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { -+ if (cmd == SNDRV_PCM_TRIGGER_START) { -+ struct snd_pcm_str *capture_str = -+ &substream->pcm->streams[SNDRV_PCM_STREAM_CAPTURE]; -+ -+ if (capture_str->substream_opened) -+ queue_delayed_work(system_power_efficient_wq, -+ &rk3308->loopback_work, -+ msecs_to_jiffies(rk3308->delay_loopback_handle_ms)); -+ } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { -+ /* -+ * Switch to dummy bist mode to kick the glitch during disable -+ * ADCs and keep zero input data -+ */ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ regmap_update_bits(rk3308->regmap, -+ RK3308_ADC_DIG_CON03(grp), -+ RK3308_ADC_L_CH_BIST_MSK, -+ RK3308_ADC_L_CH_BIST_SINE); -+ regmap_update_bits(rk3308->regmap, -+ RK3308_ADC_DIG_CON03(grp), -+ RK3308_ADC_R_CH_BIST_MSK, -+ RK3308_ADC_R_CH_BIST_SINE); -+ } -+ rk3308_codec_adc_ana_disable(rk3308, ADC_TYPE_LOOPBACK); -+ } -+ } -+ -+ return 0; -+} -+ -+static void rk3308_pcm_shutdown(struct snd_pcm_substream *substream, -+ struct snd_soc_dai *dai) -+{ -+ struct snd_soc_codec *codec = dai->codec; -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ -+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { -+ rk3308_codec_close_playback(rk3308); -+ rk3308_codec_dac_mclk_disable(rk3308); -+ regcache_cache_only(rk3308->regmap, false); -+ regcache_sync(rk3308->regmap); -+ rk3308_codec_set_dac_path_state(rk3308, PATH_IDLE); -+ } else { -+ rk3308_codec_close_capture(rk3308); -+ if (!has_en_always_grps(rk3308)) { -+ rk3308_codec_adc_mclk_disable(rk3308); -+ rk3308_codec_update_adcs_status(rk3308, PATH_IDLE); -+ if (rk3308->micbias_num && -+ rk3308->enable_micbias) -+ rk3308_codec_micbias_disable(rk3308); -+ } -+ -+ regcache_cache_only(rk3308->regmap, false); -+ regcache_sync(rk3308->regmap); -+ } -+} -+ -+static struct snd_soc_dai_ops rk3308_dai_ops = { -+ .hw_params = rk3308_hw_params, -+ .set_fmt = rk3308_set_dai_fmt, -+ .mute_stream = rk3308_mute_stream, -+ .trigger = rk3308_pcm_trigger, -+ .shutdown = rk3308_pcm_shutdown, -+}; -+ -+static struct snd_soc_dai_driver rk3308_dai[] = { -+ { -+ .name = "rk3308-hifi", -+ .id = RK3308_HIFI, -+ .playback = { -+ .stream_name = "HiFi Playback", -+ .channels_min = 2, -+ .channels_max = 2, -+ .rates = SNDRV_PCM_RATE_8000_192000, -+ .formats = (SNDRV_PCM_FMTBIT_S16_LE | -+ SNDRV_PCM_FMTBIT_S20_3LE | -+ SNDRV_PCM_FMTBIT_S24_LE | -+ SNDRV_PCM_FMTBIT_S32_LE), -+ }, -+ .capture = { -+ .stream_name = "HiFi Capture", -+ .channels_min = 1, -+ .channels_max = 8, -+ .rates = SNDRV_PCM_RATE_8000_192000, -+ .formats = (SNDRV_PCM_FMTBIT_S16_LE | -+ SNDRV_PCM_FMTBIT_S20_3LE | -+ SNDRV_PCM_FMTBIT_S24_LE | -+ SNDRV_PCM_FMTBIT_S32_LE), -+ }, -+ .ops = &rk3308_dai_ops, -+ }, -+}; -+ -+static int rk3308_suspend(struct snd_soc_codec *codec) -+{ -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ -+ if (rk3308->no_deep_low_power) -+ goto out; -+ -+ rk3308_codec_dlp_down(rk3308); -+ clk_disable_unprepare(rk3308->mclk_rx); -+ clk_disable_unprepare(rk3308->mclk_tx); -+ clk_disable_unprepare(rk3308->pclk); -+ -+out: -+ rk3308_set_bias_level(codec, SND_SOC_BIAS_OFF); -+ return 0; -+} -+ -+static int rk3308_resume(struct snd_soc_codec *codec) -+{ -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ int ret = 0; -+ -+ if (rk3308->no_deep_low_power) -+ goto out; -+ -+ ret = clk_prepare_enable(rk3308->pclk); -+ if (ret < 0) { -+ dev_err(rk3308->plat_dev, -+ "Failed to enable acodec pclk: %d\n", ret); -+ goto out; -+ } -+ -+ ret = clk_prepare_enable(rk3308->mclk_rx); -+ if (ret < 0) { -+ dev_err(rk3308->plat_dev, -+ "Failed to enable i2s mclk_rx: %d\n", ret); -+ goto out; -+ } -+ -+ ret = clk_prepare_enable(rk3308->mclk_tx); -+ if (ret < 0) { -+ dev_err(rk3308->plat_dev, -+ "Failed to enable i2s mclk_tx: %d\n", ret); -+ goto out; -+ } -+ -+ rk3308_codec_dlp_up(rk3308); -+out: -+ rk3308_set_bias_level(codec, SND_SOC_BIAS_STANDBY); -+ return ret; -+} -+ -+static int rk3308_codec_default_gains(struct rk3308_codec_priv *rk3308) -+{ -+ int grp; -+ -+ /* Prepare ADC gains */ -+ /* vendor step 12, set MIC PGA default gains */ -+ for (grp = 0; grp < ADC_LR_GROUP_MAX; grp++) { -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON01(grp), -+ RK3308_ADC_CH1_MIC_GAIN_MSK | -+ RK3308_ADC_CH2_MIC_GAIN_MSK, -+ RK3308_ADC_CH1_MIC_GAIN_0DB | -+ RK3308_ADC_CH2_MIC_GAIN_0DB); -+ } -+ -+ /* vendor step 13, set ALC default gains */ -+ for (grp = 0; grp < ADC_LR_GROUP_MAX; grp++) { -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON03(grp), -+ RK3308_ADC_CH1_ALC_GAIN_MSK, -+ RK3308_ADC_CH1_ALC_GAIN_0DB); -+ regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON04(grp), -+ RK3308_ADC_CH2_ALC_GAIN_MSK, -+ RK3308_ADC_CH2_ALC_GAIN_0DB); -+ } -+ -+ /* Prepare DAC gains */ -+ /* Step 15, set HPMIX default gains */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON12, -+ RK3308_DAC_L_HPMIX_GAIN_MSK | -+ RK3308_DAC_R_HPMIX_GAIN_MSK, -+ RK3308_DAC_L_HPMIX_GAIN_NDB_6 | -+ RK3308_DAC_R_HPMIX_GAIN_NDB_6); -+ -+ /* Step 18, set HPOUT default gains */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON05, -+ RK3308_DAC_L_HPOUT_GAIN_MSK, -+ RK3308_DAC_L_HPOUT_GAIN_NDB_39); -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON06, -+ RK3308_DAC_R_HPOUT_GAIN_MSK, -+ RK3308_DAC_R_HPOUT_GAIN_NDB_39); -+ -+ /* Using the same gain to HPOUT LR channels */ -+ rk3308->hpout_l_dgain = RK3308_DAC_L_HPOUT_GAIN_NDB_39; -+ -+ /* Step 19, set LINEOUT default gains */ -+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04, -+ RK3308_DAC_L_LINEOUT_GAIN_MSK | -+ RK3308_DAC_R_LINEOUT_GAIN_MSK, -+ RK3308_DAC_L_LINEOUT_GAIN_NDB_6 | -+ RK3308_DAC_R_LINEOUT_GAIN_NDB_6); -+ -+ return 0; -+} -+ -+static int rk3308_codec_setup_en_always_adcs(struct rk3308_codec_priv *rk3308, -+ struct device_node *np) -+{ -+ int num, ret; -+ -+ num = of_count_phandle_with_args(np, "rockchip,en-always-grps", NULL); -+ if (num < 0) { -+ if (num == -ENOENT) { -+ /* -+ * If there is note use 'rockchip,en-always-grps' -+ * property, return 0 is also right. -+ */ -+ ret = 0; -+ } else { -+ dev_err(rk3308->plat_dev, -+ "Failed to read 'rockchip,adc-grps-route' num: %d\n", -+ num); -+ ret = num; -+ } -+ -+ rk3308->en_always_grps_num = 0; -+ return ret; -+ } -+ -+ rk3308->en_always_grps_num = num; -+ -+ ret = of_property_read_u32_array(np, "rockchip,en-always-grps", -+ rk3308->en_always_grps, num); -+ if (ret < 0) { -+ dev_err(rk3308->plat_dev, -+ "Failed to read 'rockchip,en-always-grps': %d\n", -+ ret); -+ return ret; -+ } -+ -+ /* Clear all of skip_grps flags. */ -+ for (num = 0; num < ADC_LR_GROUP_MAX; num++) -+ rk3308->skip_grps[num] = 0; -+ -+ /* The loopback grp should not be enabled always. */ -+ for (num = 0; num < rk3308->en_always_grps_num; num++) { -+ if (rk3308->en_always_grps[num] == rk3308->loopback_grp) { -+ dev_err(rk3308->plat_dev, -+ "loopback_grp: %d should not be enabled always!\n", -+ rk3308->loopback_grp); -+ ret = -EINVAL; -+ return ret; -+ } -+ } -+ -+ return 0; -+} -+ -+static int rk3308_codec_dapm_mic_gains(struct rk3308_codec_priv *rk3308) -+{ -+ int ret; -+ -+ if (rk3308->codec_ver == ACODEC_VERSION_B) { -+ ret = snd_soc_add_codec_controls(rk3308->codec, -+ mic_gains_b, -+ ARRAY_SIZE(mic_gains_b)); -+ if (ret) { -+ dev_err(rk3308->plat_dev, -+ "%s: add mic_gains_b failed: %d\n", -+ __func__, ret); -+ return ret; -+ } -+ } else { -+ ret = snd_soc_add_codec_controls(rk3308->codec, -+ mic_gains_a, -+ ARRAY_SIZE(mic_gains_a)); -+ if (ret) { -+ dev_err(rk3308->plat_dev, -+ "%s: add mic_gains_a failed: %d\n", -+ __func__, ret); -+ return ret; -+ } -+ } -+ -+ return 0; -+} -+ -+static int rk3308_codec_check_micbias(struct rk3308_codec_priv *rk3308, -+ struct device_node *np) -+{ -+ struct device *dev = (struct device *)rk3308->plat_dev; -+ int num = 0, ret; -+ -+ /* Check internal micbias */ -+ rk3308->micbias1 = -+ of_property_read_bool(np, "rockchip,micbias1"); -+ if (rk3308->micbias1) -+ num++; -+ -+ rk3308->micbias2 = -+ of_property_read_bool(np, "rockchip,micbias2"); -+ if (rk3308->micbias2) -+ num++; -+ -+ rk3308->micbias_volt = RK3308_ADC_MICBIAS_VOLT_0_85; /* by default */ -+ rk3308->micbias_num = num; -+ -+ /* Check external micbias */ -+ rk3308->ext_micbias = EXT_MICBIAS_NONE; -+ -+ rk3308->micbias_en_gpio = devm_gpiod_get_optional(dev, -+ "micbias-en", -+ GPIOD_IN); -+ if (!rk3308->micbias_en_gpio) { -+ dev_info(dev, "Don't need micbias-en gpio\n"); -+ } else if (IS_ERR(rk3308->micbias_en_gpio)) { -+ ret = PTR_ERR(rk3308->micbias_en_gpio); -+ dev_err(dev, "Unable to claim gpio micbias-en\n"); -+ return ret; -+ } else if (gpiod_get_value(rk3308->micbias_en_gpio)) { -+ rk3308->ext_micbias = EXT_MICBIAS_FUNC1; -+ } -+ -+ rk3308->vcc_micbias = devm_regulator_get_optional(dev, -+ "vmicbias"); -+ if (IS_ERR(rk3308->vcc_micbias)) { -+ if (PTR_ERR(rk3308->vcc_micbias) == -EPROBE_DEFER) -+ return -EPROBE_DEFER; -+ dev_info(dev, "no vmicbias regulator found\n"); -+ } else { -+ ret = regulator_enable(rk3308->vcc_micbias); -+ if (ret) { -+ dev_err(dev, "Can't enable vmicbias: %d\n", ret); -+ return ret; -+ } -+ rk3308->ext_micbias = EXT_MICBIAS_FUNC2; -+ } -+ -+ dev_info(dev, "Check ext_micbias: %d\n", rk3308->ext_micbias); -+ -+ return 0; -+} -+ -+static int rk3308_codec_dapm_controls_prepare(struct rk3308_codec_priv *rk3308) -+{ -+ int grp; -+ -+ for (grp = 0; grp < ADC_LR_GROUP_MAX; grp++) { -+ rk3308->hpf_cutoff[grp] = 0; -+ rk3308->agc_l[grp] = 0; -+ rk3308->agc_r[grp] = 0; -+ rk3308->agc_asr_l[grp] = AGC_ASR_96KHZ; -+ rk3308->agc_asr_r[grp] = AGC_ASR_96KHZ; -+ } -+ -+ rk3308_codec_dapm_mic_gains(rk3308); -+ -+ return 0; -+} -+ -+static int rk3308_codec_prepare(struct rk3308_codec_priv *rk3308) -+{ -+ /* Clear registers for ADC and DAC */ -+ rk3308_codec_close_playback(rk3308); -+ rk3308_codec_close_all_capture(rk3308); -+ rk3308_codec_default_gains(rk3308); -+ rk3308_codec_llp_down(rk3308); -+ rk3308_codec_dapm_controls_prepare(rk3308); -+ -+ return 0; -+} -+ -+static int rk3308_probe(struct snd_soc_codec *codec) -+{ -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ int ext_micbias; -+ -+ rk3308->codec = codec; -+ rk3308_codec_set_dac_path_state(rk3308, PATH_IDLE); -+ -+ rk3308_codec_reset(codec); -+ rk3308_codec_power_on(rk3308); -+ -+ /* From vendor recommend, disable micbias at first. */ -+ ext_micbias = rk3308->ext_micbias; -+ rk3308->ext_micbias = EXT_MICBIAS_NONE; -+ rk3308_codec_micbias_disable(rk3308); -+ rk3308->ext_micbias = ext_micbias; -+ -+ rk3308_codec_prepare(rk3308); -+ if (!rk3308->no_hp_det) -+ rk3308_codec_headset_detect_enable(rk3308); -+ -+ regcache_cache_only(rk3308->regmap, false); -+ regcache_sync(rk3308->regmap); -+ -+ return 0; -+} - -- /* 5. Wait until the voltage of VCM keeps stable at the AGND */ -- usleep_range(200, 300); /* estimated value */ -+static int rk3308_remove(struct snd_soc_codec *codec) -+{ -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ -+ rk3308_headphone_ctl(rk3308, 0); -+ rk3308_speaker_ctl(rk3308, 0); -+ if (!rk3308->no_hp_det) -+ rk3308_codec_headset_detect_disable(rk3308); -+ rk3308_codec_micbias_disable(rk3308); -+ rk3308_codec_power_off(rk3308); - -- /* 6. Power off the analog power supply */ -- /* 7. Power off the digital power supply */ -+ rk3308_codec_set_dac_path_state(rk3308, PATH_IDLE); - -- /* Do something via hardware */ -+ regcache_cache_only(rk3308->regmap, false); -+ regcache_sync(rk3308->regmap); - - return 0; - } - --static int check_micbias(int micbias) -+static struct snd_soc_codec_driver soc_codec_dev_rk3308 = { -+ .probe = rk3308_probe, -+ .remove = rk3308_remove, -+ .suspend = rk3308_suspend, -+ .resume = rk3308_resume, -+ .set_bias_level = rk3308_set_bias_level, -+ .controls = rk3308_codec_dapm_controls, -+ .num_controls = ARRAY_SIZE(rk3308_codec_dapm_controls), -+}; -+ -+static const struct reg_default rk3308_codec_reg_defaults[] = { -+ { RK3308_GLB_CON, 0x07 }, -+}; -+ -+static bool rk3308_codec_write_read_reg(struct device *dev, unsigned int reg) - { -- switch (micbias) { -- case RK3308_ADC_MICBIAS_VOLT_0_85: -- case RK3308_ADC_MICBIAS_VOLT_0_8: -- case RK3308_ADC_MICBIAS_VOLT_0_75: -- case RK3308_ADC_MICBIAS_VOLT_0_7: -- case RK3308_ADC_MICBIAS_VOLT_0_65: -- case RK3308_ADC_MICBIAS_VOLT_0_6: -- case RK3308_ADC_MICBIAS_VOLT_0_55: -- case RK3308_ADC_MICBIAS_VOLT_0_5: -- return 0; -- } -+ /* All registers can be read / write */ -+ return true; -+} - -- return -EINVAL; -+static bool rk3308_codec_volatile_reg(struct device *dev, unsigned int reg) -+{ -+ return true; - } - --static int rk3308_codec_micbias_enable(struct rk3308_codec_priv *rk3308, -- int micbias) -+static void rk3308_codec_hpdetect_work(struct work_struct *work) - { -- int ch = rk3308->adc_ch; -- int ret; -+ struct rk3308_codec_priv *rk3308 = -+ container_of(work, struct rk3308_codec_priv, hpdet_work.work); -+ unsigned int val; -+ int need_poll = 0, need_irq = 0; -+ int need_report = 0, report_type = 0; -+ int dac_output = DAC_LINEOUT; -+ -+ if (rk3308->codec_ver == ACODEC_VERSION_B) { -+ /* Check headphone plugged/unplugged directly. */ -+ regmap_read(rk3308->detect_grf, -+ DETECT_GRF_ACODEC_HPDET_STATUS, &val); -+ regmap_write(rk3308->detect_grf, -+ DETECT_GRF_ACODEC_HPDET_STATUS_CLR, val); -+ -+ if (rk3308->hp_jack_reversed) { -+ switch (val) { -+ case 0x0: -+ case 0x2: -+ dac_output = DAC_HPOUT; -+ report_type = SND_JACK_HEADPHONE; -+ break; -+ default: -+ break; -+ } -+ } else { -+ switch (val) { -+ case 0x1: -+ dac_output = DAC_HPOUT; -+ report_type = SND_JACK_HEADPHONE; -+ break; -+ default: -+ /* Includes val == 2 or others. */ -+ break; -+ } -+ } - -- if (ch != 1 && ch != 2) { -- dev_err(rk3308->plat_dev, -- "%s: currnet ch: %d, only ch1/2 control MICBIAS1/2\n", -- __func__, ch); -- return -EINVAL; -- } -+ rk3308_codec_dac_switch(rk3308, dac_output); -+ if (rk3308->hpdet_jack) -+ snd_soc_jack_report(rk3308->hpdet_jack, -+ report_type, -+ SND_JACK_HEADPHONE); - -- /* 1. Power up the ACODEC and keep the AVDDH stable */ -+ enable_irq(rk3308->irq); - -- /* 2. Configure ACODEC_ADC_ANA_CON7[2:0] to the certain value */ -- ret = check_micbias(micbias); -- if (ret < 0) { -- dev_err(rk3308->plat_dev, "This is an invalid micbias: %d\n", -- micbias); -- return ret; -+ return; - } - -- /* -- * Note: Only the reg (ADC_ANA_CON7+0x0)[2:0] represent the level range -- * control signal of MICBIAS voltage -- */ -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(0), -- RK3308_ADC_LEVEL_RANGE_MICBIAS_MSK, -- micbias); -+ /* Check headphone unplugged via poll. */ -+ regmap_read(rk3308->regmap, RK3308_DAC_DIG_CON14, &val); - -- /* 3. Wait until the VCMH keep stable */ -- usleep_range(200, 300); /* estimated value */ -+ if (rk3308->hp_jack_reversed) { -+ if (!val) { -+ rk3308->hp_plugged = true; -+ report_type = SND_JACK_HEADPHONE; - -- /* 4. Configure ACODEC_ADC_ANA_CON8[4] to 0x1 */ -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON08(ch), -- RK3308_ADC_MICBIAS_CURRENT_MSK, -- RK3308_ADC_MICBIAS_CURRENT_EN); -+ need_report = 1; -+ need_irq = 1; -+ } else { -+ if (rk3308->hp_plugged) { -+ rk3308->hp_plugged = false; -+ need_report = 1; -+ } -+ need_poll = 1; -+ } -+ } else { -+ if (!val) { -+ rk3308->hp_plugged = false; - -- /* -- * 5. Configure the (ADC_ANA_CON7+0x40)[3] or (ADC_ANA_CON7+0x80)[3] -- * to 0x1. -- * (ADC_ANA_CON7+0x40)[3] used to control the MICBIAS1, and -- * (ADC_ANA_CON7+0x80)[3] used to control the MICBIAS2 -- */ -+ need_report = 1; -+ need_irq = 1; -+ } else { -+ if (!rk3308->hp_plugged) { -+ rk3308->hp_plugged = true; -+ report_type = SND_JACK_HEADPHONE; -+ need_report = 1; -+ } -+ need_poll = 1; -+ } -+ } - -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(ch), -- RK3308_ADC_MIC_BIAS_BUF_EN, -- RK3308_ADC_MIC_BIAS_BUF_EN); -+ if (need_poll) -+ queue_delayed_work(system_power_efficient_wq, -+ &rk3308->hpdet_work, -+ msecs_to_jiffies(HPDET_POLL_MS)); - -- return 0; --} -+ if (need_report) { -+ if (report_type) -+ dac_output = DAC_HPOUT; - --static int rk3308_codec_micbias_disable(struct rk3308_codec_priv *rk3308) --{ -- int ch = rk3308->adc_ch; -+ rk3308_codec_dac_switch(rk3308, dac_output); - -- if (ch != 1 && ch != 2) { -- dev_err(rk3308->plat_dev, -- "%s: currnet ch: %d, only ch1/2 control MICBIAS1/2\n", -- __func__, ch); -- return -EINVAL; -+ if (rk3308->hpdet_jack) -+ snd_soc_jack_report(rk3308->hpdet_jack, -+ report_type, -+ SND_JACK_HEADPHONE); - } - -- /* 1. Enable the MICBIAS and keep the Audio Codec stable */ -- /* Do nothing */ -- -- /* -- * 2. Configure the (ADC_ANA_CON7+0x40)[3] or -- * (ADC_ANA_CON7+0x80)[3] to 0x0 -- */ -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(ch), -- RK3308_ADC_MIC_BIAS_BUF_EN, -- RK3308_ADC_MIC_BIAS_BUF_DIS); -- -- /* 3. Configure ACODEC_ADC_ANA_CON8[4] to 0x0 */ -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON08(ch), -- RK3308_ADC_MICBIAS_CURRENT_MSK, -- RK3308_ADC_MICBIAS_CURRENT_DIS); -+ if (need_irq) -+ enable_irq(rk3308->irq); -+} - -- return 0; -+static void rk3308_codec_loopback_work(struct work_struct *work) -+{ -+ struct rk3308_codec_priv *rk3308 = -+ container_of(work, struct rk3308_codec_priv, loopback_work.work); -+ int type = ADC_TYPE_LOOPBACK; -+ int idx, grp; -+ -+ /* Prepare loopback ADCs */ -+ rk3308_codec_adc_ana_enable(rk3308, type); -+ -+ /* Waiting ADCs are stable */ -+ msleep(ADC_STABLE_MS); -+ -+ /* Recover normal mode after enable ADCs */ -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { -+ if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) -+ continue; -+ -+ regmap_update_bits(rk3308->regmap, -+ RK3308_ADC_DIG_CON03(grp), -+ RK3308_ADC_L_CH_BIST_MSK, -+ RK3308_ADC_L_CH_NORMAL_LEFT); -+ regmap_update_bits(rk3308->regmap, -+ RK3308_ADC_DIG_CON03(grp), -+ RK3308_ADC_R_CH_BIST_MSK, -+ RK3308_ADC_R_CH_NORMAL_RIGHT); -+ } - } - --static int rk3308_codec_alc_enable(struct rk3308_codec_priv *rk3308) -+static irqreturn_t rk3308_codec_hpdet_isr(int irq, void *data) - { -- int ch = rk3308->adc_ch; -+ struct rk3308_codec_priv *rk3308 = data; - - /* -- * 1. Set he max level and min level of the ALC need to control. -- * -- * These values are estimated -+ * For the high level irq trigger, disable irq and avoid a lot of -+ * repeated irq handlers entry. - */ -- regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON05(ch), -- RK3308_AGC_LO_8BITS_AGC_MIN_MSK, -- 0x16); -- regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON05(ch), -- RK3308_AGC_HI_8BITS_AGC_MIN_MSK, -- 0x40); -- -- regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON05(ch), -- RK3308_AGC_LO_8BITS_AGC_MAX_MSK, -- 0x26); -- regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON05(ch), -- RK3308_AGC_HI_8BITS_AGC_MAX_MSK, -- 0x40); -+ disable_irq_nosync(rk3308->irq); -+ queue_delayed_work(system_power_efficient_wq, -+ &rk3308->hpdet_work, msecs_to_jiffies(10)); - -- /* -- * 2. Set ACODEC_ALC_DIG_CON4[2:0] according to the sample rate -- * -- * By default is 44.1KHz for sample. -- */ -- regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON04(ch), -- RK3308_AGC_APPROX_RATE_MSK, -- RK3308_AGC_APPROX_RATE_44_1K); -- regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON04(ch), -- RK3308_AGC_APPROX_RATE_MSK, -- RK3308_AGC_APPROX_RATE_44_1K); -- -- /* 3. Set ACODEC_ALC_DIG_CON9[6] to 0x1, to enable the ALC module */ -- regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON09(ch), -- RK3308_AGC_FUNC_SEL_MSK, -- RK3308_AGC_FUNC_SEL_EN); -- regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON09(ch), -- RK3308_AGC_FUNC_SEL_MSK, -- RK3308_AGC_FUNC_SEL_EN); -+ return IRQ_HANDLED; -+} - -- /* -- * 4. Set ACODEC_ADC_ANA_CON11[1:0], (ACODEC_ADC_ANA_CON11+0x40)[1:0], -- * (ACODEC_ADC_ANA_CON11+0x80)[1:0] and (ACODEC_ADC_ANA_CON11+0xc0)[1:0] -- * to 0x3, to enable the ALC module to control the gain of PGA. -- */ -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON11(ch), -- RK3308_ADC_ALCL_CON_GAIN_PGAL_MSK | -- RK3308_ADC_ALCR_CON_GAIN_PGAR_MSK, -- RK3308_ADC_ALCL_CON_GAIN_PGAL_EN | -- RK3308_ADC_ALCR_CON_GAIN_PGAR_EN); -+void (*rk3308_codec_set_jack_detect_cb)(struct snd_soc_codec *codec, -+ struct snd_soc_jack *hpdet_jack); -+EXPORT_SYMBOL_GPL(rk3308_codec_set_jack_detect_cb); - -- /* -- * 5.Observe the current ALC output gain by reading -- * ACODEC_ALC_DIG_CON12[4:0] -- * -- * The default GAIN is 0x0c -- */ -- regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON12(ch), -- RK3308_AGC_GAIN_MSK, -- 0x0c); -- regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON12(ch), -- RK3308_AGC_GAIN_MSK, -- 0x0c); -+static void rk3308_codec_set_jack_detect(struct snd_soc_codec *codec, -+ struct snd_soc_jack *hpdet_jack) -+{ -+ struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); - -- return 0; --} -+ rk3308->hpdet_jack = hpdet_jack; - --static int rk3308_codec_alc_disable(struct rk3308_codec_priv *rk3308) --{ -- int ch = rk3308->adc_ch; -+ /* To detect jack once during startup */ -+ disable_irq_nosync(rk3308->irq); -+ queue_delayed_work(system_power_efficient_wq, -+ &rk3308->hpdet_work, msecs_to_jiffies(10)); - -- /* -- * 1. Set ACODEC_ALC_DIG_CON9[6] to 0x0, to disable the ALC module, -- * then the ALC output gain will keep to the last value -- */ -- regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON09(ch), -- RK3308_AGC_FUNC_SEL_MSK, -- RK3308_AGC_FUNC_SEL_DIS); -- regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON09(ch), -- RK3308_AGC_FUNC_SEL_MSK, -- RK3308_AGC_FUNC_SEL_DIS); -+ dev_info(rk3308->plat_dev, "%s: Request detect hp jack once\n", -+ __func__); -+} - -- /* -- * 2. Set ACODEC_ADC_ANA_CON11[1:0], (ACODEC_ADC_ANA_CON11+0x40)[1:0], -- * (ACODEC_ADC_ANA_CON11+0x80)[1:0] and (ACODEC_ADC_ANA_CON11+0xc0)[1:0] -- * to 0x0, to disable the ALC module to control the gain of PGA. -- */ -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON11(ch), -- RK3308_ADC_ALCL_CON_GAIN_PGAL_MSK | -- RK3308_ADC_ALCR_CON_GAIN_PGAR_MSK, -- RK3308_ADC_ALCL_CON_GAIN_PGAL_DIS | -- RK3308_ADC_ALCR_CON_GAIN_PGAR_DIS); -+static const struct regmap_config rk3308_codec_regmap_config = { -+ .reg_bits = 32, -+ .reg_stride = 4, -+ .val_bits = 32, -+ .max_register = RK3308_DAC_ANA_CON15, -+ .writeable_reg = rk3308_codec_write_read_reg, -+ .readable_reg = rk3308_codec_write_read_reg, -+ .volatile_reg = rk3308_codec_volatile_reg, -+ .reg_defaults = rk3308_codec_reg_defaults, -+ .num_reg_defaults = ARRAY_SIZE(rk3308_codec_reg_defaults), -+ .cache_type = REGCACHE_FLAT, -+}; - -- return 0; -+static ssize_t pm_state_show(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct rk3308_codec_priv *rk3308 = -+ container_of(dev, struct rk3308_codec_priv, dev); -+ -+ return sprintf(buf, "pm_state: %d\n", rk3308->pm_state); - } - --static int rk3308_codec_adc_ana_enable(struct rk3308_codec_priv *rk3308) -+static ssize_t pm_state_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) - { -- unsigned int adc_aif1 = 0, adc_aif2 = 0; -- unsigned int agc_func_en; -- int ch = rk3308->adc_ch; -+ struct rk3308_codec_priv *rk3308 = -+ container_of(dev, struct rk3308_codec_priv, dev); -+ unsigned long pm_state; -+ int ret = kstrtoul(buf, 10, &pm_state); - -- /* -- * 1. Set the ACODEC_ADC_ANA_CON7[7:6] and ACODEC_ADC_ANA_CON7[5:4], -- * to select the line-in or microphone as input of ADC -- * -- * Note1. Please ignore the step1 for enabling ADC3, ADC4, ADC5, -- * ADC6, ADC7, and ADC8 -- */ -- if (ch == 0) { -- if (rk3308->adc_ch0_using_linein) { -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(ch), -- RK3308_ADC_CH1_IN_SEL_MSK, -- RK3308_ADC_CH1_IN_LINEIN); -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(ch), -- RK3308_ADC_CH2_IN_SEL_MSK, -- RK3308_ADC_CH2_IN_LINEIN); -- } else { -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(ch), -- RK3308_ADC_CH1_IN_SEL_MSK, -- RK3308_ADC_CH1_IN_MIC); -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(ch), -- RK3308_ADC_CH2_IN_SEL_MSK, -- RK3308_ADC_CH2_IN_MIC); -- } -+ if (ret < 0) { -+ dev_err(dev, "Invalid pm_state: %ld, ret: %d\n", -+ pm_state, ret); -+ return -EINVAL; - } - -- /* -- * 2. Set ACODEC_ADC_ANA_CON0[7:0] to 0xff, to end the mute station -- * of ADC, to enable the MIC module, to enable the reference voltage -- * buffer, and to end the initialization of MIC -- */ -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON00(ch), -- RK3308_ADC_CH1_CH2_MIC_ALL_MSK, -- RK3308_ADC_CH1_CH2_MIC_ALL); -+ rk3308_codec_set_pm_state(rk3308, pm_state); - -- /* -- * 3. Set ACODEC_ADC_ANA_CON6[0] to 0x1, to enable the current source -- * of audio -- */ -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON06(ch), -- RK3308_ADC_CURRENT_MSK, -- RK3308_ADC_CURRENT_EN); -+ dev_info(dev, "Store pm_state: %d\n", rk3308->pm_state); - -- /* -- * 4. Set ACODEC_ADC_ANA_CON2[7:0] to 0x77, to enable the ALC module, -- * to enable the zero-crossing detection function, and to end the -- * initialization of ALC -- * -- * Note2. Please set ACODEC_ADC_ANA_CON2[7:0] to 0x33 in step4 -- * if the AGC function is closed -- */ -+ return count; -+} - -- adc_aif1 = RK3308_ADC_CH1_ALC_EN | RK3308_ADC_CH1_ALC_WORK; -- regmap_read(rk3308->regmap, RK3308_ALC_L_DIG_CON09(ch), &agc_func_en); -- if (agc_func_en & RK3308_AGC_FUNC_SEL_EN) -- adc_aif1 |= RK3308_ADC_CH1_ZEROCROSS_DET_EN; -+static ssize_t adc_grps_show(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct rk3308_codec_priv *rk3308 = -+ container_of(dev, struct rk3308_codec_priv, dev); -+ u32 grp; -+ int type = ADC_TYPE_NORMAL, count = 0; -+ int idx; -+ -+ count += sprintf(buf + count, "current used adc_grps:\n"); -+ count += sprintf(buf + count, "- normal:"); -+ for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) -+ count += sprintf(buf + count, " %d", grp); -+ count += sprintf(buf + count, "\n"); -+ count += sprintf(buf + count, "- loopback: %d\n", -+ rk3308->loopback_grp); - -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON02(ch), -- RK3308_ADC_CH1_ALC_ZC_MSK, -- adc_aif1); -+ return count; -+} - -- adc_aif2 = RK3308_ADC_CH2_ALC_EN | RK3308_ADC_CH2_ALC_WORK; -- regmap_read(rk3308->regmap, RK3308_ALC_L_DIG_CON09(ch), &agc_func_en); -- if (agc_func_en & RK3308_AGC_FUNC_SEL_EN) -- adc_aif2 |= RK3308_ADC_CH2_ZEROCROSS_DET_EN; -+static ssize_t adc_grps_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct rk3308_codec_priv *rk3308 = -+ container_of(dev, struct rk3308_codec_priv, dev); -+ char adc_type; -+ int grps, ret; -+ -+ ret = sscanf(buf, "%c,%d", &adc_type, &grps); -+ if (ret != 2) { -+ dev_err(rk3308->plat_dev, "%s sscanf failed: %d\n", -+ __func__, ret); -+ return -EFAULT; -+ } - -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON02(ch), -- RK3308_ADC_CH2_ALC_ZC_MSK, -- adc_aif2); -+ if (adc_type == 'n') -+ rk3308->used_adc_grps = grps; -+ else if (adc_type == 'l') -+ rk3308->loopback_grp = grps; - -- /* -- * 5. Set ACODEC_ADC_ANA_CON5[7:0] to 0x77, to enable the clock and -- * ADC module, and to end the initialization of ADC -- */ -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON05(ch), -- RK3308_ADC_CH1_ADC_CLK_MSK, -- RK3308_ADC_CH1_CLK_EN | -- RK3308_ADC_CH1_ADC_EN | -- RK3308_ADC_CH1_ADC_WORK); -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON05(ch), -- RK3308_ADC_CH2_ADC_CLK_MSK, -- RK3308_ADC_CH2_CLK_EN | -- RK3308_ADC_CH2_ADC_EN | -- RK3308_ADC_CH2_ADC_WORK); -+ return count; -+} - -- /* -- * 6. Set ACODEC_ADC_ANA_CON1[5:4] and ACODEC_ADC_ANA_CON1[1:0], -- * to select the gain of the MIC -- * -- * By default is 0db. -- */ -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON05(ch), -- RK3308_ADC_CH1_MIC_GAIN_MSK, -- RK3308_ADC_CH1_MIC_GAIN_0DB); -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON05(ch), -- RK3308_ADC_CH2_MIC_GAIN_MSK, -- RK3308_ADC_CH2_MIC_GAIN_0DB); -+static ssize_t adc_grps_route_show(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct rk3308_codec_priv *rk3308 = -+ container_of(dev, struct rk3308_codec_priv, dev); -+ char which_i2s[32] = {0}; -+ int count = 0; -+ u32 grp; - -- /* -- * 7.Set ACODEC_ADC_ANA_CON3[4:0] and ACODEC_ADC_ANA_CON4[3:0] to -- * select the gain of ALC -- * -- * By default is 0db. -- */ -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON03(ch), -- RK3308_ADC_CH1_ALC_GAIN_MSK, -- RK3308_ADC_CH1_ALC_GAIN_0DB); -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON04(ch), -- RK3308_ADC_CH2_ALC_GAIN_MSK, -- RK3308_ADC_CH2_ALC_GAIN_0DB); -+ switch (rk3308->which_i2s) { -+ case ACODEC_TO_I2S1_2CH: -+ strcpy(which_i2s, "i2s1_2ch"); -+ break; -+ case ACODEC_TO_I2S3_4CH: -+ strcpy(which_i2s, "i2s3_4ch"); -+ break; -+ default: -+ strcpy(which_i2s, "i2s2_8ch"); -+ break; -+ } - -- /* 8.Begin recording */ -+ count += sprintf(buf + count, "%s from acodec route mapping:\n", -+ which_i2s); -+ for (grp = 0; grp < rk3308->to_i2s_grps; grp++) { -+ count += sprintf(buf + count, "* sdi_%d <-- sdo_%d\n", -+ grp, rk3308->i2s_sdis[grp]); -+ } - -- return 0; -+ return count; - } - --static int rk3308_codec_adc_ana_disable(struct rk3308_codec_priv *rk3308) -+static ssize_t adc_grps_route_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) - { -- int ch = rk3308->adc_ch; -+ struct rk3308_codec_priv *rk3308 = -+ container_of(dev, struct rk3308_codec_priv, dev); -+ int which_i2s, idx, i2s_sdis[ADC_LR_GROUP_MAX]; -+ int ret; - -- /* -- * 1. Set ACODEC_ADC_ANA_CON2[7:0] to 0x0, to disable the ALC module, -- * to disable the zero-crossing detection function, and to begin the -- * initialization of ALC -- */ -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON02(ch), -- RK3308_ADC_CH1_ALC_ZC_MSK, -- 0); -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON02(ch), -- RK3308_ADC_CH2_ALC_ZC_MSK, -- 0); -+ ret = sscanf(buf, "%d,%d,%d,%d,%d", &which_i2s, -+ &i2s_sdis[0], &i2s_sdis[1], &i2s_sdis[2], &i2s_sdis[3]); -+ if (ret != 5) { -+ dev_err(rk3308->plat_dev, "%s sscanf failed: %d\n", -+ __func__, ret); -+ goto err; -+ } - -- /* -- * 2. Set ACODEC_ADC_ANA_CON5[7:0] to 0x0, to disable the clock and -- * ADC module, and to begin the initialization of ADC -- */ -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON05(ch), -- RK3308_ADC_CH1_ADC_CLK_MSK, -- 0); -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON05(ch), -- RK3308_ADC_CH2_ADC_CLK_MSK, -- 0); -+ if (which_i2s < ACODEC_TO_I2S2_8CH || -+ which_i2s > ACODEC_TO_I2S1_2CH) { -+ dev_err(rk3308->plat_dev, "Invalid i2s type: %d\n", which_i2s); -+ goto err; -+ } - -- /* -- * 3. Set ACODEC_ADC_ANA_CON0[7:0] to 0x88, to disable the MIC module, -- * to disable the reference voltage buffer, and to begin the -- * initialization of MIC -- */ -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON00(ch), -- RK3308_ADC_CH1_CH2_MIC_ALL_MSK, -- RK3308_ADC_CH1_MIC_UNMUTE | -- RK3308_ADC_CH2_MIC_UNMUTE); -+ rk3308->which_i2s = which_i2s; - -- /* -- * 4. Set ACODEC_ADC_ANA_CON6[0] to 0x0, to disable the current -- * source of audio -- */ -- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON06(ch), -- RK3308_ADC_CURRENT_MSK, -- RK3308_ADC_CURRENT_DIS); -+ switch (rk3308->which_i2s) { -+ case ACODEC_TO_I2S1_2CH: -+ rk3308->to_i2s_grps = 1; -+ break; -+ case ACODEC_TO_I2S3_4CH: -+ rk3308->to_i2s_grps = 2; -+ break; -+ default: -+ rk3308->to_i2s_grps = 4; -+ break; -+ } - -- return 0; -+ for (idx = 0; idx < rk3308->to_i2s_grps; idx++) -+ rk3308->i2s_sdis[idx] = i2s_sdis[idx]; -+ -+ rk3308_codec_adc_grps_route_config(rk3308); -+ -+err: -+ return count; - } - --static int rk3308_codec_open_capture(struct snd_soc_codec *codec) -+static ssize_t adc_grp0_in_show(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) - { -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -- -- rk3308_codec_alc_enable(rk3308); -- rk3308_codec_adc_ana_enable(rk3308); -+ struct rk3308_codec_priv *rk3308 = -+ container_of(dev, struct rk3308_codec_priv, dev); - -- return 0; -+ return sprintf(buf, "adc ch0 using: %s\n", -+ rk3308->adc_grp0_using_linein ? "line in" : "mic in"); - } - --static int rk3308_codec_close_capture(struct snd_soc_codec *codec) -+static ssize_t adc_grp0_in_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) - { -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct rk3308_codec_priv *rk3308 = -+ container_of(dev, struct rk3308_codec_priv, dev); -+ unsigned long using_linein; -+ int ret = kstrtoul(buf, 10, &using_linein); -+ -+ if (ret < 0 || using_linein > 1) { -+ dev_err(dev, "Invalid input status: %ld, ret: %d\n", -+ using_linein, ret); -+ return -EINVAL; -+ } - -- rk3308_codec_alc_disable(rk3308); -- rk3308_codec_adc_ana_disable(rk3308); -+ rk3308->adc_grp0_using_linein = using_linein; - -- return 0; -+ dev_info(dev, "store using_linein: %d\n", -+ rk3308->adc_grp0_using_linein); -+ -+ return count; - } - --static int rk3308_codec_open_playback(struct snd_soc_codec *codec) -+static ssize_t adc_zerocross_show(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) - { -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -- -- rk3308_codec_dac_enable(rk3308); -- rk3308_speaker_ctl(rk3308, 1); -+ struct rk3308_codec_priv *rk3308 = -+ container_of(dev, struct rk3308_codec_priv, dev); - -- return 0; -+ return sprintf(buf, "adc zerocross: %s\n", -+ rk3308->adc_zerocross ? "enabled" : "disabled"); - } - --static int rk3308_codec_close_playback(struct snd_soc_codec *codec) -+static ssize_t adc_zerocross_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) - { -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct rk3308_codec_priv *rk3308 = -+ container_of(dev, struct rk3308_codec_priv, dev); -+ unsigned long zerocross; -+ int ret = kstrtoul(buf, 10, &zerocross); - -- rk3308_speaker_ctl(rk3308, 0); -- rk3308_codec_dac_disable(rk3308); -+ if (ret < 0 || zerocross > 1) { -+ dev_err(dev, "Invalid zerocross: %ld, ret: %d\n", -+ zerocross, ret); -+ return -EINVAL; -+ } - -- return 0; -+ rk3308->adc_zerocross = zerocross; -+ -+ dev_info(dev, "store adc zerocross: %d\n", rk3308->adc_zerocross); -+ -+ return count; - } - --static int rk3308_pcm_startup(struct snd_pcm_substream *substream, -- struct snd_soc_dai *dai) -+static ssize_t adc_grps_endisable_show(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) - { -- struct snd_soc_codec *codec = dai->codec; -- int ret = 0; -+ struct rk3308_codec_priv *rk3308 = -+ container_of(dev, struct rk3308_codec_priv, dev); -+ int count = 0, i; - -- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) -- ret = rk3308_codec_open_playback(codec); -- else -- ret = rk3308_codec_open_capture(codec); -+ count += sprintf(buf + count, "enabled adc grps:"); -+ for (i = 0; i < ADC_LR_GROUP_MAX; i++) -+ count += sprintf(buf + count, "%d ", -+ rk3308->adc_grps_endisable[i]); - -- return ret; -+ count += sprintf(buf + count, "\n"); -+ return count; - } - --static void rk3308_pcm_shutdown(struct snd_pcm_substream *substream, -- struct snd_soc_dai *dai) -+static ssize_t adc_grps_endisable_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) - { -- struct snd_soc_codec *codec = dai->codec; -+ struct rk3308_codec_priv *rk3308 = -+ container_of(dev, struct rk3308_codec_priv, dev); -+ int grp, endisable, ret; - -- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) -- rk3308_codec_close_playback(codec); -- else -- rk3308_codec_close_capture(codec); --} -+ ret = sscanf(buf, "%d,%d", &grp, &endisable); -+ if (ret != 2) { -+ dev_err(rk3308->plat_dev, "%s sscanf failed: %d\n", -+ __func__, ret); -+ return -EFAULT; -+ } - --static struct snd_soc_dai_ops rk3308_dai_ops = { -- .hw_params = rk3308_hw_params, -- .set_fmt = rk3308_set_dai_fmt, -- .digital_mute = rk3308_digital_mute, -- .startup = rk3308_pcm_startup, -- .shutdown = rk3308_pcm_shutdown, --}; -+ rk3308->cur_dbg_grp = grp; - --static struct snd_soc_dai_driver rk3308_dai[] = { -- { -- .name = "rk3308-hifi", -- .id = RK3308_HIFI, -- .playback = { -- .stream_name = "HiFi Playback", -- .channels_min = 2, -- .channels_max = 2, -- .rates = SNDRV_PCM_RATE_8000_96000, -- .formats = (SNDRV_PCM_FMTBIT_S16_LE | -- SNDRV_PCM_FMTBIT_S20_3LE | -- SNDRV_PCM_FMTBIT_S24_LE | -- SNDRV_PCM_FMTBIT_S32_LE), -- }, -- .capture = { -- .stream_name = "HiFi Capture", -- .channels_min = 1, -- .channels_max = 8, -- .rates = SNDRV_PCM_RATE_8000_96000, -- .formats = (SNDRV_PCM_FMTBIT_S16_LE | -- SNDRV_PCM_FMTBIT_S20_3LE | -- SNDRV_PCM_FMTBIT_S24_LE | -- SNDRV_PCM_FMTBIT_S32_LE), -- }, -- .ops = &rk3308_dai_ops, -- }, --}; -+ if (endisable) -+ rk3308_codec_open_dbg_capture(rk3308); -+ else -+ rk3308_codec_close_dbg_capture(rk3308); - --static int rk3308_suspend(struct snd_soc_codec *codec) --{ -- rk3308_set_bias_level(codec, SND_SOC_BIAS_OFF); -+ dev_info(dev, "ADC grp %d endisable: %d\n", grp, endisable); - -- return 0; -+ return count; - } - --static int rk3308_resume(struct snd_soc_codec *codec) -+static ssize_t dac_endisable_show(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) - { -- rk3308_set_bias_level(codec, SND_SOC_BIAS_STANDBY); -+ struct rk3308_codec_priv *rk3308 = -+ container_of(dev, struct rk3308_codec_priv, dev); - -- return 0; -+ return sprintf(buf, "%d\n", rk3308->dac_endisable); - } - --static int rk3308_probe(struct snd_soc_codec *codec) -+static ssize_t dac_endisable_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) - { -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct rk3308_codec_priv *rk3308 = -+ container_of(dev, struct rk3308_codec_priv, dev); -+ unsigned long endisable; -+ int ret = kstrtoul(buf, 10, &endisable); - -- rk3308_codec_reset(codec); -- rk3308_codec_power_on(codec); -+ if (ret < 0) { -+ dev_err(dev, "Invalid endisable: %ld, ret: %d\n", -+ endisable, ret); -+ return -EINVAL; -+ } -+ -+ if (endisable) -+ rk3308_codec_open_playback(rk3308); -+ else -+ rk3308_codec_close_playback(rk3308); - -- rk3308_codec_micbias_enable(rk3308, RK3308_ADC_MICBIAS_VOLT_0_7); -+ dev_info(dev, "DAC endisable: %ld\n", endisable); - -- return 0; -+ return count; - } - --static int rk3308_remove(struct snd_soc_codec *codec) -+static ssize_t dac_output_show(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) - { -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct rk3308_codec_priv *rk3308 = -+ container_of(dev, struct rk3308_codec_priv, dev); -+ ssize_t ret = 0; - -- rk3308_speaker_ctl(rk3308, 0); -- rk3308_codec_micbias_disable(rk3308); -- rk3308_codec_power_off(codec); -+ switch (rk3308->dac_output) { -+ case DAC_LINEOUT: -+ ret = sprintf(buf, "dac path: %s\n", "line out"); -+ break; -+ case DAC_HPOUT: -+ ret = sprintf(buf, "dac path: %s\n", "hp out"); -+ break; -+ case DAC_LINEOUT_HPOUT: -+ ret = sprintf(buf, "dac path: %s\n", -+ "both line out and hp out"); -+ break; -+ default: -+ pr_err("Invalid dac path: %d ?\n", rk3308->dac_output); -+ break; -+ } - -- return 0; -+ return ret; - } - --static struct snd_soc_codec_driver soc_codec_dev_rk3308 = { -- .probe = rk3308_probe, -- .remove = rk3308_remove, -- .suspend = rk3308_suspend, -- .resume = rk3308_resume, -- .set_bias_level = rk3308_set_bias_level, -- .controls = rk3308_codec_dapm_controls, -- .num_controls = ARRAY_SIZE(rk3308_codec_dapm_controls), --}; -- --static const struct reg_default rk3308_codec_reg_defaults[] = { -- { RK3308_GLB_CON, 0x07 }, --}; -- --static bool rk3308_codec_write_read_reg(struct device *dev, unsigned int reg) -+static ssize_t dac_output_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) - { -- /* All registers can be read / write */ -- return true; --} -+ struct rk3308_codec_priv *rk3308 = -+ container_of(dev, struct rk3308_codec_priv, dev); -+ unsigned long dac_output; -+ int ret = kstrtoul(buf, 10, &dac_output); - --static bool rk3308_codec_volatile_reg(struct device *dev, unsigned int reg) --{ -- switch (reg) { -- case RK3308_GLB_CON: -- return true; -- default: -- return false; -+ if (ret < 0) { -+ dev_err(dev, "Invalid input status: %ld, ret: %d\n", -+ dac_output, ret); -+ return -EINVAL; - } --} - --static const struct regmap_config rk3308_codec_regmap_config = { -- .reg_bits = 32, -- .reg_stride = 4, -- .val_bits = 32, -- .max_register = RK3308_DAC_ANA_CON13, -- .writeable_reg = rk3308_codec_write_read_reg, -- .readable_reg = rk3308_codec_write_read_reg, -- .volatile_reg = rk3308_codec_volatile_reg, -- .reg_defaults = rk3308_codec_reg_defaults, -- .num_reg_defaults = ARRAY_SIZE(rk3308_codec_reg_defaults), -- .cache_type = REGCACHE_FLAT, --}; -+ rk3308_codec_dac_switch(rk3308, dac_output); - --static ssize_t adc_ch_show(struct device *dev, -- struct device_attribute *attr, -- char *buf) -+ dev_info(dev, "Store dac_output: %d\n", rk3308->dac_output); -+ -+ return count; -+} -+ -+static ssize_t enable_all_adcs_show(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) - { - struct rk3308_codec_priv *rk3308 = - container_of(dev, struct rk3308_codec_priv, dev); - -- return sprintf(buf, "adc_ch: %d\n", rk3308->adc_ch); -+ return sprintf(buf, "%d\n", rk3308->enable_all_adcs); - } - --static ssize_t adc_ch_store(struct device *dev, -- struct device_attribute *attr, -- const char *buf, size_t count) -+static ssize_t enable_all_adcs_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) - { - struct rk3308_codec_priv *rk3308 = - container_of(dev, struct rk3308_codec_priv, dev); -- unsigned long ch; -- int ret = kstrtoul(buf, 10, &ch); -+ unsigned long enable; -+ int ret = kstrtoul(buf, 10, &enable); - -- if (ret < 0 || ch > 4) { -- dev_err(dev, "Invalid ch: %ld, ret: %d\n", ch, ret); -+ if (ret < 0) { -+ dev_err(dev, "Invalid enable value: %ld, ret: %d\n", -+ enable, ret); - return -EINVAL; - } - -- rk3308->adc_ch = ch; -- -- dev_info(dev, "Store ch: %d\n", rk3308->adc_ch); -+ rk3308->enable_all_adcs = enable; - - return count; - } - --static const struct device_attribute adc_ch_attrs[] = { -- __ATTR(adc_ch, 0644, adc_ch_show, adc_ch_store), -+static const struct device_attribute acodec_attrs[] = { -+ __ATTR_RW(adc_grps), -+ __ATTR_RW(adc_grps_endisable), -+ __ATTR_RW(adc_grps_route), -+ __ATTR_RW(adc_grp0_in), -+ __ATTR_RW(adc_zerocross), -+ __ATTR_RW(dac_endisable), -+ __ATTR_RW(dac_output), -+ __ATTR_RW(enable_all_adcs), -+ __ATTR_RW(pm_state), - }; - - static void rk3308_codec_device_release(struct device *dev) -@@ -1468,8 +4747,8 @@ static int rk3308_codec_sysfs_init(struct platform_device *pdev, - return -ENOMEM; - } - -- for (i = 0; i < ARRAY_SIZE(adc_ch_attrs); i++) { -- if (device_create_file(dev, &adc_ch_attrs[i])) { -+ for (i = 0; i < ARRAY_SIZE(acodec_attrs); i++) { -+ if (device_create_file(dev, &acodec_attrs[i])) { - dev_err(&pdev->dev, - "Create 'rk3308-acodec-dev' attr failed\n"); - device_unregister(dev); -@@ -1480,32 +4759,136 @@ static int rk3308_codec_sysfs_init(struct platform_device *pdev, - return 0; - } - -+#if defined(CONFIG_DEBUG_FS) -+static int rk3308_codec_debugfs_reg_show(struct seq_file *s, void *v) -+{ -+ struct rk3308_codec_priv *rk3308 = s->private; -+ unsigned int i; -+ unsigned int val; -+ -+ for (i = RK3308_GLB_CON; i <= RK3308_DAC_ANA_CON13; i += 4) { -+ regmap_read(rk3308->regmap, i, &val); -+ if (!(i % 16)) -+ seq_printf(s, "\nR:%04x: ", i); -+ seq_printf(s, "%08x ", val); -+ } -+ -+ seq_puts(s, "\n"); -+ -+ return 0; -+} -+ -+static ssize_t rk3308_codec_debugfs_reg_operate(struct file *file, -+ const char __user *buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rk3308_codec_priv *rk3308 = -+ ((struct seq_file *)file->private_data)->private; -+ unsigned int reg, val; -+ char op; -+ char kbuf[32]; -+ int ret; -+ -+ if (count >= sizeof(kbuf)) -+ return -EINVAL; -+ -+ if (copy_from_user(kbuf, buf, count)) -+ return -EFAULT; -+ kbuf[count] = '\0'; -+ -+ ret = sscanf(kbuf, "%c,%x,%x", &op, ®, &val); -+ if (ret != 3) { -+ pr_err("sscanf failed: %d\n", ret); -+ return -EFAULT; -+ } -+ -+ if (op == 'w') { -+ pr_info("Write reg: 0x%04x with val: 0x%08x\n", reg, val); -+ regmap_write(rk3308->regmap, reg, val); -+ regcache_cache_only(rk3308->regmap, false); -+ regcache_sync(rk3308->regmap); -+ pr_info("Read back reg: 0x%04x with val: 0x%08x\n", reg, val); -+ } else if (op == 'r') { -+ regmap_read(rk3308->regmap, reg, &val); -+ pr_info("Read reg: 0x%04x with val: 0x%08x\n", reg, val); -+ } else { -+ pr_err("This is an invalid operation: %c\n", op); -+ } -+ -+ return count; -+} -+ -+static int rk3308_codec_debugfs_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, -+ rk3308_codec_debugfs_reg_show, inode->i_private); -+} -+ -+static const struct file_operations rk3308_codec_reg_debugfs_fops = { -+ .owner = THIS_MODULE, -+ .open = rk3308_codec_debugfs_open, -+ .read = seq_read, -+ .write = rk3308_codec_debugfs_reg_operate, -+ .llseek = seq_lseek, -+ .release = single_release, -+}; -+#endif /* CONFIG_DEBUG_FS */ -+ -+static int rk3308_codec_get_version(struct rk3308_codec_priv *rk3308) -+{ -+ unsigned int chip_id; -+ -+ regmap_read(rk3308->grf, GRF_CHIP_ID, &chip_id); -+ switch (chip_id) { -+ case 3306: -+ rk3308->codec_ver = ACODEC_VERSION_A; -+ break; -+ case 0x3308: -+ rk3308->codec_ver = ACODEC_VERSION_B; -+ break; -+ default: -+ pr_err("Unknown chip_id: %d / 0x%x\n", chip_id, chip_id); -+ return -EFAULT; -+ } -+ -+ pr_info("The acodec version is: %x\n", rk3308->codec_ver); -+ return 0; -+} -+ - static int rk3308_platform_probe(struct platform_device *pdev) - { - struct device_node *np = pdev->dev.of_node; - struct rk3308_codec_priv *rk3308; - struct resource *res; - void __iomem *base; -- int ret = 0; -- struct regmap *grf; -- -- grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); -- if (IS_ERR(grf)) { -- dev_err(&pdev->dev, -- "Missing 'rockchip,grf' property\n"); -- return PTR_ERR(grf); -- } -+ int ret; - - rk3308 = devm_kzalloc(&pdev->dev, sizeof(*rk3308), GFP_KERNEL); - if (!rk3308) - return -ENOMEM; - -+ rk3308->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); -+ if (IS_ERR(rk3308->grf)) { -+ dev_err(&pdev->dev, -+ "Missing 'rockchip,grf' property\n"); -+ return PTR_ERR(rk3308->grf); -+ } -+ - ret = rk3308_codec_sysfs_init(pdev, rk3308); - if (ret < 0) { - dev_err(&pdev->dev, "Sysfs init failed\n"); - return ret; - } - -+#if defined(CONFIG_DEBUG_FS) -+ rk3308->dbg_codec = debugfs_create_dir(CODEC_DRV_NAME, NULL); -+ if (IS_ERR(rk3308->dbg_codec)) -+ dev_err(&pdev->dev, -+ "Failed to create debugfs dir for rk3308!\n"); -+ else -+ debugfs_create_file("reg", 0644, rk3308->dbg_codec, -+ rk3308, &rk3308_codec_reg_debugfs_fops); -+#endif - rk3308->plat_dev = &pdev->dev; - - rk3308->reset = devm_reset_control_get(&pdev->dev, "acodec-reset"); -@@ -1518,27 +4901,146 @@ static int rk3308_platform_probe(struct platform_device *pdev) - rk3308->reset = NULL; - } - -- /* GPIO0_A5 control speaker on RK3308 EVB */ -- rk3308->spk_ctl_gpio = devm_gpiod_get_optional(&pdev->dev, "spk_ctl", -- GPIOD_OUT_HIGH); -- if (IS_ERR(rk3308->spk_ctl_gpio)) { -+ rk3308->hp_ctl_gpio = devm_gpiod_get_optional(&pdev->dev, "hp-ctl", -+ GPIOD_OUT_LOW); -+ if (!rk3308->hp_ctl_gpio) { -+ dev_info(&pdev->dev, "Don't need hp-ctl gpio\n"); -+ } else if (IS_ERR(rk3308->hp_ctl_gpio)) { -+ ret = PTR_ERR(rk3308->hp_ctl_gpio); -+ dev_err(&pdev->dev, "Unable to claim gpio hp-ctl\n"); -+ return ret; -+ } -+ -+ rk3308->spk_ctl_gpio = devm_gpiod_get_optional(&pdev->dev, "spk-ctl", -+ GPIOD_OUT_LOW); -+ -+ if (!rk3308->spk_ctl_gpio) { -+ dev_info(&pdev->dev, "Don't need spk-ctl gpio\n"); -+ } else if (IS_ERR(rk3308->spk_ctl_gpio)) { - ret = PTR_ERR(rk3308->spk_ctl_gpio); -- dev_err(&pdev->dev, "Unable to claim gpio spk_ctl\n"); -+ dev_err(&pdev->dev, "Unable to claim gpio spk-ctl\n"); -+ return ret; -+ } -+ -+ rk3308->pa_drv_gpio = devm_gpiod_get_optional(&pdev->dev, "pa-drv", -+ GPIOD_OUT_LOW); -+ -+ if (!rk3308->pa_drv_gpio) { -+ dev_info(&pdev->dev, "Don't need pa-drv gpio\n"); -+ } else if (IS_ERR(rk3308->pa_drv_gpio)) { -+ ret = PTR_ERR(rk3308->pa_drv_gpio); -+ dev_err(&pdev->dev, "Unable to claim gpio pa-drv\n"); - return ret; - } - -+ if (rk3308->pa_drv_gpio) { -+ rk3308->delay_pa_drv_ms = PA_DRV_MS; -+ ret = of_property_read_u32(np, "rockchip,delay-pa-drv-ms", -+ &rk3308->delay_pa_drv_ms); -+ } -+ -+#if DEBUG_POP_ALWAYS -+ dev_info(&pdev->dev, "Enable all ctl gpios always for debugging pop\n"); -+ rk3308_headphone_ctl(rk3308, 1); -+ rk3308_speaker_ctl(rk3308, 1); -+#else -+ dev_info(&pdev->dev, "De-pop as much as possible\n"); -+ rk3308_headphone_ctl(rk3308, 0); -+ rk3308_speaker_ctl(rk3308, 0); -+#endif -+ - rk3308->pclk = devm_clk_get(&pdev->dev, "acodec"); - if (IS_ERR(rk3308->pclk)) { - dev_err(&pdev->dev, "Can't get acodec pclk\n"); - return PTR_ERR(rk3308->pclk); - } - -+ rk3308->mclk_rx = devm_clk_get(&pdev->dev, "mclk_rx"); -+ if (IS_ERR(rk3308->mclk_rx)) { -+ dev_err(&pdev->dev, "Can't get acodec mclk_rx\n"); -+ return PTR_ERR(rk3308->mclk_rx); -+ } -+ -+ rk3308->mclk_tx = devm_clk_get(&pdev->dev, "mclk_tx"); -+ if (IS_ERR(rk3308->mclk_tx)) { -+ dev_err(&pdev->dev, "Can't get acodec mclk_tx\n"); -+ return PTR_ERR(rk3308->mclk_tx); -+ } -+ - ret = clk_prepare_enable(rk3308->pclk); - if (ret < 0) { - dev_err(&pdev->dev, "Failed to enable acodec pclk: %d\n", ret); - return ret; - } - -+ ret = clk_prepare_enable(rk3308->mclk_rx); -+ if (ret < 0) { -+ dev_err(&pdev->dev, "Failed to enable i2s mclk_rx: %d\n", ret); -+ return ret; -+ } -+ -+ ret = clk_prepare_enable(rk3308->mclk_tx); -+ if (ret < 0) { -+ dev_err(&pdev->dev, "Failed to enable i2s mclk_tx: %d\n", ret); -+ return ret; -+ } -+ -+ rk3308_codec_check_micbias(rk3308, np); -+ -+ rk3308->enable_all_adcs = -+ of_property_read_bool(np, "rockchip,enable-all-adcs"); -+ -+ rk3308->hp_jack_reversed = -+ of_property_read_bool(np, "rockchip,hp-jack-reversed"); -+ -+ rk3308->no_deep_low_power = -+ of_property_read_bool(np, "rockchip,no-deep-low-power"); -+ -+ rk3308->no_hp_det = -+ of_property_read_bool(np, "rockchip,no-hp-det"); -+ -+ rk3308->delay_loopback_handle_ms = LOOPBACK_HANDLE_MS; -+ ret = of_property_read_u32(np, "rockchip,delay-loopback-handle-ms", -+ &rk3308->delay_loopback_handle_ms); -+ -+ rk3308->delay_start_play_ms = 0; -+ ret = of_property_read_u32(np, "rockchip,delay-start-play-ms", -+ &rk3308->delay_start_play_ms); -+ -+ rk3308->loopback_grp = NOT_USED; -+ ret = of_property_read_u32(np, "rockchip,loopback-grp", -+ &rk3308->loopback_grp); -+ /* -+ * If there is no loopback on some board, the -EINVAL indicates that -+ * we don't need add the node, and it is not an error. -+ */ -+ if (ret < 0 && ret != -EINVAL) { -+ dev_err(&pdev->dev, "Failed to read loopback property: %d\n", -+ ret); -+ return ret; -+ } -+ -+ ret = rk3308_codec_adc_grps_route(rk3308, np); -+ if (ret < 0) { -+ dev_err(&pdev->dev, "Failed to route ADC groups: %d\n", -+ ret); -+ return ret; -+ } -+ -+ ret = rk3308_codec_setup_en_always_adcs(rk3308, np); -+ if (ret < 0) { -+ dev_err(&pdev->dev, "Failed to setup enabled always ADCs: %d\n", -+ ret); -+ return ret; -+ } -+ -+ ret = rk3308_codec_get_version(rk3308); -+ if (ret < 0) { -+ dev_err(&pdev->dev, "Failed to get acodec version: %d\n", -+ ret); -+ return ret; -+ } -+ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(base)) { -@@ -1555,10 +5057,65 @@ static int rk3308_platform_probe(struct platform_device *pdev) - goto failed; - } - -+ if (!rk3308->no_hp_det) { -+ int index = 0; -+ -+ if (rk3308->codec_ver == ACODEC_VERSION_B) -+ index = 1; -+ -+ rk3308->irq = platform_get_irq(pdev, index); -+ if (rk3308->irq < 0) { -+ dev_err(&pdev->dev, "Can not get codec irq\n"); -+ goto failed; -+ } -+ -+ INIT_DELAYED_WORK(&rk3308->hpdet_work, rk3308_codec_hpdetect_work); -+ -+ ret = devm_request_irq(&pdev->dev, rk3308->irq, -+ rk3308_codec_hpdet_isr, -+ 0, -+ "acodec-hpdet", -+ rk3308); -+ if (ret < 0) { -+ dev_err(&pdev->dev, "Failed to request IRQ: %d\n", ret); -+ goto failed; -+ } -+ -+ if (rk3308->codec_ver == ACODEC_VERSION_B) { -+ rk3308->detect_grf = -+ syscon_regmap_lookup_by_phandle(np, "rockchip,detect-grf"); -+ if (IS_ERR(rk3308->detect_grf)) { -+ dev_err(&pdev->dev, -+ "Missing 'rockchip,detect-grf' property\n"); -+ return PTR_ERR(rk3308->detect_grf); -+ } -+ -+ /* Configure filter count and enable hpdet irq. */ -+ regmap_write(rk3308->detect_grf, -+ DETECT_GRF_ACODEC_HPDET_COUNTER, -+ DEFAULT_HPDET_COUNT); -+ regmap_write(rk3308->detect_grf, -+ DETECT_GRF_ACODEC_HPDET_CON, -+ (HPDET_BOTH_NEG_POS << 16) | -+ HPDET_BOTH_NEG_POS); -+ } -+ -+ rk3308_codec_set_jack_detect_cb = rk3308_codec_set_jack_detect; -+ } -+ -+ if (rk3308->codec_ver == ACODEC_VERSION_A) -+ INIT_DELAYED_WORK(&rk3308->loopback_work, -+ rk3308_codec_loopback_work); -+ -+ rk3308->adc_grp0_using_linein = ADC_GRP0_MICIN; -+ rk3308->dac_output = DAC_LINEOUT; -+ rk3308->adc_zerocross = 1; -+ rk3308->pm_state = PM_NORMAL; -+ - platform_set_drvdata(pdev, rk3308); - - ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_rk3308, -- rk3308_dai, ARRAY_SIZE(rk3308_dai)); -+ rk3308_dai, ARRAY_SIZE(rk3308_dai)); - if (ret < 0) { - dev_err(&pdev->dev, "Failed to register codec: %d\n", ret); - goto failed; -@@ -1567,7 +5124,10 @@ static int rk3308_platform_probe(struct platform_device *pdev) - return ret; - - failed: -+ clk_disable_unprepare(rk3308->mclk_rx); -+ clk_disable_unprepare(rk3308->mclk_tx); - clk_disable_unprepare(rk3308->pclk); -+ device_unregister(&rk3308->dev); - - return ret; - } -@@ -1577,8 +5137,11 @@ static int rk3308_platform_remove(struct platform_device *pdev) - struct rk3308_codec_priv *rk3308 = - (struct rk3308_codec_priv *)platform_get_drvdata(pdev); - -+ clk_disable_unprepare(rk3308->mclk_rx); -+ clk_disable_unprepare(rk3308->mclk_tx); - clk_disable_unprepare(rk3308->pclk); - snd_soc_unregister_codec(&pdev->dev); -+ device_unregister(&rk3308->dev); - - return 0; - } -@@ -1591,7 +5154,7 @@ MODULE_DEVICE_TABLE(of, rk3308codec_of_match); - - static struct platform_driver rk3308_codec_driver = { - .driver = { -- .name = "rk3308-acodec", -+ .name = CODEC_DRV_NAME, - .of_match_table = of_match_ptr(rk3308codec_of_match), - }, - .probe = rk3308_platform_probe, -diff --git a/sound/soc/codecs/rk3308_codec.h b/sound/soc/codecs/rk3308_codec.h -index 6cfa69157785..93e089dae081 100644 ---- a/sound/soc/codecs/rk3308_codec.h -+++ b/sound/soc/codecs/rk3308_codec.h -@@ -26,7 +26,8 @@ - #define ACODEC_ADC_I2S_CTL0 0x04 /* REG 0x01 */ - #define ACODEC_ADC_I2S_CTL1 0x08 /* REG 0x02 */ - #define ACODEC_ADC_BIST_MODE_SEL 0x0c /* REG 0x03 */ --/* Resevred REG 0x04 ~ 0x06 */ -+#define ACODEC_ADC_HPF_PATH 0x10 /* REG 0x04 */ -+/* Resevred REG 0x05 ~ 0x06 */ - #define ACODEC_ADC_DATA_PATH 0x1c /* REG 0x07 */ - /* Resevred REG 0x08 ~ 0x0f */ - -@@ -62,12 +63,15 @@ - #define ACODEC_DAC_I2S_CTL0 0x04 /* REG 0x01 */ - #define ACODEC_DAC_I2S_CTL1 0x08 /* REG 0x02 */ - #define ACODEC_DAC_BIST_MODE_SEL 0x0c /* REG 0x03 */ --/* Resevred REG 0x04 */ -+#define ACODEC_DAC_DIGITAL_GAIN 0x10 /* REG 0x04 */ - #define ACODEC_DAC_DATA_SEL 0x14 /* REG 0x05 */ - /* Resevred REG 0x06 ~ 0x09 */ - #define ACODEC_DAC_DATA_HI 0x28 /* REG 0x0a */ - #define ACODEC_DAC_DATA_LO 0x2c /* REG 0x0b */ --/* Resevred REG 0x0c ~ 0x0f */ -+/* Resevred REG 0x0c */ -+#define ACODEC_DAC_HPDET_DELAYTIME 0x34 /* REG 0x0d */ -+#define ACODEC_DAC_HPDET_STATUS 0x38 /* REG 0x0e, Read-only */ -+/* Resevred REG 0x0f */ - - /* ADC ANALOG REGISTERS */ - #define ACODEC_ADC_ANA_MIC_CTL 0x00 /* REG 0x00 */ -@@ -92,10 +96,13 @@ - #define ACODEC_DAC_ANA_LINEOUT 0x10 /* REG 0x04 */ - #define ACODEC_DAC_ANA_L_HPOUT_GAIN 0x14 /* REG 0x05 */ - #define ACODEC_DAC_ANA_R_HPOUT_GAIN 0x18 /* REG 0x06 */ -+#define ACODEC_DAC_ANA_DRV_HPOUT 0x1c /* REG 0x07 */ -+#define ACODEC_DAC_ANA_DRV_LINEOUT 0x20 /* REG 0x08 */ - /* Resevred REG 0x07 ~ 0x0b */ - #define ACODEC_DAC_ANA_HPMIX_CTL0 0x30 /* REG 0x0c */ - #define ACODEC_DAC_ANA_HPMIX_CTL1 0x34 /* REG 0x0d */ --/* Resevred REG 0x0e ~ 0x0f */ -+#define ACODEC_DAC_ANA_LINEOUT_CTL0 0x38 /* REG 0x0e */ -+#define ACODEC_DAC_ANA_LINEOUT_CTL1 0x3c /* REG 0x0f */ - - /* - * These registers are referenced by codec driver -@@ -106,7 +113,7 @@ - /* ADC DIGITAL REGISTERS */ - - /* -- * The ADC chanel are 0 ~ 3, that control: -+ * The ADC group are 0 ~ 3, that control: - * - * CH0: left_0(ADC1) and right_0(ADC2) - * CH1: left_1(ADC3) and right_1(ADC4) -@@ -118,6 +125,7 @@ - #define RK3308_ADC_DIG_CON01(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_I2S_CTL0) - #define RK3308_ADC_DIG_CON02(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_I2S_CTL1) - #define RK3308_ADC_DIG_CON03(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_BIST_MODE_SEL) -+#define RK3308_ADC_DIG_CON04(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_HPF_PATH) - #define RK3308_ADC_DIG_CON07(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_DATA_PATH) - - #define RK3308_ALC_L_DIG_CON00(ch) (RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_L_CTL0) -@@ -150,13 +158,16 @@ - #define RK3308_DAC_DIG_CON01 (RK3308_DAC_DIG_OFFSET + ACODEC_DAC_I2S_CTL0) - #define RK3308_DAC_DIG_CON02 (RK3308_DAC_DIG_OFFSET + ACODEC_DAC_I2S_CTL1) - #define RK3308_DAC_DIG_CON03 (RK3308_DAC_DIG_OFFSET + ACODEC_DAC_BIST_MODE_SEL) -+#define RK3308_DAC_DIG_CON04 (RK3308_DAC_DIG_OFFSET + ACODEC_DAC_DIGITAL_GAIN) - #define RK3308_DAC_DIG_CON05 (RK3308_DAC_DIG_OFFSET + ACODEC_DAC_DATA_SEL) - #define RK3308_DAC_DIG_CON10 (RK3308_DAC_DIG_OFFSET + ACODEC_DAC_DATA_HI) - #define RK3308_DAC_DIG_CON11 (RK3308_DAC_DIG_OFFSET + ACODEC_DAC_DATA_LO) -+#define RK3308_DAC_DIG_CON13 (RK3308_DAC_DIG_OFFSET + ACODEC_DAC_HPDET_DELAYTIME) -+#define RK3308_DAC_DIG_CON14 (RK3308_DAC_DIG_OFFSET + ACODEC_DAC_HPDET_STATUS) - - /* ADC ANALOG REGISTERS */ - /* -- * The ADC chanel are 0 ~ 3, that control: -+ * The ADC group are 0 ~ 3, that control: - * - * CH0: left_0(ADC1) and right_0(ADC2) - * CH1: left_1(ADC3) and right_1(ADC4) -@@ -179,7 +190,6 @@ - - /* DAC ANALOG REGISTERS */ - #define RK3308_DAC_ANA_OFFSET 0x440 -- - #define RK3308_DAC_ANA_CON00 (RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_CTL0) - #define RK3308_DAC_ANA_CON01 (RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_POP_VOLT) - #define RK3308_DAC_ANA_CON02 (RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_CTL1) -@@ -187,8 +197,12 @@ - #define RK3308_DAC_ANA_CON04 (RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_LINEOUT) - #define RK3308_DAC_ANA_CON05 (RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_L_HPOUT_GAIN) - #define RK3308_DAC_ANA_CON06 (RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_R_HPOUT_GAIN) -+#define RK3308_DAC_ANA_CON07 (RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_DRV_HPOUT) -+#define RK3308_DAC_ANA_CON08 (RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_DRV_LINEOUT) - #define RK3308_DAC_ANA_CON12 (RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_HPMIX_CTL0) - #define RK3308_DAC_ANA_CON13 (RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_HPMIX_CTL1) -+#define RK3308_DAC_ANA_CON14 (RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_LINEOUT_CTL0) -+#define RK3308_DAC_ANA_CON15 (RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_LINEOUT_CTL1) - - /* - * These are the bits for registers -@@ -199,6 +213,12 @@ - #define RK3308_ADC_BIST_RESET (0 << 7) - #define RK3308_DAC_BIST_WORK (1 << 6) - #define RK3308_DAC_BIST_RESET (0 << 6) -+#define RK3308_ADC_MCLK_MSK (1 << 5) -+#define RK3308_ADC_MCLK_DIS (1 << 5) -+#define RK3308_ADC_MCLK_EN (0 << 5) -+#define RK3308_DAC_MCLK_MSK (1 << 4) -+#define RK3308_DAC_MCLK_DIS (1 << 4) -+#define RK3308_DAC_MCLK_EN (0 << 4) - #define RK3308_CODEC_RST_MSK (0x7 << 0) - #define RK3308_ADC_DIG_WORK (1 << 2) - #define RK3308_ADC_DIG_RESET (0 << 2) -@@ -253,16 +273,27 @@ - /* RK3308_ADC_DIG_CON03 - REG: 0x000c */ - #define RK3308_ADC_L_CH_BIST_SFT 2 - #define RK3308_ADC_L_CH_BIST_MSK (0x3 << RK3308_ADC_L_CH_BIST_SFT) --#define RK3308_ADC_L_CH_BIST_LEFT (0x3 << RK3308_ADC_L_CH_BIST_SFT) /* normal mode */ --#define RK3308_ADC_L_CH_BIST_SINE (0x2 << RK3308_ADC_L_CH_BIST_SFT) --#define RK3308_ADC_L_CH_BIST_CUBE (0x1 << RK3308_ADC_L_CH_BIST_SFT) --#define RK3308_ADC_L_CH_BIST_RIGHT (0x0 << RK3308_ADC_L_CH_BIST_SFT) /* normal mode */ -+#define RK3308_ADC_L_CH_NORMAL_RIGHT (0x3 << RK3308_ADC_L_CH_BIST_SFT) /* normal mode */ -+#define RK3308_ADC_L_CH_BIST_CUBE (0x2 << RK3308_ADC_L_CH_BIST_SFT) -+#define RK3308_ADC_L_CH_BIST_SINE (0x1 << RK3308_ADC_L_CH_BIST_SFT) -+#define RK3308_ADC_L_CH_NORMAL_LEFT (0x0 << RK3308_ADC_L_CH_BIST_SFT) /* normal mode */ - #define RK3308_ADC_R_CH_BIST_SFT 0 - #define RK3308_ADC_R_CH_BIST_MSK (0x3 << RK3308_ADC_R_CH_BIST_SFT) --#define RK3308_ADC_R_CH_BIST_LEFT (0x3 << RK3308_ADC_R_CH_BIST_SFT) /* normal mode */ --#define RK3308_ADC_R_CH_BIST_SINE (0x2 << RK3308_ADC_R_CH_BIST_SFT) --#define RK3308_ADC_R_CH_BIST_CUBE (0x1 << RK3308_ADC_R_CH_BIST_SFT) --#define RK3308_ADC_R_CH_BIST_RIGHT (0x0 << RK3308_ADC_R_CH_BIST_SFT) /* normal mode */ -+#define RK3308_ADC_R_CH_NORMAL_LEFT (0x3 << RK3308_ADC_R_CH_BIST_SFT) /* normal mode */ -+#define RK3308_ADC_R_CH_BIST_CUBE (0x2 << RK3308_ADC_R_CH_BIST_SFT) -+#define RK3308_ADC_R_CH_BIST_SINE (0x1 << RK3308_ADC_R_CH_BIST_SFT) -+#define RK3308_ADC_R_CH_NORMAL_RIGHT (0x0 << RK3308_ADC_R_CH_BIST_SFT) /* normal mode */ -+ -+/* RK3308_ADC_DIG_CON04 - REG: 0x0010 */ -+#define RK3308_ADC_HPF_PATH_SFT 2 -+#define RK3308_ADC_HPF_PATH_MSK (1 << RK3308_ADC_HPF_PATH_SFT) -+#define RK3308_ADC_HPF_PATH_DIS (1 << RK3308_ADC_HPF_PATH_SFT) -+#define RK3308_ADC_HPF_PATH_EN (0 << RK3308_ADC_HPF_PATH_SFT) -+#define RK3308_ADC_HPF_CUTOFF_SFT 0 -+#define RK3308_ADC_HPF_CUTOFF_MSK (0x3 << RK3308_ADC_HPF_CUTOFF_SFT) -+#define RK3308_ADC_HPF_CUTOFF_612HZ (0x2 << RK3308_ADC_HPF_CUTOFF_SFT) -+#define RK3308_ADC_HPF_CUTOFF_245HZ (0x1 << RK3308_ADC_HPF_CUTOFF_SFT) -+#define RK3308_ADC_HPF_CUTOFF_20HZ (0x0 << RK3308_ADC_HPF_CUTOFF_SFT) - - /* RK3308_ADC_DIG_CON07 - REG: 0x001c */ - #define RK3308_ADCL_DATA_SFT 4 -@@ -391,6 +422,8 @@ - */ - #define RK3308_AGC_PGA_ZERO_CRO_EN (0x1 << 5) - #define RK3308_AGC_PGA_ZERO_CRO_DIS (0x0 << 5) -+#define RK3308_AGC_PGA_GAIN_MAX 0x1f -+#define RK3308_AGC_PGA_GAIN_MIN 0 - #define RK3308_AGC_PGA_GAIN_SFT 0 - #define RK3308_AGC_PGA_GAIN_MSK (0x1f << RK3308_AGC_PGA_GAIN_SFT) - #define RK3308_AGC_PGA_GAIN_PDB_28_5 (0x1f << RK3308_AGC_PGA_GAIN_SFT) -@@ -474,6 +507,8 @@ - #define RK3308_AGC_FUNC_SEL_MSK (0x1 << 6) - #define RK3308_AGC_FUNC_SEL_EN (0x1 << 6) - #define RK3308_AGC_FUNC_SEL_DIS (0x0 << 6) -+#define RK3308_AGC_MAX_GAIN_PGA_MAX 0x7 -+#define RK3308_AGC_MAX_GAIN_PGA_MIN 0 - #define RK3308_AGC_MAX_GAIN_PGA_SFT 3 - #define RK3308_AGC_MAX_GAIN_PGA_MSK (0x7 << RK3308_AGC_MAX_GAIN_PGA_SFT) - #define RK3308_AGC_MAX_GAIN_PGA_PDB_28_5 (0x7 << RK3308_AGC_MAX_GAIN_PGA_SFT) -@@ -484,6 +519,8 @@ - #define RK3308_AGC_MAX_GAIN_PGA_NDB_1_5 (0x2 << RK3308_AGC_MAX_GAIN_PGA_SFT) - #define RK3308_AGC_MAX_GAIN_PGA_NDB_7_5 (0x1 << RK3308_AGC_MAX_GAIN_PGA_SFT) - #define RK3308_AGC_MAX_GAIN_PGA_NDB_13_5 (0x0 << RK3308_AGC_MAX_GAIN_PGA_SFT) -+#define RK3308_AGC_MIN_GAIN_PGA_MAX 0x7 -+#define RK3308_AGC_MIN_GAIN_PGA_MIN 0 - #define RK3308_AGC_MIN_GAIN_PGA_SFT 0 - #define RK3308_AGC_MIN_GAIN_PGA_MSK (0x7 << RK3308_AGC_MIN_GAIN_PGA_SFT) - #define RK3308_AGC_MIN_GAIN_PGA_PDB_24 (0x7 << RK3308_AGC_MIN_GAIN_PGA_SFT) -@@ -555,6 +592,18 @@ - #define RK3308_DAC_R_CH_BIST_SINE (0x1 << RK3308_DAC_R_CH_BIST_SFT) - #define RK3308_DAC_R_CH_BIST_RIGHT (0x0 << RK3308_DAC_R_CH_BIST_SFT) /* normal mode */ - -+/* RK3308_DAC_DIG_CON04 - REG: 0x0310 */ -+#define RK3308_DAC_MODULATOR_GAIN_SFT 4 -+#define RK3308_DAC_MODULATOR_GAIN_MSK (0x7 << RK3308_DAC_MODULATOR_GAIN_SFT) -+#define RK3308_DAC_MODULATOR_GAIN_4_8DB (0x5 << RK3308_DAC_MODULATOR_GAIN_SFT) -+#define RK3308_DAC_MODULATOR_GAIN_4_2DB (0x4 << RK3308_DAC_MODULATOR_GAIN_SFT) -+#define RK3308_DAC_MODULATOR_GAIN_3_5DB (0x3 << RK3308_DAC_MODULATOR_GAIN_SFT) -+#define RK3308_DAC_MODULATOR_GAIN_2_8DB (0x2 << RK3308_DAC_MODULATOR_GAIN_SFT) -+#define RK3308_DAC_MODULATOR_GAIN_2DB (0x1 << RK3308_DAC_MODULATOR_GAIN_SFT) -+#define RK3308_DAC_MODULATOR_GAIN_0DB (0x0 << RK3308_DAC_MODULATOR_GAIN_SFT) -+#define RK3308_DAC_CIC_IF_GAIN_SFT 0 -+#define RK3308_DAC_CIC_IF_GAIN_MSK (0x7 << RK3308_DAC_CIC_IF_GAIN_SFT) -+ - /* RK3308_DAC_DIG_CON05 - REG: 0x0314 */ - #define RK3308_DAC_L_REG_CTL_INDATA (0x1 << 2) - #define RK3308_DAC_L_NORMAL_DATA (0x0 << 2) -@@ -587,18 +636,30 @@ - #define RK3308_ADC_CH1_BUF_REF_EN (0x1 << 0) - #define RK3308_ADC_CH1_BUF_REF_DIS (0x0 << 0) - --/* RK3308_ADC_ANA_CON01 - REG: 0x0344 */ -+/* RK3308_ADC_ANA_CON01 - REG: 0x0344 -+ * -+ * The PGA of MIC-INs: -+ * 0x0 - MIC1~MIC8 0dB -+ * 0x1 - MIC1~MIC8 6.6dB -+ * 0x2 - MIC1~MIC8 13dB -+ * 0x3 - MIC1~MIC8 20dB -+ */ -+#define RK3308_ADC_CH2_MIC_GAIN_MAX 0x3 -+#define RK3308_ADC_CH2_MIC_GAIN_MIN 0 - #define RK3308_ADC_CH2_MIC_GAIN_SFT 4 - #define RK3308_ADC_CH2_MIC_GAIN_MSK (0x3 << RK3308_ADC_CH2_MIC_GAIN_SFT) --#define RK3308_ADC_CH2_MIC_GAIN_30DB (0x3 << RK3308_ADC_CH2_MIC_GAIN_SFT) --#define RK3308_ADC_CH2_MIC_GAIN_20DB (0x2 << RK3308_ADC_CH2_MIC_GAIN_SFT) --#define RK3308_ADC_CH2_MIC_GAIN_6DB (0x1 << RK3308_ADC_CH2_MIC_GAIN_SFT) -+#define RK3308_ADC_CH2_MIC_GAIN_20DB (0x3 << RK3308_ADC_CH2_MIC_GAIN_SFT) -+#define RK3308_ADC_CH2_MIC_GAIN_13DB (0x2 << RK3308_ADC_CH2_MIC_GAIN_SFT) /* TRM: only used for version B */ -+#define RK3308_ADC_CH2_MIC_GAIN_6_6DB (0x1 << RK3308_ADC_CH2_MIC_GAIN_SFT) /* TRM: only used for version B */ - #define RK3308_ADC_CH2_MIC_GAIN_0DB (0x0 << RK3308_ADC_CH2_MIC_GAIN_SFT) -+ -+#define RK3308_ADC_CH1_MIC_GAIN_MAX 0x3 -+#define RK3308_ADC_CH1_MIC_GAIN_MIN 0 - #define RK3308_ADC_CH1_MIC_GAIN_SFT 0 - #define RK3308_ADC_CH1_MIC_GAIN_MSK (0x3 << RK3308_ADC_CH1_MIC_GAIN_SFT) --#define RK3308_ADC_CH1_MIC_GAIN_30DB (0x3 << RK3308_ADC_CH1_MIC_GAIN_SFT) --#define RK3308_ADC_CH1_MIC_GAIN_20DB (0x2 << RK3308_ADC_CH1_MIC_GAIN_SFT) --#define RK3308_ADC_CH1_MIC_GAIN_6DB (0x1 << RK3308_ADC_CH1_MIC_GAIN_SFT) -+#define RK3308_ADC_CH1_MIC_GAIN_20DB (0x3 << RK3308_ADC_CH1_MIC_GAIN_SFT) -+#define RK3308_ADC_CH1_MIC_GAIN_13DB (0x2 << RK3308_ADC_CH1_MIC_GAIN_SFT) /* TRM: only used for version B */ -+#define RK3308_ADC_CH1_MIC_GAIN_6_6DB (0x1 << RK3308_ADC_CH1_MIC_GAIN_SFT) /* TRM: only used for version B */ - #define RK3308_ADC_CH1_MIC_GAIN_0DB (0x0 << RK3308_ADC_CH1_MIC_GAIN_SFT) - - /* RK3308_ADC_ANA_CON02 - REG: 0x0348 */ -@@ -619,6 +680,8 @@ - #define RK3308_ADC_CH1_ALC_DIS (0x0 << 0) - - /* RK3308_ADC_ANA_CON03 - REG: 0x034c */ -+#define RK3308_ADC_CH1_ALC_GAIN_MAX 0x1f -+#define RK3308_ADC_CH1_ALC_GAIN_MIN 0 - #define RK3308_ADC_CH1_ALC_GAIN_SFT 0 - #define RK3308_ADC_CH1_ALC_GAIN_MSK (0x1f << RK3308_ADC_CH1_ALC_GAIN_SFT) - #define RK3308_ADC_CH1_ALC_GAIN_PDB_28_5 (0x1f << RK3308_ADC_CH1_ALC_GAIN_SFT) -@@ -655,6 +718,8 @@ - #define RK3308_ADC_CH1_ALC_GAIN_NDB_18 (0x00 << RK3308_ADC_CH1_ALC_GAIN_SFT) - - /* RK3308_ADC_ANA_CON04 - REG: 0x0350 */ -+#define RK3308_ADC_CH2_ALC_GAIN_MAX 0x1f -+#define RK3308_ADC_CH2_ALC_GAIN_MIN 0 - #define RK3308_ADC_CH2_ALC_GAIN_SFT 0 - #define RK3308_ADC_CH2_ALC_GAIN_MSK (0x1f << RK3308_ADC_CH2_ALC_GAIN_SFT) - #define RK3308_ADC_CH2_ALC_GAIN_PDB_28_5 (0x1f << RK3308_ADC_CH2_ALC_GAIN_SFT) -@@ -728,10 +793,16 @@ - #define RK3308_ADC_CH1_IN_MIC (0x1 << RK3308_ADC_CH1_IN_SEL_SFT) - #define RK3308_ADC_CH1_IN_NONE (0x0 << RK3308_ADC_CH1_IN_SEL_SFT) - --#define RK3308_ADC_MIC_BIAS_BUF_EN (0x1 << 3) --#define RK3308_ADC_MIC_BIAS_BUF_DIS (0x0 << 3) -+#define RK3308_ADC_MIC_BIAS_BUF_SFT 3 -+#define RK3308_ADC_MIC_BIAS_BUF_EN (0x1 << RK3308_ADC_MIC_BIAS_BUF_SFT) -+#define RK3308_ADC_MIC_BIAS_BUF_DIS (0x0 << RK3308_ADC_MIC_BIAS_BUF_SFT) - #define RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT 0 - #define RK3308_ADC_LEVEL_RANGE_MICBIAS_MSK (0x7 << RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT) -+/* -+ * The follow MICBIAS_VOLTs are based on the external reference voltage(Vref). -+ * For example, the Vref == 3.3V, the MICBIAS_VOLT_0_85 is equal: -+ * 3.3V * 0.85 = 2.805V. -+ */ - #define RK3308_ADC_MICBIAS_VOLT_0_85 (0x7 << RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT) - #define RK3308_ADC_MICBIAS_VOLT_0_8 (0x6 << RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT) - #define RK3308_ADC_MICBIAS_VOLT_0_75 (0x5 << RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT) -@@ -751,18 +822,11 @@ - #define RK3308_ADC_REF_DIS (0x0 << 7) - #define RK3308_ADC_CURRENT_CHARGE_SFT 0 - #define RK3308_ADC_CURRENT_CHARGE_MSK (0x7f << RK3308_ADC_CURRENT_CHARGE_SFT) --#define RK3308_ADC_DONT_SEL_ALL (0x7f << RK3308_ADC_CURRENT_CHARGE_SFT) - /* -- * 0: Choose the current I -- * 1: Don't choose the current I -+ * 1: Choose the current I -+ * 0: Don't choose the current I - */ --#define RK3308_ADC_SEL_I_1(x) ((x & 0x1) << 6) --#define RK3308_ADC_SEL_I_2(x) ((x & 0x1) << 5) --#define RK3308_ADC_SEL_I_4(x) ((x & 0x1) << 4) --#define RK3308_ADC_SEL_I_8(x) ((x & 0x1) << 3) --#define RK3308_ADC_SEL_I_16(x) ((x & 0x1) << 2) --#define RK3308_ADC_SEL_I_32(x) ((x & 0x1) << 1) --#define RK3308_ADC_SEL_I_64(x) ((x & 0x1) << 0) -+#define RK3308_ADC_SEL_I(x) (x & 0x7f) - - /* RK3308_ADC_ANA_CON11 - REG: 0x036c */ - #define RK3308_ADC_ALCR_CON_GAIN_PGAR_MSK (0x1 << 1) -@@ -773,6 +837,7 @@ - #define RK3308_ADC_ALCL_CON_GAIN_PGAL_DIS (0x0 << 0) - - /* RK3308_DAC_ANA_CON00 - REG: 0x0440 */ -+#define RK3308_DAC_HEADPHONE_DET_MSK (0x1 << 1) - #define RK3308_DAC_HEADPHONE_DET_EN (0x1 << 1) - #define RK3308_DAC_HEADPHONE_DET_DIS (0x0 << 1) - #define RK3308_DAC_CURRENT_MSK (0x1 << 0) -@@ -783,17 +848,17 @@ - #define RK3308_DAC_BUF_REF_R_MSK (0x1 << 6) - #define RK3308_DAC_BUF_REF_R_EN (0x1 << 6) - #define RK3308_DAC_BUF_REF_R_DIS (0x0 << 6) --#define RK3308_DAC_POP_SOUND_R_SFT 4 --#define RK3308_DAC_POP_SOUND_R_MSK (0x3 << RK3308_DAC_POP_SOUND_R_SFT) --#define RK3308_DAC_POP_SOUND_R_WORK (0x2 << RK3308_DAC_POP_SOUND_R_SFT) --#define RK3308_DAC_POP_SOUND_R_INIT (0x1 << RK3308_DAC_POP_SOUND_R_SFT) -+#define RK3308_DAC_HPOUT_POP_SOUND_R_SFT 4 -+#define RK3308_DAC_HPOUT_POP_SOUND_R_MSK (0x3 << RK3308_DAC_HPOUT_POP_SOUND_R_SFT) -+#define RK3308_DAC_HPOUT_POP_SOUND_R_WORK (0x2 << RK3308_DAC_HPOUT_POP_SOUND_R_SFT) -+#define RK3308_DAC_HPOUT_POP_SOUND_R_INIT (0x1 << RK3308_DAC_HPOUT_POP_SOUND_R_SFT) - #define RK3308_DAC_BUF_REF_L_MSK (0x1 << 2) - #define RK3308_DAC_BUF_REF_L_EN (0x1 << 2) - #define RK3308_DAC_BUF_REF_L_DIS (0x0 << 2) --#define RK3308_DAC_POP_SOUND_L_SFT 0 --#define RK3308_DAC_POP_SOUND_L_MSK (0x3 << RK3308_DAC_POP_SOUND_L_SFT) --#define RK3308_DAC_POP_SOUND_L_WORK (0x2 << RK3308_DAC_POP_SOUND_L_SFT) --#define RK3308_DAC_POP_SOUND_L_INIT (0x1 << RK3308_DAC_POP_SOUND_L_SFT) -+#define RK3308_DAC_HPOUT_POP_SOUND_L_SFT 0 -+#define RK3308_DAC_HPOUT_POP_SOUND_L_MSK (0x3 << RK3308_DAC_HPOUT_POP_SOUND_L_SFT) -+#define RK3308_DAC_HPOUT_POP_SOUND_L_WORK (0x2 << RK3308_DAC_HPOUT_POP_SOUND_L_SFT) -+#define RK3308_DAC_HPOUT_POP_SOUND_L_INIT (0x1 << RK3308_DAC_HPOUT_POP_SOUND_L_SFT) - - /* RK3308_DAC_ANA_CON02 - REG: 0x0448 */ - #define RK3308_DAC_R_DAC_WORK (0x1 << 7) -@@ -828,28 +893,31 @@ - #define RK3308_DAC_L_HPOUT_MUTE (0x0 << 0) - - /* RK3308_DAC_ANA_CON04 - REG: 0x0450 */ --#define RK3308_DAC_R_GAIN_SFT 6 --#define RK3308_DAC_R_GAIN_MSK (0x3 << RK3308_DAC_R_GAIN_SFT) --#define RK3308_DAC_R_GAIN_0DB (0x3 << RK3308_DAC_R_GAIN_SFT) --#define RK3308_DAC_R_GAIN_PDB_1_5 (0x2 << RK3308_DAC_R_GAIN_SFT) --#define RK3308_DAC_R_GAIN_PDB_3 (0x1 << RK3308_DAC_R_GAIN_SFT) --#define RK3308_DAC_R_GAIN_PDB_6 (0x0 << RK3308_DAC_R_GAIN_SFT) -+#define RK3308_DAC_R_LINEOUT_GAIN_MAX 0x3 -+#define RK3308_DAC_R_LINEOUT_GAIN_SFT 6 -+#define RK3308_DAC_R_LINEOUT_GAIN_MSK (0x3 << RK3308_DAC_R_LINEOUT_GAIN_SFT) -+#define RK3308_DAC_R_LINEOUT_GAIN_0DB (0x3 << RK3308_DAC_R_LINEOUT_GAIN_SFT) -+#define RK3308_DAC_R_LINEOUT_GAIN_NDB_1_5 (0x2 << RK3308_DAC_R_LINEOUT_GAIN_SFT) -+#define RK3308_DAC_R_LINEOUT_GAIN_NDB_3 (0x1 << RK3308_DAC_R_LINEOUT_GAIN_SFT) -+#define RK3308_DAC_R_LINEOUT_GAIN_NDB_6 (0x0 << RK3308_DAC_R_LINEOUT_GAIN_SFT) - #define RK3308_DAC_R_LINEOUT_UNMUTE (0x1 << 5) - #define RK3308_DAC_R_LINEOUT_MUTE (0x0 << 5) - #define RK3308_DAC_R_LINEOUT_EN (0x1 << 4) - #define RK3308_DAC_R_LINEOUT_DIS (0x0 << 4) --#define RK3308_DAC_L_GAIN_SFT 2 --#define RK3308_DAC_L_GAIN_MSK (0x3 << RK3308_DAC_L_GAIN_SFT) --#define RK3308_DAC_L_GAIN_0DB (0x3 << RK3308_DAC_L_GAIN_SFT) --#define RK3308_DAC_L_GAIN_PDB_1_5 (0x2 << RK3308_DAC_L_GAIN_SFT) --#define RK3308_DAC_L_GAIN_PDB_3 (0x1 << RK3308_DAC_L_GAIN_SFT) --#define RK3308_DAC_L_GAIN_PDB_6 (0x0 << RK3308_DAC_L_GAIN_SFT) -+#define RK3308_DAC_L_LINEOUT_GAIN_MAX 0x3 -+#define RK3308_DAC_L_LINEOUT_GAIN_SFT 2 -+#define RK3308_DAC_L_LINEOUT_GAIN_MSK (0x3 << RK3308_DAC_L_LINEOUT_GAIN_SFT) -+#define RK3308_DAC_L_LINEOUT_GAIN_0DB (0x3 << RK3308_DAC_L_LINEOUT_GAIN_SFT) -+#define RK3308_DAC_L_LINEOUT_GAIN_NDB_1_5 (0x2 << RK3308_DAC_L_LINEOUT_GAIN_SFT) -+#define RK3308_DAC_L_LINEOUT_GAIN_NDB_3 (0x1 << RK3308_DAC_L_LINEOUT_GAIN_SFT) -+#define RK3308_DAC_L_LINEOUT_GAIN_NDB_6 (0x0 << RK3308_DAC_L_LINEOUT_GAIN_SFT) - #define RK3308_DAC_L_LINEOUT_UNMUTE (0x1 << 1) - #define RK3308_DAC_L_LINEOUT_MUTE (0x0 << 1) - #define RK3308_DAC_L_LINEOUT_EN (0x1 << 0) - #define RK3308_DAC_L_LINEOUT_DIS (0x0 << 0) - - /* RK3308_DAC_ANA_CON05 - REG: 0x0454, step is 1.5db */ -+#define RK3308_DAC_L_HPOUT_GAIN_MAX 0x1e - #define RK3308_DAC_L_HPOUT_GAIN_SFT 0 - #define RK3308_DAC_L_HPOUT_GAIN_MSK (0x1f << RK3308_DAC_L_HPOUT_GAIN_SFT) - #define RK3308_DAC_L_HPOUT_GAIN_PDB_6 (0x1e << RK3308_DAC_L_HPOUT_GAIN_SFT) -@@ -885,6 +953,7 @@ - #define RK3308_DAC_L_HPOUT_GAIN_NDB_39 (0x00 << RK3308_DAC_L_HPOUT_GAIN_SFT) - - /* RK3308_DAC_ANA_CON06 - REG: 0x0458, step is 1.5db */ -+#define RK3308_DAC_R_HPOUT_GAIN_MAX 0x1e - #define RK3308_DAC_R_HPOUT_GAIN_SFT 0 - #define RK3308_DAC_R_HPOUT_GAIN_MSK (0x1f << RK3308_DAC_R_HPOUT_GAIN_SFT) - #define RK3308_DAC_R_HPOUT_GAIN_PDB_6 (0x1e << RK3308_DAC_R_HPOUT_GAIN_SFT) -@@ -919,6 +988,18 @@ - #define RK3308_DAC_R_HPOUT_GAIN_NDB_37_5 (0x01 << RK3308_DAC_R_HPOUT_GAIN_SFT) - #define RK3308_DAC_R_HPOUT_GAIN_NDB_39 (0x00 << RK3308_DAC_R_HPOUT_GAIN_SFT) - -+/* RK3308_DAC_ANA_CON07 - REG: 0x045c */ -+#define RK3308_DAC_R_HPOUT_DRV_SFT 4 -+#define RK3308_DAC_R_HPOUT_DRV_MSK (0xf << RK3308_DAC_R_HPOUT_DRV_SFT) -+#define RK3308_DAC_L_HPOUT_DRV_SFT 0 -+#define RK3308_DAC_L_HPOUT_DRV_MSK (0xf << RK3308_DAC_L_HPOUT_DRV_SFT) -+ -+/* RK3308_DAC_ANA_CON08 - REG: 0x0460 */ -+#define RK3308_DAC_R_LINEOUT_DRV_SFT 4 -+#define RK3308_DAC_R_LINEOUT_DRV_MSK (0xf << RK3308_DAC_R_LINEOUT_DRV_SFT) -+#define RK3308_DAC_L_LINEOUT_DRV_SFT 0 -+#define RK3308_DAC_L_LINEOUT_DRV_MSK (0xf << RK3308_DAC_L_LINEOUT_DRV_SFT) -+ - /* RK3308_DAC_ANA_CON12 - REG: 0x0470 */ - #define RK3308_DAC_R_HPMIX_SEL_SFT 6 - #define RK3308_DAC_R_HPMIX_SEL_MSK (0x3 << RK3308_DAC_R_HPMIX_SEL_SFT) -@@ -926,6 +1007,8 @@ - #define RK3308_DAC_R_HPMIX_LINEIN (0x2 << RK3308_DAC_R_HPMIX_SEL_SFT) - #define RK3308_DAC_R_HPMIX_I2S (0x1 << RK3308_DAC_R_HPMIX_SEL_SFT) - #define RK3308_DAC_R_HPMIX_NONE (0x0 << RK3308_DAC_R_HPMIX_SEL_SFT) -+#define RK3308_DAC_R_HPMIX_GAIN_MIN 0x1 -+#define RK3308_DAC_R_HPMIX_GAIN_MAX 0x2 - #define RK3308_DAC_R_HPMIX_GAIN_SFT 4 - #define RK3308_DAC_R_HPMIX_GAIN_MSK (0x3 << RK3308_DAC_R_HPMIX_GAIN_SFT) - #define RK3308_DAC_R_HPMIX_GAIN_0DB (0x2 << RK3308_DAC_R_HPMIX_GAIN_SFT) -@@ -936,6 +1019,8 @@ - #define RK3308_DAC_L_HPMIX_LINEIN (0x2 << RK3308_DAC_L_HPMIX_SEL_SFT) - #define RK3308_DAC_L_HPMIX_I2S (0x1 << RK3308_DAC_L_HPMIX_SEL_SFT) - #define RK3308_DAC_L_HPMIX_NONE (0x0 << RK3308_DAC_L_HPMIX_SEL_SFT) -+#define RK3308_DAC_L_HPMIX_GAIN_MIN 0x1 -+#define RK3308_DAC_L_HPMIX_GAIN_MAX 0x2 - #define RK3308_DAC_L_HPMIX_GAIN_SFT 0 - #define RK3308_DAC_L_HPMIX_GAIN_MSK (0x3 << RK3308_DAC_L_HPMIX_GAIN_SFT) - #define RK3308_DAC_L_HPMIX_GAIN_0DB (0x2 << RK3308_DAC_L_HPMIX_GAIN_SFT) -@@ -955,6 +1040,30 @@ - #define RK3308_DAC_L_HPMIX_EN (0x1 << 0) - #define RK3308_DAC_L_HPMIX_DIS (0x0 << 0) - -+/* RK3308_DAC_ANA_CON14 - REG: 0x0478 */ -+#define RK3308_DAC_VCM_LINEOUT_EN (0x1 << 4) -+#define RK3308_DAC_VCM_LINEOUT_DIS (0x0 << 4) -+#define RK3308_DAC_CURRENT_CHARGE_SFT 0 -+#define RK3308_DAC_CURRENT_CHARGE_MSK (0xf << RK3308_DAC_CURRENT_CHARGE_SFT) -+ -+/* -+ * 1: Choose the current I -+ * 0: Don't choose the current I -+ */ -+#define RK3308_DAC_SEL_I(x) (x & 0xf) -+ -+/* RK3308_DAC_ANA_CON15 - REG: 0x047C */ -+#define RK3308_DAC_LINEOUT_POP_SOUND_R_SFT 4 -+#define RK3308_DAC_LINEOUT_POP_SOUND_R_MSK (0x3 << RK3308_DAC_LINEOUT_POP_SOUND_R_SFT) -+#define RK3308_DAC_R_SEL_DC_FROM_INTERNAL (0x2 << RK3308_DAC_LINEOUT_POP_SOUND_R_SFT) -+#define RK3308_DAC_R_SEL_DC_FROM_VCM (0x1 << RK3308_DAC_LINEOUT_POP_SOUND_R_SFT) -+#define RK3308_DAC_R_SEL_LINEOUT_FROM_INTERNAL (0x0 << RK3308_DAC_LINEOUT_POP_SOUND_R_SFT) -+#define RK3308_DAC_LINEOUT_POP_SOUND_L_SFT 0 -+#define RK3308_DAC_LINEOUT_POP_SOUND_L_MSK (0x3 << RK3308_DAC_LINEOUT_POP_SOUND_L_SFT) -+#define RK3308_DAC_L_SEL_DC_FROM_INTERNAL (0x2 << RK3308_DAC_LINEOUT_POP_SOUND_L_SFT) -+#define RK3308_DAC_L_SEL_DC_FROM_VCM (0x1 << RK3308_DAC_LINEOUT_POP_SOUND_L_SFT) -+#define RK3308_DAC_L_SEL_LINEOUT_FROM_INTERNAL (0x0 << RK3308_DAC_LINEOUT_POP_SOUND_L_SFT) -+ - #define RK3308_HIFI 0x0 - - #endif /* __RK3308_CODEC_H__ */ -diff --git a/sound/soc/codecs/rk3308_codec_provider.h b/sound/soc/codecs/rk3308_codec_provider.h -new file mode 100644 -index 000000000000..68042b1328dc ---- /dev/null -+++ b/sound/soc/codecs/rk3308_codec_provider.h -@@ -0,0 +1,28 @@ -+/* -+ * rk3308_codec_provider.h -- RK3308 ALSA Soc Audio Driver -+ * -+ * Copyright (c) 2018, Fuzhou Rockchip Electronics Co., Ltd All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope 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, see . -+ * -+ */ -+ -+#ifndef __RK3308_CODEC_PROVIDER_H__ -+#define __RK3308_CODEC_PROVIDER_H__ -+ -+#ifdef CONFIG_SND_SOC_RK3308 -+extern void (*rk3308_codec_set_jack_detect_cb)(struct snd_soc_codec *codec, -+ struct snd_soc_jack *hpdet_jack); -+#endif -+ -+#endif /* __RK3308_CODEC_PROVIDER_H__ */ --- -2.25.1 - diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0020-arm64-dts-rockchip-Add-acodec-node-for-rk3308.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpis-0020-arm64-dts-rockchip-Add-acodec-node-for-rk3308.patch deleted file mode 100644 index 15dbb49f25a3..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0020-arm64-dts-rockchip-Add-acodec-node-for-rk3308.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 198cad9a30ea2a5a252ceb97736f3475d7a6b08d Mon Sep 17 00:00:00 2001 -From: ashthespy -Date: Mon, 3 Feb 2020 17:19:33 +0100 -Subject: [PATCH 20/23] arm64: dts: rockchip: Add acodec node for rk3308 - -Change-Id: I76f4a877711d33620bdef295e9047bdba26d4da4 -Signed-off-by: Xing Zheng ---- - arch/arm64/boot/dts/rockchip/rk3308.dtsi | 18 +++++++++++++++++- - 1 file changed, 17 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3308.dtsi b/arch/arm64/boot/dts/rockchip/rk3308.dtsi -index c711c248ce29..3863f8cc2517 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3308.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3308.dtsi -@@ -510,7 +510,7 @@ rk_timer_rtc: rk-timer-rtc@ff1a0020 { - clock-names = "pclk", "timer"; - status = "disabled"; - }; -- -+ - saradc: saradc@ff1e0000 { - compatible = "rockchip,rk3308-saradc", "rockchip,rk3399-saradc"; - reg = <0x0 0xff1e0000 0x0 0x100>; -@@ -837,6 +837,22 @@ cru: clock-controller@ff500000 { - assigned-clock-rates = <32768>; - }; - -+ acodec: acodec@ff560000 { -+ compatible = "rockchip,rk3308-codec"; -+ reg = <0x0 0xff560000 0x0 0x10000>; -+ rockchip,grf = <&grf>; -+ rockchip,detect-grf = <&detect_grf>; -+ interrupts = , -+ ; -+ clocks = <&cru PCLK_ACODEC>, -+ <&cru SCLK_I2S2_8CH_TX_OUT>, -+ <&cru SCLK_I2S2_8CH_RX_OUT>; -+ clock-names = "acodec", "mclk_tx", "mclk_rx"; -+ resets = <&cru SRST_ACODEC_P>; -+ reset-names = "acodec-reset"; -+ status = "disabled"; -+}; -+ - gic: interrupt-controller@ff580000 { - compatible = "arm,gic-400"; - reg = <0x0 0xff581000 0x0 0x1000>, --- -2.25.1 - diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0022-ASoC-rk3308_codec-replace-codec-to-component.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpis-0022-ASoC-rk3308_codec-replace-codec-to-component.patch deleted file mode 100644 index 8fa58d3c84e0..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0022-ASoC-rk3308_codec-replace-codec-to-component.patch +++ /dev/null @@ -1,459 +0,0 @@ -From b882c2185ab561ec88c2540623cfa49e2cb56956 Mon Sep 17 00:00:00 2001 -From: ashthespy -Date: Mon, 3 Feb 2020 19:35:42 +0100 -Subject: [PATCH 22/23] ASoC: rk3308_codec: replace codec to component - ---- - sound/soc/codecs/rk3308_codec.c | 159 ++++++++++++----------- - sound/soc/codecs/rk3308_codec_provider.h | 2 +- - 2 files changed, 84 insertions(+), 77 deletions(-) - -diff --git a/sound/soc/codecs/rk3308_codec.c b/sound/soc/codecs/rk3308_codec.c -index 815e22fc346c..16bfb215586e 100644 ---- a/sound/soc/codecs/rk3308_codec.c -+++ b/sound/soc/codecs/rk3308_codec.c -@@ -31,7 +31,7 @@ - #include - #include - #include --#include -+// #include - #include - #include - #include -@@ -156,7 +156,7 @@ struct rk3308_codec_priv { - struct gpio_desc *hp_ctl_gpio; - struct gpio_desc *spk_ctl_gpio; - struct gpio_desc *pa_drv_gpio; -- struct snd_soc_codec *codec; -+ struct snd_soc_component *component; - struct snd_soc_jack *hpdet_jack; - struct regulator *vcc_micbias; - u32 codec_ver; -@@ -883,8 +883,8 @@ static const struct snd_kcontrol_new rk3308_codec_dapm_controls[] = { - static int rk3308_codec_agc_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) - { -- struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); -+ struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - - if (e->reg < 0 || e->reg > ADC_LR_GROUP_MAX - 1) { -@@ -904,8 +904,8 @@ static int rk3308_codec_agc_get(struct snd_kcontrol *kcontrol, - static int rk3308_codec_agc_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) - { -- struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); -+ struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - unsigned int value = ucontrol->value.integer.value[0]; - int grp = e->reg; -@@ -970,8 +970,8 @@ static int rk3308_codec_agc_put(struct snd_kcontrol *kcontrol, - static int rk3308_codec_agc_asr_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) - { -- struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); -+ struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - unsigned int value; - int grp = e->reg; -@@ -998,8 +998,8 @@ static int rk3308_codec_agc_asr_get(struct snd_kcontrol *kcontrol, - static int rk3308_codec_agc_asr_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) - { -- struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); -+ struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - unsigned int value; - int grp = e->reg; -@@ -1032,8 +1032,8 @@ static int rk3308_codec_agc_asr_put(struct snd_kcontrol *kcontrol, - static int rk3308_codec_mic_mute_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) - { -- struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); -+ struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - unsigned int value; - int grp = e->reg; -@@ -1064,8 +1064,8 @@ static int rk3308_codec_mic_mute_get(struct snd_kcontrol *kcontrol, - static int rk3308_codec_mic_mute_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) - { -- struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); -+ struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - unsigned int value; - int grp = e->reg; -@@ -1098,8 +1098,8 @@ static int rk3308_codec_mic_mute_put(struct snd_kcontrol *kcontrol, - static int rk3308_codec_micbias_volts_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) - { -- struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); -+ struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); - - ucontrol->value.integer.value[0] = rk3308->micbias_volt; - -@@ -1109,8 +1109,8 @@ static int rk3308_codec_micbias_volts_get(struct snd_kcontrol *kcontrol, - static int rk3308_codec_micbias_volts_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) - { -- struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); -+ struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); - unsigned int volt = ucontrol->value.integer.value[0]; - int ret; - -@@ -1133,8 +1133,8 @@ static int rk3308_codec_micbias_volts_put(struct snd_kcontrol *kcontrol, - static int rk3308_codec_main_micbias_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) - { -- struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); -+ struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); - - ucontrol->value.integer.value[0] = rk3308->enable_micbias; - -@@ -1144,8 +1144,8 @@ static int rk3308_codec_main_micbias_get(struct snd_kcontrol *kcontrol, - static int rk3308_codec_main_micbias_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) - { -- struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); -+ struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); - unsigned int on = ucontrol->value.integer.value[0]; - - if (on) { -@@ -1168,8 +1168,8 @@ static int rk3308_codec_mic_gain_get(struct snd_kcontrol *kcontrol, - static int rk3308_codec_mic_gain_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) - { -- struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); -+ struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); - unsigned int gain = ucontrol->value.integer.value[0]; - - if (gain > RK3308_ADC_CH1_MIC_GAIN_MAX) { -@@ -1197,8 +1197,8 @@ static int rk3308_codec_mic_gain_put(struct snd_kcontrol *kcontrol, - static int rk3308_codec_hpf_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) - { -- struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); -+ struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - unsigned int value; - -@@ -1222,8 +1222,8 @@ static int rk3308_codec_hpf_get(struct snd_kcontrol *kcontrol, - static int rk3308_codec_hpf_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) - { -- struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); -+ struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - unsigned int value = ucontrol->value.integer.value[0]; - -@@ -1259,8 +1259,8 @@ static int rk3308_codec_hpout_l_get_tlv(struct snd_kcontrol *kcontrol, - static int rk3308_codec_hpout_l_put_tlv(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) - { -- struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); -+ struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); - unsigned int dgain = ucontrol->value.integer.value[0]; - - if (dgain > RK3308_DAC_L_HPOUT_GAIN_MAX) { -@@ -1283,8 +1283,8 @@ static int rk3308_codec_hpout_r_get_tlv(struct snd_kcontrol *kcontrol, - static int rk3308_codec_hpout_r_put_tlv(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) - { -- struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); -+ struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); - unsigned int dgain = ucontrol->value.integer.value[0]; - - if (dgain > RK3308_DAC_R_HPOUT_GAIN_MAX) { -@@ -1408,9 +1408,9 @@ static void rk3308_speaker_ctl(struct rk3308_codec_priv *rk3308, int on) - } - } - --static int rk3308_codec_reset(struct snd_soc_codec *codec) -+static int rk3308_codec_reset(struct snd_soc_component *component) - { -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); - - reset_control_assert(rk3308->reset); - usleep_range(2000, 2500); /* estimated value */ -@@ -1452,10 +1452,10 @@ static int rk3308_codec_dac_dig_reset(struct rk3308_codec_priv *rk3308) - return 0; - } - --static int rk3308_set_bias_level(struct snd_soc_codec *codec, -+static int rk3308_set_bias_level(struct snd_soc_component *component, - enum snd_soc_bias_level level) - { -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); - - switch (level) { - case SND_SOC_BIAS_ON: -@@ -1473,11 +1473,11 @@ static int rk3308_set_bias_level(struct snd_soc_codec *codec, - return 0; - } - --static int rk3308_set_dai_fmt(struct snd_soc_dai *codec_dai, -+static int rk3308_set_dai_fmt(struct snd_soc_dai *dai, - unsigned int fmt) - { -- struct snd_soc_codec *codec = codec_dai->codec; -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct snd_soc_component *component = dai->component; -+ struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); - unsigned int adc_aif1 = 0, adc_aif2 = 0, dac_aif1 = 0, dac_aif2 = 0; - int idx, grp, is_master; - int type = ADC_TYPE_ALL; -@@ -1721,8 +1721,8 @@ static int rk3308_codec_update_adc_grps(struct rk3308_codec_priv *rk3308, - - static int rk3308_mute_stream(struct snd_soc_dai *dai, int mute, int stream) - { -- struct snd_soc_codec *codec = dai->codec; -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct snd_soc_component *component = dai->component; -+ struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); - - if (stream == SNDRV_PCM_STREAM_PLAYBACK) { - int dgain; -@@ -3630,8 +3630,8 @@ static int rk3308_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) - { -- struct snd_soc_codec *codec = dai->codec; -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct snd_soc_component *component = dai->component; -+ struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); - struct snd_pcm_str *playback_str = - &substream->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK]; - int type = ADC_TYPE_LOOPBACK; -@@ -3705,8 +3705,8 @@ static int rk3308_hw_params(struct snd_pcm_substream *substream, - static int rk3308_pcm_trigger(struct snd_pcm_substream *substream, - int cmd, struct snd_soc_dai *dai) - { -- struct snd_soc_codec *codec = dai->codec; -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct snd_soc_component *component = dai->component; -+ struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); - int type = ADC_TYPE_LOOPBACK; - int idx, grp; - -@@ -3749,8 +3749,8 @@ static int rk3308_pcm_trigger(struct snd_pcm_substream *substream, - static void rk3308_pcm_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) - { -- struct snd_soc_codec *codec = dai->codec; -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct snd_soc_component *component = dai->component; -+ struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - rk3308_codec_close_playback(rk3308); -@@ -3809,9 +3809,9 @@ static struct snd_soc_dai_driver rk3308_dai[] = { - }, - }; - --static int rk3308_suspend(struct snd_soc_codec *codec) -+static int rk3308_suspend(struct snd_soc_component *component) - { -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); - - if (rk3308->no_deep_low_power) - goto out; -@@ -3822,13 +3822,13 @@ static int rk3308_suspend(struct snd_soc_codec *codec) - clk_disable_unprepare(rk3308->pclk); - - out: -- rk3308_set_bias_level(codec, SND_SOC_BIAS_OFF); -+ rk3308_set_bias_level(component, SND_SOC_BIAS_OFF); - return 0; - } - --static int rk3308_resume(struct snd_soc_codec *codec) -+static int rk3308_resume(struct snd_soc_component *component) - { -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); - int ret = 0; - - if (rk3308->no_deep_low_power) -@@ -3857,7 +3857,7 @@ static int rk3308_resume(struct snd_soc_codec *codec) - - rk3308_codec_dlp_up(rk3308); - out: -- rk3308_set_bias_level(codec, SND_SOC_BIAS_STANDBY); -+ rk3308_set_bias_level(component, SND_SOC_BIAS_STANDBY); - return ret; - } - -@@ -3972,7 +3972,7 @@ static int rk3308_codec_dapm_mic_gains(struct rk3308_codec_priv *rk3308) - int ret; - - if (rk3308->codec_ver == ACODEC_VERSION_B) { -- ret = snd_soc_add_codec_controls(rk3308->codec, -+ ret = snd_soc_add_component_controls(rk3308->component, - mic_gains_b, - ARRAY_SIZE(mic_gains_b)); - if (ret) { -@@ -3982,7 +3982,7 @@ static int rk3308_codec_dapm_mic_gains(struct rk3308_codec_priv *rk3308) - return ret; - } - } else { -- ret = snd_soc_add_codec_controls(rk3308->codec, -+ ret = snd_soc_add_component_controls(rk3308->component, - mic_gains_a, - ARRAY_SIZE(mic_gains_a)); - if (ret) { -@@ -4081,15 +4081,15 @@ static int rk3308_codec_prepare(struct rk3308_codec_priv *rk3308) - return 0; - } - --static int rk3308_probe(struct snd_soc_codec *codec) -+static int rk3308_probe(struct snd_soc_component *component) - { -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); - int ext_micbias; - -- rk3308->codec = codec; -+ rk3308->component = component; - rk3308_codec_set_dac_path_state(rk3308, PATH_IDLE); - -- rk3308_codec_reset(codec); -+ rk3308_codec_reset(component); - rk3308_codec_power_on(rk3308); - - /* From vendor recommend, disable micbias at first. */ -@@ -4108,9 +4108,9 @@ static int rk3308_probe(struct snd_soc_codec *codec) - return 0; - } - --static int rk3308_remove(struct snd_soc_codec *codec) -+static void rk3308_remove(struct snd_soc_component *component) - { -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); - - rk3308_headphone_ctl(rk3308, 0); - rk3308_speaker_ctl(rk3308, 0); -@@ -4124,17 +4124,25 @@ static int rk3308_remove(struct snd_soc_codec *codec) - regcache_cache_only(rk3308->regmap, false); - regcache_sync(rk3308->regmap); - -- return 0; - } - --static struct snd_soc_codec_driver soc_codec_dev_rk3308 = { -- .probe = rk3308_probe, -- .remove = rk3308_remove, -- .suspend = rk3308_suspend, -- .resume = rk3308_resume, -- .set_bias_level = rk3308_set_bias_level, -- .controls = rk3308_codec_dapm_controls, -- .num_controls = ARRAY_SIZE(rk3308_codec_dapm_controls), -+static const struct snd_soc_component_driver soc_codec_dev_rk3308_component = { -+ .probe = rk3308_probe, -+ .remove = rk3308_remove, -+ .resume = rk3308_resume, -+ .suspend = rk3308_suspend, -+ .set_bias_level = rk3308_set_bias_level, -+ .controls = rk3308_codec_dapm_controls, -+ .num_controls = ARRAY_SIZE(rk3308_codec_dapm_controls), -+ // .dapm_widgets = rk3308_dapm_widgets, -+ // .num_dapm_widgets = ARRAY_SIZE(rk3308_dapm_widgets), -+ // .dapm_routes = rk3308_dapm_routes, -+ // .num_dapm_routes = ARRAY_SIZE(rk3308_dapm_routes), -+ // .suspend_bias_off = 1, -+ // .idle_bias_on = 1, -+ // .use_pmdown_time = 1, -+ .endianness = 1, -+ .legacy_dai_naming = 1, - }; - - static const struct reg_default rk3308_codec_reg_defaults[] = { -@@ -4299,14 +4307,14 @@ static irqreturn_t rk3308_codec_hpdet_isr(int irq, void *data) - return IRQ_HANDLED; - } - --void (*rk3308_codec_set_jack_detect_cb)(struct snd_soc_codec *codec, -+void (*rk3308_codec_set_jack_detect_cb)(struct snd_soc_component *component, - struct snd_soc_jack *hpdet_jack); - EXPORT_SYMBOL_GPL(rk3308_codec_set_jack_detect_cb); - --static void rk3308_codec_set_jack_detect(struct snd_soc_codec *codec, -+static void rk3308_codec_set_jack_detect(struct snd_soc_component *component, - struct snd_soc_jack *hpdet_jack) - { -- struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec); -+ struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); - - rk3308->hpdet_jack = hpdet_jack; - -@@ -5114,10 +5122,10 @@ static int rk3308_platform_probe(struct platform_device *pdev) - - platform_set_drvdata(pdev, rk3308); - -- ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_rk3308, -+ ret = devm_snd_soc_register_component(&pdev->dev, &soc_codec_dev_rk3308_component, - rk3308_dai, ARRAY_SIZE(rk3308_dai)); - if (ret < 0) { -- dev_err(&pdev->dev, "Failed to register codec: %d\n", ret); -+ dev_err(&pdev->dev, "Failed to register component: %d\n", ret); - goto failed; - } - -@@ -5140,7 +5148,6 @@ static int rk3308_platform_remove(struct platform_device *pdev) - clk_disable_unprepare(rk3308->mclk_rx); - clk_disable_unprepare(rk3308->mclk_tx); - clk_disable_unprepare(rk3308->pclk); -- snd_soc_unregister_codec(&pdev->dev); - device_unregister(&rk3308->dev); - - return 0; -diff --git a/sound/soc/codecs/rk3308_codec_provider.h b/sound/soc/codecs/rk3308_codec_provider.h -index 68042b1328dc..34c1ef86a507 100644 ---- a/sound/soc/codecs/rk3308_codec_provider.h -+++ b/sound/soc/codecs/rk3308_codec_provider.h -@@ -21,7 +21,7 @@ - #define __RK3308_CODEC_PROVIDER_H__ - - #ifdef CONFIG_SND_SOC_RK3308 --extern void (*rk3308_codec_set_jack_detect_cb)(struct snd_soc_codec *codec, -+extern void (*rk3308_codec_set_jack_detect_cb)(struct snd_soc_component *component, - struct snd_soc_jack *hpdet_jack); - #endif - --- -2.25.1 - diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0027-arm64-dts-rk3308-add-otp-cpuinfo.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpis-0027-arm64-dts-rk3308-add-otp-cpuinfo.patch deleted file mode 100644 index fc3d4b22e3d9..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0027-arm64-dts-rk3308-add-otp-cpuinfo.patch +++ /dev/null @@ -1,45 +0,0 @@ ---- a/arch/arm64/boot/dts/rockchip/rk3308.dtsi 2020-12-26 18:07:15.666727654 +0200 -+++ b/arch/arm64/boot/dts/rockchip/rk3308.dtsi 2020-12-26 18:35:42.115701024 +0200 -@@ -139,6 +151,12 @@ - interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; - }; - -+ cpuinfo { -+ compatible = "rockchip,cpuinfo"; -+ nvmem-cells = <&cpu_id>; -+ nvmem-cell-names = "id"; -+ }; -+ - mac_clkin: external-mac-clock { - compatible = "fixed-clock"; - clock-frequency = <50000000>; -@@ -146,6 +164,29 @@ - #clock-cells = <0>; - }; - -+ otp: otp@ff210000 { -+ compatible = "rockchip,rk3308-otp"; -+ reg = <0x0 0xff210000 0x0 0x4000>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ clocks = <&cru SCLK_OTP_USR>, <&cru PCLK_OTP_NS>, -+ <&cru PCLK_OTP_PHY>; -+ clock-names = "otp", "apb_pclk", "phy"; -+ resets = <&cru SRST_OTP_PHY>; -+ reset-names = "phy"; -+ -+ /* Data cells */ -+ cpu_id: id@7 { -+ reg = <0x07 0x10>; -+ }; -+ cpu_leakage: cpu-leakage@17 { -+ reg = <0x17 0x1>; -+ }; -+ logic_leakage: logic-leakage@18 { -+ reg = <0x18 0x1>; -+ }; -+ }; -+ - psci { - compatible = "arm,psci-1.0"; - method = "smc"; diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0029-arm64-dts-rk3308-add-reserved-memory-ramoops.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpis-0029-arm64-dts-rk3308-add-reserved-memory-ramoops.patch deleted file mode 100644 index ad0100092d23..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0029-arm64-dts-rk3308-add-reserved-memory-ramoops.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- a/arch/arm64/boot/dts/rockchip/rk3308.dtsi 2020-12-26 18:07:15.666727654 +0200 -+++ b/arch/arm64/boot/dts/rockchip/rk3308.dtsi 2020-12-26 18:13:13.061143555 +0200 -@@ -148,6 +148,26 @@ - method = "smc"; - }; - -+ reserved-memory { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ ranges; -+ -+ drm_logo: drm-logo@00000000 { -+ compatible = "rockchip,drm-logo"; -+ reg = <0x0 0x0 0x0 0x0>; -+ }; -+ -+ ramoops: ramoops@110000 { -+ compatible = "ramoops"; -+ reg = <0x0 0x110000 0x0 0xf0000>; -+ record-size = <0x30000>; -+ console-size = <0xc0000>; -+ ftrace-size = <0x00000>; -+ pmsg-size = <0x00000>; -+ }; -+ }; -+ - timer { - compatible = "arm,armv8-timer"; - interrupts = , diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0030-fix10MbitEthernet.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpis-0030-fix10MbitEthernet.patch deleted file mode 100644 index a7f194d8e188..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0030-fix10MbitEthernet.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Brent Roman -Date: Sat, 30 Dec 2023 12:04:32 -0800 -Subject: fix10MbitEthernet - drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c - -Signed-off-by: Brent Roman ---- - drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 27 ++++++---- - 1 file changed, 17 insertions(+), 10 deletions(-) - -diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c -index cf682a9e3..512a7586c 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c -@@ -504,12 +504,12 @@ static const struct rk_gmac_ops rk3288_ops = { - #define RK3308_GRF_MAC_CON0 0x04a0 - - /* RK3308_GRF_MAC_CON0 */ - #define RK3308_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(2) | GRF_CLR_BIT(3) | \ - GRF_BIT(4)) --#define RK3308_GMAC_FLOW_CTRL GRF_BIT(3) --#define RK3308_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) -+#define RK3308_GMAC_FLOW_CTRL GRF_BIT(1) -+#define RK3308_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(1) - #define RK3308_GMAC_SPEED_10M GRF_CLR_BIT(0) - #define RK3308_GMAC_SPEED_100M GRF_BIT(0) - - static void rk3308_set_to_rmii(struct rk_priv_data *bsp_priv) - { -@@ -525,24 +525,31 @@ static void rk3308_set_to_rmii(struct rk_priv_data *bsp_priv) - } - - static void rk3308_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) - { - struct device *dev = &bsp_priv->pdev->dev; -+ int rateMode; - - if (IS_ERR(bsp_priv->grf)) { - dev_err(dev, "Missing rockchip,grf property\n"); - return; - } - -- if (speed == 10) { -- regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0, -- RK3308_GMAC_SPEED_10M); -- } else if (speed == 100) { -- regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0, -- RK3308_GMAC_SPEED_100M); -- } else { -- dev_err(dev, "unknown speed value for RMII! speed=%d", speed); -+ if (speed == 10) -+ rateMode = RK3308_GMAC_SPEED_10M; -+ else if (speed == 100) -+ rateMode = RK3308_GMAC_SPEED_100M; -+ else { -+ dev_err(dev, "RMII does not support %dMbps", speed); -+ return; -+ } -+ regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0, rateMode); -+ { -+ int ret = clk_set_rate(bsp_priv->clks[RK_CLK_MAC_SPEED].clk, 250000*speed); -+ if (ret) -+ dev_err(dev, "%s: clk_set_rate for %dMbps returned: %d\n", -+ __func__, speed, ret); - } - } - - static const struct rk_gmac_ops rk3308_ops = { - .set_to_rmii = rk3308_set_to_rmii, --- -Created with Armbian build tools https://github.com/armbian/build - diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpro64-0001-Add-pcie-bus-scan-delay.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpro64-0001-Add-pcie-bus-scan-delay.patch deleted file mode 100644 index a8d60d01a925..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpro64-0001-Add-pcie-bus-scan-delay.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi -index bfd57f6f0..5374753cd 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi -@@ -579,6 +579,7 @@ &pcie0 { - pinctrl-0 = <&pcie_perst>; - vpcie12v-supply = <&vcc12v_dcin>; - vpcie3v3-supply = <&vcc3v3_pcie>; -+ bus-scan-delay-ms = <1000>; - status = "okay"; - }; - diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpro64-change-rx_delay-for-gmac.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpro64-change-rx_delay-for-gmac.patch deleted file mode 100644 index 45b8b4359882..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpro64-change-rx_delay-for-gmac.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 57825a7190ac09a1e273cab12e797010fcb7a1c9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Kamil=20Trzci=C5=84ski?= -Date: Sun, 30 Dec 2018 13:32:47 +0100 -Subject: [PATCH] ayufan: dts: rockpro64: change rx_delay for gmac - -Change-Id: Ib3899f684188aa1ed1545717af004bba53fe0e07 ---- - arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi -index cdab3089046c..0db9de46ff16 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi -@@ -249,7 +249,7 @@ - snps,reset-active-low; - snps,reset-delays-us = <0 10000 50000>; - tx_delay = <0x28>; -- rx_delay = <0x11>; -+ rx_delay = <0x20>; - status = "okay"; - }; - --- -2.20.1 - diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpro64-fix-emmc.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpro64-fix-emmc.patch deleted file mode 100644 index 2914146cf288..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpro64-fix-emmc.patch +++ /dev/null @@ -1,20 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi -index 714616618..b1fb824f3 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi -@@ -15,6 +15,7 @@ - compatible = "pine64,rockpro64", "rockchip,rk3399"; - - chosen { -+ bootargs = "mmc_cmdqueue=0 earlycon=uart8250,mmio32,0xff1a0000"; - stdout-path = "serial2:1500000n8"; - }; - -@@ -635,6 +636,7 @@ - - &sdhci { - bus-width = <8>; -+ keep-power-in-suspend; - mmc-hs200-1_8v; - non-removable; - status = "okay"; diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpro64-fix-spi1-flash-speed.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpro64-fix-spi1-flash-speed.patch deleted file mode 100644 index 51dc2a9a8d0e..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpro64-fix-spi1-flash-speed.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts -index 49050de8c..714616618 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi -@@ -646,7 +646,7 @@ - flash@0 { - compatible = "jedec,spi-nor"; - reg = <0>; -- spi-max-frequency = <10000000>; -+ spi-max-frequency = <3000000>; - }; - }; - diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpro64-work-led-heartbeat.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpro64-work-led-heartbeat.patch deleted file mode 100644 index 0458328ca343..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpro64-work-led-heartbeat.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi -index 274e72b37..311e5886f 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi -@@ -44,7 +44,7 @@ - - work-led { - label = "work"; -- default-state = "on"; -+ linux,default-trigger = "heartbeat"; - gpios = <&gpio0 RK_PB3 GPIO_ACTIVE_HIGH>; - }; - diff --git a/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/README.md b/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/README.md deleted file mode 100644 index a12897df96cc..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/README.md +++ /dev/null @@ -1 +0,0 @@ -Files archived to folder before 2023.02 release. Will be deleted for next release if not reviewed. \ No newline at end of file diff --git a/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/add-fusb30x-driver.patch.disabled b/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/add-fusb30x-driver.patch.disabled deleted file mode 100644 index 67233f0e9060..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/add-fusb30x-driver.patch.disabled +++ /dev/null @@ -1,4047 +0,0 @@ -diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig -index 1abf76be2..7ad8b090c 100644 ---- a/drivers/staging/Kconfig -+++ b/drivers/staging/Kconfig -@@ -92,6 +92,8 @@ source "drivers/staging/fbtft/Kconfig" - - source "drivers/staging/fsl-dpaa2/Kconfig" - -+source "drivers/staging/fusb30x/Kconfig" -+ - source "drivers/staging/most/Kconfig" - - source "drivers/staging/ks7010/Kconfig" -diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile -index ab0cbe881..2e308d901 100644 ---- a/drivers/staging/Makefile -+++ b/drivers/staging/Makefile -@@ -36,6 +36,7 @@ obj-$(CONFIG_UNISYSSPAR) += unisys/ - obj-$(CONFIG_UNISYSSPAR) += unisys/ - obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD) += clocking-wizard/ - obj-$(CONFIG_FB_TFT) += fbtft/ -+obj-$(CONFIG_FUSB_30X) += fusb30x/ - obj-$(CONFIG_MOST) += most/ - obj-$(CONFIG_KS7010) += ks7010/ - obj-$(CONFIG_GREYBUS) += greybus/ -diff --git a/drivers/staging/fusb30x/Kconfig b/drivers/staging/fusb30x/Kconfig -new file mode 100644 -index 000000000..5bb75270f ---- /dev/null -+++ b/drivers/staging/fusb30x/Kconfig -@@ -0,0 +1,10 @@ -+config FUSB_30X -+ tristate "Fairchild FUSB30X Type-C chip driver" -+ depends on I2C -+ help -+ This is a driver for the Fairchild FUSB302 Type-C chip. It supports -+ USB Type-C PD functionality controlled using I2C. -+ -+ This driver supports extcon reporting not yet implemented in the -+ mainline FUSB302 driver. -+ -diff --git a/drivers/staging/fusb30x/Makefile b/drivers/staging/fusb30x/Makefile -new file mode 100644 -index 000000000..1c8e35df3 ---- /dev/null -+++ b/drivers/staging/fusb30x/Makefile -@@ -0,0 +1,2 @@ -+# SPDX-License-Identifier: GPL-2.0 -+obj-$(CONFIG_FUSB_30X) += fusb30x.o -diff --git a/drivers/staging/fusb30x/fusb30x.c b/drivers/staging/fusb30x/fusb30x.c -new file mode 100644 -index 000000000..56d22648c ---- /dev/null -+++ b/drivers/staging/fusb30x/fusb30x.c -@@ -0,0 +1,3434 @@ -+/* -+ * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd -+ * Author: Zain Wang -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2, as published by the Free Software Foundation. -+ * -+ * Some ideas are from chrome ec and fairchild GPL fusb302 driver. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "fusb30x.h" -+ -+#define FUSB302_MAX_REG (FUSB_REG_FIFO + 50) -+#define FUSB_MS_TO_NS(x) ((s64)x * 1000 * 1000) -+ -+#define TYPEC_CC_VOLT_OPEN 0 -+#define TYPEC_CC_VOLT_RA 1 -+#define TYPEC_CC_VOLT_RD 2 -+#define TYPEC_CC_VOLT_RP 3 -+ -+#define EVENT_CC BIT(0) -+#define EVENT_RX BIT(1) -+#define EVENT_TX BIT(2) -+#define EVENT_REC_RESET BIT(3) -+#define EVENT_WORK_CONTINUE BIT(5) -+#define EVENT_TIMER_MUX BIT(6) -+#define EVENT_TIMER_STATE BIT(7) -+#define EVENT_DELAY_CC BIT(8) -+#define FLAG_EVENT (EVENT_RX | EVENT_TIMER_MUX | \ -+ EVENT_TIMER_STATE) -+ -+#define PACKET_IS_CONTROL_MSG(header, type) \ -+ (PD_HEADER_CNT(header) == 0 && \ -+ PD_HEADER_TYPE(header) == type) -+ -+#define PACKET_IS_DATA_MSG(header, type) \ -+ (PD_HEADER_CNT(header) != 0 && \ -+ PD_HEADER_TYPE(header) == type) -+ -+/* -+ * DisplayPort modes capabilities -+ * ------------------------------- -+ * <31:24> : Reserved (always 0). -+ * <23:16> : UFP_D pin assignment supported -+ * <15:8> : DFP_D pin assignment supported -+ * <7> : USB 2.0 signaling (0b=yes, 1b=no) -+ * <6> : Plug | Receptacle (0b == plug, 1b == receptacle) -+ * <5:2> : xxx1: Supports DPv1.3, xx1x Supports USB Gen 2 signaling -+ * Other bits are reserved. -+ * <1:0> : signal direction ( 00b=rsv, 01b=sink, 10b=src 11b=both ) -+ */ -+#define PD_DP_PIN_CAPS(x) ((((x) >> 6) & 0x1) ? (((x) >> 16) & 0x3f) \ -+ : (((x) >> 8) & 0x3f)) -+#define PD_DP_SIGNAL_GEN2(x) (((x) >> 3) & 0x1) -+ -+#define MODE_DP_PIN_A BIT(0) -+#define MODE_DP_PIN_B BIT(1) -+#define MODE_DP_PIN_C BIT(2) -+#define MODE_DP_PIN_D BIT(3) -+#define MODE_DP_PIN_E BIT(4) -+#define MODE_DP_PIN_F BIT(5) -+ -+/* Pin configs B/D/F support multi-function */ -+#define MODE_DP_PIN_MF_MASK (MODE_DP_PIN_B | MODE_DP_PIN_D | MODE_DP_PIN_F) -+/* Pin configs A/B support BR2 signaling levels */ -+#define MODE_DP_PIN_BR2_MASK (MODE_DP_PIN_A | MODE_DP_PIN_B) -+/* Pin configs C/D/E/F support DP signaling levels */ -+#define MODE_DP_PIN_DP_MASK (MODE_DP_PIN_C | MODE_DP_PIN_D | \ -+ MODE_DP_PIN_E | MODE_DP_PIN_F) -+ -+/* -+ * DisplayPort Status VDO -+ * ---------------------- -+ * <31:9> : Reserved (always 0). -+ * <8> : IRQ_HPD : 1 == irq arrived since last message otherwise 0. -+ * <7> : HPD state : 0 = HPD_LOW, 1 == HPD_HIGH -+ * <6> : Exit DP Alt mode: 0 == maintain, 1 == exit -+ * <5> : USB config : 0 == maintain current, 1 == switch to USB from DP -+ * <4> : Multi-function preference : 0 == no pref, 1 == MF preferred. -+ * <3> : enabled : is DPout on/off. -+ * <2> : power low : 0 == normal or LPM disabled, 1 == DP disabled for LPM -+ * <1:0> : connect status : 00b == no (DFP|UFP)_D is connected or disabled. -+ * 01b == DFP_D connected, 10b == UFP_D connected, 11b == both. -+ */ -+#define PD_VDO_DPSTS_HPD_IRQ(x) (((x) >> 8) & 0x1) -+#define PD_VDO_DPSTS_HPD_LVL(x) (((x) >> 7) & 0x1) -+#define PD_VDO_DPSTS_MF_PREF(x) (((x) >> 4) & 0x1) -+ -+static u8 fusb30x_port_used; -+static struct fusb30x_chip *fusb30x_port_info[256]; -+ -+static bool is_write_reg(struct device *dev, unsigned int reg) -+{ -+ if (reg >= FUSB_REG_FIFO) -+ return true; -+ else -+ return ((reg < (FUSB_REG_CONTROL4 + 1)) && (reg > 0x01)) ? -+ true : false; -+} -+ -+static bool is_volatile_reg(struct device *dev, unsigned int reg) -+{ -+ if (reg > FUSB_REG_CONTROL4) -+ return true; -+ -+ switch (reg) { -+ case FUSB_REG_CONTROL0: -+ case FUSB_REG_CONTROL1: -+ case FUSB_REG_CONTROL3: -+ case FUSB_REG_RESET: -+ return true; -+ } -+ return false; -+} -+ -+struct regmap_config fusb302_regmap_config = { -+ .reg_bits = 8, -+ .val_bits = 8, -+ .writeable_reg = is_write_reg, -+ .volatile_reg = is_volatile_reg, -+ .max_register = FUSB302_MAX_REG, -+ .cache_type = REGCACHE_RBTREE, -+}; -+ -+static void dump_notify_info(struct fusb30x_chip *chip) -+{ -+ dev_dbg(chip->dev, "port %d\n", chip->port_num); -+ dev_dbg(chip->dev, "orientation %d\n", chip->notify.orientation); -+ dev_dbg(chip->dev, "power_role %d\n", chip->notify.power_role); -+ dev_dbg(chip->dev, "data_role %d\n", chip->notify.data_role); -+ dev_dbg(chip->dev, "cc %d\n", chip->notify.is_cc_connected); -+ dev_dbg(chip->dev, "pd %d\n", chip->notify.is_pd_connected); -+ dev_dbg(chip->dev, "enter_mode %d\n", chip->notify.is_enter_mode); -+ dev_dbg(chip->dev, "pin support %d\n", -+ chip->notify.pin_assignment_support); -+ dev_dbg(chip->dev, "pin def %d\n", chip->notify.pin_assignment_def); -+ dev_dbg(chip->dev, "attention %d\n", chip->notify.attention); -+} -+ -+static const unsigned int fusb302_cable[] = { -+ EXTCON_USB, -+ EXTCON_USB_HOST, -+ EXTCON_CHG_USB_SDP, -+ EXTCON_CHG_USB_CDP, -+ EXTCON_CHG_USB_DCP, -+ EXTCON_CHG_USB_SLOW, -+ EXTCON_CHG_USB_FAST, -+ EXTCON_DISP_DP, -+ EXTCON_NONE, -+}; -+ -+static void fusb_set_pos_power(struct fusb30x_chip *chip, int max_vol, -+ int max_cur) -+{ -+ int i; -+ int pos_find; -+ int tmp; -+ -+ pos_find = 0; -+ for (i = PD_HEADER_CNT(chip->rec_head) - 1; i >= 0; i--) { -+ switch (CAP_POWER_TYPE(chip->rec_load[i])) { -+ case 0: -+ /* Fixed Supply */ -+ if ((CAP_FPDO_VOLTAGE(chip->rec_load[i]) * 50) <= -+ max_vol && -+ (CAP_FPDO_CURRENT(chip->rec_load[i]) * 10) <= -+ max_cur) { -+ chip->pos_power = i + 1; -+ tmp = CAP_FPDO_VOLTAGE(chip->rec_load[i]); -+ chip->pd_output_vol = tmp * 50; -+ tmp = CAP_FPDO_CURRENT(chip->rec_load[i]); -+ chip->pd_output_cur = tmp * 10; -+ pos_find = 1; -+ } -+ break; -+ case 1: -+ /* Battery */ -+ if ((CAP_VPDO_VOLTAGE(chip->rec_load[i]) * 50) <= -+ max_vol && -+ (CAP_VPDO_CURRENT(chip->rec_load[i]) * 10) <= -+ max_cur) { -+ chip->pos_power = i + 1; -+ tmp = CAP_VPDO_VOLTAGE(chip->rec_load[i]); -+ chip->pd_output_vol = tmp * 50; -+ tmp = CAP_VPDO_CURRENT(chip->rec_load[i]); -+ chip->pd_output_cur = tmp * 10; -+ pos_find = 1; -+ } -+ break; -+ default: -+ /* not meet battery caps */ -+ break; -+ } -+ if (pos_find) -+ break; -+ } -+} -+ -+static int fusb302_set_pos_power_by_charge_ic(struct fusb30x_chip *chip) -+{ -+ struct power_supply *psy = NULL; -+ union power_supply_propval val; -+ enum power_supply_property psp; -+ int max_vol, max_cur; -+ -+ max_vol = 0; -+ max_cur = 0; -+ psy = power_supply_get_by_phandle(chip->dev->of_node, "charge-dev"); -+ if (!psy || IS_ERR(psy)) -+ return -1; -+ -+ psp = POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX; -+ if (power_supply_get_property(psy, psp, &val) == 0) -+ max_vol = val.intval / 1000; -+ -+ psp = POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT; -+ if (power_supply_get_property(psy, psp, &val) == 0) -+ max_cur = val.intval / 1000; -+ -+ if (max_vol > 0 && max_cur > 0) -+ fusb_set_pos_power(chip, max_vol, max_cur); -+ -+ return 0; -+} -+ -+void fusb_irq_disable(struct fusb30x_chip *chip) -+{ -+ unsigned long irqflags = 0; -+ -+ spin_lock_irqsave(&chip->irq_lock, irqflags); -+ if (chip->enable_irq) { -+ disable_irq_nosync(chip->gpio_int_irq); -+ chip->enable_irq = 0; -+ } else { -+ dev_warn(chip->dev, "irq have already disabled\n"); -+ } -+ spin_unlock_irqrestore(&chip->irq_lock, irqflags); -+} -+ -+void fusb_irq_enable(struct fusb30x_chip *chip) -+{ -+ unsigned long irqflags = 0; -+ -+ spin_lock_irqsave(&chip->irq_lock, irqflags); -+ if (!chip->enable_irq) { -+ enable_irq(chip->gpio_int_irq); -+ chip->enable_irq = 1; -+ } -+ spin_unlock_irqrestore(&chip->irq_lock, irqflags); -+} -+ -+static void platform_fusb_notify(struct fusb30x_chip *chip) -+{ -+ bool plugged = false, flip = false, dfp = false, ufp = false, -+ dp = false, usb_ss = false, hpd = false; -+ union extcon_property_value property; -+ -+ if (chip->notify.is_cc_connected) -+ chip->notify.orientation = -+ (chip->cc_polarity == TYPEC_POLARITY_CC1) ? -+ CC1 : CC2; -+ -+ /* avoid notify repeated */ -+ if (memcmp(&chip->notify, &chip->notify_cmp, -+ sizeof(struct notify_info))) { -+ dump_notify_info(chip); -+ chip->notify.attention = false; -+ memcpy(&chip->notify_cmp, &chip->notify, -+ sizeof(struct notify_info)); -+ -+ plugged = chip->notify.is_cc_connected || -+ chip->notify.is_pd_connected; -+ if (chip->notify.orientation != NONE) -+ flip = (chip->notify.orientation == CC1) ? false : true; -+ dp = chip->notify.is_enter_mode; -+ -+ if (dp) { -+ dfp = true; -+ usb_ss = (chip->notify.pin_assignment_def & -+ MODE_DP_PIN_MF_MASK) ? true : false; -+ hpd = GET_DP_STATUS_HPD(chip->notify.dp_status); -+ } else if (chip->notify.data_role) { -+ dfp = true; -+ usb_ss = true; -+ } else if (plugged) { -+ ufp = true; -+ usb_ss = true; -+ } -+ -+ property.intval = flip; -+ extcon_set_property(chip->extcon, EXTCON_USB, -+ EXTCON_PROP_USB_TYPEC_POLARITY, property); -+ extcon_set_property(chip->extcon, EXTCON_USB_HOST, -+ EXTCON_PROP_USB_TYPEC_POLARITY, property); -+ extcon_set_property(chip->extcon, EXTCON_DISP_DP, -+ EXTCON_PROP_USB_TYPEC_POLARITY, property); -+ -+ property.intval = usb_ss; -+ extcon_set_property(chip->extcon, EXTCON_USB, -+ EXTCON_PROP_USB_SS, property); -+ extcon_set_property(chip->extcon, EXTCON_USB_HOST, -+ EXTCON_PROP_USB_SS, property); -+ extcon_set_property(chip->extcon, EXTCON_DISP_DP, -+ EXTCON_PROP_USB_SS, property); -+ extcon_set_state(chip->extcon, EXTCON_USB, ufp); -+ extcon_set_state(chip->extcon, EXTCON_USB_HOST, dfp); -+ extcon_set_state(chip->extcon, EXTCON_DISP_DP, dp && hpd); -+ extcon_sync(chip->extcon, EXTCON_USB); -+ extcon_sync(chip->extcon, EXTCON_USB_HOST); -+ extcon_sync(chip->extcon, EXTCON_DISP_DP); -+ if (chip->notify.power_role == POWER_ROLE_SINK && -+ chip->notify.is_pd_connected && -+ chip->pd_output_vol > 0 && chip->pd_output_cur > 0) { -+ extcon_set_state(chip->extcon, EXTCON_CHG_USB_FAST, true); -+ property.intval = -+ (chip->pd_output_cur << 15 | -+ chip->pd_output_vol); -+ extcon_set_property(chip->extcon, EXTCON_CHG_USB_FAST, -+ EXTCON_PROP_USB_TYPEC_POLARITY, -+ property); -+ extcon_sync(chip->extcon, EXTCON_CHG_USB_FAST); -+ } -+ } -+} -+ -+static bool platform_get_device_irq_state(struct fusb30x_chip *chip) -+{ -+ return !gpiod_get_value(chip->gpio_int); -+} -+ -+static void fusb_timer_start(struct hrtimer *timer, int ms) -+{ -+ ktime_t ktime; -+ -+ ktime = ktime_set(0, FUSB_MS_TO_NS(ms)); -+ hrtimer_start(timer, ktime, HRTIMER_MODE_REL); -+} -+ -+static void platform_set_vbus_lvl_enable(struct fusb30x_chip *chip, int vbus_5v, -+ int vbus_other) -+{ -+ bool gpio_vbus_value = false; -+ -+ gpio_vbus_value = gpiod_get_value(chip->gpio_vbus_5v); -+ if (chip->gpio_vbus_5v) { -+ gpiod_set_raw_value(chip->gpio_vbus_5v, vbus_5v); -+ } -+ -+ if (chip->gpio_vbus_other) -+ gpiod_set_raw_value(chip->gpio_vbus_5v, vbus_other); -+ -+ if (chip->gpio_discharge && !vbus_5v && gpio_vbus_value) { -+ gpiod_set_value(chip->gpio_discharge, 1); -+ msleep(20); -+ gpiod_set_value(chip->gpio_discharge, 0); -+ } -+} -+ -+static void set_state(struct fusb30x_chip *chip, enum connection_state state) -+{ -+ dev_dbg(chip->dev, "port %d, state %d\n", chip->port_num, state); -+ if (!state) -+ dev_info(chip->dev, "PD disabled\n"); -+ chip->conn_state = state; -+ chip->sub_state = 0; -+ chip->val_tmp = 0; -+ chip->work_continue |= EVENT_WORK_CONTINUE; -+} -+ -+static int tcpm_get_message(struct fusb30x_chip *chip) -+{ -+ u8 buf[32]; -+ int len; -+ -+ do { -+ regmap_raw_read(chip->regmap, FUSB_REG_FIFO, buf, 3); -+ chip->rec_head = (buf[1] & 0xff) | ((buf[2] << 8) & 0xff00); -+ -+ len = PD_HEADER_CNT(chip->rec_head) << 2; -+ regmap_raw_read(chip->regmap, FUSB_REG_FIFO, buf, len + 4); -+ /* ignore good_crc message */ -+ } while (PACKET_IS_CONTROL_MSG(chip->rec_head, CMT_GOODCRC)); -+ -+ memcpy(chip->rec_load, buf, len); -+ -+ return 0; -+} -+ -+static void fusb302_flush_rx_fifo(struct fusb30x_chip *chip) -+{ -+ regmap_write(chip->regmap, FUSB_REG_CONTROL1, CONTROL1_RX_FLUSH); -+} -+ -+static int tcpm_get_cc(struct fusb30x_chip *chip, int *CC1, int *CC2) -+{ -+ u32 val; -+ int *CC_MEASURE; -+ u32 store; -+ -+ *CC1 = TYPEC_CC_VOLT_OPEN; -+ *CC2 = TYPEC_CC_VOLT_OPEN; -+ -+ if (chip->cc_state & CC_STATE_TOGSS_CC1) -+ CC_MEASURE = CC1; -+ else -+ CC_MEASURE = CC2; -+ -+ if (chip->cc_state & CC_STATE_TOGSS_IS_UFP) { -+ regmap_read(chip->regmap, FUSB_REG_SWITCHES0, &store); -+ /* measure cc1 first */ -+ regmap_update_bits(chip->regmap, FUSB_REG_SWITCHES0, -+ SWITCHES0_MEAS_CC1 | SWITCHES0_MEAS_CC2 | -+ SWITCHES0_PU_EN1 | SWITCHES0_PU_EN2 | -+ SWITCHES0_PDWN1 | SWITCHES0_PDWN2, -+ SWITCHES0_PDWN1 | SWITCHES0_PDWN2 | -+ SWITCHES0_MEAS_CC1); -+ usleep_range(250, 300); -+ -+ regmap_read(chip->regmap, FUSB_REG_STATUS0, &val); -+ val &= STATUS0_BC_LVL; -+ *CC1 = val ? TYPEC_CC_VOLT_RP : TYPEC_CC_VOLT_OPEN; -+ -+ regmap_update_bits(chip->regmap, FUSB_REG_SWITCHES0, -+ SWITCHES0_MEAS_CC1 | SWITCHES0_MEAS_CC2 | -+ SWITCHES0_PU_EN1 | SWITCHES0_PU_EN2 | -+ SWITCHES0_PDWN1 | SWITCHES0_PDWN2, -+ SWITCHES0_PDWN1 | SWITCHES0_PDWN2 | -+ SWITCHES0_MEAS_CC2); -+ usleep_range(250, 300); -+ -+ regmap_read(chip->regmap, FUSB_REG_STATUS0, &val); -+ val &= STATUS0_BC_LVL; -+ *CC2 = val ? TYPEC_CC_VOLT_RP : TYPEC_CC_VOLT_OPEN; -+ -+ regmap_update_bits(chip->regmap, FUSB_REG_SWITCHES0, -+ SWITCHES0_MEAS_CC1 | SWITCHES0_MEAS_CC2, -+ store); -+ } else { -+ regmap_read(chip->regmap, FUSB_REG_SWITCHES0, &store); -+ val = store; -+ val &= ~(SWITCHES0_MEAS_CC1 | SWITCHES0_MEAS_CC2 | -+ SWITCHES0_PU_EN1 | SWITCHES0_PU_EN2); -+ if (chip->cc_state & CC_STATE_TOGSS_CC1) { -+ val |= SWITCHES0_MEAS_CC1 | SWITCHES0_PU_EN1; -+ } else { -+ val |= SWITCHES0_MEAS_CC2 | SWITCHES0_PU_EN2; -+ } -+ regmap_write(chip->regmap, FUSB_REG_SWITCHES0, val); -+ -+ regmap_write(chip->regmap, FUSB_REG_MEASURE, chip->cc_meas_high); -+ usleep_range(250, 300); -+ -+ regmap_read(chip->regmap, FUSB_REG_STATUS0, &val); -+ if (val & STATUS0_COMP) { -+ int retry = 3; -+ int comp_times = 0; -+ -+ while (retry--) { -+ regmap_write(chip->regmap, FUSB_REG_MEASURE, chip->cc_meas_high); -+ usleep_range(250, 300); -+ regmap_read(chip->regmap, FUSB_REG_STATUS0, &val); -+ if (val & STATUS0_COMP) { -+ comp_times++; -+ if (comp_times == 3) { -+ *CC_MEASURE = TYPEC_CC_VOLT_OPEN; -+ regmap_write(chip->regmap, FUSB_REG_SWITCHES0, store); -+ } -+ } -+ } -+ } else { -+ regmap_write(chip->regmap, FUSB_REG_MEASURE, chip->cc_meas_low); -+ regmap_read(chip->regmap, FUSB_REG_MEASURE, &val); -+ usleep_range(250, 300); -+ -+ regmap_read(chip->regmap, FUSB_REG_STATUS0, &val); -+ -+ if (val & STATUS0_COMP) -+ *CC_MEASURE = TYPEC_CC_VOLT_RD; -+ else -+ *CC_MEASURE = TYPEC_CC_VOLT_RA; -+ } -+ regmap_write(chip->regmap, FUSB_REG_SWITCHES0, store); -+ regmap_write(chip->regmap, FUSB_REG_MEASURE, -+ chip->cc_meas_high); -+ } -+ -+ return 0; -+} -+ -+static void tcpm_set_cc_pull_mode(struct fusb30x_chip *chip, enum CC_MODE mode) -+{ -+ u8 val; -+ -+ switch (mode) { -+ case CC_PULL_UP: -+ if (chip->cc_polarity == TYPEC_POLARITY_CC1) -+ val = SWITCHES0_PU_EN1; -+ else -+ val = SWITCHES0_PU_EN2; -+ break; -+ case CC_PULL_DOWN: -+ val = SWITCHES0_PDWN1 | SWITCHES0_PDWN2; -+ break; -+ default: -+ val = 0; -+ break; -+ } -+ -+ regmap_update_bits(chip->regmap, FUSB_REG_SWITCHES0, -+ SWITCHES0_PU_EN1 | SWITCHES0_PU_EN2 | -+ SWITCHES0_PDWN1 | SWITCHES0_PDWN2, -+ val); -+ -+ if (chip->cc_meas_high && mode == CC_PULL_UP) -+ regmap_write(chip->regmap, FUSB_REG_MEASURE, -+ chip->cc_meas_high); -+} -+ -+static int tcpm_set_cc(struct fusb30x_chip *chip, enum role_mode mode) -+{ -+ switch (mode) { -+ case ROLE_MODE_DFP: -+ tcpm_set_cc_pull_mode(chip, CC_PULL_UP); -+ regmap_update_bits(chip->regmap, FUSB_REG_CONTROL2, -+ CONTROL2_MODE | CONTROL2_TOG_RD_ONLY, -+ CONTROL2_MODE_DFP | CONTROL2_TOG_RD_ONLY); -+ break; -+ case ROLE_MODE_UFP: -+ tcpm_set_cc_pull_mode(chip, CC_PULL_UP); -+ regmap_update_bits(chip->regmap, FUSB_REG_CONTROL2, -+ CONTROL2_MODE | CONTROL2_TOG_RD_ONLY, -+ CONTROL2_MODE_UFP); -+ break; -+ case ROLE_MODE_DRP: -+ tcpm_set_cc_pull_mode(chip, CC_PULL_NONE); -+ regmap_update_bits(chip->regmap, FUSB_REG_CONTROL2, -+ CONTROL2_MODE | CONTROL2_TOG_RD_ONLY, -+ CONTROL2_MODE_DRP | CONTROL2_TOG_RD_ONLY); -+ break; -+ default: -+ dev_err(chip->dev, "%s: Unsupport cc mode %d\n", -+ __func__, mode); -+ return -EINVAL; -+ break; -+ } -+ -+ regmap_update_bits(chip->regmap, FUSB_REG_CONTROL2, CONTROL2_TOGGLE, -+ CONTROL2_TOGGLE); -+ -+ return 0; -+} -+ -+static int tcpm_set_rx_enable(struct fusb30x_chip *chip, int enable) -+{ -+ u8 val = 0; -+ -+ if (enable) { -+ if (chip->cc_polarity == TYPEC_POLARITY_CC1) -+ val |= SWITCHES0_MEAS_CC1; -+ else -+ val |= SWITCHES0_MEAS_CC2; -+ regmap_update_bits(chip->regmap, FUSB_REG_SWITCHES0, -+ SWITCHES0_MEAS_CC1 | SWITCHES0_MEAS_CC2, -+ val); -+ fusb302_flush_rx_fifo(chip); -+ regmap_update_bits(chip->regmap, FUSB_REG_SWITCHES1, -+ SWITCHES1_AUTO_CRC, SWITCHES1_AUTO_CRC); -+ } else { -+ regmap_update_bits(chip->regmap, FUSB_REG_SWITCHES0, -+ SWITCHES0_MEAS_CC1 | SWITCHES0_MEAS_CC2, -+ 0); -+ regmap_update_bits(chip->regmap, -+ FUSB_REG_SWITCHES1, SWITCHES1_AUTO_CRC, 0); -+ } -+ -+ return 0; -+} -+ -+static int tcpm_set_msg_header(struct fusb30x_chip *chip) -+{ -+ regmap_update_bits(chip->regmap, FUSB_REG_SWITCHES1, -+ SWITCHES1_POWERROLE | SWITCHES1_DATAROLE, -+ (chip->notify.power_role << 7) | -+ (chip->notify.data_role << 4)); -+ regmap_update_bits(chip->regmap, FUSB_REG_SWITCHES1, -+ SWITCHES1_SPECREV, 2 << 5); -+ return 0; -+} -+ -+static int tcpm_set_polarity(struct fusb30x_chip *chip, -+ enum typec_cc_polarity polarity) -+{ -+ u8 val = 0; -+ -+ if (chip->vconn_enabled) { -+ if (polarity) -+ val |= SWITCHES0_VCONN_CC1; -+ else -+ val |= SWITCHES0_VCONN_CC2; -+ } -+ -+ if (chip->cc_state & CC_STATE_TOGSS_IS_UFP) { -+ if (polarity == TYPEC_POLARITY_CC1) -+ val |= SWITCHES0_MEAS_CC1; -+ else -+ val |= SWITCHES0_MEAS_CC2; -+ } else { -+ if (polarity == TYPEC_POLARITY_CC1) -+ val |= SWITCHES0_MEAS_CC1 | SWITCHES0_PU_EN1; -+ else -+ val |= SWITCHES0_MEAS_CC2 | SWITCHES0_PU_EN2; -+ } -+ -+ regmap_update_bits(chip->regmap, FUSB_REG_SWITCHES0, -+ SWITCHES0_VCONN_CC1 | SWITCHES0_VCONN_CC2 | -+ SWITCHES0_MEAS_CC1 | SWITCHES0_MEAS_CC2 | -+ SWITCHES0_PU_EN1 | SWITCHES0_PU_EN2, -+ val); -+ -+ val = 0; -+ if (polarity == TYPEC_POLARITY_CC1) -+ val |= SWITCHES1_TXCC1; -+ else -+ val |= SWITCHES1_TXCC2; -+ regmap_update_bits(chip->regmap, FUSB_REG_SWITCHES1, -+ SWITCHES1_TXCC1 | SWITCHES1_TXCC2, -+ val); -+ -+ chip->cc_polarity = polarity; -+ -+ return 0; -+} -+ -+static int tcpm_set_vconn(struct fusb30x_chip *chip, int enable) -+{ -+ u8 val = 0; -+ -+ if (enable) { -+ if (chip->cc_polarity == TYPEC_POLARITY_CC1) -+ val = SWITCHES0_VCONN_CC2; -+ else -+ val = SWITCHES0_VCONN_CC1; -+ } -+ regmap_update_bits(chip->regmap, FUSB_REG_SWITCHES0, -+ SWITCHES0_VCONN_CC1 | SWITCHES0_VCONN_CC2, -+ val); -+ chip->vconn_enabled = (bool)enable; -+ return 0; -+} -+ -+static void fusb302_pd_reset(struct fusb30x_chip *chip) -+{ -+ regmap_write(chip->regmap, FUSB_REG_RESET, RESET_PD_RESET); -+ regmap_reinit_cache(chip->regmap, &fusb302_regmap_config); -+} -+ -+static void tcpm_select_rp_value(struct fusb30x_chip *chip, u32 rp) -+{ -+ u32 control0_reg; -+ -+ regmap_read(chip->regmap, FUSB_REG_CONTROL0, &control0_reg); -+ -+ control0_reg &= ~CONTROL0_HOST_CUR; -+ /* -+ * according to the host current, the compare value is different -+ * Fusb302 datasheet Table 3 -+ */ -+ switch (rp) { -+ /* -+ * host pull up current is 80ua , high voltage is 1.596v, -+ * low is 0.21v -+ */ -+ case TYPEC_RP_USB: -+ chip->cc_meas_high = 0x26; -+ chip->cc_meas_low = 0x5; -+ control0_reg |= CONTROL0_HOST_CUR_USB; -+ break; -+ /* -+ * host pull up current is 330ua , high voltage is 2.604v, -+ * low is 0.798v -+ */ -+ case TYPEC_RP_3A0: -+ chip->cc_meas_high = 0x3e; -+ chip->cc_meas_low = 0x13; -+ control0_reg |= CONTROL0_HOST_CUR_3A0; -+ break; -+ /* -+ * host pull up current is 180ua , high voltage is 1.596v, -+ * low is 0.42v -+ */ -+ case TYPEC_RP_1A5: -+ default: -+ chip->cc_meas_high = 0x26; -+ chip->cc_meas_low = 0xa; -+ control0_reg |= CONTROL0_HOST_CUR_1A5; -+ break; -+ } -+ -+ regmap_write(chip->regmap, FUSB_REG_CONTROL0, control0_reg); -+} -+ -+static int tcpm_check_vbus(struct fusb30x_chip *chip) -+{ -+ u32 val; -+ -+ /* Read status register */ -+ regmap_read(chip->regmap, FUSB_REG_STATUS0, &val); -+ -+ return (val & STATUS0_VBUSOK) ? 1 : 0; -+} -+ -+static void tcpm_init(struct fusb30x_chip *chip) -+{ -+ u8 val; -+ u32 tmp; -+ -+ regmap_read(chip->regmap, FUSB_REG_DEVICEID, &tmp); -+ chip->chip_id = (u8)tmp; -+ platform_set_vbus_lvl_enable(chip, 0, 0); -+ chip->notify.is_cc_connected = false; -+ chip->cc_state = 0; -+ -+ /* restore default settings */ -+ regmap_update_bits(chip->regmap, FUSB_REG_RESET, RESET_SW_RESET, -+ RESET_SW_RESET); -+ fusb302_pd_reset(chip); -+ /* set auto_retry and number of retries */ -+ regmap_update_bits(chip->regmap, FUSB_REG_CONTROL3, -+ CONTROL3_AUTO_RETRY | CONTROL3_N_RETRIES, -+ CONTROL3_AUTO_RETRY | CONTROL3_N_RETRIES), -+ -+ /* set interrupts */ -+ val = 0xff; -+ val &= ~(MASK_M_COLLISION | MASK_M_ALERT | MASK_M_VBUSOK); -+ regmap_write(chip->regmap, FUSB_REG_MASK, val); -+ -+ val = 0xff; -+ val &= ~(MASKA_M_RETRYFAIL | MASKA_M_HARDSENT | MASKA_M_TXSENT | -+ MASKA_M_HARDRST | MASKA_M_TOGDONE); -+ regmap_write(chip->regmap, FUSB_REG_MASKA, val); -+ -+ val = ~MASKB_M_GCRCSEND; -+ regmap_write(chip->regmap, FUSB_REG_MASKB, val); -+ -+ tcpm_select_rp_value(chip, TYPEC_RP_1A5); -+ /* Interrupts Enable */ -+ regmap_update_bits(chip->regmap, FUSB_REG_CONTROL0, CONTROL0_INT_MASK, -+ ~CONTROL0_INT_MASK); -+ -+ tcpm_set_vconn(chip, 0); -+ -+ regmap_write(chip->regmap, FUSB_REG_POWER, 0xf); -+} -+ -+static void pd_execute_hard_reset(struct fusb30x_chip *chip) -+{ -+ chip->msg_id = 0; -+ chip->vdm_state = VDM_STATE_DISCOVERY_ID; -+ if (chip->notify.power_role) -+ set_state(chip, policy_src_transition_default); -+ else -+ set_state(chip, policy_snk_transition_default); -+} -+ -+static void tcpc_alert(struct fusb30x_chip *chip, u32 *evt) -+{ -+ int interrupt, interrupta, interruptb; -+ u32 val; -+ static int retry; -+ -+ regmap_read(chip->regmap, FUSB_REG_INTERRUPT, &interrupt); -+ regmap_read(chip->regmap, FUSB_REG_INTERRUPTA, &interrupta); -+ regmap_read(chip->regmap, FUSB_REG_INTERRUPTB, &interruptb); -+ -+ if ((interrupt & INTERRUPT_COMP_CHNG) && -+ (!(chip->cc_state & CC_STATE_TOGSS_IS_UFP))) { -+ regmap_read(chip->regmap, FUSB_REG_STATUS0, &val); -+ if (val & STATUS0_COMP) -+ *evt |= EVENT_CC; -+ } -+ -+ if (interrupt & INTERRUPT_VBUSOK) { -+ if (chip->notify.is_cc_connected) -+ *evt |= EVENT_CC; -+ } -+ -+ if (interrupta & INTERRUPTA_TOGDONE) { -+ *evt |= EVENT_CC; -+ regmap_read(chip->regmap, FUSB_REG_STATUS1A, &val); -+ chip->cc_state = ((u8)val >> 3) & 0x07; -+ -+ regmap_update_bits(chip->regmap, FUSB_REG_CONTROL2, -+ CONTROL2_TOGGLE, -+ 0); -+ } -+ -+ if (interrupta & INTERRUPTA_TXSENT) { -+ *evt |= EVENT_TX; -+ chip->tx_state = tx_success; -+ } -+ -+ if (interruptb & INTERRUPTB_GCRCSENT) -+ *evt |= EVENT_RX; -+ -+ if (interrupta & INTERRUPTA_HARDRST) { -+ fusb302_pd_reset(chip); -+ pd_execute_hard_reset(chip); -+ *evt |= EVENT_REC_RESET; -+ } -+ -+ if (interrupta & INTERRUPTA_RETRYFAIL) { -+ *evt |= EVENT_TX; -+ chip->tx_state = tx_failed; -+ } -+ -+ if (interrupta & INTERRUPTA_HARDSENT) { -+ /* -+ * The fusb PD should be reset once to sync adapter PD -+ * signal after fusb sent hard reset cmd.This is not PD -+ * device if reset failed. -+ */ -+ if (!retry) { -+ retry = 1; -+ fusb302_pd_reset(chip); -+ pd_execute_hard_reset(chip); -+ } else { -+ retry = 0; -+ chip->tx_state = tx_success; -+ chip->timer_state = T_DISABLED; -+ *evt |= EVENT_TX; -+ } -+ } -+} -+ -+static void mux_alert(struct fusb30x_chip *chip, u32 *evt) -+{ -+ if (!chip->timer_mux) { -+ *evt |= EVENT_TIMER_MUX; -+ chip->timer_mux = T_DISABLED; -+ } -+ -+ if (!chip->timer_state) { -+ *evt |= EVENT_TIMER_STATE; -+ chip->timer_state = T_DISABLED; -+ } -+ -+ if (chip->work_continue) { -+ *evt |= chip->work_continue; -+ chip->work_continue = 0; -+ } -+} -+ -+static void set_state_unattached(struct fusb30x_chip *chip) -+{ -+ dev_info(chip->dev, "connection has disconnected\n"); -+ tcpm_init(chip); -+ tcpm_set_rx_enable(chip, 0); -+ set_state(chip, unattached); -+ tcpm_set_cc(chip, chip->role); -+ -+ /* claer notify_info */ -+ memset(&chip->notify, 0, sizeof(struct notify_info)); -+ platform_fusb_notify(chip); -+ -+ if (chip->gpio_discharge) -+ gpiod_set_value(chip->gpio_discharge, 1); -+ msleep(100); -+ if (chip->gpio_discharge) -+ gpiod_set_value(chip->gpio_discharge, 0); -+ -+ regmap_update_bits(chip->regmap, FUSB_REG_MASK, -+ MASK_M_COMP_CHNG, MASK_M_COMP_CHNG); -+ chip->try_role_complete = false; -+} -+ -+static void set_mesg(struct fusb30x_chip *chip, int cmd, int is_DMT) -+{ -+ int i; -+ struct PD_CAP_INFO *pd_cap_info = &chip->pd_cap_info; -+ -+ chip->send_head = ((chip->msg_id & 0x7) << 9) | -+ ((chip->notify.power_role & 0x1) << 8) | -+ (1 << 6) | -+ ((chip->notify.data_role & 0x1) << 5); -+ -+ if (is_DMT) { -+ switch (cmd) { -+ case DMT_SOURCECAPABILITIES: -+ chip->send_head |= ((chip->n_caps_used & 0x3) << 12) | (cmd & 0xf); -+ -+ for (i = 0; i < chip->n_caps_used; i++) { -+ chip->send_load[i] = (pd_cap_info->supply_type << 30) | -+ (pd_cap_info->dual_role_power << 29) | -+ (pd_cap_info->usb_suspend_support << 28) | -+ (pd_cap_info->externally_powered << 27) | -+ (pd_cap_info->usb_communications_cap << 26) | -+ (pd_cap_info->data_role_swap << 25) | -+ (pd_cap_info->peak_current << 20) | -+ (chip->source_power_supply[i] << 10) | -+ (chip->source_max_current[i]); -+ } -+ break; -+ case DMT_REQUEST: -+ chip->send_head |= ((1 << 12) | (cmd & 0xf)); -+ /* send request with FVRDO */ -+ chip->send_load[0] = (chip->pos_power << 28) | -+ (0 << 27) | -+ (1 << 26) | -+ (0 << 25) | -+ (0 << 24); -+ -+ switch (CAP_POWER_TYPE(chip->rec_load[chip->pos_power - 1])) { -+ case 0: -+ /* Fixed Supply */ -+ chip->send_load[0] |= ((CAP_FPDO_VOLTAGE(chip->rec_load[chip->pos_power - 1]) << 10) & 0x3ff); -+ chip->send_load[0] |= (CAP_FPDO_CURRENT(chip->rec_load[chip->pos_power - 1]) & 0x3ff); -+ break; -+ case 1: -+ /* Battery */ -+ chip->send_load[0] |= ((CAP_VPDO_VOLTAGE(chip->rec_load[chip->pos_power - 1]) << 10) & 0x3ff); -+ chip->send_load[0] |= (CAP_VPDO_CURRENT(chip->rec_load[chip->pos_power - 1]) & 0x3ff); -+ break; -+ default: -+ /* not meet battery caps */ -+ break; -+ } -+ break; -+ case DMT_SINKCAPABILITIES: -+ break; -+ case DMT_VENDERDEFINED: -+ break; -+ default: -+ break; -+ } -+ } else { -+ chip->send_head |= (cmd & 0xf); -+ } -+} -+ -+/* -+ * This algorithm defaults to choosing higher pin config over lower ones in -+ * order to prefer multi-function if desired. -+ * -+ * NAME | SIGNALING | OUTPUT TYPE | MULTI-FUNCTION | PIN CONFIG -+ * ------------------------------------------------------------- -+ * A | USB G2 | ? | no | 00_0001 -+ * B | USB G2 | ? | yes | 00_0010 -+ * C | DP | CONVERTED | no | 00_0100 -+ * D | PD | CONVERTED | yes | 00_1000 -+ * E | DP | DP | no | 01_0000 -+ * F | PD | DP | yes | 10_0000 -+ * -+ * if UFP has NOT asserted multi-function preferred code masks away B/D/F -+ * leaving only A/C/E. For single-output dongles that should leave only one -+ * possible pin config depending on whether its a converter DP->(VGA|HDMI) or DP -+ * output. If UFP is a USB-C receptacle it may assert C/D/E/F. The DFP USB-C -+ * receptacle must always choose C/D in those cases. -+ */ -+static int pd_dfp_dp_get_pin_assignment(struct fusb30x_chip *chip, -+ uint32_t caps, uint32_t status) -+{ -+ uint32_t pin_caps; -+ -+ /* revisit with DFP that can be a sink */ -+ pin_caps = PD_DP_PIN_CAPS(caps); -+ -+ /* if don't want multi-function then ignore those pin configs */ -+ if (!PD_VDO_DPSTS_MF_PREF(status)) -+ pin_caps &= ~MODE_DP_PIN_MF_MASK; -+ -+ /* revisit if DFP drives USB Gen 2 signals */ -+ if (PD_DP_SIGNAL_GEN2(caps)) -+ pin_caps &= ~MODE_DP_PIN_DP_MASK; -+ else -+ pin_caps &= ~MODE_DP_PIN_BR2_MASK; -+ -+ /* if C/D present they have precedence over E/F for USB-C->USB-C */ -+ if (pin_caps & (MODE_DP_PIN_C | MODE_DP_PIN_D)) -+ pin_caps &= ~(MODE_DP_PIN_E | MODE_DP_PIN_F); -+ -+ /* returns undefined for zero */ -+ if (!pin_caps) -+ return 0; -+ -+ /* choosing higher pin config over lower ones */ -+ return 1 << (31 - __builtin_clz(pin_caps)); -+} -+ -+static void set_vdm_mesg(struct fusb30x_chip *chip, int cmd, int type, int mode) -+{ -+ chip->send_head = (chip->msg_id & 0x7) << 9; -+ chip->send_head |= (chip->notify.power_role & 0x1) << 8; -+ -+ chip->send_head = ((chip->msg_id & 0x7) << 9) | -+ ((chip->notify.power_role & 0x1) << 8) | -+ (1 << 6) | -+ ((chip->notify.data_role & 0x1) << 5) | -+ (DMT_VENDERDEFINED & 0xf); -+ -+ chip->send_load[0] = (1 << 15) | -+ (0 << 13) | -+ (type << 6) | -+ (cmd); -+ -+ switch (cmd) { -+ case VDM_DISCOVERY_ID: -+ case VDM_DISCOVERY_SVIDS: -+ case VDM_ATTENTION: -+ chip->send_load[0] |= (0xff00 << 16); -+ chip->send_head |= (1 << 12); -+ break; -+ case VDM_DISCOVERY_MODES: -+ chip->send_load[0] |= -+ (chip->vdm_svid[chip->val_tmp >> 1] << 16); -+ chip->send_head |= (1 << 12); -+ break; -+ case VDM_ENTER_MODE: -+ chip->send_head |= (1 << 12); -+ chip->send_load[0] |= (mode << 8) | (0xff01 << 16); -+ break; -+ case VDM_EXIT_MODE: -+ chip->send_head |= (1 << 12); -+ chip->send_load[0] |= (0x0f << 8) | (0xff01 << 16); -+ break; -+ case VDM_DP_STATUS_UPDATE: -+ chip->send_head |= (2 << 12); -+ chip->send_load[0] |= (1 << 8) | (0xff01 << 16); -+ chip->send_load[1] = 5; -+ break; -+ case VDM_DP_CONFIG: -+ chip->send_head |= (2 << 12); -+ chip->send_load[0] |= (1 << 8) | (0xff01 << 16); -+ -+ chip->notify.pin_assignment_def = -+ pd_dfp_dp_get_pin_assignment(chip, chip->notify.dp_caps, -+ chip->notify.dp_status); -+ -+ chip->send_load[1] = (chip->notify.pin_assignment_def << 8) | -+ (1 << 2) | 2; -+ dev_dbg(chip->dev, "DisplayPort Configurations: 0x%08x\n", -+ chip->send_load[1]); -+ break; -+ default: -+ break; -+ } -+} -+ -+static enum tx_state policy_send_hardrst(struct fusb30x_chip *chip, u32 evt) -+{ -+ switch (chip->tx_state) { -+ case 0: -+ regmap_update_bits(chip->regmap, FUSB_REG_CONTROL3, -+ CONTROL3_SEND_HARDRESET, -+ CONTROL3_SEND_HARDRESET); -+ chip->tx_state = tx_busy; -+ chip->timer_state = T_BMC_TIMEOUT; -+ fusb_timer_start(&chip->timer_state_machine, -+ chip->timer_state); -+ break; -+ default: -+ if (evt & EVENT_TIMER_STATE) -+ chip->tx_state = tx_success; -+ break; -+ } -+ return chip->tx_state; -+} -+ -+static enum tx_state policy_send_data(struct fusb30x_chip *chip) -+{ -+ u8 senddata[40]; -+ int pos = 0; -+ u8 len; -+ -+ switch (chip->tx_state) { -+ case 0: -+ senddata[pos++] = FUSB_TKN_SYNC1; -+ senddata[pos++] = FUSB_TKN_SYNC1; -+ senddata[pos++] = FUSB_TKN_SYNC1; -+ senddata[pos++] = FUSB_TKN_SYNC2; -+ -+ len = PD_HEADER_CNT(chip->send_head) << 2; -+ senddata[pos++] = FUSB_TKN_PACKSYM | ((len + 2) & 0x1f); -+ -+ senddata[pos++] = chip->send_head & 0xff; -+ senddata[pos++] = (chip->send_head >> 8) & 0xff; -+ -+ memcpy(&senddata[pos], chip->send_load, len); -+ pos += len; -+ -+ senddata[pos++] = FUSB_TKN_JAMCRC; -+ senddata[pos++] = FUSB_TKN_EOP; -+ senddata[pos++] = FUSB_TKN_TXOFF; -+ senddata[pos++] = FUSB_TKN_TXON; -+ -+ regmap_raw_write(chip->regmap, FUSB_REG_FIFO, senddata, pos); -+ chip->tx_state = tx_busy; -+ break; -+ -+ default: -+ /* wait Tx result */ -+ break; -+ } -+ -+ return chip->tx_state; -+} -+ -+static void process_vdm_msg(struct fusb30x_chip *chip) -+{ -+ u32 vdm_header = chip->rec_load[0]; -+ int i; -+ u32 tmp; -+ -+ /* can't procee unstructed vdm msg */ -+ if (!GET_VDMHEAD_STRUCT_TYPE(vdm_header)) { -+ dev_warn(chip->dev, "unknown unstructed vdm message\n"); -+ return; -+ } -+ -+ switch (GET_VDMHEAD_CMD_TYPE(vdm_header)) { -+ case VDM_TYPE_INIT: -+ switch (GET_VDMHEAD_CMD(vdm_header)) { -+ case VDM_ATTENTION: -+ chip->notify.dp_status = GET_DP_STATUS(chip->rec_load[1]); -+ dev_info(chip->dev, "attention, dp_status %x\n", -+ chip->rec_load[1]); -+ chip->notify.attention = true; -+ platform_fusb_notify(chip); -+ break; -+ default: -+ dev_warn(chip->dev, "rec unknown init vdm msg\n"); -+ break; -+ } -+ break; -+ case VDM_TYPE_ACK: -+ switch (GET_VDMHEAD_CMD(vdm_header)) { -+ case VDM_DISCOVERY_ID: -+ chip->vdm_id = chip->rec_load[1]; -+ break; -+ case VDM_DISCOVERY_SVIDS: -+ for (i = 0; i < 6; i++) { -+ tmp = (chip->rec_load[i + 1] >> 16) & -+ 0x0000ffff; -+ if (tmp) { -+ chip->vdm_svid[i * 2] = tmp; -+ chip->vdm_svid_num++; -+ } else { -+ break; -+ } -+ -+ tmp = (chip->rec_load[i + 1] & 0x0000ffff); -+ if (tmp) { -+ chip->vdm_svid[i * 2 + 1] = tmp; -+ chip->vdm_svid_num++; -+ } else { -+ break; -+ } -+ } -+ break; -+ case VDM_DISCOVERY_MODES: -+ /* indicate there are some vdo modes */ -+ if (PD_HEADER_CNT(chip->rec_head) > 1) { -+ /* -+ * store mode config, -+ * enter first mode default -+ */ -+ tmp = chip->rec_load[1]; -+ -+ if ((!((tmp >> 8) & 0x3f)) && -+ (!((tmp >> 16) & 0x3f))) { -+ chip->val_tmp |= 1; -+ break; -+ } -+ chip->notify.dp_caps = chip->rec_load[1]; -+ chip->notify.pin_assignment_def = 0; -+ chip->notify.pin_assignment_support = -+ PD_DP_PIN_CAPS(tmp); -+ chip->val_tmp |= 1; -+ dev_dbg(chip->dev, -+ "DisplayPort Capabilities: 0x%08x\n", -+ chip->rec_load[1]); -+ } -+ break; -+ case VDM_ENTER_MODE: -+ chip->val_tmp = 1; -+ break; -+ case VDM_DP_STATUS_UPDATE: -+ chip->notify.dp_status = GET_DP_STATUS(chip->rec_load[1]); -+ dev_dbg(chip->dev, "DisplayPort Status: 0x%08x\n", -+ chip->rec_load[1]); -+ chip->val_tmp = 1; -+ break; -+ case VDM_DP_CONFIG: -+ chip->val_tmp = 1; -+ dev_info(chip->dev, -+ "DP config successful, pin_assignment 0x%x\n", -+ chip->notify.pin_assignment_def); -+ chip->notify.is_enter_mode = true; -+ break; -+ default: -+ break; -+ } -+ break; -+ case VDM_TYPE_NACK: -+ dev_warn(chip->dev, "REC NACK for 0x%x\n", -+ GET_VDMHEAD_CMD(vdm_header)); -+ /* disable vdm */ -+ chip->vdm_state = VDM_STATE_ERR; -+ break; -+ } -+} -+ -+static int vdm_send_discoveryid(struct fusb30x_chip *chip, u32 evt) -+{ -+ int tmp; -+ -+ switch (chip->vdm_send_state) { -+ case 0: -+ set_vdm_mesg(chip, VDM_DISCOVERY_ID, VDM_TYPE_INIT, 0); -+ chip->vdm_id = 0; -+ chip->tx_state = 0; -+ chip->vdm_send_state++; -+ case 1: -+ tmp = policy_send_data(chip); -+ if (tmp == tx_success) { -+ chip->vdm_send_state++; -+ chip->timer_state = T_SENDER_RESPONSE; -+ fusb_timer_start(&chip->timer_state_machine, -+ chip->timer_state); -+ } else if (tmp == tx_failed) { -+ dev_warn(chip->dev, "VDM_DISCOVERY_ID send failed\n"); -+ /* disable auto_vdm_machine */ -+ chip->vdm_state = VDM_STATE_ERR; -+ return -EPIPE; -+ } -+ -+ if (chip->vdm_send_state != 2) -+ break; -+ default: -+ if (chip->vdm_id) { -+ chip->vdm_send_state = 0; -+ return 0; -+ } else if (evt & EVENT_TIMER_STATE) { -+ dev_warn(chip->dev, "VDM_DISCOVERY_ID time out\n"); -+ chip->vdm_state = VDM_STATE_ERR; -+ chip->work_continue |= EVENT_WORK_CONTINUE; -+ return -ETIMEDOUT; -+ } -+ break; -+ } -+ return -EINPROGRESS; -+} -+ -+static int vdm_send_discoverysvid(struct fusb30x_chip *chip, u32 evt) -+{ -+ int tmp; -+ -+ switch (chip->vdm_send_state) { -+ case 0: -+ set_vdm_mesg(chip, VDM_DISCOVERY_SVIDS, VDM_TYPE_INIT, 0); -+ memset(chip->vdm_svid, 0, sizeof(chip->vdm_svid)); -+ chip->vdm_svid_num = 0; -+ chip->tx_state = 0; -+ chip->vdm_send_state++; -+ case 1: -+ tmp = policy_send_data(chip); -+ if (tmp == tx_success) { -+ chip->vdm_send_state++; -+ chip->timer_state = T_SENDER_RESPONSE; -+ fusb_timer_start(&chip->timer_state_machine, -+ chip->timer_state); -+ } else if (tmp == tx_failed) { -+ dev_warn(chip->dev, "VDM_DISCOVERY_SVIDS send failed\n"); -+ /* disable auto_vdm_machine */ -+ chip->vdm_state = VDM_STATE_ERR; -+ return -EPIPE; -+ } -+ -+ if (chip->vdm_send_state != 2) -+ break; -+ default: -+ if (chip->vdm_svid_num) { -+ chip->vdm_send_state = 0; -+ return 0; -+ } else if (evt & EVENT_TIMER_STATE) { -+ dev_warn(chip->dev, "VDM_DISCOVERY_SVIDS time out\n"); -+ chip->vdm_state = VDM_STATE_ERR; -+ chip->work_continue |= EVENT_WORK_CONTINUE; -+ return -ETIMEDOUT; -+ } -+ break; -+ } -+ return -EINPROGRESS; -+} -+ -+static int vdm_send_discoverymodes(struct fusb30x_chip *chip, u32 evt) -+{ -+ int tmp; -+ -+ if ((chip->val_tmp >> 1) != chip->vdm_svid_num) { -+ switch (chip->vdm_send_state) { -+ case 0: -+ set_vdm_mesg(chip, VDM_DISCOVERY_MODES, -+ VDM_TYPE_INIT, 0); -+ chip->tx_state = 0; -+ chip->vdm_send_state++; -+ case 1: -+ tmp = policy_send_data(chip); -+ if (tmp == tx_success) { -+ chip->vdm_send_state++; -+ chip->timer_state = T_SENDER_RESPONSE; -+ fusb_timer_start(&chip->timer_state_machine, -+ chip->timer_state); -+ } else if (tmp == tx_failed) { -+ dev_warn(chip->dev, -+ "VDM_DISCOVERY_MODES send failed\n"); -+ chip->vdm_state = VDM_STATE_ERR; -+ return -EPIPE; -+ } -+ -+ if (chip->vdm_send_state != 2) -+ break; -+ default: -+ if (chip->val_tmp & 1) { -+ chip->val_tmp &= 0xfe; -+ chip->val_tmp += 2; -+ chip->vdm_send_state = 0; -+ chip->work_continue |= EVENT_WORK_CONTINUE; -+ } else if (evt & EVENT_TIMER_STATE) { -+ dev_warn(chip->dev, -+ "VDM_DISCOVERY_MODES time out\n"); -+ chip->vdm_state = VDM_STATE_ERR; -+ chip->work_continue |= EVENT_WORK_CONTINUE; -+ return -ETIMEDOUT; -+ } -+ break; -+ } -+ } else { -+ chip->val_tmp = 0; -+ return 0; -+ } -+ -+ return -EINPROGRESS; -+} -+ -+static int vdm_send_entermode(struct fusb30x_chip *chip, u32 evt) -+{ -+ int tmp; -+ -+ switch (chip->vdm_send_state) { -+ case 0: -+ set_vdm_mesg(chip, VDM_ENTER_MODE, VDM_TYPE_INIT, 1); -+ chip->tx_state = 0; -+ chip->vdm_send_state++; -+ chip->notify.is_enter_mode = false; -+ case 1: -+ tmp = policy_send_data(chip); -+ if (tmp == tx_success) { -+ chip->vdm_send_state++; -+ chip->timer_state = T_SENDER_RESPONSE; -+ fusb_timer_start(&chip->timer_state_machine, -+ chip->timer_state); -+ } else if (tmp == tx_failed) { -+ dev_warn(chip->dev, "VDM_ENTER_MODE send failed\n"); -+ /* disable auto_vdm_machine */ -+ chip->vdm_state = VDM_STATE_ERR; -+ return -EPIPE; -+ } -+ -+ if (chip->vdm_send_state != 2) -+ break; -+ default: -+ if (chip->val_tmp) { -+ chip->val_tmp = 0; -+ chip->vdm_send_state = 0; -+ return 0; -+ } else if (evt & EVENT_TIMER_STATE) { -+ dev_warn(chip->dev, "VDM_ENTER_MODE time out\n"); -+ chip->vdm_state = VDM_STATE_ERR; -+ chip->work_continue |= EVENT_WORK_CONTINUE; -+ return -ETIMEDOUT; -+ } -+ break; -+ } -+ return -EINPROGRESS; -+} -+ -+static int vdm_send_getdpstatus(struct fusb30x_chip *chip, u32 evt) -+{ -+ int tmp; -+ -+ switch (chip->vdm_send_state) { -+ case 0: -+ set_vdm_mesg(chip, VDM_DP_STATUS_UPDATE, VDM_TYPE_INIT, 1); -+ chip->tx_state = 0; -+ chip->vdm_send_state++; -+ case 1: -+ tmp = policy_send_data(chip); -+ if (tmp == tx_success) { -+ chip->vdm_send_state++; -+ chip->timer_state = T_SENDER_RESPONSE; -+ fusb_timer_start(&chip->timer_state_machine, -+ chip->timer_state); -+ } else if (tmp == tx_failed) { -+ dev_warn(chip->dev, -+ "VDM_DP_STATUS_UPDATE send failed\n"); -+ /* disable auto_vdm_machine */ -+ chip->vdm_state = VDM_STATE_ERR; -+ return -EPIPE; -+ } -+ -+ if (chip->vdm_send_state != 2) -+ break; -+ default: -+ if (chip->val_tmp) { -+ chip->val_tmp = 0; -+ chip->vdm_send_state = 0; -+ return 0; -+ } else if (evt & EVENT_TIMER_STATE) { -+ dev_warn(chip->dev, "VDM_DP_STATUS_UPDATE time out\n"); -+ chip->vdm_state = VDM_STATE_ERR; -+ chip->work_continue |= EVENT_WORK_CONTINUE; -+ return -ETIMEDOUT; -+ } -+ break; -+ } -+ return -EINPROGRESS; -+} -+ -+static int vdm_send_dpconfig(struct fusb30x_chip *chip, u32 evt) -+{ -+ int tmp; -+ -+ switch (chip->vdm_send_state) { -+ case 0: -+ set_vdm_mesg(chip, VDM_DP_CONFIG, VDM_TYPE_INIT, 0); -+ chip->tx_state = 0; -+ chip->vdm_send_state++; -+ case 1: -+ tmp = policy_send_data(chip); -+ if (tmp == tx_success) { -+ chip->vdm_send_state++; -+ chip->timer_state = T_SENDER_RESPONSE; -+ fusb_timer_start(&chip->timer_state_machine, -+ chip->timer_state); -+ } else if (tmp == tx_failed) { -+ dev_warn(chip->dev, "vdm_send_dpconfig send failed\n"); -+ /* disable auto_vdm_machine */ -+ chip->vdm_state = VDM_STATE_ERR; -+ return -EPIPE; -+ } -+ -+ if (chip->vdm_send_state != 2) -+ break; -+ default: -+ if (chip->val_tmp) { -+ chip->val_tmp = 0; -+ chip->vdm_send_state = 0; -+ return 0; -+ } else if (evt & EVENT_TIMER_STATE) { -+ dev_warn(chip->dev, "vdm_send_dpconfig time out\n"); -+ chip->vdm_state = VDM_STATE_ERR; -+ chip->work_continue |= EVENT_WORK_CONTINUE; -+ return -ETIMEDOUT; -+ } -+ break; -+ } -+ return -EINPROGRESS; -+} -+ -+/* without break if success */ -+#define AUTO_VDM_HANDLE(func, chip, evt, conditions) \ -+do { \ -+ conditions = func(chip, evt); \ -+ if (!conditions) { \ -+ chip->vdm_state++; \ -+ chip->work_continue |= EVENT_WORK_CONTINUE; \ -+ } else { \ -+ if (conditions != -EINPROGRESS) \ -+ chip->vdm_state = VDM_STATE_ERR; \ -+ } \ -+} while (0) -+ -+static void auto_vdm_machine(struct fusb30x_chip *chip, u32 evt) -+{ -+ int conditions; -+ -+ switch (chip->vdm_state) { -+ case VDM_STATE_DISCOVERY_ID: -+ AUTO_VDM_HANDLE(vdm_send_discoveryid, chip, evt, conditions); -+ break; -+ case VDM_STATE_DISCOVERY_SVID: -+ AUTO_VDM_HANDLE(vdm_send_discoverysvid, chip, evt, conditions); -+ break; -+ case VDM_STATE_DISCOVERY_MODES: -+ AUTO_VDM_HANDLE(vdm_send_discoverymodes, chip, evt, conditions); -+ break; -+ case VDM_STATE_ENTER_MODE: -+ AUTO_VDM_HANDLE(vdm_send_entermode, chip, evt, conditions); -+ break; -+ case VDM_STATE_UPDATE_STATUS: -+ AUTO_VDM_HANDLE(vdm_send_getdpstatus, chip, evt, conditions); -+ break; -+ case VDM_STATE_DP_CONFIG: -+ AUTO_VDM_HANDLE(vdm_send_dpconfig, chip, evt, conditions); -+ break; -+ case VDM_STATE_NOTIFY: -+ platform_fusb_notify(chip); -+ chip->vdm_state = VDM_STATE_READY; -+ break; -+ default: -+ break; -+ } -+} -+ -+static void fusb_state_disabled(struct fusb30x_chip *chip, u32 evt) -+{ -+ /* Do nothing */ -+} -+ -+static void fusb_state_unattached(struct fusb30x_chip *chip, u32 evt) -+{ -+ chip->notify.is_cc_connected = false; -+ chip->is_pd_support = false; -+ -+ if ((evt & EVENT_CC) && chip->cc_state) { -+ if (chip->cc_state & CC_STATE_TOGSS_IS_UFP) -+ set_state(chip, attach_wait_sink); -+ else -+ set_state(chip, attach_wait_source); -+ -+ chip->vbus_begin = tcpm_check_vbus(chip); -+ -+ tcpm_set_polarity(chip, (chip->cc_state & CC_STATE_TOGSS_CC1) ? -+ TYPEC_POLARITY_CC1 : -+ TYPEC_POLARITY_CC2); -+ tcpm_get_cc(chip, &chip->cc1, &chip->cc2); -+ chip->debounce_cnt = 0; -+ chip->timer_mux = 2; -+ fusb_timer_start(&chip->timer_mux_machine, chip->timer_mux); -+ } -+} -+ -+static void fusb_state_try_attach_set(struct fusb30x_chip *chip, -+ enum role_mode mode) -+{ -+ if (mode == ROLE_MODE_NONE || mode == ROLE_MODE_DRP || -+ mode == ROLE_MODE_ASS) -+ return; -+ -+ tcpm_init(chip); -+ tcpm_set_cc(chip, (mode == ROLE_MODE_DFP) ? -+ ROLE_MODE_DFP : ROLE_MODE_UFP); -+ chip->timer_mux = T_PD_TRY_DRP; -+ fusb_timer_start(&chip->timer_mux_machine, chip->timer_mux); -+ set_state(chip, (mode == ROLE_MODE_DFP) ? -+ attach_try_src : attach_try_snk); -+} -+ -+static void fusb_state_attach_wait_sink(struct fusb30x_chip *chip, u32 evt) -+{ -+ int cc1, cc2; -+ -+ if (evt & EVENT_TIMER_MUX) { -+ if (tcpm_check_vbus(chip)) { -+ chip->timer_mux = T_DISABLED; -+ if (chip->role == ROLE_MODE_DRP && -+ chip->try_role == ROLE_MODE_DFP && -+ !chip->try_role_complete) { -+ fusb_state_try_attach_set(chip, ROLE_MODE_DFP); -+ return; -+ } else if (chip->try_role_complete) { -+ chip->timer_mux = T_PD_SOURCE_ON; -+ fusb_timer_start(&chip->timer_mux_machine, -+ chip->timer_mux); -+ set_state(chip, attached_sink); -+ return; -+ } -+ } -+ -+ tcpm_get_cc(chip, &cc1, &cc2); -+ -+ if ((chip->cc1 == cc1) && (chip->cc2 == cc2)) { -+ chip->debounce_cnt++; -+ } else { -+ chip->cc1 = cc1; -+ chip->cc2 = cc2; -+ chip->debounce_cnt = 0; -+ } -+ -+ if (chip->debounce_cnt > N_DEBOUNCE_CNT) { -+ chip->timer_mux = T_DISABLED; -+ if ((chip->cc1 == TYPEC_CC_VOLT_RP && -+ chip->cc2 == TYPEC_CC_VOLT_OPEN) || -+ (chip->cc2 == TYPEC_CC_VOLT_RP && -+ chip->cc1 == TYPEC_CC_VOLT_OPEN)) { -+ chip->timer_mux = T_PD_SOURCE_ON; -+ fusb_timer_start(&chip->timer_mux_machine, -+ chip->timer_mux); -+ set_state(chip, attached_sink); -+ } else { -+ set_state_unattached(chip); -+ } -+ return; -+ } -+ -+ chip->timer_mux = 2; -+ fusb_timer_start(&chip->timer_mux_machine, -+ chip->timer_mux); -+ } -+} -+ -+static void fusb_state_attach_wait_source(struct fusb30x_chip *chip, u32 evt) -+{ -+ int cc1, cc2; -+ -+ if (evt & EVENT_TIMER_MUX) { -+ tcpm_get_cc(chip, &cc1, &cc2); -+ -+ if ((chip->cc1 == cc1) && (chip->cc2 == cc2)) { -+ chip->debounce_cnt++; -+ } else { -+ chip->cc1 = cc1; -+ chip->cc2 = cc2; -+ chip->debounce_cnt = 0; -+ } -+ -+ if (chip->debounce_cnt > N_DEBOUNCE_CNT) { -+ if (((!chip->cc1) || (!chip->cc2)) && -+ ((chip->cc1 == TYPEC_CC_VOLT_RD) || -+ (chip->cc2 == TYPEC_CC_VOLT_RD))) { -+ if (chip->role == ROLE_MODE_DRP && -+ chip->try_role == ROLE_MODE_UFP && -+ !chip->try_role_complete) -+ fusb_state_try_attach_set(chip, -+ ROLE_MODE_UFP); -+ else -+ set_state(chip, attached_source); -+ } else { -+ set_state_unattached(chip); -+ } -+ return; -+ } -+ -+ chip->timer_mux = 2; -+ fusb_timer_start(&chip->timer_mux_machine, -+ chip->timer_mux); -+ } -+} -+ -+static void fusb_state_attached_source(struct fusb30x_chip *chip, u32 evt) -+{ -+ platform_set_vbus_lvl_enable(chip, 1, 0); -+ tcpm_set_polarity(chip, (chip->cc_state & CC_STATE_TOGSS_CC1) ? -+ TYPEC_POLARITY_CC1 : TYPEC_POLARITY_CC2); -+ tcpm_set_vconn(chip, 1); -+ -+ chip->notify.is_cc_connected = true; -+ -+ chip->notify.power_role = POWER_ROLE_SOURCE; -+ chip->notify.data_role = DATA_ROLE_DFP; -+ chip->hardrst_count = 0; -+ set_state(chip, policy_src_startup); -+ regmap_update_bits(chip->regmap, FUSB_REG_MASK, MASK_M_COMP_CHNG, 0); -+ dev_info(chip->dev, "CC connected in %s as DFP\n", -+ chip->cc_polarity ? "CC1" : "CC2"); -+} -+ -+static void fusb_state_attached_sink(struct fusb30x_chip *chip, u32 evt) -+{ -+ if (tcpm_check_vbus(chip)) { -+ chip->timer_mux = T_DISABLED; -+ chip->timer_state = T_DISABLED; -+ if (!chip->try_role_complete && -+ chip->try_role == ROLE_MODE_DFP && -+ chip->role == ROLE_MODE_DRP) { -+ fusb_state_try_attach_set(chip, ROLE_MODE_DFP); -+ return; -+ } -+ -+ chip->try_role_complete = true; -+ chip->notify.is_cc_connected = true; -+ chip->notify.power_role = POWER_ROLE_SINK; -+ chip->notify.data_role = DATA_ROLE_UFP; -+ chip->hardrst_count = 0; -+ set_state(chip, policy_snk_startup); -+ dev_info(chip->dev, "CC connected in %s as UFP\n", -+ chip->cc_polarity ? "CC1" : "CC2"); -+ return; -+ } else if (evt & EVENT_TIMER_MUX) { -+ set_state_unattached(chip); -+ return; -+ } -+ -+ chip->timer_state = 2; -+ fusb_timer_start(&chip->timer_state_machine, -+ chip->timer_state); -+} -+ -+static void fusb_state_try_attach(struct fusb30x_chip *chip, u32 evt, -+ enum role_mode mode) -+{ -+ if ((evt & EVENT_CC) && chip->cc_state) { -+ chip->try_role_complete = true; -+ if (chip->cc_state & CC_STATE_TOGSS_IS_UFP) -+ set_state(chip, (mode == ROLE_MODE_UFP) ? -+ attach_wait_sink : error_recovery); -+ else -+ set_state(chip, (mode == ROLE_MODE_DFP) ? -+ attach_wait_source : error_recovery); -+ -+ tcpm_set_polarity(chip, (chip->cc_state & CC_STATE_TOGSS_CC1) ? -+ TYPEC_POLARITY_CC1 : -+ TYPEC_POLARITY_CC2); -+ tcpm_get_cc(chip, &chip->cc1, &chip->cc2); -+ chip->debounce_cnt = 0; -+ chip->timer_mux = 2; -+ fusb_timer_start(&chip->timer_mux_machine, chip->timer_mux); -+ } else if (evt & EVENT_TIMER_MUX) { -+ if (!chip->try_role_complete) { -+ chip->try_role_complete = true; -+ fusb_state_try_attach_set(chip, -+ (mode == ROLE_MODE_DFP) ? -+ ROLE_MODE_UFP : -+ ROLE_MODE_DFP); -+ } else { -+ set_state(chip, error_recovery); -+ } -+ } -+} -+ -+static void fusb_soft_reset_parameter(struct fusb30x_chip *chip) -+{ -+ chip->caps_counter = 0; -+ chip->msg_id = 0; -+ chip->vdm_state = VDM_STATE_DISCOVERY_ID; -+ chip->vdm_substate = 0; -+ chip->vdm_send_state = 0; -+ chip->val_tmp = 0; -+ chip->pos_power = 0; -+} -+ -+static void fusb_state_src_startup(struct fusb30x_chip *chip, u32 evt) -+{ -+ chip->notify.is_pd_connected = false; -+ fusb_soft_reset_parameter(chip); -+ -+ memset(chip->partner_cap, 0, sizeof(chip->partner_cap)); -+ -+ tcpm_set_msg_header(chip); -+ tcpm_set_polarity(chip, chip->cc_polarity); -+ tcpm_set_rx_enable(chip, 1); -+ -+ set_state(chip, policy_src_send_caps); -+ platform_fusb_notify(chip); -+} -+ -+static void fusb_state_src_discovery(struct fusb30x_chip *chip, u32 evt) -+{ -+ switch (chip->sub_state) { -+ case 0: -+ chip->caps_counter++; -+ -+ if (chip->caps_counter < N_CAPS_COUNT) { -+ chip->timer_state = T_TYPEC_SEND_SOURCECAP; -+ fusb_timer_start(&chip->timer_state_machine, -+ chip->timer_state); -+ chip->sub_state = 1; -+ } else { -+ set_state(chip, disabled); -+ } -+ break; -+ default: -+ if (evt & EVENT_TIMER_STATE) { -+ set_state(chip, policy_src_send_caps); -+ } else if (evt & EVENT_TIMER_MUX) { -+ if (!chip->is_pd_support) -+ set_state(chip, disabled); -+ else if (chip->hardrst_count > N_HARDRESET_COUNT) -+ set_state(chip, error_recovery); -+ else -+ set_state(chip, policy_src_send_hardrst); -+ } -+ break; -+ } -+} -+ -+static void fusb_state_src_send_caps(struct fusb30x_chip *chip, u32 evt) -+{ -+ u32 tmp; -+ -+ switch (chip->sub_state) { -+ case 0: -+ set_mesg(chip, DMT_SOURCECAPABILITIES, DATAMESSAGE); -+ chip->sub_state = 1; -+ chip->tx_state = tx_idle; -+ /* without break */ -+ case 1: -+ tmp = policy_send_data(chip); -+ -+ if (tmp == tx_success) { -+ chip->hardrst_count = 0; -+ chip->caps_counter = 0; -+ chip->timer_state = T_SENDER_RESPONSE; -+ fusb_timer_start(&chip->timer_state_machine, -+ chip->timer_state); -+ chip->timer_mux = T_DISABLED; -+ chip->sub_state++; -+ chip->is_pd_support = true; -+ } else if (tmp == tx_failed) { -+ set_state(chip, policy_src_discovery); -+ break; -+ } -+ -+ if (!(evt & FLAG_EVENT)) -+ break; -+ default: -+ if (evt & EVENT_RX) { -+ if (PACKET_IS_DATA_MSG(chip->rec_head, DMT_REQUEST)) { -+ set_state(chip, policy_src_negotiate_cap); -+ } else { -+ set_state(chip, policy_src_send_softrst); -+ } -+ } else if (evt & EVENT_TIMER_STATE) { -+ if (chip->hardrst_count <= N_HARDRESET_COUNT) -+ set_state(chip, policy_src_send_hardrst); -+ else -+ set_state(chip, disabled); -+ } else if (evt & EVENT_TIMER_MUX) { -+ if (!chip->is_pd_support) -+ set_state(chip, disabled); -+ else if (chip->hardrst_count > N_HARDRESET_COUNT) -+ set_state(chip, error_recovery); -+ else -+ set_state(chip, policy_src_send_hardrst); -+ } -+ break; -+ } -+} -+ -+static void fusb_state_src_negotiate_cap(struct fusb30x_chip *chip, u32 evt) -+{ -+ u32 tmp; -+ -+ /* base on evb1 */ -+ tmp = (chip->rec_load[0] >> 28) & 0x07; -+ if (tmp > chip->n_caps_used) -+ set_state(chip, policy_src_cap_response); -+ else -+ set_state(chip, policy_src_transition_supply); -+} -+ -+static void fusb_state_src_transition_supply(struct fusb30x_chip *chip, -+ u32 evt) -+{ -+ u32 tmp; -+ -+ switch (chip->sub_state) { -+ case 0: -+ set_mesg(chip, CMT_ACCEPT, CONTROLMESSAGE); -+ chip->tx_state = tx_idle; -+ chip->sub_state++; -+ /* without break */ -+ case 1: -+ tmp = policy_send_data(chip); -+ if (tmp == tx_success) { -+ chip->timer_state = T_SRC_TRANSITION; -+ chip->sub_state++; -+ fusb_timer_start(&chip->timer_state_machine, -+ chip->timer_state); -+ } else if (tmp == tx_failed) { -+ set_state(chip, policy_src_send_softrst); -+ } -+ break; -+ case 2: -+ if (evt & EVENT_TIMER_STATE) { -+ chip->notify.is_pd_connected = true; -+ platform_set_vbus_lvl_enable(chip, 1, 0); -+ set_mesg(chip, CMT_PS_RDY, CONTROLMESSAGE); -+ chip->tx_state = tx_idle; -+ chip->sub_state++; -+ chip->work_continue |= EVENT_WORK_CONTINUE; -+ } -+ break; -+ default: -+ tmp = policy_send_data(chip); -+ if (tmp == tx_success) { -+ dev_info(chip->dev, -+ "PD connected as DFP, supporting 5V\n"); -+ set_state(chip, policy_src_ready); -+ } else if (tmp == tx_failed) { -+ set_state(chip, policy_src_send_softrst); -+ } -+ break; -+ } -+} -+ -+static void fusb_state_src_cap_response(struct fusb30x_chip *chip, u32 evt) -+{ -+ u32 tmp; -+ -+ switch (chip->sub_state) { -+ case 0: -+ set_mesg(chip, CMT_REJECT, CONTROLMESSAGE); -+ chip->tx_state = tx_idle; -+ chip->sub_state++; -+ /* without break */ -+ default: -+ tmp = policy_send_data(chip); -+ if (tmp == tx_success) { -+ if (chip->notify.is_pd_connected) { -+ dev_info(chip->dev, -+ "PD connected as DFP, supporting 5V\n"); -+ set_state(chip, policy_src_ready); -+ } else { -+ set_state(chip, policy_src_send_hardrst); -+ } -+ } else if (tmp == tx_failed) { -+ set_state(chip, policy_src_send_softrst); -+ } -+ break; -+ } -+} -+ -+static void fusb_state_src_transition_default(struct fusb30x_chip *chip, -+ u32 evt) -+{ -+ switch (chip->sub_state) { -+ case 0: -+ chip->notify.is_pd_connected = false; -+ platform_set_vbus_lvl_enable(chip, 0, 0); -+ if (chip->notify.data_role) -+ regmap_update_bits(chip->regmap, -+ FUSB_REG_SWITCHES1, -+ SWITCHES1_DATAROLE, -+ SWITCHES1_DATAROLE); -+ else -+ regmap_update_bits(chip->regmap, -+ FUSB_REG_SWITCHES1, -+ SWITCHES1_DATAROLE, -+ 0); -+ -+ chip->timer_state = T_SRC_RECOVER; -+ fusb_timer_start(&chip->timer_state_machine, -+ chip->timer_state); -+ chip->sub_state++; -+ break; -+ default: -+ if (evt & EVENT_TIMER_STATE) { -+ platform_set_vbus_lvl_enable(chip, 1, 0); -+ chip->timer_mux = T_NO_RESPONSE; -+ fusb_timer_start(&chip->timer_mux_machine, -+ chip->timer_mux); -+ set_state(chip, policy_src_startup); -+ dev_dbg(chip->dev, "reset over-> src startup\n"); -+ } -+ break; -+ } -+} -+ -+static void fusb_state_vcs_ufp_evaluate_swap(struct fusb30x_chip *chip, u32 evt) -+{ -+ if (chip->vconn_supported) -+ set_state(chip, policy_vcs_ufp_accept); -+ else -+ set_state(chip, policy_vcs_ufp_reject); -+} -+ -+static void fusb_state_swap_msg_process(struct fusb30x_chip *chip, u32 evt) -+{ -+ if (evt & EVENT_RX) { -+ if (PACKET_IS_CONTROL_MSG(chip->rec_head, CMT_PR_SWAP)) { -+ set_state(chip, policy_src_prs_evaluate); -+ } else if (PACKET_IS_CONTROL_MSG(chip->rec_head, -+ CMT_VCONN_SWAP)) { -+ if (chip->notify.data_role) -+ set_state(chip, chip->conn_state); -+ else -+ set_state(chip, policy_vcs_ufp_evaluate_swap); -+ } else if (PACKET_IS_CONTROL_MSG(chip->rec_head, -+ CMT_DR_SWAP)) { -+ if (chip->notify.data_role) -+ set_state(chip, policy_drs_dfp_evaluate); -+ else -+ set_state(chip, policy_drs_ufp_evaluate); -+ } -+ } -+} -+ -+#define VDM_IS_ACTIVE(chip) \ -+ (chip->notify.data_role && chip->vdm_state < VDM_STATE_READY) -+ -+static void fusb_state_src_ready(struct fusb30x_chip *chip, u32 evt) -+{ -+ if (evt & EVENT_RX) { -+ if (PACKET_IS_DATA_MSG(chip->rec_head, DMT_VENDERDEFINED)) { -+ process_vdm_msg(chip); -+ chip->work_continue |= EVENT_WORK_CONTINUE; -+ chip->timer_state = T_DISABLED; -+ } else if (!VDM_IS_ACTIVE(chip)) { -+ fusb_state_swap_msg_process(chip, evt); -+ } -+ } -+ -+ if (!chip->partner_cap[0]) -+ set_state(chip, policy_src_get_sink_caps); -+ else if (VDM_IS_ACTIVE(chip)) -+ auto_vdm_machine(chip, evt); -+} -+ -+static void fusb_state_prs_evaluate(struct fusb30x_chip *chip, u32 evt) -+{ -+ if (chip->role == ROLE_MODE_DRP) -+ set_state(chip, policy_src_prs_accept); -+ else -+ set_state(chip, policy_src_prs_reject); -+} -+ -+static void fusb_state_send_simple_msg(struct fusb30x_chip *chip, u32 evt, -+ int cmd, int is_DMT, -+ enum connection_state state_success, -+ enum connection_state state_failed) -+{ -+ u32 tmp; -+ -+ switch (chip->sub_state) { -+ case 0: -+ set_mesg(chip, cmd, is_DMT); -+ chip->tx_state = tx_idle; -+ chip->sub_state++; -+ /* fallthrough */ -+ case 1: -+ tmp = policy_send_data(chip); -+ if (tmp == tx_success) -+ set_state(chip, state_success); -+ else if (tmp == tx_failed) -+ set_state(chip, state_failed); -+ } -+} -+ -+static void fusb_state_prs_reject(struct fusb30x_chip *chip, u32 evt) -+{ -+ fusb_state_send_simple_msg(chip, evt, CMT_REJECT, CONTROLMESSAGE, -+ (chip->notify.power_role) ? -+ policy_src_ready : policy_snk_ready, -+ (chip->notify.power_role) ? -+ policy_src_send_softrst : -+ policy_snk_send_softrst); -+} -+ -+static void fusb_state_prs_accept(struct fusb30x_chip *chip, u32 evt) -+{ -+ fusb_state_send_simple_msg(chip, evt, CMT_ACCEPT, CONTROLMESSAGE, -+ (chip->notify.power_role) ? -+ policy_src_prs_transition_to_off : -+ policy_snk_prs_transition_to_off, -+ (chip->notify.power_role) ? -+ policy_src_send_softrst : -+ policy_snk_send_softrst); -+} -+ -+static void fusb_state_vcs_ufp_accept(struct fusb30x_chip *chip, u32 evt) -+{ -+ fusb_state_send_simple_msg(chip, evt, CMT_ACCEPT, CONTROLMESSAGE, -+ (chip->vconn_enabled) ? -+ policy_vcs_ufp_wait_for_dfp_vconn : -+ policy_vcs_ufp_turn_on_vconn, -+ (chip->notify.power_role) ? -+ policy_src_send_softrst : -+ policy_snk_send_softrst); -+} -+ -+static void fusb_state_vcs_set_vconn(struct fusb30x_chip *chip, -+ u32 evt, bool on) -+{ -+ if (on) { -+ tcpm_set_vconn(chip, 1); -+ set_state(chip, chip->notify.data_role ? -+ policy_vcs_dfp_send_ps_rdy : -+ policy_vcs_ufp_send_ps_rdy); -+ } else { -+ tcpm_set_vconn(chip, 0); -+ if (chip->notify.power_role) -+ set_state(chip, policy_src_ready); -+ else -+ set_state(chip, policy_snk_ready); -+ } -+} -+ -+static void fusb_state_vcs_send_ps_rdy(struct fusb30x_chip *chip, u32 evt) -+{ -+ fusb_state_send_simple_msg(chip, evt, CMT_PS_RDY, CONTROLMESSAGE, -+ (chip->notify.power_role) ? -+ policy_src_ready : policy_snk_ready, -+ (chip->notify.power_role) ? -+ policy_src_send_softrst : -+ policy_snk_send_softrst); -+} -+ -+static void fusb_state_vcs_wait_for_vconn(struct fusb30x_chip *chip, -+ u32 evt) -+{ -+ switch (chip->sub_state) { -+ case 0: -+ chip->timer_state = T_PD_VCONN_SRC_ON; -+ fusb_timer_start(&chip->timer_state_machine, -+ chip->timer_state); -+ chip->sub_state++; -+ /* fallthrough */ -+ case 1: -+ if (evt & EVENT_RX) { -+ if (PACKET_IS_CONTROL_MSG(chip->rec_head, CMT_PS_RDY)) -+ set_state(chip, chip->notify.data_role ? -+ policy_vcs_dfp_turn_off_vconn : -+ policy_vcs_ufp_turn_off_vconn); -+ } else if (evt & EVENT_TIMER_STATE) { -+ if (chip->notify.power_role) -+ set_state(chip, policy_src_send_hardrst); -+ else -+ set_state(chip, policy_snk_send_hardrst); -+ } -+ } -+} -+ -+static void fusb_state_src_prs_transition_to_off(struct fusb30x_chip *chip, -+ u32 evt) -+{ -+ switch (chip->sub_state) { -+ case 0: -+ chip->timer_state = T_SRC_TRANSITION; -+ fusb_timer_start(&chip->timer_state_machine, -+ chip->timer_state); -+ chip->sub_state++; -+ break; -+ case 1: -+ if (evt & EVENT_TIMER_STATE) { -+ platform_set_vbus_lvl_enable(chip, 0, 0); -+ chip->notify.power_role = POWER_ROLE_SINK; -+ tcpm_set_msg_header(chip); -+ if (chip->role == ROLE_MODE_DRP) -+ set_state(chip, policy_src_prs_assert_rd); -+ else -+ set_state(chip, policy_src_prs_source_off); -+ } -+ } -+} -+ -+static void fusb_state_src_prs_assert_rd(struct fusb30x_chip *chip, u32 evt) -+{ -+ tcpm_set_cc_pull_mode(chip, CC_PULL_DOWN); -+ set_state(chip, policy_src_prs_source_off); -+} -+ -+static void fusb_state_src_prs_source_off(struct fusb30x_chip *chip, u32 evt) -+{ -+ u32 tmp; -+ -+ switch (chip->sub_state) { -+ case 0: -+ set_mesg(chip, CMT_PS_RDY, CONTROLMESSAGE); -+ chip->tx_state = tx_idle; -+ chip->sub_state++; -+ /* fallthrough */ -+ case 1: -+ tmp = policy_send_data(chip); -+ if (tmp == tx_success) { -+ chip->timer_state = T_PD_SOURCE_ON; -+ fusb_timer_start(&chip->timer_state_machine, -+ chip->timer_state); -+ chip->sub_state++; -+ } else if (tmp == tx_failed) { -+ chip->notify.power_role = POWER_ROLE_SOURCE; -+ tcpm_set_msg_header(chip); -+ set_state(chip, policy_src_send_hardrst); -+ } -+ if (chip->sub_state != 3) -+ break; -+ case 2: -+ if (evt & EVENT_RX) { -+ if (PACKET_IS_CONTROL_MSG(chip->rec_head, -+ CMT_PS_RDY)) { -+ chip->timer_state = T_DISABLED; -+ /* snk startup */ -+ chip->notify.is_pd_connected = false; -+ chip->cc_state |= CC_STATE_TOGSS_IS_UFP; -+ tcpm_set_polarity(chip, chip->cc_polarity); -+ tcpm_set_rx_enable(chip, 1); -+ set_state(chip, policy_snk_discovery); -+ } else { -+ dev_dbg(chip->dev, -+ "rec careless msg: head %x\n", -+ chip->rec_head); -+ } -+ } else if (evt & EVENT_TIMER_STATE) { -+ chip->notify.power_role = POWER_ROLE_SOURCE; -+ tcpm_set_msg_header(chip); -+ set_state(chip, policy_src_send_hardrst); -+ } -+ } -+} -+ -+static void fusb_state_drs_evaluate(struct fusb30x_chip *chip, u32 evt) -+{ -+ if (chip->pd_cap_info.data_role_swap) -+ /* -+ * TODO: -+ * NOW REJECT swap when the port is DFP -+ * since we should work together with USB part -+ */ -+ set_state(chip, chip->notify.data_role ? -+ policy_drs_dfp_reject : policy_drs_ufp_accept); -+ else -+ set_state(chip, chip->notify.data_role ? -+ policy_drs_dfp_reject : policy_drs_ufp_reject); -+} -+ -+static void fusb_state_drs_send_accept(struct fusb30x_chip *chip, u32 evt) -+{ -+ fusb_state_send_simple_msg(chip, evt, CMT_ACCEPT, CONTROLMESSAGE, -+ chip->notify.power_role ? -+ policy_drs_dfp_change : -+ policy_drs_ufp_change, -+ error_recovery); -+} -+ -+static void fusb_state_drs_role_change(struct fusb30x_chip *chip, u32 evt) -+{ -+ chip->notify.data_role = chip->notify.data_role ? -+ DATA_ROLE_UFP : DATA_ROLE_DFP; -+ tcpm_set_msg_header(chip); -+ set_state(chip, chip->notify.power_role ? policy_src_ready : -+ policy_snk_ready); -+} -+ -+static void fusb_state_src_get_sink_cap(struct fusb30x_chip *chip, u32 evt) -+{ -+ u32 tmp; -+ -+ switch (chip->sub_state) { -+ case 0: -+ set_mesg(chip, CMT_GETSINKCAP, CONTROLMESSAGE); -+ chip->tx_state = tx_idle; -+ chip->sub_state++; -+ /* without break */ -+ case 1: -+ tmp = policy_send_data(chip); -+ if (tmp == tx_success) { -+ chip->timer_state = T_SENDER_RESPONSE; -+ chip->sub_state++; -+ fusb_timer_start(&chip->timer_state_machine, -+ chip->timer_state); -+ } else if (tmp == tx_failed) { -+ set_state(chip, policy_src_send_softrst); -+ } -+ -+ if (!(evt & FLAG_EVENT)) -+ break; -+ default: -+ if (evt & EVENT_RX) { -+ if (PACKET_IS_DATA_MSG(chip->rec_head, -+ DMT_SINKCAPABILITIES)) { -+ for (tmp = 0; -+ tmp < PD_HEADER_CNT(chip->rec_head); -+ tmp++) { -+ chip->partner_cap[tmp] = -+ chip->rec_load[tmp]; -+ } -+ set_state(chip, policy_src_ready); -+ } else { -+ chip->partner_cap[0] = 0xffffffff; -+ set_state(chip, policy_src_ready); -+ } -+ } else if (evt & EVENT_TIMER_STATE) { -+ dev_warn(chip->dev, "Get sink cap time out\n"); -+ chip->partner_cap[0] = 0xffffffff; -+ set_state(chip, policy_src_ready); -+ } -+ } -+} -+ -+static void fusb_state_src_send_hardreset(struct fusb30x_chip *chip, u32 evt) -+{ -+ u32 tmp; -+ -+ switch (chip->sub_state) { -+ case 0: -+ chip->tx_state = tx_idle; -+ chip->sub_state++; -+ /* without break */ -+ default: -+ tmp = policy_send_hardrst(chip, evt); -+ if (tmp == tx_success) { -+ chip->hardrst_count++; -+ set_state(chip, policy_src_transition_default); -+ } else if (tmp == tx_failed) { -+ /* can't reach here */ -+ set_state(chip, error_recovery); -+ } -+ break; -+ } -+} -+ -+static void fusb_state_src_softreset(struct fusb30x_chip *chip) -+{ -+ u32 tmp; -+ -+ switch (chip->sub_state) { -+ case 0: -+ set_mesg(chip, CMT_ACCEPT, CONTROLMESSAGE); -+ chip->tx_state = tx_idle; -+ chip->sub_state++; -+ /* without break */ -+ default: -+ tmp = policy_send_data(chip); -+ if (tmp == tx_success) { -+ fusb_soft_reset_parameter(chip); -+ set_state(chip, policy_src_send_caps); -+ } else if (tmp == tx_failed) { -+ set_state(chip, policy_src_send_hardrst); -+ } -+ break; -+ } -+} -+ -+static void fusb_state_src_send_softreset(struct fusb30x_chip *chip, u32 evt) -+{ -+ u32 tmp; -+ -+ switch (chip->sub_state) { -+ case 0: -+ set_mesg(chip, CMT_SOFTRESET, CONTROLMESSAGE); -+ chip->tx_state = tx_idle; -+ chip->sub_state++; -+ /* without break */ -+ case 1: -+ tmp = policy_send_data(chip); -+ if (tmp == tx_success) { -+ chip->timer_state = T_SENDER_RESPONSE; -+ chip->sub_state++; -+ fusb_timer_start(&chip->timer_state_machine, -+ chip->timer_state); -+ } else if (tmp == tx_failed) { -+ set_state(chip, policy_src_send_hardrst); -+ } -+ -+ if (!(evt & FLAG_EVENT)) -+ break; -+ default: -+ if (evt & EVENT_RX) { -+ if (PACKET_IS_CONTROL_MSG(chip->rec_head, CMT_ACCEPT)) { -+ fusb_soft_reset_parameter(chip); -+ set_state(chip, policy_src_send_caps); -+ } -+ } else if (evt & EVENT_TIMER_STATE) { -+ set_state(chip, policy_src_send_hardrst); -+ } -+ break; -+ } -+} -+ -+static void fusb_state_snk_startup(struct fusb30x_chip *chip, u32 evt) -+{ -+ chip->notify.is_pd_connected = false; -+ fusb_soft_reset_parameter(chip); -+ -+ memset(chip->partner_cap, 0, sizeof(chip->partner_cap)); -+ -+ tcpm_set_msg_header(chip); -+ tcpm_set_polarity(chip, chip->cc_polarity); -+ tcpm_set_rx_enable(chip, 1); -+ set_state(chip, policy_snk_discovery); -+ platform_fusb_notify(chip); -+} -+ -+static void fusb_state_snk_discovery(struct fusb30x_chip *chip, u32 evt) -+{ -+ set_state(chip, policy_snk_wait_caps); -+ chip->timer_state = T_TYPEC_SINK_WAIT_CAP; -+ fusb_timer_start(&chip->timer_state_machine, -+ chip->timer_state); -+} -+ -+static void fusb_state_snk_wait_caps(struct fusb30x_chip *chip, u32 evt) -+{ -+ if (evt & EVENT_RX) { -+ if (PACKET_IS_DATA_MSG(chip->rec_head, -+ DMT_SOURCECAPABILITIES)) { -+ chip->is_pd_support = true; -+ chip->timer_mux = T_DISABLED; -+ set_state(chip, policy_snk_evaluate_caps); -+ } -+ } else if (evt & EVENT_TIMER_STATE) { -+ if (chip->hardrst_count <= N_HARDRESET_COUNT) { -+ if (chip->vbus_begin) { -+ chip->vbus_begin = false; -+ set_state(chip, policy_snk_send_softrst); -+ } else { -+ set_state(chip, policy_snk_send_hardrst); -+ } -+ } else { -+ if (chip->is_pd_support) -+ set_state(chip, error_recovery); -+ else -+ set_state(chip, disabled); -+ } -+ } else if ((evt & EVENT_TIMER_MUX) && -+ (chip->hardrst_count > N_HARDRESET_COUNT)) { -+ if (chip->is_pd_support) -+ set_state(chip, error_recovery); -+ else -+ set_state(chip, disabled); -+ } -+} -+ -+static void fusb_state_snk_evaluate_caps(struct fusb30x_chip *chip, u32 evt) -+{ -+ u32 tmp; -+ -+ chip->hardrst_count = 0; -+ chip->pos_power = 0; -+ -+ for (tmp = 0; tmp < PD_HEADER_CNT(chip->rec_head); tmp++) { -+ switch (CAP_POWER_TYPE(chip->rec_load[tmp])) { -+ case 0: -+ /* Fixed Supply */ -+ if (CAP_FPDO_VOLTAGE(chip->rec_load[tmp]) <= 100) -+ chip->pos_power = tmp + 1; -+ break; -+ case 1: -+ /* Battery */ -+ if (CAP_VPDO_VOLTAGE(chip->rec_load[tmp]) <= 100) -+ chip->pos_power = tmp + 1; -+ break; -+ default: -+ /* not meet battery caps */ -+ break; -+ } -+ } -+ fusb302_set_pos_power_by_charge_ic(chip); -+ -+ if ((!chip->pos_power) || (chip->pos_power > 7)) { -+ chip->pos_power = 0; -+ set_state(chip, policy_snk_wait_caps); -+ } else { -+ set_state(chip, policy_snk_select_cap); -+ } -+} -+ -+static void fusb_state_snk_select_cap(struct fusb30x_chip *chip, u32 evt) -+{ -+ u32 tmp; -+ -+ switch (chip->sub_state) { -+ case 0: -+ set_mesg(chip, DMT_REQUEST, DATAMESSAGE); -+ chip->sub_state = 1; -+ chip->tx_state = tx_idle; -+ /* without break */ -+ case 1: -+ tmp = policy_send_data(chip); -+ -+ if (tmp == tx_success) { -+ chip->timer_state = T_SENDER_RESPONSE; -+ fusb_timer_start(&chip->timer_state_machine, -+ chip->timer_state); -+ chip->sub_state++; -+ } else if (tmp == tx_failed) { -+ set_state(chip, policy_snk_discovery); -+ break; -+ } -+ -+ if (!(evt & FLAG_EVENT)) -+ break; -+ default: -+ if (evt & EVENT_RX) { -+ if (!PD_HEADER_CNT(chip->rec_head)) { -+ switch (PD_HEADER_TYPE(chip->rec_head)) { -+ case CMT_ACCEPT: -+ set_state(chip, -+ policy_snk_transition_sink); -+ chip->timer_state = T_PS_TRANSITION; -+ fusb_timer_start(&chip->timer_state_machine, -+ chip->timer_state); -+ break; -+ case CMT_WAIT: -+ case CMT_REJECT: -+ if (chip->notify.is_pd_connected) { -+ dev_info(chip->dev, -+ "PD connected as UFP, fetching 5V\n"); -+ set_state(chip, -+ policy_snk_ready); -+ } else { -+ set_state(chip, -+ policy_snk_wait_caps); -+ /* -+ * make sure don't send -+ * hard reset to prevent -+ * infinite loop -+ */ -+ chip->hardrst_count = -+ N_HARDRESET_COUNT + 1; -+ } -+ break; -+ default: -+ break; -+ } -+ } -+ } else if (evt & EVENT_TIMER_STATE) { -+ set_state(chip, policy_snk_send_hardrst); -+ } -+ break; -+ } -+} -+ -+static void fusb_state_snk_transition_sink(struct fusb30x_chip *chip, u32 evt) -+{ -+ if (evt & EVENT_RX) { -+ if (PACKET_IS_CONTROL_MSG(chip->rec_head, CMT_PS_RDY)) { -+ chip->notify.is_pd_connected = true; -+ dev_info(chip->dev, -+ "PD connected as UFP, fetching 5V\n"); -+ set_state(chip, policy_snk_ready); -+ } else if (PACKET_IS_DATA_MSG(chip->rec_head, -+ DMT_SOURCECAPABILITIES)) { -+ set_state(chip, policy_snk_evaluate_caps); -+ } -+ } else if (evt & EVENT_TIMER_STATE) { -+ set_state(chip, policy_snk_send_hardrst); -+ } -+} -+ -+static void fusb_state_snk_transition_default(struct fusb30x_chip *chip, -+ u32 evt) -+{ -+ switch (chip->sub_state) { -+ case 0: -+ chip->notify.is_pd_connected = false; -+ chip->timer_mux = T_NO_RESPONSE; -+ fusb_timer_start(&chip->timer_mux_machine, -+ chip->timer_mux); -+ chip->timer_state = T_PS_HARD_RESET_MAX + T_SAFE_0V; -+ fusb_timer_start(&chip->timer_state_machine, -+ chip->timer_state); -+ if (chip->notify.data_role) -+ tcpm_set_msg_header(chip); -+ -+ chip->sub_state++; -+ /* fallthrough */ -+ case 1: -+ if (!tcpm_check_vbus(chip)) { -+ chip->sub_state++; -+ chip->timer_state = T_SRC_RECOVER_MAX + T_SRC_TURN_ON; -+ fusb_timer_start(&chip->timer_state_machine, -+ chip->timer_state); -+ } else if (evt & EVENT_TIMER_STATE) { -+ set_state(chip, policy_snk_startup); -+ } -+ break; -+ default: -+ if (tcpm_check_vbus(chip)) { -+ chip->timer_state = T_DISABLED; -+ set_state(chip, policy_snk_startup); -+ } else if (evt & EVENT_TIMER_STATE) { -+ set_state(chip, policy_snk_startup); -+ } -+ break; -+ } -+} -+ -+static void fusb_state_snk_ready(struct fusb30x_chip *chip, u32 evt) -+{ -+ if (evt & EVENT_RX) { -+ if (PACKET_IS_DATA_MSG(chip->rec_head, DMT_VENDERDEFINED)) { -+ process_vdm_msg(chip); -+ chip->work_continue |= EVENT_WORK_CONTINUE; -+ chip->timer_state = T_DISABLED; -+ } else if (!VDM_IS_ACTIVE(chip)) { -+ fusb_state_swap_msg_process(chip, evt); -+ } -+ } -+ -+ if (VDM_IS_ACTIVE(chip)) -+ auto_vdm_machine(chip, evt); -+ -+ fusb_state_swap_msg_process(chip, evt); -+ platform_fusb_notify(chip); -+} -+ -+static void fusb_state_snk_send_hardreset(struct fusb30x_chip *chip, u32 evt) -+{ -+ u32 tmp; -+ -+ switch (chip->sub_state) { -+ case 0: -+ chip->tx_state = tx_idle; -+ chip->sub_state++; -+ default: -+ tmp = policy_send_hardrst(chip, evt); -+ if (tmp == tx_success) { -+ chip->hardrst_count++; -+ set_state(chip, policy_snk_transition_default); -+ } else if (tmp == tx_failed) { -+ set_state(chip, error_recovery); -+ } -+ break; -+ } -+} -+ -+static void fusb_state_send_swap(struct fusb30x_chip *chip, u32 evt, int cmd) -+{ -+ u32 tmp; -+ -+ switch (chip->sub_state) { -+ case 0: -+ set_mesg(chip, cmd, CONTROLMESSAGE); -+ chip->sub_state = 1; -+ chip->tx_state = tx_idle; -+ /* fallthrough */ -+ case 1: -+ tmp = policy_send_data(chip); -+ -+ if (tmp == tx_success) { -+ chip->timer_state = T_SENDER_RESPONSE; -+ fusb_timer_start(&chip->timer_state_machine, -+ chip->timer_state); -+ chip->sub_state++; -+ } else if (tmp == tx_failed) { -+ if (cmd == CMT_DR_SWAP) { -+ set_state(chip, error_recovery); -+ return; -+ } -+ -+ if (chip->notify.power_role) -+ set_state(chip, policy_src_send_softrst); -+ else -+ set_state(chip, policy_snk_send_softrst); -+ } -+ break; -+ case 2: -+ if (evt & EVENT_RX) { -+ if (PACKET_IS_CONTROL_MSG(chip->rec_head, -+ CMT_ACCEPT)) { -+ chip->timer_state = T_DISABLED; -+ if (cmd == CMT_VCONN_SWAP) { -+ set_state(chip, chip->vconn_enabled ? -+ policy_vcs_dfp_wait_for_ufp_vconn : -+ policy_vcs_dfp_turn_on_vconn); -+ } else if (cmd == CMT_PR_SWAP) { -+ if (chip->notify.power_role) -+ set_state(chip, policy_src_prs_transition_to_off); -+ else -+ set_state(chip, policy_snk_prs_transition_to_off); -+ chip->notify.power_role = POWER_ROLE_SOURCE; -+ tcpm_set_msg_header(chip); -+ } else if (cmd == CMT_DR_SWAP) { -+ set_state(chip, chip->notify.data_role ? -+ policy_drs_dfp_change : -+ policy_drs_ufp_change); -+ } -+ } else if (PACKET_IS_CONTROL_MSG(chip->rec_head, -+ CMT_REJECT) || -+ PACKET_IS_CONTROL_MSG(chip->rec_head, -+ CMT_WAIT)) { -+ chip->timer_state = T_DISABLED; -+ if (chip->notify.power_role) -+ set_state(chip, policy_src_ready); -+ else -+ set_state(chip, policy_snk_ready); -+ } -+ } else if (evt & EVENT_TIMER_STATE) { -+ if (chip->notify.power_role) -+ set_state(chip, policy_src_ready); -+ else -+ set_state(chip, policy_snk_ready); -+ } -+ } -+} -+ -+static void fusb_state_snk_prs_transition_to_off(struct fusb30x_chip *chip, -+ u32 evt) -+{ -+ switch (chip->sub_state) { -+ case 0: -+ chip->timer_state = T_PD_SOURCE_OFF; -+ fusb_timer_start(&chip->timer_state_machine, -+ chip->timer_state); -+ chip->sub_state++; -+ /* fallthrough */ -+ case 1: -+ if (evt & EVENT_RX) { -+ if (PACKET_IS_CONTROL_MSG(chip->rec_head, -+ CMT_PS_RDY)) { -+ if (chip->role == ROLE_MODE_DRP) -+ set_state(chip, -+ policy_snk_prs_assert_rp); -+ else -+ set_state(chip, -+ policy_snk_prs_source_on); -+ } else { -+ dev_dbg(chip->dev, -+ "rec careless msg: head %x\n", -+ chip->rec_head); -+ } -+ } else if (evt & EVENT_TIMER_STATE) { -+ chip->notify.power_role = POWER_ROLE_SINK; -+ tcpm_set_msg_header(chip); -+ set_state(chip, policy_snk_send_hardrst); -+ } -+ break; -+ } -+} -+ -+static void fusb_state_snk_prs_assert_rp(struct fusb30x_chip *chip, u32 evt) -+{ -+ tcpm_set_cc_pull_mode(chip, CC_PULL_UP); -+ set_state(chip, policy_snk_prs_source_on); -+} -+ -+static void fusb_state_snk_prs_source_on(struct fusb30x_chip *chip, u32 evt) -+{ -+ u32 tmp; -+ -+ switch (chip->sub_state) { -+ case 0: -+ /* supply power in 50ms */ -+ platform_set_vbus_lvl_enable(chip, 1, 0); -+ chip->sub_state++; -+ chip->work_continue |= EVENT_WORK_CONTINUE; -+ break; -+ case 1: -+ set_mesg(chip, CMT_PS_RDY, CONTROLMESSAGE); -+ chip->tx_state = tx_idle; -+ chip->sub_state++; -+ /* fallthrough */ -+ case 2: -+ tmp = policy_send_data(chip); -+ if (tmp == tx_success) { -+ /* PD spe 6.5.10.2 */ -+ chip->timer_state = T_PD_SWAP_SOURCE_START; -+ fusb_timer_start(&chip->timer_state_machine, -+ chip->timer_state); -+ chip->sub_state++; -+ } else if (tmp == tx_failed) { -+ chip->notify.power_role = POWER_ROLE_SINK; -+ tcpm_set_msg_header(chip); -+ set_state(chip, policy_snk_send_hardrst); -+ } -+ break; -+ case 3: -+ if (evt & EVENT_TIMER_STATE) { -+ chip->cc_state &= ~CC_STATE_TOGSS_IS_UFP; -+ regmap_update_bits(chip->regmap, FUSB_REG_MASK, -+ MASK_M_COMP_CHNG, 0); -+ set_state(chip, policy_src_send_caps); -+ } -+ break; -+ } -+} -+ -+static void fusb_state_snk_softreset(struct fusb30x_chip *chip) -+{ -+ u32 tmp; -+ -+ switch (chip->sub_state) { -+ case 0: -+ set_mesg(chip, CMT_ACCEPT, CONTROLMESSAGE); -+ chip->tx_state = tx_idle; -+ chip->sub_state++; -+ /* without break */ -+ default: -+ tmp = policy_send_data(chip); -+ if (tmp == tx_success) { -+ fusb_soft_reset_parameter(chip); -+ chip->timer_state = T_TYPEC_SINK_WAIT_CAP; -+ fusb_timer_start(&chip->timer_state_machine, -+ chip->timer_state); -+ set_state(chip, policy_snk_wait_caps); -+ } else if (tmp == tx_failed) { -+ set_state(chip, policy_snk_send_hardrst); -+ } -+ break; -+ } -+} -+ -+static void fusb_state_snk_send_softreset(struct fusb30x_chip *chip, u32 evt) -+{ -+ u32 tmp; -+ -+ switch (chip->sub_state) { -+ case 0: -+ set_mesg(chip, CMT_SOFTRESET, CONTROLMESSAGE); -+ chip->tx_state = tx_idle; -+ chip->sub_state++; -+ case 1: -+ tmp = policy_send_data(chip); -+ if (tmp == tx_success) { -+ chip->timer_state = T_SENDER_RESPONSE; -+ chip->sub_state++; -+ fusb_timer_start(&chip->timer_state_machine, -+ chip->timer_state); -+ } else if (tmp == tx_failed) { -+ /* can't reach here */ -+ set_state(chip, policy_snk_send_hardrst); -+ } -+ -+ if (!(evt & FLAG_EVENT)) -+ break; -+ default: -+ if (evt & EVENT_RX) { -+ if ((!PD_HEADER_CNT(chip->rec_head)) && -+ (PD_HEADER_TYPE(chip->rec_head) == CMT_ACCEPT)) { -+ fusb_soft_reset_parameter(chip); -+ chip->timer_state = T_TYPEC_SINK_WAIT_CAP; -+ fusb_timer_start(&chip->timer_state_machine, -+ chip->timer_state); -+ set_state(chip, policy_snk_wait_caps); -+ } -+ } else if (evt & EVENT_TIMER_STATE) { -+ set_state(chip, policy_snk_send_hardrst); -+ } -+ break; -+ } -+} -+ -+static void fusb_try_detach(struct fusb30x_chip *chip) -+{ -+ int cc1, cc2; -+ -+ if ((chip->cc_state & CC_STATE_TOGSS_IS_UFP) && -+ (chip->conn_state != -+ policy_snk_transition_default) && -+ (chip->conn_state != -+ policy_src_prs_source_off) && -+ (chip->conn_state != policy_snk_prs_send_swap) && -+ (chip->conn_state != policy_snk_prs_assert_rp) && -+ (chip->conn_state != policy_snk_prs_source_on) && -+ (chip->conn_state != policy_snk_prs_transition_to_off)) { -+ if (!tcpm_check_vbus(chip)) -+ set_state_unattached(chip); -+ } else if ((chip->conn_state != -+ policy_src_transition_default) && -+ (chip->conn_state != -+ policy_src_prs_source_off) && -+ (chip->conn_state != policy_snk_prs_source_on)) { -+ tcpm_get_cc(chip, &cc1, &cc2); -+ if (chip->cc_state & CC_STATE_TOGSS_CC2) -+ cc1 = cc2; -+ if (cc1 == TYPEC_CC_VOLT_OPEN) -+ set_state_unattached(chip); -+ } else { -+ /* -+ * Detached may occurred at swap operations. So, DON'T ignore -+ * the EVENT_CC during swapping at all, check the connection -+ * after it. -+ */ -+ chip->work_continue |= EVENT_DELAY_CC; -+ } -+} -+ -+static void state_machine_typec(struct fusb30x_chip *chip) -+{ -+ u32 evt = 0; -+ -+ tcpc_alert(chip, &evt); -+ mux_alert(chip, &evt); -+ if (!evt) -+ goto BACK; -+ -+ if (chip->notify.is_cc_connected) -+ if (evt & (EVENT_CC | EVENT_DELAY_CC)) -+ fusb_try_detach(chip); -+ -+ if (evt & EVENT_RX) { -+ tcpm_get_message(chip); -+ if (PACKET_IS_CONTROL_MSG(chip->rec_head, CMT_SOFTRESET)) { -+ if (chip->notify.power_role) -+ set_state(chip, policy_src_softrst); -+ else -+ set_state(chip, policy_snk_softrst); -+ } -+ } -+ -+ if (evt & EVENT_TX) { -+ if (chip->tx_state == tx_success) -+ chip->msg_id++; -+ } -+ switch (chip->conn_state) { -+ case disabled: -+ fusb_state_disabled(chip, evt); -+ break; -+ case error_recovery: -+ set_state_unattached(chip); -+ break; -+ case unattached: -+ fusb_state_unattached(chip, evt); -+ break; -+ case attach_wait_sink: -+ fusb_state_attach_wait_sink(chip, evt); -+ break; -+ case attach_wait_source: -+ fusb_state_attach_wait_source(chip, evt); -+ break; -+ case attached_source: -+ fusb_state_attached_source(chip, evt); -+ break; -+ case attached_sink: -+ fusb_state_attached_sink(chip, evt); -+ break; -+ case attach_try_src: -+ fusb_state_try_attach(chip, evt, ROLE_MODE_DFP); -+ break; -+ case attach_try_snk: -+ fusb_state_try_attach(chip, evt, ROLE_MODE_UFP); -+ break; -+ -+ /* POWER DELIVERY */ -+ case policy_src_startup: -+ fusb_state_src_startup(chip, evt); -+ break; -+ case policy_src_discovery: -+ fusb_state_src_discovery(chip, evt); -+ break; -+ case policy_src_send_caps: -+ fusb_state_src_send_caps(chip, evt); -+ if (chip->conn_state != policy_src_negotiate_cap) -+ break; -+ case policy_src_negotiate_cap: -+ fusb_state_src_negotiate_cap(chip, evt); -+ -+ case policy_src_transition_supply: -+ fusb_state_src_transition_supply(chip, evt); -+ break; -+ case policy_src_cap_response: -+ fusb_state_src_cap_response(chip, evt); -+ break; -+ case policy_src_transition_default: -+ fusb_state_src_transition_default(chip, evt); -+ break; -+ case policy_src_ready: -+ fusb_state_src_ready(chip, evt); -+ break; -+ case policy_src_get_sink_caps: -+ fusb_state_src_get_sink_cap(chip, evt); -+ break; -+ case policy_src_send_hardrst: -+ fusb_state_src_send_hardreset(chip, evt); -+ break; -+ case policy_src_send_softrst: -+ fusb_state_src_send_softreset(chip, evt); -+ break; -+ case policy_src_softrst: -+ fusb_state_src_softreset(chip); -+ break; -+ -+ /* UFP */ -+ case policy_snk_startup: -+ fusb_state_snk_startup(chip, evt); -+ break; -+ case policy_snk_discovery: -+ fusb_state_snk_discovery(chip, evt); -+ break; -+ case policy_snk_wait_caps: -+ fusb_state_snk_wait_caps(chip, evt); -+ break; -+ case policy_snk_evaluate_caps: -+ fusb_state_snk_evaluate_caps(chip, evt); -+ /* without break */ -+ case policy_snk_select_cap: -+ fusb_state_snk_select_cap(chip, evt); -+ break; -+ case policy_snk_transition_sink: -+ fusb_state_snk_transition_sink(chip, evt); -+ break; -+ case policy_snk_transition_default: -+ fusb_state_snk_transition_default(chip, evt); -+ break; -+ case policy_snk_ready: -+ fusb_state_snk_ready(chip, evt); -+ break; -+ case policy_snk_send_hardrst: -+ fusb_state_snk_send_hardreset(chip, evt); -+ break; -+ case policy_snk_send_softrst: -+ fusb_state_snk_send_softreset(chip, evt); -+ break; -+ case policy_snk_softrst: -+ fusb_state_snk_softreset(chip); -+ break; -+ -+ /* -+ * PD Spec 1.0: PR SWAP: chap 8.3.3.6.3.1/2 -+ * VC SWAP: chap 8.3.3.7.1/2 -+ */ -+ case policy_src_prs_evaluate: -+ case policy_snk_prs_evaluate: -+ fusb_state_prs_evaluate(chip, evt); -+ break; -+ case policy_snk_prs_accept: -+ case policy_src_prs_accept: -+ fusb_state_prs_accept(chip, evt); -+ break; -+ case policy_snk_prs_reject: -+ case policy_src_prs_reject: -+ case policy_vcs_ufp_reject: -+ case policy_drs_dfp_reject: -+ case policy_drs_ufp_reject: -+ fusb_state_prs_reject(chip, evt); -+ break; -+ case policy_src_prs_transition_to_off: -+ fusb_state_src_prs_transition_to_off(chip, evt); -+ break; -+ case policy_src_prs_assert_rd: -+ fusb_state_src_prs_assert_rd(chip, evt); -+ break; -+ case policy_src_prs_source_off: -+ fusb_state_src_prs_source_off(chip, evt); -+ break; -+ case policy_snk_prs_send_swap: -+ case policy_src_prs_send_swap: -+ fusb_state_send_swap(chip, evt, CMT_PR_SWAP); -+ break; -+ case policy_snk_prs_transition_to_off: -+ fusb_state_snk_prs_transition_to_off(chip, evt); -+ break; -+ case policy_snk_prs_assert_rp: -+ fusb_state_snk_prs_assert_rp(chip, evt); -+ break; -+ case policy_snk_prs_source_on: -+ fusb_state_snk_prs_source_on(chip, evt); -+ break; -+ case policy_vcs_ufp_evaluate_swap: -+ fusb_state_vcs_ufp_evaluate_swap(chip, evt); -+ break; -+ case policy_vcs_ufp_accept: -+ fusb_state_vcs_ufp_accept(chip, evt); -+ break; -+ case policy_vcs_ufp_wait_for_dfp_vconn: -+ case policy_vcs_dfp_wait_for_ufp_vconn: -+ fusb_state_vcs_wait_for_vconn(chip, evt); -+ break; -+ case policy_vcs_ufp_turn_off_vconn: -+ case policy_vcs_dfp_turn_off_vconn: -+ fusb_state_vcs_set_vconn(chip, evt, false); -+ break; -+ case policy_vcs_ufp_turn_on_vconn: -+ case policy_vcs_dfp_turn_on_vconn: -+ fusb_state_vcs_set_vconn(chip, evt, true); -+ break; -+ case policy_vcs_ufp_send_ps_rdy: -+ case policy_vcs_dfp_send_ps_rdy: -+ fusb_state_vcs_send_ps_rdy(chip, evt); -+ break; -+ case policy_vcs_dfp_send_swap: -+ fusb_state_send_swap(chip, evt, CMT_VCONN_SWAP); -+ break; -+ case policy_drs_ufp_evaluate: -+ case policy_drs_dfp_evaluate: -+ fusb_state_drs_evaluate(chip, evt); -+ break; -+ case policy_drs_dfp_accept: -+ case policy_drs_ufp_accept: -+ fusb_state_drs_send_accept(chip, evt); -+ break; -+ case policy_drs_dfp_change: -+ case policy_drs_ufp_change: -+ fusb_state_drs_role_change(chip, evt); -+ break; -+ case policy_drs_ufp_send_swap: -+ case policy_drs_dfp_send_swap: -+ fusb_state_send_swap(chip, evt, CMT_DR_SWAP); -+ break; -+ -+ default: -+ break; -+ } -+ -+BACK: -+ if (chip->work_continue) { -+ queue_work(chip->fusb30x_wq, &chip->work); -+ return; -+ } -+ -+ if (!platform_get_device_irq_state(chip)) -+ fusb_irq_enable(chip); -+ else -+ queue_work(chip->fusb30x_wq, &chip->work); -+} -+ -+static irqreturn_t cc_interrupt_handler(int irq, void *dev_id) -+{ -+ struct fusb30x_chip *chip = dev_id; -+ -+ queue_work(chip->fusb30x_wq, &chip->work); -+ fusb_irq_disable(chip); -+ return IRQ_HANDLED; -+} -+ -+static int fusb_initialize_gpio(struct fusb30x_chip *chip) -+{ -+ chip->gpio_int = devm_gpiod_get_optional(chip->dev, "int-n", GPIOD_IN); -+ if (IS_ERR(chip->gpio_int)) -+ return PTR_ERR(chip->gpio_int); -+ -+ /* some board support vbus with other ways */ -+ chip->gpio_vbus_5v = devm_gpiod_get_optional(chip->dev, "vbus-5v", -+ GPIOD_OUT_LOW); -+ if (IS_ERR(chip->gpio_vbus_5v)) -+ dev_warn(chip->dev, -+ "Could not get named GPIO for VBus5V!\n"); -+ else -+ gpiod_set_raw_value(chip->gpio_vbus_5v, 0); -+ -+ chip->gpio_vbus_other = devm_gpiod_get_optional(chip->dev, -+ "vbus-other", -+ GPIOD_OUT_LOW); -+ if (IS_ERR(chip->gpio_vbus_other)) -+ dev_warn(chip->dev, -+ "Could not get named GPIO for VBusOther!\n"); -+ else -+ gpiod_set_raw_value(chip->gpio_vbus_other, 0); -+ -+ chip->gpio_discharge = devm_gpiod_get_optional(chip->dev, "discharge", -+ GPIOD_OUT_LOW); -+ if (IS_ERR(chip->gpio_discharge)) { -+ dev_warn(chip->dev, -+ "Could not get named GPIO for discharge!\n"); -+ chip->gpio_discharge = NULL; -+ } -+ -+ return 0; -+} -+ -+static enum hrtimer_restart fusb_timer_handler(struct hrtimer *timer) -+{ -+ int i; -+ -+ for (i = 0; i < fusb30x_port_used; i++) { -+ if (timer == &fusb30x_port_info[i]->timer_state_machine) { -+ if (fusb30x_port_info[i]->timer_state != T_DISABLED) -+ fusb30x_port_info[i]->timer_state = 0; -+ break; -+ } -+ -+ if (timer == &fusb30x_port_info[i]->timer_mux_machine) { -+ if (fusb30x_port_info[i]->timer_mux != T_DISABLED) -+ fusb30x_port_info[i]->timer_mux = 0; -+ break; -+ } -+ } -+ -+ if (i != fusb30x_port_used) -+ queue_work(fusb30x_port_info[i]->fusb30x_wq, -+ &fusb30x_port_info[i]->work); -+ -+ return HRTIMER_NORESTART; -+} -+ -+static void fusb_initialize_timer(struct fusb30x_chip *chip) -+{ -+ hrtimer_init(&chip->timer_state_machine, CLOCK_MONOTONIC, -+ HRTIMER_MODE_REL); -+ chip->timer_state_machine.function = fusb_timer_handler; -+ -+ hrtimer_init(&chip->timer_mux_machine, CLOCK_MONOTONIC, -+ HRTIMER_MODE_REL); -+ chip->timer_mux_machine.function = fusb_timer_handler; -+ -+ chip->timer_state = T_DISABLED; -+ chip->timer_mux = T_DISABLED; -+} -+ -+static void fusb302_work_func(struct work_struct *work) -+{ -+ struct fusb30x_chip *chip; -+ -+ chip = container_of(work, struct fusb30x_chip, work); -+ state_machine_typec(chip); -+} -+ -+static int fusb30x_probe(struct i2c_client *client, -+ const struct i2c_device_id *id) -+{ -+ struct fusb30x_chip *chip; -+ struct PD_CAP_INFO *pd_cap_info; -+ int ret; -+ char *string[2]; -+ -+ chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); -+ if (!chip) -+ return -ENOMEM; -+ -+ if (fusb30x_port_used == 0xff) -+ return -1; -+ -+ chip->port_num = fusb30x_port_used++; -+ fusb30x_port_info[chip->port_num] = chip; -+ -+ chip->dev = &client->dev; -+ chip->regmap = devm_regmap_init_i2c(client, &fusb302_regmap_config); -+ if (IS_ERR(chip->regmap)) { -+ dev_err(&client->dev, "Failed to allocate regmap!\n"); -+ return PTR_ERR(chip->regmap); -+ } -+ -+ ret = fusb_initialize_gpio(chip); -+ if (ret) -+ return ret; -+ -+ fusb_initialize_timer(chip); -+ -+ chip->fusb30x_wq = create_workqueue("fusb302_wq"); -+ INIT_WORK(&chip->work, fusb302_work_func); -+ -+ chip->role = ROLE_MODE_NONE; -+ chip->try_role = ROLE_MODE_NONE; -+ if (!of_property_read_string(chip->dev->of_node, "fusb302,role", -+ (const char **)&string[0])) { -+ if (!strcmp(string[0], "ROLE_MODE_DRP")) -+ chip->role = ROLE_MODE_DRP; -+ else if (!strcmp(string[0], "ROLE_MODE_DFP")) -+ chip->role = ROLE_MODE_DFP; -+ else if (!strcmp(string[0], "ROLE_MODE_UFP")) -+ chip->role = ROLE_MODE_UFP; -+ } -+ -+ if (chip->role == ROLE_MODE_NONE) { -+ dev_warn(chip->dev, -+ "Can't get property of role, set role to default DRP\n"); -+ chip->role = ROLE_MODE_DRP; -+ string[0] = "ROLE_MODE_DRP"; -+ } -+ -+ if (!of_property_read_string(chip->dev->of_node, "fusb302,try_role", -+ (const char **)&string[1])) { -+ if (!strcmp(string[1], "ROLE_MODE_DFP")) -+ chip->try_role = ROLE_MODE_DFP; -+ else if (!strcmp(string[1], "ROLE_MODE_UFP")) -+ chip->try_role = ROLE_MODE_UFP; -+ } -+ -+ if (chip->try_role == ROLE_MODE_NONE) -+ string[1] = "ROLE_MODE_NONE"; -+ -+ chip->vconn_supported = true; -+ tcpm_init(chip); -+ tcpm_set_rx_enable(chip, 0); -+ chip->conn_state = unattached; -+ tcpm_set_cc(chip, chip->role); -+ -+ chip->n_caps_used = 1; -+ chip->source_power_supply[0] = 0x64; -+ chip->source_max_current[0] = 0x96; -+ -+ pd_cap_info = &chip->pd_cap_info; -+ pd_cap_info->dual_role_power = 1; -+ pd_cap_info->data_role_swap = 1; -+ -+ pd_cap_info->externally_powered = 1; -+ pd_cap_info->usb_suspend_support = 0; -+ pd_cap_info->usb_communications_cap = 0; -+ pd_cap_info->supply_type = 0; -+ pd_cap_info->peak_current = 0; -+ -+ chip->extcon = devm_extcon_dev_allocate(&client->dev, fusb302_cable); -+ if (IS_ERR(chip->extcon)) { -+ dev_err(&client->dev, "allocat extcon failed\n"); -+ return PTR_ERR(chip->extcon); -+ } -+ -+ ret = devm_extcon_dev_register(&client->dev, chip->extcon); -+ if (ret) { -+ dev_err(&client->dev, "failed to register extcon: %d\n", -+ ret); -+ return ret; -+ } -+ -+ ret = extcon_set_property_capability(chip->extcon, EXTCON_USB, -+ EXTCON_PROP_USB_TYPEC_POLARITY); -+ if (ret) { -+ dev_err(&client->dev, -+ "failed to set USB property capability: %d\n", -+ ret); -+ return ret; -+ } -+ -+ ret = extcon_set_property_capability(chip->extcon, EXTCON_USB_HOST, -+ EXTCON_PROP_USB_TYPEC_POLARITY); -+ if (ret) { -+ dev_err(&client->dev, -+ "failed to set USB_HOST property capability: %d\n", -+ ret); -+ return ret; -+ } -+ -+ ret = extcon_set_property_capability(chip->extcon, EXTCON_DISP_DP, -+ EXTCON_PROP_USB_TYPEC_POLARITY); -+ if (ret) { -+ dev_err(&client->dev, -+ "failed to set DISP_DP property capability: %d\n", -+ ret); -+ return ret; -+ } -+ -+ ret = extcon_set_property_capability(chip->extcon, EXTCON_USB, -+ EXTCON_PROP_USB_SS); -+ if (ret) { -+ dev_err(&client->dev, -+ "failed to set USB USB_SS property capability: %d\n", -+ ret); -+ return ret; -+ } -+ -+ ret = extcon_set_property_capability(chip->extcon, EXTCON_USB_HOST, -+ EXTCON_PROP_USB_SS); -+ if (ret) { -+ dev_err(&client->dev, -+ "failed to set USB_HOST USB_SS property capability: %d\n", -+ ret); -+ return ret; -+ } -+ -+ ret = extcon_set_property_capability(chip->extcon, EXTCON_DISP_DP, -+ EXTCON_PROP_USB_SS); -+ if (ret) { -+ dev_err(&client->dev, -+ "failed to set DISP_DP USB_SS property capability: %d\n", -+ ret); -+ return ret; -+ } -+ -+ ret = extcon_set_property_capability(chip->extcon, EXTCON_CHG_USB_FAST, -+ EXTCON_PROP_USB_TYPEC_POLARITY); -+ if (ret) { -+ dev_err(&client->dev, -+ "failed to set USB_PD property capability: %d\n", ret); -+ return ret; -+ } -+ -+ i2c_set_clientdata(client, chip); -+ -+ spin_lock_init(&chip->irq_lock); -+ chip->enable_irq = 1; -+ -+ chip->gpio_int_irq = gpiod_to_irq(chip->gpio_int); -+ if (chip->gpio_int_irq < 0) { -+ dev_err(&client->dev, -+ "Unable to request IRQ for INT_N GPIO! %d\n", -+ ret); -+ ret = chip->gpio_int_irq; -+ goto IRQ_ERR; -+ } -+ -+ ret = devm_request_threaded_irq(&client->dev, -+ chip->gpio_int_irq, -+ NULL, -+ cc_interrupt_handler, -+ IRQF_ONESHOT | IRQF_TRIGGER_LOW, -+ client->name, -+ chip); -+ if (ret) { -+ dev_err(&client->dev, "irq request failed\n"); -+ goto IRQ_ERR; -+ } -+ -+ dev_info(chip->dev, -+ "port %d probe success with role %s, try_role %s\n", -+ chip->port_num, string[0], string[1]); -+ -+ return 0; -+ -+IRQ_ERR: -+ destroy_workqueue(chip->fusb30x_wq); -+ return ret; -+} -+ -+static int fusb30x_remove(struct i2c_client *client) -+{ -+ struct fusb30x_chip *chip = i2c_get_clientdata(client); -+ -+ destroy_workqueue(chip->fusb30x_wq); -+ return 0; -+} -+ -+static void fusb30x_shutdown(struct i2c_client *client) -+{ -+ struct fusb30x_chip *chip = i2c_get_clientdata(client); -+ -+ if (chip->gpio_vbus_5v) -+ gpiod_set_value(chip->gpio_vbus_5v, 0); -+ if (chip->gpio_discharge) { -+ gpiod_set_value(chip->gpio_discharge, 1); -+ msleep(100); -+ gpiod_set_value(chip->gpio_discharge, 0); -+ } -+} -+ -+static const struct of_device_id fusb30x_dt_match[] = { -+ { .compatible = FUSB30X_I2C_DEVICETREE_NAME }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, fusb30x_dt_match); -+ -+static const struct i2c_device_id fusb30x_i2c_device_id[] = { -+ { FUSB30X_I2C_DRIVER_NAME, 0 }, -+ {} -+}; -+MODULE_DEVICE_TABLE(i2c, fusb30x_i2c_device_id); -+ -+static struct i2c_driver fusb30x_driver = { -+ .driver = { -+ .name = FUSB30X_I2C_DRIVER_NAME, -+ .of_match_table = of_match_ptr(fusb30x_dt_match), -+ }, -+ .probe = fusb30x_probe, -+ .remove = fusb30x_remove, -+ .shutdown = fusb30x_shutdown, -+ .id_table = fusb30x_i2c_device_id, -+}; -+ -+module_i2c_driver(fusb30x_driver); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("zain wang "); -+MODULE_DESCRIPTION("fusb302 typec pd driver"); -diff --git a/drivers/staging/fusb30x/fusb30x.h b/drivers/staging/fusb30x/fusb30x.h -new file mode 100644 -index 000000000..4f5ca64f7 ---- /dev/null -+++ b/drivers/staging/fusb30x/fusb30x.h -@@ -0,0 +1,552 @@ -+/* -+ * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd -+ * Author: Zain Wang -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2, as published by the Free Software Foundation. -+ * -+ * Some ideas are from chrome ec and fairchild GPL fusb302 driver. -+ */ -+ -+#ifndef FUSB302_H -+#define FUSB302_H -+ -+#include -+#include -+ -+const char *FUSB_DT_INTERRUPT_INTN = "fsc_interrupt_int_n"; -+#define FUSB_DT_GPIO_INTN "fairchild,int_n" -+#define FUSB_DT_GPIO_VBUS_5V "fairchild,vbus5v" -+#define FUSB_DT_GPIO_VBUS_OTHER "fairchild,vbusOther" -+ -+#define FUSB30X_I2C_DRIVER_NAME "fusb302" -+#define FUSB30X_I2C_DEVICETREE_NAME "fairchild,fusb302" -+ -+/* FUSB300 Register Addresses */ -+#define FUSB_REG_DEVICEID 0x01 -+#define FUSB_REG_SWITCHES0 0x02 -+#define FUSB_REG_SWITCHES1 0x03 -+#define FUSB_REG_MEASURE 0x04 -+#define FUSB_REG_SLICE 0x05 -+#define FUSB_REG_CONTROL0 0x06 -+#define FUSB_REG_CONTROL1 0x07 -+#define FUSB_REG_CONTROL2 0x08 -+#define FUSB_REG_CONTROL3 0x09 -+#define FUSB_REG_MASK 0x0A -+#define FUSB_REG_POWER 0x0B -+#define FUSB_REG_RESET 0x0C -+#define FUSB_REG_OCPREG 0x0D -+#define FUSB_REG_MASKA 0x0E -+#define FUSB_REG_MASKB 0x0F -+#define FUSB_REG_CONTROL4 0x10 -+#define FUSB_REG_STATUS0A 0x3C -+#define FUSB_REG_STATUS1A 0x3D -+#define FUSB_REG_INTERRUPTA 0x3E -+#define FUSB_REG_INTERRUPTB 0x3F -+#define FUSB_REG_STATUS0 0x40 -+#define FUSB_REG_STATUS1 0x41 -+#define FUSB_REG_INTERRUPT 0x42 -+#define FUSB_REG_FIFO 0x43 -+ -+enum connection_state { -+ disabled = 0, -+ error_recovery, -+ unattached, -+ attach_wait_sink, -+ attach_wait_source, -+ attached_source, -+ attached_sink, -+ -+ policy_src_startup, -+ policy_src_send_caps, -+ policy_src_discovery, -+ policy_src_negotiate_cap, -+ policy_src_cap_response, -+ policy_src_transition_supply, -+ policy_src_transition_default, -+ -+ policy_src_ready, -+ policy_src_get_sink_caps, -+ -+ policy_src_send_softrst, -+ policy_src_softrst, -+ policy_src_send_hardrst, -+ -+ policy_snk_startup, -+ policy_snk_discovery, -+ policy_snk_wait_caps, -+ policy_snk_evaluate_caps, -+ policy_snk_select_cap, -+ policy_snk_transition_sink, -+ policy_snk_ready, -+ -+ policy_snk_send_softrst, -+ policy_snk_softrst, -+ policy_snk_send_hardrst, -+ -+ policy_snk_transition_default, -+ -+ /* PR SWAP */ -+ policy_src_prs_evaluate, -+ policy_src_prs_accept, -+ policy_src_prs_transition_to_off, -+ policy_src_prs_source_off, -+ policy_src_prs_assert_rd, -+ policy_src_prs_reject, -+ policy_src_prs_send_swap, -+ -+ policy_snk_prs_evaluate, -+ policy_snk_prs_accept, -+ policy_snk_prs_transition_to_off, -+ policy_snk_prs_source_on, -+ policy_snk_prs_assert_rp, -+ policy_snk_prs_reject, -+ policy_snk_prs_send_swap, -+ -+ /* VC SWAP */ -+ policy_vcs_dfp_send_swap, -+ policy_vcs_dfp_wait_for_ufp_vconn, -+ policy_vcs_dfp_turn_off_vconn, -+ policy_vcs_dfp_turn_on_vconn, -+ policy_vcs_dfp_send_ps_rdy, -+ -+ policy_vcs_ufp_evaluate_swap, -+ policy_vcs_ufp_reject, -+ policy_vcs_ufp_accept, -+ policy_vcs_ufp_wait_for_dfp_vconn, -+ policy_vcs_ufp_turn_off_vconn, -+ policy_vcs_ufp_turn_on_vconn, -+ policy_vcs_ufp_send_ps_rdy, -+ -+ policy_drs_ufp_evaluate, -+ policy_drs_ufp_accept, -+ policy_drs_ufp_reject, -+ policy_drs_ufp_change, -+ policy_drs_ufp_send_swap, -+ -+ policy_drs_dfp_evaluate, -+ policy_drs_dfp_accept, -+ policy_drs_dfp_reject, -+ policy_drs_dfp_change, -+ policy_drs_dfp_send_swap, -+ -+ attach_try_src, -+ attach_try_snk, -+}; -+ -+enum vdm_state { -+ VDM_STATE_DISCOVERY_ID, -+ VDM_STATE_DISCOVERY_SVID, -+ VDM_STATE_DISCOVERY_MODES, -+ VDM_STATE_ENTER_MODE, -+ VDM_STATE_UPDATE_STATUS, -+ VDM_STATE_DP_CONFIG, -+ VDM_STATE_NOTIFY, -+ VDM_STATE_READY, -+ VDM_STATE_ERR, -+}; -+ -+enum tcpm_rp_value { -+ TYPEC_RP_USB = 0, -+ TYPEC_RP_1A5 = 1, -+ TYPEC_RP_3A0 = 2, -+ TYPEC_RP_RESERVED = 3, -+}; -+ -+enum role_mode { -+ ROLE_MODE_NONE, -+ ROLE_MODE_DRP, -+ ROLE_MODE_UFP, -+ ROLE_MODE_DFP, -+ ROLE_MODE_ASS, -+}; -+ -+#define SBF(s, v) ((s) << (v)) -+#define SWITCHES0_PDWN1 SBF(1, 0) -+#define SWITCHES0_PDWN2 SBF(1, 1) -+#define SWITCHES0_MEAS_CC1 SBF(1, 2) -+#define SWITCHES0_MEAS_CC2 SBF(1, 3) -+#define SWITCHES0_VCONN_CC1 SBF(1, 4) -+#define SWITCHES0_VCONN_CC2 SBF(1, 5) -+#define SWITCHES0_PU_EN1 SBF(1, 6) -+#define SWITCHES0_PU_EN2 SBF(1, 7) -+ -+#define SWITCHES1_TXCC1 SBF(1, 0) -+#define SWITCHES1_TXCC2 SBF(1, 1) -+#define SWITCHES1_AUTO_CRC SBF(1, 2) -+#define SWITCHES1_DATAROLE SBF(1, 4) -+#define SWITCHES1_SPECREV SBF(3, 5) -+#define SWITCHES1_POWERROLE SBF(1, 7) -+ -+#define MEASURE_MDAC SBF(0x3f, 0) -+#define MEASURE_VBUS SBF(1, 6) -+ -+#define SLICE_SDAC SBF(0x3f, 0) -+#define SLICE_SDAC_HYS SBF(3, 6) -+ -+#define CONTROL0_TX_START SBF(1, 0) -+#define CONTROL0_AUTO_PRE SBF(1, 1) -+#define CONTROL0_HOST_CUR SBF(3, 2) -+#define CONTROL0_HOST_CUR_USB SBF(1, 2) -+#define CONTROL0_HOST_CUR_1A5 SBF(2, 2) -+#define CONTROL0_HOST_CUR_3A0 SBF(3, 2) -+#define CONTROL0_INT_MASK SBF(1, 5) -+#define CONTROL0_TX_FLUSH SBF(1, 6) -+ -+#define CONTROL1_ENSOP1 SBF(1, 0) -+#define CONTROL1_ENSOP2 SBF(1, 1) -+#define CONTROL1_RX_FLUSH SBF(1, 2) -+#define CONTROL1_BIST_MODE2 SBF(1, 4) -+#define CONTROL1_ENSOP1DB SBF(1, 5) -+#define CONTROL1_ENSOP2DB SBF(1, 6) -+ -+#define CONTROL2_TOGGLE SBF(1, 0) -+#define CONTROL2_MODE SBF(3, 1) -+#define CONTROL2_MODE_NONE 0 -+#define CONTROL2_MODE_DFP SBF(3, 1) -+#define CONTROL2_MODE_UFP SBF(2, 1) -+#define CONTROL2_MODE_DRP SBF(1, 1) -+#define CONTROL2_WAKE_EN SBF(1, 3) -+#define CONTROL2_TOG_RD_ONLY SBF(1, 5) -+#define CONTROL2_TOG_SAVE_PWR1 SBF(1, 6) -+#define CONTROL2_TOG_SAVE_PWR2 SBF(1, 7) -+ -+#define CONTROL3_AUTO_RETRY SBF(1, 0) -+#define CONTROL3_N_RETRIES SBF(3, 1) -+#define CONTROL3_AUTO_SOFTRESET SBF(1, 3) -+#define CONTROL3_AUTO_HARDRESET SBF(1, 4) -+#define CONTROL3_SEND_HARDRESET SBF(1, 6) -+ -+#define MASK_M_BC_LVL SBF(1, 0) -+#define MASK_M_COLLISION SBF(1, 1) -+#define MASK_M_WAKE SBF(1, 2) -+#define MASK_M_ALERT SBF(1, 3) -+#define MASK_M_CRC_CHK SBF(1, 4) -+#define MASK_M_COMP_CHNG SBF(1, 5) -+#define MASK_M_ACTIVITY SBF(1, 6) -+#define MASK_M_VBUSOK SBF(1, 7) -+ -+#define POWER_PWR SBF(0xf, 0) -+ -+#define RESET_SW_RESET SBF(1, 0) -+#define RESET_PD_RESET SBF(1, 1) -+ -+#define MASKA_M_HARDRST SBF(1, 0) -+#define MASKA_M_SOFTRST SBF(1, 1) -+#define MASKA_M_TXSENT SBF(1, 2) -+#define MASKA_M_HARDSENT SBF(1, 3) -+#define MASKA_M_RETRYFAIL SBF(1, 4) -+#define MASKA_M_SOFTFAIL SBF(1, 5) -+#define MASKA_M_TOGDONE SBF(1, 6) -+#define MASKA_M_OCP_TEMP SBF(1, 7) -+ -+#define MASKB_M_GCRCSEND SBF(1, 0) -+ -+#define CONTROL4_TOG_USRC_EXIT SBF(1, 0) -+ -+#define MDAC_1P6V 0x26 -+ -+#define STATUS0A_HARDRST SBF(1, 0) -+#define STATUS0A_SOFTRST SBF(1, 1) -+#define STATUS0A_POWER23 SBF(3, 2) -+#define STATUS0A_RETRYFAIL SBF(1, 4) -+#define STATUS0A_SOFTFAIL SBF(1, 5) -+#define STATUS0A_TOGDONE SBF(1, 6) -+#define STATUS0A_M_OCP_TEMP SBF(1, 7) -+ -+#define STATUS1A_RXSOP SBF(1, 0) -+#define STATUS1A_RXSOP1DB SBF(1, 1) -+#define STATUS1A_RXSOP2DB SBF(1, 2) -+#define STATUS1A_TOGSS SBF(7, 3) -+#define CC_STATE_TOGSS_CC1 SBF(1, 0) -+#define CC_STATE_TOGSS_CC2 SBF(1, 1) -+#define CC_STATE_TOGSS_IS_UFP SBF(1, 2) -+ -+#define INTERRUPTA_HARDRST SBF(1, 0) -+#define INTERRUPTA_SOFTRST SBF(1, 1) -+#define INTERRUPTA_TXSENT SBF(1, 2) -+#define INTERRUPTA_HARDSENT SBF(1, 3) -+#define INTERRUPTA_RETRYFAIL SBF(1, 4) -+#define INTERRUPTA_SOFTFAIL SBF(1, 5) -+#define INTERRUPTA_TOGDONE SBF(1, 6) -+#define INTERRUPTA_OCP_TEMP SBF(1, 7) -+ -+#define INTERRUPTB_GCRCSENT SBF(1, 0) -+ -+#define STATUS0_BC_LVL SBF(3, 0) -+#define STATUS0_WAKE SBF(1, 2) -+#define STATUS0_ALERT SBF(1, 3) -+#define STATUS0_CRC_CHK SBF(1, 4) -+#define STATUS0_COMP SBF(1, 5) -+#define STATUS0_ACTIVITY SBF(1, 6) -+#define STATUS0_VBUSOK SBF(1, 7) -+ -+#define STATUS1_OCP SBF(1, 0) -+#define STATUS1_OVRTEMP SBF(1, 1) -+#define STATUS1_TX_FULL SBF(1, 2) -+#define STATUS1_TX_EMPTY SBF(1, 3) -+#define STATUS1_RX_FULL SBF(1, 4) -+#define STATUS1_RX_EMPTY SBF(1, 5) -+#define STATUS1_RXSOP1 SBF(1, 6) -+#define STATUS1_RXSOP2 SBF(1, 7) -+ -+#define INTERRUPT_BC_LVL SBF(1, 0) -+#define INTERRUPT_COLLISION SBF(1, 1) -+#define INTERRUPT_WAKE SBF(1, 2) -+#define INTERRUPT_ALERT SBF(1, 3) -+#define INTERRUPT_CRC_CHK SBF(1, 4) -+#define INTERRUPT_COMP_CHNG SBF(1, 5) -+#define INTERRUPT_ACTIVITY SBF(1, 6) -+#define INTERRUPT_VBUSOK SBF(1, 7) -+ -+#define FUSB_TKN_TXON 0xa1 -+#define FUSB_TKN_SYNC1 0x12 -+#define FUSB_TKN_SYNC2 0x13 -+#define FUSB_TKN_SYNC3 0x1b -+#define FUSB_TKN_RST1 0x15 -+#define FUSB_TKN_RST2 0x16 -+#define FUSB_TKN_PACKSYM 0x80 -+#define FUSB_TKN_JAMCRC 0xff -+#define FUSB_TKN_EOP 0x14 -+#define FUSB_TKN_TXOFF 0xfe -+ -+/* USB PD Control Message Types */ -+#define CONTROLMESSAGE 0 -+#define CMT_GOODCRC 1 -+#define CMT_GOTOMIN 2 -+#define CMT_ACCEPT 3 -+#define CMT_REJECT 4 -+#define CMT_PING 5 -+#define CMT_PS_RDY 6 -+#define CMT_GETSOURCECAP 7 -+#define CMT_GETSINKCAP 8 -+#define CMT_DR_SWAP 9 -+#define CMT_PR_SWAP 10 -+#define CMT_VCONN_SWAP 11 -+#define CMT_WAIT 12 -+#define CMT_SOFTRESET 13 -+ -+/* USB PD Data Message Types */ -+#define DATAMESSAGE 1 -+#define DMT_SOURCECAPABILITIES 1 -+#define DMT_REQUEST 2 -+#define DMT_BIST 3 -+#define DMT_SINKCAPABILITIES 4 -+#define DMT_VENDERDEFINED 15 -+ -+/* VDM Command Types */ -+#define VDM_DISCOVERY_ID 0X01 -+#define VDM_DISCOVERY_SVIDS 0X02 -+#define VDM_DISCOVERY_MODES 0X03 -+#define VDM_ENTER_MODE 0X04 -+#define VDM_EXIT_MODE 0X05 -+#define VDM_ATTENTION 0X06 -+#define VDM_DP_STATUS_UPDATE 0X10 -+#define VDM_DP_CONFIG 0X11 -+ -+#define VDM_TYPE_INIT 0 -+#define VDM_TYPE_ACK 1 -+#define VDM_TYPE_NACK 2 -+#define VDM_TYPE_BUSY 3 -+ -+/* 200ms at least, 1 cycle about 6ms */ -+#define N_DEBOUNCE_CNT 33 -+#define N_CAPS_COUNT 50 -+#define N_HARDRESET_COUNT 0 -+ -+#define T_NO_RESPONSE 5000 -+#define T_SRC_RECOVER 830 -+#define T_TYPEC_SEND_SOURCECAP 100 -+#define T_SENDER_RESPONSE 30 -+#define T_SRC_TRANSITION 30 -+#define T_TYPEC_SINK_WAIT_CAP 500 -+#define T_PS_TRANSITION 500 -+#define T_BMC_TIMEOUT 5 -+#define T_PS_HARD_RESET_MAX 35 -+#define T_SAFE_0V 650 -+#define T_SRC_TURN_ON 275 -+#define T_SRC_RECOVER_MAX 1000 -+#define T_PD_SOURCE_OFF 920 -+#define T_PD_SOURCE_ON 480 -+#define T_PD_SWAP_SOURCE_START 20 -+#define T_PD_VCONN_SRC_ON 100 -+#define T_PD_TRY_DRP 75 -+ -+#define T_NO_TRIGGER 500 -+#define T_DISABLED 0xffff -+ -+#define PD_HEADER_CNT(header) (((header) >> 12) & 7) -+#define PD_HEADER_TYPE(header) ((header) & 0xF) -+#define PD_HEADER_ID(header) (((header) >> 9) & 7) -+ -+#define VDM_HEADER_TYPE(header) (((header) >> 6) & 3) -+#define VDMHEAD_CMD_TYPE_MASK (3 << 6) -+#define VDMHEAD_CMD_MASK (0x1f << 0) -+#define VDMHEAD_STRUCT_TYPE_MASK BIT(15) -+ -+#define GET_VDMHEAD_CMD_TYPE(head) ((head & VDMHEAD_CMD_TYPE_MASK) >> 6) -+#define GET_VDMHEAD_CMD(head) (head & VDMHEAD_CMD_MASK) -+#define GET_VDMHEAD_STRUCT_TYPE(head) ((head & VDMHEAD_STRUCT_TYPE_MASK) >> 15) -+ -+#define DP_STATUS_MASK 0x000000ff -+#define DP_STATUS_HPD_STATE BIT(7) -+ -+#define GET_DP_STATUS(status) (status & DP_STATUS_MASK) -+#define GET_DP_STATUS_HPD(status) ((status & DP_STATUS_HPD_STATE) >> 7) -+ -+#define VDM_IDHEAD_USBVID_MASK (0xffff << 0) -+#define VDM_IDHEAD_MODALSUPPORT_MASK BIT(26) -+#define VDM_IDHEAD_PRODUCTTYPE (7 << 27) -+#define VDM_IDHEAD_USBDEVICE BIT(30) -+#define VDM_IDHEAD_USBHOST BIT(30) -+ -+#define CAP_POWER_TYPE(PDO) ((PDO >> 30) & 3) -+#define CAP_FPDO_VOLTAGE(PDO) ((PDO >> 10) & 0x3ff) -+#define CAP_VPDO_VOLTAGE(PDO) ((PDO >> 20) & 0x3ff) -+#define CAP_FPDO_CURRENT(PDO) ((PDO >> 0) & 0x3ff) -+#define CAP_VPDO_CURRENT(PDO) ((PDO >> 0) & 0x3ff) -+ -+enum CC_ORIENTATION { -+ NONE, -+ CC1, -+ CC2, -+}; -+ -+enum typec_cc_polarity { -+ TYPEC_POLARITY_CC1, -+ TYPEC_POLARITY_CC2, -+}; -+ -+enum CC_MODE { -+ CC_PULL_UP, -+ CC_PULL_DOWN, -+ CC_PULL_NONE, -+}; -+ -+enum typec_power_role { -+ POWER_ROLE_SINK = 0, -+ POWER_ROLE_SOURCE, -+}; -+ -+enum typec_data_role { -+ DATA_ROLE_UFP = 0, -+ DATA_ROLE_DFP, -+}; -+ -+struct notify_info { -+ enum CC_ORIENTATION orientation; -+ /* 0 UFP : 1 DFP */ -+ enum typec_power_role power_role; -+ enum typec_data_role data_role; -+ -+ bool is_cc_connected; -+ bool is_pd_connected; -+ -+ bool is_enter_mode; -+ int pin_assignment_support; -+ int pin_assignment_def; -+ bool attention; -+ u32 dp_status; -+ u32 dp_caps; -+}; -+ -+enum tx_state { -+ tx_idle, -+ tx_busy, -+ tx_failed, -+ tx_success -+}; -+ -+struct PD_CAP_INFO { -+ u32 peak_current; -+ u32 specification_revision; -+ u32 externally_powered; -+ u32 usb_suspend_support; -+ u32 usb_communications_cap; -+ u32 dual_role_power; -+ u32 data_role_swap; -+ u32 supply_type; -+}; -+ -+struct fusb30x_chip { -+ struct i2c_client *client; -+ struct device *dev; -+ struct regmap *regmap; -+ struct work_struct work; -+ struct workqueue_struct *fusb30x_wq; -+ struct hrtimer timer_state_machine; -+ struct hrtimer timer_mux_machine; -+ struct PD_CAP_INFO pd_cap_info; -+ struct notify_info notify; -+ struct notify_info notify_cmp; -+ struct extcon_dev *extcon; -+ enum connection_state conn_state; -+ struct gpio_desc *gpio_vbus_5v; -+ struct gpio_desc *gpio_vbus_other; -+ struct gpio_desc *gpio_int; -+ struct gpio_desc *gpio_discharge; -+ int timer_state; -+ int timer_mux; -+ int port_num; -+ u32 work_continue; -+ spinlock_t irq_lock; -+ int gpio_int_irq; -+ int enable_irq; -+ -+ /* -+ * --------------------------------- -+ * | role 0x03 << 2, | cc_use 0x03 | -+ * | src 1 << 2, | cc1 1 | -+ * | snk 2 << 2, | cc2 2 | -+ * --------------------------------- -+ */ -+ u8 cc_state; -+ int cc1; -+ int cc2; -+ enum typec_cc_polarity cc_polarity; -+ u8 val_tmp; -+ u8 debounce_cnt; -+ int sub_state; -+ int caps_counter; -+ u32 send_load[7]; -+ u32 rec_load[7]; -+ u16 send_head; -+ u16 rec_head; -+ int msg_id; -+ enum tx_state tx_state; -+ int hardrst_count; -+ u32 source_power_supply[7]; -+ /* 50mv unit */ -+ u32 source_max_current[7]; -+ /* 10ma uint*/ -+ int pos_power; -+ /* -+ * if PartnerCap[0] == 0xffffffff -+ * show Partner Device do not support supply -+ */ -+ u32 partner_cap[7]; -+ int n_caps_used; -+ int vdm_state; -+ int vdm_substate; -+ int vdm_send_state; -+ u16 vdm_svid[12]; -+ int vdm_svid_num; -+ u32 vdm_id; -+ u8 chip_id; -+ bool vconn_enabled; -+ bool is_pd_support; -+ int pd_output_vol; -+ int pd_output_cur; -+ int cc_meas_high; -+ int cc_meas_low; -+ bool vbus_begin; -+ -+ enum role_mode role; -+ bool vconn_supported; -+ bool try_role_complete; -+ enum role_mode try_role; -+}; -+ -+#endif /* FUSB302_H */ -+ diff --git a/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/board-pbp-add-dp-alt-mode.patch.disabled b/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/board-pbp-add-dp-alt-mode.patch.disabled deleted file mode 100644 index aecb9c3b407d..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/board-pbp-add-dp-alt-mode.patch.disabled +++ /dev/null @@ -1,447 +0,0 @@ -From a1bbffd1cbb883be7fe3da1d09c29d57cfbeb2da Mon Sep 17 00:00:00 2001 -From: Dan Johansen -Date: Tue, 2 Jun 2020 20:20:29 +0200 -Subject: [PATCH] add-dp-alt-mode-to-PBP - ---- - .../boot/dts/rockchip/rk3399-pinebook-pro.dts | 5 + - drivers/phy/rockchip/phy-rockchip-typec.c | 17 +++ - drivers/usb/typec/altmodes/displayport.c | 58 +++++++- - drivers/usb/typec/bus.c | 8 +- - drivers/usb/typec/tcpm/tcpm.c | 139 +++++++++++++++++- - 5 files changed, 221 insertions(+), 6 deletions(-) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts b/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts -index c49982dfd8fc..66cf08e8506f 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts -@@ -374,6 +374,7 @@ mains_charger: dc-charger { - - &cdn_dp { - status = "okay"; -+ extcon = <&fusb0>; - }; - - &cpu_b0 { -@@ -708,6 +709,9 @@ connector { - ; - try-power-role = "sink"; - -+ extcon-cables = <1 2 5 6 9 10 12 44>; -+ typec-altmodes = <0xff01 1 0x001c0000 1>; -+ - ports { - #address-cells = <1>; - #size-cells = <0>; -@@ -958,6 +962,7 @@ spiflash: flash@0 { - }; - - &tcphy0 { -+ extcon = <&fusb0>; - status = "okay"; - }; - -diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c -index 24563160197f..f5b497b4b97e 100644 ---- a/drivers/phy/rockchip/phy-rockchip-typec.c -+++ b/drivers/phy/rockchip/phy-rockchip-typec.c -@@ -40,6 +40,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -1160,6 +1161,22 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev) - dev_err(dev, "Invalid or missing extcon\n"); - return PTR_ERR(tcphy->extcon); - } -+ } else { -+ extcon_set_property_capability(tcphy->extcon, EXTCON_USB, -+ EXTCON_PROP_USB_SS); -+ extcon_set_property_capability(tcphy->extcon, EXTCON_USB_HOST, -+ EXTCON_PROP_USB_SS); -+ extcon_set_property_capability(tcphy->extcon, EXTCON_DISP_DP, -+ EXTCON_PROP_USB_SS); -+ extcon_set_property_capability(tcphy->extcon, EXTCON_USB, -+ EXTCON_PROP_USB_TYPEC_POLARITY); -+ extcon_set_property_capability(tcphy->extcon, EXTCON_USB_HOST, -+ EXTCON_PROP_USB_TYPEC_POLARITY); -+ extcon_set_property_capability(tcphy->extcon, EXTCON_DISP_DP, -+ EXTCON_PROP_USB_TYPEC_POLARITY); -+ extcon_sync(tcphy->extcon, EXTCON_USB); -+ extcon_sync(tcphy->extcon, EXTCON_USB_HOST); -+ extcon_sync(tcphy->extcon, EXTCON_DISP_DP); - } - - pm_runtime_enable(dev); -diff --git a/drivers/usb/typec/altmodes/displayport.c b/drivers/usb/typec/altmodes/displayport.c -index 0edfb89e04a8..40dd68c20159 100644 ---- a/drivers/usb/typec/altmodes/displayport.c -+++ b/drivers/usb/typec/altmodes/displayport.c -@@ -9,6 +9,8 @@ - */ - - #include -+#include -+#include - #include - #include - #include -@@ -134,15 +136,53 @@ static int dp_altmode_status_update(struct dp_altmode *dp) - return ret; - } - -+static void dp_altmode_update_extcon(struct dp_altmode *dp, bool disconnect) { -+ const struct device *dev = &dp->port->dev; -+ struct extcon_dev* edev = NULL; -+ -+ while (dev) { -+ edev = extcon_find_edev_by_node(dev->of_node); -+ if(!IS_ERR(edev)) { -+ break; -+ } -+ dev = dev->parent; -+ } -+ -+ if (IS_ERR_OR_NULL(edev)) { -+ return; -+ } -+ -+ if (disconnect || !dp->data.conf) { -+ extcon_set_state_sync(edev, EXTCON_DISP_DP, false); -+ } else { -+ union extcon_property_value extcon_true = { .intval = true }; -+ extcon_set_state(edev, EXTCON_DISP_DP, true); -+ if (DP_CONF_GET_PIN_ASSIGN(dp->data.conf) & DP_PIN_ASSIGN_MULTI_FUNC_MASK) { -+ extcon_set_state_sync(edev, EXTCON_USB_HOST, true); -+ extcon_set_property(edev, EXTCON_DISP_DP, EXTCON_PROP_USB_SS, -+ extcon_true); -+ } else { -+ extcon_set_state_sync(edev, EXTCON_USB_HOST, false); -+ } -+ extcon_sync(edev, EXTCON_DISP_DP); -+ extcon_set_state_sync(edev, EXTCON_USB, false); -+ } -+ -+} -+ - static int dp_altmode_configured(struct dp_altmode *dp) - { - int ret; - - sysfs_notify(&dp->alt->dev.kobj, "displayport", "configuration"); - -- if (!dp->data.conf) -+ if (!dp->data.conf) { -+ dp_altmode_update_extcon(dp, true); - return typec_altmode_notify(dp->alt, TYPEC_STATE_USB, - &dp->data); -+ } -+ -+ dp_altmode_update_extcon(dp, false); - - ret = dp_altmode_notify(dp); - if (ret) -@@ -169,9 +209,11 @@ static int dp_altmode_configure_vdm(struct dp_altmode *dp, u32 conf) - if (ret) { - if (DP_CONF_GET_PIN_ASSIGN(dp->data.conf)) - dp_altmode_notify(dp); -- else -+ else { -+ dp_altmode_update_extcon(dp, true); - typec_altmode_notify(dp->alt, TYPEC_STATE_USB, - &dp->data); -+ } - } - - return ret; -@@ -210,6 +252,8 @@ static void dp_altmode_work(struct work_struct *work) - case DP_STATE_EXIT: - if (typec_altmode_exit(dp->alt)) - dev_err(&dp->alt->dev, "Exit Mode Failed!\n"); -+ else -+ dp_altmode_update_extcon(dp, true); - break; - default: - break; -@@ -520,8 +564,14 @@ int dp_altmode_probe(struct typec_altmode *alt) - if (!(DP_CAP_DFP_D_PIN_ASSIGN(port->vdo) & - DP_CAP_UFP_D_PIN_ASSIGN(alt->vdo)) && - !(DP_CAP_UFP_D_PIN_ASSIGN(port->vdo) & -- DP_CAP_DFP_D_PIN_ASSIGN(alt->vdo))) -- return -ENODEV; -+ DP_CAP_DFP_D_PIN_ASSIGN(alt->vdo))) { -+ dev_err(&alt->dev, "No compatible pin configuration found:"\ -+ "%04lx -> %04lx, %04lx <- %04lx", -+ DP_CAP_DFP_D_PIN_ASSIGN(port->vdo), DP_CAP_UFP_D_PIN_ASSIGN(alt->vdo), -+ DP_CAP_UFP_D_PIN_ASSIGN(port->vdo), DP_CAP_DFP_D_PIN_ASSIGN(alt->vdo)); -+ return -ENODEV; -+ } -+ - - ret = sysfs_create_group(&alt->dev.kobj, &dp_altmode_group); - if (ret) -diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c -index e8ddb81cb6df..cbc01d73739c 100644 ---- a/drivers/usb/typec/bus.c -+++ b/drivers/usb/typec/bus.c -@@ -154,8 +154,14 @@ EXPORT_SYMBOL_GPL(typec_altmode_exit); - */ - void typec_altmode_attention(struct typec_altmode *adev, u32 vdo) - { -- struct typec_altmode *pdev = &to_altmode(adev)->partner->adev; -+ struct typec_altmode *pdev; -+ WARN_ONCE(!adev, "typec bus attention: adev is NULL!"); -+ WARN_ONCE(!to_altmode(adev)->partner, "typec bus attention: partner is NULL!"); -+ if(!adev || !to_altmode(adev)->partner) { -+ return; -+ } - -+ pdev = &to_altmode(adev)->partner->adev; - if (pdev->ops && pdev->ops->attention) - pdev->ops->attention(pdev, vdo); - } -diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c -index 82b19ebd7838..6f00b17afc15 100644 ---- a/drivers/usb/typec/tcpm/tcpm.c -+++ b/drivers/usb/typec/tcpm/tcpm.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -322,6 +323,11 @@ struct tcpm_port { - /* port belongs to a self powered device */ - bool self_powered; - -+#ifdef CONFIG_EXTCON -+ struct extcon_dev *extcon; -+ unsigned int *extcon_cables; -+#endif -+ - #ifdef CONFIG_DEBUG_FS - struct dentry *dentry; - struct mutex logbuffer_lock; /* log buffer access lock */ -@@ -607,6 +613,35 @@ static void tcpm_debugfs_exit(const struct tcpm_port *port) { } - - #endif - -+static void tcpm_update_extcon_data(struct tcpm_port *port, bool attached) { -+#ifdef CONFIG_EXTCON -+ unsigned int *capability = port->extcon_cables; -+ if (port->data_role == TYPEC_HOST) { -+ extcon_set_state(port->extcon, EXTCON_USB, false); -+ extcon_set_state(port->extcon, EXTCON_USB_HOST, attached); -+ } else { -+ extcon_set_state(port->extcon, EXTCON_USB, true); -+ extcon_set_state(port->extcon, EXTCON_USB_HOST, attached); -+ } -+ while (*capability != EXTCON_NONE) { -+ if (attached) { -+ union extcon_property_value val; -+ val.intval = (port->polarity == TYPEC_POLARITY_CC2); -+ extcon_set_property(port->extcon, *capability, -+ EXTCON_PROP_USB_TYPEC_POLARITY, val); -+ } else { -+ extcon_set_state(port->extcon, *capability, false); -+ } -+ extcon_sync(port->extcon, *capability); -+ capability++; -+ } -+ tcpm_log(port, "Extcon update (%s): %s, %s", -+ attached ? "attached" : "detached", -+ port->data_role == TYPEC_HOST ? "host" : "device", -+ port->polarity == TYPEC_POLARITY_CC1 ? "normal" : "flipped"); -+#endif -+} -+ - static int tcpm_pd_transmit(struct tcpm_port *port, - enum tcpm_transmit_type type, - const struct pd_message *msg) -@@ -834,6 +869,8 @@ static int tcpm_set_roles(struct tcpm_port *port, bool attached, - typec_set_data_role(port->typec_port, data); - typec_set_pwr_role(port->typec_port, role); - -+ tcpm_update_extcon_data(port, attached); -+ - return 0; - } - -@@ -1044,7 +1081,7 @@ static void svdm_consume_modes(struct tcpm_port *port, const __le32 *payload, - paltmode->mode = i; - paltmode->vdo = le32_to_cpu(payload[i]); - -- tcpm_log(port, " Alternate mode %d: SVID 0x%04x, VDO %d: 0x%08x", -+ tcpm_log(port, "Alternate mode %d: SVID 0x%04x, VDO %d: 0x%08x", - pmdata->altmodes, paltmode->svid, - paltmode->mode, paltmode->vdo); - -@@ -1064,7 +1101,9 @@ static void tcpm_register_partner_altmodes(struct tcpm_port *port) - tcpm_log(port, "Failed to register partner SVID 0x%04x", - modep->altmode_desc[i].svid); - altmode = NULL; -- } -+ } else { -+ tcpm_log(port, "Registered altmode 0x%04x", modep->altmode_desc[i].svid); -+ } - port->partner_altmode[i] = altmode; - } - } -@@ -1167,10 +1207,12 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const __le32 *payload, int cnt, - modep->svid_index++; - if (modep->svid_index < modep->nsvids) { - u16 svid = modep->svids[modep->svid_index]; -+ tcpm_log(port, "More modes available, sending discover"); - response[0] = VDO(svid, 1, svdm_version, CMD_DISCOVER_MODES); - rlen = 1; - } else { -+ tcpm_log(port, "Got all patner modes, registering"); - tcpm_register_partner_altmodes(port); - port->vdm_sm_running = false; - } - break; -@@ -2693,6 +2735,7 @@ static int tcpm_src_attach(struct tcpm_port *port) - static void tcpm_typec_disconnect(struct tcpm_port *port) - { - if (port->connected) { -+ tcpm_update_extcon_data(port, false); - typec_unregister_partner(port->partner); - port->partner = NULL; - port->connected = false; -@@ -2750,6 +2793,8 @@ static void tcpm_detach(struct tcpm_port *port) - port->hard_reset_count = 0; - - tcpm_reset_port(port); -+ -+ tcpm_update_extcon_data(port, false); - } - - static void tcpm_src_detach(struct tcpm_port *port) -@@ -4424,6 +4469,64 @@ void tcpm_tcpc_reset(struct tcpm_port *port) - } - EXPORT_SYMBOL_GPL(tcpm_tcpc_reset); - -+unsigned int default_supported_cables[] = { -+ EXTCON_NONE -+}; -+ -+static int tcpm_fw_get_caps_late(struct tcpm_port *port, -+ struct fwnode_handle *fwnode) -+{ -+ int ret, i; -+ ret = fwnode_property_count_u32(fwnode, "typec-altmodes"); -+ if (ret > 0) { -+ u32 *props; -+ if (ret % 4) { -+ dev_err(port->dev, "Length of typec altmode array must be divisible by 4"); -+ return -EINVAL; -+ } -+ -+ props = devm_kzalloc(port->dev, sizeof(u32) * ret, GFP_KERNEL); -+ if (!props) { -+ dev_err(port->dev, "Failed to allocate memory for altmode properties"); -+ return -ENOMEM; -+ } -+ -+ if(fwnode_property_read_u32_array(fwnode, "typec-altmodes", props, ret) < 0) { -+ dev_err(port->dev, "Failed to read altmodes from port"); -+ return -EINVAL; -+ } -+ -+ i = 0; -+ while (ret > 0 && i < ARRAY_SIZE(port->port_altmode)) { -+ struct typec_altmode *alt; -+ struct typec_altmode_desc alt_desc = { -+ .svid = props[i * 4], -+ .mode = props[i * 4 + 1], -+ .vdo = props[i * 4 + 2], -+ .roles = props[i * 4 + 3], -+ }; -+ -+ -+ tcpm_log(port, "Adding altmode SVID: 0x%04x, mode: %d, vdo: %u, role: %d", -+ alt_desc.svid, alt_desc.mode, alt_desc.vdo, alt_desc.roles); -+ alt = typec_port_register_altmode(port->typec_port, -+ &alt_desc); -+ if (IS_ERR(alt)) { -+ tcpm_log(port, -+ "%s: failed to register port alternate mode 0x%x", -+ dev_name(port->dev), alt_desc.svid); -+ break; -+ } -+ typec_altmode_set_drvdata(alt, port); -+ alt->ops = &tcpm_altmode_ops; -+ port->port_altmode[i] = alt; -+ i++; -+ ret -= 4; -+ } -+ } -+ return 0; -+} -+ - static int tcpm_fw_get_caps(struct tcpm_port *port, - struct fwnode_handle *fwnode) - { -@@ -4434,6 +4537,23 @@ static int tcpm_fw_get_caps(struct tcpm_port *port, - if (!fwnode) - return -EINVAL; - -+#ifdef CONFIG_EXTCON -+ ret = fwnode_property_count_u32(fwnode, "extcon-cables"); -+ if (ret > 0) { -+ port->extcon_cables = devm_kzalloc(port->dev, sizeof(u32) * ret, GFP_KERNEL); -+ if (!port->extcon_cables) { -+ dev_err(port->dev, "Failed to allocate memory for extcon cable types. "\ -+ "Using default tyes"); -+ goto extcon_default; -+ } -+ fwnode_property_read_u32_array(fwnode, "extcon-cables", port->extcon_cables, ret); -+ } else { -+extcon_default: -+ dev_info(port->dev, "No cable types defined, using default cables"); -+ port->extcon_cables = default_supported_cables; -+ } -+#endif -+ - /* USB data support is optional */ - ret = fwnode_property_read_string(fwnode, "data-role", &cap_str); - if (ret == 0) { -@@ -4766,6 +4886,17 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc) - goto out_destroy_wq; - - port->try_role = port->typec_caps.prefer_role; -+#ifdef CONFIG_EXTCON -+ port->extcon = devm_extcon_dev_allocate(dev, port->extcon_cables); -+ if (IS_ERR(port->extcon)) { -+ dev_err(dev, "Failed to allocate extcon device: %ld", PTR_ERR(port->extcon)); -+ goto out_destroy_wq; -+ } -+ if((err = devm_extcon_dev_register(dev, port->extcon))) { -+ dev_err(dev, "Failed to register extcon device: %d", err); -+ goto out_destroy_wq; -+ } -+#endif - - port->typec_caps.fwnode = tcpc->fwnode; - port->typec_caps.revision = 0x0120; /* Type-C spec release 1.2 */ -@@ -4793,6 +4924,12 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc) - goto out_role_sw_put; - } - -+ err = tcpm_fw_get_caps_late(port, tcpc->fwnode); -+ if (err < 0) { -+ dev_err(dev, "Failed to get altmodes from fwnode"); -+ goto out_destroy_wq; -+ } -+ - mutex_lock(&port->lock); - tcpm_init(port); - mutex_unlock(&port->lock); --- -2.26.2 - diff --git a/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/board-pbp-fix-wonky-wifi-bt.patch.disabled b/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/board-pbp-fix-wonky-wifi-bt.patch.disabled deleted file mode 100644 index 6bf95db461bb..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/board-pbp-fix-wonky-wifi-bt.patch.disabled +++ /dev/null @@ -1,150 +0,0 @@ -From 0207f77ece3d07b964d5723c501adc3f3a5a3c6d Mon Sep 17 00:00:00 2001 -From: Dan Johansen -Date: Mon, 1 Jun 2020 17:14:50 +0200 -Subject: [PATCH] fix wonky wifi/bt on PBP - ---- - drivers/bluetooth/hci_bcm.c | 17 +++++++++++++++++ - drivers/bluetooth/hci_serdev.c | 2 ++ - drivers/mmc/core/pwrseq_simple.c | 19 ++++++++++++++++--- - drivers/tty/serdev/core.c | 11 +++++++++++ - include/linux/serdev.h | 1 + - 5 files changed, 47 insertions(+), 3 deletions(-) - -diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c -index b236cb11c0dc..bfd37fb9eeb0 100644 ---- a/drivers/bluetooth/hci_bcm.c -+++ b/drivers/bluetooth/hci_bcm.c -@@ -1472,6 +1472,22 @@ static void bcm_serdev_remove(struct serdev_device *serdev) - hci_uart_unregister_device(&bcmdev->serdev_hu); - } - -+static void bcm_serdev_shutdown(struct serdev_device *serdev) -+{ -+ struct bcm_device *bcmdev = serdev_device_get_drvdata(serdev); -+ -+/* -+ if (test_bit(HCI_UART_REGISTERED, &bcmdev->hu->flags)) { -+ hci_uart_unregister_device(&bcmdev->serdev_hu); -+ } -+*/ -+ dev_info(bcmdev->dev, "Cutting power to bluetooth module\n"); -+ if (bcm_gpio_set_power(bcmdev, false)) { -+ dev_err(bcmdev->dev, "Failed to power down\n"); -+ } -+ usleep_range(500000, 1000000); -+} -+ - #ifdef CONFIG_OF - static struct bcm_device_data bcm4354_device_data = { - .no_early_set_baudrate = true, -@@ -1497,6 +1513,7 @@ MODULE_DEVICE_TABLE(of, bcm_bluetooth_of_match); - static struct serdev_device_driver bcm_serdev_driver = { - .probe = bcm_serdev_probe, - .remove = bcm_serdev_remove, -+ .shutdown = bcm_serdev_shutdown, - .driver = { - .name = "hci_uart_bcm", - .of_match_table = of_match_ptr(bcm_bluetooth_of_match), -diff --git a/drivers/bluetooth/hci_serdev.c b/drivers/bluetooth/hci_serdev.c -index 4652896d4990..043c585b34a7 100644 ---- a/drivers/bluetooth/hci_serdev.c -+++ b/drivers/bluetooth/hci_serdev.c -@@ -395,5 +395,7 @@ void hci_uart_unregister_device(struct hci_uart *hu) - clear_bit(HCI_UART_PROTO_READY, &hu->flags); - serdev_device_close(hu->serdev); - } -+ -+clear_bit(HCI_UART_REGISTERED, &hu->flags); - } - EXPORT_SYMBOL_GPL(hci_uart_unregister_device); -diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c -index ea4d3670560e..b52c3f5b4f13 100644 ---- a/drivers/mmc/core/pwrseq_simple.c -+++ b/drivers/mmc/core/pwrseq_simple.c -@@ -80,10 +80,8 @@ static void mmc_pwrseq_simple_post_power_on(struct mmc_host *host) - msleep(pwrseq->post_power_on_delay_ms); - } - --static void mmc_pwrseq_simple_power_off(struct mmc_host *host) -+static void __mmc_pwrseq_simple_power_off(struct mmc_pwrseq_simple *pwrseq) - { -- struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq); -- - mmc_pwrseq_simple_set_gpios_value(pwrseq, 1); - - if (pwrseq->power_off_delay_us) -@@ -96,6 +94,12 @@ static void mmc_pwrseq_simple_power_off(struct mmc_host *host) - } - } - -+static void mmc_pwrseq_simple_power_off(struct mmc_host *host) -+{ -+ struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq); -+ __mmc_pwrseq_simple_power_off(pwrseq); -+} -+ - static const struct mmc_pwrseq_ops mmc_pwrseq_simple_ops = { - .pre_power_on = mmc_pwrseq_simple_pre_power_on, - .post_power_on = mmc_pwrseq_simple_post_power_on, -@@ -151,9 +155,18 @@ static int mmc_pwrseq_simple_remove(struct platform_device *pdev) - return 0; - } - -+static void mmc_pwrseq_simple_shutdown(struct platform_device *pdev) -+{ -+ struct mmc_pwrseq_simple *pwrseq = platform_get_drvdata(pdev); -+ -+ dev_info(&pdev->dev, "Turning off mmc\n"); -+ __mmc_pwrseq_simple_power_off(pwrseq); -+} -+ - static struct platform_driver mmc_pwrseq_simple_driver = { - .probe = mmc_pwrseq_simple_probe, - .remove = mmc_pwrseq_simple_remove, -+ .shutdown = mmc_pwrseq_simple_shutdown, - .driver = { - .name = "pwrseq_simple", - .of_match_table = mmc_pwrseq_simple_of_match, -diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c -index c5f0d936b003..54bcb38f0c05 100644 ---- a/drivers/tty/serdev/core.c -+++ b/drivers/tty/serdev/core.c -@@ -432,11 +432,22 @@ static int serdev_drv_remove(struct device *dev) - return 0; - } - -+static void serdev_drv_shutdown(struct device *dev) -+{ -+ const struct serdev_device_driver *sdrv; -+ if (dev->driver) { -+ sdrv = to_serdev_device_driver(dev->driver); -+ if (sdrv->shutdown) -+ sdrv->shutdown(to_serdev_device(dev)); -+ } -+} -+ - static struct bus_type serdev_bus_type = { - .name = "serial", - .match = serdev_device_match, - .probe = serdev_drv_probe, - .remove = serdev_drv_remove, -+ .shutdown = serdev_drv_shutdown, - }; - - /** -diff --git a/include/linux/serdev.h b/include/linux/serdev.h -index 9f14f9c12ec4..c3d5dccd6115 100644 ---- a/include/linux/serdev.h -+++ b/include/linux/serdev.h -@@ -63,6 +63,7 @@ struct serdev_device_driver { - struct device_driver driver; - int (*probe)(struct serdev_device *); - void (*remove)(struct serdev_device *); -+ void (*shutdown)(struct serdev_device *); - }; - - static inline struct serdev_device_driver *to_serdev_device_driver(struct device_driver *d) --- -2.26.2 - diff --git a/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/board-renegade-dts-cleanup.patch.dis b/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/board-renegade-dts-cleanup.patch.dis deleted file mode 100644 index 533debc6b724..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/board-renegade-dts-cleanup.patch.dis +++ /dev/null @@ -1,53 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts -index a1041ec3e..bb8748553 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts -@@ -14,6 +14,21 @@ - stdout-path = "serial2:1500000n8"; - }; - -+ leds { -+ compatible = "gpio-leds"; -+ power-led { -+ linux,default-trigger = "heartbeat"; -+ gpios = <&rk805 1 GPIO_ACTIVE_LOW>; -+ default-state = "on"; -+ }; -+ -+ user-led { -+ linux,default-trigger = "disk-activity"; -+ gpios = <&rk805 0 GPIO_ACTIVE_LOW>; -+ default-state = "off"; -+ }; -+ }; -+ - gmac_clkin: external-gmac-clock { - compatible = "fixed-clock"; - clock-frequency = <125000000>; -@@ -77,26 +92,6 @@ - pinctrl-0 = <&ir_int>; - pinctrl-names = "default"; - }; -- -- leds { -- compatible = "gpio-leds"; -- -- power { -- label = "firefly:blue:power"; -- linux,default-trigger = "heartbeat"; -- gpios = <&rk805 1 GPIO_ACTIVE_LOW>; -- default-state = "on"; -- mode = <0x23>; -- }; -- -- user { -- label = "firefly:yellow:user"; -- linux,default-trigger = "mmc1"; -- gpios = <&rk805 0 GPIO_ACTIVE_LOW>; -- default-state = "off"; -- mode = <0x05>; -- }; -- }; - }; - - &analog_sound { diff --git a/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/board-rockpi4-0001-arm64-dts-audio-over-hdmi.patch.disabled b/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/board-rockpi4-0001-arm64-dts-audio-over-hdmi.patch.disabled deleted file mode 100644 index 4b63a8793372..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/board-rockpi4-0001-arm64-dts-audio-over-hdmi.patch.disabled +++ /dev/null @@ -1,30 +0,0 @@ -From 549dcdafe793000fbe38914a1f231d3c6034a6ec Mon Sep 17 00:00:00 2001 -From: Ezequiel Garcia -Date: Fri, 7 Jun 2019 21:35:01 -0300 -Subject: [PATCH] arm64: dts: rockchip: Enable HDMI audio on Rock Pi - -This commit enables the hdmi-sound device needed to have -audio over HDMI on the Rock Pi board. - -Fixes: 1b5715c602fda ("arm64: dts: rockchip: add ROCK Pi 4 DTS support") -Signed-off-by: Ezequiel Garcia -Signed-off-by: Heiko Stuebner ---- - arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi -index 55e74f4d5cd0f..1ae1ebd4efdd0 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi -@@ -178,6 +178,10 @@ - status = "okay"; - }; - -+&hdmi_sound { -+ status = "okay"; -+}; -+ - &i2c0 { - clock-frequency = <400000>; - i2c-scl-rising-time-ns = <168>; diff --git a/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/board-rockpi4-0002-arm64-dts-leds.patch.disabled b/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/board-rockpi4-0002-arm64-dts-leds.patch.disabled deleted file mode 100644 index 2593ef0a6202..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/board-rockpi4-0002-arm64-dts-leds.patch.disabled +++ /dev/null @@ -1,55 +0,0 @@ -While mainlining Rock Pi 4 its leds were probably overlooked in the dts. -Power led is not usable in currently available board revisions <= 1.4 -and is disabled in dts to not confuse users who would like to fiddle with it. - -It could possibly be made controllable by its gpio with the help -of soldering iron, steady hands, patience (SMD0402) and additional overlay -to enable the led and its gpio pin in device tree. - -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi -index e03062715..a97e02bc0 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi -@@ -111,6 +111,25 @@ - regulator-max-microvolt = <1400000>; - vin-supply = <&vcc5v0_sys>; - }; -+ -+ leds { -+ compatible = "gpio-leds"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&power_led_gpio>, <&status_led_gpio>; -+ -+ power-status { -+ label = "power"; -+ gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "default-on"; -+ status = "disabled"; -+ }; -+ -+ system-status { -+ label = "status"; -+ gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "heartbeat"; -+ }; -+ }; - }; - - &cpu_l0 { -@@ -457,6 +476,16 @@ - }; - }; - -+ leds { -+ power_led_gpio: power_led_gpio { -+ rockchip,pins = <3 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ status_led_gpio: status_led_gpio { -+ rockchip,pins = <3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ - pmic { - pmic_int_l: pmic-int-l { - rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>; diff --git a/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/general-add-dwc3-xhci-usb-trb-quirk.patch.disabled b/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/general-add-dwc3-xhci-usb-trb-quirk.patch.disabled deleted file mode 100644 index 3cca7e731cc4..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/general-add-dwc3-xhci-usb-trb-quirk.patch.disabled +++ /dev/null @@ -1,145 +0,0 @@ -diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c -index 841daec70..48825b870 100644 ---- a/drivers/usb/dwc3/core.c -+++ b/drivers/usb/dwc3/core.c -@@ -1340,6 +1340,8 @@ static void dwc3_get_properties(struct dwc3 *dwc) - "snps,dis-del-phy-power-chg-quirk"); - dwc->dis_tx_ipgap_linecheck_quirk = device_property_read_bool(dev, - "snps,dis-tx-ipgap-linecheck-quirk"); -+ dwc->xhci_trb_ent_quirk = device_property_read_bool(dev, -+ "snps,xhci-trb-ent-quirk"); - dwc->parkmode_disable_ss_quirk = device_property_read_bool(dev, - "snps,parkmode-disable-ss-quirk"); - -diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h -index 1b241f937..e1ded14fd 100644 ---- a/drivers/usb/dwc3/core.h -+++ b/drivers/usb/dwc3/core.h -@@ -1049,6 +1049,9 @@ struct dwc3_scratchpad_array { - * change quirk. - * @dis_tx_ipgap_linecheck_quirk: set if we disable u2mac linestate - * check during HS transmit. -+ * @xhci_trb_ent_quirk: set if need to enable the Evaluate Next TRB(ENT) -+ flag in the TRB data structure to force xHC to -+ pre-fetch the next TRB of a TD. - * @parkmode_disable_ss_quirk: set if we need to disable all SuperSpeed - * instances in park mode. - * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk -@@ -1245,6 +1248,7 @@ struct dwc3 { - unsigned dis_u2_freeclk_exists_quirk:1; - unsigned dis_del_phy_power_chg_quirk:1; - unsigned dis_tx_ipgap_linecheck_quirk:1; -+ unsigned xhci_trb_ent_quirk:1; - unsigned parkmode_disable_ss_quirk:1; - - unsigned tx_de_emphasis_quirk:1; -diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c -index e19517658..19d48703d 100644 ---- a/drivers/usb/dwc3/host.c -+++ b/drivers/usb/dwc3/host.c -@@ -44,7 +44,7 @@ static int dwc3_host_get_irq(struct dwc3 *dwc) - - int dwc3_host_init(struct dwc3 *dwc) - { -- struct property_entry props[4]; -+ struct property_entry props[5]; - struct platform_device *xhci; - int ret, irq; - struct resource *res; -@@ -92,6 +92,9 @@ int dwc3_host_init(struct dwc3 *dwc) - if (dwc->usb3_lpm_capable) - props[prop_idx++] = PROPERTY_ENTRY_BOOL("usb3-lpm-capable"); - -+ if (dwc->xhci_trb_ent_quirk) -+ props[prop_idx++] = PROPERTY_ENTRY_BOOL("xhci-trb-ent-quirk"); -+ - if (dwc->usb2_lpm_disable) - props[prop_idx++] = PROPERTY_ENTRY_BOOL("usb2-lpm-disable"); - -diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c -index 4d34f6005..6972cb5b2 100644 ---- a/drivers/usb/host/xhci-plat.c -+++ b/drivers/usb/host/xhci-plat.c -@@ -312,6 +312,9 @@ static int xhci_plat_probe(struct platform_device *pdev) - if (device_property_read_bool(tmpdev, "quirk-broken-port-ped")) - xhci->quirks |= XHCI_BROKEN_PORT_PED; - -+ if (device_property_read_bool(tmpdev, "xhci-trb-ent-quirk")) -+ xhci->quirks |= XHCI_TRB_ENT_QUIRK; -+ - device_property_read_u32(tmpdev, "imod-interval-ns", - &xhci->imod_interval); - } -diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c -index 167dae117..b1bc3bd03 100644 ---- a/drivers/usb/host/xhci-ring.c -+++ b/drivers/usb/host/xhci-ring.c -@@ -3312,6 +3312,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, - bool more_trbs_coming = true; - bool need_zero_pkt = false; - bool first_trb = true; -+ bool en_trb_ent = true; - unsigned int num_trbs; - unsigned int start_cycle, num_sgs = 0; - unsigned int enqd_len, block_len, trb_buff_len, full_len; -@@ -3348,6 +3349,13 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, - if (urb->transfer_flags & URB_ZERO_PACKET && urb_priv->num_tds > 1) - need_zero_pkt = true; - -+ /* -+ * Don't enable the ENT flag in the TRB if -+ * the EP support bulk streaming protocol. -+ */ -+ if (urb->stream_id) -+ en_trb_ent = false; -+ - td = &urb_priv->td[0]; - - /* -@@ -3376,6 +3384,13 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, - first_trb = false; - if (start_cycle == 0) - field |= TRB_CYCLE; -+ /* -+ * Don't enable the ENT flag in the TRB if the -+ * transfer length of the first TRB isn't an -+ * integer multiple of the EP maxpacket. -+ */ -+ if (trb_buff_len % usb_endpoint_maxp(&urb->ep->desc)) -+ en_trb_ent = false; - } else - field |= ring->cycle_state; - -@@ -3384,6 +3399,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, - */ - if (enqd_len + trb_buff_len < full_len) { - field |= TRB_CHAIN; -+ if (xhci->quirks & XHCI_TRB_ENT_QUIRK && en_trb_ent) -+ field |= TRB_ENT; - if (trb_is_link(ring->enqueue + 1)) { - if (xhci_align_td(xhci, urb, enqd_len, - &trb_buff_len, -diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h -index d01241f1d..357217751 100644 ---- a/drivers/usb/host/xhci.h -+++ b/drivers/usb/host/xhci.h -@@ -1512,7 +1512,11 @@ static inline const char *xhci_trb_type_string(u8 type) - #define TRB_SEGMENT_SIZE (TRBS_PER_SEGMENT*16) - #define TRB_SEGMENT_SHIFT (ilog2(TRB_SEGMENT_SIZE)) - /* TRB buffer pointers can't cross 64KB boundaries */ -+#ifdef CONFIG_ARCH_ROCKCHIP -+#define TRB_MAX_BUFF_SHIFT 12 -+#else - #define TRB_MAX_BUFF_SHIFT 16 -+#endif - #define TRB_MAX_BUFF_SIZE (1 << TRB_MAX_BUFF_SHIFT) - /* How much data is left before the 64KB boundary? */ - #define TRB_BUFF_LEN_UP_TO_BOUNDARY(addr) (TRB_MAX_BUFF_SIZE - \ -@@ -1828,6 +1832,7 @@ struct xhci_hcd { - #define XHCI_STATE_HALTED (1 << 1) - #define XHCI_STATE_REMOVING (1 << 2) - unsigned long long quirks; -+#define XHCI_TRB_ENT_QUIRK BIT_ULL(63) - #define XHCI_LINK_TRB_QUIRK BIT_ULL(0) - #define XHCI_RESET_EP_QUIRK BIT_ULL(1) - #define XHCI_NEC_HOST BIT_ULL(2) diff --git a/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/rk3328-hw-cursor-plane.patch.disabled b/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/rk3328-hw-cursor-plane.patch.disabled deleted file mode 100644 index 5cd37949e4d2..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/rk3328-hw-cursor-plane.patch.disabled +++ /dev/null @@ -1,322 +0,0 @@ -From 6eb43deb95d99178419b480181fd18a9b4d9f8fe Mon Sep 17 00:00:00 2001 -From: Paolo Sabatino -Date: Sun, 24 Oct 2021 17:06:13 +0000 -Subject: [PATCH] rk3328: hardware dedicated cursor plane - ---- - drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 214 +++++++++++++++++++- - drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 3 + - drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 20 +- - 3 files changed, 234 insertions(+), 3 deletions(-) - -diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c -index f5b9028a1..9a4afba29 100644 ---- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c -+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c -@@ -1104,6 +1104,201 @@ static void vop_plane_atomic_async_update(struct drm_plane *plane, - } - } - -+static void vop_cursor_atomic_update(struct drm_plane *plane, -+ struct drm_atomic_state *state) -+{ -+ -+ struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, -+ plane); -+ struct drm_crtc *crtc = new_state->crtc; -+ struct vop_win *vop_win = to_vop_win(plane); -+ const struct vop_win_data *win = vop_win->data; -+ struct vop *vop = to_vop(new_state->crtc); -+ struct drm_framebuffer *fb = new_state->fb; -+ unsigned int actual_h; -+ unsigned int dsp_stx, dsp_sty; -+ uint32_t dsp_st; -+ struct drm_rect *src = &new_state->src; -+ struct drm_rect *dest = &new_state->dst; -+ struct drm_gem_object *obj; -+ struct rockchip_gem_object *rk_obj; -+ dma_addr_t dma_addr; -+ uint32_t val; -+ bool rb_swap; -+ int win_index = VOP_WIN_TO_INDEX(vop_win); -+ int format; -+ -+ /* -+ * can't update plane when vop is disabled. -+ */ -+ if (WARN_ON(!crtc)) -+ return; -+ -+ if (WARN_ON(!vop->is_enabled)) -+ return; -+ -+ if (!new_state->visible) { -+ vop_plane_atomic_disable(plane, state); -+ return; -+ } -+ -+ obj = fb->obj[0]; -+ rk_obj = to_rockchip_obj(obj); -+ -+ actual_h = drm_rect_height(src) >> 16; -+ -+ dsp_stx = dest->x1 + crtc->mode.htotal - crtc->mode.hsync_start; -+ dsp_sty = dest->y1 + crtc->mode.vtotal - crtc->mode.vsync_start; -+ dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff); -+ -+ dma_addr = rk_obj->dma_addr; -+ -+ /* -+ * For y-mirroring we need to move address -+ * to the beginning of the last line. -+ */ -+ if (new_state->rotation & DRM_MODE_REFLECT_Y) -+ dma_addr += (actual_h - 1) * fb->pitches[0]; -+ -+ spin_lock(&vop->reg_lock); -+ -+ if (!(vop->win_enabled & BIT(win_index))) { -+ -+ format = vop_convert_format(fb->format->format); -+ -+ VOP_WIN_SET(vop, win, format, format); -+ -+ rb_swap = has_rb_swapped(fb->format->format); -+ VOP_WIN_SET(vop, win, rb_swap, rb_swap); -+ -+ /* -+ * Blending win0 with the background color doesn't seem to work -+ * correctly. We only get the background color, no matter the contents -+ * of the win0 framebuffer. However, blending pre-multiplied color -+ * with the default opaque black default background color is a no-op, -+ * so we can just disable blending to get the correct result. -+ */ -+ if (fb->format->has_alpha && win_index > 0) { -+ VOP_WIN_SET(vop, win, dst_alpha_ctl, -+ DST_FACTOR_M0(ALPHA_SRC_INVERSE)); -+ val = SRC_ALPHA_EN(1) | SRC_COLOR_M0(ALPHA_SRC_PRE_MUL) | -+ SRC_ALPHA_M0(ALPHA_STRAIGHT) | -+ SRC_BLEND_M0(ALPHA_PER_PIX) | -+ SRC_ALPHA_CAL_M0(ALPHA_NO_SATURATION) | -+ SRC_FACTOR_M0(ALPHA_ONE); -+ VOP_WIN_SET(vop, win, src_alpha_ctl, val); -+ -+ VOP_WIN_SET(vop, win, alpha_pre_mul, ALPHA_SRC_PRE_MUL); -+ VOP_WIN_SET(vop, win, alpha_mode, ALPHA_PER_PIX); -+ VOP_WIN_SET(vop, win, alpha_en, 1); -+ } else { -+ VOP_WIN_SET(vop, win, src_alpha_ctl, SRC_ALPHA_EN(0)); -+ VOP_WIN_SET(vop, win, alpha_en, 0); -+ } -+ -+ // 32x32 = 0, 64x64 = 1, 96x96 = 2, 128x128 = 3 -+ VOP_WIN_SET(vop, win, hwc_size, (new_state->crtc_w >> 5) - 1); -+ -+ VOP_WIN_SET(vop, win, enable, 1); -+ vop->win_enabled |= BIT(win_index); -+ -+ } -+ -+ VOP_WIN_SET(vop, win, yrgb_mst, dma_addr); -+ VOP_WIN_SET(vop, win, dsp_st, dsp_st); -+ -+ spin_unlock(&vop->reg_lock); -+ -+} -+ -+static void vop_cursor_atomic_async_update(struct drm_plane *plane, -+ struct drm_atomic_state *state) -+{ -+ -+ struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, -+ plane); -+ struct vop *vop = to_vop(plane->state->crtc); -+ struct drm_framebuffer *old_fb = plane->state->fb; -+ -+ plane->state->crtc_x = new_state->crtc_x; -+ plane->state->crtc_y = new_state->crtc_y; -+ plane->state->crtc_h = new_state->crtc_h; -+ plane->state->crtc_w = new_state->crtc_w; -+ plane->state->src_x = new_state->src_x; -+ plane->state->src_y = new_state->src_y; -+ plane->state->src_h = new_state->src_h; -+ plane->state->src_w = new_state->src_w; -+ swap(plane->state->fb, new_state->fb); -+ -+ if (vop->is_enabled) { -+ vop_cursor_atomic_update(plane, state); -+ spin_lock(&vop->reg_lock); -+ vop_cfg_done(vop); -+ spin_unlock(&vop->reg_lock); -+ -+ /* -+ * A scanout can still be occurring, so we can't drop the -+ * reference to the old framebuffer. To solve this we get a -+ * reference to old_fb and set a worker to release it later. -+ * FIXME: if we perform 500 async_update calls before the -+ * vblank, then we can have 500 different framebuffers waiting -+ * to be released. -+ */ -+ if (old_fb && plane->state->fb != old_fb) { -+ drm_framebuffer_get(old_fb); -+ WARN_ON(drm_crtc_vblank_get(plane->state->crtc) != 0); -+ drm_flip_work_queue(&vop->fb_unref_work, old_fb); -+ set_bit(VOP_PENDING_FB_UNREF, &vop->pending); -+ } -+ } -+ -+} -+ -+static int vop_cursor_atomic_check(struct drm_plane *plane, -+ struct drm_atomic_state *state) -+{ -+ struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, -+ plane); -+ struct drm_crtc *crtc = new_plane_state->crtc; -+ struct drm_crtc_state *crtc_state; -+ struct drm_framebuffer *fb = new_plane_state->fb; -+ int ret; -+ -+ if (!crtc || WARN_ON(!fb)) -+ return 0; -+ -+ crtc_state = drm_atomic_get_existing_crtc_state(state, crtc); -+ if (WARN_ON(!crtc_state)) -+ return -EINVAL; -+ -+ ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state, -+ DRM_PLANE_HELPER_NO_SCALING, DRM_PLANE_HELPER_NO_SCALING, -+ true, true); -+ -+ if (ret) -+ return ret; -+ -+ if (!new_plane_state->visible) -+ return 0; -+ -+ ret = vop_convert_format(fb->format->format); -+ if (ret < 0) -+ return ret; -+ -+ if (new_plane_state->crtc_w != new_plane_state->crtc_h) -+ return -EINVAL; -+ -+ if (new_plane_state->crtc_w != 0 && -+ new_plane_state->crtc_w != 32 && -+ new_plane_state->crtc_w != 64 && -+ new_plane_state->crtc_w != 96 && -+ new_plane_state->crtc_w != 128) -+ return -EINVAL; -+ -+ return 0; -+ -+} -+ - static const struct drm_plane_helper_funcs plane_helper_funcs = { - .atomic_check = vop_plane_atomic_check, - .atomic_update = vop_plane_atomic_update, -@@ -1113,6 +1308,15 @@ static const struct drm_plane_helper_funcs plane_helper_funcs = { - .prepare_fb = drm_gem_plane_helper_prepare_fb, - }; - -+static const struct drm_plane_helper_funcs cursor_plane_helper_funcs = { -+ .atomic_check = vop_cursor_atomic_check, -+ .atomic_update = vop_cursor_atomic_update, -+ .atomic_disable = vop_plane_atomic_disable, -+ .atomic_async_check = vop_plane_atomic_async_check, -+ .atomic_async_update = vop_cursor_atomic_async_update, -+ .prepare_fb = drm_gem_plane_helper_prepare_fb, -+}; -+ - static const struct drm_plane_funcs vop_plane_funcs = { - .update_plane = drm_atomic_helper_update_plane, - .disable_plane = drm_atomic_helper_disable_plane, -@@ -1772,6 +1976,7 @@ static int vop_create_crtc(struct vop *vop) - struct drm_plane *primary = NULL, *cursor = NULL, *plane, *tmp; - struct drm_crtc *crtc = &vop->crtc; - struct device_node *port; -+ const struct drm_plane_helper_funcs *helper_funcs; - int ret; - int i; - -@@ -1801,7 +2006,14 @@ static int vop_create_crtc(struct vop *vop) - } - - plane = &vop_win->base; -- drm_plane_helper_add(plane, &plane_helper_funcs); -+ helper_funcs = &plane_helper_funcs; -+ -+ if ((plane->type == DRM_PLANE_TYPE_CURSOR) && (vop_data->feature & VOP_FEATURE_SPECIAL_CURSOR_PLANE)) { -+ dev_info(dev, "using dedicated hwcursor plane\n"); -+ helper_funcs = &cursor_plane_helper_funcs; -+ } -+ -+ drm_plane_helper_add(plane, helper_funcs); - vop_plane_add_properties(plane, win_data); - if (plane->type == DRM_PLANE_TYPE_PRIMARY) - primary = plane; -diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h -index 857d97cdc..7967359c1 100644 ---- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h -+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h -@@ -182,6 +182,8 @@ struct vop_win_phy { - struct vop_reg alpha_mode; - struct vop_reg alpha_en; - struct vop_reg channel; -+ -+ struct vop_reg hwc_size; - }; - - struct vop_win_yuv2yuv_data { -@@ -211,6 +213,7 @@ struct vop_data { - - #define VOP_FEATURE_OUTPUT_RGB10 BIT(0) - #define VOP_FEATURE_INTERNAL_RGB BIT(1) -+#define VOP_FEATURE_SPECIAL_CURSOR_PLANE BIT(2) - u64 feature; - }; - -diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c -index ca7cc8212..56eb4f774 100644 ---- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c -+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c -@@ -1048,18 +1048,34 @@ static const struct vop_intr rk3328_vop_intr = { - .clear = VOP_REG_MASK_SYNC(RK3328_INTR_CLEAR0, 0xffff, 0), - }; - -+static const struct vop_win_phy rk3328_cursor_data = { -+ .data_formats = formats_win_lite, -+ .nformats = ARRAY_SIZE(formats_win_lite), -+ .format_modifiers = format_modifiers_win_lite, -+ .enable = VOP_REG(RK3328_HWC_CTRL0, 0x1, 0), -+ .format = VOP_REG(RK3328_HWC_CTRL0, 0x7, 1), -+ .rb_swap = VOP_REG(RK3328_HWC_CTRL0, 0x1, 12), -+ .dsp_st = VOP_REG(RK3328_HWC_DSP_ST, 0x1fff1fff, 0), -+ .yrgb_mst = VOP_REG(RK3328_HWC_MST, 0xffffffff, 0), -+ .src_alpha_ctl = VOP_REG(RK3328_HWC_SRC_ALPHA_CTRL, 0xff, 0), -+ .dst_alpha_ctl = VOP_REG(RK3328_HWC_DST_ALPHA_CTRL, 0xff, 0), -+ .hwc_size = VOP_REG(RK3328_HWC_CTRL0, 0x3, 5), -+}; -+ - static const struct vop_win_data rk3328_vop_win_data[] = { - { .base = 0xd0, .phy = &rk3368_win01_data, - .type = DRM_PLANE_TYPE_PRIMARY }, - { .base = 0x1d0, .phy = &rk3368_win01_data, - .type = DRM_PLANE_TYPE_OVERLAY }, - { .base = 0x2d0, .phy = &rk3368_win01_data, -- .type = DRM_PLANE_TYPE_CURSOR }, -+ .type = DRM_PLANE_TYPE_OVERLAY }, -+ { .base = 0x00, .phy = &rk3328_cursor_data, -+ .type = DRM_PLANE_TYPE_CURSOR } - }; - - static const struct vop_data rk3328_vop = { - .version = VOP_VERSION(3, 8), -- .feature = VOP_FEATURE_OUTPUT_RGB10, -+ .feature = VOP_FEATURE_OUTPUT_RGB10 | VOP_FEATURE_SPECIAL_CURSOR_PLANE, - .intr = &rk3328_vop_intr, - .common = &rk3328_common, - .modeset = &rk3328_modeset, --- -2.30.2 - diff --git a/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/wifi-hf-lps170-bl602-kconfig-makefile.patch.disabled b/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/wifi-hf-lps170-bl602-kconfig-makefile.patch.disabled deleted file mode 100644 index 14687b1b3733..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/wifi-hf-lps170-bl602-kconfig-makefile.patch.disabled +++ /dev/null @@ -1,20 +0,0 @@ ---- a/drivers/net/wireless/Kconfig 2021-04-17 23:46:30.128653096 +0300 -+++ b/drivers/net/wireless/Kconfig 2021-04-17 23:48:11.300679976 +0300 -@@ -32,6 +32,7 @@ - source "drivers/net/wireless/realtek/Kconfig" - source "drivers/net/wireless/rsi/Kconfig" - source "drivers/net/wireless/st/Kconfig" -+source "drivers/net/wireless/hflps170/Kconfig" - source "drivers/net/wireless/ti/Kconfig" - source "drivers/net/wireless/rtl8814au/Kconfig" - source "drivers/net/wireless/rtl8723du/Kconfig" ---- a/drivers/net/wireless/Makefile 2021-04-11 19:19:48.949981359 +0300 -+++ b/drivers/net/wireless/Makefile 2021-04-17 23:47:45.688673417 +0300 -@@ -18,6 +18,7 @@ - obj-$(CONFIG_WLAN_VENDOR_RSI) += rsi/ - obj-$(CONFIG_WLAN_VENDOR_ST) += st/ - obj-$(CONFIG_WLAN_VENDOR_TI) += ti/ -+obj-$(CONFIG_HFLPS170) += hflps170/ - obj-$(CONFIG_WLAN_VENDOR_ZYDAS) += zydas/ - obj-$(CONFIG_WLAN_VENDOR_QUANTENNA) += quantenna/ - diff --git a/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/wifi-hf-lps170-bl602.patch.disabled b/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/wifi-hf-lps170-bl602.patch.disabled deleted file mode 100644 index e756c3db0643..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/disabled 2023.02/wifi-hf-lps170-bl602.patch.disabled +++ /dev/null @@ -1,22688 +0,0 @@ -diff -Naur /dev/null b/drivers/net/wireless/hflps170/Kconfig ---- /dev/null 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/Kconfig 2021-04-17 22:35:12.676948473 +0300 -@@ -0,0 +1,4 @@ -+config HFLPS170 -+ tristate "hi-flying HF-LPS170 SDIO WiFi" -+ help -+ Help message of HFLPS170 -diff -Naur /dev/null b/drivers/net/wireless/hflps170/Makefile ---- /dev/null 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/Makefile 2021-04-17 23:25:30.908143624 +0300 -@@ -0,0 +1,91 @@ -+BL_VERS_NUM=5.5.0.0 -+ -+CONFIG_BL_FULLMAC ?= m -+ -+KERNELVERSION := $(shell uname -r) -+ -+subdir-ccflags-$(CONFIG_DEBUG_FS) += -DCONFIG_BL_DEBUGFS -+subdir-ccflags-y += -I$(src)/fullmac -+ -+# FW VARS -+subdir-ccflags-y += -DNX_VIRT_DEV_MAX=4 -+subdir-ccflags-y += -DNX_REMOTE_STA_MAX=10 -+subdir-ccflags-y += -DNX_CHAN_CTXT_CNT=3 -+ -+obj-$(CONFIG_BL_FULLMAC) += fullmac/ -+ -+#KERNELDIR = ~/Workspace/linux-4.10 -+KERNELDIR ?= /lib/modules/$(KERNELVERSION)/build -+ -+# Enable A-MSDU support (need FW support) -+## Select this if FW is compiled with AMSDU support -+CONFIG_BL_SPLIT_TX_BUF ?= n -+## Select this TO send AMSDU -+CONFIG_BL_AMSDUS_TX ?= n -+ -+# Enable HW queue for Broadcast/Multicast traffic (need FW support) -+CONFIG_BL_BCMC ?= y -+ -+# extra DEBUG config -+CONFIG_BL_SW_PROFILING ?= n -+CONFIG_BL_DBG ?= n -+CONFIG_AUTO_DNLD ?= y -+ -+obj-m := bl_fdrv.o -+bl_fdrv-y := bl_cfgfile.o \ -+ fullmac/bl_main.o \ -+ bl_mod_params.o \ -+ bl_platform.o \ -+ bl_sdio.o \ -+ bl_msg_tx.o \ -+ bl_msg_rx.o \ -+ bl_utils.o \ -+ bl_cmds.o \ -+ bl_irqs.o \ -+ ipc_host.o \ -+ bl_txq.o \ -+ bl_strs.o \ -+ fullmac/bl_tx.o \ -+ fullmac/bl_rx.o \ -+ bl_v7.o \ -+ bl_bootrom.o -+bl_fdrv-$(CONFIG_DEBUG_FS) += bl_debugfs.o -+ -+ccflags-y := -DCONFIG_BL_FULLMAC -+ccflags-y += -I$(src) -+ccflags-$(CONFIG_BL_SPLIT_TX_BUF) += -DCONFIG_BL_SPLIT_TX_BUF -+ifeq ($(CONFIG_BL_SPLIT_TX_BUF), y) -+ccflags-$(CONFIG_BL_AMSDUS_TX) += -DCONFIG_BL_AMSDUS_TX -+endif -+ccflags-$(CONFIG_BL_DBG) += -DCONFIG_BL_DBG -+ccflags-$(CONFIG_BL_MOD_LEV_DBG) += -DCONFIG_BL_MOD_LEV_DBG -+ -+ccflags-y += -DCONFIG_USER_MAX=1 -+ -+ifeq ($(CONFIG_BL_BCMC), y) -+ccflags-y += -DNX_TXQ_CNT=5 -+else -+ccflags-y += -DNX_TXQ_CNT=4 -+endif -+ -+ -+quiet_cmd_genvers = GENVERSION $@ -+ cmd_genvers = ($(if $(KBUILD_EXTMOD),,$(srctree)/)$(src)/mkvers.sh bl_version_gen.h $@) -+ -+$(obj)/fullmac/bl_main.o: $(obj)/bl_version_gen.h -+ -+$(obj)/bl_version_gen.h: FORCE -+ chmod 755 $(src)/mkvers.sh -+ chmod 755 $(src)/mklink.sh -+ $(call cmd,genvers) -+ -+clean-files := bl_version_gen.h -+ -+ -+all: modules -+ -+modules clean: -+ @$(PWD)/mklink.sh fullmac -+ $(MAKE) -C $(KERNELDIR) O=$(KBUILDDIR) M=$(PWD) $@ -+ @$(PWD)/mklink.sh clean -+ -diff -Naur /dev/null.md b/drivers/net/wireless/hflps170/README.md ---- /dev/null.md 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/README.md 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,23 @@ -+=============================================================================== -+ U S E R M A N U A L -+ -+ Copyright (C) BouffaloLab 2017-2020 -+ -+1) FOR DRIVER BUILD -+ -+ Goto source code directory -+ make [clean] -+ The driver bl_fdrv.ko can be found in fullmac directory. -+ The driver code supports Linux kernel from 3.10 to 5.5.19. -+ -+2) FOR DRIVER INSTALL -+ -+ a) Copy firmware image to /lib/firmware/, and rename to wholeimg_if.bin, copy bl_settings.ini to /lib/firmware/. -+ b) Install WLAN driver -+ insmod bl_fdrv.ko -+ c) uninstall driver -+ ifconfig wlan0 down -+ rmmod bl_fdrv -+ -+ -+ -diff -Naur /dev/null_bootrom.c b/drivers/net/wireless/hflps170/bl_bootrom.c ---- /dev/null_bootrom.c 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_bootrom.c 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,444 @@ -+#include -+#include -+ -+#include "bl_bootrom.h" -+ -+int bl_bootrom_cmd_len(bootrom_host_cmd_t *cmd) -+{ -+ return cmd->len + BL_BOOTROM_HOST_CMD_LEN_HEADER; -+} -+ -+int bl_bootrom_cmd_bootinfo_get(bootrom_host_cmd_t *cmd) -+{ -+ cmd->id = BL_BOOTROM_HOST_CMD_BOOTINFO_GET; -+ cmd->len = 0; -+ return 0; -+} -+ -+int bl_bootrom_cmd_bootinfo_get_res(bootrom_res_bootinfo_t *bootinfo) -+{ -+ if ('O' == bootinfo->status[0] && -+ 'K' == bootinfo->status[1]) { -+ printk("[RSP] bootinfo versoin: 0x%08X\n", bootinfo->version); -+ printk("[RSP] bootinfo password_mode: 0x%02X\n", bootinfo->password_mode); -+ printk("[RSP] bootinfo sboot_enable: 0x%02X\n", bootinfo->sboot_enable); -+ printk("[RSP] bootinfo jtag_disable: 0x%02X\n", bootinfo->jtag_disable); -+ printk("[RSP] bootinfo uart_disable: 0x%02X\n", bootinfo->uart_disable); -+ printk("[RSP] bootinfo sign_type: 0x%02X\n", bootinfo->sign_type); -+ printk("[RSP] bootinfo aes_type: 0x%02X\n", bootinfo->aes_type); -+ printk("[RSP] bootinfo reserved: 0x%02X\n", bootinfo->reserved); -+ printk("[RSP] bootinfo chip_id: 0x%02X%02X%02X%02X%02X\n", -+ bootinfo->chip_id[0], -+ bootinfo->chip_id[1], -+ bootinfo->chip_id[2], -+ bootinfo->chip_id[3], -+ bootinfo->chip_id[4] -+ ); -+ } else { -+ printk("[RSP] unkown status:%c%c\n", -+ bootinfo->status[0], -+ bootinfo->status[1] -+ ); -+ return -1; -+ } -+ return -1; -+} -+ -+#if 0 -+int bl_bootrom_cmd_password_load(bootrom_host_cmd_t *cmd, uint8_t *password) -+{ -+ cmd->id = BL_BOOTROM_HOST_CMD_PASSWORD_LOAD; -+ cmd->len = sizeof(bootrom_host_cmd_t) - BL_BOOTROM_HOST_CMD_LEN_HEADER; -+ memcpy(cmd->data, password, sizeof(cmd->data)); -+ -+ return 0; -+} -+ -+int bl_bootrom_cmd_password_load_get_res(bootrom_res_password_load_t *bootresponse, int size) -+{ -+ if (size != (sizeof(bootrom_res_password_load_t)) && size != 1) { -+ printk("[RSP] password_load response len is not correct %d\n", size); -+ return -1; -+ } -+ -+ if ('O' == bootresponse->status[0] && -+ 'K' == bootresponse->status[1] && 1 == size) { -+ printk("[RSP] password_load response OK\n"); -+ } else if ('F' == bootresponse->status[0] && -+ 'L' == bootresponse->status[1] && 3 == size) { -+ printk("[RSP] password_load response failed, staus 0x%04X\n", bootresponse->code); -+ } else { -+ printk("[RSP] unkown status:%c%c\n", -+ bootresponse->status[0], -+ bootresponse->status[1] -+ ); -+ return -1; -+ } -+ return -1; -+} -+ -+int bl_bootrom_cmd_jtag_open(bootrom_host_cmd_t *cmd, uint8_t *password) -+{ -+ cmd->id = BL_BOOTROM_HOST_CMD_JTAG_OPEN; -+ cmd->len = sizeof(bootrom_host_cmd_t) - BL_BOOTROM_HOST_CMD_LEN_HEADER; -+ memcpy(cmd->data, password, sizeof(cmd->data)); -+ -+ return 0; -+} -+ -+int bl_bootrom_cmd_jtag_open_get_res(bootrom_res_jtag_open_t *bootresponse, int size) -+{ -+ if (size != (sizeof(bootrom_res_jtag_open_t)) && size != 1) { -+ printk("[RSP] jtag_open response len is not correct %d\n", size); -+ return -1; -+ } -+ -+ if ('O' == bootresponse->status[0] && -+ 'K' == bootresponse->status[1] && 1 == size) { -+ printk("[RSP] jtag_open response OK\n"); -+ } else if ('F' == bootresponse->status[0] && -+ 'L' == bootresponse->status[1] && 3 == size) { -+ printk("[RSP] jtag_open response failed, staus 0x%04X\n", bootresponse->code); -+ } else { -+ printk("[RSP] unkown status:%c%c\n", -+ bootresponse->status[0], -+ bootresponse->status[1] -+ ); -+ return -1; -+ } -+ return -1; -+} -+#endif -+ -+int bl_bootrom_cmd_bootheader_load(bootrom_host_cmd_t *cmd, bootheader_t *header) -+{ -+ //XXX should caller known the size of cmd->data ? -+ cmd->id = BL_BOOTROM_HOST_CMD_BOOTHEADER_LOAD; -+ cmd->len = sizeof(bootrom_host_cmd_t) - BL_BOOTROM_HOST_CMD_LEN_HEADER + sizeof(bootheader_t); -+ memcpy(cmd->data, header, sizeof(bootheader_t)); -+ -+ return 0; -+} -+ -+int bl_bootrom_cmd_bootheader_load_get_res(bootrom_res_bootheader_load_t *bootresponse) -+{ -+ if ('O' == bootresponse->status[0] && -+ 'K' == bootresponse->status[1]) { -+ printk("[RSP] bootheader_load response OK\n"); -+ } else if ('F' == bootresponse->status[0] && -+ 'L' == bootresponse->status[1]) { -+ printk("[RSP] bootheader_load response failed, staus 0x%04X\n", bootresponse->code); -+ } else { -+ printk("[RSP] unkown status:%c%c\n", -+ bootresponse->status[0], -+ bootresponse->status[1] -+ ); -+ return -1; -+ } -+ return -1; -+} -+ -+int bl_bootrom_cmd_aesiv_load(bootrom_host_cmd_t *cmd, const uint8_t *aesiv) -+{ -+ //XXX should caller known the size of cmd->data ? -+ cmd->id = BL_BOOTROM_HOST_CMD_AESIV_LOAD; -+ cmd->len = sizeof(bootrom_host_cmd_t) - BL_BOOTROM_HOST_CMD_LEN_HEADER + 20;//FIXME use struct instead -+ memcpy(cmd->data, aesiv, 20);//FIXME use struct instead, but NOT magic number(16 IV + 4 CRC32) -+ -+ return 0; -+} -+ -+int bl_bootrom_cmd_aesiv_load_get_res(bootrom_res_aesiv_load_t *bootresponse) -+{ -+ if ('O' == bootresponse->status[0] && -+ 'K' == bootresponse->status[1]) { -+ printk("[RSP] aesiv_load response OK\n"); -+ } else if ('F' == bootresponse->status[0] && -+ 'L' == bootresponse->status[1]) { -+ printk("[RSP] aesiv_load response failed, staus 0x%04X\n", bootresponse->code); -+ } else { -+ printk("[RSP] unkown status:%c%c\n", -+ bootresponse->status[0], -+ bootresponse->status[1] -+ ); -+ return -1; -+ } -+ return -1; -+} -+ -+int bl_bootrom_cmd_pkey1_load(bootrom_host_cmd_t *cmd, pkey_cfg_t *pk) -+{ -+ cmd->id = BL_BOOTROM_HOST_CMD_PK1_LOAD; -+ cmd->len = sizeof(bootrom_host_cmd_t) - BL_BOOTROM_HOST_CMD_LEN_HEADER + sizeof(pkey_cfg_t); -+ memcpy(cmd->data, pk, sizeof(pkey_cfg_t)); -+ -+ return 0; -+} -+ -+int bl_bootrom_cmd_pkey1_load_get_res(bootrom_res_pkey_load_t *bootresponse) -+{ -+ if ('O' == bootresponse->status[0] && -+ 'K' == bootresponse->status[1]) { -+ printk("[RSP] pkey1_load response OK\n"); -+ return 0; -+ } else if ('F' == bootresponse->status[0] && -+ 'L' == bootresponse->status[1]) { -+ printk("[RSP] pkey1_load response failed, staus 0x%04X\n", bootresponse->code); -+ } else { -+ printk("[RSP] unkown status:%c%c\n", -+ bootresponse->status[0], -+ bootresponse->status[1] -+ ); -+ } -+ return -1; -+} -+ -+int bl_bootrom_cmd_pkey2_load(bootrom_host_cmd_t *cmd, pkey_cfg_t *pk) -+{ -+ cmd->id = BL_BOOTROM_HOST_CMD_PK2_LOAD; -+ cmd->len = sizeof(bootrom_host_cmd_t) - BL_BOOTROM_HOST_CMD_LEN_HEADER + sizeof(pkey_cfg_t); -+ memcpy(cmd->data, pk, sizeof(pkey_cfg_t)); -+ -+ return 0; -+} -+ -+int bl_bootrom_cmd_pkey2_load_get_res(bootrom_res_pkey_load_t *bootresponse) -+{ -+ if ('O' == bootresponse->status[0] && -+ 'K' == bootresponse->status[1]) { -+ printk("[RSP] pkey2_load response OK\n"); -+ return 0; -+ } else if ('F' == bootresponse->status[0] && -+ 'L' == bootresponse->status[1]) { -+ printk("[RSP] pkey2_load response failed, staus 0x%04X\n", bootresponse->code); -+ } else { -+ printk("[RSP] unkown status:%c%c\n", -+ bootresponse->status[0], -+ bootresponse->status[1] -+ ); -+ } -+ return -1; -+} -+ -+int bl_bootrom_cmd_signature1_load(bootrom_host_cmd_t *cmd, uint8_t *signature, int len) -+{ -+ cmd->id = BL_BOOTROM_HOST_CMD_SIGNATURE1_LOAD; -+ cmd->len = sizeof(bootrom_host_cmd_t) - BL_BOOTROM_HOST_CMD_LEN_HEADER + len;//use magic number -+ memcpy(cmd->data, signature, len);//XXX overflow check -+ -+ return 0; -+} -+ -+int bl_bootrom_cmd_signature1_get_res(bootrom_res_signature_load_t *bootresponse) -+{ -+ if ('O' == bootresponse->status[0] && -+ 'K' == bootresponse->status[1]) { -+ printk("[RSP] signature1_load response OK\n"); -+ return 0; -+ } else if ('F' == bootresponse->status[0] && -+ 'L' == bootresponse->status[1]) { -+ printk("[RSP] signature1_load response failed, staus 0x%04X\n", bootresponse->code); -+ } else { -+ printk("[RSP] unkown status:%c%c\n", -+ bootresponse->status[0], -+ bootresponse->status[1] -+ ); -+ } -+ return -1; -+} -+ -+int bl_bootrom_cmd_signature2_load(bootrom_host_cmd_t *cmd, uint8_t *signature, int len) -+{ -+ cmd->id = BL_BOOTROM_HOST_CMD_SIGNATURE2_LOAD; -+ cmd->len = sizeof(bootrom_host_cmd_t) - BL_BOOTROM_HOST_CMD_LEN_HEADER + len;//use magic number -+ memcpy(cmd->data, signature, len);//XXX overflow check -+ -+ return 0; -+} -+ -+int bl_bootrom_cmd_signature2_get_res(bootrom_res_signature_load_t *bootresponse) -+{ -+ if ('O' == bootresponse->status[0] && -+ 'K' == bootresponse->status[1]) { -+ printk("[RSP] signature2_load response OK\n"); -+ return 0; -+ } else if ('F' == bootresponse->status[0] && -+ 'L' == bootresponse->status[1]) { -+ printk("[RSP] signature2_load response failed, staus 0x%04X\n", bootresponse->code); -+ } else { -+ printk("[RSP] unkown status:%c%c\n", -+ bootresponse->status[0], -+ bootresponse->status[1] -+ ); -+ } -+ return -1; -+} -+ -+#if 0 -+int bl_bootrom_cmd_tzc_load(bootrom_host_cmd_t *cmd, uint8_t *tzc, int len) -+{ -+ cmd->id = BL_BOOTROM_HOST_CMD_TZC_LOAD; -+ cmd->len = sizeof(bootrom_host_cmd_t) - BL_BOOTROM_HOST_CMD_LEN_HEADER + len;//use magic number -+ memcpy(cmd->data, tzc, len);//XXX overflow check -+ -+ return 0; -+} -+ -+int bl_bootrom_cmd_tzc_get_res(bootrom_res_tzc_load_t *bootresponse, int size) -+{ -+ if (size != (sizeof(bootrom_res_tzc_load_t)) && size != 1) { -+ printk("[RSP] tzc_load response len is not correct %d\n", size); -+ return -1; -+ } -+ -+ if ('O' == bootresponse->status[0] && -+ 'K' == bootresponse->status[1] && 1 == size) { -+ printk("[RSP] tzc_load response OK\n"); -+ } else if ('F' == bootresponse->status[0] && -+ 'L' == bootresponse->status[1] && 3 == size) { -+ printk("[RSP] tzc_load response failed, staus 0x%04X\n", bootresponse->code); -+ } else { -+ printk("[RSP] unkown status:%c%c\n", -+ bootresponse->status[0], -+ bootresponse->status[1] -+ ); -+ return -1; -+ } -+ return -1; -+} -+#endif -+ -+int bl_bootrom_cmd_sectionheader_load(bootrom_host_cmd_t *cmd, const segment_header_t *header) -+{ -+ cmd->id = BL_BOOTROM_HOST_CMD_SECTIONHEADER_LOAD; -+ cmd->len = sizeof(bootrom_host_cmd_t) - BL_BOOTROM_HOST_CMD_LEN_HEADER + sizeof(segment_header_t); -+ memcpy(cmd->data, header, sizeof(segment_header_t));//XXX overflow check -+ -+ return 0; -+} -+ -+int bl_bootrom_cmd_sectionheader_get_res(bootrom_res_sectionheader_load_t *bootresponse) -+{ -+ if ('O' == bootresponse->status[0] && -+ 'K' == bootresponse->status[1]) { -+ printk("[RSP] section_header response OK\n"); -+ return 0; -+ } else if ('F' == bootresponse->status[0] && -+ 'L' == bootresponse->status[1]) { -+ printk("[RSP] section_header response failed, staus 0x%04X\n", bootresponse->len); -+ } else { -+ printk("[RSP] unkown status:%c%c\n", -+ bootresponse->status[0], -+ bootresponse->status[1] -+ ); -+ } -+ return -1; -+} -+ -+int bl_bootrom_cmd_sectiondata_load(bootrom_host_cmd_t *cmd, const uint8_t *data, int len) -+{ -+ cmd->id = BL_BOOTROM_HOST_CMD_SECTIONDATA_LOAD; -+ cmd->len = sizeof(bootrom_host_cmd_t) - BL_BOOTROM_HOST_CMD_LEN_HEADER + len;//use magic number -+ memcpy(cmd->data, data, len);//XXX overflow check -+ -+ return 0; -+} -+ -+int bl_bootrom_cmd_sectiondata_get_res(bootrom_res_sectiondata_load_t *bootresponse) -+{ -+ if ('O' == bootresponse->status[0] && -+ 'K' == bootresponse->status[1]) { -+ printk("[RSP] section_data response OK\n"); -+ } else if ('F' == bootresponse->status[0] && -+ 'L' == bootresponse->status[1]) { -+ printk("[RSP] section_data response failed, staus 0x%04X\n", bootresponse->code); -+ } else { -+ printk("[RSP] unkown status:%c%c\n", -+ bootresponse->status[0], -+ bootresponse->status[1] -+ ); -+ return -1; -+ } -+ return -1; -+} -+ -+int bl_bootrom_cmd_checkimage_get(bootrom_host_cmd_t *cmd) -+{ -+ cmd->id = BL_BOOTROM_HOST_CMD_CHECK_IMAGE; -+ cmd->len = 0; -+ return 0; -+} -+ -+int bl_bootrom_cmd_checkimage_get_res(bootrom_res_checkimage_t *checkimage) -+{ -+ if ('O' == checkimage->status[0] && -+ 'K' == checkimage->status[1]) { -+ printk("[RSP] checkimage response OK\n"); -+ return 0; -+ } else if ('F' == checkimage->status[0] && -+ 'L' == checkimage->status[1]) { -+ printk("[RSP] checkimage response failed, staus 0x%04X\n", checkimage->code); -+ } else { -+ printk("[RSP] unkown status:%c%c\n", -+ checkimage->status[0], -+ checkimage->status[1] -+ ); -+ } -+ return -1; -+} -+ -+int bl_bootrom_cmd_runimage_get(bootrom_host_cmd_t *cmd) -+{ -+ cmd->id = BL_BOOTROM_HOST_CMD_RUN; -+ cmd->len = 0; -+ return 0; -+} -+ -+int bl_bootrom_cmd_runimage_get_res(bootrom_res_runimage_t *runimage) -+{ -+ if ('O' == runimage->status[0] && -+ 'K' == runimage->status[1]) { -+ printk("[RSP] runimage response OK\n"); -+ } else if ('F' == runimage->status[0] && -+ 'L' == runimage->status[1]) { -+ printk("[RSP] runimage response failed, staus 0x%04X\n", runimage->code); -+ } else { -+ printk("[RSP] unkown status:%c%c\n", -+ runimage->status[0], -+ runimage->status[1] -+ ); -+ return -1; -+ } -+ return 0; -+} -+ -+int bl_bootrom_cmd_run(bootrom_host_cmd_t *cmd) -+{ -+ cmd->id = BL_BOOTROM_HOST_CMD_RUN; -+ cmd->len = 0; -+ return 0; -+} -+ -+int bl_bootrom_cmd_run_get_res(bootrom_res_run_t *bootresponse, int size) -+{ -+ if (size != (sizeof(bootrom_res_sectiondata_load_t)) && size != 1) { -+ printk("[RSP] section_data response len is not correct %d\n", size); -+ return -1; -+ } -+ -+ if ('O' == bootresponse->status[0] && -+ 'K' == bootresponse->status[1] && 1 == size) { -+ printk("[RSP] section_data response OK\n"); -+ } else if ('F' == bootresponse->status[0] && -+ 'L' == bootresponse->status[1] && 3 == size) { -+ printk("[RSP] section_data response failed, staus 0x%04X\n", bootresponse->code); -+ } else { -+ printk("[RSP] unkown status:%c%c\n", -+ bootresponse->status[0], -+ bootresponse->status[1] -+ ); -+ return -1; -+ } -+ return -1; -+} -+ -diff -Naur /dev/null_bootrom.h b/drivers/net/wireless/hflps170/bl_bootrom.h ---- /dev/null_bootrom.h 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_bootrom.h 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,321 @@ -+#ifndef __BL_BOOTROOM_H__ -+#define __BL_BOOTROOM_H__ -+#include -+#pragma pack(push, 1) -+ -+#define BFLB_BOOTROM_HASH_SIZE 256/8 -+#define BFLB_BOOTROM_SIGN_MAXSIZE 2048/8 -+#define BFLB_BOOTROM_ECC_KEYXSIZE 256/8 -+#define BFLB_BOOTROM_ECC_KEYYSIZE 256/8 -+ -+typedef struct segment_header -+{ -+ uint32_t destaddr; -+ uint32_t len; -+ uint32_t rsv; -+ uint32_t crc32; -+} segment_header_t; -+ -+typedef struct spi_Flash_Cfg_Tag -+{ -+ uint8_t ioMode; -+ uint8_t cReadSupport; -+ uint8_t clk_delay; -+ uint8_t rsvd[1]; -+ -+ uint8_t resetEnCmd; -+ uint8_t resetCmd; -+ uint8_t resetCreadCmd; -+ uint8_t rsvd_reset[1]; -+ -+ uint8_t jedecIdCmd; /* jedec id cmd */ -+ uint8_t jedecIdCmdDmyClk; -+ uint8_t qpiJedecIdCmd; -+ uint8_t qpiJedecIdCmdDmyClk; -+ -+ uint8_t sectorSize; /* *1024bytes */ -+ uint8_t capBase; /* 0x17 for 64Mbits,0x18 for 128Mbits, 0x19 for 256Mbits */ -+ uint16_t pageSize; /* page size */ -+ -+ uint8_t chipEraseCmd; /* chip erase cmd */ -+ uint8_t sectorEraseCmd; /* sector erase command */ -+ uint8_t blk32EraseCmd; /* block 32K erase command,some Micron not support */ -+ uint8_t blk64EraseCmd; /* block 64K erase command */ -+ -+ uint8_t writeEnableCmd; /* need before every erase or program */ -+ uint8_t pageProgramCmd; /* page program cmd */ -+ uint8_t qpageProgramCmd; /* qio page program cmd */ -+ uint8_t qppAddrMode; /* gd and winbond and Micron use one line for addr while microchip use four lines */ -+ -+ uint8_t fastReadCmd; /* fast read command */ -+ uint8_t frDmyClk; -+ uint8_t qpiFastReadCmd; /* qpi fast read command */ -+ uint8_t qpiFrDmyClk; -+ -+ uint8_t fastReadDoCmd; /* fast read dual output command */ -+ uint8_t frDoDmyClk; -+ uint8_t fastReadDioCmd; /* fast read dual io comamnd */ -+ uint8_t frDioDmyClk; -+ -+ uint8_t fastReadQoCmd; /* fast read quad output comamnd */ -+ uint8_t frQoDmyClk; -+ uint8_t fastReadQioCmd; /* fast read quad io comamnd */ -+ uint8_t frQioDmyClk; -+ -+ uint8_t qpiFastReadQioCmd; /* qpi fast read quad io comamnd */ -+ uint8_t qpiFrQioDmyClk; -+ uint8_t qpiPageProgramCmd; /* qpi program command */ -+ uint8_t writeVregEnableCmd; /* enable write reg */ -+ -+ /*reg*/ -+ uint8_t wrEnableIndex; /* write enable bit index */ -+ uint8_t qeIndex; /* quad mode enable bit index */ -+ uint8_t busyIndex; /* busy status bit index */ -+ uint8_t wrEnableBit; -+ -+ uint8_t qeBit; -+ uint8_t busyBit; /* gd and winbond need set this bit for SPI_QIO, it seems that Micron need not */ -+ uint8_t wrEnableWriteRegLen; -+ uint8_t wrEnableReadRegLen; -+ -+ uint8_t qeWriteRegLen; -+ uint8_t qeReadRegLen; -+ uint8_t rsvd1; -+ uint8_t busyReadRegLen; -+ -+ uint8_t readRegCmd[4]; -+ -+ uint8_t writeRegCmd[4]; -+ -+ uint8_t enterQpi; /* enter qpi command */ -+ uint8_t exitQpi; /* exit qpi command */ -+ uint8_t cReadMode; /* continuous read modo value */ -+ uint8_t cRExit; -+ -+ uint8_t burstWrapCmd; /* wrap around operation */ -+ uint8_t burstWrapCmdDmyClk; -+ uint8_t burstWrapDataMode; -+ uint8_t burstWrapData; -+ -+ uint8_t deBurstWrapCmd; /* disable wrap around operation */ -+ uint8_t deBurstWrapCmdDmyClk; -+ uint8_t deBurstWrapDataMode; -+ uint8_t deBurstWrapData; -+ -+ uint16_t timeEsector; /* 4K erase time */ -+ uint16_t timeE32k; /* 32K erase time */ -+ -+ uint16_t timeE64k; /* 64K erase time */ -+ uint16_t timePagePgm; /* page program time */ -+ -+ uint32_t timeCe; /* chip erase time */ -+}spi_Flash_Cfg; -+ -+typedef struct boot_flash_cfg -+{ -+ uint32_t magiccode; /*'FCFG'*/ -+ spi_Flash_Cfg cfg; -+ uint32_t crc32; -+} boot_flash_cfg_t; -+ -+typedef struct boot_pll_cfg_t -+{ -+ uint32_t magiccode; /*'PCFG'*/ -+ -+ uint8_t root_clk; -+ uint8_t xtal_type; -+ uint8_t pll_clk; -+ uint8_t hclk_div; -+ -+ uint8_t bclk_div; -+ uint8_t flash_clk_div; -+ uint8_t uart_clk_div; -+ uint8_t sdu_clk_div; -+ -+ uint32_t crc32; -+} boot_pll_cfg_t; -+ -+typedef struct pkey_cfg -+{ -+ uint8_t eckeyx[BFLB_BOOTROM_ECC_KEYXSIZE]; //ec key in boot header -+ uint8_t eckeyy[BFLB_BOOTROM_ECC_KEYYSIZE]; //ec key in boot header -+ uint32_t crc32; -+} pkey_cfg_t; -+ -+typedef struct sign_cfg -+{ -+ uint32_t sig_len; -+ uint8_t signature[0]; -+ uint32_t crc32; //crc32 append tail, NOT use this field -+} sign_cfg_t; -+ -+typedef struct bootheader { -+ uint32_t magiccode; /*'BFXP'*/ -+ uint32_t rivison; -+ boot_flash_cfg_t flashCfg; -+ boot_pll_cfg_t pllCfg; -+ union { -+ struct { -+ uint32_t sign : 2; /* [3: 2] for sign */ -+ uint32_t encrypt : 2; /* [1: 0] for encrypt*/ -+ uint32_t key_sel : 2; /* [5: 4] for key sel in boot interface*/ -+ uint32_t rsvd6_31 : 26; /* [31:6] rsvd */ -+ } bval; -+ uint32_t wval; -+ } seccfg ; -+ uint32_t segment_cnt; -+ uint32_t bootentry; /* entry point of the image*/ -+ uint32_t flashoffset; -+ -+ uint8_t hash[BFLB_BOOTROM_HASH_SIZE]; /*hash of the image*/ -+ -+ uint32_t rsv1; -+ uint32_t rsv2; -+ uint32_t crc32; -+} bootheader_t; -+ -+typedef struct bootrom_host_cmd { -+ uint8_t id; -+ uint8_t reserved; -+ uint16_t len; -+ uint8_t data[0]; -+} bootrom_host_cmd_t; -+ -+typedef struct bootrom_host_cmd_password_load { -+ uint8_t id; -+ uint8_t reserved; -+ uint16_t len; -+ uint8_t data[8]; -+} bootrom_host_cmd_password_load_t; -+ -+typedef struct bootrom_host_cmd_jtag_open { -+ uint8_t id; -+ uint8_t reserved; -+ uint16_t len; -+ uint8_t data[8]; -+} bootrom_host_cmd_jtag_open_t; -+ -+typedef struct bootrom_res_bootinfo { -+ uint8_t status[2]; -+ uint16_t len; -+ uint32_t version; -+ -+ uint8_t password_mode; -+ uint8_t sboot_enable; -+ uint8_t jtag_disable; -+ uint8_t uart_disable; -+ -+ uint8_t sign_type; -+ uint8_t aes_type; -+ uint8_t reserved; -+ uint8_t chip_id[5]; -+ -+} bootrom_res_bootinfo_t; -+ -+typedef struct bootrom_res_password_load { -+ uint8_t status[2]; -+ uint16_t code; -+} bootrom_res_password_load_t; -+ -+typedef struct bootrom_res_jtag_open { -+ uint8_t status[2]; -+ uint16_t code; -+} bootrom_res_jtag_open_t; -+ -+typedef struct bootrom_res_bootheader_load { -+ uint8_t status[2]; -+ uint16_t code; -+} bootrom_res_bootheader_load_t; -+ -+typedef struct bootrom_res_aesiv_load { -+ uint8_t status[2]; -+ uint16_t code; -+} bootrom_res_aesiv_load_t; -+ -+typedef struct bootrom_res_pkey_load { -+ uint8_t status[2]; -+ uint16_t code; -+} bootrom_res_pkey_load_t; -+ -+typedef struct bootrom_res_signature_load { -+ uint8_t status[2]; -+ uint16_t code; -+} bootrom_res_signature_load_t; -+ -+typedef struct bootrom_res_tzc_load { -+ uint8_t status[2]; -+ uint16_t code; -+} bootrom_res_tzc_load_t; -+ -+typedef struct bootrom_res_sectionheader_load { -+ uint8_t status[2]; -+ uint16_t len;//reuse also as code. TODO: use union -+ segment_header_t header; -+} bootrom_res_sectionheader_load_t; -+ -+typedef struct bootrom_res_sectiondata_load { -+ uint8_t status[2]; -+ uint16_t code; -+} bootrom_res_sectiondata_load_t; -+ -+typedef struct bootrom_res_run { -+ uint8_t status[2]; -+ uint16_t code; -+} bootrom_res_run_t; -+ -+typedef struct bootrom_res_checkimage { -+ uint8_t status[2]; -+ uint16_t code; -+} bootrom_res_checkimage_t; -+ -+typedef struct bootrom_res_runimage { -+ uint8_t status[2]; -+ uint16_t code; -+} bootrom_res_runimage_t; -+#define BL_BOOTROM_HOST_CMD_LEN_HEADER 4 -+ -+#define BL_BOOTROM_HOST_CMD_BOOTINFO_GET 0x10 -+#define BL_BOOTROM_HOST_CMD_BOOTHEADER_LOAD 0x11 -+#define BL_BOOTROM_HOST_CMD_PK1_LOAD 0x12 -+#define BL_BOOTROM_HOST_CMD_PK2_LOAD 0x13 -+#define BL_BOOTROM_HOST_CMD_SIGNATURE1_LOAD 0x14 -+#define BL_BOOTROM_HOST_CMD_SIGNATURE2_LOAD 0x15 -+#define BL_BOOTROM_HOST_CMD_AESIV_LOAD 0x16 -+#define BL_BOOTROM_HOST_CMD_SECTIONHEADER_LOAD 0x17 -+#define BL_BOOTROM_HOST_CMD_SECTIONDATA_LOAD 0x18 -+#define BL_BOOTROM_HOST_CMD_CHECK_IMAGE 0x19 -+#define BL_BOOTROM_HOST_CMD_RUN 0x1A -+#define BL_BOOTROM_HOST_CMD_CHANGE_RATE 0x20 -+#define BL_BOOTROM_HOST_CMD_RESET 0x21 -+#define BL_BOOTROM_HOST_CMD_FLASH_ERASE 0x30 -+#define BL_BOOTROM_HOST_CMD_FLASH_WRITE 0x31 -+#define BL_BOOTROM_HOST_CMD_FLASH_READ 0x32 -+#define BL_BOOTROM_HOST_CMD_FLASH_BOOT 0x33 -+#define BL_BOOTROM_HOST_CMD_EFUSE_WRITE 0x40 -+#define BL_BOOTROM_HOST_CMD_EFUSE_READ 0x41 -+int bl_bootrom_cmd_len(bootrom_host_cmd_t *cmd); -+int bl_bootrom_cmd_bootinfo_get(bootrom_host_cmd_t *cmd); -+int bl_bootrom_cmd_bootinfo_get_res(bootrom_res_bootinfo_t *bootinfo); -+int bl_bootrom_cmd_bootheader_load(bootrom_host_cmd_t *cmd, bootheader_t *header); -+int bl_bootrom_cmd_bootheader_load_get_res(bootrom_res_bootheader_load_t *bootresponse); -+int bl_bootrom_cmd_aesiv_load(bootrom_host_cmd_t *cmd, const uint8_t *aesiv); -+int bl_bootrom_cmd_aesiv_load_get_res(bootrom_res_aesiv_load_t *bootresponse); -+int bl_bootrom_cmd_pkey1_load(bootrom_host_cmd_t *cmd, pkey_cfg_t *pk); -+int bl_bootrom_cmd_pkey1_load_get_res(bootrom_res_pkey_load_t *bootresponse); -+int bl_bootrom_cmd_pkey2_load(bootrom_host_cmd_t *cmd, pkey_cfg_t *pk); -+int bl_bootrom_cmd_pkey2_load_get_res(bootrom_res_pkey_load_t *bootresponse); -+int bl_bootrom_cmd_signature1_load(bootrom_host_cmd_t *cmd, uint8_t *signature, int len); -+int bl_bootrom_cmd_signature1_get_res(bootrom_res_signature_load_t *bootresponse); -+int bl_bootrom_cmd_signature2_load(bootrom_host_cmd_t *cmd, uint8_t *signature, int len); -+int bl_bootrom_cmd_signature2_get_res(bootrom_res_signature_load_t *bootresponse); -+int bl_bootrom_cmd_sectionheader_load(bootrom_host_cmd_t *cmd, const segment_header_t *header); -+int bl_bootrom_cmd_sectionheader_get_res(bootrom_res_sectionheader_load_t *bootresponse); -+int bl_bootrom_cmd_sectiondata_load(bootrom_host_cmd_t *cmd, const uint8_t *data, int len); -+int bl_bootrom_cmd_sectiondata_get_res(bootrom_res_sectiondata_load_t *bootresponse); -+int bl_bootrom_cmd_checkimage_get(bootrom_host_cmd_t *cmd); -+int bl_bootrom_cmd_checkimage_get_res(bootrom_res_checkimage_t *checkimage); -+int bl_bootrom_cmd_runimage_get(bootrom_host_cmd_t *cmd); -+int bl_bootrom_cmd_runimage_get_res(bootrom_res_runimage_t *runimage); -+ -+#pragma pack(pop) -+#endif -diff -Naur /dev/null_cfgfile.c b/drivers/net/wireless/hflps170/bl_cfgfile.c ---- /dev/null_cfgfile.c 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_cfgfile.c 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,237 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file bl_configparse.c -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ **************************************************************************************** -+ */ -+#include -+#include -+ -+#include "bl_defs.h" -+#include "bl_cfgfile.h" -+ -+/** -+ * -+ */ -+static const char *bl_find_tag(const u8 *file_data, unsigned int file_size, -+ const char *tag_name, unsigned int tag_len) -+{ -+ unsigned int curr, line_start = 0, line_size; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Walk through all the lines of the configuration file */ -+ while (line_start < file_size) { -+ /* Search the end of the current line (or the end of the file) */ -+ for (curr = line_start; curr < file_size; curr++) -+ if (file_data[curr] == '\n') -+ break; -+ -+ /* Compute the line size */ -+ line_size = curr - line_start; -+ -+ /* Check if this line contains the expected tag */ -+ if ((line_size == (strlen(tag_name) + tag_len)) && -+ (!strncmp(&file_data[line_start], tag_name, strlen(tag_name)))) -+ return (&file_data[line_start + strlen(tag_name)]); -+ -+ /* Move to next line */ -+ line_start = curr + 1; -+ } -+ -+ /* Tag not found */ -+ return NULL; -+} -+ -+/** -+ * Parse the Config file used at init time -+ */ -+int bl_parse_configfile(struct bl_hw *bl_hw, const char *filename, -+ struct bl_conf_file *config) -+{ -+ const struct firmware *config_fw; -+ u8 dflt_mac[ETH_ALEN] = { 0, 111, 111, 111, 111, 0 }; -+ int ret; -+ const u8 *tag_ptr; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ if ((ret = request_firmware(&config_fw, filename, bl_hw->dev))) { -+ printk(KERN_CRIT "%s: Failed to get %s (%d)\n", __func__, filename, ret); -+ return ret; -+ } -+ -+ /* Get MAC Address */ -+ tag_ptr = bl_find_tag(config_fw->data, config_fw->size, -+ "MAC_ADDR=", strlen("00:00:00:00:00:00")); -+ if (tag_ptr != NULL) { -+ u8 *addr = config->mac_addr; -+ if (sscanf(tag_ptr, -+ "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", -+ addr + 0, addr + 1, addr + 2, -+ addr + 3, addr + 4, addr + 5) != ETH_ALEN) -+ memcpy(config->mac_addr, dflt_mac, ETH_ALEN); -+ } else -+ memcpy(config->mac_addr, dflt_mac, ETH_ALEN); -+ -+ printk("MAC Address is:\n%pM\n", config->mac_addr); -+ -+ /* Release the configuration file */ -+ release_firmware(config_fw); -+ -+ return 0; -+} -+ -+/** -+ * Parse the Config file used at init time -+ */ -+int bl_parse_phy_configfile(struct bl_hw *bl_hw, const char *filename, -+ struct bl_phy_conf_file *config) -+{ -+ const struct firmware *config_fw; -+ int ret; -+ const u8 *tag_ptr; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ if ((ret = request_firmware(&config_fw, filename, bl_hw->dev))) { -+ printk(KERN_CRIT "%s: Failed to get %s (%d)\n", __func__, filename, ret); -+ return ret; -+ } -+ -+ /* Get Trident path mapping */ -+ tag_ptr = bl_find_tag(config_fw->data, config_fw->size, -+ "TRD_PATH_MAPPING=", strlen("00")); -+ if (tag_ptr != NULL) { -+ u8 val; -+ if (sscanf(tag_ptr, "%hhx", &val) == 1) -+ config->trd.path_mapping = val; -+ else -+ config->trd.path_mapping = bl_hw->mod_params->phy_cfg; -+ } else -+ config->trd.path_mapping = bl_hw->mod_params->phy_cfg; -+ -+ BL_DBG("Trident path mapping is: %d\n", config->trd.path_mapping); -+ -+ /* Get DC offset compensation */ -+ tag_ptr = bl_find_tag(config_fw->data, config_fw->size, -+ "TX_DC_OFF_COMP=", strlen("00000000")); -+ if (tag_ptr != NULL) { -+ if (sscanf(tag_ptr, "%08x", &config->trd.tx_dc_off_comp) != 1) -+ config->trd.tx_dc_off_comp = 0; -+ } else -+ config->trd.tx_dc_off_comp = 0; -+ -+ BL_DBG("TX DC offset compensation is: %08X\n", config->trd.tx_dc_off_comp); -+ -+ /* Get Karst TX IQ compensation value for path0 on 2.4GHz */ -+ tag_ptr = bl_find_tag(config_fw->data, config_fw->size, -+ "KARST_TX_IQ_COMP_2_4G_PATH_0=", strlen("00000000")); -+ if (tag_ptr != NULL) { -+ if (sscanf(tag_ptr, "%08x", &config->karst.tx_iq_comp_2_4G[0]) != 1) -+ config->karst.tx_iq_comp_2_4G[0] = 0x01000000; -+ } else -+ config->karst.tx_iq_comp_2_4G[0] = 0x01000000; -+ -+ BL_DBG("Karst TX IQ compensation for path 0 on 2.4GHz is: %08X\n", config->karst.tx_iq_comp_2_4G[0]); -+ -+ /* Get Karst TX IQ compensation value for path1 on 2.4GHz */ -+ tag_ptr = bl_find_tag(config_fw->data, config_fw->size, -+ "KARST_TX_IQ_COMP_2_4G_PATH_1=", strlen("00000000")); -+ if (tag_ptr != NULL) { -+ if (sscanf(tag_ptr, "%08x", &config->karst.tx_iq_comp_2_4G[1]) != 1) -+ config->karst.tx_iq_comp_2_4G[1] = 0x01000000; -+ } else -+ config->karst.tx_iq_comp_2_4G[1] = 0x01000000; -+ -+ BL_DBG("Karst TX IQ compensation for path 1 on 2.4GHz is: %08X\n", config->karst.tx_iq_comp_2_4G[1]); -+ -+ /* Get Karst RX IQ compensation value for path0 on 2.4GHz */ -+ tag_ptr = bl_find_tag(config_fw->data, config_fw->size, -+ "KARST_RX_IQ_COMP_2_4G_PATH_0=", strlen("00000000")); -+ if (tag_ptr != NULL) { -+ if (sscanf(tag_ptr, "%08x", &config->karst.rx_iq_comp_2_4G[0]) != 1) -+ config->karst.rx_iq_comp_2_4G[0] = 0x01000000; -+ } else -+ config->karst.rx_iq_comp_2_4G[0] = 0x01000000; -+ -+ BL_DBG("Karst RX IQ compensation for path 0 on 2.4GHz is: %08X\n", config->karst.rx_iq_comp_2_4G[0]); -+ -+ /* Get Karst RX IQ compensation value for path1 on 2.4GHz */ -+ tag_ptr = bl_find_tag(config_fw->data, config_fw->size, -+ "KARST_RX_IQ_COMP_2_4G_PATH_1=", strlen("00000000")); -+ if (tag_ptr != NULL) { -+ if (sscanf(tag_ptr, "%08x", &config->karst.rx_iq_comp_2_4G[1]) != 1) -+ config->karst.rx_iq_comp_2_4G[1] = 0x01000000; -+ } else -+ config->karst.rx_iq_comp_2_4G[1] = 0x01000000; -+ -+ BL_DBG("Karst RX IQ compensation for path 1 on 2.4GHz is: %08X\n", config->karst.rx_iq_comp_2_4G[1]); -+ -+ /* Get Karst TX IQ compensation value for path0 on 5GHz */ -+ tag_ptr = bl_find_tag(config_fw->data, config_fw->size, -+ "KARST_TX_IQ_COMP_5G_PATH_0=", strlen("00000000")); -+ if (tag_ptr != NULL) { -+ if (sscanf(tag_ptr, "%08x", &config->karst.tx_iq_comp_5G[0]) != 1) -+ config->karst.tx_iq_comp_5G[0] = 0x01000000; -+ } else -+ config->karst.tx_iq_comp_5G[0] = 0x01000000; -+ -+ BL_DBG("Karst TX IQ compensation for path 0 on 5GHz is: %08X\n", config->karst.tx_iq_comp_5G[0]); -+ -+ /* Get Karst TX IQ compensation value for path1 on 5GHz */ -+ tag_ptr = bl_find_tag(config_fw->data, config_fw->size, -+ "KARST_TX_IQ_COMP_5G_PATH_1=", strlen("00000000")); -+ if (tag_ptr != NULL) { -+ if (sscanf(tag_ptr, "%08x", &config->karst.tx_iq_comp_5G[1]) != 1) -+ config->karst.tx_iq_comp_5G[1] = 0x01000000; -+ } else -+ config->karst.tx_iq_comp_5G[1] = 0x01000000; -+ -+ BL_DBG("Karst TX IQ compensation for path 1 on 5GHz is: %08X\n", config->karst.tx_iq_comp_5G[1]); -+ -+ /* Get Karst RX IQ compensation value for path0 on 5GHz */ -+ tag_ptr = bl_find_tag(config_fw->data, config_fw->size, -+ "KARST_RX_IQ_COMP_5G_PATH_0=", strlen("00000000")); -+ if (tag_ptr != NULL) { -+ if (sscanf(tag_ptr, "%08x", &config->karst.rx_iq_comp_5G[0]) != 1) -+ config->karst.rx_iq_comp_5G[0] = 0x01000000; -+ } else -+ config->karst.rx_iq_comp_5G[0] = 0x01000000; -+ -+ BL_DBG("Karst RX IQ compensation for path 0 on 5GHz is: %08X\n", config->karst.rx_iq_comp_5G[0]); -+ -+ /* Get Karst RX IQ compensation value for path1 on 5GHz */ -+ tag_ptr = bl_find_tag(config_fw->data, config_fw->size, -+ "KARST_RX_IQ_COMP_5G_PATH_1=", strlen("00000000")); -+ if (tag_ptr != NULL) { -+ if (sscanf(tag_ptr, "%08x", &config->karst.rx_iq_comp_5G[1]) != 1) -+ config->karst.rx_iq_comp_5G[1] = 0x01000000; -+ } else -+ config->karst.rx_iq_comp_5G[1] = 0x01000000; -+ -+ BL_DBG("Karst RX IQ compensation for path 1 on 5GHz is: %08X\n", config->karst.rx_iq_comp_5G[1]); -+ -+ /* Get Karst default path */ -+ tag_ptr = bl_find_tag(config_fw->data, config_fw->size, -+ "KARST_DEFAULT_PATH=", strlen("00")); -+ if (tag_ptr != NULL) { -+ u8 val; -+ if (sscanf(tag_ptr, "%hhx", &val) == 1) -+ config->karst.path_used = val; -+ else -+ config->karst.path_used = bl_hw->mod_params->phy_cfg; -+ } else -+ config->karst.path_used = bl_hw->mod_params->phy_cfg; -+ -+ BL_DBG("Karst default path is: %d\n", config->karst.path_used); -+ -+ /* Release the configuration file */ -+ release_firmware(config_fw); -+ -+ return 0; -+} -+ -diff -Naur /dev/null_cfgfile.h b/drivers/net/wireless/hflps170/bl_cfgfile.h ---- /dev/null_cfgfile.h 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_cfgfile.h 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,35 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file bl_cfgfile.h -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ **************************************************************************************** -+ */ -+ -+#ifndef _BL_CFGFILE_H_ -+#define _BL_CFGFILE_H_ -+ -+/* -+ * Structure used to retrieve information from the Config file used at Initialization time -+ */ -+struct bl_conf_file { -+ u8 mac_addr[ETH_ALEN]; -+}; -+ -+/* -+ * Structure used to retrieve information from the PHY Config file used at Initialization time -+ */ -+struct bl_phy_conf_file { -+ struct phy_trd_cfg_tag trd; -+ struct phy_karst_cfg_tag karst; -+}; -+ -+int bl_parse_configfile(struct bl_hw *bl_hw, const char *filename, -+ struct bl_conf_file *config); -+ -+int bl_parse_phy_configfile(struct bl_hw *bl_hw, const char *filename, -+ struct bl_phy_conf_file *config); -+ -+#endif /* _BL_CFGFILE_H_ */ -diff -Naur /dev/null_cmds.c b/drivers/net/wireless/hflps170/bl_cmds.c ---- /dev/null_cmds.c 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_cmds.c 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,266 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file bl_cmds.c -+ * -+ * @brief Handles queueing (push to IPC, ack/cfm from IPC) of commands issued to LMAC FW -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ **************************************************************************************** -+ */ -+ -+#include -+ -+#include "bl_cmds.h" -+#include "bl_defs.h" -+#include "bl_msg_tx.h" -+#include "bl_strs.h" -+#define CREATE_TRACE_POINTS -+#include "bl_events.h" -+#include "bl_debugfs.h" -+#include "bl_sdio.h" -+#include "bl_v7.h" -+#include "bl_irqs.h" -+ -+ -+static void cmd_mgr_print(struct bl_cmd_mgr *cmd_mgr); -+ -+void cmd_dump(const struct bl_cmd *cmd) -+{ -+ BL_DBG("tkn[%d] flags:%04x result:%3d cmd:%4d-%-24s - reqcfm(%4d-%-s)\n", -+ cmd->tkn, cmd->flags, cmd->result, cmd->id, BL_ID2STR(cmd->id), -+ cmd->reqid, cmd->reqid != (lmac_msg_id_t)-1 ? BL_ID2STR(cmd->reqid) : "none"); -+} -+ -+static void cmd_complete(struct bl_cmd_mgr *cmd_mgr, struct bl_cmd *cmd) -+{ -+ lockdep_assert_held(&cmd_mgr->lock); -+ -+ list_del(&cmd->list); -+ cmd_mgr->queue_sz--; -+ -+ cmd->flags |= BL_CMD_FLAG_DONE; -+ if (cmd->flags & BL_CMD_FLAG_NONBLOCK) { -+ kfree(cmd); -+ } else { -+ if (BL_CMD_WAIT_COMPLETE(cmd->flags)) { -+ cmd->result = 0; -+ complete(&cmd->complete); -+ } -+ } -+} -+ -+static int cmd_mgr_queue(struct bl_cmd_mgr *cmd_mgr, struct bl_cmd *cmd) -+{ -+ struct bl_hw *bl_hw = container_of(cmd_mgr, struct bl_hw, cmd_mgr); -+ struct bl_cmd *last; -+ unsigned long tout; -+ bool defer_push = false; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ trace_msg_send(cmd->id); -+ -+ spin_lock_bh(&cmd_mgr->lock); -+ -+ if (cmd_mgr->state == BL_CMD_MGR_STATE_CRASHED) { -+ printk(KERN_CRIT"cmd queue crashed\n"); -+ cmd->result = -EPIPE; -+ spin_unlock_bh(&cmd_mgr->lock); -+ return -EPIPE; -+ } -+ -+ if (!list_empty(&cmd_mgr->cmds)) { -+ if (cmd_mgr->queue_sz == cmd_mgr->max_queue_sz) { -+ printk(KERN_CRIT"Too many cmds (%d) already queued\n", -+ cmd_mgr->max_queue_sz); -+ cmd->result = -ENOMEM; -+ spin_unlock_bh(&cmd_mgr->lock); -+ return -ENOMEM; -+ } -+ last = list_entry(cmd_mgr->cmds.prev, struct bl_cmd, list); -+ if (last->flags & (BL_CMD_FLAG_WAIT_ACK | BL_CMD_FLAG_WAIT_PUSH)) { -+ cmd->flags |= BL_CMD_FLAG_WAIT_PUSH; -+ defer_push = true; -+ } -+ } -+ -+ cmd->flags |= BL_CMD_FLAG_WAIT_ACK; -+ if (cmd->flags & BL_CMD_FLAG_REQ_CFM) -+ cmd->flags |= BL_CMD_FLAG_WAIT_CFM; -+ -+ cmd->tkn = cmd_mgr->next_tkn++; -+ cmd->result = -EINTR; -+ -+ if (!(cmd->flags & BL_CMD_FLAG_NONBLOCK)) -+ init_completion(&cmd->complete); -+ -+ list_add_tail(&cmd->list, &cmd_mgr->cmds); -+ cmd_mgr->queue_sz++; -+ tout = msecs_to_jiffies(BL_80211_CMD_TIMEOUT_MS * cmd_mgr->queue_sz); -+ spin_unlock_bh(&cmd_mgr->lock); -+ -+ if (!defer_push) { -+ ASSERT_ERR(!(bl_hw->ipc_env->msga2e_hostid)); -+ bl_hw->ipc_env->msga2e_hostid = (void *)cmd; -+ spin_lock_bh(&bl_hw->cmd_lock); -+ bl_hw->cmd_sent = true; -+ spin_unlock_bh(&bl_hw->cmd_lock); -+ bl_queue_main_work(bl_hw); -+ } -+ -+ BL_DBG("send: cmd:%4d-%-24s\n", cmd->id, BL_ID2STR(cmd->id)); -+ -+ if (!(cmd->flags & BL_CMD_FLAG_NONBLOCK)) { -+ if (!wait_for_completion_timeout(&cmd->complete, tout)) { -+ printk("wait for cmd cfm timeout!\n"); -+ cmd_dump(cmd); -+ spin_lock_bh(&cmd_mgr->lock); -+ cmd_mgr->state = BL_CMD_MGR_STATE_CRASHED; -+ if (!(cmd->flags & BL_CMD_FLAG_DONE)) { -+ cmd->result = -ETIMEDOUT; -+ cmd_complete(cmd_mgr, cmd); -+ } -+ spin_unlock_bh(&cmd_mgr->lock); -+ } -+ } else { -+ cmd->result = 0; -+ } -+ -+ return 0; -+} -+ -+static int cmd_mgr_llind(struct bl_cmd_mgr *cmd_mgr, struct bl_cmd *cmd) -+{ -+ struct bl_cmd *cur, *acked = NULL, *next = NULL; -+ struct bl_hw *bl_hw = container_of(cmd_mgr, struct bl_hw, cmd_mgr); -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ spin_lock(&cmd_mgr->lock); -+ list_for_each_entry(cur, &cmd_mgr->cmds, list) { -+ if (!acked) { -+ if (cur->tkn == cmd->tkn) { -+ if (WARN_ON_ONCE(cur != cmd)) { -+ cmd_mgr_print(cmd_mgr); -+ //cmd_dump(cmd); -+ } -+ acked = cur; -+ continue; -+ } -+ } -+ if (cur->flags & BL_CMD_FLAG_WAIT_PUSH) { -+ next = cur; -+ break; -+ } -+ } -+ if (!acked) { -+ printk(KERN_CRIT "Error: acked cmd not found\n"); -+ } else { -+ cmd->flags &= ~BL_CMD_FLAG_WAIT_ACK; -+ if (BL_CMD_WAIT_COMPLETE(cmd->flags)) { -+ cmd_complete(cmd_mgr, cmd); -+ } -+ } -+ if (next) { -+ ASSERT_ERR(!(bl_hw->ipc_env->msga2e_hostid)); -+ bl_hw->ipc_env->msga2e_hostid = (void *)next; -+ spin_lock_bh(&bl_hw->cmd_lock); -+ bl_hw->cmd_sent = true; -+ spin_unlock_bh(&bl_hw->cmd_lock); -+ bl_queue_main_work(bl_hw); -+ } -+ spin_unlock(&cmd_mgr->lock); -+ -+ return 0; -+} -+ -+static int cmd_mgr_msgind(struct bl_cmd_mgr *cmd_mgr, struct ipc_e2a_msg *msg, msg_cb_fct cb) -+{ -+ struct bl_hw *bl_hw = container_of(cmd_mgr, struct bl_hw, cmd_mgr); -+ struct bl_cmd *cmd; -+ bool found = false; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ trace_msg_recv(msg->id); -+ -+ spin_lock(&cmd_mgr->lock); -+ list_for_each_entry(cmd, &cmd_mgr->cmds, list) { -+ if (cmd->reqid == msg->id && -+ (cmd->flags & BL_CMD_FLAG_WAIT_CFM)) { -+ if (!cb || (cb && !cb(bl_hw, cmd, msg))) { -+ found = true; -+ cmd->flags &= ~BL_CMD_FLAG_WAIT_CFM; -+ -+ if (cmd->e2a_msg && msg->param_len) -+ memcpy(cmd->e2a_msg, &msg->param, msg->param_len); -+ -+ if (BL_CMD_WAIT_COMPLETE(cmd->flags)){ -+ cmd_complete(cmd_mgr, cmd); -+ } -+ -+ break; -+ } -+ } -+ } -+ spin_unlock(&cmd_mgr->lock); -+ -+ if (!found && cb) -+ { -+ cb(bl_hw, NULL, msg); -+ } -+ -+ return 0; -+} -+ -+static void cmd_mgr_print(struct bl_cmd_mgr *cmd_mgr) -+{ -+ struct bl_cmd *cur; -+ -+ spin_lock_bh(&cmd_mgr->lock); -+ BL_DBG("q_sz/max: %2d / %2d - next tkn: %d\n", -+ cmd_mgr->queue_sz, cmd_mgr->max_queue_sz, -+ cmd_mgr->next_tkn); -+ list_for_each_entry(cur, &cmd_mgr->cmds, list) { -+ cmd_dump(cur); -+ } -+ spin_unlock_bh(&cmd_mgr->lock); -+} -+ -+static void cmd_mgr_drain(struct bl_cmd_mgr *cmd_mgr) -+{ -+ struct bl_cmd *cur, *nxt; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ spin_lock_bh(&cmd_mgr->lock); -+ list_for_each_entry_safe(cur, nxt, &cmd_mgr->cmds, list) { -+ list_del(&cur->list); -+ cmd_mgr->queue_sz--; -+ if (!(cur->flags & BL_CMD_FLAG_NONBLOCK)) -+ complete(&cur->complete); -+ } -+ spin_unlock_bh(&cmd_mgr->lock); -+} -+ -+void bl_cmd_mgr_init(struct bl_cmd_mgr *cmd_mgr) -+{ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ INIT_LIST_HEAD(&cmd_mgr->cmds); -+ spin_lock_init(&cmd_mgr->lock); -+ cmd_mgr->max_queue_sz = BL_CMD_MAX_QUEUED; -+ cmd_mgr->queue = &cmd_mgr_queue; -+ cmd_mgr->print = &cmd_mgr_print; -+ cmd_mgr->drain = &cmd_mgr_drain; -+ cmd_mgr->llind = &cmd_mgr_llind; -+ cmd_mgr->msgind = &cmd_mgr_msgind; -+} -+ -+void bl_cmd_mgr_deinit(struct bl_cmd_mgr *cmd_mgr) -+{ -+ cmd_mgr->print(cmd_mgr); -+ cmd_mgr->drain(cmd_mgr); -+ cmd_mgr->print(cmd_mgr); -+ memset(cmd_mgr, 0, sizeof(*cmd_mgr)); -+} -diff -Naur /dev/null_cmds.h b/drivers/net/wireless/hflps170/bl_cmds.h ---- /dev/null_cmds.h 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_cmds.h 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,82 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file bl_cmds.h -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ **************************************************************************************** -+ */ -+ -+#ifndef _BL_CMDS_H_ -+#define _BL_CMDS_H_ -+ -+#include -+#include -+#include "lmac_msg.h" -+#include "ipc_shared.h" -+ -+#ifdef CONFIG_BL_SDM -+#define BL_80211_CMD_TIMEOUT_MS (20 * 300) -+#else -+#define BL_80211_CMD_TIMEOUT_MS 2000 -+#endif -+ -+#define BL_CMD_FLAG_NONBLOCK BIT(0) -+#define BL_CMD_FLAG_REQ_CFM BIT(1) -+#define BL_CMD_FLAG_WAIT_PUSH BIT(2) -+#define BL_CMD_FLAG_WAIT_ACK BIT(3) -+#define BL_CMD_FLAG_WAIT_CFM BIT(4) -+#define BL_CMD_FLAG_DONE BIT(5) -+/* ATM IPC design makes it possible to get the CFM before the ACK, -+ * otherwise this could have simply been a state enum */ -+#define BL_CMD_WAIT_COMPLETE(flags) \ -+ (!(flags & (BL_CMD_FLAG_WAIT_ACK | BL_CMD_FLAG_WAIT_CFM))) -+ -+#define BL_CMD_MAX_QUEUED 8 -+ -+struct bl_hw; -+struct bl_cmd; -+typedef int (*msg_cb_fct)(struct bl_hw *bl_hw, struct bl_cmd *cmd, -+ struct ipc_e2a_msg *msg); -+ -+enum bl_cmd_mgr_state { -+ BL_CMD_MGR_STATE_DEINIT, -+ BL_CMD_MGR_STATE_INITED, -+ BL_CMD_MGR_STATE_CRASHED, -+}; -+ -+struct bl_cmd { -+ struct list_head list; -+ lmac_msg_id_t id; -+ lmac_msg_id_t reqid; -+ struct lmac_msg *a2e_msg; -+ char *e2a_msg; -+ u32 tkn; -+ u16 flags; -+ -+ struct completion complete; -+ u32 result; -+}; -+ -+struct bl_cmd_mgr { -+ enum bl_cmd_mgr_state state; -+ spinlock_t lock; -+ u32 next_tkn; -+ u32 queue_sz; -+ u32 max_queue_sz; -+ -+ struct list_head cmds; -+ -+ int (*queue)(struct bl_cmd_mgr *, struct bl_cmd *); -+ int (*llind)(struct bl_cmd_mgr *, struct bl_cmd *); -+ int (*msgind)(struct bl_cmd_mgr *, struct ipc_e2a_msg *, msg_cb_fct); -+ void (*print)(struct bl_cmd_mgr *); -+ void (*drain)(struct bl_cmd_mgr *); -+}; -+ -+void cmd_dump(const struct bl_cmd *cmd); -+void bl_cmd_mgr_init(struct bl_cmd_mgr *cmd_mgr); -+void bl_cmd_mgr_deinit(struct bl_cmd_mgr *cmd_mgr); -+ -+#endif /* _BL_CMDS_H_ */ -diff -Naur /dev/null_compat.h b/drivers/net/wireless/hflps170/bl_compat.h ---- /dev/null_compat.h 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_compat.h 2021-01-19 10:07:10.000000000 +0200 -@@ -0,0 +1,508 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file bl_compat.h -+ * -+ * Ensure driver compilation for linux 3.16 to 5.5. -+ * -+ * To avoid too many #if LINUX_VERSION_CODE in the code, when prototype change -+ * between different kernel version: -+ * - For external function, define a macro whose name is the function name with -+ * _compat suffix and prototype (actually the number of parameter) of the -+ * latest version. Then latest version this macro simply call the function -+ * and for older kernel version it call the function adapting the api. -+ * - For internal function (e.g. cfg80211_ops) do the same but the macro name -+ * doesn't need to have the _compat suffix when the function is not used -+ * directly by the driver -+ * -+ ****************************************************************************** -+ */ -+#ifndef _bl_COMPAT_H_ -+#define _bl_COMPAT_H_ -+#include -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0) -+#error "Minimum kernel version supported is 3.16" -+#endif -+ -+/* Generic */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0) -+#define __bf_shf(x) (__builtin_ffsll(x) - 1) -+#define FIELD_PREP(_mask, _val) \ -+ (((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask)) -+#else -+#include -+#endif // 4.9 -+ -+#if 0 -+/* CFG80211 */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 1, 0) -+#define WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT 0 -+ -+#define IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_0US 0x00 -+#define IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_8US 0x40 -+#define IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_16US 0x80 -+#define IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_RESERVED 0xc0 -+#define IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_MASK 0xc0 -+ -+struct element { -+ u8 id; -+ u8 datalen; -+ u8 data[]; -+} __packed; -+ -+#define for_each_element(_elem, _data, _datalen) \ -+ for (_elem = (const struct element *)(_data); \ -+ (const u8 *)(_data) + (_datalen) - (const u8 *)_elem >= \ -+ (int)sizeof(*_elem) && \ -+ (const u8 *)(_data) + (_datalen) - (const u8 *)_elem >= \ -+ (int)sizeof(*_elem) + _elem->datalen; \ -+ _elem = (const struct element *)(_elem->data + _elem->datalen)) -+ -+static inline const struct element * -+cfg80211_find_elem(u8 eid, const u8 *ies, int len) -+{ -+ const struct element *elem; -+ for_each_element(elem, ies, len) { -+ if (elem->id == (eid)) -+ return elem; -+ } -+ return NULL; -+} -+ -+#endif // 5.1 -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0) -+#define cfg80211_notify_new_peer_candidate(dev, addr, ie, ie_len, sig_dbm, gfp) \ -+ cfg80211_notify_new_peer_candidate(dev, addr, ie, ie_len, gfp) -+ -+#define WLAN_EXT_CAPA10_TWT_REQUESTER_SUPPORT BIT(5) -+#define WLAN_EXT_CAPA10_TWT_RESPONDER_SUPPORT BIT(6) -+ -+#endif // 5.0 -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0) -+#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK IEEE80211_HE_MAC_CAP3_MAX_A_AMPDU_LEN_EXP_MASK -+#endif // 4.20 -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) -+#define IEEE80211_RADIOTAP_HE 23 -+#define IEEE80211_RADIOTAP_HE_MU 24 -+ -+struct ieee80211_radiotap_he { -+ __le16 data1, data2, data3, data4, data5, data6; -+}; -+ -+enum ieee80211_radiotap_he_bits { -+ IEEE80211_RADIOTAP_HE_DATA1_FORMAT_MASK = 3, -+ IEEE80211_RADIOTAP_HE_DATA1_FORMAT_SU = 0, -+ IEEE80211_RADIOTAP_HE_DATA1_FORMAT_EXT_SU = 1, -+ IEEE80211_RADIOTAP_HE_DATA1_FORMAT_MU = 2, -+ IEEE80211_RADIOTAP_HE_DATA1_FORMAT_TRIG = 3, -+ -+ IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN = 0x0004, -+ IEEE80211_RADIOTAP_HE_DATA1_BEAM_CHANGE_KNOWN = 0x0008, -+ IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN = 0x0010, -+ IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN = 0x0020, -+ IEEE80211_RADIOTAP_HE_DATA1_DATA_DCM_KNOWN = 0x0040, -+ IEEE80211_RADIOTAP_HE_DATA1_CODING_KNOWN = 0x0080, -+ IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN = 0x0100, -+ IEEE80211_RADIOTAP_HE_DATA1_STBC_KNOWN = 0x0200, -+ IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN = 0x0400, -+ IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE2_KNOWN = 0x0800, -+ IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE3_KNOWN = 0x1000, -+ IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE4_KNOWN = 0x2000, -+ IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN = 0x4000, -+ IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN = 0x8000, -+ -+ IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_KNOWN = 0x0001, -+ IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN = 0x0002, -+ IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN = 0x0004, -+ IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN = 0x0008, -+ IEEE80211_RADIOTAP_HE_DATA2_TXBF_KNOWN = 0x0010, -+ IEEE80211_RADIOTAP_HE_DATA2_PE_DISAMBIG_KNOWN = 0x0020, -+ IEEE80211_RADIOTAP_HE_DATA2_TXOP_KNOWN = 0x0040, -+ IEEE80211_RADIOTAP_HE_DATA2_MIDAMBLE_KNOWN = 0x0080, -+ IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET = 0x3f00, -+ IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET_KNOWN = 0x4000, -+ IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_SEC = 0x8000, -+ -+ IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR = 0x003f, -+ IEEE80211_RADIOTAP_HE_DATA3_BEAM_CHANGE = 0x0040, -+ IEEE80211_RADIOTAP_HE_DATA3_UL_DL = 0x0080, -+ IEEE80211_RADIOTAP_HE_DATA3_DATA_MCS = 0x0f00, -+ IEEE80211_RADIOTAP_HE_DATA3_DATA_DCM = 0x1000, -+ IEEE80211_RADIOTAP_HE_DATA3_CODING = 0x2000, -+ IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG = 0x4000, -+ IEEE80211_RADIOTAP_HE_DATA3_STBC = 0x8000, -+ -+ IEEE80211_RADIOTAP_HE_DATA4_SU_MU_SPTL_REUSE = 0x000f, -+ IEEE80211_RADIOTAP_HE_DATA4_MU_STA_ID = 0x7ff0, -+ IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE1 = 0x000f, -+ IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE2 = 0x00f0, -+ IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE3 = 0x0f00, -+ IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE4 = 0xf000, -+ -+ IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC = 0x000f, -+ IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_20MHZ = 0, -+ IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_40MHZ = 1, -+ IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_80MHZ = 2, -+ IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_160MHZ = 3, -+ IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_26T = 4, -+ IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_52T = 5, -+ IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_106T = 6, -+ IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_242T = 7, -+ IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_484T = 8, -+ IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_996T = 9, -+ IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_2x996T = 10, -+ -+ IEEE80211_RADIOTAP_HE_DATA5_GI = 0x0030, -+ IEEE80211_RADIOTAP_HE_DATA5_GI_0_8 = 0, -+ IEEE80211_RADIOTAP_HE_DATA5_GI_1_6 = 1, -+ IEEE80211_RADIOTAP_HE_DATA5_GI_3_2 = 2, -+ -+ IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE = 0x00c0, -+ IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_UNKNOWN = 0, -+ IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_1X = 1, -+ IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_2X = 2, -+ IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_4X = 3, -+ IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS = 0x0700, -+ IEEE80211_RADIOTAP_HE_DATA5_PRE_FEC_PAD = 0x3000, -+ IEEE80211_RADIOTAP_HE_DATA5_TXBF = 0x4000, -+ IEEE80211_RADIOTAP_HE_DATA5_PE_DISAMBIG = 0x8000, -+ -+ IEEE80211_RADIOTAP_HE_DATA6_NSTS = 0x000f, -+ IEEE80211_RADIOTAP_HE_DATA6_DOPPLER = 0x0010, -+ IEEE80211_RADIOTAP_HE_DATA6_TXOP = 0x7f00, -+ IEEE80211_RADIOTAP_HE_DATA6_MIDAMBLE_PDCTY = 0x8000, -+}; -+ -+struct ieee80211_radiotap_he_mu { -+ __le16 flags1, flags2; -+ u8 ru_ch1[4]; -+ u8 ru_ch2[4]; -+}; -+ -+enum ieee80211_radiotap_he_mu_bits { -+ IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS = 0x000f, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS_KNOWN = 0x0010, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM = 0x0020, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM_KNOWN = 0x0040, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH2_CTR_26T_RU_KNOWN = 0x0080, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_RU_KNOWN = 0x0100, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH2_RU_KNOWN = 0x0200, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_CTR_26T_RU_KNOWN = 0x1000, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_CTR_26T_RU = 0x2000, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_COMP_KNOWN = 0x4000, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN = 0x8000, -+ -+ IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW = 0x0003, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_20MHZ = 0x0000, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_40MHZ = 0x0001, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_80MHZ = 0x0002, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_160MHZ = 0x0003, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN = 0x0004, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_COMP = 0x0008, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_SYMS_USERS = 0x00f0, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW = 0x0300, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW_KNOWN= 0x0400, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS2_CH2_CTR_26T_RU = 0x0800, -+}; -+ -+enum { -+ IEEE80211_HE_MCS_SUPPORT_0_7 = 0, -+ IEEE80211_HE_MCS_SUPPORT_0_9 = 1, -+ IEEE80211_HE_MCS_SUPPORT_0_11 = 2, -+ IEEE80211_HE_MCS_NOT_SUPPORTED = 3, -+}; -+#endif // 4.19 -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0) -+#define cfg80211_probe_status(ndev, addr, cookie, ack, ack_pwr, pwr_valid, gfp) \ -+ cfg80211_probe_status(ndev, addr, cookie, ack, gfp) -+#endif // 4.17 -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0) -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0) -+#define bl_cfg80211_add_iface(wiphy, name, name_assign_type, type, params) \ -+ bl_cfg80211_add_iface(wiphy, name, type, u32 *flags, params) -+#else -+#define bl_cfg80211_add_iface(wiphy, name, name_assign_type, type, params) \ -+ bl_cfg80211_add_iface(wiphy, name, name_assign_type, type, u32 *flags, params) -+#endif -+ -+#define bl_cfg80211_change_iface(wiphy, dev, type, params) \ -+ bl_cfg80211_change_iface(wiphy, dev, type, u32 *flags, params) -+ -+#define CCFS0(vht) vht->center_freq_seg1_idx -+#define CCFS1(vht) vht->center_freq_seg2_idx -+ -+#define nla_parse(tb, maxtype, head, len, policy, extack) \ -+ nla_parse(tb, maxtype, head, len, policy) -+ -+struct cfg80211_roam_info { -+ struct ieee80211_channel *channel; -+ struct cfg80211_bss *bss; -+ const u8 *bssid; -+ const u8 *req_ie; -+ size_t req_ie_len; -+ const u8 *resp_ie; -+ size_t resp_ie_len; -+}; -+ -+#define cfg80211_roamed(_dev, _info, _gfp) \ -+ cfg80211_roamed(_dev, (_info)->channel, (_info)->bssid, (_info)->req_ie, \ -+ (_info)->req_ie_len, (_info)->resp_ie, (_info)->resp_ie_len, _gfp) -+ -+#else -+ -+#define CCFS0(vht) vht->center_freq_seg0_idx -+#define CCFS1(vht) vht->center_freq_seg1_idx -+#endif // 4.12 -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0) -+#define cfg80211_cqm_rssi_notify(dev, event, level, gfp) \ -+ cfg80211_cqm_rssi_notify(dev, event, gfp) -+#endif // 4.11 -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0) -+#define ieee80211_amsdu_to_8023s(skb, list, addr, iftype, extra_headroom, check_da, check_sa) \ -+ ieee80211_amsdu_to_8023s(skb, list, addr, iftype, extra_headroom, false) -+#endif // 4.9 -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 7, 0) -+#define NUM_NL80211_BANDS IEEE80211_NUM_BANDS -+#endif // 4.7 -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) -+#define cfg80211_disconnected(dev, reason, ie, len, local, gfp) \ -+ cfg80211_disconnected(dev, reason, ie, len, gfp) -+#endif // 4.2 -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) && !(defined CONFIG_VENDOR_bl) -+#define ieee80211_chandef_to_operating_class(chan_def, op_class) 0 -+#endif // 4.1 -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0) -+#define WLAN_CIPHER_SUITE_GCMP_256 0x000FAC09 -+#define WLAN_CIPHER_SUITE_CCMP_256 0x000FAC0A -+ -+#define IEEE80211_CCMP_256_MIC_LEN 16 -+#define IEEE80211_GCMP_MIC_LEN 16 -+ -+#define SURVEY_INFO_TIME SURVEY_INFO_CHANNEL_TIME -+#define SURVEY_INFO_TIME_BUSY SURVEY_INFO_CHANNEL_TIME_BUSY -+#define SURVEY_INFO_TIME_EXT_BUSY SURVEY_INFO_CHANNEL_TIME_EXT_BUSY -+#define SURVEY_INFO_TIME_RX SURVEY_INFO_CHANNEL_TIME_RX -+#define SURVEY_INFO_TIME_TX SURVEY_INFO_CHANNEL_TIME_TX -+ -+#define SURVEY_TIME(s) s->channel_time -+#define SURVEY_TIME_BUSY(s) s->channel_time_busy -+#else -+#define SURVEY_TIME(s) s->time -+#define SURVEY_TIME_BUSY(s) s->time_busy -+#endif // 4.0 -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0) -+#define cfg80211_ch_switch_started_notify(dev, chandef, count) -+ -+#define WLAN_BSS_COEX_INFORMATION_REQUEST BIT(0) -+#define WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING BIT(2) -+#define WLAN_EXT_CAPA4_TDLS_BUFFER_STA BIT(4) -+#define WLAN_EXT_CAPA4_TDLS_PEER_PSM BIT(5) -+#define WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH BIT(6) -+#define WLAN_EXT_CAPA5_TDLS_CH_SW_PROHIBITED BIT(7) -+#define NL80211_FEATURE_TDLS_CHANNEL_SWITCH 0 -+ -+#define STA_TDLS_INITIATOR(sta) 0 -+ -+#define REGULATORY_IGNORE_STALE_KICKOFF 0 -+#else -+#define STA_TDLS_INITIATOR(sta) sta->tdls_initiator -+#endif // 3.19 -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0) -+#define bl_cfg80211_del_station_compat(wiphy, dev, params) \ -+ bl_cfg80211_del_station(wiphy, dev, const u8 *mac) -+#else -+#define bl_cfg80211_del_station_compat bl_cfg80211_del_station -+#endif // 3.18 -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0) -+#define cfg80211_rx_mgmt(wdev, freq, rssi, buf, len, flags) \ -+ cfg80211_rx_mgmt(wdev, freq, rssi, buf, len, flags, GFP_ATOMIC) -+#endif // 3.18 -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) -+#define bl_cfg80211_tdls_mgmt(wiphy, dev, peer, act, tok, status, peer_capability, initiator, buf, len) \ -+ bl_cfg80211_tdls_mgmt(wiphy, dev, peer, act, tok, status, peer_capability, buf, len) -+ -+#define bl_cfg80211_del_station_compat(wiphy, dev, params) \ -+ bl_cfg80211_del_station(wiphy, dev, const u8 *mac) -+ -+#include -+ -+struct ieee80211_wmm_ac_param { -+ u8 aci_aifsn; /* AIFSN, ACM, ACI */ -+ u8 cw; /* ECWmin, ECWmax (CW = 2^ECW - 1) */ -+ __le16 txop_limit; -+} __packed; -+ -+struct ieee80211_wmm_param_ie { -+ u8 element_id; /* Element ID: 221 (0xdd); */ -+ u8 len; /* Length: 24 */ -+ /* required fields for WMM version 1 */ -+ u8 oui[3]; /* 00:50:f2 */ -+ u8 oui_type; /* 2 */ -+ u8 oui_subtype; /* 1 */ -+ u8 version; /* 1 for WMM version 1.0 */ -+ u8 qos_info; /* AP/STA specific QoS info */ -+ u8 reserved; /* 0 */ -+ /* AC_BE, AC_BK, AC_VI, AC_VO */ -+ struct ieee80211_wmm_ac_param ac[4]; -+} __packed; -+#endif // 3.17 -+ -+ -+/* MAC80211 */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 18, 0) -+#define bl_ops_mgd_prepare_tx(hw, vif, duration) \ -+ bl_ops_mgd_prepare_tx(hw, vif) -+#endif // 4.18 -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0) -+ -+#define RX_ENC_HT(s) s->flag |= RX_FLAG_HT -+#define RX_ENC_HT_GF(s) s->flag |= (RX_FLAG_HT | RX_FLAG_HT_GF) -+#define RX_ENC_VHT(s) s->flag |= RX_FLAG_HT -+#define RX_ENC_HE(s) s->flag |= RX_FLAG_HT -+#define RX_ENC_FLAG_SHORT_GI(s) s->flag |= RX_FLAG_SHORT_GI -+#define RX_ENC_FLAG_SHORT_PRE(s) s->flag |= RX_FLAG_SHORTPRE -+#define RX_ENC_FLAG_LDPC(s) s->flag |= RX_FLAG_LDPC -+#define RX_BW_40MHZ(s) s->flag |= RX_FLAG_40MHZ -+#define RX_BW_80MHZ(s) s->vht_flag |= RX_VHT_FLAG_80MHZ -+#define RX_BW_160MHZ(s) s->vht_flag |= RX_VHT_FLAG_160MHZ -+#define RX_NSS(s) s->vht_nss -+ -+#else -+#define RX_ENC_HT(s) s->encoding = RX_ENC_HT -+#define RX_ENC_HT_GF(s) { s->encoding = RX_ENC_HT; \ -+ s->enc_flags |= RX_ENC_FLAG_HT_GF; } -+#define RX_ENC_VHT(s) s->encoding = RX_ENC_VHT -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) -+#define RX_ENC_HE(s) s->encoding = RX_ENC_VHT -+#else -+#define RX_ENC_HE(s) s->encoding = RX_ENC_HE -+#endif -+#define RX_ENC_FLAG_SHORT_GI(s) s->enc_flags |= RX_ENC_FLAG_SHORT_GI -+#define RX_ENC_FLAG_SHORT_PRE(s) s->enc_flags |= RX_ENC_FLAG_SHORTPRE -+#define RX_ENC_FLAG_LDPC(s) s->enc_flags |= RX_ENC_FLAG_LDPC -+#define RX_BW_40MHZ(s) s->bw = RATE_INFO_BW_40 -+#define RX_BW_80MHZ(s) s->bw = RATE_INFO_BW_80 -+#define RX_BW_160MHZ(s) s->bw = RATE_INFO_BW_160 -+#define RX_NSS(s) s->nss -+ -+#endif // 4.12 -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0) -+#define ieee80211_cqm_rssi_notify(vif, event, level, gfp) \ -+ ieee80211_cqm_rssi_notify(vif, event, gfp) -+#endif // 4.11 -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 7, 0) -+#define RX_FLAG_MIC_STRIPPED 0 -+#endif // 4.7 -+ -+#ifndef CONFIG_VENDOR_bl_AMSDUS_TX -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0)) -+#define bl_ops_ampdu_action(hw, vif, params) \ -+ bl_ops_ampdu_action(hw, vif, enum ieee80211_ampdu_mlme_action action, \ -+ struct ieee80211_sta *sta, u16 tid, u16 *ssn, u8 buf_size) -+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)) -+#define bl_ops_ampdu_action(hw, vif, params) \ -+ bl_ops_ampdu_action(hw, vif, enum ieee80211_ampdu_mlme_action action, \ -+ struct ieee80211_sta *sta, u16 tid, u16 *ssn, u8 buf_size, \ -+ bool amsdu) -+#endif // 4.4 -+#endif /* CONFIG_VENDOR_bl_AMSDUS_TX */ -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) -+#define IEEE80211_HW_SUPPORT_FAST_XMIT 0 -+#define ieee80211_hw_check(hw, feat) (hw->flags & IEEE80211_HW_##feat) -+#define ieee80211_hw_set(hw, feat) {hw->flags |= IEEE80211_HW_##feat;} -+#endif // 4.2 -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0) -+#define bl_ops_sw_scan_start(hw, vif, mac_addr) \ -+ bl_ops_sw_scan_start(hw) -+#define bl_ops_sw_scan_complete(hw, vif) \ -+ bl_ops_sw_scan_complete(hw) -+#endif // 3.19 -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) -+#define bl_ops_hw_scan(hw, vif, hw_req) \ -+ bl_ops_hw_scan(hw, vif, struct cfg80211_scan_request *req) -+#endif // 3.17 -+ -+/* NET */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) -+#define bl_select_queue(dev, skb, sb_dev) \ -+ bl_select_queue(dev, skb) -+#elif LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0) -+#define bl_select_queue(dev, skb, sb_dev) \ -+ bl_select_queue(dev, skb, void *accel_priv) -+#elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) -+#define bl_select_queue(dev, skb, sb_dev) \ -+ bl_select_queue(dev, skb, void *accel_priv, select_queue_fallback_t fallback) -+#elif LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0) -+#define bl_select_queue(dev, skb, sb_dev) \ -+ bl_select_queue(dev, skb, sb_dev, select_queue_fallback_t fallback) -+#elif LINUX_VERSION_CODE <= KERNEL_VERSION(5, 4, 0) -+#define bl_select_queue(dev, skb, sb_dev) \ -+ bl_select_queue(dev, skb, sb_dev) -+#endif //3.13 -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0)) && !(defined CONFIG_VENDOR_bl) -+#define sk_pacing_shift_update(sk, shift) -+#endif // 4.16 -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) -+#define alloc_netdev_mqs(size, name, assign, setup, txqs, rxqs) \ -+ alloc_netdev_mqs(size, name, setup, txqs, rxqs) -+ -+#define NET_NAME_UNKNOWN 0 -+#endif // 3.17 -+ -+/* TRACE */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) -+#define trace_print_symbols_seq ftrace_print_symbols_seq -+#endif // 4.2 -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) -+#define trace_seq_buffer_ptr(p) p->buffer + p->len -+#endif // 3.17 -+ -+/* TIME */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0) -+#define time64_to_tm(t, o, tm) time_to_tm((time_t)t, o, tm) -+#endif // 4.8 -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0) -+#define ktime_get_real_seconds get_seconds -+#endif // 3.19 -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) -+typedef __s64 time64_t; -+#endif // 3.17 -+ -+/* timer */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) -+#define from_timer(var, callback_timer, timer_fieldname) \ -+ container_of(callback_timer, typeof(*var), timer_fieldname) -+ -+#define timer_setup(timer, callback, flags) \ -+ __setup_timer(timer, (void (*)(unsigned long))callback, (unsigned long)timer, flags) -+#endif // 4.14 -+ -+#endif /* _bl_COMPAT_H_ */ -diff -Naur /dev/null_debugfs.c b/drivers/net/wireless/hflps170/bl_debugfs.c ---- /dev/null_debugfs.c 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_debugfs.c 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,2181 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file bl_utils.c -+ * -+ * @brief Miscellaneous utility function definitions -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ **************************************************************************************** -+ */ -+ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "bl_debugfs.h" -+#include "bl_msg_tx.h" -+#include "bl_tx.h" -+#include "bl_utils.h" -+#include "bl_sdio.h" -+#include "bl_platform.h" -+#include "bl_v7.h" -+ -+/* some macros taken from iwlwifi */ -+/* TODO: replace with generic read and fill read buffer in open to avoid double -+ * reads */ -+#define DEBUGFS_ADD_FILE(name, parent, mode) do { \ -+ if (!debugfs_create_file(#name, mode, parent, bl_hw, \ -+ &bl_dbgfs_##name##_ops)) \ -+ goto err; \ -+} while (0) -+ -+#define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \ -+ struct dentry *__tmp; \ -+ __tmp = debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \ -+ parent, ptr); \ -+ if (IS_ERR(__tmp) || !__tmp) \ -+ goto err; \ -+} while (0) -+ -+#define DEBUGFS_ADD_X64(name, parent, ptr) do { \ -+ struct dentry *__tmp; \ -+ __tmp = debugfs_create_x64(#name, S_IWUSR | S_IRUSR, \ -+ parent, ptr); \ -+ if (IS_ERR(__tmp) || !__tmp) \ -+ goto err; \ -+} while (0) -+ -+#define DEBUGFS_ADD_U64(name, parent, ptr, mode) do { \ -+ struct dentry *__tmp; \ -+ __tmp = debugfs_create_u64(#name, mode, \ -+ parent, ptr); \ -+ if (IS_ERR(__tmp) || !__tmp) \ -+ goto err; \ -+} while (0) -+ -+#define DEBUGFS_ADD_X32(name, parent, ptr) do { \ -+ struct dentry *__tmp; \ -+ __tmp = debugfs_create_x32(#name, S_IWUSR | S_IRUSR, \ -+ parent, ptr); \ -+ if (IS_ERR(__tmp) || !__tmp) \ -+ goto err; \ -+} while (0) -+ -+#define DEBUGFS_ADD_U32(name, parent, ptr, mode) do { \ -+ struct dentry *__tmp; \ -+ __tmp = debugfs_create_u32(#name, mode, \ -+ parent, ptr); \ -+ if (IS_ERR(__tmp) || !__tmp) \ -+ goto err; \ -+} while (0) -+ -+/* file operation */ -+#define DEBUGFS_READ_FUNC(name) \ -+ static ssize_t bl_dbgfs_##name##_read(struct file *file, \ -+ char __user *user_buf, \ -+ size_t count, loff_t *ppos); -+ -+#define DEBUGFS_WRITE_FUNC(name) \ -+ static ssize_t bl_dbgfs_##name##_write(struct file *file, \ -+ const char __user *user_buf, \ -+ size_t count, loff_t *ppos); -+ -+ -+#define DEBUGFS_READ_FILE_OPS(name) \ -+ DEBUGFS_READ_FUNC(name); \ -+static const struct file_operations bl_dbgfs_##name##_ops = { \ -+ .read = bl_dbgfs_##name##_read, \ -+ .open = simple_open, \ -+ .llseek = generic_file_llseek, \ -+}; -+ -+#define DEBUGFS_WRITE_FILE_OPS(name) \ -+ DEBUGFS_WRITE_FUNC(name); \ -+static const struct file_operations bl_dbgfs_##name##_ops = { \ -+ .write = bl_dbgfs_##name##_write, \ -+ .open = simple_open, \ -+ .llseek = generic_file_llseek, \ -+}; -+ -+ -+#define DEBUGFS_READ_WRITE_FILE_OPS(name) \ -+ DEBUGFS_READ_FUNC(name); \ -+DEBUGFS_WRITE_FUNC(name); \ -+static const struct file_operations bl_dbgfs_##name##_ops = { \ -+ .write = bl_dbgfs_##name##_write, \ -+ .read = bl_dbgfs_##name##_read, \ -+ .open = simple_open, \ -+ .llseek = generic_file_llseek, \ -+}; -+ -+#define DBG_TIME_HDR "sdiotxtime" -+#define DBG_TIME_HDR_FMT "%10lld" -+#define DBG_TIME_HDR_LEN sizeof(DBG_TIME_HDR) -+static ssize_t bl_dbgfs_dbg_time_read(struct file *file , -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *bl_hw = file->private_data; -+ char *buf; -+ int idx, res; -+ ssize_t read; -+ int i; -+ size_t bufsz = sizeof(bl_hw->dbg_time)+DBG_TIME_HDR_LEN + 3000; -+ -+ bufsz = min_t(size_t, bufsz, count); -+ buf = kmalloc(bufsz, GFP_ATOMIC); -+ if (buf == NULL) -+ return 0; -+ -+ bufsz--; -+ idx = 0; -+ -+ res = scnprintf(&buf[idx], bufsz, DBG_TIME_HDR); -+ idx += res; -+ bufsz -= res; -+ -+ res = scnprintf(&buf[idx], bufsz, "\n"); -+ idx += res; -+ bufsz -= res; -+ -+ for (i = 0; i < 49; i++) { -+ -+ res = scnprintf(&buf[idx], bufsz, DBG_TIME_HDR_FMT, -+ bl_hw->dbg_time[i].sdio_tx -+ ); -+ idx += res; -+ bufsz -= res; -+ res = scnprintf(&buf[idx], bufsz, "\n"); -+ idx += res; -+ bufsz -= res; -+ } -+ -+ res = scnprintf(&buf[idx], bufsz, "\n"); -+ -+ read = simple_read_from_buffer(user_buf, count, ppos, buf, idx); -+ kfree(buf); -+ -+ return read; -+} -+ -+static ssize_t bl_dbgfs_dbg_time_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ return count; -+} -+ -+DEBUGFS_READ_WRITE_FILE_OPS(dbg_time); -+ -+#define DBG_CDT_HDR "sdioport|txqcredit|hwqcredit|credit|ready|txqidx" -+#define DBG_CDT_HDR_FMT "%8d|%9d|%9d|%6d|%5d|%6d" -+#define DBG_CDT_HDR_LEN sizeof(DBG_CDT_HDR) -+ -+static ssize_t bl_dbgfs_dbg_cdt_read(struct file *file , -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *bl_hw = file->private_data; -+ char *buf; -+ int idx, res; -+ ssize_t read; -+ int i; -+ size_t bufsz = sizeof(bl_hw->dbg_credit)+DBG_CDT_HDR_LEN + 3000; -+ -+ bufsz = min_t(size_t, bufsz, count); -+ buf = kmalloc(bufsz, GFP_ATOMIC); -+ if (buf == NULL) -+ return 0; -+ -+ bufsz--; -+ idx = 0; -+ -+ res = scnprintf(&buf[idx], bufsz, DBG_CDT_HDR); -+ idx += res; -+ bufsz -= res; -+ -+ res = scnprintf(&buf[idx], bufsz, "\n"); -+ idx += res; -+ bufsz -= res; -+ -+ for (i = 0; i < 50; i++) { -+ -+ res = scnprintf(&buf[idx], bufsz, DBG_CDT_HDR_FMT, -+ bl_hw->dbg_credit[i].sdio_port, -+ bl_hw->dbg_credit[i].txq_credit, -+ bl_hw->dbg_credit[i].hwq_credit, -+ bl_hw->dbg_credit[i].credit, -+ bl_hw->dbg_credit[i].nb_ready, -+ bl_hw->dbg_credit[i].txq_idx); -+ idx += res; -+ bufsz -= res; -+ res = scnprintf(&buf[idx], bufsz, "\n"); -+ idx += res; -+ bufsz -= res; -+ } -+ -+ res = scnprintf(&buf[idx], bufsz, "\n"); -+ -+ read = simple_read_from_buffer(user_buf, count, ppos, buf, idx); -+ kfree(buf); -+ -+ return read; -+ -+} -+ -+ -+static ssize_t bl_dbgfs_dbg_cdt_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ return count; -+} -+ -+DEBUGFS_READ_WRITE_FILE_OPS(dbg_cdt); -+ -+static ssize_t bl_dbgfs_stats_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *priv = file->private_data; -+ char *buf; -+ int ret; -+ int i, skipped; -+ ssize_t read; -+#ifdef CONFIG_BL_SPLIT_TX_BUF -+ int per; -+#endif -+ -+ int bufsz = (NX_TXQ_CNT) * 20 + (ARRAY_SIZE(priv->stats.amsdus_rx) + 1) * 40 -+ + (ARRAY_SIZE(priv->stats.ampdus_tx) * 30); -+ -+ if (*ppos) -+ return 0; -+ -+ buf = kmalloc(bufsz, GFP_ATOMIC); -+ if (buf == NULL) -+ return 0; -+ -+ ret = scnprintf(buf, bufsz, "TXQs CFM balances "); -+ for (i = 0; i < NX_TXQ_CNT; i++) -+ ret += scnprintf(&buf[ret], bufsz - ret, -+ " [%1d]:%3d", i, -+ priv->stats.cfm_balance[i]); -+ -+ ret += scnprintf(&buf[ret], bufsz - ret, "\n"); -+ -+#ifdef CONFIG_BL_SPLIT_TX_BUF -+ ret += scnprintf(&buf[ret], bufsz - ret, -+ "\nAMSDU[len] done failed received\n"); -+ for (i = skipped = 0; i < NX_TX_PAYLOAD_MAX; i++) { -+ if (priv->stats.amsdus[i].done) { -+ per = DIV_ROUND_UP((priv->stats.amsdus[i].failed) * -+ 100, priv->stats.amsdus[i].done); -+ } else if (priv->stats.amsdus_rx[i]) { -+ per = 0; -+ } else { -+ per = 0; -+ skipped = 1; -+ continue; -+ } -+ if (skipped) { -+ ret += scnprintf(&buf[ret], bufsz - ret, " ...\n"); -+ skipped = 0; -+ } -+ -+ ret += scnprintf(&buf[ret], bufsz - ret, -+ " [%2d] %10d %8d(%3d%%) %10d\n", i ? i + 1 : i, -+ priv->stats.amsdus[i].done, -+ priv->stats.amsdus[i].failed, per, -+ priv->stats.amsdus_rx[i]); -+ } -+ -+ for (; i < ARRAY_SIZE(priv->stats.amsdus_rx); i++) { -+ if (!priv->stats.amsdus_rx[i]) { -+ skipped = 1; -+ continue; -+ } -+ if (skipped) { -+ ret += scnprintf(&buf[ret], bufsz - ret, " ...\n"); -+ skipped = 0; -+ } -+ -+ ret += scnprintf(&buf[ret], bufsz - ret, -+ " [%2d] %10d\n", -+ i + 1, priv->stats.amsdus_rx[i]); -+ } -+#else -+ ret += scnprintf(&buf[ret], bufsz - ret, -+ "\nAMSDU[len] received\n"); -+ for (i = skipped = 0; i < ARRAY_SIZE(priv->stats.amsdus_rx); i++) { -+ if (!priv->stats.amsdus_rx[i]) { -+ skipped = 1; -+ continue; -+ } -+ if (skipped) { -+ ret += scnprintf(&buf[ret], bufsz - ret, -+ " ...\n"); -+ skipped = 0; -+ } -+ -+ ret += scnprintf(&buf[ret], bufsz - ret, -+ " [%2d] %10d\n", -+ i + 1, priv->stats.amsdus_rx[i]); -+ } -+ -+#endif /* CONFIG_BL_SPLIT_TX_BUF */ -+ -+ ret += scnprintf(&buf[ret], bufsz - ret, -+ "\nAMPDU[len] done received\n"); -+ for (i = skipped = 0; i < ARRAY_SIZE(priv->stats.ampdus_tx); i++) { -+ if (!priv->stats.ampdus_tx[i] && !priv->stats.ampdus_rx[i]) { -+ skipped = 1; -+ continue; -+ } -+ if (skipped) { -+ ret += scnprintf(&buf[ret], bufsz - ret, -+ " ...\n"); -+ skipped = 0; -+ } -+ -+ ret += scnprintf(&buf[ret], bufsz - ret, -+ " [%2d] %9d %9d\n", i ? i + 1 : i, -+ priv->stats.ampdus_tx[i], priv->stats.ampdus_rx[i]); -+ } -+ -+ ret += scnprintf(&buf[ret], bufsz - ret, -+ "#mpdu missed %9d\n", -+ priv->stats.ampdus_rx_miss); -+ read = simple_read_from_buffer(user_buf, count, ppos, buf, ret); -+ -+ kfree(buf); -+ -+ return read; -+} -+ -+static ssize_t bl_dbgfs_stats_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *priv = file->private_data; -+ -+ /* Prevent from interrupt preemption as these statistics are updated under -+ * interrupt */ -+ spin_lock_bh(&priv->tx_lock); -+ -+ memset(&priv->stats, 0, sizeof(priv->stats)); -+ -+ spin_unlock_bh(&priv->tx_lock); -+ -+ return count; -+} -+ -+DEBUGFS_READ_WRITE_FILE_OPS(stats); -+ -+#define TXQ_STA_PREF "tid|" -+#define TXQ_STA_PREF_FMT "%3d|" -+ -+#ifdef CONFIG_BL_FULLMAC -+#define TXQ_VIF_PREF "type|" -+#define TXQ_VIF_PREF_FMT "%4s|" -+#else -+#define TXQ_VIF_PREF "AC|" -+#define TXQ_VIF_PREF_FMT "%2s|" -+#endif /* CONFIG_BL_FULLMAC */ -+ -+#define TXQ_HDR "idx| status|credit|ready|retry" -+#define TXQ_HDR_FMT "%3d|%s%s%s%s%s%s%s|%6d|%5d|%5d" -+ -+#ifdef CONFIG_BL_AMSDUS_TX -+#ifdef CONFIG_BL_FULLMAC -+#define TXQ_HDR_SUFF "|amsdu" -+#define TXQ_HDR_SUFF_FMT "|%5d" -+#else -+#define TXQ_HDR_SUFF "|amsdu-ht|amdsu-vht" -+#define TXQ_HDR_SUFF_FMT "|%8d|%9d" -+#endif /* CONFIG_BL_FULLMAC */ -+#else -+#define TXQ_HDR_SUFF "" -+#define TXQ_HDR_SUF_FMT "" -+#endif /* CONFIG_BL_AMSDUS_TX */ -+ -+#define TXQ_HDR_MAX_LEN (sizeof(TXQ_STA_PREF) + sizeof(TXQ_HDR) + sizeof(TXQ_HDR_SUFF) + 1) -+ -+#ifdef CONFIG_BL_FULLMAC -+#define PS_HDR "Legacy PS: ready=%d, sp=%d / UAPSD: ready=%d, sp=%d" -+#define PS_HDR_LEGACY "Legacy PS: ready=%d, sp=%d" -+#define PS_HDR_UAPSD "UAPSD: ready=%d, sp=%d" -+#define PS_HDR_MAX_LEN sizeof("Legacy PS: ready=xxx, sp=xxx / UAPSD: ready=xxx, sp=xxx\n") -+#else -+#define PS_HDR "" -+#define PS_HDR_MAX_LEN 0 -+#endif /* CONFIG_BL_FULLMAC */ -+ -+#define STA_HDR "** STA %d (%pM)\n" -+#define STA_HDR_MAX_LEN sizeof("- STA xx (xx:xx:xx:xx:xx:xx)\n") + PS_HDR_MAX_LEN -+ -+#ifdef CONFIG_BL_FULLMAC -+#define VIF_HDR "* VIF [%d] %s\n" -+#define VIF_HDR_MAX_LEN sizeof(VIF_HDR) + IFNAMSIZ -+#else -+#define VIF_HDR "* VIF [%d]\n" -+#define VIF_HDR_MAX_LEN sizeof(VIF_HDR) -+#endif -+ -+ -+#ifdef CONFIG_BL_AMSDUS_TX -+ -+#ifdef CONFIG_BL_FULLMAC -+#define VIF_SEP "---------------------------------------\n" -+#else -+#define VIF_SEP "----------------------------------------------------\n" -+#endif /* CONFIG_BL_FULLMAC */ -+ -+#else /* ! CONFIG_BL_AMSDUS_TX */ -+#define VIF_SEP "---------------------------------\n" -+#endif /* CONFIG_BL_AMSDUS_TX*/ -+ -+#define VIF_SEP_LEN sizeof(VIF_SEP) -+ -+#define CAPTION "status: L=in hwq list, F=stop full, P=stop sta PS, V=stop vif PS, C=stop channel, S=stop CSA, M=stop MU" -+#define CAPTION_LEN sizeof(CAPTION) -+ -+#define STA_TXQ 0 -+#define VIF_TXQ 1 -+ -+static int bl_dbgfs_txq(char *buf, size_t size, struct bl_txq *txq, int type, int tid, char *name) -+{ -+ int res, idx = 0; -+ -+ if (type == STA_TXQ) { -+ res = scnprintf(&buf[idx], size, TXQ_STA_PREF_FMT, tid); -+ idx += res; -+ size -= res; -+ } else { -+ res = scnprintf(&buf[idx], size, TXQ_VIF_PREF_FMT, name); -+ idx += res; -+ size -= res; -+ } -+ -+ res = scnprintf(&buf[idx], size, TXQ_HDR_FMT, txq->idx, -+ (txq->status & BL_TXQ_IN_HWQ_LIST) ? "L" : " ", -+ (txq->status & BL_TXQ_STOP_FULL) ? "F" : " ", -+ (txq->status & BL_TXQ_STOP_STA_PS) ? "P" : " ", -+ (txq->status & BL_TXQ_STOP_VIF_PS) ? "V" : " ", -+ (txq->status & BL_TXQ_STOP_CHAN) ? "C" : " ", -+ (txq->status & BL_TXQ_STOP_CSA) ? "S" : " ", -+ (txq->status & BL_TXQ_STOP_MU_POS) ? "M" : " ", -+ txq->credits, skb_queue_len(&txq->sk_list), -+ txq->nb_retry); -+ idx += res; -+ size -= res; -+ -+#ifdef CONFIG_BL_AMSDUS_TX -+ if (type == STA_TXQ) { -+ res = scnprintf(&buf[idx], size, TXQ_HDR_SUFF_FMT, -+#ifdef CONFIG_BL_FULLMAC -+ txq->amsdu_len -+#else -+ txq->amsdu_ht_len_cap, txq->amsdu_vht_len_cap -+#endif /* CONFIG_BL_FULLMAC */ -+ ); -+ idx += res; -+ size -= res; -+ } -+#endif -+ -+ res = scnprintf(&buf[idx], size, "\n"); -+ idx += res; -+ size -= res; -+ -+ return idx; -+} -+ -+static int bl_dbgfs_txq_sta(char *buf, size_t size, struct bl_sta *bl_sta, -+ struct bl_hw *bl_hw) -+{ -+ int tid, res, idx = 0; -+ struct bl_txq *txq; -+ -+ res = scnprintf(&buf[idx], size, "\n" STA_HDR, -+ bl_sta->sta_idx, -+ bl_sta->mac_addr -+ ); -+ idx += res; -+ size -= res; -+ -+#ifdef CONFIG_BL_FULLMAC -+ if (bl_sta->ps.active) { -+ if (bl_sta->uapsd_tids && -+ (bl_sta->uapsd_tids == ((1 << NX_NB_TXQ_PER_STA) - 1))) -+ res = scnprintf(&buf[idx], size, PS_HDR_UAPSD "\n", -+ bl_sta->ps.pkt_ready[UAPSD_ID], -+ bl_sta->ps.sp_cnt[UAPSD_ID]); -+ else if (bl_sta->uapsd_tids) -+ res = scnprintf(&buf[idx], size, PS_HDR "\n", -+ bl_sta->ps.pkt_ready[LEGACY_PS_ID], -+ bl_sta->ps.sp_cnt[LEGACY_PS_ID], -+ bl_sta->ps.pkt_ready[UAPSD_ID], -+ bl_sta->ps.sp_cnt[UAPSD_ID]); -+ else -+ res = scnprintf(&buf[idx], size, PS_HDR_LEGACY "\n", -+ bl_sta->ps.pkt_ready[LEGACY_PS_ID], -+ bl_sta->ps.sp_cnt[LEGACY_PS_ID]); -+ idx += res; -+ size -= res; -+ } else { -+ res = scnprintf(&buf[idx], size, "\n"); -+ idx += res; -+ size -= res; -+ } -+#endif /* CONFIG_BL_FULLMAC */ -+ -+ -+ res = scnprintf(&buf[idx], size, TXQ_STA_PREF TXQ_HDR TXQ_HDR_SUFF "\n"); -+ idx += res; -+ size -= res; -+ -+#ifdef CONFIG_BL_FULLMAC -+ txq = bl_txq_sta_get(bl_sta, 0, NULL, bl_hw); -+#else -+ txq = bl_txq_sta_get(bl_sta, 0, NULL); -+#endif /* CONFIG_BL_FULLMAC */ -+ -+ for (tid = 0; tid < NX_NB_TXQ_PER_STA; tid++, txq++) { -+ res = bl_dbgfs_txq(&buf[idx], size, txq, STA_TXQ, tid, NULL); -+ idx += res; -+ size -= res; -+ } -+ -+ return idx; -+} -+ -+static int bl_dbgfs_txq_vif(char *buf, size_t size, struct bl_vif *bl_vif, -+ struct bl_hw *bl_hw) -+{ -+ int res, idx = 0; -+ struct bl_txq *txq; -+ struct bl_sta *bl_sta; -+ -+#ifdef CONFIG_BL_FULLMAC -+ res = scnprintf(&buf[idx], size, VIF_HDR, bl_vif->vif_index, bl_vif->ndev->name); -+ idx += res; -+ size -= res; -+ if (!bl_vif->up || bl_vif->ndev == NULL) -+ return idx; -+ -+#else -+ int i; -+ char ac_name[2] = {'0', '\0'}; -+ -+ res = scnprintf(&buf[idx], size, VIF_HDR, bl_vif->vif_index); -+ idx += res; -+ size -= res; -+#endif /* CONFIG_BL_FULLMAC */ -+ -+ #ifdef CONFIG_BL_FULLMAC -+ if (BL_VIF_TYPE(bl_vif) == NL80211_IFTYPE_AP || -+ BL_VIF_TYPE(bl_vif) == NL80211_IFTYPE_P2P_GO) { -+ res = scnprintf(&buf[idx], size, TXQ_VIF_PREF TXQ_HDR "\n"); -+ idx += res; -+ size -= res; -+ txq = bl_txq_vif_get(bl_vif, NX_UNK_TXQ_TYPE, NULL); -+ res = bl_dbgfs_txq(&buf[idx], size, txq, VIF_TXQ, 0, "UNK"); -+ idx += res; -+ size -= res; -+ txq = bl_txq_vif_get(bl_vif, NX_BCMC_TXQ_TYPE, NULL); -+ res = bl_dbgfs_txq(&buf[idx], size, txq, VIF_TXQ, 0, "BCMC"); -+ idx += res; -+ size -= res; -+ bl_sta = &bl_hw->sta_table[bl_vif->ap.bcmc_index]; -+ if (bl_sta->ps.active) { -+ res = scnprintf(&buf[idx], size, PS_HDR_LEGACY "\n", -+ bl_sta->ps.sp_cnt[LEGACY_PS_ID], -+ bl_sta->ps.sp_cnt[LEGACY_PS_ID]); -+ idx += res; -+ size -= res; -+ } else { -+ res = scnprintf(&buf[idx], size, "\n"); -+ idx += res; -+ size -= res; -+ } -+ -+ list_for_each_entry(bl_sta, &bl_vif->ap.sta_list, list) { -+ res = bl_dbgfs_txq_sta(&buf[idx], size, bl_sta, bl_hw); -+ idx += res; -+ size -= res; -+ } -+ } else if (BL_VIF_TYPE(bl_vif) == NL80211_IFTYPE_STATION || -+ BL_VIF_TYPE(bl_vif) == NL80211_IFTYPE_P2P_CLIENT) { -+ if (bl_vif->sta.ap) { -+ res = bl_dbgfs_txq_sta(&buf[idx], size, bl_vif->sta.ap, bl_hw); -+ idx += res; -+ size -= res; -+ } -+ } -+ -+ #else -+ res = scnprintf(&buf[idx], size, TXQ_VIF_PREF TXQ_HDR "\n"); -+ idx += res; -+ size -= res; -+ txq = bl_txq_vif_get(bl_vif, 0, NULL); -+ for (i = 0; i < NX_NB_TXQ_PER_VIF; i++, txq++) { -+ ac_name[0]++; -+ res = bl_dbgfs_txq(&buf[idx], size, txq, VIF_TXQ, 0, ac_name); -+ idx += res; -+ size -= res; -+ } -+ -+ list_for_each_entry(bl_sta, &bl_vif->stations, list) { -+ res = bl_dbgfs_txq_sta(&buf[idx], size, bl_sta, bl_hw); -+ idx += res; -+ size -= res; -+ } -+ #endif /* CONFIG_BL_FULLMAC */ -+ return idx; -+} -+ -+static ssize_t bl_dbgfs_txq_read(struct file *file , -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *bl_hw = file->private_data; -+ struct bl_vif *vif; -+ char *buf; -+ int idx, res; -+ ssize_t read; -+ size_t bufsz = ((NX_VIRT_DEV_MAX * (VIF_HDR_MAX_LEN + 2 * VIF_SEP_LEN)) + -+ (NX_REMOTE_STA_MAX * STA_HDR_MAX_LEN) + -+ ((NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX + NX_NB_TXQ) * -+ TXQ_HDR_MAX_LEN) + CAPTION_LEN); -+ -+ /* everything is read in one go */ -+ if (*ppos) -+ return 0; -+ -+ bufsz = min_t(size_t, bufsz, count); -+ buf = kmalloc(bufsz, GFP_ATOMIC); -+ if (buf == NULL) -+ return 0; -+ -+ bufsz--; -+ idx = 0; -+ -+ res = scnprintf(&buf[idx], bufsz, CAPTION); -+ idx += res; -+ bufsz -= res; -+ -+ //spin_lock_bh(&bl_hw->tx_lock); -+ list_for_each_entry(vif, &bl_hw->vifs, list) { -+ res = scnprintf(&buf[idx], bufsz, "\n"VIF_SEP); -+ idx += res; -+ bufsz -= res; -+ res = bl_dbgfs_txq_vif(&buf[idx], bufsz, vif, bl_hw); -+ idx += res; -+ bufsz -= res; -+ res = scnprintf(&buf[idx], bufsz, VIF_SEP); -+ idx += res; -+ bufsz -= res; -+ } -+ //spin_unlock_bh(&bl_hw->tx_lock); -+ -+ read = simple_read_from_buffer(user_buf, count, ppos, buf, idx); -+ kfree(buf); -+ -+ return read; -+} -+DEBUGFS_READ_FILE_OPS(txq); -+ -+static ssize_t bl_dbgfs_rhd_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *priv = file->private_data; -+ ssize_t read; -+ -+ mutex_lock(&priv->dbginfo.mutex); -+ if (!priv->debugfs.trace_prst) { -+ mutex_unlock(&priv->dbginfo.mutex); -+ return 0; -+ } -+ -+ read = simple_read_from_buffer(user_buf, count, ppos, -+ priv->dbginfo.buf->rhd_mem, -+ priv->dbginfo.buf->dbg_info.rhd_len); -+ -+ mutex_unlock(&priv->dbginfo.mutex); -+ return read; -+} -+ -+DEBUGFS_READ_FILE_OPS(rhd); -+ -+static ssize_t bl_dbgfs_rbd_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *priv = file->private_data; -+ ssize_t read; -+ -+ mutex_lock(&priv->dbginfo.mutex); -+ if (!priv->debugfs.trace_prst) { -+ mutex_unlock(&priv->dbginfo.mutex); -+ return 0; -+ } -+ -+ read = simple_read_from_buffer(user_buf, count, ppos, -+ priv->dbginfo.buf->rbd_mem, -+ priv->dbginfo.buf->dbg_info.rbd_len); -+ -+ mutex_unlock(&priv->dbginfo.mutex); -+ return read; -+} -+ -+DEBUGFS_READ_FILE_OPS(rbd); -+ -+static ssize_t bl_dbgfs_thdx_read(struct file *file, char __user *user_buf, -+ size_t count, loff_t *ppos, int idx) -+{ -+ struct bl_hw *priv = file->private_data; -+ ssize_t read; -+ -+ mutex_lock(&priv->dbginfo.mutex); -+ if (!priv->debugfs.trace_prst) { -+ mutex_unlock(&priv->dbginfo.mutex); -+ return 0; -+ } -+ -+ read = simple_read_from_buffer(user_buf, count, ppos, -+ &priv->dbginfo.buf->thd_mem[idx], -+ priv->dbginfo.buf->dbg_info.thd_len[idx]); -+ -+ mutex_unlock(&priv->dbginfo.mutex); -+ return read; -+} -+ -+static ssize_t bl_dbgfs_thd0_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ return bl_dbgfs_thdx_read(file, user_buf, count, ppos, 0); -+} -+DEBUGFS_READ_FILE_OPS(thd0); -+ -+static ssize_t bl_dbgfs_thd1_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ return bl_dbgfs_thdx_read(file, user_buf, count, ppos, 1); -+} -+DEBUGFS_READ_FILE_OPS(thd1); -+ -+static ssize_t bl_dbgfs_thd2_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ return bl_dbgfs_thdx_read(file, user_buf, count, ppos, 2); -+} -+DEBUGFS_READ_FILE_OPS(thd2); -+ -+static ssize_t bl_dbgfs_thd3_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ return bl_dbgfs_thdx_read(file, user_buf, count, ppos, 3); -+} -+DEBUGFS_READ_FILE_OPS(thd3); -+ -+#if (NX_TXQ_CNT == 5) -+static ssize_t bl_dbgfs_thd4_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ return bl_dbgfs_thdx_read(file, user_buf, count, ppos, 4); -+} -+DEBUGFS_READ_FILE_OPS(thd4); -+#endif -+ -+static ssize_t bl_dbgfs_mactrace_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *priv = file->private_data; -+ ssize_t read; -+ -+ mutex_lock(&priv->dbginfo.mutex); -+ read = simple_read_from_buffer(user_buf, count, ppos, -+ priv->dbginfo.buf->la_mem, -+ priv->dbginfo.buf->dbg_info.la_conf.trace_len); -+ -+ mutex_unlock(&priv->dbginfo.mutex); -+ return read; -+} -+DEBUGFS_READ_FILE_OPS(mactrace); -+ -+static ssize_t bl_dbgfs_mactctrig_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *priv = file->private_data; -+ ssize_t read; -+ -+ mutex_lock(&priv->dbginfo.mutex); -+ -+ priv->debugfs.trace_prst = false; -+ -+ if (!priv->debugfs.trace_prst) { -+ char msg[64]; -+ -+ printk("sent trace trigger msg\n"); -+ -+ scnprintf(msg, sizeof(msg), "Force trigger\n"); -+ bl_send_dbg_trigger_req(priv, msg); -+ -+ mutex_unlock(&priv->dbginfo.mutex); -+ return 0; -+ } -+ -+ mutex_unlock(&priv->dbginfo.mutex); -+ return read; -+} -+DEBUGFS_READ_FILE_OPS(mactctrig); -+ -+ -+static ssize_t bl_dbgfs_macdiags_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *priv = file->private_data; -+ ssize_t read; -+ -+ mutex_lock(&priv->dbginfo.mutex); -+ if (!priv->debugfs.trace_prst) { -+ mutex_unlock(&priv->dbginfo.mutex); -+ return 0; -+ } -+ -+ read = simple_read_from_buffer(user_buf, count, ppos, -+ priv->dbginfo.buf->dbg_info.diags_mac, -+ DBG_DIAGS_MAC_MAX * 2); -+ -+ mutex_unlock(&priv->dbginfo.mutex); -+ return read; -+} -+ -+DEBUGFS_READ_FILE_OPS(macdiags); -+ -+static ssize_t bl_dbgfs_phydiags_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *priv = file->private_data; -+ ssize_t read; -+ -+ mutex_lock(&priv->dbginfo.mutex); -+ if (!priv->debugfs.trace_prst) { -+ mutex_unlock(&priv->dbginfo.mutex); -+ return 0; -+ } -+ -+ read = simple_read_from_buffer(user_buf, count, ppos, -+ priv->dbginfo.buf->dbg_info.diags_phy, -+ DBG_DIAGS_PHY_MAX * 2); -+ -+ mutex_unlock(&priv->dbginfo.mutex); -+ return read; -+} -+ -+DEBUGFS_READ_FILE_OPS(phydiags); -+ -+static ssize_t bl_dbgfs_hwdiags_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *priv = file->private_data; -+ char buf[16]; -+ int ret; -+ -+ mutex_lock(&priv->dbginfo.mutex); -+ if (!priv->debugfs.trace_prst) { -+ mutex_unlock(&priv->dbginfo.mutex); -+ return 0; -+ } -+ -+ ret = scnprintf(buf, min_t(size_t, sizeof(buf) - 1, count), -+ "%08X\n", priv->dbginfo.buf->dbg_info.hw_diag); -+ -+ mutex_unlock(&priv->dbginfo.mutex); -+ return simple_read_from_buffer(user_buf, count, ppos, buf, ret); -+} -+ -+DEBUGFS_READ_FILE_OPS(hwdiags); -+ -+static ssize_t bl_dbgfs_plfdiags_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *priv = file->private_data; -+ char buf[16]; -+ int ret; -+ -+ mutex_lock(&priv->dbginfo.mutex); -+ if (!priv->debugfs.trace_prst) { -+ mutex_unlock(&priv->dbginfo.mutex); -+ return 0; -+ } -+ -+ ret = scnprintf(buf, min_t(size_t, sizeof(buf) - 1, count), -+ "%08X\n", priv->dbginfo.buf->dbg_info.la_conf.diag_conf); -+ -+ mutex_unlock(&priv->dbginfo.mutex); -+ return simple_read_from_buffer(user_buf, count, ppos, buf, ret); -+} -+ -+DEBUGFS_READ_FILE_OPS(plfdiags); -+ -+static ssize_t bl_dbgfs_swdiags_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *priv = file->private_data; -+ ssize_t read; -+ -+ mutex_lock(&priv->dbginfo.mutex); -+ if (!priv->debugfs.trace_prst) { -+ mutex_unlock(&priv->dbginfo.mutex); -+ return 0; -+ } -+ -+ read = simple_read_from_buffer(user_buf, count, ppos, -+ &priv->dbginfo.buf->dbg_info.sw_diag, -+ priv->dbginfo.buf->dbg_info.sw_diag_len); -+ -+ mutex_unlock(&priv->dbginfo.mutex); -+ return read; -+} -+ -+DEBUGFS_READ_FILE_OPS(swdiags); -+ -+static ssize_t bl_dbgfs_error_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *priv = file->private_data; -+ ssize_t read; -+ -+ mutex_lock(&priv->dbginfo.mutex); -+ if (!priv->debugfs.trace_prst) { -+ mutex_unlock(&priv->dbginfo.mutex); -+ return 0; -+ } -+ -+ read = simple_read_from_buffer(user_buf, count, ppos, -+ priv->dbginfo.buf->dbg_info.error, -+ strlen((char *)priv->dbginfo.buf->dbg_info.error)); -+ -+ mutex_unlock(&priv->dbginfo.mutex); -+ return read; -+} -+ -+DEBUGFS_READ_FILE_OPS(error); -+ -+static ssize_t bl_dbgfs_rxdesc_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *priv = file->private_data; -+ char buf[32]; -+ int ret; -+ ssize_t read; -+ -+ mutex_lock(&priv->dbginfo.mutex); -+ if (!priv->debugfs.trace_prst) { -+ mutex_unlock(&priv->dbginfo.mutex); -+ return 0; -+ } -+ -+ ret = scnprintf(buf, min_t(size_t, sizeof(buf) - 1, count), -+ "%08X\n%08X\n", priv->dbginfo.buf->dbg_info.rhd, -+ priv->dbginfo.buf->dbg_info.rbd); -+ read = simple_read_from_buffer(user_buf, count, ppos, buf, ret); -+ -+ mutex_unlock(&priv->dbginfo.mutex); -+ return read; -+} -+ -+DEBUGFS_READ_FILE_OPS(rxdesc); -+ -+static ssize_t bl_dbgfs_txdesc_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *priv = file->private_data; -+ char buf[64]; -+ int len = 0; -+ int i; -+ -+ mutex_lock(&priv->dbginfo.mutex); -+ if (!priv->debugfs.trace_prst) { -+ mutex_unlock(&priv->dbginfo.mutex); -+ return 0; -+ } -+ -+ for (i = 0; i < NX_TXQ_CNT; i++) { -+ len += scnprintf(&buf[len], min_t(size_t, sizeof(buf) - len - 1, count), -+ "%08X\n", priv->dbginfo.buf->dbg_info.thd[i]); -+ } -+ -+ mutex_unlock(&priv->dbginfo.mutex); -+ return simple_read_from_buffer(user_buf, count, ppos, buf, len); -+} -+ -+DEBUGFS_READ_FILE_OPS(txdesc); -+ -+static ssize_t bl_dbgfs_macrxptr_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *priv = file->private_data; -+ ssize_t read; -+ -+ mutex_lock(&priv->dbginfo.mutex); -+ if (!priv->debugfs.trace_prst) { -+ mutex_unlock(&priv->dbginfo.mutex); -+ return 0; -+ } -+ -+ read = simple_read_from_buffer(user_buf, count, ppos, -+ &priv->dbginfo.buf->dbg_info.rhd_hw_ptr, -+ 2 * sizeof(priv->dbginfo.buf->dbg_info.rhd_hw_ptr)); -+ -+ mutex_unlock(&priv->dbginfo.mutex); -+ return read; -+} -+ -+DEBUGFS_READ_FILE_OPS(macrxptr); -+ -+static ssize_t bl_dbgfs_lamacconf_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *priv = file->private_data; -+ ssize_t read; -+ -+ mutex_lock(&priv->dbginfo.mutex); -+ if (!priv->debugfs.trace_prst) { -+ mutex_unlock(&priv->dbginfo.mutex); -+ return 0; -+ } -+ -+ read = simple_read_from_buffer(user_buf, count, ppos, -+ priv->dbginfo.buf->dbg_info.la_conf.conf, -+ LA_CONF_LEN * 4); -+ -+ mutex_unlock(&priv->dbginfo.mutex); -+ return read; -+} -+DEBUGFS_READ_FILE_OPS(lamacconf); -+ -+static ssize_t bl_dbgfs_chaninfo_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *priv = file->private_data; -+ char buf[4 * 32]; -+ int ret; -+ -+ mutex_lock(&priv->dbginfo.mutex); -+ if (!priv->debugfs.trace_prst) { -+ mutex_unlock(&priv->dbginfo.mutex); -+ return 0; -+ } -+ -+ ret = scnprintf(buf, min_t(size_t, sizeof(buf) - 1, count), -+ "type: %d\n" -+ "prim20_freq: %d MHz\n" -+ "center1_freq: %d MHz\n" -+ "center2_freq: %d MHz\n", -+ (priv->dbginfo.buf->dbg_info.chan_info.info1 >> 8) & 0xFF, -+ (priv->dbginfo.buf->dbg_info.chan_info.info1 >> 16) & 0xFFFF, -+ (priv->dbginfo.buf->dbg_info.chan_info.info2 >> 0) & 0xFFFF, -+ (priv->dbginfo.buf->dbg_info.chan_info.info2 >> 16) & 0xFFFF); -+ -+ mutex_unlock(&priv->dbginfo.mutex); -+ return simple_read_from_buffer(user_buf, count, ppos, buf, ret); -+} -+ -+DEBUGFS_READ_FILE_OPS(chaninfo); -+ -+static ssize_t bl_dbgfs_acsinfo_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *priv = file->private_data; -+ struct wiphy *wiphy = priv->wiphy; -+ int survey_cnt = 0; -+ int len = 0; -+ int band, chan_cnt; -+ char *buf = NULL; -+ int buf_len = (SCAN_CHANNEL_MAX + 1) * 43; -+ size_t ret = 0; -+ -+ buf = kzalloc(buf_len, GFP_KERNEL); -+ if(!buf) -+ return ret; -+ -+ mutex_lock(&priv->dbginfo.mutex); -+ -+ len += scnprintf(buf, min_t(size_t, buf_len - 1, count), -+ "FREQ TIME(ms) BUSY(ms) NOISE(dBm)\n"); -+ -+ for (band = NL80211_BAND_2GHZ; band <= NL80211_BAND_5GHZ; band++) { -+ for (chan_cnt = 0; chan_cnt < wiphy->bands[band]->n_channels; chan_cnt++) { -+ struct bl_survey_info *p_survey_info = &priv->survey[survey_cnt]; -+ struct ieee80211_channel *p_chan = &wiphy->bands[band]->channels[chan_cnt]; -+ -+ if (p_survey_info->filled) { -+ len += scnprintf(buf + len, min_t(size_t, buf_len - len - 1, count), -+ "%d %03d %03d %d\n", -+ p_chan->center_freq, -+ p_survey_info->chan_time_ms, -+ p_survey_info->chan_time_busy_ms, -+ p_survey_info->noise_dbm); -+ } else { -+ len += scnprintf(buf + len, min_t(size_t, buf_len -len -1, count), -+ "%d NOT AVAILABLE\n", -+ p_chan->center_freq); -+ } -+ -+ survey_cnt++; -+ } -+ } -+ -+ mutex_unlock(&priv->dbginfo.mutex); -+ -+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); -+ -+ kfree(buf); -+ buf = NULL; -+ return ret; -+} -+ -+DEBUGFS_READ_FILE_OPS(acsinfo); -+ -+static ssize_t bl_dbgfs_fw_dbg_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ char help[]="usage: [MOD:]* " -+ "[DBG:]\n"; -+ -+ return simple_read_from_buffer(user_buf, count, ppos, help, sizeof(help)); -+} -+ -+ -+static ssize_t bl_dbgfs_fw_dbg_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ return 0; -+} -+ -+DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg); -+ -+static ssize_t bl_dbgfs_sys_stats_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ return 0; -+} -+ -+DEBUGFS_READ_FILE_OPS(sys_stats); -+ -+static ssize_t bl_dbgfs_um_helper_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *priv = file->private_data; -+ char buf[sizeof(priv->debugfs.helper_cmd)]; -+ int ret; -+ -+ ret = scnprintf(buf, min_t(size_t, sizeof(buf) - 1, count), -+ "%s", priv->debugfs.helper_cmd); -+ -+ return simple_read_from_buffer(user_buf, count, ppos, buf, ret); -+} -+ -+static ssize_t bl_dbgfs_um_helper_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *priv = file->private_data; -+ int eobuf = min_t(size_t, sizeof(priv->debugfs.helper_cmd) - 1, count); -+ -+ priv->debugfs.helper_cmd[eobuf] = '\0'; -+ if (copy_from_user(priv->debugfs.helper_cmd, user_buf, eobuf)) -+ return -EFAULT; -+ -+ return count; -+} -+ -+DEBUGFS_READ_WRITE_FILE_OPS(um_helper); -+ -+ -+static ssize_t bl_dbgfs_sdio_test_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *priv = file->private_data; -+ u8 *buf = NULL; -+ int pkt_len; -+ int ret = 0; -+ u32 port; -+ ssize_t read; -+ int i = 0; -+ -+ bl_get_rd_port(priv, &port); -+ bl_get_rd_len(priv, 0x8, 0x9, &pkt_len); -+ buf = kzalloc(pkt_len, GFP_KERNEL); -+ bl_read_data_sync(priv, buf, pkt_len, priv->plat->io_port + port); -+ -+ for(i=0; iprivate_data; -+ char buf[32]; -+ u8 *send_buf = NULL; -+ int i; -+ u32 port; -+ int val; -+ int pkt_len; -+ int act_len; -+ size_t len = min_t(size_t, count, sizeof(buf) - 1); -+ -+ if (copy_from_user(buf, user_buf, len)) -+ return -EFAULT; -+ -+ buf[len] = '\0'; -+ -+ if (sscanf(buf, "0x%x-%d", &val, &pkt_len) > 0) -+ { -+ printk("val=0x%x, pkt_len=0x%x\n", val, pkt_len); -+ } -+ -+ act_len = pkt_len; -+ -+ pkt_len = ((pkt_len + BL_SDIO_BLOCK_SIZE -1)/BL_SDIO_BLOCK_SIZE) * BL_SDIO_BLOCK_SIZE; -+ -+ printk("after adjust: alloc %d for pkt_buf\n", pkt_len); -+ -+ send_buf = kzalloc(pkt_len, GFP_KERNEL); -+ -+ for(i = 0; i < pkt_len; i++) -+ { -+ send_buf[i] = val; -+ } -+ -+ bl_get_wr_port(priv, &port); -+ -+ bl_write_data_sync(priv, send_buf, act_len, priv->plat->io_port + port); -+ -+ kfree(send_buf); -+ -+ send_buf = NULL; -+ -+ return count; -+} -+ -+DEBUGFS_READ_WRITE_FILE_OPS(sdio_test); -+ -+static ssize_t bl_dbgfs_rw_reg_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *bl_hw = file->private_data; -+ struct bl_device *bl_device; -+ struct bl_plat *bl_plat; -+ u8 sdio_ireg; -+ -+ bl_plat = bl_hw->plat; -+ bl_device = (struct bl_device *)bl_plat->priv; -+ -+ if(bl_read_data_sync(bl_hw, bl_plat->mp_regs, bl_device->reg->max_mp_regs, REG_PORT | BL_SDIO_BYTE_MODE_MASK)) { -+ printk("read mp_regs failed\n"); -+ return -1; -+ } -+ -+ sdio_ireg = bl_plat->mp_regs[bl_device->reg->host_int_status_reg]; -+ -+ printk("sdio_ireg=0x%x\n", sdio_ireg); -+ return 0; -+} -+ -+static ssize_t bl_dbgfs_rw_reg_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *priv = file->private_data; -+ char buf[32]; -+ int reg; -+ int wr_val; -+ u8 data; -+ int ret = -1; -+ -+ size_t len = min_t(size_t, count, sizeof(buf)-1); -+ -+ if (copy_from_user(buf, user_buf, len)) -+ return -EFAULT; -+ -+ buf[len] = '\0'; -+ -+ if (sscanf(buf, "0x%x-%d", ®, &wr_val) > 0) -+ { -+ printk("reg=0x%x, wr_val=0x%x\n", reg, wr_val); -+ } -+ -+ ret = bl_read_reg(priv, reg, &data); -+ -+ if(ret) -+ printk("11--read reg 0x%x failed\n", reg); -+ else -+ printk("11--read reg 0x%x success, val=0x%x\n", reg, data); -+ -+ -+ ret = bl_write_reg(priv, reg, wr_val); -+ -+ if(ret) -+ printk("22--write 0x%x to reg 0x%x failed!\n", wr_val, reg); -+ else -+ printk("22--write 0x%x to reg 0x%x success!\n", wr_val, reg); -+ -+ ret = bl_read_reg(priv, reg, &data); -+ -+ if(ret) -+ printk("33--read reg 0x%x failed\n", reg); -+ else -+ printk("33--read reg 0x%x success, val=0x%x\n", reg, data); -+ -+ return count; -+ -+} -+ -+ -+DEBUGFS_READ_WRITE_FILE_OPS(rw_reg); -+ -+static ssize_t bl_dbgfs_rdbitmap_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *priv = file->private_data; -+ u8 rd_bitmap_l; -+ u8 rd_bitmap_u; -+ u32 bitmap; -+ -+ bl_read_reg(priv, 0x04, &rd_bitmap_l); -+ bl_read_reg(priv, 0x05, &rd_bitmap_u); -+ bitmap = rd_bitmap_l; -+ bitmap |= rd_bitmap_u << 8; -+ -+ printk("rd_bitmap=0x%08x\n", bitmap); -+ -+ return 0; -+} -+ -+static ssize_t bl_dbgfs_rdbitmap_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ return 0; -+} -+ -+DEBUGFS_READ_WRITE_FILE_OPS(rdbitmap); -+ -+static ssize_t bl_dbgfs_wrbitmap_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *priv = file->private_data; -+ u8 wr_bitmap_l; -+ u8 wr_bitmap_u; -+ u32 bitmap; -+ -+ bl_read_reg(priv, 0x06, &wr_bitmap_l); -+ bl_read_reg(priv, 0x07, &wr_bitmap_u); -+ bitmap = wr_bitmap_l; -+ bitmap |= wr_bitmap_u << 8; -+ -+ printk("wr_bitmap=0x%08x\n", bitmap); -+ -+ return 0; -+} -+ -+static ssize_t bl_dbgfs_wrbitmap_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ return 0; -+} -+ -+DEBUGFS_READ_WRITE_FILE_OPS(wrbitmap); -+ -+ -+static ssize_t bl_dbgfs_run_fw_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *priv = file->private_data; -+ char buf[32]; -+ int ret; -+ ssize_t read; -+ u8 data; -+ -+ bl_read_reg(priv, 0x60, &data); -+ -+ printk("data=0x%x\n", data); -+ -+ ret = scnprintf(buf, 4, "0x%x", data); -+ -+ read = simple_read_from_buffer(user_buf, count, ppos, buf, ret); -+ -+ return read; -+} -+ -+static ssize_t bl_dbgfs_run_fw_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_hw *priv = file->private_data; -+ char buf[32]; -+ int val; -+ size_t len = min_t(size_t, count, sizeof(buf) - 1); -+ -+ if (copy_from_user(buf, user_buf, len)) -+ return -EFAULT; -+ -+ buf[len] = '\0'; -+ -+ if (sscanf(buf, "%d", &val) > 0) -+ { -+ printk("val=0x%x\n", val); -+ bl_write_reg(priv, 0x60, val); -+ } -+ -+ return count; -+} -+ -+ -+DEBUGFS_READ_WRITE_FILE_OPS(run_fw); -+ -+#ifdef CONFIG_BL_FULLMAC -+ -+#define LINE_MAX_SZ 150 -+ -+struct st { -+ char line[LINE_MAX_SZ + 1]; -+ unsigned int r_idx; -+}; -+ -+static int compare_idx(const void *st1, const void *st2) -+{ -+ int index1 = ((struct st *)st1)->r_idx; -+ int index2 = ((struct st *)st2)->r_idx; -+ -+ if (index1 > index2) return 1; -+ if (index1 < index2) return -1; -+ -+ return 0; -+} -+ -+static int print_rate(char *buf, int size, int format, int nss, int mcs, int bw, -+ int sgi, int pre, int *r_idx) -+{ -+ int res = 0; -+ int bitrates_cck[4] = { 10, 20, 55, 110 }; -+ int bitrates_ofdm[8] = { 6, 9, 12, 18, 24, 36, 48, 54}; -+ -+ if (format <= FORMATMOD_NON_HT_DUP_OFDM) { -+ if (mcs < 4) { -+ if (r_idx) { -+ *r_idx = (mcs * 2) + pre; -+ res = scnprintf(buf, size - res, "%3d ", *r_idx); -+ } -+ res += scnprintf(&buf[res], size - res, "L-CCK/%cP %2u.%1uM ", -+ pre > 0 ? 'L' : 'S', -+ bitrates_cck[mcs] / 10, -+ bitrates_cck[mcs] % 10); -+ } else { -+ if (r_idx) { -+ *r_idx = N_CCK + (mcs - 4); -+ res = scnprintf(buf, size - res, "%3d ", *r_idx); -+ } -+ res += scnprintf(&buf[res], size - res, "L-OFDM %2u.0M ", -+ bitrates_ofdm[mcs]); -+ } -+ } else if (format <= FORMATMOD_HT_GF) { -+ if (r_idx) { -+ *r_idx = N_CCK + N_OFDM + nss * 32 + mcs * 4 + bw * 2 + sgi; -+ res = scnprintf(buf, size - res, "%3d ", *r_idx); -+ } -+ res += scnprintf(&buf[res], size - res, "HT%d/%cGI MCS%-2d ", -+ 20 * (1 << bw), sgi ? 'S' : 'L', nss * 8 + mcs); -+ } else { -+ if (r_idx) { -+ *r_idx = N_CCK + N_OFDM + N_HT + nss * 80 + mcs * 8 + bw * 2 + sgi; -+ res = scnprintf(buf, size - res, "%3d ", *r_idx); -+ } -+ res += scnprintf(&buf[res], size - res, "VHT%d/%cGI%*cMCS%d/%1d", -+ 20 * (1 << bw), sgi ? 'S' : 'L', bw > 2 ? 1 : 2, ' ', -+ mcs, nss + 1); -+ -+ } -+ -+ return res; -+} -+ -+static int print_rate_from_cfg(char *buf, int size, u32 rate_config, int *r_idx) -+{ -+ union bl_rate_ctrl_info *r_cfg = (union bl_rate_ctrl_info *)&rate_config; -+ union bl_mcs_index *mcs_index = (union bl_mcs_index *)&rate_config; -+ unsigned int ft, pre, gi, bw, nss, mcs, len; -+ -+ ft = r_cfg->formatModTx; -+ pre = r_cfg->preTypeTx; -+ if (ft == FORMATMOD_VHT) { -+ mcs = mcs_index->vht.mcs; -+ nss = mcs_index->vht.nss; -+ } else if (ft >= FORMATMOD_HT_MF) { -+ mcs = mcs_index->ht.mcs; -+ nss = mcs_index->ht.nss; -+ } else { -+ mcs = mcs_index->legacy; -+ nss = 0; -+ } -+ gi = r_cfg->shortGITx; -+ bw = r_cfg->bwTx; -+ -+ len = print_rate(buf, size, ft, nss, mcs, bw, gi, pre, r_idx); -+ return len; -+} -+ -+static void idx_to_rate_cfg(int idx, union bl_rate_ctrl_info *r_cfg) -+{ -+ r_cfg->value = 0; -+ if (idx < N_CCK) -+ { -+ r_cfg->formatModTx = FORMATMOD_NON_HT; -+ r_cfg->preTypeTx = idx & 1; -+ r_cfg->mcsIndexTx = idx / 2; -+ } -+ else if (idx < (N_CCK + N_OFDM)) -+ { -+ r_cfg->formatModTx = FORMATMOD_NON_HT; -+ r_cfg->mcsIndexTx = idx - N_CCK + 4; -+ } -+ else if (idx < (N_CCK + N_OFDM + N_HT)) -+ { -+ union bl_mcs_index *r = (union bl_mcs_index *)r_cfg; -+ -+ idx -= (N_CCK + N_OFDM); -+ r_cfg->formatModTx = FORMATMOD_HT_MF; -+ r->ht.nss = idx / (8*2*2); -+ r->ht.mcs = (idx % (8*2*2)) / (2*2); -+ r_cfg->bwTx = ((idx % (8*2*2)) % (2*2)) / 2; -+ r_cfg->shortGITx = idx & 1; -+ } -+ else -+ { -+ union bl_mcs_index *r = (union bl_mcs_index *)r_cfg; -+ -+ idx -= (N_CCK + N_OFDM + N_HT); -+ r_cfg->formatModTx = FORMATMOD_VHT; -+ r->vht.nss = idx / (10*4*2); -+ r->vht.mcs = (idx % (10*4*2)) / (4*2); -+ r_cfg->bwTx = ((idx % (10*4*2)) % (4*2)) / 2; -+ r_cfg->shortGITx = idx & 1; -+ } -+} -+ -+static ssize_t bl_dbgfs_rc_stats_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_sta *sta = NULL; -+ struct bl_hw *priv = file->private_data; -+ char *buf; -+ int bufsz, len = 0; -+ ssize_t read; -+ int i = 0; -+ int error = 0; -+ struct me_rc_stats_cfm me_rc_stats_cfm; -+ unsigned int no_samples; -+ struct st *st; -+ u8 mac[6]; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* everything should fit in one call */ -+ if (*ppos) -+ return 0; -+ -+ /* Get the station index from MAC address */ -+ sscanf(file->f_path.dentry->d_parent->d_iname, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", -+ &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); -+ if (mac == NULL) -+ return 0; -+ sta = bl_get_sta(priv, mac); -+ if (sta == NULL) -+ return 0; -+ -+ /* Forward the information to the LMAC */ -+ if ((error = bl_send_me_rc_stats(priv, sta->sta_idx, &me_rc_stats_cfm))) -+ return error; -+ -+ no_samples = me_rc_stats_cfm.no_samples; -+ if (no_samples == 0) -+ return 0; -+ -+ bufsz = no_samples * LINE_MAX_SZ + 500; -+ -+ buf = kmalloc(bufsz + 1, GFP_ATOMIC); -+ if (buf == NULL) -+ return 0; -+ -+ st = kmalloc(sizeof(struct st) * no_samples, GFP_ATOMIC); -+ if (st == NULL) -+ { -+ kfree(buf); -+ return 0; -+ } -+ -+ for (i = 0; i < no_samples; i++) -+ { -+ unsigned int tp, eprob; -+ len = print_rate_from_cfg(st[i].line, LINE_MAX_SZ, -+ me_rc_stats_cfm.rate_stats[i].rate_config, -+ &st[i].r_idx); -+ -+ if (me_rc_stats_cfm.sw_retry_step != 0) -+ { -+ len += scnprintf(&st[i].line[len], LINE_MAX_SZ - len, "%c", -+ me_rc_stats_cfm.retry[me_rc_stats_cfm.sw_retry_step].idx == i ? '*' : ' '); -+ } -+ else -+ { -+ len += scnprintf(&st[i].line[len], LINE_MAX_SZ - len, " "); -+ } -+ len += scnprintf(&st[i].line[len], LINE_MAX_SZ - len, "%c", -+ me_rc_stats_cfm.retry[0].idx == i ? 'T' : ' '); -+ len += scnprintf(&st[i].line[len], LINE_MAX_SZ - len, "%c", -+ me_rc_stats_cfm.retry[1].idx == i ? 't' : ' '); -+ len += scnprintf(&st[i].line[len], LINE_MAX_SZ - len, "%c ", -+ me_rc_stats_cfm.retry[2].idx == i ? 'P' : ' '); -+ -+ tp = me_rc_stats_cfm.tp[i] / 10; -+ len += scnprintf(&st[i].line[len], LINE_MAX_SZ - len, " %4u.%1u", -+ tp / 10, tp % 10); -+ -+ eprob = ((me_rc_stats_cfm.rate_stats[i].probability * 1000) >> 16) + 1; -+ len += scnprintf(&st[i].line[len],LINE_MAX_SZ - len, -+ " %4u.%1u %6u(%6u) %6u %6u", -+ eprob / 10, eprob % 10, -+ me_rc_stats_cfm.rate_stats[i].success, -+ me_rc_stats_cfm.rate_stats[i].attempts, -+ me_rc_stats_cfm.rate_stats[i].sample_skipped, -+ me_rc_stats_cfm.rate_stats[i].n_retry & 0x1F); -+ } -+ len = scnprintf(buf, bufsz , -+ "\nTX rate info for %02X:%02X:%02X:%02X:%02X:%02X:\n", -+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); -+ -+ len += scnprintf(&buf[len], bufsz - len, -+ " # type rate tpt eprob ok( tot) skipped nRetry\n"); -+ -+ // add sorted statistics to the buffer -+ sort(st, no_samples, sizeof(st[0]), compare_idx, NULL); -+ for (i = 0; i < no_samples; i++) -+ { -+ len += scnprintf(&buf[len], bufsz - len, "%s\n", st[i].line); -+ } -+ len += scnprintf(&buf[len], bufsz - len, "\n MPDUs AMPDUs AvLen trialP"); -+ len += scnprintf(&buf[len], bufsz - len, "\n%6u %6u %3d.%1d %6u\n", -+ me_rc_stats_cfm.ampdu_len, -+ me_rc_stats_cfm.ampdu_packets, -+ me_rc_stats_cfm.avg_ampdu_len >> 16, -+ ((me_rc_stats_cfm.avg_ampdu_len * 10) >> 16) % 10, -+ me_rc_stats_cfm.sample_wait); -+ -+ read = simple_read_from_buffer(user_buf, count, ppos, buf, len); -+ -+ kfree(buf); -+ kfree(st); -+ -+ return read; -+} -+ -+DEBUGFS_READ_FILE_OPS(rc_stats); -+ -+static ssize_t bl_dbgfs_rc_fixed_rate_idx_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_sta *sta = NULL; -+ struct bl_hw *priv = file->private_data; -+ u8 mac[6]; -+ char buf[10]; -+ int fixed_rate_idx = -1; -+ union bl_rate_ctrl_info rate_config; -+ int error = 0; -+ size_t len = min_t(size_t, count, sizeof(buf) - 1); -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Get the station index from MAC address */ -+ sscanf(file->f_path.dentry->d_parent->d_iname, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", -+ &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); -+ if (mac == NULL) -+ return 0; -+ sta = bl_get_sta(priv, mac); -+ if (sta == NULL) -+ return 0; -+ -+ /* Get the content of the file */ -+ if (copy_from_user(buf, user_buf, len)) -+ return -EFAULT; -+ buf[len] = '\0'; -+ sscanf(buf, "%i\n", &fixed_rate_idx); -+ -+ /* Convert rate index into rate configuration */ -+ if ((fixed_rate_idx < 0) || (fixed_rate_idx >= (N_CCK + N_OFDM + N_HT + N_VHT))) -+ { -+ // disable fixed rate -+ rate_config.value = 0xFFFF; -+ } -+ else -+ { -+ idx_to_rate_cfg(fixed_rate_idx, &rate_config); -+ } -+ // Forward the request to the LMAC -+ if ((error = bl_send_me_rc_set_rate(priv, sta->sta_idx, -+ (u16)rate_config.value)) != 0) -+ { -+ return error; -+ } -+ -+ return len; -+} -+ -+DEBUGFS_WRITE_FILE_OPS(rc_fixed_rate_idx); -+ -+static ssize_t bl_dbgfs_last_rx_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_sta *sta = NULL; -+ struct bl_hw *priv = file->private_data; -+ struct bl_rx_rate_stats *rate_stats; -+ char *buf; -+ int bufsz, i, len = 0; -+ ssize_t read; -+ unsigned int fmt, pre, bw, nss, mcs, sgi; -+ u8 mac[6]; -+ struct hw_vect *last_rx; -+ char hist[] = "##################################################"; -+ int hist_len = sizeof(hist) - 1; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* everything should fit in one call */ -+ if (*ppos) -+ return 0; -+ -+ /* Get the station index from MAC address */ -+ sscanf(file->f_path.dentry->d_parent->d_iname, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", -+ &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); -+ if (mac == NULL) -+ return 0; -+ sta = bl_get_sta(priv, mac); -+ if (sta == NULL) -+ return 0; -+ -+ rate_stats = &sta->stats.rx_rate; -+ bufsz = (rate_stats->size * ( 30 * hist_len) + 200); -+ buf = kmalloc(bufsz + 1, GFP_ATOMIC); -+ if (buf == NULL) -+ return 0; -+ -+ len += scnprintf(buf, bufsz, -+ "\nRX rate info for %02X:%02X:%02X:%02X:%02X:%02X:\n", -+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); -+ -+ // Display Statistics -+ for (i = 0 ; i < rate_stats->size ; i++ ) -+ { -+ if (rate_stats->table[i]) { -+ union bl_rate_ctrl_info rate_config; -+ int percent = (rate_stats->table[i] * 1000) / rate_stats->cpt; -+ int p; -+ -+ idx_to_rate_cfg(i, &rate_config); -+ len += print_rate_from_cfg(&buf[len], bufsz - len, -+ rate_config.value, NULL); -+ p = (percent * hist_len) / 1000; -+ len += scnprintf(&buf[len], bufsz - len, ": %6d(%3d.%1d%%)%.*s\n", -+ rate_stats->table[i], -+ percent / 10, percent % 10, p, hist); -+ } -+ } -+ -+ // Display detailled info of the last received rate -+ last_rx = &sta->stats.last_rx; -+ -+ len += scnprintf(&buf[len], bufsz - len,"\nLast received rate\n" -+ " type rate LDPC STBC BEAMFM rssi(dBm)\n"); -+ -+ fmt = last_rx->format_mod; -+ bw = last_rx->ch_bw; -+ pre = last_rx->pre_type; -+ sgi = last_rx->short_gi; -+ if (fmt == FORMATMOD_VHT) { -+ mcs = last_rx->mcs; -+ nss = last_rx->stbc ? last_rx->n_sts/2 : last_rx->n_sts; -+ } else if (fmt >= FORMATMOD_HT_MF) { -+ mcs = last_rx->mcs; -+ nss = last_rx->stbc ? last_rx->stbc : last_rx->n_sts; -+ } else { -+ BUG_ON((mcs = legrates_lut[last_rx->leg_rate]) == -1); -+ nss = 0; -+ } -+ -+ len += print_rate(&buf[len], bufsz - len, fmt, nss, mcs, bw, sgi, pre, NULL); -+ -+ /* flags for HT/VHT */ -+ if (fmt == FORMATMOD_VHT) { -+ len += scnprintf(&buf[len], bufsz - len, " %c %c %c", -+ last_rx->fec_coding ? 'L' : ' ', -+ last_rx->stbc ? 'S' : ' ', -+ last_rx->smoothing ? ' ' : 'B'); -+ } else if (fmt >= FORMATMOD_HT_MF) { -+ len += scnprintf(&buf[len], bufsz - len, " %c %c ", -+ last_rx->fec_coding ? 'L' : ' ', -+ last_rx->stbc ? 'S' : ' '); -+ } else { -+ len += scnprintf(&buf[len], bufsz - len, " "); -+ } -+ len += scnprintf(&buf[len], bufsz - len, " %d\n", last_rx->rssi1); -+ -+ read = simple_read_from_buffer(user_buf, count, ppos, buf, len); -+ -+ kfree(buf); -+ return read; -+} -+ -+static ssize_t bl_dbgfs_last_rx_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct bl_sta *sta = NULL; -+ struct bl_hw *priv = file->private_data; -+ u8 mac[6]; -+ -+ /* Get the station index from MAC address */ -+ sscanf(file->f_path.dentry->d_parent->d_iname, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", -+ &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); -+ if (mac == NULL) -+ return 0; -+ sta = bl_get_sta(priv, mac); -+ if (sta == NULL) -+ return 0; -+ -+ /* Prevent from interrupt preemption as these statistics are updated under -+ * interrupt */ -+ spin_lock_bh(&priv->tx_lock); -+ memset(sta->stats.rx_rate.table, 0, -+ sta->stats.rx_rate.size * sizeof(sta->stats.rx_rate.table[0])); -+ sta->stats.rx_rate.cpt = 0; -+ spin_unlock_bh(&priv->tx_lock); -+ -+ return count; -+} -+ -+DEBUGFS_READ_WRITE_FILE_OPS(last_rx); -+ -+#endif /* CONFIG_BL_FULLMAC */ -+ -+/* -+ * Calls a userspace pgm -+ */ -+int bl_um_helper(struct bl_debugfs *bl_debugfs, const char *cmd) -+{ -+ char *envp[] = { "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL }; -+ char **argv; -+ int argc, ret; -+ -+ if (!bl_debugfs->dir || -+ !strlen((cmd = cmd ? cmd : bl_debugfs->helper_cmd))) -+ return 0; -+ argv = argv_split(in_interrupt() ? GFP_ATOMIC : GFP_KERNEL, cmd, &argc); -+ if (!argc) -+ return PTR_ERR(argv); -+ -+ if ((ret = call_usermodehelper(argv[0], argv, envp, -+ UMH_WAIT_PROC | UMH_KILLABLE))) -+ printk(KERN_CRIT "Failed to call %s (%s returned %d)\n", -+ argv[0], cmd, ret); -+ argv_free(argv); -+ -+ return ret; -+} -+ -+int bl_trigger_um_helper(struct bl_debugfs *bl_debugfs) -+{ -+ if (bl_debugfs->helper_scheduled == true) { -+ printk(KERN_CRIT "%s: Already scheduled\n", __func__); -+ return -EBUSY; -+ } -+ -+ spin_lock_bh(&bl_debugfs->umh_lock); -+ if (bl_debugfs->unregistering) { -+ spin_unlock_bh(&bl_debugfs->umh_lock); -+ printk(KERN_CRIT "%s: unregistering\n", __func__); -+ return -ENOENT; -+ } -+ bl_debugfs->helper_scheduled = true; -+ schedule_work(&bl_debugfs->helper_work); -+ spin_unlock_bh(&bl_debugfs->umh_lock); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_BL_FULLMAC -+static void bl_rc_stat_work(struct work_struct *ws) -+{ -+ struct bl_debugfs *bl_debugfs = container_of(ws, struct bl_debugfs, -+ rc_stat_work); -+ struct bl_hw *bl_hw = container_of(bl_debugfs, struct bl_hw, -+ debugfs); -+ struct bl_sta *sta; -+ uint8_t ridx, sta_idx; -+ -+ ridx = bl_debugfs->rc_read; -+ sta_idx = bl_debugfs->rc_sta[ridx]; -+ if (sta_idx > (NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX)) { -+ WARN(1, "Invalid sta index %d", sta_idx); -+ return; -+ } -+ -+ bl_debugfs->rc_sta[ridx] = 0xFF; -+ ridx = (ridx + 1) % ARRAY_SIZE(bl_debugfs->rc_sta); -+ bl_debugfs->rc_read = ridx; -+ sta = &bl_hw->sta_table[sta_idx]; -+ if (!sta) { -+ WARN(1, "Invalid sta %d", sta_idx); -+ return; -+ } -+ -+ if (bl_debugfs->dir_sta[sta_idx] == NULL) { -+ /* register the sta */ -+ struct dentry *dir_rc = bl_debugfs->dir_rc; -+ struct dentry *dir_sta; -+ struct dentry *file; -+ char sta_name[18]; -+ struct bl_rx_rate_stats *rate_stats = &sta->stats.rx_rate; -+ int nb_rx_rate = N_CCK + N_OFDM; -+ -+ -+ if (sta->sta_idx >= NX_REMOTE_STA_MAX) { -+ scnprintf(sta_name, sizeof(sta_name), "bc_mc"); -+ } else { -+ scnprintf(sta_name, sizeof(sta_name), "%pM", sta->mac_addr); -+ } -+ -+ if (!(dir_sta = debugfs_create_dir(sta_name, dir_rc))) -+ goto error; -+ -+ bl_debugfs->dir_sta[sta->sta_idx] = dir_sta; -+ -+ file = debugfs_create_file("stats", S_IRUSR, dir_sta, bl_hw, -+ &bl_dbgfs_rc_stats_ops); -+ if (IS_ERR_OR_NULL(file)) -+ goto error_after_dir; -+ -+ file = debugfs_create_file("fixed_rate_idx", S_IWUSR , dir_sta, bl_hw, -+ &bl_dbgfs_rc_fixed_rate_idx_ops); -+ if (IS_ERR_OR_NULL(file)) -+ goto error_after_dir; -+ -+ file = debugfs_create_file("rx_rate", S_IRUSR | S_IWUSR, dir_sta, bl_hw, -+ &bl_dbgfs_last_rx_ops); -+ if (IS_ERR_OR_NULL(file)) -+ goto error_after_dir; -+ -+ if (bl_hw->mod_params->ht_on) -+ nb_rx_rate += N_HT; -+ -+ if (bl_hw->mod_params->vht_on) -+ nb_rx_rate += N_VHT; -+ -+ rate_stats->table = kzalloc(nb_rx_rate * sizeof(rate_stats->table[0]), -+ GFP_KERNEL); -+ if (!rate_stats->table) -+ goto error_after_dir; -+ -+ rate_stats->size = nb_rx_rate; -+ rate_stats->cpt = 0; -+ -+ } else { -+ /* unregister the sta */ -+ if (sta->stats.rx_rate.table) { -+ kfree(sta->stats.rx_rate.table); -+ sta->stats.rx_rate.table = NULL; -+ } -+ sta->stats.rx_rate.size = 0; -+ sta->stats.rx_rate.cpt = 0; -+ -+ debugfs_remove_recursive(bl_debugfs->dir_sta[sta_idx]); -+ bl_debugfs->dir_sta[sta->sta_idx] = NULL; -+ } -+ -+ return; -+ -+ error_after_dir: -+ debugfs_remove_recursive(bl_debugfs->dir_sta[sta_idx]); -+ bl_debugfs->dir_sta[sta->sta_idx] = NULL; -+ error: -+ dev_err(bl_hw->dev, -+ "Error while (un)registering debug entry for sta %d\n", sta_idx); -+} -+ -+void _bl_dbgfs_rc_stat_write(struct bl_debugfs *bl_debugfs, uint8_t sta_idx) -+{ -+ uint8_t widx = bl_debugfs->rc_write; -+ if (bl_debugfs->rc_sta[widx] != 0XFF) { -+ WARN(1, "Overlap in debugfs rc_sta table\n"); -+ } -+ -+ bl_debugfs->rc_sta[widx] = sta_idx; -+ widx = (widx + 1) % ARRAY_SIZE(bl_debugfs->rc_sta); -+ bl_debugfs->rc_write = widx; -+ -+ schedule_work(&bl_debugfs->rc_stat_work); -+} -+ -+void bl_dbgfs_register_rc_stat(struct bl_hw *bl_hw, struct bl_sta *sta) -+{ -+ _bl_dbgfs_rc_stat_write(&bl_hw->debugfs, sta->sta_idx); -+} -+ -+void bl_dbgfs_unregister_rc_stat(struct bl_hw *bl_hw, struct bl_sta *sta) -+{ -+ _bl_dbgfs_rc_stat_write(&bl_hw->debugfs, sta->sta_idx); -+} -+#endif -+ -+ -+int bl_dbgfs_register(struct bl_hw *bl_hw, const char *name) -+{ -+ struct dentry *phyd = bl_hw->wiphy->debugfsdir; -+ struct dentry *dir_rc; -+ struct bl_debugfs *bl_debugfs = &bl_hw->debugfs; -+ struct dentry *dir_drv, *dir_diags; -+ -+ if (!(dir_drv = debugfs_create_dir(name, phyd))) -+ return -ENOMEM; -+ -+ bl_debugfs->dir = dir_drv; -+ bl_debugfs->unregistering = false; -+ -+ if (!(dir_diags = debugfs_create_dir("diags", dir_drv))) -+ goto err; -+ -+#ifdef CONFIG_BL_FULLMAC -+ if (!(dir_rc = debugfs_create_dir("rc", dir_drv))) -+ goto err; -+ bl_debugfs->dir_rc = dir_rc; -+ INIT_WORK(&bl_debugfs->rc_stat_work, bl_rc_stat_work); -+ bl_debugfs->rc_write = bl_debugfs->rc_read = 0; -+ memset(bl_debugfs->rc_sta, 0xFF, sizeof(bl_debugfs->rc_sta)); -+#endif -+ -+ DEBUGFS_ADD_FILE(stats, dir_drv, S_IWUSR | S_IRUSR); -+ DEBUGFS_ADD_FILE(sys_stats, dir_drv, S_IRUSR); -+ DEBUGFS_ADD_FILE(txq, dir_drv, S_IRUSR); -+ DEBUGFS_ADD_FILE(acsinfo, dir_drv, S_IRUSR); -+ -+ DEBUGFS_ADD_FILE(run_fw, dir_drv, S_IWUSR | S_IRUSR); -+ DEBUGFS_ADD_FILE(sdio_test, dir_drv, S_IWUSR | S_IRUSR); -+ DEBUGFS_ADD_FILE(rdbitmap, dir_drv, S_IWUSR | S_IRUSR); -+ DEBUGFS_ADD_FILE(wrbitmap, dir_drv, S_IWUSR | S_IRUSR); -+ DEBUGFS_ADD_FILE(rw_reg, dir_drv, S_IWUSR | S_IRUSR); -+ DEBUGFS_ADD_FILE(dbg_cdt, dir_drv, S_IWUSR | S_IRUSR); -+ DEBUGFS_ADD_FILE(dbg_time, dir_drv, S_IWUSR | S_IRUSR); -+ -+ bl_debugfs->trace_prst = bl_debugfs->helper_scheduled = false; -+ spin_lock_init(&bl_debugfs->umh_lock); -+ DEBUGFS_ADD_FILE(rhd, dir_diags, S_IRUSR); -+ DEBUGFS_ADD_FILE(rbd, dir_diags, S_IRUSR); -+ DEBUGFS_ADD_FILE(thd0, dir_diags, S_IRUSR); -+ DEBUGFS_ADD_FILE(thd1, dir_diags, S_IRUSR); -+ DEBUGFS_ADD_FILE(thd2, dir_diags, S_IRUSR); -+ DEBUGFS_ADD_FILE(thd3, dir_diags, S_IRUSR); -+#if (NX_TXQ_CNT == 5) -+ DEBUGFS_ADD_FILE(thd4, dir_diags, S_IRUSR); -+#endif -+ DEBUGFS_ADD_FILE(mactrace, dir_diags, S_IRUSR); -+ DEBUGFS_ADD_FILE(mactctrig, dir_diags, S_IRUSR); -+ DEBUGFS_ADD_FILE(macdiags, dir_diags, S_IRUSR); -+ DEBUGFS_ADD_FILE(phydiags, dir_diags, S_IRUSR); -+ DEBUGFS_ADD_FILE(plfdiags, dir_diags, S_IRUSR); -+ DEBUGFS_ADD_FILE(hwdiags, dir_diags, S_IRUSR); -+ DEBUGFS_ADD_FILE(swdiags, dir_diags, S_IRUSR); -+ DEBUGFS_ADD_FILE(error, dir_diags, S_IRUSR); -+ DEBUGFS_ADD_FILE(rxdesc, dir_diags, S_IRUSR); -+ DEBUGFS_ADD_FILE(txdesc, dir_diags, S_IRUSR); -+ DEBUGFS_ADD_FILE(macrxptr, dir_diags, S_IRUSR); -+ DEBUGFS_ADD_FILE(lamacconf, dir_diags, S_IRUSR); -+ DEBUGFS_ADD_FILE(chaninfo, dir_diags, S_IRUSR); -+ DEBUGFS_ADD_FILE(fw_dbg, dir_diags, S_IWUSR | S_IRUSR); -+ -+ return 0; -+ -+err: -+ bl_dbgfs_unregister(bl_hw); -+ return -ENOMEM; -+} -+ -+void bl_dbgfs_unregister(struct bl_hw *bl_hw) -+{ -+ struct bl_debugfs *bl_debugfs = &bl_hw->debugfs; -+ -+ if (!bl_hw->debugfs.dir) -+ return; -+ -+ bl_debugfs->unregistering = true; -+ flush_work(&bl_debugfs->helper_work); -+#ifdef CONFIG_BL_FULLMAC -+ flush_work(&bl_debugfs->rc_stat_work); -+#endif -+ debugfs_remove_recursive(bl_hw->debugfs.dir); -+ bl_hw->debugfs.dir = NULL; -+} -+ -diff -Naur /dev/null_debugfs.h b/drivers/net/wireless/hflps170/bl_debugfs.h ---- /dev/null_debugfs.h 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_debugfs.h 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,78 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file bl_debugfs.h -+ * -+ * @brief Miscellaneous utility function definitions -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ ****************************************************************************** -+ */ -+ -+ -+#ifndef _BL_DEBUGFS_H_ -+#define _BL_DEBUGFS_H_ -+ -+#include -+ -+struct bl_hw; -+struct bl_sta; -+ -+#ifdef CONFIG_BL_DEBUGFS -+ -+struct bl_debugfs { -+ unsigned long long rateidx; -+ struct dentry *dir; -+ bool trace_prst; -+ -+ char helper_cmd[64]; -+ struct work_struct helper_work; -+ bool helper_scheduled; -+ spinlock_t umh_lock; -+ -+ bool unregistering; -+ -+#ifdef CONFIG_BL_FULLMAC -+ struct work_struct rc_stat_work; -+ uint8_t rc_sta[NX_REMOTE_STA_MAX]; -+ uint8_t rc_write; -+ uint8_t rc_read; -+ struct dentry *dir_rc; -+ struct dentry *dir_sta[NX_REMOTE_STA_MAX]; -+#endif -+}; -+ -+int bl_dbgfs_register(struct bl_hw *bl_hw, const char *name); -+void bl_dbgfs_unregister(struct bl_hw *bl_hw); -+int bl_um_helper(struct bl_debugfs *bl_debugfs, const char *cmd); -+int bl_trigger_um_helper(struct bl_debugfs *bl_debugfs); -+#ifdef CONFIG_BL_FULLMAC -+void bl_dbgfs_register_rc_stat(struct bl_hw *bl_hw, struct bl_sta *sta); -+void bl_dbgfs_unregister_rc_stat(struct bl_hw *bl_hw, struct bl_sta *sta); -+#endif -+ -+void bl_dump_trace(struct bl_hw *bl_hw); -+void bl_reset_trace(struct bl_hw *bl_hw); -+ -+#else -+ -+struct bl_debugfs { -+}; -+ -+static inline int bl_dbgfs_register(struct bl_hw *bl_hw, const char *name) { return 0; } -+static inline void bl_dbgfs_unregister(struct bl_hw *bl_hw) {} -+static inline int bl_um_helper(struct bl_debugfs *bl_debugfs, const char *cmd) { return 0; } -+static inline int bl_trigger_um_helper(struct bl_debugfs *bl_debugfs) {} -+#ifdef CONFIG_BL_FULLMAC -+static inline void bl_dbgfs_register_rc_stat(struct bl_hw *bl_hw, struct bl_sta *sta) {} -+static inline void bl_dbgfs_unregister_rc_stat(struct bl_hw *bl_hw, struct bl_sta *sta) {} -+#endif -+ -+void bl_dump_trace(struct bl_hw *bl_hw) {} -+void bl_reset_trace(struct bl_hw *bl_hw) {} -+ -+#endif /* CONFIG_BL_DEBUGFS */ -+ -+ -+#endif /* _BL_DEBUGFS_H_ */ -diff -Naur /dev/null_events.h b/drivers/net/wireless/hflps170/bl_events.h ---- /dev/null_events.h 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_events.h 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,993 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file bl_events.h -+ * -+ * @brief Trace events definition -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ ****************************************************************************** -+ */ -+#undef TRACE_SYSTEM -+#define TRACE_SYSTEM bl -+ -+#if !defined(_BL_EVENTS_H) || defined(TRACE_HEADER_MULTI_READ) -+#define _BL_EVENTS_H -+ -+#include -+ -+#include "bl_compat.h" -+ -+/***************************************************************************** -+ * TRACE function for MGMT TX (FULLMAC) -+ ****************************************************************************/ -+#ifdef CONFIG_BL_FULLMAC -+#include "linux/ieee80211.h" -+#if defined(CONFIG_TRACEPOINTS) && defined(CREATE_TRACE_POINTS) -+#include -+#include -+ -+/* P2P Public Action Frames Definitions (see WiFi P2P Technical Specification, section 4.2.8) */ -+/* IEEE 802.11 Public Action Usage Category - Define P2P public action frames */ -+#define MGMT_ACTION_PUBLIC_CAT (0x04) -+/* Offset of OUI Subtype field in P2P Action Frame format */ -+#define MGMT_ACTION_OUI_SUBTYPE_OFFSET (6) -+/* P2P Public Action Frame Types */ -+enum p2p_action_type { -+ P2P_ACTION_GO_NEG_REQ = 0, /* GO Negociation Request */ -+ P2P_ACTION_GO_NEG_RSP, /* GO Negociation Response */ -+ P2P_ACTION_GO_NEG_CFM, /* GO Negociation Confirmation */ -+ P2P_ACTION_INVIT_REQ, /* P2P Invitation Request */ -+ P2P_ACTION_INVIT_RSP, /* P2P Invitation Response */ -+ P2P_ACTION_DEV_DISC_REQ, /* Device Discoverability Request */ -+ P2P_ACTION_DEV_DISC_RSP, /* Device Discoverability Response */ -+ P2P_ACTION_PROV_DISC_REQ, /* Provision Discovery Request */ -+ P2P_ACTION_PROV_DISC_RSP, /* Provision Discovery Response */ -+}; -+ -+const char *ftrace_print_mgmt_info(struct trace_seq *p, u16 frame_control, u8 cat, u8 type, u8 p2p) { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0) -+ const char *ret = trace_seq_buffer_ptr(p); -+#else -+ const char *ret = p->buffer + p->len; -+#endif -+ -+ switch (frame_control & IEEE80211_FCTL_STYPE) { -+ case (IEEE80211_STYPE_ASSOC_REQ): trace_seq_printf(p, "Association Request"); break; -+ case (IEEE80211_STYPE_ASSOC_RESP): trace_seq_printf(p, "Association Response"); break; -+ case (IEEE80211_STYPE_REASSOC_REQ): trace_seq_printf(p, "Reassociation Request"); break; -+ case (IEEE80211_STYPE_REASSOC_RESP): trace_seq_printf(p, "Reassociation Response"); break; -+ case (IEEE80211_STYPE_PROBE_REQ): trace_seq_printf(p, "Probe Request"); break; -+ case (IEEE80211_STYPE_PROBE_RESP): trace_seq_printf(p, "Probe Response"); break; -+ case (IEEE80211_STYPE_BEACON): trace_seq_printf(p, "Beacon"); break; -+ case (IEEE80211_STYPE_ATIM): trace_seq_printf(p, "ATIM"); break; -+ case (IEEE80211_STYPE_DISASSOC): trace_seq_printf(p, "Disassociation"); break; -+ case (IEEE80211_STYPE_AUTH): trace_seq_printf(p, "Authentication"); break; -+ case (IEEE80211_STYPE_DEAUTH): trace_seq_printf(p, "Deauthentication"); break; -+ case (IEEE80211_STYPE_ACTION): -+ trace_seq_printf(p, "Action"); -+ if (cat == MGMT_ACTION_PUBLIC_CAT && type == 0x9) -+ switch (p2p) { -+ case (P2P_ACTION_GO_NEG_REQ): trace_seq_printf(p, ": GO Negociation Request"); break; -+ case (P2P_ACTION_GO_NEG_RSP): trace_seq_printf(p, ": GO Negociation Response"); break; -+ case (P2P_ACTION_GO_NEG_CFM): trace_seq_printf(p, ": GO Negociation Confirmation"); break; -+ case (P2P_ACTION_INVIT_REQ): trace_seq_printf(p, ": P2P Invitation Request"); break; -+ case (P2P_ACTION_INVIT_RSP): trace_seq_printf(p, ": P2P Invitation Response"); break; -+ case (P2P_ACTION_DEV_DISC_REQ): trace_seq_printf(p, ": Device Discoverability Request"); break; -+ case (P2P_ACTION_DEV_DISC_RSP): trace_seq_printf(p, ": Device Discoverability Response"); break; -+ case (P2P_ACTION_PROV_DISC_REQ): trace_seq_printf(p, ": Provision Discovery Request"); break; -+ case (P2P_ACTION_PROV_DISC_RSP): trace_seq_printf(p, ": Provision Discovery Response"); break; -+ default: trace_seq_printf(p, "Unknown p2p %d", p2p); break; -+ } -+ else { -+ switch (cat) { -+ case 0: trace_seq_printf(p, ":Spectrum %d", type); break; -+ case 1: trace_seq_printf(p, ":QOS %d", type); break; -+ case 2: trace_seq_printf(p, ":DLS %d", type); break; -+ case 3: trace_seq_printf(p, ":BA %d", type); break; -+ case 4: trace_seq_printf(p, ":Public %d", type); break; -+ case 5: trace_seq_printf(p, ":Radio Measure %d", type); break; -+ case 6: trace_seq_printf(p, ":Fast BSS %d", type); break; -+ case 7: trace_seq_printf(p, ":HT Action %d", type); break; -+ case 8: trace_seq_printf(p, ":SA Query %d", type); break; -+ case 9: trace_seq_printf(p, ":Protected Public %d", type); break; -+ case 10: trace_seq_printf(p, ":WNM %d", type); break; -+ case 11: trace_seq_printf(p, ":Unprotected WNM %d", type); break; -+ case 12: trace_seq_printf(p, ":TDLS %d", type); break; -+ case 13: trace_seq_printf(p, ":Mesh %d", type); break; -+ case 14: trace_seq_printf(p, ":MultiHop %d", type); break; -+ case 15: trace_seq_printf(p, ":Self Protected %d", type); break; -+ case 126: trace_seq_printf(p, ":Vendor protected"); break; -+ case 127: trace_seq_printf(p, ":Vendor"); break; -+ default: trace_seq_printf(p, ":Unknown category %d", cat); break; -+ } -+ } -+ break; -+ default: trace_seq_printf(p, "Unknown subtype %d", frame_control & IEEE80211_FCTL_STYPE); break; -+ } -+ -+ trace_seq_putc(p, 0); -+ -+ return ret; -+} -+#endif /* defined(CONFIG_TRACEPOINTS) && defined(CREATE_TRACE_POINTS) */ -+ -+#undef __print_mgmt_info -+#define __print_mgmt_info(frame_control, cat, type, p2p) ftrace_print_mgmt_info(p, frame_control, cat, type, p2p) -+ -+TRACE_EVENT( -+ roc, -+ TP_PROTO(u8 vif_idx, u16 freq, unsigned int duration), -+ TP_ARGS(vif_idx, freq, duration), -+ TP_STRUCT__entry( -+ __field(u8, vif_idx) -+ __field(u16, freq) -+ __field(unsigned int, duration) -+ ), -+ TP_fast_assign( -+ __entry->vif_idx = vif_idx; -+ __entry->freq = freq; -+ __entry->duration = duration; -+ ), -+ TP_printk("f=%d vif=%d dur=%d", -+ __entry->freq, __entry->vif_idx, __entry->duration) -+); -+ -+TRACE_EVENT( -+ cancel_roc, -+ TP_PROTO(u8 vif_idx), -+ TP_ARGS(vif_idx), -+ TP_STRUCT__entry( -+ __field(u8, vif_idx) -+ ), -+ TP_fast_assign( -+ __entry->vif_idx = vif_idx; -+ ), -+ TP_printk("vif=%d", __entry->vif_idx) -+); -+ -+TRACE_EVENT( -+ roc_exp, -+ TP_PROTO(u8 vif_idx), -+ TP_ARGS(vif_idx), -+ TP_STRUCT__entry( -+ __field(u8, vif_idx) -+ ), -+ TP_fast_assign( -+ __entry->vif_idx = vif_idx; -+ ), -+ TP_printk("vif=%d", __entry->vif_idx) -+); -+ -+TRACE_EVENT( -+ switch_roc, -+ TP_PROTO(u8 vif_idx), -+ TP_ARGS(vif_idx), -+ TP_STRUCT__entry( -+ __field(u8, vif_idx) -+ ), -+ TP_fast_assign( -+ __entry->vif_idx = vif_idx; -+ ), -+ TP_printk("vif=%d", __entry->vif_idx) -+); -+ -+DECLARE_EVENT_CLASS( -+ mgmt_template, -+ TP_PROTO(u16 freq, u8 vif_idx, u8 sta_idx, struct ieee80211_mgmt *mgmt), -+ TP_ARGS(freq, vif_idx, sta_idx, mgmt), -+ TP_STRUCT__entry( -+ __field(u16, freq) -+ __field(u8, vif_idx) -+ __field(u8, sta_idx) -+ __field(u16, frame_control) -+ __field(u8, action_cat) -+ __field(u8, action_type) -+ __field(u8, action_p2p) -+ __array(u8, sa, 6) -+ __array(u8, da, 6) -+ __array(u8, bssid, 6) -+ __array(u8, name, 8) -+ ), -+ TP_fast_assign( -+ int i; -+ __entry->freq = freq; -+ __entry->vif_idx = vif_idx; -+ __entry->sta_idx = sta_idx; -+ __entry->frame_control = mgmt->frame_control; -+ __entry->action_cat = mgmt->u.action.category; -+ __entry->action_type = mgmt->u.action.u.wme_action.action_code; -+ __entry->action_p2p = *((u8 *)&mgmt->u.action.category -+ + MGMT_ACTION_OUI_SUBTYPE_OFFSET); -+ for(i=0; i<6; i++) { -+ __entry->sa[i] = mgmt->sa[i]; -+ __entry->da[i] = mgmt->da[i]; -+ __entry->bssid[i] = mgmt->bssid[i]; -+ -+ } -+ for(i=0; i<8; i++) { -+ __entry->name[i] = mgmt->u.beacon.variable[i]; -+ } -+ ), -+ TP_printk("f=%d vif=%d sta=%d -> %s, sa:%x:%x:%x:%x:%x:%x, \ -+ da:%x:%x:%x:%x:%x:%x, bssid:%x:%x:%x:%x:%x:%x, \ -+ name: %c%c%c%c%c%c", -+ __entry->freq, __entry->vif_idx, __entry->sta_idx, -+ __print_mgmt_info(__entry->frame_control, __entry->action_cat, -+ __entry->action_type, __entry->action_p2p), -+ __entry->sa[0], __entry->sa[1], __entry->sa[2], __entry->sa[3], __entry->sa[4], __entry->sa[5], -+ __entry->da[0], __entry->da[1], __entry->da[2], __entry->da[3], __entry->da[4], __entry->da[5], -+ __entry->bssid[0], __entry->bssid[1], __entry->bssid[2], __entry->bssid[3], __entry->bssid[4], __entry->bssid[5], -+ __entry->name[2], __entry->name[3], __entry->name[4], __entry->name[5], __entry->name[6], __entry->name[7]) -+); -+ -+DEFINE_EVENT(mgmt_template, mgmt_tx, -+ TP_PROTO(u16 freq, u8 vif_idx, u8 sta_idx, struct ieee80211_mgmt *mgmt), -+ TP_ARGS(freq, vif_idx, sta_idx, mgmt)); -+ -+DEFINE_EVENT(mgmt_template, mgmt_rx, -+ TP_PROTO(u16 freq, u8 vif_idx, u8 sta_idx, struct ieee80211_mgmt *mgmt), -+ TP_ARGS(freq, vif_idx, sta_idx, mgmt)); -+ -+TRACE_EVENT( -+ mgmt_cfm, -+ TP_PROTO(u8 vif_idx, u8 sta_idx, bool acked), -+ TP_ARGS(vif_idx, sta_idx, acked), -+ TP_STRUCT__entry( -+ __field(u8, vif_idx) -+ __field(u8, sta_idx) -+ __field(bool, acked) -+ ), -+ TP_fast_assign( -+ __entry->vif_idx = vif_idx; -+ __entry->sta_idx = sta_idx; -+ __entry->acked = acked; -+ ), -+ TP_printk("vif=%d sta=%d ack=%d", -+ __entry->vif_idx, __entry->sta_idx, __entry->acked) -+); -+#endif /* CONFIG_BL_FULLMAC */ -+ -+/***************************************************************************** -+ * TRACE function for TXQ -+ ****************************************************************************/ -+#include "bl_tx.h" -+#if defined(CONFIG_TRACEPOINTS) && defined(CREATE_TRACE_POINTS) -+ -+#include -+#include -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) -+#include -+#else -+#include -+#endif -+ -+ -+const char * -+ftrace_print_txq(struct trace_seq *p, int txq_idx) { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0) -+ const char *ret = trace_seq_buffer_ptr(p); -+#else -+ const char *ret = p->buffer + p->len; -+#endif -+ -+ if (txq_idx == TXQ_INACTIVE) { -+ trace_seq_printf(p, "[INACTIVE]"); -+ } else if (txq_idx < NX_FIRST_VIF_TXQ_IDX) { -+ trace_seq_printf(p, "[STA %d/%d]", -+ txq_idx / NX_NB_TXQ_PER_STA, -+ txq_idx % NX_NB_TXQ_PER_STA); -+#ifdef CONFIG_BL_FULLMAC -+ } else if (txq_idx < NX_FIRST_UNK_TXQ_IDX) { -+ trace_seq_printf(p, "[BC/MC %d]", -+ txq_idx - NX_FIRST_BCMC_TXQ_IDX); -+ } else if (txq_idx < NX_OFF_CHAN_TXQ_IDX) { -+ trace_seq_printf(p, "[UNKNOWN %d]", -+ txq_idx - NX_FIRST_UNK_TXQ_IDX); -+ } else if (txq_idx == NX_OFF_CHAN_TXQ_IDX) { -+ trace_seq_printf(p, "[OFFCHAN]"); -+#else -+ } else if (txq_idx < NX_NB_TXQ) { -+ txq_idx -= NX_FIRST_VIF_TXQ_IDX; -+ trace_seq_printf(p, "[VIF %d/%d]", -+ txq_idx / NX_NB_TXQ_PER_VIF, -+ txq_idx % NX_NB_TXQ_PER_VIF); -+#endif -+ } else { -+ trace_seq_printf(p, "[ERROR %d]", txq_idx); -+ } -+ -+ trace_seq_putc(p, 0); -+ -+ return ret; -+} -+ -+const char * -+ftrace_print_sta(struct trace_seq *p, int sta_idx) { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0) -+ const char *ret = trace_seq_buffer_ptr(p); -+#else -+ const char *ret = p->buffer + p->len; -+#endif -+ -+ if (sta_idx < NX_REMOTE_STA_MAX) { -+ trace_seq_printf(p, "[STA %d]", sta_idx); -+ } else { -+ trace_seq_printf(p, "[BC/MC %d]", sta_idx - NX_REMOTE_STA_MAX); -+ } -+ -+ trace_seq_putc(p, 0); -+ -+ return ret; -+} -+ -+const char * -+ftrace_print_hwq(struct trace_seq *p, int hwq_idx) { -+ -+ static const struct trace_print_flags symbols[] = -+ {{BL_HWQ_BK, "BK"}, -+ {BL_HWQ_BE, "BE"}, -+ {BL_HWQ_VI, "VI"}, -+ {BL_HWQ_VO, "VO"}, -+#ifdef CONFIG_BL_FULLMAC -+ {BL_HWQ_BCMC, "BCMC"}, -+#else -+ {BL_HWQ_BCN, "BCN"}, -+#endif -+ { -1, NULL }}; -+ return trace_print_symbols_seq(p, hwq_idx, symbols); -+} -+ -+const char * -+ftrace_print_hwq_cred(struct trace_seq *p, u8 *cred) { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0) -+ const char *ret = trace_seq_buffer_ptr(p); -+#else -+ const char *ret = p->buffer + p->len; -+#endif -+ -+#if CONFIG_USER_MAX == 1 -+ trace_seq_printf(p, "%d", cred[0]); -+#else -+ int i; -+ -+ for (i = 0; i < CONFIG_USER_MAX - 1; i++) -+ trace_seq_printf(p, "%d-", cred[i]); -+ trace_seq_printf(p, "%d", cred[i]); -+#endif -+ -+ trace_seq_putc(p, 0); -+ return ret; -+} -+ -+const char * -+ftrace_print_mu_info(struct trace_seq *p, u8 mu_info) { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0) -+ const char *ret = trace_seq_buffer_ptr(p); -+#else -+ const char *ret = p->buffer + p->len; -+#endif -+ -+ if (mu_info) -+ trace_seq_printf(p, "MU: %d-%d", (mu_info & 0x3f), (mu_info >> 6)); -+ -+ trace_seq_putc(p, 0); -+ return ret; -+} -+ -+const char * -+ftrace_print_mu_group(struct trace_seq *p, int nb_user, u8 *users) { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0) -+ const char *ret = trace_seq_buffer_ptr(p); -+#else -+ const char *ret = p->buffer + p->len; -+#endif -+ int i; -+ -+ if (users[0] != 0xff) -+ trace_seq_printf(p, "(%d", users[0]); -+ else -+ trace_seq_printf(p, "(-"); -+ for (i = 1; i < CONFIG_USER_MAX ; i++) { -+ if (users[i] != 0xff) -+ trace_seq_printf(p, ",%d", users[i]); -+ else -+ trace_seq_printf(p, ",-"); -+ } -+ -+ trace_seq_printf(p, ")"); -+ trace_seq_putc(p, 0); -+ return ret; -+} -+ -+#endif /* defined(CONFIG_TRACEPOINTS) && defined(CREATE_TRACE_POINTS) */ -+ -+#undef __print_txq -+#define __print_txq(txq_idx) ftrace_print_txq(p, txq_idx) -+ -+#undef __print_sta -+#define __print_sta(sta_idx) ftrace_print_sta(p, sta_idx) -+ -+#undef __print_hwq -+#define __print_hwq(hwq) ftrace_print_hwq(p, hwq) -+ -+#undef __print_hwq_cred -+#define __print_hwq_cred(cred) ftrace_print_hwq_cred(p, cred) -+ -+#undef __print_mu_info -+#define __print_mu_info(mu_info) ftrace_print_mu_info(p, mu_info) -+ -+#undef __print_mu_group -+#define __print_mu_group(nb, users) ftrace_print_mu_group(p, nb, users) -+ -+#ifdef CONFIG_BL_FULLMAC -+ -+TRACE_EVENT( -+ txq_select, -+ TP_PROTO(int txq_idx, u16 pkt_ready_up, struct sk_buff *skb), -+ TP_ARGS(txq_idx, pkt_ready_up, skb), -+ TP_STRUCT__entry( -+ __field(u16, txq_idx) -+ __field(u16, pkt_ready) -+ __field(struct sk_buff *, skb) -+ ), -+ TP_fast_assign( -+ __entry->txq_idx = txq_idx; -+ __entry->pkt_ready = pkt_ready_up; -+ __entry->skb = skb; -+ ), -+ TP_printk("%s pkt_ready_up=%d skb=%p", __print_txq(__entry->txq_idx), -+ __entry->pkt_ready, __entry->skb) -+); -+ -+#endif /* CONFIG_BL_FULLMAC */ -+ -+DECLARE_EVENT_CLASS( -+ hwq_template, -+ TP_PROTO(u8 hwq_idx), -+ TP_ARGS(hwq_idx), -+ TP_STRUCT__entry( -+ __field(u8, hwq_idx) -+ ), -+ TP_fast_assign( -+ __entry->hwq_idx = hwq_idx; -+ ), -+ TP_printk("%s", __print_hwq(__entry->hwq_idx)) -+); -+ -+DEFINE_EVENT(hwq_template, hwq_flowctrl_stop, -+ TP_PROTO(u8 hwq_idx), -+ TP_ARGS(hwq_idx)); -+ -+DEFINE_EVENT(hwq_template, hwq_flowctrl_start, -+ TP_PROTO(u8 hwq_idx), -+ TP_ARGS(hwq_idx)); -+ -+ -+DECLARE_EVENT_CLASS( -+ txq_template, -+ TP_PROTO(struct bl_txq *txq), -+ TP_ARGS(txq), -+ TP_STRUCT__entry( -+ __field(u16, txq_idx) -+ ), -+ TP_fast_assign( -+ __entry->txq_idx = txq->idx; -+ ), -+ TP_printk("%s", __print_txq(__entry->txq_idx)) -+); -+ -+DEFINE_EVENT(txq_template, txq_add_to_hw, -+ TP_PROTO(struct bl_txq *txq), -+ TP_ARGS(txq)); -+ -+DEFINE_EVENT(txq_template, txq_del_from_hw, -+ TP_PROTO(struct bl_txq *txq), -+ TP_ARGS(txq)); -+ -+#ifdef CONFIG_BL_FULLMAC -+ -+DEFINE_EVENT(txq_template, txq_flowctrl_stop, -+ TP_PROTO(struct bl_txq *txq), -+ TP_ARGS(txq)); -+ -+DEFINE_EVENT(txq_template, txq_flowctrl_restart, -+ TP_PROTO(struct bl_txq *txq), -+ TP_ARGS(txq)); -+ -+#endif /* CONFIG_BL_FULLMAC */ -+ -+TRACE_EVENT( -+ process_txq, -+ TP_PROTO(struct bl_txq *txq), -+ TP_ARGS(txq), -+ TP_STRUCT__entry( -+ __field(u16, txq_idx) -+ __field(u16, len) -+ __field(u16, len_retry) -+ __field(s8, credit) -+ #ifdef CONFIG_BL_FULLMAC -+ __field(u16, limit) -+ #endif /* CONFIG_BL_FULLMAC*/ -+ ), -+ TP_fast_assign( -+ __entry->txq_idx = txq->idx; -+ __entry->len = skb_queue_len(&txq->sk_list); -+ __entry->len_retry = txq->nb_retry; -+ __entry->credit = txq->credits; -+ #ifdef CONFIG_BL_FULLMAC -+ __entry->limit = txq->push_limit; -+ #endif /* CONFIG_BL_FULLMAC*/ -+ ), -+ -+ #ifdef CONFIG_BL_FULLMAC -+ TP_printk("%s txq_credits=%d, len=%d, retry_len=%d, push_limit=%d", -+ __print_txq(__entry->txq_idx), __entry->credit, -+ __entry->len, __entry->len_retry, __entry->limit) -+ #else -+ TP_printk("%s txq_credits=%d, len=%d, retry_len=%d", -+ __print_txq(__entry->txq_idx), __entry->credit, -+ __entry->len, __entry->len_retry) -+ #endif /* CONFIG_BL_FULLMAC*/ -+); -+ -+DECLARE_EVENT_CLASS( -+ txq_reason_template, -+ TP_PROTO(struct bl_txq *txq, u16 reason), -+ TP_ARGS(txq, reason), -+ TP_STRUCT__entry( -+ __field(u16, txq_idx) -+ __field(u16, reason) -+ __field(u16, status) -+ ), -+ TP_fast_assign( -+ __entry->txq_idx = txq->idx; -+ __entry->reason = reason; -+ __entry->status = txq->status; -+ ), -+ TP_printk("%s reason=%s status=%s", -+ __print_txq(__entry->txq_idx), -+ __print_symbolic(__entry->reason, -+ {BL_TXQ_STOP_FULL, "FULL"}, -+ {BL_TXQ_STOP_CSA, "CSA"}, -+ {BL_TXQ_STOP_STA_PS, "PS"}, -+ {BL_TXQ_STOP_VIF_PS, "VPS"}, -+ {BL_TXQ_STOP_CHAN, "CHAN"}, -+ {BL_TXQ_STOP_MU_POS, "MU"}), -+ __print_flags(__entry->status, "|", -+ {BL_TXQ_IN_HWQ_LIST, "IN LIST"}, -+ {BL_TXQ_STOP_FULL, "FULL"}, -+ {BL_TXQ_STOP_CSA, "CSA"}, -+ {BL_TXQ_STOP_STA_PS, "PS"}, -+ {BL_TXQ_STOP_VIF_PS, "VPS"}, -+ {BL_TXQ_STOP_CHAN, "CHAN"}, -+ {BL_TXQ_STOP_MU_POS, "MU"}, -+ {BL_TXQ_NDEV_FLOW_CTRL, "FLW_CTRL"})) -+); -+ -+DEFINE_EVENT(txq_reason_template, txq_start, -+ TP_PROTO(struct bl_txq *txq, u16 reason), -+ TP_ARGS(txq, reason)); -+ -+DEFINE_EVENT(txq_reason_template, txq_stop, -+ TP_PROTO(struct bl_txq *txq, u16 reason), -+ TP_ARGS(txq, reason)); -+ -+ -+TRACE_EVENT( -+ push_desc, -+ TP_PROTO(struct sk_buff *skb, struct bl_sw_txhdr *sw_txhdr, int push_flags), -+ -+ TP_ARGS(skb, sw_txhdr, push_flags), -+ -+ TP_STRUCT__entry( -+ __field(struct sk_buff *, skb) -+ __field(unsigned int, len) -+ __field(u16, tx_queue) -+ __field(u8, hw_queue) -+ __field(u8, push_flag) -+ __field(u32, flag) -+ __field(s8, txq_cred) -+ __field(u8, hwq_cred) -+ __field(u8, mu_info) -+ ), -+ TP_fast_assign( -+ __entry->skb = skb; -+ __entry->tx_queue = sw_txhdr->txq->idx; -+ __entry->push_flag = push_flags; -+ __entry->hw_queue = sw_txhdr->txq->hwq->id; -+ __entry->txq_cred = sw_txhdr->txq->credits; -+ __entry->hwq_cred = sw_txhdr->txq->hwq->credits[BL_TXQ_POS_ID(sw_txhdr->txq)]; -+ -+#ifdef CONFIG_BL_FULLMAC -+ __entry->flag = sw_txhdr->desc.host.flags; -+#ifdef CONFIG_BL_SPLIT_TX_BUF -+#ifdef CONFIG_BL_AMSDUS_TX -+ if (sw_txhdr->amsdu.len) -+ __entry->len = sw_txhdr->amsdu.len; -+ else -+#endif /* CONFIG_BL_AMSDUS_TX */ -+ __entry->len = sw_txhdr->desc.host.packet_len[0]; -+#else -+ __entry->len = sw_txhdr->desc.host.packet_len; -+#endif /* CONFIG_BL_SPLIT_TX_BUF */ -+ -+#else /* CONFIG_BL_FULLMAC */ -+ __entry->flag = sw_txhdr->desc.umac.flags; -+ __entry->len = sw_txhdr->frame_len; -+ __entry->sn = sw_txhdr->sn; -+#endif /* CONFIG_BL_FULLMAC */ -+ __entry->mu_info = 0; -+ ), -+ -+#ifdef CONFIG_BL_FULLMAC -+ TP_printk("%s skb=%p (len=%d) hw_queue=%s cred_txq=%d cred_hwq=%d %s flag=%s %s%s", -+ __print_txq(__entry->tx_queue), __entry->skb, __entry->len, -+ __print_hwq(__entry->hw_queue), -+ __entry->txq_cred, __entry->hwq_cred, -+ __print_mu_info(__entry->mu_info), -+ __print_flags(__entry->flag, "|", -+ {TXU_CNTRL_RETRY, "RETRY"}, -+ {TXU_CNTRL_MORE_DATA, "MOREDATA"}, -+ {TXU_CNTRL_MGMT, "MGMT"}, -+ {TXU_CNTRL_MGMT_NO_CCK, "NO_CCK"}, -+ {TXU_CNTRL_MGMT_ROBUST, "ROBUST"}, -+ {TXU_CNTRL_AMSDU, "AMSDU"}, -+ {TXU_CNTRL_USE_4ADDR, "4ADDR"}, -+ {TXU_CNTRL_EOSP, "EOSP"}, -+ {TXU_CNTRL_MESH_FWD, "MESH_FWD"}, -+ {TXU_CNTRL_TDLS, "TDLS"}), -+ (__entry->push_flag & BL_PUSH_IMMEDIATE) ? "(IMMEDIATE)" : "", -+ (!(__entry->flag & TXU_CNTRL_RETRY) && -+ (__entry->push_flag & BL_PUSH_RETRY)) ? "(SW_RETRY)" : "") -+#else -+ TP_printk("%s skb=%p (len=%d) hw_queue=%s cred_txq=%d cred_hwq=%d %s flag=%x (%s) sn=%d", -+ __print_txq(__entry->tx_queue), __entry->skb, __entry->len, -+ __print_hwq(__entry->hw_queue), __entry->txq_cred, __entry->hwq_cred, -+ __print_mu_info(__entry->mu_info), -+ __entry->flag, -+ __print_flags(__entry->push_flag, "|", -+ {BL_PUSH_RETRY, "RETRY"}, -+ {BL_PUSH_IMMEDIATE, "IMMEDIATE"}), -+ __entry->sn) -+#endif /* CONFIG_BL_FULLMAC */ -+); -+ -+ -+TRACE_EVENT( -+ txq_queue_skb, -+ TP_PROTO(struct sk_buff *skb, struct bl_txq *txq, bool retry), -+ TP_ARGS(skb, txq, retry), -+ TP_STRUCT__entry( -+ __field(struct sk_buff *, skb) -+ __field(u16, txq_idx) -+ __field(s8, credit) -+ __field(u16, q_len) -+ __field(u16, q_len_retry) -+ __field(bool, retry) -+ ), -+ TP_fast_assign( -+ __entry->skb = skb; -+ __entry->txq_idx = txq->idx; -+ __entry->credit = txq->credits; -+ __entry->q_len = skb_queue_len(&txq->sk_list); -+ __entry->q_len_retry = txq->nb_retry; -+ __entry->retry = retry; -+ ), -+ -+ TP_printk("%s skb=%p retry=%d txq_credits=%d queue_len=%d (retry = %d)", -+ __print_txq(__entry->txq_idx), __entry->skb, __entry->retry, -+ __entry->credit, __entry->q_len, __entry->q_len_retry) -+); -+ -+ -+DECLARE_EVENT_CLASS( -+ idx_template, -+ TP_PROTO(u16 idx), -+ TP_ARGS(idx), -+ TP_STRUCT__entry( -+ __field(u16, idx) -+ ), -+ TP_fast_assign( -+ __entry->idx = idx; -+ ), -+ TP_printk("idx=%d", __entry->idx) -+); -+ -+ -+DEFINE_EVENT(idx_template, txq_vif_start, -+ TP_PROTO(u16 idx), -+ TP_ARGS(idx)); -+ -+DEFINE_EVENT(idx_template, txq_vif_stop, -+ TP_PROTO(u16 idx), -+ TP_ARGS(idx)); -+ -+TRACE_EVENT( -+ process_hw_queue, -+ TP_PROTO(struct bl_hwq *hwq), -+ TP_ARGS(hwq), -+ TP_STRUCT__entry( -+ __field(u16, hwq) -+ __array(u8, credits, CONFIG_USER_MAX) -+ ), -+ TP_fast_assign( -+ int i; -+ __entry->hwq = hwq->id; -+ for (i=0; i < CONFIG_USER_MAX; i ++) -+ __entry->credits[i] = hwq->credits[i]; -+ ), -+ TP_printk("hw_queue=%s hw_credits=%s", -+ __print_hwq(__entry->hwq), __print_hwq_cred(__entry->credits)) -+); -+ -+DECLARE_EVENT_CLASS( -+ sta_idx_template, -+ TP_PROTO(u16 idx), -+ TP_ARGS(idx), -+ TP_STRUCT__entry( -+ __field(u16, idx) -+ ), -+ TP_fast_assign( -+ __entry->idx = idx; -+ ), -+ TP_printk("%s", __print_sta(__entry->idx)) -+); -+ -+DEFINE_EVENT(sta_idx_template, txq_sta_start, -+ TP_PROTO(u16 idx), -+ TP_ARGS(idx)); -+ -+DEFINE_EVENT(sta_idx_template, txq_sta_stop, -+ TP_PROTO(u16 idx), -+ TP_ARGS(idx)); -+ -+#ifdef CONFIG_BL_FULLMAC -+ -+DEFINE_EVENT(sta_idx_template, ps_disable, -+ TP_PROTO(u16 idx), -+ TP_ARGS(idx)); -+ -+#endif /* CONFIG_BL_FULLMAC */ -+ -+TRACE_EVENT( -+ skb_confirm, -+ TP_PROTO(struct sk_buff *skb, struct bl_txq *txq, struct bl_hwq *hwq, -+#ifdef CONFIG_BL_FULLMAC -+ struct tx_cfm_tag *cfm -+#else -+ u8 cfm -+#endif -+ ), -+ -+ TP_ARGS(skb, txq, hwq, cfm), -+ -+ TP_STRUCT__entry( -+ __field(struct sk_buff *, skb) -+ __field(u16, txq_idx) -+ __field(u8, hw_queue) -+ __array(u8, hw_credit, CONFIG_USER_MAX) -+ __field(s8, sw_credit) -+ __field(s8, sw_credit_up) -+#ifdef CONFIG_BL_FULLMAC -+ __field(u8, ampdu_size) -+#ifdef CONFIG_BL_SPLIT_TX_BUF -+ __field(u16, amsdu) -+#endif /* CONFIG_BL_SPLIT_TX_BUF */ -+#endif /* CONFIG_BL_FULLMAC*/ -+ ), -+ -+ TP_fast_assign( -+ int i; -+ __entry->skb = skb; -+ __entry->txq_idx = txq->idx; -+ __entry->hw_queue = hwq->id; -+ for (i = 0 ; i < CONFIG_USER_MAX ; i++) -+ __entry->hw_credit[i] = hwq->credits[i]; -+ __entry->sw_credit = txq->credits; -+#if defined CONFIG_BL_FULLMAC -+ __entry->sw_credit_up = cfm->credits; -+ __entry->ampdu_size = cfm->ampdu_size; -+#ifdef CONFIG_BL_SPLIT_TX_BUF -+ __entry->amsdu = cfm->amsdu_size; -+#endif -+#else -+ __entry->sw_credit_up = cfm -+#endif /* CONFIG_BL_FULLMAC */ -+ ), -+ -+ TP_printk("%s skb=%p hw_queue=%s, hw_credits=%s, txq_credits=%d (+%d)" -+#ifdef CONFIG_BL_FULLMAC -+ " ampdu=%d" -+#ifdef CONFIG_BL_SPLIT_TX_BUF -+ " amsdu=%u" -+#endif -+#endif -+ , __print_txq(__entry->txq_idx), __entry->skb, -+ __print_hwq(__entry->hw_queue), -+ __print_hwq_cred(__entry->hw_credit), -+ __entry->sw_credit, __entry->sw_credit_up -+#ifdef CONFIG_BL_FULLMAC -+ , __entry->ampdu_size -+#ifdef CONFIG_BL_SPLIT_TX_BUF -+ , __entry->amsdu -+#endif -+#endif -+ ) -+); -+ -+TRACE_EVENT( -+ credit_update, -+ TP_PROTO(struct bl_txq *txq, s8_l cred_up), -+ -+ TP_ARGS(txq, cred_up), -+ -+ TP_STRUCT__entry( -+ __field(struct sk_buff *, skb) -+ __field(u16, txq_idx) -+ __field(s8, sw_credit) -+ __field(s8, sw_credit_up) -+ ), -+ -+ TP_fast_assign( -+ __entry->txq_idx = txq->idx; -+ __entry->sw_credit = txq->credits; -+ __entry->sw_credit_up = cred_up; -+ ), -+ -+ TP_printk("%s txq_credits=%d (%+d)", __print_txq(__entry->txq_idx), -+ __entry->sw_credit, __entry->sw_credit_up) -+) -+ -+#ifdef CONFIG_BL_FULLMAC -+ -+DECLARE_EVENT_CLASS( -+ ps_template, -+ TP_PROTO(struct bl_sta *sta), -+ TP_ARGS(sta), -+ TP_STRUCT__entry( -+ __field(u16, idx) -+ __field(u16, ready_ps) -+ __field(u16, sp_ps) -+ __field(u16, ready_uapsd) -+ __field(u16, sp_uapsd) -+ ), -+ TP_fast_assign( -+ __entry->idx = sta->sta_idx; -+ __entry->ready_ps = sta->ps.pkt_ready[LEGACY_PS_ID]; -+ __entry->sp_ps = sta->ps.sp_cnt[LEGACY_PS_ID]; -+ __entry->ready_uapsd = sta->ps.pkt_ready[UAPSD_ID]; -+ __entry->sp_uapsd = sta->ps.sp_cnt[UAPSD_ID]; -+ ), -+ -+ TP_printk("%s [PS] ready=%d sp=%d [UAPSD] ready=%d sp=%d", -+ __print_sta(__entry->idx), __entry->ready_ps, __entry->sp_ps, -+ __entry->ready_uapsd, __entry->sp_uapsd) -+); -+ -+DEFINE_EVENT(ps_template, ps_queue, -+ TP_PROTO(struct bl_sta *sta), -+ TP_ARGS(sta)); -+ -+DEFINE_EVENT(ps_template, ps_push, -+ TP_PROTO(struct bl_sta *sta), -+ TP_ARGS(sta)); -+ -+DEFINE_EVENT(ps_template, ps_enable, -+ TP_PROTO(struct bl_sta *sta), -+ TP_ARGS(sta)); -+ -+TRACE_EVENT( -+ ps_traffic_update, -+ TP_PROTO(u16 sta_idx, u8 traffic, bool uapsd), -+ -+ TP_ARGS(sta_idx, traffic, uapsd), -+ -+ TP_STRUCT__entry( -+ __field(u16, sta_idx) -+ __field(u8, traffic) -+ __field(bool, uapsd) -+ ), -+ -+ TP_fast_assign( -+ __entry->sta_idx = sta_idx; -+ __entry->traffic = traffic; -+ __entry->uapsd = uapsd; -+ ), -+ -+ TP_printk("%s %s%s traffic available ", __print_sta(__entry->sta_idx), -+ __entry->traffic ? "" : "no more ", -+ __entry->uapsd ? "U-APSD" : "legacy PS") -+); -+ -+TRACE_EVENT( -+ ps_traffic_req, -+ TP_PROTO(struct bl_sta *sta, u16 pkt_req, u8 ps_id), -+ TP_ARGS(sta, pkt_req, ps_id), -+ TP_STRUCT__entry( -+ __field(u16, idx) -+ __field(u16, pkt_req) -+ __field(u8, ps_id) -+ __field(u16, ready) -+ __field(u16, sp) -+ ), -+ TP_fast_assign( -+ __entry->idx = sta->sta_idx; -+ __entry->pkt_req = pkt_req; -+ __entry->ps_id = ps_id; -+ __entry->ready = sta->ps.pkt_ready[ps_id]; -+ __entry->sp = sta->ps.sp_cnt[ps_id]; -+ ), -+ -+ TP_printk("%s %s traffic request %d pkt (ready=%d, sp=%d)", -+ __print_sta(__entry->idx), -+ __entry->ps_id == UAPSD_ID ? "U-APSD" : "legacy PS" , -+ __entry->pkt_req, __entry->ready, __entry->sp) -+); -+ -+ -+#ifdef CONFIG_BL_AMSDUS_TX -+TRACE_EVENT( -+ amsdu_subframe, -+ TP_PROTO(struct bl_sw_txhdr *sw_txhdr), -+ TP_ARGS(sw_txhdr), -+ TP_STRUCT__entry( -+ __field(struct sk_buff *, skb) -+ __field(u16, txq_idx) -+ __field(u8, nb) -+ __field(u32, len) -+ ), -+ TP_fast_assign( -+ __entry->skb = sw_txhdr->skb; -+ __entry->nb = sw_txhdr->amsdu.nb; -+ __entry->len = sw_txhdr->amsdu.len; -+ __entry->txq_idx = sw_txhdr->txq->idx; -+ ), -+ -+ TP_printk("%s skb=%p %s nb_subframe=%d, len=%u", -+ __print_txq(__entry->txq_idx), __entry->skb, -+ (__entry->nb == 2) ? "Start new AMSDU" : "Add subframe", -+ __entry->nb, __entry->len) -+); -+#endif -+ -+#endif /* CONFIG_BL_FULLMAC */ -+ -+/***************************************************************************** -+ * TRACE functions for IPC message -+ ****************************************************************************/ -+#include "bl_strs.h" -+ -+DECLARE_EVENT_CLASS( -+ ipc_msg_template, -+ TP_PROTO(u16 id), -+ TP_ARGS(id), -+ TP_STRUCT__entry( -+ __field(u16, id) -+ ), -+ TP_fast_assign( -+ __entry->id = id; -+ ), -+ -+ TP_printk("%s (%d - %d)", BL_ID2STR(__entry->id), -+ MSG_T(__entry->id), MSG_I(__entry->id)) -+); -+ -+DEFINE_EVENT(ipc_msg_template, msg_send, -+ TP_PROTO(u16 id), -+ TP_ARGS(id)); -+ -+DEFINE_EVENT(ipc_msg_template, msg_recv, -+ TP_PROTO(u16 id), -+ TP_ARGS(id)); -+ -+ -+ -+#endif /* !defined(_BL_EVENTS_H) || defined(TRACE_HEADER_MULTI_READ) */ -+ -+#undef TRACE_INCLUDE_PATH -+#undef TRACE_INCLUDE_FILE -+#define TRACE_INCLUDE_PATH . -+#define TRACE_INCLUDE_FILE bl_events -+#include -diff -Naur /dev/null_irqs.c b/drivers/net/wireless/hflps170/bl_irqs.c ---- /dev/null_irqs.c 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_irqs.c 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,886 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file bl_irqs.c -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ ****************************************************************************** -+ */ -+#include -+#include -+#include -+#include -+ -+#include "bl_defs.h" -+#include "bl_cmds.h" -+#include "ipc_host.h" -+#include "bl_sdio.h" -+#include "bl_v7.h" -+ -+int bl_main_process(struct bl_hw *bl_hw); -+ -+ -+void bl_queue_main_work(struct bl_hw *bl_hw) -+{ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ spin_lock_irq(&bl_hw->main_proc_lock); -+ if (bl_hw->bl_processing) { -+ BL_DBG("bl_queue_main_work: set more_task_flag true\n"); -+ bl_hw->more_task_flag = true; -+ spin_unlock_irq(&bl_hw->main_proc_lock); -+ } else { -+ spin_unlock_irq(&bl_hw->main_proc_lock); -+ BL_DBG("bl_queue_main_work: schedule work\n"); -+ queue_work(bl_hw->workqueue, &bl_hw->main_work); -+ } -+} -+ -+ -+/* -+ * This function decodes a received packet. -+ * -+ * Based on the type, the packet is treated as either a data, or -+ * a command response, or an event, and the correct handler -+ * function is invoked. -+ */ -+static int bl_decode_rx_packet(struct bl_hw *bl_hw, struct sk_buff *skb, u32 upld_type, u32 hw_idx, u32 port) -+{ -+ unsigned long now = jiffies; -+ void *hostid = bl_hw->ipc_env->msga2e_hostid; -+ u32 pld_len = le16_to_cpu(*(__le16 *) (skb->data)); -+ struct bl_agg_reodr_msg *agg_reord_msg = NULL; -+ struct bl_agg_reord_pkt *reord_pkt = NULL; -+ struct bl_agg_reord_pkt *reord_pkt_tmp = NULL; -+ bool found = false; -+ u8 count = 0; -+ u16 sn_copy = 0; -+ -+ u16 pad_len = 0; -+ if(port !=0) { -+ pad_len = le16_to_cpu(*(__le16 *) (skb->data + 6)); -+ BL_DBG("pad_len=%d\n", pad_len); -+ } -+ -+ //skb_pull(skb, sizeof(struct sdio_hdr)); -+ skb_pull(skb, sizeof(struct sdio_hdr)+pad_len); -+ -+ switch (upld_type) { -+ case BL_TYPE_DATA: -+ BL_DBG("info: -------------------------------------------------------->>>Rx: Data packet\n"); -+ bl_rxdataind(bl_hw, skb); -+ bl_hw->stats.last_rx = now; -+ break; -+ -+ case BL_TYPE_ACK: -+ BL_DBG("info: -------------------------------------------------------->>>Rx: ACK packet\n"); -+ BL_DBG("Receive ACK: msg_cnt=%u, src_id=%u\n", bl_hw->ipc_env->msga2e_cnt, ((*(u8 *)(skb->data)) & 0xFF)); -+ /*just msg_cnt is matched with src_id or not*/ -+ ASSERT_ERR(hostid); -+ ASSERT_ERR(bl_hw->ipc_env->msga2e_cnt == ((*(u8 *)(skb->data)) & 0xFF)); -+ -+ bl_hw->ipc_env->msga2e_hostid = NULL; -+ bl_hw->ipc_env->msga2e_cnt++; -+ bl_hw->ipc_env->cb.recv_msgack_ind(bl_hw, hostid); -+ dev_kfree_skb_any(skb); -+ break; -+ -+ case BL_TYPE_MSG: -+ BL_DBG("info: -------------------------------------------------------->>>Rx: MSG packet\n"); -+ bl_hw->ipc_env->cb.recv_msg_ind(bl_hw, (void *)(skb->data)); -+ dev_kfree_skb_any(skb); -+ break; -+ -+ case BL_TYPE_DBG_DUMP_START: -+ BL_DBG("info: -------------------------------------------------------->>>Rx: DBG_DUMP_START packet\n"); -+ if(!(bl_hw->dbg_dump_start)) { -+ BL_DBG("dbg_dump start now...\n"); -+ bl_hw->dbg_dump_start = true; -+ bl_hw->la_buf_idx = 0; -+ } else { -+ BL_DBG("dbg_dump has not completed!\n"); -+ } -+ dev_kfree_skb_any(skb); -+ break; -+ -+ case BL_TYPE_DBG_DUMP_END: -+ BL_DBG("info: -------------------------------------------------------->>>Rx: DBG_DUMP_END packet\n"); -+ bl_hw->dbg_dump_start = false; -+ BL_DBG("%s\n", (char *)(bl_hw->dbginfo.buf->dbg_info.error)); -+ //TODO: wake app to cat mactrace -+ dev_kfree_skb_any(skb); -+ break; -+ -+ case BL_TYPE_DBG_LA_TRACE: -+ BL_DBG("info: -------------------------------------------------------->>>Rx: DBG_LA_TRACE packet\n"); -+ memcpy(&(bl_hw->dbginfo.buf->la_mem[bl_hw->la_buf_idx]), skb->data, pld_len); -+ bl_hw->la_buf_idx = bl_hw->la_buf_idx + pld_len; -+ dev_kfree_skb_any(skb); -+ break; -+ -+ case BL_TYPE_DBG_RBD_DESC: -+ BL_DBG("info: -------------------------------------------------------->>>Rx: DBG_RBD_DESC packet\n"); -+ dev_kfree_skb_any(skb); -+ break; -+ -+ case BL_TYPE_DBG_RHD_DESC: -+ BL_DBG("info: -------------------------------------------------------->>>Rx: DBG_RHD_DESC packet\n"); -+ dev_kfree_skb_any(skb); -+ break; -+ -+ case BL_TYPE_DBG_TX_DESC: -+ BL_DBG("info: -------------------------------------------------------->>>Rx: DBG_TX_DESC packet\n"); -+ dev_kfree_skb_any(skb); -+ break; -+ -+ case BL_TYPE_DUMP_INFO: -+ BL_DBG("info: -------------------------------------------------------->>>Rx: DUMP_INFO packet\n"); -+ memcpy(&(bl_hw->dbginfo.buf->dbg_info), skb->data, sizeof(struct dbg_debug_info_tag)); -+ dev_kfree_skb_any(skb); -+ break; -+ -+ case BL_TYPE_TXCFM: -+ BL_DBG("info: -------------------------------------------------------->>>Rx:TXCFM packet\n"); -+ { -+ u32 i; -+ u32 count; -+ struct bl_hw_txhdr hw_hdr; -+ struct bl_txq *txq = NULL; -+ -+ /* 1. get cfm count from skb->data */ -+ memcpy(&hw_hdr, (struct bl_hw_txhdr *)(skb->data), sizeof(struct bl_hw_txhdr)); -+ count = hw_hdr.cfm.count; -+ BL_DBG("cfm.sn=%u, cfm.timestamp=%u, cfm.count=%u, cfm.credits=%d\n", hw_hdr.cfm.sn, hw_hdr.cfm.timestamp, hw_hdr.cfm.count, hw_hdr.cfm.credits); -+ -+ /* 2. handle cfm successively */ -+ for(i = 0; i < count; i++) { -+ ipc_host_tx_cfm_handler(bl_hw->ipc_env, hw_idx, 0, &hw_hdr, &txq); -+ if(!txq) -+ goto TXCFM_EXIT; -+ if((hw_hdr.cfm.status.retry_required || hw_hdr.cfm.status.sw_retry_required) && (count == 1)) { -+ BL_DBG("Retry packet received, so we just exit\n"); -+ goto RETRY_PACKET; -+ } -+ } -+ -+ //BL_DBG("get txq from cfm_handler: txq->idx=%d\n", txq->idx); -+ -+ /* 3. update txq->credits */ -+ if (txq->idx != TXQ_INACTIVE) { -+ if (hw_hdr.cfm.credits) { -+ BL_DBG("orign txq->idx=%d, txq->status=0x%x, txq->credits=%d\n", txq->idx, txq->status, txq->credits); -+ txq->credits += hw_hdr.cfm.credits; -+ BL_DBG("after add credits: hw_hdr.cfm.credits=%d, txq->idx=%d, txq->status=0x%x, txq->credits=%d\n", -+ hw_hdr.cfm.credits, txq->idx, txq->status, txq->credits); -+ -+ /* spin_lock_bh(&bl_hw->txq_lock); -+ if (txq->credits <= 0) -+ bl_txq_stop(txq, BL_TXQ_STOP_FULL); -+ else if (txq->credits > 0) -+ bl_txq_start(txq, BL_TXQ_STOP_FULL); -+ spin_unlock_bh(&bl_hw->txq_lock);*/ -+ } -+ -+ /* continue service period */ -+ if (unlikely(txq->push_limit && !bl_txq_is_full(txq))) { -+ bl_txq_add_to_hw_list(txq); -+ } -+ } -+ -+ /* 4. update ampdu_size */ -+ if (hw_hdr.cfm.ampdu_size && -+ hw_hdr.cfm.ampdu_size < IEEE80211_MAX_AMPDU_BUF) -+ bl_hw->stats.ampdus_tx[hw_hdr.cfm.ampdu_size - 1]++; -+ -+ /* 5. update amsdu_size */ -+ #ifdef CONFIG_BL_AMSDUS_TX -+ txq->amsdu_len = hw_hdr.cfm.amsdu_size; -+ #endif -+ -+ } -+ -+ bl_hw->stats.last_tx = now; -+TXCFM_EXIT: -+RETRY_PACKET: -+ dev_kfree_skb_any(skb); -+ break; -+ -+ case BL_TYPE_AGG_REORD_MSG: -+ BL_DBG("info: -------------------------------------------------------->>>Rx:AGG REORDER MSG packet\n"); -+ agg_reord_msg = (struct bl_agg_reodr_msg *)(skb->data); -+ -+ sn_copy = agg_reord_msg->sn; -+ -+ BL_DBG("AGG_REORD_MSG: sn=%u, num=%u, sta_idx=%d, tid=%d, status=%d\n", -+ agg_reord_msg->sn, agg_reord_msg->num, agg_reord_msg->sta_idx, agg_reord_msg->tid, agg_reord_msg->status); -+ -+RE_THOUGH_LIST: -+ /*1. get the skb according sn*/ -+ if (!list_empty(&bl_hw->reorder_list[agg_reord_msg->sta_idx*NX_NB_TID_PER_STA + agg_reord_msg->tid])) { -+ list_for_each_entry_safe(reord_pkt, reord_pkt_tmp, &bl_hw->reorder_list[agg_reord_msg->sta_idx*NX_NB_TID_PER_STA + agg_reord_msg->tid], list) { -+ BL_DBG("reord_pkt->sn=%u\n", reord_pkt->sn); -+ if((reord_pkt->sn == agg_reord_msg->sn) && (count < agg_reord_msg->num)) { -+ if(!found) -+ found = true; -+ -+ BL_DBG("found pkt: sn=%u, next_sn=%u, count(%u) of num(%u)\n", -+ agg_reord_msg->sn, (agg_reord_msg->sn + 1) % AGG_REORD_MSG_MAX_NUM, count, agg_reord_msg->num); -+ /*2. modify the status in skb according agg_reodr_msg->status*/ -+ memcpy(reord_pkt->skb->data, &(agg_reord_msg->status), 1); -+ /*3. call bl_rxdataind to handle the skb*/ -+ bl_rxdataind(bl_hw, reord_pkt->skb); -+ /*4. delete this agg reodr pkt node*/ -+ list_del(&reord_pkt->list); -+ kmem_cache_free(bl_hw->agg_reodr_pkt_cache, reord_pkt); -+ /*5. find next pkt, if sn == 4095, next sn will change to 0*/ -+ agg_reord_msg->sn = (agg_reord_msg->sn + 1) % AGG_REORD_MSG_MAX_NUM; -+ count++; -+ } -+ -+ BL_DBG("count=%u, agg_reord_msg->num=%u\n", count, agg_reord_msg->num); -+ -+ if((agg_reord_msg->sn == 0) && (count < agg_reord_msg->num)) { -+ BL_DBG("sn=0, re-though the list\n"); -+ goto RE_THOUGH_LIST; -+ } -+ -+ if(count == agg_reord_msg->num) { -+ count = 0; -+ agg_reord_msg->sn = 0; -+ break; -+ } -+ } -+ if(!found) -+ BL_DBG("Not found the packet, sn=%u\n", agg_reord_msg->sn); -+ } else { -+ BL_DBG("Oh! give me reodr msg, but no packet need to handle?\n"); -+ } -+ -+ dev_kfree_skb_any(skb); -+ break; -+ -+ case BL_TYPE_DBG: -+ BL_DBG("info: -------------------------------------------------------->>>Rx:DBG MSG packet\n"); -+ *(skb->data+pld_len) = '\0'; -+ BL_DBG("fw: %s", (char *)(skb->data)); -+ dev_kfree_skb_any(skb); -+ break; -+ -+ case BL_TYPE_TX_STOP: -+ BL_DBG("info: -------------------------------------------------------->>>Rx:TX_STOP packet\n"); -+ bl_hw->recovery_flag = true; -+ dev_kfree_skb_any(skb); -+ break; -+ -+ case BL_TYPE_TX_RESUME: -+ BL_DBG("info: -------------------------------------------------------->>>Rx:TX_RESUME packet\n"); -+ bl_hw->recovery_flag = false; -+ dev_kfree_skb_any(skb); -+ break; -+ -+ default: -+ BL_DBG("info: -------------------------------------------------------->>>Rx:UNKNOWN[%#x] packet\n", upld_type); -+ dev_kfree_skb_any(skb); -+ break; -+ } -+ -+ return 0; -+} -+ -+/* -+ * This function receive data from the sdio device. -+ */ -+static int bl_card_to_host(struct bl_hw *bl_hw, u32 *type, u32 *hw_idx, u8 *buffer, u32 npayload, u32 ioport) -+{ -+ int ret; -+ u32 nb; -+ int reserved; -+ u8 rd_bitmap_l = 0; -+ u8 rd_bitmap_u = 0; -+ u32 bitmap; -+ u32 bitmap_cur; -+ u32 pre_rdport = 0; -+ int count = 0; -+ struct bl_device *bl_device; -+ struct bl_plat *bl_plat; -+ -+ bl_plat = bl_hw->plat; -+ bl_device = (struct bl_device *)bl_plat->priv; -+ -+ if (!buffer) { -+ printk("%s: buffer is NULL\n", __func__); -+ return -1; -+ } -+ -+ ret = bl_read_data_sync(bl_hw, buffer, npayload, ioport); -+ -+ if (ret) { -+ printk("%s: read iomem failed: %d\n", __func__, ret); -+ return -1; -+ } else { -+ bl_read_reg(bl_hw, bl_device->reg->rd_bitmap_l, &rd_bitmap_l); -+ bl_read_reg(bl_hw, bl_device->reg->rd_bitmap_u, &rd_bitmap_u); -+ bitmap = rd_bitmap_l; -+ bitmap |= rd_bitmap_u << 8; -+ -+ bitmap_cur = bitmap; -+ -+ while(bitmap) { -+ bitmap = bitmap & (bitmap-1); -+ count++; -+ } -+ -+ pre_rdport = ioport - bl_hw->plat->io_port; -+ BL_DBG("read success: bitmap=0x%x, pre_rdport=%d, 1<1)) { -+ BL_DBG("read success, but port bitmap was not clear\n"); -+ } -+ } -+ -+ *type = le16_to_cpu(*(__le16 *) (buffer + 2)); -+ nb = le16_to_cpu(*(__le16 *) (buffer)); -+ *hw_idx = le16_to_cpu(*(__le16 *) (buffer + 4)); -+ reserved = le16_to_cpu(*(__le16 *) (buffer + 6)); -+ -+ return ret; -+} -+ -+ -+/* -+ * This function transfers received packets from card to driver, performing -+ * aggregation if required. -+ * -+ * For data received on control port, or if aggregation is disabled, the -+ * received buffers are uploaded as separate packets. However, if aggregation -+ * is enabled and required, the buffers are copied onto an aggregation buffer, -+ * provided there is space left, processed and finally uploaded. -+ */ -+static int bl_rx_process(struct bl_hw *bl_hw, struct sk_buff *skb, u32 port) -+{ -+ u32 pkt_type; -+ u32 hw_idx; -+ u16 *buf; -+ -+ if (bl_card_to_host(bl_hw, &pkt_type, &hw_idx, skb->data, skb->len, bl_hw->plat->io_port + port)) -+ goto error; -+ -+ buf = (u16 *)(skb->data); -+ BL_DBG("buf[0]=%u, buf[1]=%u, buf[2]=%u, buf[3]=%u, bl_hw->msg_idx=%u\n", buf[0], buf[1], buf[2], buf[3], bl_hw->msg_idx); -+ if(port == 0) { -+ if (bl_hw->msg_idx == buf[3]) { -+ BL_DBG("receive msg twice, msg_idx=%u\n", bl_hw->msg_idx); -+ return 0; -+ } -+ } -+ -+ //update msg idx -+ bl_hw->msg_idx = buf[3]; -+ -+ bl_decode_rx_packet(bl_hw, skb, pkt_type, hw_idx, port); -+ -+ return 0; -+ -+error: -+ dev_kfree_skb_any(skb); -+ return -1; -+} -+ -+static void bl_get_interrupt_status(struct bl_hw *bl_hw) -+{ -+ struct bl_device *bl_device; -+ struct bl_plat *bl_plat; -+ u8 sdio_ireg; -+ -+ bl_plat = bl_hw->plat; -+ bl_device = (struct bl_device *)bl_plat->priv; -+ -+ if(bl_read_data_sync_claim0(bl_hw, bl_plat->mp_regs, bl_device->reg->max_mp_regs, REG_PORT | BL_SDIO_BYTE_MODE_MASK)) { -+ printk("read mp_regs failed\n"); -+ return; -+ } -+ -+ sdio_ireg = bl_plat->mp_regs[bl_device->reg->host_int_status_reg]; -+ -+ if(sdio_ireg) { -+ BL_DBG(">>>bl_get_interrupt_status, sdio_ireg=0x%x\n", sdio_ireg); -+ spin_lock(&bl_hw->int_lock); -+ bl_hw->int_status |= sdio_ireg; -+ spin_unlock(&bl_hw->int_lock); -+ } -+} -+ -+/** -+ * bl_irq_hdlr - IRQ handler -+ * -+ * Handler registerd by the platform driver -+ */ -+void bl_irq_hdlr(struct sdio_func *func) -+{ -+ struct bl_hw *bl_hw; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ bl_hw = sdio_get_drvdata(func); -+ if(!bl_hw) { -+ printk("get bl_hw failed!\n"); -+ return; -+ } -+ -+ bl_get_interrupt_status(bl_hw); -+ -+#if 0 -+ /*irq/irq top handler call spin_lock, no need to disable irq -+ *but, workqueue and user thread need disable irq -+ */ -+ spin_lock_irq(&bl_hw->main_proc_lock); -+ if (bl_hw->bl_processing) { -+ BL_DBG("bl_irq_hdlr: set more_task_flag true\n"); -+ bl_hw->more_task_flag = true; -+ spin_unlock_irq(&bl_hw->main_proc_lock); -+ } else { -+ spin_unlock_irq(&bl_hw->main_proc_lock); -+ BL_DBG("bl_irq_hdlr: schedule work\n"); -+ queue_work(bl_hw->workqueue, &bl_hw->main_work); -+ } -+ //bl_queue_main_work(bl_hw); -+#endif -+ -+ bl_main_process(bl_hw); -+} -+ -+static int bl_pending_msg_hdl(struct bl_hw *bl_hw) -+{ -+ struct bl_cmd *cur = NULL; -+ u32 count = 0; -+ u8 wr_bitmap_l = 0; -+ struct bl_cmd *hostid = (struct bl_cmd *)(bl_hw->ipc_env->msga2e_hostid); -+ -+ struct bl_device *device = (struct bl_device *)bl_hw->plat->priv; -+ -+ list_for_each_entry(cur, &bl_hw->cmd_mgr.cmds, list) { -+ cmd_dump(cur); -+ BL_DBG("cur->tkn=%d, hostid->tkn=%d, queue_sz=%d, max_queue_sz=%d\n", cur->tkn, hostid->tkn, bl_hw->cmd_mgr.queue_sz, bl_hw->cmd_mgr.max_queue_sz); -+ if(cur->tkn == hostid->tkn) { -+ //bl_read_reg(bl_hw, device->reg->wr_bitmap_l, &wr_bitmap_l); -+ wr_bitmap_l = bl_hw->plat->mp_regs[device->reg->wr_bitmap_l]; -+ while((!(wr_bitmap_l & CTRL_PORT_MASK)) && count < 200){ -+ msleep(5); -+ count++; -+ bl_read_reg(bl_hw, device->reg->wr_bitmap_l, &wr_bitmap_l); -+ BL_DBG("wait for cmd port ready!\n"); -+ }; -+ -+ if(count >=200){ -+ BL_DBG("wait for cmd port timeout!\n"); -+ kfree(cur->a2e_msg); -+ return -1; -+ } -+ if(cur->flags |BL_CMD_FLAG_WAIT_PUSH) -+ cur->flags &= ~BL_CMD_FLAG_WAIT_PUSH; -+ bl_write_data_sync(bl_hw, (u8 *)(cur->a2e_msg), ((sizeof(struct lmac_msg) + cur->a2e_msg->param_len + 3)/4) *4, bl_hw->plat->io_port + CTRL_PORT); -+ kfree(cur->a2e_msg); -+ break; -+ } -+ } -+ -+ /*we are in bootom handler, so we just use spin_lock*/ -+ spin_lock(&bl_hw->cmd_lock); -+ bl_hw->cmd_sent = false; -+ spin_unlock(&bl_hw->cmd_lock); -+ -+ return 0; -+ -+} -+ -+void main_wq_hdlr(struct work_struct *work) -+{ -+ struct bl_hw *bl_hw = container_of(work, struct bl_hw, main_work); -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ bl_main_process(bl_hw); -+} -+ -+static int bl_upload_hdl(struct bl_hw *bl_hw) -+{ -+ u8 rd_bitmap_l = 0; -+ u8 rd_bitmap_u = 0; -+ u32 len_reg_l = 0; -+ u32 len_reg_u = 0; -+ u32 bitmap; -+ u32 rx_len; -+ u32 port = CTRL_PORT; -+ int ret = 0; -+ struct sk_buff *skb; -+ u8 cr; -+ u32 pind; -+ u8 *curr_ptr; -+ u32 pkt_len; -+ u32 pkt_type; -+ u32 hw_idx; -+ u32 reserved; -+ u32 cmd53_port = 0; -+ int avail_port_num = 0; -+ u32 rd_bitmap = 0; -+ bool rd_twice = false; -+// struct timespec ts; -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,20,0)) -+ struct timespec64 ts; -+ ktime_get_boottime_ts64(&ts); -+ return ((u64)ts.tv_sec*1000000) + ts.tv_nsec / 1000; -+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) -+ struct timespec ts; -+ get_monotonic_boottime(&ts); -+ return ((u64)ts.tv_sec*1000000) + ts.tv_nsec / 1000; -+#else -+ struct timeval tv; -+ do_gettimeofday(&tv); -+ return ((u64)tv.tv_sec*1000000) + tv.tv_usec; -+#endif -+ struct rtc_time tm; -+ long start; -+ long end; -+ -+ struct bl_plat *bl_plat = bl_hw->plat; -+ struct bl_device *bl_device = (struct bl_device *)bl_plat->priv; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+#define TEST_REBOOT_TIME -+ -+#ifdef TEST_REBOOT_TIME -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) -+ ktime_get_real_ts64(&ts); -+ rtc_time64_to_tm(ts.tv_sec,&tm); -+#else -+ getnstimeofday(&ts); -+ rtc_time_to_tm(ts.tv_sec,&tm); -+#endif -+ start = ts.tv_nsec/1000; -+ //printk("[ST]:%d-%d-%d %d:%d:%d %ld\n", tm.tm_year+1900,tm.tm_mon, tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec, start); -+#endif -+ -+ bl_hw->mpa_rx_data.pkt_cnt = 0; -+ -+ rd_bitmap_l = bl_plat->mp_regs[bl_device->reg->rd_bitmap_l]; -+ rd_bitmap_u = bl_plat->mp_regs[bl_device->reg->rd_bitmap_u]; -+ -+ bitmap = rd_bitmap_l; -+ bitmap |= rd_bitmap_u << 8; -+ -+ bl_plat->mp_rd_bitmap = bitmap; -+ rd_bitmap = bitmap; -+ -+ BL_DBG("int: UPLD: rd_bitmap=0x%x, lost_int_flag=%d\n", bl_plat->mp_rd_bitmap, bl_hw->lost_int_flag); -+ -+ rd_bitmap &= 0xFFFFFFFE; -+ while(rd_bitmap) { -+ rd_bitmap = rd_bitmap & (rd_bitmap-1); -+ avail_port_num++; -+ } -+ -+ //printk("rd_bitmap=0x%x, available rd port nums=%d,------------------------------- ", bl_plat->mp_rd_bitmap, avail_port_num); -+ if(avail_port_num > 7) { -+ //printk("will read twice\n"); -+ rd_twice = true; -+ } else { -+ //printk("\n"); -+ } -+ -+TWICE: -+ -+ while(true) { -+ ret = bl_get_rd_port(bl_hw, &port); -+ if (ret) { -+ //printk("info: no more rd_port available\n"); -+ break; -+ } -+ -+ -+ len_reg_l = bl_plat->mp_regs[bl_device->reg->rd_len_p0_l + (port << 1)]; -+ len_reg_u = bl_plat->mp_regs[bl_device->reg->rd_len_p0_u + (port << 1)]; -+ rx_len = (len_reg_u << 8) + len_reg_l; -+ -+ //printk("rd_port: port=0x%x, rx_len=%d\n", port, rx_len); -+ -+ if (rx_len < sizeof(struct sdio_hdr)) { -+ printk("Invaild rx_len\n"); -+ return -1; -+ } -+ -+ rx_len = ((rx_len + BL_SDIO_BLOCK_SIZE - 1)/BL_SDIO_BLOCK_SIZE) * BL_SDIO_BLOCK_SIZE; -+ -+ -+ BL_DBG("after round: rx_len=%d, port=%d\n", rx_len, port); -+ -+ skb = dev_alloc_skb(rx_len); -+ if (!skb) { -+ printk("%s: failed to alloc skb", __func__); -+ return -1; -+ } else { -+ //printk("alloc skb: %p\n", skb); -+ } -+ -+ if(port == CTRL_PORT) { -+ /*port0 is not aggr port, ignore */ -+ //cmd53_port = (bl_hw->plat->io_port | BL_SDIO_MPA_ADDR_BASE | -+ // (1 << 4)) + 0; -+ //printk("port0: cmd53_port=0x%08x, rx_len=%d\n", cmd53_port, rx_len); -+ -+ //ret = bl_read_data_sync(bl_hw, skb->data, rx_len, cmd53_port); -+ ret = bl_read_data_sync(bl_hw, skb->data, rx_len, bl_hw->plat->io_port + port); -+ if(ret) { -+ printk("read data failed\n"); -+ return -1; -+ } -+ -+ pkt_len = le16_to_cpu(*(__le16 *) (skb->data + 0)); -+ pkt_type = le16_to_cpu(*(__le16 *) (skb->data + 2)); -+ hw_idx = le16_to_cpu(*(__le16 *) (skb->data + 4)); -+ reserved = le16_to_cpu(*(__le16 *) (skb->data + 6)); -+ skb_put(skb, rx_len); -+ if(bl_decode_rx_packet(bl_hw, skb, pkt_type, hw_idx, port)) { -+ printk("bl_rx_process error\n"); -+ goto term_cmd; -+ } -+ #ifdef TEST_REBOOT_TIME -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) -+ ktime_get_real_ts64(&ts); -+ rtc_time64_to_tm(ts.tv_sec,&tm); -+#else -+ getnstimeofday(&ts); -+ rtc_time_to_tm(ts.tv_sec,&tm); -+#endif -+ end = ts.tv_nsec/1000; -+ if(end-start >10000) -+ printk("Rx Msg over 10ms: start=%ld, end=%ld\n", start, end); -+ //printk("[E0]:%d-%d-%d %d:%d:%d %0.4d\n",tm.tm_year+1900,tm.tm_mon, tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec, txc.time.tv_usec); -+ #endif -+ -+ continue; -+ } -+ -+ //printk("start to record multi port: port=0x%x\n", port); -+ -+ bl_hw->mpa_rx_data.buf_len += rx_len; -+ if(!bl_hw->mpa_rx_data.pkt_cnt) -+ bl_hw->mpa_rx_data.start_port = port; -+ -+ if(bl_hw->mpa_rx_data.start_port <= port) { -+ bl_hw->mpa_rx_data.ports |= (1 << bl_hw->mpa_rx_data.pkt_cnt); -+ } else { -+ bl_hw->mpa_rx_data.ports |= (1 << (bl_hw->mpa_rx_data.pkt_cnt + 1)); -+ } -+ -+ bl_hw->mpa_rx_data.buf_arr[bl_hw->mpa_rx_data.pkt_cnt] = skb; -+ bl_hw->mpa_rx_data.len_arr[bl_hw->mpa_rx_data.pkt_cnt] = rx_len; -+ bl_hw->mpa_rx_data.mp_rd_port[bl_hw->mpa_rx_data.pkt_cnt] = port; -+ bl_hw->mpa_rx_data.pkt_cnt++; -+ if(bl_hw->mpa_rx_data.pkt_cnt==7 && rd_twice == true) { -+ //printk("pkt_cnts > 7, other port will read next time, ports=0x%x, cnt=%d\n", bl_hw->mpa_rx_data.ports, bl_hw->mpa_rx_data.pkt_cnt); -+ break; -+ } -+ } -+ -+ if(bl_hw->mpa_rx_data.pkt_cnt != 0) { -+ -+ //printk("ports=0x%x, pkt_cnt=%d\n", bl_hw->mpa_rx_data.ports, bl_hw->mpa_rx_data.pkt_cnt); -+ -+ memset(bl_hw->mpa_rx_data.buf, 0, BL_RX_DATA_BUF_SIZE_16K); -+ -+ /*recv packet*/ -+ cmd53_port = (bl_hw->plat->io_port | BL_SDIO_MPA_ADDR_BASE | -+ (bl_hw->mpa_rx_data.ports << 4)) + bl_hw->mpa_rx_data.start_port; -+ -+ //printk("mpa_buf_len=%d, cmd53_port=0x%08x, mpa_rx_data.buf=%p\n", bl_hw->mpa_rx_data.buf_len, cmd53_port, bl_hw->mpa_rx_data.buf); -+ -+ ret = bl_read_data_sync(bl_hw, bl_hw->mpa_rx_data.buf, bl_hw->mpa_rx_data.buf_len, cmd53_port); -+ if(ret) -+ printk("bl_read_data_sync failed, ret=%d\n", ret); -+ -+ curr_ptr = bl_hw->mpa_rx_data.buf; -+ -+ //printk("mpa_rx_data.buf: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x \n", -+ // curr_ptr[0], -+ // curr_ptr[1], -+ // curr_ptr[2], -+ // curr_ptr[3], -+ // curr_ptr[4], -+ // curr_ptr[5], -+ // curr_ptr[6], -+ // curr_ptr[7] -+ // ); -+ -+ for(pind = 0; pind < bl_hw->mpa_rx_data.pkt_cnt; pind++) { -+ -+ memcpy((u8 *)((struct sk_buff *)(bl_hw->mpa_rx_data.buf_arr[pind])->data), curr_ptr, bl_hw->mpa_rx_data.len_arr[pind]); -+ -+ pkt_len = le16_to_cpu(*(__le16 *) (((bl_hw->mpa_rx_data.buf_arr[pind])->data + 0))); -+ pkt_type = le16_to_cpu(*(__le16 *) (((bl_hw->mpa_rx_data.buf_arr[pind])->data + 2))); -+ hw_idx = le16_to_cpu(*(__le16 *) (((bl_hw->mpa_rx_data.buf_arr[pind])->data + 4))); -+ reserved = le16_to_cpu(*(__le16 *) (((bl_hw->mpa_rx_data.buf_arr[pind])->data + 6))); -+ -+ BL_DBG("pkt_len=%d, pkt_type=%d, hw_idx=%d, reserved=%d\n", pkt_len, pkt_type, hw_idx, reserved); -+ -+ bl_hw->msg_idx = reserved; -+ skb_put(bl_hw->mpa_rx_data.buf_arr[pind], pkt_len + sizeof(struct sdio_hdr) + reserved); -+ if(bl_decode_rx_packet(bl_hw, (struct sk_buff *)(bl_hw->mpa_rx_data.buf_arr[pind]), pkt_type, hw_idx, bl_hw->mpa_rx_data.mp_rd_port[pind])) { -+ printk("bl_rx_process error\n"); -+ goto term_cmd; -+ } -+ -+ curr_ptr += bl_hw->mpa_rx_data.len_arr[pind]; -+ } -+ -+ //printk("clear pkt_cnt and ports, buf_len\n"); -+ bl_hw->mpa_rx_data.pkt_cnt = 0; -+ bl_hw->mpa_rx_data.ports = 0; -+ bl_hw->mpa_rx_data.buf_len = 0; -+ #ifdef TEST_REBOOT_TIME -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) -+ ktime_get_real_ts64(&ts); -+ rtc_time64_to_tm(ts.tv_sec,&tm); -+#else -+ getnstimeofday(&ts); -+ rtc_time_to_tm(ts.tv_sec,&tm); -+#endif -+ end = ts.tv_nsec/1000; -+ if(end-start >10000) -+ printk("Rx Data over 10ms: start=%ld, end=%ld\n", start, end); -+ //printk("[ED]:%d-%d-%d %d:%d:%d %0.4d\n",tm.tm_year+1900,tm.tm_mon, tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec, txc.time.tv_usec); -+ #endif -+ } -+ -+ if(rd_twice == true) { -+ //printk("start read twice\n"); -+ rd_twice = false; -+ goto TWICE; -+ } -+ -+ -+ return 0; -+ -+ term_cmd: -+ /* terminate cmd */ -+ if (bl_read_reg(bl_hw, CONFIGURATION_REG, &cr)) -+ printk("read CFG reg failed\n"); -+ else -+ printk("info: CFG reg val = %d\n", cr); -+ -+ if (bl_write_reg(bl_hw, CONFIGURATION_REG, (cr | 0x04))) -+ printk("write CFG reg failed\n"); -+ else -+ printk("info: write success\n"); -+ -+ if (bl_read_reg(bl_hw, CONFIGURATION_REG, &cr)) -+ printk("read CFG reg failed\n"); -+ else -+ printk("info: CFG reg val =%x\n", cr); -+ -+ return -1; -+} -+ -+static int bl_download_hdl(struct bl_hw *bl_hw) -+{ -+ u8 wr_bitmap_l = 0; -+ u8 wr_bitmap_u = 0; -+ u32 bitmap; -+ -+ struct bl_plat *bl_plat = bl_hw->plat; -+ struct bl_device *bl_device = (struct bl_device *)bl_plat->priv; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ //bl_read_reg(bl_hw, bl_device->reg->wr_bitmap_l, &wr_bitmap_l); -+ //bl_read_reg(bl_hw, bl_device->reg->wr_bitmap_u, &wr_bitmap_u); -+ //bitmap = wr_bitmap_l; -+ //bitmap |= wr_bitmap_u << 8; -+ -+ wr_bitmap_l = bl_plat->mp_regs[bl_device->reg->wr_bitmap_l]; -+ wr_bitmap_u = bl_plat->mp_regs[bl_device->reg->wr_bitmap_u]; -+ bitmap = wr_bitmap_l; -+ bitmap |= wr_bitmap_u << 8; -+ -+ bl_plat->mp_wr_bitmap = bitmap; -+ -+ BL_DBG("int: DNLD: wr_bitmap=0x%x\n", bl_plat->mp_wr_bitmap); -+ -+ return 0; -+} -+ -+int bl_main_process(struct bl_hw *bl_hw) -+{ -+ u8 sdio_ireg; -+ int ret = 0; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /*we know irq is enable, so here use spin_lock_irq*/ -+ spin_lock_irq(&bl_hw->main_proc_lock); -+ /* Check if already processing */ -+ if (bl_hw->bl_processing) { -+ BL_DBG("bl_main_process: more_task_flag = true\n"); -+ bl_hw->more_task_flag = true; -+ spin_unlock_irq(&bl_hw->main_proc_lock); -+ goto exit_main_proc; -+ } else { -+ bl_hw->bl_processing = true; -+ spin_unlock_irq(&bl_hw->main_proc_lock); -+ } -+ -+ bl_hw->lost_int_flag = 0; -+ -+process_start: -+ -+ spin_lock_irq(&bl_hw->int_lock); -+ sdio_ireg = bl_hw->int_status; -+ bl_hw->int_status = 0; -+ spin_unlock_irq(&bl_hw->int_lock); -+ -+ /* 1.handle the msg */ -+ if (!list_empty(&bl_hw->cmd_mgr.cmds)) { -+ if(bl_hw->cmd_sent) { -+ ret = bl_pending_msg_hdl(bl_hw); -+ if(ret) { -+ printk("send msg failed, ret=%d\n", ret); -+ return ret; -+ } -+ } -+ } -+ -+ /* 2.handle recv data */ -+ if (sdio_ireg & UP_LD_HOST_INT_STATUS) { -+ ret = bl_upload_hdl(bl_hw); -+ if(ret || (bl_hw->resend)) -+ goto exit_main_proc; -+ } -+ -+ /* 3. if wr port ready, see if data need to transmit */ -+ if (sdio_ireg & DN_LD_HOST_INT_STATUS) { -+ ret = bl_download_hdl(bl_hw); -+ } -+ -+ /* 4. handle tx data */ -+ BL_DBG("bl_hw->recovery_flag---> %s\n", bl_hw->recovery_flag ? "true":"false"); -+ if(!bl_hw->recovery_flag) { -+ BL_DBG("bl_main_process: start call bl_hwq_process_all\n"); -+ bl_hwq_process_all(bl_hw); -+ BL_DBG("bl_main_process: end call bl_hwq_process_all\n"); -+ } -+ -+ spin_lock_irq(&bl_hw->main_proc_lock); -+ if (bl_hw->more_task_flag) { -+ bl_hw->more_task_flag = false; -+ spin_unlock_irq(&bl_hw->main_proc_lock); -+ bl_hw->lost_int_flag = 1; -+ BL_DBG("go to process start\n"); -+ goto process_start; -+ } -+ bl_hw->bl_processing = false; -+ spin_unlock_irq(&bl_hw->main_proc_lock); -+ -+exit_main_proc: -+ return ret; -+} -diff -Naur /dev/null_irqs.h b/drivers/net/wireless/hflps170/bl_irqs.h ---- /dev/null_irqs.h 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_irqs.h 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,22 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file bl_irqs.h -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ ****************************************************************************** -+ */ -+#ifndef _BL_IRQS_H_ -+#define _BL_IRQS_H_ -+ -+#include -+ -+/* IRQ handler to be registered by platform driver */ -+//irqreturn_t bl_irq_hdlr(int irq, void *dev_id); -+void bl_irq_hdlr(struct sdio_func *func); -+void bl_task(unsigned long data); -+void main_wq_hdlr(struct work_struct *work); -+void bl_queue_main_work(struct bl_hw *bl_hw); -+ -+#endif /* _BL_IRQS_H_ */ -diff -Naur /dev/null_mod_params.c b/drivers/net/wireless/hflps170/bl_mod_params.c ---- /dev/null_mod_params.c 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_mod_params.c 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,474 @@ -+/** -+****************************************************************************** -+* -+* @file bl_mod_params.c -+* -+* @brief Set configuration according to modules parameters -+* -+* Copyright (C) BouffaloLab 2017-2018 -+* -+****************************************************************************** -+*/ -+#include -+ -+#include "bl_defs.h" -+#include "bl_tx.h" -+#include "hal_desc.h" -+#include "bl_cfgfile.h" -+#include "bl_compat.h" -+ -+#define COMMON_PARAM(name, default_softmac, default_fullmac) \ -+ .name = default_fullmac, -+#define SOFTMAC_PARAM(name, default) -+#define FULLMAC_PARAM(name, default) .name = default, -+ -+struct bl_mod_params bl_mod_params = { -+ /* common parameters */ -+ COMMON_PARAM(ht_on, true, true) -+ COMMON_PARAM(vht_on, true, true) -+ COMMON_PARAM(mcs_map, IEEE80211_VHT_MCS_SUPPORT_0_9, IEEE80211_VHT_MCS_SUPPORT_0_7) -+ COMMON_PARAM(ldpc_on, false, false) -+ COMMON_PARAM(vht_stbc, true, true) -+ COMMON_PARAM(phy_cfg, 2, 2) -+ COMMON_PARAM(uapsd_timeout, 300, 300) -+ COMMON_PARAM(ap_uapsd_on, true, true) -+ COMMON_PARAM(sgi, true, true) -+ COMMON_PARAM(sgi80, true, true) -+ COMMON_PARAM(use_2040, 0, 0) -+ COMMON_PARAM(nss, 1, 1) -+ COMMON_PARAM(bfmee, true, true) -+ COMMON_PARAM(bfmer, false, false) -+ COMMON_PARAM(mesh, false, false) -+ COMMON_PARAM(murx, true, true) -+ COMMON_PARAM(mutx, true, true) -+ COMMON_PARAM(mutx_on, true, true) -+ COMMON_PARAM(use_80, true, true) -+ COMMON_PARAM(custregd, false, false) -+ COMMON_PARAM(roc_dur_max, 500, 500) -+ COMMON_PARAM(listen_itv, 0, 0) -+ COMMON_PARAM(listen_bcmc, true, true) -+ COMMON_PARAM(lp_clk_ppm, 20, 20) -+ COMMON_PARAM(ps_on, false, false) -+ COMMON_PARAM(tx_lft, BL_TX_LIFETIME_MS, BL_TX_LIFETIME_MS) -+ COMMON_PARAM(amsdu_maxnb, NX_TX_PAYLOAD_MAX, NX_TX_PAYLOAD_MAX) -+ // By default, only enable UAPSD for Voice queue (see IEEE80211_DEFAULT_UAPSD_QUEUE comment) -+ COMMON_PARAM(uapsd_queues, IEEE80211_WMM_IE_STA_QOSINFO_AC_VO, IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) -+ COMMON_PARAM(tdls, true, true) -+}; -+ -+module_param_named(ht_on, bl_mod_params.ht_on, bool, S_IRUGO); -+MODULE_PARM_DESC(ht_on, "Enable HT (Default: 1)"); -+ -+module_param_named(vht_on, bl_mod_params.vht_on, bool, S_IRUGO); -+MODULE_PARM_DESC(vht_on, "Enable VHT (Default: 1)"); -+ -+module_param_named(mcs_map, bl_mod_params.mcs_map, int, S_IRUGO); -+MODULE_PARM_DESC(mcs_map, "VHT MCS map value 0: MCS0_7, 1: MCS0_8, 2: MCS0_9" -+ " (Default: 0)"); -+ -+module_param_named(amsdu_maxnb, bl_mod_params.amsdu_maxnb, int, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(amsdu_maxnb, "Maximum number of MSDUs inside an A-MSDU in TX: (Default: NX_TX_PAYLOAD_MAX)"); -+ -+module_param_named(ps_on, bl_mod_params.ps_on, bool, S_IRUGO); -+MODULE_PARM_DESC(ps_on, "Enable PowerSaving (Default: 1-Enabled)"); -+ -+module_param_named(tx_lft, bl_mod_params.tx_lft, int, 0644); -+MODULE_PARM_DESC(tx_lft, "Tx lifetime (ms) - setting it to 0 disables retries " -+ "(Default: "__stringify(BL_TX_LIFETIME_MS)")"); -+ -+module_param_named(ldpc_on, bl_mod_params.ldpc_on, bool, S_IRUGO); -+MODULE_PARM_DESC(ldpc_on, "Enable LDPC (Default: 1)"); -+ -+module_param_named(vht_stbc, bl_mod_params.vht_stbc, bool, S_IRUGO); -+MODULE_PARM_DESC(vht_stbc, "Enable VHT STBC in RX (Default: 1)"); -+ -+module_param_named(phycfg, bl_mod_params.phy_cfg, int, S_IRUGO); -+MODULE_PARM_DESC(phycfg, -+ "0 <= phycfg <= 5 : RF Channel Conf (Default: 2(C0-A1-B2))"); -+ -+module_param_named(uapsd_timeout, bl_mod_params.uapsd_timeout, int, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(uapsd_timeout, -+ "UAPSD Timer timeout, in ms (Default: 300). If 0, UAPSD is disabled"); -+ -+module_param_named(uapsd_queues, bl_mod_params.uapsd_queues, int, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(uapsd_queues, "UAPSD Queues, integer value, must be seen as a bitfield\n" -+ " Bit 0 = VO\n" -+ " Bit 1 = VI\n" -+ " Bit 2 = BK\n" -+ " Bit 3 = BE\n" -+ " -> uapsd_queues=7 will enable uapsd for VO, VI and BK queues"); -+ -+module_param_named(ap_uapsd_on, bl_mod_params.ap_uapsd_on, bool, S_IRUGO); -+MODULE_PARM_DESC(ap_uapsd_on, "Enable UAPSD in AP mode (Default: 1)"); -+ -+module_param_named(sgi, bl_mod_params.sgi, bool, S_IRUGO); -+MODULE_PARM_DESC(sgi, "Advertise Short Guard Interval support (Default: 1)"); -+ -+module_param_named(sgi80, bl_mod_params.sgi80, bool, S_IRUGO); -+MODULE_PARM_DESC(sgi80, "Advertise Short Guard Interval support for 80MHz (Default: 1)"); -+ -+module_param_named(use_2040, bl_mod_params.use_2040, bool, S_IRUGO); -+MODULE_PARM_DESC(use_2040, "Use tweaked 20-40MHz mode (Default: 1)"); -+ -+module_param_named(use_80, bl_mod_params.use_80, bool, S_IRUGO); -+MODULE_PARM_DESC(use_80, "Enable 80MHz (Default: 1)"); -+ -+module_param_named(custregd, bl_mod_params.custregd, bool, S_IRUGO); -+MODULE_PARM_DESC(custregd, -+ "Use permissive custom regulatory rules (for testing ONLY) (Default: 0)"); -+ -+module_param_named(nss, bl_mod_params.nss, int, S_IRUGO); -+MODULE_PARM_DESC(nss, "1 <= nss <= 2 : Supported number of Spatial Streams (Default: 1)"); -+ -+module_param_named(bfmee, bl_mod_params.bfmee, bool, S_IRUGO); -+MODULE_PARM_DESC(bfmee, "Enable Beamformee Capability (Default: 1-Enabled)"); -+ -+module_param_named(bfmer, bl_mod_params.bfmer, bool, S_IRUGO); -+MODULE_PARM_DESC(bfmer, "Enable Beamformer Capability (Default: 0-Disabled)"); -+ -+module_param_named(mesh, bl_mod_params.mesh, bool, S_IRUGO); -+MODULE_PARM_DESC(mesh, "Enable Meshing Capability (Default: 0-Disabled)"); -+ -+module_param_named(murx, bl_mod_params.murx, bool, S_IRUGO); -+MODULE_PARM_DESC(murx, "Enable MU-MIMO RX Capability (Default: 1-Enabled)"); -+ -+module_param_named(mutx, bl_mod_params.mutx, bool, S_IRUGO); -+MODULE_PARM_DESC(mutx, "Enable MU-MIMO TX Capability (Default: 1-Enabled)"); -+ -+module_param_named(mutx_on, bl_mod_params.mutx_on, bool, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(mutx_on, "Enable MU-MIMO transmissions (Default: 1-Enabled)"); -+ -+module_param_named(roc_dur_max, bl_mod_params.roc_dur_max, int, S_IRUGO); -+MODULE_PARM_DESC(roc_dur_max, "Maximum Remain on Channel duration"); -+ -+module_param_named(listen_itv, bl_mod_params.listen_itv, int, S_IRUGO); -+MODULE_PARM_DESC(listen_itv, "Maximum listen interval"); -+ -+module_param_named(listen_bcmc, bl_mod_params.listen_bcmc, bool, S_IRUGO); -+MODULE_PARM_DESC(listen_bcmc, "Wait for BC/MC traffic following DTIM beacon"); -+ -+module_param_named(lp_clk_ppm, bl_mod_params.lp_clk_ppm, int, S_IRUGO); -+MODULE_PARM_DESC(lp_clk_ppm, "Low Power Clock accuracy of the local device"); -+ -+module_param_named(tdls, bl_mod_params.tdls, bool, S_IRUGO); -+MODULE_PARM_DESC(tdls, "Enable TDLS (Default: 1-Enabled)"); -+ -+/* Regulatory rules */ -+static const struct ieee80211_regdomain bl_regdom = { -+ .n_reg_rules = 3, -+ .alpha2 = "99", -+ .reg_rules = { -+ REG_RULE(2412 - 10, 2472 + 10, 40, 0, 1000, 0), -+ REG_RULE(2484 - 10, 2484 + 10, 20, 0, 1000, 0), -+ REG_RULE(5150 - 10, 5850 + 10, 80, 0, 1000, 0), -+ } -+}; -+ -+ -+ -+/** -+ * Do some sanity check -+ * -+ */ -+static int bl_check_fw_hw_feature(struct bl_hw *bl_hw, -+ struct wiphy *wiphy) -+{ -+ u32_l sys_feat = bl_hw->version_cfm.features; -+ u32_l phy_feat = bl_hw->version_cfm.version_phy_1; -+ -+ if (!(sys_feat & BIT(MM_FEAT_UMAC_BIT))) { -+ wiphy_err(wiphy, -+ "Loading softmac firmware with fullmac driver\n"); -+ return -1; -+ } -+ -+ if (!(sys_feat & BIT(MM_FEAT_VHT_BIT))) { -+ bl_hw->mod_params->vht_on = false; -+ } -+ -+ if (!(sys_feat & BIT(MM_FEAT_PS_BIT))) { -+ bl_hw->mod_params->ps_on = false; -+ } -+ -+ /* AMSDU (non)support implies different shared structure definition -+ so insure that fw and drv have consistent compilation option */ -+ if (sys_feat & BIT(MM_FEAT_AMSDU_BIT)) { -+#ifndef CONFIG_BL_SPLIT_TX_BUF -+ wiphy_err(wiphy, -+ "AMSDU enabled in firmware but support not compiled in driver\n"); -+ return -1; -+#else -+ if (bl_hw->mod_params->amsdu_maxnb > NX_TX_PAYLOAD_MAX) -+ bl_hw->mod_params->amsdu_maxnb = NX_TX_PAYLOAD_MAX; -+#endif /* CONFIG_BL_SPLIT_TX_BUF */ -+ } else { -+#ifdef CONFIG_BL_SPLIT_TX_BUF -+ wiphy_err(wiphy, -+ "AMSDU disabled in firmware but support compiled in driver\n"); -+ return -1; -+#endif /* CONFIG_BL_SPLIT_TX_BUF */ -+ } -+ -+ if (!(sys_feat & BIT(MM_FEAT_UAPSD_BIT))) { -+ bl_hw->mod_params->uapsd_timeout = 0; -+ } -+ -+ if (sys_feat & BIT(MM_FEAT_WAPI_BIT)) { -+ bl_enable_wapi(bl_hw); -+ } -+ -+#ifdef CONFIG_BL_FULLMAC -+ if (sys_feat & BIT(MM_FEAT_MFP_BIT)) { -+ bl_enable_mfp(bl_hw); -+ } -+#endif -+ -+#define QUEUE_NAME "Broadcast/Multicast queue " -+ -+ if (sys_feat & BIT(MM_FEAT_BCN_BIT)) { -+#if NX_TXQ_CNT == 4 -+ wiphy_err(wiphy, QUEUE_NAME -+ "enabled in firmware but support not compiled in driver\n"); -+ return -1; -+#endif /* NX_TXQ_CNT == 4 */ -+ } else { -+#if NX_TXQ_CNT == 5 -+ wiphy_err(wiphy, QUEUE_NAME -+ "disabled in firmware but support compiled in driver\n"); -+ return -1; -+#endif /* NX_TXQ_CNT == 5 */ -+ } -+#undef QUEUE_NAME -+ -+#ifdef CONFIG_BL_RADAR -+ if (sys_feat & BIT(MM_FEAT_RADAR_BIT)) { -+ /* Enable combination with radar detection */ -+ wiphy->n_iface_combinations++; -+ } -+#endif /* CONFIG_BL_RADAR */ -+ -+#ifndef CONFIG_BL_SDM -+ switch (__MDM_PHYCFG_FROM_VERS(phy_feat)) { -+ case MDM_PHY_CONFIG_TRIDENT: -+ case MDM_PHY_CONFIG_ELMA: -+ bl_hw->mod_params->nss = 1; -+ break; -+ case MDM_PHY_CONFIG_KARST: -+ { -+ int nss_supp = (phy_feat & MDM_NSS_MASK) >> MDM_NSS_LSB; -+ if (bl_hw->mod_params->nss > nss_supp) -+ bl_hw->mod_params->nss = nss_supp; -+ } -+ break; -+ default: -+ WARN_ON(1); -+ break; -+ } -+#endif /* CONFIG_BL_SDM */ -+ -+ if (bl_hw->mod_params->nss < 1 || bl_hw->mod_params->nss > 2) -+ bl_hw->mod_params->nss = 1; -+ -+ wiphy_info(wiphy, "PHY features: [NSS=%d][CHBW=%d]%s\n", -+ bl_hw->mod_params->nss, -+ 20 * (1 << ((phy_feat & MDM_CHBW_MASK) >> MDM_CHBW_LSB)), -+ bl_hw->mod_params->ldpc_on ? "[LDPC]" : ""); -+ -+#define PRINT_BL_FEAT(feat) \ -+ (sys_feat & BIT(MM_FEAT_##feat##_BIT) ? "["#feat"]" : "") -+ -+ wiphy_info(wiphy, "FW features: %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", -+ PRINT_BL_FEAT(BCN), -+ PRINT_BL_FEAT(AUTOBCN), -+ PRINT_BL_FEAT(HWSCAN), -+ PRINT_BL_FEAT(CMON), -+ PRINT_BL_FEAT(MROLE), -+ PRINT_BL_FEAT(RADAR), -+ PRINT_BL_FEAT(PS), -+ PRINT_BL_FEAT(UAPSD), -+ PRINT_BL_FEAT(DPSM), -+ PRINT_BL_FEAT(AMPDU), -+ PRINT_BL_FEAT(AMSDU), -+ PRINT_BL_FEAT(CHNL_CTXT), -+ PRINT_BL_FEAT(REORD), -+ PRINT_BL_FEAT(UMAC), -+ PRINT_BL_FEAT(VHT), -+ PRINT_BL_FEAT(WAPI), -+ PRINT_BL_FEAT(MFP)); -+#undef PRINT_BL_FEAT -+ -+ return 0; -+} -+ -+ -+ -+int bl_handle_dynparams(struct bl_hw *bl_hw, struct wiphy *wiphy) -+{ -+ struct ieee80211_supported_band *band_2GHz = wiphy->bands[NL80211_BAND_2GHZ]; -+#ifndef CONFIG_BL_SDM -+ u32 mdm_phy_cfg; -+#endif -+ int i, ret; -+ int nss; -+ int mcs_map; -+ -+ ret = bl_check_fw_hw_feature(bl_hw, wiphy); -+ if (ret) -+ return ret; -+ -+ /* FULLMAC specific parameters */ -+ wiphy->flags |= WIPHY_FLAG_REPORTS_OBSS; -+ -+ if (bl_hw->mod_params->tdls) { -+ /* TDLS support */ -+ wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; -+#ifdef CONFIG_BL_FULLMAC -+ /* TDLS external setup support */ -+ wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP; -+#endif -+ } -+ -+ if (bl_hw->mod_params->ap_uapsd_on) -+ wiphy->flags |= WIPHY_FLAG_AP_UAPSD; -+ -+ if (bl_hw->mod_params->phy_cfg < 0 || bl_hw->mod_params->phy_cfg > 5) -+ bl_hw->mod_params->phy_cfg = 2; -+ -+ if (bl_hw->mod_params->mcs_map < 0 || bl_hw->mod_params->mcs_map > 2) -+ bl_hw->mod_params->mcs_map = 0; -+ -+#ifndef CONFIG_BL_SDM -+ mdm_phy_cfg = __MDM_PHYCFG_FROM_VERS(bl_hw->version_cfm.version_phy_1); -+ if (mdm_phy_cfg == MDM_PHY_CONFIG_TRIDENT) { -+ struct bl_phy_conf_file phy_conf; -+ // Retrieve the Trident configuration -+ bl_parse_phy_configfile(bl_hw, BL_PHY_CONFIG_TRD_NAME, &phy_conf); -+ memcpy(&bl_hw->phy_config, &phy_conf.trd, sizeof(phy_conf.trd)); -+ } else if (mdm_phy_cfg == MDM_PHY_CONFIG_ELMA) { -+ } else if (mdm_phy_cfg == MDM_PHY_CONFIG_KARST) { -+ struct bl_phy_conf_file phy_conf; -+ // We use the NSS parameter as is -+ // Retrieve the Karst configuration -+ bl_parse_phy_configfile(bl_hw, BL_PHY_CONFIG_KARST_NAME, &phy_conf); -+ -+ memcpy(&bl_hw->phy_config, &phy_conf.karst, sizeof(phy_conf.karst)); -+ } else { -+ WARN_ON(1); -+ } -+#endif /* CONFIG_BL_SDM */ -+ -+ nss = bl_hw->mod_params->nss; -+ -+ /* VHT capabilities */ -+ /* -+ * MCS map: -+ * This capabilities are filled according to the mcs_map module parameter. -+ * However currently we have some limitations due to FPGA clock constraints -+ * that prevent always using the range of MCS that is defined by the -+ * parameter: -+ * - in RX, 2SS, we support up to MCS7 -+ * - in TX, 2SS, we support up to MCS8 -+ */ -+ mcs_map = bl_hw->mod_params->mcs_map; -+ //band_5GHz->vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(0); -+ for (i = 0; i < nss; i++) { -+ band_2GHz->ht_cap.mcs.rx_mask[i] = 0xFF; -+ //band_5GHz->vht_cap.vht_mcs.rx_mcs_map |= cpu_to_le16(mcs_map << (i*2)); -+ mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_7; -+ } -+ for (; i < 8; i++) { -+ //band_5GHz->vht_cap.vht_mcs.rx_mcs_map |= cpu_to_le16( -+ //IEEE80211_VHT_MCS_NOT_SUPPORTED << (i*2)); -+ } -+ mcs_map = bl_hw->mod_params->mcs_map; -+ //band_5GHz->vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(0); -+ for (i = 0; i < nss; i++) { -+ //band_5GHz->vht_cap.vht_mcs.tx_mcs_map |= cpu_to_le16(mcs_map << (i*2)); -+ mcs_map = min_t(int, bl_hw->mod_params->mcs_map, -+ IEEE80211_VHT_MCS_SUPPORT_0_8); -+ } -+ -+ /* -+ * LDPC capability: -+ * This capability is filled according to the ldpc_on module parameter. -+ * However currently we have some limitations due to FPGA clock constraints -+ * that prevent correctly receiving more than MCS4-2SS when using LDPC. -+ * We therefore disable the LDPC support if 2SS is supported. -+ */ -+ bl_hw->mod_params->ldpc_on = nss > 1 ? false: bl_hw->mod_params->ldpc_on; -+ -+ /* HT capabilities */ -+ band_2GHz->ht_cap.cap |= 1 << IEEE80211_HT_CAP_RX_STBC_SHIFT; -+ if (bl_hw->mod_params->ldpc_on) -+ band_2GHz->ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING; -+ if (bl_hw->mod_params->use_2040) { -+ band_2GHz->ht_cap.mcs.rx_mask[4] = 0x1; /* MCS32 */ -+ band_2GHz->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; -+ band_2GHz->ht_cap.mcs.rx_highest = cpu_to_le16(135 * nss); -+ } else { -+ band_2GHz->ht_cap.mcs.rx_highest = cpu_to_le16(65 * nss); -+ } -+ if (nss > 1) -+ band_2GHz->ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC; -+ -+ if (bl_hw->mod_params->sgi) { -+ band_2GHz->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20; -+ if (bl_hw->mod_params->use_2040) { -+ band_2GHz->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40; -+ band_2GHz->ht_cap.mcs.rx_highest = cpu_to_le16(150 * nss); -+ } else -+ band_2GHz->ht_cap.mcs.rx_highest = cpu_to_le16(72 * nss); -+ } -+ band_2GHz->ht_cap.cap |= IEEE80211_HT_CAP_GRN_FLD; -+ printk("--->ht_on=%d\n", bl_hw->mod_params->ht_on); -+ if (!bl_hw->mod_params->ht_on) -+ band_2GHz->ht_cap.ht_supported = false; -+ -+ if (bl_hw->mod_params->custregd) { -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0) -+ // Apply custom regulatory. Note that for recent kernel versions we use instead the -+ // REGULATORY_WIPHY_SELF_MANAGED flag, along with the regulatory_set_wiphy_regd() -+ // function, that needs to be called after wiphy registration -+ printk(KERN_CRIT -+ "\n\n%s: CAUTION: USING PERMISSIVE CUSTOM REGULATORY RULES\n\n", -+ __func__); -+ wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; -+ wiphy_apply_custom_regulatory(wiphy, &bl_regdom); -+#endif -+ } -+ -+ wiphy->max_scan_ssids = SCAN_SSID_MAX; -+ wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0) -+ wiphy->support_mbssid = 1; -+#endif -+ -+ /** -+ * adjust caps with lower layers bl_hw->version_cfm -+ */ -+#ifndef CONFIG_BL_SDM -+ switch (mdm_phy_cfg) { -+ case MDM_PHY_CONFIG_TRIDENT: -+ { -+ BL_DBG("%s: found Trident phy .. using phy bw tweaks\n", __func__); -+ bl_hw->use_phy_bw_tweaks = true; -+ break; -+ } -+ case MDM_PHY_CONFIG_ELMA: -+ BL_DBG("%s: found ELMA phy .. disabling 2.4GHz and greenfield rx\n", __func__); -+ wiphy->bands[NL80211_BAND_2GHZ] = NULL; -+ band_2GHz->ht_cap.cap &= ~IEEE80211_HT_CAP_GRN_FLD; -+ break; -+ case MDM_PHY_CONFIG_KARST: -+ { -+ break; -+ } -+ default: -+ WARN_ON(1); -+ break; -+ } -+#endif /* CONFIG_BL_SDM */ -+ -+ return 0; -+} -diff -Naur /dev/null_mod_params.h b/drivers/net/wireless/hflps170/bl_mod_params.h ---- /dev/null_mod_params.h 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_mod_params.h 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,55 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file bl_mod_params.h -+ * -+ * @brief Declaration of module parameters -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ ****************************************************************************** -+ */ -+ -+#ifndef _BL_MOD_PARAM_H_ -+#define _BL_MOD_PARAM_H_ -+ -+struct bl_mod_params { -+ bool ht_on; -+ bool vht_on; -+ int mcs_map; -+ bool ldpc_on; -+ bool vht_stbc; -+ int phy_cfg; -+ int uapsd_timeout; -+ bool ap_uapsd_on; -+ bool sgi; -+ bool sgi80; -+ bool use_2040; -+ bool use_80; -+ bool custregd; -+ int nss; -+ bool bfmee; -+ bool bfmer; -+ bool mesh; -+ bool murx; -+ bool mutx; -+ bool mutx_on; -+ unsigned int roc_dur_max; -+ int listen_itv; -+ bool listen_bcmc; -+ int lp_clk_ppm; -+ bool ps_on; -+ int tx_lft; -+ int amsdu_maxnb; -+ int uapsd_queues; -+ bool tdls; -+}; -+ -+extern struct bl_mod_params bl_mod_params; -+ -+struct bl_hw; -+int bl_handle_dynparams(struct bl_hw *bl_hw, struct wiphy *wiphy); -+void bl_enable_wapi(struct bl_hw *bl_hw); -+void bl_enable_mfp(struct bl_hw *bl_hw); -+ -+#endif /* _BL_MOD_PARAM_H_ */ -diff -Naur /dev/null_msg_rx.c b/drivers/net/wireless/hflps170/bl_msg_rx.c ---- /dev/null_msg_rx.c 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_msg_rx.c 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,621 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file bl_msg_rx.c -+ * -+ * @brief RX function definitions -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ **************************************************************************************** -+ */ -+#include -+#include "bl_defs.h" -+#include "bl_tx.h" -+#include "bl_events.h" -+#include "bl_debugfs.h" -+#include "bl_msg_tx.h" -+#include "bl_compat.h" -+ -+static int bl_freq_to_idx(struct bl_hw *bl_hw, int freq) -+{ -+ struct ieee80211_supported_band *sband; -+ int band, ch, idx = 0; -+ -+ for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) { -+ sband = bl_hw->wiphy->bands[band]; -+ if (!sband) { -+ continue; -+ } -+ -+ for (ch = 0; ch < sband->n_channels; ch++, idx++) { -+ if (sband->channels[ch].center_freq == freq) { -+ goto exit; -+ } -+ } -+ } -+ -+ BUG_ON(1); -+ -+exit: -+ // Channel has been found, return the index -+ return idx; -+} -+ -+/*************************************************************************** -+ * Messages from MM task -+ **************************************************************************/ -+static inline int bl_rx_chan_pre_switch_ind(struct bl_hw *bl_hw, -+ struct bl_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct bl_vif *bl_vif; -+ int chan_idx = ((struct mm_channel_pre_switch_ind *)msg->param)->chan_index; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ list_for_each_entry(bl_vif, &bl_hw->vifs, list) { -+ if (bl_vif->up && bl_vif->ch_index == chan_idx) { -+ bl_txq_vif_stop(bl_vif, BL_TXQ_STOP_CHAN, bl_hw); -+ } -+ } -+ -+ return 0; -+} -+ -+static inline int bl_rx_chan_switch_ind(struct bl_hw *bl_hw, -+ struct bl_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct bl_vif *bl_vif; -+ int chan_idx = ((struct mm_channel_switch_ind *)msg->param)->chan_index; -+ bool roc = ((struct mm_channel_switch_ind *)msg->param)->roc; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ if (!roc) { -+ list_for_each_entry(bl_vif, &bl_hw->vifs, list) { -+ if (bl_vif->up && bl_vif->ch_index == chan_idx) { -+ bl_txq_vif_start(bl_vif, BL_TXQ_STOP_CHAN, bl_hw); -+ } -+ } -+ } else { -+ /* Retrieve the allocated RoC element */ -+ struct bl_roc_elem *roc_elem = bl_hw->roc_elem; -+ /* Get VIF on which RoC has been started */ -+ bl_vif = netdev_priv(roc_elem->wdev->netdev); -+ -+ /* For debug purpose (use ftrace kernel option) */ -+ trace_switch_roc(bl_vif->vif_index); -+ -+ /* If mgmt_roc is true, remain on channel has been started by ourself */ -+ if (!roc_elem->mgmt_roc) { -+ /* Inform the host that we have switch on the indicated off-channel */ -+ cfg80211_ready_on_channel(roc_elem->wdev, (u64)(bl_hw->roc_cookie_cnt), -+ roc_elem->chan, roc_elem->duration, GFP_KERNEL); -+ } -+ -+ /* Keep in mind that we have switched on the channel */ -+ roc_elem->on_chan = true; -+ -+ // Enable traffic on OFF channel queue -+ bl_txq_offchan_start(bl_hw); -+ } -+ -+ bl_hw->cur_chanctx = chan_idx; -+ -+ return 0; -+} -+ -+static inline int bl_rx_remain_on_channel_exp_ind(struct bl_hw *bl_hw, -+ struct bl_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ /* Retrieve the allocated RoC element */ -+ struct bl_roc_elem *roc_elem = bl_hw->roc_elem; -+ /* Get VIF on which RoC has been started */ -+ struct bl_vif *bl_vif = netdev_priv(roc_elem->wdev->netdev); -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* For debug purpose (use ftrace kernel option) */ -+ trace_roc_exp(bl_vif->vif_index); -+ -+ /* If mgmt_roc is true, remain on channel has been started by ourself */ -+ /* If RoC has been cancelled before we switched on channel, do not call cfg80211 */ -+ if (!roc_elem->mgmt_roc && roc_elem->on_chan) { -+ /* Inform the host that off-channel period has expired */ -+ cfg80211_remain_on_channel_expired(roc_elem->wdev, (u64)(bl_hw->roc_cookie_cnt), -+ roc_elem->chan, GFP_KERNEL); -+ } -+ -+ /* De-init offchannel TX queue */ -+ bl_txq_offchan_deinit(bl_vif); -+ -+ /* Increase the cookie counter cannot be zero */ -+ bl_hw->roc_cookie_cnt++; -+ -+ if (bl_hw->roc_cookie_cnt == 0) { -+ bl_hw->roc_cookie_cnt = 1; -+ } -+ -+ /* Free the allocated RoC element */ -+ kfree(roc_elem); -+ bl_hw->roc_elem = NULL; -+ -+ return 0; -+} -+ -+static inline int bl_rx_p2p_vif_ps_change_ind(struct bl_hw *bl_hw, -+ struct bl_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ int vif_idx = ((struct mm_p2p_vif_ps_change_ind *)msg->param)->vif_index; -+ int ps_state = ((struct mm_p2p_vif_ps_change_ind *)msg->param)->ps_state; -+ struct bl_vif *vif_entry; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ vif_entry = bl_hw->vif_table[vif_idx]; -+ -+ if (vif_entry) { -+ goto found_vif; -+ } -+ -+ goto exit; -+ -+found_vif: -+ -+ if (ps_state == MM_PS_MODE_OFF) { -+ // Start TX queues for provided VIF -+ bl_txq_vif_start(vif_entry, BL_TXQ_STOP_VIF_PS, bl_hw); -+ } -+ else { -+ // Stop TX queues for provided VIF -+ bl_txq_vif_stop(vif_entry, BL_TXQ_STOP_VIF_PS, bl_hw); -+ } -+ -+exit: -+ return 0; -+} -+ -+static inline int bl_rx_channel_survey_ind(struct bl_hw *bl_hw, -+ struct bl_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct mm_channel_survey_ind *ind = (struct mm_channel_survey_ind *)msg->param; -+ // Get the channel index -+ int idx = bl_freq_to_idx(bl_hw, ind->freq); -+ // Get the survey -+ struct bl_survey_info *bl_survey = &bl_hw->survey[idx]; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ // Store the received parameters -+ bl_survey->chan_time_ms = ind->chan_time_ms; -+ bl_survey->chan_time_busy_ms = ind->chan_time_busy_ms; -+ bl_survey->noise_dbm = ind->noise_dbm; -+ bl_survey->filled = (SURVEY_INFO_TIME | -+ SURVEY_INFO_TIME_BUSY); -+ -+ if (ind->noise_dbm != 0) { -+ bl_survey->filled |= SURVEY_INFO_NOISE_DBM; -+ } -+ -+ return 0; -+} -+ -+static inline int bl_rx_rssi_status_ind(struct bl_hw *bl_hw, -+ struct bl_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct mm_rssi_status_ind *ind = (struct mm_rssi_status_ind *)msg->param; -+ int vif_idx = ind->vif_index; -+ bool rssi_status = ind->rssi_status; -+ -+ struct bl_vif *vif_entry; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ vif_entry = bl_hw->vif_table[vif_idx]; -+ if (vif_entry) { -+ cfg80211_cqm_rssi_notify(vif_entry->ndev, -+ rssi_status ? NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW : -+ NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH, -+ ind->rssi, GFP_KERNEL); -+ } -+ -+ return 0; -+} -+ -+static inline int bl_rx_csa_counter_ind(struct bl_hw *bl_hw, -+ struct bl_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct mm_csa_counter_ind *ind = (struct mm_csa_counter_ind *)msg->param; -+ struct bl_vif *vif; -+ bool found = false; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ // Look for VIF entry -+ list_for_each_entry(vif, &bl_hw->vifs, list) { -+ if (vif->vif_index == ind->vif_index) { -+ found=true; -+ break; -+ } -+ } -+ -+ if (found) { -+ if (vif->ap.csa) -+ vif->ap.csa->count = ind->csa_count; -+ else -+ netdev_err(vif->ndev, "CSA counter update but no active CSA"); -+ } -+ -+ return 0; -+} -+ -+static inline int bl_rx_csa_finish_ind(struct bl_hw *bl_hw, -+ struct bl_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct mm_csa_finish_ind *ind = (struct mm_csa_finish_ind *)msg->param; -+ struct bl_vif *vif; -+ bool found = false; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ // Look for VIF entry -+ list_for_each_entry(vif, &bl_hw->vifs, list) { -+ if (vif->vif_index == ind->vif_index) { -+ found=true; -+ break; -+ } -+ } -+ -+ if (found) { -+ if (BL_VIF_TYPE(vif) == NL80211_IFTYPE_AP || -+ BL_VIF_TYPE(vif) == NL80211_IFTYPE_P2P_GO) { -+ if (vif->ap.csa) { -+ vif->ap.csa->status = ind->status; -+ vif->ap.csa->ch_idx = ind->chan_idx; -+ schedule_work(&vif->ap.csa->work); -+ } else -+ netdev_err(vif->ndev, "CSA finish indication but no active CSA"); -+ } else { -+ if (ind->status == 0) { -+ bl_chanctx_unlink(vif); -+ bl_chanctx_link(vif, ind->chan_idx, NULL); -+ if (bl_hw->cur_chanctx == ind->chan_idx) { -+ bl_txq_vif_start(vif, BL_TXQ_STOP_CHAN, bl_hw); -+ } else -+ bl_txq_vif_stop(vif, BL_TXQ_STOP_CHAN, bl_hw); -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+static inline int bl_rx_csa_traffic_ind(struct bl_hw *bl_hw, -+ struct bl_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct mm_csa_traffic_ind *ind = (struct mm_csa_traffic_ind *)msg->param; -+ struct bl_vif *vif; -+ bool found = false; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ // Look for VIF entry -+ list_for_each_entry(vif, &bl_hw->vifs, list) { -+ if (vif->vif_index == ind->vif_index) { -+ found=true; -+ break; -+ } -+ } -+ -+ if (found) { -+ if (ind->enable) -+ bl_txq_vif_start(vif, BL_TXQ_STOP_CSA, bl_hw); -+ else -+ bl_txq_vif_stop(vif, BL_TXQ_STOP_CSA, bl_hw); -+ } -+ -+ return 0; -+} -+ -+static inline int bl_rx_ps_change_ind(struct bl_hw *bl_hw, -+ struct bl_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct mm_ps_change_ind *ind = (struct mm_ps_change_ind *)msg->param; -+ struct bl_sta *sta = &bl_hw->sta_table[ind->sta_idx]; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ netdev_dbg(bl_hw->vif_table[sta->vif_idx]->ndev, -+ "Sta %d, change PS mode to %s", sta->sta_idx, -+ ind->ps_state ? "ON" : "OFF"); -+ -+ if (sta->valid) { -+ bl_ps_bh_enable(bl_hw, sta, ind->ps_state); -+ } else if (bl_hw->adding_sta) { -+ sta->ps.active = ind->ps_state ? true : false; -+ } else { -+ netdev_err(bl_hw->vif_table[sta->vif_idx]->ndev, -+ "Ignore PS mode change on invalid sta\n"); -+ } -+ -+ return 0; -+} -+ -+ -+static inline int bl_rx_traffic_req_ind(struct bl_hw *bl_hw, -+ struct bl_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct mm_traffic_req_ind *ind = (struct mm_traffic_req_ind *)msg->param; -+ struct bl_sta *sta = &bl_hw->sta_table[ind->sta_idx]; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ netdev_dbg(bl_hw->vif_table[sta->vif_idx]->ndev, -+ "Sta %d, asked for %d pkt", sta->sta_idx, ind->pkt_cnt); -+ -+ bl_ps_bh_traffic_req(bl_hw, sta, ind->pkt_cnt, -+ ind->uapsd ? UAPSD_ID : LEGACY_PS_ID); -+ -+ return 0; -+} -+ -+/*************************************************************************** -+ * Messages from SCANU task -+ **************************************************************************/ -+#ifdef CONFIG_BL_FULLMAC -+static inline int bl_rx_scanu_start_cfm(struct bl_hw *bl_hw, -+ struct bl_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ if (bl_hw->scan_request) { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) -+ struct cfg80211_scan_info info = { -+ .aborted = false, -+ }; -+ -+ cfg80211_scan_done(bl_hw->scan_request, &info); -+#else -+ cfg80211_scan_done(bl_hw->scan_request, false); -+#endif -+ } -+ -+ bl_hw->scan_request = NULL; -+ -+ return 0; -+} -+ -+static inline int bl_rx_scanu_result_ind(struct bl_hw *bl_hw, -+ struct bl_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct cfg80211_bss *bss = NULL; -+ struct ieee80211_channel *chan; -+ struct scanu_result_ind *ind = (struct scanu_result_ind *)msg->param; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ chan = ieee80211_get_channel(bl_hw->wiphy, ind->center_freq); -+ -+ if (chan != NULL) -+ bss = cfg80211_inform_bss_frame(bl_hw->wiphy, chan, -+ (struct ieee80211_mgmt *)ind->payload, -+ ind->length, ind->rssi * 100, GFP_ATOMIC); -+ -+ if (bss != NULL) -+ cfg80211_put_bss(bl_hw->wiphy, bss); -+ -+ return 0; -+} -+#endif /* CONFIG_BL_FULLMAC */ -+ -+/*************************************************************************** -+ * Messages from ME task -+ **************************************************************************/ -+#ifdef CONFIG_BL_FULLMAC -+static inline int bl_rx_me_tkip_mic_failure_ind(struct bl_hw *bl_hw, -+ struct bl_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct me_tkip_mic_failure_ind *ind = (struct me_tkip_mic_failure_ind *)msg->param; -+ struct bl_vif *bl_vif = bl_hw->vif_table[ind->vif_idx]; -+ struct net_device *dev = bl_vif->ndev; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ cfg80211_michael_mic_failure(dev, (u8 *)&ind->addr, (ind->ga?NL80211_KEYTYPE_GROUP: -+ NL80211_KEYTYPE_PAIRWISE), ind->keyid, -+ (u8 *)&ind->tsc, GFP_ATOMIC); -+ -+ return 0; -+} -+ -+static inline int bl_rx_me_tx_credits_update_ind(struct bl_hw *bl_hw, -+ struct bl_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct me_tx_credits_update_ind *ind = (struct me_tx_credits_update_ind *)msg->param; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ bl_txq_credit_update(bl_hw, ind->sta_idx, ind->tid, ind->credits); -+ -+ return 0; -+} -+#endif /* CONFIG_BL_FULLMAC */ -+ -+/*************************************************************************** -+ * Messages from SM task -+ **************************************************************************/ -+static inline int bl_rx_sm_connect_ind(struct bl_hw *bl_hw, -+ struct bl_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct sm_connect_ind *ind = (struct sm_connect_ind *)msg->param; -+ struct bl_vif *bl_vif = bl_hw->vif_table[ind->vif_idx]; -+ struct net_device *dev = bl_vif->ndev; -+ const u8 *req_ie, *rsp_ie; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Retrieve IE addresses and lengths */ -+ req_ie = (const u8 *)ind->assoc_ie_buf; -+ rsp_ie = req_ie + ind->assoc_req_ie_len; -+ -+ // Fill-in the AP information -+ if (ind->status_code == 0) -+ { -+ struct bl_sta *sta = &bl_hw->sta_table[ind->ap_idx]; -+ u8 txq_status; -+ sta->valid = true; -+ sta->sta_idx = ind->ap_idx; -+ sta->ch_idx = ind->ch_idx; -+ sta->vif_idx = ind->vif_idx; -+ sta->vlan_idx = sta->vif_idx; -+ sta->qos = ind->qos; -+ sta->acm = ind->acm; -+ sta->ps.active = false; -+ sta->aid = ind->aid; -+ sta->band = ind->band; -+ sta->width = ind->width; -+ sta->center_freq = ind->center_freq; -+ sta->center_freq1 = ind->center_freq1; -+ sta->center_freq2 = ind->center_freq2; -+ bl_vif->sta.ap = sta; -+ // TODO: Get chan def in this case (add params in cfm ??) -+ bl_chanctx_link(bl_vif, ind->ch_idx, NULL); -+ memcpy(sta->mac_addr, ind->bssid.array, ETH_ALEN); -+ if (ind->ch_idx == bl_hw->cur_chanctx) { -+ txq_status = 0; -+ } else { -+ txq_status = BL_TXQ_STOP_CHAN; -+ } -+ memcpy(sta->ac_param, ind->ac_param, sizeof(sta->ac_param)); -+ bl_txq_sta_init(bl_hw, sta, txq_status); -+ bl_dbgfs_register_rc_stat(bl_hw, sta); -+ } -+ -+ if (!ind->roamed) -+ cfg80211_connect_result(dev, (const u8 *)ind->bssid.array, req_ie, -+ ind->assoc_req_ie_len, rsp_ie, -+ ind->assoc_rsp_ie_len, ind->status_code, -+ GFP_ATOMIC); -+ -+ netif_tx_start_all_queues(dev); -+ netif_carrier_on(dev); -+ -+ return 0; -+} -+ -+static inline int bl_rx_sm_disconnect_ind(struct bl_hw *bl_hw, -+ struct bl_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct sm_disconnect_ind *ind = (struct sm_disconnect_ind *)msg->param; -+ struct bl_vif *bl_vif = bl_hw->vif_table[ind->vif_idx]; -+ struct net_device *dev = bl_vif->ndev; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* if vif is not up, bl_close has already been called */ -+ if (bl_vif->up) { -+ if (!ind->ft_over_ds) { -+ cfg80211_disconnected(dev, ind->reason_code, NULL, 0, true, GFP_ATOMIC); -+ } -+ netif_tx_stop_all_queues(dev); -+ netif_carrier_off(dev); -+ } -+ -+#ifdef CONFIG_BL_BFMER -+ /* Disable Beamformer if supported */ -+ bl_bfmer_report_del(bl_hw, bl_vif->sta.ap); -+#endif //(CONFIG_BL_BFMER) -+ -+ bl_txq_sta_deinit(bl_hw, bl_vif->sta.ap); -+ bl_dbgfs_unregister_rc_stat(bl_hw, bl_vif->sta.ap); -+ bl_vif->sta.ap->valid = false; -+ bl_vif->sta.ap = NULL; -+ bl_chanctx_unlink(bl_vif); -+ -+ return 0; -+} -+ -+/*************************************************************************** -+ * Messages from DEBUG task -+ **************************************************************************/ -+static inline int bl_rx_dbg_error_ind(struct bl_hw *bl_hw, -+ struct bl_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ bl_error_ind(bl_hw); -+ -+ return 0; -+} -+ -+static msg_cb_fct mm_hdlrs[MSG_I(MM_MAX)] = { -+ [MSG_I(MM_CHANNEL_SWITCH_IND)] = bl_rx_chan_switch_ind, -+ [MSG_I(MM_CHANNEL_PRE_SWITCH_IND)] = bl_rx_chan_pre_switch_ind, -+ [MSG_I(MM_REMAIN_ON_CHANNEL_EXP_IND)] = bl_rx_remain_on_channel_exp_ind, -+ [MSG_I(MM_PS_CHANGE_IND)] = bl_rx_ps_change_ind, -+ [MSG_I(MM_TRAFFIC_REQ_IND)] = bl_rx_traffic_req_ind, -+ [MSG_I(MM_CSA_COUNTER_IND)] = bl_rx_csa_counter_ind, -+ [MSG_I(MM_CSA_FINISH_IND)] = bl_rx_csa_finish_ind, -+ [MSG_I(MM_CSA_TRAFFIC_IND)] = bl_rx_csa_traffic_ind, -+ [MSG_I(MM_CHANNEL_SURVEY_IND)] = bl_rx_channel_survey_ind, -+ [MSG_I(MM_RSSI_STATUS_IND)] = bl_rx_rssi_status_ind, -+}; -+ -+static msg_cb_fct scan_hdlrs[MSG_I(SCANU_MAX)] = { -+ [MSG_I(SCANU_START_CFM)] = bl_rx_scanu_start_cfm, -+ [MSG_I(SCANU_RESULT_IND)] = bl_rx_scanu_result_ind, -+}; -+ -+static msg_cb_fct me_hdlrs[MSG_I(ME_MAX)] = { -+ [MSG_I(ME_TKIP_MIC_FAILURE_IND)] = bl_rx_me_tkip_mic_failure_ind, -+ [MSG_I(ME_TX_CREDITS_UPDATE_IND)] = bl_rx_me_tx_credits_update_ind, -+}; -+ -+static msg_cb_fct sm_hdlrs[MSG_I(SM_MAX)] = { -+ [MSG_I(SM_CONNECT_IND)] = bl_rx_sm_connect_ind, -+ [MSG_I(SM_DISCONNECT_IND)] = bl_rx_sm_disconnect_ind, -+}; -+ -+static msg_cb_fct apm_hdlrs[MSG_I(APM_MAX)] = { -+}; -+ -+static msg_cb_fct dbg_hdlrs[MSG_I(DBG_MAX)] = { -+ [MSG_I(DBG_ERROR_IND)] = bl_rx_dbg_error_ind, -+}; -+ -+static msg_cb_fct *msg_hdlrs[] = { -+ [TASK_MM] = mm_hdlrs, -+ [TASK_DBG] = dbg_hdlrs, -+ [TASK_SCANU] = scan_hdlrs, -+ [TASK_ME] = me_hdlrs, -+ [TASK_SM] = sm_hdlrs, -+ [TASK_APM] = apm_hdlrs, -+}; -+ -+/** -+ * -+ */ -+void bl_rx_handle_msg(struct bl_hw *bl_hw, struct ipc_e2a_msg *msg) -+{ -+ printk(KERN_CRIT "recv: msg:%4d-%-24s\n", msg->id, BL_ID2STR(msg->id)); -+ bl_hw->cmd_mgr.msgind(&bl_hw->cmd_mgr, msg, -+ msg_hdlrs[MSG_T(msg->id)][MSG_I(msg->id)]); -+} -diff -Naur /dev/null_msg_rx.h b/drivers/net/wireless/hflps170/bl_msg_rx.h ---- /dev/null_msg_rx.h 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_msg_rx.h 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,18 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file bl_msg_rx.h -+ * -+ * @brief RX function declarations -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ **************************************************************************************** -+ */ -+ -+#ifndef _BL_MSG_RX_H_ -+#define _BL_MSG_RX_H_ -+ -+void bl_rx_handle_msg(struct bl_hw *bl_hw, struct ipc_e2a_msg *msg); -+ -+#endif /* _BL_MSG_RX_H_ */ -diff -Naur /dev/null_msg_tx.c b/drivers/net/wireless/hflps170/bl_msg_tx.c ---- /dev/null_msg_tx.c 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_msg_tx.c 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,1315 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file bl_msg_tx.c -+ * -+ * @brief TX function definitions -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ ****************************************************************************** -+ */ -+#include -+#include "bl_msg_tx.h" -+#include "bl_mod_params.h" -+#ifdef CONFIG_BL_BFMER -+#include "bl_bfmer.h" -+#endif //(CONFIG_BL_BFMER) -+#include "bl_compat.h" -+ -+const struct mac_addr mac_addr_bcst = {{0xFFFF, 0xFFFF, 0xFFFF}}; -+ -+/* Default MAC Rx filters that can be changed by mac80211 -+ * (via the configure_filter() callback) */ -+#define BL_MAC80211_CHANGEABLE ( \ -+ NXMAC_ACCEPT_BA_BIT | \ -+ NXMAC_ACCEPT_BAR_BIT | \ -+ NXMAC_ACCEPT_OTHER_DATA_FRAMES_BIT | \ -+ NXMAC_ACCEPT_PROBE_REQ_BIT | \ -+ NXMAC_ACCEPT_PS_POLL_BIT \ -+ ) -+ -+/* Default MAC Rx filters that cannot be changed by mac80211 */ -+#define BL_MAC80211_NOT_CHANGEABLE ( \ -+ NXMAC_ACCEPT_QO_S_NULL_BIT | \ -+ NXMAC_ACCEPT_Q_DATA_BIT | \ -+ NXMAC_ACCEPT_DATA_BIT | \ -+ NXMAC_ACCEPT_OTHER_MGMT_FRAMES_BIT | \ -+ NXMAC_ACCEPT_MY_UNICAST_BIT | \ -+ NXMAC_ACCEPT_BROADCAST_BIT | \ -+ NXMAC_ACCEPT_BEACON_BIT | \ -+ NXMAC_ACCEPT_PROBE_RESP_BIT \ -+ ) -+ -+/* Default MAC Rx filter */ -+#define BL_DEFAULT_RX_FILTER (BL_MAC80211_CHANGEABLE | BL_MAC80211_NOT_CHANGEABLE) -+ -+static const int bw2chnl[] = { -+ [NL80211_CHAN_WIDTH_20_NOHT] = PHY_CHNL_BW_20, -+ [NL80211_CHAN_WIDTH_20] = PHY_CHNL_BW_20, -+ [NL80211_CHAN_WIDTH_40] = PHY_CHNL_BW_40, -+ [NL80211_CHAN_WIDTH_80] = PHY_CHNL_BW_80, -+ [NL80211_CHAN_WIDTH_160] = PHY_CHNL_BW_160, -+ [NL80211_CHAN_WIDTH_80P80] = PHY_CHNL_BW_80P80, -+}; -+ -+static const int chnl2bw[] = { -+ [PHY_CHNL_BW_20] = NL80211_CHAN_WIDTH_20, -+ [PHY_CHNL_BW_40] = NL80211_CHAN_WIDTH_40, -+ [PHY_CHNL_BW_80] = NL80211_CHAN_WIDTH_80, -+ [PHY_CHNL_BW_160] = NL80211_CHAN_WIDTH_160, -+ [PHY_CHNL_BW_80P80] = NL80211_CHAN_WIDTH_80P80, -+}; -+ -+/*****************************************************************************/ -+/* -+ * Parse the ampdu density to retrieve the value in usec, according to the -+ * values defined in ieee80211.h -+ */ -+static inline u8 bl_ampdudensity2usec(u8 ampdudensity) -+{ -+ switch (ampdudensity) { -+ case IEEE80211_HT_MPDU_DENSITY_NONE: -+ return 0; -+ /* 1 microsecond is our granularity */ -+ case IEEE80211_HT_MPDU_DENSITY_0_25: -+ case IEEE80211_HT_MPDU_DENSITY_0_5: -+ case IEEE80211_HT_MPDU_DENSITY_1: -+ return 1; -+ case IEEE80211_HT_MPDU_DENSITY_2: -+ return 2; -+ case IEEE80211_HT_MPDU_DENSITY_4: -+ return 4; -+ case IEEE80211_HT_MPDU_DENSITY_8: -+ return 8; -+ case IEEE80211_HT_MPDU_DENSITY_16: -+ return 16; -+ default: -+ return 0; -+ } -+} -+ -+static inline bool use_pairwise_key(struct cfg80211_crypto_settings *crypto) -+{ -+ if ((crypto->cipher_group == WLAN_CIPHER_SUITE_WEP40) || -+ (crypto->cipher_group == WLAN_CIPHER_SUITE_WEP104)) -+ return false; -+ -+ return true; -+} -+ -+static inline bool is_non_blocking_msg(int id) { -+ return ((id == MM_TIM_UPDATE_REQ) || (id == ME_RC_SET_RATE_REQ) || -+ (id == ME_TRAFFIC_IND_REQ)); -+} -+ -+static inline uint8_t passive_scan_flag(uint32_t flags) { -+ if (flags & (IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_RADAR)) -+ return SCAN_PASSIVE_BIT; -+ return 0; -+} -+ -+/** -+ ****************************************************************************** -+ * @brief Allocate memory for a message -+ * -+ * This primitive allocates memory for a message that has to be sent. The memory -+ * is allocated dynamically on the heap and the length of the variable parameter -+ * structure has to be provided in order to allocate the correct size. -+ * -+ * Several additional parameters are provided which will be preset in the message -+ * and which may be used internally to choose the kind of memory to allocate. -+ * -+ * The memory allocated will be automatically freed by the kernel, after the -+ * pointer has been sent to ke_msg_send(). If the message is not sent, it must -+ * be freed explicitly with ke_msg_free(). -+ * -+ * Allocation failure is considered critical and should not happen. -+ * -+ * @param[in] id Message identifier -+ * @param[in] dest_id Destination Task Identifier -+ * @param[in] src_id Source Task Identifier -+ * @param[in] param_len Size of the message parameters to be allocated -+ * -+ * @return Pointer to the parameter member of the ke_msg. If the parameter -+ * structure is empty, the pointer will point to the end of the message -+ * and should not be used (except to retrieve the message pointer or to -+ * send the message) -+ ****************************************************************************** -+ */ -+static inline void *bl_msg_zalloc(lmac_msg_id_t const id, -+ lmac_task_id_t const dest_id, -+ lmac_task_id_t const src_id, -+ uint16_t const param_len) -+{ -+ struct lmac_msg *msg; -+ gfp_t flags; -+ int len; -+ -+ len =(sizeof(struct lmac_msg) + param_len + 3)/4*4; -+ -+ -+ if (is_non_blocking_msg(id) && in_softirq()) -+ flags = GFP_ATOMIC; -+ else -+ flags = GFP_KERNEL; -+ -+ -+ msg = (struct lmac_msg *)kzalloc(len, flags); -+ if (msg == NULL) { -+ printk(KERN_CRIT "%s: msg allocation failed\n", __func__); -+ return NULL; -+ } -+ -+ msg->sdio_hdr.type = BL_TYPE_MSG; -+ msg->sdio_hdr.len = len; -+ msg->sdio_hdr.queue_idx = 0; -+ msg->id = id; -+ msg->dest_id = dest_id; -+ msg->src_id = src_id; -+ msg->param_len = param_len; -+ -+ return msg->param; -+} -+ -+static int bl_send_msg(struct bl_hw *bl_hw, const void *msg_params, -+ int reqcfm, lmac_msg_id_t reqid, void *cfm) -+{ -+ struct lmac_msg *msg; -+ struct bl_cmd *cmd; -+ bool nonblock; -+ int ret; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ msg = container_of((void *)msg_params, struct lmac_msg, param); -+ -+ if (!test_bit(BL_DEV_STARTED, &bl_hw->drv_flags) && -+ reqid != MM_RESET_CFM && reqid != MM_VERSION_CFM && -+ reqid != MM_START_CFM && reqid != MM_SET_IDLE_CFM && -+ reqid != ME_CONFIG_CFM && reqid != MM_SET_PS_MODE_CFM && -+ reqid != ME_CHAN_CONFIG_CFM) { -+ printk(KERN_CRIT "%s: bypassing (BL_DEV_RESTARTING set) 0x%02x\n", -+ __func__, reqid); -+ kfree(msg); -+ return -EBUSY; -+ } else if (!bl_hw->ipc_env) { -+ printk(KERN_CRIT "%s: bypassing (restart must have failed)\n", __func__); -+ kfree(msg); -+ return -EBUSY; -+ } -+ -+ nonblock = is_non_blocking_msg(msg->id); -+ -+ cmd = kzalloc(sizeof(struct bl_cmd), nonblock ? GFP_ATOMIC : GFP_KERNEL); -+ cmd->result = -EINTR; -+ cmd->id = msg->id; -+ cmd->reqid = reqid; -+ cmd->a2e_msg = msg; -+ cmd->e2a_msg = cfm; -+ if (nonblock) -+ cmd->flags = BL_CMD_FLAG_NONBLOCK; -+ if (reqcfm) -+ cmd->flags |= BL_CMD_FLAG_REQ_CFM; -+ ret = bl_hw->cmd_mgr.queue(&bl_hw->cmd_mgr, cmd); -+ -+ if (!nonblock) -+ kfree(cmd); -+ else -+ ret = cmd->result; -+ -+ return ret; -+} -+ -+/****************************************************************************** -+ * Control messages handling functions (SOFTMAC and FULLMAC) -+ *****************************************************************************/ -+int bl_send_reset(struct bl_hw *bl_hw) -+{ -+ void *void_param; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* RESET REQ has no parameter */ -+ void_param = bl_msg_zalloc(MM_RESET_REQ, TASK_MM, DRV_TASK_ID, 0); -+ if (!void_param) -+ return -ENOMEM; -+ -+ return bl_send_msg(bl_hw, void_param, 1, MM_RESET_CFM, NULL); -+} -+ -+int bl_send_start(struct bl_hw *bl_hw) -+{ -+ struct mm_start_req *start_req_param; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Build the START REQ message */ -+ start_req_param = bl_msg_zalloc(MM_START_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_start_req)); -+ if (!start_req_param) -+ return -ENOMEM; -+ -+ /* Set parameters for the START message */ -+ memcpy(&start_req_param->phy_cfg, &bl_hw->phy_config, sizeof(bl_hw->phy_config)); -+ start_req_param->uapsd_timeout = (u32_l)bl_hw->mod_params->uapsd_timeout; -+ start_req_param->lp_clk_accuracy = (u16_l)bl_hw->mod_params->lp_clk_ppm; -+ -+ /* Send the START REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, start_req_param, 1, MM_START_CFM, NULL); -+} -+ -+int bl_send_version_req(struct bl_hw *bl_hw, struct mm_version_cfm *cfm) -+{ -+ void *void_param; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* VERSION REQ has no parameter */ -+ void_param = bl_msg_zalloc(MM_VERSION_REQ, TASK_MM, DRV_TASK_ID, 0); -+ if (!void_param) -+ return -ENOMEM; -+ -+ return bl_send_msg(bl_hw, void_param, 1, MM_VERSION_CFM, cfm); -+} -+ -+int bl_send_add_if(struct bl_hw *bl_hw, const unsigned char *mac, -+ enum nl80211_iftype iftype, bool p2p, struct mm_add_if_cfm *cfm) -+{ -+ struct mm_add_if_req *add_if_req_param; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Build the ADD_IF_REQ message */ -+ add_if_req_param = bl_msg_zalloc(MM_ADD_IF_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_add_if_req)); -+ if (!add_if_req_param) -+ return -ENOMEM; -+ -+ /* Set parameters for the ADD_IF_REQ message */ -+ memcpy(&(add_if_req_param->addr.array[0]), mac, ETH_ALEN); -+ switch (iftype) { -+ #ifdef CONFIG_BL_FULLMAC -+ case NL80211_IFTYPE_P2P_CLIENT: -+ add_if_req_param->p2p = true; -+ // no break -+ #endif /* CONFIG_BL_FULLMAC */ -+ case NL80211_IFTYPE_STATION: -+ add_if_req_param->type = MM_STA; -+ break; -+ -+ case NL80211_IFTYPE_ADHOC: -+ add_if_req_param->type = MM_IBSS; -+ break; -+ -+ #ifdef CONFIG_BL_FULLMAC -+ case NL80211_IFTYPE_P2P_GO: -+ add_if_req_param->p2p = true; -+ // no break -+ #endif /* CONFIG_BL_FULLMAC */ -+ case NL80211_IFTYPE_AP: -+ add_if_req_param->type = MM_AP; -+ break; -+ case NL80211_IFTYPE_MESH_POINT: -+ add_if_req_param->type = MM_MESH_POINT; -+ break; -+ case NL80211_IFTYPE_AP_VLAN: -+ return -1; -+ default: -+ add_if_req_param->type = MM_STA; -+ break; -+ } -+ -+ /* Send the ADD_IF_REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, add_if_req_param, 1, MM_ADD_IF_CFM, cfm); -+} -+ -+int bl_send_remove_if(struct bl_hw *bl_hw, u8 vif_index) -+{ -+ struct mm_remove_if_req *remove_if_req; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Build the MM_REMOVE_IF_REQ message */ -+ remove_if_req = bl_msg_zalloc(MM_REMOVE_IF_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_remove_if_req)); -+ if (!remove_if_req) -+ return -ENOMEM; -+ -+ /* Set parameters for the MM_REMOVE_IF_REQ message */ -+ remove_if_req->inst_nbr = vif_index; -+ -+ /* Send the MM_REMOVE_IF_REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, remove_if_req, 1, MM_REMOVE_IF_CFM, NULL); -+} -+ -+int bl_send_set_channel(struct bl_hw *bl_hw, int phy_idx, -+ struct mm_set_channel_cfm *cfm) -+{ -+ struct mm_set_channel_req *set_chnl_par; -+ enum nl80211_chan_width width; -+ u16 center_freq, center_freq1, center_freq2; -+ s8 tx_power = 0; -+ enum nl80211_band band; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ if (phy_idx >= bl_hw->phy_cnt) -+ return -ENOTSUPP; -+ -+ set_chnl_par = bl_msg_zalloc(MM_SET_CHANNEL_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_set_channel_req)); -+ if (!set_chnl_par) -+ return -ENOMEM; -+ -+ if (phy_idx == 0) { -+ /* On FULLMAC only setting channel of secondary chain */ -+ wiphy_err(bl_hw->wiphy, "Trying to set channel of primary chain"); -+ return 0; -+ } else { -+ struct bl_sec_phy_chan *chan = &bl_hw->sec_phy_chan; -+ -+ width = chnl2bw[chan->type]; -+ band = chan->band; -+ center_freq = chan->prim20_freq; -+ center_freq1 = chan->center_freq1; -+ center_freq2 = chan->center_freq2; -+ } -+ -+ set_chnl_par->band = band; -+ set_chnl_par->type = bw2chnl[width]; -+ set_chnl_par->prim20_freq = center_freq; -+ set_chnl_par->center1_freq = center_freq1; -+ set_chnl_par->center2_freq = center_freq2; -+ set_chnl_par->index = phy_idx; -+ set_chnl_par->tx_power = tx_power; -+ -+ if (bl_hw->use_phy_bw_tweaks) { -+ /* XXX Tweak for 80MHz VHT */ -+ if (width > NL80211_CHAN_WIDTH_40) { -+ int _offs = center_freq1 - center_freq; -+ set_chnl_par->type = PHY_CHNL_BW_40; -+ set_chnl_par->center1_freq = center_freq + 10 * -+ (_offs > 0 ? 1 : -1) * (abs(_offs) > 10 ? 1 : -1); -+ BL_DBG("Tweak for 80MHz VHT: 80MHz chan requested\n"); -+ } -+ } -+ -+ BL_DBG("mac80211: freq=%d(c1:%d - c2:%d)/width=%d - band=%d\n" -+ " hw(%d): prim20=%d(c1:%d - c2:%d)/ type=%d - band=%d\n", -+ center_freq, center_freq1, -+ center_freq2, width, band, -+ phy_idx, set_chnl_par->prim20_freq, set_chnl_par->center1_freq, -+ set_chnl_par->center2_freq, set_chnl_par->type, set_chnl_par->band); -+ -+ /* Send the MM_SET_CHANNEL_REQ REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, set_chnl_par, 1, MM_SET_CHANNEL_CFM, cfm); -+} -+ -+ -+int bl_send_key_add(struct bl_hw *bl_hw, u8 vif_idx, u8 sta_idx, bool pairwise, -+ u8 *key, u8 key_len, u8 key_idx, u8 cipher_suite, -+ struct mm_key_add_cfm *cfm) -+{ -+ struct mm_key_add_req *key_add_req; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Build the MM_KEY_ADD_REQ message */ -+ key_add_req = bl_msg_zalloc(MM_KEY_ADD_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_key_add_req)); -+ if (!key_add_req) -+ return -ENOMEM; -+ -+ /* Set parameters for the MM_KEY_ADD_REQ message */ -+ if (sta_idx != 0xFF) { -+ /* Pairwise key */ -+ key_add_req->sta_idx = sta_idx; -+ } else { -+ /* Default key */ -+ key_add_req->sta_idx = sta_idx; -+ key_add_req->key_idx = (u8_l)key_idx; /* only useful for default keys */ -+ } -+ key_add_req->pairwise = pairwise; -+ key_add_req->inst_nbr = vif_idx; -+ key_add_req->key.length = key_len; -+ memcpy(&(key_add_req->key.array[0]), key, key_len); -+ -+ key_add_req->cipher_suite = cipher_suite; -+ -+ BL_DBG("%s: sta_idx:%d key_idx:%d inst_nbr:%d cipher:%d key_len:%d\n", __func__, -+ key_add_req->sta_idx, key_add_req->key_idx, key_add_req->inst_nbr, -+ key_add_req->cipher_suite, key_add_req->key.length); -+#if defined(CONFIG_BL_DBG) || defined(CONFIG_DYNAMIC_DEBUG) -+ print_hex_dump_bytes("key: ", DUMP_PREFIX_OFFSET, key_add_req->key.array, key_add_req->key.length); -+#endif -+ -+ /* Send the MM_KEY_ADD_REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, key_add_req, 1, MM_KEY_ADD_CFM, cfm); -+} -+ -+int bl_send_key_del(struct bl_hw *bl_hw, uint8_t hw_key_idx) -+{ -+ struct mm_key_del_req *key_del_req; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Build the MM_KEY_DEL_REQ message */ -+ key_del_req = bl_msg_zalloc(MM_KEY_DEL_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_key_del_req)); -+ if (!key_del_req) -+ return -ENOMEM; -+ -+ /* Set parameters for the MM_KEY_DEL_REQ message */ -+ key_del_req->hw_key_idx = hw_key_idx; -+ -+ /* Send the MM_KEY_DEL_REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, key_del_req, 1, MM_KEY_DEL_CFM, NULL); -+} -+ -+int bl_send_bcn_change(struct bl_hw *bl_hw, u8 vif_idx, u8 *buf, -+ u16 bcn_len, u16 tim_oft, u16 tim_len, u16 *csa_oft) -+{ -+ struct mm_bcn_change_req *req; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Build the MM_BCN_CHANGE_REQ message */ -+ req = bl_msg_zalloc(MM_BCN_CHANGE_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_bcn_change_req) + bcn_len); -+ if (!req) -+ return -ENOMEM; -+ -+ memcpy(req->bcn_buf, buf, bcn_len); -+ -+ /* Set parameters for the MM_BCN_CHANGE_REQ message */ -+ req->bcn_len = bcn_len; -+ req->tim_oft = tim_oft; -+ req->tim_len = tim_len; -+ req->inst_nbr = vif_idx; -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) -+ if (csa_oft) { -+ int i; -+ for (i = 0; i < BCN_MAX_CSA_CPT; i++) { -+ req->csa_oft[i] = csa_oft[i]; -+ } -+ } -+#endif /* VERSION >= 3.16.0 */ -+ -+ /* Send the MM_BCN_CHANGE_REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, req, 1, MM_BCN_CHANGE_CFM, NULL); -+} -+ -+int bl_send_roc(struct bl_hw *bl_hw, struct bl_vif *vif, -+ struct ieee80211_channel *chan, unsigned int duration) -+{ -+ struct mm_remain_on_channel_req *req; -+ struct cfg80211_chan_def chandef; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Create channel definition structure */ -+ cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT); -+ -+ /* Build the MM_REMAIN_ON_CHANNEL_REQ message */ -+ req = bl_msg_zalloc(MM_REMAIN_ON_CHANNEL_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_remain_on_channel_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the MM_REMAIN_ON_CHANNEL_REQ message */ -+ req->op_code = MM_ROC_OP_START; -+ req->vif_index = vif->vif_index; -+ req->duration_ms = duration; -+ req->band = chan->band; -+ req->type = bw2chnl[chandef.width]; -+ req->prim20_freq = chan->center_freq; -+ req->center1_freq = chandef.center_freq1; -+ req->center2_freq = chandef.center_freq2; -+ req->tx_power = chan->max_power; -+ -+ /* Send the MM_REMAIN_ON_CHANNEL_REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, req, 1, MM_REMAIN_ON_CHANNEL_CFM, NULL); -+} -+ -+int bl_send_cancel_roc(struct bl_hw *bl_hw) -+{ -+ struct mm_remain_on_channel_req *req; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Build the MM_REMAIN_ON_CHANNEL_REQ message */ -+ req = bl_msg_zalloc(MM_REMAIN_ON_CHANNEL_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_remain_on_channel_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the MM_REMAIN_ON_CHANNEL_REQ message */ -+ req->op_code = MM_ROC_OP_CANCEL; -+ -+ /* Send the MM_REMAIN_ON_CHANNEL_REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, req, 0, 0, NULL); -+} -+ -+int bl_send_set_power(struct bl_hw *bl_hw, u8 vif_idx, s8 pwr, -+ struct mm_set_power_cfm *cfm) -+{ -+ struct mm_set_power_req *req; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Build the MM_SET_POWER_REQ message */ -+ req = bl_msg_zalloc(MM_SET_POWER_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_set_power_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the MM_SET_POWER_REQ message */ -+ req->inst_nbr = vif_idx; -+ req->power = pwr; -+ -+ /* Send the MM_SET_POWER_REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, req, 1, MM_SET_POWER_CFM, cfm); -+} -+ -+int bl_send_set_edca(struct bl_hw *bl_hw, u8 hw_queue, u32 param, -+ bool uapsd, u8 inst_nbr) -+{ -+ struct mm_set_edca_req *set_edca_req; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Build the MM_SET_EDCA_REQ message */ -+ set_edca_req = bl_msg_zalloc(MM_SET_EDCA_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_set_edca_req)); -+ if (!set_edca_req) -+ return -ENOMEM; -+ -+ /* Set parameters for the MM_SET_EDCA_REQ message */ -+ set_edca_req->ac_param = param; -+ set_edca_req->uapsd = uapsd; -+ set_edca_req->hw_queue = hw_queue; -+ set_edca_req->inst_nbr = inst_nbr; -+ -+ /* Send the MM_SET_EDCA_REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, set_edca_req, 1, MM_SET_EDCA_CFM, NULL); -+} -+ -+/****************************************************************************** -+ * Control messages handling functions (FULLMAC only) -+ *****************************************************************************/ -+#ifdef CONFIG_BL_FULLMAC -+int bl_send_me_config_req(struct bl_hw *bl_hw) -+{ -+ struct me_config_req *req; -+ struct wiphy *wiphy = bl_hw->wiphy; -+ struct ieee80211_sta_ht_cap *ht_cap = &wiphy->bands[NL80211_BAND_2GHZ]->ht_cap; -+ uint8_t *ht_mcs = (uint8_t *)&ht_cap->mcs; -+ int i; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Build the ME_CONFIG_REQ message */ -+ req = bl_msg_zalloc(ME_CONFIG_REQ, TASK_ME, DRV_TASK_ID, -+ sizeof(struct me_config_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the ME_CONFIG_REQ message */ -+ printk("HT supp %d\n", ht_cap->ht_supported); -+ -+ req->ht_supp = ht_cap->ht_supported; -+ req->ht_cap.ht_capa_info = cpu_to_le16(ht_cap->cap); -+ req->ht_cap.a_mpdu_param = ht_cap->ampdu_factor | -+ (ht_cap->ampdu_density << -+ IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT); -+ for (i = 0; i < sizeof(ht_cap->mcs); i++) -+ req->ht_cap.mcs_rate[i] = ht_mcs[i]; -+ req->ht_cap.ht_extended_capa = 0; -+ req->ht_cap.tx_beamforming_capa = 0; -+ req->ht_cap.asel_capa = 0; -+ -+ req->ps_on = bl_hw->mod_params->ps_on; -+ req->tx_lft = bl_hw->mod_params->tx_lft; -+ -+ /* Send the ME_CONFIG_REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, req, 1, ME_CONFIG_CFM, NULL); -+} -+ -+int bl_send_me_chan_config_req(struct bl_hw *bl_hw) -+{ -+ struct me_chan_config_req *req; -+ struct wiphy *wiphy = bl_hw->wiphy; -+ int i; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Build the ME_CHAN_CONFIG_REQ message */ -+ req = bl_msg_zalloc(ME_CHAN_CONFIG_REQ, TASK_ME, DRV_TASK_ID, -+ sizeof(struct me_chan_config_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ req->chan2G4_cnt= 0; -+ if (wiphy->bands[NL80211_BAND_2GHZ] != NULL) { -+ struct ieee80211_supported_band *b = wiphy->bands[NL80211_BAND_2GHZ]; -+ for (i = 0; i < b->n_channels; i++) { -+ req->chan2G4[req->chan2G4_cnt].flags = 0; -+ if (b->channels[i].flags & IEEE80211_CHAN_DISABLED) -+ req->chan2G4[req->chan2G4_cnt].flags |= SCAN_DISABLED_BIT; -+ req->chan2G4[req->chan2G4_cnt].flags |= passive_scan_flag(b->channels[i].flags); -+ req->chan2G4[req->chan2G4_cnt].band = NL80211_BAND_2GHZ; -+ req->chan2G4[req->chan2G4_cnt].freq = b->channels[i].center_freq; -+ req->chan2G4[req->chan2G4_cnt].tx_power = b->channels[i].max_power; -+ req->chan2G4_cnt++; -+ if (req->chan2G4_cnt == SCAN_CHANNEL_2G4) -+ break; -+ } -+ } -+ -+ req->chan5G_cnt = 0; -+ if (wiphy->bands[NL80211_BAND_5GHZ] != NULL) { -+ struct ieee80211_supported_band *b = wiphy->bands[NL80211_BAND_5GHZ]; -+ for (i = 0; i < b->n_channels; i++) { -+ req->chan5G[req->chan5G_cnt].flags = 0; -+ if (b->channels[i].flags & IEEE80211_CHAN_DISABLED) -+ req->chan5G[req->chan5G_cnt].flags |= SCAN_DISABLED_BIT; -+ req->chan5G[req->chan5G_cnt].flags |= passive_scan_flag(b->channels[i].flags); -+ req->chan5G[req->chan5G_cnt].band = NL80211_BAND_5GHZ; -+ req->chan5G[req->chan5G_cnt].freq = b->channels[i].center_freq; -+ req->chan5G[req->chan5G_cnt].tx_power = b->channels[i].max_power; -+ req->chan5G_cnt++; -+ if (req->chan5G_cnt == SCAN_CHANNEL_5G) -+ break; -+ } -+ } -+ -+ /* Send the ME_CHAN_CONFIG_REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, req, 1, ME_CHAN_CONFIG_CFM, NULL); -+} -+ -+int bl_send_me_set_control_port_req(struct bl_hw *bl_hw, bool opened, u8 sta_idx) -+{ -+ struct me_set_control_port_req *req; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Build the ME_SET_CONTROL_PORT_REQ message */ -+ req = bl_msg_zalloc(ME_SET_CONTROL_PORT_REQ, TASK_ME, DRV_TASK_ID, -+ sizeof(struct me_set_control_port_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the ME_SET_CONTROL_PORT_REQ message */ -+ req->sta_idx = sta_idx; -+ req->control_port_open = opened; -+ -+ /* Send the ME_SET_CONTROL_PORT_REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, req, 1, ME_SET_CONTROL_PORT_CFM, NULL); -+} -+ -+int bl_send_me_sta_add(struct bl_hw *bl_hw, struct station_parameters *params, -+ const u8 *mac, u8 inst_nbr, struct me_sta_add_cfm *cfm) -+{ -+ struct me_sta_add_req *req; -+ u8 *ht_mcs = (u8 *)¶ms->ht_capa->mcs; -+ int i; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Build the MM_STA_ADD_REQ message */ -+ req = bl_msg_zalloc(ME_STA_ADD_REQ, TASK_ME, DRV_TASK_ID, -+ sizeof(struct me_sta_add_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the MM_STA_ADD_REQ message */ -+ memcpy(&(req->mac_addr.array[0]), mac, ETH_ALEN); -+ -+ req->rate_set.length = params->supported_rates_len; -+ for (i = 0; i < params->supported_rates_len; i++) -+ req->rate_set.array[i] = params->supported_rates[i]; -+ -+ req->flags = 0; -+ if (params->ht_capa) { -+ const struct ieee80211_ht_cap *ht_capa = params->ht_capa; -+ -+ req->flags |= STA_HT_CAPA; -+ req->ht_cap.ht_capa_info = cpu_to_le16(ht_capa->cap_info); -+ req->ht_cap.a_mpdu_param = ht_capa->ampdu_params_info; -+ for (i = 0; i < sizeof(ht_capa->mcs); i++) -+ req->ht_cap.mcs_rate[i] = ht_mcs[i]; -+ req->ht_cap.ht_extended_capa = cpu_to_le16(ht_capa->extended_ht_cap_info); -+ req->ht_cap.tx_beamforming_capa = cpu_to_le32(ht_capa->tx_BF_cap_info); -+ req->ht_cap.asel_capa = ht_capa->antenna_selection_info; -+ } -+ -+ if (params->vht_capa) { -+ const struct ieee80211_vht_cap *vht_capa = params->vht_capa; -+ -+ req->flags |= STA_VHT_CAPA; -+ req->vht_cap.vht_capa_info = cpu_to_le32(vht_capa->vht_cap_info); -+ req->vht_cap.rx_highest = cpu_to_le16(vht_capa->supp_mcs.rx_highest); -+ req->vht_cap.rx_mcs_map = cpu_to_le16(vht_capa->supp_mcs.rx_mcs_map); -+ req->vht_cap.tx_highest = cpu_to_le16(vht_capa->supp_mcs.tx_highest); -+ req->vht_cap.tx_mcs_map = cpu_to_le16(vht_capa->supp_mcs.tx_mcs_map); -+ } -+ -+ if (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME)) -+ req->flags |= STA_QOS_CAPA; -+ -+ if (params->sta_flags_set & BIT(NL80211_STA_FLAG_MFP)) -+ req->flags |= STA_MFP_CAPA; -+ -+ if (params->opmode_notif_used) { -+ req->flags |= STA_OPMOD_NOTIF; -+ req->opmode = params->opmode_notif; -+ } -+ -+ req->aid = cpu_to_le16(params->aid); -+ req->uapsd_queues = params->uapsd_queues; -+ req->max_sp_len = params->max_sp * 2; -+ req->vif_idx = inst_nbr; -+ -+ if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) -+ req->tdls_sta = true; -+ -+ /* Send the ME_STA_ADD_REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, req, 1, ME_STA_ADD_CFM, cfm); -+} -+ -+int bl_send_me_sta_del(struct bl_hw *bl_hw, u8 sta_idx, bool tdls_sta) -+{ -+ struct me_sta_del_req *req; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Build the MM_STA_DEL_REQ message */ -+ req = bl_msg_zalloc(ME_STA_DEL_REQ, TASK_ME, DRV_TASK_ID, -+ sizeof(struct me_sta_del_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the MM_STA_DEL_REQ message */ -+ req->sta_idx = sta_idx; -+ req->tdls_sta = tdls_sta; -+ -+ /* Send the ME_STA_DEL_REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, req, 1, ME_STA_DEL_CFM, NULL); -+} -+ -+int bl_send_me_traffic_ind(struct bl_hw *bl_hw, u8 sta_idx, bool uapsd, u8 tx_status) -+{ -+ struct me_traffic_ind_req *req; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Build the ME_UTRAFFIC_IND_REQ message */ -+ req = bl_msg_zalloc(ME_TRAFFIC_IND_REQ, TASK_ME, DRV_TASK_ID, -+ sizeof(struct me_traffic_ind_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the ME_TRAFFIC_IND_REQ message */ -+ req->sta_idx = sta_idx; -+ req->tx_avail = tx_status; -+ req->uapsd = uapsd; -+ -+ /* Send the ME_TRAFFIC_IND_REQ to UMAC FW */ -+ return bl_send_msg(bl_hw, req, 1, ME_TRAFFIC_IND_CFM, NULL); -+} -+ -+int bl_send_me_rc_stats(struct bl_hw *bl_hw, -+ u8 sta_idx, -+ struct me_rc_stats_cfm *cfm) -+{ -+ struct me_rc_stats_req *req; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Build the ME_RC_STATS_REQ message */ -+ req = bl_msg_zalloc(ME_RC_STATS_REQ, TASK_ME, DRV_TASK_ID, -+ sizeof(struct me_rc_stats_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the ME_RC_STATS_REQ message */ -+ req->sta_idx = sta_idx; -+ -+ /* Send the ME_RC_STATS_REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, req, 1, ME_RC_STATS_CFM, cfm); -+} -+ -+int bl_send_me_rc_set_rate(struct bl_hw *bl_hw, -+ u8 sta_idx, -+ u16 rate_cfg) -+{ -+ struct me_rc_set_rate_req *req; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Build the ME_RC_SET_RATE_REQ message */ -+ req = bl_msg_zalloc(ME_RC_SET_RATE_REQ, TASK_ME, DRV_TASK_ID, -+ sizeof(struct me_rc_set_rate_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the ME_RC_SET_RATE_REQ message */ -+ req->sta_idx = sta_idx; -+ req->fixed_rate_cfg = rate_cfg; -+ -+ /* Send the ME_RC_SET_RATE_REQ message to FW */ -+ return bl_send_msg(bl_hw, req, 0, 0, NULL); -+} -+ -+ -+int bl_send_sm_connect_req(struct bl_hw *bl_hw, -+ struct bl_vif *bl_vif, -+ struct cfg80211_connect_params *sme, -+ struct sm_connect_cfm *cfm) -+{ -+ struct sm_connect_req *req; -+ int i; -+ u32_l flags = 0; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Build the SM_CONNECT_REQ message */ -+ req = bl_msg_zalloc(SM_CONNECT_REQ, TASK_SM, DRV_TASK_ID, -+ sizeof(struct sm_connect_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the SM_CONNECT_REQ message */ -+ if (sme->crypto.n_ciphers_pairwise && -+ ((sme->crypto.ciphers_pairwise[0] == WLAN_CIPHER_SUITE_WEP40) || -+ (sme->crypto.ciphers_pairwise[0] == WLAN_CIPHER_SUITE_TKIP) || -+ (sme->crypto.ciphers_pairwise[0] == WLAN_CIPHER_SUITE_WEP104))) -+ flags |= DISABLE_HT; -+ -+ if (sme->crypto.control_port) -+ flags |= CONTROL_PORT_HOST; -+ -+ if (sme->crypto.control_port_no_encrypt) -+ flags |= CONTROL_PORT_NO_ENC; -+ -+ if (use_pairwise_key(&sme->crypto)) -+ flags |= WPA_WPA2_IN_USE; -+ -+ if (sme->mfp == NL80211_MFP_REQUIRED) -+ flags |= MFP_IN_USE; -+ -+ if (sme->crypto.control_port_ethertype) -+ req->ctrl_port_ethertype = sme->crypto.control_port_ethertype; -+ else -+ req->ctrl_port_ethertype = ETH_P_PAE; -+ -+ if (sme->bssid) -+ memcpy(&req->bssid, sme->bssid, ETH_ALEN); -+ else -+ req->bssid = mac_addr_bcst; -+ req->vif_idx = bl_vif->vif_index; -+ if (sme->channel) { -+ req->chan.band = sme->channel->band; -+ req->chan.freq = sme->channel->center_freq; -+ req->chan.flags = passive_scan_flag(sme->channel->flags); -+ } else { -+ req->chan.freq = (u16_l)-1; -+ } -+ for (i = 0; i < sme->ssid_len; i++) -+ req->ssid.array[i] = sme->ssid[i]; -+ req->ssid.length = sme->ssid_len; -+ req->flags = flags; -+ if (WARN_ON(sme->ie_len > sizeof(req->ie_buf))) -+ return -EINVAL; -+ if (sme->ie_len) -+ memcpy(req->ie_buf, sme->ie, sme->ie_len); -+ req->ie_len = sme->ie_len; -+ req->listen_interval = bl_mod_params.listen_itv; -+ req->dont_wait_bcmc = !bl_mod_params.listen_bcmc; -+ -+ /* Set auth_type */ -+ if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) -+ req->auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM; -+ else -+ req->auth_type = sme->auth_type; -+ -+ /* Set UAPSD queues */ -+ req->uapsd_queues = bl_mod_params.uapsd_queues; -+ -+ /* Send the SM_CONNECT_REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, req, 1, SM_CONNECT_CFM, cfm); -+} -+ -+int bl_send_sm_disconnect_req(struct bl_hw *bl_hw, -+ struct bl_vif *bl_vif, -+ u16 reason) -+{ -+ struct sm_disconnect_req *req; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Build the SM_DISCONNECT_REQ message */ -+ req = bl_msg_zalloc(SM_DISCONNECT_REQ, TASK_SM, DRV_TASK_ID, -+ sizeof(struct sm_disconnect_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the SM_DISCONNECT_REQ message */ -+ req->reason_code = reason; -+ req->vif_idx = bl_vif->vif_index; -+ -+ /* Send the SM_DISCONNECT_REQ message to LMAC FW */ -+ //return bl_send_msg(bl_hw, req, 1, SM_DISCONNECT_IND, NULL); -+ return bl_send_msg(bl_hw, req, 1, SM_DISCONNECT_CFM, NULL); -+} -+ -+int bl_send_apm_start_req(struct bl_hw *bl_hw, struct bl_vif *vif, -+ struct cfg80211_ap_settings *settings, -+ struct apm_start_cfm *cfm, struct bl_dma_elem *elem) -+{ -+ struct apm_start_req *req; -+ struct bl_bcn *bcn = &vif->ap.bcn; -+ u8 *buf; -+ u32 flags = 0; -+ const u8 *rate_ie; -+ u8 rate_len = 0; -+ int var_offset = offsetof(struct ieee80211_mgmt, u.beacon.variable); -+ const u8 *var_pos; -+ int len, i; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ // Build the beacon -+ bcn->dtim = (u8)settings->dtim_period; -+ buf = bl_build_bcn(bcn, &settings->beacon); -+ if (!buf) { -+ return -ENOMEM; -+ } -+ -+ /* Build the APM_START_REQ message */ -+ req = bl_msg_zalloc(APM_START_REQ, TASK_APM, DRV_TASK_ID, -+ sizeof(struct apm_start_req) + bcn->len); -+ if (!req) -+ return -ENOMEM; -+ -+ // Retrieve the basic rate set from the beacon buffer -+ len = bcn->len - var_offset; -+ var_pos = buf + var_offset; -+ -+ rate_ie = cfg80211_find_ie(WLAN_EID_SUPP_RATES, var_pos, len); -+ if (rate_ie) { -+ const u8 *rates = rate_ie + 2; -+ for (i = 0; i < rate_ie[1]; i++) { -+ if (rates[i] & 0x80) -+ req->basic_rates.array[rate_len++] = rates[i]; -+ } -+ } -+ rate_ie = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, var_pos, len); -+ if (rate_ie) { -+ const u8 *rates = rate_ie + 2; -+ for (i = 0; i < rate_ie[1]; i++) { -+ if (rates[i] & 0x80) -+ req->basic_rates.array[rate_len++] = rates[i]; -+ } -+ } -+ req->basic_rates.length = rate_len; -+ -+ // Fill in the DMA structure -+ elem->buf = buf; -+ elem->len = bcn->len; -+ //elem->dma_addr = dma_map_single(bl_hw->dev, elem->buf, elem->len, -+ // DMA_TO_DEVICE); -+ memcpy(req->bcn_buf, elem->buf, elem->len); -+ /* Set parameters for the APM_START_REQ message */ -+ req->vif_idx = vif->vif_index; -+ //req->bcn_addr = elem->dma_addr; -+ req->bcn_len = bcn->len; -+ req->tim_oft = bcn->head_len; -+ req->tim_len = bcn->tim_len; -+ req->chan.band = settings->chandef.chan->band; -+ req->chan.freq = settings->chandef.chan->center_freq; -+ req->chan.flags = 0; -+ req->chan.tx_power = settings->chandef.chan->max_power; -+ req->center_freq1 = settings->chandef.center_freq1; -+ req->center_freq2 = settings->chandef.center_freq2; -+ req->ch_width = bw2chnl[settings->chandef.width]; -+ req->bcn_int = settings->beacon_interval; -+ if (settings->crypto.control_port) -+ flags |= CONTROL_PORT_HOST; -+ -+ if (settings->crypto.control_port_no_encrypt) -+ flags |= CONTROL_PORT_NO_ENC; -+ -+ if (use_pairwise_key(&settings->crypto)) -+ flags |= WPA_WPA2_IN_USE; -+ -+ if (settings->crypto.control_port_ethertype) -+ req->ctrl_port_ethertype = settings->crypto.control_port_ethertype; -+ else -+ req->ctrl_port_ethertype = ETH_P_PAE; -+ req->flags = flags; -+ -+ /* Send the APM_START_REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, req, 1, APM_START_CFM, cfm); -+} -+ -+int bl_send_apm_stop_req(struct bl_hw *bl_hw, struct bl_vif *vif) -+{ -+ struct apm_stop_req *req; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Build the APM_STOP_REQ message */ -+ req = bl_msg_zalloc(APM_STOP_REQ, TASK_APM, DRV_TASK_ID, -+ sizeof(struct apm_stop_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the APM_STOP_REQ message */ -+ req->vif_idx = vif->vif_index; -+ -+ /* Send the APM_STOP_REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, req, 1, APM_STOP_CFM, NULL); -+} -+ -+int bl_send_scanu_req(struct bl_hw *bl_hw, struct bl_vif *bl_vif, -+ struct cfg80211_scan_request *param) -+{ -+ struct scanu_start_req *req; -+ int i; -+ uint8_t chan_flags = 0; -+ u16_l len; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ len = (param->ie == NULL) ? 0: param->ie_len; -+ -+ /* Build the SCANU_START_REQ message */ -+ req = bl_msg_zalloc(SCANU_START_REQ, TASK_SCANU, DRV_TASK_ID, -+ sizeof(struct scanu_start_req) + len); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters */ -+ req->vif_idx = bl_vif->vif_index; -+ req->chan_cnt = (u8)min_t(int, SCAN_CHANNEL_MAX, param->n_channels); -+ req->ssid_cnt = (u8)min_t(int, SCAN_SSID_MAX, param->n_ssids); -+ req->bssid = mac_addr_bcst; -+ req->no_cck = param->no_cck; -+ -+ if (req->ssid_cnt == 0) -+ chan_flags |= SCAN_PASSIVE_BIT; -+ for (i = 0; i < req->ssid_cnt; i++) { -+ int j; -+ for (j = 0; j < param->ssids[i].ssid_len; j++) -+ req->ssid[i].array[j] = param->ssids[i].ssid[j]; -+ req->ssid[i].length = param->ssids[i].ssid_len; -+ } -+ -+ if (param->ie){ -+ memcpy(req->add_ies_buf, param->ie, param->ie_len); -+ req->add_ie_len = param->ie_len; -+ } -+ -+ for (i = 0; i < req->chan_cnt; i++) { -+ struct ieee80211_channel *chan = param->channels[i]; -+ -+ req->chan[i].band = chan->band; -+ req->chan[i].freq = chan->center_freq; -+ req->chan[i].flags = chan_flags | passive_scan_flag(chan->flags); -+ req->chan[i].tx_power = chan->max_reg_power; -+ } -+ -+ /* Send the SCANU_START_REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, req, 0, 0, NULL); -+} -+ -+int bl_send_apm_start_cac_req(struct bl_hw *bl_hw, struct bl_vif *vif, -+ struct cfg80211_chan_def *chandef, -+ struct apm_start_cac_cfm *cfm) -+{ -+ struct apm_start_cac_req *req; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Build the APM_START_CAC_REQ message */ -+ req = bl_msg_zalloc(APM_START_CAC_REQ, TASK_APM, DRV_TASK_ID, -+ sizeof(struct apm_start_cac_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the APM_START_CAC_REQ message */ -+ req->vif_idx = vif->vif_index; -+ req->chan.band = chandef->chan->band; -+ req->chan.freq = chandef->chan->center_freq; -+ req->chan.flags = 0; -+ req->center_freq1 = chandef->center_freq1; -+ req->center_freq2 = chandef->center_freq2; -+ req->ch_width = bw2chnl[chandef->width]; -+ -+ /* Send the APM_START_CAC_REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, req, 1, APM_START_CAC_CFM, cfm); -+} -+ -+int bl_send_apm_stop_cac_req(struct bl_hw *bl_hw, struct bl_vif *vif) -+{ -+ struct apm_stop_cac_req *req; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Build the APM_STOP_CAC_REQ message */ -+ req = bl_msg_zalloc(APM_STOP_CAC_REQ, TASK_APM, DRV_TASK_ID, -+ sizeof(struct apm_stop_cac_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the APM_STOP_CAC_REQ message */ -+ req->vif_idx = vif->vif_index; -+ -+ /* Send the APM_STOP_CAC_REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, req, 1, APM_STOP_CAC_CFM, NULL); -+} -+#endif /* CONFIG_BL_FULLMAC */ -+ -+/********************************************************************** -+ * Debug Messages -+ *********************************************************************/ -+int bl_send_dbg_trigger_req(struct bl_hw *bl_hw, char *msg) -+{ -+ struct mm_dbg_trigger_req *req; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Build the MM_DBG_TRIGGER_REQ message */ -+ req = bl_msg_zalloc(MM_DBG_TRIGGER_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_dbg_trigger_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the MM_DBG_TRIGGER_REQ message */ -+ strncpy(req->error, msg, sizeof(req->error)); -+ -+ /* Send the MM_DBG_TRIGGER_REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, req, 0, -1, NULL); -+} -+ -+int bl_send_dbg_mem_read_req(struct bl_hw *bl_hw, u32 mem_addr, -+ struct dbg_mem_read_cfm *cfm) -+{ -+ struct dbg_mem_read_req *mem_read_req; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Build the DBG_MEM_READ_REQ message */ -+ mem_read_req = bl_msg_zalloc(DBG_MEM_READ_REQ, TASK_DBG, DRV_TASK_ID, -+ sizeof(struct dbg_mem_read_req)); -+ if (!mem_read_req) -+ return -ENOMEM; -+ -+ /* Set parameters for the DBG_MEM_READ_REQ message */ -+ mem_read_req->memaddr = mem_addr; -+ -+ /* Send the DBG_MEM_READ_REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, mem_read_req, 1, DBG_MEM_READ_CFM, cfm); -+} -+ -+int bl_send_dbg_mem_write_req(struct bl_hw *bl_hw, u32 mem_addr, -+ u32 mem_data) -+{ -+ struct dbg_mem_write_req *mem_write_req; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Build the DBG_MEM_WRITE_REQ message */ -+ mem_write_req = bl_msg_zalloc(DBG_MEM_WRITE_REQ, TASK_DBG, DRV_TASK_ID, -+ sizeof(struct dbg_mem_write_req)); -+ if (!mem_write_req) -+ return -ENOMEM; -+ -+ /* Set parameters for the DBG_MEM_WRITE_REQ message */ -+ mem_write_req->memaddr = mem_addr; -+ mem_write_req->memdata = mem_data; -+ -+ /* Send the DBG_MEM_WRITE_REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, mem_write_req, 1, DBG_MEM_WRITE_CFM, NULL); -+} -+ -+int bl_send_dbg_set_mod_filter_req(struct bl_hw *bl_hw, u32 filter) -+{ -+ struct dbg_set_mod_filter_req *set_mod_filter_req; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Build the DBG_SET_MOD_FILTER_REQ message */ -+ set_mod_filter_req = -+ bl_msg_zalloc(DBG_SET_MOD_FILTER_REQ, TASK_DBG, DRV_TASK_ID, -+ sizeof(struct dbg_set_mod_filter_req)); -+ if (!set_mod_filter_req) -+ return -ENOMEM; -+ -+ /* Set parameters for the DBG_SET_MOD_FILTER_REQ message */ -+ set_mod_filter_req->mod_filter = filter; -+ -+ /* Send the DBG_SET_MOD_FILTER_REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, set_mod_filter_req, 1, DBG_SET_MOD_FILTER_CFM, NULL); -+} -+ -+int bl_send_dbg_set_sev_filter_req(struct bl_hw *bl_hw, u32 filter) -+{ -+ struct dbg_set_sev_filter_req *set_sev_filter_req; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Build the DBG_SET_SEV_FILTER_REQ message */ -+ set_sev_filter_req = -+ bl_msg_zalloc(DBG_SET_SEV_FILTER_REQ, TASK_DBG, DRV_TASK_ID, -+ sizeof(struct dbg_set_sev_filter_req)); -+ if (!set_sev_filter_req) -+ return -ENOMEM; -+ -+ /* Set parameters for the DBG_SET_SEV_FILTER_REQ message */ -+ set_sev_filter_req->sev_filter = filter; -+ -+ /* Send the DBG_SET_SEV_FILTER_REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, set_sev_filter_req, 1, DBG_SET_SEV_FILTER_CFM, NULL); -+} -+ -+int bl_send_dbg_get_sys_stat_req(struct bl_hw *bl_hw, -+ struct dbg_get_sys_stat_cfm *cfm) -+{ -+ void *req; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Allocate the message */ -+ req = bl_msg_zalloc(DBG_GET_SYS_STAT_REQ, TASK_DBG, DRV_TASK_ID, 0); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Send the DBG_MEM_READ_REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, req, 1, DBG_GET_SYS_STAT_CFM, cfm); -+} -+ -+int bl_send_cfg_rssi_req(struct bl_hw *bl_hw, u8 vif_index, int rssi_thold, u32 rssi_hyst) -+{ -+ struct mm_cfg_rssi_req *req; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Build the MM_CFG_RSSI_REQ message */ -+ req = bl_msg_zalloc(MM_CFG_RSSI_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_cfg_rssi_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the MM_CFG_RSSI_REQ message */ -+ req->vif_index = vif_index; -+ req->rssi_thold = (s8)rssi_thold; -+ req->rssi_hyst = (u8)rssi_hyst; -+ -+ /* Send the MM_CFG_RSSI_REQ message to LMAC FW */ -+ return bl_send_msg(bl_hw, req, 0, 0, NULL); -+} -+ -diff -Naur /dev/null_msg_tx.h b/drivers/net/wireless/hflps170/bl_msg_tx.h ---- /dev/null_msg_tx.h 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_msg_tx.h 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,103 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file bl_msg_tx.h -+ * -+ * @brief TX function declarations -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ **************************************************************************************** -+ */ -+ -+#ifndef _BL_MSG_TX_H_ -+#define _BL_MSG_TX_H_ -+ -+#include "bl_defs.h" -+ -+/* -+ * c.f LMAC/src/co/mac/mac_frame.h -+ */ -+#define MAC_RSNIE_CIPHER_WEP40 0x00 -+#define MAC_RSNIE_CIPHER_TKIP 0x01 -+#define MAC_RSNIE_CIPHER_CCMP 0x02 -+#define MAC_RSNIE_CIPHER_WEP104 0x03 -+#define MAC_RSNIE_CIPHER_SMS4 0x04 -+#define MAC_RSNIE_CIPHER_AES_CMAC 0x05 -+ -+enum bl_chan_types { -+ PHY_CHNL_BW_20, -+ PHY_CHNL_BW_40, -+ PHY_CHNL_BW_80, -+ PHY_CHNL_BW_160, -+ PHY_CHNL_BW_80P80, -+ PHY_CHNL_BW_OTHER, -+}; -+ -+int bl_send_reset(struct bl_hw *bl_hw); -+int bl_send_start(struct bl_hw *bl_hw); -+int bl_send_version_req(struct bl_hw *bl_hw, struct mm_version_cfm *cfm); -+int bl_send_add_if(struct bl_hw *bl_hw, const unsigned char *mac, -+ enum nl80211_iftype iftype, bool p2p, struct mm_add_if_cfm *cfm); -+int bl_send_remove_if(struct bl_hw *bl_hw, u8 vif_index); -+int bl_send_set_channel(struct bl_hw *bl_hw, int phy_idx, -+ struct mm_set_channel_cfm *cfm); -+int bl_send_key_add(struct bl_hw *bl_hw, u8 vif_idx, u8 sta_idx, bool pairwise, -+ u8 *key, u8 key_len, u8 key_idx, u8 cipher_suite, -+ struct mm_key_add_cfm *cfm); -+int bl_send_key_del(struct bl_hw *bl_hw, uint8_t hw_key_idx); -+int bl_send_bcn_change(struct bl_hw *bl_hw, u8 vif_idx, u8 *buf, -+ u16 bcn_len, u16 tim_oft, u16 tim_len, u16 *csa_oft); -+int bl_send_tim_update(struct bl_hw *bl_hw, u8 vif_idx, u16 aid, -+ u8 tx_status); -+int bl_send_roc(struct bl_hw *bl_hw, struct bl_vif *vif, -+ struct ieee80211_channel *chan, unsigned int duration); -+int bl_send_cancel_roc(struct bl_hw *bl_hw); -+int bl_send_set_power(struct bl_hw *bl_hw, u8 vif_idx, s8 pwr, -+ struct mm_set_power_cfm *cfm); -+int bl_send_set_edca(struct bl_hw *bl_hw, u8 hw_queue, u32 param, -+ bool uapsd, u8 inst_nbr); -+ -+int bl_send_me_config_req(struct bl_hw *bl_hw); -+int bl_send_me_chan_config_req(struct bl_hw *bl_hw); -+int bl_send_me_set_control_port_req(struct bl_hw *bl_hw, bool opened, -+ u8 sta_idx); -+int bl_send_me_sta_add(struct bl_hw *bl_hw, struct station_parameters *params, -+ const u8 *mac, u8 inst_nbr, struct me_sta_add_cfm *cfm); -+int bl_send_me_sta_del(struct bl_hw *bl_hw, u8 sta_idx, bool tdls_sta); -+int bl_send_me_traffic_ind(struct bl_hw *bl_hw, u8 sta_idx, bool uapsd, u8 tx_status); -+int bl_send_me_rc_stats(struct bl_hw *bl_hw, u8 sta_idx, -+ struct me_rc_stats_cfm *cfm); -+int bl_send_me_rc_set_rate(struct bl_hw *bl_hw, -+ u8 sta_idx, -+ u16 rate_idx); -+int bl_send_sm_connect_req(struct bl_hw *bl_hw, -+ struct bl_vif *bl_vif, -+ struct cfg80211_connect_params *sme, -+ struct sm_connect_cfm *cfm); -+int bl_send_sm_disconnect_req(struct bl_hw *bl_hw, -+ struct bl_vif *bl_vif, -+ u16 reason); -+int bl_send_apm_start_req(struct bl_hw *bl_hw, struct bl_vif *vif, -+ struct cfg80211_ap_settings *settings, -+ struct apm_start_cfm *cfm, struct bl_dma_elem *elem); -+int bl_send_apm_stop_req(struct bl_hw *bl_hw, struct bl_vif *vif); -+int bl_send_scanu_req(struct bl_hw *bl_hw, struct bl_vif *bl_vif, -+ struct cfg80211_scan_request *param); -+int bl_send_apm_start_cac_req(struct bl_hw *bl_hw, struct bl_vif *vif, -+ struct cfg80211_chan_def *chandef, -+ struct apm_start_cac_cfm *cfm); -+int bl_send_apm_stop_cac_req(struct bl_hw *bl_hw, struct bl_vif *vif); -+/* Debug messages */ -+int bl_send_dbg_trigger_req(struct bl_hw *bl_hw, char *msg); -+int bl_send_dbg_mem_read_req(struct bl_hw *bl_hw, u32 mem_addr, -+ struct dbg_mem_read_cfm *cfm); -+int bl_send_dbg_mem_write_req(struct bl_hw *bl_hw, u32 mem_addr, -+ u32 mem_data); -+int bl_send_dbg_set_mod_filter_req(struct bl_hw *bl_hw, u32 filter); -+int bl_send_dbg_set_sev_filter_req(struct bl_hw *bl_hw, u32 filter); -+int bl_send_dbg_get_sys_stat_req(struct bl_hw *bl_hw, -+ struct dbg_get_sys_stat_cfm *cfm); -+int bl_send_cfg_rssi_req(struct bl_hw *bl_hw, u8 vif_index, int rssi_thold, u32 rssi_hyst); -+ -+#endif /* _BL_MSG_TX_H_ */ -diff -Naur /dev/null_platform.c b/drivers/net/wireless/hflps170/bl_platform.c ---- /dev/null_platform.c 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_platform.c 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,137 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file bl_platform.c -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ ****************************************************************************** -+ */ -+ -+#include -+#include -+ -+#include "bl_platform.h" -+#include "bl_irqs.h" -+#include "hal_desc.h" -+#include "bl_main.h" -+#include "bl_sdio.h" -+ -+/** -+ * bl_platform_on - Start the platform -+ * -+ * @bl_hw Main driver data -+ * -+ * It starts the platform : -+ * - load fw and ucodes -+ * - initialize IPC -+ * - boot the fw -+ * - enable link communication/IRQ -+ * -+ * Called by 802.11 part -+ */ -+int bl_platform_on(struct bl_hw *bl_hw) -+{ -+ struct bl_plat *bl_plat = bl_hw->plat; -+ int ret; -+ int count = 0; -+ u8 fw_ready = 0; -+ -+ if (bl_plat->enabled) -+ return 0; -+ -+ if ((ret = bl_ipc_init(bl_hw))) -+ return ret; -+ -+ //BL_DBG("start firmware...\n"); -+ //bl_write_reg(bl_hw, 0x60, 1); -+ //msleep(500); -+ -+ printk("Wait firmware...\n"); -+ do { -+ bl_read_reg(bl_hw, 0x60, &fw_ready); -+ printk("FW Mark %c:%x\n", fw_ready, fw_ready); -+ count++; -+ msleep(100); -+ } while ('B' != fw_ready && count<50);//TODO put 'B' into header file -+ msleep(500); -+ -+ if(count >= 50) -+ return -1; -+ -+ -+ bl_plat->enabled = true; -+ -+ return 0; -+} -+ -+/** -+ * bl_platform_off - Stop the platform -+ * -+ * @bl_hw Main driver data -+ * -+ * Called by 802.11 part -+ */ -+void bl_platform_off(struct bl_hw *bl_hw) -+{ -+ if (!bl_hw->plat->enabled) -+ return; -+ -+ bl_ipc_deinit(bl_hw); -+ bl_hw->plat->enabled = false; -+} -+ -+/** -+ * bl_platform_init - Initialize the platform -+ * -+ * @bl_plat platform data (already updated by platform driver) -+ * @platform_data Pointer to store the main driver data pointer (aka bl_hw) -+ * That will be set as driver data for the platform driver -+ * @return 0 on success, < 0 otherwise -+ * -+ * Called by the platform driver after it has been probed -+ */ -+int bl_platform_init(struct bl_plat *bl_plat, void **platform_data) -+{ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ bl_plat->enabled = false; -+ -+ return bl_cfg80211_init(bl_plat, platform_data); -+} -+ -+/** -+ * bl_platform_deinit - Deinitialize the platform -+ * -+ * @bl_hw ain driver data -+ * -+ * Called by the platform driver after it is removed -+ */ -+void bl_platform_deinit(struct bl_hw *bl_hw) -+{ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ bl_cfg80211_deinit(bl_hw); -+} -+ -+/** -+ * bl_platform_register_drv - Register all possible platform drivers -+ */ -+int bl_platform_register_drv(void) -+{ -+ return bl_sdio_register_drv(); -+} -+ -+ -+/** -+ * bl_platform_unregister_drv - Unegister all platform drivers -+ */ -+void bl_platform_unregister_drv(void) -+{ -+ return bl_sdio_unregister_drv(); -+} -+ -+MODULE_FIRMWARE(BL_AGC_FW_NAME); -+MODULE_FIRMWARE(BL_FCU_FW_NAME); -+MODULE_FIRMWARE(BL_LDPC_RAM_NAME); -+MODULE_FIRMWARE(BL_MAC_FW_NAME); -diff -Naur /dev/null_platform.h b/drivers/net/wireless/hflps170/bl_platform.h ---- /dev/null_platform.h 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_platform.h 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,89 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file bl_platorm.h -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ ****************************************************************************** -+ */ -+ -+#ifndef _BL_PLAT_H_ -+#define _BL_PLAT_H_ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define BL_CONFIG_FW_NAME "bl_settings.ini" -+#define BL_PHY_CONFIG_TRD_NAME "bl_trident.ini" -+#define BL_PHY_CONFIG_KARST_NAME "bl_karst.ini" -+#define BL_AGC_FW_NAME "agcram.bin" -+#define BL_LDPC_RAM_NAME "ldpcram.bin" -+#define BL_MAC_FW_NAME "fmacfw.bin" -+ -+#define BL_FCU_FW_NAME "fcuram.bin" -+ -+/** -+ * Type of memory to access (cf bl_plat.get_address) -+ * -+ * @BL_ADDR_CPU To access memory of the embedded CPU -+ * @BL_ADDR_SYSTEM To access memory/registers of one subsystem of the -+ * embedded system -+ * -+ */ -+enum bl_platform_addr { -+ BL_ADDR_CPU, -+ BL_ADDR_SYSTEM, -+ BL_ADDR_MAX, -+}; -+ -+struct bl_hw; -+ -+/** -+ * @pci_dev pointer to pci dev -+ * @enabled Set if embedded platform has been enabled (i.e. fw loaded and -+ * ipc started) -+ * @enable Configure communication with the fw (i.e. configure the transfers -+ * enable and register interrupt) -+ * @disable Stop communication with the fw -+ * @deinit Free all ressources allocated for the embedded platform -+ * @get_address Return the virtual address to access the requested address on -+ * the platform. -+ * @ack_irq Acknowledge the irq at link level. -+ * -+ * @priv Private data for the link driver -+ */ -+struct bl_plat { -+ struct sdio_func *func; -+ bool enabled; -+ -+ u8 *mp_regs; -+ u32 mp_rd_bitmap; -+ u32 mp_wr_bitmap; -+ -+ u8 curr_rd_port; -+ u8 curr_wr_port; -+ -+ u32 io_port; -+ -+ u8 priv[0] __aligned(sizeof(void *)); -+}; -+ -+int bl_platform_init(struct bl_plat *bl_plat, void **platform_data); -+void bl_platform_deinit(struct bl_hw *bl_hw); -+ -+int bl_platform_on(struct bl_hw *bl_hw); -+void bl_platform_off(struct bl_hw *bl_hw); -+ -+int bl_platform_register_drv(void); -+void bl_platform_unregister_drv(void); -+ -+static inline struct device *bl_platform_get_dev(struct bl_plat *bl_plat) -+{ -+ return &(bl_plat->func->dev); -+} -+ -+#endif /* _BL_PLAT_H_ */ -diff -Naur /dev/null_sdio.c b/drivers/net/wireless/hflps170/bl_sdio.c ---- /dev/null_sdio.c 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_sdio.c 2020-12-28 12:36:56.000000000 +0200 -@@ -0,0 +1,1437 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "bl_defs.h" -+#include "bl_v7.h" -+ -+#include "bl_sdio.h" -+#include "bl_bootrom.h" -+ -+ -+#define SDIO_VENDOR_ID_BFL 0x424c -+#define SD_DEVICE_ID_BFL 0x0606 -+ -+ -+#define BOOTROM_SDIO_PORT_USED 0x0001 -+#define BOOTROM_CMD_BUFFER_SIZE (1024 * 2) -+#define BOOTROM_DATA_BUFFER_SIZE (512 * 2 * 2) -+ -+#define BOOTROM_SDIO_TEST_READ_BLOCK_COUNT (4 * 8) -+#define BOOTROM_SDIO_TEST_READ_LOOP_COUNT (1024 * 100) -+#define BOOTROM_SDIO_TEST_WRITE_BLOCK_COUNT (4 * 8) -+#define BOOTROM_SDIO_TEST_WRITE_LOOP_COUNT (1024 * 100) -+static int count = 0; -+unsigned long time_start, time_end, time_diff, time_ms; -+extern unsigned long volatile jiffies; -+ -+ -+static const struct sdio_device_id bl_sdio_ids[] = { -+ {SDIO_DEVICE(SDIO_VENDOR_ID_BFL, SD_DEVICE_ID_BFL)}, -+ {0,} -+}; -+MODULE_DEVICE_TABLE(sdio, bl_sdio_ids); -+ -+void bl_get_rd_len(struct bl_hw *bl_hw, u32 reg_l, u32 reg_u, u32 *len) -+{ -+ u8 rd_len_l = 0; -+ u8 rd_len_u = 0; -+ -+ bl_read_reg(bl_hw, reg_l, &rd_len_l); -+ bl_read_reg(bl_hw, reg_u, &rd_len_u); -+ -+ *len = (rd_len_u << 8) + rd_len_l; -+} -+/* -+ * This function gets the read port. -+ * -+ * If control port bit is set in MP read bitmap, the control port -+ * is returned, otherwise the current read port is returned and -+ * the value is increased (provided it does not reach the maximum -+ * limit, in which case it is reset to 1) -+ */ -+int bl_get_rd_port(struct bl_hw *bl_hw, u32 *port) -+{ -+ struct bl_device *bl_device; -+ u32 rd_bitmap = bl_hw->plat->mp_rd_bitmap; -+ bl_device = (struct bl_device *)(bl_hw->plat->priv); -+ -+ if (!(rd_bitmap & (CTRL_PORT_MASK | bl_device->reg->data_port_mask))) { -+ return -EBUSY; -+ } -+ -+ if ((bl_device->has_control_mask) && (bl_hw->plat->mp_rd_bitmap & CTRL_PORT_MASK)) { -+ bl_hw->plat->mp_rd_bitmap &= (u32) (~CTRL_PORT_MASK); -+ *port = CTRL_PORT; -+ BL_DBG("ctrl: port=%d rd_bitmap=0x%08x -> 0x%08x\n", -+ *port, rd_bitmap, bl_hw->plat->mp_rd_bitmap); -+ return 0; -+ } -+ -+ if (!(bl_hw->plat->mp_rd_bitmap & (1 << bl_hw->plat->curr_rd_port))) -+ return -1; -+ -+ /* We are now handling the SDIO data ports */ -+ bl_hw->plat->mp_rd_bitmap &= (u32)(~(1 << bl_hw->plat->curr_rd_port)); -+ *port = bl_hw->plat->curr_rd_port; -+ -+ if (++(bl_hw->plat->curr_rd_port) == MAX_PORT_NUM) -+ bl_hw->plat->curr_rd_port = bl_device->reg->start_rd_port; -+ -+ BL_DBG("data: port=%d rd_bitmap=0x%08x -> 0x%08x\n", -+ *port, rd_bitmap, bl_hw->plat->mp_rd_bitmap); -+ -+ return 0; -+} -+ -+/* -+ * This function gets the write port for data. -+ * -+ * The current write port is returned if available and the value is -+ * increased (provided it does not reach the maximum limit, in which -+ * case it is reset to 1) -+ */ -+int bl_get_wr_port(struct bl_hw *bl_hw, u32 *port) -+{ -+ struct bl_device *bl_device; -+ u32 wr_bitmap = bl_hw->plat->mp_wr_bitmap; -+ bl_device = (struct bl_device *)(bl_hw->plat->priv); -+ -+ if (!(wr_bitmap & bl_device->reg->data_port_mask)) { -+ printk("no available port\n"); -+ return -EBUSY; -+ } -+ -+ if (wr_bitmap & (1 << bl_hw->plat->curr_wr_port)) { -+ bl_hw->plat->mp_wr_bitmap &= (u32) (~(1 << bl_hw->plat->curr_wr_port)); -+ *port = bl_hw->plat->curr_wr_port; -+ if (++(bl_hw->plat->curr_wr_port) == MAX_PORT_NUM) -+ bl_hw->plat->curr_wr_port = bl_device->reg->start_wr_port; -+ } else { -+ printk("no available port\n"); -+ return -EBUSY; -+ } -+ -+ BL_DBG("data: port=%d wr_bitmap=0x%08x -> 0x%08x\n", -+ *port, wr_bitmap, bl_hw->plat->mp_wr_bitmap); -+ -+ return 0; -+} -+ -+/* -+ * This function writes multiple data into SDIO card memory. -+ * -+ * This does not work in suspended mode. -+ */ -+int bl_write_data_sync_dnldfw(struct bl_plat *bl_hw, u8 *buffer, u32 pkt_len, u32 port) -+{ -+ int ret; -+ u8 blk_mode = (pkt_len < BL_SDIO_BLOCK_SIZE) ? BYTE_MODE : BLOCK_MODE; -+ u32 blk_size = (blk_mode == BLOCK_MODE) ? BL_SDIO_BLOCK_SIZE : 1; -+ u32 blk_cnt = (blk_mode == BLOCK_MODE) ? ((pkt_len + BL_SDIO_BLOCK_SIZE -1)/BL_SDIO_BLOCK_SIZE) : pkt_len; -+ -+ u32 ioport = (port & BL_SDIO_IO_PORT_MASK); -+ -+ sdio_claim_host(bl_hw->func); -+ ret = sdio_writesb(bl_hw->func, ioport, buffer, blk_cnt * blk_size); -+ sdio_release_host(bl_hw->func); -+ -+ return ret; -+} -+ -+/* -+ * This function reads multiple data from SDIO card memory. -+ */ -+int bl_read_data_sync_dnldfw(struct bl_plat *bl_hw, u8 *buffer, u32 len, u32 port) -+{ -+ int ret; -+ u8 blk_mode = (len < BL_SDIO_BLOCK_SIZE) ? BYTE_MODE : BLOCK_MODE; -+ u32 blk_size = (blk_mode == BLOCK_MODE) ? BL_SDIO_BLOCK_SIZE : 1; -+ u32 blk_cnt = (blk_mode == BLOCK_MODE) ? ((len + BL_SDIO_BLOCK_SIZE -1)/BL_SDIO_BLOCK_SIZE) : len; -+ u32 ioport = (port & BL_SDIO_IO_PORT_MASK); -+ -+ sdio_claim_host(bl_hw->func); -+ ret = sdio_readsb(bl_hw->func, buffer, ioport, blk_cnt * blk_size); -+ sdio_release_host(bl_hw->func); -+ -+ return ret; -+} -+ -+ -+/* -+ * This function reads data from SDIO card register. -+ */ -+static int bl_sdio_read_reg(struct bl_plat *card, u32 reg, u8 *data) -+{ -+ int ret = -1; -+ u8 val; -+ -+ val = sdio_readb(card->func, reg, &ret); -+ -+ *data = val; -+ -+ return ret; -+} -+ -+/* -+ * This function write data to SDIO card register. -+ */ -+static int bl_sdio_write_reg(struct bl_plat *card, u32 reg, u8 data) -+{ -+ int ret; -+ -+ sdio_writeb(card->func, data, reg, &ret); -+ -+ return ret; -+} -+ -+//TODO TIMEOUT value -+static int bl_io_write(struct bl_plat *card, u8* data, int len) -+{ -+ u8 wr_bitmap_l = 0; -+ u8 wr_bitmap_u = 0; -+ u32 bitmap = 0; -+ int ret; -+ -+ //SDIO_DBG(SDIO_FN_ENTRY_STR); -+ -+#if 0 -+ data[len - 1] = 0xFF; -+ data[len - 2] = 0xFE; -+ data[len - 3] = 0xFD; -+ data[len - 4] = 0xFC; -+ data[len - 5] = 0xFB; -+ data[len - 6] = 0xFA; -+#endif -+ count++; -+ -+ while (0 == (bitmap & (1 << card->curr_wr_port))) { -+ bl_sdio_read_reg(card, WR_BITMAP_L, &wr_bitmap_l); -+ bl_sdio_read_reg(card, WR_BITMAP_U, &wr_bitmap_u); -+ bitmap = wr_bitmap_l; -+ bitmap |= wr_bitmap_u << 8; -+#if 0 -+ printk("bl_io_write: wr_bitmap=0x%x, count %d, curr_wr_port %d\n", -+ bitmap, count, card->curr_wr_port); -+#endif -+ //msleep(500); -+ } -+ printk("bl_io_write: wr_bitmap=0x%x, count %d\n", bitmap, count); -+ ret = bl_write_data_sync_dnldfw(card, data, len, card->io_port + card->curr_wr_port); -+#if 0 -+ if ((++(card->curr_wr_port)) == 4) { -+ card->curr_wr_port = 0; -+ } -+#endif -+ //printk("%s: ret %d\n", __func__, ret); -+ -+ //SDIO_DBG(SDIO_FN_LEAVE_STR); -+ -+ return 0; -+} -+ -+//caller must free the memory -+int bl_io_read(struct bl_plat *card, u8 *buf, int rd_len) -+{ -+ u8 rd_bitmap_l = 0; -+ u8 rd_bitmap_u = 0; -+ u32 bitmap = 0; -+ -+#if 0 -+ SDIO_DBG(SDIO_FN_ENTRY_STR); -+#endif -+ -+#if 1 -+ while (0 == (bitmap & (1 << card->curr_rd_port))) { -+ bl_sdio_read_reg(card, RD_BITMAP_L, &rd_bitmap_l); -+ bl_sdio_read_reg(card, RD_BITMAP_U, &rd_bitmap_u); -+ bitmap = rd_bitmap_l; -+ bitmap |= rd_bitmap_u << 8; -+ card->mp_rd_bitmap = bitmap; -+#if 0 -+ printk("int: UPLD: rd_bitmap=0x%x\n", card->mp_rd_bitmap); -+#endif -+ //msleep(500); -+ } -+#endif -+ -+#if 1 -+ bl_read_data_sync_dnldfw(card, buf, rd_len, card->io_port + card->curr_rd_port); -+#endif -+#if 1 -+ printk("[XXX] len:%d--->receive ok\n", rd_len); -+ printk("Read 00: %02X %02X %02X %02X %02X %02X %02X %02X\n" -+ "Read 10: %02X %02X %02X %02X %02X %02X %02X %02X\n" -+ "Read 20: %02X %02X %02X %02X %02X %02X %02X %02X\n", -+ buf[0], buf[1], -+ buf[2], buf[3], -+ buf[4], buf[5], -+ buf[6], buf[7], -+ buf[8 + 0], buf[8 + 1], -+ buf[8 + 2], buf[8 + 3], -+ buf[8 + 4], buf[8 + 5], -+ buf[8 + 6], buf[8 + 7], -+ buf[16 + 0], buf[16 + 1], -+ buf[16 + 2], buf[16 + 3], -+ buf[16 + 4], buf[16 + 5], -+ buf[16 + 6], buf[16 + 7] -+ ); -+#endif -+#if 0 -+ if ((++(card->curr_rd_port)) == 4) { -+ card->curr_rd_port = 0; -+ } -+#endif -+#if 0 -+ SDIO_DBG(SDIO_FN_LEAVE_STR); -+#endif -+ -+ return 0; -+} -+ -+static int bl_sdio_run_fw(struct bl_plat *card) -+{ -+ int ret; -+ -+ printk("Enter bl_sdio_run_fw...\n"); -+ ret = bl_sdio_write_reg(card, CARD_FW_STATUS0_REG, 0x1); -+ -+ return ret; -+ -+} -+ -+static int firmware_dump_head(bootheader_t *header) -+{ -+ int i; -+ -+ printk("[************Header************]\n"); -+ printk(" magiccode: 0x%X\n", header->magiccode); -+ printk(" rivison: 0x%X\n", header->rivison); -+ printk(" flashCfg\n"); -+ printk(" magiccode: 0x%X\n", header->flashCfg.magiccode); -+ printk(" cfg see below, size: %lu\n", sizeof(header->flashCfg.cfg)); -+ printk(" crc32: 0x%X\n", header->flashCfg.crc32); -+ printk(" pllCfg\n"); -+ printk(" magiccode: 0x%X\n", header->pllCfg.magiccode); -+ printk(" root_clk: %u\n", header->pllCfg.root_clk); -+ printk(" xtal_type: %u\n", header->pllCfg.xtal_type); -+ printk(" pll_clk: %u\n", header->pllCfg.pll_clk); -+ printk(" hclk_div: %u\n", header->pllCfg.hclk_div); -+ printk(" bclk_div: %u\n", header->pllCfg.bclk_div); -+ printk(" flash_clk_div: %u\n", header->pllCfg.flash_clk_div); -+ printk(" uart_clk_div: %u\n", header->pllCfg.uart_clk_div); -+ printk(" sdu_clk_div: %u\n", header->pllCfg.sdu_clk_div); -+ printk(" crc32: 0x%X\n", header->pllCfg.crc32); -+ printk(" seccfg\n"); -+ printk(" bval in union\n"); -+ printk(" encrypt: %u\n", header->seccfg.bval.encrypt); -+ printk(" sign: %u\n", header->seccfg.bval.sign); -+ printk(" key_sel: %u\n", header->seccfg.bval.key_sel); -+ printk(" rsvd6_31: %u\n", header->seccfg.bval.rsvd6_31); -+ printk(" wval in union\n"); -+ printk(" wval: 0x%X\n", header->seccfg.wval); -+ printk(" segment_cnt: %u\n", header->segment_cnt); -+ printk(" bootentry: 0x%X\n", header->bootentry); -+ printk(" flashoffset: 0x%X\n", header->flashoffset); -+ printk(" bootentry: 0x%X\n", header->bootentry); -+ printk(" hash:\n"); -+ -+ for (i = 0; i < sizeof(header->hash); i+=4) { -+ //XXX we may access over-flow -+ printk("0x%08X ", ((uint32_t)header->hash[i]) << 24 | -+ (uint32_t)header->hash[i + 1] << 16 | -+ (uint32_t)header->hash[i + 2] << 8 | -+ (uint32_t)header->hash[i + 3] << 0 -+ ); -+ } -+ -+ -+ printk(" rsv1: %u\n", header->rsv1); -+ printk(" rsv2: %u\n", header->rsv2); -+ printk(" crc32: 0x%X\n", header->crc32); -+ printk("--------\n"); -+ -+ return 0; -+} -+ -+static int firmware_dump_flashcfg(const boot_flash_cfg_t *cfg) -+{ -+ printk("[************FLASH CFG(%lu)************]\n", sizeof(boot_flash_cfg_t)); -+ printk(" magiccode: 0x%X\n", cfg->magiccode); -+ printk(" flash cfg\n"); -+ printk(" ioMode: %u\n", cfg->cfg.ioMode); -+ printk(" cReadSupport: %u\n", cfg->cfg.cReadSupport); -+ printk(" clk_delay;: %u\n", cfg->cfg.clk_delay); -+ printk(" rsvd[1]: %X\n", cfg->cfg.rsvd[0]); -+ printk(" resetEnCmd: %u\n", cfg->cfg.resetEnCmd); -+ printk(" resetCmd: %u\n", cfg->cfg.resetCmd); -+ printk(" resetCreadCmd: %u\n", cfg->cfg.resetCreadCmd); -+ printk(" rsvd_reset[1]: %X\n", cfg->cfg.rsvd_reset[0]); -+ printk(" jedecIdCmd: %u(0x%X)\n", cfg->cfg.jedecIdCmd, cfg->cfg.jedecIdCmd); -+ printk(" jedecIdCmdDmyClk: %u(0x%X)\n", cfg->cfg.jedecIdCmdDmyClk, cfg->cfg.jedecIdCmdDmyClk); -+ printk(" qpiJedecIdCmd: %u(0x%X)\n", cfg->cfg.qpiJedecIdCmd, cfg->cfg.qpiJedecIdCmd); -+ printk(" qpiJedecIdCmdDmyClk: %u(0x%X)\n", cfg->cfg.qpiJedecIdCmdDmyClk, cfg->cfg.qpiJedecIdCmdDmyClk); -+ printk(" sectorSize: %u(0x%X)\n", cfg->cfg.sectorSize, cfg->cfg.sectorSize); -+ printk(" capBase: %u(0x%X)\n", cfg->cfg.capBase, cfg->cfg.capBase); -+ printk(" pageSize: %u(0x%X)\n", cfg->cfg.pageSize, cfg->cfg.pageSize); -+ printk(" chipEraseCmd: %u(0x%X)\n", cfg->cfg.chipEraseCmd, cfg->cfg.chipEraseCmd); -+ printk(" sectorEraseCmd: %u(0x%X)\n", cfg->cfg.sectorEraseCmd, cfg->cfg.sectorEraseCmd); -+ printk(" blk32EraseCmd: %u(0x%X)\n", cfg->cfg.blk32EraseCmd, cfg->cfg.blk32EraseCmd); -+ printk(" blk64EraseCmd: %u(0x%X)\n", cfg->cfg.blk64EraseCmd, cfg->cfg.blk64EraseCmd); -+ printk(" writeEnableCmd: %u(0x%X)\n", cfg->cfg.writeEnableCmd, cfg->cfg.writeEnableCmd); -+ printk(" pageProgramCmd: %u(0x%X)\n", cfg->cfg.pageProgramCmd, cfg->cfg.pageProgramCmd); -+ printk(" qpageProgramCmd: %u(0x%X)\n", cfg->cfg.qpageProgramCmd, cfg->cfg.qpageProgramCmd); -+ printk(" qppAddrMode: %u(0x%X)\n", cfg->cfg.qppAddrMode, cfg->cfg.qppAddrMode); -+ printk(" fastReadCmd: %u(0x%X)\n", cfg->cfg.fastReadCmd, cfg->cfg.fastReadCmd); -+ printk(" frDmyClk: %u(0x%X)\n", cfg->cfg.frDmyClk, cfg->cfg.frDmyClk); -+ printk(" qpiFastReadCmd: %u(0x%X)\n", cfg->cfg.qpiFastReadCmd, cfg->cfg.qpiFastReadCmd); -+ printk(" qpiFrDmyClk: %u(0x%X)\n", cfg->cfg.qpiFrDmyClk, cfg->cfg.qpiFrDmyClk); -+ printk(" fastReadDoCmd: %u(0x%X)\n", cfg->cfg.fastReadDoCmd, cfg->cfg.fastReadDoCmd); -+ printk(" frDoDmyClk: %u(0x%X)\n", cfg->cfg.frDoDmyClk, cfg->cfg.frDoDmyClk); -+ printk(" fastReadDioCmd: %u(0x%X)\n", cfg->cfg.fastReadDioCmd, cfg->cfg.fastReadDioCmd); -+ printk(" frDioDmyClk: %u(0x%X)\n", cfg->cfg.frDioDmyClk, cfg->cfg.frDioDmyClk); -+ printk(" fastReadQoCmd: %u(0x%X)\n", cfg->cfg.fastReadQoCmd, cfg->cfg.fastReadQoCmd); -+ printk(" frQoDmyClk: %u(0x%X)\n", cfg->cfg.frQoDmyClk, cfg->cfg.frQoDmyClk); -+ printk(" fastReadQioCmd: %u(0x%X)\n", cfg->cfg.fastReadQioCmd, cfg->cfg.fastReadQioCmd); -+ printk(" frQioDmyClk: %u(0x%X)\n", cfg->cfg.frQioDmyClk, cfg->cfg.frQioDmyClk); -+ printk(" qpiFastReadQioCmd: %u(0x%X)\n", cfg->cfg.qpiFastReadQioCmd, cfg->cfg.qpiFastReadQioCmd); -+ printk(" qpiFrQioDmyClk: %u(0x%X)\n", cfg->cfg.qpiFrQioDmyClk, cfg->cfg.qpiFrQioDmyClk); -+ printk(" qpiPageProgramCmd: %u(0x%X)\n", cfg->cfg.qpiPageProgramCmd, cfg->cfg.qpiPageProgramCmd); -+ printk(" writeVregEnableCmd: %u(0x%X)\n", cfg->cfg.writeVregEnableCmd, cfg->cfg.writeVregEnableCmd); -+ printk(" wrEnableIndex: %u(0x%X)\n", cfg->cfg.wrEnableIndex, cfg->cfg.wrEnableIndex); -+ printk(" qeIndex: %u(0x%X)\n", cfg->cfg.qeIndex, cfg->cfg.qeIndex); -+ printk(" busyIndex: %u(0x%X)\n", cfg->cfg.busyIndex, cfg->cfg.busyIndex); -+ printk(" wrEnableBit: %u(0x%X)\n", cfg->cfg.wrEnableBit, cfg->cfg.wrEnableBit); -+ printk(" qeBit: %u(0x%X)\n", cfg->cfg.qeBit, cfg->cfg.qeBit); -+ printk(" busyBit: %u(0x%X)\n", cfg->cfg.busyBit, cfg->cfg.busyBit); -+ printk(" wrEnableWriteRegLen: %u(0x%X)\n", cfg->cfg.wrEnableWriteRegLen, cfg->cfg.wrEnableWriteRegLen); -+ printk(" wrEnableReadRegLen: %u(0x%X)\n", cfg->cfg.wrEnableReadRegLen, cfg->cfg.wrEnableReadRegLen); -+ printk(" qeWriteRegLen: %u(0x%X)\n", cfg->cfg.qeWriteRegLen, cfg->cfg.qeWriteRegLen); -+ printk(" qeReadRegLen: %u(0x%X)\n", cfg->cfg.qeReadRegLen, cfg->cfg.qeReadRegLen); -+ printk(" rsvd1: %u(0x%X)\n", cfg->cfg.rsvd1, cfg->cfg.rsvd1); -+ printk(" busyReadRegLen: %u(0x%X)\n", cfg->cfg.busyReadRegLen, cfg->cfg.busyReadRegLen); -+ printk(" readRegCmd[4]: %u(0x%X), %u(0x%X), %u(0x%X), %u(0x%X)\n", -+ cfg->cfg.readRegCmd[0], cfg->cfg.readRegCmd[0], -+ cfg->cfg.readRegCmd[1], cfg->cfg.readRegCmd[1], -+ cfg->cfg.readRegCmd[2], cfg->cfg.readRegCmd[2], -+ cfg->cfg.readRegCmd[3], cfg->cfg.readRegCmd[3] -+ ); -+ printk(" writeRegCmd[4]: %u(0x%X), %u(0x%X), %u(0x%X), %u(0x%X)\n", -+ cfg->cfg.writeRegCmd[0], cfg->cfg.writeRegCmd[0], -+ cfg->cfg.writeRegCmd[1], cfg->cfg.writeRegCmd[1], -+ cfg->cfg.writeRegCmd[2], cfg->cfg.writeRegCmd[2], -+ cfg->cfg.writeRegCmd[3], cfg->cfg.writeRegCmd[3] -+ ); -+ printk(" enterQpi: %u(0x%X)\n", cfg->cfg.enterQpi, cfg->cfg.enterQpi); -+ printk(" exitQpi: %u(0x%X)\n", cfg->cfg.exitQpi, cfg->cfg.exitQpi); -+ printk(" cReadMode: %u(0x%X)\n", cfg->cfg.cReadMode, cfg->cfg.cReadMode); -+ printk(" cRExit: %u(0x%X)\n", cfg->cfg.cRExit, cfg->cfg.cRExit); -+ printk(" burstWrapCmd: %u(0x%X)\n", cfg->cfg.burstWrapCmd, cfg->cfg.burstWrapCmd); -+ printk(" burstWrapCmdDmyClk: %u(0x%X)\n", cfg->cfg.burstWrapCmdDmyClk, cfg->cfg.burstWrapCmdDmyClk); -+ printk(" burstWrapDataMode: %u(0x%X)\n", cfg->cfg.burstWrapDataMode, cfg->cfg.burstWrapDataMode); -+ printk(" burstWrapData: %u(0x%X)\n", cfg->cfg.burstWrapData, cfg->cfg.burstWrapData); -+ printk(" deBurstWrapCmd: %u(0x%X)\n", cfg->cfg.deBurstWrapCmd, cfg->cfg.deBurstWrapCmd); -+ printk(" deBurstWrapCmdDmyClk: %u(0x%X)\n", cfg->cfg.deBurstWrapCmdDmyClk, cfg->cfg.deBurstWrapCmdDmyClk); -+ printk(" deBurstWrapDataMode: %u(0x%X)\n", cfg->cfg.deBurstWrapDataMode, cfg->cfg.deBurstWrapDataMode); -+ printk(" deBurstWrapData: %u(0x%X)\n", cfg->cfg.deBurstWrapData, cfg->cfg.deBurstWrapData); -+ printk(" timeEsector: %u(0x%X)\n", cfg->cfg.timeEsector, cfg->cfg.timeEsector); -+ printk(" timeE32k: %u(0x%X)\n", cfg->cfg.timeE32k, cfg->cfg.timeE32k); -+ printk(" timeE64k: %u(0x%X)\n", cfg->cfg.timeE64k, cfg->cfg.timeE64k); -+ printk(" timePagePgm: %u(0x%X)\n", cfg->cfg.timePagePgm, cfg->cfg.timePagePgm); -+ printk(" timeCe: %u(0x%X)\n", cfg->cfg.timeCe, cfg->cfg.timeCe); -+ printk(" CRC32(%lu): %02X%02X%02X%02X\n", -+ sizeof(cfg->crc32), -+ (cfg->crc32 >> 24) & 0xFF, -+ (cfg->crc32 >> 16) & 0xFF, -+ (cfg->crc32 >> 8) & 0xFF, -+ (cfg->crc32 >> 0) & 0xFF -+ ); -+ printk("--------\n"); -+ -+ return 0; -+} -+ -+static int firmware_dump_pllcfg(const boot_pll_cfg_t *cfg) -+{ -+ printk("[************PLL CFG(%lu)************]\n", sizeof(boot_pll_cfg_t)); -+ printk(" magiccode: 0x%08X\n", cfg->magiccode); -+ printk(" root_clk: %u(0x%X)\n", cfg->root_clk, cfg->root_clk); -+ printk(" xtal_type: %u(0x%X)\n", cfg->xtal_type, cfg->xtal_type); -+ printk(" pll_clk: %u(0x%X)\n", cfg->pll_clk, cfg->pll_clk); -+ printk(" hclk_div: %u(0x%X)\n", cfg->hclk_div, cfg->hclk_div); -+ printk(" bclk_div: %u(0x%X)\n", cfg->bclk_div, cfg->bclk_div); -+ printk(" flash_clk_div: %u(0x%X)\n", cfg->flash_clk_div, cfg->flash_clk_div); -+ printk(" uart_clk_div: %u(0x%X)\n", cfg->uart_clk_div, cfg->uart_clk_div); -+ printk(" sdu_clk_div: %u(0x%X)\n", cfg->sdu_clk_div, cfg->sdu_clk_div); -+ printk(" CRC32(%lu): %02X%02X%02X%02X\n", -+ sizeof(cfg->crc32), -+ (cfg->crc32 >> 24) & 0xFF, -+ (cfg->crc32 >> 16) & 0xFF, -+ (cfg->crc32 >> 8) & 0xFF, -+ (cfg->crc32 >> 0) & 0xFF -+ ); -+ printk("--------\n"); -+ -+ return 0; -+} -+ -+static int firmware_dump_encryptiondata(const u8 *encryption) -+{ -+ //FIXME NOT use magic number -+ printk("[************ENCRYPTION DATA (20)************]\n"); -+ printk(" IV(16): %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X\n", -+ encryption[0], -+ encryption[1], -+ encryption[2], -+ encryption[3], -+ encryption[4], -+ encryption[5], -+ encryption[6], -+ encryption[7], -+ encryption[8], -+ encryption[9], -+ encryption[10], -+ encryption[11], -+ encryption[12], -+ encryption[13], -+ encryption[14], -+ encryption[15] -+ ); -+ printk(" CRC32(4): %02X%02X%02X%02X\n", -+ encryption[19], -+ encryption[18], -+ encryption[17], -+ encryption[16] -+ ); -+ printk("--------\n"); -+ -+ return 0; -+} -+ -+static int firmware_dump_publickey(const pkey_cfg_t *key) -+{ -+ printk("[************PUBLIC KEY DATA(%lu)************]\n", sizeof(pkey_cfg_t)); -+ printk(" public key X(%lu):\n", sizeof(key->eckeyx)); -+ printk(" %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X\n", -+ key->eckeyx[0], -+ key->eckeyx[1], -+ key->eckeyx[2], -+ key->eckeyx[3], -+ key->eckeyx[4], -+ key->eckeyx[5], -+ key->eckeyx[6], -+ key->eckeyx[7], -+ key->eckeyx[8], -+ key->eckeyx[9], -+ key->eckeyx[10], -+ key->eckeyx[11], -+ key->eckeyx[12], -+ key->eckeyx[13], -+ key->eckeyx[14], -+ key->eckeyx[15], -+ key->eckeyx[16], -+ key->eckeyx[17], -+ key->eckeyx[18], -+ key->eckeyx[19], -+ key->eckeyx[20], -+ key->eckeyx[21], -+ key->eckeyx[22], -+ key->eckeyx[23], -+ key->eckeyx[24], -+ key->eckeyx[25], -+ key->eckeyx[26], -+ key->eckeyx[27], -+ key->eckeyx[28], -+ key->eckeyx[29], -+ key->eckeyx[30], -+ key->eckeyx[31] -+ ); -+ printk(" public key Y(%lu):\n", sizeof(key->eckeyy)); -+ printk(" %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X\n", -+ key->eckeyy[0], -+ key->eckeyy[1], -+ key->eckeyy[2], -+ key->eckeyy[3], -+ key->eckeyy[4], -+ key->eckeyy[5], -+ key->eckeyy[6], -+ key->eckeyy[7], -+ key->eckeyy[8], -+ key->eckeyy[9], -+ key->eckeyy[10], -+ key->eckeyy[11], -+ key->eckeyy[12], -+ key->eckeyy[13], -+ key->eckeyy[14], -+ key->eckeyy[15], -+ key->eckeyy[16], -+ key->eckeyy[17], -+ key->eckeyy[18], -+ key->eckeyy[19], -+ key->eckeyy[20], -+ key->eckeyy[21], -+ key->eckeyy[22], -+ key->eckeyy[23], -+ key->eckeyy[24], -+ key->eckeyy[25], -+ key->eckeyy[26], -+ key->eckeyy[27], -+ key->eckeyy[28], -+ key->eckeyy[29], -+ key->eckeyy[30], -+ key->eckeyy[31] -+ ); -+ printk(" CRC32(%lu): %02X%02X%02X%02X\n", -+ sizeof(key->crc32), -+ (key->crc32 >> 24) & 0xFF, -+ (key->crc32 >> 16) & 0xFF, -+ (key->crc32 >> 8) & 0xFF, -+ (key->crc32 >> 0) & 0xFF -+ ); -+ printk("--------\n"); -+ -+ return 0; -+} -+ -+static int firmware_dump_signdata(const sign_cfg_t *sign) -+{ -+ int i; -+ -+ printk("[************SIGNATURE DATA(%lu)************]\n", sizeof(sign_cfg_t) + sign->sig_len); -+ printk(" sig_len: %u(0x%X)\n", sign->sig_len, sign->sig_len); -+ printk(" signature(%u):\n", sign->sig_len); -+ -+ for (i = 0; i < sign->sig_len; i+= 32) { -+ printk(" %03u: %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X\n", -+ i, -+ sign->signature[i + 0], -+ sign->signature[i + 1], -+ sign->signature[i + 2], -+ sign->signature[i + 3], -+ sign->signature[i + 4], -+ sign->signature[i + 5], -+ sign->signature[i + 6], -+ sign->signature[i + 7], -+ sign->signature[i + 8], -+ sign->signature[i + 9], -+ sign->signature[i + 10], -+ sign->signature[i + 11], -+ sign->signature[i + 12], -+ sign->signature[i + 13], -+ sign->signature[i + 14], -+ sign->signature[i + 15], -+ sign->signature[i + 16], -+ sign->signature[i + 17], -+ sign->signature[i + 18], -+ sign->signature[i + 19], -+ sign->signature[i + 20], -+ sign->signature[i + 21], -+ sign->signature[i + 22], -+ sign->signature[i + 23], -+ sign->signature[i + 24], -+ sign->signature[i + 25], -+ sign->signature[i + 26], -+ sign->signature[i + 27], -+ sign->signature[i + 28], -+ sign->signature[i + 29], -+ sign->signature[i + 30], -+ sign->signature[i + 31] -+ ); -+ } -+ printk(" CRC32(%lu): %02X%02X%02X%02X\n", -+ sizeof(sign->crc32), -+ sign->signature[sign->sig_len], -+ sign->signature[sign->sig_len + 1], -+ sign->signature[sign->sig_len + 2], -+ sign->signature[sign->sig_len + 3] -+ ); -+ printk("--------\n"); -+ return 0; -+} -+ -+static int firmware_dump_segment_piece(const segment_header_t *segment) -+{ -+ printk("[************SEGMENT DUMP(%lu + %u = %lu)************]\n", -+ sizeof(segment_header_t), -+ segment->len, -+ sizeof(segment_header_t) + segment->len -+ ); -+ printk(" destaddr: %u(0x%X)\n", segment->destaddr, segment->destaddr); -+ printk(" len: %u(0x%X)\n", segment->len, segment->len); -+ printk(" rsv: %u(0x%X)\n", segment->rsv, segment->rsv); -+ printk(" crc32: %u(0x%X)\n", segment->crc32, segment->crc32); -+ printk("--------\n"); -+ return 0; -+} -+ -+static int firmware_download_head(struct bl_plat *card, bootrom_host_cmd_t *cmd, u8* response, -+ bootheader_t *header, const u8 **data, int *len) -+{ -+ int ret; -+ -+ SDIO_DBG(SDIO_FN_ENTRY_STR); -+ printk("FUNC header: data ptr %p, data left %d\n", *data, *len); -+ if (*len < sizeof(bootheader_t)) { -+ printk("%s:len too small %lu:%d\n", __func__, sizeof(bootheader_t), *len); -+ return -1; -+ } -+ -+ firmware_dump_head(header); -+ -+ memset(cmd, 0, BOOTROM_CMD_BUFFER_SIZE); -+ bl_bootrom_cmd_bootheader_load(cmd, header); -+ printk("CMD bootheader len %d\n", cmd->len); -+ ret = bl_io_write(card, (u8*)cmd, BOOTROM_CMD_BUFFER_SIZE); -+ if (ret) { -+ printk("ERR when write\n"); -+ return -1; -+ } -+ ret = bl_io_read(card, response, BOOTROM_CMD_BUFFER_SIZE); -+ if (ret) { -+ printk("NULL response get"); -+ return -1; -+ } -+ bl_bootrom_cmd_bootheader_load_get_res((bootrom_res_bootheader_load_t*)response); -+ -+ *data += sizeof(bootheader_t); -+ *len -= sizeof(bootheader_t); -+ -+ SDIO_DBG(SDIO_FN_LEAVE_STR); -+ -+ return 0; -+} -+ -+static int firmware_download_flashcfg(struct bl_plat *card, bootrom_host_cmd_t *cmd, u8 *response, bootheader_t *header) -+{ -+ firmware_dump_flashcfg(&(header->flashCfg)); -+ -+ return 0; -+} -+ -+static int firmware_download_pllcfg(struct bl_plat *card, bootrom_host_cmd_t *cmd, u8* response, -+ bootheader_t *header) -+{ -+ firmware_dump_pllcfg(&(header->pllCfg)); -+ -+ return 0; -+} -+ -+static int firmware_download_encryptiondata(struct bl_plat *card, bootrom_host_cmd_t *cmd, u8 *response, -+ bootheader_t *header, const u8 **data, int *len) -+{ -+ int ret; -+ -+ SDIO_DBG(SDIO_FN_ENTRY_STR); -+ -+ printk("FUNC encryptiondata: data ptr %p, data left %d\n", *data, *len); -+ if (0 == header->seccfg.bval.encrypt) { -+ printk("no encrypt field detected\n"); -+ return 0; -+ } -+ -+ printk("%s, Offset 0x%X\n", __func__, (uint32_t)(((u8*)*data) - ((u8*)header))); -+ //FIXME NOT use magic number -+ if (*len < 20) { -+ printk("%s:len too small %d:%d\n", __func__, 20, *len); -+ return -1; -+ } -+ -+ firmware_dump_encryptiondata(*data); -+ -+ memset(cmd, 0, BOOTROM_CMD_BUFFER_SIZE); -+ bl_bootrom_cmd_aesiv_load(cmd, *data); -+ printk("CMD encryptiondata len %d\n", cmd->len); -+ ret = bl_io_write(card, (u8*)cmd, BOOTROM_CMD_BUFFER_SIZE); -+ if (ret) { -+ printk("ERR when write\n"); -+ return -1; -+ } -+ ret = bl_io_read(card, response, BOOTROM_CMD_BUFFER_SIZE); -+ if (ret) { -+ printk("NULL response get"); -+ return -1; -+ } -+ bl_bootrom_cmd_aesiv_load_get_res((bootrom_res_aesiv_load_t*)response); -+ -+ //FIXME NOT use magic number -+ *data += 20; -+ *len -= 20; -+ -+ SDIO_DBG(SDIO_FN_LEAVE_STR); -+ -+ return 0; -+} -+ -+static int firmware_download_publickey1(struct bl_plat *card, bootrom_host_cmd_t *cmd, u8 *response, -+ bootheader_t *header, const u8 **data, int *len) -+{ -+ int ret; -+ pkey_cfg_t *key; -+ -+ printk("FUNC publickey1: data ptr %p, data left %d\n", *data, *len); -+ if (0 == header->seccfg.bval.sign) { -+ printk("no sign field detected\n"); -+ return 0; -+ } -+ -+ printk("%s, Offset 0x%X\n", __func__, (uint32_t)(((u8*)*data) - ((u8*)header))); -+ key = (pkey_cfg_t*)(*data); -+ if (*len < sizeof(pkey_cfg_t)) { -+ printk("%s:len too small %lu:%d\n", __func__, sizeof(pkey_cfg_t), *len); -+ return -1; -+ } -+ firmware_dump_publickey(key); -+ -+ memset(cmd, 0, BOOTROM_CMD_BUFFER_SIZE); -+ bl_bootrom_cmd_pkey1_load(cmd, key); -+ printk("CMD public key1 len %d\n", cmd->len); -+ ret = bl_io_write(card, (u8*)cmd, BOOTROM_CMD_BUFFER_SIZE); -+ if (ret) { -+ printk("ERR when write\n"); -+ return -1; -+ } -+ ret = bl_io_read(card, response, BOOTROM_CMD_BUFFER_SIZE); -+ if (ret) { -+ printk("NULL response get"); -+ return -1; -+ } -+ ret = bl_bootrom_cmd_pkey1_load_get_res((bootrom_res_pkey_load_t*)response); -+ if (ret) { -+ printk("Error response get pkey1\n"); -+ return -1; -+ } -+ -+ *data += sizeof(pkey_cfg_t); -+ *len -= sizeof(pkey_cfg_t); -+ -+ return 0; -+} -+ -+static int firmware_download_publickey2(struct bl_plat *card, bootrom_host_cmd_t *cmd, u8 *response, -+ bootheader_t *header, const u8 **data, int *len) -+{ -+ int ret; -+ pkey_cfg_t *key; -+ -+ printk("FUNC publickey2: data ptr %p, data left %d\n", *data, *len); -+ if (0 == header->seccfg.bval.sign) { -+ printk("no sign field detected\n"); -+ return 0; -+ } -+ -+ printk("%s, Offset 0x%X\n", __func__, (uint32_t)(((u8*)*data) - ((u8*)header))); -+ key = (pkey_cfg_t*)(*data); -+ if (*len < sizeof(pkey_cfg_t)) { -+ printk("%s:len too small %lu:%d\n", __func__, sizeof(pkey_cfg_t), *len); -+ return -1; -+ } -+ firmware_dump_publickey(key); -+ -+ memset(cmd, 0, BOOTROM_CMD_BUFFER_SIZE); -+ bl_bootrom_cmd_pkey2_load(cmd, key); -+ printk("CMD public key2 len %d\n", cmd->len); -+ ret = bl_io_write(card, (u8*)cmd, BOOTROM_CMD_BUFFER_SIZE); -+ if (ret) { -+ printk("ERR when write\n"); -+ return -1; -+ } -+ ret = bl_io_read(card, response, BOOTROM_CMD_BUFFER_SIZE); -+ if (ret) { -+ printk("NULL response get"); -+ return -1; -+ } -+ ret = bl_bootrom_cmd_pkey2_load_get_res((bootrom_res_pkey_load_t*)response); -+ if (ret) { -+ printk("Error response get pkey2\n"); -+ return -1; -+ } -+ -+ *data += sizeof(pkey_cfg_t); -+ *len -= sizeof(pkey_cfg_t); -+ -+ return 0; -+} -+ -+static int firmware_download_signdata1(struct bl_plat *card, bootrom_host_cmd_t *cmd, u8 *response, -+ bootheader_t *header, const u8 **data, int *len) -+{ -+ int ret; -+ sign_cfg_t *sign; -+ -+ printk("FUNC signdata1: data ptr %p, data left %d\n", *data, *len); -+ if (0 == header->seccfg.bval.sign) { -+ printk("no sign field detected\n"); -+ return 0; -+ } -+ -+ printk("%s, Offset 0x%X\n", __func__, (uint32_t)(((u8*)*data) - ((u8*)header))); -+ sign = (sign_cfg_t*)(*data); -+ if (*len < sizeof(sign_cfg_t) + sign->sig_len) { -+ printk("%s:len too small %lu:%d\n", __func__, sizeof(sign_cfg_t), *len); -+ return -1; -+ } -+ -+ firmware_dump_signdata(sign); -+ -+ memset(cmd, 0, BOOTROM_CMD_BUFFER_SIZE); -+ bl_bootrom_cmd_signature1_load(cmd, (uint8_t*)sign, sizeof(sign_cfg_t) + sign->sig_len); -+ printk("CMD signa data1 len %d\n", cmd->len); -+ ret = bl_io_write(card, (u8*)cmd, BOOTROM_CMD_BUFFER_SIZE); -+ if (ret) { -+ printk("ERR when write\n"); -+ return -1; -+ } -+ ret = bl_io_read(card, response, BOOTROM_CMD_BUFFER_SIZE); -+ if (ret) { -+ printk("NULL response get"); -+ return -1; -+ } -+ ret = bl_bootrom_cmd_signature1_get_res((bootrom_res_signature_load_t*)response); -+ if (ret) { -+ printk("Error response get signature1\n"); -+ return -1; -+ } -+ -+ *data += (sizeof(sign_cfg_t) + sign->sig_len); -+ *len -= (sizeof(sign_cfg_t) + sign->sig_len); -+ -+ return 0; -+} -+ -+static int firmware_download_signdata2(struct bl_plat *card, bootrom_host_cmd_t *cmd, u8 *response, -+ bootheader_t *header, const u8 **data, int *len) -+{ -+ int ret; -+ sign_cfg_t *sign; -+ -+ printk("FUNC signdata2: data ptr %p, data left %d\n", *data, *len); -+ if (0 == header->seccfg.bval.sign) { -+ printk("no sign field detected\n"); -+ return 0; -+ } -+ -+ printk("%s, Offset 0x%X\n", __func__, (uint32_t)(((u8*)*data) - ((u8*)header))); -+ sign = (sign_cfg_t*)(*data); -+ if (*len < sizeof(sign_cfg_t) + sign->sig_len) { -+ printk("%s:len too small %lu:%d\n", __func__, sizeof(sign_cfg_t), *len); -+ return -1; -+ } -+ -+ firmware_dump_signdata(sign); -+ -+ memset(cmd, 0, BOOTROM_CMD_BUFFER_SIZE); -+ bl_bootrom_cmd_signature2_load(cmd, (uint8_t*)sign, sizeof(sign_cfg_t) + sign->sig_len); -+ printk("CMD signa data2 len %d\n", cmd->len); -+ ret = bl_io_write(card, (u8*)cmd, BOOTROM_CMD_BUFFER_SIZE); -+ if (ret) { -+ printk("ERR when write\n"); -+ return -1; -+ } -+ ret = bl_io_read(card, response, BOOTROM_CMD_BUFFER_SIZE); -+ if (ret) { -+ printk("NULL response get"); -+ return -1; -+ } -+ ret = bl_bootrom_cmd_signature2_get_res((bootrom_res_signature_load_t*)response); -+ if (ret) { -+ printk("Error response get signature2\n"); -+ return -1; -+ } -+ -+ *data += (sizeof(sign_cfg_t) + sign->sig_len); -+ *len -= (sizeof(sign_cfg_t) + sign->sig_len); -+ -+ return 0; -+} -+ -+static int firmware_download_segment_piece(struct bl_plat *card, bootrom_host_cmd_t *cmd, u8 *response, -+ bootheader_t *header, const u8 **data, int *len) -+{ -+ const segment_header_t *segment; -+ segment_header_t segment_plain; -+ int ret = 0, i, pos, wr_len; -+ -+ SDIO_DBG(SDIO_FN_ENTRY_STR); -+ -+ printk("FUNC segment_piece: data ptr %p, data left %d\n", *data, *len); -+ segment = (const segment_header_t*)(*data); -+ memset(cmd, 0, BOOTROM_CMD_BUFFER_SIZE); -+ bl_bootrom_cmd_sectionheader_load(cmd, segment); -+ printk("CMD segment piece len %d\n", cmd->len); -+ ret = bl_io_write(card, (u8*)cmd, BOOTROM_CMD_BUFFER_SIZE); -+ if (ret) { -+ printk("ERR when write\n"); -+ return -1; -+ } -+ ret = bl_io_read(card, response, BOOTROM_CMD_BUFFER_SIZE); -+ if (ret) { -+ printk("NULL response get\n"); -+ return -1; -+ } -+ ret = bl_bootrom_cmd_sectionheader_get_res((bootrom_res_sectionheader_load_t*)response); -+ if (ret) { -+ printk("response Error\n"); -+ return -1; -+ } -+ memcpy(&segment_plain, -+ &(((bootrom_res_sectionheader_load_t*)response)->header), sizeof(segment_plain)); -+ segment = &segment_plain; -+ printk("Get SEGMENT From BL606: destaddr: 0x%08x, len %d, rsv %08X, CRC32 %08X\n", -+ segment->destaddr, -+ segment->len, -+ segment->rsv, -+ segment->crc32 -+ ); -+ if (*len < (sizeof(segment_header_t) + segment->len)) { -+ printk("SEGMENT: buffer too small %lu(%lX required):%d(%X actual) to 0x%x\n", -+ sizeof(segment_header_t) + segment->len, -+ sizeof(segment_header_t) + segment->len, -+ *len, -+ *len, -+ segment->destaddr -+ ); -+ return -1; -+ } -+ firmware_dump_segment_piece(segment); -+ -+ pos = 0; -+ i = 0; -+ while (pos < segment->len) { -+#define WR_LEN ((BOOTROM_DATA_BUFFER_SIZE - sizeof(bootrom_host_cmd_t)) & 0xFFFFFFF0) -+ wr_len = segment->len - pos; -+ wr_len = (wr_len < WR_LEN) ? wr_len : WR_LEN; -+ printk("------piece %03d[%03d] %d:%u------\n", i++, wr_len, pos, segment->len); -+#if 1 -+ /*data len is less than one packet*/ -+ printk("data SRC[0-7]: %02X %02X %02X %02X %02X %02X %02X %02X\n", -+ (*data + sizeof(segment_header_t) + pos)[0], -+ (*data + sizeof(segment_header_t) + pos)[1], -+ (*data + sizeof(segment_header_t) + pos)[2], -+ (*data + sizeof(segment_header_t) + pos)[3], -+ (*data + sizeof(segment_header_t) + pos)[4], -+ (*data + sizeof(segment_header_t) + pos)[5], -+ (*data + sizeof(segment_header_t) + pos)[6], -+ (*data + sizeof(segment_header_t) + pos)[7] -+ ); -+#endif -+ bl_bootrom_cmd_sectiondata_load(cmd, *data + sizeof(segment_header_t) + pos, wr_len); -+#if 1 -+ printk("data[%u] CMD[0-7]: %02X %02X %02X %02X %02X %02X %02X %02X\n" -+ " TAL[0-7]: %02X %02X %02X %02X %02X %02X %02X %02X\n", -+ cmd->len, -+ cmd->data[0], -+ cmd->data[1], -+ cmd->data[2], -+ cmd->data[3], -+ cmd->data[4], -+ cmd->data[5], -+ cmd->data[6], -+ cmd->data[7], -+ cmd->data[cmd->len - 1 - 7], -+ cmd->data[cmd->len - 1 - 6], -+ cmd->data[cmd->len - 1 - 5], -+ cmd->data[cmd->len - 1 - 4], -+ cmd->data[cmd->len - 1 - 3], -+ cmd->data[cmd->len - 1 - 2], -+ cmd->data[cmd->len - 1 - 1], -+ cmd->data[cmd->len - 1 - 0] -+ ); -+#endif -+ printk("CMD segment piece loop len %d\n", cmd->len); -+ ret = bl_io_write(card, (u8*)cmd, BOOTROM_CMD_BUFFER_SIZE); -+ if (ret) { -+ printk("ERR when write\n"); -+ return -1; -+ } -+#if 0 -+ ret = bl_io_read(card, response, BOOTROM_CMD_BUFFER_SIZE); -+ if (ret) { -+ printk("NULL response get"); -+ return -1; -+ } -+ bl_bootrom_cmd_sectiondata_get_res((bootrom_res_sectiondata_load_t*)response); -+#endif -+ pos += wr_len; -+ } -+ -+ *data += (sizeof(segment_header_t) + segment->len); -+ *len -= (sizeof(segment_header_t) + segment->len); -+ -+ SDIO_DBG(SDIO_FN_LEAVE_STR); -+ -+ return 0; -+} -+ -+static int firmware_download_segment(struct bl_plat *card, bootrom_host_cmd_t *cmd, u8 *response, -+ bootheader_t *header, const u8 **data, int *len) -+{ -+ int i, ret; -+ -+ printk("SEGMENT AERA: @Offset 0x%lX\n", (u8*)(*data) - (u8*)(header)); -+ printk("FUNC segment: data ptr %p, data left %d\n", *data, *len); -+ for (i = 0; i < header->segment_cnt; i++) { -+ printk("------SEGMENT[%02d]@0x%lX------\n", i, (u8*)(*data) - (u8*)(header)); -+ ret = firmware_download_segment_piece(card, cmd, response, header, data, len); -+ if (ret) { -+ break; -+ } -+ } -+ -+ return ret; -+} -+ -+static int firmware_download_image_check(struct bl_plat *card, bootrom_host_cmd_t *cmd, u8 *response, bootheader_t *header) -+{ -+ int ret; -+ -+ memset(cmd, 0, BOOTROM_CMD_BUFFER_SIZE); -+ bl_bootrom_cmd_checkimage_get(cmd); -+ printk("CMD checkimage len %d\n", cmd->len); -+ ret = bl_io_write(card, (u8*)cmd, BOOTROM_CMD_BUFFER_SIZE); -+ if (ret) { -+ printk("ERR when write\n"); -+ return -1; -+ } -+ ret = bl_io_read(card, response, BOOTROM_CMD_BUFFER_SIZE); -+ if (ret) { -+ printk("NULL response get"); -+ return -1; -+ } -+ ret = bl_bootrom_cmd_checkimage_get_res((bootrom_res_checkimage_t*)response); -+ if (ret) { -+ printk("Error response get checkimage\n"); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static int firmware_download_image_run(struct bl_plat *card, bootrom_host_cmd_t *cmd, u8 *response, bootheader_t *header) -+{ -+ int ret; -+ -+ memset(cmd, 0, BOOTROM_CMD_BUFFER_SIZE); -+ bl_bootrom_cmd_runimage_get(cmd); -+ printk("CMD runimage len %d\n", cmd->len); -+ ret = bl_io_write(card, (u8*)cmd, BOOTROM_CMD_BUFFER_SIZE); -+ if (ret) { -+ printk("ERR when write\n"); -+ return -1; -+ } -+ ret = bl_io_read(card, response, BOOTROM_CMD_BUFFER_SIZE); -+ if (ret) { -+ printk("NULL response get"); -+ return -1; -+ } -+ bl_bootrom_cmd_runimage_get_res((bootrom_res_runimage_t*)response); -+ -+ return 0; -+} -+ -+static int firmware_downloader(struct bl_plat *card, const u8 *data, int len) -+{ -+ int ret = 0; -+ bootheader_t *header; -+ bootrom_host_cmd_t *cmd; -+ u8 *response; -+ -+ if (len < sizeof(bootheader_t)) { -+ printk("Illegal len when check bootheader_t\n"); -+ return -1; -+ } -+ header = (bootheader_t*)data; -+ cmd = kzalloc(BOOTROM_DATA_BUFFER_SIZE, GFP_KERNEL); -+ if (NULL == cmd) { -+ printk("NO MEM for alloc host CMD\n"); -+ return -1; -+ } -+ -+ response = kzalloc(BOOTROM_CMD_BUFFER_SIZE, GFP_KERNEL); -+ if (NULL == response) { -+ printk("NO MEM for alloc CMD response\n"); -+ kfree(cmd); -+ return -1; -+ } -+ -+ /*do NOT change the order bellow*/ -+ if (firmware_download_head(card, cmd, response, header, &data, &len) -+ || firmware_download_flashcfg(card, cmd, response, header) -+ || firmware_download_pllcfg(card, cmd, response, header) -+ || firmware_download_publickey1(card, cmd, response, header, &data, &len) -+ //|| firmware_download_publickey2(card, cmd, response, header, &data, &len) -+ || firmware_download_signdata1(card, cmd, response, header, &data, &len) -+ //|| firmware_download_signdata2(card, cmd, response, header, &data, &len) -+ || firmware_download_encryptiondata(card, cmd, response, header, &data, &len) -+ || firmware_download_segment(card, cmd, response, header, &data, &len) -+ || firmware_download_image_check(card, cmd, response, header)) { -+ printk("firmware load faield\n"); -+ return -1; -+ } -+ /*check if we need to download the other image*/ -+ if (len > 0) { -+ printk("Potential Second image found\n"); -+ header = (bootheader_t*)data;//update header to the next image -+ if (firmware_download_head(card, cmd, response, header, &data, &len) -+ || firmware_download_flashcfg(card, cmd, response, header) -+ || firmware_download_pllcfg(card, cmd, response, header) -+ || firmware_download_publickey1(card, cmd, response, header, &data, &len) -+ //|| firmware_download_publickey2(card, cmd, response, header, &data, &len) -+ || firmware_download_signdata1(card, cmd, response, header, &data, &len) -+ //|| firmware_download_signdata2(card, cmd, response, header, &data, &len) -+ || firmware_download_encryptiondata(card, cmd, response, header, &data, &len) -+ || firmware_download_segment(card, cmd, response, header, &data, &len) -+ || firmware_download_image_check(card, cmd, response, header)) { -+ printk("Sencond firmware load faield\n"); -+ return -1; -+ } -+ } -+ if (firmware_download_image_run(card, cmd, response, header)) { -+ printk("firmware check/Run faield\n"); -+ ret = -1; -+ } -+ -+ kfree(cmd); -+ kfree(response); -+ return ret; -+} -+ -+static int bl_sdio_checkversion(struct bl_plat *card) -+{ -+ bootrom_host_cmd_t *cmd; -+ int ret = 0; -+ u8 *response; -+ -+ SDIO_DBG(SDIO_FN_ENTRY_STR); -+ -+ cmd = kzalloc(BOOTROM_CMD_BUFFER_SIZE, GFP_KERNEL); -+ if (NULL == cmd) { -+ printk("NO MEM for alloc host CMD\n"); -+ return -1; -+ } -+ response = kzalloc(BOOTROM_CMD_BUFFER_SIZE, GFP_KERNEL); -+ if (NULL == response) { -+ printk("NO MEM for alloc CMD response\n"); -+ return -1; -+ } -+ -+ memset(cmd, 0, BOOTROM_CMD_BUFFER_SIZE); -+ memset(response, 0, BOOTROM_CMD_BUFFER_SIZE); -+ bl_bootrom_cmd_bootinfo_get(cmd); -+ printk("CMD check version len %d\n", cmd->len); -+ ret = bl_io_write(card, (u8*)cmd, BOOTROM_CMD_BUFFER_SIZE); -+ if (ret) { -+ printk("ERR when write\n"); -+ return -1; -+ } -+ ret = bl_io_read(card, response, BOOTROM_CMD_BUFFER_SIZE); -+ if (ret) { -+ printk("NULL response get"); -+ return -1; -+ } -+ bl_bootrom_cmd_bootinfo_get_res((bootrom_res_bootinfo_t*)response); -+ -+ kfree(response); -+ kfree(cmd); -+ SDIO_DBG(SDIO_FN_LEAVE_STR); -+ -+ return ret; -+} -+ -+static int bl_sdio_download_firmware(struct bl_plat *card) -+{ -+ const struct firmware *fw_helper = NULL; -+ int ret, imagelen; -+ const u8 *image = NULL; -+ ktime_t start; -+ s64 consume_time; -+ -+ printk("Enter bl_sdio_download_firmware...\n"); -+ ret = request_firmware(&fw_helper, "img_if_bl602_a0_rel_f157d2013f.bin", &card->func->dev); -+ if ((ret < 0) || !fw_helper) { -+ printk("request_firmware failed, error code = %d", ret); -+ ret = -ENOENT; -+ return ret; -+ } -+ -+ image = fw_helper->data; -+ imagelen = fw_helper->size; -+ -+ BL_DBG("Downloading image (%d bytes)\n", imagelen); -+ //time_start = jiffies; -+ start = ktime_get(); -+ firmware_downloader(card, image, imagelen); -+ consume_time = ktime_us_delta(ktime_get(), start); -+ BL_DBG("Download fw time: %lld\n", consume_time); -+ -+ //time_end = jiffies; -+ -+ release_firmware(fw_helper); -+ -+ return ret; -+ -+} -+ -+int bl_sdio_init(struct bl_plat *card) -+{ -+ u32 ret = 0; -+ -+ SDIO_DBG(SDIO_FN_ENTRY_STR); -+ -+ ret = bl_sdio_run_fw(card); -+ -+ ret = bl_sdio_checkversion(card); -+ -+ ret = bl_sdio_download_firmware(card); -+ -+ SDIO_DBG(SDIO_FN_LEAVE_STR); -+ -+ return ret; -+} -+ -+int bl_read_data_sync_claim0(struct bl_hw *bl_hw, u8 *buffer, u32 len, u32 port) -+{ -+ int ret; -+ u8 blk_mode = (len < BL_SDIO_BLOCK_SIZE) ? BYTE_MODE : BLOCK_MODE; -+ u32 blk_size = (blk_mode == BLOCK_MODE) ? BL_SDIO_BLOCK_SIZE : 1; -+ u32 blk_cnt = (blk_mode == BLOCK_MODE) ? ((len + BL_SDIO_BLOCK_SIZE -1)/BL_SDIO_BLOCK_SIZE) : len; -+ u32 ioport = (port & BL_SDIO_IO_PORT_MASK); -+ -+ ret = sdio_readsb(bl_hw->plat->func, buffer, ioport, blk_cnt * blk_size); -+ -+ return ret; -+} -+ -+/* -+ * This function writes multiple data into SDIO card memory. -+ * -+ * This does not work in suspended mode. -+ */ -+int bl_write_data_sync(struct bl_hw *bl_hw, u8 *buffer, u32 pkt_len, u32 port) -+{ -+ int ret; -+ u8 blk_mode = (pkt_len < BL_SDIO_BLOCK_SIZE) ? BYTE_MODE : BLOCK_MODE; -+ u32 blk_size = (blk_mode == BLOCK_MODE) ? BL_SDIO_BLOCK_SIZE : 1; -+ u32 blk_cnt = (blk_mode == BLOCK_MODE) ? ((pkt_len + BL_SDIO_BLOCK_SIZE -1)/BL_SDIO_BLOCK_SIZE) : pkt_len; -+ -+ u32 ioport = (port & BL_SDIO_IO_PORT_MASK); -+ -+ sdio_claim_host(bl_hw->plat->func); -+ ret = sdio_writesb(bl_hw->plat->func, ioport, buffer, blk_cnt * blk_size); -+ sdio_release_host(bl_hw->plat->func); -+ -+ return ret; -+} -+ -+/* -+ * This function reads multiple data from SDIO card memory. -+ */ -+int bl_read_data_sync(struct bl_hw *bl_hw, u8 *buffer, u32 len, u32 port) -+{ -+ int ret; -+ u8 blk_mode = (len < BL_SDIO_BLOCK_SIZE) ? BYTE_MODE : BLOCK_MODE; -+ u32 blk_size = (blk_mode == BLOCK_MODE) ? BL_SDIO_BLOCK_SIZE : 1; -+ u32 blk_cnt = (blk_mode == BLOCK_MODE) ? ((len + BL_SDIO_BLOCK_SIZE -1)/BL_SDIO_BLOCK_SIZE) : len; -+ u32 ioport = (port & BL_SDIO_IO_PORT_MASK); -+ -+ sdio_claim_host(bl_hw->plat->func); -+ ret = sdio_readsb(bl_hw->plat->func, buffer, ioport, blk_cnt * blk_size); -+ sdio_release_host(bl_hw->plat->func); -+ -+ return ret; -+} -+ -+/* -+ * This function reads data from SDIO card register. -+ */ -+int bl_read_reg(struct bl_hw *bl_hw, u32 reg, u8 *data) -+{ -+ int ret = -1; -+ u8 val; -+ -+ sdio_claim_host(bl_hw->plat->func); -+ val = sdio_readb(bl_hw->plat->func, reg, &ret); -+ sdio_release_host(bl_hw->plat->func); -+ -+ *data = val; -+ -+ return ret; -+} -+ -+/* -+ * This function write data to SDIO card register. -+ */ -+int bl_write_reg(struct bl_hw *bl_hw, u32 reg, u8 data) -+{ -+ int ret; -+ -+ sdio_claim_host(bl_hw->plat->func); -+ sdio_writeb(bl_hw->plat->func, data, reg, &ret); -+ sdio_release_host(bl_hw->plat->func); -+ -+ return ret; -+} -+ -+static int bl_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) -+{ -+ struct bl_plat *bl_plat = NULL; -+ void *drvdata; -+ int ret = -ENODEV; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ BL_DBG("info: vendor=0x%4.04X device=0x%4.04X class=%d function=%d\n", -+ func->vendor, func->device, func->class, func->num); -+ -+ ret = bl_device_init(func, &bl_plat); -+ if (ret) -+ return ret; -+ -+ bl_plat->func = func; -+ -+ ret = bl_platform_init(bl_plat, &drvdata); -+ sdio_set_drvdata(func, drvdata); -+ -+ if (ret) -+ bl_device_deinit(bl_plat); -+ -+ return ret; -+} -+ -+static void bl_sdio_remove(struct sdio_func *func) -+{ -+ struct bl_hw *bl_hw; -+ struct bl_plat *bl_plat; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ bl_hw = sdio_get_drvdata(func); -+ bl_plat = bl_hw->plat; -+ -+ bl_platform_deinit(bl_hw); -+ bl_device_deinit(bl_plat); -+ -+ sdio_set_drvdata(func, NULL); -+ -+} -+ -+static struct sdio_driver bl_sdio_drv = { -+ .name = KBUILD_MODNAME, -+ .id_table = bl_sdio_ids, -+ .probe = bl_sdio_probe, -+ .remove = bl_sdio_remove -+}; -+ -+int bl_sdio_register_drv(void) -+{ -+ return sdio_register_driver(&bl_sdio_drv); -+} -+ -+void bl_sdio_unregister_drv(void) -+{ -+ sdio_unregister_driver(&bl_sdio_drv); -+} -diff -Naur /dev/null_sdio.h b/drivers/net/wireless/hflps170/bl_sdio.h ---- /dev/null_sdio.h 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_sdio.h 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,199 @@ -+ -+/** -+ ****************************************************************************** -+ * -+ * @file bl_sdio.h -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ ****************************************************************************** -+ */ -+ -+#ifndef _BL_SDIO_H_ -+#define _BL_SDIO_H_ -+ -+ -+//////////////////////dnld fw////////////////////////////////// -+#define MBIT(x) (((u32)1) << (x)) -+#define HOST_INT_RSR_REG 0x01 -+#define HOST_INT_RSR_MASK 0x3F -+#define RD_BITMAP_L 0x04 -+#define RD_BITMAP_U 0x05 -+#define WR_BITMAP_L 0x06 -+#define WR_BITMAP_U 0x07 -+#define CARD_FW_STATUS0_REG 0x60 -+#define CARD_MISC_CFG_REG 0x6C -+#define CARD_MISC_CFG_REG 0x6C -+#define IO_PORT_0_REG 0x78 -+#define IO_PORT_1_REG 0x79 -+#define IO_PORT_2_REG 0x7A -+ -+#define SDIO_DBG printk -+ -+#define SDIO_FN_ENTRY_STR ">>> %s()\n", __func__ -+#define SDIO_FN_LEAVE_STR "<<< %s()\n", __func__ -+ -+ -+struct bl_fw_image { -+ u8 *fw_buf; -+ u32 fw_len; -+}; -+ -+int bl_write_data_sync_dnldfw(struct bl_plat *card, u8 *buffer, u32 pkt_len, u32 port); -+int bl_read_data_sync_dnldfw(struct bl_plat *card, u8 *buffer, u32 len, u32 port); -+//////////////////////dnld fw////////////////////////////////// -+ -+#define SD606_DEFAULT_FW_NAME "bfl_fullmac.bin" -+ -+#define USE_15_DATA_PORT -+ -+#ifdef USE_15_DATA_PORT -+#define DATA_PORT_MSK 0x0000fffe -+#define MAX_PORT_NUM 16 -+#else -+#define DATA_PORT_MSK 0x00007ffe -+#define MAX_PORT_NUM 15 -+//#define DATA_PORT_MSK 0x00000002 -+//#define MAX_PORT_NUM 2 -+#endif -+ -+#define BLOCK_MODE 1 -+#define BYTE_MODE 0 -+ -+#define BL_SDIO_BLOCK_SIZE 256 -+ -+#define REG_PORT 0 -+ -+#define BL_SDIO_IO_PORT_MASK 0xfffff -+ -+#define BL_SDIO_BYTE_MODE_MASK 0x80000000 -+ -+#define SDIO_MPA_ADDR_BASE 0x1000 -+#define CTRL_PORT 0 -+#define CTRL_PORT_MASK 0x0001 -+ -+#define CMD_PORT_UPLD_INT_MASK (0x1U<<6) -+#define CMD_PORT_DNLD_INT_MASK (0x1U<<7) -+#define HOST_TERM_CMD53 (0x1U << 2) -+#define REG_PORT 0 -+#define MEM_PORT 0x10000 -+ -+#define CMD53_NEW_MODE (0x1U << 0) -+#define CMD_PORT_RD_LEN_EN (0x1U << 2) -+#define CMD_PORT_AUTO_EN (0x1U << 0) -+#define CMD_PORT_SLCT 0x8000 -+#define UP_LD_CMD_PORT_HOST_INT_STATUS (0x40U) -+#define DN_LD_CMD_PORT_HOST_INT_STATUS (0x80U) -+ -+#define BL_MP_AGGR_BUF_SIZE_16K (16384) -+#define BL_MP_AGGR_BUF_SIZE_32K (32768) -+ -+/* Misc. Config Register : Auto Re-enable interrupts */ -+#define AUTO_RE_ENABLE_INT BIT(4) -+ -+/* Host Control Registers : Configuration */ -+#define CONFIGURATION_REG 0x00 -+/* Host Control Registers : Host power up */ -+#define HOST_POWER_UP (0x1U << 1) -+ -+/* Host Control Registers : Upload host interrupt mask */ -+#define UP_LD_HOST_INT_MASK (0x1U) -+/* Host Control Registers : Download host interrupt mask */ -+#define DN_LD_HOST_INT_MASK (0x2U) -+ -+/* Host Control Registers : Upload host interrupt status */ -+#define UP_LD_HOST_INT_STATUS (0x1U) -+/* Host Control Registers : Download host interrupt status */ -+#define DN_LD_HOST_INT_STATUS (0x2U) -+ -+/* Host Control Registers : Host interrupt status */ -+#define CARD_INT_STATUS_REG 0x28 -+ -+/* Card Control Registers : Card I/O ready */ -+#define CARD_IO_READY (0x1U << 3) -+/* Card Control Registers : Download card ready */ -+#define DN_LD_CARD_RDY (0x1U << 0) -+ -+struct bl_sdio_card_reg { -+ u8 start_rd_port; -+ u8 start_wr_port; -+ u8 base_0_reg; -+ u8 base_1_reg; -+ u8 poll_reg; -+ u8 host_int_enable; -+ u8 host_int_rsr_reg; -+ u8 host_int_status_reg; -+ u8 host_int_mask_reg; -+ u8 status_reg_0; -+ u8 status_reg_1; -+ u8 sdio_int_mask; -+ u32 data_port_mask; -+ u8 io_port_0_reg; -+ u8 io_port_1_reg; -+ u8 io_port_2_reg; -+ u8 max_mp_regs; -+ u8 rd_bitmap_l; -+ u8 rd_bitmap_u; -+ u8 rd_bitmap_1l; -+ u8 rd_bitmap_1u; -+ u8 wr_bitmap_l; -+ u8 wr_bitmap_u; -+ u8 wr_bitmap_1l; -+ u8 wr_bitmap_1u; -+ u8 rd_len_p0_l; -+ u8 rd_len_p0_u; -+ u8 card_misc_cfg_reg; -+ u8 card_cfg_2_1_reg; -+ u8 cmd_rd_len_0; -+ u8 cmd_rd_len_1; -+ u8 cmd_rd_len_2; -+ u8 cmd_rd_len_3; -+ u8 cmd_cfg_0; -+ u8 cmd_cfg_1; -+ u8 cmd_cfg_2; -+ u8 cmd_cfg_3; -+ u8 fw_dump_ctrl; -+ u8 fw_dump_start; -+ u8 fw_dump_end; -+}; -+ -+static const struct bl_sdio_card_reg bl_reg_sd606 = { -+ .start_rd_port = 1, -+ .start_wr_port = 1, -+ .base_0_reg = 0x0040, -+ .base_1_reg = 0x0041, -+ .poll_reg = 0x30, -+ .host_int_enable = UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK, -+ .host_int_rsr_reg = 0x1, -+ .host_int_mask_reg = 0x02, -+ .host_int_status_reg = 0x03, -+ .status_reg_0 = 0x60, -+ .status_reg_1 = 0x61, -+ .sdio_int_mask = 0x3f, -+ .data_port_mask = DATA_PORT_MSK, -+ .io_port_0_reg = 0x78, -+ .io_port_1_reg = 0x79, -+ .io_port_2_reg = 0x7A, -+ .max_mp_regs = 64, -+ .rd_bitmap_l = 0x04, -+ .rd_bitmap_u = 0x05, -+ .wr_bitmap_l = 0x06, -+ .wr_bitmap_u = 0x07, -+ .rd_len_p0_l = 0x08, -+ .rd_len_p0_u = 0x09, -+ .card_misc_cfg_reg = 0x6c, -+}; -+ -+int bl_sdio_register_drv(void); -+void bl_sdio_unregister_drv(void); -+int bl_read_reg(struct bl_hw *bl_hw, u32 reg, u8 *data); -+int bl_write_reg(struct bl_hw *bl_hw, u32 reg, u8 data); -+void bl_get_rd_len(struct bl_hw *bl_hw, u32 reg_l, u32 reg_u, u32 *len); -+int bl_get_rd_port(struct bl_hw *bl_hw, u32 *port); -+int bl_get_wr_port(struct bl_hw *bl_hw, u32 *port); -+int bl_read_data_sync(struct bl_hw *bl_hw, u8 *buffer, u32 len, u32 port); -+int bl_read_data_sync_claim0(struct bl_hw *bl_hw, u8 *buffer, u32 len, u32 port); -+int bl_write_data_sync(struct bl_hw *bl_hw, u8 *buffer, u32 pkt_len, u32 port); -+int bl_sdio_init(struct bl_plat *card); -+ -+#endif /* _BL_SDIO_H_ */ -diff -Naur /dev/null_strs.c b/drivers/net/wireless/hflps170/bl_strs.c ---- /dev/null_strs.c 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_strs.c 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,182 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file bl_strs.c -+ * -+ * @brief Miscellaneous debug strings -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ ****************************************************************************** -+ */ -+ -+#include "bl_utils.h" -+#include "lmac_msg.h" -+ -+static const char *const bl_mmid2str[MSG_I(MM_MAX)] = { -+ [MSG_I(MM_RESET_REQ)] = "MM_RESET_REQ", -+ [MSG_I(MM_RESET_CFM)] = "MM_RESET_CFM", -+ [MSG_I(MM_START_REQ)] = "MM_START_REQ", -+ [MSG_I(MM_START_CFM)] = "MM_START_CFM", -+ [MSG_I(MM_VERSION_REQ)] = "MM_VERSION_REQ", -+ [MSG_I(MM_VERSION_CFM)] = "MM_VERSION_CFM", -+ [MSG_I(MM_ADD_IF_REQ)] = "MM_ADD_IF_REQ", -+ [MSG_I(MM_ADD_IF_CFM)] = "MM_ADD_IF_CFM", -+ [MSG_I(MM_REMOVE_IF_REQ)] = "MM_REMOVE_IF_REQ", -+ [MSG_I(MM_REMOVE_IF_CFM)] = "MM_REMOVE_IF_CFM", -+ [MSG_I(MM_STA_ADD_REQ)] = "MM_STA_ADD_REQ", -+ [MSG_I(MM_STA_ADD_CFM)] = "MM_STA_ADD_CFM", -+ [MSG_I(MM_STA_DEL_REQ)] = "MM_STA_DEL_REQ", -+ [MSG_I(MM_STA_DEL_CFM)] = "MM_STA_DEL_CFM", -+ [MSG_I(MM_SET_FILTER_REQ)] = "MM_SET_FILTER_REQ", -+ [MSG_I(MM_SET_FILTER_CFM)] = "MM_SET_FILTER_CFM", -+ [MSG_I(MM_SET_CHANNEL_REQ)] = "MM_SET_CHANNEL_REQ", -+ [MSG_I(MM_SET_CHANNEL_CFM)] = "MM_SET_CHANNEL_CFM", -+ [MSG_I(MM_SET_DTIM_REQ)] = "MM_SET_DTIM_REQ", -+ [MSG_I(MM_SET_DTIM_CFM)] = "MM_SET_DTIM_CFM", -+ [MSG_I(MM_SET_BEACON_INT_REQ)] = "MM_SET_BEACON_INT_REQ", -+ [MSG_I(MM_SET_BEACON_INT_CFM)] = "MM_SET_BEACON_INT_CFM", -+ [MSG_I(MM_SET_BASIC_RATES_REQ)] = "MM_SET_BASIC_RATES_REQ", -+ [MSG_I(MM_SET_BASIC_RATES_CFM)] = "MM_SET_BASIC_RATES_CFM", -+ [MSG_I(MM_SET_BSSID_REQ)] = "MM_SET_BSSID_REQ", -+ [MSG_I(MM_SET_BSSID_CFM)] = "MM_SET_BSSID_CFM", -+ [MSG_I(MM_SET_EDCA_REQ)] = "MM_SET_EDCA_REQ", -+ [MSG_I(MM_SET_EDCA_CFM)] = "MM_SET_EDCA_CFM", -+ [MSG_I(MM_SET_MODE_REQ)] = "MM_SET_MODE_REQ", -+ [MSG_I(MM_SET_MODE_CFM)] = "MM_SET_MODE_CFM", -+ [MSG_I(MM_SET_VIF_STATE_REQ)] = "MM_SET_VIF_STATE_REQ", -+ [MSG_I(MM_SET_VIF_STATE_CFM)] = "MM_SET_VIF_STATE_CFM", -+ [MSG_I(MM_SET_SLOTTIME_REQ)] = "MM_SET_SLOTTIME_REQ", -+ [MSG_I(MM_SET_SLOTTIME_CFM)] = "MM_SET_SLOTTIME_CFM", -+ [MSG_I(MM_SET_IDLE_REQ)] = "MM_SET_IDLE_REQ", -+ [MSG_I(MM_SET_IDLE_CFM)] = "MM_SET_IDLE_CFM", -+ [MSG_I(MM_KEY_ADD_REQ)] = "MM_KEY_ADD_REQ", -+ [MSG_I(MM_KEY_ADD_CFM)] = "MM_KEY_ADD_CFM", -+ [MSG_I(MM_KEY_DEL_REQ)] = "MM_KEY_DEL_REQ", -+ [MSG_I(MM_KEY_DEL_CFM)] = "MM_KEY_DEL_CFM", -+ [MSG_I(MM_BA_ADD_REQ)] = "MM_BA_ADD_REQ", -+ [MSG_I(MM_BA_ADD_CFM)] = "MM_BA_ADD_CFM", -+ [MSG_I(MM_BA_DEL_REQ)] = "MM_BA_DEL_REQ", -+ [MSG_I(MM_BA_DEL_CFM)] = "MM_BA_DEL_CFM", -+ [MSG_I(MM_PRIMARY_TBTT_IND)] = "MM_PRIMARY_TBTT_IND", -+ [MSG_I(MM_SECONDARY_TBTT_IND)] = "MM_SECONDARY_TBTT_IND", -+ [MSG_I(MM_SET_POWER_REQ)] = "MM_SET_POWER_REQ", -+ [MSG_I(MM_SET_POWER_CFM)] = "MM_SET_POWER_CFM", -+ [MSG_I(MM_DBG_TRIGGER_REQ)] = "MM_DBG_TRIGGER_REQ", -+ [MSG_I(MM_SET_PS_MODE_REQ)] = "MM_SET_PS_MODE_REQ", -+ [MSG_I(MM_SET_PS_MODE_CFM)] = "MM_SET_PS_MODE_CFM", -+ [MSG_I(MM_CHAN_CTXT_ADD_REQ)] = "MM_CHAN_CTXT_ADD_REQ", -+ [MSG_I(MM_CHAN_CTXT_ADD_CFM)] = "MM_CHAN_CTXT_ADD_CFM", -+ [MSG_I(MM_CHAN_CTXT_DEL_REQ)] = "MM_CHAN_CTXT_DEL_REQ", -+ [MSG_I(MM_CHAN_CTXT_DEL_CFM)] = "MM_CHAN_CTXT_DEL_CFM", -+ [MSG_I(MM_CHAN_CTXT_LINK_REQ)] = "MM_CHAN_CTXT_LINK_REQ", -+ [MSG_I(MM_CHAN_CTXT_LINK_CFM)] = "MM_CHAN_CTXT_LINK_CFM", -+ [MSG_I(MM_CHAN_CTXT_UNLINK_REQ)] = "MM_CHAN_CTXT_UNLINK_REQ", -+ [MSG_I(MM_CHAN_CTXT_UNLINK_CFM)] = "MM_CHAN_CTXT_UNLINK_CFM", -+ [MSG_I(MM_CHAN_CTXT_UPDATE_REQ)] = "MM_CHAN_CTXT_UPDATE_REQ", -+ [MSG_I(MM_CHAN_CTXT_UPDATE_CFM)] = "MM_CHAN_CTXT_UPDATE_CFM", -+ [MSG_I(MM_CHAN_CTXT_SCHED_REQ)] = "MM_CHAN_CTXT_SCHED_REQ", -+ [MSG_I(MM_CHAN_CTXT_SCHED_CFM)] = "MM_CHAN_CTXT_SCHED_CFM", -+ [MSG_I(MM_BCN_CHANGE_REQ)] = "MM_BCN_CHANGE_REQ", -+ [MSG_I(MM_BCN_CHANGE_CFM)] = "MM_BCN_CHANGE_CFM", -+ [MSG_I(MM_TIM_UPDATE_REQ)] = "MM_TIM_UPDATE_REQ", -+ [MSG_I(MM_TIM_UPDATE_CFM)] = "MM_TIM_UPDATE_CFM", -+ [MSG_I(MM_CONNECTION_LOSS_IND)] = "MM_CONNECTION_LOSS_IND", -+ [MSG_I(MM_CHANNEL_SWITCH_IND)] = "MM_CHANNEL_SWITCH_IND", -+ [MSG_I(MM_CHANNEL_PRE_SWITCH_IND)] = "MM_CHANNEL_PRE_SWITCH_IND", -+ [MSG_I(MM_REMAIN_ON_CHANNEL_REQ)] = "MM_REMAIN_ON_CHANNEL_REQ", -+ [MSG_I(MM_REMAIN_ON_CHANNEL_CFM)] = "MM_REMAIN_ON_CHANNEL_CFM", -+ [MSG_I(MM_REMAIN_ON_CHANNEL_EXP_IND)] = "MM_REMAIN_ON_CHANNEL_EXP_IND", -+ [MSG_I(MM_PS_CHANGE_IND)] = "MM_PS_CHANGE_IND", -+ [MSG_I(MM_TRAFFIC_REQ_IND)] = "MM_TRAFFIC_REQ_IND", -+ [MSG_I(MM_SET_PS_OPTIONS_REQ)] = "MM_SET_PS_OPTIONS_REQ", -+ [MSG_I(MM_SET_PS_OPTIONS_CFM)] = "MM_SET_PS_OPTIONS_CFM", -+ [MSG_I(MM_P2P_VIF_PS_CHANGE_IND)] = "MM_P2P_VIF_PS_CHANGE_IND", -+ [MSG_I(MM_CSA_COUNTER_IND)] = "MM_CSA_COUNTER_IND", -+ [MSG_I(MM_CHANNEL_SURVEY_IND)] = "MM_CHANNEL_SURVEY_IND", -+ [MSG_I(MM_CFG_RSSI_REQ)] = "MM_CFG_RSSI_REQ", -+ [MSG_I(MM_RSSI_STATUS_IND)] = "MM_RSSI_STATUS_IND", -+ [MSG_I(MM_CSA_FINISH_IND)] = "MM_CSA_FINISH_IND", -+ [MSG_I(MM_CSA_TRAFFIC_IND)] = "MM_CSA_TRAFFIC_IND", -+}; -+ -+static const char *const bl_dbgid2str[MSG_I(DBG_MAX)] = { -+ [MSG_I(DBG_MEM_READ_REQ)] = "DBG_MEM_READ_REQ", -+ [MSG_I(DBG_MEM_READ_CFM)] = "DBG_MEM_READ_CFM", -+ [MSG_I(DBG_MEM_WRITE_REQ)] = "DBG_MEM_WRITE_REQ", -+ [MSG_I(DBG_MEM_WRITE_CFM)] = "DBG_MEM_WRITE_CFM", -+ [MSG_I(DBG_SET_MOD_FILTER_REQ)] = "DBG_SET_MOD_FILTER_REQ", -+ [MSG_I(DBG_SET_MOD_FILTER_CFM)] = "DBG_SET_MOD_FILTER_CFM", -+ [MSG_I(DBG_SET_SEV_FILTER_REQ)] = "DBG_SET_SEV_FILTER_REQ", -+ [MSG_I(DBG_SET_SEV_FILTER_CFM)] = "DBG_SET_SEV_FILTER_CFM", -+ [MSG_I(DBG_ERROR_IND)] = "DBG_ERROR_IND", -+ [MSG_I(DBG_GET_SYS_STAT_REQ)] = "DBG_GET_SYS_STAT_REQ", -+ [MSG_I(DBG_GET_SYS_STAT_CFM)] = "DBG_GET_SYS_STAT_CFM", -+}; -+ -+static const char *const bl_scanid2str[MSG_I(SCAN_MAX)] = { -+ [MSG_I(SCAN_START_REQ)] = "SCAN_START_REQ", -+ [MSG_I(SCAN_START_CFM)] = "SCAN_START_CFM", -+ [MSG_I(SCAN_DONE_IND)] = "SCAN_DONE_IND", -+}; -+ -+static const char *const bl_scanuid2str[MSG_I(SCANU_MAX)] = { -+ [MSG_I(SCANU_START_REQ)] = "SCANU_START_REQ", -+ [MSG_I(SCANU_START_CFM)] = "SCANU_START_CFM", -+ [MSG_I(SCANU_JOIN_REQ)] = "SCANU_JOIN_REQ", -+ [MSG_I(SCANU_JOIN_CFM)] = "SCANU_JOIN_CFM", -+ [MSG_I(SCANU_RESULT_IND)] = "SCANU_RESULT_IND", -+ [MSG_I(SCANU_FAST_REQ)] = "SCANU_FAST_REQ", -+ [MSG_I(SCANU_FAST_CFM)] = "SCANU_FAST_CFM", -+}; -+ -+static const char *const bl_meid2str[MSG_I(ME_MAX)] = { -+ [MSG_I(ME_CONFIG_REQ)] = "ME_CONFIG_REQ", -+ [MSG_I(ME_CONFIG_CFM)] = "ME_CONFIG_CFM", -+ [MSG_I(ME_CHAN_CONFIG_REQ)] = "ME_CHAN_CONFIG_REQ", -+ [MSG_I(ME_CHAN_CONFIG_CFM)] = "ME_CHAN_CONFIG_CFM", -+ [MSG_I(ME_SET_CONTROL_PORT_REQ)] = "ME_SET_CONTROL_PORT_REQ", -+ [MSG_I(ME_SET_CONTROL_PORT_CFM)] = "ME_SET_CONTROL_PORT_CFM", -+ [MSG_I(ME_TKIP_MIC_FAILURE_IND)] = "ME_TKIP_MIC_FAILURE_IND", -+ [MSG_I(ME_STA_ADD_REQ)] = "ME_STA_ADD_REQ", -+ [MSG_I(ME_STA_ADD_CFM)] = "ME_STA_ADD_CFM", -+ [MSG_I(ME_STA_DEL_REQ)] = "ME_STA_DEL_REQ", -+ [MSG_I(ME_STA_DEL_CFM)] = "ME_STA_DEL_CFM", -+ [MSG_I(ME_TX_CREDITS_UPDATE_IND)]= "ME_TX_CREDITS_UPDATE_IND", -+ [MSG_I(ME_RC_STATS_REQ)] = "ME_RC_STATS_REQ", -+ [MSG_I(ME_RC_STATS_CFM)] = "ME_RC_STATS_CFM", -+ [MSG_I(ME_RC_SET_RATE_REQ)] = "ME_RC_SET_RATE_REQ", -+ [MSG_I(ME_TRAFFIC_IND_REQ)] = "ME_TRAFFIC_IND_REQ", -+ [MSG_I(ME_TRAFFIC_IND_CFM)] = "ME_TRAFFIC_IND_CFM", -+}; -+ -+static const char *const bl_smid2str[MSG_I(SM_MAX)] = { -+ [MSG_I(SM_CONNECT_REQ)] = "SM_CONNECT_REQ", -+ [MSG_I(SM_CONNECT_CFM)] = "SM_CONNECT_CFM", -+ [MSG_I(SM_CONNECT_IND)] = "SM_CONNECT_IND", -+ [MSG_I(SM_DISCONNECT_REQ)] = "SM_DISCONNECT_REQ", -+ [MSG_I(SM_DISCONNECT_CFM)] = "SM_DISCONNECT_CFM", -+ [MSG_I(SM_DISCONNECT_IND)] = "SM_DISCONNECT_IND", -+ [MSG_I(SM_RSP_TIMEOUT_IND)] = "SM_RSP_TIMEOUT_IND", -+}; -+ -+static const char *const bl_apmid2str[MSG_I(APM_MAX)] = { -+ [MSG_I(APM_START_REQ)] = "APM_START_REQ", -+ [MSG_I(APM_START_CFM)] = "APM_START_CFM", -+ [MSG_I(APM_STOP_REQ)] = "APM_STOP_REQ", -+ [MSG_I(APM_STOP_CFM)] = "APM_STOP_CFM", -+ [MSG_I(APM_START_CAC_REQ)] = "APM_START_CAC_REQ", -+ [MSG_I(APM_START_CAC_CFM)] = "APM_START_CAC_CFM", -+ [MSG_I(APM_STOP_CAC_REQ)] = "APM_STOP_CAC_REQ", -+ [MSG_I(APM_STOP_CAC_CFM)] = "APM_STOP_CAC_CFM", -+}; -+ -+const char *const *bl_id2str[TASK_LAST_EMB + 1] = { -+ [TASK_MM] = bl_mmid2str, -+ [TASK_DBG] = bl_dbgid2str, -+ [TASK_SCAN] = bl_scanid2str, -+ [TASK_SCANU] = bl_scanuid2str, -+ [TASK_ME] = bl_meid2str, -+ [TASK_SM] = bl_smid2str, -+ [TASK_APM] = bl_apmid2str, -+}; -diff -Naur /dev/null_strs.h b/drivers/net/wireless/hflps170/bl_strs.h ---- /dev/null_strs.h 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_strs.h 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,25 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file bl_strs.h -+ * -+ * @brief Miscellaneous debug strings -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ **************************************************************************************** -+ */ -+ -+#ifndef _BL_STRS_H_ -+#define _BL_STRS_H_ -+ -+#include "lmac_msg.h" -+ -+#define BL_ID2STR(tag) (((MSG_T(tag) < ARRAY_SIZE(bl_id2str)) && \ -+ (bl_id2str[MSG_T(tag)]) && \ -+ ((bl_id2str[MSG_T(tag)])[MSG_I(tag)])) ? \ -+ (bl_id2str[MSG_T(tag)])[MSG_I(tag)] : "unknown") -+ -+extern const char *const *bl_id2str[TASK_LAST_EMB + 1]; -+ -+#endif /* _BL_STRS_H_ */ -diff -Naur /dev/null_txq.c b/drivers/net/wireless/hflps170/bl_txq.c ---- /dev/null_txq.c 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_txq.c 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,983 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file bl_txq.c -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ ****************************************************************************** -+ */ -+ -+#include "bl_defs.h" -+#include "bl_events.h" -+#include "bl_sdio.h" -+ -+ -+/****************************************************************************** -+ * Utils inline functions -+ *****************************************************************************/ -+struct bl_txq *bl_txq_sta_get(struct bl_sta *sta, u8 tid, int *idx, -+ struct bl_hw * bl_hw) -+{ -+ int id; -+ -+ if (tid >= NX_NB_TXQ_PER_STA) -+ tid = 0; -+ -+ if (is_multicast_sta(sta->sta_idx)) -+ id = (NX_REMOTE_STA_MAX * NX_NB_TXQ_PER_STA) + sta->vif_idx; -+ else -+ id = (sta->sta_idx * NX_NB_TXQ_PER_STA) + tid; -+ -+ if (idx) -+ *idx = id; -+ -+ return &bl_hw->txq[id]; -+} -+ -+struct bl_txq *bl_txq_vif_get(struct bl_vif *vif, u8 type, int *idx) -+{ -+ int id; -+ -+ id = NX_FIRST_VIF_TXQ_IDX + master_vif_idx(vif) + -+ (type * NX_VIRT_DEV_MAX); -+ -+ if (idx) -+ *idx = id; -+ -+ return &vif->bl_hw->txq[id]; -+} -+ -+static inline -+struct bl_sta *bl_txq_2_sta(struct bl_txq *txq) -+{ -+ return txq->sta; -+} -+ -+static const u16 bl_1d_to_wmm_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; -+ -+/****************************************************************************** -+ * Init/Deinit functions -+ *****************************************************************************/ -+/** -+ * bl_txq_init - Initialize a TX queue -+ * -+ * @txq: TX queue to be initialized -+ * @idx: TX queue index -+ * @status: TX queue initial status -+ * @hwq: Associated HW queue -+ * @ndev: Net device this queue belongs to -+ * (may be null for non netdev txq) -+ * -+ * Each queue is initialized with the credit of @NX_TXQ_INITIAL_CREDITS. -+ */ -+static void bl_txq_init(struct bl_txq *txq, int idx, u8 status, -+ struct bl_hwq *hwq, -+ struct bl_sta *sta, struct net_device *ndev -+ ) -+{ -+ int i; -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ txq->idx = idx; -+ txq->status = status; -+ txq->credits = NX_TXQ_INITIAL_CREDITS; -+ txq->pkt_sent = 0; -+ skb_queue_head_init(&txq->sk_list); -+ txq->last_retry_skb = NULL; -+ txq->nb_retry = 0; -+ txq->hwq = hwq; -+ txq->sta = sta; -+ for (i = 0; i < CONFIG_USER_MAX ; i++) -+ txq->pkt_pushed[i] = 0; -+ -+ txq->ps_id = LEGACY_PS_ID; -+ txq->push_limit = 0; -+ if (idx < NX_FIRST_VIF_TXQ_IDX) { -+ int sta_idx = sta->sta_idx; -+ int tid = idx - (sta_idx * NX_NB_TXQ_PER_STA); -+ if (tid < NX_NB_TID_PER_STA) -+ //txq->ndev_idx = NX_STA_NDEV_IDX(tid, sta_idx); -+ txq->ndev_idx = bl_1d_to_wmm_queue[tid]; -+ //txq->ndev_idx = tid; -+ else -+ txq->ndev_idx = NDEV_NO_TXQ; -+ } else if (idx < NX_FIRST_UNK_TXQ_IDX) { -+ txq->ndev_idx = NX_BCMC_TXQ_NDEV_IDX; -+ } else { -+ txq->ndev_idx = NDEV_NO_TXQ; -+ } -+ txq->ndev = ndev; -+#ifdef CONFIG_BL_AMSDUS_TX -+ txq->amsdu = NULL; -+ txq->amsdu_len = 0; -+#endif /* CONFIG_BL_AMSDUS_TX */ -+} -+ -+/** -+ * bl_txq_flush - Flush all buffers queued for a TXQ -+ * -+ * @bl_hw: main driver data -+ * @txq: txq to flush -+ */ -+void bl_txq_flush(struct bl_hw *bl_hw, struct bl_txq *txq) -+{ -+ struct sk_buff *skb; -+ -+ while((skb = skb_dequeue(&txq->sk_list)) != NULL) { -+#ifdef CONFIG_BL_AMSDUS_TX -+ struct bl_sw_txhdr *hdr = ((struct bl_txhdr *)skb->data)->sw_hdr; -+ if (hdr->desc.host.packet_cnt > 1) { -+ struct bl_amsdu_txhdr *amsdu_txhdr; -+ list_for_each_entry(amsdu_txhdr, &hdr->amsdu.hdrs, list) { -+ dma_unmap_single(bl_hw->dev, amsdu_txhdr->dma_addr, -+ amsdu_txhdr->map_len, DMA_TO_DEVICE); -+ dev_kfree_skb_any(amsdu_txhdr->skb); -+ } -+ } -+#endif -+ -+ dev_kfree_skb_any(skb); -+ } -+} -+ -+/** -+ * bl_txq_deinit - De-initialize a TX queue -+ * -+ * @bl_hw: Driver main data -+ * @txq: TX queue to be de-initialized -+ * Any buffer stuck in a queue will be freed. -+ */ -+static void bl_txq_deinit(struct bl_hw *bl_hw, struct bl_txq *txq) -+{ -+ spin_lock_bh(&bl_hw->tx_lock); -+ bl_txq_del_from_hw_list(txq); -+ txq->idx = TXQ_INACTIVE; -+ spin_unlock_bh(&bl_hw->tx_lock); -+ -+ bl_txq_flush(bl_hw, txq); -+} -+ -+/** -+ * bl_txq_vif_init - Initialize all TXQ linked to a vif -+ * -+ * @bl_hw: main driver data -+ * @bl_vif: Pointer on VIF -+ * @status: Intial txq status -+ * -+ * Softmac : 1 VIF TXQ per HWQ -+ * -+ * Fullmac : 1 VIF TXQ for BC/MC -+ * 1 VIF TXQ for MGMT to unknown STA -+ */ -+void bl_txq_vif_init(struct bl_hw *bl_hw, struct bl_vif *bl_vif, -+ u8 status) -+{ -+ struct bl_txq *txq; -+ int idx; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ txq = bl_txq_vif_get(bl_vif, NX_BCMC_TXQ_TYPE, &idx); -+ bl_txq_init(txq, idx, status, &bl_hw->hwq[BL_HWQ_BE], -+ &bl_hw->sta_table[bl_vif->ap.bcmc_index], bl_vif->ndev); -+ -+ txq = bl_txq_vif_get(bl_vif, NX_UNK_TXQ_TYPE, &idx); -+ bl_txq_init(txq, idx, status, &bl_hw->hwq[BL_HWQ_VO], -+ NULL, bl_vif->ndev); -+} -+ -+/** -+ * bl_txq_vif_deinit - Deinitialize all TXQ linked to a vif -+ * -+ * @bl_hw: main driver data -+ * @bl_vif: Pointer on VIF -+ */ -+void bl_txq_vif_deinit(struct bl_hw * bl_hw, struct bl_vif *bl_vif) -+{ -+ struct bl_txq *txq; -+ -+ txq = bl_txq_vif_get(bl_vif, NX_BCMC_TXQ_TYPE, NULL); -+ bl_txq_deinit(bl_hw, txq); -+ -+ txq = bl_txq_vif_get(bl_vif, NX_UNK_TXQ_TYPE, NULL); -+ bl_txq_deinit(bl_hw, txq); -+} -+ -+ -+/** -+ * bl_txq_sta_init - Initialize TX queues for a STA -+ * -+ * @bl_hw: Main driver data -+ * @bl_sta: STA for which tx queues need to be initialized -+ * @status: Intial txq status -+ * -+ * This function initialize all the TXQ associated to a STA. -+ * Softmac : 1 TXQ per TID -+ * -+ * Fullmac : 1 TXQ per TID (limited to 8) -+ * 1 TXQ for MGMT -+ */ -+void bl_txq_sta_init(struct bl_hw * bl_hw, struct bl_sta *bl_sta, -+ u8 status) -+{ -+ struct bl_txq *txq; -+ int tid, idx; -+ struct bl_vif *bl_vif = NULL; -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ bl_vif = bl_hw->vif_table[bl_sta->vif_idx]; -+ -+ txq = bl_txq_sta_get(bl_sta, 0, &idx, bl_hw); -+ for (tid = 0; tid < NX_NB_TXQ_PER_STA; tid++, txq++, idx++) { -+ bl_txq_init(txq, idx, status, &bl_hw->hwq[bl_tid2hwq[tid]], -+ bl_sta, bl_vif->ndev); -+ txq->ps_id = bl_sta->uapsd_tids & (1 << tid) ? UAPSD_ID : LEGACY_PS_ID; -+ } -+} -+ -+/** -+ * bl_txq_sta_deinit - Deinitialize TX queues for a STA -+ * -+ * @bl_hw: Main driver data -+ * @bl_sta: STA for which tx queues need to be deinitialized -+ */ -+void bl_txq_sta_deinit(struct bl_hw *bl_hw, struct bl_sta *bl_sta) -+{ -+ struct bl_txq *txq; -+ int i; -+ -+ txq = bl_txq_sta_get(bl_sta, 0, NULL, bl_hw); -+ -+ for (i = 0; i < NX_NB_TXQ_PER_STA; i++, txq++) { -+ bl_txq_deinit(bl_hw, txq); -+ } -+} -+ -+#ifdef CONFIG_BL_FULLMAC -+ -+/** -+ * bl_init_unk_txq - Initialize TX queue for the transmission on a offchannel -+ * -+ * @vif: Interface for which the queue has to be initialized -+ * -+ * NOTE: Offchannel txq is only active for the duration of the ROC -+ */ -+void bl_txq_offchan_init(struct bl_vif *bl_vif) -+{ -+ struct bl_hw *bl_hw = bl_vif->bl_hw; -+ struct bl_txq *txq; -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ txq = &bl_hw->txq[NX_OFF_CHAN_TXQ_IDX]; -+ bl_txq_init(txq, NX_OFF_CHAN_TXQ_IDX, BL_TXQ_STOP_CHAN, -+ &bl_hw->hwq[BL_HWQ_VO], NULL, bl_vif->ndev); -+} -+ -+/** -+ * bl_deinit_offchan_txq - Deinitialize TX queue for offchannel -+ * -+ * @vif: Interface that manages the STA -+ * -+ * This function deintialize txq for one STA. -+ * Any buffer stuck in a queue will be freed. -+ */ -+void bl_txq_offchan_deinit(struct bl_vif *bl_vif) -+{ -+ struct bl_txq *txq; -+ -+ txq = &bl_vif->bl_hw->txq[NX_OFF_CHAN_TXQ_IDX]; -+ bl_txq_deinit(bl_vif->bl_hw, txq); -+} -+ -+#endif -+ -+/****************************************************************************** -+ * Start/Stop functions -+ *****************************************************************************/ -+/** -+ * bl_txq_add_to_hw_list - Add TX queue to a HW queue schedule list. -+ * -+ * @txq: TX queue to add -+ * -+ * Add the TX queue if not already present in the HW queue list. -+ * To be called with tx_lock hold -+ */ -+void bl_txq_add_to_hw_list(struct bl_txq *txq) -+{ -+ if (!(txq->status & BL_TXQ_IN_HWQ_LIST)) { -+ trace_txq_add_to_hw(txq); -+ txq->status |= BL_TXQ_IN_HWQ_LIST; -+ list_add_tail(&txq->sched_list, &txq->hwq->list); -+ } else { -+ BL_DBG("txq is not scheduled for transmission, txq->status=0x%x\n", txq->status); -+ } -+} -+ -+/** -+ * bl_txq_del_from_hw_list - Delete TX queue from a HW queue schedule list. -+ * -+ * @txq: TX queue to delete -+ * -+ * Remove the TX queue from the HW queue list if present. -+ * To be called with tx_lock hold -+ */ -+void bl_txq_del_from_hw_list(struct bl_txq *txq) -+{ -+ if (txq->status & BL_TXQ_IN_HWQ_LIST) { -+ trace_txq_del_from_hw(txq); -+ txq->status &= ~BL_TXQ_IN_HWQ_LIST; -+ list_del(&txq->sched_list); -+ } -+} -+ -+/** -+ * bl_txq_start - Try to Start one TX queue -+ * -+ * @txq: TX queue to start -+ * @reason: reason why the TX queue is started (among BL_TXQ_STOP_xxx) -+ * -+ * Re-start the TX queue for one reason. -+ * If after this the txq is no longer stopped and some buffers are ready, -+ * the TX queue is also added to HW queue list. -+ * To be called with tx_lock hold -+ */ -+void bl_txq_start(struct bl_txq *txq, u16 reason) -+{ -+ BUG_ON(txq==NULL); -+ if (txq->idx != TXQ_INACTIVE && (txq->status & reason)) -+ { -+ trace_txq_start(txq, reason); -+ txq->status &= ~reason; -+ if (!bl_txq_is_stopped(txq) && -+ !skb_queue_empty(&txq->sk_list)) { -+ bl_txq_add_to_hw_list(txq); -+ } -+ } -+} -+ -+/** -+ * bl_txq_stop - Stop one TX queue -+ * -+ * @txq: TX queue to stop -+ * @reason: reason why the TX queue is stopped (among BL_TXQ_STOP_xxx) -+ * -+ * Stop the TX queue. It will remove the TX queue from HW queue list -+ * To be called with tx_lock hold -+ */ -+void bl_txq_stop(struct bl_txq *txq, u16 reason) -+{ -+ BUG_ON(txq==NULL); -+ if (txq->idx != TXQ_INACTIVE) -+ { -+ trace_txq_stop(txq, reason); -+ txq->status |= reason; -+ bl_txq_del_from_hw_list(txq); -+ } -+} -+ -+ -+/** -+ * bl_txq_sta_start - Start all the TX queue linked to a STA -+ * -+ * @sta: STA whose TX queues must be re-started -+ * @reason: Reason why the TX queue are restarted (among BL_TXQ_STOP_xxx) -+ * @bl_hw: Driver main data -+ * -+ * This function will re-start all the TX queues of the STA for the reason -+ * specified. It can be : -+ * - BL_TXQ_STOP_STA_PS: the STA is no longer in power save mode -+ * - BL_TXQ_STOP_VIF_PS: the VIF is in power save mode (p2p absence) -+ * - BL_TXQ_STOP_CHAN: the STA's VIF is now on the current active channel -+ * -+ * Any TX queue with buffer ready and not Stopped for other reasons, will be -+ * added to the HW queue list -+ * To be called with tx_lock hold -+ */ -+void bl_txq_sta_start(struct bl_sta *bl_sta, u16 reason -+#ifdef CONFIG_BL_FULLMAC -+ , struct bl_hw *bl_hw -+#endif -+ ) -+{ -+ struct bl_txq *txq; -+ int i; -+ int nb_txq; -+ -+ if (!bl_sta) -+ return; -+ -+ trace_txq_sta_start(bl_sta->sta_idx); -+ -+ txq = bl_txq_sta_get(bl_sta, 0, NULL, bl_hw); -+ -+ if (is_multicast_sta(bl_sta->sta_idx)) -+ nb_txq = 1; -+ else -+ nb_txq = NX_NB_TXQ_PER_STA; -+ -+ for (i = 0; i < nb_txq; i++, txq++) -+ bl_txq_start(txq, reason); -+} -+ -+ -+/** -+ * bl_stop_sta_txq - Stop all the TX queue linked to a STA -+ * -+ * @sta: STA whose TX queues must be stopped -+ * @reason: Reason why the TX queue are stopped (among BL_TX_STOP_xxx) -+ * @bl_hw: Driver main data -+ * -+ * This function will stop all the TX queues of the STA for the reason -+ * specified. It can be : -+ * - BL_TXQ_STOP_STA_PS: the STA is in power save mode -+ * - BL_TXQ_STOP_VIF_PS: the VIF is in power save mode (p2p absence) -+ * - BL_TXQ_STOP_CHAN: the STA's VIF is not on the current active channel -+ * -+ * Any TX queue present in a HW queue list will be removed from this list. -+ * To be called with tx_lock hold -+ */ -+void bl_txq_sta_stop(struct bl_sta *bl_sta, u16 reason -+#ifdef CONFIG_BL_FULLMAC -+ , struct bl_hw *bl_hw -+#endif -+ ) -+{ -+ struct bl_txq *txq; -+ int i; -+#ifdef CONFIG_BL_FULLMAC -+ int nb_txq; -+#endif -+ -+ if (!bl_sta) -+ return; -+ -+ trace_txq_sta_stop(bl_sta->sta_idx); -+ txq = bl_txq_sta_get(bl_sta, 0, NULL, bl_hw); -+ -+ if (is_multicast_sta(bl_sta->sta_idx)) -+ nb_txq = 1; -+ else -+ nb_txq = NX_NB_TXQ_PER_STA; -+ -+ for (i = 0; i < nb_txq; i++, txq++) -+ bl_txq_stop(txq, reason); -+ -+} -+ -+#ifdef CONFIG_BL_FULLMAC -+static inline -+void bl_txq_vif_for_each_sta(struct bl_hw *bl_hw, struct bl_vif *bl_vif, -+ void (*f)(struct bl_sta *, u16, struct bl_hw *), -+ u16 reason) -+{ -+ -+ switch (BL_VIF_TYPE(bl_vif)) { -+ case NL80211_IFTYPE_STATION: -+ { -+ f(bl_vif->sta.ap, reason, bl_hw); -+ break; -+ } -+ case NL80211_IFTYPE_AP_VLAN: -+ bl_vif = bl_vif->ap_vlan.master; -+ case NL80211_IFTYPE_AP: -+ { -+ struct bl_sta *sta; -+ list_for_each_entry(sta, &bl_vif->ap.sta_list, list) { -+ f(sta, reason, bl_hw); -+ } -+ break; -+ } -+ default: -+ BUG(); -+ break; -+ } -+} -+ -+#endif -+ -+/** -+ * bl_txq_vif_start - START TX queues of all STA associated to the vif -+ * and vif's TXQ -+ * -+ * @vif: Interface to start -+ * @reason: Start reason (BL_TXQ_STOP_CHAN or BL_TXQ_STOP_VIF_PS) -+ * @bl_hw: Driver main data -+ * -+ * Iterate over all the STA associated to the vif and re-start them for the -+ * reason @reason -+ * Take tx_lock -+ */ -+void bl_txq_vif_start(struct bl_vif *bl_vif, u16 reason, -+ struct bl_hw *bl_hw) -+{ -+ struct bl_txq *txq; -+ -+ trace_txq_vif_start(bl_vif->vif_index); -+ -+ spin_lock_bh(&bl_hw->tx_lock); -+ bl_txq_vif_for_each_sta(bl_hw, bl_vif, bl_txq_sta_start, reason); -+ -+ txq = bl_txq_vif_get(bl_vif, NX_BCMC_TXQ_TYPE, NULL); -+ bl_txq_start(txq, reason); -+ txq = bl_txq_vif_get(bl_vif, NX_UNK_TXQ_TYPE, NULL); -+ bl_txq_start(txq, reason); -+ -+ spin_unlock_bh(&bl_hw->tx_lock); -+} -+ -+ -+ -+/** -+ * bl_txq_vif_stop - STOP TX queues of all STA associated to the vif -+ * -+ * @vif: Interface to stop -+ * @arg: Stop reason (BL_TXQ_STOP_CHAN or BL_TXQ_STOP_VIF_PS) -+ * @bl_hw: Driver main data -+ * -+ * Iterate over all the STA associated to the vif and stop them for the -+ * reason BL_TXQ_STOP_CHAN or BL_TXQ_STOP_VIF_PS -+ * Take tx_lock -+ */ -+void bl_txq_vif_stop(struct bl_vif *bl_vif, u16 reason, -+ struct bl_hw *bl_hw) -+{ -+ struct bl_txq *txq; -+ -+ trace_txq_vif_stop(bl_vif->vif_index); -+ -+ spin_lock_bh(&bl_hw->tx_lock); -+ -+ bl_txq_vif_for_each_sta(bl_hw, bl_vif, bl_txq_sta_stop, reason); -+ -+ txq = bl_txq_vif_get(bl_vif, NX_BCMC_TXQ_TYPE, NULL); -+ bl_txq_stop(txq, reason); -+ txq = bl_txq_vif_get(bl_vif, NX_UNK_TXQ_TYPE, NULL); -+ bl_txq_stop(txq, reason); -+ -+ spin_unlock_bh(&bl_hw->tx_lock); -+} -+ -+#ifdef CONFIG_BL_FULLMAC -+ -+/** -+ * bl_start_offchan_txq - START TX queue for offchannel frame -+ * -+ * @bl_hw: Driver main data -+ */ -+void bl_txq_offchan_start(struct bl_hw *bl_hw) -+{ -+ struct bl_txq *txq; -+ -+ txq = &bl_hw->txq[NX_OFF_CHAN_TXQ_IDX]; -+ bl_txq_start(txq, BL_TXQ_STOP_CHAN); -+} -+ -+/** -+ * bl_switch_vif_sta_txq - Associate TXQ linked to a STA to a new vif -+ * -+ * @sta: STA whose txq must be switched -+ * @old_vif: Vif currently associated to the STA (may no longer be active) -+ * @new_vif: vif which should be associated to the STA for now on -+ * -+ * This function will switch the vif (i.e. the netdev) associated to all STA's -+ * TXQ. This is used when AP_VLAN interface are created. -+ * If one STA is associated to an AP_vlan vif, it will be moved from the master -+ * AP vif to the AP_vlan vif. -+ * If an AP_vlan vif is removed, then STA will be moved back to mastert AP vif. -+ * -+ */ -+void bl_txq_sta_switch_vif(struct bl_sta *sta, struct bl_vif *old_vif, -+ struct bl_vif *new_vif) -+{ -+ struct bl_hw *bl_hw = new_vif->bl_hw; -+ struct bl_txq *txq; -+ int i; -+ -+ /* start TXQ on the new interface, and update ndev field in txq */ -+ if (!netif_carrier_ok(new_vif->ndev)) -+ netif_carrier_on(new_vif->ndev); -+ txq = bl_txq_sta_get(sta, 0, NULL, bl_hw); -+ for (i = 0; i < NX_NB_TID_PER_STA; i++, txq++) { -+ txq->ndev = new_vif->ndev; -+ netif_wake_subqueue(txq->ndev, txq->ndev_idx); -+ } -+} -+#endif /* CONFIG_BL_FULLMAC */ -+ -+/****************************************************************************** -+ * TXQ queue/schedule functions -+ *****************************************************************************/ -+/** -+ * bl_txq_queue_skb - Queue a buffer in a TX queue -+ * -+ * @skb: Buffer to queue -+ * @txq: TX Queue in which the buffer must be added -+ * @bl_hw: Driver main data -+ * @retry: Should it be queued in the retry list -+ * -+ * @return: Retrun 1 if txq has been added to hwq list, 0 otherwise -+ * -+ * Add a buffer in the buffer list of the TX queue -+ * and add this TX queue in the HW queue list if the txq is not stopped. -+ * If this is a retry packet it is added after the last retry packet or at the -+ * beginning if there is no retry packet queued. -+ * -+ * If the STA is in PS mode and this is the first packet queued for this txq -+ * update TIM. -+ * -+ * To be called with tx_lock hold -+ */ -+int bl_txq_queue_skb(struct sk_buff *skb, struct bl_txq *txq, -+ struct bl_hw *bl_hw, bool retry) -+{ -+ -+#ifdef CONFIG_BL_FULLMAC -+ if (unlikely(txq->sta && txq->sta->ps.active)) { -+ txq->sta->ps.pkt_ready[txq->ps_id]++; -+ trace_ps_queue(txq->sta); -+ -+ if (txq->sta->ps.pkt_ready[txq->ps_id] == 1) { -+ BL_DBG("unlikely, sta was in ps mode!\n, txq->ps_id=%d\n", txq->ps_id); -+ bl_set_traffic_status(bl_hw, txq->sta, true, txq->ps_id); -+ } -+ } -+#endif -+ -+ if (!retry) { -+ /* add buffer in the sk_list */ -+ skb_queue_tail(&txq->sk_list, skb); -+ } else { -+ if(skb==NULL) -+ printk("skb = NULL\n"); -+ if(&txq->sk_list == NULL) -+ printk("txq->sk_list NULL\n"); -+ -+ if (txq->last_retry_skb) { -+ BL_DBG("append last retry skb\n"); -+ skb_append(txq->last_retry_skb, skb, &txq->sk_list); -+ }else{ -+ BL_DBG("append retry skb to head\n"); -+ skb_queue_head(&txq->sk_list, skb); -+ } -+ -+ txq->last_retry_skb = skb; -+ txq->nb_retry++; -+ } -+ -+ trace_txq_queue_skb(skb, txq, retry); -+ -+ /* Flowctrl corresponding netdev queue if needed */ -+ /* If too many buffer are queued for this TXQ stop netdev queue */ -+ if ((txq->ndev_idx != NDEV_NO_TXQ) && -+ (skb_queue_len(&txq->sk_list) > BL_NDEV_FLOW_CTRL_STOP)) { -+ //printk("stop: txq[%d], txq_netdev_idx[%d], skb_len[%d], txq->ndev->num_tx_queues[%d]\n", txq->idx, txq->ndev_idx, skb_queue_len(&txq->sk_list), txq->ndev->num_tx_queues); -+ txq->status |= BL_TXQ_NDEV_FLOW_CTRL; -+ netif_stop_subqueue(txq->ndev, txq->ndev_idx); -+ //netif_tx_stop_all_queues(txq->ndev); -+ trace_txq_flowctrl_stop(txq); -+ } -+ -+ /* add it in the hwq list if not stopped and not yet present */ -+ if (!bl_txq_is_stopped(txq)) { -+ bl_txq_add_to_hw_list(txq); -+ return 1; -+ } else { -+ BL_DBG("txq stopped, txq->status=0x%x\n", txq->status); -+ } -+ -+ return 0; -+} -+ -+/** -+ * bl_txq_confirm_any - Process buffer confirmed by fw -+ * -+ * @bl_hw: Driver main data -+ * @txq: TX Queue -+ * @hwq: HW Queue -+ * @sw_txhdr: software descriptor of the confirmed packet -+ * -+ * Process a buffer returned by the fw. It doesn't check buffer status -+ * and only does systematic counter update: -+ * - hw credit -+ * - buffer pushed to fw -+ * -+ * To be called with tx_lock hold -+ */ -+void bl_txq_confirm_any(struct bl_hw *bl_hw, struct bl_txq *txq, -+ struct bl_hwq *hwq, struct bl_sw_txhdr *sw_txhdr) -+{ -+ int user = 0; -+ -+ if (txq->pkt_pushed[user]) -+ txq->pkt_pushed[user]--; -+ -+ hwq->credits[user]++; -+ bl_hw->stats.cfm_balance[hwq->id]--; -+} -+ -+/****************************************************************************** -+ * HWQ processing -+ *****************************************************************************/ -+static inline -+s8 bl_txq_get_credits(struct bl_txq *txq) -+{ -+ s8 cred = txq->credits; -+#ifdef CONFIG_BL_FULLMAC -+ /* if destination is in PS mode, push_limit indicates the maximum -+ number of packet that can be pushed on this txq. */ -+ if (txq->push_limit && (cred > txq->push_limit)) { -+ cred = txq->push_limit; -+ } -+#endif -+ return cred; -+} -+ -+/** -+ * bl_txq_get_skb_to_push - Get list of buffer to push for one txq -+ * -+ * @bl_hw: main driver data -+ * @hwq: HWQ on wich buffers will be pushed -+ * @txq: TXQ to get buffers from -+ * @user: user postion to use -+ * @sk_list_push: list to update -+ * -+ * -+ * This function will returned a list of buffer to push for one txq. -+ * It will take into account the number of credit of the HWQ for this user -+ * position and TXQ (and push_limit for fullmac). -+ * This allow to get a list that can be pushed without having to test for -+ * hwq/txq status after each push -+ * -+ * If a MU group has been selected for this txq, it will also update the -+ * counter for the group -+ * -+ * @return true if txq no longer have buffer ready after the ones returned. -+ * false otherwise -+ */ -+static -+bool bl_txq_get_skb_to_push(struct bl_hw *bl_hw, struct bl_hwq *hwq, -+ struct bl_txq *txq, int user, -+ struct sk_buff_head *sk_list_push) -+{ -+ int nb_ready = skb_queue_len(&txq->sk_list); -+ int credits; -+ int hwq_credits; -+ int txq_credits; -+ bool res = false; -+ int avail_port_num = 0; -+ u32 wr_bitmap = bl_hw->plat->mp_wr_bitmap; -+ -+ wr_bitmap &= 0xFFFFFFFE; -+ while(wr_bitmap) { -+ wr_bitmap = wr_bitmap & (wr_bitmap-1); -+ avail_port_num++; -+ } -+ -+ hwq_credits = bl_hw->ipc_env->rb_len[hwq->id]; -+ txq_credits = bl_txq_get_credits(txq); -+// credits = min3(avail_port_num, txq_credits, hwq_credits); -+ credits = min(avail_port_num, 8); -+ -+ BL_DBG("bl_txq_get_skb_to_push: env->rb_len[%d]=%d\n", hwq->id, bl_hw->ipc_env->rb_len[hwq->id]); -+ -+ BL_DBG("nb_ready=%d, txq->idx=%d, hwq->idx=%d, txq->status=0x%x, txq->credits=%d, avail_port_num=%d, hwq_credits=%d, credits=%d\n", -+ nb_ready, txq->idx, hwq->id, txq->status, bl_txq_get_credits(txq), avail_port_num, hwq_credits, credits); -+ -+ bl_hw->dbg_credit[bl_hw->dbg_credit_idx].sdio_port = avail_port_num; -+ bl_hw->dbg_credit[bl_hw->dbg_credit_idx].txq_credit = txq_credits; -+ bl_hw->dbg_credit[bl_hw->dbg_credit_idx].hwq_credit = hwq_credits; -+ bl_hw->dbg_credit[bl_hw->dbg_credit_idx].credit = credits; -+ bl_hw->dbg_credit[bl_hw->dbg_credit_idx].nb_ready = nb_ready; -+ bl_hw->dbg_credit[bl_hw->dbg_credit_idx].txq_idx = txq->idx; -+ -+ bl_hw->dbg_credit_idx++; -+ -+ if(bl_hw->dbg_credit_idx == 50) -+ bl_hw->dbg_credit_idx = 0; -+ -+ __skb_queue_head_init(sk_list_push); -+ -+ if(credits == 0) { -+ BL_DBG("credits=0, no availe port\n"); -+ return true; -+ } -+ -+ if(bl_hw->plat->curr_wr_port + credits > 16) -+ credits -= 1; -+ -+#if 0 -+ if (credits >= nb_ready) { -+ skb_queue_splice_init(&txq->sk_list, sk_list_push); -+ credits = nb_ready; -+ res = true; -+ } else { -+ skb_queue_extract(&txq->sk_list, sk_list_push, credits); -+#endif -+ -+ if(credits >= nb_ready) { -+ skb_queue_extract(&txq->sk_list, sk_list_push, nb_ready); -+ credits = nb_ready; -+ res = true; -+ } else { -+ skb_queue_extract(&txq->sk_list, sk_list_push, credits); -+ -+#ifdef CONFIG_BL_FULLMAC -+ /* When processing PS service period (i.e. push_limit != 0), no longer -+ process this txq if this is a legacy PS service period (even if no -+ packet is pushed) or the SP is complete for this txq */ -+ if (txq->push_limit && -+ ((txq->ps_id == LEGACY_PS_ID) || -+ (credits >= txq->push_limit))) -+ res = true; -+#endif -+ } -+ -+ return res; -+} -+ -+/** -+ * bl_hwq_process - Process one HW queue list -+ * -+ * @bl_hw: Driver main data -+ * @hw_queue: HW queue index to process -+ * -+ * The function will iterate over all the TX queues linked in this HW queue -+ * list. For each TX queue, push as many buffers as possible in the HW queue. -+ * (NB: TX queue have at least 1 buffer, otherwise it wouldn't be in the list) -+ * - If TX queue no longer have buffer, remove it from the list and check next -+ * TX queue -+ * - If TX queue no longer have credits or has a push_limit (PS mode) and it -+ * is reached , remove it from the list and check next TX queue -+ * - If HW queue is full, update list head to start with the next TX queue on -+ * next call if current TX queue already pushed "too many" pkt in a row, and -+ * return -+ * -+ * To be called when HW queue list is modified: -+ * - when a buffer is pushed on a TX queue -+ * - when new credits are received -+ * - when a STA returns from Power Save mode or receives traffic request. -+ * - when Channel context change -+ * -+ * To be called with tx_lock hold -+ */ -+#define ALL_HWQ_MASK ((1 << CONFIG_USER_MAX) - 1) -+ -+void bl_hwq_process(struct bl_hw *bl_hw, struct bl_hwq *hwq) -+{ -+ struct bl_txq *txq, *next; -+ int user = 0; -+ -+ trace_process_hw_queue(hwq); -+ -+ list_for_each_entry_safe(txq, next, &hwq->list, sched_list) { -+ struct sk_buff_head sk_list_push; -+ bool txq_empty; -+ -+ trace_process_txq(txq); -+ -+ spin_lock_bh(&bl_hw->txq_lock); -+ -+ BL_DBG("---> txq->idx=%d, hwq->idx=%d, txq->status=0x%x, txq->credits=%d\n", txq->idx, hwq->id, txq->status, txq->credits); -+ /* sanity check for debug */ -+ if(!(txq->status & BL_TXQ_IN_HWQ_LIST)) { -+ printk("txq was not in hwq, but why we probe this txq!\n"); -+ spin_unlock_bh(&bl_hw->txq_lock); -+ break; -+ } -+ BUG_ON(txq->idx == TXQ_INACTIVE); -+// BUG_ON(txq->credits <= 0); -+ if(skb_queue_len(&txq->sk_list) == 0) { -+ printk("there is no skb in txq...\n"); -+ spin_unlock_bh(&bl_hw->txq_lock); -+ continue; -+ } -+ -+ txq_empty = bl_txq_get_skb_to_push(bl_hw, hwq, txq, user, -+ &sk_list_push); -+ spin_unlock_bh(&bl_hw->txq_lock); -+ -+ if(skb_queue_len(&sk_list_push) != 0) -+ bl_tx_multi_pkt_push(bl_hw, &sk_list_push); -+ -+ if (txq_empty) { -+ if(skb_queue_len(&txq->sk_list) == 0) { -+ BL_DBG("txq sk_list empty, delete it\n"); -+ bl_txq_del_from_hw_list(txq); -+ txq->pkt_sent = 0; -+ } else { -+ BL_DBG("txq sk_list is not empty!\n"); -+ } -+ } else { -+ BL_DBG("txq_empty=false, txq->credits=%d\n", txq->credits); -+// if(txq->credits != 0) { -+// break; -+// } -+ } -+ -+#ifdef CONFIG_BL_FULLMAC -+ /* Unable to complete PS traffic request because of hwq credit */ -+ if (txq->push_limit && txq->sta) { -+ BL_DBG("Unable to complete PS traffic request because of hwq credit\n"); -+ if (txq->ps_id == LEGACY_PS_ID) { -+ /* for legacy PS abort SP and wait next ps-poll */ -+ BL_DBG("for legacy PS abort SP and wait next ps-poll\n"); -+ txq->sta->ps.sp_cnt[txq->ps_id] -= txq->push_limit; -+ txq->push_limit = 0; -+ } -+ /* for u-apsd need to complete the SP to send EOSP frame */ -+ } -+ -+ /* restart netdev queue if number of queued buffer is below threshold */ -+ if (unlikely(txq->status & BL_TXQ_NDEV_FLOW_CTRL) && -+ skb_queue_len(&txq->sk_list) < BL_NDEV_FLOW_CTRL_RESTART) { -+ BL_DBG("restart netdev queue if number of queued buffer is below threshold\n"); -+ txq->status &= ~BL_TXQ_NDEV_FLOW_CTRL; -+ netif_wake_subqueue(txq->ndev, txq->ndev_idx); -+ //trace_txq_flowctrl_restart(txq); -+ } -+#endif /* CONFIG_BL_FULLMAC */ -+ } -+} -+ -+/** -+ * bl_hwq_process_all - Process all HW queue list -+ * -+ * @bl_hw: Driver main data -+ * -+ * Loop over all HWQ, and process them if needed -+ * To be called with tx_lock hold -+ */ -+void bl_hwq_process_all(struct bl_hw *bl_hw) -+{ -+ int id; -+ -+ if(!(bl_hw->plat->mp_wr_bitmap & 0xfffe)) -+ return; -+ -+ for (id = ARRAY_SIZE(bl_hw->hwq) - 1; id >= 0 ; id--) { -+ bl_hwq_process(bl_hw, &bl_hw->hwq[id]); -+ } -+} -+ -+ -+/** -+ * bl_hwq_init - Initialize all hwq structures -+ * -+ * @bl_hw: Driver main data -+ * -+ */ -+void bl_hwq_init(struct bl_hw *bl_hw) -+{ -+ int i, j; -+ -+ for (i = 0; i < ARRAY_SIZE(bl_hw->hwq); i++) { -+ struct bl_hwq *hwq = &bl_hw->hwq[i]; -+ -+ for (j = 0 ; j < CONFIG_USER_MAX; j++) -+ hwq->credits[j] = nx_txdesc_cnt[i]; -+ hwq->id = i; -+ hwq->size = nx_txdesc_cnt[i]; -+ INIT_LIST_HEAD(&hwq->list); -+ } -+} -diff -Naur /dev/null_txq.h b/drivers/net/wireless/hflps170/bl_txq.h ---- /dev/null_txq.h 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_txq.h 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,335 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file bl_txq.h -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ **************************************************************************************** -+ */ -+#ifndef _BL_TXQ_H_ -+#define _BL_TXQ_H_ -+ -+#include -+#include -+#include -+ -+/** -+ * Fullmac TXQ configuration: -+ * - STA: 1 TXQ per TID (limited to 8) -+ * 1 txq for bufferable MGT frames -+ * - VIF: 1 tXQ for Multi/Broadcast + -+ * 1 TXQ for MGT for unknown STAs or non-bufferable MGT frames -+ * - 1 TXQ for offchannel transmissions -+ * -+ * -+ * Txq mapping looks like -+ * for NX_REMOTE_STA_MAX=10 and NX_VIRT_DEV_MAX=4 -+ * -+ * | TXQ | NDEV_ID | VIF | STA | TID | HWQ | -+ * |-----+---------+-----+-------+------+-----|- -+ * | 0 | 0 | | 0 | 0 | 1 | 9 TXQ per STA -+ * | 1 | 1 | | 0 | 1 | 0 | (8 data + 1 mgmt) -+ * | 2 | 2 | | 0 | 2 | 0 | -+ * | 3 | 3 | | 0 | 3 | 1 | -+ * | 4 | 4 | | 0 | 4 | 2 | -+ * | 5 | 5 | | 0 | 5 | 2 | -+ * | 6 | 6 | | 0 | 6 | 3 | -+ * | 7 | 7 | | 0 | 7 | 3 | -+ * | 8 | N/A | | 0 | MGMT | 3 | -+ * |-----+---------+-----+-------+------+-----|- -+ * | ... | | | | | | Same for all STAs -+ * |-----+---------+-----+-------+------+-----|- -+ * | 90 | 80 | 0 | BC/MC | 0 | 1/4 | 1 TXQ for BC/MC per VIF -+ * | ... | | | | | | -+ * | 93 | 80 | 3 | BC/MC | 0 | 1/4 | -+ * |-----+---------+-----+-------+------+-----|- -+ * | 94 | N/A | 0 | N/A | MGMT | 3 | 1 TXQ for unknown STA per VIF -+ * | ... | | | | | | -+ * | 97 | N/A | 3 | N/A | MGMT | 3 | -+ * |-----+---------+-----+-------+------+-----|- -+ * | 98 | N/A | | N/A | MGMT | 3 | 1 TXQ for offchannel frame -+ */ -+#define NX_NB_TID_PER_STA 8 -+#define NX_NB_TXQ_PER_STA (NX_NB_TID_PER_STA + 1) -+#define NX_NB_TXQ_PER_VIF 2 -+#define NX_NB_TXQ ((NX_NB_TXQ_PER_STA * NX_REMOTE_STA_MAX) + \ -+ (NX_NB_TXQ_PER_VIF * NX_VIRT_DEV_MAX) + 1) -+ -+#define NX_FIRST_VIF_TXQ_IDX (NX_REMOTE_STA_MAX * NX_NB_TXQ_PER_STA) -+#define NX_FIRST_BCMC_TXQ_IDX NX_FIRST_VIF_TXQ_IDX -+#define NX_FIRST_UNK_TXQ_IDX (NX_FIRST_BCMC_TXQ_IDX + NX_VIRT_DEV_MAX) -+ -+#define NX_OFF_CHAN_TXQ_IDX (NX_FIRST_VIF_TXQ_IDX + \ -+ (NX_VIRT_DEV_MAX * NX_NB_TXQ_PER_VIF)) -+#define NX_BCMC_TXQ_TYPE 0 -+#define NX_UNK_TXQ_TYPE 1 -+ -+/** -+ * Each data TXQ is a netdev queue. TXQ to send MGT are not data TXQ as -+ * they did not recieved buffer from netdev interface. -+ * Need to allocate the maximum case. -+ * AP : all STAs + 1 BC/MC -+ */ -+#define NX_NB_NDEV_TXQ ((NX_NB_TID_PER_STA * NX_REMOTE_STA_MAX) + 1 ) -+#define NX_BCMC_TXQ_NDEV_IDX (NX_NB_TID_PER_STA * NX_REMOTE_STA_MAX) -+#define NX_STA_NDEV_IDX(tid, sta_idx) ((tid) + (sta_idx) * NX_NB_TID_PER_STA) -+#define NDEV_NO_TXQ 0xffff -+#if (NX_NB_NDEV_TXQ >= NDEV_NO_TXQ) -+#error("Need to increase struct bl_txq->ndev_idx size") -+#endif -+ -+/* stop netdev queue when number of queued buffers if greater than this */ -+#define BL_NDEV_FLOW_CTRL_STOP 200//32 -+/* restart netdev queue when number of queued buffers is lower than this */ -+#define BL_NDEV_FLOW_CTRL_RESTART 32//16 -+ -+#define TXQ_INACTIVE 0xffff -+#if (NX_NB_TXQ >= TXQ_INACTIVE) -+#error("Need to increase struct bl_txq->idx size") -+#endif -+ -+#define NX_TXQ_INITIAL_CREDITS 32 -+ -+/** -+ * struct bl_hwq - Structure used to save information relative to -+ * an AC TX queue (aka HW queue) -+ * @list: List of TXQ, that have buffers ready for this HWQ -+ * @credits: available credit for the queue (i.e. nb of buffers that -+ * can be pushed to FW ) -+ * @id Id of the HWQ among BL_HWQ_.... -+ * @size size of the queue -+ * @need_processing Indicate if hwq should be processed -+ * @len number of packet ready to be pushed to fw for this HW queue -+ * @len_stop threshold to stop mac80211(i.e. netdev) queues. Stop queue when -+ * driver has more than @len_stop packets ready. -+ * @len_start threshold to wake mac8011 queues. Wake queue when driver has -+ * less than @len_start packets ready. -+ */ -+struct bl_hwq { -+ struct list_head list; -+ u8 credits[CONFIG_USER_MAX]; -+ u8 size; -+ u8 id; -+ bool need_processing; -+}; -+ -+/** -+ * enum bl_push_flags - Flags of pushed buffer -+ * -+ * @BL_PUSH_RETRY Pushing a buffer for retry -+ * @BL_PUSH_IMMEDIATE Pushing a buffer without queuing it first -+ */ -+enum bl_push_flags { -+ BL_PUSH_RETRY = BIT(0), -+ BL_PUSH_IMMEDIATE = BIT(1), -+}; -+ -+/** -+ * enum bl_txq_flags - TXQ status flag -+ * -+ * @BL_TXQ_IN_HWQ_LIST The queue is scheduled for transmission -+ * @BL_TXQ_STOP_FULL No more credits for the queue -+ * @BL_TXQ_STOP_CSA CSA is in progress -+ * @BL_TXQ_STOP_STA_PS Destiniation sta is currently in power save mode -+ * @BL_TXQ_STOP_VIF_PS Vif owning this queue is currently in power save mode -+ * @BL_TXQ_STOP_CHAN Channel of this queue is not the current active channel -+ * @BL_TXQ_STOP_MU_POS TXQ is stopped waiting for all the buffers pushed to -+ * fw to be confirmed -+ * @BL_TXQ_STOP All possible reason to have a txq stopped -+ * @BL_TXQ_NDEV_FLOW_CTRL associated netdev queue is currently stopped. -+ * Note: when a TXQ is flowctrl it is NOT stopped -+ */ -+enum bl_txq_flags { -+ BL_TXQ_IN_HWQ_LIST = BIT(0), -+ BL_TXQ_STOP_FULL = BIT(1), -+ BL_TXQ_STOP_CSA = BIT(2), -+ BL_TXQ_STOP_STA_PS = BIT(3), -+ BL_TXQ_STOP_VIF_PS = BIT(4), -+ BL_TXQ_STOP_CHAN = BIT(5), -+ BL_TXQ_STOP_MU_POS = BIT(6), -+ BL_TXQ_STOP = (BL_TXQ_STOP_FULL | BL_TXQ_STOP_CSA | -+ BL_TXQ_STOP_STA_PS | BL_TXQ_STOP_VIF_PS | -+ BL_TXQ_STOP_CHAN) , -+ BL_TXQ_NDEV_FLOW_CTRL = BIT(7), -+}; -+ -+ -+/** -+ * struct bl_txq - Structure used to save information relative to -+ * a RA/TID TX queue -+ * -+ * @idx: Unique txq idx. Set to TXQ_INACTIVE if txq is not used. -+ * @status: bitfield of @bl_txq_flags. -+ * @credits: available credit for the queue (i.e. nb of buffers that -+ * can be pushed to FW). -+ * @pkt_sent: number of consecutive pkt sent without leaving HW queue list -+ * @pkt_pushed: number of pkt currently pending for transmission confirmation -+ * @sched_list: list node for HW queue schedule list (bl_hwq.list) -+ * @sk_list: list of buffers to push to fw -+ * @last_retry_skb: pointer on the last skb in @sk_list that is a retry. -+ * (retry skb are stored at the beginning of the list) -+ * NULL if no retry skb is queued in @sk_list -+ * @nb_retry: Number of retry packet queued. -+ * @hwq: Pointer on the associated HW queue. -+ * -+ * SOFTMAC specific: -+ * @baw: Block Ack window information -+ * @amsdu_anchor: pointer to bl_sw_txhdr of the first subframe of the A-MSDU. -+ * NULL if no A-MSDU frame is in construction -+ * @amsdu_ht_len_cap: -+ * @amsdu_vht_len_cap: -+ * @tid: -+ * -+ * FULLMAC specific -+ * @ps_id: Index to use for Power save mode (LEGACY or UAPSD) -+ * @push_limit: number of packet to push before removing the txq from hwq list. -+ * (we always have push_limit < skb_queue_len(sk_list)) -+ * @ndev_idx: txq idx from netdev point of view (0xFF for non netdev queue) -+ * @ndev: pointer to ndev of the corresponding vif -+ * @amsdu: pointer to bl_sw_txhdr of the first subframe of the A-MSDU. -+ * NULL if no A-MSDU frame is in construction -+ * @amsdu_len: Maximum size allowed for an A-MSDU. 0 means A-MSDU not allowed -+ */ -+struct bl_txq { -+ u16 idx; -+ u8 status; -+ s8 credits; -+ u8 pkt_sent; -+ u8 pkt_pushed[CONFIG_USER_MAX]; -+ struct list_head sched_list; -+ struct sk_buff_head sk_list; -+ struct sk_buff *last_retry_skb; -+ struct bl_hwq *hwq; -+ int nb_retry; -+ struct bl_sta *sta; -+ u8 ps_id; -+ u8 push_limit; -+ u16 ndev_idx; -+ struct net_device *ndev; -+ #ifdef CONFIG_BL_AMSDUS_TX -+ struct bl_sw_txhdr *amsdu; -+ u16 amsdu_len; -+ #endif /* CONFIG_BL_AMSDUS_TX */ -+}; -+ -+struct bl_sta; -+struct bl_vif; -+struct bl_hw; -+struct bl_sw_txhdr; -+ -+#define BL_TXQ_GROUP_ID(txq) 0 -+#define BL_TXQ_POS_ID(txq) 0 -+ -+static inline bool bl_txq_is_stopped(struct bl_txq *txq) -+{ -+ return (txq->status & BL_TXQ_STOP); -+} -+ -+static inline bool bl_txq_is_full(struct bl_txq *txq) -+{ -+ return (txq->status & BL_TXQ_STOP_FULL); -+} -+ -+static inline bool bl_txq_is_scheduled(struct bl_txq *txq) -+{ -+ return (txq->status & BL_TXQ_IN_HWQ_LIST); -+} -+ -+/* -+ * if -+ * - txq is not stopped -+ * - hwq has credits -+ * - there is no buffer queued -+ * then a buffer can be immediately pushed without having to queue it first -+ */ -+static inline bool bl_txq_is_ready_for_push(struct bl_txq *txq) -+{ -+ return (!bl_txq_is_stopped(txq) && -+ txq->hwq->credits[BL_TXQ_POS_ID(txq)] > 0 && -+ skb_queue_empty(&txq->sk_list)); -+} -+ -+ -+/** -+ * extract the first @nb_elt of @list and append them to @head -+ * It is assume that: -+ * - @list contains more that @nb_elt -+ * - There is no need to take @list nor @head lock to modify them -+ */ -+static inline void skb_queue_extract(struct sk_buff_head *list, -+ struct sk_buff_head *head, int nb_elt) -+{ -+ int i; -+ struct sk_buff *first, *last, *ptr; -+ -+ first = ptr = list->next; -+ for (i = 0; i < nb_elt; i++) { -+ ptr = ptr->next; -+ } -+ last = ptr->prev; -+ -+ /* unlink nb_elt in list */ -+ list->qlen -= nb_elt; -+ list->next = ptr; -+ ptr->prev = (struct sk_buff *)list; -+ -+ /* append nb_elt at end of head */ -+ head->qlen += nb_elt; -+ last->next = (struct sk_buff *)head; -+ head->prev->next = first; -+ first->prev = head->prev; -+ head->prev = last; -+} -+ -+struct bl_txq *bl_txq_sta_get(struct bl_sta *sta, u8 tid, int *idx, -+ struct bl_hw * bl_hw); -+struct bl_txq *bl_txq_vif_get(struct bl_vif *vif, u8 type, int *idx); -+ -+/* return status bits related to the vif */ -+static inline u8 bl_txq_vif_get_status(struct bl_vif *bl_vif) -+{ -+ struct bl_txq *txq = bl_txq_vif_get(bl_vif, 0, NULL); -+ return (txq->status & (BL_TXQ_STOP_CHAN | BL_TXQ_STOP_VIF_PS)); -+} -+ -+void bl_txq_vif_init(struct bl_hw * bl_hw, struct bl_vif *vif, -+ u8 status); -+void bl_txq_vif_deinit(struct bl_hw * bl_hw, struct bl_vif *vif); -+void bl_txq_sta_init(struct bl_hw * bl_hw, struct bl_sta *bl_sta, -+ u8 status); -+void bl_txq_sta_deinit(struct bl_hw * bl_hw, struct bl_sta *bl_sta); -+#ifdef CONFIG_BL_FULLMAC -+void bl_txq_offchan_init(struct bl_vif *bl_vif); -+void bl_txq_offchan_deinit(struct bl_vif *bl_vif); -+#endif -+ -+ -+void bl_txq_add_to_hw_list(struct bl_txq *txq); -+void bl_txq_del_from_hw_list(struct bl_txq *txq); -+void bl_txq_stop(struct bl_txq *txq, u16 reason); -+void bl_txq_start(struct bl_txq *txq, u16 reason); -+void bl_txq_vif_start(struct bl_vif *vif, u16 reason, -+ struct bl_hw *bl_hw); -+void bl_txq_vif_stop(struct bl_vif *vif, u16 reason, -+ struct bl_hw *bl_hw); -+ -+void bl_txq_sta_start(struct bl_sta *sta, u16 reason, -+ struct bl_hw *bl_hw); -+void bl_txq_sta_stop(struct bl_sta *sta, u16 reason, -+ struct bl_hw *bl_hw); -+void bl_txq_offchan_start(struct bl_hw *bl_hw); -+void bl_txq_sta_switch_vif(struct bl_sta *sta, struct bl_vif *old_vif, -+ struct bl_vif *new_vif); -+ -+int bl_txq_queue_skb(struct sk_buff *skb, struct bl_txq *txq, -+ struct bl_hw *bl_hw, bool retry); -+void bl_txq_confirm_any(struct bl_hw *bl_hw, struct bl_txq *txq, -+ struct bl_hwq *hwq, struct bl_sw_txhdr *sw_txhdr); -+ -+ -+void bl_hwq_init(struct bl_hw *bl_hw); -+void bl_hwq_process(struct bl_hw *bl_hw, struct bl_hwq *hwq); -+void bl_hwq_process_all(struct bl_hw *bl_hw); -+ -+#endif /* _BL_TXQ_H_ */ -diff -Naur /dev/null_utils.c b/drivers/net/wireless/hflps170/bl_utils.c ---- /dev/null_utils.c 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_utils.c 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,415 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file bl_utils.c -+ * -+ * @brief IPC utility function definitions -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ **************************************************************************************** -+ */ -+#include -+#include -+#include -+#include -+ -+#include "bl_utils.h" -+#include "bl_defs.h" -+#include "bl_rx.h" -+#include "bl_tx.h" -+#include "bl_msg_rx.h" -+#include "bl_debugfs.h" -+ -+#ifdef CONFIG_BL_MOD_LEV_DBG -+unsigned long bl_filter_severity = 0xffffffff; -+unsigned long bl_filter_module = 0x0; -+#else -+unsigned long bl_filter_severity; -+unsigned long bl_filter_module; -+#endif -+ -+struct device_attribute dev_attr_filter_severity; -+EXPORT_SYMBOL_GPL(dev_attr_filter_severity); -+struct device_attribute dev_attr_filter_module; -+EXPORT_SYMBOL_GPL(dev_attr_filter_module); -+ -+module_param(bl_filter_severity, ulong, S_IRUGO|S_IWUSR); -+MODULE_PARM_DESC(bl_filter_severity, "used to filter severity"); -+module_param(bl_filter_module, ulong, S_IRUGO|S_IWUSR); -+MODULE_PARM_DESC(bl_filter_module, "used to filter module"); -+ -+static ssize_t filter_severity_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ return sprintf(buf, "%lx\n", bl_filter_severity); -+} -+ -+static ssize_t filter_severity_store(struct device *dev, -+ struct device_attribute *attr, const char *buf, -+ size_t count) -+{ -+ if (sscanf(buf, "%lx", &bl_filter_severity) != 1) -+ return -EINVAL; -+ return count; -+} -+DEVICE_ATTR_RW(filter_severity); -+ -+static ssize_t filter_module_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ return sprintf(buf, "%lx\n", bl_filter_module); -+} -+ -+static ssize_t filter_module_store(struct device *dev, -+ struct device_attribute *attr, const char *buf, -+ size_t count) -+{ -+ if (sscanf(buf, "%lx", &bl_filter_module) != 1) -+ return -EINVAL; -+ return count; -+} -+DEVICE_ATTR_RW(filter_module); -+ -+void log_buf_output(struct bl_hw *bl_hw, const char* buf, size_t size) { -+ size_t write_size = 0, write_index = 0; -+ //char tmp_buf[256] = {0}; -+ -+ while (true) { -+ if (bl_hw->buf_write_size + size > LOG_BUF_OUTPUT_BUF_SIZE) { -+ write_size = LOG_BUF_OUTPUT_BUF_SIZE - bl_hw->buf_write_size; -+ memcpy(bl_hw->log_buff + bl_hw->buf_write_size, buf + write_index, write_size); -+ //snprintf(tmp_buf, write_size, "%s", buf + write_index); -+ write_index += write_size; -+ size -= write_size; -+ /* reset write index */ -+ bl_hw->buf_write_size = 0; -+ } else { -+ memcpy(bl_hw->log_buff + bl_hw->buf_write_size, buf + write_index, size); -+ bl_hw->buf_write_size += size; -+ break; -+ } -+ } -+} -+ -+size_t bl_log_strcpy(size_t cur_len, char *dst, const char *src) { -+ const char *src_old = src; -+ -+ ASSERT_ERR(dst); -+ ASSERT_ERR(src); -+ -+ while (*src != 0) { -+ /* make sure destination has enough space */ -+ if (cur_len++ < LOG_LINE_BUF_SIZE) { -+ *dst++ = *src++; -+ } else { -+ break; -+ } -+ } -+ return src - src_old; -+} -+ -+#define LOG_LINE_NUM_MAX_LEN 5 -+static void bl_do_log(struct bl_hw *bl_hw, const char *func, const long line, const char *fmt_usr, va_list args) -+{ -+ static char buf[LOG_LINE_BUF_SIZE]; -+ char line_num[LOG_LINE_NUM_MAX_LEN + 1] = { 0 }; -+ int log_len = 0; -+ -+ snprintf(line_num, LOG_LINE_NUM_MAX_LEN, "%ld", line); -+ log_len += bl_log_strcpy(log_len, buf + log_len, line_num); -+ log_len += bl_log_strcpy(log_len, buf + log_len, ":"); -+ log_len += bl_log_strcpy(log_len, buf + log_len, func); -+ log_len += bl_log_strcpy(log_len, buf + log_len, ":"); -+ -+ log_len += vsnprintf(buf + log_len, LOG_LINE_BUF_SIZE - log_len, fmt_usr, args); -+ log_buf_output(bl_hw, buf, log_len); -+ //printk("%s", buf); -+} -+ -+/** -+ **************************************************************************************** -+ * @brief Function formatting a string and sending it to the defined output -+ * -+ * @param[in] fmt Format string -+ * -+ **************************************************************************************** -+ */ -+void dbg_test_print(struct bl_hw *bl_hw, const char *func, const long line, const char *fmt, ...) -+{ -+ const char *fmt_usr = (const char*) fmt; -+ uint32_t severity = 0; -+ va_list args; -+ va_start(args, fmt); -+ -+ //printk("%d %d %d %d\n", fmt_usr[0], fmt_usr[1], DBG_MOD_MAX, DBG_SEV_MIN); -+ -+ // permit all the debug message is permited -+ bl_filter_severity = DBG_SEV_MAX; -+ -+ if (bl_filter_severity == 0) return; -+ -+ do -+ { -+ // Get the prefix -+ unsigned char prefix = ((unsigned char)*fmt_usr) & 0xFF; -+ -+ // ASCII char, start of the user string -+ if (prefix < DBG_MOD_MIN) break; -+ -+ if (prefix < DBG_MOD_MAX) -+ { -+ // test module, if filtered returns -+ if (~bl_filter_module & CO_BIT(prefix - DBG_MOD_MIN)) return; -+ } -+ else -+ { -+ // must be severity code -+ ASSERT_ERR(DBG_SEV_MIN <= prefix && prefix < DBG_SEV_MAX); -+ severity = (uint32_t)(prefix - DBG_SEV_MIN); -+ -+ // test severity, if filtered returns -+ if (bl_filter_severity <= severity) return; -+ } -+ -+ // Check first and second char -+ fmt_usr++; -+ } -+ while (fmt_usr != fmt + 2); -+ -+ // print -+ bl_do_log(bl_hw, func, line, fmt_usr, args); -+ -+ va_end(args); -+} -+ -+ -+/** -+ * -+ */ -+static int dbginfo_allocs(struct bl_hw *bl_hw) -+{ -+ struct dbg_debug_dump_tag *buf; -+ u32 len = sizeof(*buf); -+ -+ /* Allocate the debug information buffer */ -+ buf = kmalloc(len, GFP_KERNEL); -+ -+ if (!buf) { -+ printk(KERN_CRIT "%s:%d: buffer alloc of size %u failed\n\n", -+ __func__, __LINE__, len); -+ return -ENOMEM; -+ } -+ bl_hw->dbginfo.buf = buf; -+ -+ return 0; -+} -+ -+/** -+ * -+ */ -+static void bl_dbginfo_deallocs(struct bl_hw *bl_hw) -+{ -+ if (bl_hw->dbginfo.buf) { -+ kfree(bl_hw->dbginfo.buf); -+ bl_hw->dbginfo.buf = NULL; -+ } -+} -+ -+ -+/** -+ * @brief Deallocate storage elements. -+ * -+ * This function deallocates all the elements required for communications with LMAC, -+ * such as Rx Data elements, MSGs elements, ... -+ * -+ * This function should be called in correspondence with the allocation function. -+ * -+ * @param[in] bl_hw Pointer to main structure storing all the relevant information -+ */ -+static void bl_elems_deallocs(struct bl_hw *bl_hw) -+{ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ bl_dbginfo_deallocs(bl_hw); -+} -+ -+/** -+ * @brief Allocate storage elements. -+ * -+ * This function allocates all the elements required for communications with LMAC, -+ * such as Rx Data elements, MSGs elements, ... -+ * -+ * This function should be called in correspondence with the deallocation function. -+ * -+ * @param[in] bl_hw Pointer to main structure storing all the relevant information -+ */ -+static int bl_elems_allocs(struct bl_hw *bl_hw) -+{ -+ BL_DBG(BL_FN_ENTRY_STR); -+ /* Initialize the debug information buffer */ -+ if (dbginfo_allocs(bl_hw)) { -+ printk(KERN_CRIT "%s:%d: ALLOCATIONS FAILED !\n", __func__, -+ __LINE__); -+ goto err_alloc; -+ } -+ -+ return 0; -+ -+err_alloc: -+ bl_elems_deallocs(bl_hw); -+ return -ENOMEM; -+} -+ -+/** -+ * WLAN driver call-back function for message reception indication -+ */ -+u8 bl_msgind(void *pthis, void *hostid) -+{ -+ u8 ret = 0; -+ struct bl_hw *bl_hw = (struct bl_hw *)pthis; -+ struct ipc_e2a_msg *msg = (struct ipc_e2a_msg *)hostid; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Relay further actions to the msg parser */ -+ bl_rx_handle_msg(bl_hw, msg); -+ -+ return ret; -+} -+ -+/** -+ * FIXME -+ * -+ */ -+u8 bl_msgackind(void *pthis, void *hostid) -+{ -+ struct bl_hw *bl_hw = (struct bl_hw *)pthis; -+ -+ bl_hw->cmd_mgr.llind(&bl_hw->cmd_mgr, (struct bl_cmd *)hostid); -+ -+ return -1; -+} -+ -+/** -+ * WLAN driver call-back function for primary TBTT indication -+ */ -+void bl_prim_tbtt_ind(void *pthis) -+{ -+} -+ -+/** -+ * WLAN driver call-back function for secondary TBTT indication -+ */ -+void bl_sec_tbtt_ind(void *pthis) -+{ -+ /* TODO */ -+} -+ -+/** -+ * WLAN driver call-back function for Debug message reception indication -+ */ -+u8 bl_dbgind(void *pthis, void *hostid) -+{ -+ struct bl_dbg_elem *dbg_elem = hostid; -+ struct ipc_dbg_msg *dbg_msg; -+ u8 ret = 0; -+ -+ /* Retrieve the message structure */ -+ dbg_msg = (struct ipc_dbg_msg *)dbg_elem->dbgbuf_ptr; -+ -+ /* Look for pattern which means that this hostbuf has been used for a MSG */ -+ if (dbg_msg->pattern != IPC_DBG_VALID_PATTERN) { -+ ret = -1; -+ goto dbg_no_push; -+ } -+ -+ /* Display the LMAC string */ -+ printk("lmac %s", (char *)dbg_msg->string); -+ -+ /* Reset the msg element and re-use it */ -+ dbg_msg->pattern = 0; -+ wmb(); -+ -+dbg_no_push: -+ return ret; -+} -+ -+int bl_ipc_init(struct bl_hw *bl_hw) -+{ -+ struct ipc_host_cb_tag cb; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* initialize the API interface */ -+ cb.recv_data_ind = bl_rxdataind; -+ cb.recv_msg_ind = bl_msgind; -+ cb.recv_msgack_ind = bl_msgackind; -+ cb.recv_dbg_ind = bl_dbgind; -+ cb.send_data_cfm = bl_txdatacfm; -+ cb.prim_tbtt_ind = bl_prim_tbtt_ind; -+ cb.sec_tbtt_ind = bl_sec_tbtt_ind; -+ -+ /* set the IPC environment */ -+ bl_hw->ipc_env = (struct ipc_host_env_tag *) -+ kzalloc(sizeof(struct ipc_host_env_tag), GFP_KERNEL); -+ -+ /* call the initialization of the IPC */ -+ ipc_host_init(bl_hw->ipc_env, &cb, bl_hw); -+ -+ bl_cmd_mgr_init(&bl_hw->cmd_mgr); -+ -+ return bl_elems_allocs(bl_hw); -+} -+ -+/** -+ * -+ */ -+void bl_ipc_deinit(struct bl_hw *bl_hw) -+{ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ bl_ipc_tx_drain(bl_hw); -+ bl_cmd_mgr_deinit(&bl_hw->cmd_mgr); -+ bl_elems_deallocs(bl_hw); -+ kfree(bl_hw->ipc_env); -+ bl_hw->ipc_env = NULL; -+} -+ -+/** -+ * This assumes LMAC is still (tx wise) and there's no TX race until LMAC is up -+ * tx wise. -+ * This also lets both IPC sides remain in sync before resetting the LMAC, -+ * e.g with bl_send_reset. -+ */ -+void bl_ipc_tx_drain(struct bl_hw *bl_hw) -+{ -+ int i, j; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ if (!bl_hw->ipc_env) { -+ printk("%s: bypassing (restart must have failed)\n", __func__); -+ return; -+ } -+ -+ for (i = 0; i < BL_HWQ_NB; i++) { -+ for (j = 0; j < nx_txuser_cnt[i]; j++) { -+ struct sk_buff *skb; -+ while ((skb = (struct sk_buff *)ipc_host_tx_flush(bl_hw->ipc_env, i, j))) { -+ struct bl_sw_txhdr *sw_txhdr = -+ ((struct bl_txhdr *)skb->data)->sw_hdr; -+ skb_pull(skb, sw_txhdr->headroom); -+ dev_kfree_skb_any(skb); -+ } -+ } -+ } -+} -+ -+void bl_error_ind(struct bl_hw *bl_hw) -+{ -+ printk(KERN_CRIT "%s (type %d): dump received\n", __func__, -+ bl_hw->dbginfo.buf->dbg_info.error_type); -+ bl_hw->debugfs.trace_prst = true; -+} -+ -diff -Naur /dev/null_utils.h b/drivers/net/wireless/hflps170/bl_utils.h ---- /dev/null_utils.h 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_utils.h 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,275 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file bl_ipc_utils.h -+ * -+ * @brief IPC utility function declarations -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ ****************************************************************************** -+ */ -+ -+#ifndef _BL_IPC_UTILS_H_ -+#define _BL_IPC_UTILS_H_ -+ -+#include -+#include -+ -+#include "lmac_msg.h" -+#include "ipc_host.h" -+#include "bl_cmds.h" -+ -+ -+#ifdef CONFIG_BL_DBG -+#define BL_DBG printk -+//#define BL_DBG(f, args...) trace_printk(f, ##args) -+#else -+#define BL_DBG(a...) do {} while (0) -+#endif -+ -+#define LOG_BUF_SIZE (32*PAGE_SIZE) -+#define LOG_NEWLINE_SIGN "\n" -+/* buffer size for every line's log */ -+#define LOG_LINE_BUF_SIZE 256 -+#define LOG_BUF_OUTPUT_BUF_SIZE (LOG_LINE_BUF_SIZE*4*4*32) -+ -+// Prefix used for module filtering -+// If you modify any value, modify also DBG_MOD_ macros below -+#define D_INI "\x80" ///< Prefix for Init -+#define D_MSG "\x81" ///< Prefix for MSG -+#define D_TX "\x82" ///< Prefix for TX -+#define D_RX "\x83" ///< Prefix for RX -+#define D_CREDIT "\x84" ///< Prefix for CREDIT -+#define D_AGGR "\x85" ///< Prefix for AGGR -+#define D_XX0 "\x86" ///< Prefix unused -+#define D_XX1 "\x87" ///< Prefix unused -+#define D_XX2 "\x88" ///< Prefix unused -+#define D_XX3 "\x89" ///< Prefix unused -+#define D_XX4 "\x8A" ///< Prefix unused -+#define D_XX5 "\x8B" ///< Prefix unused -+#define D_XX6 "\x8C" ///< Prefix unused -+ -+// Prefix used for severity filtering -+// If you modify any value, modify also DBG_SEV_ macros below -+#define D_CRT "\x9A" ///< Prefix for critical -+#define D_ERR "\x9B" ///< Prefix for error -+#define D_WRN "\x9C" ///< Prefix for warning -+#define D_INF "\x9D" ///< Prefix for info -+#define D_VRB "\x9E" ///< Prefix for verbose debug -+ -+/// Module filtering macros, used only by debug module -+enum dbg_mod_tag -+{ -+ DBG_MOD_IDX_INI = 0, ///< Bit index for init -+ DBG_MOD_IDX_MSG, ///< Bit index for msg -+ DBG_MOD_IDX_TX, ///< Bit index for tx -+ DBG_MOD_IDX_RX, ///< Bit index for rx -+ DBG_MOD_IDX_CREDIT, ///< Bit index for credit -+ DBG_MOD_IDX_AGGR, ///< Bit index for aggr -+ DBG_MOD_IDX_MAX, ///< Number of modules -+}; -+ -+#define DBG_MOD_MIN 0x80 -+#define DBG_MOD_MAX (DBG_MOD_MIN + DBG_MOD_IDX_MAX) -+ -+#define DBG_MOD_ALL 0xFFFFFFFF -+ -+/// Severity filtering macros, used only by debug module -+enum dbg_sev_tag -+{ -+ DBG_SEV_IDX_NONE = 0, ///< No print allowed -+ DBG_SEV_IDX_CRT, ///< Critical and unspecified allowed only -+ DBG_SEV_IDX_ERR, ///< Error allowed and above -+ DBG_SEV_IDX_WRN, ///< Warning allowed and above -+ DBG_SEV_IDX_INF, ///< Info allowed and above -+ DBG_SEV_IDX_VRB, ///< All allowed -+ DBG_SEV_IDX_MAX, ///< Number of severity levels -+ DBG_SEV_ALL ///< Convenient macro -+}; -+ -+#define DBG_SEV_MIN 0x9A -+#define DBG_SEV_MAX 0xA0 -+ -+#ifdef CONFIG_BL_MOD_LEV_DBG -+ void dbg_test_print(struct bl_hw *bl_hw, const char *func, const long line, const char *fmt, ...); -+ #define BL_DBG_MOD_LEVEL(bl_hw, fmt, ...) dbg_test_print(bl_hw, __func__, __LINE__, fmt, ## __VA_ARGS__) -+#else -+ #define BL_DBG_MOD_LEVEL(bl_hw, fmt, ...) do {} while (0) -+#endif -+ -+#define BL_FN_ENTRY_STR ">>> %s()\n", __func__ -+ -+enum bl_dev_flag { -+ BL_DEV_RESTARTING, -+ BL_DEV_STACK_RESTARTING, -+ BL_DEV_STARTED, -+}; -+ -+struct bl_preq_ie_elem { -+ u8 *buf; -+ dma_addr_t dma_addr; -+ int bufsz; -+}; -+ -+struct bl_dma_elem { -+ u8 *buf; -+ dma_addr_t dma_addr; -+ int len; -+}; -+ -+struct bl_patternbuf { -+ u32 *buf; -+ dma_addr_t dma_addr; -+ int bufsz; -+}; -+ -+struct bl_labuf { -+ u8 *buf; -+ dma_addr_t dma_addr; -+ int bufsz; -+}; -+ -+struct bl_dbginfo { -+ struct mutex mutex; -+ struct dbg_debug_dump_tag *buf; -+ dma_addr_t dma_addr; -+ int bufsz; -+}; -+ -+#define BL_RXBUFF_PATTERN (0xCAFEFADE) -+ -+/* Maximum number of rx buffer the fw may use at the same time */ -+#define BL_RXBUFF_MAX (64 * 10) -+ -+/** -+ * struct bl_skb_cb - Control Buffer structure for RX buffer -+ * -+ * @dma_addr: DMA address of the data buffer -+ * @pattern: Known pattern (used to check pointer on skb) -+ * @idx: Index in bl_hw.rxbuff_table to contians address of this buffer -+ */ -+struct bl_skb_cb { -+ dma_addr_t dma_addr; -+ uint32_t pattern; -+ uint32_t idx; -+}; -+ -+#define BL_RXBUFF_DMA_ADDR_SET(skbuff, addr) \ -+ ((struct bl_skb_cb *)(skbuff->cb))->dma_addr = addr -+#define BL_RXBUFF_DMA_ADDR_GET(skbuff) \ -+ ((struct bl_skb_cb *)(skbuff->cb))->dma_addr -+ -+#define BL_RXBUFF_PATTERN_SET(skbuff, pat) \ -+ ((struct bl_skb_cb *)(skbuff->cb))->pattern = pat -+#define BL_RXBUFF_PATTERN_GET(skbuff) \ -+ ((struct bl_skb_cb *)(skbuff->cb))->pattern -+ -+#define BL_RXBUFF_IDX_SET(skbuff, val) \ -+ ((struct bl_skb_cb *)(skbuff->cb))->idx = val -+#define BL_RXBUFF_IDX_GET(skbuff) \ -+ ((struct bl_skb_cb *)(skbuff->cb))->idx -+ -+#define BL_RXBUFF_VALID_IDX(idx) ((idx) < BL_RXBUFF_MAX) -+ -+/* Used to ensure that hostid set to fw is never 0 */ -+#define BL_RXBUFF_IDX_TO_HOSTID(idx) ((idx) + 1) -+#define BL_RXBUFF_HOSTID_TO_IDX(hostid) ((hostid) - 1) -+ -+struct bl_e2arxdesc_elem { -+ struct rxdesc_tag *rxdesc_ptr; -+ dma_addr_t dma_addr; -+}; -+ -+/* -+ * Structure used to store information regarding E2A radar events in the driver -+ */ -+struct bl_e2aradar_elem { -+ struct radar_pulse_array_desc *radarbuf_ptr; -+ dma_addr_t dma_addr; -+}; -+ -+/* -+ * Structure used to store information regarding E2A msg buffers in the driver -+ */ -+struct bl_e2amsg_elem { -+ struct ipc_e2a_msg *msgbuf_ptr; -+ dma_addr_t dma_addr; -+}; -+ -+/* -+ * Structure used to store information regarding Debug msg buffers in the driver -+ */ -+struct bl_dbg_elem { -+ struct ipc_dbg_msg *dbgbuf_ptr; -+ dma_addr_t dma_addr; -+}; -+ -+/** -+ ****************************************************************************** -+ * @brief Initialize IPC interface. -+ * -+ * This function initializes IPC interface by registering callbacks, setting -+ * shared memory area and calling IPC Init function. -+ * -+ * This function should be called only once during driver's lifetime. -+ * -+ * @param[in] bl_hw Pointer to main structure storing all the -+ * relevant information -+ * @param[in] ipc_shared_mem -+ * -+ ****************************************************************************** -+ */ -+int bl_ipc_init(struct bl_hw *bl_hw); -+ -+/** -+ ****************************************************************************** -+ * @brief Release IPC interface. -+ * -+ * @param[in] bl_hw Pointer to main structure storing all the relevant -+ * information -+ * -+ ****************************************************************************** -+ */ -+void bl_ipc_deinit(struct bl_hw *bl_hw); -+ -+/** -+ ****************************************************************************** -+ * @brief Flush IPC . -+ * -+ * @param[in] bl_hw Pointer to main structure storing all the relevant -+ * information -+ * -+ ****************************************************************************** -+ */ -+void bl_ipc_tx_drain(struct bl_hw *bl_hw); -+ -+/** -+ ****************************************************************************** -+ * @brief Function called upon DBG_ERROR_IND message reception. -+ * This function triggers the UMH script call that will indicate to the user -+ * space the error that occurred and stored the debug dump. Once the UMH script -+ * is executed, the bl_umh_done function has to be called. -+ * -+ * @param[in] bl_hw Pointer to main structure storing all the relevant -+ * information -+ * -+ ****************************************************************************** -+ */ -+void bl_error_ind(struct bl_hw *bl_hw); -+ -+/** -+ ****************************************************************************** -+ * @brief Function called once UMH script execution is finished. -+ * -+ * @param[in] bl_hw Pointer to main structure storing all the relevant -+ * information -+ * -+ ****************************************************************************** -+ */ -+void bl_umh_done(struct bl_hw *bl_hw); -+ -+struct bl_sta *bl_get_sta(struct bl_hw *bl_hw, const u8 *mac_addr); -+ -+ -+#endif /* _BL_IPC_UTILS_H_ */ -diff -Naur /dev/null_v7.c b/drivers/net/wireless/hflps170/bl_v7.c ---- /dev/null_v7.c 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_v7.c 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,139 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file bl_v7.c - Support for v7 platform -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ ****************************************************************************** -+ */ -+ -+#include "bl_v7.h" -+#include "bl_defs.h" -+#include "bl_irqs.h" -+#include "bl_sdio.h" -+ -+ -+void bl_device_deinit(struct bl_plat *bl_plat) -+{ -+ -+ sdio_claim_host(bl_plat->func); -+ sdio_release_irq(bl_plat->func); -+ sdio_disable_func(bl_plat->func); -+ sdio_release_host(bl_plat->func); -+ -+ kfree(bl_plat->mp_regs); -+ kfree(bl_plat); -+} -+ -+int bl_device_init(struct sdio_func *func, struct bl_plat **bl_plat) -+{ -+ struct bl_device *device; -+ u8 sdio_ireg; -+ int ret = 0; -+ -+ *bl_plat = kzalloc(sizeof(struct bl_plat) + sizeof(struct bl_device), GFP_KERNEL); -+ if (!*bl_plat) -+ return -ENOMEM; -+ -+ device = (struct bl_device *)(*bl_plat)->priv; -+ -+ device->firmware = SD606_DEFAULT_FW_NAME; -+ device->reg = &bl_reg_sd606; -+ device->max_ports = 16; -+ device->mp_agg_pkt_limit = 8; -+ device->supports_sdio_new_mode = false; -+ device->has_control_mask = true; -+ device->supports_fw_dump = false; -+ device->mp_tx_agg_buf_size = BL_MP_AGGR_BUF_SIZE_16K; -+ device->mp_rx_agg_buf_size = BL_MP_AGGR_BUF_SIZE_16K; -+ device->auto_tdls = false; -+ -+ func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE; -+ -+ sdio_claim_host(func); -+ -+ /*1. enable func*/ -+ ret = sdio_enable_func(func); -+ -+ /* -+ * 2. Read the host_int_status_reg for ACK the first interrupt got -+ * from the bootloader. If we don't do this we get a interrupt -+ * as soon as we register the irq. -+ */ -+ sdio_readb(func, device->reg->host_int_status_reg, &ret); -+ -+ /* 3. Get SDIO ioport */ -+ (*bl_plat)->io_port = (sdio_readb(func, device->reg->io_port_0_reg, &ret) & 0xff); -+ (*bl_plat)->io_port |= ((sdio_readb(func, device->reg->io_port_1_reg, &ret) & 0xff) << 8); -+ (*bl_plat)->io_port |= ((sdio_readb(func, device->reg->io_port_2_reg, &ret) & 0xff) << 16); -+ BL_DBG("info: SDIO FUNC1 IO port: %#x\n", (*bl_plat)->io_port); -+ -+ /* Set Host interrupt reset to read to clear */ -+ sdio_ireg = sdio_readb(func, device->reg->host_int_rsr_reg, &ret); -+ if(!ret) -+ sdio_writeb(func, sdio_ireg | device->reg->sdio_int_mask, device->reg->host_int_rsr_reg, &ret); -+ -+ /* Dnld/Upld ready set to auto reset */ -+ sdio_ireg = sdio_readb(func, device->reg->card_misc_cfg_reg, &ret); -+ if(!ret) -+ sdio_writeb(func, sdio_ireg | AUTO_RE_ENABLE_INT, device->reg->card_misc_cfg_reg, &ret); -+ -+ -+ /* 4. set block size*/ -+ sdio_set_block_size(func, BL_SDIO_BLOCK_SIZE); -+ -+ /* 4.1 Download Wi-Fi firmware*/ -+ (*bl_plat)->func = func; -+ ret = bl_sdio_init(*bl_plat); -+ if (ret) { -+ printk("bl_sdio_init failed: ret=%d\n", ret); -+ sdio_release_host(func); -+ return ret; -+ } -+ -+ /* 5. request irq */ -+ ret = sdio_claim_irq(func, bl_irq_hdlr); -+ if (ret) { -+ printk("sdio_claim_irq failed: ret=%d\n", ret); -+ sdio_release_host(func); -+ return ret; -+ } -+ -+ /* Simply write the mask to the register */ -+ sdio_writeb(func, UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK, device->reg->host_int_mask_reg, &ret); -+ if (ret) { -+ printk("enable host interrupt failed\n"); -+ sdio_release_irq(func); -+ sdio_release_host(func); -+ return ret; -+ } -+ -+ sdio_ireg = sdio_readb(func, device->reg->host_int_mask_reg, &ret); -+ BL_DBG("irq_enable=0x%x\n", sdio_ireg); -+ -+ sdio_release_host(func); -+ -+ /* 6. Initialize SDIO variables in card */ -+ (*bl_plat)->mp_rd_bitmap = 0; -+ (*bl_plat)->mp_wr_bitmap = 0; -+ (*bl_plat)->curr_rd_port = device->reg->start_rd_port; -+ (*bl_plat)->curr_wr_port = device->reg->start_wr_port; -+ -+ (*bl_plat)->mp_regs = kzalloc(device->reg->max_mp_regs, GFP_KERNEL); -+ if (!(*bl_plat)->mp_regs) { -+ printk("kzalloc mp_regs failed!\n"); -+ return -ENOMEM; -+ } -+ -+ if(ret) { -+ printk("bl_device_init failed!\n"); -+ sdio_claim_host(func); -+ sdio_release_irq(func); -+ ret = sdio_disable_func(func); -+ sdio_release_host(func); -+ kfree((*bl_plat)->mp_regs); -+ kfree(*bl_plat); -+ } -+ return ret; -+} -diff -Naur /dev/null_v7.h b/drivers/net/wireless/hflps170/bl_v7.h ---- /dev/null_v7.h 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_v7.h 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,34 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file bl_v7.h -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ ****************************************************************************** -+ */ -+ -+#ifndef _BL_V7_H_ -+#define _BL_V7_H_ -+ -+#include "bl_platform.h" -+ -+struct bl_device { -+ const char *firmware; -+ const struct bl_sdio_card_reg *reg; -+ u8 *mp_regs; -+ u8 max_ports; -+ u8 mp_agg_pkt_limit; -+ bool supports_sdio_new_mode; -+ bool has_control_mask; -+ bool supports_fw_dump; -+ u16 tx_buf_size; -+ u32 mp_tx_agg_buf_size; -+ u32 mp_rx_agg_buf_size; -+ u8 auto_tdls; -+}; -+ -+int bl_device_init(struct sdio_func *func, struct bl_plat **bl_plat); -+void bl_device_deinit(struct bl_plat *bl_plat); -+ -+#endif /* _BL_V7_H_ */ -diff -Naur /dev/null_version.h b/drivers/net/wireless/hflps170/bl_version.h ---- /dev/null_version.h 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/bl_version.h 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,11 @@ -+#ifndef _BL_VERSION_H_ -+#define _BL_VERSION_H_ -+ -+#include "bl_version_gen.h" -+ -+static inline void bl_print_version(void) -+{ -+ printk(BL_VERS_BANNER"\n"); -+} -+ -+#endif /* _BL_VERSION_H_ */ -diff -Naur /dev/null/Makefile b/drivers/net/wireless/hflps170/fullmac/Makefile ---- /dev/null/Makefile 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/fullmac/Makefile 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,61 @@ -+# Enable A-MSDU support (need FW support) -+## Select this if FW is compiled with AMSDU support -+CONFIG_BL_SPLIT_TX_BUF ?= n -+## Select this TO send AMSDU -+CONFIG_BL_AMSDUS_TX ?= n -+ -+# Enable HW queue for Broadcast/Multicast traffic (need FW support) -+CONFIG_BL_BCMC ?= y -+ -+# extra DEBUG config -+CONFIG_BL_SW_PROFILING ?= n -+CONFIG_BL_DBG ?= n -+CONFIG_AUTO_DNLD ?= y -+ -+obj-m := bl_fdrv.o -+bl_fdrv-y := bl_cfgfile.o \ -+ bl_main.o \ -+ bl_mod_params.o \ -+ bl_platform.o \ -+ bl_sdio.o \ -+ bl_msg_tx.o \ -+ bl_msg_rx.o \ -+ bl_utils.o \ -+ bl_cmds.o \ -+ bl_irqs.o \ -+ ipc_host.o \ -+ bl_txq.o \ -+ bl_strs.o \ -+ bl_tx.o \ -+ bl_rx.o \ -+ bl_v7.o \ -+ bl_bootrom.o -+bl_fdrv-$(CONFIG_DEBUG_FS) += bl_debugfs.o -+ -+ccflags-y := -DCONFIG_BL_FULLMAC -+ccflags-y += -I$(src)/.. -+ccflags-$(CONFIG_BL_SPLIT_TX_BUF) += -DCONFIG_BL_SPLIT_TX_BUF -+ifeq ($(CONFIG_BL_SPLIT_TX_BUF), y) -+ccflags-$(CONFIG_BL_AMSDUS_TX) += -DCONFIG_BL_AMSDUS_TX -+endif -+ccflags-$(CONFIG_BL_DBG) += -DCONFIG_BL_DBG -+ccflags-$(CONFIG_BL_MOD_LEV_DBG) += -DCONFIG_BL_MOD_LEV_DBG -+ -+ccflags-y += -DCONFIG_USER_MAX=1 -+ -+ifeq ($(CONFIG_BL_BCMC), y) -+ccflags-y += -DNX_TXQ_CNT=5 -+else -+ccflags-y += -DNX_TXQ_CNT=4 -+endif -+ -+ -+quiet_cmd_genvers = GENVERSION $@ -+ cmd_genvers = ($(if $(KBUILD_EXTMOD),,$(srctree)/)$(src)/../mkvers.sh $@) -+ -+$(obj)/bl_main.o: $(obj)/bl_version_gen.h -+ -+$(obj)/bl_version_gen.h: FORCE -+ $(call cmd,genvers) -+ -+clean-files := bl_version_gen.h -diff -Naur /dev/null/bl_defs.h b/drivers/net/wireless/hflps170/fullmac/bl_defs.h ---- /dev/null/bl_defs.h 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/fullmac/bl_defs.h 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,464 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file bl_defs.h -+ * -+ * @brief Main driver structure declarations for fullmac driver -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ ****************************************************************************** -+ */ -+ -+#ifndef _BL_DEFS_H_ -+#define _BL_DEFS_H_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "bl_mod_params.h" -+#include "bl_debugfs.h" -+#include "bl_tx.h" -+#include "bl_rx.h" -+#include "bl_utils.h" -+#include "bl_platform.h" -+ -+#define WPI_HDR_LEN 18 -+#define WPI_PN_LEN 16 -+#define WPI_PN_OFST 2 -+#define WPI_MIC_LEN 16 -+#define WPI_KEY_LEN 32 -+#define WPI_SUBKEY_LEN 16 // WPI key is actually two 16bytes key -+ -+#define LEGACY_PS_ID 0 -+#define UAPSD_ID 1 -+#define IEEE80211_MAX_AMPDU_BUF IEEE80211_MAX_AMPDU_BUF_HT -+ -+/** -+ * struct bl_bcn - Information of the beacon in used (AP mode) -+ * -+ * @head: head portion of beacon (before TIM IE) -+ * @tail: tail portion of beacon (after TIM IE) -+ * @ies: extra IEs (not used ?) -+ * @head_len: length of head data -+ * @tail_len: length of tail data -+ * @ies_len: length of extra IEs data -+ * @tim_len: length of TIM IE -+ * @len: Total beacon len (head + tim + tail + extra) -+ * @dtim: dtim period -+ */ -+struct bl_bcn { -+ u8 *head; -+ u8 *tail; -+ u8 *ies; -+ size_t head_len; -+ size_t tail_len; -+ size_t ies_len; -+ size_t tim_len; -+ size_t len; -+ u8 dtim; -+}; -+ -+/** -+ * struct bl_key - Key information -+ * -+ * @hw_idx: Idx of the key from hardware point of view -+ */ -+struct bl_key { -+ u8 hw_idx; -+}; -+ -+/** -+ * struct bl_csa - Information for CSA (Channel Switch Announcement) -+ * -+ * @vif: Pointer to the vif doing the CSA -+ * @bcn: Beacon to use after CSA -+ * @dma: DMA descriptor to send the new beacon to the fw -+ * @chandef: defines the channel to use after the switch -+ * @count: Current csa counter -+ * @status: Status of the CSA at fw level -+ * @ch_idx: Index of the new channel context -+ * @work: work scheduled at the end of CSA -+ */ -+struct bl_csa { -+ struct bl_vif *vif; -+ struct bl_bcn bcn; -+ struct bl_dma_elem dma; -+ struct cfg80211_chan_def chandef; -+ int count; -+ int status; -+ int ch_idx; -+ struct work_struct work; -+}; -+ -+/** -+ * enum bl_ap_flags - AP flags -+ * -+ * @BL_AP_ISOLATE Isolate clients (i.e. Don't brige packets transmitted by -+ * one client for another one) -+ */ -+enum bl_ap_flags { -+ BL_AP_ISOLATE = BIT(0), -+}; -+ -+/* -+ * Structure used to save information relative to the managed interfaces. -+ * This is also linked within the bl_hw vifs list. -+ * -+ */ -+struct bl_vif { -+ struct list_head list; -+ struct bl_hw *bl_hw; -+ struct wireless_dev wdev; -+ struct net_device *ndev; -+ struct net_device_stats net_stats; -+ struct bl_key key[6]; -+ u8 drv_vif_index; /* Identifier of the VIF in driver */ -+ u8 vif_index; /* Identifier of the station in FW */ -+ u8 ch_index; /* Channel context identifier */ -+ bool up; /* Indicate if associated netdev is up -+ (i.e. Interface is created at fw level) */ -+ bool use_4addr; /* Should we use 4addresses mode */ -+ bool is_resending; /* Indicate if a frame is being resent on this interface */ -+ bool user_mpm; /* In case of Mesh Point VIF, indicate if MPM is handled by userspace */ -+ bool roc_tdls; /* Indicate if the ROC has been called by a -+ TDLS station */ -+ u8 tdls_status; /* Status of the TDLS link */ -+ union -+ { -+ struct -+ { -+ struct bl_sta *ap; /* Pointer to the peer STA entry allocated for -+ the AP */ -+ struct bl_sta *tdls_sta; /* Pointer to the TDLS station */ -+ } sta; -+ struct -+ { -+ u16 flags; /* see bl_ap_flags */ -+ struct list_head sta_list; /* List of STA connected to the AP */ -+ struct bl_bcn bcn; /* beacon */ -+ u8 bcmc_index; /* Index of the BCMC sta to use */ -+ struct bl_csa *csa; -+ -+ struct list_head mpath_list; /* List of Mesh Paths used on this interface */ -+ struct list_head proxy_list; /* List of Proxies Information used on this interface */ -+ bool create_path; /* Indicate if we are waiting for a MESH_CREATE_PATH_CFM -+ message */ -+ int generation; /* Increased each time the list of Mesh Paths is updated */ -+ } ap; -+ struct -+ { -+ struct bl_vif *master; /* pointer on master interface */ -+ struct bl_sta *sta_4a; -+ } ap_vlan; -+ }; -+}; -+ -+#define BL_VIF_TYPE(bl_vif) (bl_vif->wdev.iftype) -+ -+/** -+ * Structure used to store information relative to PS mode. -+ * -+ * @active: True when the sta is in PS mode. -+ * If false, other values should be ignored -+ * @pkt_ready: Number of packets buffered for the sta in drv's txq -+ * (1 counter for Legacy PS and 1 for U-APSD) -+ * @sp_cnt: Number of packets that remain to be pushed in the service period. -+ * 0 means that no service period is in progress -+ * (1 counter for Legacy PS and 1 for U-APSD) -+ */ -+struct bl_sta_ps { -+ bool active; -+ u16 pkt_ready[2]; -+ u16 sp_cnt[2]; -+}; -+ -+/** -+ * struct bl_rx_rate_stats - Store statistics for RX rates -+ * -+ * @table: Table indicating how many frame has been receive which each -+ * rate index. Rate index is the same as the one used by RC algo for TX -+ * @size: Size of the table array -+ * @cpt: number of frames received -+ */ -+struct bl_rx_rate_stats { -+ int *table; -+ int size; -+ int cpt; -+}; -+ -+/** -+ * struct bl_sta_stats - Structure Used to store statistics specific to a STA -+ * -+ * @last_rx: Hardware vector of the last received frame -+ * @rx_rate: Statistics of the received rates -+ */ -+struct bl_sta_stats { -+#ifdef CONFIG_BL_DEBUGFS -+ struct hw_vect last_rx; -+ struct bl_rx_rate_stats rx_rate; -+#endif -+}; -+ -+/* -+ * Structure used to save information relative to the managed stations. -+ */ -+struct bl_sta { -+ struct list_head list; -+ u16 aid; /* association ID */ -+ u8 sta_idx; /* Identifier of the station */ -+ u8 vif_idx; /* Identifier of the VIF (fw id) the station -+ belongs to */ -+ u8 vlan_idx; /* Identifier of the VLAN VIF (fw id) the station -+ belongs to (= vif_idx if no vlan in used) */ -+ enum nl80211_band band; /* Band */ -+ enum nl80211_chan_width width; /* Channel width */ -+ u16 center_freq; /* Center frequency */ -+ u32 center_freq1; /* Center frequency 1 */ -+ u32 center_freq2; /* Center frequency 2 */ -+ u8 ch_idx; /* Identifier of the channel -+ context the station belongs to */ -+ bool qos; /* Flag indicating if the station -+ supports QoS */ -+ u8 acm; /* Bitfield indicating which queues -+ have AC mandatory */ -+ u16 uapsd_tids; /* Bitfield indicating which tids are subject to -+ UAPSD */ -+ u8 mac_addr[ETH_ALEN]; /* MAC address of the station */ -+ struct bl_key key; -+ bool valid; /* Flag indicating if the entry is valid */ -+ struct bl_sta_ps ps; /* Information when STA is in PS (AP only) */ -+ bool ht; /* Flag indicating if the station -+ supports HT */ -+ bool vht; /* Flag indicating if the station -+ supports VHT */ -+ u32 ac_param[AC_MAX]; /* EDCA parameters */ -+ struct bl_sta_stats stats; -+}; -+ -+#ifdef CONFIG_BL_SPLIT_TX_BUF -+struct bl_amsdu_stats { -+ int done; -+ int failed; -+}; -+#endif -+ -+struct bl_stats { -+ int cfm_balance[NX_TXQ_CNT]; -+ unsigned long last_rx, last_tx; /* jiffies */ -+ int ampdus_tx[IEEE80211_MAX_AMPDU_BUF]; -+ int ampdus_rx[IEEE80211_MAX_AMPDU_BUF]; -+ int ampdus_rx_map[4]; -+ int ampdus_rx_miss; -+#ifdef CONFIG_BL_SPLIT_TX_BUF -+ struct bl_amsdu_stats amsdus[NX_TX_PAYLOAD_MAX]; -+#endif -+ int amsdus_rx[64]; -+}; -+ -+struct bl_sec_phy_chan { -+ u16 prim20_freq; -+ u16 center_freq1; -+ u16 center_freq2; -+ enum nl80211_band band; -+ u8 type; -+}; -+ -+/* Structure that will contains all RoC information received from cfg80211 */ -+struct bl_roc_elem { -+ struct wireless_dev *wdev; -+ struct ieee80211_channel *chan; -+ unsigned int duration; -+ /* Used to avoid call of CFG80211 callback upon expiration of RoC */ -+ bool mgmt_roc; -+ /* Indicate if we have switch on the RoC channel */ -+ bool on_chan; -+}; -+ -+/* Structure containing channel survey information received from MAC */ -+struct bl_survey_info { -+ // Filled -+ u32 filled; -+ // Amount of time in ms the radio spent on the channel -+ u32 chan_time_ms; -+ // Amount of time the primary channel was sensed busy -+ u32 chan_time_busy_ms; -+ // Noise in dbm -+ s8 noise_dbm; -+}; -+ -+struct bl_agg_reord_pkt { -+ struct list_head list; -+ struct sk_buff *skb; -+ u16 sn; -+}; -+ -+#define BL_CH_NOT_SET 0xFF -+ -+/* Structure containing channel context information */ -+struct bl_chanctx { -+ struct cfg80211_chan_def chan_def; /* channel description */ -+ u8 count; /* number of vif using this ctxt */ -+}; -+ -+struct bl_dbg_credit { -+ int sdio_port; -+ int txq_credit; -+ int hwq_credit; -+ int credit; -+ int nb_ready; -+ int txq_idx; -+}; -+ -+struct bl_dbg_time { -+ s64 sdio_tx; -+}; -+ -+/** 2K buf size */ -+#define BL_TX_DATA_BUF_SIZE_16K 16*1024 -+#define BL_RX_DATA_BUF_SIZE_16K 16*1024 -+ -+#define BL_SDIO_MP_AGGR_PKT_LIMIT_MAX 8 -+#define BL_SDIO_MPA_ADDR_BASE 0x1000 -+ -+typedef struct _sdio_mpa_tx { -+ u8 *buf; -+ u32 buf_len; -+ u32 pkt_cnt; -+ u32 ports; -+ u16 start_port; -+ u16 mp_wr_info[BL_SDIO_MP_AGGR_PKT_LIMIT_MAX]; -+}sdio_mpa_tx; -+ -+typedef struct _sdio_mpa_rx { -+ u8 *buf; -+ u32 buf_len; -+ u32 pkt_cnt; -+ u32 ports; -+ u16 start_port; -+ struct sk_buff *buf_arr[BL_SDIO_MP_AGGR_PKT_LIMIT_MAX]; -+ u32 len_arr[BL_SDIO_MP_AGGR_PKT_LIMIT_MAX]; -+ u16 mp_rd_info[BL_SDIO_MP_AGGR_PKT_LIMIT_MAX]; -+ u16 mp_rd_port[BL_SDIO_MP_AGGR_PKT_LIMIT_MAX]; -+}sdio_mpa_rx; -+ -+struct bl_hw { -+ struct bl_mod_params *mod_params; -+ void *log_buff; -+ int buf_write_size; -+ bool use_phy_bw_tweaks; -+ struct device *dev; -+ struct wiphy *wiphy; -+ struct list_head vifs; -+ struct bl_vif *vif_table[NX_VIRT_DEV_MAX + NX_REMOTE_STA_MAX]; /* indexed with fw id */ -+ struct bl_sta sta_table[NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX]; -+ struct bl_survey_info survey[SCAN_CHANNEL_MAX]; -+ struct cfg80211_scan_request *scan_request; -+ struct bl_chanctx chanctx_table[NX_CHAN_CTXT_CNT]; -+ u8 cur_chanctx; -+ -+ -+ /* RoC Management */ -+ struct bl_roc_elem *roc_elem; /* Information provided by cfg80211 in its remain on channel request */ -+ u32 roc_cookie_cnt; /* Counter used to identify RoC request sent by cfg80211 */ -+ -+ struct bl_cmd_mgr cmd_mgr; -+ -+ unsigned long drv_flags; -+ struct bl_plat *plat; -+ struct ipc_host_env_tag *ipc_env; /* store the IPC environment */ -+ -+ spinlock_t tx_lock; -+ spinlock_t main_proc_lock; -+ spinlock_t int_lock; -+ spinlock_t cmd_lock; -+ spinlock_t resend_lock; -+ spinlock_t txq_lock; -+ spinlock_t rd_int_lock; -+ struct mutex mutex; /* per-device perimeter lock */ -+ struct semaphore sem; -+ u8 bl_processing; -+ u8 more_task_flag; -+ u8 lost_int_flag; -+ -+ struct tasklet_struct task; -+ struct work_struct main_work; -+ struct workqueue_struct *workqueue; -+ struct mm_version_cfm version_cfm; /* Lower layers versions - obtained via MM_VERSION_REQ */ -+ u32 int_status; -+ u32 cmd_sent; -+ u32 resend; -+ -+ int rxbuff_idx; -+ struct sk_buff *rxbuff_table[BL_RXBUFF_MAX]; -+ struct bl_e2amsg_elem *msg_elems; /* pointer to the E2A msg useful addresses */ -+ struct bl_dbg_elem *dbg_elems; /* pointer to the Debug msg useful addresses */ -+ struct bl_e2aradar_elem *radar_elems; /* pointer to the E2A radar useful addresses */ -+ struct bl_e2arxdesc_elem *rxdesc_elems; /* pointer to the E2A RX Desc useful addresses */ -+ struct kmem_cache *sw_txhdr_cache; -+ struct kmem_cache *agg_reodr_pkt_cache; -+ sdio_mpa_tx mpa_tx_data; -+ sdio_mpa_rx mpa_rx_data; -+ -+ struct bl_dbginfo dbginfo; /* Debug information from FW */ -+ -+ struct bl_debugfs debugfs; -+ struct bl_stats stats; -+ -+ struct bl_txq txq[NX_NB_TXQ]; -+ struct bl_hwq hwq[NX_TXQ_CNT]; -+ struct bl_preq_ie_elem preq_ie; -+ struct bl_sec_phy_chan sec_phy_chan; -+ u8 phy_cnt; -+ u8 chan_ctxt_req; -+ u8 avail_idx_map; -+ u8 vif_started; -+ bool adding_sta; -+ struct phy_cfg_tag phy_config; -+ -+ /* extended capabilities supported */ -+ u8 ext_capa[8]; -+ -+ u8 dbg_dump_start; -+ u32 la_buf_idx; -+ -+ u8 recovery_flag; //temp add for fw recovery flag -+ -+ u16 msg_idx; -+ -+ struct bl_dbg_credit dbg_credit[50]; -+ int dbg_credit_idx; -+ -+ struct bl_dbg_time dbg_time[50]; -+ int dbg_time_idx; -+ -+ struct list_head reorder_list[NX_REMOTE_STA_MAX*NX_NB_TID_PER_STA]; -+}; -+ -+u8 *bl_build_bcn(struct bl_bcn *bcn, struct cfg80211_beacon_data *new); -+ -+void bl_chanctx_link(struct bl_vif *vif, u8 idx, -+ struct cfg80211_chan_def *chandef); -+void bl_chanctx_unlink(struct bl_vif *vif); -+int bl_chanctx_valid(struct bl_hw *bl_hw, u8 idx); -+ -+static inline bool is_multicast_sta(int sta_idx) -+{ -+ return (sta_idx >= NX_REMOTE_STA_MAX); -+} -+ -+static inline uint8_t master_vif_idx(struct bl_vif *vif) -+{ -+ if (unlikely(vif->wdev.iftype == NL80211_IFTYPE_AP_VLAN)) { -+ return vif->ap_vlan.master->vif_index; -+ } else { -+ return vif->vif_index; -+ } -+} -+ -+ -+#endif /* _BL_DEFS_H_ */ -diff -Naur /dev/null/bl_main.c b/drivers/net/wireless/hflps170/fullmac/bl_main.c ---- /dev/null/bl_main.c 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/fullmac/bl_main.c 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,2706 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file bl_main.c -+ * -+ * @brief Entry point of the BL driver -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ ****************************************************************************** -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "bl_compat.h" -+#include "bl_defs.h" -+#include "bl_msg_tx.h" -+#include "bl_tx.h" -+#include "hal_desc.h" -+#include "bl_debugfs.h" -+#include "bl_cfgfile.h" -+#include "bl_irqs.h" -+#include "bl_version.h" -+#include "bl_events.h" -+#include "bl_sdio.h" -+ -+#define RW_DRV_DESCRIPTION "BouffaloLab 11nac driver for Linux cfg80211" -+#define RW_DRV_COPYRIGHT "Copyright(c) 2015-2016 BouffaloLab" -+#define RW_DRV_AUTHOR "BouffaloLab S.A.S" -+ -+#define BL_PRINT_CFM_ERR(req) \ -+ printk(KERN_CRIT "%s: Status Error(%d)\n", #req, (&req##_cfm)->status) -+ -+#define BL_HT_CAPABILITIES \ -+{ \ -+ .ht_supported = true, \ -+ .cap = 0, \ -+ .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, \ -+ .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, \ -+ .mcs = { \ -+ .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, \ -+ .rx_highest = cpu_to_le16(65), \ -+ .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \ -+ }, \ -+} -+ -+#define BL_VHT_CAPABILITIES \ -+{ \ -+ .vht_supported = false, \ -+ .cap = \ -+ (7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT),\ -+ .vht_mcs = { \ -+ .rx_mcs_map = cpu_to_le16( \ -+ IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | \ -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 2 | \ -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 | \ -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 | \ -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 | \ -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 | \ -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 | \ -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 14), \ -+ .tx_mcs_map = cpu_to_le16( \ -+ IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | \ -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 2 | \ -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 | \ -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 | \ -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 | \ -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 | \ -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 | \ -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 14), \ -+ } \ -+} -+ -+#define RATE(_bitrate, _hw_rate, _flags) { \ -+ .bitrate = (_bitrate), \ -+ .flags = (_flags), \ -+ .hw_value = (_hw_rate), \ -+} -+ -+#define CHAN(_freq) { \ -+ .center_freq = (_freq), \ -+ .max_power = 30, /* FIXME */ \ -+} -+ -+void *kbuff = NULL; -+extern struct device_attribute dev_attr_filter_severity; -+extern struct device_attribute dev_attr_filter_module; -+ -+static struct ieee80211_rate bl_ratetable[] = { -+ RATE(10, 0x00, 0), -+ RATE(20, 0x01, IEEE80211_RATE_SHORT_PREAMBLE), -+ RATE(55, 0x02, IEEE80211_RATE_SHORT_PREAMBLE), -+ RATE(110, 0x03, IEEE80211_RATE_SHORT_PREAMBLE), -+ RATE(60, 0x04, 0), -+ RATE(90, 0x05, 0), -+ RATE(120, 0x06, 0), -+ RATE(180, 0x07, 0), -+ RATE(240, 0x08, 0), -+ RATE(360, 0x09, 0), -+ RATE(480, 0x0A, 0), -+ RATE(540, 0x0B, 0), -+}; -+ -+/* The channels indexes here are not used anymore */ -+static struct ieee80211_channel bl_2ghz_channels[] = { -+ CHAN(2412), -+ CHAN(2417), -+ CHAN(2422), -+ CHAN(2427), -+ CHAN(2432), -+ CHAN(2437), -+ CHAN(2442), -+ CHAN(2447), -+ CHAN(2452), -+ CHAN(2457), -+ CHAN(2462), -+ CHAN(2467), -+ CHAN(2472), -+ CHAN(2484), -+}; -+ -+static struct ieee80211_supported_band bl_band_2GHz = { -+ .channels = bl_2ghz_channels, -+ .n_channels = ARRAY_SIZE(bl_2ghz_channels), -+ .bitrates = bl_ratetable, -+ .n_bitrates = ARRAY_SIZE(bl_ratetable), -+ .ht_cap = BL_HT_CAPABILITIES, -+}; -+ -+static struct ieee80211_iface_limit bl_limits[] = { -+ { .max = NX_VIRT_DEV_MAX, .types = BIT(NL80211_IFTYPE_AP) | -+ BIT(NL80211_IFTYPE_STATION)} -+}; -+ -+static struct ieee80211_iface_limit bl_limits_dfs[] = { -+ { .max = NX_VIRT_DEV_MAX, .types = BIT(NL80211_IFTYPE_AP)} -+}; -+ -+static const struct ieee80211_iface_combination bl_combinations[] = { -+ { -+ .limits = bl_limits, -+ .n_limits = ARRAY_SIZE(bl_limits), -+ .num_different_channels = NX_CHAN_CTXT_CNT, -+ .max_interfaces = NX_VIRT_DEV_MAX, -+ }, -+ /* Keep this combination as the last one */ -+ { -+ .limits = bl_limits_dfs, -+ .n_limits = ARRAY_SIZE(bl_limits_dfs), -+ .num_different_channels = 1, -+ .max_interfaces = NX_VIRT_DEV_MAX, -+ .radar_detect_widths = (BIT(NL80211_CHAN_WIDTH_20_NOHT) | -+ BIT(NL80211_CHAN_WIDTH_20) | -+ BIT(NL80211_CHAN_WIDTH_40) | -+ BIT(NL80211_CHAN_WIDTH_80)), -+ } -+}; -+ -+/* There isn't a lot of sense in it, but you can transmit anything you like */ -+static struct ieee80211_txrx_stypes -+bl_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { -+ [NL80211_IFTYPE_STATION] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | -+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4), -+ }, -+ [NL80211_IFTYPE_AP] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | -+ BIT(IEEE80211_STYPE_DISASSOC >> 4) | -+ BIT(IEEE80211_STYPE_AUTH >> 4) | -+ BIT(IEEE80211_STYPE_DEAUTH >> 4) | -+ BIT(IEEE80211_STYPE_ACTION >> 4), -+ }, -+ [NL80211_IFTYPE_AP_VLAN] = { -+ /* copy AP */ -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | -+ BIT(IEEE80211_STYPE_DISASSOC >> 4) | -+ BIT(IEEE80211_STYPE_AUTH >> 4) | -+ BIT(IEEE80211_STYPE_DEAUTH >> 4) | -+ BIT(IEEE80211_STYPE_ACTION >> 4), -+ }, -+ [NL80211_IFTYPE_P2P_CLIENT] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | -+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4), -+ }, -+ [NL80211_IFTYPE_P2P_GO] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | -+ BIT(IEEE80211_STYPE_DISASSOC >> 4) | -+ BIT(IEEE80211_STYPE_AUTH >> 4) | -+ BIT(IEEE80211_STYPE_DEAUTH >> 4) | -+ BIT(IEEE80211_STYPE_ACTION >> 4), -+ }, -+ [NL80211_IFTYPE_P2P_DEVICE] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | -+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4), -+ }, -+}; -+ -+ -+static u32 cipher_suites[] = { -+ WLAN_CIPHER_SUITE_WEP40, -+ WLAN_CIPHER_SUITE_WEP104, -+ WLAN_CIPHER_SUITE_TKIP, -+ WLAN_CIPHER_SUITE_CCMP, -+ 0, // reserved entries to enable AES-CMAC and/or SMS4 -+ 0, -+}; -+#define NB_RESERVED_CIPHER 2; -+ -+static const int bl_ac2hwq[1][NL80211_NUM_ACS] = { -+ { -+ [NL80211_TXQ_Q_VO] = BL_HWQ_VO, -+ [NL80211_TXQ_Q_VI] = BL_HWQ_VI, -+ [NL80211_TXQ_Q_BE] = BL_HWQ_BE, -+ [NL80211_TXQ_Q_BK] = BL_HWQ_BK -+ } -+}; -+ -+const int bl_tid2hwq[IEEE80211_NUM_TIDS] = { -+ BL_HWQ_BE, -+ BL_HWQ_BK, -+ BL_HWQ_BK, -+ BL_HWQ_BE, -+ BL_HWQ_VI, -+ BL_HWQ_VI, -+ BL_HWQ_VO, -+ BL_HWQ_VO, -+ /* TID_8 is used for management frames */ -+ BL_HWQ_VO, -+ /* At the moment, all others TID are mapped to BE */ -+ BL_HWQ_BE, -+ BL_HWQ_BE, -+ BL_HWQ_BE, -+ BL_HWQ_BE, -+ BL_HWQ_BE, -+ BL_HWQ_BE, -+ BL_HWQ_BE, -+}; -+ -+static const int bl_hwq2uapsd[NL80211_NUM_ACS] = { -+ [BL_HWQ_VO] = IEEE80211_WMM_IE_STA_QOSINFO_AC_VO, -+ [BL_HWQ_VI] = IEEE80211_WMM_IE_STA_QOSINFO_AC_VI, -+ [BL_HWQ_BE] = IEEE80211_WMM_IE_STA_QOSINFO_AC_BE, -+ [BL_HWQ_BK] = IEEE80211_WMM_IE_STA_QOSINFO_AC_BK, -+}; -+ -+/********************************************************************* -+ * helper -+ *********************************************************************/ -+struct bl_sta *bl_get_sta(struct bl_hw *bl_hw, const u8 *mac_addr) -+{ -+ int i; -+ -+ for (i = 0; i < NX_REMOTE_STA_MAX; i++) { -+ struct bl_sta *sta = &bl_hw->sta_table[i]; -+ if (sta->valid && (memcmp(mac_addr, &sta->mac_addr, 6) == 0)) -+ return sta; -+ } -+ -+ return NULL; -+} -+ -+void bl_enable_wapi(struct bl_hw *bl_hw) -+{ -+ cipher_suites[bl_hw->wiphy->n_cipher_suites] = WLAN_CIPHER_SUITE_SMS4; -+ bl_hw->wiphy->n_cipher_suites ++; -+ bl_hw->wiphy->flags |= WIPHY_FLAG_CONTROL_PORT_PROTOCOL; -+} -+ -+void bl_enable_mfp(struct bl_hw *bl_hw) -+{ -+ cipher_suites[bl_hw->wiphy->n_cipher_suites] = WLAN_CIPHER_SUITE_AES_CMAC; -+ bl_hw->wiphy->n_cipher_suites ++; -+} -+ -+u8 *bl_build_bcn(struct bl_bcn *bcn, struct cfg80211_beacon_data *new) -+{ -+ u8 *buf, *pos; -+ -+ if (new->head) { -+ u8 *head = kmalloc(new->head_len, GFP_KERNEL); -+ -+ if (!head) -+ return NULL; -+ -+ if (bcn->head) -+ kfree(bcn->head); -+ -+ bcn->head = head; -+ bcn->head_len = new->head_len; -+ memcpy(bcn->head, new->head, new->head_len); -+ } -+ if (new->tail) { -+ u8 *tail = kmalloc(new->tail_len, GFP_KERNEL); -+ -+ if (!tail) -+ return NULL; -+ -+ if (bcn->tail) -+ kfree(bcn->tail); -+ -+ bcn->tail = tail; -+ bcn->tail_len = new->tail_len; -+ memcpy(bcn->tail, new->tail, new->tail_len); -+ } -+ -+ if (!bcn->head) -+ return NULL; -+ -+ bcn->tim_len = 6; -+ bcn->len = bcn->head_len + bcn->tail_len + bcn->ies_len + bcn->tim_len; -+ -+ buf = kmalloc(bcn->len, GFP_KERNEL); -+ if (!buf) -+ return NULL; -+ -+ // Build the beacon buffer -+ pos = buf; -+ memcpy(pos, bcn->head, bcn->head_len); -+ pos += bcn->head_len; -+ *pos++ = WLAN_EID_TIM; -+ *pos++ = 4; -+ *pos++ = 0; -+ *pos++ = bcn->dtim; -+ *pos++ = 0; -+ *pos++ = 0; -+ if (bcn->tail) { -+ memcpy(pos, bcn->tail, bcn->tail_len); -+ pos += bcn->tail_len; -+ } -+ if (bcn->ies) { -+ memcpy(pos, bcn->ies, bcn->ies_len); -+ } -+ -+ return buf; -+} -+ -+ -+static void bl_del_bcn(struct bl_bcn *bcn) -+{ -+ if (bcn->head) { -+ kfree(bcn->head); -+ bcn->head = NULL; -+ } -+ bcn->head_len = 0; -+ -+ if (bcn->tail) { -+ kfree(bcn->tail); -+ bcn->tail = NULL; -+ } -+ bcn->tail_len = 0; -+ -+ if (bcn->ies) { -+ kfree(bcn->ies); -+ bcn->ies = NULL; -+ } -+ bcn->ies_len = 0; -+ bcn->tim_len = 0; -+ bcn->dtim = 0; -+ bcn->len = 0; -+} -+ -+/** -+ * Link channel ctxt to a vif and thus increments count for this context. -+ */ -+void bl_chanctx_link(struct bl_vif *vif, u8 ch_idx, -+ struct cfg80211_chan_def *chandef) -+{ -+ struct bl_chanctx *ctxt; -+ -+ if (ch_idx >= NX_CHAN_CTXT_CNT) { -+ WARN(1, "Invalid channel ctxt id %d", ch_idx); -+ return; -+ } -+ -+ vif->ch_index = ch_idx; -+ ctxt = &vif->bl_hw->chanctx_table[ch_idx]; -+ ctxt->count++; -+ -+ // For now chandef is NULL for STATION interface -+ if (chandef) { -+ if (!ctxt->chan_def.chan) -+ ctxt->chan_def = *chandef; -+ else { -+ // TODO. check that chandef is the same as the one already -+ // set for this ctxt -+ } -+ } -+} -+ -+/** -+ * Unlink channel ctxt from a vif and thus decrements count for this context -+ */ -+void bl_chanctx_unlink(struct bl_vif *vif) -+{ -+ struct bl_chanctx *ctxt; -+ -+ if (vif->ch_index == BL_CH_NOT_SET) -+ return; -+ -+ ctxt = &vif->bl_hw->chanctx_table[vif->ch_index]; -+ -+ if (ctxt->count == 0) { -+ WARN(1, "Chan ctxt ref count is already 0"); -+ } else { -+ ctxt->count--; -+ } -+ -+ if (ctxt->count == 0) { -+ /* set chan to null, so that if this ctxt is relinked to a vif that -+ don't have channel information, don't use wrong information */ -+ ctxt->chan_def.chan = NULL; -+ } -+ vif->ch_index = BL_CH_NOT_SET; -+} -+ -+int bl_chanctx_valid(struct bl_hw *bl_hw, u8 ch_idx) -+{ -+ if (ch_idx >= NX_CHAN_CTXT_CNT || -+ bl_hw->chanctx_table[ch_idx].chan_def.chan == NULL) { -+ return 0; -+ } -+ -+ return 1; -+} -+ -+static void bl_del_csa(struct bl_vif *vif) -+{ -+ struct bl_csa *csa = vif->ap.csa; -+ -+ if (!csa) -+ return; -+ -+ if (csa->dma.buf) { -+ kfree(csa->dma.buf); -+ } -+ bl_del_bcn(&csa->bcn); -+ kfree(csa); -+ vif->ap.csa = NULL; -+} -+ -+static void bl_csa_finish(struct work_struct *ws) -+{ -+ struct bl_csa *csa = container_of(ws, struct bl_csa, work); -+ struct bl_vif *vif = csa->vif; -+ struct bl_hw *bl_hw = vif->bl_hw; -+ int error = csa->status; -+ -+ if (!error) -+ error = bl_send_bcn_change(bl_hw, vif->vif_index, csa->dma.buf, -+ csa->bcn.len, csa->bcn.head_len, -+ csa->bcn.tim_len, NULL); -+ -+ if (error) -+ cfg80211_stop_iface(bl_hw->wiphy, &vif->wdev, GFP_KERNEL); -+ else { -+ bl_chanctx_unlink(vif); -+ bl_chanctx_link(vif, csa->ch_idx, &csa->chandef); -+ spin_lock_bh(&bl_hw->cmd_mgr.lock); -+ if (bl_hw->cur_chanctx == csa->ch_idx) { -+ bl_txq_vif_start(vif, BL_TXQ_STOP_CHAN, bl_hw); -+ } else -+ bl_txq_vif_stop(vif, BL_TXQ_STOP_CHAN, bl_hw); -+ spin_unlock_bh(&bl_hw->cmd_mgr.lock); -+ cfg80211_ch_switch_notify(vif->ndev, &csa->chandef); -+ } -+ bl_del_csa(vif); -+} -+ -+/********************************************************************* -+ * netdev callbacks -+ ********************************************************************/ -+/** -+ * int (*ndo_open)(struct net_device *dev); -+ * This function is called when network device transistions to the up -+ * state. -+ * -+ * - Start FW if this is the first interface opened -+ * - Add interface at fw level -+ */ -+static int bl_open(struct net_device *dev) -+{ -+ struct bl_vif *bl_vif = netdev_priv(dev); -+ struct bl_hw *bl_hw = bl_vif->bl_hw; -+ struct mm_add_if_cfm add_if_cfm; -+ int error = 0; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ // Check if it is the first opened VIF -+ if (bl_hw->vif_started == 0) -+ { -+ // Start the FW -+ if ((error = bl_send_start(bl_hw))) -+ return error; -+ -+ /* Device is now started */ -+ set_bit(BL_DEV_STARTED, &bl_hw->drv_flags); -+ } -+ -+ if (BL_VIF_TYPE(bl_vif) == NL80211_IFTYPE_AP_VLAN) { -+ /* For AP_vlan use same fw and drv indexes. We ensure that this index -+ will not be used by fw for another vif by taking index >= NX_VIRT_DEV_MAX */ -+ add_if_cfm.inst_nbr = bl_vif->drv_vif_index; -+ netif_tx_stop_all_queues(dev); -+ } else { -+ /* Forward the information to the LMAC, -+ * p2p value not used in FMAC configuration, iftype is sufficient */ -+ if ((error = bl_send_add_if(bl_hw, dev->dev_addr, -+ BL_VIF_TYPE(bl_vif), false, &add_if_cfm))) -+ return error; -+ -+ if (add_if_cfm.status != 0) { -+ BL_PRINT_CFM_ERR(add_if); -+ return -EIO; -+ } -+ } -+ -+ /* Save the index retrieved from LMAC */ -+ bl_vif->vif_index = add_if_cfm.inst_nbr; -+ bl_vif->up = true; -+ bl_hw->vif_started++; -+ bl_hw->vif_table[add_if_cfm.inst_nbr] = bl_vif; -+ -+ netif_carrier_off(dev); -+ -+ return error; -+} -+ -+/** -+ * int (*ndo_stop)(struct net_device *dev); -+ * This function is called when network device transistions to the down -+ * state. -+ * -+ * - Remove interface at fw level -+ * - Reset FW if this is the last interface opened -+ */ -+static int bl_close(struct net_device *dev) -+{ -+ struct bl_vif *bl_vif = netdev_priv(dev); -+ struct bl_hw *bl_hw = bl_vif->bl_hw; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ netdev_info(dev, "CLOSE"); -+ -+ /* Abort scan request on the vif */ -+ if (bl_hw->scan_request && -+ bl_hw->scan_request->wdev == &bl_vif->wdev) { -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) -+ struct cfg80211_scan_info info = { -+ .aborted = true, -+ }; -+ -+ cfg80211_scan_done(bl_hw->scan_request, &info); -+#else -+ cfg80211_scan_done(bl_hw->scan_request, true); -+#endif -+ bl_hw->scan_request = NULL; -+ } -+ -+ bl_send_remove_if(bl_hw, bl_vif->vif_index); -+ -+ if (bl_hw->roc_elem && (bl_hw->roc_elem->wdev == &bl_vif->wdev)) { -+ /* Initialize RoC element pointer to NULL, indicate that RoC can be started */ -+ bl_hw->roc_elem = NULL; -+ } -+ -+ /* Ensure that we won't process disconnect ind */ -+ spin_lock_bh(&bl_hw->cmd_mgr.lock); -+ -+ bl_vif->up = false; -+ if (netif_carrier_ok(dev)) { -+ if (BL_VIF_TYPE(bl_vif) == NL80211_IFTYPE_STATION || -+ BL_VIF_TYPE(bl_vif) == NL80211_IFTYPE_P2P_CLIENT) { -+ cfg80211_disconnected(dev, WLAN_REASON_DEAUTH_LEAVING, -+ NULL, 0, true, GFP_ATOMIC); -+ netif_tx_stop_all_queues(dev); -+ netif_carrier_off(dev); -+ } else if (BL_VIF_TYPE(bl_vif) == NL80211_IFTYPE_AP_VLAN) { -+ netif_carrier_off(dev); -+ } else { -+ netdev_warn(dev, "AP not stopped when disabling interface"); -+ } -+ } -+ -+ spin_unlock_bh(&bl_hw->cmd_mgr.lock); -+ -+ bl_hw->vif_table[bl_vif->vif_index] = NULL; -+ bl_hw->vif_started--; -+ if (bl_hw->vif_started == 0) { -+ /* This also lets both ipc sides remain in sync before resetting */ -+ bl_ipc_tx_drain(bl_hw); -+ -+ bl_send_reset(bl_hw); -+ -+ // Set parameters to firmware -+ bl_send_me_config_req(bl_hw); -+ -+ // Set channel parameters to firmware -+ bl_send_me_chan_config_req(bl_hw); -+ -+ clear_bit(BL_DEV_STARTED, &bl_hw->drv_flags); -+ } -+ -+ return 0; -+} -+ -+/** -+ * struct net_device_stats* (*ndo_get_stats)(struct net_device *dev); -+ * Called when a user wants to get the network device usage -+ * statistics. Drivers must do one of the following: -+ * 1. Define @ndo_get_stats64 to fill in a zero-initialised -+ * rtnl_link_stats64 structure passed by the caller. -+ * 2. Define @ndo_get_stats to update a net_device_stats structure -+ * (which should normally be dev->stats) and return a pointer to -+ * it. The structure may be changed asynchronously only if each -+ * field is written atomically. -+ * 3. Update dev->stats asynchronously and atomically, and define -+ * neither operation. -+ */ -+static struct net_device_stats *bl_get_stats(struct net_device *dev) -+{ -+ struct bl_vif *vif = netdev_priv(dev); -+ -+ return &vif->net_stats; -+} -+ -+static const u16 bl_1d_to_wmm_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; -+/** -+ * u16 (*ndo_select_queue)(struct net_device *dev, struct sk_buff *skb, -+ * void *accel_priv, select_queue_fallback_t fallback); -+ * Called to decide which queue to when device supports multiple -+ * transmit queues. -+ */ -+u16 bl_select_queue(struct net_device *dev, struct sk_buff *skb, -+ struct net_device *sb_dev) -+{ -+ struct bl_vif *bl_vif = netdev_priv(dev); -+ struct bl_hw *bl_hw = bl_vif->bl_hw; -+ struct wireless_dev *wdev = &bl_vif->wdev; -+ struct bl_sta *sta = NULL; -+ struct bl_txq *txq; -+ u16 netdev_queue; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+#define PRIO_STA_NULL 0xAA -+ -+ switch (wdev->iftype) { -+ case NL80211_IFTYPE_STATION: -+ case NL80211_IFTYPE_P2P_CLIENT: -+ { -+ struct ethhdr *eth; -+ eth = (struct ethhdr *)skb->data; -+ sta = bl_vif->sta.ap; -+ break; -+ } -+ case NL80211_IFTYPE_AP_VLAN: -+ if (bl_vif->ap_vlan.sta_4a) { -+ sta = bl_vif->ap_vlan.sta_4a; -+ break; -+ } -+ -+ /* AP_VLAN interface is not used for a 4A STA, -+ fallback searching sta amongs all AP's clients */ -+ bl_vif = bl_vif->ap_vlan.master; -+ case NL80211_IFTYPE_AP: -+ case NL80211_IFTYPE_P2P_GO: -+ { -+ struct bl_sta *cur; -+ struct ethhdr *eth = (struct ethhdr *)skb->data; -+ -+ if (is_multicast_ether_addr(eth->h_dest)) { -+ sta = &bl_hw->sta_table[bl_vif->ap.bcmc_index]; -+ } else { -+ list_for_each_entry(cur, &bl_vif->ap.sta_list, list) { -+ if (!memcmp(cur->mac_addr, eth->h_dest, ETH_ALEN)) { -+ sta = cur; -+ break; -+ } -+ } -+ } -+ -+ break; -+ } -+ default: -+ break; -+ } -+ -+ if (sta && sta->qos) -+ { -+ /* use the data classifier to determine what 802.1d tag the data frame has */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) -+ skb->priority = cfg80211_classify8021d(skb, NULL) & IEEE80211_QOS_CTL_TAG1D_MASK; -+#else -+ skb->priority = cfg80211_classify8021d(skb) & IEEE80211_QOS_CTL_TAG1D_MASK; -+#endif -+ if (sta->acm) -+ bl_downgrade_ac(sta, skb); -+ -+ txq = bl_txq_sta_get(sta, skb->priority, NULL, bl_hw); -+ netdev_queue = txq->ndev_idx; -+ } -+ else if (sta) -+ { -+ skb->priority = 0xFF; -+ txq = bl_txq_sta_get(sta, 0, NULL, bl_hw); -+ netdev_queue = txq->ndev_idx; -+ } -+ else -+ { -+ /* This packet will be dropped in xmit function, still need to select -+ an active queue for xmit to be called. As it most likely to happen -+ for AP interface, select BCMC queue -+ (TODO: select another queue if BCMC queue is stopped) */ -+ skb->priority = PRIO_STA_NULL; -+ netdev_queue = NX_BCMC_TXQ_NDEV_IDX; -+ } -+ -+ if(skb->priority < 8) -+ return bl_1d_to_wmm_queue[skb->priority]; -+ else -+ return 0; -+ -+ //BUG_ON(netdev_queue >= NX_NB_NDEV_TXQ); -+ //return netdev_queue; -+} -+ -+/** -+ * int (*ndo_set_mac_address)(struct net_device *dev, void *addr); -+ * This function is called when the Media Access Control address -+ * needs to be changed. If this interface is not defined, the -+ * mac address can not be changed. -+ */ -+static int bl_set_mac_address(struct net_device *dev, void *addr) -+{ -+ struct sockaddr *sa = addr; -+ int ret; -+ -+ ret = eth_mac_addr(dev, sa); -+ -+ return ret; -+} -+ -+static const struct net_device_ops bl_netdev_ops = { -+ .ndo_open = bl_open, -+ .ndo_stop = bl_close, -+ .ndo_start_xmit = bl_start_xmit, -+ .ndo_get_stats = bl_get_stats, -+ .ndo_select_queue = bl_select_queue, -+ .ndo_set_mac_address = bl_set_mac_address -+}; -+ -+static void bl_netdev_setup(struct net_device *dev) -+{ -+ ether_setup(dev); -+ dev->priv_flags &= ~IFF_TX_SKB_SHARING; -+ dev->netdev_ops = &bl_netdev_ops; -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0) -+ dev->destructor = free_netdev; -+#else -+ dev->needs_free_netdev = true; -+#endif -+ -+ dev->watchdog_timeo = BL_TX_LIFETIME_MS; -+ -+ dev->needed_headroom = sizeof(struct bl_txhdr) + BL_SWTXHDR_ALIGN_SZ; -+#ifdef CONFIG_BL_AMSDUS_TX -+ dev->needed_headroom = max(dev->needed_headroom, -+ (unsigned short)(sizeof(struct bl_amsdu_txhdr) -+ + sizeof(struct ethhdr) + 4 -+ + sizeof(rfc1042_header) + 2)); -+#endif /* CONFIG_BL_AMSDUS_TX */ -+ dev->flags |= IFF_BROADCAST | IFF_MULTICAST; -+ -+ dev->hw_features = 0; -+} -+ -+/********************************************************************* -+ * Cfg80211 callbacks (and helper) -+ *********************************************************************/ -+static struct wireless_dev *bl_interface_add(struct bl_hw *bl_hw, -+ const char *name, -+ enum nl80211_iftype type, -+ struct vif_params *params) -+{ -+ struct net_device *ndev; -+ struct bl_vif *vif; -+ int min_idx, max_idx; -+ int vif_idx = -1; -+ int i; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ // Look for an available VIF -+ if (type == NL80211_IFTYPE_AP_VLAN) { -+ min_idx = NX_VIRT_DEV_MAX; -+ max_idx = NX_VIRT_DEV_MAX + NX_REMOTE_STA_MAX; -+ } else { -+ min_idx = 0; -+ max_idx = NX_VIRT_DEV_MAX; -+ } -+ -+ for (i = min_idx; i < max_idx; i++) { -+ if ((bl_hw->avail_idx_map) & BIT(i)) { -+ vif_idx = i; -+ break; -+ } -+ } -+ if (vif_idx < 0) -+ return NULL; -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0) -+ ndev = alloc_netdev_mqs(sizeof(*vif), name, NET_NAME_UNKNOWN, -+ bl_netdev_setup, IEEE80211_NUM_ACS, 1); -+#else -+ ndev = alloc_netdev_mqs(sizeof(*vif), name, bl_netdev_setup, -+ IEEE80211_NUM_ACS, 1); -+#endif -+ if (!ndev) -+ return NULL; -+ -+ vif = netdev_priv(ndev); -+ ndev->ieee80211_ptr = &vif->wdev; -+ vif->wdev.wiphy = bl_hw->wiphy; -+ vif->bl_hw = bl_hw; -+ vif->ndev = ndev; -+ vif->drv_vif_index = vif_idx; -+ SET_NETDEV_DEV(ndev, wiphy_dev(vif->wdev.wiphy)); -+ vif->wdev.netdev = ndev; -+ vif->wdev.iftype = type; -+ vif->up = false; -+ vif->ch_index = BL_CH_NOT_SET; -+ memset(&vif->net_stats, 0, sizeof(vif->net_stats)); -+ -+ switch (type) { -+ case NL80211_IFTYPE_STATION: -+ case NL80211_IFTYPE_P2P_CLIENT: -+ vif->sta.ap = NULL; -+ vif->sta.tdls_sta = NULL; -+ break; -+ case NL80211_IFTYPE_MESH_POINT: -+ INIT_LIST_HEAD(&vif->ap.mpath_list); -+ INIT_LIST_HEAD(&vif->ap.proxy_list); -+ vif->ap.create_path = false; -+ vif->ap.generation = 0; -+ // no break -+ case NL80211_IFTYPE_AP: -+ case NL80211_IFTYPE_P2P_GO: -+ INIT_LIST_HEAD(&vif->ap.sta_list); -+ memset(&vif->ap.bcn, 0, sizeof(vif->ap.bcn)); -+ break; -+ case NL80211_IFTYPE_AP_VLAN: -+ { -+ struct bl_vif *master_vif; -+ bool found = false; -+ list_for_each_entry(master_vif, &bl_hw->vifs, list) { -+ if ((BL_VIF_TYPE(master_vif) == NL80211_IFTYPE_AP) && -+ !(!memcmp(master_vif->ndev->dev_addr, params->macaddr, -+ ETH_ALEN))) { -+ found=true; -+ break; -+ } -+ } -+ -+ if (!found) -+ goto err; -+ -+ vif->ap_vlan.master = master_vif; -+ vif->ap_vlan.sta_4a = NULL; -+ break; -+ } -+ default: -+ break; -+ } -+ -+ if (type == NL80211_IFTYPE_AP_VLAN) -+ memcpy(ndev->dev_addr, params->macaddr, ETH_ALEN); -+ else { -+ memcpy(ndev->dev_addr, bl_hw->wiphy->perm_addr, ETH_ALEN); -+ ndev->dev_addr[5] ^= vif_idx; -+ } -+ -+ if (params) { -+ vif->use_4addr = params->use_4addr; -+ ndev->ieee80211_ptr->use_4addr = params->use_4addr; -+ } else -+ vif->use_4addr = false; -+ -+ if (register_netdevice(ndev)) -+ goto err; -+ -+ list_add_tail(&vif->list, &bl_hw->vifs); -+ bl_hw->avail_idx_map &= ~BIT(vif_idx); -+ -+ return &vif->wdev; -+ -+err: -+ free_netdev(ndev); -+ return NULL; -+} -+ -+ -+/* -+ * @brief Retrieve the bl_sta object allocated for a given MAC address -+ * and a given role. -+ */ -+static struct bl_sta *bl_retrieve_sta(struct bl_hw *bl_hw, -+ struct bl_vif *bl_vif, u8 *addr, -+ __le16 fc, bool ap) -+{ -+ if (ap) { -+ /* only deauth, disassoc and action are bufferable MMPDUs */ -+ bool bufferable = ieee80211_is_deauth(fc) || -+ ieee80211_is_disassoc(fc) || -+ ieee80211_is_action(fc); -+ -+ /* Check if the packet is bufferable or not */ -+ if (bufferable) -+ { -+ /* Check if address is a broadcast or a multicast address */ -+ if (is_broadcast_ether_addr(addr) || is_multicast_ether_addr(addr)) { -+ /* Returned STA pointer */ -+ struct bl_sta *bl_sta = &bl_hw->sta_table[bl_vif->ap.bcmc_index]; -+ -+ if (bl_sta->valid) -+ return bl_sta; -+ } else { -+ /* Returned STA pointer */ -+ struct bl_sta *bl_sta; -+ -+ /* Go through list of STAs linked with the provided VIF */ -+ list_for_each_entry(bl_sta, &bl_vif->ap.sta_list, list) { -+ if (bl_sta->valid && -+ ether_addr_equal(bl_sta->mac_addr, addr)) { -+ /* Return the found STA */ -+ return bl_sta; -+ } -+ } -+ } -+ } -+ } else { -+ return bl_vif->sta.ap; -+ } -+ -+ return NULL; -+} -+ -+/** -+ * @add_virtual_intf: create a new virtual interface with the given name, -+ * must set the struct wireless_dev's iftype. Beware: You must create -+ * the new netdev in the wiphy's network namespace! Returns the struct -+ * wireless_dev, or an ERR_PTR. For P2P device wdevs, the driver must -+ * also set the address member in the wdev. -+ */ -+static struct wireless_dev *bl_cfg80211_add_iface(struct wiphy *wiphy, -+ const char *name, -+ unsigned char name_assign_type, -+ enum nl80211_iftype type, -+ struct vif_params *params) -+{ -+ struct bl_hw *bl_hw = wiphy_priv(wiphy); -+ struct wireless_dev *wdev; -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) -+ unsigned char name_assign_type = NET_NAME_UNKNOWN; -+#endif -+ -+ wdev = bl_interface_add(bl_hw, name, type, params); -+ -+ return wdev; -+} -+ -+/** -+ * @del_virtual_intf: remove the virtual interface -+ */ -+static int bl_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev) -+{ -+ struct net_device *dev = wdev->netdev; -+ struct bl_vif *bl_vif = netdev_priv(dev); -+ struct bl_hw *bl_hw = wiphy_priv(wiphy); -+ -+ netdev_info(dev, "Remove Interface"); -+ -+ if (dev->reg_state == NETREG_REGISTERED) { -+ /* Will call bl_close if interface is UP */ -+ unregister_netdevice(dev); -+ } -+ -+ list_del(&bl_vif->list); -+ bl_hw->avail_idx_map |= BIT(bl_vif->drv_vif_index); -+ bl_vif->ndev = NULL; -+ -+ /* Clear the priv in adapter */ -+ dev->ieee80211_ptr = NULL; -+ -+ return 0; -+} -+ -+/** -+ * @change_virtual_intf: change type/configuration of virtual interface, -+ * keep the struct wireless_dev's iftype updated. -+ */ -+static int bl_cfg80211_change_iface(struct wiphy *wiphy, -+ struct net_device *dev, -+ enum nl80211_iftype type, -+ struct vif_params *params) -+{ -+ struct bl_vif *vif = netdev_priv(dev); -+ -+ if (vif->up) -+ return (-EBUSY); -+ -+ switch (type) { -+ case NL80211_IFTYPE_STATION: -+ case NL80211_IFTYPE_P2P_CLIENT: -+ vif->sta.ap = NULL; -+ vif->sta.tdls_sta = NULL; -+ break; -+ case NL80211_IFTYPE_MESH_POINT: -+ INIT_LIST_HEAD(&vif->ap.mpath_list); -+ INIT_LIST_HEAD(&vif->ap.proxy_list); -+ vif->ap.create_path = false; -+ vif->ap.generation = 0; -+ // no break -+ case NL80211_IFTYPE_AP: -+ case NL80211_IFTYPE_P2P_GO: -+ INIT_LIST_HEAD(&vif->ap.sta_list); -+ memset(&vif->ap.bcn, 0, sizeof(vif->ap.bcn)); -+ break; -+ case NL80211_IFTYPE_AP_VLAN: -+ return -EPERM; -+ default: -+ break; -+ } -+ -+ vif->wdev.iftype = type; -+ if (params->use_4addr != -1) -+ vif->use_4addr = params->use_4addr; -+ -+ return 0; -+} -+ -+/** -+ * @scan: Request to do a scan. If returning zero, the scan request is given -+ * the driver, and will be valid until passed to cfg80211_scan_done(). -+ * For scan results, call cfg80211_inform_bss(); you can call this outside -+ * the scan/scan_done bracket too. -+ */ -+static int bl_cfg80211_scan(struct wiphy *wiphy, -+ struct cfg80211_scan_request *request) -+{ -+ struct bl_hw *bl_hw = wiphy_priv(wiphy); -+ struct bl_vif *bl_vif = container_of(request->wdev, struct bl_vif, -+ wdev); -+ int error; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ if ((error = bl_send_scanu_req(bl_hw, bl_vif, request))) -+ return error; -+ -+ bl_hw->scan_request = request; -+ -+ return 0; -+} -+ -+/** -+ * @add_key: add a key with the given parameters. @mac_addr will be %NULL -+ * when adding a group key. -+ */ -+static int bl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev, -+ u8 key_index, bool pairwise, const u8 *mac_addr, -+ struct key_params *params) -+{ -+ struct bl_hw *bl_hw = wiphy_priv(wiphy); -+ struct bl_vif *vif = netdev_priv(netdev); -+ int i, error = 0; -+ struct mm_key_add_cfm key_add_cfm; -+ u8_l cipher = 0; -+ struct bl_sta *sta = NULL; -+ struct bl_key *bl_key; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ if (mac_addr) { -+ sta = bl_get_sta(bl_hw, mac_addr); -+ if (!sta) -+ return -EINVAL; -+ bl_key = &sta->key; -+ } -+ else -+ bl_key = &vif->key[key_index]; -+ -+ /* Retrieve the cipher suite selector */ -+ switch (params->cipher) { -+ case WLAN_CIPHER_SUITE_WEP40: -+ cipher = MAC_RSNIE_CIPHER_WEP40; -+ break; -+ case WLAN_CIPHER_SUITE_WEP104: -+ cipher = MAC_RSNIE_CIPHER_WEP104; -+ break; -+ case WLAN_CIPHER_SUITE_TKIP: -+ cipher = MAC_RSNIE_CIPHER_TKIP; -+ break; -+ case WLAN_CIPHER_SUITE_CCMP: -+ cipher = MAC_RSNIE_CIPHER_CCMP; -+ break; -+ case WLAN_CIPHER_SUITE_AES_CMAC: -+ cipher = MAC_RSNIE_CIPHER_AES_CMAC; -+ break; -+ case WLAN_CIPHER_SUITE_SMS4: -+ { -+ // Need to reverse key order -+ u8 tmp, *key = (u8 *)params->key; -+ cipher = MAC_RSNIE_CIPHER_SMS4; -+ for (i = 0; i < WPI_SUBKEY_LEN/2; i++) { -+ tmp = key[i]; -+ key[i] = key[WPI_SUBKEY_LEN - 1 - i]; -+ key[WPI_SUBKEY_LEN - 1 - i] = tmp; -+ } -+ for (i = 0; i < WPI_SUBKEY_LEN/2; i++) { -+ tmp = key[i + WPI_SUBKEY_LEN]; -+ key[i + WPI_SUBKEY_LEN] = key[WPI_KEY_LEN - 1 - i]; -+ key[WPI_KEY_LEN - 1 - i] = tmp; -+ } -+ break; -+ } -+ default: -+ return -EINVAL; -+ } -+ -+ if ((error = bl_send_key_add(bl_hw, vif->vif_index, -+ (sta ? sta->sta_idx : 0xFF), pairwise, -+ (u8 *)params->key, params->key_len, -+ key_index, cipher, &key_add_cfm))) -+ return error; -+ -+ if (key_add_cfm.status != 0) { -+ BL_PRINT_CFM_ERR(key_add); -+ return -EIO; -+ } -+ -+ /* Save the index retrieved from LMAC */ -+ bl_key->hw_idx = key_add_cfm.hw_key_idx; -+ -+ return 0; -+} -+ -+/** -+ * @get_key: get information about the key with the given parameters. -+ * @mac_addr will be %NULL when requesting information for a group -+ * key. All pointers given to the @callback function need not be valid -+ * after it returns. This function should return an error if it is -+ * not possible to retrieve the key, -ENOENT if it doesn't exist. -+ * -+ */ -+static int bl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *netdev, -+ u8 key_index, bool pairwise, const u8 *mac_addr, -+ void *cookie, -+ void (*callback)(void *cookie, struct key_params*)) -+{ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ return -1; -+} -+ -+ -+/** -+ * @del_key: remove a key given the @mac_addr (%NULL for a group key) -+ * and @key_index, return -ENOENT if the key doesn't exist. -+ */ -+static int bl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev, -+ u8 key_index, bool pairwise, const u8 *mac_addr) -+{ -+ struct bl_hw *bl_hw = wiphy_priv(wiphy); -+ struct bl_vif *vif = netdev_priv(netdev); -+ int error; -+ struct bl_sta *sta = NULL; -+ struct bl_key *bl_key; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ if (mac_addr) { -+ sta = bl_get_sta(bl_hw, mac_addr); -+ if (!sta) -+ return -EINVAL; -+ bl_key = &sta->key; -+ } -+ else -+ bl_key = &vif->key[key_index]; -+ -+ error = bl_send_key_del(bl_hw, bl_key->hw_idx); -+ return error; -+} -+ -+/** -+ * @set_default_key: set the default key on an interface -+ */ -+static int bl_cfg80211_set_default_key(struct wiphy *wiphy, -+ struct net_device *netdev, -+ u8 key_index, bool unicast, bool multicast) -+{ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ return 0; -+} -+ -+/** -+ * @set_default_mgmt_key: set the default management frame key on an interface -+ */ -+static int bl_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, -+ struct net_device *netdev, -+ u8 key_index) -+{ -+ return 0; -+} -+ -+/** -+ * @connect: Connect to the ESS with the specified parameters. When connected, -+ * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS. -+ * If the connection fails for some reason, call cfg80211_connect_result() -+ * with the status from the AP. -+ * (invoked with the wireless_dev mutex held) -+ */ -+static int bl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, -+ struct cfg80211_connect_params *sme) -+{ -+ struct bl_hw *bl_hw = wiphy_priv(wiphy); -+ struct bl_vif *bl_vif = netdev_priv(dev); -+ struct sm_connect_cfm sm_connect_cfm; -+ int error = 0; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* For SHARED-KEY authentication, must install key first */ -+ if (sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY && sme->key) -+ { -+ struct key_params key_params; -+ key_params.key = sme->key; -+ key_params.seq = NULL; -+ key_params.key_len = sme->key_len; -+ key_params.seq_len = 0; -+ key_params.cipher = sme->crypto.cipher_group; -+ bl_cfg80211_add_key(wiphy, dev, sme->key_idx, false, NULL, &key_params); -+ } -+ -+ /* Forward the information to the LMAC */ -+ if ((error = bl_send_sm_connect_req(bl_hw, bl_vif, sme, &sm_connect_cfm))) -+ return error; -+ -+ // Check the status -+ switch (sm_connect_cfm.status) -+ { -+ case CO_OK: -+ error = 0; -+ break; -+ case CO_BUSY: -+ error = -EINPROGRESS; -+ break; -+ case CO_OP_IN_PROGRESS: -+ error = -EALREADY; -+ break; -+ default: -+ error = -EIO; -+ break; -+ } -+ -+ return error; -+} -+ -+/** -+ * @disconnect: Disconnect from the BSS/ESS. -+ * (invoked with the wireless_dev mutex held) -+ */ -+static int bl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, -+ u16 reason_code) -+{ -+ struct bl_hw *bl_hw = wiphy_priv(wiphy); -+ struct bl_vif *bl_vif = netdev_priv(dev); -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ return(bl_send_sm_disconnect_req(bl_hw, bl_vif, reason_code)); -+} -+ -+/** -+ * @add_station: Add a new station. -+ */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) -+static int bl_cfg80211_add_station(struct wiphy *wiphy, struct net_device *dev, -+ const u8 *mac, struct station_parameters *params) -+ -+#else -+static int bl_cfg80211_add_station(struct wiphy *wiphy, struct net_device *dev, -+ u8 *mac, struct station_parameters *params) -+#endif -+{ -+ struct bl_hw *bl_hw = wiphy_priv(wiphy); -+ struct bl_vif *bl_vif = netdev_priv(dev); -+ struct me_sta_add_cfm me_sta_add_cfm; -+ int error = 0; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ WARN_ON(BL_VIF_TYPE(bl_vif) == NL80211_IFTYPE_AP_VLAN); -+ -+ /* Do not add TDLS station */ -+ if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) -+ return 0; -+ -+ /* Indicate we are in a STA addition process - This will allow handling -+ * potential PS mode change indications correctly -+ */ -+ bl_hw->adding_sta = true; -+ -+ /* Forward the information to the LMAC */ -+ if ((error = bl_send_me_sta_add(bl_hw, params, mac, bl_vif->vif_index, -+ &me_sta_add_cfm))) -+ return error; -+ -+ // Check the status -+ switch (me_sta_add_cfm.status) -+ { -+ case CO_OK: -+ { -+ struct bl_sta *sta = &bl_hw->sta_table[me_sta_add_cfm.sta_idx]; -+ int tid; -+ sta->aid = params->aid; -+ -+ sta->sta_idx = me_sta_add_cfm.sta_idx; -+ sta->ch_idx = bl_vif->ch_index; -+ sta->vif_idx = bl_vif->vif_index; -+ sta->vlan_idx = sta->vif_idx; -+ sta->qos = (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME)) != 0; -+ sta->ht = params->ht_capa ? 1 : 0; -+ sta->vht = params->vht_capa ? 1 : 0; -+ sta->acm = 0; -+ for (tid = 0; tid < NX_NB_TXQ_PER_STA; tid++) { -+ int uapsd_bit = bl_hwq2uapsd[bl_tid2hwq[tid]]; -+ if (params->uapsd_queues & uapsd_bit) -+ sta->uapsd_tids |= 1 << tid; -+ else -+ sta->uapsd_tids &= ~(1 << tid); -+ } -+ memcpy(sta->mac_addr, mac, ETH_ALEN); -+ bl_dbgfs_register_rc_stat(bl_hw, sta); -+ -+ /* Ensure that we won't process PS change or channel switch ind*/ -+ spin_lock_bh(&bl_hw->cmd_mgr.lock); -+ bl_txq_sta_init(bl_hw, sta, bl_txq_vif_get_status(bl_vif)); -+ list_add_tail(&sta->list, &bl_vif->ap.sta_list); -+ sta->valid = true; -+ bl_ps_bh_enable(bl_hw, sta, sta->ps.active || me_sta_add_cfm.pm_state); -+ spin_unlock_bh(&bl_hw->cmd_mgr.lock); -+ -+ error = 0; -+ -+#ifdef CONFIG_BL_BFMER -+ if (bl_hw->mod_params->bfmer) -+ bl_send_bfmer_enable(bl_hw, sta, params->vht_capa); -+ -+ bl_mu_group_sta_init(sta, params->vht_capa); -+#endif /* CONFIG_BL_BFMER */ -+ -+ #define PRINT_STA_FLAG(f) \ -+ (params->sta_flags_set & BIT(NL80211_STA_FLAG_##f) ? "["#f"]" : "") -+ -+ netdev_info(dev, "Add sta %d (%pM) flags=%s%s%s%s%s%s%s", -+ sta->sta_idx, mac, -+ PRINT_STA_FLAG(AUTHORIZED), -+ PRINT_STA_FLAG(SHORT_PREAMBLE), -+ PRINT_STA_FLAG(WME), -+ PRINT_STA_FLAG(MFP), -+ PRINT_STA_FLAG(AUTHENTICATED), -+ PRINT_STA_FLAG(TDLS_PEER), -+ PRINT_STA_FLAG(ASSOCIATED)); -+ #undef PRINT_STA_FLAG -+ break; -+ } -+ default: -+ error = -EBUSY; -+ break; -+ } -+ -+ bl_hw->adding_sta = false; -+ -+ return error; -+} -+ -+/** -+ * @del_station: Remove a station -+ */ -+static int bl_cfg80211_del_station_compat(struct wiphy *wiphy, struct net_device *dev, -+ struct station_del_parameters *params) -+{ -+ struct bl_hw *bl_hw = wiphy_priv(wiphy); -+ struct bl_vif *bl_vif = netdev_priv(dev); -+ struct bl_sta *cur, *tmp; -+ int error = 0, found = 0; -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) -+ const u8 *mac = NULL; -+ if(params) -+ mac = params->mac; -+#endif -+ -+ list_for_each_entry_safe(cur, tmp, &bl_vif->ap.sta_list, list) { -+ if ((!mac) || (!memcmp(cur->mac_addr, mac, ETH_ALEN))) { -+ netdev_info(dev, "Del sta %d (%pM)", cur->sta_idx, cur->mac_addr); -+ /* Ensure that we won't process PS change ind */ -+ spin_lock_bh(&bl_hw->cmd_mgr.lock); -+ cur->ps.active = false; -+ cur->valid = false; -+ spin_unlock_bh(&bl_hw->cmd_mgr.lock); -+ -+ if (cur->vif_idx != cur->vlan_idx) { -+ struct bl_vif *vlan_vif; -+ vlan_vif = bl_hw->vif_table[cur->vlan_idx]; -+ if (vlan_vif->up) { -+ if ((BL_VIF_TYPE(vlan_vif) == NL80211_IFTYPE_AP_VLAN) && -+ (vlan_vif->use_4addr)) { -+ vlan_vif->ap_vlan.sta_4a = NULL; -+ } else { -+ WARN(1, "Deleting sta belonging to VLAN other than AP_VLAN 4A"); -+ } -+ } -+ } -+ -+ bl_txq_sta_deinit(bl_hw, cur); -+ error = bl_send_me_sta_del(bl_hw, cur->sta_idx, false); -+ if ((error != 0) && (error != -EPIPE)) -+ return error; -+ -+#ifdef CONFIG_BL_BFMER -+ // Disable Beamformer if supported -+ bl_bfmer_report_del(bl_hw, cur); -+ bl_mu_group_sta_del(bl_hw, cur); -+#endif /* CONFIG_BL_BFMER */ -+ -+ list_del(&cur->list); -+ bl_dbgfs_unregister_rc_stat(bl_hw, cur); -+ found ++; -+ break; -+ } -+ } -+ -+ if (!found) -+ return -ENOENT; -+ else -+ return 0; -+} -+ -+/** -+ * @change_station: Modify a given station. Note that flags changes are not much -+ * validated in cfg80211, in particular the auth/assoc/authorized flags -+ * might come to the driver in invalid combinations -- make sure to check -+ * them, also against the existing state! Drivers must call -+ * cfg80211_check_station_change() to validate the information. -+ */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0) -+static int bl_cfg80211_change_station(struct wiphy *wiphy, struct net_device *dev, -+ const u8 *mac, struct station_parameters *params) -+#else -+static int bl_cfg80211_change_station(struct wiphy *wiphy, struct net_device *dev, -+ u8 *mac, struct station_parameters *params) -+#endif -+{ -+ struct bl_hw *bl_hw = wiphy_priv(wiphy); -+ struct bl_vif *vif = netdev_priv(dev); -+ struct bl_sta *sta; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ sta = bl_get_sta(bl_hw, mac); -+ if (!sta) -+ { -+ /* Add the TDLS station */ -+ if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) -+ { -+ struct bl_vif *bl_vif = netdev_priv(dev); -+ struct me_sta_add_cfm me_sta_add_cfm; -+ int error = 0; -+ -+ /* Indicate we are in a STA addition process - This will allow handling -+ * potential PS mode change indications correctly -+ */ -+ bl_hw->adding_sta = true; -+ -+ /* Forward the information to the LMAC */ -+ if ((error = bl_send_me_sta_add(bl_hw, params, mac, bl_vif->vif_index, -+ &me_sta_add_cfm))) -+ return error; -+ -+ // Check the status -+ switch (me_sta_add_cfm.status) -+ { -+ case CO_OK: -+ { -+ int tid; -+ sta = &bl_hw->sta_table[me_sta_add_cfm.sta_idx]; -+ sta->aid = params->aid; -+ sta->sta_idx = me_sta_add_cfm.sta_idx; -+ sta->ch_idx = bl_vif->ch_index; -+ sta->vif_idx = bl_vif->vif_index; -+ sta->vlan_idx = sta->vif_idx; -+ sta->qos = (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME)) != 0; -+ sta->ht = params->ht_capa ? 1 : 0; -+ sta->vht = params->vht_capa ? 1 : 0; -+ sta->acm = 0; -+ for (tid = 0; tid < NX_NB_TXQ_PER_STA; tid++) { -+ int uapsd_bit = bl_hwq2uapsd[bl_tid2hwq[tid]]; -+ if (params->uapsd_queues & uapsd_bit) -+ sta->uapsd_tids |= 1 << tid; -+ else -+ sta->uapsd_tids &= ~(1 << tid); -+ } -+ memcpy(sta->mac_addr, mac, ETH_ALEN); -+ bl_dbgfs_register_rc_stat(bl_hw, sta); -+ -+ /* Ensure that we won't process PS change or channel switch ind*/ -+ spin_lock_bh(&bl_hw->cmd_mgr.lock); -+ bl_txq_sta_init(bl_hw, sta, bl_txq_vif_get_status(bl_vif)); -+ sta->valid = true; -+ spin_unlock_bh(&bl_hw->cmd_mgr.lock); -+ -+ #define PRINT_STA_FLAG(f) \ -+ (params->sta_flags_set & BIT(NL80211_STA_FLAG_##f) ? "["#f"]" : "") -+ -+ netdev_info(dev, "Add TDLS sta %d (%pM) flags=%s%s%s%s%s%s%s", -+ sta->sta_idx, mac, -+ PRINT_STA_FLAG(AUTHORIZED), -+ PRINT_STA_FLAG(SHORT_PREAMBLE), -+ PRINT_STA_FLAG(WME), -+ PRINT_STA_FLAG(MFP), -+ PRINT_STA_FLAG(AUTHENTICATED), -+ PRINT_STA_FLAG(TDLS_PEER), -+ PRINT_STA_FLAG(ASSOCIATED)); -+ #undef PRINT_STA_FLAG -+ -+ break; -+ } -+ default: -+ error = -EBUSY; -+ break; -+ } -+ -+ bl_hw->adding_sta = false; -+ } else { -+ return -EINVAL; -+ } -+ } -+ -+ if (params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) -+ bl_send_me_set_control_port_req(bl_hw, -+ (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED)) != 0, -+ sta->sta_idx); -+ -+ if (params->vlan) { -+ uint8_t vlan_idx; -+ -+ vif = netdev_priv(params->vlan); -+ vlan_idx = vif->vif_index; -+ -+ if (sta->vlan_idx != vlan_idx) { -+ struct bl_vif *old_vif; -+ old_vif = bl_hw->vif_table[sta->vlan_idx]; -+ bl_txq_sta_switch_vif(sta, old_vif, vif); -+ sta->vlan_idx = vlan_idx; -+ -+ if ((BL_VIF_TYPE(vif) == NL80211_IFTYPE_AP_VLAN) && -+ (vif->use_4addr)) { -+ WARN((vif->ap_vlan.sta_4a), -+ "4A AP_VLAN interface with more than one sta"); -+ vif->ap_vlan.sta_4a = sta; -+ } -+ -+ if ((BL_VIF_TYPE(old_vif) == NL80211_IFTYPE_AP_VLAN) && -+ (old_vif->use_4addr)) { -+ old_vif->ap_vlan.sta_4a = NULL; -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+/** -+ * @start_ap: Start acting in AP mode defined by the parameters. -+ */ -+static int bl_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *dev, -+ struct cfg80211_ap_settings *settings) -+{ -+ struct bl_hw *bl_hw = wiphy_priv(wiphy); -+ struct bl_vif *bl_vif = netdev_priv(dev); -+ struct apm_start_cfm apm_start_cfm; -+ struct bl_dma_elem elem; -+ struct bl_sta *sta; -+ int error = 0; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* Forward the information to the LMAC */ -+ if ((error = bl_send_apm_start_req(bl_hw, bl_vif, settings, &apm_start_cfm, &elem))) { -+ return error; -+ } -+ -+ // Check the status -+ switch (apm_start_cfm.status) -+ { -+ case CO_OK: -+ { -+ u8 txq_status = 0; -+ bl_vif->ap.bcmc_index = apm_start_cfm.bcmc_idx; -+ bl_vif->ap.flags = 0; -+ sta = &bl_hw->sta_table[apm_start_cfm.bcmc_idx]; -+ sta->valid = true; -+ sta->aid = 0; -+ sta->sta_idx = apm_start_cfm.bcmc_idx; -+ sta->ch_idx = apm_start_cfm.ch_idx; -+ sta->vif_idx = bl_vif->vif_index; -+ sta->qos = false; -+ sta->acm = 0; -+ sta->ps.active = false; -+ spin_lock_bh(&bl_hw->cmd_mgr.lock); -+ bl_chanctx_link(bl_vif, apm_start_cfm.ch_idx, -+ &settings->chandef); -+ if (bl_hw->cur_chanctx != apm_start_cfm.ch_idx) { -+ txq_status = BL_TXQ_STOP_CHAN; -+ } -+ bl_txq_vif_init(bl_hw, bl_vif, txq_status); -+ spin_unlock_bh(&bl_hw->cmd_mgr.lock); -+ -+ netif_tx_start_all_queues(dev); -+ netif_carrier_on(dev); -+ error = 0; -+ break; -+ } -+ case CO_BUSY: -+ error = -EINPROGRESS; -+ break; -+ case CO_OP_IN_PROGRESS: -+ error = -EALREADY; -+ break; -+ default: -+ error = -EIO; -+ break; -+ } -+ -+ if (error) { -+ netdev_info(dev, "Failed to start AP (%d)", error); -+ } else { -+ netdev_info(dev, "AP started: ch=%d, bcmc_idx=%d", -+ bl_vif->ch_index, bl_vif->ap.bcmc_index); -+ } -+ -+ // Free the buffer used to build the beacon -+ kfree(elem.buf); -+ -+ return error; -+} -+ -+ -+/** -+ * @change_beacon: Change the beacon parameters for an access point mode -+ * interface. This should reject the call when AP mode wasn't started. -+ */ -+static int bl_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *dev, -+ struct cfg80211_beacon_data *info) -+{ -+ struct bl_hw *bl_hw = wiphy_priv(wiphy); -+ struct bl_vif *vif = netdev_priv(dev); -+ struct bl_bcn *bcn = &vif->ap.bcn; -+ struct bl_dma_elem elem; -+ u8 *buf; -+ int error = 0; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ // Build the beacon -+ buf = bl_build_bcn(bcn, info); -+ if (!buf) -+ return -ENOMEM; -+ -+ // Fill in the DMA structure -+ elem.buf = buf; -+ elem.len = bcn->len; -+ -+ // Forward the information to the LMAC -+ error = bl_send_bcn_change(bl_hw, vif->vif_index, elem.buf, -+ bcn->len, bcn->head_len, bcn->tim_len, NULL); -+ -+ kfree(elem.buf); -+ -+ return error; -+} -+ -+/** -+ * * @stop_ap: Stop being an AP, including stopping beaconing. -+ */ -+static int bl_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) -+{ -+ struct bl_hw *bl_hw = wiphy_priv(wiphy); -+ struct bl_vif *bl_vif = netdev_priv(dev); -+ struct bl_sta *sta; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) -+ struct station_del_parameters params; -+ params.mac = NULL; -+#endif -+ -+ bl_send_apm_stop_req(bl_hw, bl_vif); -+ bl_chanctx_unlink(bl_vif); -+ -+ /* delete any remaining STA*/ -+ while (!list_empty(&bl_vif->ap.sta_list)) { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) -+ bl_cfg80211_del_station(wiphy, dev, ¶ms); -+#else -+ bl_cfg80211_del_station(wiphy, dev, NULL); -+#endif -+ } -+ -+ /* delete BC/MC STA */ -+ sta = &bl_hw->sta_table[bl_vif->ap.bcmc_index]; -+ bl_txq_vif_deinit(bl_hw, bl_vif); -+ bl_del_bcn(&bl_vif->ap.bcn); -+ bl_del_csa(bl_vif); -+ -+ netif_tx_stop_all_queues(dev); -+ netif_carrier_off(dev); -+ -+ netdev_info(dev, "AP Stopped"); -+ -+ return 0; -+} -+ -+/** -+ * @set_monitor_channel: Set the monitor mode channel for the device. If other -+ * interfaces are active this callback should reject the configuration. -+ * If no interfaces are active or the device is down, the channel should -+ * be stored for when a monitor interface becomes active. -+ */ -+static int bl_cfg80211_set_monitor_channel(struct wiphy *wiphy, -+ struct cfg80211_chan_def *chandef) -+{ -+ return 0; -+} -+ -+/** -+ * @probe_client: probe an associated client, must return a cookie that it -+ * later passes to cfg80211_probe_status(). -+ */ -+int bl_cfg80211_probe_client(struct wiphy *wiphy, struct net_device *dev, -+ const u8 *peer, u64 *cookie) -+{ -+ return 0; -+} -+ -+/** -+ * @mgmt_frame_register: Notify driver that a management frame type was -+ * registered. Note that this callback may not sleep, and cannot run -+ * concurrently with itself. -+ */ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)) -+ -+void bl_cfg80211_update_mgmt_frame_registrations(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ struct mgmt_frame_regs *upd) -+{ -+} -+ -+#else -+ -+void bl_cfg80211_mgmt_frame_register(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ u16 frame_type, bool reg) -+{ -+} -+ -+#endif -+ -+ -+/** -+ * @set_wiphy_params: Notify that wiphy parameters have changed; -+ * @changed bitfield (see &enum wiphy_params_flags) describes which values -+ * have changed. The actual parameter values are available in -+ * struct wiphy. If returning an error, no value should be changed. -+ */ -+static int bl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) -+{ -+ return 0; -+} -+ -+ -+/** -+ * @set_tx_power: set the transmit power according to the parameters, -+ * the power passed is in mBm, to get dBm use MBM_TO_DBM(). The -+ * wdev may be %NULL if power was set for the wiphy, and will -+ * always be %NULL unless the driver supports per-vif TX power -+ * (as advertised by the nl80211 feature flag.) -+ */ -+static int bl_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, -+ enum nl80211_tx_power_setting type, int mbm) -+{ -+ struct bl_hw *bl_hw = wiphy_priv(wiphy); -+ struct bl_vif *vif; -+ s8 pwr; -+ int res = 0; -+ -+ if (type == NL80211_TX_POWER_AUTOMATIC) { -+ pwr = 0x7f; -+ } else { -+ pwr = MBM_TO_DBM(mbm); -+ } -+ -+ if (wdev) { -+ vif = container_of(wdev, struct bl_vif, wdev); -+ res = bl_send_set_power(bl_hw, vif->vif_index, pwr, NULL); -+ } else { -+ list_for_each_entry(vif, &bl_hw->vifs, list) { -+ res = bl_send_set_power(bl_hw, vif->vif_index, pwr, NULL); -+ if (res) -+ break; -+ } -+ } -+ -+ return res; -+} -+ -+static int bl_cfg80211_set_txq_params(struct wiphy *wiphy, struct net_device *dev, -+ struct ieee80211_txq_params *params) -+{ -+ struct bl_hw *bl_hw = wiphy_priv(wiphy); -+ struct bl_vif *bl_vif = netdev_priv(dev); -+ u8 hw_queue, aifs, cwmin, cwmax; -+ u32 param; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ hw_queue = bl_ac2hwq[0][params->ac]; -+ -+ aifs = params->aifs; -+ cwmin = fls(params->cwmin); -+ cwmax = fls(params->cwmax); -+ -+ /* Store queue information in general structure */ -+ param = (u32) (aifs << 0); -+ param |= (u32) (cwmin << 4); -+ param |= (u32) (cwmax << 8); -+ param |= (u32) (params->txop) << 12; -+ -+ /* Send the MM_SET_EDCA_REQ message to the FW */ -+ return bl_send_set_edca(bl_hw, hw_queue, param, false, bl_vif->vif_index); -+} -+ -+ -+/** -+ * @remain_on_channel: Request the driver to remain awake on the specified -+ * channel for the specified duration to complete an off-channel -+ * operation (e.g., public action frame exchange). When the driver is -+ * ready on the requested channel, it must indicate this with an event -+ * notification by calling cfg80211_ready_on_channel(). -+ */ -+static int -+bl_cfg80211_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, -+ struct ieee80211_channel *chan, -+ unsigned int duration, u64 *cookie) -+{ -+ struct bl_hw *bl_hw = wiphy_priv(wiphy); -+ struct bl_vif *bl_vif = netdev_priv(wdev->netdev); -+ struct bl_roc_elem *roc_elem; -+ int error; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* For debug purpose (use ftrace kernel option) */ -+ trace_roc(bl_vif->vif_index, chan->center_freq, duration); -+ -+ /* Check that no other RoC procedure has been launched */ -+ if (bl_hw->roc_elem) { -+ return -EBUSY; -+ } -+ -+ /* Allocate a temporary RoC element */ -+ roc_elem = kmalloc(sizeof(struct bl_roc_elem), GFP_KERNEL); -+ -+ /* Verify that element has well been allocated */ -+ if (!roc_elem) { -+ return -ENOMEM; -+ } -+ -+ /* Initialize the RoC information element */ -+ roc_elem->wdev = wdev; -+ roc_elem->chan = chan; -+ roc_elem->duration = duration; -+ roc_elem->mgmt_roc = false; -+ roc_elem->on_chan = false; -+ -+ /* Forward the information to the FMAC */ -+ error = bl_send_roc(bl_hw, bl_vif, chan, duration); -+ -+ /* If no error, keep all the information for handling of end of procedure */ -+ if (error == 0) { -+ bl_hw->roc_elem = roc_elem; -+ -+ /* Set the cookie value */ -+ *cookie = (u64)(bl_hw->roc_cookie_cnt); -+ -+ /* Initialize the OFFCHAN TX queue to allow off-channel transmissions */ -+ bl_txq_offchan_init(bl_vif); -+ } else { -+ /* Free the allocated element */ -+ kfree(roc_elem); -+ } -+ -+ return error; -+} -+ -+/** -+ * @cancel_remain_on_channel: Cancel an on-going remain-on-channel operation. -+ * This allows the operation to be terminated prior to timeout based on -+ * the duration value. -+ */ -+static int bl_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ u64 cookie) -+{ -+ struct bl_hw *bl_hw = wiphy_priv(wiphy); -+ struct bl_vif *bl_vif = netdev_priv(wdev->netdev); -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* For debug purpose (use ftrace kernel option) */ -+ trace_cancel_roc(bl_vif->vif_index); -+ -+ /* Check if a RoC procedure is pending */ -+ if (!bl_hw->roc_elem) { -+ return 0; -+ } -+ -+ /* Forward the information to the FMAC */ -+ return bl_send_cancel_roc(bl_hw); -+} -+ -+/** -+ * @dump_survey: get site survey information. -+ */ -+static int bl_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *netdev, -+ int idx, struct survey_info *info) -+{ -+ struct bl_hw *bl_hw = wiphy_priv(wiphy); -+ struct ieee80211_supported_band *sband; -+ struct bl_survey_info *bl_survey; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ if (idx >= ARRAY_SIZE(bl_hw->survey)) -+ return -ENOENT; -+ -+ bl_survey = &bl_hw->survey[idx]; -+ -+ // Check if provided index matches with a supported 2.4GHz channel -+ sband = wiphy->bands[NL80211_BAND_2GHZ]; -+ if (sband && idx >= sband->n_channels) { -+ idx -= sband->n_channels; -+ sband = NULL; -+ return -ENOENT; -+ } -+ -+ // Fill the survey -+ info->channel = &sband->channels[idx]; -+ info->filled = bl_survey->filled; -+ -+ if (bl_survey->filled != 0) { -+ info->time = (u64)bl_survey->chan_time_ms; -+ info->time_busy = (u64)bl_survey->chan_time_busy_ms; -+ info->noise = bl_survey->noise_dbm; -+ -+ // Set the survey report as not used -+ bl_survey->filled = 0; -+ } -+ -+ return 0; -+} -+ -+/** -+ * @get_channel: Get the current operating channel for the virtual interface. -+ * For monitor interfaces, it should return %NULL unless there's a single -+ * current monitoring channel. -+ */ -+static int bl_cfg80211_get_channel(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ struct cfg80211_chan_def *chandef) { -+ -+ struct bl_hw *bl_hw = wiphy_priv(wiphy); -+ struct bl_vif *bl_vif = container_of(wdev, struct bl_vif, wdev); -+ struct bl_chanctx *ctxt; -+ -+ if (!bl_vif->up || -+ !bl_chanctx_valid(bl_hw, bl_vif->ch_index)) { -+ return -ENODATA; -+ } -+ -+ ctxt = &bl_hw->chanctx_table[bl_vif->ch_index]; -+ *chandef = ctxt->chan_def; -+ -+ return 0; -+} -+ -+/** -+ * @mgmt_tx: Transmit a management frame. -+ */ -+static int bl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, -+ struct cfg80211_mgmt_tx_params *params, -+ u64 *cookie) -+{ -+ struct bl_hw *bl_hw = wiphy_priv(wiphy); -+ struct bl_vif *bl_vif = netdev_priv(wdev->netdev); -+ struct bl_sta *bl_sta; -+ struct ieee80211_mgmt *mgmt = (void *)params->buf; -+ int error = 0; -+ bool ap = false; -+ bool offchan = false; -+ -+ do -+ { -+ /* Check if provided VIF is an AP or a STA one */ -+ switch (BL_VIF_TYPE(bl_vif)) { -+ case NL80211_IFTYPE_AP_VLAN: -+ bl_vif = bl_vif->ap_vlan.master; -+ case NL80211_IFTYPE_AP: -+ case NL80211_IFTYPE_P2P_GO: -+ case NL80211_IFTYPE_MESH_POINT: -+ ap = true; -+ break; -+ case NL80211_IFTYPE_STATION: -+ case NL80211_IFTYPE_P2P_CLIENT: -+ default: -+ break; -+ } -+ -+ /* Get STA on which management frame has to be sent */ -+ bl_sta = bl_retrieve_sta(bl_hw, bl_vif, mgmt->da, -+ mgmt->frame_control, ap); -+ -+ /* For debug purpose (use ftrace kernel option) */ -+ trace_mgmt_tx((params->chan) ? params->chan->center_freq : 0, -+ bl_vif->vif_index, -+ (bl_sta) ? bl_sta->sta_idx : 0xFF, -+ mgmt); -+ -+ /* If AP, STA have to exist */ -+ if (!bl_sta) { -+ if (!ap) { -+ /* ROC is needed, check that channel parameters have been provided */ -+ if (!params->chan) { -+ error = -EINVAL; -+ break; -+ } -+ -+ /* Check that a RoC is already pending */ -+ if (bl_hw->roc_elem) { -+ /* Get VIF used for current ROC */ -+ struct bl_vif *bl_roc_vif = netdev_priv(bl_hw->roc_elem->wdev->netdev); -+ -+ /* Check if RoC channel is the same than the required one */ -+ if ((bl_hw->roc_elem->chan->center_freq != params->chan->center_freq) -+ || (bl_vif->vif_index != bl_roc_vif->vif_index)) { -+ error = -EINVAL; -+ break; -+ } -+ } else { -+ u64 cookie; -+ -+ /* Start a ROC procedure for 30ms */ -+ error = bl_cfg80211_remain_on_channel(wiphy, wdev, params->chan, -+ 30, &cookie); -+ -+ if (error) { -+ break; -+ } -+ -+ /* -+ * Need to keep in mind that RoC has been launched internally in order to -+ * avoid to call the cfg80211 callback once expired -+ */ -+ bl_hw->roc_elem->mgmt_roc = true; -+ } -+ -+ offchan = true; -+ } -+ } -+ -+ /* Push the management frame on the TX path */ -+ error = bl_start_mgmt_xmit(bl_vif, bl_sta, params, offchan, cookie); -+ } while (0); -+ -+ return error; -+} -+ -+/** -+ * @update_ft_ies: Provide updated Fast BSS Transition information to the -+ * driver. If the SME is in the driver/firmware, this information can be -+ * used in building Authentication and Reassociation Request frames. -+ */ -+static -+int bl_cfg80211_update_ft_ies(struct wiphy *wiphy, -+ struct net_device *dev, -+ struct cfg80211_update_ft_ies_params *ftie) -+{ -+ return 0; -+} -+ -+/** -+ * @set_cqm_rssi_config: Configure connection quality monitor RSSI threshold. -+ */ -+static -+int bl_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy, -+ struct net_device *dev, -+ int32_t rssi_thold, uint32_t rssi_hyst) -+{ -+ struct bl_hw *bl_hw = wiphy_priv(wiphy); -+ struct bl_vif *bl_vif = netdev_priv(dev); -+ -+ return bl_send_cfg_rssi_req(bl_hw, bl_vif->vif_index, rssi_thold, rssi_hyst); -+} -+ -+/** -+ * -+ * @channel_switch: initiate channel-switch procedure (with CSA). Driver is -+ * responsible for veryfing if the switch is possible. Since this is -+ * inherently tricky driver may decide to disconnect an interface later -+ * with cfg80211_stop_iface(). This doesn't mean driver can accept -+ * everything. It should do it's best to verify requests and reject them -+ * as soon as possible. -+ */ -+int bl_cfg80211_channel_switch(struct wiphy *wiphy, -+ struct net_device *dev, -+ struct cfg80211_csa_settings *params) -+{ -+ struct bl_hw *bl_hw = wiphy_priv(wiphy); -+ struct bl_vif *vif = netdev_priv(dev); -+ struct bl_dma_elem elem; -+ struct bl_bcn *bcn, *bcn_after; -+ struct bl_csa *csa; -+ u16 csa_oft[BCN_MAX_CSA_CPT]; -+ u8 *buf; -+ int i, error = 0; -+ -+ -+ if (vif->ap.csa) -+ return -EBUSY; -+ -+ if (params->n_counter_offsets_beacon > BCN_MAX_CSA_CPT) -+ return -EINVAL; -+ -+ /* Build the new beacon with CSA IE */ -+ bcn = &vif->ap.bcn; -+ buf = bl_build_bcn(bcn, ¶ms->beacon_csa); -+ if (!buf) -+ return -ENOMEM; -+ -+ memset(csa_oft, 0, sizeof(csa_oft)); -+ for (i = 0; i < params->n_counter_offsets_beacon; i++) -+ { -+ csa_oft[i] = params->counter_offsets_beacon[i] + bcn->head_len + -+ bcn->tim_len; -+ } -+ -+ /* If count is set to 0 (i.e anytime after this beacon) force it to 2 */ -+ if (params->count == 0) { -+ params->count = 2; -+ for (i = 0; i < params->n_counter_offsets_beacon; i++) -+ { -+ buf[csa_oft[i]] = 2; -+ } -+ } -+ -+ elem.buf = buf; -+ elem.len = bcn->len; -+ -+ /* Build the beacon to use after CSA. It will only be sent to fw once -+ CSA is over. */ -+ csa = kzalloc(sizeof(struct bl_csa), GFP_KERNEL); -+ if (!csa) { -+ error = -ENOMEM; -+ goto end; -+ } -+ -+ -+ bcn_after = &csa->bcn; -+ buf = bl_build_bcn(bcn_after, ¶ms->beacon_after); -+ if (!buf) { -+ error = -ENOMEM; -+ bl_del_csa(vif); -+ goto end; -+ } -+ -+ vif->ap.csa = csa; -+ csa->vif = vif; -+ csa->chandef = params->chandef; -+ csa->dma.buf = buf; -+ csa->dma.len = bcn_after->len; -+ -+ /* Send new Beacon. FW will extract channel and count from the beacon */ -+ error = bl_send_bcn_change(bl_hw, vif->vif_index, elem.buf, -+ bcn->len, bcn->head_len, bcn->tim_len, csa_oft); -+ -+ if (error) { -+ bl_del_csa(vif); -+ goto end; -+ } else { -+ INIT_WORK(&csa->work, bl_csa_finish); -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)) -+ cfg80211_ch_switch_started_notify(dev, &csa->chandef, params->count, false); -+#else -+ cfg80211_ch_switch_started_notify(dev, &csa->chandef, params->count); -+#endif -+ } -+ -+ end: -+ kfree(elem.buf); -+ -+ return error; -+} -+ -+/** -+ * @change_bss: Modify parameters for a given BSS (mainly for AP mode). -+ */ -+int bl_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *dev, -+ struct bss_parameters *params) -+{ -+ struct bl_vif *bl_vif = netdev_priv(dev); -+ int res = -EOPNOTSUPP; -+ -+ if (((BL_VIF_TYPE(bl_vif) == NL80211_IFTYPE_AP) || -+ (BL_VIF_TYPE(bl_vif) == NL80211_IFTYPE_P2P_GO)) && -+ (params->ap_isolate > -1)) { -+ -+ if (params->ap_isolate) -+ bl_vif->ap.flags |= BL_AP_ISOLATE; -+ else -+ bl_vif->ap.flags &= ~BL_AP_ISOLATE; -+ -+ res = 0; -+ } -+ -+ return res; -+} -+ -+static struct cfg80211_ops bl_cfg80211_ops = { -+ .add_virtual_intf = bl_cfg80211_add_iface, -+ .del_virtual_intf = bl_cfg80211_del_iface, -+ .change_virtual_intf = bl_cfg80211_change_iface, -+ .scan = bl_cfg80211_scan, -+ .connect = bl_cfg80211_connect, -+ .disconnect = bl_cfg80211_disconnect, -+ .add_key = bl_cfg80211_add_key, -+ .get_key = bl_cfg80211_get_key, -+ .del_key = bl_cfg80211_del_key, -+ .set_default_key = bl_cfg80211_set_default_key, -+ .set_default_mgmt_key = bl_cfg80211_set_default_mgmt_key, -+ .add_station = bl_cfg80211_add_station, -+ .del_station = bl_cfg80211_del_station, -+ .change_station = bl_cfg80211_change_station, -+ .mgmt_tx = bl_cfg80211_mgmt_tx, -+ .start_ap = bl_cfg80211_start_ap, -+ .change_beacon = bl_cfg80211_change_beacon, -+ .stop_ap = bl_cfg80211_stop_ap, -+ .set_monitor_channel = bl_cfg80211_set_monitor_channel, -+ .probe_client = bl_cfg80211_probe_client, -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)) -+// .update_mgmt_frame_registrations = cfg80211_rtw_update_mgmt_frame_registrations, -+ .update_mgmt_frame_registrations = bl_cfg80211_update_mgmt_frame_registrations, -+#else -+// .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register, -+ .mgmt_frame_register = bl_cfg80211_mgmt_frame_register, -+#endif -+ .set_wiphy_params = bl_cfg80211_set_wiphy_params, -+ .set_txq_params = bl_cfg80211_set_txq_params, -+ .set_tx_power = bl_cfg80211_set_tx_power, -+ .remain_on_channel = bl_cfg80211_remain_on_channel, -+ .cancel_remain_on_channel = bl_cfg80211_cancel_remain_on_channel, -+ .dump_survey = bl_cfg80211_dump_survey, -+ .get_channel = bl_cfg80211_get_channel, -+ .update_ft_ies = bl_cfg80211_update_ft_ies, -+ .set_cqm_rssi_config = bl_cfg80211_set_cqm_rssi_config, -+ .channel_switch = bl_cfg80211_channel_switch, -+ .change_bss = bl_cfg80211_change_bss, -+}; -+ -+ -+/********************************************************************* -+ * Init/Exit functions -+ *********************************************************************/ -+static void bl_wdev_unregister(struct bl_hw *bl_hw) -+{ -+ struct bl_vif *bl_vif, *tmp; -+ -+ rtnl_lock(); -+ list_for_each_entry_safe(bl_vif, tmp, &bl_hw->vifs, list) { -+ bl_cfg80211_del_iface(bl_hw->wiphy, &bl_vif->wdev); -+ } -+ rtnl_unlock(); -+} -+ -+static void bl_set_vers(struct bl_hw *bl_hw) -+{ -+ u32 vers = bl_hw->version_cfm.version_lmac; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ snprintf(bl_hw->wiphy->fw_version, -+ sizeof(bl_hw->wiphy->fw_version), "%d.%d.%d.%d", -+ (vers & (0xff << 24)) >> 24, (vers & (0xff << 16)) >> 16, -+ (vers & (0xff << 8)) >> 8, (vers & (0xff << 0)) >> 0); -+} -+ -+static void bl_reg_notifier(struct wiphy *wiphy, -+ struct regulatory_request *request) -+{ -+ struct bl_hw *bl_hw = wiphy_priv(wiphy); -+ -+ // For now trust all initiator -+ bl_send_me_chan_config_req(bl_hw); -+} -+ -+static int remap_pfn_open(struct inode *inode, struct file *file) -+{ -+ struct mm_struct *mm = current->mm; -+ -+ printk("client: %s (%d)\n", current->comm, current->pid); -+ printk("code section: [0x%lx 0x%lx]\n", mm->start_code, mm->end_code); -+ printk("data section: [0x%lx 0x%lx]\n", mm->start_data, mm->end_data); -+ printk("brk section: s: 0x%lx, c: 0x%lx\n", mm->start_brk, mm->brk); -+ printk("mmap section: s: 0x%lx\n", mm->mmap_base); -+ printk("stack section: s: 0x%lx\n", mm->start_stack); -+ printk("arg section: [0x%lx 0x%lx]\n", mm->arg_start, mm->arg_end); -+ printk("env section: [0x%lx 0x%lx]\n", mm->env_start, mm->env_end); -+ -+ return 0; -+} -+ -+static int remap_pfn_mmap(struct file *file, struct vm_area_struct *vma) -+{ -+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; -+ unsigned long pfn_start = (virt_to_phys(kbuff) >> PAGE_SHIFT) + vma->vm_pgoff; -+ unsigned long virt_start = (unsigned long)kbuff + offset; -+ unsigned long size = vma->vm_end - vma->vm_start; -+ int ret = 0; -+ -+ printk("phy: 0x%lx, offset: 0x%lx, size: 0x%lx\n", pfn_start << PAGE_SHIFT, offset, size); -+ -+ ret = remap_pfn_range(vma, vma->vm_start, pfn_start, size, vma->vm_page_prot); -+ if (ret) -+ printk("%s: remap_pfn_range failed at [0x%lx 0x%lx]\n", -+ __func__, vma->vm_start, vma->vm_end); -+ else -+ printk("%s: map 0x%lx to 0x%lx, size: 0x%lx\n", __func__, virt_start, -+ vma->vm_start, size); -+ -+ return ret; -+} -+ -+static const struct file_operations remap_pfn_fops = { -+ .owner = THIS_MODULE, -+ .open = remap_pfn_open, -+ .mmap = remap_pfn_mmap, -+}; -+ -+static struct miscdevice remap_pfn_misc = { -+ .minor = MISC_DYNAMIC_MINOR, -+ .name = "bl_log", -+ .fops = &remap_pfn_fops, -+}; -+ -+ -+int bl_logbuf_create(struct bl_hw *bl_hw) -+{ -+ int ret = 0; -+ -+ kbuff = kzalloc(LOG_BUF_SIZE, GFP_KERNEL); -+ bl_hw->log_buff = kbuff; -+ -+ device_create_file(bl_hw->dev, &dev_attr_filter_severity); -+ device_create_file(bl_hw->dev, &dev_attr_filter_module); -+ -+ ret = misc_register(&remap_pfn_misc); -+ -+ return ret; -+} -+ -+void bl_logbuf_destroy(struct bl_hw *bl_hw) -+{ -+ kfree(kbuff); -+ -+ device_remove_file(bl_hw->dev, &dev_attr_filter_severity); -+ device_remove_file(bl_hw->dev, &dev_attr_filter_module); -+ -+ misc_deregister(&remap_pfn_misc); -+} -+ -+int bl_cfg80211_init(struct bl_plat *bl_plat, void **platform_data) -+{ -+ struct bl_hw *bl_hw; -+ struct bl_conf_file init_conf; -+ int ret = 0; -+ struct wiphy *wiphy; -+ struct wireless_dev *wdev; -+ int i; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ /* create a new wiphy for use with cfg80211 */ -+ wiphy = wiphy_new(&bl_cfg80211_ops, sizeof(struct bl_hw)); -+ -+ if (!wiphy) { -+ dev_err(bl_platform_get_dev(bl_plat), "Failed to create new wiphy\n"); -+ ret = -ENOMEM; -+ goto err_out; -+ } -+ -+ bl_hw = wiphy_priv(wiphy); -+ bl_hw->wiphy = wiphy; -+ bl_hw->plat = bl_plat; -+ bl_hw->dev = bl_platform_get_dev(bl_plat); -+ bl_hw->mod_params = &bl_mod_params; -+ -+ /* set device pointer for wiphy */ -+ set_wiphy_dev(wiphy, bl_hw->dev); -+ -+ /* Create cache to allocate sw_txhdr */ -+ bl_hw->sw_txhdr_cache = kmem_cache_create("bl_sw_txhdr_cache", -+ sizeof(struct bl_sw_txhdr), -+ 0, 0, NULL); -+ if (!bl_hw->sw_txhdr_cache) { -+ wiphy_err(wiphy, "Cannot allocate cache for sw TX header\n"); -+ ret = -ENOMEM; -+ goto err_cache; -+ } -+ -+ bl_hw->agg_reodr_pkt_cache= kmem_cache_create("bl_agg_reodr_pkt_cache", -+ sizeof(struct bl_agg_reord_pkt), -+ 0, 0, NULL); -+ if (!bl_hw->agg_reodr_pkt_cache) { -+ wiphy_err(wiphy, "Cannot allocate cache for agg reorder packet\n"); -+ ret = -ENOMEM; -+ goto err_reodr; -+ } -+ -+ bl_hw->mpa_rx_data.buf = kzalloc(BL_RX_DATA_BUF_SIZE_16K, GFP_KERNEL); -+ if(!bl_hw->mpa_rx_data.buf){ -+ BL_DBG("allocate rx buf fail \n"); -+ ret = -ENOMEM; -+ goto err_config; -+ } -+ -+ bl_hw->mpa_tx_data.buf = kzalloc(BL_TX_DATA_BUF_SIZE_16K, GFP_KERNEL); -+ if(!bl_hw->mpa_tx_data.buf){ -+ BL_DBG("allocate tx buf fail \n"); -+ ret = -ENOMEM; -+ goto err_alloc; -+ } -+ -+ if ((ret = bl_parse_configfile(bl_hw, BL_CONFIG_FW_NAME, &init_conf))) { -+ wiphy_err(wiphy, "bl_parse_configfile failed\n"); -+ goto err_platon; -+ } -+ -+ bl_hw->sec_phy_chan.band = NL80211_BAND_5GHZ; -+ bl_hw->sec_phy_chan.type = PHY_CHNL_BW_20; -+ bl_hw->sec_phy_chan.prim20_freq = 5500; -+ bl_hw->sec_phy_chan.center_freq1 = 5500; -+ bl_hw->sec_phy_chan.center_freq2 = 0; -+ bl_hw->vif_started = 0; -+ bl_hw->adding_sta = false; -+ -+ bl_hw->preq_ie.buf = NULL; -+ -+ for (i = 0; i < NX_VIRT_DEV_MAX + NX_REMOTE_STA_MAX; i++) -+ bl_hw->avail_idx_map |= BIT(i); -+ -+ bl_hwq_init(bl_hw); -+ -+ for (i = 0; i < NX_NB_TXQ; i++) { -+ bl_hw->txq[i].idx = TXQ_INACTIVE; -+ } -+ -+ /* Initialize RoC element pointer to NULL, indicate that RoC can be started */ -+ bl_hw->roc_elem = NULL; -+ /* Cookie can not be 0 */ -+ bl_hw->roc_cookie_cnt = 1; -+ -+ memcpy(wiphy->perm_addr, init_conf.mac_addr, ETH_ALEN); -+ wiphy->mgmt_stypes = bl_default_mgmt_stypes; -+ wiphy->bands[NL80211_BAND_2GHZ] = &bl_band_2GHz; -+ wiphy->interface_modes = -+ BIT(NL80211_IFTYPE_STATION) | -+ BIT(NL80211_IFTYPE_AP) | -+ BIT(NL80211_IFTYPE_AP_VLAN) | -+ BIT(NL80211_IFTYPE_P2P_CLIENT) | -+ BIT(NL80211_IFTYPE_P2P_GO); -+ wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | -+ WIPHY_FLAG_HAS_CHANNEL_SWITCH | -+ WIPHY_FLAG_4ADDR_STATION | -+ WIPHY_FLAG_4ADDR_AP; -+ -+ wiphy->max_num_csa_counters = BCN_MAX_CSA_CPT; -+ -+ wiphy->max_remain_on_channel_duration = bl_hw->mod_params->roc_dur_max; -+ -+ wiphy->features |= NL80211_FEATURE_NEED_OBSS_SCAN | -+ NL80211_FEATURE_SK_TX_STATUS | -+ NL80211_FEATURE_VIF_TXPOWER; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) -+ wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE; -+#endif -+ -+ wiphy->iface_combinations = bl_combinations; -+ /* -1 not to include combination with radar detection, will be re-added in -+ bl_handle_dynparams if supported */ -+ wiphy->n_iface_combinations = ARRAY_SIZE(bl_combinations) - 1; -+ wiphy->reg_notifier = bl_reg_notifier; -+ -+ wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; -+ -+ wiphy->cipher_suites = cipher_suites; -+ wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites) - NB_RESERVED_CIPHER; -+ -+ bl_hw->ext_capa[0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING; -+ bl_hw->ext_capa[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF; -+ -+ wiphy->extended_capabilities = bl_hw->ext_capa; -+ wiphy->extended_capabilities_mask = bl_hw->ext_capa; -+ wiphy->extended_capabilities_len = ARRAY_SIZE(bl_hw->ext_capa); -+ bl_hw->workqueue = alloc_workqueue("BL_WORK_QUEUE", WQ_HIGHPRI | WQ_MEM_RECLAIM | WQ_UNBOUND, 1); -+ if (!bl_hw->workqueue) { -+ printk("creat workqueue failed\n"); -+ goto err_platon; -+ } -+ INIT_WORK(&bl_hw->main_work, main_wq_hdlr); -+ -+ INIT_LIST_HEAD(&bl_hw->vifs); -+ -+ mutex_init(&bl_hw->dbginfo.mutex); -+ spin_lock_init(&bl_hw->tx_lock); -+ spin_lock_init(&bl_hw->main_proc_lock); -+ spin_lock_init(&bl_hw->int_lock); -+ spin_lock_init(&bl_hw->cmd_lock); -+ spin_lock_init(&bl_hw->resend_lock); -+ spin_lock_init(&bl_hw->txq_lock); -+ bl_hw->bl_processing = false; -+ bl_hw->more_task_flag = false; -+ bl_hw->cmd_sent = false; -+ bl_hw->resend = false; -+ bl_hw->recovery_flag = false; -+ bl_hw->msg_idx = 1; -+ -+ for(i = 0; i < NX_REMOTE_STA_MAX*NX_NB_TID_PER_STA; i++) -+ INIT_LIST_HEAD(&bl_hw->reorder_list[i]); -+ -+ if ((ret = bl_platform_on(bl_hw))) -+ goto err_workqueue; -+ -+ *platform_data = bl_hw; -+ sdio_set_drvdata(bl_hw->plat->func, bl_hw); -+ -+ bl_logbuf_create(bl_hw); -+ //TODO add magic char 'L' to header file -+ BL_DBG("Notify FW to start...\n"); -+ bl_write_reg(bl_hw, 0x60, 'L'); -+ -+ /* Reset FW */ -+ if ((ret = bl_send_reset(bl_hw))) -+ goto err_lmac_reqs; -+ -+ if ((ret = bl_send_version_req(bl_hw, &bl_hw->version_cfm))) -+ goto err_lmac_reqs; -+ bl_set_vers(bl_hw); -+ -+ if ((ret = bl_handle_dynparams(bl_hw, bl_hw->wiphy))) -+ goto err_lmac_reqs; -+ -+ /* Set parameters to firmware */ -+ bl_send_me_config_req(bl_hw); -+ -+ if ((ret = wiphy_register(wiphy))) { -+ wiphy_err(wiphy, "Could not register wiphy device\n"); -+ goto err_register_wiphy; -+ } -+ -+ -+ /* Set channel parameters to firmware (must be done after WiPHY registration) */ -+ bl_send_me_chan_config_req(bl_hw); -+ -+ *platform_data = bl_hw; -+ -+ //bl_logbuf_create(bl_hw); -+ -+ bl_dbgfs_register(bl_hw, "bl"); -+ -+ -+ rtnl_lock(); -+ -+ /* Add an initial station interface */ -+ wdev = bl_interface_add(bl_hw, "wlan%d", NL80211_IFTYPE_STATION, NULL); -+ -+ rtnl_unlock(); -+ -+ if (!wdev) { -+ wiphy_err(wiphy, "Failed to instantiate a network device\n"); -+ ret = -ENOMEM; -+ goto err_add_interface; -+ } -+ -+ wiphy_info(wiphy, "New interface create %s", wdev->netdev->name); -+ -+ return 0; -+ -+err_add_interface: -+ wiphy_unregister(bl_hw->wiphy); -+err_register_wiphy: -+err_lmac_reqs: -+ bl_platform_off(bl_hw); -+err_workqueue: -+ if(bl_hw->workqueue) -+ destroy_workqueue(bl_hw->workqueue); -+err_platon: -+ kfree(bl_hw->mpa_tx_data.buf); -+err_alloc: -+ kfree(bl_hw->mpa_rx_data.buf); -+err_config: -+ kmem_cache_destroy(bl_hw->agg_reodr_pkt_cache); -+err_reodr: -+ kmem_cache_destroy(bl_hw->sw_txhdr_cache); -+err_cache: -+ wiphy_free(wiphy); -+err_out: -+ return ret; -+} -+ -+void bl_cfg80211_deinit(struct bl_hw *bl_hw) -+{ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ bl_logbuf_destroy(bl_hw); -+ kfree(bl_hw->mpa_rx_data.buf); -+ bl_hw->mpa_rx_data.buf = NULL; -+ kfree(bl_hw->mpa_tx_data.buf); -+ bl_hw->mpa_tx_data.buf = NULL; -+ -+ bl_dbgfs_unregister(bl_hw); -+ -+ bl_wdev_unregister(bl_hw); -+ wiphy_unregister(bl_hw->wiphy); -+ -+ msleep(5000); -+ -+ destroy_workqueue(bl_hw->workqueue); -+ -+ bl_platform_off(bl_hw); -+ kmem_cache_destroy(bl_hw->sw_txhdr_cache); -+ kmem_cache_destroy(bl_hw->agg_reodr_pkt_cache); -+ wiphy_free(bl_hw->wiphy); -+} -+ -+static int __init bl_mod_init(void) -+{ -+ BL_DBG(BL_FN_ENTRY_STR); -+ bl_print_version(); -+ -+ return bl_platform_register_drv(); -+} -+ -+static void __exit bl_mod_exit(void) -+{ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ bl_platform_unregister_drv(); -+} -+ -+module_init(bl_mod_init); -+module_exit(bl_mod_exit); -+ -+MODULE_FIRMWARE(BL_CONFIG_FW_NAME); -+ -+MODULE_DESCRIPTION(RW_DRV_DESCRIPTION); -+MODULE_VERSION(BL_VERS_MOD); -+MODULE_AUTHOR(RW_DRV_COPYRIGHT " " RW_DRV_AUTHOR); -+MODULE_LICENSE("GPL"); -diff -Naur /dev/null/bl_main.h b/drivers/net/wireless/hflps170/fullmac/bl_main.h ---- /dev/null/bl_main.h 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/fullmac/bl_main.h 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,19 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file bl_main.h -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ ****************************************************************************** -+ */ -+ -+#ifndef _BL_MAIN_H_ -+#define _BL_MAIN_H_ -+ -+#include "bl_defs.h" -+ -+int bl_cfg80211_init(struct bl_plat *bl_plat, void **platform_data); -+void bl_cfg80211_deinit(struct bl_hw *bl_hw); -+ -+#endif /* _BL_MAIN_H_ */ -diff -Naur /dev/null/bl_rx.c b/drivers/net/wireless/hflps170/fullmac/bl_rx.c ---- /dev/null/bl_rx.c 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/fullmac/bl_rx.c 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,568 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file bl_rx.c -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ ****************************************************************************** -+ */ -+#include -+#include -+#include -+#include -+ -+#include "bl_defs.h" -+#include "bl_rx.h" -+#include "bl_tx.h" -+#include "bl_events.h" -+#include "bl_compat.h" -+ -+const u8 legrates_lut[] = { -+ 0, /* 0 */ -+ 1, /* 1 */ -+ 2, /* 2 */ -+ 3, /* 3 */ -+ -1, /* 4 */ -+ -1, /* 5 */ -+ -1, /* 6 */ -+ -1, /* 7 */ -+ 10, /* 8 */ -+ 8, /* 9 */ -+ 6, /* 10 */ -+ 4, /* 11 */ -+ 11, /* 12 */ -+ 9, /* 13 */ -+ 7, /* 14 */ -+ 5 /* 15 */ -+}; -+ -+ -+/** -+ * bl_rx_statistic - save some statistics about received frames -+ * -+ * @bl_hw: main driver data. -+ * @hw_rxhdr: Rx Hardware descriptor of the received frame. -+ * @sta: STA that sent the frame. -+ */ -+static void bl_rx_statistic(struct bl_hw *bl_hw, struct hw_rxhdr *hw_rxhdr, -+ struct bl_sta *sta) -+{ -+#ifdef CONFIG_BL_DEBUGFS -+ struct bl_stats *stats = &bl_hw->stats; -+ struct bl_rx_rate_stats *rate_stats = &sta->stats.rx_rate; -+ struct hw_vect *hwvect = &hw_rxhdr->hwvect; -+ int mpdu, ampdu, mpdu_prev, rate_idx; -+ -+ /* save complete hwvect */ -+ sta->stats.last_rx = *hwvect; -+ -+ /* update ampdu rx stats */ -+ mpdu = hwvect->mpdu_cnt; -+ ampdu = hwvect->ampdu_cnt; -+ mpdu_prev = stats->ampdus_rx_map[ampdu]; -+ -+ if (mpdu_prev < mpdu ) { -+ stats->ampdus_rx_miss += mpdu - mpdu_prev - 1; -+ } else { -+ stats->ampdus_rx[mpdu_prev]++; -+ } -+ stats->ampdus_rx_map[ampdu] = mpdu; -+ -+ /* update rx rate statistic */ -+ if (hwvect->format_mod > FORMATMOD_NON_HT_DUP_OFDM) { -+ int mcs = hwvect->mcs; -+ int bw = hwvect->ch_bw; -+ int sgi = hwvect->short_gi; -+ int nss; -+ if (hwvect->format_mod <= FORMATMOD_HT_GF) { -+ nss = hwvect->stbc ? hwvect->stbc : hwvect->n_sts; -+ rate_idx = 16 + nss * 32 + mcs * 4 + bw * 2 + sgi; -+ } else { -+ nss = hwvect->stbc ? hwvect->stbc/2 : hwvect->n_sts; -+ rate_idx = 144 + nss * 80 + mcs * 8 + bw * 2 + sgi; -+ } -+ } else { -+ int idx = legrates_lut[hwvect->leg_rate]; -+ if (idx < 4) { -+ rate_idx = idx * 2 + hwvect->pre_type; -+ } else { -+ rate_idx = 8 + idx - 4; -+ } -+ } -+ if (rate_idx < rate_stats->size) { -+ rate_stats->table[rate_idx]++; -+ rate_stats->cpt++; -+ } else { -+ pr_err("Invalid index conversion => %d / %d\n", rate_idx, rate_stats->size); -+ } -+#endif -+} -+ -+ static const u16 bl_1d_to_wmm_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; -+ -+u16 bl_recal_priority_netdevidx(struct bl_vif *bl_vif, struct sk_buff *skb) -+{ -+ struct bl_hw *bl_hw = bl_vif->bl_hw; -+ struct wireless_dev *wdev = &bl_vif->wdev; -+ struct bl_sta *sta = NULL; -+ struct bl_txq *txq; -+ u16 netdev_queue; -+ bool tdls_mgmgt_frame = false; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ switch (wdev->iftype) { -+ case NL80211_IFTYPE_STATION: -+ { -+ struct ethhdr *eth; -+ eth = (struct ethhdr *)skb->data; -+ if (eth->h_proto == cpu_to_be16(ETH_P_TDLS)) { -+ tdls_mgmgt_frame = true; -+ } -+ sta = bl_vif->sta.ap; -+ break; -+ } -+ case NL80211_IFTYPE_AP_VLAN: -+ if (bl_vif->ap_vlan.sta_4a) { -+ sta = bl_vif->ap_vlan.sta_4a; -+ break; -+ } -+ -+ /* AP_VLAN interface is not used for a 4A STA, -+ fallback searching sta amongs all AP's clients */ -+ bl_vif = bl_vif->ap_vlan.master; -+ case NL80211_IFTYPE_AP: -+ { -+ struct bl_sta *cur; -+ struct ethhdr *eth = (struct ethhdr *)skb->data; -+ -+ if (is_multicast_ether_addr(eth->h_dest)) { -+ sta = &bl_hw->sta_table[bl_vif->ap.bcmc_index]; -+ } else { -+ list_for_each_entry(cur, &bl_vif->ap.sta_list, list) { -+ if (!memcmp(cur->mac_addr, eth->h_dest, ETH_ALEN)) { -+ sta = cur; -+ break; -+ } -+ } -+ } -+ -+ break; -+ } -+ default: -+ break; -+ } -+ -+ if (sta && sta->qos) -+ { -+ /* use the data classifier to determine what 802.1d tag the data frame has */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) -+ skb->priority = cfg80211_classify8021d(skb, NULL) & IEEE80211_QOS_CTL_TAG1D_MASK; -+#else -+ skb->priority = cfg80211_classify8021d(skb) & IEEE80211_QOS_CTL_TAG1D_MASK; -+#endif -+ if (sta->acm) -+ bl_downgrade_ac(sta, skb); -+ -+ txq = bl_txq_sta_get(sta, skb->priority, NULL, bl_hw); -+ netdev_queue = txq->ndev_idx; -+ } -+ else if (sta) -+ { -+ skb->priority = 0xFF; -+ txq = bl_txq_sta_get(sta, 0, NULL, bl_hw); -+ netdev_queue = txq->ndev_idx; -+ } -+ else -+ { -+ /* This packet will be dropped in xmit function, still need to select -+ an active queue for xmit to be called. As it most likely to happen -+ for AP interface, select BCMC queue -+ (TODO: select another queue if BCMC queue is stopped) */ -+ skb->priority = 0xAA; -+ netdev_queue = NX_BCMC_TXQ_NDEV_IDX; -+ } -+ -+ BUG_ON(netdev_queue >= NX_NB_NDEV_TXQ); -+ -+ if(skb->priority < 8) -+ return bl_1d_to_wmm_queue[skb->priority]; -+ else -+ return 0; -+ -+// return netdev_queue; -+} -+ -+/** -+ * bl_rx_data_skb - Process one data frame -+ * -+ * @bl_hw: main driver data -+ * @bl_vif: vif that received the buffer -+ * @skb: skb received -+ * @rxhdr: HW rx descriptor -+ * @return: true if buffer has been forwarded to upper layer -+ * -+ * If buffer is amsdu , it is first split into a list of skb. -+ * Then each skb may be: -+ * - forwarded to upper layer -+ * - resent on wireless interface -+ * -+ * When vif is a STA interface, every skb is only forwarded to upper layer. -+ * When vif is an AP interface, multicast skb are forwarded and resent, whereas -+ * skb for other BSS's STA are only resent. -+ */ -+static bool bl_rx_data_skb(struct bl_hw *bl_hw, struct bl_vif *bl_vif, -+ struct sk_buff *skb, struct hw_rxhdr *rxhdr) -+{ -+ struct sk_buff_head list; -+ struct sk_buff *rx_skb; -+ struct bl_sta *sta = NULL; -+ u16 netdev_queue; -+ bool amsdu = rxhdr->flags_is_amsdu; -+ bool resend = false, forward = true; -+ -+ skb->dev = bl_vif->ndev; -+ -+ __skb_queue_head_init(&list); -+ -+ if (amsdu) { -+ int count; -+ -+ ieee80211_amsdu_to_8023s(skb, &list, bl_vif->ndev->dev_addr, -+ BL_VIF_TYPE(bl_vif), 0, NULL, NULL); -+ -+ count = skb_queue_len(&list); -+ if (count > ARRAY_SIZE(bl_hw->stats.amsdus_rx)) -+ count = ARRAY_SIZE(bl_hw->stats.amsdus_rx); -+ bl_hw->stats.amsdus_rx[count - 1]++; -+ } else { -+ bl_hw->stats.amsdus_rx[0]++; -+ __skb_queue_head(&list, skb); -+ } -+ -+ if (((BL_VIF_TYPE(bl_vif) == NL80211_IFTYPE_AP) || -+ (BL_VIF_TYPE(bl_vif) == NL80211_IFTYPE_AP_VLAN)) && -+ !(bl_vif->ap.flags & BL_AP_ISOLATE)) { -+ const struct ethhdr *eth; -+ rx_skb = skb_peek(&list); -+ if(rx_skb == NULL) -+ printk("rx_skb=NULL!!!\n"); -+ /*go through mac_header, after mac_header is eth header*/ -+ skb_reset_mac_header(rx_skb); -+ eth = eth_hdr(rx_skb); -+ -+ if (unlikely(is_multicast_ether_addr(eth->h_dest))) { -+ /* broadcast pkt need to be forwared to upper layer and resent -+ on wireless interface */ -+ BL_DBG("this is a broadcast packet, forwared true and resend true!\n"); -+ resend = true; -+ } else { -+ /* unicast pkt for STA inside the BSS, no need to forward to upper -+ layer simply resend on wireless interface */ -+ if (rxhdr->flags_dst_idx != 0xFF) -+ { -+ BL_DBG("unicast pkt for STA inside the BSS, and forward false and resend true\n"); -+ sta = &bl_hw->sta_table[rxhdr->flags_dst_idx]; -+ if (sta->valid && (sta->vlan_idx == bl_vif->vif_index)) -+ { -+ forward = false; -+ resend = true; -+ } -+ } -+ } -+ } -+ -+ while (!skb_queue_empty(&list)) { -+ rx_skb = __skb_dequeue(&list); -+ BL_DBG("resend rx_skb->priority=%d, ndev_idx=%d\n", rx_skb->priority, skb_get_queue_mapping(rx_skb)); -+ -+ resend = false; -+ /* resend pkt on wireless interface */ -+ if (resend) { -+ struct sk_buff *skb_copy; -+ /* always need to copy buffer when forward=0 to get enough headrom for tsdesc */ -+ skb_copy = skb_copy_expand(rx_skb, sizeof(struct bl_txhdr) + sizeof(struct txdesc_api) + sizeof(struct sdio_hdr) + -+ BL_SWTXHDR_ALIGN_SZ, 0, GFP_ATOMIC); -+ if (skb_copy) { -+ int res; -+ skb_copy->protocol = htons(ETH_P_802_3); -+ skb_reset_network_header(skb_copy); -+ skb_reset_mac_header(skb_copy); -+ -+ BL_DBG("resend skb_copy=%p, skb len=0x%02x, skb->priority=%d, ndev_idx=%d\n", skb_copy, skb_copy->len, skb_copy->priority, skb_get_queue_mapping(skb_copy)); -+ -+ bl_vif->is_resending = true; -+ -+ netdev_queue = bl_recal_priority_netdevidx(bl_vif, skb_copy); -+ -+ skb_set_queue_mapping(skb_copy, netdev_queue); -+ -+ BL_DBG("after recal: skb->priority=%d, netdev_queue=%d\n", skb_copy->priority, netdev_queue); -+ -+ bl_hw->resend = true; -+ //res = dev_queue_xmit(skb_copy); -+ res = bl_requeue_multicast_skb(skb_copy, bl_vif); -+ bl_vif->is_resending = false; -+ /* note: buffer is always consummed by dev_queue_xmit */ -+ if (res == NET_XMIT_DROP) { -+ bl_vif->net_stats.rx_dropped++; -+ bl_vif->net_stats.tx_dropped++; -+ } else if (res != NET_XMIT_SUCCESS) { -+ netdev_err(bl_vif->ndev, -+ "Failed to re-send buffer to driver (res=%d)", -+ res); -+ bl_vif->net_stats.tx_errors++; -+ } -+ } else { -+ netdev_err(bl_vif->ndev, "Failed to copy skb"); -+ } -+ } -+ -+ /* forward pkt to upper layer */ -+ if (forward) { -+ rx_skb->protocol = eth_type_trans(rx_skb, bl_vif->ndev); -+ memset(rx_skb->cb, 0, sizeof(rx_skb->cb)); -+ -+ netif_receive_skb(rx_skb); -+ -+ /* Update statistics */ -+ bl_vif->net_stats.rx_packets++; -+ bl_vif->net_stats.rx_bytes += rx_skb->len; -+ BL_DBG("forward this packet to network layer success\n"); -+ } -+ } -+ -+ return forward; -+} -+ -+/** -+ * bl_rx_mgmt - Process one 802.11 management frame -+ * -+ * @bl_hw: main driver data -+ * @bl_vif: vif that received the buffer -+ * @skb: skb received -+ * @rxhdr: HW rx descriptor -+ * -+ * Process the management frame and free the corresponding skb -+ */ -+static void bl_rx_mgmt(struct bl_hw *bl_hw, struct bl_vif *bl_vif, -+ struct sk_buff *skb, struct hw_rxhdr *hw_rxhdr) -+{ -+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; -+ -+ trace_mgmt_rx(hw_rxhdr->phy_prim20_freq, hw_rxhdr->flags_vif_idx, -+ hw_rxhdr->flags_sta_idx, mgmt); -+ -+ if (ieee80211_is_beacon(mgmt->frame_control)) { -+ cfg80211_report_obss_beacon(bl_hw->wiphy, skb->data, skb->len, -+ hw_rxhdr->phy_prim20_freq, -+ hw_rxhdr->hwvect.rssi1); -+ } else if ((ieee80211_is_deauth(mgmt->frame_control) || -+ ieee80211_is_disassoc(mgmt->frame_control)) && -+ (mgmt->u.deauth.reason_code == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA || -+ mgmt->u.deauth.reason_code == WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA)) { -+ cfg80211_rx_unprot_mlme_mgmt(bl_vif->ndev, skb->data, skb->len); -+ } else if ((BL_VIF_TYPE(bl_vif) == NL80211_IFTYPE_STATION) && -+ (ieee80211_is_action(mgmt->frame_control) && -+ (mgmt->u.action.category == 6))) { -+ struct cfg80211_ft_event_params ft_event; -+ ft_event.target_ap = (uint8_t *)&mgmt->u.action + ETH_ALEN + 2; -+ ft_event.ies = (uint8_t *)&mgmt->u.action + ETH_ALEN*2 + 2; -+ ft_event.ies_len = hw_rxhdr->hwvect.len - (ft_event.ies - (uint8_t *)mgmt); -+ ft_event.ric_ies = NULL; -+ ft_event.ric_ies_len = 0; -+ cfg80211_ft_event(bl_vif->ndev, &ft_event); -+ } else { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0) -+ cfg80211_rx_mgmt(&bl_vif->wdev, hw_rxhdr->phy_prim20_freq, -+ hw_rxhdr->hwvect.rssi1, skb->data, skb->len, 0); -+#else -+ cfg80211_rx_mgmt(&bl_vif->wdev, hw_rxhdr->phy_prim20_freq, -+ hw_rxhdr->hwvect.rssi1, skb->data, skb->len, 0, GFP_ATOMIC); -+#endif -+ } -+ dev_kfree_skb(skb); -+} -+ -+/** -+ * bl_rx_get_vif - Return pointer to the destination vif -+ * -+ * @bl_hw: main driver data -+ * @vif_idx: vif index present in rx descriptor -+ * -+ * Select the vif that should receive this frame returns NULL if the destination -+ * vif is not active. -+ * If no vif is specified, this is probably a mgmt broadcast frame, so select -+ * the first active interface -+ */ -+static inline -+struct bl_vif *bl_rx_get_vif(struct bl_hw * bl_hw, int vif_idx) -+{ -+ struct bl_vif *bl_vif = NULL; -+ -+ if (vif_idx == 0xFF) { -+ list_for_each_entry(bl_vif, &bl_hw->vifs, list) { -+ if (bl_vif->up) -+ return bl_vif; -+ } -+ return NULL; -+ } else if (vif_idx < NX_VIRT_DEV_MAX) { -+ bl_vif = bl_hw->vif_table[vif_idx]; -+ if (!bl_vif || !bl_vif->up) -+ return NULL; -+ } -+ -+ return bl_vif; -+} -+ -+/** -+ * bl_rxdataind - Process rx buffer -+ * -+ * @pthis: Pointer to the object attached to the IPC structure -+ * (points to struct bl_hw is this case) -+ * @hostid: Address of the RX descriptor -+ * -+ * This function is called for each buffer received by the fw -+ * -+ */ -+u8 bl_rxdataind(void *pthis, void *hostid) -+{ -+ u32 status; -+ int sta_idx; -+ int tid; -+ u16 sn; -+ bool found = false; -+ -+ struct bl_hw *bl_hw = (struct bl_hw *)pthis; -+ struct hw_rxhdr *hw_rxhdr; -+ struct bl_vif *bl_vif; -+ struct sk_buff *skb = (struct sk_buff *)hostid; -+ struct bl_agg_reord_pkt *reord_pkt = NULL; -+ struct bl_agg_reord_pkt *reord_pkt_inst = NULL; -+ -+ int msdu_offset = sizeof(struct hw_rxhdr); -+ -+ /*status occupy 4 bytes*/ -+ memcpy(&status, skb->data, 4); -+ skb_pull(skb, 4); -+ -+ /* check that frame is completely uploaded */ -+ if (!status) { -+ printk("receive status error, status=0x%x\n", status); -+ return -1; -+ } -+ -+ BL_DBG("status---->:0x%x\n", status); -+ -+ if(status & RX_STAT_DELETE) { -+ BL_DBG("staus->delete, just free skb\n"); -+ skb_push(skb, sizeof(struct sdio_hdr) + 4); -+ dev_kfree_skb(skb); -+ goto end; -+ } -+ -+ /* Check if we need to forward the buffer */ -+ if (status & RX_STAT_FORWARD) { -+ hw_rxhdr = (struct hw_rxhdr *)skb->data; -+ bl_vif = bl_rx_get_vif(bl_hw, hw_rxhdr->flags_vif_idx); -+ -+ sn = hw_rxhdr->sn; -+ tid = hw_rxhdr->tid; -+ BL_DBG("RX_STATE_FORWARD: sn=%u, tid=%d\n", sn, tid); -+ -+ if (!bl_vif) { -+ dev_err(bl_hw->dev, "Frame received but no active vif (%d)", -+ hw_rxhdr->flags_vif_idx); -+ dev_kfree_skb(skb); -+ goto end; -+ } -+ -+ skb_pull(skb, msdu_offset); -+ /*Now, skb->data pointed to the real payload*/ -+ -+ if (hw_rxhdr->flags_is_80211_mpdu) { -+ BL_DBG("receive mgmt packet: type=0x%x, subtype=0x%x\n", -+ BL_FC_GET_TYPE(((struct ieee80211_mgmt *)skb->data)->frame_control), BL_FC_GET_STYPE(((struct ieee80211_mgmt *)skb->data)->frame_control)); -+ bl_rx_mgmt(bl_hw, bl_vif, skb, hw_rxhdr); -+ } else { -+ BL_DBG("receive data packet: type=0x%x, subtype=0x%x\n", -+ BL_FC_GET_TYPE(*((u8 *)(skb->data))), BL_FC_GET_STYPE(*((u8 *)(skb->data)))); -+ -+ if (hw_rxhdr->flags_sta_idx != 0xff) { -+ struct bl_sta *sta= &bl_hw->sta_table[hw_rxhdr->flags_sta_idx]; -+ -+ bl_rx_statistic(bl_hw, hw_rxhdr, sta); -+ -+ //printk("sta->vlan_idx=%d, bl_vif->vif_index=%d\n", sta->vlan_idx, bl_vif->vif_index); -+ if (sta->vlan_idx != bl_vif->vif_index) { -+ bl_vif = bl_hw->vif_table[sta->vlan_idx]; -+ if (!bl_vif) { -+ printk("cannot find the vif\n"); -+ dev_kfree_skb(skb); -+ goto end; -+ } -+ } -+ -+ if (hw_rxhdr->flags_is_4addr && !bl_vif->use_4addr) { -+ cfg80211_rx_unexpected_4addr_frame(bl_vif->ndev, -+ sta->mac_addr, GFP_ATOMIC); -+ } -+ } -+ -+ BL_DBG("original skb->priority=%d\n", skb->priority); -+ skb->priority = 256 + hw_rxhdr->flags_user_prio; -+ BL_DBG("hw_rxhdr->flags_user_prio=%d, skb->priority=%d, ndev_idx=%d\n", hw_rxhdr->flags_user_prio, skb->priority, skb_get_queue_mapping(skb)); -+ if (!bl_rx_data_skb(bl_hw, bl_vif, skb, hw_rxhdr)) { -+ dev_kfree_skb(skb); -+ } -+ } -+ } -+ -+ if (status & RX_STAT_ALLOC) { -+ /*put skb into right list according sta_idx & tid*/ -+ hw_rxhdr = (struct hw_rxhdr *)skb->data; -+ sta_idx = hw_rxhdr->flags_sta_idx; -+ sn = hw_rxhdr->sn; -+ tid = hw_rxhdr->tid; -+ -+ BL_DBG("RX_STATE_ALLOC: sta_idx=%d, sn=%u, tid=%d\n", sta_idx, sn, tid); -+ -+ //restore the skb and add into the tail of reorder list -+ skb_push(skb, 4); -+ -+ /*construct the reorder pkt*/ -+ reord_pkt = kmem_cache_alloc(bl_hw->agg_reodr_pkt_cache, GFP_ATOMIC); -+ if(reord_pkt == NULL) { -+ printk("KMEM CACHE ALLOC failed\n"); -+ return -1; -+ } -+ -+ reord_pkt->skb = skb; -+ reord_pkt->sn = sn; -+ -+ if (!list_empty(&bl_hw->reorder_list[sta_idx*NX_NB_TID_PER_STA + tid])) { -+ list_for_each_entry(reord_pkt_inst, &bl_hw->reorder_list[sta_idx*NX_NB_TID_PER_STA + tid], list) { -+ BL_DBG("reord_pkt_inst->sn=%u, sn=%u\n", reord_pkt_inst->sn, sn); -+ if(reord_pkt_inst->sn > sn) { -+ BL_DBG("Add sn %u before sn %u\n", sn, reord_pkt_inst->sn); -+ found = true; -+ list_add(&(reord_pkt->list), reord_pkt_inst->list.prev); -+ break; -+ } -+ } -+ -+ if(!found) { -+ BL_DBG("not found, add sn %u to tail\n", sn); -+ list_add_tail(&(reord_pkt->list), &bl_hw->reorder_list[sta_idx*NX_NB_TID_PER_STA+tid]); -+ } -+ } else { -+ BL_DBG("list is empty, add sn %u in tail\n", sn); -+ list_add_tail(&(reord_pkt->list), &bl_hw->reorder_list[sta_idx*NX_NB_TID_PER_STA+tid]); -+ } -+ } -+ -+ end: -+ -+ return 0; -+} -diff -Naur /dev/null/bl_rx.h b/drivers/net/wireless/hflps170/fullmac/bl_rx.h ---- /dev/null/bl_rx.h 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/fullmac/bl_rx.h 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,176 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file bl_rx.h -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ ****************************************************************************** -+ */ -+#ifndef _BL_RX_H_ -+#define _BL_RX_H_ -+ -+enum rx_status_bits -+{ -+ /// The buffer can be forwarded to the networking stack -+ RX_STAT_FORWARD = 1 << 0, -+ /// A new buffer has to be allocated -+ RX_STAT_ALLOC = 1 << 1, -+ /// The buffer has to be deleted -+ RX_STAT_DELETE = 1 << 2, -+ /// The length of the buffer has to be updated -+ RX_STAT_LEN_UPDATE = 1 << 3, -+ /// The length in the Ethernet header has to be updated -+ RX_STAT_ETH_LEN_UPDATE = 1 << 4, -+ /// Simple copy -+ RX_STAT_COPY = 1 << 5, -+}; -+ -+ -+/* -+ * Decryption status subfields. -+ * { -+ */ -+#define BL_RX_HD_DECR_UNENC 0 // Frame unencrypted -+#define BL_RX_HD_DECR_ICVFAIL 1 // WEP/TKIP ICV failure -+#define BL_RX_HD_DECR_CCMPFAIL 2 // CCMP failure -+#define BL_RX_HD_DECR_AMSDUDISCARD 3 // A-MSDU discarded at HW -+#define BL_RX_HD_DECR_NULLKEY 4 // NULL key found -+#define BL_RX_HD_DECR_WEPSUCCESS 5 // Security type WEP -+#define BL_RX_HD_DECR_TKIPSUCCESS 6 // Security type TKIP -+#define BL_RX_HD_DECR_CCMPSUCCESS 7 // Security type CCMP -+// @} -+ -+struct hw_vect { -+ /** Total length for the MPDU transfer */ -+ u32 len :16; -+ -+ u32 reserved : 8; -+ -+ /** AMPDU Status Information */ -+ u32 mpdu_cnt : 6; -+ u32 ampdu_cnt : 2; -+ -+ -+ /** TSF Low */ -+ __le32 tsf_lo; -+ /** TSF High */ -+ __le32 tsf_hi; -+ -+ /** Receive Vector 1a */ -+ u32 leg_length :12; -+ u32 leg_rate : 4; -+ u32 ht_length :16; -+ -+ /** Receive Vector 1b */ -+ u32 _ht_length : 4; // FIXME -+ u32 short_gi : 1; -+ u32 stbc : 2; -+ u32 smoothing : 1; -+ u32 mcs : 7; -+ u32 pre_type : 1; -+ u32 format_mod : 3; -+ u32 ch_bw : 2; -+ u32 n_sts : 3; -+ u32 lsig_valid : 1; -+ u32 sounding : 1; -+ u32 num_extn_ss : 2; -+ u32 aggregation : 1; -+ u32 fec_coding : 1; -+ u32 dyn_bw : 1; -+ u32 doze_not_allowed : 1; -+ -+ /** Receive Vector 1c */ -+ u32 antenna_set : 8; -+ u32 partial_aid : 9; -+ u32 group_id : 6; -+ u32 reserved_1c : 1; -+ s32 rssi1 : 8; -+ -+ /** Receive Vector 1d */ -+ s32 rssi2 : 8; -+ s32 rssi3 : 8; -+ s32 rssi4 : 8; -+ u32 reserved_1d : 8; -+ -+ /** Receive Vector 2a */ -+ u32 rcpi : 8; -+ u32 evm1 : 8; -+ u32 evm2 : 8; -+ u32 evm3 : 8; -+ -+ /** Receive Vector 2b */ -+ u32 evm4 : 8; -+ u32 reserved2b_1 : 8; -+ u32 reserved2b_2 : 8; -+ u32 reserved2b_3 : 8; -+ -+ /** Status **/ -+ u32 rx_vect2_valid : 1; -+ u32 resp_frame : 1; -+ /** Decryption Status */ -+ u32 decr_status : 3; -+ u32 rx_fifo_oflow : 1; -+ -+ /** Frame Unsuccessful */ -+ u32 undef_err : 1; -+ u32 phy_err : 1; -+ u32 fcs_err : 1; -+ u32 addr_mismatch : 1; -+ u32 ga_frame : 1; -+ u32 current_ac : 2; -+ -+ u32 frm_successful_rx : 1; -+ /** Descriptor Done */ -+ u32 desc_done_rx : 1; -+ /** Key Storage RAM Index */ -+ u32 key_sram_index : 10; -+ /** Key Storage RAM Index Valid */ -+ u32 key_sram_v : 1; -+ u32 type : 2; -+ u32 subtype : 4; -+}; -+ -+struct hw_rxhdr { -+ /** RX vector */ -+ struct hw_vect hwvect; -+ -+ /** PHY channel information 1 */ -+ u32 phy_band : 8; -+ u32 phy_channel_type : 8; -+ u32 phy_prim20_freq : 16; -+ /** PHY channel information 2 */ -+ u32 phy_center1_freq : 16; -+ u32 phy_center2_freq : 16; -+ /** RX flags */ -+ u32 flags_is_amsdu : 1; -+ u32 flags_is_80211_mpdu: 1; -+ u32 flags_is_4addr : 1; -+ u32 flags_new_peer : 1; -+ u32 flags_user_prio : 3; -+ u32 flags_rsvd0 : 1; -+ u32 flags_vif_idx : 8; // 0xFF if invalid VIF index -+ u32 flags_sta_idx : 8; // 0xFF if invalid STA index -+ u32 flags_dst_idx : 8; // 0xFF if unknown destination STA -+ u16 sn; -+ u16 tid; -+}__packed; -+ -+struct bl_agg_reodr_msg { -+ u16 sn; -+ u8 sta_idx; -+ u8 tid; -+ u8 status; -+ u8 num; -+}__packed; -+ -+extern const u8 legrates_lut[]; -+#define BL_FC_GET_TYPE(fc) (((fc) & 0x000c) >> 2) -+#define BL_FC_GET_STYPE(fc) (((fc) & 0x00f0) >> 4) -+ -+#define AGG_REORD_MSG_MAX_NUM 4096 -+ -+ -+u8 bl_rxdataind(void *pthis, void *hostid); -+ -+#endif /* _BL_RX_H_ */ -diff -Naur /dev/null/bl_tx.c b/drivers/net/wireless/hflps170/fullmac/bl_tx.c ---- /dev/null/bl_tx.c 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/fullmac/bl_tx.c 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,1558 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file bl_tx.c -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ ****************************************************************************** -+ */ -+#include -+#include -+#include -+#include -+#include -+ -+#include "bl_defs.h" -+#include "bl_tx.h" -+#include "bl_msg_tx.h" -+#include "bl_events.h" -+#include "bl_sdio.h" -+#include "bl_irqs.h" -+#include "bl_compat.h" -+ -+static u16 g_pkt_sn = 0; -+ -+/****************************************************************************** -+ * Power Save functions -+ *****************************************************************************/ -+/** -+ * bl_set_traffic_status - Inform FW if traffic is available for STA in PS -+ * -+ * @bl_hw: Driver main data -+ * @sta: Sta in PS mode -+ * @available: whether traffic is buffered for the STA -+ * @ps_id: type of PS data requested (@LEGACY_PS_ID or @UAPSD_ID) -+ */ -+void bl_set_traffic_status(struct bl_hw *bl_hw, -+ struct bl_sta *sta, -+ bool available, -+ u8 ps_id) -+{ -+ bool uapsd = (ps_id != LEGACY_PS_ID); -+ bl_send_me_traffic_ind(bl_hw, sta->sta_idx, uapsd, available); -+ trace_ps_traffic_update(sta->sta_idx, available, uapsd); -+} -+ -+/** -+ * bl_ps_bh_enable - Enable/disable PS mode for one STA -+ * -+ * @bl_hw: Driver main data -+ * @sta: Sta which enters/leaves PS mode -+ * @enable: PS mode status -+ * -+ * This function will enable/disable PS mode for one STA. -+ * When enabling PS mode: -+ * - Stop all STA's txq for BL_TXQ_STOP_STA_PS reason -+ * - Count how many buffers are already ready for this STA -+ * - For BC/MC sta, update all queued SKB to use hw_queue BCMC -+ * - Update TIM if some packet are ready -+ * -+ * When disabling PS mode: -+ * - Start all STA's txq for BL_TXQ_STOP_STA_PS reason -+ * - For BC/MC sta, update all queued SKB to use hw_queue AC_BE -+ * - Update TIM if some packet are ready (otherwise fw will not update TIM -+ * in beacon for this STA) -+ * -+ * All counter/skb updates are protected from TX path by taking tx_lock -+ * -+ * NOTE: _bh_ in function name indicates that this function is called -+ * from a bottom_half tasklet. -+ */ -+void bl_ps_bh_enable(struct bl_hw *bl_hw, struct bl_sta *sta, -+ bool enable) -+{ -+ struct bl_txq *txq = NULL; -+ txq = bl_txq_sta_get(sta, 0, NULL, bl_hw); -+ -+ if (enable) { -+ trace_ps_enable(sta); -+ -+ spin_lock(&bl_hw->tx_lock); -+ sta->ps.active = true; -+ sta->ps.sp_cnt[LEGACY_PS_ID] = 0; -+ sta->ps.sp_cnt[UAPSD_ID] = 0; -+ bl_txq_sta_stop(sta, BL_TXQ_STOP_STA_PS, bl_hw); -+ -+ if (is_multicast_sta(sta->sta_idx)) { -+ sta->ps.pkt_ready[LEGACY_PS_ID] = skb_queue_len(&txq->sk_list); -+ sta->ps.pkt_ready[UAPSD_ID] = 0; -+ txq->hwq = &bl_hw->hwq[BL_HWQ_BCMC]; -+ } else { -+ int i; -+ -+ sta->ps.pkt_ready[LEGACY_PS_ID] = 0; -+ sta->ps.pkt_ready[UAPSD_ID] = 0; -+ for (i = 0; i < NX_NB_TXQ_PER_STA; i++, txq++) { -+ sta->ps.pkt_ready[txq->ps_id] += skb_queue_len(&txq->sk_list); -+ } -+ } -+ -+ spin_unlock(&bl_hw->tx_lock); -+ -+ if (sta->ps.pkt_ready[LEGACY_PS_ID]) -+ bl_set_traffic_status(bl_hw, sta, true, LEGACY_PS_ID); -+ -+ if (sta->ps.pkt_ready[UAPSD_ID]) -+ bl_set_traffic_status(bl_hw, sta, true, UAPSD_ID); -+ } else { -+ trace_ps_disable(sta->sta_idx); -+ -+ spin_lock(&bl_hw->tx_lock); -+ sta->ps.active = false; -+ -+ if (is_multicast_sta(sta->sta_idx)) { -+ txq->hwq = &bl_hw->hwq[BL_HWQ_BE]; -+ txq->push_limit = 0; -+ } else { -+ int i; -+ for (i = 0; i < NX_NB_TXQ_PER_STA; i++, txq++) { -+ txq->push_limit = 0; -+ } -+ } -+ -+ bl_txq_sta_start(sta, BL_TXQ_STOP_STA_PS, bl_hw); -+ spin_unlock(&bl_hw->tx_lock); -+ -+ if (sta->ps.pkt_ready[LEGACY_PS_ID]) -+ bl_set_traffic_status(bl_hw, sta, false, LEGACY_PS_ID); -+ -+ if (sta->ps.pkt_ready[UAPSD_ID]) -+ bl_set_traffic_status(bl_hw, sta, false, UAPSD_ID); -+ } -+} -+ -+/** -+ * bl_ps_bh_traffic_req - Handle traffic request for STA in PS mode -+ * -+ * @bl_hw: Driver main data -+ * @sta: Sta which enters/leaves PS mode -+ * @pkt_req: number of pkt to push -+ * @ps_id: type of PS data requested (@LEGACY_PS_ID or @UAPSD_ID) -+ * -+ * This function will make sure that @pkt_req are pushed to fw -+ * whereas the STA is in PS mode. -+ * If request is 0, send all traffic -+ * If request is greater than available pkt, reduce request -+ * Note: request will also be reduce if txq credits are not available -+ * -+ * All counter updates are protected from TX path by taking tx_lock -+ * -+ * NOTE: _bh_ in function name indicates that this function is called -+ * from the bottom_half tasklet. -+ */ -+void bl_ps_bh_traffic_req(struct bl_hw *bl_hw, struct bl_sta *sta, -+ u16 pkt_req, u8 ps_id) -+{ -+ int pkt_ready_all; -+ struct bl_txq *txq; -+ -+ if (WARN(!sta->ps.active, "sta %pM is not in Power Save mode", -+ sta->mac_addr)) -+ return; -+ -+ trace_ps_traffic_req(sta, pkt_req, ps_id); -+ -+ spin_lock(&bl_hw->tx_lock); -+ -+ pkt_ready_all = (sta->ps.pkt_ready[ps_id] - sta->ps.sp_cnt[ps_id]); -+ -+ /* Don't start SP until previous one is finished or we don't have -+ packet ready (which must not happen for U-APSD) */ -+ if (sta->ps.sp_cnt[ps_id] || pkt_ready_all <= 0) { -+ goto done; -+ } -+ -+ /* Adapt request to what is available. */ -+ if (pkt_req == 0 || pkt_req > pkt_ready_all) { -+ pkt_req = pkt_ready_all; -+ } -+ -+ /* Reset the SP counter */ -+ sta->ps.sp_cnt[ps_id] = 0; -+ -+ /* "dispatch" the request between txq */ -+ txq = bl_txq_sta_get(sta, NX_NB_TXQ_PER_STA - 1, NULL, bl_hw); -+ -+ if (is_multicast_sta(sta->sta_idx)) { -+ if (txq->credits <= 0) -+ goto done; -+ if (pkt_req > txq->credits) -+ pkt_req = txq->credits; -+ txq->push_limit = pkt_req; -+ sta->ps.sp_cnt[ps_id] = pkt_req; -+ bl_txq_add_to_hw_list(txq); -+ } else { -+ int i; -+ /* TODO: dispatch using correct txq priority */ -+ for (i = NX_NB_TXQ_PER_STA - 1; i >= 0; i--, txq--) { -+ u16 txq_len = skb_queue_len(&txq->sk_list); -+ -+ if (txq->ps_id != ps_id) -+ continue; -+ -+ if (txq_len > txq->credits) -+ txq_len = txq->credits; -+ -+ if (txq_len > 0) { -+ if (txq_len < pkt_req) { -+ /* Not enough pkt queued in this txq, add this -+ txq to hwq list and process next txq */ -+ pkt_req -= txq_len; -+ txq->push_limit = txq_len; -+ sta->ps.sp_cnt[ps_id] += txq_len; -+ bl_txq_add_to_hw_list(txq); -+ } else { -+ /* Enough pkt in this txq to comlete the request -+ add this txq to hwq list and stop processing txq */ -+ txq->push_limit = pkt_req; -+ sta->ps.sp_cnt[ps_id] += pkt_req; -+ bl_txq_add_to_hw_list(txq); -+ break; -+ } -+ } -+ } -+ } -+ -+ done: -+ spin_unlock(&bl_hw->tx_lock); -+} -+ -+/****************************************************************************** -+ * TX functions -+ *****************************************************************************/ -+static const int bl_down_hwq2tid[3] = { -+ [BL_HWQ_BK] = 2, -+ [BL_HWQ_BE] = 3, -+ [BL_HWQ_VI] = 5, -+}; -+ -+void bl_downgrade_ac(struct bl_sta *sta, struct sk_buff *skb) -+{ -+ int8_t ac = bl_tid2hwq[skb->priority]; -+ -+ if (WARN((ac > BL_HWQ_VO), -+ "Unexepcted ac %d for skb before downgrade", ac)) -+ ac = BL_HWQ_VO; -+ -+ while (sta->acm & BIT(ac)) { -+ if (ac == BL_HWQ_BK) { -+ skb->priority = 1; -+ return; -+ } -+ ac--; -+ skb->priority = bl_down_hwq2tid[ac]; -+ } -+} -+ -+ -+/** -+ * bl_set_more_data_flag - Update MORE_DATA flag in tx sw desc -+ * -+ * @bl_hw: Driver main data -+ * @sw_txhdr: Header for pkt to be pushed -+ * -+ * If STA is in PS mode -+ * - Set EOSP in case the packet is the last of the UAPSD service period -+ * - Set MORE_DATA flag if more pkt are ready for this sta -+ * - Update TIM if this is the last pkt buffered for this sta -+ * -+ * note: tx_lock already taken. -+ */ -+static inline void bl_set_more_data_flag(struct bl_hw *bl_hw, -+ struct bl_sw_txhdr *sw_txhdr) -+{ -+ struct bl_sta *sta = sw_txhdr->bl_sta; -+ struct bl_txq *txq = sw_txhdr->txq; -+ -+ if (unlikely(sta->ps.active)) { -+ sta->ps.pkt_ready[txq->ps_id]--; -+ sta->ps.sp_cnt[txq->ps_id]--; -+ -+ trace_ps_push(sta); -+ -+ if (((txq->ps_id == UAPSD_ID)) -+ && !sta->ps.sp_cnt[txq->ps_id]) { -+ sw_txhdr->desc.host.flags |= TXU_CNTRL_EOSP; -+ } -+ -+ if (sta->ps.pkt_ready[txq->ps_id]) { -+ sw_txhdr->desc.host.flags |= TXU_CNTRL_MORE_DATA; -+ } else { -+ bl_set_traffic_status(bl_hw, sta, false, txq->ps_id); -+ } -+ } -+} -+ -+#define PRIO_STA_NULL 0xAA -+/** -+ * bl_get_tx_info - Get STA and tid for one skb -+ * -+ * @bl_vif: vif ptr -+ * @skb: skb -+ * @tid: pointer updated with the tid to use for this skb -+ * -+ * @return: pointer on the destination STA (may be NULL) -+ * -+ * skb has already been parsed in bl_select_queue function -+ * simply re-read information form skb. -+ */ -+static struct bl_sta *bl_get_tx_info(struct bl_vif *bl_vif, -+ struct sk_buff *skb, -+ u8 *tid) -+{ -+ struct bl_hw *bl_hw = bl_vif->bl_hw; -+ struct bl_sta *sta = NULL; -+ struct wireless_dev *wdev = &bl_vif->wdev; -+ struct ethhdr *eth = (struct ethhdr *)skb->data; -+ -+ *tid = skb->priority; -+ -+ if (unlikely(skb->priority == PRIO_STA_NULL)) { -+ return NULL; -+ } else { -+ switch (wdev->iftype) { -+ case NL80211_IFTYPE_STATION: -+ case NL80211_IFTYPE_P2P_CLIENT: -+ { -+ sta = bl_vif->sta.ap; -+ break; -+ } -+ case NL80211_IFTYPE_AP_VLAN: -+ if (bl_vif->ap_vlan.sta_4a) { -+ sta = bl_vif->ap_vlan.sta_4a; -+ break; -+ } -+ -+ /* AP_VLAN interface is not used for a 4A STA, -+ fallback searching sta amongs all AP's clients */ -+ bl_vif = bl_vif->ap_vlan.master; -+ case NL80211_IFTYPE_AP: -+ case NL80211_IFTYPE_P2P_GO: -+ { -+ struct bl_sta *cur; -+ if (is_broadcast_ether_addr(eth->h_dest) || is_multicast_ether_addr(eth->h_dest)) { -+ sta = &bl_hw->sta_table[bl_vif->ap.bcmc_index]; -+ } else { -+ list_for_each_entry(cur, &bl_vif->ap.sta_list, list) { -+ if (!memcmp(cur->mac_addr, eth->h_dest, ETH_ALEN)) { -+ sta = cur; -+ break; -+ } -+ } -+ } -+ -+ break; -+ } -+ default: -+ break; -+ } -+ } -+ -+ -+ return sta; -+} -+ -+#if 0 -+/** -+ * bl_get_tx_info - Get STA and tid for one skb -+ * -+ * @bl_vif: vif ptr -+ * @skb: skb -+ * @tid: pointer updated with the tid to use for this skb -+ * -+ * @return: pointer on the destination STA (may be NULL) -+ * -+ * skb has already been parsed in bl_select_queue function -+ * simply re-read information form skb. -+ */ -+static struct bl_sta *bl_get_tx_info(struct bl_vif *bl_vif, -+ struct sk_buff *skb, -+ u8 *tid) -+{ -+ struct bl_hw *bl_hw = bl_vif->bl_hw; -+ struct bl_sta *sta; -+ int sta_idx; -+ -+ *tid = skb->priority; -+ if (unlikely(skb->priority == PRIO_STA_NULL)) { -+ return NULL; -+ } else { -+ int ndev_idx = skb_get_queue_mapping(skb); -+ if (ndev_idx == NX_BCMC_TXQ_NDEV_IDX) -+ sta_idx = NX_REMOTE_STA_MAX + master_vif_idx(bl_vif); -+ else -+ sta_idx = ndev_idx / NX_NB_TID_PER_STA; -+ -+ sta = &bl_hw->sta_table[sta_idx]; -+ } -+ -+ return sta; -+} -+#endif -+ -+/** -+ * bl_tx_push - Push one packet to fw -+ * -+ * @bl_hw: Driver main data -+ * @txhdr: tx desc of the buffer to push -+ * @flags: push flags (see @bl_push_flags) -+ * -+ * Push one packet to fw. Sw desc of the packet has already been updated. -+ * Only MORE_DATA flag will be set if needed. -+ */ -+void bl_tx_push(struct bl_hw *bl_hw, struct bl_txhdr *txhdr, int flags) -+{ -+ struct bl_sw_txhdr *sw_txhdr = txhdr->sw_hdr; -+ struct txdesc_api *desc; -+ struct sk_buff *skb = sw_txhdr->skb; -+ struct bl_txq *txq = sw_txhdr->txq; -+ u16 hw_queue = txq->hwq->id; -+ int user = 0; -+ u32 wr_port; -+ u32 ret = 0; -+ ktime_t start; -+ -+ lockdep_assert_held(&bl_hw->tx_lock); -+ -+ /* RETRY flag is not always set so retest here */ -+ if (txq->nb_retry) { -+ flags |= BL_PUSH_RETRY; -+ txq->nb_retry--; -+ if (txq->nb_retry == 0) { -+ WARN(skb != txq->last_retry_skb, -+ "last retry buffer is not the expected one"); -+ txq->last_retry_skb = NULL; -+ } -+ } else if (!(flags & BL_PUSH_RETRY)) { -+ txq->pkt_sent++; -+ } -+ -+#ifdef CONFIG_BL_AMSDUS_TX -+ if (txq->amsdu == sw_txhdr) { -+ WARN((flags & BL_PUSH_RETRY), "End A-MSDU on a retry"); -+ bl_hw->stats.amsdus[sw_txhdr->amsdu.nb - 1].done++; -+ txq->amsdu = NULL; -+ } else if (!(flags & BL_PUSH_RETRY) && -+ !(sw_txhdr->desc.host.flags & TXU_CNTRL_AMSDU)) { -+ bl_hw->stats.amsdus[0].done++; -+ } -+#endif /* CONFIG_BL_AMSDUS_TX */ -+ -+ /* Wait here to update hw_queue, as for multicast STA hwq may change -+ between queue and push (because of PS) */ -+ sw_txhdr->hw_queue = hw_queue; -+ -+ if (sw_txhdr->bl_sta) { -+ /* only for AP mode */ -+ bl_set_more_data_flag(bl_hw, sw_txhdr); -+ } -+ -+ trace_push_desc(skb, sw_txhdr, flags); -+ BL_DBG("bl_tx_push:txq->idx=%d, txq->status=0x%x, txq->credits: %d--->%d\n", txq->idx, txq->status, txq->credits, txq->credits-1); -+ txq->credits--; -+ txq->pkt_pushed[user]++; -+ -+ if (txq->credits <= 0) { -+ bl_txq_stop(txq, BL_TXQ_STOP_FULL); -+ BL_DBG("delete txq from hwq, txq->idx=%d, txq->status=0x%x, txq-credits=%d\n", txq->idx, txq->status, txq->credits); -+ } -+ -+ if (txq->push_limit) -+ txq->push_limit--; -+ -+ /*use sdio interface to send the whole skb packet */ -+ /* fisrt, we should ignore the txhdr, after skb_pull, we got the real data */ -+ skb_pull(skb, sw_txhdr->headroom); -+ /*use sw_txhdr to override the sdio special header*/ -+ sw_txhdr->hdr.queue_idx = txq->hwq->id; //update queue idx to avoid ps mode modify it. -+ memcpy((void *)skb->data, &sw_txhdr->hdr, sizeof(struct sdio_hdr)); -+ memcpy((void *)skb->data + sizeof(struct sdio_hdr), &sw_txhdr->desc, sizeof(*desc)); -+ -+ /*when get wr_port failed*/ -+ ret = bl_get_wr_port(bl_hw, &wr_port); -+ if (ret) { -+ printk("get wr port failed ret=%d, requeue skb=%p\n", ret, skb); -+ skb_push(skb, sw_txhdr->headroom); -+ bl_txq_queue_skb(skb, txq, bl_hw, false); -+ return; -+ } -+ -+ BL_DBG("bl_tx_push: send skb=%p, skb->len=%d\n", skb, skb->len); -+ -+ start = ktime_get(); -+ ret = bl_write_data_sync(bl_hw, skb->data, skb->len, bl_hw->plat->io_port + wr_port); -+ bl_hw->dbg_time[bl_hw->dbg_time_idx].sdio_tx = ktime_us_delta(ktime_get(), start); -+ bl_hw->dbg_time_idx++; -+ -+ if(bl_hw->dbg_time_idx == 50) -+ bl_hw->dbg_time_idx = 0; -+ if(ret) { -+ printk("bl_write_data_sync failed, ret=%d\n", ret); -+ dev_kfree_skb_any(skb); -+ return; -+ } -+ -+ /*restore skb, txcfm will use this skb*/ -+ skb_push(skb, sw_txhdr->headroom); -+ ipc_host_txdesc_push(bl_hw->ipc_env, hw_queue, user, skb); -+ txq->hwq->credits[user]--; -+ bl_hw->stats.cfm_balance[hw_queue]++; -+} -+ -+/** 2K buf size */ -+#define BL_TX_DATA_BUF_SIZE_16K 16*1024 -+#define BL_SDIO_MP_AGGR_PKT_LIMIT_MAX 8 -+#define BL_SDIO_MPA_ADDR_BASE 0x1000 -+ -+//typedef struct _sdio_mpa_tx { -+// u8 *buf; -+// u32 buf_len; -+// u32 pkt_cnt; -+// u32 ports; -+// u16 start_port; -+// u16 mp_wr_info[BL_SDIO_MP_AGGR_PKT_LIMIT_MAX]; -+//}sdio_mpa_tx; -+ -+void bl_tx_multi_pkt_push(struct bl_hw *bl_hw, struct sk_buff_head *sk_list_push) -+{ -+ struct sk_buff *skb; -+ struct bl_txhdr *txhdr; -+ sdio_mpa_tx mpa_tx_data = {0}; -+ int ret; -+ u32 port; -+ u32 cmd53_port; -+ u32 buf_block_len; -+ int flags = 0; -+ -+ /*fix alloc buf size, such as 16K(2*8(aggr num))*/ -+ mpa_tx_data.buf = bl_hw->mpa_tx_data.buf; -+ if(mpa_tx_data.buf == NULL){ -+ printk("mpa_tx_data.buf is null!\n"); -+ return; -+ } -+ -+ /*copy multi skbs into one large buf*/ -+ while ((skb = __skb_dequeue(sk_list_push)) != NULL) { -+ txhdr = (struct bl_txhdr *)skb->data; -+ /* RETRY flag is not always set so retest here */ -+ if (txhdr->sw_hdr->txq->nb_retry) { -+ flags |= BL_PUSH_RETRY; -+ txhdr->sw_hdr->txq->nb_retry--; -+ if (txhdr->sw_hdr->txq->nb_retry == 0) { -+ WARN(skb != txhdr->sw_hdr->txq->last_retry_skb, -+ "last retry buffer is not the expected one"); -+ txhdr->sw_hdr->txq->last_retry_skb = NULL; -+ } -+ } else if (!(flags & BL_PUSH_RETRY)) { -+ txhdr->sw_hdr->txq->pkt_sent++; -+ } -+ -+ txhdr->sw_hdr->hw_queue = txhdr->sw_hdr->txq->hwq->id; -+ -+ if(txhdr->sw_hdr->bl_sta) -+ bl_set_more_data_flag(bl_hw, txhdr->sw_hdr); -+ -+// txhdr->sw_hdr->txq->credits--; -+ txhdr->sw_hdr->txq->pkt_pushed[0]++; -+ -+// if(txhdr->sw_hdr->txq->credits <= 0) -+// bl_txq_stop(txhdr->sw_hdr->txq, BL_TXQ_STOP_FULL); -+ -+ skb_pull(skb, txhdr->sw_hdr->headroom); -+ txhdr->sw_hdr->hdr.queue_idx = txhdr->sw_hdr->txq->hwq->id; -+ memcpy((void *)skb->data, &txhdr->sw_hdr->hdr, sizeof(struct sdio_hdr)); -+ memcpy((void *)skb->data + sizeof(struct sdio_hdr), &txhdr->sw_hdr->desc, sizeof(struct txdesc_api)); -+ buf_block_len = (skb->len + BL_SDIO_BLOCK_SIZE - 1) / BL_SDIO_BLOCK_SIZE; -+ memcpy((void *)&mpa_tx_data.buf[mpa_tx_data.buf_len], skb->data, buf_block_len * BL_SDIO_BLOCK_SIZE); -+ mpa_tx_data.buf_len += buf_block_len * BL_SDIO_BLOCK_SIZE; -+ -+ //printk("###%d: skb->len: %d, pad_len: %d\n", mpa_tx_data.pkt_cnt, skb->len, buf_block_len*BL_SDIO_BLOCK_SIZE); -+ -+ //mpa_tx_data.mp_wr_info[mpa_tx_data.pkt_cnt] = *(u16 *)skb->data; -+ -+ bl_get_wr_port(bl_hw, &port); -+ if(!mpa_tx_data.pkt_cnt) { -+ mpa_tx_data.start_port = port; -+ } -+ -+ if(mpa_tx_data.start_port <= port) { -+ mpa_tx_data.ports |= (1 << (mpa_tx_data.pkt_cnt)); -+ } else { -+ mpa_tx_data.ports |= (1 << (mpa_tx_data.pkt_cnt + 1)); -+ } -+ -+ mpa_tx_data.pkt_cnt++; -+ -+ skb_push(skb, txhdr->sw_hdr->headroom); -+ ipc_host_txdesc_push(bl_hw->ipc_env, txhdr->sw_hdr->hw_queue, 0, skb); -+// txhdr->sw_hdr->txq->hwq->credits[0]--; -+ bl_hw->stats.cfm_balance[txhdr->sw_hdr->hw_queue]++; -+ -+ } -+/* -+ printk("mpa_tx_data:ports=0x%02x, start_port=%d, buf=%p, buf_len=%d, pkt_cnt=%d\n", -+ mpa_tx_data.ports, -+ mpa_tx_data.start_port, -+ mpa_tx_data.buf, -+ mpa_tx_data.buf_len, -+ mpa_tx_data.pkt_cnt); -+*/ -+ -+ /*send packet*/ -+ cmd53_port = (bl_hw->plat->io_port | BL_SDIO_MPA_ADDR_BASE | -+ (mpa_tx_data.ports << 4)) + mpa_tx_data.start_port; -+ -+// printk("cmd53_port=0x%08x\n", cmd53_port); -+ -+ ret = bl_write_data_sync(bl_hw, mpa_tx_data.buf, mpa_tx_data.buf_len, cmd53_port); -+ if(ret) -+ printk("bl_write_data_sync failed, ret=%d\n", ret); -+ -+ if(bl_hw->mpa_tx_data.buf) -+ memset(bl_hw->mpa_tx_data.buf, 0, BL_RX_DATA_BUF_SIZE_16K); -+} -+ -+/** -+ * bl_tx_retry - Push an AMPDU pkt that need to be retried -+ * -+ * @bl_hw: Driver main data -+ * @skb: pkt to re-push -+ * @txhdr: tx desc of the pkt to re-push -+ * @sw_retry: Indicates if fw decide to retry this buffer -+ * (i.e. it has never been transmitted over the air) -+ * -+ * Called when a packet needs to be repushed to the firmware. -+ * First update sw descriptor and then queue it in the retry list. -+ */ -+static void bl_tx_retry(struct bl_hw *bl_hw, struct sk_buff *skb, -+ struct bl_txhdr *txhdr, bool sw_retry) -+{ -+ struct bl_sw_txhdr *sw_txhdr = txhdr->sw_hdr; -+ struct tx_cfm_tag *cfm = &txhdr->hw_hdr.cfm; -+ struct bl_txq *txq = sw_txhdr->txq; -+ -+ if (!sw_retry) { -+ /* update sw desc */ -+ sw_txhdr->desc.host.sn = cfm->sn; -+ sw_txhdr->desc.host.pn[0] = cfm->pn[0]; -+ sw_txhdr->desc.host.pn[1] = cfm->pn[1]; -+ sw_txhdr->desc.host.pn[2] = cfm->pn[2]; -+ sw_txhdr->desc.host.pn[3] = cfm->pn[3]; -+ sw_txhdr->desc.host.timestamp = cfm->timestamp; -+ sw_txhdr->desc.host.flags |= TXU_CNTRL_RETRY; -+ -+ #ifdef CONFIG_BL_AMSDUS_TX -+ if (sw_txhdr->desc.host.flags & TXU_CNTRL_AMSDU) -+ bl_hw->stats.amsdus[sw_txhdr->amsdu.nb - 1].failed++; -+ #endif -+ } -+ -+ /* MORE_DATA will be re-set if needed when pkt will be repushed */ -+ sw_txhdr->desc.host.flags &= ~TXU_CNTRL_MORE_DATA; -+ -+ cfm->status.value = 0; -+ -+ BL_DBG("bl_tx_retry: skb=%p, sn=%u\n", skb, sw_txhdr->desc.host.sn); -+ BL_DBG("bl_tx_retry: txq->idx=%d, txq->status=0x%x, txq->credits=%d-->%d\n", txq->idx, txq->status, txq->credits, txq->credits+1); -+ txq->credits++; -+/* -+ spin_lock_bh(&bl_hw->txq_lock); -+ if (txq->credits > 0) -+ bl_txq_start(txq, BL_TXQ_STOP_FULL); -+ spin_unlock_bh(&bl_hw->txq_lock); -+ */ -+ /* Queue the buffer */ -+ bl_txq_queue_skb(skb, txq, bl_hw, true); -+} -+ -+ -+#ifdef CONFIG_BL_AMSDUS_TX -+/* return size of subframe (including header) */ -+static inline int bl_amsdu_subframe_length(struct ethhdr *eth, int eth_len) -+{ -+ /* ethernet header is replaced with amdsu header that have the same size -+ Only need to check if LLC/SNAP header will be added */ -+ int len = eth_len; -+ -+ if (ntohs(eth->h_proto) >= ETH_P_802_3_MIN) { -+ len += sizeof(rfc1042_header) + 2; -+ } -+ -+ return len; -+} -+ -+static inline bool bl_amsdu_is_aggregable(struct sk_buff *skb) -+{ -+ /* need to add some check on buffer to see if it can be aggregated ? */ -+ return true; -+} -+ -+ -+/** -+ * bl_amsdu_del_subframe_header - remove AMSDU header -+ * -+ * amsdu_txhdr: amsdu tx descriptor -+ * -+ * Move back the ethernet header at the "beginning" of the data buffer. -+ * (which has been moved in @bl_amsdu_add_subframe_header) -+ */ -+static void bl_amsdu_del_subframe_header(struct bl_amsdu_txhdr *amsdu_txhdr) -+{ -+ struct sk_buff *skb = amsdu_txhdr->skb; -+ struct ethhdr *eth; -+ u8 *pos; -+ -+ pos = skb->data; -+ pos += sizeof(struct bl_amsdu_txhdr); -+ eth = (struct ethhdr*)pos; -+ pos += amsdu_txhdr->pad + sizeof(struct ethhdr); -+ -+ if (ntohs(eth->h_proto) >= ETH_P_802_3_MIN) { -+ pos += sizeof(rfc1042_header) + 2; -+ } -+ -+ memmove(pos, eth, sizeof(*eth)); -+ skb_pull(skb, (pos - skb->data)); -+} -+ -+/** -+ * bl_amsdu_add_subframe_header - Add AMSDU header and link subframe -+ * -+ * @bl_hw Driver main data -+ * @skb Buffer to aggregate -+ * @sw_txhdr Tx descriptor for the first A-MSDU subframe -+ * -+ * return 0 on sucess, -1 otherwise -+ * -+ * This functions Add A-MSDU header and LLC/SNAP header in the buffer -+ * and update sw_txhdr of the first subframe to link this buffer. -+ * If an error happens, the buffer will be queued as a normal buffer. -+ * -+ * -+ * Before After -+ * +-------------+ +-------------+ -+ * | HEADROOM | | HEADROOM | -+ * | | +-------------+ <- data -+ * | | | amsdu_txhdr | -+ * | | | * pad size | -+ * | | +-------------+ -+ * | | | ETH hdr | keep original eth hdr -+ * | | | | to restore it once transmitted -+ * | | +-------------+ <- packet_addr[x] -+ * | | | Pad | -+ * | | +-------------+ -+ * data -> +-------------+ | AMSDU HDR | -+ * | ETH hdr | +-------------+ -+ * | | | LLC/SNAP | -+ * +-------------+ +-------------+ -+ * | DATA | | DATA | -+ * | | | | -+ * +-------------+ +-------------+ -+ * -+ * Called with tx_lock hold -+ */ -+static int bl_amsdu_add_subframe_header(struct bl_hw *bl_hw, -+ struct sk_buff *skb, -+ struct bl_sw_txhdr *sw_txhdr) -+{ -+ struct bl_amsdu *amsdu = &sw_txhdr->amsdu; -+ struct bl_amsdu_txhdr *amsdu_txhdr; -+ struct ethhdr *amsdu_hdr, *eth = (struct ethhdr *)skb->data; -+ int headroom_need, map_len, msdu_len; -+ dma_addr_t dma_addr; -+ u8 *pos, *map_start; -+ -+ msdu_len = skb->len - sizeof(*eth); -+ headroom_need = sizeof(*amsdu_txhdr) + amsdu->pad + -+ sizeof(*amsdu_hdr); -+ if (ntohs(eth->h_proto) >= ETH_P_802_3_MIN) { -+ headroom_need += sizeof(rfc1042_header) + 2; -+ msdu_len += sizeof(rfc1042_header) + 2; -+ } -+ -+ /* we should have enough headroom (checked in xmit) */ -+ if (WARN_ON(skb_headroom(skb) < headroom_need)) { -+ return -1; -+ } -+ -+ /* allocate headroom */ -+ pos = skb_push(skb, headroom_need); -+ amsdu_txhdr = (struct bl_amsdu_txhdr *)pos; -+ pos += sizeof(*amsdu_txhdr); -+ -+ /* move eth header */ -+ memmove(pos, eth, sizeof(*eth)); -+ eth = (struct ethhdr *)pos; -+ pos += sizeof(*eth); -+ -+ /* Add padding from previous subframe */ -+ map_start = pos; -+ memset(pos, 0, amsdu->pad); -+ pos += amsdu->pad; -+ -+ /* Add AMSDU hdr */ -+ amsdu_hdr = (struct ethhdr *)pos; -+ memcpy(amsdu_hdr->h_dest, eth->h_dest, ETH_ALEN); -+ memcpy(amsdu_hdr->h_source, eth->h_source, ETH_ALEN); -+ amsdu_hdr->h_proto = htons(msdu_len); -+ pos += sizeof(*amsdu_hdr); -+ -+ if (ntohs(eth->h_proto) >= ETH_P_802_3_MIN) { -+ memcpy(pos, rfc1042_header, sizeof(rfc1042_header)); -+ pos += sizeof(rfc1042_header); -+ } -+ -+ /* MAP (and sync) memory for DMA */ -+ map_len = msdu_len + amsdu->pad + sizeof(*amsdu_hdr); -+ dma_addr = dma_map_single(bl_hw->dev, map_start, map_len, -+ DMA_BIDIRECTIONAL); -+ if (WARN_ON(dma_mapping_error(bl_hw->dev, dma_addr))) { -+ pos -= sizeof(*eth); -+ memmove(pos, eth, sizeof(*eth)); -+ skb_pull(skb, headroom_need); -+ return -1; -+ } -+ -+ /* update amdsu_txhdr */ -+ amsdu_txhdr->map_len = map_len; -+ amsdu_txhdr->dma_addr = dma_addr; -+ amsdu_txhdr->skb = skb; -+ amsdu_txhdr->pad = amsdu->pad; -+ -+ /* update bl_sw_txhdr (of the first subframe) */ -+ BUG_ON(amsdu->nb != sw_txhdr->desc.host.packet_cnt); -+ sw_txhdr->desc.host.packet_addr[amsdu->nb] = dma_addr; -+ sw_txhdr->desc.host.packet_len[amsdu->nb] = map_len; -+ sw_txhdr->desc.host.packet_cnt++; -+ amsdu->nb++; -+ -+ amsdu->pad = AMSDU_PADDING(map_len - amsdu->pad); -+ list_add_tail(&amsdu_txhdr->list, &amsdu->hdrs); -+ amsdu->len += map_len; -+ -+ trace_amsdu_subframe(sw_txhdr); -+ return 0; -+} -+ -+/** -+ * bl_amsdu_add_subframe - Add this buffer as an A-MSDU subframe if possible -+ * -+ * @bl_hw Driver main data -+ * @skb Buffer to aggregate if possible -+ * @sta Destination STA -+ * @txq sta's txq used for this buffer -+ * -+ * Tyr to aggregate the buffer in an A-MSDU. If it succeed then the -+ * buffer is added as a new A-MSDU subframe with AMSDU and LLC/SNAP -+ * headers added (so FW won't have to modify this subframe). -+ * -+ * To be added as subframe : -+ * - sta must allow amsdu -+ * - buffer must be aggregable (to be defined) -+ * - at least one other aggregable buffer is pending in the queue -+ * or an a-msdu (with enough free space) is currently in progress -+ * -+ * returns true if buffer has been added as A-MDSP subframe, false otherwise -+ * -+ */ -+static bool bl_amsdu_add_subframe(struct bl_hw *bl_hw, struct sk_buff *skb, -+ struct bl_sta *sta, struct bl_txq *txq) -+{ -+ bool res = false; -+ struct ethhdr *eth; -+ -+ /* immedialtely return if amsdu are not allowed for this sta */ -+ if (!txq->amsdu_len || bl_hw->mod_params->amsdu_maxnb < 2 || -+ !bl_amsdu_is_aggregable(skb)) -+ return false; -+ -+ spin_lock_bh(&bl_hw->tx_lock); -+ if (txq->amsdu) { -+ /* aggreagation already in progress, add this buffer if enough space -+ available, otherwise end the current amsdu */ -+ struct bl_sw_txhdr *sw_txhdr = txq->amsdu; -+ eth = (struct ethhdr *)(skb->data); -+ -+ if (((sw_txhdr->amsdu.len + sw_txhdr->amsdu.pad + -+ bl_amsdu_subframe_length(eth, skb->len)) > txq->amsdu_len) || -+ bl_amsdu_add_subframe_header(bl_hw, skb, sw_txhdr)) { -+ txq->amsdu = NULL; -+ goto end; -+ } -+ -+ if (sw_txhdr->amsdu.nb >= bl_hw->mod_params->amsdu_maxnb) { -+ bl_hw->stats.amsdus[sw_txhdr->amsdu.nb - 1].done++; -+ /* max number of subframes reached */ -+ txq->amsdu = NULL; -+ } -+ } else { -+ /* Check if a new amsdu can be started with the previous buffer -+ (if any) and this one */ -+ struct sk_buff *skb_prev = skb_peek_tail(&txq->sk_list); -+ struct bl_txhdr *txhdr; -+ struct bl_sw_txhdr *sw_txhdr; -+ int len1, len2; -+ -+ if (!skb_prev || !bl_amsdu_is_aggregable(skb_prev)) -+ goto end; -+ -+ txhdr = (struct bl_txhdr *)skb_prev->data; -+ sw_txhdr = txhdr->sw_hdr; -+ if ((sw_txhdr->amsdu.len) || -+ (sw_txhdr->desc.host.flags & TXU_CNTRL_RETRY)) -+ /* previous buffer is already a complete amsdu or a retry */ -+ goto end; -+ -+ eth = (struct ethhdr *)(skb_prev->data + sw_txhdr->headroom); -+ len1 = bl_amsdu_subframe_length(eth, (sw_txhdr->frame_len + -+ sizeof(struct ethhdr))); -+ -+ eth = (struct ethhdr *)(skb->data); -+ len2 = bl_amsdu_subframe_length(eth, skb->len); -+ -+ if (len1 + AMSDU_PADDING(len1) + len2 > txq->amsdu_len) -+ /* not enough space to aggregate those two buffers */ -+ goto end; -+ -+ /* Add subframe header. -+ Note: Fw will take care of adding AMDSU header for the first -+ subframe while generating 802.11 MAC header */ -+ INIT_LIST_HEAD(&sw_txhdr->amsdu.hdrs); -+ sw_txhdr->amsdu.len = len1; -+ sw_txhdr->amsdu.nb = 1; -+ sw_txhdr->amsdu.pad = AMSDU_PADDING(len1); -+ if (bl_amsdu_add_subframe_header(bl_hw, skb, sw_txhdr)) -+ goto end; -+ -+ sw_txhdr->desc.host.flags |= TXU_CNTRL_AMSDU; -+ -+ if (sw_txhdr->amsdu.nb < bl_hw->mod_params->amsdu_maxnb) -+ txq->amsdu = sw_txhdr; -+ else -+ bl_hw->stats.amsdus[sw_txhdr->amsdu.nb - 1].done++; -+ } -+ -+ res = true; -+ -+ end: -+ spin_unlock_bh(&bl_hw->tx_lock); -+ return res; -+} -+#endif /* CONFIG_BL_AMSDUS_TX */ -+ -+int bl_requeue_multicast_skb(struct sk_buff *skb, struct bl_vif *bl_vif) -+{ -+ struct bl_hw *bl_hw = bl_vif->bl_hw; -+ struct bl_txhdr *txhdr; -+ struct bl_sw_txhdr *sw_txhdr; -+ struct ethhdr *eth; -+ struct ethhdr tmp_eth; -+ struct txdesc_api *desc; -+ struct bl_sta *sta; -+ struct bl_txq *txq; -+ int headroom; -+ int hdr_pads; -+ -+ u16 frame_len; -+ u16 frame_oft; -+ u8 tid; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ BL_DBG("1111bl_requeue_multicast_skb: skb=%p, skb->priority=%d\n", skb, skb->priority); -+ -+ /* Get the STA id and TID information */ -+ sta = bl_get_tx_info(bl_vif, skb, &tid); -+ if (!sta) -+ goto free; -+ -+ txq = bl_txq_sta_get(sta, tid, NULL, bl_hw); -+ -+ BL_DBG("requeue: txq->idx=%d, txq->status=%d, txq->ndev_idx=%d\n", txq->idx, txq->status, txq->ndev_idx); -+ -+#ifdef CONFIG_BL_AMSDUS_TX -+ if (bl_amsdu_add_subframe(bl_hw, skb, sta, txq)) -+ return NETDEV_TX_OK; -+#endif -+ -+ /* Retrieve the pointer to the Ethernet data */ -+ eth = (struct ethhdr *)skb->data; -+ memcpy(tmp_eth.h_dest, eth->h_dest, ETH_ALEN); -+ memcpy(tmp_eth.h_source, eth->h_source, ETH_ALEN); -+ tmp_eth.h_proto = eth->h_proto; -+ hdr_pads = sizeof(struct ethhdr); -+ headroom = sizeof(struct bl_txhdr); -+ -+ /* first we increase the area for tx descriptor */ -+ skb_push(skb, sizeof(struct txdesc_api)); -+ /* then we increase the area for sdio header*/ -+ skb_push(skb, sizeof(struct sdio_hdr)); -+ /* then we increase the area for tx header */ -+ skb_push(skb, headroom); -+ -+ txhdr = (struct bl_txhdr *)skb->data; -+ sw_txhdr = kmem_cache_alloc(bl_hw->sw_txhdr_cache, GFP_ATOMIC); -+ if (unlikely(sw_txhdr == NULL)) -+ goto free; -+ txhdr->sw_hdr = sw_txhdr; -+ desc = &sw_txhdr->desc; -+ -+ /* the frame len contains sdio special and actual skb->data */ -+ frame_len = (u16)skb->len - headroom - sizeof(struct sdio_hdr)-sizeof(struct txdesc_api); -+ -+ sw_txhdr->hdr.type = BL_TYPE_DATA; -+ sw_txhdr->hdr.len = frame_len + sizeof(struct txdesc_api); -+ sw_txhdr->hdr.queue_idx = txq->hwq->id; -+ sw_txhdr->hdr.reserved = 0x0; -+ -+ sw_txhdr->txq = txq; -+ sw_txhdr->frame_len = frame_len; -+ sw_txhdr->bl_sta = sta; -+ sw_txhdr->bl_vif = bl_vif; -+ sw_txhdr->skb = skb; -+ sw_txhdr->headroom = headroom; -+ sw_txhdr->map_len = skb->len - offsetof(struct bl_txhdr, hw_hdr); -+ -+#ifdef CONFIG_BL_AMSDUS_TX -+ sw_txhdr->amsdu.len = 0; -+ sw_txhdr->amsdu.nb = 0; -+#endif -+ // Fill-in the descriptor -+ memcpy(&desc->host.eth_dest_addr, tmp_eth.h_dest, ETH_ALEN); -+ memcpy(&desc->host.eth_src_addr, tmp_eth.h_source, ETH_ALEN); -+ desc->host.ethertype = tmp_eth.h_proto; -+ BL_DBG("dest_addr:%04x%04x%04x\n", desc->host.eth_dest_addr.array[0], desc->host.eth_dest_addr.array[1], desc->host.eth_dest_addr.array[2]); -+ BL_DBG("src_addr:%04x%04x%04x\n", desc->host.eth_src_addr.array[0], desc->host.eth_src_addr.array[1], desc->host.eth_src_addr.array[2]); -+ BL_DBG("desc->host.ethertype=0x%x\n", desc->host.ethertype); -+ desc->host.staid = sta->sta_idx; -+ desc->host.tid = tid; -+ desc->host.host_hdr_pads = hdr_pads; -+ if (unlikely(bl_vif->wdev.iftype == NL80211_IFTYPE_AP_VLAN)) { -+ desc->host.vif_idx = bl_vif->ap_vlan.master->vif_index; -+ } else { -+ desc->host.vif_idx = bl_vif->vif_index; -+ } -+ -+ if (bl_vif->use_4addr && (sta->sta_idx < NX_REMOTE_STA_MAX)) -+ desc->host.flags = TXU_CNTRL_USE_4ADDR; -+ else -+ desc->host.flags = 0; -+ -+ if (bl_vif->wdev.iftype == NL80211_IFTYPE_MESH_POINT) { -+ if (bl_vif->is_resending) { -+ desc->host.flags |= TXU_CNTRL_MESH_FWD; -+ } -+ } -+ -+#ifdef CONFIG_BL_SPLIT_TX_BUF -+ desc->host.packet_len[0] = frame_len; -+#else -+ desc->host.packet_len = frame_len; -+#endif -+ -+ txhdr->hw_hdr.cfm.status.value = 0; -+ -+ /* Fill-in TX descriptor */ -+ frame_oft = sizeof(struct bl_txhdr) - offsetof(struct bl_txhdr, hw_hdr) -+ + sizeof(*eth); -+#ifdef CONFIG_BL_SPLIT_TX_BUF -+ desc->host.packet_addr[0] = sw_txhdr->dma_addr + frame_oft; -+ desc->host.packet_cnt = 1; -+#else -+ desc->host.packet_addr = sw_txhdr->dma_addr + frame_oft; -+#endif -+ //desc->host.status_desc_addr = sw_txhdr->dma_addr; -+ -+ BL_DBG("requeue total length[%lu], sdio_txdesc[%lu], payload[%u]\n", frame_len+sizeof(struct sdio_hdr)+sizeof(struct txdesc_api), sizeof(struct sdio_hdr)+sizeof(struct txdesc_api), frame_len); -+ BL_DBG("requeue sdio_hdr: [%04x %04x %04x %04x]\n", sw_txhdr->hdr.type, sw_txhdr->hdr.len, sw_txhdr->hdr.queue_idx, sw_txhdr->hdr.reserved); -+ BL_DBG("txdesc: %08x%08x%04x%08x%04x%04x%04x%04x%04x%04x%04x%04x%04x%04x%04x%04x%04x%02x%02x%02x%04x\n", \ -+ desc->ready, desc->host.packet_addr, desc->host.packet_len, desc->host.host_hdr_pads, desc->host.eth_dest_addr.array[0], desc->host.eth_dest_addr.array[1], desc->host.eth_dest_addr.array[2], \ -+ desc->host.eth_src_addr.array[0], desc->host.eth_src_addr.array[1], desc->host.eth_src_addr.array[2],desc->host.ethertype, desc->host.pn[0], desc->host.pn[1], desc->host.pn[2], desc->host.pn[3], \ -+ desc->host.sn, desc->host.timestamp, desc->host.tid, desc->host.vif_idx, desc->host.staid, desc->host.flags); -+ BL_DBG("requeue sw_txhdr: frame_len[%04x], headroom[%04x]\n", sw_txhdr->frame_len,sw_txhdr->headroom); -+ BL_DBG("requeue hw_txhdr: staid[%02x]vif_idx[%02x]tid[%02x]flags[%04x]\n", desc->host.staid, desc->host.vif_idx, desc->host.tid, desc->host.flags); -+ BL_DBG("requeue skb=%p\n", skb); -+ spin_lock_bh(&bl_hw->txq_lock); -+ if (bl_txq_queue_skb(skb, txq, bl_hw, false)) { -+ BL_DBG("rwqueue multicast_skb success!\n"); -+ spin_unlock_bh(&bl_hw->txq_lock); -+ //bl_queue_main_work(bl_hw); -+ } else { -+ BL_DBG("rwqueue multicast_skb success failed"); -+ spin_unlock_bh(&bl_hw->txq_lock); -+ return NETDEV_TX_OK; -+ } -+ -+ return NETDEV_TX_OK; -+ -+free: -+ dev_kfree_skb_any(skb); -+ -+ return NETDEV_TX_OK; -+} -+ -+/** -+ * netdev_tx_t (*ndo_start_xmit)(struct sk_buff *skb, -+ * struct net_device *dev); -+ * Called when a packet needs to be transmitted. -+ * Must return NETDEV_TX_OK , NETDEV_TX_BUSY. -+ * (can also return NETDEV_TX_LOCKED if NETIF_F_LLTX) -+ * -+ * - Initialize the desciptor for this pkt (stored in skb before data) -+ * - Push the pkt in the corresponding Txq -+ * - If possible (i.e. credit available and not in PS) the pkt is pushed -+ * to fw -+ */ -+netdev_tx_t bl_start_xmit(struct sk_buff *skb, struct net_device *dev) -+{ -+ struct bl_vif *bl_vif = netdev_priv(dev); -+ struct bl_hw *bl_hw = bl_vif->bl_hw; -+ struct bl_txhdr *txhdr; -+ struct bl_sw_txhdr *sw_txhdr; -+ struct ethhdr *eth; -+ struct ethhdr tmp_eth; -+ struct txdesc_api *desc; -+ struct bl_sta *sta; -+ struct bl_txq *txq; -+ int headroom; -+ int max_headroom; -+ int hdr_pads; -+ -+ u16 frame_len; -+ u16 frame_oft; -+ u8 tid; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ max_headroom = sizeof(struct bl_txhdr)+sizeof(struct txdesc_api) + sizeof(struct sdio_hdr); -+ -+ /* check whether the current skb can be used */ -+ if (skb_shared(skb) || (skb_headroom(skb) < max_headroom)) { -+ struct sk_buff *newskb = skb_copy_expand(skb, max_headroom, 0, -+ GFP_ATOMIC); -+ if (unlikely(newskb == NULL)) -+ goto free; -+ -+ dev_kfree_skb_any(skb); -+ -+ skb = newskb; -+ } -+ -+ /* Get the STA id and TID information */ -+ sta = bl_get_tx_info(bl_vif, skb, &tid); -+ if (!sta) -+ goto free; -+ -+ txq = bl_txq_sta_get(sta, tid, NULL, bl_hw); -+ -+#ifdef CONFIG_BL_AMSDUS_TX -+ if (bl_amsdu_add_subframe(bl_hw, skb, sta, txq)) -+ return NETDEV_TX_OK; -+#endif -+ -+ /* Retrieve the pointer to the Ethernet data */ -+ eth = (struct ethhdr *)skb->data; -+ memcpy(tmp_eth.h_dest, eth->h_dest, ETH_ALEN); -+ memcpy(tmp_eth.h_source, eth->h_source, ETH_ALEN); -+ tmp_eth.h_proto = eth->h_proto; -+ -+ hdr_pads = sizeof(struct ethhdr); -+ headroom = sizeof(struct bl_txhdr); -+ -+ /* first we increase the area for tx descriptor */ -+ skb_push(skb, sizeof(struct txdesc_api)); -+ /* then we increase the area for sdio header*/ -+ skb_push(skb, sizeof(struct sdio_hdr)); -+ /* then we increase the area for tx header */ -+ skb_push(skb, headroom); -+ -+ txhdr = (struct bl_txhdr *)skb->data; -+ sw_txhdr = kmem_cache_alloc(bl_hw->sw_txhdr_cache, GFP_ATOMIC); -+ if (unlikely(sw_txhdr == NULL)) -+ goto free; -+ txhdr->sw_hdr = sw_txhdr; -+ desc = &sw_txhdr->desc; -+ -+ /* the frame len contains sdio special and actual skb->data */ -+ frame_len = (u16)skb->len - headroom - sizeof(struct sdio_hdr)-sizeof(struct txdesc_api) - hdr_pads; -+ -+ sw_txhdr->hdr.type = BL_TYPE_DATA; -+ sw_txhdr->hdr.len = skb->len - headroom; -+ sw_txhdr->hdr.queue_idx = txq->hwq->id; -+ sw_txhdr->hdr.reserved = g_pkt_sn; -+ -+ BL_DBG("xmit_pkt_sn: hw_idx=%d, frame_len=%u, sn=%u\n",txq->hwq->id, frame_len, g_pkt_sn); -+ g_pkt_sn++; -+ -+ sw_txhdr->txq = txq; -+ sw_txhdr->frame_len = frame_len; -+ sw_txhdr->bl_sta = sta; -+ sw_txhdr->bl_vif = bl_vif; -+ sw_txhdr->skb = skb; -+ sw_txhdr->headroom = headroom; -+ sw_txhdr->map_len = skb->len - offsetof(struct bl_txhdr, hw_hdr); -+ -+#ifdef CONFIG_BL_AMSDUS_TX -+ sw_txhdr->amsdu.len = 0; -+ sw_txhdr->amsdu.nb = 0; -+#endif -+ // Fill-in the descriptor -+ memcpy(&desc->host.eth_dest_addr, tmp_eth.h_dest, ETH_ALEN); -+ memcpy(&desc->host.eth_src_addr, tmp_eth.h_source, ETH_ALEN); -+ desc->host.ethertype = tmp_eth.h_proto; -+ desc->host.staid = sta->sta_idx; -+ desc->host.tid = tid; -+ desc->host.host_hdr_pads = hdr_pads; -+ if (unlikely(bl_vif->wdev.iftype == NL80211_IFTYPE_AP_VLAN)) { -+ desc->host.vif_idx = bl_vif->ap_vlan.master->vif_index; -+ } else { -+ desc->host.vif_idx = bl_vif->vif_index; -+ } -+ -+ if (bl_vif->use_4addr && (sta->sta_idx < NX_REMOTE_STA_MAX)) -+ desc->host.flags = TXU_CNTRL_USE_4ADDR; -+ else -+ desc->host.flags = 0; -+ -+#ifdef CONFIG_BL_SPLIT_TX_BUF -+ desc->host.packet_len[0] = frame_len; -+#else -+ desc->host.packet_len = frame_len; -+#endif -+ -+ txhdr->hw_hdr.cfm.status.value = 0; -+ -+ /* Fill-in TX descriptor */ -+ frame_oft = sizeof(struct bl_txhdr) - offsetof(struct bl_txhdr, hw_hdr) + sizeof(*eth); -+#ifdef CONFIG_BL_SPLIT_TX_BUF -+ desc->host.packet_addr[0] = sw_txhdr->dma_addr + frame_oft; -+ desc->host.packet_cnt = 1; -+#else -+ desc->host.packet_addr = sw_txhdr->dma_addr + frame_oft; -+#endif -+ -+ BL_DBG_MOD_LEVEL(bl_hw, D_TX D_INF "bl_start_xmit: queue skb=%p on hwq->idx=%d, txq->idx=%d\n", skb, sw_txhdr->hdr.queue_idx, txq->idx); -+ -+ spin_lock_bh(&bl_hw->txq_lock); -+ if (bl_txq_queue_skb(skb, txq, bl_hw, false)) { -+ BL_DBG("start_xmit: queue_skb success!\n"); -+ bl_queue_main_work(bl_hw); -+ spin_unlock_bh(&bl_hw->txq_lock); -+ } else { -+ /*when in ps mode, it just add skb into txq, but donot add txq in hwq*/ -+ BL_DBG("start_xmit: queue_skb success failed"); -+ spin_unlock_bh(&bl_hw->txq_lock); -+ return NETDEV_TX_OK; -+ } -+ -+ return NETDEV_TX_OK; -+ -+free: -+ dev_kfree_skb_any(skb); -+ -+ return NETDEV_TX_OK; -+} -+ -+/** -+ * bl_start_mgmt_xmit - Transmit a management frame -+ * -+ * @vif: Vif that send the frame -+ * @sta: Destination of the frame. May be NULL if the destiantion is unknown -+ * to the AP. -+ * @params: Mgmt frame parameters -+ * @offchan: Indicate whether the frame must be send via the offchan TXQ. -+ * (is is redundant with params->offchan ?) -+ * @cookie: updated with a unique value to identify the frame with upper layer -+ * -+ */ -+int bl_start_mgmt_xmit(struct bl_vif *vif, struct bl_sta *sta, -+ struct cfg80211_mgmt_tx_params *params, bool offchan, -+ u64 *cookie) -+{ -+ struct bl_hw *bl_hw = vif->bl_hw; -+ struct bl_txhdr *txhdr; -+ struct bl_sw_txhdr *sw_txhdr; -+ struct txdesc_api *desc; -+ struct sk_buff *skb; -+ u16 frame_len, headroom, frame_oft; -+ u8 *data; -+ struct bl_txq *txq; -+ bool robust; -+ int i; -+ int hdr_pads; -+ -+ BL_DBG(BL_FN_ENTRY_STR); -+ -+ headroom = sizeof(struct bl_txhdr) + sizeof(struct txdesc_api) + sizeof(struct sdio_hdr); -+ frame_len = params->len; -+ -+ /* Set TID and Queues indexes */ -+ if (sta) { -+ txq = bl_txq_sta_get(sta, 8, NULL, bl_hw); -+ } else { -+ if (offchan) { -+ txq = &bl_hw->txq[NX_OFF_CHAN_TXQ_IDX]; -+ } else { -+ txq = bl_txq_vif_get(vif, NX_UNK_TXQ_TYPE, NULL); -+ } -+ } -+ -+ /* Ensure that TXQ is active */ -+ if (txq->idx == TXQ_INACTIVE) { -+ netdev_dbg(vif->ndev, "TXQ inactive\n"); -+ return -EBUSY; -+ } -+ -+ /* Create a SK Buff object that will contain the provided data */ -+ skb = dev_alloc_skb(headroom + frame_len); -+ if (!skb) { -+ return -ENOMEM; -+ } -+ -+ -+ *cookie = (unsigned long)skb; -+ -+ /* -+ * Move skb->data pointer in order to reserve room for bl_txhdr -+ * headroom value will be equal to sizeof(struct bl_txhdr) -+ */ -+ skb_reserve(skb, headroom); -+ -+ /* -+ * Extend the buffer data area in order to contain the provided packet -+ * len value (for skb) will be equal to param->len -+ */ -+ data = skb_put(skb, frame_len); -+ /* Copy the provided data */ -+ memcpy(data, params->buf, frame_len); -+ robust = ieee80211_is_robust_mgmt_frame(skb); -+ -+ /* Update CSA counter if present */ -+ if (unlikely(params->n_csa_offsets) && -+ vif->wdev.iftype == NL80211_IFTYPE_AP && -+ vif->ap.csa) { -+ data = skb->data; -+ for (i = 0; i < params->n_csa_offsets ; i++) { -+ data[params->csa_offsets[i]] = vif->ap.csa->count; -+ } -+ } -+ -+ hdr_pads = BL_SWTXHDR_ALIGN_PADS((long)(skb->data)-sizeof(struct txdesc_api)-sizeof(struct sdio_hdr)); -+ -+ /* -+ * Go back to the beginning of the allocated data area -+ * skb->data pointer will move backward -+ */ -+ skb_push(skb, hdr_pads); -+ /* first we increase the area for tx descriptor */ -+ skb_push(skb, sizeof(struct txdesc_api)); -+ /* then we increase the area for sdio header*/ -+ skb_push(skb, sizeof(struct sdio_hdr)); -+ /* then we increase the area for tx header */ -+ skb_push(skb, headroom); -+ -+ /* Fill the TX Header */ -+ txhdr = (struct bl_txhdr *)skb->data; -+ txhdr->hw_hdr.cfm.status.value = 0; -+ -+ /* Fill the SW TX Header */ -+ sw_txhdr = kmem_cache_alloc(bl_hw->sw_txhdr_cache, GFP_ATOMIC); -+ if (unlikely(sw_txhdr == NULL)) { -+ dev_kfree_skb(skb); -+ return -ENOMEM; -+ } -+ txhdr->sw_hdr = sw_txhdr; -+ -+ sw_txhdr->hdr.type = BL_TYPE_DATA; -+ sw_txhdr->hdr.len = frame_len + sizeof(struct txdesc_api); -+ sw_txhdr->hdr.queue_idx = txq->hwq->id; -+ sw_txhdr->hdr.reserved = g_pkt_sn; -+ -+ BL_DBG("xmit_pkt_sn: hw_idx=%d, frame_len=%u, sn=%u\n",txq->hwq->id, frame_len, g_pkt_sn); -+ g_pkt_sn++; -+ -+ sw_txhdr->txq = txq; -+ sw_txhdr->frame_len = frame_len; -+ sw_txhdr->bl_sta = sta; -+ sw_txhdr->bl_vif = vif; -+ sw_txhdr->skb = skb; -+ sw_txhdr->headroom = headroom; -+ sw_txhdr->map_len = skb->len - offsetof(struct bl_txhdr, hw_hdr); -+#ifdef CONFIG_BL_AMSDUS_TX -+ sw_txhdr->amsdu.len = 0; -+ sw_txhdr->amsdu.nb = 0; -+#endif -+ -+ /* Fill the Descriptor to be provided to the MAC SW */ -+ desc = &sw_txhdr->desc; -+ -+ desc->host.staid = (sta) ? sta->sta_idx : 0xFF; -+ desc->host.vif_idx = vif->vif_index; -+ desc->host.tid = 0xFF; -+ desc->host.host_hdr_pads = hdr_pads; -+ desc->host.flags = TXU_CNTRL_MGMT; -+ if (robust) -+ desc->host.flags |= TXU_CNTRL_MGMT_ROBUST; -+ -+#ifdef CONFIG_BL_SPLIT_TX_BUF -+ desc->host.packet_len[0] = frame_len; -+#else -+ desc->host.packet_len = frame_len; -+#endif -+ -+ if (params->no_cck) { -+ desc->host.flags |= TXU_CNTRL_MGMT_NO_CCK; -+ } -+ -+ frame_oft = sizeof(struct bl_txhdr) - offsetof(struct bl_txhdr, hw_hdr); -+#ifdef CONFIG_BL_SPLIT_TX_BUF -+ desc->host.packet_addr[0] = sw_txhdr->dma_addr + frame_oft; -+ desc->host.packet_cnt = 1; -+#else -+ desc->host.packet_addr = sw_txhdr->dma_addr + frame_oft; -+#endif -+ -+ BL_DBG("mgmt_xmit: queue_skb=%p\n", skb); -+ spin_lock_bh(&bl_hw->txq_lock); -+ if (bl_txq_queue_skb(skb, txq, bl_hw, false)) { -+ BL_DBG("mgmt_xmit: queue_skb success!\n"); -+ bl_queue_main_work(bl_hw); -+ spin_unlock_bh(&bl_hw->txq_lock); -+ } else { -+ /*when in ps mode, it just add skb into txq, but donot add txq in hwq*/ -+ BL_DBG("mgmt_xmit: queue_skb success failed"); -+ spin_unlock_bh(&bl_hw->txq_lock); -+ return NETDEV_TX_OK; -+ } -+ -+ return 0; -+} -+ -+/** -+ * bl_txdatacfm - FW callback for TX confirmation -+ * -+ * called with tx_lock hold -+ */ -+int bl_txdatacfm(void *pthis, void *host_id, void *_hw_hdr, void **txq_saved) -+{ -+ struct bl_hw *bl_hw = (struct bl_hw *)pthis; -+ struct bl_hw_txhdr *hw_hdr = (struct bl_hw_txhdr *)_hw_hdr; -+ struct sk_buff *skb = host_id; -+ struct bl_txhdr *txhdr; -+ union bl_hw_txstatus bl_txst; -+ struct bl_sw_txhdr *sw_txhdr; -+ struct bl_hwq *hwq; -+ struct bl_txq *txq; -+ -+ txhdr = (struct bl_txhdr *)skb->data; -+ sw_txhdr = txhdr->sw_hdr; -+ bl_txst = hw_hdr->cfm.status; -+ -+ memcpy(&txhdr->hw_hdr, hw_hdr, sizeof(struct bl_hw_txhdr)); -+ -+ txq = sw_txhdr->txq; -+ *txq_saved = txq; -+ /* don't use txq->hwq as it may have changed between push and confirm */ -+ hwq = &bl_hw->hwq[sw_txhdr->hw_queue]; -+ if(hwq == NULL) { -+ printk("bl_txdatacfm: hwq is NULL!\n"); -+ return -1; -+ } -+ -+ bl_txq_confirm_any(bl_hw, txq, hwq, sw_txhdr); -+ -+ /* Update txq and HW queue credits */ -+ if (sw_txhdr->desc.host.flags & TXU_CNTRL_MGMT) { -+ /* For debug purpose (use ftrace kernel option) */ -+ trace_mgmt_cfm(sw_txhdr->bl_vif->vif_index, -+ (sw_txhdr->bl_sta) ? sw_txhdr->bl_sta->sta_idx : 0xFF, -+ !(bl_txst.retry_required || bl_txst.sw_retry_required)); -+ -+ /* Confirm transmission to CFG80211 */ -+ cfg80211_mgmt_tx_status(&sw_txhdr->bl_vif->wdev, -+ (unsigned long)skb, -+ (skb->data + sw_txhdr->headroom + sizeof(struct txdesc_api) + sizeof(struct sdio_hdr)), -+ sw_txhdr->frame_len, -+ !(bl_txst.retry_required || bl_txst.sw_retry_required), -+ GFP_ATOMIC); -+ } else if ((txq->idx != TXQ_INACTIVE) && -+ (bl_txst.retry_required || bl_txst.sw_retry_required)) { -+ bool sw_retry = (bl_txst.sw_retry_required) ? true : false; -+ -+ /* Reset the status */ -+ txhdr->hw_hdr.cfm.status.value = 0; -+ -+ /* The confirmed packet was part of an AMPDU and not acked -+ * correctly, so reinject it in the TX path to be retried */ -+ bl_tx_retry(bl_hw, skb, txhdr, sw_retry); -+ return 0; -+ } -+ -+ /* Update statistics */ -+ sw_txhdr->bl_vif->net_stats.tx_packets++; -+ sw_txhdr->bl_vif->net_stats.tx_bytes += sw_txhdr->frame_len; -+ -+ /* Release SKBs */ -+#ifdef CONFIG_BL_AMSDUS_TX -+ if (sw_txhdr->desc.host.flags & TXU_CNTRL_AMSDU) { -+ struct bl_amsdu_txhdr *amsdu_txhdr; -+ list_for_each_entry(amsdu_txhdr, &sw_txhdr->amsdu.hdrs, list) { -+ bl_amsdu_del_subframe_header(amsdu_txhdr); -+ dma_unmap_single(bl_hw->dev, amsdu_txhdr->dma_addr, -+ amsdu_txhdr->map_len, DMA_TO_DEVICE); -+ consume_skb(amsdu_txhdr->skb); -+ } -+ } -+#endif /* CONFIG_BL_AMSDUS_TX */ -+ -+ kmem_cache_free(bl_hw->sw_txhdr_cache, sw_txhdr); -+ skb_pull(skb, sw_txhdr->headroom); -+ BL_DBG("txdata_cfm, free skb=%p, sn=%u\n", skb, hw_hdr->cfm.sn); -+ consume_skb(skb); -+ -+ return 0; -+} -+ -+/** -+ * bl_txq_credit_update - Update credit for one txq -+ * -+ * @bl_hw: Driver main data -+ * @sta_idx: STA idx -+ * @tid: TID -+ * @update: offset to apply in txq credits -+ * -+ * Called when fw send ME_TX_CREDITS_UPDATE_IND message. -+ * Apply @update to txq credits, and stop/start the txq if needed -+ */ -+void bl_txq_credit_update(struct bl_hw *bl_hw, int sta_idx, u8 tid, -+ s8 update) -+{ -+ struct bl_sta *sta = &bl_hw->sta_table[sta_idx]; -+ struct bl_txq *txq; -+ -+ txq = bl_txq_sta_get(sta, tid, NULL, bl_hw); -+ -+ spin_lock(&bl_hw->tx_lock); -+ -+ if (txq->idx != TXQ_INACTIVE) { -+ txq->credits += update; -+ trace_credit_update(txq, update); -+ /* if (txq->credits <= 0) -+ bl_txq_stop(txq, BL_TXQ_STOP_FULL); -+ else -+ bl_txq_start(txq, BL_TXQ_STOP_FULL);*/ -+ } -+ -+ spin_unlock(&bl_hw->tx_lock); -+} -diff -Naur /dev/null/bl_tx.h b/drivers/net/wireless/hflps170/fullmac/bl_tx.h ---- /dev/null/bl_tx.h 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/fullmac/bl_tx.h 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,177 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file bl_tx.h -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ ****************************************************************************** -+ */ -+#ifndef _BL_TX_H_ -+#define _BL_TX_H_ -+ -+#include -+#include -+#include -+#include -+#include "lmac_types.h" -+#include "lmac_msg.h" -+#include "ipc_shared.h" -+#include "bl_txq.h" -+#include "hal_desc.h" -+ -+#define BL_HWQ_BK 0 -+#define BL_HWQ_BE 1 -+#define BL_HWQ_VI 2 -+#define BL_HWQ_VO 3 -+#define BL_HWQ_BCMC 4 -+#define BL_HWQ_NB NX_TXQ_CNT -+#define BL_HWQ_ALL_ACS (BL_HWQ_BK | BL_HWQ_BE | BL_HWQ_VI | BL_HWQ_VO) -+#define BL_HWQ_ALL_ACS_BIT ( BIT(BL_HWQ_BK) | BIT(BL_HWQ_BE) | \ -+ BIT(BL_HWQ_VI) | BIT(BL_HWQ_VO) ) -+ -+#define BL_TX_LIFETIME_MS 100 -+ -+#define BL_SWTXHDR_ALIGN_SZ 4 -+#define BL_SWTXHDR_ALIGN_MSK (BL_SWTXHDR_ALIGN_SZ - 1) -+#define BL_SWTXHDR_ALIGN_PADS(x) \ -+ ((BL_SWTXHDR_ALIGN_SZ - ((x) & BL_SWTXHDR_ALIGN_MSK)) \ -+ & BL_SWTXHDR_ALIGN_MSK) -+#if BL_SWTXHDR_ALIGN_SZ & BL_SWTXHDR_ALIGN_MSK -+#error bad BL_SWTXHDR_ALIGN_SZ -+#endif -+ -+#define AMSDU_PADDING(x) ((4 - ((x) & 0x3)) & 0x3) -+ -+#define TXU_CNTRL_RETRY BIT(0) -+#define TXU_CNTRL_MORE_DATA BIT(2) -+#define TXU_CNTRL_MGMT BIT(3) -+#define TXU_CNTRL_MGMT_NO_CCK BIT(4) -+#define TXU_CNTRL_AMSDU BIT(6) -+#define TXU_CNTRL_MGMT_ROBUST BIT(7) -+#define TXU_CNTRL_USE_4ADDR BIT(8) -+#define TXU_CNTRL_EOSP BIT(9) -+#define TXU_CNTRL_MESH_FWD BIT(10) -+#define TXU_CNTRL_TDLS BIT(11) -+ -+extern const int bl_tid2hwq[IEEE80211_NUM_TIDS]; -+ -+/** -+ * struct bl_amsdu_txhdr - Structure added in skb headroom (instead of -+ * bl_txhdr) for amsdu subframe buffer (except for the first subframe -+ * that has a normal bl_txhdr) -+ * -+ * @list List of other amsdu subframe (bl_sw_txhdr.amsdu.hdrs) -+ * @map_len Length to be downloaded for this subframe -+ * @dma_addr Buffer address form embedded point of view -+ * @skb skb -+ * @pad padding added before this subframe -+ * (only use when amsdu must be dismantled) -+ */ -+struct bl_amsdu_txhdr { -+ struct list_head list; -+ size_t map_len; -+ dma_addr_t dma_addr; -+ struct sk_buff *skb; -+ u16 pad; -+}; -+ -+/** -+ * struct bl_amsdu - Structure to manage creation of an A-MSDU, updated -+ * only In the first subframe of an A-MSDU -+ * -+ * @hdrs List of subframe of bl_amsdu_txhdr -+ * @len Current size for this A-MDSU (doesn't take padding into account) -+ * 0 means that no amsdu is in progress -+ * @nb Number of subframe in the amsdu -+ * @pad Padding to add before adding a new subframe -+ */ -+struct bl_amsdu { -+ struct list_head hdrs; -+ u16 len; -+ u8 nb; -+ u8 pad; -+}; -+ -+/** -+ * struct bl_sw_txhdr - Software part of tx header -+ * -+ * @bl_sta sta to which this buffer is addressed -+ * @bl_vif vif that send the buffer -+ * @txq pointer to TXQ used to send the buffer -+ * @hw_queue Index of the HWQ used to push the buffer. -+ * May be different than txq->hwq->id on confirmation. -+ * @frame_len Size of the frame (doesn't not include mac header) -+ * (Only used to update stat, can't we use skb->len instead ?) -+ * @headroom Headroom added in skb to add bl_txhdr -+ * (Only used to remove it before freeing skb, is it needed ?) -+ * @amsdu Description of amsdu whose first subframe is this buffer -+ * (amsdu.nb = 0 means this buffer is not part of amsdu) -+ * @skb skb received from transmission -+ * @map_len Length mapped for DMA (only bl_hw_txhdr and data are mapped) -+ * @dma_addr DMA address after mapping -+ * @desc Buffer description that will be copied in shared mem for FW -+ */ -+struct bl_sw_txhdr { -+ struct bl_sta *bl_sta; -+ struct bl_vif *bl_vif; -+ struct bl_txq *txq; -+ u8 hw_queue; -+ u16 frame_len; -+ u16 headroom; -+#ifdef CONFIG_BL_AMSDUS_TX -+ struct bl_amsdu amsdu; -+#endif -+ struct sk_buff *skb; -+ -+ size_t map_len; -+ dma_addr_t dma_addr; -+ struct sdio_hdr hdr; -+ struct txdesc_api desc; -+}; -+ -+/** -+ * struct bl_txhdr - Stucture to control transimission of packet -+ * (Added in skb headroom) -+ * -+ * @sw_hdr: Information from driver -+ * @cache_guard: -+ * @hw_hdr: Information for/from hardware -+ */ -+struct bl_txhdr { -+ struct bl_sw_txhdr *sw_hdr; -+ char cache_guard[L1_CACHE_BYTES]; -+ struct bl_hw_txhdr hw_hdr; -+}; -+ -+int bl_start_xmit(struct sk_buff *skb, struct net_device *dev); -+int bl_requeue_multicast_skb(struct sk_buff *skb, struct bl_vif *bl_vif); -+int bl_start_mgmt_xmit(struct bl_vif *vif, struct bl_sta *sta, -+ struct cfg80211_mgmt_tx_params *params, bool offchan, -+ u64 *cookie); -+int bl_txdatacfm(void *pthis, void *host_id, void *data1, void **data2); -+ -+struct bl_hw; -+struct bl_sta; -+void bl_set_traffic_status(struct bl_hw *bl_hw, -+ struct bl_sta *sta, -+ bool available, -+ u8 ps_id); -+void bl_ps_bh_enable(struct bl_hw *bl_hw, struct bl_sta *sta, -+ bool enable); -+void bl_ps_bh_traffic_req(struct bl_hw *bl_hw, struct bl_sta *sta, -+ u16 pkt_req, u8 ps_id); -+ -+void bl_switch_vif_sta_txq(struct bl_sta *sta, struct bl_vif *old_vif, -+ struct bl_vif *new_vif); -+ -+int bl_dbgfs_print_sta(char *buf, size_t size, struct bl_sta *sta, -+ struct bl_hw *bl_hw); -+void bl_txq_credit_update(struct bl_hw *bl_hw, int sta_idx, u8 tid, -+ s8 update); -+void bl_tx_push(struct bl_hw *bl_hw, struct bl_txhdr *txhdr, int flags); -+void bl_tx_multi_pkt_push(struct bl_hw *bl_hw, struct sk_buff_head *sk_list_push); -+ -+void bl_downgrade_ac(struct bl_sta *sta, struct sk_buff *skb); -+ -+#endif /* _BL_TX_H_ */ -diff -Naur /dev/null_desc.h b/drivers/net/wireless/hflps170/hal_desc.h ---- /dev/null_desc.h 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/hal_desc.h 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,265 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file hal_desc.h -+ * -+ * @brief File containing the definition of HW descriptors. -+ * -+ * Contains the definition and structures used by HW -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ ****************************************************************************** -+ */ -+ -+#ifndef _HAL_DESC_H_ -+#define _HAL_DESC_H_ -+ -+#include "lmac_types.h" -+ -+/* Rate and policy table */ -+ -+#define N_CCK 8 -+#define N_OFDM 8 -+#define N_HT (8 * 2 * 2 * 4) -+#define N_VHT (10 * 4 * 2 * 8) -+#define N_RATE (N_CCK + N_OFDM + N_HT + N_VHT) -+ -+/* Values for bwTx */ -+#define __CHBW_CBW20 0 -+#define __CHBW_CBW40 1 -+#define __CHBW_CBW80 2 -+#define __CHBW_CBW160 3 -+ -+/* Values for formatModTx */ -+#define FORMATMOD_NON_HT 0 -+#define FORMATMOD_NON_HT_DUP_OFDM 1 -+#define FORMATMOD_HT_MF 2 -+#define FORMATMOD_HT_GF 3 -+#define FORMATMOD_VHT 4 -+ -+/* Values for navProtFrmEx */ -+#define NAV_PROT_NO_PROT_BIT 0 -+#define NAV_PROT_SELF_CTS_BIT 1 -+#define NAV_PROT_RTS_CTS_BIT 2 -+#define NAV_PROT_RTS_CTS_WITH_QAP_BIT 3 -+#define NAV_PROT_STBC_BIT 4 -+ -+union bl_mcs_index { -+ struct { -+ u32 mcs : 3; -+ u32 nss : 2; -+ } ht; -+ struct { -+ u32 mcs : 4; -+ u32 nss : 3; -+ } vht; -+ u32 legacy : 7; -+}; -+ -+/* c.f RW-WLAN-nX-MAC-HW-UM */ -+union bl_rate_ctrl_info { -+ struct { -+ u32 mcsIndexTx : 7; -+ u32 bwTx : 2; -+ u32 shortGITx : 1; -+ u32 preTypeTx : 1; -+ u32 formatModTx : 3; -+ u32 navProtFrmEx : 3; -+ u32 mcsIndexProtTx : 7; -+ u32 bwProtTx : 2; -+ u32 formatModProtTx : 3; -+ u32 nRetry : 3; -+ }; -+ u32 value; -+}; -+ -+/* c.f RW-WLAN-nX-MAC-HW-UM */ -+struct bl_power_ctrl_info { -+ u32 txPwrLevelPT : 8; -+ u32 txPwrLevelProtPT : 8; -+ u32 reserved :16; -+}; -+ -+/* c.f RW-WLAN-nX-MAC-HW-UM */ -+union bl_pol_phy_ctrl_info_1 { -+ struct { -+ u32 rsvd1 : 3; -+ u32 bfFrmEx : 1; -+ u32 numExtnSS : 2; -+ u32 fecCoding : 1; -+ u32 stbc : 2; -+ u32 rsvd2 : 5; -+ u32 nTx : 3; -+ u32 nTxProt : 3; -+ }; -+ u32 value; -+}; -+ -+/* c.f RW-WLAN-nX-MAC-HW-UM */ -+union bl_pol_phy_ctrl_info_2 { -+ struct { -+ u32 antennaSet : 8; -+ u32 smmIndex : 8; -+ u32 beamFormed : 1; -+ }; -+ u32 value; -+}; -+ -+/* c.f RW-WLAN-nX-MAC-HW-UM */ -+union bl_pol_mac_ctrl_info_1 { -+ struct { -+ u32 keySRamIndex : 10; -+ u32 keySRamIndexRA : 10; -+ }; -+ u32 value; -+}; -+ -+/* c.f RW-WLAN-nX-MAC-HW-UM */ -+union bl_pol_mac_ctrl_info_2 { -+ struct { -+ u32 longRetryLimit : 8; -+ u32 shortRetryLimit : 8; -+ u32 rtsThreshold : 12; -+ }; -+ u32 value; -+}; -+ -+#define POLICY_TABLE_PATTERN 0xBADCAB1E -+ -+/** -+ * struct bl_hw_txstatus - Bitfield of confirmation status -+ * -+ * @tx_done: packet has been sucessfully transmitted -+ * @retry_required: packet has been transmitted but not acknoledged. -+ * Driver must repush it. -+ * @sw_retry_required: packet has not been transmitted (FW wasn't able to push -+ * it when it received it: not active channel ...). Driver must repush it. -+ */ -+union bl_hw_txstatus { -+ struct { -+ u32 tx_done : 1; -+ u32 retry_required : 1; -+ u32 sw_retry_required : 1; -+ u32 reserved :29; -+ }; -+ u32 value; -+}; -+ -+/** -+ * struct tx_cfm_tag - Structure indicating the status and other -+ * information about the transmission -+ * -+ * @pn: PN that was used for the transmission -+ * @sn: Sequence number of the packet -+ * @timestamp: Timestamp of first transmission of this MPDU -+ * @credits: Number of credits to be reallocated for the txq that push this -+ * buffer (can be 0 or 1) -+ * @ampdu_size: Size of the ampdu in which the frame has been transmitted if -+ * this was the last frame of the a-mpdu, and 0 if the frame is not the last -+ * frame on a a-mdpu. -+ * 1 means that the frame has been transmitted as a singleton. -+ * @amsdu_size: Size, in bytes, allowed to create a-msdu. -+ * @status: transmission status -+ */ -+struct tx_cfm_tag -+{ -+ u16_l pn[4]; -+ u16_l sn; -+ u16_l timestamp; -+ s8_l credits; -+ u8_l ampdu_size; -+#ifdef CONFIG_BL_SPLIT_TX_BUF -+ u16_l amsdu_size; -+#endif -+ union bl_hw_txstatus status; -+ u32_l count; -+}__packed; -+ -+/** -+ * struct bl_hw_txhdr - Hardware part of tx header -+ * -+ * @cfm: Information updated by fw/hardware after sending a frame -+ */ -+struct bl_hw_txhdr { -+ struct tx_cfm_tag cfm; -+}; -+ -+/* Modem */ -+ -+#define MDM_PHY_CONFIG_TRIDENT 0 -+#define MDM_PHY_CONFIG_ELMA 1 -+#define MDM_PHY_CONFIG_KARST 2 -+ -+// MODEM features (from reg_mdm_stat.h) -+/// LDPCDEC field bit -+#define MDM_LDPCDEC_BIT ((u32)0x08000000) -+/// LDPCDEC field position -+#define MDM_LDPCDEC_POS 27 -+/// LDPCENC field bit -+#define MDM_LDPCENC_BIT ((u32)0x04000000) -+/// LDPCENC field position -+#define MDM_LDPCENC_POS 26 -+/// CHBW field mask -+#define MDM_CHBW_MASK ((u32)0x03000000) -+/// CHBW field LSB position -+#define MDM_CHBW_LSB 24 -+/// CHBW field width -+#define MDM_CHBW_WIDTH ((u32)0x00000002) -+/// DSSSCCK field bit -+#define MDM_DSSSCCK_BIT ((u32)0x00800000) -+/// DSSSCCK field position -+#define MDM_DSSSCCK_POS 23 -+/// NESS field mask -+#define MDM_NESS_MASK ((u32)0x00700000) -+/// NESS field LSB position -+#define MDM_NESS_LSB 20 -+/// NESS field width -+#define MDM_NESS_WIDTH ((u32)0x00000003) -+/// RFMODE field mask -+#define MDM_RFMODE_MASK ((u32)0x000F0000) -+/// RFMODE field LSB position -+#define MDM_RFMODE_LSB 16 -+/// RFMODE field width -+#define MDM_RFMODE_WIDTH ((u32)0x00000004) -+/// NSTS field mask -+#define MDM_NSTS_MASK ((u32)0x0000F000) -+/// NSTS field LSB position -+#define MDM_NSTS_LSB 12 -+/// NSTS field width -+#define MDM_NSTS_WIDTH ((u32)0x00000004) -+/// NSS field mask -+#define MDM_NSS_MASK ((u32)0x00000F00) -+/// NSS field LSB position -+#define MDM_NSS_LSB 8 -+/// NSS field width -+#define MDM_NSS_WIDTH ((u32)0x00000004) -+/// NTX field mask -+#define MDM_NTX_MASK ((u32)0x000000F0) -+/// NTX field LSB position -+#define MDM_NTX_LSB 4 -+/// NTX field width -+#define MDM_NTX_WIDTH ((u32)0x00000004) -+/// NRX field mask -+#define MDM_NRX_MASK ((u32)0x0000000F) -+/// NRX field LSB position -+#define MDM_NRX_LSB 0 -+/// NRX field width -+#define MDM_NRX_WIDTH ((u32)0x00000004) -+ -+#define __MDM_PHYCFG_FROM_VERS(v) (((v) & MDM_RFMODE_MASK) >> MDM_RFMODE_LSB) -+ -+#define RIU_FCU_PRESENT_MASK ((u32)0xFF000000) -+#define RIU_FCU_PRESENT_LSB 24 -+ -+#define __RIU_FCU_PRESENT(v) (((v) & RIU_FCU_PRESENT_MASK) >> RIU_FCU_PRESENT_LSB == 5) -+ -+/// AGC load version field mask -+#define RIU_AGC_LOAD_MASK ((u32)0x00C00000) -+/// AGC load version field LSB position -+#define RIU_AGC_LOAD_LSB 22 -+ -+#define __RIU_AGCLOAD_FROM_VERS(v) (((v) & RIU_AGC_LOAD_MASK) >> RIU_AGC_LOAD_LSB) -+ -+ -+#endif // _HAL_DESC_H_ -diff -Naur /dev/null_compat.h b/drivers/net/wireless/hflps170/ipc_compat.h ---- /dev/null_compat.h 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/ipc_compat.h 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,25 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file ipc_compat.h -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ **************************************************************************************** -+ */ -+ -+#ifndef _IPC_H_ -+#define _IPC_H_ -+ -+#define __INLINE static __attribute__((__always_inline__)) inline -+ -+#define __ALIGN4 __aligned(4) -+ -+#define ASSERT_ERR(condition) \ -+ do { \ -+ if (unlikely(!(condition))) { \ -+ printk(KERN_ERR "%s:%d:ASSERT_ERR(" #condition ")\n", __FILE__, __LINE__); \ -+ } \ -+ } while(0) -+ -+#endif /* _IPC_H_ */ -diff -Naur /dev/null_host.c b/drivers/net/wireless/hflps170/ipc_host.c ---- /dev/null_host.c 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/ipc_host.c 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,204 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file ipc_host.c -+ * -+ * @brief IPC module. -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ ****************************************************************************** -+ */ -+ -+/* -+ * INCLUDE FILES -+ ****************************************************************************** -+ */ -+#include -+#include "bl_defs.h" -+ -+#include "ipc_host.h" -+ -+/* -+ * TYPES DEFINITION -+ ****************************************************************************** -+ */ -+ -+const int nx_txdesc_cnt[] = -+{ -+ NX_TXDESC_CNT0, -+ NX_TXDESC_CNT1, -+ NX_TXDESC_CNT2, -+ NX_TXDESC_CNT3, -+ #if NX_TXQ_CNT == 5 -+ NX_TXDESC_CNT4, -+ #endif -+}; -+ -+const int nx_txdesc_cnt_msk[] = -+{ -+ NX_TXDESC_CNT0 - 1, -+ NX_TXDESC_CNT1 - 1, -+ NX_TXDESC_CNT2 - 1, -+ NX_TXDESC_CNT3 - 1, -+ #if NX_TXQ_CNT == 5 -+ NX_TXDESC_CNT4 - 1, -+ #endif -+}; -+ -+const int nx_txuser_cnt[] = -+{ -+ CONFIG_USER_MAX, -+ CONFIG_USER_MAX, -+ CONFIG_USER_MAX, -+ CONFIG_USER_MAX, -+ #if NX_TXQ_CNT == 5 -+ 1, -+ #endif -+}; -+ -+/** -+ ****************************************************************************** -+ */ -+void *ipc_host_tx_flush(struct ipc_host_env_tag *env, const int queue_idx, const int user_pos) -+{ -+ uint32_t used_idx = env->txdesc_used_idx[queue_idx][user_pos]; -+ void *host_id = env->tx_host_id[queue_idx][user_pos][used_idx & nx_txdesc_cnt_msk[queue_idx]]; -+ -+ // call the external function to indicate that a TX packet is freed -+ if (host_id != 0) -+ { -+ // Reset the host id in the array -+ env->tx_host_id[queue_idx][user_pos][used_idx & nx_txdesc_cnt_msk[queue_idx]] = 0; -+ -+ // Increment the used index -+ env->txdesc_used_idx[queue_idx][user_pos]++; -+ } -+ -+ return (host_id); -+} -+ -+/** -+ ****************************************************************************** -+ */ -+void ipc_host_tx_cfm_handler(struct ipc_host_env_tag *env, const int queue_idx, const int user_pos, struct bl_hw_txhdr *hw_hdr, struct bl_txq **txq_saved) -+{ -+ void *host_id = NULL; -+ struct sk_buff *skb; -+ uint32_t used_idx = env->txdesc_used_idx[queue_idx][user_pos] & nx_txdesc_cnt_msk[queue_idx]; -+ uint32_t free_idx = env->txdesc_free_idx[queue_idx][user_pos] & nx_txdesc_cnt_msk[queue_idx]; -+ -+ host_id = env->tx_host_id[queue_idx][user_pos][used_idx]; -+ //ASSERT_ERR(host_id != NULL); -+ if(!host_id){ -+ printk("%s: host id is null \n",__func__); -+ goto exit; -+ } -+ env->tx_host_id[queue_idx][user_pos][used_idx] = 0; -+ skb=host_id; -+ -+ BL_DBG("cfm skb=%p in %d of buffer, pkt_sn=%u\n", host_id, used_idx & nx_txdesc_cnt_msk[queue_idx], ((struct bl_txhdr *)(skb->data))->sw_hdr->hdr.reserved); -+ -+ if (env->cb.send_data_cfm(env->pthis, host_id, hw_hdr, (void **)txq_saved) != 0) { -+ BL_DBG("send_data_cfm!=0, so break, used_idx=%d\n", used_idx); -+ env->tx_host_id[queue_idx][user_pos][used_idx] = host_id; -+ } else { -+ env->txdesc_used_idx[queue_idx][user_pos]++; -+ } -+ -+exit: -+ if ((env->txdesc_used_idx[queue_idx][user_pos]&nx_txdesc_cnt_msk[queue_idx]) == free_idx) { -+ BL_DBG("ipc_host_tx_cfm_handler: used_idx=free_idx=%d\n", free_idx); -+ env->rb_len[queue_idx] = nx_txdesc_cnt[queue_idx]; -+ } else { -+ BL_DBG("ipc_host_tx_cfm_handler: used_idx=%d, free_idx=%d\n", env->txdesc_used_idx[queue_idx][user_pos]&nx_txdesc_cnt_msk[queue_idx], free_idx); -+ env->rb_len[queue_idx] = ((env->txdesc_used_idx[queue_idx][user_pos]&nx_txdesc_cnt_msk[queue_idx])-free_idx + nx_txdesc_cnt[queue_idx]) % nx_txdesc_cnt[queue_idx]; -+ } -+ -+ BL_DBG("ipc_host_tx_cfm_handler: env->rb_len[%d]=%d\n", queue_idx, env->rb_len[queue_idx]); -+ BL_DBG("used_idx=%d--->%d\n", env->txdesc_used_idx[queue_idx][user_pos]-1, env->txdesc_used_idx[queue_idx][user_pos]); -+} -+ -+/** -+ ****************************************************************************** -+ */ -+void ipc_host_init(struct ipc_host_env_tag *env, -+ struct ipc_host_cb_tag *cb, -+ void *pthis) -+{ -+ unsigned int i; -+ // Reset the IPC Host environment -+ memset(env, 0, sizeof(struct ipc_host_env_tag)); -+ -+ // Save the callbacks in our own environment -+ env->cb = *cb; -+ -+ // Save the pointer to the register base -+ env->pthis = pthis; -+ -+ // Initialize buffers numbers and buffers sizes needed for DMA Receptions -+ env->rx_bufnb = IPC_RXBUF_CNT; -+ env->rx_bufsz = IPC_RXBUF_SIZE; -+ #ifdef CONFIG_BL_FULLMAC -+ env->rxdesc_nb = IPC_RXDESC_CNT; -+ #endif //(CONFIG_BL_FULLMAC) -+ env->ipc_e2amsg_bufnb = IPC_MSGE2A_BUF_CNT; -+ env->ipc_e2amsg_bufsz = sizeof(struct ipc_e2a_msg); -+ env->ipc_dbg_bufnb = IPC_DBGBUF_CNT; -+ env->ipc_dbg_bufsz = sizeof(struct ipc_dbg_msg); -+ -+ env->rb_len[0] = NX_TXDESC_CNT0; -+ env->rb_len[1] = NX_TXDESC_CNT1; -+ env->rb_len[2] = NX_TXDESC_CNT2; -+ env->rb_len[3] = NX_TXDESC_CNT3; -+ #if NX_TXQ_CNT == 5 -+ env->rb_len[4] = NX_TXDESC_CNT4; -+ #endif -+ -+ for (i = 0; i < CONFIG_USER_MAX; i++) -+ { -+ // Initialize the pointers to the hostid arrays -+ env->tx_host_id[0][i] = env->tx_host_id0[i]; -+ env->tx_host_id[1][i] = env->tx_host_id1[i]; -+ env->tx_host_id[2][i] = env->tx_host_id2[i]; -+ env->tx_host_id[3][i] = env->tx_host_id3[i]; -+ #if NX_TXQ_CNT == 5 -+ env->tx_host_id[4][i] = NULL; -+ #endif -+ } -+ -+ #if NX_TXQ_CNT == 5 -+ env->tx_host_id[4][0] = env->tx_host_id4[0]; -+ #endif -+} -+ -+/** -+ ****************************************************************************** -+ */ -+void ipc_host_txdesc_push(struct ipc_host_env_tag *env, const int queue_idx, -+ const int user_pos, void *host_id) -+{ -+#ifdef CONFIG_BL_DBG -+ struct sk_buff *skb = host_id; -+#endif -+ uint32_t free_idx = env->txdesc_free_idx[queue_idx][user_pos] & nx_txdesc_cnt_msk[queue_idx]; -+ uint32_t used_idx = env->txdesc_used_idx[queue_idx][user_pos] & nx_txdesc_cnt_msk[queue_idx]; -+ -+ BL_DBG("save skb=%p in %d of buffer, pkt_sn=%u\n", host_id, free_idx, ((struct bl_txhdr *)((struct sk_buff *)skb->data))->sw_hdr->hdr.reserved); -+ -+ // Save the host id in the environment -+ env->tx_host_id[queue_idx][user_pos][free_idx] = host_id; -+ -+ if((free_idx + 1) % nx_txdesc_cnt[queue_idx] == used_idx) { -+ BL_DBG("queue is full: free_idx=%d, used_idx=%d\n", free_idx, used_idx); -+ env->txdesc_free_idx[queue_idx][user_pos]++; -+ env->rb_len[queue_idx] = 0; -+ } else { -+ env->txdesc_free_idx[queue_idx][user_pos]++; -+ BL_DBG("ipc_host_txdesc_push: used_idx=%d, free_idx=%d\n", used_idx, env->txdesc_free_idx[queue_idx][user_pos]&nx_txdesc_cnt_msk[queue_idx]); -+ env->rb_len[queue_idx] = (used_idx-(env->txdesc_free_idx[queue_idx][user_pos]&nx_txdesc_cnt_msk[queue_idx]) + nx_txdesc_cnt[queue_idx]) % nx_txdesc_cnt[queue_idx]; -+ } -+ -+ BL_DBG("ipc_host_txdesc_push: env->rb_len[%d]=%d\n", queue_idx, env->rb_len[queue_idx]); -+ BL_DBG("queue_idx[%d], free_idx: %d--->%d\n", queue_idx, env->txdesc_free_idx[queue_idx][user_pos] - 1, env->txdesc_free_idx[queue_idx][user_pos]); -+} -diff -Naur /dev/null_host.h b/drivers/net/wireless/hflps170/ipc_host.h ---- /dev/null_host.h 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/ipc_host.h 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,212 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file ipc_host.h -+ * -+ * @brief IPC module. -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ ****************************************************************************** -+ */ -+#ifndef _IPC_HOST_H_ -+#define _IPC_HOST_H_ -+ -+/* -+ * INCLUDE FILES -+ ****************************************************************************** -+ */ -+#include "ipc_shared.h" -+#ifndef __KERNEL__ -+#include "arch.h" -+#else -+#include "ipc_compat.h" -+#endif -+ -+#include "bl_txq.h" -+#include "hal_desc.h" -+ -+/** -+ ****************************************************************************** -+ * @brief This structure is used to initialize the MAC SW -+ * -+ * The WLAN device driver provides functions call-back with this structure -+ ****************************************************************************** -+ */ -+struct ipc_host_cb_tag -+{ -+ /// WLAN driver call-back function: send_data_cfm -+ int (*send_data_cfm)(void *pthis, void *host_id, void *data1, void **data2); -+ -+ /// WLAN driver call-back function: recv_data_ind -+ uint8_t (*recv_data_ind)(void *pthis, void *host_id); -+ -+ /// WLAN driver call-back function: recv_radar_ind -+ uint8_t (*recv_radar_ind)(void *pthis, void *host_id); -+ -+ /// WLAN driver call-back function: recv_msg_ind -+ uint8_t (*recv_msg_ind)(void *pthis, void *host_id); -+ -+ /// WLAN driver call-back function: recv_msgack_ind -+ uint8_t (*recv_msgack_ind)(void *pthis, void *host_id); -+ -+ /// WLAN driver call-back function: recv_dbg_ind -+ uint8_t (*recv_dbg_ind)(void *pthis, void *host_id); -+ -+ /// WLAN driver call-back function: prim_tbtt_ind -+ void (*prim_tbtt_ind)(void *pthis); -+ -+ /// WLAN driver call-back function: sec_tbtt_ind -+ void (*sec_tbtt_ind)(void *pthis); -+ -+}; -+ -+/* -+ * Struct used to store information about host buffers (DMA Address and local pointer) -+ */ -+struct ipc_hostbuf -+{ -+ void *hostid; ///< ptr to hostbuf client (ipc_host client) structure -+ uint32_t dma_addr; ///< ptr to real hostbuf dma address -+}; -+ -+/// Definition of the IPC Host environment structure. -+struct ipc_host_env_tag -+{ -+ /// Structure containing the callback pointers -+ struct ipc_host_cb_tag cb; -+ -+ #ifdef CONFIG_BL_FULLMAC -+ // Array used to store the descriptor addresses -+ struct ipc_hostbuf ipc_host_rxdesc_array[IPC_RXDESC_CNT]; -+ // Index of the host RX descriptor array (ipc_shared environment) -+ uint8_t ipc_host_rxdesc_idx; -+ /// Store the number of RX Descriptors -+ uint8_t rxdesc_nb; -+ #endif //(CONFIG_BL_FULLMAC) -+ -+ /// Fields for Data Rx handling -+ // Index used for ipc_host_rxbuf_array to point to current buffer -+ uint8_t ipc_host_rxbuf_idx; -+ // Store the number of Rx Data buffers -+ uint32_t rx_bufnb; -+ // Store the size of the Rx Data buffers -+ uint32_t rx_bufsz; -+ -+ uint32_t rb_len[NX_TXQ_CNT]; -+ -+ // Index used that points to the first free TX desc -+ uint32_t txdesc_free_idx[IPC_TXQUEUE_CNT][CONFIG_USER_MAX]; -+ // Index used that points to the first used TX desc -+ uint32_t txdesc_used_idx[IPC_TXQUEUE_CNT][CONFIG_USER_MAX]; -+ // Array storing the currently pushed host ids for the BK queue -+ void *tx_host_id0[CONFIG_USER_MAX][NX_TXDESC_CNT0]; -+ // Array storing the currently pushed host ids for the BE queue -+ void *tx_host_id1[CONFIG_USER_MAX][NX_TXDESC_CNT1]; -+ // Array storing the currently pushed host ids for the VI queue -+ void *tx_host_id2[CONFIG_USER_MAX][NX_TXDESC_CNT2]; -+ // Array storing the currently pushed host ids for the VO queue -+ void *tx_host_id3[CONFIG_USER_MAX][NX_TXDESC_CNT3]; -+ #if NX_TXQ_CNT == 5 -+ // Array storing the currently pushed host ids for the BCN queue -+ void *tx_host_id4[1][NX_TXDESC_CNT4]; -+ #endif -+ // Pointer to the different host ids arrays, per IPC queue -+ void **tx_host_id[IPC_TXQUEUE_CNT][CONFIG_USER_MAX]; -+ // Pointer to the different TX descriptor arrays, per IPC queue -+ volatile struct txdesc_host *txdesc[IPC_TXQUEUE_CNT][CONFIG_USER_MAX]; -+ -+ /// Fields for Emb->App MSGs handling -+ // Global array used to store the hostid and hostbuf addresses for msg/ind -+ struct ipc_hostbuf ipc_host_msgbuf_array[IPC_MSGE2A_BUF_CNT]; -+ // Index of the MSG E2A buffers array to point to current buffer -+ uint8_t ipc_host_msge2a_idx; -+ // Store the number of E2A MSG buffers -+ uint32_t ipc_e2amsg_bufnb; -+ // Store the size of the E2A MSG buffers -+ uint32_t ipc_e2amsg_bufsz; -+ -+ /// E2A ACKs of A2E MSGs -+ uint8_t msga2e_cnt; -+ void *msga2e_hostid; -+ -+ /// Fields for Debug MSGs handling -+ // Global array used to store the hostid and hostbuf addresses for Debug messages -+ struct ipc_hostbuf ipc_host_dbgbuf_array[IPC_DBGBUF_CNT]; -+ // Index of the Debug messages buffers array to point to current buffer -+ uint8_t ipc_host_dbg_idx; -+ // Store the number of Debug messages buffers -+ uint32_t ipc_dbg_bufnb; -+ // Store the size of the Debug messages buffers -+ uint32_t ipc_dbg_bufsz; -+ -+ /// Pointer to the attached object (used in callbacks and register accesses) -+ void *pthis; -+}; -+ -+extern const int nx_txdesc_cnt[]; -+extern const int nx_txdesc_cnt_msk[]; -+extern const int nx_txuser_cnt[]; -+ -+/** -+ ****************************************************************************** -+ * @brief Initialize the IPC running on the Application CPU. -+ * -+ * This function: -+ * - initializes the IPC software environments -+ * - enables the interrupts in the IPC block -+ * -+ * @param[in] env Pointer to the IPC host environment -+ * -+ * @warning Since this function resets the IPC Shared memory, it must be called -+ * before the LMAC FW is launched because LMAC sets some init values in IPC -+ * Shared memory at boot. -+ * -+ ****************************************************************************** -+ */ -+void ipc_host_init(struct ipc_host_env_tag *env, -+ struct ipc_host_cb_tag *cb, -+ void *pthis); -+ -+/** -+ ****************************************************************************** -+ * @brief Push a filled Tx descriptor (host side). -+ * -+ * This function sets the next Tx descriptor available by the host side: -+ * - as used for the host side -+ * - as available for the emb side. -+ * The Tx descriptor must be correctly filled before calling this function. -+ * -+ * This function may trigger an IRQ to the emb CPU depending on the interrupt -+ * mitigation policy and on the push count. -+ * -+ * @param[in] env Pointer to the IPC host environment -+ * @param[in] queue_idx Queue index. Same value than ipc_host_txdesc_get() -+ * @param[in] user_pos User position. If MU-MIMO is not used, this value -+ * shall be 0. -+ * @param[in] host_id Parameter indicated by the IPC at TX confirmation, -+ * that allows the driver finding the buffer -+ * -+ ****************************************************************************** -+ */ -+void ipc_host_txdesc_push(struct ipc_host_env_tag *env, const int queue_idx, -+ const int user_pos, void *host_id); -+ -+/** -+ ****************************************************************************** -+ * @brief Get and flush a packet from the IPC queue passed as parameter. -+ * -+ * @param[in] env Pointer to the IPC host environment -+ * @param[in] queue_idx Index of the queue to flush -+ * @param[in] user_pos User position to flush -+ * -+ * @return The flushed hostid if there is one, 0 otherwise. -+ * -+ ****************************************************************************** -+ */ -+void *ipc_host_tx_flush(struct ipc_host_env_tag *env, const int queue_idx, -+ const int user_pos); -+void ipc_host_tx_cfm_handler(struct ipc_host_env_tag *env, const int queue_idx, const int user_pos, struct bl_hw_txhdr *hw_hdr, struct bl_txq **txq_saved); -+ -+ -+#endif // _IPC_HOST_H_ -diff -Naur /dev/null_shared.h b/drivers/net/wireless/hflps170/ipc_shared.h ---- /dev/null_shared.h 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/ipc_shared.h 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,341 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file ipc_shared.h -+ * -+ * @brief Shared data between both IPC modules. -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ **************************************************************************************** -+ */ -+ -+#ifndef _IPC_SHARED_H_ -+#define _IPC_SHARED_H_ -+ -+/* -+ * INCLUDE FILES -+ **************************************************************************************** -+ */ -+#include "ipc_compat.h" -+#include "lmac_types.h" -+#include "lmac_mac.h" -+ -+/* -+ * DEFINES AND MACROS -+ **************************************************************************************** -+ */ -+#define CO_BIT(pos) (1U<<(pos)) -+ -+#define IPC_TXQUEUE_CNT NX_TXQ_CNT -+#define NX_TXDESC_CNT0 8 -+#define NX_TXDESC_CNT1 64 -+#define NX_TXDESC_CNT2 64 -+#define NX_TXDESC_CNT3 8 -+#if NX_TXQ_CNT == 5 -+#define NX_TXDESC_CNT4 8 -+#endif -+ -+/* -+ * Number of Host buffers available for Data Rx handling (through DMA) -+ */ -+#define IPC_RXBUF_CNT 128 -+ -+/* -+ * Number of shared descriptors available for Data RX handling -+ */ -+#define IPC_RXDESC_CNT 128 -+ -+/* -+ * RX Data buffers size (in bytes) -+ */ -+#define IPC_RXBUF_SIZE 5120 -+ -+/* -+ * Number of Host buffers available for Emb->App MSGs sending (through DMA) -+ */ -+#define IPC_MSGE2A_BUF_CNT 64 -+/* -+ * Number of Host buffers available for Debug Messages sending (through DMA) -+ */ -+#define IPC_DBGBUF_CNT 32 -+ -+/* -+ * Length used in MSGs structures -+ */ -+#define IPC_A2E_MSG_BUF_SIZE 127 // size in 4-byte words -+#define IPC_E2A_MSG_PARAM_SIZE 256 // size in 4-byte words -+/* -+ * Debug messages buffers size (in bytes) -+ */ -+#define IPC_DBG_PARAM_SIZE 256 -+ -+/* -+ * Define used for Rx hostbuf validity. -+ * This value should appear only when hostbuf was used for a Reception. -+ */ -+#define RX_DMA_OVER_PATTERN 0xAAAAAA00 -+ -+/* -+ * Define used for MSG buffers validity. -+ * This value will be written only when a MSG buffer is used for sending from Emb to App. -+ */ -+#define IPC_MSGE2A_VALID_PATTERN 0xADDEDE2A -+ -+/* -+ * Define used for Debug messages buffers validity. -+ * This value will be written only when a DBG buffer is used for sending from Emb to App. -+ */ -+#define IPC_DBG_VALID_PATTERN 0x000CACA0 -+ -+/* -+ * Length of the receive vectors, in bytes -+ */ -+#define DMA_HDR_PHYVECT_LEN 36 -+ -+/* -+ * Maximum number of payload addresses and lengths present in the descriptor -+ */ -+#define NX_TX_PAYLOAD_MAX 6 -+ -+/* -+ **************************************************************************************** -+ */ -+// c.f LMAC/src/tx/tx_swdesc.h -+/// Descriptor filled by the Host -+struct hostdesc -+{ -+#ifdef CONFIG_BL_SPLIT_TX_BUF -+ /// Pointers to packet payloads -+ u32_l packet_addr[NX_TX_PAYLOAD_MAX]; -+ /// Sizes of the MPDU/MSDU payloads -+ u16_l packet_len[NX_TX_PAYLOAD_MAX]; -+ /// Number of payloads forming the MPDU -+ u8_l packet_cnt; -+#else -+ /// Pointer to packet payload -+ u32_l packet_addr; -+ /// Size of the payload -+ u16_l packet_len; -+#endif //(NX_AMSDU_TX) -+ -+ /// Address of the status descriptor in host memory (used for confirmation upload) -+ u32_l host_hdr_pads; -+ /// Destination Address -+ struct mac_addr eth_dest_addr; -+ /// Source Address -+ struct mac_addr eth_src_addr; -+ /// Ethernet Type -+ u16_l ethertype; -+ /// Buffer containing the PN to be used for this packet -+ u16_l pn[4]; -+ /// Sequence Number used for transmission of this MPDU -+ u16_l sn; -+ /// Timestamp of first transmission of this MPDU -+ u16_l timestamp; -+ /// Packet TID (0xFF if not a QoS frame) -+ u8_l tid; -+ /// Interface Id -+ u8_l vif_idx; -+ /// Station Id (0xFF if station is unknown) -+ u8_l staid; -+#ifdef CONFIG_BL_FULLMAC -+ /// TX flags -+ u16_l flags; -+#endif /* CONFIG_BL_FULLMAC */ -+}; -+ -+struct txdesc_api -+{ -+ /// add templately -+ u32_l ready; -+ /// Information provided by Host -+ struct hostdesc host; -+}; -+ -+ -+struct txdesc_host -+{ -+ u32_l ready; -+ -+ /// API of the embedded part -+ struct txdesc_api api; -+}; -+ -+/// Comes from ipc_dma.h -+/// Element in the pool of TX DMA bridge descriptors. -+struct dma_desc -+{ -+ /** Application subsystem address which is used as source address for DMA payload -+ * transfer*/ -+ u32_l src; -+ /** Points to the start of the embedded data buffer associated with this descriptor. -+ * This address acts as the destination address for the DMA payload transfer*/ -+ u32_l dest; -+ /// Complete length of the buffer in memory -+ u16_l length; -+ /// Control word for the DMA engine (e.g. for interrupt generation) -+ u16_l ctrl; -+ /// Pointer to the next element of the chained list -+ u32_l next; -+}; -+ -+// Comes from la.h -+/// Length of the configuration data of a logic analyzer -+#define LA_CONF_LEN 10 -+ -+/// Structure containing the configuration data of a logic analyzer -+struct la_conf_tag -+{ -+ u32_l conf[LA_CONF_LEN]; -+ u32_l trace_len; -+ u32_l diag_conf; -+}; -+ -+/// Size of a logic analyzer memory -+#define LA_MEM_LEN (1024 * 1024) -+ -+/// Type of errors -+enum -+{ -+ /// Recoverable error, not requiring any action from Upper MAC -+ DBG_ERROR_RECOVERABLE = 0, -+ /// Fatal error, requiring Upper MAC to reset Lower MAC and HW and restart operation -+ DBG_ERROR_FATAL -+}; -+ -+/// Maximum length of the SW diag trace -+#define DBG_SW_DIAG_MAX_LEN 1024 -+ -+/// Maximum length of the error trace -+#define DBG_ERROR_TRACE_SIZE 256 -+ -+/// Number of MAC diagnostic port banks -+#define DBG_DIAGS_MAC_MAX 48 -+ -+/// Number of PHY diagnostic port banks -+#define DBG_DIAGS_PHY_MAX 32 -+ -+/// Maximum size of the RX header descriptor information in the debug dump -+#define DBG_RHD_MEM_LEN (5 * 1024) -+ -+/// Maximum size of the RX buffer descriptor information in the debug dump -+#define DBG_RBD_MEM_LEN (5 * 1024) -+ -+/// Maximum size of the TX header descriptor information in the debug dump -+#define DBG_THD_MEM_LEN (10 * 1024) -+ -+/// Structure containing the information about the PHY channel that is used -+struct phy_channel_info -+{ -+ /// PHY channel information 1 -+ u32_l info1; -+ /// PHY channel information 2 -+ u32_l info2; -+}; -+ -+/// Debug information forwarded to host when an error occurs -+struct dbg_debug_info_tag -+{ -+ /// Type of error (0: recoverable, 1: fatal) -+ u32_l error_type; -+ /// Pointer to the first RX Header Descriptor chained to the MAC HW -+ u32_l rhd; -+ /// Size of the RX header descriptor buffer -+ u32_l rhd_len; -+ /// Pointer to the first RX Buffer Descriptor chained to the MAC HW -+ u32_l rbd; -+ /// Size of the RX buffer descriptor buffer -+ u32_l rbd_len; -+ /// Pointer to the first TX Header Descriptors chained to the MAC HW -+ u32_l thd[NX_TXQ_CNT]; -+ /// Size of the TX header descriptor buffer -+ u32_l thd_len[NX_TXQ_CNT]; -+ /// MAC HW diag configuration -+ u32_l hw_diag; -+ /// Error message -+ u32_l error[DBG_ERROR_TRACE_SIZE/4]; -+ /// SW diag configuration length -+ u32_l sw_diag_len; -+ /// SW diag configuration -+ u32_l sw_diag[DBG_SW_DIAG_MAX_LEN/4]; -+ /// PHY channel information -+ struct phy_channel_info chan_info; -+ /// Embedded LA configuration -+ struct la_conf_tag la_conf; -+ /// MAC diagnostic port state -+ u16_l diags_mac[DBG_DIAGS_MAC_MAX]; -+ /// PHY diagnostic port state -+ u16_l diags_phy[DBG_DIAGS_PHY_MAX]; -+ /// MAC HW RX Header descriptor pointer -+ u32_l rhd_hw_ptr; -+ /// MAC HW RX Buffer descriptor pointer -+ u32_l rbd_hw_ptr; -+}; -+ -+/// Full debug dump that is forwarded to host in case of error -+struct dbg_debug_dump_tag -+{ -+ /// Debug information -+ struct dbg_debug_info_tag dbg_info; -+ -+ /// RX header descriptor memory -+ u8_l rhd_mem[DBG_RHD_MEM_LEN]; -+ -+ /// RX buffer descriptor memory -+ u8_l rbd_mem[DBG_RBD_MEM_LEN]; -+ -+ /// TX header descriptor memory -+ u8_l thd_mem[NX_TXQ_CNT][DBG_THD_MEM_LEN]; -+ -+ /// Logic analyzer memory -+ u8_l la_mem[LA_MEM_LEN]; -+}; -+ -+struct rxdesc_tag -+{ -+ /// Host Buffer Address -+ u32_l host_id; -+ /// Length -+ u32_l frame_len; -+ /// Status -+ u8_l status; -+}; -+ -+ -+/** -+ **************************************************************************************** -+ * @defgroup IPC_MISC IPC Misc -+ * @ingroup IPC -+ * @brief IPC miscellaneous functions -+ **************************************************************************************** -+ */ -+ -+/// Message structure for MSGs from Emb to App -+struct ipc_e2a_msg -+{ -+ u16_l id; ///< Message id. -+ u16_l dummy_dest_id; ///< -+ u16_l dummy_src_id; ///< -+ u16_l param_len; ///< Parameter embedded struct length. -+ //u32_l param[IPC_E2A_MSG_PARAM_SIZE]; ///< Parameter embedded struct. Must be word-aligned. -+ u32_l param[]; ///< Parameter embedded struct. Must be word-aligned. -+}; -+ -+/// Message structure for Debug messages from Emb to App -+struct ipc_dbg_msg -+{ -+ u32_l string[IPC_DBG_PARAM_SIZE/4]; ///< Debug string -+ u32_l pattern; ///< Used to stamp a valid buffer -+}; -+ -+/// Message structure for MSGs from App to Emb. -+/// Actually a sub-structure will be used when filling the messages. -+struct ipc_a2e_msg -+{ -+ u32_l dummy_word; // used to cope with kernel message structure -+ u32_l msg[IPC_A2E_MSG_BUF_SIZE]; // body of the msg -+}; -+ -+#endif // _IPC_SHARED_H_ -+ -diff -Naur /dev/null_mac.h b/drivers/net/wireless/hflps170/lmac_mac.h ---- /dev/null_mac.h 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/lmac_mac.h 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,526 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file lmac_mac.h -+ * -+ * @brief MAC related definitions. -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ **************************************************************************************** -+ */ -+ -+#ifndef _MAC_H_ -+#define _MAC_H_ -+ -+/** -+ **************************************************************************************** -+ * @defgroup MAC MAC -+ * @ingroup COMMON -+ * @brief Common defines,structures -+ * -+ * This module contains defines commonaly used for MAC -+ * @{ -+ **************************************************************************************** -+ */ -+ -+/* -+ * INCLUDE FILES -+ **************************************************************************************** -+ */ -+#ifndef __KERNEL__ -+// standard includes -+#include -+#else -+#include -+#endif -+ -+ -+/* -+ * DEFINES -+ **************************************************************************************** -+ */ -+/// duration of a Time Unit in microseconds -+#define TU_DURATION 1024 -+ -+/// max number of channels in the 2.4 GHZ band -+#define MAC_DOMAINCHANNEL_24G_MAX 14 -+ -+/// max number of channels in the 5 GHZ band -+#define MAC_DOMAINCHANNEL_5G_MAX 45 -+ -+/// Mask to test if it's a basic rate - BIT(7) -+#define MAC_BASIC_RATE 0x80 -+/// Mask for extracting/checking word alignment -+#define WORD_ALIGN 3 -+ -+#define MAX_AMSDU_LENGTH 7935 -+ -+/* -+ * MACRO DEFINITIONS -+ **************************************************************************************** -+ */ -+ -+/** -+ **************************************************************************************** -+ * Compare two MAC addresses. -+ * The MAC addresses MUST be 16 bit aligned. -+ * @param[in] addr1_ptr Pointer to the first MAC address. -+ * @param[in] addr2_ptr Pointer to the second MAC address. -+ * @return True if equal, false if not. -+ **************************************************************************************** -+ */ -+#define MAC_ADDR_CMP(addr1_ptr, addr2_ptr) \ -+ ((*(((u16*)(addr1_ptr)) + 0) == *(((u16*)(addr2_ptr)) + 0)) && \ -+ (*(((u16*)(addr1_ptr)) + 1) == *(((u16*)(addr2_ptr)) + 1)) && \ -+ (*(((u16*)(addr1_ptr)) + 2) == *(((u16*)(addr2_ptr)) + 2))) -+ -+/** -+ **************************************************************************************** -+ * Compare two MAC addresses whose alignment is not known. -+ * @param[in] __a1 Pointer to the first MAC address. -+ * @param[in] __a2 Pointer to the second MAC address. -+ * @return True if equal, false if not. -+ **************************************************************************************** -+ */ -+#define MAC_ADDR_CMP_PACKED(__a1, __a2) \ -+ (memcmp(__a1, __a2, MAC_ADDR_LEN) == 0) -+ -+/** -+ **************************************************************************************** -+ * Copy a MAC address. -+ * The MAC addresses MUST be 16 bit aligned. -+ * @param[in] addr1_ptr Pointer to the destination MAC address. -+ * @param[in] addr2_ptr Pointer to the source MAC address. -+ **************************************************************************************** -+ */ -+#define MAC_ADDR_CPY(addr1_ptr, addr2_ptr) \ -+ *(((u16*)(addr1_ptr)) + 0) = *(((u16*)(addr2_ptr)) + 0); \ -+ *(((u16*)(addr1_ptr)) + 1) = *(((u16*)(addr2_ptr)) + 1); \ -+ *(((u16*)(addr1_ptr)) + 2) = *(((u16*)(addr2_ptr)) + 2) -+ -+/** -+ **************************************************************************************** -+ * Compare two SSID. -+ * @param ssid1_ptr Pointer to the first SSID structure. -+ * @param ssid2_ptr Pointer to the second SSID structure. -+ * @return True if equal, false if not. -+ **************************************************************************************** -+ */ -+#define MAC_SSID_CMP(ssid1_ptr,ssid2_ptr) \ -+ (((ssid1_ptr)->length == (ssid2_ptr)->length) && \ -+ (memcmp((&(ssid1_ptr)->array[0]), (&(ssid2_ptr)->array[0]), (ssid1_ptr)->length) == 0)) -+ -+/// Check if MAC address is a group address: test the multicast bit. -+#define MAC_ADDR_GROUP(mac_addr_ptr) ((*(mac_addr_ptr)) & 1) -+ -+/// MAC address length in bytes. -+#define MAC_ADDR_LEN 6 -+ -+/// MAC address structure. -+struct mac_addr -+{ -+ /// Array of bytes that make up the MAC address. -+ u16_l array[MAC_ADDR_LEN/2]; -+}__packed; -+ -+/// SSID maximum length. -+#define MAC_SSID_LEN 32 -+ -+/// SSID. -+struct mac_ssid -+{ -+ /// Actual length of the SSID. -+ u8_l length; -+ /// Array containing the SSID name. -+ u8_l array[MAC_SSID_LEN]; -+}; -+ -+/// MAC RATE-SET -+#define MAC_RATESET_LEN 12 -+#define MAC_OFDM_PHY_RATESET_LEN 8 -+#define MAC_EXT_RATES_OFF 8 -+struct mac_rateset -+{ -+ u8_l length; -+ u8_l array[MAC_RATESET_LEN]; -+}; -+ -+/// MAC RATES -+#define MAC_MCS_WORD_CNT 3 -+struct mac_rates -+{ -+ /// MCS 0 to 76 -+ u32 mcs[MAC_MCS_WORD_CNT]; -+ /// Legacy rates (1Mbps to 54Mbps) -+ u16 legacy; -+}; -+ -+/// IV/EIV data -+#define MAC_IV_LEN 4 -+#define MAC_EIV_LEN 4 -+struct rx_seciv -+{ -+ u8 iv[MAC_IV_LEN]; -+ u8 ext_iv[MAC_EIV_LEN]; -+}; -+ -+/// MAC MCS SET -+#define MAX_MCS_LEN 16 // 16 * 8 = 128 -+struct mac_mcsset -+{ -+ u8 length; -+ u8 array[MAX_MCS_LEN]; -+}; -+ -+/// MAC Secret Key -+#define MAC_WEP_KEY_CNT 4 // Number of WEP keys per virtual device -+#define MAC_WEP_KEY_LEN 13 // Max size of a WEP key (104/8 = 13) -+struct mac_wep_key -+{ -+ u8 array[MAC_WEP_KEY_LEN]; // Key material -+}; -+ -+ -+/// MAC Secret Key -+#define MAC_SEC_KEY_LEN 32 // TKIP keys 256 bits (max length) with MIC keys -+struct mac_sec_key -+{ -+ u8_l length; // Key material length -+ u32_l array[MAC_SEC_KEY_LEN/4]; // Key material -+}; -+ -+/// MAC channel list -+/// @todo: fix that number -+#define MAC_MAX_CH 40 -+struct mac_ch_list -+{ -+ /// Number of channels in channel list. -+ u16 nbr; -+ /// List of the channels. -+ u8 list[MAC_MAX_CH]; -+}; -+ -+ -+struct mac_country_subband -+{ -+ // First channel number of the triplet. -+ u8 first_chn; -+ // Max number of channel number for the triplet. -+ u8 nbr_of_chn; -+ // Maximum allowed transmit power. -+ u8 max_tx_power; -+}; -+ -+#define MAX_COUNTRY_LEN 3 -+#define MAX_COUNTRY_SUBBAND 5 -+struct mac_country -+{ -+ // Length of the country string -+ u8 length; -+ // Country string 2 char. -+ u8 string[MAX_COUNTRY_LEN]; -+ // channel info triplet -+ struct mac_country_subband subband[MAX_COUNTRY_SUBBAND]; -+}; -+ -+/// MAC HT CAPABILITY -+struct mac_htcapability -+{ -+ u16_l ht_capa_info; -+ u8_l a_mpdu_param; -+ u8_l mcs_rate[MAX_MCS_LEN]; -+ u16_l ht_extended_capa; -+ u32_l tx_beamforming_capa; -+ u8_l asel_capa; -+}; -+ -+/// MAC VHT CAPABILITY -+struct mac_vhtcapability -+{ -+ u32_l vht_capa_info; -+ u16_l rx_mcs_map; -+ u16_l rx_highest; -+ u16_l tx_mcs_map; -+ u16_l tx_highest; -+}; -+ -+ -+/// MAC HT CAPABILITY -+struct mac_htoprnelmt -+{ -+ u8 prim_channel; -+ u8 ht_oper_1; -+ u16 ht_oper_2; -+ u16 ht_oper_3; -+ u8 mcs_rate[MAX_MCS_LEN]; -+ -+}; -+ -+/// MAC QOS CAPABILITY -+struct mac_qoscapability -+{ -+ u8 qos_info; -+}; -+ -+/// RSN information element -+#define MAC_RAW_RSN_IE_LEN 34 -+struct mac_raw_rsn_ie -+{ -+ u8 data[2 + MAC_RAW_RSN_IE_LEN]; -+}; -+ -+#define MAC_RAW_ENC_LEN 0x1A -+struct mac_wpa_frame -+{ -+ u8 array[MAC_RAW_ENC_LEN]; -+}; -+ -+#define MAC_WME_PARAM_LEN 16 -+struct mac_wmm_frame -+{ -+ u8 array [MAC_WME_PARAM_LEN]; -+}; -+ -+/// BSS load element -+struct mac_bss_load -+{ -+ u16 sta_cnt; -+ u8 ch_utilization; -+ u16 avail_adm_capacity; -+}; -+ -+///EDCA Parameter Set Element -+struct mac_edca_param_set -+{ -+ u8 qos_info; -+ u32 ac_be_param_record; -+ u32 ac_bk_param_record; -+ u32 ac_vi_param_record; -+ u32 ac_vo_param_record; -+}; -+ -+ -+///MAC Twenty Forty BSS -+ -+struct mac_twenty_fourty_bss -+{ -+ u8 bss_coexistence; -+}; -+ -+/// MAC BA PARAMETERS -+struct mac_ba_param -+{ -+ struct mac_addr peer_sta_address; ///< Peer STA MAC Address to which BA is Setup -+ u16 buffer_size; ///< Number of buffers available for this BA -+ u16 start_sequence_number;///< Start Sequence Number of BA -+ u16 ba_timeout; ///< BA Setup timeout value -+ u8 dev_type; ///< BA Device Type Originator/Responder -+ u8 block_ack_policy; ///< BLOCK-ACK Policy Setup Immedaite/Delayed -+ u8 buffer_cnt; ///< Number of buffers required for BA Setup -+}; -+ -+/// MAC TS INFO field -+struct mac_ts_info -+{ -+ u8 traffic_type; -+ u8 ack_policy; -+ u8 access_policy; -+ u8 dir; -+ u8 tsid; -+ u8 user_priority; -+ bool aggregation; -+ bool apsd; -+ bool schedule; -+}; -+ -+/// MAC TSPEC PARAMETERS -+struct mac_tspec_param -+{ -+ struct mac_ts_info ts_info; -+ u16 nominal_msdu_size; -+ u16 max_msdu_size; -+ u32 min_service_interval; -+ u32 max_service_interval; -+ u32 inactivity_interval; -+ u32 short_inactivity_interval; -+ u32 service_start_time; -+ u32 max_burst_size; -+ u32 min_data_rate; -+ u32 mean_data_rate; -+ u32 min_phy_rate; -+ u32 peak_data_rate; -+ u32 delay_bound; -+ u16 medium_time; -+ u8 surplusbwallowance; -+}; -+ -+/// Scan result element, parsed from beacon or probe response frames. -+struct mac_scan_result -+{ -+ /// Network BSSID. -+ struct mac_addr bssid; -+ /// Network name. -+ struct mac_ssid ssid; -+ /// Network type (IBSS or ESS). -+ u16 bsstype; -+ /// Network channel number. -+ u16 ch_nbr; -+ /// Network beacon period. -+ u16 beacon_period; -+ u32 timestamp_high; -+ u32 timestamp_low; -+ u16 dtim_period; -+ u16 ibss_parameter; -+ u16 cap_info; -+ struct mac_rateset rate_set; -+ struct mac_bss_load bss_load; -+ u8 country_element[3]; -+ struct mac_edca_param_set edca_param; -+ struct mac_raw_rsn_ie rsn_ie; -+ struct mac_qoscapability qos_cap; -+ struct mac_htcapability ht_cap; -+ u8 sec_ch_oft; -+ struct mac_twenty_fourty_bss twenty_fourty_bss; -+ bool valid_flag; -+ u8 rssi; -+}; -+ -+/// Structure containing the information required to perform a measurement request -+struct mac_request_set -+{ -+ -+ u8 mode; ///> 10)) -+#define MSG_I(msg) ((msg) & ((1<<10)-1)) -+ -+struct sdio_hdr -+{ -+ u16 len; -+ u16 type; -+ u16 queue_idx; -+ u16 reserved; -+}__packed; -+ -+/// Message structure. -+struct lmac_msg -+{ -+ struct sdio_hdr sdio_hdr; -+ lmac_msg_id_t id; ///< Message id. -+ lmac_task_id_t dest_id; ///< Destination kernel identifier. -+ lmac_task_id_t src_id; ///< Source kernel identifier. -+ u16 param_len; ///< Parameter embedded struct length. -+ u8 param[]; ///< Parameter embedded struct. Must be word-aligned. -+}; -+ -+enum lmac_msg_type -+{ -+ BL_TYPE_MSG, -+ BL_TYPE_ACK, -+ BL_TYPE_DBG, -+ BL_TYPE_DATA, -+ BL_TYPE_TXCFM, -+ BL_TYPE_AGG_REORD_MSG, -+ BL_TYPE_DBG_DUMP_START, -+ BL_TYPE_DBG_DUMP_END, -+ BL_TYPE_DBG_LA_TRACE, -+ BL_TYPE_DBG_RHD_DESC, -+ BL_TYPE_DBG_RBD_DESC, -+ BL_TYPE_DBG_TX_DESC, -+ BL_TYPE_DUMP_INFO, -+ BL_TYPE_TX_STOP, -+ BL_TYPE_TX_RESUME, -+ BL_TYPE_MAX, -+}; -+ -+/// List of messages related to the task. -+enum mm_msg_tag -+{ -+ /// RESET Request. -+ MM_RESET_REQ = LMAC_FIRST_MSG(TASK_MM), -+ /// RESET Confirmation. -+ MM_RESET_CFM, -+ /// START Request. -+ MM_START_REQ, -+ /// START Confirmation. -+ MM_START_CFM, -+ /// Read Version Request. -+ MM_VERSION_REQ, -+ /// Read Version Confirmation. -+ MM_VERSION_CFM, -+ /// ADD INTERFACE Request. -+ MM_ADD_IF_REQ, -+ /// ADD INTERFACE Confirmation. -+ MM_ADD_IF_CFM, -+ /// REMOVE INTERFACE Request. -+ MM_REMOVE_IF_REQ, -+ /// REMOVE INTERFACE Confirmation. -+ MM_REMOVE_IF_CFM, -+ /// STA ADD Request. -+ MM_STA_ADD_REQ, -+ /// STA ADD Confirm. -+ MM_STA_ADD_CFM, -+ /// STA DEL Request. -+ MM_STA_DEL_REQ, -+ /// STA DEL Confirm. -+ MM_STA_DEL_CFM, -+ /// RX FILTER CONFIGURATION Request. -+ MM_SET_FILTER_REQ, -+ /// RX FILTER CONFIGURATION Confirmation. -+ MM_SET_FILTER_CFM, -+ /// CHANNEL CONFIGURATION Request. -+ MM_SET_CHANNEL_REQ, -+ /// CHANNEL CONFIGURATION Confirmation. -+ MM_SET_CHANNEL_CFM, -+ /// DTIM PERIOD CONFIGURATION Request. -+ MM_SET_DTIM_REQ, -+ /// DTIM PERIOD CONFIGURATION Confirmation. -+ MM_SET_DTIM_CFM, -+ /// BEACON INTERVAL CONFIGURATION Request. -+ MM_SET_BEACON_INT_REQ, -+ /// BEACON INTERVAL CONFIGURATION Confirmation. -+ MM_SET_BEACON_INT_CFM, -+ /// BASIC RATES CONFIGURATION Request. -+ MM_SET_BASIC_RATES_REQ, -+ /// BASIC RATES CONFIGURATION Confirmation. -+ MM_SET_BASIC_RATES_CFM, -+ /// BSSID CONFIGURATION Request. -+ MM_SET_BSSID_REQ, -+ /// BSSID CONFIGURATION Confirmation. -+ MM_SET_BSSID_CFM, -+ /// EDCA PARAMETERS CONFIGURATION Request. -+ MM_SET_EDCA_REQ, -+ /// EDCA PARAMETERS CONFIGURATION Confirmation. -+ MM_SET_EDCA_CFM, -+ /// ABGN MODE CONFIGURATION Request. -+ MM_SET_MODE_REQ, -+ /// ABGN MODE CONFIGURATION Confirmation. -+ MM_SET_MODE_CFM, -+ /// Request setting the VIF active state (i.e associated or AP started) -+ MM_SET_VIF_STATE_REQ, -+ /// Confirmation of the @ref MM_SET_VIF_STATE_REQ message. -+ MM_SET_VIF_STATE_CFM, -+ /// SLOT TIME PARAMETERS CONFIGURATION Request. -+ MM_SET_SLOTTIME_REQ, -+ /// SLOT TIME PARAMETERS CONFIGURATION Confirmation. -+ MM_SET_SLOTTIME_CFM, -+ /// Power Mode Change Request. -+ MM_SET_IDLE_REQ, -+ /// Power Mode Change Confirm. -+ MM_SET_IDLE_CFM, -+ /// KEY ADD Request. -+ MM_KEY_ADD_REQ, -+ /// KEY ADD Confirm. -+ MM_KEY_ADD_CFM, -+ /// KEY DEL Request. -+ MM_KEY_DEL_REQ, -+ /// KEY DEL Confirm. -+ MM_KEY_DEL_CFM, -+ /// Block Ack agreement info addition -+ MM_BA_ADD_REQ, -+ /// Block Ack agreement info addition confirmation -+ MM_BA_ADD_CFM, -+ /// Block Ack agreement info deletion -+ MM_BA_DEL_REQ, -+ /// Block Ack agreement info deletion confirmation -+ MM_BA_DEL_CFM, -+ /// Indication of the primary TBTT to the upper MAC. Upon the reception of this -+ // message the upper MAC has to push the beacon(s) to the beacon transmission queue. -+ MM_PRIMARY_TBTT_IND, -+ /// Indication of the secondary TBTT to the upper MAC. Upon the reception of this -+ // message the upper MAC has to push the beacon(s) to the beacon transmission queue. -+ MM_SECONDARY_TBTT_IND, -+ /// Request for changing the TX power -+ MM_SET_POWER_REQ, -+ /// Confirmation of the TX power change -+ MM_SET_POWER_CFM, -+ /// Request to the LMAC to trigger the embedded logic analyzer and forward the debug -+ /// dump. -+ MM_DBG_TRIGGER_REQ, -+ /// Set Power Save mode -+ MM_SET_PS_MODE_REQ, -+ /// Set Power Save mode confirmation -+ MM_SET_PS_MODE_CFM, -+ /// Request to add a channel context -+ MM_CHAN_CTXT_ADD_REQ, -+ /// Confirmation of the channel context addition -+ MM_CHAN_CTXT_ADD_CFM, -+ /// Request to delete a channel context -+ MM_CHAN_CTXT_DEL_REQ, -+ /// Confirmation of the channel context deletion -+ MM_CHAN_CTXT_DEL_CFM, -+ /// Request to link a channel context to a VIF -+ MM_CHAN_CTXT_LINK_REQ, -+ /// Confirmation of the channel context link -+ MM_CHAN_CTXT_LINK_CFM, -+ /// Request to unlink a channel context from a VIF -+ MM_CHAN_CTXT_UNLINK_REQ, -+ /// Confirmation of the channel context unlink -+ MM_CHAN_CTXT_UNLINK_CFM, -+ /// Request to update a channel context -+ MM_CHAN_CTXT_UPDATE_REQ, -+ /// Confirmation of the channel context update -+ MM_CHAN_CTXT_UPDATE_CFM, -+ /// Request to schedule a channel context -+ MM_CHAN_CTXT_SCHED_REQ, -+ /// Confirmation of the channel context scheduling -+ MM_CHAN_CTXT_SCHED_CFM, -+ /// Request to change the beacon template in LMAC -+ MM_BCN_CHANGE_REQ, -+ /// Confirmation of the beacon change -+ MM_BCN_CHANGE_CFM, -+ /// Request to update the TIM in the beacon (i.e to indicate traffic bufferized at AP) -+ MM_TIM_UPDATE_REQ, -+ /// Confirmation of the TIM update -+ MM_TIM_UPDATE_CFM, -+ /// Connection loss indication -+ MM_CONNECTION_LOSS_IND, -+ /// Channel context switch indication to the upper layers -+ MM_CHANNEL_SWITCH_IND, -+ /// Channel context pre-switch indication to the upper layers -+ MM_CHANNEL_PRE_SWITCH_IND, -+ /// Request to remain on channel or cancel remain on channel -+ MM_REMAIN_ON_CHANNEL_REQ, -+ /// Confirmation of the (cancel) remain on channel request -+ MM_REMAIN_ON_CHANNEL_CFM, -+ /// Remain on channel expired indication -+ MM_REMAIN_ON_CHANNEL_EXP_IND, -+ /// Indication of a PS state change of a peer device -+ MM_PS_CHANGE_IND, -+ /// Indication that some buffered traffic should be sent to the peer device -+ MM_TRAFFIC_REQ_IND, -+ /// Request to modify the STA Power-save mode options -+ MM_SET_PS_OPTIONS_REQ, -+ /// Confirmation of the PS options setting -+ MM_SET_PS_OPTIONS_CFM, -+ /// Indication of PS state change for a P2P VIF -+ MM_P2P_VIF_PS_CHANGE_IND, -+ /// Indication that CSA counter has been updated -+ MM_CSA_COUNTER_IND, -+ /// Channel occupation report indication -+ MM_CHANNEL_SURVEY_IND, -+ /// Message containing Beamformer Information -+ MM_BFMER_ENABLE_REQ, -+ /// Request to Start/Stop/Update NOA - GO Only -+ MM_SET_P2P_NOA_REQ, -+ /// Request to Start/Stop/Update Opportunistic PS - GO Only -+ MM_SET_P2P_OPPPS_REQ, -+ /// Start/Stop/Update NOA Confirmation -+ MM_SET_P2P_NOA_CFM, -+ /// Start/Stop/Update Opportunistic PS Confirmation -+ MM_SET_P2P_OPPPS_CFM, -+ /// P2P NoA Update Indication - GO Only -+ MM_P2P_NOA_UPD_IND, -+ /// Request to set RSSI threshold and RSSI hysteresis -+ MM_CFG_RSSI_REQ, -+ /// Indication that RSSI level is below or above the threshold -+ MM_RSSI_STATUS_IND, -+ /// Indication that CSA is done -+ MM_CSA_FINISH_IND, -+ /// Indication that CSA is in prorgess (resp. done) and traffic must be stopped (resp. restarted) -+ MM_CSA_TRAFFIC_IND, -+ /// Request to update the group information of a station -+ MM_MU_GROUP_UPDATE_REQ, -+ /// Confirmation of the @ref MM_MU_GROUP_UPDATE_REQ message -+ MM_MU_GROUP_UPDATE_CFM, -+ -+ /// MAX number of messages -+ MM_MAX, -+}; -+ -+/// Interface types -+enum -+{ -+ /// ESS STA interface -+ MM_STA, -+ /// IBSS STA interface -+ MM_IBSS, -+ /// AP interface -+ MM_AP, -+ // Mesh Point interface -+ MM_MESH_POINT, -+}; -+ -+///BA agreement types -+enum -+{ -+ ///BlockAck agreement for TX -+ BA_AGMT_TX, -+ ///BlockAck agreement for RX -+ BA_AGMT_RX, -+}; -+ -+///BA agreement related status -+enum -+{ -+ ///Correct BA agreement establishment -+ BA_AGMT_ESTABLISHED, -+ ///BA agreement already exists for STA+TID requested, cannot override it (should have been deleted first) -+ BA_AGMT_ALREADY_EXISTS, -+ ///Correct BA agreement deletion -+ BA_AGMT_DELETED, -+ ///BA agreement for the (STA, TID) doesn't exist so nothing to delete -+ BA_AGMT_DOESNT_EXIST, -+}; -+ -+/// Features supported by LMAC - Positions -+enum mm_features -+{ -+ /// Beaconing -+ MM_FEAT_BCN_BIT = 0, -+ /// Autonomous Beacon Transmission -+ MM_FEAT_AUTOBCN_BIT, -+ /// Scan in LMAC -+ MM_FEAT_HWSCAN_BIT, -+ /// Connection Monitoring -+ MM_FEAT_CMON_BIT, -+ /// Multi Role -+ MM_FEAT_MROLE_BIT, -+ /// Radar Detection -+ MM_FEAT_RADAR_BIT, -+ /// Power Save -+ MM_FEAT_PS_BIT, -+ /// UAPSD -+ MM_FEAT_UAPSD_BIT, -+ /// DPSM -+ MM_FEAT_DPSM_BIT, -+ /// A-MPDU -+ MM_FEAT_AMPDU_BIT, -+ /// A-MSDU -+ MM_FEAT_AMSDU_BIT, -+ /// Channel Context -+ MM_FEAT_CHNL_CTXT_BIT, -+ /// Packet reordering -+ MM_FEAT_REORD_BIT, -+ /// P2P -+ MM_FEAT_P2P_BIT, -+ /// P2P Go -+ MM_FEAT_P2P_GO_BIT, -+ /// UMAC Present -+ MM_FEAT_UMAC_BIT, -+ /// VHT support -+ MM_FEAT_VHT_BIT, -+ /// Beamformee -+ MM_FEAT_BFMEE_BIT, -+ /// Beamformer -+ MM_FEAT_BFMER_BIT, -+ /// WAPI -+ MM_FEAT_WAPI_BIT, -+ /// MFP -+ MM_FEAT_MFP_BIT, -+}; -+ -+/// Maximum number of words in the configuration buffer -+#define PHY_CFG_BUF_SIZE 16 -+ -+/// Structure containing the parameters of the PHY configuration -+struct phy_cfg_tag -+{ -+ /// Buffer containing the parameters specific for the PHY used -+ u32_l parameters[PHY_CFG_BUF_SIZE]; -+}; -+ -+/// Structure containing the parameters of the Trident PHY configuration -+struct phy_trd_cfg_tag -+{ -+ /// MDM type(nxm)(upper nibble) and MDM2RF path mapping(lower nibble) -+ u8_l path_mapping; -+ /// TX DC offset compensation -+ u32_l tx_dc_off_comp; -+}; -+ -+/// Structure containing the parameters of the Karst PHY configuration -+struct phy_karst_cfg_tag -+{ -+ /// TX IQ mismatch compensation in 2.4GHz -+ u32_l tx_iq_comp_2_4G[2]; -+ /// RX IQ mismatch compensation in 2.4GHz -+ u32_l rx_iq_comp_2_4G[2]; -+ /// TX IQ mismatch compensation in 5GHz -+ u32_l tx_iq_comp_5G[2]; -+ /// RX IQ mismatch compensation in 5GHz -+ u32_l rx_iq_comp_5G[2]; -+ /// RF path used by default (0 or 1) -+ u8_l path_used; -+}; -+ -+/// Structure containing the parameters of the @ref MM_START_REQ message -+struct mm_start_req -+{ -+ /// PHY configuration -+ struct phy_cfg_tag phy_cfg; -+ /// UAPSD timeout -+ u32_l uapsd_timeout; -+ /// Local LP clock accuracy (in ppm) -+ u16_l lp_clk_accuracy; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_CHANNEL_REQ message -+struct mm_set_channel_req -+{ -+ /// Band (2.4GHz or 5GHz) -+ u8_l band; -+ /// Channel type: 20,40,80,160 or 80+80 MHz -+ u8_l type; -+ /// Frequency for Primary 20MHz channel (in MHz) -+ u16_l prim20_freq; -+ /// Frequency for Center of the contiguous channel or center of Primary 80+80 -+ u16_l center1_freq; -+ /// Frequency for Center of the non-contiguous secondary 80+80 -+ u16_l center2_freq; -+ /// Index of the RF for which the channel has to be set (0: operating (primary), 1: secondary -+ /// RF (used for additional radar detection). This parameter is reserved if no secondary RF -+ /// is available in the system -+ u8_l index; -+ /// Max tx power for this channel -+ s8_l tx_power; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_CHANNEL_CFM message -+struct mm_set_channel_cfm -+{ -+ /// Radio index to be used in policy table -+ u8_l radio_idx; -+ /// TX power configured (in dBm) -+ s8_l power; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_DTIM_REQ message -+struct mm_set_dtim_req -+{ -+ /// DTIM period -+ u8_l dtim_period; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_POWER_REQ message -+struct mm_set_power_req -+{ -+ /// Index of the interface for which the parameter is configured -+ u8_l inst_nbr; -+ /// TX power (in dBm) -+ s8_l power; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_POWER_CFM message -+struct mm_set_power_cfm -+{ -+ /// Radio index to be used in policy table -+ u8_l radio_idx; -+ /// TX power configured (in dBm) -+ s8_l power; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_BEACON_INT_REQ message -+struct mm_set_beacon_int_req -+{ -+ /// Beacon interval -+ u16_l beacon_int; -+ /// Index of the interface for which the parameter is configured -+ u8_l inst_nbr; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_BASIC_RATES_REQ message -+struct mm_set_basic_rates_req -+{ -+ /// Basic rate set (as expected by bssBasicRateSet field of Rates MAC HW register) -+ u32_l rates; -+ /// Index of the interface for which the parameter is configured -+ u8_l inst_nbr; -+ /// Band on which the interface will operate -+ u8_l band; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_BSSID_REQ message -+struct mm_set_bssid_req -+{ -+ /// BSSID to be configured in HW -+ struct mac_addr bssid; -+ /// Index of the interface for which the parameter is configured -+ u8_l inst_nbr; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_FILTER_REQ message -+struct mm_set_filter_req -+{ -+ /// RX filter to be put into rxCntrlReg HW register -+ u32_l filter; -+}; -+ -+/// Structure containing the parameters of the @ref MM_ADD_IF_REQ message. -+struct mm_add_if_req -+{ -+ /// Type of the interface (AP, STA, ADHOC, ...) -+ u8_l type; -+ /// MAC ADDR of the interface to start -+ struct mac_addr addr; -+ /// P2P Interface -+ bool_l p2p; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_EDCA_REQ message -+struct mm_set_edca_req -+{ -+ /// EDCA parameters of the queue (as expected by edcaACxReg HW register) -+ u32_l ac_param; -+ /// Flag indicating if UAPSD can be used on this queue -+ bool_l uapsd; -+ /// HW queue for which the parameters are configured -+ u8_l hw_queue; -+ /// Index of the interface for which the parameters are configured -+ u8_l inst_nbr; -+}; -+ -+struct mm_set_idle_req -+{ -+ u8_l hw_idle; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_SLOTTIME_REQ message -+struct mm_set_slottime_req -+{ -+ /// Slot time expressed in us -+ u8_l slottime; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_MODE_REQ message -+struct mm_set_mode_req -+{ -+ /// abgnMode field of macCntrl1Reg register -+ u8_l abgnmode; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_VIF_STATE_REQ message -+struct mm_set_vif_state_req -+{ -+ /// Association Id received from the AP (valid only if the VIF is of STA type) -+ u16_l aid; -+ /// Flag indicating if the VIF is active or not -+ bool_l active; -+ /// Interface index -+ u8_l inst_nbr; -+}; -+ -+/// Structure containing the parameters of the @ref MM_ADD_IF_CFM message. -+struct mm_add_if_cfm -+{ -+ /// Status of operation (different from 0 if unsuccessful) -+ u8_l status; -+ /// Interface index assigned by the LMAC -+ u8_l inst_nbr; -+}; -+ -+/// Structure containing the parameters of the @ref MM_REMOVE_IF_REQ message. -+struct mm_remove_if_req -+{ -+ /// Interface index assigned by the LMAC -+ u8_l inst_nbr; -+}; -+ -+/// Structure containing the parameters of the @ref MM_VERSION_CFM message. -+struct mm_version_cfm -+{ -+ /// Version of the LMAC FW -+ u32_l version_lmac; -+ /// Version1 of the MAC HW (as encoded in version1Reg MAC HW register) -+ u32_l version_machw_1; -+ /// Version2 of the MAC HW (as encoded in version2Reg MAC HW register) -+ u32_l version_machw_2; -+ /// Version1 of the PHY (depends on actual PHY) -+ u32_l version_phy_1; -+ /// Version2 of the PHY (depends on actual PHY) -+ u32_l version_phy_2; -+ /// Supported Features -+ u32_l features; -+}; -+ -+/// Structure containing the parameters of the @ref MM_STA_ADD_REQ message. -+struct mm_sta_add_req -+{ -+ /// Maximum A-MPDU size, in bytes, for VHT frames -+ u32_l ampdu_size_max_vht; -+ /// PAID/GID -+ u32_l paid_gid; -+ /// Maximum A-MPDU size, in bytes, for HT frames -+ u16_l ampdu_size_max_ht; -+ /// MAC address of the station to be added -+ struct mac_addr mac_addr; -+ /// A-MPDU spacing, in us -+ u8_l ampdu_spacing_min; -+ /// Interface index -+ u8_l inst_nbr; -+ /// TDLS station -+ bool_l tdls_sta; -+}; -+ -+/// Structure containing the parameters of the @ref MM_STA_ADD_CFM message. -+struct mm_sta_add_cfm -+{ -+ /// Status of the operation (different from 0 if unsuccessful) -+ u8_l status; -+ /// Index assigned by the LMAC to the newly added station -+ u8_l sta_idx; -+ /// MAC HW index of the newly added station -+ u8_l hw_sta_idx; -+}; -+ -+/// Structure containing the parameters of the @ref MM_STA_DEL_REQ message. -+struct mm_sta_del_req -+{ -+ /// Index of the station to be deleted -+ u8_l sta_idx; -+}; -+ -+/// Structure containing the parameters of the @ref MM_STA_DEL_CFM message. -+struct mm_sta_del_cfm -+{ -+ /// Status of the operation (different from 0 if unsuccessful) -+ u8_l status; -+}; -+ -+/// Structure containing the parameters of the SET_POWER_MODE REQ message. -+struct mm_setpowermode_req -+{ -+ u8_l mode; -+ u8_l sta_idx; -+}; -+ -+/// Structure containing the parameters of the SET_POWER_MODE CFM message. -+struct mm_setpowermode_cfm -+{ -+ u8_l status; -+}; -+ -+/// Structure containing the parameters of the @ref MM_KEY_ADD REQ message. -+struct mm_key_add_req -+{ -+ /// Key index (valid only for default keys) -+ u8_l key_idx; -+ /// STA index (valid only for pairwise or mesh group keys) -+ u8_l sta_idx; -+ /// Key material -+ struct mac_sec_key key; -+ /// Cipher suite (WEP64, WEP128, TKIP, CCMP) -+ u8_l cipher_suite; -+ /// Index of the interface for which the key is set (valid only for default keys or mesh group keys) -+ u8_l inst_nbr; -+ /// A-MSDU SPP parameter -+ u8_l spp; -+ /// Indicate if provided key is a pairwise key or not -+ bool_l pairwise; -+}; -+ -+/// Structure containing the parameters of the @ref MM_KEY_ADD_CFM message. -+struct mm_key_add_cfm -+{ -+ /// Status of the operation (different from 0 if unsuccessful) -+ u8_l status; -+ /// HW index of the key just added -+ u8_l hw_key_idx; -+}; -+ -+/// Structure containing the parameters of the @ref MM_KEY_DEL_REQ message. -+struct mm_key_del_req -+{ -+ /// HW index of the key to be deleted -+ u8_l hw_key_idx; -+}; -+ -+/// Structure containing the parameters of the @ref MM_BA_ADD_REQ message. -+struct mm_ba_add_req -+{ -+ ///Type of agreement (0: TX, 1: RX) -+ u8_l type; -+ ///Index of peer station with which the agreement is made -+ u8_l sta_idx; -+ ///TID for which the agreement is made with peer station -+ u8_l tid; -+ ///Buffer size - number of MPDUs that can be held in its buffer per TID -+ u8_l bufsz; -+ /// Start sequence number negotiated during BA setup - the one in first aggregated MPDU counts more -+ u16_l ssn; -+}; -+ -+/// Structure containing the parameters of the @ref MM_BA_ADD_CFM message. -+struct mm_ba_add_cfm -+{ -+ ///Index of peer station for which the agreement is being confirmed -+ u8_l sta_idx; -+ ///TID for which the agreement is being confirmed -+ u8_l tid; -+ /// Status of ba establishment -+ u8_l status; -+}; -+ -+/// Structure containing the parameters of the @ref MM_BA_DEL_REQ message. -+struct mm_ba_del_req -+{ -+ ///Type of agreement (0: TX, 1: RX) -+ u8_l type; -+ ///Index of peer station for which the agreement is being deleted -+ u8_l sta_idx; -+ ///TID for which the agreement is being deleted -+ u8_l tid; -+}; -+ -+/// Structure containing the parameters of the @ref MM_BA_DEL_CFM message. -+struct mm_ba_del_cfm -+{ -+ ///Index of peer station for which the agreement deletion is being confirmed -+ u8_l sta_idx; -+ ///TID for which the agreement deletion is being confirmed -+ u8_l tid; -+ /// Status of ba deletion -+ u8_l status; -+}; -+ -+/// Structure containing the parameters of the @ref MM_CHAN_CTXT_ADD_REQ message -+struct mm_chan_ctxt_add_req -+{ -+ /// Band (2.4GHz or 5GHz) -+ u8_l band; -+ /// Channel type: 20,40,80,160 or 80+80 MHz -+ u8_l type; -+ /// Frequency for Primary 20MHz channel (in MHz) -+ u16_l prim20_freq; -+ /// Frequency for Center of the contiguous channel or center of Primary 80+80 -+ u16_l center1_freq; -+ /// Frequency for Center of the non-contiguous secondary 80+80 -+ u16_l center2_freq; -+ /// Max tx power for this channel -+ s8_l tx_power; -+}; -+ -+/// Structure containing the parameters of the @ref MM_CHAN_CTXT_ADD_REQ message -+struct mm_chan_ctxt_add_cfm -+{ -+ /// Status of the addition -+ u8_l status; -+ /// Index of the new channel context -+ u8_l index; -+}; -+ -+ -+/// Structure containing the parameters of the @ref MM_CHAN_CTXT_DEL_REQ message -+struct mm_chan_ctxt_del_req -+{ -+ /// Index of the new channel context to be deleted -+ u8_l index; -+}; -+ -+ -+/// Structure containing the parameters of the @ref MM_CHAN_CTXT_LINK_REQ message -+struct mm_chan_ctxt_link_req -+{ -+ /// VIF index -+ u8_l vif_index; -+ /// Channel context index -+ u8_l chan_index; -+ /// Indicate if this is a channel switch (unlink current ctx first if true) -+ u8_l chan_switch; -+}; -+ -+/// Structure containing the parameters of the @ref MM_CHAN_CTXT_UNLINK_REQ message -+struct mm_chan_ctxt_unlink_req -+{ -+ /// VIF index -+ u8_l vif_index; -+}; -+ -+/// Structure containing the parameters of the @ref MM_CHAN_CTXT_UPDATE_REQ message -+struct mm_chan_ctxt_update_req -+{ -+ /// Channel context index -+ u8_l chan_index; -+ /// Band (2.4GHz or 5GHz) -+ u8_l band; -+ /// Channel type: 20,40,80,160 or 80+80 MHz -+ u8_l type; -+ /// Frequency for Primary 20MHz channel (in MHz) -+ u16_l prim20_freq; -+ /// Frequency for Center of the contiguous channel or center of Primary 80+80 -+ u16_l center1_freq; -+ /// Frequency for Center of the non-contiguous secondary 80+80 -+ u16_l center2_freq; -+}; -+ -+/// Structure containing the parameters of the @ref MM_CHAN_CTXT_SCHED_REQ message -+struct mm_chan_ctxt_sched_req -+{ -+ /// VIF index -+ u8_l vif_index; -+ /// Channel context index -+ u8_l chan_index; -+ /// Type of the scheduling request (0: normal scheduling, 1: derogatory -+ /// scheduling) -+ u8_l type; -+}; -+ -+/// Structure containing the parameters of the @ref MM_CHANNEL_SWITCH_IND message -+struct mm_channel_switch_ind -+{ -+ /// Index of the channel context we will switch to -+ u8_l chan_index; -+ /// Indicate if the switch has been triggered by a Remain on channel request -+ bool_l roc; -+ /// VIF on which remain on channel operation has been started (if roc == 1) -+ u8_l vif_index; -+ /// Indicate if the switch has been triggered by a TDLS Remain on channel request -+ bool_l roc_tdls; -+}; -+ -+/// Structure containing the parameters of the @ref MM_CHANNEL_PRE_SWITCH_IND message -+struct mm_channel_pre_switch_ind -+{ -+ /// Index of the channel context we will switch to -+ u8_l chan_index; -+}; -+ -+/// Structure containing the parameters of the @ref MM_CONNECTION_LOSS_IND message. -+struct mm_connection_loss_ind -+{ -+ /// VIF instance number -+ u8_l inst_nbr; -+}; -+ -+ -+/// Structure containing the parameters of the @ref MM_DBG_TRIGGER_REQ message. -+struct mm_dbg_trigger_req -+{ -+ /// Error trace to be reported by the LMAC -+ char error[64]; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_PS_MODE_REQ message. -+struct mm_set_ps_mode_req -+{ -+ /// Power Save is activated or deactivated -+ u8_l new_state; -+}; -+ -+/// Structure containing the parameters of the @ref MM_BCN_CHANGE_REQ message. -+#define BCN_MAX_CSA_CPT 2 -+struct mm_bcn_change_req -+{ -+ /// Pointer, in host memory, to the new beacon template -+ u32_l bcn_ptr; -+ /// Length of the beacon template -+ u16_l bcn_len; -+ /// Offset of the TIM IE in the beacon -+ u16_l tim_oft; -+ /// Length of the TIM IE -+ u8_l tim_len; -+ /// Index of the VIF for which the beacon is updated -+ u8_l inst_nbr; -+ /// Offset of CSA (channel switch announcement) counters (0 means no counter) -+ u8_l csa_oft[BCN_MAX_CSA_CPT]; -+ /// -+ u8_l bcn_buf[]; -+}; -+ -+ -+/// Structure containing the parameters of the @ref MM_TIM_UPDATE_REQ message. -+struct mm_tim_update_req -+{ -+ /// Association ID of the STA the bit of which has to be updated (0 for BC/MC traffic) -+ u16_l aid; -+ /// Flag indicating the availability of data packets for the given STA -+ u8_l tx_avail; -+ /// Index of the VIF for which the TIM is updated -+ u8_l inst_nbr; -+}; -+ -+/// Structure containing the parameters of the @ref MM_REMAIN_ON_CHANNEL_REQ message. -+struct mm_remain_on_channel_req -+{ -+ /// Operation Code -+ u8_l op_code; -+ /// VIF Index -+ u8_l vif_index; -+ /// Band (2.4GHz or 5GHz) -+ u8_l band; -+ /// Channel type: 20,40,80,160 or 80+80 MHz -+ u8_l type; -+ /// Frequency for Primary 20MHz channel (in MHz) -+ u16_l prim20_freq; -+ /// Frequency for Center of the contiguous channel or center of Primary 80+80 -+ u16_l center1_freq; -+ /// Frequency for Center of the non-contiguous secondary 80+80 -+ u16_l center2_freq; -+ /// Duration (in ms) -+ u32_l duration_ms; -+ /// TX power (in dBm) -+ s8_l tx_power; -+}; -+ -+/// Structure containing the parameters of the @ref MM_REMAIN_ON_CHANNEL_CFM message -+struct mm_remain_on_channel_cfm -+{ -+ /// Operation Code -+ u8_l op_code; -+ /// Status of the operation -+ u8_l status; -+ /// Channel Context index -+ u8_l chan_ctxt_index; -+}; -+ -+/// Structure containing the parameters of the @ref MM_REMAIN_ON_CHANNEL_EXP_IND message -+struct mm_remain_on_channel_exp_ind -+{ -+ /// VIF Index -+ u8_l vif_index; -+ /// Channel Context index -+ u8_l chan_ctxt_index; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_UAPSD_TMR_REQ message. -+struct mm_set_uapsd_tmr_req -+{ -+ /// action: Start or Stop the timer -+ u8_l action; -+ /// timeout value, in milliseconds -+ u32_l timeout; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_UAPSD_TMR_CFM message. -+struct mm_set_uapsd_tmr_cfm -+{ -+ /// Status of the operation (different from 0 if unsuccessful) -+ u8_l status; -+}; -+ -+ -+/// Structure containing the parameters of the @ref MM_PS_CHANGE_IND message -+struct mm_ps_change_ind -+{ -+ /// Index of the peer device that is switching its PS state -+ u8_l sta_idx; -+ /// New PS state of the peer device (0: active, 1: sleeping) -+ u8_l ps_state; -+}; -+ -+/// Structure containing the parameters of the @ref MM_P2P_VIF_PS_CHANGE_IND message -+struct mm_p2p_vif_ps_change_ind -+{ -+ /// Index of the P2P VIF that is switching its PS state -+ u8_l vif_index; -+ /// New PS state of the P2P VIF interface (0: active, 1: sleeping) -+ u8_l ps_state; -+}; -+ -+/// Structure containing the parameters of the @ref MM_TRAFFIC_REQ_IND message -+struct mm_traffic_req_ind -+{ -+ /// Index of the peer device that needs traffic -+ u8_l sta_idx; -+ /// Number of packets that need to be sent (if 0, all buffered traffic shall be sent) -+ u8_l pkt_cnt; -+ /// Flag indicating if the traffic request concerns U-APSD queues or not -+ bool_l uapsd; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_PS_OPTIONS_REQ message. -+struct mm_set_ps_options_req -+{ -+ /// VIF Index -+ u8_l vif_index; -+ /// Listen interval (0 if wake up shall be based on DTIM period) -+ u16_l listen_interval; -+ /// Flag indicating if we shall listen the BC/MC traffic or not -+ bool_l dont_listen_bc_mc; -+}; -+ -+/// Structure containing the parameters of the @ref MM_CSA_COUNTER_IND message -+struct mm_csa_counter_ind -+{ -+ /// Index of the VIF -+ u8_l vif_index; -+ /// Updated CSA counter value -+ u8_l csa_count; -+}; -+ -+/// Structure containing the parameters of the @ref MM_CHANNEL_SURVEY_IND message -+struct mm_channel_survey_ind -+{ -+ /// Frequency of the channel -+ u16_l freq; -+ /// Noise in dbm -+ s8_l noise_dbm; -+ /// Amount of time spent of the channel (in ms) -+ u32_l chan_time_ms; -+ /// Amount of time the primary channel was sensed busy -+ u32_l chan_time_busy_ms; -+}; -+ -+/// Structure containing the parameters of the @ref MM_BFMER_ENABLE_REQ message. -+struct mm_bfmer_enable_req -+{ -+ /** -+ * Address of Beamforming Report in host memory -+ * (Valid only if vht_su_bfmee is true) -+ */ -+ u32_l host_bfr_addr; -+ /// AID -+ u16_l aid; -+ /// Station Index -+ u8_l sta_idx; -+ /// Maximum number of spatial streams the station can receive -+ u8_l rx_nss; -+ /** -+ * Indicate if peer STA is MU Beamformee (VHT) capable -+ * (Valid only if vht_su_bfmee is true) -+ */ -+ bool_l vht_mu_bfmee; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_P2P_NOA_REQ message. -+struct mm_set_p2p_noa_req -+{ -+ /// VIF Index -+ u8_l vif_index; -+ /// Allocated NOA Instance Number - Valid only if count = 0 -+ u8_l noa_inst_nb; -+ /// Count -+ u8_l count; -+ /// Indicate if NoA can be paused for traffic reason -+ bool_l dyn_noa; -+ /// Duration (in us) -+ u32_l duration_us; -+ /// Interval (in us) -+ u32_l interval_us; -+ /// Start Time offset from next TBTT (in us) -+ u32_l start_offset; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_P2P_OPPPS_REQ message. -+struct mm_set_p2p_oppps_req -+{ -+ /// VIF Index -+ u8_l vif_index; -+ /// CTWindow -+ u8_l ctwindow; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_P2P_NOA_CFM message. -+struct mm_set_p2p_noa_cfm -+{ -+ /// Request status -+ u8_l status; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_P2P_OPPPS_CFM message. -+struct mm_set_p2p_oppps_cfm -+{ -+ /// Request status -+ u8_l status; -+}; -+ -+/// Structure containing the parameters of the @ref MM_P2P_NOA_UPD_IND message. -+struct mm_p2p_noa_upd_ind -+{ -+ /// VIF Index -+ u8_l vif_index; -+ /// NOA Instance Number -+ u8_l noa_inst_nb; -+ /// NoA Type -+ u8_l noa_type; -+ /// Count -+ u8_l count; -+ /// Duration (in us) -+ u32_l duration_us; -+ /// Interval (in us) -+ u32_l interval_us; -+ /// Start Time -+ u32_l start_time; -+}; -+ -+/// Structure containing the parameters of the @ref MM_CFG_RSSI_REQ message -+struct mm_cfg_rssi_req -+{ -+ /// Index of the VIF -+ u8_l vif_index; -+ /// RSSI threshold -+ s8_l rssi_thold; -+ /// RSSI hysteresis -+ u8_l rssi_hyst; -+}; -+ -+/// Structure containing the parameters of the @ref MM_RSSI_STATUS_IND message -+struct mm_rssi_status_ind -+{ -+ /// Index of the VIF -+ u8_l vif_index; -+ /// Status of the RSSI -+ bool_l rssi_status; -+ /// Current RSSI -+ s8_l rssi; -+}; -+ -+/// Structure containing the parameters of the @ref MM_CSA_FINISH_IND message -+struct mm_csa_finish_ind -+{ -+ /// Index of the VIF -+ u8_l vif_index; -+ /// Status of the operation -+ u8_l status; -+ /// New channel ctx index -+ u8_l chan_idx; -+}; -+ -+/// Structure containing the parameters of the @ref MM_CSA_TRAFFIC_IND message -+struct mm_csa_traffic_ind -+{ -+ /// Index of the VIF -+ u8_l vif_index; -+ /// Is tx traffic enable or disable -+ bool_l enable; -+}; -+ -+/// Structure containing the parameters of the @ref MM_MU_GROUP_UPDATE_REQ message. -+/// Size allocated for the structure depends of the number of group -+struct mm_mu_group_update_req -+{ -+ /// Station index -+ u8_l sta_idx; -+ /// Number of groups the STA belongs to -+ u8_l group_cnt; -+ /// Group information -+ struct -+ { -+ /// Group Id -+ u8_l group_id; -+ /// User position -+ u8_l user_pos; -+ } groups[0]; -+}; -+ -+/////////////////////////////////////////////////////////////////////////////// -+/////////// For Scan messages -+/////////////////////////////////////////////////////////////////////////////// -+enum scan_msg_tag -+{ -+ /// Scanning start Request. -+ SCAN_START_REQ = LMAC_FIRST_MSG(TASK_SCAN), -+ /// Scanning start Confirmation. -+ SCAN_START_CFM, -+ /// End of scanning indication. -+ SCAN_DONE_IND, -+ /// Cancel scan request -+ SCAN_CANCEL_REQ, -+ /// Cancel scan confirmation -+ SCAN_CANCEL_CFM, -+ -+ /// MAX number of messages -+ SCAN_MAX, -+}; -+ -+/// Maximum number of SSIDs in a scan request -+#define SCAN_SSID_MAX 2 -+ -+/// Maximum number of 2.4GHz channels -+#define SCAN_CHANNEL_2G4 14 -+ -+/// Maximum number of 5GHz channels -+#define SCAN_CHANNEL_5G 28 -+ -+/// Maximum number of channels in a scan request -+#define SCAN_CHANNEL_MAX (SCAN_CHANNEL_2G4 + SCAN_CHANNEL_5G) -+ -+/// Flag bits -+#define SCAN_PASSIVE_BIT BIT(0) -+#define SCAN_DISABLED_BIT BIT(1) -+ -+/// Maximum number of PHY bands supported -+#define SCAN_BAND_MAX 2 -+ -+/// Definition of a channel to be scanned -+struct scan_chan_tag -+{ -+ /// Frequency of the channel -+ u16_l freq; -+ /// RF band (0: 2.4GHz, 1: 5GHz) -+ u8_l band; -+ /// Bit field containing additional information about the channel -+ u8_l flags; -+ /// Max tx_power for this channel (dBm) -+ s8_l tx_power; -+}; -+ -+/// Structure containing the parameters of the @ref SCAN_START_REQ message -+struct scan_start_req -+{ -+ /// List of channel to be scanned -+ struct scan_chan_tag chan[SCAN_CHANNEL_MAX]; -+ /// List of SSIDs to be scanned -+ struct mac_ssid ssid[SCAN_SSID_MAX]; -+ /// BSSID to be scanned -+ struct mac_addr bssid; -+ /// Pointer (in host memory) to the additional IEs that need to be added to the ProbeReq -+ /// (following the SSID element) -+ u32_l add_ies; -+ /// Length of the additional IEs -+ u16_l add_ie_len; -+ /// Index of the VIF that is scanning -+ u8_l vif_idx; -+ /// Number of channels to scan -+ u8_l chan_cnt; -+ /// Number of SSIDs to scan for -+ u8_l ssid_cnt; -+ /// no CCK - For P2P frames not being sent at CCK rate in 2GHz band. -+ bool no_cck; -+}; -+ -+/// Structure containing the parameters of the @ref SCAN_START_CFM message -+struct scan_start_cfm -+{ -+ /// Status of the request -+ u8_l status; -+}; -+ -+/// Structure containing the parameters of the @ref SCAN_CANCEL_REQ message -+struct scan_cancel_req -+{ -+}; -+ -+/// Structure containing the parameters of the @ref SCAN_START_CFM message -+struct scan_cancel_cfm -+{ -+ /// Status of the request -+ u8_l status; -+}; -+ -+/////////////////////////////////////////////////////////////////////////////// -+/////////// For Scanu messages -+/////////////////////////////////////////////////////////////////////////////// -+/// Messages that are logically related to the task. -+enum -+{ -+ /// Scan request from host. -+ SCANU_START_REQ = LMAC_FIRST_MSG(TASK_SCANU), -+ /// Scanning start Confirmation. -+ SCANU_START_CFM, -+ /// Join request -+ SCANU_JOIN_REQ, -+ /// Join confirmation. -+ SCANU_JOIN_CFM, -+ /// Scan result indication. -+ SCANU_RESULT_IND, -+ /// Fast scan request from any other module. -+ SCANU_FAST_REQ, -+ /// Confirmation of fast scan request. -+ SCANU_FAST_CFM, -+ -+ /// MAX number of messages -+ SCANU_MAX, -+}; -+ -+/// Structure containing the parameters of the @ref SCANU_START_REQ message -+struct scanu_start_req -+{ -+ /// List of channel to be scanned -+ struct scan_chan_tag chan[SCAN_CHANNEL_MAX]; -+ /// List of SSIDs to be scanned -+ struct mac_ssid ssid[SCAN_SSID_MAX]; -+ /// BSSID to be scanned (or WILDCARD BSSID if no BSSID is searched in particular) -+ struct mac_addr bssid; -+ /// Address (in host memory) of the additional IEs that need to be added to the ProbeReq -+ /// (following the SSID element) -+ u32_l add_ies; -+ /// Length of the additional IEs -+ u16_l add_ie_len; -+ /// Index of the VIF that is scanning -+ u8_l vif_idx; -+ /// Number of channels to scan -+ u8_l chan_cnt; -+ /// Number of SSIDs to scan for -+ u8_l ssid_cnt; -+ /// no CCK - For P2P frames not being sent at CCK rate in 2GHz band. -+ bool no_cck; -+ ///buf for storing additional IEs -+ u8_l add_ies_buf[]; -+}; -+ -+/// Structure containing the parameters of the @ref SCANU_START_CFM message -+struct scanu_start_cfm -+{ -+ /// Status of the request -+ u8_l status; -+}; -+ -+/// Parameters of the @SCANU_RESULT_IND message -+struct scanu_result_ind -+{ -+ /// Length of the frame -+ u16_l length; -+ /// Frame control field of the frame. -+ u16_l framectrl; -+ /// Center frequency on which we received the packet -+ u16_l center_freq; -+ /// PHY band -+ u8_l band; -+ /// Index of the station that sent the frame. 0xFF if unknown. -+ u8_l sta_idx; -+ /// Index of the VIF that received the frame. 0xFF if unknown. -+ u8_l inst_nbr; -+ /// RSSI of the received frame. -+ s8_l rssi; -+ /// Frame payload. -+ u32_l payload[]; -+}; -+ -+/// Structure containing the parameters of the message. -+struct scanu_fast_req -+{ -+ /// The SSID to scan in the channel. -+ struct mac_ssid ssid; -+ /// BSSID. -+ struct mac_addr bssid; -+ /// Probe delay. -+ u16_l probe_delay; -+ /// Minimum channel time. -+ u16_l minch_time; -+ /// Maximum channel time. -+ u16_l maxch_time; -+ /// The channel number to scan. -+ u16_l ch_nbr; -+}; -+ -+/////////////////////////////////////////////////////////////////////////////// -+/////////// For ME messages -+/////////////////////////////////////////////////////////////////////////////// -+/// Messages that are logically related to the task. -+enum -+{ -+ /// Configuration request from host. -+ ME_CONFIG_REQ = LMAC_FIRST_MSG(TASK_ME), -+ /// Configuration confirmation. -+ ME_CONFIG_CFM, -+ /// Configuration request from host. -+ ME_CHAN_CONFIG_REQ, -+ /// Configuration confirmation. -+ ME_CHAN_CONFIG_CFM, -+ /// Set control port state for a station. -+ ME_SET_CONTROL_PORT_REQ, -+ /// Control port setting confirmation. -+ ME_SET_CONTROL_PORT_CFM, -+ /// TKIP MIC failure indication. -+ ME_TKIP_MIC_FAILURE_IND, -+ /// Add a station to the FW (AP mode) -+ ME_STA_ADD_REQ, -+ /// Confirmation of the STA addition -+ ME_STA_ADD_CFM, -+ /// Delete a station from the FW (AP mode) -+ ME_STA_DEL_REQ, -+ /// Confirmation of the STA deletion -+ ME_STA_DEL_CFM, -+ /// Indication of a TX RA/TID queue credit update -+ ME_TX_CREDITS_UPDATE_IND, -+ /// Request indicating to the FW that there is traffic buffered on host -+ ME_TRAFFIC_IND_REQ, -+ /// Confirmation that the @ref ME_TRAFFIC_IND_REQ has been executed -+ ME_TRAFFIC_IND_CFM, -+ /// Request of RC statistics to a station -+ ME_RC_STATS_REQ, -+ /// RC statistics confirmation -+ ME_RC_STATS_CFM, -+ /// RC fixed rate request -+ ME_RC_SET_RATE_REQ, -+ /// MAX number of messages -+ ME_MAX, -+}; -+ -+/// Structure containing the parameters of the @ref ME_START_REQ message -+struct me_config_req -+{ -+ /// HT Capabilities -+ struct mac_htcapability ht_cap; -+ /// VHT Capabilities -+ struct mac_vhtcapability vht_cap; -+ /// Lifetime of packets sent under a BlockAck agreement (expressed in TUs) -+ u16_l tx_lft; -+ /// Boolean indicating if HT is supported or not -+ bool_l ht_supp; -+ /// Boolean indicating if VHT is supported or not -+ bool_l vht_supp; -+ /// Boolean indicating if PS mode shall be enabled or not -+ bool_l ps_on; -+}; -+ -+/// Structure containing the parameters of the @ref ME_CHAN_CONFIG_REQ message -+struct me_chan_config_req -+{ -+ /// List of 2.4GHz supported channels -+ struct scan_chan_tag chan2G4[SCAN_CHANNEL_2G4]; -+ /// List of 5GHz supported channels -+ struct scan_chan_tag chan5G[SCAN_CHANNEL_5G]; -+ /// Number of 2.4GHz channels in the list -+ u8_l chan2G4_cnt; -+ /// Number of 5GHz channels in the list -+ u8_l chan5G_cnt; -+}; -+ -+/// Structure containing the parameters of the @ref ME_SET_CONTROL_PORT_REQ message -+struct me_set_control_port_req -+{ -+ /// Index of the station for which the control port is opened -+ u8_l sta_idx; -+ /// Control port state -+ bool_l control_port_open; -+}; -+ -+/// Structure containing the parameters of the @ref ME_TKIP_MIC_FAILURE_IND message -+struct me_tkip_mic_failure_ind -+{ -+ /// Address of the sending STA -+ struct mac_addr addr; -+ /// TSC value -+ u64_l tsc; -+ /// Boolean indicating if the packet was a group or unicast one (true if group) -+ bool_l ga; -+ /// Key Id -+ u8_l keyid; -+ /// VIF index -+ u8_l vif_idx; -+}; -+ -+/// Structure containing the parameters of the @ref ME_STA_ADD_REQ message -+struct me_sta_add_req -+{ -+ /// MAC address of the station to be added -+ struct mac_addr mac_addr; -+ /// Supported legacy rates -+ struct mac_rateset rate_set; -+ /// HT Capabilities -+ struct mac_htcapability ht_cap; -+ /// VHT Capabilities -+ struct mac_vhtcapability vht_cap; -+ /// Flags giving additional information about the station -+ u32_l flags; -+ /// Association ID of the station -+ u16_l aid; -+ /// Bit field indicating which queues have U-APSD enabled -+ u8_l uapsd_queues; -+ /// Maximum size, in frames, of a APSD service period -+ u8_l max_sp_len; -+ /// Operation mode information (valid if bit @ref STA_OPMOD_NOTIF is -+ /// set in the flags) -+ u8_l opmode; -+ /// Index of the VIF the station is attached to -+ u8_l vif_idx; -+ /// Whether the the station is TDLS station -+ bool_l tdls_sta; -+}; -+ -+/// Structure containing the parameters of the @ref ME_STA_ADD_CFM message -+struct me_sta_add_cfm -+{ -+ /// Station index -+ u8_l sta_idx; -+ /// Status of the station addition -+ u8_l status; -+ /// PM state of the station -+ u8_l pm_state; -+}; -+ -+/// Structure containing the parameters of the @ref ME_STA_DEL_REQ message. -+struct me_sta_del_req -+{ -+ /// Index of the station to be deleted -+ u8_l sta_idx; -+ /// Whether the the station is TDLS station -+ bool_l tdls_sta; -+}; -+ -+/// Structure containing the parameters of the @ref ME_TX_CREDITS_UPDATE_IND message. -+struct me_tx_credits_update_ind -+{ -+ /// Index of the station for which the credits are updated -+ u8_l sta_idx; -+ /// TID for which the credits are updated -+ u8_l tid; -+ /// Offset to be applied on the credit count -+ s8_l credits; -+}; -+ -+/// Structure containing the parameters of the @ref ME_TRAFFIC_IND_REQ message. -+struct me_traffic_ind_req -+{ -+ /// Index of the station for which UAPSD traffic is available on host -+ u8_l sta_idx; -+ /// Flag indicating the availability of UAPSD packets for the given STA -+ u8_l tx_avail; -+ /// Indicate if traffic is on uapsd-enabled queues -+ bool_l uapsd; -+}; -+ -+/// Structure containing the parameters of the @ref ME_RC_STATS_REQ message. -+struct me_rc_stats_req -+{ -+ /// Index of the station for which the RC statistics are requested -+ u8_l sta_idx; -+}; -+ -+/// Structure containing the structure of a retry chain step -+struct step -+{ -+ /// Current calculated throughput -+ u32_l tp; -+ /// Index of the sample in the rate_stats table -+ u16_l idx; -+}; -+ -+/// Structure containing the rate control statistics -+struct rc_rate_stats -+{ -+ /// Number of attempts (per sampling interval) -+ u16_l attempts; -+ /// Number of success (per sampling interval) -+ u16_l success; -+ /// Estimated probability of success (EWMA) -+ u16_l probability; -+ /// Rate configuration of the sample -+ u16_l rate_config; -+ /// Number of times the sample has been skipped (per sampling interval) -+ u8_l sample_skipped; -+ /// Whether the old probability is available -+ bool_l old_prob_available; -+ /// Number of times the AMPDU has been retried with this rate -+ u8_l n_retry; -+ // Whether the rate can be used in the retry chain -+ bool_l rate_allowed; -+}; -+ -+/// Structure containing the parameters of the @ref ME_RC_STATS_CFM message. -+struct me_rc_stats_cfm -+{ -+ /// Index of the station for which the RC statistics are provided -+ u8_l sta_idx; -+ /// Number of samples used in the RC algorithm -+ u16_l no_samples; -+ /// Number of MPDUs transmitted (per sampling interval) -+ u16_l ampdu_len; -+ /// Number of AMPDUs transmitted (per sampling interval) -+ u16_l ampdu_packets; -+ /// Average number of MPDUs in each AMPDU frame (EWMA) -+ u32_l avg_ampdu_len; -+ // Current step 0 of the retry chain -+ u8_l sw_retry_step; -+ /// Trial transmission period -+ u8_l sample_wait; -+ /// Retry chain steps -+ struct step retry[4]; -+ /// RC statistics -+ struct rc_rate_stats rate_stats[10]; -+ /// Throughput -+ u32_l tp[10]; -+}; -+ -+/// Structure containing the parameters of the @ref ME_RC_SET_RATE_REQ message. -+struct me_rc_set_rate_req -+{ -+ /// Index of the station for which the fixed rate is set -+ u8_l sta_idx; -+ /// Rate configuration to be set -+ u16_l fixed_rate_cfg; -+}; -+ -+/////////////////////////////////////////////////////////////////////////////// -+/////////// For SM messages -+/////////////////////////////////////////////////////////////////////////////// -+/// Message API of the SM task -+enum sm_msg_tag -+{ -+ /// Request to connect to an AP -+ SM_CONNECT_REQ = LMAC_FIRST_MSG(TASK_SM), -+ /// Confirmation of connection -+ SM_CONNECT_CFM, -+ /// Indicates that the SM associated to the AP -+ SM_CONNECT_IND, -+ /// Request to disconnect -+ SM_DISCONNECT_REQ, -+ /// Confirmation of disconnection -+ SM_DISCONNECT_CFM, -+ /// Indicates that the SM disassociated the AP -+ SM_DISCONNECT_IND, -+ /// Timeout message for procedures requiring a response from peer -+ SM_RSP_TIMEOUT_IND, -+ -+ /// MAX number of messages -+ SM_MAX, -+}; -+ -+/// Structure containing the parameters of @ref SM_CONNECT_REQ message. -+struct sm_connect_req -+{ -+ /// Connection flags (see @ref sm_connect_flags) -+ u32_l flags; -+ /// Buffer containing the additional information elements to be put in the -+ /// association request -+ u32_l ie_buf[64]; -+ /// BSSID to connect to (if not specified, set this field to WILDCARD BSSID) -+ struct mac_addr bssid; -+ /// Control port Ethertype -+ u16_l ctrl_port_ethertype; -+ /// Length of the association request IEs -+ u16_l ie_len; -+ /// Listen interval to be used for this connection -+ u16_l listen_interval; -+ /// SSID to connect to -+ struct mac_ssid ssid; -+ /// Channel on which we have to connect (if not specified, set -1 in the chan.freq field) -+ struct scan_chan_tag chan; -+ /// Flag indicating if the we have to wait for the BC/MC traffic after beacon or not -+ bool_l dont_wait_bcmc; -+ /// Authentication type -+ u8_l auth_type; -+ /// UAPSD queues (bit0: VO, bit1: VI, bit2: BE, bit3: BK) -+ u8_l uapsd_queues; -+ /// VIF index -+ u8_l vif_idx; -+}; -+ -+/// Structure containing the parameters of the @ref SM_CONNECT_CFM message. -+struct sm_connect_cfm -+{ -+ /// Status. If 0, it means that the connection procedure will be performed and that -+ /// a subsequent @ref SM_CONNECT_IND message will be forwarded once the procedure is -+ /// completed -+ u8_l status; -+}; -+ -+#define SM_ASSOC_IE_LEN 800 -+/// Structure containing the parameters of the @ref SM_CONNECT_IND message. -+struct sm_connect_ind -+{ -+ /// Status code of the connection procedure -+ u16_l status_code; -+ /// BSSID -+ struct mac_addr bssid; -+ /// Flag indicating if the indication refers to an internal roaming or from a host request -+ bool_l roamed; -+ /// Index of the VIF for which the association process is complete -+ u8_l vif_idx; -+ /// Index of the STA entry allocated for the AP -+ u8_l ap_idx; -+ /// Index of the LMAC channel context the connection is attached to -+ u8_l ch_idx; -+ /// Flag indicating if the AP is supporting QoS -+ bool_l qos; -+ /// ACM bits set in the AP WMM parameter element -+ u8_l acm; -+ /// Length of the AssocReq IEs -+ u16_l assoc_req_ie_len; -+ /// Length of the AssocRsp IEs -+ u16_l assoc_rsp_ie_len; -+ /// IE buffer -+ u32_l assoc_ie_buf[SM_ASSOC_IE_LEN/4]; -+ -+ u16_l aid; -+ u8_l band; -+ u16_l center_freq; -+ u8_l width; -+ u32_l center_freq1; -+ u32_l center_freq2; -+ -+ /// EDCA parameters -+ u32_l ac_param[AC_MAX]; -+}; -+ -+/// Structure containing the parameters of the @ref SM_DISCONNECT_REQ message. -+struct sm_disconnect_req -+{ -+ /// Reason of the deauthentication. -+ u16_l reason_code; -+ /// Index of the VIF. -+ u8_l vif_idx; -+}; -+ -+/// Structure containing the parameters of SM_ASSOCIATION_IND the message -+struct sm_association_ind -+{ -+ // MAC ADDR of the STA -+ struct mac_addr me_mac_addr; -+}; -+ -+ -+/// Structure containing the parameters of the @ref SM_DISCONNECT_IND message. -+struct sm_disconnect_ind -+{ -+ /// Reason of the disconnection. -+ u16_l reason_code; -+ /// Index of the VIF. -+ u8_l vif_idx; -+ /// FT over DS is ongoing -+ bool_l ft_over_ds; -+}; -+ -+ -+/////////////////////////////////////////////////////////////////////////////// -+/////////// For SM messages -+/////////////////////////////////////////////////////////////////////////////// -+/// Message API of the APM task -+enum apm_msg_tag -+{ -+ /// Request to start the AP. -+ APM_START_REQ = LMAC_FIRST_MSG(TASK_APM), -+ /// Confirmation of the AP start. -+ APM_START_CFM, -+ /// Request to stop the AP. -+ APM_STOP_REQ, -+ /// Confirmation of the AP stop. -+ APM_STOP_CFM, -+ /// Request to start CAC -+ APM_START_CAC_REQ, -+ /// Confirmation of the CAC start -+ APM_START_CAC_CFM, -+ /// Request to stop CAC -+ APM_STOP_CAC_REQ, -+ /// Confirmation of the CAC stop -+ APM_STOP_CAC_CFM, -+ -+ /// MAX number of messages -+ APM_MAX, -+}; -+ -+/// Structure containing the parameters of the @ref APM_START_REQ message. -+struct apm_start_req -+{ -+ /// Basic rate set -+ struct mac_rateset basic_rates; -+ /// Control channel on which we have to enable the AP -+ struct scan_chan_tag chan; -+ /// Center frequency of the first segment -+ u32_l center_freq1; -+ /// Center frequency of the second segment (only in 80+80 configuration) -+ u32_l center_freq2; -+ /// Width of channel -+ u8_l ch_width; -+ /// Address, in host memory, to the beacon template -+ u32_l bcn_addr; -+ /// Length of the beacon template -+ u16_l bcn_len; -+ /// Offset of the TIM IE in the beacon -+ u16_l tim_oft; -+ /// Beacon interval -+ u16_l bcn_int; -+ /// Flags -+ u32_l flags; -+ /// Control port Ethertype -+ u16_l ctrl_port_ethertype; -+ /// Length of the TIM IE -+ u8_l tim_len; -+ /// Index of the VIF for which the AP is started -+ u8_l vif_idx; -+ /// -+ u8_l bcn_buf[]; -+}; -+ -+/// Structure containing the parameters of the @ref APM_START_CFM message. -+struct apm_start_cfm -+{ -+ /// Status of the AP starting procedure -+ u8_l status; -+ /// Index of the VIF for which the AP is started -+ u8_l vif_idx; -+ /// Index of the channel context attached to the VIF -+ u8_l ch_idx; -+ /// Index of the STA used for BC/MC traffic -+ u8_l bcmc_idx; -+}; -+ -+/// Structure containing the parameters of the @ref APM_STOP_REQ message. -+struct apm_stop_req -+{ -+ /// Index of the VIF for which the AP has to be stopped -+ u8_l vif_idx; -+}; -+ -+/// Structure containing the parameters of the @ref APM_START_CAC_REQ message. -+struct apm_start_cac_req -+{ -+ /// Control channel on which we have to start the CAC -+ struct scan_chan_tag chan; -+ /// Center frequency of the first segment -+ u32_l center_freq1; -+ /// Center frequency of the second segment (only in 80+80 configuration) -+ u32_l center_freq2; -+ /// Width of channel -+ u8_l ch_width; -+ /// Index of the VIF for which the CAC is started -+ u8_l vif_idx; -+}; -+ -+/// Structure containing the parameters of the @ref APM_START_CAC_CFM message. -+struct apm_start_cac_cfm -+{ -+ /// Status of the CAC starting procedure -+ u8_l status; -+ /// Index of the channel context attached to the VIF for CAC -+ u8_l ch_idx; -+}; -+ -+/// Structure containing the parameters of the @ref APM_STOP_CAC_REQ message. -+struct apm_stop_cac_req -+{ -+ /// Index of the VIF for which the CAC has to be stopped -+ u8_l vif_idx; -+}; -+ -+/////////////////////////////////////////////////////////////////////////////// -+/////////// For Debug messages -+/////////////////////////////////////////////////////////////////////////////// -+ -+/// Messages related to Debug Task -+enum dbg_msg_tag -+{ -+ /// Memory read request -+ DBG_MEM_READ_REQ = LMAC_FIRST_MSG(TASK_DBG), -+ /// Memory read confirm -+ DBG_MEM_READ_CFM, -+ /// Memory write request -+ DBG_MEM_WRITE_REQ, -+ /// Memory write confirm -+ DBG_MEM_WRITE_CFM, -+ /// Module filter request -+ DBG_SET_MOD_FILTER_REQ, -+ /// Module filter confirm -+ DBG_SET_MOD_FILTER_CFM, -+ /// Severity filter request -+ DBG_SET_SEV_FILTER_REQ, -+ /// Severity filter confirm -+ DBG_SET_SEV_FILTER_CFM, -+ /// LMAC/MAC HW fatal error indication -+ DBG_ERROR_IND, -+ /// Request to get system statistics -+ DBG_GET_SYS_STAT_REQ, -+ /// COnfirmation of system statistics -+ DBG_GET_SYS_STAT_CFM, -+ /// Max number of Debug messages -+ DBG_MAX, -+}; -+ -+/// Structure containing the parameters of the @ref DBG_MEM_READ_REQ message. -+struct dbg_mem_read_req -+{ -+ u32_l memaddr; -+}; -+ -+/// Structure containing the parameters of the @ref DBG_MEM_READ_CFM message. -+struct dbg_mem_read_cfm -+{ -+ u32_l memaddr; -+ u32_l memdata; -+}; -+ -+/// Structure containing the parameters of the @ref DBG_MEM_WRITE_REQ message. -+struct dbg_mem_write_req -+{ -+ u32_l memaddr; -+ u32_l memdata; -+}; -+ -+/// Structure containing the parameters of the @ref DBG_MEM_WRITE_CFM message. -+struct dbg_mem_write_cfm -+{ -+ u32_l memaddr; -+ u32_l memdata; -+}; -+ -+/// Structure containing the parameters of the @ref DBG_SET_MOD_FILTER_REQ message. -+struct dbg_set_mod_filter_req -+{ -+ /// Bit field indicating for each module if the traces are enabled or not -+ u32_l mod_filter; -+}; -+ -+/// Structure containing the parameters of the @ref DBG_SEV_MOD_FILTER_REQ message. -+struct dbg_set_sev_filter_req -+{ -+ /// Bit field indicating the severity threshold for the traces -+ u32_l sev_filter; -+}; -+ -+/// Structure containing the parameters of the @ref DBG_GET_SYS_STAT_CFM message. -+struct dbg_get_sys_stat_cfm -+{ -+ /// Time spent in CPU sleep since last reset of the system statistics -+ u32_l cpu_sleep_time; -+ /// Time spent in DOZE since last reset of the system statistics -+ u32_l doze_time; -+ /// Total time spent since last reset of the system statistics -+ u32_l stats_time; -+}; -+ -+#endif // LMAC_MSG_H_ -diff -Naur /dev/null_types.h b/drivers/net/wireless/hflps170/lmac_types.h ---- /dev/null_types.h 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/lmac_types.h 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,56 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file co_types.h -+ * -+ * @brief This file replaces the need to include stdint or stdbool typical headers, -+ * which may not be available in all toolchains, and adds new types -+ * -+ * Copyright (C) BouffaloLab 2017-2018 -+ * -+ * $Rev: $ -+ * -+ **************************************************************************************** -+ */ -+ -+#ifndef _LMAC_INT_H_ -+#define _LMAC_INT_H_ -+ -+ -+/** -+ **************************************************************************************** -+ * @addtogroup CO_INT -+ * @ingroup COMMON -+ * @brief Common integer standard types (removes use of stdint) -+ * -+ * @{ -+ **************************************************************************************** -+ */ -+ -+ -+/* -+ * DEFINES -+ **************************************************************************************** -+ */ -+ -+ -+#include -+#include -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) -+#include -+#else -+#include -+#endif -+ -+ -+typedef uint8_t u8_l; -+typedef int8_t s8_l; -+typedef bool bool_l; -+typedef uint16_t u16_l; -+typedef int16_t s16_l; -+typedef uint32_t u32_l; -+typedef int32_t s32_l; -+typedef uint64_t u64_l; -+ -+/// @} CO_INT -+#endif // _LMAC_INT_H_ -diff -Naur /dev/null.sh b/drivers/net/wireless/hflps170/mklink.sh ---- /dev/null.sh 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/mklink.sh 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,51 @@ -+#!/bin/bash -+# -+# Generate link for shared .c files in softmac and fullmac directories -+# Note: -+# links are not mandatory and we could easily update softmac (fullmac) -+# Makefile to compile shared file directly but this would imply to recompile -+# shared code eveytime when both driver are enabled -+# -+ -+set -e -+ -+dir_list= -+ -+if [ $1 ] && [ $1 = "clean" ] -+then -+ action="clean" -+else -+ action="create" -+fi -+ -+if [ -d softmac ] -+then -+ dir_list="softmac" -+fi -+ -+if [ -d fullmac ] -+then -+ dir_list="$dir_list fullmac" -+fi -+ -+for f in $(find . -maxdepth 1 -name "*.c") -+do -+ for d in $dir_list -+ do -+ if [ $action = "clean" ] -+ then -+ # only delete link -+ if [ -L $d/${f#./} ] -+ then -+ rm -f $d/${f#./} -+ fi -+ else -+ # only create link if file doesn't exist -+ # (whether it is a link or not) -+ if [ ! -e $d/${f#./} ] -+ then -+ ln -sf .$f $d/${f#./} -+ fi -+ fi -+ done -+done -diff -Naur /dev/null.sh b/drivers/net/wireless/hflps170/mkvers.sh ---- /dev/null.sh 1970-01-01 03:00:00.000000000 +0300 -+++ b/drivers/net/wireless/hflps170/mkvers.sh 2020-12-23 11:53:40.000000000 +0200 -@@ -0,0 +1,72 @@ -+#!/bin/bash -+# -+# Outputs svn revision of directory $VERDIR into $TARGET if it changes $TARGET -+# example output omitting enclosing quotes: -+# -+# '#define BL_VERS_REV "svn1676M"' -+# '#define BL_VERS_MOD "vX.X.X.X"' -+# '#define BL_VERS_OTH "build: username date hour"' -+ -+set -e -+ -+VERDIR=$(dirname $(readlink -f $0)) -+TARGET=$1 -+ -+DATE_FORMAT="%b %d %Y %T" -+BL_VERS_MOD=$(grep BL_VERS_NUM $VERDIR/Makefile | cut -f2 -d=) -+ -+tmpout=$TARGET.tmp -+cd $VERDIR -+ -+if [ -e ".svn" ] -+then -+ svnrev=$(svnversion -c | sed 's/.*://') -+elif (git status -uno > /dev/null) -+then -+ # maybe git-svn -+ idx=0 -+ while [ "$svnrev" = "" ] -+ do -+ # loop on all commit to find the first one that match a svn revision -+ # svnrev=$(git svn find-rev HEAD~$idx) -+ # we not use svn,we use git -+ svnrev=$(git rev-parse HEAD~$idx) -+ if [ $? -ne 0 ] -+ then -+ svnrev=": Unknown Revision" -+ elif [ "$svnrev" = "" ] -+ then -+ idx=$((idx + 1)) -+ elif [ $idx -gt 0 ] || (git status -uno --porcelain | grep -q '^ M') -+ then -+ # If this is not the HEAD, or working copy is not clean then we're -+ # not at a commited svn revision so add 'M' -+ svnrev=$svnrev"M" -+ fi -+ done -+ -+ # append git info (sha1 and branch name) -+ git_sha1=$(git rev-parse --short HEAD) -+ git_branch=$(git symbolic-ref --short HEAD 2>/dev/null || echo "detached") -+ svnrev="$svnrev ($git_sha1/$git_branch)" -+else -+ svnrev=": Unknown Revision" -+fi -+ -+date=$(LC_TIME=C date +"$DATE_FORMAT") -+ -+BL_VERS_REV="git$svnrev" -+# "lmac vX.X.X.X - build:" -+banner="bl v$BL_VERS_MOD - build: $(whoami) $date - $BL_VERS_REV" -+ -+define() { echo "#define $1 \"$2\""; } -+{ -+ define "BL_VERS_REV" "$BL_VERS_REV" -+ define "BL_VERS_MOD" "$BL_VERS_MOD" -+ define "BL_VERS_BANNER" "$banner" -+} > $tmpout -+ -+ -+ -+ -+cmp -s $TARGET $tmpout && rm -f $tmpout || mv $tmpout $TARGET diff --git a/patch/kernel/archive/rockchip64-6.1/drv-spi-spidev-remove-warnings.patch b/patch/kernel/archive/rockchip64-6.1/drv-spi-spidev-remove-warnings.patch deleted file mode 100644 index b060c0d7413e..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/drv-spi-spidev-remove-warnings.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 2653defc5e22ba86bd1d455eb01fc7edd2958473 Mon Sep 17 00:00:00 2001 -From: The-going <48602507+The-going@users.noreply.github.com> -Date: Wed, 2 Feb 2022 11:56:51 +0300 -Subject: [PATCH 08/50] drv:spi:spidev remove warnings - ---- - drivers/spi/spidev.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c -index b2775d82d2d7..3c65d3d74559 100644 ---- a/drivers/spi/spidev.c -+++ b/drivers/spi/spidev.c -@@ -683,6 +683,7 @@ static const struct file_operations spidev_fops = { - static struct class *spidev_class; - - static const struct spi_device_id spidev_spi_ids[] = { -+ { .name = "spi-dev" }, - { .name = "dh2228fv" }, - { .name = "ltc2488" }, - { .name = "sx1301" }, -@@ -709,6 +710,7 @@ static int spidev_of_check(struct device *dev) - } - - static const struct of_device_id spidev_dt_ids[] = { -+ { .compatible = "armbian,spi-dev", .data = &spidev_of_check }, - { .compatible = "rohm,dh2228fv", .data = &spidev_of_check }, - { .compatible = "lineartechnology,ltc2488", .data = &spidev_of_check }, - { .compatible = "semtech,sx1301", .data = &spidev_of_check }, --- -2.35.3 diff --git a/patch/kernel/archive/rockchip64-6.1/general-add-miniDP-dt-doc.patch b/patch/kernel/archive/rockchip64-6.1/general-add-miniDP-dt-doc.patch deleted file mode 100644 index 58b1a9a7ab8b..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/general-add-miniDP-dt-doc.patch +++ /dev/null @@ -1,73 +0,0 @@ -diff --git a/Documentation/devicetree/bindings/extcon/extcon-usbc-virtual-pd.yaml b/Documentation/devicetree/bindings/extcon/extcon-usbc-virtual-pd.yaml -new file mode 100644 -index 000000000000..8110fbe2ddc2 ---- /dev/null -+++ b/Documentation/devicetree/bindings/extcon/extcon-usbc-virtual-pd.yaml -@@ -0,0 +1,66 @@ -+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/extcon/extcon-usbc-virtual-pd.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: Type-C Virtual PD extcon -+ -+maintainers: -+ - Jagan Teki -+ -+description: | -+ USB Type-C protocol supports various modes of operations includes PD, -+ USB3, and Altmode. If the platform design supports a Type-C connector -+ then configuring these modes can be done via enumeration. -+ -+ However, there are some platforms that design these modes as separate -+ protocol connectors like design Display Port from on-chip USB3 controller. -+ So we can access Type-C Altmode Display Port via onboard Display Port -+ connector instead of a Type-C connector. These kinds of platforms require -+ an explicit extcon driver in order to handle Power Delivery and -+ Port Detection. -+ -+properties: -+ compatible: -+ const: linux,extcon-usbc-virtual-pd -+ -+ det-gpios: -+ description: Detect GPIO pin. Pin can be Display Port Detect or USB ID. -+ maxItems: 1 -+ -+ vpd-polarity: -+ description: USB Type-C Polarity. false for Normal and true for Flip. -+ type: boolean -+ -+ vpd-super-speed: -+ description: USB Super Speed. false for USB2 and true for USB3. -+ type: boolean -+ -+ vpd-data-role: -+ description: USB Data roles for Virtual Type-C. -+ $ref: /schemas/types.yaml#definitions/string -+ -+ enum: -+ - host -+ - device -+ - display-port -+ -+required: -+ - compatible -+ - det-gpios -+ - vpd-data-role -+ -+additionalProperties: false -+ -+examples: -+ - | -+ #include -+ #include -+ -+ virtual_pd: virtual-pd { -+ compatible = "linux,extcon-usbc-virtual-pd"; -+ det-gpios = <&gpio4 RK_PD1 GPIO_ACTIVE_LOW>; -+ vpd-data-role = "display-port"; -+ vpd-super-speed; -+ }; - diff --git a/patch/kernel/archive/rockchip64-6.1/general-add-miniDP-virtual-extcon.patch b/patch/kernel/archive/rockchip64-6.1/general-add-miniDP-virtual-extcon.patch deleted file mode 100644 index 07adbb5037af..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/general-add-miniDP-virtual-extcon.patch +++ /dev/null @@ -1,337 +0,0 @@ -diff --git a/MAINTAINERS b/MAINTAINERS -index 68f21d46614c..aeb161b19dae 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -6466,6 +6466,12 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git - F: Documentation/filesystems/ext4/ - F: fs/ext4/ - -+EXTCON DRIVER FOR TYPE-C VIRTUAL PD -+M: Jagan Teki -+S: Maintained -+F: Documentation/devicetree/bindings/extcon/extcon-usbc-virtual-pd.yaml -+F: drivers/extcon/extcon-usbc-virtual-pd.c -+ - Extended Verification Module (EVM) - M: Mimi Zohar - L: linux-integrity@vger.kernel.org -diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig -index aac507bff135..edd6c3c52699 100644 ---- a/drivers/extcon/Kconfig -+++ b/drivers/extcon/Kconfig -@@ -186,4 +186,14 @@ config EXTCON_USBC_CROS_EC - Say Y here to enable USB Type C cable detection extcon support when - using Chrome OS EC based USB Type-C ports. - -+config EXTCON_USBC_VIRTUAL_PD -+ tristate "Virtual Type-C PD EXTCON support" -+ depends on GPIOLIB || COMPILE_TEST -+ help -+ Say Y here to enable Virtual Type-C PD extcon driver support, if -+ hardware platform designed Type-C modes separately. -+ -+ Example, of designing Display Port separately from Type-C Altmode -+ instead of accessing Altmode Display Port in Type-C connector. -+ - endif -diff --git a/drivers/extcon/Makefile b/drivers/extcon/Makefile -index 52096fd8a216..c35191eef0e1 100644 ---- a/drivers/extcon/Makefile -+++ b/drivers/extcon/Makefile -@@ -25,3 +25,4 @@ obj-$(CONFIG_EXTCON_RT8973A) += extcon-rt8973a.o - obj-$(CONFIG_EXTCON_USB_GPIO) += extcon-usb-gpio.o - obj-$(CONFIG_EXTCON_USBC_CROS_EC) += extcon-usbc-cros-ec.o - obj-$(CONFIG_EXTCON_USBC_TUSB320) += extcon-usbc-tusb320.o -+obj-$(CONFIG_EXTCON_USBC_VIRTUAL_PD) += extcon-usbc-virtual-pd.o -diff --git a/drivers/extcon/extcon-usbc-virtual-pd.c b/drivers/extcon/extcon-usbc-virtual-pd.c -new file mode 100644 -index 000000000000..e0713670e33d ---- /dev/null -+++ b/drivers/extcon/extcon-usbc-virtual-pd.c -@@ -0,0 +1,285 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Type-C Virtual PD Extcon driver -+ * -+ * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd -+ * Copyright (c) 2019 Radxa Limited -+ * Copyright (c) 2019 Amarula Solutions(India) -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static const unsigned int vpd_cable[] = { -+ EXTCON_USB, -+ EXTCON_USB_HOST, -+ EXTCON_DISP_DP, -+ EXTCON_NONE, -+}; -+ -+enum vpd_data_role { -+ DR_NONE, -+ DR_HOST, -+ DR_DEVICE, -+ DR_DISPLAY_PORT, -+}; -+ -+enum vpd_polarity { -+ POLARITY_NORMAL, -+ POLARITY_FLIP, -+}; -+ -+enum vpd_usb_ss { -+ USB_SS_USB2, -+ USB_SS_USB3, -+}; -+ -+struct vpd_extcon { -+ struct device *dev; -+ struct extcon_dev *extcon; -+ struct gpio_desc *det_gpio; -+ -+ u8 polarity; -+ u8 usb_ss; -+ enum vpd_data_role data_role; -+ -+ int irq; -+ bool enable_irq; -+ struct work_struct work; -+ struct delayed_work irq_work; -+}; -+ -+static void vpd_extcon_irq_work(struct work_struct *work) -+{ -+ struct vpd_extcon *vpd = container_of(work, struct vpd_extcon, irq_work.work); -+ bool host_connected = false, device_connected = false, dp_connected = false; -+ union extcon_property_value property; -+ int det; -+ -+ det = vpd->det_gpio ? gpiod_get_raw_value(vpd->det_gpio) : 0; -+ if (det) { -+ device_connected = (vpd->data_role == DR_DEVICE) ? true : false; -+ host_connected = (vpd->data_role == DR_HOST) ? true : false; -+ dp_connected = (vpd->data_role == DR_DISPLAY_PORT) ? true : false; -+ } -+ -+ extcon_set_state(vpd->extcon, EXTCON_USB, host_connected); -+ extcon_set_state(vpd->extcon, EXTCON_USB_HOST, device_connected); -+ extcon_set_state(vpd->extcon, EXTCON_DISP_DP, dp_connected); -+ -+ property.intval = vpd->polarity; -+ extcon_set_property(vpd->extcon, EXTCON_USB, -+ EXTCON_PROP_USB_TYPEC_POLARITY, property); -+ extcon_set_property(vpd->extcon, EXTCON_USB_HOST, -+ EXTCON_PROP_USB_TYPEC_POLARITY, property); -+ extcon_set_property(vpd->extcon, EXTCON_DISP_DP, -+ EXTCON_PROP_USB_TYPEC_POLARITY, property); -+ -+ property.intval = vpd->usb_ss; -+ extcon_set_property(vpd->extcon, EXTCON_USB, -+ EXTCON_PROP_USB_SS, property); -+ extcon_set_property(vpd->extcon, EXTCON_USB_HOST, -+ EXTCON_PROP_USB_SS, property); -+ extcon_set_property(vpd->extcon, EXTCON_DISP_DP, -+ EXTCON_PROP_USB_SS, property); -+ -+ extcon_sync(vpd->extcon, EXTCON_USB); -+ extcon_sync(vpd->extcon, EXTCON_USB_HOST); -+ extcon_sync(vpd->extcon, EXTCON_DISP_DP); -+} -+ -+static irqreturn_t vpd_extcon_irq_handler(int irq, void *dev_id) -+{ -+ struct vpd_extcon *vpd = dev_id; -+ -+ schedule_delayed_work(&vpd->irq_work, msecs_to_jiffies(10)); -+ -+ return IRQ_HANDLED; -+} -+ -+static enum vpd_data_role vpd_extcon_data_role(struct vpd_extcon *vpd) -+{ -+ const char *const data_roles[] = { -+ [DR_NONE] = "NONE", -+ [DR_HOST] = "host", -+ [DR_DEVICE] = "device", -+ [DR_DISPLAY_PORT] = "display-port", -+ }; -+ struct device *dev = vpd->dev; -+ int ret; -+ const char *dr; -+ -+ ret = device_property_read_string(dev, "vpd-data-role", &dr); -+ if (ret < 0) -+ return DR_NONE; -+ -+ ret = match_string(data_roles, ARRAY_SIZE(data_roles), dr); -+ -+ return (ret < 0) ? DR_NONE : ret; -+} -+ -+static int vpd_extcon_parse_dts(struct vpd_extcon *vpd) -+{ -+ struct device *dev = vpd->dev; -+ bool val = false; -+ int ret; -+ -+ val = device_property_read_bool(dev, "vpd-polarity"); -+ if (val) -+ vpd->polarity = POLARITY_FLIP; -+ else -+ vpd->polarity = POLARITY_NORMAL; -+ -+ val = device_property_read_bool(dev, "vpd-super-speed"); -+ if (val) -+ vpd->usb_ss = USB_SS_USB3; -+ else -+ vpd->usb_ss = USB_SS_USB2; -+ -+ vpd->data_role = vpd_extcon_data_role(vpd); -+ -+ vpd->det_gpio = devm_gpiod_get_optional(dev, "det", GPIOD_OUT_LOW); -+ if (IS_ERR(vpd->det_gpio)) { -+ ret = PTR_ERR(vpd->det_gpio); -+ dev_warn(dev, "failed to get det gpio: %d\n", ret); -+ return ret; -+ } -+ -+ vpd->irq = gpiod_to_irq(vpd->det_gpio); -+ if (vpd->irq < 0) { -+ dev_err(dev, "failed to get irq for gpio: %d\n", vpd->irq); -+ return vpd->irq; -+ } -+ -+ ret = devm_request_threaded_irq(dev, vpd->irq, NULL, -+ vpd_extcon_irq_handler, -+ IRQF_TRIGGER_FALLING | -+ IRQF_TRIGGER_RISING | IRQF_ONESHOT, -+ NULL, vpd); -+ if (ret) -+ dev_err(dev, "failed to request gpio irq\n"); -+ -+ return ret; -+} -+ -+static int vpd_extcon_probe(struct platform_device *pdev) -+{ -+ struct vpd_extcon *vpd; -+ struct device *dev = &pdev->dev; -+ int ret; -+ -+ vpd = devm_kzalloc(dev, sizeof(*vpd), GFP_KERNEL); -+ if (!vpd) -+ return -ENOMEM; -+ -+ vpd->dev = dev; -+ ret = vpd_extcon_parse_dts(vpd); -+ if (ret) -+ return ret; -+ -+ INIT_DELAYED_WORK(&vpd->irq_work, vpd_extcon_irq_work); -+ -+ vpd->extcon = devm_extcon_dev_allocate(dev, vpd_cable); -+ if (IS_ERR(vpd->extcon)) { -+ dev_err(dev, "allocat extcon failed\n"); -+ return PTR_ERR(vpd->extcon); -+ } -+ -+ ret = devm_extcon_dev_register(dev, vpd->extcon); -+ if (ret) { -+ dev_err(dev, "register extcon failed: %d\n", ret); -+ return ret; -+ } -+ -+ extcon_set_property_capability(vpd->extcon, EXTCON_USB, -+ EXTCON_PROP_USB_VBUS); -+ extcon_set_property_capability(vpd->extcon, EXTCON_USB_HOST, -+ EXTCON_PROP_USB_VBUS); -+ -+ extcon_set_property_capability(vpd->extcon, EXTCON_USB, -+ EXTCON_PROP_USB_TYPEC_POLARITY); -+ extcon_set_property_capability(vpd->extcon, EXTCON_USB_HOST, -+ EXTCON_PROP_USB_TYPEC_POLARITY); -+ extcon_set_property_capability(vpd->extcon, EXTCON_USB, -+ EXTCON_PROP_USB_SS); -+ extcon_set_property_capability(vpd->extcon, EXTCON_USB_HOST, -+ EXTCON_PROP_USB_SS); -+ -+ extcon_set_property_capability(vpd->extcon, EXTCON_DISP_DP, -+ EXTCON_PROP_USB_SS); -+ extcon_set_property_capability(vpd->extcon, EXTCON_DISP_DP, -+ EXTCON_PROP_USB_TYPEC_POLARITY); -+ -+ platform_set_drvdata(pdev, vpd); -+ -+ vpd_extcon_irq_work(&vpd->irq_work.work); -+ -+ return 0; -+} -+ -+static int vpd_extcon_remove(struct platform_device *pdev) -+{ -+ struct vpd_extcon *vpd = platform_get_drvdata(pdev); -+ -+ cancel_delayed_work_sync(&vpd->irq_work); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_PM_SLEEP -+static int vpd_extcon_suspend(struct device *dev) -+{ -+ struct vpd_extcon *vpd = dev_get_drvdata(dev); -+ -+ if (!vpd->enable_irq) { -+ disable_irq_nosync(vpd->irq); -+ vpd->enable_irq = true; -+ } -+ -+ return 0; -+} -+ -+static int vpd_extcon_resume(struct device *dev) -+{ -+ struct vpd_extcon *vpd = dev_get_drvdata(dev); -+ -+ if (vpd->enable_irq) { -+ enable_irq(vpd->irq); -+ vpd->enable_irq = false; -+ } -+ -+ return 0; -+} -+#endif -+ -+static SIMPLE_DEV_PM_OPS(vpd_extcon_pm_ops, -+ vpd_extcon_suspend, vpd_extcon_resume); -+ -+static const struct of_device_id vpd_extcon_dt_match[] = { -+ { .compatible = "linux,extcon-usbc-virtual-pd", }, -+ { /* sentinel */ } -+}; -+ -+static struct platform_driver vpd_extcon_driver = { -+ .probe = vpd_extcon_probe, -+ .remove = vpd_extcon_remove, -+ .driver = { -+ .name = "extcon-usbc-virtual-pd", -+ .pm = &vpd_extcon_pm_ops, -+ .of_match_table = vpd_extcon_dt_match, -+ }, -+}; -+ -+module_platform_driver(vpd_extcon_driver); -+ -+MODULE_AUTHOR("Jagan Teki "); -+MODULE_DESCRIPTION("Type-C Virtual PD extcon driver"); -+MODULE_LICENSE("GPL v2"); - diff --git a/patch/kernel/archive/rockchip64-6.1/general-add-overlay-compilation-support.patch b/patch/kernel/archive/rockchip64-6.1/general-add-overlay-compilation-support.patch deleted file mode 100644 index a1ff52cef6a7..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/general-add-overlay-compilation-support.patch +++ /dev/null @@ -1,82 +0,0 @@ -diff --git a/arch/arm/boot/.gitignore b/arch/arm/boot/.gitignore -index 3c79f859..4e5c1d59 100644 ---- a/arch/arm/boot/.gitignore -+++ b/arch/arm/boot/.gitignore -@@ -3,3 +3,5 @@ zImage - xipImage - bootpImage - uImage -+*.dtb* -+*.scr -diff --git a/scripts/Makefile.dtbinst b/scripts/Makefile.dtbinst -index 50d580d77..94bd15617 100644 ---- a/scripts/Makefile.dtbinst -+++ b/scripts/Makefile.dtbinst -@@ -18,9 +18,12 @@ include scripts/Kbuild.include - include $(src)/Makefile - - dtbs := $(addprefix $(dst)/, $(dtb-y) $(if $(CONFIG_OF_ALL_DTBS),$(dtb-))) -+dtbos := $(addprefix $(dst)/, $(dtbo-y)) -+scrs := $(addprefix $(dst)/, $(scr-y)) -+readmes := $(addprefix $(dst)/, $(dtbotxt-y)) - subdirs := $(addprefix $(obj)/, $(subdir-y) $(subdir-m)) - --__dtbs_install: $(dtbs) $(subdirs) -+__dtbs_install: $(dtbs) $(dtbos) $(scrs) $(readmes) $(subdirs) - @: - - quiet_cmd_dtb_install = INSTALL $@ -@@ -29,6 +32,15 @@ quiet_cmd_dtb_install = INSTALL $@ - $(dst)/%.dtb: $(obj)/%.dtb - $(call cmd,dtb_install) - -+$(dst)/%.dtbo: $(obj)/%.dtbo -+ $(call cmd,dtb_install) -+ -+$(dst)/%.scr: $(obj)/%.scr -+ $(call cmd,dtb_install) -+ -+$(dst)/README.rockchip-overlays: $(src)/README.rockchip-overlays -+ $(call cmd,dtb_install) -+ - PHONY += $(subdirs) - $(subdirs): - $(Q)$(MAKE) $(dtbinst)=$@ dst=$(patsubst $(obj)/%,$(dst)/%,$@) -diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib -index 58c05e5d..2b95dda9 100644 ---- a/scripts/Makefile.lib -+++ b/scripts/Makefile.lib -@@ -278,6 +278,9 @@ cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -n -f -9 > $@) || \ - # --------------------------------------------------------------------------- - DTC ?= $(objtree)/scripts/dtc/dtc - -+# Overlay support -+DTC_FLAGS += -@ -Wno-unit_address_format -Wno-simple_bus_reg -+ - # Disable noisy checks by default - ifeq ($(KBUILD_ENABLE_EXTRA_GCC_CHECKS),) - DTC_FLAGS += -Wno-unit_address_vs_reg \ -@@ -324,6 +327,23 @@ cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \ - $(obj)/%.dtb: $(src)/%.dts FORCE - $(call if_changed_dep,dtc) - -+quiet_cmd_dtco = DTCO $@ -+cmd_dtco = mkdir -p $(dir ${dtc-tmp}) ; \ -+ $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ -+ $(DTC) -O dtb -o $@ -b 0 \ -+ -i $(dir $<) $(DTC_FLAGS) \ -+ -d $(depfile).dtc.tmp $(dtc-tmp) ; \ -+ cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) -+ -+$(obj)/%.dtbo: $(src)/%.dts FORCE -+ $(call if_changed_dep,dtco) -+ -+quiet_cmd_scr = MKIMAGE $@ -+cmd_scr = mkimage -C none -A $(ARCH) -T script -d $< $@ -+ -+$(obj)/%.scr: $(src)/%.scr-cmd FORCE -+ $(call if_changed,scr) -+ - dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp) - - # Bzip2 diff --git a/patch/kernel/archive/rockchip64-6.1/general-add-overlay-configfs.patch b/patch/kernel/archive/rockchip64-6.1/general-add-overlay-configfs.patch deleted file mode 100644 index 5a61dfef33aa..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/general-add-overlay-configfs.patch +++ /dev/null @@ -1,403 +0,0 @@ -From 2959948b2a17f92e0ddc2e3cc9742eac7541461d Mon Sep 17 00:00:00 2001 -From: schwar3kat <61094841+schwar3kat@users.noreply.github.com> -Date: Mon, 16 Jan 2023 22:57:26 +1300 -Subject: [PATCH] OF: DT-Overlay configfs interface - -Commit message: Clean up mbox format in general-add-overlay-configfs.patch. No diff changes. - -Below patch is a squash of 4 commits borrowed from ayufan's -https://github.com/ayufan-rock64/linux-mainline-kernel repo: - -This is a port of Pantelis Antoniou's v3 port that makes use of the -upstreamed configfs support for binary attributes. - -Original commit message: -Add a runtime interface to using configfs for generic device tree overlay -usage. With it its possible to use device tree overlays without having -to use a per-platform overlay manager. -Please see Documentation/devicetree/configfs-overlays.txt for more info. - -Changes since v2: -- Removed ifdef CONFIG_OF_OVERLAY (since for now it's required) -- Created a documentation entry -- Slight rewording in Kconfig -- Fix build errors - -Changes since v1: -- of_resolve() -> of_resolve_phandles(). - -Signed-off-by: Pantelis Antoniou -Signed-off-by: Phil Elwell ---- - .../devicetree/configfs-overlays.txt | 31 ++ - drivers/of/Kconfig | 7 + - drivers/of/Makefile | 1 + - drivers/of/configfs.c | 290 ++++++++++++++++++ - 4 files changed, 329 insertions(+) - create mode 100644 Documentation/devicetree/configfs-overlays.txt - create mode 100644 drivers/of/configfs.c - -diff --git a/Documentation/devicetree/configfs-overlays.txt b/Documentation/devicetree/configfs-overlays.txt -new file mode 100644 -index 000000000..5fa43e064 ---- /dev/null -+++ b/Documentation/devicetree/configfs-overlays.txt -@@ -0,0 +1,31 @@ -+Howto use the configfs overlay interface. -+ -+A device-tree configfs entry is created in /config/device-tree/overlays -+and and it is manipulated using standard file system I/O. -+Note that this is a debug level interface, for use by developers and -+not necessarily something accessed by normal users due to the -+security implications of having direct access to the kernel's device tree. -+ -+* To create an overlay you mkdir the directory: -+ -+ # mkdir /config/device-tree/overlays/foo -+ -+* Either you echo the overlay firmware file to the path property file. -+ -+ # echo foo.dtbo >/config/device-tree/overlays/foo/path -+ -+* Or you cat the contents of the overlay to the dtbo file -+ -+ # cat foo.dtbo >/config/device-tree/overlays/foo/dtbo -+ -+The overlay file will be applied, and devices will be created/destroyed -+as required. -+ -+To remove it simply rmdir the directory. -+ -+ # rmdir /config/device-tree/overlays/foo -+ -+The rationalle of the dual interface (firmware & direct copy) is that each is -+better suited to different use patterns. The firmware interface is what's -+intended to be used by hardware managers in the kernel, while the copy interface -+make sense for developers (since it avoids problems with namespaces). -diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig -index 80b5fd44a..14c2ce96e 100644 ---- a/drivers/of/Kconfig -+++ b/drivers/of/Kconfig -@@ -94,4 +94,11 @@ config OF_DMA_DEFAULT_COHERENT - # arches should select this if DMA is coherent by default for OF devices - bool - -+config OF_CONFIGFS -+ bool "Device Tree Overlay ConfigFS interface" -+ select CONFIGFS_FS -+ select OF_OVERLAY -+ help -+ Enable a simple user-space driven DT overlay interface. -+ - endif # OF -diff --git a/drivers/of/Makefile b/drivers/of/Makefile -index e0360a443..90c92ced2 100644 ---- a/drivers/of/Makefile -+++ b/drivers/of/Makefile -@@ -1,6 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - obj-y = base.o device.o platform.o property.o - obj-$(CONFIG_OF_KOBJ) += kobj.o -+obj-$(CONFIG_OF_CONFIGFS) += configfs.o - obj-$(CONFIG_OF_DYNAMIC) += dynamic.o - obj-$(CONFIG_OF_FLATTREE) += fdt.o - obj-$(CONFIG_OF_EARLY_FLATTREE) += fdt_address.o -diff --git a/drivers/of/configfs.c b/drivers/of/configfs.c -new file mode 100644 -index 000000000..5dd509e8f ---- /dev/null -+++ b/drivers/of/configfs.c -@@ -0,0 +1,290 @@ -+/* -+ * Configfs entries for device-tree -+ * -+ * Copyright (C) 2013 - Pantelis Antoniou -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "of_private.h" -+ -+struct cfs_overlay_item { -+ struct config_item item; -+ -+ char path[PATH_MAX]; -+ -+ const struct firmware *fw; -+ struct device_node *overlay; -+ int ov_id; -+ -+ void *dtbo; -+ int dtbo_size; -+}; -+ -+static int create_overlay(struct cfs_overlay_item *overlay, void *blob, u32 blob_size) -+{ -+ int err; -+ -+ err = of_overlay_fdt_apply(blob, blob_size, &overlay->ov_id); -+ if (err < 0) { -+ pr_err("%s: Failed to create overlay (err=%d)\n", -+ __func__, err); -+ goto out_err; -+ } -+ -+out_err: -+ return err; -+} -+ -+static inline struct cfs_overlay_item *to_cfs_overlay_item( -+ struct config_item *item) -+{ -+ return item ? container_of(item, struct cfs_overlay_item, item) : NULL; -+} -+ -+static ssize_t cfs_overlay_item_path_show(struct config_item *item, -+ char *page) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ return sprintf(page, "%s\n", overlay->path); -+} -+ -+static ssize_t cfs_overlay_item_path_store(struct config_item *item, -+ const char *page, size_t count) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ const char *p = page; -+ char *s; -+ int err; -+ -+ /* if it's set do not allow changes */ -+ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0) -+ return -EPERM; -+ -+ /* copy to path buffer (and make sure it's always zero terminated */ -+ count = snprintf(overlay->path, sizeof(overlay->path) - 1, "%s", p); -+ overlay->path[sizeof(overlay->path) - 1] = '\0'; -+ -+ /* strip trailing newlines */ -+ s = overlay->path + strlen(overlay->path); -+ while (s > overlay->path && *--s == '\n') -+ *s = '\0'; -+ -+ pr_debug("%s: path is '%s'\n", __func__, overlay->path); -+ -+ err = request_firmware(&overlay->fw, overlay->path, NULL); -+ if (err != 0) -+ goto out_err; -+ -+ err = create_overlay(overlay, (void *)overlay->fw->data, overlay->fw->size); -+ if (err != 0) -+ goto out_err; -+ -+ return count; -+ -+out_err: -+ -+ release_firmware(overlay->fw); -+ overlay->fw = NULL; -+ -+ overlay->path[0] = '\0'; -+ return err; -+} -+ -+static ssize_t cfs_overlay_item_status_show(struct config_item *item, -+ char *page) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ -+ return sprintf(page, "%s\n", -+ overlay->ov_id >= 0 ? "applied" : "unapplied"); -+} -+ -+CONFIGFS_ATTR(cfs_overlay_item_, path); -+CONFIGFS_ATTR_RO(cfs_overlay_item_, status); -+ -+static struct configfs_attribute *cfs_overlay_attrs[] = { -+ &cfs_overlay_item_attr_path, -+ &cfs_overlay_item_attr_status, -+ NULL, -+}; -+ -+ssize_t cfs_overlay_item_dtbo_read(struct config_item *item, -+ void *buf, size_t max_count) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ -+ pr_debug("%s: buf=%p max_count=%zu\n", __func__, -+ buf, max_count); -+ -+ if (overlay->dtbo == NULL) -+ return 0; -+ -+ /* copy if buffer provided */ -+ if (buf != NULL) { -+ /* the buffer must be large enough */ -+ if (overlay->dtbo_size > max_count) -+ return -ENOSPC; -+ -+ memcpy(buf, overlay->dtbo, overlay->dtbo_size); -+ } -+ -+ return overlay->dtbo_size; -+} -+ -+ssize_t cfs_overlay_item_dtbo_write(struct config_item *item, -+ const void *buf, size_t count) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ int err; -+ -+ /* if it's set do not allow changes */ -+ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0) -+ return -EPERM; -+ -+ /* copy the contents */ -+ overlay->dtbo = kmemdup(buf, count, GFP_KERNEL); -+ if (overlay->dtbo == NULL) -+ return -ENOMEM; -+ -+ overlay->dtbo_size = count; -+ -+ err = create_overlay(overlay, overlay->dtbo, overlay->dtbo_size); -+ if (err != 0) -+ goto out_err; -+ -+ return count; -+ -+out_err: -+ kfree(overlay->dtbo); -+ overlay->dtbo = NULL; -+ overlay->dtbo_size = 0; -+ -+ return err; -+} -+ -+CONFIGFS_BIN_ATTR(cfs_overlay_item_, dtbo, NULL, SZ_1M); -+ -+static struct configfs_bin_attribute *cfs_overlay_bin_attrs[] = { -+ &cfs_overlay_item_attr_dtbo, -+ NULL, -+}; -+ -+static void cfs_overlay_release(struct config_item *item) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ -+ if (overlay->ov_id >= 0) -+ of_overlay_remove(&overlay->ov_id); -+ if (overlay->fw) -+ release_firmware(overlay->fw); -+ /* kfree with NULL is safe */ -+ kfree(overlay->dtbo); -+ kfree(overlay); -+} -+ -+static struct configfs_item_operations cfs_overlay_item_ops = { -+ .release = cfs_overlay_release, -+}; -+ -+static struct config_item_type cfs_overlay_type = { -+ .ct_item_ops = &cfs_overlay_item_ops, -+ .ct_attrs = cfs_overlay_attrs, -+ .ct_bin_attrs = cfs_overlay_bin_attrs, -+ .ct_owner = THIS_MODULE, -+}; -+ -+static struct config_item *cfs_overlay_group_make_item( -+ struct config_group *group, const char *name) -+{ -+ struct cfs_overlay_item *overlay; -+ -+ overlay = kzalloc(sizeof(*overlay), GFP_KERNEL); -+ if (!overlay) -+ return ERR_PTR(-ENOMEM); -+ overlay->ov_id = -1; -+ -+ config_item_init_type_name(&overlay->item, name, &cfs_overlay_type); -+ return &overlay->item; -+} -+ -+static void cfs_overlay_group_drop_item(struct config_group *group, -+ struct config_item *item) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ -+ config_item_put(&overlay->item); -+} -+ -+static struct configfs_group_operations overlays_ops = { -+ .make_item = cfs_overlay_group_make_item, -+ .drop_item = cfs_overlay_group_drop_item, -+}; -+ -+static struct config_item_type overlays_type = { -+ .ct_group_ops = &overlays_ops, -+ .ct_owner = THIS_MODULE, -+}; -+ -+static struct configfs_group_operations of_cfs_ops = { -+ /* empty - we don't allow anything to be created */ -+}; -+ -+static struct config_item_type of_cfs_type = { -+ .ct_group_ops = &of_cfs_ops, -+ .ct_owner = THIS_MODULE, -+}; -+ -+struct config_group of_cfs_overlay_group; -+ -+static struct configfs_subsystem of_cfs_subsys = { -+ .su_group = { -+ .cg_item = { -+ .ci_namebuf = "device-tree", -+ .ci_type = &of_cfs_type, -+ }, -+ }, -+ .su_mutex = __MUTEX_INITIALIZER(of_cfs_subsys.su_mutex), -+}; -+ -+static int __init of_cfs_init(void) -+{ -+ int ret; -+ -+ pr_info("%s\n", __func__); -+ -+ config_group_init(&of_cfs_subsys.su_group); -+ config_group_init_type_name(&of_cfs_overlay_group, "overlays", -+ &overlays_type); -+ configfs_add_default_group(&of_cfs_overlay_group, -+ &of_cfs_subsys.su_group); -+ -+ ret = configfs_register_subsystem(&of_cfs_subsys); -+ if (ret != 0) { -+ pr_err("%s: failed to register subsys\n", __func__); -+ goto out; -+ } -+ pr_info("%s: OK\n", __func__); -+out: -+ return ret; -+} -+late_initcall(of_cfs_init); --- -Created with Armbian build tools https://github.com/armbian/build - diff --git a/patch/kernel/archive/rockchip64-6.1/general-add-panel-simple-dsi.patch b/patch/kernel/archive/rockchip64-6.1/general-add-panel-simple-dsi.patch deleted file mode 100644 index fcead1cb9759..000000000000 --- a/patch/kernel/archive/rockchip64-6.1/general-add-panel-simple-dsi.patch +++ /dev/null @@ -1,790 +0,0 @@ -diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile -index 42a7ab542..822999710 100644 ---- a/drivers/gpu/drm/panel/Makefile -+++ b/drivers/gpu/drm/panel/Makefile -@@ -8,6 +8,7 @@ obj-$(CONFIG_DRM_PANEL_BOE_TV101WUM_NL6) += panel-boe-tv101wum-nl6.o - obj-$(CONFIG_DRM_PANEL_DSI_CM) += panel-dsi-cm.o - obj-$(CONFIG_DRM_PANEL_LVDS) += panel-lvds.o - obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o -+obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple-dsi.o - obj-$(CONFIG_DRM_PANEL_EDP) += panel-edp.o - obj-$(CONFIG_DRM_PANEL_ELIDA_KD35T133) += panel-elida-kd35t133.o - obj-$(CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02) += panel-feixin-k101-im2ba02.o -diff --git a/drivers/gpu/drm/panel/panel-simple-dsi.c b/drivers/gpu/drm/panel/panel-simple-dsi.c -new file mode 100644 -index 000000000..906d40ebe ---- /dev/null -+++ b/drivers/gpu/drm/panel/panel-simple-dsi.c -@@ -0,0 +1,772 @@ -+/* -+ * Copyright (C) 2021 -+ * This simple dsi driver porting from rock-chip panel-simple.c on linux-4.4 -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include