[PATCH] leds: Add device tree binding for pca9633

Bryan Wu cooloney at gmail.com
Tue Jul 2 05:06:13 EST 2013


On Thu, Jun 27, 2013 at 7:24 AM, Tony Lindgren <tony at atomide.com> wrote:
> * Tony Lindgren <tony at atomide.com> [130627 00:28]:
>> * Bryan Wu <cooloney at gmail.com> [130626 16:53]:
>> > On Wed, Jun 26, 2013 at 7:17 AM, Tony Lindgren <tony at atomide.com> wrote:
>> > > @@ -22,6 +22,7 @@
>> > >  #include <linux/i2c.h>
>> > >  #include <linux/workqueue.h>
>> > >  #include <linux/slab.h>
>> > > +#include <linux/of.h>
>> > >  #include <linux/platform_data/leds-pca9633.h>
>> > >
>> > >  /* LED select registers determine the source that drives LED outputs */
>> > > @@ -93,6 +94,61 @@ static void pca9633_led_set(struct led_classdev *led_cdev,
>> > >         schedule_work(&pca9633->work);
>> > >  }
>> > >
>> > > +#ifdef CONFIG_OF
>> >
>> > Shall we use "#if IS_ENABLED(CONFIG_OF)", as Grant pointed out recently.
>>
>> Thanks will do, I'll also add the push-pull vs totem pole binding
>> as that can be quite crucial for some hardware configurations.
>
> Here's the updated patch.
>
> Regards,
>
> Tony
>

Thanks, I merged it into my -devel branch. And it targets for 3.12
merge window, since 3.11 merge window opened right now.

-Bryan

>
> From: Tony Lindgren <tmlind at panda>
> Date: Wed, 26 Jun 2013 15:52:49 +0300
> Subject: [PATCH] leds: Add device tree binding for pca9633
>
> Similar to tca6507, we can just parse the standard LED
> properties for pca9633.
>
> Tested on a pca9632, which is compatible with pca9633.
>
> Signed-off-by: Tony Lindgren <tony at atomide.com>
>
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/leds/pca9633.txt
> @@ -0,0 +1,45 @@
> +LEDs connected to pca9633 or pca9632
> +
> +Required properties:
> +- compatible : should be : "nxp,pca963x"
> +
> +Optional properties:
> +- nxp,totem-pole : use totem pole (push-pull) instead of default open-drain
> +
> +Each led is represented as a sub-node of the nxp,pca9633 device.
> +
> +LED sub-node properties:
> +- label : (optional) see Documentation/devicetree/bindings/leds/common.txt
> +- reg : number of LED line (could be from 0 to 4)
> +- linux,default-trigger : (optional)
> +   see Documentation/devicetree/bindings/leds/common.txt
> +
> +Examples:
> +
> +pca9632: pca9632 {
> +       compatible = "nxp,pca9632", "nxp,pca963x";
> +       #address-cells = <1>;
> +       #size-cells = <0>;
> +       reg = <0x62>;
> +
> +       red at 0 {
> +               label = "red";
> +               reg = <0>;
> +               linux,default-trigger = "none";
> +       };
> +       green at 1 {
> +               label = "green";
> +               reg = <1>;
> +               linux,default-trigger = "none";
> +       };
> +       blue at 2 {
> +               label = "blue";
> +               reg = <2>;
> +               linux,default-trigger = "none";
> +       };
> +       unused at 3 {
> +               label = "unused";
> +               reg = <3>;
> +               linux,default-trigger = "none";
> +       };
> +};
> --- a/drivers/leds/leds-pca9633.c
> +++ b/drivers/leds/leds-pca9633.c
> @@ -22,6 +22,7 @@
>  #include <linux/i2c.h>
>  #include <linux/workqueue.h>
>  #include <linux/slab.h>
> +#include <linux/of.h>
>  #include <linux/platform_data/leds-pca9633.h>
>
>  /* LED select registers determine the source that drives LED outputs */
> @@ -93,6 +94,67 @@ static void pca9633_led_set(struct led_classdev *led_cdev,
>         schedule_work(&pca9633->work);
>  }
>
> +#if IS_ENABLED(CONFIG_OF)
> +static struct pca9633_platform_data *
> +pca9633_dt_init(struct i2c_client *client)
> +{
> +       struct device_node *np = client->dev.of_node, *child;
> +       struct pca9633_platform_data *pdata;
> +       struct led_info *pca9633_leds;
> +       int count;
> +
> +       count = of_get_child_count(np);
> +       if (!count || count > 4)
> +               return ERR_PTR(-ENODEV);
> +
> +       pca9633_leds = devm_kzalloc(&client->dev,
> +                               sizeof(struct led_info) * count, GFP_KERNEL);
> +       if (!pca9633_leds)
> +               return ERR_PTR(-ENOMEM);
> +
> +       for_each_child_of_node(np, child) {
> +               struct led_info led;
> +               u32 reg;
> +               int res;
> +
> +               led.name =
> +                       of_get_property(child, "label", NULL) ? : child->name;
> +               led.default_trigger =
> +                       of_get_property(child, "linux,default-trigger", NULL);
> +               res = of_property_read_u32(child, "reg", &reg);
> +               if (res != 0)
> +                       continue;
> +               pca9633_leds[reg] = led;
> +       }
> +       pdata = devm_kzalloc(&client->dev,
> +                            sizeof(struct pca9633_platform_data), GFP_KERNEL);
> +       if (!pdata)
> +               return ERR_PTR(-ENOMEM);
> +
> +       pdata->leds.leds = pca9633_leds;
> +       pdata->leds.num_leds = count;
> +
> +       /* default to open-drain unless totem pole (push-pull) is specified */
> +       if (of_property_read_bool(np, "nxp,totem-pole"))
> +               pdata->outdrv = PCA9633_TOTEM_POLE;
> +       else
> +               pdata->outdrv = PCA9633_OPEN_DRAIN;
> +
> +       return pdata;
> +}
> +
> +static const struct of_device_id of_pca9633_match[] = {
> +       { .compatible = "nxp,pca963x", },
> +       {},
> +};
> +#else
> +static struct pca9633_platform_data *
> +pca9633_dt_init(struct i2c_client *client)
> +{
> +       return ERR_PTR(-ENODEV);
> +}
> +#endif
> +
>  static int pca9633_probe(struct i2c_client *client,
>                                         const struct i2c_device_id *id)
>  {
> @@ -102,6 +164,14 @@ static int pca9633_probe(struct i2c_client *client,
>
>         pdata = client->dev.platform_data;
>
> +       if (!pdata) {
> +               pdata = pca9633_dt_init(client);
> +               if (IS_ERR(pdata)) {
> +                       dev_warn(&client->dev, "could not parse configuration\n");
> +                       pdata = NULL;
> +               }
> +       }
> +
>         if (pdata) {
>                 if (pdata->leds.num_leds <= 0 || pdata->leds.num_leds > 4) {
>                         dev_err(&client->dev, "board info must claim at most 4 LEDs");
> @@ -181,6 +251,7 @@ static struct i2c_driver pca9633_driver = {
>         .driver = {
>                 .name   = "leds-pca9633",
>                 .owner  = THIS_MODULE,
> +               .of_match_table = of_match_ptr(of_pca9633_match),
>         },
>         .probe  = pca9633_probe,
>         .remove = pca9633_remove,


More information about the devicetree-discuss mailing list