Skip to content

Commit 5974e8f

Browse files
fenglinw-qcomlag-linaro
authored andcommitted
leds: flash: leds-qcom-flash: Update torch current clamp setting
There is a register to clamp the flash current per LED channel when safety timer is disabled. It needs to be updated according to the maximum torch LED current setting to ensure the torch current won't be clamped unexpectedly. Fixes: 96a2e24 ("leds: flash: Add driver to support flash LED module in QCOM PMICs") Signed-off-by: Fenglin Wu <fenglin.wu@oss.qualcomm.com> Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com> Link: https://lore.kernel.org/r/20250729-fix-torch-clamp-issue-v2-1-9b83816437a3@oss.qualcomm.com Signed-off-by: Lee Jones <lee@kernel.org>
1 parent 6e3779e commit 5974e8f

1 file changed

Lines changed: 36 additions & 26 deletions

File tree

drivers/leds/flash/leds-qcom-flash.c

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// SPDX-License-Identifier: GPL-2.0-only
22
/*
3-
* Copyright (c) 2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
3+
* Copyright (c) 2022, 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
44
*/
55

66
#include <linux/bitfield.h>
@@ -114,36 +114,39 @@ enum {
114114
REG_THERM_THRSH1,
115115
REG_THERM_THRSH2,
116116
REG_THERM_THRSH3,
117+
REG_TORCH_CLAMP,
117118
REG_MAX_COUNT,
118119
};
119120

120121
static const struct reg_field mvflash_3ch_regs[REG_MAX_COUNT] = {
121-
REG_FIELD(0x08, 0, 7), /* status1 */
122-
REG_FIELD(0x09, 0, 7), /* status2 */
123-
REG_FIELD(0x0a, 0, 7), /* status3 */
124-
REG_FIELD_ID(0x40, 0, 7, 3, 1), /* chan_timer */
125-
REG_FIELD_ID(0x43, 0, 6, 3, 1), /* itarget */
126-
REG_FIELD(0x46, 7, 7), /* module_en */
127-
REG_FIELD(0x47, 0, 5), /* iresolution */
128-
REG_FIELD_ID(0x49, 0, 2, 3, 1), /* chan_strobe */
129-
REG_FIELD(0x4c, 0, 2), /* chan_en */
130-
REG_FIELD(0x56, 0, 2), /* therm_thrsh1 */
131-
REG_FIELD(0x57, 0, 2), /* therm_thrsh2 */
132-
REG_FIELD(0x58, 0, 2), /* therm_thrsh3 */
122+
[REG_STATUS1] = REG_FIELD(0x08, 0, 7),
123+
[REG_STATUS2] = REG_FIELD(0x09, 0, 7),
124+
[REG_STATUS3] = REG_FIELD(0x0a, 0, 7),
125+
[REG_CHAN_TIMER] = REG_FIELD_ID(0x40, 0, 7, 3, 1),
126+
[REG_ITARGET] = REG_FIELD_ID(0x43, 0, 6, 3, 1),
127+
[REG_MODULE_EN] = REG_FIELD(0x46, 7, 7),
128+
[REG_IRESOLUTION] = REG_FIELD(0x47, 0, 5),
129+
[REG_CHAN_STROBE] = REG_FIELD_ID(0x49, 0, 2, 3, 1),
130+
[REG_CHAN_EN] = REG_FIELD(0x4c, 0, 2),
131+
[REG_THERM_THRSH1] = REG_FIELD(0x56, 0, 2),
132+
[REG_THERM_THRSH2] = REG_FIELD(0x57, 0, 2),
133+
[REG_THERM_THRSH3] = REG_FIELD(0x58, 0, 2),
134+
[REG_TORCH_CLAMP] = REG_FIELD(0xec, 0, 6),
133135
};
134136

135137
static const struct reg_field mvflash_4ch_regs[REG_MAX_COUNT] = {
136-
REG_FIELD(0x06, 0, 7), /* status1 */
137-
REG_FIELD(0x07, 0, 6), /* status2 */
138-
REG_FIELD(0x09, 0, 7), /* status3 */
139-
REG_FIELD_ID(0x3e, 0, 7, 4, 1), /* chan_timer */
140-
REG_FIELD_ID(0x42, 0, 6, 4, 1), /* itarget */
141-
REG_FIELD(0x46, 7, 7), /* module_en */
142-
REG_FIELD(0x49, 0, 3), /* iresolution */
143-
REG_FIELD_ID(0x4a, 0, 6, 4, 1), /* chan_strobe */
144-
REG_FIELD(0x4e, 0, 3), /* chan_en */
145-
REG_FIELD(0x7a, 0, 2), /* therm_thrsh1 */
146-
REG_FIELD(0x78, 0, 2), /* therm_thrsh2 */
138+
[REG_STATUS1] = REG_FIELD(0x06, 0, 7),
139+
[REG_STATUS2] = REG_FIELD(0x07, 0, 6),
140+
[REG_STATUS3] = REG_FIELD(0x09, 0, 7),
141+
[REG_CHAN_TIMER] = REG_FIELD_ID(0x3e, 0, 7, 4, 1),
142+
[REG_ITARGET] = REG_FIELD_ID(0x42, 0, 6, 4, 1),
143+
[REG_MODULE_EN] = REG_FIELD(0x46, 7, 7),
144+
[REG_IRESOLUTION] = REG_FIELD(0x49, 0, 3),
145+
[REG_CHAN_STROBE] = REG_FIELD_ID(0x4a, 0, 6, 4, 1),
146+
[REG_CHAN_EN] = REG_FIELD(0x4e, 0, 3),
147+
[REG_THERM_THRSH1] = REG_FIELD(0x7a, 0, 2),
148+
[REG_THERM_THRSH2] = REG_FIELD(0x78, 0, 2),
149+
[REG_TORCH_CLAMP] = REG_FIELD(0xed, 0, 6),
147150
};
148151

149152
struct qcom_flash_data {
@@ -156,6 +159,7 @@ struct qcom_flash_data {
156159
u8 max_channels;
157160
u8 chan_en_bits;
158161
u8 revision;
162+
u8 torch_clamp;
159163
};
160164

161165
struct qcom_flash_led {
@@ -702,6 +706,7 @@ static int qcom_flash_register_led_device(struct device *dev,
702706
u32 current_ua, timeout_us;
703707
u32 channels[4];
704708
int i, rc, count;
709+
u8 torch_clamp;
705710

706711
count = fwnode_property_count_u32(node, "led-sources");
707712
if (count <= 0) {
@@ -751,6 +756,12 @@ static int qcom_flash_register_led_device(struct device *dev,
751756
current_ua = min_t(u32, current_ua, TORCH_CURRENT_MAX_UA * led->chan_count);
752757
led->max_torch_current_ma = current_ua / UA_PER_MA;
753758

759+
torch_clamp = (current_ua / led->chan_count) / TORCH_IRES_UA;
760+
if (torch_clamp != 0)
761+
torch_clamp--;
762+
763+
flash_data->torch_clamp = max_t(u8, flash_data->torch_clamp, torch_clamp);
764+
754765
if (fwnode_property_present(node, "flash-max-microamp")) {
755766
flash->led_cdev.flags |= LED_DEV_CAP_FLASH;
756767

@@ -917,8 +928,7 @@ static int qcom_flash_led_probe(struct platform_device *pdev)
917928
flash_data->leds_count++;
918929
}
919930

920-
return 0;
921-
931+
return regmap_field_write(flash_data->r_fields[REG_TORCH_CLAMP], flash_data->torch_clamp);
922932
release:
923933
while (flash_data->v4l2_flash[flash_data->leds_count] && flash_data->leds_count)
924934
v4l2_flash_release(flash_data->v4l2_flash[flash_data->leds_count--]);

0 commit comments

Comments
 (0)