cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

leds-lm3532.c (18935B)


      1// SPDX-License-Identifier: GPL-2.0
      2// TI LM3532 LED driver
      3// Copyright (C) 2019 Texas Instruments Incorporated - https://www.ti.com/
      4// https://www.ti.com/lit/ds/symlink/lm3532.pdf
      5
      6#include <linux/i2c.h>
      7#include <linux/leds.h>
      8#include <linux/slab.h>
      9#include <linux/regmap.h>
     10#include <linux/types.h>
     11#include <linux/regulator/consumer.h>
     12#include <linux/module.h>
     13#include <uapi/linux/uleds.h>
     14#include <linux/gpio/consumer.h>
     15
     16#define LM3532_NAME "lm3532-led"
     17#define LM3532_BL_MODE_MANUAL	0x00
     18#define LM3532_BL_MODE_ALS	0x01
     19
     20#define LM3532_REG_OUTPUT_CFG	0x10
     21#define LM3532_REG_STARTSHUT_RAMP	0x11
     22#define LM3532_REG_RT_RAMP	0x12
     23#define LM3532_REG_PWM_A_CFG	0x13
     24#define LM3532_REG_PWM_B_CFG	0x14
     25#define LM3532_REG_PWM_C_CFG	0x15
     26#define LM3532_REG_ZONE_CFG_A	0x16
     27#define LM3532_REG_CTRL_A_FS_CURR	0x17
     28#define LM3532_REG_ZONE_CFG_B	0x18
     29#define LM3532_REG_CTRL_B_FS_CURR	0x19
     30#define LM3532_REG_ZONE_CFG_C	0x1a
     31#define LM3532_REG_CTRL_C_FS_CURR	0x1b
     32#define LM3532_REG_ENABLE	0x1d
     33#define LM3532_ALS_CONFIG	0x23
     34#define LM3532_REG_ZN_0_HI	0x60
     35#define LM3532_REG_ZN_0_LO	0x61
     36#define LM3532_REG_ZN_1_HI	0x62
     37#define LM3532_REG_ZN_1_LO	0x63
     38#define LM3532_REG_ZN_2_HI	0x64
     39#define LM3532_REG_ZN_2_LO	0x65
     40#define LM3532_REG_ZN_3_HI	0x66
     41#define LM3532_REG_ZN_3_LO	0x67
     42#define LM3532_REG_ZONE_TRGT_A	0x70
     43#define LM3532_REG_ZONE_TRGT_B	0x75
     44#define LM3532_REG_ZONE_TRGT_C	0x7a
     45#define LM3532_REG_MAX		0x7e
     46
     47/* Control Enable */
     48#define LM3532_CTRL_A_ENABLE	BIT(0)
     49#define LM3532_CTRL_B_ENABLE	BIT(1)
     50#define LM3532_CTRL_C_ENABLE	BIT(2)
     51
     52/* PWM Zone Control */
     53#define LM3532_PWM_ZONE_MASK	0x7c
     54#define LM3532_PWM_ZONE_0_EN	BIT(2)
     55#define LM3532_PWM_ZONE_1_EN	BIT(3)
     56#define LM3532_PWM_ZONE_2_EN	BIT(4)
     57#define LM3532_PWM_ZONE_3_EN	BIT(5)
     58#define LM3532_PWM_ZONE_4_EN	BIT(6)
     59
     60/* Brightness Configuration */
     61#define LM3532_I2C_CTRL		BIT(0)
     62#define LM3532_ALS_CTRL		0
     63#define LM3532_LINEAR_MAP	BIT(1)
     64#define LM3532_ZONE_MASK	(BIT(2) | BIT(3) | BIT(4))
     65#define LM3532_ZONE_0		0
     66#define LM3532_ZONE_1		BIT(2)
     67#define LM3532_ZONE_2		BIT(3)
     68#define LM3532_ZONE_3		(BIT(2) | BIT(3))
     69#define LM3532_ZONE_4		BIT(4)
     70
     71#define LM3532_ENABLE_ALS	BIT(3)
     72#define LM3532_ALS_SEL_SHIFT	6
     73
     74/* Zone Boundary Register */
     75#define LM3532_ALS_WINDOW_mV	2000
     76#define LM3532_ALS_ZB_MAX	4
     77#define LM3532_ALS_OFFSET_mV	2
     78
     79#define LM3532_CONTROL_A	0
     80#define LM3532_CONTROL_B	1
     81#define LM3532_CONTROL_C	2
     82#define LM3532_MAX_CONTROL_BANKS 3
     83#define LM3532_MAX_LED_STRINGS	3
     84
     85#define LM3532_OUTPUT_CFG_MASK	0x3
     86#define LM3532_BRT_VAL_ADJUST	8
     87#define LM3532_RAMP_DOWN_SHIFT	3
     88
     89#define LM3532_NUM_RAMP_VALS	8
     90#define LM3532_NUM_AVG_VALS	8
     91#define LM3532_NUM_IMP_VALS	32
     92
     93#define LM3532_FS_CURR_MIN	5000
     94#define LM3532_FS_CURR_MAX	29800
     95#define LM3532_FS_CURR_STEP	800
     96
     97/*
     98 * struct lm3532_als_data
     99 * @config: value of ALS configuration register
    100 * @als1_imp_sel: value of ALS1 resistor select register
    101 * @als2_imp_sel: value of ALS2 resistor select register
    102 * @als_avrg_time: ALS averaging time
    103 * @als_input_mode: ALS input mode for brightness control
    104 * @als_vmin: Minimum ALS voltage
    105 * @als_vmax: Maximum ALS voltage
    106 * @zone_lo: values of ALS lo ZB(Zone Boundary) registers
    107 * @zone_hi: values of ALS hi ZB(Zone Boundary) registers
    108 */
    109struct lm3532_als_data {
    110	u8 config;
    111	u8 als1_imp_sel;
    112	u8 als2_imp_sel;
    113	u8 als_avrg_time;
    114	u8 als_input_mode;
    115	u32 als_vmin;
    116	u32 als_vmax;
    117	u8 zones_lo[LM3532_ALS_ZB_MAX];
    118	u8 zones_hi[LM3532_ALS_ZB_MAX];
    119};
    120
    121/**
    122 * struct lm3532_led
    123 * @led_dev: led class device
    124 * @priv: Pointer the device data structure
    125 * @control_bank: Control bank the LED is associated to
    126 * @mode: Mode of the LED string
    127 * @ctrl_brt_pointer: Zone target register that controls the sink
    128 * @num_leds: Number of LED strings are supported in this array
    129 * @full_scale_current: The full-scale current setting for the current sink.
    130 * @led_strings: The LED strings supported in this array
    131 * @enabled: Enabled status
    132 */
    133struct lm3532_led {
    134	struct led_classdev led_dev;
    135	struct lm3532_data *priv;
    136
    137	int control_bank;
    138	int mode;
    139	int ctrl_brt_pointer;
    140	int num_leds;
    141	int full_scale_current;
    142	unsigned int enabled:1;
    143	u32 led_strings[LM3532_MAX_CONTROL_BANKS];
    144};
    145
    146/**
    147 * struct lm3532_data
    148 * @enable_gpio: Hardware enable gpio
    149 * @regulator: regulator
    150 * @client: i2c client
    151 * @regmap: Devices register map
    152 * @dev: Pointer to the devices device struct
    153 * @lock: Lock for reading/writing the device
    154 * @als_data: Pointer to the als data struct
    155 * @runtime_ramp_up: Runtime ramp up setting
    156 * @runtime_ramp_down: Runtime ramp down setting
    157 * @leds: Array of LED strings
    158 */
    159struct lm3532_data {
    160	struct gpio_desc *enable_gpio;
    161	struct regulator *regulator;
    162	struct i2c_client *client;
    163	struct regmap *regmap;
    164	struct device *dev;
    165	struct mutex lock;
    166
    167	struct lm3532_als_data *als_data;
    168
    169	u32 runtime_ramp_up;
    170	u32 runtime_ramp_down;
    171
    172	struct lm3532_led leds[];
    173};
    174
    175static const struct reg_default lm3532_reg_defs[] = {
    176	{LM3532_REG_OUTPUT_CFG, 0xe4},
    177	{LM3532_REG_STARTSHUT_RAMP, 0xc0},
    178	{LM3532_REG_RT_RAMP, 0xc0},
    179	{LM3532_REG_PWM_A_CFG, 0x82},
    180	{LM3532_REG_PWM_B_CFG, 0x82},
    181	{LM3532_REG_PWM_C_CFG, 0x82},
    182	{LM3532_REG_ZONE_CFG_A, 0xf1},
    183	{LM3532_REG_CTRL_A_FS_CURR, 0xf3},
    184	{LM3532_REG_ZONE_CFG_B, 0xf1},
    185	{LM3532_REG_CTRL_B_FS_CURR, 0xf3},
    186	{LM3532_REG_ZONE_CFG_C, 0xf1},
    187	{LM3532_REG_CTRL_C_FS_CURR, 0xf3},
    188	{LM3532_REG_ENABLE, 0xf8},
    189	{LM3532_ALS_CONFIG, 0x44},
    190	{LM3532_REG_ZN_0_HI, 0x35},
    191	{LM3532_REG_ZN_0_LO, 0x33},
    192	{LM3532_REG_ZN_1_HI, 0x6a},
    193	{LM3532_REG_ZN_1_LO, 0x66},
    194	{LM3532_REG_ZN_2_HI, 0xa1},
    195	{LM3532_REG_ZN_2_LO, 0x99},
    196	{LM3532_REG_ZN_3_HI, 0xdc},
    197	{LM3532_REG_ZN_3_LO, 0xcc},
    198};
    199
    200static const struct regmap_config lm3532_regmap_config = {
    201	.reg_bits = 8,
    202	.val_bits = 8,
    203
    204	.max_register = LM3532_REG_MAX,
    205	.reg_defaults = lm3532_reg_defs,
    206	.num_reg_defaults = ARRAY_SIZE(lm3532_reg_defs),
    207	.cache_type = REGCACHE_FLAT,
    208};
    209
    210static const int als_imp_table[LM3532_NUM_IMP_VALS] = {37000, 18500, 12330,
    211						       92500, 7400, 6170, 5290,
    212						       4630, 4110, 3700, 3360,
    213						       3080, 2850, 2640, 2440,
    214						       2310, 2180, 2060, 1950,
    215						       1850, 1760, 1680, 1610,
    216						       1540, 1480, 1420, 1370,
    217						       1320, 1280, 1230, 1190};
    218static int lm3532_get_als_imp_index(int als_imped)
    219{
    220	int i;
    221
    222	if (als_imped > als_imp_table[1])
    223		return 0;
    224
    225	if (als_imped < als_imp_table[LM3532_NUM_IMP_VALS - 1])
    226		return LM3532_NUM_IMP_VALS - 1;
    227
    228	for (i = 1; i < LM3532_NUM_IMP_VALS; i++) {
    229		if (als_imped == als_imp_table[i])
    230			return i;
    231
    232		/* Find an approximate index by looking up the table */
    233		if (als_imped < als_imp_table[i - 1] &&
    234		    als_imped > als_imp_table[i]) {
    235			if (als_imped - als_imp_table[i - 1] <
    236			    als_imp_table[i] - als_imped)
    237				return i + 1;
    238			else
    239				return i;
    240		}
    241	}
    242
    243	return -EINVAL;
    244}
    245
    246static int lm3532_get_index(const int table[], int size, int value)
    247{
    248	int i;
    249
    250	for (i = 1; i < size; i++) {
    251		if (value == table[i])
    252			return i;
    253
    254		/* Find an approximate index by looking up the table */
    255		if (value > table[i - 1] &&
    256		    value < table[i]) {
    257			if (value - table[i - 1] < table[i] - value)
    258				return i - 1;
    259			else
    260				return i;
    261		}
    262	}
    263
    264	return -EINVAL;
    265}
    266
    267static const int als_avrg_table[LM3532_NUM_AVG_VALS] = {17920, 35840, 71680,
    268							1433360, 286720, 573440,
    269							1146880, 2293760};
    270static int lm3532_get_als_avg_index(int avg_time)
    271{
    272	if (avg_time <= als_avrg_table[0])
    273		return 0;
    274
    275	if (avg_time > als_avrg_table[LM3532_NUM_AVG_VALS - 1])
    276		return LM3532_NUM_AVG_VALS - 1;
    277
    278	return lm3532_get_index(&als_avrg_table[0], LM3532_NUM_AVG_VALS,
    279				avg_time);
    280}
    281
    282static const int ramp_table[LM3532_NUM_RAMP_VALS] = { 8, 1024, 2048, 4096, 8192,
    283						     16384, 32768, 65536};
    284static int lm3532_get_ramp_index(int ramp_time)
    285{
    286	if (ramp_time <= ramp_table[0])
    287		return 0;
    288
    289	if (ramp_time > ramp_table[LM3532_NUM_RAMP_VALS - 1])
    290		return LM3532_NUM_RAMP_VALS - 1;
    291
    292	return lm3532_get_index(&ramp_table[0], LM3532_NUM_RAMP_VALS,
    293				ramp_time);
    294}
    295
    296/* Caller must take care of locking */
    297static int lm3532_led_enable(struct lm3532_led *led_data)
    298{
    299	int ctrl_en_val = BIT(led_data->control_bank);
    300	int ret;
    301
    302	if (led_data->enabled)
    303		return 0;
    304
    305	ret = regmap_update_bits(led_data->priv->regmap, LM3532_REG_ENABLE,
    306					 ctrl_en_val, ctrl_en_val);
    307	if (ret) {
    308		dev_err(led_data->priv->dev, "Failed to set ctrl:%d\n", ret);
    309		return ret;
    310	}
    311
    312	ret = regulator_enable(led_data->priv->regulator);
    313	if (ret < 0)
    314		return ret;
    315
    316	led_data->enabled = 1;
    317
    318	return 0;
    319}
    320
    321/* Caller must take care of locking */
    322static int lm3532_led_disable(struct lm3532_led *led_data)
    323{
    324	int ctrl_en_val = BIT(led_data->control_bank);
    325	int ret;
    326
    327	if (!led_data->enabled)
    328		return 0;
    329
    330	ret = regmap_update_bits(led_data->priv->regmap, LM3532_REG_ENABLE,
    331					 ctrl_en_val, 0);
    332	if (ret) {
    333		dev_err(led_data->priv->dev, "Failed to set ctrl:%d\n", ret);
    334		return ret;
    335	}
    336
    337	ret = regulator_disable(led_data->priv->regulator);
    338	if (ret < 0)
    339		return ret;
    340
    341	led_data->enabled = 0;
    342
    343	return 0;
    344}
    345
    346static int lm3532_brightness_set(struct led_classdev *led_cdev,
    347				 enum led_brightness brt_val)
    348{
    349	struct lm3532_led *led =
    350			container_of(led_cdev, struct lm3532_led, led_dev);
    351	u8 brightness_reg;
    352	int ret;
    353
    354	mutex_lock(&led->priv->lock);
    355
    356	if (led->mode == LM3532_ALS_CTRL) {
    357		if (brt_val > LED_OFF)
    358			ret = lm3532_led_enable(led);
    359		else
    360			ret = lm3532_led_disable(led);
    361
    362		goto unlock;
    363	}
    364
    365	if (brt_val == LED_OFF) {
    366		ret = lm3532_led_disable(led);
    367		goto unlock;
    368	}
    369
    370	ret = lm3532_led_enable(led);
    371	if (ret)
    372		goto unlock;
    373
    374	brightness_reg = LM3532_REG_ZONE_TRGT_A + led->control_bank * 5 +
    375			 (led->ctrl_brt_pointer >> 2);
    376
    377	ret = regmap_write(led->priv->regmap, brightness_reg, brt_val);
    378
    379unlock:
    380	mutex_unlock(&led->priv->lock);
    381	return ret;
    382}
    383
    384static int lm3532_init_registers(struct lm3532_led *led)
    385{
    386	struct lm3532_data *drvdata = led->priv;
    387	unsigned int runtime_ramp_val;
    388	unsigned int output_cfg_val = 0;
    389	unsigned int output_cfg_shift = 0;
    390	unsigned int output_cfg_mask = 0;
    391	unsigned int brightness_config_reg;
    392	unsigned int brightness_config_val;
    393	int fs_current_reg;
    394	int fs_current_val;
    395	int ret, i;
    396
    397	if (drvdata->enable_gpio)
    398		gpiod_direction_output(drvdata->enable_gpio, 1);
    399
    400	brightness_config_reg = LM3532_REG_ZONE_CFG_A + led->control_bank * 2;
    401	/*
    402	 * This could be hard coded to the default value but the control
    403	 * brightness register may have changed during boot.
    404	 */
    405	ret = regmap_read(drvdata->regmap, brightness_config_reg,
    406			  &led->ctrl_brt_pointer);
    407	if (ret)
    408		return ret;
    409
    410	led->ctrl_brt_pointer &= LM3532_ZONE_MASK;
    411	brightness_config_val = led->ctrl_brt_pointer | led->mode;
    412	ret = regmap_write(drvdata->regmap, brightness_config_reg,
    413			   brightness_config_val);
    414	if (ret)
    415		return ret;
    416
    417	if (led->full_scale_current) {
    418		fs_current_reg = LM3532_REG_CTRL_A_FS_CURR + led->control_bank * 2;
    419		fs_current_val = (led->full_scale_current - LM3532_FS_CURR_MIN) /
    420				 LM3532_FS_CURR_STEP;
    421
    422		ret = regmap_write(drvdata->regmap, fs_current_reg,
    423				   fs_current_val);
    424		if (ret)
    425			return ret;
    426	}
    427
    428	for (i = 0; i < led->num_leds; i++) {
    429		output_cfg_shift = led->led_strings[i] * 2;
    430		output_cfg_val |= (led->control_bank << output_cfg_shift);
    431		output_cfg_mask |= LM3532_OUTPUT_CFG_MASK << output_cfg_shift;
    432	}
    433
    434	ret = regmap_update_bits(drvdata->regmap, LM3532_REG_OUTPUT_CFG,
    435				 output_cfg_mask, output_cfg_val);
    436	if (ret)
    437		return ret;
    438
    439	runtime_ramp_val = drvdata->runtime_ramp_up |
    440			 (drvdata->runtime_ramp_down << LM3532_RAMP_DOWN_SHIFT);
    441
    442	return regmap_write(drvdata->regmap, LM3532_REG_RT_RAMP,
    443			    runtime_ramp_val);
    444}
    445
    446static int lm3532_als_configure(struct lm3532_data *priv,
    447				struct lm3532_led *led)
    448{
    449	struct lm3532_als_data *als = priv->als_data;
    450	u32 als_vmin, als_vmax, als_vstep;
    451	int zone_reg = LM3532_REG_ZN_0_HI;
    452	int ret;
    453	int i;
    454
    455	als_vmin = als->als_vmin;
    456	als_vmax = als->als_vmax;
    457
    458	als_vstep = (als_vmax - als_vmin) / ((LM3532_ALS_ZB_MAX + 1) * 2);
    459
    460	for (i = 0; i < LM3532_ALS_ZB_MAX; i++) {
    461		als->zones_lo[i] = ((als_vmin + als_vstep + (i * als_vstep)) *
    462				LED_FULL) / 1000;
    463		als->zones_hi[i] = ((als_vmin + LM3532_ALS_OFFSET_mV +
    464				als_vstep + (i * als_vstep)) * LED_FULL) / 1000;
    465
    466		zone_reg = LM3532_REG_ZN_0_HI + i * 2;
    467		ret = regmap_write(priv->regmap, zone_reg, als->zones_lo[i]);
    468		if (ret)
    469			return ret;
    470
    471		zone_reg += 1;
    472		ret = regmap_write(priv->regmap, zone_reg, als->zones_hi[i]);
    473		if (ret)
    474			return ret;
    475	}
    476
    477	als->config = (als->als_avrg_time | (LM3532_ENABLE_ALS) |
    478		(als->als_input_mode << LM3532_ALS_SEL_SHIFT));
    479
    480	return regmap_write(priv->regmap, LM3532_ALS_CONFIG, als->config);
    481}
    482
    483static int lm3532_parse_als(struct lm3532_data *priv)
    484{
    485	struct lm3532_als_data *als;
    486	int als_avg_time;
    487	int als_impedance;
    488	int ret;
    489
    490	als = devm_kzalloc(priv->dev, sizeof(*als), GFP_KERNEL);
    491	if (als == NULL)
    492		return -ENOMEM;
    493
    494	ret = device_property_read_u32(&priv->client->dev, "ti,als-vmin",
    495				       &als->als_vmin);
    496	if (ret)
    497		als->als_vmin = 0;
    498
    499	ret = device_property_read_u32(&priv->client->dev, "ti,als-vmax",
    500				       &als->als_vmax);
    501	if (ret)
    502		als->als_vmax = LM3532_ALS_WINDOW_mV;
    503
    504	if (als->als_vmax > LM3532_ALS_WINDOW_mV) {
    505		ret = -EINVAL;
    506		return ret;
    507	}
    508
    509	ret = device_property_read_u32(&priv->client->dev, "ti,als1-imp-sel",
    510				      &als_impedance);
    511	if (ret)
    512		als->als1_imp_sel = 0;
    513	else
    514		als->als1_imp_sel = lm3532_get_als_imp_index(als_impedance);
    515
    516	ret = device_property_read_u32(&priv->client->dev, "ti,als2-imp-sel",
    517				      &als_impedance);
    518	if (ret)
    519		als->als2_imp_sel = 0;
    520	else
    521		als->als2_imp_sel = lm3532_get_als_imp_index(als_impedance);
    522
    523	ret = device_property_read_u32(&priv->client->dev, "ti,als-avrg-time-us",
    524				      &als_avg_time);
    525	if (ret)
    526		als->als_avrg_time = 0;
    527	else
    528		als->als_avrg_time = lm3532_get_als_avg_index(als_avg_time);
    529
    530	ret = device_property_read_u8(&priv->client->dev, "ti,als-input-mode",
    531				      &als->als_input_mode);
    532	if (ret)
    533		als->als_input_mode = 0;
    534
    535	if (als->als_input_mode > LM3532_BL_MODE_ALS) {
    536		ret = -EINVAL;
    537		return ret;
    538	}
    539
    540	priv->als_data = als;
    541
    542	return ret;
    543}
    544
    545static int lm3532_parse_node(struct lm3532_data *priv)
    546{
    547	struct fwnode_handle *child = NULL;
    548	struct lm3532_led *led;
    549	int control_bank;
    550	u32 ramp_time;
    551	size_t i = 0;
    552	int ret;
    553
    554	priv->enable_gpio = devm_gpiod_get_optional(&priv->client->dev,
    555						   "enable", GPIOD_OUT_LOW);
    556	if (IS_ERR(priv->enable_gpio))
    557		priv->enable_gpio = NULL;
    558
    559	priv->regulator = devm_regulator_get(&priv->client->dev, "vin");
    560	if (IS_ERR(priv->regulator))
    561		priv->regulator = NULL;
    562
    563	ret = device_property_read_u32(&priv->client->dev, "ramp-up-us",
    564				       &ramp_time);
    565	if (ret)
    566		dev_info(&priv->client->dev, "ramp-up-ms property missing\n");
    567	else
    568		priv->runtime_ramp_up = lm3532_get_ramp_index(ramp_time);
    569
    570	ret = device_property_read_u32(&priv->client->dev, "ramp-down-us",
    571				       &ramp_time);
    572	if (ret)
    573		dev_info(&priv->client->dev, "ramp-down-ms property missing\n");
    574	else
    575		priv->runtime_ramp_down = lm3532_get_ramp_index(ramp_time);
    576
    577	device_for_each_child_node(priv->dev, child) {
    578		struct led_init_data idata = {
    579			.fwnode = child,
    580			.default_label = ":",
    581			.devicename = priv->client->name,
    582		};
    583
    584		led = &priv->leds[i];
    585
    586		ret = fwnode_property_read_u32(child, "reg", &control_bank);
    587		if (ret) {
    588			dev_err(&priv->client->dev, "reg property missing\n");
    589			goto child_out;
    590		}
    591
    592		if (control_bank > LM3532_CONTROL_C) {
    593			dev_err(&priv->client->dev, "Control bank invalid\n");
    594			continue;
    595		}
    596
    597		led->control_bank = control_bank;
    598
    599		ret = fwnode_property_read_u32(child, "ti,led-mode",
    600					       &led->mode);
    601		if (ret) {
    602			dev_err(&priv->client->dev, "ti,led-mode property missing\n");
    603			goto child_out;
    604		}
    605
    606		if (fwnode_property_present(child, "led-max-microamp") &&
    607		    fwnode_property_read_u32(child, "led-max-microamp",
    608					     &led->full_scale_current))
    609			dev_err(&priv->client->dev,
    610				"Failed getting led-max-microamp\n");
    611		else
    612			led->full_scale_current = min(led->full_scale_current,
    613						      LM3532_FS_CURR_MAX);
    614
    615		if (led->mode == LM3532_BL_MODE_ALS) {
    616			led->mode = LM3532_ALS_CTRL;
    617			ret = lm3532_parse_als(priv);
    618			if (ret)
    619				dev_err(&priv->client->dev, "Failed to parse als\n");
    620			else
    621				lm3532_als_configure(priv, led);
    622		} else {
    623			led->mode = LM3532_I2C_CTRL;
    624		}
    625
    626		led->num_leds = fwnode_property_count_u32(child, "led-sources");
    627		if (led->num_leds > LM3532_MAX_LED_STRINGS) {
    628			dev_err(&priv->client->dev, "Too many LED string defined\n");
    629			continue;
    630		}
    631
    632		ret = fwnode_property_read_u32_array(child, "led-sources",
    633						    led->led_strings,
    634						    led->num_leds);
    635		if (ret) {
    636			dev_err(&priv->client->dev, "led-sources property missing\n");
    637			goto child_out;
    638		}
    639
    640		led->priv = priv;
    641		led->led_dev.brightness_set_blocking = lm3532_brightness_set;
    642
    643		ret = devm_led_classdev_register_ext(priv->dev, &led->led_dev, &idata);
    644		if (ret) {
    645			dev_err(&priv->client->dev, "led register err: %d\n",
    646				ret);
    647			goto child_out;
    648		}
    649
    650		ret = lm3532_init_registers(led);
    651		if (ret) {
    652			dev_err(&priv->client->dev, "register init err: %d\n",
    653				ret);
    654			goto child_out;
    655		}
    656
    657		i++;
    658	}
    659	return 0;
    660
    661child_out:
    662	fwnode_handle_put(child);
    663	return ret;
    664}
    665
    666static int lm3532_probe(struct i2c_client *client,
    667			   const struct i2c_device_id *id)
    668{
    669	struct lm3532_data *drvdata;
    670	int ret = 0;
    671	int count;
    672
    673	count = device_get_child_node_count(&client->dev);
    674	if (!count) {
    675		dev_err(&client->dev, "LEDs are not defined in device tree!");
    676		return -ENODEV;
    677	}
    678
    679	drvdata = devm_kzalloc(&client->dev, struct_size(drvdata, leds, count),
    680			   GFP_KERNEL);
    681	if (drvdata == NULL)
    682		return -ENOMEM;
    683
    684	drvdata->client = client;
    685	drvdata->dev = &client->dev;
    686
    687	drvdata->regmap = devm_regmap_init_i2c(client, &lm3532_regmap_config);
    688	if (IS_ERR(drvdata->regmap)) {
    689		ret = PTR_ERR(drvdata->regmap);
    690		dev_err(&client->dev, "Failed to allocate register map: %d\n",
    691			ret);
    692		return ret;
    693	}
    694
    695	mutex_init(&drvdata->lock);
    696	i2c_set_clientdata(client, drvdata);
    697
    698	ret = lm3532_parse_node(drvdata);
    699	if (ret) {
    700		dev_err(&client->dev, "Failed to parse node\n");
    701		return ret;
    702	}
    703
    704	return ret;
    705}
    706
    707static int lm3532_remove(struct i2c_client *client)
    708{
    709	struct lm3532_data *drvdata = i2c_get_clientdata(client);
    710
    711	mutex_destroy(&drvdata->lock);
    712
    713	if (drvdata->enable_gpio)
    714		gpiod_direction_output(drvdata->enable_gpio, 0);
    715
    716	return 0;
    717}
    718
    719static const struct of_device_id of_lm3532_leds_match[] = {
    720	{ .compatible = "ti,lm3532", },
    721	{},
    722};
    723MODULE_DEVICE_TABLE(of, of_lm3532_leds_match);
    724
    725static const struct i2c_device_id lm3532_id[] = {
    726	{LM3532_NAME, 0},
    727	{}
    728};
    729MODULE_DEVICE_TABLE(i2c, lm3532_id);
    730
    731static struct i2c_driver lm3532_i2c_driver = {
    732	.probe = lm3532_probe,
    733	.remove = lm3532_remove,
    734	.id_table = lm3532_id,
    735	.driver = {
    736		.name = LM3532_NAME,
    737		.of_match_table = of_lm3532_leds_match,
    738	},
    739};
    740module_i2c_driver(lm3532_i2c_driver);
    741
    742MODULE_DESCRIPTION("Back Light driver for LM3532");
    743MODULE_LICENSE("GPL v2");
    744MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");