diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2012-06-25 06:35:01 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2012-06-30 09:30:30 -0400 |
commit | 77bcefd90c52b6806046b71212dcd5983475265b (patch) | |
tree | f645586fad9ee1b56c702587e3d23cca56c92b8e /arch/arm/mach-shmobile/board-kzm9g.c | |
parent | 0fcc6d55028d94f3e5c1f9de39e6134764a4a17c (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/mach-shmobile/board-kzm9g.c')
-rw-r--r-- | arch/arm/mach-shmobile/board-kzm9g.c | 150 |
1 files changed, 150 insertions, 0 deletions
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 */ | ||
127 | struct 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 | |||
143 | static 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 | |||
150 | static 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 | |||
158 | static int usbhs_get_id(struct platform_device *pdev) | ||
159 | { | ||
160 | return USBHS_GADGET; | ||
161 | } | ||
162 | |||
163 | static 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 | |||
176 | static 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 | |||
197 | static 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 | |||
207 | static 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 | |||
226 | static 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 | |||
246 | static 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 | |||
259 | static 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 */ |
126 | static struct fb_videomode kzm_lcdc_mode = { | 272 | static 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[] = { | |||
361 | static struct platform_device *kzm_devices[] __initdata = { | 507 | static 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); |