diff options
Diffstat (limited to 'sound')
| -rw-r--r-- | sound/core/device.c | 43 | ||||
| -rw-r--r-- | sound/core/init.c | 5 | ||||
| -rw-r--r-- | sound/pci/hda/hda_beep.c | 4 | ||||
| -rw-r--r-- | sound/pci/hda/hda_bind.c | 41 | ||||
| -rw-r--r-- | sound/pci/hda/hda_codec.c | 445 | ||||
| -rw-r--r-- | sound/pci/hda/hda_codec.h | 30 | ||||
| -rw-r--r-- | sound/pci/hda/hda_controller.c | 79 | ||||
| -rw-r--r-- | sound/pci/hda/hda_controller.h | 6 | ||||
| -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_hwdep.c | 2 | ||||
| -rw-r--r-- | sound/pci/hda/hda_intel.c | 39 | ||||
| -rw-r--r-- | sound/pci/hda/hda_jack.c | 8 | ||||
| -rw-r--r-- | sound/pci/hda/hda_local.h | 1 | ||||
| -rw-r--r-- | sound/pci/hda/hda_proc.c | 8 | ||||
| -rw-r--r-- | sound/pci/hda/hda_sysfs.c | 2 | ||||
| -rw-r--r-- | sound/pci/hda/hda_tegra.c | 26 | ||||
| -rw-r--r-- | sound/pci/hda/hda_trace.h | 4 | ||||
| -rw-r--r-- | sound/pci/hda/patch_ca0132.c | 34 | ||||
| -rw-r--r-- | sound/pci/hda/patch_hdmi.c | 44 | ||||
| -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 | 17 |
23 files changed, 418 insertions, 463 deletions
diff --git a/sound/core/device.c b/sound/core/device.c index c1a845b42a8b..8918838b1999 100644 --- a/sound/core/device.c +++ b/sound/core/device.c | |||
| @@ -71,7 +71,7 @@ int snd_device_new(struct snd_card *card, enum snd_device_type type, | |||
| 71 | } | 71 | } |
| 72 | EXPORT_SYMBOL(snd_device_new); | 72 | EXPORT_SYMBOL(snd_device_new); |
| 73 | 73 | ||
| 74 | static int __snd_device_disconnect(struct snd_device *dev) | 74 | static void __snd_device_disconnect(struct snd_device *dev) |
| 75 | { | 75 | { |
| 76 | if (dev->state == SNDRV_DEV_REGISTERED) { | 76 | if (dev->state == SNDRV_DEV_REGISTERED) { |
| 77 | if (dev->ops->dev_disconnect && | 77 | if (dev->ops->dev_disconnect && |
| @@ -79,7 +79,6 @@ static int __snd_device_disconnect(struct snd_device *dev) | |||
| 79 | dev_err(dev->card->dev, "device disconnect failure\n"); | 79 | dev_err(dev->card->dev, "device disconnect failure\n"); |
| 80 | dev->state = SNDRV_DEV_DISCONNECTED; | 80 | dev->state = SNDRV_DEV_DISCONNECTED; |
| 81 | } | 81 | } |
| 82 | return 0; | ||
| 83 | } | 82 | } |
| 84 | 83 | ||
| 85 | static void __snd_device_free(struct snd_device *dev) | 84 | static void __snd_device_free(struct snd_device *dev) |
| @@ -107,6 +106,34 @@ static struct snd_device *look_for_dev(struct snd_card *card, void *device_data) | |||
| 107 | } | 106 | } |
| 108 | 107 | ||
| 109 | /** | 108 | /** |
| 109 | * snd_device_disconnect - disconnect the device | ||
| 110 | * @card: the card instance | ||
| 111 | * @device_data: the data pointer to disconnect | ||
| 112 | * | ||
| 113 | * Turns the device into the disconnection state, invoking | ||
| 114 | * dev_disconnect callback, if the device was already registered. | ||
| 115 | * | ||
| 116 | * Usually called from snd_card_disconnect(). | ||
| 117 | * | ||
| 118 | * Return: Zero if successful, or a negative error code on failure or if the | ||
| 119 | * device not found. | ||
| 120 | */ | ||
| 121 | void snd_device_disconnect(struct snd_card *card, void *device_data) | ||
| 122 | { | ||
| 123 | struct snd_device *dev; | ||
| 124 | |||
| 125 | if (snd_BUG_ON(!card || !device_data)) | ||
| 126 | return; | ||
| 127 | dev = look_for_dev(card, device_data); | ||
| 128 | if (dev) | ||
| 129 | __snd_device_disconnect(dev); | ||
| 130 | else | ||
| 131 | dev_dbg(card->dev, "device disconnect %p (from %pF), not found\n", | ||
| 132 | device_data, __builtin_return_address(0)); | ||
| 133 | } | ||
| 134 | EXPORT_SYMBOL_GPL(snd_device_disconnect); | ||
| 135 | |||
| 136 | /** | ||
| 110 | * snd_device_free - release the device from the card | 137 | * snd_device_free - release the device from the card |
| 111 | * @card: the card instance | 138 | * @card: the card instance |
| 112 | * @device_data: the data pointer to release | 139 | * @device_data: the data pointer to release |
| @@ -193,18 +220,14 @@ int snd_device_register_all(struct snd_card *card) | |||
| 193 | * disconnect all the devices on the card. | 220 | * disconnect all the devices on the card. |
| 194 | * called from init.c | 221 | * called from init.c |
| 195 | */ | 222 | */ |
| 196 | int snd_device_disconnect_all(struct snd_card *card) | 223 | void snd_device_disconnect_all(struct snd_card *card) |
| 197 | { | 224 | { |
| 198 | struct snd_device *dev; | 225 | struct snd_device *dev; |
| 199 | int err = 0; | ||
| 200 | 226 | ||
| 201 | if (snd_BUG_ON(!card)) | 227 | if (snd_BUG_ON(!card)) |
| 202 | return -ENXIO; | 228 | return; |
| 203 | list_for_each_entry_reverse(dev, &card->devices, list) { | 229 | list_for_each_entry_reverse(dev, &card->devices, list) |
| 204 | if (__snd_device_disconnect(dev) < 0) | 230 | __snd_device_disconnect(dev); |
| 205 | err = -ENXIO; | ||
| 206 | } | ||
| 207 | return err; | ||
| 208 | } | 231 | } |
| 209 | 232 | ||
| 210 | /* | 233 | /* |
diff --git a/sound/core/init.c b/sound/core/init.c index 35419054821c..04734e047bfe 100644 --- a/sound/core/init.c +++ b/sound/core/init.c | |||
| @@ -400,7 +400,6 @@ static const struct file_operations snd_shutdown_f_ops = | |||
| 400 | int snd_card_disconnect(struct snd_card *card) | 400 | int snd_card_disconnect(struct snd_card *card) |
| 401 | { | 401 | { |
| 402 | struct snd_monitor_file *mfile; | 402 | struct snd_monitor_file *mfile; |
| 403 | int err; | ||
| 404 | 403 | ||
| 405 | if (!card) | 404 | if (!card) |
| 406 | return -EINVAL; | 405 | return -EINVAL; |
| @@ -445,9 +444,7 @@ int snd_card_disconnect(struct snd_card *card) | |||
| 445 | #endif | 444 | #endif |
| 446 | 445 | ||
| 447 | /* notify all devices that we are disconnected */ | 446 | /* notify all devices that we are disconnected */ |
| 448 | err = snd_device_disconnect_all(card); | 447 | snd_device_disconnect_all(card); |
| 449 | if (err < 0) | ||
| 450 | dev_err(card->dev, "not all devices for card %i can be disconnected\n", card->number); | ||
| 451 | 448 | ||
| 452 | snd_info_card_disconnect(card); | 449 | snd_info_card_disconnect(card); |
| 453 | if (card->registered) { | 450 | if (card->registered) { |
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index e98438e95e79..581b7fdef0e3 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c | |||
| @@ -160,7 +160,7 @@ static int snd_hda_do_attach(struct hda_beep *beep) | |||
| 160 | input_dev->name = "HDA Digital PCBeep"; | 160 | input_dev->name = "HDA Digital PCBeep"; |
| 161 | input_dev->phys = beep->phys; | 161 | input_dev->phys = beep->phys; |
| 162 | input_dev->id.bustype = BUS_PCI; | 162 | input_dev->id.bustype = BUS_PCI; |
| 163 | input_dev->dev.parent = &codec->bus->card->card_dev; | 163 | input_dev->dev.parent = &codec->card->card_dev; |
| 164 | 164 | ||
| 165 | input_dev->id.vendor = codec->vendor_id >> 16; | 165 | input_dev->id.vendor = codec->vendor_id >> 16; |
| 166 | input_dev->id.product = codec->vendor_id & 0xffff; | 166 | input_dev->id.product = codec->vendor_id & 0xffff; |
| @@ -224,7 +224,7 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) | |||
| 224 | if (beep == NULL) | 224 | if (beep == NULL) |
| 225 | return -ENOMEM; | 225 | return -ENOMEM; |
| 226 | snprintf(beep->phys, sizeof(beep->phys), | 226 | snprintf(beep->phys, sizeof(beep->phys), |
| 227 | "card%d/codec#%d/beep0", codec->bus->card->number, codec->addr); | 227 | "card%d/codec#%d/beep0", codec->card->number, codec->addr); |
| 228 | /* enable linear scale */ | 228 | /* enable linear scale */ |
| 229 | snd_hda_codec_write_cache(codec, nid, 0, | 229 | snd_hda_codec_write_cache(codec, nid, 0, |
| 230 | AC_VERB_SET_DIGI_CONVERT_2, 0x01); | 230 | AC_VERB_SET_DIGI_CONVERT_2, 0x01); |
diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c index ce2dd7b0dc07..1f40ce3c1696 100644 --- a/sound/pci/hda/hda_bind.c +++ b/sound/pci/hda/hda_bind.c | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
| 10 | #include <linux/export.h> | 10 | #include <linux/export.h> |
| 11 | #include <linux/pm.h> | 11 | #include <linux/pm.h> |
| 12 | #include <linux/pm_runtime.h> | ||
| 12 | #include <sound/core.h> | 13 | #include <sound/core.h> |
| 13 | #include "hda_codec.h" | 14 | #include "hda_codec.h" |
| 14 | #include "hda_local.h" | 15 | #include "hda_local.h" |
| @@ -106,16 +107,28 @@ static int hda_codec_driver_probe(struct device *dev) | |||
| 106 | } | 107 | } |
| 107 | 108 | ||
| 108 | err = codec->preset->patch(codec); | 109 | err = codec->preset->patch(codec); |
| 109 | if (err < 0) { | 110 | if (err < 0) |
| 110 | module_put(owner); | 111 | goto error_module; |
| 111 | goto error; | 112 | |
| 113 | err = snd_hda_codec_build_pcms(codec); | ||
| 114 | if (err < 0) | ||
| 115 | goto error_module; | ||
| 116 | err = snd_hda_codec_build_controls(codec); | ||
| 117 | if (err < 0) | ||
| 118 | goto error_module; | ||
| 119 | if (codec->card->registered) { | ||
| 120 | err = snd_card_register(codec->card); | ||
| 121 | if (err < 0) | ||
| 122 | goto error_module; | ||
| 112 | } | 123 | } |
| 113 | 124 | ||
| 114 | return 0; | 125 | return 0; |
| 115 | 126 | ||
| 127 | error_module: | ||
| 128 | module_put(owner); | ||
| 129 | |||
| 116 | error: | 130 | error: |
| 117 | codec->preset = NULL; | 131 | snd_hda_codec_cleanup_for_unbind(codec); |
| 118 | memset(&codec->patch_ops, 0, sizeof(codec->patch_ops)); | ||
| 119 | return err; | 132 | return err; |
| 120 | } | 133 | } |
| 121 | 134 | ||
| @@ -125,12 +138,19 @@ static int hda_codec_driver_remove(struct device *dev) | |||
| 125 | 138 | ||
| 126 | if (codec->patch_ops.free) | 139 | if (codec->patch_ops.free) |
| 127 | codec->patch_ops.free(codec); | 140 | codec->patch_ops.free(codec); |
| 128 | codec->preset = NULL; | 141 | snd_hda_codec_cleanup_for_unbind(codec); |
| 129 | memset(&codec->patch_ops, 0, sizeof(codec->patch_ops)); | ||
| 130 | module_put(dev->driver->owner); | 142 | module_put(dev->driver->owner); |
| 131 | return 0; | 143 | return 0; |
| 132 | } | 144 | } |
| 133 | 145 | ||
| 146 | static void hda_codec_driver_shutdown(struct device *dev) | ||
| 147 | { | ||
| 148 | struct hda_codec *codec = dev_to_hda_codec(dev); | ||
| 149 | |||
| 150 | if (!pm_runtime_suspended(dev) && codec->patch_ops.reboot_notify) | ||
| 151 | codec->patch_ops.reboot_notify(codec); | ||
| 152 | } | ||
| 153 | |||
| 134 | int __hda_codec_driver_register(struct hda_codec_driver *drv, const char *name, | 154 | int __hda_codec_driver_register(struct hda_codec_driver *drv, const char *name, |
| 135 | struct module *owner) | 155 | struct module *owner) |
| 136 | { | 156 | { |
| @@ -139,6 +159,7 @@ int __hda_codec_driver_register(struct hda_codec_driver *drv, const char *name, | |||
| 139 | drv->driver.bus = &snd_hda_bus_type; | 159 | drv->driver.bus = &snd_hda_bus_type; |
| 140 | drv->driver.probe = hda_codec_driver_probe; | 160 | drv->driver.probe = hda_codec_driver_probe; |
| 141 | drv->driver.remove = hda_codec_driver_remove; | 161 | drv->driver.remove = hda_codec_driver_remove; |
| 162 | drv->driver.shutdown = hda_codec_driver_shutdown; | ||
| 142 | drv->driver.pm = &hda_codec_driver_pm; | 163 | drv->driver.pm = &hda_codec_driver_pm; |
| 143 | return driver_register(&drv->driver); | 164 | return driver_register(&drv->driver); |
| 144 | } | 165 | } |
| @@ -287,9 +308,9 @@ int snd_hda_codec_configure(struct hda_codec *codec) | |||
| 287 | } | 308 | } |
| 288 | 309 | ||
| 289 | /* audio codec should override the mixer name */ | 310 | /* audio codec should override the mixer name */ |
| 290 | if (codec->afg || !*codec->bus->card->mixername) | 311 | if (codec->afg || !*codec->card->mixername) |
| 291 | snprintf(codec->bus->card->mixername, | 312 | snprintf(codec->card->mixername, |
| 292 | sizeof(codec->bus->card->mixername), | 313 | sizeof(codec->card->mixername), |
| 293 | "%s %s", codec->vendor_name, codec->chip_name); | 314 | "%s %s", codec->vendor_name, codec->chip_name); |
| 294 | return 0; | 315 | return 0; |
| 295 | 316 | ||
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index db86b446743c..3e4fb7a8fdcb 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
| @@ -681,7 +681,7 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex) | |||
| 681 | struct hda_bus_unsolicited *unsol; | 681 | struct hda_bus_unsolicited *unsol; |
| 682 | unsigned int wp; | 682 | unsigned int wp; |
| 683 | 683 | ||
| 684 | if (!bus || !bus->workq) | 684 | if (!bus) |
| 685 | return 0; | 685 | return 0; |
| 686 | 686 | ||
| 687 | trace_hda_unsol_event(bus, res, res_ex); | 687 | trace_hda_unsol_event(bus, res, res_ex); |
| @@ -693,7 +693,7 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex) | |||
| 693 | unsol->queue[wp] = res; | 693 | unsol->queue[wp] = res; |
| 694 | unsol->queue[wp + 1] = res_ex; | 694 | unsol->queue[wp + 1] = res_ex; |
| 695 | 695 | ||
| 696 | queue_work(bus->workq, &unsol->work); | 696 | schedule_work(&unsol->work); |
| 697 | 697 | ||
| 698 | return 0; | 698 | return 0; |
| 699 | } | 699 | } |
| @@ -732,13 +732,9 @@ static void snd_hda_bus_free(struct hda_bus *bus) | |||
| 732 | return; | 732 | return; |
| 733 | 733 | ||
| 734 | WARN_ON(!list_empty(&bus->codec_list)); | 734 | WARN_ON(!list_empty(&bus->codec_list)); |
| 735 | if (bus->workq) | 735 | cancel_work_sync(&bus->unsol.work); |
| 736 | flush_workqueue(bus->workq); | ||
| 737 | if (bus->ops.private_free) | 736 | if (bus->ops.private_free) |
| 738 | bus->ops.private_free(bus); | 737 | bus->ops.private_free(bus); |
| 739 | if (bus->workq) | ||
| 740 | destroy_workqueue(bus->workq); | ||
| 741 | |||
| 742 | kfree(bus); | 738 | kfree(bus); |
| 743 | } | 739 | } |
| 744 | 740 | ||
| @@ -776,10 +772,8 @@ int snd_hda_bus_new(struct snd_card *card, | |||
| 776 | *busp = NULL; | 772 | *busp = NULL; |
| 777 | 773 | ||
| 778 | bus = kzalloc(sizeof(*bus), GFP_KERNEL); | 774 | bus = kzalloc(sizeof(*bus), GFP_KERNEL); |
| 779 | if (bus == NULL) { | 775 | if (!bus) |
| 780 | dev_err(card->dev, "can't allocate struct hda_bus\n"); | ||
| 781 | return -ENOMEM; | 776 | return -ENOMEM; |
| 782 | } | ||
| 783 | 777 | ||
| 784 | bus->card = card; | 778 | bus->card = card; |
| 785 | mutex_init(&bus->cmd_mutex); | 779 | mutex_init(&bus->cmd_mutex); |
| @@ -787,16 +781,6 @@ int snd_hda_bus_new(struct snd_card *card, | |||
| 787 | INIT_LIST_HEAD(&bus->codec_list); | 781 | INIT_LIST_HEAD(&bus->codec_list); |
| 788 | INIT_WORK(&bus->unsol.work, process_unsol_events); | 782 | INIT_WORK(&bus->unsol.work, process_unsol_events); |
| 789 | 783 | ||
| 790 | snprintf(bus->workq_name, sizeof(bus->workq_name), | ||
| 791 | "hd-audio%d", card->number); | ||
| 792 | bus->workq = create_singlethread_workqueue(bus->workq_name); | ||
| 793 | if (!bus->workq) { | ||
| 794 | dev_err(card->dev, "cannot create workqueue %s\n", | ||
| 795 | bus->workq_name); | ||
| 796 | kfree(bus); | ||
| 797 | return -ENOMEM; | ||
| 798 | } | ||
| 799 | |||
| 800 | err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops); | 784 | err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops); |
| 801 | if (err < 0) { | 785 | if (err < 0) { |
| 802 | snd_hda_bus_free(bus); | 786 | snd_hda_bus_free(bus); |
| @@ -1070,8 +1054,8 @@ static void hda_jackpoll_work(struct work_struct *work) | |||
| 1070 | if (!codec->jackpoll_interval) | 1054 | if (!codec->jackpoll_interval) |
| 1071 | return; | 1055 | return; |
| 1072 | 1056 | ||
| 1073 | queue_delayed_work(codec->bus->workq, &codec->jackpoll_work, | 1057 | schedule_delayed_work(&codec->jackpoll_work, |
| 1074 | codec->jackpoll_interval); | 1058 | codec->jackpoll_interval); |
| 1075 | } | 1059 | } |
| 1076 | 1060 | ||
| 1077 | static void init_hda_cache(struct hda_cache_rec *cache, | 1061 | static void init_hda_cache(struct hda_cache_rec *cache, |
| @@ -1119,35 +1103,92 @@ get_hda_cvt_setup(struct hda_codec *codec, hda_nid_t nid) | |||
| 1119 | } | 1103 | } |
| 1120 | 1104 | ||
| 1121 | /* | 1105 | /* |
| 1106 | * PCM device | ||
| 1107 | */ | ||
| 1108 | static void release_pcm(struct kref *kref) | ||
| 1109 | { | ||
| 1110 | struct hda_pcm *pcm = container_of(kref, struct hda_pcm, kref); | ||
| 1111 | |||
| 1112 | if (pcm->pcm) | ||
| 1113 | snd_device_free(pcm->codec->card, pcm->pcm); | ||
| 1114 | clear_bit(pcm->device, pcm->codec->bus->pcm_dev_bits); | ||
| 1115 | kfree(pcm->name); | ||
| 1116 | kfree(pcm); | ||
| 1117 | } | ||
| 1118 | |||
| 1119 | void snd_hda_codec_pcm_put(struct hda_pcm *pcm) | ||
| 1120 | { | ||
| 1121 | kref_put(&pcm->kref, release_pcm); | ||
| 1122 | } | ||
| 1123 | EXPORT_SYMBOL_GPL(snd_hda_codec_pcm_put); | ||
| 1124 | |||
| 1125 | struct hda_pcm *snd_hda_codec_pcm_new(struct hda_codec *codec, | ||
| 1126 | const char *fmt, ...) | ||
| 1127 | { | ||
| 1128 | struct hda_pcm *pcm; | ||
| 1129 | va_list args; | ||
| 1130 | |||
| 1131 | va_start(args, fmt); | ||
| 1132 | pcm = kzalloc(sizeof(*pcm), GFP_KERNEL); | ||
| 1133 | if (!pcm) | ||
| 1134 | return NULL; | ||
| 1135 | |||
| 1136 | pcm->codec = codec; | ||
| 1137 | kref_init(&pcm->kref); | ||
| 1138 | pcm->name = kvasprintf(GFP_KERNEL, fmt, args); | ||
| 1139 | if (!pcm->name) { | ||
| 1140 | kfree(pcm); | ||
| 1141 | return NULL; | ||
| 1142 | } | ||
| 1143 | |||
| 1144 | list_add_tail(&pcm->list, &codec->pcm_list_head); | ||
| 1145 | return pcm; | ||
| 1146 | } | ||
| 1147 | EXPORT_SYMBOL_GPL(snd_hda_codec_pcm_new); | ||
| 1148 | |||
| 1149 | /* | ||
| 1122 | * codec destructor | 1150 | * codec destructor |
| 1123 | */ | 1151 | */ |
| 1124 | static void snd_hda_codec_free(struct hda_codec *codec) | 1152 | static void codec_release_pcms(struct hda_codec *codec) |
| 1153 | { | ||
| 1154 | struct hda_pcm *pcm, *n; | ||
| 1155 | |||
| 1156 | list_for_each_entry_safe(pcm, n, &codec->pcm_list_head, list) { | ||
| 1157 | list_del_init(&pcm->list); | ||
| 1158 | if (pcm->pcm) | ||
| 1159 | snd_device_disconnect(codec->card, pcm->pcm); | ||
| 1160 | snd_hda_codec_pcm_put(pcm); | ||
| 1161 | } | ||
| 1162 | } | ||
| 1163 | |||
| 1164 | void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec) | ||
| 1125 | { | 1165 | { |
| 1126 | if (!codec) | ||
| 1127 | return; | ||
| 1128 | cancel_delayed_work_sync(&codec->jackpoll_work); | 1166 | cancel_delayed_work_sync(&codec->jackpoll_work); |
| 1129 | if (device_is_registered(hda_codec_dev(codec))) | 1167 | if (!codec->in_freeing) |
| 1130 | device_del(hda_codec_dev(codec)); | 1168 | snd_hda_ctls_clear(codec); |
| 1169 | codec_release_pcms(codec); | ||
| 1170 | snd_hda_detach_beep_device(codec); | ||
| 1171 | memset(&codec->patch_ops, 0, sizeof(codec->patch_ops)); | ||
| 1131 | snd_hda_jack_tbl_clear(codec); | 1172 | snd_hda_jack_tbl_clear(codec); |
| 1132 | free_init_pincfgs(codec); | 1173 | codec->proc_widget_hook = NULL; |
| 1133 | flush_workqueue(codec->bus->workq); | 1174 | codec->spec = NULL; |
| 1134 | list_del(&codec->list); | 1175 | |
| 1135 | snd_array_free(&codec->mixers); | 1176 | free_hda_cache(&codec->amp_cache); |
| 1136 | snd_array_free(&codec->nids); | 1177 | free_hda_cache(&codec->cmd_cache); |
| 1178 | init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); | ||
| 1179 | init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); | ||
| 1180 | |||
| 1181 | /* free only driver_pins so that init_pins + user_pins are restored */ | ||
| 1182 | snd_array_free(&codec->driver_pins); | ||
| 1137 | snd_array_free(&codec->cvt_setups); | 1183 | snd_array_free(&codec->cvt_setups); |
| 1138 | snd_array_free(&codec->spdif_out); | 1184 | snd_array_free(&codec->spdif_out); |
| 1185 | snd_array_free(&codec->verbs); | ||
| 1186 | codec->preset = NULL; | ||
| 1187 | codec->slave_dig_outs = NULL; | ||
| 1188 | codec->spdif_status_reset = 0; | ||
| 1189 | snd_array_free(&codec->mixers); | ||
| 1190 | snd_array_free(&codec->nids); | ||
| 1139 | remove_conn_list(codec); | 1191 | remove_conn_list(codec); |
| 1140 | codec->bus->caddr_tbl[codec->addr] = NULL; | ||
| 1141 | clear_bit(codec->addr, &codec->bus->codec_powered); | ||
| 1142 | snd_hda_sysfs_clear(codec); | ||
| 1143 | free_hda_cache(&codec->amp_cache); | ||
| 1144 | free_hda_cache(&codec->cmd_cache); | ||
| 1145 | kfree(codec->vendor_name); | ||
| 1146 | kfree(codec->chip_name); | ||
| 1147 | kfree(codec->modelname); | ||
| 1148 | kfree(codec->wcaps); | ||
| 1149 | codec->bus->num_codecs--; | ||
| 1150 | put_device(hda_codec_dev(codec)); | ||
| 1151 | } | 1192 | } |
| 1152 | 1193 | ||
| 1153 | static bool snd_hda_codec_get_supported_ps(struct hda_codec *codec, | 1194 | static bool snd_hda_codec_get_supported_ps(struct hda_codec *codec, |
| @@ -1178,14 +1219,32 @@ static int snd_hda_codec_dev_disconnect(struct snd_device *device) | |||
| 1178 | 1219 | ||
| 1179 | static int snd_hda_codec_dev_free(struct snd_device *device) | 1220 | static int snd_hda_codec_dev_free(struct snd_device *device) |
| 1180 | { | 1221 | { |
| 1181 | snd_hda_codec_free(device->device_data); | 1222 | struct hda_codec *codec = device->device_data; |
| 1223 | |||
| 1224 | codec->in_freeing = 1; | ||
| 1225 | if (device_is_registered(hda_codec_dev(codec))) | ||
| 1226 | device_del(hda_codec_dev(codec)); | ||
| 1227 | put_device(hda_codec_dev(codec)); | ||
| 1182 | return 0; | 1228 | return 0; |
| 1183 | } | 1229 | } |
| 1184 | 1230 | ||
| 1185 | /* just free the container */ | ||
| 1186 | static void snd_hda_codec_dev_release(struct device *dev) | 1231 | static void snd_hda_codec_dev_release(struct device *dev) |
| 1187 | { | 1232 | { |
| 1188 | kfree(dev_to_hda_codec(dev)); | 1233 | struct hda_codec *codec = dev_to_hda_codec(dev); |
| 1234 | |||
| 1235 | free_init_pincfgs(codec); | ||
| 1236 | list_del(&codec->list); | ||
| 1237 | codec->bus->caddr_tbl[codec->addr] = NULL; | ||
| 1238 | clear_bit(codec->addr, &codec->bus->codec_powered); | ||
| 1239 | snd_hda_sysfs_clear(codec); | ||
| 1240 | free_hda_cache(&codec->amp_cache); | ||
| 1241 | free_hda_cache(&codec->cmd_cache); | ||
| 1242 | kfree(codec->vendor_name); | ||
| 1243 | kfree(codec->chip_name); | ||
| 1244 | kfree(codec->modelname); | ||
| 1245 | kfree(codec->wcaps); | ||
| 1246 | codec->bus->num_codecs--; | ||
| 1247 | kfree(codec); | ||
| 1189 | } | 1248 | } |
| 1190 | 1249 | ||
| 1191 | /** | 1250 | /** |
| @@ -1196,9 +1255,8 @@ static void snd_hda_codec_dev_release(struct device *dev) | |||
| 1196 | * | 1255 | * |
| 1197 | * Returns 0 if successful, or a negative error code. | 1256 | * Returns 0 if successful, or a negative error code. |
| 1198 | */ | 1257 | */ |
| 1199 | int snd_hda_codec_new(struct hda_bus *bus, | 1258 | int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card, |
| 1200 | unsigned int codec_addr, | 1259 | unsigned int codec_addr, struct hda_codec **codecp) |
| 1201 | struct hda_codec **codecp) | ||
| 1202 | { | 1260 | { |
| 1203 | struct hda_codec *codec; | 1261 | struct hda_codec *codec; |
| 1204 | struct device *dev; | 1262 | struct device *dev; |
| @@ -1217,29 +1275,28 @@ int snd_hda_codec_new(struct hda_bus *bus, | |||
| 1217 | return -EINVAL; | 1275 | return -EINVAL; |
| 1218 | 1276 | ||
| 1219 | if (bus->caddr_tbl[codec_addr]) { | 1277 | if (bus->caddr_tbl[codec_addr]) { |
| 1220 | dev_err(bus->card->dev, | 1278 | dev_err(card->dev, |
| 1221 | "address 0x%x is already occupied\n", | 1279 | "address 0x%x is already occupied\n", |
| 1222 | codec_addr); | 1280 | codec_addr); |
| 1223 | return -EBUSY; | 1281 | return -EBUSY; |
| 1224 | } | 1282 | } |
| 1225 | 1283 | ||
| 1226 | codec = kzalloc(sizeof(*codec), GFP_KERNEL); | 1284 | codec = kzalloc(sizeof(*codec), GFP_KERNEL); |
| 1227 | if (codec == NULL) { | 1285 | if (!codec) |
| 1228 | dev_err(bus->card->dev, "can't allocate struct hda_codec\n"); | ||
| 1229 | return -ENOMEM; | 1286 | return -ENOMEM; |
| 1230 | } | ||
| 1231 | 1287 | ||
| 1232 | dev = hda_codec_dev(codec); | 1288 | dev = hda_codec_dev(codec); |
| 1233 | device_initialize(dev); | 1289 | device_initialize(dev); |
| 1234 | dev->parent = bus->card->dev; | 1290 | dev->parent = card->dev; |
| 1235 | dev->bus = &snd_hda_bus_type; | 1291 | dev->bus = &snd_hda_bus_type; |
| 1236 | dev->release = snd_hda_codec_dev_release; | 1292 | dev->release = snd_hda_codec_dev_release; |
| 1237 | dev->groups = snd_hda_dev_attr_groups; | 1293 | dev->groups = snd_hda_dev_attr_groups; |
| 1238 | dev_set_name(dev, "hdaudioC%dD%d", bus->card->number, codec_addr); | 1294 | dev_set_name(dev, "hdaudioC%dD%d", card->number, codec_addr); |
| 1239 | dev_set_drvdata(dev, codec); /* for sysfs */ | 1295 | dev_set_drvdata(dev, codec); /* for sysfs */ |
| 1240 | device_enable_async_suspend(dev); | 1296 | device_enable_async_suspend(dev); |
| 1241 | 1297 | ||
| 1242 | codec->bus = bus; | 1298 | codec->bus = bus; |
| 1299 | codec->card = card; | ||
| 1243 | codec->addr = codec_addr; | 1300 | codec->addr = codec_addr; |
| 1244 | mutex_init(&codec->spdif_mutex); | 1301 | mutex_init(&codec->spdif_mutex); |
| 1245 | mutex_init(&codec->control_mutex); | 1302 | mutex_init(&codec->control_mutex); |
| @@ -1255,6 +1312,7 @@ int snd_hda_codec_new(struct hda_bus *bus, | |||
| 1255 | snd_array_init(&codec->jacktbl, sizeof(struct hda_jack_tbl), 16); | 1312 | snd_array_init(&codec->jacktbl, sizeof(struct hda_jack_tbl), 16); |
| 1256 | snd_array_init(&codec->verbs, sizeof(struct hda_verb *), 8); | 1313 | snd_array_init(&codec->verbs, sizeof(struct hda_verb *), 8); |
| 1257 | INIT_LIST_HEAD(&codec->conn_list); | 1314 | INIT_LIST_HEAD(&codec->conn_list); |
| 1315 | INIT_LIST_HEAD(&codec->pcm_list_head); | ||
| 1258 | 1316 | ||
| 1259 | INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work); | 1317 | INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work); |
| 1260 | codec->depop_delay = -1; | 1318 | codec->depop_delay = -1; |
| @@ -1300,17 +1358,15 @@ int snd_hda_codec_new(struct hda_bus *bus, | |||
| 1300 | 1358 | ||
| 1301 | setup_fg_nodes(codec); | 1359 | setup_fg_nodes(codec); |
| 1302 | if (!codec->afg && !codec->mfg) { | 1360 | if (!codec->afg && !codec->mfg) { |
| 1303 | dev_err(bus->card->dev, "no AFG or MFG node found\n"); | 1361 | codec_err(codec, "no AFG or MFG node found\n"); |
| 1304 | err = -ENODEV; | 1362 | err = -ENODEV; |
| 1305 | goto error; | 1363 | goto error; |
| 1306 | } | 1364 | } |
| 1307 | 1365 | ||
| 1308 | fg = codec->afg ? codec->afg : codec->mfg; | 1366 | fg = codec->afg ? codec->afg : codec->mfg; |
| 1309 | err = read_widget_caps(codec, fg); | 1367 | err = read_widget_caps(codec, fg); |
| 1310 | if (err < 0) { | 1368 | if (err < 0) |
| 1311 | dev_err(bus->card->dev, "cannot malloc\n"); | ||
| 1312 | goto error; | 1369 | goto error; |
| 1313 | } | ||
| 1314 | err = read_pin_defaults(codec); | 1370 | err = read_pin_defaults(codec); |
| 1315 | if (err < 0) | 1371 | if (err < 0) |
| 1316 | goto error; | 1372 | goto error; |
| @@ -1337,9 +1393,9 @@ int snd_hda_codec_new(struct hda_bus *bus, | |||
| 1337 | 1393 | ||
| 1338 | sprintf(component, "HDA:%08x,%08x,%08x", codec->vendor_id, | 1394 | sprintf(component, "HDA:%08x,%08x,%08x", codec->vendor_id, |
| 1339 | codec->subsystem_id, codec->revision_id); | 1395 | codec->subsystem_id, codec->revision_id); |
| 1340 | snd_component_add(codec->bus->card, component); | 1396 | snd_component_add(card, component); |
| 1341 | 1397 | ||
| 1342 | err = snd_device_new(bus->card, SNDRV_DEV_CODEC, codec, &dev_ops); | 1398 | err = snd_device_new(card, SNDRV_DEV_CODEC, codec, &dev_ops); |
| 1343 | if (err < 0) | 1399 | if (err < 0) |
| 1344 | goto error; | 1400 | goto error; |
| 1345 | 1401 | ||
| @@ -1348,7 +1404,7 @@ int snd_hda_codec_new(struct hda_bus *bus, | |||
| 1348 | return 0; | 1404 | return 0; |
| 1349 | 1405 | ||
| 1350 | error: | 1406 | error: |
| 1351 | snd_hda_codec_free(codec); | 1407 | put_device(hda_codec_dev(codec)); |
| 1352 | return err; | 1408 | return err; |
| 1353 | } | 1409 | } |
| 1354 | EXPORT_SYMBOL_GPL(snd_hda_codec_new); | 1410 | EXPORT_SYMBOL_GPL(snd_hda_codec_new); |
| @@ -1371,10 +1427,8 @@ int snd_hda_codec_update_widgets(struct hda_codec *codec) | |||
| 1371 | kfree(codec->wcaps); | 1427 | kfree(codec->wcaps); |
| 1372 | fg = codec->afg ? codec->afg : codec->mfg; | 1428 | fg = codec->afg ? codec->afg : codec->mfg; |
| 1373 | err = read_widget_caps(codec, fg); | 1429 | err = read_widget_caps(codec, fg); |
| 1374 | if (err < 0) { | 1430 | if (err < 0) |
| 1375 | codec_err(codec, "cannot malloc\n"); | ||
| 1376 | return err; | 1431 | return err; |
| 1377 | } | ||
| 1378 | 1432 | ||
| 1379 | snd_array_free(&codec->init_pins); | 1433 | snd_array_free(&codec->init_pins); |
| 1380 | err = read_pin_defaults(codec); | 1434 | err = read_pin_defaults(codec); |
| @@ -2237,7 +2291,7 @@ find_mixer_ctl(struct hda_codec *codec, const char *name, int dev, int idx) | |||
| 2237 | if (snd_BUG_ON(strlen(name) >= sizeof(id.name))) | 2291 | if (snd_BUG_ON(strlen(name) >= sizeof(id.name))) |
| 2238 | return NULL; | 2292 | return NULL; |
| 2239 | strcpy(id.name, name); | 2293 | strcpy(id.name, name); |
| 2240 | return snd_ctl_find_id(codec->bus->card, &id); | 2294 | return snd_ctl_find_id(codec->card, &id); |
| 2241 | } | 2295 | } |
| 2242 | 2296 | ||
| 2243 | /** | 2297 | /** |
| @@ -2301,7 +2355,7 @@ int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid, | |||
| 2301 | nid = kctl->id.subdevice & 0xffff; | 2355 | nid = kctl->id.subdevice & 0xffff; |
| 2302 | if (kctl->id.subdevice & (HDA_SUBDEV_NID_FLAG|HDA_SUBDEV_AMP_FLAG)) | 2356 | if (kctl->id.subdevice & (HDA_SUBDEV_NID_FLAG|HDA_SUBDEV_AMP_FLAG)) |
| 2303 | kctl->id.subdevice = 0; | 2357 | kctl->id.subdevice = 0; |
| 2304 | err = snd_ctl_add(codec->bus->card, kctl); | 2358 | err = snd_ctl_add(codec->card, kctl); |
| 2305 | if (err < 0) | 2359 | if (err < 0) |
| 2306 | return err; | 2360 | return err; |
| 2307 | item = snd_array_new(&codec->mixers); | 2361 | item = snd_array_new(&codec->mixers); |
| @@ -2354,7 +2408,7 @@ void snd_hda_ctls_clear(struct hda_codec *codec) | |||
| 2354 | int i; | 2408 | int i; |
| 2355 | struct hda_nid_item *items = codec->mixers.list; | 2409 | struct hda_nid_item *items = codec->mixers.list; |
| 2356 | for (i = 0; i < codec->mixers.used; i++) | 2410 | for (i = 0; i < codec->mixers.used; i++) |
| 2357 | snd_ctl_remove(codec->bus->card, items[i].kctl); | 2411 | snd_ctl_remove(codec->card, items[i].kctl); |
| 2358 | snd_array_free(&codec->mixers); | 2412 | snd_array_free(&codec->mixers); |
| 2359 | snd_array_free(&codec->nids); | 2413 | snd_array_free(&codec->nids); |
| 2360 | } | 2414 | } |
| @@ -2378,9 +2432,8 @@ int snd_hda_lock_devices(struct hda_bus *bus) | |||
| 2378 | goto err_clear; | 2432 | goto err_clear; |
| 2379 | 2433 | ||
| 2380 | list_for_each_entry(codec, &bus->codec_list, list) { | 2434 | list_for_each_entry(codec, &bus->codec_list, list) { |
| 2381 | int pcm; | 2435 | struct hda_pcm *cpcm; |
| 2382 | for (pcm = 0; pcm < codec->num_pcms; pcm++) { | 2436 | list_for_each_entry(cpcm, &codec->pcm_list_head, list) { |
| 2383 | struct hda_pcm *cpcm = &codec->pcm_info[pcm]; | ||
| 2384 | if (!cpcm->pcm) | 2437 | if (!cpcm->pcm) |
| 2385 | continue; | 2438 | continue; |
| 2386 | if (cpcm->pcm->streams[0].substream_opened || | 2439 | if (cpcm->pcm->streams[0].substream_opened || |
| @@ -2407,7 +2460,6 @@ void snd_hda_unlock_devices(struct hda_bus *bus) | |||
| 2407 | { | 2460 | { |
| 2408 | struct snd_card *card = bus->card; | 2461 | struct snd_card *card = bus->card; |
| 2409 | 2462 | ||
| 2410 | card = bus->card; | ||
| 2411 | spin_lock(&card->files_lock); | 2463 | spin_lock(&card->files_lock); |
| 2412 | card->shutdown = 0; | 2464 | card->shutdown = 0; |
| 2413 | spin_unlock(&card->files_lock); | 2465 | spin_unlock(&card->files_lock); |
| @@ -2427,47 +2479,14 @@ EXPORT_SYMBOL_GPL(snd_hda_unlock_devices); | |||
| 2427 | int snd_hda_codec_reset(struct hda_codec *codec) | 2479 | int snd_hda_codec_reset(struct hda_codec *codec) |
| 2428 | { | 2480 | { |
| 2429 | struct hda_bus *bus = codec->bus; | 2481 | struct hda_bus *bus = codec->bus; |
| 2430 | struct snd_card *card = bus->card; | ||
| 2431 | int i; | ||
| 2432 | 2482 | ||
| 2433 | if (snd_hda_lock_devices(bus) < 0) | 2483 | if (snd_hda_lock_devices(bus) < 0) |
| 2434 | return -EBUSY; | 2484 | return -EBUSY; |
| 2435 | 2485 | ||
| 2436 | /* OK, let it free */ | 2486 | /* OK, let it free */ |
| 2437 | cancel_delayed_work_sync(&codec->jackpoll_work); | ||
| 2438 | flush_workqueue(bus->workq); | ||
| 2439 | snd_hda_ctls_clear(codec); | ||
| 2440 | /* release PCMs */ | ||
| 2441 | for (i = 0; i < codec->num_pcms; i++) { | ||
| 2442 | if (codec->pcm_info[i].pcm) { | ||
| 2443 | snd_device_free(card, codec->pcm_info[i].pcm); | ||
| 2444 | clear_bit(codec->pcm_info[i].device, | ||
| 2445 | bus->pcm_dev_bits); | ||
| 2446 | } | ||
| 2447 | } | ||
| 2448 | snd_hda_detach_beep_device(codec); | ||
| 2449 | if (device_is_registered(hda_codec_dev(codec))) | 2487 | if (device_is_registered(hda_codec_dev(codec))) |
| 2450 | device_del(hda_codec_dev(codec)); | 2488 | device_del(hda_codec_dev(codec)); |
| 2451 | 2489 | ||
| 2452 | memset(&codec->patch_ops, 0, sizeof(codec->patch_ops)); | ||
| 2453 | snd_hda_jack_tbl_clear(codec); | ||
| 2454 | codec->proc_widget_hook = NULL; | ||
| 2455 | codec->spec = NULL; | ||
| 2456 | free_hda_cache(&codec->amp_cache); | ||
| 2457 | free_hda_cache(&codec->cmd_cache); | ||
| 2458 | init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); | ||
| 2459 | init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); | ||
| 2460 | /* free only driver_pins so that init_pins + user_pins are restored */ | ||
| 2461 | snd_array_free(&codec->driver_pins); | ||
| 2462 | snd_array_free(&codec->cvt_setups); | ||
| 2463 | snd_array_free(&codec->spdif_out); | ||
| 2464 | snd_array_free(&codec->verbs); | ||
| 2465 | codec->num_pcms = 0; | ||
| 2466 | codec->pcm_info = NULL; | ||
| 2467 | codec->preset = NULL; | ||
| 2468 | codec->slave_dig_outs = NULL; | ||
| 2469 | codec->spdif_status_reset = 0; | ||
| 2470 | |||
| 2471 | /* allow device access again */ | 2490 | /* allow device access again */ |
| 2472 | snd_hda_unlock_devices(bus); | 2491 | snd_hda_unlock_devices(bus); |
| 2473 | return 0; | 2492 | return 0; |
| @@ -3960,12 +3979,12 @@ static void hda_call_codec_resume(struct hda_codec *codec) | |||
| 3960 | static int hda_codec_runtime_suspend(struct device *dev) | 3979 | static int hda_codec_runtime_suspend(struct device *dev) |
| 3961 | { | 3980 | { |
| 3962 | struct hda_codec *codec = dev_to_hda_codec(dev); | 3981 | struct hda_codec *codec = dev_to_hda_codec(dev); |
| 3982 | struct hda_pcm *pcm; | ||
| 3963 | unsigned int state; | 3983 | unsigned int state; |
| 3964 | int i; | ||
| 3965 | 3984 | ||
| 3966 | cancel_delayed_work_sync(&codec->jackpoll_work); | 3985 | cancel_delayed_work_sync(&codec->jackpoll_work); |
| 3967 | for (i = 0; i < codec->num_pcms; i++) | 3986 | list_for_each_entry(pcm, &codec->pcm_list_head, list) |
| 3968 | snd_pcm_suspend_all(codec->pcm_info[i].pcm); | 3987 | snd_pcm_suspend_all(pcm->pcm); |
| 3969 | state = hda_call_codec_suspend(codec); | 3988 | state = hda_call_codec_suspend(codec); |
| 3970 | if (codec->d3_stop_clk && codec->epss && (state & AC_PWRST_CLK_STOP_OK)) | 3989 | if (codec->d3_stop_clk && codec->epss && (state & AC_PWRST_CLK_STOP_OK)) |
| 3971 | clear_bit(codec->addr, &codec->bus->codec_powered); | 3990 | clear_bit(codec->addr, &codec->bus->codec_powered); |
| @@ -3991,57 +4010,26 @@ const struct dev_pm_ops hda_codec_driver_pm = { | |||
| 3991 | NULL) | 4010 | NULL) |
| 3992 | }; | 4011 | }; |
| 3993 | 4012 | ||
| 3994 | /** | ||
| 3995 | * snd_hda_build_controls - build mixer controls | ||
| 3996 | * @bus: the BUS | ||
| 3997 | * | ||
| 3998 | * Creates mixer controls for each codec included in the bus. | ||
| 3999 | * | ||
| 4000 | * Returns 0 if successful, otherwise a negative error code. | ||
| 4001 | */ | ||
| 4002 | int snd_hda_build_controls(struct hda_bus *bus) | ||
| 4003 | { | ||
| 4004 | struct hda_codec *codec; | ||
| 4005 | |||
| 4006 | list_for_each_entry(codec, &bus->codec_list, list) { | ||
| 4007 | int err = snd_hda_codec_build_controls(codec); | ||
| 4008 | if (err < 0) { | ||
| 4009 | codec_err(codec, | ||
| 4010 | "cannot build controls for #%d (error %d)\n", | ||
| 4011 | codec->addr, err); | ||
| 4012 | err = snd_hda_codec_reset(codec); | ||
| 4013 | if (err < 0) { | ||
| 4014 | codec_err(codec, | ||
| 4015 | "cannot revert codec\n"); | ||
| 4016 | return err; | ||
| 4017 | } | ||
| 4018 | } | ||
| 4019 | } | ||
| 4020 | return 0; | ||
| 4021 | } | ||
| 4022 | EXPORT_SYMBOL_GPL(snd_hda_build_controls); | ||
| 4023 | |||
| 4024 | /* | 4013 | /* |
| 4025 | * add standard channel maps if not specified | 4014 | * add standard channel maps if not specified |
| 4026 | */ | 4015 | */ |
| 4027 | static int add_std_chmaps(struct hda_codec *codec) | 4016 | static int add_std_chmaps(struct hda_codec *codec) |
| 4028 | { | 4017 | { |
| 4029 | int i, str, err; | 4018 | struct hda_pcm *pcm; |
| 4019 | int str, err; | ||
| 4030 | 4020 | ||
| 4031 | for (i = 0; i < codec->num_pcms; i++) { | 4021 | list_for_each_entry(pcm, &codec->pcm_list_head, list) { |
| 4032 | for (str = 0; str < 2; str++) { | 4022 | for (str = 0; str < 2; str++) { |
| 4033 | struct snd_pcm *pcm = codec->pcm_info[i].pcm; | 4023 | struct hda_pcm_stream *hinfo = &pcm->stream[str]; |
| 4034 | struct hda_pcm_stream *hinfo = | ||
| 4035 | &codec->pcm_info[i].stream[str]; | ||
| 4036 | struct snd_pcm_chmap *chmap; | 4024 | struct snd_pcm_chmap *chmap; |
| 4037 | const struct snd_pcm_chmap_elem *elem; | 4025 | const struct snd_pcm_chmap_elem *elem; |
| 4038 | 4026 | ||
| 4039 | if (codec->pcm_info[i].own_chmap) | 4027 | if (pcm->own_chmap) |
| 4040 | continue; | 4028 | continue; |
| 4041 | if (!pcm || !hinfo->substreams) | 4029 | if (!pcm || !hinfo->substreams) |
| 4042 | continue; | 4030 | continue; |
| 4043 | elem = hinfo->chmap ? hinfo->chmap : snd_pcm_std_chmaps; | 4031 | elem = hinfo->chmap ? hinfo->chmap : snd_pcm_std_chmaps; |
| 4044 | err = snd_pcm_add_chmap_ctls(pcm, str, elem, | 4032 | err = snd_pcm_add_chmap_ctls(pcm->pcm, str, elem, |
| 4045 | hinfo->channels_max, | 4033 | hinfo->channels_max, |
| 4046 | 0, &chmap); | 4034 | 0, &chmap); |
| 4047 | if (err < 0) | 4035 | if (err < 0) |
| @@ -4490,7 +4478,11 @@ int snd_hda_codec_prepare(struct hda_codec *codec, | |||
| 4490 | { | 4478 | { |
| 4491 | int ret; | 4479 | int ret; |
| 4492 | mutex_lock(&codec->bus->prepare_mutex); | 4480 | mutex_lock(&codec->bus->prepare_mutex); |
| 4493 | ret = hinfo->ops.prepare(hinfo, codec, stream, format, substream); | 4481 | if (hinfo->ops.prepare) |
| 4482 | ret = hinfo->ops.prepare(hinfo, codec, stream, format, | ||
| 4483 | substream); | ||
| 4484 | else | ||
| 4485 | ret = -ENODEV; | ||
| 4494 | if (ret >= 0) | 4486 | if (ret >= 0) |
| 4495 | purify_inactive_streams(codec); | 4487 | purify_inactive_streams(codec); |
| 4496 | mutex_unlock(&codec->bus->prepare_mutex); | 4488 | mutex_unlock(&codec->bus->prepare_mutex); |
| @@ -4511,7 +4503,8 @@ void snd_hda_codec_cleanup(struct hda_codec *codec, | |||
| 4511 | struct snd_pcm_substream *substream) | 4503 | struct snd_pcm_substream *substream) |
| 4512 | { | 4504 | { |
| 4513 | mutex_lock(&codec->bus->prepare_mutex); | 4505 | mutex_lock(&codec->bus->prepare_mutex); |
| 4514 | hinfo->ops.cleanup(hinfo, codec, substream); | 4506 | if (hinfo->ops.cleanup) |
| 4507 | hinfo->ops.cleanup(hinfo, codec, substream); | ||
| 4515 | mutex_unlock(&codec->bus->prepare_mutex); | 4508 | mutex_unlock(&codec->bus->prepare_mutex); |
| 4516 | } | 4509 | } |
| 4517 | EXPORT_SYMBOL_GPL(snd_hda_codec_cleanup); | 4510 | EXPORT_SYMBOL_GPL(snd_hda_codec_cleanup); |
| @@ -4569,112 +4562,84 @@ static int get_empty_pcm_device(struct hda_bus *bus, unsigned int type) | |||
| 4569 | return -EAGAIN; | 4562 | return -EAGAIN; |
| 4570 | } | 4563 | } |
| 4571 | 4564 | ||
| 4572 | /* | 4565 | /* call build_pcms ops of the given codec and set up the default parameters */ |
| 4573 | * attach a new PCM stream | 4566 | int snd_hda_codec_parse_pcms(struct hda_codec *codec) |
| 4574 | */ | ||
| 4575 | static int snd_hda_attach_pcm(struct hda_codec *codec, struct hda_pcm *pcm) | ||
| 4576 | { | 4567 | { |
| 4577 | struct hda_bus *bus = codec->bus; | 4568 | struct hda_pcm *cpcm; |
| 4578 | struct hda_pcm_stream *info; | 4569 | int err; |
| 4579 | int stream, err; | ||
| 4580 | 4570 | ||
| 4581 | if (snd_BUG_ON(!pcm->name)) | 4571 | if (!list_empty(&codec->pcm_list_head)) |
| 4582 | return -EINVAL; | 4572 | return 0; /* already parsed */ |
| 4583 | for (stream = 0; stream < 2; stream++) { | 4573 | |
| 4584 | info = &pcm->stream[stream]; | 4574 | if (!codec->patch_ops.build_pcms) |
| 4585 | if (info->substreams) { | 4575 | return 0; |
| 4576 | |||
| 4577 | err = codec->patch_ops.build_pcms(codec); | ||
| 4578 | if (err < 0) { | ||
| 4579 | codec_err(codec, "cannot build PCMs for #%d (error %d)\n", | ||
| 4580 | codec->addr, err); | ||
| 4581 | return err; | ||
| 4582 | } | ||
| 4583 | |||
| 4584 | list_for_each_entry(cpcm, &codec->pcm_list_head, list) { | ||
| 4585 | int stream; | ||
| 4586 | |||
| 4587 | for (stream = 0; stream < 2; stream++) { | ||
| 4588 | struct hda_pcm_stream *info = &cpcm->stream[stream]; | ||
| 4589 | |||
| 4590 | if (!info->substreams) | ||
| 4591 | continue; | ||
| 4586 | err = set_pcm_default_values(codec, info); | 4592 | err = set_pcm_default_values(codec, info); |
| 4587 | if (err < 0) | 4593 | if (err < 0) { |
| 4594 | codec_warn(codec, | ||
| 4595 | "fail to setup default for PCM %s\n", | ||
| 4596 | cpcm->name); | ||
| 4588 | return err; | 4597 | return err; |
| 4598 | } | ||
| 4589 | } | 4599 | } |
| 4590 | } | 4600 | } |
| 4591 | return bus->ops.attach_pcm(bus, codec, pcm); | 4601 | |
| 4602 | return 0; | ||
| 4592 | } | 4603 | } |
| 4593 | 4604 | ||
| 4594 | /* assign all PCMs of the given codec */ | 4605 | /* assign all PCMs of the given codec */ |
| 4595 | int snd_hda_codec_build_pcms(struct hda_codec *codec) | 4606 | int snd_hda_codec_build_pcms(struct hda_codec *codec) |
| 4596 | { | 4607 | { |
| 4597 | unsigned int pcm; | 4608 | struct hda_bus *bus = codec->bus; |
| 4598 | int err; | 4609 | struct hda_pcm *cpcm; |
| 4610 | int dev, err; | ||
| 4599 | 4611 | ||
| 4600 | if (!codec->num_pcms) { | 4612 | if (snd_BUG_ON(!bus->ops.attach_pcm)) |
| 4601 | if (!codec->patch_ops.build_pcms) | 4613 | return -EINVAL; |
| 4602 | return 0; | 4614 | |
| 4603 | err = codec->patch_ops.build_pcms(codec); | 4615 | err = snd_hda_codec_parse_pcms(codec); |
| 4604 | if (err < 0) { | 4616 | if (err < 0) { |
| 4605 | codec_err(codec, | 4617 | snd_hda_codec_reset(codec); |
| 4606 | "cannot build PCMs for #%d (error %d)\n", | 4618 | return err; |
| 4607 | codec->addr, err); | ||
| 4608 | err = snd_hda_codec_reset(codec); | ||
| 4609 | if (err < 0) { | ||
| 4610 | codec_err(codec, | ||
| 4611 | "cannot revert codec\n"); | ||
| 4612 | return err; | ||
| 4613 | } | ||
| 4614 | } | ||
| 4615 | } | 4619 | } |
| 4616 | for (pcm = 0; pcm < codec->num_pcms; pcm++) { | ||
| 4617 | struct hda_pcm *cpcm = &codec->pcm_info[pcm]; | ||
| 4618 | int dev; | ||
| 4619 | 4620 | ||
| 4621 | /* attach a new PCM streams */ | ||
| 4622 | list_for_each_entry(cpcm, &codec->pcm_list_head, list) { | ||
| 4623 | if (cpcm->pcm) | ||
| 4624 | continue; /* already attached */ | ||
| 4620 | if (!cpcm->stream[0].substreams && !cpcm->stream[1].substreams) | 4625 | if (!cpcm->stream[0].substreams && !cpcm->stream[1].substreams) |
| 4621 | continue; /* no substreams assigned */ | 4626 | continue; /* no substreams assigned */ |
| 4622 | 4627 | ||
| 4623 | if (!cpcm->pcm) { | 4628 | dev = get_empty_pcm_device(bus, cpcm->pcm_type); |
| 4624 | dev = get_empty_pcm_device(codec->bus, cpcm->pcm_type); | 4629 | if (dev < 0) |
| 4625 | if (dev < 0) | 4630 | continue; /* no fatal error */ |
| 4626 | continue; /* no fatal error */ | 4631 | cpcm->device = dev; |
| 4627 | cpcm->device = dev; | 4632 | err = bus->ops.attach_pcm(bus, codec, cpcm); |
| 4628 | err = snd_hda_attach_pcm(codec, cpcm); | 4633 | if (err < 0) { |
| 4629 | if (err < 0) { | 4634 | codec_err(codec, |
| 4630 | codec_err(codec, | 4635 | "cannot attach PCM stream %d for codec #%d\n", |
| 4631 | "cannot attach PCM stream %d for codec #%d\n", | 4636 | dev, codec->addr); |
| 4632 | dev, codec->addr); | 4637 | continue; /* no fatal error */ |
| 4633 | continue; /* no fatal error */ | ||
| 4634 | } | ||
| 4635 | } | 4638 | } |
| 4636 | } | 4639 | } |
| 4637 | return 0; | ||
| 4638 | } | ||
| 4639 | 4640 | ||
| 4640 | /** | ||
| 4641 | * snd_hda_build_pcms - build PCM information | ||
| 4642 | * @bus: the BUS | ||
| 4643 | * | ||
| 4644 | * Create PCM information for each codec included in the bus. | ||
| 4645 | * | ||
| 4646 | * The build_pcms codec patch is requested to set up codec->num_pcms and | ||
| 4647 | * codec->pcm_info properly. The array is referred by the top-level driver | ||
| 4648 | * to create its PCM instances. | ||
| 4649 | * The allocated codec->pcm_info should be released in codec->patch_ops.free | ||
| 4650 | * callback. | ||
| 4651 | * | ||
| 4652 | * At least, substreams, channels_min and channels_max must be filled for | ||
| 4653 | * each stream. substreams = 0 indicates that the stream doesn't exist. | ||
| 4654 | * When rates and/or formats are zero, the supported values are queried | ||
| 4655 | * from the given nid. The nid is used also by the default ops.prepare | ||
| 4656 | * and ops.cleanup callbacks. | ||
| 4657 | * | ||
| 4658 | * The driver needs to call ops.open in its open callback. Similarly, | ||
| 4659 | * ops.close is supposed to be called in the close callback. | ||
| 4660 | * ops.prepare should be called in the prepare or hw_params callback | ||
| 4661 | * with the proper parameters for set up. | ||
| 4662 | * ops.cleanup should be called in hw_free for clean up of streams. | ||
| 4663 | * | ||
| 4664 | * This function returns 0 if successful, or a negative error code. | ||
| 4665 | */ | ||
| 4666 | int snd_hda_build_pcms(struct hda_bus *bus) | ||
| 4667 | { | ||
| 4668 | struct hda_codec *codec; | ||
| 4669 | |||
| 4670 | list_for_each_entry(codec, &bus->codec_list, list) { | ||
| 4671 | int err = snd_hda_codec_build_pcms(codec); | ||
| 4672 | if (err < 0) | ||
| 4673 | return err; | ||
| 4674 | } | ||
| 4675 | return 0; | 4641 | return 0; |
| 4676 | } | 4642 | } |
| 4677 | EXPORT_SYMBOL_GPL(snd_hda_build_pcms); | ||
| 4678 | 4643 | ||
| 4679 | /** | 4644 | /** |
| 4680 | * snd_hda_add_new_ctls - create controls from the array | 4645 | * snd_hda_add_new_ctls - create controls from the array |
| @@ -4977,24 +4942,6 @@ static void cleanup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid) | |||
| 4977 | } | 4942 | } |
| 4978 | 4943 | ||
| 4979 | /** | 4944 | /** |
| 4980 | * snd_hda_bus_reboot_notify - call the reboot notifier of each codec | ||
| 4981 | * @bus: HD-audio bus | ||
| 4982 | */ | ||
| 4983 | void snd_hda_bus_reboot_notify(struct hda_bus *bus) | ||
| 4984 | { | ||
| 4985 | struct hda_codec *codec; | ||
| 4986 | |||
| 4987 | if (!bus) | ||
| 4988 | return; | ||
| 4989 | list_for_each_entry(codec, &bus->codec_list, list) { | ||
| 4990 | if (hda_codec_is_power_on(codec) && | ||
| 4991 | codec->patch_ops.reboot_notify) | ||
| 4992 | codec->patch_ops.reboot_notify(codec); | ||
| 4993 | } | ||
| 4994 | } | ||
| 4995 | EXPORT_SYMBOL_GPL(snd_hda_bus_reboot_notify); | ||
| 4996 | |||
| 4997 | /** | ||
| 4998 | * snd_hda_multi_out_dig_open - open the digital out in the exclusive mode | 4945 | * snd_hda_multi_out_dig_open - open the digital out in the exclusive mode |
| 4999 | * @codec: the HDA codec | 4946 | * @codec: the HDA codec |
| 5000 | * @mout: hda_multi_out object | 4947 | * @mout: hda_multi_out object |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 457fc589eb46..70851e6d5f10 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> |
| @@ -131,8 +132,6 @@ struct hda_bus { | |||
| 131 | 132 | ||
| 132 | /* unsolicited event queue */ | 133 | /* unsolicited event queue */ |
| 133 | struct hda_bus_unsolicited unsol; | 134 | struct hda_bus_unsolicited unsol; |
| 134 | char workq_name[16]; | ||
| 135 | struct workqueue_struct *workq; /* common workqueue for codecs */ | ||
| 136 | 135 | ||
| 137 | /* assigned PCMs */ | 136 | /* assigned PCMs */ |
| 138 | DECLARE_BITMAP(pcm_dev_bits, SNDRV_PCM_DEVICES); | 137 | DECLARE_BITMAP(pcm_dev_bits, SNDRV_PCM_DEVICES); |
| @@ -268,12 +267,17 @@ struct hda_pcm { | |||
| 268 | int device; /* device number to assign */ | 267 | int device; /* device number to assign */ |
| 269 | struct snd_pcm *pcm; /* assigned PCM instance */ | 268 | struct snd_pcm *pcm; /* assigned PCM instance */ |
| 270 | bool own_chmap; /* codec driver provides own channel maps */ | 269 | bool own_chmap; /* codec driver provides own channel maps */ |
| 270 | /* private: */ | ||
| 271 | struct hda_codec *codec; | ||
| 272 | struct kref kref; | ||
| 273 | struct list_head list; | ||
| 271 | }; | 274 | }; |
| 272 | 275 | ||
| 273 | /* codec information */ | 276 | /* codec information */ |
| 274 | struct hda_codec { | 277 | struct hda_codec { |
| 275 | struct device dev; | 278 | struct device dev; |
| 276 | struct hda_bus *bus; | 279 | struct hda_bus *bus; |
| 280 | struct snd_card *card; | ||
| 277 | unsigned int addr; /* codec addr*/ | 281 | unsigned int addr; /* codec addr*/ |
| 278 | struct list_head list; /* list point */ | 282 | struct list_head list; /* list point */ |
| 279 | 283 | ||
| @@ -300,8 +304,7 @@ struct hda_codec { | |||
| 300 | struct hda_codec_ops patch_ops; | 304 | struct hda_codec_ops patch_ops; |
| 301 | 305 | ||
| 302 | /* PCM to create, set by patch_ops.build_pcms callback */ | 306 | /* PCM to create, set by patch_ops.build_pcms callback */ |
| 303 | unsigned int num_pcms; | 307 | struct list_head pcm_list_head; |
| 304 | struct hda_pcm *pcm_info; | ||
| 305 | 308 | ||
| 306 | /* codec specific info */ | 309 | /* codec specific info */ |
| 307 | void *spec; | 310 | void *spec; |
| @@ -345,6 +348,7 @@ struct hda_codec { | |||
| 345 | #endif | 348 | #endif |
| 346 | 349 | ||
| 347 | /* misc flags */ | 350 | /* misc flags */ |
| 351 | unsigned int in_freeing:1; /* being released */ | ||
| 348 | unsigned int spdif_status_reset :1; /* needs to toggle SPDIF for each | 352 | unsigned int spdif_status_reset :1; /* needs to toggle SPDIF for each |
| 349 | * status change | 353 | * status change |
| 350 | * (e.g. Realtek codecs) | 354 | * (e.g. Realtek codecs) |
| @@ -420,8 +424,8 @@ enum { | |||
| 420 | * constructors | 424 | * constructors |
| 421 | */ | 425 | */ |
| 422 | int snd_hda_bus_new(struct snd_card *card, struct hda_bus **busp); | 426 | int snd_hda_bus_new(struct snd_card *card, struct hda_bus **busp); |
| 423 | int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, | 427 | int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card, |
| 424 | struct hda_codec **codecp); | 428 | unsigned int codec_addr, struct hda_codec **codecp); |
| 425 | int snd_hda_codec_configure(struct hda_codec *codec); | 429 | int snd_hda_codec_configure(struct hda_codec *codec); |
| 426 | int snd_hda_codec_update_widgets(struct hda_codec *codec); | 430 | int snd_hda_codec_update_widgets(struct hda_codec *codec); |
| 427 | 431 | ||
| @@ -510,15 +514,24 @@ void snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid); | |||
| 510 | /* | 514 | /* |
| 511 | * Mixer | 515 | * Mixer |
| 512 | */ | 516 | */ |
| 513 | int snd_hda_build_controls(struct hda_bus *bus); | ||
| 514 | int snd_hda_codec_build_controls(struct hda_codec *codec); | 517 | int snd_hda_codec_build_controls(struct hda_codec *codec); |
| 515 | 518 | ||
| 516 | /* | 519 | /* |
| 517 | * PCM | 520 | * PCM |
| 518 | */ | 521 | */ |
| 519 | int snd_hda_build_pcms(struct hda_bus *bus); | 522 | int snd_hda_codec_parse_pcms(struct hda_codec *codec); |
| 520 | int snd_hda_codec_build_pcms(struct hda_codec *codec); | 523 | int snd_hda_codec_build_pcms(struct hda_codec *codec); |
| 521 | 524 | ||
| 525 | __printf(2, 3) | ||
| 526 | struct hda_pcm *snd_hda_codec_pcm_new(struct hda_codec *codec, | ||
| 527 | const char *fmt, ...); | ||
| 528 | |||
| 529 | static inline void snd_hda_codec_pcm_get(struct hda_pcm *pcm) | ||
| 530 | { | ||
| 531 | kref_get(&pcm->kref); | ||
| 532 | } | ||
| 533 | void snd_hda_codec_pcm_put(struct hda_pcm *pcm); | ||
| 534 | |||
| 522 | int snd_hda_codec_prepare(struct hda_codec *codec, | 535 | int snd_hda_codec_prepare(struct hda_codec *codec, |
| 523 | struct hda_pcm_stream *hinfo, | 536 | struct hda_pcm_stream *hinfo, |
| 524 | unsigned int stream, | 537 | unsigned int stream, |
| @@ -550,7 +563,6 @@ extern const struct snd_pcm_chmap_elem snd_pcm_2_1_chmaps[]; | |||
| 550 | * Misc | 563 | * Misc |
| 551 | */ | 564 | */ |
| 552 | void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen); | 565 | void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen); |
| 553 | void snd_hda_bus_reboot_notify(struct hda_bus *bus); | ||
| 554 | void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg, | 566 | void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg, |
| 555 | unsigned int power_state); | 567 | unsigned int power_state); |
| 556 | 568 | ||
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c index a438e8540763..4fd0b2ef26e9 100644 --- a/sound/pci/hda/hda_controller.c +++ b/sound/pci/hda/hda_controller.c | |||
| @@ -27,7 +27,6 @@ | |||
| 27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
| 28 | #include <linux/pm_runtime.h> | 28 | #include <linux/pm_runtime.h> |
| 29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
| 30 | #include <linux/reboot.h> | ||
| 31 | #include <sound/core.h> | 30 | #include <sound/core.h> |
| 32 | #include <sound/initval.h> | 31 | #include <sound/initval.h> |
| 33 | #include "hda_controller.h" | 32 | #include "hda_controller.h" |
| @@ -416,9 +415,11 @@ static int azx_pcm_close(struct snd_pcm_substream *substream) | |||
| 416 | azx_dev->running = 0; | 415 | azx_dev->running = 0; |
| 417 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 416 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
| 418 | azx_release_device(azx_dev); | 417 | azx_release_device(azx_dev); |
| 419 | hinfo->ops.close(hinfo, apcm->codec, substream); | 418 | if (hinfo->ops.close) |
| 419 | hinfo->ops.close(hinfo, apcm->codec, substream); | ||
| 420 | snd_hda_power_down(apcm->codec); | 420 | snd_hda_power_down(apcm->codec); |
| 421 | mutex_unlock(&chip->open_mutex); | 421 | mutex_unlock(&chip->open_mutex); |
| 422 | snd_hda_codec_pcm_put(apcm->info); | ||
| 422 | return 0; | 423 | return 0; |
| 423 | } | 424 | } |
| 424 | 425 | ||
| @@ -805,11 +806,12 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |||
| 805 | int err; | 806 | int err; |
| 806 | int buff_step; | 807 | int buff_step; |
| 807 | 808 | ||
| 809 | snd_hda_codec_pcm_get(apcm->info); | ||
| 808 | mutex_lock(&chip->open_mutex); | 810 | mutex_lock(&chip->open_mutex); |
| 809 | azx_dev = azx_assign_device(chip, substream); | 811 | azx_dev = azx_assign_device(chip, substream); |
| 810 | if (azx_dev == NULL) { | 812 | if (azx_dev == NULL) { |
| 811 | mutex_unlock(&chip->open_mutex); | 813 | err = -EBUSY; |
| 812 | return -EBUSY; | 814 | goto unlock; |
| 813 | } | 815 | } |
| 814 | runtime->hw = azx_pcm_hw; | 816 | runtime->hw = azx_pcm_hw; |
| 815 | runtime->hw.channels_min = hinfo->channels_min; | 817 | runtime->hw.channels_min = hinfo->channels_min; |
| @@ -844,12 +846,13 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |||
| 844 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, | 846 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, |
| 845 | buff_step); | 847 | buff_step); |
| 846 | snd_hda_power_up(apcm->codec); | 848 | snd_hda_power_up(apcm->codec); |
| 847 | err = hinfo->ops.open(hinfo, apcm->codec, substream); | 849 | if (hinfo->ops.open) |
| 850 | err = hinfo->ops.open(hinfo, apcm->codec, substream); | ||
| 851 | else | ||
| 852 | err = -ENODEV; | ||
| 848 | if (err < 0) { | 853 | if (err < 0) { |
| 849 | azx_release_device(azx_dev); | 854 | azx_release_device(azx_dev); |
| 850 | snd_hda_power_down(apcm->codec); | 855 | goto powerdown; |
| 851 | mutex_unlock(&chip->open_mutex); | ||
| 852 | return err; | ||
| 853 | } | 856 | } |
| 854 | snd_pcm_limit_hw_rates(runtime); | 857 | snd_pcm_limit_hw_rates(runtime); |
| 855 | /* sanity check */ | 858 | /* sanity check */ |
| @@ -858,10 +861,10 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |||
| 858 | snd_BUG_ON(!runtime->hw.formats) || | 861 | snd_BUG_ON(!runtime->hw.formats) || |
| 859 | snd_BUG_ON(!runtime->hw.rates)) { | 862 | snd_BUG_ON(!runtime->hw.rates)) { |
| 860 | azx_release_device(azx_dev); | 863 | azx_release_device(azx_dev); |
| 861 | hinfo->ops.close(hinfo, apcm->codec, substream); | 864 | if (hinfo->ops.close) |
| 862 | snd_hda_power_down(apcm->codec); | 865 | hinfo->ops.close(hinfo, apcm->codec, substream); |
| 863 | mutex_unlock(&chip->open_mutex); | 866 | err = -EINVAL; |
| 864 | return -EINVAL; | 867 | goto powerdown; |
| 865 | } | 868 | } |
| 866 | 869 | ||
| 867 | /* disable LINK_ATIME timestamps for capture streams | 870 | /* disable LINK_ATIME timestamps for capture streams |
| @@ -880,6 +883,13 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |||
| 880 | snd_pcm_set_sync(substream); | 883 | snd_pcm_set_sync(substream); |
| 881 | mutex_unlock(&chip->open_mutex); | 884 | mutex_unlock(&chip->open_mutex); |
| 882 | return 0; | 885 | return 0; |
| 886 | |||
| 887 | powerdown: | ||
| 888 | snd_hda_power_down(apcm->codec); | ||
| 889 | unlock: | ||
| 890 | mutex_unlock(&chip->open_mutex); | ||
| 891 | snd_hda_codec_pcm_put(apcm->info); | ||
| 892 | return err; | ||
| 883 | } | 893 | } |
| 884 | 894 | ||
| 885 | static int azx_pcm_mmap(struct snd_pcm_substream *substream, | 895 | static int azx_pcm_mmap(struct snd_pcm_substream *substream, |
| @@ -974,14 +984,9 @@ static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, | |||
| 974 | */ | 984 | */ |
| 975 | static int azx_alloc_cmd_io(struct azx *chip) | 985 | static int azx_alloc_cmd_io(struct azx *chip) |
| 976 | { | 986 | { |
| 977 | int err; | ||
| 978 | |||
| 979 | /* single page (at least 4096 bytes) must suffice for both ringbuffes */ | 987 | /* single page (at least 4096 bytes) must suffice for both ringbuffes */ |
| 980 | err = chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV, | 988 | return chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV, |
| 981 | PAGE_SIZE, &chip->rb); | 989 | PAGE_SIZE, &chip->rb); |
| 982 | if (err < 0) | ||
| 983 | dev_err(chip->card->dev, "cannot allocate CORB/RIRB\n"); | ||
| 984 | return err; | ||
| 985 | } | 990 | } |
| 986 | 991 | ||
| 987 | static void azx_init_cmd_io(struct azx *chip) | 992 | static void azx_init_cmd_io(struct azx *chip) |
| @@ -1467,7 +1472,6 @@ static void azx_load_dsp_cleanup(struct hda_bus *bus, | |||
| 1467 | int azx_alloc_stream_pages(struct azx *chip) | 1472 | int azx_alloc_stream_pages(struct azx *chip) |
| 1468 | { | 1473 | { |
| 1469 | int i, err; | 1474 | int i, err; |
| 1470 | struct snd_card *card = chip->card; | ||
| 1471 | 1475 | ||
| 1472 | for (i = 0; i < chip->num_streams; i++) { | 1476 | for (i = 0; i < chip->num_streams; i++) { |
| 1473 | dsp_lock_init(&chip->azx_dev[i]); | 1477 | dsp_lock_init(&chip->azx_dev[i]); |
| @@ -1475,18 +1479,14 @@ int azx_alloc_stream_pages(struct azx *chip) | |||
| 1475 | err = chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV, | 1479 | err = chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV, |
| 1476 | BDL_SIZE, | 1480 | BDL_SIZE, |
| 1477 | &chip->azx_dev[i].bdl); | 1481 | &chip->azx_dev[i].bdl); |
| 1478 | if (err < 0) { | 1482 | if (err < 0) |
| 1479 | dev_err(card->dev, "cannot allocate BDL\n"); | ||
| 1480 | return -ENOMEM; | 1483 | return -ENOMEM; |
| 1481 | } | ||
| 1482 | } | 1484 | } |
| 1483 | /* allocate memory for the position buffer */ | 1485 | /* allocate memory for the position buffer */ |
| 1484 | err = chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV, | 1486 | err = chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV, |
| 1485 | chip->num_streams * 8, &chip->posbuf); | 1487 | chip->num_streams * 8, &chip->posbuf); |
| 1486 | if (err < 0) { | 1488 | if (err < 0) |
| 1487 | dev_err(card->dev, "cannot allocate posbuf\n"); | ||
| 1488 | return -ENOMEM; | 1489 | return -ENOMEM; |
| 1489 | } | ||
| 1490 | 1490 | ||
| 1491 | /* allocate CORB/RIRB */ | 1491 | /* allocate CORB/RIRB */ |
| 1492 | err = azx_alloc_cmd_io(chip); | 1492 | err = azx_alloc_cmd_io(chip); |
| @@ -1893,7 +1893,7 @@ int azx_probe_codecs(struct azx *chip, unsigned int max_slots) | |||
| 1893 | for (c = 0; c < max_slots; c++) { | 1893 | for (c = 0; c < max_slots; c++) { |
| 1894 | if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) { | 1894 | if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) { |
| 1895 | struct hda_codec *codec; | 1895 | struct hda_codec *codec; |
| 1896 | err = snd_hda_codec_new(bus, c, &codec); | 1896 | err = snd_hda_codec_new(bus, bus->card, c, &codec); |
| 1897 | if (err < 0) | 1897 | if (err < 0) |
| 1898 | continue; | 1898 | continue; |
| 1899 | codec->jackpoll_interval = get_jackpoll_interval(chip); | 1899 | codec->jackpoll_interval = get_jackpoll_interval(chip); |
| @@ -1966,30 +1966,5 @@ int azx_init_stream(struct azx *chip) | |||
| 1966 | } | 1966 | } |
| 1967 | EXPORT_SYMBOL_GPL(azx_init_stream); | 1967 | EXPORT_SYMBOL_GPL(azx_init_stream); |
| 1968 | 1968 | ||
| 1969 | /* | ||
| 1970 | * reboot notifier for hang-up problem at power-down | ||
| 1971 | */ | ||
| 1972 | static int azx_halt(struct notifier_block *nb, unsigned long event, void *buf) | ||
| 1973 | { | ||
| 1974 | struct azx *chip = container_of(nb, struct azx, reboot_notifier); | ||
| 1975 | snd_hda_bus_reboot_notify(chip->bus); | ||
| 1976 | azx_stop_chip(chip); | ||
| 1977 | return NOTIFY_OK; | ||
| 1978 | } | ||
| 1979 | |||
| 1980 | void azx_notifier_register(struct azx *chip) | ||
| 1981 | { | ||
| 1982 | chip->reboot_notifier.notifier_call = azx_halt; | ||
| 1983 | register_reboot_notifier(&chip->reboot_notifier); | ||
| 1984 | } | ||
| 1985 | EXPORT_SYMBOL_GPL(azx_notifier_register); | ||
| 1986 | |||
| 1987 | void azx_notifier_unregister(struct azx *chip) | ||
| 1988 | { | ||
| 1989 | if (chip->reboot_notifier.notifier_call) | ||
| 1990 | unregister_reboot_notifier(&chip->reboot_notifier); | ||
| 1991 | } | ||
| 1992 | EXPORT_SYMBOL_GPL(azx_notifier_unregister); | ||
| 1993 | |||
| 1994 | MODULE_LICENSE("GPL"); | 1969 | MODULE_LICENSE("GPL"); |
| 1995 | MODULE_DESCRIPTION("Common HDA driver functions"); | 1970 | MODULE_DESCRIPTION("Common HDA driver functions"); |
diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h index 94c1a4719f7f..be1b7ded8d82 100644 --- a/sound/pci/hda/hda_controller.h +++ b/sound/pci/hda/hda_controller.h | |||
| @@ -362,9 +362,6 @@ struct azx { | |||
| 362 | /* for debugging */ | 362 | /* for debugging */ |
| 363 | unsigned int last_cmd[AZX_MAX_CODECS]; | 363 | unsigned int last_cmd[AZX_MAX_CODECS]; |
| 364 | 364 | ||
| 365 | /* reboot notifier (for mysterious hangup problem at power-down) */ | ||
| 366 | struct notifier_block reboot_notifier; | ||
| 367 | |||
| 368 | #ifdef CONFIG_SND_HDA_DSP_LOADER | 365 | #ifdef CONFIG_SND_HDA_DSP_LOADER |
| 369 | struct azx_dev saved_azx_dev; | 366 | struct azx_dev saved_azx_dev; |
| 370 | #endif | 367 | #endif |
| @@ -437,7 +434,4 @@ int azx_probe_codecs(struct azx *chip, unsigned int max_slots); | |||
| 437 | int azx_codec_configure(struct azx *chip); | 434 | int azx_codec_configure(struct azx *chip); |
| 438 | int azx_init_stream(struct azx *chip); | 435 | int azx_init_stream(struct azx *chip); |
| 439 | 436 | ||
| 440 | void azx_notifier_register(struct azx *chip); | ||
| 441 | void azx_notifier_unregister(struct azx *chip); | ||
| 442 | |||
| 443 | #endif /* __SOUND_HDA_CONTROLLER_H */ | 437 | #endif /* __SOUND_HDA_CONTROLLER_H */ |
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 43ad51c672d6..ebdbc023583d 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c | |||
| @@ -4675,7 +4675,7 @@ int snd_hda_gen_build_controls(struct hda_codec *codec) | |||
| 4675 | err = snd_hda_create_dig_out_ctls(codec, | 4675 | err = snd_hda_create_dig_out_ctls(codec, |
| 4676 | spec->multiout.dig_out_nid, | 4676 | spec->multiout.dig_out_nid, |
| 4677 | spec->multiout.dig_out_nid, | 4677 | spec->multiout.dig_out_nid, |
| 4678 | spec->pcm_rec[1].pcm_type); | 4678 | spec->pcm_rec[1]->pcm_type); |
| 4679 | if (err < 0) | 4679 | if (err < 0) |
| 4680 | return err; | 4680 | return err; |
| 4681 | if (!spec->no_analog) { | 4681 | if (!spec->no_analog) { |
| @@ -5146,20 +5146,20 @@ static void fill_pcm_stream_name(char *str, size_t len, const char *sfx, | |||
| 5146 | int snd_hda_gen_build_pcms(struct hda_codec *codec) | 5146 | int snd_hda_gen_build_pcms(struct hda_codec *codec) |
| 5147 | { | 5147 | { |
| 5148 | struct hda_gen_spec *spec = codec->spec; | 5148 | struct hda_gen_spec *spec = codec->spec; |
| 5149 | struct hda_pcm *info = spec->pcm_rec; | 5149 | struct hda_pcm *info; |
| 5150 | const struct hda_pcm_stream *p; | 5150 | const struct hda_pcm_stream *p; |
| 5151 | bool have_multi_adcs; | 5151 | bool have_multi_adcs; |
| 5152 | 5152 | ||
| 5153 | codec->num_pcms = 1; | ||
| 5154 | codec->pcm_info = info; | ||
| 5155 | |||
| 5156 | if (spec->no_analog) | 5153 | if (spec->no_analog) |
| 5157 | goto skip_analog; | 5154 | goto skip_analog; |
| 5158 | 5155 | ||
| 5159 | fill_pcm_stream_name(spec->stream_name_analog, | 5156 | fill_pcm_stream_name(spec->stream_name_analog, |
| 5160 | sizeof(spec->stream_name_analog), | 5157 | sizeof(spec->stream_name_analog), |
| 5161 | " Analog", codec->chip_name); | 5158 | " Analog", codec->chip_name); |
| 5162 | info->name = spec->stream_name_analog; | 5159 | info = snd_hda_codec_pcm_new(codec, "%s", spec->stream_name_analog); |
| 5160 | if (!info) | ||
| 5161 | return -ENOMEM; | ||
| 5162 | spec->pcm_rec[0] = info; | ||
| 5163 | 5163 | ||
| 5164 | if (spec->multiout.num_dacs > 0) { | 5164 | if (spec->multiout.num_dacs > 0) { |
| 5165 | p = spec->stream_analog_playback; | 5165 | p = spec->stream_analog_playback; |
| @@ -5192,10 +5192,12 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec) | |||
| 5192 | fill_pcm_stream_name(spec->stream_name_digital, | 5192 | fill_pcm_stream_name(spec->stream_name_digital, |
| 5193 | sizeof(spec->stream_name_digital), | 5193 | sizeof(spec->stream_name_digital), |
| 5194 | " Digital", codec->chip_name); | 5194 | " Digital", codec->chip_name); |
| 5195 | codec->num_pcms = 2; | 5195 | info = snd_hda_codec_pcm_new(codec, "%s", |
| 5196 | spec->stream_name_digital); | ||
| 5197 | if (!info) | ||
| 5198 | return -ENOMEM; | ||
| 5196 | codec->slave_dig_outs = spec->multiout.slave_dig_outs; | 5199 | codec->slave_dig_outs = spec->multiout.slave_dig_outs; |
| 5197 | info = spec->pcm_rec + 1; | 5200 | spec->pcm_rec[1] = info; |
| 5198 | info->name = spec->stream_name_digital; | ||
| 5199 | if (spec->dig_out_type) | 5201 | if (spec->dig_out_type) |
| 5200 | info->pcm_type = spec->dig_out_type; | 5202 | info->pcm_type = spec->dig_out_type; |
| 5201 | else | 5203 | else |
| @@ -5229,9 +5231,11 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec) | |||
| 5229 | fill_pcm_stream_name(spec->stream_name_alt_analog, | 5231 | fill_pcm_stream_name(spec->stream_name_alt_analog, |
| 5230 | sizeof(spec->stream_name_alt_analog), | 5232 | sizeof(spec->stream_name_alt_analog), |
| 5231 | " Alt Analog", codec->chip_name); | 5233 | " Alt Analog", codec->chip_name); |
| 5232 | codec->num_pcms = 3; | 5234 | info = snd_hda_codec_pcm_new(codec, "%s", |
| 5233 | info = spec->pcm_rec + 2; | 5235 | spec->stream_name_alt_analog); |
| 5234 | info->name = spec->stream_name_alt_analog; | 5236 | if (!info) |
| 5237 | return -ENOMEM; | ||
| 5238 | spec->pcm_rec[2] = info; | ||
| 5235 | if (spec->alt_dac_nid) { | 5239 | if (spec->alt_dac_nid) { |
| 5236 | p = spec->stream_analog_alt_playback; | 5240 | p = spec->stream_analog_alt_playback; |
| 5237 | if (!p) | 5241 | 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_hwdep.c b/sound/pci/hda/hda_hwdep.c index 125f3420fa6a..57df06e76968 100644 --- a/sound/pci/hda/hda_hwdep.c +++ b/sound/pci/hda/hda_hwdep.c | |||
| @@ -101,7 +101,7 @@ int snd_hda_create_hwdep(struct hda_codec *codec) | |||
| 101 | int err; | 101 | int err; |
| 102 | 102 | ||
| 103 | sprintf(hwname, "HDA Codec %d", codec->addr); | 103 | sprintf(hwname, "HDA Codec %d", codec->addr); |
| 104 | err = snd_hwdep_new(codec->bus->card, hwname, codec->addr, &hwdep); | 104 | err = snd_hwdep_new(codec->card, hwname, codec->addr, &hwdep); |
| 105 | if (err < 0) | 105 | if (err < 0) |
| 106 | return err; | 106 | return err; |
| 107 | codec->hwdep = hwdep; | 107 | codec->hwdep = hwdep; |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 13529715bc55..060f7a2b1aeb 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
| @@ -528,10 +528,10 @@ static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev) | |||
| 528 | if (ok == 1) { | 528 | if (ok == 1) { |
| 529 | azx_dev->irq_pending = 0; | 529 | azx_dev->irq_pending = 0; |
| 530 | return ok; | 530 | return ok; |
| 531 | } else if (ok == 0 && chip->bus && chip->bus->workq) { | 531 | } else if (ok == 0) { |
| 532 | /* bogus IRQ, process it later */ | 532 | /* bogus IRQ, process it later */ |
| 533 | azx_dev->irq_pending = 1; | 533 | azx_dev->irq_pending = 1; |
| 534 | queue_work(chip->bus->workq, &hda->irq_pending_work); | 534 | schedule_work(&hda->irq_pending_work); |
| 535 | } | 535 | } |
| 536 | return 0; | 536 | return 0; |
| 537 | } | 537 | } |
| @@ -893,8 +893,8 @@ static int azx_runtime_resume(struct device *dev) | |||
| 893 | if (status && bus) { | 893 | if (status && bus) { |
| 894 | list_for_each_entry(codec, &bus->codec_list, list) | 894 | list_for_each_entry(codec, &bus->codec_list, list) |
| 895 | if (status & (1 << codec->addr)) | 895 | if (status & (1 << codec->addr)) |
| 896 | queue_delayed_work(codec->bus->workq, | 896 | schedule_delayed_work(&codec->jackpoll_work, |
| 897 | &codec->jackpoll_work, codec->jackpoll_interval); | 897 | codec->jackpoll_interval); |
| 898 | } | 898 | } |
| 899 | 899 | ||
| 900 | /* disable controller Wake Up event*/ | 900 | /* disable controller Wake Up event*/ |
| @@ -1066,8 +1066,6 @@ static int azx_free(struct azx *chip) | |||
| 1066 | 1066 | ||
| 1067 | azx_del_card_list(chip); | 1067 | azx_del_card_list(chip); |
| 1068 | 1068 | ||
| 1069 | azx_notifier_unregister(chip); | ||
| 1070 | |||
| 1071 | hda->init_failed = 1; /* to be sure */ | 1069 | hda->init_failed = 1; /* to be sure */ |
| 1072 | complete_all(&hda->probe_wait); | 1070 | complete_all(&hda->probe_wait); |
| 1073 | 1071 | ||
| @@ -1383,7 +1381,6 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci, | |||
| 1383 | 1381 | ||
| 1384 | hda = kzalloc(sizeof(*hda), GFP_KERNEL); | 1382 | hda = kzalloc(sizeof(*hda), GFP_KERNEL); |
| 1385 | if (!hda) { | 1383 | if (!hda) { |
| 1386 | dev_err(card->dev, "Cannot allocate hda\n"); | ||
| 1387 | pci_disable_device(pci); | 1384 | pci_disable_device(pci); |
| 1388 | return -ENOMEM; | 1385 | return -ENOMEM; |
| 1389 | } | 1386 | } |
| @@ -1564,10 +1561,8 @@ static int azx_first_init(struct azx *chip) | |||
| 1564 | chip->num_streams = chip->playback_streams + chip->capture_streams; | 1561 | chip->num_streams = chip->playback_streams + chip->capture_streams; |
| 1565 | chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev), | 1562 | chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev), |
| 1566 | GFP_KERNEL); | 1563 | GFP_KERNEL); |
| 1567 | if (!chip->azx_dev) { | 1564 | if (!chip->azx_dev) |
| 1568 | dev_err(card->dev, "cannot malloc azx_dev\n"); | ||
| 1569 | return -ENOMEM; | 1565 | return -ENOMEM; |
| 1570 | } | ||
| 1571 | 1566 | ||
| 1572 | err = azx_alloc_stream_pages(chip); | 1567 | err = azx_alloc_stream_pages(chip); |
| 1573 | if (err < 0) | 1568 | if (err < 0) |
| @@ -1898,22 +1893,11 @@ static int azx_probe_continue(struct azx *chip) | |||
| 1898 | goto out_free; | 1893 | goto out_free; |
| 1899 | } | 1894 | } |
| 1900 | 1895 | ||
| 1901 | /* create PCM streams */ | ||
| 1902 | err = snd_hda_build_pcms(chip->bus); | ||
| 1903 | if (err < 0) | ||
| 1904 | goto out_free; | ||
| 1905 | |||
| 1906 | /* create mixer controls */ | ||
| 1907 | err = snd_hda_build_controls(chip->bus); | ||
| 1908 | if (err < 0) | ||
| 1909 | goto out_free; | ||
| 1910 | |||
| 1911 | err = snd_card_register(chip->card); | 1896 | err = snd_card_register(chip->card); |
| 1912 | if (err < 0) | 1897 | if (err < 0) |
| 1913 | goto out_free; | 1898 | goto out_free; |
| 1914 | 1899 | ||
| 1915 | chip->running = 1; | 1900 | chip->running = 1; |
| 1916 | azx_notifier_register(chip); | ||
| 1917 | azx_add_card_list(chip); | 1901 | azx_add_card_list(chip); |
| 1918 | snd_hda_set_power_save(chip->bus, power_save * 1000); | 1902 | snd_hda_set_power_save(chip->bus, power_save * 1000); |
| 1919 | if (azx_has_pm_runtime(chip) || hda->use_vga_switcheroo) | 1903 | if (azx_has_pm_runtime(chip) || hda->use_vga_switcheroo) |
| @@ -1934,6 +1918,18 @@ static void azx_remove(struct pci_dev *pci) | |||
| 1934 | snd_card_free(card); | 1918 | snd_card_free(card); |
| 1935 | } | 1919 | } |
| 1936 | 1920 | ||
| 1921 | static void azx_shutdown(struct pci_dev *pci) | ||
| 1922 | { | ||
| 1923 | struct snd_card *card = pci_get_drvdata(pci); | ||
| 1924 | struct azx *chip; | ||
| 1925 | |||
| 1926 | if (!card) | ||
| 1927 | return; | ||
| 1928 | chip = card->private_data; | ||
| 1929 | if (chip && chip->running) | ||
| 1930 | azx_stop_chip(chip); | ||
| 1931 | } | ||
| 1932 | |||
| 1937 | /* PCI IDs */ | 1933 | /* PCI IDs */ |
| 1938 | static const struct pci_device_id azx_ids[] = { | 1934 | static const struct pci_device_id azx_ids[] = { |
| 1939 | /* CPT */ | 1935 | /* CPT */ |
| @@ -2156,6 +2152,7 @@ static struct pci_driver azx_driver = { | |||
| 2156 | .id_table = azx_ids, | 2152 | .id_table = azx_ids, |
| 2157 | .probe = azx_probe, | 2153 | .probe = azx_probe, |
| 2158 | .remove = azx_remove, | 2154 | .remove = azx_remove, |
| 2155 | .shutdown = azx_shutdown, | ||
| 2159 | .driver = { | 2156 | .driver = { |
| 2160 | .pm = AZX_PM_OPS, | 2157 | .pm = AZX_PM_OPS, |
| 2161 | }, | 2158 | }, |
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c index e664307617bd..d7cfe7b8c32b 100644 --- a/sound/pci/hda/hda_jack.c +++ b/sound/pci/hda/hda_jack.c | |||
| @@ -135,7 +135,7 @@ void snd_hda_jack_tbl_clear(struct hda_codec *codec) | |||
| 135 | #ifdef CONFIG_SND_HDA_INPUT_JACK | 135 | #ifdef CONFIG_SND_HDA_INPUT_JACK |
| 136 | /* free jack instances manually when clearing/reconfiguring */ | 136 | /* free jack instances manually when clearing/reconfiguring */ |
| 137 | if (!codec->bus->shutdown && jack->jack) | 137 | if (!codec->bus->shutdown && jack->jack) |
| 138 | snd_device_free(codec->bus->card, jack->jack); | 138 | snd_device_free(codec->card, jack->jack); |
| 139 | #endif | 139 | #endif |
| 140 | for (cb = jack->callback; cb; cb = next) { | 140 | for (cb = jack->callback; cb; cb = next) { |
| 141 | next = cb->next; | 141 | next = cb->next; |
| @@ -340,7 +340,7 @@ void snd_hda_jack_report_sync(struct hda_codec *codec) | |||
| 340 | if (!jack->kctl || jack->block_report) | 340 | if (!jack->kctl || jack->block_report) |
| 341 | continue; | 341 | continue; |
| 342 | state = get_jack_plug_state(jack->pin_sense); | 342 | state = get_jack_plug_state(jack->pin_sense); |
| 343 | snd_kctl_jack_report(codec->bus->card, jack->kctl, state); | 343 | snd_kctl_jack_report(codec->card, jack->kctl, state); |
| 344 | #ifdef CONFIG_SND_HDA_INPUT_JACK | 344 | #ifdef CONFIG_SND_HDA_INPUT_JACK |
| 345 | if (jack->jack) | 345 | if (jack->jack) |
| 346 | snd_jack_report(jack->jack, | 346 | snd_jack_report(jack->jack, |
| @@ -412,11 +412,11 @@ static int __snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, | |||
| 412 | jack->phantom_jack = !!phantom_jack; | 412 | jack->phantom_jack = !!phantom_jack; |
| 413 | 413 | ||
| 414 | state = snd_hda_jack_detect(codec, nid); | 414 | state = snd_hda_jack_detect(codec, nid); |
| 415 | snd_kctl_jack_report(codec->bus->card, kctl, state); | 415 | snd_kctl_jack_report(codec->card, kctl, state); |
| 416 | #ifdef CONFIG_SND_HDA_INPUT_JACK | 416 | #ifdef CONFIG_SND_HDA_INPUT_JACK |
| 417 | if (!phantom_jack) { | 417 | if (!phantom_jack) { |
| 418 | jack->type = get_input_jack_type(codec, nid); | 418 | jack->type = get_input_jack_type(codec, nid); |
| 419 | err = snd_jack_new(codec->bus->card, name, jack->type, | 419 | err = snd_jack_new(codec->card, name, jack->type, |
| 420 | &jack->jack); | 420 | &jack->jack); |
| 421 | if (err < 0) | 421 | if (err < 0) |
| 422 | return err; | 422 | return err; |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 8588813163e3..1d001647fc47 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
| @@ -150,6 +150,7 @@ int __snd_hda_add_vmaster(struct hda_codec *codec, char *name, | |||
| 150 | #define snd_hda_add_vmaster(codec, name, tlv, slaves, suffix) \ | 150 | #define snd_hda_add_vmaster(codec, name, tlv, slaves, suffix) \ |
| 151 | __snd_hda_add_vmaster(codec, name, tlv, slaves, suffix, true, NULL) | 151 | __snd_hda_add_vmaster(codec, name, tlv, slaves, suffix, true, NULL) |
| 152 | int snd_hda_codec_reset(struct hda_codec *codec); | 152 | int snd_hda_codec_reset(struct hda_codec *codec); |
| 153 | void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec); | ||
| 153 | 154 | ||
| 154 | enum { | 155 | enum { |
| 155 | HDA_VMUTE_OFF, | 156 | HDA_VMUTE_OFF, |
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index 05e19f78b4cb..dacfe74a2a1f 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; |
| @@ -861,7 +861,7 @@ int snd_hda_codec_proc_new(struct hda_codec *codec) | |||
| 861 | int err; | 861 | int err; |
| 862 | 862 | ||
| 863 | snprintf(name, sizeof(name), "codec#%d", codec->addr); | 863 | snprintf(name, sizeof(name), "codec#%d", codec->addr); |
| 864 | err = snd_card_proc_new(codec->bus->card, name, &entry); | 864 | err = snd_card_proc_new(codec->card, name, &entry); |
| 865 | if (err < 0) | 865 | if (err < 0) |
| 866 | return err; | 866 | return err; |
| 867 | 867 | ||
diff --git a/sound/pci/hda/hda_sysfs.c b/sound/pci/hda/hda_sysfs.c index ccc962a1699f..e13c75d67847 100644 --- a/sound/pci/hda/hda_sysfs.c +++ b/sound/pci/hda/hda_sysfs.c | |||
| @@ -149,7 +149,7 @@ static int reconfig_codec(struct hda_codec *codec) | |||
| 149 | err = snd_hda_codec_build_controls(codec); | 149 | err = snd_hda_codec_build_controls(codec); |
| 150 | if (err < 0) | 150 | if (err < 0) |
| 151 | goto error; | 151 | goto error; |
| 152 | err = snd_card_register(codec->bus->card); | 152 | err = snd_card_register(codec->card); |
| 153 | error: | 153 | error: |
| 154 | snd_hda_power_down(codec); | 154 | snd_hda_power_down(codec); |
| 155 | return err; | 155 | return err; |
diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c index 1359fdd20f02..2e4fd5c56d3b 100644 --- a/sound/pci/hda/hda_tegra.c +++ b/sound/pci/hda/hda_tegra.c | |||
| @@ -290,8 +290,6 @@ static int hda_tegra_dev_free(struct snd_device *device) | |||
| 290 | int i; | 290 | int i; |
| 291 | struct azx *chip = device->device_data; | 291 | struct azx *chip = device->device_data; |
| 292 | 292 | ||
| 293 | azx_notifier_unregister(chip); | ||
| 294 | |||
| 295 | if (chip->initialized) { | 293 | if (chip->initialized) { |
| 296 | for (i = 0; i < chip->num_streams; i++) | 294 | for (i = 0; i < chip->num_streams; i++) |
| 297 | azx_stream_stop(chip, &chip->azx_dev[i]); | 295 | azx_stream_stop(chip, &chip->azx_dev[i]); |
| @@ -497,22 +495,11 @@ static int hda_tegra_probe(struct platform_device *pdev) | |||
| 497 | if (err < 0) | 495 | if (err < 0) |
| 498 | goto out_free; | 496 | goto out_free; |
| 499 | 497 | ||
| 500 | /* create PCM streams */ | ||
| 501 | err = snd_hda_build_pcms(chip->bus); | ||
| 502 | if (err < 0) | ||
| 503 | goto out_free; | ||
| 504 | |||
| 505 | /* create mixer controls */ | ||
| 506 | err = snd_hda_build_controls(chip->bus); | ||
| 507 | if (err < 0) | ||
| 508 | goto out_free; | ||
| 509 | |||
| 510 | err = snd_card_register(chip->card); | 498 | err = snd_card_register(chip->card); |
| 511 | if (err < 0) | 499 | if (err < 0) |
| 512 | goto out_free; | 500 | goto out_free; |
| 513 | 501 | ||
| 514 | chip->running = 1; | 502 | chip->running = 1; |
| 515 | azx_notifier_register(chip); | ||
| 516 | snd_hda_set_power_save(chip->bus, power_save * 1000); | 503 | snd_hda_set_power_save(chip->bus, power_save * 1000); |
| 517 | 504 | ||
| 518 | return 0; | 505 | return 0; |
| @@ -527,6 +514,18 @@ static int hda_tegra_remove(struct platform_device *pdev) | |||
| 527 | return snd_card_free(dev_get_drvdata(&pdev->dev)); | 514 | return snd_card_free(dev_get_drvdata(&pdev->dev)); |
| 528 | } | 515 | } |
| 529 | 516 | ||
| 517 | static void hda_tegra_shutdown(struct platform_device *pdev) | ||
| 518 | { | ||
| 519 | struct snd_card *card = dev_get_drvdata(&pdev->dev); | ||
| 520 | struct azx *chip; | ||
| 521 | |||
| 522 | if (!card) | ||
| 523 | return; | ||
| 524 | chip = card->private_data; | ||
| 525 | if (chip && chip->running) | ||
| 526 | azx_stop_chip(chip); | ||
| 527 | } | ||
| 528 | |||
| 530 | static struct platform_driver tegra_platform_hda = { | 529 | static struct platform_driver tegra_platform_hda = { |
| 531 | .driver = { | 530 | .driver = { |
| 532 | .name = "tegra-hda", | 531 | .name = "tegra-hda", |
| @@ -535,6 +534,7 @@ static struct platform_driver tegra_platform_hda = { | |||
| 535 | }, | 534 | }, |
| 536 | .probe = hda_tegra_probe, | 535 | .probe = hda_tegra_probe, |
| 537 | .remove = hda_tegra_remove, | 536 | .remove = hda_tegra_remove, |
| 537 | .shutdown = hda_tegra_shutdown, | ||
| 538 | }; | 538 | }; |
| 539 | module_platform_driver(tegra_platform_hda); | 539 | module_platform_driver(tegra_platform_hda); |
| 540 | 540 | ||
diff --git a/sound/pci/hda/hda_trace.h b/sound/pci/hda/hda_trace.h index c0e1c7d24dbe..7fedfa862419 100644 --- a/sound/pci/hda/hda_trace.h +++ b/sound/pci/hda/hda_trace.h | |||
| @@ -23,7 +23,7 @@ DECLARE_EVENT_CLASS(hda_cmd, | |||
| 23 | ), | 23 | ), |
| 24 | 24 | ||
| 25 | TP_fast_assign( | 25 | TP_fast_assign( |
| 26 | __entry->card = (codec)->bus->card->number; | 26 | __entry->card = (codec)->card->number; |
| 27 | __entry->addr = (codec)->addr; | 27 | __entry->addr = (codec)->addr; |
| 28 | __entry->val = (val); | 28 | __entry->val = (val); |
| 29 | ), | 29 | ), |
| @@ -71,7 +71,7 @@ DECLARE_EVENT_CLASS(hda_power, | |||
| 71 | ), | 71 | ), |
| 72 | 72 | ||
| 73 | TP_fast_assign( | 73 | TP_fast_assign( |
| 74 | __entry->card = (codec)->bus->card->number; | 74 | __entry->card = (codec)->card->number; |
| 75 | __entry->addr = (codec)->addr; | 75 | __entry->addr = (codec)->addr; |
| 76 | ), | 76 | ), |
| 77 | 77 | ||
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 81991b4134cd..72d20652df50 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 | } |
| @@ -4352,7 +4349,7 @@ static bool ca0132_download_dsp_images(struct hda_codec *codec) | |||
| 4352 | const struct dsp_image_seg *dsp_os_image; | 4349 | const struct dsp_image_seg *dsp_os_image; |
| 4353 | const struct firmware *fw_entry; | 4350 | const struct firmware *fw_entry; |
| 4354 | 4351 | ||
| 4355 | if (request_firmware(&fw_entry, EFX_FILE, codec->bus->card->dev) != 0) | 4352 | if (request_firmware(&fw_entry, EFX_FILE, codec->card->dev) != 0) |
| 4356 | return false; | 4353 | return false; |
| 4357 | 4354 | ||
| 4358 | dsp_os_image = (struct dsp_image_seg *)(fw_entry->data); | 4355 | dsp_os_image = (struct dsp_image_seg *)(fw_entry->data); |
| @@ -4413,8 +4410,7 @@ static void hp_callback(struct hda_codec *codec, struct hda_jack_callback *cb) | |||
| 4413 | * state machine run. | 4410 | * state machine run. |
| 4414 | */ | 4411 | */ |
| 4415 | cancel_delayed_work_sync(&spec->unsol_hp_work); | 4412 | cancel_delayed_work_sync(&spec->unsol_hp_work); |
| 4416 | queue_delayed_work(codec->bus->workq, &spec->unsol_hp_work, | 4413 | schedule_delayed_work(&spec->unsol_hp_work, msecs_to_jiffies(500)); |
| 4417 | msecs_to_jiffies(500)); | ||
| 4418 | cb->tbl->block_report = 1; | 4414 | cb->tbl->block_report = 1; |
| 4419 | } | 4415 | } |
| 4420 | 4416 | ||
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index f1812aabd63e..7e9ff7b16e56 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 | { |
| @@ -579,7 +577,7 @@ static int eld_proc_new(struct hdmi_spec_per_pin *per_pin, int index) | |||
| 579 | int err; | 577 | int err; |
| 580 | 578 | ||
| 581 | snprintf(name, sizeof(name), "eld#%d.%d", codec->addr, index); | 579 | snprintf(name, sizeof(name), "eld#%d.%d", codec->addr, index); |
| 582 | err = snd_card_proc_new(codec->bus->card, name, &entry); | 580 | err = snd_card_proc_new(codec->card, name, &entry); |
| 583 | if (err < 0) | 581 | if (err < 0) |
| 584 | return err; | 582 | return err; |
| 585 | 583 | ||
| @@ -594,7 +592,7 @@ static int eld_proc_new(struct hdmi_spec_per_pin *per_pin, int index) | |||
| 594 | static void eld_proc_free(struct hdmi_spec_per_pin *per_pin) | 592 | static void eld_proc_free(struct hdmi_spec_per_pin *per_pin) |
| 595 | { | 593 | { |
| 596 | if (!per_pin->codec->bus->shutdown && per_pin->proc_entry) { | 594 | if (!per_pin->codec->bus->shutdown && per_pin->proc_entry) { |
| 597 | snd_device_free(per_pin->codec->bus->card, per_pin->proc_entry); | 595 | snd_device_free(per_pin->codec->card, per_pin->proc_entry); |
| 598 | per_pin->proc_entry = NULL; | 596 | per_pin->proc_entry = NULL; |
| 599 | } | 597 | } |
| 600 | } | 598 | } |
| @@ -1578,9 +1576,8 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) | |||
| 1578 | update_eld = true; | 1576 | update_eld = true; |
| 1579 | } | 1577 | } |
| 1580 | else if (repoll) { | 1578 | else if (repoll) { |
| 1581 | queue_delayed_work(codec->bus->workq, | 1579 | schedule_delayed_work(&per_pin->work, |
| 1582 | &per_pin->work, | 1580 | msecs_to_jiffies(300)); |
| 1583 | msecs_to_jiffies(300)); | ||
| 1584 | goto unlock; | 1581 | goto unlock; |
| 1585 | } | 1582 | } |
| 1586 | } | 1583 | } |
| @@ -1624,7 +1621,7 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) | |||
| 1624 | } | 1621 | } |
| 1625 | 1622 | ||
| 1626 | if (eld_changed) | 1623 | if (eld_changed) |
| 1627 | snd_ctl_notify(codec->bus->card, | 1624 | snd_ctl_notify(codec->card, |
| 1628 | SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO, | 1625 | SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO, |
| 1629 | &per_pin->eld_ctl->id); | 1626 | &per_pin->eld_ctl->id); |
| 1630 | unlock: | 1627 | unlock: |
| @@ -2056,11 +2053,10 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec) | |||
| 2056 | struct hdmi_spec_per_pin *per_pin; | 2053 | struct hdmi_spec_per_pin *per_pin; |
| 2057 | 2054 | ||
| 2058 | per_pin = get_pin(spec, pin_idx); | 2055 | per_pin = get_pin(spec, pin_idx); |
| 2059 | sprintf(per_pin->pcm_name, "HDMI %d", pin_idx); | 2056 | info = snd_hda_codec_pcm_new(codec, "HDMI %d", pin_idx); |
| 2060 | info = snd_array_new(&spec->pcm_rec); | ||
| 2061 | if (!info) | 2057 | if (!info) |
| 2062 | return -ENOMEM; | 2058 | return -ENOMEM; |
| 2063 | info->name = per_pin->pcm_name; | 2059 | spec->pcm_rec[pin_idx] = info; |
| 2064 | info->pcm_type = HDA_PCM_TYPE_HDMI; | 2060 | info->pcm_type = HDA_PCM_TYPE_HDMI; |
| 2065 | info->own_chmap = true; | 2061 | info->own_chmap = true; |
| 2066 | 2062 | ||
| @@ -2070,9 +2066,6 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec) | |||
| 2070 | /* other pstr fields are set in open */ | 2066 | /* other pstr fields are set in open */ |
| 2071 | } | 2067 | } |
| 2072 | 2068 | ||
| 2073 | codec->num_pcms = spec->num_pins; | ||
| 2074 | codec->pcm_info = spec->pcm_rec.list; | ||
| 2075 | |||
| 2076 | return 0; | 2069 | return 0; |
| 2077 | } | 2070 | } |
| 2078 | 2071 | ||
| @@ -2125,13 +2118,15 @@ static int generic_hdmi_build_controls(struct hda_codec *codec) | |||
| 2125 | 2118 | ||
| 2126 | /* add channel maps */ | 2119 | /* add channel maps */ |
| 2127 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { | 2120 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { |
| 2121 | struct hda_pcm *pcm; | ||
| 2128 | struct snd_pcm_chmap *chmap; | 2122 | struct snd_pcm_chmap *chmap; |
| 2129 | struct snd_kcontrol *kctl; | 2123 | struct snd_kcontrol *kctl; |
| 2130 | int i; | 2124 | int i; |
| 2131 | 2125 | ||
| 2132 | if (!codec->pcm_info[pin_idx].pcm) | 2126 | pcm = spec->pcm_rec[pin_idx]; |
| 2127 | if (!pcm || !pcm->pcm) | ||
| 2133 | break; | 2128 | break; |
| 2134 | err = snd_pcm_add_chmap_ctls(codec->pcm_info[pin_idx].pcm, | 2129 | err = snd_pcm_add_chmap_ctls(pcm->pcm, |
| 2135 | SNDRV_PCM_STREAM_PLAYBACK, | 2130 | SNDRV_PCM_STREAM_PLAYBACK, |
| 2136 | NULL, 0, pin_idx, &chmap); | 2131 | NULL, 0, pin_idx, &chmap); |
| 2137 | if (err < 0) | 2132 | if (err < 0) |
| @@ -2186,14 +2181,12 @@ static void hdmi_array_init(struct hdmi_spec *spec, int nums) | |||
| 2186 | { | 2181 | { |
| 2187 | snd_array_init(&spec->pins, sizeof(struct hdmi_spec_per_pin), nums); | 2182 | 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); | 2183 | 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 | } | 2184 | } |
| 2191 | 2185 | ||
| 2192 | static void hdmi_array_free(struct hdmi_spec *spec) | 2186 | static void hdmi_array_free(struct hdmi_spec *spec) |
| 2193 | { | 2187 | { |
| 2194 | snd_array_free(&spec->pins); | 2188 | snd_array_free(&spec->pins); |
| 2195 | snd_array_free(&spec->cvts); | 2189 | snd_array_free(&spec->cvts); |
| 2196 | snd_array_free(&spec->pcm_rec); | ||
| 2197 | } | 2190 | } |
| 2198 | 2191 | ||
| 2199 | static void generic_hdmi_free(struct hda_codec *codec) | 2192 | static void generic_hdmi_free(struct hda_codec *codec) |
| @@ -2204,11 +2197,10 @@ static void generic_hdmi_free(struct hda_codec *codec) | |||
| 2204 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { | 2197 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { |
| 2205 | struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); | 2198 | struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); |
| 2206 | 2199 | ||
| 2207 | cancel_delayed_work(&per_pin->work); | 2200 | cancel_delayed_work_sync(&per_pin->work); |
| 2208 | eld_proc_free(per_pin); | 2201 | eld_proc_free(per_pin); |
| 2209 | } | 2202 | } |
| 2210 | 2203 | ||
| 2211 | flush_workqueue(codec->bus->workq); | ||
| 2212 | hdmi_array_free(spec); | 2204 | hdmi_array_free(spec); |
| 2213 | kfree(spec); | 2205 | kfree(spec); |
| 2214 | } | 2206 | } |
| @@ -2381,11 +2373,10 @@ static int simple_playback_build_pcms(struct hda_codec *codec) | |||
| 2381 | chans = get_wcaps(codec, per_cvt->cvt_nid); | 2373 | chans = get_wcaps(codec, per_cvt->cvt_nid); |
| 2382 | chans = get_wcaps_channels(chans); | 2374 | chans = get_wcaps_channels(chans); |
| 2383 | 2375 | ||
| 2384 | info = snd_array_new(&spec->pcm_rec); | 2376 | info = snd_hda_codec_pcm_new(codec, "HDMI 0"); |
| 2385 | if (!info) | 2377 | if (!info) |
| 2386 | return -ENOMEM; | 2378 | return -ENOMEM; |
| 2387 | info->name = get_pin(spec, 0)->pcm_name; | 2379 | spec->pcm_rec[0] = info; |
| 2388 | sprintf(info->name, "HDMI 0"); | ||
| 2389 | info->pcm_type = HDA_PCM_TYPE_HDMI; | 2380 | info->pcm_type = HDA_PCM_TYPE_HDMI; |
| 2390 | pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; | 2381 | pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; |
| 2391 | *pstr = spec->pcm_playback; | 2382 | *pstr = spec->pcm_playback; |
| @@ -2393,9 +2384,6 @@ static int simple_playback_build_pcms(struct hda_codec *codec) | |||
| 2393 | if (pstr->channels_max <= 2 && chans && chans <= 16) | 2384 | if (pstr->channels_max <= 2 && chans && chans <= 16) |
| 2394 | pstr->channels_max = chans; | 2385 | pstr->channels_max = chans; |
| 2395 | 2386 | ||
| 2396 | codec->num_pcms = 1; | ||
| 2397 | codec->pcm_info = info; | ||
| 2398 | |||
| 2399 | return 0; | 2387 | return 0; |
| 2400 | } | 2388 | } |
| 2401 | 2389 | ||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 0ae1f5b7639b..2a61bda8115d 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
| @@ -5850,7 +5850,7 @@ static void alc_fixup_bass_chmap(struct hda_codec *codec, | |||
| 5850 | { | 5850 | { |
| 5851 | if (action == HDA_FIXUP_ACT_BUILD) { | 5851 | if (action == HDA_FIXUP_ACT_BUILD) { |
| 5852 | struct alc_spec *spec = codec->spec; | 5852 | struct alc_spec *spec = codec->spec; |
| 5853 | spec->gen.pcm_rec[0].stream[0].chmap = asus_pcm_2_1_chmaps; | 5853 | spec->gen.pcm_rec[0]->stream[0].chmap = asus_pcm_2_1_chmaps; |
| 5854 | } | 5854 | } |
| 5855 | } | 5855 | } |
| 5856 | 5856 | ||
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 2045f33b1ace..2112fbe9e577 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
| @@ -222,8 +222,7 @@ static void vt1708_update_hp_work(struct hda_codec *codec) | |||
| 222 | if (!spec->hp_work_active) { | 222 | if (!spec->hp_work_active) { |
| 223 | codec->jackpoll_interval = msecs_to_jiffies(100); | 223 | codec->jackpoll_interval = msecs_to_jiffies(100); |
| 224 | snd_hda_codec_write(codec, 0x1, 0, 0xf81, 0); | 224 | snd_hda_codec_write(codec, 0x1, 0, 0xf81, 0); |
| 225 | queue_delayed_work(codec->bus->workq, | 225 | schedule_delayed_work(&codec->jackpoll_work, 0); |
| 226 | &codec->jackpoll_work, 0); | ||
| 227 | spec->hp_work_active = true; | 226 | spec->hp_work_active = true; |
| 228 | } | 227 | } |
| 229 | } else if (!hp_detect_with_aa(codec)) | 228 | } else if (!hp_detect_with_aa(codec)) |
| @@ -683,8 +682,10 @@ static int vt1708_build_pcms(struct hda_codec *codec) | |||
| 683 | * 24bit samples are used. Until any workaround is found, | 682 | * 24bit samples are used. Until any workaround is found, |
| 684 | * disable the 24bit format, so far. | 683 | * disable the 24bit format, so far. |
| 685 | */ | 684 | */ |
| 686 | for (i = 0; i < codec->num_pcms; i++) { | 685 | for (i = 0; i < ARRAY_SIZE(spec->gen.pcm_rec); i++) { |
| 687 | struct hda_pcm *info = &spec->gen.pcm_rec[i]; | 686 | struct hda_pcm *info = spec->gen.pcm_rec[i]; |
| 687 | if (!info) | ||
| 688 | continue; | ||
| 688 | if (!info->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams || | 689 | if (!info->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams || |
| 689 | info->pcm_type != HDA_PCM_TYPE_AUDIO) | 690 | info->pcm_type != HDA_PCM_TYPE_AUDIO) |
| 690 | continue; | 691 | continue; |
| @@ -907,16 +908,16 @@ static int patch_vt1708S(struct hda_codec *codec) | |||
| 907 | if (get_codec_type(codec) == VT1708BCE) { | 908 | if (get_codec_type(codec) == VT1708BCE) { |
| 908 | kfree(codec->chip_name); | 909 | kfree(codec->chip_name); |
| 909 | codec->chip_name = kstrdup("VT1708BCE", GFP_KERNEL); | 910 | codec->chip_name = kstrdup("VT1708BCE", GFP_KERNEL); |
| 910 | snprintf(codec->bus->card->mixername, | 911 | snprintf(codec->card->mixername, |
| 911 | sizeof(codec->bus->card->mixername), | 912 | sizeof(codec->card->mixername), |
| 912 | "%s %s", codec->vendor_name, codec->chip_name); | 913 | "%s %s", codec->vendor_name, codec->chip_name); |
| 913 | } | 914 | } |
| 914 | /* correct names for VT1705 */ | 915 | /* correct names for VT1705 */ |
| 915 | if (codec->vendor_id == 0x11064397) { | 916 | if (codec->vendor_id == 0x11064397) { |
| 916 | kfree(codec->chip_name); | 917 | kfree(codec->chip_name); |
| 917 | codec->chip_name = kstrdup("VT1705", GFP_KERNEL); | 918 | codec->chip_name = kstrdup("VT1705", GFP_KERNEL); |
| 918 | snprintf(codec->bus->card->mixername, | 919 | snprintf(codec->card->mixername, |
| 919 | sizeof(codec->bus->card->mixername), | 920 | sizeof(codec->card->mixername), |
| 920 | "%s %s", codec->vendor_name, codec->chip_name); | 921 | "%s %s", codec->vendor_name, codec->chip_name); |
| 921 | } | 922 | } |
| 922 | 923 | ||
