linux/drivers/usb/host/ohci-nxp.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * driver for NXP USB Host devices
   4 *
   5 * Currently supported OHCI host devices:
   6 * - NXP LPC32xx
   7 *
   8 * Authors: Dmitry Chigirev <source@mvista.com>
   9 *          Vitaly Wool <vitalywool@gmail.com>
  10 *
  11 * register initialization is based on code examples provided by Philips
  12 * Copyright (c) 2005 Koninklijke Philips Electronics N.V.
  13 *
  14 * NOTE: This driver does not have suspend/resume functionality
  15 * This driver is intended for engineering development purposes only
  16 *
  17 * 2005-2006 (c) MontaVista Software, Inc.
  18 */
  19#include <linux/clk.h>
  20#include <linux/dma-mapping.h>
  21#include <linux/io.h>
  22#include <linux/i2c.h>
  23#include <linux/module.h>
  24#include <linux/of.h>
  25#include <linux/platform_device.h>
  26#include <linux/usb/isp1301.h>
  27#include <linux/usb.h>
  28#include <linux/usb/hcd.h>
  29
  30#include "ohci.h"
  31
  32#include <mach/hardware.h>
  33
  34#define USB_CONFIG_BASE         0x31020000
  35#define USB_OTG_STAT_CONTROL    IO_ADDRESS(USB_CONFIG_BASE + 0x110)
  36
  37/* USB_OTG_STAT_CONTROL bit defines */
  38#define TRANSPARENT_I2C_EN      (1 << 7)
  39#define HOST_EN                 (1 << 0)
  40
  41/* On LPC32xx, those are undefined */
  42#ifndef start_int_set_falling_edge
  43#define start_int_set_falling_edge(irq)
  44#define start_int_set_rising_edge(irq)
  45#define start_int_ack(irq)
  46#define start_int_mask(irq)
  47#define start_int_umask(irq)
  48#endif
  49
  50#define DRIVER_DESC "OHCI NXP driver"
  51
  52static const char hcd_name[] = "ohci-nxp";
  53static struct hc_driver __read_mostly ohci_nxp_hc_driver;
  54
  55static struct i2c_client *isp1301_i2c_client;
  56
  57static struct clk *usb_host_clk;
  58
  59static void isp1301_configure_lpc32xx(void)
  60{
  61        /* LPC32XX only supports DAT_SE0 USB mode */
  62        /* This sequence is important */
  63
  64        /* Disable transparent UART mode first */
  65        i2c_smbus_write_byte_data(isp1301_i2c_client,
  66                (ISP1301_I2C_MODE_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR),
  67                MC1_UART_EN);
  68        i2c_smbus_write_byte_data(isp1301_i2c_client,
  69                (ISP1301_I2C_MODE_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR),
  70                ~MC1_SPEED_REG);
  71        i2c_smbus_write_byte_data(isp1301_i2c_client,
  72                                  ISP1301_I2C_MODE_CONTROL_1, MC1_SPEED_REG);
  73        i2c_smbus_write_byte_data(isp1301_i2c_client,
  74                  (ISP1301_I2C_MODE_CONTROL_2 | ISP1301_I2C_REG_CLEAR_ADDR),
  75                  ~0);
  76        i2c_smbus_write_byte_data(isp1301_i2c_client,
  77                ISP1301_I2C_MODE_CONTROL_2,
  78                (MC2_BI_DI | MC2_PSW_EN | MC2_SPD_SUSP_CTRL));
  79        i2c_smbus_write_byte_data(isp1301_i2c_client,
  80                (ISP1301_I2C_OTG_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR), ~0);
  81        i2c_smbus_write_byte_data(isp1301_i2c_client,
  82                ISP1301_I2C_MODE_CONTROL_1, MC1_DAT_SE0);
  83        i2c_smbus_write_byte_data(isp1301_i2c_client,
  84                ISP1301_I2C_OTG_CONTROL_1,
  85                (OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN));
  86        i2c_smbus_write_byte_data(isp1301_i2c_client,
  87                (ISP1301_I2C_OTG_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR),
  88                (OTG1_DM_PULLUP | OTG1_DP_PULLUP));
  89        i2c_smbus_write_byte_data(isp1301_i2c_client,
  90                ISP1301_I2C_INTERRUPT_LATCH | ISP1301_I2C_REG_CLEAR_ADDR, ~0);
  91        i2c_smbus_write_byte_data(isp1301_i2c_client,
  92                ISP1301_I2C_INTERRUPT_FALLING | ISP1301_I2C_REG_CLEAR_ADDR,
  93                ~0);
  94        i2c_smbus_write_byte_data(isp1301_i2c_client,
  95                ISP1301_I2C_INTERRUPT_RISING | ISP1301_I2C_REG_CLEAR_ADDR, ~0);
  96
  97        printk(KERN_INFO "ISP1301 Vendor ID  : 0x%04x\n",
  98              i2c_smbus_read_word_data(isp1301_i2c_client, 0x00));
  99        printk(KERN_INFO "ISP1301 Product ID : 0x%04x\n",
 100              i2c_smbus_read_word_data(isp1301_i2c_client, 0x02));
 101        printk(KERN_INFO "ISP1301 Version ID : 0x%04x\n",
 102              i2c_smbus_read_word_data(isp1301_i2c_client, 0x14));
 103}
 104
 105static void isp1301_configure(void)
 106{
 107        isp1301_configure_lpc32xx();
 108}
 109
 110static inline void isp1301_vbus_on(void)
 111{
 112        i2c_smbus_write_byte_data(isp1301_i2c_client, ISP1301_I2C_OTG_CONTROL_1,
 113                                  OTG1_VBUS_DRV);
 114}
 115
 116static inline void isp1301_vbus_off(void)
 117{
 118        i2c_smbus_write_byte_data(isp1301_i2c_client,
 119                ISP1301_I2C_OTG_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR,
 120                OTG1_VBUS_DRV);
 121}
 122
 123static void ohci_nxp_start_hc(void)
 124{
 125        unsigned long tmp = __raw_readl(USB_OTG_STAT_CONTROL) | HOST_EN;
 126
 127        __raw_writel(tmp, USB_OTG_STAT_CONTROL);
 128        isp1301_vbus_on();
 129}
 130
 131static void ohci_nxp_stop_hc(void)
 132{
 133        unsigned long tmp;
 134
 135        isp1301_vbus_off();
 136        tmp = __raw_readl(USB_OTG_STAT_CONTROL) & ~HOST_EN;
 137        __raw_writel(tmp, USB_OTG_STAT_CONTROL);
 138}
 139
 140static int ohci_hcd_nxp_probe(struct platform_device *pdev)
 141{
 142        struct usb_hcd *hcd = 0;
 143        const struct hc_driver *driver = &ohci_nxp_hc_driver;
 144        struct resource *res;
 145        int ret = 0, irq;
 146        struct device_node *isp1301_node;
 147
 148        if (pdev->dev.of_node) {
 149                isp1301_node = of_parse_phandle(pdev->dev.of_node,
 150                                                "transceiver", 0);
 151        } else {
 152                isp1301_node = NULL;
 153        }
 154
 155        isp1301_i2c_client = isp1301_get_client(isp1301_node);
 156        if (!isp1301_i2c_client)
 157                return -EPROBE_DEFER;
 158
 159        ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
 160        if (ret)
 161                goto fail_disable;
 162
 163        dev_dbg(&pdev->dev, "%s: " DRIVER_DESC " (nxp)\n", hcd_name);
 164        if (usb_disabled()) {
 165                dev_err(&pdev->dev, "USB is disabled\n");
 166                ret = -ENODEV;
 167                goto fail_disable;
 168        }
 169
 170        /* Enable USB host clock */
 171        usb_host_clk = devm_clk_get(&pdev->dev, NULL);
 172        if (IS_ERR(usb_host_clk)) {
 173                dev_err(&pdev->dev, "failed to acquire USB OHCI clock\n");
 174                ret = PTR_ERR(usb_host_clk);
 175                goto fail_disable;
 176        }
 177
 178        ret = clk_prepare_enable(usb_host_clk);
 179        if (ret < 0) {
 180                dev_err(&pdev->dev, "failed to start USB OHCI clock\n");
 181                goto fail_disable;
 182        }
 183
 184        isp1301_configure();
 185
 186        hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
 187        if (!hcd) {
 188                dev_err(&pdev->dev, "Failed to allocate HC buffer\n");
 189                ret = -ENOMEM;
 190                goto fail_hcd;
 191        }
 192
 193        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 194        hcd->regs = devm_ioremap_resource(&pdev->dev, res);
 195        if (IS_ERR(hcd->regs)) {
 196                ret = PTR_ERR(hcd->regs);
 197                goto fail_resource;
 198        }
 199        hcd->rsrc_start = res->start;
 200        hcd->rsrc_len = resource_size(res);
 201
 202        irq = platform_get_irq(pdev, 0);
 203        if (irq < 0) {
 204                ret = -ENXIO;
 205                goto fail_resource;
 206        }
 207
 208        ohci_nxp_start_hc();
 209        platform_set_drvdata(pdev, hcd);
 210
 211        dev_info(&pdev->dev, "at 0x%p, irq %d\n", hcd->regs, hcd->irq);
 212        ret = usb_add_hcd(hcd, irq, 0);
 213        if (ret == 0) {
 214                device_wakeup_enable(hcd->self.controller);
 215                return ret;
 216        }
 217
 218        ohci_nxp_stop_hc();
 219fail_resource:
 220        usb_put_hcd(hcd);
 221fail_hcd:
 222        clk_disable_unprepare(usb_host_clk);
 223fail_disable:
 224        isp1301_i2c_client = NULL;
 225        return ret;
 226}
 227
 228static int ohci_hcd_nxp_remove(struct platform_device *pdev)
 229{
 230        struct usb_hcd *hcd = platform_get_drvdata(pdev);
 231
 232        usb_remove_hcd(hcd);
 233        ohci_nxp_stop_hc();
 234        usb_put_hcd(hcd);
 235        clk_disable_unprepare(usb_host_clk);
 236        isp1301_i2c_client = NULL;
 237
 238        return 0;
 239}
 240
 241/* work with hotplug and coldplug */
 242MODULE_ALIAS("platform:usb-ohci");
 243
 244#ifdef CONFIG_OF
 245static const struct of_device_id ohci_hcd_nxp_match[] = {
 246        { .compatible = "nxp,ohci-nxp" },
 247        {},
 248};
 249MODULE_DEVICE_TABLE(of, ohci_hcd_nxp_match);
 250#endif
 251
 252static struct platform_driver ohci_hcd_nxp_driver = {
 253        .driver = {
 254                .name = "usb-ohci",
 255                .of_match_table = of_match_ptr(ohci_hcd_nxp_match),
 256        },
 257        .probe = ohci_hcd_nxp_probe,
 258        .remove = ohci_hcd_nxp_remove,
 259};
 260
 261static int __init ohci_nxp_init(void)
 262{
 263        if (usb_disabled())
 264                return -ENODEV;
 265
 266        pr_info("%s: " DRIVER_DESC "\n", hcd_name);
 267
 268        ohci_init_driver(&ohci_nxp_hc_driver, NULL);
 269        return platform_driver_register(&ohci_hcd_nxp_driver);
 270}
 271module_init(ohci_nxp_init);
 272
 273static void __exit ohci_nxp_cleanup(void)
 274{
 275        platform_driver_unregister(&ohci_hcd_nxp_driver);
 276}
 277module_exit(ohci_nxp_cleanup);
 278
 279MODULE_DESCRIPTION(DRIVER_DESC);
 280MODULE_LICENSE("GPL v2");
 281