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