From 4d34365898fca7b1467f5467fb7675f04f2d4b77 Mon Sep 17 00:00:00 2001 From: "Karpovich@cirrus.com" Date: Thu, 12 Jul 2018 13:03:40 -0500 Subject: [PATCH] extcon: madera: Add support for 2 gpio mic bias switch. This is port from switch-madera driver. Change-Id: I491a03a9cebfca1ff8ee9f71d6c9a3000e21d5a8 Signed-off-by: Vlad Karpovich Signed-off-by: Ravi Vembu Mot-CRs-Fixed: (CR) Change-Id: I491a03a9cebfca1ff8ee9f71d6c9a3000e21d5a8 Reviewed-on: https://gerrit.mot.com/1209118 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Reviewed-by: Rav(CR) Vembu Tested-by: Jira Key Submit-Approved: Jira Key --- .../bindings/extcon/extcon-madera.txt | 6 +++- drivers/extcon/extcon-madera.c | 33 +++++++++++++------ include/linux/extcon/extcon-madera.h | 2 +- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/Documentation/devicetree/bindings/extcon/extcon-madera.txt b/Documentation/devicetree/bindings/extcon/extcon-madera.txt index 7cd1cc6a6274..30b8df8bb833 100644 --- a/Documentation/devicetree/bindings/extcon/extcon-madera.txt +++ b/Documentation/devicetree/bindings/extcon/extcon-madera.txt @@ -18,9 +18,13 @@ Optional properties: First cell is the value for the SW1_MODE Second cell is the value for the SW2_MODE (cs47l90, cs47l91) - - cirrus,micd-pol-gpios : GPIO specifier for the GPIO controlling the headset + - cirrus,micd-pol-gpio : GPIO specifier for the GPIO controlling the headset polarity if one exists. One cell for each child node. + - cirrus,micd-pol-alt-gpio : GPIO specifier for second GPIO controlling the headset + polarity if one exist. If 2 alt gpio is configured, its value will be set opposite + to the first GPIO. + Child node mandatory properties: - reg : output number this configuration applies to, must be 1 diff --git a/drivers/extcon/extcon-madera.c b/drivers/extcon/extcon-madera.c index c6e1c9f4bd85..90c4339c2ba8 100644 --- a/drivers/extcon/extcon-madera.c +++ b/drivers/extcon/extcon-madera.c @@ -946,9 +946,12 @@ static void madera_extcon_set_mode(struct madera_extcon *info, int mode) info->micd_modes[mode].bias, info->micd_modes[mode].gpio, info->micd_modes[mode].hp_gnd); - if (info->micd_pol_gpio > 0) - gpiod_set_value_cansleep(info->micd_pol_gpio, - info->micd_modes[mode].gpio); + if (info->micd_pol_gpio[0] > 0) + gpiod_set_value_cansleep(info->micd_pol_gpio[0], + info->micd_modes[mode].gpio); + if (info->micd_pol_gpio[1] > 0) + gpiod_set_value_cansleep(info->micd_pol_gpio[1], + !info->micd_modes[mode].gpio); switch (madera->type) { case CS47L35: @@ -2455,15 +2458,20 @@ static void madera_extcon_process_accdet_node(struct madera_extcon *info, madera_extcon_get_hpd_pins(info, node, pdata); madera_extcon_get_micd_configs(info, node, pdata); - info->micd_pol_gpio = devm_get_gpiod_from_child(madera->dev, + info->micd_pol_gpio[0] = devm_get_gpiod_from_child(madera->dev, "cirrus,micd-pol", node); - if (IS_ERR(info->micd_pol_gpio)) { + if (IS_ERR(info->micd_pol_gpio[0])) { dev_warn(info->dev, "Malformed cirrus,micd-pol-gpios ignored: %ld\n", - PTR_ERR(info->micd_pol_gpio)); - info->micd_pol_gpio = 0; + PTR_ERR(info->micd_pol_gpio[0])); + info->micd_pol_gpio[0] = 0; } + info->micd_pol_gpio[1] = devm_get_gpiod_from_child(madera->dev, + "cirrus,micd-pol-alt", + node); + if (IS_ERR(info->micd_pol_gpio[1])) + info->micd_pol_gpio[1] = 0; } static int madera_extcon_get_device_pdata(struct madera_extcon *info) @@ -2531,12 +2539,16 @@ static void madera_extcon_dump_config(struct madera_extcon *info) MADERA_EXTCON_PDATA_DUMP(micd_open_circuit_declare, "%u"); MADERA_EXTCON_PDATA_DUMP(micd_software_compare, "%u"); - if (info->micd_pol_gpio > 0) + if (info->micd_pol_gpio[0] > 0) dev_dbg(info->dev, "micd_pol_gpio: %d\n", - desc_to_gpio(info->micd_pol_gpio)); + desc_to_gpio(info->micd_pol_gpio[0])); else dev_dbg(info->dev, "micd_pol_gpio: 0\n"); + if (info->micd_pol_gpio[1] > 0) + dev_dbg(info->dev, "micd_pol_gpio-alt: %d\n", + desc_to_gpio(info->micd_pol_gpio[1])); + dev_dbg(info->dev, "\tmicd_ranges {\n"); for (j = 0; j < info->num_micd_ranges; ++j) dev_dbg(info->dev, "\t\tmax: %d key: %d\n", @@ -2881,7 +2893,8 @@ static int madera_extcon_probe(struct platform_device *pdev) return ret; } - info->micd_pol_gpio = gpio_to_desc(pdata->micd_pol_gpio); + info->micd_pol_gpio[0] = gpio_to_desc(pdata->micd_pol_gpio); + info->micd_pol_gpio[1] = 0; } else { ret = madera_extcon_get_device_pdata(info); if (ret < 0) diff --git a/include/linux/extcon/extcon-madera.h b/include/linux/extcon/extcon-madera.h index 407c6df7d46e..ecf07bca8c76 100644 --- a/include/linux/extcon/extcon-madera.h +++ b/include/linux/extcon/extcon-madera.h @@ -70,7 +70,7 @@ struct madera_extcon { struct regulator *micvdd; struct input_dev *input; struct extcon_dev *edev; - struct gpio_desc *micd_pol_gpio; + struct gpio_desc *micd_pol_gpio[2]; u16 last_jackdet; int hp_tuning_level;