diff options
| -rw-r--r-- | sound/soc/codecs/wm8904.c | 90 |
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 @@ | |||
| 33 | static struct snd_soc_codec *wm8904_codec; | 33 | static struct snd_soc_codec *wm8904_codec; |
| 34 | struct snd_soc_codec_device soc_codec_dev_wm8904; | 34 | struct snd_soc_codec_device soc_codec_dev_wm8904; |
| 35 | 35 | ||
| 36 | enum 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 | ||
| 1421 | static 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 | |||
| 1414 | static int wm8904_add_widgets(struct snd_soc_codec *codec) | 1429 | static 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 | ||
| 2561 | static const struct i2c_device_id wm8904_i2c_id[] = { | 2614 | static const struct i2c_device_id wm8904_i2c_id[] = { |
| 2562 | { "wm8904", 0 }, | 2615 | { "wm8904", WM8904 }, |
| 2616 | { "wm8912", WM8912 }, | ||
| 2563 | { } | 2617 | { } |
| 2564 | }; | 2618 | }; |
| 2565 | MODULE_DEVICE_TABLE(i2c, wm8904_i2c_id); | 2619 | MODULE_DEVICE_TABLE(i2c, wm8904_i2c_id); |
