drivers/leds/flash/leds-lm3601x.c

Source file repositories/reference/linux-study-clean/drivers/leds/flash/leds-lm3601x.c

File Facts

System
Linux kernel
Corpus path
drivers/leds/flash/leds-lm3601x.c
Extension
.c
Size
12582 bytes
Lines
495
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct lm3601x_led {
	struct led_classdev_flash fled_cdev;
	struct i2c_client *client;
	struct regmap *regmap;
	struct mutex lock;

	unsigned int flash_timeout;
	unsigned int last_flag;

	u32 torch_current_max;
	u32 flash_current_max;
	u32 max_flash_timeout;

	u32 led_mode;
};

static const struct reg_default lm3601x_regmap_defs[] = {
	{ LM3601X_ENABLE_REG, 0x20 },
	{ LM3601X_CFG_REG, 0x15 },
	{ LM3601X_LED_FLASH_REG, 0x00 },
	{ LM3601X_LED_TORCH_REG, 0x00 },
};

static bool lm3601x_volatile_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case LM3601X_FLAGS_REG:
		return true;
	default:
		return false;
	}
}

static const struct regmap_config lm3601x_regmap = {
	.reg_bits = 8,
	.val_bits = 8,

	.max_register = LM3601X_DEV_ID_REG,
	.reg_defaults = lm3601x_regmap_defs,
	.num_reg_defaults = ARRAY_SIZE(lm3601x_regmap_defs),
	.cache_type = REGCACHE_MAPLE,
	.volatile_reg = lm3601x_volatile_reg,
};

static struct lm3601x_led *fled_cdev_to_led(struct led_classdev_flash *fled_cdev)
{
	return container_of(fled_cdev, struct lm3601x_led, fled_cdev);
}

static int lm3601x_read_faults(struct lm3601x_led *led)
{
	int flags_val;
	int ret;

	ret = regmap_read(led->regmap, LM3601X_FLAGS_REG, &flags_val);
	if (ret < 0)
		return -EIO;

	led->last_flag = 0;

	if (flags_val & LM36010_OVP_FAULT)
		led->last_flag |= LED_FAULT_OVER_VOLTAGE;

	if (flags_val & (LM3601X_THERM_SHUTDOWN | LM3601X_THERM_CURR))
		led->last_flag |= LED_FAULT_OVER_TEMPERATURE;

	if (flags_val & LM3601X_SHORT_FAULT)
		led->last_flag |= LED_FAULT_SHORT_CIRCUIT;

	if (flags_val & LM36010_CURR_LIMIT)
		led->last_flag |= LED_FAULT_OVER_CURRENT;

	if (flags_val & LM3601X_UVLO_FAULT)
		led->last_flag |= LED_FAULT_UNDER_VOLTAGE;

	if (flags_val & LM3601X_IVFM_TRIP)
		led->last_flag |= LED_FAULT_INPUT_VOLTAGE;

	if (flags_val & LM3601X_THERM_SHUTDOWN)
		led->last_flag |= LED_FAULT_LED_OVER_TEMPERATURE;

	return led->last_flag;
}

static int lm3601x_brightness_set(struct led_classdev *cdev,
					enum led_brightness brightness)
{
	struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(cdev);
	struct lm3601x_led *led = fled_cdev_to_led(fled_cdev);
	int ret, led_mode_val;

Annotation

Implementation Notes