1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2023 Richtek Technology Corp. 4 * 5 * Authors: 6 * ChiYuan Huang <cy_huang@richtek.com> 7 * Alice Chen <alice_chen@richtek.com> 8 */ 9 10 #include <linux/bitfield.h> 11 #include <linux/bitops.h> 12 #include <linux/kernel.h> 13 #include <linux/leds.h> 14 #include <linux/led-class-multicolor.h> 15 #include <linux/linear_range.h> 16 #include <linux/mod_devicetable.h> 17 #include <linux/module.h> 18 #include <linux/mutex.h> 19 #include <linux/platform_device.h> 20 #include <linux/property.h> 21 #include <linux/regmap.h> 22 #include <linux/util_macros.h> 23 24 #include <asm/unaligned.h> 25 26 enum { 27 MT6370_LED_ISNK1 = 0, 28 MT6370_LED_ISNK2, 29 MT6370_LED_ISNK3, 30 MT6370_LED_ISNK4, 31 MT6370_MAX_LEDS 32 }; 33 34 enum mt6370_led_mode { 35 MT6370_LED_PWM_MODE = 0, 36 MT6370_LED_BREATH_MODE, 37 MT6370_LED_REG_MODE, 38 MT6370_LED_MAX_MODE 39 }; 40 41 enum mt6370_led_field { 42 F_RGB_EN = 0, 43 F_CHGIND_EN, 44 F_LED1_CURR, 45 F_LED2_CURR, 46 F_LED3_CURR, 47 F_LED4_CURR, 48 F_LED1_MODE, 49 F_LED2_MODE, 50 F_LED3_MODE, 51 F_LED4_MODE, 52 F_LED1_DUTY, 53 F_LED2_DUTY, 54 F_LED3_DUTY, 55 F_LED4_DUTY, 56 F_LED1_FREQ, 57 F_LED2_FREQ, 58 F_LED3_FREQ, 59 F_LED4_FREQ, 60 F_MAX_FIELDS 61 }; 62 63 enum mt6370_led_ranges { 64 R_LED123_CURR = 0, 65 R_LED4_CURR, 66 R_LED_TRFON, 67 R_LED_TOFF, 68 R_MAX_RANGES 69 }; 70 71 enum mt6370_pattern { 72 P_LED_TR1 = 0, 73 P_LED_TR2, 74 P_LED_TF1, 75 P_LED_TF2, 76 P_LED_TON, 77 P_LED_TOFF, 78 P_MAX_PATTERNS 79 }; 80 81 #define MT6370_REG_DEV_INFO 0x100 82 #define MT6370_REG_RGB1_DIM 0x182 83 #define MT6370_REG_RGB2_DIM 0x183 84 #define MT6370_REG_RGB3_DIM 0x184 85 #define MT6370_REG_RGB_EN 0x185 86 #define MT6370_REG_RGB1_ISNK 0x186 87 #define MT6370_REG_RGB2_ISNK 0x187 88 #define MT6370_REG_RGB3_ISNK 0x188 89 #define MT6370_REG_RGB1_TR 0x189 90 #define MT6370_REG_RGB_CHRIND_DIM 0x192 91 #define MT6370_REG_RGB_CHRIND_CTRL 0x193 92 #define MT6370_REG_RGB_CHRIND_TR 0x194 93 94 #define MT6372_REG_RGB_EN 0x182 95 #define MT6372_REG_RGB1_ISNK 0x183 96 #define MT6372_REG_RGB2_ISNK 0x184 97 #define MT6372_REG_RGB3_ISNK 0x185 98 #define MT6372_REG_RGB4_ISNK 0x186 99 #define MT6372_REG_RGB1_DIM 0x187 100 #define MT6372_REG_RGB2_DIM 0x188 101 #define MT6372_REG_RGB3_DIM 0x189 102 #define MT6372_REG_RGB4_DIM 0x18A 103 #define MT6372_REG_RGB12_FREQ 0x18B 104 #define MT6372_REG_RGB34_FREQ 0x18C 105 #define MT6372_REG_RGB1_TR 0x18D 106 107 #define MT6370_VENDOR_ID_MASK GENMASK(7, 4) 108 #define MT6372_VENDOR_ID 0x9 109 #define MT6372C_VENDOR_ID 0xb 110 #define MT6370_CHEN_BIT(id) BIT(MT6370_LED_ISNK4 - id) 111 #define MT6370_VIRTUAL_MULTICOLOR 5 112 #define MC_CHANNEL_NUM 3 113 #define MT6370_PWM_DUTY (BIT(5) - 1) 114 #define MT6372_PWM_DUTY (BIT(8) - 1) 115 116 struct mt6370_led { 117 /* 118 * If the color of the LED in DT is set to 119 * - 'LED_COLOR_ID_RGB' 120 * - 'LED_COLOR_ID_MULTI' 121 * The member 'index' of this struct will be set to 122 * 'MT6370_VIRTUAL_MULTICOLOR'. 123 * If so, this LED will choose 'struct led_classdev_mc mc' to use. 124 * Instead, if the member 'index' of this struct is set to 125 * 'MT6370_LED_ISNK1' ~ 'MT6370_LED_ISNK4', then this LED will choose 126 * 'struct led_classdev isink' to use. 127 */ 128 union { 129 struct led_classdev isink; 130 struct led_classdev_mc mc; 131 }; 132 struct mt6370_priv *priv; 133 enum led_default_state default_state; 134 u32 index; 135 }; 136 137 struct mt6370_pdata { 138 const unsigned int *tfreq; 139 unsigned int tfreq_len; 140 u16 reg_rgb1_tr; 141 s16 reg_rgb_chrind_tr; 142 u8 pwm_duty; 143 }; 144 145 struct mt6370_priv { 146 /* Per LED access lock */ 147 struct mutex lock; 148 struct regmap *regmap; 149 struct regmap_field *fields[F_MAX_FIELDS]; 150 const struct reg_field *reg_fields; 151 const struct linear_range *ranges; 152 struct reg_cfg *reg_cfgs; 153 const struct mt6370_pdata *pdata; 154 unsigned int leds_count; 155 unsigned int leds_active; 156 struct mt6370_led leds[]; 157 }; 158 159 static const struct reg_field common_reg_fields[F_MAX_FIELDS] = { 160 [F_RGB_EN] = REG_FIELD(MT6370_REG_RGB_EN, 4, 7), 161 [F_CHGIND_EN] = REG_FIELD(MT6370_REG_RGB_CHRIND_DIM, 7, 7), 162 [F_LED1_CURR] = REG_FIELD(MT6370_REG_RGB1_ISNK, 0, 2), 163 [F_LED2_CURR] = REG_FIELD(MT6370_REG_RGB2_ISNK, 0, 2), 164 [F_LED3_CURR] = REG_FIELD(MT6370_REG_RGB3_ISNK, 0, 2), 165 [F_LED4_CURR] = REG_FIELD(MT6370_REG_RGB_CHRIND_CTRL, 0, 1), 166 [F_LED1_MODE] = REG_FIELD(MT6370_REG_RGB1_DIM, 5, 6), 167 [F_LED2_MODE] = REG_FIELD(MT6370_REG_RGB2_DIM, 5, 6), 168 [F_LED3_MODE] = REG_FIELD(MT6370_REG_RGB3_DIM, 5, 6), 169 [F_LED4_MODE] = REG_FIELD(MT6370_REG_RGB_CHRIND_DIM, 5, 6), 170 [F_LED1_DUTY] = REG_FIELD(MT6370_REG_RGB1_DIM, 0, 4), 171 [F_LED2_DUTY] = REG_FIELD(MT6370_REG_RGB2_DIM, 0, 4), 172 [F_LED3_DUTY] = REG_FIELD(MT6370_REG_RGB3_DIM, 0, 4), 173 [F_LED4_DUTY] = REG_FIELD(MT6370_REG_RGB_CHRIND_DIM, 0, 4), 174 [F_LED1_FREQ] = REG_FIELD(MT6370_REG_RGB1_ISNK, 3, 5), 175 [F_LED2_FREQ] = REG_FIELD(MT6370_REG_RGB2_ISNK, 3, 5), 176 [F_LED3_FREQ] = REG_FIELD(MT6370_REG_RGB3_ISNK, 3, 5), 177 [F_LED4_FREQ] = REG_FIELD(MT6370_REG_RGB_CHRIND_CTRL, 2, 4), 178 }; 179 180 static const struct reg_field mt6372_reg_fields[F_MAX_FIELDS] = { 181 [F_RGB_EN] = REG_FIELD(MT6372_REG_RGB_EN, 4, 7), 182 [F_CHGIND_EN] = REG_FIELD(MT6372_REG_RGB_EN, 3, 3), 183 [F_LED1_CURR] = REG_FIELD(MT6372_REG_RGB1_ISNK, 0, 3), 184 [F_LED2_CURR] = REG_FIELD(MT6372_REG_RGB2_ISNK, 0, 3), 185 [F_LED3_CURR] = REG_FIELD(MT6372_REG_RGB3_ISNK, 0, 3), 186 [F_LED4_CURR] = REG_FIELD(MT6372_REG_RGB4_ISNK, 0, 3), 187 [F_LED1_MODE] = REG_FIELD(MT6372_REG_RGB1_ISNK, 6, 7), 188 [F_LED2_MODE] = REG_FIELD(MT6372_REG_RGB2_ISNK, 6, 7), 189 [F_LED3_MODE] = REG_FIELD(MT6372_REG_RGB3_ISNK, 6, 7), 190 [F_LED4_MODE] = REG_FIELD(MT6372_REG_RGB4_ISNK, 6, 7), 191 [F_LED1_DUTY] = REG_FIELD(MT6372_REG_RGB1_DIM, 0, 7), 192 [F_LED2_DUTY] = REG_FIELD(MT6372_REG_RGB2_DIM, 0, 7), 193 [F_LED3_DUTY] = REG_FIELD(MT6372_REG_RGB3_DIM, 0, 7), 194 [F_LED4_DUTY] = REG_FIELD(MT6372_REG_RGB4_DIM, 0, 7), 195 [F_LED1_FREQ] = REG_FIELD(MT6372_REG_RGB12_FREQ, 5, 7), 196 [F_LED2_FREQ] = REG_FIELD(MT6372_REG_RGB12_FREQ, 2, 4), 197 [F_LED3_FREQ] = REG_FIELD(MT6372_REG_RGB34_FREQ, 5, 7), 198 [F_LED4_FREQ] = REG_FIELD(MT6372_REG_RGB34_FREQ, 2, 4), 199 }; 200 201 /* Current unit: microamp, time unit: millisecond */ 202 static const struct linear_range common_led_ranges[R_MAX_RANGES] = { 203 [R_LED123_CURR] = { 4000, 1, 6, 4000 }, 204 [R_LED4_CURR] = { 2000, 1, 3, 2000 }, 205 [R_LED_TRFON] = { 125, 0, 15, 200 }, 206 [R_LED_TOFF] = { 250, 0, 15, 400 }, 207 }; 208 209 static const struct linear_range mt6372_led_ranges[R_MAX_RANGES] = { 210 [R_LED123_CURR] = { 2000, 1, 14, 2000 }, 211 [R_LED4_CURR] = { 2000, 1, 14, 2000 }, 212 [R_LED_TRFON] = { 125, 0, 15, 250 }, 213 [R_LED_TOFF] = { 250, 0, 15, 500 }, 214 }; 215 216 static const unsigned int common_tfreqs[] = { 217 10000, 5000, 2000, 1000, 500, 200, 5, 1, 218 }; 219 220 static const unsigned int mt6372_tfreqs[] = { 221 8000, 4000, 2000, 1000, 500, 250, 8, 4, 222 }; 223 224 static const struct mt6370_pdata common_pdata = { 225 .tfreq = common_tfreqs, 226 .tfreq_len = ARRAY_SIZE(common_tfreqs), 227 .pwm_duty = MT6370_PWM_DUTY, 228 .reg_rgb1_tr = MT6370_REG_RGB1_TR, 229 .reg_rgb_chrind_tr = MT6370_REG_RGB_CHRIND_TR, 230 }; 231 232 static const struct mt6370_pdata mt6372_pdata = { 233 .tfreq = mt6372_tfreqs, 234 .tfreq_len = ARRAY_SIZE(mt6372_tfreqs), 235 .pwm_duty = MT6372_PWM_DUTY, 236 .reg_rgb1_tr = MT6372_REG_RGB1_TR, 237 .reg_rgb_chrind_tr = -1, 238 }; 239 240 static enum mt6370_led_field mt6370_get_led_current_field(unsigned int led_no) 241 { 242 switch (led_no) { 243 case MT6370_LED_ISNK1: 244 return F_LED1_CURR; 245 case MT6370_LED_ISNK2: 246 return F_LED2_CURR; 247 case MT6370_LED_ISNK3: 248 return F_LED3_CURR; 249 default: 250 return F_LED4_CURR; 251 } 252 } 253 254 static int mt6370_set_led_brightness(struct mt6370_priv *priv, unsigned int led_no, 255 unsigned int level) 256 { 257 enum mt6370_led_field sel_field; 258 259 sel_field = mt6370_get_led_current_field(led_no); 260 261 return regmap_field_write(priv->fields[sel_field], level); 262 } 263 264 static int mt6370_get_led_brightness(struct mt6370_priv *priv, unsigned int led_no, 265 unsigned int *level) 266 { 267 enum mt6370_led_field sel_field; 268 269 sel_field = mt6370_get_led_current_field(led_no); 270 271 return regmap_field_read(priv->fields[sel_field], level); 272 } 273 274 static int mt6370_set_led_duty(struct mt6370_priv *priv, unsigned int led_no, unsigned int ton, 275 unsigned int toff) 276 { 277 const struct mt6370_pdata *pdata = priv->pdata; 278 enum mt6370_led_field sel_field; 279 unsigned int divisor, ratio; 280 281 divisor = pdata->pwm_duty; 282 ratio = ton * divisor / (ton + toff); 283 284 switch (led_no) { 285 case MT6370_LED_ISNK1: 286 sel_field = F_LED1_DUTY; 287 break; 288 case MT6370_LED_ISNK2: 289 sel_field = F_LED2_DUTY; 290 break; 291 case MT6370_LED_ISNK3: 292 sel_field = F_LED3_DUTY; 293 break; 294 default: 295 sel_field = F_LED4_DUTY; 296 break; 297 } 298 299 return regmap_field_write(priv->fields[sel_field], ratio); 300 } 301 302 static int mt6370_set_led_freq(struct mt6370_priv *priv, unsigned int led_no, unsigned int ton, 303 unsigned int toff) 304 { 305 const struct mt6370_pdata *pdata = priv->pdata; 306 enum mt6370_led_field sel_field; 307 unsigned int tfreq_len = pdata->tfreq_len; 308 unsigned int tsum, sel; 309 310 tsum = ton + toff; 311 312 if (tsum > pdata->tfreq[0] || tsum < pdata->tfreq[tfreq_len - 1]) 313 return -EOPNOTSUPP; 314 315 sel = find_closest_descending(tsum, pdata->tfreq, tfreq_len); 316 317 switch (led_no) { 318 case MT6370_LED_ISNK1: 319 sel_field = F_LED1_FREQ; 320 break; 321 case MT6370_LED_ISNK2: 322 sel_field = F_LED2_FREQ; 323 break; 324 case MT6370_LED_ISNK3: 325 sel_field = F_LED3_FREQ; 326 break; 327 default: 328 sel_field = F_LED4_FREQ; 329 break; 330 } 331 332 return regmap_field_write(priv->fields[sel_field], sel); 333 } 334 335 static void mt6370_get_breath_reg_base(struct mt6370_priv *priv, unsigned int led_no, 336 unsigned int *base) 337 { 338 const struct mt6370_pdata *pdata = priv->pdata; 339 340 if (pdata->reg_rgb_chrind_tr < 0) { 341 *base = pdata->reg_rgb1_tr + led_no * 3; 342 return; 343 } 344 345 switch (led_no) { 346 case MT6370_LED_ISNK1: 347 case MT6370_LED_ISNK2: 348 case MT6370_LED_ISNK3: 349 *base = pdata->reg_rgb1_tr + led_no * 3; 350 break; 351 default: 352 *base = pdata->reg_rgb_chrind_tr; 353 break; 354 } 355 } 356 357 static int mt6370_gen_breath_pattern(struct mt6370_priv *priv, struct led_pattern *pattern, u32 len, 358 u8 *pattern_val, u32 val_len) 359 { 360 enum mt6370_led_ranges sel_range; 361 struct led_pattern *curr; 362 unsigned int sel; 363 u32 val = 0; 364 int i; 365 366 if (len < P_MAX_PATTERNS && val_len < P_MAX_PATTERNS / 2) 367 return -EINVAL; 368 369 /* 370 * Pattern list 371 * tr1: byte 0, b'[7:4] 372 * tr2: byte 0, b'[3:0] 373 * tf1: byte 1, b'[7:4] 374 * tf2: byte 1, b'[3:0] 375 * ton: byte 2, b'[7:4] 376 * toff: byte 2, b'[3:0] 377 */ 378 for (i = 0; i < P_MAX_PATTERNS; i++) { 379 curr = pattern + i; 380 381 sel_range = i == P_LED_TOFF ? R_LED_TOFF : R_LED_TRFON; 382 383 linear_range_get_selector_within(priv->ranges + sel_range, curr->delta_t, &sel); 384 385 if (i % 2) { 386 val |= sel; 387 } else { 388 val <<= 8; 389 val |= sel << 4; 390 } 391 } 392 393 put_unaligned_be24(val, pattern_val); 394 395 return 0; 396 } 397 398 static int mt6370_set_led_mode(struct mt6370_priv *priv, unsigned int led_no, 399 enum mt6370_led_mode mode) 400 { 401 enum mt6370_led_field sel_field; 402 403 switch (led_no) { 404 case MT6370_LED_ISNK1: 405 sel_field = F_LED1_MODE; 406 break; 407 case MT6370_LED_ISNK2: 408 sel_field = F_LED2_MODE; 409 break; 410 case MT6370_LED_ISNK3: 411 sel_field = F_LED3_MODE; 412 break; 413 default: 414 sel_field = F_LED4_MODE; 415 break; 416 } 417 418 return regmap_field_write(priv->fields[sel_field], mode); 419 } 420 421 static int mt6370_mc_brightness_set(struct led_classdev *lcdev, enum led_brightness level) 422 { 423 struct led_classdev_mc *mccdev = lcdev_to_mccdev(lcdev); 424 struct mt6370_led *led = container_of(mccdev, struct mt6370_led, mc); 425 struct mt6370_priv *priv = led->priv; 426 struct mc_subled *subled; 427 unsigned int enable, disable; 428 int i, ret; 429 430 mutex_lock(&priv->lock); 431 432 led_mc_calc_color_components(mccdev, level); 433 434 ret = regmap_field_read(priv->fields[F_RGB_EN], &enable); 435 if (ret) 436 goto out_unlock; 437 438 disable = enable; 439 440 for (i = 0; i < mccdev->num_colors; i++) { 441 u32 brightness; 442 443 subled = mccdev->subled_info + i; 444 brightness = min(subled->brightness, lcdev->max_brightness); 445 disable &= ~MT6370_CHEN_BIT(subled->channel); 446 447 if (level == 0) { 448 enable &= ~MT6370_CHEN_BIT(subled->channel); 449 450 ret = mt6370_set_led_mode(priv, subled->channel, MT6370_LED_REG_MODE); 451 if (ret) 452 goto out_unlock; 453 454 continue; 455 } 456 457 if (brightness == 0) { 458 enable &= ~MT6370_CHEN_BIT(subled->channel); 459 continue; 460 } 461 462 enable |= MT6370_CHEN_BIT(subled->channel); 463 464 ret = mt6370_set_led_brightness(priv, subled->channel, brightness); 465 if (ret) 466 goto out_unlock; 467 } 468 469 ret = regmap_field_write(priv->fields[F_RGB_EN], disable); 470 if (ret) 471 goto out_unlock; 472 473 ret = regmap_field_write(priv->fields[F_RGB_EN], enable); 474 475 out_unlock: 476 mutex_unlock(&priv->lock); 477 478 return ret; 479 } 480 481 static int mt6370_mc_blink_set(struct led_classdev *lcdev, 482 unsigned long *delay_on, 483 unsigned long *delay_off) 484 { 485 struct led_classdev_mc *mccdev = lcdev_to_mccdev(lcdev); 486 struct mt6370_led *led = container_of(mccdev, struct mt6370_led, mc); 487 struct mt6370_priv *priv = led->priv; 488 struct mc_subled *subled; 489 unsigned int enable, disable; 490 int i, ret; 491 492 mutex_lock(&priv->lock); 493 494 if (!*delay_on && !*delay_off) 495 *delay_on = *delay_off = 500; 496 497 ret = regmap_field_read(priv->fields[F_RGB_EN], &enable); 498 if (ret) 499 goto out_unlock; 500 501 disable = enable; 502 503 for (i = 0; i < mccdev->num_colors; i++) { 504 subled = mccdev->subled_info + i; 505 506 disable &= ~MT6370_CHEN_BIT(subled->channel); 507 508 ret = mt6370_set_led_duty(priv, subled->channel, *delay_on, *delay_off); 509 if (ret) 510 goto out_unlock; 511 512 ret = mt6370_set_led_freq(priv, subled->channel, *delay_on, *delay_off); 513 if (ret) 514 goto out_unlock; 515 516 ret = mt6370_set_led_mode(priv, subled->channel, MT6370_LED_PWM_MODE); 517 if (ret) 518 goto out_unlock; 519 } 520 521 /* Toggle to make pattern timing the same */ 522 ret = regmap_field_write(priv->fields[F_RGB_EN], disable); 523 if (ret) 524 goto out_unlock; 525 526 ret = regmap_field_write(priv->fields[F_RGB_EN], enable); 527 528 out_unlock: 529 mutex_unlock(&priv->lock); 530 531 return ret; 532 } 533 534 static int mt6370_mc_pattern_set(struct led_classdev *lcdev, struct led_pattern *pattern, u32 len, 535 int repeat) 536 { 537 struct led_classdev_mc *mccdev = lcdev_to_mccdev(lcdev); 538 struct mt6370_led *led = container_of(mccdev, struct mt6370_led, mc); 539 struct mt6370_priv *priv = led->priv; 540 struct mc_subled *subled; 541 unsigned int reg_base, enable, disable; 542 u8 params[P_MAX_PATTERNS / 2]; 543 int i, ret; 544 545 mutex_lock(&priv->lock); 546 547 ret = mt6370_gen_breath_pattern(priv, pattern, len, params, sizeof(params)); 548 if (ret) 549 goto out_unlock; 550 551 ret = regmap_field_read(priv->fields[F_RGB_EN], &enable); 552 if (ret) 553 goto out_unlock; 554 555 disable = enable; 556 557 for (i = 0; i < mccdev->num_colors; i++) { 558 subled = mccdev->subled_info + i; 559 560 mt6370_get_breath_reg_base(priv, subled->channel, ®_base); 561 disable &= ~MT6370_CHEN_BIT(subled->channel); 562 563 ret = regmap_raw_write(priv->regmap, reg_base, params, sizeof(params)); 564 if (ret) 565 goto out_unlock; 566 567 ret = mt6370_set_led_mode(priv, subled->channel, MT6370_LED_BREATH_MODE); 568 if (ret) 569 goto out_unlock; 570 } 571 572 /* Toggle to make pattern timing be the same */ 573 ret = regmap_field_write(priv->fields[F_RGB_EN], disable); 574 if (ret) 575 goto out_unlock; 576 577 ret = regmap_field_write(priv->fields[F_RGB_EN], enable); 578 579 out_unlock: 580 mutex_unlock(&priv->lock); 581 582 return ret; 583 } 584 585 static inline int mt6370_mc_pattern_clear(struct led_classdev *lcdev) 586 { 587 struct led_classdev_mc *mccdev = lcdev_to_mccdev(lcdev); 588 struct mt6370_led *led = container_of(mccdev, struct mt6370_led, mc); 589 struct mt6370_priv *priv = led->priv; 590 struct mc_subled *subled; 591 int i, ret; 592 593 mutex_lock(&led->priv->lock); 594 595 for (i = 0; i < mccdev->num_colors; i++) { 596 subled = mccdev->subled_info + i; 597 598 ret = mt6370_set_led_mode(priv, subled->channel, MT6370_LED_REG_MODE); 599 if (ret) 600 break; 601 } 602 603 mutex_unlock(&led->priv->lock); 604 605 return ret; 606 } 607 608 static int mt6370_isnk_brightness_set(struct led_classdev *lcdev, 609 enum led_brightness level) 610 { 611 struct mt6370_led *led = container_of(lcdev, struct mt6370_led, isink); 612 struct mt6370_priv *priv = led->priv; 613 unsigned int enable; 614 int ret; 615 616 mutex_lock(&priv->lock); 617 618 ret = regmap_field_read(priv->fields[F_RGB_EN], &enable); 619 if (ret) 620 goto out_unlock; 621 622 if (level == 0) { 623 enable &= ~MT6370_CHEN_BIT(led->index); 624 625 ret = mt6370_set_led_mode(priv, led->index, MT6370_LED_REG_MODE); 626 if (ret) 627 goto out_unlock; 628 } else { 629 enable |= MT6370_CHEN_BIT(led->index); 630 631 ret = mt6370_set_led_brightness(priv, led->index, level); 632 if (ret) 633 goto out_unlock; 634 } 635 636 ret = regmap_field_write(priv->fields[F_RGB_EN], enable); 637 638 out_unlock: 639 mutex_unlock(&priv->lock); 640 641 return ret; 642 } 643 644 static int mt6370_isnk_blink_set(struct led_classdev *lcdev, unsigned long *delay_on, 645 unsigned long *delay_off) 646 { 647 struct mt6370_led *led = container_of(lcdev, struct mt6370_led, isink); 648 struct mt6370_priv *priv = led->priv; 649 int ret; 650 651 mutex_lock(&priv->lock); 652 653 if (!*delay_on && !*delay_off) 654 *delay_on = *delay_off = 500; 655 656 ret = mt6370_set_led_duty(priv, led->index, *delay_on, *delay_off); 657 if (ret) 658 goto out_unlock; 659 660 ret = mt6370_set_led_freq(priv, led->index, *delay_on, *delay_off); 661 if (ret) 662 goto out_unlock; 663 664 ret = mt6370_set_led_mode(priv, led->index, MT6370_LED_PWM_MODE); 665 666 out_unlock: 667 mutex_unlock(&priv->lock); 668 669 return ret; 670 } 671 672 static int mt6370_isnk_pattern_set(struct led_classdev *lcdev, struct led_pattern *pattern, u32 len, 673 int repeat) 674 { 675 struct mt6370_led *led = container_of(lcdev, struct mt6370_led, isink); 676 struct mt6370_priv *priv = led->priv; 677 unsigned int reg_base; 678 u8 params[P_MAX_PATTERNS / 2]; 679 int ret; 680 681 mutex_lock(&priv->lock); 682 683 ret = mt6370_gen_breath_pattern(priv, pattern, len, params, sizeof(params)); 684 if (ret) 685 goto out_unlock; 686 687 mt6370_get_breath_reg_base(priv, led->index, ®_base); 688 689 ret = regmap_raw_write(priv->regmap, reg_base, params, sizeof(params)); 690 if (ret) 691 goto out_unlock; 692 693 ret = mt6370_set_led_mode(priv, led->index, MT6370_LED_BREATH_MODE); 694 695 out_unlock: 696 mutex_unlock(&priv->lock); 697 698 return ret; 699 } 700 701 static inline int mt6370_isnk_pattern_clear(struct led_classdev *lcdev) 702 { 703 struct mt6370_led *led = container_of(lcdev, struct mt6370_led, isink); 704 struct mt6370_priv *priv = led->priv; 705 int ret; 706 707 mutex_lock(&led->priv->lock); 708 ret = mt6370_set_led_mode(priv, led->index, MT6370_LED_REG_MODE); 709 mutex_unlock(&led->priv->lock); 710 711 return ret; 712 } 713 714 static int mt6370_assign_multicolor_info(struct device *dev, struct mt6370_led *led, 715 struct fwnode_handle *fwnode) 716 { 717 struct mt6370_priv *priv = led->priv; 718 struct fwnode_handle *child; 719 struct mc_subled *sub_led; 720 u32 num_color = 0; 721 int ret; 722 723 sub_led = devm_kcalloc(dev, MC_CHANNEL_NUM, sizeof(*sub_led), GFP_KERNEL); 724 if (!sub_led) 725 return -ENOMEM; 726 727 fwnode_for_each_child_node(fwnode, child) { 728 u32 reg, color; 729 730 ret = fwnode_property_read_u32(child, "reg", ®); 731 if (ret || reg > MT6370_LED_ISNK3 || priv->leds_active & BIT(reg)) { 732 fwnode_handle_put(child); 733 return -EINVAL; 734 } 735 736 ret = fwnode_property_read_u32(child, "color", &color); 737 if (ret) { 738 fwnode_handle_put(child); 739 return dev_err_probe(dev, ret, "LED %d, no color specified\n", led->index); 740 } 741 742 priv->leds_active |= BIT(reg); 743 sub_led[num_color].color_index = color; 744 sub_led[num_color].channel = reg; 745 sub_led[num_color].intensity = 0; 746 num_color++; 747 } 748 749 if (num_color < 2) 750 return dev_err_probe(dev, -EINVAL, 751 "Multicolor must include 2 or more LED channels\n"); 752 753 led->mc.num_colors = num_color; 754 led->mc.subled_info = sub_led; 755 756 return 0; 757 } 758 759 static int mt6370_init_led_properties(struct device *dev, struct mt6370_led *led, 760 struct led_init_data *init_data) 761 { 762 struct mt6370_priv *priv = led->priv; 763 struct led_classdev *lcdev; 764 enum mt6370_led_ranges sel_range; 765 u32 max_uA, max_level; 766 int ret; 767 768 if (led->index == MT6370_VIRTUAL_MULTICOLOR) { 769 ret = mt6370_assign_multicolor_info(dev, led, init_data->fwnode); 770 if (ret) 771 return ret; 772 773 lcdev = &led->mc.led_cdev; 774 lcdev->brightness_set_blocking = mt6370_mc_brightness_set; 775 lcdev->blink_set = mt6370_mc_blink_set; 776 lcdev->pattern_set = mt6370_mc_pattern_set; 777 lcdev->pattern_clear = mt6370_mc_pattern_clear; 778 } else { 779 lcdev = &led->isink; 780 lcdev->brightness_set_blocking = mt6370_isnk_brightness_set; 781 lcdev->blink_set = mt6370_isnk_blink_set; 782 lcdev->pattern_set = mt6370_isnk_pattern_set; 783 lcdev->pattern_clear = mt6370_isnk_pattern_clear; 784 } 785 786 ret = fwnode_property_read_u32(init_data->fwnode, "led-max-microamp", &max_uA); 787 if (ret) { 788 dev_warn(dev, "Not specified led-max-microamp, config to the minimum\n"); 789 max_uA = 0; 790 } 791 792 if (led->index == MT6370_LED_ISNK4) 793 sel_range = R_LED4_CURR; 794 else 795 sel_range = R_LED123_CURR; 796 797 linear_range_get_selector_within(priv->ranges + sel_range, max_uA, &max_level); 798 799 lcdev->max_brightness = max_level; 800 801 led->default_state = led_init_default_state_get(init_data->fwnode); 802 803 return 0; 804 } 805 806 static int mt6370_isnk_init_default_state(struct mt6370_led *led) 807 { 808 struct mt6370_priv *priv = led->priv; 809 unsigned int enable, level; 810 int ret; 811 812 ret = mt6370_get_led_brightness(priv, led->index, &level); 813 if (ret) 814 return ret; 815 816 ret = regmap_field_read(priv->fields[F_RGB_EN], &enable); 817 if (ret) 818 return ret; 819 820 if (!(enable & MT6370_CHEN_BIT(led->index))) 821 level = 0; 822 823 switch (led->default_state) { 824 case LEDS_DEFSTATE_ON: 825 led->isink.brightness = led->isink.max_brightness; 826 break; 827 case LEDS_DEFSTATE_KEEP: 828 led->isink.brightness = min(level, led->isink.max_brightness); 829 break; 830 default: 831 led->isink.brightness = 0; 832 break; 833 } 834 835 return mt6370_isnk_brightness_set(&led->isink, led->isink.brightness); 836 } 837 838 static int mt6370_multicolor_led_register(struct device *dev, struct mt6370_led *led, 839 struct led_init_data *init_data) 840 { 841 int ret; 842 843 ret = mt6370_mc_brightness_set(&led->mc.led_cdev, 0); 844 if (ret) 845 return dev_err_probe(dev, ret, "Couldn't set multicolor brightness\n"); 846 847 ret = devm_led_classdev_multicolor_register_ext(dev, &led->mc, init_data); 848 if (ret) 849 return dev_err_probe(dev, ret, "Couldn't register multicolor\n"); 850 851 return 0; 852 } 853 854 static int mt6370_led_register(struct device *dev, struct mt6370_led *led, 855 struct led_init_data *init_data) 856 { 857 struct mt6370_priv *priv = led->priv; 858 int ret; 859 860 if (led->index == MT6370_VIRTUAL_MULTICOLOR) 861 return mt6370_multicolor_led_register(dev, led, init_data); 862 863 /* If ISNK4 is declared, change its mode from HW auto to SW control */ 864 if (led->index == MT6370_LED_ISNK4) { 865 ret = regmap_field_write(priv->fields[F_CHGIND_EN], 1); 866 if (ret) 867 return dev_err_probe(dev, ret, "Failed to set CHRIND to SW\n"); 868 } 869 870 ret = mt6370_isnk_init_default_state(led); 871 if (ret) 872 return dev_err_probe(dev, ret, "Failed to init %d isnk state\n", led->index); 873 874 ret = devm_led_classdev_register_ext(dev, &led->isink, init_data); 875 if (ret) 876 return dev_err_probe(dev, ret, "Couldn't register isink %d\n", led->index); 877 878 return 0; 879 } 880 881 static int mt6370_check_vendor_info(struct mt6370_priv *priv) 882 { 883 unsigned int devinfo, vid; 884 int ret; 885 886 ret = regmap_read(priv->regmap, MT6370_REG_DEV_INFO, &devinfo); 887 if (ret) 888 return ret; 889 890 vid = FIELD_GET(MT6370_VENDOR_ID_MASK, devinfo); 891 if (vid == MT6372_VENDOR_ID || vid == MT6372C_VENDOR_ID) { 892 priv->reg_fields = mt6372_reg_fields; 893 priv->ranges = mt6372_led_ranges; 894 priv->pdata = &mt6372_pdata; 895 } else { 896 /* Common for MT6370/71 */ 897 priv->reg_fields = common_reg_fields; 898 priv->ranges = common_led_ranges; 899 priv->pdata = &common_pdata; 900 } 901 902 return 0; 903 } 904 905 static int mt6370_leds_probe(struct platform_device *pdev) 906 { 907 struct device *dev = &pdev->dev; 908 struct mt6370_priv *priv; 909 struct fwnode_handle *child; 910 size_t count; 911 unsigned int i = 0; 912 int ret; 913 914 count = device_get_child_node_count(dev); 915 if (!count || count > MT6370_MAX_LEDS) 916 return dev_err_probe(dev, -EINVAL, 917 "No child node or node count over max LED number %zu\n", 918 count); 919 920 priv = devm_kzalloc(dev, struct_size(priv, leds, count), GFP_KERNEL); 921 if (!priv) 922 return -ENOMEM; 923 924 priv->leds_count = count; 925 mutex_init(&priv->lock); 926 927 priv->regmap = dev_get_regmap(dev->parent, NULL); 928 if (!priv->regmap) 929 return dev_err_probe(dev, -ENODEV, "Failed to get parent regmap\n"); 930 931 ret = mt6370_check_vendor_info(priv); 932 if (ret) 933 return dev_err_probe(dev, ret, "Failed to check vendor info\n"); 934 935 ret = devm_regmap_field_bulk_alloc(dev, priv->regmap, priv->fields, priv->reg_fields, 936 F_MAX_FIELDS); 937 if (ret) 938 return dev_err_probe(dev, ret, "Failed to allocate regmap field\n"); 939 940 device_for_each_child_node(dev, child) { 941 struct mt6370_led *led = priv->leds + i++; 942 struct led_init_data init_data = { .fwnode = child }; 943 u32 reg, color; 944 945 ret = fwnode_property_read_u32(child, "reg", ®); 946 if (ret) { 947 dev_err(dev, "Failed to parse reg property\n"); 948 goto fwnode_release; 949 } 950 951 if (reg >= MT6370_MAX_LEDS) { 952 ret = -EINVAL; 953 dev_err(dev, "Error reg property number\n"); 954 goto fwnode_release; 955 } 956 957 ret = fwnode_property_read_u32(child, "color", &color); 958 if (ret) { 959 dev_err(dev, "Failed to parse color property\n"); 960 goto fwnode_release; 961 } 962 963 if (color == LED_COLOR_ID_RGB || color == LED_COLOR_ID_MULTI) 964 reg = MT6370_VIRTUAL_MULTICOLOR; 965 966 if (priv->leds_active & BIT(reg)) { 967 ret = -EINVAL; 968 dev_err(dev, "Duplicate reg property\n"); 969 goto fwnode_release; 970 } 971 972 priv->leds_active |= BIT(reg); 973 974 led->index = reg; 975 led->priv = priv; 976 977 ret = mt6370_init_led_properties(dev, led, &init_data); 978 if (ret) 979 goto fwnode_release; 980 981 ret = mt6370_led_register(dev, led, &init_data); 982 if (ret) 983 goto fwnode_release; 984 } 985 986 return 0; 987 988 fwnode_release: 989 fwnode_handle_put(child); 990 return ret; 991 } 992 993 static const struct of_device_id mt6370_rgbled_device_table[] = { 994 { .compatible = "mediatek,mt6370-indicator" }, 995 {} 996 }; 997 MODULE_DEVICE_TABLE(of, mt6370_rgbled_device_table); 998 999 static struct platform_driver mt6370_rgbled_driver = { 1000 .driver = { 1001 .name = "mt6370-indicator", 1002 .of_match_table = mt6370_rgbled_device_table, 1003 }, 1004 .probe = mt6370_leds_probe, 1005 }; 1006 module_platform_driver(mt6370_rgbled_driver); 1007 1008 MODULE_AUTHOR("Alice Chen <alice_chen@richtek.com>"); 1009 MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>"); 1010 MODULE_DESCRIPTION("MediaTek MT6370 RGB LED Driver"); 1011 MODULE_LICENSE("GPL"); 1012