drivers/leds/rgb/leds-ncp5623.c

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

File Facts

System
Linux kernel
Corpus path
drivers/leds/rgb/leds-ncp5623.c
Extension
.c
Size
6746 bytes
Lines
271
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 ncp5623 {
	struct i2c_client *client;
	struct led_classdev_mc mc_dev;
	struct mutex lock;

	int current_brightness;
	unsigned long delay;
};

static int ncp5623_write(struct i2c_client *client, u8 reg, u8 data)
{
	return i2c_smbus_write_byte_data(client, reg | data, 0);
}

static int ncp5623_brightness_set(struct led_classdev *cdev,
				  enum led_brightness brightness)
{
	struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev);
	struct ncp5623 *ncp = container_of(mc_cdev, struct ncp5623, mc_dev);
	int ret;

	guard(mutex)(&ncp->lock);

	if (ncp->delay && time_is_after_jiffies(ncp->delay))
		return -EBUSY;

	ncp->delay = 0;

	for (int i = 0; i < mc_cdev->num_colors; i++) {
		ret = ncp5623_write(ncp->client,
				    NCP5623_PWM_REG(mc_cdev->subled_info[i].channel),
				    mc_cdev->subled_info[i].intensity);
		if (ret)
			return ret;
	}

	ret = ncp5623_write(ncp->client, NCP5623_DIMMING_TIME_REG, 0);
	if (ret)
		return ret;

	ret = ncp5623_write(ncp->client, NCP5623_ILED_REG, brightness);
	if (ret)
		return ret;

	ncp->current_brightness = brightness;

	return 0;
}

static int ncp5623_pattern_set(struct led_classdev *cdev,
			       struct led_pattern *pattern,
			       u32 len, int repeat)
{
	struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev);
	struct ncp5623 *ncp = container_of(mc_cdev, struct ncp5623, mc_dev);
	int brightness_diff;
	u8 reg;
	int ret;

	guard(mutex)(&ncp->lock);

	if (ncp->delay && time_is_after_jiffies(ncp->delay))
		return -EBUSY;

	ncp->delay = 0;

	if (pattern[0].delta_t > NCP5623_MAX_DIM_TIME_MS ||
	   (pattern[0].delta_t % NCP5623_DIM_STEP_MS) != 0)
		return -EINVAL;

	brightness_diff = pattern[0].brightness - ncp->current_brightness;

	if (brightness_diff == 0)
		return 0;

	if (pattern[0].delta_t) {
		if (brightness_diff > 0)
			reg = NCP5623_UPWARD_STEP_REG;
		else
			reg = NCP5623_DOWNWARD_STEP_REG;
	} else {
		reg = NCP5623_ILED_REG;
	}

	ret = ncp5623_write(ncp->client, reg,
			    min(pattern[0].brightness, NCP5623_MAX_BRIGHTNESS));
	if (ret)
		return ret;

	ret = ncp5623_write(ncp->client,

Annotation

Implementation Notes