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_MAX 0x1F 35 36 #define INT_DEBOUNCE_MSEC 10 37 struct lm3630a_chip { 38 struct device *dev; 39 struct delayed_work work; 40 41 int irq; 42 struct workqueue_struct *irqthread; 43 struct lm3630a_platform_data *pdata; 44 struct backlight_device *bleda; 45 struct backlight_device *bledb; 46 struct regmap *regmap; 47 struct pwm_device *pwmd; 48 }; 49 50 /* i2c access */ 51 static int lm3630a_read(struct lm3630a_chip *pchip, unsigned int reg) 52 { 53 int rval; 54 unsigned int reg_val; 55 56 rval = regmap_read(pchip->regmap, reg, ®_val); 57 if (rval < 0) 58 return rval; 59 return reg_val & 0xFF; 60 } 61 62 static int lm3630a_write(struct lm3630a_chip *pchip, 63 unsigned int reg, unsigned int data) 64 { 65 return regmap_write(pchip->regmap, reg, data); 66 } 67 68 static int lm3630a_update(struct lm3630a_chip *pchip, 69 unsigned int reg, unsigned int mask, 70 unsigned int data) 71 { 72 return regmap_update_bits(pchip->regmap, reg, mask, data); 73 } 74 75 /* initialize chip */ 76 static int lm3630a_chip_init(struct lm3630a_chip *pchip) 77 { 78 int rval; 79 struct lm3630a_platform_data *pdata = pchip->pdata; 80 81 usleep_range(1000, 2000); 82 /* set Filter Strength Register */ 83 rval = lm3630a_write(pchip, 0x50, 0x03); 84 /* set Cofig. register */ 85 rval |= lm3630a_update(pchip, REG_CONFIG, 0x07, pdata->pwm_ctrl); 86 /* set boost control */ 87 rval |= lm3630a_write(pchip, REG_BOOST, 0x38); 88 /* set current A */ 89 rval |= lm3630a_update(pchip, REG_I_A, 0x1F, 0x1F); 90 /* set current B */ 91 rval |= lm3630a_write(pchip, REG_I_B, 0x1F); 92 /* set control */ 93 rval |= 94 lm3630a_write(pchip, REG_CTRL, pdata->leda_ctrl | pdata->ledb_ctrl); 95 usleep_range(1000, 2000); 96 /* set brightness A and B */ 97 rval |= lm3630a_write(pchip, REG_BRT_A, pdata->leda_init_brt); 98 rval |= lm3630a_write(pchip, REG_BRT_B, pdata->ledb_init_brt); 99 100 if (rval < 0) 101 dev_err(pchip->dev, "i2c failed to access register\n"); 102 return rval; 103 } 104 105 /* interrupt handling */ 106 static void lm3630a_delayed_func(struct work_struct *work) 107 { 108 unsigned int rval; 109 struct lm3630a_chip *pchip; 110 111 pchip = container_of(work, struct lm3630a_chip, work.work); 112 113 rval = lm3630a_read(pchip, REG_INT_STATUS); 114 if (rval < 0) { 115 dev_err(pchip->dev, 116 "i2c failed to access REG_INT_STATUS Register\n"); 117 return; 118 } 119 120 dev_info(pchip->dev, "REG_INT_STATUS Register is 0x%x\n", rval); 121 } 122 123 static irqreturn_t lm3630a_isr_func(int irq, void *chip) 124 { 125 int rval; 126 struct lm3630a_chip *pchip = chip; 127 unsigned long delay = msecs_to_jiffies(INT_DEBOUNCE_MSEC); 128 129 queue_delayed_work(pchip->irqthread, &pchip->work, delay); 130 131 rval = lm3630a_update(pchip, REG_CTRL, 0x80, 0x00); 132 if (rval < 0) { 133 dev_err(pchip->dev, "i2c failed to access register\n"); 134 return IRQ_NONE; 135 } 136 return IRQ_HANDLED; 137 } 138 139 static int lm3630a_intr_config(struct lm3630a_chip *pchip) 140 { 141 int rval; 142 143 rval = lm3630a_write(pchip, REG_INT_EN, 0x87); 144 if (rval < 0) 145 return rval; 146 147 INIT_DELAYED_WORK(&pchip->work, lm3630a_delayed_func); 148 pchip->irqthread = create_singlethread_workqueue("lm3630a-irqthd"); 149 if (!pchip->irqthread) { 150 dev_err(pchip->dev, "create irq thread fail\n"); 151 return -ENOMEM; 152 } 153 if (request_threaded_irq 154 (pchip->irq, NULL, lm3630a_isr_func, 155 IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "lm3630a_irq", pchip)) { 156 dev_err(pchip->dev, "request threaded irq fail\n"); 157 return -ENOMEM; 158 } 159 return rval; 160 } 161 162 static void lm3630a_pwm_ctrl(struct lm3630a_chip *pchip, int br, int br_max) 163 { 164 unsigned int period = pwm_get_period(pchip->pwmd); 165 unsigned int duty = br * period / br_max; 166 167 pwm_config(pchip->pwmd, duty, period); 168 if (duty) 169 pwm_enable(pchip->pwmd); 170 else 171 pwm_disable(pchip->pwmd); 172 } 173 174 /* update and get brightness */ 175 static int lm3630a_bank_a_update_status(struct backlight_device *bl) 176 { 177 int ret; 178 struct lm3630a_chip *pchip = bl_get_data(bl); 179 enum lm3630a_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; 180 181 /* pwm control */ 182 if ((pwm_ctrl & LM3630A_PWM_BANK_A) != 0) { 183 lm3630a_pwm_ctrl(pchip, bl->props.brightness, 184 bl->props.max_brightness); 185 return bl->props.brightness; 186 } 187 188 /* disable sleep */ 189 ret = lm3630a_update(pchip, REG_CTRL, 0x80, 0x00); 190 if (ret < 0) 191 goto out_i2c_err; 192 usleep_range(1000, 2000); 193 /* minimum brightness is 0x04 */ 194 ret = lm3630a_write(pchip, REG_BRT_A, bl->props.brightness); 195 if (bl->props.brightness < 0x4) 196 ret |= lm3630a_update(pchip, REG_CTRL, LM3630A_LEDA_ENABLE, 0); 197 else 198 ret |= lm3630a_update(pchip, REG_CTRL, 199 LM3630A_LEDA_ENABLE, LM3630A_LEDA_ENABLE); 200 if (ret < 0) 201 goto out_i2c_err; 202 return bl->props.brightness; 203 204 out_i2c_err: 205 dev_err(pchip->dev, "i2c failed to access\n"); 206 return bl->props.brightness; 207 } 208 209 static int lm3630a_bank_a_get_brightness(struct backlight_device *bl) 210 { 211 int brightness, rval; 212 struct lm3630a_chip *pchip = bl_get_data(bl); 213 enum lm3630a_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; 214 215 if ((pwm_ctrl & LM3630A_PWM_BANK_A) != 0) { 216 rval = lm3630a_read(pchip, REG_PWM_OUTHIGH); 217 if (rval < 0) 218 goto out_i2c_err; 219 brightness = (rval & 0x01) << 8; 220 rval = lm3630a_read(pchip, REG_PWM_OUTLOW); 221 if (rval < 0) 222 goto out_i2c_err; 223 brightness |= rval; 224 goto out; 225 } 226 227 /* disable sleep */ 228 rval = lm3630a_update(pchip, REG_CTRL, 0x80, 0x00); 229 if (rval < 0) 230 goto out_i2c_err; 231 usleep_range(1000, 2000); 232 rval = lm3630a_read(pchip, REG_BRT_A); 233 if (rval < 0) 234 goto out_i2c_err; 235 brightness = rval; 236 237 out: 238 bl->props.brightness = brightness; 239 return bl->props.brightness; 240 out_i2c_err: 241 dev_err(pchip->dev, "i2c failed to access register\n"); 242 return 0; 243 } 244 245 static const struct backlight_ops lm3630a_bank_a_ops = { 246 .options = BL_CORE_SUSPENDRESUME, 247 .update_status = lm3630a_bank_a_update_status, 248 .get_brightness = lm3630a_bank_a_get_brightness, 249 }; 250 251 /* update and get brightness */ 252 static int lm3630a_bank_b_update_status(struct backlight_device *bl) 253 { 254 int ret; 255 struct lm3630a_chip *pchip = bl_get_data(bl); 256 enum lm3630a_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; 257 258 /* pwm control */ 259 if ((pwm_ctrl & LM3630A_PWM_BANK_B) != 0) { 260 lm3630a_pwm_ctrl(pchip, bl->props.brightness, 261 bl->props.max_brightness); 262 return bl->props.brightness; 263 } 264 265 /* disable sleep */ 266 ret = lm3630a_update(pchip, REG_CTRL, 0x80, 0x00); 267 if (ret < 0) 268 goto out_i2c_err; 269 usleep_range(1000, 2000); 270 /* minimum brightness is 0x04 */ 271 ret = lm3630a_write(pchip, REG_BRT_B, bl->props.brightness); 272 if (bl->props.brightness < 0x4) 273 ret |= lm3630a_update(pchip, REG_CTRL, LM3630A_LEDB_ENABLE, 0); 274 else 275 ret |= lm3630a_update(pchip, REG_CTRL, 276 LM3630A_LEDB_ENABLE, LM3630A_LEDB_ENABLE); 277 if (ret < 0) 278 goto out_i2c_err; 279 return bl->props.brightness; 280 281 out_i2c_err: 282 dev_err(pchip->dev, "i2c failed to access REG_CTRL\n"); 283 return bl->props.brightness; 284 } 285 286 static int lm3630a_bank_b_get_brightness(struct backlight_device *bl) 287 { 288 int brightness, rval; 289 struct lm3630a_chip *pchip = bl_get_data(bl); 290 enum lm3630a_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; 291 292 if ((pwm_ctrl & LM3630A_PWM_BANK_B) != 0) { 293 rval = lm3630a_read(pchip, REG_PWM_OUTHIGH); 294 if (rval < 0) 295 goto out_i2c_err; 296 brightness = (rval & 0x01) << 8; 297 rval = lm3630a_read(pchip, REG_PWM_OUTLOW); 298 if (rval < 0) 299 goto out_i2c_err; 300 brightness |= rval; 301 goto out; 302 } 303 304 /* disable sleep */ 305 rval = lm3630a_update(pchip, REG_CTRL, 0x80, 0x00); 306 if (rval < 0) 307 goto out_i2c_err; 308 usleep_range(1000, 2000); 309 rval = lm3630a_read(pchip, REG_BRT_B); 310 if (rval < 0) 311 goto out_i2c_err; 312 brightness = rval; 313 314 out: 315 bl->props.brightness = brightness; 316 return bl->props.brightness; 317 out_i2c_err: 318 dev_err(pchip->dev, "i2c failed to access register\n"); 319 return 0; 320 } 321 322 static const struct backlight_ops lm3630a_bank_b_ops = { 323 .options = BL_CORE_SUSPENDRESUME, 324 .update_status = lm3630a_bank_b_update_status, 325 .get_brightness = lm3630a_bank_b_get_brightness, 326 }; 327 328 static int lm3630a_backlight_register(struct lm3630a_chip *pchip) 329 { 330 struct backlight_properties props; 331 struct lm3630a_platform_data *pdata = pchip->pdata; 332 333 props.type = BACKLIGHT_RAW; 334 if (pdata->leda_ctrl != LM3630A_LEDA_DISABLE) { 335 props.brightness = pdata->leda_init_brt; 336 props.max_brightness = pdata->leda_max_brt; 337 pchip->bleda = 338 devm_backlight_device_register(pchip->dev, "lm3630a_leda", 339 pchip->dev, pchip, 340 &lm3630a_bank_a_ops, &props); 341 if (IS_ERR(pchip->bleda)) 342 return PTR_ERR(pchip->bleda); 343 } 344 345 if ((pdata->ledb_ctrl != LM3630A_LEDB_DISABLE) && 346 (pdata->ledb_ctrl != LM3630A_LEDB_ON_A)) { 347 props.brightness = pdata->ledb_init_brt; 348 props.max_brightness = pdata->ledb_max_brt; 349 pchip->bledb = 350 devm_backlight_device_register(pchip->dev, "lm3630a_ledb", 351 pchip->dev, pchip, 352 &lm3630a_bank_b_ops, &props); 353 if (IS_ERR(pchip->bledb)) 354 return PTR_ERR(pchip->bledb); 355 } 356 return 0; 357 } 358 359 static const struct regmap_config lm3630a_regmap = { 360 .reg_bits = 8, 361 .val_bits = 8, 362 .max_register = REG_MAX, 363 }; 364 365 static int lm3630a_probe(struct i2c_client *client, 366 const struct i2c_device_id *id) 367 { 368 struct lm3630a_platform_data *pdata = client->dev.platform_data; 369 struct lm3630a_chip *pchip; 370 int rval; 371 372 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 373 dev_err(&client->dev, "fail : i2c functionality check\n"); 374 return -EOPNOTSUPP; 375 } 376 377 pchip = devm_kzalloc(&client->dev, sizeof(struct lm3630a_chip), 378 GFP_KERNEL); 379 if (!pchip) 380 return -ENOMEM; 381 pchip->dev = &client->dev; 382 383 pchip->regmap = devm_regmap_init_i2c(client, &lm3630a_regmap); 384 if (IS_ERR(pchip->regmap)) { 385 rval = PTR_ERR(pchip->regmap); 386 dev_err(&client->dev, "fail : allocate reg. map: %d\n", rval); 387 return rval; 388 } 389 390 i2c_set_clientdata(client, pchip); 391 if (pdata == NULL) { 392 pchip->pdata = devm_kzalloc(pchip->dev, 393 sizeof(struct 394 lm3630a_platform_data), 395 GFP_KERNEL); 396 if (pchip->pdata == NULL) 397 return -ENOMEM; 398 /* default values */ 399 pchip->pdata->leda_ctrl = LM3630A_LEDA_ENABLE; 400 pchip->pdata->ledb_ctrl = LM3630A_LEDB_ENABLE; 401 pchip->pdata->leda_max_brt = LM3630A_MAX_BRIGHTNESS; 402 pchip->pdata->ledb_max_brt = LM3630A_MAX_BRIGHTNESS; 403 pchip->pdata->leda_init_brt = LM3630A_MAX_BRIGHTNESS; 404 pchip->pdata->ledb_init_brt = LM3630A_MAX_BRIGHTNESS; 405 } else { 406 pchip->pdata = pdata; 407 } 408 /* chip initialize */ 409 rval = lm3630a_chip_init(pchip); 410 if (rval < 0) { 411 dev_err(&client->dev, "fail : init chip\n"); 412 return rval; 413 } 414 /* backlight register */ 415 rval = lm3630a_backlight_register(pchip); 416 if (rval < 0) { 417 dev_err(&client->dev, "fail : backlight register.\n"); 418 return rval; 419 } 420 /* pwm */ 421 if (pdata->pwm_ctrl != LM3630A_PWM_DISABLE) { 422 pchip->pwmd = devm_pwm_get(pchip->dev, "lm3630a-pwm"); 423 if (IS_ERR(pchip->pwmd)) { 424 dev_err(&client->dev, "fail : get pwm device\n"); 425 return PTR_ERR(pchip->pwmd); 426 } 427 } 428 pchip->pwmd->period = pdata->pwm_period; 429 430 /* interrupt enable : irq 0 is not allowed */ 431 pchip->irq = client->irq; 432 if (pchip->irq) { 433 rval = lm3630a_intr_config(pchip); 434 if (rval < 0) 435 return rval; 436 } 437 dev_info(&client->dev, "LM3630A backlight register OK.\n"); 438 return 0; 439 } 440 441 static int lm3630a_remove(struct i2c_client *client) 442 { 443 int rval; 444 struct lm3630a_chip *pchip = i2c_get_clientdata(client); 445 446 rval = lm3630a_write(pchip, REG_BRT_A, 0); 447 if (rval < 0) 448 dev_err(pchip->dev, "i2c failed to access register\n"); 449 450 rval = lm3630a_write(pchip, REG_BRT_B, 0); 451 if (rval < 0) 452 dev_err(pchip->dev, "i2c failed to access register\n"); 453 454 if (pchip->irq) { 455 free_irq(pchip->irq, pchip); 456 flush_workqueue(pchip->irqthread); 457 destroy_workqueue(pchip->irqthread); 458 } 459 return 0; 460 } 461 462 static const struct i2c_device_id lm3630a_id[] = { 463 {LM3630A_NAME, 0}, 464 {} 465 }; 466 467 MODULE_DEVICE_TABLE(i2c, lm3630a_id); 468 469 static struct i2c_driver lm3630a_i2c_driver = { 470 .driver = { 471 .name = LM3630A_NAME, 472 }, 473 .probe = lm3630a_probe, 474 .remove = lm3630a_remove, 475 .id_table = lm3630a_id, 476 }; 477 478 module_i2c_driver(lm3630a_i2c_driver); 479 480 MODULE_DESCRIPTION("Texas Instruments Backlight driver for LM3630A"); 481 MODULE_AUTHOR("Daniel Jeong <gshark.jeong@gmail.com>"); 482 MODULE_AUTHOR("LDD MLP <ldd-mlp@list.ti.com>"); 483 MODULE_LICENSE("GPL v2"); 484