Lines Matching +full:no +full:- +full:wp
1 // SPDX-License-Identifier: GPL-2.0-only
3 * HD-audio core bus driver
24 * snd_hdac_bus_init - initialize a HD-audio bas bus
35 bus->dev = dev;
37 bus->ops = ops;
39 bus->ops = &default_ops;
40 bus->dma_type = SNDRV_DMA_TYPE_DEV;
41 INIT_LIST_HEAD(&bus->stream_list);
42 INIT_LIST_HEAD(&bus->codec_list);
43 INIT_WORK(&bus->unsol_work, snd_hdac_bus_process_unsol_events);
44 spin_lock_init(&bus->reg_lock);
45 mutex_init(&bus->cmd_mutex);
46 mutex_init(&bus->lock);
47 INIT_LIST_HEAD(&bus->hlink_list);
48 init_waitqueue_head(&bus->rirb_wq);
49 bus->irq = -1;
60 bus->sdo_limit = 8;
67 * snd_hdac_bus_exit - clean up a HD-audio bas bus
72 WARN_ON(!list_empty(&bus->stream_list));
73 WARN_ON(!list_empty(&bus->codec_list));
74 cancel_work_sync(&bus->unsol_work);
79 * snd_hdac_bus_exec_verb - execute a HD-audio verb on the given bus
82 * @cmd: HD-audio encoded verb
90 guard(mutex)(&bus->cmd_mutex);
95 * snd_hdac_bus_exec_verb_unlocked - unlocked version
98 * @cmd: HD-audio encoded verb
110 return -EINVAL;
113 *res = -1;
114 else if (bus->sync_write)
118 err = bus->ops->command(bus, cmd);
119 if (err != -EAGAIN)
122 err = bus->ops->get_response(bus, addr, &tmp);
127 err = bus->ops->get_response(bus, addr, res);
135 * snd_hdac_bus_queue_event - add an unsolicited event to queue
146 unsigned int wp;
152 wp = (bus->unsol_wp + 1) % HDA_UNSOL_QUEUE_SIZE;
153 bus->unsol_wp = wp;
155 wp <<= 1;
156 bus->unsol_queue[wp] = res;
157 bus->unsol_queue[wp + 1] = res_ex;
159 schedule_work(&bus->unsol_work);
172 spin_lock_irq(&bus->reg_lock);
173 while (bus->unsol_rp != bus->unsol_wp) {
174 rp = (bus->unsol_rp + 1) % HDA_UNSOL_QUEUE_SIZE;
175 bus->unsol_rp = rp;
177 res = bus->unsol_queue[rp];
178 caddr = bus->unsol_queue[rp + 1];
179 if (!(caddr & (1 << 4))) /* no unsolicited event? */
181 codec = bus->caddr_tbl[caddr & 0x0f];
182 if (!codec || !codec->registered)
184 spin_unlock_irq(&bus->reg_lock);
185 drv = drv_to_hdac_driver(codec->dev.driver);
186 if (drv->unsol_event)
187 drv->unsol_event(codec, res);
188 spin_lock_irq(&bus->reg_lock);
190 spin_unlock_irq(&bus->reg_lock);
194 * snd_hdac_bus_add_device - Add a codec to bus
204 if (bus->caddr_tbl[codec->addr]) {
205 dev_err(bus->dev, "address 0x%x is already occupied\n",
206 codec->addr);
207 return -EBUSY;
210 list_add_tail(&codec->list, &bus->codec_list);
211 bus->caddr_tbl[codec->addr] = codec;
212 set_bit(codec->addr, &bus->codec_powered);
213 bus->num_codecs++;
218 * snd_hdac_bus_remove_device - Remove a codec from bus
225 WARN_ON(bus != codec->bus);
226 if (list_empty(&codec->list))
228 list_del_init(&codec->list);
229 bus->caddr_tbl[codec->addr] = NULL;
230 clear_bit(codec->addr, &bus->codec_powered);
231 bus->num_codecs--;
232 flush_work(&bus->unsol_work);
267 struct hdac_bus *bus = codec->bus;
269 if (bus->ops->link_power)
270 bus->ops->link_power(codec, true);
278 struct hdac_bus *bus = codec->bus;
280 if (bus->ops->link_power)
281 bus->ops->link_power(codec, false);