aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8753.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8753.c')
-rw-r--r--sound/soc/codecs/wm8753.c404
1 files changed, 141 insertions, 263 deletions
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index b59f349c5218..8f679a13f2bc 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -57,7 +57,7 @@ module_param(caps_charge, int, 0);
57MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)"); 57MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)");
58 58
59static void wm8753_set_dai_mode(struct snd_soc_codec *codec, 59static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
60 unsigned int mode); 60 struct snd_soc_dai *dai, unsigned int hifi);
61 61
62/* 62/*
63 * wm8753 register cache 63 * wm8753 register cache
@@ -85,10 +85,11 @@ static const u16 wm8753_reg[] = {
85 85
86/* codec private data */ 86/* codec private data */
87struct wm8753_priv { 87struct wm8753_priv {
88 enum snd_soc_control_type control_type;
88 unsigned int sysclk; 89 unsigned int sysclk;
89 unsigned int pcmclk; 90 unsigned int pcmclk;
90 struct snd_soc_codec codec;
91 u16 reg_cache[ARRAY_SIZE(wm8753_reg)]; 91 u16 reg_cache[ARRAY_SIZE(wm8753_reg)];
92 int dai_func;
92}; 93};
93 94
94/* 95/*
@@ -228,6 +229,7 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
228{ 229{
229 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 230 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
230 int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL); 231 int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL);
232 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
231 233
232 if (((mode & 0xc) >> 2) == ucontrol->value.integer.value[0]) 234 if (((mode & 0xc) >> 2) == ucontrol->value.integer.value[0])
233 return 0; 235 return 0;
@@ -235,8 +237,7 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
235 mode &= 0xfff3; 237 mode &= 0xfff3;
236 mode |= (ucontrol->value.integer.value[0] << 2); 238 mode |= (ucontrol->value.integer.value[0] << 2);
237 239
238 wm8753_write(codec, WM8753_IOCTL, mode); 240 wm8753->dai_func = ucontrol->value.integer.value[0];
239 wm8753_set_dai_mode(codec, ucontrol->value.integer.value[0]);
240 return 1; 241 return 1;
241} 242}
242 243
@@ -904,6 +905,13 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai,
904 return 0; 905 return 0;
905} 906}
906 907
908static int wm8753_pcm_startup(struct snd_pcm_substream *substream,
909 struct snd_soc_dai *dai)
910{
911 wm8753_set_dai_mode(dai->codec, dai, 0);
912 return 0;
913}
914
907/* 915/*
908 * Set PCM DAI bit size and sample rate. 916 * Set PCM DAI bit size and sample rate.
909 */ 917 */
@@ -912,8 +920,7 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
912 struct snd_soc_dai *dai) 920 struct snd_soc_dai *dai)
913{ 921{
914 struct snd_soc_pcm_runtime *rtd = substream->private_data; 922 struct snd_soc_pcm_runtime *rtd = substream->private_data;
915 struct snd_soc_device *socdev = rtd->socdev; 923 struct snd_soc_codec *codec = rtd->codec;
916 struct snd_soc_codec *codec = socdev->card->codec;
917 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); 924 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
918 u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3; 925 u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3;
919 u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f; 926 u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f;
@@ -1138,6 +1145,13 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
1138 return 0; 1145 return 0;
1139} 1146}
1140 1147
1148static int wm8753_i2s_startup(struct snd_pcm_substream *substream,
1149 struct snd_soc_dai *dai)
1150{
1151 wm8753_set_dai_mode(dai->codec, dai, 1);
1152 return 0;
1153}
1154
1141/* 1155/*
1142 * Set PCM DAI bit size and sample rate. 1156 * Set PCM DAI bit size and sample rate.
1143 */ 1157 */
@@ -1146,8 +1160,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
1146 struct snd_soc_dai *dai) 1160 struct snd_soc_dai *dai)
1147{ 1161{
1148 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1162 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1149 struct snd_soc_device *socdev = rtd->socdev; 1163 struct snd_soc_codec *codec = rtd->codec;
1150 struct snd_soc_codec *codec = socdev->card->codec;
1151 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); 1164 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1152 u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0; 1165 u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0;
1153 u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3; 1166 u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3;
@@ -1240,12 +1253,12 @@ static int wm8753_mute(struct snd_soc_dai *dai, int mute)
1240{ 1253{
1241 struct snd_soc_codec *codec = dai->codec; 1254 struct snd_soc_codec *codec = dai->codec;
1242 u16 mute_reg = wm8753_read_reg_cache(codec, WM8753_DAC) & 0xfff7; 1255 u16 mute_reg = wm8753_read_reg_cache(codec, WM8753_DAC) & 0xfff7;
1256 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1243 1257
1244 /* the digital mute covers the HiFi and Voice DAC's on the WM8753. 1258 /* the digital mute covers the HiFi and Voice DAC's on the WM8753.
1245 * make sure we check if they are not both active when we mute */ 1259 * make sure we check if they are not both active when we mute */
1246 if (mute && dai->id == 1) { 1260 if (mute && wm8753->dai_func == 1) {
1247 if (!wm8753_dai[WM8753_DAI_VOICE].playback.active || 1261 if (!codec->active)
1248 !wm8753_dai[WM8753_DAI_HIFI].playback.active)
1249 wm8753_write(codec, WM8753_DAC, mute_reg | 0x8); 1262 wm8753_write(codec, WM8753_DAC, mute_reg | 0x8);
1250 } else { 1263 } else {
1251 if (mute) 1264 if (mute)
@@ -1303,6 +1316,7 @@ static int wm8753_set_bias_level(struct snd_soc_codec *codec,
1303 * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture 1316 * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture
1304 */ 1317 */
1305static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode1 = { 1318static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode1 = {
1319 .startup = wm8753_i2s_startup,
1306 .hw_params = wm8753_i2s_hw_params, 1320 .hw_params = wm8753_i2s_hw_params,
1307 .digital_mute = wm8753_mute, 1321 .digital_mute = wm8753_mute,
1308 .set_fmt = wm8753_mode1h_set_dai_fmt, 1322 .set_fmt = wm8753_mode1h_set_dai_fmt,
@@ -1312,6 +1326,7 @@ static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode1 = {
1312}; 1326};
1313 1327
1314static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode1 = { 1328static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode1 = {
1329 .startup = wm8753_pcm_startup,
1315 .hw_params = wm8753_pcm_hw_params, 1330 .hw_params = wm8753_pcm_hw_params,
1316 .digital_mute = wm8753_mute, 1331 .digital_mute = wm8753_mute,
1317 .set_fmt = wm8753_mode1v_set_dai_fmt, 1332 .set_fmt = wm8753_mode1v_set_dai_fmt,
@@ -1321,6 +1336,7 @@ static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode1 = {
1321}; 1336};
1322 1337
1323static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode2 = { 1338static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode2 = {
1339 .startup = wm8753_pcm_startup,
1324 .hw_params = wm8753_pcm_hw_params, 1340 .hw_params = wm8753_pcm_hw_params,
1325 .digital_mute = wm8753_mute, 1341 .digital_mute = wm8753_mute,
1326 .set_fmt = wm8753_mode2_set_dai_fmt, 1342 .set_fmt = wm8753_mode2_set_dai_fmt,
@@ -1330,6 +1346,7 @@ static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode2 = {
1330}; 1346};
1331 1347
1332static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode3 = { 1348static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode3 = {
1349 .startup = wm8753_i2s_startup,
1333 .hw_params = wm8753_i2s_hw_params, 1350 .hw_params = wm8753_i2s_hw_params,
1334 .digital_mute = wm8753_mute, 1351 .digital_mute = wm8753_mute,
1335 .set_fmt = wm8753_mode3_4_set_dai_fmt, 1352 .set_fmt = wm8753_mode3_4_set_dai_fmt,
@@ -1339,6 +1356,7 @@ static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode3 = {
1339}; 1356};
1340 1357
1341static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode4 = { 1358static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode4 = {
1359 .startup = wm8753_i2s_startup,
1342 .hw_params = wm8753_i2s_hw_params, 1360 .hw_params = wm8753_i2s_hw_params,
1343 .digital_mute = wm8753_mute, 1361 .digital_mute = wm8753_mute,
1344 .set_fmt = wm8753_mode3_4_set_dai_fmt, 1362 .set_fmt = wm8753_mode3_4_set_dai_fmt,
@@ -1347,10 +1365,9 @@ static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode4 = {
1347 .set_sysclk = wm8753_set_dai_sysclk, 1365 .set_sysclk = wm8753_set_dai_sysclk,
1348}; 1366};
1349 1367
1350static const struct snd_soc_dai wm8753_all_dai[] = { 1368static struct snd_soc_dai_driver wm8753_all_dai[] = {
1351/* DAI HiFi mode 1 */ 1369/* DAI HiFi mode 1 */
1352{ .name = "WM8753 HiFi", 1370{ .name = "wm8753-hifi",
1353 .id = 1,
1354 .playback = { 1371 .playback = {
1355 .stream_name = "HiFi Playback", 1372 .stream_name = "HiFi Playback",
1356 .channels_min = 1, 1373 .channels_min = 1,
@@ -1366,8 +1383,7 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1366 .ops = &wm8753_dai_ops_hifi_mode1, 1383 .ops = &wm8753_dai_ops_hifi_mode1,
1367}, 1384},
1368/* DAI Voice mode 1 */ 1385/* DAI Voice mode 1 */
1369{ .name = "WM8753 Voice", 1386{ .name = "wm8753-voice",
1370 .id = 1,
1371 .playback = { 1387 .playback = {
1372 .stream_name = "Voice Playback", 1388 .stream_name = "Voice Playback",
1373 .channels_min = 1, 1389 .channels_min = 1,
@@ -1383,12 +1399,10 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1383 .ops = &wm8753_dai_ops_voice_mode1, 1399 .ops = &wm8753_dai_ops_voice_mode1,
1384}, 1400},
1385/* DAI HiFi mode 2 - dummy */ 1401/* DAI HiFi mode 2 - dummy */
1386{ .name = "WM8753 HiFi", 1402{ .name = "wm8753-hifi",
1387 .id = 2,
1388}, 1403},
1389/* DAI Voice mode 2 */ 1404/* DAI Voice mode 2 */
1390{ .name = "WM8753 Voice", 1405{ .name = "wm8753-voice",
1391 .id = 2,
1392 .playback = { 1406 .playback = {
1393 .stream_name = "Voice Playback", 1407 .stream_name = "Voice Playback",
1394 .channels_min = 1, 1408 .channels_min = 1,
@@ -1404,8 +1418,7 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1404 .ops = &wm8753_dai_ops_voice_mode2, 1418 .ops = &wm8753_dai_ops_voice_mode2,
1405}, 1419},
1406/* DAI HiFi mode 3 */ 1420/* DAI HiFi mode 3 */
1407{ .name = "WM8753 HiFi", 1421{ .name = "wm8753-hifi",
1408 .id = 3,
1409 .playback = { 1422 .playback = {
1410 .stream_name = "HiFi Playback", 1423 .stream_name = "HiFi Playback",
1411 .channels_min = 1, 1424 .channels_min = 1,
@@ -1421,12 +1434,10 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1421 .ops = &wm8753_dai_ops_hifi_mode3, 1434 .ops = &wm8753_dai_ops_hifi_mode3,
1422}, 1435},
1423/* DAI Voice mode 3 - dummy */ 1436/* DAI Voice mode 3 - dummy */
1424{ .name = "WM8753 Voice", 1437{ .name = "wm8753-voice",
1425 .id = 3,
1426}, 1438},
1427/* DAI HiFi mode 4 */ 1439/* DAI HiFi mode 4 */
1428{ .name = "WM8753 HiFi", 1440{ .name = "wm8753-hifi",
1429 .id = 4,
1430 .playback = { 1441 .playback = {
1431 .stream_name = "HiFi Playback", 1442 .stream_name = "HiFi Playback",
1432 .channels_min = 1, 1443 .channels_min = 1,
@@ -1442,58 +1453,31 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1442 .ops = &wm8753_dai_ops_hifi_mode4, 1453 .ops = &wm8753_dai_ops_hifi_mode4,
1443}, 1454},
1444/* DAI Voice mode 4 - dummy */ 1455/* DAI Voice mode 4 - dummy */
1445{ .name = "WM8753 Voice", 1456{ .name = "wm8753-voice",
1446 .id = 4,
1447}, 1457},
1448}; 1458};
1449 1459
1450struct snd_soc_dai wm8753_dai[] = { 1460static struct snd_soc_dai_driver wm8753_dai[] = {
1451 { 1461 {
1452 .name = "WM8753 DAI 0", 1462 .name = "wm8753-aif0",
1453 }, 1463 },
1454 { 1464 {
1455 .name = "WM8753 DAI 1", 1465 .name = "wm8753-aif1",
1456 }, 1466 },
1457}; 1467};
1458EXPORT_SYMBOL_GPL(wm8753_dai);
1459 1468
1460static void wm8753_set_dai_mode(struct snd_soc_codec *codec, unsigned int mode) 1469static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
1470 struct snd_soc_dai *dai, unsigned int hifi)
1461{ 1471{
1462 if (mode < 4) { 1472 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1463 int playback_active, capture_active, codec_active, pop_wait; 1473
1464 void *private_data; 1474 if (wm8753->dai_func < 4) {
1465 struct list_head list; 1475 if (hifi)
1466 1476 dai->driver = &wm8753_all_dai[wm8753->dai_func << 1];
1467 playback_active = wm8753_dai[0].playback.active; 1477 else
1468 capture_active = wm8753_dai[0].capture.active; 1478 dai->driver = &wm8753_all_dai[(wm8753->dai_func << 1) + 1];
1469 codec_active = wm8753_dai[0].active;
1470 private_data = wm8753_dai[0].private_data;
1471 pop_wait = wm8753_dai[0].pop_wait;
1472 list = wm8753_dai[0].list;
1473 wm8753_dai[0] = wm8753_all_dai[mode << 1];
1474 wm8753_dai[0].playback.active = playback_active;
1475 wm8753_dai[0].capture.active = capture_active;
1476 wm8753_dai[0].active = codec_active;
1477 wm8753_dai[0].private_data = private_data;
1478 wm8753_dai[0].pop_wait = pop_wait;
1479 wm8753_dai[0].list = list;
1480
1481 playback_active = wm8753_dai[1].playback.active;
1482 capture_active = wm8753_dai[1].capture.active;
1483 codec_active = wm8753_dai[1].active;
1484 private_data = wm8753_dai[1].private_data;
1485 pop_wait = wm8753_dai[1].pop_wait;
1486 list = wm8753_dai[1].list;
1487 wm8753_dai[1] = wm8753_all_dai[(mode << 1) + 1];
1488 wm8753_dai[1].playback.active = playback_active;
1489 wm8753_dai[1].capture.active = capture_active;
1490 wm8753_dai[1].active = codec_active;
1491 wm8753_dai[1].private_data = private_data;
1492 wm8753_dai[1].pop_wait = pop_wait;
1493 wm8753_dai[1].list = list;
1494 } 1479 }
1495 wm8753_dai[0].codec = codec; 1480 wm8753_write(codec, WM8753_IOCTL, wm8753->dai_func);
1496 wm8753_dai[1].codec = codec;
1497} 1481}
1498 1482
1499static void wm8753_work(struct work_struct *work) 1483static void wm8753_work(struct work_struct *work)
@@ -1503,19 +1487,14 @@ static void wm8753_work(struct work_struct *work)
1503 wm8753_set_bias_level(codec, codec->bias_level); 1487 wm8753_set_bias_level(codec, codec->bias_level);
1504} 1488}
1505 1489
1506static int wm8753_suspend(struct platform_device *pdev, pm_message_t state) 1490static int wm8753_suspend(struct snd_soc_codec *codec, pm_message_t state)
1507{ 1491{
1508 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1509 struct snd_soc_codec *codec = socdev->card->codec;
1510
1511 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); 1492 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
1512 return 0; 1493 return 0;
1513} 1494}
1514 1495
1515static int wm8753_resume(struct platform_device *pdev) 1496static int wm8753_resume(struct snd_soc_codec *codec)
1516{ 1497{
1517 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1518 struct snd_soc_codec *codec = socdev->card->codec;
1519 int i; 1498 int i;
1520 u8 data[2]; 1499 u8 data[2];
1521 u16 *cache = codec->reg_cache; 1500 u16 *cache = codec->reg_cache;
@@ -1547,41 +1526,6 @@ static int wm8753_resume(struct platform_device *pdev)
1547 return 0; 1526 return 0;
1548} 1527}
1549 1528
1550static struct snd_soc_codec *wm8753_codec;
1551
1552static int wm8753_probe(struct platform_device *pdev)
1553{
1554 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1555 struct snd_soc_codec *codec;
1556 int ret = 0;
1557
1558 if (!wm8753_codec) {
1559 dev_err(&pdev->dev, "WM8753 codec not yet registered\n");
1560 return -EINVAL;
1561 }
1562
1563 socdev->card->codec = wm8753_codec;
1564 codec = wm8753_codec;
1565
1566 wm8753_set_dai_mode(codec, 0);
1567
1568 /* register pcms */
1569 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1570 if (ret < 0) {
1571 printk(KERN_ERR "wm8753: failed to create pcms\n");
1572 goto pcm_err;
1573 }
1574
1575 snd_soc_add_controls(codec, wm8753_snd_controls,
1576 ARRAY_SIZE(wm8753_snd_controls));
1577 wm8753_add_widgets(codec);
1578
1579 return 0;
1580
1581pcm_err:
1582 return ret;
1583}
1584
1585/* 1529/*
1586 * This function forces any delayed work to be queued and run. 1530 * This function forces any delayed work to be queued and run.
1587 */ 1531 */
@@ -1601,62 +1545,28 @@ static int run_delayed_work(struct delayed_work *dwork)
1601 return ret; 1545 return ret;
1602} 1546}
1603 1547
1604/* power down chip */ 1548static int wm8753_probe(struct snd_soc_codec *codec)
1605static int wm8753_remove(struct platform_device *pdev)
1606{ 1549{
1607 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1550 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1608 1551 int ret = 0, reg;
1609 snd_soc_free_pcms(socdev);
1610 snd_soc_dapm_free(socdev);
1611
1612 return 0;
1613}
1614
1615struct snd_soc_codec_device soc_codec_dev_wm8753 = {
1616 .probe = wm8753_probe,
1617 .remove = wm8753_remove,
1618 .suspend = wm8753_suspend,
1619 .resume = wm8753_resume,
1620};
1621EXPORT_SYMBOL_GPL(soc_codec_dev_wm8753);
1622 1552
1623static int wm8753_register(struct wm8753_priv *wm8753) 1553 INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work);
1624{
1625 int ret, i;
1626 struct snd_soc_codec *codec = &wm8753->codec;
1627 u16 reg;
1628 1554
1629 if (wm8753_codec) { 1555 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8753->control_type);
1630 dev_err(codec->dev, "Multiple WM8753 devices not supported\n"); 1556 if (ret < 0) {
1631 ret = -EINVAL; 1557 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1632 goto err; 1558 return ret;
1633 } 1559 }
1634 1560
1635 mutex_init(&codec->mutex);
1636 INIT_LIST_HEAD(&codec->dapm_widgets);
1637 INIT_LIST_HEAD(&codec->dapm_paths);
1638
1639 codec->name = "WM8753";
1640 codec->owner = THIS_MODULE;
1641 codec->read = wm8753_read_reg_cache;
1642 codec->write = wm8753_write;
1643 codec->bias_level = SND_SOC_BIAS_STANDBY;
1644 codec->set_bias_level = wm8753_set_bias_level;
1645 codec->dai = wm8753_dai;
1646 codec->num_dai = 2;
1647 codec->reg_cache_size = ARRAY_SIZE(wm8753->reg_cache) + 1;
1648 codec->reg_cache = &wm8753->reg_cache;
1649 snd_soc_codec_set_drvdata(codec, wm8753);
1650
1651 memcpy(codec->reg_cache, wm8753_reg, sizeof(wm8753->reg_cache));
1652 INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work);
1653
1654 ret = wm8753_reset(codec); 1561 ret = wm8753_reset(codec);
1655 if (ret < 0) { 1562 if (ret < 0) {
1656 dev_err(codec->dev, "Failed to issue reset\n"); 1563 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
1657 goto err; 1564 return ret;
1658 } 1565 }
1659 1566
1567 wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1568 wm8753->dai_func = 0;
1569
1660 /* charge output caps */ 1570 /* charge output caps */
1661 wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE); 1571 wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
1662 schedule_delayed_work(&codec->delayed_work, 1572 schedule_delayed_work(&codec->delayed_work,
@@ -1684,165 +1594,133 @@ static int wm8753_register(struct wm8753_priv *wm8753)
1684 reg = wm8753_read_reg_cache(codec, WM8753_RINVOL); 1594 reg = wm8753_read_reg_cache(codec, WM8753_RINVOL);
1685 wm8753_write(codec, WM8753_RINVOL, reg | 0x0100); 1595 wm8753_write(codec, WM8753_RINVOL, reg | 0x0100);
1686 1596
1687 wm8753_codec = codec; 1597 snd_soc_add_controls(codec, wm8753_snd_controls,
1688 1598 ARRAY_SIZE(wm8753_snd_controls));
1689 for (i = 0; i < ARRAY_SIZE(wm8753_dai); i++) 1599 wm8753_add_widgets(codec);
1690 wm8753_dai[i].dev = codec->dev;
1691
1692 ret = snd_soc_register_codec(codec);
1693 if (ret != 0) {
1694 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1695 goto err;
1696 }
1697
1698 ret = snd_soc_register_dais(&wm8753_dai[0], ARRAY_SIZE(wm8753_dai));
1699 if (ret != 0) {
1700 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
1701 goto err_codec;
1702 }
1703 1600
1704 return 0; 1601 return 0;
1705
1706err_codec:
1707 run_delayed_work(&codec->delayed_work);
1708 snd_soc_unregister_codec(codec);
1709err:
1710 kfree(wm8753);
1711 return ret;
1712} 1602}
1713 1603
1714static void wm8753_unregister(struct wm8753_priv *wm8753) 1604/* power down chip */
1605static int wm8753_remove(struct snd_soc_codec *codec)
1715{ 1606{
1716 wm8753_set_bias_level(&wm8753->codec, SND_SOC_BIAS_OFF); 1607 run_delayed_work(&codec->delayed_work);
1717 run_delayed_work(&wm8753->codec.delayed_work); 1608 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
1718 snd_soc_unregister_dais(&wm8753_dai[0], ARRAY_SIZE(wm8753_dai)); 1609
1719 snd_soc_unregister_codec(&wm8753->codec); 1610 return 0;
1720 kfree(wm8753);
1721 wm8753_codec = NULL;
1722} 1611}
1723 1612
1724#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1613static struct snd_soc_codec_driver soc_codec_dev_wm8753 = {
1614 .probe = wm8753_probe,
1615 .remove = wm8753_remove,
1616 .suspend = wm8753_suspend,
1617 .resume = wm8753_resume,
1618 .set_bias_level = wm8753_set_bias_level,
1619 .reg_cache_size = ARRAY_SIZE(wm8753_reg),
1620 .reg_word_size = sizeof(u16),
1621 .reg_cache_default = wm8753_reg,
1622};
1725 1623
1726static int wm8753_i2c_probe(struct i2c_client *i2c, 1624#if defined(CONFIG_SPI_MASTER)
1727 const struct i2c_device_id *id) 1625static int __devinit wm8753_spi_probe(struct spi_device *spi)
1728{ 1626{
1729 struct snd_soc_codec *codec;
1730 struct wm8753_priv *wm8753; 1627 struct wm8753_priv *wm8753;
1628 int ret;
1731 1629
1732 wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL); 1630 wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL);
1733 if (wm8753 == NULL) 1631 if (wm8753 == NULL)
1734 return -ENOMEM; 1632 return -ENOMEM;
1735 1633
1736 codec = &wm8753->codec; 1634 wm8753->control_type = SND_SOC_SPI;
1737 codec->hw_write = (hw_write_t)i2c_master_send; 1635 spi_set_drvdata(spi, wm8753);
1738 codec->control_data = i2c;
1739 i2c_set_clientdata(i2c, wm8753);
1740
1741 codec->dev = &i2c->dev;
1742 1636
1743 return wm8753_register(wm8753); 1637 ret = snd_soc_register_codec(&spi->dev,
1638 &soc_codec_dev_wm8753, wm8753_dai, ARRAY_SIZE(wm8753_dai));
1639 if (ret < 0)
1640 kfree(wm8753);
1641 return ret;
1744} 1642}
1745 1643
1746static int wm8753_i2c_remove(struct i2c_client *client) 1644static int __devexit wm8753_spi_remove(struct spi_device *spi)
1747{ 1645{
1748 struct wm8753_priv *wm8753 = i2c_get_clientdata(client); 1646 snd_soc_unregister_codec(&spi->dev);
1749 wm8753_unregister(wm8753); 1647 kfree(spi_get_drvdata(spi));
1750 return 0; 1648 return 0;
1751} 1649}
1752 1650
1753static const struct i2c_device_id wm8753_i2c_id[] = { 1651static struct spi_driver wm8753_spi_driver = {
1754 { "wm8753", 0 },
1755 { }
1756};
1757MODULE_DEVICE_TABLE(i2c, wm8753_i2c_id);
1758
1759static struct i2c_driver wm8753_i2c_driver = {
1760 .driver = { 1652 .driver = {
1761 .name = "wm8753", 1653 .name = "wm8753-codec",
1762 .owner = THIS_MODULE, 1654 .owner = THIS_MODULE,
1763 }, 1655 },
1764 .probe = wm8753_i2c_probe, 1656 .probe = wm8753_spi_probe,
1765 .remove = wm8753_i2c_remove, 1657 .remove = __devexit_p(wm8753_spi_remove),
1766 .id_table = wm8753_i2c_id,
1767}; 1658};
1768#endif 1659#endif /* CONFIG_SPI_MASTER */
1769
1770#if defined(CONFIG_SPI_MASTER)
1771static int wm8753_spi_write(struct spi_device *spi, const char *data, int len)
1772{
1773 struct spi_transfer t;
1774 struct spi_message m;
1775 u8 msg[2];
1776
1777 if (len <= 0)
1778 return 0;
1779 1660
1780 msg[0] = data[0]; 1661#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1781 msg[1] = data[1]; 1662static __devinit int wm8753_i2c_probe(struct i2c_client *i2c,
1782 1663 const struct i2c_device_id *id)
1783 spi_message_init(&m);
1784 memset(&t, 0, (sizeof t));
1785
1786 t.tx_buf = &msg[0];
1787 t.len = len;
1788
1789 spi_message_add_tail(&t, &m);
1790 spi_sync(spi, &m);
1791
1792 return len;
1793}
1794
1795static int __devinit wm8753_spi_probe(struct spi_device *spi)
1796{ 1664{
1797 struct snd_soc_codec *codec;
1798 struct wm8753_priv *wm8753; 1665 struct wm8753_priv *wm8753;
1666 int ret;
1799 1667
1800 wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL); 1668 wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL);
1801 if (wm8753 == NULL) 1669 if (wm8753 == NULL)
1802 return -ENOMEM; 1670 return -ENOMEM;
1803 1671
1804 codec = &wm8753->codec; 1672 i2c_set_clientdata(i2c, wm8753);
1805 codec->control_data = spi; 1673 wm8753->control_type = SND_SOC_I2C;
1806 codec->hw_write = (hw_write_t)wm8753_spi_write;
1807 codec->dev = &spi->dev;
1808 1674
1809 dev_set_drvdata(&spi->dev, wm8753); 1675 ret = snd_soc_register_codec(&i2c->dev,
1810 1676 &soc_codec_dev_wm8753, wm8753_dai, ARRAY_SIZE(wm8753_dai));
1811 return wm8753_register(wm8753); 1677 if (ret < 0)
1678 kfree(wm8753);
1679 return ret;
1812} 1680}
1813 1681
1814static int __devexit wm8753_spi_remove(struct spi_device *spi) 1682static __devexit int wm8753_i2c_remove(struct i2c_client *client)
1815{ 1683{
1816 struct wm8753_priv *wm8753 = dev_get_drvdata(&spi->dev); 1684 snd_soc_unregister_codec(&client->dev);
1817 wm8753_unregister(wm8753); 1685 kfree(i2c_get_clientdata(client));
1818 return 0; 1686 return 0;
1819} 1687}
1820 1688
1821static struct spi_driver wm8753_spi_driver = { 1689static const struct i2c_device_id wm8753_i2c_id[] = {
1690 { "wm8753", 0 },
1691 { }
1692};
1693MODULE_DEVICE_TABLE(i2c, wm8753_i2c_id);
1694
1695static struct i2c_driver wm8753_i2c_driver = {
1822 .driver = { 1696 .driver = {
1823 .name = "wm8753", 1697 .name = "wm8753-codec",
1824 .bus = &spi_bus_type, 1698 .owner = THIS_MODULE,
1825 .owner = THIS_MODULE,
1826 }, 1699 },
1827 .probe = wm8753_spi_probe, 1700 .probe = wm8753_i2c_probe,
1828 .remove = __devexit_p(wm8753_spi_remove), 1701 .remove = __devexit_p(wm8753_i2c_remove),
1702 .id_table = wm8753_i2c_id,
1829}; 1703};
1830#endif 1704#endif
1831 1705
1832static int __init wm8753_modinit(void) 1706static int __init wm8753_modinit(void)
1833{ 1707{
1834 int ret; 1708 int ret = 0;
1835#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1709#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1836 ret = i2c_add_driver(&wm8753_i2c_driver); 1710 ret = i2c_add_driver(&wm8753_i2c_driver);
1837 if (ret != 0) 1711 if (ret != 0) {
1838 pr_err("Failed to register WM8753 I2C driver: %d\n", ret); 1712 printk(KERN_ERR "Failed to register wm8753 I2C driver: %d\n",
1713 ret);
1714 }
1839#endif 1715#endif
1840#if defined(CONFIG_SPI_MASTER) 1716#if defined(CONFIG_SPI_MASTER)
1841 ret = spi_register_driver(&wm8753_spi_driver); 1717 ret = spi_register_driver(&wm8753_spi_driver);
1842 if (ret != 0) 1718 if (ret != 0) {
1843 pr_err("Failed to register WM8753 SPI driver: %d\n", ret); 1719 printk(KERN_ERR "Failed to register wm8753 SPI driver: %d\n",
1720 ret);
1721 }
1844#endif 1722#endif
1845 return 0; 1723 return ret;
1846} 1724}
1847module_init(wm8753_modinit); 1725module_init(wm8753_modinit);
1848 1726