一、前言
安卓产品的关机方式有多种,长按关机键直接关机是一种,按出选择框进行关机也是一种。可以在power键值上报时进行操作功放脚,但是长按power键和短按power键是不同的效果,需要具体处理,在操作时发现耳机插入后功放脚的处理有偏差,所以需要把耳机插入这个问题考虑进去
二、代码路径
Android\longan\kernel\linux-5.4\drivers\input\keyboard\sunxi-keyboard.c
Android\longan\kernel\linux-5.4\sound\soc\sunxi\sun50iw12-codec.c
Android\longan\kernel\linux-5.4\sound\soc\sunxi\sun50iw12-sndcodec.c
三、代码操作
1.sun50iw12-codec.c
void hotack_codec_spk_ctr(int spkon)
{
if(sunxi_codec_tmp != NULL)
{
struct codec_spk_config *spk_cfg = &(sunxi_codec_tmp->spk_cfg);
if(spkon == 0) {
/* Disable the PA Here */
if (spk_cfg->spk_used) {
gpio_set_value(spk_cfg->spk_gpio, !(spk_cfg->pa_level));
// if (spk_cfg->pa_msleep > 0) {
// msleep(spk_cfg->pa_msleep);
// }
}
} else {
/* Enable the PA Here */
if (spk_cfg->spk_used) {
// if (spk_cfg->pa_msleep > 0) {
// msleep(spk_cfg->pa_msleep);
// }
gpio_direction_output(spk_cfg->spk_gpio, 0x1);
gpio_set_value(spk_cfg->spk_gpio, spk_cfg->pa_level);
}
}
}
}
EXPORT_SYMBOL(hotack_codec_spk_ctr);
2.sun50iw12-sndcodec.c
+u32 headphone_status;
+u32 get_headphone_status(u32 status)
+{
+ status = headphone_status;
+ return status;
+}
+EXPORT_SYMBOL(get_headphone_status);
....
/* headphone plugin */
if (jack_state & (1 << JACK_DET_IIN_ST)) {
regval = jack_state;
regval &= ~(0x1 << JACK_DET_OUT_ST);
regmap_write(sunxi_codec->codec_regmap, SUNXI_HMIC_STS, regval);
priv->detect_state = PLUG_IN;
+ headphone_status = priv->detect_state;//hotack
/* get jack insert time to set mic det dead time */
ktime_get_real_ts64(&priv->tv_headset_plugin);
schedule_delayed_work(&priv->hs_detect_work,
msecs_to_jiffies(10));
}
/* headphone plugout */
if (jack_state & (1 << JACK_DET_OUT_ST)) {
regval = jack_state;
regval &= ~(0x1 << JACK_DET_IIN_ST);
regmap_write(sunxi_codec->codec_regmap, SUNXI_HMIC_STS, regval);
priv->detect_state = PLUG_OUT;
+ headphone_status = priv->detect_state;//hotack
schedule_delayed_work(&priv->hs_detect_work,
msecs_to_jiffies(10));
}
....
把耳机插入和拔出的状态引出
3.sunxi-keyboard.c
+ extern u32 get_headphone_status(u32 status);
static void sunxi_report_power_key(struct timer_list *t)
{
int wakeup_flag = 0;
int num = 0;
+ u32 earphone_status = 0;
struct sunxi_key_data *key_data = from_timer(key_data, t, key_timer);
+ earphone_status = get_headphone_status(earphone_status);
+ printk("earphone_status!!!!!!is %d\n",earphone_status);
for (num = 1; num < SAMPLE_NUMBER; num++) {
key_data->power_gpio_level[num] = gpio_get_value(key_data->power_gpio);
if (key_data->power_gpio_level[0] != key_data->power_gpio_level[num])
return;
mdelay(key_data->time_delay);
}
if (key_data->power_gpio_level[1] == GPIO_LOW_LEVEL) {
wakeup_flag = 1;
+ if(is_power_down == true && (jiffies - con_times) >= 200) {
+ hotack_codec_spk_ctr(0);
+ }
//gpio_set_value(gpio_spk,0);
+ if(!earphone_status)
+ {
+ hotack_codec_spk_ctr(0);
+ mdelay(100);
+ }
input_report_key(key_data->input_dev, key_data->power_key, 1);
} else {
if (wakeup_flag == 0){
//gpio_set_value(gpio_spk,0);
+ if(!earphone_status)
+ {
+ hotack_codec_spk_ctr(1);
+ }
input_report_key(key_data->input_dev, key_data->power_key, 1);
}
+ if(!earphone_status)
+ {
+ hotack_codec_spk_ctr(1);
+ }
input_report_key(key_data->input_dev, key_data->power_key, 0);
is_power_down = false;
con_times = 0;
//hotack_codec_spk_ctr(pre_spk_status);
wakeup_flag = 0;
}
+ pr_debug("con_times = %d, spk status = %d\n",con_times,hotack_codec_spk_status());
input_sync(key_data->input_dev);
}
四、总结
考虑到耳机插拔的问题,所以要做以上处理