diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2008-12-09 07:51:56 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2008-12-09 08:30:05 -0500 |
commit | f0752331b89ce79063f765545dd7dd5f49d9a713 (patch) | |
tree | b8af22b735ec99bf65ae47a636ced7e6e59db7f6 /sound/soc/codecs/wm8900.c | |
parent | 6b05eda6383d89bffc21da654d148733e7839540 (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.c | 97 |
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 | ||
1385 | static struct snd_soc_device *wm8900_socdev; | 1385 | static 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 */ | ||
1391 | static int wm8900_i2c_probe(struct i2c_client *i2c, | 1387 | static 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 | ||
1407 | static int wm8900_i2c_remove(struct i2c_client *client) | 1395 | static 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 | ||
1430 | static 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 | |||
1465 | err_driver: | ||
1466 | i2c_del_driver(&wm8900_i2c_driver); | ||
1467 | return -ENODEV; | ||
1468 | } | ||
1469 | #endif | ||
1470 | |||
1471 | static int wm8900_probe(struct platform_device *pdev) | 1419 | static 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 | ||
1533 | static int __devinit wm8900_modinit(void) | 1476 | static 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 | } |
1537 | module_init(wm8900_modinit); | 1480 | module_init(wm8900_modinit); |
1538 | 1481 | ||
1539 | static void __exit wm8900_exit(void) | 1482 | static void __exit wm8900_exit(void) |
1540 | { | 1483 | { |
1541 | snd_soc_unregister_dai(&wm8900_dai); | 1484 | i2c_del_driver(&wm8900_i2c_driver); |
1542 | } | 1485 | } |
1543 | module_exit(wm8900_exit); | 1486 | module_exit(wm8900_exit); |
1544 | 1487 | ||