Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.2-rc6 711 lines 16 kB view raw
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/consumer.h> 21 22#include "leds-lp55xx-common.h" 23 24/* External clock rate */ 25#define LP55XX_CLK_32K 32768 26 27static struct lp55xx_led *cdev_to_lp55xx_led(struct led_classdev *cdev) 28{ 29 return container_of(cdev, struct lp55xx_led, cdev); 30} 31 32static struct lp55xx_led *dev_to_lp55xx_led(struct device *dev) 33{ 34 return cdev_to_lp55xx_led(dev_get_drvdata(dev)); 35} 36 37static struct lp55xx_led *mcled_cdev_to_led(struct led_classdev_mc *mc_cdev) 38{ 39 return container_of(mc_cdev, struct lp55xx_led, mc_cdev); 40} 41 42static void lp55xx_reset_device(struct lp55xx_chip *chip) 43{ 44 struct lp55xx_device_config *cfg = chip->cfg; 45 u8 addr = cfg->reset.addr; 46 u8 val = cfg->reset.val; 47 48 /* no error checking here because no ACK from the device after reset */ 49 lp55xx_write(chip, addr, val); 50} 51 52static int lp55xx_detect_device(struct lp55xx_chip *chip) 53{ 54 struct lp55xx_device_config *cfg = chip->cfg; 55 u8 addr = cfg->enable.addr; 56 u8 val = cfg->enable.val; 57 int ret; 58 59 ret = lp55xx_write(chip, addr, val); 60 if (ret) 61 return ret; 62 63 usleep_range(1000, 2000); 64 65 ret = lp55xx_read(chip, addr, &val); 66 if (ret) 67 return ret; 68 69 if (val != cfg->enable.val) 70 return -ENODEV; 71 72 return 0; 73} 74 75static int lp55xx_post_init_device(struct lp55xx_chip *chip) 76{ 77 struct lp55xx_device_config *cfg = chip->cfg; 78 79 if (!cfg->post_init_device) 80 return 0; 81 82 return cfg->post_init_device(chip); 83} 84 85static ssize_t led_current_show(struct device *dev, 86 struct device_attribute *attr, 87 char *buf) 88{ 89 struct lp55xx_led *led = dev_to_lp55xx_led(dev); 90 91 return sysfs_emit(buf, "%d\n", led->led_current); 92} 93 94static ssize_t led_current_store(struct device *dev, 95 struct device_attribute *attr, 96 const char *buf, size_t len) 97{ 98 struct lp55xx_led *led = dev_to_lp55xx_led(dev); 99 struct lp55xx_chip *chip = led->chip; 100 unsigned long curr; 101 102 if (kstrtoul(buf, 0, &curr)) 103 return -EINVAL; 104 105 if (curr > led->max_current) 106 return -EINVAL; 107 108 if (!chip->cfg->set_led_current) 109 return len; 110 111 mutex_lock(&chip->lock); 112 chip->cfg->set_led_current(led, (u8)curr); 113 mutex_unlock(&chip->lock); 114 115 return len; 116} 117 118static ssize_t max_current_show(struct device *dev, 119 struct device_attribute *attr, 120 char *buf) 121{ 122 struct lp55xx_led *led = dev_to_lp55xx_led(dev); 123 124 return sysfs_emit(buf, "%d\n", led->max_current); 125} 126 127static DEVICE_ATTR_RW(led_current); 128static DEVICE_ATTR_RO(max_current); 129 130static struct attribute *lp55xx_led_attrs[] = { 131 &dev_attr_led_current.attr, 132 &dev_attr_max_current.attr, 133 NULL, 134}; 135ATTRIBUTE_GROUPS(lp55xx_led); 136 137static int lp55xx_set_mc_brightness(struct led_classdev *cdev, 138 enum led_brightness brightness) 139{ 140 struct led_classdev_mc *mc_dev = lcdev_to_mccdev(cdev); 141 struct lp55xx_led *led = mcled_cdev_to_led(mc_dev); 142 struct lp55xx_device_config *cfg = led->chip->cfg; 143 144 led_mc_calc_color_components(&led->mc_cdev, brightness); 145 return cfg->multicolor_brightness_fn(led); 146 147} 148 149static int lp55xx_set_brightness(struct led_classdev *cdev, 150 enum led_brightness brightness) 151{ 152 struct lp55xx_led *led = cdev_to_lp55xx_led(cdev); 153 struct lp55xx_device_config *cfg = led->chip->cfg; 154 155 led->brightness = (u8)brightness; 156 return cfg->brightness_fn(led); 157} 158 159static int lp55xx_init_led(struct lp55xx_led *led, 160 struct lp55xx_chip *chip, int chan) 161{ 162 struct lp55xx_platform_data *pdata = chip->pdata; 163 struct lp55xx_device_config *cfg = chip->cfg; 164 struct device *dev = &chip->cl->dev; 165 int max_channel = cfg->max_channel; 166 struct mc_subled *mc_led_info; 167 struct led_classdev *led_cdev; 168 char name[32]; 169 int i; 170 int ret; 171 172 if (chan >= max_channel) { 173 dev_err(dev, "invalid channel: %d / %d\n", chan, max_channel); 174 return -EINVAL; 175 } 176 177 if (pdata->led_config[chan].led_current == 0) 178 return 0; 179 180 if (pdata->led_config[chan].name) { 181 led->cdev.name = pdata->led_config[chan].name; 182 } else { 183 snprintf(name, sizeof(name), "%s:channel%d", 184 pdata->label ? : chip->cl->name, chan); 185 led->cdev.name = name; 186 } 187 188 if (pdata->led_config[chan].num_colors > 1) { 189 mc_led_info = devm_kcalloc(dev, 190 pdata->led_config[chan].num_colors, 191 sizeof(*mc_led_info), GFP_KERNEL); 192 if (!mc_led_info) 193 return -ENOMEM; 194 195 led_cdev = &led->mc_cdev.led_cdev; 196 led_cdev->name = led->cdev.name; 197 led_cdev->brightness_set_blocking = lp55xx_set_mc_brightness; 198 led->mc_cdev.num_colors = pdata->led_config[chan].num_colors; 199 for (i = 0; i < led->mc_cdev.num_colors; i++) { 200 mc_led_info[i].color_index = 201 pdata->led_config[chan].color_id[i]; 202 mc_led_info[i].channel = 203 pdata->led_config[chan].output_num[i]; 204 } 205 206 led->mc_cdev.subled_info = mc_led_info; 207 } else { 208 led->cdev.brightness_set_blocking = lp55xx_set_brightness; 209 } 210 211 led->cdev.groups = lp55xx_led_groups; 212 led->cdev.default_trigger = pdata->led_config[chan].default_trigger; 213 led->led_current = pdata->led_config[chan].led_current; 214 led->max_current = pdata->led_config[chan].max_current; 215 led->chan_nr = pdata->led_config[chan].chan_nr; 216 217 if (led->chan_nr >= max_channel) { 218 dev_err(dev, "Use channel numbers between 0 and %d\n", 219 max_channel - 1); 220 return -EINVAL; 221 } 222 223 if (pdata->led_config[chan].num_colors > 1) 224 ret = devm_led_classdev_multicolor_register(dev, &led->mc_cdev); 225 else 226 ret = devm_led_classdev_register(dev, &led->cdev); 227 228 if (ret) { 229 dev_err(dev, "led register err: %d\n", ret); 230 return ret; 231 } 232 233 return 0; 234} 235 236static void lp55xx_firmware_loaded(const struct firmware *fw, void *context) 237{ 238 struct lp55xx_chip *chip = context; 239 struct device *dev = &chip->cl->dev; 240 enum lp55xx_engine_index idx = chip->engine_idx; 241 242 if (!fw) { 243 dev_err(dev, "firmware request failed\n"); 244 return; 245 } 246 247 /* handling firmware data is chip dependent */ 248 mutex_lock(&chip->lock); 249 250 chip->engines[idx - 1].mode = LP55XX_ENGINE_LOAD; 251 chip->fw = fw; 252 if (chip->cfg->firmware_cb) 253 chip->cfg->firmware_cb(chip); 254 255 mutex_unlock(&chip->lock); 256 257 /* firmware should be released for other channel use */ 258 release_firmware(chip->fw); 259 chip->fw = NULL; 260} 261 262static int lp55xx_request_firmware(struct lp55xx_chip *chip) 263{ 264 const char *name = chip->cl->name; 265 struct device *dev = &chip->cl->dev; 266 267 return request_firmware_nowait(THIS_MODULE, false, name, dev, 268 GFP_KERNEL, chip, lp55xx_firmware_loaded); 269} 270 271static ssize_t select_engine_show(struct device *dev, 272 struct device_attribute *attr, 273 char *buf) 274{ 275 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 276 struct lp55xx_chip *chip = led->chip; 277 278 return sprintf(buf, "%d\n", chip->engine_idx); 279} 280 281static ssize_t select_engine_store(struct device *dev, 282 struct device_attribute *attr, 283 const char *buf, size_t len) 284{ 285 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 286 struct lp55xx_chip *chip = led->chip; 287 unsigned long val; 288 int ret; 289 290 if (kstrtoul(buf, 0, &val)) 291 return -EINVAL; 292 293 /* select the engine to be run */ 294 295 switch (val) { 296 case LP55XX_ENGINE_1: 297 case LP55XX_ENGINE_2: 298 case LP55XX_ENGINE_3: 299 mutex_lock(&chip->lock); 300 chip->engine_idx = val; 301 ret = lp55xx_request_firmware(chip); 302 mutex_unlock(&chip->lock); 303 break; 304 default: 305 dev_err(dev, "%lu: invalid engine index. (1, 2, 3)\n", val); 306 return -EINVAL; 307 } 308 309 if (ret) { 310 dev_err(dev, "request firmware err: %d\n", ret); 311 return ret; 312 } 313 314 return len; 315} 316 317static inline void lp55xx_run_engine(struct lp55xx_chip *chip, bool start) 318{ 319 if (chip->cfg->run_engine) 320 chip->cfg->run_engine(chip, start); 321} 322 323static ssize_t run_engine_store(struct device *dev, 324 struct device_attribute *attr, 325 const char *buf, size_t len) 326{ 327 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 328 struct lp55xx_chip *chip = led->chip; 329 unsigned long val; 330 331 if (kstrtoul(buf, 0, &val)) 332 return -EINVAL; 333 334 /* run or stop the selected engine */ 335 336 if (val <= 0) { 337 lp55xx_run_engine(chip, false); 338 return len; 339 } 340 341 mutex_lock(&chip->lock); 342 lp55xx_run_engine(chip, true); 343 mutex_unlock(&chip->lock); 344 345 return len; 346} 347 348static DEVICE_ATTR_RW(select_engine); 349static DEVICE_ATTR_WO(run_engine); 350 351static struct attribute *lp55xx_engine_attributes[] = { 352 &dev_attr_select_engine.attr, 353 &dev_attr_run_engine.attr, 354 NULL, 355}; 356 357static const struct attribute_group lp55xx_engine_attr_group = { 358 .attrs = lp55xx_engine_attributes, 359}; 360 361int lp55xx_write(struct lp55xx_chip *chip, u8 reg, u8 val) 362{ 363 return i2c_smbus_write_byte_data(chip->cl, reg, val); 364} 365EXPORT_SYMBOL_GPL(lp55xx_write); 366 367int lp55xx_read(struct lp55xx_chip *chip, u8 reg, u8 *val) 368{ 369 s32 ret; 370 371 ret = i2c_smbus_read_byte_data(chip->cl, reg); 372 if (ret < 0) 373 return ret; 374 375 *val = ret; 376 return 0; 377} 378EXPORT_SYMBOL_GPL(lp55xx_read); 379 380int lp55xx_update_bits(struct lp55xx_chip *chip, u8 reg, u8 mask, u8 val) 381{ 382 int ret; 383 u8 tmp; 384 385 ret = lp55xx_read(chip, reg, &tmp); 386 if (ret) 387 return ret; 388 389 tmp &= ~mask; 390 tmp |= val & mask; 391 392 return lp55xx_write(chip, reg, tmp); 393} 394EXPORT_SYMBOL_GPL(lp55xx_update_bits); 395 396bool lp55xx_is_extclk_used(struct lp55xx_chip *chip) 397{ 398 struct clk *clk; 399 int err; 400 401 clk = devm_clk_get(&chip->cl->dev, "32k_clk"); 402 if (IS_ERR(clk)) 403 goto use_internal_clk; 404 405 err = clk_prepare_enable(clk); 406 if (err) 407 goto use_internal_clk; 408 409 if (clk_get_rate(clk) != LP55XX_CLK_32K) { 410 clk_disable_unprepare(clk); 411 goto use_internal_clk; 412 } 413 414 dev_info(&chip->cl->dev, "%dHz external clock used\n", LP55XX_CLK_32K); 415 416 chip->clk = clk; 417 return true; 418 419use_internal_clk: 420 dev_info(&chip->cl->dev, "internal clock used\n"); 421 return false; 422} 423EXPORT_SYMBOL_GPL(lp55xx_is_extclk_used); 424 425int lp55xx_init_device(struct lp55xx_chip *chip) 426{ 427 struct lp55xx_platform_data *pdata; 428 struct lp55xx_device_config *cfg; 429 struct device *dev = &chip->cl->dev; 430 int ret = 0; 431 432 WARN_ON(!chip); 433 434 pdata = chip->pdata; 435 cfg = chip->cfg; 436 437 if (!pdata || !cfg) 438 return -EINVAL; 439 440 if (pdata->enable_gpiod) { 441 gpiod_direction_output(pdata->enable_gpiod, 0); 442 443 gpiod_set_consumer_name(pdata->enable_gpiod, "LP55xx enable"); 444 gpiod_set_value(pdata->enable_gpiod, 0); 445 usleep_range(1000, 2000); /* Keep enable down at least 1ms */ 446 gpiod_set_value(pdata->enable_gpiod, 1); 447 usleep_range(1000, 2000); /* 500us abs min. */ 448 } 449 450 lp55xx_reset_device(chip); 451 452 /* 453 * Exact value is not available. 10 - 20ms 454 * appears to be enough for reset. 455 */ 456 usleep_range(10000, 20000); 457 458 ret = lp55xx_detect_device(chip); 459 if (ret) { 460 dev_err(dev, "device detection err: %d\n", ret); 461 goto err; 462 } 463 464 /* chip specific initialization */ 465 ret = lp55xx_post_init_device(chip); 466 if (ret) { 467 dev_err(dev, "post init device err: %d\n", ret); 468 goto err_post_init; 469 } 470 471 return 0; 472 473err_post_init: 474 lp55xx_deinit_device(chip); 475err: 476 return ret; 477} 478EXPORT_SYMBOL_GPL(lp55xx_init_device); 479 480void lp55xx_deinit_device(struct lp55xx_chip *chip) 481{ 482 struct lp55xx_platform_data *pdata = chip->pdata; 483 484 if (chip->clk) 485 clk_disable_unprepare(chip->clk); 486 487 if (pdata->enable_gpiod) 488 gpiod_set_value(pdata->enable_gpiod, 0); 489} 490EXPORT_SYMBOL_GPL(lp55xx_deinit_device); 491 492int lp55xx_register_leds(struct lp55xx_led *led, struct lp55xx_chip *chip) 493{ 494 struct lp55xx_platform_data *pdata = chip->pdata; 495 struct lp55xx_device_config *cfg = chip->cfg; 496 int num_channels = pdata->num_channels; 497 struct lp55xx_led *each; 498 u8 led_current; 499 int ret; 500 int i; 501 502 if (!cfg->brightness_fn) { 503 dev_err(&chip->cl->dev, "empty brightness configuration\n"); 504 return -EINVAL; 505 } 506 507 for (i = 0; i < num_channels; i++) { 508 509 /* do not initialize channels that are not connected */ 510 if (pdata->led_config[i].led_current == 0) 511 continue; 512 513 led_current = pdata->led_config[i].led_current; 514 each = led + i; 515 ret = lp55xx_init_led(each, chip, i); 516 if (ret) 517 goto err_init_led; 518 519 chip->num_leds++; 520 each->chip = chip; 521 522 /* setting led current at each channel */ 523 if (cfg->set_led_current) 524 cfg->set_led_current(each, led_current); 525 } 526 527 return 0; 528 529err_init_led: 530 return ret; 531} 532EXPORT_SYMBOL_GPL(lp55xx_register_leds); 533 534int lp55xx_register_sysfs(struct lp55xx_chip *chip) 535{ 536 struct device *dev = &chip->cl->dev; 537 struct lp55xx_device_config *cfg = chip->cfg; 538 int ret; 539 540 if (!cfg->run_engine || !cfg->firmware_cb) 541 goto dev_specific_attrs; 542 543 ret = sysfs_create_group(&dev->kobj, &lp55xx_engine_attr_group); 544 if (ret) 545 return ret; 546 547dev_specific_attrs: 548 return cfg->dev_attr_group ? 549 sysfs_create_group(&dev->kobj, cfg->dev_attr_group) : 0; 550} 551EXPORT_SYMBOL_GPL(lp55xx_register_sysfs); 552 553void lp55xx_unregister_sysfs(struct lp55xx_chip *chip) 554{ 555 struct device *dev = &chip->cl->dev; 556 struct lp55xx_device_config *cfg = chip->cfg; 557 558 if (cfg->dev_attr_group) 559 sysfs_remove_group(&dev->kobj, cfg->dev_attr_group); 560 561 sysfs_remove_group(&dev->kobj, &lp55xx_engine_attr_group); 562} 563EXPORT_SYMBOL_GPL(lp55xx_unregister_sysfs); 564 565static int lp55xx_parse_common_child(struct device_node *np, 566 struct lp55xx_led_config *cfg, 567 int led_number, int *chan_nr) 568{ 569 int ret; 570 571 of_property_read_string(np, "chan-name", 572 &cfg[led_number].name); 573 of_property_read_u8(np, "led-cur", 574 &cfg[led_number].led_current); 575 of_property_read_u8(np, "max-cur", 576 &cfg[led_number].max_current); 577 578 ret = of_property_read_u32(np, "reg", chan_nr); 579 if (ret) 580 return ret; 581 582 if (*chan_nr < 0 || *chan_nr > cfg->max_channel) 583 return -EINVAL; 584 585 return 0; 586} 587 588static int lp55xx_parse_multi_led_child(struct device_node *child, 589 struct lp55xx_led_config *cfg, 590 int child_number, int color_number) 591{ 592 int chan_nr, color_id, ret; 593 594 ret = lp55xx_parse_common_child(child, cfg, child_number, &chan_nr); 595 if (ret) 596 return ret; 597 598 ret = of_property_read_u32(child, "color", &color_id); 599 if (ret) 600 return ret; 601 602 cfg[child_number].color_id[color_number] = color_id; 603 cfg[child_number].output_num[color_number] = chan_nr; 604 605 return 0; 606} 607 608static int lp55xx_parse_multi_led(struct device_node *np, 609 struct lp55xx_led_config *cfg, 610 int child_number) 611{ 612 struct device_node *child; 613 int num_colors = 0, ret; 614 615 for_each_available_child_of_node(np, child) { 616 ret = lp55xx_parse_multi_led_child(child, cfg, child_number, 617 num_colors); 618 if (ret) { 619 of_node_put(child); 620 return ret; 621 } 622 num_colors++; 623 } 624 625 cfg[child_number].num_colors = num_colors; 626 627 return 0; 628} 629 630static int lp55xx_parse_logical_led(struct device_node *np, 631 struct lp55xx_led_config *cfg, 632 int child_number) 633{ 634 int led_color, ret; 635 int chan_nr = 0; 636 637 cfg[child_number].default_trigger = 638 of_get_property(np, "linux,default-trigger", NULL); 639 640 ret = of_property_read_u32(np, "color", &led_color); 641 if (ret) 642 return ret; 643 644 if (led_color == LED_COLOR_ID_RGB) 645 return lp55xx_parse_multi_led(np, cfg, child_number); 646 647 ret = lp55xx_parse_common_child(np, cfg, child_number, &chan_nr); 648 if (ret < 0) 649 return ret; 650 651 cfg[child_number].chan_nr = chan_nr; 652 653 return ret; 654} 655 656struct lp55xx_platform_data *lp55xx_of_populate_pdata(struct device *dev, 657 struct device_node *np, 658 struct lp55xx_chip *chip) 659{ 660 struct device_node *child; 661 struct lp55xx_platform_data *pdata; 662 struct lp55xx_led_config *cfg; 663 int num_channels; 664 int i = 0; 665 int ret; 666 667 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); 668 if (!pdata) 669 return ERR_PTR(-ENOMEM); 670 671 num_channels = of_get_available_child_count(np); 672 if (num_channels == 0) { 673 dev_err(dev, "no LED channels\n"); 674 return ERR_PTR(-EINVAL); 675 } 676 677 cfg = devm_kcalloc(dev, num_channels, sizeof(*cfg), GFP_KERNEL); 678 if (!cfg) 679 return ERR_PTR(-ENOMEM); 680 681 pdata->led_config = &cfg[0]; 682 pdata->num_channels = num_channels; 683 cfg->max_channel = chip->cfg->max_channel; 684 685 for_each_available_child_of_node(np, child) { 686 ret = lp55xx_parse_logical_led(child, cfg, i); 687 if (ret) { 688 of_node_put(child); 689 return ERR_PTR(-EINVAL); 690 } 691 i++; 692 } 693 694 of_property_read_string(np, "label", &pdata->label); 695 of_property_read_u8(np, "clock-mode", &pdata->clock_mode); 696 697 pdata->enable_gpiod = devm_gpiod_get_optional(dev, "enable", 698 GPIOD_ASIS); 699 if (IS_ERR(pdata->enable_gpiod)) 700 return ERR_CAST(pdata->enable_gpiod); 701 702 /* LP8501 specific */ 703 of_property_read_u8(np, "pwr-sel", (u8 *)&pdata->pwr_sel); 704 705 return pdata; 706} 707EXPORT_SYMBOL_GPL(lp55xx_of_populate_pdata); 708 709MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>"); 710MODULE_DESCRIPTION("LP55xx Common Driver"); 711MODULE_LICENSE("GPL");