diff mbox series

[1/4] dt: lm3532: Add lm3532 dt doc and update ti_lmu doc

Message ID 20190307220947.20057-1-dmurphy@ti.com
State New
Headers show
Series [1/4] dt: lm3532: Add lm3532 dt doc and update ti_lmu doc | expand

Commit Message

Dan Murphy March 7, 2019, 10:09 p.m. UTC
Add the lm3532 device tree documentation.
Remove lm3532 device tree reference from the ti_lmu devicetree
documentation.

With the addition of the dedicated lm3532 documentation the device
can be removed from the ti_lmu.txt.

The reason for this is that the lm3532 dt documentation now defines
the ability to control LED output strings against different control
banks or groups multiple strings to be controlled by a single control
bank.

Another addition was for ALS lighting control and configuration.  The
LM3532 has a feature that can take in the ALS reading from 2 separate
ALS devices and adjust the brightness on the strings that are configured
to support this feature.

Finally the device specific properties were moved to the parent node as these
properties are not control bank configurable.  These include the runtime ramp
and the ALS configuration.

Signed-off-by: Dan Murphy <dmurphy@ti.com>

---
 .../devicetree/bindings/leds/leds-lm3532.txt  | 113 ++++++++++++++++++
 .../devicetree/bindings/mfd/ti-lmu.txt        |  20 ----
 2 files changed, 113 insertions(+), 20 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-lm3532.txt

-- 
2.20.1.390.gb5101f9297

Comments

Pavel Machek March 8, 2019, 3:14 p.m. UTC | #1
Hi!

> Update the properties for the lm3532 device node for droid4.

> With this change the backlight LED string and the keypad

> LED strings will be controlled separately.

> 

> Signed-off-by: Dan Murphy <dmurphy@ti.com>

> ---

>  arch/arm/boot/dts/omap4-droid4-xt894.dts | 27 +++++++++++++++++-------

>  1 file changed, 19 insertions(+), 8 deletions(-)

> 

> diff --git a/arch/arm/boot/dts/omap4-droid4-xt894.dts b/arch/arm/boot/dts/omap4-droid4-xt894.dts

> index e21ec929f096..94e3d53dbcf3 100644

> --- a/arch/arm/boot/dts/omap4-droid4-xt894.dts

> +++ b/arch/arm/boot/dts/omap4-droid4-xt894.dts

> @@ -6,6 +6,7 @@

>  /dts-v1/;

>  

>  #include <dt-bindings/input/input.h>

> +#include <dt-bindings/leds/leds-lm3532.h>

>  #include "omap443x.dtsi"

>  #include "motorola-cpcap-mapphone.dtsi"

>  

> @@ -383,20 +384,30 @@

>  };

>  

>  &i2c1 {

> -	lm3532@38 {

> +	led-controller@38 {

>  		compatible = "ti,lm3532";

> +		#address-cells = <1>;

> +		#size-cells = <0>;

>  		reg = <0x38>;

>  

>  		enable-gpios = <&gpio6 12 GPIO_ACTIVE_HIGH>;

>  

> -		lcd_backlight: backlight {

> -			compatible = "ti,lm3532-backlight";

> +		ramp-up-ms = <LM3532_RAMP_1024us>;

> +		ramp-down-ms = <LM3532_RAMP_65536us>;


I guess dt people will have some comments here. I'd expect

ramp-up-us = <1024> would be more natural.

> +		lcd_backlight: led@0 {

> +			reg = <0>;

> +			led-sources = <2>;

> +			ti,led-mode = <LM3532_BL_MODE_MANUAL>;

> +			label = "backlight";


Ok, so we'll have lm3532::backlight. That is not too useful, as it
does not tell userland what kaclight it is.

main_display::backlight ?

OTOH this one is not too important as backlight subsystem should
handle this.

> +		led@1 {

> +			reg = <1>;

> +			led-sources = <1>;

> +			ti,led-mode = <LM3532_BL_MODE_MANUAL>;

> +			label = "keypad";


I guess best variant would be inputX::backlight here, but that might
be tricky to implement.

									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Pavel Machek March 8, 2019, 9:06 p.m. UTC | #2
> >> +		led@1 {

> >> +			reg = <1>;

> >> +			led-sources = <1>;

> >> +			ti,led-mode = <LM3532_BL_MODE_MANUAL>;

> >> +			label = "keypad";

> > 

> > I guess best variant would be inputX::backlight here, but that might

> > be tricky to implement.

> > 

> 

> Yeah because we don't know what input the keyboard would be on.

> Unless there are APIs to retrieve that info.  I have not looked at the input

> framework in a while.


Lets just make it "platform::kbd_backlight". *:kbd_backlight is
already used by quite a few drivers.

									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Jacek Anaszewski March 10, 2019, 7:49 p.m. UTC | #3
Hi Dan,

Thank your for the patch.

I have some comments below, please take a look.

On 3/7/19 11:09 PM, Dan Murphy wrote:
> Introduce the Texas Instruments LM3532 White LED driver.

> The driver supports ALS configurability or manual brightness

> control.

> 

> The driver also supports associating LED strings with specific

> control banks in a group or as individually controlled strings.

> 

> Signed-off-by: Dan Murphy <dmurphy@ti.com>

> ---

>   drivers/leds/Kconfig                   |  10 +

>   drivers/leds/Makefile                  |   1 +

>   drivers/leds/leds-lm3532.c             | 595 +++++++++++++++++++++++++

>   include/dt-bindings/leds/leds-lm3532.h |  72 +++

>   4 files changed, 678 insertions(+)

>   create mode 100644 drivers/leds/leds-lm3532.c

>   create mode 100644 include/dt-bindings/leds/leds-lm3532.h

> 

> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig

> index a72f97fca57b..da00b9ed5a5c 100644

> --- a/drivers/leds/Kconfig

> +++ b/drivers/leds/Kconfig

> @@ -138,6 +138,16 @@ config LEDS_LM3530

>   	  controlled manually or using PWM input or using ambient

>   	  light automatically.

>   

> +config LEDS_LM3532

> +	tristate "LCD Backlight driver for LM3532"

> +	depends on LEDS_CLASS

> +	depends on I2C

> +	help

> +	  This option enables support for the LCD backlight using

> +	  LM3532 ambient light sensor chip. This ALS chip can be

> +	  controlled manually or using PWM input or using ambient

> +	  light automatically.

> +

>   config LEDS_LM3533

>   	tristate "LED support for LM3533"

>   	depends on LEDS_CLASS

> diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile

> index 4c1b0054f379..7a8b1f55d459 100644

> --- a/drivers/leds/Makefile

> +++ b/drivers/leds/Makefile

> @@ -18,6 +18,7 @@ obj-$(CONFIG_LEDS_BD2802)		+= leds-bd2802.o

>   obj-$(CONFIG_LEDS_CPCAP)		+= leds-cpcap.o

>   obj-$(CONFIG_LEDS_LOCOMO)		+= leds-locomo.o

>   obj-$(CONFIG_LEDS_LM3530)		+= leds-lm3530.o

> +obj-$(CONFIG_LEDS_LM3532)		+= leds-lm3532.o

>   obj-$(CONFIG_LEDS_LM3533)		+= leds-lm3533.o

>   obj-$(CONFIG_LEDS_LM3642)		+= leds-lm3642.o

>   obj-$(CONFIG_LEDS_MIKROTIK_RB532)	+= leds-rb532.o

> diff --git a/drivers/leds/leds-lm3532.c b/drivers/leds/leds-lm3532.c

> new file mode 100644

> index 000000000000..005478359d06

> --- /dev/null

> +++ b/drivers/leds/leds-lm3532.c

> @@ -0,0 +1,595 @@

> +// SPDX-License-Identifier: GPL-2.0

> +// TI LM3532 LED driver

> +// Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/

> +

> +#include <linux/i2c.h>

> +#include <linux/leds.h>

> +#include <linux/slab.h>

> +#include <linux/regmap.h>

> +#include <linux/input.h>

> +#include <linux/types.h>

> +#include <linux/regulator/consumer.h>

> +#include <linux/module.h>

> +#include <uapi/linux/uleds.h>

> +#include <linux/gpio/consumer.h>

> +

> +#include <dt-bindings/leds/leds-lm3532.h>

> +

> +#define LM3532_NAME "lm3532-led"

> +

> +#define LM3532_REG_OUTPUT_CFG	0x10

> +#define LM3532_REG_STARTSHUT_RAMP	0x11

> +#define LM3532_REG_RT_RAMP	0x12

> +#define LM3532_REG_PWM_A_CFG	0x13

> +#define LM3532_REG_PWM_B_CFG	0x14

> +#define LM3532_REG_PWM_C_CFG	0x15

> +#define LM3532_REG_ZONE_CFG_A	0x16

> +#define LM3532_REG_CTRL_A_BRT	0x17

> +#define LM3532_REG_ZONE_CFG_B	0x18

> +#define LM3532_REG_CTRL_B_BRT	0x19

> +#define LM3532_REG_ZONE_CFG_C	0x1a

> +#define LM3532_REG_CTRL_C_BRT	0x1b

> +#define LM3532_REG_ENABLE	0x1d

> +#define LM3532_ALS_CONFIG	0x23

> +#define LM3532_REG_ZN_0_HI	0x60

> +#define LM3532_REG_ZN_0_LO	0x61

> +#define LM3532_REG_ZN_1_HI	0x62

> +#define LM3532_REG_ZN_1_LO	0x63

> +#define LM3532_REG_ZN_2_HI	0x64

> +#define LM3532_REG_ZN_2_LO	0x65

> +#define LM3532_REG_ZN_3_HI	0x66

> +#define LM3532_REG_ZN_3_LO	0x67

> +#define LM3532_REG_MAX		0x7e

> +

> +/* Contorl Enable */

> +#define LM3532_CTRL_A_ENABLE	BIT(0)

> +#define LM3532_CTRL_B_ENABLE	BIT(1)

> +#define LM3532_CTRL_C_ENABLE	BIT(2)

> +

> +/* PWM Zone Control */

> +#define LM3532_PWM_ZONE_MASK	0x7c

> +#define LM3532_PWM_ZONE_0_EN	BIT(2)

> +#define LM3532_PWM_ZONE_1_EN	BIT(3)

> +#define LM3532_PWM_ZONE_2_EN	BIT(4)

> +#define LM3532_PWM_ZONE_3_EN	BIT(5)

> +#define LM3532_PWM_ZONE_4_EN	BIT(6)

> +

> +/* Brightness Configuration */

> +#define LM3532_I2C_CTRL		BIT(0)

> +#define LM3532_LINEAR_MAP	BIT(1)

> +#define LM3532_ZONE_MASK	(BIT(2) | BIT(3) | BIT(4))

> +#define LM3532_ZONE_0		0

> +#define LM3532_ZONE_1		BIT(2)

> +#define LM3532_ZONE_2		BIT(3)

> +#define LM3532_ZONE_3		(BIT(2) | BIT(3))

> +#define LM3532_ZONE_4		BIT(4)

> +

> +#define LM3532_ENABLE_ALS	BIT(3)

> +#define LM3532_ALS_SEL_SHIFT	6

> +

> +/* Zone Boundary Register */

> +#define LM3532_ALS_WINDOW_mV	2000

> +#define LM3532_ALS_ZB_MAX	4

> +#define LM3532_ALS_OFFSET_mV	2

> +

> +#define LM3532_CONTROL_A	0

> +#define LM3532_CONTROL_B	1

> +#define LM3532_CONTROL_C	2

> +#define LM3532_MAX_CONTROL_BANKS 3

> +#define LM3532_MAX_LED_STRINGS	3

> +

> +#define LM3532_OUTPUT_CFG_MASK	0x3

> +#define LM3532_BRT_VAL_ADJUST	8

> +#define LM3532_RAMP_DOWN_SHIFT	3

> +

> +/*

> + * struct lm3532_als_data

> + * @config - value of ALS configuration register

> + * @als1_imp_sel - value of ALS1 resistor select register

> + * @als2_imp_sel - value of ALS2 resistor select register

> + * @als_avrg_time - ALS averaging time

> + * @als_input_mode - ALS input mode for brightness control

> + * @als_vmin - Minimum ALS voltage

> + * @als_vmax - Maximum ALS voltage

> + * @zone_lo - values of ALS lo ZB(Zone Boundary) registers

> + * @zone_hi - values of ALS hi ZB(Zone Boundary) registers

> + */

> +struct lm3532_als_data {

> +	u8 config;

> +	u8 als1_imp_sel;

> +	u8 als2_imp_sel;

> +	u8 als_avrg_time;

> +	u8 als_input_mode;

> +	u32 als_vmin;

> +	u32 als_vmax;

> +	u8 zones_lo[LM3532_ALS_ZB_MAX];

> +	u8 zones_hi[LM3532_ALS_ZB_MAX];

> +};

> +

> +/**

> + * struct lm3532_led

> + * @led_dev: led class device

> + * @priv - Pointer the device data structure

> + * @control_bank - Control bank the LED is associated to

> + * @mode - Mode of the LED string

> + * @num_leds - Number of LED strings are supported in this array

> + * @led_strings - The LED strings supported in this array

> + * @label - LED label

> + */

> +struct lm3532_led {

> +	struct led_classdev led_dev;

> +	struct lm3532_data *priv;

> +

> +	int control_bank;

> +	int mode;

> +	int num_leds;

> +	u32 led_strings[LM3532_MAX_CONTROL_BANKS];

> +	char label[LED_MAX_NAME_SIZE];

> +};

> +

> +/**

> + * struct lm3532_data

> + * @enable_gpio - Hardware enable gpio

> + * @regulator: regulator

> + * @client: i2c client

> + * @regmap - Devices register map

> + * @dev - Pointer to the devices device struct

> + * @lock - Lock for reading/writing the device

> + * @als_data - Pointer to the als data struct

> + * @runtime_ramp_up - Runtime ramp up setting

> + * @runtime_ramp_down - Runtime ramp down setting

> + * @leds - Array of LED strings

> + */

> +struct lm3532_data {

> +	struct gpio_desc *enable_gpio;

> +	struct regulator *regulator;

> +	struct i2c_client *client;

> +	struct regmap *regmap;

> +	struct device *dev;

> +	struct mutex lock;

> +

> +	struct lm3532_als_data *als_data;

> +

> +	u32 runtime_ramp_up;

> +	u32 runtime_ramp_down;

> +

> +	struct lm3532_led leds[];

> +};

> +

> +static const struct reg_default lm3532_reg_defs[] = {

> +	{LM3532_REG_OUTPUT_CFG, 0xe4},

> +	{LM3532_REG_STARTSHUT_RAMP, 0xc0},

> +	{LM3532_REG_RT_RAMP, 0xc0},

> +	{LM3532_REG_PWM_A_CFG, 0x82},

> +	{LM3532_REG_PWM_B_CFG, 0x82},

> +	{LM3532_REG_PWM_C_CFG, 0x82},

> +	{LM3532_REG_ZONE_CFG_A, 0xf1},

> +	{LM3532_REG_CTRL_A_BRT, 0xf3},

> +	{LM3532_REG_ZONE_CFG_B, 0xf1},

> +	{LM3532_REG_CTRL_B_BRT, 0xf3},

> +	{LM3532_REG_ZONE_CFG_C, 0xf1},

> +	{LM3532_REG_CTRL_C_BRT, 0xf3},

> +	{LM3532_REG_ENABLE, 0xf8},

> +	{LM3532_ALS_CONFIG, 0x44},

> +	{LM3532_REG_ZN_0_HI, 0x35},

> +	{LM3532_REG_ZN_0_LO, 0x33},

> +	{LM3532_REG_ZN_1_HI, 0x6a},

> +	{LM3532_REG_ZN_1_LO, 0x66},

> +	{LM3532_REG_ZN_2_HI, 0xa1},

> +	{LM3532_REG_ZN_2_LO, 0x99},

> +	{LM3532_REG_ZN_3_HI, 0xdc},

> +	{LM3532_REG_ZN_3_LO, 0xcc},

> +};

> +

> +static const struct regmap_config lm3532_regmap_config = {

> +	.reg_bits = 8,

> +	.val_bits = 8,

> +

> +	.max_register = LM3532_REG_MAX,

> +	.reg_defaults = lm3532_reg_defs,

> +	.num_reg_defaults = ARRAY_SIZE(lm3532_reg_defs),

> +	.cache_type = REGCACHE_FLAT,

> +};

> +

> +static int lm3532_led_enable(struct lm3532_led *led_data)

> +{

> +	int ctrl_en_val;

> +	int ret;

> +

> +	switch (led_data->control_bank) {

> +	case LM3532_CONTROL_A:

> +		ctrl_en_val = LM3532_CTRL_A_ENABLE;

> +		break;

> +	case LM3532_CONTROL_B:

> +		ctrl_en_val = LM3532_CTRL_B_ENABLE;

> +		break;

> +	case LM3532_CONTROL_C:

> +		ctrl_en_val = LM3532_CTRL_C_ENABLE;

> +		break;

> +	default:

> +		dev_err(led_data->priv->dev, "Invalid control bank\n");


If control_bank was validated in lm3532_parse_node(), then you wouldn't
have to take into account this option here.

Besides, you don't need this switch statement, but can easily calculate
ctrl_en_val:

#define LM3532_GET_CTRL_BANK_EN_VAL(bank_id) BIT(bank_id)

> +		return -EINVAL;

> +	};

> +

> +	ret = regmap_update_bits(led_data->priv->regmap, LM3532_REG_ENABLE,

> +					 ctrl_en_val, ctrl_en_val);

> +	if (ret) {

> +		dev_err(led_data->priv->dev, "Failed to set ctrl:%d\n", ret);

> +		return ret;

> +	}

> +

> +	return regulator_enable(led_data->priv->regulator);

> +}

> +

> +static int lm3532_led_disable(struct lm3532_led *led_data)

> +{

> +	int ctrl_en_val;

> +	int ret;

> +

> +	switch (led_data->control_bank) {

> +	case LM3532_CONTROL_A:

> +		ctrl_en_val = LM3532_CTRL_A_ENABLE;

> +		break;

> +	case LM3532_CONTROL_B:

> +		ctrl_en_val = LM3532_CTRL_B_ENABLE;

> +		break;

> +	case LM3532_CONTROL_C:

> +		ctrl_en_val = LM3532_CTRL_C_ENABLE;

> +		break;

> +	default:

> +		dev_err(led_data->priv->dev, "Invalid control bank\n");

> +		return -EINVAL;

> +	};


Ditto.

> +

> +	ret = regmap_update_bits(led_data->priv->regmap, LM3532_REG_ENABLE,

> +					 ctrl_en_val, ~ctrl_en_val);

> +	if (ret) {

> +		dev_err(led_data->priv->dev, "Failed to set ctrl:%d\n", ret);

> +		return ret;

> +	}

> +

> +	return regulator_disable(led_data->priv->regulator);

> +}

> +

> +static int lm3532_brightness_set(struct led_classdev *led_cdev,

> +				 enum led_brightness brt_val)

> +{

> +	struct lm3532_led *led =

> +			container_of(led_cdev, struct lm3532_led, led_dev);

> +	u8 brightnes_reg;

> +	int ret;

> +

> +	mutex_lock(&led->priv->lock);

> +

> +	if (led->mode == LM3532_BL_MODE_ALS) {

> +		ret = 0;

> +		goto unlock;

> +	}

> +

> +	switch (led->control_bank) {

> +	case LM3532_CONTROL_A:

> +		brightnes_reg = LM3532_REG_CTRL_A_BRT;

> +		break;

> +	case LM3532_CONTROL_B:

> +		brightnes_reg = LM3532_REG_CTRL_B_BRT;

> +		break;

> +	case LM3532_CONTROL_C:

> +		brightnes_reg = LM3532_REG_CTRL_C_BRT;

> +		break;

> +	default:

> +		dev_err(led->priv->dev, "Invalid control bank\n");

> +		ret = -EINVAL;

> +		goto unlock;

> +	};


Similarly here. use following macro:

#define LM3532_GET_CTRL_BANK_BRT_REG (bank_id) 
BIT((LM3532_REG_CTRL_A_BRT + bank_id*2))

> +	if (brt_val == LED_OFF) {

> +		ret = lm3532_led_disable(led);

> +		goto unlock;

> +	}

> +

> +	lm3532_led_enable(led);

> +	brt_val = brt_val / LM3532_BRT_VAL_ADJUST;

> +

> +	ret = regmap_write(led->priv->regmap, brightnes_reg, brt_val);

> +

> +unlock:

> +	mutex_unlock(&led->priv->lock);

> +	return ret;

> +}

> +

> +static int lm3532_init_registers(struct lm3532_led *led)

> +{

> +	struct lm3532_data *drvdata = led->priv;

> +	unsigned int runtime_ramp_val;

> +	unsigned int output_cfg_val = 0;

> +	unsigned int output_cfg_shift = 0;

> +	unsigned int output_cfg_mask = 0;

> +	int ret, i;

> +

> +	for (i = 0; i < led->num_leds; i++) {

> +		output_cfg_shift = led->led_strings[i] * 2;

> +		output_cfg_val |= (led->control_bank << output_cfg_shift);

> +		output_cfg_mask |= LM3532_OUTPUT_CFG_MASK << output_cfg_shift;

> +	}

> +

> +	ret = regmap_update_bits(drvdata->regmap, LM3532_REG_OUTPUT_CFG,

> +				 output_cfg_mask, output_cfg_val);

> +

> +	runtime_ramp_val = drvdata->runtime_ramp_up |

> +			 (drvdata->runtime_ramp_down << LM3532_RAMP_DOWN_SHIFT);

> +

> +	return regmap_write(drvdata->regmap, LM3532_REG_RT_RAMP,

> +			    runtime_ramp_val);

> +}

> +

> +static int lm3532_als_configure(struct lm3532_data *priv)

> +{

> +	struct lm3532_als_data *als = priv->als_data;

> +	u32 als_vmin, als_vmax, als_vstep;

> +	int zone_reg = LM3532_REG_ZN_0_HI;

> +	int ret;

> +	int i;

> +

> +	als_vmin = als->als_vmin;

> +	als_vmax = als->als_vmax;

> +

> +	als_vstep = (als_vmax - als_vmin) / ((LM3532_ALS_ZB_MAX + 1) * 2);

> +

> +	for (i = 0; i < LM3532_ALS_ZB_MAX; i++) {

> +		als->zones_lo[i] = ((als_vmin + als_vstep + (i * als_vstep)) *

> +				LED_FULL) / 1000;

> +		als->zones_hi[i] = ((als_vmin + LM3532_ALS_OFFSET_mV +

> +				als_vstep + (i * als_vstep)) * LED_FULL) / 1000;

> +

> +		zone_reg = LM3532_REG_ZN_0_HI + i * 2;

> +		ret = regmap_write(priv->regmap, zone_reg, als->zones_lo[i]);

> +		if (ret)

> +			return ret;

> +

> +		zone_reg += 1;

> +		ret = regmap_write(priv->regmap, zone_reg, als->zones_hi[i]);

> +		if (ret)

> +			return ret;

> +	}

> +

> +	als->config = (als->als_avrg_time | (LM3532_ENABLE_ALS) |

> +		(als->als_input_mode << LM3532_ALS_SEL_SHIFT));

> +

> +	return regmap_write(priv->regmap, LM3532_ALS_CONFIG, als->config);

> +}

> +

> +static int lm3532_parse_als(struct lm3532_data *priv)

> +{

> +	struct lm3532_als_data *als;

> +	int ret;

> +

> +	als = devm_kzalloc(priv->dev, sizeof(*als), GFP_KERNEL);

> +	if (als == NULL)

> +		return -ENOMEM;

> +

> +	ret = device_property_read_u32(&priv->client->dev, "als-vmin",

> +				       &als->als_vmin);

> +	if (ret)

> +		als->als_vmin = 0;

> +

> +	ret = device_property_read_u32(&priv->client->dev, "als-vmax",

> +				       &als->als_vmax);

> +	if (ret)

> +		als->als_vmax = LM3532_ALS_WINDOW_mV;

> +

> +	ret = device_property_read_u8(&priv->client->dev, "als1-imp-sel",

> +				      &als->als1_imp_sel);

> +	if (ret)

> +		als->als1_imp_sel = 0;

> +

> +	ret = device_property_read_u8(&priv->client->dev, "als2-imp-sel",

> +				      &als->als2_imp_sel);

> +	if (ret)

> +		als->als2_imp_sel = 0;

> +

> +	ret = device_property_read_u8(&priv->client->dev, "als-avrg-time",

> +				      &als->als_avrg_time);

> +	if (ret)

> +		als->als_avrg_time = 0;

> +

> +	ret = device_property_read_u8(&priv->client->dev, "als-input-mode",

> +				      &als->als_input_mode);

> +	if (ret)

> +		als->als_input_mode = 0;

> +

> +	priv->als_data = als;

> +

> +	return ret;

> +}

> +

> +static int lm3532_parse_node(struct lm3532_data *priv)

> +{

> +	struct fwnode_handle *child = NULL;

> +	struct lm3532_led *led;

> +	const char *name;

> +	int control_bank;

> +	size_t i = 0;

> +	int ret;

> +

> +	priv->enable_gpio = devm_gpiod_get_optional(&priv->client->dev,

> +						   "enable", GPIOD_OUT_LOW);

> +	if (IS_ERR(priv->enable_gpio))

> +		priv->enable_gpio = NULL;

> +

> +	priv->regulator = devm_regulator_get(&priv->client->dev, "vin");

> +	if (IS_ERR(priv->regulator))

> +		priv->regulator = NULL;

> +

> +	ret = device_property_read_u32(&priv->client->dev, "ramp-down-ms",

> +				       &priv->runtime_ramp_up);

> +	if (ret)

> +		dev_info(&priv->client->dev, "ramp-down-ms property missing\n");

> +

> +	ret = device_property_read_u32(&priv->client->dev, "ramp-down-ms",

> +				       &priv->runtime_ramp_down);

> +	if (ret)

> +		dev_info(&priv->client->dev, "ramp-down-ms property missing\n");

> +

> +	device_for_each_child_node(priv->dev, child) {

> +		led = &priv->leds[i];

> +

> +		ret = fwnode_property_read_u32(child, "reg", &control_bank);

> +		if (ret) {

> +			dev_err(&priv->client->dev, "reg property missing\n");

> +			fwnode_handle_put(child);

> +			goto child_out;

> +		}

> +

> +		if (control_bank > LM3532_CONTROL_C) {

> +			dev_err(&priv->client->dev, "Control bank invalid\n");

> +			continue;

> +		}

> +

> +		led->control_bank = control_bank;

> +

> +		ret = fwnode_property_read_u32(child, "ti,led-mode",

> +					       &led->mode);

> +		if (ret) {

> +			dev_err(&priv->client->dev, "ti,led-mode property missing\n");

> +			fwnode_handle_put(child);

> +			goto child_out;

> +		}

> +

> +		if (led->mode == LM3532_BL_MODE_ALS) {

> +			ret = lm3532_parse_als(priv);

> +			if (ret)

> +				dev_err(&priv->client->dev, "Failed to parse als\n");

> +			else

> +				lm3532_als_configure(priv);

> +		}

> +

> +		led->num_leds = fwnode_property_read_u32_array(child,

> +							       "led-sources",

> +							       NULL, 0);

> +

> +		if (led->num_leds > LM3532_MAX_LED_STRINGS) {

> +			dev_err(&priv->client->dev, "To many LED string defined\n");

> +			continue;

> +		}

> +

> +		ret = fwnode_property_read_u32_array(child, "led-sources",

> +						    led->led_strings,

> +						    led->num_leds);

> +		if (ret) {

> +			dev_err(&priv->client->dev, "led-sources property missing\n");

> +			fwnode_handle_put(child);

> +			goto child_out;

> +		}

> +

> +		fwnode_property_read_string(child, "linux,default-trigger",

> +					    &led->led_dev.default_trigger);

> +

> +		ret = fwnode_property_read_string(child, "label", &name);

> +		if (ret)

> +			snprintf(led->label, sizeof(led->label),

> +				"%s::", priv->client->name);

> +		else

> +			snprintf(led->label, sizeof(led->label),

> +				 "%s:%s", priv->client->name, name);

> +

> +		led->priv = priv;

> +		led->led_dev.name = led->label;

> +		led->led_dev.brightness_set_blocking = lm3532_brightness_set;

> +

> +		ret = devm_led_classdev_register(priv->dev, &led->led_dev);

> +		if (ret) {

> +			dev_err(&priv->client->dev, "led register err: %d\n",

> +				ret);

> +			fwnode_handle_put(child);

> +			goto child_out;

> +		}

> +

> +		lm3532_init_registers(led);

> +

> +		i++;

> +	}

> +

> +child_out:

> +	return ret;

> +}

> +

> +static int lm3532_probe(struct i2c_client *client,

> +			   const struct i2c_device_id *id)

> +{

> +	struct lm3532_data *drvdata;

> +	int ret = 0;

> +	int count;

> +

> +	count = device_get_child_node_count(&client->dev);

> +	if (!count) {

> +		dev_err(&client->dev, "LEDs are not defined in device tree!");

> +		return -ENODEV;

> +	}

> +

> +	drvdata = devm_kzalloc(&client->dev, struct_size(drvdata, leds, count),

> +			   GFP_KERNEL);

> +	if (drvdata == NULL)

> +		return -ENOMEM;

> +

> +	drvdata->client = client;

> +	drvdata->dev = &client->dev;

> +

> +	drvdata->regmap = devm_regmap_init_i2c(client, &lm3532_regmap_config);

> +	if (IS_ERR(drvdata->regmap)) {

> +		ret = PTR_ERR(drvdata->regmap);

> +		dev_err(&client->dev, "Failed to allocate register map: %d\n",

> +			ret);

> +		return ret;

> +	}

> +

> +	mutex_init(&drvdata->lock);

> +	i2c_set_clientdata(client, drvdata);

> +

> +	ret = lm3532_parse_node(drvdata);

> +	if (ret) {

> +		dev_err(&client->dev, "Failed to parse node\n");

> +		return ret;

> +	}

> +

> +	if (drvdata->enable_gpio)

> +		gpiod_direction_output(drvdata->enable_gpio, 1);

> +

> +	return ret;

> +}

> +

> +static int lm3532_remove(struct i2c_client *client)

> +{

> +	struct lm3532_data *drvdata = i2c_get_clientdata(client);


mutex_destroy() is missing here.

> +	if (drvdata->enable_gpio)

> +		gpiod_direction_output(drvdata->enable_gpio, 0);

> +

> +	return 0;

> +}

> +

> +static const struct of_device_id of_lm3532_leds_match[] = {

> +	{ .compatible = "ti,lm3532", },

> +	{},

> +};

> +MODULE_DEVICE_TABLE(of, of_lm3532_leds_match);

> +

> +static const struct i2c_device_id lm3532_id[] = {

> +	{LM3532_NAME, 0},

> +	{}

> +};

> +MODULE_DEVICE_TABLE(i2c, lm3532_id);

> +

> +static struct i2c_driver lm3532_i2c_driver = {

> +	.probe = lm3532_probe,

> +	.remove = lm3532_remove,

> +	.id_table = lm3532_id,

> +	.driver = {

> +		.name = LM3532_NAME,

> +		.of_match_table = of_lm3532_leds_match,

> +	},

> +};

> +module_i2c_driver(lm3532_i2c_driver);

> +

> +MODULE_DESCRIPTION("Back Light driver for LM3532");

> +MODULE_LICENSE("GPL v2");

> +MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");

> diff --git a/include/dt-bindings/leds/leds-lm3532.h b/include/dt-bindings/leds/leds-lm3532.h

> new file mode 100644

> index 000000000000..724dbc0cb395

> --- /dev/null

> +++ b/include/dt-bindings/leds/leds-lm3532.h


This should go in a separate patch, with DT bindings - see checkpatch.pl
complaint.

> @@ -0,0 +1,72 @@

> +/* SPDX-License-Identifier: GPL-2.0 */

> +/* TI LM3532 LED driver

> + * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/

> + */

> +

> +#ifndef __DT_BINDINGS_LEDS_LM3532_H

> +#define __DT_BINDINGS_LEDS_LM3532_H

> +

> +#define LM3532_BL_MODE_MANUAL	0x00 /* "man" */

> +#define LM3532_BL_MODE_ALS	0x01 /* "als" */

> +

> +/* ALS Resistor Select */

> +#define LM3532_IMP_HIGH		0x00

> +#define LM3532_IMP_37K		0x01

> +#define LM3532_IMP_18_5K	0x02

> +#define LM3532_IMP_12_33K	0x03

> +#define LM3532_IMP_9_25K	0x04

> +#define LM3532_IMP_7_4K		0x05

> +#define LM3532_IMP_6_17K	0x06

> +#define LM3532_IMP_5_29K	0x07

> +#define LM3532_IMP_4_63K	0x08

> +#define LM3532_IMP_4_11K	0x09

> +#define LM3532_IMP_3_7K		0x0a

> +#define LM3532_IMP_3_36K	0x0b

> +#define LM3532_IMP_3_08K	0x0c

> +#define LM3532_IMP_2_85K	0x0d

> +#define LM3532_IMP_2_64K	0x0e

> +#define LM3532_IMP_2_44K	0x0f

> +#define LM3532_IMP_2_31K	0x10

> +#define LM3532_IMP_2_18K	0x11

> +#define LM3532_IMP_2_06K	0x12

> +#define LM3532_IMP_1_95K	0x13

> +#define LM3532_IMP_1_85K	0x14

> +#define LM3532_IMP_1_76K	0x15

> +#define LM3532_IMP_1_68K	0x16

> +#define LM3532_IMP_1_61K	0x17

> +#define LM3532_IMP_1_54K	0x18

> +#define LM3532_IMP_1_48K	0x19

> +#define LM3532_IMP_1_42K	0x1a

> +#define LM3532_IMP_1_37K	0x1b

> +#define LM3532_IMP_1_32K	0x1c

> +#define LM3532_IMP_1_28K	0x1d

> +#define LM3532_IMP_1_23K	0x1e

> +#define LM3532_IMP_1_19K	0x1f

> +

> +/* ALS Averaging Time */

> +#define LM3532_ALS_AVRG_TIME_17_92ms	0x00

> +#define LM3532_ALS_AVRG_TIME_35_84ms	0x01

> +#define LM3532_ALS_AVRG_TIME_71_68ms	0x02

> +#define LM3532_ALS_AVRG_TIME_143_36ms	0x03

> +#define LM3532_ALS_AVRG_TIME_286_72ms	0x04

> +#define LM3532_ALS_AVRG_TIME_573_44ms	0x05

> +#define LM3532_ALS_AVRG_TIME_1146_88ms	0x06

> +#define LM3532_ALS_AVRG_TIME_2293_76ms	0x07

> +

> +/* ALS input select */

> +#define LM3532_ALS_INPUT_AVRG	0x00 /* ALS1 and ALS2 input average */

> +#define LM3532_ALS_INPUT_ALS1	0x01 /* ALS1 Input */

> +#define LM3532_ALS_INPUT_ALS2	0x02 /* ALS2 Input */

> +#define LM3532_ALS_INPUT_CEIL	0x03 /* Max of ALS1 and ALS2 */

> +

> +/* Ramp Times */

> +#define LM3532_RAMP_8us		0x00

> +#define LM3532_RAMP_1024us	0x01

> +#define LM3532_RAMP_2048us	0x02

> +#define LM3532_RAMP_4096us	0x03

> +#define LM3532_RAMP_8192us	0x04

> +#define LM3532_RAMP_16384us	0x05

> +#define LM3532_RAMP_32768us	0x06

> +#define LM3532_RAMP_65536us	0x07

> +

> +#endif /* __DT_BINDINGS_LEDS_LM3532_H */

> 


-- 
Best regards,
Jacek Anaszewski
Joe Perches March 11, 2019, 5:30 p.m. UTC | #4
On Mon, 2019-03-11 at 12:24 -0500, Dan Murphy wrote:
> checkpatch takes issue with // in headers.

> Unless they have removed that requirement.


Awhile ago...

commit dadf680de3c2eb4cba9840619991eda0cfe98778
Author: Joe Perches <joe@perches.com>
Date:   Tue Aug 2 14:04:33 2016 -0700

    checkpatch: allow c99 style // comments
    
    Sanitise the lines that contain c99 comments so that the error doesn't
    get emitted.
    
    Link: http://lkml.kernel.org/r/d4d22c34ad7bcc1bceb52f0742f76b7a6d585235.1468368420.git.joe@perches.com
    Signed-off-by: Joe Perches <joe@perches.com>

    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
diff mbox series

Patch

diff --git a/Documentation/devicetree/bindings/leds/leds-lm3532.txt b/Documentation/devicetree/bindings/leds/leds-lm3532.txt
new file mode 100644
index 000000000000..7cf6739eafe0
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/leds-lm3532.txt
@@ -0,0 +1,113 @@ 
+* Texas Instruments - lm3532 White LED driver with ambient light sensing
+capability.
+
+The LM3532 provides the 3 high-voltage, low-side current sinks. The device is
+programmable over an I2C-compatible interface and has independent
+current control for all three channels. The adaptive current regulation
+method allows for different LED currents in each current sink thus allowing
+for a wide variety of backlight and keypad applications.
+
+The main features of the LM3532 include dual ambient light sensor inputs
+each with 32 internal voltage setting resistors, 8-bit logarithmic and linear
+brightness control, dual external PWM brightness control inputs, and up to
+1000:1 dimming ratio with programmable fade in and fade out settings.
+
+Required properties:
+	- compatible : "ti,lm3532"
+	- reg : I2C slave address
+	- #address-cells : 1
+	- #size-cells : 0
+
+Required child properties:
+	- reg : Indicates control bank the LED string is controlled by
+	- led-sources : see Documentation/devicetree/bindings/leds/common.txt
+	- ti,led-mode : Defines if the LED strings are manually controlled or
+			if the LED strings are controlled by the ALS
+
+Optional child properties if ALS mode is used:
+	- als-vmin - Minimum ALS voltage defined in Volts
+	- als-vmax - Maximum ALS voltage defined in Volts
+
+The values for each of the following can be found in the
+include/dt-bindings/leds/leds-lm3532.h
+
+	- als1-imp-sel - ALS1 impedance resistor selection
+	- als2-imp-sel - ALS2 impedance resistor selection
+	- als-avrg-time - Determines the length of time the device needs to
+			  average the two ALS inputs.  This is only used if
+			  the input mode is LM3532_ALS_INPUT_AVRG.
+	- als-input-mode - Determines how the device uses the attached ALS
+			   devices.
+
+Optional LED child properties:
+	- label : see Documentation/devicetree/bindings/leds/common.txt
+	- linux,default-trigger :
+	   see Documentation/devicetree/bindings/leds/common.txt
+
+Example:
+#include <dt-bindings/leds/leds-lm3532.h>
+
+led-controller@38 {
+	compatible = "ti,lm3532";
+	#address-cells = <1>;
+	#size-cells = <0>;
+	reg = <0x38>;
+
+	enable-gpios = <&gpio6 12 GPIO_ACTIVE_HIGH>;
+	ramp-up-ms = <LM3532_RAMP_1024us>;
+	ramp-down-ms = <LM3532_RAMP_65536us>;
+
+	lcd_backlight: led@0 {
+		reg = <0>;
+		led-sources = <2>;
+		ti,led-mode = <LM3532_BL_MODE_MANUAL>;
+		label = "backlight";
+		linux,default-trigger = "backlight";
+	};
+
+	led@1 {
+		reg = <1>;
+		led-sources = <1>;
+		ti,led-mode = <LM3532_BL_MODE_MANUAL>;
+		label = "keypad";
+	};
+};
+
+Example with ALS
+#include <dt-bindings/leds/leds-lm3532.h>
+
+led-controller@38 {
+	compatible = "ti,lm3532";
+	#address-cells = <1>;
+	#size-cells = <0>;
+	reg = <0x38>;
+
+	enable-gpios = <&gpio6 12 GPIO_ACTIVE_HIGH>;
+	ramp-up-ms = <LM3532_RAMP_1024us>;
+	ramp-down-ms = <LM3532_RAMP_65536us>;
+
+	als-vmin = <0>;
+	als-vmax = <2000>;
+	als1-imp-sel = <LM3532_IMP_4_11K>;
+	als2-imp-sel = <LM3532_IMP_2_18K>;
+	als-avrg-time = <LM3532_ALS_AVRG_TIME_17_92ms>;
+	als-input-mode = <LM3532_ALS_INPUT_AVRG>;
+
+	lcd_backlight: led@0 {
+		reg = <0>;
+		led-sources = <2>;
+		ti,led-mode = <LM3532_BL_MODE_ALS>;
+		label = "backlight";
+		linux,default-trigger = "backlight";
+	};
+
+	led@1 {
+		reg = <1>;
+		led-sources = <1>;
+		ti,led-mode = <LM3532_BL_MODE_MANUAL>;
+		label = "keypad";
+	};
+};
+
+For more product information please see the links below:
+http://www.ti.com/product/LM3532
diff --git a/Documentation/devicetree/bindings/mfd/ti-lmu.txt b/Documentation/devicetree/bindings/mfd/ti-lmu.txt
index c885cf89b8ce..980394d701a7 100644
--- a/Documentation/devicetree/bindings/mfd/ti-lmu.txt
+++ b/Documentation/devicetree/bindings/mfd/ti-lmu.txt
@@ -4,7 +4,6 @@  TI LMU driver supports lighting devices below.
 
    Name                  Child nodes
   ------      ---------------------------------
-  LM3532       Backlight
   LM3631       Backlight and regulator
   LM3632       Backlight and regulator
   LM3633       Backlight, LED and fault monitor
@@ -13,7 +12,6 @@  TI LMU driver supports lighting devices below.
 
 Required properties:
   - compatible: Should be one of:
-                "ti,lm3532"
                 "ti,lm3631"
                 "ti,lm3632"
                 "ti,lm3633"
@@ -23,7 +21,6 @@  Required properties:
          0x11 for LM3632
          0x29 for LM3631
          0x36 for LM3633, LM3697
-         0x38 for LM3532
          0x63 for LM3695
 
 Optional property:
@@ -47,23 +44,6 @@  Optional nodes:
 [2] ../leds/leds-lm3633.txt
 [3] ../regulator/lm363x-regulator.txt
 
-lm3532@38 {
-	compatible = "ti,lm3532";
-	reg = <0x38>;
-
-	enable-gpios = <&pioC 2 GPIO_ACTIVE_HIGH>;
-
-	backlight {
-		compatible = "ti,lm3532-backlight";
-
-		lcd {
-			led-sources = <0 1 2>;
-			ramp-up-msec = <30>;
-			ramp-down-msec = <0>;
-		};
-	};
-};
-
 lm3631@29 {
 	compatible = "ti,lm3631";
 	reg = <0x29>;