drivers/leds/leds-max77705.c

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

File Facts

System
Linux kernel
Corpus path
drivers/leds/leds-max77705.c
Extension
.c
Size
7557 bytes
Lines
276
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 max77705_led {
	struct led_classdev cdev;
	struct led_classdev_mc mcdev;
	struct regmap *regmap;

	struct mc_subled *subled_info;
};

static const struct regmap_config max77705_leds_regmap_config = {
	.reg_base = MAX77705_RGBLED_REG_BASE,
	.reg_bits = 8,
	.val_bits = 8,
	.max_register = MAX77705_LED_REG_END,
};

static int max77705_rgb_blink(struct led_classdev *cdev,
				unsigned long *delay_on,
				unsigned long *delay_off)
{
	struct max77705_led *led = container_of(cdev, struct max77705_led, cdev);
	int value, on_value, off_value;

	if (*delay_on < MAX77705_RGB_DELAY_100_STEP)
		on_value = 0;
	else if (*delay_on < MAX77705_RGB_DELAY_100_STEP_LIM)
		on_value = *delay_on / MAX77705_RGB_DELAY_100_STEP - 1;
	else if (*delay_on < MAX77705_RGB_DELAY_250_STEP_LIM)
		on_value = (*delay_on - MAX77705_RGB_DELAY_100_STEP_LIM) /
				MAX77705_RGB_DELAY_250_STEP +
				MAX77705_RGB_DELAY_100_STEP_COUNT;
	else
		on_value = 15;

	on_value <<= 4;

	if (*delay_off < 1)
		off_value = 0;
	else if (*delay_off < MAX77705_RGB_DELAY_500_STEP)
		off_value = 1;
	else if (*delay_off < MAX77705_RGB_DELAY_500_STEP_LIM)
		off_value = *delay_off / MAX77705_RGB_DELAY_500_STEP;
	else if (*delay_off < MAX77705_RGB_DELAY_1000_STEP_LIM)
		off_value = (*delay_off - MAX77705_RGB_DELAY_1000_STEP_LIM) /
				MAX77705_RGB_DELAY_1000_STEP +
				MAX77705_RGB_DELAY_500_STEP_COUNT;
	else if (*delay_off < MAX77705_RGB_DELAY_2000_STEP_LIM)
		off_value = (*delay_off - MAX77705_RGB_DELAY_2000_STEP_LIM) /
				MAX77705_RGB_DELAY_2000_STEP +
				MAX77705_RGB_DELAY_1000_STEP_COUNT;
	else
		off_value = 15;

	value = on_value | off_value;
	return regmap_write(led->regmap, MAX77705_RGBLED_REG_LEDBLNK, value);
}

static int max77705_led_brightness_set(struct regmap *regmap, struct mc_subled *subled,
				int num_colors)
{
	int ret;

	for (int i = 0; i < num_colors; i++) {
		unsigned int channel, brightness;

		channel = subled[i].channel;
		brightness = subled[i].brightness;

		if (brightness == LED_OFF) {
			/* Flash OFF */
			ret = regmap_update_bits(regmap,
					MAX77705_RGBLED_REG_LEDEN,
					MAX77705_LED_EN_MASK << MAX77705_LED_EN_SHIFT(channel), 0);
		} else {
			/* Set current */
			ret = regmap_write(regmap, MAX77705_LED_REG_BRIGHTNESS(channel),
					brightness);
			if (ret < 0)
				return ret;

			ret = regmap_update_bits(regmap,
					MAX77705_RGBLED_REG_LEDEN,
					LED_ON << MAX77705_LED_EN_SHIFT(channel),
					MAX77705_LED_EN_MASK << MAX77705_LED_EN_SHIFT(channel));
		}
	}

	return ret;
}

static int max77705_led_brightness_set_single(struct led_classdev *cdev,

Annotation

Implementation Notes