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);