Message ID | 67cea1f0a74c333ec2048c7796cda37302d45e95.1418826016.git.Andrew.Jackson@arm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Fri, Dec 19, 2014 at 04:18:06PM +0000, Andrew Jackson wrote: > The Designware core can be configured with up to four stereo channels. > Each stereo channel is individually configured so, when the driver's > hw_params call is made, each requested stereo channel has to be > programmed. This is quite unclear to someone who doesn't know the hardware, is this a bug fix or a new feature? It looks like it's a fix...
On 12/22/14 13:53, Mark Brown wrote: > On Fri, Dec 19, 2014 at 04:18:06PM +0000, Andrew Jackson wrote: > >> The Designware core can be configured with up to four stereo channels. >> Each stereo channel is individually configured so, when the driver's >> hw_params call is made, each requested stereo channel has to be >> programmed. > > This is quite unclear to someone who doesn't know the hardware, is this > a bug fix or a new feature? It looks like it's a fix... > It is a fix. In the Designware core, each stereo channel is configured individually. So, when hw_params is called to configure N channels, N/2 stereo channels need to be configured in the core. The existing code doesn't do this and will only configure the highest numbered channel. Andrew
On Fri, Dec 19, 2014 at 04:18:06PM +0000, Andrew Jackson wrote: > From: Andrew Jackson <Andrew.Jackson@arm.com> > > The Designware core can be configured with up to four stereo channels. > Each stereo channel is individually configured so, when the driver's > hw_params call is made, each requested stereo channel has to be > programmed. Applied, thanks.
diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c index 5c13303..2ba1e2e 100644 --- a/sound/soc/dwc/designware_i2s.c +++ b/sound/soc/dwc/designware_i2s.c @@ -209,16 +209,9 @@ static int dw_i2s_hw_params(struct snd_pcm_substream *substream, switch (config->chan_nr) { case EIGHT_CHANNEL_SUPPORT: - ch_reg = 3; - break; case SIX_CHANNEL_SUPPORT: - ch_reg = 2; - break; case FOUR_CHANNEL_SUPPORT: - ch_reg = 1; - break; case TWO_CHANNEL_SUPPORT: - ch_reg = 0; break; default: dev_err(dev->dev, "channel not supported\n"); @@ -227,18 +220,22 @@ static int dw_i2s_hw_params(struct snd_pcm_substream *substream, i2s_disable_channels(dev, substream->stream); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - i2s_write_reg(dev->i2s_base, TCR(ch_reg), xfer_resolution); - i2s_write_reg(dev->i2s_base, TFCR(ch_reg), 0x02); - irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg)); - i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x30); - i2s_write_reg(dev->i2s_base, TER(ch_reg), 1); - } else { - i2s_write_reg(dev->i2s_base, RCR(ch_reg), xfer_resolution); - i2s_write_reg(dev->i2s_base, RFCR(ch_reg), 0x07); - irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg)); - i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x03); - i2s_write_reg(dev->i2s_base, RER(ch_reg), 1); + for (ch_reg = 0; ch_reg < (config->chan_nr / 2); ch_reg++) { + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + i2s_write_reg(dev->i2s_base, TCR(ch_reg), + xfer_resolution); + i2s_write_reg(dev->i2s_base, TFCR(ch_reg), 0x02); + irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg)); + i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x30); + i2s_write_reg(dev->i2s_base, TER(ch_reg), 1); + } else { + i2s_write_reg(dev->i2s_base, RCR(ch_reg), + xfer_resolution); + i2s_write_reg(dev->i2s_base, RFCR(ch_reg), 0x07); + irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg)); + i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x03); + i2s_write_reg(dev->i2s_base, RER(ch_reg), 1); + } } i2s_write_reg(dev->i2s_base, CCR, ccr);