Commit 0bf9eff3 authored by Eduardo Valentin's avatar Eduardo Valentin Committed by Tony Lindgren

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: default avatarEduardo Valentin <eduardo.valentin@indt.org.br>
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
parent ac3bf8ad
...@@ -258,6 +258,33 @@ static void tsc2301_dev_init(void) ...@@ -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 = { static struct omap2_mcspi_device_config tsc2301_mcspi_config = {
.turbo_mode = 0, .turbo_mode = 0,
.single_channel = 1, .single_channel = 1,
...@@ -470,6 +497,11 @@ static struct i2c_board_info __initdata n800_i2c_board_info_2[] = { ...@@ -470,6 +497,11 @@ static struct i2c_board_info __initdata n800_i2c_board_info_2[] = {
.platform_data = &n800_tcm825x_platform_data, .platform_data = &n800_tcm825x_platform_data,
}, },
#endif #endif
#if defined(CONFIG_RADIO_TEA5761) || defined(CONFIG_RADIO_TEA5761_MODULE)
{
I2C_BOARD_INFO("tea5761", 0x10),
},
#endif
}; };
void __init nokia_n800_common_init(void) void __init nokia_n800_common_init(void)
...@@ -500,6 +532,7 @@ static void __init nokia_n800_init(void) ...@@ -500,6 +532,7 @@ static void __init nokia_n800_init(void)
n800_audio_init(&tsc2301_config); n800_audio_init(&tsc2301_config);
n800_ts_set_config(); n800_ts_set_config();
tsc2301_dev_init(); tsc2301_dev_init();
tea5761_dev_init();
omap_register_gpio_switches(n800_gpio_switches, omap_register_gpio_switches(n800_gpio_switches,
ARRAY_SIZE(n800_gpio_switches)); ARRAY_SIZE(n800_gpio_switches));
} }
......
...@@ -23,8 +23,6 @@ ...@@ -23,8 +23,6 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <media/v4l2-common.h> #include <media/v4l2-common.h>
#include <asm/arch/gpio.h>
#include <asm/arch/board.h>
#define DRIVER_NAME "tea5761" #define DRIVER_NAME "tea5761"
...@@ -74,14 +72,6 @@ ...@@ -74,14 +72,6 @@
#define TEA5761_FREQ_LOW 87500 #define TEA5761_FREQ_LOW 87500
#define TEA5761_FREQ_HIGH 108000 #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 { struct tea5761_regs {
u16 intreg; u16 intreg;
u16 frqset; u16 frqset;
...@@ -423,67 +413,22 @@ static struct video_device tea5761_video_device = { ...@@ -423,67 +413,22 @@ static struct video_device tea5761_video_device = {
.release = video_device_release .release = video_device_release
}; };
static int tea5761_probe(struct i2c_adapter *adapter, int address, static int tea5761_i2c_driver_probe(struct i2c_client *client)
int kind)
{ {
struct i2c_client *client;
struct video_device *video_dev; struct video_device *video_dev;
int err = 0; int err = 0;
static const char *client_name = "TEA5761 FM-Radio";
struct tea5761_device *tea = &tea5761; struct tea5761_device *tea = &tea5761;
struct tea5761_regs *r = &tea->regs;
mutex_init(&tea->mutex); 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; tea->i2c_dev = client;
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;
}
/* V4L initialization */ /* V4L initialization */
video_dev = video_device_alloc(); video_dev = video_device_alloc();
if (video_dev == NULL) { if (video_dev == NULL) {
dev_err(&client->dev, "couldn't allocate memory\n"); dev_err(&client->dev, "couldn't allocate memory\n");
err = -ENOMEM; err = -ENOMEM;
goto err_i2c_attach; goto exit;
} }
tea->video_dev = video_dev; tea->video_dev = video_dev;
...@@ -506,105 +451,39 @@ static int tea5761_probe(struct i2c_adapter *adapter, int address, ...@@ -506,105 +451,39 @@ static int tea5761_probe(struct i2c_adapter *adapter, int address,
goto err_video_alloc; goto err_video_alloc;
} }
dev_info(&client->dev, "tea5761 (version %d) detected at %d-%04x\n", dev_info(&client->dev, "tea5761 (version %d) detected\n",
(tea->regs.manid >> 12) & 0xf, adapter->nr, address); (tea->regs.manid >> 12) & 0xf);
return 0; return 0;
err_video_alloc: err_video_alloc:
video_device_release(video_dev); video_device_release(video_dev);
err_i2c_attach: exit:
i2c_detach_client(client);
err_tea_dev:
kfree(client); kfree(client);
return err; return err;
} }
static int tea5761_attach_adapter(struct i2c_adapter *adapter) static int tea5761_i2c_driver_remove(struct i2c_client *client)
{
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)
{ {
struct video_device *vd = i2c_get_clientdata(client); struct video_device *vd = i2c_get_clientdata(client);
i2c_detach_client(client);
video_unregister_device(vd); video_unregister_device(vd);
kfree(client);
return 0; return 0;
} }
static struct i2c_driver tea5761_driver = { static struct i2c_driver tea5761_driver = {
.id = I2C_DRIVERID_TUNER,
.driver = { .driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
}, },
.attach_adapter = tea5761_attach_adapter, .probe = tea5761_i2c_driver_probe,
.detach_client = tea5761_detach_client, .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) static int __init tea5761_init(void)
{ {
int res; int res;
if ((res = tea5761_dev_init()) < 0)
return res;
if ((res = i2c_add_driver(&tea5761_driver))) { if ((res = i2c_add_driver(&tea5761_driver))) {
printk(KERN_ERR DRIVER_NAME ": driver registration failed\n"); printk(KERN_ERR DRIVER_NAME ": driver registration failed\n");
return res; return res;
...@@ -616,7 +495,6 @@ static int __init tea5761_init(void) ...@@ -616,7 +495,6 @@ static int __init tea5761_init(void)
static void __exit tea5761_exit(void) static void __exit tea5761_exit(void)
{ {
i2c_del_driver(&tea5761_driver); i2c_del_driver(&tea5761_driver);
tea5761_dev_exit();
} }
MODULE_AUTHOR("Timo Ters"); MODULE_AUTHOR("Timo Ters");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment