1 /* 2 * TI LP8860 4-Channel LED Driver 3 * 4 * Copyright (C) 2014 Texas Instruments 5 * 6 * Author: Dan Murphy <dmurphy@ti.com> 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License 10 * version 2 as published by the Free Software Foundation. 11 * 12 */ 13 14 #include <linux/i2c.h> 15 #include <linux/init.h> 16 #include <linux/leds.h> 17 #include <linux/regmap.h> 18 #include <linux/regulator/consumer.h> 19 #include <linux/module.h> 20 #include <linux/mutex.h> 21 #include <linux/of.h> 22 #include <linux/of_gpio.h> 23 #include <linux/gpio/consumer.h> 24 #include <linux/slab.h> 25 #include <uapi/linux/uleds.h> 26 27 #define LP8860_DISP_CL1_BRT_MSB 0x00 28 #define LP8860_DISP_CL1_BRT_LSB 0x01 29 #define LP8860_DISP_CL1_CURR_MSB 0x02 30 #define LP8860_DISP_CL1_CURR_LSB 0x03 31 #define LP8860_CL2_BRT_MSB 0x04 32 #define LP8860_CL2_BRT_LSB 0x05 33 #define LP8860_CL2_CURRENT 0x06 34 #define LP8860_CL3_BRT_MSB 0x07 35 #define LP8860_CL3_BRT_LSB 0x08 36 #define LP8860_CL3_CURRENT 0x09 37 #define LP8860_CL4_BRT_MSB 0x0a 38 #define LP8860_CL4_BRT_LSB 0x0b 39 #define LP8860_CL4_CURRENT 0x0c 40 #define LP8860_CONFIG 0x0d 41 #define LP8860_STATUS 0x0e 42 #define LP8860_FAULT 0x0f 43 #define LP8860_LED_FAULT 0x10 44 #define LP8860_FAULT_CLEAR 0x11 45 #define LP8860_ID 0x12 46 #define LP8860_TEMP_MSB 0x13 47 #define LP8860_TEMP_LSB 0x14 48 #define LP8860_DISP_LED_CURR_MSB 0x15 49 #define LP8860_DISP_LED_CURR_LSB 0x16 50 #define LP8860_DISP_LED_PWM_MSB 0x17 51 #define LP8860_DISP_LED_PWM_LSB 0x18 52 #define LP8860_EEPROM_CNTRL 0x19 53 #define LP8860_EEPROM_UNLOCK 0x1a 54 55 #define LP8860_EEPROM_REG_0 0x60 56 #define LP8860_EEPROM_REG_1 0x61 57 #define LP8860_EEPROM_REG_2 0x62 58 #define LP8860_EEPROM_REG_3 0x63 59 #define LP8860_EEPROM_REG_4 0x64 60 #define LP8860_EEPROM_REG_5 0x65 61 #define LP8860_EEPROM_REG_6 0x66 62 #define LP8860_EEPROM_REG_7 0x67 63 #define LP8860_EEPROM_REG_8 0x68 64 #define LP8860_EEPROM_REG_9 0x69 65 #define LP8860_EEPROM_REG_10 0x6a 66 #define LP8860_EEPROM_REG_11 0x6b 67 #define LP8860_EEPROM_REG_12 0x6c 68 #define LP8860_EEPROM_REG_13 0x6d 69 #define LP8860_EEPROM_REG_14 0x6e 70 #define LP8860_EEPROM_REG_15 0x6f 71 #define LP8860_EEPROM_REG_16 0x70 72 #define LP8860_EEPROM_REG_17 0x71 73 #define LP8860_EEPROM_REG_18 0x72 74 #define LP8860_EEPROM_REG_19 0x73 75 #define LP8860_EEPROM_REG_20 0x74 76 #define LP8860_EEPROM_REG_21 0x75 77 #define LP8860_EEPROM_REG_22 0x76 78 #define LP8860_EEPROM_REG_23 0x77 79 #define LP8860_EEPROM_REG_24 0x78 80 81 #define LP8860_LOCK_EEPROM 0x00 82 #define LP8860_UNLOCK_EEPROM 0x01 83 #define LP8860_PROGRAM_EEPROM 0x02 84 #define LP8860_EEPROM_CODE_1 0x08 85 #define LP8860_EEPROM_CODE_2 0xba 86 #define LP8860_EEPROM_CODE_3 0xef 87 88 #define LP8860_CLEAR_FAULTS 0x01 89 90 /** 91 * struct lp8860_led - 92 * @lock - Lock for reading/writing the device 93 * @client - Pointer to the I2C client 94 * @led_dev - led class device pointer 95 * @regmap - Devices register map 96 * @eeprom_regmap - EEPROM register map 97 * @enable_gpio - VDDIO/EN gpio to enable communication interface 98 * @regulator - LED supply regulator pointer 99 * @label - LED label 100 */ 101 struct lp8860_led { 102 struct mutex lock; 103 struct i2c_client *client; 104 struct led_classdev led_dev; 105 struct regmap *regmap; 106 struct regmap *eeprom_regmap; 107 struct gpio_desc *enable_gpio; 108 struct regulator *regulator; 109 char label[LED_MAX_NAME_SIZE]; 110 }; 111 112 struct lp8860_eeprom_reg { 113 uint8_t reg; 114 uint8_t value; 115 }; 116 117 static struct lp8860_eeprom_reg lp8860_eeprom_disp_regs[] = { 118 { LP8860_EEPROM_REG_0, 0xed }, 119 { LP8860_EEPROM_REG_1, 0xdf }, 120 { LP8860_EEPROM_REG_2, 0xdc }, 121 { LP8860_EEPROM_REG_3, 0xf0 }, 122 { LP8860_EEPROM_REG_4, 0xdf }, 123 { LP8860_EEPROM_REG_5, 0xe5 }, 124 { LP8860_EEPROM_REG_6, 0xf2 }, 125 { LP8860_EEPROM_REG_7, 0x77 }, 126 { LP8860_EEPROM_REG_8, 0x77 }, 127 { LP8860_EEPROM_REG_9, 0x71 }, 128 { LP8860_EEPROM_REG_10, 0x3f }, 129 { LP8860_EEPROM_REG_11, 0xb7 }, 130 { LP8860_EEPROM_REG_12, 0x17 }, 131 { LP8860_EEPROM_REG_13, 0xef }, 132 { LP8860_EEPROM_REG_14, 0xb0 }, 133 { LP8860_EEPROM_REG_15, 0x87 }, 134 { LP8860_EEPROM_REG_16, 0xce }, 135 { LP8860_EEPROM_REG_17, 0x72 }, 136 { LP8860_EEPROM_REG_18, 0xe5 }, 137 { LP8860_EEPROM_REG_19, 0xdf }, 138 { LP8860_EEPROM_REG_20, 0x35 }, 139 { LP8860_EEPROM_REG_21, 0x06 }, 140 { LP8860_EEPROM_REG_22, 0xdc }, 141 { LP8860_EEPROM_REG_23, 0x88 }, 142 { LP8860_EEPROM_REG_24, 0x3E }, 143 }; 144 145 static int lp8860_unlock_eeprom(struct lp8860_led *led, int lock) 146 { 147 int ret; 148 149 mutex_lock(&led->lock); 150 151 if (lock == LP8860_UNLOCK_EEPROM) { 152 ret = regmap_write(led->regmap, 153 LP8860_EEPROM_UNLOCK, 154 LP8860_EEPROM_CODE_1); 155 if (ret) { 156 dev_err(&led->client->dev, "EEPROM Unlock failed\n"); 157 goto out; 158 } 159 160 ret = regmap_write(led->regmap, 161 LP8860_EEPROM_UNLOCK, 162 LP8860_EEPROM_CODE_2); 163 if (ret) { 164 dev_err(&led->client->dev, "EEPROM Unlock failed\n"); 165 goto out; 166 } 167 ret = regmap_write(led->regmap, 168 LP8860_EEPROM_UNLOCK, 169 LP8860_EEPROM_CODE_3); 170 if (ret) { 171 dev_err(&led->client->dev, "EEPROM Unlock failed\n"); 172 goto out; 173 } 174 } else { 175 ret = regmap_write(led->regmap, 176 LP8860_EEPROM_UNLOCK, 177 LP8860_LOCK_EEPROM); 178 } 179 180 out: 181 mutex_unlock(&led->lock); 182 return ret; 183 } 184 185 static int lp8860_fault_check(struct lp8860_led *led) 186 { 187 int ret, fault; 188 unsigned int read_buf; 189 190 ret = regmap_read(led->regmap, LP8860_LED_FAULT, &read_buf); 191 if (ret) 192 goto out; 193 194 fault = read_buf; 195 196 ret = regmap_read(led->regmap, LP8860_FAULT, &read_buf); 197 if (ret) 198 goto out; 199 200 fault |= read_buf; 201 202 /* Attempt to clear any faults */ 203 if (fault) 204 ret = regmap_write(led->regmap, LP8860_FAULT_CLEAR, 205 LP8860_CLEAR_FAULTS); 206 out: 207 return ret; 208 } 209 210 static int lp8860_brightness_set(struct led_classdev *led_cdev, 211 enum led_brightness brt_val) 212 { 213 struct lp8860_led *led = 214 container_of(led_cdev, struct lp8860_led, led_dev); 215 int disp_brightness = brt_val * 255; 216 int ret; 217 218 mutex_lock(&led->lock); 219 220 ret = lp8860_fault_check(led); 221 if (ret) { 222 dev_err(&led->client->dev, "Cannot read/clear faults\n"); 223 goto out; 224 } 225 226 ret = regmap_write(led->regmap, LP8860_DISP_CL1_BRT_MSB, 227 (disp_brightness & 0xff00) >> 8); 228 if (ret) { 229 dev_err(&led->client->dev, "Cannot write CL1 MSB\n"); 230 goto out; 231 } 232 233 ret = regmap_write(led->regmap, LP8860_DISP_CL1_BRT_LSB, 234 disp_brightness & 0xff); 235 if (ret) { 236 dev_err(&led->client->dev, "Cannot write CL1 LSB\n"); 237 goto out; 238 } 239 out: 240 mutex_unlock(&led->lock); 241 return ret; 242 } 243 244 static int lp8860_init(struct lp8860_led *led) 245 { 246 unsigned int read_buf; 247 int ret, i, reg_count; 248 249 if (led->regulator) { 250 ret = regulator_enable(led->regulator); 251 if (ret) { 252 dev_err(&led->client->dev, 253 "Failed to enable regulator\n"); 254 return ret; 255 } 256 } 257 258 if (led->enable_gpio) 259 gpiod_direction_output(led->enable_gpio, 1); 260 261 ret = lp8860_fault_check(led); 262 if (ret) 263 goto out; 264 265 ret = regmap_read(led->regmap, LP8860_STATUS, &read_buf); 266 if (ret) 267 goto out; 268 269 ret = lp8860_unlock_eeprom(led, LP8860_UNLOCK_EEPROM); 270 if (ret) { 271 dev_err(&led->client->dev, "Failed unlocking EEPROM\n"); 272 goto out; 273 } 274 275 reg_count = ARRAY_SIZE(lp8860_eeprom_disp_regs) / sizeof(lp8860_eeprom_disp_regs[0]); 276 for (i = 0; i < reg_count; i++) { 277 ret = regmap_write(led->eeprom_regmap, 278 lp8860_eeprom_disp_regs[i].reg, 279 lp8860_eeprom_disp_regs[i].value); 280 if (ret) { 281 dev_err(&led->client->dev, "Failed writing EEPROM\n"); 282 goto out; 283 } 284 } 285 286 ret = lp8860_unlock_eeprom(led, LP8860_LOCK_EEPROM); 287 if (ret) 288 goto out; 289 290 ret = regmap_write(led->regmap, 291 LP8860_EEPROM_CNTRL, 292 LP8860_PROGRAM_EEPROM); 293 if (ret) { 294 dev_err(&led->client->dev, "Failed programming EEPROM\n"); 295 goto out; 296 } 297 298 return ret; 299 300 out: 301 if (ret) 302 if (led->enable_gpio) 303 gpiod_direction_output(led->enable_gpio, 0); 304 305 if (led->regulator) { 306 ret = regulator_disable(led->regulator); 307 if (ret) 308 dev_err(&led->client->dev, 309 "Failed to disable regulator\n"); 310 } 311 312 return ret; 313 } 314 315 static const struct reg_default lp8860_reg_defs[] = { 316 { LP8860_DISP_CL1_BRT_MSB, 0x00}, 317 { LP8860_DISP_CL1_BRT_LSB, 0x00}, 318 { LP8860_DISP_CL1_CURR_MSB, 0x00}, 319 { LP8860_DISP_CL1_CURR_LSB, 0x00}, 320 { LP8860_CL2_BRT_MSB, 0x00}, 321 { LP8860_CL2_BRT_LSB, 0x00}, 322 { LP8860_CL2_CURRENT, 0x00}, 323 { LP8860_CL3_BRT_MSB, 0x00}, 324 { LP8860_CL3_BRT_LSB, 0x00}, 325 { LP8860_CL3_CURRENT, 0x00}, 326 { LP8860_CL4_BRT_MSB, 0x00}, 327 { LP8860_CL4_BRT_LSB, 0x00}, 328 { LP8860_CL4_CURRENT, 0x00}, 329 { LP8860_CONFIG, 0x00}, 330 { LP8860_FAULT_CLEAR, 0x00}, 331 { LP8860_EEPROM_CNTRL, 0x80}, 332 { LP8860_EEPROM_UNLOCK, 0x00}, 333 }; 334 335 static const struct regmap_config lp8860_regmap_config = { 336 .reg_bits = 8, 337 .val_bits = 8, 338 339 .max_register = LP8860_EEPROM_UNLOCK, 340 .reg_defaults = lp8860_reg_defs, 341 .num_reg_defaults = ARRAY_SIZE(lp8860_reg_defs), 342 .cache_type = REGCACHE_NONE, 343 }; 344 345 static const struct reg_default lp8860_eeprom_defs[] = { 346 { LP8860_EEPROM_REG_0, 0x00 }, 347 { LP8860_EEPROM_REG_1, 0x00 }, 348 { LP8860_EEPROM_REG_2, 0x00 }, 349 { LP8860_EEPROM_REG_3, 0x00 }, 350 { LP8860_EEPROM_REG_4, 0x00 }, 351 { LP8860_EEPROM_REG_5, 0x00 }, 352 { LP8860_EEPROM_REG_6, 0x00 }, 353 { LP8860_EEPROM_REG_7, 0x00 }, 354 { LP8860_EEPROM_REG_8, 0x00 }, 355 { LP8860_EEPROM_REG_9, 0x00 }, 356 { LP8860_EEPROM_REG_10, 0x00 }, 357 { LP8860_EEPROM_REG_11, 0x00 }, 358 { LP8860_EEPROM_REG_12, 0x00 }, 359 { LP8860_EEPROM_REG_13, 0x00 }, 360 { LP8860_EEPROM_REG_14, 0x00 }, 361 { LP8860_EEPROM_REG_15, 0x00 }, 362 { LP8860_EEPROM_REG_16, 0x00 }, 363 { LP8860_EEPROM_REG_17, 0x00 }, 364 { LP8860_EEPROM_REG_18, 0x00 }, 365 { LP8860_EEPROM_REG_19, 0x00 }, 366 { LP8860_EEPROM_REG_20, 0x00 }, 367 { LP8860_EEPROM_REG_21, 0x00 }, 368 { LP8860_EEPROM_REG_22, 0x00 }, 369 { LP8860_EEPROM_REG_23, 0x00 }, 370 { LP8860_EEPROM_REG_24, 0x00 }, 371 }; 372 373 static const struct regmap_config lp8860_eeprom_regmap_config = { 374 .reg_bits = 8, 375 .val_bits = 8, 376 377 .max_register = LP8860_EEPROM_REG_24, 378 .reg_defaults = lp8860_eeprom_defs, 379 .num_reg_defaults = ARRAY_SIZE(lp8860_eeprom_defs), 380 .cache_type = REGCACHE_NONE, 381 }; 382 383 static int lp8860_probe(struct i2c_client *client, 384 const struct i2c_device_id *id) 385 { 386 int ret; 387 struct lp8860_led *led; 388 struct device_node *np = client->dev.of_node; 389 struct device_node *child_node; 390 const char *name; 391 392 led = devm_kzalloc(&client->dev, sizeof(*led), GFP_KERNEL); 393 if (!led) 394 return -ENOMEM; 395 396 for_each_available_child_of_node(np, child_node) { 397 led->led_dev.default_trigger = of_get_property(child_node, 398 "linux,default-trigger", 399 NULL); 400 401 ret = of_property_read_string(child_node, "label", &name); 402 if (!ret) 403 snprintf(led->label, sizeof(led->label), "%s:%s", 404 id->name, name); 405 else 406 snprintf(led->label, sizeof(led->label), 407 "%s::display_cluster", id->name); 408 } 409 410 led->enable_gpio = devm_gpiod_get_optional(&client->dev, 411 "enable", GPIOD_OUT_LOW); 412 if (IS_ERR(led->enable_gpio)) { 413 ret = PTR_ERR(led->enable_gpio); 414 dev_err(&client->dev, "Failed to get enable gpio: %d\n", ret); 415 return ret; 416 } 417 418 led->regulator = devm_regulator_get(&client->dev, "vled"); 419 if (IS_ERR(led->regulator)) 420 led->regulator = NULL; 421 422 led->client = client; 423 led->led_dev.name = led->label; 424 led->led_dev.brightness_set_blocking = lp8860_brightness_set; 425 426 mutex_init(&led->lock); 427 428 i2c_set_clientdata(client, led); 429 430 led->regmap = devm_regmap_init_i2c(client, &lp8860_regmap_config); 431 if (IS_ERR(led->regmap)) { 432 ret = PTR_ERR(led->regmap); 433 dev_err(&client->dev, "Failed to allocate register map: %d\n", 434 ret); 435 return ret; 436 } 437 438 led->eeprom_regmap = devm_regmap_init_i2c(client, &lp8860_eeprom_regmap_config); 439 if (IS_ERR(led->eeprom_regmap)) { 440 ret = PTR_ERR(led->eeprom_regmap); 441 dev_err(&client->dev, "Failed to allocate register map: %d\n", 442 ret); 443 return ret; 444 } 445 446 ret = lp8860_init(led); 447 if (ret) 448 return ret; 449 450 ret = devm_led_classdev_register(&client->dev, &led->led_dev); 451 if (ret) { 452 dev_err(&client->dev, "led register err: %d\n", ret); 453 return ret; 454 } 455 456 return 0; 457 } 458 459 static int lp8860_remove(struct i2c_client *client) 460 { 461 struct lp8860_led *led = i2c_get_clientdata(client); 462 int ret; 463 464 if (led->enable_gpio) 465 gpiod_direction_output(led->enable_gpio, 0); 466 467 if (led->regulator) { 468 ret = regulator_disable(led->regulator); 469 if (ret) 470 dev_err(&led->client->dev, 471 "Failed to disable regulator\n"); 472 } 473 474 mutex_destroy(&led->lock); 475 476 return 0; 477 } 478 479 static const struct i2c_device_id lp8860_id[] = { 480 { "lp8860", 0 }, 481 { } 482 }; 483 MODULE_DEVICE_TABLE(i2c, lp8860_id); 484 485 static const struct of_device_id of_lp8860_leds_match[] = { 486 { .compatible = "ti,lp8860", }, 487 {}, 488 }; 489 MODULE_DEVICE_TABLE(of, of_lp8860_leds_match); 490 491 static struct i2c_driver lp8860_driver = { 492 .driver = { 493 .name = "lp8860", 494 .of_match_table = of_lp8860_leds_match, 495 }, 496 .probe = lp8860_probe, 497 .remove = lp8860_remove, 498 .id_table = lp8860_id, 499 }; 500 module_i2c_driver(lp8860_driver); 501 502 MODULE_DESCRIPTION("Texas Instruments LP8860 LED driver"); 503 MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>"); 504 MODULE_LICENSE("GPL v2"); 505