diff options
author | Roland Stigge <stigge@antcom.de> | 2012-03-12 17:54:51 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-03-13 17:27:28 -0400 |
commit | 53dc25ada62ff418bbbffb6bd982ed923cd84021 (patch) | |
tree | a98ea893e331c018af46392858e8a8aed71796ca /drivers/usb/host/ohci-nxp.c | |
parent | 286431048b99705b555b6040da72bb2964386cea (diff) |
USB: ohci-nxp: Support for LPC32xx
This patch adds support for the LPC32xx to ohci-nxp
Signed-off-by: Roland Stigge <stigge@antcom.de>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/ohci-nxp.c')
-rw-r--r-- | drivers/usb/host/ohci-nxp.c | 142 |
1 files changed, 108 insertions, 34 deletions
diff --git a/drivers/usb/host/ohci-nxp.c b/drivers/usb/host/ohci-nxp.c index a12c6b40472e..e7cc7b633214 100644 --- a/drivers/usb/host/ohci-nxp.c +++ b/drivers/usb/host/ohci-nxp.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Currently supported OHCI host devices: | 4 | * Currently supported OHCI host devices: |
5 | * - Philips PNX4008 | 5 | * - Philips PNX4008 |
6 | * - NXP LPC32xx | ||
6 | * | 7 | * |
7 | * Authors: Dmitry Chigirev <source@mvista.com> | 8 | * Authors: Dmitry Chigirev <source@mvista.com> |
8 | * Vitaly Wool <vitalywool@gmail.com> | 9 | * Vitaly Wool <vitalywool@gmail.com> |
@@ -23,20 +24,24 @@ | |||
23 | #include <linux/i2c.h> | 24 | #include <linux/i2c.h> |
24 | 25 | ||
25 | #include <mach/hardware.h> | 26 | #include <mach/hardware.h> |
27 | #include <asm/mach-types.h> | ||
26 | #include <asm/io.h> | 28 | #include <asm/io.h> |
27 | 29 | ||
28 | #include <mach/platform.h> | 30 | #include <mach/platform.h> |
29 | #include <mach/irqs.h> | 31 | #include <mach/irqs.h> |
30 | #include <asm/gpio.h> | 32 | #include <asm/gpio.h> |
31 | 33 | ||
32 | #define USB_CTRL IO_ADDRESS(PNX4008_PWRMAN_BASE + 0x64) | 34 | #define USB_CONFIG_BASE 0x31020000 |
35 | #define PWRMAN_BASE 0x40004000 | ||
36 | |||
37 | #define USB_CTRL IO_ADDRESS(PWRMAN_BASE + 0x64) | ||
33 | 38 | ||
34 | /* USB_CTRL bit defines */ | 39 | /* USB_CTRL bit defines */ |
35 | #define USB_SLAVE_HCLK_EN (1 << 24) | 40 | #define USB_SLAVE_HCLK_EN (1 << 24) |
36 | #define USB_HOST_NEED_CLK_EN (1 << 21) | 41 | #define USB_HOST_NEED_CLK_EN (1 << 21) |
37 | 42 | ||
38 | #define USB_OTG_CLK_CTRL IO_ADDRESS(PNX4008_USB_CONFIG_BASE + 0xFF4) | 43 | #define USB_OTG_CLK_CTRL IO_ADDRESS(USB_CONFIG_BASE + 0xFF4) |
39 | #define USB_OTG_CLK_STAT IO_ADDRESS(PNX4008_USB_CONFIG_BASE + 0xFF8) | 44 | #define USB_OTG_CLK_STAT IO_ADDRESS(USB_CONFIG_BASE + 0xFF8) |
40 | 45 | ||
41 | /* USB_OTG_CLK_CTRL bit defines */ | 46 | /* USB_OTG_CLK_CTRL bit defines */ |
42 | #define AHB_M_CLOCK_ON (1 << 4) | 47 | #define AHB_M_CLOCK_ON (1 << 4) |
@@ -45,7 +50,7 @@ | |||
45 | #define DEV_CLOCK_ON (1 << 1) | 50 | #define DEV_CLOCK_ON (1 << 1) |
46 | #define HOST_CLOCK_ON (1 << 0) | 51 | #define HOST_CLOCK_ON (1 << 0) |
47 | 52 | ||
48 | #define USB_OTG_STAT_CONTROL IO_ADDRESS(PNX4008_USB_CONFIG_BASE + 0x110) | 53 | #define USB_OTG_STAT_CONTROL IO_ADDRESS(USB_CONFIG_BASE + 0x110) |
49 | 54 | ||
50 | /* USB_OTG_STAT_CONTROL bit defines */ | 55 | /* USB_OTG_STAT_CONTROL bit defines */ |
51 | #define TRANSPARENT_I2C_EN (1 << 7) | 56 | #define TRANSPARENT_I2C_EN (1 << 7) |
@@ -99,6 +104,15 @@ | |||
99 | #define ISP1301_I2C_INTERRUPT_RISING 0xE | 104 | #define ISP1301_I2C_INTERRUPT_RISING 0xE |
100 | #define ISP1301_I2C_REG_CLEAR_ADDR 1 | 105 | #define ISP1301_I2C_REG_CLEAR_ADDR 1 |
101 | 106 | ||
107 | /* On LPC32xx, those are undefined */ | ||
108 | #ifndef start_int_set_falling_edge | ||
109 | #define start_int_set_falling_edge(irq) | ||
110 | #define start_int_set_rising_edge(irq) | ||
111 | #define start_int_ack(irq) | ||
112 | #define start_int_mask(irq) | ||
113 | #define start_int_umask(irq) | ||
114 | #endif | ||
115 | |||
102 | static struct i2c_driver isp1301_driver; | 116 | static struct i2c_driver isp1301_driver; |
103 | static struct i2c_client *isp1301_i2c_client; | 117 | static struct i2c_client *isp1301_i2c_client; |
104 | 118 | ||
@@ -144,7 +158,7 @@ static void i2c_write(u8 buf, u8 subaddr) | |||
144 | i2c_master_send(isp1301_i2c_client, &tmpbuf[0], 2); | 158 | i2c_master_send(isp1301_i2c_client, &tmpbuf[0], 2); |
145 | } | 159 | } |
146 | 160 | ||
147 | static void isp1301_configure(void) | 161 | static void isp1301_configure_pnx4008(void) |
148 | { | 162 | { |
149 | /* PNX4008 only supports DAT_SE0 USB mode */ | 163 | /* PNX4008 only supports DAT_SE0 USB mode */ |
150 | /* PNX4008 R2A requires setting the MAX603 to output 3.6V */ | 164 | /* PNX4008 R2A requires setting the MAX603 to output 3.6V */ |
@@ -167,7 +181,63 @@ static void isp1301_configure(void) | |||
167 | ISP1301_I2C_INTERRUPT_FALLING | ISP1301_I2C_REG_CLEAR_ADDR); | 181 | ISP1301_I2C_INTERRUPT_FALLING | ISP1301_I2C_REG_CLEAR_ADDR); |
168 | i2c_write(0xFF, | 182 | i2c_write(0xFF, |
169 | ISP1301_I2C_INTERRUPT_RISING | ISP1301_I2C_REG_CLEAR_ADDR); | 183 | ISP1301_I2C_INTERRUPT_RISING | ISP1301_I2C_REG_CLEAR_ADDR); |
184 | } | ||
170 | 185 | ||
186 | static void isp1301_configure_lpc32xx(void) | ||
187 | { | ||
188 | /* LPC32XX only supports DAT_SE0 USB mode */ | ||
189 | /* This sequence is important */ | ||
190 | |||
191 | /* Disable transparent UART mode first */ | ||
192 | i2c_smbus_write_byte_data(isp1301_i2c_client, | ||
193 | (ISP1301_I2C_MODE_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR), | ||
194 | MC1_UART_EN); | ||
195 | i2c_smbus_write_byte_data(isp1301_i2c_client, | ||
196 | (ISP1301_I2C_MODE_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR), | ||
197 | ~MC1_SPEED_REG); | ||
198 | i2c_smbus_write_byte_data(isp1301_i2c_client, | ||
199 | ISP1301_I2C_MODE_CONTROL_1, MC1_SPEED_REG); | ||
200 | i2c_smbus_write_byte_data(isp1301_i2c_client, | ||
201 | (ISP1301_I2C_MODE_CONTROL_2 | ISP1301_I2C_REG_CLEAR_ADDR), | ||
202 | ~0); | ||
203 | i2c_smbus_write_byte_data(isp1301_i2c_client, | ||
204 | ISP1301_I2C_MODE_CONTROL_2, | ||
205 | (MC2_BI_DI | MC2_PSW_EN | MC2_SPD_SUSP_CTRL)); | ||
206 | i2c_smbus_write_byte_data(isp1301_i2c_client, | ||
207 | (ISP1301_I2C_OTG_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR), ~0); | ||
208 | i2c_smbus_write_byte_data(isp1301_i2c_client, | ||
209 | ISP1301_I2C_MODE_CONTROL_1, MC1_DAT_SE0); | ||
210 | i2c_smbus_write_byte_data(isp1301_i2c_client, | ||
211 | ISP1301_I2C_OTG_CONTROL_1, | ||
212 | (OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN)); | ||
213 | i2c_smbus_write_byte_data(isp1301_i2c_client, | ||
214 | (ISP1301_I2C_OTG_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR), | ||
215 | (OTG1_DM_PULLUP | OTG1_DP_PULLUP)); | ||
216 | i2c_smbus_write_byte_data(isp1301_i2c_client, | ||
217 | ISP1301_I2C_INTERRUPT_LATCH | ISP1301_I2C_REG_CLEAR_ADDR, ~0); | ||
218 | i2c_smbus_write_byte_data(isp1301_i2c_client, | ||
219 | ISP1301_I2C_INTERRUPT_FALLING | ISP1301_I2C_REG_CLEAR_ADDR, | ||
220 | ~0); | ||
221 | i2c_smbus_write_byte_data(isp1301_i2c_client, | ||
222 | ISP1301_I2C_INTERRUPT_RISING | ISP1301_I2C_REG_CLEAR_ADDR, ~0); | ||
223 | |||
224 | /* Enable usb_need_clk clock after transceiver is initialized */ | ||
225 | __raw_writel((__raw_readl(USB_CTRL) | (1 << 22)), USB_CTRL); | ||
226 | |||
227 | printk(KERN_INFO "ISP1301 Vendor ID : 0x%04x\n", | ||
228 | i2c_smbus_read_word_data(isp1301_i2c_client, 0x00)); | ||
229 | printk(KERN_INFO "ISP1301 Product ID : 0x%04x\n", | ||
230 | i2c_smbus_read_word_data(isp1301_i2c_client, 0x02)); | ||
231 | printk(KERN_INFO "ISP1301 Version ID : 0x%04x\n", | ||
232 | i2c_smbus_read_word_data(isp1301_i2c_client, 0x14)); | ||
233 | } | ||
234 | |||
235 | static void isp1301_configure(void) | ||
236 | { | ||
237 | if (machine_is_pnx4008()) | ||
238 | isp1301_configure_pnx4008(); | ||
239 | else | ||
240 | isp1301_configure_lpc32xx(); | ||
171 | } | 241 | } |
172 | 242 | ||
173 | static inline void isp1301_vbus_on(void) | 243 | static inline void isp1301_vbus_on(void) |
@@ -258,39 +328,43 @@ static const struct hc_driver ohci_nxp_hc_driver = { | |||
258 | 328 | ||
259 | static void nxp_set_usb_bits(void) | 329 | static void nxp_set_usb_bits(void) |
260 | { | 330 | { |
261 | start_int_set_falling_edge(SE_USB_OTG_ATX_INT_N); | 331 | if (machine_is_pnx4008()) { |
262 | start_int_ack(SE_USB_OTG_ATX_INT_N); | 332 | start_int_set_falling_edge(SE_USB_OTG_ATX_INT_N); |
263 | start_int_umask(SE_USB_OTG_ATX_INT_N); | 333 | start_int_ack(SE_USB_OTG_ATX_INT_N); |
264 | 334 | start_int_umask(SE_USB_OTG_ATX_INT_N); | |
265 | start_int_set_rising_edge(SE_USB_OTG_TIMER_INT); | 335 | |
266 | start_int_ack(SE_USB_OTG_TIMER_INT); | 336 | start_int_set_rising_edge(SE_USB_OTG_TIMER_INT); |
267 | start_int_umask(SE_USB_OTG_TIMER_INT); | 337 | start_int_ack(SE_USB_OTG_TIMER_INT); |
268 | 338 | start_int_umask(SE_USB_OTG_TIMER_INT); | |
269 | start_int_set_rising_edge(SE_USB_I2C_INT); | 339 | |
270 | start_int_ack(SE_USB_I2C_INT); | 340 | start_int_set_rising_edge(SE_USB_I2C_INT); |
271 | start_int_umask(SE_USB_I2C_INT); | 341 | start_int_ack(SE_USB_I2C_INT); |
272 | 342 | start_int_umask(SE_USB_I2C_INT); | |
273 | start_int_set_rising_edge(SE_USB_INT); | 343 | |
274 | start_int_ack(SE_USB_INT); | 344 | start_int_set_rising_edge(SE_USB_INT); |
275 | start_int_umask(SE_USB_INT); | 345 | start_int_ack(SE_USB_INT); |
276 | 346 | start_int_umask(SE_USB_INT); | |
277 | start_int_set_rising_edge(SE_USB_NEED_CLK_INT); | 347 | |
278 | start_int_ack(SE_USB_NEED_CLK_INT); | 348 | start_int_set_rising_edge(SE_USB_NEED_CLK_INT); |
279 | start_int_umask(SE_USB_NEED_CLK_INT); | 349 | start_int_ack(SE_USB_NEED_CLK_INT); |
280 | 350 | start_int_umask(SE_USB_NEED_CLK_INT); | |
281 | start_int_set_rising_edge(SE_USB_AHB_NEED_CLK_INT); | 351 | |
282 | start_int_ack(SE_USB_AHB_NEED_CLK_INT); | 352 | start_int_set_rising_edge(SE_USB_AHB_NEED_CLK_INT); |
283 | start_int_umask(SE_USB_AHB_NEED_CLK_INT); | 353 | start_int_ack(SE_USB_AHB_NEED_CLK_INT); |
354 | start_int_umask(SE_USB_AHB_NEED_CLK_INT); | ||
355 | } | ||
284 | } | 356 | } |
285 | 357 | ||
286 | static void nxp_unset_usb_bits(void) | 358 | static void nxp_unset_usb_bits(void) |
287 | { | 359 | { |
288 | start_int_mask(SE_USB_OTG_ATX_INT_N); | 360 | if (machine_is_pnx4008()) { |
289 | start_int_mask(SE_USB_OTG_TIMER_INT); | 361 | start_int_mask(SE_USB_OTG_ATX_INT_N); |
290 | start_int_mask(SE_USB_I2C_INT); | 362 | start_int_mask(SE_USB_OTG_TIMER_INT); |
291 | start_int_mask(SE_USB_INT); | 363 | start_int_mask(SE_USB_I2C_INT); |
292 | start_int_mask(SE_USB_NEED_CLK_INT); | 364 | start_int_mask(SE_USB_INT); |
293 | start_int_mask(SE_USB_AHB_NEED_CLK_INT); | 365 | start_int_mask(SE_USB_NEED_CLK_INT); |
366 | start_int_mask(SE_USB_AHB_NEED_CLK_INT); | ||
367 | } | ||
294 | } | 368 | } |
295 | 369 | ||
296 | static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev) | 370 | static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev) |