⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ohci-sl811.h

📁 优龙2410linux2.6.8内核源代码
💻 H
字号:
/* * SL811HS OHCI HCD (Host Controller Driver) for USB. * * linux/drivers/usb/host/ohci-sl811.h * * Copyright (C) 2004 by Lothar Wassmann <LW at KARO-electronics.de> * * This file is subject to the terms and conditions of the GNU General Public * License.  See the file "COPYING" in the main directory of this archive * for more details. * * * HW access macros and HW specific definitions * *///#include <asm/arch/karo.h>//#define USE_DMA //Can't use DMA because of SL811 register address alignment :(#define FLIP_BUFFERS	1#define USB_RESET_WIDTH	50#define DATA0_WR	0x07	// (Arm+Enable+tranmist to Host+DATA0)#define DATA1_WR	0x47	// (Arm+Enable+tranmist to Host on DATA1)#define ZDATA0_WR	0x05	// (Arm+Transaction Ignored+tranmist to Host+DATA0)#define ZDATA1_WR	0x45	// (Arm+Transaction Ignored+tranmist to Host+DATA1)#define DATA0_RD	0x03	// (Arm+Enable+received from Host+DATA0)#define DATA1_RD	0x43	// (Arm+Enable+received from Host+DATA1)#define PID_SETUP	0x2d	// USB Specification 1.1 Standard Definition#define PID_SOF		0xA5#define PID_IN		0x69#define PID_OUT		0xe1#define SL11H_HOSTCTLREG	0x00#define SL11H_BUFADDRREG	0x01#define SL11H_BUFLNTHREG	0x02#define SL11H_PKTSTATREG	0x03	/* read */#define SL11H_PIDEPREG		0x03	/* write */#define SL11H_XFERCNTREG	0x04	/* read */#define SL11H_DEVADDRREG	0x04	/* write */#define SL11H_CTLREG1		0x05#define SL11H_INTENBLREG	0x06#define SL11H_HOSTCTLREG_B	0x08#define SL11H_BUFADDRREG_B	0x09#define SL11H_BUFLNTHREG_B	0x0A#define SL11H_PKTSTATREG_B	0x0B	/* read */#define SL11H_PIDEPREG_B	0x0B	/* write */#define SL11H_XFERCNTREG_B	0x0C	/* read */#define SL11H_DEVADDRREG_B	0x0C	/* write */#define SL11H_INTSTATREG	0x0D	/* write clears bitwise */#define SL11H_HWREVREG		0x0E	/* read */#define SL11H_SOFLOWREG		0x0E	/* write */#define SL11H_SOFTMRREG		0x0F	/* read */#define SL11H_CTLREG2		0x0F	/* write */#define SL11H_DATA_START	0x10/* Host control register bits (addr 0) */#define SL11H_HCTLMASK_ARM	0x01#define SL11H_HCTLMASK_ENBLEP	0x02#define SL11H_HCTLMASK_WRITE	0x04#define SL11H_HCTLMASK_ISOCH	0x10#define SL11H_HCTLMASK_AFTERSOF	0x20#define SL11H_HCTLMASK_SEQ	0x40#define SL11H_HCTLMASK_PREAMBLE	0x80/* Packet status register bits (addr 3) */#define SL11H_STATMASK_ACK	0x01#define SL11H_STATMASK_ERROR	0x02#define SL11H_STATMASK_TMOUT	0x04#define SL11H_STATMASK_SEQ	0x08#define SL11H_STATMASK_SETUP	0x10#define SL11H_STATMASK_OVF	0x20#define SL11H_STATMASK_NAK	0x40#define SL11H_STATMASK_STALL	0x80#define SL811_PKT_ERR_MASK (SL11H_STATMASK_ERROR |	\			    SL11H_STATMASK_TMOUT |	\			    SL11H_STATMASK_OVF |	\			    SL11H_STATMASK_NAK |	\			    SL11H_STATMASK_STALL |	\			    SL11H_STATMASK_SEQ)/* Control register 1 bits (addr 5) */#define SL11H_CTL1MASK_SOFENA	(1 << 0)#define SL11H_CTL1MASK_NOTXEOF2	(1 << 2) /* ??? */#define SL11H_CTL1MASK_DSTATE	0x18#define SL11H_CTL1MASK_NSPD	0x20#define SL11H_CTL1MASK_SUSPEND	0x40#define SL11H_CTL1MASK_CLK12	0x80#define SL11H_CTL1VAL_NORMAL	0x00#define SL11H_CTL1VAL_RESET	0x08#define SL11H_CTL1VAL_FORCE_J	0x10#define SL11H_CTL1VAL_FORCE_K	0x18/* Interrupt enable (addr 6) and interrupt status register bits (addr 0xD) */#define SL11H_INTMASK_XFERDONE	0x01#define SL11H_INTMASK_XFERDONE_B 0x02#define SL11H_INTMASK_SOFINTR	0x10#define SL11H_INTMASK_INSRMV	0x20#define SL11H_INTMASK_RESUME	0x40#define SL11H_INTMASK_DSTATE	0x80	/* only in status reg */#define SL811_INT_MASK		(SL11H_INTMASK_SOFINTR | SL11H_INTMASK_INSRMV)/* HW rev and SOF lo register bits (addr 0xE) */#define SL11H_HWRMASK_HWREV	0xF0/* SOF counter and control reg 2 (addr 0xF) */#define SL11H_CTL2MASK_SOFHI	0x3F#define SL11H_CTL2MASK_DSWAP	0x40#define SL11H_CTL2MASK_HOSTMODE	0x80#define SL811_MAP_SIZE		256#define SL811_BUF_SIZE		(SL811_MAP_SIZE - SL11H_DATA_START)#define ohci_to_hcd(ohci) (&(ohci)->hcd)typedef enum {	DEV_IDLE	= 0x00,	DEV_LOW_SPEED	= 0x01,	DEV_FULL_SPEED	= 0x02,	DEV_ACTIVE	= 0x04,	DEV_CHECK	= 0x08,	DEV_SOF		= 0x10,	DEV_SLEEP	= 0x20,	DEV_OHCI_IRQ	= 0x40,	DEV_CONN_CHK	= 0x80,} dev_state_t;#define DEV_CONNECTED	(DEV_FULL_SPEED | DEV_LOW_SPEED)#define DEV_TRIGGERED	(DEV_CONN_CHK | DEV_OHCI_IRQ)struct xfer_buf {	void		*buf_addr;	int		buf_len;	struct td	*td;	union {		u8	send_data[3];		struct {			u8	len;			u8	pid_ep;			u8	dev_addr;		} __attribute__((packed));	} __attribute__((packed));	u8	hc;	union {		u8	rcv_data[2];		struct {			u8	pkt_stat;			u8	count;		} __attribute__((packed));	} __attribute__((packed));};struct hc_sl811_dev {	struct device	dev;	void		*addr_reg;	void		*data_reg;	int		irq;	struct timer_list int_timer;	unsigned int	last_sof;	struct tasklet_struct usb_reset_bh;	struct xfer_buf	xfer_buf[FLIP_BUFFERS];	unsigned int	flip;	void		*buf_addr;	int		buf_len;	unsigned int	num_bufs;	unsigned int	buf_map;	struct td	*current_td;	int		dev_state;	u32		pm_state;	u8 		cbc;	u8 		intrdelay;	u8 		hw_rev;};struct hc_sl811_driver {	struct device_driver	drv;	unsigned int		devid;	int (*probe)(struct hc_sl811_dev *dev);	int (*remove)(struct hc_sl811_dev *dev);	int (*suspend)(struct hc_sl811_dev *dev, u32 state);	int (*resume)(struct hc_sl811_dev *dev);};#define SL811_DRV(_d)		container_of((_d), struct hc_sl811_driver, drv)/* * SL811 HW Interface */#define hc_sl811_addr_reg (dev->addr_reg)#define hc_sl811_data_reg (dev->data_reg)static inline void HC_SL811_WRITE_ADDR(struct hc_sl811_dev *dev, int reg){	writeb(reg, hc_sl811_addr_reg);}static inline void HC_SL811_WRITE_DATA(struct hc_sl811_dev *dev, int val){	writeb(val, hc_sl811_data_reg);}static inline u8 HC_SL811_READ_DATA(struct hc_sl811_dev *dev){	u8 val;	val = readb(hc_sl811_data_reg);	return val;}static inline u8 __hc_sl811_read_reg(struct hc_sl811_dev *dev, int reg){	u8 val;	HC_SL811_WRITE_ADDR(dev, reg);	val = HC_SL811_READ_DATA(dev);	return val;}static inline u8 hc_sl811_read_reg(struct hc_sl811_dev *dev, int reg){	u8 val;	unsigned long flags;	local_irq_save(flags);	val = __hc_sl811_read_reg(dev, reg);	local_irq_restore(flags);	return val;}static inline void __hc_sl811_write_reg(struct hc_sl811_dev *dev, int reg, u8 val){	HC_SL811_WRITE_ADDR(dev, reg);	HC_SL811_WRITE_DATA(dev, val);}static inline void hc_sl811_write_reg(struct hc_sl811_dev *dev, int reg, u8 val){	unsigned long flags;	local_irq_save(flags);	__hc_sl811_write_reg(dev, reg, val);	local_irq_restore(flags);}static inline void __hc_sl811_set_mask(struct hc_sl811_dev *dev, int reg, u8 mask){	u8 val;	val = __hc_sl811_read_reg(dev, reg);	val |= mask;	__hc_sl811_write_reg(dev, reg, val);}static inline void hc_sl811_set_mask(struct hc_sl811_dev *dev, int reg, u8 mask){	unsigned long flags;	local_irq_save(flags);	__hc_sl811_set_mask(dev, reg, mask);	local_irq_restore(flags);}static inline void __hc_sl811_clr_mask(struct hc_sl811_dev *dev, int reg, u8 mask){	u8 val;	val = __hc_sl811_read_reg(dev, reg);	val &= ~mask;	__hc_sl811_write_reg(dev, reg, val);}static inline void hc_sl811_clr_mask(struct hc_sl811_dev *dev, int reg, u8 mask){	unsigned long flags;	local_irq_save(flags);	__hc_sl811_clr_mask(dev, reg, mask);	local_irq_restore(flags);}static void __hc_sl811_write_regs(struct hc_sl811_dev *dev, u8 reg, const void *buf, int count){	int i;	const u8 *data = buf;	HC_SL811_WRITE_ADDR(dev, reg);	for (i = 0; i < count; i++) {		HC_SL811_WRITE_DATA(dev, data[i]);	}}static void __hc_sl811_read_regs(struct hc_sl811_dev *dev, u8 reg, void *buf, int count){	int i;	u8 *data = buf;	HC_SL811_WRITE_ADDR(dev, reg);	for (i = 0; i < count; i++) {		data[i] = HC_SL811_READ_DATA(dev);	}}static void hc_sl811_dump_regs(struct hc_sl811_dev *dev){	u8 reg;	for (reg = SL11H_HOSTCTLREG; reg <= SL11H_CTLREG2; reg++) {		u8 val;		unsigned long flags;		if (reg == 7) continue;		local_irq_save(flags);		val = __hc_sl811_read_reg(dev, reg);		local_irq_restore(flags);		printk(KERN_DEBUG "%s: reg[%02x]=%02x\n", __FUNCTION__, reg, val);	}}#if defined(CONFIG_ARCH_KARO)static void sl811_set_hw_reset(void){	if (karo_pcf8574_clr(FMsk(KARO_PCF8574_USBRST)) < 0) {		printk(KERN_ERR "%s: failed to assert reset via PCF8574\n", __FUNCTION__);	}}static void sl811_clr_hw_reset(void){	if (karo_pcf8574_set(FMsk(KARO_PCF8574_USBRST)) < 0) {		printk(KERN_ERR "%s: failed to deassert reset via PCF8574\n", __FUNCTION__);	}}#else//#error Define your hardware specific functions herestatic void sl811_set_hw_reset(void){}static void sl811_clr_hw_reset(void){}#endif// function prototypesstatic int hc_sl811_detect_device(struct usb_hcd *hcd);static void hc_sl811_usb_reset(struct usb_hcd *hcd, int assert);static void hc_sl811_start_sof(struct usb_hcd *hcd, int lowspeed);static void ohci_sl811_bh(unsigned long data);static u32 retire_td(struct usb_hcd *hcd, struct td *td, struct ed *ed, u32 cc);static u32 kill_current_td(struct usb_hcd *hcd, struct hc_sl811_dev *dev);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -