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