aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8900.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2008-12-09 07:51:56 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2008-12-09 08:30:05 -0500
commitf0752331b89ce79063f765545dd7dd5f49d9a713 (patch)
treeb8af22b735ec99bf65ae47a636ced7e6e59db7f6 /sound/soc/codecs/wm8900.c
parent6b05eda6383d89bffc21da654d148733e7839540 (diff)
ASoC: Convert WM8900 to allow registration by machine code
This makes use of the support for delayed DAI registration to allow the WM8900 I2C device to be registered by general platform/architecture code rather than as part of the ASoC device probe. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/wm8900.c')
-rw-r--r--sound/soc/codecs/wm8900.c97
1 files changed, 20 insertions, 77 deletions
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index 02bb1c999ba1..34e58af0c65a 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -1382,32 +1382,21 @@ priv_err:
1382 return ret; 1382 return ret;
1383} 1383}
1384 1384
1385static struct snd_soc_device *wm8900_socdev; 1385static struct i2c_client *wm8900_client;
1386 1386
1387#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1388
1389/* If the i2c layer weren't so broken, we could pass this kind of data
1390 around */
1391static int wm8900_i2c_probe(struct i2c_client *i2c, 1387static int wm8900_i2c_probe(struct i2c_client *i2c,
1392 const struct i2c_device_id *id) 1388 const struct i2c_device_id *id)
1393{ 1389{
1394 struct snd_soc_device *socdev = wm8900_socdev; 1390 wm8900_client = i2c;
1395 struct snd_soc_codec *codec = socdev->codec; 1391 wm8900_dai.dev = &i2c->dev;
1396 int ret; 1392 return snd_soc_register_dai(&wm8900_dai);
1397
1398 i2c_set_clientdata(i2c, codec);
1399 codec->control_data = i2c;
1400
1401 ret = wm8900_init(socdev);
1402 if (ret < 0)
1403 dev_err(&i2c->dev, "failed to initialise WM8900\n");
1404 return ret;
1405} 1393}
1406 1394
1407static int wm8900_i2c_remove(struct i2c_client *client) 1395static int wm8900_i2c_remove(struct i2c_client *client)
1408{ 1396{
1409 struct snd_soc_codec *codec = i2c_get_clientdata(client); 1397 snd_soc_unregister_dai(&wm8900_dai);
1410 kfree(codec->reg_cache); 1398 wm8900_dai.dev = NULL;
1399 wm8900_client = NULL;
1411 return 0; 1400 return 0;
1412} 1401}
1413 1402
@@ -1427,57 +1416,17 @@ static struct i2c_driver wm8900_i2c_driver = {
1427 .id_table = wm8900_i2c_id, 1416 .id_table = wm8900_i2c_id,
1428}; 1417};
1429 1418
1430static int wm8900_add_i2c_device(struct platform_device *pdev,
1431 const struct wm8900_setup_data *setup)
1432{
1433 struct i2c_board_info info;
1434 struct i2c_adapter *adapter;
1435 struct i2c_client *client;
1436 int ret;
1437
1438 ret = i2c_add_driver(&wm8900_i2c_driver);
1439 if (ret != 0) {
1440 dev_err(&pdev->dev, "can't add i2c driver\n");
1441 return ret;
1442 }
1443
1444 memset(&info, 0, sizeof(struct i2c_board_info));
1445 info.addr = setup->i2c_address;
1446 strlcpy(info.type, "wm8900", I2C_NAME_SIZE);
1447
1448 adapter = i2c_get_adapter(setup->i2c_bus);
1449 if (!adapter) {
1450 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
1451 setup->i2c_bus);
1452 goto err_driver;
1453 }
1454
1455 client = i2c_new_device(adapter, &info);
1456 i2c_put_adapter(adapter);
1457 if (!client) {
1458 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
1459 (unsigned int)info.addr);
1460 goto err_driver;
1461 }
1462
1463 return 0;
1464
1465err_driver:
1466 i2c_del_driver(&wm8900_i2c_driver);
1467 return -ENODEV;
1468}
1469#endif
1470
1471static int wm8900_probe(struct platform_device *pdev) 1419static int wm8900_probe(struct platform_device *pdev)
1472{ 1420{
1473 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1421 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1474 struct wm8900_setup_data *setup;
1475 struct snd_soc_codec *codec; 1422 struct snd_soc_codec *codec;
1476 int ret = 0; 1423 int ret = 0;
1477 1424
1478 dev_info(&pdev->dev, "WM8900 Audio Codec\n"); 1425 if (!wm8900_client) {
1426 dev_err(&pdev->dev, "I2C client not yet instantiated\n");
1427 return -ENODEV;
1428 }
1479 1429
1480 setup = socdev->codec_data;
1481 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 1430 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
1482 if (codec == NULL) 1431 if (codec == NULL)
1483 return -ENOMEM; 1432 return -ENOMEM;
@@ -1490,15 +1439,13 @@ static int wm8900_probe(struct platform_device *pdev)
1490 1439
1491 codec->set_bias_level = wm8900_set_bias_level; 1440 codec->set_bias_level = wm8900_set_bias_level;
1492 1441
1493 wm8900_socdev = socdev; 1442 codec->hw_write = (hw_write_t)i2c_master_send;
1494#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1443 codec->control_data = wm8900_client;
1495 if (setup->i2c_address) { 1444
1496 codec->hw_write = (hw_write_t)i2c_master_send; 1445 ret = wm8900_init(socdev);
1497 ret = wm8900_add_i2c_device(pdev, setup); 1446 if (ret != 0)
1498 } 1447 kfree(codec);
1499#else 1448
1500#error Non-I2C interfaces not yet supported
1501#endif
1502 return ret; 1449 return ret;
1503} 1450}
1504 1451
@@ -1513,10 +1460,6 @@ static int wm8900_remove(struct platform_device *pdev)
1513 1460
1514 snd_soc_free_pcms(socdev); 1461 snd_soc_free_pcms(socdev);
1515 snd_soc_dapm_free(socdev); 1462 snd_soc_dapm_free(socdev);
1516#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1517 i2c_unregister_device(codec->control_data);
1518 i2c_del_driver(&wm8900_i2c_driver);
1519#endif
1520 kfree(codec); 1463 kfree(codec);
1521 1464
1522 return 0; 1465 return 0;
@@ -1532,13 +1475,13 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_wm8900);
1532 1475
1533static int __devinit wm8900_modinit(void) 1476static int __devinit wm8900_modinit(void)
1534{ 1477{
1535 return snd_soc_register_dai(&wm8900_dai); 1478 return i2c_add_driver(&wm8900_i2c_driver);
1536} 1479}
1537module_init(wm8900_modinit); 1480module_init(wm8900_modinit);
1538 1481
1539static void __exit wm8900_exit(void) 1482static void __exit wm8900_exit(void)
1540{ 1483{
1541 snd_soc_unregister_dai(&wm8900_dai); 1484 i2c_del_driver(&wm8900_i2c_driver);
1542} 1485}
1543module_exit(wm8900_exit); 1486module_exit(wm8900_exit);
1544 1487