--- zzzz-none-000/linux-2.6.19.2/drivers/i2c/chips/isp1301_omap.c 2007-01-10 19:10:37.000000000 +0000 +++ davinci-8020-5505/linux-2.6.19.2/drivers/i2c/chips/isp1301_omap.c 2007-01-11 07:38:19.000000000 +0000 @@ -35,7 +35,11 @@ #include #include +#include + +#include #include +#include #ifndef DEBUG @@ -44,7 +48,7 @@ #define DRIVER_VERSION "24 August 2004" -#define DRIVER_NAME (isp1301_driver.name) +#define DRIVER_NAME (isp1301_driver.driver.name) MODULE_DESCRIPTION("ISP1301 USB OTG Transceiver Driver"); MODULE_LICENSE("GPL"); @@ -55,6 +59,7 @@ void (*i2c_release)(struct device *dev); int irq; + int irq_type; u32 last_otg_ctrl; unsigned working:1; @@ -90,14 +95,11 @@ /*-------------------------------------------------------------------------*/ -#ifdef CONFIG_MACH_OMAP_H2 +#if defined(CONFIG_MACH_OMAP_H2) || \ + defined(CONFIG_MACH_OMAP_H3) /* board-specific PM hooks */ -#include -#include -#include - #if defined(CONFIG_TPS65010) || defined(CONFIG_TPS65010_MODULE) @@ -128,17 +130,30 @@ } -/* products will deliver OTG messages with LEDs, GUI, etc */ -static inline void notresponding(struct isp1301 *isp) +#else + +static void enable_vbus_draw(struct isp1301 *isp, unsigned mA) { - printk(KERN_NOTICE "OTG device not responding.\n"); + pr_debug("%s UNIMPL\n", __FUNCTION__); } +static void enable_vbus_source(struct isp1301 *isp) +{ + pr_debug("%s UNIMPL\n", __FUNCTION__); +} #endif /*-------------------------------------------------------------------------*/ +/* products will deliver OTG messages with LEDs, GUI, etc */ +static inline void notresponding(struct isp1301 *isp) +{ + printk(KERN_NOTICE "OTG device not responding.\n"); +} + +/*-------------------------------------------------------------------------*/ + /* only two addresses possible */ #define ISP_BASE 0x2c static unsigned short normal_i2c[] = { @@ -514,6 +529,7 @@ static void update_otg1(struct isp1301 *isp, u8 int_src) { u32 otg_ctrl; + u8 int_id; otg_ctrl = OTG_CTRL_REG & OTG_CTRL_MASK @@ -527,7 +543,10 @@ } if (int_src & INTR_VBUS_VLD) otg_ctrl |= OTG_VBUSVLD; - if (int_src & INTR_ID_GND) { /* default-A */ + + int_id = isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE); + + if (int_id & INTR_ID_GND) { /* default-A */ if (isp->otg.state == OTG_STATE_B_IDLE || isp->otg.state == OTG_STATE_UNDEFINED) { a_idle(isp, "init"); @@ -908,7 +927,7 @@ if (otg_dev) status = request_irq(otg_dev->resource[1].start, omap_otg_irq, - IRQF_DISABLED, DRIVER_NAME, isp); + SA_INTERRUPT, DRIVER_NAME, isp); else status = -ENODEV; @@ -1082,7 +1101,7 @@ /* update the OTG controller state to match the isp1301; may * trigger OPRT_CHG irqs for changes going to the isp1301. */ - update_otg1(isp, isp_stat); + update_otg1(isp, stat); // pass the actual interrupt latch status update_otg2(isp, isp_bstat); check_state(isp, __FUNCTION__); #endif @@ -1223,6 +1242,9 @@ if (machine_is_omap_h2()) omap_free_gpio(2); + if (machine_is_omap_h3()) + omap_free_gpio(14); + isp->timer.data = 0; set_bit(WORK_STOP, &isp->todo); del_timer_sync(&isp->timer); @@ -1301,7 +1323,7 @@ power_up(isp); - if (machine_is_omap_h2()) + 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"); @@ -1364,13 +1386,13 @@ power_up(isp); isp->otg.state = OTG_STATE_B_IDLE; - if (machine_is_omap_h2()) + 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_SESS_VLD | INTR_VBUS_VLD); isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, - INTR_VBUS_VLD); + INTR_VBUS_VLD | INTR_SESS_VLD); dev_info(&isp->client.dev, "B-Peripheral sessions ok\n"); dump_regs(isp, __FUNCTION__); @@ -1447,6 +1469,10 @@ * So do this part as early as possible... */ switch (isp->otg.state) { + case OTG_STATE_B_PERIPHERAL: + isp->otg.state = OTG_STATE_B_WAIT_ACON; + isp1301_defer_work(isp, WORK_UPDATE_ISP); + break; case OTG_STATE_B_HOST: isp->otg.state = OTG_STATE_B_PERIPHERAL; /* caller will suspend next */ @@ -1500,6 +1526,7 @@ isp->timer.data = (unsigned long) isp; isp->irq = -1; + isp->irq_type = 0; isp->client.addr = address; i2c_set_clientdata(&isp->client, isp); isp->client.adapter = bus; @@ -1562,23 +1589,34 @@ } #endif - if (machine_is_omap_h2()) { + if (machine_is_omap_h2() || machine_is_omap_h3()) { /* full speed signaling by default */ isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SPEED_REG); isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, MC2_SPD_SUSP_CTRL); + } + if (machine_is_omap_h2()) { /* IRQ wired at M14 */ omap_cfg_reg(M14_1510_GPIO2); isp->irq = OMAP_GPIO_IRQ(2); omap_request_gpio(2); omap_set_gpio_direction(2, 1); - omap_set_gpio_edge_ctrl(2, OMAP_GPIO_FALLING_EDGE); + isp->irq_type = SA_TRIGGER_FALLING; + } + + if (machine_is_omap_h3()) { + /* IRQ wired at N21 */ + omap_cfg_reg(N21_1710_GPIO14); + isp->irq = OMAP_GPIO_IRQ(14); + omap_request_gpio(14); + omap_set_gpio_direction(14, 1); + isp->irq_type = SA_TRIGGER_FALLING; } status = request_irq(isp->irq, isp1301_irq, - IRQF_SAMPLE_RANDOM, DRIVER_NAME, isp); + isp->irq_type, DRIVER_NAME, isp); if (status < 0) { dev_dbg(&i2c->dev, "can't get IRQ %d, err %d\n", isp->irq, status);