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