linux/drivers/usb/host/ohci-da8xx.c
<<
>>
Prefs
   1/*
   2 * OHCI HCD (Host Controller Driver) for USB.
   3 *
   4 * TI DA8xx (OMAP-L1x) Bus Glue
   5 *
   6 * Derived from: ohci-omap.c and ohci-s3c2410.c
   7 * Copyright (C) 2008-2009 MontaVista Software, Inc. <source@mvista.com>
   8 *
   9 * This file is licensed under the terms of the GNU General Public License
  10 * version 2. This program is licensed "as is" without any warranty of any
  11 * kind, whether express or implied.
  12 */
  13
  14#include <linux/clk.h>
  15#include <linux/io.h>
  16#include <linux/interrupt.h>
  17#include <linux/jiffies.h>
  18#include <linux/kernel.h>
  19#include <linux/module.h>
  20#include <linux/platform_device.h>
  21#include <linux/phy/phy.h>
  22#include <linux/platform_data/usb-davinci.h>
  23#include <linux/regulator/consumer.h>
  24#include <linux/usb.h>
  25#include <linux/usb/hcd.h>
  26#include <asm/unaligned.h>
  27
  28#include "ohci.h"
  29
  30#define DRIVER_DESC "DA8XX"
  31#define DRV_NAME "ohci-da8xx"
  32
  33static struct hc_driver __read_mostly ohci_da8xx_hc_driver;
  34
  35static int (*orig_ohci_hub_control)(struct usb_hcd  *hcd, u16 typeReq,
  36                        u16 wValue, u16 wIndex, char *buf, u16 wLength);
  37static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char *buf);
  38
  39struct da8xx_ohci_hcd {
  40        struct usb_hcd *hcd;
  41        struct clk *usb11_clk;
  42        struct phy *usb11_phy;
  43        struct regulator *vbus_reg;
  44        struct notifier_block nb;
  45        unsigned int reg_enabled;
  46};
  47
  48#define to_da8xx_ohci(hcd) (struct da8xx_ohci_hcd *)(hcd_to_ohci(hcd)->priv)
  49
  50/* Over-current indicator change bitmask */
  51static volatile u16 ocic_mask;
  52
  53static int ohci_da8xx_enable(struct usb_hcd *hcd)
  54{
  55        struct da8xx_ohci_hcd *da8xx_ohci = to_da8xx_ohci(hcd);
  56        int ret;
  57
  58        ret = clk_prepare_enable(da8xx_ohci->usb11_clk);
  59        if (ret)
  60                return ret;
  61
  62        ret = phy_init(da8xx_ohci->usb11_phy);
  63        if (ret)
  64                goto err_phy_init;
  65
  66        ret = phy_power_on(da8xx_ohci->usb11_phy);
  67        if (ret)
  68                goto err_phy_power_on;
  69
  70        return 0;
  71
  72err_phy_power_on:
  73        phy_exit(da8xx_ohci->usb11_phy);
  74err_phy_init:
  75        clk_disable_unprepare(da8xx_ohci->usb11_clk);
  76
  77        return ret;
  78}
  79
  80static void ohci_da8xx_disable(struct usb_hcd *hcd)
  81{
  82        struct da8xx_ohci_hcd *da8xx_ohci = to_da8xx_ohci(hcd);
  83
  84        phy_power_off(da8xx_ohci->usb11_phy);
  85        phy_exit(da8xx_ohci->usb11_phy);
  86        clk_disable_unprepare(da8xx_ohci->usb11_clk);
  87}
  88
  89static int ohci_da8xx_set_power(struct usb_hcd *hcd, int on)
  90{
  91        struct da8xx_ohci_hcd *da8xx_ohci = to_da8xx_ohci(hcd);
  92        struct device *dev              = hcd->self.controller;
  93        struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
  94        int ret;
  95
  96        if (hub && hub->set_power)
  97                return hub->set_power(1, on);
  98
  99        if (!da8xx_ohci->vbus_reg)
 100                return 0;
 101
 102        if (on && !da8xx_ohci->reg_enabled) {
 103                ret = regulator_enable(da8xx_ohci->vbus_reg);
 104                if (ret) {
 105                        dev_err(dev, "Failed to enable regulator: %d\n", ret);
 106                        return ret;
 107                }
 108                da8xx_ohci->reg_enabled = 1;
 109
 110        } else if (!on && da8xx_ohci->reg_enabled) {
 111                ret = regulator_disable(da8xx_ohci->vbus_reg);
 112                if (ret) {
 113                        dev_err(dev, "Failed  to disable regulator: %d\n", ret);
 114                        return ret;
 115                }
 116                da8xx_ohci->reg_enabled = 0;
 117        }
 118
 119        return 0;
 120}
 121
 122static int ohci_da8xx_get_power(struct usb_hcd *hcd)
 123{
 124        struct da8xx_ohci_hcd *da8xx_ohci = to_da8xx_ohci(hcd);
 125        struct device *dev              = hcd->self.controller;
 126        struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
 127
 128        if (hub && hub->get_power)
 129                return hub->get_power(1);
 130
 131        if (da8xx_ohci->vbus_reg)
 132                return regulator_is_enabled(da8xx_ohci->vbus_reg);
 133
 134        return 1;
 135}
 136
 137static int ohci_da8xx_get_oci(struct usb_hcd *hcd)
 138{
 139        struct da8xx_ohci_hcd *da8xx_ohci = to_da8xx_ohci(hcd);
 140        struct device *dev              = hcd->self.controller;
 141        struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
 142        unsigned int flags;
 143        int ret;
 144
 145        if (hub && hub->get_oci)
 146                return hub->get_oci(1);
 147
 148        if (!da8xx_ohci->vbus_reg)
 149                return 0;
 150
 151        ret = regulator_get_error_flags(da8xx_ohci->vbus_reg, &flags);
 152        if (ret)
 153                return ret;
 154
 155        if (flags & REGULATOR_ERROR_OVER_CURRENT)
 156                return 1;
 157
 158        return 0;
 159}
 160
 161static int ohci_da8xx_has_set_power(struct usb_hcd *hcd)
 162{
 163        struct da8xx_ohci_hcd *da8xx_ohci = to_da8xx_ohci(hcd);
 164        struct device *dev              = hcd->self.controller;
 165        struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
 166
 167        if (hub && hub->set_power)
 168                return 1;
 169
 170        if (da8xx_ohci->vbus_reg)
 171                return 1;
 172
 173        return 0;
 174}
 175
 176static int ohci_da8xx_has_oci(struct usb_hcd *hcd)
 177{
 178        struct da8xx_ohci_hcd *da8xx_ohci = to_da8xx_ohci(hcd);
 179        struct device *dev              = hcd->self.controller;
 180        struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
 181
 182        if (hub && hub->get_oci)
 183                return 1;
 184
 185        if (da8xx_ohci->vbus_reg)
 186                return 1;
 187
 188        return 0;
 189}
 190
 191static int ohci_da8xx_has_potpgt(struct usb_hcd *hcd)
 192{
 193        struct device *dev              = hcd->self.controller;
 194        struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
 195
 196        if (hub && hub->potpgt)
 197                return 1;
 198
 199        return 0;
 200}
 201
 202/*
 203 * Handle the port over-current indicator change.
 204 */
 205static void ohci_da8xx_ocic_handler(struct da8xx_ohci_root_hub *hub,
 206                                    unsigned port)
 207{
 208        ocic_mask |= 1 << port;
 209
 210        /* Once over-current is detected, the port needs to be powered down */
 211        if (hub->get_oci(port) > 0)
 212                hub->set_power(port, 0);
 213}
 214
 215static int ohci_da8xx_regulator_event(struct notifier_block *nb,
 216                                unsigned long event, void *data)
 217{
 218        struct da8xx_ohci_hcd *da8xx_ohci =
 219                                container_of(nb, struct da8xx_ohci_hcd, nb);
 220
 221        if (event & REGULATOR_EVENT_OVER_CURRENT) {
 222                ocic_mask |= 1 << 1;
 223                ohci_da8xx_set_power(da8xx_ohci->hcd, 0);
 224        }
 225
 226        return 0;
 227}
 228
 229static int ohci_da8xx_register_notify(struct usb_hcd *hcd)
 230{
 231        struct da8xx_ohci_hcd *da8xx_ohci = to_da8xx_ohci(hcd);
 232        struct device *dev              = hcd->self.controller;
 233        struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
 234        int ret = 0;
 235
 236        if (hub && hub->ocic_notify) {
 237                ret = hub->ocic_notify(ohci_da8xx_ocic_handler);
 238        } else if (da8xx_ohci->vbus_reg) {
 239                da8xx_ohci->nb.notifier_call = ohci_da8xx_regulator_event;
 240                ret = devm_regulator_register_notifier(da8xx_ohci->vbus_reg,
 241                                                &da8xx_ohci->nb);
 242        }
 243
 244        if (ret)
 245                dev_err(dev, "Failed to register notifier: %d\n", ret);
 246
 247        return ret;
 248}
 249
 250static void ohci_da8xx_unregister_notify(struct usb_hcd *hcd)
 251{
 252        struct device *dev              = hcd->self.controller;
 253        struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
 254
 255        if (hub && hub->ocic_notify)
 256                hub->ocic_notify(NULL);
 257}
 258
 259static int ohci_da8xx_reset(struct usb_hcd *hcd)
 260{
 261        struct device *dev              = hcd->self.controller;
 262        struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
 263        struct ohci_hcd *ohci           = hcd_to_ohci(hcd);
 264        int result;
 265        u32 rh_a;
 266
 267        dev_dbg(dev, "starting USB controller\n");
 268
 269        result = ohci_da8xx_enable(hcd);
 270        if (result < 0)
 271                return result;
 272
 273        /*
 274         * DA8xx only have 1 port connected to the pins but the HC root hub
 275         * register A reports 2 ports, thus we'll have to override it...
 276         */
 277        ohci->num_ports = 1;
 278
 279        result = ohci_setup(hcd);
 280        if (result < 0) {
 281                ohci_da8xx_disable(hcd);
 282                return result;
 283        }
 284
 285        /*
 286         * Since we're providing a board-specific root hub port power control
 287         * and over-current reporting, we have to override the HC root hub A
 288         * register's default value, so that ohci_hub_control() could return
 289         * the correct hub descriptor...
 290         */
 291        rh_a = ohci_readl(ohci, &ohci->regs->roothub.a);
 292        if (ohci_da8xx_has_set_power(hcd)) {
 293                rh_a &= ~RH_A_NPS;
 294                rh_a |=  RH_A_PSM;
 295        }
 296        if (ohci_da8xx_has_oci(hcd)) {
 297                rh_a &= ~RH_A_NOCP;
 298                rh_a |=  RH_A_OCPM;
 299        }
 300        if (ohci_da8xx_has_potpgt(hcd)) {
 301                rh_a &= ~RH_A_POTPGT;
 302                rh_a |= hub->potpgt << 24;
 303        }
 304        ohci_writel(ohci, rh_a, &ohci->regs->roothub.a);
 305
 306        return result;
 307}
 308
 309/*
 310 * Update the status data from the hub with the over-current indicator change.
 311 */
 312static int ohci_da8xx_hub_status_data(struct usb_hcd *hcd, char *buf)
 313{
 314        int length              = orig_ohci_hub_status_data(hcd, buf);
 315
 316        /* See if we have OCIC bit set on port 1 */
 317        if (ocic_mask & (1 << 1)) {
 318                dev_dbg(hcd->self.controller, "over-current indicator change "
 319                        "on port 1\n");
 320
 321                if (!length)
 322                        length = 1;
 323
 324                buf[0] |= 1 << 1;
 325        }
 326        return length;
 327}
 328
 329/*
 330 * Look at the control requests to the root hub and see if we need to override.
 331 */
 332static int ohci_da8xx_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 333                                  u16 wIndex, char *buf, u16 wLength)
 334{
 335        struct device *dev              = hcd->self.controller;
 336        int temp;
 337
 338        switch (typeReq) {
 339        case GetPortStatus:
 340                /* Check the port number */
 341                if (wIndex != 1)
 342                        break;
 343
 344                dev_dbg(dev, "GetPortStatus(%u)\n", wIndex);
 345
 346                temp = roothub_portstatus(hcd_to_ohci(hcd), wIndex - 1);
 347
 348                /* The port power status (PPS) bit defaults to 1 */
 349                if (!ohci_da8xx_get_power(hcd))
 350                        temp &= ~RH_PS_PPS;
 351
 352                /* The port over-current indicator (POCI) bit is always 0 */
 353                if (ohci_da8xx_get_oci(hcd) > 0)
 354                        temp |=  RH_PS_POCI;
 355
 356                /* The over-current indicator change (OCIC) bit is 0 too */
 357                if (ocic_mask & (1 << wIndex))
 358                        temp |=  RH_PS_OCIC;
 359
 360                put_unaligned(cpu_to_le32(temp), (__le32 *)buf);
 361                return 0;
 362        case SetPortFeature:
 363                temp = 1;
 364                goto check_port;
 365        case ClearPortFeature:
 366                temp = 0;
 367
 368check_port:
 369                /* Check the port number */
 370                if (wIndex != 1)
 371                        break;
 372
 373                switch (wValue) {
 374                case USB_PORT_FEAT_POWER:
 375                        dev_dbg(dev, "%sPortFeature(%u): %s\n",
 376                                temp ? "Set" : "Clear", wIndex, "POWER");
 377
 378                        return ohci_da8xx_set_power(hcd, temp) ? -EPIPE : 0;
 379                case USB_PORT_FEAT_C_OVER_CURRENT:
 380                        dev_dbg(dev, "%sPortFeature(%u): %s\n",
 381                                temp ? "Set" : "Clear", wIndex,
 382                                "C_OVER_CURRENT");
 383
 384                        if (temp)
 385                                ocic_mask |= 1 << wIndex;
 386                        else
 387                                ocic_mask &= ~(1 << wIndex);
 388                        return 0;
 389                }
 390        }
 391
 392        return orig_ohci_hub_control(hcd, typeReq, wValue,
 393                        wIndex, buf, wLength);
 394}
 395
 396/*-------------------------------------------------------------------------*/
 397#ifdef CONFIG_OF
 398static const struct of_device_id da8xx_ohci_ids[] = {
 399        { .compatible = "ti,da830-ohci" },
 400        { }
 401};
 402MODULE_DEVICE_TABLE(of, da8xx_ohci_ids);
 403#endif
 404
 405static int ohci_da8xx_probe(struct platform_device *pdev)
 406{
 407        struct da8xx_ohci_hcd *da8xx_ohci;
 408        struct usb_hcd  *hcd;
 409        struct resource *mem;
 410        int error, irq;
 411        hcd = usb_create_hcd(&ohci_da8xx_hc_driver, &pdev->dev,
 412                                dev_name(&pdev->dev));
 413        if (!hcd)
 414                return -ENOMEM;
 415
 416        da8xx_ohci = to_da8xx_ohci(hcd);
 417        da8xx_ohci->hcd = hcd;
 418
 419        da8xx_ohci->usb11_clk = devm_clk_get(&pdev->dev, "usb11");
 420        if (IS_ERR(da8xx_ohci->usb11_clk)) {
 421                error = PTR_ERR(da8xx_ohci->usb11_clk);
 422                if (error != -EPROBE_DEFER)
 423                        dev_err(&pdev->dev, "Failed to get clock.\n");
 424                goto err;
 425        }
 426
 427        da8xx_ohci->usb11_phy = devm_phy_get(&pdev->dev, "usb-phy");
 428        if (IS_ERR(da8xx_ohci->usb11_phy)) {
 429                error = PTR_ERR(da8xx_ohci->usb11_phy);
 430                if (error != -EPROBE_DEFER)
 431                        dev_err(&pdev->dev, "Failed to get phy.\n");
 432                goto err;
 433        }
 434
 435        da8xx_ohci->vbus_reg = devm_regulator_get_optional(&pdev->dev, "vbus");
 436        if (IS_ERR(da8xx_ohci->vbus_reg)) {
 437                error = PTR_ERR(da8xx_ohci->vbus_reg);
 438                if (error == -ENODEV) {
 439                        da8xx_ohci->vbus_reg = NULL;
 440                } else if (error == -EPROBE_DEFER) {
 441                        goto err;
 442                } else {
 443                        dev_err(&pdev->dev, "Failed to get regulator\n");
 444                        goto err;
 445                }
 446        }
 447
 448        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 449        hcd->regs = devm_ioremap_resource(&pdev->dev, mem);
 450        if (IS_ERR(hcd->regs)) {
 451                error = PTR_ERR(hcd->regs);
 452                goto err;
 453        }
 454        hcd->rsrc_start = mem->start;
 455        hcd->rsrc_len = resource_size(mem);
 456
 457        irq = platform_get_irq(pdev, 0);
 458        if (irq < 0) {
 459                error = -ENODEV;
 460                goto err;
 461        }
 462
 463        error = usb_add_hcd(hcd, irq, 0);
 464        if (error)
 465                goto err;
 466
 467        device_wakeup_enable(hcd->self.controller);
 468
 469        error = ohci_da8xx_register_notify(hcd);
 470        if (error)
 471                goto err_remove_hcd;
 472
 473        return 0;
 474
 475err_remove_hcd:
 476        usb_remove_hcd(hcd);
 477err:
 478        usb_put_hcd(hcd);
 479        return error;
 480}
 481
 482static int ohci_da8xx_remove(struct platform_device *pdev)
 483{
 484        struct usb_hcd  *hcd = platform_get_drvdata(pdev);
 485
 486        ohci_da8xx_unregister_notify(hcd);
 487        usb_remove_hcd(hcd);
 488        usb_put_hcd(hcd);
 489
 490        return 0;
 491}
 492
 493#ifdef CONFIG_PM
 494static int ohci_da8xx_suspend(struct platform_device *pdev,
 495                                pm_message_t message)
 496{
 497        struct usb_hcd  *hcd    = platform_get_drvdata(pdev);
 498        struct ohci_hcd *ohci   = hcd_to_ohci(hcd);
 499        bool            do_wakeup       = device_may_wakeup(&pdev->dev);
 500        int             ret;
 501
 502
 503        if (time_before(jiffies, ohci->next_statechange))
 504                msleep(5);
 505        ohci->next_statechange = jiffies;
 506
 507        ret = ohci_suspend(hcd, do_wakeup);
 508        if (ret)
 509                return ret;
 510
 511        ohci_da8xx_disable(hcd);
 512        hcd->state = HC_STATE_SUSPENDED;
 513
 514        return ret;
 515}
 516
 517static int ohci_da8xx_resume(struct platform_device *dev)
 518{
 519        struct usb_hcd  *hcd    = platform_get_drvdata(dev);
 520        struct ohci_hcd *ohci   = hcd_to_ohci(hcd);
 521        int ret;
 522
 523        if (time_before(jiffies, ohci->next_statechange))
 524                msleep(5);
 525        ohci->next_statechange = jiffies;
 526
 527        ret = ohci_da8xx_enable(hcd);
 528        if (ret)
 529                return ret;
 530
 531        ohci_resume(hcd, false);
 532
 533        return 0;
 534}
 535#endif
 536
 537static const struct ohci_driver_overrides da8xx_overrides __initconst = {
 538        .reset           = ohci_da8xx_reset,
 539        .extra_priv_size = sizeof(struct da8xx_ohci_hcd),
 540};
 541
 542/*
 543 * Driver definition to register with platform structure.
 544 */
 545static struct platform_driver ohci_hcd_da8xx_driver = {
 546        .probe          = ohci_da8xx_probe,
 547        .remove         = ohci_da8xx_remove,
 548        .shutdown       = usb_hcd_platform_shutdown,
 549#ifdef  CONFIG_PM
 550        .suspend        = ohci_da8xx_suspend,
 551        .resume         = ohci_da8xx_resume,
 552#endif
 553        .driver         = {
 554                .name   = DRV_NAME,
 555                .of_match_table = of_match_ptr(da8xx_ohci_ids),
 556        },
 557};
 558
 559static int __init ohci_da8xx_init(void)
 560{
 561
 562        if (usb_disabled())
 563                return -ENODEV;
 564
 565        pr_info("%s: " DRIVER_DESC "\n", DRV_NAME);
 566        ohci_init_driver(&ohci_da8xx_hc_driver, &da8xx_overrides);
 567
 568        /*
 569         * The Davinci da8xx HW has some unusual quirks, which require
 570         * da8xx-specific workarounds. We override certain hc_driver
 571         * functions here to achieve that. We explicitly do not enhance
 572         * ohci_driver_overrides to allow this more easily, since this
 573         * is an unusual case, and we don't want to encourage others to
 574         * override these functions by making it too easy.
 575         */
 576
 577        orig_ohci_hub_control = ohci_da8xx_hc_driver.hub_control;
 578        orig_ohci_hub_status_data = ohci_da8xx_hc_driver.hub_status_data;
 579
 580        ohci_da8xx_hc_driver.hub_status_data     = ohci_da8xx_hub_status_data;
 581        ohci_da8xx_hc_driver.hub_control         = ohci_da8xx_hub_control;
 582
 583        return platform_driver_register(&ohci_hcd_da8xx_driver);
 584}
 585module_init(ohci_da8xx_init);
 586
 587static void __exit ohci_da8xx_exit(void)
 588{
 589        platform_driver_unregister(&ohci_hcd_da8xx_driver);
 590}
 591module_exit(ohci_da8xx_exit);
 592MODULE_DESCRIPTION(DRIVER_DESC);
 593MODULE_LICENSE("GPL");
 594MODULE_ALIAS("platform:" DRV_NAME);
 595