RK3399 android7.1 耳机拔插ADC检测

rk3399_android7.1耳机拔插ADC检测 平仄散人

ADC 使用

一.frameworks\base\services\core\java\com\android\server\WiredAccessoryManager.java

private static final String HEADSET_CONNECTION_NODE  =  "/sys/devices/virtual/switch/h2w/state";

            public String getDevName() { return mDevName; }

            public String getDevPath() {
                return String.format(Locale.US, "/devices/virtual/switch/%s", mDevName);
            }

            public String getSwitchStatePath() {
                return String.format(Locale.US, "/sys/class/switch/%s/state", mDevName);
            }

  

 二.驱动解析

2.1.dts 配置 

    rockchip_headset {
				status = "okay";
				compatible = "rockchip_headset";
				io-channels = <&saradc 2>;
        io-channel-names = "headset";
				headset_gpio = <&gpio0 8 GPIO_ACTIVE_LOW>;
    };  

 

2.2.kernel\drivers\headset_observe\rockchip_headset_core.c

ret = of_get_named_gpio_flags(node, "headset_gpio", 0, &flags); //解析gpio
如果解析到gpio就devm_gpio_request //申请GPIO,gpio_direction_input//设置GPIO口为输入状态

of_get_named_gpio_flags(node, "hook_gpio", 0, &pdata->hook_gpio); //解析GPIO
如果解析不到GPIO就 pdata->chan = iio_channel_get(&pdev->dev, NULL); //获取ADC通道

static int rockchip_headset_probe(struct platform_device *pdev)
{
	struct device_node *node = pdev->dev.of_node;
	struct rk_headset_pdata *pdata;
	int ret,i,val;
	//enum of_gpio_flags flags;

	pdata = kzalloc(sizeof(struct rk_headset_pdata), GFP_KERNEL);
	if (pdata == NULL) {
		printk("%s failed to allocate driver data\n",__FUNCTION__);
		return -ENOMEM;
	}
	memset(pdata,0,sizeof(struct rk_headset_pdata));
	pdata_info = pdata;

	//headset
	ret = of_get_named_gpio(node, "headset_gpio", 0);
	if (ret < 0) {
		printk("%s() Can not read property headset_gpio\n", __FUNCTION__);
		goto err;
	} else {
		pdata->headset_gpio = ret;
		ret = devm_gpio_request(&pdev->dev, pdata->headset_gpio, "headset_gpio");
		if(ret < 0){
			printk("%s() devm_gpio_request headset_gpio request ERROR\n", __FUNCTION__);
			goto err;
		}

		ret = gpio_direction_input(pdata->headset_gpio); 
		if(ret < 0){
			printk("%s() gpio_direction_input headset_gpio set ERROR\n", __FUNCTION__);
			goto err;
		}

		pdata->headset_insert_type = HEADSET_IN_LOW;
	}
	pdata->chan = iio_channel_get(&pdev->dev, NULL);
   	if (IS_ERR(pdata->chan))
 	{
			pdata->chan = NULL;
			printk("%s() have not set adc chan\n", __FUNCTION__);
	}
	set_headset_mic_power(1);
	
	for(i = 0;i < 5;i++){
		ret = iio_read_channel_raw(pdata->chan, &val);
		  if (ret < 0) 
		  {
		     	pr_err("timer_work_callback read adc channel() error: %d\n", ret);
		  }
		  msleep(100);  		
	}	
	printk("eric  222 iio_read_channel_raw = %d \n",val);	
	
	if(val > 5)
	{
		printk("%s() ZK-R39A V1.1\n",__FUNCTION__);
		ret = rk_headset_adc_probe(pdev,pdata);
		if(ret < 0)
		{
			goto err;
		}	

	}
	else
	{
		printk("%s() ZK-R39A V1.0\n",__FUNCTION__);
		ret = rk_headset_probe(pdev,pdata);
		if(ret < 0)
		{
			goto err;
		}
	}

	return 0;
err:
	kfree(pdata);
	return ret;
}

2.3.kernel\drivers\headset_observe\rk_headset_irq_hook_adc.c

读取 AD 采集到的原始数据
int value,Vresult;
ret = iio_read_channel_raw(chan, &value);
调用 iio_read_channel_raw 函数读取 AD 采集的原始数据并存入value变量中

static void hook_once_work(struct work_struct *work)
{
	int ret,val;

	#ifdef CONFIG_SND_SOC_WM8994
	wm8994_headset_mic_detect(true);
	#endif

	#if defined (CONFIG_SND_SOC_RT3261) || defined (CONFIG_SND_SOC_RT3224)
	rt3261_headset_mic_detect(true);
	#endif

	#ifdef CONFIG_SND_SOC_RT5631_PHONE
	rt5631_headset_mic_detect(true);
	#endif

  ret = iio_read_channel_raw(headset_info->chan, &val);
  if (ret < 0) {
		pr_err("read hook_once_work adc channel() error: %d\n", ret);
	}else
		DBG("hook_once_work read adc value: %d\n",val);

	if(val >= 800 && val < 1000)
	{
		headset_info->isMic= 0;//No microphone
		#ifdef CONFIG_SND_SOC_WM8994
		wm8994_headset_mic_detect(false);
		#endif

		#if defined (CONFIG_SND_SOC_RT3261) || defined (CONFIG_SND_SOC_RT3224)
		rt3261_headset_mic_detect(false);
		#endif	

		#ifdef CONFIG_SND_SOC_RT5631_PHONE
		rt5631_headset_mic_detect(false);
		#endif					
	}	
	else if(val >= 550 && val < 750)
	{
		headset_info->isMic = 1;//four headseet in
	}
	else if(val >= 5 && val < 100)
	{
		headset_info->isMic = 1;//three headseet in
	}	

	headset_info->cur_headset_status = headset_info->isMic ? 1:0;

	#if defined(CONFIG_SND_SOC_CX2072X)
	if (cx2072x_jack_report() != -1)
		headset_info->cur_headset_status =
			(cx2072x_jack_report() == 3) ?
			BIT_HEADSET : BIT_HEADSET_NO_MIC;
	#endif
	
	switch_set_state(&headset_info->sdev, headset_info->cur_headset_status);	
	DBG("%s notice android headset status = %d\n",__func__,headset_info->cur_headset_status);
	schedule_delayed_work(&headset_info->h_delayed_work[HOOK],msecs_to_jiffies(500));
}

  

  

posted @ 2021-08-03 11:32  CrushGirl  阅读(888)  评论(0编辑  收藏  举报