diff options
-rw-r--r-- | sound/soc/codecs/wm8990.c | 103 | ||||
-rw-r--r-- | sound/soc/codecs/wm8990.h | 1 |
2 files changed, 54 insertions, 50 deletions
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index dd995ef448b4..e1bb5059755a 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c | |||
@@ -1477,81 +1477,86 @@ static struct snd_soc_device *wm8990_socdev; | |||
1477 | * low = 0x34 | 1477 | * low = 0x34 |
1478 | * high = 0x36 | 1478 | * high = 0x36 |
1479 | */ | 1479 | */ |
1480 | static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END }; | ||
1481 | 1480 | ||
1482 | /* Magic definition of all other variables and things */ | 1481 | static int wm8990_i2c_probe(struct i2c_client *i2c, |
1483 | I2C_CLIENT_INSMOD; | 1482 | const struct i2c_device_id *id) |
1484 | |||
1485 | static struct i2c_driver wm8990_i2c_driver; | ||
1486 | static struct i2c_client client_template; | ||
1487 | |||
1488 | static int wm8990_codec_probe(struct i2c_adapter *adap, int addr, int kind) | ||
1489 | { | 1483 | { |
1490 | struct snd_soc_device *socdev = wm8990_socdev; | 1484 | struct snd_soc_device *socdev = wm8990_socdev; |
1491 | struct wm8990_setup_data *setup = socdev->codec_data; | ||
1492 | struct snd_soc_codec *codec = socdev->codec; | 1485 | struct snd_soc_codec *codec = socdev->codec; |
1493 | struct i2c_client *i2c; | ||
1494 | int ret; | 1486 | int ret; |
1495 | 1487 | ||
1496 | if (addr != setup->i2c_address) | ||
1497 | return -ENODEV; | ||
1498 | |||
1499 | client_template.adapter = adap; | ||
1500 | client_template.addr = addr; | ||
1501 | |||
1502 | i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); | ||
1503 | if (i2c == NULL) | ||
1504 | return -ENOMEM; | ||
1505 | |||
1506 | i2c_set_clientdata(i2c, codec); | 1488 | i2c_set_clientdata(i2c, codec); |
1507 | codec->control_data = i2c; | 1489 | codec->control_data = i2c; |
1508 | 1490 | ||
1509 | ret = i2c_attach_client(i2c); | ||
1510 | if (ret < 0) { | ||
1511 | pr_err("failed to attach codec at addr %x\n", addr); | ||
1512 | goto err; | ||
1513 | } | ||
1514 | |||
1515 | ret = wm8990_init(socdev); | 1491 | ret = wm8990_init(socdev); |
1516 | if (ret < 0) { | 1492 | if (ret < 0) |
1517 | pr_err("failed to initialise WM8990\n"); | 1493 | pr_err("failed to initialise WM8990\n"); |
1518 | goto err; | ||
1519 | } | ||
1520 | return ret; | ||
1521 | 1494 | ||
1522 | err: | ||
1523 | kfree(i2c); | ||
1524 | return ret; | 1495 | return ret; |
1525 | } | 1496 | } |
1526 | 1497 | ||
1527 | static int wm8990_i2c_detach(struct i2c_client *client) | 1498 | static int wm8990_i2c_remove(struct i2c_client *client) |
1528 | { | 1499 | { |
1529 | struct snd_soc_codec *codec = i2c_get_clientdata(client); | 1500 | struct snd_soc_codec *codec = i2c_get_clientdata(client); |
1530 | i2c_detach_client(client); | ||
1531 | kfree(codec->reg_cache); | 1501 | kfree(codec->reg_cache); |
1532 | kfree(client); | ||
1533 | return 0; | 1502 | return 0; |
1534 | } | 1503 | } |
1535 | 1504 | ||
1536 | static int wm8990_i2c_attach(struct i2c_adapter *adap) | 1505 | static const struct i2c_device_id wm8990_i2c_id[] = { |
1537 | { | 1506 | { "wm8990", 0 }, |
1538 | return i2c_probe(adap, &addr_data, wm8990_codec_probe); | 1507 | { } |
1539 | } | 1508 | }; |
1509 | MODULE_DEVICE_TABLE(i2c, wm8990_i2c_id); | ||
1540 | 1510 | ||
1541 | static struct i2c_driver wm8990_i2c_driver = { | 1511 | static struct i2c_driver wm8990_i2c_driver = { |
1542 | .driver = { | 1512 | .driver = { |
1543 | .name = "WM8990 I2C Codec", | 1513 | .name = "WM8990 I2C Codec", |
1544 | .owner = THIS_MODULE, | 1514 | .owner = THIS_MODULE, |
1545 | }, | 1515 | }, |
1546 | .attach_adapter = wm8990_i2c_attach, | 1516 | .probe = wm8990_i2c_probe, |
1547 | .detach_client = wm8990_i2c_detach, | 1517 | .remove = wm8990_i2c_remove, |
1548 | .command = NULL, | 1518 | .id_table = wm8990_i2c_id, |
1549 | }; | 1519 | }; |
1550 | 1520 | ||
1551 | static struct i2c_client client_template = { | 1521 | static int wm8990_add_i2c_device(struct platform_device *pdev, |
1552 | .name = "WM8990", | 1522 | const struct wm8990_setup_data *setup) |
1553 | .driver = &wm8990_i2c_driver, | 1523 | { |
1554 | }; | 1524 | struct i2c_board_info info; |
1525 | struct i2c_adapter *adapter; | ||
1526 | struct i2c_client *client; | ||
1527 | int ret; | ||
1528 | |||
1529 | ret = i2c_add_driver(&wm8990_i2c_driver); | ||
1530 | if (ret != 0) { | ||
1531 | dev_err(&pdev->dev, "can't add i2c driver\n"); | ||
1532 | return ret; | ||
1533 | } | ||
1534 | |||
1535 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
1536 | info.addr = setup->i2c_address; | ||
1537 | strlcpy(info.type, "wm8990", I2C_NAME_SIZE); | ||
1538 | |||
1539 | adapter = i2c_get_adapter(setup->i2c_bus); | ||
1540 | if (!adapter) { | ||
1541 | dev_err(&pdev->dev, "can't get i2c adapter %d\n", | ||
1542 | setup->i2c_bus); | ||
1543 | goto err_driver; | ||
1544 | } | ||
1545 | |||
1546 | client = i2c_new_device(adapter, &info); | ||
1547 | i2c_put_adapter(adapter); | ||
1548 | if (!client) { | ||
1549 | dev_err(&pdev->dev, "can't add i2c device at 0x%x\n", | ||
1550 | (unsigned int)info.addr); | ||
1551 | goto err_driver; | ||
1552 | } | ||
1553 | |||
1554 | return 0; | ||
1555 | |||
1556 | err_driver: | ||
1557 | i2c_del_driver(&wm8990_i2c_driver); | ||
1558 | return -ENODEV; | ||
1559 | } | ||
1555 | #endif | 1560 | #endif |
1556 | 1561 | ||
1557 | static int wm8990_probe(struct platform_device *pdev) | 1562 | static int wm8990_probe(struct platform_device *pdev) |
@@ -1584,11 +1589,8 @@ static int wm8990_probe(struct platform_device *pdev) | |||
1584 | 1589 | ||
1585 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 1590 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
1586 | if (setup->i2c_address) { | 1591 | if (setup->i2c_address) { |
1587 | normal_i2c[0] = setup->i2c_address; | ||
1588 | codec->hw_write = (hw_write_t)i2c_master_send; | 1592 | codec->hw_write = (hw_write_t)i2c_master_send; |
1589 | ret = i2c_add_driver(&wm8990_i2c_driver); | 1593 | ret = wm8990_add_i2c_device(pdev, setup); |
1590 | if (ret != 0) | ||
1591 | printk(KERN_ERR "can't add i2c driver"); | ||
1592 | } | 1594 | } |
1593 | #else | 1595 | #else |
1594 | /* Add other interfaces here */ | 1596 | /* Add other interfaces here */ |
@@ -1612,6 +1614,7 @@ static int wm8990_remove(struct platform_device *pdev) | |||
1612 | snd_soc_free_pcms(socdev); | 1614 | snd_soc_free_pcms(socdev); |
1613 | snd_soc_dapm_free(socdev); | 1615 | snd_soc_dapm_free(socdev); |
1614 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 1616 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
1617 | i2c_unregister_device(codec->control_data); | ||
1615 | i2c_del_driver(&wm8990_i2c_driver); | 1618 | i2c_del_driver(&wm8990_i2c_driver); |
1616 | #endif | 1619 | #endif |
1617 | kfree(codec->private_data); | 1620 | kfree(codec->private_data); |
diff --git a/sound/soc/codecs/wm8990.h b/sound/soc/codecs/wm8990.h index 0a08325d5443..0e192f3b0788 100644 --- a/sound/soc/codecs/wm8990.h +++ b/sound/soc/codecs/wm8990.h | |||
@@ -827,6 +827,7 @@ | |||
827 | #define WM8990_AINRMUX_PWR_BIT 3 | 827 | #define WM8990_AINRMUX_PWR_BIT 3 |
828 | 828 | ||
829 | struct wm8990_setup_data { | 829 | struct wm8990_setup_data { |
830 | unsigned i2c_bus; | ||
830 | unsigned short i2c_address; | 831 | unsigned short i2c_address; |
831 | }; | 832 | }; |
832 | 833 | ||