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