aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2012-06-25 06:35:01 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2012-06-30 09:30:30 -0400
commit77bcefd90c52b6806046b71212dcd5983475265b (patch)
treef645586fad9ee1b56c702587e3d23cca56c92b8e /arch/arm
parent0fcc6d55028d94f3e5c1f9de39e6134764a4a17c (diff)
ARM: shmobile: kzm9g: enable USB function
This patch enable USB function on CN17 Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Acked-by: Magnus Damm <damm@opensource.se> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/configs/kzm9g_defconfig5
-rw-r--r--arch/arm/mach-shmobile/board-kzm9g.c150
2 files changed, 155 insertions, 0 deletions
diff --git a/arch/arm/configs/kzm9g_defconfig b/arch/arm/configs/kzm9g_defconfig
index 686129f3a937..7b2eecd6dcc5 100644
--- a/arch/arm/configs/kzm9g_defconfig
+++ b/arch/arm/configs/kzm9g_defconfig
@@ -100,7 +100,12 @@ CONFIG_SND_SOC_SH4_FSI=y
100CONFIG_USB=y 100CONFIG_USB=y
101CONFIG_USB_DEVICEFS=y 101CONFIG_USB_DEVICEFS=y
102CONFIG_USB_R8A66597_HCD=y 102CONFIG_USB_R8A66597_HCD=y
103CONFIG_USB_RENESAS_USBHS=y
103CONFIG_USB_STORAGE=y 104CONFIG_USB_STORAGE=y
105CONFIG_USB_GADGET=y
106CONFIG_USB_RENESAS_USBHS_UDC=y
107CONFIG_USB_ETH=m
108CONFIG_USB_MASS_STORAGE=m
104CONFIG_MMC=y 109CONFIG_MMC=y
105# CONFIG_MMC_BLOCK_BOUNCE is not set 110# CONFIG_MMC_BLOCK_BOUNCE is not set
106CONFIG_MMC_SDHI=y 111CONFIG_MMC_SDHI=y
diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c
index a5cb11358e00..27194bc6ee3c 100644
--- a/arch/arm/mach-shmobile/board-kzm9g.c
+++ b/arch/arm/mach-shmobile/board-kzm9g.c
@@ -32,6 +32,7 @@
32#include <linux/platform_device.h> 32#include <linux/platform_device.h>
33#include <linux/smsc911x.h> 33#include <linux/smsc911x.h>
34#include <linux/usb/r8a66597.h> 34#include <linux/usb/r8a66597.h>
35#include <linux/usb/renesas_usbhs.h>
35#include <linux/videodev2.h> 36#include <linux/videodev2.h>
36#include <sound/sh_fsi.h> 37#include <sound/sh_fsi.h>
37#include <sound/simple_card.h> 38#include <sound/simple_card.h>
@@ -122,6 +123,151 @@ static struct platform_device usb_host_device = {
122 .resource = usb_resources, 123 .resource = usb_resources,
123}; 124};
124 125
126/* USB Func CN17 */
127struct usbhs_private {
128 unsigned int phy;
129 unsigned int cr2;
130 struct renesas_usbhs_platform_info info;
131};
132
133#define IRQ15 intcs_evt2irq(0x03e0)
134#define USB_PHY_MODE (1 << 4)
135#define USB_PHY_INT_EN ((1 << 3) | (1 << 2))
136#define USB_PHY_ON (1 << 1)
137#define USB_PHY_OFF (1 << 0)
138#define USB_PHY_INT_CLR (USB_PHY_ON | USB_PHY_OFF)
139
140#define usbhs_get_priv(pdev) \
141 container_of(renesas_usbhs_get_info(pdev), struct usbhs_private, info)
142
143static int usbhs_get_vbus(struct platform_device *pdev)
144{
145 struct usbhs_private *priv = usbhs_get_priv(pdev);
146
147 return !((1 << 7) & __raw_readw(priv->cr2));
148}
149
150static void usbhs_phy_reset(struct platform_device *pdev)
151{
152 struct usbhs_private *priv = usbhs_get_priv(pdev);
153
154 /* init phy */
155 __raw_writew(0x8a0a, priv->cr2);
156}
157
158static int usbhs_get_id(struct platform_device *pdev)
159{
160 return USBHS_GADGET;
161}
162
163static irqreturn_t usbhs_interrupt(int irq, void *data)
164{
165 struct platform_device *pdev = data;
166 struct usbhs_private *priv = usbhs_get_priv(pdev);
167
168 renesas_usbhs_call_notify_hotplug(pdev);
169
170 /* clear status */
171 __raw_writew(__raw_readw(priv->phy) | USB_PHY_INT_CLR, priv->phy);
172
173 return IRQ_HANDLED;
174}
175
176static int usbhs_hardware_init(struct platform_device *pdev)
177{
178 struct usbhs_private *priv = usbhs_get_priv(pdev);
179 int ret;
180
181 /* clear interrupt status */
182 __raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->phy);
183
184 ret = request_irq(IRQ15, usbhs_interrupt, IRQF_TRIGGER_HIGH,
185 dev_name(&pdev->dev), pdev);
186 if (ret) {
187 dev_err(&pdev->dev, "request_irq err\n");
188 return ret;
189 }
190
191 /* enable USB phy interrupt */
192 __raw_writew(USB_PHY_MODE | USB_PHY_INT_EN, priv->phy);
193
194 return 0;
195}
196
197static void usbhs_hardware_exit(struct platform_device *pdev)
198{
199 struct usbhs_private *priv = usbhs_get_priv(pdev);
200
201 /* clear interrupt status */
202 __raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->phy);
203
204 free_irq(IRQ15, pdev);
205}
206
207static u32 usbhs_pipe_cfg[] = {
208 USB_ENDPOINT_XFER_CONTROL,
209 USB_ENDPOINT_XFER_ISOC,
210 USB_ENDPOINT_XFER_ISOC,
211 USB_ENDPOINT_XFER_BULK,
212 USB_ENDPOINT_XFER_BULK,
213 USB_ENDPOINT_XFER_BULK,
214 USB_ENDPOINT_XFER_INT,
215 USB_ENDPOINT_XFER_INT,
216 USB_ENDPOINT_XFER_INT,
217 USB_ENDPOINT_XFER_BULK,
218 USB_ENDPOINT_XFER_BULK,
219 USB_ENDPOINT_XFER_BULK,
220 USB_ENDPOINT_XFER_BULK,
221 USB_ENDPOINT_XFER_BULK,
222 USB_ENDPOINT_XFER_BULK,
223 USB_ENDPOINT_XFER_BULK,
224};
225
226static struct usbhs_private usbhs_private = {
227 .phy = 0xe60781e0, /* USBPHYINT */
228 .cr2 = 0xe605810c, /* USBCR2 */
229 .info = {
230 .platform_callback = {
231 .hardware_init = usbhs_hardware_init,
232 .hardware_exit = usbhs_hardware_exit,
233 .get_id = usbhs_get_id,
234 .phy_reset = usbhs_phy_reset,
235 .get_vbus = usbhs_get_vbus,
236 },
237 .driver_param = {
238 .buswait_bwait = 4,
239 .has_otg = 1,
240 .pipe_type = usbhs_pipe_cfg,
241 .pipe_size = ARRAY_SIZE(usbhs_pipe_cfg),
242 },
243 },
244};
245
246static struct resource usbhs_resources[] = {
247 [0] = {
248 .start = 0xE6890000,
249 .end = 0xE68900e6 - 1,
250 .flags = IORESOURCE_MEM,
251 },
252 [1] = {
253 .start = gic_spi(62),
254 .end = gic_spi(62),
255 .flags = IORESOURCE_IRQ,
256 },
257};
258
259static struct platform_device usbhs_device = {
260 .name = "renesas_usbhs",
261 .id = -1,
262 .dev = {
263 .dma_mask = NULL,
264 .coherent_dma_mask = 0xffffffff,
265 .platform_data = &usbhs_private.info,
266 },
267 .num_resources = ARRAY_SIZE(usbhs_resources),
268 .resource = usbhs_resources,
269};
270
125/* LCDC */ 271/* LCDC */
126static struct fb_videomode kzm_lcdc_mode = { 272static struct fb_videomode kzm_lcdc_mode = {
127 .name = "WVGA Panel", 273 .name = "WVGA Panel",
@@ -361,6 +507,7 @@ static struct i2c_board_info i2c3_devices[] = {
361static struct platform_device *kzm_devices[] __initdata = { 507static struct platform_device *kzm_devices[] __initdata = {
362 &smsc_device, 508 &smsc_device,
363 &usb_host_device, 509 &usb_host_device,
510 &usbhs_device,
364 &lcdc_device, 511 &lcdc_device,
365 &mmc_device, 512 &mmc_device,
366 &sdhi0_device, 513 &sdhi0_device,
@@ -512,6 +659,9 @@ static void __init kzm_init(void)
512 gpio_request(GPIO_FN_FSIAISLD, NULL); 659 gpio_request(GPIO_FN_FSIAISLD, NULL);
513 gpio_request(GPIO_FN_FSIAOSLD, NULL); 660 gpio_request(GPIO_FN_FSIAOSLD, NULL);
514 661
662 /* enable USB */
663 gpio_request(GPIO_FN_VBUS_0, NULL);
664
515#ifdef CONFIG_CACHE_L2X0 665#ifdef CONFIG_CACHE_L2X0
516 /* Early BRESP enable, Shared attribute override enable, 64K*8way */ 666 /* Early BRESP enable, Shared attribute override enable, 64K*8way */
517 l2x0_init(IOMEM(0xf0100000), 0x40460000, 0x82000fff); 667 l2x0_init(IOMEM(0xf0100000), 0x40460000, 0x82000fff);