aboutsummaryrefslogtreecommitdiffstats
path: root/sound/hda/ext/hdac_ext_stream.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/hda/ext/hdac_ext_stream.c')
-rw-r--r--sound/hda/ext/hdac_ext_stream.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/sound/hda/ext/hdac_ext_stream.c b/sound/hda/ext/hdac_ext_stream.c
index cb89ec7c8147..023cc4cad5c1 100644
--- a/sound/hda/ext/hdac_ext_stream.c
+++ b/sound/hda/ext/hdac_ext_stream.c
@@ -59,6 +59,10 @@ void snd_hdac_ext_stream_init(struct hdac_ext_bus *ebus,
59 AZX_SPB_MAXFIFO; 59 AZX_SPB_MAXFIFO;
60 } 60 }
61 61
62 if (ebus->drsmcap)
63 stream->dpibr_addr = ebus->drsmcap + AZX_DRSM_BASE +
64 AZX_DRSM_INTERVAL * idx;
65
62 stream->decoupled = false; 66 stream->decoupled = false;
63 snd_hdac_stream_init(bus, &stream->hstream, idx, direction, tag); 67 snd_hdac_stream_init(bus, &stream->hstream, idx, direction, tag);
64} 68}
@@ -107,6 +111,7 @@ void snd_hdac_stream_free_all(struct hdac_ext_bus *ebus)
107 while (!list_empty(&bus->stream_list)) { 111 while (!list_empty(&bus->stream_list)) {
108 s = list_first_entry(&bus->stream_list, struct hdac_stream, list); 112 s = list_first_entry(&bus->stream_list, struct hdac_stream, list);
109 stream = stream_to_hdac_ext_stream(s); 113 stream = stream_to_hdac_ext_stream(s);
114 snd_hdac_ext_stream_decouple(ebus, stream, false);
110 list_del(&s->list); 115 list_del(&s->list);
111 kfree(stream); 116 kfree(stream);
112 } 117 }
@@ -497,3 +502,70 @@ void snd_hdac_ext_stop_streams(struct hdac_ext_bus *ebus)
497 } 502 }
498} 503}
499EXPORT_SYMBOL_GPL(snd_hdac_ext_stop_streams); 504EXPORT_SYMBOL_GPL(snd_hdac_ext_stop_streams);
505
506/**
507 * snd_hdac_ext_stream_drsm_enable - enable DMA resume for a stream
508 * @ebus: HD-audio ext core bus
509 * @enable: flag to enable/disable DRSM
510 * @index: stream index for which DRSM need to be enabled
511 */
512void snd_hdac_ext_stream_drsm_enable(struct hdac_ext_bus *ebus,
513 bool enable, int index)
514{
515 u32 mask = 0;
516 u32 register_mask = 0;
517 struct hdac_bus *bus = &ebus->bus;
518
519 if (!ebus->drsmcap) {
520 dev_err(bus->dev, "Address of DRSM capability is NULL");
521 return;
522 }
523
524 mask |= (1 << index);
525
526 register_mask = readl(ebus->drsmcap + AZX_REG_SPB_SPBFCCTL);
527
528 mask |= register_mask;
529
530 if (enable)
531 snd_hdac_updatel(ebus->drsmcap, AZX_REG_DRSM_CTL, 0, mask);
532 else
533 snd_hdac_updatel(ebus->drsmcap, AZX_REG_DRSM_CTL, mask, 0);
534}
535EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_drsm_enable);
536
537/**
538 * snd_hdac_ext_stream_set_dpibr - sets the dpibr value of a stream
539 * @ebus: HD-audio ext core bus
540 * @stream: hdac_ext_stream
541 * @value: dpib value to set
542 */
543int snd_hdac_ext_stream_set_dpibr(struct hdac_ext_bus *ebus,
544 struct hdac_ext_stream *stream, u32 value)
545{
546 struct hdac_bus *bus = &ebus->bus;
547
548 if (!ebus->drsmcap) {
549 dev_err(bus->dev, "Address of DRSM capability is NULL");
550 return -EINVAL;
551 }
552
553 writel(value, stream->dpibr_addr);
554
555 return 0;
556}
557EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_set_dpibr);
558
559/**
560 * snd_hdac_ext_stream_set_lpib - sets the lpib value of a stream
561 * @ebus: HD-audio ext core bus
562 * @stream: hdac_ext_stream
563 * @value: lpib value to set
564 */
565int snd_hdac_ext_stream_set_lpib(struct hdac_ext_stream *stream, u32 value)
566{
567 snd_hdac_stream_writel(&stream->hstream, SD_LPIB, value);
568
569 return 0;
570}
571EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_set_lpib);