wm8993.c (cf0dbba515415bb19b11f9323d5f7bebd7f24fd6) wm8993.c (b2c812e22de88bb79c290c0e718280f10b64a48d)
1/*
2 * wm8993.c -- WM8993 ALSA SoC audio driver
3 *
4 * Copyright 2009, 2010 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify

--- 4 unchanged lines hidden (view full) ---

13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/i2c.h>
19#include <linux/regulator/consumer.h>
20#include <linux/spi/spi.h>
1/*
2 * wm8993.c -- WM8993 ALSA SoC audio driver
3 *
4 * Copyright 2009, 2010 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify

--- 4 unchanged lines hidden (view full) ---

13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/i2c.h>
19#include <linux/regulator/consumer.h>
20#include <linux/spi/spi.h>
21#include <linux/slab.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/tlv.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h>
29#include <sound/wm8993.h>

--- 336 unchanged lines hidden (view full) ---

366
367 return 0;
368}
369
370static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
371 unsigned int Fref, unsigned int Fout)
372{
373 struct snd_soc_codec *codec = dai->codec;
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/tlv.h>
25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h>
28#include <sound/wm8993.h>

--- 336 unchanged lines hidden (view full) ---

365
366 return 0;
367}
368
369static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
370 unsigned int Fref, unsigned int Fout)
371{
372 struct snd_soc_codec *codec = dai->codec;
374 struct wm8993_priv *wm8993 = codec->private_data;
373 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
375 u16 reg1, reg4, reg5;
376 struct _fll_div fll_div;
377 int ret;
378
379 /* Any change? */
380 if (Fref == wm8993->fll_fref && Fout == wm8993->fll_fout)
381 return 0;
382

--- 70 unchanged lines hidden (view full) ---

453 wm8993->fll_fout = Fout;
454 wm8993->fll_src = source;
455
456 return 0;
457}
458
459static int configure_clock(struct snd_soc_codec *codec)
460{
374 u16 reg1, reg4, reg5;
375 struct _fll_div fll_div;
376 int ret;
377
378 /* Any change? */
379 if (Fref == wm8993->fll_fref && Fout == wm8993->fll_fout)
380 return 0;
381

--- 70 unchanged lines hidden (view full) ---

452 wm8993->fll_fout = Fout;
453 wm8993->fll_src = source;
454
455 return 0;
456}
457
458static int configure_clock(struct snd_soc_codec *codec)
459{
461 struct wm8993_priv *wm8993 = codec->private_data;
460 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
462 unsigned int reg;
463
464 /* This should be done on init() for bypass paths */
465 switch (wm8993->sysclk_source) {
466 case WM8993_SYSCLK_MCLK:
467 dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8993->mclk_rate);
468
469 reg = snd_soc_read(codec, WM8993_CLOCKING_2);

--- 242 unchanged lines hidden (view full) ---

712 * Currently the only supported paths are the direct DAC->headphone
713 * paths (which provide minimum power consumption anyway).
714 */
715static int class_w_put(struct snd_kcontrol *kcontrol,
716 struct snd_ctl_elem_value *ucontrol)
717{
718 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
719 struct snd_soc_codec *codec = widget->codec;
461 unsigned int reg;
462
463 /* This should be done on init() for bypass paths */
464 switch (wm8993->sysclk_source) {
465 case WM8993_SYSCLK_MCLK:
466 dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8993->mclk_rate);
467
468 reg = snd_soc_read(codec, WM8993_CLOCKING_2);

--- 242 unchanged lines hidden (view full) ---

711 * Currently the only supported paths are the direct DAC->headphone
712 * paths (which provide minimum power consumption anyway).
713 */
714static int class_w_put(struct snd_kcontrol *kcontrol,
715 struct snd_ctl_elem_value *ucontrol)
716{
717 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
718 struct snd_soc_codec *codec = widget->codec;
720 struct wm8993_priv *wm8993 = codec->private_data;
719 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
721 int ret;
722
723 /* Turn it off if we're using the main output mixer */
724 if (ucontrol->value.integer.value[0] == 0) {
725 if (wm8993->class_w_users == 0) {
726 dev_dbg(codec->dev, "Disabling Class W\n");
727 snd_soc_update_bits(codec, WM8993_CLASS_W_0,
728 WM8993_CP_DYN_FREQ |

--- 215 unchanged lines hidden (view full) ---

944
945 /* We're in sync again */
946 codec->cache_sync = 0;
947}
948
949static int wm8993_set_bias_level(struct snd_soc_codec *codec,
950 enum snd_soc_bias_level level)
951{
720 int ret;
721
722 /* Turn it off if we're using the main output mixer */
723 if (ucontrol->value.integer.value[0] == 0) {
724 if (wm8993->class_w_users == 0) {
725 dev_dbg(codec->dev, "Disabling Class W\n");
726 snd_soc_update_bits(codec, WM8993_CLASS_W_0,
727 WM8993_CP_DYN_FREQ |

--- 215 unchanged lines hidden (view full) ---

943
944 /* We're in sync again */
945 codec->cache_sync = 0;
946}
947
948static int wm8993_set_bias_level(struct snd_soc_codec *codec,
949 enum snd_soc_bias_level level)
950{
952 struct wm8993_priv *wm8993 = codec->private_data;
951 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
953 int ret;
954
955 switch (level) {
956 case SND_SOC_BIAS_ON:
957 case SND_SOC_BIAS_PREPARE:
958 /* VMID=2*40k */
959 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
960 WM8993_VMID_SEL_MASK, 0x2);

--- 81 unchanged lines hidden (view full) ---

1042
1043 return 0;
1044}
1045
1046static int wm8993_set_sysclk(struct snd_soc_dai *codec_dai,
1047 int clk_id, unsigned int freq, int dir)
1048{
1049 struct snd_soc_codec *codec = codec_dai->codec;
952 int ret;
953
954 switch (level) {
955 case SND_SOC_BIAS_ON:
956 case SND_SOC_BIAS_PREPARE:
957 /* VMID=2*40k */
958 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
959 WM8993_VMID_SEL_MASK, 0x2);

--- 81 unchanged lines hidden (view full) ---

1041
1042 return 0;
1043}
1044
1045static int wm8993_set_sysclk(struct snd_soc_dai *codec_dai,
1046 int clk_id, unsigned int freq, int dir)
1047{
1048 struct snd_soc_codec *codec = codec_dai->codec;
1050 struct wm8993_priv *wm8993 = codec->private_data;
1049 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1051
1052 switch (clk_id) {
1053 case WM8993_SYSCLK_MCLK:
1054 wm8993->mclk_rate = freq;
1055 case WM8993_SYSCLK_FLL:
1056 wm8993->sysclk_source = clk_id;
1057 break;
1058
1059 default:
1060 return -EINVAL;
1061 }
1062
1063 return 0;
1064}
1065
1066static int wm8993_set_dai_fmt(struct snd_soc_dai *dai,
1067 unsigned int fmt)
1068{
1069 struct snd_soc_codec *codec = dai->codec;
1050
1051 switch (clk_id) {
1052 case WM8993_SYSCLK_MCLK:
1053 wm8993->mclk_rate = freq;
1054 case WM8993_SYSCLK_FLL:
1055 wm8993->sysclk_source = clk_id;
1056 break;
1057
1058 default:
1059 return -EINVAL;
1060 }
1061
1062 return 0;
1063}
1064
1065static int wm8993_set_dai_fmt(struct snd_soc_dai *dai,
1066 unsigned int fmt)
1067{
1068 struct snd_soc_codec *codec = dai->codec;
1070 struct wm8993_priv *wm8993 = codec->private_data;
1069 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1071 unsigned int aif1 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_1);
1072 unsigned int aif4 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_4);
1073
1074 aif1 &= ~(WM8993_BCLK_DIR | WM8993_AIF_BCLK_INV |
1075 WM8993_AIF_LRCLK_INV | WM8993_AIF_FMT_MASK);
1076 aif4 &= ~WM8993_LRCLK_DIR;
1077
1078 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {

--- 79 unchanged lines hidden (view full) ---

1158 return 0;
1159}
1160
1161static int wm8993_hw_params(struct snd_pcm_substream *substream,
1162 struct snd_pcm_hw_params *params,
1163 struct snd_soc_dai *dai)
1164{
1165 struct snd_soc_codec *codec = dai->codec;
1070 unsigned int aif1 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_1);
1071 unsigned int aif4 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_4);
1072
1073 aif1 &= ~(WM8993_BCLK_DIR | WM8993_AIF_BCLK_INV |
1074 WM8993_AIF_LRCLK_INV | WM8993_AIF_FMT_MASK);
1075 aif4 &= ~WM8993_LRCLK_DIR;
1076
1077 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {

--- 79 unchanged lines hidden (view full) ---

1157 return 0;
1158}
1159
1160static int wm8993_hw_params(struct snd_pcm_substream *substream,
1161 struct snd_pcm_hw_params *params,
1162 struct snd_soc_dai *dai)
1163{
1164 struct snd_soc_codec *codec = dai->codec;
1166 struct wm8993_priv *wm8993 = codec->private_data;
1165 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1167 int ret, i, best, best_val, cur_val;
1168 unsigned int clocking1, clocking3, aif1, aif4;
1169
1170 clocking1 = snd_soc_read(codec, WM8993_CLOCKING_1);
1171 clocking1 &= ~WM8993_BCLK_DIV_MASK;
1172
1173 clocking3 = snd_soc_read(codec, WM8993_CLOCKING_3);
1174 clocking3 &= ~(WM8993_CLK_SYS_RATE_MASK | WM8993_SAMPLE_RATE_MASK);

--- 148 unchanged lines hidden (view full) ---

1323
1324 return 0;
1325}
1326
1327static int wm8993_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
1328 unsigned int rx_mask, int slots, int slot_width)
1329{
1330 struct snd_soc_codec *codec = dai->codec;
1166 int ret, i, best, best_val, cur_val;
1167 unsigned int clocking1, clocking3, aif1, aif4;
1168
1169 clocking1 = snd_soc_read(codec, WM8993_CLOCKING_1);
1170 clocking1 &= ~WM8993_BCLK_DIV_MASK;
1171
1172 clocking3 = snd_soc_read(codec, WM8993_CLOCKING_3);
1173 clocking3 &= ~(WM8993_CLK_SYS_RATE_MASK | WM8993_SAMPLE_RATE_MASK);

--- 148 unchanged lines hidden (view full) ---

1322
1323 return 0;
1324}
1325
1326static int wm8993_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
1327 unsigned int rx_mask, int slots, int slot_width)
1328{
1329 struct snd_soc_codec *codec = dai->codec;
1331 struct wm8993_priv *wm8993 = codec->private_data;
1330 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1332 int aif1 = 0;
1333 int aif2 = 0;
1334
1335 /* Don't need to validate anything if we're turning off TDM */
1336 if (slots == 0) {
1337 wm8993->tdm_slots = 0;
1338 goto out;
1339 }

--- 86 unchanged lines hidden (view full) ---

1426
1427 if (!wm8993_codec) {
1428 dev_err(&pdev->dev, "I2C device not yet probed\n");
1429 goto err;
1430 }
1431
1432 socdev->card->codec = wm8993_codec;
1433 codec = wm8993_codec;
1331 int aif1 = 0;
1332 int aif2 = 0;
1333
1334 /* Don't need to validate anything if we're turning off TDM */
1335 if (slots == 0) {
1336 wm8993->tdm_slots = 0;
1337 goto out;
1338 }

--- 86 unchanged lines hidden (view full) ---

1425
1426 if (!wm8993_codec) {
1427 dev_err(&pdev->dev, "I2C device not yet probed\n");
1428 goto err;
1429 }
1430
1431 socdev->card->codec = wm8993_codec;
1432 codec = wm8993_codec;
1434 wm8993 = codec->private_data;
1433 wm8993 = snd_soc_codec_get_drvdata(codec);
1435
1436 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1437 if (ret < 0) {
1438 dev_err(codec->dev, "failed to create pcms\n");
1439 goto err;
1440 }
1441
1442 snd_soc_add_controls(codec, wm8993_snd_controls,

--- 30 unchanged lines hidden (view full) ---

1473 return 0;
1474}
1475
1476#ifdef CONFIG_PM
1477static int wm8993_suspend(struct platform_device *pdev, pm_message_t state)
1478{
1479 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1480 struct snd_soc_codec *codec = socdev->card->codec;
1434
1435 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1436 if (ret < 0) {
1437 dev_err(codec->dev, "failed to create pcms\n");
1438 goto err;
1439 }
1440
1441 snd_soc_add_controls(codec, wm8993_snd_controls,

--- 30 unchanged lines hidden (view full) ---

1472 return 0;
1473}
1474
1475#ifdef CONFIG_PM
1476static int wm8993_suspend(struct platform_device *pdev, pm_message_t state)
1477{
1478 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1479 struct snd_soc_codec *codec = socdev->card->codec;
1481 struct wm8993_priv *wm8993 = codec->private_data;
1480 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1482 int fll_fout = wm8993->fll_fout;
1483 int fll_fref = wm8993->fll_fref;
1484 int ret;
1485
1486 /* Stop the FLL in an orderly fashion */
1487 ret = wm8993_set_fll(codec->dai, 0, 0, 0, 0);
1488 if (ret != 0) {
1489 dev_err(&pdev->dev, "Failed to stop FLL\n");

--- 7 unchanged lines hidden (view full) ---

1497
1498 return 0;
1499}
1500
1501static int wm8993_resume(struct platform_device *pdev)
1502{
1503 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1504 struct snd_soc_codec *codec = socdev->card->codec;
1481 int fll_fout = wm8993->fll_fout;
1482 int fll_fref = wm8993->fll_fref;
1483 int ret;
1484
1485 /* Stop the FLL in an orderly fashion */
1486 ret = wm8993_set_fll(codec->dai, 0, 0, 0, 0);
1487 if (ret != 0) {
1488 dev_err(&pdev->dev, "Failed to stop FLL\n");

--- 7 unchanged lines hidden (view full) ---

1496
1497 return 0;
1498}
1499
1500static int wm8993_resume(struct platform_device *pdev)
1501{
1502 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1503 struct snd_soc_codec *codec = socdev->card->codec;
1505 struct wm8993_priv *wm8993 = codec->private_data;
1504 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1506 int ret;
1507
1508 wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1509
1510 /* Restart the FLL? */
1511 if (wm8993->fll_fout) {
1512 int fll_fout = wm8993->fll_fout;
1513 int fll_fref = wm8993->fll_fref;

--- 52 unchanged lines hidden (view full) ---

1566 codec->name = "WM8993";
1567 codec->volatile_register = wm8993_volatile;
1568 codec->reg_cache = wm8993->reg_cache;
1569 codec->reg_cache_size = ARRAY_SIZE(wm8993->reg_cache);
1570 codec->bias_level = SND_SOC_BIAS_OFF;
1571 codec->set_bias_level = wm8993_set_bias_level;
1572 codec->dai = &wm8993_dai;
1573 codec->num_dai = 1;
1505 int ret;
1506
1507 wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1508
1509 /* Restart the FLL? */
1510 if (wm8993->fll_fout) {
1511 int fll_fout = wm8993->fll_fout;
1512 int fll_fref = wm8993->fll_fref;

--- 52 unchanged lines hidden (view full) ---

1565 codec->name = "WM8993";
1566 codec->volatile_register = wm8993_volatile;
1567 codec->reg_cache = wm8993->reg_cache;
1568 codec->reg_cache_size = ARRAY_SIZE(wm8993->reg_cache);
1569 codec->bias_level = SND_SOC_BIAS_OFF;
1570 codec->set_bias_level = wm8993_set_bias_level;
1571 codec->dai = &wm8993_dai;
1572 codec->num_dai = 1;
1574 codec->private_data = wm8993;
1573 snd_soc_codec_set_drvdata(codec, wm8993);
1575
1576 wm8993->hubs_data.hp_startup_mode = 1;
1577 wm8993->hubs_data.dcs_codes = -2;
1578
1579 memcpy(wm8993->reg_cache, wm8993_reg_defaults,
1580 sizeof(wm8993->reg_cache));
1581
1582 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);

--- 146 unchanged lines hidden ---
1574
1575 wm8993->hubs_data.hp_startup_mode = 1;
1576 wm8993->hubs_data.dcs_codes = -2;
1577
1578 memcpy(wm8993->reg_cache, wm8993_reg_defaults,
1579 sizeof(wm8993->reg_cache));
1580
1581 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);

--- 146 unchanged lines hidden ---