From 0bf9eff3d7de08b93a19c60f34ab40c3154ac1ef Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 28 Mar 2008 08:04:09 -0400 Subject: [PATCH] i2c: tea5761: New-style i2c driver This patch updates the fm radio driver for tea5761 chip. It also moves board dependent code to its correct board file place. Signed-off-by: Eduardo Valentin Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-n800.c | 33 +++++++ drivers/media/radio/radio-tea5761.c | 140 ++-------------------------- 2 files changed, 42 insertions(+), 131 deletions(-) diff --git a/arch/arm/mach-omap2/board-n800.c b/arch/arm/mach-omap2/board-n800.c index 34f1c37b99e..758e2c1864f 100644 --- a/arch/arm/mach-omap2/board-n800.c +++ b/arch/arm/mach-omap2/board-n800.c @@ -258,6 +258,33 @@ static void tsc2301_dev_init(void) } } +static int __init tea5761_dev_init(void) +{ + const struct omap_tea5761_config *info; + int enable_gpio = 0; + + info = omap_get_config(OMAP_TAG_TEA5761, struct omap_tea5761_config); + if (info) + enable_gpio = info->enable_gpio; + + if (enable_gpio) { + pr_debug("Enabling tea5761 at GPIO %d\n", + enable_gpio); + + if (omap_request_gpio(enable_gpio) < 0) { + printk(KERN_ERR "Can't request GPIO %d\n", + enable_gpio); + return -ENODEV; + } + + omap_set_gpio_direction(enable_gpio, 0); + udelay(50); + omap_set_gpio_dataout(enable_gpio, 1); + } + + return 0; +} + static struct omap2_mcspi_device_config tsc2301_mcspi_config = { .turbo_mode = 0, .single_channel = 1, @@ -470,6 +497,11 @@ static struct i2c_board_info __initdata n800_i2c_board_info_2[] = { .platform_data = &n800_tcm825x_platform_data, }, #endif +#if defined(CONFIG_RADIO_TEA5761) || defined(CONFIG_RADIO_TEA5761_MODULE) + { + I2C_BOARD_INFO("tea5761", 0x10), + }, +#endif }; void __init nokia_n800_common_init(void) @@ -500,6 +532,7 @@ static void __init nokia_n800_init(void) n800_audio_init(&tsc2301_config); n800_ts_set_config(); tsc2301_dev_init(); + tea5761_dev_init(); omap_register_gpio_switches(n800_gpio_switches, ARRAY_SIZE(n800_gpio_switches)); } diff --git a/drivers/media/radio/radio-tea5761.c b/drivers/media/radio/radio-tea5761.c index ac0f62100c1..0fb0cdc5b46 100644 --- a/drivers/media/radio/radio-tea5761.c +++ b/drivers/media/radio/radio-tea5761.c @@ -23,8 +23,6 @@ #include #include #include -#include -#include #define DRIVER_NAME "tea5761" @@ -74,14 +72,6 @@ #define TEA5761_FREQ_LOW 87500 #define TEA5761_FREQ_HIGH 108000 -/* Probe for TEA5761 twice since the version N4B seems to be - * broken and needs two probes to be found */ -static unsigned short normal_i2c[] = { - TEA5761_I2C_ADDR, TEA5761_I2C_ADDR, I2C_CLIENT_END -}; - -I2C_CLIENT_INSMOD; - struct tea5761_regs { u16 intreg; u16 frqset; @@ -423,67 +413,22 @@ static struct video_device tea5761_video_device = { .release = video_device_release }; -static int tea5761_probe(struct i2c_adapter *adapter, int address, - int kind) +static int tea5761_i2c_driver_probe(struct i2c_client *client) { - struct i2c_client *client; struct video_device *video_dev; int err = 0; - static const char *client_name = "TEA5761 FM-Radio"; struct tea5761_device *tea = &tea5761; - struct tea5761_regs *r = &tea->regs; mutex_init(&tea->mutex); - /* I2C detection and initialization */ - client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (client == NULL) { - dev_err(&adapter->dev, DRIVER_NAME - ": couldn't allocate memory\n"); - return -ENOMEM; - } - tea->i2c_dev = client; - client->addr = address; - client->adapter = adapter; - client->driver = &tea5761_driver; - client->dev.driver = &tea5761_driver.driver; - client->flags = 0; - strlcpy(client->name, client_name, I2C_NAME_SIZE); - - if (kind < 0) { - if (tea5761_read_regs(tea) < 0) { - dev_info(&client->dev, - "chip read failed for %d-%04x\n", - adapter->nr, address); - goto err_tea_dev; - } - if (r->chipid != TEA5761_CHIPID) { - dev_info(&client->dev, - "bad chipid (0x%04x) at %d-%04x\n", - r->chipid, adapter->nr, address); - goto err_tea_dev; - } - if ((r->manid & 0x0fff) != TEA5761_MANID) { - dev_info(&client->dev, - "bad manid (0x%04x) at %d-%04x\n", - r->manid, adapter->nr, address); - goto err_tea_dev; - } - } - - err = i2c_attach_client(client); - if (err) { - dev_err(&client->dev, "couldn't attach to address %d-%04x\n", - adapter->nr, address); - goto err_tea_dev; - } + tea->i2c_dev = client; /* V4L initialization */ video_dev = video_device_alloc(); if (video_dev == NULL) { dev_err(&client->dev, "couldn't allocate memory\n"); err = -ENOMEM; - goto err_i2c_attach; + goto exit; } tea->video_dev = video_dev; @@ -506,105 +451,39 @@ static int tea5761_probe(struct i2c_adapter *adapter, int address, goto err_video_alloc; } - dev_info(&client->dev, "tea5761 (version %d) detected at %d-%04x\n", - (tea->regs.manid >> 12) & 0xf, adapter->nr, address); + dev_info(&client->dev, "tea5761 (version %d) detected\n", + (tea->regs.manid >> 12) & 0xf); return 0; err_video_alloc: video_device_release(video_dev); -err_i2c_attach: - i2c_detach_client(client); -err_tea_dev: +exit: kfree(client); return err; } -static int tea5761_attach_adapter(struct i2c_adapter *adapter) -{ - if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) - return -EINVAL; - - return i2c_probe(adapter, &addr_data, tea5761_probe); -} - -static int tea5761_detach_client(struct i2c_client *client) +static int tea5761_i2c_driver_remove(struct i2c_client *client) { struct video_device *vd = i2c_get_clientdata(client); - i2c_detach_client(client); video_unregister_device(vd); - kfree(client); return 0; } static struct i2c_driver tea5761_driver = { - .id = I2C_DRIVERID_TUNER, .driver = { .name = DRIVER_NAME, }, - .attach_adapter = tea5761_attach_adapter, - .detach_client = tea5761_detach_client, + .probe = tea5761_i2c_driver_probe, + .remove = tea5761_i2c_driver_remove, }; -#if CONFIG_ARCH_OMAP -/* No way to pass platform device data. Enable here all the TEA5761 - * devices, since I2C address scanning will need them to respond. - */ -static int enable_gpio; - -static int __init tea5761_dev_init(void) -{ - const struct omap_tea5761_config *info; - - info = omap_get_config(OMAP_TAG_TEA5761, struct omap_tea5761_config); - if (info) { - enable_gpio = info->enable_gpio; - } - - if (enable_gpio) { - pr_debug(DRIVER_NAME ": enabling tea5761 at GPIO %d\n", - enable_gpio); - - if (omap_request_gpio(enable_gpio) < 0) { - printk(KERN_ERR DRIVER_NAME ": can't request GPIO %d\n", - enable_gpio); - return -ENODEV; - } - - omap_set_gpio_direction(enable_gpio, 0); - udelay(50); - omap_set_gpio_dataout(enable_gpio, 1); - } - - return 0; -} - -static void __exit tea5761_dev_exit(void) -{ - if (enable_gpio) { - omap_set_gpio_dataout(enable_gpio, 0); - omap_free_gpio(enable_gpio); - } -} -#else -static int __init tea5761_dev_init(void) -{ -} - -static void __exit tea5761_dev_exit(void) -{ -} -#endif - static int __init tea5761_init(void) { int res; - if ((res = tea5761_dev_init()) < 0) - return res; - if ((res = i2c_add_driver(&tea5761_driver))) { printk(KERN_ERR DRIVER_NAME ": driver registration failed\n"); return res; @@ -616,7 +495,6 @@ static int __init tea5761_init(void) static void __exit tea5761_exit(void) { i2c_del_driver(&tea5761_driver); - tea5761_dev_exit(); } MODULE_AUTHOR("Timo Teräs"); -- 2.41.0