--- /dev/null
+/*
+ * 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;
+ };
+ };
+};
--- /dev/null
+/*
+ * 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;
+ };
+ };
+};
*/
#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";
};
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
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
#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);
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)
{
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);
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;
}
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;
}
{
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");
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) {
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);
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;
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");
}
}
}
+
+ 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;
}
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);