root/sound/hda/hdac_controller.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. azx_clear_corbrp
  2. snd_hdac_bus_init_cmd_io
  3. hdac_wait_for_cmd_dmas
  4. snd_hdac_bus_stop_cmd_io
  5. azx_command_addr
  6. snd_hdac_bus_send_cmd
  7. snd_hdac_bus_update_rirb
  8. snd_hdac_bus_get_response
  9. snd_hdac_bus_parse_capabilities
  10. snd_hdac_bus_enter_link_reset
  11. snd_hdac_bus_exit_link_reset
  12. snd_hdac_bus_reset_link
  13. azx_int_enable
  14. azx_int_disable
  15. azx_int_clear
  16. snd_hdac_bus_init_chip
  17. snd_hdac_bus_stop_chip
  18. snd_hdac_bus_handle_stream_irq
  19. snd_hdac_bus_alloc_stream_pages
  20. snd_hdac_bus_free_stream_pages

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

/* [<][>][^][v][top][bottom][index][help] */