Commit c94aa30e authored by Mark Brown's avatar Mark Brown

ASoC: arizona: Allow number of channels clocked to be restricted

Place a cap on the number of channels clocks are generated for. This is
intended for use with systems which have the WM5102 master an I2S bus with
multiple data lines.
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent f2c26d48
...@@ -62,6 +62,8 @@ ...@@ -62,6 +62,8 @@
#define ARIZONA_MAX_OUTPUT 6 #define ARIZONA_MAX_OUTPUT 6
#define ARIZONA_MAX_AIF 3
#define ARIZONA_HAP_ACT_ERM 0 #define ARIZONA_HAP_ACT_ERM 0
#define ARIZONA_HAP_ACT_LRA 2 #define ARIZONA_HAP_ACT_LRA 2
...@@ -96,6 +98,13 @@ struct arizona_pdata { ...@@ -96,6 +98,13 @@ struct arizona_pdata {
/** Pin state for GPIO pins */ /** Pin state for GPIO pins */
int gpio_defaults[ARIZONA_MAX_GPIO]; int gpio_defaults[ARIZONA_MAX_GPIO];
/**
* Maximum number of channels clocks will be generated for,
* useful for systems where and I2S bus with multiple data
* lines is mastered.
*/
int max_channels_clocked[ARIZONA_MAX_AIF];
/** GPIO for mic detection polarity */ /** GPIO for mic detection polarity */
int micd_pol_gpio; int micd_pol_gpio;
......
...@@ -762,18 +762,28 @@ static int arizona_hw_params(struct snd_pcm_substream *substream, ...@@ -762,18 +762,28 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai) struct snd_soc_dai *dai)
{ {
struct snd_soc_codec *codec = dai->codec; struct snd_soc_codec *codec = dai->codec;
struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
struct arizona *arizona = priv->arizona;
int base = dai->driver->base; int base = dai->driver->base;
const int *rates; const int *rates;
int i, ret; int i, ret;
int bclk, lrclk, wl, frame; int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1];
int bclk, lrclk, wl, frame, bclk_target;
if (params_rate(params) % 8000) if (params_rate(params) % 8000)
rates = &arizona_44k1_bclk_rates[0]; rates = &arizona_44k1_bclk_rates[0];
else else
rates = &arizona_48k_bclk_rates[0]; rates = &arizona_48k_bclk_rates[0];
bclk_target = snd_soc_params_to_bclk(params);
if (chan_limit && chan_limit < params_channels(params)) {
arizona_aif_dbg(dai, "Limiting to %d channels\n", chan_limit);
bclk_target /= params_channels(params);
bclk_target *= chan_limit;
}
for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) { for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
if (rates[i] >= snd_soc_params_to_bclk(params) && if (rates[i] >= bclk_target &&
rates[i] % params_rate(params) == 0) { rates[i] % params_rate(params) == 0) {
bclk = i; bclk = i;
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment