linux/drivers/leds/leds-lm3532.c
<<
>>
Prefs
   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>");
 745