2 * Driver for the NXP ISP1760 chip
4 * Copyright 2014 Laurent Pinchart
5 * Copyright 2007 Sebastian Siewior
8 * Sebastian Siewior <bigeasy@linutronix.de>
9 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * version 2 as published by the Free Software Foundation.
16 #include <linux/delay.h>
17 #include <linux/gpio/consumer.h>
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/slab.h>
22 #include <linux/usb.h>
24 #include "isp1760-core.h"
25 #include "isp1760-hcd.h"
26 #include "isp1760-regs.h"
28 static void isp1760_init_core(struct isp1760_device *isp)
32 /* Low-level chip reset */
34 gpiod_set_value_cansleep(isp->rst_gpio, 1);
36 gpiod_set_value_cansleep(isp->rst_gpio, 0);
40 * Reset the host controller, including the CPU interface
43 isp1760_write32(isp->regs, HC_RESET_REG, SW_RESET_RESET_ALL);
46 /* Setup HW Mode Control: This assumes a level active-low interrupt */
47 hwmode = HW_DATA_BUS_32BIT;
49 if (isp->devflags & ISP1760_FLAG_BUS_WIDTH_16)
50 hwmode &= ~HW_DATA_BUS_32BIT;
51 if (isp->devflags & ISP1760_FLAG_ANALOG_OC)
52 hwmode |= HW_ANA_DIGI_OC;
53 if (isp->devflags & ISP1760_FLAG_DACK_POL_HIGH)
54 hwmode |= HW_DACK_POL_HIGH;
55 if (isp->devflags & ISP1760_FLAG_DREQ_POL_HIGH)
56 hwmode |= HW_DREQ_POL_HIGH;
57 if (isp->devflags & ISP1760_FLAG_INTR_POL_HIGH)
58 hwmode |= HW_INTR_HIGH_ACT;
59 if (isp->devflags & ISP1760_FLAG_INTR_EDGE_TRIG)
60 hwmode |= HW_INTR_EDGE_TRIG;
63 * We have to set this first in case we're in 16-bit mode.
64 * Write it twice to ensure correct upper bits if switching
67 isp1760_write32(isp->regs, HC_HW_MODE_CTRL, hwmode);
68 isp1760_write32(isp->regs, HC_HW_MODE_CTRL, hwmode);
70 dev_info(isp->dev, "bus width: %u, oc: %s\n",
71 isp->devflags & ISP1760_FLAG_BUS_WIDTH_16 ? 16 : 32,
72 isp->devflags & ISP1760_FLAG_ANALOG_OC ? "analog" : "digital");
75 int isp1760_register(struct resource *mem, int irq, unsigned long irqflags,
76 struct device *dev, unsigned int devflags)
78 struct isp1760_device *isp;
84 /* prevent usb-core allocating DMA pages */
87 isp = devm_kzalloc(dev, sizeof(*isp), GFP_KERNEL);
92 isp->devflags = devflags;
94 isp->rst_gpio = devm_gpiod_get_optional(dev, NULL, GPIOD_OUT_HIGH);
95 if (IS_ERR(isp->rst_gpio))
96 return PTR_ERR(isp->rst_gpio);
98 isp->regs = devm_ioremap_resource(dev, mem);
99 if (IS_ERR(isp->regs))
100 return PTR_ERR(isp->regs);
102 isp1760_init_core(isp);
104 ret = isp1760_hcd_register(&isp->hcd, isp->regs, mem, irq,
105 irqflags | IRQF_SHARED, dev);
109 dev_set_drvdata(dev, isp);
114 void isp1760_unregister(struct device *dev)
116 struct isp1760_device *isp = dev_get_drvdata(dev);
118 isp1760_hcd_unregister(&isp->hcd);
121 MODULE_DESCRIPTION("Driver for the ISP1760 USB-controller from NXP");
122 MODULE_AUTHOR("Sebastian Siewior <bigeasy@linuxtronix.de>");
123 MODULE_LICENSE("GPL v2");