1 // SPDX-License-Identifier: GPL-2.0
3 * Driver for the NXP ISP1760 chip
5 * Copyright 2014 Laurent Pinchart
6 * Copyright 2007 Sebastian Siewior
9 * Sebastian Siewior <bigeasy@linutronix.de>
10 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
13 #include <linux/delay.h>
14 #include <linux/gpio/consumer.h>
16 #include <linux/kernel.h>
17 #include <linux/module.h>
18 #include <linux/slab.h>
19 #include <linux/usb.h>
21 #include "isp1760-core.h"
22 #include "isp1760-hcd.h"
23 #include "isp1760-regs.h"
24 #include "isp1760-udc.h"
26 static void isp1760_init_core(struct isp1760_device
*isp
)
31 /* Low-level chip reset */
33 gpiod_set_value_cansleep(isp
->rst_gpio
, 1);
35 gpiod_set_value_cansleep(isp
->rst_gpio
, 0);
39 * Reset the host controller, including the CPU interface
42 isp1760_write32(isp
->regs
, HC_RESET_REG
, SW_RESET_RESET_ALL
);
45 /* Setup HW Mode Control: This assumes a level active-low interrupt */
46 hwmode
= HW_DATA_BUS_32BIT
;
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
;
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.
67 if (isp
->devflags
& ISP1760_FLAG_ISP1761
) {
68 isp1760_write32(isp
->regs
, DC_MODE
, 0);
69 hwmode
|= HW_COMN_IRQ
;
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
77 isp1760_write32(isp
->regs
, HC_HW_MODE_CTRL
, hwmode
);
78 isp1760_write32(isp
->regs
, HC_HW_MODE_CTRL
, hwmode
);
81 * PORT 1 Control register of the ISP1760 is the OTG control register
84 * TODO: Really support OTG. For now we configure port 1 in device mode
85 * when OTG is requested.
87 if ((isp
->devflags
& ISP1760_FLAG_ISP1761
) &&
88 (isp
->devflags
& ISP1760_FLAG_OTG_EN
))
89 otgctrl
= ((HW_DM_PULLDOWN
| HW_DP_PULLDOWN
) << 16)
92 otgctrl
= (HW_SW_SEL_HC_DC
<< 16)
93 | (HW_VBUS_DRV
| HW_SEL_CP_EXT
);
95 isp1760_write32(isp
->regs
, HC_PORT1_CTRL
, otgctrl
);
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");
102 void isp1760_set_pullup(struct isp1760_device
*isp
, bool enable
)
104 isp1760_write32(isp
->regs
, HW_OTG_CTRL_SET
,
105 enable
? HW_DP_PULLUP
: HW_DP_PULLUP
<< 16);
108 int isp1760_register(struct resource
*mem
, int irq
, unsigned long irqflags
,
109 struct device
*dev
, unsigned int devflags
)
111 struct isp1760_device
*isp
;
112 bool udc_disabled
= !(devflags
& ISP1760_FLAG_ISP1761
);
116 * If neither the HCD not the UDC is enabled return an error, as no
117 * device would be registered.
119 if ((!IS_ENABLED(CONFIG_USB_ISP1760_HCD
) || usb_disabled()) &&
120 (!IS_ENABLED(CONFIG_USB_ISP1761_UDC
) || udc_disabled
))
123 /* prevent usb-core allocating DMA pages */
124 dev
->dma_mask
= NULL
;
126 isp
= devm_kzalloc(dev
, sizeof(*isp
), GFP_KERNEL
);
131 isp
->devflags
= devflags
;
133 isp
->rst_gpio
= devm_gpiod_get_optional(dev
, NULL
, GPIOD_OUT_HIGH
);
134 if (IS_ERR(isp
->rst_gpio
))
135 return PTR_ERR(isp
->rst_gpio
);
137 isp
->regs
= devm_ioremap_resource(dev
, mem
);
138 if (IS_ERR(isp
->regs
))
139 return PTR_ERR(isp
->regs
);
141 isp1760_init_core(isp
);
143 if (IS_ENABLED(CONFIG_USB_ISP1760_HCD
) && !usb_disabled()) {
144 ret
= isp1760_hcd_register(&isp
->hcd
, isp
->regs
, mem
, irq
,
145 irqflags
| IRQF_SHARED
, dev
);
150 if (IS_ENABLED(CONFIG_USB_ISP1761_UDC
) && !udc_disabled
) {
151 ret
= isp1760_udc_register(isp
, irq
, irqflags
);
153 isp1760_hcd_unregister(&isp
->hcd
);
158 dev_set_drvdata(dev
, isp
);
163 void isp1760_unregister(struct device
*dev
)
165 struct isp1760_device
*isp
= dev_get_drvdata(dev
);
167 isp1760_udc_unregister(isp
);
168 isp1760_hcd_unregister(&isp
->hcd
);
171 MODULE_DESCRIPTION("Driver for the ISP1760 USB-controller from NXP");
172 MODULE_AUTHOR("Sebastian Siewior <bigeasy@linuxtronix.de>");
173 MODULE_LICENSE("GPL v2");