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 index 940e3cffc..3e53e5873 100644 --- 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 @@ -2,11 +2,10 @@ diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchi index 26661c7b7..1462ed38b 100644 --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile -@@ -1,4 +1,23 @@ +@@ -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) += rk3308-rock-pi-s.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 diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0001-arm64-dts-rockchip-add-ROCK-Pi-S-DTS-support.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpis-0001-arm64-dts-rockchip-add-ROCK-Pi-S-DTS-support.patch deleted file mode 100644 index a3368a900..000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0001-arm64-dts-rockchip-add-ROCK-Pi-S-DTS-support.patch +++ /dev/null @@ -1,271 +0,0 @@ -From 4c09666816df62c1b8ab13410b8d0cc9234c608f Mon Sep 17 00:00:00 2001 -From: ashthespy -Date: Wed, 15 Jan 2020 14:54:14 +0100 -Subject: [PATCH 01/23] arm64: dts: rockchip: add ROCK Pi S DTS support - -ROCK Pi S is RK3308 based SBC from radxa.com. ROCK Pi S has a, -- 256MB/512MB DDR3 RAM -- SD, NAND flash (optional on board 1/2/4/8Gb) -- 100MB ethernet, PoE (optional) -- Onboard 802.11 b/g/n wifi + Bluetooth 4.0 Module -- USB2.0 Type-A HOST x1 -- USB3.0 Type-C OTG x1 -- 26-pin expansion header -- USB Type-C DC 5V Power Supply - -This patch enables -- Console -- NAND Flash -- SD Card - -Signed-off-by: Akash Gajjar ---- -Changes for v2 -- Use pwm-supply for vdd_core node instead of vi-supply -- Add USB2.0 node support - -Changes for v3 -- Use small S on dts file name -- Add missing semicolon -- Remove USB2.0 node support - - .../devicetree/bindings/arm/rockchip.yaml | 5 + - arch/arm64/boot/dts/rockchip/Makefile | 1 + - .../boot/dts/rockchip/rk3308-rock-pi-s.dts | 221 ++++++++++++++++++ - 3 files changed, 227 insertions(+) - create mode 100644 arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts ---- - .../boot/dts/rockchip/rk3308-rock-pi-s.dts | 221 ++++++++++++++++++ - 2 files changed, 222 insertions(+) - create mode 100644 arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts - -diff --git a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -new file mode 100644 -index 000000000000..4fccae43f008 ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -@@ -0,0 +1,221 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Copyright (c) 2019 Akash Gajjar -+ * Copyright (c) 2019 Jagan Teki -+ */ -+ -+/dts-v1/; -+#include "rk3308.dtsi" -+ -+/ { -+ model = "Radxa ROCK Pi S"; -+ compatible = "radxa,rockpis", "rockchip,rk3308"; -+ -+ chosen { -+ stdout-path = "serial0:1500000n8"; -+ }; -+ -+ leds { -+ compatible = "gpio-leds"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&green_led_gio>, <&heartbeat_led_gpio>; -+ -+ green-led { -+ label = "rockpis:green:power"; -+ gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "default-on"; -+ default-state = "on"; -+ }; -+ -+ blue-led { -+ label = "rockpis:blue:user"; -+ gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; -+ default-state = "on"; -+ linux,default-trigger = "heartbeat"; -+ }; -+ }; -+ -+ sdio_pwrseq: sdio-pwrseq { -+ compatible = "mmc-pwrseq-simple"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&wifi_enable_h>; -+ 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>; -+ }; -+ -+ 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 = <4>; -+ cap-mmc-highspeed; -+ mmc-hs200-1_8v; -+ supports-sd; -+ disable-wp; -+ non-removable; -+ num-slots = <1>; -+ vin-supply = <&vcc_io>; -+ status = "okay"; -+}; -+ -+&i2c1 { -+ status = "okay"; -+}; -+ -+&sdmmc { -+ bus-width = <4>; -+ cap-mmc-highspeed; -+ cap-sd-highspeed; -+ max-frequeency = <150000000>; -+ supports-sd; -+ disable-wp; -+ num-slots = <1>; -+ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_det &sdmmc_bus4>; -+ card-detect-delay = <800>; -+ status = "okay"; -+}; -+ -+&spi2 { -+ status = "okay"; -+ max-freq = <10000000>; -+}; -+ -+&pinctrl { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&rtc_32k>; -+ -+ leds { -+ green_led_gio: green-led-gpio { -+ rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ heartbeat_led_gpio: heartbeat-led-gpio { -+ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ 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_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"; -+}; -+ -+&sdio { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ bus-width = <4>; -+ max-frequency = <1000000>; -+ cap-sd-highspeed; -+ cap-sdio-irq; -+ supports-sdio; -+ keep-power-in-suspend; -+ mmc-pwrseq = <&sdio_pwrseq>; -+ non-removable; -+ sd-uhs-sdr104; -+ status = "okay"; -+}; -+ -+&uart0 { -+ status = "okay"; -+}; -+ -+&uart4 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart4_xfer &uart4_rts &uart4_cts>; -+ status = "okay"; -+}; --- -2.25.1 - 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 new file mode 100644 index 000000000..92a9d0c26 --- /dev/null +++ b/patch/kernel/archive/rockchip64-6.1/board-rockpis-0001-arm64-dts.patch @@ -0,0 +1,377 @@ +--- 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-0002-Fixes-for-rk3308-rock-pi-s-dts.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpis-0002-Fixes-for-rk3308-rock-pi-s-dts.patch deleted file mode 100644 index 1aac13c9b..000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0002-Fixes-for-rk3308-rock-pi-s-dts.patch +++ /dev/null @@ -1,71 +0,0 @@ -From a7a6d6f06de8b629537ddada1bda5beef88ecea3 Mon Sep 17 00:00:00 2001 -From: ashthespy -Date: Wed, 15 Jan 2020 15:14:16 +0100 -Subject: [PATCH 02/23] Fixes for rk3308-rock-pi-s dts - ---- - .../boot/dts/rockchip/rk3308-rock-pi-s.dts | 24 ++++++++++--------- - 1 file changed, 13 insertions(+), 11 deletions(-) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -index 4fccae43f008..f06ff0c6e028 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -@@ -121,13 +121,15 @@ &cpu0 { - }; - - &emmc { -- bus-width = <4>; -+ bus-width = <4>; // Confirm if right value - <8> - cap-mmc-highspeed; - mmc-hs200-1_8v; -- supports-sd; -- disable-wp; -+ /* supports-sd; */ -+ /* disable-wp; */ - non-removable; -- num-slots = <1>; -+ /* num-slots = <1>; */ -+ /* please provide actual vmmc and vqmmc supplies -+ vin is not a valid supply for emmcs */ - vin-supply = <&vcc_io>; - status = "okay"; - }; -@@ -137,15 +139,15 @@ &i2c1 { - }; - - &sdmmc { -- bus-width = <4>; -+ /* bus-width = <4>; */ - cap-mmc-highspeed; - cap-sd-highspeed; -- max-frequeency = <150000000>; -- supports-sd; -+ /* max-frequency = <150000000>; */ -+ /* supports-sd; */ - disable-wp; -- num-slots = <1>; -+ /* num-slots = <1>; */ - pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_det &sdmmc_bus4>; -- card-detect-delay = <800>; -+ card-detect-delay = <800>; // Confirm if right value - <200> - status = "okay"; - }; - -@@ -198,11 +200,11 @@ &saradc { - &sdio { - #address-cells = <1>; - #size-cells = <0>; -- bus-width = <4>; -+ /* bus-width = <4>; */ - max-frequency = <1000000>; - cap-sd-highspeed; - cap-sdio-irq; -- supports-sdio; -+ /* supports-sdio; */ - keep-power-in-suspend; - mmc-pwrseq = <&sdio_pwrseq>; - non-removable; --- -2.25.1 - diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0003-WIP-Wireless-support.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpis-0003-WIP-Wireless-support.patch deleted file mode 100644 index c706c4840..000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0003-WIP-Wireless-support.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 44f753e6f7be183e49c408d4db8a2c7530e7f057 Mon Sep 17 00:00:00 2001 -From: ashthespy -Date: Wed, 15 Jan 2020 20:03:48 +0100 -Subject: [PATCH 03/23] WIP: Wireless support - ---- - .../boot/dts/rockchip/rk3308-rock-pi-s.dts | 21 +++++++++++++++++++ - 1 file changed, 21 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -index f06ff0c6e028..88468a6065cf 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -@@ -39,6 +39,12 @@ 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 = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; - }; - -@@ -114,6 +120,19 @@ vcc5v0_otg: vcc5v0-otg { - pinctrl-0 = <&otg_vbus_drv>; - vin-supply = <&vcc5v0_sys>; - }; -+ -+ wireless-wlan { -+ compatible = "wlan-platdata"; -+ rockchip,grf = <&grf>; -+ clocks = <&cru SCLK_WIFI>; -+ clock-names = "clk_wifi"; -+ ref-clock-frequency = <24000000>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&wifi_host_wake>; -+ wifi_chip_type = "rtl8723ds"; -+ WIFI,host_wake_irq = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; -+ status = "okay"; -+ }; - }; - - &cpu0 { -@@ -180,7 +199,9 @@ sdio-pwrseq { - wifi_enable_h: wifi-enable-h { - rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; - }; -+ }; - -+ wireless-wlan { - wifi_host_wake: wifi-host-wake { - rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_down>; - }; --- -2.25.1 - diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0006-arm64-dts-rockchip-Enable-mac-node-on-rk3308-rock-pi.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpis-0006-arm64-dts-rockchip-Enable-mac-node-on-rk3308-rock-pi.patch deleted file mode 100644 index cc45b8bdd..000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0006-arm64-dts-rockchip-Enable-mac-node-on-rk3308-rock-pi.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 3bca021b34c95801788a53052f3fbe6f326756f8 Mon Sep 17 00:00:00 2001 -From: ashthespy -Date: Thu, 16 Jan 2020 21:14:23 +0100 -Subject: [PATCH 06/23] arm64: dts: rockchip: Enable mac node on - rk3308-rock-pi-s - ---- - .../boot/dts/rockchip/rk3308-rock-pi-s.dts | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -index 88468a6065cf..50ae9b98da67 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -@@ -110,6 +110,13 @@ vcc_io: vcc-io { - 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"; -@@ -170,6 +177,17 @@ &sdmmc { - status = "okay"; - }; - -+&gmac { -+ phy-supply = <&vcc_phy>; -+ clock_in_out = "output"; -+ 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"; -+}; -+ - &spi2 { - status = "okay"; - max-freq = <10000000>; --- -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 6f2a00191..000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0008-thermal-rockchip-add-tsadc-support-for-rk3308.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 498c9f200325f0397fd03163a98e053430b80aa4 Mon Sep 17 00:00:00 2001 -From: ashthespy -Date: Fri, 17 Jan 2020 15:58:20 +0100 -Subject: [PATCH 08/23] thermal: rockchip: add tsadc support for rk3308 - -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-0009-arm64-dts-rockchip-Enable-tsadc-node-on-rk3308-rock-.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpis-0009-arm64-dts-rockchip-Enable-tsadc-node-on-rk3308-rock-.patch deleted file mode 100644 index 13a3861c4..000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0009-arm64-dts-rockchip-Enable-tsadc-node-on-rk3308-rock-.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0c3ca953caf46013cc425a5a1c1c78f9c65dbf03 Mon Sep 17 00:00:00 2001 -From: ashthespy -Date: Fri, 17 Jan 2020 15:59:32 +0100 -Subject: [PATCH 09/23] arm64: dts: rockchip: Enable tsadc node on - rk3308-rock-pi-s - ---- - arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -index 50ae9b98da67..bf08d0d9bd90 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -@@ -251,6 +251,12 @@ &sdio { - status = "okay"; - }; - -+&tsadc { -+ rockchip,hw-tshut-mode = <0>; /* 0:CRU */ -+ rockchip,hw-tshut-polarity = <1>; /* 1:HIGH */ -+ status = "okay"; -+}; -+ - &uart0 { - status = "okay"; - }; --- -2.25.1 - diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0011-arm64-dts-rockchip-Set-is2_8ch-clocks-on-rk3308-rock.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpis-0011-arm64-dts-rockchip-Set-is2_8ch-clocks-on-rk3308-rock.patch deleted file mode 100644 index 165fa28a6..000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0011-arm64-dts-rockchip-Set-is2_8ch-clocks-on-rk3308-rock.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 6c7fe1f4faaeeb214add0b7044be2c063d23d725 Mon Sep 17 00:00:00 2001 -From: ashthespy -Date: Fri, 17 Jan 2020 16:01:10 +0100 -Subject: [PATCH 11/23] arm64: dts: rockchip: Set is2_8ch clocks on - rk3308-rock-pi-s - ---- - arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -index bf08d0d9bd90..7970e282a45c 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -@@ -188,6 +188,13 @@ &mac { - status = "okay"; - }; - -+&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>; -+}; -+ - &spi2 { - status = "okay"; - max-freq = <10000000>; --- -2.25.1 - diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0013-Add-simple-audio-card.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpis-0013-Add-simple-audio-card.patch deleted file mode 100644 index aecacd386..000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0013-Add-simple-audio-card.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 1a034263ed69e8cf58b0f95e52f09e4e1a279ca6 Mon Sep 17 00:00:00 2001 -From: ashthespy -Date: Fri, 17 Jan 2020 18:09:51 +0100 -Subject: [PATCH 13/23] Add simple-audio-card - ---- - .../boot/dts/rockchip/rk3308-rock-pi-s.dts | 24 +++++++++++++++++++ - 1 file changed, 24 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -index 7970e282a45c..a812b9a1b949 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -@@ -35,6 +35,30 @@ blue-led { - }; - }; - -+ 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-names = "default"; --- -2.25.1 - diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0015-arm64-dts-rockchip-Move-wireless-wlan-node-into-sdio.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpis-0015-arm64-dts-rockchip-Move-wireless-wlan-node-into-sdio.patch deleted file mode 100644 index 3a0069b50..000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0015-arm64-dts-rockchip-Move-wireless-wlan-node-into-sdio.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 7797745f77993145bd5ac05faef504c299a12228 Mon Sep 17 00:00:00 2001 -From: ashthespy -Date: Fri, 31 Jan 2020 16:59:34 +0100 -Subject: [PATCH 15/23] arm64: dts: rockchip: Move `wireless-wlan` node into - sdio - ---- - .../boot/dts/rockchip/rk3308-rock-pi-s.dts | 34 ++++++++++++------- - 1 file changed, 21 insertions(+), 13 deletions(-) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -index a812b9a1b949..5536460e65c2 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -@@ -152,18 +152,18 @@ vcc5v0_otg: vcc5v0-otg { - vin-supply = <&vcc5v0_sys>; - }; - -- wireless-wlan { -- compatible = "wlan-platdata"; -- rockchip,grf = <&grf>; -- clocks = <&cru SCLK_WIFI>; -- clock-names = "clk_wifi"; -- ref-clock-frequency = <24000000>; -- pinctrl-names = "default"; -- pinctrl-0 = <&wifi_host_wake>; -- wifi_chip_type = "rtl8723ds"; -- WIFI,host_wake_irq = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; -- status = "okay"; -- }; -+ // wireless-wlan { -+ // compatible = "wlan-platdata"; -+ // rockchip,grf = <&grf>; -+ // clocks = <&cru SCLK_WIFI>; -+ // clock-names = "clk_wifi"; -+ // ref-clock-frequency = <24000000>; -+ // pinctrl-names = "default"; -+ // pinctrl-0 = <&wifi_host_wake>; -+ // wifi_chip_type = "rtl8723ds"; -+ // WIFI,host_wake_irq = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; -+ // status = "okay"; -+ // }; - }; - - &cpu0 { -@@ -250,7 +250,7 @@ wifi_enable_h: wifi-enable-h { - }; - }; - -- wireless-wlan { -+ wifi { - wifi_host_wake: wifi-host-wake { - rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_down>; - }; -@@ -280,6 +280,14 @@ &sdio { - non-removable; - sd-uhs-sdr104; - status = "okay"; -+ -+ rtl8723ds: wifi@1 { -+ interrupt-parent = <&gpio0>; -+ interrupts = ; -+ interrupt-names = "host-wake"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&wifi_host_wake>; -+ }; - }; - - &tsadc { --- -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 1e280eca1..000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0018-ASoC-codecs-Add-RK3308-internal-codec-driver.patch +++ /dev/null @@ -1,2645 +0,0 @@ -From 76f98b4d0be07417ab9bc4a5669d185299f54cdf Mon Sep 17 00:00:00 2001 -From: ashthespy -Date: Mon, 3 Feb 2020 17:09:38 +0100 -Subject: [PATCH 18/23] ASoC: codecs: Add RK3308 internal codec driver - -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 0cb108633..000000000 --- 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-0021-arm64-dts-rockchip-enable-analog-audio-node-for-rk33.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpis-0021-arm64-dts-rockchip-enable-analog-audio-node-for-rk33.patch deleted file mode 100644 index a35d2f92d..000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0021-arm64-dts-rockchip-enable-analog-audio-node-for-rk33.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 1456af021789aed2f6020afa0353093be3d64f98 Mon Sep 17 00:00:00 2001 -From: ashthespy -Date: Mon, 3 Feb 2020 17:29:59 +0100 -Subject: [PATCH 21/23] arm64: dts: rockchip: enable analog audio node for - rk3308-rock-pi-s - ---- - .../boot/dts/rockchip/rk3308-rock-pi-s.dts | 26 +++++++++++++++++++ - 1 file changed, 26 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -index 5536460e65c2..c65f906ecc5b 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -@@ -35,6 +35,22 @@ blue-led { - }; - }; - -+ 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"; -@@ -166,6 +182,11 @@ vcc5v0_otg: vcc5v0-otg { - // }; - }; - -+&acodec { -+ status = "okay"; -+ #sound-dai-cells = <0>; -+}; -+ - &cpu0 { - cpu-supply = <&vdd_core>; - }; -@@ -219,6 +240,11 @@ &i2s_8ch_0 { - #sound-dai-cells = <0>; - }; - -+&i2s_8ch_2 { -+ status = "okay"; -+ #sound-dai-cells = <0>; -+}; -+ - &spi2 { - status = "okay"; - max-freq = <10000000>; --- -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 8fa58d3c8..000000000 --- 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-0024-add-uart2-for-debug-rock-pi-s-dts.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpis-0024-add-uart2-for-debug-rock-pi-s-dts.patch deleted file mode 100644 index f49b4fb9d..000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0024-add-uart2-for-debug-rock-pi-s-dts.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts 2020-08-30 17:11:49.162572017 +0300 -+++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts 2020-08-30 17:12:00.122550893 +0300 -@@ -12,7 +12,7 @@ - compatible = "radxa,rockpis", "rockchip,rk3308"; - - chosen { -- stdout-path = "serial0:1500000n8"; -+ stdout-path = "serial2:1500000n8"; - }; - - leds { -@@ -326,6 +326,10 @@ - status = "okay"; - }; - -+&uart2 { -+ status = "okay"; -+}; -+ - &uart4 { - pinctrl-names = "default"; - pinctrl-0 = <&uart4_xfer &uart4_rts &uart4_cts>; - diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0026-add-usb-host-otg-dts.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpis-0026-add-usb-host-otg-dts.patch deleted file mode 100644 index da7264303..000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0026-add-usb-host-otg-dts.patch +++ /dev/null @@ -1,31 +0,0 @@ ---- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts 2020-12-01 17:53:08.008768652 +0200 -+++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts 2020-12-01 17:54:29.728826515 +0200 -@@ -344,3 +344,28 @@ - pinctrl-0 = <&uart4_xfer &uart4_rts &uart4_cts>; - status = "okay"; - }; -+ -+&u2phy { -+ status = "okay"; -+ -+ u2phy_host: host-port { -+ phy-supply = <&vcc5v0_otg>; -+ status = "okay"; -+ }; -+ -+ u2phy_otg: otg-port { -+ status = "okay"; -+ }; -+}; -+ -+&usb20_otg { -+ status = "okay"; -+}; -+ -+&usb_host_ehci { -+ status = "okay"; -+}; -+ -+&usb_host_ohci{ -+ status = "okay"; -+}; diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0032-iodomains.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpis-0032-iodomains.patch deleted file mode 100644 index 9e761072e..000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0032-iodomains.patch +++ /dev/null @@ -1,92 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -index 880976849..a7ecfb188 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -@@ -192,13 +192,9 @@ &cpu0 { - }; - - &emmc { -- bus-width = <4>; // Confirm if right value - <8> -+ bus-width = <4>; - cap-mmc-highspeed; -- mmc-hs200-1_8v; -- /* supports-sd; */ -- /* disable-wp; */ - non-removable; -- /* num-slots = <1>; */ - /* please provide actual vmmc and vqmmc supplies - vin is not a valid supply for emmcs */ - vin-supply = <&vcc_io>; -@@ -210,13 +206,9 @@ &i2c1 { - }; - - &sdmmc { -- /* bus-width = <4>; */ - cap-mmc-highspeed; - cap-sd-highspeed; -- /* max-frequency = <150000000>; */ -- /* supports-sd; */ - disable-wp; -- /* num-slots = <1>; */ - pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_det &sdmmc_bus4>; - card-detect-delay = <800>; // Confirm if right value - <200> - status = "okay"; -@@ -233,6 +225,16 @@ &gmac { - status = "okay"; - }; - -+&io_domains { -+ vccio0-supply = <&vcc_io>; -+ vccio1-supply = <&vcc_io>; -+ vccio2-supply = <&vcc_io>; -+ vccio3-supply = <&vcc_io>; -+ vccio4-supply = <&vcc_1v8>; -+ vccio5-supply = <&vcc_io>; -+ status = "okay"; -+}; -+ - &i2s_8ch_0 { - assigned-clocks = <&cru SCLK_I2S0_8CH_RX>; - assigned-clock-parents = <&cru SCLK_I2S0_8CH_TX_MUX>; -@@ -246,7 +248,7 @@ &i2s_8ch_2 { - }; - - &spi2 { -- status = "okay"; -+// status = "okay"; //conflicts with UART2 - max-freq = <10000000>; - }; - -@@ -296,15 +298,12 @@ &saradc { - &sdio { - #address-cells = <1>; - #size-cells = <0>; -- /* bus-width = <4>; */ -- max-frequency = <1000000>; - cap-sd-highspeed; - cap-sdio-irq; -- /* supports-sdio; */ - keep-power-in-suspend; - mmc-pwrseq = <&sdio_pwrseq>; - non-removable; -- sd-uhs-sdr104; -+ no-mmc; - status = "okay"; - - rtl8723ds: wifi@1 { -diff --git a/arch/arm64/boot/dts/rockchip/rk3308.dtsi b/arch/arm64/boot/dts/rockchip/rk3308.dtsi -index fd8685d7c..b1cf9fa77 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3308.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3308.dtsi -@@ -216,6 +216,11 @@ grf: grf@ff000000 { - compatible = "rockchip,rk3308-grf", "syscon", "simple-mfd"; - reg = <0x0 0xff000000 0x0 0x08000>; - -+ io_domains: io-domains { -+ compatible = "rockchip,rk3308-io-voltage-domain"; -+ status = "disabled"; -+ }; -+ - reboot-mode { - compatible = "syscon-reboot-mode"; - offset = <0x500>; diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0033-remove-iodomains.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpis-0033-remove-iodomains.patch deleted file mode 100644 index 773db880c..000000000 --- a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0033-remove-iodomains.patch +++ /dev/null @@ -1,152 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -index a7ecfb188..8294deecc 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts -@@ -167,19 +167,6 @@ vcc5v0_otg: vcc5v0-otg { - pinctrl-0 = <&otg_vbus_drv>; - vin-supply = <&vcc5v0_sys>; - }; -- -- // wireless-wlan { -- // compatible = "wlan-platdata"; -- // rockchip,grf = <&grf>; -- // clocks = <&cru SCLK_WIFI>; -- // clock-names = "clk_wifi"; -- // ref-clock-frequency = <24000000>; -- // pinctrl-names = "default"; -- // pinctrl-0 = <&wifi_host_wake>; -- // wifi_chip_type = "rtl8723ds"; -- // WIFI,host_wake_irq = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; -- // status = "okay"; -- // }; - }; - - &acodec { -@@ -195,13 +182,6 @@ &emmc { - bus-width = <4>; - cap-mmc-highspeed; - non-removable; -- /* please provide actual vmmc and vqmmc supplies -- vin is not a valid supply for emmcs */ -- vin-supply = <&vcc_io>; -- status = "okay"; --}; -- --&i2c1 { - status = "okay"; - }; - -@@ -214,6 +194,26 @@ &sdmmc { - 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"; -@@ -225,16 +225,6 @@ &gmac { - status = "okay"; - }; - --&io_domains { -- vccio0-supply = <&vcc_io>; -- vccio1-supply = <&vcc_io>; -- vccio2-supply = <&vcc_io>; -- vccio3-supply = <&vcc_io>; -- vccio4-supply = <&vcc_1v8>; -- vccio5-supply = <&vcc_io>; -- status = "okay"; --}; -- - &i2s_8ch_0 { - assigned-clocks = <&cru SCLK_I2S0_8CH_RX>; - assigned-clock-parents = <&cru SCLK_I2S0_8CH_TX_MUX>; -@@ -247,11 +237,6 @@ &i2s_8ch_2 { - #sound-dai-cells = <0>; - }; - --&spi2 { --// status = "okay"; //conflicts with UART2 -- max-freq = <10000000>; --}; -- - &pinctrl { - pinctrl-names = "default"; - pinctrl-0 = <&rtc_32k>; -@@ -295,32 +280,21 @@ &saradc { - 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>; -- }; --}; -- - &tsadc { - rockchip,hw-tshut-mode = <0>; /* 0:CRU */ - rockchip,hw-tshut-polarity = <1>; /* 1:HIGH */ - status = "okay"; - }; - -+&i2c1 { -+ status = "okay"; -+}; -+ -+&spi2 { -+// status = "okay"; //conflicts with UART2 -+ max-freq = <10000000>; -+}; -+ - &uart0 { - status = "okay"; - }; -diff --git a/arch/arm64/boot/dts/rockchip/rk3308.dtsi b/arch/arm64/boot/dts/rockchip/rk3308.dtsi -index b1cf9fa77..fd8685d7c 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3308.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3308.dtsi -@@ -216,11 +216,6 @@ grf: grf@ff000000 { - compatible = "rockchip,rk3308-grf", "syscon", "simple-mfd"; - reg = <0x0 0xff000000 0x0 0x08000>; - -- io_domains: io-domains { -- compatible = "rockchip,rk3308-io-voltage-domain"; -- status = "disabled"; -- }; -- - reboot-mode { - compatible = "syscon-reboot-mode"; - offset = <0x500>; diff --git a/patch/kernel/archive/rockchip64-6.1/board-rockpis-0031-arm64-dts-rk3399-rockpro64-Add-pcie-bus-scan-delay.patch b/patch/kernel/archive/rockchip64-6.1/board-rockpro64-0001-Add-pcie-bus-scan-delay.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.1/board-rockpis-0031-arm64-dts-rk3399-rockpro64-Add-pcie-bus-scan-delay.patch rename to patch/kernel/archive/rockchip64-6.1/board-rockpro64-0001-Add-pcie-bus-scan-delay.patch