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