aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_codec.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2008-07-30 09:01:44 -0400
committerTakashi Iwai <tiwai@suse.de>2008-10-12 20:42:58 -0400
commit176d5335fe66f379a339b0ab99cc7566e90ff1a9 (patch)
tree00f294bebf1270f65fe527141d3e6c1f440bba36 /sound/pci/hda/hda_codec.c
parent687cb98e893f492932abb3e92660d7d828bd44fb (diff)
ALSA: hda - Add infrastructure for dynamic stream allocation
Added the infrastructure for dynamic stream allocation on HD-audio. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r--sound/pci/hda/hda_codec.c74
1 files changed, 66 insertions, 8 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 6447754ae56e..19b4530e3baf 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -2262,6 +2262,28 @@ static int __devinit set_pcm_default_values(struct hda_codec *codec,
2262 return 0; 2262 return 0;
2263} 2263}
2264 2264
2265/*
2266 * attach a new PCM stream
2267 */
2268static int __devinit
2269snd_hda_attach_pcm(struct hda_codec *codec, struct hda_pcm *pcm)
2270{
2271 struct hda_pcm_stream *info;
2272 int stream, err;
2273
2274 if (!pcm->name)
2275 return -EINVAL;
2276 for (stream = 0; stream < 2; stream++) {
2277 info = &pcm->stream[stream];
2278 if (info->substreams) {
2279 err = set_pcm_default_values(codec, info);
2280 if (err < 0)
2281 return err;
2282 }
2283 }
2284 return codec->bus->ops.attach_pcm(codec, pcm);
2285}
2286
2265/** 2287/**
2266 * snd_hda_build_pcms - build PCM information 2288 * snd_hda_build_pcms - build PCM information
2267 * @bus: the BUS 2289 * @bus: the BUS
@@ -2290,10 +2312,24 @@ static int __devinit set_pcm_default_values(struct hda_codec *codec,
2290 */ 2312 */
2291int __devinit snd_hda_build_pcms(struct hda_bus *bus) 2313int __devinit snd_hda_build_pcms(struct hda_bus *bus)
2292{ 2314{
2315 static const char *dev_name[HDA_PCM_NTYPES] = {
2316 "Audio", "SPDIF", "HDMI", "Modem"
2317 };
2318 /* starting device index for each PCM type */
2319 static int dev_idx[HDA_PCM_NTYPES] = {
2320 [HDA_PCM_TYPE_AUDIO] = 0,
2321 [HDA_PCM_TYPE_SPDIF] = 1,
2322 [HDA_PCM_TYPE_HDMI] = 3,
2323 [HDA_PCM_TYPE_MODEM] = 6
2324 };
2325 /* normal audio device indices; not linear to keep compatibility */
2326 static int audio_idx[4] = { 0, 2, 4, 5 };
2293 struct hda_codec *codec; 2327 struct hda_codec *codec;
2328 int num_devs[HDA_PCM_NTYPES];
2294 2329
2330 memset(num_devs, 0, sizeof(num_devs));
2295 list_for_each_entry(codec, &bus->codec_list, list) { 2331 list_for_each_entry(codec, &bus->codec_list, list) {
2296 unsigned int pcm, s; 2332 unsigned int pcm;
2297 int err; 2333 int err;
2298 if (!codec->patch_ops.build_pcms) 2334 if (!codec->patch_ops.build_pcms)
2299 continue; 2335 continue;
@@ -2301,15 +2337,37 @@ int __devinit snd_hda_build_pcms(struct hda_bus *bus)
2301 if (err < 0) 2337 if (err < 0)
2302 return err; 2338 return err;
2303 for (pcm = 0; pcm < codec->num_pcms; pcm++) { 2339 for (pcm = 0; pcm < codec->num_pcms; pcm++) {
2304 for (s = 0; s < 2; s++) { 2340 struct hda_pcm *cpcm = &codec->pcm_info[pcm];
2305 struct hda_pcm_stream *info; 2341 int type = cpcm->pcm_type;
2306 info = &codec->pcm_info[pcm].stream[s]; 2342 switch (type) {
2307 if (!info->substreams) 2343 case HDA_PCM_TYPE_AUDIO:
2344 if (num_devs[type] >= ARRAY_SIZE(audio_idx)) {
2345 snd_printk(KERN_WARNING
2346 "Too many audio devices\n");
2347 continue;
2348 }
2349 cpcm->device = audio_idx[num_devs[type]];
2350 break;
2351 case HDA_PCM_TYPE_SPDIF:
2352 case HDA_PCM_TYPE_HDMI:
2353 case HDA_PCM_TYPE_MODEM:
2354 if (num_devs[type]) {
2355 snd_printk(KERN_WARNING
2356 "%s already defined\n",
2357 dev_name[type]);
2308 continue; 2358 continue;
2309 err = set_pcm_default_values(codec, info); 2359 }
2310 if (err < 0) 2360 cpcm->device = dev_idx[type];
2311 return err; 2361 break;
2362 default:
2363 snd_printk(KERN_WARNING
2364 "Invalid PCM type %d\n", type);
2365 continue;
2312 } 2366 }
2367 num_devs[type]++;
2368 err = snd_hda_attach_pcm(codec, cpcm);
2369 if (err < 0)
2370 return err;
2313 } 2371 }
2314 } 2372 }
2315 return 0; 2373 return 0;