Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 148198
b: refs/heads/master
c: 6b87a91
h: refs/heads/master
v: v3
  • Loading branch information
Peter Ujfalusi authored and Mark Brown committed Apr 17, 2009
1 parent 18cedf6 commit 39df492
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 20 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8d98f2246d7c622198ae0b8ca66f1c82b8a25377
refs/heads/master: 6b87a91f5417226c7fe62100b0e7217e7096b789
85 changes: 66 additions & 19 deletions trunk/sound/soc/codecs/twl4030.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,11 @@ struct twl4030_priv {

struct snd_pcm_substream *master_substream;
struct snd_pcm_substream *slave_substream;

unsigned int configured;
unsigned int rate;
unsigned int sample_bits;
unsigned int channels;
};

/*
Expand Down Expand Up @@ -1220,6 +1225,36 @@ static int twl4030_set_bias_level(struct snd_soc_codec *codec,
return 0;
}

static void twl4030_constraints(struct twl4030_priv *twl4030,
struct snd_pcm_substream *mst_substream)
{
struct snd_pcm_substream *slv_substream;

/* Pick the stream, which need to be constrained */
if (mst_substream == twl4030->master_substream)
slv_substream = twl4030->slave_substream;
else if (mst_substream == twl4030->slave_substream)
slv_substream = twl4030->master_substream;
else /* This should not happen.. */
return;

/* Set the constraints according to the already configured stream */
snd_pcm_hw_constraint_minmax(slv_substream->runtime,
SNDRV_PCM_HW_PARAM_RATE,
twl4030->rate,
twl4030->rate);

snd_pcm_hw_constraint_minmax(slv_substream->runtime,
SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
twl4030->sample_bits,
twl4030->sample_bits);

snd_pcm_hw_constraint_minmax(slv_substream->runtime,
SNDRV_PCM_HW_PARAM_CHANNELS,
twl4030->channels,
twl4030->channels);
}

static int twl4030_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
Expand All @@ -1228,26 +1263,16 @@ static int twl4030_startup(struct snd_pcm_substream *substream,
struct snd_soc_codec *codec = socdev->card->codec;
struct twl4030_priv *twl4030 = codec->private_data;

/* If we already have a playback or capture going then constrain
* this substream to match it.
*/
if (twl4030->master_substream) {
struct snd_pcm_runtime *master_runtime;
master_runtime = twl4030->master_substream->runtime;

snd_pcm_hw_constraint_minmax(substream->runtime,
SNDRV_PCM_HW_PARAM_RATE,
master_runtime->rate,
master_runtime->rate);

snd_pcm_hw_constraint_minmax(substream->runtime,
SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
master_runtime->sample_bits,
master_runtime->sample_bits);

twl4030->slave_substream = substream;
} else
/* The DAI has one configuration for playback and capture, so
* if the DAI has been already configured then constrain this
* substream to match it. */
if (twl4030->configured)
twl4030_constraints(twl4030, twl4030->master_substream);
} else {
twl4030->master_substream = substream;
}

return 0;
}
Expand All @@ -1264,6 +1289,13 @@ static void twl4030_shutdown(struct snd_pcm_substream *substream,
twl4030->master_substream = twl4030->slave_substream;

twl4030->slave_substream = NULL;

/* If all streams are closed, or the remaining stream has not yet
* been configured than set the DAI as not configured. */
if (!twl4030->master_substream)
twl4030->configured = 0;
else if (!twl4030->master_substream->runtime->channels)
twl4030->configured = 0;
}

static int twl4030_hw_params(struct snd_pcm_substream *substream,
Expand All @@ -1276,8 +1308,8 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
struct twl4030_priv *twl4030 = codec->private_data;
u8 mode, old_mode, format, old_format;

if (substream == twl4030->slave_substream)
/* Ignoring hw_params for slave substream */
if (twl4030->configured)
/* Ignoring hw_params for already configured DAI */
return 0;

/* bit rate */
Expand Down Expand Up @@ -1357,6 +1389,21 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
/* set CODECPDZ afterwards */
twl4030_codec_enable(codec, 1);
}

/* Store the important parameters for the DAI configuration and set
* the DAI as configured */
twl4030->configured = 1;
twl4030->rate = params_rate(params);
twl4030->sample_bits = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min;
twl4030->channels = params_channels(params);

/* If both playback and capture streams are open, and one of them
* is setting the hw parameters right now (since we are here), set
* constraints to the other stream to match the current one. */
if (twl4030->slave_substream)
twl4030_constraints(twl4030, substream);

return 0;
}

Expand Down

0 comments on commit 39df492

Please sign in to comment.