ALSA: ASoC: Convert wm8990 to a new-style i2c driver

Convert the wm8990 codec driver to the new (standard) device driver
binding model. After this change, WM8990 devices are no longer
discovered automatically and must instead be instantiated explicitly.

Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
Jean Delvare 2008-09-01 18:47:02 +01:00 committed by Jaroslav Kysela
parent 81297c8a4b
commit e5d3fd38f9
2 changed files with 54 additions and 50 deletions

View File

@ -1477,81 +1477,86 @@ static struct snd_soc_device *wm8990_socdev;
* low = 0x34 * low = 0x34
* high = 0x36 * high = 0x36
*/ */
static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
/* Magic definition of all other variables and things */ static int wm8990_i2c_probe(struct i2c_client *i2c,
I2C_CLIENT_INSMOD; const struct i2c_device_id *id)
static struct i2c_driver wm8990_i2c_driver;
static struct i2c_client client_template;
static int wm8990_codec_probe(struct i2c_adapter *adap, int addr, int kind)
{ {
struct snd_soc_device *socdev = wm8990_socdev; struct snd_soc_device *socdev = wm8990_socdev;
struct wm8990_setup_data *setup = socdev->codec_data;
struct snd_soc_codec *codec = socdev->codec; struct snd_soc_codec *codec = socdev->codec;
struct i2c_client *i2c;
int ret; int ret;
if (addr != setup->i2c_address)
return -ENODEV;
client_template.adapter = adap;
client_template.addr = addr;
i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
if (i2c == NULL)
return -ENOMEM;
i2c_set_clientdata(i2c, codec); i2c_set_clientdata(i2c, codec);
codec->control_data = i2c; codec->control_data = i2c;
ret = i2c_attach_client(i2c);
if (ret < 0) {
pr_err("failed to attach codec at addr %x\n", addr);
goto err;
}
ret = wm8990_init(socdev); ret = wm8990_init(socdev);
if (ret < 0) { if (ret < 0)
pr_err("failed to initialise WM8990\n"); pr_err("failed to initialise WM8990\n");
goto err;
}
return ret;
err:
kfree(i2c);
return ret; return ret;
} }
static int wm8990_i2c_detach(struct i2c_client *client) static int wm8990_i2c_remove(struct i2c_client *client)
{ {
struct snd_soc_codec *codec = i2c_get_clientdata(client); struct snd_soc_codec *codec = i2c_get_clientdata(client);
i2c_detach_client(client);
kfree(codec->reg_cache); kfree(codec->reg_cache);
kfree(client);
return 0; return 0;
} }
static int wm8990_i2c_attach(struct i2c_adapter *adap) static const struct i2c_device_id wm8990_i2c_id[] = {
{ { "wm8990", 0 },
return i2c_probe(adap, &addr_data, wm8990_codec_probe); { }
} };
MODULE_DEVICE_TABLE(i2c, wm8990_i2c_id);
static struct i2c_driver wm8990_i2c_driver = { static struct i2c_driver wm8990_i2c_driver = {
.driver = { .driver = {
.name = "WM8990 I2C Codec", .name = "WM8990 I2C Codec",
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
.attach_adapter = wm8990_i2c_attach, .probe = wm8990_i2c_probe,
.detach_client = wm8990_i2c_detach, .remove = wm8990_i2c_remove,
.command = NULL, .id_table = wm8990_i2c_id,
}; };
static struct i2c_client client_template = { static int wm8990_add_i2c_device(struct platform_device *pdev,
.name = "WM8990", const struct wm8990_setup_data *setup)
.driver = &wm8990_i2c_driver, {
}; struct i2c_board_info info;
struct i2c_adapter *adapter;
struct i2c_client *client;
int ret;
ret = i2c_add_driver(&wm8990_i2c_driver);
if (ret != 0) {
dev_err(&pdev->dev, "can't add i2c driver\n");
return ret;
}
memset(&info, 0, sizeof(struct i2c_board_info));
info.addr = setup->i2c_address;
strlcpy(info.type, "wm8990", I2C_NAME_SIZE);
adapter = i2c_get_adapter(setup->i2c_bus);
if (!adapter) {
dev_err(&pdev->dev, "can't get i2c adapter %d\n",
setup->i2c_bus);
goto err_driver;
}
client = i2c_new_device(adapter, &info);
i2c_put_adapter(adapter);
if (!client) {
dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
(unsigned int)info.addr);
goto err_driver;
}
return 0;
err_driver:
i2c_del_driver(&wm8990_i2c_driver);
return -ENODEV;
}
#endif #endif
static int wm8990_probe(struct platform_device *pdev) static int wm8990_probe(struct platform_device *pdev)
@ -1584,11 +1589,8 @@ static int wm8990_probe(struct platform_device *pdev)
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
if (setup->i2c_address) { if (setup->i2c_address) {
normal_i2c[0] = setup->i2c_address;
codec->hw_write = (hw_write_t)i2c_master_send; codec->hw_write = (hw_write_t)i2c_master_send;
ret = i2c_add_driver(&wm8990_i2c_driver); ret = wm8990_add_i2c_device(pdev, setup);
if (ret != 0)
printk(KERN_ERR "can't add i2c driver");
} }
#else #else
/* Add other interfaces here */ /* Add other interfaces here */
@ -1612,6 +1614,7 @@ static int wm8990_remove(struct platform_device *pdev)
snd_soc_free_pcms(socdev); snd_soc_free_pcms(socdev);
snd_soc_dapm_free(socdev); snd_soc_dapm_free(socdev);
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
i2c_unregister_device(codec->control_data);
i2c_del_driver(&wm8990_i2c_driver); i2c_del_driver(&wm8990_i2c_driver);
#endif #endif
kfree(codec->private_data); kfree(codec->private_data);

View File

@ -827,6 +827,7 @@
#define WM8990_AINRMUX_PWR_BIT 3 #define WM8990_AINRMUX_PWR_BIT 3
struct wm8990_setup_data { struct wm8990_setup_data {
unsigned i2c_bus;
unsigned short i2c_address; unsigned short i2c_address;
}; };