Hi On 2/1/19 1:45 PM, Jacek Anaszewski wrote: > Hi Bartosz, > > Thanks for the update. > > On 2/1/19 10:47 AM, Bartosz Golaszewski wrote: >> From: Bartosz Golaszewski <bgolaszewski@xxxxxxxxxxxx> >> >> This adds basic support for LEDs for the max77650 PMIC. The device has >> three current sinks for driving LEDs. >> >> Signed-off-by: Bartosz Golaszewski <bgolaszewski@xxxxxxxxxxxx> >> --- >> drivers/leds/Kconfig | 6 ++ >> drivers/leds/Makefile | 1 + >> drivers/leds/leds-max77650.c | 147 +++++++++++++++++++++++++++++++++++ >> 3 files changed, 154 insertions(+) >> create mode 100644 drivers/leds/leds-max77650.c >> >> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig >> index a72f97fca57b..6e7a8f51eccc 100644 >> --- a/drivers/leds/Kconfig >> +++ b/drivers/leds/Kconfig >> @@ -608,6 +608,12 @@ config LEDS_TLC591XX >> This option enables support for Texas Instruments TLC59108 >> and TLC59116 LED controllers. >> +config LEDS_MAX77650 >> + tristate "LED support for Maxim MAX77650 PMIC" >> + depends on MFD_MAX77650 >> + help >> + LEDs driver for MAX77650 family of PMICs from Maxim Integrated." >> + >> config LEDS_MAX77693 >> tristate "LED support for MAX77693 Flash" >> depends on LEDS_CLASS_FLASH >> diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile >> index 4c1b0054f379..f48b2404dbb7 100644 >> --- a/drivers/leds/Makefile >> +++ b/drivers/leds/Makefile >> @@ -61,6 +61,7 @@ obj-$(CONFIG_LEDS_MC13783) += leds-mc13783.o >> obj-$(CONFIG_LEDS_NS2) += leds-ns2.o >> obj-$(CONFIG_LEDS_NETXBIG) += leds-netxbig.o >> obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o >> +obj-$(CONFIG_LEDS_MAX77650) += leds-max77650.o >> obj-$(CONFIG_LEDS_MAX77693) += leds-max77693.o >> obj-$(CONFIG_LEDS_MAX8997) += leds-max8997.o >> obj-$(CONFIG_LEDS_LM355x) += leds-lm355x.o >> diff --git a/drivers/leds/leds-max77650.c b/drivers/leds/leds-max77650.c >> new file mode 100644 >> index 000000000000..6b74ce9cac12 >> --- /dev/null >> +++ b/drivers/leds/leds-max77650.c >> @@ -0,0 +1,147 @@ >> +// SPDX-License-Identifier: GPL-2.0 >> +// >> +// Copyright (C) 2018 BayLibre SAS >> +// Author: Bartosz Golaszewski <bgolaszewski@xxxxxxxxxxxx> >> +// >> +// LED driver for MAXIM 77650/77651 charger/power-supply. >> + >> +#include <linux/i2c.h> >> +#include <linux/leds.h> >> +#include <linux/mfd/max77650.h> >> +#include <linux/module.h> >> +#include <linux/platform_device.h> >> +#include <linux/regmap.h> >> + >> +#define MAX77650_LED_NUM_LEDS 3 >> + >> +#define MAX77650_LED_A_BASE 0x40 >> +#define MAX77650_LED_B_BASE 0x43 >> + >> +#define MAX77650_LED_BR_MASK GENMASK(4, 0) >> +#define MAX77650_LED_EN_MASK GENMASK(7, 6) >> + >> +#define MAX77650_LED_MAX_BRIGHTNESS MAX77650_LED_BR_MASK >> + >> +/* Enable EN_LED_MSTR. */ >> +#define MAX77650_LED_TOP_DEFAULT BIT(0) >> + >> +#define MAX77650_LED_ENABLE GENMASK(7, 6) >> +#define MAX77650_LED_DISABLE 0x00 >> + >> +#define MAX77650_LED_A_DEFAULT MAX77650_LED_DISABLE >> +/* 100% on duty */ >> +#define MAX77650_LED_B_DEFAULT GENMASK(3, 0) >> + >> +struct max77650_led { >> + struct led_classdev cdev; >> + struct regmap *map; >> + unsigned int regA; >> + unsigned int regB; Please don't use camel case. >> +}; >> + >> +static struct max77650_led *max77650_to_led(struct led_classdev *cdev) >> +{ >> + return container_of(cdev, struct max77650_led, cdev); >> +} >> + >> +static int max77650_led_brightness_set(struct led_classdev *cdev, >> + enum led_brightness brightness) >> +{ >> + struct max77650_led *led = max77650_to_led(cdev); >> + int val, mask; >> + The register value and bits are only 8 bit why an int? >> + mask = MAX77650_LED_BR_MASK | MAX77650_LED_EN_MASK; >> + >> + if (brightness == LED_OFF) >> + val = MAX77650_LED_DISABLE; >> + else >> + val = MAX77650_LED_ENABLE | brightness; >> + >> + return regmap_update_bits(led->map, led->regA, mask, val); >> +} >> + >> +static int max77650_led_probe(struct platform_device *pdev) >> +{ >> + struct device_node *of_node, *child; >> + struct max77650_led *leds, *led; >> + struct device *parent; >> + struct device *dev; >> + struct regmap *map; >> + const char *label; >> + int rv, num_leds; >> + u32 reg; >> + >> + dev = &pdev->dev; >> + parent = dev->parent; >> + of_node = dev->of_node; >> + >> + if (!of_node) >> + return -ENODEV; >> + >> + leds = devm_kcalloc(dev, sizeof(*leds), >> + MAX77650_LED_NUM_LEDS, GFP_KERNEL); >> + if (!leds) >> + return -ENOMEM; >> + >> + map = dev_get_regmap(dev->parent, NULL); >> + if (!map) >> + return -ENODEV; >> + >> + num_leds = of_get_child_count(of_node); >> + if (!num_leds || num_leds > MAX77650_LED_NUM_LEDS) >> + return -ENODEV; >> + >> + for_each_child_of_node(of_node, child) { >> + rv = of_property_read_u32(child, "reg", ®); Can we use the fwnode_property_read_u32 call here? And the same for all below as well? >> + if (rv || reg >= MAX77650_LED_NUM_LEDS) >> + return -EINVAL; >> + >> + led = &leds[reg]; >> + led->map = map; >> + led->regA = MAX77650_LED_A_BASE + reg; >> + led->regB = MAX77650_LED_B_BASE + reg; >> + led->cdev.brightness_set_blocking = max77650_led_brightness_set; >> + led->cdev.max_brightness = MAX77650_LED_MAX_BRIGHTNESS; >> + >> + label = of_get_property(child, "label", NULL); >> + if (!label) { >> + led->cdev.name = "max77650::"; >> + } else { >> + led->cdev.name = devm_kasprintf(dev, GFP_KERNEL, >> + "max77650:%s", label); >> + if (!led->cdev.name) >> + return -ENOMEM; >> + } >> + >> + of_property_read_string(child, "linux,default-trigger", >> + &led->cdev.default_trigger); >> + >> + rv = devm_of_led_classdev_register(dev, child, &led->cdev); >> + if (rv) >> + return rv; >> + >> + rv = regmap_write(map, led->regA, MAX77650_LED_A_DEFAULT); >> + if (rv) >> + return rv; >> + >> + rv = regmap_write(map, led->regB, MAX77650_LED_B_DEFAULT); >> + if (rv) >> + return rv; >> + } >> + >> + return regmap_write(map, >> + MAX77650_REG_CNFG_LED_TOP, >> + MAX77650_LED_TOP_DEFAULT); >> +} >> + >> +static struct platform_driver max77650_led_driver = { >> + .driver = { >> + .name = "max77650-led", >> + }, >> + .probe = max77650_led_probe, >> +}; >> +module_platform_driver(max77650_led_driver); >> + >> +MODULE_DESCRIPTION("MAXIM 77650/77651 LED driver"); >> +MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@xxxxxxxxxxxx>"); >> +MODULE_LICENSE("GPL v2"); >> > > Acked-by: Jacek Anaszewski <jacek.anaszewski@xxxxxxxxx> > -- ------------------ Dan Murphy