1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2023 Richtek Technology Corp. 4 * 5 * Authors: 6 * Alice Chen <alice_chen@richtek.com> 7 * ChiYuan Huang <cy_huang@richtek.com> 8 */ 9 10 #include <linux/bitops.h> 11 #include <linux/delay.h> 12 #include <linux/init.h> 13 #include <linux/interrupt.h> 14 #include <linux/kernel.h> 15 #include <linux/led-class-flash.h> 16 #include <linux/module.h> 17 #include <linux/mutex.h> 18 #include <linux/platform_device.h> 19 #include <linux/property.h> 20 #include <linux/regmap.h> 21 22 #include <media/v4l2-flash-led-class.h> 23 24 enum { 25 MT6370_LED_FLASH1 = 0, 26 MT6370_LED_FLASH2, 27 MT6370_MAX_LEDS 28 }; 29 30 /* Virtual definition for multicolor */ 31 32 #define MT6370_REG_FLEDEN 0x17E 33 #define MT6370_REG_STRBTO 0x173 34 #define MT6370_REG_CHGSTAT2 0x1D1 35 #define MT6370_REG_FLEDSTAT1 0x1D9 36 #define MT6370_REG_FLEDISTRB(_id) (0x174 + 4 * (_id)) 37 #define MT6370_REG_FLEDITOR(_id) (0x175 + 4 * (_id)) 38 #define MT6370_ITORCH_MASK GENMASK(4, 0) 39 #define MT6370_ISTROBE_MASK GENMASK(6, 0) 40 #define MT6370_STRBTO_MASK GENMASK(6, 0) 41 #define MT6370_TORCHEN_MASK BIT(3) 42 #define MT6370_STROBEN_MASK BIT(2) 43 #define MT6370_FLCSEN_MASK(_id) BIT(MT6370_LED_FLASH2 - (_id)) 44 #define MT6370_FLCSEN_MASK_ALL GENMASK(1, 0) 45 #define MT6370_FLEDCHGVINOVP_MASK BIT(3) 46 #define MT6370_FLED1STRBTO_MASK BIT(11) 47 #define MT6370_FLED2STRBTO_MASK BIT(10) 48 #define MT6370_FLED1STRB_MASK BIT(9) 49 #define MT6370_FLED2STRB_MASK BIT(8) 50 #define MT6370_FLED1SHORT_MASK BIT(7) 51 #define MT6370_FLED2SHORT_MASK BIT(6) 52 #define MT6370_FLEDLVF_MASK BIT(3) 53 54 #define MT6370_LED_JOINT 2 55 #define MT6370_RANGE_FLED_REG 4 56 #define MT6370_ITORCH_MIN_uA 25000 57 #define MT6370_ITORCH_STEP_uA 12500 58 #define MT6370_ITORCH_MAX_uA 400000 59 #define MT6370_ITORCH_DOUBLE_MAX_uA 800000 60 #define MT6370_ISTRB_MIN_uA 50000 61 #define MT6370_ISTRB_STEP_uA 12500 62 #define MT6370_ISTRB_MAX_uA 1500000 63 #define MT6370_ISTRB_DOUBLE_MAX_uA 3000000 64 #define MT6370_STRBTO_MIN_US 64000 65 #define MT6370_STRBTO_STEP_US 32000 66 #define MT6370_STRBTO_MAX_US 2432000 67 68 #define to_mt6370_led(ptr, member) container_of(ptr, struct mt6370_led, member) 69 70 struct mt6370_led { 71 struct led_classdev_flash flash; 72 struct v4l2_flash *v4l2_flash; 73 struct mt6370_priv *priv; 74 u8 led_no; 75 }; 76 77 struct mt6370_priv { 78 struct regmap *regmap; 79 struct mutex lock; 80 unsigned int fled_strobe_used; 81 unsigned int fled_torch_used; 82 unsigned int leds_active; 83 unsigned int leds_count; 84 struct mt6370_led leds[]; 85 }; 86 87 static int mt6370_torch_brightness_set(struct led_classdev *lcdev, enum led_brightness level) 88 { 89 struct mt6370_led *led = to_mt6370_led(lcdev, flash.led_cdev); 90 struct mt6370_priv *priv = led->priv; 91 u32 led_enable_mask = led->led_no == MT6370_LED_JOINT ? MT6370_FLCSEN_MASK_ALL : 92 MT6370_FLCSEN_MASK(led->led_no); 93 u32 enable_mask = MT6370_TORCHEN_MASK | led_enable_mask; 94 u32 val = level ? led_enable_mask : 0; 95 u32 curr; 96 int ret, i; 97 98 mutex_lock(&priv->lock); 99 100 /* 101 * There is only one set of flash control logic, and this flag is used to check if 'strobe' 102 * is currently being used. 103 */ 104 if (priv->fled_strobe_used) { 105 dev_warn(lcdev->dev, "Please disable strobe first [%d]\n", priv->fled_strobe_used); 106 ret = -EBUSY; 107 goto unlock; 108 } 109 110 if (level) 111 curr = priv->fled_torch_used | BIT(led->led_no); 112 else 113 curr = priv->fled_torch_used & ~BIT(led->led_no); 114 115 if (curr) 116 val |= MT6370_TORCHEN_MASK; 117 118 if (level) { 119 level -= 1; 120 if (led->led_no == MT6370_LED_JOINT) { 121 u32 flevel[MT6370_MAX_LEDS]; 122 123 /* 124 * There're two flash channels in MT6370. If joint flash output is used, 125 * torch current will be averaged output from both channels. 126 */ 127 flevel[0] = level / 2; 128 flevel[1] = level - flevel[0]; 129 for (i = 0; i < MT6370_MAX_LEDS; i++) { 130 ret = regmap_update_bits(priv->regmap, MT6370_REG_FLEDITOR(i), 131 MT6370_ITORCH_MASK, flevel[i]); 132 if (ret) 133 goto unlock; 134 } 135 } else { 136 ret = regmap_update_bits(priv->regmap, MT6370_REG_FLEDITOR(led->led_no), 137 MT6370_ITORCH_MASK, level); 138 if (ret) 139 goto unlock; 140 } 141 } 142 143 ret = regmap_update_bits(priv->regmap, MT6370_REG_FLEDEN, enable_mask, val); 144 if (ret) 145 goto unlock; 146 147 priv->fled_torch_used = curr; 148 149 unlock: 150 mutex_unlock(&priv->lock); 151 return ret; 152 } 153 154 static int mt6370_flash_brightness_set(struct led_classdev_flash *fl_cdev, u32 brightness) 155 { 156 /* 157 * Because of the current spikes when turning on the flash, the brightness should be kept 158 * by the LED framework. This empty function is used to prevent checking failure when 159 * led_classdev_flash registers ops. 160 */ 161 return 0; 162 } 163 164 static int _mt6370_flash_brightness_set(struct led_classdev_flash *fl_cdev, u32 brightness) 165 { 166 struct mt6370_led *led = to_mt6370_led(fl_cdev, flash); 167 struct mt6370_priv *priv = led->priv; 168 struct led_flash_setting *setting = &fl_cdev->brightness; 169 u32 val = (brightness - setting->min) / setting->step; 170 int ret, i; 171 172 if (led->led_no == MT6370_LED_JOINT) { 173 u32 flevel[MT6370_MAX_LEDS]; 174 175 /* 176 * There're two flash channels in MT6370. If joint flash output is used, storbe 177 * current will be averaged output from both channels. 178 */ 179 flevel[0] = val / 2; 180 flevel[1] = val - flevel[0]; 181 for (i = 0; i < MT6370_MAX_LEDS; i++) { 182 ret = regmap_update_bits(priv->regmap, MT6370_REG_FLEDISTRB(i), 183 MT6370_ISTROBE_MASK, flevel[i]); 184 if (ret) 185 break; 186 } 187 } else { 188 ret = regmap_update_bits(priv->regmap, MT6370_REG_FLEDISTRB(led->led_no), 189 MT6370_ISTROBE_MASK, val); 190 } 191 192 return ret; 193 } 194 195 static int mt6370_strobe_set(struct led_classdev_flash *fl_cdev, bool state) 196 { 197 struct mt6370_led *led = to_mt6370_led(fl_cdev, flash); 198 struct mt6370_priv *priv = led->priv; 199 struct led_classdev *lcdev = &fl_cdev->led_cdev; 200 struct led_flash_setting *s = &fl_cdev->brightness; 201 u32 led_enable_mask = led->led_no == MT6370_LED_JOINT ? MT6370_FLCSEN_MASK_ALL : 202 MT6370_FLCSEN_MASK(led->led_no); 203 u32 enable_mask = MT6370_STROBEN_MASK | led_enable_mask; 204 u32 val = state ? led_enable_mask : 0; 205 u32 curr; 206 int ret; 207 208 mutex_lock(&priv->lock); 209 210 /* 211 * There is only one set of flash control logic, and this flag is used to check if 'torch' 212 * is currently being used. 213 */ 214 if (priv->fled_torch_used) { 215 dev_warn(lcdev->dev, "Please disable torch first [0x%x]\n", priv->fled_torch_used); 216 ret = -EBUSY; 217 goto unlock; 218 } 219 220 if (state) 221 curr = priv->fled_strobe_used | BIT(led->led_no); 222 else 223 curr = priv->fled_strobe_used & ~BIT(led->led_no); 224 225 if (curr) 226 val |= MT6370_STROBEN_MASK; 227 228 ret = regmap_update_bits(priv->regmap, MT6370_REG_FLEDEN, enable_mask, val); 229 if (ret) { 230 dev_err(lcdev->dev, "[%d] control current source %d fail\n", led->led_no, state); 231 goto unlock; 232 } 233 234 /* 235 * If the flash needs to turn on, configure the flash current to ramp up to the setting 236 * value. Otherwise, always revert to the minimum one. 237 */ 238 ret = _mt6370_flash_brightness_set(fl_cdev, state ? s->val : s->min); 239 if (ret) { 240 dev_err(lcdev->dev, "[%d] Failed to set brightness\n", led->led_no); 241 goto unlock; 242 } 243 244 /* 245 * For the flash to turn on/off, we must wait for HW ramping up/down time 5ms/500us to 246 * prevent the unexpected problem. 247 */ 248 if (!priv->fled_strobe_used && curr) 249 usleep_range(5000, 6000); 250 else if (priv->fled_strobe_used && !curr) 251 usleep_range(500, 600); 252 253 priv->fled_strobe_used = curr; 254 255 unlock: 256 mutex_unlock(&priv->lock); 257 return ret; 258 } 259 260 static int mt6370_strobe_get(struct led_classdev_flash *fl_cdev, bool *state) 261 { 262 struct mt6370_led *led = to_mt6370_led(fl_cdev, flash); 263 struct mt6370_priv *priv = led->priv; 264 265 mutex_lock(&priv->lock); 266 *state = !!(priv->fled_strobe_used & BIT(led->led_no)); 267 mutex_unlock(&priv->lock); 268 269 return 0; 270 } 271 272 static int mt6370_timeout_set(struct led_classdev_flash *fl_cdev, u32 timeout) 273 { 274 struct mt6370_led *led = to_mt6370_led(fl_cdev, flash); 275 struct mt6370_priv *priv = led->priv; 276 struct led_flash_setting *s = &fl_cdev->timeout; 277 u32 val = (timeout - s->min) / s->step; 278 279 return regmap_update_bits(priv->regmap, MT6370_REG_STRBTO, MT6370_STRBTO_MASK, val); 280 } 281 282 static int mt6370_fault_get(struct led_classdev_flash *fl_cdev, u32 *fault) 283 { 284 struct mt6370_led *led = to_mt6370_led(fl_cdev, flash); 285 struct mt6370_priv *priv = led->priv; 286 u16 fled_stat; 287 unsigned int chg_stat, strobe_timeout_mask, fled_short_mask; 288 u32 rfault = 0; 289 int ret; 290 291 ret = regmap_read(priv->regmap, MT6370_REG_CHGSTAT2, &chg_stat); 292 if (ret) 293 return ret; 294 295 ret = regmap_raw_read(priv->regmap, MT6370_REG_FLEDSTAT1, &fled_stat, sizeof(fled_stat)); 296 if (ret) 297 return ret; 298 299 switch (led->led_no) { 300 case MT6370_LED_FLASH1: 301 strobe_timeout_mask = MT6370_FLED1STRBTO_MASK; 302 fled_short_mask = MT6370_FLED1SHORT_MASK; 303 break; 304 305 case MT6370_LED_FLASH2: 306 strobe_timeout_mask = MT6370_FLED2STRBTO_MASK; 307 fled_short_mask = MT6370_FLED2SHORT_MASK; 308 break; 309 310 case MT6370_LED_JOINT: 311 strobe_timeout_mask = MT6370_FLED1STRBTO_MASK | MT6370_FLED2STRBTO_MASK; 312 fled_short_mask = MT6370_FLED1SHORT_MASK | MT6370_FLED2SHORT_MASK; 313 break; 314 default: 315 return -EINVAL; 316 } 317 318 if (chg_stat & MT6370_FLEDCHGVINOVP_MASK) 319 rfault |= LED_FAULT_INPUT_VOLTAGE; 320 321 if (fled_stat & strobe_timeout_mask) 322 rfault |= LED_FAULT_TIMEOUT; 323 324 if (fled_stat & fled_short_mask) 325 rfault |= LED_FAULT_SHORT_CIRCUIT; 326 327 if (fled_stat & MT6370_FLEDLVF_MASK) 328 rfault |= LED_FAULT_UNDER_VOLTAGE; 329 330 *fault = rfault; 331 return ret; 332 } 333 334 static const struct led_flash_ops mt6370_flash_ops = { 335 .flash_brightness_set = mt6370_flash_brightness_set, 336 .strobe_set = mt6370_strobe_set, 337 .strobe_get = mt6370_strobe_get, 338 .timeout_set = mt6370_timeout_set, 339 .fault_get = mt6370_fault_get, 340 }; 341 342 #if IS_ENABLED(CONFIG_V4L2_FLASH_LED_CLASS) 343 static int mt6370_flash_external_strobe_set(struct v4l2_flash *v4l2_flash, 344 bool enable) 345 { 346 struct led_classdev_flash *flash = v4l2_flash->fled_cdev; 347 struct mt6370_led *led = to_mt6370_led(flash, flash); 348 struct mt6370_priv *priv = led->priv; 349 u32 mask = led->led_no == MT6370_LED_JOINT ? MT6370_FLCSEN_MASK_ALL : 350 MT6370_FLCSEN_MASK(led->led_no); 351 u32 val = enable ? mask : 0; 352 int ret; 353 354 mutex_lock(&priv->lock); 355 356 ret = regmap_update_bits(priv->regmap, MT6370_REG_FLEDEN, mask, val); 357 if (ret) 358 goto unlock; 359 360 if (enable) 361 priv->fled_strobe_used |= BIT(led->led_no); 362 else 363 priv->fled_strobe_used &= ~BIT(led->led_no); 364 365 unlock: 366 mutex_unlock(&priv->lock); 367 return ret; 368 } 369 370 static const struct v4l2_flash_ops v4l2_flash_ops = { 371 .external_strobe_set = mt6370_flash_external_strobe_set, 372 }; 373 374 static void mt6370_init_v4l2_flash_config(struct mt6370_led *led, struct v4l2_flash_config *cfg) 375 { 376 struct led_classdev *lcdev; 377 struct led_flash_setting *s = &cfg->intensity; 378 379 lcdev = &led->flash.led_cdev; 380 381 s->min = MT6370_ITORCH_MIN_uA; 382 s->step = MT6370_ITORCH_STEP_uA; 383 s->val = s->max = s->min + (lcdev->max_brightness - 1) * s->step; 384 385 cfg->has_external_strobe = 1; 386 strscpy(cfg->dev_name, dev_name(lcdev->dev), sizeof(cfg->dev_name)); 387 388 cfg->flash_faults = LED_FAULT_SHORT_CIRCUIT | LED_FAULT_TIMEOUT | 389 LED_FAULT_INPUT_VOLTAGE | LED_FAULT_UNDER_VOLTAGE; 390 } 391 #else 392 static const struct v4l2_flash_ops v4l2_flash_ops; 393 static void mt6370_init_v4l2_flash_config(struct mt6370_led *led, struct v4l2_flash_config *cfg) 394 { 395 } 396 #endif 397 398 static void mt6370_v4l2_flash_release(void *v4l2_flash) 399 { 400 v4l2_flash_release(v4l2_flash); 401 } 402 403 static int mt6370_led_register(struct device *parent, struct mt6370_led *led, 404 struct fwnode_handle *fwnode) 405 { 406 struct led_init_data init_data = { .fwnode = fwnode }; 407 struct v4l2_flash_config v4l2_config = {}; 408 int ret; 409 410 ret = devm_led_classdev_flash_register_ext(parent, &led->flash, &init_data); 411 if (ret) 412 return dev_err_probe(parent, ret, "Couldn't register flash %d\n", led->led_no); 413 414 mt6370_init_v4l2_flash_config(led, &v4l2_config); 415 led->v4l2_flash = v4l2_flash_init(parent, fwnode, &led->flash, &v4l2_flash_ops, 416 &v4l2_config); 417 if (IS_ERR(led->v4l2_flash)) 418 return dev_err_probe(parent, PTR_ERR(led->v4l2_flash), 419 "Failed to register %d v4l2 sd\n", led->led_no); 420 421 return devm_add_action_or_reset(parent, mt6370_v4l2_flash_release, led->v4l2_flash); 422 } 423 424 static u32 mt6370_clamp(u32 val, u32 min, u32 max, u32 step) 425 { 426 u32 retval; 427 428 retval = clamp_val(val, min, max); 429 if (step > 1) 430 retval = rounddown(retval - min, step) + min; 431 432 return retval; 433 } 434 435 static int mt6370_init_flash_properties(struct device *dev, struct mt6370_led *led, 436 struct fwnode_handle *fwnode) 437 { 438 struct led_classdev_flash *flash = &led->flash; 439 struct led_classdev *lcdev = &flash->led_cdev; 440 struct mt6370_priv *priv = led->priv; 441 struct led_flash_setting *s; 442 u32 sources[MT6370_MAX_LEDS]; 443 u32 max_ua, val; 444 int i, ret, num; 445 446 num = fwnode_property_count_u32(fwnode, "led-sources"); 447 if (num < 1) 448 return dev_err_probe(dev, -EINVAL, 449 "Not specified or wrong number of led-sources\n"); 450 451 ret = fwnode_property_read_u32_array(fwnode, "led-sources", sources, num); 452 if (ret) 453 return ret; 454 455 for (i = 0; i < num; i++) { 456 if (sources[i] >= MT6370_MAX_LEDS) 457 return -EINVAL; 458 if (priv->leds_active & BIT(sources[i])) 459 return -EINVAL; 460 priv->leds_active |= BIT(sources[i]); 461 } 462 463 /* If both channels are specified in 'led-sources', joint flash output mode is used */ 464 led->led_no = num == 2 ? MT6370_LED_JOINT : sources[0]; 465 466 max_ua = num == 2 ? MT6370_ITORCH_DOUBLE_MAX_uA : MT6370_ITORCH_MAX_uA; 467 val = MT6370_ITORCH_MIN_uA; 468 ret = fwnode_property_read_u32(fwnode, "led-max-microamp", &val); 469 if (!ret) 470 val = mt6370_clamp(val, MT6370_ITORCH_MIN_uA, max_ua, MT6370_ITORCH_STEP_uA); 471 472 lcdev->max_brightness = (val - MT6370_ITORCH_MIN_uA) / MT6370_ITORCH_STEP_uA + 1; 473 lcdev->brightness_set_blocking = mt6370_torch_brightness_set; 474 lcdev->flags |= LED_DEV_CAP_FLASH; 475 476 max_ua = num == 2 ? MT6370_ISTRB_DOUBLE_MAX_uA : MT6370_ISTRB_MAX_uA; 477 val = MT6370_ISTRB_MIN_uA; 478 ret = fwnode_property_read_u32(fwnode, "flash-max-microamp", &val); 479 if (!ret) 480 val = mt6370_clamp(val, MT6370_ISTRB_MIN_uA, max_ua, MT6370_ISTRB_STEP_uA); 481 482 s = &flash->brightness; 483 s->min = MT6370_ISTRB_MIN_uA; 484 s->step = MT6370_ISTRB_STEP_uA; 485 s->val = s->max = val; 486 487 /* Always configure to the minimum level when off to prevent flash current spikes. */ 488 ret = _mt6370_flash_brightness_set(flash, s->min); 489 if (ret) 490 return ret; 491 492 val = MT6370_STRBTO_MIN_US; 493 ret = fwnode_property_read_u32(fwnode, "flash-max-timeout-us", &val); 494 if (!ret) 495 val = mt6370_clamp(val, MT6370_STRBTO_MIN_US, MT6370_STRBTO_MAX_US, 496 MT6370_STRBTO_STEP_US); 497 498 s = &flash->timeout; 499 s->min = MT6370_STRBTO_MIN_US; 500 s->step = MT6370_STRBTO_STEP_US; 501 s->val = s->max = val; 502 503 flash->ops = &mt6370_flash_ops; 504 505 return 0; 506 } 507 508 static int mt6370_led_probe(struct platform_device *pdev) 509 { 510 struct device *dev = &pdev->dev; 511 struct mt6370_priv *priv; 512 struct fwnode_handle *child; 513 size_t count; 514 int i = 0, ret; 515 516 count = device_get_child_node_count(dev); 517 if (!count || count > MT6370_MAX_LEDS) 518 return dev_err_probe(dev, -EINVAL, 519 "No child node or node count over max led number %zu\n", count); 520 521 priv = devm_kzalloc(dev, struct_size(priv, leds, count), GFP_KERNEL); 522 if (!priv) 523 return -ENOMEM; 524 525 priv->leds_count = count; 526 mutex_init(&priv->lock); 527 528 priv->regmap = dev_get_regmap(dev->parent, NULL); 529 if (!priv->regmap) 530 return dev_err_probe(dev, -ENODEV, "Failed to get parent regmap\n"); 531 532 device_for_each_child_node(dev, child) { 533 struct mt6370_led *led = priv->leds + i; 534 535 led->priv = priv; 536 537 ret = mt6370_init_flash_properties(dev, led, child); 538 if (ret) { 539 fwnode_handle_put(child); 540 return ret; 541 } 542 543 ret = mt6370_led_register(dev, led, child); 544 if (ret) { 545 fwnode_handle_put(child); 546 return ret; 547 } 548 549 i++; 550 } 551 552 return 0; 553 } 554 555 static const struct of_device_id mt6370_led_of_id[] = { 556 { .compatible = "mediatek,mt6370-flashlight" }, 557 {} 558 }; 559 MODULE_DEVICE_TABLE(of, mt6370_led_of_id); 560 561 static struct platform_driver mt6370_led_driver = { 562 .driver = { 563 .name = "mt6370-flashlight", 564 .of_match_table = mt6370_led_of_id, 565 }, 566 .probe = mt6370_led_probe, 567 }; 568 module_platform_driver(mt6370_led_driver); 569 570 MODULE_AUTHOR("Alice Chen <alice_chen@richtek.com>"); 571 MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>"); 572 MODULE_DESCRIPTION("MT6370 FLASH LED Driver"); 573 MODULE_LICENSE("GPL"); 574