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:
parent
81297c8a4b
commit
e5d3fd38f9
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue