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 |= lm3630a_update(pchip, REG_CTRL, 0x14, pdata->leda_ctrl); 94 rval |= lm3630a_update(pchip, REG_CTRL, 0x0B, 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 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 destroy_workqueue(pchip->irqthread); 158 return -ENOMEM; 159 } 160 return rval; 161 } 162 163 static void lm3630a_pwm_ctrl(struct lm3630a_chip *pchip, int br, int br_max) 164 { 165 unsigned int period = pwm_get_period(pchip->pwmd); 166 unsigned int duty = br * period / br_max; 167 168 pwm_config(pchip->pwmd, duty, period); 169 if (duty) 170 pwm_enable(pchip->pwmd); 171 else 172 pwm_disable(pchip->pwmd); 173 } 174 175 /* update and get brightness */ 176 static int lm3630a_bank_a_update_status(struct backlight_device *bl) 177 { 178 int ret; 179 struct lm3630a_chip *pchip = bl_get_data(bl); 180 enum lm3630a_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; 181 182 /* pwm control */ 183 if ((pwm_ctrl & LM3630A_PWM_BANK_A) != 0) { 184 lm3630a_pwm_ctrl(pchip, bl->props.brightness, 185 bl->props.max_brightness); 186 return bl->props.brightness; 187 } 188 189 /* disable sleep */ 190 ret = lm3630a_update(pchip, REG_CTRL, 0x80, 0x00); 191 if (ret < 0) 192 goto out_i2c_err; 193 usleep_range(1000, 2000); 194 /* minimum brightness is 0x04 */ 195 ret = lm3630a_write(pchip, REG_BRT_A, bl->props.brightness); 196 if (bl->props.brightness < 0x4) 197 ret |= lm3630a_update(pchip, REG_CTRL, LM3630A_LEDA_ENABLE, 0); 198 else 199 ret |= lm3630a_update(pchip, REG_CTRL, 200 LM3630A_LEDA_ENABLE, LM3630A_LEDA_ENABLE); 201 if (ret < 0) 202 goto out_i2c_err; 203 return bl->props.brightness; 204 205 out_i2c_err: 206 dev_err(pchip->dev, "i2c failed to access\n"); 207 return bl->props.brightness; 208 } 209 210 static int lm3630a_bank_a_get_brightness(struct backlight_device *bl) 211 { 212 int brightness, rval; 213 struct lm3630a_chip *pchip = bl_get_data(bl); 214 enum lm3630a_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; 215 216 if ((pwm_ctrl & LM3630A_PWM_BANK_A) != 0) { 217 rval = lm3630a_read(pchip, REG_PWM_OUTHIGH); 218 if (rval < 0) 219 goto out_i2c_err; 220 brightness = (rval & 0x01) << 8; 221 rval = lm3630a_read(pchip, REG_PWM_OUTLOW); 222 if (rval < 0) 223 goto out_i2c_err; 224 brightness |= rval; 225 goto out; 226 } 227 228 /* disable sleep */ 229 rval = lm3630a_update(pchip, REG_CTRL, 0x80, 0x00); 230 if (rval < 0) 231 goto out_i2c_err; 232 usleep_range(1000, 2000); 233 rval = lm3630a_read(pchip, REG_BRT_A); 234 if (rval < 0) 235 goto out_i2c_err; 236 brightness = rval; 237 238 out: 239 bl->props.brightness = brightness; 240 return bl->props.brightness; 241 out_i2c_err: 242 dev_err(pchip->dev, "i2c failed to access register\n"); 243 return 0; 244 } 245 246 static const struct backlight_ops lm3630a_bank_a_ops = { 247 .options = BL_CORE_SUSPENDRESUME, 248 .update_status = lm3630a_bank_a_update_status, 249 .get_brightness = lm3630a_bank_a_get_brightness, 250 }; 251 252 /* update and get brightness */ 253 static int lm3630a_bank_b_update_status(struct backlight_device *bl) 254 { 255 int ret; 256 struct lm3630a_chip *pchip = bl_get_data(bl); 257 enum lm3630a_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; 258 259 /* pwm control */ 260 if ((pwm_ctrl & LM3630A_PWM_BANK_B) != 0) { 261 lm3630a_pwm_ctrl(pchip, bl->props.brightness, 262 bl->props.max_brightness); 263 return bl->props.brightness; 264 } 265 266 /* disable sleep */ 267 ret = lm3630a_update(pchip, REG_CTRL, 0x80, 0x00); 268 if (ret < 0) 269 goto out_i2c_err; 270 usleep_range(1000, 2000); 271 /* minimum brightness is 0x04 */ 272 ret = lm3630a_write(pchip, REG_BRT_B, bl->props.brightness); 273 if (bl->props.brightness < 0x4) 274 ret |= lm3630a_update(pchip, REG_CTRL, LM3630A_LEDB_ENABLE, 0); 275 else 276 ret |= lm3630a_update(pchip, REG_CTRL, 277 LM3630A_LEDB_ENABLE, LM3630A_LEDB_ENABLE); 278 if (ret < 0) 279 goto out_i2c_err; 280 return bl->props.brightness; 281 282 out_i2c_err: 283 dev_err(pchip->dev, "i2c failed to access REG_CTRL\n"); 284 return bl->props.brightness; 285 } 286 287 static int lm3630a_bank_b_get_brightness(struct backlight_device *bl) 288 { 289 int brightness, rval; 290 struct lm3630a_chip *pchip = bl_get_data(bl); 291 enum lm3630a_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; 292 293 if ((pwm_ctrl & LM3630A_PWM_BANK_B) != 0) { 294 rval = lm3630a_read(pchip, REG_PWM_OUTHIGH); 295 if (rval < 0) 296 goto out_i2c_err; 297 brightness = (rval & 0x01) << 8; 298 rval = lm3630a_read(pchip, REG_PWM_OUTLOW); 299 if (rval < 0) 300 goto out_i2c_err; 301 brightness |= rval; 302 goto out; 303 } 304 305 /* disable sleep */ 306 rval = lm3630a_update(pchip, REG_CTRL, 0x80, 0x00); 307 if (rval < 0) 308 goto out_i2c_err; 309 usleep_range(1000, 2000); 310 rval = lm3630a_read(pchip, REG_BRT_B); 311 if (rval < 0) 312 goto out_i2c_err; 313 brightness = rval; 314 315 out: 316 bl->props.brightness = brightness; 317 return bl->props.brightness; 318 out_i2c_err: 319 dev_err(pchip->dev, "i2c failed to access register\n"); 320 return 0; 321 } 322 323 static const struct backlight_ops lm3630a_bank_b_ops = { 324 .options = BL_CORE_SUSPENDRESUME, 325 .update_status = lm3630a_bank_b_update_status, 326 .get_brightness = lm3630a_bank_b_get_brightness, 327 }; 328 329 static int lm3630a_backlight_register(struct lm3630a_chip *pchip) 330 { 331 struct backlight_properties props; 332 struct lm3630a_platform_data *pdata = pchip->pdata; 333 334 props.type = BACKLIGHT_RAW; 335 if (pdata->leda_ctrl != LM3630A_LEDA_DISABLE) { 336 props.brightness = pdata->leda_init_brt; 337 props.max_brightness = pdata->leda_max_brt; 338 pchip->bleda = 339 devm_backlight_device_register(pchip->dev, "lm3630a_leda", 340 pchip->dev, pchip, 341 &lm3630a_bank_a_ops, &props); 342 if (IS_ERR(pchip->bleda)) 343 return PTR_ERR(pchip->bleda); 344 } 345 346 if ((pdata->ledb_ctrl != LM3630A_LEDB_DISABLE) && 347 (pdata->ledb_ctrl != LM3630A_LEDB_ON_A)) { 348 props.brightness = pdata->ledb_init_brt; 349 props.max_brightness = pdata->ledb_max_brt; 350 pchip->bledb = 351 devm_backlight_device_register(pchip->dev, "lm3630a_ledb", 352 pchip->dev, pchip, 353 &lm3630a_bank_b_ops, &props); 354 if (IS_ERR(pchip->bledb)) 355 return PTR_ERR(pchip->bledb); 356 } 357 return 0; 358 } 359 360 static const struct regmap_config lm3630a_regmap = { 361 .reg_bits = 8, 362 .val_bits = 8, 363 .max_register = REG_MAX, 364 }; 365 366 static int lm3630a_probe(struct i2c_client *client, 367 const struct i2c_device_id *id) 368 { 369 struct lm3630a_platform_data *pdata = dev_get_platdata(&client->dev); 370 struct lm3630a_chip *pchip; 371 int rval; 372 373 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 374 dev_err(&client->dev, "fail : i2c functionality check\n"); 375 return -EOPNOTSUPP; 376 } 377 378 pchip = devm_kzalloc(&client->dev, sizeof(struct lm3630a_chip), 379 GFP_KERNEL); 380 if (!pchip) 381 return -ENOMEM; 382 pchip->dev = &client->dev; 383 384 pchip->regmap = devm_regmap_init_i2c(client, &lm3630a_regmap); 385 if (IS_ERR(pchip->regmap)) { 386 rval = PTR_ERR(pchip->regmap); 387 dev_err(&client->dev, "fail : allocate reg. map: %d\n", rval); 388 return rval; 389 } 390 391 i2c_set_clientdata(client, pchip); 392 if (pdata == NULL) { 393 pdata = devm_kzalloc(pchip->dev, 394 sizeof(struct lm3630a_platform_data), 395 GFP_KERNEL); 396 if (pdata == NULL) 397 return -ENOMEM; 398 /* default values */ 399 pdata->leda_ctrl = LM3630A_LEDA_ENABLE; 400 pdata->ledb_ctrl = LM3630A_LEDB_ENABLE; 401 pdata->leda_max_brt = LM3630A_MAX_BRIGHTNESS; 402 pdata->ledb_max_brt = LM3630A_MAX_BRIGHTNESS; 403 pdata->leda_init_brt = LM3630A_MAX_BRIGHTNESS; 404 pdata->ledb_init_brt = LM3630A_MAX_BRIGHTNESS; 405 } 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