aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core/pcm.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core/pcm.c')
-rw-r--r--sound/core/pcm.c99
1 files changed, 69 insertions, 30 deletions
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 8928ca871c22..6e4bfcc14254 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -650,7 +650,7 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
650 pstr->stream = stream; 650 pstr->stream = stream;
651 pstr->pcm = pcm; 651 pstr->pcm = pcm;
652 pstr->substream_count = substream_count; 652 pstr->substream_count = substream_count;
653 if (substream_count > 0) { 653 if (substream_count > 0 && !pcm->internal) {
654 err = snd_pcm_stream_proc_init(pstr); 654 err = snd_pcm_stream_proc_init(pstr);
655 if (err < 0) { 655 if (err < 0) {
656 snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n"); 656 snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");
@@ -674,15 +674,18 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
674 pstr->substream = substream; 674 pstr->substream = substream;
675 else 675 else
676 prev->next = substream; 676 prev->next = substream;
677 err = snd_pcm_substream_proc_init(substream); 677
678 if (err < 0) { 678 if (!pcm->internal) {
679 snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n"); 679 err = snd_pcm_substream_proc_init(substream);
680 if (prev == NULL) 680 if (err < 0) {
681 pstr->substream = NULL; 681 snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");
682 else 682 if (prev == NULL)
683 prev->next = NULL; 683 pstr->substream = NULL;
684 kfree(substream); 684 else
685 return err; 685 prev->next = NULL;
686 kfree(substream);
687 return err;
688 }
686 } 689 }
687 substream->group = &substream->self_group; 690 substream->group = &substream->self_group;
688 spin_lock_init(&substream->self_group.lock); 691 spin_lock_init(&substream->self_group.lock);
@@ -696,25 +699,9 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
696 699
697EXPORT_SYMBOL(snd_pcm_new_stream); 700EXPORT_SYMBOL(snd_pcm_new_stream);
698 701
699/** 702static int _snd_pcm_new(struct snd_card *card, const char *id, int device,
700 * snd_pcm_new - create a new PCM instance 703 int playback_count, int capture_count, bool internal,
701 * @card: the card instance 704 struct snd_pcm **rpcm)
702 * @id: the id string
703 * @device: the device index (zero based)
704 * @playback_count: the number of substreams for playback
705 * @capture_count: the number of substreams for capture
706 * @rpcm: the pointer to store the new pcm instance
707 *
708 * Creates a new PCM instance.
709 *
710 * The pcm operators have to be set afterwards to the new instance
711 * via snd_pcm_set_ops().
712 *
713 * Returns zero if successful, or a negative error code on failure.
714 */
715int snd_pcm_new(struct snd_card *card, const char *id, int device,
716 int playback_count, int capture_count,
717 struct snd_pcm ** rpcm)
718{ 705{
719 struct snd_pcm *pcm; 706 struct snd_pcm *pcm;
720 int err; 707 int err;
@@ -735,6 +722,7 @@ int snd_pcm_new(struct snd_card *card, const char *id, int device,
735 } 722 }
736 pcm->card = card; 723 pcm->card = card;
737 pcm->device = device; 724 pcm->device = device;
725 pcm->internal = internal;
738 if (id) 726 if (id)
739 strlcpy(pcm->id, id, sizeof(pcm->id)); 727 strlcpy(pcm->id, id, sizeof(pcm->id));
740 if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, playback_count)) < 0) { 728 if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, playback_count)) < 0) {
@@ -756,8 +744,59 @@ int snd_pcm_new(struct snd_card *card, const char *id, int device,
756 return 0; 744 return 0;
757} 745}
758 746
747/**
748 * snd_pcm_new - create a new PCM instance
749 * @card: the card instance
750 * @id: the id string
751 * @device: the device index (zero based)
752 * @playback_count: the number of substreams for playback
753 * @capture_count: the number of substreams for capture
754 * @rpcm: the pointer to store the new pcm instance
755 *
756 * Creates a new PCM instance.
757 *
758 * The pcm operators have to be set afterwards to the new instance
759 * via snd_pcm_set_ops().
760 *
761 * Returns zero if successful, or a negative error code on failure.
762 */
763int snd_pcm_new(struct snd_card *card, const char *id, int device,
764 int playback_count, int capture_count, struct snd_pcm **rpcm)
765{
766 return _snd_pcm_new(card, id, device, playback_count, capture_count,
767 false, rpcm);
768}
759EXPORT_SYMBOL(snd_pcm_new); 769EXPORT_SYMBOL(snd_pcm_new);
760 770
771/**
772 * snd_pcm_new_internal - create a new internal PCM instance
773 * @card: the card instance
774 * @id: the id string
775 * @device: the device index (zero based - shared with normal PCMs)
776 * @playback_count: the number of substreams for playback
777 * @capture_count: the number of substreams for capture
778 * @rpcm: the pointer to store the new pcm instance
779 *
780 * Creates a new internal PCM instance with no userspace device or procfs
781 * entries. This is used by ASoC Back End PCMs in order to create a PCM that
782 * will only be used internally by kernel drivers. i.e. it cannot be opened
783 * by userspace. It provides existing ASoC components drivers with a substream
784 * and access to any private data.
785 *
786 * The pcm operators have to be set afterwards to the new instance
787 * via snd_pcm_set_ops().
788 *
789 * Returns zero if successful, or a negative error code on failure.
790 */
791int snd_pcm_new_internal(struct snd_card *card, const char *id, int device,
792 int playback_count, int capture_count,
793 struct snd_pcm **rpcm)
794{
795 return _snd_pcm_new(card, id, device, playback_count, capture_count,
796 true, rpcm);
797}
798EXPORT_SYMBOL(snd_pcm_new_internal);
799
761static void snd_pcm_free_stream(struct snd_pcm_str * pstr) 800static void snd_pcm_free_stream(struct snd_pcm_str * pstr)
762{ 801{
763 struct snd_pcm_substream *substream, *substream_next; 802 struct snd_pcm_substream *substream, *substream_next;
@@ -994,7 +1033,7 @@ static int snd_pcm_dev_register(struct snd_device *device)
994 } 1033 }
995 for (cidx = 0; cidx < 2; cidx++) { 1034 for (cidx = 0; cidx < 2; cidx++) {
996 int devtype = -1; 1035 int devtype = -1;
997 if (pcm->streams[cidx].substream == NULL) 1036 if (pcm->streams[cidx].substream == NULL || pcm->internal)
998 continue; 1037 continue;
999 switch (cidx) { 1038 switch (cidx) {
1000 case SNDRV_PCM_STREAM_PLAYBACK: 1039 case SNDRV_PCM_STREAM_PLAYBACK: