diff options
author | Dylan Reid <dgreid@chromium.org> | 2014-02-28 18:41:27 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2014-03-01 05:23:06 -0500 |
commit | f43923ff2c97c2ecad668c5133a36c2a9821b5df (patch) | |
tree | f45193950cd8987b65fb586dc65cd6399e399447 /sound/pci/hda | |
parent | f19c3ec21bef658b48df78c82cec7fd78681d653 (diff) |
ALSA: hda - Move low level functions to hda_controller
Share more code from hda_intel. This moves the link control and
initialization to hda_controller. The code will also be used by an
hda platform driver.
Signed-off-by: Dylan Reid <dgreid@chromium.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda')
-rw-r--r-- | sound/pci/hda/hda_controller.c | 177 | ||||
-rw-r--r-- | sound/pci/hda/hda_controller.h | 7 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 175 |
3 files changed, 180 insertions, 179 deletions
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c index a7c5a5d9ad8f..bde4935afbab 100644 --- a/sound/pci/hda/hda_controller.c +++ b/sound/pci/hda/hda_controller.c | |||
@@ -1039,7 +1039,7 @@ static int azx_alloc_cmd_io(struct azx *chip) | |||
1039 | } | 1039 | } |
1040 | EXPORT_SYMBOL_GPL(azx_alloc_cmd_io); | 1040 | EXPORT_SYMBOL_GPL(azx_alloc_cmd_io); |
1041 | 1041 | ||
1042 | void azx_init_cmd_io(struct azx *chip) | 1042 | static void azx_init_cmd_io(struct azx *chip) |
1043 | { | 1043 | { |
1044 | int timeout; | 1044 | int timeout; |
1045 | 1045 | ||
@@ -1102,7 +1102,7 @@ void azx_init_cmd_io(struct azx *chip) | |||
1102 | } | 1102 | } |
1103 | EXPORT_SYMBOL_GPL(azx_init_cmd_io); | 1103 | EXPORT_SYMBOL_GPL(azx_init_cmd_io); |
1104 | 1104 | ||
1105 | void azx_free_cmd_io(struct azx *chip) | 1105 | static void azx_free_cmd_io(struct azx *chip) |
1106 | { | 1106 | { |
1107 | spin_lock_irq(&chip->reg_lock); | 1107 | spin_lock_irq(&chip->reg_lock); |
1108 | /* disable ringbuffer DMAs */ | 1108 | /* disable ringbuffer DMAs */ |
@@ -1574,5 +1574,178 @@ void azx_free_stream_pages(struct azx *chip) | |||
1574 | } | 1574 | } |
1575 | EXPORT_SYMBOL_GPL(azx_free_stream_pages); | 1575 | EXPORT_SYMBOL_GPL(azx_free_stream_pages); |
1576 | 1576 | ||
1577 | /* | ||
1578 | * Lowlevel interface | ||
1579 | */ | ||
1580 | |||
1581 | /* enter link reset */ | ||
1582 | void azx_enter_link_reset(struct azx *chip) | ||
1583 | { | ||
1584 | unsigned long timeout; | ||
1585 | |||
1586 | /* reset controller */ | ||
1587 | azx_writel(chip, GCTL, azx_readl(chip, GCTL) & ~ICH6_GCTL_RESET); | ||
1588 | |||
1589 | timeout = jiffies + msecs_to_jiffies(100); | ||
1590 | while ((azx_readb(chip, GCTL) & ICH6_GCTL_RESET) && | ||
1591 | time_before(jiffies, timeout)) | ||
1592 | usleep_range(500, 1000); | ||
1593 | } | ||
1594 | EXPORT_SYMBOL_GPL(azx_enter_link_reset); | ||
1595 | |||
1596 | /* exit link reset */ | ||
1597 | static void azx_exit_link_reset(struct azx *chip) | ||
1598 | { | ||
1599 | unsigned long timeout; | ||
1600 | |||
1601 | azx_writeb(chip, GCTL, azx_readb(chip, GCTL) | ICH6_GCTL_RESET); | ||
1602 | |||
1603 | timeout = jiffies + msecs_to_jiffies(100); | ||
1604 | while (!azx_readb(chip, GCTL) && | ||
1605 | time_before(jiffies, timeout)) | ||
1606 | usleep_range(500, 1000); | ||
1607 | } | ||
1608 | |||
1609 | /* reset codec link */ | ||
1610 | static int azx_reset(struct azx *chip, int full_reset) | ||
1611 | { | ||
1612 | if (!full_reset) | ||
1613 | goto __skip; | ||
1614 | |||
1615 | /* clear STATESTS */ | ||
1616 | azx_writew(chip, STATESTS, STATESTS_INT_MASK); | ||
1617 | |||
1618 | /* reset controller */ | ||
1619 | azx_enter_link_reset(chip); | ||
1620 | |||
1621 | /* delay for >= 100us for codec PLL to settle per spec | ||
1622 | * Rev 0.9 section 5.5.1 | ||
1623 | */ | ||
1624 | usleep_range(500, 1000); | ||
1625 | |||
1626 | /* Bring controller out of reset */ | ||
1627 | azx_exit_link_reset(chip); | ||
1628 | |||
1629 | /* Brent Chartrand said to wait >= 540us for codecs to initialize */ | ||
1630 | usleep_range(1000, 1200); | ||
1631 | |||
1632 | __skip: | ||
1633 | /* check to see if controller is ready */ | ||
1634 | if (!azx_readb(chip, GCTL)) { | ||
1635 | dev_dbg(chip->card->dev, "azx_reset: controller not ready!\n"); | ||
1636 | return -EBUSY; | ||
1637 | } | ||
1638 | |||
1639 | /* Accept unsolicited responses */ | ||
1640 | if (!chip->single_cmd) | ||
1641 | azx_writel(chip, GCTL, azx_readl(chip, GCTL) | | ||
1642 | ICH6_GCTL_UNSOL); | ||
1643 | |||
1644 | /* detect codecs */ | ||
1645 | if (!chip->codec_mask) { | ||
1646 | chip->codec_mask = azx_readw(chip, STATESTS); | ||
1647 | dev_dbg(chip->card->dev, "codec_mask = 0x%x\n", | ||
1648 | chip->codec_mask); | ||
1649 | } | ||
1650 | |||
1651 | return 0; | ||
1652 | } | ||
1653 | |||
1654 | /* enable interrupts */ | ||
1655 | static void azx_int_enable(struct azx *chip) | ||
1656 | { | ||
1657 | /* enable controller CIE and GIE */ | ||
1658 | azx_writel(chip, INTCTL, azx_readl(chip, INTCTL) | | ||
1659 | ICH6_INT_CTRL_EN | ICH6_INT_GLOBAL_EN); | ||
1660 | } | ||
1661 | |||
1662 | /* disable interrupts */ | ||
1663 | static void azx_int_disable(struct azx *chip) | ||
1664 | { | ||
1665 | int i; | ||
1666 | |||
1667 | /* disable interrupts in stream descriptor */ | ||
1668 | for (i = 0; i < chip->num_streams; i++) { | ||
1669 | struct azx_dev *azx_dev = &chip->azx_dev[i]; | ||
1670 | azx_sd_writeb(chip, azx_dev, SD_CTL, | ||
1671 | azx_sd_readb(chip, azx_dev, SD_CTL) & | ||
1672 | ~SD_INT_MASK); | ||
1673 | } | ||
1674 | |||
1675 | /* disable SIE for all streams */ | ||
1676 | azx_writeb(chip, INTCTL, 0); | ||
1677 | |||
1678 | /* disable controller CIE and GIE */ | ||
1679 | azx_writel(chip, INTCTL, azx_readl(chip, INTCTL) & | ||
1680 | ~(ICH6_INT_CTRL_EN | ICH6_INT_GLOBAL_EN)); | ||
1681 | } | ||
1682 | |||
1683 | /* clear interrupts */ | ||
1684 | static void azx_int_clear(struct azx *chip) | ||
1685 | { | ||
1686 | int i; | ||
1687 | |||
1688 | /* clear stream status */ | ||
1689 | for (i = 0; i < chip->num_streams; i++) { | ||
1690 | struct azx_dev *azx_dev = &chip->azx_dev[i]; | ||
1691 | azx_sd_writeb(chip, azx_dev, SD_STS, SD_INT_MASK); | ||
1692 | } | ||
1693 | |||
1694 | /* clear STATESTS */ | ||
1695 | azx_writew(chip, STATESTS, STATESTS_INT_MASK); | ||
1696 | |||
1697 | /* clear rirb status */ | ||
1698 | azx_writeb(chip, RIRBSTS, RIRB_INT_MASK); | ||
1699 | |||
1700 | /* clear int status */ | ||
1701 | azx_writel(chip, INTSTS, ICH6_INT_CTRL_EN | ICH6_INT_ALL_STREAM); | ||
1702 | } | ||
1703 | |||
1704 | /* | ||
1705 | * reset and start the controller registers | ||
1706 | */ | ||
1707 | void azx_init_chip(struct azx *chip, int full_reset) | ||
1708 | { | ||
1709 | if (chip->initialized) | ||
1710 | return; | ||
1711 | |||
1712 | /* reset controller */ | ||
1713 | azx_reset(chip, full_reset); | ||
1714 | |||
1715 | /* initialize interrupts */ | ||
1716 | azx_int_clear(chip); | ||
1717 | azx_int_enable(chip); | ||
1718 | |||
1719 | /* initialize the codec command I/O */ | ||
1720 | if (!chip->single_cmd) | ||
1721 | azx_init_cmd_io(chip); | ||
1722 | |||
1723 | /* program the position buffer */ | ||
1724 | azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); | ||
1725 | azx_writel(chip, DPUBASE, upper_32_bits(chip->posbuf.addr)); | ||
1726 | |||
1727 | chip->initialized = 1; | ||
1728 | } | ||
1729 | EXPORT_SYMBOL_GPL(azx_init_chip); | ||
1730 | |||
1731 | void azx_stop_chip(struct azx *chip) | ||
1732 | { | ||
1733 | if (!chip->initialized) | ||
1734 | return; | ||
1735 | |||
1736 | /* disable interrupts */ | ||
1737 | azx_int_disable(chip); | ||
1738 | azx_int_clear(chip); | ||
1739 | |||
1740 | /* disable CORB/RIRB */ | ||
1741 | azx_free_cmd_io(chip); | ||
1742 | |||
1743 | /* disable position buffer */ | ||
1744 | azx_writel(chip, DPLBASE, 0); | ||
1745 | azx_writel(chip, DPUBASE, 0); | ||
1746 | |||
1747 | chip->initialized = 0; | ||
1748 | } | ||
1749 | |||
1577 | MODULE_LICENSE("GPL"); | 1750 | MODULE_LICENSE("GPL"); |
1578 | MODULE_DESCRIPTION("Common HDA driver funcitons"); | 1751 | MODULE_DESCRIPTION("Common HDA driver funcitons"); |
diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h index 3a3d78ed6da8..67d9f28a669f 100644 --- a/sound/pci/hda/hda_controller.h +++ b/sound/pci/hda/hda_controller.h | |||
@@ -50,11 +50,14 @@ void azx_free_stream_pages(struct azx *chip); | |||
50 | /* | 50 | /* |
51 | * CORB / RIRB interface | 51 | * CORB / RIRB interface |
52 | */ | 52 | */ |
53 | void azx_init_cmd_io(struct azx *chip); | ||
54 | void azx_free_cmd_io(struct azx *chip); | ||
55 | void azx_update_rirb(struct azx *chip); | 53 | void azx_update_rirb(struct azx *chip); |
56 | int azx_send_cmd(struct hda_bus *bus, unsigned int val); | 54 | int azx_send_cmd(struct hda_bus *bus, unsigned int val); |
57 | unsigned int azx_get_response(struct hda_bus *bus, | 55 | unsigned int azx_get_response(struct hda_bus *bus, |
58 | unsigned int addr); | 56 | unsigned int addr); |
59 | 57 | ||
58 | /* Low level azx interface */ | ||
59 | void azx_init_chip(struct azx *chip, int full_reset); | ||
60 | void azx_stop_chip(struct azx *chip); | ||
61 | void azx_enter_link_reset(struct azx *chip); | ||
62 | |||
60 | #endif /* __SOUND_HDA_CONTROLLER_H */ | 63 | #endif /* __SOUND_HDA_CONTROLLER_H */ |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 3d6ccb8ef86e..4f693eff531a 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -340,159 +340,6 @@ static int azx_acquire_irq(struct azx *chip, int do_disconnect); | |||
340 | static void azx_power_notify(struct hda_bus *bus, bool power_up); | 340 | static void azx_power_notify(struct hda_bus *bus, bool power_up); |
341 | #endif | 341 | #endif |
342 | 342 | ||
343 | /* enter link reset */ | ||
344 | static void azx_enter_link_reset(struct azx *chip) | ||
345 | { | ||
346 | unsigned long timeout; | ||
347 | |||
348 | /* reset controller */ | ||
349 | azx_writel(chip, GCTL, azx_readl(chip, GCTL) & ~ICH6_GCTL_RESET); | ||
350 | |||
351 | timeout = jiffies + msecs_to_jiffies(100); | ||
352 | while ((azx_readb(chip, GCTL) & ICH6_GCTL_RESET) && | ||
353 | time_before(jiffies, timeout)) | ||
354 | usleep_range(500, 1000); | ||
355 | } | ||
356 | |||
357 | /* exit link reset */ | ||
358 | static void azx_exit_link_reset(struct azx *chip) | ||
359 | { | ||
360 | unsigned long timeout; | ||
361 | |||
362 | azx_writeb(chip, GCTL, azx_readb(chip, GCTL) | ICH6_GCTL_RESET); | ||
363 | |||
364 | timeout = jiffies + msecs_to_jiffies(100); | ||
365 | while (!azx_readb(chip, GCTL) && | ||
366 | time_before(jiffies, timeout)) | ||
367 | usleep_range(500, 1000); | ||
368 | } | ||
369 | |||
370 | /* reset codec link */ | ||
371 | static int azx_reset(struct azx *chip, int full_reset) | ||
372 | { | ||
373 | if (!full_reset) | ||
374 | goto __skip; | ||
375 | |||
376 | /* clear STATESTS */ | ||
377 | azx_writew(chip, STATESTS, STATESTS_INT_MASK); | ||
378 | |||
379 | /* reset controller */ | ||
380 | azx_enter_link_reset(chip); | ||
381 | |||
382 | /* delay for >= 100us for codec PLL to settle per spec | ||
383 | * Rev 0.9 section 5.5.1 | ||
384 | */ | ||
385 | usleep_range(500, 1000); | ||
386 | |||
387 | /* Bring controller out of reset */ | ||
388 | azx_exit_link_reset(chip); | ||
389 | |||
390 | /* Brent Chartrand said to wait >= 540us for codecs to initialize */ | ||
391 | usleep_range(1000, 1200); | ||
392 | |||
393 | __skip: | ||
394 | /* check to see if controller is ready */ | ||
395 | if (!azx_readb(chip, GCTL)) { | ||
396 | dev_dbg(chip->card->dev, "azx_reset: controller not ready!\n"); | ||
397 | return -EBUSY; | ||
398 | } | ||
399 | |||
400 | /* Accept unsolicited responses */ | ||
401 | if (!chip->single_cmd) | ||
402 | azx_writel(chip, GCTL, azx_readl(chip, GCTL) | | ||
403 | ICH6_GCTL_UNSOL); | ||
404 | |||
405 | /* detect codecs */ | ||
406 | if (!chip->codec_mask) { | ||
407 | chip->codec_mask = azx_readw(chip, STATESTS); | ||
408 | dev_dbg(chip->card->dev, "codec_mask = 0x%x\n", | ||
409 | chip->codec_mask); | ||
410 | } | ||
411 | |||
412 | return 0; | ||
413 | } | ||
414 | |||
415 | |||
416 | /* | ||
417 | * Lowlevel interface | ||
418 | */ | ||
419 | |||
420 | /* enable interrupts */ | ||
421 | static void azx_int_enable(struct azx *chip) | ||
422 | { | ||
423 | /* enable controller CIE and GIE */ | ||
424 | azx_writel(chip, INTCTL, azx_readl(chip, INTCTL) | | ||
425 | ICH6_INT_CTRL_EN | ICH6_INT_GLOBAL_EN); | ||
426 | } | ||
427 | |||
428 | /* disable interrupts */ | ||
429 | static void azx_int_disable(struct azx *chip) | ||
430 | { | ||
431 | int i; | ||
432 | |||
433 | /* disable interrupts in stream descriptor */ | ||
434 | for (i = 0; i < chip->num_streams; i++) { | ||
435 | struct azx_dev *azx_dev = &chip->azx_dev[i]; | ||
436 | azx_sd_writeb(chip, azx_dev, SD_CTL, | ||
437 | azx_sd_readb(chip, azx_dev, SD_CTL) & | ||
438 | ~SD_INT_MASK); | ||
439 | } | ||
440 | |||
441 | /* disable SIE for all streams */ | ||
442 | azx_writeb(chip, INTCTL, 0); | ||
443 | |||
444 | /* disable controller CIE and GIE */ | ||
445 | azx_writel(chip, INTCTL, azx_readl(chip, INTCTL) & | ||
446 | ~(ICH6_INT_CTRL_EN | ICH6_INT_GLOBAL_EN)); | ||
447 | } | ||
448 | |||
449 | /* clear interrupts */ | ||
450 | static void azx_int_clear(struct azx *chip) | ||
451 | { | ||
452 | int i; | ||
453 | |||
454 | /* clear stream status */ | ||
455 | for (i = 0; i < chip->num_streams; i++) { | ||
456 | struct azx_dev *azx_dev = &chip->azx_dev[i]; | ||
457 | azx_sd_writeb(chip, azx_dev, SD_STS, SD_INT_MASK); | ||
458 | } | ||
459 | |||
460 | /* clear STATESTS */ | ||
461 | azx_writew(chip, STATESTS, STATESTS_INT_MASK); | ||
462 | |||
463 | /* clear rirb status */ | ||
464 | azx_writeb(chip, RIRBSTS, RIRB_INT_MASK); | ||
465 | |||
466 | /* clear int status */ | ||
467 | azx_writel(chip, INTSTS, ICH6_INT_CTRL_EN | ICH6_INT_ALL_STREAM); | ||
468 | } | ||
469 | |||
470 | /* | ||
471 | * reset and start the controller registers | ||
472 | */ | ||
473 | static void azx_init_chip(struct azx *chip, int full_reset) | ||
474 | { | ||
475 | if (chip->initialized) | ||
476 | return; | ||
477 | |||
478 | /* reset controller */ | ||
479 | azx_reset(chip, full_reset); | ||
480 | |||
481 | /* initialize interrupts */ | ||
482 | azx_int_clear(chip); | ||
483 | azx_int_enable(chip); | ||
484 | |||
485 | /* initialize the codec command I/O */ | ||
486 | if (!chip->single_cmd) | ||
487 | azx_init_cmd_io(chip); | ||
488 | |||
489 | /* program the position buffer */ | ||
490 | azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); | ||
491 | azx_writel(chip, DPUBASE, upper_32_bits(chip->posbuf.addr)); | ||
492 | |||
493 | chip->initialized = 1; | ||
494 | } | ||
495 | |||
496 | /* | 343 | /* |
497 | * initialize the PCI registers | 344 | * initialize the PCI registers |
498 | */ | 345 | */ |
@@ -660,8 +507,6 @@ static int probe_codec(struct azx *chip, int addr) | |||
660 | return 0; | 507 | return 0; |
661 | } | 508 | } |
662 | 509 | ||
663 | static void azx_stop_chip(struct azx *chip); | ||
664 | |||
665 | static void azx_bus_reset(struct hda_bus *bus) | 510 | static void azx_bus_reset(struct hda_bus *bus) |
666 | { | 511 | { |
667 | struct azx *chip = bus->private_data; | 512 | struct azx *chip = bus->private_data; |
@@ -942,26 +787,6 @@ static int azx_acquire_irq(struct azx *chip, int do_disconnect) | |||
942 | return 0; | 787 | return 0; |
943 | } | 788 | } |
944 | 789 | ||
945 | |||
946 | static void azx_stop_chip(struct azx *chip) | ||
947 | { | ||
948 | if (!chip->initialized) | ||
949 | return; | ||
950 | |||
951 | /* disable interrupts */ | ||
952 | azx_int_disable(chip); | ||
953 | azx_int_clear(chip); | ||
954 | |||
955 | /* disable CORB/RIRB */ | ||
956 | azx_free_cmd_io(chip); | ||
957 | |||
958 | /* disable position buffer */ | ||
959 | azx_writel(chip, DPLBASE, 0); | ||
960 | azx_writel(chip, DPUBASE, 0); | ||
961 | |||
962 | chip->initialized = 0; | ||
963 | } | ||
964 | |||
965 | #ifdef CONFIG_PM | 790 | #ifdef CONFIG_PM |
966 | /* power-up/down the controller */ | 791 | /* power-up/down the controller */ |
967 | static void azx_power_notify(struct hda_bus *bus, bool power_up) | 792 | static void azx_power_notify(struct hda_bus *bus, bool power_up) |