aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8904.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2010-02-03 14:33:49 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-02-04 05:43:10 -0500
commit8c1264740e7c9688c5d11b96d26e4393618ef60e (patch)
tree89c0cab2621dc358dcbb89987198e1d17111bb41 /sound/soc/codecs/wm8904.c
parente4bc669610d75106a00b0f96f2410ac5898ef1ca (diff)
ASoC: Add WM8912 DAC support
The WM8912 is a DAC only device register compatible with the WM8904 CODEC with ADC portions omitted. Support it within the WM8904 driver based on the configured I2C device name. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Diffstat (limited to 'sound/soc/codecs/wm8904.c')
-rw-r--r--sound/soc/codecs/wm8904.c90
1 files changed, 72 insertions, 18 deletions
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 80dd8df0b864..593e47d0e0eb 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -33,6 +33,11 @@
33static struct snd_soc_codec *wm8904_codec; 33static struct snd_soc_codec *wm8904_codec;
34struct snd_soc_codec_device soc_codec_dev_wm8904; 34struct snd_soc_codec_device soc_codec_dev_wm8904;
35 35
36enum wm8904_type {
37 WM8904,
38 WM8912,
39};
40
36#define WM8904_NUM_DCS_CHANNELS 4 41#define WM8904_NUM_DCS_CHANNELS 4
37 42
38#define WM8904_NUM_SUPPLIES 5 43#define WM8904_NUM_SUPPLIES 5
@@ -49,6 +54,8 @@ struct wm8904_priv {
49 struct snd_soc_codec codec; 54 struct snd_soc_codec codec;
50 u16 reg_cache[WM8904_MAX_REGISTER + 1]; 55 u16 reg_cache[WM8904_MAX_REGISTER + 1];
51 56
57 enum wm8904_type devtype;
58
52 struct regulator_bulk_data supplies[WM8904_NUM_SUPPLIES]; 59 struct regulator_bulk_data supplies[WM8904_NUM_SUPPLIES];
53 60
54 struct wm8904_pdata *pdata; 61 struct wm8904_pdata *pdata;
@@ -1411,30 +1418,62 @@ static const struct snd_soc_dapm_route wm8904_intercon[] = {
1411 { "LINER PGA", NULL, "LINER Mux" }, 1418 { "LINER PGA", NULL, "LINER Mux" },
1412}; 1419};
1413 1420
1421static const struct snd_soc_dapm_route wm8912_intercon[] = {
1422 { "HPL PGA", NULL, "DACL" },
1423 { "HPR PGA", NULL, "DACR" },
1424
1425 { "LINEL PGA", NULL, "DACL" },
1426 { "LINER PGA", NULL, "DACR" },
1427};
1428
1414static int wm8904_add_widgets(struct snd_soc_codec *codec) 1429static int wm8904_add_widgets(struct snd_soc_codec *codec)
1415{ 1430{
1416 snd_soc_add_controls(codec, wm8904_adc_snd_controls, 1431 struct wm8904_priv *wm8904 = codec->private_data;
1417 ARRAY_SIZE(wm8904_adc_snd_controls));
1418 snd_soc_add_controls(codec, wm8904_dac_snd_controls,
1419 ARRAY_SIZE(wm8904_dac_snd_controls));
1420 snd_soc_add_controls(codec, wm8904_snd_controls,
1421 ARRAY_SIZE(wm8904_snd_controls));
1422 1432
1423 snd_soc_dapm_new_controls(codec, wm8904_core_dapm_widgets, 1433 snd_soc_dapm_new_controls(codec, wm8904_core_dapm_widgets,
1424 ARRAY_SIZE(wm8904_core_dapm_widgets)); 1434 ARRAY_SIZE(wm8904_core_dapm_widgets));
1425 snd_soc_dapm_new_controls(codec, wm8904_adc_dapm_widgets,
1426 ARRAY_SIZE(wm8904_adc_dapm_widgets));
1427 snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets,
1428 ARRAY_SIZE(wm8904_dac_dapm_widgets));
1429 snd_soc_dapm_new_controls(codec, wm8904_dapm_widgets,
1430 ARRAY_SIZE(wm8904_dapm_widgets));
1431
1432 snd_soc_dapm_add_routes(codec, core_intercon, 1435 snd_soc_dapm_add_routes(codec, core_intercon,
1433 ARRAY_SIZE(core_intercon)); 1436 ARRAY_SIZE(core_intercon));
1434 snd_soc_dapm_add_routes(codec, adc_intercon, ARRAY_SIZE(adc_intercon)); 1437
1435 snd_soc_dapm_add_routes(codec, dac_intercon, ARRAY_SIZE(dac_intercon)); 1438 switch (wm8904->devtype) {
1436 snd_soc_dapm_add_routes(codec, wm8904_intercon, 1439 case WM8904:
1437 ARRAY_SIZE(wm8904_intercon)); 1440 snd_soc_add_controls(codec, wm8904_adc_snd_controls,
1441 ARRAY_SIZE(wm8904_adc_snd_controls));
1442 snd_soc_add_controls(codec, wm8904_dac_snd_controls,
1443 ARRAY_SIZE(wm8904_dac_snd_controls));
1444 snd_soc_add_controls(codec, wm8904_snd_controls,
1445 ARRAY_SIZE(wm8904_snd_controls));
1446
1447 snd_soc_dapm_new_controls(codec, wm8904_adc_dapm_widgets,
1448 ARRAY_SIZE(wm8904_adc_dapm_widgets));
1449 snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets,
1450 ARRAY_SIZE(wm8904_dac_dapm_widgets));
1451 snd_soc_dapm_new_controls(codec, wm8904_dapm_widgets,
1452 ARRAY_SIZE(wm8904_dapm_widgets));
1453
1454 snd_soc_dapm_add_routes(codec, core_intercon,
1455 ARRAY_SIZE(core_intercon));
1456 snd_soc_dapm_add_routes(codec, adc_intercon,
1457 ARRAY_SIZE(adc_intercon));
1458 snd_soc_dapm_add_routes(codec, dac_intercon,
1459 ARRAY_SIZE(dac_intercon));
1460 snd_soc_dapm_add_routes(codec, wm8904_intercon,
1461 ARRAY_SIZE(wm8904_intercon));
1462 break;
1463
1464 case WM8912:
1465 snd_soc_add_controls(codec, wm8904_dac_snd_controls,
1466 ARRAY_SIZE(wm8904_dac_snd_controls));
1467
1468 snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets,
1469 ARRAY_SIZE(wm8904_dac_dapm_widgets));
1470
1471 snd_soc_dapm_add_routes(codec, dac_intercon,
1472 ARRAY_SIZE(dac_intercon));
1473 snd_soc_dapm_add_routes(codec, wm8912_intercon,
1474 ARRAY_SIZE(wm8912_intercon));
1475 break;
1476 }
1438 1477
1439 snd_soc_dapm_new_widgets(codec); 1478 snd_soc_dapm_new_widgets(codec);
1440 return 0; 1479 return 0;
@@ -2412,6 +2451,18 @@ static int wm8904_register(struct wm8904_priv *wm8904,
2412 codec->cache_sync = 1; 2451 codec->cache_sync = 1;
2413 codec->idle_bias_off = 1; 2452 codec->idle_bias_off = 1;
2414 2453
2454 switch (wm8904->devtype) {
2455 case WM8904:
2456 break;
2457 case WM8912:
2458 memset(&wm8904_dai.capture, 0, sizeof(wm8904_dai.capture));
2459 break;
2460 default:
2461 dev_err(codec->dev, "Unknown device type %d\n",
2462 wm8904->devtype);
2463 return -EINVAL;
2464 }
2465
2415 memcpy(codec->reg_cache, wm8904_reg, sizeof(wm8904_reg)); 2466 memcpy(codec->reg_cache, wm8904_reg, sizeof(wm8904_reg));
2416 2467
2417 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control); 2468 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
@@ -2542,6 +2593,8 @@ static __devinit int wm8904_i2c_probe(struct i2c_client *i2c,
2542 codec = &wm8904->codec; 2593 codec = &wm8904->codec;
2543 codec->hw_write = (hw_write_t)i2c_master_send; 2594 codec->hw_write = (hw_write_t)i2c_master_send;
2544 2595
2596 wm8904->devtype = id->driver_data;
2597
2545 i2c_set_clientdata(i2c, wm8904); 2598 i2c_set_clientdata(i2c, wm8904);
2546 codec->control_data = i2c; 2599 codec->control_data = i2c;
2547 wm8904->pdata = i2c->dev.platform_data; 2600 wm8904->pdata = i2c->dev.platform_data;
@@ -2559,7 +2612,8 @@ static __devexit int wm8904_i2c_remove(struct i2c_client *client)
2559} 2612}
2560 2613
2561static const struct i2c_device_id wm8904_i2c_id[] = { 2614static const struct i2c_device_id wm8904_i2c_id[] = {
2562 { "wm8904", 0 }, 2615 { "wm8904", WM8904 },
2616 { "wm8912", WM8912 },
2563 { } 2617 { }
2564}; 2618};
2565MODULE_DEVICE_TABLE(i2c, wm8904_i2c_id); 2619MODULE_DEVICE_TABLE(i2c, wm8904_i2c_id);