Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 // TI LM3532 LED driver
0003 // Copyright (C) 2019 Texas Instruments Incorporated - https://www.ti.com/
0004 // https://www.ti.com/lit/ds/symlink/lm3532.pdf
0005 
0006 #include <linux/i2c.h>
0007 #include <linux/leds.h>
0008 #include <linux/slab.h>
0009 #include <linux/regmap.h>
0010 #include <linux/types.h>
0011 #include <linux/regulator/consumer.h>
0012 #include <linux/module.h>
0013 #include <uapi/linux/uleds.h>
0014 #include <linux/gpio/consumer.h>
0015 
0016 #define LM3532_NAME "lm3532-led"
0017 #define LM3532_BL_MODE_MANUAL   0x00
0018 #define LM3532_BL_MODE_ALS  0x01
0019 
0020 #define LM3532_REG_OUTPUT_CFG   0x10
0021 #define LM3532_REG_STARTSHUT_RAMP   0x11
0022 #define LM3532_REG_RT_RAMP  0x12
0023 #define LM3532_REG_PWM_A_CFG    0x13
0024 #define LM3532_REG_PWM_B_CFG    0x14
0025 #define LM3532_REG_PWM_C_CFG    0x15
0026 #define LM3532_REG_ZONE_CFG_A   0x16
0027 #define LM3532_REG_CTRL_A_FS_CURR   0x17
0028 #define LM3532_REG_ZONE_CFG_B   0x18
0029 #define LM3532_REG_CTRL_B_FS_CURR   0x19
0030 #define LM3532_REG_ZONE_CFG_C   0x1a
0031 #define LM3532_REG_CTRL_C_FS_CURR   0x1b
0032 #define LM3532_REG_ENABLE   0x1d
0033 #define LM3532_ALS_CONFIG   0x23
0034 #define LM3532_REG_ZN_0_HI  0x60
0035 #define LM3532_REG_ZN_0_LO  0x61
0036 #define LM3532_REG_ZN_1_HI  0x62
0037 #define LM3532_REG_ZN_1_LO  0x63
0038 #define LM3532_REG_ZN_2_HI  0x64
0039 #define LM3532_REG_ZN_2_LO  0x65
0040 #define LM3532_REG_ZN_3_HI  0x66
0041 #define LM3532_REG_ZN_3_LO  0x67
0042 #define LM3532_REG_ZONE_TRGT_A  0x70
0043 #define LM3532_REG_ZONE_TRGT_B  0x75
0044 #define LM3532_REG_ZONE_TRGT_C  0x7a
0045 #define LM3532_REG_MAX      0x7e
0046 
0047 /* Control Enable */
0048 #define LM3532_CTRL_A_ENABLE    BIT(0)
0049 #define LM3532_CTRL_B_ENABLE    BIT(1)
0050 #define LM3532_CTRL_C_ENABLE    BIT(2)
0051 
0052 /* PWM Zone Control */
0053 #define LM3532_PWM_ZONE_MASK    0x7c
0054 #define LM3532_PWM_ZONE_0_EN    BIT(2)
0055 #define LM3532_PWM_ZONE_1_EN    BIT(3)
0056 #define LM3532_PWM_ZONE_2_EN    BIT(4)
0057 #define LM3532_PWM_ZONE_3_EN    BIT(5)
0058 #define LM3532_PWM_ZONE_4_EN    BIT(6)
0059 
0060 /* Brightness Configuration */
0061 #define LM3532_I2C_CTRL     BIT(0)
0062 #define LM3532_ALS_CTRL     0
0063 #define LM3532_LINEAR_MAP   BIT(1)
0064 #define LM3532_ZONE_MASK    (BIT(2) | BIT(3) | BIT(4))
0065 #define LM3532_ZONE_0       0
0066 #define LM3532_ZONE_1       BIT(2)
0067 #define LM3532_ZONE_2       BIT(3)
0068 #define LM3532_ZONE_3       (BIT(2) | BIT(3))
0069 #define LM3532_ZONE_4       BIT(4)
0070 
0071 #define LM3532_ENABLE_ALS   BIT(3)
0072 #define LM3532_ALS_SEL_SHIFT    6
0073 
0074 /* Zone Boundary Register */
0075 #define LM3532_ALS_WINDOW_mV    2000
0076 #define LM3532_ALS_ZB_MAX   4
0077 #define LM3532_ALS_OFFSET_mV    2
0078 
0079 #define LM3532_CONTROL_A    0
0080 #define LM3532_CONTROL_B    1
0081 #define LM3532_CONTROL_C    2
0082 #define LM3532_MAX_CONTROL_BANKS 3
0083 #define LM3532_MAX_LED_STRINGS  3
0084 
0085 #define LM3532_OUTPUT_CFG_MASK  0x3
0086 #define LM3532_BRT_VAL_ADJUST   8
0087 #define LM3532_RAMP_DOWN_SHIFT  3
0088 
0089 #define LM3532_NUM_RAMP_VALS    8
0090 #define LM3532_NUM_AVG_VALS 8
0091 #define LM3532_NUM_IMP_VALS 32
0092 
0093 #define LM3532_FS_CURR_MIN  5000
0094 #define LM3532_FS_CURR_MAX  29800
0095 #define LM3532_FS_CURR_STEP 800
0096 
0097 /*
0098  * struct lm3532_als_data
0099  * @config: value of ALS configuration register
0100  * @als1_imp_sel: value of ALS1 resistor select register
0101  * @als2_imp_sel: value of ALS2 resistor select register
0102  * @als_avrg_time: ALS averaging time
0103  * @als_input_mode: ALS input mode for brightness control
0104  * @als_vmin: Minimum ALS voltage
0105  * @als_vmax: Maximum ALS voltage
0106  * @zone_lo: values of ALS lo ZB(Zone Boundary) registers
0107  * @zone_hi: values of ALS hi ZB(Zone Boundary) registers
0108  */
0109 struct lm3532_als_data {
0110     u8 config;
0111     u8 als1_imp_sel;
0112     u8 als2_imp_sel;
0113     u8 als_avrg_time;
0114     u8 als_input_mode;
0115     u32 als_vmin;
0116     u32 als_vmax;
0117     u8 zones_lo[LM3532_ALS_ZB_MAX];
0118     u8 zones_hi[LM3532_ALS_ZB_MAX];
0119 };
0120 
0121 /**
0122  * struct lm3532_led
0123  * @led_dev: led class device
0124  * @priv: Pointer the device data structure
0125  * @control_bank: Control bank the LED is associated to
0126  * @mode: Mode of the LED string
0127  * @ctrl_brt_pointer: Zone target register that controls the sink
0128  * @num_leds: Number of LED strings are supported in this array
0129  * @full_scale_current: The full-scale current setting for the current sink.
0130  * @led_strings: The LED strings supported in this array
0131  * @enabled: Enabled status
0132  */
0133 struct lm3532_led {
0134     struct led_classdev led_dev;
0135     struct lm3532_data *priv;
0136 
0137     int control_bank;
0138     int mode;
0139     int ctrl_brt_pointer;
0140     int num_leds;
0141     int full_scale_current;
0142     unsigned int enabled:1;
0143     u32 led_strings[LM3532_MAX_CONTROL_BANKS];
0144 };
0145 
0146 /**
0147  * struct lm3532_data
0148  * @enable_gpio: Hardware enable gpio
0149  * @regulator: regulator
0150  * @client: i2c client
0151  * @regmap: Devices register map
0152  * @dev: Pointer to the devices device struct
0153  * @lock: Lock for reading/writing the device
0154  * @als_data: Pointer to the als data struct
0155  * @runtime_ramp_up: Runtime ramp up setting
0156  * @runtime_ramp_down: Runtime ramp down setting
0157  * @leds: Array of LED strings
0158  */
0159 struct lm3532_data {
0160     struct gpio_desc *enable_gpio;
0161     struct regulator *regulator;
0162     struct i2c_client *client;
0163     struct regmap *regmap;
0164     struct device *dev;
0165     struct mutex lock;
0166 
0167     struct lm3532_als_data *als_data;
0168 
0169     u32 runtime_ramp_up;
0170     u32 runtime_ramp_down;
0171 
0172     struct lm3532_led leds[];
0173 };
0174 
0175 static const struct reg_default lm3532_reg_defs[] = {
0176     {LM3532_REG_OUTPUT_CFG, 0xe4},
0177     {LM3532_REG_STARTSHUT_RAMP, 0xc0},
0178     {LM3532_REG_RT_RAMP, 0xc0},
0179     {LM3532_REG_PWM_A_CFG, 0x82},
0180     {LM3532_REG_PWM_B_CFG, 0x82},
0181     {LM3532_REG_PWM_C_CFG, 0x82},
0182     {LM3532_REG_ZONE_CFG_A, 0xf1},
0183     {LM3532_REG_CTRL_A_FS_CURR, 0xf3},
0184     {LM3532_REG_ZONE_CFG_B, 0xf1},
0185     {LM3532_REG_CTRL_B_FS_CURR, 0xf3},
0186     {LM3532_REG_ZONE_CFG_C, 0xf1},
0187     {LM3532_REG_CTRL_C_FS_CURR, 0xf3},
0188     {LM3532_REG_ENABLE, 0xf8},
0189     {LM3532_ALS_CONFIG, 0x44},
0190     {LM3532_REG_ZN_0_HI, 0x35},
0191     {LM3532_REG_ZN_0_LO, 0x33},
0192     {LM3532_REG_ZN_1_HI, 0x6a},
0193     {LM3532_REG_ZN_1_LO, 0x66},
0194     {LM3532_REG_ZN_2_HI, 0xa1},
0195     {LM3532_REG_ZN_2_LO, 0x99},
0196     {LM3532_REG_ZN_3_HI, 0xdc},
0197     {LM3532_REG_ZN_3_LO, 0xcc},
0198 };
0199 
0200 static const struct regmap_config lm3532_regmap_config = {
0201     .reg_bits = 8,
0202     .val_bits = 8,
0203 
0204     .max_register = LM3532_REG_MAX,
0205     .reg_defaults = lm3532_reg_defs,
0206     .num_reg_defaults = ARRAY_SIZE(lm3532_reg_defs),
0207     .cache_type = REGCACHE_FLAT,
0208 };
0209 
0210 static const int als_imp_table[LM3532_NUM_IMP_VALS] = {37000, 18500, 12330,
0211                                92500, 7400, 6170, 5290,
0212                                4630, 4110, 3700, 3360,
0213                                3080, 2850, 2640, 2440,
0214                                2310, 2180, 2060, 1950,
0215                                1850, 1760, 1680, 1610,
0216                                1540, 1480, 1420, 1370,
0217                                1320, 1280, 1230, 1190};
0218 static int lm3532_get_als_imp_index(int als_imped)
0219 {
0220     int i;
0221 
0222     if (als_imped > als_imp_table[1])
0223         return 0;
0224 
0225     if (als_imped < als_imp_table[LM3532_NUM_IMP_VALS - 1])
0226         return LM3532_NUM_IMP_VALS - 1;
0227 
0228     for (i = 1; i < LM3532_NUM_IMP_VALS; i++) {
0229         if (als_imped == als_imp_table[i])
0230             return i;
0231 
0232         /* Find an approximate index by looking up the table */
0233         if (als_imped < als_imp_table[i - 1] &&
0234             als_imped > als_imp_table[i]) {
0235             if (als_imped - als_imp_table[i - 1] <
0236                 als_imp_table[i] - als_imped)
0237                 return i + 1;
0238             else
0239                 return i;
0240         }
0241     }
0242 
0243     return -EINVAL;
0244 }
0245 
0246 static int lm3532_get_index(const int table[], int size, int value)
0247 {
0248     int i;
0249 
0250     for (i = 1; i < size; i++) {
0251         if (value == table[i])
0252             return i;
0253 
0254         /* Find an approximate index by looking up the table */
0255         if (value > table[i - 1] &&
0256             value < table[i]) {
0257             if (value - table[i - 1] < table[i] - value)
0258                 return i - 1;
0259             else
0260                 return i;
0261         }
0262     }
0263 
0264     return -EINVAL;
0265 }
0266 
0267 static const int als_avrg_table[LM3532_NUM_AVG_VALS] = {17920, 35840, 71680,
0268                             1433360, 286720, 573440,
0269                             1146880, 2293760};
0270 static int lm3532_get_als_avg_index(int avg_time)
0271 {
0272     if (avg_time <= als_avrg_table[0])
0273         return 0;
0274 
0275     if (avg_time > als_avrg_table[LM3532_NUM_AVG_VALS - 1])
0276         return LM3532_NUM_AVG_VALS - 1;
0277 
0278     return lm3532_get_index(&als_avrg_table[0], LM3532_NUM_AVG_VALS,
0279                 avg_time);
0280 }
0281 
0282 static const int ramp_table[LM3532_NUM_RAMP_VALS] = { 8, 1024, 2048, 4096, 8192,
0283                              16384, 32768, 65536};
0284 static int lm3532_get_ramp_index(int ramp_time)
0285 {
0286     if (ramp_time <= ramp_table[0])
0287         return 0;
0288 
0289     if (ramp_time > ramp_table[LM3532_NUM_RAMP_VALS - 1])
0290         return LM3532_NUM_RAMP_VALS - 1;
0291 
0292     return lm3532_get_index(&ramp_table[0], LM3532_NUM_RAMP_VALS,
0293                 ramp_time);
0294 }
0295 
0296 /* Caller must take care of locking */
0297 static int lm3532_led_enable(struct lm3532_led *led_data)
0298 {
0299     int ctrl_en_val = BIT(led_data->control_bank);
0300     int ret;
0301 
0302     if (led_data->enabled)
0303         return 0;
0304 
0305     ret = regmap_update_bits(led_data->priv->regmap, LM3532_REG_ENABLE,
0306                      ctrl_en_val, ctrl_en_val);
0307     if (ret) {
0308         dev_err(led_data->priv->dev, "Failed to set ctrl:%d\n", ret);
0309         return ret;
0310     }
0311 
0312     ret = regulator_enable(led_data->priv->regulator);
0313     if (ret < 0)
0314         return ret;
0315 
0316     led_data->enabled = 1;
0317 
0318     return 0;
0319 }
0320 
0321 /* Caller must take care of locking */
0322 static int lm3532_led_disable(struct lm3532_led *led_data)
0323 {
0324     int ctrl_en_val = BIT(led_data->control_bank);
0325     int ret;
0326 
0327     if (!led_data->enabled)
0328         return 0;
0329 
0330     ret = regmap_update_bits(led_data->priv->regmap, LM3532_REG_ENABLE,
0331                      ctrl_en_val, 0);
0332     if (ret) {
0333         dev_err(led_data->priv->dev, "Failed to set ctrl:%d\n", ret);
0334         return ret;
0335     }
0336 
0337     ret = regulator_disable(led_data->priv->regulator);
0338     if (ret < 0)
0339         return ret;
0340 
0341     led_data->enabled = 0;
0342 
0343     return 0;
0344 }
0345 
0346 static int lm3532_brightness_set(struct led_classdev *led_cdev,
0347                  enum led_brightness brt_val)
0348 {
0349     struct lm3532_led *led =
0350             container_of(led_cdev, struct lm3532_led, led_dev);
0351     u8 brightness_reg;
0352     int ret;
0353 
0354     mutex_lock(&led->priv->lock);
0355 
0356     if (led->mode == LM3532_ALS_CTRL) {
0357         if (brt_val > LED_OFF)
0358             ret = lm3532_led_enable(led);
0359         else
0360             ret = lm3532_led_disable(led);
0361 
0362         goto unlock;
0363     }
0364 
0365     if (brt_val == LED_OFF) {
0366         ret = lm3532_led_disable(led);
0367         goto unlock;
0368     }
0369 
0370     ret = lm3532_led_enable(led);
0371     if (ret)
0372         goto unlock;
0373 
0374     brightness_reg = LM3532_REG_ZONE_TRGT_A + led->control_bank * 5 +
0375              (led->ctrl_brt_pointer >> 2);
0376 
0377     ret = regmap_write(led->priv->regmap, brightness_reg, brt_val);
0378 
0379 unlock:
0380     mutex_unlock(&led->priv->lock);
0381     return ret;
0382 }
0383 
0384 static int lm3532_init_registers(struct lm3532_led *led)
0385 {
0386     struct lm3532_data *drvdata = led->priv;
0387     unsigned int runtime_ramp_val;
0388     unsigned int output_cfg_val = 0;
0389     unsigned int output_cfg_shift = 0;
0390     unsigned int output_cfg_mask = 0;
0391     unsigned int brightness_config_reg;
0392     unsigned int brightness_config_val;
0393     int fs_current_reg;
0394     int fs_current_val;
0395     int ret, i;
0396 
0397     if (drvdata->enable_gpio)
0398         gpiod_direction_output(drvdata->enable_gpio, 1);
0399 
0400     brightness_config_reg = LM3532_REG_ZONE_CFG_A + led->control_bank * 2;
0401     /*
0402      * This could be hard coded to the default value but the control
0403      * brightness register may have changed during boot.
0404      */
0405     ret = regmap_read(drvdata->regmap, brightness_config_reg,
0406               &led->ctrl_brt_pointer);
0407     if (ret)
0408         return ret;
0409 
0410     led->ctrl_brt_pointer &= LM3532_ZONE_MASK;
0411     brightness_config_val = led->ctrl_brt_pointer | led->mode;
0412     ret = regmap_write(drvdata->regmap, brightness_config_reg,
0413                brightness_config_val);
0414     if (ret)
0415         return ret;
0416 
0417     if (led->full_scale_current) {
0418         fs_current_reg = LM3532_REG_CTRL_A_FS_CURR + led->control_bank * 2;
0419         fs_current_val = (led->full_scale_current - LM3532_FS_CURR_MIN) /
0420                  LM3532_FS_CURR_STEP;
0421 
0422         ret = regmap_write(drvdata->regmap, fs_current_reg,
0423                    fs_current_val);
0424         if (ret)
0425             return ret;
0426     }
0427 
0428     for (i = 0; i < led->num_leds; i++) {
0429         output_cfg_shift = led->led_strings[i] * 2;
0430         output_cfg_val |= (led->control_bank << output_cfg_shift);
0431         output_cfg_mask |= LM3532_OUTPUT_CFG_MASK << output_cfg_shift;
0432     }
0433 
0434     ret = regmap_update_bits(drvdata->regmap, LM3532_REG_OUTPUT_CFG,
0435                  output_cfg_mask, output_cfg_val);
0436     if (ret)
0437         return ret;
0438 
0439     runtime_ramp_val = drvdata->runtime_ramp_up |
0440              (drvdata->runtime_ramp_down << LM3532_RAMP_DOWN_SHIFT);
0441 
0442     return regmap_write(drvdata->regmap, LM3532_REG_RT_RAMP,
0443                 runtime_ramp_val);
0444 }
0445 
0446 static int lm3532_als_configure(struct lm3532_data *priv,
0447                 struct lm3532_led *led)
0448 {
0449     struct lm3532_als_data *als = priv->als_data;
0450     u32 als_vmin, als_vmax, als_vstep;
0451     int zone_reg = LM3532_REG_ZN_0_HI;
0452     int ret;
0453     int i;
0454 
0455     als_vmin = als->als_vmin;
0456     als_vmax = als->als_vmax;
0457 
0458     als_vstep = (als_vmax - als_vmin) / ((LM3532_ALS_ZB_MAX + 1) * 2);
0459 
0460     for (i = 0; i < LM3532_ALS_ZB_MAX; i++) {
0461         als->zones_lo[i] = ((als_vmin + als_vstep + (i * als_vstep)) *
0462                 LED_FULL) / 1000;
0463         als->zones_hi[i] = ((als_vmin + LM3532_ALS_OFFSET_mV +
0464                 als_vstep + (i * als_vstep)) * LED_FULL) / 1000;
0465 
0466         zone_reg = LM3532_REG_ZN_0_HI + i * 2;
0467         ret = regmap_write(priv->regmap, zone_reg, als->zones_lo[i]);
0468         if (ret)
0469             return ret;
0470 
0471         zone_reg += 1;
0472         ret = regmap_write(priv->regmap, zone_reg, als->zones_hi[i]);
0473         if (ret)
0474             return ret;
0475     }
0476 
0477     als->config = (als->als_avrg_time | (LM3532_ENABLE_ALS) |
0478         (als->als_input_mode << LM3532_ALS_SEL_SHIFT));
0479 
0480     return regmap_write(priv->regmap, LM3532_ALS_CONFIG, als->config);
0481 }
0482 
0483 static int lm3532_parse_als(struct lm3532_data *priv)
0484 {
0485     struct lm3532_als_data *als;
0486     int als_avg_time;
0487     int als_impedance;
0488     int ret;
0489 
0490     als = devm_kzalloc(priv->dev, sizeof(*als), GFP_KERNEL);
0491     if (als == NULL)
0492         return -ENOMEM;
0493 
0494     ret = device_property_read_u32(&priv->client->dev, "ti,als-vmin",
0495                        &als->als_vmin);
0496     if (ret)
0497         als->als_vmin = 0;
0498 
0499     ret = device_property_read_u32(&priv->client->dev, "ti,als-vmax",
0500                        &als->als_vmax);
0501     if (ret)
0502         als->als_vmax = LM3532_ALS_WINDOW_mV;
0503 
0504     if (als->als_vmax > LM3532_ALS_WINDOW_mV) {
0505         ret = -EINVAL;
0506         return ret;
0507     }
0508 
0509     ret = device_property_read_u32(&priv->client->dev, "ti,als1-imp-sel",
0510                       &als_impedance);
0511     if (ret)
0512         als->als1_imp_sel = 0;
0513     else
0514         als->als1_imp_sel = lm3532_get_als_imp_index(als_impedance);
0515 
0516     ret = device_property_read_u32(&priv->client->dev, "ti,als2-imp-sel",
0517                       &als_impedance);
0518     if (ret)
0519         als->als2_imp_sel = 0;
0520     else
0521         als->als2_imp_sel = lm3532_get_als_imp_index(als_impedance);
0522 
0523     ret = device_property_read_u32(&priv->client->dev, "ti,als-avrg-time-us",
0524                       &als_avg_time);
0525     if (ret)
0526         als->als_avrg_time = 0;
0527     else
0528         als->als_avrg_time = lm3532_get_als_avg_index(als_avg_time);
0529 
0530     ret = device_property_read_u8(&priv->client->dev, "ti,als-input-mode",
0531                       &als->als_input_mode);
0532     if (ret)
0533         als->als_input_mode = 0;
0534 
0535     if (als->als_input_mode > LM3532_BL_MODE_ALS) {
0536         ret = -EINVAL;
0537         return ret;
0538     }
0539 
0540     priv->als_data = als;
0541 
0542     return ret;
0543 }
0544 
0545 static int lm3532_parse_node(struct lm3532_data *priv)
0546 {
0547     struct fwnode_handle *child = NULL;
0548     struct lm3532_led *led;
0549     int control_bank;
0550     u32 ramp_time;
0551     size_t i = 0;
0552     int ret;
0553 
0554     priv->enable_gpio = devm_gpiod_get_optional(&priv->client->dev,
0555                            "enable", GPIOD_OUT_LOW);
0556     if (IS_ERR(priv->enable_gpio))
0557         priv->enable_gpio = NULL;
0558 
0559     priv->regulator = devm_regulator_get(&priv->client->dev, "vin");
0560     if (IS_ERR(priv->regulator))
0561         priv->regulator = NULL;
0562 
0563     ret = device_property_read_u32(&priv->client->dev, "ramp-up-us",
0564                        &ramp_time);
0565     if (ret)
0566         dev_info(&priv->client->dev, "ramp-up-ms property missing\n");
0567     else
0568         priv->runtime_ramp_up = lm3532_get_ramp_index(ramp_time);
0569 
0570     ret = device_property_read_u32(&priv->client->dev, "ramp-down-us",
0571                        &ramp_time);
0572     if (ret)
0573         dev_info(&priv->client->dev, "ramp-down-ms property missing\n");
0574     else
0575         priv->runtime_ramp_down = lm3532_get_ramp_index(ramp_time);
0576 
0577     device_for_each_child_node(priv->dev, child) {
0578         struct led_init_data idata = {
0579             .fwnode = child,
0580             .default_label = ":",
0581             .devicename = priv->client->name,
0582         };
0583 
0584         led = &priv->leds[i];
0585 
0586         ret = fwnode_property_read_u32(child, "reg", &control_bank);
0587         if (ret) {
0588             dev_err(&priv->client->dev, "reg property missing\n");
0589             goto child_out;
0590         }
0591 
0592         if (control_bank > LM3532_CONTROL_C) {
0593             dev_err(&priv->client->dev, "Control bank invalid\n");
0594             continue;
0595         }
0596 
0597         led->control_bank = control_bank;
0598 
0599         ret = fwnode_property_read_u32(child, "ti,led-mode",
0600                            &led->mode);
0601         if (ret) {
0602             dev_err(&priv->client->dev, "ti,led-mode property missing\n");
0603             goto child_out;
0604         }
0605 
0606         if (fwnode_property_present(child, "led-max-microamp") &&
0607             fwnode_property_read_u32(child, "led-max-microamp",
0608                          &led->full_scale_current))
0609             dev_err(&priv->client->dev,
0610                 "Failed getting led-max-microamp\n");
0611         else
0612             led->full_scale_current = min(led->full_scale_current,
0613                               LM3532_FS_CURR_MAX);
0614 
0615         if (led->mode == LM3532_BL_MODE_ALS) {
0616             led->mode = LM3532_ALS_CTRL;
0617             ret = lm3532_parse_als(priv);
0618             if (ret)
0619                 dev_err(&priv->client->dev, "Failed to parse als\n");
0620             else
0621                 lm3532_als_configure(priv, led);
0622         } else {
0623             led->mode = LM3532_I2C_CTRL;
0624         }
0625 
0626         led->num_leds = fwnode_property_count_u32(child, "led-sources");
0627         if (led->num_leds > LM3532_MAX_LED_STRINGS) {
0628             dev_err(&priv->client->dev, "Too many LED string defined\n");
0629             continue;
0630         }
0631 
0632         ret = fwnode_property_read_u32_array(child, "led-sources",
0633                             led->led_strings,
0634                             led->num_leds);
0635         if (ret) {
0636             dev_err(&priv->client->dev, "led-sources property missing\n");
0637             goto child_out;
0638         }
0639 
0640         led->priv = priv;
0641         led->led_dev.brightness_set_blocking = lm3532_brightness_set;
0642 
0643         ret = devm_led_classdev_register_ext(priv->dev, &led->led_dev, &idata);
0644         if (ret) {
0645             dev_err(&priv->client->dev, "led register err: %d\n",
0646                 ret);
0647             goto child_out;
0648         }
0649 
0650         ret = lm3532_init_registers(led);
0651         if (ret) {
0652             dev_err(&priv->client->dev, "register init err: %d\n",
0653                 ret);
0654             goto child_out;
0655         }
0656 
0657         i++;
0658     }
0659     return 0;
0660 
0661 child_out:
0662     fwnode_handle_put(child);
0663     return ret;
0664 }
0665 
0666 static int lm3532_probe(struct i2c_client *client,
0667                const struct i2c_device_id *id)
0668 {
0669     struct lm3532_data *drvdata;
0670     int ret = 0;
0671     int count;
0672 
0673     count = device_get_child_node_count(&client->dev);
0674     if (!count) {
0675         dev_err(&client->dev, "LEDs are not defined in device tree!");
0676         return -ENODEV;
0677     }
0678 
0679     drvdata = devm_kzalloc(&client->dev, struct_size(drvdata, leds, count),
0680                GFP_KERNEL);
0681     if (drvdata == NULL)
0682         return -ENOMEM;
0683 
0684     drvdata->client = client;
0685     drvdata->dev = &client->dev;
0686 
0687     drvdata->regmap = devm_regmap_init_i2c(client, &lm3532_regmap_config);
0688     if (IS_ERR(drvdata->regmap)) {
0689         ret = PTR_ERR(drvdata->regmap);
0690         dev_err(&client->dev, "Failed to allocate register map: %d\n",
0691             ret);
0692         return ret;
0693     }
0694 
0695     mutex_init(&drvdata->lock);
0696     i2c_set_clientdata(client, drvdata);
0697 
0698     ret = lm3532_parse_node(drvdata);
0699     if (ret) {
0700         dev_err(&client->dev, "Failed to parse node\n");
0701         return ret;
0702     }
0703 
0704     return ret;
0705 }
0706 
0707 static int lm3532_remove(struct i2c_client *client)
0708 {
0709     struct lm3532_data *drvdata = i2c_get_clientdata(client);
0710 
0711     mutex_destroy(&drvdata->lock);
0712 
0713     if (drvdata->enable_gpio)
0714         gpiod_direction_output(drvdata->enable_gpio, 0);
0715 
0716     return 0;
0717 }
0718 
0719 static const struct of_device_id of_lm3532_leds_match[] = {
0720     { .compatible = "ti,lm3532", },
0721     {},
0722 };
0723 MODULE_DEVICE_TABLE(of, of_lm3532_leds_match);
0724 
0725 static const struct i2c_device_id lm3532_id[] = {
0726     {LM3532_NAME, 0},
0727     {}
0728 };
0729 MODULE_DEVICE_TABLE(i2c, lm3532_id);
0730 
0731 static struct i2c_driver lm3532_i2c_driver = {
0732     .probe = lm3532_probe,
0733     .remove = lm3532_remove,
0734     .id_table = lm3532_id,
0735     .driver = {
0736         .name = LM3532_NAME,
0737         .of_match_table = of_lm3532_leds_match,
0738     },
0739 };
0740 module_i2c_driver(lm3532_i2c_driver);
0741 
0742 MODULE_DESCRIPTION("Back Light driver for LM3532");
0743 MODULE_LICENSE("GPL v2");
0744 MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");