diff options
author | Takashi Iwai <tiwai@suse.de> | 2015-03-02 17:22:59 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2015-03-23 08:17:02 -0400 |
commit | d068ebc25e6e1360510ad8023fe7bca3dacd204e (patch) | |
tree | 982ba3c4c1aa5f1a647f505d1d0863b926fde605 /sound/pci | |
parent | e3d280fc6d42017b2379503fbda83655a05294fe (diff) |
ALSA: hda - Move some codes up to hdac_bus struct
A few basic codes for communicating over HD-audio bus are moved to
struct hdac_bus now. It has only command and get_response ops in
addition to the unsolicited event handling.
Note that the codec-side tracing support is disabled temporarily
during this transition due to the code shuffling. It will be
re-enabled later once when all pieces are settled down.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/hda_bind.c | 10 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.c | 191 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.h | 34 | ||||
-rw-r--r-- | sound/pci/hda/hda_controller.c | 8 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 4 | ||||
-rw-r--r-- | sound/pci/hda/hda_sysfs.c | 2 | ||||
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 4 |
7 files changed, 92 insertions, 161 deletions
diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c index e3bd2807b644..0b9ea70c546b 100644 --- a/sound/pci/hda/hda_bind.c +++ b/sound/pci/hda/hda_bind.c | |||
@@ -74,6 +74,15 @@ static int hda_codec_match(struct hdac_device *dev, struct hdac_driver *drv) | |||
74 | return 0; | 74 | return 0; |
75 | } | 75 | } |
76 | 76 | ||
77 | /* process an unsolicited event */ | ||
78 | static void hda_codec_unsol_event(struct hdac_device *dev, unsigned int ev) | ||
79 | { | ||
80 | struct hda_codec *codec = container_of(dev, struct hda_codec, core); | ||
81 | |||
82 | if (codec->patch_ops.unsol_event) | ||
83 | codec->patch_ops.unsol_event(codec, ev); | ||
84 | } | ||
85 | |||
77 | /* reset the codec name from the preset */ | 86 | /* reset the codec name from the preset */ |
78 | static int codec_refresh_name(struct hda_codec *codec, const char *name) | 87 | static int codec_refresh_name(struct hda_codec *codec, const char *name) |
79 | { | 88 | { |
@@ -163,6 +172,7 @@ int __hda_codec_driver_register(struct hda_codec_driver *drv, const char *name, | |||
163 | drv->core.driver.pm = &hda_codec_driver_pm; | 172 | drv->core.driver.pm = &hda_codec_driver_pm; |
164 | drv->core.type = HDA_DEV_LEGACY; | 173 | drv->core.type = HDA_DEV_LEGACY; |
165 | drv->core.match = hda_codec_match; | 174 | drv->core.match = hda_codec_match; |
175 | drv->core.unsol_event = hda_codec_unsol_event; | ||
166 | return driver_register(&drv->core.driver); | 176 | return driver_register(&drv->core.driver); |
167 | } | 177 | } |
168 | EXPORT_SYMBOL_GPL(__hda_codec_driver_register); | 178 | EXPORT_SYMBOL_GPL(__hda_codec_driver_register); |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index e14f9f562874..f96bff37c787 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -39,9 +39,6 @@ | |||
39 | #include "hda_jack.h" | 39 | #include "hda_jack.h" |
40 | #include <sound/hda_hwdep.h> | 40 | #include <sound/hda_hwdep.h> |
41 | 41 | ||
42 | #define CREATE_TRACE_POINTS | ||
43 | #include "hda_trace.h" | ||
44 | |||
45 | #ifdef CONFIG_PM | 42 | #ifdef CONFIG_PM |
46 | #define codec_in_pm(codec) atomic_read(&(codec)->in_pm) | 43 | #define codec_in_pm(codec) atomic_read(&(codec)->in_pm) |
47 | #define hda_codec_is_power_on(codec) \ | 44 | #define hda_codec_is_power_on(codec) \ |
@@ -128,16 +125,17 @@ static inline unsigned int | |||
128 | make_codec_cmd(struct hda_codec *codec, hda_nid_t nid, int flags, | 125 | make_codec_cmd(struct hda_codec *codec, hda_nid_t nid, int flags, |
129 | unsigned int verb, unsigned int parm) | 126 | unsigned int verb, unsigned int parm) |
130 | { | 127 | { |
128 | unsigned int addr = codec->core.addr; | ||
131 | u32 val; | 129 | u32 val; |
132 | 130 | ||
133 | if ((codec->addr & ~0xf) || (nid & ~0x7f) || | 131 | if ((addr & ~0xf) || (nid & ~0x7f) || |
134 | (verb & ~0xfff) || (parm & ~0xffff)) { | 132 | (verb & ~0xfff) || (parm & ~0xffff)) { |
135 | codec_err(codec, "hda-codec: out of range cmd %x:%x:%x:%x\n", | 133 | codec_err(codec, "hda-codec: out of range cmd %x:%x:%x:%x\n", |
136 | codec->addr, nid, verb, parm); | 134 | addr, nid, verb, parm); |
137 | return ~0; | 135 | return ~0; |
138 | } | 136 | } |
139 | 137 | ||
140 | val = (u32)codec->addr << 28; | 138 | val = (u32)addr << 28; |
141 | val |= (u32)nid << 20; | 139 | val |= (u32)nid << 20; |
142 | val |= verb << 8; | 140 | val |= verb << 8; |
143 | val |= parm; | 141 | val |= parm; |
@@ -156,33 +154,20 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd, | |||
156 | if (cmd == ~0) | 154 | if (cmd == ~0) |
157 | return -1; | 155 | return -1; |
158 | 156 | ||
159 | if (res) | ||
160 | *res = -1; | ||
161 | again: | 157 | again: |
162 | snd_hda_power_up(codec); | 158 | snd_hda_power_up(codec); |
163 | mutex_lock(&bus->cmd_mutex); | 159 | mutex_lock(&bus->core.cmd_mutex); |
164 | if (flags & HDA_RW_NO_RESPONSE_FALLBACK) | 160 | if (flags & HDA_RW_NO_RESPONSE_FALLBACK) |
165 | bus->no_response_fallback = 1; | 161 | bus->no_response_fallback = 1; |
166 | for (;;) { | 162 | err = snd_hdac_bus_exec_verb_unlocked(&bus->core, codec->core.addr, |
167 | trace_hda_send_cmd(codec, cmd); | 163 | cmd, res); |
168 | err = bus->ops.command(bus, cmd); | ||
169 | if (err != -EAGAIN) | ||
170 | break; | ||
171 | /* process pending verbs */ | ||
172 | bus->ops.get_response(bus, codec->addr); | ||
173 | } | ||
174 | if (!err && res) { | ||
175 | *res = bus->ops.get_response(bus, codec->addr); | ||
176 | trace_hda_get_response(codec, *res); | ||
177 | } | ||
178 | bus->no_response_fallback = 0; | 164 | bus->no_response_fallback = 0; |
179 | mutex_unlock(&bus->cmd_mutex); | 165 | mutex_unlock(&bus->core.cmd_mutex); |
180 | snd_hda_power_down(codec); | 166 | snd_hda_power_down(codec); |
181 | if (!codec_in_pm(codec) && res && *res == -1 && bus->rirb_error) { | 167 | if (!codec_in_pm(codec) && res && err < 0 && bus->rirb_error) { |
182 | if (bus->response_reset) { | 168 | if (bus->response_reset) { |
183 | codec_dbg(codec, | 169 | codec_dbg(codec, |
184 | "resetting BUS due to fatal communication error\n"); | 170 | "resetting BUS due to fatal communication error\n"); |
185 | trace_hda_bus_reset(bus); | ||
186 | bus->ops.bus_reset(bus); | 171 | bus->ops.bus_reset(bus); |
187 | } | 172 | } |
188 | goto again; | 173 | goto again; |
@@ -233,9 +218,7 @@ int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int flags, | |||
233 | unsigned int verb, unsigned int parm) | 218 | unsigned int verb, unsigned int parm) |
234 | { | 219 | { |
235 | unsigned int cmd = make_codec_cmd(codec, nid, flags, verb, parm); | 220 | unsigned int cmd = make_codec_cmd(codec, nid, flags, verb, parm); |
236 | unsigned int res; | 221 | return codec_exec_verb(codec, cmd, flags, NULL); |
237 | return codec_exec_verb(codec, cmd, flags, | ||
238 | codec->bus->sync_write ? &res : NULL); | ||
239 | } | 222 | } |
240 | EXPORT_SYMBOL_GPL(snd_hda_codec_write); | 223 | EXPORT_SYMBOL_GPL(snd_hda_codec_write); |
241 | 224 | ||
@@ -664,65 +647,6 @@ int snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid, | |||
664 | return devices; | 647 | return devices; |
665 | } | 648 | } |
666 | 649 | ||
667 | /** | ||
668 | * snd_hda_queue_unsol_event - add an unsolicited event to queue | ||
669 | * @bus: the BUS | ||
670 | * @res: unsolicited event (lower 32bit of RIRB entry) | ||
671 | * @res_ex: codec addr and flags (upper 32bit or RIRB entry) | ||
672 | * | ||
673 | * Adds the given event to the queue. The events are processed in | ||
674 | * the workqueue asynchronously. Call this function in the interrupt | ||
675 | * hanlder when RIRB receives an unsolicited event. | ||
676 | * | ||
677 | * Returns 0 if successful, or a negative error code. | ||
678 | */ | ||
679 | int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex) | ||
680 | { | ||
681 | struct hda_bus_unsolicited *unsol; | ||
682 | unsigned int wp; | ||
683 | |||
684 | if (!bus) | ||
685 | return 0; | ||
686 | |||
687 | trace_hda_unsol_event(bus, res, res_ex); | ||
688 | unsol = &bus->unsol; | ||
689 | wp = (unsol->wp + 1) % HDA_UNSOL_QUEUE_SIZE; | ||
690 | unsol->wp = wp; | ||
691 | |||
692 | wp <<= 1; | ||
693 | unsol->queue[wp] = res; | ||
694 | unsol->queue[wp + 1] = res_ex; | ||
695 | |||
696 | schedule_work(&unsol->work); | ||
697 | |||
698 | return 0; | ||
699 | } | ||
700 | EXPORT_SYMBOL_GPL(snd_hda_queue_unsol_event); | ||
701 | |||
702 | /* | ||
703 | * process queued unsolicited events | ||
704 | */ | ||
705 | static void process_unsol_events(struct work_struct *work) | ||
706 | { | ||
707 | struct hda_bus *bus = container_of(work, struct hda_bus, unsol.work); | ||
708 | struct hda_bus_unsolicited *unsol = &bus->unsol; | ||
709 | struct hda_codec *codec; | ||
710 | unsigned int rp, caddr, res; | ||
711 | |||
712 | while (unsol->rp != unsol->wp) { | ||
713 | rp = (unsol->rp + 1) % HDA_UNSOL_QUEUE_SIZE; | ||
714 | unsol->rp = rp; | ||
715 | rp <<= 1; | ||
716 | res = unsol->queue[rp]; | ||
717 | caddr = unsol->queue[rp + 1]; | ||
718 | if (!(caddr & (1 << 4))) /* no unsolicited event? */ | ||
719 | continue; | ||
720 | codec = bus->caddr_tbl[caddr & 0x0f]; | ||
721 | if (codec && codec->patch_ops.unsol_event) | ||
722 | codec->patch_ops.unsol_event(codec, res); | ||
723 | } | ||
724 | } | ||
725 | |||
726 | /* | 650 | /* |
727 | * destructor | 651 | * destructor |
728 | */ | 652 | */ |
@@ -730,11 +654,9 @@ static void snd_hda_bus_free(struct hda_bus *bus) | |||
730 | { | 654 | { |
731 | if (!bus) | 655 | if (!bus) |
732 | return; | 656 | return; |
733 | |||
734 | WARN_ON(!list_empty(&bus->codec_list)); | ||
735 | cancel_work_sync(&bus->unsol.work); | ||
736 | if (bus->ops.private_free) | 657 | if (bus->ops.private_free) |
737 | bus->ops.private_free(bus); | 658 | bus->ops.private_free(bus); |
659 | snd_hdac_bus_exit(&bus->core); | ||
738 | kfree(bus); | 660 | kfree(bus); |
739 | } | 661 | } |
740 | 662 | ||
@@ -751,6 +673,26 @@ static int snd_hda_bus_dev_disconnect(struct snd_device *device) | |||
751 | return 0; | 673 | return 0; |
752 | } | 674 | } |
753 | 675 | ||
676 | /* hdac_bus_ops translations */ | ||
677 | static int _hda_bus_command(struct hdac_bus *_bus, unsigned int cmd) | ||
678 | { | ||
679 | struct hda_bus *bus = container_of(_bus, struct hda_bus, core); | ||
680 | return bus->ops.command(bus, cmd); | ||
681 | } | ||
682 | |||
683 | static int _hda_bus_get_response(struct hdac_bus *_bus, unsigned int addr, | ||
684 | unsigned int *res) | ||
685 | { | ||
686 | struct hda_bus *bus = container_of(_bus, struct hda_bus, core); | ||
687 | *res = bus->ops.get_response(bus, addr); | ||
688 | return bus->rirb_error ? -EIO : 0; | ||
689 | } | ||
690 | |||
691 | static const struct hdac_bus_ops bus_ops = { | ||
692 | .command = _hda_bus_command, | ||
693 | .get_response = _hda_bus_get_response, | ||
694 | }; | ||
695 | |||
754 | /** | 696 | /** |
755 | * snd_hda_bus_new - create a HDA bus | 697 | * snd_hda_bus_new - create a HDA bus |
756 | * @card: the card entry | 698 | * @card: the card entry |
@@ -775,11 +717,14 @@ int snd_hda_bus_new(struct snd_card *card, | |||
775 | if (!bus) | 717 | if (!bus) |
776 | return -ENOMEM; | 718 | return -ENOMEM; |
777 | 719 | ||
720 | err = snd_hdac_bus_init(&bus->core, card->dev, &bus_ops); | ||
721 | if (err < 0) { | ||
722 | kfree(bus); | ||
723 | return err; | ||
724 | } | ||
725 | |||
778 | bus->card = card; | 726 | bus->card = card; |
779 | mutex_init(&bus->cmd_mutex); | ||
780 | mutex_init(&bus->prepare_mutex); | 727 | mutex_init(&bus->prepare_mutex); |
781 | INIT_LIST_HEAD(&bus->codec_list); | ||
782 | INIT_WORK(&bus->unsol.work, process_unsol_events); | ||
783 | 728 | ||
784 | err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops); | 729 | err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops); |
785 | if (err < 0) { | 730 | if (err < 0) { |
@@ -1233,9 +1178,7 @@ static void snd_hda_codec_dev_release(struct device *dev) | |||
1233 | struct hda_codec *codec = dev_to_hda_codec(dev); | 1178 | struct hda_codec *codec = dev_to_hda_codec(dev); |
1234 | 1179 | ||
1235 | free_init_pincfgs(codec); | 1180 | free_init_pincfgs(codec); |
1236 | list_del(&codec->list); | 1181 | snd_hdac_bus_remove_device(&codec->bus->core, &codec->core); |
1237 | codec->bus->caddr_tbl[codec->addr] = NULL; | ||
1238 | clear_bit(codec->addr, &codec->bus->codec_powered); | ||
1239 | snd_hda_sysfs_clear(codec); | 1182 | snd_hda_sysfs_clear(codec); |
1240 | free_hda_cache(&codec->amp_cache); | 1183 | free_hda_cache(&codec->amp_cache); |
1241 | free_hda_cache(&codec->cmd_cache); | 1184 | free_hda_cache(&codec->cmd_cache); |
@@ -1243,7 +1186,6 @@ static void snd_hda_codec_dev_release(struct device *dev) | |||
1243 | kfree(codec->chip_name); | 1186 | kfree(codec->chip_name); |
1244 | kfree(codec->modelname); | 1187 | kfree(codec->modelname); |
1245 | kfree(codec->wcaps); | 1188 | kfree(codec->wcaps); |
1246 | codec->bus->num_codecs--; | ||
1247 | kfree(codec); | 1189 | kfree(codec); |
1248 | } | 1190 | } |
1249 | 1191 | ||
@@ -1274,27 +1216,23 @@ int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card, | |||
1274 | if (snd_BUG_ON(codec_addr > HDA_MAX_CODEC_ADDRESS)) | 1216 | if (snd_BUG_ON(codec_addr > HDA_MAX_CODEC_ADDRESS)) |
1275 | return -EINVAL; | 1217 | return -EINVAL; |
1276 | 1218 | ||
1277 | if (bus->caddr_tbl[codec_addr]) { | ||
1278 | dev_err(card->dev, | ||
1279 | "address 0x%x is already occupied\n", | ||
1280 | codec_addr); | ||
1281 | return -EBUSY; | ||
1282 | } | ||
1283 | |||
1284 | codec = kzalloc(sizeof(*codec), GFP_KERNEL); | 1219 | codec = kzalloc(sizeof(*codec), GFP_KERNEL); |
1285 | if (!codec) | 1220 | if (!codec) |
1286 | return -ENOMEM; | 1221 | return -ENOMEM; |
1287 | 1222 | ||
1223 | codec->core.bus = &bus->core; | ||
1224 | codec->core.addr = codec_addr; | ||
1225 | codec->core.type = HDA_DEV_LEGACY; | ||
1226 | |||
1288 | dev = hda_codec_dev(codec); | 1227 | dev = hda_codec_dev(codec); |
1289 | device_initialize(dev); | 1228 | device_initialize(dev); |
1290 | dev->parent = card->dev; | 1229 | dev->parent = bus->core.dev; |
1291 | dev->bus = &snd_hda_bus_type; | 1230 | dev->bus = &snd_hda_bus_type; |
1292 | dev->release = snd_hda_codec_dev_release; | 1231 | dev->release = snd_hda_codec_dev_release; |
1293 | dev->groups = snd_hda_dev_attr_groups; | 1232 | dev->groups = snd_hda_dev_attr_groups; |
1294 | dev_set_name(dev, "hdaudioC%dD%d", card->number, codec_addr); | 1233 | dev_set_name(dev, "hdaudioC%dD%d", card->number, codec_addr); |
1295 | dev_set_drvdata(dev, codec); /* for sysfs */ | 1234 | dev_set_drvdata(dev, codec); /* for sysfs */ |
1296 | device_enable_async_suspend(dev); | 1235 | device_enable_async_suspend(dev); |
1297 | codec->core.type = HDA_DEV_LEGACY; | ||
1298 | 1236 | ||
1299 | codec->bus = bus; | 1237 | codec->bus = bus; |
1300 | codec->card = card; | 1238 | codec->card = card; |
@@ -1323,7 +1261,7 @@ int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card, | |||
1323 | /* snd_hda_codec_new() marks the codec as power-up, and leave it as is. | 1261 | /* snd_hda_codec_new() marks the codec as power-up, and leave it as is. |
1324 | * it's powered down later in snd_hda_codec_dev_register(). | 1262 | * it's powered down later in snd_hda_codec_dev_register(). |
1325 | */ | 1263 | */ |
1326 | set_bit(codec->addr, &bus->codec_powered); | 1264 | set_bit(codec->core.addr, &bus->core.codec_powered); |
1327 | pm_runtime_set_active(hda_codec_dev(codec)); | 1265 | pm_runtime_set_active(hda_codec_dev(codec)); |
1328 | pm_runtime_get_noresume(hda_codec_dev(codec)); | 1266 | pm_runtime_get_noresume(hda_codec_dev(codec)); |
1329 | codec->power_jiffies = jiffies; | 1267 | codec->power_jiffies = jiffies; |
@@ -1339,10 +1277,9 @@ int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card, | |||
1339 | } | 1277 | } |
1340 | } | 1278 | } |
1341 | 1279 | ||
1342 | list_add_tail(&codec->list, &bus->codec_list); | 1280 | err = snd_hdac_bus_add_device(&bus->core, &codec->core); |
1343 | bus->num_codecs++; | 1281 | if (err < 0) |
1344 | 1282 | goto error; | |
1345 | bus->caddr_tbl[codec_addr] = codec; | ||
1346 | 1283 | ||
1347 | codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, | 1284 | codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, |
1348 | AC_PAR_VENDOR_ID); | 1285 | AC_PAR_VENDOR_ID); |
@@ -1516,7 +1453,7 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
1516 | 1453 | ||
1517 | /* make other inactive cvts with the same stream-tag dirty */ | 1454 | /* make other inactive cvts with the same stream-tag dirty */ |
1518 | type = get_wcaps_type(get_wcaps(codec, nid)); | 1455 | type = get_wcaps_type(get_wcaps(codec, nid)); |
1519 | list_for_each_entry(c, &codec->bus->codec_list, list) { | 1456 | list_for_each_codec(c, codec->bus) { |
1520 | for (i = 0; i < c->cvt_setups.used; i++) { | 1457 | for (i = 0; i < c->cvt_setups.used; i++) { |
1521 | p = snd_array_elem(&c->cvt_setups, i); | 1458 | p = snd_array_elem(&c->cvt_setups, i); |
1522 | if (!p->active && p->stream_tag == stream_tag && | 1459 | if (!p->active && p->stream_tag == stream_tag && |
@@ -1583,7 +1520,7 @@ static void purify_inactive_streams(struct hda_codec *codec) | |||
1583 | struct hda_codec *c; | 1520 | struct hda_codec *c; |
1584 | int i; | 1521 | int i; |
1585 | 1522 | ||
1586 | list_for_each_entry(c, &codec->bus->codec_list, list) { | 1523 | list_for_each_codec(c, codec->bus) { |
1587 | for (i = 0; i < c->cvt_setups.used; i++) { | 1524 | for (i = 0; i < c->cvt_setups.used; i++) { |
1588 | struct hda_cvt_setup *p; | 1525 | struct hda_cvt_setup *p; |
1589 | p = snd_array_elem(&c->cvt_setups, i); | 1526 | p = snd_array_elem(&c->cvt_setups, i); |
@@ -2436,7 +2373,7 @@ int snd_hda_lock_devices(struct hda_bus *bus) | |||
2436 | if (!list_empty(&card->ctl_files)) | 2373 | if (!list_empty(&card->ctl_files)) |
2437 | goto err_clear; | 2374 | goto err_clear; |
2438 | 2375 | ||
2439 | list_for_each_entry(codec, &bus->codec_list, list) { | 2376 | list_for_each_codec(codec, bus) { |
2440 | struct hda_pcm *cpcm; | 2377 | struct hda_pcm *cpcm; |
2441 | list_for_each_entry(cpcm, &codec->pcm_list_head, list) { | 2378 | list_for_each_entry(cpcm, &codec->pcm_list_head, list) { |
2442 | if (!cpcm->pcm) | 2379 | if (!cpcm->pcm) |
@@ -3607,13 +3544,13 @@ int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, | |||
3607 | verb = verb | (parm >> 8); | 3544 | verb = verb | (parm >> 8); |
3608 | parm &= 0xff; | 3545 | parm &= 0xff; |
3609 | key = build_cmd_cache_key(nid, verb); | 3546 | key = build_cmd_cache_key(nid, verb); |
3610 | mutex_lock(&codec->bus->cmd_mutex); | 3547 | mutex_lock(&codec->bus->core.cmd_mutex); |
3611 | c = get_alloc_hash(&codec->cmd_cache, key); | 3548 | c = get_alloc_hash(&codec->cmd_cache, key); |
3612 | if (c) { | 3549 | if (c) { |
3613 | c->val = parm; | 3550 | c->val = parm; |
3614 | c->dirty = cache_only; | 3551 | c->dirty = cache_only; |
3615 | } | 3552 | } |
3616 | mutex_unlock(&codec->bus->cmd_mutex); | 3553 | mutex_unlock(&codec->bus->core.cmd_mutex); |
3617 | return 0; | 3554 | return 0; |
3618 | } | 3555 | } |
3619 | EXPORT_SYMBOL_GPL(snd_hda_codec_write_cache); | 3556 | EXPORT_SYMBOL_GPL(snd_hda_codec_write_cache); |
@@ -3642,13 +3579,13 @@ int snd_hda_codec_update_cache(struct hda_codec *codec, hda_nid_t nid, | |||
3642 | verb = verb | (parm >> 8); | 3579 | verb = verb | (parm >> 8); |
3643 | parm &= 0xff; | 3580 | parm &= 0xff; |
3644 | key = build_cmd_cache_key(nid, verb); | 3581 | key = build_cmd_cache_key(nid, verb); |
3645 | mutex_lock(&codec->bus->cmd_mutex); | 3582 | mutex_lock(&codec->bus->core.cmd_mutex); |
3646 | c = get_hash(&codec->cmd_cache, key); | 3583 | c = get_hash(&codec->cmd_cache, key); |
3647 | if (c && c->val == parm) { | 3584 | if (c && c->val == parm) { |
3648 | mutex_unlock(&codec->bus->cmd_mutex); | 3585 | mutex_unlock(&codec->bus->core.cmd_mutex); |
3649 | return 0; | 3586 | return 0; |
3650 | } | 3587 | } |
3651 | mutex_unlock(&codec->bus->cmd_mutex); | 3588 | mutex_unlock(&codec->bus->core.cmd_mutex); |
3652 | return snd_hda_codec_write_cache(codec, nid, flags, verb, parm); | 3589 | return snd_hda_codec_write_cache(codec, nid, flags, verb, parm); |
3653 | } | 3590 | } |
3654 | EXPORT_SYMBOL_GPL(snd_hda_codec_update_cache); | 3591 | EXPORT_SYMBOL_GPL(snd_hda_codec_update_cache); |
@@ -3927,7 +3864,6 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec) | |||
3927 | codec->patch_ops.suspend(codec); | 3864 | codec->patch_ops.suspend(codec); |
3928 | hda_cleanup_all_streams(codec); | 3865 | hda_cleanup_all_streams(codec); |
3929 | state = hda_set_power_state(codec, AC_PWRST_D3); | 3866 | state = hda_set_power_state(codec, AC_PWRST_D3); |
3930 | trace_hda_power_down(codec); | ||
3931 | update_power_acct(codec, true); | 3867 | update_power_acct(codec, true); |
3932 | atomic_dec(&codec->in_pm); | 3868 | atomic_dec(&codec->in_pm); |
3933 | return state; | 3869 | return state; |
@@ -3956,7 +3892,6 @@ static void hda_call_codec_resume(struct hda_codec *codec) | |||
3956 | { | 3892 | { |
3957 | atomic_inc(&codec->in_pm); | 3893 | atomic_inc(&codec->in_pm); |
3958 | 3894 | ||
3959 | trace_hda_power_up(codec); | ||
3960 | hda_mark_cmd_cache_dirty(codec); | 3895 | hda_mark_cmd_cache_dirty(codec); |
3961 | 3896 | ||
3962 | codec->power_jiffies = jiffies; | 3897 | codec->power_jiffies = jiffies; |
@@ -3992,7 +3927,7 @@ static int hda_codec_runtime_suspend(struct device *dev) | |||
3992 | snd_pcm_suspend_all(pcm->pcm); | 3927 | snd_pcm_suspend_all(pcm->pcm); |
3993 | state = hda_call_codec_suspend(codec); | 3928 | state = hda_call_codec_suspend(codec); |
3994 | if (codec->d3_stop_clk && codec->epss && (state & AC_PWRST_CLK_STOP_OK)) | 3929 | if (codec->d3_stop_clk && codec->epss && (state & AC_PWRST_CLK_STOP_OK)) |
3995 | clear_bit(codec->addr, &codec->bus->codec_powered); | 3930 | clear_bit(codec->core.addr, &codec->bus->core.codec_powered); |
3996 | return 0; | 3931 | return 0; |
3997 | } | 3932 | } |
3998 | 3933 | ||
@@ -4000,7 +3935,7 @@ static int hda_codec_runtime_resume(struct device *dev) | |||
4000 | { | 3935 | { |
4001 | struct hda_codec *codec = dev_to_hda_codec(dev); | 3936 | struct hda_codec *codec = dev_to_hda_codec(dev); |
4002 | 3937 | ||
4003 | set_bit(codec->addr, &codec->bus->codec_powered); | 3938 | set_bit(codec->core.addr, &codec->bus->core.codec_powered); |
4004 | hda_call_codec_resume(codec); | 3939 | hda_call_codec_resume(codec); |
4005 | pm_runtime_mark_last_busy(dev); | 3940 | pm_runtime_mark_last_busy(dev); |
4006 | return 0; | 3941 | return 0; |
@@ -4582,7 +4517,7 @@ int snd_hda_codec_parse_pcms(struct hda_codec *codec) | |||
4582 | err = codec->patch_ops.build_pcms(codec); | 4517 | err = codec->patch_ops.build_pcms(codec); |
4583 | if (err < 0) { | 4518 | if (err < 0) { |
4584 | codec_err(codec, "cannot build PCMs for #%d (error %d)\n", | 4519 | codec_err(codec, "cannot build PCMs for #%d (error %d)\n", |
4585 | codec->addr, err); | 4520 | codec->core.addr, err); |
4586 | return err; | 4521 | return err; |
4587 | } | 4522 | } |
4588 | 4523 | ||
@@ -4638,7 +4573,7 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec) | |||
4638 | if (err < 0) { | 4573 | if (err < 0) { |
4639 | codec_err(codec, | 4574 | codec_err(codec, |
4640 | "cannot attach PCM stream %d for codec #%d\n", | 4575 | "cannot attach PCM stream %d for codec #%d\n", |
4641 | dev, codec->addr); | 4576 | dev, codec->core.addr); |
4642 | continue; /* no fatal error */ | 4577 | continue; /* no fatal error */ |
4643 | } | 4578 | } |
4644 | } | 4579 | } |
@@ -4681,8 +4616,8 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, | |||
4681 | * the codec addr; if it still fails (or it's the | 4616 | * the codec addr; if it still fails (or it's the |
4682 | * primary codec), then try another control index | 4617 | * primary codec), then try another control index |
4683 | */ | 4618 | */ |
4684 | if (!addr && codec->addr) | 4619 | if (!addr && codec->core.addr) |
4685 | addr = codec->addr; | 4620 | addr = codec->core.addr; |
4686 | else if (!idx && !knew->index) { | 4621 | else if (!idx && !knew->index) { |
4687 | idx = find_empty_mixer_ctl_idx(codec, | 4622 | idx = find_empty_mixer_ctl_idx(codec, |
4688 | knew->name, 0); | 4623 | knew->name, 0); |
@@ -4757,7 +4692,7 @@ void snd_hda_set_power_save(struct hda_bus *bus, int delay) | |||
4757 | { | 4692 | { |
4758 | struct hda_codec *c; | 4693 | struct hda_codec *c; |
4759 | 4694 | ||
4760 | list_for_each_entry(c, &bus->codec_list, list) | 4695 | list_for_each_codec(c, bus) |
4761 | codec_set_power_save(c, delay); | 4696 | codec_set_power_save(c, delay); |
4762 | } | 4697 | } |
4763 | EXPORT_SYMBOL_GPL(snd_hda_set_power_save); | 4698 | EXPORT_SYMBOL_GPL(snd_hda_set_power_save); |
@@ -5344,7 +5279,7 @@ void snd_hda_bus_reset(struct hda_bus *bus) | |||
5344 | { | 5279 | { |
5345 | struct hda_codec *codec; | 5280 | struct hda_codec *codec; |
5346 | 5281 | ||
5347 | list_for_each_entry(codec, &bus->codec_list, list) { | 5282 | list_for_each_codec(codec, bus) { |
5348 | /* FIXME: maybe a better way needed for forced reset */ | 5283 | /* FIXME: maybe a better way needed for forced reset */ |
5349 | cancel_delayed_work_sync(&codec->jackpoll_work); | 5284 | cancel_delayed_work_sync(&codec->jackpoll_work); |
5350 | #ifdef CONFIG_PM | 5285 | #ifdef CONFIG_PM |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 31a9e10e5137..6efcb4ad6935 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -98,16 +98,6 @@ struct hda_bus_ops { | |||
98 | #endif | 98 | #endif |
99 | }; | 99 | }; |
100 | 100 | ||
101 | /* unsolicited event handler */ | ||
102 | #define HDA_UNSOL_QUEUE_SIZE 64 | ||
103 | struct hda_bus_unsolicited { | ||
104 | /* ring buffer */ | ||
105 | u32 queue[HDA_UNSOL_QUEUE_SIZE * 2]; | ||
106 | unsigned int rp, wp; | ||
107 | /* workqueue */ | ||
108 | struct work_struct work; | ||
109 | }; | ||
110 | |||
111 | /* | 101 | /* |
112 | * codec bus | 102 | * codec bus |
113 | * | 103 | * |
@@ -115,6 +105,8 @@ struct hda_bus_unsolicited { | |||
115 | * A hda_bus contains several codecs in the list codec_list. | 105 | * A hda_bus contains several codecs in the list codec_list. |
116 | */ | 106 | */ |
117 | struct hda_bus { | 107 | struct hda_bus { |
108 | struct hdac_bus core; | ||
109 | |||
118 | struct snd_card *card; | 110 | struct snd_card *card; |
119 | 111 | ||
120 | void *private_data; | 112 | void *private_data; |
@@ -122,25 +114,14 @@ struct hda_bus { | |||
122 | const char *modelname; | 114 | const char *modelname; |
123 | struct hda_bus_ops ops; | 115 | struct hda_bus_ops ops; |
124 | 116 | ||
125 | /* codec linked list */ | ||
126 | struct list_head codec_list; | ||
127 | unsigned int num_codecs; | ||
128 | /* link caddr -> codec */ | ||
129 | struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1]; | ||
130 | |||
131 | struct mutex cmd_mutex; | ||
132 | struct mutex prepare_mutex; | 117 | struct mutex prepare_mutex; |
133 | 118 | ||
134 | /* unsolicited event queue */ | ||
135 | struct hda_bus_unsolicited unsol; | ||
136 | |||
137 | /* assigned PCMs */ | 119 | /* assigned PCMs */ |
138 | DECLARE_BITMAP(pcm_dev_bits, SNDRV_PCM_DEVICES); | 120 | DECLARE_BITMAP(pcm_dev_bits, SNDRV_PCM_DEVICES); |
139 | 121 | ||
140 | /* misc op flags */ | 122 | /* misc op flags */ |
141 | unsigned int needs_damn_long_delay :1; | 123 | unsigned int needs_damn_long_delay :1; |
142 | unsigned int allow_bus_reset:1; /* allow bus reset at fatal error */ | 124 | unsigned int allow_bus_reset:1; /* allow bus reset at fatal error */ |
143 | unsigned int sync_write:1; /* sync after verb write */ | ||
144 | /* status for codec/controller */ | 125 | /* status for codec/controller */ |
145 | unsigned int shutdown :1; /* being unloaded */ | 126 | unsigned int shutdown :1; /* being unloaded */ |
146 | unsigned int rirb_error:1; /* error in codec communication */ | 127 | unsigned int rirb_error:1; /* error in codec communication */ |
@@ -149,7 +130,6 @@ struct hda_bus { | |||
149 | unsigned int no_response_fallback:1; /* don't fallback at RIRB error */ | 130 | unsigned int no_response_fallback:1; /* don't fallback at RIRB error */ |
150 | 131 | ||
151 | int primary_dig_out_type; /* primary digital out PCM type */ | 132 | int primary_dig_out_type; /* primary digital out PCM type */ |
152 | unsigned long codec_powered; /* bit flags of powered codecs */ | ||
153 | }; | 133 | }; |
154 | 134 | ||
155 | /* | 135 | /* |
@@ -281,7 +261,6 @@ struct hda_codec { | |||
281 | struct hda_bus *bus; | 261 | struct hda_bus *bus; |
282 | struct snd_card *card; | 262 | struct snd_card *card; |
283 | unsigned int addr; /* codec addr*/ | 263 | unsigned int addr; /* codec addr*/ |
284 | struct list_head list; /* list point */ | ||
285 | 264 | ||
286 | hda_nid_t afg; /* AFG node id */ | 265 | hda_nid_t afg; /* AFG node id */ |
287 | hda_nid_t mfg; /* MFG node id */ | 266 | hda_nid_t mfg; /* MFG node id */ |
@@ -413,6 +392,9 @@ struct hda_codec { | |||
413 | #define dev_to_hda_codec(_dev) container_of(_dev, struct hda_codec, core.dev) | 392 | #define dev_to_hda_codec(_dev) container_of(_dev, struct hda_codec, core.dev) |
414 | #define hda_codec_dev(_dev) (&(_dev)->core.dev) | 393 | #define hda_codec_dev(_dev) (&(_dev)->core.dev) |
415 | 394 | ||
395 | #define list_for_each_codec(c, bus) \ | ||
396 | list_for_each_entry(c, &(bus)->core.codec_list, core.list) | ||
397 | |||
416 | /* direction */ | 398 | /* direction */ |
417 | enum { | 399 | enum { |
418 | HDA_INPUT, HDA_OUTPUT | 400 | HDA_INPUT, HDA_OUTPUT |
@@ -473,7 +455,11 @@ void snd_hda_sequence_write(struct hda_codec *codec, | |||
473 | const struct hda_verb *seq); | 455 | const struct hda_verb *seq); |
474 | 456 | ||
475 | /* unsolicited event */ | 457 | /* unsolicited event */ |
476 | int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex); | 458 | static inline void |
459 | snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex) | ||
460 | { | ||
461 | snd_hdac_bus_queue_event(&bus->core, res, res_ex); | ||
462 | } | ||
477 | 463 | ||
478 | /* cached write */ | 464 | /* cached write */ |
479 | int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, | 465 | int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, |
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c index 4fd0b2ef26e9..26ce990592a0 100644 --- a/sound/pci/hda/hda_controller.c +++ b/sound/pci/hda/hda_controller.c | |||
@@ -1764,12 +1764,12 @@ static int probe_codec(struct azx *chip, int addr) | |||
1764 | (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID; | 1764 | (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID; |
1765 | unsigned int res; | 1765 | unsigned int res; |
1766 | 1766 | ||
1767 | mutex_lock(&chip->bus->cmd_mutex); | 1767 | mutex_lock(&chip->bus->core.cmd_mutex); |
1768 | chip->probing = 1; | 1768 | chip->probing = 1; |
1769 | azx_send_cmd(chip->bus, cmd); | 1769 | azx_send_cmd(chip->bus, cmd); |
1770 | res = azx_get_response(chip->bus, addr); | 1770 | res = azx_get_response(chip->bus, addr); |
1771 | chip->probing = 0; | 1771 | chip->probing = 0; |
1772 | mutex_unlock(&chip->bus->cmd_mutex); | 1772 | mutex_unlock(&chip->bus->core.cmd_mutex); |
1773 | if (res == -1) | 1773 | if (res == -1) |
1774 | return -EIO; | 1774 | return -EIO; |
1775 | dev_dbg(chip->card->dev, "codec #%d probed OK\n", addr); | 1775 | dev_dbg(chip->card->dev, "codec #%d probed OK\n", addr); |
@@ -1848,7 +1848,7 @@ int azx_bus_create(struct azx *chip, const char *model) | |||
1848 | */ | 1848 | */ |
1849 | if (chip->driver_caps & AZX_DCAPS_SYNC_WRITE) { | 1849 | if (chip->driver_caps & AZX_DCAPS_SYNC_WRITE) { |
1850 | dev_dbg(chip->card->dev, "Enable sync_write for stable communication\n"); | 1850 | dev_dbg(chip->card->dev, "Enable sync_write for stable communication\n"); |
1851 | bus->sync_write = 1; | 1851 | bus->core.sync_write = 1; |
1852 | bus->allow_bus_reset = 1; | 1852 | bus->allow_bus_reset = 1; |
1853 | } | 1853 | } |
1854 | 1854 | ||
@@ -1913,7 +1913,7 @@ EXPORT_SYMBOL_GPL(azx_probe_codecs); | |||
1913 | int azx_codec_configure(struct azx *chip) | 1913 | int azx_codec_configure(struct azx *chip) |
1914 | { | 1914 | { |
1915 | struct hda_codec *codec; | 1915 | struct hda_codec *codec; |
1916 | list_for_each_entry(codec, &chip->bus->codec_list, list) { | 1916 | list_for_each_codec(codec, chip->bus) { |
1917 | snd_hda_codec_configure(codec); | 1917 | snd_hda_codec_configure(codec); |
1918 | } | 1918 | } |
1919 | return 0; | 1919 | return 0; |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 060f7a2b1aeb..feebc1dda912 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -891,7 +891,7 @@ static int azx_runtime_resume(struct device *dev) | |||
891 | 891 | ||
892 | bus = chip->bus; | 892 | bus = chip->bus; |
893 | if (status && bus) { | 893 | if (status && bus) { |
894 | list_for_each_entry(codec, &bus->codec_list, list) | 894 | list_for_each_codec(codec, bus) |
895 | if (status & (1 << codec->addr)) | 895 | if (status & (1 << codec->addr)) |
896 | schedule_delayed_work(&codec->jackpoll_work, | 896 | schedule_delayed_work(&codec->jackpoll_work, |
897 | codec->jackpoll_interval); | 897 | codec->jackpoll_interval); |
@@ -919,7 +919,7 @@ static int azx_runtime_idle(struct device *dev) | |||
919 | return 0; | 919 | return 0; |
920 | 920 | ||
921 | if (!power_save_controller || !azx_has_pm_runtime(chip) || | 921 | if (!power_save_controller || !azx_has_pm_runtime(chip) || |
922 | chip->bus->codec_powered) | 922 | chip->bus->core.codec_powered) |
923 | return -EBUSY; | 923 | return -EBUSY; |
924 | 924 | ||
925 | return 0; | 925 | return 0; |
diff --git a/sound/pci/hda/hda_sysfs.c b/sound/pci/hda/hda_sysfs.c index e13c75d67847..3b5ed1108f9f 100644 --- a/sound/pci/hda/hda_sysfs.c +++ b/sound/pci/hda/hda_sysfs.c | |||
@@ -552,7 +552,7 @@ static void parse_codec_mode(char *buf, struct hda_bus *bus, | |||
552 | 552 | ||
553 | *codecp = NULL; | 553 | *codecp = NULL; |
554 | if (sscanf(buf, "%i %i %i", &vendorid, &subid, &caddr) == 3) { | 554 | if (sscanf(buf, "%i %i %i", &vendorid, &subid, &caddr) == 3) { |
555 | list_for_each_entry(codec, &bus->codec_list, list) { | 555 | list_for_each_codec(codec, bus) { |
556 | if ((vendorid <= 0 || codec->vendor_id == vendorid) && | 556 | if ((vendorid <= 0 || codec->vendor_id == vendorid) && |
557 | (subid <= 0 || codec->subsystem_id == subid) && | 557 | (subid <= 0 || codec->subsystem_id == subid) && |
558 | codec->addr == caddr) { | 558 | codec->addr == caddr) { |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 5aa466a13e43..142a6cf786da 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -919,10 +919,10 @@ static int patch_conexant_auto(struct hda_codec *codec) | |||
919 | * which falls into the single-cmd mode. | 919 | * which falls into the single-cmd mode. |
920 | * Better to make reset, then. | 920 | * Better to make reset, then. |
921 | */ | 921 | */ |
922 | if (!codec->bus->sync_write) { | 922 | if (!codec->bus->core.sync_write) { |
923 | codec_info(codec, | 923 | codec_info(codec, |
924 | "Enable sync_write for stable communication\n"); | 924 | "Enable sync_write for stable communication\n"); |
925 | codec->bus->sync_write = 1; | 925 | codec->bus->core.sync_write = 1; |
926 | codec->bus->allow_bus_reset = 1; | 926 | codec->bus->allow_bus_reset = 1; |
927 | } | 927 | } |
928 | 928 | ||