drivers/leds/rgb/leds-s2m-rgb.c

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

File Facts

System
Linux kernel
Corpus path
drivers/leds/rgb/leds-s2m-rgb.c
Extension
.c
Size
11948 bytes
Lines
427
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 s2m_rgb {
	struct device *dev;
	struct regmap *regmap;
	struct led_classdev_mc mc;
	/*
	 * The mutex object prevents race conditions when evaluation and
	 * application of LED pattern state.
	 */
	struct mutex lock;
	/*
	 * State variables representing the current LED pattern, these only to
	 * be accessed when lock is held.
	 */
	u8 ramp_up;
	u8 ramp_dn;
	u8 stay_hi;
	u8 stay_lo;
};

static struct led_classdev_mc *to_s2m_mc(struct led_classdev *cdev)
{
	return container_of(cdev, struct led_classdev_mc, led_cdev);
}

static struct s2m_rgb *to_s2m_rgb(struct led_classdev_mc *mc)
{
	return container_of(mc, struct s2m_rgb, mc);
}

static const u32 s2mu005_rgb_lut_ramp[] = {
	0,	100,	200,	300,	400,	500,	600,	700,
	800,	1000,	1200,	1400,	1600,	1800,	2000,	2200,
};

static const u32 s2mu005_rgb_lut_stay_hi[] = {
	100,	200,	300,	400,	500,	750,	1000,	1250,
	1500,	1750,	2000,	2250,	2500,	2750,	3000,	3250,
};

static const u32 s2mu005_rgb_lut_stay_lo[] = {
	0,	500,	1000,	1500,	2000,	2500,	3000,	3500,
	4000,	4500,	5000,	6000,	7000,	8000,	10000,	12000,
};

static int s2mu005_rgb_apply_params(struct s2m_rgb *rgb)
{
	struct regmap *regmap = rgb->regmap;
	unsigned int ramp_val = 0;
	unsigned int stay_val = 0;
	int ret;

	ramp_val |= FIELD_PREP(S2MU005_RGB_CH_RAMP_UP, rgb->ramp_up);
	ramp_val |= FIELD_PREP(S2MU005_RGB_CH_RAMP_DN, rgb->ramp_dn);

	stay_val |= FIELD_PREP(S2MU005_RGB_CH_STAY_HI, rgb->stay_hi);
	stay_val |= FIELD_PREP(S2MU005_RGB_CH_STAY_LO, rgb->stay_lo);

	ret = regmap_write(regmap, S2MU005_REG_RGB_EN, S2MU005_RGB_RESET);
	if (ret) {
		dev_err(rgb->dev, "failed to reset RGB LEDs\n");
		return ret;
	}

	for (int i = 0; i < rgb->mc.num_colors; i++) {
		ret = regmap_write(regmap, S2MU005_REG_RGB_CH_CTRL(i),
				   rgb->mc.subled_info[i].brightness);
		if (ret) {
			dev_err(rgb->dev, "failed to set LED brightness\n");
			return ret;
		}

		ret = regmap_write(regmap, S2MU005_REG_RGB_CH_RAMP(i), ramp_val);
		if (ret) {
			dev_err(rgb->dev, "failed to set ramp timings\n");
			return ret;
		}

		ret = regmap_write(regmap, S2MU005_REG_RGB_CH_STAY(i), stay_val);
		if (ret) {
			dev_err(rgb->dev, "failed to set stay timings\n");
			return ret;
		}
	}

	ret = regmap_write(regmap, S2MU005_REG_RGB_EN, S2MU005_RGB_SLOPE_SMOOTH);
	if (ret) {
		dev_err(rgb->dev, "failed to set ramp slope\n");
		return ret;
	}

Annotation

Implementation Notes