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