]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/mfd/palmas.c
Merge branch 'slab/for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/penber...
[karo-tx-linux.git] / drivers / mfd / palmas.c
index a345f9bb7b4758765725cf2c056303950ecc1c02..4f8d6e6b19aa3d023173a20537fce2bdf46e5281 100644 (file)
 #include <linux/err.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/palmas.h>
-
-static const struct resource gpadc_resource[] = {
-       {
-               .name = "EOC_SW",
-               .start = PALMAS_GPADC_EOC_SW_IRQ,
-               .end = PALMAS_GPADC_EOC_SW_IRQ,
-               .flags = IORESOURCE_IRQ,
-       }
-};
-
-static const struct resource usb_resource[] = {
-       {
-               .name = "ID",
-               .start = PALMAS_ID_OTG_IRQ,
-               .end = PALMAS_ID_OTG_IRQ,
-               .flags = IORESOURCE_IRQ,
-       },
-       {
-               .name = "ID_WAKEUP",
-               .start = PALMAS_ID_IRQ,
-               .end = PALMAS_ID_IRQ,
-               .flags = IORESOURCE_IRQ,
-       },
-       {
-               .name = "VBUS",
-               .start = PALMAS_VBUS_OTG_IRQ,
-               .end = PALMAS_VBUS_OTG_IRQ,
-               .flags = IORESOURCE_IRQ,
-       },
-       {
-               .name = "VBUS_WAKEUP",
-               .start = PALMAS_VBUS_IRQ,
-               .end = PALMAS_VBUS_IRQ,
-               .flags = IORESOURCE_IRQ,
-       },
-};
-
-static const struct resource rtc_resource[] = {
-       {
-               .name = "RTC_ALARM",
-               .start = PALMAS_RTC_ALARM_IRQ,
-               .end = PALMAS_RTC_ALARM_IRQ,
-               .flags = IORESOURCE_IRQ,
-       },
-};
-
-static const struct resource pwron_resource[] = {
-       {
-               .name = "PWRON_BUTTON",
-               .start = PALMAS_PWRON_IRQ,
-               .end = PALMAS_PWRON_IRQ,
-               .flags = IORESOURCE_IRQ,
-       },
-};
+#include <linux/of_platform.h>
 
 enum palmas_ids {
        PALMAS_PMIC_ID,
@@ -111,20 +58,14 @@ static const struct mfd_cell palmas_children[] = {
        },
        {
                .name = "palmas-rtc",
-               .num_resources = ARRAY_SIZE(rtc_resource),
-               .resources = rtc_resource,
                .id = PALMAS_RTC_ID,
        },
        {
                .name = "palmas-pwrbutton",
-               .num_resources = ARRAY_SIZE(pwron_resource),
-               .resources = pwron_resource,
                .id = PALMAS_PWRBUTTON_ID,
        },
        {
                .name = "palmas-gpadc",
-               .num_resources = ARRAY_SIZE(gpadc_resource),
-               .resources = gpadc_resource,
                .id = PALMAS_GPADC_ID,
        },
        {
@@ -141,8 +82,6 @@ static const struct mfd_cell palmas_children[] = {
        },
        {
                .name = "palmas-usb",
-               .num_resources = ARRAY_SIZE(usb_resource),
-               .resources = usb_resource,
                .id = PALMAS_USB_ID,
        }
 };
@@ -308,17 +247,56 @@ static struct regmap_irq_chip palmas_irq_chip = {
                        PALMAS_INT1_MASK),
 };
 
+static void __devinit palmas_dt_to_pdata(struct device_node *node,
+               struct palmas_platform_data *pdata)
+{
+       int ret;
+       u32 prop;
+
+       ret = of_property_read_u32(node, "ti,mux_pad1", &prop);
+       if (!ret) {
+               pdata->mux_from_pdata = 1;
+               pdata->pad1 = prop;
+       }
+
+       ret = of_property_read_u32(node, "ti,mux_pad2", &prop);
+       if (!ret) {
+               pdata->mux_from_pdata = 1;
+               pdata->pad2 = prop;
+       }
+
+       /* The default for this register is all masked */
+       ret = of_property_read_u32(node, "ti,power_ctrl", &prop);
+       if (!ret)
+               pdata->power_ctrl = prop;
+       else
+               pdata->power_ctrl = PALMAS_POWER_CTRL_NSLEEP_MASK |
+                                       PALMAS_POWER_CTRL_ENABLE1_MASK |
+                                       PALMAS_POWER_CTRL_ENABLE2_MASK;
+}
+
 static int __devinit palmas_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
        struct palmas *palmas;
        struct palmas_platform_data *pdata;
+       struct device_node *node = i2c->dev.of_node;
        int ret = 0, i;
        unsigned int reg, addr;
        int slave;
        struct mfd_cell *children;
 
        pdata = dev_get_platdata(&i2c->dev);
+
+       if (node && !pdata) {
+               pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL);
+
+               if (!pdata)
+                       return -ENOMEM;
+
+               palmas_dt_to_pdata(node, pdata);
+       }
+
        if (!pdata)
                return -EINVAL;
 
@@ -364,7 +342,7 @@ static int __devinit palmas_i2c_probe(struct i2c_client *i2c,
        regmap_write(palmas->regmap[slave], addr, reg);
 
        ret = regmap_add_irq_chip(palmas->regmap[slave], palmas->irq,
-                       IRQF_ONESHOT | IRQF_TRIGGER_LOW, -1, &palmas_irq_chip,
+                       IRQF_ONESHOT | IRQF_TRIGGER_LOW, 0, &palmas_irq_chip,
                        &palmas->irq_data);
        if (ret < 0)
                goto err;
@@ -377,11 +355,11 @@ static int __devinit palmas_i2c_probe(struct i2c_client *i2c,
                reg = pdata->pad1;
                ret = regmap_write(palmas->regmap[slave], addr, reg);
                if (ret)
-                       goto err;
+                       goto err_irq;
        } else {
                ret = regmap_read(palmas->regmap[slave], addr, &reg);
                if (ret)
-                       goto err;
+                       goto err_irq;
        }
 
        if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_0))
@@ -412,11 +390,11 @@ static int __devinit palmas_i2c_probe(struct i2c_client *i2c,
                reg = pdata->pad2;
                ret = regmap_write(palmas->regmap[slave], addr, reg);
                if (ret)
-                       goto err;
+                       goto err_irq;
        } else {
                ret = regmap_read(palmas->regmap[slave], addr, &reg);
                if (ret)
-                       goto err;
+                       goto err_irq;
        }
 
        if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_4))
@@ -439,18 +417,43 @@ static int __devinit palmas_i2c_probe(struct i2c_client *i2c,
 
        ret = regmap_write(palmas->regmap[slave], addr, reg);
        if (ret)
-               goto err;
+               goto err_irq;
+
+       /*
+        * If we are probing with DT do this the DT way and return here
+        * otherwise continue and add devices using mfd helpers.
+        */
+       if (node) {
+               ret = of_platform_populate(node, NULL, NULL, &i2c->dev);
+               if (ret < 0)
+                       goto err_irq;
+               else
+                       return ret;
+       }
 
        children = kmemdup(palmas_children, sizeof(palmas_children),
                           GFP_KERNEL);
        if (!children) {
                ret = -ENOMEM;
-               goto err;
+               goto err_irq;
        }
 
        children[PALMAS_PMIC_ID].platform_data = pdata->pmic_pdata;
        children[PALMAS_PMIC_ID].pdata_size = sizeof(*pdata->pmic_pdata);
 
+       children[PALMAS_GPADC_ID].platform_data = pdata->gpadc_pdata;
+       children[PALMAS_GPADC_ID].pdata_size = sizeof(*pdata->gpadc_pdata);
+
+       children[PALMAS_RESOURCE_ID].platform_data = pdata->resource_pdata;
+       children[PALMAS_RESOURCE_ID].pdata_size =
+                       sizeof(*pdata->resource_pdata);
+
+       children[PALMAS_USB_ID].platform_data = pdata->usb_pdata;
+       children[PALMAS_USB_ID].pdata_size = sizeof(*pdata->usb_pdata);
+
+       children[PALMAS_CLK_ID].platform_data = pdata->clk_pdata;
+       children[PALMAS_CLK_ID].pdata_size = sizeof(*pdata->clk_pdata);
+
        ret = mfd_add_devices(palmas->dev, -1,
                              children, ARRAY_SIZE(palmas_children),
                              NULL, regmap_irq_chip_get_base(palmas->irq_data),
@@ -458,13 +461,15 @@ static int __devinit palmas_i2c_probe(struct i2c_client *i2c,
        kfree(children);
 
        if (ret < 0)
-               goto err;
+               goto err_devices;
 
        return ret;
 
-err:
+err_devices:
        mfd_remove_devices(palmas->dev);
-       kfree(palmas);
+err_irq:
+       regmap_del_irq_chip(palmas->irq, palmas->irq_data);
+err:
        return ret;
 }