File Index
Files and directories
Sign in
FILE

controller.c

File preview with syntax highlighting.

linux-6.19.14/sound/hda/core/controller.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * HD-audio controller helpers
  4 */
  5
  6#include <linux/kernel.h>
  7#include <linux/delay.h>
  8#include <linux/export.h>
  9#include <sound/core.h>
 10#include <sound/hdaudio.h>
 11#include <sound/hda_register.h>
 12#include "local.h"
 13
 14/* clear CORB read pointer properly */
 15static void azx_clear_corbrp(struct hdac_bus *bus)
 16{
 17	int timeout;
 18
 19	for (timeout = 1000; timeout > 0; timeout--) {
 20		if (snd_hdac_chip_readw(bus, CORBRP) & AZX_CORBRP_RST)
 21			break;
 22		udelay(1);
 23	}
 24	if (timeout <= 0)
 25		dev_err(bus->dev, "CORB reset timeout#1, CORBRP = %d\n",
 26			snd_hdac_chip_readw(bus, CORBRP));
 27
 28	snd_hdac_chip_writew(bus, CORBRP, 0);
 29	for (timeout = 1000; timeout > 0; timeout--) {
 30		if (snd_hdac_chip_readw(bus, CORBRP) == 0)
 31			break;
 32		udelay(1);
 33	}
 34	if (timeout <= 0)
 35		dev_err(bus->dev, "CORB reset timeout#2, CORBRP = %d\n",
 36			snd_hdac_chip_readw(bus, CORBRP));
 37}
 38
 39/**
 40 * snd_hdac_bus_init_cmd_io - set up CORB/RIRB buffers
 41 * @bus: HD-audio core bus
 42 */
 43void snd_hdac_bus_init_cmd_io(struct hdac_bus *bus)
 44{
 45	WARN_ON_ONCE(!bus->rb.area);
 46
 47	guard(spinlock_irq)(&bus->reg_lock);
 48	/* CORB set up */
 49	bus->corb.addr = bus->rb.addr;
 50	bus->corb.buf = (__le32 *)bus->rb.area;
 51	snd_hdac_chip_writel(bus, CORBLBASE, (u32)(bus->corb.addr + bus->addr_offset));
 52	snd_hdac_chip_writel(bus, CORBUBASE, upper_32_bits(bus->corb.addr + bus->addr_offset));
 53
 54	/* set the corb size to 256 entries (ULI requires explicitly) */
 55	snd_hdac_chip_writeb(bus, CORBSIZE, 0x02);
 56	/* set the corb write pointer to 0 */
 57	snd_hdac_chip_writew(bus, CORBWP, 0);
 58
 59	/* reset the corb hw read pointer */
 60	snd_hdac_chip_writew(bus, CORBRP, AZX_CORBRP_RST);
 61	if (!bus->corbrp_self_clear)
 62		azx_clear_corbrp(bus);
 63
 64	/* enable corb dma */
 65	if (!bus->use_pio_for_commands)
 66		snd_hdac_chip_writeb(bus, CORBCTL, AZX_CORBCTL_RUN);
 67
 68	/* RIRB set up */
 69	bus->rirb.addr = bus->rb.addr + 2048;
 70	bus->rirb.buf = (__le32 *)(bus->rb.area + 2048);
 71	bus->rirb.wp = bus->rirb.rp = 0;
 72	memset(bus->rirb.cmds, 0, sizeof(bus->rirb.cmds));
 73	snd_hdac_chip_writel(bus, RIRBLBASE, (u32)(bus->rirb.addr + bus->addr_offset));
 74	snd_hdac_chip_writel(bus, RIRBUBASE, upper_32_bits(bus->rirb.addr + bus->addr_offset));
 75
 76	/* set the rirb size to 256 entries (ULI requires explicitly) */
 77	snd_hdac_chip_writeb(bus, RIRBSIZE, 0x02);
 78	/* reset the rirb hw write pointer */
 79	snd_hdac_chip_writew(bus, RIRBWP, AZX_RIRBWP_RST);
 80	/* set N=1, get RIRB response interrupt for new entry */
 81	snd_hdac_chip_writew(bus, RINTCNT, 1);
 82	/* enable rirb dma and response irq */
 83	if (bus->not_use_interrupts)
 84		snd_hdac_chip_writeb(bus, RIRBCTL, AZX_RBCTL_DMA_EN);
 85	else
 86		snd_hdac_chip_writeb(bus, RIRBCTL, AZX_RBCTL_DMA_EN | AZX_RBCTL_IRQ_EN);
 87	/* Accept unsolicited responses */
 88	snd_hdac_chip_updatel(bus, GCTL, AZX_GCTL_UNSOL, AZX_GCTL_UNSOL);
 89}
 90EXPORT_SYMBOL_GPL(snd_hdac_bus_init_cmd_io);
 91
 92/* wait for cmd dmas till they are stopped */
 93static void hdac_wait_for_cmd_dmas(struct hdac_bus *bus)
 94{
 95	unsigned long timeout;
 96
 97	timeout = jiffies + msecs_to_jiffies(100);
 98	while ((snd_hdac_chip_readb(bus, RIRBCTL) & AZX_RBCTL_DMA_EN)
 99		&& time_before(jiffies, timeout))
100		udelay(10);
101
102	timeout = jiffies + msecs_to_jiffies(100);
103	while ((snd_hdac_chip_readb(bus, CORBCTL) & AZX_CORBCTL_RUN)
104		&& time_before(jiffies, timeout))
105		udelay(10);
106}
107
108/**
109 * snd_hdac_bus_stop_cmd_io - clean up CORB/RIRB buffers
110 * @bus: HD-audio core bus
111 */
112void snd_hdac_bus_stop_cmd_io(struct hdac_bus *bus)
113{
114	scoped_guard(spinlock_irq, &bus->reg_lock) {
115		/* disable ringbuffer DMAs */
116		snd_hdac_chip_writeb(bus, RIRBCTL, 0);
117		snd_hdac_chip_writeb(bus, CORBCTL, 0);
118	}
119
120	hdac_wait_for_cmd_dmas(bus);
121
122	guard(spinlock_irq)(&bus->reg_lock);
123	/* disable unsolicited responses */
124	snd_hdac_chip_updatel(bus, GCTL, AZX_GCTL_UNSOL, 0);
125}
126EXPORT_SYMBOL_GPL(snd_hdac_bus_stop_cmd_io);
127
128static unsigned int azx_command_addr(u32 cmd)
129{
130	unsigned int addr = cmd >> 28;
131
132	if (snd_BUG_ON(addr >= HDA_MAX_CODECS))
133		addr = 0;
134	return addr;
135}
136
137/* receive an Immediate Response with PIO */
138static int snd_hdac_bus_wait_for_pio_response(struct hdac_bus *bus,
139					      unsigned int addr)
140{
141	int timeout = 50;
142
143	while (timeout--) {
144		/* check IRV bit */
145		if (snd_hdac_chip_readw(bus, IRS) & AZX_IRS_VALID) {
146			/* reuse rirb.res as the response return value */
147			bus->rirb.res[addr] = snd_hdac_chip_readl(bus, IR);
148			return 0;
149		}
150		udelay(1);
151	}
152
153	dev_dbg_ratelimited(bus->dev, "get_response_pio timeout: IRS=%#x\n",
154			    snd_hdac_chip_readw(bus, IRS));
155
156	bus->rirb.res[addr] = -1;
157
158	return -EIO;
159}
160
161/**
162 * snd_hdac_bus_send_cmd_pio - send a command verb via Immediate Command
163 * @bus: HD-audio core bus
164 * @val: encoded verb value to send
165 *
166 * Returns zero for success or a negative error code.
167 */
168static int snd_hdac_bus_send_cmd_pio(struct hdac_bus *bus, unsigned int val)
169{
170	unsigned int addr = azx_command_addr(val);
171	int timeout = 50;
172
173	guard(spinlock_irq)(&bus->reg_lock);
174
175	while (timeout--) {
176		/* check ICB bit */
177		if (!((snd_hdac_chip_readw(bus, IRS) & AZX_IRS_BUSY))) {
178			/* Clear IRV bit */
179			snd_hdac_chip_updatew(bus, IRS, AZX_IRS_VALID, AZX_IRS_VALID);
180			snd_hdac_chip_writel(bus, IC, val);
181			/* Set ICB bit */
182			snd_hdac_chip_updatew(bus, IRS, AZX_IRS_BUSY, AZX_IRS_BUSY);
183
184			return snd_hdac_bus_wait_for_pio_response(bus, addr);
185		}
186		udelay(1);
187	}
188
189	dev_dbg_ratelimited(bus->dev, "send_cmd_pio timeout: IRS=%#x, val=%#x\n",
190			    snd_hdac_chip_readw(bus, IRS), val);
191
192	return -EIO;
193}
194
195/**
196 * snd_hdac_bus_get_response_pio - receive a response via Immediate Response
197 * @bus: HD-audio core bus
198 * @addr: codec address
199 * @res: pointer to store the value, NULL when not needed
200 *
201 * Returns zero if a value is read, or a negative error code.
202 */
203static int snd_hdac_bus_get_response_pio(struct hdac_bus *bus,
204					 unsigned int addr, unsigned int *res)
205{
206	if (res)
207		*res = bus->rirb.res[addr];
208
209	return 0;
210}
211
212/**
213 * snd_hdac_bus_send_cmd_corb - send a command verb via CORB
214 * @bus: HD-audio core bus
215 * @val: encoded verb value to send
216 *
217 * Returns zero for success or a negative error code.
218 */
219static int snd_hdac_bus_send_cmd_corb(struct hdac_bus *bus, unsigned int val)
220{
221	unsigned int addr = azx_command_addr(val);
222	unsigned int wp, rp;
223
224	guard(spinlock_irq)(&bus->reg_lock);
225
226	bus->last_cmd[azx_command_addr(val)] = val;
227
228	/* add command to corb */
229	wp = snd_hdac_chip_readw(bus, CORBWP);
230	if (wp == 0xffff) {
231		/* something wrong, controller likely turned to D3 */
232		return -EIO;
233	}
234	wp++;
235	wp %= AZX_MAX_CORB_ENTRIES;
236
237	rp = snd_hdac_chip_readw(bus, CORBRP);
238	if (wp == rp) {
239		/* oops, it's full */
240		return -EAGAIN;
241	}
242
243	bus->rirb.cmds[addr]++;
244	bus->corb.buf[wp] = cpu_to_le32(val);
245	snd_hdac_chip_writew(bus, CORBWP, wp);
246
247	return 0;
248}
249
250#define AZX_RIRB_EX_UNSOL_EV	(1<<4)
251
252/**
253 * snd_hdac_bus_update_rirb - retrieve RIRB entries
254 * @bus: HD-audio core bus
255 *
256 * Usually called from interrupt handler.
257 * The caller needs bus->reg_lock spinlock before calling this.
258 */
259void snd_hdac_bus_update_rirb(struct hdac_bus *bus)
260{
261	unsigned int rp, wp;
262	unsigned int addr;
263	u32 res, res_ex;
264
265	wp = snd_hdac_chip_readw(bus, RIRBWP);
266	if (wp == 0xffff) {
267		/* something wrong, controller likely turned to D3 */
268		return;
269	}
270
271	if (wp == bus->rirb.wp)
272		return;
273	bus->rirb.wp = wp;
274
275	while (bus->rirb.rp != wp) {
276		bus->rirb.rp++;
277		bus->rirb.rp %= AZX_MAX_RIRB_ENTRIES;
278
279		rp = bus->rirb.rp << 1; /* an RIRB entry is 8-bytes */
280		res_ex = le32_to_cpu(bus->rirb.buf[rp + 1]);
281		res = le32_to_cpu(bus->rirb.buf[rp]);
282		addr = res_ex & 0xf;
283		if (addr >= HDA_MAX_CODECS) {
284			dev_err(bus->dev,
285				"spurious response %#x:%#x, rp = %d, wp = %d",
286				res, res_ex, bus->rirb.rp, wp);
287			snd_BUG();
288		} else if (res_ex & AZX_RIRB_EX_UNSOL_EV)
289			snd_hdac_bus_queue_event(bus, res, res_ex);
290		else if (bus->rirb.cmds[addr]) {
291			bus->rirb.res[addr] = res;
292			bus->rirb.cmds[addr]--;
293			if (!bus->rirb.cmds[addr] &&
294			    waitqueue_active(&bus->rirb_wq))
295				wake_up(&bus->rirb_wq);
296		} else {
297			dev_err_ratelimited(bus->dev,
298				"spurious response %#x:%#x, last cmd=%#08x\n",
299				res, res_ex, bus->last_cmd[addr]);
300		}
301	}
302}
303EXPORT_SYMBOL_GPL(snd_hdac_bus_update_rirb);
304
305/**
306 * snd_hdac_bus_get_response_rirb - receive a response via RIRB
307 * @bus: HD-audio core bus
308 * @addr: codec address
309 * @res: pointer to store the value, NULL when not needed
310 *
311 * Returns zero if a value is read, or a negative error code.
312 */
313static int snd_hdac_bus_get_response_rirb(struct hdac_bus *bus,
314					  unsigned int addr, unsigned int *res)
315{
316	unsigned long timeout;
317	unsigned long loopcounter;
318	wait_queue_entry_t wait;
319	bool warned = false;
320
321	init_wait_entry(&wait, 0);
322	timeout = jiffies + msecs_to_jiffies(1000);
323
324	for (loopcounter = 0;; loopcounter++) {
325		scoped_guard(spinlock_irq, &bus->reg_lock) {
326			if (!bus->polling_mode)
327				prepare_to_wait(&bus->rirb_wq, &wait,
328						TASK_UNINTERRUPTIBLE);
329			if (bus->polling_mode)
330				snd_hdac_bus_update_rirb(bus);
331			if (!bus->rirb.cmds[addr]) {
332				if (res)
333					*res = bus->rirb.res[addr]; /* the last value */
334				if (!bus->polling_mode)
335					finish_wait(&bus->rirb_wq, &wait);
336				return 0;
337			}
338		}
339		if (time_after(jiffies, timeout))
340			break;
341#define LOOP_COUNT_MAX	3000
342		if (!bus->polling_mode) {
343			schedule_timeout(msecs_to_jiffies(2));
344		} else if (bus->needs_damn_long_delay ||
345			   loopcounter > LOOP_COUNT_MAX) {
346			if (loopcounter > LOOP_COUNT_MAX && !warned) {
347				dev_dbg_ratelimited(bus->dev,
348						    "too slow response, last cmd=%#08x\n",
349						    bus->last_cmd[addr]);
350				warned = true;
351			}
352			msleep(2); /* temporary workaround */
353		} else {
354			udelay(10);
355			cond_resched();
356		}
357	}
358
359	if (!bus->polling_mode)
360		finish_wait(&bus->rirb_wq, &wait);
361
362	return -EIO;
363}
364
365/**
366 * snd_hdac_bus_send_cmd - send a command verb via CORB or PIO
367 * @bus: HD-audio core bus
368 * @val: encoded verb value to send
369 *
370 * Returns zero for success or a negative error code.
371 */
372int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val)
373{
374	if (bus->use_pio_for_commands)
375		return snd_hdac_bus_send_cmd_pio(bus, val);
376
377	return snd_hdac_bus_send_cmd_corb(bus, val);
378}
379EXPORT_SYMBOL_GPL(snd_hdac_bus_send_cmd);
380
381/**
382 * snd_hdac_bus_get_response - receive a response via RIRB or PIO
383 * @bus: HD-audio core bus
384 * @addr: codec address
385 * @res: pointer to store the value, NULL when not needed
386 *
387 * Returns zero if a value is read, or a negative error code.
388 */
389int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr,
390			      unsigned int *res)
391{
392	if (bus->use_pio_for_commands)
393		return snd_hdac_bus_get_response_pio(bus, addr, res);
394
395	return snd_hdac_bus_get_response_rirb(bus, addr, res);
396}
397EXPORT_SYMBOL_GPL(snd_hdac_bus_get_response);
398
399#define HDAC_MAX_CAPS 10
400/**
401 * snd_hdac_bus_parse_capabilities - parse capability structure
402 * @bus: the pointer to bus object
403 *
404 * Returns 0 if successful, or a negative error code.
405 */
406int snd_hdac_bus_parse_capabilities(struct hdac_bus *bus)
407{
408	unsigned int cur_cap;
409	unsigned int offset;
410	unsigned int counter = 0;
411
412	offset = snd_hdac_chip_readw(bus, LLCH);
413
414	/* Lets walk the linked capabilities list */
415	do {
416		cur_cap = _snd_hdac_chip_readl(bus, offset);
417
418		dev_dbg(bus->dev, "Capability version: 0x%x\n",
419			(cur_cap & AZX_CAP_HDR_VER_MASK) >> AZX_CAP_HDR_VER_OFF);
420
421		dev_dbg(bus->dev, "HDA capability ID: 0x%x\n",
422			(cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF);
423
424		if (cur_cap == -1) {
425			dev_dbg(bus->dev, "Invalid capability reg read\n");
426			break;
427		}
428
429		switch ((cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF) {
430		case AZX_ML_CAP_ID:
431			dev_dbg(bus->dev, "Found ML capability\n");
432			bus->mlcap = bus->remap_addr + offset;
433			break;
434
435		case AZX_GTS_CAP_ID:
436			dev_dbg(bus->dev, "Found GTS capability offset=%x\n", offset);
437			bus->gtscap = bus->remap_addr + offset;
438			break;
439
440		case AZX_PP_CAP_ID:
441			/* PP capability found, the Audio DSP is present */
442			dev_dbg(bus->dev, "Found PP capability offset=%x\n", offset);
443			bus->ppcap = bus->remap_addr + offset;
444			break;
445
446		case AZX_SPB_CAP_ID:
447			/* SPIB capability found, handler function */
448			dev_dbg(bus->dev, "Found SPB capability\n");
449			bus->spbcap = bus->remap_addr + offset;
450			break;
451
452		case AZX_DRSM_CAP_ID:
453			/* DMA resume  capability found, handler function */
454			dev_dbg(bus->dev, "Found DRSM capability\n");
455			bus->drsmcap = bus->remap_addr + offset;
456			break;
457
458		default:
459			dev_err(bus->dev, "Unknown capability %d\n", cur_cap);
460			cur_cap = 0;
461			break;
462		}
463
464		counter++;
465
466		if (counter > HDAC_MAX_CAPS) {
467			dev_err(bus->dev, "We exceeded HDAC capabilities!!!\n");
468			break;
469		}
470
471		/* read the offset of next capability */
472		offset = cur_cap & AZX_CAP_HDR_NXT_PTR_MASK;
473
474	} while (offset);
475
476	return 0;
477}
478EXPORT_SYMBOL_GPL(snd_hdac_bus_parse_capabilities);
479
480/*
481 * Lowlevel interface
482 */
483
484/**
485 * snd_hdac_bus_enter_link_reset - enter link reset
486 * @bus: HD-audio core bus
487 *
488 * Enter to the link reset state.
489 */
490void snd_hdac_bus_enter_link_reset(struct hdac_bus *bus)
491{
492	unsigned long timeout;
493
494	/* reset controller */
495	snd_hdac_chip_updatel(bus, GCTL, AZX_GCTL_RESET, 0);
496
497	timeout = jiffies + msecs_to_jiffies(100);
498	while ((snd_hdac_chip_readb(bus, GCTL) & AZX_GCTL_RESET) &&
499	       time_before(jiffies, timeout))
500		usleep_range(500, 1000);
501}
502EXPORT_SYMBOL_GPL(snd_hdac_bus_enter_link_reset);
503
504/**
505 * snd_hdac_bus_exit_link_reset - exit link reset
506 * @bus: HD-audio core bus
507 *
508 * Exit from the link reset state.
509 */
510void snd_hdac_bus_exit_link_reset(struct hdac_bus *bus)
511{
512	unsigned long timeout;
513
514	snd_hdac_chip_updateb(bus, GCTL, AZX_GCTL_RESET, AZX_GCTL_RESET);
515
516	timeout = jiffies + msecs_to_jiffies(100);
517	while (!snd_hdac_chip_readb(bus, GCTL) && time_before(jiffies, timeout))
518		usleep_range(500, 1000);
519}
520EXPORT_SYMBOL_GPL(snd_hdac_bus_exit_link_reset);
521
522/* reset codec link */
523int snd_hdac_bus_reset_link(struct hdac_bus *bus, bool full_reset)
524{
525	if (!full_reset)
526		goto skip_reset;
527
528	/* clear STATESTS if not in reset */
529	if (snd_hdac_chip_readb(bus, GCTL) & AZX_GCTL_RESET)
530		snd_hdac_chip_writew(bus, STATESTS, STATESTS_INT_MASK);
531
532	/* reset controller */
533	snd_hdac_bus_enter_link_reset(bus);
534
535	/* delay for >= 100us for codec PLL to settle per spec
536	 * Rev 0.9 section 5.5.1
537	 */
538	usleep_range(500, 1000);
539
540	/* Bring controller out of reset */
541	snd_hdac_bus_exit_link_reset(bus);
542
543	/* Brent Chartrand said to wait >= 540us for codecs to initialize */
544	usleep_range(1000, 1200);
545
546 skip_reset:
547	/* check to see if controller is ready */
548	if (!snd_hdac_chip_readb(bus, GCTL)) {
549		dev_dbg(bus->dev, "controller not ready!\n");
550		return -EBUSY;
551	}
552
553	/* detect codecs */
554	if (!bus->codec_mask) {
555		bus->codec_mask = snd_hdac_chip_readw(bus, STATESTS);
556		dev_dbg(bus->dev, "codec_mask = 0x%lx\n", bus->codec_mask);
557	}
558
559	return 0;
560}
561EXPORT_SYMBOL_GPL(snd_hdac_bus_reset_link);
562
563/* enable interrupts */
564static void azx_int_enable(struct hdac_bus *bus)
565{
566	/* enable controller CIE and GIE */
567	snd_hdac_chip_updatel(bus, INTCTL,
568			      AZX_INT_CTRL_EN | AZX_INT_GLOBAL_EN,
569			      AZX_INT_CTRL_EN | AZX_INT_GLOBAL_EN);
570}
571
572/* disable interrupts */
573static void azx_int_disable(struct hdac_bus *bus)
574{
575	struct hdac_stream *azx_dev;
576
577	/* disable interrupts in stream descriptor */
578	list_for_each_entry(azx_dev, &bus->stream_list, list)
579		snd_hdac_stream_updateb(azx_dev, SD_CTL, SD_INT_MASK, 0);
580
581	/* disable SIE for all streams & disable controller CIE and GIE */
582	snd_hdac_chip_writel(bus, INTCTL, 0);
583}
584
585/* clear interrupts */
586static void azx_int_clear(struct hdac_bus *bus)
587{
588	struct hdac_stream *azx_dev;
589
590	/* clear stream status */
591	list_for_each_entry(azx_dev, &bus->stream_list, list)
592		snd_hdac_stream_writeb(azx_dev, SD_STS, SD_INT_MASK);
593
594	/* clear STATESTS */
595	snd_hdac_chip_writew(bus, STATESTS, STATESTS_INT_MASK);
596
597	/* clear rirb status */
598	snd_hdac_chip_writeb(bus, RIRBSTS, RIRB_INT_MASK);
599
600	/* clear int status */
601	snd_hdac_chip_writel(bus, INTSTS, AZX_INT_CTRL_EN | AZX_INT_ALL_STREAM);
602}
603
604/**
605 * snd_hdac_bus_init_chip - reset and start the controller registers
606 * @bus: HD-audio core bus
607 * @full_reset: Do full reset
608 */
609bool snd_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset)
610{
611	if (bus->chip_init)
612		return false;
613
614	/* reset controller */
615	snd_hdac_bus_reset_link(bus, full_reset);
616
617	/* clear interrupts */
618	azx_int_clear(bus);
619
620	/* initialize the codec command I/O */
621	snd_hdac_bus_init_cmd_io(bus);
622
623	/* enable interrupts after CORB/RIRB buffers are initialized above */
624	azx_int_enable(bus);
625
626	/* program the position buffer */
627	if (bus->use_posbuf && bus->posbuf.addr) {
628		snd_hdac_chip_writel(bus, DPLBASE, (u32)(bus->posbuf.addr + bus->addr_offset));
629		snd_hdac_chip_writel(bus, DPUBASE, upper_32_bits(bus->posbuf.addr + bus->addr_offset));
630	}
631
632	bus->chip_init = true;
633
634	return true;
635}
636EXPORT_SYMBOL_GPL(snd_hdac_bus_init_chip);
637
638/**
639 * snd_hdac_bus_stop_chip - disable the whole IRQ and I/Os
640 * @bus: HD-audio core bus
641 */
642void snd_hdac_bus_stop_chip(struct hdac_bus *bus)
643{
644	if (!bus->chip_init)
645		return;
646
647	/* disable interrupts */
648	azx_int_disable(bus);
649	azx_int_clear(bus);
650
651	/* disable CORB/RIRB */
652	snd_hdac_bus_stop_cmd_io(bus);
653
654	/* disable position buffer */
655	if (bus->posbuf.addr) {
656		snd_hdac_chip_writel(bus, DPLBASE, 0);
657		snd_hdac_chip_writel(bus, DPUBASE, 0);
658	}
659
660	bus->chip_init = false;
661}
662EXPORT_SYMBOL_GPL(snd_hdac_bus_stop_chip);
663
664/**
665 * snd_hdac_bus_handle_stream_irq - interrupt handler for streams
666 * @bus: HD-audio core bus
667 * @status: INTSTS register value
668 * @ack: callback to be called for woken streams
669 *
670 * Returns the bits of handled streams, or zero if no stream is handled.
671 */
672int snd_hdac_bus_handle_stream_irq(struct hdac_bus *bus, unsigned int status,
673				    void (*ack)(struct hdac_bus *,
674						struct hdac_stream *))
675{
676	struct hdac_stream *azx_dev;
677	u8 sd_status;
678	int handled = 0;
679
680	list_for_each_entry(azx_dev, &bus->stream_list, list) {
681		if (status & azx_dev->sd_int_sta_mask) {
682			sd_status = snd_hdac_stream_readb(azx_dev, SD_STS);
683			snd_hdac_stream_writeb(azx_dev, SD_STS, SD_INT_MASK);
684			handled |= 1 << azx_dev->index;
685			if ((!azx_dev->substream && !azx_dev->cstream) ||
686			    !azx_dev->running || !(sd_status & SD_INT_COMPLETE))
687				continue;
688			if (ack)
689				ack(bus, azx_dev);
690		}
691	}
692	return handled;
693}
694EXPORT_SYMBOL_GPL(snd_hdac_bus_handle_stream_irq);
695
696/**
697 * snd_hdac_bus_alloc_stream_pages - allocate BDL and other buffers
698 * @bus: HD-audio core bus
699 *
700 * Call this after assigning the all streams.
701 * Returns zero for success, or a negative error code.
702 */
703int snd_hdac_bus_alloc_stream_pages(struct hdac_bus *bus)
704{
705	struct hdac_stream *s;
706	int num_streams = 0;
707	int dma_type = bus->dma_type ? bus->dma_type : SNDRV_DMA_TYPE_DEV;
708	int err;
709
710	list_for_each_entry(s, &bus->stream_list, list) {
711		/* allocate memory for the BDL for each stream */
712		err = snd_dma_alloc_pages(dma_type, bus->dev,
713					  BDL_SIZE, &s->bdl);
714		num_streams++;
715		if (err < 0)
716			return -ENOMEM;
717	}
718
719	if (WARN_ON(!num_streams))
720		return -EINVAL;
721	/* allocate memory for the position buffer */
722	err = snd_dma_alloc_pages(dma_type, bus->dev,
723				  num_streams * 8, &bus->posbuf);
724	if (err < 0)
725		return -ENOMEM;
726	list_for_each_entry(s, &bus->stream_list, list)
727		s->posbuf = (__le32 *)(bus->posbuf.area + s->index * 8);
728
729	/* single page (at least 4096 bytes) must suffice for both ringbuffes */
730	return snd_dma_alloc_pages(dma_type, bus->dev, PAGE_SIZE, &bus->rb);
731}
732EXPORT_SYMBOL_GPL(snd_hdac_bus_alloc_stream_pages);
733
734/**
735 * snd_hdac_bus_free_stream_pages - release BDL and other buffers
736 * @bus: HD-audio core bus
737 */
738void snd_hdac_bus_free_stream_pages(struct hdac_bus *bus)
739{
740	struct hdac_stream *s;
741
742	list_for_each_entry(s, &bus->stream_list, list) {
743		if (s->bdl.area)
744			snd_dma_free_pages(&s->bdl);
745	}
746
747	if (bus->rb.area)
748		snd_dma_free_pages(&bus->rb);
749	if (bus->posbuf.area)
750		snd_dma_free_pages(&bus->posbuf);
751}
752EXPORT_SYMBOL_GPL(snd_hdac_bus_free_stream_pages);
753
754/**
755 * snd_hdac_bus_link_power - power up/down codec link
756 * @codec: HD-audio device
757 * @enable: whether to power-up the link
758 */
759void snd_hdac_bus_link_power(struct hdac_device *codec, bool enable)
760{
761	if (enable)
762		set_bit(codec->addr, &codec->bus->codec_powered);
763	else
764		clear_bit(codec->addr, &codec->bus->codec_powered);
765}
766EXPORT_SYMBOL_GPL(snd_hdac_bus_link_power);
~/ Read-only file preview.