Skip to content

Commit 694954a

Browse files
author
Fox Snowpatch
committed
1 parent a2f7734 commit 694954a

File tree

1 file changed

+42
-11
lines changed
  • sound/aoa/soundbus/i2sbus

1 file changed

+42
-11
lines changed

sound/aoa/soundbus/i2sbus/pcm.c

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -165,17 +165,16 @@ static int i2sbus_pcm_open(struct i2sbus_dev *i2sdev, int in)
165165
* currently in use (if any). */
166166
hw->rate_min = 5512;
167167
hw->rate_max = 192000;
168-
/* if the other stream is active, then we can only
169-
* support what it is currently using.
170-
* FIXME: I lied. This comment is wrong. We can support
171-
* anything that works with the same serial format, ie.
172-
* when recording 24 bit sound we can well play 16 bit
173-
* sound at the same time iff using the same transfer mode.
168+
/* If the other stream is already prepared, keep this stream
169+
* on the same duplex format and rate.
170+
*
171+
* i2sbus_pcm_prepare() still programs one shared transport
172+
* configuration for both directions, so mixed duplex formats
173+
* are not supported here.
174174
*/
175175
if (other->active) {
176-
/* FIXME: is this guaranteed by the alsa api? */
177176
hw->formats &= pcm_format_to_bits(i2sdev->format);
178-
/* see above, restrict rates to the one we already have */
177+
/* Restrict rates to the one already in use. */
179178
hw->rate_min = i2sdev->rate;
180179
hw->rate_max = i2sdev->rate;
181180
}
@@ -283,6 +282,22 @@ void i2sbus_wait_for_stop_both(struct i2sbus_dev *i2sdev)
283282
}
284283
#endif
285284

285+
static void i2sbus_pcm_clear_active(struct i2sbus_dev *i2sdev, int in)
286+
{
287+
struct pcm_info *pi;
288+
289+
guard(mutex)(&i2sdev->lock);
290+
291+
get_pcm_info(i2sdev, in, &pi, NULL);
292+
pi->active = 0;
293+
}
294+
295+
static inline int i2sbus_hw_params(struct snd_pcm_substream *substream, int in)
296+
{
297+
i2sbus_pcm_clear_active(snd_pcm_substream_chip(substream), in);
298+
return 0;
299+
}
300+
286301
static inline int i2sbus_hw_free(struct snd_pcm_substream *substream, int in)
287302
{
288303
struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
@@ -291,14 +306,25 @@ static inline int i2sbus_hw_free(struct snd_pcm_substream *substream, int in)
291306
get_pcm_info(i2sdev, in, &pi, NULL);
292307
if (pi->dbdma_ring.stopping)
293308
i2sbus_wait_for_stop(i2sdev, pi);
309+
i2sbus_pcm_clear_active(i2sdev, in);
294310
return 0;
295311
}
296312

313+
static int i2sbus_playback_hw_params(struct snd_pcm_substream *substream)
314+
{
315+
return i2sbus_hw_params(substream, 0);
316+
}
317+
297318
static int i2sbus_playback_hw_free(struct snd_pcm_substream *substream)
298319
{
299320
return i2sbus_hw_free(substream, 0);
300321
}
301322

323+
static int i2sbus_record_hw_params(struct snd_pcm_substream *substream)
324+
{
325+
return i2sbus_hw_params(substream, 1);
326+
}
327+
302328
static int i2sbus_record_hw_free(struct snd_pcm_substream *substream)
303329
{
304330
return i2sbus_hw_free(substream, 1);
@@ -335,7 +361,7 @@ static int i2sbus_pcm_prepare(struct i2sbus_dev *i2sdev, int in)
335361
return -EINVAL;
336362

337363
runtime = pi->substream->runtime;
338-
pi->active = 1;
364+
pi->active = 0;
339365
if (other->active &&
340366
((i2sdev->format != runtime->format)
341367
|| (i2sdev->rate != runtime->rate)))
@@ -450,9 +476,11 @@ static int i2sbus_pcm_prepare(struct i2sbus_dev *i2sdev, int in)
450476

451477
/* early exit if already programmed correctly */
452478
/* not locking these is fine since we touch them only in this function */
453-
if (in_le32(&i2sdev->intfregs->serial_format) == sfr
454-
&& in_le32(&i2sdev->intfregs->data_word_sizes) == dws)
479+
if (in_le32(&i2sdev->intfregs->serial_format) == sfr &&
480+
in_le32(&i2sdev->intfregs->data_word_sizes) == dws) {
481+
pi->active = 1;
455482
return 0;
483+
}
456484

457485
/* let's notify the codecs about clocks going away.
458486
* For now we only do mastering on the i2s cell... */
@@ -490,6 +518,7 @@ static int i2sbus_pcm_prepare(struct i2sbus_dev *i2sdev, int in)
490518
if (cii->codec->switch_clock)
491519
cii->codec->switch_clock(cii, CLOCK_SWITCH_SLAVE);
492520

521+
pi->active = 1;
493522
return 0;
494523
}
495524

@@ -734,6 +763,7 @@ static snd_pcm_uframes_t i2sbus_playback_pointer(struct snd_pcm_substream
734763
static const struct snd_pcm_ops i2sbus_playback_ops = {
735764
.open = i2sbus_playback_open,
736765
.close = i2sbus_playback_close,
766+
.hw_params = i2sbus_playback_hw_params,
737767
.hw_free = i2sbus_playback_hw_free,
738768
.prepare = i2sbus_playback_prepare,
739769
.trigger = i2sbus_playback_trigger,
@@ -802,6 +832,7 @@ static snd_pcm_uframes_t i2sbus_record_pointer(struct snd_pcm_substream
802832
static const struct snd_pcm_ops i2sbus_record_ops = {
803833
.open = i2sbus_record_open,
804834
.close = i2sbus_record_close,
835+
.hw_params = i2sbus_record_hw_params,
805836
.hw_free = i2sbus_record_hw_free,
806837
.prepare = i2sbus_record_prepare,
807838
.trigger = i2sbus_record_trigger,

0 commit comments

Comments
 (0)