diff options
Diffstat (limited to 'sound/hda/ext/hdac_ext_stream.c')
-rw-r--r-- | sound/hda/ext/hdac_ext_stream.c | 72 |
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 | } |
499 | EXPORT_SYMBOL_GPL(snd_hdac_ext_stop_streams); | 504 | EXPORT_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 | */ | ||
512 | void 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 | } | ||
535 | EXPORT_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 | */ | ||
543 | int 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 | } | ||
557 | EXPORT_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 | */ | ||
565 | int 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 | } | ||
571 | EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_set_lpib); | ||