0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/led-class-flash.h>
0012 #include <linux/mfd/max77693.h>
0013 #include <linux/mfd/max77693-common.h>
0014 #include <linux/mfd/max77693-private.h>
0015 #include <linux/module.h>
0016 #include <linux/mutex.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/regmap.h>
0019 #include <linux/slab.h>
0020 #include <media/v4l2-flash-led-class.h>
0021
0022 #define MODE_OFF 0
0023 #define MODE_FLASH(a) (1 << (a))
0024 #define MODE_TORCH(a) (1 << (2 + (a)))
0025 #define MODE_FLASH_EXTERNAL(a) (1 << (4 + (a)))
0026
0027 #define MODE_FLASH_MASK (MODE_FLASH(FLED1) | MODE_FLASH(FLED2) | \
0028 MODE_FLASH_EXTERNAL(FLED1) | \
0029 MODE_FLASH_EXTERNAL(FLED2))
0030 #define MODE_TORCH_MASK (MODE_TORCH(FLED1) | MODE_TORCH(FLED2))
0031
0032 #define FLED1_IOUT (1 << 0)
0033 #define FLED2_IOUT (1 << 1)
0034
0035 enum max77693_fled {
0036 FLED1,
0037 FLED2,
0038 };
0039
0040 enum max77693_led_mode {
0041 FLASH,
0042 TORCH,
0043 };
0044
0045 struct max77693_led_config_data {
0046 const char *label[2];
0047 u32 iout_torch_max[2];
0048 u32 iout_flash_max[2];
0049 u32 flash_timeout_max[2];
0050 u32 num_leds;
0051 u32 boost_mode;
0052 u32 boost_vout;
0053 u32 low_vsys;
0054 };
0055
0056 struct max77693_sub_led {
0057
0058 int fled_id;
0059
0060 struct led_classdev_flash fled_cdev;
0061
0062 struct v4l2_flash *v4l2_flash;
0063
0064
0065 unsigned int torch_brightness;
0066
0067 unsigned int flash_timeout;
0068
0069 u32 flash_faults;
0070 };
0071
0072 struct max77693_led_device {
0073
0074 struct regmap *regmap;
0075
0076 struct platform_device *pdev;
0077
0078 struct mutex lock;
0079
0080
0081 struct max77693_sub_led sub_leds[2];
0082
0083
0084 u32 iout_torch_max[2];
0085
0086 u32 iout_flash_max[2];
0087
0088
0089 unsigned int current_flash_timeout;
0090
0091 u8 torch_iout_reg;
0092
0093 unsigned int mode_flags;
0094
0095 int strobing_sub_led_id;
0096
0097 u8 fled_mask;
0098
0099 u8 allowed_modes;
0100
0101
0102 bool iout_joint;
0103 };
0104
0105 static u8 max77693_led_iout_to_reg(u32 ua)
0106 {
0107 if (ua < FLASH_IOUT_MIN)
0108 ua = FLASH_IOUT_MIN;
0109 return (ua - FLASH_IOUT_MIN) / FLASH_IOUT_STEP;
0110 }
0111
0112 static u8 max77693_flash_timeout_to_reg(u32 us)
0113 {
0114 return (us - FLASH_TIMEOUT_MIN) / FLASH_TIMEOUT_STEP;
0115 }
0116
0117 static inline struct max77693_sub_led *flcdev_to_sub_led(
0118 struct led_classdev_flash *fled_cdev)
0119 {
0120 return container_of(fled_cdev, struct max77693_sub_led, fled_cdev);
0121 }
0122
0123 static inline struct max77693_led_device *sub_led_to_led(
0124 struct max77693_sub_led *sub_led)
0125 {
0126 return container_of(sub_led, struct max77693_led_device,
0127 sub_leds[sub_led->fled_id]);
0128 }
0129
0130 static inline u8 max77693_led_vsys_to_reg(u32 mv)
0131 {
0132 return ((mv - MAX_FLASH1_VSYS_MIN) / MAX_FLASH1_VSYS_STEP) << 2;
0133 }
0134
0135 static inline u8 max77693_led_vout_to_reg(u32 mv)
0136 {
0137 return (mv - FLASH_VOUT_MIN) / FLASH_VOUT_STEP + FLASH_VOUT_RMIN;
0138 }
0139
0140 static inline bool max77693_fled_used(struct max77693_led_device *led,
0141 int fled_id)
0142 {
0143 u8 fled_bit = (fled_id == FLED1) ? FLED1_IOUT : FLED2_IOUT;
0144
0145 return led->fled_mask & fled_bit;
0146 }
0147
0148 static int max77693_set_mode_reg(struct max77693_led_device *led, u8 mode)
0149 {
0150 struct regmap *rmap = led->regmap;
0151 int ret, v = 0, i;
0152
0153 for (i = FLED1; i <= FLED2; ++i) {
0154 if (mode & MODE_TORCH(i))
0155 v |= FLASH_EN_ON << TORCH_EN_SHIFT(i);
0156
0157 if (mode & MODE_FLASH(i)) {
0158 v |= FLASH_EN_ON << FLASH_EN_SHIFT(i);
0159 } else if (mode & MODE_FLASH_EXTERNAL(i)) {
0160 v |= FLASH_EN_FLASH << FLASH_EN_SHIFT(i);
0161
0162
0163
0164
0165
0166 v |= FLASH_EN_TORCH << TORCH_EN_SHIFT(i);
0167 }
0168 }
0169
0170
0171 if (mode & ~(MODE_TORCH(FLED1) | MODE_TORCH(FLED2))) {
0172 ret = regmap_write(rmap, MAX77693_LED_REG_FLASH_EN, 0);
0173 if (ret < 0)
0174 return ret;
0175 }
0176
0177 return regmap_write(rmap, MAX77693_LED_REG_FLASH_EN, v);
0178 }
0179
0180 static int max77693_add_mode(struct max77693_led_device *led, u8 mode)
0181 {
0182 u8 new_mode_flags;
0183 int i, ret;
0184
0185 if (led->iout_joint)
0186
0187 mode |= (mode << 1);
0188
0189
0190
0191
0192
0193
0194 for (i = FLED1; i <= FLED2; ++i)
0195 if (mode & MODE_FLASH_EXTERNAL(i))
0196 led->mode_flags &= (~MODE_TORCH(i) & ~MODE_FLASH(i));
0197
0198 new_mode_flags = mode | led->mode_flags;
0199 new_mode_flags &= led->allowed_modes;
0200
0201 if (new_mode_flags ^ led->mode_flags)
0202 led->mode_flags = new_mode_flags;
0203 else
0204 return 0;
0205
0206 ret = max77693_set_mode_reg(led, led->mode_flags);
0207 if (ret < 0)
0208 return ret;
0209
0210
0211
0212
0213
0214 if (mode & MODE_FLASH_MASK)
0215 led->mode_flags &= ~mode;
0216
0217 return ret;
0218 }
0219
0220 static int max77693_clear_mode(struct max77693_led_device *led,
0221 u8 mode)
0222 {
0223 if (led->iout_joint)
0224
0225 mode |= (mode << 1);
0226
0227 led->mode_flags &= ~mode;
0228
0229 return max77693_set_mode_reg(led, led->mode_flags);
0230 }
0231
0232 static void max77693_add_allowed_modes(struct max77693_led_device *led,
0233 int fled_id, enum max77693_led_mode mode)
0234 {
0235 if (mode == FLASH)
0236 led->allowed_modes |= (MODE_FLASH(fled_id) |
0237 MODE_FLASH_EXTERNAL(fled_id));
0238 else
0239 led->allowed_modes |= MODE_TORCH(fled_id);
0240 }
0241
0242 static void max77693_distribute_currents(struct max77693_led_device *led,
0243 int fled_id, enum max77693_led_mode mode,
0244 u32 micro_amp, u32 iout_max[2], u32 iout[2])
0245 {
0246 if (!led->iout_joint) {
0247 iout[fled_id] = micro_amp;
0248 max77693_add_allowed_modes(led, fled_id, mode);
0249 return;
0250 }
0251
0252 iout[FLED1] = min(micro_amp, iout_max[FLED1]);
0253 iout[FLED2] = micro_amp - iout[FLED1];
0254
0255 if (mode == FLASH)
0256 led->allowed_modes &= ~MODE_FLASH_MASK;
0257 else
0258 led->allowed_modes &= ~MODE_TORCH_MASK;
0259
0260 max77693_add_allowed_modes(led, FLED1, mode);
0261
0262 if (iout[FLED2])
0263 max77693_add_allowed_modes(led, FLED2, mode);
0264 }
0265
0266 static int max77693_set_torch_current(struct max77693_led_device *led,
0267 int fled_id, u32 micro_amp)
0268 {
0269 struct regmap *rmap = led->regmap;
0270 u8 iout1_reg = 0, iout2_reg = 0;
0271 u32 iout[2];
0272
0273 max77693_distribute_currents(led, fled_id, TORCH, micro_amp,
0274 led->iout_torch_max, iout);
0275
0276 if (fled_id == FLED1 || led->iout_joint) {
0277 iout1_reg = max77693_led_iout_to_reg(iout[FLED1]);
0278 led->torch_iout_reg &= TORCH_IOUT_MASK(TORCH_IOUT2_SHIFT);
0279 }
0280 if (fled_id == FLED2 || led->iout_joint) {
0281 iout2_reg = max77693_led_iout_to_reg(iout[FLED2]);
0282 led->torch_iout_reg &= TORCH_IOUT_MASK(TORCH_IOUT1_SHIFT);
0283 }
0284
0285 led->torch_iout_reg |= ((iout1_reg << TORCH_IOUT1_SHIFT) |
0286 (iout2_reg << TORCH_IOUT2_SHIFT));
0287
0288 return regmap_write(rmap, MAX77693_LED_REG_ITORCH,
0289 led->torch_iout_reg);
0290 }
0291
0292 static int max77693_set_flash_current(struct max77693_led_device *led,
0293 int fled_id,
0294 u32 micro_amp)
0295 {
0296 struct regmap *rmap = led->regmap;
0297 u8 iout1_reg, iout2_reg;
0298 u32 iout[2];
0299 int ret = -EINVAL;
0300
0301 max77693_distribute_currents(led, fled_id, FLASH, micro_amp,
0302 led->iout_flash_max, iout);
0303
0304 if (fled_id == FLED1 || led->iout_joint) {
0305 iout1_reg = max77693_led_iout_to_reg(iout[FLED1]);
0306 ret = regmap_write(rmap, MAX77693_LED_REG_IFLASH1,
0307 iout1_reg);
0308 if (ret < 0)
0309 return ret;
0310 }
0311 if (fled_id == FLED2 || led->iout_joint) {
0312 iout2_reg = max77693_led_iout_to_reg(iout[FLED2]);
0313 ret = regmap_write(rmap, MAX77693_LED_REG_IFLASH2,
0314 iout2_reg);
0315 }
0316
0317 return ret;
0318 }
0319
0320 static int max77693_set_timeout(struct max77693_led_device *led, u32 microsec)
0321 {
0322 struct regmap *rmap = led->regmap;
0323 u8 v;
0324 int ret;
0325
0326 v = max77693_flash_timeout_to_reg(microsec) | FLASH_TMR_LEVEL;
0327
0328 ret = regmap_write(rmap, MAX77693_LED_REG_FLASH_TIMER, v);
0329 if (ret < 0)
0330 return ret;
0331
0332 led->current_flash_timeout = microsec;
0333
0334 return 0;
0335 }
0336
0337 static int max77693_get_strobe_status(struct max77693_led_device *led,
0338 bool *state)
0339 {
0340 struct regmap *rmap = led->regmap;
0341 unsigned int v;
0342 int ret;
0343
0344 ret = regmap_read(rmap, MAX77693_LED_REG_FLASH_STATUS, &v);
0345 if (ret < 0)
0346 return ret;
0347
0348 *state = v & FLASH_STATUS_FLASH_ON;
0349
0350 return ret;
0351 }
0352
0353 static int max77693_get_flash_faults(struct max77693_sub_led *sub_led)
0354 {
0355 struct max77693_led_device *led = sub_led_to_led(sub_led);
0356 struct regmap *rmap = led->regmap;
0357 unsigned int v;
0358 u8 fault_open_mask, fault_short_mask;
0359 int ret;
0360
0361 sub_led->flash_faults = 0;
0362
0363 if (led->iout_joint) {
0364 fault_open_mask = FLASH_INT_FLED1_OPEN | FLASH_INT_FLED2_OPEN;
0365 fault_short_mask = FLASH_INT_FLED1_SHORT |
0366 FLASH_INT_FLED2_SHORT;
0367 } else {
0368 fault_open_mask = (sub_led->fled_id == FLED1) ?
0369 FLASH_INT_FLED1_OPEN :
0370 FLASH_INT_FLED2_OPEN;
0371 fault_short_mask = (sub_led->fled_id == FLED1) ?
0372 FLASH_INT_FLED1_SHORT :
0373 FLASH_INT_FLED2_SHORT;
0374 }
0375
0376 ret = regmap_read(rmap, MAX77693_LED_REG_FLASH_INT, &v);
0377 if (ret < 0)
0378 return ret;
0379
0380 if (v & fault_open_mask)
0381 sub_led->flash_faults |= LED_FAULT_OVER_VOLTAGE;
0382 if (v & fault_short_mask)
0383 sub_led->flash_faults |= LED_FAULT_SHORT_CIRCUIT;
0384 if (v & FLASH_INT_OVER_CURRENT)
0385 sub_led->flash_faults |= LED_FAULT_OVER_CURRENT;
0386
0387 return 0;
0388 }
0389
0390 static int max77693_setup(struct max77693_led_device *led,
0391 struct max77693_led_config_data *led_cfg)
0392 {
0393 struct regmap *rmap = led->regmap;
0394 int i, first_led, last_led, ret;
0395 u32 max_flash_curr[2];
0396 u8 v;
0397
0398
0399
0400
0401
0402
0403 if (led->iout_joint) {
0404 first_led = FLED1;
0405 last_led = FLED1;
0406 max_flash_curr[FLED1] = led_cfg->iout_flash_max[FLED1] +
0407 led_cfg->iout_flash_max[FLED2];
0408 } else {
0409 first_led = max77693_fled_used(led, FLED1) ? FLED1 : FLED2;
0410 last_led = max77693_fled_used(led, FLED2) ? FLED2 : FLED1;
0411 max_flash_curr[FLED1] = led_cfg->iout_flash_max[FLED1];
0412 max_flash_curr[FLED2] = led_cfg->iout_flash_max[FLED2];
0413 }
0414
0415 for (i = first_led; i <= last_led; ++i) {
0416 ret = max77693_set_flash_current(led, i,
0417 max_flash_curr[i]);
0418 if (ret < 0)
0419 return ret;
0420 }
0421
0422 v = TORCH_TMR_NO_TIMER | MAX77693_LED_TRIG_TYPE_LEVEL;
0423 ret = regmap_write(rmap, MAX77693_LED_REG_ITORCHTIMER, v);
0424 if (ret < 0)
0425 return ret;
0426
0427 if (led_cfg->low_vsys > 0)
0428 v = max77693_led_vsys_to_reg(led_cfg->low_vsys) |
0429 MAX_FLASH1_MAX_FL_EN;
0430 else
0431 v = 0;
0432
0433 ret = regmap_write(rmap, MAX77693_LED_REG_MAX_FLASH1, v);
0434 if (ret < 0)
0435 return ret;
0436 ret = regmap_write(rmap, MAX77693_LED_REG_MAX_FLASH2, 0);
0437 if (ret < 0)
0438 return ret;
0439
0440 if (led_cfg->boost_mode == MAX77693_LED_BOOST_FIXED)
0441 v = FLASH_BOOST_FIXED;
0442 else
0443 v = led_cfg->boost_mode | led_cfg->boost_mode << 1;
0444
0445 if (max77693_fled_used(led, FLED1) && max77693_fled_used(led, FLED2))
0446 v |= FLASH_BOOST_LEDNUM_2;
0447
0448 ret = regmap_write(rmap, MAX77693_LED_REG_VOUT_CNTL, v);
0449 if (ret < 0)
0450 return ret;
0451
0452 v = max77693_led_vout_to_reg(led_cfg->boost_vout);
0453 ret = regmap_write(rmap, MAX77693_LED_REG_VOUT_FLASH1, v);
0454 if (ret < 0)
0455 return ret;
0456
0457 return max77693_set_mode_reg(led, MODE_OFF);
0458 }
0459
0460
0461 static int max77693_led_brightness_set(struct led_classdev *led_cdev,
0462 enum led_brightness value)
0463 {
0464 struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev);
0465 struct max77693_sub_led *sub_led = flcdev_to_sub_led(fled_cdev);
0466 struct max77693_led_device *led = sub_led_to_led(sub_led);
0467 int fled_id = sub_led->fled_id, ret;
0468
0469 mutex_lock(&led->lock);
0470
0471 if (value == 0) {
0472 ret = max77693_clear_mode(led, MODE_TORCH(fled_id));
0473 if (ret < 0)
0474 dev_dbg(&led->pdev->dev,
0475 "Failed to clear torch mode (%d)\n",
0476 ret);
0477 goto unlock;
0478 }
0479
0480 ret = max77693_set_torch_current(led, fled_id, value * TORCH_IOUT_STEP);
0481 if (ret < 0) {
0482 dev_dbg(&led->pdev->dev,
0483 "Failed to set torch current (%d)\n",
0484 ret);
0485 goto unlock;
0486 }
0487
0488 ret = max77693_add_mode(led, MODE_TORCH(fled_id));
0489 if (ret < 0)
0490 dev_dbg(&led->pdev->dev,
0491 "Failed to set torch mode (%d)\n",
0492 ret);
0493 unlock:
0494 mutex_unlock(&led->lock);
0495
0496 return ret;
0497 }
0498
0499 static int max77693_led_flash_brightness_set(
0500 struct led_classdev_flash *fled_cdev,
0501 u32 brightness)
0502 {
0503 struct max77693_sub_led *sub_led = flcdev_to_sub_led(fled_cdev);
0504 struct max77693_led_device *led = sub_led_to_led(sub_led);
0505 int ret;
0506
0507 mutex_lock(&led->lock);
0508 ret = max77693_set_flash_current(led, sub_led->fled_id, brightness);
0509 mutex_unlock(&led->lock);
0510
0511 return ret;
0512 }
0513
0514 static int max77693_led_flash_strobe_set(
0515 struct led_classdev_flash *fled_cdev,
0516 bool state)
0517 {
0518 struct max77693_sub_led *sub_led = flcdev_to_sub_led(fled_cdev);
0519 struct max77693_led_device *led = sub_led_to_led(sub_led);
0520 int fled_id = sub_led->fled_id;
0521 int ret;
0522
0523 mutex_lock(&led->lock);
0524
0525 if (!state) {
0526 ret = max77693_clear_mode(led, MODE_FLASH(fled_id));
0527 goto unlock;
0528 }
0529
0530 if (sub_led->flash_timeout != led->current_flash_timeout) {
0531 ret = max77693_set_timeout(led, sub_led->flash_timeout);
0532 if (ret < 0)
0533 goto unlock;
0534 }
0535
0536 led->strobing_sub_led_id = fled_id;
0537
0538 ret = max77693_add_mode(led, MODE_FLASH(fled_id));
0539 if (ret < 0)
0540 goto unlock;
0541
0542 ret = max77693_get_flash_faults(sub_led);
0543
0544 unlock:
0545 mutex_unlock(&led->lock);
0546 return ret;
0547 }
0548
0549 static int max77693_led_flash_fault_get(
0550 struct led_classdev_flash *fled_cdev,
0551 u32 *fault)
0552 {
0553 struct max77693_sub_led *sub_led = flcdev_to_sub_led(fled_cdev);
0554
0555 *fault = sub_led->flash_faults;
0556
0557 return 0;
0558 }
0559
0560 static int max77693_led_flash_strobe_get(
0561 struct led_classdev_flash *fled_cdev,
0562 bool *state)
0563 {
0564 struct max77693_sub_led *sub_led = flcdev_to_sub_led(fled_cdev);
0565 struct max77693_led_device *led = sub_led_to_led(sub_led);
0566 int ret;
0567
0568 if (!state)
0569 return -EINVAL;
0570
0571 mutex_lock(&led->lock);
0572
0573 ret = max77693_get_strobe_status(led, state);
0574
0575 *state = !!(*state && (led->strobing_sub_led_id == sub_led->fled_id));
0576
0577 mutex_unlock(&led->lock);
0578
0579 return ret;
0580 }
0581
0582 static int max77693_led_flash_timeout_set(
0583 struct led_classdev_flash *fled_cdev,
0584 u32 timeout)
0585 {
0586 struct max77693_sub_led *sub_led = flcdev_to_sub_led(fled_cdev);
0587 struct max77693_led_device *led = sub_led_to_led(sub_led);
0588
0589 mutex_lock(&led->lock);
0590 sub_led->flash_timeout = timeout;
0591 mutex_unlock(&led->lock);
0592
0593 return 0;
0594 }
0595
0596 static int max77693_led_parse_dt(struct max77693_led_device *led,
0597 struct max77693_led_config_data *cfg,
0598 struct device_node **sub_nodes)
0599 {
0600 struct device *dev = &led->pdev->dev;
0601 struct max77693_sub_led *sub_leds = led->sub_leds;
0602 struct device_node *node = dev_of_node(dev), *child_node;
0603 struct property *prop;
0604 u32 led_sources[2];
0605 int i, ret, fled_id;
0606
0607 of_property_read_u32(node, "maxim,boost-mode", &cfg->boost_mode);
0608 of_property_read_u32(node, "maxim,boost-mvout", &cfg->boost_vout);
0609 of_property_read_u32(node, "maxim,mvsys-min", &cfg->low_vsys);
0610
0611 for_each_available_child_of_node(node, child_node) {
0612 prop = of_find_property(child_node, "led-sources", NULL);
0613 if (prop) {
0614 const __be32 *srcs = NULL;
0615
0616 for (i = 0; i < ARRAY_SIZE(led_sources); ++i) {
0617 srcs = of_prop_next_u32(prop, srcs,
0618 &led_sources[i]);
0619 if (!srcs)
0620 break;
0621 }
0622 } else {
0623 dev_err(dev,
0624 "led-sources DT property missing\n");
0625 of_node_put(child_node);
0626 return -EINVAL;
0627 }
0628
0629 if (i == 2) {
0630 fled_id = FLED1;
0631 led->fled_mask = FLED1_IOUT | FLED2_IOUT;
0632 } else if (led_sources[0] == FLED1) {
0633 fled_id = FLED1;
0634 led->fled_mask |= FLED1_IOUT;
0635 } else if (led_sources[0] == FLED2) {
0636 fled_id = FLED2;
0637 led->fled_mask |= FLED2_IOUT;
0638 } else {
0639 dev_err(dev,
0640 "Wrong led-sources DT property value.\n");
0641 of_node_put(child_node);
0642 return -EINVAL;
0643 }
0644
0645 if (sub_nodes[fled_id]) {
0646 dev_err(dev,
0647 "Conflicting \"led-sources\" DT properties\n");
0648 of_node_put(child_node);
0649 return -EINVAL;
0650 }
0651
0652 sub_nodes[fled_id] = child_node;
0653 sub_leds[fled_id].fled_id = fled_id;
0654
0655 cfg->label[fled_id] =
0656 of_get_property(child_node, "label", NULL) ? :
0657 child_node->name;
0658
0659 ret = of_property_read_u32(child_node, "led-max-microamp",
0660 &cfg->iout_torch_max[fled_id]);
0661 if (ret < 0) {
0662 cfg->iout_torch_max[fled_id] = TORCH_IOUT_MIN;
0663 dev_warn(dev, "led-max-microamp DT property missing\n");
0664 }
0665
0666 ret = of_property_read_u32(child_node, "flash-max-microamp",
0667 &cfg->iout_flash_max[fled_id]);
0668 if (ret < 0) {
0669 cfg->iout_flash_max[fled_id] = FLASH_IOUT_MIN;
0670 dev_warn(dev,
0671 "flash-max-microamp DT property missing\n");
0672 }
0673
0674 ret = of_property_read_u32(child_node, "flash-max-timeout-us",
0675 &cfg->flash_timeout_max[fled_id]);
0676 if (ret < 0) {
0677 cfg->flash_timeout_max[fled_id] = FLASH_TIMEOUT_MIN;
0678 dev_warn(dev,
0679 "flash-max-timeout-us DT property missing\n");
0680 }
0681
0682 if (++cfg->num_leds == 2 ||
0683 (max77693_fled_used(led, FLED1) &&
0684 max77693_fled_used(led, FLED2))) {
0685 of_node_put(child_node);
0686 break;
0687 }
0688 }
0689
0690 if (cfg->num_leds == 0) {
0691 dev_err(dev, "No DT child node found for connected LED(s).\n");
0692 return -EINVAL;
0693 }
0694
0695 return 0;
0696 }
0697
0698 static void clamp_align(u32 *v, u32 min, u32 max, u32 step)
0699 {
0700 *v = clamp_val(*v, min, max);
0701 if (step > 1)
0702 *v = (*v - min) / step * step + min;
0703 }
0704
0705 static void max77693_align_iout_current(struct max77693_led_device *led,
0706 u32 *iout, u32 min, u32 max, u32 step)
0707 {
0708 int i;
0709
0710 if (led->iout_joint) {
0711 if (iout[FLED1] > min) {
0712 iout[FLED1] /= 2;
0713 iout[FLED2] = iout[FLED1];
0714 } else {
0715 iout[FLED1] = min;
0716 iout[FLED2] = 0;
0717 return;
0718 }
0719 }
0720
0721 for (i = FLED1; i <= FLED2; ++i)
0722 if (max77693_fled_used(led, i))
0723 clamp_align(&iout[i], min, max, step);
0724 else
0725 iout[i] = 0;
0726 }
0727
0728 static void max77693_led_validate_configuration(struct max77693_led_device *led,
0729 struct max77693_led_config_data *cfg)
0730 {
0731 u32 flash_iout_max = cfg->boost_mode ? FLASH_IOUT_MAX_2LEDS :
0732 FLASH_IOUT_MAX_1LED;
0733 int i;
0734
0735 if (cfg->num_leds == 1 &&
0736 max77693_fled_used(led, FLED1) && max77693_fled_used(led, FLED2))
0737 led->iout_joint = true;
0738
0739 cfg->boost_mode = clamp_val(cfg->boost_mode, MAX77693_LED_BOOST_NONE,
0740 MAX77693_LED_BOOST_FIXED);
0741
0742
0743 if ((cfg->boost_mode == MAX77693_LED_BOOST_NONE) && led->iout_joint)
0744 cfg->boost_mode = MAX77693_LED_BOOST_FIXED;
0745
0746 max77693_align_iout_current(led, cfg->iout_torch_max,
0747 TORCH_IOUT_MIN, TORCH_IOUT_MAX, TORCH_IOUT_STEP);
0748
0749 max77693_align_iout_current(led, cfg->iout_flash_max,
0750 FLASH_IOUT_MIN, flash_iout_max, FLASH_IOUT_STEP);
0751
0752 for (i = 0; i < ARRAY_SIZE(cfg->flash_timeout_max); ++i)
0753 clamp_align(&cfg->flash_timeout_max[i], FLASH_TIMEOUT_MIN,
0754 FLASH_TIMEOUT_MAX, FLASH_TIMEOUT_STEP);
0755
0756 clamp_align(&cfg->boost_vout, FLASH_VOUT_MIN, FLASH_VOUT_MAX,
0757 FLASH_VOUT_STEP);
0758
0759 if (cfg->low_vsys)
0760 clamp_align(&cfg->low_vsys, MAX_FLASH1_VSYS_MIN,
0761 MAX_FLASH1_VSYS_MAX, MAX_FLASH1_VSYS_STEP);
0762 }
0763
0764 static int max77693_led_get_configuration(struct max77693_led_device *led,
0765 struct max77693_led_config_data *cfg,
0766 struct device_node **sub_nodes)
0767 {
0768 int ret;
0769
0770 ret = max77693_led_parse_dt(led, cfg, sub_nodes);
0771 if (ret < 0)
0772 return ret;
0773
0774 max77693_led_validate_configuration(led, cfg);
0775
0776 memcpy(led->iout_torch_max, cfg->iout_torch_max,
0777 sizeof(led->iout_torch_max));
0778 memcpy(led->iout_flash_max, cfg->iout_flash_max,
0779 sizeof(led->iout_flash_max));
0780
0781 return 0;
0782 }
0783
0784 static const struct led_flash_ops flash_ops = {
0785 .flash_brightness_set = max77693_led_flash_brightness_set,
0786 .strobe_set = max77693_led_flash_strobe_set,
0787 .strobe_get = max77693_led_flash_strobe_get,
0788 .timeout_set = max77693_led_flash_timeout_set,
0789 .fault_get = max77693_led_flash_fault_get,
0790 };
0791
0792 static void max77693_init_flash_settings(struct max77693_sub_led *sub_led,
0793 struct max77693_led_config_data *led_cfg)
0794 {
0795 struct led_classdev_flash *fled_cdev = &sub_led->fled_cdev;
0796 struct max77693_led_device *led = sub_led_to_led(sub_led);
0797 int fled_id = sub_led->fled_id;
0798 struct led_flash_setting *setting;
0799
0800
0801 setting = &fled_cdev->brightness;
0802 setting->min = FLASH_IOUT_MIN;
0803 setting->max = led->iout_joint ?
0804 led_cfg->iout_flash_max[FLED1] +
0805 led_cfg->iout_flash_max[FLED2] :
0806 led_cfg->iout_flash_max[fled_id];
0807 setting->step = FLASH_IOUT_STEP;
0808 setting->val = setting->max;
0809
0810
0811 setting = &fled_cdev->timeout;
0812 setting->min = FLASH_TIMEOUT_MIN;
0813 setting->max = led_cfg->flash_timeout_max[fled_id];
0814 setting->step = FLASH_TIMEOUT_STEP;
0815 setting->val = setting->max;
0816 }
0817
0818 #if IS_ENABLED(CONFIG_V4L2_FLASH_LED_CLASS)
0819
0820 static int max77693_led_external_strobe_set(
0821 struct v4l2_flash *v4l2_flash,
0822 bool enable)
0823 {
0824 struct max77693_sub_led *sub_led =
0825 flcdev_to_sub_led(v4l2_flash->fled_cdev);
0826 struct max77693_led_device *led = sub_led_to_led(sub_led);
0827 int fled_id = sub_led->fled_id;
0828 int ret;
0829
0830 mutex_lock(&led->lock);
0831
0832 if (enable)
0833 ret = max77693_add_mode(led, MODE_FLASH_EXTERNAL(fled_id));
0834 else
0835 ret = max77693_clear_mode(led, MODE_FLASH_EXTERNAL(fled_id));
0836
0837 mutex_unlock(&led->lock);
0838
0839 return ret;
0840 }
0841
0842 static void max77693_init_v4l2_flash_config(struct max77693_sub_led *sub_led,
0843 struct max77693_led_config_data *led_cfg,
0844 struct v4l2_flash_config *v4l2_sd_cfg)
0845 {
0846 struct max77693_led_device *led = sub_led_to_led(sub_led);
0847 struct device *dev = &led->pdev->dev;
0848 struct max77693_dev *iodev = dev_get_drvdata(dev->parent);
0849 struct i2c_client *i2c = iodev->i2c;
0850 struct led_flash_setting *s;
0851
0852 snprintf(v4l2_sd_cfg->dev_name, sizeof(v4l2_sd_cfg->dev_name),
0853 "%s %d-%04x", sub_led->fled_cdev.led_cdev.name,
0854 i2c_adapter_id(i2c->adapter), i2c->addr);
0855
0856 s = &v4l2_sd_cfg->intensity;
0857 s->min = TORCH_IOUT_MIN;
0858 s->max = sub_led->fled_cdev.led_cdev.max_brightness * TORCH_IOUT_STEP;
0859 s->step = TORCH_IOUT_STEP;
0860 s->val = s->max;
0861
0862
0863 v4l2_sd_cfg->flash_faults = LED_FAULT_OVER_VOLTAGE |
0864 LED_FAULT_SHORT_CIRCUIT |
0865 LED_FAULT_OVER_CURRENT;
0866
0867 v4l2_sd_cfg->has_external_strobe = true;
0868 }
0869
0870 static const struct v4l2_flash_ops v4l2_flash_ops = {
0871 .external_strobe_set = max77693_led_external_strobe_set,
0872 };
0873 #else
0874 static inline void max77693_init_v4l2_flash_config(
0875 struct max77693_sub_led *sub_led,
0876 struct max77693_led_config_data *led_cfg,
0877 struct v4l2_flash_config *v4l2_sd_cfg)
0878 {
0879 }
0880 static const struct v4l2_flash_ops v4l2_flash_ops;
0881 #endif
0882
0883 static void max77693_init_fled_cdev(struct max77693_sub_led *sub_led,
0884 struct max77693_led_config_data *led_cfg)
0885 {
0886 struct max77693_led_device *led = sub_led_to_led(sub_led);
0887 int fled_id = sub_led->fled_id;
0888 struct led_classdev_flash *fled_cdev;
0889 struct led_classdev *led_cdev;
0890
0891
0892 fled_cdev = &sub_led->fled_cdev;
0893 fled_cdev->ops = &flash_ops;
0894 led_cdev = &fled_cdev->led_cdev;
0895
0896 led_cdev->name = led_cfg->label[fled_id];
0897
0898 led_cdev->brightness_set_blocking = max77693_led_brightness_set;
0899 led_cdev->max_brightness = (led->iout_joint ?
0900 led_cfg->iout_torch_max[FLED1] +
0901 led_cfg->iout_torch_max[FLED2] :
0902 led_cfg->iout_torch_max[fled_id]) /
0903 TORCH_IOUT_STEP;
0904 led_cdev->flags |= LED_DEV_CAP_FLASH;
0905
0906 max77693_init_flash_settings(sub_led, led_cfg);
0907
0908
0909 sub_led->flash_timeout = fled_cdev->timeout.val;
0910 }
0911
0912 static int max77693_register_led(struct max77693_sub_led *sub_led,
0913 struct max77693_led_config_data *led_cfg,
0914 struct device_node *sub_node)
0915 {
0916 struct max77693_led_device *led = sub_led_to_led(sub_led);
0917 struct led_classdev_flash *fled_cdev = &sub_led->fled_cdev;
0918 struct device *dev = &led->pdev->dev;
0919 struct v4l2_flash_config v4l2_sd_cfg = {};
0920 int ret;
0921
0922
0923 ret = led_classdev_flash_register(dev, fled_cdev);
0924 if (ret < 0)
0925 return ret;
0926
0927 max77693_init_v4l2_flash_config(sub_led, led_cfg, &v4l2_sd_cfg);
0928
0929
0930 sub_led->v4l2_flash = v4l2_flash_init(dev, of_fwnode_handle(sub_node),
0931 fled_cdev, &v4l2_flash_ops,
0932 &v4l2_sd_cfg);
0933 if (IS_ERR(sub_led->v4l2_flash)) {
0934 ret = PTR_ERR(sub_led->v4l2_flash);
0935 goto err_v4l2_flash_init;
0936 }
0937
0938 return 0;
0939
0940 err_v4l2_flash_init:
0941 led_classdev_flash_unregister(fled_cdev);
0942 return ret;
0943 }
0944
0945 static int max77693_led_probe(struct platform_device *pdev)
0946 {
0947 struct device *dev = &pdev->dev;
0948 struct max77693_dev *iodev = dev_get_drvdata(dev->parent);
0949 struct max77693_led_device *led;
0950 struct max77693_sub_led *sub_leds;
0951 struct device_node *sub_nodes[2] = {};
0952 struct max77693_led_config_data led_cfg = {};
0953 int init_fled_cdev[2], i, ret;
0954
0955 led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
0956 if (!led)
0957 return -ENOMEM;
0958
0959 led->pdev = pdev;
0960 led->regmap = iodev->regmap;
0961 led->allowed_modes = MODE_FLASH_MASK;
0962 sub_leds = led->sub_leds;
0963
0964 platform_set_drvdata(pdev, led);
0965 ret = max77693_led_get_configuration(led, &led_cfg, sub_nodes);
0966 if (ret < 0)
0967 return ret;
0968
0969 ret = max77693_setup(led, &led_cfg);
0970 if (ret < 0)
0971 return ret;
0972
0973 mutex_init(&led->lock);
0974
0975 init_fled_cdev[FLED1] =
0976 led->iout_joint || max77693_fled_used(led, FLED1);
0977 init_fled_cdev[FLED2] =
0978 !led->iout_joint && max77693_fled_used(led, FLED2);
0979
0980 for (i = FLED1; i <= FLED2; ++i) {
0981 if (!init_fled_cdev[i])
0982 continue;
0983
0984
0985 max77693_init_fled_cdev(&sub_leds[i], &led_cfg);
0986
0987
0988
0989
0990
0991 ret = max77693_register_led(&sub_leds[i], &led_cfg,
0992 sub_nodes[i]);
0993 if (ret < 0) {
0994
0995
0996
0997
0998 if (i == FLED2)
0999 goto err_register_led2;
1000 else
1001 goto err_register_led1;
1002 }
1003 }
1004
1005 return 0;
1006
1007 err_register_led2:
1008
1009 if (!init_fled_cdev[FLED1])
1010 goto err_register_led1;
1011 v4l2_flash_release(sub_leds[FLED1].v4l2_flash);
1012 led_classdev_flash_unregister(&sub_leds[FLED1].fled_cdev);
1013 err_register_led1:
1014 mutex_destroy(&led->lock);
1015
1016 return ret;
1017 }
1018
1019 static int max77693_led_remove(struct platform_device *pdev)
1020 {
1021 struct max77693_led_device *led = platform_get_drvdata(pdev);
1022 struct max77693_sub_led *sub_leds = led->sub_leds;
1023
1024 if (led->iout_joint || max77693_fled_used(led, FLED1)) {
1025 v4l2_flash_release(sub_leds[FLED1].v4l2_flash);
1026 led_classdev_flash_unregister(&sub_leds[FLED1].fled_cdev);
1027 }
1028
1029 if (!led->iout_joint && max77693_fled_used(led, FLED2)) {
1030 v4l2_flash_release(sub_leds[FLED2].v4l2_flash);
1031 led_classdev_flash_unregister(&sub_leds[FLED2].fled_cdev);
1032 }
1033
1034 mutex_destroy(&led->lock);
1035
1036 return 0;
1037 }
1038
1039 static const struct of_device_id max77693_led_dt_match[] = {
1040 { .compatible = "maxim,max77693-led" },
1041 {},
1042 };
1043 MODULE_DEVICE_TABLE(of, max77693_led_dt_match);
1044
1045 static struct platform_driver max77693_led_driver = {
1046 .probe = max77693_led_probe,
1047 .remove = max77693_led_remove,
1048 .driver = {
1049 .name = "max77693-led",
1050 .of_match_table = max77693_led_dt_match,
1051 },
1052 };
1053
1054 module_platform_driver(max77693_led_driver);
1055
1056 MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>");
1057 MODULE_AUTHOR("Andrzej Hajda <a.hajda@samsung.com>");
1058 MODULE_DESCRIPTION("Maxim MAX77693 led flash driver");
1059 MODULE_LICENSE("GPL v2");