From: hzq Date: Mon, 26 Feb 2018 02:28:57 +0000 (+0800) Subject: ARM: DTS: Add AIO-3288J board support X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=28aa51965395bb1568cd048f7bdeb6320465b13b;p=firefly-linux-kernel-4.4.55.git ARM: DTS: Add AIO-3288J board support --- 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 index 000000000000..87d0715db36d --- /dev/null +++ b/arch/arm/boot/dts/rk3288-firefly-aio-linux-lvds.dts @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2014, 2015 FUKAUMI Naoki + * + * 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 index 000000000000..fb631d9b878d --- /dev/null +++ b/arch/arm/boot/dts/rk3288-firefly-aio-linux.dts @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2014, 2015 FUKAUMI Naoki + * + * 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; + }; + }; +}; diff --git a/arch/arm/boot/dts/rk3288-firefly.dtsi b/arch/arm/boot/dts/rk3288-firefly.dtsi index b3bb02ea23fe..ad16acea92be 100644 --- a/arch/arm/boot/dts/rk3288-firefly.dtsi +++ b/arch/arm/boot/dts/rk3288-firefly.dtsi @@ -41,6 +41,7 @@ */ #include "rk3288.dtsi" +#include / { memory { @@ -143,22 +144,24 @@ }; 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"; }; }; @@ -342,13 +345,8 @@ }; }; -&edp_in { - /delete-node/ endpoint@0; -}; - &edp_phy { status = "disabled"; - //status = "okay"; }; &emmc { @@ -394,10 +392,6 @@ }; -&hdmi_in { - /delete-node/ endpoint@1; -}; - &i2c0 { clock-frequency = <400000>; status = "okay"; @@ -656,12 +650,12 @@ }; 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>; }; }; @@ -719,6 +713,31 @@ }; }; +&pwm0 { + interrupts = ; + 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>; @@ -821,10 +840,6 @@ status = "okay"; }; -&vopb_out { - /delete-node/ endpoint@1; -}; - &vopl { status = "okay"; }; @@ -837,10 +852,6 @@ status = "okay"; }; -&vopl_out { - /delete-node/ endpoint@0; -}; - &wdt { status = "okay"; }; diff --git a/arch/arm/configs/firefly_linux_defconfig b/arch/arm/configs/firefly_linux_defconfig index b858d74eed7f..812afd19dfde 100644 --- a/arch/arm/configs/firefly_linux_defconfig +++ b/arch/arm/configs/firefly_linux_defconfig @@ -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 diff --git a/sound/soc/codecs/es8323.c b/sound/soc/codecs/es8323.c index 05bdc5a8b79e..eead9226ec80 100755 --- a/sound/soc/codecs/es8323.c +++ b/sound/soc/codecs/es8323.c @@ -36,11 +36,16 @@ #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);