]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/usb/renesas_usbhs/common.c
arm: imx6: defconfig: update tx6 defconfigs
[karo-tx-linux.git] / drivers / usb / renesas_usbhs / common.c
1 /*
2  * Renesas USB driver
3  *
4  * Copyright (C) 2011 Renesas Solutions Corp.
5  * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6  *
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.
11  *
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
15  *
16  */
17 #include <linux/err.h>
18 #include <linux/io.h>
19 #include <linux/module.h>
20 #include <linux/pm_runtime.h>
21 #include <linux/slab.h>
22 #include <linux/sysfs.h>
23 #include "common.h"
24
25 /*
26  *              image of renesas_usbhs
27  *
28  * ex) gadget case
29
30  * mod.c
31  * mod_gadget.c
32  * mod_host.c           pipe.c          fifo.c
33  *
34  *                      +-------+       +-----------+
35  *                      | pipe0 |------>| fifo pio  |
36  * +------------+       +-------+       +-----------+
37  * | mod_gadget |=====> | pipe1 |--+
38  * +------------+       +-------+  |    +-----------+
39  *                      | pipe2 |  |  +-| fifo dma0 |
40  * +------------+       +-------+  |  | +-----------+
41  * | mod_host   |       | pipe3 |<-|--+
42  * +------------+       +-------+  |    +-----------+
43  *                      | ....  |  +--->| fifo dma1 |
44  *                      | ....  |       +-----------+
45  */
46
47
48 #define USBHSF_RUNTIME_PWCTRL   (1 << 0)
49
50 /* status */
51 #define usbhsc_flags_init(p)   do {(p)->flags = 0; } while (0)
52 #define usbhsc_flags_set(p, b) ((p)->flags |=  (b))
53 #define usbhsc_flags_clr(p, b) ((p)->flags &= ~(b))
54 #define usbhsc_flags_has(p, b) ((p)->flags &   (b))
55
56 /*
57  * platform call back
58  *
59  * renesas usb support platform callback function.
60  * Below macro call it.
61  * if platform doesn't have callback, it return 0 (no error)
62  */
63 #define usbhs_platform_call(priv, func, args...)\
64         (!(priv) ? -ENODEV :                    \
65          !((priv)->pfunc.func) ? 0 :            \
66          (priv)->pfunc.func(args))
67
68 /*
69  *              common functions
70  */
71 u16 usbhs_read(struct usbhs_priv *priv, u32 reg)
72 {
73         return ioread16(priv->base + reg);
74 }
75
76 void usbhs_write(struct usbhs_priv *priv, u32 reg, u16 data)
77 {
78         iowrite16(data, priv->base + reg);
79 }
80
81 void usbhs_bset(struct usbhs_priv *priv, u32 reg, u16 mask, u16 data)
82 {
83         u16 val = usbhs_read(priv, reg);
84
85         val &= ~mask;
86         val |= data & mask;
87
88         usbhs_write(priv, reg, val);
89 }
90
91 struct usbhs_priv *usbhs_pdev_to_priv(struct platform_device *pdev)
92 {
93         return dev_get_drvdata(&pdev->dev);
94 }
95
96 /*
97  *              syscfg functions
98  */
99 static void usbhs_sys_clock_ctrl(struct usbhs_priv *priv, int enable)
100 {
101         usbhs_bset(priv, SYSCFG, SCKE, enable ? SCKE : 0);
102 }
103
104 void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable)
105 {
106         u16 mask = DCFM | DRPD | DPRPU | HSE | USBE;
107         u16 val  = DCFM | DRPD | HSE | USBE;
108         int has_otg = usbhs_get_dparam(priv, has_otg);
109
110         if (has_otg)
111                 usbhs_bset(priv, DVSTCTR, (EXTLP | PWEN), (EXTLP | PWEN));
112
113         /*
114          * if enable
115          *
116          * - select Host mode
117          * - D+ Line/D- Line Pull-down
118          */
119         usbhs_bset(priv, SYSCFG, mask, enable ? val : 0);
120 }
121
122 void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable)
123 {
124         u16 mask = DCFM | DRPD | DPRPU | HSE | USBE;
125         u16 val  = DPRPU | HSE | USBE;
126
127         /*
128          * if enable
129          *
130          * - select Function mode
131          * - D+ Line Pull-up
132          */
133         usbhs_bset(priv, SYSCFG, mask, enable ? val : 0);
134 }
135
136 void usbhs_sys_function_pullup(struct usbhs_priv *priv, int enable)
137 {
138         usbhs_bset(priv, SYSCFG, DPRPU, enable ? DPRPU : 0);
139 }
140
141 void usbhs_sys_set_test_mode(struct usbhs_priv *priv, u16 mode)
142 {
143         usbhs_write(priv, TESTMODE, mode);
144 }
145
146 /*
147  *              frame functions
148  */
149 int usbhs_frame_get_num(struct usbhs_priv *priv)
150 {
151         return usbhs_read(priv, FRMNUM) & FRNM_MASK;
152 }
153
154 /*
155  *              usb request functions
156  */
157 void usbhs_usbreq_get_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req)
158 {
159         u16 val;
160
161         val = usbhs_read(priv, USBREQ);
162         req->bRequest           = (val >> 8) & 0xFF;
163         req->bRequestType       = (val >> 0) & 0xFF;
164
165         req->wValue     = usbhs_read(priv, USBVAL);
166         req->wIndex     = usbhs_read(priv, USBINDX);
167         req->wLength    = usbhs_read(priv, USBLENG);
168 }
169
170 void usbhs_usbreq_set_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req)
171 {
172         usbhs_write(priv, USBREQ,  (req->bRequest << 8) | req->bRequestType);
173         usbhs_write(priv, USBVAL,  req->wValue);
174         usbhs_write(priv, USBINDX, req->wIndex);
175         usbhs_write(priv, USBLENG, req->wLength);
176
177         usbhs_bset(priv, DCPCTR, SUREQ, SUREQ);
178 }
179
180 /*
181  *              bus/vbus functions
182  */
183 void usbhs_bus_send_sof_enable(struct usbhs_priv *priv)
184 {
185         u16 status = usbhs_read(priv, DVSTCTR) & (USBRST | UACT);
186
187         if (status != USBRST) {
188                 struct device *dev = usbhs_priv_to_dev(priv);
189                 dev_err(dev, "usbhs should be reset\n");
190         }
191
192         usbhs_bset(priv, DVSTCTR, (USBRST | UACT), UACT);
193 }
194
195 void usbhs_bus_send_reset(struct usbhs_priv *priv)
196 {
197         usbhs_bset(priv, DVSTCTR, (USBRST | UACT), USBRST);
198 }
199
200 int usbhs_bus_get_speed(struct usbhs_priv *priv)
201 {
202         u16 dvstctr = usbhs_read(priv, DVSTCTR);
203
204         switch (RHST & dvstctr) {
205         case RHST_LOW_SPEED:
206                 return USB_SPEED_LOW;
207         case RHST_FULL_SPEED:
208                 return USB_SPEED_FULL;
209         case RHST_HIGH_SPEED:
210                 return USB_SPEED_HIGH;
211         }
212
213         return USB_SPEED_UNKNOWN;
214 }
215
216 int usbhs_vbus_ctrl(struct usbhs_priv *priv, int enable)
217 {
218         struct platform_device *pdev = usbhs_priv_to_pdev(priv);
219
220         return usbhs_platform_call(priv, set_vbus, pdev, enable);
221 }
222
223 static void usbhsc_bus_init(struct usbhs_priv *priv)
224 {
225         usbhs_write(priv, DVSTCTR, 0);
226
227         usbhs_vbus_ctrl(priv, 0);
228 }
229
230 /*
231  *              device configuration
232  */
233 int usbhs_set_device_config(struct usbhs_priv *priv, int devnum,
234                            u16 upphub, u16 hubport, u16 speed)
235 {
236         struct device *dev = usbhs_priv_to_dev(priv);
237         u16 usbspd = 0;
238         u32 reg = DEVADD0 + (2 * devnum);
239
240         if (devnum > 10) {
241                 dev_err(dev, "cannot set speed to unknown device %d\n", devnum);
242                 return -EIO;
243         }
244
245         if (upphub > 0xA) {
246                 dev_err(dev, "unsupported hub number %d\n", upphub);
247                 return -EIO;
248         }
249
250         switch (speed) {
251         case USB_SPEED_LOW:
252                 usbspd = USBSPD_SPEED_LOW;
253                 break;
254         case USB_SPEED_FULL:
255                 usbspd = USBSPD_SPEED_FULL;
256                 break;
257         case USB_SPEED_HIGH:
258                 usbspd = USBSPD_SPEED_HIGH;
259                 break;
260         default:
261                 dev_err(dev, "unsupported speed %d\n", speed);
262                 return -EIO;
263         }
264
265         usbhs_write(priv, reg,  UPPHUB(upphub)  |
266                                 HUBPORT(hubport)|
267                                 USBSPD(usbspd));
268
269         return 0;
270 }
271
272 /*
273  *              local functions
274  */
275 static void usbhsc_set_buswait(struct usbhs_priv *priv)
276 {
277         int wait = usbhs_get_dparam(priv, buswait_bwait);
278
279         /* set bus wait if platform have */
280         if (wait)
281                 usbhs_bset(priv, BUSWAIT, 0x000F, wait);
282 }
283
284 /*
285  *              platform default param
286  */
287 static u32 usbhsc_default_pipe_type[] = {
288                 USB_ENDPOINT_XFER_CONTROL,
289                 USB_ENDPOINT_XFER_ISOC,
290                 USB_ENDPOINT_XFER_ISOC,
291                 USB_ENDPOINT_XFER_BULK,
292                 USB_ENDPOINT_XFER_BULK,
293                 USB_ENDPOINT_XFER_BULK,
294                 USB_ENDPOINT_XFER_INT,
295                 USB_ENDPOINT_XFER_INT,
296                 USB_ENDPOINT_XFER_INT,
297                 USB_ENDPOINT_XFER_INT,
298 };
299
300 /*
301  *              power control
302  */
303 static void usbhsc_power_ctrl(struct usbhs_priv *priv, int enable)
304 {
305         struct platform_device *pdev = usbhs_priv_to_pdev(priv);
306         struct device *dev = usbhs_priv_to_dev(priv);
307
308         if (enable) {
309                 /* enable PM */
310                 pm_runtime_get_sync(dev);
311
312                 /* enable platform power */
313                 usbhs_platform_call(priv, power_ctrl, pdev, priv->base, enable);
314
315                 /* USB on */
316                 usbhs_sys_clock_ctrl(priv, enable);
317         } else {
318                 /* USB off */
319                 usbhs_sys_clock_ctrl(priv, enable);
320
321                 /* disable platform power */
322                 usbhs_platform_call(priv, power_ctrl, pdev, priv->base, enable);
323
324                 /* disable PM */
325                 pm_runtime_put_sync(dev);
326         }
327 }
328
329 /*
330  *              hotplug
331  */
332 static void usbhsc_hotplug(struct usbhs_priv *priv)
333 {
334         struct platform_device *pdev = usbhs_priv_to_pdev(priv);
335         struct usbhs_mod *mod = usbhs_mod_get_current(priv);
336         int id;
337         int enable;
338         int ret;
339
340         /*
341          * get vbus status from platform
342          */
343         enable = usbhs_platform_call(priv, get_vbus, pdev);
344
345         /*
346          * get id from platform
347          */
348         id = usbhs_platform_call(priv, get_id, pdev);
349
350         if (enable && !mod) {
351                 ret = usbhs_mod_change(priv, id);
352                 if (ret < 0)
353                         return;
354
355                 dev_dbg(&pdev->dev, "%s enable\n", __func__);
356
357                 /* power on */
358                 if (usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL))
359                         usbhsc_power_ctrl(priv, enable);
360
361                 /* bus init */
362                 usbhsc_set_buswait(priv);
363                 usbhsc_bus_init(priv);
364
365                 /* module start */
366                 usbhs_mod_call(priv, start, priv);
367
368         } else if (!enable && mod) {
369                 dev_dbg(&pdev->dev, "%s disable\n", __func__);
370
371                 /* module stop */
372                 usbhs_mod_call(priv, stop, priv);
373
374                 /* bus init */
375                 usbhsc_bus_init(priv);
376
377                 /* power off */
378                 if (usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL))
379                         usbhsc_power_ctrl(priv, enable);
380
381                 usbhs_mod_change(priv, -1);
382
383                 /* reset phy for next connection */
384                 usbhs_platform_call(priv, phy_reset, pdev);
385         }
386 }
387
388 /*
389  *              notify hotplug
390  */
391 static void usbhsc_notify_hotplug(struct work_struct *work)
392 {
393         struct usbhs_priv *priv = container_of(work,
394                                                struct usbhs_priv,
395                                                notify_hotplug_work.work);
396         usbhsc_hotplug(priv);
397 }
398
399 static int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev)
400 {
401         struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev);
402         int delay = usbhs_get_dparam(priv, detection_delay);
403
404         /*
405          * This functions will be called in interrupt.
406          * To make sure safety context,
407          * use workqueue for usbhs_notify_hotplug
408          */
409         schedule_delayed_work(&priv->notify_hotplug_work,
410                               msecs_to_jiffies(delay));
411         return 0;
412 }
413
414 /*
415  *              platform functions
416  */
417 static int usbhs_probe(struct platform_device *pdev)
418 {
419         struct renesas_usbhs_platform_info *info = dev_get_platdata(&pdev->dev);
420         struct renesas_usbhs_driver_callback *dfunc;
421         struct usbhs_priv *priv;
422         struct resource *res, *irq_res;
423         int ret;
424
425         /* check platform information */
426         if (!info ||
427             !info->platform_callback.get_id) {
428                 dev_err(&pdev->dev, "no platform information\n");
429                 return -EINVAL;
430         }
431
432         /* platform data */
433         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
434         irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
435         if (!res || !irq_res) {
436                 dev_err(&pdev->dev, "Not enough Renesas USB platform resources.\n");
437                 return -ENODEV;
438         }
439
440         /* usb private data */
441         priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
442         if (!priv) {
443                 dev_err(&pdev->dev, "Could not allocate priv\n");
444                 return -ENOMEM;
445         }
446
447         priv->base = devm_ioremap_resource(&pdev->dev, res);
448         if (IS_ERR(priv->base))
449                 return PTR_ERR(priv->base);
450
451         /*
452          * care platform info
453          */
454         memcpy(&priv->pfunc,
455                &info->platform_callback,
456                sizeof(struct renesas_usbhs_platform_callback));
457         memcpy(&priv->dparam,
458                &info->driver_param,
459                sizeof(struct renesas_usbhs_driver_param));
460
461         /* set driver callback functions for platform */
462         dfunc                   = &info->driver_callback;
463         dfunc->notify_hotplug   = usbhsc_drvcllbck_notify_hotplug;
464
465         /* set default param if platform doesn't have */
466         if (!priv->dparam.pipe_type) {
467                 priv->dparam.pipe_type = usbhsc_default_pipe_type;
468                 priv->dparam.pipe_size = ARRAY_SIZE(usbhsc_default_pipe_type);
469         }
470         if (!priv->dparam.pio_dma_border)
471                 priv->dparam.pio_dma_border = 64; /* 64byte */
472
473         /* FIXME */
474         /* runtime power control ? */
475         if (priv->pfunc.get_vbus)
476                 usbhsc_flags_set(priv, USBHSF_RUNTIME_PWCTRL);
477
478         /*
479          * priv settings
480          */
481         priv->irq       = irq_res->start;
482         if (irq_res->flags & IORESOURCE_IRQ_SHAREABLE)
483                 priv->irqflags = IRQF_SHARED;
484         priv->pdev      = pdev;
485         INIT_DELAYED_WORK(&priv->notify_hotplug_work, usbhsc_notify_hotplug);
486         spin_lock_init(usbhs_priv_to_lock(priv));
487
488         /* call pipe and module init */
489         ret = usbhs_pipe_probe(priv);
490         if (ret < 0)
491                 return ret;
492
493         ret = usbhs_fifo_probe(priv);
494         if (ret < 0)
495                 goto probe_end_pipe_exit;
496
497         ret = usbhs_mod_probe(priv);
498         if (ret < 0)
499                 goto probe_end_fifo_exit;
500
501         /* dev_set_drvdata should be called after usbhs_mod_init */
502         platform_set_drvdata(pdev, priv);
503
504         /*
505          * deviece reset here because
506          * USB device might be used in boot loader.
507          */
508         usbhs_sys_clock_ctrl(priv, 0);
509
510         /*
511          * platform call
512          *
513          * USB phy setup might depend on CPU/Board.
514          * If platform has its callback functions,
515          * call it here.
516          */
517         ret = usbhs_platform_call(priv, hardware_init, pdev);
518         if (ret < 0) {
519                 dev_err(&pdev->dev, "platform prove failed.\n");
520                 goto probe_end_mod_exit;
521         }
522
523         /* reset phy for connection */
524         usbhs_platform_call(priv, phy_reset, pdev);
525
526         /* power control */
527         pm_runtime_enable(&pdev->dev);
528         if (!usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL)) {
529                 usbhsc_power_ctrl(priv, 1);
530                 usbhs_mod_autonomy_mode(priv);
531         }
532
533         /*
534          * manual call notify_hotplug for cold plug
535          */
536         ret = usbhsc_drvcllbck_notify_hotplug(pdev);
537         if (ret < 0)
538                 goto probe_end_call_remove;
539
540         dev_info(&pdev->dev, "probed\n");
541
542         return ret;
543
544 probe_end_call_remove:
545         usbhs_platform_call(priv, hardware_exit, pdev);
546 probe_end_mod_exit:
547         usbhs_mod_remove(priv);
548 probe_end_fifo_exit:
549         usbhs_fifo_remove(priv);
550 probe_end_pipe_exit:
551         usbhs_pipe_remove(priv);
552
553         dev_info(&pdev->dev, "probe failed\n");
554
555         return ret;
556 }
557
558 static int usbhs_remove(struct platform_device *pdev)
559 {
560         struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev);
561         struct renesas_usbhs_platform_info *info = dev_get_platdata(&pdev->dev);
562         struct renesas_usbhs_driver_callback *dfunc = &info->driver_callback;
563
564         dev_dbg(&pdev->dev, "usb remove\n");
565
566         dfunc->notify_hotplug = NULL;
567
568         /* power off */
569         if (!usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL))
570                 usbhsc_power_ctrl(priv, 0);
571
572         pm_runtime_disable(&pdev->dev);
573
574         usbhs_platform_call(priv, hardware_exit, pdev);
575         usbhs_mod_remove(priv);
576         usbhs_fifo_remove(priv);
577         usbhs_pipe_remove(priv);
578
579         return 0;
580 }
581
582 static int usbhsc_suspend(struct device *dev)
583 {
584         struct usbhs_priv *priv = dev_get_drvdata(dev);
585         struct usbhs_mod *mod = usbhs_mod_get_current(priv);
586
587         if (mod) {
588                 usbhs_mod_call(priv, stop, priv);
589                 usbhs_mod_change(priv, -1);
590         }
591
592         if (mod || !usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL))
593                 usbhsc_power_ctrl(priv, 0);
594
595         return 0;
596 }
597
598 static int usbhsc_resume(struct device *dev)
599 {
600         struct usbhs_priv *priv = dev_get_drvdata(dev);
601         struct platform_device *pdev = usbhs_priv_to_pdev(priv);
602
603         if (!usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL))
604                 usbhsc_power_ctrl(priv, 1);
605
606         usbhs_platform_call(priv, phy_reset, pdev);
607
608         usbhsc_drvcllbck_notify_hotplug(pdev);
609
610         return 0;
611 }
612
613 static int usbhsc_runtime_nop(struct device *dev)
614 {
615         /* Runtime PM callback shared between ->runtime_suspend()
616          * and ->runtime_resume(). Simply returns success.
617          *
618          * This driver re-initializes all registers after
619          * pm_runtime_get_sync() anyway so there is no need
620          * to save and restore registers here.
621          */
622         return 0;
623 }
624
625 static const struct dev_pm_ops usbhsc_pm_ops = {
626         .suspend                = usbhsc_suspend,
627         .resume                 = usbhsc_resume,
628         .runtime_suspend        = usbhsc_runtime_nop,
629         .runtime_resume         = usbhsc_runtime_nop,
630 };
631
632 static struct platform_driver renesas_usbhs_driver = {
633         .driver         = {
634                 .name   = "renesas_usbhs",
635                 .pm     = &usbhsc_pm_ops,
636         },
637         .probe          = usbhs_probe,
638         .remove         = usbhs_remove,
639 };
640
641 module_platform_driver(renesas_usbhs_driver);
642
643 MODULE_LICENSE("GPL");
644 MODULE_DESCRIPTION("Renesas USB driver");
645 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");