drivers/leds/leds-lp8860.c

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

File Facts

System
Linux kernel
Corpus path
drivers/leds/leds-lp8860.c
Extension
.c
Size
9563 bytes
Lines
360
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 lp8860_led {
	struct mutex lock;
	struct i2c_client *client;
	struct led_classdev led_dev;
	struct regmap *regmap;
};

static bool program_eeprom;
module_param(program_eeprom, bool, 0644);
MODULE_PARM_DESC(program_eeprom, "Program the configuration EEPROM on device startup");

/*
 * EEPROM bits are intended to be set/programmed before normal operation only
 * once during silicon production, but can be reprogrammed for evaluation purposes
 * up to 1000 cycles. To program this EEPROM using this driver, update the below
 * table and set the module param "program_eeprom" to 1
 */
static const struct reg_sequence lp8860_eeprom_disp_regs[] = {
	{ LP8860_EEPROM_REG_0, 0xed },
	{ LP8860_EEPROM_REG_1, 0xdf },
	{ LP8860_EEPROM_REG_2, 0xdc },
	{ LP8860_EEPROM_REG_3, 0xf0 },
	{ LP8860_EEPROM_REG_4, 0xdf },
	{ LP8860_EEPROM_REG_5, 0xe5 },
	{ LP8860_EEPROM_REG_6, 0xf2 },
	{ LP8860_EEPROM_REG_7, 0x77 },
	{ LP8860_EEPROM_REG_8, 0x77 },
	{ LP8860_EEPROM_REG_9, 0x71 },
	{ LP8860_EEPROM_REG_10, 0x3f },
	{ LP8860_EEPROM_REG_11, 0xb7 },
	{ LP8860_EEPROM_REG_12, 0x17 },
	{ LP8860_EEPROM_REG_13, 0xef },
	{ LP8860_EEPROM_REG_14, 0xb0 },
	{ LP8860_EEPROM_REG_15, 0x87 },
	{ LP8860_EEPROM_REG_16, 0xce },
	{ LP8860_EEPROM_REG_17, 0x72 },
	{ LP8860_EEPROM_REG_18, 0xe5 },
	{ LP8860_EEPROM_REG_19, 0xdf },
	{ LP8860_EEPROM_REG_20, 0x35 },
	{ LP8860_EEPROM_REG_21, 0x06 },
	{ LP8860_EEPROM_REG_22, 0xdc },
	{ LP8860_EEPROM_REG_23, 0x88 },
	{ LP8860_EEPROM_REG_24, 0x3E },
};

static int lp8860_fault_check(struct lp8860_led *led)
{
	int ret, fault;
	unsigned int read_buf;

	ret = regmap_read(led->regmap, LP8860_LED_FAULT, &read_buf);
	if (ret)
		goto out;

	fault = read_buf;

	ret = regmap_read(led->regmap, LP8860_FAULT, &read_buf);
	if (ret)
		goto out;

	fault |= read_buf;

	/* Attempt to clear any faults */
	if (fault)
		ret = regmap_write(led->regmap, LP8860_FAULT_CLEAR,
			LP8860_CLEAR_FAULTS);
out:
	return ret;
}

static int lp8860_brightness_set(struct led_classdev *led_cdev,
				enum led_brightness brt_val)
{
	struct lp8860_led *led =
			container_of(led_cdev, struct lp8860_led, led_dev);
	int disp_brightness = brt_val * 255;
	int ret;

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

	ret = lp8860_fault_check(led);
	if (ret) {
		dev_err(&led->client->dev, "Cannot read/clear faults\n");
		return ret;
	}

	ret = regmap_write(led->regmap, LP8860_DISP_CL1_BRT_MSB,
			(disp_brightness & 0xff00) >> 8);
	if (ret) {
		dev_err(&led->client->dev, "Cannot write CL1 MSB\n");

Annotation

Implementation Notes