1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Awinic AW20036/AW20054/AW20072/AW20108 LED driver 4 * 5 * Copyright (c) 2023, SberDevices. All Rights Reserved. 6 * 7 * Author: Martin Kurbanov <mmkurbanov@sberdevices.ru> 8 */ 9 10 #include <linux/bitfield.h> 11 #include <linux/bits.h> 12 #include <linux/container_of.h> 13 #include <linux/gpio/consumer.h> 14 #include <linux/i2c.h> 15 #include <linux/leds.h> 16 #include <linux/mod_devicetable.h> 17 #include <linux/module.h> 18 #include <linux/mutex.h> 19 #include <linux/regmap.h> 20 #include <linux/time.h> 21 #include <linux/units.h> 22 23 #define AW200XX_DIM_MAX (BIT(6) - 1) 24 #define AW200XX_FADE_MAX (BIT(8) - 1) 25 #define AW200XX_IMAX_DEFAULT_uA 60000 26 #define AW200XX_IMAX_MAX_uA 160000 27 #define AW200XX_IMAX_MIN_uA 3300 28 29 /* Page 0 */ 30 #define AW200XX_REG_PAGE0_BASE 0xc000 31 32 /* Select page register */ 33 #define AW200XX_REG_PAGE 0xF0 34 #define AW200XX_PAGE_MASK (GENMASK(7, 6) | GENMASK(2, 0)) 35 #define AW200XX_PAGE_SHIFT 0 36 #define AW200XX_NUM_PAGES 6 37 #define AW200XX_PAGE_SIZE 256 38 #define AW200XX_REG(page, reg) \ 39 (AW200XX_REG_PAGE0_BASE + (page) * AW200XX_PAGE_SIZE + (reg)) 40 #define AW200XX_REG_MAX \ 41 AW200XX_REG(AW200XX_NUM_PAGES - 1, AW200XX_PAGE_SIZE - 1) 42 #define AW200XX_PAGE0 0 43 #define AW200XX_PAGE1 1 44 #define AW200XX_PAGE2 2 45 #define AW200XX_PAGE3 3 46 #define AW200XX_PAGE4 4 47 #define AW200XX_PAGE5 5 48 49 /* Chip ID register */ 50 #define AW200XX_REG_IDR AW200XX_REG(AW200XX_PAGE0, 0x00) 51 #define AW200XX_IDR_CHIPID 0x18 52 53 /* Sleep mode register */ 54 #define AW200XX_REG_SLPCR AW200XX_REG(AW200XX_PAGE0, 0x01) 55 #define AW200XX_SLPCR_ACTIVE 0x00 56 57 /* Reset register */ 58 #define AW200XX_REG_RSTR AW200XX_REG(AW200XX_PAGE0, 0x02) 59 #define AW200XX_RSTR_RESET 0x01 60 61 /* Global current configuration register */ 62 #define AW200XX_REG_GCCR AW200XX_REG(AW200XX_PAGE0, 0x03) 63 #define AW200XX_GCCR_IMAX_MASK GENMASK(7, 4) 64 #define AW200XX_GCCR_IMAX(x) ((x) << 4) 65 #define AW200XX_GCCR_ALLON BIT(3) 66 67 /* Fast clear display control register */ 68 #define AW200XX_REG_FCD AW200XX_REG(AW200XX_PAGE0, 0x04) 69 #define AW200XX_FCD_CLEAR 0x01 70 71 /* Display size configuration */ 72 #define AW200XX_REG_DSIZE AW200XX_REG(AW200XX_PAGE0, 0x80) 73 #define AW200XX_DSIZE_COLUMNS_MAX 12 74 75 #define AW200XX_LED2REG(x, columns) \ 76 ((x) + (((x) / (columns)) * (AW200XX_DSIZE_COLUMNS_MAX - (columns)))) 77 78 /* DIM current configuration register on page 1 */ 79 #define AW200XX_REG_DIM_PAGE1(x, columns) \ 80 AW200XX_REG(AW200XX_PAGE1, AW200XX_LED2REG(x, columns)) 81 82 /* 83 * DIM current configuration register (page 4). 84 * The even address for current DIM configuration. 85 * The odd address for current FADE configuration 86 */ 87 #define AW200XX_REG_DIM(x, columns) \ 88 AW200XX_REG(AW200XX_PAGE4, AW200XX_LED2REG(x, columns) * 2) 89 #define AW200XX_REG_DIM2FADE(x) ((x) + 1) 90 #define AW200XX_REG_FADE2DIM(fade) \ 91 DIV_ROUND_UP((fade) * AW200XX_DIM_MAX, AW200XX_FADE_MAX) 92 93 /* 94 * Duty ratio of display scan (see p.15 of datasheet for formula): 95 * duty = (592us / 600.5us) * (1 / (display_rows + 1)) 96 * 97 * Multiply to 1000 (MILLI) to improve the accuracy of calculations. 98 */ 99 #define AW200XX_DUTY_RATIO(rows) \ 100 (((592UL * USEC_PER_SEC) / 600500UL) * (MILLI / (rows)) / MILLI) 101 102 struct aw200xx_chipdef { 103 u32 channels; 104 u32 display_size_rows_max; 105 u32 display_size_columns; 106 }; 107 108 struct aw200xx_led { 109 struct led_classdev cdev; 110 struct aw200xx *chip; 111 int dim; 112 u32 num; 113 }; 114 115 struct aw200xx { 116 const struct aw200xx_chipdef *cdef; 117 struct i2c_client *client; 118 struct regmap *regmap; 119 struct mutex mutex; 120 u32 num_leds; 121 u32 display_rows; 122 struct gpio_desc *hwen; 123 struct aw200xx_led leds[] __counted_by(num_leds); 124 }; 125 126 static ssize_t dim_show(struct device *dev, struct device_attribute *devattr, 127 char *buf) 128 { 129 struct led_classdev *cdev = dev_get_drvdata(dev); 130 struct aw200xx_led *led = container_of(cdev, struct aw200xx_led, cdev); 131 int dim = led->dim; 132 133 if (dim < 0) 134 return sysfs_emit(buf, "auto\n"); 135 136 return sysfs_emit(buf, "%d\n", dim); 137 } 138 139 static ssize_t dim_store(struct device *dev, struct device_attribute *devattr, 140 const char *buf, size_t count) 141 { 142 struct led_classdev *cdev = dev_get_drvdata(dev); 143 struct aw200xx_led *led = container_of(cdev, struct aw200xx_led, cdev); 144 struct aw200xx *chip = led->chip; 145 u32 columns = chip->cdef->display_size_columns; 146 int dim; 147 ssize_t ret; 148 149 if (sysfs_streq(buf, "auto")) { 150 dim = -1; 151 } else { 152 ret = kstrtoint(buf, 0, &dim); 153 if (ret) 154 return ret; 155 156 if (dim > AW200XX_DIM_MAX) 157 return -EINVAL; 158 } 159 160 mutex_lock(&chip->mutex); 161 162 if (dim >= 0) { 163 ret = regmap_write(chip->regmap, 164 AW200XX_REG_DIM_PAGE1(led->num, columns), 165 dim); 166 if (ret) 167 goto out_unlock; 168 } 169 170 led->dim = dim; 171 ret = count; 172 173 out_unlock: 174 mutex_unlock(&chip->mutex); 175 return ret; 176 } 177 static DEVICE_ATTR_RW(dim); 178 179 static struct attribute *dim_attrs[] = { 180 &dev_attr_dim.attr, 181 NULL 182 }; 183 ATTRIBUTE_GROUPS(dim); 184 185 static int aw200xx_brightness_set(struct led_classdev *cdev, 186 enum led_brightness brightness) 187 { 188 struct aw200xx_led *led = container_of(cdev, struct aw200xx_led, cdev); 189 struct aw200xx *chip = led->chip; 190 int dim; 191 u32 reg; 192 int ret; 193 194 mutex_lock(&chip->mutex); 195 196 reg = AW200XX_REG_DIM(led->num, chip->cdef->display_size_columns); 197 198 dim = led->dim; 199 if (dim < 0) 200 dim = AW200XX_REG_FADE2DIM(brightness); 201 202 ret = regmap_write(chip->regmap, reg, dim); 203 if (ret) 204 goto out_unlock; 205 206 ret = regmap_write(chip->regmap, 207 AW200XX_REG_DIM2FADE(reg), brightness); 208 209 out_unlock: 210 mutex_unlock(&chip->mutex); 211 212 return ret; 213 } 214 215 static u32 aw200xx_imax_from_global(const struct aw200xx *const chip, 216 u32 global_imax_uA) 217 { 218 u64 led_imax_uA; 219 220 /* 221 * The output current of each LED (see p.14 of datasheet for formula): 222 * Iled = Imax * (dim / 63) * ((fade + 1) / 256) * duty 223 * 224 * The value of duty is determined by the following formula: 225 * duty = (592us / 600.5us) * (1 / (display_rows + 1)) 226 * 227 * Calculated for the maximum values of fade and dim. 228 * We divide by 1000 because we earlier multiplied by 1000 to improve 229 * accuracy when calculating the duty. 230 */ 231 led_imax_uA = global_imax_uA * AW200XX_DUTY_RATIO(chip->display_rows); 232 do_div(led_imax_uA, MILLI); 233 234 return led_imax_uA; 235 } 236 237 static u32 aw200xx_imax_to_global(const struct aw200xx *const chip, 238 u32 led_imax_uA) 239 { 240 u32 duty = AW200XX_DUTY_RATIO(chip->display_rows); 241 242 /* The output current of each LED (see p.14 of datasheet for formula) */ 243 return (led_imax_uA * 1000U) / duty; 244 } 245 246 #define AW200XX_IMAX_MULTIPLIER1 10000 247 #define AW200XX_IMAX_MULTIPLIER2 3333 248 #define AW200XX_IMAX_BASE_VAL1 0 249 #define AW200XX_IMAX_BASE_VAL2 8 250 251 /* 252 * The AW200XX has a 4-bit register (GCCR) to configure the global current, 253 * which ranges from 3.3mA to 160mA. The following table indicates the values 254 * of the global current, divided into two parts: 255 * 256 * +-----------+-----------------+-----------+-----------------+ 257 * | reg value | global max (mA) | reg value | global max (mA) | 258 * +-----------+-----------------+-----------+-----------------+ 259 * | 0 | 10 | 8 | 3.3 | 260 * | 1 | 20 | 9 | 6.7 | 261 * | 2 | 30 | 10 | 10 | 262 * | 3 | 40 | 11 | 13.3 | 263 * | 4 | 60 | 12 | 20 | 264 * | 5 | 80 | 13 | 26.7 | 265 * | 6 | 120 | 14 | 40 | 266 * | 7 | 160 | 15 | 53.3 | 267 * +-----------+-----------------+-----------+-----------------+ 268 * 269 * The left part with a multiplier of 10, and the right part with a multiplier 270 * of 3.3. 271 * So we have two formulas to calculate the global current: 272 * for the left part of the table: 273 * imax = coefficient * 10 274 * 275 * for the right part of the table: 276 * imax = coefficient * 3.3 277 * 278 * The coefficient table consists of the following values: 279 * 1, 2, 3, 4, 6, 8, 12, 16. 280 */ 281 static int aw200xx_set_imax(const struct aw200xx *const chip, 282 u32 led_imax_uA) 283 { 284 u32 g_imax_uA = aw200xx_imax_to_global(chip, led_imax_uA); 285 static const u32 coeff_table[] = {1, 2, 3, 4, 6, 8, 12, 16}; 286 u32 gccr_imax = UINT_MAX; 287 u32 cur_imax = 0; 288 int i; 289 290 for (i = 0; i < ARRAY_SIZE(coeff_table); i++) { 291 u32 imax; 292 293 /* select closest ones */ 294 imax = coeff_table[i] * AW200XX_IMAX_MULTIPLIER1; 295 if (g_imax_uA >= imax && imax > cur_imax) { 296 cur_imax = imax; 297 gccr_imax = i + AW200XX_IMAX_BASE_VAL1; 298 } 299 300 imax = coeff_table[i] * AW200XX_IMAX_MULTIPLIER2; 301 imax = DIV_ROUND_CLOSEST(imax, 100) * 100; 302 if (g_imax_uA >= imax && imax > cur_imax) { 303 cur_imax = imax; 304 gccr_imax = i + AW200XX_IMAX_BASE_VAL2; 305 } 306 } 307 308 if (gccr_imax == UINT_MAX) 309 return -EINVAL; 310 311 return regmap_update_bits(chip->regmap, AW200XX_REG_GCCR, 312 AW200XX_GCCR_IMAX_MASK, 313 AW200XX_GCCR_IMAX(gccr_imax)); 314 } 315 316 static int aw200xx_chip_reset(const struct aw200xx *const chip) 317 { 318 int ret; 319 320 ret = regmap_write(chip->regmap, AW200XX_REG_RSTR, AW200XX_RSTR_RESET); 321 if (ret) 322 return ret; 323 324 /* According to the datasheet software reset takes at least 1ms */ 325 fsleep(1000); 326 327 regcache_mark_dirty(chip->regmap); 328 return regmap_write(chip->regmap, AW200XX_REG_FCD, AW200XX_FCD_CLEAR); 329 } 330 331 static int aw200xx_chip_init(const struct aw200xx *const chip) 332 { 333 int ret; 334 335 ret = regmap_write(chip->regmap, AW200XX_REG_DSIZE, 336 chip->display_rows - 1); 337 if (ret) 338 return ret; 339 340 ret = regmap_write(chip->regmap, AW200XX_REG_SLPCR, 341 AW200XX_SLPCR_ACTIVE); 342 if (ret) 343 return ret; 344 345 return regmap_update_bits(chip->regmap, AW200XX_REG_GCCR, 346 AW200XX_GCCR_ALLON, AW200XX_GCCR_ALLON); 347 } 348 349 static int aw200xx_chip_check(const struct aw200xx *const chip) 350 { 351 struct device *dev = &chip->client->dev; 352 u32 chipid; 353 int ret; 354 355 ret = regmap_read(chip->regmap, AW200XX_REG_IDR, &chipid); 356 if (ret) 357 return dev_err_probe(dev, ret, "Failed to read chip ID\n"); 358 359 if (chipid != AW200XX_IDR_CHIPID) 360 return dev_err_probe(dev, -ENODEV, 361 "Chip reported wrong ID: %x\n", chipid); 362 363 return 0; 364 } 365 366 static void aw200xx_enable(const struct aw200xx *const chip) 367 { 368 gpiod_set_value_cansleep(chip->hwen, 1); 369 370 /* 371 * After HWEN pin set high the chip begins to load the OTP information, 372 * which takes 200us to complete. About 200us wait time is needed for 373 * internal oscillator startup and display SRAM initialization. After 374 * display SRAM initialization, the registers in page1 to page5 can be 375 * configured via i2c interface. 376 */ 377 fsleep(400); 378 } 379 380 static void aw200xx_disable(const struct aw200xx *const chip) 381 { 382 return gpiod_set_value_cansleep(chip->hwen, 0); 383 } 384 385 static int aw200xx_probe_get_display_rows(struct device *dev, 386 struct aw200xx *chip) 387 { 388 struct fwnode_handle *child; 389 u32 max_source = 0; 390 391 device_for_each_child_node(dev, child) { 392 u32 source; 393 int ret; 394 395 ret = fwnode_property_read_u32(child, "reg", &source); 396 if (ret || source >= chip->cdef->channels) 397 continue; 398 399 max_source = max(max_source, source); 400 } 401 402 if (max_source == 0) 403 return -EINVAL; 404 405 chip->display_rows = max_source / chip->cdef->display_size_columns + 1; 406 407 return 0; 408 } 409 410 static int aw200xx_probe_fw(struct device *dev, struct aw200xx *chip) 411 { 412 u32 current_min, current_max, min_uA; 413 int ret; 414 int i; 415 416 ret = aw200xx_probe_get_display_rows(dev, chip); 417 if (ret) 418 return dev_err_probe(dev, ret, 419 "No valid led definitions found\n"); 420 421 current_max = aw200xx_imax_from_global(chip, AW200XX_IMAX_MAX_uA); 422 current_min = aw200xx_imax_from_global(chip, AW200XX_IMAX_MIN_uA); 423 min_uA = UINT_MAX; 424 i = 0; 425 426 device_for_each_child_node_scoped(dev, child) { 427 struct led_init_data init_data = {}; 428 struct aw200xx_led *led; 429 u32 source, imax; 430 431 ret = fwnode_property_read_u32(child, "reg", &source); 432 if (ret) { 433 dev_err(dev, "Missing reg property\n"); 434 chip->num_leds--; 435 continue; 436 } 437 438 if (source >= chip->cdef->channels) { 439 dev_err(dev, "LED reg %u out of range (max %u)\n", 440 source, chip->cdef->channels); 441 chip->num_leds--; 442 continue; 443 } 444 445 ret = fwnode_property_read_u32(child, "led-max-microamp", 446 &imax); 447 if (ret) { 448 dev_info(&chip->client->dev, 449 "DT property led-max-microamp is missing\n"); 450 } else if (imax < current_min || imax > current_max) { 451 dev_err(dev, "Invalid value %u for led-max-microamp\n", 452 imax); 453 chip->num_leds--; 454 continue; 455 } else { 456 min_uA = min(min_uA, imax); 457 } 458 459 led = &chip->leds[i]; 460 led->dim = -1; 461 led->num = source; 462 led->chip = chip; 463 led->cdev.brightness_set_blocking = aw200xx_brightness_set; 464 led->cdev.max_brightness = AW200XX_FADE_MAX; 465 led->cdev.groups = dim_groups; 466 init_data.fwnode = child; 467 468 ret = devm_led_classdev_register_ext(dev, &led->cdev, 469 &init_data); 470 if (ret) 471 break; 472 473 i++; 474 } 475 476 if (!chip->num_leds) 477 return -EINVAL; 478 479 if (min_uA == UINT_MAX) { 480 min_uA = aw200xx_imax_from_global(chip, 481 AW200XX_IMAX_DEFAULT_uA); 482 } 483 484 return aw200xx_set_imax(chip, min_uA); 485 } 486 487 static const struct regmap_range_cfg aw200xx_ranges[] = { 488 { 489 .name = "aw200xx", 490 .range_min = 0, 491 .range_max = AW200XX_REG_MAX, 492 .selector_reg = AW200XX_REG_PAGE, 493 .selector_mask = AW200XX_PAGE_MASK, 494 .selector_shift = AW200XX_PAGE_SHIFT, 495 .window_start = 0, 496 .window_len = AW200XX_PAGE_SIZE, 497 }, 498 }; 499 500 static const struct regmap_range aw200xx_writeonly_ranges[] = { 501 regmap_reg_range(AW200XX_REG(AW200XX_PAGE1, 0x00), AW200XX_REG_MAX), 502 }; 503 504 static const struct regmap_access_table aw200xx_readable_table = { 505 .no_ranges = aw200xx_writeonly_ranges, 506 .n_no_ranges = ARRAY_SIZE(aw200xx_writeonly_ranges), 507 }; 508 509 static const struct regmap_range aw200xx_readonly_ranges[] = { 510 regmap_reg_range(AW200XX_REG_IDR, AW200XX_REG_IDR), 511 }; 512 513 static const struct regmap_access_table aw200xx_writeable_table = { 514 .no_ranges = aw200xx_readonly_ranges, 515 .n_no_ranges = ARRAY_SIZE(aw200xx_readonly_ranges), 516 }; 517 518 static const struct regmap_config aw200xx_regmap_config = { 519 .reg_bits = 8, 520 .val_bits = 8, 521 .max_register = AW200XX_REG_MAX, 522 .ranges = aw200xx_ranges, 523 .num_ranges = ARRAY_SIZE(aw200xx_ranges), 524 .rd_table = &aw200xx_readable_table, 525 .wr_table = &aw200xx_writeable_table, 526 .cache_type = REGCACHE_MAPLE, 527 .disable_locking = true, 528 }; 529 530 static void aw200xx_chip_reset_action(void *data) 531 { 532 aw200xx_chip_reset(data); 533 } 534 535 static void aw200xx_disable_action(void *data) 536 { 537 aw200xx_disable(data); 538 } 539 540 static int aw200xx_probe(struct i2c_client *client) 541 { 542 const struct aw200xx_chipdef *cdef; 543 struct aw200xx *chip; 544 int count; 545 int ret; 546 547 cdef = device_get_match_data(&client->dev); 548 if (!cdef) 549 return -ENODEV; 550 551 count = device_get_child_node_count(&client->dev); 552 if (!count || count > cdef->channels) 553 return dev_err_probe(&client->dev, -EINVAL, 554 "Incorrect number of leds (%d)", count); 555 556 chip = devm_kzalloc(&client->dev, struct_size(chip, leds, count), 557 GFP_KERNEL); 558 if (!chip) 559 return -ENOMEM; 560 561 chip->cdef = cdef; 562 chip->num_leds = count; 563 chip->client = client; 564 i2c_set_clientdata(client, chip); 565 566 chip->regmap = devm_regmap_init_i2c(client, &aw200xx_regmap_config); 567 if (IS_ERR(chip->regmap)) 568 return PTR_ERR(chip->regmap); 569 570 chip->hwen = devm_gpiod_get_optional(&client->dev, "enable", 571 GPIOD_OUT_HIGH); 572 if (IS_ERR(chip->hwen)) 573 return dev_err_probe(&client->dev, PTR_ERR(chip->hwen), 574 "Cannot get enable GPIO"); 575 576 aw200xx_enable(chip); 577 578 ret = devm_add_action(&client->dev, aw200xx_disable_action, chip); 579 if (ret) 580 return ret; 581 582 ret = aw200xx_chip_check(chip); 583 if (ret) 584 return ret; 585 586 ret = devm_mutex_init(&client->dev, &chip->mutex); 587 if (ret) 588 return ret; 589 590 /* Need a lock now since after call aw200xx_probe_fw, sysfs nodes created */ 591 mutex_lock(&chip->mutex); 592 593 ret = aw200xx_chip_reset(chip); 594 if (ret) 595 goto out_unlock; 596 597 ret = devm_add_action(&client->dev, aw200xx_chip_reset_action, chip); 598 if (ret) 599 goto out_unlock; 600 601 ret = aw200xx_probe_fw(&client->dev, chip); 602 if (ret) 603 goto out_unlock; 604 605 ret = aw200xx_chip_init(chip); 606 607 out_unlock: 608 if (ret) 609 aw200xx_disable(chip); 610 611 mutex_unlock(&chip->mutex); 612 return ret; 613 } 614 615 static const struct aw200xx_chipdef aw20036_cdef = { 616 .channels = 36, 617 .display_size_rows_max = 3, 618 .display_size_columns = 12, 619 }; 620 621 static const struct aw200xx_chipdef aw20054_cdef = { 622 .channels = 54, 623 .display_size_rows_max = 6, 624 .display_size_columns = 9, 625 }; 626 627 static const struct aw200xx_chipdef aw20072_cdef = { 628 .channels = 72, 629 .display_size_rows_max = 6, 630 .display_size_columns = 12, 631 }; 632 633 static const struct aw200xx_chipdef aw20108_cdef = { 634 .channels = 108, 635 .display_size_rows_max = 9, 636 .display_size_columns = 12, 637 }; 638 639 static const struct i2c_device_id aw200xx_id[] = { 640 { "aw20036" }, 641 { "aw20054" }, 642 { "aw20072" }, 643 { "aw20108" }, 644 {} 645 }; 646 MODULE_DEVICE_TABLE(i2c, aw200xx_id); 647 648 static const struct of_device_id aw200xx_match_table[] = { 649 { .compatible = "awinic,aw20036", .data = &aw20036_cdef, }, 650 { .compatible = "awinic,aw20054", .data = &aw20054_cdef, }, 651 { .compatible = "awinic,aw20072", .data = &aw20072_cdef, }, 652 { .compatible = "awinic,aw20108", .data = &aw20108_cdef, }, 653 {} 654 }; 655 MODULE_DEVICE_TABLE(of, aw200xx_match_table); 656 657 static struct i2c_driver aw200xx_driver = { 658 .driver = { 659 .name = "aw200xx", 660 .of_match_table = aw200xx_match_table, 661 }, 662 .probe = aw200xx_probe, 663 .id_table = aw200xx_id, 664 }; 665 module_i2c_driver(aw200xx_driver); 666 667 MODULE_AUTHOR("Martin Kurbanov <mmkurbanov@sberdevices.ru>"); 668 MODULE_DESCRIPTION("AW200XX LED driver"); 669 MODULE_LICENSE("GPL"); 670