Version:  2.0.40 2.2.26 2.4.37 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16

Linux/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>");
646 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us