1 /* 2 * LP5521/LP5523/LP55231/LP5562 Common Driver 3 * 4 * Copyright 2012 Texas Instruments 5 * 6 * Author: Milo(Woogyom) Kim <milo.kim@ti.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 * 12 * Derived from leds-lp5521.c, leds-lp5523.c 13 */ 14 15 #include <linux/clk.h> 16 #include <linux/delay.h> 17 #include <linux/firmware.h> 18 #include <linux/i2c.h> 19 #include <linux/leds.h> 20 #include <linux/module.h> 21 #include <linux/platform_data/leds-lp55xx.h> 22 23 #include "leds-lp55xx-common.h" 24 25 /* External clock rate */ 26 #define LP55XX_CLK_32K 32768 27 28 static struct lp55xx_led *cdev_to_lp55xx_led(struct led_classdev *cdev) 29 { 30 return container_of(cdev, struct lp55xx_led, cdev); 31 } 32 33 static struct lp55xx_led *dev_to_lp55xx_led(struct device *dev) 34 { 35 return cdev_to_lp55xx_led(dev_get_drvdata(dev)); 36 } 37 38 static void lp55xx_reset_device(struct lp55xx_chip *chip) 39 { 40 struct lp55xx_device_config *cfg = chip->cfg; 41 u8 addr = cfg->reset.addr; 42 u8 val = cfg->reset.val; 43 44 /* no error checking here because no ACK from the device after reset */ 45 lp55xx_write(chip, addr, val); 46 } 47 48 static int lp55xx_detect_device(struct lp55xx_chip *chip) 49 { 50 struct lp55xx_device_config *cfg = chip->cfg; 51 u8 addr = cfg->enable.addr; 52 u8 val = cfg->enable.val; 53 int ret; 54 55 ret = lp55xx_write(chip, addr, val); 56 if (ret) 57 return ret; 58 59 usleep_range(1000, 2000); 60 61 ret = lp55xx_read(chip, addr, &val); 62 if (ret) 63 return ret; 64 65 if (val != cfg->enable.val) 66 return -ENODEV; 67 68 return 0; 69 } 70 71 static int lp55xx_post_init_device(struct lp55xx_chip *chip) 72 { 73 struct lp55xx_device_config *cfg = chip->cfg; 74 75 if (!cfg->post_init_device) 76 return 0; 77 78 return cfg->post_init_device(chip); 79 } 80 81 static ssize_t lp55xx_show_current(struct device *dev, 82 struct device_attribute *attr, 83 char *buf) 84 { 85 struct lp55xx_led *led = dev_to_lp55xx_led(dev); 86 87 return scnprintf(buf, PAGE_SIZE, "%d\n", led->led_current); 88 } 89 90 static ssize_t lp55xx_store_current(struct device *dev, 91 struct device_attribute *attr, 92 const char *buf, size_t len) 93 { 94 struct lp55xx_led *led = dev_to_lp55xx_led(dev); 95 struct lp55xx_chip *chip = led->chip; 96 unsigned long curr; 97 98 if (kstrtoul(buf, 0, &curr)) 99 return -EINVAL; 100 101 if (curr > led->max_current) 102 return -EINVAL; 103 104 if (!chip->cfg->set_led_current) 105 return len; 106 107 mutex_lock(&chip->lock); 108 chip->cfg->set_led_current(led, (u8)curr); 109 mutex_unlock(&chip->lock); 110 111 return len; 112 } 113 114 static ssize_t lp55xx_show_max_current(struct device *dev, 115 struct device_attribute *attr, 116 char *buf) 117 { 118 struct lp55xx_led *led = dev_to_lp55xx_led(dev); 119 120 return scnprintf(buf, PAGE_SIZE, "%d\n", led->max_current); 121 } 122 123 static DEVICE_ATTR(led_current, S_IRUGO | S_IWUSR, lp55xx_show_current, 124 lp55xx_store_current); 125 static DEVICE_ATTR(max_current, S_IRUGO , lp55xx_show_max_current, NULL); 126 127 static struct attribute *lp55xx_led_attributes[] = { 128 &dev_attr_led_current.attr, 129 &dev_attr_max_current.attr, 130 NULL, 131 }; 132 133 static struct attribute_group lp55xx_led_attr_group = { 134 .attrs = lp55xx_led_attributes 135 }; 136 137 static void lp55xx_set_brightness(struct led_classdev *cdev, 138 enum led_brightness brightness) 139 { 140 struct lp55xx_led *led = cdev_to_lp55xx_led(cdev); 141 142 led->brightness = (u8)brightness; 143 schedule_work(&led->brightness_work); 144 } 145 146 static int lp55xx_init_led(struct lp55xx_led *led, 147 struct lp55xx_chip *chip, int chan) 148 { 149 struct lp55xx_platform_data *pdata = chip->pdata; 150 struct lp55xx_device_config *cfg = chip->cfg; 151 struct device *dev = &chip->cl->dev; 152 char name[32]; 153 int ret; 154 int max_channel = cfg->max_channel; 155 156 if (chan >= max_channel) { 157 dev_err(dev, "invalid channel: %d / %d\n", chan, max_channel); 158 return -EINVAL; 159 } 160 161 if (pdata->led_config[chan].led_current == 0) 162 return 0; 163 164 led->led_current = pdata->led_config[chan].led_current; 165 led->max_current = pdata->led_config[chan].max_current; 166 led->chan_nr = pdata->led_config[chan].chan_nr; 167 168 if (led->chan_nr >= max_channel) { 169 dev_err(dev, "Use channel numbers between 0 and %d\n", 170 max_channel - 1); 171 return -EINVAL; 172 } 173 174 led->cdev.brightness_set = lp55xx_set_brightness; 175 176 if (pdata->led_config[chan].name) { 177 led->cdev.name = pdata->led_config[chan].name; 178 } else { 179 snprintf(name, sizeof(name), "%s:channel%d", 180 pdata->label ? : chip->cl->name, chan); 181 led->cdev.name = name; 182 } 183 184 /* 185 * register led class device for each channel and 186 * add device attributes 187 */ 188 189 ret = led_classdev_register(dev, &led->cdev); 190 if (ret) { 191 dev_err(dev, "led register err: %d\n", ret); 192 return ret; 193 } 194 195 ret = sysfs_create_group(&led->cdev.dev->kobj, &lp55xx_led_attr_group); 196 if (ret) { 197 dev_err(dev, "led sysfs err: %d\n", ret); 198 led_classdev_unregister(&led->cdev); 199 return ret; 200 } 201 202 return 0; 203 } 204 205 static void lp55xx_firmware_loaded(const struct firmware *fw, void *context) 206 { 207 struct lp55xx_chip *chip = context; 208 struct device *dev = &chip->cl->dev; 209 210 if (!fw) { 211 dev_err(dev, "firmware request failed\n"); 212 goto out; 213 } 214 215 /* handling firmware data is chip dependent */ 216 mutex_lock(&chip->lock); 217 218 chip->fw = fw; 219 if (chip->cfg->firmware_cb) 220 chip->cfg->firmware_cb(chip); 221 222 mutex_unlock(&chip->lock); 223 224 out: 225 /* firmware should be released for other channel use */ 226 release_firmware(chip->fw); 227 } 228 229 static int lp55xx_request_firmware(struct lp55xx_chip *chip) 230 { 231 const char *name = chip->cl->name; 232 struct device *dev = &chip->cl->dev; 233 234 return request_firmware_nowait(THIS_MODULE, true, name, dev, 235 GFP_KERNEL, chip, lp55xx_firmware_loaded); 236 } 237 238 static ssize_t lp55xx_show_engine_select(struct device *dev, 239 struct device_attribute *attr, 240 char *buf) 241 { 242 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 243 struct lp55xx_chip *chip = led->chip; 244 245 return sprintf(buf, "%d\n", chip->engine_idx); 246 } 247 248 static ssize_t lp55xx_store_engine_select(struct device *dev, 249 struct device_attribute *attr, 250 const char *buf, size_t len) 251 { 252 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 253 struct lp55xx_chip *chip = led->chip; 254 unsigned long val; 255 int ret; 256 257 if (kstrtoul(buf, 0, &val)) 258 return -EINVAL; 259 260 /* select the engine to be run */ 261 262 switch (val) { 263 case LP55XX_ENGINE_1: 264 case LP55XX_ENGINE_2: 265 case LP55XX_ENGINE_3: 266 mutex_lock(&chip->lock); 267 chip->engine_idx = val; 268 ret = lp55xx_request_firmware(chip); 269 mutex_unlock(&chip->lock); 270 break; 271 default: 272 dev_err(dev, "%lu: invalid engine index. (1, 2, 3)\n", val); 273 return -EINVAL; 274 } 275 276 if (ret) { 277 dev_err(dev, "request firmware err: %d\n", ret); 278 return ret; 279 } 280 281 return len; 282 } 283 284 static inline void lp55xx_run_engine(struct lp55xx_chip *chip, bool start) 285 { 286 if (chip->cfg->run_engine) 287 chip->cfg->run_engine(chip, start); 288 } 289 290 static ssize_t lp55xx_store_engine_run(struct device *dev, 291 struct device_attribute *attr, 292 const char *buf, size_t len) 293 { 294 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 295 struct lp55xx_chip *chip = led->chip; 296 unsigned long val; 297 298 if (kstrtoul(buf, 0, &val)) 299 return -EINVAL; 300 301 /* run or stop the selected engine */ 302 303 if (val <= 0) { 304 lp55xx_run_engine(chip, false); 305 return len; 306 } 307 308 mutex_lock(&chip->lock); 309 lp55xx_run_engine(chip, true); 310 mutex_unlock(&chip->lock); 311 312 return len; 313 } 314 315 static DEVICE_ATTR(select_engine, S_IRUGO | S_IWUSR, 316 lp55xx_show_engine_select, lp55xx_store_engine_select); 317 static DEVICE_ATTR(run_engine, S_IWUSR, NULL, lp55xx_store_engine_run); 318 319 static struct attribute *lp55xx_engine_attributes[] = { 320 &dev_attr_select_engine.attr, 321 &dev_attr_run_engine.attr, 322 NULL, 323 }; 324 325 static const struct attribute_group lp55xx_engine_attr_group = { 326 .attrs = lp55xx_engine_attributes, 327 }; 328 329 int lp55xx_write(struct lp55xx_chip *chip, u8 reg, u8 val) 330 { 331 return i2c_smbus_write_byte_data(chip->cl, reg, val); 332 } 333 EXPORT_SYMBOL_GPL(lp55xx_write); 334 335 int lp55xx_read(struct lp55xx_chip *chip, u8 reg, u8 *val) 336 { 337 s32 ret; 338 339 ret = i2c_smbus_read_byte_data(chip->cl, reg); 340 if (ret < 0) 341 return ret; 342 343 *val = ret; 344 return 0; 345 } 346 EXPORT_SYMBOL_GPL(lp55xx_read); 347 348 int lp55xx_update_bits(struct lp55xx_chip *chip, u8 reg, u8 mask, u8 val) 349 { 350 int ret; 351 u8 tmp; 352 353 ret = lp55xx_read(chip, reg, &tmp); 354 if (ret) 355 return ret; 356 357 tmp &= ~mask; 358 tmp |= val & mask; 359 360 return lp55xx_write(chip, reg, tmp); 361 } 362 EXPORT_SYMBOL_GPL(lp55xx_update_bits); 363 364 bool lp55xx_is_extclk_used(struct lp55xx_chip *chip) 365 { 366 struct clk *clk; 367 int err; 368 369 clk = devm_clk_get(&chip->cl->dev, "32k_clk"); 370 if (IS_ERR(clk)) 371 goto use_internal_clk; 372 373 err = clk_prepare_enable(clk); 374 if (err) 375 goto use_internal_clk; 376 377 if (clk_get_rate(clk) != LP55XX_CLK_32K) { 378 clk_disable_unprepare(clk); 379 goto use_internal_clk; 380 } 381 382 dev_info(&chip->cl->dev, "%dHz external clock used\n", LP55XX_CLK_32K); 383 384 chip->clk = clk; 385 return true; 386 387 use_internal_clk: 388 dev_info(&chip->cl->dev, "internal clock used\n"); 389 return false; 390 } 391 EXPORT_SYMBOL_GPL(lp55xx_is_extclk_used); 392 393 int lp55xx_init_device(struct lp55xx_chip *chip) 394 { 395 struct lp55xx_platform_data *pdata; 396 struct lp55xx_device_config *cfg; 397 struct device *dev = &chip->cl->dev; 398 int ret = 0; 399 400 WARN_ON(!chip); 401 402 pdata = chip->pdata; 403 cfg = chip->cfg; 404 405 if (!pdata || !cfg) 406 return -EINVAL; 407 408 if (pdata->setup_resources) { 409 ret = pdata->setup_resources(); 410 if (ret < 0) { 411 dev_err(dev, "setup resoure err: %d\n", ret); 412 goto err; 413 } 414 } 415 416 if (pdata->enable) { 417 pdata->enable(0); 418 usleep_range(1000, 2000); /* Keep enable down at least 1ms */ 419 pdata->enable(1); 420 usleep_range(1000, 2000); /* 500us abs min. */ 421 } 422 423 lp55xx_reset_device(chip); 424 425 /* 426 * Exact value is not available. 10 - 20ms 427 * appears to be enough for reset. 428 */ 429 usleep_range(10000, 20000); 430 431 ret = lp55xx_detect_device(chip); 432 if (ret) { 433 dev_err(dev, "device detection err: %d\n", ret); 434 goto err; 435 } 436 437 /* chip specific initialization */ 438 ret = lp55xx_post_init_device(chip); 439 if (ret) { 440 dev_err(dev, "post init device err: %d\n", ret); 441 goto err_post_init; 442 } 443 444 return 0; 445 446 err_post_init: 447 lp55xx_deinit_device(chip); 448 err: 449 return ret; 450 } 451 EXPORT_SYMBOL_GPL(lp55xx_init_device); 452 453 void lp55xx_deinit_device(struct lp55xx_chip *chip) 454 { 455 struct lp55xx_platform_data *pdata = chip->pdata; 456 457 if (chip->clk) 458 clk_disable_unprepare(chip->clk); 459 460 if (pdata->enable) 461 pdata->enable(0); 462 463 if (pdata->release_resources) 464 pdata->release_resources(); 465 } 466 EXPORT_SYMBOL_GPL(lp55xx_deinit_device); 467 468 int lp55xx_register_leds(struct lp55xx_led *led, struct lp55xx_chip *chip) 469 { 470 struct lp55xx_platform_data *pdata = chip->pdata; 471 struct lp55xx_device_config *cfg = chip->cfg; 472 int num_channels = pdata->num_channels; 473 struct lp55xx_led *each; 474 u8 led_current; 475 int ret; 476 int i; 477 478 if (!cfg->brightness_work_fn) { 479 dev_err(&chip->cl->dev, "empty brightness configuration\n"); 480 return -EINVAL; 481 } 482 483 for (i = 0; i < num_channels; i++) { 484 485 /* do not initialize channels that are not connected */ 486 if (pdata->led_config[i].led_current == 0) 487 continue; 488 489 led_current = pdata->led_config[i].led_current; 490 each = led + i; 491 ret = lp55xx_init_led(each, chip, i); 492 if (ret) 493 goto err_init_led; 494 495 INIT_WORK(&each->brightness_work, cfg->brightness_work_fn); 496 497 chip->num_leds++; 498 each->chip = chip; 499 500 /* setting led current at each channel */ 501 if (cfg->set_led_current) 502 cfg->set_led_current(each, led_current); 503 } 504 505 return 0; 506 507 err_init_led: 508 lp55xx_unregister_leds(led, chip); 509 return ret; 510 } 511 EXPORT_SYMBOL_GPL(lp55xx_register_leds); 512 513 void lp55xx_unregister_leds(struct lp55xx_led *led, struct lp55xx_chip *chip) 514 { 515 int i; 516 struct lp55xx_led *each; 517 518 for (i = 0; i < chip->num_leds; i++) { 519 each = led + i; 520 led_classdev_unregister(&each->cdev); 521 flush_work(&each->brightness_work); 522 } 523 } 524 EXPORT_SYMBOL_GPL(lp55xx_unregister_leds); 525 526 int lp55xx_register_sysfs(struct lp55xx_chip *chip) 527 { 528 struct device *dev = &chip->cl->dev; 529 struct lp55xx_device_config *cfg = chip->cfg; 530 int ret; 531 532 if (!cfg->run_engine || !cfg->firmware_cb) 533 goto dev_specific_attrs; 534 535 ret = sysfs_create_group(&dev->kobj, &lp55xx_engine_attr_group); 536 if (ret) 537 return ret; 538 539 dev_specific_attrs: 540 return cfg->dev_attr_group ? 541 sysfs_create_group(&dev->kobj, cfg->dev_attr_group) : 0; 542 } 543 EXPORT_SYMBOL_GPL(lp55xx_register_sysfs); 544 545 void lp55xx_unregister_sysfs(struct lp55xx_chip *chip) 546 { 547 struct device *dev = &chip->cl->dev; 548 struct lp55xx_device_config *cfg = chip->cfg; 549 550 if (cfg->dev_attr_group) 551 sysfs_remove_group(&dev->kobj, cfg->dev_attr_group); 552 553 sysfs_remove_group(&dev->kobj, &lp55xx_engine_attr_group); 554 } 555 EXPORT_SYMBOL_GPL(lp55xx_unregister_sysfs); 556 557 MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>"); 558 MODULE_DESCRIPTION("LP55xx Common Driver"); 559 MODULE_LICENSE("GPL"); 560