|
@@ -673,6 +673,8 @@ static inline int snd_pcm_substream_proc_init(struct snd_pcm_substream *substrea
|
|
|
static inline int snd_pcm_substream_proc_done(struct snd_pcm_substream *substream) { return 0; }
|
|
|
#endif /* CONFIG_SND_VERBOSE_PROCFS */
|
|
|
|
|
|
+static const struct attribute_group *pcm_dev_attr_groups[];
|
|
|
+
|
|
|
/**
|
|
|
* snd_pcm_new_stream - create a new PCM stream
|
|
|
* @pcm: the pcm instance
|
|
@@ -698,7 +700,15 @@ 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 && !pcm->internal) {
|
|
|
+ if (!substream_count)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ snd_device_initialize(&pstr->dev, pcm->card);
|
|
|
+ pstr->dev.groups = pcm_dev_attr_groups;
|
|
|
+ dev_set_name(&pstr->dev, "pcmC%iD%i%c", pcm->card->number, pcm->device,
|
|
|
+ stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c');
|
|
|
+
|
|
|
+ if (!pcm->internal) {
|
|
|
err = snd_pcm_stream_proc_init(pstr);
|
|
|
if (err < 0) {
|
|
|
pcm_err(pcm, "Error in snd_pcm_stream_proc_init\n");
|
|
@@ -868,6 +878,8 @@ static void snd_pcm_free_stream(struct snd_pcm_str * pstr)
|
|
|
kfree(setup);
|
|
|
}
|
|
|
#endif
|
|
|
+ if (pstr->substream_count)
|
|
|
+ put_device(&pstr->dev);
|
|
|
}
|
|
|
|
|
|
static int snd_pcm_free(struct snd_pcm *pcm)
|
|
@@ -1069,9 +1081,7 @@ static int snd_pcm_dev_register(struct snd_device *device)
|
|
|
int cidx, err;
|
|
|
struct snd_pcm_substream *substream;
|
|
|
struct snd_pcm_notify *notify;
|
|
|
- char str[16];
|
|
|
struct snd_pcm *pcm;
|
|
|
- struct device *dev;
|
|
|
|
|
|
if (snd_BUG_ON(!device || !device->device_data))
|
|
|
return -ENXIO;
|
|
@@ -1088,42 +1098,24 @@ static int snd_pcm_dev_register(struct snd_device *device)
|
|
|
continue;
|
|
|
switch (cidx) {
|
|
|
case SNDRV_PCM_STREAM_PLAYBACK:
|
|
|
- sprintf(str, "pcmC%iD%ip", pcm->card->number, pcm->device);
|
|
|
devtype = SNDRV_DEVICE_TYPE_PCM_PLAYBACK;
|
|
|
break;
|
|
|
case SNDRV_PCM_STREAM_CAPTURE:
|
|
|
- sprintf(str, "pcmC%iD%ic", pcm->card->number, pcm->device);
|
|
|
devtype = SNDRV_DEVICE_TYPE_PCM_CAPTURE;
|
|
|
break;
|
|
|
}
|
|
|
- /* device pointer to use, pcm->dev takes precedence if
|
|
|
- * it is assigned, otherwise fall back to card's device
|
|
|
- * if possible */
|
|
|
- dev = pcm->dev;
|
|
|
- if (!dev)
|
|
|
- dev = snd_card_get_device_link(pcm->card);
|
|
|
/* register pcm */
|
|
|
err = snd_register_device_for_dev(devtype, pcm->card,
|
|
|
pcm->device,
|
|
|
&snd_pcm_f_ops[cidx],
|
|
|
- pcm, NULL, dev, str);
|
|
|
+ pcm, &pcm->streams[cidx].dev,
|
|
|
+ NULL, NULL);
|
|
|
if (err < 0) {
|
|
|
list_del(&pcm->list);
|
|
|
mutex_unlock(®ister_mutex);
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
- dev = snd_get_device(devtype, pcm->card, pcm->device);
|
|
|
- if (dev) {
|
|
|
- err = sysfs_create_groups(&dev->kobj,
|
|
|
- pcm_dev_attr_groups);
|
|
|
- if (err < 0)
|
|
|
- dev_warn(dev,
|
|
|
- "pcm %d:%d: cannot create sysfs groups\n",
|
|
|
- pcm->card->number, pcm->device);
|
|
|
- put_device(dev);
|
|
|
- }
|
|
|
-
|
|
|
for (substream = pcm->streams[cidx].substream; substream; substream = substream->next)
|
|
|
snd_pcm_timer_init(substream);
|
|
|
}
|