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