drivers/leds/leds-pca955x.c

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

File Facts

System
Linux kernel
Corpus path
drivers/leds/leds-pca955x.c
Extension
.c
Size
20490 bytes
Lines
800
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 pca955x_chipdef {
	u8			bits;
	u8			slv_addr;	/* 7-bit slave address mask */
	int			slv_addr_shift;	/* Number of bits to ignore */
	int			blink_div;	/* PSC divider */
};

static const struct pca955x_chipdef pca955x_chipdefs[] = {
	[pca9550] = {
		.bits		= 2,
		.slv_addr	= /* 110000x */ 0x60,
		.slv_addr_shift	= 1,
		.blink_div	= 44,
	},
	[pca9551] = {
		.bits		= 8,
		.slv_addr	= /* 1100xxx */ 0x60,
		.slv_addr_shift	= 3,
		.blink_div	= 38,
	},
	[pca9552] = {
		.bits		= 16,
		.slv_addr	= /* 1100xxx */ 0x60,
		.slv_addr_shift	= 3,
		.blink_div	= 44,
	},
	[ibm_pca9552] = {
		.bits		= 16,
		.slv_addr	= /* 0110xxx */ 0x30,
		.slv_addr_shift	= 3,
		.blink_div	= 44,
	},
	[pca9553] = {
		.bits		= 4,
		.slv_addr	= /* 110001x */ 0x62,
		.slv_addr_shift	= 1,
		.blink_div	= 44,
	},
};

struct pca955x {
	struct mutex lock;
	struct pca955x_led *leds;
	const struct pca955x_chipdef	*chipdef;
	struct i2c_client	*client;
	unsigned long active_blink;
	unsigned long active_pins;
	unsigned long blink_period;
#ifdef CONFIG_LEDS_PCA955X_GPIO
	struct gpio_chip gpio;
#endif
};

struct pca955x_led {
	struct pca955x	*pca955x;
	struct led_classdev	led_cdev;
	int			led_num;	/* 0 .. 15 potentially */
	u32			type;
	enum led_default_state	default_state;
	struct fwnode_handle	*fwnode;
};

#define led_to_pca955x(l)	container_of(l, struct pca955x_led, led_cdev)

struct pca955x_platform_data {
	struct pca955x_led	*leds;
	int			num_leds;
};

/* 8 bits per input register */
static inline u8 pca955x_num_input_regs(u8 bits)
{
	return (bits + 7) / 8;
}

/* 4 bits per LED selector register */
static inline u8 pca955x_num_led_regs(u8 bits)
{
	return (bits + 3)  / 4;
}

/*
 * Return an LED selector register value based on an existing one, with
 * the appropriate 2-bit state value set for the given LED number (0-3).
 */
static inline u8 pca955x_ledsel(u8 oldval, int led_num, int state)
{
	return (oldval & (~(0x3 << (led_num << 1)))) |
		((state & 0x3) << (led_num << 1));
}

Annotation

Implementation Notes