aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_codec.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r--sound/pci/hda/hda_codec.c147
1 files changed, 100 insertions, 47 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index bc3ed249b0f..5b54ac07fcb 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -344,7 +344,7 @@ static void process_unsol_events(struct work_struct *work)
344/* 344/*
345 * initialize unsolicited queue 345 * initialize unsolicited queue
346 */ 346 */
347static int __devinit init_unsol_queue(struct hda_bus *bus) 347static int init_unsol_queue(struct hda_bus *bus)
348{ 348{
349 struct hda_bus_unsolicited *unsol; 349 struct hda_bus_unsolicited *unsol;
350 350
@@ -454,7 +454,7 @@ int __devinit snd_hda_bus_new(struct snd_card *card,
454/* 454/*
455 * find a matching codec preset 455 * find a matching codec preset
456 */ 456 */
457static const struct hda_codec_preset __devinit * 457static const struct hda_codec_preset *
458find_codec_preset(struct hda_codec *codec) 458find_codec_preset(struct hda_codec *codec)
459{ 459{
460 const struct hda_codec_preset **tbl, *preset; 460 const struct hda_codec_preset **tbl, *preset;
@@ -624,6 +624,13 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
624 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); 624 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info));
625 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); 625 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
626 snd_array_init(&codec->mixers, sizeof(struct snd_kcontrol *), 32); 626 snd_array_init(&codec->mixers, sizeof(struct snd_kcontrol *), 32);
627 if (codec->bus->modelname) {
628 codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL);
629 if (!codec->modelname) {
630 snd_hda_codec_free(codec);
631 return -ENODEV;
632 }
633 }
627 634
628#ifdef CONFIG_SND_HDA_POWER_SAVE 635#ifdef CONFIG_SND_HDA_POWER_SAVE
629 INIT_DELAYED_WORK(&codec->power_work, hda_power_work); 636 INIT_DELAYED_WORK(&codec->power_work, hda_power_work);
@@ -672,6 +679,30 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
672 if (bus->modelname) 679 if (bus->modelname)
673 codec->modelname = kstrdup(bus->modelname, GFP_KERNEL); 680 codec->modelname = kstrdup(bus->modelname, GFP_KERNEL);
674 681
682 err = snd_hda_codec_configure(codec);
683 if (err < 0) {
684 snd_hda_codec_free(codec);
685 return err;
686 }
687 snd_hda_codec_proc_new(codec);
688
689#ifdef CONFIG_SND_HDA_HWDEP
690 snd_hda_create_hwdep(codec);
691#endif
692
693 sprintf(component, "HDA:%08x,%08x,%08x", codec->vendor_id,
694 codec->subsystem_id, codec->revision_id);
695 snd_component_add(codec->bus->card, component);
696
697 if (codecp)
698 *codecp = codec;
699 return 0;
700}
701
702int snd_hda_codec_configure(struct hda_codec *codec)
703{
704 int err;
705
675 codec->preset = find_codec_preset(codec); 706 codec->preset = find_codec_preset(codec);
676 if (!codec->name) { 707 if (!codec->name) {
677 err = get_codec_name(codec); 708 err = get_codec_name(codec);
@@ -698,25 +729,9 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
698 printk(KERN_ERR "hda-codec: No codec parser is available\n"); 729 printk(KERN_ERR "hda-codec: No codec parser is available\n");
699 730
700 patched: 731 patched:
701 if (err < 0) { 732 if (!err && codec->patch_ops.unsol_event)
702 snd_hda_codec_free(codec); 733 err = init_unsol_queue(codec->bus);
703 return err; 734 return err;
704 }
705
706 if (codec->patch_ops.unsol_event)
707 init_unsol_queue(bus);
708
709 snd_hda_codec_proc_new(codec);
710#ifdef CONFIG_SND_HDA_HWDEP
711 snd_hda_create_hwdep(codec);
712#endif
713
714 sprintf(component, "HDA:%08x,%08x,%08x", codec->vendor_id, codec->subsystem_id, codec->revision_id);
715 snd_component_add(codec->bus->card, component);
716
717 if (codecp)
718 *codecp = codec;
719 return 0;
720} 735}
721 736
722/** 737/**
@@ -1118,6 +1133,31 @@ void snd_hda_ctls_clear(struct hda_codec *codec)
1118 snd_array_free(&codec->mixers); 1133 snd_array_free(&codec->mixers);
1119} 1134}
1120 1135
1136void snd_hda_codec_reset(struct hda_codec *codec)
1137{
1138 int i;
1139
1140#ifdef CONFIG_SND_HDA_POWER_SAVE
1141 cancel_delayed_work(&codec->power_work);
1142 flush_scheduled_work();
1143#endif
1144 snd_hda_ctls_clear(codec);
1145 /* relase PCMs */
1146 for (i = 0; i < codec->num_pcms; i++) {
1147 if (codec->pcm_info[i].pcm)
1148 snd_device_free(codec->bus->card,
1149 codec->pcm_info[i].pcm);
1150 }
1151 if (codec->patch_ops.free)
1152 codec->patch_ops.free(codec);
1153 codec->spec = NULL;
1154 free_hda_cache(&codec->amp_cache);
1155 free_hda_cache(&codec->cmd_cache);
1156 codec->num_pcms = 0;
1157 codec->pcm_info = NULL;
1158 codec->preset = NULL;
1159}
1160
1121/* create a virtual master control and add slaves */ 1161/* create a virtual master control and add slaves */
1122int snd_hda_add_vmaster(struct hda_codec *codec, char *name, 1162int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
1123 unsigned int *tlv, const char **slaves) 1163 unsigned int *tlv, const char **slaves)
@@ -1939,23 +1979,30 @@ int __devinit snd_hda_build_controls(struct hda_bus *bus)
1939 struct hda_codec *codec; 1979 struct hda_codec *codec;
1940 1980
1941 list_for_each_entry(codec, &bus->codec_list, list) { 1981 list_for_each_entry(codec, &bus->codec_list, list) {
1942 int err = 0; 1982 int err = snd_hda_codec_build_controls(codec);
1943 /* fake as if already powered-on */
1944 hda_keep_power_on(codec);
1945 /* then fire up */
1946 hda_set_power_state(codec,
1947 codec->afg ? codec->afg : codec->mfg,
1948 AC_PWRST_D0);
1949 /* continue to initialize... */
1950 if (codec->patch_ops.init)
1951 err = codec->patch_ops.init(codec);
1952 if (!err && codec->patch_ops.build_controls)
1953 err = codec->patch_ops.build_controls(codec);
1954 snd_hda_power_down(codec);
1955 if (err < 0) 1983 if (err < 0)
1956 return err; 1984 return err;
1957 } 1985 }
1986 return 0;
1987}
1958 1988
1989int snd_hda_codec_build_controls(struct hda_codec *codec)
1990{
1991 int err = 0;
1992 /* fake as if already powered-on */
1993 hda_keep_power_on(codec);
1994 /* then fire up */
1995 hda_set_power_state(codec,
1996 codec->afg ? codec->afg : codec->mfg,
1997 AC_PWRST_D0);
1998 /* continue to initialize... */
1999 if (codec->patch_ops.init)
2000 err = codec->patch_ops.init(codec);
2001 if (!err && codec->patch_ops.build_controls)
2002 err = codec->patch_ops.build_controls(codec);
2003 snd_hda_power_down(codec);
2004 if (err < 0)
2005 return err;
1959 return 0; 2006 return 0;
1960} 2007}
1961 2008
@@ -2256,8 +2303,8 @@ static int hda_pcm_default_cleanup(struct hda_pcm_stream *hinfo,
2256 return 0; 2303 return 0;
2257} 2304}
2258 2305
2259static int __devinit set_pcm_default_values(struct hda_codec *codec, 2306static int set_pcm_default_values(struct hda_codec *codec,
2260 struct hda_pcm_stream *info) 2307 struct hda_pcm_stream *info)
2261{ 2308{
2262 /* query support PCM information from the given NID */ 2309 /* query support PCM information from the given NID */
2263 if (info->nid && (!info->rates || !info->formats)) { 2310 if (info->nid && (!info->rates || !info->formats)) {
@@ -2331,7 +2378,7 @@ snd_hda_attach_pcm(struct hda_codec *codec, struct hda_pcm *pcm)
2331 * 2378 *
2332 * This function returns 0 if successfull, or a negative error code. 2379 * This function returns 0 if successfull, or a negative error code.
2333 */ 2380 */
2334int __devinit snd_hda_build_pcms(struct hda_bus *bus) 2381int snd_hda_build_pcms(struct hda_bus *bus)
2335{ 2382{
2336 static const char *dev_name[HDA_PCM_NTYPES] = { 2383 static const char *dev_name[HDA_PCM_NTYPES] = {
2337 "Audio", "SPDIF", "HDMI", "Modem" 2384 "Audio", "SPDIF", "HDMI", "Modem"
@@ -2352,14 +2399,17 @@ int __devinit snd_hda_build_pcms(struct hda_bus *bus)
2352 list_for_each_entry(codec, &bus->codec_list, list) { 2399 list_for_each_entry(codec, &bus->codec_list, list) {
2353 unsigned int pcm; 2400 unsigned int pcm;
2354 int err; 2401 int err;
2355 if (!codec->patch_ops.build_pcms) 2402 if (!codec->num_pcms) {
2356 continue; 2403 if (!codec->patch_ops.build_pcms)
2357 err = codec->patch_ops.build_pcms(codec); 2404 continue;
2358 if (err < 0) 2405 err = codec->patch_ops.build_pcms(codec);
2359 return err; 2406 if (err < 0)
2407 return err;
2408 }
2360 for (pcm = 0; pcm < codec->num_pcms; pcm++) { 2409 for (pcm = 0; pcm < codec->num_pcms; pcm++) {
2361 struct hda_pcm *cpcm = &codec->pcm_info[pcm]; 2410 struct hda_pcm *cpcm = &codec->pcm_info[pcm];
2362 int type = cpcm->pcm_type; 2411 int type = cpcm->pcm_type;
2412 int dev;
2363 switch (type) { 2413 switch (type) {
2364 case HDA_PCM_TYPE_AUDIO: 2414 case HDA_PCM_TYPE_AUDIO:
2365 if (num_devs[type] >= ARRAY_SIZE(audio_idx)) { 2415 if (num_devs[type] >= ARRAY_SIZE(audio_idx)) {
@@ -2367,7 +2417,7 @@ int __devinit snd_hda_build_pcms(struct hda_bus *bus)
2367 "Too many audio devices\n"); 2417 "Too many audio devices\n");
2368 continue; 2418 continue;
2369 } 2419 }
2370 cpcm->device = audio_idx[num_devs[type]]; 2420 dev = audio_idx[num_devs[type]];
2371 break; 2421 break;
2372 case HDA_PCM_TYPE_SPDIF: 2422 case HDA_PCM_TYPE_SPDIF:
2373 case HDA_PCM_TYPE_HDMI: 2423 case HDA_PCM_TYPE_HDMI:
@@ -2378,7 +2428,7 @@ int __devinit snd_hda_build_pcms(struct hda_bus *bus)
2378 dev_name[type]); 2428 dev_name[type]);
2379 continue; 2429 continue;
2380 } 2430 }
2381 cpcm->device = dev_idx[type]; 2431 dev = dev_idx[type];
2382 break; 2432 break;
2383 default: 2433 default:
2384 snd_printk(KERN_WARNING 2434 snd_printk(KERN_WARNING
@@ -2386,9 +2436,12 @@ int __devinit snd_hda_build_pcms(struct hda_bus *bus)
2386 continue; 2436 continue;
2387 } 2437 }
2388 num_devs[type]++; 2438 num_devs[type]++;
2389 err = snd_hda_attach_pcm(codec, cpcm); 2439 if (!cpcm->pcm) {
2390 if (err < 0) 2440 cpcm->device = dev;
2391 return err; 2441 err = snd_hda_attach_pcm(codec, cpcm);
2442 if (err < 0)
2443 return err;
2444 }
2392 } 2445 }
2393 } 2446 }
2394 return 0; 2447 return 0;