ARM: DTS: Add AIO-3288J board support
authorhzq <account@t-firefly.com>
Mon, 26 Feb 2018 02:28:57 +0000 (10:28 +0800)
committerhzq <account@t-firefly.com>
Mon, 26 Feb 2018 02:28:57 +0000 (10:28 +0800)
arch/arm/boot/dts/rk3288-firefly-aio-linux-lvds.dts [new file with mode: 0644]
arch/arm/boot/dts/rk3288-firefly-aio-linux.dts [new file with mode: 0644]
arch/arm/boot/dts/rk3288-firefly.dtsi
arch/arm/configs/firefly_linux_defconfig
sound/soc/codecs/es8323.c

diff --git a/arch/arm/boot/dts/rk3288-firefly-aio-linux-lvds.dts b/arch/arm/boot/dts/rk3288-firefly-aio-linux-lvds.dts
new file mode 100644 (file)
index 0000000..87d0715
--- /dev/null
@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 2014, 2015 FUKAUMI Naoki <naobsd@gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "rk3288-firefly.dtsi"
+
+/ {
+       model = "AIO Board BOX (Linux)";
+       compatible = "firefly,aio-3288j", "rockchip,rk3288";
+
+       test-power {
+               status = "okay";
+       };
+
+       lvds_panel: lvds_panel {
+               compatible ="simple-panel";
+               backlight = <&backlight>;
+               enable-gpios = <&gpio7 3 GPIO_ACTIVE_HIGH>;
+               status = "disabled";
+               /*
+               ports {
+                       panel_in_lvds: endpoint {
+                               remote-endpoint = <&lvds_out_panel>;
+                       };
+               };
+               */
+
+               disp_timings: display-timings {
+                       native-mode = <&timing0>;
+                       timing0: timing0 {
+                               clock-frequency = <60000000>;
+                               hactive = <1366>;
+                               vactive = <768>;
+                               hback-porch = <60>;
+                               hfront-porch = <5>;
+                               vback-porch = <5>;
+                               vfront-porch = <5>;
+                               hsync-len = <8>;
+                               vsync-len = <2>;
+                               hsync-active = <0>;
+                               vsync-active = <0>;
+                               de-active = <0>;
+                               pixelclk-active = <0>;
+                               swap-rb = <0>;
+                               swap-rg = <0>;
+                               swap-gb = <0>;
+                        };
+               };
+       };
+};
+
+&vcc_5v {
+       enable-active-high;
+       gpio = <&gpio0 13 GPIO_ACTIVE_HIGH>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pwr5v_en>;
+};
+
+&ir {
+       gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
+};
+
+&pinctrl {
+       act8846 {
+               pmic_vsel: pmic-vsel {
+                       rockchip,pins = <7 14 RK_FUNC_GPIO &pcfg_output_low>;
+               };
+
+               pwr_hold: pwr-hold {
+                       rockchip,pins = <0 6 RK_FUNC_GPIO &pcfg_output_high>;
+               };
+       };
+
+       ir {
+               ir_int: ir-int {
+                       rockchip,pins = <7 0 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       pwr5v_en: pwr5v-en {
+               rockchip,pins = <0 13 RK_FUNC_GPIO &pcfg_output_high>;
+       };
+
+       es8323 {
+               es8323_earcon: es8323-earcon {
+                       rockchip,pins = <0 10 RK_FUNC_GPIO &pcfg_output_high>;
+               };
+
+               es8323_spkcon:es8323-spkcon {
+                       rockchip,pins = <7 6 RK_FUNC_GPIO &pcfg_output_low>;
+               };
+       };
+};
+
+&pwm1 {
+       status = "okay";
+};
+
+&usb_otg {
+       dr_mode = "host";
+       status = "okay";
+};
+
+&es8323 {
+       hp-det-gpio = <&gpio7 15 GPIO_ACTIVE_HIGH>;
+       line-det-gpio = <&gpio2 15 GPIO_ACTIVE_LOW>;
+       ear-con-gpio = <&gpio0 10 GPIO_ACTIVE_HIGH>;
+       spk-con-gpio = <&gpio7 6 GPIO_ACTIVE_LOW>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&es8323_earcon &es8323_spkcon>;
+};
+
+&spi0 {
+       status = "okay";
+       max-freq = <48000000>;
+
+       spidev@00 {
+        status = "disabled";
+        compatible = "linux,spidev";
+        reg = <0x00>;
+        spi-max-frequency = <48000000>;
+    };
+
+       spi_wk2xxx: spi_wk2xxx@00{
+               status = "okay";
+               compatible = "firefly,spi-wk2xxx";
+               reg = <0x00>;
+               spi-max-frequency = <10000000>;
+               power-gpio = <&gpio3 14 GPIO_ACTIVE_HIGH>;
+        reset-gpio = <&gpio0 18 GPIO_ACTIVE_HIGH>;
+        irq-gpio = <&gpio0 7 IRQ_TYPE_EDGE_FALLING>;
+        cs-gpio = <&gpio5 13 GPIO_ACTIVE_HIGH>;
+       };
+};
+
+&backlight {
+       pwms = <&pwm1 0 10000 0>;
+       enable-gpios = <&gpio5 17 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+};
+
+&lvds {
+       /*
+       avdd1v0-supply = <&vdd10_lcd>;
+       avdd1v8-supply = <&vcc18_lcd>;
+       avdd3v3-supply = <&vcca_33>;
+       */
+       rockchip,data-mapping = "vesa";
+       rockchip,data-width = <24>;
+       rockchip,output = "lvds";
+       rockchip,panel = <&lvds_panel>;
+       status = "disabled";
+
+       /*
+       ports {
+               port@1 {
+                       reg = <1>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       lvds_out_panel: endpoint@0 {
+                               reg = <0>;
+                               remote-endpoint = <&panel_in_lvds>;
+                       };
+               };
+       };
+       */
+};
+
+&act8846 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pmic_vsel>, <&pwr_hold>;
+       system-power-controller;
+
+       regulators {
+               vcc_ddr: REG1 {
+                       regulator-name = "vcc_ddr";
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1200000>;
+                       regulator-always-on;
+               };
+
+               vcc_io: REG2 {
+                       regulator-name = "vcc_io";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               vdd_log: REG3 {
+                       regulator-name = "vdd_log";
+                       regulator-min-microvolt = <700000>;
+                       regulator-max-microvolt = <1500000>;
+                       regulator-always-on;
+               };
+
+               vcc_20: REG4 {
+                       regulator-name = "vcc_20";
+                       regulator-min-microvolt = <2000000>;
+                       regulator-max-microvolt = <2000000>;
+                       regulator-always-on;
+               };
+
+               vccio_sd: REG5 {
+                       regulator-name = "vccio_sd";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               vdd10_lcd: REG6 {
+                       regulator-name = "vdd10_lcd";
+                       regulator-min-microvolt = <1050000>;
+                       regulator-max-microvolt = <1050000>;
+                       regulator-always-on;
+               };
+
+               vcca_18: REG7 {
+                       regulator-name = "vcca_18";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               vcca_33: REG8 {
+                       regulator-name = "vcca_33";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               vcc_lan: REG9 {
+                       regulator-name = "vcc_lan";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+                       regulator-boot-on;
+               };
+
+               vdd_10: REG10 {
+                       regulator-name = "vdd_10";
+                       regulator-min-microvolt = <1100000>;
+                       regulator-max-microvolt = <1100000>;
+                       regulator-always-on;
+               };
+
+               vccio_wl: vcc_18: REG11 {
+                       regulator-name = "vcc_18";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-always-on;
+               };
+
+               vcc18_lcd: REG12 {
+                       regulator-name = "vcc18_lcd";
+                       regulator-min-microvolt = <1850000>;
+                       regulator-max-microvolt = <1850000>;
+                       regulator-always-on;
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/rk3288-firefly-aio-linux.dts b/arch/arm/boot/dts/rk3288-firefly-aio-linux.dts
new file mode 100644 (file)
index 0000000..fb631d9
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2014, 2015 FUKAUMI Naoki <naobsd@gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "rk3288-firefly.dtsi"
+
+/ {
+       model = "AIO Board BOX (Linux)";
+       compatible = "firefly,aio-3288j", "rockchip,rk3288";
+
+       test-power {
+               status = "okay";
+       };
+};
+
+&vcc_5v {
+       enable-active-high;
+       gpio = <&gpio0 13 GPIO_ACTIVE_HIGH>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pwr5v_en>;
+};
+
+&ir {
+       gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
+};
+
+&pinctrl {
+       act8846 {
+               pmic_vsel: pmic-vsel {
+                       rockchip,pins = <7 14 RK_FUNC_GPIO &pcfg_output_low>;
+               };
+
+               pwr_hold: pwr-hold {
+                       rockchip,pins = <0 6 RK_FUNC_GPIO &pcfg_output_high>;
+               };
+       };
+
+       ir {
+               ir_int: ir-int {
+                       rockchip,pins = <7 0 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       pwr5v_en: pwr5v-en {
+               rockchip,pins = <0 13 RK_FUNC_GPIO &pcfg_output_high>;
+       };
+
+       es8323 {
+               es8323_earcon: es8323-earcon {
+                       rockchip,pins = <0 10 RK_FUNC_GPIO &pcfg_output_high>;
+               };
+
+               es8323_spkcon:es8323-spkcon {
+                       rockchip,pins = <7 6 RK_FUNC_GPIO &pcfg_output_low>;
+               };
+       };
+};
+
+&usb_otg {
+       dr_mode = "host";
+       status = "okay";
+};
+
+&es8323 {
+       hp-det-gpio = <&gpio7 15 GPIO_ACTIVE_HIGH>;
+       line-det-gpio = <&gpio2 15 GPIO_ACTIVE_LOW>;
+       ear-con-gpio = <&gpio0 10 GPIO_ACTIVE_HIGH>;
+       spk-con-gpio = <&gpio7 6 GPIO_ACTIVE_LOW>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&es8323_earcon &es8323_spkcon>;
+};
+
+&spi0 {
+       status = "okay";
+       max-freq = <48000000>;
+
+       spidev@00 {
+        status = "disabled";
+        compatible = "linux,spidev";
+        reg = <0x00>;
+        spi-max-frequency = <48000000>;
+    };
+
+       spi_wk2xxx: spi_wk2xxx@00{
+               status = "okay";
+               compatible = "firefly,spi-wk2xxx";
+               reg = <0x00>;
+               spi-max-frequency = <10000000>;
+               power-gpio = <&gpio3 14 GPIO_ACTIVE_HIGH>;
+        reset-gpio = <&gpio0 18 GPIO_ACTIVE_HIGH>;
+        irq-gpio = <&gpio0 7 IRQ_TYPE_EDGE_FALLING>;
+        cs-gpio = <&gpio5 13 GPIO_ACTIVE_HIGH>;
+       };
+};
+
+&act8846 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pmic_vsel>, <&pwr_hold>;
+       system-power-controller;
+
+       regulators {
+               vcc_ddr: REG1 {
+                       regulator-name = "vcc_ddr";
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1200000>;
+                       regulator-always-on;
+               };
+
+               vcc_io: REG2 {
+                       regulator-name = "vcc_io";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               vdd_log: REG3 {
+                       regulator-name = "vdd_log";
+                       regulator-min-microvolt = <700000>;
+                       regulator-max-microvolt = <1500000>;
+                       regulator-always-on;
+               };
+
+               vcc_20: REG4 {
+                       regulator-name = "vcc_20";
+                       regulator-min-microvolt = <2000000>;
+                       regulator-max-microvolt = <2000000>;
+                       regulator-always-on;
+               };
+
+               vccio_sd: REG5 {
+                       regulator-name = "vccio_sd";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               vdd10_lcd: REG6 {
+                       regulator-name = "vdd10_lcd";
+                       regulator-min-microvolt = <1050000>;
+                       regulator-max-microvolt = <1050000>;
+                       regulator-always-on;
+               };
+
+               vcca_18: REG7 {
+                       regulator-name = "vcca_18";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               vcca_33: REG8 {
+                       regulator-name = "vcca_33";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               vcc_lan: REG9 {
+                       regulator-name = "vcc_lan";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+                       regulator-boot-on;
+               };
+
+               vdd_10: REG10 {
+                       regulator-name = "vdd_10";
+                       regulator-min-microvolt = <1100000>;
+                       regulator-max-microvolt = <1100000>;
+                       regulator-always-on;
+               };
+
+               vccio_wl: vcc_18: REG11 {
+                       regulator-name = "vcc_18";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-always-on;
+               };
+
+               vcc18_lcd: REG12 {
+                       regulator-name = "vcc18_lcd";
+                       regulator-min-microvolt = <1850000>;
+                       regulator-max-microvolt = <1850000>;
+                       regulator-always-on;
+               };
+       };
+};
index b3bb02ea23fee090d5b9752f530b6d948edb803e..ad16acea92be9c012393dcc19094b906167322a3 100644 (file)
@@ -41,6 +41,7 @@
  */
 
 #include "rk3288.dtsi"
+#include <dt-bindings/input/input.h>
 
 / {
        memory {
        };
 
        leds {
-               compatible = "gpio-leds";
+       compatible = "gpio-leds";
 
-               work {
-                       gpios = <&gpio8 1 GPIO_ACTIVE_LOW>;
-                       label = "firefly:blue:user";
-                       linux,default-trigger = "rc-feedback";
+               power_led: power {
+                       label = "firefly:blue:power";
+                       linux,default-trigger = "ir-power-click";
+                       gpios = <&gpio8 1 GPIO_ACTIVE_HIGH>;
                        pinctrl-names = "default";
-                       pinctrl-0 = <&work_led>;
+                       pinctrl-0 = <&led_power>;
+                       default-state = "on";
                };
 
-               power {
-                       gpios = <&gpio8 2 GPIO_ACTIVE_LOW>;
-                       label = "firefly:green:power";
-                       linux,default-trigger = "default-on";
+               user_led: user {
+                       label = "firefly:yellow:user";
+                       linux,default-trigger = "ir-user-click";
+                       gpios = <&gpio8 2 GPIO_ACTIVE_HIGH>;
                        pinctrl-names = "default";
-                       pinctrl-0 = <&power_led>;
+                       pinctrl-0 = <&led_user>;
+                       default-state = "off";
                };
        };
 
        };
 };
 
-&edp_in {
-       /delete-node/ endpoint@0;
-};
-
 &edp_phy {
        status = "disabled";
-       //status = "okay";
 };
 
 &emmc {
 
 };
 
-&hdmi_in {
-       /delete-node/ endpoint@1;
-};
-
 &i2c0 {
        clock-frequency = <400000>;
        status = "okay";
        };
 
        leds {
-               power_led: power-led {
-                       rockchip,pins = <8 2 RK_FUNC_GPIO &pcfg_pull_none>;
+               led_power: led-power {
+                       rockchip,pins = <8 1 RK_FUNC_GPIO &pcfg_pull_none>;
                };
 
-               work_led: work-led {
-                       rockchip,pins = <8 1 RK_FUNC_GPIO &pcfg_pull_none>;
+               led_user: led-work {
+                       rockchip,pins = <8 2 RK_FUNC_GPIO &pcfg_pull_none>;
                };
        };
 
        };
 };
 
+&pwm0 {
+       interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+       compatible = "rockchip,remotectl-pwm";
+       remote_pwm_id = <0>;
+       handle_cpu_id = <1>;
+       status = "okay";
+
+       ir_key1 {
+        rockchip,usercode = <0xff00>;
+        rockchip,key_table =
+            <0xeb   KEY_POWER>,
+            <0xec   KEY_COMPOSE>,
+            <0xfe   KEY_BACK>,
+            <0xb7   KEY_HOME>,
+            <0xa3   KEY_WWW>,
+            <0xf4   KEY_VOLUMEUP>,
+            <0xa7   KEY_VOLUMEDOWN>,
+            <0xf8   KEY_ENTER>,
+            <0xfc   KEY_UP>,
+            <0xfd   KEY_DOWN>,
+            <0xf1   KEY_LEFT>,
+            <0xe5   KEY_RIGHT>;
+    };
+};
+
 &i2s {
        status = "okay";
        #sound-dai-cells = <0>;
        status = "okay";
 };
 
-&vopb_out {
-       /delete-node/ endpoint@1;
-};
-
 &vopl {
        status = "okay";
 };
        status = "okay";
 };
 
-&vopl_out {
-       /delete-node/ endpoint@0;
-};
-
 &wdt {
        status = "okay";
 };
index b858d74eed7fb1c5cdce9c4b8b7edc803de5a42b..812afd19dfde659426c0213b1ed24889fbabf298 100644 (file)
@@ -226,6 +226,9 @@ CONFIG_INPUT_MISC=y
 CONFIG_INPUT_UINPUT=y
 CONFIG_SERIO_RAW=y
 CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
+CONFIG_ROCKCHIP_REMOTECTL=y
+CONFIG_ROCKCHIP_REMOTECTL_PWM=y
+CONFIG_RK_IR_NO_DEEP_SLEEP=y
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_8250=y
@@ -243,6 +246,7 @@ CONFIG_SPI=y
 CONFIG_SPI_BITBANG=y
 CONFIG_SPI_ROCKCHIP=y
 CONFIG_SPI_SPIDEV=y
+CONFIG_SPI_WK2XXX=y
 CONFIG_DEBUG_GPIO=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_GENERIC_PLATFORM=y
index 05bdc5a8b79eb4c16e34e0808231839a085ddd96..eead9226ec800cb1ca4155e5ad95f33164d79cd5 100755 (executable)
 #include "es8323.h"
 
 #define INVALID_GPIO -1
+int es8323_line_det_gpio = INVALID_GPIO;
+int LINE_IRQ = 0;
 
-#define ES8323_CODEC_SET_SPK   1
-#define ES8323_CODEC_SET_HP    2
+#define ES8323_CODEC_SET_EAR   1
+#define ES8323_CODEC_SET_HP            2
+#define ES8323_CODEC_SET_SPK   3
+#define LINE_IN_OKAY 1
+#define LINE_IN_NO   0
 
-#define es8323_DEF_VOL 0x20
+#define es8323_DEF_VOL 0x1e
 
 static int es8323_set_bias_level(struct snd_soc_codec *codec,
                                 enum snd_soc_bias_level level);
@@ -75,13 +80,19 @@ struct es8323_priv {
 
        int spk_ctl_gpio;
        int hp_det_gpio;
+       int ear_ctl_gpio;
 
        bool muted;
        bool hp_inserted;
        bool spk_gpio_level;
        bool hp_det_level;
+       bool ear_gpio_level;
+       bool line_in_status;
 };
 
+static void line_detect_do_switch(struct work_struct *work);
+static DECLARE_DELAYED_WORK(line_wakeup_work, line_detect_do_switch);
+
 static struct es8323_priv *es8323_private;
 static int es8323_set_gpio(int gpio, bool level)
 {
@@ -91,6 +102,10 @@ static int es8323_set_gpio(int gpio, bool level)
                return 0;
        }
 
+       if ((gpio & ES8323_CODEC_SET_EAR) && es8323
+           && es8323->ear_ctl_gpio != INVALID_GPIO) {
+               gpio_set_value(es8323->ear_ctl_gpio, level);
+       }
        if ((gpio & ES8323_CODEC_SET_SPK) && es8323
            && es8323->spk_ctl_gpio != INVALID_GPIO) {
                gpio_set_value(es8323->spk_ctl_gpio, level);
@@ -99,21 +114,63 @@ static int es8323_set_gpio(int gpio, bool level)
        return 0;
 }
 
+static void spk_detect_do_switch(int ctrl)
+{
+       struct es8323_priv *es8323 = es8323_private;
+
+    if (ctrl == 1) {
+        if (es8323->hp_det_level == es8323->hp_inserted)
+        {
+            if (es8323->ear_ctl_gpio != INVALID_GPIO) {
+                               es8323_set_gpio(ES8323_CODEC_SET_EAR, es8323->ear_gpio_level);
+                       }
+            if (es8323->spk_ctl_gpio != INVALID_GPIO) {
+                               es8323_set_gpio(ES8323_CODEC_SET_SPK, !es8323->spk_gpio_level);
+                       }
+        }
+        else {
+            if (es8323->ear_ctl_gpio != INVALID_GPIO)
+                               es8323_set_gpio(ES8323_CODEC_SET_EAR, !es8323->ear_gpio_level);
+            if (es8323->spk_ctl_gpio != INVALID_GPIO)
+                               es8323_set_gpio(ES8323_CODEC_SET_SPK, es8323->spk_gpio_level);
+        }
+    } else {
+               if (es8323->ear_ctl_gpio != INVALID_GPIO)
+                       es8323_set_gpio(ES8323_CODEC_SET_EAR, !es8323->ear_gpio_level);
+               if (es8323->spk_ctl_gpio != INVALID_GPIO)
+                       es8323_set_gpio(ES8323_CODEC_SET_SPK, !es8323->spk_gpio_level);
+    }
+}
+
 static irqreturn_t hp_det_irq_handler(int irq, void *dev_id)
 {
        struct es8323_priv *es8323 = es8323_private;
 
-       if (gpio_get_value(es8323->hp_det_gpio))
+       if (!gpio_get_value(es8323->hp_det_gpio))
                es8323->hp_inserted = 0;
        else
                es8323->hp_inserted = 1;
 
+       /*
        if (es8323->muted == 0) {
                if (es8323->hp_det_level != es8323->hp_inserted)
-                       es8323_set_gpio(ES8323_CODEC_SET_SPK, !es8323->spk_gpio_level);
+                       es8323_set_gpio(ES8323_CODEC_SET_EAR, !es8323->ear_gpio_level);
                else
-                       es8323_set_gpio(ES8323_CODEC_SET_SPK, es8323->spk_gpio_level);
+                       es8323_set_gpio(ES8323_CODEC_SET_EAR, es8323->ear_gpio_level);
        }
+       */
+       if (es8323->line_in_status == LINE_IN_NO)
+               spk_detect_do_switch(!es8323->muted);
+       else
+               spk_detect_do_switch(1);
+
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t line_det_irq_handler(int irq, void *dev_id)
+{
+       disable_irq_nosync(irq);
+       schedule_delayed_work(&line_wakeup_work, msecs_to_jiffies(250));
        return IRQ_HANDLED;
 }
 
@@ -667,18 +724,26 @@ static int es8323_mute(struct snd_soc_dai *dai, int mute)
 
        es8323->muted = mute;
        if (mute) {
-               es8323_set_gpio(ES8323_CODEC_SET_SPK, !es8323->spk_gpio_level);
-               usleep_range(18000, 20000);
-               snd_soc_write(codec, ES8323_DACCONTROL3, 0x06);
+                       //es8323_set_gpio(ES8323_CODEC_SET_SPK, !es8323->spk_gpio_level);
+                       usleep_range(18000, 20000);
+                       snd_soc_write(codec, ES8323_DACCONTROL3, 0x06);
        } else {
                snd_soc_write(codec, ES8323_DACCONTROL3, 0x02);
                snd_soc_write(codec, 0x30, es8323_DEF_VOL);
                snd_soc_write(codec, 0x31, es8323_DEF_VOL);
                msleep(50);
+               /*
                if (!es8323->hp_inserted)
                        es8323_set_gpio(ES8323_CODEC_SET_SPK, es8323->spk_gpio_level);
+               */
                usleep_range(18000, 20000);
        }
+
+       if (es8323->line_in_status == LINE_IN_NO)
+               spk_detect_do_switch(!es8323->muted);
+       else
+               spk_detect_do_switch(1);
+
        return 0;
 }
 
@@ -798,6 +863,7 @@ static int es8323_probe(struct snd_soc_codec *codec)
 {
        struct es8323_priv *es8323 = snd_soc_codec_get_drvdata(codec);
        int ret = 0;
+       int flags;
 
        if (codec == NULL) {
                dev_err(codec->dev, "Codec device not registered\n");
@@ -816,6 +882,32 @@ static int es8323_probe(struct snd_soc_codec *codec)
        codec->hw_write = (hw_write_t) i2c_master_send;
        codec->control_data = container_of(codec->dev, struct i2c_client, dev);
 
+       if (es8323_line_det_gpio  != INVALID_GPIO) {
+               ret = gpio_request(es8323_line_det_gpio, "line_det");
+               if (ret != 0) {
+                       printk("%s request line_DET error", __func__);
+                       return ret;
+               }
+
+               gpio_direction_input(es8323_line_det_gpio);
+               flags = gpio_get_value(es8323_line_det_gpio) ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING;
+
+               LINE_IRQ = gpio_to_irq(es8323_line_det_gpio);
+               if (LINE_IRQ){
+                       ret = request_irq(LINE_IRQ, line_det_irq_handler, flags, "ES8323", NULL);
+                       if(ret == 0){
+                               printk("%s:register ISR (irq=%d)\n", __FUNCTION__,LINE_IRQ);
+                       }
+                       else
+                               printk("request_irq LINE_IRQ failed\n");
+               }
+               disable_irq(LINE_IRQ);
+               schedule_delayed_work(&line_wakeup_work, msecs_to_jiffies(500));
+       }
+       if (gpio_get_value(es8323->hp_det_gpio) == es8323->hp_det_level) {
+               es8323->hp_inserted = 1;
+       }
+
        es8323_codec = codec;
        ret = es8323_reset(codec);
        if (ret < 0) {
@@ -871,9 +963,51 @@ static int es8323_probe(struct snd_soc_codec *codec)
        snd_soc_write(codec, 0x04, 0x2c);       /* pdn_ana=0,ibiasgen_pdn=0 */
 
        es8323_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
        return 0;
 }
 
+static void line_detect_do_switch(struct work_struct *work)
+{
+       int level;
+       struct es8323_priv *es8323 = es8323_private;
+       int irq = gpio_to_irq(es8323_line_det_gpio);
+
+       level = gpio_get_value(es8323_line_det_gpio);
+
+       if (level == 0)
+       {
+        printk("%s Enter line in mode\n",__func__);
+               es8323->line_in_status = LINE_IN_OKAY;
+
+               snd_soc_write(es8323_codec, 0x26, 0x00);
+        snd_soc_write(es8323_codec, 0x27, 0x40);
+        snd_soc_write(es8323_codec, 0x2a, 0x40);
+        snd_soc_write(es8323_codec, 0x0b, 0x02);
+        snd_soc_write(es8323_codec, 0x04, 0x0c);
+
+        spk_detect_do_switch(1);
+
+               irq_set_irq_type(irq,  IRQ_TYPE_EDGE_RISING);
+       }
+       else {
+        printk("%s Exit line in mode\n",__func__);
+               es8323->line_in_status = LINE_IN_NO;
+
+               snd_soc_write(es8323_codec, 0x26, 0x12);
+        snd_soc_write(es8323_codec, 0x27, 0xb8);
+        snd_soc_write(es8323_codec, 0x2a, 0xb8);
+        snd_soc_write(es8323_codec, 0x0b, 0x82);
+        snd_soc_write(es8323_codec, 0x04, 0x3c);
+
+        spk_detect_do_switch(!es8323->muted);
+
+               irq_set_irq_type(irq, IRQ_TYPE_EDGE_FALLING);
+       }
+
+       enable_irq(irq);
+}
+
 static int es8323_remove(struct snd_soc_codec *codec)
 {
        es8323_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -931,7 +1065,7 @@ static int es8323_i2c_probe(struct i2c_client *i2c,
                es8323->spk_ctl_gpio = INVALID_GPIO;
        } else {
                es8323->spk_gpio_level = (flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1;
-               ret = devm_gpio_request_one(&i2c->dev, es8323->spk_ctl_gpio, GPIOF_DIR_OUT, NULL);
+               ret = devm_gpio_request_one(&i2c->dev, es8323->spk_ctl_gpio, GPIOF_DIR_OUT, "spk_ctl_gpio");
                if (ret != 0) {
                        dev_err(&i2c->dev, "Failed to request spk_ctl_gpio\n");
                        return ret;
@@ -939,6 +1073,20 @@ static int es8323_i2c_probe(struct i2c_client *i2c,
                es8323_set_gpio(ES8323_CODEC_SET_SPK, !es8323->spk_gpio_level);
        }
 
+       es8323->ear_ctl_gpio = of_get_named_gpio_flags(i2c->dev.of_node, "ear-con-gpio", 0, &flags);
+       if (es8323->ear_ctl_gpio < 0) {
+               dev_info(&i2c->dev, "Can not read property ear_ctl_gpio\n");
+               es8323->ear_ctl_gpio = INVALID_GPIO;
+       } else {
+               es8323->ear_gpio_level = (flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1;
+               ret = devm_gpio_request_one(&i2c->dev, es8323->ear_ctl_gpio, GPIOF_DIR_OUT, "ear_ctl_gpio");
+               if (ret != 0) {
+                       dev_err(&i2c->dev, "Failed to request ear_ctl_gpio\n");
+                       return ret;
+               }
+               es8323_set_gpio(ES8323_CODEC_SET_EAR, !es8323->ear_gpio_level);
+       }
+
        es8323->hp_det_gpio = of_get_named_gpio_flags(i2c->dev.of_node, "hp-det-gpio", 0, &flags);
        if (es8323->hp_det_gpio < 0) {
                dev_info(&i2c->dev, "Can not read property hp_det_gpio\n");
@@ -961,9 +1109,18 @@ static int es8323_i2c_probe(struct i2c_client *i2c,
                        }
                }
        }
+
+       es8323_line_det_gpio = of_get_named_gpio(i2c->dev.of_node, "line-det-gpio", 0);
+       if (es8323_line_det_gpio < 0) {
+               printk("%s() Can not read property es8323_line_det_gpio\n", __FUNCTION__);
+               es8323_line_det_gpio = INVALID_GPIO;
+       }
+    printk("es8323_line_det_gpio:%d\n", es8323_line_det_gpio);
+
        ret = snd_soc_register_codec(&i2c->dev,
                                     &soc_codec_dev_es8323,
                                     &es8323_dai, 1);
+
        return ret;
 }
 
@@ -982,9 +1139,13 @@ MODULE_DEVICE_TABLE(i2c, es8323_i2c_id);
 
 void es8323_i2c_shutdown(struct i2c_client *client)
 {
+       /*
        struct es8323_priv *es8323 = es8323_private;
 
        es8323_set_gpio(ES8323_CODEC_SET_SPK, !es8323->spk_gpio_level);
+       */
+       spk_detect_do_switch(0);
+
        mdelay(20);
        snd_soc_write(es8323_codec, ES8323_CONTROL2, 0x58);
        snd_soc_write(es8323_codec, ES8323_CONTROL1, 0x32);