From 63f974d974befb95c2bc560e9107bf4342020f83 Mon Sep 17 00:00:00 2001 From: Guanzl Date: Sat, 14 Oct 2017 17:53:03 +0800 Subject: [PATCH] AIO:: Kernel->sound:add line in function --- .../arch/arm/boot/dts/firefly-rk3288-AIO.dts | 1 + kernel/sound/soc/codecs/es8323.c | 98 +++++++++++++++++++ 2 files changed, 99 insertions(+) diff --git a/kernel/arch/arm/boot/dts/firefly-rk3288-AIO.dts b/kernel/arch/arm/boot/dts/firefly-rk3288-AIO.dts index fa881dc48a..1b9f8e943c 100644 --- a/kernel/arch/arm/boot/dts/firefly-rk3288-AIO.dts +++ b/kernel/arch/arm/boot/dts/firefly-rk3288-AIO.dts @@ -426,6 +426,7 @@ reg = <0x10>; spk-con-gpio = <&gpio0 GPIO_B2 GPIO_ACTIVE_HIGH>; hp-det-gpio = <&gpio7 GPIO_B7 GPIO_ACTIVE_HIGH>; + line-det-gpio = <&gpio2 GPIO_B7 GPIO_ACTIVE_HIGH>; hp-mic-only = <1>; clocks = <&clk_i2s>, <&clk_i2s_out>; clock-names = "i2s_clk","i2s_mclk"; diff --git a/kernel/sound/soc/codecs/es8323.c b/kernel/sound/soc/codecs/es8323.c index bb79f8dc41..80ba2b7254 100755 --- a/kernel/sound/soc/codecs/es8323.c +++ b/kernel/sound/soc/codecs/es8323.c @@ -55,11 +55,14 @@ int es8323_hdmi_ctrl=0; #define INVALID_GPIO -1 int es8323_spk_con_gpio = INVALID_GPIO; int es8323_hp_det_gpio = INVALID_GPIO; +int es8323_line_det_gpio = INVALID_GPIO; int es8323_hp_det_action_value = 0; int es8323_hp_mic_only = 0; char es8323_mic_state = 0; static int HP_IRQ=0; static int hp_irq_flag = 0; +int LINE_IRQ = 0; +int line_in_state = 0; // 0:line in out 1:line in in int mic_state_switch(void); static u32 cur_reg=0; @@ -112,6 +115,63 @@ struct es8323_priv { int is_biason; }; +static int es8323_read_gpio(int gpio) +{ + int i,level; + for(i=0; i<3; i++) + { + level = gpio_get_value(gpio); + if(level < 0) + { + printk("%s:get pin level again,pin=%d,i=%d\n",__FUNCTION__,gpio,i); + msleep(1); + continue; + } + else + break; + } + if(level < 0) + printk("%s:get pin level err!\n",__FUNCTION__); + + return level; +} + +static void line_detect_do_switch(struct work_struct *work) +{ + int ret; + int level = 0; + int irq = gpio_to_irq(es8323_line_det_gpio); + unsigned int type; + + level = es8323_read_gpio(es8323_line_det_gpio); + printk("line_detect_do_switch level: %d\n",level); + + + if(level == 1) //line in in + { + line_in_state = 1; + + snd_soc_write(es8323_codec, 0x26, 0x00); + snd_soc_write(es8323_codec, 0x0b, 0x02); //line1 + + //power on left analog input N left ADC + snd_soc_write(es8323_codec, 0x03, 0x00); + + snd_soc_write(es8323_codec, 0x09, 0x66); + snd_soc_write(es8323_codec, 0x0a, 0x00); + + irq_set_irq_type(irq, IRQ_TYPE_EDGE_FALLING); + } + else //line in out + { + line_in_state = 0; + snd_soc_write(es8323_codec, 0x0b, 0x02); + irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING); + } + + enable_irq(irq); +} + static void hp_detect_do_switch(struct work_struct *work) { int ret; @@ -143,6 +203,7 @@ static void hp_detect_do_switch(struct work_struct *work) static DECLARE_DELAYED_WORK(wakeup_work, hp_detect_do_switch); +static DECLARE_DELAYED_WORK(line_wakeup_work, line_detect_do_switch); static irqreturn_t hp_det_irq_handler(int irq, void *dev_id) @@ -168,7 +229,16 @@ static irqreturn_t hp_det_irq_handler(int irq, void *dev_id) } +static irqreturn_t line_det_irq_handler(int irq, void *dev_id) +{ + printk("hjc:%s>>>>\n",__func__); + disable_irq_nosync(irq); // for irq debounce + //wake_lock_timeout(&usb_wakelock, WAKE_LOCK_TIMEOUT); + schedule_delayed_work(&line_wakeup_work, msecs_to_jiffies(250)); + return IRQ_HANDLED; + +} static unsigned int es8323_read_reg_cache(struct snd_soc_codec *codec, unsigned int reg) @@ -1226,6 +1296,28 @@ static int es8323_probe(struct snd_soc_codec *codec) } } */ + 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 (codec == NULL) { dev_err(codec->dev, "Codec device not registered\n"); return -ENODEV; @@ -1567,6 +1659,12 @@ static int es8323_i2c_probe(struct i2c_client *i2c, es8323_hp_det_gpio = INVALID_GPIO; } + es8323_line_det_gpio = of_get_named_gpio(i2c->dev.of_node, "line-det-gpio", 0); + if (es8323_line_det_gpio < 0) { + DBG("%s() Can not read property es8323_line_det_gpio\n", __FUNCTION__); + es8323_line_det_gpio = INVALID_GPIO; + } + printk("jp es8323_line_det_gpio:%d\n",es8323_line_det_gpio); of_property_read_u32(i2c->dev.of_node, "hp-mic-only", &es8323_hp_mic_only); if(es8323_hp_mic_only != 1) { es8323_hp_mic_only = 0;