extcon: madera: Read micd ranges from devicetree
authorRichard Fitzgerald <rf@opensource.wolfsonmicro.com>
Tue, 1 Aug 2017 12:01:14 +0000 (13:01 +0100)
committer강신형 <s47.kang@samsung.com>
Tue, 19 Jun 2018 07:52:27 +0000 (16:52 +0900)
This adds a devicetree node cirrus,micd-ranges to populate the
list of button levels and corresponding key events.

Change-Id: I2c4c4c6e938a137694a4e752367e25e5e637d2c4
Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
Documentation/devicetree/bindings/extcon/extcon-madera.txt
drivers/extcon/extcon-madera.c

index 7cd1cc6a6274d209a2edef373cbf1b91a1072607..16add298be40a72210d293e1b033e2394fc2c354 100644 (file)
@@ -77,6 +77,12 @@ Child node optional properties:
     register. A value >0xFFFF means use the default.
     (cs47l90, cs47l91)
 
+  - cirrus,micd-ranges : Microphone detection level and key configuration, this
+    field can be of variable length but should always be a multiple of 2 cells
+    long, each two cell group represents one button configuration
+    The first cell is the maximum impedance for this button in ohms
+    The second cell the key that should be reported to the input layer
+
   - cirrus,micd-configs : Headset polarity configurations, variable length but
     must be a multiple of 5 cells, each 5-cell group represents one
     polarity configuration
index e01caf272f6df17e59a9538347df4189e950b747..42f8c891855535f5839b41f74aae07f52f339705 100644 (file)
@@ -2324,6 +2324,47 @@ static void madera_micd_set_level(struct madera *madera, int index,
        regmap_update_bits(madera->regmap, reg, mask, level);
 }
 
+static void madera_extcon_of_get_micd_ranges(struct madera_extcon *info,
+                                           struct fwnode_handle *node,
+                                           struct madera_accdet_pdata *pdata)
+{
+       struct madera_micd_range *micd_ranges;
+       u32 *values;
+       int nvalues, nranges, i, j;
+       int ret;
+
+       nvalues = fwnode_property_read_u32_array(node, "cirrus,micd-ranges",
+                                                NULL, 0);
+       if (nvalues < 0)
+               return;
+
+       values = kmalloc_array(nvalues, sizeof(u32), GFP_KERNEL);
+       if (!values)
+               return;
+
+       ret = fwnode_property_read_u32_array(node, "cirrus,micd-ranges",
+                                            values, nvalues);
+       if (ret < 0)
+               goto err;
+
+       nranges = nvalues / 2;
+       micd_ranges = devm_kcalloc(info->dev,
+                                  nranges,
+                                  sizeof(struct madera_micd_range),
+                                  GFP_KERNEL);
+
+       for (i = 0, j = 0; i < nranges; ++i) {
+               micd_ranges[i].max = values[j++];
+               micd_ranges[i].key = values[j++];
+       }
+
+       pdata->micd_ranges = micd_ranges;
+       pdata->num_micd_ranges = nranges;
+
+err:
+       kfree(values);
+}
+
 static void madera_extcon_get_micd_configs(struct madera_extcon *info,
                                           struct fwnode_handle *node,
                                           struct madera_accdet_pdata *pdata)
@@ -2498,6 +2539,7 @@ 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);
+       madera_extcon_of_get_micd_ranges(info, node, pdata);
 
        if (info->micd_modes[0].gpio)
                gpio_status = GPIOD_OUT_HIGH;