[PATCH] extcon-gpio: add devicetree support.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




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 <neilb@xxxxxxx>

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


[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]
  Powered by Linux