/* * There is only one set of flash control logic, and this flag is used to check if 'strobe' * is currently being used.
*/ if (priv->fled_strobe_used) {
dev_warn(lcdev->dev, "Please disable strobe first [%d]\n", priv->fled_strobe_used);
ret = -EBUSY; goto unlock;
}
if (level) {
level -= 1; if (led->led_no == MT6370_LED_JOINT) {
u32 flevel[MT6370_MAX_LEDS];
/* * There're two flash channels in MT6370. If joint flash output is used, * torch current will be averaged output from both channels.
*/
flevel[0] = level / 2;
flevel[1] = level - flevel[0]; for (i = 0; i < MT6370_MAX_LEDS; i++) {
ret = regmap_update_bits(priv->regmap, MT6370_REG_FLEDITOR(i),
MT6370_ITORCH_MASK, flevel[i]); if (ret) goto unlock;
}
} else {
ret = regmap_update_bits(priv->regmap, MT6370_REG_FLEDITOR(led->led_no),
MT6370_ITORCH_MASK, level); if (ret) goto unlock;
}
}
ret = regmap_update_bits(priv->regmap, MT6370_REG_FLEDEN, enable_mask, val); if (ret) goto unlock;
priv->fled_torch_used = curr;
unlock:
mutex_unlock(&priv->lock); return ret;
}
staticint mt6370_flash_brightness_set(struct led_classdev_flash *fl_cdev, u32 brightness)
{ /* * Because of the current spikes when turning on the flash, the brightness should be kept * by the LED framework. This empty function is used to prevent checking failure when * led_classdev_flash registers ops.
*/ return 0;
}
if (led->led_no == MT6370_LED_JOINT) {
u32 flevel[MT6370_MAX_LEDS];
/* * There're two flash channels in MT6370. If joint flash output is used, storbe * current will be averaged output from both channels.
*/
flevel[0] = val / 2;
flevel[1] = val - flevel[0]; for (i = 0; i < MT6370_MAX_LEDS; i++) {
ret = regmap_update_bits(priv->regmap, MT6370_REG_FLEDISTRB(i),
MT6370_ISTROBE_MASK, flevel[i]); if (ret) break;
}
} else {
ret = regmap_update_bits(priv->regmap, MT6370_REG_FLEDISTRB(led->led_no),
MT6370_ISTROBE_MASK, val);
}
/* * There is only one set of flash control logic, and this flag is used to check if 'torch' * is currently being used.
*/ if (priv->fled_torch_used) {
dev_warn(lcdev->dev, "Please disable torch first [0x%x]\n", priv->fled_torch_used);
ret = -EBUSY; goto unlock;
}
ret = regmap_update_bits(priv->regmap, MT6370_REG_FLEDEN, enable_mask, val); if (ret) {
dev_err(lcdev->dev, "[%d] control current source %d fail\n", led->led_no, state); goto unlock;
}
/* * If the flash needs to turn on, configure the flash current to ramp up to the setting * value. Otherwise, always revert to the minimum one.
*/
ret = _mt6370_flash_brightness_set(fl_cdev, state ? s->val : s->min); if (ret) {
dev_err(lcdev->dev, "[%d] Failed to set brightness\n", led->led_no); goto unlock;
}
/* * For the flash to turn on/off, we must wait for HW ramping up/down time 5ms/500us to * prevent the unexpected problem.
*/ if (!priv->fled_strobe_used && curr)
usleep_range(5000, 6000); elseif (priv->fled_strobe_used && !curr)
usleep_range(500, 600);
num = fwnode_property_count_u32(fwnode, "led-sources"); if (num < 1) return dev_err_probe(dev, -EINVAL, "Not specified or wrong number of led-sources\n");
ret = fwnode_property_read_u32_array(fwnode, "led-sources", sources, num); if (ret) return ret;
for (i = 0; i < num; i++) { if (sources[i] >= MT6370_MAX_LEDS) return -EINVAL; if (priv->leds_active & BIT(sources[i])) return -EINVAL;
priv->leds_active |= BIT(sources[i]);
}
/* If both channels are specified in 'led-sources', joint flash output mode is used */
led->led_no = num == 2 ? MT6370_LED_JOINT : sources[0];
max_ua = num == 2 ? MT6370_ITORCH_DOUBLE_MAX_uA : MT6370_ITORCH_MAX_uA;
val = MT6370_ITORCH_MIN_uA;
ret = fwnode_property_read_u32(fwnode, "led-max-microamp", &val); if (!ret)
val = mt6370_clamp(val, MT6370_ITORCH_MIN_uA, max_ua, MT6370_ITORCH_STEP_uA);
max_ua = num == 2 ? MT6370_ISTRB_DOUBLE_MAX_uA : MT6370_ISTRB_MAX_uA;
val = MT6370_ISTRB_MIN_uA;
ret = fwnode_property_read_u32(fwnode, "flash-max-microamp", &val); if (!ret)
val = mt6370_clamp(val, MT6370_ISTRB_MIN_uA, max_ua, MT6370_ISTRB_STEP_uA);
/* Always configure to the minimum level when off to prevent flash current spikes. */
ret = _mt6370_flash_brightness_set(flash, s->min); if (ret) return ret;
val = MT6370_STRBTO_MIN_US;
ret = fwnode_property_read_u32(fwnode, "flash-max-timeout-us", &val); if (!ret)
val = mt6370_clamp(val, MT6370_STRBTO_MIN_US, MT6370_STRBTO_MAX_US,
MT6370_STRBTO_STEP_US);
staticint mt6370_led_probe(struct platform_device *pdev)
{ struct device *dev = &pdev->dev; struct mt6370_priv *priv;
size_t count; int i = 0, ret;
count = device_get_child_node_count(dev); if (!count || count > MT6370_MAX_LEDS) return dev_err_probe(dev, -EINVAL, "No child node or node count over max led number %zu\n", count);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.