1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Driver for the NXP ISP1760 chip 4 * 5 * Copyright 2014 Laurent Pinchart 6 * Copyright 2007 Sebastian Siewior 7 * 8 * Contacts: 9 * Sebastian Siewior <bigeasy@linutronix.de> 10 * Laurent Pinchart <laurent.pinchart@ideasonboard.com> 11 */ 12 13 #include <linux/delay.h> 14 #include <linux/gpio/consumer.h> 15 #include <linux/io.h> 16 #include <linux/kernel.h> 17 #include <linux/module.h> 18 #include <linux/slab.h> 19 #include <linux/usb.h> 20 21 #include "isp1760-core.h" 22 #include "isp1760-hcd.h" 23 #include "isp1760-regs.h" 24 #include "isp1760-udc.h" 25 26 static void isp1760_init_core(struct isp1760_device *isp) 27 { 28 u32 otgctrl; 29 u32 hwmode; 30 31 /* Low-level chip reset */ 32 if (isp->rst_gpio) { 33 gpiod_set_value_cansleep(isp->rst_gpio, 1); 34 msleep(50); 35 gpiod_set_value_cansleep(isp->rst_gpio, 0); 36 } 37 38 /* 39 * Reset the host controller, including the CPU interface 40 * configuration. 41 */ 42 isp1760_write32(isp->regs, HC_RESET_REG, SW_RESET_RESET_ALL); 43 msleep(100); 44 45 /* Setup HW Mode Control: This assumes a level active-low interrupt */ 46 hwmode = HW_DATA_BUS_32BIT; 47 48 if (isp->devflags & ISP1760_FLAG_BUS_WIDTH_16) 49 hwmode &= ~HW_DATA_BUS_32BIT; 50 if (isp->devflags & ISP1760_FLAG_ANALOG_OC) 51 hwmode |= HW_ANA_DIGI_OC; 52 if (isp->devflags & ISP1760_FLAG_DACK_POL_HIGH) 53 hwmode |= HW_DACK_POL_HIGH; 54 if (isp->devflags & ISP1760_FLAG_DREQ_POL_HIGH) 55 hwmode |= HW_DREQ_POL_HIGH; 56 if (isp->devflags & ISP1760_FLAG_INTR_POL_HIGH) 57 hwmode |= HW_INTR_HIGH_ACT; 58 if (isp->devflags & ISP1760_FLAG_INTR_EDGE_TRIG) 59 hwmode |= HW_INTR_EDGE_TRIG; 60 61 /* 62 * The ISP1761 has a dedicated DC IRQ line but supports sharing the HC 63 * IRQ line for both the host and device controllers. Hardcode IRQ 64 * sharing for now and disable the DC interrupts globally to avoid 65 * spurious interrupts during HCD registration. 66 */ 67 if (isp->devflags & ISP1760_FLAG_ISP1761) { 68 isp1760_write32(isp->regs, DC_MODE, 0); 69 hwmode |= HW_COMN_IRQ; 70 } 71 72 /* 73 * We have to set this first in case we're in 16-bit mode. 74 * Write it twice to ensure correct upper bits if switching 75 * to 16-bit mode. 76 */ 77 isp1760_write32(isp->regs, HC_HW_MODE_CTRL, hwmode); 78 isp1760_write32(isp->regs, HC_HW_MODE_CTRL, hwmode); 79 80 /* 81 * PORT 1 Control register of the ISP1760 is the OTG control register 82 * on ISP1761. 83 * 84 * TODO: Really support OTG. For now we configure port 1 in device mode 85 * when OTG is requested. 86 */ 87 if ((isp->devflags & ISP1760_FLAG_ISP1761) && 88 (isp->devflags & ISP1760_FLAG_OTG_EN)) 89 otgctrl = ((HW_DM_PULLDOWN | HW_DP_PULLDOWN) << 16) 90 | HW_OTG_DISABLE; 91 else 92 otgctrl = (HW_SW_SEL_HC_DC << 16) 93 | (HW_VBUS_DRV | HW_SEL_CP_EXT); 94 95 isp1760_write32(isp->regs, HC_PORT1_CTRL, otgctrl); 96 97 dev_info(isp->dev, "bus width: %u, oc: %s\n", 98 isp->devflags & ISP1760_FLAG_BUS_WIDTH_16 ? 16 : 32, 99 isp->devflags & ISP1760_FLAG_ANALOG_OC ? "analog" : "digital"); 100 } 101 102 void isp1760_set_pullup(struct isp1760_device *isp, bool enable) 103 { 104 isp1760_write32(isp->regs, HW_OTG_CTRL_SET, 105 enable ? HW_DP_PULLUP : HW_DP_PULLUP << 16); 106 } 107 108 int isp1760_register(struct resource *mem, int irq, unsigned long irqflags, 109 struct device *dev, unsigned int devflags) 110 { 111 struct isp1760_device *isp; 112 bool udc_disabled = !(devflags & ISP1760_FLAG_ISP1761); 113 int ret; 114 115 /* 116 * If neither the HCD not the UDC is enabled return an error, as no 117 * device would be registered. 118 */ 119 if ((!IS_ENABLED(CONFIG_USB_ISP1760_HCD) || usb_disabled()) && 120 (!IS_ENABLED(CONFIG_USB_ISP1761_UDC) || udc_disabled)) 121 return -ENODEV; 122 123 isp = devm_kzalloc(dev, sizeof(*isp), GFP_KERNEL); 124 if (!isp) 125 return -ENOMEM; 126 127 isp->dev = dev; 128 isp->devflags = devflags; 129 130 isp->rst_gpio = devm_gpiod_get_optional(dev, NULL, GPIOD_OUT_HIGH); 131 if (IS_ERR(isp->rst_gpio)) 132 return PTR_ERR(isp->rst_gpio); 133 134 isp->regs = devm_ioremap_resource(dev, mem); 135 if (IS_ERR(isp->regs)) 136 return PTR_ERR(isp->regs); 137 138 isp1760_init_core(isp); 139 140 if (IS_ENABLED(CONFIG_USB_ISP1760_HCD) && !usb_disabled()) { 141 ret = isp1760_hcd_register(&isp->hcd, isp->regs, mem, irq, 142 irqflags | IRQF_SHARED, dev); 143 if (ret < 0) 144 return ret; 145 } 146 147 if (IS_ENABLED(CONFIG_USB_ISP1761_UDC) && !udc_disabled) { 148 ret = isp1760_udc_register(isp, irq, irqflags); 149 if (ret < 0) { 150 isp1760_hcd_unregister(&isp->hcd); 151 return ret; 152 } 153 } 154 155 dev_set_drvdata(dev, isp); 156 157 return 0; 158 } 159 160 void isp1760_unregister(struct device *dev) 161 { 162 struct isp1760_device *isp = dev_get_drvdata(dev); 163 164 isp1760_udc_unregister(isp); 165 isp1760_hcd_unregister(&isp->hcd); 166 } 167 168 MODULE_DESCRIPTION("Driver for the ISP1760 USB-controller from NXP"); 169 MODULE_AUTHOR("Sebastian Siewior <bigeasy@linuxtronix.de>"); 170 MODULE_LICENSE("GPL v2"); 171