drivers/leds/flash/leds-qcom-flash.c
Source file repositories/reference/linux-study-clean/drivers/leds/flash/leds-qcom-flash.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/leds/flash/leds-qcom-flash.c- Extension
.c- Size
- 28158 bytes
- Lines
- 990
- Domain
- Driver Families
- Bucket
- drivers/leds
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bitfield.hlinux/bits.hlinux/leds.hlinux/led-class-flash.hlinux/module.hlinux/platform_device.hlinux/property.hlinux/regmap.hmedia/v4l2-flash-led-class.h
Detected Declarations
struct qcom_flash_datastruct qcom_flash_ledenum hw_typeenum led_modeenum led_strobefunction set_flash_module_enfunction update_allowed_flash_currentfunction set_flash_currentfunction set_flash_timeoutfunction set_flash_strobefunction qcom_flash_brightness_setfunction qcom_flash_timeout_setfunction qcom_flash_strobe_setfunction qcom_flash_strobe_getfunction qcom_flash_fault_getfunction qcom_flash_led_brightness_setfunction qcom_flash_external_strobe_setfunction qcom_flash_intensity_to_led_brightnessfunction qcom_flash_brightness_to_led_intensityfunction qcom_flash_v4l2_initfunction qcom_flash_v4l2_initfunction qcom_flash_register_led_devicefunction qcom_flash_led_probefunction device_for_each_child_node_scopedfunction qcom_flash_led_remove
Annotated Snippet
struct qcom_flash_data {
struct v4l2_flash **v4l2_flash;
struct regmap_field *r_fields[REG_MAX_COUNT];
struct mutex lock;
enum hw_type hw_type;
u32 total_ma;
u8 leds_count;
u8 max_channels;
u8 chan_en_bits;
u8 revision;
u8 torch_clamp;
};
struct qcom_flash_led {
struct qcom_flash_data *flash_data;
struct led_classdev_flash flash;
u32 max_flash_current_ma;
u32 max_torch_current_ma;
u32 max_timeout_ms;
u32 flash_current_ma;
u32 flash_timeout_ms;
u32 current_in_use_ma;
u8 *chan_id;
u8 chan_count;
bool enabled;
};
static int set_flash_module_en(struct qcom_flash_led *led, bool en)
{
struct qcom_flash_data *flash_data = led->flash_data;
u8 led_mask = 0, enable;
int i, rc;
for (i = 0; i < led->chan_count; i++)
led_mask |= BIT(led->chan_id[i]);
mutex_lock(&flash_data->lock);
if (en)
flash_data->chan_en_bits |= led_mask;
else
flash_data->chan_en_bits &= ~led_mask;
enable = !!flash_data->chan_en_bits;
rc = regmap_field_write(flash_data->r_fields[REG_MODULE_EN], enable);
if (rc)
dev_err(led->flash.led_cdev.dev, "write module_en failed, rc=%d\n", rc);
mutex_unlock(&flash_data->lock);
return rc;
}
static int update_allowed_flash_current(struct qcom_flash_led *led, u32 *current_ma, bool strobe)
{
struct qcom_flash_data *flash_data = led->flash_data;
u32 therm_ma, avail_ma, thrsh[3], min_thrsh, sts;
int rc = 0;
mutex_lock(&flash_data->lock);
/*
* Put previously allocated current into allowed budget in either of these two cases:
* 1) LED is disabled;
* 2) LED is enabled repeatedly
*/
if (!strobe || led->current_in_use_ma != 0) {
if (flash_data->total_ma >= led->current_in_use_ma)
flash_data->total_ma -= led->current_in_use_ma;
else
flash_data->total_ma = 0;
led->current_in_use_ma = 0;
if (!strobe)
goto unlock;
}
/*
* Cache the default thermal threshold settings, and set them to the lowest levels before
* reading over-temp real time status. If over-temp has been triggered at the lowest
* threshold, it's very likely that it would be triggered at a higher (default) threshold
* when more flash current is requested. Prevent device from triggering over-temp condition
* by limiting the flash current for the new request.
*/
rc = regmap_field_read(flash_data->r_fields[REG_THERM_THRSH1], &thrsh[0]);
if (rc < 0)
goto unlock;
rc = regmap_field_read(flash_data->r_fields[REG_THERM_THRSH2], &thrsh[1]);
if (rc < 0)
goto unlock;
if (flash_data->hw_type == QCOM_MVFLASH_3CH) {
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/bits.h`, `linux/leds.h`, `linux/led-class-flash.h`, `linux/module.h`, `linux/platform_device.h`, `linux/property.h`, `linux/regmap.h`.
- Detected declarations: `struct qcom_flash_data`, `struct qcom_flash_led`, `enum hw_type`, `enum led_mode`, `enum led_strobe`, `function set_flash_module_en`, `function update_allowed_flash_current`, `function set_flash_current`, `function set_flash_timeout`, `function set_flash_strobe`.
- Atlas domain: Driver Families / drivers/leds.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.