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 <sound/core.h>
27#include <sound/pcm.h>
28#include <sound/pcm_params.h>
29#include <sound/soc.h>
30#include <sound/jack.h>
31#include <sound/initval.h>
32#include <sound/tlv.h>
33
34#include <linux/mfd/arizona/registers.h>
35
36#include "arizona.h"
37#include "wm_adsp.h"
38
39#define adsp_crit(_dsp, fmt, ...) \
40	dev_crit(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__)
41#define adsp_err(_dsp, fmt, ...) \
42	dev_err(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__)
43#define adsp_warn(_dsp, fmt, ...) \
44	dev_warn(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__)
45#define adsp_info(_dsp, fmt, ...) \
46	dev_info(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__)
47#define adsp_dbg(_dsp, fmt, ...) \
48	dev_dbg(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__)
49
50#define ADSP1_CONTROL_1                   0x00
51#define ADSP1_CONTROL_2                   0x02
52#define ADSP1_CONTROL_3                   0x03
53#define ADSP1_CONTROL_4                   0x04
54#define ADSP1_CONTROL_5                   0x06
55#define ADSP1_CONTROL_6                   0x07
56#define ADSP1_CONTROL_7                   0x08
57#define ADSP1_CONTROL_8                   0x09
58#define ADSP1_CONTROL_9                   0x0A
59#define ADSP1_CONTROL_10                  0x0B
60#define ADSP1_CONTROL_11                  0x0C
61#define ADSP1_CONTROL_12                  0x0D
62#define ADSP1_CONTROL_13                  0x0F
63#define ADSP1_CONTROL_14                  0x10
64#define ADSP1_CONTROL_15                  0x11
65#define ADSP1_CONTROL_16                  0x12
66#define ADSP1_CONTROL_17                  0x13
67#define ADSP1_CONTROL_18                  0x14
68#define ADSP1_CONTROL_19                  0x16
69#define ADSP1_CONTROL_20                  0x17
70#define ADSP1_CONTROL_21                  0x18
71#define ADSP1_CONTROL_22                  0x1A
72#define ADSP1_CONTROL_23                  0x1B
73#define ADSP1_CONTROL_24                  0x1C
74#define ADSP1_CONTROL_25                  0x1E
75#define ADSP1_CONTROL_26                  0x20
76#define ADSP1_CONTROL_27                  0x21
77#define ADSP1_CONTROL_28                  0x22
78#define ADSP1_CONTROL_29                  0x23
79#define ADSP1_CONTROL_30                  0x24
80#define ADSP1_CONTROL_31                  0x26
81
82/*
83 * ADSP1 Control 19
84 */
85#define ADSP1_WDMA_BUFFER_LENGTH_MASK     0x00FF  /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */
86#define ADSP1_WDMA_BUFFER_LENGTH_SHIFT         0  /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */
87#define ADSP1_WDMA_BUFFER_LENGTH_WIDTH         8  /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */
88
89
90/*
91 * ADSP1 Control 30
92 */
93#define ADSP1_DBG_CLK_ENA                 0x0008  /* DSP1_DBG_CLK_ENA */
94#define ADSP1_DBG_CLK_ENA_MASK            0x0008  /* DSP1_DBG_CLK_ENA */
95#define ADSP1_DBG_CLK_ENA_SHIFT                3  /* DSP1_DBG_CLK_ENA */
96#define ADSP1_DBG_CLK_ENA_WIDTH                1  /* DSP1_DBG_CLK_ENA */
97#define ADSP1_SYS_ENA                     0x0004  /* DSP1_SYS_ENA */
98#define ADSP1_SYS_ENA_MASK                0x0004  /* DSP1_SYS_ENA */
99#define ADSP1_SYS_ENA_SHIFT                    2  /* DSP1_SYS_ENA */
100#define ADSP1_SYS_ENA_WIDTH                    1  /* DSP1_SYS_ENA */
101#define ADSP1_CORE_ENA                    0x0002  /* DSP1_CORE_ENA */
102#define ADSP1_CORE_ENA_MASK               0x0002  /* DSP1_CORE_ENA */
103#define ADSP1_CORE_ENA_SHIFT                   1  /* DSP1_CORE_ENA */
104#define ADSP1_CORE_ENA_WIDTH                   1  /* DSP1_CORE_ENA */
105#define ADSP1_START                       0x0001  /* DSP1_START */
106#define ADSP1_START_MASK                  0x0001  /* DSP1_START */
107#define ADSP1_START_SHIFT                      0  /* DSP1_START */
108#define ADSP1_START_WIDTH                      1  /* DSP1_START */
109
110/*
111 * ADSP1 Control 31
112 */
113#define ADSP1_CLK_SEL_MASK                0x0007  /* CLK_SEL_ENA */
114#define ADSP1_CLK_SEL_SHIFT                    0  /* CLK_SEL_ENA */
115#define ADSP1_CLK_SEL_WIDTH                    3  /* CLK_SEL_ENA */
116
117#define ADSP2_CONTROL        0x0
118#define ADSP2_CLOCKING       0x1
119#define ADSP2_STATUS1        0x4
120#define ADSP2_WDMA_CONFIG_1 0x30
121#define ADSP2_WDMA_CONFIG_2 0x31
122#define ADSP2_RDMA_CONFIG_1 0x34
123
124/*
125 * ADSP2 Control
126 */
127
128#define ADSP2_MEM_ENA                     0x0010  /* DSP1_MEM_ENA */
129#define ADSP2_MEM_ENA_MASK                0x0010  /* DSP1_MEM_ENA */
130#define ADSP2_MEM_ENA_SHIFT                    4  /* DSP1_MEM_ENA */
131#define ADSP2_MEM_ENA_WIDTH                    1  /* DSP1_MEM_ENA */
132#define ADSP2_SYS_ENA                     0x0004  /* DSP1_SYS_ENA */
133#define ADSP2_SYS_ENA_MASK                0x0004  /* DSP1_SYS_ENA */
134#define ADSP2_SYS_ENA_SHIFT                    2  /* DSP1_SYS_ENA */
135#define ADSP2_SYS_ENA_WIDTH                    1  /* DSP1_SYS_ENA */
136#define ADSP2_CORE_ENA                    0x0002  /* DSP1_CORE_ENA */
137#define ADSP2_CORE_ENA_MASK               0x0002  /* DSP1_CORE_ENA */
138#define ADSP2_CORE_ENA_SHIFT                   1  /* DSP1_CORE_ENA */
139#define ADSP2_CORE_ENA_WIDTH                   1  /* DSP1_CORE_ENA */
140#define ADSP2_START                       0x0001  /* DSP1_START */
141#define ADSP2_START_MASK                  0x0001  /* DSP1_START */
142#define ADSP2_START_SHIFT                      0  /* DSP1_START */
143#define ADSP2_START_WIDTH                      1  /* DSP1_START */
144
145/*
146 * ADSP2 clocking
147 */
148#define ADSP2_CLK_SEL_MASK                0x0007  /* CLK_SEL_ENA */
149#define ADSP2_CLK_SEL_SHIFT                    0  /* CLK_SEL_ENA */
150#define ADSP2_CLK_SEL_WIDTH                    3  /* CLK_SEL_ENA */
151
152/*
153 * ADSP2 Status 1
154 */
155#define ADSP2_RAM_RDY                     0x0001
156#define ADSP2_RAM_RDY_MASK                0x0001
157#define ADSP2_RAM_RDY_SHIFT                    0
158#define ADSP2_RAM_RDY_WIDTH                    1
159
160struct wm_adsp_buf {
161	struct list_head list;
162	void *buf;
163};
164
165static struct wm_adsp_buf *wm_adsp_buf_alloc(const void *src, size_t len,
166					     struct list_head *list)
167{
168	struct wm_adsp_buf *buf = kzalloc(sizeof(*buf), GFP_KERNEL);
169
170	if (buf == NULL)
171		return NULL;
172
173	buf->buf = vmalloc(len);
174	if (!buf->buf) {
175		vfree(buf);
176		return NULL;
177	}
178	memcpy(buf->buf, src, len);
179
180	if (list)
181		list_add_tail(&buf->list, list);
182
183	return buf;
184}
185
186static void wm_adsp_buf_free(struct list_head *list)
187{
188	while (!list_empty(list)) {
189		struct wm_adsp_buf *buf = list_first_entry(list,
190							   struct wm_adsp_buf,
191							   list);
192		list_del(&buf->list);
193		vfree(buf->buf);
194		kfree(buf);
195	}
196}
197
198#define WM_ADSP_NUM_FW 4
199
200#define WM_ADSP_FW_MBC_VSS 0
201#define WM_ADSP_FW_TX      1
202#define WM_ADSP_FW_TX_SPK  2
203#define WM_ADSP_FW_RX_ANC  3
204
205static const char *wm_adsp_fw_text[WM_ADSP_NUM_FW] = {
206	[WM_ADSP_FW_MBC_VSS] = "MBC/VSS",
207	[WM_ADSP_FW_TX] =      "Tx",
208	[WM_ADSP_FW_TX_SPK] =  "Tx Speaker",
209	[WM_ADSP_FW_RX_ANC] =  "Rx ANC",
210};
211
212static struct {
213	const char *file;
214} wm_adsp_fw[WM_ADSP_NUM_FW] = {
215	[WM_ADSP_FW_MBC_VSS] = { .file = "mbc-vss" },
216	[WM_ADSP_FW_TX] =      { .file = "tx" },
217	[WM_ADSP_FW_TX_SPK] =  { .file = "tx-spk" },
218	[WM_ADSP_FW_RX_ANC] =  { .file = "rx-anc" },
219};
220
221struct wm_coeff_ctl_ops {
222	int (*xget)(struct snd_kcontrol *kcontrol,
223		    struct snd_ctl_elem_value *ucontrol);
224	int (*xput)(struct snd_kcontrol *kcontrol,
225		    struct snd_ctl_elem_value *ucontrol);
226	int (*xinfo)(struct snd_kcontrol *kcontrol,
227		     struct snd_ctl_elem_info *uinfo);
228};
229
230struct wm_coeff_ctl {
231	const char *name;
232	struct wm_adsp_alg_region region;
233	struct wm_coeff_ctl_ops ops;
234	struct wm_adsp *adsp;
235	void *private;
236	unsigned int enabled:1;
237	struct list_head list;
238	void *cache;
239	size_t len;
240	unsigned int set:1;
241	struct snd_kcontrol *kcontrol;
242};
243
244static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol,
245			  struct snd_ctl_elem_value *ucontrol)
246{
247	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
248	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
249	struct wm_adsp *adsp = snd_soc_codec_get_drvdata(codec);
250
251	ucontrol->value.enumerated.item[0] = adsp[e->shift_l].fw;
252
253	return 0;
254}
255
256static int wm_adsp_fw_put(struct snd_kcontrol *kcontrol,
257			  struct snd_ctl_elem_value *ucontrol)
258{
259	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
260	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
261	struct wm_adsp *adsp = snd_soc_codec_get_drvdata(codec);
262
263	if (ucontrol->value.enumerated.item[0] == adsp[e->shift_l].fw)
264		return 0;
265
266	if (ucontrol->value.enumerated.item[0] >= WM_ADSP_NUM_FW)
267		return -EINVAL;
268
269	if (adsp[e->shift_l].running)
270		return -EBUSY;
271
272	adsp[e->shift_l].fw = ucontrol->value.enumerated.item[0];
273
274	return 0;
275}
276
277static const struct soc_enum wm_adsp_fw_enum[] = {
278	SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
279	SOC_ENUM_SINGLE(0, 1, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
280	SOC_ENUM_SINGLE(0, 2, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
281	SOC_ENUM_SINGLE(0, 3, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
282};
283
284const struct snd_kcontrol_new wm_adsp1_fw_controls[] = {
285	SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0],
286		     wm_adsp_fw_get, wm_adsp_fw_put),
287	SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1],
288		     wm_adsp_fw_get, wm_adsp_fw_put),
289	SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2],
290		     wm_adsp_fw_get, wm_adsp_fw_put),
291};
292EXPORT_SYMBOL_GPL(wm_adsp1_fw_controls);
293
294#if IS_ENABLED(CONFIG_SND_SOC_ARIZONA)
295static const struct soc_enum wm_adsp2_rate_enum[] = {
296	SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP1_CONTROL_1,
297			      ARIZONA_DSP1_RATE_SHIFT, 0xf,
298			      ARIZONA_RATE_ENUM_SIZE,
299			      arizona_rate_text, arizona_rate_val),
300	SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP2_CONTROL_1,
301			      ARIZONA_DSP1_RATE_SHIFT, 0xf,
302			      ARIZONA_RATE_ENUM_SIZE,
303			      arizona_rate_text, arizona_rate_val),
304	SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP3_CONTROL_1,
305			      ARIZONA_DSP1_RATE_SHIFT, 0xf,
306			      ARIZONA_RATE_ENUM_SIZE,
307			      arizona_rate_text, arizona_rate_val),
308	SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP4_CONTROL_1,
309			      ARIZONA_DSP1_RATE_SHIFT, 0xf,
310			      ARIZONA_RATE_ENUM_SIZE,
311			      arizona_rate_text, arizona_rate_val),
312};
313
314const struct snd_kcontrol_new wm_adsp2_fw_controls[] = {
315	SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0],
316		     wm_adsp_fw_get, wm_adsp_fw_put),
317	SOC_ENUM("DSP1 Rate", wm_adsp2_rate_enum[0]),
318	SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1],
319		     wm_adsp_fw_get, wm_adsp_fw_put),
320	SOC_ENUM("DSP2 Rate", wm_adsp2_rate_enum[1]),
321	SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2],
322		     wm_adsp_fw_get, wm_adsp_fw_put),
323	SOC_ENUM("DSP3 Rate", wm_adsp2_rate_enum[2]),
324	SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3],
325		     wm_adsp_fw_get, wm_adsp_fw_put),
326	SOC_ENUM("DSP4 Rate", wm_adsp2_rate_enum[3]),
327};
328EXPORT_SYMBOL_GPL(wm_adsp2_fw_controls);
329#endif
330
331static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp,
332							int type)
333{
334	int i;
335
336	for (i = 0; i < dsp->num_mems; i++)
337		if (dsp->mem[i].type == type)
338			return &dsp->mem[i];
339
340	return NULL;
341}
342
343static unsigned int wm_adsp_region_to_reg(struct wm_adsp_region const *region,
344					  unsigned int offset)
345{
346	if (WARN_ON(!region))
347		return offset;
348	switch (region->type) {
349	case WMFW_ADSP1_PM:
350		return region->base + (offset * 3);
351	case WMFW_ADSP1_DM:
352		return region->base + (offset * 2);
353	case WMFW_ADSP2_XM:
354		return region->base + (offset * 2);
355	case WMFW_ADSP2_YM:
356		return region->base + (offset * 2);
357	case WMFW_ADSP1_ZM:
358		return region->base + (offset * 2);
359	default:
360		WARN(1, "Unknown memory region type");
361		return offset;
362	}
363}
364
365static int wm_coeff_info(struct snd_kcontrol *kcontrol,
366			 struct snd_ctl_elem_info *uinfo)
367{
368	struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value;
369
370	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
371	uinfo->count = ctl->len;
372	return 0;
373}
374
375static int wm_coeff_write_control(struct snd_kcontrol *kcontrol,
376				  const void *buf, size_t len)
377{
378	struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value;
379	struct wm_adsp_alg_region *region = &ctl->region;
380	const struct wm_adsp_region *mem;
381	struct wm_adsp *adsp = ctl->adsp;
382	void *scratch;
383	int ret;
384	unsigned int reg;
385
386	mem = wm_adsp_find_region(adsp, region->type);
387	if (!mem) {
388		adsp_err(adsp, "No base for region %x\n",
389			 region->type);
390		return -EINVAL;
391	}
392
393	reg = ctl->region.base;
394	reg = wm_adsp_region_to_reg(mem, reg);
395
396	scratch = kmemdup(buf, ctl->len, GFP_KERNEL | GFP_DMA);
397	if (!scratch)
398		return -ENOMEM;
399
400	ret = regmap_raw_write(adsp->regmap, reg, scratch,
401			       ctl->len);
402	if (ret) {
403		adsp_err(adsp, "Failed to write %zu bytes to %x: %d\n",
404			 ctl->len, reg, ret);
405		kfree(scratch);
406		return ret;
407	}
408	adsp_dbg(adsp, "Wrote %zu bytes to %x\n", ctl->len, reg);
409
410	kfree(scratch);
411
412	return 0;
413}
414
415static int wm_coeff_put(struct snd_kcontrol *kcontrol,
416			struct snd_ctl_elem_value *ucontrol)
417{
418	struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value;
419	char *p = ucontrol->value.bytes.data;
420
421	memcpy(ctl->cache, p, ctl->len);
422
423	ctl->set = 1;
424	if (!ctl->enabled)
425		return 0;
426
427	return wm_coeff_write_control(kcontrol, p, ctl->len);
428}
429
430static int wm_coeff_read_control(struct snd_kcontrol *kcontrol,
431				 void *buf, size_t len)
432{
433	struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value;
434	struct wm_adsp_alg_region *region = &ctl->region;
435	const struct wm_adsp_region *mem;
436	struct wm_adsp *adsp = ctl->adsp;
437	void *scratch;
438	int ret;
439	unsigned int reg;
440
441	mem = wm_adsp_find_region(adsp, region->type);
442	if (!mem) {
443		adsp_err(adsp, "No base for region %x\n",
444			 region->type);
445		return -EINVAL;
446	}
447
448	reg = ctl->region.base;
449	reg = wm_adsp_region_to_reg(mem, reg);
450
451	scratch = kmalloc(ctl->len, GFP_KERNEL | GFP_DMA);
452	if (!scratch)
453		return -ENOMEM;
454
455	ret = regmap_raw_read(adsp->regmap, reg, scratch, ctl->len);
456	if (ret) {
457		adsp_err(adsp, "Failed to read %zu bytes from %x: %d\n",
458			 ctl->len, reg, ret);
459		kfree(scratch);
460		return ret;
461	}
462	adsp_dbg(adsp, "Read %zu bytes from %x\n", ctl->len, reg);
463
464	memcpy(buf, scratch, ctl->len);
465	kfree(scratch);
466
467	return 0;
468}
469
470static int wm_coeff_get(struct snd_kcontrol *kcontrol,
471			struct snd_ctl_elem_value *ucontrol)
472{
473	struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value;
474	char *p = ucontrol->value.bytes.data;
475
476	memcpy(p, ctl->cache, ctl->len);
477	return 0;
478}
479
480struct wmfw_ctl_work {
481	struct wm_adsp *adsp;
482	struct wm_coeff_ctl *ctl;
483	struct work_struct work;
484};
485
486static int wmfw_add_ctl(struct wm_adsp *adsp, struct wm_coeff_ctl *ctl)
487{
488	struct snd_kcontrol_new *kcontrol;
489	int ret;
490
491	if (!ctl || !ctl->name)
492		return -EINVAL;
493
494	kcontrol = kzalloc(sizeof(*kcontrol), GFP_KERNEL);
495	if (!kcontrol)
496		return -ENOMEM;
497	kcontrol->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
498
499	kcontrol->name = ctl->name;
500	kcontrol->info = wm_coeff_info;
501	kcontrol->get = wm_coeff_get;
502	kcontrol->put = wm_coeff_put;
503	kcontrol->private_value = (unsigned long)ctl;
504
505	ret = snd_soc_add_card_controls(adsp->card,
506					kcontrol, 1);
507	if (ret < 0)
508		goto err_kcontrol;
509
510	kfree(kcontrol);
511
512	ctl->kcontrol = snd_soc_card_get_kcontrol(adsp->card,
513						  ctl->name);
514
515	list_add(&ctl->list, &adsp->ctl_list);
516	return 0;
517
518err_kcontrol:
519	kfree(kcontrol);
520	return ret;
521}
522
523static int wm_adsp_load(struct wm_adsp *dsp)
524{
525	LIST_HEAD(buf_list);
526	const struct firmware *firmware;
527	struct regmap *regmap = dsp->regmap;
528	unsigned int pos = 0;
529	const struct wmfw_header *header;
530	const struct wmfw_adsp1_sizes *adsp1_sizes;
531	const struct wmfw_adsp2_sizes *adsp2_sizes;
532	const struct wmfw_footer *footer;
533	const struct wmfw_region *region;
534	const struct wm_adsp_region *mem;
535	const char *region_name;
536	char *file, *text;
537	struct wm_adsp_buf *buf;
538	unsigned int reg;
539	int regions = 0;
540	int ret, offset, type, sizes;
541
542	file = kzalloc(PAGE_SIZE, GFP_KERNEL);
543	if (file == NULL)
544		return -ENOMEM;
545
546	snprintf(file, PAGE_SIZE, "%s-dsp%d-%s.wmfw", dsp->part, dsp->num,
547		 wm_adsp_fw[dsp->fw].file);
548	file[PAGE_SIZE - 1] = '\0';
549
550	ret = request_firmware(&firmware, file, dsp->dev);
551	if (ret != 0) {
552		adsp_err(dsp, "Failed to request '%s'\n", file);
553		goto out;
554	}
555	ret = -EINVAL;
556
557	pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer);
558	if (pos >= firmware->size) {
559		adsp_err(dsp, "%s: file too short, %zu bytes\n",
560			 file, firmware->size);
561		goto out_fw;
562	}
563
564	header = (void*)&firmware->data[0];
565
566	if (memcmp(&header->magic[0], "WMFW", 4) != 0) {
567		adsp_err(dsp, "%s: invalid magic\n", file);
568		goto out_fw;
569	}
570
571	if (header->ver != 0) {
572		adsp_err(dsp, "%s: unknown file format %d\n",
573			 file, header->ver);
574		goto out_fw;
575	}
576	adsp_info(dsp, "Firmware version: %d\n", header->ver);
577
578	if (header->core != dsp->type) {
579		adsp_err(dsp, "%s: invalid core %d != %d\n",
580			 file, header->core, dsp->type);
581		goto out_fw;
582	}
583
584	switch (dsp->type) {
585	case WMFW_ADSP1:
586		pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer);
587		adsp1_sizes = (void *)&(header[1]);
588		footer = (void *)&(adsp1_sizes[1]);
589		sizes = sizeof(*adsp1_sizes);
590
591		adsp_dbg(dsp, "%s: %d DM, %d PM, %d ZM\n",
592			 file, le32_to_cpu(adsp1_sizes->dm),
593			 le32_to_cpu(adsp1_sizes->pm),
594			 le32_to_cpu(adsp1_sizes->zm));
595		break;
596
597	case WMFW_ADSP2:
598		pos = sizeof(*header) + sizeof(*adsp2_sizes) + sizeof(*footer);
599		adsp2_sizes = (void *)&(header[1]);
600		footer = (void *)&(adsp2_sizes[1]);
601		sizes = sizeof(*adsp2_sizes);
602
603		adsp_dbg(dsp, "%s: %d XM, %d YM %d PM, %d ZM\n",
604			 file, le32_to_cpu(adsp2_sizes->xm),
605			 le32_to_cpu(adsp2_sizes->ym),
606			 le32_to_cpu(adsp2_sizes->pm),
607			 le32_to_cpu(adsp2_sizes->zm));
608		break;
609
610	default:
611		WARN(1, "Unknown DSP type");
612		goto out_fw;
613	}
614
615	if (le32_to_cpu(header->len) != sizeof(*header) +
616	    sizes + sizeof(*footer)) {
617		adsp_err(dsp, "%s: unexpected header length %d\n",
618			 file, le32_to_cpu(header->len));
619		goto out_fw;
620	}
621
622	adsp_dbg(dsp, "%s: timestamp %llu\n", file,
623		 le64_to_cpu(footer->timestamp));
624
625	while (pos < firmware->size &&
626	       pos - firmware->size > sizeof(*region)) {
627		region = (void *)&(firmware->data[pos]);
628		region_name = "Unknown";
629		reg = 0;
630		text = NULL;
631		offset = le32_to_cpu(region->offset) & 0xffffff;
632		type = be32_to_cpu(region->type) & 0xff;
633		mem = wm_adsp_find_region(dsp, type);
634
635		switch (type) {
636		case WMFW_NAME_TEXT:
637			region_name = "Firmware name";
638			text = kzalloc(le32_to_cpu(region->len) + 1,
639				       GFP_KERNEL);
640			break;
641		case WMFW_INFO_TEXT:
642			region_name = "Information";
643			text = kzalloc(le32_to_cpu(region->len) + 1,
644				       GFP_KERNEL);
645			break;
646		case WMFW_ABSOLUTE:
647			region_name = "Absolute";
648			reg = offset;
649			break;
650		case WMFW_ADSP1_PM:
651			region_name = "PM";
652			reg = wm_adsp_region_to_reg(mem, offset);
653			break;
654		case WMFW_ADSP1_DM:
655			region_name = "DM";
656			reg = wm_adsp_region_to_reg(mem, offset);
657			break;
658		case WMFW_ADSP2_XM:
659			region_name = "XM";
660			reg = wm_adsp_region_to_reg(mem, offset);
661			break;
662		case WMFW_ADSP2_YM:
663			region_name = "YM";
664			reg = wm_adsp_region_to_reg(mem, offset);
665			break;
666		case WMFW_ADSP1_ZM:
667			region_name = "ZM";
668			reg = wm_adsp_region_to_reg(mem, offset);
669			break;
670		default:
671			adsp_warn(dsp,
672				  "%s.%d: Unknown region type %x at %d(%x)\n",
673				  file, regions, type, pos, pos);
674			break;
675		}
676
677		adsp_dbg(dsp, "%s.%d: %d bytes at %d in %s\n", file,
678			 regions, le32_to_cpu(region->len), offset,
679			 region_name);
680
681		if (text) {
682			memcpy(text, region->data, le32_to_cpu(region->len));
683			adsp_info(dsp, "%s: %s\n", file, text);
684			kfree(text);
685		}
686
687		if (reg) {
688			buf = wm_adsp_buf_alloc(region->data,
689						le32_to_cpu(region->len),
690						&buf_list);
691			if (!buf) {
692				adsp_err(dsp, "Out of memory\n");
693				ret = -ENOMEM;
694				goto out_fw;
695			}
696
697			ret = regmap_raw_write_async(regmap, reg, buf->buf,
698						     le32_to_cpu(region->len));
699			if (ret != 0) {
700				adsp_err(dsp,
701					"%s.%d: Failed to write %d bytes at %d in %s: %d\n",
702					file, regions,
703					le32_to_cpu(region->len), offset,
704					region_name, ret);
705				goto out_fw;
706			}
707		}
708
709		pos += le32_to_cpu(region->len) + sizeof(*region);
710		regions++;
711	}
712
713	ret = regmap_async_complete(regmap);
714	if (ret != 0) {
715		adsp_err(dsp, "Failed to complete async write: %d\n", ret);
716		goto out_fw;
717	}
718
719	if (pos > firmware->size)
720		adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n",
721			  file, regions, pos - firmware->size);
722
723out_fw:
724	regmap_async_complete(regmap);
725	wm_adsp_buf_free(&buf_list);
726	release_firmware(firmware);
727out:
728	kfree(file);
729
730	return ret;
731}
732
733static int wm_coeff_init_control_caches(struct wm_adsp *adsp)
734{
735	struct wm_coeff_ctl *ctl;
736	int ret;
737
738	list_for_each_entry(ctl, &adsp->ctl_list, list) {
739		if (!ctl->enabled || ctl->set)
740			continue;
741		ret = wm_coeff_read_control(ctl->kcontrol,
742					    ctl->cache,
743					    ctl->len);
744		if (ret < 0)
745			return ret;
746	}
747
748	return 0;
749}
750
751static int wm_coeff_sync_controls(struct wm_adsp *adsp)
752{
753	struct wm_coeff_ctl *ctl;
754	int ret;
755
756	list_for_each_entry(ctl, &adsp->ctl_list, list) {
757		if (!ctl->enabled)
758			continue;
759		if (ctl->set) {
760			ret = wm_coeff_write_control(ctl->kcontrol,
761						     ctl->cache,
762						     ctl->len);
763			if (ret < 0)
764				return ret;
765		}
766	}
767
768	return 0;
769}
770
771static void wm_adsp_ctl_work(struct work_struct *work)
772{
773	struct wmfw_ctl_work *ctl_work = container_of(work,
774						      struct wmfw_ctl_work,
775						      work);
776
777	wmfw_add_ctl(ctl_work->adsp, ctl_work->ctl);
778	kfree(ctl_work);
779}
780
781static int wm_adsp_create_control(struct wm_adsp *dsp,
782				  const struct wm_adsp_alg_region *region)
783
784{
785	struct wm_coeff_ctl *ctl;
786	struct wmfw_ctl_work *ctl_work;
787	char *name;
788	char *region_name;
789	int ret;
790
791	name = kmalloc(PAGE_SIZE, GFP_KERNEL);
792	if (!name)
793		return -ENOMEM;
794
795	switch (region->type) {
796	case WMFW_ADSP1_PM:
797		region_name = "PM";
798		break;
799	case WMFW_ADSP1_DM:
800		region_name = "DM";
801		break;
802	case WMFW_ADSP2_XM:
803		region_name = "XM";
804		break;
805	case WMFW_ADSP2_YM:
806		region_name = "YM";
807		break;
808	case WMFW_ADSP1_ZM:
809		region_name = "ZM";
810		break;
811	default:
812		ret = -EINVAL;
813		goto err_name;
814	}
815
816	snprintf(name, PAGE_SIZE, "DSP%d %s %x",
817		 dsp->num, region_name, region->alg);
818
819	list_for_each_entry(ctl, &dsp->ctl_list,
820			    list) {
821		if (!strcmp(ctl->name, name)) {
822			if (!ctl->enabled)
823				ctl->enabled = 1;
824			goto found;
825		}
826	}
827
828	ctl = kzalloc(sizeof(*ctl), GFP_KERNEL);
829	if (!ctl) {
830		ret = -ENOMEM;
831		goto err_name;
832	}
833	ctl->region = *region;
834	ctl->name = kmemdup(name, strlen(name) + 1, GFP_KERNEL);
835	if (!ctl->name) {
836		ret = -ENOMEM;
837		goto err_ctl;
838	}
839	ctl->enabled = 1;
840	ctl->set = 0;
841	ctl->ops.xget = wm_coeff_get;
842	ctl->ops.xput = wm_coeff_put;
843	ctl->adsp = dsp;
844
845	ctl->len = region->len;
846	ctl->cache = kzalloc(ctl->len, GFP_KERNEL);
847	if (!ctl->cache) {
848		ret = -ENOMEM;
849		goto err_ctl_name;
850	}
851
852	ctl_work = kzalloc(sizeof(*ctl_work), GFP_KERNEL);
853	if (!ctl_work) {
854		ret = -ENOMEM;
855		goto err_ctl_cache;
856	}
857
858	ctl_work->adsp = dsp;
859	ctl_work->ctl = ctl;
860	INIT_WORK(&ctl_work->work, wm_adsp_ctl_work);
861	schedule_work(&ctl_work->work);
862
863found:
864	kfree(name);
865
866	return 0;
867
868err_ctl_cache:
869	kfree(ctl->cache);
870err_ctl_name:
871	kfree(ctl->name);
872err_ctl:
873	kfree(ctl);
874err_name:
875	kfree(name);
876	return ret;
877}
878
879static int wm_adsp_setup_algs(struct wm_adsp *dsp)
880{
881	struct regmap *regmap = dsp->regmap;
882	struct wmfw_adsp1_id_hdr adsp1_id;
883	struct wmfw_adsp2_id_hdr adsp2_id;
884	struct wmfw_adsp1_alg_hdr *adsp1_alg;
885	struct wmfw_adsp2_alg_hdr *adsp2_alg;
886	void *alg, *buf;
887	struct wm_adsp_alg_region *region;
888	const struct wm_adsp_region *mem;
889	unsigned int pos, term;
890	size_t algs, buf_size;
891	__be32 val;
892	int i, ret;
893
894	switch (dsp->type) {
895	case WMFW_ADSP1:
896		mem = wm_adsp_find_region(dsp, WMFW_ADSP1_DM);
897		break;
898	case WMFW_ADSP2:
899		mem = wm_adsp_find_region(dsp, WMFW_ADSP2_XM);
900		break;
901	default:
902		mem = NULL;
903		break;
904	}
905
906	if (WARN_ON(!mem))
907		return -EINVAL;
908
909	switch (dsp->type) {
910	case WMFW_ADSP1:
911		ret = regmap_raw_read(regmap, mem->base, &adsp1_id,
912				      sizeof(adsp1_id));
913		if (ret != 0) {
914			adsp_err(dsp, "Failed to read algorithm info: %d\n",
915				 ret);
916			return ret;
917		}
918
919		buf = &adsp1_id;
920		buf_size = sizeof(adsp1_id);
921
922		algs = be32_to_cpu(adsp1_id.algs);
923		dsp->fw_id = be32_to_cpu(adsp1_id.fw.id);
924		adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n",
925			  dsp->fw_id,
926			  (be32_to_cpu(adsp1_id.fw.ver) & 0xff0000) >> 16,
927			  (be32_to_cpu(adsp1_id.fw.ver) & 0xff00) >> 8,
928			  be32_to_cpu(adsp1_id.fw.ver) & 0xff,
929			  algs);
930
931		region = kzalloc(sizeof(*region), GFP_KERNEL);
932		if (!region)
933			return -ENOMEM;
934		region->type = WMFW_ADSP1_ZM;
935		region->alg = be32_to_cpu(adsp1_id.fw.id);
936		region->base = be32_to_cpu(adsp1_id.zm);
937		list_add_tail(&region->list, &dsp->alg_regions);
938
939		region = kzalloc(sizeof(*region), GFP_KERNEL);
940		if (!region)
941			return -ENOMEM;
942		region->type = WMFW_ADSP1_DM;
943		region->alg = be32_to_cpu(adsp1_id.fw.id);
944		region->base = be32_to_cpu(adsp1_id.dm);
945		list_add_tail(&region->list, &dsp->alg_regions);
946
947		pos = sizeof(adsp1_id) / 2;
948		term = pos + ((sizeof(*adsp1_alg) * algs) / 2);
949		break;
950
951	case WMFW_ADSP2:
952		ret = regmap_raw_read(regmap, mem->base, &adsp2_id,
953				      sizeof(adsp2_id));
954		if (ret != 0) {
955			adsp_err(dsp, "Failed to read algorithm info: %d\n",
956				 ret);
957			return ret;
958		}
959
960		buf = &adsp2_id;
961		buf_size = sizeof(adsp2_id);
962
963		algs = be32_to_cpu(adsp2_id.algs);
964		dsp->fw_id = be32_to_cpu(adsp2_id.fw.id);
965		adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n",
966			  dsp->fw_id,
967			  (be32_to_cpu(adsp2_id.fw.ver) & 0xff0000) >> 16,
968			  (be32_to_cpu(adsp2_id.fw.ver) & 0xff00) >> 8,
969			  be32_to_cpu(adsp2_id.fw.ver) & 0xff,
970			  algs);
971
972		region = kzalloc(sizeof(*region), GFP_KERNEL);
973		if (!region)
974			return -ENOMEM;
975		region->type = WMFW_ADSP2_XM;
976		region->alg = be32_to_cpu(adsp2_id.fw.id);
977		region->base = be32_to_cpu(adsp2_id.xm);
978		list_add_tail(&region->list, &dsp->alg_regions);
979
980		region = kzalloc(sizeof(*region), GFP_KERNEL);
981		if (!region)
982			return -ENOMEM;
983		region->type = WMFW_ADSP2_YM;
984		region->alg = be32_to_cpu(adsp2_id.fw.id);
985		region->base = be32_to_cpu(adsp2_id.ym);
986		list_add_tail(&region->list, &dsp->alg_regions);
987
988		region = kzalloc(sizeof(*region), GFP_KERNEL);
989		if (!region)
990			return -ENOMEM;
991		region->type = WMFW_ADSP2_ZM;
992		region->alg = be32_to_cpu(adsp2_id.fw.id);
993		region->base = be32_to_cpu(adsp2_id.zm);
994		list_add_tail(&region->list, &dsp->alg_regions);
995
996		pos = sizeof(adsp2_id) / 2;
997		term = pos + ((sizeof(*adsp2_alg) * algs) / 2);
998		break;
999
1000	default:
1001		WARN(1, "Unknown DSP type");
1002		return -EINVAL;
1003	}
1004
1005	if (algs == 0) {
1006		adsp_err(dsp, "No algorithms\n");
1007		return -EINVAL;
1008	}
1009
1010	if (algs > 1024) {
1011		adsp_err(dsp, "Algorithm count %zx excessive\n", algs);
1012		print_hex_dump_bytes(dev_name(dsp->dev), DUMP_PREFIX_OFFSET,
1013				     buf, buf_size);
1014		return -EINVAL;
1015	}
1016
1017	/* Read the terminator first to validate the length */
1018	ret = regmap_raw_read(regmap, mem->base + term, &val, sizeof(val));
1019	if (ret != 0) {
1020		adsp_err(dsp, "Failed to read algorithm list end: %d\n",
1021			ret);
1022		return ret;
1023	}
1024
1025	if (be32_to_cpu(val) != 0xbedead)
1026		adsp_warn(dsp, "Algorithm list end %x 0x%x != 0xbeadead\n",
1027			  term, be32_to_cpu(val));
1028
1029	alg = kzalloc((term - pos) * 2, GFP_KERNEL | GFP_DMA);
1030	if (!alg)
1031		return -ENOMEM;
1032
1033	ret = regmap_raw_read(regmap, mem->base + pos, alg, (term - pos) * 2);
1034	if (ret != 0) {
1035		adsp_err(dsp, "Failed to read algorithm list: %d\n",
1036			ret);
1037		goto out;
1038	}
1039
1040	adsp1_alg = alg;
1041	adsp2_alg = alg;
1042
1043	for (i = 0; i < algs; i++) {
1044		switch (dsp->type) {
1045		case WMFW_ADSP1:
1046			adsp_info(dsp, "%d: ID %x v%d.%d.%d DM@%x ZM@%x\n",
1047				  i, be32_to_cpu(adsp1_alg[i].alg.id),
1048				  (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff0000) >> 16,
1049				  (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff00) >> 8,
1050				  be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff,
1051				  be32_to_cpu(adsp1_alg[i].dm),
1052				  be32_to_cpu(adsp1_alg[i].zm));
1053
1054			region = kzalloc(sizeof(*region), GFP_KERNEL);
1055			if (!region) {
1056				ret = -ENOMEM;
1057				goto out;
1058			}
1059			region->type = WMFW_ADSP1_DM;
1060			region->alg = be32_to_cpu(adsp1_alg[i].alg.id);
1061			region->base = be32_to_cpu(adsp1_alg[i].dm);
1062			region->len = 0;
1063			list_add_tail(&region->list, &dsp->alg_regions);
1064			if (i + 1 < algs) {
1065				region->len = be32_to_cpu(adsp1_alg[i + 1].dm);
1066				region->len -= be32_to_cpu(adsp1_alg[i].dm);
1067				region->len *= 4;
1068				wm_adsp_create_control(dsp, region);
1069			} else {
1070				adsp_warn(dsp, "Missing length info for region DM with ID %x\n",
1071					  be32_to_cpu(adsp1_alg[i].alg.id));
1072			}
1073
1074			region = kzalloc(sizeof(*region), GFP_KERNEL);
1075			if (!region) {
1076				ret = -ENOMEM;
1077				goto out;
1078			}
1079			region->type = WMFW_ADSP1_ZM;
1080			region->alg = be32_to_cpu(adsp1_alg[i].alg.id);
1081			region->base = be32_to_cpu(adsp1_alg[i].zm);
1082			region->len = 0;
1083			list_add_tail(&region->list, &dsp->alg_regions);
1084			if (i + 1 < algs) {
1085				region->len = be32_to_cpu(adsp1_alg[i + 1].zm);
1086				region->len -= be32_to_cpu(adsp1_alg[i].zm);
1087				region->len *= 4;
1088				wm_adsp_create_control(dsp, region);
1089			} else {
1090				adsp_warn(dsp, "Missing length info for region ZM with ID %x\n",
1091					  be32_to_cpu(adsp1_alg[i].alg.id));
1092			}
1093			break;
1094
1095		case WMFW_ADSP2:
1096			adsp_info(dsp,
1097				  "%d: ID %x v%d.%d.%d XM@%x YM@%x ZM@%x\n",
1098				  i, be32_to_cpu(adsp2_alg[i].alg.id),
1099				  (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff0000) >> 16,
1100				  (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff00) >> 8,
1101				  be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff,
1102				  be32_to_cpu(adsp2_alg[i].xm),
1103				  be32_to_cpu(adsp2_alg[i].ym),
1104				  be32_to_cpu(adsp2_alg[i].zm));
1105
1106			region = kzalloc(sizeof(*region), GFP_KERNEL);
1107			if (!region) {
1108				ret = -ENOMEM;
1109				goto out;
1110			}
1111			region->type = WMFW_ADSP2_XM;
1112			region->alg = be32_to_cpu(adsp2_alg[i].alg.id);
1113			region->base = be32_to_cpu(adsp2_alg[i].xm);
1114			region->len = 0;
1115			list_add_tail(&region->list, &dsp->alg_regions);
1116			if (i + 1 < algs) {
1117				region->len = be32_to_cpu(adsp2_alg[i + 1].xm);
1118				region->len -= be32_to_cpu(adsp2_alg[i].xm);
1119				region->len *= 4;
1120				wm_adsp_create_control(dsp, region);
1121			} else {
1122				adsp_warn(dsp, "Missing length info for region XM with ID %x\n",
1123					  be32_to_cpu(adsp2_alg[i].alg.id));
1124			}
1125
1126			region = kzalloc(sizeof(*region), GFP_KERNEL);
1127			if (!region) {
1128				ret = -ENOMEM;
1129				goto out;
1130			}
1131			region->type = WMFW_ADSP2_YM;
1132			region->alg = be32_to_cpu(adsp2_alg[i].alg.id);
1133			region->base = be32_to_cpu(adsp2_alg[i].ym);
1134			region->len = 0;
1135			list_add_tail(&region->list, &dsp->alg_regions);
1136			if (i + 1 < algs) {
1137				region->len = be32_to_cpu(adsp2_alg[i + 1].ym);
1138				region->len -= be32_to_cpu(adsp2_alg[i].ym);
1139				region->len *= 4;
1140				wm_adsp_create_control(dsp, region);
1141			} else {
1142				adsp_warn(dsp, "Missing length info for region YM with ID %x\n",
1143					  be32_to_cpu(adsp2_alg[i].alg.id));
1144			}
1145
1146			region = kzalloc(sizeof(*region), GFP_KERNEL);
1147			if (!region) {
1148				ret = -ENOMEM;
1149				goto out;
1150			}
1151			region->type = WMFW_ADSP2_ZM;
1152			region->alg = be32_to_cpu(adsp2_alg[i].alg.id);
1153			region->base = be32_to_cpu(adsp2_alg[i].zm);
1154			region->len = 0;
1155			list_add_tail(&region->list, &dsp->alg_regions);
1156			if (i + 1 < algs) {
1157				region->len = be32_to_cpu(adsp2_alg[i + 1].zm);
1158				region->len -= be32_to_cpu(adsp2_alg[i].zm);
1159				region->len *= 4;
1160				wm_adsp_create_control(dsp, region);
1161			} else {
1162				adsp_warn(dsp, "Missing length info for region ZM with ID %x\n",
1163					  be32_to_cpu(adsp2_alg[i].alg.id));
1164			}
1165			break;
1166		}
1167	}
1168
1169out:
1170	kfree(alg);
1171	return ret;
1172}
1173
1174static int wm_adsp_load_coeff(struct wm_adsp *dsp)
1175{
1176	LIST_HEAD(buf_list);
1177	struct regmap *regmap = dsp->regmap;
1178	struct wmfw_coeff_hdr *hdr;
1179	struct wmfw_coeff_item *blk;
1180	const struct firmware *firmware;
1181	const struct wm_adsp_region *mem;
1182	struct wm_adsp_alg_region *alg_region;
1183	const char *region_name;
1184	int ret, pos, blocks, type, offset, reg;
1185	char *file;
1186	struct wm_adsp_buf *buf;
1187
1188	file = kzalloc(PAGE_SIZE, GFP_KERNEL);
1189	if (file == NULL)
1190		return -ENOMEM;
1191
1192	snprintf(file, PAGE_SIZE, "%s-dsp%d-%s.bin", dsp->part, dsp->num,
1193		 wm_adsp_fw[dsp->fw].file);
1194	file[PAGE_SIZE - 1] = '\0';
1195
1196	ret = request_firmware(&firmware, file, dsp->dev);
1197	if (ret != 0) {
1198		adsp_warn(dsp, "Failed to request '%s'\n", file);
1199		ret = 0;
1200		goto out;
1201	}
1202	ret = -EINVAL;
1203
1204	if (sizeof(*hdr) >= firmware->size) {
1205		adsp_err(dsp, "%s: file too short, %zu bytes\n",
1206			file, firmware->size);
1207		goto out_fw;
1208	}
1209
1210	hdr = (void*)&firmware->data[0];
1211	if (memcmp(hdr->magic, "WMDR", 4) != 0) {
1212		adsp_err(dsp, "%s: invalid magic\n", file);
1213		goto out_fw;
1214	}
1215
1216	switch (be32_to_cpu(hdr->rev) & 0xff) {
1217	case 1:
1218		break;
1219	default:
1220		adsp_err(dsp, "%s: Unsupported coefficient file format %d\n",
1221			 file, be32_to_cpu(hdr->rev) & 0xff);
1222		ret = -EINVAL;
1223		goto out_fw;
1224	}
1225
1226	adsp_dbg(dsp, "%s: v%d.%d.%d\n", file,
1227		(le32_to_cpu(hdr->ver) >> 16) & 0xff,
1228		(le32_to_cpu(hdr->ver) >>  8) & 0xff,
1229		le32_to_cpu(hdr->ver) & 0xff);
1230
1231	pos = le32_to_cpu(hdr->len);
1232
1233	blocks = 0;
1234	while (pos < firmware->size &&
1235	       pos - firmware->size > sizeof(*blk)) {
1236		blk = (void*)(&firmware->data[pos]);
1237
1238		type = le16_to_cpu(blk->type);
1239		offset = le16_to_cpu(blk->offset);
1240
1241		adsp_dbg(dsp, "%s.%d: %x v%d.%d.%d\n",
1242			 file, blocks, le32_to_cpu(blk->id),
1243			 (le32_to_cpu(blk->ver) >> 16) & 0xff,
1244			 (le32_to_cpu(blk->ver) >>  8) & 0xff,
1245			 le32_to_cpu(blk->ver) & 0xff);
1246		adsp_dbg(dsp, "%s.%d: %d bytes at 0x%x in %x\n",
1247			 file, blocks, le32_to_cpu(blk->len), offset, type);
1248
1249		reg = 0;
1250		region_name = "Unknown";
1251		switch (type) {
1252		case (WMFW_NAME_TEXT << 8):
1253		case (WMFW_INFO_TEXT << 8):
1254			break;
1255		case (WMFW_ABSOLUTE << 8):
1256			/*
1257			 * Old files may use this for global
1258			 * coefficients.
1259			 */
1260			if (le32_to_cpu(blk->id) == dsp->fw_id &&
1261			    offset == 0) {
1262				region_name = "global coefficients";
1263				mem = wm_adsp_find_region(dsp, type);
1264				if (!mem) {
1265					adsp_err(dsp, "No ZM\n");
1266					break;
1267				}
1268				reg = wm_adsp_region_to_reg(mem, 0);
1269
1270			} else {
1271				region_name = "register";
1272				reg = offset;
1273			}
1274			break;
1275
1276		case WMFW_ADSP1_DM:
1277		case WMFW_ADSP1_ZM:
1278		case WMFW_ADSP2_XM:
1279		case WMFW_ADSP2_YM:
1280			adsp_dbg(dsp, "%s.%d: %d bytes in %x for %x\n",
1281				 file, blocks, le32_to_cpu(blk->len),
1282				 type, le32_to_cpu(blk->id));
1283
1284			mem = wm_adsp_find_region(dsp, type);
1285			if (!mem) {
1286				adsp_err(dsp, "No base for region %x\n", type);
1287				break;
1288			}
1289
1290			reg = 0;
1291			list_for_each_entry(alg_region,
1292					    &dsp->alg_regions, list) {
1293				if (le32_to_cpu(blk->id) == alg_region->alg &&
1294				    type == alg_region->type) {
1295					reg = alg_region->base;
1296					reg = wm_adsp_region_to_reg(mem,
1297								    reg);
1298					reg += offset;
1299					break;
1300				}
1301			}
1302
1303			if (reg == 0)
1304				adsp_err(dsp, "No %x for algorithm %x\n",
1305					 type, le32_to_cpu(blk->id));
1306			break;
1307
1308		default:
1309			adsp_err(dsp, "%s.%d: Unknown region type %x at %d\n",
1310				 file, blocks, type, pos);
1311			break;
1312		}
1313
1314		if (reg) {
1315			buf = wm_adsp_buf_alloc(blk->data,
1316						le32_to_cpu(blk->len),
1317						&buf_list);
1318			if (!buf) {
1319				adsp_err(dsp, "Out of memory\n");
1320				ret = -ENOMEM;
1321				goto out_fw;
1322			}
1323
1324			adsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n",
1325				 file, blocks, le32_to_cpu(blk->len),
1326				 reg);
1327			ret = regmap_raw_write_async(regmap, reg, buf->buf,
1328						     le32_to_cpu(blk->len));
1329			if (ret != 0) {
1330				adsp_err(dsp,
1331					"%s.%d: Failed to write to %x in %s: %d\n",
1332					file, blocks, reg, region_name, ret);
1333			}
1334		}
1335
1336		pos += (le32_to_cpu(blk->len) + sizeof(*blk) + 3) & ~0x03;
1337		blocks++;
1338	}
1339
1340	ret = regmap_async_complete(regmap);
1341	if (ret != 0)
1342		adsp_err(dsp, "Failed to complete async write: %d\n", ret);
1343
1344	if (pos > firmware->size)
1345		adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n",
1346			  file, blocks, pos - firmware->size);
1347
1348out_fw:
1349	regmap_async_complete(regmap);
1350	release_firmware(firmware);
1351	wm_adsp_buf_free(&buf_list);
1352out:
1353	kfree(file);
1354	return ret;
1355}
1356
1357int wm_adsp1_init(struct wm_adsp *adsp)
1358{
1359	INIT_LIST_HEAD(&adsp->alg_regions);
1360
1361	return 0;
1362}
1363EXPORT_SYMBOL_GPL(wm_adsp1_init);
1364
1365int wm_adsp1_event(struct snd_soc_dapm_widget *w,
1366		   struct snd_kcontrol *kcontrol,
1367		   int event)
1368{
1369	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1370	struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
1371	struct wm_adsp *dsp = &dsps[w->shift];
1372	struct wm_adsp_alg_region *alg_region;
1373	struct wm_coeff_ctl *ctl;
1374	int ret;
1375	int val;
1376
1377	dsp->card = codec->component.card;
1378
1379	switch (event) {
1380	case SND_SOC_DAPM_POST_PMU:
1381		regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
1382				   ADSP1_SYS_ENA, ADSP1_SYS_ENA);
1383
1384		/*
1385		 * For simplicity set the DSP clock rate to be the
1386		 * SYSCLK rate rather than making it configurable.
1387		 */
1388		if(dsp->sysclk_reg) {
1389			ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val);
1390			if (ret != 0) {
1391				adsp_err(dsp, "Failed to read SYSCLK state: %d\n",
1392				ret);
1393				return ret;
1394			}
1395
1396			val = (val & dsp->sysclk_mask)
1397				>> dsp->sysclk_shift;
1398
1399			ret = regmap_update_bits(dsp->regmap,
1400						 dsp->base + ADSP1_CONTROL_31,
1401						 ADSP1_CLK_SEL_MASK, val);
1402			if (ret != 0) {
1403				adsp_err(dsp, "Failed to set clock rate: %d\n",
1404					 ret);
1405				return ret;
1406			}
1407		}
1408
1409		ret = wm_adsp_load(dsp);
1410		if (ret != 0)
1411			goto err;
1412
1413		ret = wm_adsp_setup_algs(dsp);
1414		if (ret != 0)
1415			goto err;
1416
1417		ret = wm_adsp_load_coeff(dsp);
1418		if (ret != 0)
1419			goto err;
1420
1421		/* Initialize caches for enabled and unset controls */
1422		ret = wm_coeff_init_control_caches(dsp);
1423		if (ret != 0)
1424			goto err;
1425
1426		/* Sync set controls */
1427		ret = wm_coeff_sync_controls(dsp);
1428		if (ret != 0)
1429			goto err;
1430
1431		/* Start the core running */
1432		regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
1433				   ADSP1_CORE_ENA | ADSP1_START,
1434				   ADSP1_CORE_ENA | ADSP1_START);
1435		break;
1436
1437	case SND_SOC_DAPM_PRE_PMD:
1438		/* Halt the core */
1439		regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
1440				   ADSP1_CORE_ENA | ADSP1_START, 0);
1441
1442		regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_19,
1443				   ADSP1_WDMA_BUFFER_LENGTH_MASK, 0);
1444
1445		regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
1446				   ADSP1_SYS_ENA, 0);
1447
1448		list_for_each_entry(ctl, &dsp->ctl_list, list)
1449			ctl->enabled = 0;
1450
1451		while (!list_empty(&dsp->alg_regions)) {
1452			alg_region = list_first_entry(&dsp->alg_regions,
1453						      struct wm_adsp_alg_region,
1454						      list);
1455			list_del(&alg_region->list);
1456			kfree(alg_region);
1457		}
1458		break;
1459
1460	default:
1461		break;
1462	}
1463
1464	return 0;
1465
1466err:
1467	regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
1468			   ADSP1_SYS_ENA, 0);
1469	return ret;
1470}
1471EXPORT_SYMBOL_GPL(wm_adsp1_event);
1472
1473static int wm_adsp2_ena(struct wm_adsp *dsp)
1474{
1475	unsigned int val;
1476	int ret, count;
1477
1478	ret = regmap_update_bits_async(dsp->regmap, dsp->base + ADSP2_CONTROL,
1479				       ADSP2_SYS_ENA, ADSP2_SYS_ENA);
1480	if (ret != 0)
1481		return ret;
1482
1483	/* Wait for the RAM to start, should be near instantaneous */
1484	for (count = 0; count < 10; ++count) {
1485		ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1,
1486				  &val);
1487		if (ret != 0)
1488			return ret;
1489
1490		if (val & ADSP2_RAM_RDY)
1491			break;
1492
1493		msleep(1);
1494	}
1495
1496	if (!(val & ADSP2_RAM_RDY)) {
1497		adsp_err(dsp, "Failed to start DSP RAM\n");
1498		return -EBUSY;
1499	}
1500
1501	adsp_dbg(dsp, "RAM ready after %d polls\n", count);
1502
1503	return 0;
1504}
1505
1506static void wm_adsp2_boot_work(struct work_struct *work)
1507{
1508	struct wm_adsp *dsp = container_of(work,
1509					   struct wm_adsp,
1510					   boot_work);
1511	int ret;
1512	unsigned int val;
1513
1514	/*
1515	 * For simplicity set the DSP clock rate to be the
1516	 * SYSCLK rate rather than making it configurable.
1517	 */
1518	ret = regmap_read(dsp->regmap, ARIZONA_SYSTEM_CLOCK_1, &val);
1519	if (ret != 0) {
1520		adsp_err(dsp, "Failed to read SYSCLK state: %d\n", ret);
1521		return;
1522	}
1523	val = (val & ARIZONA_SYSCLK_FREQ_MASK)
1524		>> ARIZONA_SYSCLK_FREQ_SHIFT;
1525
1526	ret = regmap_update_bits_async(dsp->regmap,
1527				       dsp->base + ADSP2_CLOCKING,
1528				       ADSP2_CLK_SEL_MASK, val);
1529	if (ret != 0) {
1530		adsp_err(dsp, "Failed to set clock rate: %d\n", ret);
1531		return;
1532	}
1533
1534	if (dsp->dvfs) {
1535		ret = regmap_read(dsp->regmap,
1536				  dsp->base + ADSP2_CLOCKING, &val);
1537		if (ret != 0) {
1538			adsp_err(dsp, "Failed to read clocking: %d\n", ret);
1539			return;
1540		}
1541
1542		if ((val & ADSP2_CLK_SEL_MASK) >= 3) {
1543			ret = regulator_enable(dsp->dvfs);
1544			if (ret != 0) {
1545				adsp_err(dsp,
1546					 "Failed to enable supply: %d\n",
1547					 ret);
1548				return;
1549			}
1550
1551			ret = regulator_set_voltage(dsp->dvfs,
1552						    1800000,
1553						    1800000);
1554			if (ret != 0) {
1555				adsp_err(dsp,
1556					 "Failed to raise supply: %d\n",
1557					 ret);
1558				return;
1559			}
1560		}
1561	}
1562
1563	ret = wm_adsp2_ena(dsp);
1564	if (ret != 0)
1565		return;
1566
1567	ret = wm_adsp_load(dsp);
1568	if (ret != 0)
1569		goto err;
1570
1571	ret = wm_adsp_setup_algs(dsp);
1572	if (ret != 0)
1573		goto err;
1574
1575	ret = wm_adsp_load_coeff(dsp);
1576	if (ret != 0)
1577		goto err;
1578
1579	/* Initialize caches for enabled and unset controls */
1580	ret = wm_coeff_init_control_caches(dsp);
1581	if (ret != 0)
1582		goto err;
1583
1584	/* Sync set controls */
1585	ret = wm_coeff_sync_controls(dsp);
1586	if (ret != 0)
1587		goto err;
1588
1589	dsp->running = true;
1590
1591	return;
1592
1593err:
1594	regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
1595			   ADSP2_SYS_ENA | ADSP2_CORE_ENA | ADSP2_START, 0);
1596}
1597
1598int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
1599		   struct snd_kcontrol *kcontrol, int event)
1600{
1601	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1602	struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
1603	struct wm_adsp *dsp = &dsps[w->shift];
1604
1605	dsp->card = codec->component.card;
1606
1607	switch (event) {
1608	case SND_SOC_DAPM_PRE_PMU:
1609		queue_work(system_unbound_wq, &dsp->boot_work);
1610		break;
1611	default:
1612		break;
1613	}
1614
1615	return 0;
1616}
1617EXPORT_SYMBOL_GPL(wm_adsp2_early_event);
1618
1619int wm_adsp2_event(struct snd_soc_dapm_widget *w,
1620		   struct snd_kcontrol *kcontrol, int event)
1621{
1622	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1623	struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
1624	struct wm_adsp *dsp = &dsps[w->shift];
1625	struct wm_adsp_alg_region *alg_region;
1626	struct wm_coeff_ctl *ctl;
1627	int ret;
1628
1629	switch (event) {
1630	case SND_SOC_DAPM_POST_PMU:
1631		flush_work(&dsp->boot_work);
1632
1633		if (!dsp->running)
1634			return -EIO;
1635
1636		ret = regmap_update_bits(dsp->regmap,
1637					 dsp->base + ADSP2_CONTROL,
1638					 ADSP2_CORE_ENA | ADSP2_START,
1639					 ADSP2_CORE_ENA | ADSP2_START);
1640		if (ret != 0)
1641			goto err;
1642		break;
1643
1644	case SND_SOC_DAPM_PRE_PMD:
1645		dsp->running = false;
1646
1647		regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
1648				   ADSP2_SYS_ENA | ADSP2_CORE_ENA |
1649				   ADSP2_START, 0);
1650
1651		/* Make sure DMAs are quiesced */
1652		regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0);
1653		regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_2, 0);
1654		regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0);
1655
1656		if (dsp->dvfs) {
1657			ret = regulator_set_voltage(dsp->dvfs, 1200000,
1658						    1800000);
1659			if (ret != 0)
1660				adsp_warn(dsp,
1661					  "Failed to lower supply: %d\n",
1662					  ret);
1663
1664			ret = regulator_disable(dsp->dvfs);
1665			if (ret != 0)
1666				adsp_err(dsp,
1667					 "Failed to enable supply: %d\n",
1668					 ret);
1669		}
1670
1671		list_for_each_entry(ctl, &dsp->ctl_list, list)
1672			ctl->enabled = 0;
1673
1674		while (!list_empty(&dsp->alg_regions)) {
1675			alg_region = list_first_entry(&dsp->alg_regions,
1676						      struct wm_adsp_alg_region,
1677						      list);
1678			list_del(&alg_region->list);
1679			kfree(alg_region);
1680		}
1681
1682		adsp_dbg(dsp, "Shutdown complete\n");
1683		break;
1684
1685	default:
1686		break;
1687	}
1688
1689	return 0;
1690err:
1691	regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
1692			   ADSP2_SYS_ENA | ADSP2_CORE_ENA | ADSP2_START, 0);
1693	return ret;
1694}
1695EXPORT_SYMBOL_GPL(wm_adsp2_event);
1696
1697int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs)
1698{
1699	int ret;
1700
1701	/*
1702	 * Disable the DSP memory by default when in reset for a small
1703	 * power saving.
1704	 */
1705	ret = regmap_update_bits(adsp->regmap, adsp->base + ADSP2_CONTROL,
1706				 ADSP2_MEM_ENA, 0);
1707	if (ret != 0) {
1708		adsp_err(adsp, "Failed to clear memory retention: %d\n", ret);
1709		return ret;
1710	}
1711
1712	INIT_LIST_HEAD(&adsp->alg_regions);
1713	INIT_LIST_HEAD(&adsp->ctl_list);
1714	INIT_WORK(&adsp->boot_work, wm_adsp2_boot_work);
1715
1716	if (dvfs) {
1717		adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD");
1718		if (IS_ERR(adsp->dvfs)) {
1719			ret = PTR_ERR(adsp->dvfs);
1720			adsp_err(adsp, "Failed to get DCVDD: %d\n", ret);
1721			return ret;
1722		}
1723
1724		ret = regulator_enable(adsp->dvfs);
1725		if (ret != 0) {
1726			adsp_err(adsp, "Failed to enable DCVDD: %d\n", ret);
1727			return ret;
1728		}
1729
1730		ret = regulator_set_voltage(adsp->dvfs, 1200000, 1800000);
1731		if (ret != 0) {
1732			adsp_err(adsp, "Failed to initialise DVFS: %d\n", ret);
1733			return ret;
1734		}
1735
1736		ret = regulator_disable(adsp->dvfs);
1737		if (ret != 0) {
1738			adsp_err(adsp, "Failed to disable DCVDD: %d\n", ret);
1739			return ret;
1740		}
1741	}
1742
1743	return 0;
1744}
1745EXPORT_SYMBOL_GPL(wm_adsp2_init);
1746
1747MODULE_LICENSE("GPL v2");
1748