/* I2C operations are always synchronous, and require a task context. * With unloaded systems, using the shared workqueue seems to suffice * to satisfy the 100msec A_WAIT_VRISE timeout... */ static void evm_deferred_drvvbus(void *_musb) { int is_on = vbus_state; #ifdef CONFIG_MACH_DAVINCI_EVM davinci_i2c_expander_op(0x3a, USB_DRVVBUS, !is_on); #endif #ifdef CONFIG_MACH_DAVINCI_HD_EVM davinci_i2c_expander_op(0x3a, USB_FB_DM646X, !is_on); #endif vbus_state = is_on; }
static void davinci_source_power(struct musb *musb, int is_on, int immediate) { if (is_on) is_on = 1; if (vbus_state == is_on) return; vbus_state = !is_on; /* 0/1 vs "-1 == unknown/init" */ #ifdef CONFIG_MACH_DAVINCI_EVM if (machine_is_davinci_evm()) { #ifdef CONFIG_MACH_DAVINCI_EVM_OTG /* modified EVM board switching VBUS with GPIO(6) not I2C * NOTE: PINMUX0.RGB888 (bit23) must be clear */ if (is_on) gpio_set(GPIO(6)); else gpio_clear(GPIO(6)); immediate = 1; #else if (immediate) davinci_i2c_expander_op(0x3a, USB_DRVVBUS, !is_on); else schedule_work(&evm_vbus_work); #endif } #endif if (immediate) vbus_state = is_on; }
static __init void dm644x_evm_expander_setup(void) { #if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \ defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE) /* * ATA_SEL is 1 -> disable, 0 -> enable. * CF_SEL is 1 -> disable, 0 -> enable. * * Ensure both are not enabled at once. */ #ifdef CONFIG_DAVINCI_EVM_CF_SUPPORT davinci_i2c_expander_op(ATA_SEL, 1); davinci_i2c_expander_op(CF_RESET, 1); davinci_i2c_expander_op(CF_SEL, 0); #else davinci_i2c_expander_op(CF_SEL, 1); davinci_i2c_expander_op(ATA_SEL, 0); #endif #endif }
/* I2C operations are always synchronous, and require a task context. * With unloaded systems, using the shared workqueue seems to suffice * to satisfy the 100msec A_WAIT_VRISE timeout... */ static void evm_deferred_drvvbus(struct work_struct *ignored) { davinci_i2c_expander_op(0x3a, USB_DRVVBUS, vbus_state); vbus_state = !vbus_state; }
static int __init i2c_davinci_init(void) { int status; struct device *dev = NULL; DEB0("%s %s", __TIME__, __DATE__); DEB1("i2c_davinci_init()"); if (cpu_is_davinci_dm6467()) davinci_i2c_expander_op (0x3A, I2C_INT_DM646X, 0); /* * NOTE: On DaVinci EVM, the i2c bus frequency is set to 20kHz * so that the MSP430, which is doing software i2c, has * some extra processing time */ if (machine_is_davinci_evm()) i2c_davinci_busFreq = 20; else if (machine_is_davinci_dm6467_evm()) i2c_davinci_busFreq = 100; else if (i2c_davinci_busFreq > 200) i2c_davinci_busFreq = 400; /*Fast mode */ else i2c_davinci_busFreq = 100; /*Standard mode */ i2c_clock = clk_get (dev, "I2CCLK"); if (IS_ERR(i2c_clock)) return -1; clk_use (i2c_clock); clk_enable (i2c_clock); i2c_davinci_inputClock = clk_get_rate (i2c_clock); DEB1 ("IP CLOCK = %ld", i2c_davinci_inputClock); memset(&i2c_davinci_dev, 0, sizeof(i2c_davinci_dev)); init_waitqueue_head(&i2c_davinci_dev.cmd_wait); i2c_davinci_dev.regs = (davinci_i2cregsovly)I2C_BASE; status = (int)request_region(I2C_BASE, I2C_IOSIZE, MODULE_NAME); if (!status) { i2c_err("I2C is already in use\n"); return -ENODEV; } status = request_irq(IRQ_I2C, i2c_davinci_isr, 0, "i2c", &i2c_davinci_dev); if (status) { i2c_err("failed to request I2C IRQ"); goto do_release_region; } i2c_set_adapdata(&i2c_davinci_adap, &i2c_davinci_dev); status = i2c_add_adapter(&i2c_davinci_adap); if (status) { i2c_err("failed to add adapter"); goto do_free_irq; } i2c_davinci_reset(&i2c_davinci_dev); if (driver_register(&davinci_i2c_driver) != 0) printk(KERN_ERR "Driver register failed for davinci_i2c\n"); if (platform_device_register(&davinci_i2c_device) != 0) { printk(KERN_ERR "Device register failed for i2c\n"); driver_unregister(&davinci_i2c_driver); } return 0; do_free_irq: free_irq(IRQ_I2C, &i2c_davinci_dev); do_release_region: release_region(I2C_BASE, I2C_IOSIZE); return status; }