aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2016-09-29 15:43:59 -0400
committerMark Brown <broonie@kernel.org>2016-09-29 15:43:59 -0400
commit4a2447b483e17c580ed1d7c9cde3267d9c3a380f (patch)
treed4845df7d877abe55229b97f16359509c1eea140
parent00f12dbd3c33bb46b2d5e122406410b325b2c77d (diff)
parent0730bd2e2ade00d88647b13a0c17cde254ddf56e (diff)
Merge remote-tracking branch 'asoc/topic/intel' into asoc-next
-rw-r--r--include/sound/hda_register.h36
-rw-r--r--include/sound/hdaudio.h13
-rw-r--r--include/sound/hdaudio_ext.h12
-rw-r--r--include/uapi/sound/Kbuild1
-rw-r--r--include/uapi/sound/snd_sst_tokens.h214
-rw-r--r--sound/hda/ext/hdac_ext_controller.c91
-rw-r--r--sound/hda/ext/hdac_ext_stream.c46
-rw-r--r--sound/hda/hdac_controller.c75
-rw-r--r--sound/pci/hda/hda_controller.c203
-rw-r--r--sound/pci/hda/hda_controller.h3
-rw-r--r--sound/pci/hda/hda_intel.c17
-rw-r--r--sound/soc/codecs/rt5640.c3
-rw-r--r--sound/soc/codecs/rt5640.h1
-rw-r--r--sound/soc/intel/Kconfig12
-rw-r--r--sound/soc/intel/atom/sst-atom-controls.c32
-rw-r--r--sound/soc/intel/atom/sst-atom-controls.h6
-rw-r--r--sound/soc/intel/atom/sst/sst.c5
-rw-r--r--sound/soc/intel/atom/sst/sst_acpi.c97
-rw-r--r--sound/soc/intel/boards/Makefile2
-rw-r--r--sound/soc/intel/boards/bdw-rt5677.c347
-rw-r--r--sound/soc/intel/boards/bxt_da7219_max98357a.c75
-rw-r--r--sound/soc/intel/boards/bxt_rt298.c14
-rw-r--r--sound/soc/intel/boards/bytcr_rt5640.c507
-rw-r--r--sound/soc/intel/common/sst-acpi.c1
-rw-r--r--sound/soc/intel/skylake/bxt-sst.c118
-rw-r--r--sound/soc/intel/skylake/skl-messages.c67
-rw-r--r--sound/soc/intel/skylake/skl-pcm.c58
-rw-r--r--sound/soc/intel/skylake/skl-sst-cldma.c4
-rw-r--r--sound/soc/intel/skylake/skl-sst-dsp.h18
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.c41
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.h12
-rw-r--r--sound/soc/intel/skylake/skl-sst-utils.c176
-rw-r--r--sound/soc/intel/skylake/skl-sst.c49
-rw-r--r--sound/soc/intel/skylake/skl-topology.c918
-rw-r--r--sound/soc/intel/skylake/skl-topology.h15
-rw-r--r--sound/soc/intel/skylake/skl-tplg-interface.h95
-rw-r--r--sound/soc/intel/skylake/skl.c6
-rw-r--r--sound/soc/intel/skylake/skl.h2
38 files changed, 2907 insertions, 485 deletions
diff --git a/include/sound/hda_register.h b/include/sound/hda_register.h
index ff1aecf325e8..0013063db7f2 100644
--- a/include/sound/hda_register.h
+++ b/include/sound/hda_register.h
@@ -89,6 +89,19 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
89#define AZX_REG_SD_BDLPL 0x18 89#define AZX_REG_SD_BDLPL 0x18
90#define AZX_REG_SD_BDLPU 0x1c 90#define AZX_REG_SD_BDLPU 0x1c
91 91
92/* GTS registers */
93#define AZX_REG_LLCH 0x14
94
95#define AZX_REG_GTS_BASE 0x520
96
97#define AZX_REG_GTSCC (AZX_REG_GTS_BASE + 0x00)
98#define AZX_REG_WALFCC (AZX_REG_GTS_BASE + 0x04)
99#define AZX_REG_TSCCL (AZX_REG_GTS_BASE + 0x08)
100#define AZX_REG_TSCCU (AZX_REG_GTS_BASE + 0x0C)
101#define AZX_REG_LLPFOC (AZX_REG_GTS_BASE + 0x14)
102#define AZX_REG_LLPCL (AZX_REG_GTS_BASE + 0x18)
103#define AZX_REG_LLPCU (AZX_REG_GTS_BASE + 0x1C)
104
92/* Haswell/Broadwell display HD-A controller Extended Mode registers */ 105/* Haswell/Broadwell display HD-A controller Extended Mode registers */
93#define AZX_REG_HSW_EM4 0x100c 106#define AZX_REG_HSW_EM4 0x100c
94#define AZX_REG_HSW_EM5 0x1010 107#define AZX_REG_HSW_EM5 0x1010
@@ -242,6 +255,29 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
242/* Interval used to calculate the iterating register offset */ 255/* Interval used to calculate the iterating register offset */
243#define AZX_DRSM_INTERVAL 0x08 256#define AZX_DRSM_INTERVAL 0x08
244 257
258/* Global time synchronization registers */
259#define GTSCC_TSCCD_MASK 0x80000000
260#define GTSCC_TSCCD_SHIFT BIT(31)
261#define GTSCC_TSCCI_MASK 0x20
262#define GTSCC_CDMAS_DMA_DIR_SHIFT 4
263
264#define WALFCC_CIF_MASK 0x1FF
265#define WALFCC_FN_SHIFT 9
266#define HDA_CLK_CYCLES_PER_FRAME 512
267
268/*
269 * An error occurs near frame "rollover". The clocks in frame value indicates
270 * whether this error may have occurred. Here we use the value of 10. Please
271 * see the errata for the right number [<10]
272 */
273#define HDA_MAX_CYCLE_VALUE 499
274#define HDA_MAX_CYCLE_OFFSET 10
275#define HDA_MAX_CYCLE_READ_RETRY 10
276
277#define TSCCU_CCU_SHIFT 32
278#define LLPC_CCU_SHIFT 32
279
280
245/* 281/*
246 * helpers to read the stream position 282 * helpers to read the stream position
247 */ 283 */
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index 93e63c56f48f..56004ec8d441 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -245,6 +245,12 @@ struct hdac_rb {
245 245
246/* 246/*
247 * HD-audio bus base driver 247 * HD-audio bus base driver
248 *
249 * @ppcap: pp capabilities pointer
250 * @spbcap: SPIB capabilities pointer
251 * @mlcap: MultiLink capabilities pointer
252 * @gtscap: gts capabilities pointer
253 * @drsmcap: dma resume capabilities pointer
248 */ 254 */
249struct hdac_bus { 255struct hdac_bus {
250 struct device *dev; 256 struct device *dev;
@@ -256,6 +262,12 @@ struct hdac_bus {
256 void __iomem *remap_addr; 262 void __iomem *remap_addr;
257 int irq; 263 int irq;
258 264
265 void __iomem *ppcap;
266 void __iomem *spbcap;
267 void __iomem *mlcap;
268 void __iomem *gtscap;
269 void __iomem *drsmcap;
270
259 /* codec linked list */ 271 /* codec linked list */
260 struct list_head codec_list; 272 struct list_head codec_list;
261 unsigned int num_codecs; 273 unsigned int num_codecs;
@@ -335,6 +347,7 @@ static inline void snd_hdac_codec_link_down(struct hdac_device *codec)
335int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val); 347int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val);
336int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr, 348int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr,
337 unsigned int *res); 349 unsigned int *res);
350int snd_hdac_bus_parse_capabilities(struct hdac_bus *bus);
338int snd_hdac_link_power(struct hdac_device *codec, bool enable); 351int snd_hdac_link_power(struct hdac_device *codec, bool enable);
339 352
340bool snd_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset); 353bool snd_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset);
diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h
index b9593b201599..8660a7f10851 100644
--- a/include/sound/hdaudio_ext.h
+++ b/include/sound/hdaudio_ext.h
@@ -8,11 +8,6 @@
8 * 8 *
9 * @bus: hdac bus 9 * @bus: hdac bus
10 * @num_streams: streams supported 10 * @num_streams: streams supported
11 * @ppcap: pp capabilities pointer
12 * @spbcap: SPIB capabilities pointer
13 * @mlcap: MultiLink capabilities pointer
14 * @gtscap: gts capabilities pointer
15 * @drsmcap: dma resume capabilities pointer
16 * @hlink_list: link list of HDA links 11 * @hlink_list: link list of HDA links
17 * @lock: lock for link mgmt 12 * @lock: lock for link mgmt
18 * @cmd_dma_state: state of cmd DMAs: CORB and RIRB 13 * @cmd_dma_state: state of cmd DMAs: CORB and RIRB
@@ -22,12 +17,6 @@ struct hdac_ext_bus {
22 int num_streams; 17 int num_streams;
23 int idx; 18 int idx;
24 19
25 void __iomem *ppcap;
26 void __iomem *spbcap;
27 void __iomem *mlcap;
28 void __iomem *gtscap;
29 void __iomem *drsmcap;
30
31 struct list_head hlink_list; 20 struct list_head hlink_list;
32 21
33 struct mutex lock; 22 struct mutex lock;
@@ -54,7 +43,6 @@ void snd_hdac_ext_bus_device_remove(struct hdac_ext_bus *ebus);
54#define HDA_CODEC_EXT_ENTRY(_vid, _revid, _name, _drv_data) \ 43#define HDA_CODEC_EXT_ENTRY(_vid, _revid, _name, _drv_data) \
55 HDA_CODEC_REV_EXT_ENTRY(_vid, _revid, _name, _drv_data) 44 HDA_CODEC_REV_EXT_ENTRY(_vid, _revid, _name, _drv_data)
56 45
57int snd_hdac_ext_bus_parse_capabilities(struct hdac_ext_bus *sbus);
58void snd_hdac_ext_bus_ppcap_enable(struct hdac_ext_bus *chip, bool enable); 46void snd_hdac_ext_bus_ppcap_enable(struct hdac_ext_bus *chip, bool enable);
59void snd_hdac_ext_bus_ppcap_int_enable(struct hdac_ext_bus *chip, bool enable); 47void snd_hdac_ext_bus_ppcap_int_enable(struct hdac_ext_bus *chip, bool enable);
60 48
diff --git a/include/uapi/sound/Kbuild b/include/uapi/sound/Kbuild
index 691984cb0b91..9578d8bdbf31 100644
--- a/include/uapi/sound/Kbuild
+++ b/include/uapi/sound/Kbuild
@@ -13,3 +13,4 @@ header-y += sb16_csp.h
13header-y += sfnt_info.h 13header-y += sfnt_info.h
14header-y += tlv.h 14header-y += tlv.h
15header-y += usb_stream.h 15header-y += usb_stream.h
16header-y += snd_sst_tokens.h
diff --git a/include/uapi/sound/snd_sst_tokens.h b/include/uapi/sound/snd_sst_tokens.h
new file mode 100644
index 000000000000..1ee2e943d66a
--- /dev/null
+++ b/include/uapi/sound/snd_sst_tokens.h
@@ -0,0 +1,214 @@
1/*
2 * snd_sst_tokens.h - Intel SST tokens definition
3 *
4 * Copyright (C) 2016 Intel Corp
5 * Author: Shreyas NC <shreyas.nc@intel.com>
6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as version 2, as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17#ifndef __SND_SST_TOKENS_H__
18#define __SND_SST_TOKENS_H__
19
20/**
21 * %SKL_TKN_UUID: Module UUID
22 *
23 * %SKL_TKN_U8_BLOCK_TYPE: Type of the private data block.Can be:
24 * tuples, bytes, short and words
25 *
26 * %SKL_TKN_U8_IN_PIN_TYPE: Input pin type,
27 * homogenous=0, heterogenous=1
28 *
29 * %SKL_TKN_U8_OUT_PIN_TYPE: Output pin type,
30 * homogenous=0, heterogenous=1
31 * %SKL_TKN_U8_DYN_IN_PIN: Configure Input pin dynamically
32 * if true
33 *
34 * %SKL_TKN_U8_DYN_OUT_PIN: Configure Output pin dynamically
35 * if true
36 *
37 * %SKL_TKN_U8_IN_QUEUE_COUNT: Store the number of Input pins
38 *
39 * %SKL_TKN_U8_OUT_QUEUE_COUNT: Store the number of Output pins
40 *
41 * %SKL_TKN_U8_TIME_SLOT: TDM slot number
42 *
43 * %SKL_TKN_U8_CORE_ID: Stores module affinity value.Can take
44 * the values:
45 * SKL_AFFINITY_CORE_0 = 0,
46 * SKL_AFFINITY_CORE_1,
47 * SKL_AFFINITY_CORE_MAX
48 *
49 * %SKL_TKN_U8_MOD_TYPE: Module type value.
50 *
51 * %SKL_TKN_U8_CONN_TYPE: Module connection type can be a FE,
52 * BE or NONE as defined :
53 * SKL_PIPE_CONN_TYPE_NONE = 0,
54 * SKL_PIPE_CONN_TYPE_FE = 1 (HOST_DMA)
55 * SKL_PIPE_CONN_TYPE_BE = 2 (LINK_DMA)
56 *
57 * %SKL_TKN_U8_DEV_TYPE: Type of device to which the module is
58 * connected
59 * Can take the values:
60 * SKL_DEVICE_BT = 0x0,
61 * SKL_DEVICE_DMIC = 0x1,
62 * SKL_DEVICE_I2S = 0x2,
63 * SKL_DEVICE_SLIMBUS = 0x3,
64 * SKL_DEVICE_HDALINK = 0x4,
65 * SKL_DEVICE_HDAHOST = 0x5,
66 * SKL_DEVICE_NONE
67 *
68 * %SKL_TKN_U8_HW_CONN_TYPE: Connection type of the HW to which the
69 * module is connected
70 * SKL_CONN_NONE = 0,
71 * SKL_CONN_SOURCE = 1,
72 * SKL_CONN_SINK = 2
73 *
74 * %SKL_TKN_U16_PIN_INST_ID: Stores the pin instance id
75 *
76 * %SKL_TKN_U16_MOD_INST_ID: Stores the mdule instance id
77 *
78 * %SKL_TKN_U32_MAX_MCPS: Module max mcps value
79 *
80 * %SKL_TKN_U32_MEM_PAGES: Module resource pages
81 *
82 * %SKL_TKN_U32_OBS: Stores Output Buffer size
83 *
84 * %SKL_TKN_U32_IBS: Stores input buffer size
85 *
86 * %SKL_TKN_U32_VBUS_ID: Module VBUS_ID. PDM=0, SSP0=0,
87 * SSP1=1,SSP2=2,
88 * SSP3=3, SSP4=4,
89 * SSP5=5, SSP6=6,INVALID
90 *
91 * %SKL_TKN_U32_PARAMS_FIXUP: Module Params fixup mask
92 * %SKL_TKN_U32_CONVERTER: Module params converter mask
93 * %SKL_TKN_U32_PIPE_ID: Stores the pipe id
94 *
95 * %SKL_TKN_U32_PIPE_CONN_TYPE: Type of the token to which the pipe is
96 * connected to. It can be
97 * SKL_PIPE_CONN_TYPE_NONE = 0,
98 * SKL_PIPE_CONN_TYPE_FE = 1 (HOST_DMA),
99 * SKL_PIPE_CONN_TYPE_BE = 2 (LINK_DMA),
100 *
101 * %SKL_TKN_U32_PIPE_PRIORITY: Pipe priority value
102 * %SKL_TKN_U32_PIPE_MEM_PGS: Pipe resource pages
103 *
104 * %SKL_TKN_U32_DIR_PIN_COUNT: Value for the direction to set input/output
105 * formats and the pin count.
106 * The first 4 bits have the direction
107 * value and the next 4 have
108 * the pin count value.
109 * SKL_DIR_IN = 0, SKL_DIR_OUT = 1.
110 * The input and output formats
111 * share the same set of tokens
112 * with the distinction between input
113 * and output made by reading direction
114 * token.
115 *
116 * %SKL_TKN_U32_FMT_CH: Supported channel count
117 *
118 * %SKL_TKN_U32_FMT_FREQ: Supported frequency/sample rate
119 *
120 * %SKL_TKN_U32_FMT_BIT_DEPTH: Supported container size
121 *
122 * %SKL_TKN_U32_FMT_SAMPLE_SIZE:Number of samples in the container
123 *
124 * %SKL_TKN_U32_FMT_CH_CONFIG: Supported channel configurations for the
125 * input/output.
126 *
127 * %SKL_TKN_U32_FMT_INTERLEAVE: Interleaving style which can be per
128 * channel or per sample. The values can be :
129 * SKL_INTERLEAVING_PER_CHANNEL = 0,
130 * SKL_INTERLEAVING_PER_SAMPLE = 1,
131 *
132 * %SKL_TKN_U32_FMT_SAMPLE_TYPE:
133 * Specifies the sample type. Can take the
134 * values: SKL_SAMPLE_TYPE_INT_MSB = 0,
135 * SKL_SAMPLE_TYPE_INT_LSB = 1,
136 * SKL_SAMPLE_TYPE_INT_SIGNED = 2,
137 * SKL_SAMPLE_TYPE_INT_UNSIGNED = 3,
138 * SKL_SAMPLE_TYPE_FLOAT = 4
139 *
140 * %SKL_TKN_U32_CH_MAP: Channel map values
141 * %SKL_TKN_U32_MOD_SET_PARAMS: It can take these values:
142 * SKL_PARAM_DEFAULT, SKL_PARAM_INIT,
143 * SKL_PARAM_SET, SKL_PARAM_BIND
144 *
145 * %SKL_TKN_U32_MOD_PARAM_ID: ID of the module params
146 *
147 * %SKL_TKN_U32_CAPS_SET_PARAMS:
148 * Set params value
149 *
150 * %SKL_TKN_U32_CAPS_PARAMS_ID: Params ID
151 *
152 * %SKL_TKN_U32_CAPS_SIZE: Caps size
153 *
154 * %SKL_TKN_U32_PROC_DOMAIN: Specify processing domain
155 *
156 * %SKL_TKN_U32_LIB_COUNT: Specifies the number of libraries
157 *
158 * %SKL_TKN_STR_LIB_NAME: Specifies the library name
159 *
160 * module_id and loadable flags dont have tokens as these values will be
161 * read from the DSP FW manifest
162 */
163enum SKL_TKNS {
164 SKL_TKN_UUID = 1,
165 SKL_TKN_U8_NUM_BLOCKS,
166 SKL_TKN_U8_BLOCK_TYPE,
167 SKL_TKN_U8_IN_PIN_TYPE,
168 SKL_TKN_U8_OUT_PIN_TYPE,
169 SKL_TKN_U8_DYN_IN_PIN,
170 SKL_TKN_U8_DYN_OUT_PIN,
171 SKL_TKN_U8_IN_QUEUE_COUNT,
172 SKL_TKN_U8_OUT_QUEUE_COUNT,
173 SKL_TKN_U8_TIME_SLOT,
174 SKL_TKN_U8_CORE_ID,
175 SKL_TKN_U8_MOD_TYPE,
176 SKL_TKN_U8_CONN_TYPE,
177 SKL_TKN_U8_DEV_TYPE,
178 SKL_TKN_U8_HW_CONN_TYPE,
179 SKL_TKN_U16_MOD_INST_ID,
180 SKL_TKN_U16_BLOCK_SIZE,
181 SKL_TKN_U32_MAX_MCPS,
182 SKL_TKN_U32_MEM_PAGES,
183 SKL_TKN_U32_OBS,
184 SKL_TKN_U32_IBS,
185 SKL_TKN_U32_VBUS_ID,
186 SKL_TKN_U32_PARAMS_FIXUP,
187 SKL_TKN_U32_CONVERTER,
188 SKL_TKN_U32_PIPE_ID,
189 SKL_TKN_U32_PIPE_CONN_TYPE,
190 SKL_TKN_U32_PIPE_PRIORITY,
191 SKL_TKN_U32_PIPE_MEM_PGS,
192 SKL_TKN_U32_DIR_PIN_COUNT,
193 SKL_TKN_U32_FMT_CH,
194 SKL_TKN_U32_FMT_FREQ,
195 SKL_TKN_U32_FMT_BIT_DEPTH,
196 SKL_TKN_U32_FMT_SAMPLE_SIZE,
197 SKL_TKN_U32_FMT_CH_CONFIG,
198 SKL_TKN_U32_FMT_INTERLEAVE,
199 SKL_TKN_U32_FMT_SAMPLE_TYPE,
200 SKL_TKN_U32_FMT_CH_MAP,
201 SKL_TKN_U32_PIN_MOD_ID,
202 SKL_TKN_U32_PIN_INST_ID,
203 SKL_TKN_U32_MOD_SET_PARAMS,
204 SKL_TKN_U32_MOD_PARAM_ID,
205 SKL_TKN_U32_CAPS_SET_PARAMS,
206 SKL_TKN_U32_CAPS_PARAMS_ID,
207 SKL_TKN_U32_CAPS_SIZE,
208 SKL_TKN_U32_PROC_DOMAIN,
209 SKL_TKN_U32_LIB_COUNT,
210 SKL_TKN_STR_LIB_NAME,
211 SKL_TKN_MAX = SKL_TKN_STR_LIB_NAME,
212};
213
214#endif
diff --git a/sound/hda/ext/hdac_ext_controller.c b/sound/hda/ext/hdac_ext_controller.c
index 860f8cad6602..261469188566 100644
--- a/sound/hda/ext/hdac_ext_controller.c
+++ b/sound/hda/ext/hdac_ext_controller.c
@@ -29,81 +29,6 @@
29 */ 29 */
30#define HDAC_MAX_CAPS 10 30#define HDAC_MAX_CAPS 10
31 31
32/**
33 * snd_hdac_ext_bus_parse_capabilities - parse capablity structure
34 * @ebus: the pointer to extended bus object
35 *
36 * Returns 0 if successful, or a negative error code.
37 */
38int snd_hdac_ext_bus_parse_capabilities(struct hdac_ext_bus *ebus)
39{
40 unsigned int cur_cap;
41 unsigned int offset;
42 struct hdac_bus *bus = &ebus->bus;
43 unsigned int counter = 0;
44
45 offset = snd_hdac_chip_readl(bus, LLCH);
46
47 /* Lets walk the linked capabilities list */
48 do {
49 cur_cap = _snd_hdac_chip_read(l, bus, offset);
50
51 dev_dbg(bus->dev, "Capability version: 0x%x\n",
52 ((cur_cap & AZX_CAP_HDR_VER_MASK) >> AZX_CAP_HDR_VER_OFF));
53
54 dev_dbg(bus->dev, "HDA capability ID: 0x%x\n",
55 (cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF);
56
57 switch ((cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF) {
58 case AZX_ML_CAP_ID:
59 dev_dbg(bus->dev, "Found ML capability\n");
60 ebus->mlcap = bus->remap_addr + offset;
61 break;
62
63 case AZX_GTS_CAP_ID:
64 dev_dbg(bus->dev, "Found GTS capability offset=%x\n", offset);
65 ebus->gtscap = bus->remap_addr + offset;
66 break;
67
68 case AZX_PP_CAP_ID:
69 /* PP capability found, the Audio DSP is present */
70 dev_dbg(bus->dev, "Found PP capability offset=%x\n", offset);
71 ebus->ppcap = bus->remap_addr + offset;
72 break;
73
74 case AZX_SPB_CAP_ID:
75 /* SPIB capability found, handler function */
76 dev_dbg(bus->dev, "Found SPB capability\n");
77 ebus->spbcap = bus->remap_addr + offset;
78 break;
79
80 case AZX_DRSM_CAP_ID:
81 /* DMA resume capability found, handler function */
82 dev_dbg(bus->dev, "Found DRSM capability\n");
83 ebus->drsmcap = bus->remap_addr + offset;
84 break;
85
86 default:
87 dev_dbg(bus->dev, "Unknown capability %d\n", cur_cap);
88 break;
89 }
90
91 counter++;
92
93 if (counter > HDAC_MAX_CAPS) {
94 dev_err(bus->dev, "We exceeded HDAC Ext capablities!!!\n");
95 break;
96 }
97
98 /* read the offset of next capabiity */
99 offset = cur_cap & AZX_CAP_HDR_NXT_PTR_MASK;
100
101 } while (offset);
102
103 return 0;
104}
105EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_parse_capabilities);
106
107/* 32/*
108 * processing pipe helpers - these helpers are useful for dealing with HDA 33 * processing pipe helpers - these helpers are useful for dealing with HDA
109 * new capability of processing pipelines 34 * new capability of processing pipelines
@@ -118,15 +43,15 @@ void snd_hdac_ext_bus_ppcap_enable(struct hdac_ext_bus *ebus, bool enable)
118{ 43{
119 struct hdac_bus *bus = &ebus->bus; 44 struct hdac_bus *bus = &ebus->bus;
120 45
121 if (!ebus->ppcap) { 46 if (!bus->ppcap) {
122 dev_err(bus->dev, "Address of PP capability is NULL"); 47 dev_err(bus->dev, "Address of PP capability is NULL");
123 return; 48 return;
124 } 49 }
125 50
126 if (enable) 51 if (enable)
127 snd_hdac_updatel(ebus->ppcap, AZX_REG_PP_PPCTL, 0, AZX_PPCTL_GPROCEN); 52 snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, 0, AZX_PPCTL_GPROCEN);
128 else 53 else
129 snd_hdac_updatel(ebus->ppcap, AZX_REG_PP_PPCTL, AZX_PPCTL_GPROCEN, 0); 54 snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, AZX_PPCTL_GPROCEN, 0);
130} 55}
131EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_ppcap_enable); 56EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_ppcap_enable);
132 57
@@ -139,15 +64,15 @@ void snd_hdac_ext_bus_ppcap_int_enable(struct hdac_ext_bus *ebus, bool enable)
139{ 64{
140 struct hdac_bus *bus = &ebus->bus; 65 struct hdac_bus *bus = &ebus->bus;
141 66
142 if (!ebus->ppcap) { 67 if (!bus->ppcap) {
143 dev_err(bus->dev, "Address of PP capability is NULL\n"); 68 dev_err(bus->dev, "Address of PP capability is NULL\n");
144 return; 69 return;
145 } 70 }
146 71
147 if (enable) 72 if (enable)
148 snd_hdac_updatel(ebus->ppcap, AZX_REG_PP_PPCTL, 0, AZX_PPCTL_PIE); 73 snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, 0, AZX_PPCTL_PIE);
149 else 74 else
150 snd_hdac_updatel(ebus->ppcap, AZX_REG_PP_PPCTL, AZX_PPCTL_PIE, 0); 75 snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, AZX_PPCTL_PIE, 0);
151} 76}
152EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_ppcap_int_enable); 77EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_ppcap_int_enable);
153 78
@@ -171,7 +96,7 @@ int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_ext_bus *ebus)
171 struct hdac_ext_link *hlink; 96 struct hdac_ext_link *hlink;
172 struct hdac_bus *bus = &ebus->bus; 97 struct hdac_bus *bus = &ebus->bus;
173 98
174 link_count = readl(ebus->mlcap + AZX_REG_ML_MLCD) + 1; 99 link_count = readl(bus->mlcap + AZX_REG_ML_MLCD) + 1;
175 100
176 dev_dbg(bus->dev, "In %s Link count: %d\n", __func__, link_count); 101 dev_dbg(bus->dev, "In %s Link count: %d\n", __func__, link_count);
177 102
@@ -181,7 +106,7 @@ int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_ext_bus *ebus)
181 return -ENOMEM; 106 return -ENOMEM;
182 hlink->index = idx; 107 hlink->index = idx;
183 hlink->bus = bus; 108 hlink->bus = bus;
184 hlink->ml_addr = ebus->mlcap + AZX_ML_BASE + 109 hlink->ml_addr = bus->mlcap + AZX_ML_BASE +
185 (AZX_ML_INTERVAL * idx); 110 (AZX_ML_INTERVAL * idx);
186 hlink->lcaps = readl(hlink->ml_addr + AZX_REG_ML_LCAP); 111 hlink->lcaps = readl(hlink->ml_addr + AZX_REG_ML_LCAP);
187 hlink->lsdiid = readw(hlink->ml_addr + AZX_REG_ML_LSDIID); 112 hlink->lsdiid = readw(hlink->ml_addr + AZX_REG_ML_LSDIID);
diff --git a/sound/hda/ext/hdac_ext_stream.c b/sound/hda/ext/hdac_ext_stream.c
index 626f3bb24c55..2441273adcef 100644
--- a/sound/hda/ext/hdac_ext_stream.c
+++ b/sound/hda/ext/hdac_ext_stream.c
@@ -40,27 +40,27 @@ void snd_hdac_ext_stream_init(struct hdac_ext_bus *ebus,
40{ 40{
41 struct hdac_bus *bus = &ebus->bus; 41 struct hdac_bus *bus = &ebus->bus;
42 42
43 if (ebus->ppcap) { 43 if (bus->ppcap) {
44 stream->pphc_addr = ebus->ppcap + AZX_PPHC_BASE + 44 stream->pphc_addr = bus->ppcap + AZX_PPHC_BASE +
45 AZX_PPHC_INTERVAL * idx; 45 AZX_PPHC_INTERVAL * idx;
46 46
47 stream->pplc_addr = ebus->ppcap + AZX_PPLC_BASE + 47 stream->pplc_addr = bus->ppcap + AZX_PPLC_BASE +
48 AZX_PPLC_MULTI * ebus->num_streams + 48 AZX_PPLC_MULTI * ebus->num_streams +
49 AZX_PPLC_INTERVAL * idx; 49 AZX_PPLC_INTERVAL * idx;
50 } 50 }
51 51
52 if (ebus->spbcap) { 52 if (bus->spbcap) {
53 stream->spib_addr = ebus->spbcap + AZX_SPB_BASE + 53 stream->spib_addr = bus->spbcap + AZX_SPB_BASE +
54 AZX_SPB_INTERVAL * idx + 54 AZX_SPB_INTERVAL * idx +
55 AZX_SPB_SPIB; 55 AZX_SPB_SPIB;
56 56
57 stream->fifo_addr = ebus->spbcap + AZX_SPB_BASE + 57 stream->fifo_addr = bus->spbcap + AZX_SPB_BASE +
58 AZX_SPB_INTERVAL * idx + 58 AZX_SPB_INTERVAL * idx +
59 AZX_SPB_MAXFIFO; 59 AZX_SPB_MAXFIFO;
60 } 60 }
61 61
62 if (ebus->drsmcap) 62 if (bus->drsmcap)
63 stream->dpibr_addr = ebus->drsmcap + AZX_DRSM_BASE + 63 stream->dpibr_addr = bus->drsmcap + AZX_DRSM_BASE +
64 AZX_DRSM_INTERVAL * idx; 64 AZX_DRSM_INTERVAL * idx;
65 65
66 stream->decoupled = false; 66 stream->decoupled = false;
@@ -131,10 +131,10 @@ void snd_hdac_ext_stream_decouple(struct hdac_ext_bus *ebus,
131 131
132 spin_lock_irq(&bus->reg_lock); 132 spin_lock_irq(&bus->reg_lock);
133 if (decouple) 133 if (decouple)
134 snd_hdac_updatel(ebus->ppcap, AZX_REG_PP_PPCTL, 0, 134 snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, 0,
135 AZX_PPCTL_PROCEN(hstream->index)); 135 AZX_PPCTL_PROCEN(hstream->index));
136 else 136 else
137 snd_hdac_updatel(ebus->ppcap, AZX_REG_PP_PPCTL, 137 snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL,
138 AZX_PPCTL_PROCEN(hstream->index), 0); 138 AZX_PPCTL_PROCEN(hstream->index), 0);
139 stream->decoupled = decouple; 139 stream->decoupled = decouple;
140 spin_unlock_irq(&bus->reg_lock); 140 spin_unlock_irq(&bus->reg_lock);
@@ -255,7 +255,7 @@ hdac_ext_link_stream_assign(struct hdac_ext_bus *ebus,
255 struct hdac_stream *stream = NULL; 255 struct hdac_stream *stream = NULL;
256 struct hdac_bus *hbus = &ebus->bus; 256 struct hdac_bus *hbus = &ebus->bus;
257 257
258 if (!ebus->ppcap) { 258 if (!hbus->ppcap) {
259 dev_err(hbus->dev, "stream type not supported\n"); 259 dev_err(hbus->dev, "stream type not supported\n");
260 return NULL; 260 return NULL;
261 } 261 }
@@ -296,7 +296,7 @@ hdac_ext_host_stream_assign(struct hdac_ext_bus *ebus,
296 struct hdac_stream *stream = NULL; 296 struct hdac_stream *stream = NULL;
297 struct hdac_bus *hbus = &ebus->bus; 297 struct hdac_bus *hbus = &ebus->bus;
298 298
299 if (!ebus->ppcap) { 299 if (!hbus->ppcap) {
300 dev_err(hbus->dev, "stream type not supported\n"); 300 dev_err(hbus->dev, "stream type not supported\n");
301 return NULL; 301 return NULL;
302 } 302 }
@@ -423,21 +423,21 @@ void snd_hdac_ext_stream_spbcap_enable(struct hdac_ext_bus *ebus,
423 u32 register_mask = 0; 423 u32 register_mask = 0;
424 struct hdac_bus *bus = &ebus->bus; 424 struct hdac_bus *bus = &ebus->bus;
425 425
426 if (!ebus->spbcap) { 426 if (!bus->spbcap) {
427 dev_err(bus->dev, "Address of SPB capability is NULL"); 427 dev_err(bus->dev, "Address of SPB capability is NULL");
428 return; 428 return;
429 } 429 }
430 430
431 mask |= (1 << index); 431 mask |= (1 << index);
432 432
433 register_mask = readl(ebus->spbcap + AZX_REG_SPB_SPBFCCTL); 433 register_mask = readl(bus->spbcap + AZX_REG_SPB_SPBFCCTL);
434 434
435 mask |= register_mask; 435 mask |= register_mask;
436 436
437 if (enable) 437 if (enable)
438 snd_hdac_updatel(ebus->spbcap, AZX_REG_SPB_SPBFCCTL, 0, mask); 438 snd_hdac_updatel(bus->spbcap, AZX_REG_SPB_SPBFCCTL, 0, mask);
439 else 439 else
440 snd_hdac_updatel(ebus->spbcap, AZX_REG_SPB_SPBFCCTL, mask, 0); 440 snd_hdac_updatel(bus->spbcap, AZX_REG_SPB_SPBFCCTL, mask, 0);
441} 441}
442EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_spbcap_enable); 442EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_spbcap_enable);
443 443
@@ -452,7 +452,7 @@ int snd_hdac_ext_stream_set_spib(struct hdac_ext_bus *ebus,
452{ 452{
453 struct hdac_bus *bus = &ebus->bus; 453 struct hdac_bus *bus = &ebus->bus;
454 454
455 if (!ebus->spbcap) { 455 if (!bus->spbcap) {
456 dev_err(bus->dev, "Address of SPB capability is NULL"); 456 dev_err(bus->dev, "Address of SPB capability is NULL");
457 return -EINVAL; 457 return -EINVAL;
458 } 458 }
@@ -475,7 +475,7 @@ int snd_hdac_ext_stream_get_spbmaxfifo(struct hdac_ext_bus *ebus,
475{ 475{
476 struct hdac_bus *bus = &ebus->bus; 476 struct hdac_bus *bus = &ebus->bus;
477 477
478 if (!ebus->spbcap) { 478 if (!bus->spbcap) {
479 dev_err(bus->dev, "Address of SPB capability is NULL"); 479 dev_err(bus->dev, "Address of SPB capability is NULL");
480 return -EINVAL; 480 return -EINVAL;
481 } 481 }
@@ -515,21 +515,21 @@ void snd_hdac_ext_stream_drsm_enable(struct hdac_ext_bus *ebus,
515 u32 register_mask = 0; 515 u32 register_mask = 0;
516 struct hdac_bus *bus = &ebus->bus; 516 struct hdac_bus *bus = &ebus->bus;
517 517
518 if (!ebus->drsmcap) { 518 if (!bus->drsmcap) {
519 dev_err(bus->dev, "Address of DRSM capability is NULL"); 519 dev_err(bus->dev, "Address of DRSM capability is NULL");
520 return; 520 return;
521 } 521 }
522 522
523 mask |= (1 << index); 523 mask |= (1 << index);
524 524
525 register_mask = readl(ebus->drsmcap + AZX_REG_SPB_SPBFCCTL); 525 register_mask = readl(bus->drsmcap + AZX_REG_SPB_SPBFCCTL);
526 526
527 mask |= register_mask; 527 mask |= register_mask;
528 528
529 if (enable) 529 if (enable)
530 snd_hdac_updatel(ebus->drsmcap, AZX_REG_DRSM_CTL, 0, mask); 530 snd_hdac_updatel(bus->drsmcap, AZX_REG_DRSM_CTL, 0, mask);
531 else 531 else
532 snd_hdac_updatel(ebus->drsmcap, AZX_REG_DRSM_CTL, mask, 0); 532 snd_hdac_updatel(bus->drsmcap, AZX_REG_DRSM_CTL, mask, 0);
533} 533}
534EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_drsm_enable); 534EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_drsm_enable);
535 535
@@ -544,7 +544,7 @@ int snd_hdac_ext_stream_set_dpibr(struct hdac_ext_bus *ebus,
544{ 544{
545 struct hdac_bus *bus = &ebus->bus; 545 struct hdac_bus *bus = &ebus->bus;
546 546
547 if (!ebus->drsmcap) { 547 if (!bus->drsmcap) {
548 dev_err(bus->dev, "Address of DRSM capability is NULL"); 548 dev_err(bus->dev, "Address of DRSM capability is NULL");
549 return -EINVAL; 549 return -EINVAL;
550 } 550 }
diff --git a/sound/hda/hdac_controller.c b/sound/hda/hdac_controller.c
index 9fee464e5d49..043065867656 100644
--- a/sound/hda/hdac_controller.c
+++ b/sound/hda/hdac_controller.c
@@ -255,6 +255,81 @@ int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr,
255} 255}
256EXPORT_SYMBOL_GPL(snd_hdac_bus_get_response); 256EXPORT_SYMBOL_GPL(snd_hdac_bus_get_response);
257 257
258#define HDAC_MAX_CAPS 10
259/**
260 * snd_hdac_bus_parse_capabilities - parse capability structure
261 * @bus: the pointer to bus object
262 *
263 * Returns 0 if successful, or a negative error code.
264 */
265int snd_hdac_bus_parse_capabilities(struct hdac_bus *bus)
266{
267 unsigned int cur_cap;
268 unsigned int offset;
269 unsigned int counter = 0;
270
271 offset = snd_hdac_chip_readl(bus, LLCH);
272
273 /* Lets walk the linked capabilities list */
274 do {
275 cur_cap = _snd_hdac_chip_read(l, bus, offset);
276
277 dev_dbg(bus->dev, "Capability version: 0x%x\n",
278 (cur_cap & AZX_CAP_HDR_VER_MASK) >> AZX_CAP_HDR_VER_OFF);
279
280 dev_dbg(bus->dev, "HDA capability ID: 0x%x\n",
281 (cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF);
282
283 switch ((cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF) {
284 case AZX_ML_CAP_ID:
285 dev_dbg(bus->dev, "Found ML capability\n");
286 bus->mlcap = bus->remap_addr + offset;
287 break;
288
289 case AZX_GTS_CAP_ID:
290 dev_dbg(bus->dev, "Found GTS capability offset=%x\n", offset);
291 bus->gtscap = bus->remap_addr + offset;
292 break;
293
294 case AZX_PP_CAP_ID:
295 /* PP capability found, the Audio DSP is present */
296 dev_dbg(bus->dev, "Found PP capability offset=%x\n", offset);
297 bus->ppcap = bus->remap_addr + offset;
298 break;
299
300 case AZX_SPB_CAP_ID:
301 /* SPIB capability found, handler function */
302 dev_dbg(bus->dev, "Found SPB capability\n");
303 bus->spbcap = bus->remap_addr + offset;
304 break;
305
306 case AZX_DRSM_CAP_ID:
307 /* DMA resume capability found, handler function */
308 dev_dbg(bus->dev, "Found DRSM capability\n");
309 bus->drsmcap = bus->remap_addr + offset;
310 break;
311
312 default:
313 dev_dbg(bus->dev, "Unknown capability %d\n", cur_cap);
314 break;
315 }
316
317 counter++;
318
319 if (counter > HDAC_MAX_CAPS) {
320 dev_err(bus->dev, "We exceeded HDAC capabilities!!!\n");
321 break;
322 }
323
324 /* read the offset of next capability */
325 offset = cur_cap & AZX_CAP_HDR_NXT_PTR_MASK;
326
327 } while (offset);
328
329 return 0;
330}
331EXPORT_SYMBOL_GPL(snd_hdac_bus_parse_capabilities);
332
258/* 333/*
259 * Lowlevel interface 334 * Lowlevel interface
260 */ 335 */
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
index 27de8015717d..2ad3b447483f 100644
--- a/sound/pci/hda/hda_controller.c
+++ b/sound/pci/hda/hda_controller.c
@@ -27,6 +27,12 @@
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/pm_runtime.h> 28#include <linux/pm_runtime.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30
31#ifdef CONFIG_X86
32/* for art-tsc conversion */
33#include <asm/tsc.h>
34#endif
35
30#include <sound/core.h> 36#include <sound/core.h>
31#include <sound/initval.h> 37#include <sound/initval.h>
32#include "hda_controller.h" 38#include "hda_controller.h"
@@ -337,12 +343,173 @@ static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream)
337 azx_get_position(chip, azx_dev)); 343 azx_get_position(chip, azx_dev));
338} 344}
339 345
346/*
347 * azx_scale64: Scale base by mult/div while not overflowing sanely
348 *
349 * Derived from scale64_check_overflow in kernel/time/timekeeping.c
350 *
351 * The tmestamps for a 48Khz stream can overflow after (2^64/10^9)/48K which
352 * is about 384307 ie ~4.5 days.
353 *
354 * This scales the calculation so that overflow will happen but after 2^64 /
355 * 48000 secs, which is pretty large!
356 *
357 * In caln below:
358 * base may overflow, but since there isn’t any additional division
359 * performed on base it’s OK
360 * rem can’t overflow because both are 32-bit values
361 */
362
363#ifdef CONFIG_X86
364static u64 azx_scale64(u64 base, u32 num, u32 den)
365{
366 u64 rem;
367
368 rem = do_div(base, den);
369
370 base *= num;
371 rem *= num;
372
373 do_div(rem, den);
374
375 return base + rem;
376}
377
378static int azx_get_sync_time(ktime_t *device,
379 struct system_counterval_t *system, void *ctx)
380{
381 struct snd_pcm_substream *substream = ctx;
382 struct azx_dev *azx_dev = get_azx_dev(substream);
383 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
384 struct azx *chip = apcm->chip;
385 struct snd_pcm_runtime *runtime;
386 u64 ll_counter, ll_counter_l, ll_counter_h;
387 u64 tsc_counter, tsc_counter_l, tsc_counter_h;
388 u32 wallclk_ctr, wallclk_cycles;
389 bool direction;
390 u32 dma_select;
391 u32 timeout = 200;
392 u32 retry_count = 0;
393
394 runtime = substream->runtime;
395
396 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
397 direction = 1;
398 else
399 direction = 0;
400
401 /* 0th stream tag is not used, so DMA ch 0 is for 1st stream tag */
402 do {
403 timeout = 100;
404 dma_select = (direction << GTSCC_CDMAS_DMA_DIR_SHIFT) |
405 (azx_dev->core.stream_tag - 1);
406 snd_hdac_chip_writel(azx_bus(chip), GTSCC, dma_select);
407
408 /* Enable the capture */
409 snd_hdac_chip_updatel(azx_bus(chip), GTSCC, 0, GTSCC_TSCCI_MASK);
410
411 while (timeout) {
412 if (snd_hdac_chip_readl(azx_bus(chip), GTSCC) &
413 GTSCC_TSCCD_MASK)
414 break;
415
416 timeout--;
417 }
418
419 if (!timeout) {
420 dev_err(chip->card->dev, "GTSCC capture Timedout!\n");
421 return -EIO;
422 }
423
424 /* Read wall clock counter */
425 wallclk_ctr = snd_hdac_chip_readl(azx_bus(chip), WALFCC);
426
427 /* Read TSC counter */
428 tsc_counter_l = snd_hdac_chip_readl(azx_bus(chip), TSCCL);
429 tsc_counter_h = snd_hdac_chip_readl(azx_bus(chip), TSCCU);
430
431 /* Read Link counter */
432 ll_counter_l = snd_hdac_chip_readl(azx_bus(chip), LLPCL);
433 ll_counter_h = snd_hdac_chip_readl(azx_bus(chip), LLPCU);
434
435 /* Ack: registers read done */
436 snd_hdac_chip_writel(azx_bus(chip), GTSCC, GTSCC_TSCCD_SHIFT);
437
438 tsc_counter = (tsc_counter_h << TSCCU_CCU_SHIFT) |
439 tsc_counter_l;
440
441 ll_counter = (ll_counter_h << LLPC_CCU_SHIFT) | ll_counter_l;
442 wallclk_cycles = wallclk_ctr & WALFCC_CIF_MASK;
443
444 /*
445 * An error occurs near frame "rollover". The clocks in
446 * frame value indicates whether this error may have
447 * occurred. Here we use the value of 10 i.e.,
448 * HDA_MAX_CYCLE_OFFSET
449 */
450 if (wallclk_cycles < HDA_MAX_CYCLE_VALUE - HDA_MAX_CYCLE_OFFSET
451 && wallclk_cycles > HDA_MAX_CYCLE_OFFSET)
452 break;
453
454 /*
455 * Sleep before we read again, else we may again get
456 * value near to MAX_CYCLE. Try to sleep for different
457 * amount of time so we dont hit the same number again
458 */
459 udelay(retry_count++);
460
461 } while (retry_count != HDA_MAX_CYCLE_READ_RETRY);
462
463 if (retry_count == HDA_MAX_CYCLE_READ_RETRY) {
464 dev_err_ratelimited(chip->card->dev,
465 "Error in WALFCC cycle count\n");
466 return -EIO;
467 }
468
469 *device = ns_to_ktime(azx_scale64(ll_counter,
470 NSEC_PER_SEC, runtime->rate));
471 *device = ktime_add_ns(*device, (wallclk_cycles * NSEC_PER_SEC) /
472 ((HDA_MAX_CYCLE_VALUE + 1) * runtime->rate));
473
474 *system = convert_art_to_tsc(tsc_counter);
475
476 return 0;
477}
478
479#else
480static int azx_get_sync_time(ktime_t *device,
481 struct system_counterval_t *system, void *ctx)
482{
483 return -ENXIO;
484}
485#endif
486
487static int azx_get_crosststamp(struct snd_pcm_substream *substream,
488 struct system_device_crosststamp *xtstamp)
489{
490 return get_device_system_crosststamp(azx_get_sync_time,
491 substream, NULL, xtstamp);
492}
493
494static inline bool is_link_time_supported(struct snd_pcm_runtime *runtime,
495 struct snd_pcm_audio_tstamp_config *ts)
496{
497 if (runtime->hw.info & SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME)
498 if (ts->type_requested == SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED)
499 return true;
500
501 return false;
502}
503
340static int azx_get_time_info(struct snd_pcm_substream *substream, 504static int azx_get_time_info(struct snd_pcm_substream *substream,
341 struct timespec *system_ts, struct timespec *audio_ts, 505 struct timespec *system_ts, struct timespec *audio_ts,
342 struct snd_pcm_audio_tstamp_config *audio_tstamp_config, 506 struct snd_pcm_audio_tstamp_config *audio_tstamp_config,
343 struct snd_pcm_audio_tstamp_report *audio_tstamp_report) 507 struct snd_pcm_audio_tstamp_report *audio_tstamp_report)
344{ 508{
345 struct azx_dev *azx_dev = get_azx_dev(substream); 509 struct azx_dev *azx_dev = get_azx_dev(substream);
510 struct snd_pcm_runtime *runtime = substream->runtime;
511 struct system_device_crosststamp xtstamp;
512 int ret;
346 u64 nsec; 513 u64 nsec;
347 514
348 if ((substream->runtime->hw.info & SNDRV_PCM_INFO_HAS_LINK_ATIME) && 515 if ((substream->runtime->hw.info & SNDRV_PCM_INFO_HAS_LINK_ATIME) &&
@@ -361,8 +528,37 @@ static int azx_get_time_info(struct snd_pcm_substream *substream,
361 audio_tstamp_report->accuracy_report = 1; /* rest of structure is valid */ 528 audio_tstamp_report->accuracy_report = 1; /* rest of structure is valid */
362 audio_tstamp_report->accuracy = 42; /* 24 MHz WallClock == 42ns resolution */ 529 audio_tstamp_report->accuracy = 42; /* 24 MHz WallClock == 42ns resolution */
363 530
364 } else 531 } else if (is_link_time_supported(runtime, audio_tstamp_config)) {
532
533 ret = azx_get_crosststamp(substream, &xtstamp);
534 if (ret)
535 return ret;
536
537 switch (runtime->tstamp_type) {
538 case SNDRV_PCM_TSTAMP_TYPE_MONOTONIC:
539 return -EINVAL;
540
541 case SNDRV_PCM_TSTAMP_TYPE_MONOTONIC_RAW:
542 *system_ts = ktime_to_timespec(xtstamp.sys_monoraw);
543 break;
544
545 default:
546 *system_ts = ktime_to_timespec(xtstamp.sys_realtime);
547 break;
548
549 }
550
551 *audio_ts = ktime_to_timespec(xtstamp.device);
552
553 audio_tstamp_report->actual_type =
554 SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED;
555 audio_tstamp_report->accuracy_report = 1;
556 /* 24 MHz WallClock == 42ns resolution */
557 audio_tstamp_report->accuracy = 42;
558
559 } else {
365 audio_tstamp_report->actual_type = SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT; 560 audio_tstamp_report->actual_type = SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT;
561 }
366 562
367 return 0; 563 return 0;
368} 564}
@@ -412,6 +608,11 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
412 goto unlock; 608 goto unlock;
413 } 609 }
414 runtime->private_data = azx_dev; 610 runtime->private_data = azx_dev;
611
612 if (chip->gts_present)
613 azx_pcm_hw.info = azx_pcm_hw.info |
614 SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME;
615
415 runtime->hw = azx_pcm_hw; 616 runtime->hw = azx_pcm_hw;
416 runtime->hw.channels_min = hinfo->channels_min; 617 runtime->hw.channels_min = hinfo->channels_min;
417 runtime->hw.channels_max = hinfo->channels_max; 618 runtime->hw.channels_max = hinfo->channels_max;
diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h
index ec63bbf1ec6d..a50e0532622a 100644
--- a/sound/pci/hda/hda_controller.h
+++ b/sound/pci/hda/hda_controller.h
@@ -159,6 +159,9 @@ struct azx {
159 unsigned int region_requested:1; 159 unsigned int region_requested:1;
160 unsigned int disabled:1; /* disabled by vga_switcheroo */ 160 unsigned int disabled:1; /* disabled by vga_switcheroo */
161 161
162 /* GTS present */
163 unsigned int gts_present:1;
164
162#ifdef CONFIG_SND_HDA_DSP_LOADER 165#ifdef CONFIG_SND_HDA_DSP_LOADER
163 struct azx_dev saved_azx_dev; 166 struct azx_dev saved_azx_dev;
164#endif 167#endif
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 160c7f713722..c3469f756ec2 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -54,6 +54,7 @@
54/* for snoop control */ 54/* for snoop control */
55#include <asm/pgtable.h> 55#include <asm/pgtable.h>
56#include <asm/cacheflush.h> 56#include <asm/cacheflush.h>
57#include <asm/cpufeature.h>
57#endif 58#endif
58#include <sound/core.h> 59#include <sound/core.h>
59#include <sound/initval.h> 60#include <sound/initval.h>
@@ -1663,6 +1664,22 @@ static int azx_first_init(struct azx *chip)
1663 return -ENXIO; 1664 return -ENXIO;
1664 } 1665 }
1665 1666
1667 if (IS_SKL_PLUS(pci))
1668 snd_hdac_bus_parse_capabilities(bus);
1669
1670 /*
1671 * Some Intel CPUs has always running timer (ART) feature and
1672 * controller may have Global time sync reporting capability, so
1673 * check both of these before declaring synchronized time reporting
1674 * capability SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME
1675 */
1676 chip->gts_present = false;
1677
1678#ifdef CONFIG_X86
1679 if (bus->ppcap && boot_cpu_has(X86_FEATURE_ART))
1680 chip->gts_present = true;
1681#endif
1682
1666 if (chip->msi) { 1683 if (chip->msi) {
1667 if (chip->driver_caps & AZX_DCAPS_NO_MSI64) { 1684 if (chip->driver_caps & AZX_DCAPS_NO_MSI64) {
1668 dev_dbg(card->dev, "Disabling 64bit MSI\n"); 1685 dev_dbg(card->dev, "Disabling 64bit MSI\n");
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index 09e8988bbb2d..b0f6f0712ba1 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -1870,6 +1870,9 @@ static int rt5640_set_dai_sysclk(struct snd_soc_dai *dai,
1870 case RT5640_SCLK_S_PLL1: 1870 case RT5640_SCLK_S_PLL1:
1871 reg_val |= RT5640_SCLK_SRC_PLL1; 1871 reg_val |= RT5640_SCLK_SRC_PLL1;
1872 break; 1872 break;
1873 case RT5640_SCLK_S_RCCLK:
1874 reg_val |= RT5640_SCLK_SRC_RCCLK;
1875 break;
1873 default: 1876 default:
1874 dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id); 1877 dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
1875 return -EINVAL; 1878 return -EINVAL;
diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h
index 58b664b06c16..90c88711c72a 100644
--- a/sound/soc/codecs/rt5640.h
+++ b/sound/soc/codecs/rt5640.h
@@ -984,6 +984,7 @@
984#define RT5640_SCLK_SRC_SFT 14 984#define RT5640_SCLK_SRC_SFT 14
985#define RT5640_SCLK_SRC_MCLK (0x0 << 14) 985#define RT5640_SCLK_SRC_MCLK (0x0 << 14)
986#define RT5640_SCLK_SRC_PLL1 (0x1 << 14) 986#define RT5640_SCLK_SRC_PLL1 (0x1 << 14)
987#define RT5640_SCLK_SRC_RCCLK (0x2 << 14)
987#define RT5640_PLL1_SRC_MASK (0x3 << 12) 988#define RT5640_PLL1_SRC_MASK (0x3 << 12)
988#define RT5640_PLL1_SRC_SFT 12 989#define RT5640_PLL1_SRC_SFT 12
989#define RT5640_PLL1_SRC_MCLK (0x0 << 12) 990#define RT5640_PLL1_SRC_MCLK (0x0 << 12)
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig
index a20c3dfbcb5d..26eb5a0a5575 100644
--- a/sound/soc/intel/Kconfig
+++ b/sound/soc/intel/Kconfig
@@ -25,6 +25,7 @@ config SND_SST_IPC_ACPI
25 tristate 25 tristate
26 select SND_SST_IPC 26 select SND_SST_IPC
27 select SND_SOC_INTEL_SST 27 select SND_SOC_INTEL_SST
28 select IOSF_MBI
28 29
29config SND_SOC_INTEL_SST 30config SND_SOC_INTEL_SST
30 tristate 31 tristate
@@ -120,6 +121,17 @@ config SND_SOC_INTEL_BYT_MAX98090_MACH
120 This adds audio driver for Intel Baytrail platform based boards 121 This adds audio driver for Intel Baytrail platform based boards
121 with the MAX98090 audio codec. 122 with the MAX98090 audio codec.
122 123
124config SND_SOC_INTEL_BDW_RT5677_MACH
125 tristate "ASoC Audio driver for Intel Broadwell with RT5677 codec"
126 depends on X86_INTEL_LPSS && GPIOLIB && I2C && DW_DMAC
127 depends on DW_DMAC_CORE=y
128 select SND_SOC_INTEL_SST
129 select SND_SOC_INTEL_HASWELL
130 select SND_SOC_RT5677
131 help
132 This adds support for Intel Broadwell platform based boards with
133 the RT5677 audio codec.
134
123config SND_SOC_INTEL_BROADWELL_MACH 135config SND_SOC_INTEL_BROADWELL_MACH
124 tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint" 136 tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint"
125 depends on X86_INTEL_LPSS && I2C && DW_DMAC && \ 137 depends on X86_INTEL_LPSS && I2C && DW_DMAC && \
diff --git a/sound/soc/intel/atom/sst-atom-controls.c b/sound/soc/intel/atom/sst-atom-controls.c
index 98720a93de8a..0838478c4c3f 100644
--- a/sound/soc/intel/atom/sst-atom-controls.c
+++ b/sound/soc/intel/atom/sst-atom-controls.c
@@ -1,4 +1,4 @@
1/* 1 /*
2 * sst-atom-controls.c - Intel MID Platform driver DPCM ALSA controls for Mrfld 2 * sst-atom-controls.c - Intel MID Platform driver DPCM ALSA controls for Mrfld
3 * 3 *
4 * Copyright (C) 2013-14 Intel Corp 4 * Copyright (C) 2013-14 Intel Corp
@@ -534,6 +534,7 @@ static const DECLARE_TLV_DB_SCALE(sst_gain_tlv_common, SST_GAIN_MIN_VALUE * 10,
534 534
535/* Look up table to convert MIXER SW bit regs to SWM inputs */ 535/* Look up table to convert MIXER SW bit regs to SWM inputs */
536static const uint swm_mixer_input_ids[SST_SWM_INPUT_COUNT] = { 536static const uint swm_mixer_input_ids[SST_SWM_INPUT_COUNT] = {
537 [SST_IP_MODEM] = SST_SWM_IN_MODEM,
537 [SST_IP_CODEC0] = SST_SWM_IN_CODEC0, 538 [SST_IP_CODEC0] = SST_SWM_IN_CODEC0,
538 [SST_IP_CODEC1] = SST_SWM_IN_CODEC1, 539 [SST_IP_CODEC1] = SST_SWM_IN_CODEC1,
539 [SST_IP_LOOP0] = SST_SWM_IN_SPROT_LOOP, 540 [SST_IP_LOOP0] = SST_SWM_IN_SPROT_LOOP,
@@ -674,6 +675,7 @@ static int sst_swm_mixer_event(struct snd_soc_dapm_widget *w,
674/* SBA mixers - 16 inputs */ 675/* SBA mixers - 16 inputs */
675#define SST_SBA_DECLARE_MIX_CONTROLS(kctl_name) \ 676#define SST_SBA_DECLARE_MIX_CONTROLS(kctl_name) \
676 static const struct snd_kcontrol_new kctl_name[] = { \ 677 static const struct snd_kcontrol_new kctl_name[] = { \
678 SOC_DAPM_SINGLE("modem_in Switch", SND_SOC_NOPM, SST_IP_MODEM, 1, 0), \
677 SOC_DAPM_SINGLE("codec_in0 Switch", SND_SOC_NOPM, SST_IP_CODEC0, 1, 0), \ 679 SOC_DAPM_SINGLE("codec_in0 Switch", SND_SOC_NOPM, SST_IP_CODEC0, 1, 0), \
678 SOC_DAPM_SINGLE("codec_in1 Switch", SND_SOC_NOPM, SST_IP_CODEC1, 1, 0), \ 680 SOC_DAPM_SINGLE("codec_in1 Switch", SND_SOC_NOPM, SST_IP_CODEC1, 1, 0), \
679 SOC_DAPM_SINGLE("sprot_loop_in Switch", SND_SOC_NOPM, SST_IP_LOOP0, 1, 0), \ 681 SOC_DAPM_SINGLE("sprot_loop_in Switch", SND_SOC_NOPM, SST_IP_LOOP0, 1, 0), \
@@ -684,6 +686,7 @@ static int sst_swm_mixer_event(struct snd_soc_dapm_widget *w,
684 } 686 }
685 687
686#define SST_SBA_MIXER_GRAPH_MAP(mix_name) \ 688#define SST_SBA_MIXER_GRAPH_MAP(mix_name) \
689 { mix_name, "modem_in Switch", "modem_in" }, \
687 { mix_name, "codec_in0 Switch", "codec_in0" }, \ 690 { mix_name, "codec_in0 Switch", "codec_in0" }, \
688 { mix_name, "codec_in1 Switch", "codec_in1" }, \ 691 { mix_name, "codec_in1 Switch", "codec_in1" }, \
689 { mix_name, "sprot_loop_in Switch", "sprot_loop_in" }, \ 692 { mix_name, "sprot_loop_in Switch", "sprot_loop_in" }, \
@@ -713,6 +716,7 @@ SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_media_l2_controls);
713SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_voip_controls); 716SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_voip_controls);
714SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_codec0_controls); 717SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_codec0_controls);
715SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_codec1_controls); 718SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_codec1_controls);
719SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_modem_controls);
716 720
717/* 721/*
718 * sst_handle_vb_timer - Start/Stop the DSP scheduler 722 * sst_handle_vb_timer - Start/Stop the DSP scheduler
@@ -931,17 +935,26 @@ void sst_fill_ssp_defaults(struct snd_soc_dai *dai)
931int send_ssp_cmd(struct snd_soc_dai *dai, const char *id, bool enable) 935int send_ssp_cmd(struct snd_soc_dai *dai, const char *id, bool enable)
932{ 936{
933 struct sst_data *drv = snd_soc_dai_get_drvdata(dai); 937 struct sst_data *drv = snd_soc_dai_get_drvdata(dai);
934 const struct sst_ssp_config *config; 938 int ssp_id;
935 939
936 dev_info(dai->dev, "Enter: enable=%d port_name=%s\n", enable, id); 940 dev_info(dai->dev, "Enter: enable=%d port_name=%s\n", enable, id);
937 941
942 if (strcmp(id, "ssp0-port") == 0)
943 ssp_id = SSP_MODEM;
944 else if (strcmp(id, "ssp2-port") == 0)
945 ssp_id = SSP_CODEC;
946 else {
947 dev_dbg(dai->dev, "port %s is not supported\n", id);
948 return -1;
949 }
950
938 SST_FILL_DEFAULT_DESTINATION(drv->ssp_cmd.header.dst); 951 SST_FILL_DEFAULT_DESTINATION(drv->ssp_cmd.header.dst);
939 drv->ssp_cmd.header.command_id = SBA_HW_SET_SSP; 952 drv->ssp_cmd.header.command_id = SBA_HW_SET_SSP;
940 drv->ssp_cmd.header.length = sizeof(struct sst_cmd_sba_hw_set_ssp) 953 drv->ssp_cmd.header.length = sizeof(struct sst_cmd_sba_hw_set_ssp)
941 - sizeof(struct sst_dsp_header); 954 - sizeof(struct sst_dsp_header);
942 955
943 config = &sst_ssp_configs; 956 drv->ssp_cmd.selection = ssp_id;
944 dev_dbg(dai->dev, "ssp_id: %u\n", config->ssp_id); 957 dev_dbg(dai->dev, "ssp_id: %u\n", ssp_id);
945 958
946 if (enable) 959 if (enable)
947 drv->ssp_cmd.switch_state = SST_SWITCH_ON; 960 drv->ssp_cmd.switch_state = SST_SWITCH_ON;
@@ -1047,8 +1060,10 @@ static int sst_set_media_loop(struct snd_soc_dapm_widget *w,
1047} 1060}
1048 1061
1049static const struct snd_soc_dapm_widget sst_dapm_widgets[] = { 1062static const struct snd_soc_dapm_widget sst_dapm_widgets[] = {
1063 SST_AIF_IN("modem_in", sst_set_be_modules),
1050 SST_AIF_IN("codec_in0", sst_set_be_modules), 1064 SST_AIF_IN("codec_in0", sst_set_be_modules),
1051 SST_AIF_IN("codec_in1", sst_set_be_modules), 1065 SST_AIF_IN("codec_in1", sst_set_be_modules),
1066 SST_AIF_OUT("modem_out", sst_set_be_modules),
1052 SST_AIF_OUT("codec_out0", sst_set_be_modules), 1067 SST_AIF_OUT("codec_out0", sst_set_be_modules),
1053 SST_AIF_OUT("codec_out1", sst_set_be_modules), 1068 SST_AIF_OUT("codec_out1", sst_set_be_modules),
1054 1069
@@ -1103,6 +1118,9 @@ static const struct snd_soc_dapm_widget sst_dapm_widgets[] = {
1103 sst_mix_codec0_controls, sst_swm_mixer_event), 1118 sst_mix_codec0_controls, sst_swm_mixer_event),
1104 SST_SWM_MIXER("codec_out1 mix 0", SND_SOC_NOPM, SST_TASK_SBA, SST_SWM_OUT_CODEC1, 1119 SST_SWM_MIXER("codec_out1 mix 0", SND_SOC_NOPM, SST_TASK_SBA, SST_SWM_OUT_CODEC1,
1105 sst_mix_codec1_controls, sst_swm_mixer_event), 1120 sst_mix_codec1_controls, sst_swm_mixer_event),
1121 SST_SWM_MIXER("modem_out mix 0", SND_SOC_NOPM, SST_TASK_SBA, SST_SWM_OUT_MODEM,
1122 sst_mix_modem_controls, sst_swm_mixer_event),
1123
1106}; 1124};
1107 1125
1108static const struct snd_soc_dapm_route intercon[] = { 1126static const struct snd_soc_dapm_route intercon[] = {
@@ -1148,6 +1166,9 @@ static const struct snd_soc_dapm_route intercon[] = {
1148 SST_SBA_MIXER_GRAPH_MAP("codec_out0 mix 0"), 1166 SST_SBA_MIXER_GRAPH_MAP("codec_out0 mix 0"),
1149 {"codec_out1", NULL, "codec_out1 mix 0"}, 1167 {"codec_out1", NULL, "codec_out1 mix 0"},
1150 SST_SBA_MIXER_GRAPH_MAP("codec_out1 mix 0"), 1168 SST_SBA_MIXER_GRAPH_MAP("codec_out1 mix 0"),
1169 {"modem_out", NULL, "modem_out mix 0"},
1170 SST_SBA_MIXER_GRAPH_MAP("modem_out mix 0"),
1171
1151 1172
1152}; 1173};
1153static const char * const slot_names[] = { 1174static const char * const slot_names[] = {
@@ -1217,6 +1238,9 @@ static const struct snd_kcontrol_new sst_gain_controls[] = {
1217 SST_GAIN("media_loop2_out", SST_PATH_INDEX_MEDIA_LOOP2_OUT, SST_TASK_SBA, 0, &sst_gains[13]), 1238 SST_GAIN("media_loop2_out", SST_PATH_INDEX_MEDIA_LOOP2_OUT, SST_TASK_SBA, 0, &sst_gains[13]),
1218 SST_GAIN("sprot_loop_out", SST_PATH_INDEX_SPROT_LOOP_OUT, SST_TASK_SBA, 0, &sst_gains[14]), 1239 SST_GAIN("sprot_loop_out", SST_PATH_INDEX_SPROT_LOOP_OUT, SST_TASK_SBA, 0, &sst_gains[14]),
1219 SST_VOLUME("media0_in", SST_PATH_INDEX_MEDIA0_IN, SST_TASK_MMX, 0, &sst_gains[15]), 1240 SST_VOLUME("media0_in", SST_PATH_INDEX_MEDIA0_IN, SST_TASK_MMX, 0, &sst_gains[15]),
1241 SST_GAIN("modem_in", SST_PATH_INDEX_MODEM_IN, SST_TASK_SBA, 0, &sst_gains[16]),
1242 SST_GAIN("modem_out", SST_PATH_INDEX_MODEM_OUT, SST_TASK_SBA, 0, &sst_gains[17]),
1243
1220}; 1244};
1221 1245
1222#define SST_GAIN_NUM_CONTROLS 3 1246#define SST_GAIN_NUM_CONTROLS 3
diff --git a/sound/soc/intel/atom/sst-atom-controls.h b/sound/soc/intel/atom/sst-atom-controls.h
index e0113112f668..351d81469685 100644
--- a/sound/soc/intel/atom/sst-atom-controls.h
+++ b/sound/soc/intel/atom/sst-atom-controls.h
@@ -35,6 +35,8 @@ enum {
35/* define a bit for each mixer input */ 35/* define a bit for each mixer input */
36#define SST_MIX_IP(x) (x) 36#define SST_MIX_IP(x) (x)
37 37
38#define SST_IP_MODEM SST_MIX_IP(0)
39#define SST_IP_BT SST_MIX_IP(1)
38#define SST_IP_CODEC0 SST_MIX_IP(2) 40#define SST_IP_CODEC0 SST_MIX_IP(2)
39#define SST_IP_CODEC1 SST_MIX_IP(3) 41#define SST_IP_CODEC1 SST_MIX_IP(3)
40#define SST_IP_LOOP0 SST_MIX_IP(4) 42#define SST_IP_LOOP0 SST_MIX_IP(4)
@@ -63,6 +65,7 @@ enum {
63 * Audio DSP Path Ids. Specified by the audio DSP FW 65 * Audio DSP Path Ids. Specified by the audio DSP FW
64 */ 66 */
65enum sst_path_index { 67enum sst_path_index {
68 SST_PATH_INDEX_MODEM_OUT = (0x00 << SST_PATH_ID_SHIFT),
66 SST_PATH_INDEX_CODEC_OUT0 = (0x02 << SST_PATH_ID_SHIFT), 69 SST_PATH_INDEX_CODEC_OUT0 = (0x02 << SST_PATH_ID_SHIFT),
67 SST_PATH_INDEX_CODEC_OUT1 = (0x03 << SST_PATH_ID_SHIFT), 70 SST_PATH_INDEX_CODEC_OUT1 = (0x03 << SST_PATH_ID_SHIFT),
68 71
@@ -80,6 +83,7 @@ enum sst_path_index {
80 83
81 84
82 /* Start of input paths */ 85 /* Start of input paths */
86 SST_PATH_INDEX_MODEM_IN = (0x80 << SST_PATH_ID_SHIFT),
83 SST_PATH_INDEX_CODEC_IN0 = (0x82 << SST_PATH_ID_SHIFT), 87 SST_PATH_INDEX_CODEC_IN0 = (0x82 << SST_PATH_ID_SHIFT),
84 SST_PATH_INDEX_CODEC_IN1 = (0x83 << SST_PATH_ID_SHIFT), 88 SST_PATH_INDEX_CODEC_IN1 = (0x83 << SST_PATH_ID_SHIFT),
85 89
@@ -105,6 +109,7 @@ enum sst_path_index {
105 * path IDs 109 * path IDs
106 */ 110 */
107enum sst_swm_inputs { 111enum sst_swm_inputs {
112 SST_SWM_IN_MODEM = (SST_PATH_INDEX_MODEM_IN | SST_DEFAULT_CELL_NBR),
108 SST_SWM_IN_CODEC0 = (SST_PATH_INDEX_CODEC_IN0 | SST_DEFAULT_CELL_NBR), 113 SST_SWM_IN_CODEC0 = (SST_PATH_INDEX_CODEC_IN0 | SST_DEFAULT_CELL_NBR),
109 SST_SWM_IN_CODEC1 = (SST_PATH_INDEX_CODEC_IN1 | SST_DEFAULT_CELL_NBR), 114 SST_SWM_IN_CODEC1 = (SST_PATH_INDEX_CODEC_IN1 | SST_DEFAULT_CELL_NBR),
110 SST_SWM_IN_SPROT_LOOP = (SST_PATH_INDEX_SPROT_LOOP_IN | SST_DEFAULT_CELL_NBR), 115 SST_SWM_IN_SPROT_LOOP = (SST_PATH_INDEX_SPROT_LOOP_IN | SST_DEFAULT_CELL_NBR),
@@ -124,6 +129,7 @@ enum sst_swm_inputs {
124 * path IDs 129 * path IDs
125 */ 130 */
126enum sst_swm_outputs { 131enum sst_swm_outputs {
132 SST_SWM_OUT_MODEM = (SST_PATH_INDEX_MODEM_OUT | SST_DEFAULT_CELL_NBR),
127 SST_SWM_OUT_CODEC0 = (SST_PATH_INDEX_CODEC_OUT0 | SST_DEFAULT_CELL_NBR), 133 SST_SWM_OUT_CODEC0 = (SST_PATH_INDEX_CODEC_OUT0 | SST_DEFAULT_CELL_NBR),
128 SST_SWM_OUT_CODEC1 = (SST_PATH_INDEX_CODEC_OUT1 | SST_DEFAULT_CELL_NBR), 134 SST_SWM_OUT_CODEC1 = (SST_PATH_INDEX_CODEC_OUT1 | SST_DEFAULT_CELL_NBR),
129 SST_SWM_OUT_SPROT_LOOP = (SST_PATH_INDEX_SPROT_LOOP_OUT | SST_DEFAULT_CELL_NBR), 135 SST_SWM_OUT_SPROT_LOOP = (SST_PATH_INDEX_SPROT_LOOP_OUT | SST_DEFAULT_CELL_NBR),
diff --git a/sound/soc/intel/atom/sst/sst.c b/sound/soc/intel/atom/sst/sst.c
index a4b458e77089..9b6e27385dc9 100644
--- a/sound/soc/intel/atom/sst/sst.c
+++ b/sound/soc/intel/atom/sst/sst.c
@@ -190,7 +190,8 @@ int sst_driver_ops(struct intel_sst_drv *sst)
190 190
191 default: 191 default:
192 dev_err(sst->dev, 192 dev_err(sst->dev,
193 "SST Driver capablities missing for dev_id: %x", sst->dev_id); 193 "SST Driver capabilities missing for dev_id: %x",
194 sst->dev_id);
194 return -EINVAL; 195 return -EINVAL;
195 }; 196 };
196} 197}
@@ -441,7 +442,7 @@ static int intel_sst_suspend(struct device *dev)
441 struct stream_info *stream = &ctx->streams[i]; 442 struct stream_info *stream = &ctx->streams[i];
442 443
443 if (stream->status == STREAM_RUNNING) { 444 if (stream->status == STREAM_RUNNING) {
444 dev_err(dev, "stream %d is running, cant susupend, abort\n", i); 445 dev_err(dev, "stream %d is running, can't suspend, abort\n", i);
445 return -EBUSY; 446 return -EBUSY;
446 } 447 }
447 } 448 }
diff --git a/sound/soc/intel/atom/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c
index 4d3184971227..ba5c0d71720a 100644
--- a/sound/soc/intel/atom/sst/sst_acpi.c
+++ b/sound/soc/intel/atom/sst/sst_acpi.c
@@ -39,6 +39,8 @@
39#include <acpi/platform/aclinux.h> 39#include <acpi/platform/aclinux.h>
40#include <acpi/actypes.h> 40#include <acpi/actypes.h>
41#include <acpi/acpi_bus.h> 41#include <acpi/acpi_bus.h>
42#include <asm/cpu_device_id.h>
43#include <asm/iosf_mbi.h>
42#include "../sst-mfld-platform.h" 44#include "../sst-mfld-platform.h"
43#include "../../common/sst-dsp.h" 45#include "../../common/sst-dsp.h"
44#include "../../common/sst-acpi.h" 46#include "../../common/sst-acpi.h"
@@ -113,6 +115,28 @@ static const struct sst_res_info byt_rvp_res_info = {
113 .acpi_ipc_irq_index = 5, 115 .acpi_ipc_irq_index = 5,
114}; 116};
115 117
118/* BYTCR has different BIOS from BYT */
119static const struct sst_res_info bytcr_res_info = {
120 .shim_offset = 0x140000,
121 .shim_size = 0x000100,
122 .shim_phy_addr = SST_BYT_SHIM_PHY_ADDR,
123 .ssp0_offset = 0xa0000,
124 .ssp0_size = 0x1000,
125 .dma0_offset = 0x98000,
126 .dma0_size = 0x4000,
127 .dma1_offset = 0x9c000,
128 .dma1_size = 0x4000,
129 .iram_offset = 0x0c0000,
130 .iram_size = 0x14000,
131 .dram_offset = 0x100000,
132 .dram_size = 0x28000,
133 .mbox_offset = 0x144000,
134 .mbox_size = 0x1000,
135 .acpi_lpe_res_index = 0,
136 .acpi_ddr_index = 2,
137 .acpi_ipc_irq_index = 0
138};
139
116static struct sst_platform_info byt_rvp_platform_data = { 140static struct sst_platform_info byt_rvp_platform_data = {
117 .probe_data = &byt_fwparse_info, 141 .probe_data = &byt_fwparse_info,
118 .ipc_info = &byt_ipc_info, 142 .ipc_info = &byt_ipc_info,
@@ -142,7 +166,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
142 rsrc = platform_get_resource(pdev, IORESOURCE_MEM, 166 rsrc = platform_get_resource(pdev, IORESOURCE_MEM,
143 ctx->pdata->res_info->acpi_lpe_res_index); 167 ctx->pdata->res_info->acpi_lpe_res_index);
144 if (!rsrc) { 168 if (!rsrc) {
145 dev_err(ctx->dev, "Invalid SHIM base from IFWI"); 169 dev_err(ctx->dev, "Invalid SHIM base from IFWI\n");
146 return -EIO; 170 return -EIO;
147 } 171 }
148 dev_info(ctx->dev, "LPE base: %#x size:%#x", (unsigned int) rsrc->start, 172 dev_info(ctx->dev, "LPE base: %#x size:%#x", (unsigned int) rsrc->start,
@@ -154,7 +178,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
154 ctx->iram = devm_ioremap_nocache(ctx->dev, ctx->iram_base, 178 ctx->iram = devm_ioremap_nocache(ctx->dev, ctx->iram_base,
155 ctx->pdata->res_info->iram_size); 179 ctx->pdata->res_info->iram_size);
156 if (!ctx->iram) { 180 if (!ctx->iram) {
157 dev_err(ctx->dev, "unable to map IRAM"); 181 dev_err(ctx->dev, "unable to map IRAM\n");
158 return -EIO; 182 return -EIO;
159 } 183 }
160 184
@@ -164,7 +188,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
164 ctx->dram = devm_ioremap_nocache(ctx->dev, ctx->dram_base, 188 ctx->dram = devm_ioremap_nocache(ctx->dev, ctx->dram_base,
165 ctx->pdata->res_info->dram_size); 189 ctx->pdata->res_info->dram_size);
166 if (!ctx->dram) { 190 if (!ctx->dram) {
167 dev_err(ctx->dev, "unable to map DRAM"); 191 dev_err(ctx->dev, "unable to map DRAM\n");
168 return -EIO; 192 return -EIO;
169 } 193 }
170 194
@@ -173,7 +197,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
173 ctx->shim = devm_ioremap_nocache(ctx->dev, ctx->shim_phy_add, 197 ctx->shim = devm_ioremap_nocache(ctx->dev, ctx->shim_phy_add,
174 ctx->pdata->res_info->shim_size); 198 ctx->pdata->res_info->shim_size);
175 if (!ctx->shim) { 199 if (!ctx->shim) {
176 dev_err(ctx->dev, "unable to map SHIM"); 200 dev_err(ctx->dev, "unable to map SHIM\n");
177 return -EIO; 201 return -EIO;
178 } 202 }
179 203
@@ -186,7 +210,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
186 ctx->mailbox = devm_ioremap_nocache(ctx->dev, ctx->mailbox_add, 210 ctx->mailbox = devm_ioremap_nocache(ctx->dev, ctx->mailbox_add,
187 ctx->pdata->res_info->mbox_size); 211 ctx->pdata->res_info->mbox_size);
188 if (!ctx->mailbox) { 212 if (!ctx->mailbox) {
189 dev_err(ctx->dev, "unable to map mailbox"); 213 dev_err(ctx->dev, "unable to map mailbox\n");
190 return -EIO; 214 return -EIO;
191 } 215 }
192 216
@@ -196,7 +220,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
196 rsrc = platform_get_resource(pdev, IORESOURCE_MEM, 220 rsrc = platform_get_resource(pdev, IORESOURCE_MEM,
197 ctx->pdata->res_info->acpi_ddr_index); 221 ctx->pdata->res_info->acpi_ddr_index);
198 if (!rsrc) { 222 if (!rsrc) {
199 dev_err(ctx->dev, "Invalid DDR base from IFWI"); 223 dev_err(ctx->dev, "Invalid DDR base from IFWI\n");
200 return -EIO; 224 return -EIO;
201 } 225 }
202 ctx->ddr_base = rsrc->start; 226 ctx->ddr_base = rsrc->start;
@@ -205,7 +229,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
205 ctx->ddr = devm_ioremap_nocache(ctx->dev, ctx->ddr_base, 229 ctx->ddr = devm_ioremap_nocache(ctx->dev, ctx->ddr_base,
206 resource_size(rsrc)); 230 resource_size(rsrc));
207 if (!ctx->ddr) { 231 if (!ctx->ddr) {
208 dev_err(ctx->dev, "unable to map DDR"); 232 dev_err(ctx->dev, "unable to map DDR\n");
209 return -EIO; 233 return -EIO;
210 } 234 }
211 235
@@ -215,6 +239,46 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
215 return 0; 239 return 0;
216} 240}
217 241
242
243static int is_byt_cr(struct device *dev, bool *bytcr)
244{
245 int status = 0;
246
247 if (IS_ENABLED(CONFIG_IOSF_MBI)) {
248 static const struct x86_cpu_id cpu_ids[] = {
249 { X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */
250 {}
251 };
252 u32 bios_status;
253
254 if (!x86_match_cpu(cpu_ids) || !iosf_mbi_available()) {
255 /* bail silently */
256 return status;
257 }
258
259 status = iosf_mbi_read(BT_MBI_UNIT_PMC, /* 0x04 PUNIT */
260 MBI_REG_READ, /* 0x10 */
261 0x006, /* BIOS_CONFIG */
262 &bios_status);
263
264 if (status) {
265 dev_err(dev, "could not read PUNIT BIOS_CONFIG\n");
266 } else {
267 /* bits 26:27 mirror PMIC options */
268 bios_status = (bios_status >> 26) & 3;
269
270 if ((bios_status == 1) || (bios_status == 3))
271 *bytcr = true;
272 else
273 dev_info(dev, "BYT-CR not detected\n");
274 }
275 } else {
276 dev_info(dev, "IOSF_MBI not enabled, no BYT-CR detection\n");
277 }
278 return status;
279}
280
281
218static int sst_acpi_probe(struct platform_device *pdev) 282static int sst_acpi_probe(struct platform_device *pdev)
219{ 283{
220 struct device *dev = &pdev->dev; 284 struct device *dev = &pdev->dev;
@@ -226,11 +290,12 @@ static int sst_acpi_probe(struct platform_device *pdev)
226 struct platform_device *plat_dev; 290 struct platform_device *plat_dev;
227 struct sst_platform_info *pdata; 291 struct sst_platform_info *pdata;
228 unsigned int dev_id; 292 unsigned int dev_id;
293 bool bytcr = false;
229 294
230 id = acpi_match_device(dev->driver->acpi_match_table, dev); 295 id = acpi_match_device(dev->driver->acpi_match_table, dev);
231 if (!id) 296 if (!id)
232 return -ENODEV; 297 return -ENODEV;
233 dev_dbg(dev, "for %s", id->id); 298 dev_dbg(dev, "for %s\n", id->id);
234 299
235 mach = (struct sst_acpi_mach *)id->driver_data; 300 mach = (struct sst_acpi_mach *)id->driver_data;
236 mach = sst_acpi_find_machine(mach); 301 mach = sst_acpi_find_machine(mach);
@@ -251,6 +316,18 @@ static int sst_acpi_probe(struct platform_device *pdev)
251 316
252 dev_dbg(dev, "ACPI device id: %x\n", dev_id); 317 dev_dbg(dev, "ACPI device id: %x\n", dev_id);
253 318
319 ret = sst_alloc_drv_context(&ctx, dev, dev_id);
320 if (ret < 0)
321 return ret;
322
323 ret = is_byt_cr(dev, &bytcr);
324 if (!((ret < 0) || (bytcr == false))) {
325 dev_info(dev, "Detected Baytrail-CR platform\n");
326
327 /* override resource info */
328 byt_rvp_platform_data.res_info = &bytcr_res_info;
329 }
330
254 plat_dev = platform_device_register_data(dev, pdata->platform, -1, 331 plat_dev = platform_device_register_data(dev, pdata->platform, -1,
255 NULL, 0); 332 NULL, 0);
256 if (IS_ERR(plat_dev)) { 333 if (IS_ERR(plat_dev)) {
@@ -271,10 +348,6 @@ static int sst_acpi_probe(struct platform_device *pdev)
271 return PTR_ERR(mdev); 348 return PTR_ERR(mdev);
272 } 349 }
273 350
274 ret = sst_alloc_drv_context(&ctx, dev, dev_id);
275 if (ret < 0)
276 return ret;
277
278 /* Fill sst platform data */ 351 /* Fill sst platform data */
279 ctx->pdata = pdata; 352 ctx->pdata = pdata;
280 strcpy(ctx->firmware_name, mach->fw_filename); 353 strcpy(ctx->firmware_name, mach->fw_filename);
diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile
index dac03a06bfd8..5639f10774e6 100644
--- a/sound/soc/intel/boards/Makefile
+++ b/sound/soc/intel/boards/Makefile
@@ -1,6 +1,7 @@
1snd-soc-sst-haswell-objs := haswell.o 1snd-soc-sst-haswell-objs := haswell.o
2snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o 2snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o
3snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o 3snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o
4snd-soc-sst-bdw-rt5677-mach-objs := bdw-rt5677.o
4snd-soc-sst-broadwell-objs := broadwell.o 5snd-soc-sst-broadwell-objs := broadwell.o
5snd-soc-sst-bxt-da7219_max98357a-objs := bxt_da7219_max98357a.o 6snd-soc-sst-bxt-da7219_max98357a-objs := bxt_da7219_max98357a.o
6snd-soc-sst-bxt-rt298-objs := bxt_rt298.o 7snd-soc-sst-bxt-rt298-objs := bxt_rt298.o
@@ -19,6 +20,7 @@ obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o
19obj-$(CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH) += snd-soc-sst-bxt-da7219_max98357a.o 20obj-$(CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH) += snd-soc-sst-bxt-da7219_max98357a.o
20obj-$(CONFIG_SND_SOC_INTEL_BXT_RT298_MACH) += snd-soc-sst-bxt-rt298.o 21obj-$(CONFIG_SND_SOC_INTEL_BXT_RT298_MACH) += snd-soc-sst-bxt-rt298.o
21obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o 22obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o
23obj-$(CONFIG_SND_SOC_INTEL_BDW_RT5677_MACH) += snd-soc-sst-bdw-rt5677-mach.o
22obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-rt5640.o 24obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-rt5640.o
23obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH) += snd-soc-sst-bytcr-rt5651.o 25obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH) += snd-soc-sst-bytcr-rt5651.o
24obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o 26obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o
diff --git a/sound/soc/intel/boards/bdw-rt5677.c b/sound/soc/intel/boards/bdw-rt5677.c
new file mode 100644
index 000000000000..547e6705bf6d
--- /dev/null
+++ b/sound/soc/intel/boards/bdw-rt5677.c
@@ -0,0 +1,347 @@
1/*
2 * ASoC machine driver for Intel Broadwell platforms with RT5677 codec
3 *
4 * Copyright (c) 2014, The Chromium OS Authors. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <linux/gpio/consumer.h>
22#include <linux/delay.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/soc.h>
26#include <sound/pcm_params.h>
27#include <sound/jack.h>
28
29#include "../common/sst-dsp.h"
30#include "../haswell/sst-haswell-ipc.h"
31
32#include "../../codecs/rt5677.h"
33
34struct bdw_rt5677_priv {
35 struct gpio_desc *gpio_hp_en;
36 struct snd_soc_codec *codec;
37};
38
39static int bdw_rt5677_event_hp(struct snd_soc_dapm_widget *w,
40 struct snd_kcontrol *k, int event)
41{
42 struct snd_soc_dapm_context *dapm = w->dapm;
43 struct snd_soc_card *card = dapm->card;
44 struct bdw_rt5677_priv *bdw_rt5677 = snd_soc_card_get_drvdata(card);
45
46 if (SND_SOC_DAPM_EVENT_ON(event))
47 msleep(70);
48
49 gpiod_set_value_cansleep(bdw_rt5677->gpio_hp_en,
50 SND_SOC_DAPM_EVENT_ON(event));
51
52 return 0;
53}
54
55static const struct snd_soc_dapm_widget bdw_rt5677_widgets[] = {
56 SND_SOC_DAPM_HP("Headphone", bdw_rt5677_event_hp),
57 SND_SOC_DAPM_SPK("Speaker", NULL),
58 SND_SOC_DAPM_MIC("Headset Mic", NULL),
59 SND_SOC_DAPM_MIC("Local DMICs", NULL),
60 SND_SOC_DAPM_MIC("Remote DMICs", NULL),
61};
62
63static const struct snd_soc_dapm_route bdw_rt5677_map[] = {
64 /* Speakers */
65 {"Speaker", NULL, "PDM1L"},
66 {"Speaker", NULL, "PDM1R"},
67
68 /* Headset jack connectors */
69 {"Headphone", NULL, "LOUT1"},
70 {"Headphone", NULL, "LOUT2"},
71 {"IN1P", NULL, "Headset Mic"},
72 {"IN1N", NULL, "Headset Mic"},
73
74 /* Digital MICs
75 * Local DMICs: the two DMICs on the mainboard
76 * Remote DMICs: the two DMICs on the camera module
77 */
78 {"DMIC L1", NULL, "Remote DMICs"},
79 {"DMIC R1", NULL, "Remote DMICs"},
80 {"DMIC L2", NULL, "Local DMICs"},
81 {"DMIC R2", NULL, "Local DMICs"},
82
83 /* CODEC BE connections */
84 {"SSP0 CODEC IN", NULL, "AIF1 Capture"},
85 {"AIF1 Playback", NULL, "SSP0 CODEC OUT"},
86};
87
88static const struct snd_kcontrol_new bdw_rt5677_controls[] = {
89 SOC_DAPM_PIN_SWITCH("Speaker"),
90 SOC_DAPM_PIN_SWITCH("Headphone"),
91 SOC_DAPM_PIN_SWITCH("Headset Mic"),
92 SOC_DAPM_PIN_SWITCH("Local DMICs"),
93 SOC_DAPM_PIN_SWITCH("Remote DMICs"),
94};
95
96
97static struct snd_soc_jack headphone_jack;
98static struct snd_soc_jack mic_jack;
99
100static struct snd_soc_jack_pin headphone_jack_pin = {
101 .pin = "Headphone",
102 .mask = SND_JACK_HEADPHONE,
103};
104
105static struct snd_soc_jack_pin mic_jack_pin = {
106 .pin = "Headset Mic",
107 .mask = SND_JACK_MICROPHONE,
108};
109
110static struct snd_soc_jack_gpio headphone_jack_gpio = {
111 .name = "plug-det",
112 .report = SND_JACK_HEADPHONE,
113 .debounce_time = 200,
114};
115
116static struct snd_soc_jack_gpio mic_jack_gpio = {
117 .name = "mic-present",
118 .report = SND_JACK_MICROPHONE,
119 .debounce_time = 200,
120 .invert = 1,
121};
122
123static int broadwell_ssp0_fixup(struct snd_soc_pcm_runtime *rtd,
124 struct snd_pcm_hw_params *params)
125{
126 struct snd_interval *rate = hw_param_interval(params,
127 SNDRV_PCM_HW_PARAM_RATE);
128 struct snd_interval *channels = hw_param_interval(params,
129 SNDRV_PCM_HW_PARAM_CHANNELS);
130
131 /* The ADSP will covert the FE rate to 48k, stereo */
132 rate->min = rate->max = 48000;
133 channels->min = channels->max = 2;
134
135 /* set SSP0 to 16 bit */
136 snd_mask_set(&params->masks[SNDRV_PCM_HW_PARAM_FORMAT -
137 SNDRV_PCM_HW_PARAM_FIRST_MASK],
138 SNDRV_PCM_FORMAT_S16_LE);
139 return 0;
140}
141
142static int bdw_rt5677_hw_params(struct snd_pcm_substream *substream,
143 struct snd_pcm_hw_params *params)
144{
145 struct snd_soc_pcm_runtime *rtd = substream->private_data;
146 struct snd_soc_dai *codec_dai = rtd->codec_dai;
147 int ret;
148
149 ret = snd_soc_dai_set_sysclk(codec_dai, RT5677_SCLK_S_MCLK, 24576000,
150 SND_SOC_CLOCK_IN);
151 if (ret < 0) {
152 dev_err(rtd->dev, "can't set codec sysclk configuration\n");
153 return ret;
154 }
155
156 return ret;
157}
158
159static struct snd_soc_ops bdw_rt5677_ops = {
160 .hw_params = bdw_rt5677_hw_params,
161};
162
163static int bdw_rt5677_rtd_init(struct snd_soc_pcm_runtime *rtd)
164{
165 struct sst_pdata *pdata = dev_get_platdata(rtd->platform->dev);
166 struct sst_hsw *broadwell = pdata->dsp;
167 int ret;
168
169 /* Set ADSP SSP port settings */
170 ret = sst_hsw_device_set_config(broadwell, SST_HSW_DEVICE_SSP_0,
171 SST_HSW_DEVICE_MCLK_FREQ_24_MHZ,
172 SST_HSW_DEVICE_CLOCK_MASTER, 9);
173 if (ret < 0) {
174 dev_err(rtd->dev, "error: failed to set device config\n");
175 return ret;
176 }
177
178 return 0;
179}
180
181static int bdw_rt5677_init(struct snd_soc_pcm_runtime *rtd)
182{
183 struct bdw_rt5677_priv *bdw_rt5677 =
184 snd_soc_card_get_drvdata(rtd->card);
185 struct snd_soc_codec *codec = rtd->codec;
186 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
187
188 /* Enable codec ASRC function for Stereo DAC/Stereo1 ADC/DMIC/I2S1.
189 * The ASRC clock source is clk_i2s1_asrc.
190 */
191 rt5677_sel_asrc_clk_src(codec, RT5677_DA_STEREO_FILTER |
192 RT5677_AD_STEREO1_FILTER | RT5677_I2S1_SOURCE,
193 RT5677_CLK_SEL_I2S1_ASRC);
194
195 /* Request rt5677 GPIO for headphone amp control */
196 bdw_rt5677->gpio_hp_en = devm_gpiod_get_index(codec->dev,
197 "headphone-enable", 0, 0);
198 if (IS_ERR(bdw_rt5677->gpio_hp_en)) {
199 dev_err(codec->dev, "Can't find HP_AMP_SHDN_L gpio\n");
200 return PTR_ERR(bdw_rt5677->gpio_hp_en);
201 }
202 gpiod_direction_output(bdw_rt5677->gpio_hp_en, 0);
203
204 /* Create and initialize headphone jack */
205 if (!snd_soc_card_jack_new(rtd->card, "Headphone Jack",
206 SND_JACK_HEADPHONE, &headphone_jack,
207 &headphone_jack_pin, 1)) {
208 headphone_jack_gpio.gpiod_dev = codec->dev;
209 if (snd_soc_jack_add_gpios(&headphone_jack, 1,
210 &headphone_jack_gpio))
211 dev_err(codec->dev, "Can't add headphone jack gpio\n");
212 } else {
213 dev_err(codec->dev, "Can't create headphone jack\n");
214 }
215
216 /* Create and initialize mic jack */
217 if (!snd_soc_card_jack_new(rtd->card, "Mic Jack",
218 SND_JACK_MICROPHONE, &mic_jack,
219 &mic_jack_pin, 1)) {
220 mic_jack_gpio.gpiod_dev = codec->dev;
221 if (snd_soc_jack_add_gpios(&mic_jack, 1, &mic_jack_gpio))
222 dev_err(codec->dev, "Can't add mic jack gpio\n");
223 } else {
224 dev_err(codec->dev, "Can't create mic jack\n");
225 }
226 bdw_rt5677->codec = codec;
227
228 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
229 return 0;
230}
231
232/* broadwell digital audio interface glue - connects codec <--> CPU */
233static struct snd_soc_dai_link bdw_rt5677_dais[] = {
234 /* Front End DAI links */
235 {
236 .name = "System PCM",
237 .stream_name = "System Playback/Capture",
238 .cpu_dai_name = "System Pin",
239 .platform_name = "haswell-pcm-audio",
240 .dynamic = 1,
241 .codec_name = "snd-soc-dummy",
242 .codec_dai_name = "snd-soc-dummy-dai",
243 .init = bdw_rt5677_rtd_init,
244 .trigger = {
245 SND_SOC_DPCM_TRIGGER_POST,
246 SND_SOC_DPCM_TRIGGER_POST
247 },
248 .dpcm_capture = 1,
249 .dpcm_playback = 1,
250 },
251
252 /* Back End DAI links */
253 {
254 /* SSP0 - Codec */
255 .name = "Codec",
256 .id = 0,
257 .cpu_dai_name = "snd-soc-dummy-dai",
258 .platform_name = "snd-soc-dummy",
259 .no_pcm = 1,
260 .codec_name = "i2c-RT5677CE:00",
261 .codec_dai_name = "rt5677-aif1",
262 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
263 SND_SOC_DAIFMT_CBS_CFS,
264 .ignore_suspend = 1,
265 .ignore_pmdown_time = 1,
266 .be_hw_params_fixup = broadwell_ssp0_fixup,
267 .ops = &bdw_rt5677_ops,
268 .dpcm_playback = 1,
269 .dpcm_capture = 1,
270 .init = bdw_rt5677_init,
271 },
272};
273
274static int bdw_rt5677_suspend_pre(struct snd_soc_card *card)
275{
276 struct bdw_rt5677_priv *bdw_rt5677 = snd_soc_card_get_drvdata(card);
277 struct snd_soc_dapm_context *dapm;
278
279 if (bdw_rt5677->codec) {
280 dapm = snd_soc_codec_get_dapm(bdw_rt5677->codec);
281 snd_soc_dapm_disable_pin(dapm, "MICBIAS1");
282 }
283 return 0;
284}
285
286static int bdw_rt5677_resume_post(struct snd_soc_card *card)
287{
288 struct bdw_rt5677_priv *bdw_rt5677 = snd_soc_card_get_drvdata(card);
289 struct snd_soc_dapm_context *dapm;
290
291 if (bdw_rt5677->codec) {
292 dapm = snd_soc_codec_get_dapm(bdw_rt5677->codec);
293 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
294 }
295 return 0;
296}
297
298/* ASoC machine driver for Broadwell DSP + RT5677 */
299static struct snd_soc_card bdw_rt5677_card = {
300 .name = "bdw-rt5677",
301 .owner = THIS_MODULE,
302 .dai_link = bdw_rt5677_dais,
303 .num_links = ARRAY_SIZE(bdw_rt5677_dais),
304 .dapm_widgets = bdw_rt5677_widgets,
305 .num_dapm_widgets = ARRAY_SIZE(bdw_rt5677_widgets),
306 .dapm_routes = bdw_rt5677_map,
307 .num_dapm_routes = ARRAY_SIZE(bdw_rt5677_map),
308 .controls = bdw_rt5677_controls,
309 .num_controls = ARRAY_SIZE(bdw_rt5677_controls),
310 .fully_routed = true,
311 .suspend_pre = bdw_rt5677_suspend_pre,
312 .resume_post = bdw_rt5677_resume_post,
313};
314
315static int bdw_rt5677_probe(struct platform_device *pdev)
316{
317 struct bdw_rt5677_priv *bdw_rt5677;
318
319 bdw_rt5677_card.dev = &pdev->dev;
320
321 /* Allocate driver private struct */
322 bdw_rt5677 = devm_kzalloc(&pdev->dev, sizeof(struct bdw_rt5677_priv),
323 GFP_KERNEL);
324 if (!bdw_rt5677) {
325 dev_err(&pdev->dev, "Can't allocate bdw_rt5677\n");
326 return -ENOMEM;
327 }
328
329 snd_soc_card_set_drvdata(&bdw_rt5677_card, bdw_rt5677);
330
331 return devm_snd_soc_register_card(&pdev->dev, &bdw_rt5677_card);
332}
333
334static struct platform_driver bdw_rt5677_audio = {
335 .probe = bdw_rt5677_probe,
336 .driver = {
337 .name = "bdw-rt5677",
338 },
339};
340
341module_platform_driver(bdw_rt5677_audio)
342
343/* Module information */
344MODULE_AUTHOR("Ben Zhang");
345MODULE_DESCRIPTION("Intel Broadwell RT5677 machine driver");
346MODULE_LICENSE("GPL v2");
347MODULE_ALIAS("platform:bdw-rt5677");
diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c
index 3774b117d365..6532b8f0ab2f 100644
--- a/sound/soc/intel/boards/bxt_da7219_max98357a.c
+++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c
@@ -37,6 +37,7 @@ enum {
37 BXT_DPCM_AUDIO_PB = 0, 37 BXT_DPCM_AUDIO_PB = 0,
38 BXT_DPCM_AUDIO_CP, 38 BXT_DPCM_AUDIO_CP,
39 BXT_DPCM_AUDIO_REF_CP, 39 BXT_DPCM_AUDIO_REF_CP,
40 BXT_DPCM_AUDIO_DMIC_CP,
40 BXT_DPCM_AUDIO_HDMI1_PB, 41 BXT_DPCM_AUDIO_HDMI1_PB,
41 BXT_DPCM_AUDIO_HDMI2_PB, 42 BXT_DPCM_AUDIO_HDMI2_PB,
42 BXT_DPCM_AUDIO_HDMI3_PB, 43 BXT_DPCM_AUDIO_HDMI3_PB,
@@ -252,10 +253,56 @@ static struct snd_soc_ops broxton_da7219_ops = {
252 .hw_free = broxton_da7219_hw_free, 253 .hw_free = broxton_da7219_hw_free,
253}; 254};
254 255
256static int broxton_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
257 struct snd_pcm_hw_params *params)
258{
259 struct snd_interval *channels = hw_param_interval(params,
260 SNDRV_PCM_HW_PARAM_CHANNELS);
261 channels->min = channels->max = DUAL_CHANNEL;
262
263 return 0;
264}
265
266static int broxton_dmic_startup(struct snd_pcm_substream *substream)
267{
268 struct snd_pcm_runtime *runtime = substream->runtime;
269
270 runtime->hw.channels_max = DUAL_CHANNEL;
271 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
272 &constraints_channels);
273
274 return snd_pcm_hw_constraint_list(substream->runtime, 0,
275 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
276}
277
278static const struct snd_soc_ops broxton_dmic_ops = {
279 .startup = broxton_dmic_startup,
280};
281
282static const unsigned int rates_16000[] = {
283 16000,
284};
285
286static const struct snd_pcm_hw_constraint_list constraints_16000 = {
287 .count = ARRAY_SIZE(rates_16000),
288 .list = rates_16000,
289};
290
291static int broxton_refcap_startup(struct snd_pcm_substream *substream)
292{
293 return snd_pcm_hw_constraint_list(substream->runtime, 0,
294 SNDRV_PCM_HW_PARAM_RATE,
295 &constraints_16000);
296};
297
298static struct snd_soc_ops broxton_refcap_ops = {
299 .startup = broxton_refcap_startup,
300};
301
255/* broxton digital audio interface glue - connects codec <--> CPU */ 302/* broxton digital audio interface glue - connects codec <--> CPU */
256static struct snd_soc_dai_link broxton_dais[] = { 303static struct snd_soc_dai_link broxton_dais[] = {
257 /* Front End DAI links */ 304 /* Front End DAI links */
258 [BXT_DPCM_AUDIO_PB] 305 [BXT_DPCM_AUDIO_PB] =
259 { 306 {
260 .name = "Bxt Audio Port", 307 .name = "Bxt Audio Port",
261 .stream_name = "Audio", 308 .stream_name = "Audio",
@@ -271,7 +318,7 @@ static struct snd_soc_dai_link broxton_dais[] = {
271 .dpcm_playback = 1, 318 .dpcm_playback = 1,
272 .ops = &broxton_da7219_fe_ops, 319 .ops = &broxton_da7219_fe_ops,
273 }, 320 },
274 [BXT_DPCM_AUDIO_CP] 321 [BXT_DPCM_AUDIO_CP] =
275 { 322 {
276 .name = "Bxt Audio Capture Port", 323 .name = "Bxt Audio Capture Port",
277 .stream_name = "Audio Record", 324 .stream_name = "Audio Record",
@@ -286,7 +333,7 @@ static struct snd_soc_dai_link broxton_dais[] = {
286 .dpcm_capture = 1, 333 .dpcm_capture = 1,
287 .ops = &broxton_da7219_fe_ops, 334 .ops = &broxton_da7219_fe_ops,
288 }, 335 },
289 [BXT_DPCM_AUDIO_REF_CP] 336 [BXT_DPCM_AUDIO_REF_CP] =
290 { 337 {
291 .name = "Bxt Audio Reference cap", 338 .name = "Bxt Audio Reference cap",
292 .stream_name = "Refcap", 339 .stream_name = "Refcap",
@@ -299,8 +346,23 @@ static struct snd_soc_dai_link broxton_dais[] = {
299 .ignore_suspend = 1, 346 .ignore_suspend = 1,
300 .nonatomic = 1, 347 .nonatomic = 1,
301 .dynamic = 1, 348 .dynamic = 1,
349 .ops = &broxton_refcap_ops,
350 },
351 [BXT_DPCM_AUDIO_DMIC_CP]
352 {
353 .name = "Bxt Audio DMIC cap",
354 .stream_name = "dmiccap",
355 .cpu_dai_name = "DMIC Pin",
356 .codec_name = "snd-soc-dummy",
357 .codec_dai_name = "snd-soc-dummy-dai",
358 .platform_name = "0000:00:0e.0",
359 .init = NULL,
360 .dpcm_capture = 1,
361 .nonatomic = 1,
362 .dynamic = 1,
363 .ops = &broxton_dmic_ops,
302 }, 364 },
303 [BXT_DPCM_AUDIO_HDMI1_PB] 365 [BXT_DPCM_AUDIO_HDMI1_PB] =
304 { 366 {
305 .name = "Bxt HDMI Port1", 367 .name = "Bxt HDMI Port1",
306 .stream_name = "Hdmi1", 368 .stream_name = "Hdmi1",
@@ -313,7 +375,7 @@ static struct snd_soc_dai_link broxton_dais[] = {
313 .nonatomic = 1, 375 .nonatomic = 1,
314 .dynamic = 1, 376 .dynamic = 1,
315 }, 377 },
316 [BXT_DPCM_AUDIO_HDMI2_PB] 378 [BXT_DPCM_AUDIO_HDMI2_PB] =
317 { 379 {
318 .name = "Bxt HDMI Port2", 380 .name = "Bxt HDMI Port2",
319 .stream_name = "Hdmi2", 381 .stream_name = "Hdmi2",
@@ -326,7 +388,7 @@ static struct snd_soc_dai_link broxton_dais[] = {
326 .nonatomic = 1, 388 .nonatomic = 1,
327 .dynamic = 1, 389 .dynamic = 1,
328 }, 390 },
329 [BXT_DPCM_AUDIO_HDMI3_PB] 391 [BXT_DPCM_AUDIO_HDMI3_PB] =
330 { 392 {
331 .name = "Bxt HDMI Port3", 393 .name = "Bxt HDMI Port3",
332 .stream_name = "Hdmi3", 394 .stream_name = "Hdmi3",
@@ -382,6 +444,7 @@ static struct snd_soc_dai_link broxton_dais[] = {
382 .codec_dai_name = "dmic-hifi", 444 .codec_dai_name = "dmic-hifi",
383 .platform_name = "0000:00:0e.0", 445 .platform_name = "0000:00:0e.0",
384 .ignore_suspend = 1, 446 .ignore_suspend = 1,
447 .be_hw_params_fixup = broxton_dmic_fixup,
385 .dpcm_capture = 1, 448 .dpcm_capture = 1,
386 .no_pcm = 1, 449 .no_pcm = 1,
387 }, 450 },
diff --git a/sound/soc/intel/boards/bxt_rt298.c b/sound/soc/intel/boards/bxt_rt298.c
index 253d7bfbf511..d610bdca1608 100644
--- a/sound/soc/intel/boards/bxt_rt298.c
+++ b/sound/soc/intel/boards/bxt_rt298.c
@@ -271,7 +271,7 @@ static const struct snd_soc_ops broxton_rt286_fe_ops = {
271/* broxton digital audio interface glue - connects codec <--> CPU */ 271/* broxton digital audio interface glue - connects codec <--> CPU */
272static struct snd_soc_dai_link broxton_rt298_dais[] = { 272static struct snd_soc_dai_link broxton_rt298_dais[] = {
273 /* Front End DAI links */ 273 /* Front End DAI links */
274 [BXT_DPCM_AUDIO_PB] 274 [BXT_DPCM_AUDIO_PB] =
275 { 275 {
276 .name = "Bxt Audio Port", 276 .name = "Bxt Audio Port",
277 .stream_name = "Audio", 277 .stream_name = "Audio",
@@ -286,7 +286,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
286 .dpcm_playback = 1, 286 .dpcm_playback = 1,
287 .ops = &broxton_rt286_fe_ops, 287 .ops = &broxton_rt286_fe_ops,
288 }, 288 },
289 [BXT_DPCM_AUDIO_CP] 289 [BXT_DPCM_AUDIO_CP] =
290 { 290 {
291 .name = "Bxt Audio Capture Port", 291 .name = "Bxt Audio Capture Port",
292 .stream_name = "Audio Record", 292 .stream_name = "Audio Record",
@@ -300,7 +300,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
300 .dpcm_capture = 1, 300 .dpcm_capture = 1,
301 .ops = &broxton_rt286_fe_ops, 301 .ops = &broxton_rt286_fe_ops,
302 }, 302 },
303 [BXT_DPCM_AUDIO_REF_CP] 303 [BXT_DPCM_AUDIO_REF_CP] =
304 { 304 {
305 .name = "Bxt Audio Reference cap", 305 .name = "Bxt Audio Reference cap",
306 .stream_name = "refcap", 306 .stream_name = "refcap",
@@ -313,7 +313,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
313 .nonatomic = 1, 313 .nonatomic = 1,
314 .dynamic = 1, 314 .dynamic = 1,
315 }, 315 },
316 [BXT_DPCM_AUDIO_DMIC_CP] 316 [BXT_DPCM_AUDIO_DMIC_CP] =
317 { 317 {
318 .name = "Bxt Audio DMIC cap", 318 .name = "Bxt Audio DMIC cap",
319 .stream_name = "dmiccap", 319 .stream_name = "dmiccap",
@@ -327,7 +327,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
327 .dynamic = 1, 327 .dynamic = 1,
328 .ops = &broxton_dmic_ops, 328 .ops = &broxton_dmic_ops,
329 }, 329 },
330 [BXT_DPCM_AUDIO_HDMI1_PB] 330 [BXT_DPCM_AUDIO_HDMI1_PB] =
331 { 331 {
332 .name = "Bxt HDMI Port1", 332 .name = "Bxt HDMI Port1",
333 .stream_name = "Hdmi1", 333 .stream_name = "Hdmi1",
@@ -340,7 +340,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
340 .nonatomic = 1, 340 .nonatomic = 1,
341 .dynamic = 1, 341 .dynamic = 1,
342 }, 342 },
343 [BXT_DPCM_AUDIO_HDMI2_PB] 343 [BXT_DPCM_AUDIO_HDMI2_PB] =
344 { 344 {
345 .name = "Bxt HDMI Port2", 345 .name = "Bxt HDMI Port2",
346 .stream_name = "Hdmi2", 346 .stream_name = "Hdmi2",
@@ -353,7 +353,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
353 .nonatomic = 1, 353 .nonatomic = 1,
354 .dynamic = 1, 354 .dynamic = 1,
355 }, 355 },
356 [BXT_DPCM_AUDIO_HDMI3_PB] 356 [BXT_DPCM_AUDIO_HDMI3_PB] =
357 { 357 {
358 .name = "Bxt HDMI Port3", 358 .name = "Bxt HDMI Port3",
359 .stream_name = "Hdmi3", 359 .stream_name = "Hdmi3",
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index 88efb62439ba..bff77a1f27fc 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -24,6 +24,9 @@
24#include <linux/device.h> 24#include <linux/device.h>
25#include <linux/dmi.h> 25#include <linux/dmi.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <asm/cpu_device_id.h>
28#include <asm/platform_sst_audio.h>
29#include <linux/clk.h>
27#include <sound/pcm.h> 30#include <sound/pcm.h>
28#include <sound/pcm_params.h> 31#include <sound/pcm_params.h>
29#include <sound/soc.h> 32#include <sound/soc.h>
@@ -31,42 +34,153 @@
31#include "../../codecs/rt5640.h" 34#include "../../codecs/rt5640.h"
32#include "../atom/sst-atom-controls.h" 35#include "../atom/sst-atom-controls.h"
33#include "../common/sst-acpi.h" 36#include "../common/sst-acpi.h"
37#include "../common/sst-dsp.h"
34 38
35enum { 39enum {
36 BYT_RT5640_DMIC1_MAP, 40 BYT_RT5640_DMIC1_MAP,
37 BYT_RT5640_DMIC2_MAP, 41 BYT_RT5640_DMIC2_MAP,
38 BYT_RT5640_IN1_MAP, 42 BYT_RT5640_IN1_MAP,
43 BYT_RT5640_IN3_MAP,
39}; 44};
40 45
41#define BYT_RT5640_MAP(quirk) ((quirk) & 0xff) 46#define BYT_RT5640_MAP(quirk) ((quirk) & 0xff)
42#define BYT_RT5640_DMIC_EN BIT(16) 47#define BYT_RT5640_DMIC_EN BIT(16)
48#define BYT_RT5640_MONO_SPEAKER BIT(17)
49#define BYT_RT5640_DIFF_MIC BIT(18) /* defaut is single-ended */
50#define BYT_RT5640_SSP2_AIF2 BIT(19) /* default is using AIF1 */
51#define BYT_RT5640_SSP0_AIF1 BIT(20)
52#define BYT_RT5640_SSP0_AIF2 BIT(21)
53#define BYT_RT5640_MCLK_EN BIT(22)
54#define BYT_RT5640_MCLK_25MHZ BIT(23)
55
56struct byt_rt5640_private {
57 struct clk *mclk;
58};
43 59
44static unsigned long byt_rt5640_quirk = BYT_RT5640_DMIC1_MAP | 60static unsigned long byt_rt5640_quirk = BYT_RT5640_DMIC1_MAP |
45 BYT_RT5640_DMIC_EN; 61 BYT_RT5640_DMIC_EN |
62 BYT_RT5640_MCLK_EN;
63
64static void log_quirks(struct device *dev)
65{
66 if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_DMIC1_MAP)
67 dev_info(dev, "quirk DMIC1_MAP enabled");
68 if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_DMIC2_MAP)
69 dev_info(dev, "quirk DMIC2_MAP enabled");
70 if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_IN1_MAP)
71 dev_info(dev, "quirk IN1_MAP enabled");
72 if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_IN3_MAP)
73 dev_info(dev, "quirk IN3_MAP enabled");
74 if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN)
75 dev_info(dev, "quirk DMIC enabled");
76 if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER)
77 dev_info(dev, "quirk MONO_SPEAKER enabled");
78 if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
79 dev_info(dev, "quirk DIFF_MIC enabled");
80 if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2)
81 dev_info(dev, "quirk SSP2_AIF2 enabled");
82 if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1)
83 dev_info(dev, "quirk SSP0_AIF1 enabled");
84 if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)
85 dev_info(dev, "quirk SSP0_AIF2 enabled");
86 if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN)
87 dev_info(dev, "quirk MCLK_EN enabled");
88 if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ)
89 dev_info(dev, "quirk MCLK_25MHZ enabled");
90}
91
92
93#define BYT_CODEC_DAI1 "rt5640-aif1"
94#define BYT_CODEC_DAI2 "rt5640-aif2"
95
96static inline struct snd_soc_dai *byt_get_codec_dai(struct snd_soc_card *card)
97{
98 struct snd_soc_pcm_runtime *rtd;
99
100 list_for_each_entry(rtd, &card->rtd_list, list) {
101 if (!strncmp(rtd->codec_dai->name, BYT_CODEC_DAI1,
102 strlen(BYT_CODEC_DAI1)))
103 return rtd->codec_dai;
104 if (!strncmp(rtd->codec_dai->name, BYT_CODEC_DAI2,
105 strlen(BYT_CODEC_DAI2)))
106 return rtd->codec_dai;
107
108 }
109 return NULL;
110}
111
112static int platform_clock_control(struct snd_soc_dapm_widget *w,
113 struct snd_kcontrol *k, int event)
114{
115 struct snd_soc_dapm_context *dapm = w->dapm;
116 struct snd_soc_card *card = dapm->card;
117 struct snd_soc_dai *codec_dai;
118 struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
119 int ret;
120
121 codec_dai = byt_get_codec_dai(card);
122 if (!codec_dai) {
123 dev_err(card->dev,
124 "Codec dai not found; Unable to set platform clock\n");
125 return -EIO;
126 }
127
128 if (SND_SOC_DAPM_EVENT_ON(event)) {
129 if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk) {
130 ret = clk_prepare_enable(priv->mclk);
131 if (ret < 0) {
132 dev_err(card->dev,
133 "could not configure MCLK state");
134 return ret;
135 }
136 }
137 ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1,
138 48000 * 512,
139 SND_SOC_CLOCK_IN);
140 } else {
141 /*
142 * Set codec clock source to internal clock before
143 * turning off the platform clock. Codec needs clock
144 * for Jack detection and button press
145 */
146 ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_RCCLK,
147 0,
148 SND_SOC_CLOCK_IN);
149 if (!ret) {
150 if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk)
151 clk_disable_unprepare(priv->mclk);
152 }
153 }
154
155 if (ret < 0) {
156 dev_err(card->dev, "can't set codec sysclk: %d\n", ret);
157 return ret;
158 }
159
160 return 0;
161}
46 162
47static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = { 163static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = {
48 SND_SOC_DAPM_HP("Headphone", NULL), 164 SND_SOC_DAPM_HP("Headphone", NULL),
49 SND_SOC_DAPM_MIC("Headset Mic", NULL), 165 SND_SOC_DAPM_MIC("Headset Mic", NULL),
50 SND_SOC_DAPM_MIC("Internal Mic", NULL), 166 SND_SOC_DAPM_MIC("Internal Mic", NULL),
51 SND_SOC_DAPM_SPK("Speaker", NULL), 167 SND_SOC_DAPM_SPK("Speaker", NULL),
168 SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
169 platform_clock_control, SND_SOC_DAPM_PRE_PMU |
170 SND_SOC_DAPM_POST_PMD),
171
52}; 172};
53 173
54static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = { 174static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = {
55 {"AIF1 Playback", NULL, "ssp2 Tx"}, 175 {"Headphone", NULL, "Platform Clock"},
56 {"ssp2 Tx", NULL, "codec_out0"}, 176 {"Headset Mic", NULL, "Platform Clock"},
57 {"ssp2 Tx", NULL, "codec_out1"}, 177 {"Internal Mic", NULL, "Platform Clock"},
58 {"codec_in0", NULL, "ssp2 Rx"}, 178 {"Speaker", NULL, "Platform Clock"},
59 {"codec_in1", NULL, "ssp2 Rx"},
60 {"ssp2 Rx", NULL, "AIF1 Capture"},
61 179
62 {"Headset Mic", NULL, "MICBIAS1"}, 180 {"Headset Mic", NULL, "MICBIAS1"},
63 {"IN2P", NULL, "Headset Mic"}, 181 {"IN2P", NULL, "Headset Mic"},
64 {"Headphone", NULL, "HPOL"}, 182 {"Headphone", NULL, "HPOL"},
65 {"Headphone", NULL, "HPOR"}, 183 {"Headphone", NULL, "HPOR"},
66 {"Speaker", NULL, "SPOLP"},
67 {"Speaker", NULL, "SPOLN"},
68 {"Speaker", NULL, "SPORP"},
69 {"Speaker", NULL, "SPORN"},
70}; 184};
71 185
72static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic1_map[] = { 186static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic1_map[] = {
@@ -82,6 +196,59 @@ static const struct snd_soc_dapm_route byt_rt5640_intmic_in1_map[] = {
82 {"IN1P", NULL, "Internal Mic"}, 196 {"IN1P", NULL, "Internal Mic"},
83}; 197};
84 198
199static const struct snd_soc_dapm_route byt_rt5640_intmic_in3_map[] = {
200 {"Internal Mic", NULL, "MICBIAS1"},
201 {"IN3P", NULL, "Internal Mic"},
202};
203
204static const struct snd_soc_dapm_route byt_rt5640_ssp2_aif1_map[] = {
205 {"ssp2 Tx", NULL, "codec_out0"},
206 {"ssp2 Tx", NULL, "codec_out1"},
207 {"codec_in0", NULL, "ssp2 Rx"},
208 {"codec_in1", NULL, "ssp2 Rx"},
209
210 {"AIF1 Playback", NULL, "ssp2 Tx"},
211 {"ssp2 Rx", NULL, "AIF1 Capture"},
212};
213
214static const struct snd_soc_dapm_route byt_rt5640_ssp2_aif2_map[] = {
215 {"ssp2 Tx", NULL, "codec_out0"},
216 {"ssp2 Tx", NULL, "codec_out1"},
217 {"codec_in0", NULL, "ssp2 Rx"},
218 {"codec_in1", NULL, "ssp2 Rx"},
219
220 {"AIF2 Playback", NULL, "ssp2 Tx"},
221 {"ssp2 Rx", NULL, "AIF2 Capture"},
222};
223
224static const struct snd_soc_dapm_route byt_rt5640_ssp0_aif1_map[] = {
225 {"ssp0 Tx", NULL, "modem_out"},
226 {"modem_in", NULL, "ssp0 Rx"},
227
228 {"AIF1 Playback", NULL, "ssp0 Tx"},
229 {"ssp0 Rx", NULL, "AIF1 Capture"},
230};
231
232static const struct snd_soc_dapm_route byt_rt5640_ssp0_aif2_map[] = {
233 {"ssp0 Tx", NULL, "modem_out"},
234 {"modem_in", NULL, "ssp0 Rx"},
235
236 {"AIF2 Playback", NULL, "ssp0 Tx"},
237 {"ssp0 Rx", NULL, "AIF2 Capture"},
238};
239
240static const struct snd_soc_dapm_route byt_rt5640_stereo_spk_map[] = {
241 {"Speaker", NULL, "SPOLP"},
242 {"Speaker", NULL, "SPOLN"},
243 {"Speaker", NULL, "SPORP"},
244 {"Speaker", NULL, "SPORN"},
245};
246
247static const struct snd_soc_dapm_route byt_rt5640_mono_spk_map[] = {
248 {"Speaker", NULL, "SPOLP"},
249 {"Speaker", NULL, "SPOLN"},
250};
251
85static const struct snd_kcontrol_new byt_rt5640_controls[] = { 252static const struct snd_kcontrol_new byt_rt5640_controls[] = {
86 SOC_DAPM_PIN_SWITCH("Headphone"), 253 SOC_DAPM_PIN_SWITCH("Headphone"),
87 SOC_DAPM_PIN_SWITCH("Headset Mic"), 254 SOC_DAPM_PIN_SWITCH("Headset Mic"),
@@ -96,19 +263,46 @@ static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream,
96 struct snd_soc_dai *codec_dai = rtd->codec_dai; 263 struct snd_soc_dai *codec_dai = rtd->codec_dai;
97 int ret; 264 int ret;
98 265
99 snd_soc_dai_set_bclk_ratio(codec_dai, 50);
100
101 ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1, 266 ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1,
102 params_rate(params) * 512, 267 params_rate(params) * 512,
103 SND_SOC_CLOCK_IN); 268 SND_SOC_CLOCK_IN);
269
104 if (ret < 0) { 270 if (ret < 0) {
105 dev_err(rtd->dev, "can't set codec clock %d\n", ret); 271 dev_err(rtd->dev, "can't set codec clock %d\n", ret);
106 return ret; 272 return ret;
107 } 273 }
108 274
109 ret = snd_soc_dai_set_pll(codec_dai, 0, RT5640_PLL1_S_BCLK1, 275 if (!(byt_rt5640_quirk & BYT_RT5640_MCLK_EN)) {
110 params_rate(params) * 50, 276 /* use bitclock as PLL input */
111 params_rate(params) * 512); 277 if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
278 (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
279
280 /* 2x16 bit slots on SSP0 */
281 ret = snd_soc_dai_set_pll(codec_dai, 0,
282 RT5640_PLL1_S_BCLK1,
283 params_rate(params) * 32,
284 params_rate(params) * 512);
285 } else {
286 /* 2x15 bit slots on SSP2 */
287 ret = snd_soc_dai_set_pll(codec_dai, 0,
288 RT5640_PLL1_S_BCLK1,
289 params_rate(params) * 50,
290 params_rate(params) * 512);
291 }
292 } else {
293 if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) {
294 ret = snd_soc_dai_set_pll(codec_dai, 0,
295 RT5640_PLL1_S_MCLK,
296 25000000,
297 params_rate(params) * 512);
298 } else {
299 ret = snd_soc_dai_set_pll(codec_dai, 0,
300 RT5640_PLL1_S_MCLK,
301 19200000,
302 params_rate(params) * 512);
303 }
304 }
305
112 if (ret < 0) { 306 if (ret < 0) {
113 dev_err(rtd->dev, "can't set codec pll: %d\n", ret); 307 dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
114 return ret; 308 return ret;
@@ -127,27 +321,73 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
127 { 321 {
128 .callback = byt_rt5640_quirk_cb, 322 .callback = byt_rt5640_quirk_cb,
129 .matches = { 323 .matches = {
130 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 324 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
131 DMI_MATCH(DMI_PRODUCT_NAME, "T100TA"), 325 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"),
326 },
327 .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP |
328 BYT_RT5640_MCLK_EN),
329 },
330 {
331 .callback = byt_rt5640_quirk_cb,
332 .matches = {
333 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
334 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TAF"),
132 }, 335 },
133 .driver_data = (unsigned long *)BYT_RT5640_IN1_MAP, 336 .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP |
337 BYT_RT5640_MONO_SPEAKER |
338 BYT_RT5640_DIFF_MIC |
339 BYT_RT5640_SSP0_AIF2 |
340 BYT_RT5640_MCLK_EN
341 ),
134 }, 342 },
135 { 343 {
136 .callback = byt_rt5640_quirk_cb, 344 .callback = byt_rt5640_quirk_cb,
137 .matches = { 345 .matches = {
138 DMI_MATCH(DMI_SYS_VENDOR, "DellInc."), 346 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "DellInc."),
139 DMI_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"), 347 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"),
140 }, 348 },
141 .driver_data = (unsigned long *)(BYT_RT5640_DMIC2_MAP | 349 .driver_data = (unsigned long *)(BYT_RT5640_DMIC2_MAP |
350 BYT_RT5640_DMIC_EN |
351 BYT_RT5640_MCLK_EN),
352 },
353 {
354 .callback = byt_rt5640_quirk_cb,
355 .matches = {
356 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
357 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"),
358 },
359 .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP |
360 BYT_RT5640_MCLK_EN),
361 },
362 {
363 .callback = byt_rt5640_quirk_cb,
364 .matches = {
365 DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
366 DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"),
367 },
368 .driver_data = (unsigned long *)(BYT_RT5640_DMIC1_MAP |
142 BYT_RT5640_DMIC_EN), 369 BYT_RT5640_DMIC_EN),
143 }, 370 },
144 { 371 {
145 .callback = byt_rt5640_quirk_cb, 372 .callback = byt_rt5640_quirk_cb,
146 .matches = { 373 .matches = {
147 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 374 DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"),
148 DMI_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"), 375 DMI_MATCH(DMI_BOARD_NAME, "tPAD"),
149 }, 376 },
150 .driver_data = (unsigned long *)BYT_RT5640_IN1_MAP, 377 .driver_data = (unsigned long *)(BYT_RT5640_IN3_MAP |
378 BYT_RT5640_MCLK_EN |
379 BYT_RT5640_SSP0_AIF1),
380 },
381 {
382 .callback = byt_rt5640_quirk_cb,
383 .matches = {
384 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
385 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
386 },
387 .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP |
388 BYT_RT5640_MCLK_EN |
389 BYT_RT5640_SSP0_AIF1),
390
151 }, 391 },
152 {} 392 {}
153}; 393};
@@ -158,13 +398,18 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
158 struct snd_soc_codec *codec = runtime->codec; 398 struct snd_soc_codec *codec = runtime->codec;
159 struct snd_soc_card *card = runtime->card; 399 struct snd_soc_card *card = runtime->card;
160 const struct snd_soc_dapm_route *custom_map; 400 const struct snd_soc_dapm_route *custom_map;
401 struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
161 int num_routes; 402 int num_routes;
162 403
163 card->dapm.idle_bias_off = true; 404 card->dapm.idle_bias_off = true;
164 405
165 rt5640_sel_asrc_clk_src(codec, 406 rt5640_sel_asrc_clk_src(codec,
166 RT5640_DA_STEREO_FILTER | 407 RT5640_DA_STEREO_FILTER |
167 RT5640_AD_STEREO_FILTER, 408 RT5640_DA_MONO_L_FILTER |
409 RT5640_DA_MONO_R_FILTER |
410 RT5640_AD_STEREO_FILTER |
411 RT5640_AD_MONO_L_FILTER |
412 RT5640_AD_MONO_R_FILTER,
168 RT5640_CLK_SEL_ASRC); 413 RT5640_CLK_SEL_ASRC);
169 414
170 ret = snd_soc_add_card_controls(card, byt_rt5640_controls, 415 ret = snd_soc_add_card_controls(card, byt_rt5640_controls,
@@ -179,6 +424,10 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
179 custom_map = byt_rt5640_intmic_in1_map; 424 custom_map = byt_rt5640_intmic_in1_map;
180 num_routes = ARRAY_SIZE(byt_rt5640_intmic_in1_map); 425 num_routes = ARRAY_SIZE(byt_rt5640_intmic_in1_map);
181 break; 426 break;
427 case BYT_RT5640_IN3_MAP:
428 custom_map = byt_rt5640_intmic_in3_map;
429 num_routes = ARRAY_SIZE(byt_rt5640_intmic_in3_map);
430 break;
182 case BYT_RT5640_DMIC2_MAP: 431 case BYT_RT5640_DMIC2_MAP:
183 custom_map = byt_rt5640_intmic_dmic2_map; 432 custom_map = byt_rt5640_intmic_dmic2_map;
184 num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic2_map); 433 num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic2_map);
@@ -192,6 +441,43 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
192 if (ret) 441 if (ret)
193 return ret; 442 return ret;
194 443
444 if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) {
445 ret = snd_soc_dapm_add_routes(&card->dapm,
446 byt_rt5640_ssp2_aif2_map,
447 ARRAY_SIZE(byt_rt5640_ssp2_aif2_map));
448 } else if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) {
449 ret = snd_soc_dapm_add_routes(&card->dapm,
450 byt_rt5640_ssp0_aif1_map,
451 ARRAY_SIZE(byt_rt5640_ssp0_aif1_map));
452 } else if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2) {
453 ret = snd_soc_dapm_add_routes(&card->dapm,
454 byt_rt5640_ssp0_aif2_map,
455 ARRAY_SIZE(byt_rt5640_ssp0_aif2_map));
456 } else {
457 ret = snd_soc_dapm_add_routes(&card->dapm,
458 byt_rt5640_ssp2_aif1_map,
459 ARRAY_SIZE(byt_rt5640_ssp2_aif1_map));
460 }
461 if (ret)
462 return ret;
463
464 if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) {
465 ret = snd_soc_dapm_add_routes(&card->dapm,
466 byt_rt5640_mono_spk_map,
467 ARRAY_SIZE(byt_rt5640_mono_spk_map));
468 } else {
469 ret = snd_soc_dapm_add_routes(&card->dapm,
470 byt_rt5640_stereo_spk_map,
471 ARRAY_SIZE(byt_rt5640_stereo_spk_map));
472 }
473 if (ret)
474 return ret;
475
476 if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC) {
477 snd_soc_update_bits(codec, RT5640_IN1_IN2, RT5640_IN_DF1,
478 RT5640_IN_DF1);
479 }
480
195 if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) { 481 if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) {
196 ret = rt5640_dmic_enable(codec, 0, 0); 482 ret = rt5640_dmic_enable(codec, 0, 0);
197 if (ret) 483 if (ret)
@@ -201,6 +487,30 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
201 snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone"); 487 snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone");
202 snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker"); 488 snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker");
203 489
490 if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk) {
491 /*
492 * The firmware might enable the clock at
493 * boot (this information may or may not
494 * be reflected in the enable clock register).
495 * To change the rate we must disable the clock
496 * first to cover these cases. Due to common
497 * clock framework restrictions that do not allow
498 * to disable a clock that has not been enabled,
499 * we need to enable the clock first.
500 */
501 ret = clk_prepare_enable(priv->mclk);
502 if (!ret)
503 clk_disable_unprepare(priv->mclk);
504
505 if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ)
506 ret = clk_set_rate(priv->mclk, 25000000);
507 else
508 ret = clk_set_rate(priv->mclk, 19200000);
509
510 if (ret)
511 dev_err(card->dev, "unable to set MCLK rate\n");
512 }
513
204 return ret; 514 return ret;
205} 515}
206 516
@@ -221,34 +531,63 @@ static int byt_rt5640_codec_fixup(struct snd_soc_pcm_runtime *rtd,
221 SNDRV_PCM_HW_PARAM_CHANNELS); 531 SNDRV_PCM_HW_PARAM_CHANNELS);
222 int ret; 532 int ret;
223 533
224 /* The DSP will covert the FE rate to 48k, stereo, 24bits */ 534 /* The DSP will covert the FE rate to 48k, stereo */
225 rate->min = rate->max = 48000; 535 rate->min = rate->max = 48000;
226 channels->min = channels->max = 2; 536 channels->min = channels->max = 2;
227 537
228 /* set SSP2 to 24-bit */ 538 if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
229 params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); 539 (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
540
541 /* set SSP0 to 16-bit */
542 params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
543
544 /*
545 * Default mode for SSP configuration is TDM 4 slot, override config
546 * with explicit setting to I2S 2ch 16-bit. The word length is set with
547 * dai_set_tdm_slot() since there is no other API exposed
548 */
549 ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
550 SND_SOC_DAIFMT_I2S |
551 SND_SOC_DAIFMT_NB_IF |
552 SND_SOC_DAIFMT_CBS_CFS
553 );
554 if (ret < 0) {
555 dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
556 return ret;
557 }
230 558
231 /* 559 ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 16);
232 * Default mode for SSP configuration is TDM 4 slot, override config 560 if (ret < 0) {
233 * with explicit setting to I2S 2ch 24-bit. The word length is set with 561 dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
234 * dai_set_tdm_slot() since there is no other API exposed 562 return ret;
235 */ 563 }
236 ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
237 SND_SOC_DAIFMT_I2S |
238 SND_SOC_DAIFMT_NB_IF |
239 SND_SOC_DAIFMT_CBS_CFS
240 );
241 if (ret < 0) {
242 dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
243 return ret;
244 }
245 564
246 ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24); 565 } else {
247 if (ret < 0) { 566
248 dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); 567 /* set SSP2 to 24-bit */
249 return ret; 568 params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
250 } 569
570 /*
571 * Default mode for SSP configuration is TDM 4 slot, override config
572 * with explicit setting to I2S 2ch 24-bit. The word length is set with
573 * dai_set_tdm_slot() since there is no other API exposed
574 */
575 ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
576 SND_SOC_DAIFMT_I2S |
577 SND_SOC_DAIFMT_NB_IF |
578 SND_SOC_DAIFMT_CBS_CFS
579 );
580 if (ret < 0) {
581 dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
582 return ret;
583 }
251 584
585 ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24);
586 if (ret < 0) {
587 dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
588 return ret;
589 }
590 }
252 return 0; 591 return 0;
253} 592}
254 593
@@ -305,10 +644,10 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = {
305 { 644 {
306 .name = "SSP2-Codec", 645 .name = "SSP2-Codec",
307 .id = 1, 646 .id = 1,
308 .cpu_dai_name = "ssp2-port", 647 .cpu_dai_name = "ssp2-port", /* overwritten for ssp0 routing */
309 .platform_name = "sst-mfld-platform", 648 .platform_name = "sst-mfld-platform",
310 .no_pcm = 1, 649 .no_pcm = 1,
311 .codec_dai_name = "rt5640-aif1", 650 .codec_dai_name = "rt5640-aif1", /* changed w/ quirk */
312 .codec_name = "i2c-10EC5640:00", /* overwritten with HID */ 651 .codec_name = "i2c-10EC5640:00", /* overwritten with HID */
313 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF 652 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
314 | SND_SOC_DAIFMT_CBS_CFS, 653 | SND_SOC_DAIFMT_CBS_CFS,
@@ -335,6 +674,21 @@ static struct snd_soc_card byt_rt5640_card = {
335}; 674};
336 675
337static char byt_rt5640_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */ 676static char byt_rt5640_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */
677static char byt_rt5640_codec_aif_name[12]; /* = "rt5640-aif[1|2]" */
678static char byt_rt5640_cpu_dai_name[10]; /* = "ssp[0|2]-port" */
679
680static bool is_valleyview(void)
681{
682 static const struct x86_cpu_id cpu_ids[] = {
683 { X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */
684 {}
685 };
686
687 if (!x86_match_cpu(cpu_ids))
688 return false;
689 return true;
690}
691
338 692
339static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) 693static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
340{ 694{
@@ -343,10 +697,16 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
343 const char *i2c_name = NULL; 697 const char *i2c_name = NULL;
344 int i; 698 int i;
345 int dai_index; 699 int dai_index;
700 struct byt_rt5640_private *priv;
701
702 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC);
703 if (!priv)
704 return -ENOMEM;
346 705
347 /* register the soc card */ 706 /* register the soc card */
348 byt_rt5640_card.dev = &pdev->dev; 707 byt_rt5640_card.dev = &pdev->dev;
349 mach = byt_rt5640_card.dev->platform_data; 708 mach = byt_rt5640_card.dev->platform_data;
709 snd_soc_card_set_drvdata(&byt_rt5640_card, priv);
350 710
351 /* fix index of codec dai */ 711 /* fix index of codec dai */
352 dai_index = MERR_DPCM_COMPR + 1; 712 dai_index = MERR_DPCM_COMPR + 1;
@@ -366,8 +726,57 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
366 byt_rt5640_dais[dai_index].codec_name = byt_rt5640_codec_name; 726 byt_rt5640_dais[dai_index].codec_name = byt_rt5640_codec_name;
367 } 727 }
368 728
729 /*
730 * swap SSP0 if bytcr is detected
731 * (will be overridden if DMI quirk is detected)
732 */
733 if (is_valleyview()) {
734 struct sst_platform_info *p_info = mach->pdata;
735 const struct sst_res_info *res_info = p_info->res_info;
736
737 /* TODO: use CHAN package info from BIOS to detect AIF1/AIF2 */
738 if (res_info->acpi_ipc_irq_index == 0) {
739 byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF2;
740 }
741 }
742
369 /* check quirks before creating card */ 743 /* check quirks before creating card */
370 dmi_check_system(byt_rt5640_quirk_table); 744 dmi_check_system(byt_rt5640_quirk_table);
745 log_quirks(&pdev->dev);
746
747 if ((byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) ||
748 (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
749
750 /* fixup codec aif name */
751 snprintf(byt_rt5640_codec_aif_name,
752 sizeof(byt_rt5640_codec_aif_name),
753 "%s", "rt5640-aif2");
754
755 byt_rt5640_dais[dai_index].codec_dai_name =
756 byt_rt5640_codec_aif_name;
757 }
758
759 if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
760 (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
761
762 /* fixup cpu dai name name */
763 snprintf(byt_rt5640_cpu_dai_name,
764 sizeof(byt_rt5640_cpu_dai_name),
765 "%s", "ssp0-port");
766
767 byt_rt5640_dais[dai_index].cpu_dai_name =
768 byt_rt5640_cpu_dai_name;
769 }
770
771 if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && (is_valleyview())) {
772 priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
773 if (IS_ERR(priv->mclk)) {
774 dev_err(&pdev->dev,
775 "Failed to get MCLK from pmc_plt_clk_3: %ld\n",
776 PTR_ERR(priv->mclk));
777 return PTR_ERR(priv->mclk);
778 }
779 }
371 780
372 ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card); 781 ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card);
373 782
diff --git a/sound/soc/intel/common/sst-acpi.c b/sound/soc/intel/common/sst-acpi.c
index 2c5eda14d510..1285cc597b6b 100644
--- a/sound/soc/intel/common/sst-acpi.c
+++ b/sound/soc/intel/common/sst-acpi.c
@@ -199,6 +199,7 @@ static struct sst_acpi_desc sst_acpi_haswell_desc = {
199 199
200static struct sst_acpi_mach broadwell_machines[] = { 200static struct sst_acpi_mach broadwell_machines[] = {
201 { "INT343A", "broadwell-audio", "intel/IntcSST2.bin", NULL, NULL, NULL }, 201 { "INT343A", "broadwell-audio", "intel/IntcSST2.bin", NULL, NULL, NULL },
202 { "RT5677CE", "bdw-rt5677", "intel/IntcSST2.bin", NULL, NULL, NULL },
202 {} 203 {}
203}; 204};
204 205
diff --git a/sound/soc/intel/skylake/bxt-sst.c b/sound/soc/intel/skylake/bxt-sst.c
index 2663781278aa..1d251d59bcb9 100644
--- a/sound/soc/intel/skylake/bxt-sst.c
+++ b/sound/soc/intel/skylake/bxt-sst.c
@@ -23,6 +23,7 @@
23#include "../common/sst-dsp.h" 23#include "../common/sst-dsp.h"
24#include "../common/sst-dsp-priv.h" 24#include "../common/sst-dsp-priv.h"
25#include "skl-sst-ipc.h" 25#include "skl-sst-ipc.h"
26#include "skl-tplg-interface.h"
26 27
27#define BXT_BASEFW_TIMEOUT 3000 28#define BXT_BASEFW_TIMEOUT 3000
28#define BXT_INIT_TIMEOUT 500 29#define BXT_INIT_TIMEOUT 500
@@ -40,11 +41,73 @@
40#define BXT_INSTANCE_ID 0 41#define BXT_INSTANCE_ID 0
41#define BXT_BASE_FW_MODULE_ID 0 42#define BXT_BASE_FW_MODULE_ID 0
42 43
44#define BXT_ADSP_FW_BIN_HDR_OFFSET 0x2000
45
43static unsigned int bxt_get_errorcode(struct sst_dsp *ctx) 46static unsigned int bxt_get_errorcode(struct sst_dsp *ctx)
44{ 47{
45 return sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE); 48 return sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE);
46} 49}
47 50
51static int
52bxt_load_library(struct sst_dsp *ctx, struct skl_dfw_manifest *minfo)
53{
54 struct snd_dma_buffer dmab;
55 struct skl_sst *skl = ctx->thread_context;
56 const struct firmware *fw = NULL;
57 struct firmware stripped_fw;
58 int ret = 0, i, dma_id, stream_tag;
59
60 /* library indices start from 1 to N. 0 represents base FW */
61 for (i = 1; i < minfo->lib_count; i++) {
62 ret = request_firmware(&fw, minfo->lib[i].name, ctx->dev);
63 if (ret < 0) {
64 dev_err(ctx->dev, "Request lib %s failed:%d\n",
65 minfo->lib[i].name, ret);
66 return ret;
67 }
68
69 if (skl->is_first_boot) {
70 ret = snd_skl_parse_uuids(ctx, fw,
71 BXT_ADSP_FW_BIN_HDR_OFFSET, i);
72 if (ret < 0)
73 goto load_library_failed;
74 }
75
76 stripped_fw.data = fw->data;
77 stripped_fw.size = fw->size;
78 skl_dsp_strip_extended_manifest(&stripped_fw);
79
80 stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40,
81 stripped_fw.size, &dmab);
82 if (stream_tag <= 0) {
83 dev_err(ctx->dev, "Lib prepare DMA err: %x\n",
84 stream_tag);
85 ret = stream_tag;
86 goto load_library_failed;
87 }
88
89 dma_id = stream_tag - 1;
90 memcpy(dmab.area, stripped_fw.data, stripped_fw.size);
91
92 ctx->dsp_ops.trigger(ctx->dev, true, stream_tag);
93 ret = skl_sst_ipc_load_library(&skl->ipc, dma_id, i);
94 if (ret < 0)
95 dev_err(ctx->dev, "IPC Load Lib for %s fail: %d\n",
96 minfo->lib[i].name, ret);
97
98 ctx->dsp_ops.trigger(ctx->dev, false, stream_tag);
99 ctx->dsp_ops.cleanup(ctx->dev, &dmab, stream_tag);
100 release_firmware(fw);
101 fw = NULL;
102 }
103
104 return ret;
105
106load_library_failed:
107 release_firmware(fw);
108 return ret;
109}
110
48/* 111/*
49 * First boot sequence has some extra steps. Core 0 waits for power 112 * First boot sequence has some extra steps. Core 0 waits for power
50 * status on core 1, so power up core 1 also momentarily, keep it in 113 * status on core 1, so power up core 1 also momentarily, keep it in
@@ -157,8 +220,6 @@ static int sst_transfer_fw_host_dma(struct sst_dsp *ctx)
157 return ret; 220 return ret;
158} 221}
159 222
160#define BXT_ADSP_FW_BIN_HDR_OFFSET 0x2000
161
162static int bxt_load_base_firmware(struct sst_dsp *ctx) 223static int bxt_load_base_firmware(struct sst_dsp *ctx)
163{ 224{
164 struct firmware stripped_fw; 225 struct firmware stripped_fw;
@@ -175,9 +236,12 @@ static int bxt_load_base_firmware(struct sst_dsp *ctx)
175 if (ctx->fw == NULL) 236 if (ctx->fw == NULL)
176 goto sst_load_base_firmware_failed; 237 goto sst_load_base_firmware_failed;
177 238
178 ret = snd_skl_parse_uuids(ctx, BXT_ADSP_FW_BIN_HDR_OFFSET); 239 /* prase uuids on first boot */
179 if (ret < 0) 240 if (skl->is_first_boot) {
180 goto sst_load_base_firmware_failed; 241 ret = snd_skl_parse_uuids(ctx, ctx->fw, BXT_ADSP_FW_BIN_HDR_OFFSET, 0);
242 if (ret < 0)
243 goto sst_load_base_firmware_failed;
244 }
181 245
182 stripped_fw.data = ctx->fw->data; 246 stripped_fw.data = ctx->fw->data;
183 stripped_fw.size = ctx->fw->size; 247 stripped_fw.size = ctx->fw->size;
@@ -230,12 +294,23 @@ static int bxt_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
230 int ret; 294 int ret;
231 struct skl_ipc_dxstate_info dx; 295 struct skl_ipc_dxstate_info dx;
232 unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); 296 unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
297 struct skl_dfw_manifest *minfo = &skl->manifest;
233 298
234 if (skl->fw_loaded == false) { 299 if (skl->fw_loaded == false) {
235 skl->boot_complete = false; 300 skl->boot_complete = false;
236 ret = bxt_load_base_firmware(ctx); 301 ret = bxt_load_base_firmware(ctx);
237 if (ret < 0) 302 if (ret < 0) {
238 dev_err(ctx->dev, "reload fw failed: %d\n", ret); 303 dev_err(ctx->dev, "reload fw failed: %d\n", ret);
304 return ret;
305 }
306
307 if (minfo->lib_count > 1) {
308 ret = bxt_load_library(ctx, minfo);
309 if (ret < 0) {
310 dev_err(ctx->dev, "reload libs failed: %d\n", ret);
311 return ret;
312 }
313 }
239 return ret; 314 return ret;
240 } 315 }
241 316
@@ -329,7 +404,7 @@ static int bxt_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id)
329 404
330 ret = skl_dsp_disable_core(ctx, core_mask); 405 ret = skl_dsp_disable_core(ctx, core_mask);
331 if (ret < 0) { 406 if (ret < 0) {
332 dev_err(ctx->dev, "Failed to disable core %d", ret); 407 dev_err(ctx->dev, "Failed to disable core %d\n", ret);
333 return ret; 408 return ret;
334 } 409 }
335 skl->cores.state[core_id] = SKL_DSP_RESET; 410 skl->cores.state[core_id] = SKL_DSP_RESET;
@@ -341,6 +416,7 @@ static struct skl_dsp_fw_ops bxt_fw_ops = {
341 .set_state_D3 = bxt_set_dsp_D3, 416 .set_state_D3 = bxt_set_dsp_D3,
342 .load_fw = bxt_load_base_firmware, 417 .load_fw = bxt_load_base_firmware,
343 .get_fw_errcode = bxt_get_errorcode, 418 .get_fw_errcode = bxt_get_errorcode,
419 .load_library = bxt_load_library,
344}; 420};
345 421
346static struct sst_ops skl_ops = { 422static struct sst_ops skl_ops = {
@@ -397,22 +473,40 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
397 skl->cores.count = 2; 473 skl->cores.count = 2;
398 skl->boot_complete = false; 474 skl->boot_complete = false;
399 init_waitqueue_head(&skl->boot_wait); 475 init_waitqueue_head(&skl->boot_wait);
476 skl->is_first_boot = true;
477
478 if (dsp)
479 *dsp = skl;
480
481 return 0;
482}
483EXPORT_SYMBOL_GPL(bxt_sst_dsp_init);
484
485int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx)
486{
487 int ret;
488 struct sst_dsp *sst = ctx->dsp;
400 489
401 ret = sst->fw_ops.load_fw(sst); 490 ret = sst->fw_ops.load_fw(sst);
402 if (ret < 0) { 491 if (ret < 0) {
403 dev_err(dev, "Load base fw failed: %x", ret); 492 dev_err(dev, "Load base fw failed: %x\n", ret);
404 return ret; 493 return ret;
405 } 494 }
406 495
407 skl_dsp_init_core_state(sst); 496 skl_dsp_init_core_state(sst);
408 497
409 if (dsp) 498 if (ctx->manifest.lib_count > 1) {
410 *dsp = skl; 499 ret = sst->fw_ops.load_library(sst, &ctx->manifest);
500 if (ret < 0) {
501 dev_err(dev, "Load Library failed : %x\n", ret);
502 return ret;
503 }
504 }
505 ctx->is_first_boot = false;
411 506
412 return 0; 507 return 0;
413} 508}
414EXPORT_SYMBOL_GPL(bxt_sst_dsp_init); 509EXPORT_SYMBOL_GPL(bxt_sst_init_fw);
415
416 510
417void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) 511void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx)
418{ 512{
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c
index 44ab595ce21a..805b7f2173f3 100644
--- a/sound/soc/intel/skylake/skl-messages.c
+++ b/sound/soc/intel/skylake/skl-messages.c
@@ -203,32 +203,35 @@ static const struct skl_dsp_ops dsp_ops[] = {
203 .id = 0x9d70, 203 .id = 0x9d70,
204 .loader_ops = skl_get_loader_ops, 204 .loader_ops = skl_get_loader_ops,
205 .init = skl_sst_dsp_init, 205 .init = skl_sst_dsp_init,
206 .init_fw = skl_sst_init_fw,
206 .cleanup = skl_sst_dsp_cleanup 207 .cleanup = skl_sst_dsp_cleanup
207 }, 208 },
208 { 209 {
209 .id = 0x9d71, 210 .id = 0x9d71,
210 .loader_ops = skl_get_loader_ops, 211 .loader_ops = skl_get_loader_ops,
211 .init = skl_sst_dsp_init, 212 .init = skl_sst_dsp_init,
213 .init_fw = skl_sst_init_fw,
212 .cleanup = skl_sst_dsp_cleanup 214 .cleanup = skl_sst_dsp_cleanup
213 }, 215 },
214 { 216 {
215 .id = 0x5a98, 217 .id = 0x5a98,
216 .loader_ops = bxt_get_loader_ops, 218 .loader_ops = bxt_get_loader_ops,
217 .init = bxt_sst_dsp_init, 219 .init = bxt_sst_dsp_init,
220 .init_fw = bxt_sst_init_fw,
218 .cleanup = bxt_sst_dsp_cleanup 221 .cleanup = bxt_sst_dsp_cleanup
219 }, 222 },
220}; 223};
221 224
222static int skl_get_dsp_ops(int pci_id) 225const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id)
223{ 226{
224 int i; 227 int i;
225 228
226 for (i = 0; i < ARRAY_SIZE(dsp_ops); i++) { 229 for (i = 0; i < ARRAY_SIZE(dsp_ops); i++) {
227 if (dsp_ops[i].id == pci_id) 230 if (dsp_ops[i].id == pci_id)
228 return i; 231 return &dsp_ops[i];
229 } 232 }
230 233
231 return -EINVAL; 234 return NULL;
232} 235}
233 236
234int skl_init_dsp(struct skl *skl) 237int skl_init_dsp(struct skl *skl)
@@ -238,7 +241,8 @@ int skl_init_dsp(struct skl *skl)
238 struct hdac_bus *bus = ebus_to_hbus(ebus); 241 struct hdac_bus *bus = ebus_to_hbus(ebus);
239 struct skl_dsp_loader_ops loader_ops; 242 struct skl_dsp_loader_ops loader_ops;
240 int irq = bus->irq; 243 int irq = bus->irq;
241 int ret, index; 244 const struct skl_dsp_ops *ops;
245 int ret;
242 246
243 /* enable ppcap interrupt */ 247 /* enable ppcap interrupt */
244 snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true); 248 snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true);
@@ -251,18 +255,18 @@ int skl_init_dsp(struct skl *skl)
251 return -ENXIO; 255 return -ENXIO;
252 } 256 }
253 257
254 index = skl_get_dsp_ops(skl->pci->device); 258 ops = skl_get_dsp_ops(skl->pci->device);
255 if (index < 0) 259 if (!ops)
256 return -EINVAL; 260 return -EIO;
257 261
258 loader_ops = dsp_ops[index].loader_ops(); 262 loader_ops = ops->loader_ops();
259 ret = dsp_ops[index].init(bus->dev, mmio_base, irq, 263 ret = ops->init(bus->dev, mmio_base, irq,
260 skl->fw_name, loader_ops, &skl->skl_sst); 264 skl->fw_name, loader_ops,
265 &skl->skl_sst);
261 266
262 if (ret < 0) 267 if (ret < 0)
263 return ret; 268 return ret;
264 269
265 skl_dsp_enable_notification(skl->skl_sst, false);
266 dev_dbg(bus->dev, "dsp registration status=%d\n", ret); 270 dev_dbg(bus->dev, "dsp registration status=%d\n", ret);
267 271
268 return ret; 272 return ret;
@@ -273,16 +277,16 @@ int skl_free_dsp(struct skl *skl)
273 struct hdac_ext_bus *ebus = &skl->ebus; 277 struct hdac_ext_bus *ebus = &skl->ebus;
274 struct hdac_bus *bus = ebus_to_hbus(ebus); 278 struct hdac_bus *bus = ebus_to_hbus(ebus);
275 struct skl_sst *ctx = skl->skl_sst; 279 struct skl_sst *ctx = skl->skl_sst;
276 int index; 280 const struct skl_dsp_ops *ops;
277 281
278 /* disable ppcap interrupt */ 282 /* disable ppcap interrupt */
279 snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, false); 283 snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, false);
280 284
281 index = skl_get_dsp_ops(skl->pci->device); 285 ops = skl_get_dsp_ops(skl->pci->device);
282 if (index < 0) 286 if (!ops)
283 return -EIO; 287 return -EIO;
284 288
285 dsp_ops[index].cleanup(bus->dev, ctx); 289 ops->cleanup(bus->dev, ctx);
286 290
287 if (ctx->dsp->addr.lpe) 291 if (ctx->dsp->addr.lpe)
288 iounmap(ctx->dsp->addr.lpe); 292 iounmap(ctx->dsp->addr.lpe);
@@ -296,7 +300,7 @@ int skl_suspend_dsp(struct skl *skl)
296 int ret; 300 int ret;
297 301
298 /* if ppcap is not supported return 0 */ 302 /* if ppcap is not supported return 0 */
299 if (!skl->ebus.ppcap) 303 if (!skl->ebus.bus.ppcap)
300 return 0; 304 return 0;
301 305
302 ret = skl_dsp_sleep(ctx->dsp); 306 ret = skl_dsp_sleep(ctx->dsp);
@@ -316,13 +320,17 @@ int skl_resume_dsp(struct skl *skl)
316 int ret; 320 int ret;
317 321
318 /* if ppcap is not supported return 0 */ 322 /* if ppcap is not supported return 0 */
319 if (!skl->ebus.ppcap) 323 if (!skl->ebus.bus.ppcap)
320 return 0; 324 return 0;
321 325
322 /* enable ppcap interrupt */ 326 /* enable ppcap interrupt */
323 snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true); 327 snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true);
324 snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, true); 328 snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, true);
325 329
330 /* check if DSP 1st boot is done */
331 if (skl->skl_sst->is_first_boot == true)
332 return 0;
333
326 ret = skl_dsp_wake(ctx->dsp); 334 ret = skl_dsp_wake(ctx->dsp);
327 if (ret < 0) 335 if (ret < 0)
328 return ret; 336 return ret;
@@ -672,6 +680,7 @@ static u16 skl_get_module_param_size(struct skl_sst *ctx,
672 return param_size; 680 return param_size;
673 681
674 case SKL_MODULE_TYPE_BASE_OUTFMT: 682 case SKL_MODULE_TYPE_BASE_OUTFMT:
683 case SKL_MODULE_TYPE_KPB:
675 return sizeof(struct skl_base_outfmt_cfg); 684 return sizeof(struct skl_base_outfmt_cfg);
676 685
677 default: 686 default:
@@ -725,6 +734,7 @@ static int skl_set_module_format(struct skl_sst *ctx,
725 break; 734 break;
726 735
727 case SKL_MODULE_TYPE_BASE_OUTFMT: 736 case SKL_MODULE_TYPE_BASE_OUTFMT:
737 case SKL_MODULE_TYPE_KPB:
728 skl_set_base_outfmt_format(ctx, module_config, *param_data); 738 skl_set_base_outfmt_format(ctx, module_config, *param_data);
729 break; 739 break;
730 740
@@ -779,6 +789,7 @@ static int skl_alloc_queue(struct skl_module_pin *mpin,
779 mpin[i].in_use = true; 789 mpin[i].in_use = true;
780 mpin[i].id.module_id = id.module_id; 790 mpin[i].id.module_id = id.module_id;
781 mpin[i].id.instance_id = id.instance_id; 791 mpin[i].id.instance_id = id.instance_id;
792 mpin[i].id.pvt_id = id.pvt_id;
782 mpin[i].tgt_mcfg = tgt_cfg; 793 mpin[i].tgt_mcfg = tgt_cfg;
783 return i; 794 return i;
784 } 795 }
@@ -802,6 +813,7 @@ static void skl_free_queue(struct skl_module_pin *mpin, int q_index)
802 mpin[q_index].in_use = false; 813 mpin[q_index].in_use = false;
803 mpin[q_index].id.module_id = 0; 814 mpin[q_index].id.module_id = 0;
804 mpin[q_index].id.instance_id = 0; 815 mpin[q_index].id.instance_id = 0;
816 mpin[q_index].id.pvt_id = 0;
805 } 817 }
806 mpin[q_index].pin_state = SKL_PIN_UNBIND; 818 mpin[q_index].pin_state = SKL_PIN_UNBIND;
807 mpin[q_index].tgt_mcfg = NULL; 819 mpin[q_index].tgt_mcfg = NULL;
@@ -842,7 +854,7 @@ int skl_init_module(struct skl_sst *ctx,
842 struct skl_ipc_init_instance_msg msg; 854 struct skl_ipc_init_instance_msg msg;
843 855
844 dev_dbg(ctx->dev, "%s: module_id = %d instance=%d\n", __func__, 856 dev_dbg(ctx->dev, "%s: module_id = %d instance=%d\n", __func__,
845 mconfig->id.module_id, mconfig->id.instance_id); 857 mconfig->id.module_id, mconfig->id.pvt_id);
846 858
847 if (mconfig->pipe->state != SKL_PIPE_CREATED) { 859 if (mconfig->pipe->state != SKL_PIPE_CREATED) {
848 dev_err(ctx->dev, "Pipe not created state= %d pipe_id= %d\n", 860 dev_err(ctx->dev, "Pipe not created state= %d pipe_id= %d\n",
@@ -858,10 +870,11 @@ int skl_init_module(struct skl_sst *ctx,
858 } 870 }
859 871
860 msg.module_id = mconfig->id.module_id; 872 msg.module_id = mconfig->id.module_id;
861 msg.instance_id = mconfig->id.instance_id; 873 msg.instance_id = mconfig->id.pvt_id;
862 msg.ppl_instance_id = mconfig->pipe->ppl_id; 874 msg.ppl_instance_id = mconfig->pipe->ppl_id;
863 msg.param_data_size = module_config_size; 875 msg.param_data_size = module_config_size;
864 msg.core_id = mconfig->core_id; 876 msg.core_id = mconfig->core_id;
877 msg.domain = mconfig->domain;
865 878
866 ret = skl_ipc_init_instance(&ctx->ipc, &msg, param_data); 879 ret = skl_ipc_init_instance(&ctx->ipc, &msg, param_data);
867 if (ret < 0) { 880 if (ret < 0) {
@@ -878,9 +891,9 @@ static void skl_dump_bind_info(struct skl_sst *ctx, struct skl_module_cfg
878 *src_module, struct skl_module_cfg *dst_module) 891 *src_module, struct skl_module_cfg *dst_module)
879{ 892{
880 dev_dbg(ctx->dev, "%s: src module_id = %d src_instance=%d\n", 893 dev_dbg(ctx->dev, "%s: src module_id = %d src_instance=%d\n",
881 __func__, src_module->id.module_id, src_module->id.instance_id); 894 __func__, src_module->id.module_id, src_module->id.pvt_id);
882 dev_dbg(ctx->dev, "%s: dst_module=%d dst_instacne=%d\n", __func__, 895 dev_dbg(ctx->dev, "%s: dst_module=%d dst_instacne=%d\n", __func__,
883 dst_module->id.module_id, dst_module->id.instance_id); 896 dst_module->id.module_id, dst_module->id.pvt_id);
884 897
885 dev_dbg(ctx->dev, "src_module state = %d dst module state = %d\n", 898 dev_dbg(ctx->dev, "src_module state = %d dst module state = %d\n",
886 src_module->m_state, dst_module->m_state); 899 src_module->m_state, dst_module->m_state);
@@ -927,9 +940,9 @@ int skl_unbind_modules(struct skl_sst *ctx,
927 return 0; 940 return 0;
928 941
929 msg.module_id = src_mcfg->id.module_id; 942 msg.module_id = src_mcfg->id.module_id;
930 msg.instance_id = src_mcfg->id.instance_id; 943 msg.instance_id = src_mcfg->id.pvt_id;
931 msg.dst_module_id = dst_mcfg->id.module_id; 944 msg.dst_module_id = dst_mcfg->id.module_id;
932 msg.dst_instance_id = dst_mcfg->id.instance_id; 945 msg.dst_instance_id = dst_mcfg->id.pvt_id;
933 msg.bind = false; 946 msg.bind = false;
934 947
935 ret = skl_ipc_bind_unbind(&ctx->ipc, &msg); 948 ret = skl_ipc_bind_unbind(&ctx->ipc, &msg);
@@ -988,9 +1001,9 @@ int skl_bind_modules(struct skl_sst *ctx,
988 msg.src_queue, msg.dst_queue); 1001 msg.src_queue, msg.dst_queue);
989 1002
990 msg.module_id = src_mcfg->id.module_id; 1003 msg.module_id = src_mcfg->id.module_id;
991 msg.instance_id = src_mcfg->id.instance_id; 1004 msg.instance_id = src_mcfg->id.pvt_id;
992 msg.dst_module_id = dst_mcfg->id.module_id; 1005 msg.dst_module_id = dst_mcfg->id.module_id;
993 msg.dst_instance_id = dst_mcfg->id.instance_id; 1006 msg.dst_instance_id = dst_mcfg->id.pvt_id;
994 msg.bind = true; 1007 msg.bind = true;
995 1008
996 ret = skl_ipc_bind_unbind(&ctx->ipc, &msg); 1009 ret = skl_ipc_bind_unbind(&ctx->ipc, &msg);
@@ -1168,7 +1181,7 @@ int skl_set_module_params(struct skl_sst *ctx, u32 *params, int size,
1168 struct skl_ipc_large_config_msg msg; 1181 struct skl_ipc_large_config_msg msg;
1169 1182
1170 msg.module_id = mcfg->id.module_id; 1183 msg.module_id = mcfg->id.module_id;
1171 msg.instance_id = mcfg->id.instance_id; 1184 msg.instance_id = mcfg->id.pvt_id;
1172 msg.param_data_size = size; 1185 msg.param_data_size = size;
1173 msg.large_param_id = param_id; 1186 msg.large_param_id = param_id;
1174 1187
@@ -1181,7 +1194,7 @@ int skl_get_module_params(struct skl_sst *ctx, u32 *params, int size,
1181 struct skl_ipc_large_config_msg msg; 1194 struct skl_ipc_large_config_msg msg;
1182 1195
1183 msg.module_id = mcfg->id.module_id; 1196 msg.module_id = mcfg->id.module_id;
1184 msg.instance_id = mcfg->id.instance_id; 1197 msg.instance_id = mcfg->id.pvt_id;
1185 msg.param_data_size = size; 1198 msg.param_data_size = size;
1186 msg.large_param_id = param_id; 1199 msg.large_param_id = param_id;
1187 1200
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c
index 6e05bf8622f7..c7cdcba04c5d 100644
--- a/sound/soc/intel/skylake/skl-pcm.c
+++ b/sound/soc/intel/skylake/skl-pcm.c
@@ -106,7 +106,7 @@ static void skl_set_pcm_constrains(struct hdac_ext_bus *ebus,
106 106
107static enum hdac_ext_stream_type skl_get_host_stream_type(struct hdac_ext_bus *ebus) 107static enum hdac_ext_stream_type skl_get_host_stream_type(struct hdac_ext_bus *ebus)
108{ 108{
109 if (ebus->ppcap) 109 if ((ebus_to_hbus(ebus))->ppcap)
110 return HDAC_EXT_STREAM_TYPE_HOST; 110 return HDAC_EXT_STREAM_TYPE_HOST;
111 else 111 else
112 return HDAC_EXT_STREAM_TYPE_COUPLED; 112 return HDAC_EXT_STREAM_TYPE_COUPLED;
@@ -188,7 +188,7 @@ static int skl_get_format(struct snd_pcm_substream *substream,
188 struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev); 188 struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev);
189 int format_val = 0; 189 int format_val = 0;
190 190
191 if (ebus->ppcap) { 191 if ((ebus_to_hbus(ebus))->ppcap) {
192 struct snd_pcm_runtime *runtime = substream->runtime; 192 struct snd_pcm_runtime *runtime = substream->runtime;
193 193
194 format_val = snd_hdac_calc_stream_format(runtime->rate, 194 format_val = snd_hdac_calc_stream_format(runtime->rate,
@@ -648,7 +648,8 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
648 .channels_min = HDA_MONO, 648 .channels_min = HDA_MONO,
649 .channels_max = HDA_STEREO, 649 .channels_max = HDA_STEREO,
650 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_8000, 650 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_8000,
651 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 651 .formats = SNDRV_PCM_FMTBIT_S16_LE |
652 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
652 }, 653 },
653 .capture = { 654 .capture = {
654 .stream_name = "System Capture", 655 .stream_name = "System Capture",
@@ -1020,7 +1021,7 @@ static int skl_platform_pcm_trigger(struct snd_pcm_substream *substream,
1020{ 1021{
1021 struct hdac_ext_bus *ebus = get_bus_ctx(substream); 1022 struct hdac_ext_bus *ebus = get_bus_ctx(substream);
1022 1023
1023 if (!ebus->ppcap) 1024 if (!(ebus_to_hbus(ebus))->ppcap)
1024 return skl_coupled_trigger(substream, cmd); 1025 return skl_coupled_trigger(substream, cmd);
1025 1026
1026 return 0; 1027 return 0;
@@ -1138,20 +1139,67 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd)
1138 return retval; 1139 return retval;
1139} 1140}
1140 1141
1142static int skl_populate_modules(struct skl *skl)
1143{
1144 struct skl_pipeline *p;
1145 struct skl_pipe_module *m;
1146 struct snd_soc_dapm_widget *w;
1147 struct skl_module_cfg *mconfig;
1148 int ret;
1149
1150 list_for_each_entry(p, &skl->ppl_list, node) {
1151 list_for_each_entry(m, &p->pipe->w_list, node) {
1152
1153 w = m->w;
1154 mconfig = w->priv;
1155
1156 ret = snd_skl_get_module_info(skl->skl_sst, mconfig);
1157 if (ret < 0) {
1158 dev_err(skl->skl_sst->dev,
1159 "query module info failed:%d\n", ret);
1160 goto err;
1161 }
1162 }
1163 }
1164err:
1165 return ret;
1166}
1167
1141static int skl_platform_soc_probe(struct snd_soc_platform *platform) 1168static int skl_platform_soc_probe(struct snd_soc_platform *platform)
1142{ 1169{
1143 struct hdac_ext_bus *ebus = dev_get_drvdata(platform->dev); 1170 struct hdac_ext_bus *ebus = dev_get_drvdata(platform->dev);
1144 struct skl *skl = ebus_to_skl(ebus); 1171 struct skl *skl = ebus_to_skl(ebus);
1172 const struct skl_dsp_ops *ops;
1145 int ret; 1173 int ret;
1146 1174
1147 if (ebus->ppcap) { 1175 pm_runtime_get_sync(platform->dev);
1176 if ((ebus_to_hbus(ebus))->ppcap) {
1148 ret = skl_tplg_init(platform, ebus); 1177 ret = skl_tplg_init(platform, ebus);
1149 if (ret < 0) { 1178 if (ret < 0) {
1150 dev_err(platform->dev, "Failed to init topology!\n"); 1179 dev_err(platform->dev, "Failed to init topology!\n");
1151 return ret; 1180 return ret;
1152 } 1181 }
1153 skl->platform = platform; 1182 skl->platform = platform;
1183
1184 /* load the firmwares, since all is set */
1185 ops = skl_get_dsp_ops(skl->pci->device);
1186 if (!ops)
1187 return -EIO;
1188
1189 if (skl->skl_sst->is_first_boot == false) {
1190 dev_err(platform->dev, "DSP reports first boot done!!!\n");
1191 return -EIO;
1192 }
1193
1194 ret = ops->init_fw(platform->dev, skl->skl_sst);
1195 if (ret < 0) {
1196 dev_err(platform->dev, "Failed to boot first fw: %d\n", ret);
1197 return ret;
1198 }
1199 skl_populate_modules(skl);
1154 } 1200 }
1201 pm_runtime_mark_last_busy(platform->dev);
1202 pm_runtime_put_autosuspend(platform->dev);
1155 1203
1156 return 0; 1204 return 0;
1157} 1205}
diff --git a/sound/soc/intel/skylake/skl-sst-cldma.c b/sound/soc/intel/skylake/skl-sst-cldma.c
index da2329d17f4d..efa2532114ba 100644
--- a/sound/soc/intel/skylake/skl-sst-cldma.c
+++ b/sound/soc/intel/skylake/skl-sst-cldma.c
@@ -341,14 +341,14 @@ int skl_cldma_prepare(struct sst_dsp *ctx)
341 ret = ctx->dsp_ops.alloc_dma_buf(ctx->dev, 341 ret = ctx->dsp_ops.alloc_dma_buf(ctx->dev,
342 &ctx->cl_dev.dmab_data, ctx->cl_dev.bufsize); 342 &ctx->cl_dev.dmab_data, ctx->cl_dev.bufsize);
343 if (ret < 0) { 343 if (ret < 0) {
344 dev_err(ctx->dev, "Alloc buffer for base fw failed: %x", ret); 344 dev_err(ctx->dev, "Alloc buffer for base fw failed: %x\n", ret);
345 return ret; 345 return ret;
346 } 346 }
347 /* Setup Code loader BDL */ 347 /* Setup Code loader BDL */
348 ret = ctx->dsp_ops.alloc_dma_buf(ctx->dev, 348 ret = ctx->dsp_ops.alloc_dma_buf(ctx->dev,
349 &ctx->cl_dev.dmab_bdl, PAGE_SIZE); 349 &ctx->cl_dev.dmab_bdl, PAGE_SIZE);
350 if (ret < 0) { 350 if (ret < 0) {
351 dev_err(ctx->dev, "Alloc buffer for blde failed: %x", ret); 351 dev_err(ctx->dev, "Alloc buffer for blde failed: %x\n", ret);
352 ctx->dsp_ops.free_dma_buf(ctx->dev, &ctx->cl_dev.dmab_data); 352 ctx->dsp_ops.free_dma_buf(ctx->dev, &ctx->cl_dev.dmab_data);
353 return ret; 353 return ret;
354 } 354 }
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.h b/sound/soc/intel/skylake/skl-sst-dsp.h
index 0f8629ef79ac..b9e71d051fb1 100644
--- a/sound/soc/intel/skylake/skl-sst-dsp.h
+++ b/sound/soc/intel/skylake/skl-sst-dsp.h
@@ -20,6 +20,7 @@
20#include <sound/memalloc.h> 20#include <sound/memalloc.h>
21#include "skl-sst-cldma.h" 21#include "skl-sst-cldma.h"
22#include "skl-tplg-interface.h" 22#include "skl-tplg-interface.h"
23#include "skl-topology.h"
23 24
24struct sst_dsp; 25struct sst_dsp;
25struct skl_sst; 26struct skl_sst;
@@ -133,6 +134,8 @@ enum skl_dsp_states {
133struct skl_dsp_fw_ops { 134struct skl_dsp_fw_ops {
134 int (*load_fw)(struct sst_dsp *ctx); 135 int (*load_fw)(struct sst_dsp *ctx);
135 /* FW module parser/loader */ 136 /* FW module parser/loader */
137 int (*load_library)(struct sst_dsp *ctx,
138 struct skl_dfw_manifest *minfo);
136 int (*parse_fw)(struct sst_dsp *ctx); 139 int (*parse_fw)(struct sst_dsp *ctx);
137 int (*set_state_D0)(struct sst_dsp *ctx, unsigned int core_id); 140 int (*set_state_D0)(struct sst_dsp *ctx, unsigned int core_id);
138 int (*set_state_D3)(struct sst_dsp *ctx, unsigned int core_id); 141 int (*set_state_D3)(struct sst_dsp *ctx, unsigned int core_id);
@@ -203,12 +206,21 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
203int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, 206int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
204 const char *fw_name, struct skl_dsp_loader_ops dsp_ops, 207 const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
205 struct skl_sst **dsp); 208 struct skl_sst **dsp);
209int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx);
210int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx);
206void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); 211void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx);
207void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); 212void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx);
208 213
209int snd_skl_get_module_info(struct skl_sst *ctx, u8 *uuid, 214int snd_skl_get_module_info(struct skl_sst *ctx,
210 struct skl_dfw_module *dfw_config); 215 struct skl_module_cfg *mconfig);
211int snd_skl_parse_uuids(struct sst_dsp *ctx, unsigned int offset); 216int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw,
217 unsigned int offset, int index);
218int skl_get_pvt_id(struct skl_sst *ctx,
219 struct skl_module_cfg *mconfig);
220int skl_put_pvt_id(struct skl_sst *ctx,
221 struct skl_module_cfg *mconfig);
222int skl_get_pvt_instance_id_map(struct skl_sst *ctx,
223 int module_id, int instance_id);
212void skl_freeup_uuid_list(struct skl_sst *ctx); 224void skl_freeup_uuid_list(struct skl_sst *ctx);
213 225
214int skl_dsp_strip_extended_manifest(struct firmware *fw); 226int skl_dsp_strip_extended_manifest(struct firmware *fw);
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c
index 96f2f6889b18..0bd01e62622c 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.c
+++ b/sound/soc/intel/skylake/skl-sst-ipc.c
@@ -114,6 +114,11 @@
114#define IPC_CORE_ID(x) (((x) & IPC_CORE_ID_MASK) \ 114#define IPC_CORE_ID(x) (((x) & IPC_CORE_ID_MASK) \
115 << IPC_CORE_ID_SHIFT) 115 << IPC_CORE_ID_SHIFT)
116 116
117#define IPC_DOMAIN_SHIFT 28
118#define IPC_DOMAIN_MASK 0x1
119#define IPC_DOMAIN(x) (((x) & IPC_DOMAIN_MASK) \
120 << IPC_DOMAIN_SHIFT)
121
117/* Bind/Unbind message extension register */ 122/* Bind/Unbind message extension register */
118#define IPC_DST_MOD_ID_SHIFT 0 123#define IPC_DST_MOD_ID_SHIFT 0
119#define IPC_DST_MOD_ID(x) (((x) & IPC_MOD_ID_MASK) \ 124#define IPC_DST_MOD_ID(x) (((x) & IPC_MOD_ID_MASK) \
@@ -190,6 +195,7 @@ enum skl_ipc_glb_type {
190 IPC_GLB_GET_PPL_CONTEXT_SIZE = 21, 195 IPC_GLB_GET_PPL_CONTEXT_SIZE = 21,
191 IPC_GLB_SAVE_PPL = 22, 196 IPC_GLB_SAVE_PPL = 22,
192 IPC_GLB_RESTORE_PPL = 23, 197 IPC_GLB_RESTORE_PPL = 23,
198 IPC_GLB_LOAD_LIBRARY = 24,
193 IPC_GLB_NOTIFY = 26, 199 IPC_GLB_NOTIFY = 26,
194 IPC_GLB_MAX_IPC_MSG_NUMBER = 31 /* Maximum message number */ 200 IPC_GLB_MAX_IPC_MSG_NUMBER = 31 /* Maximum message number */
195}; 201};
@@ -338,7 +344,7 @@ static int skl_ipc_process_notification(struct sst_generic_ipc *ipc,
338 break; 344 break;
339 345
340 default: 346 default:
341 dev_err(ipc->dev, "ipc: Unhandled error msg=%x", 347 dev_err(ipc->dev, "ipc: Unhandled error msg=%x\n",
342 header.primary); 348 header.primary);
343 break; 349 break;
344 } 350 }
@@ -379,13 +385,13 @@ static void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
379 break; 385 break;
380 386
381 default: 387 default:
382 dev_err(ipc->dev, "Unknown ipc reply: 0x%x", reply); 388 dev_err(ipc->dev, "Unknown ipc reply: 0x%x\n", reply);
383 msg->errno = -EINVAL; 389 msg->errno = -EINVAL;
384 break; 390 break;
385 } 391 }
386 392
387 if (reply != IPC_GLB_REPLY_SUCCESS) { 393 if (reply != IPC_GLB_REPLY_SUCCESS) {
388 dev_err(ipc->dev, "ipc FW reply: reply=%d", reply); 394 dev_err(ipc->dev, "ipc FW reply: reply=%d\n", reply);
389 dev_err(ipc->dev, "FW Error Code: %u\n", 395 dev_err(ipc->dev, "FW Error Code: %u\n",
390 ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp)); 396 ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp));
391 } 397 }
@@ -434,9 +440,9 @@ irqreturn_t skl_dsp_irq_thread_handler(int irq, void *context)
434 hipcte = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCTE); 440 hipcte = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCTE);
435 header.primary = hipct; 441 header.primary = hipct;
436 header.extension = hipcte; 442 header.extension = hipcte;
437 dev_dbg(dsp->dev, "IPC irq: Firmware respond primary:%x", 443 dev_dbg(dsp->dev, "IPC irq: Firmware respond primary:%x\n",
438 header.primary); 444 header.primary);
439 dev_dbg(dsp->dev, "IPC irq: Firmware respond extension:%x", 445 dev_dbg(dsp->dev, "IPC irq: Firmware respond extension:%x\n",
440 header.extension); 446 header.extension);
441 447
442 if (IPC_GLB_NOTIFY_RSP_TYPE(header.primary)) { 448 if (IPC_GLB_NOTIFY_RSP_TYPE(header.primary)) {
@@ -704,6 +710,7 @@ int skl_ipc_init_instance(struct sst_generic_ipc *ipc,
704 header.extension = IPC_CORE_ID(msg->core_id); 710 header.extension = IPC_CORE_ID(msg->core_id);
705 header.extension |= IPC_PPL_INSTANCE_ID(msg->ppl_instance_id); 711 header.extension |= IPC_PPL_INSTANCE_ID(msg->ppl_instance_id);
706 header.extension |= IPC_PARAM_BLOCK_SIZE(param_block_size); 712 header.extension |= IPC_PARAM_BLOCK_SIZE(param_block_size);
713 header.extension |= IPC_DOMAIN(msg->domain);
707 714
708 dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__, 715 dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__,
709 header.primary, header.extension); 716 header.primary, header.extension);
@@ -742,7 +749,7 @@ int skl_ipc_bind_unbind(struct sst_generic_ipc *ipc,
742 header.extension); 749 header.extension);
743 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); 750 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0);
744 if (ret < 0) { 751 if (ret < 0) {
745 dev_err(ipc->dev, "ipc: bind/unbind faileden"); 752 dev_err(ipc->dev, "ipc: bind/unbind failed\n");
746 return ret; 753 return ret;
747 } 754 }
748 755
@@ -902,3 +909,25 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
902 return ret; 909 return ret;
903} 910}
904EXPORT_SYMBOL_GPL(skl_ipc_get_large_config); 911EXPORT_SYMBOL_GPL(skl_ipc_get_large_config);
912
913int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
914 u8 dma_id, u8 table_id)
915{
916 struct skl_ipc_header header = {0};
917 u64 *ipc_header = (u64 *)(&header);
918 int ret = 0;
919
920 header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
921 header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
922 header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_LIBRARY);
923 header.primary |= IPC_MOD_INSTANCE_ID(table_id);
924 header.primary |= IPC_MOD_ID(dma_id);
925
926 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0);
927
928 if (ret < 0)
929 dev_err(ipc->dev, "ipc: load lib failed\n");
930
931 return ret;
932}
933EXPORT_SYMBOL_GPL(skl_sst_ipc_load_library);
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.h b/sound/soc/intel/skylake/skl-sst-ipc.h
index 2e3d4e80ef97..0334ed4af031 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.h
+++ b/sound/soc/intel/skylake/skl-sst-ipc.h
@@ -66,7 +66,7 @@ struct skl_sst {
66 66
67 /* callback for miscbdge */ 67 /* callback for miscbdge */
68 void (*enable_miscbdcge)(struct device *dev, bool enable); 68 void (*enable_miscbdcge)(struct device *dev, bool enable);
69 /*Is CGCTL.MISCBDCGE disabled*/ 69 /* Is CGCTL.MISCBDCGE disabled */
70 bool miscbdcg_disabled; 70 bool miscbdcg_disabled;
71 71
72 /* Populate module information */ 72 /* Populate module information */
@@ -75,8 +75,14 @@ struct skl_sst {
75 /* Is firmware loaded */ 75 /* Is firmware loaded */
76 bool fw_loaded; 76 bool fw_loaded;
77 77
78 /* first boot ? */
79 bool is_first_boot;
80
78 /* multi-core */ 81 /* multi-core */
79 struct skl_dsp_cores cores; 82 struct skl_dsp_cores cores;
83
84 /* tplg manifest */
85 struct skl_dfw_manifest manifest;
80}; 86};
81 87
82struct skl_ipc_init_instance_msg { 88struct skl_ipc_init_instance_msg {
@@ -85,6 +91,7 @@ struct skl_ipc_init_instance_msg {
85 u16 param_data_size; 91 u16 param_data_size;
86 u8 ppl_instance_id; 92 u8 ppl_instance_id;
87 u8 core_id; 93 u8 core_id;
94 u8 domain;
88}; 95};
89 96
90struct skl_ipc_bind_unbind_msg { 97struct skl_ipc_bind_unbind_msg {
@@ -145,6 +152,9 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
145int skl_ipc_get_large_config(struct sst_generic_ipc *ipc, 152int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
146 struct skl_ipc_large_config_msg *msg, u32 *param); 153 struct skl_ipc_large_config_msg *msg, u32 *param);
147 154
155int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
156 u8 dma_id, u8 table_id);
157
148void skl_ipc_int_enable(struct sst_dsp *dsp); 158void skl_ipc_int_enable(struct sst_dsp *dsp);
149void skl_ipc_op_int_enable(struct sst_dsp *ctx); 159void skl_ipc_op_int_enable(struct sst_dsp *ctx);
150void skl_ipc_op_int_disable(struct sst_dsp *ctx); 160void skl_ipc_op_int_disable(struct sst_dsp *ctx);
diff --git a/sound/soc/intel/skylake/skl-sst-utils.c b/sound/soc/intel/skylake/skl-sst-utils.c
index ddcb52a51854..8dc03039b311 100644
--- a/sound/soc/intel/skylake/skl-sst-utils.c
+++ b/sound/soc/intel/skylake/skl-sst-utils.c
@@ -28,11 +28,6 @@
28/* FW Extended Manifest Header id = $AE1 */ 28/* FW Extended Manifest Header id = $AE1 */
29#define SKL_EXT_MANIFEST_HEADER_MAGIC 0x31454124 29#define SKL_EXT_MANIFEST_HEADER_MAGIC 0x31454124
30 30
31struct skl_dfw_module_mod {
32 char name[100];
33 struct skl_dfw_module skl_dfw_mod;
34};
35
36struct UUID { 31struct UUID {
37 u8 id[16]; 32 u8 id[16];
38}; 33};
@@ -99,10 +94,15 @@ struct adsp_fw_hdr {
99 u32 load_offset; 94 u32 load_offset;
100} __packed; 95} __packed;
101 96
97#define MAX_INSTANCE_BUFF 2
98
102struct uuid_module { 99struct uuid_module {
103 uuid_le uuid; 100 uuid_le uuid;
104 int id; 101 int id;
105 int is_loadable; 102 int is_loadable;
103 int max_instance;
104 u64 pvt_id[MAX_INSTANCE_BUFF];
105 int *instance_id;
106 106
107 struct list_head list; 107 struct list_head list;
108}; 108};
@@ -115,13 +115,13 @@ struct skl_ext_manifest_hdr {
115 u32 entries; 115 u32 entries;
116}; 116};
117 117
118int snd_skl_get_module_info(struct skl_sst *ctx, u8 *uuid, 118int snd_skl_get_module_info(struct skl_sst *ctx,
119 struct skl_dfw_module *dfw_config) 119 struct skl_module_cfg *mconfig)
120{ 120{
121 struct uuid_module *module; 121 struct uuid_module *module;
122 uuid_le *uuid_mod; 122 uuid_le *uuid_mod;
123 123
124 uuid_mod = (uuid_le *)uuid; 124 uuid_mod = (uuid_le *)mconfig->guid;
125 125
126 if (list_empty(&ctx->uuid_list)) { 126 if (list_empty(&ctx->uuid_list)) {
127 dev_err(ctx->dev, "Module list is empty\n"); 127 dev_err(ctx->dev, "Module list is empty\n");
@@ -130,8 +130,8 @@ int snd_skl_get_module_info(struct skl_sst *ctx, u8 *uuid,
130 130
131 list_for_each_entry(module, &ctx->uuid_list, list) { 131 list_for_each_entry(module, &ctx->uuid_list, list) {
132 if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) { 132 if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) {
133 dfw_config->module_id = module->id; 133 mconfig->id.module_id = module->id;
134 dfw_config->is_loadable = module->is_loadable; 134 mconfig->is_loadable = module->is_loadable;
135 135
136 return 0; 136 return 0;
137 } 137 }
@@ -141,15 +141,154 @@ int snd_skl_get_module_info(struct skl_sst *ctx, u8 *uuid,
141} 141}
142EXPORT_SYMBOL_GPL(snd_skl_get_module_info); 142EXPORT_SYMBOL_GPL(snd_skl_get_module_info);
143 143
144static int skl_get_pvtid_map(struct uuid_module *module, int instance_id)
145{
146 int pvt_id;
147
148 for (pvt_id = 0; pvt_id < module->max_instance; pvt_id++) {
149 if (module->instance_id[pvt_id] == instance_id)
150 return pvt_id;
151 }
152 return -EINVAL;
153}
154
155int skl_get_pvt_instance_id_map(struct skl_sst *ctx,
156 int module_id, int instance_id)
157{
158 struct uuid_module *module;
159
160 list_for_each_entry(module, &ctx->uuid_list, list) {
161 if (module->id == module_id)
162 return skl_get_pvtid_map(module, instance_id);
163 }
164
165 return -EINVAL;
166}
167EXPORT_SYMBOL_GPL(skl_get_pvt_instance_id_map);
168
169static inline int skl_getid_32(struct uuid_module *module, u64 *val,
170 int word1_mask, int word2_mask)
171{
172 int index, max_inst, pvt_id;
173 u32 mask_val;
174
175 max_inst = module->max_instance;
176 mask_val = (u32)(*val >> word1_mask);
177
178 if (mask_val != 0xffffffff) {
179 index = ffz(mask_val);
180 pvt_id = index + word1_mask + word2_mask;
181 if (pvt_id <= (max_inst - 1)) {
182 *val |= 1 << (index + word1_mask);
183 return pvt_id;
184 }
185 }
186
187 return -EINVAL;
188}
189
190static inline int skl_pvtid_128(struct uuid_module *module)
191{
192 int j, i, word1_mask, word2_mask = 0, pvt_id;
193
194 for (j = 0; j < MAX_INSTANCE_BUFF; j++) {
195 word1_mask = 0;
196
197 for (i = 0; i < 2; i++) {
198 pvt_id = skl_getid_32(module, &module->pvt_id[j],
199 word1_mask, word2_mask);
200 if (pvt_id >= 0)
201 return pvt_id;
202
203 word1_mask += 32;
204 if ((word1_mask + word2_mask) >= module->max_instance)
205 return -EINVAL;
206 }
207
208 word2_mask += 64;
209 if (word2_mask >= module->max_instance)
210 return -EINVAL;
211 }
212
213 return -EINVAL;
214}
215
216/**
217 * skl_get_pvt_id: generate a private id for use as module id
218 *
219 * @ctx: driver context
220 * @mconfig: module configuration data
221 *
222 * This generates a 128 bit private unique id for a module TYPE so that
223 * module instance is unique
224 */
225int skl_get_pvt_id(struct skl_sst *ctx, struct skl_module_cfg *mconfig)
226{
227 struct uuid_module *module;
228 uuid_le *uuid_mod;
229 int pvt_id;
230
231 uuid_mod = (uuid_le *)mconfig->guid;
232
233 list_for_each_entry(module, &ctx->uuid_list, list) {
234 if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) {
235
236 pvt_id = skl_pvtid_128(module);
237 if (pvt_id >= 0) {
238 module->instance_id[pvt_id] =
239 mconfig->id.instance_id;
240 return pvt_id;
241 }
242 }
243 }
244
245 return -EINVAL;
246}
247EXPORT_SYMBOL_GPL(skl_get_pvt_id);
248
249/**
250 * skl_put_pvt_id: free up the private id allocated
251 *
252 * @ctx: driver context
253 * @mconfig: module configuration data
254 *
255 * This frees a 128 bit private unique id previously generated
256 */
257int skl_put_pvt_id(struct skl_sst *ctx, struct skl_module_cfg *mconfig)
258{
259 int i;
260 uuid_le *uuid_mod;
261 struct uuid_module *module;
262
263 uuid_mod = (uuid_le *)mconfig->guid;
264 list_for_each_entry(module, &ctx->uuid_list, list) {
265 if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) {
266
267 if (mconfig->id.pvt_id != 0)
268 i = (mconfig->id.pvt_id) / 64;
269 else
270 i = 0;
271
272 module->pvt_id[i] &= ~(1 << (mconfig->id.pvt_id));
273 mconfig->id.pvt_id = -1;
274 return 0;
275 }
276 }
277
278 return -EINVAL;
279}
280EXPORT_SYMBOL_GPL(skl_put_pvt_id);
281
144/* 282/*
145 * Parse the firmware binary to get the UUID, module id 283 * Parse the firmware binary to get the UUID, module id
146 * and loadable flags 284 * and loadable flags
147 */ 285 */
148int snd_skl_parse_uuids(struct sst_dsp *ctx, unsigned int offset) 286int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw,
287 unsigned int offset, int index)
149{ 288{
150 struct adsp_fw_hdr *adsp_hdr; 289 struct adsp_fw_hdr *adsp_hdr;
151 struct adsp_module_entry *mod_entry; 290 struct adsp_module_entry *mod_entry;
152 int i, num_entry; 291 int i, num_entry, size;
153 uuid_le *uuid_bin; 292 uuid_le *uuid_bin;
154 const char *buf; 293 const char *buf;
155 struct skl_sst *skl = ctx->thread_context; 294 struct skl_sst *skl = ctx->thread_context;
@@ -158,8 +297,8 @@ int snd_skl_parse_uuids(struct sst_dsp *ctx, unsigned int offset)
158 unsigned int safe_file; 297 unsigned int safe_file;
159 298
160 /* Get the FW pointer to derive ADSP header */ 299 /* Get the FW pointer to derive ADSP header */
161 stripped_fw.data = ctx->fw->data; 300 stripped_fw.data = fw->data;
162 stripped_fw.size = ctx->fw->size; 301 stripped_fw.size = fw->size;
163 302
164 skl_dsp_strip_extended_manifest(&stripped_fw); 303 skl_dsp_strip_extended_manifest(&stripped_fw);
165 304
@@ -210,8 +349,15 @@ int snd_skl_parse_uuids(struct sst_dsp *ctx, unsigned int offset)
210 uuid_bin = (uuid_le *)mod_entry->uuid.id; 349 uuid_bin = (uuid_le *)mod_entry->uuid.id;
211 memcpy(&module->uuid, uuid_bin, sizeof(module->uuid)); 350 memcpy(&module->uuid, uuid_bin, sizeof(module->uuid));
212 351
213 module->id = i; 352 module->id = (i | (index << 12));
214 module->is_loadable = mod_entry->type.load_type; 353 module->is_loadable = mod_entry->type.load_type;
354 module->max_instance = mod_entry->instance_max_count;
355 size = sizeof(int) * mod_entry->instance_max_count;
356 module->instance_id = devm_kzalloc(ctx->dev, size, GFP_KERNEL);
357 if (!module->instance_id) {
358 kfree(module);
359 return -ENOMEM;
360 }
215 361
216 list_add_tail(&module->list, &skl->uuid_list); 362 list_add_tail(&module->list, &skl->uuid_list);
217 363
diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c
index 588f899ceb65..8fc3178bc79c 100644
--- a/sound/soc/intel/skylake/skl-sst.c
+++ b/sound/soc/intel/skylake/skl-sst.c
@@ -88,13 +88,15 @@ static int skl_load_base_firmware(struct sst_dsp *ctx)
88 } 88 }
89 } 89 }
90 90
91 ret = snd_skl_parse_uuids(ctx, SKL_ADSP_FW_BIN_HDR_OFFSET); 91 /* prase uuids on first boot */
92 if (ret < 0) { 92 if (skl->is_first_boot) {
93 dev_err(ctx->dev, 93 ret = snd_skl_parse_uuids(ctx, ctx->fw, SKL_ADSP_FW_BIN_HDR_OFFSET, 0);
94 "UUID parsing err: %d\n", ret); 94 if (ret < 0) {
95 release_firmware(ctx->fw); 95 dev_err(ctx->dev, "UUID parsing err: %d\n", ret);
96 skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK); 96 release_firmware(ctx->fw);
97 return ret; 97 skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK);
98 return ret;
99 }
98 } 100 }
99 101
100 /* check for extended manifest */ 102 /* check for extended manifest */
@@ -105,13 +107,13 @@ static int skl_load_base_firmware(struct sst_dsp *ctx)
105 107
106 ret = skl_dsp_boot(ctx); 108 ret = skl_dsp_boot(ctx);
107 if (ret < 0) { 109 if (ret < 0) {
108 dev_err(ctx->dev, "Boot dsp core failed ret: %d", ret); 110 dev_err(ctx->dev, "Boot dsp core failed ret: %d\n", ret);
109 goto skl_load_base_firmware_failed; 111 goto skl_load_base_firmware_failed;
110 } 112 }
111 113
112 ret = skl_cldma_prepare(ctx); 114 ret = skl_cldma_prepare(ctx);
113 if (ret < 0) { 115 if (ret < 0) {
114 dev_err(ctx->dev, "CL dma prepare failed : %d", ret); 116 dev_err(ctx->dev, "CL dma prepare failed : %d\n", ret);
115 goto skl_load_base_firmware_failed; 117 goto skl_load_base_firmware_failed;
116 } 118 }
117 119
@@ -484,25 +486,32 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
484 return ret; 486 return ret;
485 487
486 skl->cores.count = 2; 488 skl->cores.count = 2;
489 skl->is_first_boot = true;
490
491 if (dsp)
492 *dsp = skl;
493
494 return ret;
495}
496EXPORT_SYMBOL_GPL(skl_sst_dsp_init);
497
498int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx)
499{
500 int ret;
501 struct sst_dsp *sst = ctx->dsp;
487 502
488 ret = sst->fw_ops.load_fw(sst); 503 ret = sst->fw_ops.load_fw(sst);
489 if (ret < 0) { 504 if (ret < 0) {
490 dev_err(dev, "Load base fw failed : %d", ret); 505 dev_err(dev, "Load base fw failed : %d\n", ret);
491 goto cleanup; 506 return ret;
492 } 507 }
493 508
494 skl_dsp_init_core_state(sst); 509 skl_dsp_init_core_state(sst);
510 ctx->is_first_boot = false;
495 511
496 if (dsp) 512 return 0;
497 *dsp = skl;
498
499 return ret;
500
501cleanup:
502 skl_sst_dsp_cleanup(dev, skl);
503 return ret;
504} 513}
505EXPORT_SYMBOL_GPL(skl_sst_dsp_init); 514EXPORT_SYMBOL_GPL(skl_sst_init_fw);
506 515
507void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) 516void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx)
508{ 517{
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
index cc0150fc2601..b5b1934d8550 100644
--- a/sound/soc/intel/skylake/skl-topology.c
+++ b/sound/soc/intel/skylake/skl-topology.c
@@ -21,6 +21,7 @@
21#include <linux/firmware.h> 21#include <linux/firmware.h>
22#include <sound/soc.h> 22#include <sound/soc.h>
23#include <sound/soc-topology.h> 23#include <sound/soc-topology.h>
24#include <uapi/sound/snd_sst_tokens.h>
24#include "skl-sst-dsp.h" 25#include "skl-sst-dsp.h"
25#include "skl-sst-ipc.h" 26#include "skl-sst-ipc.h"
26#include "skl-topology.h" 27#include "skl-topology.h"
@@ -32,6 +33,8 @@
32#define SKL_CH_FIXUP_MASK (1 << 0) 33#define SKL_CH_FIXUP_MASK (1 << 0)
33#define SKL_RATE_FIXUP_MASK (1 << 1) 34#define SKL_RATE_FIXUP_MASK (1 << 1)
34#define SKL_FMT_FIXUP_MASK (1 << 2) 35#define SKL_FMT_FIXUP_MASK (1 << 2)
36#define SKL_IN_DIR_BIT_MASK BIT(0)
37#define SKL_PIN_COUNT_MASK GENMASK(7, 4)
35 38
36/* 39/*
37 * SKL DSP driver modelling uses only few DAPM widgets so for rest we will 40 * SKL DSP driver modelling uses only few DAPM widgets so for rest we will
@@ -473,6 +476,14 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
473 w = w_module->w; 476 w = w_module->w;
474 mconfig = w->priv; 477 mconfig = w->priv;
475 478
479 /* check if module ids are populated */
480 if (mconfig->id.module_id < 0) {
481 dev_err(skl->skl_sst->dev,
482 "module %pUL id not populated\n",
483 (uuid_le *)mconfig->guid);
484 return -EIO;
485 }
486
476 /* check resource available */ 487 /* check resource available */
477 if (!skl_is_pipe_mcps_avail(skl, mconfig)) 488 if (!skl_is_pipe_mcps_avail(skl, mconfig))
478 return -ENOMEM; 489 return -ENOMEM;
@@ -494,12 +505,15 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
494 * FE/BE params 505 * FE/BE params
495 */ 506 */
496 skl_tplg_update_module_params(w, ctx); 507 skl_tplg_update_module_params(w, ctx);
497 508 mconfig->id.pvt_id = skl_get_pvt_id(ctx, mconfig);
509 if (mconfig->id.pvt_id < 0)
510 return ret;
498 skl_tplg_set_module_init_data(w); 511 skl_tplg_set_module_init_data(w);
499 ret = skl_init_module(ctx, mconfig); 512 ret = skl_init_module(ctx, mconfig);
500 if (ret < 0) 513 if (ret < 0) {
514 skl_put_pvt_id(ctx, mconfig);
501 return ret; 515 return ret;
502 516 }
503 skl_tplg_alloc_pipe_mcps(skl, mconfig); 517 skl_tplg_alloc_pipe_mcps(skl, mconfig);
504 ret = skl_tplg_set_module_params(w, ctx); 518 ret = skl_tplg_set_module_params(w, ctx);
505 if (ret < 0) 519 if (ret < 0)
@@ -512,6 +526,7 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
512static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx, 526static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx,
513 struct skl_pipe *pipe) 527 struct skl_pipe *pipe)
514{ 528{
529 int ret;
515 struct skl_pipe_module *w_module = NULL; 530 struct skl_pipe_module *w_module = NULL;
516 struct skl_module_cfg *mconfig = NULL; 531 struct skl_module_cfg *mconfig = NULL;
517 532
@@ -519,9 +534,13 @@ static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx,
519 mconfig = w_module->w->priv; 534 mconfig = w_module->w->priv;
520 535
521 if (mconfig->is_loadable && ctx->dsp->fw_ops.unload_mod && 536 if (mconfig->is_loadable && ctx->dsp->fw_ops.unload_mod &&
522 mconfig->m_state > SKL_MODULE_UNINIT) 537 mconfig->m_state > SKL_MODULE_UNINIT) {
523 return ctx->dsp->fw_ops.unload_mod(ctx->dsp, 538 ret = ctx->dsp->fw_ops.unload_mod(ctx->dsp,
524 mconfig->id.module_id); 539 mconfig->id.module_id);
540 if (ret < 0)
541 return -EIO;
542 }
543 skl_put_pvt_id(ctx, mconfig);
525 } 544 }
526 545
527 /* no modules to unload in this path, so return */ 546 /* no modules to unload in this path, so return */
@@ -588,6 +607,26 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
588 return 0; 607 return 0;
589} 608}
590 609
610static int skl_fill_sink_instance_id(struct skl_sst *ctx,
611 struct skl_algo_data *alg_data)
612{
613 struct skl_kpb_params *params = (struct skl_kpb_params *)alg_data->params;
614 struct skl_mod_inst_map *inst;
615 int i, pvt_id;
616
617 inst = params->map;
618
619 for (i = 0; i < params->num_modules; i++) {
620 pvt_id = skl_get_pvt_instance_id_map(ctx,
621 inst->mod_id, inst->inst_id);
622 if (pvt_id < 0)
623 return -EINVAL;
624 inst->inst_id = pvt_id;
625 inst++;
626 }
627 return 0;
628}
629
591/* 630/*
592 * Some modules require params to be set after the module is bound to 631 * Some modules require params to be set after the module is bound to
593 * all pins connected. 632 * all pins connected.
@@ -636,6 +675,8 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w,
636 bc = (struct skl_algo_data *)sb->dobj.private; 675 bc = (struct skl_algo_data *)sb->dobj.private;
637 676
638 if (bc->set_params == SKL_PARAM_BIND) { 677 if (bc->set_params == SKL_PARAM_BIND) {
678 if (mconfig->m_type == SKL_MODULE_TYPE_KPB)
679 skl_fill_sink_instance_id(ctx, bc);
639 ret = skl_set_module_params(ctx, 680 ret = skl_set_module_params(ctx,
640 (u32 *)bc->params, bc->max, 681 (u32 *)bc->params, bc->max,
641 bc->param_id, mconfig); 682 bc->param_id, mconfig);
@@ -1460,85 +1501,570 @@ static const struct snd_soc_tplg_bytes_ext_ops skl_tlv_ops[] = {
1460 skl_tplg_tlv_control_set}, 1501 skl_tplg_tlv_control_set},
1461}; 1502};
1462 1503
1463/* 1504static int skl_tplg_fill_pipe_tkn(struct device *dev,
1464 * The topology binary passes the pin info for a module so initialize the pin 1505 struct skl_pipe *pipe, u32 tkn,
1465 * info passed into module instance 1506 u32 tkn_val)
1466 */
1467static void skl_fill_module_pin_info(struct skl_dfw_module_pin *dfw_pin,
1468 struct skl_module_pin *m_pin,
1469 bool is_dynamic, int max_pin)
1470{ 1507{
1471 int i;
1472 1508
1473 for (i = 0; i < max_pin; i++) { 1509 switch (tkn) {
1474 m_pin[i].id.module_id = dfw_pin[i].module_id; 1510 case SKL_TKN_U32_PIPE_CONN_TYPE:
1475 m_pin[i].id.instance_id = dfw_pin[i].instance_id; 1511 pipe->conn_type = tkn_val;
1476 m_pin[i].in_use = false; 1512 break;
1477 m_pin[i].is_dynamic = is_dynamic; 1513
1478 m_pin[i].pin_state = SKL_PIN_UNBIND; 1514 case SKL_TKN_U32_PIPE_PRIORITY:
1515 pipe->pipe_priority = tkn_val;
1516 break;
1517
1518 case SKL_TKN_U32_PIPE_MEM_PGS:
1519 pipe->memory_pages = tkn_val;
1520 break;
1521
1522 default:
1523 dev_err(dev, "Token not handled %d\n", tkn);
1524 return -EINVAL;
1479 } 1525 }
1526
1527 return 0;
1480} 1528}
1481 1529
1482/* 1530/*
1483 * Add pipeline from topology binary into driver pipeline list 1531 * Add pipeline by parsing the relevant tokens
1484 * 1532 * Return an existing pipe if the pipe already exists.
1485 * If already added we return that instance
1486 * Otherwise we create a new instance and add into driver list
1487 */ 1533 */
1488static struct skl_pipe *skl_tplg_add_pipe(struct device *dev, 1534static int skl_tplg_add_pipe(struct device *dev,
1489 struct skl *skl, struct skl_dfw_pipe *dfw_pipe) 1535 struct skl_module_cfg *mconfig, struct skl *skl,
1536 struct snd_soc_tplg_vendor_value_elem *tkn_elem)
1490{ 1537{
1491 struct skl_pipeline *ppl; 1538 struct skl_pipeline *ppl;
1492 struct skl_pipe *pipe; 1539 struct skl_pipe *pipe;
1493 struct skl_pipe_params *params; 1540 struct skl_pipe_params *params;
1494 1541
1495 list_for_each_entry(ppl, &skl->ppl_list, node) { 1542 list_for_each_entry(ppl, &skl->ppl_list, node) {
1496 if (ppl->pipe->ppl_id == dfw_pipe->pipe_id) 1543 if (ppl->pipe->ppl_id == tkn_elem->value) {
1497 return ppl->pipe; 1544 mconfig->pipe = ppl->pipe;
1545 return EEXIST;
1546 }
1498 } 1547 }
1499 1548
1500 ppl = devm_kzalloc(dev, sizeof(*ppl), GFP_KERNEL); 1549 ppl = devm_kzalloc(dev, sizeof(*ppl), GFP_KERNEL);
1501 if (!ppl) 1550 if (!ppl)
1502 return NULL; 1551 return -ENOMEM;
1503 1552
1504 pipe = devm_kzalloc(dev, sizeof(*pipe), GFP_KERNEL); 1553 pipe = devm_kzalloc(dev, sizeof(*pipe), GFP_KERNEL);
1505 if (!pipe) 1554 if (!pipe)
1506 return NULL; 1555 return -ENOMEM;
1507 1556
1508 params = devm_kzalloc(dev, sizeof(*params), GFP_KERNEL); 1557 params = devm_kzalloc(dev, sizeof(*params), GFP_KERNEL);
1509 if (!params) 1558 if (!params)
1510 return NULL; 1559 return -ENOMEM;
1511 1560
1512 pipe->ppl_id = dfw_pipe->pipe_id;
1513 pipe->memory_pages = dfw_pipe->memory_pages;
1514 pipe->pipe_priority = dfw_pipe->pipe_priority;
1515 pipe->conn_type = dfw_pipe->conn_type;
1516 pipe->state = SKL_PIPE_INVALID;
1517 pipe->p_params = params; 1561 pipe->p_params = params;
1562 pipe->ppl_id = tkn_elem->value;
1518 INIT_LIST_HEAD(&pipe->w_list); 1563 INIT_LIST_HEAD(&pipe->w_list);
1519 1564
1520 ppl->pipe = pipe; 1565 ppl->pipe = pipe;
1521 list_add(&ppl->node, &skl->ppl_list); 1566 list_add(&ppl->node, &skl->ppl_list);
1522 1567
1523 return ppl->pipe; 1568 mconfig->pipe = pipe;
1569 mconfig->pipe->state = SKL_PIPE_INVALID;
1570
1571 return 0;
1572}
1573
1574static int skl_tplg_fill_pin(struct device *dev, u32 tkn,
1575 struct skl_module_pin *m_pin,
1576 int pin_index, u32 value)
1577{
1578 switch (tkn) {
1579 case SKL_TKN_U32_PIN_MOD_ID:
1580 m_pin[pin_index].id.module_id = value;
1581 break;
1582
1583 case SKL_TKN_U32_PIN_INST_ID:
1584 m_pin[pin_index].id.instance_id = value;
1585 break;
1586
1587 default:
1588 dev_err(dev, "%d Not a pin token\n", value);
1589 return -EINVAL;
1590 }
1591
1592 return 0;
1593}
1594
1595/*
1596 * Parse for pin config specific tokens to fill up the
1597 * module private data
1598 */
1599static int skl_tplg_fill_pins_info(struct device *dev,
1600 struct skl_module_cfg *mconfig,
1601 struct snd_soc_tplg_vendor_value_elem *tkn_elem,
1602 int dir, int pin_count)
1603{
1604 int ret;
1605 struct skl_module_pin *m_pin;
1606
1607 switch (dir) {
1608 case SKL_DIR_IN:
1609 m_pin = mconfig->m_in_pin;
1610 break;
1611
1612 case SKL_DIR_OUT:
1613 m_pin = mconfig->m_out_pin;
1614 break;
1615
1616 default:
1617 dev_err(dev, "Invalid direction value\n");
1618 return -EINVAL;
1619 }
1620
1621 ret = skl_tplg_fill_pin(dev, tkn_elem->token,
1622 m_pin, pin_count, tkn_elem->value);
1623
1624 if (ret < 0)
1625 return ret;
1626
1627 m_pin[pin_count].in_use = false;
1628 m_pin[pin_count].pin_state = SKL_PIN_UNBIND;
1629
1630 return 0;
1631}
1632
1633/*
1634 * Fill up input/output module config format based
1635 * on the direction
1636 */
1637static int skl_tplg_fill_fmt(struct device *dev,
1638 struct skl_module_cfg *mconfig, u32 tkn,
1639 u32 value, u32 dir, u32 pin_count)
1640{
1641 struct skl_module_fmt *dst_fmt;
1642
1643 switch (dir) {
1644 case SKL_DIR_IN:
1645 dst_fmt = mconfig->in_fmt;
1646 dst_fmt += pin_count;
1647 break;
1648
1649 case SKL_DIR_OUT:
1650 dst_fmt = mconfig->out_fmt;
1651 dst_fmt += pin_count;
1652 break;
1653
1654 default:
1655 dev_err(dev, "Invalid direction value\n");
1656 return -EINVAL;
1657 }
1658
1659 switch (tkn) {
1660 case SKL_TKN_U32_FMT_CH:
1661 dst_fmt->channels = value;
1662 break;
1663
1664 case SKL_TKN_U32_FMT_FREQ:
1665 dst_fmt->s_freq = value;
1666 break;
1667
1668 case SKL_TKN_U32_FMT_BIT_DEPTH:
1669 dst_fmt->bit_depth = value;
1670 break;
1671
1672 case SKL_TKN_U32_FMT_SAMPLE_SIZE:
1673 dst_fmt->valid_bit_depth = value;
1674 break;
1675
1676 case SKL_TKN_U32_FMT_CH_CONFIG:
1677 dst_fmt->ch_cfg = value;
1678 break;
1679
1680 case SKL_TKN_U32_FMT_INTERLEAVE:
1681 dst_fmt->interleaving_style = value;
1682 break;
1683
1684 case SKL_TKN_U32_FMT_SAMPLE_TYPE:
1685 dst_fmt->sample_type = value;
1686 break;
1687
1688 case SKL_TKN_U32_FMT_CH_MAP:
1689 dst_fmt->ch_map = value;
1690 break;
1691
1692 default:
1693 dev_err(dev, "Invalid token %d\n", tkn);
1694 return -EINVAL;
1695 }
1696
1697 return 0;
1524} 1698}
1525 1699
1526static void skl_tplg_fill_fmt(struct skl_module_fmt *dst_fmt, 1700static int skl_tplg_get_uuid(struct device *dev, struct skl_module_cfg *mconfig,
1527 struct skl_dfw_module_fmt *src_fmt, 1701 struct snd_soc_tplg_vendor_uuid_elem *uuid_tkn)
1528 int pins) 1702{
1703 if (uuid_tkn->token == SKL_TKN_UUID)
1704 memcpy(&mconfig->guid, &uuid_tkn->uuid, 16);
1705 else {
1706 dev_err(dev, "Not an UUID token tkn %d\n", uuid_tkn->token);
1707 return -EINVAL;
1708 }
1709
1710 return 0;
1711}
1712
1713static void skl_tplg_fill_pin_dynamic_val(
1714 struct skl_module_pin *mpin, u32 pin_count, u32 value)
1529{ 1715{
1530 int i; 1716 int i;
1531 1717
1532 for (i = 0; i < pins; i++) { 1718 for (i = 0; i < pin_count; i++)
1533 dst_fmt[i].channels = src_fmt[i].channels; 1719 mpin[i].is_dynamic = value;
1534 dst_fmt[i].s_freq = src_fmt[i].freq; 1720}
1535 dst_fmt[i].bit_depth = src_fmt[i].bit_depth; 1721
1536 dst_fmt[i].valid_bit_depth = src_fmt[i].valid_bit_depth; 1722/*
1537 dst_fmt[i].ch_cfg = src_fmt[i].ch_cfg; 1723 * Parse tokens to fill up the module private data
1538 dst_fmt[i].ch_map = src_fmt[i].ch_map; 1724 */
1539 dst_fmt[i].interleaving_style = src_fmt[i].interleaving_style; 1725static int skl_tplg_get_token(struct device *dev,
1540 dst_fmt[i].sample_type = src_fmt[i].sample_type; 1726 struct snd_soc_tplg_vendor_value_elem *tkn_elem,
1727 struct skl *skl, struct skl_module_cfg *mconfig)
1728{
1729 int tkn_count = 0;
1730 int ret;
1731 static int is_pipe_exists;
1732 static int pin_index, dir;
1733
1734 if (tkn_elem->token > SKL_TKN_MAX)
1735 return -EINVAL;
1736
1737 switch (tkn_elem->token) {
1738 case SKL_TKN_U8_IN_QUEUE_COUNT:
1739 mconfig->max_in_queue = tkn_elem->value;
1740 mconfig->m_in_pin = devm_kzalloc(dev, mconfig->max_in_queue *
1741 sizeof(*mconfig->m_in_pin),
1742 GFP_KERNEL);
1743 if (!mconfig->m_in_pin)
1744 return -ENOMEM;
1745
1746 break;
1747
1748 case SKL_TKN_U8_OUT_QUEUE_COUNT:
1749 mconfig->max_out_queue = tkn_elem->value;
1750 mconfig->m_out_pin = devm_kzalloc(dev, mconfig->max_out_queue *
1751 sizeof(*mconfig->m_out_pin),
1752 GFP_KERNEL);
1753
1754 if (!mconfig->m_out_pin)
1755 return -ENOMEM;
1756
1757 break;
1758
1759 case SKL_TKN_U8_DYN_IN_PIN:
1760 if (!mconfig->m_in_pin)
1761 return -ENOMEM;
1762
1763 skl_tplg_fill_pin_dynamic_val(mconfig->m_in_pin,
1764 mconfig->max_in_queue, tkn_elem->value);
1765
1766 break;
1767
1768 case SKL_TKN_U8_DYN_OUT_PIN:
1769 if (!mconfig->m_out_pin)
1770 return -ENOMEM;
1771
1772 skl_tplg_fill_pin_dynamic_val(mconfig->m_out_pin,
1773 mconfig->max_out_queue, tkn_elem->value);
1774
1775 break;
1776
1777 case SKL_TKN_U8_TIME_SLOT:
1778 mconfig->time_slot = tkn_elem->value;
1779 break;
1780
1781 case SKL_TKN_U8_CORE_ID:
1782 mconfig->core_id = tkn_elem->value;
1783
1784 case SKL_TKN_U8_MOD_TYPE:
1785 mconfig->m_type = tkn_elem->value;
1786 break;
1787
1788 case SKL_TKN_U8_DEV_TYPE:
1789 mconfig->dev_type = tkn_elem->value;
1790 break;
1791
1792 case SKL_TKN_U8_HW_CONN_TYPE:
1793 mconfig->hw_conn_type = tkn_elem->value;
1794 break;
1795
1796 case SKL_TKN_U16_MOD_INST_ID:
1797 mconfig->id.instance_id =
1798 tkn_elem->value;
1799 break;
1800
1801 case SKL_TKN_U32_MEM_PAGES:
1802 mconfig->mem_pages = tkn_elem->value;
1803 break;
1804
1805 case SKL_TKN_U32_MAX_MCPS:
1806 mconfig->mcps = tkn_elem->value;
1807 break;
1808
1809 case SKL_TKN_U32_OBS:
1810 mconfig->obs = tkn_elem->value;
1811 break;
1812
1813 case SKL_TKN_U32_IBS:
1814 mconfig->ibs = tkn_elem->value;
1815 break;
1816
1817 case SKL_TKN_U32_VBUS_ID:
1818 mconfig->vbus_id = tkn_elem->value;
1819 break;
1820
1821 case SKL_TKN_U32_PARAMS_FIXUP:
1822 mconfig->params_fixup = tkn_elem->value;
1823 break;
1824
1825 case SKL_TKN_U32_CONVERTER:
1826 mconfig->converter = tkn_elem->value;
1827 break;
1828
1829 case SKL_TKN_U32_PIPE_ID:
1830 ret = skl_tplg_add_pipe(dev,
1831 mconfig, skl, tkn_elem);
1832
1833 if (ret < 0)
1834 return is_pipe_exists;
1835
1836 if (ret == EEXIST)
1837 is_pipe_exists = 1;
1838
1839 break;
1840
1841 case SKL_TKN_U32_PIPE_CONN_TYPE:
1842 case SKL_TKN_U32_PIPE_PRIORITY:
1843 case SKL_TKN_U32_PIPE_MEM_PGS:
1844 if (is_pipe_exists) {
1845 ret = skl_tplg_fill_pipe_tkn(dev, mconfig->pipe,
1846 tkn_elem->token, tkn_elem->value);
1847 if (ret < 0)
1848 return ret;
1849 }
1850
1851 break;
1852
1853 /*
1854 * SKL_TKN_U32_DIR_PIN_COUNT token has the value for both
1855 * direction and the pin count. The first four bits represent
1856 * direction and next four the pin count.
1857 */
1858 case SKL_TKN_U32_DIR_PIN_COUNT:
1859 dir = tkn_elem->value & SKL_IN_DIR_BIT_MASK;
1860 pin_index = (tkn_elem->value &
1861 SKL_PIN_COUNT_MASK) >> 4;
1862
1863 break;
1864
1865 case SKL_TKN_U32_FMT_CH:
1866 case SKL_TKN_U32_FMT_FREQ:
1867 case SKL_TKN_U32_FMT_BIT_DEPTH:
1868 case SKL_TKN_U32_FMT_SAMPLE_SIZE:
1869 case SKL_TKN_U32_FMT_CH_CONFIG:
1870 case SKL_TKN_U32_FMT_INTERLEAVE:
1871 case SKL_TKN_U32_FMT_SAMPLE_TYPE:
1872 case SKL_TKN_U32_FMT_CH_MAP:
1873 ret = skl_tplg_fill_fmt(dev, mconfig, tkn_elem->token,
1874 tkn_elem->value, dir, pin_index);
1875
1876 if (ret < 0)
1877 return ret;
1878
1879 break;
1880
1881 case SKL_TKN_U32_PIN_MOD_ID:
1882 case SKL_TKN_U32_PIN_INST_ID:
1883 ret = skl_tplg_fill_pins_info(dev,
1884 mconfig, tkn_elem, dir,
1885 pin_index);
1886 if (ret < 0)
1887 return ret;
1888
1889 break;
1890
1891 case SKL_TKN_U32_CAPS_SIZE:
1892 mconfig->formats_config.caps_size =
1893 tkn_elem->value;
1894
1895 break;
1896
1897 case SKL_TKN_U32_PROC_DOMAIN:
1898 mconfig->domain =
1899 tkn_elem->value;
1900
1901 break;
1902
1903 case SKL_TKN_U8_IN_PIN_TYPE:
1904 case SKL_TKN_U8_OUT_PIN_TYPE:
1905 case SKL_TKN_U8_CONN_TYPE:
1906 break;
1907
1908 default:
1909 dev_err(dev, "Token %d not handled\n",
1910 tkn_elem->token);
1911 return -EINVAL;
1912 }
1913
1914 tkn_count++;
1915
1916 return tkn_count;
1917}
1918
1919/*
1920 * Parse the vendor array for specific tokens to construct
1921 * module private data
1922 */
1923static int skl_tplg_get_tokens(struct device *dev,
1924 char *pvt_data, struct skl *skl,
1925 struct skl_module_cfg *mconfig, int block_size)
1926{
1927 struct snd_soc_tplg_vendor_array *array;
1928 struct snd_soc_tplg_vendor_value_elem *tkn_elem;
1929 int tkn_count = 0, ret;
1930 int off = 0, tuple_size = 0;
1931
1932 if (block_size <= 0)
1933 return -EINVAL;
1934
1935 while (tuple_size < block_size) {
1936 array = (struct snd_soc_tplg_vendor_array *)(pvt_data + off);
1937
1938 off += array->size;
1939
1940 switch (array->type) {
1941 case SND_SOC_TPLG_TUPLE_TYPE_STRING:
1942 dev_warn(dev, "no string tokens expected for skl tplg\n");
1943 continue;
1944
1945 case SND_SOC_TPLG_TUPLE_TYPE_UUID:
1946 ret = skl_tplg_get_uuid(dev, mconfig, array->uuid);
1947 if (ret < 0)
1948 return ret;
1949
1950 tuple_size += sizeof(*array->uuid);
1951
1952 continue;
1953
1954 default:
1955 tkn_elem = array->value;
1956 tkn_count = 0;
1957 break;
1958 }
1959
1960 while (tkn_count <= (array->num_elems - 1)) {
1961 ret = skl_tplg_get_token(dev, tkn_elem,
1962 skl, mconfig);
1963
1964 if (ret < 0)
1965 return ret;
1966
1967 tkn_count = tkn_count + ret;
1968 tkn_elem++;
1969 }
1970
1971 tuple_size += tkn_count * sizeof(*tkn_elem);
1972 }
1973
1974 return 0;
1975}
1976
1977/*
1978 * Every data block is preceded by a descriptor to read the number
1979 * of data blocks, they type of the block and it's size
1980 */
1981static int skl_tplg_get_desc_blocks(struct device *dev,
1982 struct snd_soc_tplg_vendor_array *array)
1983{
1984 struct snd_soc_tplg_vendor_value_elem *tkn_elem;
1985
1986 tkn_elem = array->value;
1987
1988 switch (tkn_elem->token) {
1989 case SKL_TKN_U8_NUM_BLOCKS:
1990 case SKL_TKN_U8_BLOCK_TYPE:
1991 case SKL_TKN_U16_BLOCK_SIZE:
1992 return tkn_elem->value;
1993
1994 default:
1995 dev_err(dev, "Invalid descriptor token %d\n", tkn_elem->token);
1996 break;
1997 }
1998
1999 return -EINVAL;
2000}
2001
2002/*
2003 * Parse the private data for the token and corresponding value.
2004 * The private data can have multiple data blocks. So, a data block
2005 * is preceded by a descriptor for number of blocks and a descriptor
2006 * for the type and size of the suceeding data block.
2007 */
2008static int skl_tplg_get_pvt_data(struct snd_soc_tplg_dapm_widget *tplg_w,
2009 struct skl *skl, struct device *dev,
2010 struct skl_module_cfg *mconfig)
2011{
2012 struct snd_soc_tplg_vendor_array *array;
2013 int num_blocks, block_size = 0, block_type, off = 0;
2014 char *data;
2015 int ret;
2016
2017 /* Read the NUM_DATA_BLOCKS descriptor */
2018 array = (struct snd_soc_tplg_vendor_array *)tplg_w->priv.data;
2019 ret = skl_tplg_get_desc_blocks(dev, array);
2020 if (ret < 0)
2021 return ret;
2022 num_blocks = ret;
2023
2024 off += array->size;
2025 array = (struct snd_soc_tplg_vendor_array *)(tplg_w->priv.data + off);
2026
2027 /* Read the BLOCK_TYPE and BLOCK_SIZE descriptor */
2028 while (num_blocks > 0) {
2029 ret = skl_tplg_get_desc_blocks(dev, array);
2030
2031 if (ret < 0)
2032 return ret;
2033 block_type = ret;
2034 off += array->size;
2035
2036 array = (struct snd_soc_tplg_vendor_array *)
2037 (tplg_w->priv.data + off);
2038
2039 ret = skl_tplg_get_desc_blocks(dev, array);
2040
2041 if (ret < 0)
2042 return ret;
2043 block_size = ret;
2044 off += array->size;
2045
2046 array = (struct snd_soc_tplg_vendor_array *)
2047 (tplg_w->priv.data + off);
2048
2049 data = (tplg_w->priv.data + off);
2050
2051 if (block_type == SKL_TYPE_TUPLE) {
2052 ret = skl_tplg_get_tokens(dev, data,
2053 skl, mconfig, block_size);
2054
2055 if (ret < 0)
2056 return ret;
2057
2058 --num_blocks;
2059 } else {
2060 if (mconfig->formats_config.caps_size > 0)
2061 memcpy(mconfig->formats_config.caps, data,
2062 mconfig->formats_config.caps_size);
2063 --num_blocks;
2064 }
1541 } 2065 }
2066
2067 return 0;
1542} 2068}
1543 2069
1544static void skl_clear_pin_config(struct snd_soc_platform *platform, 2070static void skl_clear_pin_config(struct snd_soc_platform *platform,
@@ -1606,9 +2132,6 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt,
1606 struct skl *skl = ebus_to_skl(ebus); 2132 struct skl *skl = ebus_to_skl(ebus);
1607 struct hdac_bus *bus = ebus_to_hbus(ebus); 2133 struct hdac_bus *bus = ebus_to_hbus(ebus);
1608 struct skl_module_cfg *mconfig; 2134 struct skl_module_cfg *mconfig;
1609 struct skl_pipe *pipe;
1610 struct skl_dfw_module *dfw_config =
1611 (struct skl_dfw_module *)tplg_w->priv.data;
1612 2135
1613 if (!tplg_w->priv.size) 2136 if (!tplg_w->priv.size)
1614 goto bind_event; 2137 goto bind_event;
@@ -1619,76 +2142,17 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt,
1619 return -ENOMEM; 2142 return -ENOMEM;
1620 2143
1621 w->priv = mconfig; 2144 w->priv = mconfig;
1622 memcpy(&mconfig->guid, &dfw_config->uuid, 16);
1623 2145
1624 ret = snd_skl_get_module_info(skl->skl_sst, mconfig->guid, dfw_config); 2146 /*
2147 * module binary can be loaded later, so set it to query when
2148 * module is load for a use case
2149 */
2150 mconfig->id.module_id = -1;
2151
2152 /* Parse private data for tuples */
2153 ret = skl_tplg_get_pvt_data(tplg_w, skl, bus->dev, mconfig);
1625 if (ret < 0) 2154 if (ret < 0)
1626 return ret; 2155 return ret;
1627
1628 mconfig->id.module_id = dfw_config->module_id;
1629 mconfig->id.instance_id = dfw_config->instance_id;
1630 mconfig->mcps = dfw_config->max_mcps;
1631 mconfig->ibs = dfw_config->ibs;
1632 mconfig->obs = dfw_config->obs;
1633 mconfig->core_id = dfw_config->core_id;
1634 mconfig->max_in_queue = dfw_config->max_in_queue;
1635 mconfig->max_out_queue = dfw_config->max_out_queue;
1636 mconfig->is_loadable = dfw_config->is_loadable;
1637 skl_tplg_fill_fmt(mconfig->in_fmt, dfw_config->in_fmt,
1638 MODULE_MAX_IN_PINS);
1639 skl_tplg_fill_fmt(mconfig->out_fmt, dfw_config->out_fmt,
1640 MODULE_MAX_OUT_PINS);
1641
1642 mconfig->params_fixup = dfw_config->params_fixup;
1643 mconfig->converter = dfw_config->converter;
1644 mconfig->m_type = dfw_config->module_type;
1645 mconfig->vbus_id = dfw_config->vbus_id;
1646 mconfig->mem_pages = dfw_config->mem_pages;
1647
1648 pipe = skl_tplg_add_pipe(bus->dev, skl, &dfw_config->pipe);
1649 if (pipe)
1650 mconfig->pipe = pipe;
1651
1652 mconfig->dev_type = dfw_config->dev_type;
1653 mconfig->hw_conn_type = dfw_config->hw_conn_type;
1654 mconfig->time_slot = dfw_config->time_slot;
1655 mconfig->formats_config.caps_size = dfw_config->caps.caps_size;
1656
1657 mconfig->m_in_pin = devm_kzalloc(bus->dev, (mconfig->max_in_queue) *
1658 sizeof(*mconfig->m_in_pin),
1659 GFP_KERNEL);
1660 if (!mconfig->m_in_pin)
1661 return -ENOMEM;
1662
1663 mconfig->m_out_pin = devm_kzalloc(bus->dev, (mconfig->max_out_queue) *
1664 sizeof(*mconfig->m_out_pin),
1665 GFP_KERNEL);
1666 if (!mconfig->m_out_pin)
1667 return -ENOMEM;
1668
1669 skl_fill_module_pin_info(dfw_config->in_pin, mconfig->m_in_pin,
1670 dfw_config->is_dynamic_in_pin,
1671 mconfig->max_in_queue);
1672
1673 skl_fill_module_pin_info(dfw_config->out_pin, mconfig->m_out_pin,
1674 dfw_config->is_dynamic_out_pin,
1675 mconfig->max_out_queue);
1676
1677
1678 if (mconfig->formats_config.caps_size == 0)
1679 goto bind_event;
1680
1681 mconfig->formats_config.caps = (u32 *)devm_kzalloc(bus->dev,
1682 mconfig->formats_config.caps_size, GFP_KERNEL);
1683
1684 if (mconfig->formats_config.caps == NULL)
1685 return -ENOMEM;
1686
1687 memcpy(mconfig->formats_config.caps, dfw_config->caps.caps,
1688 dfw_config->caps.caps_size);
1689 mconfig->formats_config.param_id = dfw_config->caps.param_id;
1690 mconfig->formats_config.set_params = dfw_config->caps.set_params;
1691
1692bind_event: 2156bind_event:
1693 if (tplg_w->event_type == 0) { 2157 if (tplg_w->event_type == 0) {
1694 dev_dbg(bus->dev, "ASoC: No event handler required\n"); 2158 dev_dbg(bus->dev, "ASoC: No event handler required\n");
@@ -1767,11 +2231,229 @@ static int skl_tplg_control_load(struct snd_soc_component *cmpnt,
1767 return 0; 2231 return 0;
1768} 2232}
1769 2233
2234static int skl_tplg_fill_str_mfest_tkn(struct device *dev,
2235 struct snd_soc_tplg_vendor_string_elem *str_elem,
2236 struct skl_dfw_manifest *minfo)
2237{
2238 int tkn_count = 0;
2239 static int ref_count;
2240
2241 switch (str_elem->token) {
2242 case SKL_TKN_STR_LIB_NAME:
2243 if (ref_count > minfo->lib_count - 1) {
2244 ref_count = 0;
2245 return -EINVAL;
2246 }
2247
2248 strncpy(minfo->lib[ref_count].name, str_elem->string,
2249 ARRAY_SIZE(minfo->lib[ref_count].name));
2250 ref_count++;
2251 tkn_count++;
2252 break;
2253
2254 default:
2255 dev_err(dev, "Not a string token %d\n", str_elem->token);
2256 break;
2257 }
2258
2259 return tkn_count;
2260}
2261
2262static int skl_tplg_get_str_tkn(struct device *dev,
2263 struct snd_soc_tplg_vendor_array *array,
2264 struct skl_dfw_manifest *minfo)
2265{
2266 int tkn_count = 0, ret;
2267 struct snd_soc_tplg_vendor_string_elem *str_elem;
2268
2269 str_elem = (struct snd_soc_tplg_vendor_string_elem *)array->value;
2270 while (tkn_count < array->num_elems) {
2271 ret = skl_tplg_fill_str_mfest_tkn(dev, str_elem, minfo);
2272 str_elem++;
2273
2274 if (ret < 0)
2275 return ret;
2276
2277 tkn_count = tkn_count + ret;
2278 }
2279
2280 return tkn_count;
2281}
2282
2283static int skl_tplg_get_int_tkn(struct device *dev,
2284 struct snd_soc_tplg_vendor_value_elem *tkn_elem,
2285 struct skl_dfw_manifest *minfo)
2286{
2287 int tkn_count = 0;
2288
2289 switch (tkn_elem->token) {
2290 case SKL_TKN_U32_LIB_COUNT:
2291 minfo->lib_count = tkn_elem->value;
2292 tkn_count++;
2293 break;
2294
2295 default:
2296 dev_err(dev, "Not a manifest token %d\n", tkn_elem->token);
2297 return -EINVAL;
2298 }
2299
2300 return tkn_count;
2301}
2302
2303/*
2304 * Fill the manifest structure by parsing the tokens based on the
2305 * type.
2306 */
2307static int skl_tplg_get_manifest_tkn(struct device *dev,
2308 char *pvt_data, struct skl_dfw_manifest *minfo,
2309 int block_size)
2310{
2311 int tkn_count = 0, ret;
2312 int off = 0, tuple_size = 0;
2313 struct snd_soc_tplg_vendor_array *array;
2314 struct snd_soc_tplg_vendor_value_elem *tkn_elem;
2315
2316 if (block_size <= 0)
2317 return -EINVAL;
2318
2319 while (tuple_size < block_size) {
2320 array = (struct snd_soc_tplg_vendor_array *)(pvt_data + off);
2321 off += array->size;
2322 switch (array->type) {
2323 case SND_SOC_TPLG_TUPLE_TYPE_STRING:
2324 ret = skl_tplg_get_str_tkn(dev, array, minfo);
2325
2326 if (ret < 0)
2327 return ret;
2328 tkn_count += ret;
2329
2330 tuple_size += tkn_count *
2331 sizeof(struct snd_soc_tplg_vendor_string_elem);
2332 continue;
2333
2334 case SND_SOC_TPLG_TUPLE_TYPE_UUID:
2335 dev_warn(dev, "no uuid tokens for skl tplf manifest\n");
2336 continue;
2337
2338 default:
2339 tkn_elem = array->value;
2340 tkn_count = 0;
2341 break;
2342 }
2343
2344 while (tkn_count <= array->num_elems - 1) {
2345 ret = skl_tplg_get_int_tkn(dev,
2346 tkn_elem, minfo);
2347 if (ret < 0)
2348 return ret;
2349
2350 tkn_count = tkn_count + ret;
2351 tkn_elem++;
2352 tuple_size += tkn_count *
2353 sizeof(struct snd_soc_tplg_vendor_value_elem);
2354 break;
2355 }
2356 tkn_count = 0;
2357 }
2358
2359 return 0;
2360}
2361
2362/*
2363 * Parse manifest private data for tokens. The private data block is
2364 * preceded by descriptors for type and size of data block.
2365 */
2366static int skl_tplg_get_manifest_data(struct snd_soc_tplg_manifest *manifest,
2367 struct device *dev, struct skl_dfw_manifest *minfo)
2368{
2369 struct snd_soc_tplg_vendor_array *array;
2370 int num_blocks, block_size = 0, block_type, off = 0;
2371 char *data;
2372 int ret;
2373
2374 /* Read the NUM_DATA_BLOCKS descriptor */
2375 array = (struct snd_soc_tplg_vendor_array *)manifest->priv.data;
2376 ret = skl_tplg_get_desc_blocks(dev, array);
2377 if (ret < 0)
2378 return ret;
2379 num_blocks = ret;
2380
2381 off += array->size;
2382 array = (struct snd_soc_tplg_vendor_array *)
2383 (manifest->priv.data + off);
2384
2385 /* Read the BLOCK_TYPE and BLOCK_SIZE descriptor */
2386 while (num_blocks > 0) {
2387 ret = skl_tplg_get_desc_blocks(dev, array);
2388
2389 if (ret < 0)
2390 return ret;
2391 block_type = ret;
2392 off += array->size;
2393
2394 array = (struct snd_soc_tplg_vendor_array *)
2395 (manifest->priv.data + off);
2396
2397 ret = skl_tplg_get_desc_blocks(dev, array);
2398
2399 if (ret < 0)
2400 return ret;
2401 block_size = ret;
2402 off += array->size;
2403
2404 array = (struct snd_soc_tplg_vendor_array *)
2405 (manifest->priv.data + off);
2406
2407 data = (manifest->priv.data + off);
2408
2409 if (block_type == SKL_TYPE_TUPLE) {
2410 ret = skl_tplg_get_manifest_tkn(dev, data, minfo,
2411 block_size);
2412
2413 if (ret < 0)
2414 return ret;
2415
2416 --num_blocks;
2417 } else {
2418 return -EINVAL;
2419 }
2420 }
2421
2422 return 0;
2423}
2424
2425static int skl_manifest_load(struct snd_soc_component *cmpnt,
2426 struct snd_soc_tplg_manifest *manifest)
2427{
2428 struct skl_dfw_manifest *minfo;
2429 struct hdac_ext_bus *ebus = snd_soc_component_get_drvdata(cmpnt);
2430 struct hdac_bus *bus = ebus_to_hbus(ebus);
2431 struct skl *skl = ebus_to_skl(ebus);
2432 int ret = 0;
2433
2434 /* proceed only if we have private data defined */
2435 if (manifest->priv.size == 0)
2436 return 0;
2437
2438 minfo = &skl->skl_sst->manifest;
2439
2440 skl_tplg_get_manifest_data(manifest, bus->dev, minfo);
2441
2442 if (minfo->lib_count > HDA_MAX_LIB) {
2443 dev_err(bus->dev, "Exceeding max Library count. Got:%d\n",
2444 minfo->lib_count);
2445 ret = -EINVAL;
2446 }
2447
2448 return ret;
2449}
2450
1770static struct snd_soc_tplg_ops skl_tplg_ops = { 2451static struct snd_soc_tplg_ops skl_tplg_ops = {
1771 .widget_load = skl_tplg_widget_load, 2452 .widget_load = skl_tplg_widget_load,
1772 .control_load = skl_tplg_control_load, 2453 .control_load = skl_tplg_control_load,
1773 .bytes_ext_ops = skl_tlv_ops, 2454 .bytes_ext_ops = skl_tlv_ops,
1774 .bytes_ext_ops_count = ARRAY_SIZE(skl_tlv_ops), 2455 .bytes_ext_ops_count = ARRAY_SIZE(skl_tlv_ops),
2456 .manifest = skl_manifest_load,
1775}; 2457};
1776 2458
1777/* 2459/*
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h
index 22d3ef83817d..a519360f42a6 100644
--- a/sound/soc/intel/skylake/skl-topology.h
+++ b/sound/soc/intel/skylake/skl-topology.h
@@ -133,7 +133,7 @@ struct skl_i2s_config_blob {
133struct skl_dma_control { 133struct skl_dma_control {
134 u32 node_id; 134 u32 node_id;
135 u32 config_length; 135 u32 config_length;
136 u32 config_data[1]; 136 u32 config_data[0];
137} __packed; 137} __packed;
138 138
139struct skl_cpr_cfg { 139struct skl_cpr_cfg {
@@ -215,9 +215,20 @@ struct skl_module_fmt {
215 215
216struct skl_module_cfg; 216struct skl_module_cfg;
217 217
218struct skl_mod_inst_map {
219 u16 mod_id;
220 u16 inst_id;
221};
222
223struct skl_kpb_params {
224 u32 num_modules;
225 struct skl_mod_inst_map map[0];
226};
227
218struct skl_module_inst_id { 228struct skl_module_inst_id {
219 u32 module_id; 229 int module_id;
220 u32 instance_id; 230 u32 instance_id;
231 int pvt_id;
221}; 232};
222 233
223enum skl_module_pin_state { 234enum skl_module_pin_state {
diff --git a/sound/soc/intel/skylake/skl-tplg-interface.h b/sound/soc/intel/skylake/skl-tplg-interface.h
index a32e5e9cc530..2f6281e056d6 100644
--- a/sound/soc/intel/skylake/skl-tplg-interface.h
+++ b/sound/soc/intel/skylake/skl-tplg-interface.h
@@ -80,7 +80,8 @@ enum skl_module_type {
80 SKL_MODULE_TYPE_UPDWMIX, 80 SKL_MODULE_TYPE_UPDWMIX,
81 SKL_MODULE_TYPE_SRCINT, 81 SKL_MODULE_TYPE_SRCINT,
82 SKL_MODULE_TYPE_ALGO, 82 SKL_MODULE_TYPE_ALGO,
83 SKL_MODULE_TYPE_BASE_OUTFMT 83 SKL_MODULE_TYPE_BASE_OUTFMT,
84 SKL_MODULE_TYPE_KPB,
84}; 85};
85 86
86enum skl_core_affinity { 87enum skl_core_affinity {
@@ -148,84 +149,34 @@ enum skl_module_param_type {
148 SKL_PARAM_BIND 149 SKL_PARAM_BIND
149}; 150};
150 151
151struct skl_dfw_module_pin { 152struct skl_dfw_algo_data {
152 u16 module_id;
153 u16 instance_id;
154} __packed;
155
156struct skl_dfw_module_fmt {
157 u32 channels;
158 u32 freq;
159 u32 bit_depth;
160 u32 valid_bit_depth;
161 u32 ch_cfg;
162 u32 interleaving_style;
163 u32 sample_type;
164 u32 ch_map;
165} __packed;
166
167struct skl_dfw_module_caps {
168 u32 set_params:2; 153 u32 set_params:2;
169 u32 rsvd:30; 154 u32 rsvd:30;
170 u32 param_id; 155 u32 param_id;
171 u32 caps_size; 156 u32 max;
172 u32 caps[HDA_SST_CFG_MAX]; 157 char params[0];
173};
174
175struct skl_dfw_pipe {
176 u8 pipe_id;
177 u8 pipe_priority;
178 u16 conn_type:4;
179 u16 rsvd:4;
180 u16 memory_pages:8;
181} __packed; 158} __packed;
182 159
183struct skl_dfw_module { 160#define LIB_NAME_LENGTH 128
184 u8 uuid[16]; 161#define HDA_MAX_LIB 16
185 162
186 u16 module_id; 163struct lib_info {
187 u16 instance_id; 164 char name[LIB_NAME_LENGTH];
188 u32 max_mcps;
189 u32 mem_pages;
190 u32 obs;
191 u32 ibs;
192 u32 vbus_id;
193
194 u32 max_in_queue:8;
195 u32 max_out_queue:8;
196 u32 time_slot:8;
197 u32 core_id:4;
198 u32 rsvd1:4;
199
200 u32 module_type:8;
201 u32 conn_type:4;
202 u32 dev_type:4;
203 u32 hw_conn_type:4;
204 u32 rsvd2:12;
205
206 u32 params_fixup:8;
207 u32 converter:8;
208 u32 input_pin_type:1;
209 u32 output_pin_type:1;
210 u32 is_dynamic_in_pin:1;
211 u32 is_dynamic_out_pin:1;
212 u32 is_loadable:1;
213 u32 rsvd3:11;
214
215 struct skl_dfw_pipe pipe;
216 struct skl_dfw_module_fmt in_fmt[MAX_IN_QUEUE];
217 struct skl_dfw_module_fmt out_fmt[MAX_OUT_QUEUE];
218 struct skl_dfw_module_pin in_pin[MAX_IN_QUEUE];
219 struct skl_dfw_module_pin out_pin[MAX_OUT_QUEUE];
220 struct skl_dfw_module_caps caps;
221} __packed; 165} __packed;
222 166
223struct skl_dfw_algo_data { 167struct skl_dfw_manifest {
224 u32 set_params:2; 168 u32 lib_count;
225 u32 rsvd:30; 169 struct lib_info lib[HDA_MAX_LIB];
226 u32 param_id;
227 u32 max;
228 char params[0];
229} __packed; 170} __packed;
230 171
172enum skl_tkn_dir {
173 SKL_DIR_IN,
174 SKL_DIR_OUT
175};
176
177enum skl_tuple_type {
178 SKL_TYPE_TUPLE,
179 SKL_TYPE_DATA
180};
181
231#endif 182#endif
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c
index e3e764167765..2989c164dafe 100644
--- a/sound/soc/intel/skylake/skl.c
+++ b/sound/soc/intel/skylake/skl.c
@@ -587,7 +587,7 @@ static int skl_first_init(struct hdac_ext_bus *ebus)
587 return -ENXIO; 587 return -ENXIO;
588 } 588 }
589 589
590 snd_hdac_ext_bus_parse_capabilities(ebus); 590 snd_hdac_bus_parse_capabilities(bus);
591 591
592 if (skl_acquire_irq(ebus, 0) < 0) 592 if (skl_acquire_irq(ebus, 0) < 0)
593 return -EBUSY; 593 return -EBUSY;
@@ -684,7 +684,7 @@ static int skl_probe(struct pci_dev *pci,
684 skl_dmic_data.dmic_num = skl_get_dmic_geo(skl); 684 skl_dmic_data.dmic_num = skl_get_dmic_geo(skl);
685 685
686 /* check if dsp is there */ 686 /* check if dsp is there */
687 if (ebus->ppcap) { 687 if (bus->ppcap) {
688 err = skl_machine_device_register(skl, 688 err = skl_machine_device_register(skl,
689 (void *)pci_id->driver_data); 689 (void *)pci_id->driver_data);
690 if (err < 0) 690 if (err < 0)
@@ -698,7 +698,7 @@ static int skl_probe(struct pci_dev *pci,
698 skl->skl_sst->enable_miscbdcge = skl_enable_miscbdcge; 698 skl->skl_sst->enable_miscbdcge = skl_enable_miscbdcge;
699 699
700 } 700 }
701 if (ebus->mlcap) 701 if (bus->mlcap)
702 snd_hdac_ext_bus_get_ml_capabilities(ebus); 702 snd_hdac_ext_bus_get_ml_capabilities(ebus);
703 703
704 /* create device for soc dmic */ 704 /* create device for soc dmic */
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h
index 9064e5b0d676..5d4fbb094c48 100644
--- a/sound/soc/intel/skylake/skl.h
+++ b/sound/soc/intel/skylake/skl.h
@@ -105,6 +105,7 @@ struct skl_dsp_ops {
105 int irq, const char *fw_name, 105 int irq, const char *fw_name,
106 struct skl_dsp_loader_ops loader_ops, 106 struct skl_dsp_loader_ops loader_ops,
107 struct skl_sst **skl_sst); 107 struct skl_sst **skl_sst);
108 int (*init_fw)(struct device *dev, struct skl_sst *ctx);
108 void (*cleanup)(struct device *dev, struct skl_sst *ctx); 109 void (*cleanup)(struct device *dev, struct skl_sst *ctx);
109}; 110};
110 111
@@ -123,4 +124,5 @@ int skl_free_dsp(struct skl *skl);
123int skl_suspend_dsp(struct skl *skl); 124int skl_suspend_dsp(struct skl *skl);
124int skl_resume_dsp(struct skl *skl); 125int skl_resume_dsp(struct skl *skl);
125void skl_cleanup_resources(struct skl *skl); 126void skl_cleanup_resources(struct skl *skl);
127const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id);
126#endif /* __SOUND_SOC_SKL_H */ 128#endif /* __SOUND_SOC_SKL_H */