static int max14688_read_mic_impedence (struct device *dev)
{
	struct qpnp_vadc_result result;
	int acc_read_value = 0;

	int rc;

	rc = qpnp_vadc_read_lge(P_MUX6_1_1, &result);
	if (rc < 0) {
		if (rc == -ETIMEDOUT) {
			pr_err("[DEBUG] button_pressed : adc read timeout \n");
		} else {
			pr_err("button_pressed: adc read error - %d\n", rc);
		}
	}

	acc_read_value = (int)result.physical;
	log_dbg("%s[adc value =  %d]\n", __func__, acc_read_value);

	return acc_read_value;
}
Exemplo n.º 2
0
static int lge_hsd_probe(struct platform_device *pdev)
{
	int ret = 0;
	struct max1462x_platform_data *pdata = pdev->dev.platform_data;


	struct hsd_info *hi;

	HSD_DBG("lge_hsd_probe\n");

	hi = kzalloc(sizeof(struct hsd_info), GFP_KERNEL);

	if ( hi == NULL) {
		HSD_ERR("Failed to allloate headset per device info\n");
		return -ENOMEM;
	}

	if(pdev->dev.of_node){
		pdata = devm_kzalloc(&pdev->dev,sizeof(struct max1462x_platform_data),GFP_KERNEL);
		if(!pdata){
			HSD_ERR("Failed to allocate memory\n");
			return -ENOMEM;
		}
		pdev->dev.platform_data = pdata;

		max1462x_parse_dt(&pdev->dev,pdata);
	} else {
		pdata = devm_kzalloc(&pdev->dev,sizeof(struct max1462x_platform_data),GFP_KERNEL);
		if(!pdata){
			HSD_ERR("Failed to allocate memory\n");
			return -ENOMEM;
		}
		else
			pdata = pdev->dev.platform_data;
	}
	hi->key_code = pdata->key_code;

	platform_set_drvdata(pdev, hi);

	atomic_set(&hi->btn_state, 0);
	atomic_set(&hi->is_3_pole_or_not, 1);
	atomic_set(&hi->irq_key_enabled, FALSE);

	hi->gpio_mic_en = pdata->gpio_mic_en;
	hi->gpio_detect = pdata->gpio_detect;
	hi->gpio_key = pdata->gpio_key;
	hi->gpio_set_value_func = pdata->gpio_set_value_func;
	hi->gpio_get_value_func = pdata->gpio_get_value_func;
#ifdef CONFIG_SWITCH_MAX1462X_WA
	hi->latency_for_key = msecs_to_jiffies(80);
#else
	hi->latency_for_key = msecs_to_jiffies(50); /* convert milli to jiffies */
#endif
	mutex_init(&hi->mutex_lock);
	INIT_WORK(&hi->work, detect_work);
	INIT_DELAYED_WORK(&hi->work_for_key_pressed, button_pressed);
	INIT_DELAYED_WORK(&hi->work_for_key_released, button_released);

	ret = gpio_request(hi->gpio_mic_en, "gpio_mic_en");
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_mic_en) gpio_request\n", hi->gpio_mic_en);
		goto error_02;
	}

	ret = gpio_direction_output(hi->gpio_mic_en, 0);
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_mic_en) gpio_direction_input\n", hi->gpio_mic_en);
		goto error_02;
	}
	HSD_DBG("gpio_get_value_cansleep(hi->gpio_mic_en) = %d\n", gpio_get_value_cansleep(hi->gpio_mic_en));

	/* init gpio_detect */
	ret = gpio_request(hi->gpio_detect, "gpio_detect");
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_det) gpio_request\n", hi->gpio_detect);
		goto error_03;
	}

	ret = gpio_direction_input(hi->gpio_detect);
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_det) gpio_direction_input\n", hi->gpio_detect);
		goto error_03;
	}

	/*init gpio_key */
	ret = gpio_request(hi->gpio_key, "gpio_key");
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_key) gpio_request\n", hi->gpio_key);
		goto error_04;
	}

	ret = gpio_direction_input(hi->gpio_key);
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_key) gpio_direction_input\n", hi->gpio_key);
		goto error_04;
	}


	/* initialize irq of gpio_key */
	hi->irq_key = gpio_to_irq(hi->gpio_key);

	HSD_DBG("hi->irq_key = %d\n", hi->irq_key);

	if (hi->irq_key < 0) {
		HSD_ERR("Failed to get interrupt number\n");
		ret = hi->irq_key;
		goto error_06;
	}
	ret = request_threaded_irq(hi->irq_key, NULL, button_irq_handler,
			IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING|IRQF_ONESHOT,
			pdev->name, hi);
	if (ret) {
		HSD_ERR("failed to request button irq\n");
		goto error_06;
	}

	ret = irq_set_irq_wake(hi->irq_key, 1);
	if (ret < 0) {
		HSD_ERR("Failed to set irq_key interrupt wake\n");
		goto error_06;
	}

	hi->irq_detect = gpio_to_irq(hi->gpio_detect);
	HSD_DBG("hi->irq_detect = %d\n", hi->irq_detect);

	if (hi->irq_detect < 0) {
		HSD_ERR("Failed to get interrupt number\n");
		ret = hi->irq_detect;
		goto error_07;
	}
	ret = request_threaded_irq(hi->irq_detect, NULL, earjack_det_irq_handler,
			IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING|IRQF_ONESHOT,
			pdev->name, hi);

	if (ret) {
		HSD_ERR("failed to request button irq\n");
		goto error_07;
	}

	ret = irq_set_irq_wake(hi->irq_detect, 1);
	if (ret < 0) {
		HSD_ERR("Failed to set gpio_detect interrupt wake\n");
		goto error_07;
	}
	/* initialize switch device */
	hi->sdev.name = pdata->switch_name;
	hi->sdev.print_state = lge_hsd_print_state;
	hi->sdev.print_name = lge_hsd_print_name;

	ret = switch_dev_register(&hi->sdev);
	if (ret < 0) {
		HSD_ERR("Failed to register switch device\n");
		goto error_08;
	}

	/* initialize input device */
	hi->input = input_allocate_device();
	if (!hi->input) {
		HSD_ERR("Failed to allocate input device\n");
		ret = -ENOMEM;
		goto error_09;
	}

	hi->input->name = pdata->keypad_name;

	hi->input->id.vendor    = 0x0001;
	hi->input->id.product   = 1;
	hi->input->id.version   = 1;

	/* headset tx noise */
	{
		struct qpnp_vadc_result result;
		int acc_read_value = 0;
		int i, rc = 0;
		int count = 3;

		for (i = 0; i < count; i++)
		{
/* LIMIT: Include ONLY A1, B1, Vu3, Z models used MSM8974 AA/AB */
#ifdef CONFIG_ADC_READY_CHECK_JB
			rc = qpnp_vadc_read_lge(P_MUX6_1_1,&result);
#else
			/* MUST BE IMPLEMENT :
			 * After MSM8974 AC and later version(PMIC combination change),
			 * ADC AMUX of PMICs are separated in each dual PMIC.
			 *
			 * Ref.
			 * qpnp-adc-voltage.c : *qpnp_get_vadc(), qpnp_vadc_read().
			 * qpnp-charger.c     : new implementation by QCT.
			 */
#endif
			if (rc < 0)
			{
				if (rc == -ETIMEDOUT) {
					pr_err("[DEBUG]adc read timeout \n");
				} else {
					pr_err("[DEBUG]adc read error - %d\n", rc);
				}
			}
			else
			{
				acc_read_value = (int)result.physical;
				pr_info("%s: acc_read_value - %d\n", __func__, (int)result.physical);
				break;
			}
		}
	}
	set_bit(EV_SYN, hi->input->evbit);
	set_bit(EV_KEY, hi->input->evbit);
	set_bit(EV_SW, hi->input->evbit);
	set_bit(hi->key_code, hi->input->keybit);
	set_bit(SW_HEADPHONE_INSERT, hi->input->swbit);
	set_bit(SW_MICROPHONE_INSERT, hi->input->swbit);
	input_set_capability(hi->input, EV_KEY, KEY_MEDIA);
	input_set_capability(hi->input, EV_KEY, KEY_VOLUMEUP);
	input_set_capability(hi->input, EV_KEY, KEY_VOLUMEDOWN);
	ret = input_register_device(hi->input);
	if (ret) {
		HSD_ERR("Failed to register input device\n");
		goto error_09;
	}

	if (!(hi->gpio_get_value_func(hi->gpio_detect)))

#ifdef CONFIG_MAX1462X_USE_LOCAL_WORK_QUEUE
		/* to detect in initialization with eacjack insertion */
		queue_work(local_max1462x_workqueue, &(hi->work));
#else
	/* to detect in initialization with eacjack insertion */
	schedule_work(&(hi->work));
#endif
	return ret;

error_09:
	input_free_device(hi->input);
error_08:
	switch_dev_unregister(&hi->sdev);
error_07:
	free_irq(hi->irq_detect, 0);
error_06:
	free_irq(hi->irq_key, 0);
error_04:
	gpio_free(hi->gpio_key);
error_03:
	gpio_free(hi->gpio_detect);
error_02:
	gpio_free(hi->gpio_mic_en);
	kfree(hi);
	return ret;
}
Exemplo n.º 3
0
static void button_pressed(struct work_struct *work)
{
	struct delayed_work *dwork = container_of(work, struct delayed_work, work);
	struct hsd_info *hi = container_of(dwork, struct hsd_info, work_for_key_pressed);
	struct qpnp_vadc_result result;
	int acc_read_value = 0;
	int i, rc;
	struct ear_3button_info_table *table;
	int table_size = ARRAY_SIZE(max1462x_ear_3button_type_data);

	if (hi->gpio_get_value_func(hi->gpio_detect)||(atomic_read(&hi->is_3_pole_or_not)))
	{
		HSD_ERR("button_pressed but 4 pole ear jack is plugged out already! just ignore the event.\n");
		return;
	}

/* LIMIT: Include ONLY A1, B1, Vu3, Z models used MSM8974 AA/AB */
#ifdef CONFIG_ADC_READY_CHECK_JB
	rc = qpnp_vadc_read_lge(P_MUX6_1_1,&result);
#else
	/* MUST BE IMPLEMENT :
	 * After MSM8974 AC and later version(PMIC combination change),
	 * ADC AMUX of PMICs are separated in each dual PMIC.
	 *
	 * Ref.
	 * qpnp-adc-voltage.c : *qpnp_get_vadc(), qpnp_vadc_read().
	 * qpnp-charger.c     : new implementation by QCT.
	 */
	return;
#endif
	if (rc < 0) {
		if (rc == -ETIMEDOUT) {
			pr_err("[DEBUG] button_pressed : adc read timeout \n");
		} else {
			pr_err("button_pressed: adc read error - %d\n", rc);
		}
	}
	acc_read_value = (int)result.physical;
	pr_info("%s: acc_read_value - %d\n", __func__, acc_read_value);

	for (i = 0; i < table_size; i++) {
		table = &max1462x_ear_3button_type_data[i];
		/* [AUDIO_BSP] 20130110, junday.lee,
		 * include min value '=' for 1 button earjack (ADC value= 0)
		 */
		if ((acc_read_value <= table->PERMISS_REANGE_MAX) &&
				(acc_read_value >= table->PERMISS_REANGE_MIN)) {
			HSD_DBG("button_pressed \n");
			atomic_set(&hi->btn_state, 1);
			switch(table->ADC_HEADSET_BUTTON){
				case  KEY_MEDIA :
					input_report_key(hi->input, KEY_MEDIA, 1);
					pr_info("%s: KEY_MEDIA \n", __func__);
					break;
				case KEY_VOLUMEUP :
					input_report_key(hi->input, KEY_VOLUMEUP, 1);
					pr_info("%s: KEY_VOLUMEUP \n", __func__);
					break;
				case KEY_VOLUMEDOWN :
					input_report_key(hi->input, KEY_VOLUMEDOWN, 1);
					pr_info("%s: KEY_VOLUMDOWN \n", __func__);
					break;
				default:
					break;
			}
			table->PRESS_OR_NOT = 1;
			input_sync(hi->input);
			break;
		}
	}
	return;
}
static void button_pressed(struct work_struct *work)
{
	struct delayed_work *dwork = container_of(work, struct delayed_work, work);
	struct hsd_info *hi = container_of(dwork, struct hsd_info, work_for_key_pressed);
	struct qpnp_vadc_result result;
	int acc_read_value = 0;
	int i, rc;
	struct ear_3button_info_table *table;
	int table_size = ARRAY_SIZE(max1462x_ear_3button_type_data);

	if (hi->gpio_get_value_func(hi->gpio_detect) || (atomic_read(&hi->is_3_pole_or_not))) {
		HSD_ERR("button_pressed but 4 pole ear jack is plugged out already! just ignore the event.\n");
		return;
	}

	rc = qpnp_vadc_read_lge(P_MUX6_1_1,&result);

	if (rc < 0) {
		if (rc == -ETIMEDOUT) {
			pr_err("[DEBUG] button_pressed : adc read timeout \n");
		} else {
			pr_err("button_pressed: adc read error - %d\n", rc);
		}
	}
	acc_read_value = (int)result.physical;
	pr_info("%s: acc_read_value - %d\n", __func__, acc_read_value);

	for (i = 0; i < table_size; i++) {
		table = &max1462x_ear_3button_type_data[i];
		/* [AUDIO_BSP] 20130110, junday.lee,
		 * include min value '=' for 1 button earjack (ADC value= 0)
		 */
		if ((acc_read_value <= table->PERMISS_REANGE_MAX) &&
				(acc_read_value >= table->PERMISS_REANGE_MIN)) {
			HSD_DBG("%s: button_pressed  and acc_read_value :%d \n ", __func__, acc_read_value);
			atomic_set(&hi->btn_state, 1);
			switch (table->ADC_HEADSET_BUTTON) {
			case  KEY_MEDIA:
				input_report_key(hi->input, KEY_MEDIA, 1);
				pr_info("%s: KEY_MEDIA \n", __func__);
				break;
			case KEY_VOLUMEUP:
				input_report_key(hi->input, KEY_VOLUMEUP, 1);
				pr_info("%s: KEY_VOLUMEUP \n", __func__);
				break;
			case KEY_VOLUMEDOWN:
				input_report_key(hi->input, KEY_VOLUMEDOWN, 1);
				pr_info("%s: KEY_VOLUMDOWN \n", __func__);
				break;

			case 582: //KEY_ASSIST
				input_report_key(hi->input, 582, 1);
				pr_info("%s: KEY_ASSIST \n", __func__);
				break;
			default:
				break;
			}
			table->PRESS_OR_NOT = 1;
			input_sync(hi->input);
			break;
		}
	}
	return;
}