4 * Copyright (C) 2011 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 #include <linux/module.h>
19 #include <linux/pm_runtime.h>
20 #include <linux/slab.h>
21 #include <linux/sysfs.h>
27 * renesas usb support platform callback function.
28 * Below macro call it.
29 * if platform doesn't have callback, it return 0 (no error)
31 #define usbhs_platform_call(priv, func, args...)\
32 (!(priv) ? -ENODEV : \
33 !((priv)->pfunc->func) ? 0 : \
34 (priv)->pfunc->func(args))
39 u16
usbhs_read(struct usbhs_priv
*priv
, u32 reg
)
41 return ioread16(priv
->base
+ reg
);
44 void usbhs_write(struct usbhs_priv
*priv
, u32 reg
, u16 data
)
46 iowrite16(data
, priv
->base
+ reg
);
49 void usbhs_bset(struct usbhs_priv
*priv
, u32 reg
, u16 mask
, u16 data
)
51 u16 val
= usbhs_read(priv
, reg
);
56 usbhs_write(priv
, reg
, val
);
62 void usbhs_sys_clock_ctrl(struct usbhs_priv
*priv
, int enable
)
64 usbhs_bset(priv
, SYSCFG
, SCKE
, enable
? SCKE
: 0);
67 void usbhs_sys_hispeed_ctrl(struct usbhs_priv
*priv
, int enable
)
69 usbhs_bset(priv
, SYSCFG
, HSE
, enable
? HSE
: 0);
72 void usbhs_sys_usb_ctrl(struct usbhs_priv
*priv
, int enable
)
74 usbhs_bset(priv
, SYSCFG
, USBE
, enable
? USBE
: 0);
77 void usbhs_sys_host_ctrl(struct usbhs_priv
*priv
, int enable
)
79 u16 mask
= DCFM
| DRPD
| DPRPU
;
80 u16 val
= DCFM
| DRPD
;
86 * - D+ Line/D- Line Pull-down
88 usbhs_bset(priv
, SYSCFG
, mask
, enable
? val
: 0);
91 void usbhs_sys_function_ctrl(struct usbhs_priv
*priv
, int enable
)
93 u16 mask
= DCFM
| DRPD
| DPRPU
;
99 * - select Function mode
102 usbhs_bset(priv
, SYSCFG
, mask
, enable
? val
: 0);
108 int usbhs_frame_get_num(struct usbhs_priv
*priv
)
110 return usbhs_read(priv
, FRMNUM
) & FRNM_MASK
;
116 static struct usbhs_priv
*usbhsc_pdev_to_priv(struct platform_device
*pdev
)
118 return dev_get_drvdata(&pdev
->dev
);
121 static void usbhsc_bus_ctrl(struct usbhs_priv
*priv
, int enable
)
123 int wait
= usbhs_get_dparam(priv
, buswait_bwait
);
127 /* set bus wait if platform have */
129 usbhs_bset(priv
, BUSWAIT
, 0x000F, wait
);
131 usbhs_write(priv
, DVSTCTR
, data
);
135 * platform default param
137 static u32 usbhsc_default_pipe_type
[] = {
138 USB_ENDPOINT_XFER_CONTROL
,
139 USB_ENDPOINT_XFER_ISOC
,
140 USB_ENDPOINT_XFER_ISOC
,
141 USB_ENDPOINT_XFER_BULK
,
142 USB_ENDPOINT_XFER_BULK
,
143 USB_ENDPOINT_XFER_BULK
,
144 USB_ENDPOINT_XFER_INT
,
145 USB_ENDPOINT_XFER_INT
,
146 USB_ENDPOINT_XFER_INT
,
147 USB_ENDPOINT_XFER_INT
,
151 * driver callback functions
153 static void usbhsc_notify_hotplug(struct work_struct
*work
)
155 struct usbhs_priv
*priv
= container_of(work
,
157 notify_hotplug_work
);
158 struct platform_device
*pdev
= usbhs_priv_to_pdev(priv
);
159 struct usbhs_mod
*mod
= usbhs_mod_get_current(priv
);
165 * get vbus status from platform
167 enable
= usbhs_platform_call(priv
, get_vbus
, pdev
);
170 * get id from platform
172 id
= usbhs_platform_call(priv
, get_id
, pdev
);
174 if (enable
&& !mod
) {
175 ret
= usbhs_mod_change(priv
, id
);
179 dev_dbg(&pdev
->dev
, "%s enable\n", __func__
);
182 pm_runtime_get_sync(&pdev
->dev
);
185 usbhs_sys_clock_ctrl(priv
, enable
);
186 usbhsc_bus_ctrl(priv
, enable
);
189 usbhs_mod_call(priv
, start
, priv
);
191 } else if (!enable
&& mod
) {
192 dev_dbg(&pdev
->dev
, "%s disable\n", __func__
);
195 usbhs_mod_call(priv
, stop
, priv
);
198 usbhsc_bus_ctrl(priv
, enable
);
199 usbhs_sys_clock_ctrl(priv
, enable
);
202 pm_runtime_put_sync(&pdev
->dev
);
204 usbhs_mod_change(priv
, -1);
206 /* reset phy for next connection */
207 usbhs_platform_call(priv
, phy_reset
, pdev
);
211 static int usbhsc_drvcllbck_notify_hotplug(struct platform_device
*pdev
)
213 struct usbhs_priv
*priv
= usbhsc_pdev_to_priv(pdev
);
216 * This functions will be called in interrupt.
217 * To make sure safety context,
218 * use workqueue for usbhs_notify_hotplug
220 schedule_work(&priv
->notify_hotplug_work
);
227 static int __devinit
usbhs_probe(struct platform_device
*pdev
)
229 struct renesas_usbhs_platform_info
*info
= pdev
->dev
.platform_data
;
230 struct renesas_usbhs_driver_callback
*dfunc
;
231 struct usbhs_priv
*priv
;
232 struct resource
*res
;
236 /* check platform information */
238 !info
->platform_callback
.get_id
||
239 !info
->platform_callback
.get_vbus
) {
240 dev_err(&pdev
->dev
, "no platform information\n");
245 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
246 irq
= platform_get_irq(pdev
, 0);
247 if (!res
|| (int)irq
<= 0) {
248 dev_err(&pdev
->dev
, "Not enough Renesas USB platform resources.\n");
252 /* usb private data */
253 priv
= kzalloc(sizeof(*priv
), GFP_KERNEL
);
255 dev_err(&pdev
->dev
, "Could not allocate priv\n");
259 priv
->base
= ioremap_nocache(res
->start
, resource_size(res
));
261 dev_err(&pdev
->dev
, "ioremap error.\n");
263 goto probe_end_kfree
;
269 priv
->pfunc
= &info
->platform_callback
;
270 priv
->dparam
= &info
->driver_param
;
272 /* set driver callback functions for platform */
273 dfunc
= &info
->driver_callback
;
274 dfunc
->notify_hotplug
= usbhsc_drvcllbck_notify_hotplug
;
276 /* set default param if platform doesn't have */
277 if (!priv
->dparam
->pipe_type
) {
278 priv
->dparam
->pipe_type
= usbhsc_default_pipe_type
;
279 priv
->dparam
->pipe_size
= ARRAY_SIZE(usbhsc_default_pipe_type
);
287 INIT_WORK(&priv
->notify_hotplug_work
, usbhsc_notify_hotplug
);
288 spin_lock_init(usbhs_priv_to_lock(priv
));
290 /* call pipe and module init */
291 ret
= usbhs_pipe_probe(priv
);
293 goto probe_end_mod_exit
;
295 ret
= usbhs_mod_probe(priv
);
297 goto probe_end_iounmap
;
299 /* dev_set_drvdata should be called after usbhs_mod_init */
300 dev_set_drvdata(&pdev
->dev
, priv
);
303 * deviece reset here because
304 * USB device might be used in boot loader.
306 usbhs_sys_clock_ctrl(priv
, 0);
311 * USB phy setup might depend on CPU/Board.
312 * If platform has its callback functions,
315 ret
= usbhs_platform_call(priv
, hardware_init
, pdev
);
317 dev_err(&pdev
->dev
, "platform prove failed.\n");
318 goto probe_end_pipe_exit
;
321 /* reset phy for connection */
322 usbhs_platform_call(priv
, phy_reset
, pdev
);
325 * manual call notify_hotplug for cold plug
327 pm_runtime_enable(&pdev
->dev
);
328 ret
= usbhsc_drvcllbck_notify_hotplug(pdev
);
330 goto probe_end_call_remove
;
332 dev_info(&pdev
->dev
, "probed\n");
336 probe_end_call_remove
:
337 usbhs_platform_call(priv
, hardware_exit
, pdev
);
339 usbhs_pipe_remove(priv
);
341 usbhs_mod_remove(priv
);
347 dev_info(&pdev
->dev
, "probe failed\n");
352 static int __devexit
usbhs_remove(struct platform_device
*pdev
)
354 struct usbhs_priv
*priv
= usbhsc_pdev_to_priv(pdev
);
356 dev_dbg(&pdev
->dev
, "usb remove\n");
358 pm_runtime_disable(&pdev
->dev
);
360 usbhsc_bus_ctrl(priv
, 0);
362 usbhs_platform_call(priv
, hardware_exit
, pdev
);
363 usbhs_pipe_remove(priv
);
364 usbhs_mod_remove(priv
);
371 static struct platform_driver renesas_usbhs_driver
= {
373 .name
= "renesas_usbhs",
375 .probe
= usbhs_probe
,
376 .remove
= __devexit_p(usbhs_remove
),
379 static int __init
usbhs_init(void)
381 return platform_driver_register(&renesas_usbhs_driver
);
384 static void __exit
usbhs_exit(void)
386 platform_driver_unregister(&renesas_usbhs_driver
);
389 module_init(usbhs_init
);
390 module_exit(usbhs_exit
);
392 MODULE_LICENSE("GPL");
393 MODULE_DESCRIPTION("Renesas USB driver");
394 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");