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; }
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; }
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; }