diff options
-rw-r--r-- | sound/pci/hda/hda_codec.c | 116 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.h | 18 | ||||
-rw-r--r-- | sound/pci/hda/hda_generic.c | 28 | ||||
-rw-r--r-- | sound/pci/hda/hda_generic.h | 2 | ||||
-rw-r--r-- | sound/pci/hda/hda_proc.c | 6 | ||||
-rw-r--r-- | sound/pci/hda/patch_ca0132.c | 29 | ||||
-rw-r--r-- | sound/pci/hda/patch_hdmi.c | 30 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 2 | ||||
-rw-r--r-- | sound/pci/hda/patch_si3054.c | 11 | ||||
-rw-r--r-- | sound/pci/hda/patch_via.c | 6 |
10 files changed, 145 insertions, 103 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 262c41a8f96e..20283bead10a 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -1117,6 +1117,60 @@ get_hda_cvt_setup(struct hda_codec *codec, hda_nid_t nid) | |||
1117 | } | 1117 | } |
1118 | 1118 | ||
1119 | /* | 1119 | /* |
1120 | * PCM device | ||
1121 | */ | ||
1122 | static void release_pcm(struct kref *kref) | ||
1123 | { | ||
1124 | struct hda_pcm *pcm = container_of(kref, struct hda_pcm, kref); | ||
1125 | |||
1126 | if (pcm->pcm) | ||
1127 | snd_device_free(pcm->codec->card, pcm->pcm); | ||
1128 | clear_bit(pcm->device, pcm->codec->bus->pcm_dev_bits); | ||
1129 | kfree(pcm->name); | ||
1130 | kfree(pcm); | ||
1131 | } | ||
1132 | |||
1133 | void snd_hda_codec_pcm_put(struct hda_pcm *pcm) | ||
1134 | { | ||
1135 | kref_put(&pcm->kref, release_pcm); | ||
1136 | } | ||
1137 | EXPORT_SYMBOL_GPL(snd_hda_codec_pcm_put); | ||
1138 | |||
1139 | struct hda_pcm *snd_hda_codec_pcm_new(struct hda_codec *codec, | ||
1140 | const char *fmt, ...) | ||
1141 | { | ||
1142 | struct hda_pcm *pcm; | ||
1143 | va_list args; | ||
1144 | |||
1145 | va_start(args, fmt); | ||
1146 | pcm = kzalloc(sizeof(*pcm), GFP_KERNEL); | ||
1147 | if (!pcm) | ||
1148 | return NULL; | ||
1149 | |||
1150 | pcm->codec = codec; | ||
1151 | kref_init(&pcm->kref); | ||
1152 | pcm->name = kvasprintf(GFP_KERNEL, fmt, args); | ||
1153 | if (!pcm->name) { | ||
1154 | kfree(pcm); | ||
1155 | return NULL; | ||
1156 | } | ||
1157 | |||
1158 | list_add_tail(&pcm->list, &codec->pcm_list_head); | ||
1159 | return pcm; | ||
1160 | } | ||
1161 | EXPORT_SYMBOL_GPL(snd_hda_codec_pcm_new); | ||
1162 | |||
1163 | static void codec_release_pcms(struct hda_codec *codec) | ||
1164 | { | ||
1165 | struct hda_pcm *pcm, *n; | ||
1166 | |||
1167 | list_for_each_entry_safe(pcm, n, &codec->pcm_list_head, list) { | ||
1168 | list_del_init(&pcm->list); | ||
1169 | snd_hda_codec_pcm_put(pcm); | ||
1170 | } | ||
1171 | } | ||
1172 | |||
1173 | /* | ||
1120 | * codec destructor | 1174 | * codec destructor |
1121 | */ | 1175 | */ |
1122 | static void snd_hda_codec_free(struct hda_codec *codec) | 1176 | static void snd_hda_codec_free(struct hda_codec *codec) |
@@ -1124,6 +1178,7 @@ static void snd_hda_codec_free(struct hda_codec *codec) | |||
1124 | if (!codec) | 1178 | if (!codec) |
1125 | return; | 1179 | return; |
1126 | cancel_delayed_work_sync(&codec->jackpoll_work); | 1180 | cancel_delayed_work_sync(&codec->jackpoll_work); |
1181 | codec_release_pcms(codec); | ||
1127 | if (device_is_registered(hda_codec_dev(codec))) | 1182 | if (device_is_registered(hda_codec_dev(codec))) |
1128 | device_del(hda_codec_dev(codec)); | 1183 | device_del(hda_codec_dev(codec)); |
1129 | snd_hda_jack_tbl_clear(codec); | 1184 | snd_hda_jack_tbl_clear(codec); |
@@ -1251,6 +1306,7 @@ int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card, | |||
1251 | snd_array_init(&codec->jacktbl, sizeof(struct hda_jack_tbl), 16); | 1306 | snd_array_init(&codec->jacktbl, sizeof(struct hda_jack_tbl), 16); |
1252 | snd_array_init(&codec->verbs, sizeof(struct hda_verb *), 8); | 1307 | snd_array_init(&codec->verbs, sizeof(struct hda_verb *), 8); |
1253 | INIT_LIST_HEAD(&codec->conn_list); | 1308 | INIT_LIST_HEAD(&codec->conn_list); |
1309 | INIT_LIST_HEAD(&codec->pcm_list_head); | ||
1254 | 1310 | ||
1255 | INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work); | 1311 | INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work); |
1256 | codec->depop_delay = -1; | 1312 | codec->depop_delay = -1; |
@@ -2370,9 +2426,8 @@ int snd_hda_lock_devices(struct hda_bus *bus) | |||
2370 | goto err_clear; | 2426 | goto err_clear; |
2371 | 2427 | ||
2372 | list_for_each_entry(codec, &bus->codec_list, list) { | 2428 | list_for_each_entry(codec, &bus->codec_list, list) { |
2373 | int pcm; | 2429 | struct hda_pcm *cpcm; |
2374 | for (pcm = 0; pcm < codec->num_pcms; pcm++) { | 2430 | list_for_each_entry(cpcm, &codec->pcm_list_head, list) { |
2375 | struct hda_pcm *cpcm = &codec->pcm_info[pcm]; | ||
2376 | if (!cpcm->pcm) | 2431 | if (!cpcm->pcm) |
2377 | continue; | 2432 | continue; |
2378 | if (cpcm->pcm->streams[0].substream_opened || | 2433 | if (cpcm->pcm->streams[0].substream_opened || |
@@ -2419,8 +2474,6 @@ EXPORT_SYMBOL_GPL(snd_hda_unlock_devices); | |||
2419 | int snd_hda_codec_reset(struct hda_codec *codec) | 2474 | int snd_hda_codec_reset(struct hda_codec *codec) |
2420 | { | 2475 | { |
2421 | struct hda_bus *bus = codec->bus; | 2476 | struct hda_bus *bus = codec->bus; |
2422 | struct snd_card *card = codec->card; | ||
2423 | int i; | ||
2424 | 2477 | ||
2425 | if (snd_hda_lock_devices(bus) < 0) | 2478 | if (snd_hda_lock_devices(bus) < 0) |
2426 | return -EBUSY; | 2479 | return -EBUSY; |
@@ -2429,14 +2482,7 @@ int snd_hda_codec_reset(struct hda_codec *codec) | |||
2429 | cancel_delayed_work_sync(&codec->jackpoll_work); | 2482 | cancel_delayed_work_sync(&codec->jackpoll_work); |
2430 | flush_workqueue(bus->workq); | 2483 | flush_workqueue(bus->workq); |
2431 | snd_hda_ctls_clear(codec); | 2484 | snd_hda_ctls_clear(codec); |
2432 | /* release PCMs */ | 2485 | codec_release_pcms(codec); |
2433 | for (i = 0; i < codec->num_pcms; i++) { | ||
2434 | if (codec->pcm_info[i].pcm) { | ||
2435 | snd_device_free(card, codec->pcm_info[i].pcm); | ||
2436 | clear_bit(codec->pcm_info[i].device, | ||
2437 | bus->pcm_dev_bits); | ||
2438 | } | ||
2439 | } | ||
2440 | snd_hda_detach_beep_device(codec); | 2486 | snd_hda_detach_beep_device(codec); |
2441 | if (device_is_registered(hda_codec_dev(codec))) | 2487 | if (device_is_registered(hda_codec_dev(codec))) |
2442 | device_del(hda_codec_dev(codec)); | 2488 | device_del(hda_codec_dev(codec)); |
@@ -2454,8 +2500,6 @@ int snd_hda_codec_reset(struct hda_codec *codec) | |||
2454 | snd_array_free(&codec->cvt_setups); | 2500 | snd_array_free(&codec->cvt_setups); |
2455 | snd_array_free(&codec->spdif_out); | 2501 | snd_array_free(&codec->spdif_out); |
2456 | snd_array_free(&codec->verbs); | 2502 | snd_array_free(&codec->verbs); |
2457 | codec->num_pcms = 0; | ||
2458 | codec->pcm_info = NULL; | ||
2459 | codec->preset = NULL; | 2503 | codec->preset = NULL; |
2460 | codec->slave_dig_outs = NULL; | 2504 | codec->slave_dig_outs = NULL; |
2461 | codec->spdif_status_reset = 0; | 2505 | codec->spdif_status_reset = 0; |
@@ -3952,12 +3996,12 @@ static void hda_call_codec_resume(struct hda_codec *codec) | |||
3952 | static int hda_codec_runtime_suspend(struct device *dev) | 3996 | static int hda_codec_runtime_suspend(struct device *dev) |
3953 | { | 3997 | { |
3954 | struct hda_codec *codec = dev_to_hda_codec(dev); | 3998 | struct hda_codec *codec = dev_to_hda_codec(dev); |
3999 | struct hda_pcm *pcm; | ||
3955 | unsigned int state; | 4000 | unsigned int state; |
3956 | int i; | ||
3957 | 4001 | ||
3958 | cancel_delayed_work_sync(&codec->jackpoll_work); | 4002 | cancel_delayed_work_sync(&codec->jackpoll_work); |
3959 | for (i = 0; i < codec->num_pcms; i++) | 4003 | list_for_each_entry(pcm, &codec->pcm_list_head, list) |
3960 | snd_pcm_suspend_all(codec->pcm_info[i].pcm); | 4004 | snd_pcm_suspend_all(pcm->pcm); |
3961 | state = hda_call_codec_suspend(codec); | 4005 | state = hda_call_codec_suspend(codec); |
3962 | if (codec->d3_stop_clk && codec->epss && (state & AC_PWRST_CLK_STOP_OK)) | 4006 | if (codec->d3_stop_clk && codec->epss && (state & AC_PWRST_CLK_STOP_OK)) |
3963 | clear_bit(codec->addr, &codec->bus->codec_powered); | 4007 | clear_bit(codec->addr, &codec->bus->codec_powered); |
@@ -4018,22 +4062,21 @@ EXPORT_SYMBOL_GPL(snd_hda_build_controls); | |||
4018 | */ | 4062 | */ |
4019 | static int add_std_chmaps(struct hda_codec *codec) | 4063 | static int add_std_chmaps(struct hda_codec *codec) |
4020 | { | 4064 | { |
4021 | int i, str, err; | 4065 | struct hda_pcm *pcm; |
4066 | int str, err; | ||
4022 | 4067 | ||
4023 | for (i = 0; i < codec->num_pcms; i++) { | 4068 | list_for_each_entry(pcm, &codec->pcm_list_head, list) { |
4024 | for (str = 0; str < 2; str++) { | 4069 | for (str = 0; str < 2; str++) { |
4025 | struct snd_pcm *pcm = codec->pcm_info[i].pcm; | 4070 | struct hda_pcm_stream *hinfo = &pcm->stream[str]; |
4026 | struct hda_pcm_stream *hinfo = | ||
4027 | &codec->pcm_info[i].stream[str]; | ||
4028 | struct snd_pcm_chmap *chmap; | 4071 | struct snd_pcm_chmap *chmap; |
4029 | const struct snd_pcm_chmap_elem *elem; | 4072 | const struct snd_pcm_chmap_elem *elem; |
4030 | 4073 | ||
4031 | if (codec->pcm_info[i].own_chmap) | 4074 | if (pcm->own_chmap) |
4032 | continue; | 4075 | continue; |
4033 | if (!pcm || !hinfo->substreams) | 4076 | if (!pcm || !hinfo->substreams) |
4034 | continue; | 4077 | continue; |
4035 | elem = hinfo->chmap ? hinfo->chmap : snd_pcm_std_chmaps; | 4078 | elem = hinfo->chmap ? hinfo->chmap : snd_pcm_std_chmaps; |
4036 | err = snd_pcm_add_chmap_ctls(pcm, str, elem, | 4079 | err = snd_pcm_add_chmap_ctls(pcm->pcm, str, elem, |
4037 | hinfo->channels_max, | 4080 | hinfo->channels_max, |
4038 | 0, &chmap); | 4081 | 0, &chmap); |
4039 | if (err < 0) | 4082 | if (err < 0) |
@@ -4564,10 +4607,10 @@ static int get_empty_pcm_device(struct hda_bus *bus, unsigned int type) | |||
4564 | /* call build_pcms ops of the given codec and set up the default parameters */ | 4607 | /* call build_pcms ops of the given codec and set up the default parameters */ |
4565 | int snd_hda_codec_parse_pcms(struct hda_codec *codec) | 4608 | int snd_hda_codec_parse_pcms(struct hda_codec *codec) |
4566 | { | 4609 | { |
4567 | unsigned int pcm; | 4610 | struct hda_pcm *cpcm; |
4568 | int err; | 4611 | int err; |
4569 | 4612 | ||
4570 | if (codec->num_pcms) | 4613 | if (!list_empty(&codec->pcm_list_head)) |
4571 | return 0; /* already parsed */ | 4614 | return 0; /* already parsed */ |
4572 | 4615 | ||
4573 | if (!codec->patch_ops.build_pcms) | 4616 | if (!codec->patch_ops.build_pcms) |
@@ -4580,8 +4623,7 @@ int snd_hda_codec_parse_pcms(struct hda_codec *codec) | |||
4580 | return err; | 4623 | return err; |
4581 | } | 4624 | } |
4582 | 4625 | ||
4583 | for (pcm = 0; pcm < codec->num_pcms; pcm++) { | 4626 | list_for_each_entry(cpcm, &codec->pcm_list_head, list) { |
4584 | struct hda_pcm *cpcm = &codec->pcm_info[pcm]; | ||
4585 | int stream; | 4627 | int stream; |
4586 | 4628 | ||
4587 | for (stream = 0; stream < 2; stream++) { | 4629 | for (stream = 0; stream < 2; stream++) { |
@@ -4589,8 +4631,6 @@ int snd_hda_codec_parse_pcms(struct hda_codec *codec) | |||
4589 | 4631 | ||
4590 | if (!info->substreams) | 4632 | if (!info->substreams) |
4591 | continue; | 4633 | continue; |
4592 | if (snd_BUG_ON(!cpcm->name)) | ||
4593 | return -EINVAL; | ||
4594 | err = set_pcm_default_values(codec, info); | 4634 | err = set_pcm_default_values(codec, info); |
4595 | if (err < 0) { | 4635 | if (err < 0) { |
4596 | codec_warn(codec, | 4636 | codec_warn(codec, |
@@ -4608,7 +4648,7 @@ int snd_hda_codec_parse_pcms(struct hda_codec *codec) | |||
4608 | int snd_hda_codec_build_pcms(struct hda_codec *codec) | 4648 | int snd_hda_codec_build_pcms(struct hda_codec *codec) |
4609 | { | 4649 | { |
4610 | struct hda_bus *bus = codec->bus; | 4650 | struct hda_bus *bus = codec->bus; |
4611 | unsigned int pcm; | 4651 | struct hda_pcm *cpcm; |
4612 | int dev, err; | 4652 | int dev, err; |
4613 | 4653 | ||
4614 | if (snd_BUG_ON(!bus->ops.attach_pcm)) | 4654 | if (snd_BUG_ON(!bus->ops.attach_pcm)) |
@@ -4621,9 +4661,7 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec) | |||
4621 | } | 4661 | } |
4622 | 4662 | ||
4623 | /* attach a new PCM streams */ | 4663 | /* attach a new PCM streams */ |
4624 | for (pcm = 0; pcm < codec->num_pcms; pcm++) { | 4664 | list_for_each_entry(cpcm, &codec->pcm_list_head, list) { |
4625 | struct hda_pcm *cpcm = &codec->pcm_info[pcm]; | ||
4626 | |||
4627 | if (cpcm->pcm) | 4665 | if (cpcm->pcm) |
4628 | continue; /* already attached */ | 4666 | continue; /* already attached */ |
4629 | if (!cpcm->stream[0].substreams && !cpcm->stream[1].substreams) | 4667 | if (!cpcm->stream[0].substreams && !cpcm->stream[1].substreams) |
@@ -4651,11 +4689,9 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec) | |||
4651 | * | 4689 | * |
4652 | * Create PCM information for each codec included in the bus. | 4690 | * Create PCM information for each codec included in the bus. |
4653 | * | 4691 | * |
4654 | * The build_pcms codec patch is requested to set up codec->num_pcms and | 4692 | * The build_pcms codec patch is requested to create and assign new |
4655 | * codec->pcm_info properly. The array is referred by the top-level driver | 4693 | * hda_pcm objects. The codec is responsible to call snd_hda_codec_pcm_new() |
4656 | * to create its PCM instances. | 4694 | * and fills the fields. Later they are instantiated by this function. |
4657 | * The allocated codec->pcm_info should be released in codec->patch_ops.free | ||
4658 | * callback. | ||
4659 | * | 4695 | * |
4660 | * At least, substreams, channels_min and channels_max must be filled for | 4696 | * At least, substreams, channels_min and channels_max must be filled for |
4661 | * each stream. substreams = 0 indicates that the stream doesn't exist. | 4697 | * each stream. substreams = 0 indicates that the stream doesn't exist. |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 8908a0768736..2ccd6f9a91fe 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #ifndef __SOUND_HDA_CODEC_H | 21 | #ifndef __SOUND_HDA_CODEC_H |
22 | #define __SOUND_HDA_CODEC_H | 22 | #define __SOUND_HDA_CODEC_H |
23 | 23 | ||
24 | #include <linux/kref.h> | ||
24 | #include <sound/info.h> | 25 | #include <sound/info.h> |
25 | #include <sound/control.h> | 26 | #include <sound/control.h> |
26 | #include <sound/pcm.h> | 27 | #include <sound/pcm.h> |
@@ -268,6 +269,10 @@ struct hda_pcm { | |||
268 | int device; /* device number to assign */ | 269 | int device; /* device number to assign */ |
269 | struct snd_pcm *pcm; /* assigned PCM instance */ | 270 | struct snd_pcm *pcm; /* assigned PCM instance */ |
270 | bool own_chmap; /* codec driver provides own channel maps */ | 271 | bool own_chmap; /* codec driver provides own channel maps */ |
272 | /* private: */ | ||
273 | struct hda_codec *codec; | ||
274 | struct kref kref; | ||
275 | struct list_head list; | ||
271 | }; | 276 | }; |
272 | 277 | ||
273 | /* codec information */ | 278 | /* codec information */ |
@@ -301,8 +306,7 @@ struct hda_codec { | |||
301 | struct hda_codec_ops patch_ops; | 306 | struct hda_codec_ops patch_ops; |
302 | 307 | ||
303 | /* PCM to create, set by patch_ops.build_pcms callback */ | 308 | /* PCM to create, set by patch_ops.build_pcms callback */ |
304 | unsigned int num_pcms; | 309 | struct list_head pcm_list_head; |
305 | struct hda_pcm *pcm_info; | ||
306 | 310 | ||
307 | /* codec specific info */ | 311 | /* codec specific info */ |
308 | void *spec; | 312 | void *spec; |
@@ -521,6 +525,16 @@ int snd_hda_build_pcms(struct hda_bus *bus); | |||
521 | int snd_hda_codec_parse_pcms(struct hda_codec *codec); | 525 | int snd_hda_codec_parse_pcms(struct hda_codec *codec); |
522 | int snd_hda_codec_build_pcms(struct hda_codec *codec); | 526 | int snd_hda_codec_build_pcms(struct hda_codec *codec); |
523 | 527 | ||
528 | __printf(2, 3) | ||
529 | struct hda_pcm *snd_hda_codec_pcm_new(struct hda_codec *codec, | ||
530 | const char *fmt, ...); | ||
531 | |||
532 | static inline void snd_hda_codec_pcm_get(struct hda_pcm *pcm) | ||
533 | { | ||
534 | kref_get(&pcm->kref); | ||
535 | } | ||
536 | void snd_hda_codec_pcm_put(struct hda_pcm *pcm); | ||
537 | |||
524 | int snd_hda_codec_prepare(struct hda_codec *codec, | 538 | int snd_hda_codec_prepare(struct hda_codec *codec, |
525 | struct hda_pcm_stream *hinfo, | 539 | struct hda_pcm_stream *hinfo, |
526 | unsigned int stream, | 540 | unsigned int stream, |
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 947d1a50f384..092f06fd21bd 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c | |||
@@ -4644,7 +4644,7 @@ int snd_hda_gen_build_controls(struct hda_codec *codec) | |||
4644 | err = snd_hda_create_dig_out_ctls(codec, | 4644 | err = snd_hda_create_dig_out_ctls(codec, |
4645 | spec->multiout.dig_out_nid, | 4645 | spec->multiout.dig_out_nid, |
4646 | spec->multiout.dig_out_nid, | 4646 | spec->multiout.dig_out_nid, |
4647 | spec->pcm_rec[1].pcm_type); | 4647 | spec->pcm_rec[1]->pcm_type); |
4648 | if (err < 0) | 4648 | if (err < 0) |
4649 | return err; | 4649 | return err; |
4650 | if (!spec->no_analog) { | 4650 | if (!spec->no_analog) { |
@@ -5115,20 +5115,20 @@ static void fill_pcm_stream_name(char *str, size_t len, const char *sfx, | |||
5115 | int snd_hda_gen_build_pcms(struct hda_codec *codec) | 5115 | int snd_hda_gen_build_pcms(struct hda_codec *codec) |
5116 | { | 5116 | { |
5117 | struct hda_gen_spec *spec = codec->spec; | 5117 | struct hda_gen_spec *spec = codec->spec; |
5118 | struct hda_pcm *info = spec->pcm_rec; | 5118 | struct hda_pcm *info; |
5119 | const struct hda_pcm_stream *p; | 5119 | const struct hda_pcm_stream *p; |
5120 | bool have_multi_adcs; | 5120 | bool have_multi_adcs; |
5121 | 5121 | ||
5122 | codec->num_pcms = 1; | ||
5123 | codec->pcm_info = info; | ||
5124 | |||
5125 | if (spec->no_analog) | 5122 | if (spec->no_analog) |
5126 | goto skip_analog; | 5123 | goto skip_analog; |
5127 | 5124 | ||
5128 | fill_pcm_stream_name(spec->stream_name_analog, | 5125 | fill_pcm_stream_name(spec->stream_name_analog, |
5129 | sizeof(spec->stream_name_analog), | 5126 | sizeof(spec->stream_name_analog), |
5130 | " Analog", codec->chip_name); | 5127 | " Analog", codec->chip_name); |
5131 | info->name = spec->stream_name_analog; | 5128 | info = snd_hda_codec_pcm_new(codec, "%s", spec->stream_name_analog); |
5129 | if (!info) | ||
5130 | return -ENOMEM; | ||
5131 | spec->pcm_rec[0] = info; | ||
5132 | 5132 | ||
5133 | if (spec->multiout.num_dacs > 0) { | 5133 | if (spec->multiout.num_dacs > 0) { |
5134 | p = spec->stream_analog_playback; | 5134 | p = spec->stream_analog_playback; |
@@ -5161,10 +5161,12 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec) | |||
5161 | fill_pcm_stream_name(spec->stream_name_digital, | 5161 | fill_pcm_stream_name(spec->stream_name_digital, |
5162 | sizeof(spec->stream_name_digital), | 5162 | sizeof(spec->stream_name_digital), |
5163 | " Digital", codec->chip_name); | 5163 | " Digital", codec->chip_name); |
5164 | codec->num_pcms = 2; | 5164 | info = snd_hda_codec_pcm_new(codec, "%s", |
5165 | spec->stream_name_digital); | ||
5166 | if (!info) | ||
5167 | return -ENOMEM; | ||
5165 | codec->slave_dig_outs = spec->multiout.slave_dig_outs; | 5168 | codec->slave_dig_outs = spec->multiout.slave_dig_outs; |
5166 | info = spec->pcm_rec + 1; | 5169 | spec->pcm_rec[1] = info; |
5167 | info->name = spec->stream_name_digital; | ||
5168 | if (spec->dig_out_type) | 5170 | if (spec->dig_out_type) |
5169 | info->pcm_type = spec->dig_out_type; | 5171 | info->pcm_type = spec->dig_out_type; |
5170 | else | 5172 | else |
@@ -5198,9 +5200,11 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec) | |||
5198 | fill_pcm_stream_name(spec->stream_name_alt_analog, | 5200 | fill_pcm_stream_name(spec->stream_name_alt_analog, |
5199 | sizeof(spec->stream_name_alt_analog), | 5201 | sizeof(spec->stream_name_alt_analog), |
5200 | " Alt Analog", codec->chip_name); | 5202 | " Alt Analog", codec->chip_name); |
5201 | codec->num_pcms = 3; | 5203 | info = snd_hda_codec_pcm_new(codec, "%s", |
5202 | info = spec->pcm_rec + 2; | 5204 | spec->stream_name_alt_analog); |
5203 | info->name = spec->stream_name_alt_analog; | 5205 | if (!info) |
5206 | return -ENOMEM; | ||
5207 | spec->pcm_rec[2] = info; | ||
5204 | if (spec->alt_dac_nid) { | 5208 | if (spec->alt_dac_nid) { |
5205 | p = spec->stream_analog_alt_playback; | 5209 | p = spec->stream_analog_alt_playback; |
5206 | if (!p) | 5210 | if (!p) |
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h index 3d852660443a..b211f889b335 100644 --- a/sound/pci/hda/hda_generic.h +++ b/sound/pci/hda/hda_generic.h | |||
@@ -144,7 +144,7 @@ struct hda_gen_spec { | |||
144 | int const_channel_count; /* channel count for all */ | 144 | int const_channel_count; /* channel count for all */ |
145 | 145 | ||
146 | /* PCM information */ | 146 | /* PCM information */ |
147 | struct hda_pcm pcm_rec[3]; /* used in build_pcms() */ | 147 | struct hda_pcm *pcm_rec[3]; /* used in build_pcms() */ |
148 | 148 | ||
149 | /* dynamic controls, init_verbs and input_mux */ | 149 | /* dynamic controls, init_verbs and input_mux */ |
150 | struct auto_pin_cfg autocfg; | 150 | struct auto_pin_cfg autocfg; |
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index cc32b878ae2e..aeb983e7506d 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c | |||
@@ -99,10 +99,10 @@ static void print_nid_array(struct snd_info_buffer *buffer, | |||
99 | static void print_nid_pcms(struct snd_info_buffer *buffer, | 99 | static void print_nid_pcms(struct snd_info_buffer *buffer, |
100 | struct hda_codec *codec, hda_nid_t nid) | 100 | struct hda_codec *codec, hda_nid_t nid) |
101 | { | 101 | { |
102 | int pcm, type; | 102 | int type; |
103 | struct hda_pcm *cpcm; | 103 | struct hda_pcm *cpcm; |
104 | for (pcm = 0; pcm < codec->num_pcms; pcm++) { | 104 | |
105 | cpcm = &codec->pcm_info[pcm]; | 105 | list_for_each_entry(cpcm, &codec->pcm_list_head, list) { |
106 | for (type = 0; type < 2; type++) { | 106 | for (type = 0; type < 2; type++) { |
107 | if (cpcm->stream[type].nid != nid || cpcm->pcm == NULL) | 107 | if (cpcm->stream[type].nid != nid || cpcm->pcm == NULL) |
108 | continue; | 108 | continue; |
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index ced3e82d9e23..555781fad26f 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c | |||
@@ -719,7 +719,6 @@ struct ca0132_spec { | |||
719 | unsigned int num_inputs; | 719 | unsigned int num_inputs; |
720 | hda_nid_t shared_mic_nid; | 720 | hda_nid_t shared_mic_nid; |
721 | hda_nid_t shared_out_nid; | 721 | hda_nid_t shared_out_nid; |
722 | struct hda_pcm pcm_rec[5]; /* PCM information */ | ||
723 | 722 | ||
724 | /* chip access */ | 723 | /* chip access */ |
725 | struct mutex chipio_mutex; /* chip access mutex */ | 724 | struct mutex chipio_mutex; /* chip access mutex */ |
@@ -4036,12 +4035,11 @@ static struct hda_pcm_stream ca0132_pcm_digital_capture = { | |||
4036 | static int ca0132_build_pcms(struct hda_codec *codec) | 4035 | static int ca0132_build_pcms(struct hda_codec *codec) |
4037 | { | 4036 | { |
4038 | struct ca0132_spec *spec = codec->spec; | 4037 | struct ca0132_spec *spec = codec->spec; |
4039 | struct hda_pcm *info = spec->pcm_rec; | 4038 | struct hda_pcm *info; |
4040 | 4039 | ||
4041 | codec->pcm_info = info; | 4040 | info = snd_hda_codec_pcm_new(codec, "CA0132 Analog"); |
4042 | codec->num_pcms = 0; | 4041 | if (!info) |
4043 | 4042 | return -ENOMEM; | |
4044 | info->name = "CA0132 Analog"; | ||
4045 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ca0132_pcm_analog_playback; | 4043 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ca0132_pcm_analog_playback; |
4046 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dacs[0]; | 4044 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dacs[0]; |
4047 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = | 4045 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = |
@@ -4049,27 +4047,27 @@ static int ca0132_build_pcms(struct hda_codec *codec) | |||
4049 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0132_pcm_analog_capture; | 4047 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0132_pcm_analog_capture; |
4050 | info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1; | 4048 | info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1; |
4051 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[0]; | 4049 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[0]; |
4052 | codec->num_pcms++; | ||
4053 | 4050 | ||
4054 | info++; | 4051 | info = snd_hda_codec_pcm_new(codec, "CA0132 Analog Mic-In2"); |
4055 | info->name = "CA0132 Analog Mic-In2"; | 4052 | if (!info) |
4053 | return -ENOMEM; | ||
4056 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0132_pcm_analog_capture; | 4054 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0132_pcm_analog_capture; |
4057 | info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1; | 4055 | info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1; |
4058 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[1]; | 4056 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[1]; |
4059 | codec->num_pcms++; | ||
4060 | 4057 | ||
4061 | info++; | 4058 | info = snd_hda_codec_pcm_new(codec, "CA0132 What U Hear"); |
4062 | info->name = "CA0132 What U Hear"; | 4059 | if (!info) |
4060 | return -ENOMEM; | ||
4063 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0132_pcm_analog_capture; | 4061 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0132_pcm_analog_capture; |
4064 | info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1; | 4062 | info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1; |
4065 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[2]; | 4063 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[2]; |
4066 | codec->num_pcms++; | ||
4067 | 4064 | ||
4068 | if (!spec->dig_out && !spec->dig_in) | 4065 | if (!spec->dig_out && !spec->dig_in) |
4069 | return 0; | 4066 | return 0; |
4070 | 4067 | ||
4071 | info++; | 4068 | info = snd_hda_codec_pcm_new(codec, "CA0132 Digital"); |
4072 | info->name = "CA0132 Digital"; | 4069 | if (!info) |
4070 | return -ENOMEM; | ||
4073 | info->pcm_type = HDA_PCM_TYPE_SPDIF; | 4071 | info->pcm_type = HDA_PCM_TYPE_SPDIF; |
4074 | if (spec->dig_out) { | 4072 | if (spec->dig_out) { |
4075 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = | 4073 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = |
@@ -4081,7 +4079,6 @@ static int ca0132_build_pcms(struct hda_codec *codec) | |||
4081 | ca0132_pcm_digital_capture; | 4079 | ca0132_pcm_digital_capture; |
4082 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in; | 4080 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in; |
4083 | } | 4081 | } |
4084 | codec->num_pcms++; | ||
4085 | 4082 | ||
4086 | return 0; | 4083 | return 0; |
4087 | } | 4084 | } |
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 0f8354cbc7a7..708bbed15ea3 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -86,7 +86,6 @@ struct hdmi_spec_per_pin { | |||
86 | bool non_pcm; | 86 | bool non_pcm; |
87 | bool chmap_set; /* channel-map override by ALSA API? */ | 87 | bool chmap_set; /* channel-map override by ALSA API? */ |
88 | unsigned char chmap[8]; /* ALSA API channel-map */ | 88 | unsigned char chmap[8]; /* ALSA API channel-map */ |
89 | char pcm_name[8]; /* filled in build_pcm callbacks */ | ||
90 | #ifdef CONFIG_PROC_FS | 89 | #ifdef CONFIG_PROC_FS |
91 | struct snd_info_entry *proc_entry; | 90 | struct snd_info_entry *proc_entry; |
92 | #endif | 91 | #endif |
@@ -132,7 +131,7 @@ struct hdmi_spec { | |||
132 | 131 | ||
133 | int num_pins; | 132 | int num_pins; |
134 | struct snd_array pins; /* struct hdmi_spec_per_pin */ | 133 | struct snd_array pins; /* struct hdmi_spec_per_pin */ |
135 | struct snd_array pcm_rec; /* struct hda_pcm */ | 134 | struct hda_pcm *pcm_rec[16]; |
136 | unsigned int channels_max; /* max over all cvts */ | 135 | unsigned int channels_max; /* max over all cvts */ |
137 | 136 | ||
138 | struct hdmi_eld temp_eld; | 137 | struct hdmi_eld temp_eld; |
@@ -355,8 +354,7 @@ static struct cea_channel_speaker_allocation channel_allocations[] = { | |||
355 | ((struct hdmi_spec_per_pin *)snd_array_elem(&spec->pins, idx)) | 354 | ((struct hdmi_spec_per_pin *)snd_array_elem(&spec->pins, idx)) |
356 | #define get_cvt(spec, idx) \ | 355 | #define get_cvt(spec, idx) \ |
357 | ((struct hdmi_spec_per_cvt *)snd_array_elem(&spec->cvts, idx)) | 356 | ((struct hdmi_spec_per_cvt *)snd_array_elem(&spec->cvts, idx)) |
358 | #define get_pcm_rec(spec, idx) \ | 357 | #define get_pcm_rec(spec, idx) ((spec)->pcm_rec[idx]) |
359 | ((struct hda_pcm *)snd_array_elem(&spec->pcm_rec, idx)) | ||
360 | 358 | ||
361 | static int pin_nid_to_pin_index(struct hda_codec *codec, hda_nid_t pin_nid) | 359 | static int pin_nid_to_pin_index(struct hda_codec *codec, hda_nid_t pin_nid) |
362 | { | 360 | { |
@@ -2056,11 +2054,10 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec) | |||
2056 | struct hdmi_spec_per_pin *per_pin; | 2054 | struct hdmi_spec_per_pin *per_pin; |
2057 | 2055 | ||
2058 | per_pin = get_pin(spec, pin_idx); | 2056 | per_pin = get_pin(spec, pin_idx); |
2059 | sprintf(per_pin->pcm_name, "HDMI %d", pin_idx); | 2057 | info = snd_hda_codec_pcm_new(codec, "HDMI %d", pin_idx); |
2060 | info = snd_array_new(&spec->pcm_rec); | ||
2061 | if (!info) | 2058 | if (!info) |
2062 | return -ENOMEM; | 2059 | return -ENOMEM; |
2063 | info->name = per_pin->pcm_name; | 2060 | spec->pcm_rec[pin_idx] = info; |
2064 | info->pcm_type = HDA_PCM_TYPE_HDMI; | 2061 | info->pcm_type = HDA_PCM_TYPE_HDMI; |
2065 | info->own_chmap = true; | 2062 | info->own_chmap = true; |
2066 | 2063 | ||
@@ -2070,9 +2067,6 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec) | |||
2070 | /* other pstr fields are set in open */ | 2067 | /* other pstr fields are set in open */ |
2071 | } | 2068 | } |
2072 | 2069 | ||
2073 | codec->num_pcms = spec->num_pins; | ||
2074 | codec->pcm_info = spec->pcm_rec.list; | ||
2075 | |||
2076 | return 0; | 2070 | return 0; |
2077 | } | 2071 | } |
2078 | 2072 | ||
@@ -2125,13 +2119,15 @@ static int generic_hdmi_build_controls(struct hda_codec *codec) | |||
2125 | 2119 | ||
2126 | /* add channel maps */ | 2120 | /* add channel maps */ |
2127 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { | 2121 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { |
2122 | struct hda_pcm *pcm; | ||
2128 | struct snd_pcm_chmap *chmap; | 2123 | struct snd_pcm_chmap *chmap; |
2129 | struct snd_kcontrol *kctl; | 2124 | struct snd_kcontrol *kctl; |
2130 | int i; | 2125 | int i; |
2131 | 2126 | ||
2132 | if (!codec->pcm_info[pin_idx].pcm) | 2127 | pcm = spec->pcm_rec[pin_idx]; |
2128 | if (!pcm || !pcm->pcm) | ||
2133 | break; | 2129 | break; |
2134 | err = snd_pcm_add_chmap_ctls(codec->pcm_info[pin_idx].pcm, | 2130 | err = snd_pcm_add_chmap_ctls(pcm->pcm, |
2135 | SNDRV_PCM_STREAM_PLAYBACK, | 2131 | SNDRV_PCM_STREAM_PLAYBACK, |
2136 | NULL, 0, pin_idx, &chmap); | 2132 | NULL, 0, pin_idx, &chmap); |
2137 | if (err < 0) | 2133 | if (err < 0) |
@@ -2186,14 +2182,12 @@ static void hdmi_array_init(struct hdmi_spec *spec, int nums) | |||
2186 | { | 2182 | { |
2187 | snd_array_init(&spec->pins, sizeof(struct hdmi_spec_per_pin), nums); | 2183 | snd_array_init(&spec->pins, sizeof(struct hdmi_spec_per_pin), nums); |
2188 | snd_array_init(&spec->cvts, sizeof(struct hdmi_spec_per_cvt), nums); | 2184 | snd_array_init(&spec->cvts, sizeof(struct hdmi_spec_per_cvt), nums); |
2189 | snd_array_init(&spec->pcm_rec, sizeof(struct hda_pcm), nums); | ||
2190 | } | 2185 | } |
2191 | 2186 | ||
2192 | static void hdmi_array_free(struct hdmi_spec *spec) | 2187 | static void hdmi_array_free(struct hdmi_spec *spec) |
2193 | { | 2188 | { |
2194 | snd_array_free(&spec->pins); | 2189 | snd_array_free(&spec->pins); |
2195 | snd_array_free(&spec->cvts); | 2190 | snd_array_free(&spec->cvts); |
2196 | snd_array_free(&spec->pcm_rec); | ||
2197 | } | 2191 | } |
2198 | 2192 | ||
2199 | static void generic_hdmi_free(struct hda_codec *codec) | 2193 | static void generic_hdmi_free(struct hda_codec *codec) |
@@ -2381,11 +2375,10 @@ static int simple_playback_build_pcms(struct hda_codec *codec) | |||
2381 | chans = get_wcaps(codec, per_cvt->cvt_nid); | 2375 | chans = get_wcaps(codec, per_cvt->cvt_nid); |
2382 | chans = get_wcaps_channels(chans); | 2376 | chans = get_wcaps_channels(chans); |
2383 | 2377 | ||
2384 | info = snd_array_new(&spec->pcm_rec); | 2378 | info = snd_hda_codec_pcm_new(codec, "HDMI 0"); |
2385 | if (!info) | 2379 | if (!info) |
2386 | return -ENOMEM; | 2380 | return -ENOMEM; |
2387 | info->name = get_pin(spec, 0)->pcm_name; | 2381 | spec->pcm_rec[0] = info; |
2388 | sprintf(info->name, "HDMI 0"); | ||
2389 | info->pcm_type = HDA_PCM_TYPE_HDMI; | 2382 | info->pcm_type = HDA_PCM_TYPE_HDMI; |
2390 | pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; | 2383 | pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; |
2391 | *pstr = spec->pcm_playback; | 2384 | *pstr = spec->pcm_playback; |
@@ -2393,9 +2386,6 @@ static int simple_playback_build_pcms(struct hda_codec *codec) | |||
2393 | if (pstr->channels_max <= 2 && chans && chans <= 16) | 2386 | if (pstr->channels_max <= 2 && chans && chans <= 16) |
2394 | pstr->channels_max = chans; | 2387 | pstr->channels_max = chans; |
2395 | 2388 | ||
2396 | codec->num_pcms = 1; | ||
2397 | codec->pcm_info = info; | ||
2398 | |||
2399 | return 0; | 2389 | return 0; |
2400 | } | 2390 | } |
2401 | 2391 | ||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 70808f92276a..0a5a2246e57a 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -5843,7 +5843,7 @@ static void alc_fixup_bass_chmap(struct hda_codec *codec, | |||
5843 | { | 5843 | { |
5844 | if (action == HDA_FIXUP_ACT_BUILD) { | 5844 | if (action == HDA_FIXUP_ACT_BUILD) { |
5845 | struct alc_spec *spec = codec->spec; | 5845 | struct alc_spec *spec = codec->spec; |
5846 | spec->gen.pcm_rec[0].stream[0].chmap = asus_pcm_2_1_chmaps; | 5846 | spec->gen.pcm_rec[0]->stream[0].chmap = asus_pcm_2_1_chmaps; |
5847 | } | 5847 | } |
5848 | } | 5848 | } |
5849 | 5849 | ||
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c index 38a477333321..df243134baa8 100644 --- a/sound/pci/hda/patch_si3054.c +++ b/sound/pci/hda/patch_si3054.c | |||
@@ -83,7 +83,6 @@ | |||
83 | 83 | ||
84 | struct si3054_spec { | 84 | struct si3054_spec { |
85 | unsigned international; | 85 | unsigned international; |
86 | struct hda_pcm pcm; | ||
87 | }; | 86 | }; |
88 | 87 | ||
89 | 88 | ||
@@ -199,11 +198,11 @@ static const struct hda_pcm_stream si3054_pcm = { | |||
199 | 198 | ||
200 | static int si3054_build_pcms(struct hda_codec *codec) | 199 | static int si3054_build_pcms(struct hda_codec *codec) |
201 | { | 200 | { |
202 | struct si3054_spec *spec = codec->spec; | 201 | struct hda_pcm *info; |
203 | struct hda_pcm *info = &spec->pcm; | 202 | |
204 | codec->num_pcms = 1; | 203 | info = snd_hda_codec_pcm_new(codec, "Si3054 Modem"); |
205 | codec->pcm_info = info; | 204 | if (!info) |
206 | info->name = "Si3054 Modem"; | 205 | return -ENOMEM; |
207 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = si3054_pcm; | 206 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = si3054_pcm; |
208 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = si3054_pcm; | 207 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = si3054_pcm; |
209 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = codec->mfg; | 208 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = codec->mfg; |
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 57ad503ff940..11a05638e03b 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -683,8 +683,10 @@ static int vt1708_build_pcms(struct hda_codec *codec) | |||
683 | * 24bit samples are used. Until any workaround is found, | 683 | * 24bit samples are used. Until any workaround is found, |
684 | * disable the 24bit format, so far. | 684 | * disable the 24bit format, so far. |
685 | */ | 685 | */ |
686 | for (i = 0; i < codec->num_pcms; i++) { | 686 | for (i = 0; i < ARRAY_SIZE(spec->gen.pcm_rec); i++) { |
687 | struct hda_pcm *info = &spec->gen.pcm_rec[i]; | 687 | struct hda_pcm *info = spec->gen.pcm_rec[i]; |
688 | if (!info) | ||
689 | continue; | ||
688 | if (!info->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams || | 690 | if (!info->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams || |
689 | info->pcm_type != HDA_PCM_TYPE_AUDIO) | 691 | info->pcm_type != HDA_PCM_TYPE_AUDIO) |
690 | continue; | 692 | continue; |