|
@@ -650,7 +650,7 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
|
|
|
pstr->stream = stream;
|
|
|
pstr->pcm = pcm;
|
|
|
pstr->substream_count = substream_count;
|
|
|
- if (substream_count > 0) {
|
|
|
+ if (substream_count > 0 && !pcm->internal) {
|
|
|
err = snd_pcm_stream_proc_init(pstr);
|
|
|
if (err < 0) {
|
|
|
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)
|
|
|
pstr->substream = substream;
|
|
|
else
|
|
|
prev->next = substream;
|
|
|
- err = snd_pcm_substream_proc_init(substream);
|
|
|
- if (err < 0) {
|
|
|
- snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");
|
|
|
- if (prev == NULL)
|
|
|
- pstr->substream = NULL;
|
|
|
- else
|
|
|
- prev->next = NULL;
|
|
|
- kfree(substream);
|
|
|
- return err;
|
|
|
+
|
|
|
+ if (!pcm->internal) {
|
|
|
+ err = snd_pcm_substream_proc_init(substream);
|
|
|
+ if (err < 0) {
|
|
|
+ snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");
|
|
|
+ if (prev == NULL)
|
|
|
+ pstr->substream = NULL;
|
|
|
+ else
|
|
|
+ prev->next = NULL;
|
|
|
+ kfree(substream);
|
|
|
+ return err;
|
|
|
+ }
|
|
|
}
|
|
|
substream->group = &substream->self_group;
|
|
|
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)
|
|
|
|
|
|
EXPORT_SYMBOL(snd_pcm_new_stream);
|
|
|
|
|
|
-/**
|
|
|
- * snd_pcm_new - create a new PCM instance
|
|
|
- * @card: the card instance
|
|
|
- * @id: the id string
|
|
|
- * @device: the device index (zero based)
|
|
|
- * @playback_count: the number of substreams for playback
|
|
|
- * @capture_count: the number of substreams for capture
|
|
|
- * @rpcm: the pointer to store the new pcm instance
|
|
|
- *
|
|
|
- * Creates a new PCM instance.
|
|
|
- *
|
|
|
- * The pcm operators have to be set afterwards to the new instance
|
|
|
- * via snd_pcm_set_ops().
|
|
|
- *
|
|
|
- * Returns zero if successful, or a negative error code on failure.
|
|
|
- */
|
|
|
-int snd_pcm_new(struct snd_card *card, const char *id, int device,
|
|
|
- int playback_count, int capture_count,
|
|
|
- struct snd_pcm ** rpcm)
|
|
|
+static int _snd_pcm_new(struct snd_card *card, const char *id, int device,
|
|
|
+ int playback_count, int capture_count, bool internal,
|
|
|
+ struct snd_pcm **rpcm)
|
|
|
{
|
|
|
struct snd_pcm *pcm;
|
|
|
int err;
|
|
@@ -735,6 +722,7 @@ int snd_pcm_new(struct snd_card *card, const char *id, int device,
|
|
|
}
|
|
|
pcm->card = card;
|
|
|
pcm->device = device;
|
|
|
+ pcm->internal = internal;
|
|
|
if (id)
|
|
|
strlcpy(pcm->id, id, sizeof(pcm->id));
|
|
|
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,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * snd_pcm_new - create a new PCM instance
|
|
|
+ * @card: the card instance
|
|
|
+ * @id: the id string
|
|
|
+ * @device: the device index (zero based)
|
|
|
+ * @playback_count: the number of substreams for playback
|
|
|
+ * @capture_count: the number of substreams for capture
|
|
|
+ * @rpcm: the pointer to store the new pcm instance
|
|
|
+ *
|
|
|
+ * Creates a new PCM instance.
|
|
|
+ *
|
|
|
+ * The pcm operators have to be set afterwards to the new instance
|
|
|
+ * via snd_pcm_set_ops().
|
|
|
+ *
|
|
|
+ * Returns zero if successful, or a negative error code on failure.
|
|
|
+ */
|
|
|
+int snd_pcm_new(struct snd_card *card, const char *id, int device,
|
|
|
+ int playback_count, int capture_count, struct snd_pcm **rpcm)
|
|
|
+{
|
|
|
+ return _snd_pcm_new(card, id, device, playback_count, capture_count,
|
|
|
+ false, rpcm);
|
|
|
+}
|
|
|
EXPORT_SYMBOL(snd_pcm_new);
|
|
|
|
|
|
+/**
|
|
|
+ * snd_pcm_new_internal - create a new internal PCM instance
|
|
|
+ * @card: the card instance
|
|
|
+ * @id: the id string
|
|
|
+ * @device: the device index (zero based - shared with normal PCMs)
|
|
|
+ * @playback_count: the number of substreams for playback
|
|
|
+ * @capture_count: the number of substreams for capture
|
|
|
+ * @rpcm: the pointer to store the new pcm instance
|
|
|
+ *
|
|
|
+ * Creates a new internal PCM instance with no userspace device or procfs
|
|
|
+ * entries. This is used by ASoC Back End PCMs in order to create a PCM that
|
|
|
+ * will only be used internally by kernel drivers. i.e. it cannot be opened
|
|
|
+ * by userspace. It provides existing ASoC components drivers with a substream
|
|
|
+ * and access to any private data.
|
|
|
+ *
|
|
|
+ * The pcm operators have to be set afterwards to the new instance
|
|
|
+ * via snd_pcm_set_ops().
|
|
|
+ *
|
|
|
+ * Returns zero if successful, or a negative error code on failure.
|
|
|
+ */
|
|
|
+int snd_pcm_new_internal(struct snd_card *card, const char *id, int device,
|
|
|
+ int playback_count, int capture_count,
|
|
|
+ struct snd_pcm **rpcm)
|
|
|
+{
|
|
|
+ return _snd_pcm_new(card, id, device, playback_count, capture_count,
|
|
|
+ true, rpcm);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(snd_pcm_new_internal);
|
|
|
+
|
|
|
static void snd_pcm_free_stream(struct snd_pcm_str * pstr)
|
|
|
{
|
|
|
struct snd_pcm_substream *substream, *substream_next;
|
|
@@ -994,7 +1033,7 @@ static int snd_pcm_dev_register(struct snd_device *device)
|
|
|
}
|
|
|
for (cidx = 0; cidx < 2; cidx++) {
|
|
|
int devtype = -1;
|
|
|
- if (pcm->streams[cidx].substream == NULL)
|
|
|
+ if (pcm->streams[cidx].substream == NULL || pcm->internal)
|
|
|
continue;
|
|
|
switch (cidx) {
|
|
|
case SNDRV_PCM_STREAM_PLAYBACK:
|