diff options
-rw-r--r-- | arch/arm/mach-ux500/include/mach/abx500-accdet.h | 2 | ||||
-rw-r--r-- | drivers/input/misc/ab8500-accdet.c | 25 | ||||
-rw-r--r-- | drivers/input/misc/abx500-accdet.c | 30 |
3 files changed, 50 insertions, 7 deletions
diff --git a/arch/arm/mach-ux500/include/mach/abx500-accdet.h b/arch/arm/mach-ux500/include/mach/abx500-accdet.h index cdd78cd7d0c..9871ae11530 100644 --- a/arch/arm/mach-ux500/include/mach/abx500-accdet.h +++ b/arch/arm/mach-ux500/include/mach/abx500-accdet.h @@ -101,6 +101,7 @@ * @accdet2122_th Voltage thresholds for accdet21 and accdet22 inputs. * @is_detection_inverted Whether the accessory insert/removal, button * press/release irq's are inverted. + * @mic_ctrl Gpio to select between CVBS and MIC. */ struct abx500_accdet_platform_data { int btn_keycode; @@ -108,6 +109,7 @@ struct abx500_accdet_platform_data { u8 accdet2122_th; unsigned int video_ctrl_gpio; bool is_detection_inverted; + unsigned int mic_ctrl; }; /* Enumerations */ diff --git a/drivers/input/misc/ab8500-accdet.c b/drivers/input/misc/ab8500-accdet.c index 8faa7c425a5..59ad959e909 100644 --- a/drivers/input/misc/ab8500-accdet.c +++ b/drivers/input/misc/ab8500-accdet.c @@ -351,18 +351,33 @@ static void ab8500_set_av_switch(struct abx500_ad *dd, ret = gpio_direction_input(dd->pdata->video_ctrl_gpio); dd->gpio35_dir_set = 0; ret = gpio_direction_output(dd->pdata->video_ctrl_gpio, 0); + if (dd->pdata->mic_ctrl) + gpio_direction_output(dd->pdata->mic_ctrl, 0); } else if (!dd->gpio35_dir_set) { ret = gpio_direction_output(dd->pdata->video_ctrl_gpio, dir == AUDIO_IN ? 1 : 0); if (ret < 0) { dev_err(&dd->pdev->dev, - "%s: Output video ctrl signal failed (%d).\n", + "%s: video_ctrl pin output config failed (%d).\n", __func__, ret); - } else { - dd->gpio35_dir_set = 1; - dev_dbg(&dd->pdev->dev, "AV-SWITCH: %s\n", - dir == AUDIO_IN ? "AUDIO_IN" : "VIDEO_OUT"); + return; + } + + if (dd->pdata->mic_ctrl) { + ret = gpio_direction_output(dd->pdata->mic_ctrl, + dir == AUDIO_IN ? 1 : 0); + if (ret < 0) { + dev_err(&dd->pdev->dev, + "%s: mic_ctrl pin output" + "config failed (%d).\n", + __func__, ret); + return; + } } + + dd->gpio35_dir_set = 1; + dev_dbg(&dd->pdev->dev, "AV-SWITCH: %s\n", + dir == AUDIO_IN ? "AUDIO_IN" : "VIDEO_OUT"); } else { gpio_set_value(dd->pdata->video_ctrl_gpio, dir == AUDIO_IN ? 1 : 0); diff --git a/drivers/input/misc/abx500-accdet.c b/drivers/input/misc/abx500-accdet.c index c0d1cb04a0e..5c4e96c73d6 100644 --- a/drivers/input/misc/abx500-accdet.c +++ b/drivers/input/misc/abx500-accdet.c @@ -786,7 +786,25 @@ static int abx500_accessory_init(struct platform_device *pdev) } } - (ret = create_btn_input_dev(dd)); + if (dd->pdata->mic_ctrl) { + ret = gpio_is_valid(dd->pdata->mic_ctrl); + if (!ret) { + dev_err(&pdev->dev, + "%s: Mic ctrl GPIO invalid (%d).\n", __func__, + dd->pdata->mic_ctrl); + + goto mic_ctrl_fail; + } + ret = gpio_request(dd->pdata->mic_ctrl, + "Mic Control"); + if (ret) { + dev_err(&pdev->dev, "%s: Get mic ctrl GPIO" + "failed.\n", __func__); + goto mic_ctrl_fail; + } + } + + ret = create_btn_input_dev(dd); if (ret < 0) { dev_err(&pdev->dev, "%s: create_button_input_dev failed.\n", __func__); @@ -827,6 +845,9 @@ fail_no_mem_for_wq: fail_no_regulators: input_unregister_device(dd->btn_input_dev); fail_no_btn_input_dev: + if (dd->pdata->mic_ctrl) + gpio_free(dd->pdata->mic_ctrl); +mic_ctrl_fail: if (dd->pdata->video_ctrl_gpio) gpio_free(dd->pdata->video_ctrl_gpio); return ret; @@ -842,7 +863,12 @@ static void abx500_accessory_cleanup(struct abx500_ad *dd) dd->jack_type = JACK_TYPE_UNSPECIFIED; config_accdetect(dd); - gpio_free(dd->pdata->video_ctrl_gpio); + if (dd->pdata->mic_ctrl) + gpio_free(dd->pdata->mic_ctrl); + + if (dd->pdata->video_ctrl_gpio) + gpio_free(dd->pdata->video_ctrl_gpio); + input_unregister_device(dd->btn_input_dev); free_regulators(dd); |