drivers/gpio/gpio-winbond.c

Source file repositories/reference/linux-study-clean/drivers/gpio/gpio-winbond.c

File Facts

System
Linux kernel
Corpus path
drivers/gpio/gpio-winbond.c
Extension
.c
Size
19336 bytes
Lines
738
Domain
Driver Families
Bucket
drivers/gpio
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 winbond_gpio_params {
	unsigned long base;
	unsigned long gpios;
	unsigned long ppgpios;
	unsigned long odgpios;
	bool pledgpio;
	bool beepgpio;
	bool i2cgpio;
};

static struct winbond_gpio_params params;

static int winbond_sio_enter(unsigned long base)
{
	if (!request_muxed_region(base, 2, WB_GPIO_DRIVER_NAME))
		return -EBUSY;

	/*
	 * datasheet says two successive writes of the "key" value are needed
	 * in order for chip to enter the "Extended Function Mode"
	 */
	outb(WB_SIO_EXT_ENTER_KEY, base);
	outb(WB_SIO_EXT_ENTER_KEY, base);

	return 0;
}

static void winbond_sio_select_logical(unsigned long base, u8 dev)
{
	outb(WB_SIO_REG_LOGICAL, base);
	outb(dev, base + 1);
}

static void winbond_sio_leave(unsigned long base)
{
	outb(WB_SIO_EXT_EXIT_KEY, base);

	release_region(base, 2);
}

static void winbond_sio_reg_write(unsigned long base, u8 reg, u8 data)
{
	outb(reg, base);
	outb(data, base + 1);
}

static u8 winbond_sio_reg_read(unsigned long base, u8 reg)
{
	outb(reg, base);
	return inb(base + 1);
}

static void winbond_sio_reg_bset(unsigned long base, u8 reg, u8 bit)
{
	u8 val;

	val = winbond_sio_reg_read(base, reg);
	val |= BIT(bit);
	winbond_sio_reg_write(base, reg, val);
}

static void winbond_sio_reg_bclear(unsigned long base, u8 reg, u8 bit)
{
	u8 val;

	val = winbond_sio_reg_read(base, reg);
	val &= ~BIT(bit);
	winbond_sio_reg_write(base, reg, val);
}

static bool winbond_sio_reg_btest(unsigned long base, u8 reg, u8 bit)
{
	return winbond_sio_reg_read(base, reg) & BIT(bit);
}

/**
 * struct winbond_gpio_port_conflict - possibly conflicting device information
 * @name:	device name (NULL means no conflicting device defined)
 * @dev:	Super I/O logical device number where the testreg register
 *		is located (or WB_SIO_DEV_NONE - don't select any
 *		logical device)
 * @testreg:	register number where the testbit bit is located
 * @testbit:	index of a bit to check whether an actual conflict exists
 * @warnonly:	if set then a conflict isn't fatal (just warn about it),
 *		otherwise disable the particular GPIO port if a conflict
 *		is detected
 */
struct winbond_gpio_port_conflict {
	const char *name;
	u8 dev;

Annotation

Implementation Notes