xref: /linux/sound/soc/sof/intel/hda-bus.c (revision 44f57d78)
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