As this device is not vendor specific, I haven't included any "vendor,"
prefixes.  For my model I used "regulator-gpio" which takes a similar
approach.

Signed-off-by: NeilBrown <ne...@suse.de>

diff --git a/Documentation/devicetree/bindings/extcon/extcon-gpio.txt 
b/Documentation/devicetree/bindings/extcon/extcon-gpio.txt
new file mode 100644
index 000000000000..2346b61cc620
--- /dev/null
+++ b/Documentation/devicetree/bindings/extcon/extcon-gpio.txt
@@ -0,0 +1,26 @@
+* EXTCON detector using GPIO
+
+Required Properties:
+ - compatible: "extcon-gpio"
+ - gpios: gpio line that detects connector
+ - interrupts: interrupt generated by that gpio
+ - debounce-delay-ms: debouncing delay
+
+Optional Properties:
+ - label: name for connector.  If not given, device name is used.
+ - state-on: string to report when GPIO is high (else '0')
+ - state-off: string to report when GPIO is low (else '1')
+
+Example:
+
+antenna-detect {
+       compatible = "extcon-gpio";
+       label = "gps_antenna";
+       interrupt-parent = <&gpio5>;
+       interrupts = <16 IRQ_TYPE_EDGE_BOTH>;
+       gpios = <&gpio5 16 0>;
+       debounce-delay-ms = <10>;
+       state-on = "external";
+       state-off = "internal";
+};
+
diff --git a/drivers/extcon/extcon-gpio.c b/drivers/extcon/extcon-gpio.c
index f874c30ddbff..a683d2b99213 100644
--- a/drivers/extcon/extcon-gpio.c
+++ b/drivers/extcon/extcon-gpio.c
@@ -30,6 +30,9 @@
 #include <linux/gpio.h>
 #include <linux/extcon.h>
 #include <linux/extcon/extcon-gpio.h>
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
+#include <linux/of_irq.h>
 
 struct gpio_extcon_data {
        struct extcon_dev edev;
@@ -76,6 +79,45 @@ static ssize_t extcon_gpio_print_state(struct extcon_dev 
*edev, char *buf)
        return -EINVAL;
 }
 
+#ifdef CONFIG_OF
+static struct gpio_extcon_platform_data *
+gpio_extcon_parse(struct device *dev)
+{
+       struct gpio_extcon_platform_data *pdata;
+       struct device_node *np = dev->of_node;
+       u32 num;
+       int irq;
+
+       if (!np)
+               return NULL;
+       pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+       if (!pdata)
+               return NULL;
+       pdata->name = dev_name(dev);
+       of_property_read_string(np, "label", &pdata->name);
+       irq = irq_of_parse_and_map(np, 0);
+       pdata->irq_flags = irq_get_trigger_type(irq);
+       pdata->gpio = of_get_named_gpio(np, "gpios", 0);
+       if (pdata->gpio < 0)
+               return ERR_PTR(pdata->gpio);
+       if (irq != gpio_to_irq(pdata->gpio)) {
+               dev_err(dev, "IRQ doesn't match GPIO\n");
+               return ERR_PTR(-EINVAL);
+       }
+       if (of_property_read_u32(np, "debounce-delay-ms", &num) == 0)
+               pdata->debounce = num;
+       of_property_read_string(np, "state-on", &pdata->state_on);
+       of_property_read_string(np, "state-off", &pdata->state_off);
+       return pdata;
+}
+#else
+static inline struct gpio_extcon_platform_data *
+gpio_extcon_parse(struct device *dev)
+{
+       return NULL;
+}
+#endif
+
 static int gpio_extcon_probe(struct platform_device *pdev)
 {
        struct gpio_extcon_platform_data *pdata = pdev->dev.platform_data;
@@ -83,7 +125,11 @@ static int gpio_extcon_probe(struct platform_device *pdev)
        int ret = 0;
 
        if (!pdata)
+               pdata = gpio_extcon_parse(&pdev->dev);
+       if (!pdata)
                return -EBUSY;
+       if (IS_ERR(pdata))
+               return PTR_ERR(pdata);
        if (!pdata->irq_flags) {
                dev_err(&pdev->dev, "IRQ flag is not specified.\n");
                return -EINVAL;
@@ -148,12 +194,19 @@ static int gpio_extcon_remove(struct platform_device 
*pdev)
        return 0;
 }
 
+static const struct of_device_id gpio_extcon_match[] = {
+       { .compatible = "extcon-gpio" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, gpio_extcon_mastch);
+
 static struct platform_driver gpio_extcon_driver = {
        .probe          = gpio_extcon_probe,
        .remove         = gpio_extcon_remove,
        .driver         = {
                .name   = "extcon-gpio",
                .owner  = THIS_MODULE,
+               .of_match_table = gpio_extcon_match,
        },
 };
 

Attachment: signature.asc
Description: PGP signature

Reply via email to