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 * @label - LED label
 133 */
 134struct lm3532_led {
 135        struct led_classdev led_dev;
 136        struct lm3532_data *priv;
 137
 138        int control_bank;
 139        int mode;
 140        int ctrl_brt_pointer;
 141        int num_leds;
 142        int full_scale_current;
 143        unsigned int enabled:1;
 144        u32 led_strings[LM3532_MAX_CONTROL_BANKS];
 145        char label[LED_MAX_NAME_SIZE];
 146};
 147
 148/**
 149 * struct lm3532_data
 150 * @enable_gpio - Hardware enable gpio
 151 * @regulator: regulator
 152 * @client: i2c client
 153 * @regmap - Devices register map
 154 * @dev - Pointer to the devices device struct
 155 * @lock - Lock for reading/writing the device
 156 * @als_data - Pointer to the als data struct
 157 * @runtime_ramp_up - Runtime ramp up setting
 158 * @runtime_ramp_down - Runtime ramp down setting
 159 * @leds - Array of LED strings
 160 */
 161struct lm3532_data {
 162        struct gpio_desc *enable_gpio;
 163        struct regulator *regulator;
 164        struct i2c_client *client;
 165        struct regmap *regmap;
 166        struct device *dev;
 167        struct mutex lock;
 168
 169        struct lm3532_als_data *als_data;
 170
 171        u32 runtime_ramp_up;
 172        u32 runtime_ramp_down;
 173
 174        struct lm3532_led leds[];
 175};
 176
 177static const struct reg_default lm3532_reg_defs[] = {
 178        {LM3532_REG_OUTPUT_CFG, 0xe4},
 179        {LM3532_REG_STARTSHUT_RAMP, 0xc0},
 180        {LM3532_REG_RT_RAMP, 0xc0},
 181        {LM3532_REG_PWM_A_CFG, 0x82},
 182        {LM3532_REG_PWM_B_CFG, 0x82},
 183        {LM3532_REG_PWM_C_CFG, 0x82},
 184        {LM3532_REG_ZONE_CFG_A, 0xf1},
 185        {LM3532_REG_CTRL_A_FS_CURR, 0xf3},
 186        {LM3532_REG_ZONE_CFG_B, 0xf1},
 187        {LM3532_REG_CTRL_B_FS_CURR, 0xf3},
 188        {LM3532_REG_ZONE_CFG_C, 0xf1},
 189        {LM3532_REG_CTRL_C_FS_CURR, 0xf3},
 190        {LM3532_REG_ENABLE, 0xf8},
 191        {LM3532_ALS_CONFIG, 0x44},
 192        {LM3532_REG_ZN_0_HI, 0x35},
 193        {LM3532_REG_ZN_0_LO, 0x33},
 194        {LM3532_REG_ZN_1_HI, 0x6a},
 195        {LM3532_REG_ZN_1_LO, 0x66},
 196        {LM3532_REG_ZN_2_HI, 0xa1},
 197        {LM3532_REG_ZN_2_LO, 0x99},
 198        {LM3532_REG_ZN_3_HI, 0xdc},
 199        {LM3532_REG_ZN_3_LO, 0xcc},
 200};
 201
 202static const struct regmap_config lm3532_regmap_config = {
 203        .reg_bits = 8,
 204        .val_bits = 8,
 205
 206        .max_register = LM3532_REG_MAX,
 207        .reg_defaults = lm3532_reg_defs,
 208        .num_reg_defaults = ARRAY_SIZE(lm3532_reg_defs),
 209        .cache_type = REGCACHE_FLAT,
 210};
 211
 212static const int als_imp_table[LM3532_NUM_IMP_VALS] = {37000, 18500, 12330,
 213                                                       92500, 7400, 6170, 5290,
 214                                                       4630, 4110, 3700, 3360,
 215                                                       3080, 2850, 2640, 2440,
 216                                                       2310, 2180, 2060, 1950,
 217                                                       1850, 1760, 1680, 1610,
 218                                                       1540, 1480, 1420, 1370,
 219                                                       1320, 1280, 1230, 1190};
 220static int lm3532_get_als_imp_index(int als_imped)
 221{
 222        int i;
 223
 224        if (als_imped > als_imp_table[1])
 225                return 0;
 226
 227        if (als_imped < als_imp_table[LM3532_NUM_IMP_VALS - 1])
 228                return LM3532_NUM_IMP_VALS - 1;
 229
 230        for (i = 1; i < LM3532_NUM_IMP_VALS; i++) {
 231                if (als_imped == als_imp_table[i])
 232                        return i;
 233
 234                /* Find an approximate index by looking up the table */
 235                if (als_imped < als_imp_table[i - 1] &&
 236                    als_imped > als_imp_table[i]) {
 237                        if (als_imped - als_imp_table[i - 1] <
 238                            als_imp_table[i] - als_imped)
 239                                return i + 1;
 240                        else
 241                                return i;
 242                }
 243        }
 244
 245        return -EINVAL;
 246}
 247
 248static int lm3532_get_index(const int table[], int size, int value)
 249{
 250        int i;
 251
 252        for (i = 1; i < size; i++) {
 253                if (value == table[i])
 254                        return i;
 255
 256                /* Find an approximate index by looking up the table */
 257                if (value > table[i - 1] &&
 258                    value < table[i]) {
 259                        if (value - table[i - 1] < table[i] - value)
 260                                return i - 1;
 261                        else
 262                                return i;
 263                }
 264        }
 265
 266        return -EINVAL;
 267}
 268
 269static const int als_avrg_table[LM3532_NUM_AVG_VALS] = {17920, 35840, 71680,
 270                                                        1433360, 286720, 573440,
 271                                                        1146880, 2293760};
 272static int lm3532_get_als_avg_index(int avg_time)
 273{
 274        if (avg_time <= als_avrg_table[0])
 275                return 0;
 276
 277        if (avg_time > als_avrg_table[LM3532_NUM_AVG_VALS - 1])
 278                return LM3532_NUM_AVG_VALS - 1;
 279
 280        return lm3532_get_index(&als_avrg_table[0], LM3532_NUM_AVG_VALS,
 281                                avg_time);
 282}
 283
 284static const int ramp_table[LM3532_NUM_RAMP_VALS] = { 8, 1024, 2048, 4096, 8192,
 285                                                     16384, 32768, 65536};
 286static int lm3532_get_ramp_index(int ramp_time)
 287{
 288        if (ramp_time <= ramp_table[0])
 289                return 0;
 290
 291        if (ramp_time > ramp_table[LM3532_NUM_RAMP_VALS - 1])
 292                return LM3532_NUM_RAMP_VALS - 1;
 293
 294        return lm3532_get_index(&ramp_table[0], LM3532_NUM_RAMP_VALS,
 295                                ramp_time);
 296}
 297
 298/* Caller must take care of locking */
 299static int lm3532_led_enable(struct lm3532_led *led_data)
 300{
 301        int ctrl_en_val = BIT(led_data->control_bank);
 302        int ret;
 303
 304        if (led_data->enabled)
 305                return 0;
 306
 307        ret = regmap_update_bits(led_data->priv->regmap, LM3532_REG_ENABLE,
 308                                         ctrl_en_val, ctrl_en_val);
 309        if (ret) {
 310                dev_err(led_data->priv->dev, "Failed to set ctrl:%d\n", ret);
 311                return ret;
 312        }
 313
 314        ret = regulator_enable(led_data->priv->regulator);
 315        if (ret < 0)
 316                return ret;
 317
 318        led_data->enabled = 1;
 319
 320        return 0;
 321}
 322
 323/* Caller must take care of locking */
 324static int lm3532_led_disable(struct lm3532_led *led_data)
 325{
 326        int ctrl_en_val = BIT(led_data->control_bank);
 327        int ret;
 328
 329        if (!led_data->enabled)
 330                return 0;
 331
 332        ret = regmap_update_bits(led_data->priv->regmap, LM3532_REG_ENABLE,
 333                                         ctrl_en_val, 0);
 334        if (ret) {
 335                dev_err(led_data->priv->dev, "Failed to set ctrl:%d\n", ret);
 336                return ret;
 337        }
 338
 339        ret = regulator_disable(led_data->priv->regulator);
 340        if (ret < 0)
 341                return ret;
 342
 343        led_data->enabled = 0;
 344
 345        return 0;
 346}
 347
 348static int lm3532_brightness_set(struct led_classdev *led_cdev,
 349                                 enum led_brightness brt_val)
 350{
 351        struct lm3532_led *led =
 352                        container_of(led_cdev, struct lm3532_led, led_dev);
 353        u8 brightness_reg;
 354        int ret;
 355
 356        mutex_lock(&led->priv->lock);
 357
 358        if (led->mode == LM3532_ALS_CTRL) {
 359                if (brt_val > LED_OFF)
 360                        ret = lm3532_led_enable(led);
 361                else
 362                        ret = lm3532_led_disable(led);
 363
 364                goto unlock;
 365        }
 366
 367        if (brt_val == LED_OFF) {
 368                ret = lm3532_led_disable(led);
 369                goto unlock;
 370        }
 371
 372        ret = lm3532_led_enable(led);
 373        if (ret)
 374                goto unlock;
 375
 376        brightness_reg = LM3532_REG_ZONE_TRGT_A + led->control_bank * 5 +
 377                         (led->ctrl_brt_pointer >> 2);
 378
 379        ret = regmap_write(led->priv->regmap, brightness_reg, brt_val);
 380
 381unlock:
 382        mutex_unlock(&led->priv->lock);
 383        return ret;
 384}
 385
 386static int lm3532_init_registers(struct lm3532_led *led)
 387{
 388        struct lm3532_data *drvdata = led->priv;
 389        unsigned int runtime_ramp_val;
 390        unsigned int output_cfg_val = 0;
 391        unsigned int output_cfg_shift = 0;
 392        unsigned int output_cfg_mask = 0;
 393        unsigned int brightness_config_reg;
 394        unsigned int brightness_config_val;
 395        int fs_current_reg;
 396        int fs_current_val;
 397        int ret, i;
 398
 399        if (drvdata->enable_gpio)
 400                gpiod_direction_output(drvdata->enable_gpio, 1);
 401
 402        brightness_config_reg = LM3532_REG_ZONE_CFG_A + led->control_bank * 2;
 403        /*
 404         * This could be hard coded to the default value but the control
 405         * brightness register may have changed during boot.
 406         */
 407        ret = regmap_read(drvdata->regmap, brightness_config_reg,
 408                          &led->ctrl_brt_pointer);
 409        if (ret)
 410                return ret;
 411
 412        led->ctrl_brt_pointer &= LM3532_ZONE_MASK;
 413        brightness_config_val = led->ctrl_brt_pointer | led->mode;
 414        ret = regmap_write(drvdata->regmap, brightness_config_reg,
 415                           brightness_config_val);
 416        if (ret)
 417                return ret;
 418
 419        if (led->full_scale_current) {
 420                fs_current_reg = LM3532_REG_CTRL_A_FS_CURR + led->control_bank * 2;
 421                fs_current_val = (led->full_scale_current - LM3532_FS_CURR_MIN) /
 422                                 LM3532_FS_CURR_STEP;
 423
 424                ret = regmap_write(drvdata->regmap, fs_current_reg,
 425                                   fs_current_val);
 426                if (ret)
 427                        return ret;
 428        }
 429
 430        for (i = 0; i < led->num_leds; i++) {
 431                output_cfg_shift = led->led_strings[i] * 2;
 432                output_cfg_val |= (led->control_bank << output_cfg_shift);
 433                output_cfg_mask |= LM3532_OUTPUT_CFG_MASK << output_cfg_shift;
 434        }
 435
 436        ret = regmap_update_bits(drvdata->regmap, LM3532_REG_OUTPUT_CFG,
 437                                 output_cfg_mask, output_cfg_val);
 438        if (ret)
 439                return ret;
 440
 441        runtime_ramp_val = drvdata->runtime_ramp_up |
 442                         (drvdata->runtime_ramp_down << LM3532_RAMP_DOWN_SHIFT);
 443
 444        return regmap_write(drvdata->regmap, LM3532_REG_RT_RAMP,
 445                            runtime_ramp_val);
 446}
 447
 448static int lm3532_als_configure(struct lm3532_data *priv,
 449                                struct lm3532_led *led)
 450{
 451        struct lm3532_als_data *als = priv->als_data;
 452        u32 als_vmin, als_vmax, als_vstep;
 453        int zone_reg = LM3532_REG_ZN_0_HI;
 454        int ret;
 455        int i;
 456
 457        als_vmin = als->als_vmin;
 458        als_vmax = als->als_vmax;
 459
 460        als_vstep = (als_vmax - als_vmin) / ((LM3532_ALS_ZB_MAX + 1) * 2);
 461
 462        for (i = 0; i < LM3532_ALS_ZB_MAX; i++) {
 463                als->zones_lo[i] = ((als_vmin + als_vstep + (i * als_vstep)) *
 464                                LED_FULL) / 1000;
 465                als->zones_hi[i] = ((als_vmin + LM3532_ALS_OFFSET_mV +
 466                                als_vstep + (i * als_vstep)) * LED_FULL) / 1000;
 467
 468                zone_reg = LM3532_REG_ZN_0_HI + i * 2;
 469                ret = regmap_write(priv->regmap, zone_reg, als->zones_lo[i]);
 470                if (ret)
 471                        return ret;
 472
 473                zone_reg += 1;
 474                ret = regmap_write(priv->regmap, zone_reg, als->zones_hi[i]);
 475                if (ret)
 476                        return ret;
 477        }
 478
 479        als->config = (als->als_avrg_time | (LM3532_ENABLE_ALS) |
 480                (als->als_input_mode << LM3532_ALS_SEL_SHIFT));
 481
 482        return regmap_write(priv->regmap, LM3532_ALS_CONFIG, als->config);
 483}
 484
 485static int lm3532_parse_als(struct lm3532_data *priv)
 486{
 487        struct lm3532_als_data *als;
 488        int als_avg_time;
 489        int als_impedance;
 490        int ret;
 491
 492        als = devm_kzalloc(priv->dev, sizeof(*als), GFP_KERNEL);
 493        if (als == NULL)
 494                return -ENOMEM;
 495
 496        ret = device_property_read_u32(&priv->client->dev, "ti,als-vmin",
 497                                       &als->als_vmin);
 498        if (ret)
 499                als->als_vmin = 0;
 500
 501        ret = device_property_read_u32(&priv->client->dev, "ti,als-vmax",
 502                                       &als->als_vmax);
 503        if (ret)
 504                als->als_vmax = LM3532_ALS_WINDOW_mV;
 505
 506        if (als->als_vmax > LM3532_ALS_WINDOW_mV) {
 507                ret = -EINVAL;
 508                return ret;
 509        }
 510
 511        ret = device_property_read_u32(&priv->client->dev, "ti,als1-imp-sel",
 512                                      &als_impedance);
 513        if (ret)
 514                als->als1_imp_sel = 0;
 515        else
 516                als->als1_imp_sel = lm3532_get_als_imp_index(als_impedance);
 517
 518        ret = device_property_read_u32(&priv->client->dev, "ti,als2-imp-sel",
 519                                      &als_impedance);
 520        if (ret)
 521                als->als2_imp_sel = 0;
 522        else
 523                als->als2_imp_sel = lm3532_get_als_imp_index(als_impedance);
 524
 525        ret = device_property_read_u32(&priv->client->dev, "ti,als-avrg-time-us",
 526                                      &als_avg_time);
 527        if (ret)
 528                als->als_avrg_time = 0;
 529        else
 530                als->als_avrg_time = lm3532_get_als_avg_index(als_avg_time);
 531
 532        ret = device_property_read_u8(&priv->client->dev, "ti,als-input-mode",
 533                                      &als->als_input_mode);
 534        if (ret)
 535                als->als_input_mode = 0;
 536
 537        if (als->als_input_mode > LM3532_BL_MODE_ALS) {
 538                ret = -EINVAL;
 539                return ret;
 540        }
 541
 542        priv->als_data = als;
 543
 544        return ret;
 545}
 546
 547static int lm3532_parse_node(struct lm3532_data *priv)
 548{
 549        struct fwnode_handle *child = NULL;
 550        struct lm3532_led *led;
 551        const char *name;
 552        int control_bank;
 553        u32 ramp_time;
 554        size_t i = 0;
 555        int ret;
 556
 557        priv->enable_gpio = devm_gpiod_get_optional(&priv->client->dev,
 558                                                   "enable", GPIOD_OUT_LOW);
 559        if (IS_ERR(priv->enable_gpio))
 560                priv->enable_gpio = NULL;
 561
 562        priv->regulator = devm_regulator_get(&priv->client->dev, "vin");
 563        if (IS_ERR(priv->regulator))
 564                priv->regulator = NULL;
 565
 566        ret = device_property_read_u32(&priv->client->dev, "ramp-up-us",
 567                                       &ramp_time);
 568        if (ret)
 569                dev_info(&priv->client->dev, "ramp-up-ms property missing\n");
 570        else
 571                priv->runtime_ramp_up = lm3532_get_ramp_index(ramp_time);
 572
 573        ret = device_property_read_u32(&priv->client->dev, "ramp-down-us",
 574                                       &ramp_time);
 575        if (ret)
 576                dev_info(&priv->client->dev, "ramp-down-ms property missing\n");
 577        else
 578                priv->runtime_ramp_down = lm3532_get_ramp_index(ramp_time);
 579
 580        device_for_each_child_node(priv->dev, child) {
 581                struct led_init_data idata = {
 582                        .fwnode = child,
 583                        .default_label = ":",
 584                        .devicename = priv->client->name,
 585                };
 586
 587                led = &priv->leds[i];
 588
 589                ret = fwnode_property_read_u32(child, "reg", &control_bank);
 590                if (ret) {
 591                        dev_err(&priv->client->dev, "reg property missing\n");
 592                        fwnode_handle_put(child);
 593                        goto child_out;
 594                }
 595
 596                if (control_bank > LM3532_CONTROL_C) {
 597                        dev_err(&priv->client->dev, "Control bank invalid\n");
 598                        continue;
 599                }
 600
 601                led->control_bank = control_bank;
 602
 603                ret = fwnode_property_read_u32(child, "ti,led-mode",
 604                                               &led->mode);
 605                if (ret) {
 606                        dev_err(&priv->client->dev, "ti,led-mode property missing\n");
 607                        fwnode_handle_put(child);
 608                        goto child_out;
 609                }
 610
 611                if (fwnode_property_present(child, "led-max-microamp") &&
 612                    fwnode_property_read_u32(child, "led-max-microamp",
 613                                             &led->full_scale_current))
 614                        dev_err(&priv->client->dev,
 615                                "Failed getting led-max-microamp\n");
 616                else
 617                        led->full_scale_current = min(led->full_scale_current,
 618                                                      LM3532_FS_CURR_MAX);
 619
 620                if (led->mode == LM3532_BL_MODE_ALS) {
 621                        led->mode = LM3532_ALS_CTRL;
 622                        ret = lm3532_parse_als(priv);
 623                        if (ret)
 624                                dev_err(&priv->client->dev, "Failed to parse als\n");
 625                        else
 626                                lm3532_als_configure(priv, led);
 627                } else {
 628                        led->mode = LM3532_I2C_CTRL;
 629                }
 630
 631                led->num_leds = fwnode_property_count_u32(child, "led-sources");
 632                if (led->num_leds > LM3532_MAX_LED_STRINGS) {
 633                        dev_err(&priv->client->dev, "Too many LED string defined\n");
 634                        continue;
 635                }
 636
 637                ret = fwnode_property_read_u32_array(child, "led-sources",
 638                                                    led->led_strings,
 639                                                    led->num_leds);
 640                if (ret) {
 641                        dev_err(&priv->client->dev, "led-sources property missing\n");
 642                        fwnode_handle_put(child);
 643                        goto child_out;
 644                }
 645
 646                fwnode_property_read_string(child, "linux,default-trigger",
 647                                            &led->led_dev.default_trigger);
 648
 649                ret = fwnode_property_read_string(child, "label", &name);
 650                if (ret)
 651                        snprintf(led->label, sizeof(led->label),
 652                                "%s::", priv->client->name);
 653                else
 654                        snprintf(led->label, sizeof(led->label),
 655                                 "%s:%s", priv->client->name, name);
 656
 657                led->priv = priv;
 658                led->led_dev.name = led->label;
 659                led->led_dev.brightness_set_blocking = lm3532_brightness_set;
 660
 661                ret = devm_led_classdev_register_ext(priv->dev, &led->led_dev, &idata);
 662                if (ret) {
 663                        dev_err(&priv->client->dev, "led register err: %d\n",
 664                                ret);
 665                        fwnode_handle_put(child);
 666                        goto child_out;
 667                }
 668
 669                ret = lm3532_init_registers(led);
 670                if (ret) {
 671                        dev_err(&priv->client->dev, "register init err: %d\n",
 672                                ret);
 673                        fwnode_handle_put(child);
 674                        goto child_out;
 675                }
 676
 677                i++;
 678        }
 679
 680child_out:
 681        return ret;
 682}
 683
 684static int lm3532_probe(struct i2c_client *client,
 685                           const struct i2c_device_id *id)
 686{
 687        struct lm3532_data *drvdata;
 688        int ret = 0;
 689        int count;
 690
 691        count = device_get_child_node_count(&client->dev);
 692        if (!count) {
 693                dev_err(&client->dev, "LEDs are not defined in device tree!");
 694                return -ENODEV;
 695        }
 696
 697        drvdata = devm_kzalloc(&client->dev, struct_size(drvdata, leds, count),
 698                           GFP_KERNEL);
 699        if (drvdata == NULL)
 700                return -ENOMEM;
 701
 702        drvdata->client = client;
 703        drvdata->dev = &client->dev;
 704
 705        drvdata->regmap = devm_regmap_init_i2c(client, &lm3532_regmap_config);
 706        if (IS_ERR(drvdata->regmap)) {
 707                ret = PTR_ERR(drvdata->regmap);
 708                dev_err(&client->dev, "Failed to allocate register map: %d\n",
 709                        ret);
 710                return ret;
 711        }
 712
 713        mutex_init(&drvdata->lock);
 714        i2c_set_clientdata(client, drvdata);
 715
 716        ret = lm3532_parse_node(drvdata);
 717        if (ret) {
 718                dev_err(&client->dev, "Failed to parse node\n");
 719                return ret;
 720        }
 721
 722        return ret;
 723}
 724
 725static int lm3532_remove(struct i2c_client *client)
 726{
 727        struct lm3532_data *drvdata = i2c_get_clientdata(client);
 728
 729        mutex_destroy(&drvdata->lock);
 730
 731        if (drvdata->enable_gpio)
 732                gpiod_direction_output(drvdata->enable_gpio, 0);
 733
 734        return 0;
 735}
 736
 737static const struct of_device_id of_lm3532_leds_match[] = {
 738        { .compatible = "ti,lm3532", },
 739        {},
 740};
 741MODULE_DEVICE_TABLE(of, of_lm3532_leds_match);
 742
 743static const struct i2c_device_id lm3532_id[] = {
 744        {LM3532_NAME, 0},
 745        {}
 746};
 747MODULE_DEVICE_TABLE(i2c, lm3532_id);
 748
 749static struct i2c_driver lm3532_i2c_driver = {
 750        .probe = lm3532_probe,
 751        .remove = lm3532_remove,
 752        .id_table = lm3532_id,
 753        .driver = {
 754                .name = LM3532_NAME,
 755                .of_match_table = of_lm3532_leds_match,
 756        },
 757};
 758module_i2c_driver(lm3532_i2c_driver);
 759
 760MODULE_DESCRIPTION("Back Light driver for LM3532");
 761MODULE_LICENSE("GPL v2");
 762MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
 763