drivers/usb/c67x00/c67x00-ll-hpi.c

Source file repositories/reference/linux-study-clean/drivers/usb/c67x00/c67x00-ll-hpi.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/c67x00/c67x00-ll-hpi.c
Extension
.c
Size
11801 bytes
Lines
478
Domain
Driver Families
Bucket
drivers/usb
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 c67x00_lcp_int_data {
	u16 regs[COMM_REGS];
};

/* -------------------------------------------------------------------------- */
/* Interface definitions */

#define COMM_ACK			0x0FED
#define COMM_NAK			0xDEAD

#define COMM_RESET			0xFA50
#define COMM_EXEC_INT			0xCE01
#define COMM_INT_NUM			0x01C2

/* Registers 0 to COMM_REGS-1 */
#define COMM_R(x)			(0x01C4 + 2 * (x))

#define HUSB_SIE_pCurrentTDPtr(x)	((x) ? 0x01B2 : 0x01B0)
#define HUSB_SIE_pTDListDone_Sem(x)	((x) ? 0x01B8 : 0x01B6)
#define HUSB_pEOT			0x01B4

/* Software interrupts */
/* 114, 115: */
#define HUSB_SIE_INIT_INT(x)		((x) ? 0x0073 : 0x0072)
#define HUSB_RESET_INT			0x0074

#define SUSB_INIT_INT			0x0071
#define SUSB_INIT_INT_LOC		(SUSB_INIT_INT * 2)

/* -----------------------------------------------------------------------
 * HPI implementation
 *
 * The c67x00 chip also support control via SPI or HSS serial
 * interfaces. However, this driver assumes that register access can
 * be performed from IRQ context. While this is a safe assumption with
 * the HPI interface, it is not true for the serial interfaces.
 */

/* HPI registers */
#define HPI_DATA	0
#define HPI_MAILBOX	1
#define HPI_ADDR	2
#define HPI_STATUS	3

/*
 * According to CY7C67300 specification (tables 140 and 141) HPI read and
 * write cycle duration Tcyc must be at least 6T long, where T is 1/48MHz,
 * which is 125ns.
 */
#define HPI_T_CYC_NS	125

static inline u16 hpi_read_reg(struct c67x00_device *dev, int reg)
{
	ndelay(HPI_T_CYC_NS);
	return __raw_readw(dev->hpi.base + reg * dev->hpi.regstep);
}

static inline void hpi_write_reg(struct c67x00_device *dev, int reg, u16 value)
{
	ndelay(HPI_T_CYC_NS);
	__raw_writew(value, dev->hpi.base + reg * dev->hpi.regstep);
}

static inline u16 hpi_read_word_nolock(struct c67x00_device *dev, u16 reg)
{
	hpi_write_reg(dev, HPI_ADDR, reg);
	return hpi_read_reg(dev, HPI_DATA);
}

static u16 hpi_read_word(struct c67x00_device *dev, u16 reg)
{
	u16 value;
	unsigned long flags;

	spin_lock_irqsave(&dev->hpi.lock, flags);
	value = hpi_read_word_nolock(dev, reg);
	spin_unlock_irqrestore(&dev->hpi.lock, flags);

	return value;
}

static void hpi_write_word_nolock(struct c67x00_device *dev, u16 reg, u16 value)
{
	hpi_write_reg(dev, HPI_ADDR, reg);
	hpi_write_reg(dev, HPI_DATA, value);
}

static void hpi_write_word(struct c67x00_device *dev, u16 reg, u16 value)
{
	unsigned long flags;

Annotation

Implementation Notes