mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 02:32:09 -04:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6: (262 commits) sh: mach-ecovec24: Add user debug switch support sh: Kill off unused se_skipped in alignment trap notification code. sh: Wire up HAVE_SYSCALL_TRACEPOINTS. video: sh_mobile_lcdcfb: use both register sets for display panning video: sh_mobile_lcdcfb: implement display panning sh: Fix up sh7705 flush_dcache_page() build. sh: kfr2r09: document the PLL/FLL <-> RF relationship. sh: mach-ecovec24: need asm/clock.h. sh: mach-ecovec24: deassert usb irq on boot. sh: Add KEYSC support for EcoVec24 sh: add kycr2_delay for sh_keysc sh: cpufreq: Include CPU id in info messages. sh: multi-evt support for SH-X3 proto CPU. sh: clkfwk: remove bogus set_bus_parent() from SH7709. sh: Fix the indication point of the liquid crystal of AP-325RXA(AP3300) sh: Add EcoVec24 romImage defconfig sh: USB disable process is needed if romImage boot for EcoVec24 sh: EcoVec24: add HIZA setting for LED sh: EcoVec24: write MAC address in boot sh: Add romImage support for EcoVec24 ...
This commit is contained in:
commit
515b696b28
229 changed files with 18935 additions and 3986 deletions
|
|
@ -251,6 +251,24 @@ config USB_PXA25X_SMALL
|
|||
default y if USB_ETH
|
||||
default y if USB_G_SERIAL
|
||||
|
||||
config USB_GADGET_R8A66597
|
||||
boolean "Renesas R8A66597 USB Peripheral Controller"
|
||||
select USB_GADGET_DUALSPEED
|
||||
help
|
||||
R8A66597 is a discrete USB host and peripheral controller chip that
|
||||
supports both full and high speed USB 2.0 data transfers.
|
||||
It has nine configurable endpoints, and endpoint zero.
|
||||
|
||||
Say "y" to link the driver statically, or "m" to build a
|
||||
dynamically linked module called "r8a66597_udc" and force all
|
||||
gadget drivers to also be dynamically linked.
|
||||
|
||||
config USB_R8A66597
|
||||
tristate
|
||||
depends on USB_GADGET_R8A66597
|
||||
default USB_GADGET
|
||||
select USB_GADGET_SELECTED
|
||||
|
||||
config USB_GADGET_PXA27X
|
||||
boolean "PXA 27x"
|
||||
depends on ARCH_PXA && (PXA27x || PXA3xx)
|
||||
|
|
@ -360,16 +378,6 @@ config USB_M66592
|
|||
default USB_GADGET
|
||||
select USB_GADGET_SELECTED
|
||||
|
||||
config SUPERH_BUILT_IN_M66592
|
||||
boolean "Enable SuperH built-in USB like the M66592"
|
||||
depends on USB_GADGET_M66592 && CPU_SUBTYPE_SH7722
|
||||
help
|
||||
SH7722 has USB like the M66592.
|
||||
|
||||
The transfer rate is very slow when use "Ethernet Gadget".
|
||||
However, this problem is improved if change a value of
|
||||
NET_IP_ALIGN to 4.
|
||||
|
||||
#
|
||||
# Controllers available only in discrete form (and all PCI controllers)
|
||||
#
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ ifeq ($(CONFIG_ARCH_MXC),y)
|
|||
fsl_usb2_udc-objs += fsl_mx3_udc.o
|
||||
endif
|
||||
obj-$(CONFIG_USB_M66592) += m66592-udc.o
|
||||
obj-$(CONFIG_USB_R8A66597) += r8a66597-udc.o
|
||||
obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o
|
||||
obj-$(CONFIG_USB_CI13XXX) += ci13xxx_udc.o
|
||||
obj-$(CONFIG_USB_S3C_HSOTG) += s3c-hsotg.o
|
||||
|
|
|
|||
|
|
@ -173,6 +173,12 @@
|
|||
// CONFIG_USB_GADGET_AU1X00
|
||||
// ...
|
||||
|
||||
#ifdef CONFIG_USB_GADGET_R8A66597
|
||||
#define gadget_is_r8a66597(g) !strcmp("r8a66597_udc", (g)->name)
|
||||
#else
|
||||
#define gadget_is_r8a66597(g) 0
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* usb_gadget_controller_number - support bcdDevice id convention
|
||||
|
|
@ -239,6 +245,8 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
|
|||
return 0x23;
|
||||
else if (gadget_is_langwell(gadget))
|
||||
return 0x24;
|
||||
else if (gadget_is_r8a66597(gadget))
|
||||
return 0x25;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,44 +25,18 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/usb/ch9.h>
|
||||
#include <linux/usb/gadget.h>
|
||||
|
||||
#include "m66592-udc.h"
|
||||
|
||||
|
||||
MODULE_DESCRIPTION("M66592 USB gadget driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Yoshihiro Shimoda");
|
||||
MODULE_ALIAS("platform:m66592_udc");
|
||||
|
||||
#define DRIVER_VERSION "18 Oct 2007"
|
||||
|
||||
/* module parameters */
|
||||
#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
|
||||
static unsigned short endian = M66592_LITTLE;
|
||||
module_param(endian, ushort, 0644);
|
||||
MODULE_PARM_DESC(endian, "data endian: big=0, little=0 (default=0)");
|
||||
#else
|
||||
static unsigned short clock = M66592_XTAL24;
|
||||
module_param(clock, ushort, 0644);
|
||||
MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 "
|
||||
"(default=16384)");
|
||||
|
||||
static unsigned short vif = M66592_LDRV;
|
||||
module_param(vif, ushort, 0644);
|
||||
MODULE_PARM_DESC(vif, "input VIF: 3.3V=32768, 1.5V=0 (default=32768)");
|
||||
|
||||
static unsigned short endian;
|
||||
module_param(endian, ushort, 0644);
|
||||
MODULE_PARM_DESC(endian, "data endian: big=256, little=0 (default=0)");
|
||||
|
||||
static unsigned short irq_sense = M66592_INTL;
|
||||
module_param(irq_sense, ushort, 0644);
|
||||
MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=2, falling edge=0 "
|
||||
"(default=2)");
|
||||
#endif
|
||||
#define DRIVER_VERSION "21 July 2009"
|
||||
|
||||
static const char udc_name[] = "m66592_udc";
|
||||
static const char *m66592_ep_name[] = {
|
||||
|
|
@ -244,6 +218,7 @@ static inline int get_buffer_size(struct m66592 *m66592, u16 pipenum)
|
|||
static inline void pipe_change(struct m66592 *m66592, u16 pipenum)
|
||||
{
|
||||
struct m66592_ep *ep = m66592->pipenum2ep[pipenum];
|
||||
unsigned short mbw;
|
||||
|
||||
if (ep->use_dma)
|
||||
return;
|
||||
|
|
@ -252,7 +227,12 @@ static inline void pipe_change(struct m66592 *m66592, u16 pipenum)
|
|||
|
||||
ndelay(450);
|
||||
|
||||
m66592_bset(m66592, M66592_MBW, ep->fifosel);
|
||||
if (m66592->pdata->on_chip)
|
||||
mbw = M66592_MBW_32;
|
||||
else
|
||||
mbw = M66592_MBW_16;
|
||||
|
||||
m66592_bset(m66592, mbw, ep->fifosel);
|
||||
}
|
||||
|
||||
static int pipe_buffer_setting(struct m66592 *m66592,
|
||||
|
|
@ -276,24 +256,27 @@ static int pipe_buffer_setting(struct m66592 *m66592,
|
|||
buf_bsize = 0;
|
||||
break;
|
||||
case M66592_BULK:
|
||||
bufnum = m66592->bi_bufnum +
|
||||
(info->pipe - M66592_BASE_PIPENUM_BULK) * 16;
|
||||
m66592->bi_bufnum += 16;
|
||||
/* isochronous pipes may be used as bulk pipes */
|
||||
if (info->pipe > M66592_BASE_PIPENUM_BULK)
|
||||
bufnum = info->pipe - M66592_BASE_PIPENUM_BULK;
|
||||
else
|
||||
bufnum = info->pipe - M66592_BASE_PIPENUM_ISOC;
|
||||
|
||||
bufnum = M66592_BASE_BUFNUM + (bufnum * 16);
|
||||
buf_bsize = 7;
|
||||
pipecfg |= M66592_DBLB;
|
||||
if (!info->dir_in)
|
||||
pipecfg |= M66592_SHTNAK;
|
||||
break;
|
||||
case M66592_ISO:
|
||||
bufnum = m66592->bi_bufnum +
|
||||
bufnum = M66592_BASE_BUFNUM +
|
||||
(info->pipe - M66592_BASE_PIPENUM_ISOC) * 16;
|
||||
m66592->bi_bufnum += 16;
|
||||
buf_bsize = 7;
|
||||
break;
|
||||
}
|
||||
if (m66592->bi_bufnum > M66592_MAX_BUFNUM) {
|
||||
pr_err("m66592 pipe memory is insufficient(%d)\n",
|
||||
m66592->bi_bufnum);
|
||||
|
||||
if (buf_bsize && ((bufnum + 16) >= M66592_MAX_BUFNUM)) {
|
||||
pr_err("m66592 pipe memory is insufficient\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
|
@ -313,17 +296,6 @@ static void pipe_buffer_release(struct m66592 *m66592,
|
|||
if (info->pipe == 0)
|
||||
return;
|
||||
|
||||
switch (info->type) {
|
||||
case M66592_BULK:
|
||||
if (is_bulk_pipe(info->pipe))
|
||||
m66592->bi_bufnum -= 16;
|
||||
break;
|
||||
case M66592_ISO:
|
||||
if (is_isoc_pipe(info->pipe))
|
||||
m66592->bi_bufnum -= 16;
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_bulk_pipe(info->pipe)) {
|
||||
m66592->bulk--;
|
||||
} else if (is_interrupt_pipe(info->pipe))
|
||||
|
|
@ -340,6 +312,7 @@ static void pipe_buffer_release(struct m66592 *m66592,
|
|||
static void pipe_initialize(struct m66592_ep *ep)
|
||||
{
|
||||
struct m66592 *m66592 = ep->m66592;
|
||||
unsigned short mbw;
|
||||
|
||||
m66592_mdfy(m66592, 0, M66592_CURPIPE, ep->fifosel);
|
||||
|
||||
|
|
@ -351,7 +324,12 @@ static void pipe_initialize(struct m66592_ep *ep)
|
|||
|
||||
ndelay(450);
|
||||
|
||||
m66592_bset(m66592, M66592_MBW, ep->fifosel);
|
||||
if (m66592->pdata->on_chip)
|
||||
mbw = M66592_MBW_32;
|
||||
else
|
||||
mbw = M66592_MBW_16;
|
||||
|
||||
m66592_bset(m66592, mbw, ep->fifosel);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -367,15 +345,13 @@ static void m66592_ep_setting(struct m66592 *m66592, struct m66592_ep *ep,
|
|||
ep->fifosel = M66592_D0FIFOSEL;
|
||||
ep->fifoctr = M66592_D0FIFOCTR;
|
||||
ep->fifotrn = M66592_D0FIFOTRN;
|
||||
#if !defined(CONFIG_SUPERH_BUILT_IN_M66592)
|
||||
} else if (m66592->num_dma == 1) {
|
||||
} else if (!m66592->pdata->on_chip && m66592->num_dma == 1) {
|
||||
m66592->num_dma++;
|
||||
ep->use_dma = 1;
|
||||
ep->fifoaddr = M66592_D1FIFO;
|
||||
ep->fifosel = M66592_D1FIFOSEL;
|
||||
ep->fifoctr = M66592_D1FIFOCTR;
|
||||
ep->fifotrn = M66592_D1FIFOTRN;
|
||||
#endif
|
||||
} else {
|
||||
ep->use_dma = 0;
|
||||
ep->fifoaddr = M66592_CFIFO;
|
||||
|
|
@ -620,76 +596,120 @@ static void start_ep0(struct m66592_ep *ep, struct m66592_request *req)
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
|
||||
static void init_controller(struct m66592 *m66592)
|
||||
{
|
||||
m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */
|
||||
m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
|
||||
m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
|
||||
m66592_bset(m66592, M66592_USBE, M66592_SYSCFG);
|
||||
unsigned int endian;
|
||||
|
||||
/* This is a workaound for SH7722 2nd cut */
|
||||
m66592_bset(m66592, 0x8000, M66592_DVSTCTR);
|
||||
m66592_bset(m66592, 0x1000, M66592_TESTMODE);
|
||||
m66592_bclr(m66592, 0x8000, M66592_DVSTCTR);
|
||||
if (m66592->pdata->on_chip) {
|
||||
if (m66592->pdata->endian)
|
||||
endian = 0; /* big endian */
|
||||
else
|
||||
endian = M66592_LITTLE; /* little endian */
|
||||
|
||||
m66592_bset(m66592, M66592_INTL, M66592_INTENB1);
|
||||
m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */
|
||||
m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
|
||||
m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
|
||||
m66592_bset(m66592, M66592_USBE, M66592_SYSCFG);
|
||||
|
||||
m66592_write(m66592, 0, M66592_CFBCFG);
|
||||
m66592_write(m66592, 0, M66592_D0FBCFG);
|
||||
m66592_bset(m66592, endian, M66592_CFBCFG);
|
||||
m66592_bset(m66592, endian, M66592_D0FBCFG);
|
||||
/* This is a workaound for SH7722 2nd cut */
|
||||
m66592_bset(m66592, 0x8000, M66592_DVSTCTR);
|
||||
m66592_bset(m66592, 0x1000, M66592_TESTMODE);
|
||||
m66592_bclr(m66592, 0x8000, M66592_DVSTCTR);
|
||||
|
||||
m66592_bset(m66592, M66592_INTL, M66592_INTENB1);
|
||||
|
||||
m66592_write(m66592, 0, M66592_CFBCFG);
|
||||
m66592_write(m66592, 0, M66592_D0FBCFG);
|
||||
m66592_bset(m66592, endian, M66592_CFBCFG);
|
||||
m66592_bset(m66592, endian, M66592_D0FBCFG);
|
||||
} else {
|
||||
unsigned int clock, vif, irq_sense;
|
||||
|
||||
if (m66592->pdata->endian)
|
||||
endian = M66592_BIGEND; /* big endian */
|
||||
else
|
||||
endian = 0; /* little endian */
|
||||
|
||||
if (m66592->pdata->vif)
|
||||
vif = M66592_LDRV; /* 3.3v */
|
||||
else
|
||||
vif = 0; /* 1.5v */
|
||||
|
||||
switch (m66592->pdata->xtal) {
|
||||
case M66592_PLATDATA_XTAL_12MHZ:
|
||||
clock = M66592_XTAL12;
|
||||
break;
|
||||
case M66592_PLATDATA_XTAL_24MHZ:
|
||||
clock = M66592_XTAL24;
|
||||
break;
|
||||
case M66592_PLATDATA_XTAL_48MHZ:
|
||||
clock = M66592_XTAL48;
|
||||
break;
|
||||
default:
|
||||
pr_warning("m66592-udc: xtal configuration error\n");
|
||||
clock = 0;
|
||||
}
|
||||
|
||||
switch (m66592->irq_trigger) {
|
||||
case IRQF_TRIGGER_LOW:
|
||||
irq_sense = M66592_INTL;
|
||||
break;
|
||||
case IRQF_TRIGGER_FALLING:
|
||||
irq_sense = 0;
|
||||
break;
|
||||
default:
|
||||
pr_warning("m66592-udc: irq trigger config error\n");
|
||||
irq_sense = 0;
|
||||
}
|
||||
|
||||
m66592_bset(m66592,
|
||||
(vif & M66592_LDRV) | (endian & M66592_BIGEND),
|
||||
M66592_PINCFG);
|
||||
m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */
|
||||
m66592_mdfy(m66592, clock & M66592_XTAL, M66592_XTAL,
|
||||
M66592_SYSCFG);
|
||||
m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
|
||||
m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
|
||||
m66592_bset(m66592, M66592_USBE, M66592_SYSCFG);
|
||||
|
||||
m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG);
|
||||
|
||||
msleep(3);
|
||||
|
||||
m66592_bset(m66592, M66592_RCKE | M66592_PLLC, M66592_SYSCFG);
|
||||
|
||||
msleep(1);
|
||||
|
||||
m66592_bset(m66592, M66592_SCKE, M66592_SYSCFG);
|
||||
|
||||
m66592_bset(m66592, irq_sense & M66592_INTL, M66592_INTENB1);
|
||||
m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR,
|
||||
M66592_DMA0CFG);
|
||||
}
|
||||
}
|
||||
#else /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
|
||||
static void init_controller(struct m66592 *m66592)
|
||||
{
|
||||
m66592_bset(m66592, (vif & M66592_LDRV) | (endian & M66592_BIGEND),
|
||||
M66592_PINCFG);
|
||||
m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */
|
||||
m66592_mdfy(m66592, clock & M66592_XTAL, M66592_XTAL, M66592_SYSCFG);
|
||||
|
||||
m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
|
||||
m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
|
||||
m66592_bset(m66592, M66592_USBE, M66592_SYSCFG);
|
||||
|
||||
m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG);
|
||||
|
||||
msleep(3);
|
||||
|
||||
m66592_bset(m66592, M66592_RCKE | M66592_PLLC, M66592_SYSCFG);
|
||||
|
||||
msleep(1);
|
||||
|
||||
m66592_bset(m66592, M66592_SCKE, M66592_SYSCFG);
|
||||
|
||||
m66592_bset(m66592, irq_sense & M66592_INTL, M66592_INTENB1);
|
||||
m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR,
|
||||
M66592_DMA0CFG);
|
||||
}
|
||||
#endif /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
|
||||
|
||||
static void disable_controller(struct m66592 *m66592)
|
||||
{
|
||||
#if !defined(CONFIG_SUPERH_BUILT_IN_M66592)
|
||||
m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG);
|
||||
udelay(1);
|
||||
m66592_bclr(m66592, M66592_PLLC, M66592_SYSCFG);
|
||||
udelay(1);
|
||||
m66592_bclr(m66592, M66592_RCKE, M66592_SYSCFG);
|
||||
udelay(1);
|
||||
m66592_bclr(m66592, M66592_XCKE, M66592_SYSCFG);
|
||||
#endif
|
||||
if (!m66592->pdata->on_chip) {
|
||||
m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG);
|
||||
udelay(1);
|
||||
m66592_bclr(m66592, M66592_PLLC, M66592_SYSCFG);
|
||||
udelay(1);
|
||||
m66592_bclr(m66592, M66592_RCKE, M66592_SYSCFG);
|
||||
udelay(1);
|
||||
m66592_bclr(m66592, M66592_XCKE, M66592_SYSCFG);
|
||||
}
|
||||
}
|
||||
|
||||
static void m66592_start_xclock(struct m66592 *m66592)
|
||||
{
|
||||
#if !defined(CONFIG_SUPERH_BUILT_IN_M66592)
|
||||
u16 tmp;
|
||||
|
||||
tmp = m66592_read(m66592, M66592_SYSCFG);
|
||||
if (!(tmp & M66592_XCKE))
|
||||
m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG);
|
||||
#endif
|
||||
if (!m66592->pdata->on_chip) {
|
||||
tmp = m66592_read(m66592, M66592_SYSCFG);
|
||||
if (!(tmp & M66592_XCKE))
|
||||
m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
|
@ -1177,8 +1197,7 @@ static irqreturn_t m66592_irq(int irq, void *_m66592)
|
|||
intsts0 = m66592_read(m66592, M66592_INTSTS0);
|
||||
intenb0 = m66592_read(m66592, M66592_INTENB0);
|
||||
|
||||
#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
|
||||
if (!intsts0 && !intenb0) {
|
||||
if (m66592->pdata->on_chip && !intsts0 && !intenb0) {
|
||||
/*
|
||||
* When USB clock stops, it cannot read register. Even if a
|
||||
* clock stops, the interrupt occurs. So this driver turn on
|
||||
|
|
@ -1188,7 +1207,6 @@ static irqreturn_t m66592_irq(int irq, void *_m66592)
|
|||
intsts0 = m66592_read(m66592, M66592_INTSTS0);
|
||||
intenb0 = m66592_read(m66592, M66592_INTENB0);
|
||||
}
|
||||
#endif
|
||||
|
||||
savepipe = m66592_read(m66592, M66592_CFIFOSEL);
|
||||
|
||||
|
|
@ -1534,9 +1552,11 @@ static int __exit m66592_remove(struct platform_device *pdev)
|
|||
iounmap(m66592->reg);
|
||||
free_irq(platform_get_irq(pdev, 0), m66592);
|
||||
m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req);
|
||||
#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
|
||||
clk_disable(m66592->clk);
|
||||
clk_put(m66592->clk);
|
||||
#ifdef CONFIG_HAVE_CLK
|
||||
if (m66592->pdata->on_chip) {
|
||||
clk_disable(m66592->clk);
|
||||
clk_put(m66592->clk);
|
||||
}
|
||||
#endif
|
||||
kfree(m66592);
|
||||
return 0;
|
||||
|
|
@ -1548,11 +1568,10 @@ static void nop_completion(struct usb_ep *ep, struct usb_request *r)
|
|||
|
||||
static int __init m66592_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
int irq;
|
||||
struct resource *res, *ires;
|
||||
void __iomem *reg = NULL;
|
||||
struct m66592 *m66592 = NULL;
|
||||
#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
|
||||
#ifdef CONFIG_HAVE_CLK
|
||||
char clk_name[8];
|
||||
#endif
|
||||
int ret = 0;
|
||||
|
|
@ -1565,10 +1584,11 @@ static int __init m66592_probe(struct platform_device *pdev)
|
|||
goto clean_up;
|
||||
}
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
if (!ires) {
|
||||
ret = -ENODEV;
|
||||
pr_err("platform_get_irq error.\n");
|
||||
dev_err(&pdev->dev,
|
||||
"platform_get_resource IORESOURCE_IRQ error.\n");
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
|
|
@ -1579,6 +1599,12 @@ static int __init m66592_probe(struct platform_device *pdev)
|
|||
goto clean_up;
|
||||
}
|
||||
|
||||
if (pdev->dev.platform_data == NULL) {
|
||||
dev_err(&pdev->dev, "no platform data\n");
|
||||
ret = -ENODEV;
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
/* initialize ucd */
|
||||
m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL);
|
||||
if (m66592 == NULL) {
|
||||
|
|
@ -1586,6 +1612,9 @@ static int __init m66592_probe(struct platform_device *pdev)
|
|||
goto clean_up;
|
||||
}
|
||||
|
||||
m66592->pdata = pdev->dev.platform_data;
|
||||
m66592->irq_trigger = ires->flags & IRQF_TRIGGER_MASK;
|
||||
|
||||
spin_lock_init(&m66592->lock);
|
||||
dev_set_drvdata(&pdev->dev, m66592);
|
||||
|
||||
|
|
@ -1603,24 +1632,25 @@ static int __init m66592_probe(struct platform_device *pdev)
|
|||
m66592->timer.data = (unsigned long)m66592;
|
||||
m66592->reg = reg;
|
||||
|
||||
m66592->bi_bufnum = M66592_BASE_BUFNUM;
|
||||
|
||||
ret = request_irq(irq, m66592_irq, IRQF_DISABLED | IRQF_SHARED,
|
||||
ret = request_irq(ires->start, m66592_irq, IRQF_DISABLED | IRQF_SHARED,
|
||||
udc_name, m66592);
|
||||
if (ret < 0) {
|
||||
pr_err("request_irq error (%d)\n", ret);
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
|
||||
snprintf(clk_name, sizeof(clk_name), "usbf%d", pdev->id);
|
||||
m66592->clk = clk_get(&pdev->dev, clk_name);
|
||||
if (IS_ERR(m66592->clk)) {
|
||||
dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
|
||||
ret = PTR_ERR(m66592->clk);
|
||||
goto clean_up2;
|
||||
#ifdef CONFIG_HAVE_CLK
|
||||
if (m66592->pdata->on_chip) {
|
||||
snprintf(clk_name, sizeof(clk_name), "usbf%d", pdev->id);
|
||||
m66592->clk = clk_get(&pdev->dev, clk_name);
|
||||
if (IS_ERR(m66592->clk)) {
|
||||
dev_err(&pdev->dev, "cannot get clock \"%s\"\n",
|
||||
clk_name);
|
||||
ret = PTR_ERR(m66592->clk);
|
||||
goto clean_up2;
|
||||
}
|
||||
clk_enable(m66592->clk);
|
||||
}
|
||||
clk_enable(m66592->clk);
|
||||
#endif
|
||||
INIT_LIST_HEAD(&m66592->gadget.ep_list);
|
||||
m66592->gadget.ep0 = &m66592->ep[0].ep;
|
||||
|
|
@ -1662,12 +1692,14 @@ static int __init m66592_probe(struct platform_device *pdev)
|
|||
return 0;
|
||||
|
||||
clean_up3:
|
||||
#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
|
||||
clk_disable(m66592->clk);
|
||||
clk_put(m66592->clk);
|
||||
#ifdef CONFIG_HAVE_CLK
|
||||
if (m66592->pdata->on_chip) {
|
||||
clk_disable(m66592->clk);
|
||||
clk_put(m66592->clk);
|
||||
}
|
||||
clean_up2:
|
||||
#endif
|
||||
free_irq(irq, m66592);
|
||||
free_irq(ires->start, m66592);
|
||||
clean_up:
|
||||
if (m66592) {
|
||||
if (m66592->ep0_req)
|
||||
|
|
|
|||
|
|
@ -23,10 +23,12 @@
|
|||
#ifndef __M66592_UDC_H__
|
||||
#define __M66592_UDC_H__
|
||||
|
||||
#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
|
||||
#ifdef CONFIG_HAVE_CLK
|
||||
#include <linux/clk.h>
|
||||
#endif
|
||||
|
||||
#include <linux/usb/m66592.h>
|
||||
|
||||
#define M66592_SYSCFG 0x00
|
||||
#define M66592_XTAL 0xC000 /* b15-14: Crystal selection */
|
||||
#define M66592_XTAL48 0x8000 /* 48MHz */
|
||||
|
|
@ -76,11 +78,11 @@
|
|||
#define M66592_P_TST_J 0x0001 /* PERI TEST J */
|
||||
#define M66592_P_TST_NORMAL 0x0000 /* PERI Normal Mode */
|
||||
|
||||
#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
|
||||
/* built-in registers */
|
||||
#define M66592_CFBCFG 0x0A
|
||||
#define M66592_D0FBCFG 0x0C
|
||||
#define M66592_LITTLE 0x0100 /* b8: Little endian mode */
|
||||
#else
|
||||
/* external chip case */
|
||||
#define M66592_PINCFG 0x0A
|
||||
#define M66592_LDRV 0x8000 /* b15: Drive Current Adjust */
|
||||
#define M66592_BIGEND 0x0100 /* b8: Big endian mode */
|
||||
|
|
@ -100,8 +102,8 @@
|
|||
#define M66592_PKTM 0x0020 /* b5: Packet mode */
|
||||
#define M66592_DENDE 0x0010 /* b4: Dend enable */
|
||||
#define M66592_OBUS 0x0004 /* b2: OUTbus mode */
|
||||
#endif /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
|
||||
|
||||
/* common case */
|
||||
#define M66592_CFIFO 0x10
|
||||
#define M66592_D0FIFO 0x14
|
||||
#define M66592_D1FIFO 0x18
|
||||
|
|
@ -113,13 +115,9 @@
|
|||
#define M66592_REW 0x4000 /* b14: Buffer rewind */
|
||||
#define M66592_DCLRM 0x2000 /* b13: DMA buffer clear mode */
|
||||
#define M66592_DREQE 0x1000 /* b12: DREQ output enable */
|
||||
#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
|
||||
#define M66592_MBW 0x0800 /* b11: Maximum bit width for FIFO */
|
||||
#else
|
||||
#define M66592_MBW 0x0400 /* b10: Maximum bit width for FIFO */
|
||||
#define M66592_MBW_8 0x0000 /* 8bit */
|
||||
#define M66592_MBW_16 0x0400 /* 16bit */
|
||||
#endif /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
|
||||
#define M66592_MBW_8 0x0000 /* 8bit */
|
||||
#define M66592_MBW_16 0x0400 /* 16bit */
|
||||
#define M66592_MBW_32 0x0800 /* 32bit */
|
||||
#define M66592_TRENB 0x0200 /* b9: Transaction counter enable */
|
||||
#define M66592_TRCLR 0x0100 /* b8: Transaction counter clear */
|
||||
#define M66592_DEZPM 0x0080 /* b7: Zero-length packet mode */
|
||||
|
|
@ -480,9 +478,11 @@ struct m66592_ep {
|
|||
struct m66592 {
|
||||
spinlock_t lock;
|
||||
void __iomem *reg;
|
||||
#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
|
||||
#ifdef CONFIG_HAVE_CLK
|
||||
struct clk *clk;
|
||||
#endif
|
||||
struct m66592_platdata *pdata;
|
||||
unsigned long irq_trigger;
|
||||
|
||||
struct usb_gadget gadget;
|
||||
struct usb_gadget_driver *driver;
|
||||
|
|
@ -506,7 +506,6 @@ struct m66592 {
|
|||
int interrupt;
|
||||
int isochronous;
|
||||
int num_dma;
|
||||
int bi_bufnum; /* bulk and isochronous's bufnum */
|
||||
};
|
||||
|
||||
#define gadget_to_m66592(_gadget) container_of(_gadget, struct m66592, gadget)
|
||||
|
|
@ -547,13 +546,13 @@ static inline void m66592_read_fifo(struct m66592 *m66592,
|
|||
{
|
||||
unsigned long fifoaddr = (unsigned long)m66592->reg + offset;
|
||||
|
||||
#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
|
||||
len = (len + 3) / 4;
|
||||
insl(fifoaddr, buf, len);
|
||||
#else
|
||||
len = (len + 1) / 2;
|
||||
insw(fifoaddr, buf, len);
|
||||
#endif
|
||||
if (m66592->pdata->on_chip) {
|
||||
len = (len + 3) / 4;
|
||||
insl(fifoaddr, buf, len);
|
||||
} else {
|
||||
len = (len + 1) / 2;
|
||||
insw(fifoaddr, buf, len);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void m66592_write(struct m66592 *m66592, u16 val,
|
||||
|
|
@ -567,33 +566,34 @@ static inline void m66592_write_fifo(struct m66592 *m66592,
|
|||
void *buf, unsigned long len)
|
||||
{
|
||||
unsigned long fifoaddr = (unsigned long)m66592->reg + offset;
|
||||
#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
|
||||
unsigned long count;
|
||||
unsigned char *pb;
|
||||
int i;
|
||||
|
||||
count = len / 4;
|
||||
outsl(fifoaddr, buf, count);
|
||||
if (m66592->pdata->on_chip) {
|
||||
unsigned long count;
|
||||
unsigned char *pb;
|
||||
int i;
|
||||
|
||||
if (len & 0x00000003) {
|
||||
pb = buf + count * 4;
|
||||
for (i = 0; i < (len & 0x00000003); i++) {
|
||||
if (m66592_read(m66592, M66592_CFBCFG)) /* little */
|
||||
outb(pb[i], fifoaddr + (3 - i));
|
||||
else
|
||||
outb(pb[i], fifoaddr + i);
|
||||
count = len / 4;
|
||||
outsl(fifoaddr, buf, count);
|
||||
|
||||
if (len & 0x00000003) {
|
||||
pb = buf + count * 4;
|
||||
for (i = 0; i < (len & 0x00000003); i++) {
|
||||
if (m66592_read(m66592, M66592_CFBCFG)) /* le */
|
||||
outb(pb[i], fifoaddr + (3 - i));
|
||||
else
|
||||
outb(pb[i], fifoaddr + i);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unsigned long odd = len & 0x0001;
|
||||
|
||||
len = len / 2;
|
||||
outsw(fifoaddr, buf, len);
|
||||
if (odd) {
|
||||
unsigned char *p = buf + len*2;
|
||||
outb(*p, fifoaddr);
|
||||
}
|
||||
}
|
||||
#else
|
||||
unsigned long odd = len & 0x0001;
|
||||
|
||||
len = len / 2;
|
||||
outsw(fifoaddr, buf, len);
|
||||
if (odd) {
|
||||
unsigned char *p = buf + len*2;
|
||||
outb(*p, fifoaddr);
|
||||
}
|
||||
#endif /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
|
||||
}
|
||||
|
||||
static inline void m66592_mdfy(struct m66592 *m66592, u16 val, u16 pat,
|
||||
|
|
|
|||
1689
drivers/usb/gadget/r8a66597-udc.c
Normal file
1689
drivers/usb/gadget/r8a66597-udc.c
Normal file
File diff suppressed because it is too large
Load diff
256
drivers/usb/gadget/r8a66597-udc.h
Normal file
256
drivers/usb/gadget/r8a66597-udc.h
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
/*
|
||||
* R8A66597 UDC
|
||||
*
|
||||
* Copyright (C) 2007-2009 Renesas Solutions Corp.
|
||||
*
|
||||
* Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __R8A66597_H__
|
||||
#define __R8A66597_H__
|
||||
|
||||
#ifdef CONFIG_HAVE_CLK
|
||||
#include <linux/clk.h>
|
||||
#endif
|
||||
|
||||
#include <linux/usb/r8a66597.h>
|
||||
|
||||
#define R8A66597_MAX_SAMPLING 10
|
||||
|
||||
#define R8A66597_MAX_NUM_PIPE 8
|
||||
#define R8A66597_MAX_NUM_BULK 3
|
||||
#define R8A66597_MAX_NUM_ISOC 2
|
||||
#define R8A66597_MAX_NUM_INT 2
|
||||
|
||||
#define R8A66597_BASE_PIPENUM_BULK 3
|
||||
#define R8A66597_BASE_PIPENUM_ISOC 1
|
||||
#define R8A66597_BASE_PIPENUM_INT 6
|
||||
|
||||
#define R8A66597_BASE_BUFNUM 6
|
||||
#define R8A66597_MAX_BUFNUM 0x4F
|
||||
|
||||
#define is_bulk_pipe(pipenum) \
|
||||
((pipenum >= R8A66597_BASE_PIPENUM_BULK) && \
|
||||
(pipenum < (R8A66597_BASE_PIPENUM_BULK + R8A66597_MAX_NUM_BULK)))
|
||||
#define is_interrupt_pipe(pipenum) \
|
||||
((pipenum >= R8A66597_BASE_PIPENUM_INT) && \
|
||||
(pipenum < (R8A66597_BASE_PIPENUM_INT + R8A66597_MAX_NUM_INT)))
|
||||
#define is_isoc_pipe(pipenum) \
|
||||
((pipenum >= R8A66597_BASE_PIPENUM_ISOC) && \
|
||||
(pipenum < (R8A66597_BASE_PIPENUM_ISOC + R8A66597_MAX_NUM_ISOC)))
|
||||
|
||||
struct r8a66597_pipe_info {
|
||||
u16 pipe;
|
||||
u16 epnum;
|
||||
u16 maxpacket;
|
||||
u16 type;
|
||||
u16 interval;
|
||||
u16 dir_in;
|
||||
};
|
||||
|
||||
struct r8a66597_request {
|
||||
struct usb_request req;
|
||||
struct list_head queue;
|
||||
};
|
||||
|
||||
struct r8a66597_ep {
|
||||
struct usb_ep ep;
|
||||
struct r8a66597 *r8a66597;
|
||||
|
||||
struct list_head queue;
|
||||
unsigned busy:1;
|
||||
unsigned wedge:1;
|
||||
unsigned internal_ccpl:1; /* use only control */
|
||||
|
||||
/* this member can able to after r8a66597_enable */
|
||||
unsigned use_dma:1;
|
||||
u16 pipenum;
|
||||
u16 type;
|
||||
const struct usb_endpoint_descriptor *desc;
|
||||
/* register address */
|
||||
unsigned char fifoaddr;
|
||||
unsigned char fifosel;
|
||||
unsigned char fifoctr;
|
||||
unsigned char fifotrn;
|
||||
unsigned char pipectr;
|
||||
};
|
||||
|
||||
struct r8a66597 {
|
||||
spinlock_t lock;
|
||||
unsigned long reg;
|
||||
|
||||
#ifdef CONFIG_HAVE_CLK
|
||||
struct clk *clk;
|
||||
#endif
|
||||
struct r8a66597_platdata *pdata;
|
||||
|
||||
struct usb_gadget gadget;
|
||||
struct usb_gadget_driver *driver;
|
||||
|
||||
struct r8a66597_ep ep[R8A66597_MAX_NUM_PIPE];
|
||||
struct r8a66597_ep *pipenum2ep[R8A66597_MAX_NUM_PIPE];
|
||||
struct r8a66597_ep *epaddr2ep[16];
|
||||
|
||||
struct timer_list timer;
|
||||
struct usb_request *ep0_req; /* for internal request */
|
||||
u16 ep0_data; /* for internal request */
|
||||
u16 old_vbus;
|
||||
u16 scount;
|
||||
u16 old_dvsq;
|
||||
|
||||
/* pipe config */
|
||||
unsigned char bulk;
|
||||
unsigned char interrupt;
|
||||
unsigned char isochronous;
|
||||
unsigned char num_dma;
|
||||
|
||||
unsigned irq_sense_low:1;
|
||||
};
|
||||
|
||||
#define gadget_to_r8a66597(_gadget) \
|
||||
container_of(_gadget, struct r8a66597, gadget)
|
||||
#define r8a66597_to_gadget(r8a66597) (&r8a66597->gadget)
|
||||
|
||||
static inline u16 r8a66597_read(struct r8a66597 *r8a66597, unsigned long offset)
|
||||
{
|
||||
return inw(r8a66597->reg + offset);
|
||||
}
|
||||
|
||||
static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597,
|
||||
unsigned long offset, u16 *buf,
|
||||
int len)
|
||||
{
|
||||
if (r8a66597->pdata->on_chip) {
|
||||
unsigned long fifoaddr = r8a66597->reg + offset;
|
||||
unsigned long count;
|
||||
union {
|
||||
unsigned long dword;
|
||||
unsigned char byte[4];
|
||||
} data;
|
||||
unsigned char *pb;
|
||||
int i;
|
||||
|
||||
count = len / 4;
|
||||
insl(fifoaddr, buf, count);
|
||||
|
||||
if (len & 0x00000003) {
|
||||
data.dword = inl(fifoaddr);
|
||||
pb = (unsigned char *)buf + count * 4;
|
||||
for (i = 0; i < (len & 0x00000003); i++)
|
||||
pb[i] = data.byte[i];
|
||||
}
|
||||
} else {
|
||||
len = (len + 1) / 2;
|
||||
insw(r8a66597->reg + offset, buf, len);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val,
|
||||
unsigned long offset)
|
||||
{
|
||||
outw(val, r8a66597->reg + offset);
|
||||
}
|
||||
|
||||
static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597,
|
||||
unsigned long offset, u16 *buf,
|
||||
int len)
|
||||
{
|
||||
unsigned long fifoaddr = r8a66597->reg + offset;
|
||||
|
||||
if (r8a66597->pdata->on_chip) {
|
||||
unsigned long count;
|
||||
unsigned char *pb;
|
||||
int i;
|
||||
|
||||
count = len / 4;
|
||||
outsl(fifoaddr, buf, count);
|
||||
|
||||
if (len & 0x00000003) {
|
||||
pb = (unsigned char *)buf + count * 4;
|
||||
for (i = 0; i < (len & 0x00000003); i++) {
|
||||
if (r8a66597_read(r8a66597, CFIFOSEL) & BIGEND)
|
||||
outb(pb[i], fifoaddr + i);
|
||||
else
|
||||
outb(pb[i], fifoaddr + 3 - i);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int odd = len & 0x0001;
|
||||
|
||||
len = len / 2;
|
||||
outsw(fifoaddr, buf, len);
|
||||
if (unlikely(odd)) {
|
||||
buf = &buf[len];
|
||||
outb((unsigned char)*buf, fifoaddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void r8a66597_mdfy(struct r8a66597 *r8a66597,
|
||||
u16 val, u16 pat, unsigned long offset)
|
||||
{
|
||||
u16 tmp;
|
||||
tmp = r8a66597_read(r8a66597, offset);
|
||||
tmp = tmp & (~pat);
|
||||
tmp = tmp | val;
|
||||
r8a66597_write(r8a66597, tmp, offset);
|
||||
}
|
||||
|
||||
static inline u16 get_xtal_from_pdata(struct r8a66597_platdata *pdata)
|
||||
{
|
||||
u16 clock = 0;
|
||||
|
||||
switch (pdata->xtal) {
|
||||
case R8A66597_PLATDATA_XTAL_12MHZ:
|
||||
clock = XTAL12;
|
||||
break;
|
||||
case R8A66597_PLATDATA_XTAL_24MHZ:
|
||||
clock = XTAL24;
|
||||
break;
|
||||
case R8A66597_PLATDATA_XTAL_48MHZ:
|
||||
clock = XTAL48;
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR "r8a66597: platdata clock is wrong.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return clock;
|
||||
}
|
||||
|
||||
#define r8a66597_bclr(r8a66597, val, offset) \
|
||||
r8a66597_mdfy(r8a66597, 0, val, offset)
|
||||
#define r8a66597_bset(r8a66597, val, offset) \
|
||||
r8a66597_mdfy(r8a66597, val, 0, offset)
|
||||
|
||||
#define get_pipectr_addr(pipenum) (PIPE1CTR + (pipenum - 1) * 2)
|
||||
|
||||
#define enable_irq_ready(r8a66597, pipenum) \
|
||||
enable_pipe_irq(r8a66597, pipenum, BRDYENB)
|
||||
#define disable_irq_ready(r8a66597, pipenum) \
|
||||
disable_pipe_irq(r8a66597, pipenum, BRDYENB)
|
||||
#define enable_irq_empty(r8a66597, pipenum) \
|
||||
enable_pipe_irq(r8a66597, pipenum, BEMPENB)
|
||||
#define disable_irq_empty(r8a66597, pipenum) \
|
||||
disable_pipe_irq(r8a66597, pipenum, BEMPENB)
|
||||
#define enable_irq_nrdy(r8a66597, pipenum) \
|
||||
enable_pipe_irq(r8a66597, pipenum, NRDYENB)
|
||||
#define disable_irq_nrdy(r8a66597, pipenum) \
|
||||
disable_pipe_irq(r8a66597, pipenum, NRDYENB)
|
||||
|
||||
#endif /* __R8A66597_H__ */
|
||||
|
||||
|
|
@ -336,13 +336,6 @@ config USB_R8A66597_HCD
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called r8a66597-hcd.
|
||||
|
||||
config SUPERH_ON_CHIP_R8A66597
|
||||
boolean "Enable SuperH on-chip R8A66597 USB"
|
||||
depends on USB_R8A66597_HCD && (CPU_SUBTYPE_SH7366 || CPU_SUBTYPE_SH7723 || CPU_SUBTYPE_SH7724)
|
||||
help
|
||||
This driver enables support for the on-chip R8A66597 in the
|
||||
SH7366, SH7723 and SH7724 processors.
|
||||
|
||||
config USB_WHCI_HCD
|
||||
tristate "Wireless USB Host Controller Interface (WHCI) driver (EXPERIMENTAL)"
|
||||
depends on EXPERIMENTAL
|
||||
|
|
|
|||
|
|
@ -91,43 +91,43 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597)
|
|||
u16 tmp;
|
||||
int i = 0;
|
||||
|
||||
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
|
||||
#if defined(CONFIG_HAVE_CLK)
|
||||
clk_enable(r8a66597->clk);
|
||||
if (r8a66597->pdata->on_chip) {
|
||||
#ifdef CONFIG_HAVE_CLK
|
||||
clk_enable(r8a66597->clk);
|
||||
#endif
|
||||
do {
|
||||
r8a66597_write(r8a66597, SCKE, SYSCFG0);
|
||||
tmp = r8a66597_read(r8a66597, SYSCFG0);
|
||||
if (i++ > 1000) {
|
||||
printk(KERN_ERR "r8a66597: register access fail.\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
} while ((tmp & SCKE) != SCKE);
|
||||
r8a66597_write(r8a66597, 0x04, 0x02);
|
||||
#else
|
||||
do {
|
||||
r8a66597_write(r8a66597, USBE, SYSCFG0);
|
||||
tmp = r8a66597_read(r8a66597, SYSCFG0);
|
||||
if (i++ > 1000) {
|
||||
printk(KERN_ERR "r8a66597: register access fail.\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
} while ((tmp & USBE) != USBE);
|
||||
r8a66597_bclr(r8a66597, USBE, SYSCFG0);
|
||||
r8a66597_mdfy(r8a66597, get_xtal_from_pdata(r8a66597->pdata), XTAL,
|
||||
SYSCFG0);
|
||||
do {
|
||||
r8a66597_write(r8a66597, SCKE, SYSCFG0);
|
||||
tmp = r8a66597_read(r8a66597, SYSCFG0);
|
||||
if (i++ > 1000) {
|
||||
printk(KERN_ERR "r8a66597: reg access fail.\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
} while ((tmp & SCKE) != SCKE);
|
||||
r8a66597_write(r8a66597, 0x04, 0x02);
|
||||
} else {
|
||||
do {
|
||||
r8a66597_write(r8a66597, USBE, SYSCFG0);
|
||||
tmp = r8a66597_read(r8a66597, SYSCFG0);
|
||||
if (i++ > 1000) {
|
||||
printk(KERN_ERR "r8a66597: reg access fail.\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
} while ((tmp & USBE) != USBE);
|
||||
r8a66597_bclr(r8a66597, USBE, SYSCFG0);
|
||||
r8a66597_mdfy(r8a66597, get_xtal_from_pdata(r8a66597->pdata),
|
||||
XTAL, SYSCFG0);
|
||||
|
||||
i = 0;
|
||||
r8a66597_bset(r8a66597, XCKE, SYSCFG0);
|
||||
do {
|
||||
msleep(1);
|
||||
tmp = r8a66597_read(r8a66597, SYSCFG0);
|
||||
if (i++ > 500) {
|
||||
printk(KERN_ERR "r8a66597: register access fail.\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
} while ((tmp & SCKE) != SCKE);
|
||||
#endif /* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */
|
||||
i = 0;
|
||||
r8a66597_bset(r8a66597, XCKE, SYSCFG0);
|
||||
do {
|
||||
msleep(1);
|
||||
tmp = r8a66597_read(r8a66597, SYSCFG0);
|
||||
if (i++ > 500) {
|
||||
printk(KERN_ERR "r8a66597: reg access fail.\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
} while ((tmp & SCKE) != SCKE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -136,15 +136,16 @@ static void r8a66597_clock_disable(struct r8a66597 *r8a66597)
|
|||
{
|
||||
r8a66597_bclr(r8a66597, SCKE, SYSCFG0);
|
||||
udelay(1);
|
||||
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
|
||||
#if defined(CONFIG_HAVE_CLK)
|
||||
clk_disable(r8a66597->clk);
|
||||
#endif
|
||||
#else
|
||||
r8a66597_bclr(r8a66597, PLLC, SYSCFG0);
|
||||
r8a66597_bclr(r8a66597, XCKE, SYSCFG0);
|
||||
r8a66597_bclr(r8a66597, USBE, SYSCFG0);
|
||||
|
||||
if (r8a66597->pdata->on_chip) {
|
||||
#ifdef CONFIG_HAVE_CLK
|
||||
clk_disable(r8a66597->clk);
|
||||
#endif
|
||||
} else {
|
||||
r8a66597_bclr(r8a66597, PLLC, SYSCFG0);
|
||||
r8a66597_bclr(r8a66597, XCKE, SYSCFG0);
|
||||
r8a66597_bclr(r8a66597, USBE, SYSCFG0);
|
||||
}
|
||||
}
|
||||
|
||||
static void r8a66597_enable_port(struct r8a66597 *r8a66597, int port)
|
||||
|
|
@ -205,7 +206,7 @@ static int enable_controller(struct r8a66597 *r8a66597)
|
|||
|
||||
r8a66597_bset(r8a66597, SIGNE | SACKE, INTENB1);
|
||||
|
||||
for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
|
||||
for (port = 0; port < r8a66597->max_root_hub; port++)
|
||||
r8a66597_enable_port(r8a66597, port);
|
||||
|
||||
return 0;
|
||||
|
|
@ -218,7 +219,7 @@ static void disable_controller(struct r8a66597 *r8a66597)
|
|||
r8a66597_write(r8a66597, 0, INTENB0);
|
||||
r8a66597_write(r8a66597, 0, INTSTS0);
|
||||
|
||||
for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
|
||||
for (port = 0; port < r8a66597->max_root_hub; port++)
|
||||
r8a66597_disable_port(r8a66597, port);
|
||||
|
||||
r8a66597_clock_disable(r8a66597);
|
||||
|
|
@ -249,11 +250,12 @@ static int is_hub_limit(char *devpath)
|
|||
return ((strlen(devpath) >= 4) ? 1 : 0);
|
||||
}
|
||||
|
||||
static void get_port_number(char *devpath, u16 *root_port, u16 *hub_port)
|
||||
static void get_port_number(struct r8a66597 *r8a66597,
|
||||
char *devpath, u16 *root_port, u16 *hub_port)
|
||||
{
|
||||
if (root_port) {
|
||||
*root_port = (devpath[0] & 0x0F) - 1;
|
||||
if (*root_port >= R8A66597_MAX_ROOT_HUB)
|
||||
if (*root_port >= r8a66597->max_root_hub)
|
||||
printk(KERN_ERR "r8a66597: Illegal root port number.\n");
|
||||
}
|
||||
if (hub_port)
|
||||
|
|
@ -355,7 +357,8 @@ static int make_r8a66597_device(struct r8a66597 *r8a66597,
|
|||
INIT_LIST_HEAD(&dev->device_list);
|
||||
list_add_tail(&dev->device_list, &r8a66597->child_device);
|
||||
|
||||
get_port_number(urb->dev->devpath, &dev->root_port, &dev->hub_port);
|
||||
get_port_number(r8a66597, urb->dev->devpath,
|
||||
&dev->root_port, &dev->hub_port);
|
||||
if (!is_child_device(urb->dev->devpath))
|
||||
r8a66597->root_hub[dev->root_port].dev = dev;
|
||||
|
||||
|
|
@ -420,7 +423,7 @@ static void free_usb_address(struct r8a66597 *r8a66597,
|
|||
list_del(&dev->device_list);
|
||||
kfree(dev);
|
||||
|
||||
for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
|
||||
for (port = 0; port < r8a66597->max_root_hub; port++) {
|
||||
if (r8a66597->root_hub[port].dev == dev) {
|
||||
r8a66597->root_hub[port].dev = NULL;
|
||||
break;
|
||||
|
|
@ -495,10 +498,20 @@ static void r8a66597_pipe_toggle(struct r8a66597 *r8a66597,
|
|||
r8a66597_bset(r8a66597, SQCLR, pipe->pipectr);
|
||||
}
|
||||
|
||||
static inline unsigned short mbw_value(struct r8a66597 *r8a66597)
|
||||
{
|
||||
if (r8a66597->pdata->on_chip)
|
||||
return MBW_32;
|
||||
else
|
||||
return MBW_16;
|
||||
}
|
||||
|
||||
/* this function must be called with interrupt disabled */
|
||||
static inline void cfifo_change(struct r8a66597 *r8a66597, u16 pipenum)
|
||||
{
|
||||
r8a66597_mdfy(r8a66597, MBW | pipenum, MBW | CURPIPE, CFIFOSEL);
|
||||
unsigned short mbw = mbw_value(r8a66597);
|
||||
|
||||
r8a66597_mdfy(r8a66597, mbw | pipenum, mbw | CURPIPE, CFIFOSEL);
|
||||
r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, pipenum);
|
||||
}
|
||||
|
||||
|
|
@ -506,11 +519,13 @@ static inline void cfifo_change(struct r8a66597 *r8a66597, u16 pipenum)
|
|||
static inline void fifo_change_from_pipe(struct r8a66597 *r8a66597,
|
||||
struct r8a66597_pipe *pipe)
|
||||
{
|
||||
cfifo_change(r8a66597, 0);
|
||||
r8a66597_mdfy(r8a66597, MBW | 0, MBW | CURPIPE, D0FIFOSEL);
|
||||
r8a66597_mdfy(r8a66597, MBW | 0, MBW | CURPIPE, D1FIFOSEL);
|
||||
unsigned short mbw = mbw_value(r8a66597);
|
||||
|
||||
r8a66597_mdfy(r8a66597, MBW | pipe->info.pipenum, MBW | CURPIPE,
|
||||
cfifo_change(r8a66597, 0);
|
||||
r8a66597_mdfy(r8a66597, mbw | 0, mbw | CURPIPE, D0FIFOSEL);
|
||||
r8a66597_mdfy(r8a66597, mbw | 0, mbw | CURPIPE, D1FIFOSEL);
|
||||
|
||||
r8a66597_mdfy(r8a66597, mbw | pipe->info.pipenum, mbw | CURPIPE,
|
||||
pipe->fifosel);
|
||||
r8a66597_reg_wait(r8a66597, pipe->fifosel, CURPIPE, pipe->info.pipenum);
|
||||
}
|
||||
|
|
@ -742,9 +757,13 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597,
|
|||
struct r8a66597_pipe *pipe,
|
||||
struct urb *urb)
|
||||
{
|
||||
#if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
|
||||
int i;
|
||||
struct r8a66597_pipe_info *info = &pipe->info;
|
||||
unsigned short mbw = mbw_value(r8a66597);
|
||||
|
||||
/* pipe dma is only for external controlles */
|
||||
if (r8a66597->pdata->on_chip)
|
||||
return;
|
||||
|
||||
if ((pipe->info.pipenum != 0) && (info->type != R8A66597_INT)) {
|
||||
for (i = 0; i < R8A66597_MAX_DMA_CHANNEL; i++) {
|
||||
|
|
@ -763,8 +782,8 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597,
|
|||
set_pipe_reg_addr(pipe, i);
|
||||
|
||||
cfifo_change(r8a66597, 0);
|
||||
r8a66597_mdfy(r8a66597, MBW | pipe->info.pipenum,
|
||||
MBW | CURPIPE, pipe->fifosel);
|
||||
r8a66597_mdfy(r8a66597, mbw | pipe->info.pipenum,
|
||||
mbw | CURPIPE, pipe->fifosel);
|
||||
|
||||
r8a66597_reg_wait(r8a66597, pipe->fifosel, CURPIPE,
|
||||
pipe->info.pipenum);
|
||||
|
|
@ -772,7 +791,6 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597,
|
|||
break;
|
||||
}
|
||||
}
|
||||
#endif /* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */
|
||||
}
|
||||
|
||||
/* this function must be called with interrupt disabled */
|
||||
|
|
@ -1769,7 +1787,7 @@ static void r8a66597_timer(unsigned long _r8a66597)
|
|||
|
||||
spin_lock_irqsave(&r8a66597->lock, flags);
|
||||
|
||||
for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
|
||||
for (port = 0; port < r8a66597->max_root_hub; port++)
|
||||
r8a66597_root_hub_control(r8a66597, port);
|
||||
|
||||
spin_unlock_irqrestore(&r8a66597->lock, flags);
|
||||
|
|
@ -1807,7 +1825,7 @@ static void set_address_zero(struct r8a66597 *r8a66597, struct urb *urb)
|
|||
u16 root_port, hub_port;
|
||||
|
||||
if (usb_address == 0) {
|
||||
get_port_number(urb->dev->devpath,
|
||||
get_port_number(r8a66597, urb->dev->devpath,
|
||||
&root_port, &hub_port);
|
||||
set_devadd_reg(r8a66597, 0,
|
||||
get_r8a66597_usb_speed(urb->dev->speed),
|
||||
|
|
@ -2082,7 +2100,7 @@ static int r8a66597_hub_status_data(struct usb_hcd *hcd, char *buf)
|
|||
|
||||
*buf = 0; /* initialize (no change) */
|
||||
|
||||
for (i = 0; i < R8A66597_MAX_ROOT_HUB; i++) {
|
||||
for (i = 0; i < r8a66597->max_root_hub; i++) {
|
||||
if (r8a66597->root_hub[i].port & 0xffff0000)
|
||||
*buf |= 1 << (i + 1);
|
||||
}
|
||||
|
|
@ -2097,11 +2115,11 @@ static void r8a66597_hub_descriptor(struct r8a66597 *r8a66597,
|
|||
{
|
||||
desc->bDescriptorType = 0x29;
|
||||
desc->bHubContrCurrent = 0;
|
||||
desc->bNbrPorts = R8A66597_MAX_ROOT_HUB;
|
||||
desc->bNbrPorts = r8a66597->max_root_hub;
|
||||
desc->bDescLength = 9;
|
||||
desc->bPwrOn2PwrGood = 0;
|
||||
desc->wHubCharacteristics = cpu_to_le16(0x0011);
|
||||
desc->bitmap[0] = ((1 << R8A66597_MAX_ROOT_HUB) - 1) << 1;
|
||||
desc->bitmap[0] = ((1 << r8a66597->max_root_hub) - 1) << 1;
|
||||
desc->bitmap[1] = ~0;
|
||||
}
|
||||
|
||||
|
|
@ -2129,7 +2147,7 @@ static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
|||
}
|
||||
break;
|
||||
case ClearPortFeature:
|
||||
if (wIndex > R8A66597_MAX_ROOT_HUB)
|
||||
if (wIndex > r8a66597->max_root_hub)
|
||||
goto error;
|
||||
if (wLength != 0)
|
||||
goto error;
|
||||
|
|
@ -2162,12 +2180,12 @@ static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
|||
*buf = 0x00;
|
||||
break;
|
||||
case GetPortStatus:
|
||||
if (wIndex > R8A66597_MAX_ROOT_HUB)
|
||||
if (wIndex > r8a66597->max_root_hub)
|
||||
goto error;
|
||||
*(__le32 *)buf = cpu_to_le32(rh->port);
|
||||
break;
|
||||
case SetPortFeature:
|
||||
if (wIndex > R8A66597_MAX_ROOT_HUB)
|
||||
if (wIndex > r8a66597->max_root_hub)
|
||||
goto error;
|
||||
if (wLength != 0)
|
||||
goto error;
|
||||
|
|
@ -2216,7 +2234,7 @@ static int r8a66597_bus_suspend(struct usb_hcd *hcd)
|
|||
|
||||
dbg("%s", __func__);
|
||||
|
||||
for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
|
||||
for (port = 0; port < r8a66597->max_root_hub; port++) {
|
||||
struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
|
||||
unsigned long dvstctr_reg = get_dvstctr_reg(port);
|
||||
|
||||
|
|
@ -2247,7 +2265,7 @@ static int r8a66597_bus_resume(struct usb_hcd *hcd)
|
|||
|
||||
dbg("%s", __func__);
|
||||
|
||||
for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
|
||||
for (port = 0; port < r8a66597->max_root_hub; port++) {
|
||||
struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
|
||||
unsigned long dvstctr_reg = get_dvstctr_reg(port);
|
||||
|
||||
|
|
@ -2305,16 +2323,16 @@ static struct hc_driver r8a66597_hc_driver = {
|
|||
};
|
||||
|
||||
#if defined(CONFIG_PM)
|
||||
static int r8a66597_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
static int r8a66597_suspend(struct device *dev)
|
||||
{
|
||||
struct r8a66597 *r8a66597 = dev_get_drvdata(&pdev->dev);
|
||||
struct r8a66597 *r8a66597 = dev_get_drvdata(dev);
|
||||
int port;
|
||||
|
||||
dbg("%s", __func__);
|
||||
|
||||
disable_controller(r8a66597);
|
||||
|
||||
for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
|
||||
for (port = 0; port < r8a66597->max_root_hub; port++) {
|
||||
struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
|
||||
|
||||
rh->port = 0x00000000;
|
||||
|
|
@ -2323,9 +2341,9 @@ static int r8a66597_suspend(struct platform_device *pdev, pm_message_t state)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int r8a66597_resume(struct platform_device *pdev)
|
||||
static int r8a66597_resume(struct device *dev)
|
||||
{
|
||||
struct r8a66597 *r8a66597 = dev_get_drvdata(&pdev->dev);
|
||||
struct r8a66597 *r8a66597 = dev_get_drvdata(dev);
|
||||
struct usb_hcd *hcd = r8a66597_to_hcd(r8a66597);
|
||||
|
||||
dbg("%s", __func__);
|
||||
|
|
@ -2335,9 +2353,17 @@ static int r8a66597_resume(struct platform_device *pdev)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dev_pm_ops r8a66597_dev_pm_ops = {
|
||||
.suspend = r8a66597_suspend,
|
||||
.resume = r8a66597_resume,
|
||||
.poweroff = r8a66597_suspend,
|
||||
.restore = r8a66597_resume,
|
||||
};
|
||||
|
||||
#define R8A66597_DEV_PM_OPS (&r8a66597_dev_pm_ops)
|
||||
#else /* if defined(CONFIG_PM) */
|
||||
#define r8a66597_suspend NULL
|
||||
#define r8a66597_resume NULL
|
||||
#define R8A66597_DEV_PM_OPS NULL
|
||||
#endif
|
||||
|
||||
static int __init_or_module r8a66597_remove(struct platform_device *pdev)
|
||||
|
|
@ -2348,8 +2374,9 @@ static int __init_or_module r8a66597_remove(struct platform_device *pdev)
|
|||
del_timer_sync(&r8a66597->rh_timer);
|
||||
usb_remove_hcd(hcd);
|
||||
iounmap((void *)r8a66597->reg);
|
||||
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
|
||||
clk_put(r8a66597->clk);
|
||||
#ifdef CONFIG_HAVE_CLK
|
||||
if (r8a66597->pdata->on_chip)
|
||||
clk_put(r8a66597->clk);
|
||||
#endif
|
||||
usb_put_hcd(hcd);
|
||||
return 0;
|
||||
|
|
@ -2357,7 +2384,7 @@ static int __init_or_module r8a66597_remove(struct platform_device *pdev)
|
|||
|
||||
static int __devinit r8a66597_probe(struct platform_device *pdev)
|
||||
{
|
||||
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
|
||||
#ifdef CONFIG_HAVE_CLK
|
||||
char clk_name[8];
|
||||
#endif
|
||||
struct resource *res = NULL, *ires;
|
||||
|
|
@ -2419,15 +2446,20 @@ static int __devinit r8a66597_probe(struct platform_device *pdev)
|
|||
r8a66597->pdata = pdev->dev.platform_data;
|
||||
r8a66597->irq_sense_low = irq_trigger == IRQF_TRIGGER_LOW;
|
||||
|
||||
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
|
||||
snprintf(clk_name, sizeof(clk_name), "usb%d", pdev->id);
|
||||
r8a66597->clk = clk_get(&pdev->dev, clk_name);
|
||||
if (IS_ERR(r8a66597->clk)) {
|
||||
dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
|
||||
ret = PTR_ERR(r8a66597->clk);
|
||||
goto clean_up2;
|
||||
}
|
||||
if (r8a66597->pdata->on_chip) {
|
||||
#ifdef CONFIG_HAVE_CLK
|
||||
snprintf(clk_name, sizeof(clk_name), "usb%d", pdev->id);
|
||||
r8a66597->clk = clk_get(&pdev->dev, clk_name);
|
||||
if (IS_ERR(r8a66597->clk)) {
|
||||
dev_err(&pdev->dev, "cannot get clock \"%s\"\n",
|
||||
clk_name);
|
||||
ret = PTR_ERR(r8a66597->clk);
|
||||
goto clean_up2;
|
||||
}
|
||||
#endif
|
||||
r8a66597->max_root_hub = 1;
|
||||
} else
|
||||
r8a66597->max_root_hub = 2;
|
||||
|
||||
spin_lock_init(&r8a66597->lock);
|
||||
init_timer(&r8a66597->rh_timer);
|
||||
|
|
@ -2457,8 +2489,9 @@ static int __devinit r8a66597_probe(struct platform_device *pdev)
|
|||
return 0;
|
||||
|
||||
clean_up3:
|
||||
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
|
||||
clk_put(r8a66597->clk);
|
||||
#ifdef CONFIG_HAVE_CLK
|
||||
if (r8a66597->pdata->on_chip)
|
||||
clk_put(r8a66597->clk);
|
||||
clean_up2:
|
||||
#endif
|
||||
usb_put_hcd(hcd);
|
||||
|
|
@ -2473,11 +2506,10 @@ clean_up:
|
|||
static struct platform_driver r8a66597_driver = {
|
||||
.probe = r8a66597_probe,
|
||||
.remove = r8a66597_remove,
|
||||
.suspend = r8a66597_suspend,
|
||||
.resume = r8a66597_resume,
|
||||
.driver = {
|
||||
.name = (char *) hcd_name,
|
||||
.owner = THIS_MODULE,
|
||||
.pm = R8A66597_DEV_PM_OPS,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -26,390 +26,16 @@
|
|||
#ifndef __R8A66597_H__
|
||||
#define __R8A66597_H__
|
||||
|
||||
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
|
||||
#ifdef CONFIG_HAVE_CLK
|
||||
#include <linux/clk.h>
|
||||
#endif
|
||||
|
||||
#include <linux/usb/r8a66597.h>
|
||||
|
||||
#define SYSCFG0 0x00
|
||||
#define SYSCFG1 0x02
|
||||
#define SYSSTS0 0x04
|
||||
#define SYSSTS1 0x06
|
||||
#define DVSTCTR0 0x08
|
||||
#define DVSTCTR1 0x0A
|
||||
#define TESTMODE 0x0C
|
||||
#define PINCFG 0x0E
|
||||
#define DMA0CFG 0x10
|
||||
#define DMA1CFG 0x12
|
||||
#define CFIFO 0x14
|
||||
#define D0FIFO 0x18
|
||||
#define D1FIFO 0x1C
|
||||
#define CFIFOSEL 0x20
|
||||
#define CFIFOCTR 0x22
|
||||
#define CFIFOSIE 0x24
|
||||
#define D0FIFOSEL 0x28
|
||||
#define D0FIFOCTR 0x2A
|
||||
#define D1FIFOSEL 0x2C
|
||||
#define D1FIFOCTR 0x2E
|
||||
#define INTENB0 0x30
|
||||
#define INTENB1 0x32
|
||||
#define INTENB2 0x34
|
||||
#define BRDYENB 0x36
|
||||
#define NRDYENB 0x38
|
||||
#define BEMPENB 0x3A
|
||||
#define SOFCFG 0x3C
|
||||
#define INTSTS0 0x40
|
||||
#define INTSTS1 0x42
|
||||
#define INTSTS2 0x44
|
||||
#define BRDYSTS 0x46
|
||||
#define NRDYSTS 0x48
|
||||
#define BEMPSTS 0x4A
|
||||
#define FRMNUM 0x4C
|
||||
#define UFRMNUM 0x4E
|
||||
#define USBADDR 0x50
|
||||
#define USBREQ 0x54
|
||||
#define USBVAL 0x56
|
||||
#define USBINDX 0x58
|
||||
#define USBLENG 0x5A
|
||||
#define DCPCFG 0x5C
|
||||
#define DCPMAXP 0x5E
|
||||
#define DCPCTR 0x60
|
||||
#define PIPESEL 0x64
|
||||
#define PIPECFG 0x68
|
||||
#define PIPEBUF 0x6A
|
||||
#define PIPEMAXP 0x6C
|
||||
#define PIPEPERI 0x6E
|
||||
#define PIPE1CTR 0x70
|
||||
#define PIPE2CTR 0x72
|
||||
#define PIPE3CTR 0x74
|
||||
#define PIPE4CTR 0x76
|
||||
#define PIPE5CTR 0x78
|
||||
#define PIPE6CTR 0x7A
|
||||
#define PIPE7CTR 0x7C
|
||||
#define PIPE8CTR 0x7E
|
||||
#define PIPE9CTR 0x80
|
||||
#define PIPE1TRE 0x90
|
||||
#define PIPE1TRN 0x92
|
||||
#define PIPE2TRE 0x94
|
||||
#define PIPE2TRN 0x96
|
||||
#define PIPE3TRE 0x98
|
||||
#define PIPE3TRN 0x9A
|
||||
#define PIPE4TRE 0x9C
|
||||
#define PIPE4TRN 0x9E
|
||||
#define PIPE5TRE 0xA0
|
||||
#define PIPE5TRN 0xA2
|
||||
#define DEVADD0 0xD0
|
||||
#define DEVADD1 0xD2
|
||||
#define DEVADD2 0xD4
|
||||
#define DEVADD3 0xD6
|
||||
#define DEVADD4 0xD8
|
||||
#define DEVADD5 0xDA
|
||||
#define DEVADD6 0xDC
|
||||
#define DEVADD7 0xDE
|
||||
#define DEVADD8 0xE0
|
||||
#define DEVADD9 0xE2
|
||||
#define DEVADDA 0xE4
|
||||
|
||||
/* System Configuration Control Register */
|
||||
#define XTAL 0xC000 /* b15-14: Crystal selection */
|
||||
#define XTAL48 0x8000 /* 48MHz */
|
||||
#define XTAL24 0x4000 /* 24MHz */
|
||||
#define XTAL12 0x0000 /* 12MHz */
|
||||
#define XCKE 0x2000 /* b13: External clock enable */
|
||||
#define PLLC 0x0800 /* b11: PLL control */
|
||||
#define SCKE 0x0400 /* b10: USB clock enable */
|
||||
#define PCSDIS 0x0200 /* b9: not CS wakeup */
|
||||
#define LPSME 0x0100 /* b8: Low power sleep mode */
|
||||
#define HSE 0x0080 /* b7: Hi-speed enable */
|
||||
#define DCFM 0x0040 /* b6: Controller function select */
|
||||
#define DRPD 0x0020 /* b5: D+/- pull down control */
|
||||
#define DPRPU 0x0010 /* b4: D+ pull up control */
|
||||
#define USBE 0x0001 /* b0: USB module operation enable */
|
||||
|
||||
/* System Configuration Status Register */
|
||||
#define OVCBIT 0x8000 /* b15-14: Over-current bit */
|
||||
#define OVCMON 0xC000 /* b15-14: Over-current monitor */
|
||||
#define SOFEA 0x0020 /* b5: SOF monitor */
|
||||
#define IDMON 0x0004 /* b3: ID-pin monitor */
|
||||
#define LNST 0x0003 /* b1-0: D+, D- line status */
|
||||
#define SE1 0x0003 /* SE1 */
|
||||
#define FS_KSTS 0x0002 /* Full-Speed K State */
|
||||
#define FS_JSTS 0x0001 /* Full-Speed J State */
|
||||
#define LS_JSTS 0x0002 /* Low-Speed J State */
|
||||
#define LS_KSTS 0x0001 /* Low-Speed K State */
|
||||
#define SE0 0x0000 /* SE0 */
|
||||
|
||||
/* Device State Control Register */
|
||||
#define EXTLP0 0x0400 /* b10: External port */
|
||||
#define VBOUT 0x0200 /* b9: VBUS output */
|
||||
#define WKUP 0x0100 /* b8: Remote wakeup */
|
||||
#define RWUPE 0x0080 /* b7: Remote wakeup sense */
|
||||
#define USBRST 0x0040 /* b6: USB reset enable */
|
||||
#define RESUME 0x0020 /* b5: Resume enable */
|
||||
#define UACT 0x0010 /* b4: USB bus enable */
|
||||
#define RHST 0x0007 /* b1-0: Reset handshake status */
|
||||
#define HSPROC 0x0004 /* HS handshake is processing */
|
||||
#define HSMODE 0x0003 /* Hi-Speed mode */
|
||||
#define FSMODE 0x0002 /* Full-Speed mode */
|
||||
#define LSMODE 0x0001 /* Low-Speed mode */
|
||||
#define UNDECID 0x0000 /* Undecided */
|
||||
|
||||
/* Test Mode Register */
|
||||
#define UTST 0x000F /* b3-0: Test select */
|
||||
#define H_TST_PACKET 0x000C /* HOST TEST Packet */
|
||||
#define H_TST_SE0_NAK 0x000B /* HOST TEST SE0 NAK */
|
||||
#define H_TST_K 0x000A /* HOST TEST K */
|
||||
#define H_TST_J 0x0009 /* HOST TEST J */
|
||||
#define H_TST_NORMAL 0x0000 /* HOST Normal Mode */
|
||||
#define P_TST_PACKET 0x0004 /* PERI TEST Packet */
|
||||
#define P_TST_SE0_NAK 0x0003 /* PERI TEST SE0 NAK */
|
||||
#define P_TST_K 0x0002 /* PERI TEST K */
|
||||
#define P_TST_J 0x0001 /* PERI TEST J */
|
||||
#define P_TST_NORMAL 0x0000 /* PERI Normal Mode */
|
||||
|
||||
/* Data Pin Configuration Register */
|
||||
#define LDRV 0x8000 /* b15: Drive Current Adjust */
|
||||
#define VIF1 0x0000 /* VIF = 1.8V */
|
||||
#define VIF3 0x8000 /* VIF = 3.3V */
|
||||
#define INTA 0x0001 /* b1: USB INT-pin active */
|
||||
|
||||
/* DMAx Pin Configuration Register */
|
||||
#define DREQA 0x4000 /* b14: Dreq active select */
|
||||
#define BURST 0x2000 /* b13: Burst mode */
|
||||
#define DACKA 0x0400 /* b10: Dack active select */
|
||||
#define DFORM 0x0380 /* b9-7: DMA mode select */
|
||||
#define CPU_ADR_RD_WR 0x0000 /* Address + RD/WR mode (CPU bus) */
|
||||
#define CPU_DACK_RD_WR 0x0100 /* DACK + RD/WR mode (CPU bus) */
|
||||
#define CPU_DACK_ONLY 0x0180 /* DACK only mode (CPU bus) */
|
||||
#define SPLIT_DACK_ONLY 0x0200 /* DACK only mode (SPLIT bus) */
|
||||
#define DENDA 0x0040 /* b6: Dend active select */
|
||||
#define PKTM 0x0020 /* b5: Packet mode */
|
||||
#define DENDE 0x0010 /* b4: Dend enable */
|
||||
#define OBUS 0x0004 /* b2: OUTbus mode */
|
||||
|
||||
/* CFIFO/DxFIFO Port Select Register */
|
||||
#define RCNT 0x8000 /* b15: Read count mode */
|
||||
#define REW 0x4000 /* b14: Buffer rewind */
|
||||
#define DCLRM 0x2000 /* b13: DMA buffer clear mode */
|
||||
#define DREQE 0x1000 /* b12: DREQ output enable */
|
||||
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
|
||||
#define MBW 0x0800
|
||||
#else
|
||||
#define MBW 0x0400 /* b10: Maximum bit width for FIFO access */
|
||||
#endif
|
||||
#define MBW_8 0x0000 /* 8bit */
|
||||
#define MBW_16 0x0400 /* 16bit */
|
||||
#define BIGEND 0x0100 /* b8: Big endian mode */
|
||||
#define BYTE_LITTLE 0x0000 /* little dendian */
|
||||
#define BYTE_BIG 0x0100 /* big endifan */
|
||||
#define ISEL 0x0020 /* b5: DCP FIFO port direction select */
|
||||
#define CURPIPE 0x000F /* b2-0: PIPE select */
|
||||
|
||||
/* CFIFO/DxFIFO Port Control Register */
|
||||
#define BVAL 0x8000 /* b15: Buffer valid flag */
|
||||
#define BCLR 0x4000 /* b14: Buffer clear */
|
||||
#define FRDY 0x2000 /* b13: FIFO ready */
|
||||
#define DTLN 0x0FFF /* b11-0: FIFO received data length */
|
||||
|
||||
/* Interrupt Enable Register 0 */
|
||||
#define VBSE 0x8000 /* b15: VBUS interrupt */
|
||||
#define RSME 0x4000 /* b14: Resume interrupt */
|
||||
#define SOFE 0x2000 /* b13: Frame update interrupt */
|
||||
#define DVSE 0x1000 /* b12: Device state transition interrupt */
|
||||
#define CTRE 0x0800 /* b11: Control transfer stage transition interrupt */
|
||||
#define BEMPE 0x0400 /* b10: Buffer empty interrupt */
|
||||
#define NRDYE 0x0200 /* b9: Buffer not ready interrupt */
|
||||
#define BRDYE 0x0100 /* b8: Buffer ready interrupt */
|
||||
|
||||
/* Interrupt Enable Register 1 */
|
||||
#define OVRCRE 0x8000 /* b15: Over-current interrupt */
|
||||
#define BCHGE 0x4000 /* b14: USB us chenge interrupt */
|
||||
#define DTCHE 0x1000 /* b12: Detach sense interrupt */
|
||||
#define ATTCHE 0x0800 /* b11: Attach sense interrupt */
|
||||
#define EOFERRE 0x0040 /* b6: EOF error interrupt */
|
||||
#define SIGNE 0x0020 /* b5: SETUP IGNORE interrupt */
|
||||
#define SACKE 0x0010 /* b4: SETUP ACK interrupt */
|
||||
|
||||
/* BRDY Interrupt Enable/Status Register */
|
||||
#define BRDY9 0x0200 /* b9: PIPE9 */
|
||||
#define BRDY8 0x0100 /* b8: PIPE8 */
|
||||
#define BRDY7 0x0080 /* b7: PIPE7 */
|
||||
#define BRDY6 0x0040 /* b6: PIPE6 */
|
||||
#define BRDY5 0x0020 /* b5: PIPE5 */
|
||||
#define BRDY4 0x0010 /* b4: PIPE4 */
|
||||
#define BRDY3 0x0008 /* b3: PIPE3 */
|
||||
#define BRDY2 0x0004 /* b2: PIPE2 */
|
||||
#define BRDY1 0x0002 /* b1: PIPE1 */
|
||||
#define BRDY0 0x0001 /* b1: PIPE0 */
|
||||
|
||||
/* NRDY Interrupt Enable/Status Register */
|
||||
#define NRDY9 0x0200 /* b9: PIPE9 */
|
||||
#define NRDY8 0x0100 /* b8: PIPE8 */
|
||||
#define NRDY7 0x0080 /* b7: PIPE7 */
|
||||
#define NRDY6 0x0040 /* b6: PIPE6 */
|
||||
#define NRDY5 0x0020 /* b5: PIPE5 */
|
||||
#define NRDY4 0x0010 /* b4: PIPE4 */
|
||||
#define NRDY3 0x0008 /* b3: PIPE3 */
|
||||
#define NRDY2 0x0004 /* b2: PIPE2 */
|
||||
#define NRDY1 0x0002 /* b1: PIPE1 */
|
||||
#define NRDY0 0x0001 /* b1: PIPE0 */
|
||||
|
||||
/* BEMP Interrupt Enable/Status Register */
|
||||
#define BEMP9 0x0200 /* b9: PIPE9 */
|
||||
#define BEMP8 0x0100 /* b8: PIPE8 */
|
||||
#define BEMP7 0x0080 /* b7: PIPE7 */
|
||||
#define BEMP6 0x0040 /* b6: PIPE6 */
|
||||
#define BEMP5 0x0020 /* b5: PIPE5 */
|
||||
#define BEMP4 0x0010 /* b4: PIPE4 */
|
||||
#define BEMP3 0x0008 /* b3: PIPE3 */
|
||||
#define BEMP2 0x0004 /* b2: PIPE2 */
|
||||
#define BEMP1 0x0002 /* b1: PIPE1 */
|
||||
#define BEMP0 0x0001 /* b0: PIPE0 */
|
||||
|
||||
/* SOF Pin Configuration Register */
|
||||
#define TRNENSEL 0x0100 /* b8: Select transaction enable period */
|
||||
#define BRDYM 0x0040 /* b6: BRDY clear timing */
|
||||
#define INTL 0x0020 /* b5: Interrupt sense select */
|
||||
#define EDGESTS 0x0010 /* b4: */
|
||||
#define SOFMODE 0x000C /* b3-2: SOF pin select */
|
||||
#define SOF_125US 0x0008 /* SOF OUT 125us Frame Signal */
|
||||
#define SOF_1MS 0x0004 /* SOF OUT 1ms Frame Signal */
|
||||
#define SOF_DISABLE 0x0000 /* SOF OUT Disable */
|
||||
|
||||
/* Interrupt Status Register 0 */
|
||||
#define VBINT 0x8000 /* b15: VBUS interrupt */
|
||||
#define RESM 0x4000 /* b14: Resume interrupt */
|
||||
#define SOFR 0x2000 /* b13: SOF frame update interrupt */
|
||||
#define DVST 0x1000 /* b12: Device state transition interrupt */
|
||||
#define CTRT 0x0800 /* b11: Control transfer stage transition interrupt */
|
||||
#define BEMP 0x0400 /* b10: Buffer empty interrupt */
|
||||
#define NRDY 0x0200 /* b9: Buffer not ready interrupt */
|
||||
#define BRDY 0x0100 /* b8: Buffer ready interrupt */
|
||||
#define VBSTS 0x0080 /* b7: VBUS input port */
|
||||
#define DVSQ 0x0070 /* b6-4: Device state */
|
||||
#define DS_SPD_CNFG 0x0070 /* Suspend Configured */
|
||||
#define DS_SPD_ADDR 0x0060 /* Suspend Address */
|
||||
#define DS_SPD_DFLT 0x0050 /* Suspend Default */
|
||||
#define DS_SPD_POWR 0x0040 /* Suspend Powered */
|
||||
#define DS_SUSP 0x0040 /* Suspend */
|
||||
#define DS_CNFG 0x0030 /* Configured */
|
||||
#define DS_ADDS 0x0020 /* Address */
|
||||
#define DS_DFLT 0x0010 /* Default */
|
||||
#define DS_POWR 0x0000 /* Powered */
|
||||
#define DVSQS 0x0030 /* b5-4: Device state */
|
||||
#define VALID 0x0008 /* b3: Setup packet detected flag */
|
||||
#define CTSQ 0x0007 /* b2-0: Control transfer stage */
|
||||
#define CS_SQER 0x0006 /* Sequence error */
|
||||
#define CS_WRND 0x0005 /* Control write nodata status stage */
|
||||
#define CS_WRSS 0x0004 /* Control write status stage */
|
||||
#define CS_WRDS 0x0003 /* Control write data stage */
|
||||
#define CS_RDSS 0x0002 /* Control read status stage */
|
||||
#define CS_RDDS 0x0001 /* Control read data stage */
|
||||
#define CS_IDST 0x0000 /* Idle or setup stage */
|
||||
|
||||
/* Interrupt Status Register 1 */
|
||||
#define OVRCR 0x8000 /* b15: Over-current interrupt */
|
||||
#define BCHG 0x4000 /* b14: USB bus chenge interrupt */
|
||||
#define DTCH 0x1000 /* b12: Detach sense interrupt */
|
||||
#define ATTCH 0x0800 /* b11: Attach sense interrupt */
|
||||
#define EOFERR 0x0040 /* b6: EOF-error interrupt */
|
||||
#define SIGN 0x0020 /* b5: Setup ignore interrupt */
|
||||
#define SACK 0x0010 /* b4: Setup acknowledge interrupt */
|
||||
|
||||
/* Frame Number Register */
|
||||
#define OVRN 0x8000 /* b15: Overrun error */
|
||||
#define CRCE 0x4000 /* b14: Received data error */
|
||||
#define FRNM 0x07FF /* b10-0: Frame number */
|
||||
|
||||
/* Micro Frame Number Register */
|
||||
#define UFRNM 0x0007 /* b2-0: Micro frame number */
|
||||
|
||||
/* Default Control Pipe Maxpacket Size Register */
|
||||
/* Pipe Maxpacket Size Register */
|
||||
#define DEVSEL 0xF000 /* b15-14: Device address select */
|
||||
#define MAXP 0x007F /* b6-0: Maxpacket size of default control pipe */
|
||||
|
||||
/* Default Control Pipe Control Register */
|
||||
#define BSTS 0x8000 /* b15: Buffer status */
|
||||
#define SUREQ 0x4000 /* b14: Send USB request */
|
||||
#define CSCLR 0x2000 /* b13: complete-split status clear */
|
||||
#define CSSTS 0x1000 /* b12: complete-split status */
|
||||
#define SUREQCLR 0x0800 /* b11: stop setup request */
|
||||
#define SQCLR 0x0100 /* b8: Sequence toggle bit clear */
|
||||
#define SQSET 0x0080 /* b7: Sequence toggle bit set */
|
||||
#define SQMON 0x0040 /* b6: Sequence toggle bit monitor */
|
||||
#define PBUSY 0x0020 /* b5: pipe busy */
|
||||
#define PINGE 0x0010 /* b4: ping enable */
|
||||
#define CCPL 0x0004 /* b2: Enable control transfer complete */
|
||||
#define PID 0x0003 /* b1-0: Response PID */
|
||||
#define PID_STALL11 0x0003 /* STALL */
|
||||
#define PID_STALL 0x0002 /* STALL */
|
||||
#define PID_BUF 0x0001 /* BUF */
|
||||
#define PID_NAK 0x0000 /* NAK */
|
||||
|
||||
/* Pipe Window Select Register */
|
||||
#define PIPENM 0x0007 /* b2-0: Pipe select */
|
||||
|
||||
/* Pipe Configuration Register */
|
||||
#define R8A66597_TYP 0xC000 /* b15-14: Transfer type */
|
||||
#define R8A66597_ISO 0xC000 /* Isochronous */
|
||||
#define R8A66597_INT 0x8000 /* Interrupt */
|
||||
#define R8A66597_BULK 0x4000 /* Bulk */
|
||||
#define R8A66597_BFRE 0x0400 /* b10: Buffer ready interrupt mode select */
|
||||
#define R8A66597_DBLB 0x0200 /* b9: Double buffer mode select */
|
||||
#define R8A66597_CNTMD 0x0100 /* b8: Continuous transfer mode select */
|
||||
#define R8A66597_SHTNAK 0x0080 /* b7: Transfer end NAK */
|
||||
#define R8A66597_DIR 0x0010 /* b4: Transfer direction select */
|
||||
#define R8A66597_EPNUM 0x000F /* b3-0: Eendpoint number select */
|
||||
|
||||
/* Pipe Buffer Configuration Register */
|
||||
#define BUFSIZE 0x7C00 /* b14-10: Pipe buffer size */
|
||||
#define BUFNMB 0x007F /* b6-0: Pipe buffer number */
|
||||
#define PIPE0BUF 256
|
||||
#define PIPExBUF 64
|
||||
|
||||
/* Pipe Maxpacket Size Register */
|
||||
#define MXPS 0x07FF /* b10-0: Maxpacket size */
|
||||
|
||||
/* Pipe Cycle Configuration Register */
|
||||
#define IFIS 0x1000 /* b12: Isochronous in-buffer flush mode select */
|
||||
#define IITV 0x0007 /* b2-0: Isochronous interval */
|
||||
|
||||
/* Pipex Control Register */
|
||||
#define BSTS 0x8000 /* b15: Buffer status */
|
||||
#define INBUFM 0x4000 /* b14: IN buffer monitor (Only for PIPE1 to 5) */
|
||||
#define CSCLR 0x2000 /* b13: complete-split status clear */
|
||||
#define CSSTS 0x1000 /* b12: complete-split status */
|
||||
#define ATREPM 0x0400 /* b10: Auto repeat mode */
|
||||
#define ACLRM 0x0200 /* b9: Out buffer auto clear mode */
|
||||
#define SQCLR 0x0100 /* b8: Sequence toggle bit clear */
|
||||
#define SQSET 0x0080 /* b7: Sequence toggle bit set */
|
||||
#define SQMON 0x0040 /* b6: Sequence toggle bit monitor */
|
||||
#define PBUSY 0x0020 /* b5: pipe busy */
|
||||
#define PID 0x0003 /* b1-0: Response PID */
|
||||
|
||||
/* PIPExTRE */
|
||||
#define TRENB 0x0200 /* b9: Transaction counter enable */
|
||||
#define TRCLR 0x0100 /* b8: Transaction counter clear */
|
||||
|
||||
/* PIPExTRN */
|
||||
#define TRNCNT 0xFFFF /* b15-0: Transaction counter */
|
||||
|
||||
/* DEVADDx */
|
||||
#define UPPHUB 0x7800
|
||||
#define HUBPORT 0x0700
|
||||
#define USBSPD 0x00C0
|
||||
#define RTPORT 0x0001
|
||||
|
||||
#define R8A66597_MAX_NUM_PIPE 10
|
||||
#define R8A66597_BUF_BSIZE 8
|
||||
#define R8A66597_MAX_DEVICE 10
|
||||
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
|
||||
#define R8A66597_MAX_ROOT_HUB 1
|
||||
#else
|
||||
#define R8A66597_MAX_ROOT_HUB 2
|
||||
#endif
|
||||
#define R8A66597_MAX_SAMPLING 5
|
||||
#define R8A66597_RH_POLL_TIME 10
|
||||
#define R8A66597_MAX_DMA_CHANNEL 2
|
||||
|
|
@ -487,7 +113,7 @@ struct r8a66597_root_hub {
|
|||
struct r8a66597 {
|
||||
spinlock_t lock;
|
||||
unsigned long reg;
|
||||
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
|
||||
#ifdef CONFIG_HAVE_CLK
|
||||
struct clk *clk;
|
||||
#endif
|
||||
struct r8a66597_platdata *pdata;
|
||||
|
|
@ -504,6 +130,7 @@ struct r8a66597 {
|
|||
unsigned short interval_map;
|
||||
unsigned char pipe_cnt[R8A66597_MAX_NUM_PIPE];
|
||||
unsigned char dma_map;
|
||||
unsigned int max_root_hub;
|
||||
|
||||
struct list_head child_device;
|
||||
unsigned long child_connect_map[4];
|
||||
|
|
@ -550,21 +177,22 @@ static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597,
|
|||
unsigned long offset, u16 *buf,
|
||||
int len)
|
||||
{
|
||||
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
|
||||
unsigned long fifoaddr = r8a66597->reg + offset;
|
||||
unsigned long count;
|
||||
|
||||
count = len / 4;
|
||||
insl(fifoaddr, buf, count);
|
||||
if (r8a66597->pdata->on_chip) {
|
||||
count = len / 4;
|
||||
insl(fifoaddr, buf, count);
|
||||
|
||||
if (len & 0x00000003) {
|
||||
unsigned long tmp = inl(fifoaddr);
|
||||
memcpy((unsigned char *)buf + count * 4, &tmp, len & 0x03);
|
||||
if (len & 0x00000003) {
|
||||
unsigned long tmp = inl(fifoaddr);
|
||||
memcpy((unsigned char *)buf + count * 4, &tmp,
|
||||
len & 0x03);
|
||||
}
|
||||
} else {
|
||||
len = (len + 1) / 2;
|
||||
insw(fifoaddr, buf, len);
|
||||
}
|
||||
#else
|
||||
len = (len + 1) / 2;
|
||||
insw(r8a66597->reg + offset, buf, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val,
|
||||
|
|
@ -578,33 +206,33 @@ static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597,
|
|||
int len)
|
||||
{
|
||||
unsigned long fifoaddr = r8a66597->reg + offset;
|
||||
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
|
||||
unsigned long count;
|
||||
unsigned char *pb;
|
||||
int i;
|
||||
|
||||
count = len / 4;
|
||||
outsl(fifoaddr, buf, count);
|
||||
if (r8a66597->pdata->on_chip) {
|
||||
count = len / 4;
|
||||
outsl(fifoaddr, buf, count);
|
||||
|
||||
if (len & 0x00000003) {
|
||||
pb = (unsigned char *)buf + count * 4;
|
||||
for (i = 0; i < (len & 0x00000003); i++) {
|
||||
if (r8a66597_read(r8a66597, CFIFOSEL) & BIGEND)
|
||||
outb(pb[i], fifoaddr + i);
|
||||
else
|
||||
outb(pb[i], fifoaddr + 3 - i);
|
||||
if (len & 0x00000003) {
|
||||
pb = (unsigned char *)buf + count * 4;
|
||||
for (i = 0; i < (len & 0x00000003); i++) {
|
||||
if (r8a66597_read(r8a66597, CFIFOSEL) & BIGEND)
|
||||
outb(pb[i], fifoaddr + i);
|
||||
else
|
||||
outb(pb[i], fifoaddr + 3 - i);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int odd = len & 0x0001;
|
||||
|
||||
len = len / 2;
|
||||
outsw(fifoaddr, buf, len);
|
||||
if (unlikely(odd)) {
|
||||
buf = &buf[len];
|
||||
outb((unsigned char)*buf, fifoaddr);
|
||||
}
|
||||
}
|
||||
#else
|
||||
int odd = len & 0x0001;
|
||||
|
||||
len = len / 2;
|
||||
outsw(fifoaddr, buf, len);
|
||||
if (unlikely(odd)) {
|
||||
buf = &buf[len];
|
||||
outb((unsigned char)*buf, fifoaddr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void r8a66597_mdfy(struct r8a66597 *r8a66597,
|
||||
|
|
|
|||
Loading…
Reference in a new issue