void hi6402_jack_report(struct hi6402_mbhc_platform_data *pdata)
{
	enum hisi_jack_states jack_status = pdata->hs_status;
	int jack_report = 0;

	switch(pdata->hs_status) {
	case HISI_JACK_NONE:
		jack_report = 0;
		pr_info("%s : plug out\n", __FUNCTION__);
		break;
	case HISI_JACK_HEADSET:
		jack_report = SND_JACK_HEADSET;
		pr_info("%s : 4-pole headset plug in\n", __FUNCTION__);
		break;
	case HISI_JACK_INVERT:
		jack_report = SND_JACK_HEADPHONE;
		pr_info("%s : invert headset plug in\n", __FUNCTION__);
		break;
	case HISI_JACK_HEADPHONE:
		jack_report = SND_JACK_HEADPHONE;
		pr_info("%s : 3-pole headphone plug in\n", __FUNCTION__);
		break;
	default:
		pr_err("%s : error hs_status(%d)\n", __FUNCTION__, pdata->hs_status);
		break;
	}

	/* clear btn event */
	hi6402_soc_jack_report(0, HI6402_BTN_MASK);
	/* btn_report jack status */
	hi6402_soc_jack_report(jack_report, SND_JACK_HEADSET);
#ifdef CONFIG_SWITCH
	switch_set_state(&pdata->sdev, jack_status);
#endif
}
static irqreturn_t hi6402_btnup_eco_handler(int irq, void *data)
{
	struct hi6402_mbhc_platform_data *pdata =
			(struct hi6402_mbhc_platform_data *)data;

	BUG_ON(NULL == pdata);

	if (!check_headset_pluged_in(pdata))
		return IRQ_HANDLED;

	wake_lock_timeout(&pdata->wake_lock, 100);

	if (HISI_JACK_INVERT == pdata->hs_status) {
		pr_err("%s: further detect\n", __FUNCTION__);
		/* further detect */
		hi6402_plug_in_detect(pdata);
	} else if (0 == pdata->btn_report){
		if (HISI_JACK_HEADSET != pdata->hs_status) {
			/* further detect */
			hi6402_plug_in_detect(pdata);
		}
		return IRQ_HANDLED;
	} else {
		mutex_lock(&pdata->status_mutex);
		pdata->btn_report = 0;
		hi6402_soc_jack_report(pdata->btn_report, HI6402_BTN_MASK);
		mutex_unlock(&pdata->status_mutex);
		pr_info("%s(%u) : btn up !\n", __FUNCTION__, __LINE__);
	}

	return IRQ_HANDLED;
}
Ejemplo n.º 3
0
void hi6402_btnup_workfunc(struct work_struct *work)
{
	struct hi6402_mbhc_platform_data *pdata = container_of(work,
			struct hi6402_mbhc_platform_data,
			headset_btn_up_delay_work.work);

	BUG_ON(NULL == pdata);

	pr_info("%s(%u) : btn up !\n", __FUNCTION__, __LINE__);

	pdata->btn_report = 0;

	hi6402_soc_jack_report(pdata->btn_report, HI6402_BTN_MASK);

	/* mask btn up interrupt*/
	mask_irq(pdata->irq[HI6402_IRQ_BTNUP_COMP1], true);
	/* unmask btn down interrupt*/
	mask_irq(pdata->irq[HI6402_IRQ_BTNDOWN_COMP1], false);

	return;
}
void hi6402_btn_down(struct hi6402_mbhc_platform_data *pdata)
{
	int saradc_value = 0;

	if (!check_headset_pluged_in(pdata)) {
		pr_info("%s(%u) : hs pluged out \n", __FUNCTION__, __LINE__);
		return;
	}

	wake_lock(&pdata->wake_lock);

	if (HISI_JACK_HEADSET == pdata->hs_status) {
		/* micbias on */
		hi6402_irq_micbias_mbhc_enable(pdata->p_irq, true);

		/* auto read */
		saradc_value = hi6402_read_saradc_value_detect(pdata);

		/* micbias off */
		hi6402_irq_micbias_mbhc_enable(pdata->p_irq, false);

		msleep(30);

		if (!check_headset_pluged_in(pdata)) {
			pr_info("%s(%u) : hs pluged out \n", __FUNCTION__, __LINE__);
			goto end;
		}

		if ((saradc_value >= pdata->hs_4_pole_min_voltage) && (saradc_value <= pdata->hs_4_pole_max_voltage)) {
			pr_info("%s(%u) : process as btn up! \n", __FUNCTION__, __LINE__);
			mutex_lock(&pdata->status_mutex);
			pdata->btn_report = 0;
			mutex_unlock(&pdata->status_mutex);
		} else if ((saradc_value >= pdata->btn_play_min_voltage) && (saradc_value <= pdata->btn_play_max_voltage)) {
			mutex_lock(&pdata->status_mutex);
			pdata->btn_report = SND_JACK_BTN_0;
			mutex_unlock(&pdata->status_mutex);
		} else if (pdata->btn_volume_up_min_voltage < saradc_value && saradc_value <= pdata->btn_volume_up_max_voltage) {
			mutex_lock(&pdata->status_mutex);
			pdata->btn_report = SND_JACK_BTN_1;
			mutex_unlock(&pdata->status_mutex);
		} else if (pdata->btn_volume_down_min_voltage < saradc_value && saradc_value <= pdata->btn_volume_down_max_voltage) {
			mutex_lock(&pdata->status_mutex);
			pdata->btn_report = SND_JACK_BTN_2;
			mutex_unlock(&pdata->status_mutex);
		} else {
			msleep(30);
			hi6402_plug_in_detect(pdata);
			goto end;
		}

		if (!check_headset_pluged_in(pdata)) {
			pr_info("%s(%u) : hs pluged out \n", __FUNCTION__, __LINE__);
			goto end;
		}

		/*btn_report key event*/
		pr_info("%s(%u): btn_report type = 0x%x, status=0x%x\n",
				__FUNCTION__, __LINE__, pdata->btn_report, pdata->hs_status);
		hi6402_soc_jack_report(pdata->btn_report, HI6402_BTN_MASK);
	}

end:
	wake_unlock(&pdata->wake_lock);

	return;
}
Ejemplo n.º 5
0
void hi6402_btndown_workfunc(struct work_struct *work)
{
	int saradc_value = 0;
	struct hi6402_mbhc_platform_data *pdata = container_of(work,
			struct hi6402_mbhc_platform_data,
			headset_btn_down_delay_work.work);

	BUG_ON(NULL == pdata);

	if (!check_headset_pluged_in(pdata)) {
		pr_info("%s(%u) : hs pluged out \n", __FUNCTION__, __LINE__);
		return;
	}

	pr_info("%s(%u) : btn down !\n", __FUNCTION__, __LINE__);

	wake_lock(&pdata->wake_lock);

	if (HISI_JACK_HEADSET == pdata->hs_status) {
		/* power on hs-micbias */
		//hi6401_hs_micbias_saradc_enable(codec, true);
		//saradc_value = hi6401_read_saradc_value(codec);
		//pr_info("%s(%u) :saradc_value: %d \n", __FUNCTION__, __LINE__, saradc_value);
		//hi6401_hs_micbias_saradc_enable(codec, false);

		if (!check_headset_pluged_in(pdata)) {
			pr_info("%s(%u) : hs pluged out \n", __FUNCTION__, __LINE__);

			/* mask all btn interrupt*/
			mask_irq(pdata->irq[HI6402_IRQ_BTNUP_COMP1], true);
			mask_irq(pdata->irq[HI6402_IRQ_BTNDOWN_COMP1], true);
			goto end;
		}

		if ((saradc_value >= pdata->hs_4_pole_min_voltage) && (saradc_value <= pdata->hs_4_pole_max_voltage)) {
			pr_info("%s(%u) : process as btn up! \n", __FUNCTION__, __LINE__);
			mutex_lock(&pdata->status_mutex);
			pdata->btn_report = 0;
			mutex_unlock(&pdata->status_mutex);
		} else if ((saradc_value >= pdata->btn_play_min_voltage) && (saradc_value <= pdata->btn_play_max_voltage)) {
			mutex_lock(&pdata->status_mutex);
			pdata->btn_report = SND_JACK_BTN_0;
			mutex_unlock(&pdata->status_mutex);
		} else if (pdata->btn_volume_up_min_voltage < saradc_value && saradc_value <= pdata->btn_volume_up_max_voltage) {
			mutex_lock(&pdata->status_mutex);
			pdata->btn_report = SND_JACK_BTN_1;
			mutex_unlock(&pdata->status_mutex);
		} else if (pdata->btn_volume_down_min_voltage < saradc_value && saradc_value <= pdata->btn_volume_down_max_voltage) {
			mutex_lock(&pdata->status_mutex);
			pdata->btn_report = SND_JACK_BTN_2;
			mutex_unlock(&pdata->status_mutex);
		} else {
			msleep(30);
			hi6402_plug_in_detect(pdata);
			goto end;
		}

		if (!check_headset_pluged_in(pdata)) {
			pr_info("%s(%u) : hs pluged out \n", __FUNCTION__, __LINE__);

			/* mask all btn interrupt*/
			mask_irq(pdata->irq[HI6402_IRQ_BTNUP_COMP1], true);
			mask_irq(pdata->irq[HI6402_IRQ_BTNDOWN_COMP1], true);
			goto end;
		}

		/*btn_report key event*/
		pr_info("%s(%u): btn_report type = 0x%x, status=0x%x\n",
				__FUNCTION__, __LINE__, pdata->btn_report, pdata->hs_status);
		hi6402_soc_jack_report(pdata->btn_report, HI6402_BTN_MASK);
	}

	/* mask btn down interrupt*/
	mask_irq(pdata->irq[HI6402_IRQ_BTNDOWN_COMP1], true);
	/* unmask btn up interrupt*/
	mask_irq(pdata->irq[HI6402_IRQ_BTNUP_COMP1], false);
end:
	wake_unlock(&pdata->wake_lock);

	return;
}