drivers/tty/serial/8250/8250_fintek.c

Source file repositories/reference/linux-study-clean/drivers/tty/serial/8250/8250_fintek.c

File Facts

System
Linux kernel
Corpus path
drivers/tty/serial/8250/8250_fintek.c
Extension
.c
Size
11475 bytes
Lines
485
Domain
Driver Families
Bucket
drivers/tty
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 fintek_8250 {
	u16 pid;
	u16 base_port;
	u8 index;
	u8 key;
};

static u8 sio_read_reg(struct fintek_8250 *pdata, u8 reg)
{
	outb(reg, pdata->base_port + ADDR_PORT);
	return inb(pdata->base_port + DATA_PORT);
}

static void sio_write_reg(struct fintek_8250 *pdata, u8 reg, u8 data)
{
	outb(reg, pdata->base_port + ADDR_PORT);
	outb(data, pdata->base_port + DATA_PORT);
}

static void sio_write_mask_reg(struct fintek_8250 *pdata, u8 reg, u8 mask,
			       u8 data)
{
	u8 tmp;

	tmp = (sio_read_reg(pdata, reg) & ~mask) | (mask & data);
	sio_write_reg(pdata, reg, tmp);
}

static int fintek_8250_enter_key(u16 base_port, u8 key)
{
	if (!request_muxed_region(base_port, 2, "8250_fintek"))
		return -EBUSY;

	/* Force to deactivate all SuperIO in this base_port */
	outb(EXIT_KEY, base_port + ADDR_PORT);

	outb(key, base_port + ADDR_PORT);
	outb(key, base_port + ADDR_PORT);
	return 0;
}

static void fintek_8250_exit_key(u16 base_port)
{

	outb(EXIT_KEY, base_port + ADDR_PORT);
	release_region(base_port + ADDR_PORT, 2);
}

static int fintek_8250_check_id(struct fintek_8250 *pdata)
{
	u16 chip;

	if (sio_read_reg(pdata, VENDOR_ID1) != VENDOR_ID1_VAL)
		return -ENODEV;

	if (sio_read_reg(pdata, VENDOR_ID2) != VENDOR_ID2_VAL)
		return -ENODEV;

	chip = sio_read_reg(pdata, CHIP_ID1);
	chip |= sio_read_reg(pdata, CHIP_ID2) << 8;

	switch (chip) {
	case CHIP_ID_F81865:
	case CHIP_ID_F81866:
	case CHIP_ID_F81966:
	case CHIP_ID_F81216AD:
	case CHIP_ID_F81216E:
	case CHIP_ID_F81216H:
	case CHIP_ID_F81214E:
	case CHIP_ID_F81216:
		break;
	default:
		return -ENODEV;
	}

	pdata->pid = chip;
	return 0;
}

static int fintek_8250_get_ldn_range(struct fintek_8250 *pdata, int *min,
				     int *max)
{
	switch (pdata->pid) {
	case CHIP_ID_F81966:
	case CHIP_ID_F81865:
	case CHIP_ID_F81866:
		*min = F81866_LDN_LOW;
		*max = F81866_LDN_HIGH;
		return 0;

Annotation

Implementation Notes