]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - drivers/extcon/extcon-arizona.c
Merge tag 'efi-urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/mfleming...
[mirror_ubuntu-artful-kernel.git] / drivers / extcon / extcon-arizona.c
index 6c84e3d120435f9ad16d5afd3a030e98140b6f47..ba51588cc00054bfcf55b76782e3390daa470434 100644 (file)
 #define ARIZONA_ACCDET_MODE_HPL 1
 #define ARIZONA_ACCDET_MODE_HPR 2
 
+#define ARIZONA_MICD_CLAMP_MODE_JDL      0x4
+#define ARIZONA_MICD_CLAMP_MODE_JDH      0x5
+#define ARIZONA_MICD_CLAMP_MODE_JDL_GP5H 0x9
+#define ARIZONA_MICD_CLAMP_MODE_JDH_GP5H 0xb
+
 #define ARIZONA_HPDET_MAX 10000
 
 #define HPDET_DEBOUNCE 500
@@ -324,14 +329,17 @@ static void arizona_stop_mic(struct arizona_extcon_info *info)
 }
 
 static struct {
+       unsigned int threshold;
        unsigned int factor_a;
        unsigned int factor_b;
 } arizona_hpdet_b_ranges[] = {
-       {  5528,   362464 },
-       { 11084,  6186851 },
-       { 11065, 65460395 },
+       { 100,  5528,   362464 },
+       { 169, 11084,  6186851 },
+       { 169, 11065, 65460395 },
 };
 
+#define ARIZONA_HPDET_B_RANGE_MAX 0x3fb
+
 static struct {
        int min;
        int max;
@@ -386,7 +394,8 @@ static int arizona_hpdet_read(struct arizona_extcon_info *info)
                           >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;
 
                if (range < ARRAY_SIZE(arizona_hpdet_b_ranges) - 1 &&
-                   (val < 100 || val >= 0x3fb)) {
+                   (val < arizona_hpdet_b_ranges[range].threshold ||
+                    val >= ARIZONA_HPDET_B_RANGE_MAX)) {
                        range++;
                        dev_dbg(arizona->dev, "Moving to HPDET range %d\n",
                                range);
@@ -399,7 +408,8 @@ static int arizona_hpdet_read(struct arizona_extcon_info *info)
                }
 
                /* If we go out of range report top of range */
-               if (val < 100 || val >= 0x3fb) {
+               if (val < arizona_hpdet_b_ranges[range].threshold ||
+                   val >= ARIZONA_HPDET_B_RANGE_MAX) {
                        dev_dbg(arizona->dev, "Measurement out of range\n");
                        return ARIZONA_HPDET_MAX;
                }
@@ -664,9 +674,8 @@ err:
                           ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
 
        /* Just report headphone */
-       ret = extcon_update_state(info->edev,
-                                 1 << ARIZONA_CABLE_HEADPHONE,
-                                 1 << ARIZONA_CABLE_HEADPHONE);
+       ret = extcon_set_cable_state_(info->edev,
+                                     ARIZONA_CABLE_HEADPHONE, true);
        if (ret != 0)
                dev_err(arizona->dev, "Failed to report headphone: %d\n", ret);
 
@@ -723,9 +732,8 @@ err:
                           ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
 
        /* Just report headphone */
-       ret = extcon_update_state(info->edev,
-                                 1 << ARIZONA_CABLE_HEADPHONE,
-                                 1 << ARIZONA_CABLE_HEADPHONE);
+       ret = extcon_set_cable_state_(info->edev,
+                                     ARIZONA_CABLE_HEADPHONE, true);
        if (ret != 0)
                dev_err(arizona->dev, "Failed to report headphone: %d\n", ret);
 
@@ -812,16 +820,15 @@ static void arizona_micd_detect(struct work_struct *work)
        if (info->detecting && (val & ARIZONA_MICD_LVL_8)) {
                arizona_identify_headphone(info);
 
-               ret = extcon_update_state(info->edev,
-                                         1 << ARIZONA_CABLE_MICROPHONE,
-                                         1 << ARIZONA_CABLE_MICROPHONE);
+               ret = extcon_set_cable_state_(info->edev,
+                                             ARIZONA_CABLE_MICROPHONE, true);
 
                if (ret != 0)
                        dev_err(arizona->dev, "Headset report failed: %d\n",
                                ret);
 
                /* Don't need to regulate for button detection */
-               ret = regulator_allow_bypass(info->micvdd, false);
+               ret = regulator_allow_bypass(info->micvdd, true);
                if (ret != 0) {
                        dev_err(arizona->dev, "Failed to bypass MICVDD: %d\n",
                                ret);
@@ -962,10 +969,16 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
 
        if (arizona->pdata.jd_gpio5) {
                mask = ARIZONA_MICD_CLAMP_STS;
-               present = 0;
+               if (arizona->pdata.jd_invert)
+                       present = ARIZONA_MICD_CLAMP_STS;
+               else
+                       present = 0;
        } else {
                mask = ARIZONA_JD1_STS;
-               present = ARIZONA_JD1_STS;
+               if (arizona->pdata.jd_invert)
+                       present = 0;
+               else
+                       present = ARIZONA_JD1_STS;
        }
 
        ret = regmap_read(arizona->regmap, ARIZONA_AOD_IRQ_RAW_STATUS, &val);
@@ -1096,6 +1109,7 @@ static int arizona_extcon_probe(struct platform_device *pdev)
        struct arizona_pdata *pdata = &arizona->pdata;
        struct arizona_extcon_info *info;
        unsigned int val;
+       unsigned int clamp_mode;
        int jack_irq_fall, jack_irq_rise;
        int ret, mode, i, j;
 
@@ -1103,12 +1117,10 @@ static int arizona_extcon_probe(struct platform_device *pdev)
                return -EPROBE_DEFER;
 
        info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
-       if (!info) {
-               dev_err(&pdev->dev, "Failed to allocate memory\n");
+       if (!info)
                return -ENOMEM;
-       }
 
-       info->micvdd = devm_regulator_get(arizona->dev, "MICVDD");
+       info->micvdd = devm_regulator_get(&pdev->dev, "MICVDD");
        if (IS_ERR(info->micvdd)) {
                ret = PTR_ERR(info->micvdd);
                dev_err(arizona->dev, "Failed to get MICVDD: %d\n", ret);
@@ -1156,7 +1168,6 @@ static int arizona_extcon_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
        info->edev->name = "Headset Jack";
-       info->edev->dev.parent = arizona->dev;
 
        ret = devm_extcon_dev_register(&pdev->dev, info->edev);
        if (ret < 0) {
@@ -1174,7 +1185,6 @@ static int arizona_extcon_probe(struct platform_device *pdev)
 
        info->input->name = "Headset";
        info->input->phys = "arizona/extcon";
-       info->input->dev.parent = &pdev->dev;
 
        if (pdata->num_micd_configs) {
                info->micd_modes = pdata->micd_configs;
@@ -1305,15 +1315,21 @@ static int arizona_extcon_probe(struct platform_device *pdev)
                        regmap_write(arizona->regmap, ARIZONA_GPIO5_CTRL,
                                     val);
 
-                       regmap_update_bits(arizona->regmap,
-                                          ARIZONA_MICD_CLAMP_CONTROL,
-                                          ARIZONA_MICD_CLAMP_MODE_MASK, 0x9);
+                       if (arizona->pdata.jd_invert)
+                               clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDH_GP5H;
+                       else
+                               clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDL_GP5H;
                } else {
-                       regmap_update_bits(arizona->regmap,
-                                          ARIZONA_MICD_CLAMP_CONTROL,
-                                          ARIZONA_MICD_CLAMP_MODE_MASK, 0x4);
+                       if (arizona->pdata.jd_invert)
+                               clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDH;
+                       else
+                               clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDL;
                }
 
+               regmap_update_bits(arizona->regmap,
+                                  ARIZONA_MICD_CLAMP_CONTROL,
+                                  ARIZONA_MICD_CLAMP_MODE_MASK, clamp_mode);
+
                regmap_update_bits(arizona->regmap,
                                   ARIZONA_JACK_DETECT_DEBOUNCE,
                                   ARIZONA_MICD_CLAMP_DB,