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