Merge tag 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm
[platform/kernel/linux-rpi.git] / sound / soc / sof / intel / hda-bus.c
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 }