1 /* 2 * Simple driver for Texas Instruments LM3630A Backlight driver chip 3 * Copyright (C) 2012 Texas Instruments 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 */ 10 #include <linux/module.h> 11 #include <linux/slab.h> 12 #include <linux/i2c.h> 13 #include <linux/backlight.h> 14 #include <linux/err.h> 15 #include <linux/delay.h> 16 #include <linux/uaccess.h> 17 #include <linux/interrupt.h> 18 #include <linux/regmap.h> 19 #include <linux/pwm.h> 20 #include <linux/platform_data/lm3630a_bl.h> 21 22 #define REG_CTRL 0x00 23 #define REG_BOOST 0x02 24 #define REG_CONFIG 0x01 25 #define REG_BRT_A 0x03 26 #define REG_BRT_B 0x04 27 #define REG_I_A 0x05 28 #define REG_I_B 0x06 29 #define REG_INT_STATUS 0x09 30 #define REG_INT_EN 0x0A 31 #define REG_FAULT 0x0B 32 #define REG_PWM_OUTLOW 0x12 33 #define REG_PWM_OUTHIGH 0x13 34 #define REG_FILTER_STRENGTH 0x50 35 #define REG_MAX 0x50 36 37 #define INT_DEBOUNCE_MSEC 10 38 39 #define LM3630A_BANK_0 0 40 #define LM3630A_BANK_1 1 41 42 #define LM3630A_NUM_SINKS 2 43 #define LM3630A_SINK_0 0 44 #define LM3630A_SINK_1 1 45 46 struct lm3630a_chip { 47 struct device *dev; 48 struct delayed_work work; 49 50 int irq; 51 struct workqueue_struct *irqthread; 52 struct lm3630a_platform_data *pdata; 53 struct backlight_device *bleda; 54 struct backlight_device *bledb; 55 struct regmap *regmap; 56 struct pwm_device *pwmd; 57 }; 58 59 /* i2c access */ 60 static int lm3630a_read(struct lm3630a_chip *pchip, unsigned int reg) 61 { 62 int rval; 63 unsigned int reg_val; 64 65 rval = regmap_read(pchip->regmap, reg, ®_val); 66 if (rval < 0) 67 return rval; 68 return reg_val & 0xFF; 69 } 70 71 static int lm3630a_write(struct lm3630a_chip *pchip, 72 unsigned int reg, unsigned int data) 73 { 74 return regmap_write(pchip->regmap, reg, data); 75 } 76 77 static int lm3630a_update(struct lm3630a_chip *pchip, 78 unsigned int reg, unsigned int mask, 79 unsigned int data) 80 { 81 return regmap_update_bits(pchip->regmap, reg, mask, data); 82 } 83 84 /* initialize chip */ 85 static int lm3630a_chip_init(struct lm3630a_chip *pchip) 86 { 87 int rval; 88 struct lm3630a_platform_data *pdata = pchip->pdata; 89 90 usleep_range(1000, 2000); 91 /* set Filter Strength Register */ 92 rval = lm3630a_write(pchip, REG_FILTER_STRENGTH, 0x03); 93 /* set Cofig. register */ 94 rval |= lm3630a_update(pchip, REG_CONFIG, 0x07, pdata->pwm_ctrl); 95 /* set boost control */ 96 rval |= lm3630a_write(pchip, REG_BOOST, 0x38); 97 /* set current A */ 98 rval |= lm3630a_update(pchip, REG_I_A, 0x1F, 0x1F); 99 /* set current B */ 100 rval |= lm3630a_write(pchip, REG_I_B, 0x1F); 101 /* set control */ 102 rval |= lm3630a_update(pchip, REG_CTRL, 0x14, pdata->leda_ctrl); 103 rval |= lm3630a_update(pchip, REG_CTRL, 0x0B, pdata->ledb_ctrl); 104 usleep_range(1000, 2000); 105 /* set brightness A and B */ 106 rval |= lm3630a_write(pchip, REG_BRT_A, pdata->leda_init_brt); 107 rval |= lm3630a_write(pchip, REG_BRT_B, pdata->ledb_init_brt); 108 109 if (rval < 0) 110 dev_err(pchip->dev, "i2c failed to access register\n"); 111 return rval; 112 } 113 114 /* interrupt handling */ 115 static void lm3630a_delayed_func(struct work_struct *work) 116 { 117 int rval; 118 struct lm3630a_chip *pchip; 119 120 pchip = container_of(work, struct lm3630a_chip, work.work); 121 122 rval = lm3630a_read(pchip, REG_INT_STATUS); 123 if (rval < 0) { 124 dev_err(pchip->dev, 125 "i2c failed to access REG_INT_STATUS Register\n"); 126 return; 127 } 128 129 dev_info(pchip->dev, "REG_INT_STATUS Register is 0x%x\n", rval); 130 } 131 132 static irqreturn_t lm3630a_isr_func(int irq, void *chip) 133 { 134 int rval; 135 struct lm3630a_chip *pchip = chip; 136 unsigned long delay = msecs_to_jiffies(INT_DEBOUNCE_MSEC); 137 138 queue_delayed_work(pchip->irqthread, &pchip->work, delay); 139 140 rval = lm3630a_update(pchip, REG_CTRL, 0x80, 0x00); 141 if (rval < 0) { 142 dev_err(pchip->dev, "i2c failed to access register\n"); 143 return IRQ_NONE; 144 } 145 return IRQ_HANDLED; 146 } 147 148 static int lm3630a_intr_config(struct lm3630a_chip *pchip) 149 { 150 int rval; 151 152 rval = lm3630a_write(pchip, REG_INT_EN, 0x87); 153 if (rval < 0) 154 return rval; 155 156 INIT_DELAYED_WORK(&pchip->work, lm3630a_delayed_func); 157 pchip->irqthread = create_singlethread_workqueue("lm3630a-irqthd"); 158 if (!pchip->irqthread) { 159 dev_err(pchip->dev, "create irq thread fail\n"); 160 return -ENOMEM; 161 } 162 if (request_threaded_irq 163 (pchip->irq, NULL, lm3630a_isr_func, 164 IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "lm3630a_irq", pchip)) { 165 dev_err(pchip->dev, "request threaded irq fail\n"); 166 destroy_workqueue(pchip->irqthread); 167 return -ENOMEM; 168 } 169 return rval; 170 } 171 172 static void lm3630a_pwm_ctrl(struct lm3630a_chip *pchip, int br, int br_max) 173 { 174 unsigned int period = pchip->pdata->pwm_period; 175 unsigned int duty = br * period / br_max; 176 177 pwm_config(pchip->pwmd, duty, period); 178 if (duty) 179 pwm_enable(pchip->pwmd); 180 else 181 pwm_disable(pchip->pwmd); 182 } 183 184 /* update and get brightness */ 185 static int lm3630a_bank_a_update_status(struct backlight_device *bl) 186 { 187 int ret; 188 struct lm3630a_chip *pchip = bl_get_data(bl); 189 enum lm3630a_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; 190 191 /* pwm control */ 192 if ((pwm_ctrl & LM3630A_PWM_BANK_A) != 0) { 193 lm3630a_pwm_ctrl(pchip, bl->props.brightness, 194 bl->props.max_brightness); 195 return bl->props.brightness; 196 } 197 198 /* disable sleep */ 199 ret = lm3630a_update(pchip, REG_CTRL, 0x80, 0x00); 200 if (ret < 0) 201 goto out_i2c_err; 202 usleep_range(1000, 2000); 203 /* minimum brightness is 0x04 */ 204 ret = lm3630a_write(pchip, REG_BRT_A, bl->props.brightness); 205 if (bl->props.brightness < 0x4) 206 ret |= lm3630a_update(pchip, REG_CTRL, LM3630A_LEDA_ENABLE, 0); 207 else 208 ret |= lm3630a_update(pchip, REG_CTRL, 209 LM3630A_LEDA_ENABLE, LM3630A_LEDA_ENABLE); 210 if (ret < 0) 211 goto out_i2c_err; 212 return 0; 213 214 out_i2c_err: 215 dev_err(pchip->dev, "i2c failed to access\n"); 216 return bl->props.brightness; 217 } 218 219 static int lm3630a_bank_a_get_brightness(struct backlight_device *bl) 220 { 221 int brightness, rval; 222 struct lm3630a_chip *pchip = bl_get_data(bl); 223 enum lm3630a_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; 224 225 if ((pwm_ctrl & LM3630A_PWM_BANK_A) != 0) { 226 rval = lm3630a_read(pchip, REG_PWM_OUTHIGH); 227 if (rval < 0) 228 goto out_i2c_err; 229 brightness = (rval & 0x01) << 8; 230 rval = lm3630a_read(pchip, REG_PWM_OUTLOW); 231 if (rval < 0) 232 goto out_i2c_err; 233 brightness |= rval; 234 goto out; 235 } 236 237 /* disable sleep */ 238 rval = lm3630a_update(pchip, REG_CTRL, 0x80, 0x00); 239 if (rval < 0) 240 goto out_i2c_err; 241 usleep_range(1000, 2000); 242 rval = lm3630a_read(pchip, REG_BRT_A); 243 if (rval < 0) 244 goto out_i2c_err; 245 brightness = rval; 246 247 out: 248 bl->props.brightness = brightness; 249 return bl->props.brightness; 250 out_i2c_err: 251 dev_err(pchip->dev, "i2c failed to access register\n"); 252 return 0; 253 } 254 255 static const struct backlight_ops lm3630a_bank_a_ops = { 256 .options = BL_CORE_SUSPENDRESUME, 257 .update_status = lm3630a_bank_a_update_status, 258 .get_brightness = lm3630a_bank_a_get_brightness, 259 }; 260 261 /* update and get brightness */ 262 static int lm3630a_bank_b_update_status(struct backlight_device *bl) 263 { 264 int ret; 265 struct lm3630a_chip *pchip = bl_get_data(bl); 266 enum lm3630a_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; 267 268 /* pwm control */ 269 if ((pwm_ctrl & LM3630A_PWM_BANK_B) != 0) { 270 lm3630a_pwm_ctrl(pchip, bl->props.brightness, 271 bl->props.max_brightness); 272 return bl->props.brightness; 273 } 274 275 /* disable sleep */ 276 ret = lm3630a_update(pchip, REG_CTRL, 0x80, 0x00); 277 if (ret < 0) 278 goto out_i2c_err; 279 usleep_range(1000, 2000); 280 /* minimum brightness is 0x04 */ 281 ret = lm3630a_write(pchip, REG_BRT_B, bl->props.brightness); 282 if (bl->props.brightness < 0x4) 283 ret |= lm3630a_update(pchip, REG_CTRL, LM3630A_LEDB_ENABLE, 0); 284 else 285 ret |= lm3630a_update(pchip, REG_CTRL, 286 LM3630A_LEDB_ENABLE, LM3630A_LEDB_ENABLE); 287 if (ret < 0) 288 goto out_i2c_err; 289 return 0; 290 291 out_i2c_err: 292 dev_err(pchip->dev, "i2c failed to access REG_CTRL\n"); 293 return bl->props.brightness; 294 } 295 296 static int lm3630a_bank_b_get_brightness(struct backlight_device *bl) 297 { 298 int brightness, rval; 299 struct lm3630a_chip *pchip = bl_get_data(bl); 300 enum lm3630a_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; 301 302 if ((pwm_ctrl & LM3630A_PWM_BANK_B) != 0) { 303 rval = lm3630a_read(pchip, REG_PWM_OUTHIGH); 304 if (rval < 0) 305 goto out_i2c_err; 306 brightness = (rval & 0x01) << 8; 307 rval = lm3630a_read(pchip, REG_PWM_OUTLOW); 308 if (rval < 0) 309 goto out_i2c_err; 310 brightness |= rval; 311 goto out; 312 } 313 314 /* disable sleep */ 315 rval = lm3630a_update(pchip, REG_CTRL, 0x80, 0x00); 316 if (rval < 0) 317 goto out_i2c_err; 318 usleep_range(1000, 2000); 319 rval = lm3630a_read(pchip, REG_BRT_B); 320 if (rval < 0) 321 goto out_i2c_err; 322 brightness = rval; 323 324 out: 325 bl->props.brightness = brightness; 326 return bl->props.brightness; 327 out_i2c_err: 328 dev_err(pchip->dev, "i2c failed to access register\n"); 329 return 0; 330 } 331 332 static const struct backlight_ops lm3630a_bank_b_ops = { 333 .options = BL_CORE_SUSPENDRESUME, 334 .update_status = lm3630a_bank_b_update_status, 335 .get_brightness = lm3630a_bank_b_get_brightness, 336 }; 337 338 static int lm3630a_backlight_register(struct lm3630a_chip *pchip) 339 { 340 struct lm3630a_platform_data *pdata = pchip->pdata; 341 struct backlight_properties props; 342 const char *label; 343 344 props.type = BACKLIGHT_RAW; 345 if (pdata->leda_ctrl != LM3630A_LEDA_DISABLE) { 346 props.brightness = pdata->leda_init_brt; 347 props.max_brightness = pdata->leda_max_brt; 348 label = pdata->leda_label ? pdata->leda_label : "lm3630a_leda"; 349 pchip->bleda = 350 devm_backlight_device_register(pchip->dev, label, 351 pchip->dev, pchip, 352 &lm3630a_bank_a_ops, &props); 353 if (IS_ERR(pchip->bleda)) 354 return PTR_ERR(pchip->bleda); 355 } 356 357 if ((pdata->ledb_ctrl != LM3630A_LEDB_DISABLE) && 358 (pdata->ledb_ctrl != LM3630A_LEDB_ON_A)) { 359 props.brightness = pdata->ledb_init_brt; 360 props.max_brightness = pdata->ledb_max_brt; 361 label = pdata->ledb_label ? pdata->ledb_label : "lm3630a_ledb"; 362 pchip->bledb = 363 devm_backlight_device_register(pchip->dev, label, 364 pchip->dev, pchip, 365 &lm3630a_bank_b_ops, &props); 366 if (IS_ERR(pchip->bledb)) 367 return PTR_ERR(pchip->bledb); 368 } 369 return 0; 370 } 371 372 static const struct regmap_config lm3630a_regmap = { 373 .reg_bits = 8, 374 .val_bits = 8, 375 .max_register = REG_MAX, 376 }; 377 378 static int lm3630a_parse_led_sources(struct fwnode_handle *node, 379 int default_led_sources) 380 { 381 u32 sources[LM3630A_NUM_SINKS]; 382 int ret, num_sources, i; 383 384 num_sources = fwnode_property_read_u32_array(node, "led-sources", NULL, 385 0); 386 if (num_sources < 0) 387 return default_led_sources; 388 else if (num_sources > ARRAY_SIZE(sources)) 389 return -EINVAL; 390 391 ret = fwnode_property_read_u32_array(node, "led-sources", sources, 392 num_sources); 393 if (ret) 394 return ret; 395 396 for (i = 0; i < num_sources; i++) { 397 if (sources[i] < LM3630A_SINK_0 || sources[i] > LM3630A_SINK_1) 398 return -EINVAL; 399 400 ret |= BIT(sources[i]); 401 } 402 403 return ret; 404 } 405 406 static int lm3630a_parse_bank(struct lm3630a_platform_data *pdata, 407 struct fwnode_handle *node, int *seen_led_sources) 408 { 409 int led_sources, ret; 410 const char *label; 411 u32 bank, val; 412 bool linear; 413 414 ret = fwnode_property_read_u32(node, "reg", &bank); 415 if (ret) 416 return ret; 417 418 if (bank < LM3630A_BANK_0 || bank > LM3630A_BANK_1) 419 return -EINVAL; 420 421 led_sources = lm3630a_parse_led_sources(node, BIT(bank)); 422 if (led_sources < 0) 423 return led_sources; 424 425 if (*seen_led_sources & led_sources) 426 return -EINVAL; 427 428 *seen_led_sources |= led_sources; 429 430 linear = fwnode_property_read_bool(node, 431 "ti,linear-mapping-mode"); 432 if (bank) { 433 if (led_sources & BIT(LM3630A_SINK_0) || 434 !(led_sources & BIT(LM3630A_SINK_1))) 435 return -EINVAL; 436 437 pdata->ledb_ctrl = linear ? 438 LM3630A_LEDB_ENABLE_LINEAR : 439 LM3630A_LEDB_ENABLE; 440 } else { 441 if (!(led_sources & BIT(LM3630A_SINK_0))) 442 return -EINVAL; 443 444 pdata->leda_ctrl = linear ? 445 LM3630A_LEDA_ENABLE_LINEAR : 446 LM3630A_LEDA_ENABLE; 447 448 if (led_sources & BIT(LM3630A_SINK_1)) 449 pdata->ledb_ctrl = LM3630A_LEDB_ON_A; 450 } 451 452 ret = fwnode_property_read_string(node, "label", &label); 453 if (!ret) { 454 if (bank) 455 pdata->ledb_label = label; 456 else 457 pdata->leda_label = label; 458 } 459 460 ret = fwnode_property_read_u32(node, "default-brightness", 461 &val); 462 if (!ret) { 463 if (bank) 464 pdata->ledb_init_brt = val; 465 else 466 pdata->leda_init_brt = val; 467 } 468 469 ret = fwnode_property_read_u32(node, "max-brightness", &val); 470 if (!ret) { 471 if (bank) 472 pdata->ledb_max_brt = val; 473 else 474 pdata->leda_max_brt = val; 475 } 476 477 return 0; 478 } 479 480 static int lm3630a_parse_node(struct lm3630a_chip *pchip, 481 struct lm3630a_platform_data *pdata) 482 { 483 int ret = -ENODEV, seen_led_sources = 0; 484 struct fwnode_handle *node; 485 486 device_for_each_child_node(pchip->dev, node) { 487 ret = lm3630a_parse_bank(pdata, node, &seen_led_sources); 488 if (ret) 489 return ret; 490 } 491 492 return ret; 493 } 494 495 static int lm3630a_probe(struct i2c_client *client, 496 const struct i2c_device_id *id) 497 { 498 struct lm3630a_platform_data *pdata = dev_get_platdata(&client->dev); 499 struct lm3630a_chip *pchip; 500 int rval; 501 502 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 503 dev_err(&client->dev, "fail : i2c functionality check\n"); 504 return -EOPNOTSUPP; 505 } 506 507 pchip = devm_kzalloc(&client->dev, sizeof(struct lm3630a_chip), 508 GFP_KERNEL); 509 if (!pchip) 510 return -ENOMEM; 511 pchip->dev = &client->dev; 512 513 pchip->regmap = devm_regmap_init_i2c(client, &lm3630a_regmap); 514 if (IS_ERR(pchip->regmap)) { 515 rval = PTR_ERR(pchip->regmap); 516 dev_err(&client->dev, "fail : allocate reg. map: %d\n", rval); 517 return rval; 518 } 519 520 i2c_set_clientdata(client, pchip); 521 if (pdata == NULL) { 522 pdata = devm_kzalloc(pchip->dev, 523 sizeof(struct lm3630a_platform_data), 524 GFP_KERNEL); 525 if (pdata == NULL) 526 return -ENOMEM; 527 528 /* default values */ 529 pdata->leda_max_brt = LM3630A_MAX_BRIGHTNESS; 530 pdata->ledb_max_brt = LM3630A_MAX_BRIGHTNESS; 531 pdata->leda_init_brt = LM3630A_MAX_BRIGHTNESS; 532 pdata->ledb_init_brt = LM3630A_MAX_BRIGHTNESS; 533 534 rval = lm3630a_parse_node(pchip, pdata); 535 if (rval) { 536 dev_err(&client->dev, "fail : parse node\n"); 537 return rval; 538 } 539 } 540 pchip->pdata = pdata; 541 542 /* chip initialize */ 543 rval = lm3630a_chip_init(pchip); 544 if (rval < 0) { 545 dev_err(&client->dev, "fail : init chip\n"); 546 return rval; 547 } 548 /* backlight register */ 549 rval = lm3630a_backlight_register(pchip); 550 if (rval < 0) { 551 dev_err(&client->dev, "fail : backlight register.\n"); 552 return rval; 553 } 554 /* pwm */ 555 if (pdata->pwm_ctrl != LM3630A_PWM_DISABLE) { 556 pchip->pwmd = devm_pwm_get(pchip->dev, "lm3630a-pwm"); 557 if (IS_ERR(pchip->pwmd)) { 558 dev_err(&client->dev, "fail : get pwm device\n"); 559 return PTR_ERR(pchip->pwmd); 560 } 561 562 /* 563 * FIXME: pwm_apply_args() should be removed when switching to 564 * the atomic PWM API. 565 */ 566 pwm_apply_args(pchip->pwmd); 567 } 568 569 /* interrupt enable : irq 0 is not allowed */ 570 pchip->irq = client->irq; 571 if (pchip->irq) { 572 rval = lm3630a_intr_config(pchip); 573 if (rval < 0) 574 return rval; 575 } 576 dev_info(&client->dev, "LM3630A backlight register OK.\n"); 577 return 0; 578 } 579 580 static int lm3630a_remove(struct i2c_client *client) 581 { 582 int rval; 583 struct lm3630a_chip *pchip = i2c_get_clientdata(client); 584 585 rval = lm3630a_write(pchip, REG_BRT_A, 0); 586 if (rval < 0) 587 dev_err(pchip->dev, "i2c failed to access register\n"); 588 589 rval = lm3630a_write(pchip, REG_BRT_B, 0); 590 if (rval < 0) 591 dev_err(pchip->dev, "i2c failed to access register\n"); 592 593 if (pchip->irq) { 594 free_irq(pchip->irq, pchip); 595 flush_workqueue(pchip->irqthread); 596 destroy_workqueue(pchip->irqthread); 597 } 598 return 0; 599 } 600 601 static const struct i2c_device_id lm3630a_id[] = { 602 {LM3630A_NAME, 0}, 603 {} 604 }; 605 606 static const struct of_device_id lm3630a_match_table[] = { 607 { .compatible = "ti,lm3630a", }, 608 { }, 609 }; 610 611 MODULE_DEVICE_TABLE(i2c, lm3630a_id); 612 613 static struct i2c_driver lm3630a_i2c_driver = { 614 .driver = { 615 .name = LM3630A_NAME, 616 .of_match_table = lm3630a_match_table, 617 }, 618 .probe = lm3630a_probe, 619 .remove = lm3630a_remove, 620 .id_table = lm3630a_id, 621 }; 622 623 module_i2c_driver(lm3630a_i2c_driver); 624 625 MODULE_DESCRIPTION("Texas Instruments Backlight driver for LM3630A"); 626 MODULE_AUTHOR("Daniel Jeong <gshark.jeong@gmail.com>"); 627 MODULE_AUTHOR("LDD MLP <ldd-mlp@list.ti.com>"); 628 MODULE_LICENSE("GPL v2"); 629