xref: /openbmc/linux/sound/soc/codecs/wm_adsp.c (revision 93032e31)
1 /*
2  * wm_adsp.c  --  Wolfson ADSP support
3  *
4  * Copyright 2012 Wolfson Microelectronics plc
5  *
6  * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
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 version 2 as
10  * published by the Free Software Foundation.
11  */
12 
13 #include <linux/module.h>
14 #include <linux/moduleparam.h>
15 #include <linux/init.h>
16 #include <linux/delay.h>
17 #include <linux/firmware.h>
18 #include <linux/list.h>
19 #include <linux/pm.h>
20 #include <linux/pm_runtime.h>
21 #include <linux/regmap.h>
22 #include <linux/regulator/consumer.h>
23 #include <linux/slab.h>
24 #include <linux/vmalloc.h>
25 #include <linux/workqueue.h>
26 #include <linux/debugfs.h>
27 #include <sound/core.h>
28 #include <sound/pcm.h>
29 #include <sound/pcm_params.h>
30 #include <sound/soc.h>
31 #include <sound/jack.h>
32 #include <sound/initval.h>
33 #include <sound/tlv.h>
34 
35 #include "wm_adsp.h"
36 
37 #define adsp_crit(_dsp, fmt, ...) \
38 	dev_crit(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__)
39 #define adsp_err(_dsp, fmt, ...) \
40 	dev_err(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__)
41 #define adsp_warn(_dsp, fmt, ...) \
42 	dev_warn(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__)
43 #define adsp_info(_dsp, fmt, ...) \
44 	dev_info(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__)
45 #define adsp_dbg(_dsp, fmt, ...) \
46 	dev_dbg(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__)
47 
48 #define ADSP1_CONTROL_1                   0x00
49 #define ADSP1_CONTROL_2                   0x02
50 #define ADSP1_CONTROL_3                   0x03
51 #define ADSP1_CONTROL_4                   0x04
52 #define ADSP1_CONTROL_5                   0x06
53 #define ADSP1_CONTROL_6                   0x07
54 #define ADSP1_CONTROL_7                   0x08
55 #define ADSP1_CONTROL_8                   0x09
56 #define ADSP1_CONTROL_9                   0x0A
57 #define ADSP1_CONTROL_10                  0x0B
58 #define ADSP1_CONTROL_11                  0x0C
59 #define ADSP1_CONTROL_12                  0x0D
60 #define ADSP1_CONTROL_13                  0x0F
61 #define ADSP1_CONTROL_14                  0x10
62 #define ADSP1_CONTROL_15                  0x11
63 #define ADSP1_CONTROL_16                  0x12
64 #define ADSP1_CONTROL_17                  0x13
65 #define ADSP1_CONTROL_18                  0x14
66 #define ADSP1_CONTROL_19                  0x16
67 #define ADSP1_CONTROL_20                  0x17
68 #define ADSP1_CONTROL_21                  0x18
69 #define ADSP1_CONTROL_22                  0x1A
70 #define ADSP1_CONTROL_23                  0x1B
71 #define ADSP1_CONTROL_24                  0x1C
72 #define ADSP1_CONTROL_25                  0x1E
73 #define ADSP1_CONTROL_26                  0x20
74 #define ADSP1_CONTROL_27                  0x21
75 #define ADSP1_CONTROL_28                  0x22
76 #define ADSP1_CONTROL_29                  0x23
77 #define ADSP1_CONTROL_30                  0x24
78 #define ADSP1_CONTROL_31                  0x26
79 
80 /*
81  * ADSP1 Control 19
82  */
83 #define ADSP1_WDMA_BUFFER_LENGTH_MASK     0x00FF  /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */
84 #define ADSP1_WDMA_BUFFER_LENGTH_SHIFT         0  /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */
85 #define ADSP1_WDMA_BUFFER_LENGTH_WIDTH         8  /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */
86 
87 
88 /*
89  * ADSP1 Control 30
90  */
91 #define ADSP1_DBG_CLK_ENA                 0x0008  /* DSP1_DBG_CLK_ENA */
92 #define ADSP1_DBG_CLK_ENA_MASK            0x0008  /* DSP1_DBG_CLK_ENA */
93 #define ADSP1_DBG_CLK_ENA_SHIFT                3  /* DSP1_DBG_CLK_ENA */
94 #define ADSP1_DBG_CLK_ENA_WIDTH                1  /* DSP1_DBG_CLK_ENA */
95 #define ADSP1_SYS_ENA                     0x0004  /* DSP1_SYS_ENA */
96 #define ADSP1_SYS_ENA_MASK                0x0004  /* DSP1_SYS_ENA */
97 #define ADSP1_SYS_ENA_SHIFT                    2  /* DSP1_SYS_ENA */
98 #define ADSP1_SYS_ENA_WIDTH                    1  /* DSP1_SYS_ENA */
99 #define ADSP1_CORE_ENA                    0x0002  /* DSP1_CORE_ENA */
100 #define ADSP1_CORE_ENA_MASK               0x0002  /* DSP1_CORE_ENA */
101 #define ADSP1_CORE_ENA_SHIFT                   1  /* DSP1_CORE_ENA */
102 #define ADSP1_CORE_ENA_WIDTH                   1  /* DSP1_CORE_ENA */
103 #define ADSP1_START                       0x0001  /* DSP1_START */
104 #define ADSP1_START_MASK                  0x0001  /* DSP1_START */
105 #define ADSP1_START_SHIFT                      0  /* DSP1_START */
106 #define ADSP1_START_WIDTH                      1  /* DSP1_START */
107 
108 /*
109  * ADSP1 Control 31
110  */
111 #define ADSP1_CLK_SEL_MASK                0x0007  /* CLK_SEL_ENA */
112 #define ADSP1_CLK_SEL_SHIFT                    0  /* CLK_SEL_ENA */
113 #define ADSP1_CLK_SEL_WIDTH                    3  /* CLK_SEL_ENA */
114 
115 #define ADSP2_CONTROL        0x0
116 #define ADSP2_CLOCKING       0x1
117 #define ADSP2_STATUS1        0x4
118 #define ADSP2_WDMA_CONFIG_1 0x30
119 #define ADSP2_WDMA_CONFIG_2 0x31
120 #define ADSP2_RDMA_CONFIG_1 0x34
121 
122 #define ADSP2_SCRATCH0        0x40
123 #define ADSP2_SCRATCH1        0x41
124 #define ADSP2_SCRATCH2        0x42
125 #define ADSP2_SCRATCH3        0x43
126 
127 /*
128  * ADSP2 Control
129  */
130 
131 #define ADSP2_MEM_ENA                     0x0010  /* DSP1_MEM_ENA */
132 #define ADSP2_MEM_ENA_MASK                0x0010  /* DSP1_MEM_ENA */
133 #define ADSP2_MEM_ENA_SHIFT                    4  /* DSP1_MEM_ENA */
134 #define ADSP2_MEM_ENA_WIDTH                    1  /* DSP1_MEM_ENA */
135 #define ADSP2_SYS_ENA                     0x0004  /* DSP1_SYS_ENA */
136 #define ADSP2_SYS_ENA_MASK                0x0004  /* DSP1_SYS_ENA */
137 #define ADSP2_SYS_ENA_SHIFT                    2  /* DSP1_SYS_ENA */
138 #define ADSP2_SYS_ENA_WIDTH                    1  /* DSP1_SYS_ENA */
139 #define ADSP2_CORE_ENA                    0x0002  /* DSP1_CORE_ENA */
140 #define ADSP2_CORE_ENA_MASK               0x0002  /* DSP1_CORE_ENA */
141 #define ADSP2_CORE_ENA_SHIFT                   1  /* DSP1_CORE_ENA */
142 #define ADSP2_CORE_ENA_WIDTH                   1  /* DSP1_CORE_ENA */
143 #define ADSP2_START                       0x0001  /* DSP1_START */
144 #define ADSP2_START_MASK                  0x0001  /* DSP1_START */
145 #define ADSP2_START_SHIFT                      0  /* DSP1_START */
146 #define ADSP2_START_WIDTH                      1  /* DSP1_START */
147 
148 /*
149  * ADSP2 clocking
150  */
151 #define ADSP2_CLK_SEL_MASK                0x0007  /* CLK_SEL_ENA */
152 #define ADSP2_CLK_SEL_SHIFT                    0  /* CLK_SEL_ENA */
153 #define ADSP2_CLK_SEL_WIDTH                    3  /* CLK_SEL_ENA */
154 
155 /*
156  * ADSP2 Status 1
157  */
158 #define ADSP2_RAM_RDY                     0x0001
159 #define ADSP2_RAM_RDY_MASK                0x0001
160 #define ADSP2_RAM_RDY_SHIFT                    0
161 #define ADSP2_RAM_RDY_WIDTH                    1
162 
163 #define ADSP_MAX_STD_CTRL_SIZE               512
164 
165 struct wm_adsp_buf {
166 	struct list_head list;
167 	void *buf;
168 };
169 
170 static struct wm_adsp_buf *wm_adsp_buf_alloc(const void *src, size_t len,
171 					     struct list_head *list)
172 {
173 	struct wm_adsp_buf *buf = kzalloc(sizeof(*buf), GFP_KERNEL);
174 
175 	if (buf == NULL)
176 		return NULL;
177 
178 	buf->buf = vmalloc(len);
179 	if (!buf->buf) {
180 		vfree(buf);
181 		return NULL;
182 	}
183 	memcpy(buf->buf, src, len);
184 
185 	if (list)
186 		list_add_tail(&buf->list, list);
187 
188 	return buf;
189 }
190 
191 static void wm_adsp_buf_free(struct list_head *list)
192 {
193 	while (!list_empty(list)) {
194 		struct wm_adsp_buf *buf = list_first_entry(list,
195 							   struct wm_adsp_buf,
196 							   list);
197 		list_del(&buf->list);
198 		vfree(buf->buf);
199 		kfree(buf);
200 	}
201 }
202 
203 #define WM_ADSP_FW_MBC_VSS  0
204 #define WM_ADSP_FW_HIFI     1
205 #define WM_ADSP_FW_TX       2
206 #define WM_ADSP_FW_TX_SPK   3
207 #define WM_ADSP_FW_RX       4
208 #define WM_ADSP_FW_RX_ANC   5
209 #define WM_ADSP_FW_CTRL     6
210 #define WM_ADSP_FW_ASR      7
211 #define WM_ADSP_FW_TRACE    8
212 #define WM_ADSP_FW_SPK_PROT 9
213 #define WM_ADSP_FW_MISC     10
214 
215 #define WM_ADSP_NUM_FW      11
216 
217 static const char *wm_adsp_fw_text[WM_ADSP_NUM_FW] = {
218 	[WM_ADSP_FW_MBC_VSS] =  "MBC/VSS",
219 	[WM_ADSP_FW_HIFI] =     "MasterHiFi",
220 	[WM_ADSP_FW_TX] =       "Tx",
221 	[WM_ADSP_FW_TX_SPK] =   "Tx Speaker",
222 	[WM_ADSP_FW_RX] =       "Rx",
223 	[WM_ADSP_FW_RX_ANC] =   "Rx ANC",
224 	[WM_ADSP_FW_CTRL] =     "Voice Ctrl",
225 	[WM_ADSP_FW_ASR] =      "ASR Assist",
226 	[WM_ADSP_FW_TRACE] =    "Dbg Trace",
227 	[WM_ADSP_FW_SPK_PROT] = "Protection",
228 	[WM_ADSP_FW_MISC] =     "Misc",
229 };
230 
231 struct wm_adsp_system_config_xm_hdr {
232 	__be32 sys_enable;
233 	__be32 fw_id;
234 	__be32 fw_rev;
235 	__be32 boot_status;
236 	__be32 watchdog;
237 	__be32 dma_buffer_size;
238 	__be32 rdma[6];
239 	__be32 wdma[8];
240 	__be32 build_job_name[3];
241 	__be32 build_job_number;
242 };
243 
244 struct wm_adsp_alg_xm_struct {
245 	__be32 magic;
246 	__be32 smoothing;
247 	__be32 threshold;
248 	__be32 host_buf_ptr;
249 	__be32 start_seq;
250 	__be32 high_water_mark;
251 	__be32 low_water_mark;
252 	__be64 smoothed_power;
253 };
254 
255 struct wm_adsp_buffer {
256 	__be32 X_buf_base;		/* XM base addr of first X area */
257 	__be32 X_buf_size;		/* Size of 1st X area in words */
258 	__be32 X_buf_base2;		/* XM base addr of 2nd X area */
259 	__be32 X_buf_brk;		/* Total X size in words */
260 	__be32 Y_buf_base;		/* YM base addr of Y area */
261 	__be32 wrap;			/* Total size X and Y in words */
262 	__be32 high_water_mark;		/* Point at which IRQ is asserted */
263 	__be32 irq_count;		/* bits 1-31 count IRQ assertions */
264 	__be32 irq_ack;			/* acked IRQ count, bit 0 enables IRQ */
265 	__be32 next_write_index;	/* word index of next write */
266 	__be32 next_read_index;		/* word index of next read */
267 	__be32 error;			/* error if any */
268 	__be32 oldest_block_index;	/* word index of oldest surviving */
269 	__be32 requested_rewind;	/* how many blocks rewind was done */
270 	__be32 reserved_space;		/* internal */
271 	__be32 min_free;		/* min free space since stream start */
272 	__be32 blocks_written[2];	/* total blocks written (64 bit) */
273 	__be32 words_written[2];	/* total words written (64 bit) */
274 };
275 
276 struct wm_adsp_compr;
277 
278 struct wm_adsp_compr_buf {
279 	struct wm_adsp *dsp;
280 	struct wm_adsp_compr *compr;
281 
282 	struct wm_adsp_buffer_region *regions;
283 	u32 host_buf_ptr;
284 
285 	u32 error;
286 	u32 irq_count;
287 	int read_index;
288 	int avail;
289 };
290 
291 struct wm_adsp_compr {
292 	struct wm_adsp *dsp;
293 	struct wm_adsp_compr_buf *buf;
294 
295 	struct snd_compr_stream *stream;
296 	struct snd_compressed_buffer size;
297 
298 	u32 *raw_buf;
299 	unsigned int copied_total;
300 
301 	unsigned int sample_rate;
302 };
303 
304 #define WM_ADSP_DATA_WORD_SIZE         3
305 
306 #define WM_ADSP_MIN_FRAGMENTS          1
307 #define WM_ADSP_MAX_FRAGMENTS          256
308 #define WM_ADSP_MIN_FRAGMENT_SIZE      (64 * WM_ADSP_DATA_WORD_SIZE)
309 #define WM_ADSP_MAX_FRAGMENT_SIZE      (4096 * WM_ADSP_DATA_WORD_SIZE)
310 
311 #define WM_ADSP_ALG_XM_STRUCT_MAGIC    0x49aec7
312 
313 #define HOST_BUFFER_FIELD(field) \
314 	(offsetof(struct wm_adsp_buffer, field) / sizeof(__be32))
315 
316 #define ALG_XM_FIELD(field) \
317 	(offsetof(struct wm_adsp_alg_xm_struct, field) / sizeof(__be32))
318 
319 static int wm_adsp_buffer_init(struct wm_adsp *dsp);
320 static int wm_adsp_buffer_free(struct wm_adsp *dsp);
321 
322 struct wm_adsp_buffer_region {
323 	unsigned int offset;
324 	unsigned int cumulative_size;
325 	unsigned int mem_type;
326 	unsigned int base_addr;
327 };
328 
329 struct wm_adsp_buffer_region_def {
330 	unsigned int mem_type;
331 	unsigned int base_offset;
332 	unsigned int size_offset;
333 };
334 
335 static const struct wm_adsp_buffer_region_def default_regions[] = {
336 	{
337 		.mem_type = WMFW_ADSP2_XM,
338 		.base_offset = HOST_BUFFER_FIELD(X_buf_base),
339 		.size_offset = HOST_BUFFER_FIELD(X_buf_size),
340 	},
341 	{
342 		.mem_type = WMFW_ADSP2_XM,
343 		.base_offset = HOST_BUFFER_FIELD(X_buf_base2),
344 		.size_offset = HOST_BUFFER_FIELD(X_buf_brk),
345 	},
346 	{
347 		.mem_type = WMFW_ADSP2_YM,
348 		.base_offset = HOST_BUFFER_FIELD(Y_buf_base),
349 		.size_offset = HOST_BUFFER_FIELD(wrap),
350 	},
351 };
352 
353 struct wm_adsp_fw_caps {
354 	u32 id;
355 	struct snd_codec_desc desc;
356 	int num_regions;
357 	const struct wm_adsp_buffer_region_def *region_defs;
358 };
359 
360 static const struct wm_adsp_fw_caps ctrl_caps[] = {
361 	{
362 		.id = SND_AUDIOCODEC_BESPOKE,
363 		.desc = {
364 			.max_ch = 1,
365 			.sample_rates = { 16000 },
366 			.num_sample_rates = 1,
367 			.formats = SNDRV_PCM_FMTBIT_S16_LE,
368 		},
369 		.num_regions = ARRAY_SIZE(default_regions),
370 		.region_defs = default_regions,
371 	},
372 };
373 
374 static const struct wm_adsp_fw_caps trace_caps[] = {
375 	{
376 		.id = SND_AUDIOCODEC_BESPOKE,
377 		.desc = {
378 			.max_ch = 8,
379 			.sample_rates = {
380 				4000, 8000, 11025, 12000, 16000, 22050,
381 				24000, 32000, 44100, 48000, 64000, 88200,
382 				96000, 176400, 192000
383 			},
384 			.num_sample_rates = 15,
385 			.formats = SNDRV_PCM_FMTBIT_S16_LE,
386 		},
387 		.num_regions = ARRAY_SIZE(default_regions),
388 		.region_defs = default_regions,
389 	},
390 };
391 
392 static const struct {
393 	const char *file;
394 	int compr_direction;
395 	int num_caps;
396 	const struct wm_adsp_fw_caps *caps;
397 	bool voice_trigger;
398 } wm_adsp_fw[WM_ADSP_NUM_FW] = {
399 	[WM_ADSP_FW_MBC_VSS] =  { .file = "mbc-vss" },
400 	[WM_ADSP_FW_HIFI] =     { .file = "hifi" },
401 	[WM_ADSP_FW_TX] =       { .file = "tx" },
402 	[WM_ADSP_FW_TX_SPK] =   { .file = "tx-spk" },
403 	[WM_ADSP_FW_RX] =       { .file = "rx" },
404 	[WM_ADSP_FW_RX_ANC] =   { .file = "rx-anc" },
405 	[WM_ADSP_FW_CTRL] =     {
406 		.file = "ctrl",
407 		.compr_direction = SND_COMPRESS_CAPTURE,
408 		.num_caps = ARRAY_SIZE(ctrl_caps),
409 		.caps = ctrl_caps,
410 		.voice_trigger = true,
411 	},
412 	[WM_ADSP_FW_ASR] =      { .file = "asr" },
413 	[WM_ADSP_FW_TRACE] =    {
414 		.file = "trace",
415 		.compr_direction = SND_COMPRESS_CAPTURE,
416 		.num_caps = ARRAY_SIZE(trace_caps),
417 		.caps = trace_caps,
418 	},
419 	[WM_ADSP_FW_SPK_PROT] = { .file = "spk-prot" },
420 	[WM_ADSP_FW_MISC] =     { .file = "misc" },
421 };
422 
423 struct wm_coeff_ctl_ops {
424 	int (*xget)(struct snd_kcontrol *kcontrol,
425 		    struct snd_ctl_elem_value *ucontrol);
426 	int (*xput)(struct snd_kcontrol *kcontrol,
427 		    struct snd_ctl_elem_value *ucontrol);
428 	int (*xinfo)(struct snd_kcontrol *kcontrol,
429 		     struct snd_ctl_elem_info *uinfo);
430 };
431 
432 struct wm_coeff_ctl {
433 	const char *name;
434 	const char *fw_name;
435 	struct wm_adsp_alg_region alg_region;
436 	struct wm_coeff_ctl_ops ops;
437 	struct wm_adsp *dsp;
438 	unsigned int enabled:1;
439 	struct list_head list;
440 	void *cache;
441 	unsigned int offset;
442 	size_t len;
443 	unsigned int set:1;
444 	struct snd_kcontrol *kcontrol;
445 	struct soc_bytes_ext bytes_ext;
446 	unsigned int flags;
447 };
448 
449 #ifdef CONFIG_DEBUG_FS
450 static void wm_adsp_debugfs_save_wmfwname(struct wm_adsp *dsp, const char *s)
451 {
452 	char *tmp = kasprintf(GFP_KERNEL, "%s\n", s);
453 
454 	kfree(dsp->wmfw_file_name);
455 	dsp->wmfw_file_name = tmp;
456 }
457 
458 static void wm_adsp_debugfs_save_binname(struct wm_adsp *dsp, const char *s)
459 {
460 	char *tmp = kasprintf(GFP_KERNEL, "%s\n", s);
461 
462 	kfree(dsp->bin_file_name);
463 	dsp->bin_file_name = tmp;
464 }
465 
466 static void wm_adsp_debugfs_clear(struct wm_adsp *dsp)
467 {
468 	kfree(dsp->wmfw_file_name);
469 	kfree(dsp->bin_file_name);
470 	dsp->wmfw_file_name = NULL;
471 	dsp->bin_file_name = NULL;
472 }
473 
474 static ssize_t wm_adsp_debugfs_wmfw_read(struct file *file,
475 					 char __user *user_buf,
476 					 size_t count, loff_t *ppos)
477 {
478 	struct wm_adsp *dsp = file->private_data;
479 	ssize_t ret;
480 
481 	mutex_lock(&dsp->pwr_lock);
482 
483 	if (!dsp->wmfw_file_name || !dsp->booted)
484 		ret = 0;
485 	else
486 		ret = simple_read_from_buffer(user_buf, count, ppos,
487 					      dsp->wmfw_file_name,
488 					      strlen(dsp->wmfw_file_name));
489 
490 	mutex_unlock(&dsp->pwr_lock);
491 	return ret;
492 }
493 
494 static ssize_t wm_adsp_debugfs_bin_read(struct file *file,
495 					char __user *user_buf,
496 					size_t count, loff_t *ppos)
497 {
498 	struct wm_adsp *dsp = file->private_data;
499 	ssize_t ret;
500 
501 	mutex_lock(&dsp->pwr_lock);
502 
503 	if (!dsp->bin_file_name || !dsp->booted)
504 		ret = 0;
505 	else
506 		ret = simple_read_from_buffer(user_buf, count, ppos,
507 					      dsp->bin_file_name,
508 					      strlen(dsp->bin_file_name));
509 
510 	mutex_unlock(&dsp->pwr_lock);
511 	return ret;
512 }
513 
514 static const struct {
515 	const char *name;
516 	const struct file_operations fops;
517 } wm_adsp_debugfs_fops[] = {
518 	{
519 		.name = "wmfw_file_name",
520 		.fops = {
521 			.open = simple_open,
522 			.read = wm_adsp_debugfs_wmfw_read,
523 		},
524 	},
525 	{
526 		.name = "bin_file_name",
527 		.fops = {
528 			.open = simple_open,
529 			.read = wm_adsp_debugfs_bin_read,
530 		},
531 	},
532 };
533 
534 static void wm_adsp2_init_debugfs(struct wm_adsp *dsp,
535 				  struct snd_soc_codec *codec)
536 {
537 	struct dentry *root = NULL;
538 	char *root_name;
539 	int i;
540 
541 	if (!codec->component.debugfs_root) {
542 		adsp_err(dsp, "No codec debugfs root\n");
543 		goto err;
544 	}
545 
546 	root_name = kmalloc(PAGE_SIZE, GFP_KERNEL);
547 	if (!root_name)
548 		goto err;
549 
550 	snprintf(root_name, PAGE_SIZE, "dsp%d", dsp->num);
551 	root = debugfs_create_dir(root_name, codec->component.debugfs_root);
552 	kfree(root_name);
553 
554 	if (!root)
555 		goto err;
556 
557 	if (!debugfs_create_bool("booted", S_IRUGO, root, &dsp->booted))
558 		goto err;
559 
560 	if (!debugfs_create_bool("running", S_IRUGO, root, &dsp->running))
561 		goto err;
562 
563 	if (!debugfs_create_x32("fw_id", S_IRUGO, root, &dsp->fw_id))
564 		goto err;
565 
566 	if (!debugfs_create_x32("fw_version", S_IRUGO, root,
567 				&dsp->fw_id_version))
568 		goto err;
569 
570 	for (i = 0; i < ARRAY_SIZE(wm_adsp_debugfs_fops); ++i) {
571 		if (!debugfs_create_file(wm_adsp_debugfs_fops[i].name,
572 					 S_IRUGO, root, dsp,
573 					 &wm_adsp_debugfs_fops[i].fops))
574 			goto err;
575 	}
576 
577 	dsp->debugfs_root = root;
578 	return;
579 
580 err:
581 	debugfs_remove_recursive(root);
582 	adsp_err(dsp, "Failed to create debugfs\n");
583 }
584 
585 static void wm_adsp2_cleanup_debugfs(struct wm_adsp *dsp)
586 {
587 	wm_adsp_debugfs_clear(dsp);
588 	debugfs_remove_recursive(dsp->debugfs_root);
589 }
590 #else
591 static inline void wm_adsp2_init_debugfs(struct wm_adsp *dsp,
592 					 struct snd_soc_codec *codec)
593 {
594 }
595 
596 static inline void wm_adsp2_cleanup_debugfs(struct wm_adsp *dsp)
597 {
598 }
599 
600 static inline void wm_adsp_debugfs_save_wmfwname(struct wm_adsp *dsp,
601 						 const char *s)
602 {
603 }
604 
605 static inline void wm_adsp_debugfs_save_binname(struct wm_adsp *dsp,
606 						const char *s)
607 {
608 }
609 
610 static inline void wm_adsp_debugfs_clear(struct wm_adsp *dsp)
611 {
612 }
613 #endif
614 
615 static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol,
616 			  struct snd_ctl_elem_value *ucontrol)
617 {
618 	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
619 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
620 	struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec);
621 
622 	ucontrol->value.enumerated.item[0] = dsp[e->shift_l].fw;
623 
624 	return 0;
625 }
626 
627 static int wm_adsp_fw_put(struct snd_kcontrol *kcontrol,
628 			  struct snd_ctl_elem_value *ucontrol)
629 {
630 	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
631 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
632 	struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec);
633 	int ret = 0;
634 
635 	if (ucontrol->value.enumerated.item[0] == dsp[e->shift_l].fw)
636 		return 0;
637 
638 	if (ucontrol->value.enumerated.item[0] >= WM_ADSP_NUM_FW)
639 		return -EINVAL;
640 
641 	mutex_lock(&dsp[e->shift_l].pwr_lock);
642 
643 	if (dsp[e->shift_l].booted || dsp[e->shift_l].compr)
644 		ret = -EBUSY;
645 	else
646 		dsp[e->shift_l].fw = ucontrol->value.enumerated.item[0];
647 
648 	mutex_unlock(&dsp[e->shift_l].pwr_lock);
649 
650 	return ret;
651 }
652 
653 static const struct soc_enum wm_adsp_fw_enum[] = {
654 	SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
655 	SOC_ENUM_SINGLE(0, 1, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
656 	SOC_ENUM_SINGLE(0, 2, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
657 	SOC_ENUM_SINGLE(0, 3, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
658 };
659 
660 const struct snd_kcontrol_new wm_adsp_fw_controls[] = {
661 	SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0],
662 		     wm_adsp_fw_get, wm_adsp_fw_put),
663 	SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1],
664 		     wm_adsp_fw_get, wm_adsp_fw_put),
665 	SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2],
666 		     wm_adsp_fw_get, wm_adsp_fw_put),
667 	SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3],
668 		     wm_adsp_fw_get, wm_adsp_fw_put),
669 };
670 EXPORT_SYMBOL_GPL(wm_adsp_fw_controls);
671 
672 static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp,
673 							int type)
674 {
675 	int i;
676 
677 	for (i = 0; i < dsp->num_mems; i++)
678 		if (dsp->mem[i].type == type)
679 			return &dsp->mem[i];
680 
681 	return NULL;
682 }
683 
684 static unsigned int wm_adsp_region_to_reg(struct wm_adsp_region const *mem,
685 					  unsigned int offset)
686 {
687 	if (WARN_ON(!mem))
688 		return offset;
689 	switch (mem->type) {
690 	case WMFW_ADSP1_PM:
691 		return mem->base + (offset * 3);
692 	case WMFW_ADSP1_DM:
693 		return mem->base + (offset * 2);
694 	case WMFW_ADSP2_XM:
695 		return mem->base + (offset * 2);
696 	case WMFW_ADSP2_YM:
697 		return mem->base + (offset * 2);
698 	case WMFW_ADSP1_ZM:
699 		return mem->base + (offset * 2);
700 	default:
701 		WARN(1, "Unknown memory region type");
702 		return offset;
703 	}
704 }
705 
706 static void wm_adsp2_show_fw_status(struct wm_adsp *dsp)
707 {
708 	u16 scratch[4];
709 	int ret;
710 
711 	ret = regmap_raw_read(dsp->regmap, dsp->base + ADSP2_SCRATCH0,
712 				scratch, sizeof(scratch));
713 	if (ret) {
714 		adsp_err(dsp, "Failed to read SCRATCH regs: %d\n", ret);
715 		return;
716 	}
717 
718 	adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n",
719 		 be16_to_cpu(scratch[0]),
720 		 be16_to_cpu(scratch[1]),
721 		 be16_to_cpu(scratch[2]),
722 		 be16_to_cpu(scratch[3]));
723 }
724 
725 static inline struct wm_coeff_ctl *bytes_ext_to_ctl(struct soc_bytes_ext *ext)
726 {
727 	return container_of(ext, struct wm_coeff_ctl, bytes_ext);
728 }
729 
730 static int wm_coeff_info(struct snd_kcontrol *kctl,
731 			 struct snd_ctl_elem_info *uinfo)
732 {
733 	struct soc_bytes_ext *bytes_ext =
734 		(struct soc_bytes_ext *)kctl->private_value;
735 	struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext);
736 
737 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
738 	uinfo->count = ctl->len;
739 	return 0;
740 }
741 
742 static int wm_coeff_write_control(struct wm_coeff_ctl *ctl,
743 				  const void *buf, size_t len)
744 {
745 	struct wm_adsp_alg_region *alg_region = &ctl->alg_region;
746 	const struct wm_adsp_region *mem;
747 	struct wm_adsp *dsp = ctl->dsp;
748 	void *scratch;
749 	int ret;
750 	unsigned int reg;
751 
752 	mem = wm_adsp_find_region(dsp, alg_region->type);
753 	if (!mem) {
754 		adsp_err(dsp, "No base for region %x\n",
755 			 alg_region->type);
756 		return -EINVAL;
757 	}
758 
759 	reg = ctl->alg_region.base + ctl->offset;
760 	reg = wm_adsp_region_to_reg(mem, reg);
761 
762 	scratch = kmemdup(buf, len, GFP_KERNEL | GFP_DMA);
763 	if (!scratch)
764 		return -ENOMEM;
765 
766 	ret = regmap_raw_write(dsp->regmap, reg, scratch,
767 			       len);
768 	if (ret) {
769 		adsp_err(dsp, "Failed to write %zu bytes to %x: %d\n",
770 			 len, reg, ret);
771 		kfree(scratch);
772 		return ret;
773 	}
774 	adsp_dbg(dsp, "Wrote %zu bytes to %x\n", len, reg);
775 
776 	kfree(scratch);
777 
778 	return 0;
779 }
780 
781 static int wm_coeff_put(struct snd_kcontrol *kctl,
782 			struct snd_ctl_elem_value *ucontrol)
783 {
784 	struct soc_bytes_ext *bytes_ext =
785 		(struct soc_bytes_ext *)kctl->private_value;
786 	struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext);
787 	char *p = ucontrol->value.bytes.data;
788 	int ret = 0;
789 
790 	mutex_lock(&ctl->dsp->pwr_lock);
791 
792 	memcpy(ctl->cache, p, ctl->len);
793 
794 	ctl->set = 1;
795 	if (ctl->enabled && ctl->dsp->running)
796 		ret = wm_coeff_write_control(ctl, p, ctl->len);
797 
798 	mutex_unlock(&ctl->dsp->pwr_lock);
799 
800 	return ret;
801 }
802 
803 static int wm_coeff_tlv_put(struct snd_kcontrol *kctl,
804 			    const unsigned int __user *bytes, unsigned int size)
805 {
806 	struct soc_bytes_ext *bytes_ext =
807 		(struct soc_bytes_ext *)kctl->private_value;
808 	struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext);
809 	int ret = 0;
810 
811 	mutex_lock(&ctl->dsp->pwr_lock);
812 
813 	if (copy_from_user(ctl->cache, bytes, size)) {
814 		ret = -EFAULT;
815 	} else {
816 		ctl->set = 1;
817 		if (ctl->enabled && ctl->dsp->running)
818 			ret = wm_coeff_write_control(ctl, ctl->cache, size);
819 	}
820 
821 	mutex_unlock(&ctl->dsp->pwr_lock);
822 
823 	return ret;
824 }
825 
826 static int wm_coeff_read_control(struct wm_coeff_ctl *ctl,
827 				 void *buf, size_t len)
828 {
829 	struct wm_adsp_alg_region *alg_region = &ctl->alg_region;
830 	const struct wm_adsp_region *mem;
831 	struct wm_adsp *dsp = ctl->dsp;
832 	void *scratch;
833 	int ret;
834 	unsigned int reg;
835 
836 	mem = wm_adsp_find_region(dsp, alg_region->type);
837 	if (!mem) {
838 		adsp_err(dsp, "No base for region %x\n",
839 			 alg_region->type);
840 		return -EINVAL;
841 	}
842 
843 	reg = ctl->alg_region.base + ctl->offset;
844 	reg = wm_adsp_region_to_reg(mem, reg);
845 
846 	scratch = kmalloc(len, GFP_KERNEL | GFP_DMA);
847 	if (!scratch)
848 		return -ENOMEM;
849 
850 	ret = regmap_raw_read(dsp->regmap, reg, scratch, len);
851 	if (ret) {
852 		adsp_err(dsp, "Failed to read %zu bytes from %x: %d\n",
853 			 len, reg, ret);
854 		kfree(scratch);
855 		return ret;
856 	}
857 	adsp_dbg(dsp, "Read %zu bytes from %x\n", len, reg);
858 
859 	memcpy(buf, scratch, len);
860 	kfree(scratch);
861 
862 	return 0;
863 }
864 
865 static int wm_coeff_get(struct snd_kcontrol *kctl,
866 			struct snd_ctl_elem_value *ucontrol)
867 {
868 	struct soc_bytes_ext *bytes_ext =
869 		(struct soc_bytes_ext *)kctl->private_value;
870 	struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext);
871 	char *p = ucontrol->value.bytes.data;
872 	int ret = 0;
873 
874 	mutex_lock(&ctl->dsp->pwr_lock);
875 
876 	if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) {
877 		if (ctl->enabled && ctl->dsp->running)
878 			ret = wm_coeff_read_control(ctl, p, ctl->len);
879 		else
880 			ret = -EPERM;
881 	} else {
882 		if (!ctl->flags && ctl->enabled && ctl->dsp->running)
883 			ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len);
884 
885 		memcpy(p, ctl->cache, ctl->len);
886 	}
887 
888 	mutex_unlock(&ctl->dsp->pwr_lock);
889 
890 	return ret;
891 }
892 
893 static int wm_coeff_tlv_get(struct snd_kcontrol *kctl,
894 			    unsigned int __user *bytes, unsigned int size)
895 {
896 	struct soc_bytes_ext *bytes_ext =
897 		(struct soc_bytes_ext *)kctl->private_value;
898 	struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext);
899 	int ret = 0;
900 
901 	mutex_lock(&ctl->dsp->pwr_lock);
902 
903 	if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) {
904 		if (ctl->enabled && ctl->dsp->running)
905 			ret = wm_coeff_read_control(ctl, ctl->cache, size);
906 		else
907 			ret = -EPERM;
908 	} else {
909 		if (!ctl->flags && ctl->enabled && ctl->dsp->running)
910 			ret = wm_coeff_read_control(ctl, ctl->cache, size);
911 	}
912 
913 	if (!ret && copy_to_user(bytes, ctl->cache, size))
914 		ret = -EFAULT;
915 
916 	mutex_unlock(&ctl->dsp->pwr_lock);
917 
918 	return ret;
919 }
920 
921 struct wmfw_ctl_work {
922 	struct wm_adsp *dsp;
923 	struct wm_coeff_ctl *ctl;
924 	struct work_struct work;
925 };
926 
927 static unsigned int wmfw_convert_flags(unsigned int in, unsigned int len)
928 {
929 	unsigned int out, rd, wr, vol;
930 
931 	if (len > ADSP_MAX_STD_CTRL_SIZE) {
932 		rd = SNDRV_CTL_ELEM_ACCESS_TLV_READ;
933 		wr = SNDRV_CTL_ELEM_ACCESS_TLV_WRITE;
934 		vol = SNDRV_CTL_ELEM_ACCESS_VOLATILE;
935 
936 		out = SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
937 	} else {
938 		rd = SNDRV_CTL_ELEM_ACCESS_READ;
939 		wr = SNDRV_CTL_ELEM_ACCESS_WRITE;
940 		vol = SNDRV_CTL_ELEM_ACCESS_VOLATILE;
941 
942 		out = 0;
943 	}
944 
945 	if (in) {
946 		if (in & WMFW_CTL_FLAG_READABLE)
947 			out |= rd;
948 		if (in & WMFW_CTL_FLAG_WRITEABLE)
949 			out |= wr;
950 		if (in & WMFW_CTL_FLAG_VOLATILE)
951 			out |= vol;
952 	} else {
953 		out |= rd | wr | vol;
954 	}
955 
956 	return out;
957 }
958 
959 static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl)
960 {
961 	struct snd_kcontrol_new *kcontrol;
962 	int ret;
963 
964 	if (!ctl || !ctl->name)
965 		return -EINVAL;
966 
967 	kcontrol = kzalloc(sizeof(*kcontrol), GFP_KERNEL);
968 	if (!kcontrol)
969 		return -ENOMEM;
970 	kcontrol->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
971 
972 	kcontrol->name = ctl->name;
973 	kcontrol->info = wm_coeff_info;
974 	kcontrol->get = wm_coeff_get;
975 	kcontrol->put = wm_coeff_put;
976 	kcontrol->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
977 	kcontrol->tlv.c = snd_soc_bytes_tlv_callback;
978 	kcontrol->private_value = (unsigned long)&ctl->bytes_ext;
979 
980 	ctl->bytes_ext.max = ctl->len;
981 	ctl->bytes_ext.get = wm_coeff_tlv_get;
982 	ctl->bytes_ext.put = wm_coeff_tlv_put;
983 
984 	kcontrol->access = wmfw_convert_flags(ctl->flags, ctl->len);
985 
986 	ret = snd_soc_add_card_controls(dsp->card, kcontrol, 1);
987 	if (ret < 0)
988 		goto err_kcontrol;
989 
990 	kfree(kcontrol);
991 
992 	ctl->kcontrol = snd_soc_card_get_kcontrol(dsp->card, ctl->name);
993 
994 	return 0;
995 
996 err_kcontrol:
997 	kfree(kcontrol);
998 	return ret;
999 }
1000 
1001 static int wm_coeff_init_control_caches(struct wm_adsp *dsp)
1002 {
1003 	struct wm_coeff_ctl *ctl;
1004 	int ret;
1005 
1006 	list_for_each_entry(ctl, &dsp->ctl_list, list) {
1007 		if (!ctl->enabled || ctl->set)
1008 			continue;
1009 		if (ctl->flags & WMFW_CTL_FLAG_VOLATILE)
1010 			continue;
1011 
1012 		ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len);
1013 		if (ret < 0)
1014 			return ret;
1015 	}
1016 
1017 	return 0;
1018 }
1019 
1020 static int wm_coeff_sync_controls(struct wm_adsp *dsp)
1021 {
1022 	struct wm_coeff_ctl *ctl;
1023 	int ret;
1024 
1025 	list_for_each_entry(ctl, &dsp->ctl_list, list) {
1026 		if (!ctl->enabled)
1027 			continue;
1028 		if (ctl->set && !(ctl->flags & WMFW_CTL_FLAG_VOLATILE)) {
1029 			ret = wm_coeff_write_control(ctl, ctl->cache, ctl->len);
1030 			if (ret < 0)
1031 				return ret;
1032 		}
1033 	}
1034 
1035 	return 0;
1036 }
1037 
1038 static void wm_adsp_ctl_work(struct work_struct *work)
1039 {
1040 	struct wmfw_ctl_work *ctl_work = container_of(work,
1041 						      struct wmfw_ctl_work,
1042 						      work);
1043 
1044 	wmfw_add_ctl(ctl_work->dsp, ctl_work->ctl);
1045 	kfree(ctl_work);
1046 }
1047 
1048 static void wm_adsp_free_ctl_blk(struct wm_coeff_ctl *ctl)
1049 {
1050 	kfree(ctl->cache);
1051 	kfree(ctl->name);
1052 	kfree(ctl);
1053 }
1054 
1055 static int wm_adsp_create_control(struct wm_adsp *dsp,
1056 				  const struct wm_adsp_alg_region *alg_region,
1057 				  unsigned int offset, unsigned int len,
1058 				  const char *subname, unsigned int subname_len,
1059 				  unsigned int flags)
1060 {
1061 	struct wm_coeff_ctl *ctl;
1062 	struct wmfw_ctl_work *ctl_work;
1063 	char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
1064 	char *region_name;
1065 	int ret;
1066 
1067 	if (flags & WMFW_CTL_FLAG_SYS)
1068 		return 0;
1069 
1070 	switch (alg_region->type) {
1071 	case WMFW_ADSP1_PM:
1072 		region_name = "PM";
1073 		break;
1074 	case WMFW_ADSP1_DM:
1075 		region_name = "DM";
1076 		break;
1077 	case WMFW_ADSP2_XM:
1078 		region_name = "XM";
1079 		break;
1080 	case WMFW_ADSP2_YM:
1081 		region_name = "YM";
1082 		break;
1083 	case WMFW_ADSP1_ZM:
1084 		region_name = "ZM";
1085 		break;
1086 	default:
1087 		adsp_err(dsp, "Unknown region type: %d\n", alg_region->type);
1088 		return -EINVAL;
1089 	}
1090 
1091 	switch (dsp->fw_ver) {
1092 	case 0:
1093 	case 1:
1094 		snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "DSP%d %s %x",
1095 			 dsp->num, region_name, alg_region->alg);
1096 		break;
1097 	default:
1098 		ret = snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN,
1099 				"DSP%d%c %.12s %x", dsp->num, *region_name,
1100 				wm_adsp_fw_text[dsp->fw], alg_region->alg);
1101 
1102 		/* Truncate the subname from the start if it is too long */
1103 		if (subname) {
1104 			int avail = SNDRV_CTL_ELEM_ID_NAME_MAXLEN - ret - 2;
1105 			int skip = 0;
1106 
1107 			if (subname_len > avail)
1108 				skip = subname_len - avail;
1109 
1110 			snprintf(name + ret,
1111 				 SNDRV_CTL_ELEM_ID_NAME_MAXLEN - ret, " %.*s",
1112 				 subname_len - skip, subname + skip);
1113 		}
1114 		break;
1115 	}
1116 
1117 	list_for_each_entry(ctl, &dsp->ctl_list, list) {
1118 		if (!strcmp(ctl->name, name)) {
1119 			if (!ctl->enabled)
1120 				ctl->enabled = 1;
1121 			return 0;
1122 		}
1123 	}
1124 
1125 	ctl = kzalloc(sizeof(*ctl), GFP_KERNEL);
1126 	if (!ctl)
1127 		return -ENOMEM;
1128 	ctl->fw_name = wm_adsp_fw_text[dsp->fw];
1129 	ctl->alg_region = *alg_region;
1130 	ctl->name = kmemdup(name, strlen(name) + 1, GFP_KERNEL);
1131 	if (!ctl->name) {
1132 		ret = -ENOMEM;
1133 		goto err_ctl;
1134 	}
1135 	ctl->enabled = 1;
1136 	ctl->set = 0;
1137 	ctl->ops.xget = wm_coeff_get;
1138 	ctl->ops.xput = wm_coeff_put;
1139 	ctl->dsp = dsp;
1140 
1141 	ctl->flags = flags;
1142 	ctl->offset = offset;
1143 	ctl->len = len;
1144 	ctl->cache = kzalloc(ctl->len, GFP_KERNEL);
1145 	if (!ctl->cache) {
1146 		ret = -ENOMEM;
1147 		goto err_ctl_name;
1148 	}
1149 
1150 	list_add(&ctl->list, &dsp->ctl_list);
1151 
1152 	ctl_work = kzalloc(sizeof(*ctl_work), GFP_KERNEL);
1153 	if (!ctl_work) {
1154 		ret = -ENOMEM;
1155 		goto err_ctl_cache;
1156 	}
1157 
1158 	ctl_work->dsp = dsp;
1159 	ctl_work->ctl = ctl;
1160 	INIT_WORK(&ctl_work->work, wm_adsp_ctl_work);
1161 	schedule_work(&ctl_work->work);
1162 
1163 	return 0;
1164 
1165 err_ctl_cache:
1166 	kfree(ctl->cache);
1167 err_ctl_name:
1168 	kfree(ctl->name);
1169 err_ctl:
1170 	kfree(ctl);
1171 
1172 	return ret;
1173 }
1174 
1175 struct wm_coeff_parsed_alg {
1176 	int id;
1177 	const u8 *name;
1178 	int name_len;
1179 	int ncoeff;
1180 };
1181 
1182 struct wm_coeff_parsed_coeff {
1183 	int offset;
1184 	int mem_type;
1185 	const u8 *name;
1186 	int name_len;
1187 	int ctl_type;
1188 	int flags;
1189 	int len;
1190 };
1191 
1192 static int wm_coeff_parse_string(int bytes, const u8 **pos, const u8 **str)
1193 {
1194 	int length;
1195 
1196 	switch (bytes) {
1197 	case 1:
1198 		length = **pos;
1199 		break;
1200 	case 2:
1201 		length = le16_to_cpu(*((__le16 *)*pos));
1202 		break;
1203 	default:
1204 		return 0;
1205 	}
1206 
1207 	if (str)
1208 		*str = *pos + bytes;
1209 
1210 	*pos += ((length + bytes) + 3) & ~0x03;
1211 
1212 	return length;
1213 }
1214 
1215 static int wm_coeff_parse_int(int bytes, const u8 **pos)
1216 {
1217 	int val = 0;
1218 
1219 	switch (bytes) {
1220 	case 2:
1221 		val = le16_to_cpu(*((__le16 *)*pos));
1222 		break;
1223 	case 4:
1224 		val = le32_to_cpu(*((__le32 *)*pos));
1225 		break;
1226 	default:
1227 		break;
1228 	}
1229 
1230 	*pos += bytes;
1231 
1232 	return val;
1233 }
1234 
1235 static inline void wm_coeff_parse_alg(struct wm_adsp *dsp, const u8 **data,
1236 				      struct wm_coeff_parsed_alg *blk)
1237 {
1238 	const struct wmfw_adsp_alg_data *raw;
1239 
1240 	switch (dsp->fw_ver) {
1241 	case 0:
1242 	case 1:
1243 		raw = (const struct wmfw_adsp_alg_data *)*data;
1244 		*data = raw->data;
1245 
1246 		blk->id = le32_to_cpu(raw->id);
1247 		blk->name = raw->name;
1248 		blk->name_len = strlen(raw->name);
1249 		blk->ncoeff = le32_to_cpu(raw->ncoeff);
1250 		break;
1251 	default:
1252 		blk->id = wm_coeff_parse_int(sizeof(raw->id), data);
1253 		blk->name_len = wm_coeff_parse_string(sizeof(u8), data,
1254 						      &blk->name);
1255 		wm_coeff_parse_string(sizeof(u16), data, NULL);
1256 		blk->ncoeff = wm_coeff_parse_int(sizeof(raw->ncoeff), data);
1257 		break;
1258 	}
1259 
1260 	adsp_dbg(dsp, "Algorithm ID: %#x\n", blk->id);
1261 	adsp_dbg(dsp, "Algorithm name: %.*s\n", blk->name_len, blk->name);
1262 	adsp_dbg(dsp, "# of coefficient descriptors: %#x\n", blk->ncoeff);
1263 }
1264 
1265 static inline void wm_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data,
1266 					struct wm_coeff_parsed_coeff *blk)
1267 {
1268 	const struct wmfw_adsp_coeff_data *raw;
1269 	const u8 *tmp;
1270 	int length;
1271 
1272 	switch (dsp->fw_ver) {
1273 	case 0:
1274 	case 1:
1275 		raw = (const struct wmfw_adsp_coeff_data *)*data;
1276 		*data = *data + sizeof(raw->hdr) + le32_to_cpu(raw->hdr.size);
1277 
1278 		blk->offset = le16_to_cpu(raw->hdr.offset);
1279 		blk->mem_type = le16_to_cpu(raw->hdr.type);
1280 		blk->name = raw->name;
1281 		blk->name_len = strlen(raw->name);
1282 		blk->ctl_type = le16_to_cpu(raw->ctl_type);
1283 		blk->flags = le16_to_cpu(raw->flags);
1284 		blk->len = le32_to_cpu(raw->len);
1285 		break;
1286 	default:
1287 		tmp = *data;
1288 		blk->offset = wm_coeff_parse_int(sizeof(raw->hdr.offset), &tmp);
1289 		blk->mem_type = wm_coeff_parse_int(sizeof(raw->hdr.type), &tmp);
1290 		length = wm_coeff_parse_int(sizeof(raw->hdr.size), &tmp);
1291 		blk->name_len = wm_coeff_parse_string(sizeof(u8), &tmp,
1292 						      &blk->name);
1293 		wm_coeff_parse_string(sizeof(u8), &tmp, NULL);
1294 		wm_coeff_parse_string(sizeof(u16), &tmp, NULL);
1295 		blk->ctl_type = wm_coeff_parse_int(sizeof(raw->ctl_type), &tmp);
1296 		blk->flags = wm_coeff_parse_int(sizeof(raw->flags), &tmp);
1297 		blk->len = wm_coeff_parse_int(sizeof(raw->len), &tmp);
1298 
1299 		*data = *data + sizeof(raw->hdr) + length;
1300 		break;
1301 	}
1302 
1303 	adsp_dbg(dsp, "\tCoefficient type: %#x\n", blk->mem_type);
1304 	adsp_dbg(dsp, "\tCoefficient offset: %#x\n", blk->offset);
1305 	adsp_dbg(dsp, "\tCoefficient name: %.*s\n", blk->name_len, blk->name);
1306 	adsp_dbg(dsp, "\tCoefficient flags: %#x\n", blk->flags);
1307 	adsp_dbg(dsp, "\tALSA control type: %#x\n", blk->ctl_type);
1308 	adsp_dbg(dsp, "\tALSA control len: %#x\n", blk->len);
1309 }
1310 
1311 static int wm_adsp_parse_coeff(struct wm_adsp *dsp,
1312 			       const struct wmfw_region *region)
1313 {
1314 	struct wm_adsp_alg_region alg_region = {};
1315 	struct wm_coeff_parsed_alg alg_blk;
1316 	struct wm_coeff_parsed_coeff coeff_blk;
1317 	const u8 *data = region->data;
1318 	int i, ret;
1319 
1320 	wm_coeff_parse_alg(dsp, &data, &alg_blk);
1321 	for (i = 0; i < alg_blk.ncoeff; i++) {
1322 		wm_coeff_parse_coeff(dsp, &data, &coeff_blk);
1323 
1324 		switch (coeff_blk.ctl_type) {
1325 		case SNDRV_CTL_ELEM_TYPE_BYTES:
1326 			break;
1327 		default:
1328 			adsp_err(dsp, "Unknown control type: %d\n",
1329 				 coeff_blk.ctl_type);
1330 			return -EINVAL;
1331 		}
1332 
1333 		alg_region.type = coeff_blk.mem_type;
1334 		alg_region.alg = alg_blk.id;
1335 
1336 		ret = wm_adsp_create_control(dsp, &alg_region,
1337 					     coeff_blk.offset,
1338 					     coeff_blk.len,
1339 					     coeff_blk.name,
1340 					     coeff_blk.name_len,
1341 					     coeff_blk.flags);
1342 		if (ret < 0)
1343 			adsp_err(dsp, "Failed to create control: %.*s, %d\n",
1344 				 coeff_blk.name_len, coeff_blk.name, ret);
1345 	}
1346 
1347 	return 0;
1348 }
1349 
1350 static int wm_adsp_load(struct wm_adsp *dsp)
1351 {
1352 	LIST_HEAD(buf_list);
1353 	const struct firmware *firmware;
1354 	struct regmap *regmap = dsp->regmap;
1355 	unsigned int pos = 0;
1356 	const struct wmfw_header *header;
1357 	const struct wmfw_adsp1_sizes *adsp1_sizes;
1358 	const struct wmfw_adsp2_sizes *adsp2_sizes;
1359 	const struct wmfw_footer *footer;
1360 	const struct wmfw_region *region;
1361 	const struct wm_adsp_region *mem;
1362 	const char *region_name;
1363 	char *file, *text;
1364 	struct wm_adsp_buf *buf;
1365 	unsigned int reg;
1366 	int regions = 0;
1367 	int ret, offset, type, sizes;
1368 
1369 	file = kzalloc(PAGE_SIZE, GFP_KERNEL);
1370 	if (file == NULL)
1371 		return -ENOMEM;
1372 
1373 	snprintf(file, PAGE_SIZE, "%s-dsp%d-%s.wmfw", dsp->part, dsp->num,
1374 		 wm_adsp_fw[dsp->fw].file);
1375 	file[PAGE_SIZE - 1] = '\0';
1376 
1377 	ret = request_firmware(&firmware, file, dsp->dev);
1378 	if (ret != 0) {
1379 		adsp_err(dsp, "Failed to request '%s'\n", file);
1380 		goto out;
1381 	}
1382 	ret = -EINVAL;
1383 
1384 	pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer);
1385 	if (pos >= firmware->size) {
1386 		adsp_err(dsp, "%s: file too short, %zu bytes\n",
1387 			 file, firmware->size);
1388 		goto out_fw;
1389 	}
1390 
1391 	header = (void *)&firmware->data[0];
1392 
1393 	if (memcmp(&header->magic[0], "WMFW", 4) != 0) {
1394 		adsp_err(dsp, "%s: invalid magic\n", file);
1395 		goto out_fw;
1396 	}
1397 
1398 	switch (header->ver) {
1399 	case 0:
1400 		adsp_warn(dsp, "%s: Depreciated file format %d\n",
1401 			  file, header->ver);
1402 		break;
1403 	case 1:
1404 	case 2:
1405 		break;
1406 	default:
1407 		adsp_err(dsp, "%s: unknown file format %d\n",
1408 			 file, header->ver);
1409 		goto out_fw;
1410 	}
1411 
1412 	adsp_info(dsp, "Firmware version: %d\n", header->ver);
1413 	dsp->fw_ver = header->ver;
1414 
1415 	if (header->core != dsp->type) {
1416 		adsp_err(dsp, "%s: invalid core %d != %d\n",
1417 			 file, header->core, dsp->type);
1418 		goto out_fw;
1419 	}
1420 
1421 	switch (dsp->type) {
1422 	case WMFW_ADSP1:
1423 		pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer);
1424 		adsp1_sizes = (void *)&(header[1]);
1425 		footer = (void *)&(adsp1_sizes[1]);
1426 		sizes = sizeof(*adsp1_sizes);
1427 
1428 		adsp_dbg(dsp, "%s: %d DM, %d PM, %d ZM\n",
1429 			 file, le32_to_cpu(adsp1_sizes->dm),
1430 			 le32_to_cpu(adsp1_sizes->pm),
1431 			 le32_to_cpu(adsp1_sizes->zm));
1432 		break;
1433 
1434 	case WMFW_ADSP2:
1435 		pos = sizeof(*header) + sizeof(*adsp2_sizes) + sizeof(*footer);
1436 		adsp2_sizes = (void *)&(header[1]);
1437 		footer = (void *)&(adsp2_sizes[1]);
1438 		sizes = sizeof(*adsp2_sizes);
1439 
1440 		adsp_dbg(dsp, "%s: %d XM, %d YM %d PM, %d ZM\n",
1441 			 file, le32_to_cpu(adsp2_sizes->xm),
1442 			 le32_to_cpu(adsp2_sizes->ym),
1443 			 le32_to_cpu(adsp2_sizes->pm),
1444 			 le32_to_cpu(adsp2_sizes->zm));
1445 		break;
1446 
1447 	default:
1448 		WARN(1, "Unknown DSP type");
1449 		goto out_fw;
1450 	}
1451 
1452 	if (le32_to_cpu(header->len) != sizeof(*header) +
1453 	    sizes + sizeof(*footer)) {
1454 		adsp_err(dsp, "%s: unexpected header length %d\n",
1455 			 file, le32_to_cpu(header->len));
1456 		goto out_fw;
1457 	}
1458 
1459 	adsp_dbg(dsp, "%s: timestamp %llu\n", file,
1460 		 le64_to_cpu(footer->timestamp));
1461 
1462 	while (pos < firmware->size &&
1463 	       pos - firmware->size > sizeof(*region)) {
1464 		region = (void *)&(firmware->data[pos]);
1465 		region_name = "Unknown";
1466 		reg = 0;
1467 		text = NULL;
1468 		offset = le32_to_cpu(region->offset) & 0xffffff;
1469 		type = be32_to_cpu(region->type) & 0xff;
1470 		mem = wm_adsp_find_region(dsp, type);
1471 
1472 		switch (type) {
1473 		case WMFW_NAME_TEXT:
1474 			region_name = "Firmware name";
1475 			text = kzalloc(le32_to_cpu(region->len) + 1,
1476 				       GFP_KERNEL);
1477 			break;
1478 		case WMFW_ALGORITHM_DATA:
1479 			region_name = "Algorithm";
1480 			ret = wm_adsp_parse_coeff(dsp, region);
1481 			if (ret != 0)
1482 				goto out_fw;
1483 			break;
1484 		case WMFW_INFO_TEXT:
1485 			region_name = "Information";
1486 			text = kzalloc(le32_to_cpu(region->len) + 1,
1487 				       GFP_KERNEL);
1488 			break;
1489 		case WMFW_ABSOLUTE:
1490 			region_name = "Absolute";
1491 			reg = offset;
1492 			break;
1493 		case WMFW_ADSP1_PM:
1494 			region_name = "PM";
1495 			reg = wm_adsp_region_to_reg(mem, offset);
1496 			break;
1497 		case WMFW_ADSP1_DM:
1498 			region_name = "DM";
1499 			reg = wm_adsp_region_to_reg(mem, offset);
1500 			break;
1501 		case WMFW_ADSP2_XM:
1502 			region_name = "XM";
1503 			reg = wm_adsp_region_to_reg(mem, offset);
1504 			break;
1505 		case WMFW_ADSP2_YM:
1506 			region_name = "YM";
1507 			reg = wm_adsp_region_to_reg(mem, offset);
1508 			break;
1509 		case WMFW_ADSP1_ZM:
1510 			region_name = "ZM";
1511 			reg = wm_adsp_region_to_reg(mem, offset);
1512 			break;
1513 		default:
1514 			adsp_warn(dsp,
1515 				  "%s.%d: Unknown region type %x at %d(%x)\n",
1516 				  file, regions, type, pos, pos);
1517 			break;
1518 		}
1519 
1520 		adsp_dbg(dsp, "%s.%d: %d bytes at %d in %s\n", file,
1521 			 regions, le32_to_cpu(region->len), offset,
1522 			 region_name);
1523 
1524 		if (text) {
1525 			memcpy(text, region->data, le32_to_cpu(region->len));
1526 			adsp_info(dsp, "%s: %s\n", file, text);
1527 			kfree(text);
1528 		}
1529 
1530 		if (reg) {
1531 			buf = wm_adsp_buf_alloc(region->data,
1532 						le32_to_cpu(region->len),
1533 						&buf_list);
1534 			if (!buf) {
1535 				adsp_err(dsp, "Out of memory\n");
1536 				ret = -ENOMEM;
1537 				goto out_fw;
1538 			}
1539 
1540 			ret = regmap_raw_write_async(regmap, reg, buf->buf,
1541 						     le32_to_cpu(region->len));
1542 			if (ret != 0) {
1543 				adsp_err(dsp,
1544 					"%s.%d: Failed to write %d bytes at %d in %s: %d\n",
1545 					file, regions,
1546 					le32_to_cpu(region->len), offset,
1547 					region_name, ret);
1548 				goto out_fw;
1549 			}
1550 		}
1551 
1552 		pos += le32_to_cpu(region->len) + sizeof(*region);
1553 		regions++;
1554 	}
1555 
1556 	ret = regmap_async_complete(regmap);
1557 	if (ret != 0) {
1558 		adsp_err(dsp, "Failed to complete async write: %d\n", ret);
1559 		goto out_fw;
1560 	}
1561 
1562 	if (pos > firmware->size)
1563 		adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n",
1564 			  file, regions, pos - firmware->size);
1565 
1566 	wm_adsp_debugfs_save_wmfwname(dsp, file);
1567 
1568 out_fw:
1569 	regmap_async_complete(regmap);
1570 	wm_adsp_buf_free(&buf_list);
1571 	release_firmware(firmware);
1572 out:
1573 	kfree(file);
1574 
1575 	return ret;
1576 }
1577 
1578 static void wm_adsp_ctl_fixup_base(struct wm_adsp *dsp,
1579 				  const struct wm_adsp_alg_region *alg_region)
1580 {
1581 	struct wm_coeff_ctl *ctl;
1582 
1583 	list_for_each_entry(ctl, &dsp->ctl_list, list) {
1584 		if (ctl->fw_name == wm_adsp_fw_text[dsp->fw] &&
1585 		    alg_region->alg == ctl->alg_region.alg &&
1586 		    alg_region->type == ctl->alg_region.type) {
1587 			ctl->alg_region.base = alg_region->base;
1588 		}
1589 	}
1590 }
1591 
1592 static void *wm_adsp_read_algs(struct wm_adsp *dsp, size_t n_algs,
1593 			       unsigned int pos, unsigned int len)
1594 {
1595 	void *alg;
1596 	int ret;
1597 	__be32 val;
1598 
1599 	if (n_algs == 0) {
1600 		adsp_err(dsp, "No algorithms\n");
1601 		return ERR_PTR(-EINVAL);
1602 	}
1603 
1604 	if (n_algs > 1024) {
1605 		adsp_err(dsp, "Algorithm count %zx excessive\n", n_algs);
1606 		return ERR_PTR(-EINVAL);
1607 	}
1608 
1609 	/* Read the terminator first to validate the length */
1610 	ret = regmap_raw_read(dsp->regmap, pos + len, &val, sizeof(val));
1611 	if (ret != 0) {
1612 		adsp_err(dsp, "Failed to read algorithm list end: %d\n",
1613 			ret);
1614 		return ERR_PTR(ret);
1615 	}
1616 
1617 	if (be32_to_cpu(val) != 0xbedead)
1618 		adsp_warn(dsp, "Algorithm list end %x 0x%x != 0xbeadead\n",
1619 			  pos + len, be32_to_cpu(val));
1620 
1621 	alg = kzalloc(len * 2, GFP_KERNEL | GFP_DMA);
1622 	if (!alg)
1623 		return ERR_PTR(-ENOMEM);
1624 
1625 	ret = regmap_raw_read(dsp->regmap, pos, alg, len * 2);
1626 	if (ret != 0) {
1627 		adsp_err(dsp, "Failed to read algorithm list: %d\n", ret);
1628 		kfree(alg);
1629 		return ERR_PTR(ret);
1630 	}
1631 
1632 	return alg;
1633 }
1634 
1635 static struct wm_adsp_alg_region *
1636 	wm_adsp_find_alg_region(struct wm_adsp *dsp, int type, unsigned int id)
1637 {
1638 	struct wm_adsp_alg_region *alg_region;
1639 
1640 	list_for_each_entry(alg_region, &dsp->alg_regions, list) {
1641 		if (id == alg_region->alg && type == alg_region->type)
1642 			return alg_region;
1643 	}
1644 
1645 	return NULL;
1646 }
1647 
1648 static struct wm_adsp_alg_region *wm_adsp_create_region(struct wm_adsp *dsp,
1649 							int type, __be32 id,
1650 							__be32 base)
1651 {
1652 	struct wm_adsp_alg_region *alg_region;
1653 
1654 	alg_region = kzalloc(sizeof(*alg_region), GFP_KERNEL);
1655 	if (!alg_region)
1656 		return ERR_PTR(-ENOMEM);
1657 
1658 	alg_region->type = type;
1659 	alg_region->alg = be32_to_cpu(id);
1660 	alg_region->base = be32_to_cpu(base);
1661 
1662 	list_add_tail(&alg_region->list, &dsp->alg_regions);
1663 
1664 	if (dsp->fw_ver > 0)
1665 		wm_adsp_ctl_fixup_base(dsp, alg_region);
1666 
1667 	return alg_region;
1668 }
1669 
1670 static void wm_adsp_free_alg_regions(struct wm_adsp *dsp)
1671 {
1672 	struct wm_adsp_alg_region *alg_region;
1673 
1674 	while (!list_empty(&dsp->alg_regions)) {
1675 		alg_region = list_first_entry(&dsp->alg_regions,
1676 					      struct wm_adsp_alg_region,
1677 					      list);
1678 		list_del(&alg_region->list);
1679 		kfree(alg_region);
1680 	}
1681 }
1682 
1683 static int wm_adsp1_setup_algs(struct wm_adsp *dsp)
1684 {
1685 	struct wmfw_adsp1_id_hdr adsp1_id;
1686 	struct wmfw_adsp1_alg_hdr *adsp1_alg;
1687 	struct wm_adsp_alg_region *alg_region;
1688 	const struct wm_adsp_region *mem;
1689 	unsigned int pos, len;
1690 	size_t n_algs;
1691 	int i, ret;
1692 
1693 	mem = wm_adsp_find_region(dsp, WMFW_ADSP1_DM);
1694 	if (WARN_ON(!mem))
1695 		return -EINVAL;
1696 
1697 	ret = regmap_raw_read(dsp->regmap, mem->base, &adsp1_id,
1698 			      sizeof(adsp1_id));
1699 	if (ret != 0) {
1700 		adsp_err(dsp, "Failed to read algorithm info: %d\n",
1701 			 ret);
1702 		return ret;
1703 	}
1704 
1705 	n_algs = be32_to_cpu(adsp1_id.n_algs);
1706 	dsp->fw_id = be32_to_cpu(adsp1_id.fw.id);
1707 	adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n",
1708 		  dsp->fw_id,
1709 		  (be32_to_cpu(adsp1_id.fw.ver) & 0xff0000) >> 16,
1710 		  (be32_to_cpu(adsp1_id.fw.ver) & 0xff00) >> 8,
1711 		  be32_to_cpu(adsp1_id.fw.ver) & 0xff,
1712 		  n_algs);
1713 
1714 	alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_ZM,
1715 					   adsp1_id.fw.id, adsp1_id.zm);
1716 	if (IS_ERR(alg_region))
1717 		return PTR_ERR(alg_region);
1718 
1719 	alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_DM,
1720 					   adsp1_id.fw.id, adsp1_id.dm);
1721 	if (IS_ERR(alg_region))
1722 		return PTR_ERR(alg_region);
1723 
1724 	pos = sizeof(adsp1_id) / 2;
1725 	len = (sizeof(*adsp1_alg) * n_algs) / 2;
1726 
1727 	adsp1_alg = wm_adsp_read_algs(dsp, n_algs, mem->base + pos, len);
1728 	if (IS_ERR(adsp1_alg))
1729 		return PTR_ERR(adsp1_alg);
1730 
1731 	for (i = 0; i < n_algs; i++) {
1732 		adsp_info(dsp, "%d: ID %x v%d.%d.%d DM@%x ZM@%x\n",
1733 			  i, be32_to_cpu(adsp1_alg[i].alg.id),
1734 			  (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff0000) >> 16,
1735 			  (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff00) >> 8,
1736 			  be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff,
1737 			  be32_to_cpu(adsp1_alg[i].dm),
1738 			  be32_to_cpu(adsp1_alg[i].zm));
1739 
1740 		alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_DM,
1741 						   adsp1_alg[i].alg.id,
1742 						   adsp1_alg[i].dm);
1743 		if (IS_ERR(alg_region)) {
1744 			ret = PTR_ERR(alg_region);
1745 			goto out;
1746 		}
1747 		if (dsp->fw_ver == 0) {
1748 			if (i + 1 < n_algs) {
1749 				len = be32_to_cpu(adsp1_alg[i + 1].dm);
1750 				len -= be32_to_cpu(adsp1_alg[i].dm);
1751 				len *= 4;
1752 				wm_adsp_create_control(dsp, alg_region, 0,
1753 						       len, NULL, 0, 0);
1754 			} else {
1755 				adsp_warn(dsp, "Missing length info for region DM with ID %x\n",
1756 					  be32_to_cpu(adsp1_alg[i].alg.id));
1757 			}
1758 		}
1759 
1760 		alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_ZM,
1761 						   adsp1_alg[i].alg.id,
1762 						   adsp1_alg[i].zm);
1763 		if (IS_ERR(alg_region)) {
1764 			ret = PTR_ERR(alg_region);
1765 			goto out;
1766 		}
1767 		if (dsp->fw_ver == 0) {
1768 			if (i + 1 < n_algs) {
1769 				len = be32_to_cpu(adsp1_alg[i + 1].zm);
1770 				len -= be32_to_cpu(adsp1_alg[i].zm);
1771 				len *= 4;
1772 				wm_adsp_create_control(dsp, alg_region, 0,
1773 						       len, NULL, 0, 0);
1774 			} else {
1775 				adsp_warn(dsp, "Missing length info for region ZM with ID %x\n",
1776 					  be32_to_cpu(adsp1_alg[i].alg.id));
1777 			}
1778 		}
1779 	}
1780 
1781 out:
1782 	kfree(adsp1_alg);
1783 	return ret;
1784 }
1785 
1786 static int wm_adsp2_setup_algs(struct wm_adsp *dsp)
1787 {
1788 	struct wmfw_adsp2_id_hdr adsp2_id;
1789 	struct wmfw_adsp2_alg_hdr *adsp2_alg;
1790 	struct wm_adsp_alg_region *alg_region;
1791 	const struct wm_adsp_region *mem;
1792 	unsigned int pos, len;
1793 	size_t n_algs;
1794 	int i, ret;
1795 
1796 	mem = wm_adsp_find_region(dsp, WMFW_ADSP2_XM);
1797 	if (WARN_ON(!mem))
1798 		return -EINVAL;
1799 
1800 	ret = regmap_raw_read(dsp->regmap, mem->base, &adsp2_id,
1801 			      sizeof(adsp2_id));
1802 	if (ret != 0) {
1803 		adsp_err(dsp, "Failed to read algorithm info: %d\n",
1804 			 ret);
1805 		return ret;
1806 	}
1807 
1808 	n_algs = be32_to_cpu(adsp2_id.n_algs);
1809 	dsp->fw_id = be32_to_cpu(adsp2_id.fw.id);
1810 	dsp->fw_id_version = be32_to_cpu(adsp2_id.fw.ver);
1811 	adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n",
1812 		  dsp->fw_id,
1813 		  (dsp->fw_id_version & 0xff0000) >> 16,
1814 		  (dsp->fw_id_version & 0xff00) >> 8,
1815 		  dsp->fw_id_version & 0xff,
1816 		  n_algs);
1817 
1818 	alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_XM,
1819 					   adsp2_id.fw.id, adsp2_id.xm);
1820 	if (IS_ERR(alg_region))
1821 		return PTR_ERR(alg_region);
1822 
1823 	alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_YM,
1824 					   adsp2_id.fw.id, adsp2_id.ym);
1825 	if (IS_ERR(alg_region))
1826 		return PTR_ERR(alg_region);
1827 
1828 	alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_ZM,
1829 					   adsp2_id.fw.id, adsp2_id.zm);
1830 	if (IS_ERR(alg_region))
1831 		return PTR_ERR(alg_region);
1832 
1833 	pos = sizeof(adsp2_id) / 2;
1834 	len = (sizeof(*adsp2_alg) * n_algs) / 2;
1835 
1836 	adsp2_alg = wm_adsp_read_algs(dsp, n_algs, mem->base + pos, len);
1837 	if (IS_ERR(adsp2_alg))
1838 		return PTR_ERR(adsp2_alg);
1839 
1840 	for (i = 0; i < n_algs; i++) {
1841 		adsp_info(dsp,
1842 			  "%d: ID %x v%d.%d.%d XM@%x YM@%x ZM@%x\n",
1843 			  i, be32_to_cpu(adsp2_alg[i].alg.id),
1844 			  (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff0000) >> 16,
1845 			  (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff00) >> 8,
1846 			  be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff,
1847 			  be32_to_cpu(adsp2_alg[i].xm),
1848 			  be32_to_cpu(adsp2_alg[i].ym),
1849 			  be32_to_cpu(adsp2_alg[i].zm));
1850 
1851 		alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_XM,
1852 						   adsp2_alg[i].alg.id,
1853 						   adsp2_alg[i].xm);
1854 		if (IS_ERR(alg_region)) {
1855 			ret = PTR_ERR(alg_region);
1856 			goto out;
1857 		}
1858 		if (dsp->fw_ver == 0) {
1859 			if (i + 1 < n_algs) {
1860 				len = be32_to_cpu(adsp2_alg[i + 1].xm);
1861 				len -= be32_to_cpu(adsp2_alg[i].xm);
1862 				len *= 4;
1863 				wm_adsp_create_control(dsp, alg_region, 0,
1864 						       len, NULL, 0, 0);
1865 			} else {
1866 				adsp_warn(dsp, "Missing length info for region XM with ID %x\n",
1867 					  be32_to_cpu(adsp2_alg[i].alg.id));
1868 			}
1869 		}
1870 
1871 		alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_YM,
1872 						   adsp2_alg[i].alg.id,
1873 						   adsp2_alg[i].ym);
1874 		if (IS_ERR(alg_region)) {
1875 			ret = PTR_ERR(alg_region);
1876 			goto out;
1877 		}
1878 		if (dsp->fw_ver == 0) {
1879 			if (i + 1 < n_algs) {
1880 				len = be32_to_cpu(adsp2_alg[i + 1].ym);
1881 				len -= be32_to_cpu(adsp2_alg[i].ym);
1882 				len *= 4;
1883 				wm_adsp_create_control(dsp, alg_region, 0,
1884 						       len, NULL, 0, 0);
1885 			} else {
1886 				adsp_warn(dsp, "Missing length info for region YM with ID %x\n",
1887 					  be32_to_cpu(adsp2_alg[i].alg.id));
1888 			}
1889 		}
1890 
1891 		alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_ZM,
1892 						   adsp2_alg[i].alg.id,
1893 						   adsp2_alg[i].zm);
1894 		if (IS_ERR(alg_region)) {
1895 			ret = PTR_ERR(alg_region);
1896 			goto out;
1897 		}
1898 		if (dsp->fw_ver == 0) {
1899 			if (i + 1 < n_algs) {
1900 				len = be32_to_cpu(adsp2_alg[i + 1].zm);
1901 				len -= be32_to_cpu(adsp2_alg[i].zm);
1902 				len *= 4;
1903 				wm_adsp_create_control(dsp, alg_region, 0,
1904 						       len, NULL, 0, 0);
1905 			} else {
1906 				adsp_warn(dsp, "Missing length info for region ZM with ID %x\n",
1907 					  be32_to_cpu(adsp2_alg[i].alg.id));
1908 			}
1909 		}
1910 	}
1911 
1912 out:
1913 	kfree(adsp2_alg);
1914 	return ret;
1915 }
1916 
1917 static int wm_adsp_load_coeff(struct wm_adsp *dsp)
1918 {
1919 	LIST_HEAD(buf_list);
1920 	struct regmap *regmap = dsp->regmap;
1921 	struct wmfw_coeff_hdr *hdr;
1922 	struct wmfw_coeff_item *blk;
1923 	const struct firmware *firmware;
1924 	const struct wm_adsp_region *mem;
1925 	struct wm_adsp_alg_region *alg_region;
1926 	const char *region_name;
1927 	int ret, pos, blocks, type, offset, reg;
1928 	char *file;
1929 	struct wm_adsp_buf *buf;
1930 
1931 	file = kzalloc(PAGE_SIZE, GFP_KERNEL);
1932 	if (file == NULL)
1933 		return -ENOMEM;
1934 
1935 	snprintf(file, PAGE_SIZE, "%s-dsp%d-%s.bin", dsp->part, dsp->num,
1936 		 wm_adsp_fw[dsp->fw].file);
1937 	file[PAGE_SIZE - 1] = '\0';
1938 
1939 	ret = request_firmware(&firmware, file, dsp->dev);
1940 	if (ret != 0) {
1941 		adsp_warn(dsp, "Failed to request '%s'\n", file);
1942 		ret = 0;
1943 		goto out;
1944 	}
1945 	ret = -EINVAL;
1946 
1947 	if (sizeof(*hdr) >= firmware->size) {
1948 		adsp_err(dsp, "%s: file too short, %zu bytes\n",
1949 			file, firmware->size);
1950 		goto out_fw;
1951 	}
1952 
1953 	hdr = (void *)&firmware->data[0];
1954 	if (memcmp(hdr->magic, "WMDR", 4) != 0) {
1955 		adsp_err(dsp, "%s: invalid magic\n", file);
1956 		goto out_fw;
1957 	}
1958 
1959 	switch (be32_to_cpu(hdr->rev) & 0xff) {
1960 	case 1:
1961 		break;
1962 	default:
1963 		adsp_err(dsp, "%s: Unsupported coefficient file format %d\n",
1964 			 file, be32_to_cpu(hdr->rev) & 0xff);
1965 		ret = -EINVAL;
1966 		goto out_fw;
1967 	}
1968 
1969 	adsp_dbg(dsp, "%s: v%d.%d.%d\n", file,
1970 		(le32_to_cpu(hdr->ver) >> 16) & 0xff,
1971 		(le32_to_cpu(hdr->ver) >>  8) & 0xff,
1972 		le32_to_cpu(hdr->ver) & 0xff);
1973 
1974 	pos = le32_to_cpu(hdr->len);
1975 
1976 	blocks = 0;
1977 	while (pos < firmware->size &&
1978 	       pos - firmware->size > sizeof(*blk)) {
1979 		blk = (void *)(&firmware->data[pos]);
1980 
1981 		type = le16_to_cpu(blk->type);
1982 		offset = le16_to_cpu(blk->offset);
1983 
1984 		adsp_dbg(dsp, "%s.%d: %x v%d.%d.%d\n",
1985 			 file, blocks, le32_to_cpu(blk->id),
1986 			 (le32_to_cpu(blk->ver) >> 16) & 0xff,
1987 			 (le32_to_cpu(blk->ver) >>  8) & 0xff,
1988 			 le32_to_cpu(blk->ver) & 0xff);
1989 		adsp_dbg(dsp, "%s.%d: %d bytes at 0x%x in %x\n",
1990 			 file, blocks, le32_to_cpu(blk->len), offset, type);
1991 
1992 		reg = 0;
1993 		region_name = "Unknown";
1994 		switch (type) {
1995 		case (WMFW_NAME_TEXT << 8):
1996 		case (WMFW_INFO_TEXT << 8):
1997 			break;
1998 		case (WMFW_ABSOLUTE << 8):
1999 			/*
2000 			 * Old files may use this for global
2001 			 * coefficients.
2002 			 */
2003 			if (le32_to_cpu(blk->id) == dsp->fw_id &&
2004 			    offset == 0) {
2005 				region_name = "global coefficients";
2006 				mem = wm_adsp_find_region(dsp, type);
2007 				if (!mem) {
2008 					adsp_err(dsp, "No ZM\n");
2009 					break;
2010 				}
2011 				reg = wm_adsp_region_to_reg(mem, 0);
2012 
2013 			} else {
2014 				region_name = "register";
2015 				reg = offset;
2016 			}
2017 			break;
2018 
2019 		case WMFW_ADSP1_DM:
2020 		case WMFW_ADSP1_ZM:
2021 		case WMFW_ADSP2_XM:
2022 		case WMFW_ADSP2_YM:
2023 			adsp_dbg(dsp, "%s.%d: %d bytes in %x for %x\n",
2024 				 file, blocks, le32_to_cpu(blk->len),
2025 				 type, le32_to_cpu(blk->id));
2026 
2027 			mem = wm_adsp_find_region(dsp, type);
2028 			if (!mem) {
2029 				adsp_err(dsp, "No base for region %x\n", type);
2030 				break;
2031 			}
2032 
2033 			alg_region = wm_adsp_find_alg_region(dsp, type,
2034 						le32_to_cpu(blk->id));
2035 			if (alg_region) {
2036 				reg = alg_region->base;
2037 				reg = wm_adsp_region_to_reg(mem, reg);
2038 				reg += offset;
2039 			} else {
2040 				adsp_err(dsp, "No %x for algorithm %x\n",
2041 					 type, le32_to_cpu(blk->id));
2042 			}
2043 			break;
2044 
2045 		default:
2046 			adsp_err(dsp, "%s.%d: Unknown region type %x at %d\n",
2047 				 file, blocks, type, pos);
2048 			break;
2049 		}
2050 
2051 		if (reg) {
2052 			buf = wm_adsp_buf_alloc(blk->data,
2053 						le32_to_cpu(blk->len),
2054 						&buf_list);
2055 			if (!buf) {
2056 				adsp_err(dsp, "Out of memory\n");
2057 				ret = -ENOMEM;
2058 				goto out_fw;
2059 			}
2060 
2061 			adsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n",
2062 				 file, blocks, le32_to_cpu(blk->len),
2063 				 reg);
2064 			ret = regmap_raw_write_async(regmap, reg, buf->buf,
2065 						     le32_to_cpu(blk->len));
2066 			if (ret != 0) {
2067 				adsp_err(dsp,
2068 					"%s.%d: Failed to write to %x in %s: %d\n",
2069 					file, blocks, reg, region_name, ret);
2070 			}
2071 		}
2072 
2073 		pos += (le32_to_cpu(blk->len) + sizeof(*blk) + 3) & ~0x03;
2074 		blocks++;
2075 	}
2076 
2077 	ret = regmap_async_complete(regmap);
2078 	if (ret != 0)
2079 		adsp_err(dsp, "Failed to complete async write: %d\n", ret);
2080 
2081 	if (pos > firmware->size)
2082 		adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n",
2083 			  file, blocks, pos - firmware->size);
2084 
2085 	wm_adsp_debugfs_save_binname(dsp, file);
2086 
2087 out_fw:
2088 	regmap_async_complete(regmap);
2089 	release_firmware(firmware);
2090 	wm_adsp_buf_free(&buf_list);
2091 out:
2092 	kfree(file);
2093 	return ret;
2094 }
2095 
2096 int wm_adsp1_init(struct wm_adsp *dsp)
2097 {
2098 	INIT_LIST_HEAD(&dsp->alg_regions);
2099 
2100 	mutex_init(&dsp->pwr_lock);
2101 
2102 	return 0;
2103 }
2104 EXPORT_SYMBOL_GPL(wm_adsp1_init);
2105 
2106 int wm_adsp1_event(struct snd_soc_dapm_widget *w,
2107 		   struct snd_kcontrol *kcontrol,
2108 		   int event)
2109 {
2110 	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
2111 	struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
2112 	struct wm_adsp *dsp = &dsps[w->shift];
2113 	struct wm_coeff_ctl *ctl;
2114 	int ret;
2115 	unsigned int val;
2116 
2117 	dsp->card = codec->component.card;
2118 
2119 	mutex_lock(&dsp->pwr_lock);
2120 
2121 	switch (event) {
2122 	case SND_SOC_DAPM_POST_PMU:
2123 		regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
2124 				   ADSP1_SYS_ENA, ADSP1_SYS_ENA);
2125 
2126 		/*
2127 		 * For simplicity set the DSP clock rate to be the
2128 		 * SYSCLK rate rather than making it configurable.
2129 		 */
2130 		if (dsp->sysclk_reg) {
2131 			ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val);
2132 			if (ret != 0) {
2133 				adsp_err(dsp, "Failed to read SYSCLK state: %d\n",
2134 				ret);
2135 				goto err_mutex;
2136 			}
2137 
2138 			val = (val & dsp->sysclk_mask) >> dsp->sysclk_shift;
2139 
2140 			ret = regmap_update_bits(dsp->regmap,
2141 						 dsp->base + ADSP1_CONTROL_31,
2142 						 ADSP1_CLK_SEL_MASK, val);
2143 			if (ret != 0) {
2144 				adsp_err(dsp, "Failed to set clock rate: %d\n",
2145 					 ret);
2146 				goto err_mutex;
2147 			}
2148 		}
2149 
2150 		ret = wm_adsp_load(dsp);
2151 		if (ret != 0)
2152 			goto err_ena;
2153 
2154 		ret = wm_adsp1_setup_algs(dsp);
2155 		if (ret != 0)
2156 			goto err_ena;
2157 
2158 		ret = wm_adsp_load_coeff(dsp);
2159 		if (ret != 0)
2160 			goto err_ena;
2161 
2162 		/* Initialize caches for enabled and unset controls */
2163 		ret = wm_coeff_init_control_caches(dsp);
2164 		if (ret != 0)
2165 			goto err_ena;
2166 
2167 		/* Sync set controls */
2168 		ret = wm_coeff_sync_controls(dsp);
2169 		if (ret != 0)
2170 			goto err_ena;
2171 
2172 		dsp->booted = true;
2173 
2174 		/* Start the core running */
2175 		regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
2176 				   ADSP1_CORE_ENA | ADSP1_START,
2177 				   ADSP1_CORE_ENA | ADSP1_START);
2178 
2179 		dsp->running = true;
2180 		break;
2181 
2182 	case SND_SOC_DAPM_PRE_PMD:
2183 		dsp->running = false;
2184 		dsp->booted = false;
2185 
2186 		/* Halt the core */
2187 		regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
2188 				   ADSP1_CORE_ENA | ADSP1_START, 0);
2189 
2190 		regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_19,
2191 				   ADSP1_WDMA_BUFFER_LENGTH_MASK, 0);
2192 
2193 		regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
2194 				   ADSP1_SYS_ENA, 0);
2195 
2196 		list_for_each_entry(ctl, &dsp->ctl_list, list)
2197 			ctl->enabled = 0;
2198 
2199 
2200 		wm_adsp_free_alg_regions(dsp);
2201 		break;
2202 
2203 	default:
2204 		break;
2205 	}
2206 
2207 	mutex_unlock(&dsp->pwr_lock);
2208 
2209 	return 0;
2210 
2211 err_ena:
2212 	regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
2213 			   ADSP1_SYS_ENA, 0);
2214 err_mutex:
2215 	mutex_unlock(&dsp->pwr_lock);
2216 
2217 	return ret;
2218 }
2219 EXPORT_SYMBOL_GPL(wm_adsp1_event);
2220 
2221 static int wm_adsp2_ena(struct wm_adsp *dsp)
2222 {
2223 	unsigned int val;
2224 	int ret, count;
2225 
2226 	ret = regmap_update_bits_async(dsp->regmap, dsp->base + ADSP2_CONTROL,
2227 				       ADSP2_SYS_ENA, ADSP2_SYS_ENA);
2228 	if (ret != 0)
2229 		return ret;
2230 
2231 	/* Wait for the RAM to start, should be near instantaneous */
2232 	for (count = 0; count < 10; ++count) {
2233 		ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1, &val);
2234 		if (ret != 0)
2235 			return ret;
2236 
2237 		if (val & ADSP2_RAM_RDY)
2238 			break;
2239 
2240 		usleep_range(250, 500);
2241 	}
2242 
2243 	if (!(val & ADSP2_RAM_RDY)) {
2244 		adsp_err(dsp, "Failed to start DSP RAM\n");
2245 		return -EBUSY;
2246 	}
2247 
2248 	adsp_dbg(dsp, "RAM ready after %d polls\n", count);
2249 
2250 	return 0;
2251 }
2252 
2253 static void wm_adsp2_boot_work(struct work_struct *work)
2254 {
2255 	struct wm_adsp *dsp = container_of(work,
2256 					   struct wm_adsp,
2257 					   boot_work);
2258 	int ret;
2259 
2260 	mutex_lock(&dsp->pwr_lock);
2261 
2262 	ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
2263 				 ADSP2_MEM_ENA, ADSP2_MEM_ENA);
2264 	if (ret != 0)
2265 		goto err_mutex;
2266 
2267 	ret = wm_adsp2_ena(dsp);
2268 	if (ret != 0)
2269 		goto err_mutex;
2270 
2271 	ret = wm_adsp_load(dsp);
2272 	if (ret != 0)
2273 		goto err_ena;
2274 
2275 	ret = wm_adsp2_setup_algs(dsp);
2276 	if (ret != 0)
2277 		goto err_ena;
2278 
2279 	ret = wm_adsp_load_coeff(dsp);
2280 	if (ret != 0)
2281 		goto err_ena;
2282 
2283 	/* Initialize caches for enabled and unset controls */
2284 	ret = wm_coeff_init_control_caches(dsp);
2285 	if (ret != 0)
2286 		goto err_ena;
2287 
2288 	dsp->booted = true;
2289 
2290 	/* Turn DSP back off until we are ready to run */
2291 	ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
2292 				 ADSP2_SYS_ENA, 0);
2293 	if (ret != 0)
2294 		goto err_ena;
2295 
2296 	mutex_unlock(&dsp->pwr_lock);
2297 
2298 	return;
2299 
2300 err_ena:
2301 	regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
2302 			   ADSP2_SYS_ENA | ADSP2_CORE_ENA | ADSP2_START, 0);
2303 err_mutex:
2304 	mutex_unlock(&dsp->pwr_lock);
2305 }
2306 
2307 static void wm_adsp2_set_dspclk(struct wm_adsp *dsp, unsigned int freq)
2308 {
2309 	int ret;
2310 
2311 	ret = regmap_update_bits_async(dsp->regmap,
2312 				       dsp->base + ADSP2_CLOCKING,
2313 				       ADSP2_CLK_SEL_MASK,
2314 				       freq << ADSP2_CLK_SEL_SHIFT);
2315 	if (ret != 0)
2316 		adsp_err(dsp, "Failed to set clock rate: %d\n", ret);
2317 }
2318 
2319 int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
2320 			 struct snd_kcontrol *kcontrol, int event,
2321 			 unsigned int freq)
2322 {
2323 	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
2324 	struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
2325 	struct wm_adsp *dsp = &dsps[w->shift];
2326 	struct wm_coeff_ctl *ctl;
2327 
2328 	dsp->card = codec->component.card;
2329 
2330 	switch (event) {
2331 	case SND_SOC_DAPM_PRE_PMU:
2332 		wm_adsp2_set_dspclk(dsp, freq);
2333 		queue_work(system_unbound_wq, &dsp->boot_work);
2334 		break;
2335 	case SND_SOC_DAPM_PRE_PMD:
2336 		wm_adsp_debugfs_clear(dsp);
2337 
2338 		dsp->fw_id = 0;
2339 		dsp->fw_id_version = 0;
2340 
2341 		dsp->booted = false;
2342 
2343 		regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
2344 				   ADSP2_MEM_ENA, 0);
2345 
2346 		list_for_each_entry(ctl, &dsp->ctl_list, list)
2347 			ctl->enabled = 0;
2348 
2349 		wm_adsp_free_alg_regions(dsp);
2350 
2351 		adsp_dbg(dsp, "Shutdown complete\n");
2352 		break;
2353 	default:
2354 		break;
2355 	}
2356 
2357 	return 0;
2358 }
2359 EXPORT_SYMBOL_GPL(wm_adsp2_early_event);
2360 
2361 int wm_adsp2_event(struct snd_soc_dapm_widget *w,
2362 		   struct snd_kcontrol *kcontrol, int event)
2363 {
2364 	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
2365 	struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
2366 	struct wm_adsp *dsp = &dsps[w->shift];
2367 	int ret;
2368 
2369 	switch (event) {
2370 	case SND_SOC_DAPM_POST_PMU:
2371 		flush_work(&dsp->boot_work);
2372 
2373 		if (!dsp->booted)
2374 			return -EIO;
2375 
2376 		ret = wm_adsp2_ena(dsp);
2377 		if (ret != 0)
2378 			goto err;
2379 
2380 		/* Sync set controls */
2381 		ret = wm_coeff_sync_controls(dsp);
2382 		if (ret != 0)
2383 			goto err;
2384 
2385 		ret = regmap_update_bits(dsp->regmap,
2386 					 dsp->base + ADSP2_CONTROL,
2387 					 ADSP2_CORE_ENA | ADSP2_START,
2388 					 ADSP2_CORE_ENA | ADSP2_START);
2389 		if (ret != 0)
2390 			goto err;
2391 
2392 		dsp->running = true;
2393 
2394 		mutex_lock(&dsp->pwr_lock);
2395 
2396 		if (wm_adsp_fw[dsp->fw].num_caps != 0)
2397 			ret = wm_adsp_buffer_init(dsp);
2398 
2399 		mutex_unlock(&dsp->pwr_lock);
2400 
2401 		break;
2402 
2403 	case SND_SOC_DAPM_PRE_PMD:
2404 		/* Log firmware state, it can be useful for analysis */
2405 		wm_adsp2_show_fw_status(dsp);
2406 
2407 		mutex_lock(&dsp->pwr_lock);
2408 
2409 		dsp->running = false;
2410 
2411 		regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
2412 				   ADSP2_CORE_ENA | ADSP2_START, 0);
2413 
2414 		/* Make sure DMAs are quiesced */
2415 		regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0);
2416 		regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0);
2417 		regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_2, 0);
2418 
2419 		regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
2420 				   ADSP2_SYS_ENA, 0);
2421 
2422 		if (wm_adsp_fw[dsp->fw].num_caps != 0)
2423 			wm_adsp_buffer_free(dsp);
2424 
2425 		mutex_unlock(&dsp->pwr_lock);
2426 
2427 		adsp_dbg(dsp, "Execution stopped\n");
2428 		break;
2429 
2430 	default:
2431 		break;
2432 	}
2433 
2434 	return 0;
2435 err:
2436 	regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
2437 			   ADSP2_SYS_ENA | ADSP2_CORE_ENA | ADSP2_START, 0);
2438 	return ret;
2439 }
2440 EXPORT_SYMBOL_GPL(wm_adsp2_event);
2441 
2442 int wm_adsp2_codec_probe(struct wm_adsp *dsp, struct snd_soc_codec *codec)
2443 {
2444 	wm_adsp2_init_debugfs(dsp, codec);
2445 
2446 	return snd_soc_add_codec_controls(codec,
2447 					  &wm_adsp_fw_controls[dsp->num - 1],
2448 					  1);
2449 }
2450 EXPORT_SYMBOL_GPL(wm_adsp2_codec_probe);
2451 
2452 int wm_adsp2_codec_remove(struct wm_adsp *dsp, struct snd_soc_codec *codec)
2453 {
2454 	wm_adsp2_cleanup_debugfs(dsp);
2455 
2456 	return 0;
2457 }
2458 EXPORT_SYMBOL_GPL(wm_adsp2_codec_remove);
2459 
2460 int wm_adsp2_init(struct wm_adsp *dsp)
2461 {
2462 	int ret;
2463 
2464 	/*
2465 	 * Disable the DSP memory by default when in reset for a small
2466 	 * power saving.
2467 	 */
2468 	ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
2469 				 ADSP2_MEM_ENA, 0);
2470 	if (ret != 0) {
2471 		adsp_err(dsp, "Failed to clear memory retention: %d\n", ret);
2472 		return ret;
2473 	}
2474 
2475 	INIT_LIST_HEAD(&dsp->alg_regions);
2476 	INIT_LIST_HEAD(&dsp->ctl_list);
2477 	INIT_WORK(&dsp->boot_work, wm_adsp2_boot_work);
2478 
2479 	mutex_init(&dsp->pwr_lock);
2480 
2481 	return 0;
2482 }
2483 EXPORT_SYMBOL_GPL(wm_adsp2_init);
2484 
2485 void wm_adsp2_remove(struct wm_adsp *dsp)
2486 {
2487 	struct wm_coeff_ctl *ctl;
2488 
2489 	while (!list_empty(&dsp->ctl_list)) {
2490 		ctl = list_first_entry(&dsp->ctl_list, struct wm_coeff_ctl,
2491 					list);
2492 		list_del(&ctl->list);
2493 		wm_adsp_free_ctl_blk(ctl);
2494 	}
2495 }
2496 EXPORT_SYMBOL_GPL(wm_adsp2_remove);
2497 
2498 static inline int wm_adsp_compr_attached(struct wm_adsp_compr *compr)
2499 {
2500 	return compr->buf != NULL;
2501 }
2502 
2503 static int wm_adsp_compr_attach(struct wm_adsp_compr *compr)
2504 {
2505 	/*
2506 	 * Note this will be more complex once each DSP can support multiple
2507 	 * streams
2508 	 */
2509 	if (!compr->dsp->buffer)
2510 		return -EINVAL;
2511 
2512 	compr->buf = compr->dsp->buffer;
2513 	compr->buf->compr = compr;
2514 
2515 	return 0;
2516 }
2517 
2518 static void wm_adsp_compr_detach(struct wm_adsp_compr *compr)
2519 {
2520 	if (!compr)
2521 		return;
2522 
2523 	/* Wake the poll so it can see buffer is no longer attached */
2524 	if (compr->stream)
2525 		snd_compr_fragment_elapsed(compr->stream);
2526 
2527 	if (wm_adsp_compr_attached(compr)) {
2528 		compr->buf->compr = NULL;
2529 		compr->buf = NULL;
2530 	}
2531 }
2532 
2533 int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream)
2534 {
2535 	struct wm_adsp_compr *compr;
2536 	int ret = 0;
2537 
2538 	mutex_lock(&dsp->pwr_lock);
2539 
2540 	if (wm_adsp_fw[dsp->fw].num_caps == 0) {
2541 		adsp_err(dsp, "Firmware does not support compressed API\n");
2542 		ret = -ENXIO;
2543 		goto out;
2544 	}
2545 
2546 	if (wm_adsp_fw[dsp->fw].compr_direction != stream->direction) {
2547 		adsp_err(dsp, "Firmware does not support stream direction\n");
2548 		ret = -EINVAL;
2549 		goto out;
2550 	}
2551 
2552 	if (dsp->compr) {
2553 		/* It is expect this limitation will be removed in future */
2554 		adsp_err(dsp, "Only a single stream supported per DSP\n");
2555 		ret = -EBUSY;
2556 		goto out;
2557 	}
2558 
2559 	compr = kzalloc(sizeof(*compr), GFP_KERNEL);
2560 	if (!compr) {
2561 		ret = -ENOMEM;
2562 		goto out;
2563 	}
2564 
2565 	compr->dsp = dsp;
2566 	compr->stream = stream;
2567 
2568 	dsp->compr = compr;
2569 
2570 	stream->runtime->private_data = compr;
2571 
2572 out:
2573 	mutex_unlock(&dsp->pwr_lock);
2574 
2575 	return ret;
2576 }
2577 EXPORT_SYMBOL_GPL(wm_adsp_compr_open);
2578 
2579 int wm_adsp_compr_free(struct snd_compr_stream *stream)
2580 {
2581 	struct wm_adsp_compr *compr = stream->runtime->private_data;
2582 	struct wm_adsp *dsp = compr->dsp;
2583 
2584 	mutex_lock(&dsp->pwr_lock);
2585 
2586 	wm_adsp_compr_detach(compr);
2587 	dsp->compr = NULL;
2588 
2589 	kfree(compr->raw_buf);
2590 	kfree(compr);
2591 
2592 	mutex_unlock(&dsp->pwr_lock);
2593 
2594 	return 0;
2595 }
2596 EXPORT_SYMBOL_GPL(wm_adsp_compr_free);
2597 
2598 static int wm_adsp_compr_check_params(struct snd_compr_stream *stream,
2599 				      struct snd_compr_params *params)
2600 {
2601 	struct wm_adsp_compr *compr = stream->runtime->private_data;
2602 	struct wm_adsp *dsp = compr->dsp;
2603 	const struct wm_adsp_fw_caps *caps;
2604 	const struct snd_codec_desc *desc;
2605 	int i, j;
2606 
2607 	if (params->buffer.fragment_size < WM_ADSP_MIN_FRAGMENT_SIZE ||
2608 	    params->buffer.fragment_size > WM_ADSP_MAX_FRAGMENT_SIZE ||
2609 	    params->buffer.fragments < WM_ADSP_MIN_FRAGMENTS ||
2610 	    params->buffer.fragments > WM_ADSP_MAX_FRAGMENTS ||
2611 	    params->buffer.fragment_size % WM_ADSP_DATA_WORD_SIZE) {
2612 		adsp_err(dsp, "Invalid buffer fragsize=%d fragments=%d\n",
2613 			 params->buffer.fragment_size,
2614 			 params->buffer.fragments);
2615 
2616 		return -EINVAL;
2617 	}
2618 
2619 	for (i = 0; i < wm_adsp_fw[dsp->fw].num_caps; i++) {
2620 		caps = &wm_adsp_fw[dsp->fw].caps[i];
2621 		desc = &caps->desc;
2622 
2623 		if (caps->id != params->codec.id)
2624 			continue;
2625 
2626 		if (stream->direction == SND_COMPRESS_PLAYBACK) {
2627 			if (desc->max_ch < params->codec.ch_out)
2628 				continue;
2629 		} else {
2630 			if (desc->max_ch < params->codec.ch_in)
2631 				continue;
2632 		}
2633 
2634 		if (!(desc->formats & (1 << params->codec.format)))
2635 			continue;
2636 
2637 		for (j = 0; j < desc->num_sample_rates; ++j)
2638 			if (desc->sample_rates[j] == params->codec.sample_rate)
2639 				return 0;
2640 	}
2641 
2642 	adsp_err(dsp, "Invalid params id=%u ch=%u,%u rate=%u fmt=%u\n",
2643 		 params->codec.id, params->codec.ch_in, params->codec.ch_out,
2644 		 params->codec.sample_rate, params->codec.format);
2645 	return -EINVAL;
2646 }
2647 
2648 static inline unsigned int wm_adsp_compr_frag_words(struct wm_adsp_compr *compr)
2649 {
2650 	return compr->size.fragment_size / WM_ADSP_DATA_WORD_SIZE;
2651 }
2652 
2653 int wm_adsp_compr_set_params(struct snd_compr_stream *stream,
2654 			     struct snd_compr_params *params)
2655 {
2656 	struct wm_adsp_compr *compr = stream->runtime->private_data;
2657 	unsigned int size;
2658 	int ret;
2659 
2660 	ret = wm_adsp_compr_check_params(stream, params);
2661 	if (ret)
2662 		return ret;
2663 
2664 	compr->size = params->buffer;
2665 
2666 	adsp_dbg(compr->dsp, "fragment_size=%d fragments=%d\n",
2667 		 compr->size.fragment_size, compr->size.fragments);
2668 
2669 	size = wm_adsp_compr_frag_words(compr) * sizeof(*compr->raw_buf);
2670 	compr->raw_buf = kmalloc(size, GFP_DMA | GFP_KERNEL);
2671 	if (!compr->raw_buf)
2672 		return -ENOMEM;
2673 
2674 	compr->sample_rate = params->codec.sample_rate;
2675 
2676 	return 0;
2677 }
2678 EXPORT_SYMBOL_GPL(wm_adsp_compr_set_params);
2679 
2680 int wm_adsp_compr_get_caps(struct snd_compr_stream *stream,
2681 			   struct snd_compr_caps *caps)
2682 {
2683 	struct wm_adsp_compr *compr = stream->runtime->private_data;
2684 	int fw = compr->dsp->fw;
2685 	int i;
2686 
2687 	if (wm_adsp_fw[fw].caps) {
2688 		for (i = 0; i < wm_adsp_fw[fw].num_caps; i++)
2689 			caps->codecs[i] = wm_adsp_fw[fw].caps[i].id;
2690 
2691 		caps->num_codecs = i;
2692 		caps->direction = wm_adsp_fw[fw].compr_direction;
2693 
2694 		caps->min_fragment_size = WM_ADSP_MIN_FRAGMENT_SIZE;
2695 		caps->max_fragment_size = WM_ADSP_MAX_FRAGMENT_SIZE;
2696 		caps->min_fragments = WM_ADSP_MIN_FRAGMENTS;
2697 		caps->max_fragments = WM_ADSP_MAX_FRAGMENTS;
2698 	}
2699 
2700 	return 0;
2701 }
2702 EXPORT_SYMBOL_GPL(wm_adsp_compr_get_caps);
2703 
2704 static int wm_adsp_read_data_block(struct wm_adsp *dsp, int mem_type,
2705 				   unsigned int mem_addr,
2706 				   unsigned int num_words, u32 *data)
2707 {
2708 	struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type);
2709 	unsigned int i, reg;
2710 	int ret;
2711 
2712 	if (!mem)
2713 		return -EINVAL;
2714 
2715 	reg = wm_adsp_region_to_reg(mem, mem_addr);
2716 
2717 	ret = regmap_raw_read(dsp->regmap, reg, data,
2718 			      sizeof(*data) * num_words);
2719 	if (ret < 0)
2720 		return ret;
2721 
2722 	for (i = 0; i < num_words; ++i)
2723 		data[i] = be32_to_cpu(data[i]) & 0x00ffffffu;
2724 
2725 	return 0;
2726 }
2727 
2728 static inline int wm_adsp_read_data_word(struct wm_adsp *dsp, int mem_type,
2729 					 unsigned int mem_addr, u32 *data)
2730 {
2731 	return wm_adsp_read_data_block(dsp, mem_type, mem_addr, 1, data);
2732 }
2733 
2734 static int wm_adsp_write_data_word(struct wm_adsp *dsp, int mem_type,
2735 				   unsigned int mem_addr, u32 data)
2736 {
2737 	struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type);
2738 	unsigned int reg;
2739 
2740 	if (!mem)
2741 		return -EINVAL;
2742 
2743 	reg = wm_adsp_region_to_reg(mem, mem_addr);
2744 
2745 	data = cpu_to_be32(data & 0x00ffffffu);
2746 
2747 	return regmap_raw_write(dsp->regmap, reg, &data, sizeof(data));
2748 }
2749 
2750 static inline int wm_adsp_buffer_read(struct wm_adsp_compr_buf *buf,
2751 				      unsigned int field_offset, u32 *data)
2752 {
2753 	return wm_adsp_read_data_word(buf->dsp, WMFW_ADSP2_XM,
2754 				      buf->host_buf_ptr + field_offset, data);
2755 }
2756 
2757 static inline int wm_adsp_buffer_write(struct wm_adsp_compr_buf *buf,
2758 				       unsigned int field_offset, u32 data)
2759 {
2760 	return wm_adsp_write_data_word(buf->dsp, WMFW_ADSP2_XM,
2761 				       buf->host_buf_ptr + field_offset, data);
2762 }
2763 
2764 static int wm_adsp_buffer_locate(struct wm_adsp_compr_buf *buf)
2765 {
2766 	struct wm_adsp_alg_region *alg_region;
2767 	struct wm_adsp *dsp = buf->dsp;
2768 	u32 xmalg, addr, magic;
2769 	int i, ret;
2770 
2771 	alg_region = wm_adsp_find_alg_region(dsp, WMFW_ADSP2_XM, dsp->fw_id);
2772 	xmalg = sizeof(struct wm_adsp_system_config_xm_hdr) / sizeof(__be32);
2773 
2774 	addr = alg_region->base + xmalg + ALG_XM_FIELD(magic);
2775 	ret = wm_adsp_read_data_word(dsp, WMFW_ADSP2_XM, addr, &magic);
2776 	if (ret < 0)
2777 		return ret;
2778 
2779 	if (magic != WM_ADSP_ALG_XM_STRUCT_MAGIC)
2780 		return -EINVAL;
2781 
2782 	addr = alg_region->base + xmalg + ALG_XM_FIELD(host_buf_ptr);
2783 	for (i = 0; i < 5; ++i) {
2784 		ret = wm_adsp_read_data_word(dsp, WMFW_ADSP2_XM, addr,
2785 					     &buf->host_buf_ptr);
2786 		if (ret < 0)
2787 			return ret;
2788 
2789 		if (buf->host_buf_ptr)
2790 			break;
2791 
2792 		usleep_range(1000, 2000);
2793 	}
2794 
2795 	if (!buf->host_buf_ptr)
2796 		return -EIO;
2797 
2798 	adsp_dbg(dsp, "host_buf_ptr=%x\n", buf->host_buf_ptr);
2799 
2800 	return 0;
2801 }
2802 
2803 static int wm_adsp_buffer_populate(struct wm_adsp_compr_buf *buf)
2804 {
2805 	const struct wm_adsp_fw_caps *caps = wm_adsp_fw[buf->dsp->fw].caps;
2806 	struct wm_adsp_buffer_region *region;
2807 	u32 offset = 0;
2808 	int i, ret;
2809 
2810 	for (i = 0; i < caps->num_regions; ++i) {
2811 		region = &buf->regions[i];
2812 
2813 		region->offset = offset;
2814 		region->mem_type = caps->region_defs[i].mem_type;
2815 
2816 		ret = wm_adsp_buffer_read(buf, caps->region_defs[i].base_offset,
2817 					  &region->base_addr);
2818 		if (ret < 0)
2819 			return ret;
2820 
2821 		ret = wm_adsp_buffer_read(buf, caps->region_defs[i].size_offset,
2822 					  &offset);
2823 		if (ret < 0)
2824 			return ret;
2825 
2826 		region->cumulative_size = offset;
2827 
2828 		adsp_dbg(buf->dsp,
2829 			 "region=%d type=%d base=%04x off=%04x size=%04x\n",
2830 			 i, region->mem_type, region->base_addr,
2831 			 region->offset, region->cumulative_size);
2832 	}
2833 
2834 	return 0;
2835 }
2836 
2837 static int wm_adsp_buffer_init(struct wm_adsp *dsp)
2838 {
2839 	struct wm_adsp_compr_buf *buf;
2840 	int ret;
2841 
2842 	buf = kzalloc(sizeof(*buf), GFP_KERNEL);
2843 	if (!buf)
2844 		return -ENOMEM;
2845 
2846 	buf->dsp = dsp;
2847 	buf->read_index = -1;
2848 	buf->irq_count = 0xFFFFFFFF;
2849 
2850 	ret = wm_adsp_buffer_locate(buf);
2851 	if (ret < 0) {
2852 		adsp_err(dsp, "Failed to acquire host buffer: %d\n", ret);
2853 		goto err_buffer;
2854 	}
2855 
2856 	buf->regions = kcalloc(wm_adsp_fw[dsp->fw].caps->num_regions,
2857 			       sizeof(*buf->regions), GFP_KERNEL);
2858 	if (!buf->regions) {
2859 		ret = -ENOMEM;
2860 		goto err_buffer;
2861 	}
2862 
2863 	ret = wm_adsp_buffer_populate(buf);
2864 	if (ret < 0) {
2865 		adsp_err(dsp, "Failed to populate host buffer: %d\n", ret);
2866 		goto err_regions;
2867 	}
2868 
2869 	dsp->buffer = buf;
2870 
2871 	return 0;
2872 
2873 err_regions:
2874 	kfree(buf->regions);
2875 err_buffer:
2876 	kfree(buf);
2877 	return ret;
2878 }
2879 
2880 static int wm_adsp_buffer_free(struct wm_adsp *dsp)
2881 {
2882 	if (dsp->buffer) {
2883 		wm_adsp_compr_detach(dsp->buffer->compr);
2884 
2885 		kfree(dsp->buffer->regions);
2886 		kfree(dsp->buffer);
2887 
2888 		dsp->buffer = NULL;
2889 	}
2890 
2891 	return 0;
2892 }
2893 
2894 int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd)
2895 {
2896 	struct wm_adsp_compr *compr = stream->runtime->private_data;
2897 	struct wm_adsp *dsp = compr->dsp;
2898 	int ret = 0;
2899 
2900 	adsp_dbg(dsp, "Trigger: %d\n", cmd);
2901 
2902 	mutex_lock(&dsp->pwr_lock);
2903 
2904 	switch (cmd) {
2905 	case SNDRV_PCM_TRIGGER_START:
2906 		if (wm_adsp_compr_attached(compr))
2907 			break;
2908 
2909 		ret = wm_adsp_compr_attach(compr);
2910 		if (ret < 0) {
2911 			adsp_err(dsp, "Failed to link buffer and stream: %d\n",
2912 				 ret);
2913 			break;
2914 		}
2915 
2916 		/* Trigger the IRQ at one fragment of data */
2917 		ret = wm_adsp_buffer_write(compr->buf,
2918 					   HOST_BUFFER_FIELD(high_water_mark),
2919 					   wm_adsp_compr_frag_words(compr));
2920 		if (ret < 0) {
2921 			adsp_err(dsp, "Failed to set high water mark: %d\n",
2922 				 ret);
2923 			break;
2924 		}
2925 		break;
2926 	case SNDRV_PCM_TRIGGER_STOP:
2927 		break;
2928 	default:
2929 		ret = -EINVAL;
2930 		break;
2931 	}
2932 
2933 	mutex_unlock(&dsp->pwr_lock);
2934 
2935 	return ret;
2936 }
2937 EXPORT_SYMBOL_GPL(wm_adsp_compr_trigger);
2938 
2939 static inline int wm_adsp_buffer_size(struct wm_adsp_compr_buf *buf)
2940 {
2941 	int last_region = wm_adsp_fw[buf->dsp->fw].caps->num_regions - 1;
2942 
2943 	return buf->regions[last_region].cumulative_size;
2944 }
2945 
2946 static int wm_adsp_buffer_update_avail(struct wm_adsp_compr_buf *buf)
2947 {
2948 	u32 next_read_index, next_write_index;
2949 	int write_index, read_index, avail;
2950 	int ret;
2951 
2952 	/* Only sync read index if we haven't already read a valid index */
2953 	if (buf->read_index < 0) {
2954 		ret = wm_adsp_buffer_read(buf,
2955 				HOST_BUFFER_FIELD(next_read_index),
2956 				&next_read_index);
2957 		if (ret < 0)
2958 			return ret;
2959 
2960 		read_index = sign_extend32(next_read_index, 23);
2961 
2962 		if (read_index < 0) {
2963 			adsp_dbg(buf->dsp, "Avail check on unstarted stream\n");
2964 			return 0;
2965 		}
2966 
2967 		buf->read_index = read_index;
2968 	}
2969 
2970 	ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(next_write_index),
2971 			&next_write_index);
2972 	if (ret < 0)
2973 		return ret;
2974 
2975 	write_index = sign_extend32(next_write_index, 23);
2976 
2977 	avail = write_index - buf->read_index;
2978 	if (avail < 0)
2979 		avail += wm_adsp_buffer_size(buf);
2980 
2981 	adsp_dbg(buf->dsp, "readindex=0x%x, writeindex=0x%x, avail=%d\n",
2982 		 buf->read_index, write_index, avail * WM_ADSP_DATA_WORD_SIZE);
2983 
2984 	buf->avail = avail;
2985 
2986 	return 0;
2987 }
2988 
2989 static int wm_adsp_buffer_get_error(struct wm_adsp_compr_buf *buf)
2990 {
2991 	int ret;
2992 
2993 	ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(error), &buf->error);
2994 	if (ret < 0) {
2995 		adsp_err(buf->dsp, "Failed to check buffer error: %d\n", ret);
2996 		return ret;
2997 	}
2998 	if (buf->error != 0) {
2999 		adsp_err(buf->dsp, "Buffer error occurred: %d\n", buf->error);
3000 		return -EIO;
3001 	}
3002 
3003 	return 0;
3004 }
3005 
3006 int wm_adsp_compr_handle_irq(struct wm_adsp *dsp)
3007 {
3008 	struct wm_adsp_compr_buf *buf;
3009 	struct wm_adsp_compr *compr;
3010 	int ret = 0;
3011 
3012 	mutex_lock(&dsp->pwr_lock);
3013 
3014 	buf = dsp->buffer;
3015 	compr = dsp->compr;
3016 
3017 	if (!buf) {
3018 		ret = -ENODEV;
3019 		goto out;
3020 	}
3021 
3022 	adsp_dbg(dsp, "Handling buffer IRQ\n");
3023 
3024 	ret = wm_adsp_buffer_get_error(buf);
3025 	if (ret < 0)
3026 		goto out_notify; /* Wake poll to report error */
3027 
3028 	ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(irq_count),
3029 				  &buf->irq_count);
3030 	if (ret < 0) {
3031 		adsp_err(dsp, "Failed to get irq_count: %d\n", ret);
3032 		goto out;
3033 	}
3034 
3035 	ret = wm_adsp_buffer_update_avail(buf);
3036 	if (ret < 0) {
3037 		adsp_err(dsp, "Error reading avail: %d\n", ret);
3038 		goto out;
3039 	}
3040 
3041 	if (wm_adsp_fw[dsp->fw].voice_trigger && buf->irq_count == 2)
3042 		ret = WM_ADSP_COMPR_VOICE_TRIGGER;
3043 
3044 out_notify:
3045 	if (compr && compr->stream)
3046 		snd_compr_fragment_elapsed(compr->stream);
3047 
3048 out:
3049 	mutex_unlock(&dsp->pwr_lock);
3050 
3051 	return ret;
3052 }
3053 EXPORT_SYMBOL_GPL(wm_adsp_compr_handle_irq);
3054 
3055 static int wm_adsp_buffer_reenable_irq(struct wm_adsp_compr_buf *buf)
3056 {
3057 	if (buf->irq_count & 0x01)
3058 		return 0;
3059 
3060 	adsp_dbg(buf->dsp, "Enable IRQ(0x%x) for next fragment\n",
3061 		 buf->irq_count);
3062 
3063 	buf->irq_count |= 0x01;
3064 
3065 	return wm_adsp_buffer_write(buf, HOST_BUFFER_FIELD(irq_ack),
3066 				    buf->irq_count);
3067 }
3068 
3069 int wm_adsp_compr_pointer(struct snd_compr_stream *stream,
3070 			  struct snd_compr_tstamp *tstamp)
3071 {
3072 	struct wm_adsp_compr *compr = stream->runtime->private_data;
3073 	struct wm_adsp *dsp = compr->dsp;
3074 	struct wm_adsp_compr_buf *buf;
3075 	int ret = 0;
3076 
3077 	adsp_dbg(dsp, "Pointer request\n");
3078 
3079 	mutex_lock(&dsp->pwr_lock);
3080 
3081 	buf = compr->buf;
3082 
3083 	if (!compr->buf || compr->buf->error) {
3084 		snd_compr_stop_error(stream, SNDRV_PCM_STATE_XRUN);
3085 		ret = -EIO;
3086 		goto out;
3087 	}
3088 
3089 	if (buf->avail < wm_adsp_compr_frag_words(compr)) {
3090 		ret = wm_adsp_buffer_update_avail(buf);
3091 		if (ret < 0) {
3092 			adsp_err(dsp, "Error reading avail: %d\n", ret);
3093 			goto out;
3094 		}
3095 
3096 		/*
3097 		 * If we really have less than 1 fragment available tell the
3098 		 * DSP to inform us once a whole fragment is available.
3099 		 */
3100 		if (buf->avail < wm_adsp_compr_frag_words(compr)) {
3101 			ret = wm_adsp_buffer_get_error(buf);
3102 			if (ret < 0) {
3103 				if (compr->buf->error)
3104 					snd_compr_stop_error(stream,
3105 							SNDRV_PCM_STATE_XRUN);
3106 				goto out;
3107 			}
3108 
3109 			ret = wm_adsp_buffer_reenable_irq(buf);
3110 			if (ret < 0) {
3111 				adsp_err(dsp,
3112 					 "Failed to re-enable buffer IRQ: %d\n",
3113 					 ret);
3114 				goto out;
3115 			}
3116 		}
3117 	}
3118 
3119 	tstamp->copied_total = compr->copied_total;
3120 	tstamp->copied_total += buf->avail * WM_ADSP_DATA_WORD_SIZE;
3121 	tstamp->sampling_rate = compr->sample_rate;
3122 
3123 out:
3124 	mutex_unlock(&dsp->pwr_lock);
3125 
3126 	return ret;
3127 }
3128 EXPORT_SYMBOL_GPL(wm_adsp_compr_pointer);
3129 
3130 static int wm_adsp_buffer_capture_block(struct wm_adsp_compr *compr, int target)
3131 {
3132 	struct wm_adsp_compr_buf *buf = compr->buf;
3133 	u8 *pack_in = (u8 *)compr->raw_buf;
3134 	u8 *pack_out = (u8 *)compr->raw_buf;
3135 	unsigned int adsp_addr;
3136 	int mem_type, nwords, max_read;
3137 	int i, j, ret;
3138 
3139 	/* Calculate read parameters */
3140 	for (i = 0; i < wm_adsp_fw[buf->dsp->fw].caps->num_regions; ++i)
3141 		if (buf->read_index < buf->regions[i].cumulative_size)
3142 			break;
3143 
3144 	if (i == wm_adsp_fw[buf->dsp->fw].caps->num_regions)
3145 		return -EINVAL;
3146 
3147 	mem_type = buf->regions[i].mem_type;
3148 	adsp_addr = buf->regions[i].base_addr +
3149 		    (buf->read_index - buf->regions[i].offset);
3150 
3151 	max_read = wm_adsp_compr_frag_words(compr);
3152 	nwords = buf->regions[i].cumulative_size - buf->read_index;
3153 
3154 	if (nwords > target)
3155 		nwords = target;
3156 	if (nwords > buf->avail)
3157 		nwords = buf->avail;
3158 	if (nwords > max_read)
3159 		nwords = max_read;
3160 	if (!nwords)
3161 		return 0;
3162 
3163 	/* Read data from DSP */
3164 	ret = wm_adsp_read_data_block(buf->dsp, mem_type, adsp_addr,
3165 				      nwords, compr->raw_buf);
3166 	if (ret < 0)
3167 		return ret;
3168 
3169 	/* Remove the padding bytes from the data read from the DSP */
3170 	for (i = 0; i < nwords; i++) {
3171 		for (j = 0; j < WM_ADSP_DATA_WORD_SIZE; j++)
3172 			*pack_out++ = *pack_in++;
3173 
3174 		pack_in += sizeof(*(compr->raw_buf)) - WM_ADSP_DATA_WORD_SIZE;
3175 	}
3176 
3177 	/* update read index to account for words read */
3178 	buf->read_index += nwords;
3179 	if (buf->read_index == wm_adsp_buffer_size(buf))
3180 		buf->read_index = 0;
3181 
3182 	ret = wm_adsp_buffer_write(buf, HOST_BUFFER_FIELD(next_read_index),
3183 				   buf->read_index);
3184 	if (ret < 0)
3185 		return ret;
3186 
3187 	/* update avail to account for words read */
3188 	buf->avail -= nwords;
3189 
3190 	return nwords;
3191 }
3192 
3193 static int wm_adsp_compr_read(struct wm_adsp_compr *compr,
3194 			      char __user *buf, size_t count)
3195 {
3196 	struct wm_adsp *dsp = compr->dsp;
3197 	int ntotal = 0;
3198 	int nwords, nbytes;
3199 
3200 	adsp_dbg(dsp, "Requested read of %zu bytes\n", count);
3201 
3202 	if (!compr->buf || compr->buf->error) {
3203 		snd_compr_stop_error(compr->stream, SNDRV_PCM_STATE_XRUN);
3204 		return -EIO;
3205 	}
3206 
3207 	count /= WM_ADSP_DATA_WORD_SIZE;
3208 
3209 	do {
3210 		nwords = wm_adsp_buffer_capture_block(compr, count);
3211 		if (nwords < 0) {
3212 			adsp_err(dsp, "Failed to capture block: %d\n", nwords);
3213 			return nwords;
3214 		}
3215 
3216 		nbytes = nwords * WM_ADSP_DATA_WORD_SIZE;
3217 
3218 		adsp_dbg(dsp, "Read %d bytes\n", nbytes);
3219 
3220 		if (copy_to_user(buf + ntotal, compr->raw_buf, nbytes)) {
3221 			adsp_err(dsp, "Failed to copy data to user: %d, %d\n",
3222 				 ntotal, nbytes);
3223 			return -EFAULT;
3224 		}
3225 
3226 		count -= nwords;
3227 		ntotal += nbytes;
3228 	} while (nwords > 0 && count > 0);
3229 
3230 	compr->copied_total += ntotal;
3231 
3232 	return ntotal;
3233 }
3234 
3235 int wm_adsp_compr_copy(struct snd_compr_stream *stream, char __user *buf,
3236 		       size_t count)
3237 {
3238 	struct wm_adsp_compr *compr = stream->runtime->private_data;
3239 	struct wm_adsp *dsp = compr->dsp;
3240 	int ret;
3241 
3242 	mutex_lock(&dsp->pwr_lock);
3243 
3244 	if (stream->direction == SND_COMPRESS_CAPTURE)
3245 		ret = wm_adsp_compr_read(compr, buf, count);
3246 	else
3247 		ret = -ENOTSUPP;
3248 
3249 	mutex_unlock(&dsp->pwr_lock);
3250 
3251 	return ret;
3252 }
3253 EXPORT_SYMBOL_GPL(wm_adsp_compr_copy);
3254 
3255 MODULE_LICENSE("GPL v2");
3256