root/drivers/leds/leds-lp55xx-common.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cdev_to_lp55xx_led
  2. dev_to_lp55xx_led
  3. lp55xx_reset_device
  4. lp55xx_detect_device
  5. lp55xx_post_init_device
  6. lp55xx_show_current
  7. lp55xx_store_current
  8. lp55xx_show_max_current
  9. lp55xx_set_brightness
  10. lp55xx_init_led
  11. lp55xx_firmware_loaded
  12. lp55xx_request_firmware
  13. lp55xx_show_engine_select
  14. lp55xx_store_engine_select
  15. lp55xx_run_engine
  16. lp55xx_store_engine_run
  17. lp55xx_write
  18. lp55xx_read
  19. lp55xx_update_bits
  20. lp55xx_is_extclk_used
  21. lp55xx_init_device
  22. lp55xx_deinit_device
  23. lp55xx_register_leds
  24. lp55xx_unregister_leds
  25. lp55xx_register_sysfs
  26. lp55xx_unregister_sysfs
  27. lp55xx_of_populate_pdata

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * LP5521/LP5523/LP55231/LP5562 Common Driver
   4  *
   5  * Copyright 2012 Texas Instruments
   6  *
   7  * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
   8  *
   9  * Derived from leds-lp5521.c, leds-lp5523.c
  10  */
  11 
  12 #include <linux/clk.h>
  13 #include <linux/delay.h>
  14 #include <linux/firmware.h>
  15 #include <linux/i2c.h>
  16 #include <linux/leds.h>
  17 #include <linux/module.h>
  18 #include <linux/platform_data/leds-lp55xx.h>
  19 #include <linux/slab.h>
  20 #include <linux/gpio.h>
  21 #include <linux/of_gpio.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_attrs[] = {
 128         &dev_attr_led_current.attr,
 129         &dev_attr_max_current.attr,
 130         NULL,
 131 };
 132 ATTRIBUTE_GROUPS(lp55xx_led);
 133 
 134 static int lp55xx_set_brightness(struct led_classdev *cdev,
 135                              enum led_brightness brightness)
 136 {
 137         struct lp55xx_led *led = cdev_to_lp55xx_led(cdev);
 138         struct lp55xx_device_config *cfg = led->chip->cfg;
 139 
 140         led->brightness = (u8)brightness;
 141         return cfg->brightness_fn(led);
 142 }
 143 
 144 static int lp55xx_init_led(struct lp55xx_led *led,
 145                         struct lp55xx_chip *chip, int chan)
 146 {
 147         struct lp55xx_platform_data *pdata = chip->pdata;
 148         struct lp55xx_device_config *cfg = chip->cfg;
 149         struct device *dev = &chip->cl->dev;
 150         char name[32];
 151         int ret;
 152         int max_channel = cfg->max_channel;
 153 
 154         if (chan >= max_channel) {
 155                 dev_err(dev, "invalid channel: %d / %d\n", chan, max_channel);
 156                 return -EINVAL;
 157         }
 158 
 159         if (pdata->led_config[chan].led_current == 0)
 160                 return 0;
 161 
 162         led->led_current = pdata->led_config[chan].led_current;
 163         led->max_current = pdata->led_config[chan].max_current;
 164         led->chan_nr = pdata->led_config[chan].chan_nr;
 165         led->cdev.default_trigger = pdata->led_config[chan].default_trigger;
 166 
 167         if (led->chan_nr >= max_channel) {
 168                 dev_err(dev, "Use channel numbers between 0 and %d\n",
 169                         max_channel - 1);
 170                 return -EINVAL;
 171         }
 172 
 173         led->cdev.brightness_set_blocking = lp55xx_set_brightness;
 174         led->cdev.groups = lp55xx_led_groups;
 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         ret = led_classdev_register(dev, &led->cdev);
 185         if (ret) {
 186                 dev_err(dev, "led register err: %d\n", ret);
 187                 return ret;
 188         }
 189 
 190         return 0;
 191 }
 192 
 193 static void lp55xx_firmware_loaded(const struct firmware *fw, void *context)
 194 {
 195         struct lp55xx_chip *chip = context;
 196         struct device *dev = &chip->cl->dev;
 197         enum lp55xx_engine_index idx = chip->engine_idx;
 198 
 199         if (!fw) {
 200                 dev_err(dev, "firmware request failed\n");
 201                 return;
 202         }
 203 
 204         /* handling firmware data is chip dependent */
 205         mutex_lock(&chip->lock);
 206 
 207         chip->engines[idx - 1].mode = LP55XX_ENGINE_LOAD;
 208         chip->fw = fw;
 209         if (chip->cfg->firmware_cb)
 210                 chip->cfg->firmware_cb(chip);
 211 
 212         mutex_unlock(&chip->lock);
 213 
 214         /* firmware should be released for other channel use */
 215         release_firmware(chip->fw);
 216         chip->fw = NULL;
 217 }
 218 
 219 static int lp55xx_request_firmware(struct lp55xx_chip *chip)
 220 {
 221         const char *name = chip->cl->name;
 222         struct device *dev = &chip->cl->dev;
 223 
 224         return request_firmware_nowait(THIS_MODULE, false, name, dev,
 225                                 GFP_KERNEL, chip, lp55xx_firmware_loaded);
 226 }
 227 
 228 static ssize_t lp55xx_show_engine_select(struct device *dev,
 229                             struct device_attribute *attr,
 230                             char *buf)
 231 {
 232         struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
 233         struct lp55xx_chip *chip = led->chip;
 234 
 235         return sprintf(buf, "%d\n", chip->engine_idx);
 236 }
 237 
 238 static ssize_t lp55xx_store_engine_select(struct device *dev,
 239                              struct device_attribute *attr,
 240                              const char *buf, size_t len)
 241 {
 242         struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
 243         struct lp55xx_chip *chip = led->chip;
 244         unsigned long val;
 245         int ret;
 246 
 247         if (kstrtoul(buf, 0, &val))
 248                 return -EINVAL;
 249 
 250         /* select the engine to be run */
 251 
 252         switch (val) {
 253         case LP55XX_ENGINE_1:
 254         case LP55XX_ENGINE_2:
 255         case LP55XX_ENGINE_3:
 256                 mutex_lock(&chip->lock);
 257                 chip->engine_idx = val;
 258                 ret = lp55xx_request_firmware(chip);
 259                 mutex_unlock(&chip->lock);
 260                 break;
 261         default:
 262                 dev_err(dev, "%lu: invalid engine index. (1, 2, 3)\n", val);
 263                 return -EINVAL;
 264         }
 265 
 266         if (ret) {
 267                 dev_err(dev, "request firmware err: %d\n", ret);
 268                 return ret;
 269         }
 270 
 271         return len;
 272 }
 273 
 274 static inline void lp55xx_run_engine(struct lp55xx_chip *chip, bool start)
 275 {
 276         if (chip->cfg->run_engine)
 277                 chip->cfg->run_engine(chip, start);
 278 }
 279 
 280 static ssize_t lp55xx_store_engine_run(struct device *dev,
 281                              struct device_attribute *attr,
 282                              const char *buf, size_t len)
 283 {
 284         struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
 285         struct lp55xx_chip *chip = led->chip;
 286         unsigned long val;
 287 
 288         if (kstrtoul(buf, 0, &val))
 289                 return -EINVAL;
 290 
 291         /* run or stop the selected engine */
 292 
 293         if (val <= 0) {
 294                 lp55xx_run_engine(chip, false);
 295                 return len;
 296         }
 297 
 298         mutex_lock(&chip->lock);
 299         lp55xx_run_engine(chip, true);
 300         mutex_unlock(&chip->lock);
 301 
 302         return len;
 303 }
 304 
 305 static DEVICE_ATTR(select_engine, S_IRUGO | S_IWUSR,
 306                    lp55xx_show_engine_select, lp55xx_store_engine_select);
 307 static DEVICE_ATTR(run_engine, S_IWUSR, NULL, lp55xx_store_engine_run);
 308 
 309 static struct attribute *lp55xx_engine_attributes[] = {
 310         &dev_attr_select_engine.attr,
 311         &dev_attr_run_engine.attr,
 312         NULL,
 313 };
 314 
 315 static const struct attribute_group lp55xx_engine_attr_group = {
 316         .attrs = lp55xx_engine_attributes,
 317 };
 318 
 319 int lp55xx_write(struct lp55xx_chip *chip, u8 reg, u8 val)
 320 {
 321         return i2c_smbus_write_byte_data(chip->cl, reg, val);
 322 }
 323 EXPORT_SYMBOL_GPL(lp55xx_write);
 324 
 325 int lp55xx_read(struct lp55xx_chip *chip, u8 reg, u8 *val)
 326 {
 327         s32 ret;
 328 
 329         ret = i2c_smbus_read_byte_data(chip->cl, reg);
 330         if (ret < 0)
 331                 return ret;
 332 
 333         *val = ret;
 334         return 0;
 335 }
 336 EXPORT_SYMBOL_GPL(lp55xx_read);
 337 
 338 int lp55xx_update_bits(struct lp55xx_chip *chip, u8 reg, u8 mask, u8 val)
 339 {
 340         int ret;
 341         u8 tmp;
 342 
 343         ret = lp55xx_read(chip, reg, &tmp);
 344         if (ret)
 345                 return ret;
 346 
 347         tmp &= ~mask;
 348         tmp |= val & mask;
 349 
 350         return lp55xx_write(chip, reg, tmp);
 351 }
 352 EXPORT_SYMBOL_GPL(lp55xx_update_bits);
 353 
 354 bool lp55xx_is_extclk_used(struct lp55xx_chip *chip)
 355 {
 356         struct clk *clk;
 357         int err;
 358 
 359         clk = devm_clk_get(&chip->cl->dev, "32k_clk");
 360         if (IS_ERR(clk))
 361                 goto use_internal_clk;
 362 
 363         err = clk_prepare_enable(clk);
 364         if (err)
 365                 goto use_internal_clk;
 366 
 367         if (clk_get_rate(clk) != LP55XX_CLK_32K) {
 368                 clk_disable_unprepare(clk);
 369                 goto use_internal_clk;
 370         }
 371 
 372         dev_info(&chip->cl->dev, "%dHz external clock used\n",  LP55XX_CLK_32K);
 373 
 374         chip->clk = clk;
 375         return true;
 376 
 377 use_internal_clk:
 378         dev_info(&chip->cl->dev, "internal clock used\n");
 379         return false;
 380 }
 381 EXPORT_SYMBOL_GPL(lp55xx_is_extclk_used);
 382 
 383 int lp55xx_init_device(struct lp55xx_chip *chip)
 384 {
 385         struct lp55xx_platform_data *pdata;
 386         struct lp55xx_device_config *cfg;
 387         struct device *dev = &chip->cl->dev;
 388         int ret = 0;
 389 
 390         WARN_ON(!chip);
 391 
 392         pdata = chip->pdata;
 393         cfg = chip->cfg;
 394 
 395         if (!pdata || !cfg)
 396                 return -EINVAL;
 397 
 398         if (gpio_is_valid(pdata->enable_gpio)) {
 399                 ret = devm_gpio_request_one(dev, pdata->enable_gpio,
 400                                             GPIOF_DIR_OUT, "lp5523_enable");
 401                 if (ret < 0) {
 402                         dev_err(dev, "could not acquire enable gpio (err=%d)\n",
 403                                 ret);
 404                         goto err;
 405                 }
 406 
 407                 gpio_set_value(pdata->enable_gpio, 0);
 408                 usleep_range(1000, 2000); /* Keep enable down at least 1ms */
 409                 gpio_set_value(pdata->enable_gpio, 1);
 410                 usleep_range(1000, 2000); /* 500us abs min. */
 411         }
 412 
 413         lp55xx_reset_device(chip);
 414 
 415         /*
 416          * Exact value is not available. 10 - 20ms
 417          * appears to be enough for reset.
 418          */
 419         usleep_range(10000, 20000);
 420 
 421         ret = lp55xx_detect_device(chip);
 422         if (ret) {
 423                 dev_err(dev, "device detection err: %d\n", ret);
 424                 goto err;
 425         }
 426 
 427         /* chip specific initialization */
 428         ret = lp55xx_post_init_device(chip);
 429         if (ret) {
 430                 dev_err(dev, "post init device err: %d\n", ret);
 431                 goto err_post_init;
 432         }
 433 
 434         return 0;
 435 
 436 err_post_init:
 437         lp55xx_deinit_device(chip);
 438 err:
 439         return ret;
 440 }
 441 EXPORT_SYMBOL_GPL(lp55xx_init_device);
 442 
 443 void lp55xx_deinit_device(struct lp55xx_chip *chip)
 444 {
 445         struct lp55xx_platform_data *pdata = chip->pdata;
 446 
 447         if (chip->clk)
 448                 clk_disable_unprepare(chip->clk);
 449 
 450         if (gpio_is_valid(pdata->enable_gpio))
 451                 gpio_set_value(pdata->enable_gpio, 0);
 452 }
 453 EXPORT_SYMBOL_GPL(lp55xx_deinit_device);
 454 
 455 int lp55xx_register_leds(struct lp55xx_led *led, struct lp55xx_chip *chip)
 456 {
 457         struct lp55xx_platform_data *pdata = chip->pdata;
 458         struct lp55xx_device_config *cfg = chip->cfg;
 459         int num_channels = pdata->num_channels;
 460         struct lp55xx_led *each;
 461         u8 led_current;
 462         int ret;
 463         int i;
 464 
 465         if (!cfg->brightness_fn) {
 466                 dev_err(&chip->cl->dev, "empty brightness configuration\n");
 467                 return -EINVAL;
 468         }
 469 
 470         for (i = 0; i < num_channels; i++) {
 471 
 472                 /* do not initialize channels that are not connected */
 473                 if (pdata->led_config[i].led_current == 0)
 474                         continue;
 475 
 476                 led_current = pdata->led_config[i].led_current;
 477                 each = led + i;
 478                 ret = lp55xx_init_led(each, chip, i);
 479                 if (ret)
 480                         goto err_init_led;
 481 
 482                 chip->num_leds++;
 483                 each->chip = chip;
 484 
 485                 /* setting led current at each channel */
 486                 if (cfg->set_led_current)
 487                         cfg->set_led_current(each, led_current);
 488         }
 489 
 490         return 0;
 491 
 492 err_init_led:
 493         lp55xx_unregister_leds(led, chip);
 494         return ret;
 495 }
 496 EXPORT_SYMBOL_GPL(lp55xx_register_leds);
 497 
 498 void lp55xx_unregister_leds(struct lp55xx_led *led, struct lp55xx_chip *chip)
 499 {
 500         int i;
 501         struct lp55xx_led *each;
 502 
 503         for (i = 0; i < chip->num_leds; i++) {
 504                 each = led + i;
 505                 led_classdev_unregister(&each->cdev);
 506         }
 507 }
 508 EXPORT_SYMBOL_GPL(lp55xx_unregister_leds);
 509 
 510 int lp55xx_register_sysfs(struct lp55xx_chip *chip)
 511 {
 512         struct device *dev = &chip->cl->dev;
 513         struct lp55xx_device_config *cfg = chip->cfg;
 514         int ret;
 515 
 516         if (!cfg->run_engine || !cfg->firmware_cb)
 517                 goto dev_specific_attrs;
 518 
 519         ret = sysfs_create_group(&dev->kobj, &lp55xx_engine_attr_group);
 520         if (ret)
 521                 return ret;
 522 
 523 dev_specific_attrs:
 524         return cfg->dev_attr_group ?
 525                 sysfs_create_group(&dev->kobj, cfg->dev_attr_group) : 0;
 526 }
 527 EXPORT_SYMBOL_GPL(lp55xx_register_sysfs);
 528 
 529 void lp55xx_unregister_sysfs(struct lp55xx_chip *chip)
 530 {
 531         struct device *dev = &chip->cl->dev;
 532         struct lp55xx_device_config *cfg = chip->cfg;
 533 
 534         if (cfg->dev_attr_group)
 535                 sysfs_remove_group(&dev->kobj, cfg->dev_attr_group);
 536 
 537         sysfs_remove_group(&dev->kobj, &lp55xx_engine_attr_group);
 538 }
 539 EXPORT_SYMBOL_GPL(lp55xx_unregister_sysfs);
 540 
 541 struct lp55xx_platform_data *lp55xx_of_populate_pdata(struct device *dev,
 542                                                       struct device_node *np)
 543 {
 544         struct device_node *child;
 545         struct lp55xx_platform_data *pdata;
 546         struct lp55xx_led_config *cfg;
 547         int num_channels;
 548         int i = 0;
 549 
 550         pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
 551         if (!pdata)
 552                 return ERR_PTR(-ENOMEM);
 553 
 554         num_channels = of_get_child_count(np);
 555         if (num_channels == 0) {
 556                 dev_err(dev, "no LED channels\n");
 557                 return ERR_PTR(-EINVAL);
 558         }
 559 
 560         cfg = devm_kcalloc(dev, num_channels, sizeof(*cfg), GFP_KERNEL);
 561         if (!cfg)
 562                 return ERR_PTR(-ENOMEM);
 563 
 564         pdata->led_config = &cfg[0];
 565         pdata->num_channels = num_channels;
 566 
 567         for_each_child_of_node(np, child) {
 568                 cfg[i].chan_nr = i;
 569 
 570                 of_property_read_string(child, "chan-name", &cfg[i].name);
 571                 of_property_read_u8(child, "led-cur", &cfg[i].led_current);
 572                 of_property_read_u8(child, "max-cur", &cfg[i].max_current);
 573                 cfg[i].default_trigger =
 574                         of_get_property(child, "linux,default-trigger", NULL);
 575 
 576                 i++;
 577         }
 578 
 579         of_property_read_string(np, "label", &pdata->label);
 580         of_property_read_u8(np, "clock-mode", &pdata->clock_mode);
 581 
 582         pdata->enable_gpio = of_get_named_gpio(np, "enable-gpio", 0);
 583 
 584         /* LP8501 specific */
 585         of_property_read_u8(np, "pwr-sel", (u8 *)&pdata->pwr_sel);
 586 
 587         return pdata;
 588 }
 589 EXPORT_SYMBOL_GPL(lp55xx_of_populate_pdata);
 590 
 591 MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>");
 592 MODULE_DESCRIPTION("LP55xx Common Driver");
 593 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */