1 /* 2 * TI LP855x Backlight Driver 3 * 4 * Copyright (C) 2011 Texas Instruments 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 * 10 */ 11 12 #include <linux/module.h> 13 #include <linux/slab.h> 14 #include <linux/i2c.h> 15 #include <linux/backlight.h> 16 #include <linux/delay.h> 17 #include <linux/err.h> 18 #include <linux/of.h> 19 #include <linux/platform_data/lp855x.h> 20 #include <linux/pwm.h> 21 #include <linux/regulator/consumer.h> 22 23 /* LP8550/1/2/3/6 Registers */ 24 #define LP855X_BRIGHTNESS_CTRL 0x00 25 #define LP855X_DEVICE_CTRL 0x01 26 #define LP855X_EEPROM_START 0xA0 27 #define LP855X_EEPROM_END 0xA7 28 #define LP8556_EPROM_START 0xA0 29 #define LP8556_EPROM_END 0xAF 30 31 /* LP8555/7 Registers */ 32 #define LP8557_BL_CMD 0x00 33 #define LP8557_BL_MASK 0x01 34 #define LP8557_BL_ON 0x01 35 #define LP8557_BL_OFF 0x00 36 #define LP8557_BRIGHTNESS_CTRL 0x04 37 #define LP8557_CONFIG 0x10 38 #define LP8555_EPROM_START 0x10 39 #define LP8555_EPROM_END 0x7A 40 #define LP8557_EPROM_START 0x10 41 #define LP8557_EPROM_END 0x1E 42 43 #define DEFAULT_BL_NAME "lcd-backlight" 44 #define MAX_BRIGHTNESS 255 45 46 enum lp855x_brightness_ctrl_mode { 47 PWM_BASED = 1, 48 REGISTER_BASED, 49 }; 50 51 struct lp855x; 52 53 /* 54 * struct lp855x_device_config 55 * @pre_init_device: init device function call before updating the brightness 56 * @reg_brightness: register address for brigthenss control 57 * @reg_devicectrl: register address for device control 58 * @post_init_device: late init device function call 59 */ 60 struct lp855x_device_config { 61 int (*pre_init_device)(struct lp855x *); 62 u8 reg_brightness; 63 u8 reg_devicectrl; 64 int (*post_init_device)(struct lp855x *); 65 }; 66 67 struct lp855x { 68 const char *chipname; 69 enum lp855x_chip_id chip_id; 70 enum lp855x_brightness_ctrl_mode mode; 71 struct lp855x_device_config *cfg; 72 struct i2c_client *client; 73 struct backlight_device *bl; 74 struct device *dev; 75 struct lp855x_platform_data *pdata; 76 struct pwm_device *pwm; 77 struct regulator *supply; /* regulator for VDD input */ 78 struct regulator *enable; /* regulator for EN/VDDIO input */ 79 }; 80 81 static int lp855x_write_byte(struct lp855x *lp, u8 reg, u8 data) 82 { 83 return i2c_smbus_write_byte_data(lp->client, reg, data); 84 } 85 86 static int lp855x_update_bit(struct lp855x *lp, u8 reg, u8 mask, u8 data) 87 { 88 int ret; 89 u8 tmp; 90 91 ret = i2c_smbus_read_byte_data(lp->client, reg); 92 if (ret < 0) { 93 dev_err(lp->dev, "failed to read 0x%.2x\n", reg); 94 return ret; 95 } 96 97 tmp = (u8)ret; 98 tmp &= ~mask; 99 tmp |= data & mask; 100 101 return lp855x_write_byte(lp, reg, tmp); 102 } 103 104 static bool lp855x_is_valid_rom_area(struct lp855x *lp, u8 addr) 105 { 106 u8 start, end; 107 108 switch (lp->chip_id) { 109 case LP8550: 110 case LP8551: 111 case LP8552: 112 case LP8553: 113 start = LP855X_EEPROM_START; 114 end = LP855X_EEPROM_END; 115 break; 116 case LP8556: 117 start = LP8556_EPROM_START; 118 end = LP8556_EPROM_END; 119 break; 120 case LP8555: 121 start = LP8555_EPROM_START; 122 end = LP8555_EPROM_END; 123 break; 124 case LP8557: 125 start = LP8557_EPROM_START; 126 end = LP8557_EPROM_END; 127 break; 128 default: 129 return false; 130 } 131 132 return addr >= start && addr <= end; 133 } 134 135 static int lp8557_bl_off(struct lp855x *lp) 136 { 137 /* BL_ON = 0 before updating EPROM settings */ 138 return lp855x_update_bit(lp, LP8557_BL_CMD, LP8557_BL_MASK, 139 LP8557_BL_OFF); 140 } 141 142 static int lp8557_bl_on(struct lp855x *lp) 143 { 144 /* BL_ON = 1 after updating EPROM settings */ 145 return lp855x_update_bit(lp, LP8557_BL_CMD, LP8557_BL_MASK, 146 LP8557_BL_ON); 147 } 148 149 static struct lp855x_device_config lp855x_dev_cfg = { 150 .reg_brightness = LP855X_BRIGHTNESS_CTRL, 151 .reg_devicectrl = LP855X_DEVICE_CTRL, 152 }; 153 154 static struct lp855x_device_config lp8557_dev_cfg = { 155 .reg_brightness = LP8557_BRIGHTNESS_CTRL, 156 .reg_devicectrl = LP8557_CONFIG, 157 .pre_init_device = lp8557_bl_off, 158 .post_init_device = lp8557_bl_on, 159 }; 160 161 /* 162 * Device specific configuration flow 163 * 164 * a) pre_init_device(optional) 165 * b) update the brightness register 166 * c) update device control register 167 * d) update ROM area(optional) 168 * e) post_init_device(optional) 169 * 170 */ 171 static int lp855x_configure(struct lp855x *lp) 172 { 173 u8 val, addr; 174 int i, ret; 175 struct lp855x_platform_data *pd = lp->pdata; 176 177 switch (lp->chip_id) { 178 case LP8550: 179 case LP8551: 180 case LP8552: 181 case LP8553: 182 case LP8556: 183 lp->cfg = &lp855x_dev_cfg; 184 break; 185 case LP8555: 186 case LP8557: 187 lp->cfg = &lp8557_dev_cfg; 188 break; 189 default: 190 return -EINVAL; 191 } 192 193 if (lp->cfg->pre_init_device) { 194 ret = lp->cfg->pre_init_device(lp); 195 if (ret) { 196 dev_err(lp->dev, "pre init device err: %d\n", ret); 197 goto err; 198 } 199 } 200 201 val = pd->initial_brightness; 202 ret = lp855x_write_byte(lp, lp->cfg->reg_brightness, val); 203 if (ret) 204 goto err; 205 206 val = pd->device_control; 207 ret = lp855x_write_byte(lp, lp->cfg->reg_devicectrl, val); 208 if (ret) 209 goto err; 210 211 if (pd->size_program > 0) { 212 for (i = 0; i < pd->size_program; i++) { 213 addr = pd->rom_data[i].addr; 214 val = pd->rom_data[i].val; 215 if (!lp855x_is_valid_rom_area(lp, addr)) 216 continue; 217 218 ret = lp855x_write_byte(lp, addr, val); 219 if (ret) 220 goto err; 221 } 222 } 223 224 if (lp->cfg->post_init_device) { 225 ret = lp->cfg->post_init_device(lp); 226 if (ret) { 227 dev_err(lp->dev, "post init device err: %d\n", ret); 228 goto err; 229 } 230 } 231 232 return 0; 233 234 err: 235 return ret; 236 } 237 238 static void lp855x_pwm_ctrl(struct lp855x *lp, int br, int max_br) 239 { 240 unsigned int period = lp->pdata->period_ns; 241 unsigned int duty = br * period / max_br; 242 struct pwm_device *pwm; 243 244 /* request pwm device with the consumer name */ 245 if (!lp->pwm) { 246 pwm = devm_pwm_get(lp->dev, lp->chipname); 247 if (IS_ERR(pwm)) 248 return; 249 250 lp->pwm = pwm; 251 252 /* 253 * FIXME: pwm_apply_args() should be removed when switching to 254 * the atomic PWM API. 255 */ 256 pwm_apply_args(pwm); 257 } 258 259 pwm_config(lp->pwm, duty, period); 260 if (duty) 261 pwm_enable(lp->pwm); 262 else 263 pwm_disable(lp->pwm); 264 } 265 266 static int lp855x_bl_update_status(struct backlight_device *bl) 267 { 268 struct lp855x *lp = bl_get_data(bl); 269 int brightness = bl->props.brightness; 270 271 if (bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK)) 272 brightness = 0; 273 274 if (lp->mode == PWM_BASED) 275 lp855x_pwm_ctrl(lp, brightness, bl->props.max_brightness); 276 else if (lp->mode == REGISTER_BASED) 277 lp855x_write_byte(lp, lp->cfg->reg_brightness, (u8)brightness); 278 279 return 0; 280 } 281 282 static const struct backlight_ops lp855x_bl_ops = { 283 .options = BL_CORE_SUSPENDRESUME, 284 .update_status = lp855x_bl_update_status, 285 }; 286 287 static int lp855x_backlight_register(struct lp855x *lp) 288 { 289 struct backlight_device *bl; 290 struct backlight_properties props; 291 struct lp855x_platform_data *pdata = lp->pdata; 292 const char *name = pdata->name ? : DEFAULT_BL_NAME; 293 294 memset(&props, 0, sizeof(props)); 295 props.type = BACKLIGHT_PLATFORM; 296 props.max_brightness = MAX_BRIGHTNESS; 297 298 if (pdata->initial_brightness > props.max_brightness) 299 pdata->initial_brightness = props.max_brightness; 300 301 props.brightness = pdata->initial_brightness; 302 303 bl = devm_backlight_device_register(lp->dev, name, lp->dev, lp, 304 &lp855x_bl_ops, &props); 305 if (IS_ERR(bl)) 306 return PTR_ERR(bl); 307 308 lp->bl = bl; 309 310 return 0; 311 } 312 313 static ssize_t lp855x_get_chip_id(struct device *dev, 314 struct device_attribute *attr, char *buf) 315 { 316 struct lp855x *lp = dev_get_drvdata(dev); 317 318 return scnprintf(buf, PAGE_SIZE, "%s\n", lp->chipname); 319 } 320 321 static ssize_t lp855x_get_bl_ctl_mode(struct device *dev, 322 struct device_attribute *attr, char *buf) 323 { 324 struct lp855x *lp = dev_get_drvdata(dev); 325 char *strmode = NULL; 326 327 if (lp->mode == PWM_BASED) 328 strmode = "pwm based"; 329 else if (lp->mode == REGISTER_BASED) 330 strmode = "register based"; 331 332 return scnprintf(buf, PAGE_SIZE, "%s\n", strmode); 333 } 334 335 static DEVICE_ATTR(chip_id, S_IRUGO, lp855x_get_chip_id, NULL); 336 static DEVICE_ATTR(bl_ctl_mode, S_IRUGO, lp855x_get_bl_ctl_mode, NULL); 337 338 static struct attribute *lp855x_attributes[] = { 339 &dev_attr_chip_id.attr, 340 &dev_attr_bl_ctl_mode.attr, 341 NULL, 342 }; 343 344 static const struct attribute_group lp855x_attr_group = { 345 .attrs = lp855x_attributes, 346 }; 347 348 #ifdef CONFIG_OF 349 static int lp855x_parse_dt(struct lp855x *lp) 350 { 351 struct device *dev = lp->dev; 352 struct device_node *node = dev->of_node; 353 struct lp855x_platform_data *pdata; 354 int rom_length; 355 356 if (!node) { 357 dev_err(dev, "no platform data\n"); 358 return -EINVAL; 359 } 360 361 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); 362 if (!pdata) 363 return -ENOMEM; 364 365 of_property_read_string(node, "bl-name", &pdata->name); 366 of_property_read_u8(node, "dev-ctrl", &pdata->device_control); 367 of_property_read_u8(node, "init-brt", &pdata->initial_brightness); 368 of_property_read_u32(node, "pwm-period", &pdata->period_ns); 369 370 /* Fill ROM platform data if defined */ 371 rom_length = of_get_child_count(node); 372 if (rom_length > 0) { 373 struct lp855x_rom_data *rom; 374 struct device_node *child; 375 int i = 0; 376 377 rom = devm_kzalloc(dev, sizeof(*rom) * rom_length, GFP_KERNEL); 378 if (!rom) 379 return -ENOMEM; 380 381 for_each_child_of_node(node, child) { 382 of_property_read_u8(child, "rom-addr", &rom[i].addr); 383 of_property_read_u8(child, "rom-val", &rom[i].val); 384 i++; 385 } 386 387 pdata->size_program = rom_length; 388 pdata->rom_data = &rom[0]; 389 } 390 391 lp->pdata = pdata; 392 393 return 0; 394 } 395 #else 396 static int lp855x_parse_dt(struct lp855x *lp) 397 { 398 return -EINVAL; 399 } 400 #endif 401 402 static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id) 403 { 404 struct lp855x *lp; 405 int ret; 406 407 if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) 408 return -EIO; 409 410 lp = devm_kzalloc(&cl->dev, sizeof(struct lp855x), GFP_KERNEL); 411 if (!lp) 412 return -ENOMEM; 413 414 lp->client = cl; 415 lp->dev = &cl->dev; 416 lp->chipname = id->name; 417 lp->chip_id = id->driver_data; 418 lp->pdata = dev_get_platdata(&cl->dev); 419 420 if (!lp->pdata) { 421 ret = lp855x_parse_dt(lp); 422 if (ret < 0) 423 return ret; 424 } 425 426 if (lp->pdata->period_ns > 0) 427 lp->mode = PWM_BASED; 428 else 429 lp->mode = REGISTER_BASED; 430 431 lp->supply = devm_regulator_get(lp->dev, "power"); 432 if (IS_ERR(lp->supply)) { 433 if (PTR_ERR(lp->supply) == -EPROBE_DEFER) 434 return -EPROBE_DEFER; 435 lp->supply = NULL; 436 } 437 438 lp->enable = devm_regulator_get_optional(lp->dev, "enable"); 439 if (IS_ERR(lp->enable)) { 440 ret = PTR_ERR(lp->enable); 441 if (ret == -ENODEV) { 442 lp->enable = NULL; 443 } else { 444 if (ret != -EPROBE_DEFER) 445 dev_err(lp->dev, "error getting enable regulator: %d\n", 446 ret); 447 return ret; 448 } 449 } 450 451 if (lp->supply) { 452 ret = regulator_enable(lp->supply); 453 if (ret < 0) { 454 dev_err(&cl->dev, "failed to enable supply: %d\n", ret); 455 return ret; 456 } 457 } 458 459 if (lp->enable) { 460 ret = regulator_enable(lp->enable); 461 if (ret < 0) { 462 dev_err(lp->dev, "failed to enable vddio: %d\n", ret); 463 return ret; 464 } 465 466 /* 467 * LP8555 datasheet says t_RESPONSE (time between VDDIO and 468 * I2C) is 1ms. 469 */ 470 usleep_range(1000, 2000); 471 } 472 473 i2c_set_clientdata(cl, lp); 474 475 ret = lp855x_configure(lp); 476 if (ret) { 477 dev_err(lp->dev, "device config err: %d", ret); 478 return ret; 479 } 480 481 ret = lp855x_backlight_register(lp); 482 if (ret) { 483 dev_err(lp->dev, 484 "failed to register backlight. err: %d\n", ret); 485 return ret; 486 } 487 488 ret = sysfs_create_group(&lp->dev->kobj, &lp855x_attr_group); 489 if (ret) { 490 dev_err(lp->dev, "failed to register sysfs. err: %d\n", ret); 491 return ret; 492 } 493 494 backlight_update_status(lp->bl); 495 return 0; 496 } 497 498 static int lp855x_remove(struct i2c_client *cl) 499 { 500 struct lp855x *lp = i2c_get_clientdata(cl); 501 502 lp->bl->props.brightness = 0; 503 backlight_update_status(lp->bl); 504 if (lp->supply) 505 regulator_disable(lp->supply); 506 sysfs_remove_group(&lp->dev->kobj, &lp855x_attr_group); 507 508 return 0; 509 } 510 511 static const struct of_device_id lp855x_dt_ids[] = { 512 { .compatible = "ti,lp8550", }, 513 { .compatible = "ti,lp8551", }, 514 { .compatible = "ti,lp8552", }, 515 { .compatible = "ti,lp8553", }, 516 { .compatible = "ti,lp8555", }, 517 { .compatible = "ti,lp8556", }, 518 { .compatible = "ti,lp8557", }, 519 { } 520 }; 521 MODULE_DEVICE_TABLE(of, lp855x_dt_ids); 522 523 static const struct i2c_device_id lp855x_ids[] = { 524 {"lp8550", LP8550}, 525 {"lp8551", LP8551}, 526 {"lp8552", LP8552}, 527 {"lp8553", LP8553}, 528 {"lp8555", LP8555}, 529 {"lp8556", LP8556}, 530 {"lp8557", LP8557}, 531 { } 532 }; 533 MODULE_DEVICE_TABLE(i2c, lp855x_ids); 534 535 static struct i2c_driver lp855x_driver = { 536 .driver = { 537 .name = "lp855x", 538 .of_match_table = of_match_ptr(lp855x_dt_ids), 539 }, 540 .probe = lp855x_probe, 541 .remove = lp855x_remove, 542 .id_table = lp855x_ids, 543 }; 544 545 module_i2c_driver(lp855x_driver); 546 547 MODULE_DESCRIPTION("Texas Instruments LP855x Backlight driver"); 548 MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>"); 549 MODULE_LICENSE("GPL"); 550