root/drivers/leds/leds-lm3532.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. lm3532_get_als_imp_index
  2. lm3532_get_index
  3. lm3532_get_als_avg_index
  4. lm3532_get_ramp_index
  5. lm3532_led_enable
  6. lm3532_led_disable
  7. lm3532_brightness_set
  8. lm3532_init_registers
  9. lm3532_als_configure
  10. lm3532_parse_als
  11. lm3532_parse_node
  12. lm3532_probe
  13. lm3532_remove

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

/* [<][>][^][v][top][bottom][index][help] */