X-Git-Url: http://git.rohieb.name/openwrt.git/blobdiff_plain/15331876847019b1a3cdec43dcc19073b6b41dd2..3329b43e7655951c4b496eb7c24b2af096fcbef7:/target/linux/adm5120/files/drivers/usb/host/adm5120.h diff --git a/target/linux/adm5120/files/drivers/usb/host/adm5120.h b/target/linux/adm5120/files/drivers/usb/host/adm5120.h index 95616f27a..52fe039f4 100644 --- a/target/linux/adm5120/files/drivers/usb/host/adm5120.h +++ b/target/linux/adm5120/files/drivers/usb/host/adm5120.h @@ -1,10 +1,16 @@ /* - * OHCI HCD (Host Controller Driver) for USB. + * ADM5120 HCD (Host Controller Driver) for USB * - * (C) Copyright 1999 Roman Weissgaerber - * (C) Copyright 2000-2002 David Brownell + * Copyright (C) 2007-2008 Gabor Juhos + * + * This file was derived from: drivers/usb/host/ohci.h + * (C) Copyright 1999 Roman Weissgaerber + * (C) Copyright 2000-2002 David Brownell + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. * - * This file is licenced under the GPL. */ /* @@ -58,14 +64,10 @@ struct ed { struct list_head urb_list; /* list of our URBs */ - struct list_head ed_list; /* list of all EDs*/ - struct list_head rm_list; /* for remove list */ - /* host's view of schedule */ struct ed *ed_next; /* on schedule list */ struct ed *ed_prev; /* for non-interrupt EDs */ struct ed *ed_rm_next; /* on rm list */ - struct ed *ed_soft_list; /* on software int list */ struct list_head td_list; /* "shadow list" of our TDs */ /* create --> IDLE --> OPER --> ... --> IDLE --> destroy @@ -115,16 +117,17 @@ struct td { #define TD_T_SHIFT 23 /* data toggle state */ #define TD_T_MASK 0x3 #define TD_T (TD_T_MASK << TD_T_SHIFT) -#define TD_T_DATA0 (0x2 << TD_T_SHIFT) /* DATA0 */ -#define TD_T_DATA1 (0x3 << TD_T_SHIFT) /* DATA1 */ -#define TD_T_CARRY (0x0 << TD_T_SHIFT) /* uses ED_C */ +#define TD_T_DATA0 (0x2 << TD_T_SHIFT) /* DATA0 */ +#define TD_T_DATA1 (0x3 << TD_T_SHIFT) /* DATA1 */ +#define TD_T_CARRY (0x0 << TD_T_SHIFT) /* uses ED_C */ #define TD_T_GET(x) (((x) >> TD_T_SHIFT) & TD_T_MASK) #define TD_DP_SHIFT 21 /* direction/pid */ #define TD_DP_MASK 0x3 #define TD_DP (TD_DP_MASK << TD_DP_SHIFT) -#define TD_DP_SETUP (0x0 << TD_DP_SHIFT) /* SETUP pid */ -#define TD_DP_OUT (0x1 << TD_DP_SHIFT) /* OUT pid */ -#define TD_DP_IN (0x2 << TD_DP_SHIFT) /* IN pid */ +#define TD_DP_GET (((x) >> TD_DP_SHIFT) & TD_DP_MASK) +#define TD_DP_SETUP (0x0 << TD_DP_SHIFT) /* SETUP pid */ +#define TD_DP_OUT (0x1 << TD_DP_SHIFT) /* OUT pid */ +#define TD_DP_IN (0x2 << TD_DP_SHIFT) /* IN pid */ #define TD_ISI_SHIFT 8 /* Interrupt Service Interval */ #define TD_ISI_MASK 0x3f #define TD_ISI_GET(x) (((x) >> TD_ISI_SHIFT) & TD_ISI_MASK) @@ -184,7 +187,7 @@ struct td { /* map OHCI TD status codes (CC) to errno values */ -static const int cc_to_error [16] = { +static const int cc_to_error[16] = { /* No Error */ 0, /* CRC Error */ -EILSEQ, /* Bit Stuff */ -EPROTO, @@ -269,6 +272,8 @@ struct admhcd_regs { */ #define ADMHC_INTR_SOFI (1 << 4) /* start of frame */ #define ADMHC_INTR_RESI (1 << 5) /* resume detected */ +#define ADMHC_INTR_6 (1 << 6) /* unknown */ +#define ADMHC_INTR_7 (1 << 7) /* unknown */ #define ADMHC_INTR_BABI (1 << 8) /* babble detected */ #define ADMHC_INTR_INSM (1 << 9) /* root hub status change */ #define ADMHC_INTR_SO (1 << 10) /* scheduling overrun */ @@ -389,8 +394,6 @@ struct admhcd { struct ed *ed_tails[4]; struct ed *ed_rm_list; /* to be removed */ - struct ed *ed_halt_list; /* halted due to an error */ - struct ed *ed_soft_list; /* for software interrupt processing */ struct ed *periodic[NUM_INTS]; /* shadow int_table */ @@ -427,7 +430,14 @@ struct admhcd { #define OHCI_QUIRK_BE_DESC 0x08 /* BE descriptors */ #define OHCI_QUIRK_BE_MMIO 0x10 /* BE registers */ #define OHCI_QUIRK_ZFMICRO 0x20 /* Compaq ZFMicro chipset*/ - // there are also chip quirks/bugs in init logic + /* there are also chip quirks/bugs in init logic */ + +#ifdef DEBUG + struct dentry *debug_dir; + struct dentry *debug_async; + struct dentry *debug_periodic; + struct dentry *debug_registers; +#endif }; /* convert between an hcd pointer and the corresponding ahcd_hcd */ @@ -446,14 +456,19 @@ static inline struct usb_hcd *admhcd_to_hcd(const struct admhcd *ahcd) #define STUB_DEBUG_FILES #endif /* DEBUG */ -#define admhc_dbg(ahcd, fmt, args...) \ - dev_dbg(admhcd_to_hcd(ahcd)->self.controller , fmt , ## args ) +#ifdef DEBUG +# define admhc_dbg(ahcd, fmt, args...) \ + printk(KERN_DEBUG "adm5120-hcd: " fmt, ## args) +#else +# define admhc_dbg(ahcd, fmt, args...) do { } while (0) +#endif + #define admhc_err(ahcd, fmt, args...) \ - dev_err(admhcd_to_hcd(ahcd)->self.controller , fmt , ## args ) -#define ahcd_info(ahcd, fmt, args...) \ - dev_info(admhcd_to_hcd(ahcd)->self.controller , fmt , ## args ) + printk(KERN_ERR "adm5120-hcd: " fmt, ## args) +#define admhc_info(ahcd, fmt, args...) \ + printk(KERN_INFO "adm5120-hcd: " fmt, ## args) #define admhc_warn(ahcd, fmt, args...) \ - dev_warn(admhcd_to_hcd(ahcd)->self.controller , fmt , ## args ) + printk(KERN_WARNING "adm5120-hcd: " fmt, ## args) #ifdef ADMHC_VERBOSE_DEBUG # define admhc_vdbg admhc_dbg @@ -557,8 +572,9 @@ static inline void admhc_writel(const struct admhcd *ahcd, static inline void admhc_writel_flush(const struct admhcd *ahcd) { -#if 0 /* TODO: needed? */ - (void) admhc_readl(ahcd, &ahcd->regs->control); +#if 0 + /* TODO: remove? */ + (void) admhc_readl(ahcd, &ahcd->regs->gencontrol); #endif } @@ -633,6 +649,15 @@ static inline u16 admhc_frame_no(const struct admhcd *ahcd) return (u16)t; } +static inline u16 admhc_frame_remain(const struct admhcd *ahcd) +{ + u32 t; + + t = admhc_readl(ahcd, &ahcd->regs->fmnumber) >> ADMHC_SFN_FR_SHIFT; + t &= ADMHC_SFN_FR_MASK; + return (u16)t; +} + /*-------------------------------------------------------------------------*/ static inline void admhc_disable(struct admhcd *ahcd) @@ -640,31 +665,45 @@ static inline void admhc_disable(struct admhcd *ahcd) admhcd_to_hcd(ahcd)->state = HC_STATE_HALT; } -#define FI 0x2edf /* 12000 bits per frame (-1) */ -#define FSLDP(fi) (0x7fff & ((6 * ((fi) - 210)) / 7)) -#define FIT ADMHC_SFI_FIT -#define LSTHRESH 0x628 /* lowspeed bit threshold */ +#define FI 0x2edf /* 12000 bits per frame (-1) */ +#define FSLDP(fi) (0x7fff & ((6 * ((fi) - 1200)) / 7)) +#define FIT ADMHC_SFI_FIT +#define LSTHRESH 0x628 /* lowspeed bit threshold */ static inline void periodic_reinit(struct admhcd *ahcd) { +#if 0 u32 fi = ahcd->fminterval & ADMHC_SFI_FI_MASK; u32 fit = admhc_readl(ahcd, &ahcd->regs->fminterval) & FIT; /* TODO: adjust FSLargestDataPacket value too? */ admhc_writel(ahcd, (fit ^ FIT) | ahcd->fminterval, - &ahcd->regs->fminterval); + &ahcd->regs->fminterval); +#else + u32 fit = admhc_readl(ahcd, &ahcd->regs->fminterval) & FIT; + + /* TODO: adjust FSLargestDataPacket value too? */ + admhc_writel(ahcd, (fit ^ FIT) | ahcd->fminterval, + &ahcd->regs->fminterval); +#endif } -static inline u32 admhc_get_rhdesc(struct admhcd *ahcd) +static inline u32 admhc_read_rhdesc(struct admhcd *ahcd) { return admhc_readl(ahcd, &ahcd->regs->rhdesc); } -static inline u32 admhc_get_portstatus(struct admhcd *ahcd, int port) +static inline u32 admhc_read_portstatus(struct admhcd *ahcd, int port) { return admhc_readl(ahcd, &ahcd->regs->portstatus[port]); } +static inline void admhc_write_portstatus(struct admhcd *ahcd, int port, + u32 value) +{ + admhc_writel(ahcd, value, &ahcd->regs->portstatus[port]); +} + static inline void roothub_write_status(struct admhcd *ahcd, u32 value) { /* FIXME: read-only bits must be masked out */ @@ -698,17 +737,26 @@ static inline void admhc_intr_ack(struct admhcd *ahcd, u32 ints) static inline void admhc_dma_enable(struct admhcd *ahcd) { - ahcd->host_control = admhc_readl(ahcd, &ahcd->regs->host_control); - if (ahcd->host_control & ADMHC_HC_DMAE) + u32 t; + + t = admhc_readl(ahcd, &ahcd->regs->host_control); + if (t & ADMHC_HC_DMAE) return; - ahcd->host_control |= ADMHC_HC_DMAE; - admhc_writel(ahcd, ahcd->host_control, &ahcd->regs->host_control); + t |= ADMHC_HC_DMAE; + admhc_writel(ahcd, t, &ahcd->regs->host_control); + admhc_vdbg(ahcd, "DMA enabled\n"); } static inline void admhc_dma_disable(struct admhcd *ahcd) { - ahcd->host_control = admhc_readl(ahcd, &ahcd->regs->host_control); - ahcd->host_control &= ~ADMHC_HC_DMAE; - admhc_writel(ahcd, ahcd->host_control, &ahcd->regs->host_control); + u32 t; + + t = admhc_readl(ahcd, &ahcd->regs->host_control); + if (!(t & ADMHC_HC_DMAE)) + return; + + t &= ~ADMHC_HC_DMAE; + admhc_writel(ahcd, t, &ahcd->regs->host_control); + admhc_vdbg(ahcd, "DMA disabled\n"); }