drivers/media/i2c/lm3646.c
Source file repositories/reference/linux-study-clean/drivers/media/i2c/lm3646.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/media/i2c/lm3646.c- Extension
.c- Size
- 10731 bytes
- Lines
- 410
- Domain
- Driver Families
- Bucket
- drivers/media
- 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.
- 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/delay.hlinux/i2c.hlinux/module.hlinux/slab.hlinux/regmap.hlinux/videodev2.hmedia/i2c/lm3646.hmedia/v4l2-ctrls.hmedia/v4l2-device.h
Detected Declarations
struct lm3646_flashenum led_modefunction lm3646_mode_ctrlfunction lm3646_get_ctrlfunction lm3646_set_ctrlfunction lm3646_init_controlsfunction lm3646_subdev_initfunction lm3646_init_devicefunction lm3646_probefunction lm3646_remove
Annotated Snippet
struct lm3646_flash {
struct device *dev;
struct lm3646_platform_data *pdata;
struct regmap *regmap;
struct v4l2_ctrl_handler ctrls_led;
struct v4l2_subdev subdev_led;
u8 mode_reg;
};
#define to_lm3646_flash(_ctrl) \
container_of(_ctrl->handler, struct lm3646_flash, ctrls_led)
/* enable mode control */
static int lm3646_mode_ctrl(struct lm3646_flash *flash,
enum v4l2_flash_led_mode led_mode)
{
switch (led_mode) {
case V4L2_FLASH_LED_MODE_NONE:
return regmap_write(flash->regmap,
REG_ENABLE, flash->mode_reg | MODE_SHDN);
case V4L2_FLASH_LED_MODE_TORCH:
return regmap_write(flash->regmap,
REG_ENABLE, flash->mode_reg | MODE_TORCH);
case V4L2_FLASH_LED_MODE_FLASH:
return regmap_write(flash->regmap,
REG_ENABLE, flash->mode_reg | MODE_FLASH);
}
return -EINVAL;
}
/* V4L2 controls */
static int lm3646_get_ctrl(struct v4l2_ctrl *ctrl)
{
struct lm3646_flash *flash = to_lm3646_flash(ctrl);
unsigned int reg_val;
int rval;
if (ctrl->id != V4L2_CID_FLASH_FAULT)
return -EINVAL;
rval = regmap_read(flash->regmap, REG_FLAG, ®_val);
if (rval < 0)
return rval;
ctrl->val = 0;
if (reg_val & FAULT_TIMEOUT)
ctrl->val |= V4L2_FLASH_FAULT_TIMEOUT;
if (reg_val & FAULT_SHORT_CIRCUIT)
ctrl->val |= V4L2_FLASH_FAULT_SHORT_CIRCUIT;
if (reg_val & FAULT_UVLO)
ctrl->val |= V4L2_FLASH_FAULT_UNDER_VOLTAGE;
if (reg_val & FAULT_IVFM)
ctrl->val |= V4L2_FLASH_FAULT_INPUT_VOLTAGE;
if (reg_val & FAULT_OCP)
ctrl->val |= V4L2_FLASH_FAULT_OVER_CURRENT;
if (reg_val & FAULT_OVERTEMP)
ctrl->val |= V4L2_FLASH_FAULT_OVER_TEMPERATURE;
if (reg_val & FAULT_NTC_TRIP)
ctrl->val |= V4L2_FLASH_FAULT_LED_OVER_TEMPERATURE;
if (reg_val & FAULT_OVP)
ctrl->val |= V4L2_FLASH_FAULT_OVER_VOLTAGE;
return 0;
}
static int lm3646_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct lm3646_flash *flash = to_lm3646_flash(ctrl);
unsigned int reg_val;
int rval;
switch (ctrl->id) {
case V4L2_CID_FLASH_LED_MODE:
if (ctrl->val != V4L2_FLASH_LED_MODE_FLASH)
return lm3646_mode_ctrl(flash, ctrl->val);
/* switch to SHDN mode before flash strobe on */
return lm3646_mode_ctrl(flash, V4L2_FLASH_LED_MODE_NONE);
case V4L2_CID_FLASH_STROBE_SOURCE:
return regmap_update_bits(flash->regmap,
REG_STROBE_SRC, MASK_STROBE_SRC,
(ctrl->val) << 7);
case V4L2_CID_FLASH_STROBE:
/* read and check current mode of chip to start flash */
rval = regmap_read(flash->regmap, REG_ENABLE, ®_val);
Annotation
- Immediate include surface: `linux/delay.h`, `linux/i2c.h`, `linux/module.h`, `linux/slab.h`, `linux/regmap.h`, `linux/videodev2.h`, `media/i2c/lm3646.h`, `media/v4l2-ctrls.h`.
- Detected declarations: `struct lm3646_flash`, `enum led_mode`, `function lm3646_mode_ctrl`, `function lm3646_get_ctrl`, `function lm3646_set_ctrl`, `function lm3646_init_controls`, `function lm3646_subdev_init`, `function lm3646_init_device`, `function lm3646_probe`, `function lm3646_remove`.
- Atlas domain: Driver Families / drivers/media.
- Implementation status: source implementation candidate.
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.