Based on David Brownell's patch for tps65010, this patch finish conversting isp1301_omap.c to new-style i2c driver. Signed-off-by: Felipe Balbi <felipe.lima@xxxxxxxxxxx> --- arch/arm/mach-omap1/board-h2.c | 10 ++ arch/arm/mach-omap1/board-h3.c | 5 + arch/arm/mach-omap2/board-h4.c | 5 + drivers/i2c/chips/isp1301_omap.c | 179 +++++++++++--------------------------- 4 files changed, 71 insertions(+), 128 deletions(-) diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c index 1ba59bb..f3e1398 100644 --- a/arch/arm/mach-omap1/board-h2.c +++ b/arch/arm/mach-omap1/board-h2.c @@ -435,11 +435,21 @@ static void __init h2_init_smc91x(void) } } +static struct i2c_board_info __initdata h2_i2c_board_info[] = { + { + I2C_BOARD_INFO("isp1301_omap", 0x2d), + .type = "isp1301_omap", + .irq = OMAP_GPIOIRQ(2), + }, +}; + static void __init h2_init_irq(void) { omap1_init_common_hw(); omap_init_irq(); omap_gpio_init(); + i2c_register_board_info(1, h2_i2c_board_info, + ARRAY_SIZE(h2_i2c_board_info)); h2_init_smc91x(); } diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c index 092c814..1020dd7 100644 --- a/arch/arm/mach-omap1/board-h3.c +++ b/arch/arm/mach-omap1/board-h3.c @@ -667,6 +667,11 @@ static struct i2c_board_info __initdata h3_i2c_board_info[] = { .platform_data = &h3_ov9640_platform_data, }, #endif + { + I2C_BOARD_INFO("isp1301_omap", 0x2d), + .type = "isp1301_omap", + .irq = OMAP_GPIO_IRQ(14), + }, }; extern void __init h3_mmc_init(void); diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c index df434d7..a94f229 100644 --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c @@ -640,6 +640,11 @@ static struct i2c_board_info __initdata h4_i2c_board_info[] = { I2C_BOARD_INFO("menelaus", 0x72), .irq = INT_24XX_SYS_NIRQ, }, + { + I2C_BOARD_INFO("isp1301_omap", 0x2d), + .type = "isp1301_omap", + .irq = OMAP_GPIOIRQ(125), + }, #if defined(CONFIG_VIDEO_OV9640) || defined(CONFIG_VIDEO_OV9640_MODULE) { I2C_BOARD_INFO("ov9640", 0x30), diff --git a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c index ffb4477..5fb27cb 100644 --- a/drivers/i2c/chips/isp1301_omap.c +++ b/drivers/i2c/chips/isp1301_omap.c @@ -33,20 +33,13 @@ #include <linux/usb/otg.h> #include <linux/i2c.h> #include <linux/workqueue.h> - -#include <asm/irq.h> -#include <asm/mach-types.h> - -#include <asm/arch/gpio.h> #include <asm/arch/usb.h> -#include <asm/arch/mux.h> #ifndef DEBUG #undef VERBOSE #endif - #define DRIVER_VERSION "24 August 2004" #define DRIVER_NAME (isp1301_driver.driver.name) @@ -56,12 +49,8 @@ MODULE_LICENSE("GPL"); struct isp1301 { struct otg_transceiver otg; struct i2c_client *client; - struct i2c_client c; void (*i2c_release)(struct device *dev); - int irq; - int irq_type; - u32 last_otg_ctrl; unsigned working:1; @@ -156,13 +145,6 @@ static inline void notresponding(struct isp1301 *isp) /*-------------------------------------------------------------------------*/ /* only two addresses possible */ -#define ISP_BASE 0x2c -static unsigned short normal_i2c[] = { - ISP_BASE, ISP_BASE + 1, - I2C_CLIENT_END }; - -I2C_CLIENT_INSMOD; - static struct i2c_driver isp1301_driver; /* smbus apis are used for portability */ @@ -1216,9 +1198,11 @@ static void isp1301_timer(unsigned long _isp) static void isp1301_release(struct device *dev) { - struct isp1301 *isp; + struct i2c_client *client; + struct isp1301 *isp; - isp = container_of(dev, struct isp1301, c.dev); + client = container_of(dev, struct i2c_client, dev); + isp = i2c_get_clientdata(client); /* ugly -- i2c hijacks our memory hook to wait_for_completion() */ if (isp->i2c_release) @@ -1228,36 +1212,27 @@ static void isp1301_release(struct device *dev) static struct isp1301 *the_transceiver; -static int isp1301_detach_client(struct i2c_client *i2c) +static int __exit isp1301_remove(struct i2c_client *client) { - struct isp1301 *isp; - - isp = container_of(i2c, struct isp1301, c); + struct isp1301 *isp = i2c_get_clientdata(client); isp1301_clear_bits(isp, ISP1301_INTERRUPT_FALLING, ~0); isp1301_clear_bits(isp, ISP1301_INTERRUPT_RISING, ~0); - free_irq(isp->irq, isp); + + if (client->irq > 0) + free_irq(client->irq, isp); #ifdef CONFIG_USB_OTG otg_unbind(isp); #endif - if (machine_is_omap_h2()) - omap_free_gpio(2); - - 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); flush_scheduled_work(); - put_device(&i2c->dev); + put_device(&client->dev); the_transceiver = 0; - return i2c_detach_client(i2c); + return 0; } /*-------------------------------------------------------------------------*/ @@ -1327,10 +1302,6 @@ 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); @@ -1513,11 +1484,10 @@ isp1301_start_hnp(struct otg_transceiver *dev) /*-------------------------------------------------------------------------*/ /* no error returns, they'd just make bus scanning stop */ -static int isp1301_probe(struct i2c_adapter *bus, int address, int kind) +static int __init isp1301_probe(struct i2c_client *client) { int status; struct isp1301 *isp; - struct i2c_client *i2c; if (the_transceiver) return 0; @@ -1530,46 +1500,35 @@ static int isp1301_probe(struct i2c_adapter *bus, int address, int kind) init_timer(&isp->timer); isp->timer.function = isp1301_timer; isp->timer.data = (unsigned long) isp; - - isp->irq = -1; - isp->irq_type = 0; - isp->c.addr = address; - i2c_set_clientdata(&isp->c, isp); - isp->c.adapter = bus; - isp->c.driver = &isp1301_driver; - strlcpy(isp->c.name, DRIVER_NAME, I2C_NAME_SIZE); - isp->client = i2c = &isp->c; + isp->client = client; /* if this is a true probe, verify the chip ... */ - if (kind < 0) { - status = isp1301_get_u16(isp, ISP1301_VENDOR_ID); - if (status != I2C_VENDOR_ID_PHILIPS) { - dev_dbg(&bus->dev, "addr %d not philips id: %d\n", - address, status); - goto fail1; - } - status = isp1301_get_u16(isp, ISP1301_PRODUCT_ID); - if (status != I2C_PRODUCT_ID_PHILIPS_1301) { - dev_dbg(&bus->dev, "%d not isp1301, %d\n", - address, status); - goto fail1; - } + status = isp1301_get_u16(isp, ISP1301_VENDOR_ID); + if (status != I2C_VENDOR_ID_PHILIPS) { + dev_dbg(&client->dev, "not philips id: %d\n", + status); + goto fail1; + } + status = isp1301_get_u16(isp, ISP1301_PRODUCT_ID); + if (status != I2C_PRODUCT_ID_PHILIPS_1301) { + dev_dbg(&client->dev, "not isp1301, %d\n", + status); + goto fail1; } - status = i2c_attach_client(i2c); if (status < 0) { - dev_dbg(&bus->dev, "can't attach %s to device %d, err %d\n", - DRIVER_NAME, address, status); + dev_dbg(&client->dev, "can't attach %s to device, err %d\n", + DRIVER_NAME, status); fail1: kfree(isp); return 0; } - isp->i2c_release = i2c->dev.release; - i2c->dev.release = isp1301_release; + isp->i2c_release = client->dev.release; + client->dev.release = isp1301_release; /* initial development used chiprev 2.00 */ - status = i2c_smbus_read_word_data(i2c, ISP1301_BCD_DEVICE); - dev_info(&i2c->dev, "chiprev %x.%02x, driver " DRIVER_VERSION "\n", + status = i2c_smbus_read_word_data(client, ISP1301_BCD_DEVICE); + dev_info(&client->dev, "chiprev %x.%02x, driver " DRIVER_VERSION "\n", status >> 8, status & 0xff); /* make like power-on reset */ @@ -1590,60 +1549,25 @@ fail1: #ifdef CONFIG_USB_OTG status = otg_bind(isp); if (status < 0) { - dev_dbg(&i2c->dev, "can't bind OTG\n"); + dev_dbg(&client->dev, "can't bind OTG\n"); goto fail2; } #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, - 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); - isp->irq_type = IRQF_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 = IRQF_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); + status = request_irq(client->irq, isp1301_irq, + IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_FALLING, + DRIVER_NAME, isp); if (status < 0) { - dev_dbg(&i2c->dev, "can't get IRQ %d, err %d\n", - isp->irq, status); + dev_dbg(&client->dev, "can't get IRQ %d, err %d\n", + client->irq, status); #ifdef CONFIG_USB_OTG fail2: #endif - i2c_detach_client(i2c); + i2c_detach_client(client); goto fail1; } - isp->otg.dev = &isp->client->dev; + isp->otg.dev = &client->dev; isp->otg.label = DRIVER_NAME; isp->otg.set_host = isp1301_set_host, @@ -1660,43 +1584,42 @@ fail2: update_otg1(isp, isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE)); update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS)); #endif - dump_regs(isp, __FUNCTION__); #ifdef VERBOSE mod_timer(&isp->timer, jiffies + TIMER_JIFFIES); - dev_dbg(&i2c->dev, "scheduled timer, %d min\n", TIMER_MINUTES); + dev_dbg(&client->dev, "scheduled timer, %d min\n", TIMER_MINUTES); #endif status = otg_set_transceiver(&isp->otg); if (status < 0) - dev_err(&i2c->dev, "can't register transceiver, %d\n", + dev_err(&client->dev, "can't register transceiver, %d\n", status); return 0; } -static int isp1301_scan_bus(struct i2c_adapter *bus) -{ - if (!i2c_check_functionality(bus, I2C_FUNC_SMBUS_BYTE_DATA - | I2C_FUNC_SMBUS_READ_WORD_DATA)) - return -EINVAL; - return i2c_probe(bus, &addr_data, isp1301_probe); -} - static struct i2c_driver isp1301_driver = { .driver = { .name = "isp1301_omap", }, - .attach_adapter = isp1301_scan_bus, - .detach_client = isp1301_detach_client, + .probe = isp1301_probe, + .remove = __exit_p(isp1301_remove), }; /*-------------------------------------------------------------------------*/ static int __init isp_init(void) { - return i2c_add_driver(&isp1301_driver); + int status = -ENODEV; + + printk(KERN_INFO "%s: version %s\n", DRIVER_NAME, DRIVER_VERSION); + + status = i2c_add_driver(&isp1301_driver); + if (status) + printk(KERN_ERR "%s failed to probe\n", DRIVER_NAME); + + return status; } module_init(isp_init); -- 1.5.3.7.1149.g591a - To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html