1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 2 // 3 // This file is provided under a dual BSD/GPLv2 license. When using or 4 // redistributing this file, you may do so under either license. 5 // 6 // Copyright(c) 2018 Intel Corporation. All rights reserved. 7 // 8 // Authors: Keyon Jie <yang.jie@linux.intel.com> 9 10 #include <linux/io.h> 11 #include <sound/hdaudio.h> 12 #include "../sof-priv.h" 13 #include "hda.h" 14 15 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 16 17 static const struct hdac_bus_ops bus_ops = { 18 .command = snd_hdac_bus_send_cmd, 19 .get_response = snd_hdac_bus_get_response, 20 }; 21 22 #endif 23 24 static void sof_hda_writel(u32 value, u32 __iomem *addr) 25 { 26 writel(value, addr); 27 } 28 29 static u32 sof_hda_readl(u32 __iomem *addr) 30 { 31 return readl(addr); 32 } 33 34 static void sof_hda_writew(u16 value, u16 __iomem *addr) 35 { 36 writew(value, addr); 37 } 38 39 static u16 sof_hda_readw(u16 __iomem *addr) 40 { 41 return readw(addr); 42 } 43 44 static void sof_hda_writeb(u8 value, u8 __iomem *addr) 45 { 46 writeb(value, addr); 47 } 48 49 static u8 sof_hda_readb(u8 __iomem *addr) 50 { 51 return readb(addr); 52 } 53 54 static int sof_hda_dma_alloc_pages(struct hdac_bus *bus, int type, 55 size_t size, struct snd_dma_buffer *buf) 56 { 57 return snd_dma_alloc_pages(type, bus->dev, size, buf); 58 } 59 60 static void sof_hda_dma_free_pages(struct hdac_bus *bus, 61 struct snd_dma_buffer *buf) 62 { 63 snd_dma_free_pages(buf); 64 } 65 66 static const struct hdac_io_ops io_ops = { 67 .reg_writel = sof_hda_writel, 68 .reg_readl = sof_hda_readl, 69 .reg_writew = sof_hda_writew, 70 .reg_readw = sof_hda_readw, 71 .reg_writeb = sof_hda_writeb, 72 .reg_readb = sof_hda_readb, 73 .dma_alloc_pages = sof_hda_dma_alloc_pages, 74 .dma_free_pages = sof_hda_dma_free_pages, 75 }; 76 77 /* 78 * This can be used for both with/without hda link support. 79 */ 80 void sof_hda_bus_init(struct hdac_bus *bus, struct device *dev, 81 const struct hdac_ext_bus_ops *ext_ops) 82 { 83 memset(bus, 0, sizeof(*bus)); 84 bus->dev = dev; 85 86 bus->io_ops = &io_ops; 87 INIT_LIST_HEAD(&bus->stream_list); 88 89 bus->irq = -1; 90 bus->ext_ops = ext_ops; 91 92 /* 93 * There is only one HDA bus atm. keep the index as 0. 94 * Need to fix when there are more than one HDA bus. 95 */ 96 bus->idx = 0; 97 98 spin_lock_init(&bus->reg_lock); 99 100 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 101 INIT_LIST_HEAD(&bus->codec_list); 102 INIT_LIST_HEAD(&bus->hlink_list); 103 104 mutex_init(&bus->cmd_mutex); 105 mutex_init(&bus->lock); 106 bus->ops = &bus_ops; 107 INIT_WORK(&bus->unsol_work, snd_hdac_bus_process_unsol_events); 108 bus->cmd_dma_state = true; 109 #endif 110 111 } 112