Commit 6d70934a authored by Mark Brown's avatar Mark Brown

Merge branch 'topic/pcm-internal' of...

Merge branch 'topic/pcm-internal' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound into for-3.4
parents 17c0cee9 945e5038
...@@ -454,6 +454,7 @@ struct snd_pcm { ...@@ -454,6 +454,7 @@ struct snd_pcm {
void *private_data; void *private_data;
void (*private_free) (struct snd_pcm *pcm); void (*private_free) (struct snd_pcm *pcm);
struct device *dev; /* actual hw device this belongs to */ struct device *dev; /* actual hw device this belongs to */
bool internal; /* pcm is for internal use only */
#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
struct snd_pcm_oss oss; struct snd_pcm_oss oss;
#endif #endif
...@@ -475,6 +476,9 @@ extern const struct file_operations snd_pcm_f_ops[2]; ...@@ -475,6 +476,9 @@ extern const struct file_operations snd_pcm_f_ops[2];
int snd_pcm_new(struct snd_card *card, const char *id, int device, int snd_pcm_new(struct snd_card *card, const char *id, int device,
int playback_count, int capture_count, int playback_count, int capture_count,
struct snd_pcm **rpcm); struct snd_pcm **rpcm);
int snd_pcm_new_internal(struct snd_card *card, const char *id, int device,
int playback_count, int capture_count,
struct snd_pcm **rpcm);
int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count); int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count);
int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree); int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree);
......
...@@ -650,7 +650,7 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count) ...@@ -650,7 +650,7 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
pstr->stream = stream; pstr->stream = stream;
pstr->pcm = pcm; pstr->pcm = pcm;
pstr->substream_count = substream_count; pstr->substream_count = substream_count;
if (substream_count > 0) { if (substream_count > 0 && !pcm->internal) {
err = snd_pcm_stream_proc_init(pstr); err = snd_pcm_stream_proc_init(pstr);
if (err < 0) { if (err < 0) {
snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n"); 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,15 +674,18 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
pstr->substream = substream; pstr->substream = substream;
else else
prev->next = substream; prev->next = substream;
err = snd_pcm_substream_proc_init(substream);
if (err < 0) { if (!pcm->internal) {
snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n"); err = snd_pcm_substream_proc_init(substream);
if (prev == NULL) if (err < 0) {
pstr->substream = NULL; snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");
else if (prev == NULL)
prev->next = NULL; pstr->substream = NULL;
kfree(substream); else
return err; prev->next = NULL;
kfree(substream);
return err;
}
} }
substream->group = &substream->self_group; substream->group = &substream->self_group;
spin_lock_init(&substream->self_group.lock); 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,25 +699,9 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
EXPORT_SYMBOL(snd_pcm_new_stream); EXPORT_SYMBOL(snd_pcm_new_stream);
/** static int _snd_pcm_new(struct snd_card *card, const char *id, int device,
* snd_pcm_new - create a new PCM instance int playback_count, int capture_count, bool internal,
* @card: the card instance struct snd_pcm **rpcm)
* @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)
{ {
struct snd_pcm *pcm; struct snd_pcm *pcm;
int err; int err;
...@@ -735,6 +722,7 @@ int snd_pcm_new(struct snd_card *card, const char *id, int device, ...@@ -735,6 +722,7 @@ int snd_pcm_new(struct snd_card *card, const char *id, int device,
} }
pcm->card = card; pcm->card = card;
pcm->device = device; pcm->device = device;
pcm->internal = internal;
if (id) if (id)
strlcpy(pcm->id, id, sizeof(pcm->id)); strlcpy(pcm->id, id, sizeof(pcm->id));
if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, playback_count)) < 0) { 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,8 +744,59 @@ int snd_pcm_new(struct snd_card *card, const char *id, int device,
return 0; 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); 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) static void snd_pcm_free_stream(struct snd_pcm_str * pstr)
{ {
struct snd_pcm_substream *substream, *substream_next; struct snd_pcm_substream *substream, *substream_next;
...@@ -994,7 +1033,7 @@ static int snd_pcm_dev_register(struct snd_device *device) ...@@ -994,7 +1033,7 @@ static int snd_pcm_dev_register(struct snd_device *device)
} }
for (cidx = 0; cidx < 2; cidx++) { for (cidx = 0; cidx < 2; cidx++) {
int devtype = -1; int devtype = -1;
if (pcm->streams[cidx].substream == NULL) if (pcm->streams[cidx].substream == NULL || pcm->internal)
continue; continue;
switch (cidx) { switch (cidx) {
case SNDRV_PCM_STREAM_PLAYBACK: case SNDRV_PCM_STREAM_PLAYBACK:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment