From: David Brownell Date: Sat, 11 Nov 2006 00:12:43 +0000 (+0200) Subject: ARM: OMAP: USB peripheral support on H4 X-Git-Tag: v2.6.19-omap1~55 X-Git-Url: http://pilppa.com/gitweb/?a=commitdiff_plain;h=d5a13235a282b8b556ca79fc743152cc71d4f26d;p=linux-2.6-omap-h63xx.git ARM: OMAP: USB peripheral support on H4 H4 has two peripheral ports, one for "download" and one for OTG. The one to use is selected through Kconfig. Also removes some bad whitespace from isp1301_omap.c NOTE: not yet working; I suspect there's a clock still turned off or something like that, since neither port responds. Signed-off-by: David Brownell --- diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 8c82d5511ef..83608e43c9e 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -49,6 +49,27 @@ config MACH_OMAP_H4_TUSB Be sure to select OTG mode operation, not host-only or peripheral-only. +config MACH_OMAP_H4_OTG + bool "Use USB OTG connector, not device connector (S1.10)" + depends on MACH_OMAP_H4 + help + Set this if you've set S1.10 (on the mainboard) to use the + Mini-AB (OTG) connector and OTG transceiver with the USB0 + port, instead of the Mini-B ("download") connector with its + non-OTG transceiver. + + Note that the "download" connector can be used to bootstrap + the system from the OMAP mask ROM. Also, since this is a + development platform, you can also force the OTG port into + a non-OTG operational mode. + +config MACH_OMAP2_H4_USB1 + bool "Use USB1 port, not UART2 (S3.3)" + depends on MACH_OMAP_H4 + help + Set this if you've set SW3.3 (on the CPU card) so that the + expansion connectors receive USB1 signals instead of UART2. + config MACH_OMAP_APOLLON bool "OMAP 2420 Apollon board" depends on ARCH_OMAP2 && ARCH_OMAP24XX diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c index 7edfe0ecabd..7fbf378811b 100644 --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c @@ -362,7 +362,11 @@ static void __init omap_h4_init_irq(void) } static struct omap_uart_config h4_uart_config __initdata = { +#ifdef CONFIG_MACH_OMAP2_H4_USB1 + .enabled_uarts = ((1 << 0) | (1 << 1)), +#else .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), +#endif }; static struct omap_mmc_config h4_mmc_config __initdata = { @@ -379,10 +383,44 @@ static struct omap_lcd_config h4_lcd_config __initdata = { .ctrl_name = "internal", }; +static struct omap_usb_config h4_usb_config __initdata = { +#ifdef CONFIG_MACH_OMAP2_H4_USB1 + /* NOTE: usb1 could also be used with 3 wire signaling */ + .pins[1] = 4, +#endif + +#ifdef CONFIG_MACH_OMAP_H4_OTG + /* S1.10 ON -- USB OTG port + * usb0 switched to Mini-AB port and isp1301 transceiver; + * S2.POS3 = OFF, S2.POS4 = ON ... to allow battery charging + */ + .otg = 1, + .pins[0] = 4, +#ifdef CONFIG_USB_GADGET_OMAP + /* use OTG cable, or standard A-to-MiniB */ + .hmc_mode = 0x14, /* 0:dev/otg 1:host 2:disable */ +#elif defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) + /* use OTG cable, or NONSTANDARD (B-to-MiniB) */ + .hmc_mode = 0x11, /* 0:host 1:host 2:disable */ +#endif /* XX */ + +#else + /* S1.10 OFF -- usb "download port" + * usb0 switched to Mini-B port and isp1105 transceiver; + * S2.POS3 = ON, S2.POS4 = OFF ... to enable battery charging + */ + .register_dev = 1, + .pins[0] = 3, +// .hmc_mode = 0x14, /* 0:dev 1:host 2:disable */ + .hmc_mode = 0x00, /* 0:dev|otg 1:disable 2:disable */ +#endif +}; + static struct omap_board_config_kernel h4_config[] = { { OMAP_TAG_UART, &h4_uart_config }, { OMAP_TAG_MMC, &h4_mmc_config }, { OMAP_TAG_LCD, &h4_lcd_config }, + { OMAP_TAG_USB, &h4_usb_config }, }; #ifdef CONFIG_MACH_OMAP_H4_TUSB @@ -471,6 +509,14 @@ static void __init omap_h4_init(void) } #endif +#ifdef CONFIG_MACH_OMAP2_H4_USB1 + /* S3.3 controls whether these pins are for UART2 or USB1 */ + omap_cfg_reg(N14_24XX_USB1_SE0); + omap_cfg_reg(P15_24XX_USB1_DAT); + omap_cfg_reg(W20_24XX_USB1_TXEN); + omap_cfg_reg(V19_24XX_USB1_RCV); +#endif + platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices)); omap_board_config = h4_config; omap_board_config_size = ARRAY_SIZE(h4_config); diff --git a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c index 53a486306af..2a7547f4dd1 100644 --- a/drivers/i2c/chips/isp1301_omap.c +++ b/drivers/i2c/chips/isp1301_omap.c @@ -68,7 +68,7 @@ struct isp1301 { /* use keventd context to change the state for us */ struct work_struct work; - + unsigned long todo; # define WORK_UPDATE_ISP 0 /* update ISP from OTG */ # define WORK_UPDATE_OTG 1 /* update OTG from ISP */ @@ -306,7 +306,7 @@ static void power_up(struct isp1301 *isp) { // isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_2, MC2_GLOBAL_PWR_DN); isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SUSPEND_REG); - + /* do this only when cpu is driving transceiver, * so host won't see a low speed device... */ @@ -818,7 +818,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp) /* role is host */ } else { if (!(otg_ctrl & OTG_ID)) { - otg_ctrl &= OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; + otg_ctrl &= OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; OTG_CTRL_REG = otg_ctrl | OTG_A_BUSREQ; } @@ -1245,6 +1245,9 @@ static int isp1301_detach_client(struct i2c_client *i2c) if (machine_is_omap_h3()) omap_free_gpio(14); + if (machine_is_omap_h4()) + omap_free_gpio(125); + isp->timer.data = 0; set_bit(WORK_STOP, &isp->todo); del_timer_sync(&isp->timer); @@ -1266,7 +1269,7 @@ static int isp1301_detach_client(struct i2c_client *i2c) * - DEVICE mode, for when there's a B/Mini-B (device) connector * * As a rule, you won't have an isp1301 chip unless it's there to - * support the OTG mode. Other modes help testing USB controllers + * support the OTG mode. Other modes help testing USB controllers * in isolation from (full) OTG support, or maybe so later board * revisions can help to support those feature. */ @@ -1282,9 +1285,9 @@ static int isp1301_otg_enable(struct isp1301 *isp) * a few more interrupts than are strictly needed. */ isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING, - INTR_VBUS_VLD | INTR_SESS_VLD | INTR_ID_GND); + INTR_VBUS_VLD | INTR_SESS_VLD | INTR_ID_GND); isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, - INTR_VBUS_VLD | INTR_SESS_VLD | INTR_ID_GND); + INTR_VBUS_VLD | INTR_SESS_VLD | INTR_ID_GND); dev_info(&isp->client.dev, "ready for dual-role USB ...\n"); @@ -1323,14 +1326,15 @@ isp1301_set_host(struct otg_transceiver *otg, struct usb_bus *host) power_up(isp); +// XXX h4 too? if (machine_is_omap_h2() || machine_is_omap_h3()) isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); dev_info(&isp->client.dev, "A-Host sessions ok\n"); isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING, - INTR_ID_GND); + INTR_ID_GND); isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, - INTR_ID_GND); + INTR_ID_GND); /* If this has a Mini-AB connector, this mode is highly * nonstandard ... but can be handy for testing, especially with @@ -1386,13 +1390,14 @@ isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget) power_up(isp); isp->otg.state = OTG_STATE_B_IDLE; +// XXX h4 too? if (machine_is_omap_h2() || machine_is_omap_h3()) isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING, - INTR_SESS_VLD | INTR_VBUS_VLD); + INTR_SESS_VLD | INTR_VBUS_VLD); isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, - INTR_VBUS_VLD | INTR_SESS_VLD); + INTR_VBUS_VLD | INTR_SESS_VLD); dev_info(&isp->client.dev, "B-Peripheral sessions ok\n"); dump_regs(isp, __FUNCTION__); @@ -1589,6 +1594,7 @@ fail1: } #endif +// XXX h4 too? if (machine_is_omap_h2() || machine_is_omap_h3()) { /* full speed signaling by default */ isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, @@ -1615,6 +1621,15 @@ fail1: isp->irq_type = SA_TRIGGER_FALLING; } + if (machine_is_omap_h4()) { + /* IRQ wired at P14 */ + omap_cfg_reg(P14_24XX_GPIO125); + isp->irq = OMAP_GPIO_IRQ(125); + omap_request_gpio(125); + omap_set_gpio_direction(125, 1); + isp->irq_type = IRQF_TRIGGER_LOW; + } + status = request_irq(isp->irq, isp1301_irq, isp->irq_type, DRIVER_NAME, isp); if (status < 0) { diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 6fb770c499d..04c64aa26ee 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -168,7 +168,7 @@ config USB_GADGET_MUSB_HDRC config USB_GADGET_OMAP boolean "OMAP USB Device Controller" depends on ARCH_OMAP - select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 + select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H4_OTG help Many Texas Instruments OMAP processors have flexible full speed USB device controllers, with support for up to 30