747 lines · c
1// SPDX-License-Identifier: GPL-2.02// TI LM3532 LED driver3// Copyright (C) 2019 Texas Instruments Incorporated - https://www.ti.com/4// https://www.ti.com/lit/ds/symlink/lm3532.pdf5 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 0x0018#define LM3532_BL_MODE_ALS 0x0119 20#define LM3532_REG_OUTPUT_CFG 0x1021#define LM3532_REG_STARTSHUT_RAMP 0x1122#define LM3532_REG_RT_RAMP 0x1223#define LM3532_REG_PWM_A_CFG 0x1324#define LM3532_REG_PWM_B_CFG 0x1425#define LM3532_REG_PWM_C_CFG 0x1526#define LM3532_REG_ZONE_CFG_A 0x1627#define LM3532_REG_CTRL_A_FS_CURR 0x1728#define LM3532_REG_ZONE_CFG_B 0x1829#define LM3532_REG_CTRL_B_FS_CURR 0x1930#define LM3532_REG_ZONE_CFG_C 0x1a31#define LM3532_REG_CTRL_C_FS_CURR 0x1b32#define LM3532_REG_ENABLE 0x1d33#define LM3532_ALS_CONFIG 0x2334#define LM3532_REG_ZN_0_HI 0x6035#define LM3532_REG_ZN_0_LO 0x6136#define LM3532_REG_ZN_1_HI 0x6237#define LM3532_REG_ZN_1_LO 0x6338#define LM3532_REG_ZN_2_HI 0x6439#define LM3532_REG_ZN_2_LO 0x6540#define LM3532_REG_ZN_3_HI 0x6641#define LM3532_REG_ZN_3_LO 0x6742#define LM3532_REG_ZONE_TRGT_A 0x7043#define LM3532_REG_ZONE_TRGT_B 0x7544#define LM3532_REG_ZONE_TRGT_C 0x7a45#define LM3532_REG_MAX 0x7e46 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 0x7c54#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 063#define LM3532_LINEAR_MAP BIT(1)64#define LM3532_ZONE_MASK (BIT(2) | BIT(3) | BIT(4))65#define LM3532_ZONE_0 066#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 673 74/* Zone Boundary Register */75#define LM3532_ALS_WINDOW_mV 200076#define LM3532_ALS_ZB_MAX 477#define LM3532_ALS_OFFSET_mV 278 79#define LM3532_CONTROL_A 080#define LM3532_CONTROL_B 181#define LM3532_CONTROL_C 282#define LM3532_MAX_CONTROL_BANKS 383#define LM3532_MAX_LED_STRINGS 384 85#define LM3532_OUTPUT_CFG_MASK 0x386#define LM3532_BRT_VAL_ADJUST 887#define LM3532_RAMP_DOWN_SHIFT 388 89#define LM3532_NUM_RAMP_VALS 890#define LM3532_NUM_AVG_VALS 891#define LM3532_NUM_IMP_VALS 3292 93#define LM3532_FS_CURR_MIN 500094#define LM3532_FS_CURR_MAX 2980095#define LM3532_FS_CURR_STEP 80096 97/*98 * struct lm3532_als_data99 * @config: value of ALS configuration register100 * @als1_imp_sel: value of ALS1 resistor select register101 * @als2_imp_sel: value of ALS2 resistor select register102 * @als_avrg_time: ALS averaging time103 * @als_input_mode: ALS input mode for brightness control104 * @als_vmin: Minimum ALS voltage105 * @als_vmax: Maximum ALS voltage106 * @zone_lo: values of ALS lo ZB(Zone Boundary) registers107 * @zone_hi: values of ALS hi ZB(Zone Boundary) registers108 */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_led123 * @led_dev: led class device124 * @priv: Pointer the device data structure125 * @control_bank: Control bank the LED is associated to126 * @mode: Mode of the LED string127 * @ctrl_brt_pointer: Zone target register that controls the sink128 * @num_leds: Number of LED strings are supported in this array129 * @full_scale_current: The full-scale current setting for the current sink.130 * @led_strings: The LED strings supported in this array131 * @enabled: Enabled status132 */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_data148 * @enable_gpio: Hardware enable gpio149 * @regulator: regulator150 * @client: i2c client151 * @regmap: Devices register map152 * @dev: Pointer to the devices device struct153 * @lock: Lock for reading/writing the device154 * @als_data: Pointer to the als data struct155 * @runtime_ramp_up: Runtime ramp up setting156 * @runtime_ramp_down: Runtime ramp down setting157 * @leds: Array of LED strings158 */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 else239 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 else260 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 else360 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 control403 * 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 else514 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 else521 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 else528 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 void gpio_set_low_action(void *data)546{547 struct lm3532_data *priv = data;548 549 gpiod_direction_output(priv->enable_gpio, 0);550}551 552static int lm3532_parse_node(struct lm3532_data *priv)553{554 struct fwnode_handle *child = NULL;555 struct lm3532_led *led;556 int control_bank;557 u32 ramp_time;558 size_t i = 0;559 int ret;560 561 priv->enable_gpio = devm_gpiod_get_optional(&priv->client->dev,562 "enable", GPIOD_OUT_LOW);563 if (IS_ERR(priv->enable_gpio))564 priv->enable_gpio = NULL;565 566 if (priv->enable_gpio) {567 ret = devm_add_action(&priv->client->dev, gpio_set_low_action, priv);568 if (ret)569 return ret;570 }571 572 priv->regulator = devm_regulator_get(&priv->client->dev, "vin");573 if (IS_ERR(priv->regulator))574 priv->regulator = NULL;575 576 ret = device_property_read_u32(&priv->client->dev, "ramp-up-us",577 &ramp_time);578 if (ret)579 dev_info(&priv->client->dev, "ramp-up-ms property missing\n");580 else581 priv->runtime_ramp_up = lm3532_get_ramp_index(ramp_time);582 583 ret = device_property_read_u32(&priv->client->dev, "ramp-down-us",584 &ramp_time);585 if (ret)586 dev_info(&priv->client->dev, "ramp-down-ms property missing\n");587 else588 priv->runtime_ramp_down = lm3532_get_ramp_index(ramp_time);589 590 device_for_each_child_node(priv->dev, child) {591 struct led_init_data idata = {592 .fwnode = child,593 .default_label = ":",594 .devicename = priv->client->name,595 };596 597 led = &priv->leds[i];598 599 ret = fwnode_property_read_u32(child, "reg", &control_bank);600 if (ret) {601 dev_err(&priv->client->dev, "reg property missing\n");602 goto child_out;603 }604 605 if (control_bank > LM3532_CONTROL_C) {606 dev_err(&priv->client->dev, "Control bank invalid\n");607 continue;608 }609 610 led->control_bank = control_bank;611 612 ret = fwnode_property_read_u32(child, "ti,led-mode",613 &led->mode);614 if (ret) {615 dev_err(&priv->client->dev, "ti,led-mode property missing\n");616 goto child_out;617 }618 619 if (fwnode_property_present(child, "led-max-microamp") &&620 fwnode_property_read_u32(child, "led-max-microamp",621 &led->full_scale_current))622 dev_err(&priv->client->dev,623 "Failed getting led-max-microamp\n");624 else625 led->full_scale_current = min(led->full_scale_current,626 LM3532_FS_CURR_MAX);627 628 if (led->mode == LM3532_BL_MODE_ALS) {629 led->mode = LM3532_ALS_CTRL;630 ret = lm3532_parse_als(priv);631 if (ret)632 dev_err(&priv->client->dev, "Failed to parse als\n");633 else634 lm3532_als_configure(priv, led);635 } else {636 led->mode = LM3532_I2C_CTRL;637 }638 639 led->num_leds = fwnode_property_count_u32(child, "led-sources");640 if (led->num_leds > LM3532_MAX_LED_STRINGS) {641 dev_err(&priv->client->dev, "Too many LED string defined\n");642 continue;643 }644 645 ret = fwnode_property_read_u32_array(child, "led-sources",646 led->led_strings,647 led->num_leds);648 if (ret) {649 dev_err(&priv->client->dev, "led-sources property missing\n");650 goto child_out;651 }652 653 led->priv = priv;654 led->led_dev.brightness_set_blocking = lm3532_brightness_set;655 656 ret = devm_led_classdev_register_ext(priv->dev, &led->led_dev, &idata);657 if (ret) {658 dev_err(&priv->client->dev, "led register err: %d\n",659 ret);660 goto child_out;661 }662 663 ret = lm3532_init_registers(led);664 if (ret) {665 dev_err(&priv->client->dev, "register init err: %d\n",666 ret);667 goto child_out;668 }669 670 i++;671 }672 return 0;673 674child_out:675 fwnode_handle_put(child);676 return ret;677}678 679static int lm3532_probe(struct i2c_client *client)680{681 struct lm3532_data *drvdata;682 int ret = 0;683 int count;684 685 count = device_get_child_node_count(&client->dev);686 if (!count) {687 dev_err(&client->dev, "LEDs are not defined in device tree!");688 return -ENODEV;689 }690 691 drvdata = devm_kzalloc(&client->dev, struct_size(drvdata, leds, count),692 GFP_KERNEL);693 if (drvdata == NULL)694 return -ENOMEM;695 696 drvdata->client = client;697 drvdata->dev = &client->dev;698 699 drvdata->regmap = devm_regmap_init_i2c(client, &lm3532_regmap_config);700 if (IS_ERR(drvdata->regmap)) {701 ret = PTR_ERR(drvdata->regmap);702 dev_err(&client->dev, "Failed to allocate register map: %d\n",703 ret);704 return ret;705 }706 707 ret = devm_mutex_init(&client->dev, &drvdata->lock);708 if (ret)709 return ret;710 711 i2c_set_clientdata(client, drvdata);712 713 ret = lm3532_parse_node(drvdata);714 if (ret) {715 dev_err(&client->dev, "Failed to parse node\n");716 return ret;717 }718 719 return ret;720}721 722static const struct of_device_id of_lm3532_leds_match[] = {723 { .compatible = "ti,lm3532", },724 {},725};726MODULE_DEVICE_TABLE(of, of_lm3532_leds_match);727 728static const struct i2c_device_id lm3532_id[] = {729 { LM3532_NAME },730 {}731};732MODULE_DEVICE_TABLE(i2c, lm3532_id);733 734static struct i2c_driver lm3532_i2c_driver = {735 .probe = lm3532_probe,736 .id_table = lm3532_id,737 .driver = {738 .name = LM3532_NAME,739 .of_match_table = of_lm3532_leds_match,740 },741};742module_i2c_driver(lm3532_i2c_driver);743 744MODULE_DESCRIPTION("Back Light driver for LM3532");745MODULE_LICENSE("GPL v2");746MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");747