On Mon, 2004-09-13 at 09:59, Olav Kongas wrote: > Hi Lothar, > > On Sat, 11 Sep 2004, Dimitris Lampridis wrote: > > > On Fri, 2004-09-10 at 16:56, Lothar Wassmann wrote: > > > No. The device could be used as a slave DMA device, but: > > > 1) in our hardware the data register is located on a non-DMAable > > > address (PXA DMA addresses must be aligned to double word > > > boundary) > > > 2) the SL811 requires CPU intervention for every data packet that is > > > sent or received anyway and could possibly transfer at most 240 > > > byte in a single packet. Thus it's not worth the effort of using > > > DMA to move data to/from the chip. > > > For the ISP116x/1362 it's a different story. > > I guess these are your answers to Dimitris' questions about > your sl811 driver. It seems that you posted these directly > to Dimitris. Also, I couldn't find the 1362 header file > Dimitris was talking about. Could you please repost all this > to the list as well. > > Thanks in advance, > Olav Propably true. Since Lothar hasn't replied, i'll send it.
Dimitris
/* * ISP1362 HCD (Host Controller Driver) for USB. * * COPYRIGHT (C) by L. Wassmann <[EMAIL PROTECTED]> * * */ #include <asm/arch/bitfield.h> #ifdef CONFIG_ARCH_KARO #include <asm/arch/karo.h> #endif // settings used for debugging: #define DEBUG #ifdef DEBUG #define BUFFER_TEST #define TEST_BUF_SIZE 4096 #endif #define FLIP_BUFFERS 32 #define USB_RESET_WIDTH 50 #define REG_WIDTH_16 0x000 #define REG_WIDTH_32 0x100 #define REG_WIDTH_MASK 0x100 #define REG_NO_MASK 0x0ff #define REG_ACCESS_R 0x200 #define REG_ACCESS_W 0x400 #define REG_ACCESS_RW 0x600 #define REG_ACCESS_M 0x800 // reg needs to be merged with shadow reg #define REG_ACCESS_MASK 0x600 //#define PTD_BLK_SIZE 64 #define ISP1362_BUF_SIZE 4096 #define ISP1362_REG_WRITE_OFFSET 0x80 #ifdef DEBUG typedef const unsigned int isp1362_reg_t; #define _BUG_ON(x) BUG_ON(x) #define ISP1362_REG(name,addr,width,rw) \ static isp1362_reg_t ISP1362_REG_##name = ((addr) | (width) | (rw)); #else typedef const unsigned char isp1362_reg_t; #define _BUG_ON(x) do {} while(0) #define ISP1362_REG(name,addr,width,rw) \ static isp1362_reg_t ISP1362_REG_##name = addr; #endif // OHCI compatible registers /* * some of the ISP1362 'OHCI' registers implement only a subset of the * bits defined in the OHCI spec. For those registers we keep a shadow * copy in 'struct ohci_regs' that maintains the state of the bits that * are not defined in the ISP1362 controller register. * Those registers have to be read/written with the ohci_{read|write}_masked() functions. * Bitmasks for the individual bits of these registers are defined in "ohci.h" */ ISP1362_REG(HCREVISION, 0x00, REG_WIDTH_32, REG_ACCESS_R); ISP1362_REG(HCCONTROL, 0x01, REG_WIDTH_32, REG_ACCESS_RW | REG_ACCESS_M); #define ISP1362_MASK_HCCONTROL (OHCI_CTRL_HCFS | OHCI_CTRL_RWE | OHCI_CTRL_RWC) ISP1362_REG(HCCMDSTAT, 0x02, REG_WIDTH_32, REG_ACCESS_RW | REG_ACCESS_M); #define ISP1362_MASK_HCCMDSTAT (OHCI_HCR | OHCI_SOC) ISP1362_REG(HCINTSTAT, 0x03, REG_WIDTH_32, REG_ACCESS_RW | REG_ACCESS_M); #define ISP1362_MASK_HCINTSTAT (OHCI_INTR_SO | OHCI_INTR_SF | OHCI_INTR_RD | OHCI_INTR_UE | OHCI_INTR_FNO | OHCI_INTR_RHSC) ISP1362_REG(HCINTENB, 0x04, REG_WIDTH_32, REG_ACCESS_RW | REG_ACCESS_M); #define ISP1362_MASK_HCINTENB (ISP1362_MASK_HCINTSTAT | OHCI_INTR_MIE) ISP1362_REG(HCINTDIS, 0x05, REG_WIDTH_32, REG_ACCESS_RW | REG_ACCESS_M); // OHCI_INTR_SF is required for internal housekeeping and shouldn't be disabled by OHCI layer #define ISP1362_MASK_HCINTDIS (ISP1362_MASK_HCINTENB & ~OHCI_INTR_SF) ISP1362_REG(HCFMINTVL, 0x0d, REG_WIDTH_32, REG_ACCESS_RW); ISP1362_REG(HCFMREM, 0x0e, REG_WIDTH_32, REG_ACCESS_RW); ISP1362_REG(HCFMNUM, 0x0f, REG_WIDTH_32, REG_ACCESS_RW); ISP1362_REG(HCLSTHRESH, 0x11, REG_WIDTH_32, REG_ACCESS_RW); ISP1362_REG(HCRHDESCA, 0x12, REG_WIDTH_32, REG_ACCESS_RW); ISP1362_REG(HCRHDESCB, 0x13, REG_WIDTH_32, REG_ACCESS_RW); ISP1362_REG(HCRHSTATUS, 0x14, REG_WIDTH_32, REG_ACCESS_RW); ISP1362_REG(HCRHPORT1, 0x15, REG_WIDTH_32, REG_ACCESS_RW); ISP1362_REG(HCRHPORT2, 0x16, REG_WIDTH_32, REG_ACCESS_RW); // Philips ISP1362 specific registers ISP1362_REG(HCHWCFG, 0x20, REG_WIDTH_16, REG_ACCESS_RW); #define HCHWCFG_DISABLE_SUSPEND (1 << 15) #define HCHWCFG_GLOBAL_PWRDOWN (1 << 14) #define HCHWCFG_PULLDOWN_DS1 (1 << 13) #define HCHWCFG_PULLDOWN_DS2 (1 << 12) #define HCHWCFG_CLKNOTSTOP (1 << 11) #define HCHWCFG_ANALOG_OC (1 << 10) #define HCHWCFG_ONEINT (1 << 9) #define HCHWCFG_DACK_MODE (1 << 8) #define HCHWCFG_ONEDMA (1 << 7) #define HCHWCFG_DACK_POL (1 << 6) #define HCHWCFG_DREQ_POL (1 << 5) #define HCHWCFG_DBWIDTH_MASK (0x03 << 3) #define HCHWCFG_DBWIDTH(n) (((n) << 3) & HCHWCFG_DBWIDTH_MASK) #define HCHWCFG_INT_POL (1 << 2) #define HCHWCFG_INT_TRIGGER (1 << 1) #define HCHWCFG_INT_ENABLE (1 << 0) ISP1362_REG(HCDMACFG, 0x21, REG_WIDTH_16, REG_ACCESS_RW); #define HCDMACFG_CTR_ENABLE (1 << 7) #define HCDMACFG_BURST_LEN_MASK (0x03 << 5) #define HCDMACFG_BURST_LEN(n) (((n) << 5) & HCDMACFG_BURST_LEN__MASK) #define HCDMACFG_BURST_LEN_1 HCDMACFG_BURST_LEN(0) #define HCDMACFG_BURST_LEN_4 HCDMACFG_BURST_LEN(1) #define HCDMACFG_BURST_LEN_8 HCDMACFG_BURST_LEN(2) #define HCDMACFG_DMA_ENABLE (1 << 4) #define HCDMACFG_BUF_TYPE_MASK (0x07 << 1) #define HCDMACFG_BUF_TYPE(n) (((n) << 1) & HCDMACFG_BURST_LEN__MASK) #define HCDMACFG_BUF_ISTL0 HCDMACFG_BUF_TYPE(0) #define HCDMACFG_BUF_ISTL1 HCDMACFG_BUF_TYPE(1) #define HCDMACFG_BUF_INTL HCDMACFG_BUF_TYPE(2) #define HCDMACFG_BUF_ATL HCDMACFG_BUF_TYPE(3) #define HCDMACFG_BUF_DIRECT HCDMACFG_BUF_TYPE(4) #define HCDMACFG_DMA_RW_SELECT (1 << 0) ISP1362_REG(HCXFERCTR, 0x22, REG_WIDTH_16, REG_ACCESS_RW); ISP1362_REG(HCuPINT, 0x24, REG_WIDTH_16, REG_ACCESS_RW); #define HCuPINT_SOF (1 << 0) #define HCuPINT_ISTL0 (1 << 1) #define HCuPINT_ISTL1 (1 << 2) #define HCuPINT_EOT (1 << 3) #define HCuPINT_OPR (1 << 4) #define HCuPINT_SUSP (1 << 5) #define HCuPINT_CLKRDY (1 << 6) #define HCuPINT_INTL (1 << 7) #define HCuPINT_ATL (1 << 8) #define HCuPINT_OTG (1 << 9) ISP1362_REG(HCuPINTENB, 0x25, REG_WIDTH_16, REG_ACCESS_RW); // same bit definitions apply as for HCuPINT ISP1362_REG(HCCHIPID, 0x27, REG_WIDTH_16, REG_ACCESS_R); #define HCCHIPID_MASK 0xff00 #define HCCHIPID_MAGIC 0x3600 ISP1362_REG(HCSCRATCH, 0x28, REG_WIDTH_16, REG_ACCESS_RW); ISP1362_REG(HCSWRES, 0x29, REG_WIDTH_16, REG_ACCESS_W); #define HCSWRES_MAGIC 0x00f6 ISP1362_REG(HCBUFSTAT, 0x2c, REG_WIDTH_16, REG_ACCESS_RW); #define HCBUFSTAT_ISTL0_FULL (1 << 0) #define HCBUFSTAT_ISTL1_FULL (1 << 1) #define HCBUFSTAT_INTL_ACTIVE (1 << 2) #define HCBUFSTAT_ATL_ACTIVE (1 << 3) #define HCBUFSTAT_RESET_HWPP (1 << 4) #define HCBUFSTAT_ISTL0_ACTIVE (1 << 5) #define HCBUFSTAT_ISTL1_ACTIVE (1 << 6) #define HCBUFSTAT_ISTL0_DONE (1 << 8) #define HCBUFSTAT_ISTL1_DONE (1 << 9) #define HCBUFSTAT_PAIRED_PTDPP (1 << 10) ISP1362_REG(HCDIRADDR, 0x32, REG_WIDTH_32, REG_ACCESS_RW); #define _HCDIRADDR_ADDR Fld(16, 0) #define HCDIRADDR_ADDR_MASK FMsk(_HCDIRADDR_ADDR) #define HCDIRADDR_ADDR(n) (FInsrt(n, _HCDIRADDR_ADDR) & FMsk(_HCDIRADDR_ADDR)) #define _HCDIRADDR_COUNT Fld(16, 16) #define HCDIRADDR_COUNT_MASK FMsk(_HCDIRADDR_COUNT) #define HCDIRADDR_COUNT(n) (FInsrt(n, _HCDIRADDR_COUNT) & FMsk(_HCDIRADDR_COUNT)) ISP1362_REG(HCDIRDATA, 0x45, REG_WIDTH_16, REG_ACCESS_RW); ISP1362_REG(HCISTLBUFSZ, 0x30, REG_WIDTH_16, REG_ACCESS_RW); ISP1362_REG(HCISTL0PORT, 0x40, REG_WIDTH_16, REG_ACCESS_RW); ISP1362_REG(HCISTL1PORT, 0x42, REG_WIDTH_16, REG_ACCESS_RW); ISP1362_REG(HCISTLRATE, 0x47, REG_WIDTH_16, REG_ACCESS_RW); ISP1362_REG(HCINTLBUFSZ, 0x33, REG_WIDTH_16, REG_ACCESS_RW); ISP1362_REG(HCINTLPORT, 0x43, REG_WIDTH_16, REG_ACCESS_RW); ISP1362_REG(HCINTLBLKSZ, 0x53, REG_WIDTH_16, REG_ACCESS_RW); ISP1362_REG(HCINTLDONE, 0x17, REG_WIDTH_32, REG_ACCESS_R); ISP1362_REG(HCINTLSKIP, 0x18, REG_WIDTH_32, REG_ACCESS_RW); ISP1362_REG(HCINTLLAST, 0x19, REG_WIDTH_32, REG_ACCESS_RW); ISP1362_REG(HCINTLCURR, 0x1a, REG_WIDTH_16, REG_ACCESS_R); ISP1362_REG(HCATLBUFSZ, 0x34, REG_WIDTH_16, REG_ACCESS_RW); ISP1362_REG(HCATLPORT, 0x44, REG_WIDTH_16, REG_ACCESS_RW); ISP1362_REG(HCATLBLKSZ, 0x54, REG_WIDTH_16, REG_ACCESS_RW); ISP1362_REG(HCATLDONE, 0x1b, REG_WIDTH_32, REG_ACCESS_R); ISP1362_REG(HCATLSKIP, 0x1c, REG_WIDTH_32, REG_ACCESS_RW); ISP1362_REG(HCATLLAST, 0x1d, REG_WIDTH_32, REG_ACCESS_RW); ISP1362_REG(HCATLCURR, 0x1e, REG_WIDTH_16, REG_ACCESS_R); ISP1362_REG(HCATLDTC, 0x51, REG_WIDTH_16, REG_ACCESS_RW); ISP1362_REG(HCATLDTCTO, 0x52, REG_WIDTH_16, REG_ACCESS_RW); /* * define initial values for the HW configuration registers * Since those values are implementation specific we define * them here for conveniently changing them according to the * machine type. */ #ifdef CONFIG_ARCH_KARO #define HCHWCFG_INIT_VAL (HCHWCFG_GLOBAL_PWRDOWN | \ HCHWCFG_ANALOG_OC | \ HCHWCFG_DREQ_POL | \ HCHWCFG_CLKNOTSTOP | \ HCHWCFG_DBWIDTH(1) | \ HCHWCFG_INT_POL | \ HCHWCFG_INT_ENABLE) #else #error Specify appropriate initialization values for HW configuration registers #define HCHWCFG_INIT_VAL () #endif #define ohci_to_hcd(ohci) (&(ohci)->hcd) #define hcd_to_isp1362_dev(hcd) ((struct hc_isp1362_dev *)dev_get_drvdata(hcd->self.controller)) #define ohci_to_isp1362_dev(ohci) ((struct hc_isp1362_dev *)dev_get_drvdata(ohci->hcd.self.controller)) #define hc_isp1362_dev_to_hcd(dev) ((struct usb_hcd *)dev_get_drvdata(&dev->dev)) struct ptd { u8 count; u8 cc_toggle; u8 mps; u8 ep_spd; u8 len; u8 dir; u8 func_addr; u8 pr_sf; } __attribute__((packed)); #define _PTD_COUNT Fld(10, 0) #define PTD_COUNT(v) FInsrt(v, _PTD_COUNT) #define PTD_GET_COUNT(p) FExtr(*(u16*)(&(p)->count), _PTD_COUNT) #define _PTD_TOGGLE Fld(1, 2) #define PTD_TOGGLE(v) FInsrt(v, _PTD_TOGGLE) #define PTD_GET_TOGGLE(p) FExtr((p)->cc_toggle, _PTD_TOGGLE) #define _PTD_ACTIVE Fld(1, 3) #define PTD_ACTIVE(v) FInsrt(v, _PTD_ACTIVE) #define PTD_GET_ACTIVE(p) FExtr((p)->cc_toggle, _PTD_ACTIVE) #define _PTD_CC Fld(4, 12) #define PTD_CC(v) FInsrt(v, _PTD_CC) #define PTD_GET_CC(p) FExtr((p)->cc_toggle, _PTD_CC) #define _PTD_MPS Fld(10, 0) #define PTD_MPS(v) FInsrt(v, _PTD_MPS) #define PTD_GET_MPS(p) FExtr(*(u16*)(&(p)->dir), _PTD_MPS) #define _PTD_MPS_H Fld(2, 0) #define PTD_MPS_H(v) FInsrt(v, _PTD_MPS_H) #define _PTD_SPD Fld(1, 2) #define PTD_SPD(v) FInsrt(v, _PTD_SPD) #define PTD_GET_SPD(p) FExtr((p)->ep_spd, _PTD_SPD) #define _PTD_LAST_ISO Fld(1, 3) #define PTD_LAST_ISO(v) FInsrt(v, _PTD_LAST_ISO) #define PTD_GET_LAST_ISO(p) FExtr((p)->ep_spd, _PTD_LAST_ISO) #define _PTD_EP Fld(4, 4) #define PTD_EP(v) FInsrt(v, _PTD_EP) #define PTD_GET_EP(p) FExtr((p)->ep_spd, _PTD_EP) #define _PTD_LEN Fld(10, 0) #define PTD_LEN(v) FInsrt(v, _PTD_LEN) #define PTD_GET_LEN(p) FExtr(*(u16*)(&(p)->len), _PTD_LEN) #define _PTD_LEN_H Fld(2, 0) #define PTD_LEN_H(v) FInsrt(v, _PTD_LEN_H) #define _PTD_DIR Fld(2, 2) #define PTD_DIR(v) FInsrt(v, _PTD_DIR) #define PTD_GET_DIR(p) FExtr((p)->dir, _PTD_DIR) #define _PTD_SF Fld(4, 0) #define PTD_SF(v) FInsrt(v, _PTD_SF) #define PTD_GET_SF(p) FExtr(*(u16*)(&(p)->pr_sf), _PTD_SF) #define _PTD_PR Fld(3, 5) #define PTD_PR(v) FInsrt(v, _PTD_PR) #define PTD_GET_PR(p) FExtr(*(u16*)(&(p)->pr_sf), _PTD_PR) #define PID_SETUP 0 #define PID_OUT 1 #define PID_IN 2 #define PTD_HEADER_SIZE sizeof(struct ptd) struct xfer_buf { struct ptd ptd; struct td *td; int xfer_type:2; int port:1; u16 buf_addr; // int buf_len; } __attribute__((packed)); struct ptd_queue { struct xfer_buf *buf_list; unsigned long buf_map; u16 buf_start; u16 blk_size; u8 num_bufs; }; struct hc_isp1362_dev { struct device dev; void *addr_reg; void *data_reg; int hwres_pin; int irq; #ifdef CONFIG_USB_OHCI_DMA int dma; #endif int pm_state; int iso_flip:1; int bulk_flip:1; #if 0 struct ptd_queue *ptd_queues[4]; enum { PTD_Q_ISTL0, PTD_Q_ISTL1, PTD_Q_INTL, PTD_Q_ATL, } ptd_q_type; #else void *ptd_mem; ssize_t ptd_mem_size; #ifdef ONE_ISTL_Q struct ptd_queue *ptd_queues[3]; struct ptd_queue istl_queue; #else struct ptd_queue *ptd_queues[4]; struct ptd_queue istl0_queue; struct ptd_queue istl1_queue; #endif struct ptd_queue intl_queue; struct ptd_queue atl_queue; #endif int cbc; int intrdelay; u8 hw_rev; }; struct hc_isp1362_driver { struct device_driver drv; unsigned int devid; int (*probe)(struct hc_isp1362_dev *dev); int (*remove)(struct hc_isp1362_dev *dev); int (*suspend)(struct hc_isp1362_dev *dev, u32 state); int (*resume)(struct hc_isp1362_dev *dev); // TODO: define these and init them from platform specific code // void (*reset_chip)(struct hc_isp1362_dev *dev, int flag); // void (*start_stop_clock)(struct hc_isp1362_dev *dev, int flag); }; #define ISP1362_DRV(_d) container_of((_d), struct hc_isp1362_driver, drv) /* * ISP1362 HW Interface */ #define hc_isp1362_addr_reg (dev->addr_reg) #define hc_isp1362_data_reg (dev->data_reg) // basic access functions for ISP1362 chip registers static inline void HC_ISP1362_WRITE_ADDR(struct hc_isp1362_dev *dev, isp1362_reg_t reg) { //DDPRINTK("A>[EMAIL PROTECTED]", reg, (u32)hc_isp1362_addr_reg); __asm__ volatile ("/* HC_ISP1362_WRITE_ADDR START */"); _BUG_ON((reg & 0x80) && !(reg & REG_ACCESS_W)); writew(reg, hc_isp1362_addr_reg); __asm__ volatile ("/* HC_ISP1362_WRITE_ADDR END */"); } static inline void HC_ISP1362_WRITE_DATA16(struct hc_isp1362_dev *dev, u16 val) { __asm__ volatile ("/* HC_ISP1362_WRITE_DATA16 START */"); writew(val, hc_isp1362_data_reg); __asm__ volatile ("/* HC_ISP1362_WRITE_DATA16 END */"); } static inline u16 HC_ISP1362_READ_DATA16(struct hc_isp1362_dev *dev) { u16 val; __asm__ volatile ("/* HC_ISP1362_READ_DATA16 START */"); val = readw(hc_isp1362_data_reg); //DDPRINTK("D<[EMAIL PROTECTED]", val, (u32)hc_isp1362_data_reg); __asm__ volatile ("/* HC_ISP1362_READ_DATA16 END */"); return val; } static inline void HC_ISP1362_WRITE_DATA32(struct hc_isp1362_dev *dev, u32 val) { __asm__ volatile ("/* HC_ISP1362_WRITE_DATA32 START */"); writel(val, hc_isp1362_data_reg); __asm__ volatile ("/* HC_ISP1362_WRITE_DATA32 END */"); } static inline u32 HC_ISP1362_READ_DATA32(struct hc_isp1362_dev *dev) { u32 val; __asm__ volatile ("/* HC_ISP1362_READ_DATA32 START */"); val = readl(hc_isp1362_data_reg); //DDPRINTK("D<[EMAIL PROTECTED]", val, (u32)hc_isp1362_data_reg); __asm__ volatile ("/* HC_ISP1362_READ_DATA32 END */"); return val; } #define __isp1362_read_reg16(d, r) ({ \ u16 __v; \ _BUG_ON(((ISP1362_REG_##r) & REG_WIDTH_MASK) != REG_WIDTH_16); \ HC_ISP1362_WRITE_ADDR(d, ISP1362_REG_##r); \ __v = HC_ISP1362_READ_DATA16(d); \ }) #define isp1362_read_reg16(d, r) ({ \ u16 __v; \ unsigned long __f; \ local_irq_save(__f); \ __v = __isp1362_read_reg16(d, r); \ local_irq_restore(__f); \ __v; \ }) #define __isp1362_read_reg32(d, r) ({ \ u32 __v; \ _BUG_ON(((ISP1362_REG_##r) & REG_WIDTH_MASK) != REG_WIDTH_32); \ HC_ISP1362_WRITE_ADDR(d, ISP1362_REG_##r); \ __v = HC_ISP1362_READ_DATA32(d); \ }) #define __isp1362_write_reg16(d, r, v) { \ _BUG_ON(((ISP1362_REG_##r) & REG_WIDTH_MASK) != REG_WIDTH_16); \ HC_ISP1362_WRITE_ADDR(d, (ISP1362_REG_##r) | ISP1362_REG_WRITE_OFFSET); \ HC_ISP1362_WRITE_DATA16(d, v); \ } #define __isp1362_write_reg32(d, r, v) { \ _BUG_ON(((ISP1362_REG_##r) & REG_WIDTH_MASK) != REG_WIDTH_32); \ HC_ISP1362_WRITE_ADDR(d, (ISP1362_REG_##r) | ISP1362_REG_WRITE_OFFSET); \ HC_ISP1362_WRITE_DATA32(d, v); \ } #define isp1362_write_reg16(d, r, v) { \ unsigned long flags; \ local_irq_save(flags); \ __isp1362_write_reg16(d, r, v); \ local_irq_restore(flags); \ } #if 0 // access functions for ISP1362 specific (16bit) registers static inline u16 __hc_isp1362_read_reg(struct hc_isp1362_dev *dev, isp1362_reg_t reg) { u16 val; __asm__ volatile ("/* __hc_isp1362_read_reg START */"); _BUG_ON((reg & REG_WIDTH_MASK) != REG_WIDTH_16); HC_ISP1362_WRITE_ADDR(dev, reg); val = HC_ISP1362_READ_DATA16(dev); __asm__ volatile ("/* __hc_isp1362_read_reg END */"); return val; } static inline u16 hc_isp1362_read_reg(struct hc_isp1362_dev *dev, isp1362_reg_t reg) { u16 val; unsigned long flags; local_irq_save(flags); val = __hc_isp1362_read_reg(dev, reg); local_irq_restore(flags); return val; } static inline void __hc_isp1362_write_reg(struct hc_isp1362_dev *dev, isp1362_reg_t reg, u16 val) { __asm__ volatile ("/* __hc_isp1362_write_reg START */"); _BUG_ON((reg & REG_WIDTH_MASK) != REG_WIDTH_16); HC_ISP1362_WRITE_ADDR(dev, reg | ISP1362_REG_WRITE_OFFSET); HC_ISP1362_WRITE_DATA16(dev, val); __asm__ volatile ("/* __hc_isp1362_write_reg END */"); } static inline void hc_isp1362_write_reg(struct hc_isp1362_dev *dev, isp1362_reg_t reg, u16 val) { unsigned long flags; local_irq_save(flags); __hc_isp1362_write_reg(dev, reg, val); local_irq_restore(flags); } #endif #define __isp1362_set_mask16(d,r,m) { \ u16 __v; \ __v = __isp1362_read_reg16(dev, r); \ __v |= m; \ __isp1362_write_reg16(dev, r, __v); \ } #define isp1362_set_mask16(d,r,m) { \ unsigned long flags; \ \ local_irq_save(flags); \ __isp1362_set_mask16(d, r, m); \ local_irq_restore(flags); \ } #define __isp1362_clr_mask16(d,r,m) { \ u16 __v; \ __v = __isp1362_read_reg16(dev, r); \ __v |= m; \ __isp1362_write_reg16(dev, r, __v); \ } #define isp1362_clr_mask16(d,r,m) { \ unsigned long flags; \ \ local_irq_save(flags); \ __isp1362_clr_mask16(d, r, m); \ local_irq_restore(flags); \ } static inline int __isp1362_read_buffer(struct hc_isp1362_dev *dev, void *buf, u16 offset, u16 len) { int ret; u8 *dp = buf; u16 data; int i; __isp1362_write_reg32(dev, HCDIRADDR, HCDIRADDR_ADDR(offset) | HCDIRADDR_COUNT(len)); for (i = 0; i < len - 1; i += 2) { data = __isp1362_read_reg16(dev, HCDIRDATA); *dp++ = data; *dp++ = data >> 8; } if (len & 1) { data = __isp1362_read_reg16(dev, HCDIRDATA); *dp++ = data; } return ret; } static inline int __isp1362_write_buffer(struct hc_isp1362_dev *dev, void *buf, u16 offset, u16 len) { int ret; u8 *dp = buf; u16 data; int i; __isp1362_write_reg32(dev, HCDIRADDR, HCDIRADDR_ADDR(offset) | HCDIRADDR_COUNT(len)); for (i = 0; i < len - 1; i += 2) { data = *dp++; data = (data << 8) | *dp++; __isp1362_write_reg16(dev, HCDIRDATA, data); } if (len & 1) { data = *dp++; __isp1362_write_reg16(dev, HCDIRDATA, data); } return ret; } static inline void hc_isp1362_dump_regs(struct hc_isp1362_dev *dev) { } #if defined(CONFIG_ARCH_KARO) static inline void isp1362_set_hw_reset(struct hc_isp1362_dev *dev) { if (dev->hwres_pin) { DPRINTK("%s: ***ASSERTING HW RESET***\n", __FUNCTION__); if (dev->hwres_pin < 0) { gpio_clr_bit(dev->hwres_pin & 0xff); } else { gpio_set_bit(dev->hwres_pin & 0xff); } } else { DPRINTK("%s: ***PERFORMING SW RESET***\n", __FUNCTION__); isp1362_write_reg16(dev, HCSWRES, HCSWRES_MAGIC); } } static inline void isp1362_clr_hw_reset(struct hc_isp1362_dev *dev) { if (dev->hwres_pin) { DPRINTK("%s: --DEASSERTING HW RESET--\n", __FUNCTION__); if (dev->hwres_pin < 0) { gpio_set_bit(dev->hwres_pin & 0xff); } else { gpio_clr_bit(dev->hwres_pin & 0xff); } } } #define isp1362_start_clock(dev) #define isp1362_stop_clock(dev) #else #error Define your hardware specific reset functions here #endif // function prototypes static __inline void retire_td(struct usb_hcd *hcd, struct td *td, struct ed *ed);