aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOmair Mohammed Abdullah2013-01-31 05:05:39 -0600
committerGlenn Kasten2014-07-09 21:25:27 -0500
commit7a0b995d87f6b08d6370f36e48f056069d61aa12 (patch)
treea00d40142c218ddb8e90c3a0554008bb5d3249e6
parentc6d37224e75b68a70a852fd78f88e38124d1781c (diff)
downloadplatform-external-tinyalsa-7a0b995d87f6b08d6370f36e48f056069d61aa12.tar.gz
platform-external-tinyalsa-7a0b995d87f6b08d6370f36e48f056069d61aa12.tar.xz
platform-external-tinyalsa-7a0b995d87f6b08d6370f36e48f056069d61aa12.zip
tinyalsa: add separate call for pcm prepare
Tinyalsa combines PREPARE and START calls to the driver in the pcm_start() function. Typically, this is needed for making a driver allocating hardware resources that are not related to a PCM stream. Change-Id: Ic83fad784936bbebab28e8e425debd449182db88 Signed-off-by: Omair Mohammed Abdullah <omair.m.abdullah@linux.intel.com> Signed-off-by: David Wagner <david.wagner@intel.com> Signed-off-by: Bruce Beare <bruce.j.beare@intel.com> Signed-off-by: Jack Ren <jack.ren@intel.com> Author-Tracking-BZ: 73509 Signed-off-by: Glenn Kasten <gkasten@google.com> Bug: 16191181
-rw-r--r--include/tinyalsa/asoundlib.h2
-rw-r--r--pcm.c26
2 files changed, 25 insertions, 3 deletions
diff --git a/include/tinyalsa/asoundlib.h b/include/tinyalsa/asoundlib.h
index de9dde7..0c4c7af 100644
--- a/include/tinyalsa/asoundlib.h
+++ b/include/tinyalsa/asoundlib.h
@@ -232,6 +232,8 @@ int pcm_mmap_begin(struct pcm *pcm, void **areas, unsigned int *offset,
232 unsigned int *frames); 232 unsigned int *frames);
233int pcm_mmap_commit(struct pcm *pcm, unsigned int offset, unsigned int frames); 233int pcm_mmap_commit(struct pcm *pcm, unsigned int offset, unsigned int frames);
234 234
235/* Prepare the PCM substream to be triggerable */
236int pcm_prepare(struct pcm *pcm);
235/* Start and stop a PCM channel that doesn't transfer data */ 237/* Start and stop a PCM channel that doesn't transfer data */
236int pcm_start(struct pcm *pcm); 238int pcm_start(struct pcm *pcm);
237int pcm_stop(struct pcm *pcm); 239int pcm_stop(struct pcm *pcm);
diff --git a/pcm.c b/pcm.c
index 6d85839..a25428e 100644
--- a/pcm.c
+++ b/pcm.c
@@ -245,6 +245,7 @@ struct pcm {
245 int fd; 245 int fd;
246 unsigned int flags; 246 unsigned int flags;
247 int running:1; 247 int running:1;
248 int prepared:1;
248 int underruns; 249 int underruns;
249 unsigned int buffer_size; 250 unsigned int buffer_size;
250 unsigned int boundary; 251 unsigned int boundary;
@@ -492,14 +493,16 @@ int pcm_write(struct pcm *pcm, const void *data, unsigned int count)
492 493
493 for (;;) { 494 for (;;) {
494 if (!pcm->running) { 495 if (!pcm->running) {
495 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_PREPARE)) 496 int prepare_error = pcm_prepare(pcm);
496 return oops(pcm, errno, "cannot prepare channel"); 497 if (prepare_error)
498 return prepare_error;
497 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &x)) 499 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &x))
498 return oops(pcm, errno, "cannot write initial data"); 500 return oops(pcm, errno, "cannot write initial data");
499 pcm->running = 1; 501 pcm->running = 1;
500 return 0; 502 return 0;
501 } 503 }
502 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &x)) { 504 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &x)) {
505 pcm->prepared = 0;
503 pcm->running = 0; 506 pcm->running = 0;
504 if (errno == EPIPE) { 507 if (errno == EPIPE) {
505 /* we failed to make our window -- try to restart if we are 508 /* we failed to make our window -- try to restart if we are
@@ -535,6 +538,7 @@ int pcm_read(struct pcm *pcm, void *data, unsigned int count)
535 } 538 }
536 } 539 }
537 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_READI_FRAMES, &x)) { 540 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_READI_FRAMES, &x)) {
541 pcm->prepared = 0;
538 pcm->running = 0; 542 pcm->running = 0;
539 if (errno == EPIPE) { 543 if (errno == EPIPE) {
540 /* we failed to make our window -- try to restart */ 544 /* we failed to make our window -- try to restart */
@@ -824,6 +828,7 @@ int pcm_close(struct pcm *pcm)
824 828
825 if (pcm->fd >= 0) 829 if (pcm->fd >= 0)
826 close(pcm->fd); 830 close(pcm->fd);
831 pcm->prepared = 0;
827 pcm->running = 0; 832 pcm->running = 0;
828 pcm->buffer_size = 0; 833 pcm->buffer_size = 0;
829 pcm->fd = -1; 834 pcm->fd = -1;
@@ -994,11 +999,24 @@ int pcm_is_ready(struct pcm *pcm)
994 return pcm->fd >= 0; 999 return pcm->fd >= 0;
995} 1000}
996 1001
997int pcm_start(struct pcm *pcm) 1002int pcm_prepare(struct pcm *pcm)
998{ 1003{
1004 if (pcm->prepared)
1005 return 0;
1006
999 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_PREPARE) < 0) 1007 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_PREPARE) < 0)
1000 return oops(pcm, errno, "cannot prepare channel"); 1008 return oops(pcm, errno, "cannot prepare channel");
1001 1009
1010 pcm->prepared = 1;
1011 return 0;
1012}
1013
1014int pcm_start(struct pcm *pcm)
1015{
1016 int prepare_error = pcm_prepare(pcm);
1017 if (prepare_error)
1018 return prepare_error;
1019
1002 if (pcm->flags & PCM_MMAP) 1020 if (pcm->flags & PCM_MMAP)
1003 pcm_sync_ptr(pcm, 0); 1021 pcm_sync_ptr(pcm, 0);
1004 1022
@@ -1014,6 +1032,7 @@ int pcm_stop(struct pcm *pcm)
1014 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_DROP) < 0) 1032 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_DROP) < 0)
1015 return oops(pcm, errno, "cannot stop channel"); 1033 return oops(pcm, errno, "cannot stop channel");
1016 1034
1035 pcm->prepared = 0;
1017 pcm->running = 0; 1036 pcm->running = 0;
1018 return 0; 1037 return 0;
1019} 1038}
@@ -1212,6 +1231,7 @@ int pcm_mmap_transfer(struct pcm *pcm, const void *buffer, unsigned int bytes)
1212 1231
1213 err = pcm_wait(pcm, time); 1232 err = pcm_wait(pcm, time);
1214 if (err < 0) { 1233 if (err < 0) {
1234 pcm->prepared = 0;
1215 pcm->running = 0; 1235 pcm->running = 0;
1216 oops(pcm, err, "wait error: hw 0x%x app 0x%x avail 0x%x\n", 1236 oops(pcm, err, "wait error: hw 0x%x app 0x%x avail 0x%x\n",
1217 (unsigned int)pcm->mmap_status->hw_ptr, 1237 (unsigned int)pcm->mmap_status->hw_ptr,