Commit e5d3fd38 authored by Jean Delvare's avatar Jean Delvare Committed by Jaroslav Kysela

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: default avatarJean Delvare <khali@linux-fr.org>
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarJaroslav Kysela <perex@perex.cz>
parent 81297c8a
...@@ -1477,81 +1477,86 @@ static struct snd_soc_device *wm8990_socdev; ...@@ -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) ...@@ -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) ...@@ -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);
......
...@@ -827,6 +827,7 @@ ...@@ -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;
}; };
......
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