.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * intel_hdmi_audio.c - Intel HDMI audio driver |
---|
3 | 4 | * |
---|
.. | .. |
---|
7 | 8 | * Vaibhav Agarwal <vaibhav.agarwal@intel.com> |
---|
8 | 9 | * Jerome Anand <jerome.anand@intel.com> |
---|
9 | 10 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
10 | | - * |
---|
11 | | - * This program is free software; you can redistribute it and/or modify |
---|
12 | | - * it under the terms of the GNU General Public License as published by |
---|
13 | | - * the Free Software Foundation; version 2 of the License. |
---|
14 | | - * |
---|
15 | | - * This program is distributed in the hope that it will be useful, but |
---|
16 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
17 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
18 | | - * General Public License for more details. |
---|
19 | 11 | * |
---|
20 | 12 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
21 | 13 | * ALSA driver for Intel HDMI audio |
---|
.. | .. |
---|
30 | 22 | #include <linux/pm_runtime.h> |
---|
31 | 23 | #include <linux/dma-mapping.h> |
---|
32 | 24 | #include <linux/delay.h> |
---|
33 | | -#include <asm/set_memory.h> |
---|
34 | 25 | #include <sound/core.h> |
---|
35 | 26 | #include <sound/asoundef.h> |
---|
36 | 27 | #include <sound/pcm.h> |
---|
.. | .. |
---|
1141 | 1132 | struct snd_pcm_hw_params *hw_params) |
---|
1142 | 1133 | { |
---|
1143 | 1134 | struct snd_intelhad *intelhaddata; |
---|
1144 | | - unsigned long addr; |
---|
1145 | | - int pages, buf_size, retval; |
---|
| 1135 | + int buf_size; |
---|
1146 | 1136 | |
---|
1147 | 1137 | intelhaddata = snd_pcm_substream_chip(substream); |
---|
1148 | 1138 | buf_size = params_buffer_bytes(hw_params); |
---|
1149 | | - retval = snd_pcm_lib_malloc_pages(substream, buf_size); |
---|
1150 | | - if (retval < 0) |
---|
1151 | | - return retval; |
---|
1152 | 1139 | dev_dbg(intelhaddata->dev, "%s:allocated memory = %d\n", |
---|
1153 | 1140 | __func__, buf_size); |
---|
1154 | | - /* mark the pages as uncached region */ |
---|
1155 | | - addr = (unsigned long) substream->runtime->dma_area; |
---|
1156 | | - pages = (substream->runtime->dma_bytes + PAGE_SIZE - 1) / PAGE_SIZE; |
---|
1157 | | - retval = set_memory_uc(addr, pages); |
---|
1158 | | - if (retval) { |
---|
1159 | | - dev_err(intelhaddata->dev, "set_memory_uc failed.Error:%d\n", |
---|
1160 | | - retval); |
---|
1161 | | - return retval; |
---|
1162 | | - } |
---|
1163 | | - memset(substream->runtime->dma_area, 0, buf_size); |
---|
1164 | | - |
---|
1165 | | - return retval; |
---|
| 1141 | + return 0; |
---|
1166 | 1142 | } |
---|
1167 | 1143 | |
---|
1168 | 1144 | /* |
---|
.. | .. |
---|
1171 | 1147 | static int had_pcm_hw_free(struct snd_pcm_substream *substream) |
---|
1172 | 1148 | { |
---|
1173 | 1149 | struct snd_intelhad *intelhaddata; |
---|
1174 | | - unsigned long addr; |
---|
1175 | | - u32 pages; |
---|
1176 | 1150 | |
---|
1177 | 1151 | intelhaddata = snd_pcm_substream_chip(substream); |
---|
1178 | 1152 | had_do_reset(intelhaddata); |
---|
1179 | 1153 | |
---|
1180 | | - /* mark back the pages as cached/writeback region before the free */ |
---|
1181 | | - if (substream->runtime->dma_area != NULL) { |
---|
1182 | | - addr = (unsigned long) substream->runtime->dma_area; |
---|
1183 | | - pages = (substream->runtime->dma_bytes + PAGE_SIZE - 1) / |
---|
1184 | | - PAGE_SIZE; |
---|
1185 | | - set_memory_wb(addr, pages); |
---|
1186 | | - return snd_pcm_lib_free_pages(substream); |
---|
1187 | | - } |
---|
1188 | 1154 | return 0; |
---|
1189 | 1155 | } |
---|
1190 | 1156 | |
---|
.. | .. |
---|
1310 | 1276 | { |
---|
1311 | 1277 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
---|
1312 | 1278 | return remap_pfn_range(vma, vma->vm_start, |
---|
1313 | | - substream->dma_buffer.addr >> PAGE_SHIFT, |
---|
| 1279 | + substream->runtime->dma_addr >> PAGE_SHIFT, |
---|
1314 | 1280 | vma->vm_end - vma->vm_start, vma->vm_page_prot); |
---|
1315 | 1281 | } |
---|
1316 | 1282 | |
---|
.. | .. |
---|
1320 | 1286 | static const struct snd_pcm_ops had_pcm_ops = { |
---|
1321 | 1287 | .open = had_pcm_open, |
---|
1322 | 1288 | .close = had_pcm_close, |
---|
1323 | | - .ioctl = snd_pcm_lib_ioctl, |
---|
1324 | 1289 | .hw_params = had_pcm_hw_params, |
---|
1325 | 1290 | .hw_free = had_pcm_hw_free, |
---|
1326 | 1291 | .prepare = had_pcm_prepare, |
---|
.. | .. |
---|
1671 | 1636 | * PM callbacks |
---|
1672 | 1637 | */ |
---|
1673 | 1638 | |
---|
1674 | | -static int hdmi_lpe_audio_runtime_suspend(struct device *dev) |
---|
1675 | | -{ |
---|
1676 | | - struct snd_intelhad_card *card_ctx = dev_get_drvdata(dev); |
---|
1677 | | - int port; |
---|
1678 | | - |
---|
1679 | | - for_each_port(card_ctx, port) { |
---|
1680 | | - struct snd_intelhad *ctx = &card_ctx->pcm_ctx[port]; |
---|
1681 | | - struct snd_pcm_substream *substream; |
---|
1682 | | - |
---|
1683 | | - substream = had_substream_get(ctx); |
---|
1684 | | - if (substream) { |
---|
1685 | | - snd_pcm_suspend(substream); |
---|
1686 | | - had_substream_put(ctx); |
---|
1687 | | - } |
---|
1688 | | - } |
---|
1689 | | - |
---|
1690 | | - return 0; |
---|
1691 | | -} |
---|
1692 | | - |
---|
1693 | 1639 | static int __maybe_unused hdmi_lpe_audio_suspend(struct device *dev) |
---|
1694 | 1640 | { |
---|
1695 | 1641 | struct snd_intelhad_card *card_ctx = dev_get_drvdata(dev); |
---|
1696 | | - int err; |
---|
1697 | 1642 | |
---|
1698 | | - err = hdmi_lpe_audio_runtime_suspend(dev); |
---|
1699 | | - if (!err) |
---|
1700 | | - snd_power_change_state(card_ctx->card, SNDRV_CTL_POWER_D3hot); |
---|
1701 | | - return err; |
---|
1702 | | -} |
---|
| 1643 | + snd_power_change_state(card_ctx->card, SNDRV_CTL_POWER_D3hot); |
---|
1703 | 1644 | |
---|
1704 | | -static int hdmi_lpe_audio_runtime_resume(struct device *dev) |
---|
1705 | | -{ |
---|
1706 | | - pm_runtime_mark_last_busy(dev); |
---|
1707 | 1645 | return 0; |
---|
1708 | 1646 | } |
---|
1709 | 1647 | |
---|
.. | .. |
---|
1711 | 1649 | { |
---|
1712 | 1650 | struct snd_intelhad_card *card_ctx = dev_get_drvdata(dev); |
---|
1713 | 1651 | |
---|
1714 | | - hdmi_lpe_audio_runtime_resume(dev); |
---|
| 1652 | + pm_runtime_mark_last_busy(dev); |
---|
| 1653 | + |
---|
1715 | 1654 | snd_power_change_state(card_ctx->card, SNDRV_CTL_POWER_D0); |
---|
| 1655 | + |
---|
1716 | 1656 | return 0; |
---|
1717 | 1657 | } |
---|
1718 | 1658 | |
---|
.. | .. |
---|
1764 | 1704 | |
---|
1765 | 1705 | /* get resources */ |
---|
1766 | 1706 | irq = platform_get_irq(pdev, 0); |
---|
1767 | | - if (irq < 0) { |
---|
1768 | | - dev_err(&pdev->dev, "Could not get irq resource: %d\n", irq); |
---|
| 1707 | + if (irq < 0) |
---|
1769 | 1708 | return irq; |
---|
1770 | | - } |
---|
1771 | 1709 | |
---|
1772 | 1710 | res_mmio = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
1773 | 1711 | if (!res_mmio) { |
---|
.. | .. |
---|
1813 | 1751 | __func__, (unsigned int)res_mmio->start, |
---|
1814 | 1752 | (unsigned int)res_mmio->end); |
---|
1815 | 1753 | |
---|
1816 | | - card_ctx->mmio_start = ioremap_nocache(res_mmio->start, |
---|
| 1754 | + card_ctx->mmio_start = ioremap(res_mmio->start, |
---|
1817 | 1755 | (size_t)(resource_size(res_mmio))); |
---|
1818 | 1756 | if (!card_ctx->mmio_start) { |
---|
1819 | 1757 | dev_err(&pdev->dev, "Could not get ioremap\n"); |
---|
.. | .. |
---|
1859 | 1797 | /* allocate dma pages; |
---|
1860 | 1798 | * try to allocate 600k buffer as default which is large enough |
---|
1861 | 1799 | */ |
---|
1862 | | - snd_pcm_lib_preallocate_pages_for_all(pcm, |
---|
1863 | | - SNDRV_DMA_TYPE_DEV, NULL, |
---|
1864 | | - HAD_DEFAULT_BUFFER, HAD_MAX_BUFFER); |
---|
| 1800 | + snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV_UC, |
---|
| 1801 | + card->dev, HAD_DEFAULT_BUFFER, |
---|
| 1802 | + HAD_MAX_BUFFER); |
---|
1865 | 1803 | |
---|
1866 | 1804 | /* create controls */ |
---|
1867 | 1805 | for (i = 0; i < ARRAY_SIZE(had_controls); i++) { |
---|
.. | .. |
---|
1930 | 1868 | |
---|
1931 | 1869 | static const struct dev_pm_ops hdmi_lpe_audio_pm = { |
---|
1932 | 1870 | SET_SYSTEM_SLEEP_PM_OPS(hdmi_lpe_audio_suspend, hdmi_lpe_audio_resume) |
---|
1933 | | - SET_RUNTIME_PM_OPS(hdmi_lpe_audio_runtime_suspend, |
---|
1934 | | - hdmi_lpe_audio_runtime_resume, NULL) |
---|
1935 | 1871 | }; |
---|
1936 | 1872 | |
---|
1937 | 1873 | static struct platform_driver hdmi_lpe_audio_driver = { |
---|