drivers/leds/leds-lp8788.c

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

File Facts

System
Linux kernel
Corpus path
drivers/leds/leds-lp8788.c
Extension
.c
Size
3802 bytes
Lines
172
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 lp8788_led {
	struct lp8788 *lp;
	struct mutex lock;
	struct led_classdev led_dev;
	enum lp8788_isink_number isink_num;
	int on;
};

struct lp8788_led_config {
	enum lp8788_isink_scale scale;
	enum lp8788_isink_number num;
	int iout;
};

static struct lp8788_led_config default_led_config = {
	.scale = LP8788_ISINK_SCALE_100mA,
	.num   = LP8788_ISINK_3,
	.iout  = 0,
};

static int lp8788_led_init_device(struct lp8788_led *led,
				struct lp8788_led_platform_data *pdata)
{
	struct lp8788_led_config *cfg = &default_led_config;
	u8 addr, mask, val;
	int ret;

	if (pdata) {
		cfg->scale = pdata->scale;
		cfg->num = pdata->num;
		cfg->iout = pdata->iout_code;
	}

	led->isink_num = cfg->num;

	/* scale configuration */
	addr = LP8788_ISINK_CTRL;
	mask = 1 << (cfg->num + LP8788_ISINK_SCALE_OFFSET);
	val = cfg->scale << (cfg->num + LP8788_ISINK_SCALE_OFFSET);
	ret = lp8788_update_bits(led->lp, addr, mask, val);
	if (ret)
		return ret;

	/* current configuration */
	addr = lp8788_iout_addr[cfg->num];
	mask = lp8788_iout_mask[cfg->num];
	val = cfg->iout;

	return lp8788_update_bits(led->lp, addr, mask, val);
}

static int lp8788_led_enable(struct lp8788_led *led,
			enum lp8788_isink_number num, int on)
{
	int ret;

	u8 mask = 1 << num;
	u8 val = on << num;

	ret = lp8788_update_bits(led->lp, LP8788_ISINK_CTRL, mask, val);
	if (ret == 0)
		led->on = on;

	return ret;
}

static int lp8788_brightness_set(struct led_classdev *led_cdev,
				enum led_brightness val)
{
	struct lp8788_led *led =
			container_of(led_cdev, struct lp8788_led, led_dev);

	enum lp8788_isink_number num = led->isink_num;
	int enable, ret;

	mutex_lock(&led->lock);

	switch (num) {
	case LP8788_ISINK_1:
	case LP8788_ISINK_2:
	case LP8788_ISINK_3:
		ret = lp8788_write_byte(led->lp, lp8788_pwm_addr[num], val);
		if (ret < 0)
			goto unlock;
		break;
	default:
		mutex_unlock(&led->lock);
		return -EINVAL;
	}

Annotation

Implementation Notes