ASoC: Complete supported clock ratios and rate constraints for wm8741

Signed-off-by: Ian Lartey <ian@opensource.wolfsonmicro.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
This commit is contained in:
Ian Lartey 2010-08-27 15:26:27 +01:00 committed by Mark Brown
parent 7eba6c05c5
commit 3fe4a5ee9c
1 changed files with 121 additions and 48 deletions

View File

@ -36,7 +36,7 @@ static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = {
"DVDD", "DVDD",
}; };
#define WM8741_NUM_RATES 4 #define WM8741_NUM_RATES 6
/* codec private data */ /* codec private data */
struct wm8741_priv { struct wm8741_priv {
@ -44,8 +44,7 @@ struct wm8741_priv {
u16 reg_cache[WM8741_REGISTER_COUNT]; u16 reg_cache[WM8741_REGISTER_COUNT];
struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES]; struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES];
unsigned int sysclk; unsigned int sysclk;
unsigned int rate_constraint_list[WM8741_NUM_RATES]; struct snd_pcm_hw_constraint_list *sysclk_constraints;
struct snd_pcm_hw_constraint_list rate_constraint;
}; };
static const u16 wm8741_reg_defaults[WM8741_REGISTER_COUNT] = { static const u16 wm8741_reg_defaults[WM8741_REGISTER_COUNT] = {
@ -108,10 +107,84 @@ static struct {
int value; int value;
int ratio; int ratio;
} lrclk_ratios[WM8741_NUM_RATES] = { } lrclk_ratios[WM8741_NUM_RATES] = {
{ 1, 256 }, { 1, 128 },
{ 2, 384 }, { 2, 192 },
{ 3, 512 }, { 3, 256 },
{ 4, 768 }, { 4, 384 },
{ 5, 512 },
{ 6, 768 },
};
static unsigned int rates_11289[] = {
44100, 88235,
};
static struct snd_pcm_hw_constraint_list constraints_11289 = {
.count = ARRAY_SIZE(rates_11289),
.list = rates_11289,
};
static unsigned int rates_12288[] = {
32000, 48000, 96000,
};
static struct snd_pcm_hw_constraint_list constraints_12288 = {
.count = ARRAY_SIZE(rates_12288),
.list = rates_12288,
};
static unsigned int rates_16384[] = {
32000,
};
static struct snd_pcm_hw_constraint_list constraints_16384 = {
.count = ARRAY_SIZE(rates_16384),
.list = rates_16384,
};
static unsigned int rates_16934[] = {
44100, 88235,
};
static struct snd_pcm_hw_constraint_list constraints_16934 = {
.count = ARRAY_SIZE(rates_16934),
.list = rates_16934,
};
static unsigned int rates_18432[] = {
48000, 96000,
};
static struct snd_pcm_hw_constraint_list constraints_18432 = {
.count = ARRAY_SIZE(rates_18432),
.list = rates_18432,
};
static unsigned int rates_22579[] = {
44100, 88235, 1764000
};
static struct snd_pcm_hw_constraint_list constraints_22579 = {
.count = ARRAY_SIZE(rates_22579),
.list = rates_22579,
};
static unsigned int rates_24576[] = {
32000, 48000, 96000, 192000
};
static struct snd_pcm_hw_constraint_list constraints_24576 = {
.count = ARRAY_SIZE(rates_24576),
.list = rates_24576,
};
static unsigned int rates_36864[] = {
48000, 96000, 19200
};
static struct snd_pcm_hw_constraint_list constraints_36864 = {
.count = ARRAY_SIZE(rates_36864),
.list = rates_36864,
}; };
@ -132,7 +205,7 @@ static int wm8741_startup(struct snd_pcm_substream *substream,
snd_pcm_hw_constraint_list(substream->runtime, 0, snd_pcm_hw_constraint_list(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_RATE, SNDRV_PCM_HW_PARAM_RATE,
&wm8741->rate_constraint); wm8741->sysclk_constraints);
return 0; return 0;
} }
@ -192,47 +265,52 @@ static int wm8741_set_dai_sysclk(struct snd_soc_dai *codec_dai,
{ {
struct snd_soc_codec *codec = codec_dai->codec; struct snd_soc_codec *codec = codec_dai->codec;
struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec); struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
unsigned int val;
int i;
dev_dbg(codec->dev, "wm8741_set_dai_sysclk info: freq=%dHz\n", freq); dev_dbg(codec->dev, "wm8741_set_dai_sysclk info: freq=%dHz\n", freq);
switch (freq) {
case 11289600:
wm8741->sysclk_constraints = &constraints_11289;
wm8741->sysclk = freq; wm8741->sysclk = freq;
wm8741->rate_constraint.count = 0;
for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) {
dev_dbg(codec->dev, "index = %d, ratio = %d, freq = %d",
i, lrclk_ratios[i].ratio, freq);
val = freq / lrclk_ratios[i].ratio;
/* Check that it's a standard rate since core can't
* cope with others and having the odd rates confuses
* constraint matching.
*/
switch (val) {
case 32000:
case 44100:
case 48000:
case 64000:
case 88200:
case 96000:
dev_dbg(codec->dev, "Supported sample rate: %dHz\n",
val);
wm8741->rate_constraint_list[i] = val;
wm8741->rate_constraint.count++;
break;
default:
dev_dbg(codec->dev, "Skipping sample rate: %dHz\n",
val);
}
}
/* Need at least one supported rate... */
if (wm8741->rate_constraint.count == 0)
return -EINVAL;
return 0; return 0;
case 12288000:
wm8741->sysclk_constraints = &constraints_12288;
wm8741->sysclk = freq;
return 0;
case 16384000:
wm8741->sysclk_constraints = &constraints_16384;
wm8741->sysclk = freq;
return 0;
case 16934400:
wm8741->sysclk_constraints = &constraints_16934;
wm8741->sysclk = freq;
return 0;
case 18432000:
wm8741->sysclk_constraints = &constraints_18432;
wm8741->sysclk = freq;
return 0;
case 22579200:
case 33868800:
wm8741->sysclk_constraints = &constraints_22579;
wm8741->sysclk = freq;
return 0;
case 24576000:
wm8741->sysclk_constraints = &constraints_24576;
wm8741->sysclk = freq;
return 0;
case 36864000:
wm8741->sysclk_constraints = &constraints_36864;
wm8741->sysclk = freq;
return 0;
}
return -EINVAL;
} }
static int wm8741_set_dai_fmt(struct snd_soc_dai *codec_dai, static int wm8741_set_dai_fmt(struct snd_soc_dai *codec_dai,
@ -391,10 +469,6 @@ static int wm8741_i2c_probe(struct i2c_client *i2c,
if (wm8741 == NULL) if (wm8741 == NULL)
return -ENOMEM; return -ENOMEM;
wm8741->rate_constraint.list = &wm8741->rate_constraint_list[0];
wm8741->rate_constraint.count =
ARRAY_SIZE(wm8741->rate_constraint_list);
for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++) for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++)
wm8741->supplies[i].supply = wm8741_supply_names[i]; wm8741->supplies[i].supply = wm8741_supply_names[i];
@ -464,9 +538,8 @@ static int __init wm8741_modinit(void)
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
ret = i2c_add_driver(&wm8741_i2c_driver); ret = i2c_add_driver(&wm8741_i2c_driver);
if (ret != 0) { if (ret != 0)
pr_err("Failed to register WM8741 I2C driver: %d\n", ret); pr_err("Failed to register WM8741 I2C driver: %d\n", ret);
}
#endif #endif
return ret; return ret;