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 if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) 903 ret = -EPERM; 904 else 905 memcpy(ctl->cache, p, ctl->len); 906 907 ctl->set = 1; 908 if (ctl->enabled && ctl->dsp->running) 909 ret = wm_coeff_write_control(ctl, p, ctl->len); 910 911 mutex_unlock(&ctl->dsp->pwr_lock); 912 913 return ret; 914 } 915 916 static int wm_coeff_tlv_put(struct snd_kcontrol *kctl, 917 const unsigned int __user *bytes, unsigned int size) 918 { 919 struct soc_bytes_ext *bytes_ext = 920 (struct soc_bytes_ext *)kctl->private_value; 921 struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); 922 int ret = 0; 923 924 mutex_lock(&ctl->dsp->pwr_lock); 925 926 if (copy_from_user(ctl->cache, bytes, size)) { 927 ret = -EFAULT; 928 } else { 929 ctl->set = 1; 930 if (ctl->enabled && ctl->dsp->running) 931 ret = wm_coeff_write_control(ctl, ctl->cache, size); 932 else if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) 933 ret = -EPERM; 934 } 935 936 mutex_unlock(&ctl->dsp->pwr_lock); 937 938 return ret; 939 } 940 941 static int wm_coeff_put_acked(struct snd_kcontrol *kctl, 942 struct snd_ctl_elem_value *ucontrol) 943 { 944 struct soc_bytes_ext *bytes_ext = 945 (struct soc_bytes_ext *)kctl->private_value; 946 struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); 947 unsigned int val = ucontrol->value.integer.value[0]; 948 int ret; 949 950 if (val == 0) 951 return 0; /* 0 means no event */ 952 953 mutex_lock(&ctl->dsp->pwr_lock); 954 955 if (ctl->enabled && ctl->dsp->running) 956 ret = wm_coeff_write_acked_control(ctl, val); 957 else 958 ret = -EPERM; 959 960 mutex_unlock(&ctl->dsp->pwr_lock); 961 962 return ret; 963 } 964 965 static int wm_coeff_read_control(struct wm_coeff_ctl *ctl, 966 void *buf, size_t len) 967 { 968 struct wm_adsp *dsp = ctl->dsp; 969 void *scratch; 970 int ret; 971 unsigned int reg; 972 973 ret = wm_coeff_base_reg(ctl, ®); 974 if (ret) 975 return ret; 976 977 scratch = kmalloc(len, GFP_KERNEL | GFP_DMA); 978 if (!scratch) 979 return -ENOMEM; 980 981 ret = regmap_raw_read(dsp->regmap, reg, scratch, len); 982 if (ret) { 983 adsp_err(dsp, "Failed to read %zu bytes from %x: %d\n", 984 len, reg, ret); 985 kfree(scratch); 986 return ret; 987 } 988 adsp_dbg(dsp, "Read %zu bytes from %x\n", len, reg); 989 990 memcpy(buf, scratch, len); 991 kfree(scratch); 992 993 return 0; 994 } 995 996 static int wm_coeff_get(struct snd_kcontrol *kctl, 997 struct snd_ctl_elem_value *ucontrol) 998 { 999 struct soc_bytes_ext *bytes_ext = 1000 (struct soc_bytes_ext *)kctl->private_value; 1001 struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); 1002 char *p = ucontrol->value.bytes.data; 1003 int ret = 0; 1004 1005 mutex_lock(&ctl->dsp->pwr_lock); 1006 1007 if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { 1008 if (ctl->enabled && ctl->dsp->running) 1009 ret = wm_coeff_read_control(ctl, p, ctl->len); 1010 else 1011 ret = -EPERM; 1012 } else { 1013 if (!ctl->flags && ctl->enabled && ctl->dsp->running) 1014 ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len); 1015 1016 memcpy(p, ctl->cache, ctl->len); 1017 } 1018 1019 mutex_unlock(&ctl->dsp->pwr_lock); 1020 1021 return ret; 1022 } 1023 1024 static int wm_coeff_tlv_get(struct snd_kcontrol *kctl, 1025 unsigned int __user *bytes, unsigned int size) 1026 { 1027 struct soc_bytes_ext *bytes_ext = 1028 (struct soc_bytes_ext *)kctl->private_value; 1029 struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); 1030 int ret = 0; 1031 1032 mutex_lock(&ctl->dsp->pwr_lock); 1033 1034 if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { 1035 if (ctl->enabled && ctl->dsp->running) 1036 ret = wm_coeff_read_control(ctl, ctl->cache, size); 1037 else 1038 ret = -EPERM; 1039 } else { 1040 if (!ctl->flags && ctl->enabled && ctl->dsp->running) 1041 ret = wm_coeff_read_control(ctl, ctl->cache, size); 1042 } 1043 1044 if (!ret && copy_to_user(bytes, ctl->cache, size)) 1045 ret = -EFAULT; 1046 1047 mutex_unlock(&ctl->dsp->pwr_lock); 1048 1049 return ret; 1050 } 1051 1052 static int wm_coeff_get_acked(struct snd_kcontrol *kcontrol, 1053 struct snd_ctl_elem_value *ucontrol) 1054 { 1055 /* 1056 * Although it's not useful to read an acked control, we must satisfy 1057 * user-side assumptions that all controls are readable and that a 1058 * write of the same value should be filtered out (it's valid to send 1059 * the same event number again to the firmware). We therefore return 0, 1060 * meaning "no event" so valid event numbers will always be a change 1061 */ 1062 ucontrol->value.integer.value[0] = 0; 1063 1064 return 0; 1065 } 1066 1067 struct wmfw_ctl_work { 1068 struct wm_adsp *dsp; 1069 struct wm_coeff_ctl *ctl; 1070 struct work_struct work; 1071 }; 1072 1073 static unsigned int wmfw_convert_flags(unsigned int in, unsigned int len) 1074 { 1075 unsigned int out, rd, wr, vol; 1076 1077 if (len > ADSP_MAX_STD_CTRL_SIZE) { 1078 rd = SNDRV_CTL_ELEM_ACCESS_TLV_READ; 1079 wr = SNDRV_CTL_ELEM_ACCESS_TLV_WRITE; 1080 vol = SNDRV_CTL_ELEM_ACCESS_VOLATILE; 1081 1082 out = SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; 1083 } else { 1084 rd = SNDRV_CTL_ELEM_ACCESS_READ; 1085 wr = SNDRV_CTL_ELEM_ACCESS_WRITE; 1086 vol = SNDRV_CTL_ELEM_ACCESS_VOLATILE; 1087 1088 out = 0; 1089 } 1090 1091 if (in) { 1092 if (in & WMFW_CTL_FLAG_READABLE) 1093 out |= rd; 1094 if (in & WMFW_CTL_FLAG_WRITEABLE) 1095 out |= wr; 1096 if (in & WMFW_CTL_FLAG_VOLATILE) 1097 out |= vol; 1098 } else { 1099 out |= rd | wr | vol; 1100 } 1101 1102 return out; 1103 } 1104 1105 static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl) 1106 { 1107 struct snd_kcontrol_new *kcontrol; 1108 int ret; 1109 1110 if (!ctl || !ctl->name) 1111 return -EINVAL; 1112 1113 kcontrol = kzalloc(sizeof(*kcontrol), GFP_KERNEL); 1114 if (!kcontrol) 1115 return -ENOMEM; 1116 1117 kcontrol->name = ctl->name; 1118 kcontrol->info = wm_coeff_info; 1119 kcontrol->iface = SNDRV_CTL_ELEM_IFACE_MIXER; 1120 kcontrol->tlv.c = snd_soc_bytes_tlv_callback; 1121 kcontrol->private_value = (unsigned long)&ctl->bytes_ext; 1122 kcontrol->access = wmfw_convert_flags(ctl->flags, ctl->len); 1123 1124 switch (ctl->type) { 1125 case WMFW_CTL_TYPE_ACKED: 1126 kcontrol->get = wm_coeff_get_acked; 1127 kcontrol->put = wm_coeff_put_acked; 1128 break; 1129 default: 1130 kcontrol->get = wm_coeff_get; 1131 kcontrol->put = wm_coeff_put; 1132 1133 ctl->bytes_ext.max = ctl->len; 1134 ctl->bytes_ext.get = wm_coeff_tlv_get; 1135 ctl->bytes_ext.put = wm_coeff_tlv_put; 1136 break; 1137 } 1138 1139 ret = snd_soc_add_codec_controls(dsp->codec, kcontrol, 1); 1140 if (ret < 0) 1141 goto err_kcontrol; 1142 1143 kfree(kcontrol); 1144 1145 return 0; 1146 1147 err_kcontrol: 1148 kfree(kcontrol); 1149 return ret; 1150 } 1151 1152 static int wm_coeff_init_control_caches(struct wm_adsp *dsp) 1153 { 1154 struct wm_coeff_ctl *ctl; 1155 int ret; 1156 1157 list_for_each_entry(ctl, &dsp->ctl_list, list) { 1158 if (!ctl->enabled || ctl->set) 1159 continue; 1160 if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) 1161 continue; 1162 1163 ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len); 1164 if (ret < 0) 1165 return ret; 1166 } 1167 1168 return 0; 1169 } 1170 1171 static int wm_coeff_sync_controls(struct wm_adsp *dsp) 1172 { 1173 struct wm_coeff_ctl *ctl; 1174 int ret; 1175 1176 list_for_each_entry(ctl, &dsp->ctl_list, list) { 1177 if (!ctl->enabled) 1178 continue; 1179 if (ctl->set && !(ctl->flags & WMFW_CTL_FLAG_VOLATILE)) { 1180 ret = wm_coeff_write_control(ctl, ctl->cache, ctl->len); 1181 if (ret < 0) 1182 return ret; 1183 } 1184 } 1185 1186 return 0; 1187 } 1188 1189 static void wm_adsp_signal_event_controls(struct wm_adsp *dsp, 1190 unsigned int event) 1191 { 1192 struct wm_coeff_ctl *ctl; 1193 int ret; 1194 1195 list_for_each_entry(ctl, &dsp->ctl_list, list) { 1196 if (ctl->type != WMFW_CTL_TYPE_HOSTEVENT) 1197 continue; 1198 1199 if (!ctl->enabled) 1200 continue; 1201 1202 ret = wm_coeff_write_acked_control(ctl, event); 1203 if (ret) 1204 adsp_warn(dsp, 1205 "Failed to send 0x%x event to alg 0x%x (%d)\n", 1206 event, ctl->alg_region.alg, ret); 1207 } 1208 } 1209 1210 static void wm_adsp_ctl_work(struct work_struct *work) 1211 { 1212 struct wmfw_ctl_work *ctl_work = container_of(work, 1213 struct wmfw_ctl_work, 1214 work); 1215 1216 wmfw_add_ctl(ctl_work->dsp, ctl_work->ctl); 1217 kfree(ctl_work); 1218 } 1219 1220 static void wm_adsp_free_ctl_blk(struct wm_coeff_ctl *ctl) 1221 { 1222 kfree(ctl->cache); 1223 kfree(ctl->name); 1224 kfree(ctl); 1225 } 1226 1227 static int wm_adsp_create_control(struct wm_adsp *dsp, 1228 const struct wm_adsp_alg_region *alg_region, 1229 unsigned int offset, unsigned int len, 1230 const char *subname, unsigned int subname_len, 1231 unsigned int flags, unsigned int type) 1232 { 1233 struct wm_coeff_ctl *ctl; 1234 struct wmfw_ctl_work *ctl_work; 1235 char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; 1236 const char *region_name; 1237 int ret; 1238 1239 region_name = wm_adsp_mem_region_name(alg_region->type); 1240 if (!region_name) { 1241 adsp_err(dsp, "Unknown region type: %d\n", alg_region->type); 1242 return -EINVAL; 1243 } 1244 1245 switch (dsp->fw_ver) { 1246 case 0: 1247 case 1: 1248 snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "DSP%d %s %x", 1249 dsp->num, region_name, alg_region->alg); 1250 break; 1251 default: 1252 ret = snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, 1253 "DSP%d%c %.12s %x", dsp->num, *region_name, 1254 wm_adsp_fw_text[dsp->fw], alg_region->alg); 1255 1256 /* Truncate the subname from the start if it is too long */ 1257 if (subname) { 1258 int avail = SNDRV_CTL_ELEM_ID_NAME_MAXLEN - ret - 2; 1259 int skip = 0; 1260 1261 if (subname_len > avail) 1262 skip = subname_len - avail; 1263 1264 snprintf(name + ret, 1265 SNDRV_CTL_ELEM_ID_NAME_MAXLEN - ret, " %.*s", 1266 subname_len - skip, subname + skip); 1267 } 1268 break; 1269 } 1270 1271 list_for_each_entry(ctl, &dsp->ctl_list, list) { 1272 if (!strcmp(ctl->name, name)) { 1273 if (!ctl->enabled) 1274 ctl->enabled = 1; 1275 return 0; 1276 } 1277 } 1278 1279 ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); 1280 if (!ctl) 1281 return -ENOMEM; 1282 ctl->fw_name = wm_adsp_fw_text[dsp->fw]; 1283 ctl->alg_region = *alg_region; 1284 ctl->name = kmemdup(name, strlen(name) + 1, GFP_KERNEL); 1285 if (!ctl->name) { 1286 ret = -ENOMEM; 1287 goto err_ctl; 1288 } 1289 ctl->enabled = 1; 1290 ctl->set = 0; 1291 ctl->ops.xget = wm_coeff_get; 1292 ctl->ops.xput = wm_coeff_put; 1293 ctl->dsp = dsp; 1294 1295 ctl->flags = flags; 1296 ctl->type = type; 1297 ctl->offset = offset; 1298 ctl->len = len; 1299 ctl->cache = kzalloc(ctl->len, GFP_KERNEL); 1300 if (!ctl->cache) { 1301 ret = -ENOMEM; 1302 goto err_ctl_name; 1303 } 1304 1305 list_add(&ctl->list, &dsp->ctl_list); 1306 1307 if (flags & WMFW_CTL_FLAG_SYS) 1308 return 0; 1309 1310 ctl_work = kzalloc(sizeof(*ctl_work), GFP_KERNEL); 1311 if (!ctl_work) { 1312 ret = -ENOMEM; 1313 goto err_ctl_cache; 1314 } 1315 1316 ctl_work->dsp = dsp; 1317 ctl_work->ctl = ctl; 1318 INIT_WORK(&ctl_work->work, wm_adsp_ctl_work); 1319 schedule_work(&ctl_work->work); 1320 1321 return 0; 1322 1323 err_ctl_cache: 1324 kfree(ctl->cache); 1325 err_ctl_name: 1326 kfree(ctl->name); 1327 err_ctl: 1328 kfree(ctl); 1329 1330 return ret; 1331 } 1332 1333 struct wm_coeff_parsed_alg { 1334 int id; 1335 const u8 *name; 1336 int name_len; 1337 int ncoeff; 1338 }; 1339 1340 struct wm_coeff_parsed_coeff { 1341 int offset; 1342 int mem_type; 1343 const u8 *name; 1344 int name_len; 1345 int ctl_type; 1346 int flags; 1347 int len; 1348 }; 1349 1350 static int wm_coeff_parse_string(int bytes, const u8 **pos, const u8 **str) 1351 { 1352 int length; 1353 1354 switch (bytes) { 1355 case 1: 1356 length = **pos; 1357 break; 1358 case 2: 1359 length = le16_to_cpu(*((__le16 *)*pos)); 1360 break; 1361 default: 1362 return 0; 1363 } 1364 1365 if (str) 1366 *str = *pos + bytes; 1367 1368 *pos += ((length + bytes) + 3) & ~0x03; 1369 1370 return length; 1371 } 1372 1373 static int wm_coeff_parse_int(int bytes, const u8 **pos) 1374 { 1375 int val = 0; 1376 1377 switch (bytes) { 1378 case 2: 1379 val = le16_to_cpu(*((__le16 *)*pos)); 1380 break; 1381 case 4: 1382 val = le32_to_cpu(*((__le32 *)*pos)); 1383 break; 1384 default: 1385 break; 1386 } 1387 1388 *pos += bytes; 1389 1390 return val; 1391 } 1392 1393 static inline void wm_coeff_parse_alg(struct wm_adsp *dsp, const u8 **data, 1394 struct wm_coeff_parsed_alg *blk) 1395 { 1396 const struct wmfw_adsp_alg_data *raw; 1397 1398 switch (dsp->fw_ver) { 1399 case 0: 1400 case 1: 1401 raw = (const struct wmfw_adsp_alg_data *)*data; 1402 *data = raw->data; 1403 1404 blk->id = le32_to_cpu(raw->id); 1405 blk->name = raw->name; 1406 blk->name_len = strlen(raw->name); 1407 blk->ncoeff = le32_to_cpu(raw->ncoeff); 1408 break; 1409 default: 1410 blk->id = wm_coeff_parse_int(sizeof(raw->id), data); 1411 blk->name_len = wm_coeff_parse_string(sizeof(u8), data, 1412 &blk->name); 1413 wm_coeff_parse_string(sizeof(u16), data, NULL); 1414 blk->ncoeff = wm_coeff_parse_int(sizeof(raw->ncoeff), data); 1415 break; 1416 } 1417 1418 adsp_dbg(dsp, "Algorithm ID: %#x\n", blk->id); 1419 adsp_dbg(dsp, "Algorithm name: %.*s\n", blk->name_len, blk->name); 1420 adsp_dbg(dsp, "# of coefficient descriptors: %#x\n", blk->ncoeff); 1421 } 1422 1423 static inline void wm_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data, 1424 struct wm_coeff_parsed_coeff *blk) 1425 { 1426 const struct wmfw_adsp_coeff_data *raw; 1427 const u8 *tmp; 1428 int length; 1429 1430 switch (dsp->fw_ver) { 1431 case 0: 1432 case 1: 1433 raw = (const struct wmfw_adsp_coeff_data *)*data; 1434 *data = *data + sizeof(raw->hdr) + le32_to_cpu(raw->hdr.size); 1435 1436 blk->offset = le16_to_cpu(raw->hdr.offset); 1437 blk->mem_type = le16_to_cpu(raw->hdr.type); 1438 blk->name = raw->name; 1439 blk->name_len = strlen(raw->name); 1440 blk->ctl_type = le16_to_cpu(raw->ctl_type); 1441 blk->flags = le16_to_cpu(raw->flags); 1442 blk->len = le32_to_cpu(raw->len); 1443 break; 1444 default: 1445 tmp = *data; 1446 blk->offset = wm_coeff_parse_int(sizeof(raw->hdr.offset), &tmp); 1447 blk->mem_type = wm_coeff_parse_int(sizeof(raw->hdr.type), &tmp); 1448 length = wm_coeff_parse_int(sizeof(raw->hdr.size), &tmp); 1449 blk->name_len = wm_coeff_parse_string(sizeof(u8), &tmp, 1450 &blk->name); 1451 wm_coeff_parse_string(sizeof(u8), &tmp, NULL); 1452 wm_coeff_parse_string(sizeof(u16), &tmp, NULL); 1453 blk->ctl_type = wm_coeff_parse_int(sizeof(raw->ctl_type), &tmp); 1454 blk->flags = wm_coeff_parse_int(sizeof(raw->flags), &tmp); 1455 blk->len = wm_coeff_parse_int(sizeof(raw->len), &tmp); 1456 1457 *data = *data + sizeof(raw->hdr) + length; 1458 break; 1459 } 1460 1461 adsp_dbg(dsp, "\tCoefficient type: %#x\n", blk->mem_type); 1462 adsp_dbg(dsp, "\tCoefficient offset: %#x\n", blk->offset); 1463 adsp_dbg(dsp, "\tCoefficient name: %.*s\n", blk->name_len, blk->name); 1464 adsp_dbg(dsp, "\tCoefficient flags: %#x\n", blk->flags); 1465 adsp_dbg(dsp, "\tALSA control type: %#x\n", blk->ctl_type); 1466 adsp_dbg(dsp, "\tALSA control len: %#x\n", blk->len); 1467 } 1468 1469 static int wm_adsp_check_coeff_flags(struct wm_adsp *dsp, 1470 const struct wm_coeff_parsed_coeff *coeff_blk, 1471 unsigned int f_required, 1472 unsigned int f_illegal) 1473 { 1474 if ((coeff_blk->flags & f_illegal) || 1475 ((coeff_blk->flags & f_required) != f_required)) { 1476 adsp_err(dsp, "Illegal flags 0x%x for control type 0x%x\n", 1477 coeff_blk->flags, coeff_blk->ctl_type); 1478 return -EINVAL; 1479 } 1480 1481 return 0; 1482 } 1483 1484 static int wm_adsp_parse_coeff(struct wm_adsp *dsp, 1485 const struct wmfw_region *region) 1486 { 1487 struct wm_adsp_alg_region alg_region = {}; 1488 struct wm_coeff_parsed_alg alg_blk; 1489 struct wm_coeff_parsed_coeff coeff_blk; 1490 const u8 *data = region->data; 1491 int i, ret; 1492 1493 wm_coeff_parse_alg(dsp, &data, &alg_blk); 1494 for (i = 0; i < alg_blk.ncoeff; i++) { 1495 wm_coeff_parse_coeff(dsp, &data, &coeff_blk); 1496 1497 switch (coeff_blk.ctl_type) { 1498 case SNDRV_CTL_ELEM_TYPE_BYTES: 1499 break; 1500 case WMFW_CTL_TYPE_ACKED: 1501 if (coeff_blk.flags & WMFW_CTL_FLAG_SYS) 1502 continue; /* ignore */ 1503 1504 ret = wm_adsp_check_coeff_flags(dsp, &coeff_blk, 1505 WMFW_CTL_FLAG_VOLATILE | 1506 WMFW_CTL_FLAG_WRITEABLE | 1507 WMFW_CTL_FLAG_READABLE, 1508 0); 1509 if (ret) 1510 return -EINVAL; 1511 break; 1512 case WMFW_CTL_TYPE_HOSTEVENT: 1513 ret = wm_adsp_check_coeff_flags(dsp, &coeff_blk, 1514 WMFW_CTL_FLAG_SYS | 1515 WMFW_CTL_FLAG_VOLATILE | 1516 WMFW_CTL_FLAG_WRITEABLE | 1517 WMFW_CTL_FLAG_READABLE, 1518 0); 1519 if (ret) 1520 return -EINVAL; 1521 break; 1522 default: 1523 adsp_err(dsp, "Unknown control type: %d\n", 1524 coeff_blk.ctl_type); 1525 return -EINVAL; 1526 } 1527 1528 alg_region.type = coeff_blk.mem_type; 1529 alg_region.alg = alg_blk.id; 1530 1531 ret = wm_adsp_create_control(dsp, &alg_region, 1532 coeff_blk.offset, 1533 coeff_blk.len, 1534 coeff_blk.name, 1535 coeff_blk.name_len, 1536 coeff_blk.flags, 1537 coeff_blk.ctl_type); 1538 if (ret < 0) 1539 adsp_err(dsp, "Failed to create control: %.*s, %d\n", 1540 coeff_blk.name_len, coeff_blk.name, ret); 1541 } 1542 1543 return 0; 1544 } 1545 1546 static int wm_adsp_load(struct wm_adsp *dsp) 1547 { 1548 LIST_HEAD(buf_list); 1549 const struct firmware *firmware; 1550 struct regmap *regmap = dsp->regmap; 1551 unsigned int pos = 0; 1552 const struct wmfw_header *header; 1553 const struct wmfw_adsp1_sizes *adsp1_sizes; 1554 const struct wmfw_adsp2_sizes *adsp2_sizes; 1555 const struct wmfw_footer *footer; 1556 const struct wmfw_region *region; 1557 const struct wm_adsp_region *mem; 1558 const char *region_name; 1559 char *file, *text = NULL; 1560 struct wm_adsp_buf *buf; 1561 unsigned int reg; 1562 int regions = 0; 1563 int ret, offset, type, sizes; 1564 1565 file = kzalloc(PAGE_SIZE, GFP_KERNEL); 1566 if (file == NULL) 1567 return -ENOMEM; 1568 1569 snprintf(file, PAGE_SIZE, "%s-dsp%d-%s.wmfw", dsp->part, dsp->num, 1570 wm_adsp_fw[dsp->fw].file); 1571 file[PAGE_SIZE - 1] = '\0'; 1572 1573 ret = request_firmware(&firmware, file, dsp->dev); 1574 if (ret != 0) { 1575 adsp_err(dsp, "Failed to request '%s'\n", file); 1576 goto out; 1577 } 1578 ret = -EINVAL; 1579 1580 pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer); 1581 if (pos >= firmware->size) { 1582 adsp_err(dsp, "%s: file too short, %zu bytes\n", 1583 file, firmware->size); 1584 goto out_fw; 1585 } 1586 1587 header = (void *)&firmware->data[0]; 1588 1589 if (memcmp(&header->magic[0], "WMFW", 4) != 0) { 1590 adsp_err(dsp, "%s: invalid magic\n", file); 1591 goto out_fw; 1592 } 1593 1594 switch (header->ver) { 1595 case 0: 1596 adsp_warn(dsp, "%s: Depreciated file format %d\n", 1597 file, header->ver); 1598 break; 1599 case 1: 1600 case 2: 1601 break; 1602 default: 1603 adsp_err(dsp, "%s: unknown file format %d\n", 1604 file, header->ver); 1605 goto out_fw; 1606 } 1607 1608 adsp_info(dsp, "Firmware version: %d\n", header->ver); 1609 dsp->fw_ver = header->ver; 1610 1611 if (header->core != dsp->type) { 1612 adsp_err(dsp, "%s: invalid core %d != %d\n", 1613 file, header->core, dsp->type); 1614 goto out_fw; 1615 } 1616 1617 switch (dsp->type) { 1618 case WMFW_ADSP1: 1619 pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer); 1620 adsp1_sizes = (void *)&(header[1]); 1621 footer = (void *)&(adsp1_sizes[1]); 1622 sizes = sizeof(*adsp1_sizes); 1623 1624 adsp_dbg(dsp, "%s: %d DM, %d PM, %d ZM\n", 1625 file, le32_to_cpu(adsp1_sizes->dm), 1626 le32_to_cpu(adsp1_sizes->pm), 1627 le32_to_cpu(adsp1_sizes->zm)); 1628 break; 1629 1630 case WMFW_ADSP2: 1631 pos = sizeof(*header) + sizeof(*adsp2_sizes) + sizeof(*footer); 1632 adsp2_sizes = (void *)&(header[1]); 1633 footer = (void *)&(adsp2_sizes[1]); 1634 sizes = sizeof(*adsp2_sizes); 1635 1636 adsp_dbg(dsp, "%s: %d XM, %d YM %d PM, %d ZM\n", 1637 file, le32_to_cpu(adsp2_sizes->xm), 1638 le32_to_cpu(adsp2_sizes->ym), 1639 le32_to_cpu(adsp2_sizes->pm), 1640 le32_to_cpu(adsp2_sizes->zm)); 1641 break; 1642 1643 default: 1644 WARN(1, "Unknown DSP type"); 1645 goto out_fw; 1646 } 1647 1648 if (le32_to_cpu(header->len) != sizeof(*header) + 1649 sizes + sizeof(*footer)) { 1650 adsp_err(dsp, "%s: unexpected header length %d\n", 1651 file, le32_to_cpu(header->len)); 1652 goto out_fw; 1653 } 1654 1655 adsp_dbg(dsp, "%s: timestamp %llu\n", file, 1656 le64_to_cpu(footer->timestamp)); 1657 1658 while (pos < firmware->size && 1659 pos - firmware->size > sizeof(*region)) { 1660 region = (void *)&(firmware->data[pos]); 1661 region_name = "Unknown"; 1662 reg = 0; 1663 text = NULL; 1664 offset = le32_to_cpu(region->offset) & 0xffffff; 1665 type = be32_to_cpu(region->type) & 0xff; 1666 mem = wm_adsp_find_region(dsp, type); 1667 1668 switch (type) { 1669 case WMFW_NAME_TEXT: 1670 region_name = "Firmware name"; 1671 text = kzalloc(le32_to_cpu(region->len) + 1, 1672 GFP_KERNEL); 1673 break; 1674 case WMFW_ALGORITHM_DATA: 1675 region_name = "Algorithm"; 1676 ret = wm_adsp_parse_coeff(dsp, region); 1677 if (ret != 0) 1678 goto out_fw; 1679 break; 1680 case WMFW_INFO_TEXT: 1681 region_name = "Information"; 1682 text = kzalloc(le32_to_cpu(region->len) + 1, 1683 GFP_KERNEL); 1684 break; 1685 case WMFW_ABSOLUTE: 1686 region_name = "Absolute"; 1687 reg = offset; 1688 break; 1689 case WMFW_ADSP1_PM: 1690 case WMFW_ADSP1_DM: 1691 case WMFW_ADSP2_XM: 1692 case WMFW_ADSP2_YM: 1693 case WMFW_ADSP1_ZM: 1694 region_name = wm_adsp_mem_region_name(type); 1695 reg = wm_adsp_region_to_reg(mem, offset); 1696 break; 1697 default: 1698 adsp_warn(dsp, 1699 "%s.%d: Unknown region type %x at %d(%x)\n", 1700 file, regions, type, pos, pos); 1701 break; 1702 } 1703 1704 adsp_dbg(dsp, "%s.%d: %d bytes at %d in %s\n", file, 1705 regions, le32_to_cpu(region->len), offset, 1706 region_name); 1707 1708 if ((pos + le32_to_cpu(region->len) + sizeof(*region)) > 1709 firmware->size) { 1710 adsp_err(dsp, 1711 "%s.%d: %s region len %d bytes exceeds file length %zu\n", 1712 file, regions, region_name, 1713 le32_to_cpu(region->len), firmware->size); 1714 ret = -EINVAL; 1715 goto out_fw; 1716 } 1717 1718 if (text) { 1719 memcpy(text, region->data, le32_to_cpu(region->len)); 1720 adsp_info(dsp, "%s: %s\n", file, text); 1721 kfree(text); 1722 text = NULL; 1723 } 1724 1725 if (reg) { 1726 buf = wm_adsp_buf_alloc(region->data, 1727 le32_to_cpu(region->len), 1728 &buf_list); 1729 if (!buf) { 1730 adsp_err(dsp, "Out of memory\n"); 1731 ret = -ENOMEM; 1732 goto out_fw; 1733 } 1734 1735 ret = regmap_raw_write_async(regmap, reg, buf->buf, 1736 le32_to_cpu(region->len)); 1737 if (ret != 0) { 1738 adsp_err(dsp, 1739 "%s.%d: Failed to write %d bytes at %d in %s: %d\n", 1740 file, regions, 1741 le32_to_cpu(region->len), offset, 1742 region_name, ret); 1743 goto out_fw; 1744 } 1745 } 1746 1747 pos += le32_to_cpu(region->len) + sizeof(*region); 1748 regions++; 1749 } 1750 1751 ret = regmap_async_complete(regmap); 1752 if (ret != 0) { 1753 adsp_err(dsp, "Failed to complete async write: %d\n", ret); 1754 goto out_fw; 1755 } 1756 1757 if (pos > firmware->size) 1758 adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", 1759 file, regions, pos - firmware->size); 1760 1761 wm_adsp_debugfs_save_wmfwname(dsp, file); 1762 1763 out_fw: 1764 regmap_async_complete(regmap); 1765 wm_adsp_buf_free(&buf_list); 1766 release_firmware(firmware); 1767 kfree(text); 1768 out: 1769 kfree(file); 1770 1771 return ret; 1772 } 1773 1774 static void wm_adsp_ctl_fixup_base(struct wm_adsp *dsp, 1775 const struct wm_adsp_alg_region *alg_region) 1776 { 1777 struct wm_coeff_ctl *ctl; 1778 1779 list_for_each_entry(ctl, &dsp->ctl_list, list) { 1780 if (ctl->fw_name == wm_adsp_fw_text[dsp->fw] && 1781 alg_region->alg == ctl->alg_region.alg && 1782 alg_region->type == ctl->alg_region.type) { 1783 ctl->alg_region.base = alg_region->base; 1784 } 1785 } 1786 } 1787 1788 static void *wm_adsp_read_algs(struct wm_adsp *dsp, size_t n_algs, 1789 unsigned int pos, unsigned int len) 1790 { 1791 void *alg; 1792 int ret; 1793 __be32 val; 1794 1795 if (n_algs == 0) { 1796 adsp_err(dsp, "No algorithms\n"); 1797 return ERR_PTR(-EINVAL); 1798 } 1799 1800 if (n_algs > 1024) { 1801 adsp_err(dsp, "Algorithm count %zx excessive\n", n_algs); 1802 return ERR_PTR(-EINVAL); 1803 } 1804 1805 /* Read the terminator first to validate the length */ 1806 ret = regmap_raw_read(dsp->regmap, pos + len, &val, sizeof(val)); 1807 if (ret != 0) { 1808 adsp_err(dsp, "Failed to read algorithm list end: %d\n", 1809 ret); 1810 return ERR_PTR(ret); 1811 } 1812 1813 if (be32_to_cpu(val) != 0xbedead) 1814 adsp_warn(dsp, "Algorithm list end %x 0x%x != 0xbeadead\n", 1815 pos + len, be32_to_cpu(val)); 1816 1817 alg = kzalloc(len * 2, GFP_KERNEL | GFP_DMA); 1818 if (!alg) 1819 return ERR_PTR(-ENOMEM); 1820 1821 ret = regmap_raw_read(dsp->regmap, pos, alg, len * 2); 1822 if (ret != 0) { 1823 adsp_err(dsp, "Failed to read algorithm list: %d\n", ret); 1824 kfree(alg); 1825 return ERR_PTR(ret); 1826 } 1827 1828 return alg; 1829 } 1830 1831 static struct wm_adsp_alg_region * 1832 wm_adsp_find_alg_region(struct wm_adsp *dsp, int type, unsigned int id) 1833 { 1834 struct wm_adsp_alg_region *alg_region; 1835 1836 list_for_each_entry(alg_region, &dsp->alg_regions, list) { 1837 if (id == alg_region->alg && type == alg_region->type) 1838 return alg_region; 1839 } 1840 1841 return NULL; 1842 } 1843 1844 static struct wm_adsp_alg_region *wm_adsp_create_region(struct wm_adsp *dsp, 1845 int type, __be32 id, 1846 __be32 base) 1847 { 1848 struct wm_adsp_alg_region *alg_region; 1849 1850 alg_region = kzalloc(sizeof(*alg_region), GFP_KERNEL); 1851 if (!alg_region) 1852 return ERR_PTR(-ENOMEM); 1853 1854 alg_region->type = type; 1855 alg_region->alg = be32_to_cpu(id); 1856 alg_region->base = be32_to_cpu(base); 1857 1858 list_add_tail(&alg_region->list, &dsp->alg_regions); 1859 1860 if (dsp->fw_ver > 0) 1861 wm_adsp_ctl_fixup_base(dsp, alg_region); 1862 1863 return alg_region; 1864 } 1865 1866 static void wm_adsp_free_alg_regions(struct wm_adsp *dsp) 1867 { 1868 struct wm_adsp_alg_region *alg_region; 1869 1870 while (!list_empty(&dsp->alg_regions)) { 1871 alg_region = list_first_entry(&dsp->alg_regions, 1872 struct wm_adsp_alg_region, 1873 list); 1874 list_del(&alg_region->list); 1875 kfree(alg_region); 1876 } 1877 } 1878 1879 static int wm_adsp1_setup_algs(struct wm_adsp *dsp) 1880 { 1881 struct wmfw_adsp1_id_hdr adsp1_id; 1882 struct wmfw_adsp1_alg_hdr *adsp1_alg; 1883 struct wm_adsp_alg_region *alg_region; 1884 const struct wm_adsp_region *mem; 1885 unsigned int pos, len; 1886 size_t n_algs; 1887 int i, ret; 1888 1889 mem = wm_adsp_find_region(dsp, WMFW_ADSP1_DM); 1890 if (WARN_ON(!mem)) 1891 return -EINVAL; 1892 1893 ret = regmap_raw_read(dsp->regmap, mem->base, &adsp1_id, 1894 sizeof(adsp1_id)); 1895 if (ret != 0) { 1896 adsp_err(dsp, "Failed to read algorithm info: %d\n", 1897 ret); 1898 return ret; 1899 } 1900 1901 n_algs = be32_to_cpu(adsp1_id.n_algs); 1902 dsp->fw_id = be32_to_cpu(adsp1_id.fw.id); 1903 adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n", 1904 dsp->fw_id, 1905 (be32_to_cpu(adsp1_id.fw.ver) & 0xff0000) >> 16, 1906 (be32_to_cpu(adsp1_id.fw.ver) & 0xff00) >> 8, 1907 be32_to_cpu(adsp1_id.fw.ver) & 0xff, 1908 n_algs); 1909 1910 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_ZM, 1911 adsp1_id.fw.id, adsp1_id.zm); 1912 if (IS_ERR(alg_region)) 1913 return PTR_ERR(alg_region); 1914 1915 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_DM, 1916 adsp1_id.fw.id, adsp1_id.dm); 1917 if (IS_ERR(alg_region)) 1918 return PTR_ERR(alg_region); 1919 1920 pos = sizeof(adsp1_id) / 2; 1921 len = (sizeof(*adsp1_alg) * n_algs) / 2; 1922 1923 adsp1_alg = wm_adsp_read_algs(dsp, n_algs, mem->base + pos, len); 1924 if (IS_ERR(adsp1_alg)) 1925 return PTR_ERR(adsp1_alg); 1926 1927 for (i = 0; i < n_algs; i++) { 1928 adsp_info(dsp, "%d: ID %x v%d.%d.%d DM@%x ZM@%x\n", 1929 i, be32_to_cpu(adsp1_alg[i].alg.id), 1930 (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff0000) >> 16, 1931 (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff00) >> 8, 1932 be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff, 1933 be32_to_cpu(adsp1_alg[i].dm), 1934 be32_to_cpu(adsp1_alg[i].zm)); 1935 1936 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_DM, 1937 adsp1_alg[i].alg.id, 1938 adsp1_alg[i].dm); 1939 if (IS_ERR(alg_region)) { 1940 ret = PTR_ERR(alg_region); 1941 goto out; 1942 } 1943 if (dsp->fw_ver == 0) { 1944 if (i + 1 < n_algs) { 1945 len = be32_to_cpu(adsp1_alg[i + 1].dm); 1946 len -= be32_to_cpu(adsp1_alg[i].dm); 1947 len *= 4; 1948 wm_adsp_create_control(dsp, alg_region, 0, 1949 len, NULL, 0, 0, 1950 SNDRV_CTL_ELEM_TYPE_BYTES); 1951 } else { 1952 adsp_warn(dsp, "Missing length info for region DM with ID %x\n", 1953 be32_to_cpu(adsp1_alg[i].alg.id)); 1954 } 1955 } 1956 1957 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_ZM, 1958 adsp1_alg[i].alg.id, 1959 adsp1_alg[i].zm); 1960 if (IS_ERR(alg_region)) { 1961 ret = PTR_ERR(alg_region); 1962 goto out; 1963 } 1964 if (dsp->fw_ver == 0) { 1965 if (i + 1 < n_algs) { 1966 len = be32_to_cpu(adsp1_alg[i + 1].zm); 1967 len -= be32_to_cpu(adsp1_alg[i].zm); 1968 len *= 4; 1969 wm_adsp_create_control(dsp, alg_region, 0, 1970 len, NULL, 0, 0, 1971 SNDRV_CTL_ELEM_TYPE_BYTES); 1972 } else { 1973 adsp_warn(dsp, "Missing length info for region ZM with ID %x\n", 1974 be32_to_cpu(adsp1_alg[i].alg.id)); 1975 } 1976 } 1977 } 1978 1979 out: 1980 kfree(adsp1_alg); 1981 return ret; 1982 } 1983 1984 static int wm_adsp2_setup_algs(struct wm_adsp *dsp) 1985 { 1986 struct wmfw_adsp2_id_hdr adsp2_id; 1987 struct wmfw_adsp2_alg_hdr *adsp2_alg; 1988 struct wm_adsp_alg_region *alg_region; 1989 const struct wm_adsp_region *mem; 1990 unsigned int pos, len; 1991 size_t n_algs; 1992 int i, ret; 1993 1994 mem = wm_adsp_find_region(dsp, WMFW_ADSP2_XM); 1995 if (WARN_ON(!mem)) 1996 return -EINVAL; 1997 1998 ret = regmap_raw_read(dsp->regmap, mem->base, &adsp2_id, 1999 sizeof(adsp2_id)); 2000 if (ret != 0) { 2001 adsp_err(dsp, "Failed to read algorithm info: %d\n", 2002 ret); 2003 return ret; 2004 } 2005 2006 n_algs = be32_to_cpu(adsp2_id.n_algs); 2007 dsp->fw_id = be32_to_cpu(adsp2_id.fw.id); 2008 dsp->fw_id_version = be32_to_cpu(adsp2_id.fw.ver); 2009 adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n", 2010 dsp->fw_id, 2011 (dsp->fw_id_version & 0xff0000) >> 16, 2012 (dsp->fw_id_version & 0xff00) >> 8, 2013 dsp->fw_id_version & 0xff, 2014 n_algs); 2015 2016 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_XM, 2017 adsp2_id.fw.id, adsp2_id.xm); 2018 if (IS_ERR(alg_region)) 2019 return PTR_ERR(alg_region); 2020 2021 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_YM, 2022 adsp2_id.fw.id, adsp2_id.ym); 2023 if (IS_ERR(alg_region)) 2024 return PTR_ERR(alg_region); 2025 2026 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_ZM, 2027 adsp2_id.fw.id, adsp2_id.zm); 2028 if (IS_ERR(alg_region)) 2029 return PTR_ERR(alg_region); 2030 2031 pos = sizeof(adsp2_id) / 2; 2032 len = (sizeof(*adsp2_alg) * n_algs) / 2; 2033 2034 adsp2_alg = wm_adsp_read_algs(dsp, n_algs, mem->base + pos, len); 2035 if (IS_ERR(adsp2_alg)) 2036 return PTR_ERR(adsp2_alg); 2037 2038 for (i = 0; i < n_algs; i++) { 2039 adsp_info(dsp, 2040 "%d: ID %x v%d.%d.%d XM@%x YM@%x ZM@%x\n", 2041 i, be32_to_cpu(adsp2_alg[i].alg.id), 2042 (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff0000) >> 16, 2043 (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff00) >> 8, 2044 be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff, 2045 be32_to_cpu(adsp2_alg[i].xm), 2046 be32_to_cpu(adsp2_alg[i].ym), 2047 be32_to_cpu(adsp2_alg[i].zm)); 2048 2049 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_XM, 2050 adsp2_alg[i].alg.id, 2051 adsp2_alg[i].xm); 2052 if (IS_ERR(alg_region)) { 2053 ret = PTR_ERR(alg_region); 2054 goto out; 2055 } 2056 if (dsp->fw_ver == 0) { 2057 if (i + 1 < n_algs) { 2058 len = be32_to_cpu(adsp2_alg[i + 1].xm); 2059 len -= be32_to_cpu(adsp2_alg[i].xm); 2060 len *= 4; 2061 wm_adsp_create_control(dsp, alg_region, 0, 2062 len, NULL, 0, 0, 2063 SNDRV_CTL_ELEM_TYPE_BYTES); 2064 } else { 2065 adsp_warn(dsp, "Missing length info for region XM with ID %x\n", 2066 be32_to_cpu(adsp2_alg[i].alg.id)); 2067 } 2068 } 2069 2070 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_YM, 2071 adsp2_alg[i].alg.id, 2072 adsp2_alg[i].ym); 2073 if (IS_ERR(alg_region)) { 2074 ret = PTR_ERR(alg_region); 2075 goto out; 2076 } 2077 if (dsp->fw_ver == 0) { 2078 if (i + 1 < n_algs) { 2079 len = be32_to_cpu(adsp2_alg[i + 1].ym); 2080 len -= be32_to_cpu(adsp2_alg[i].ym); 2081 len *= 4; 2082 wm_adsp_create_control(dsp, alg_region, 0, 2083 len, NULL, 0, 0, 2084 SNDRV_CTL_ELEM_TYPE_BYTES); 2085 } else { 2086 adsp_warn(dsp, "Missing length info for region YM with ID %x\n", 2087 be32_to_cpu(adsp2_alg[i].alg.id)); 2088 } 2089 } 2090 2091 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_ZM, 2092 adsp2_alg[i].alg.id, 2093 adsp2_alg[i].zm); 2094 if (IS_ERR(alg_region)) { 2095 ret = PTR_ERR(alg_region); 2096 goto out; 2097 } 2098 if (dsp->fw_ver == 0) { 2099 if (i + 1 < n_algs) { 2100 len = be32_to_cpu(adsp2_alg[i + 1].zm); 2101 len -= be32_to_cpu(adsp2_alg[i].zm); 2102 len *= 4; 2103 wm_adsp_create_control(dsp, alg_region, 0, 2104 len, NULL, 0, 0, 2105 SNDRV_CTL_ELEM_TYPE_BYTES); 2106 } else { 2107 adsp_warn(dsp, "Missing length info for region ZM with ID %x\n", 2108 be32_to_cpu(adsp2_alg[i].alg.id)); 2109 } 2110 } 2111 } 2112 2113 out: 2114 kfree(adsp2_alg); 2115 return ret; 2116 } 2117 2118 static int wm_adsp_load_coeff(struct wm_adsp *dsp) 2119 { 2120 LIST_HEAD(buf_list); 2121 struct regmap *regmap = dsp->regmap; 2122 struct wmfw_coeff_hdr *hdr; 2123 struct wmfw_coeff_item *blk; 2124 const struct firmware *firmware; 2125 const struct wm_adsp_region *mem; 2126 struct wm_adsp_alg_region *alg_region; 2127 const char *region_name; 2128 int ret, pos, blocks, type, offset, reg; 2129 char *file; 2130 struct wm_adsp_buf *buf; 2131 2132 file = kzalloc(PAGE_SIZE, GFP_KERNEL); 2133 if (file == NULL) 2134 return -ENOMEM; 2135 2136 snprintf(file, PAGE_SIZE, "%s-dsp%d-%s.bin", dsp->part, dsp->num, 2137 wm_adsp_fw[dsp->fw].file); 2138 file[PAGE_SIZE - 1] = '\0'; 2139 2140 ret = request_firmware(&firmware, file, dsp->dev); 2141 if (ret != 0) { 2142 adsp_warn(dsp, "Failed to request '%s'\n", file); 2143 ret = 0; 2144 goto out; 2145 } 2146 ret = -EINVAL; 2147 2148 if (sizeof(*hdr) >= firmware->size) { 2149 adsp_err(dsp, "%s: file too short, %zu bytes\n", 2150 file, firmware->size); 2151 goto out_fw; 2152 } 2153 2154 hdr = (void *)&firmware->data[0]; 2155 if (memcmp(hdr->magic, "WMDR", 4) != 0) { 2156 adsp_err(dsp, "%s: invalid magic\n", file); 2157 goto out_fw; 2158 } 2159 2160 switch (be32_to_cpu(hdr->rev) & 0xff) { 2161 case 1: 2162 break; 2163 default: 2164 adsp_err(dsp, "%s: Unsupported coefficient file format %d\n", 2165 file, be32_to_cpu(hdr->rev) & 0xff); 2166 ret = -EINVAL; 2167 goto out_fw; 2168 } 2169 2170 adsp_dbg(dsp, "%s: v%d.%d.%d\n", file, 2171 (le32_to_cpu(hdr->ver) >> 16) & 0xff, 2172 (le32_to_cpu(hdr->ver) >> 8) & 0xff, 2173 le32_to_cpu(hdr->ver) & 0xff); 2174 2175 pos = le32_to_cpu(hdr->len); 2176 2177 blocks = 0; 2178 while (pos < firmware->size && 2179 pos - firmware->size > sizeof(*blk)) { 2180 blk = (void *)(&firmware->data[pos]); 2181 2182 type = le16_to_cpu(blk->type); 2183 offset = le16_to_cpu(blk->offset); 2184 2185 adsp_dbg(dsp, "%s.%d: %x v%d.%d.%d\n", 2186 file, blocks, le32_to_cpu(blk->id), 2187 (le32_to_cpu(blk->ver) >> 16) & 0xff, 2188 (le32_to_cpu(blk->ver) >> 8) & 0xff, 2189 le32_to_cpu(blk->ver) & 0xff); 2190 adsp_dbg(dsp, "%s.%d: %d bytes at 0x%x in %x\n", 2191 file, blocks, le32_to_cpu(blk->len), offset, type); 2192 2193 reg = 0; 2194 region_name = "Unknown"; 2195 switch (type) { 2196 case (WMFW_NAME_TEXT << 8): 2197 case (WMFW_INFO_TEXT << 8): 2198 break; 2199 case (WMFW_ABSOLUTE << 8): 2200 /* 2201 * Old files may use this for global 2202 * coefficients. 2203 */ 2204 if (le32_to_cpu(blk->id) == dsp->fw_id && 2205 offset == 0) { 2206 region_name = "global coefficients"; 2207 mem = wm_adsp_find_region(dsp, type); 2208 if (!mem) { 2209 adsp_err(dsp, "No ZM\n"); 2210 break; 2211 } 2212 reg = wm_adsp_region_to_reg(mem, 0); 2213 2214 } else { 2215 region_name = "register"; 2216 reg = offset; 2217 } 2218 break; 2219 2220 case WMFW_ADSP1_DM: 2221 case WMFW_ADSP1_ZM: 2222 case WMFW_ADSP2_XM: 2223 case WMFW_ADSP2_YM: 2224 adsp_dbg(dsp, "%s.%d: %d bytes in %x for %x\n", 2225 file, blocks, le32_to_cpu(blk->len), 2226 type, le32_to_cpu(blk->id)); 2227 2228 mem = wm_adsp_find_region(dsp, type); 2229 if (!mem) { 2230 adsp_err(dsp, "No base for region %x\n", type); 2231 break; 2232 } 2233 2234 alg_region = wm_adsp_find_alg_region(dsp, type, 2235 le32_to_cpu(blk->id)); 2236 if (alg_region) { 2237 reg = alg_region->base; 2238 reg = wm_adsp_region_to_reg(mem, reg); 2239 reg += offset; 2240 } else { 2241 adsp_err(dsp, "No %x for algorithm %x\n", 2242 type, le32_to_cpu(blk->id)); 2243 } 2244 break; 2245 2246 default: 2247 adsp_err(dsp, "%s.%d: Unknown region type %x at %d\n", 2248 file, blocks, type, pos); 2249 break; 2250 } 2251 2252 if (reg) { 2253 if ((pos + le32_to_cpu(blk->len) + sizeof(*blk)) > 2254 firmware->size) { 2255 adsp_err(dsp, 2256 "%s.%d: %s region len %d bytes exceeds file length %zu\n", 2257 file, blocks, region_name, 2258 le32_to_cpu(blk->len), 2259 firmware->size); 2260 ret = -EINVAL; 2261 goto out_fw; 2262 } 2263 2264 buf = wm_adsp_buf_alloc(blk->data, 2265 le32_to_cpu(blk->len), 2266 &buf_list); 2267 if (!buf) { 2268 adsp_err(dsp, "Out of memory\n"); 2269 ret = -ENOMEM; 2270 goto out_fw; 2271 } 2272 2273 adsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n", 2274 file, blocks, le32_to_cpu(blk->len), 2275 reg); 2276 ret = regmap_raw_write_async(regmap, reg, buf->buf, 2277 le32_to_cpu(blk->len)); 2278 if (ret != 0) { 2279 adsp_err(dsp, 2280 "%s.%d: Failed to write to %x in %s: %d\n", 2281 file, blocks, reg, region_name, ret); 2282 } 2283 } 2284 2285 pos += (le32_to_cpu(blk->len) + sizeof(*blk) + 3) & ~0x03; 2286 blocks++; 2287 } 2288 2289 ret = regmap_async_complete(regmap); 2290 if (ret != 0) 2291 adsp_err(dsp, "Failed to complete async write: %d\n", ret); 2292 2293 if (pos > firmware->size) 2294 adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", 2295 file, blocks, pos - firmware->size); 2296 2297 wm_adsp_debugfs_save_binname(dsp, file); 2298 2299 out_fw: 2300 regmap_async_complete(regmap); 2301 release_firmware(firmware); 2302 wm_adsp_buf_free(&buf_list); 2303 out: 2304 kfree(file); 2305 return ret; 2306 } 2307 2308 int wm_adsp1_init(struct wm_adsp *dsp) 2309 { 2310 INIT_LIST_HEAD(&dsp->alg_regions); 2311 2312 mutex_init(&dsp->pwr_lock); 2313 2314 return 0; 2315 } 2316 EXPORT_SYMBOL_GPL(wm_adsp1_init); 2317 2318 int wm_adsp1_event(struct snd_soc_dapm_widget *w, 2319 struct snd_kcontrol *kcontrol, 2320 int event) 2321 { 2322 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 2323 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); 2324 struct wm_adsp *dsp = &dsps[w->shift]; 2325 struct wm_coeff_ctl *ctl; 2326 int ret; 2327 unsigned int val; 2328 2329 dsp->codec = codec; 2330 2331 mutex_lock(&dsp->pwr_lock); 2332 2333 switch (event) { 2334 case SND_SOC_DAPM_POST_PMU: 2335 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 2336 ADSP1_SYS_ENA, ADSP1_SYS_ENA); 2337 2338 /* 2339 * For simplicity set the DSP clock rate to be the 2340 * SYSCLK rate rather than making it configurable. 2341 */ 2342 if (dsp->sysclk_reg) { 2343 ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val); 2344 if (ret != 0) { 2345 adsp_err(dsp, "Failed to read SYSCLK state: %d\n", 2346 ret); 2347 goto err_mutex; 2348 } 2349 2350 val = (val & dsp->sysclk_mask) >> dsp->sysclk_shift; 2351 2352 ret = regmap_update_bits(dsp->regmap, 2353 dsp->base + ADSP1_CONTROL_31, 2354 ADSP1_CLK_SEL_MASK, val); 2355 if (ret != 0) { 2356 adsp_err(dsp, "Failed to set clock rate: %d\n", 2357 ret); 2358 goto err_mutex; 2359 } 2360 } 2361 2362 ret = wm_adsp_load(dsp); 2363 if (ret != 0) 2364 goto err_ena; 2365 2366 ret = wm_adsp1_setup_algs(dsp); 2367 if (ret != 0) 2368 goto err_ena; 2369 2370 ret = wm_adsp_load_coeff(dsp); 2371 if (ret != 0) 2372 goto err_ena; 2373 2374 /* Initialize caches for enabled and unset controls */ 2375 ret = wm_coeff_init_control_caches(dsp); 2376 if (ret != 0) 2377 goto err_ena; 2378 2379 /* Sync set controls */ 2380 ret = wm_coeff_sync_controls(dsp); 2381 if (ret != 0) 2382 goto err_ena; 2383 2384 dsp->booted = true; 2385 2386 /* Start the core running */ 2387 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 2388 ADSP1_CORE_ENA | ADSP1_START, 2389 ADSP1_CORE_ENA | ADSP1_START); 2390 2391 dsp->running = true; 2392 break; 2393 2394 case SND_SOC_DAPM_PRE_PMD: 2395 dsp->running = false; 2396 dsp->booted = false; 2397 2398 /* Halt the core */ 2399 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 2400 ADSP1_CORE_ENA | ADSP1_START, 0); 2401 2402 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_19, 2403 ADSP1_WDMA_BUFFER_LENGTH_MASK, 0); 2404 2405 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 2406 ADSP1_SYS_ENA, 0); 2407 2408 list_for_each_entry(ctl, &dsp->ctl_list, list) 2409 ctl->enabled = 0; 2410 2411 2412 wm_adsp_free_alg_regions(dsp); 2413 break; 2414 2415 default: 2416 break; 2417 } 2418 2419 mutex_unlock(&dsp->pwr_lock); 2420 2421 return 0; 2422 2423 err_ena: 2424 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 2425 ADSP1_SYS_ENA, 0); 2426 err_mutex: 2427 mutex_unlock(&dsp->pwr_lock); 2428 2429 return ret; 2430 } 2431 EXPORT_SYMBOL_GPL(wm_adsp1_event); 2432 2433 static int wm_adsp2_ena(struct wm_adsp *dsp) 2434 { 2435 unsigned int val; 2436 int ret, count; 2437 2438 ret = regmap_update_bits_async(dsp->regmap, dsp->base + ADSP2_CONTROL, 2439 ADSP2_SYS_ENA, ADSP2_SYS_ENA); 2440 if (ret != 0) 2441 return ret; 2442 2443 /* Wait for the RAM to start, should be near instantaneous */ 2444 for (count = 0; count < 10; ++count) { 2445 ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1, &val); 2446 if (ret != 0) 2447 return ret; 2448 2449 if (val & ADSP2_RAM_RDY) 2450 break; 2451 2452 usleep_range(250, 500); 2453 } 2454 2455 if (!(val & ADSP2_RAM_RDY)) { 2456 adsp_err(dsp, "Failed to start DSP RAM\n"); 2457 return -EBUSY; 2458 } 2459 2460 adsp_dbg(dsp, "RAM ready after %d polls\n", count); 2461 2462 return 0; 2463 } 2464 2465 static void wm_adsp2_boot_work(struct work_struct *work) 2466 { 2467 struct wm_adsp *dsp = container_of(work, 2468 struct wm_adsp, 2469 boot_work); 2470 int ret; 2471 2472 mutex_lock(&dsp->pwr_lock); 2473 2474 ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2475 ADSP2_MEM_ENA, ADSP2_MEM_ENA); 2476 if (ret != 0) 2477 goto err_mutex; 2478 2479 ret = wm_adsp2_ena(dsp); 2480 if (ret != 0) 2481 goto err_mem; 2482 2483 ret = wm_adsp_load(dsp); 2484 if (ret != 0) 2485 goto err_ena; 2486 2487 ret = wm_adsp2_setup_algs(dsp); 2488 if (ret != 0) 2489 goto err_ena; 2490 2491 ret = wm_adsp_load_coeff(dsp); 2492 if (ret != 0) 2493 goto err_ena; 2494 2495 /* Initialize caches for enabled and unset controls */ 2496 ret = wm_coeff_init_control_caches(dsp); 2497 if (ret != 0) 2498 goto err_ena; 2499 2500 /* Turn DSP back off until we are ready to run */ 2501 ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2502 ADSP2_SYS_ENA, 0); 2503 if (ret != 0) 2504 goto err_ena; 2505 2506 dsp->booted = true; 2507 2508 mutex_unlock(&dsp->pwr_lock); 2509 2510 return; 2511 2512 err_ena: 2513 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2514 ADSP2_SYS_ENA | ADSP2_CORE_ENA | ADSP2_START, 0); 2515 err_mem: 2516 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2517 ADSP2_MEM_ENA, 0); 2518 err_mutex: 2519 mutex_unlock(&dsp->pwr_lock); 2520 } 2521 2522 static void wm_adsp2_set_dspclk(struct wm_adsp *dsp, unsigned int freq) 2523 { 2524 int ret; 2525 2526 ret = regmap_update_bits_async(dsp->regmap, 2527 dsp->base + ADSP2_CLOCKING, 2528 ADSP2_CLK_SEL_MASK, 2529 freq << ADSP2_CLK_SEL_SHIFT); 2530 if (ret != 0) 2531 adsp_err(dsp, "Failed to set clock rate: %d\n", ret); 2532 } 2533 2534 int wm_adsp2_preloader_get(struct snd_kcontrol *kcontrol, 2535 struct snd_ctl_elem_value *ucontrol) 2536 { 2537 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 2538 struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec); 2539 2540 ucontrol->value.integer.value[0] = dsp->preloaded; 2541 2542 return 0; 2543 } 2544 EXPORT_SYMBOL_GPL(wm_adsp2_preloader_get); 2545 2546 int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol, 2547 struct snd_ctl_elem_value *ucontrol) 2548 { 2549 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 2550 struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec); 2551 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); 2552 struct soc_mixer_control *mc = 2553 (struct soc_mixer_control *)kcontrol->private_value; 2554 char preload[32]; 2555 2556 snprintf(preload, ARRAY_SIZE(preload), "DSP%d Preload", mc->shift); 2557 2558 dsp->preloaded = ucontrol->value.integer.value[0]; 2559 2560 if (ucontrol->value.integer.value[0]) 2561 snd_soc_dapm_force_enable_pin(dapm, preload); 2562 else 2563 snd_soc_dapm_disable_pin(dapm, preload); 2564 2565 snd_soc_dapm_sync(dapm); 2566 2567 return 0; 2568 } 2569 EXPORT_SYMBOL_GPL(wm_adsp2_preloader_put); 2570 2571 int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, 2572 struct snd_kcontrol *kcontrol, int event, 2573 unsigned int freq) 2574 { 2575 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 2576 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); 2577 struct wm_adsp *dsp = &dsps[w->shift]; 2578 struct wm_coeff_ctl *ctl; 2579 2580 switch (event) { 2581 case SND_SOC_DAPM_PRE_PMU: 2582 wm_adsp2_set_dspclk(dsp, freq); 2583 queue_work(system_unbound_wq, &dsp->boot_work); 2584 break; 2585 case SND_SOC_DAPM_PRE_PMD: 2586 mutex_lock(&dsp->pwr_lock); 2587 2588 wm_adsp_debugfs_clear(dsp); 2589 2590 dsp->fw_id = 0; 2591 dsp->fw_id_version = 0; 2592 2593 dsp->booted = false; 2594 2595 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2596 ADSP2_MEM_ENA, 0); 2597 2598 list_for_each_entry(ctl, &dsp->ctl_list, list) 2599 ctl->enabled = 0; 2600 2601 wm_adsp_free_alg_regions(dsp); 2602 2603 mutex_unlock(&dsp->pwr_lock); 2604 2605 adsp_dbg(dsp, "Shutdown complete\n"); 2606 break; 2607 default: 2608 break; 2609 } 2610 2611 return 0; 2612 } 2613 EXPORT_SYMBOL_GPL(wm_adsp2_early_event); 2614 2615 int wm_adsp2_event(struct snd_soc_dapm_widget *w, 2616 struct snd_kcontrol *kcontrol, int event) 2617 { 2618 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 2619 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); 2620 struct wm_adsp *dsp = &dsps[w->shift]; 2621 int ret; 2622 2623 switch (event) { 2624 case SND_SOC_DAPM_POST_PMU: 2625 flush_work(&dsp->boot_work); 2626 2627 mutex_lock(&dsp->pwr_lock); 2628 2629 if (!dsp->booted) { 2630 ret = -EIO; 2631 goto err; 2632 } 2633 2634 ret = wm_adsp2_ena(dsp); 2635 if (ret != 0) 2636 goto err; 2637 2638 /* Sync set controls */ 2639 ret = wm_coeff_sync_controls(dsp); 2640 if (ret != 0) 2641 goto err; 2642 2643 ret = regmap_update_bits(dsp->regmap, 2644 dsp->base + ADSP2_CONTROL, 2645 ADSP2_CORE_ENA | ADSP2_START, 2646 ADSP2_CORE_ENA | ADSP2_START); 2647 if (ret != 0) 2648 goto err; 2649 2650 if (wm_adsp_fw[dsp->fw].num_caps != 0) { 2651 ret = wm_adsp_buffer_init(dsp); 2652 if (ret < 0) 2653 goto err; 2654 } 2655 2656 dsp->running = true; 2657 2658 mutex_unlock(&dsp->pwr_lock); 2659 2660 break; 2661 2662 case SND_SOC_DAPM_PRE_PMD: 2663 /* Tell the firmware to cleanup */ 2664 wm_adsp_signal_event_controls(dsp, WM_ADSP_FW_EVENT_SHUTDOWN); 2665 2666 /* Log firmware state, it can be useful for analysis */ 2667 wm_adsp2_show_fw_status(dsp); 2668 2669 mutex_lock(&dsp->pwr_lock); 2670 2671 dsp->running = false; 2672 2673 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2674 ADSP2_CORE_ENA | ADSP2_START, 0); 2675 2676 /* Make sure DMAs are quiesced */ 2677 regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); 2678 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0); 2679 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_2, 0); 2680 2681 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2682 ADSP2_SYS_ENA, 0); 2683 2684 if (wm_adsp_fw[dsp->fw].num_caps != 0) 2685 wm_adsp_buffer_free(dsp); 2686 2687 mutex_unlock(&dsp->pwr_lock); 2688 2689 adsp_dbg(dsp, "Execution stopped\n"); 2690 break; 2691 2692 default: 2693 break; 2694 } 2695 2696 return 0; 2697 err: 2698 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2699 ADSP2_SYS_ENA | ADSP2_CORE_ENA | ADSP2_START, 0); 2700 mutex_unlock(&dsp->pwr_lock); 2701 return ret; 2702 } 2703 EXPORT_SYMBOL_GPL(wm_adsp2_event); 2704 2705 int wm_adsp2_codec_probe(struct wm_adsp *dsp, struct snd_soc_codec *codec) 2706 { 2707 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); 2708 char preload[32]; 2709 2710 snprintf(preload, ARRAY_SIZE(preload), "DSP%d Preload", dsp->num); 2711 snd_soc_dapm_disable_pin(dapm, preload); 2712 2713 wm_adsp2_init_debugfs(dsp, codec); 2714 2715 dsp->codec = codec; 2716 2717 return snd_soc_add_codec_controls(codec, 2718 &wm_adsp_fw_controls[dsp->num - 1], 2719 1); 2720 } 2721 EXPORT_SYMBOL_GPL(wm_adsp2_codec_probe); 2722 2723 int wm_adsp2_codec_remove(struct wm_adsp *dsp, struct snd_soc_codec *codec) 2724 { 2725 wm_adsp2_cleanup_debugfs(dsp); 2726 2727 return 0; 2728 } 2729 EXPORT_SYMBOL_GPL(wm_adsp2_codec_remove); 2730 2731 int wm_adsp2_init(struct wm_adsp *dsp) 2732 { 2733 int ret; 2734 2735 /* 2736 * Disable the DSP memory by default when in reset for a small 2737 * power saving. 2738 */ 2739 ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2740 ADSP2_MEM_ENA, 0); 2741 if (ret != 0) { 2742 adsp_err(dsp, "Failed to clear memory retention: %d\n", ret); 2743 return ret; 2744 } 2745 2746 INIT_LIST_HEAD(&dsp->alg_regions); 2747 INIT_LIST_HEAD(&dsp->ctl_list); 2748 INIT_WORK(&dsp->boot_work, wm_adsp2_boot_work); 2749 2750 mutex_init(&dsp->pwr_lock); 2751 2752 return 0; 2753 } 2754 EXPORT_SYMBOL_GPL(wm_adsp2_init); 2755 2756 void wm_adsp2_remove(struct wm_adsp *dsp) 2757 { 2758 struct wm_coeff_ctl *ctl; 2759 2760 while (!list_empty(&dsp->ctl_list)) { 2761 ctl = list_first_entry(&dsp->ctl_list, struct wm_coeff_ctl, 2762 list); 2763 list_del(&ctl->list); 2764 wm_adsp_free_ctl_blk(ctl); 2765 } 2766 } 2767 EXPORT_SYMBOL_GPL(wm_adsp2_remove); 2768 2769 static inline int wm_adsp_compr_attached(struct wm_adsp_compr *compr) 2770 { 2771 return compr->buf != NULL; 2772 } 2773 2774 static int wm_adsp_compr_attach(struct wm_adsp_compr *compr) 2775 { 2776 /* 2777 * Note this will be more complex once each DSP can support multiple 2778 * streams 2779 */ 2780 if (!compr->dsp->buffer) 2781 return -EINVAL; 2782 2783 compr->buf = compr->dsp->buffer; 2784 compr->buf->compr = compr; 2785 2786 return 0; 2787 } 2788 2789 static void wm_adsp_compr_detach(struct wm_adsp_compr *compr) 2790 { 2791 if (!compr) 2792 return; 2793 2794 /* Wake the poll so it can see buffer is no longer attached */ 2795 if (compr->stream) 2796 snd_compr_fragment_elapsed(compr->stream); 2797 2798 if (wm_adsp_compr_attached(compr)) { 2799 compr->buf->compr = NULL; 2800 compr->buf = NULL; 2801 } 2802 } 2803 2804 int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream) 2805 { 2806 struct wm_adsp_compr *compr; 2807 int ret = 0; 2808 2809 mutex_lock(&dsp->pwr_lock); 2810 2811 if (wm_adsp_fw[dsp->fw].num_caps == 0) { 2812 adsp_err(dsp, "Firmware does not support compressed API\n"); 2813 ret = -ENXIO; 2814 goto out; 2815 } 2816 2817 if (wm_adsp_fw[dsp->fw].compr_direction != stream->direction) { 2818 adsp_err(dsp, "Firmware does not support stream direction\n"); 2819 ret = -EINVAL; 2820 goto out; 2821 } 2822 2823 if (dsp->compr) { 2824 /* It is expect this limitation will be removed in future */ 2825 adsp_err(dsp, "Only a single stream supported per DSP\n"); 2826 ret = -EBUSY; 2827 goto out; 2828 } 2829 2830 compr = kzalloc(sizeof(*compr), GFP_KERNEL); 2831 if (!compr) { 2832 ret = -ENOMEM; 2833 goto out; 2834 } 2835 2836 compr->dsp = dsp; 2837 compr->stream = stream; 2838 2839 dsp->compr = compr; 2840 2841 stream->runtime->private_data = compr; 2842 2843 out: 2844 mutex_unlock(&dsp->pwr_lock); 2845 2846 return ret; 2847 } 2848 EXPORT_SYMBOL_GPL(wm_adsp_compr_open); 2849 2850 int wm_adsp_compr_free(struct snd_compr_stream *stream) 2851 { 2852 struct wm_adsp_compr *compr = stream->runtime->private_data; 2853 struct wm_adsp *dsp = compr->dsp; 2854 2855 mutex_lock(&dsp->pwr_lock); 2856 2857 wm_adsp_compr_detach(compr); 2858 dsp->compr = NULL; 2859 2860 kfree(compr->raw_buf); 2861 kfree(compr); 2862 2863 mutex_unlock(&dsp->pwr_lock); 2864 2865 return 0; 2866 } 2867 EXPORT_SYMBOL_GPL(wm_adsp_compr_free); 2868 2869 static int wm_adsp_compr_check_params(struct snd_compr_stream *stream, 2870 struct snd_compr_params *params) 2871 { 2872 struct wm_adsp_compr *compr = stream->runtime->private_data; 2873 struct wm_adsp *dsp = compr->dsp; 2874 const struct wm_adsp_fw_caps *caps; 2875 const struct snd_codec_desc *desc; 2876 int i, j; 2877 2878 if (params->buffer.fragment_size < WM_ADSP_MIN_FRAGMENT_SIZE || 2879 params->buffer.fragment_size > WM_ADSP_MAX_FRAGMENT_SIZE || 2880 params->buffer.fragments < WM_ADSP_MIN_FRAGMENTS || 2881 params->buffer.fragments > WM_ADSP_MAX_FRAGMENTS || 2882 params->buffer.fragment_size % WM_ADSP_DATA_WORD_SIZE) { 2883 adsp_err(dsp, "Invalid buffer fragsize=%d fragments=%d\n", 2884 params->buffer.fragment_size, 2885 params->buffer.fragments); 2886 2887 return -EINVAL; 2888 } 2889 2890 for (i = 0; i < wm_adsp_fw[dsp->fw].num_caps; i++) { 2891 caps = &wm_adsp_fw[dsp->fw].caps[i]; 2892 desc = &caps->desc; 2893 2894 if (caps->id != params->codec.id) 2895 continue; 2896 2897 if (stream->direction == SND_COMPRESS_PLAYBACK) { 2898 if (desc->max_ch < params->codec.ch_out) 2899 continue; 2900 } else { 2901 if (desc->max_ch < params->codec.ch_in) 2902 continue; 2903 } 2904 2905 if (!(desc->formats & (1 << params->codec.format))) 2906 continue; 2907 2908 for (j = 0; j < desc->num_sample_rates; ++j) 2909 if (desc->sample_rates[j] == params->codec.sample_rate) 2910 return 0; 2911 } 2912 2913 adsp_err(dsp, "Invalid params id=%u ch=%u,%u rate=%u fmt=%u\n", 2914 params->codec.id, params->codec.ch_in, params->codec.ch_out, 2915 params->codec.sample_rate, params->codec.format); 2916 return -EINVAL; 2917 } 2918 2919 static inline unsigned int wm_adsp_compr_frag_words(struct wm_adsp_compr *compr) 2920 { 2921 return compr->size.fragment_size / WM_ADSP_DATA_WORD_SIZE; 2922 } 2923 2924 int wm_adsp_compr_set_params(struct snd_compr_stream *stream, 2925 struct snd_compr_params *params) 2926 { 2927 struct wm_adsp_compr *compr = stream->runtime->private_data; 2928 unsigned int size; 2929 int ret; 2930 2931 ret = wm_adsp_compr_check_params(stream, params); 2932 if (ret) 2933 return ret; 2934 2935 compr->size = params->buffer; 2936 2937 adsp_dbg(compr->dsp, "fragment_size=%d fragments=%d\n", 2938 compr->size.fragment_size, compr->size.fragments); 2939 2940 size = wm_adsp_compr_frag_words(compr) * sizeof(*compr->raw_buf); 2941 compr->raw_buf = kmalloc(size, GFP_DMA | GFP_KERNEL); 2942 if (!compr->raw_buf) 2943 return -ENOMEM; 2944 2945 compr->sample_rate = params->codec.sample_rate; 2946 2947 return 0; 2948 } 2949 EXPORT_SYMBOL_GPL(wm_adsp_compr_set_params); 2950 2951 int wm_adsp_compr_get_caps(struct snd_compr_stream *stream, 2952 struct snd_compr_caps *caps) 2953 { 2954 struct wm_adsp_compr *compr = stream->runtime->private_data; 2955 int fw = compr->dsp->fw; 2956 int i; 2957 2958 if (wm_adsp_fw[fw].caps) { 2959 for (i = 0; i < wm_adsp_fw[fw].num_caps; i++) 2960 caps->codecs[i] = wm_adsp_fw[fw].caps[i].id; 2961 2962 caps->num_codecs = i; 2963 caps->direction = wm_adsp_fw[fw].compr_direction; 2964 2965 caps->min_fragment_size = WM_ADSP_MIN_FRAGMENT_SIZE; 2966 caps->max_fragment_size = WM_ADSP_MAX_FRAGMENT_SIZE; 2967 caps->min_fragments = WM_ADSP_MIN_FRAGMENTS; 2968 caps->max_fragments = WM_ADSP_MAX_FRAGMENTS; 2969 } 2970 2971 return 0; 2972 } 2973 EXPORT_SYMBOL_GPL(wm_adsp_compr_get_caps); 2974 2975 static int wm_adsp_read_data_block(struct wm_adsp *dsp, int mem_type, 2976 unsigned int mem_addr, 2977 unsigned int num_words, u32 *data) 2978 { 2979 struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type); 2980 unsigned int i, reg; 2981 int ret; 2982 2983 if (!mem) 2984 return -EINVAL; 2985 2986 reg = wm_adsp_region_to_reg(mem, mem_addr); 2987 2988 ret = regmap_raw_read(dsp->regmap, reg, data, 2989 sizeof(*data) * num_words); 2990 if (ret < 0) 2991 return ret; 2992 2993 for (i = 0; i < num_words; ++i) 2994 data[i] = be32_to_cpu(data[i]) & 0x00ffffffu; 2995 2996 return 0; 2997 } 2998 2999 static inline int wm_adsp_read_data_word(struct wm_adsp *dsp, int mem_type, 3000 unsigned int mem_addr, u32 *data) 3001 { 3002 return wm_adsp_read_data_block(dsp, mem_type, mem_addr, 1, data); 3003 } 3004 3005 static int wm_adsp_write_data_word(struct wm_adsp *dsp, int mem_type, 3006 unsigned int mem_addr, u32 data) 3007 { 3008 struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type); 3009 unsigned int reg; 3010 3011 if (!mem) 3012 return -EINVAL; 3013 3014 reg = wm_adsp_region_to_reg(mem, mem_addr); 3015 3016 data = cpu_to_be32(data & 0x00ffffffu); 3017 3018 return regmap_raw_write(dsp->regmap, reg, &data, sizeof(data)); 3019 } 3020 3021 static inline int wm_adsp_buffer_read(struct wm_adsp_compr_buf *buf, 3022 unsigned int field_offset, u32 *data) 3023 { 3024 return wm_adsp_read_data_word(buf->dsp, WMFW_ADSP2_XM, 3025 buf->host_buf_ptr + field_offset, data); 3026 } 3027 3028 static inline int wm_adsp_buffer_write(struct wm_adsp_compr_buf *buf, 3029 unsigned int field_offset, u32 data) 3030 { 3031 return wm_adsp_write_data_word(buf->dsp, WMFW_ADSP2_XM, 3032 buf->host_buf_ptr + field_offset, data); 3033 } 3034 3035 static int wm_adsp_buffer_locate(struct wm_adsp_compr_buf *buf) 3036 { 3037 struct wm_adsp_alg_region *alg_region; 3038 struct wm_adsp *dsp = buf->dsp; 3039 u32 xmalg, addr, magic; 3040 int i, ret; 3041 3042 alg_region = wm_adsp_find_alg_region(dsp, WMFW_ADSP2_XM, dsp->fw_id); 3043 xmalg = sizeof(struct wm_adsp_system_config_xm_hdr) / sizeof(__be32); 3044 3045 addr = alg_region->base + xmalg + ALG_XM_FIELD(magic); 3046 ret = wm_adsp_read_data_word(dsp, WMFW_ADSP2_XM, addr, &magic); 3047 if (ret < 0) 3048 return ret; 3049 3050 if (magic != WM_ADSP_ALG_XM_STRUCT_MAGIC) 3051 return -EINVAL; 3052 3053 addr = alg_region->base + xmalg + ALG_XM_FIELD(host_buf_ptr); 3054 for (i = 0; i < 5; ++i) { 3055 ret = wm_adsp_read_data_word(dsp, WMFW_ADSP2_XM, addr, 3056 &buf->host_buf_ptr); 3057 if (ret < 0) 3058 return ret; 3059 3060 if (buf->host_buf_ptr) 3061 break; 3062 3063 usleep_range(1000, 2000); 3064 } 3065 3066 if (!buf->host_buf_ptr) 3067 return -EIO; 3068 3069 adsp_dbg(dsp, "host_buf_ptr=%x\n", buf->host_buf_ptr); 3070 3071 return 0; 3072 } 3073 3074 static int wm_adsp_buffer_populate(struct wm_adsp_compr_buf *buf) 3075 { 3076 const struct wm_adsp_fw_caps *caps = wm_adsp_fw[buf->dsp->fw].caps; 3077 struct wm_adsp_buffer_region *region; 3078 u32 offset = 0; 3079 int i, ret; 3080 3081 for (i = 0; i < caps->num_regions; ++i) { 3082 region = &buf->regions[i]; 3083 3084 region->offset = offset; 3085 region->mem_type = caps->region_defs[i].mem_type; 3086 3087 ret = wm_adsp_buffer_read(buf, caps->region_defs[i].base_offset, 3088 ®ion->base_addr); 3089 if (ret < 0) 3090 return ret; 3091 3092 ret = wm_adsp_buffer_read(buf, caps->region_defs[i].size_offset, 3093 &offset); 3094 if (ret < 0) 3095 return ret; 3096 3097 region->cumulative_size = offset; 3098 3099 adsp_dbg(buf->dsp, 3100 "region=%d type=%d base=%04x off=%04x size=%04x\n", 3101 i, region->mem_type, region->base_addr, 3102 region->offset, region->cumulative_size); 3103 } 3104 3105 return 0; 3106 } 3107 3108 static int wm_adsp_buffer_init(struct wm_adsp *dsp) 3109 { 3110 struct wm_adsp_compr_buf *buf; 3111 int ret; 3112 3113 buf = kzalloc(sizeof(*buf), GFP_KERNEL); 3114 if (!buf) 3115 return -ENOMEM; 3116 3117 buf->dsp = dsp; 3118 buf->read_index = -1; 3119 buf->irq_count = 0xFFFFFFFF; 3120 3121 ret = wm_adsp_buffer_locate(buf); 3122 if (ret < 0) { 3123 adsp_err(dsp, "Failed to acquire host buffer: %d\n", ret); 3124 goto err_buffer; 3125 } 3126 3127 buf->regions = kcalloc(wm_adsp_fw[dsp->fw].caps->num_regions, 3128 sizeof(*buf->regions), GFP_KERNEL); 3129 if (!buf->regions) { 3130 ret = -ENOMEM; 3131 goto err_buffer; 3132 } 3133 3134 ret = wm_adsp_buffer_populate(buf); 3135 if (ret < 0) { 3136 adsp_err(dsp, "Failed to populate host buffer: %d\n", ret); 3137 goto err_regions; 3138 } 3139 3140 dsp->buffer = buf; 3141 3142 return 0; 3143 3144 err_regions: 3145 kfree(buf->regions); 3146 err_buffer: 3147 kfree(buf); 3148 return ret; 3149 } 3150 3151 static int wm_adsp_buffer_free(struct wm_adsp *dsp) 3152 { 3153 if (dsp->buffer) { 3154 wm_adsp_compr_detach(dsp->buffer->compr); 3155 3156 kfree(dsp->buffer->regions); 3157 kfree(dsp->buffer); 3158 3159 dsp->buffer = NULL; 3160 } 3161 3162 return 0; 3163 } 3164 3165 int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd) 3166 { 3167 struct wm_adsp_compr *compr = stream->runtime->private_data; 3168 struct wm_adsp *dsp = compr->dsp; 3169 int ret = 0; 3170 3171 adsp_dbg(dsp, "Trigger: %d\n", cmd); 3172 3173 mutex_lock(&dsp->pwr_lock); 3174 3175 switch (cmd) { 3176 case SNDRV_PCM_TRIGGER_START: 3177 if (wm_adsp_compr_attached(compr)) 3178 break; 3179 3180 ret = wm_adsp_compr_attach(compr); 3181 if (ret < 0) { 3182 adsp_err(dsp, "Failed to link buffer and stream: %d\n", 3183 ret); 3184 break; 3185 } 3186 3187 /* Trigger the IRQ at one fragment of data */ 3188 ret = wm_adsp_buffer_write(compr->buf, 3189 HOST_BUFFER_FIELD(high_water_mark), 3190 wm_adsp_compr_frag_words(compr)); 3191 if (ret < 0) { 3192 adsp_err(dsp, "Failed to set high water mark: %d\n", 3193 ret); 3194 break; 3195 } 3196 break; 3197 case SNDRV_PCM_TRIGGER_STOP: 3198 break; 3199 default: 3200 ret = -EINVAL; 3201 break; 3202 } 3203 3204 mutex_unlock(&dsp->pwr_lock); 3205 3206 return ret; 3207 } 3208 EXPORT_SYMBOL_GPL(wm_adsp_compr_trigger); 3209 3210 static inline int wm_adsp_buffer_size(struct wm_adsp_compr_buf *buf) 3211 { 3212 int last_region = wm_adsp_fw[buf->dsp->fw].caps->num_regions - 1; 3213 3214 return buf->regions[last_region].cumulative_size; 3215 } 3216 3217 static int wm_adsp_buffer_update_avail(struct wm_adsp_compr_buf *buf) 3218 { 3219 u32 next_read_index, next_write_index; 3220 int write_index, read_index, avail; 3221 int ret; 3222 3223 /* Only sync read index if we haven't already read a valid index */ 3224 if (buf->read_index < 0) { 3225 ret = wm_adsp_buffer_read(buf, 3226 HOST_BUFFER_FIELD(next_read_index), 3227 &next_read_index); 3228 if (ret < 0) 3229 return ret; 3230 3231 read_index = sign_extend32(next_read_index, 23); 3232 3233 if (read_index < 0) { 3234 adsp_dbg(buf->dsp, "Avail check on unstarted stream\n"); 3235 return 0; 3236 } 3237 3238 buf->read_index = read_index; 3239 } 3240 3241 ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(next_write_index), 3242 &next_write_index); 3243 if (ret < 0) 3244 return ret; 3245 3246 write_index = sign_extend32(next_write_index, 23); 3247 3248 avail = write_index - buf->read_index; 3249 if (avail < 0) 3250 avail += wm_adsp_buffer_size(buf); 3251 3252 adsp_dbg(buf->dsp, "readindex=0x%x, writeindex=0x%x, avail=%d\n", 3253 buf->read_index, write_index, avail * WM_ADSP_DATA_WORD_SIZE); 3254 3255 buf->avail = avail; 3256 3257 return 0; 3258 } 3259 3260 static int wm_adsp_buffer_get_error(struct wm_adsp_compr_buf *buf) 3261 { 3262 int ret; 3263 3264 ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(error), &buf->error); 3265 if (ret < 0) { 3266 adsp_err(buf->dsp, "Failed to check buffer error: %d\n", ret); 3267 return ret; 3268 } 3269 if (buf->error != 0) { 3270 adsp_err(buf->dsp, "Buffer error occurred: %d\n", buf->error); 3271 return -EIO; 3272 } 3273 3274 return 0; 3275 } 3276 3277 int wm_adsp_compr_handle_irq(struct wm_adsp *dsp) 3278 { 3279 struct wm_adsp_compr_buf *buf; 3280 struct wm_adsp_compr *compr; 3281 int ret = 0; 3282 3283 mutex_lock(&dsp->pwr_lock); 3284 3285 buf = dsp->buffer; 3286 compr = dsp->compr; 3287 3288 if (!buf) { 3289 ret = -ENODEV; 3290 goto out; 3291 } 3292 3293 adsp_dbg(dsp, "Handling buffer IRQ\n"); 3294 3295 ret = wm_adsp_buffer_get_error(buf); 3296 if (ret < 0) 3297 goto out_notify; /* Wake poll to report error */ 3298 3299 ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(irq_count), 3300 &buf->irq_count); 3301 if (ret < 0) { 3302 adsp_err(dsp, "Failed to get irq_count: %d\n", ret); 3303 goto out; 3304 } 3305 3306 ret = wm_adsp_buffer_update_avail(buf); 3307 if (ret < 0) { 3308 adsp_err(dsp, "Error reading avail: %d\n", ret); 3309 goto out; 3310 } 3311 3312 if (wm_adsp_fw[dsp->fw].voice_trigger && buf->irq_count == 2) 3313 ret = WM_ADSP_COMPR_VOICE_TRIGGER; 3314 3315 out_notify: 3316 if (compr && compr->stream) 3317 snd_compr_fragment_elapsed(compr->stream); 3318 3319 out: 3320 mutex_unlock(&dsp->pwr_lock); 3321 3322 return ret; 3323 } 3324 EXPORT_SYMBOL_GPL(wm_adsp_compr_handle_irq); 3325 3326 static int wm_adsp_buffer_reenable_irq(struct wm_adsp_compr_buf *buf) 3327 { 3328 if (buf->irq_count & 0x01) 3329 return 0; 3330 3331 adsp_dbg(buf->dsp, "Enable IRQ(0x%x) for next fragment\n", 3332 buf->irq_count); 3333 3334 buf->irq_count |= 0x01; 3335 3336 return wm_adsp_buffer_write(buf, HOST_BUFFER_FIELD(irq_ack), 3337 buf->irq_count); 3338 } 3339 3340 int wm_adsp_compr_pointer(struct snd_compr_stream *stream, 3341 struct snd_compr_tstamp *tstamp) 3342 { 3343 struct wm_adsp_compr *compr = stream->runtime->private_data; 3344 struct wm_adsp *dsp = compr->dsp; 3345 struct wm_adsp_compr_buf *buf; 3346 int ret = 0; 3347 3348 adsp_dbg(dsp, "Pointer request\n"); 3349 3350 mutex_lock(&dsp->pwr_lock); 3351 3352 buf = compr->buf; 3353 3354 if (!compr->buf || compr->buf->error) { 3355 snd_compr_stop_error(stream, SNDRV_PCM_STATE_XRUN); 3356 ret = -EIO; 3357 goto out; 3358 } 3359 3360 if (buf->avail < wm_adsp_compr_frag_words(compr)) { 3361 ret = wm_adsp_buffer_update_avail(buf); 3362 if (ret < 0) { 3363 adsp_err(dsp, "Error reading avail: %d\n", ret); 3364 goto out; 3365 } 3366 3367 /* 3368 * If we really have less than 1 fragment available tell the 3369 * DSP to inform us once a whole fragment is available. 3370 */ 3371 if (buf->avail < wm_adsp_compr_frag_words(compr)) { 3372 ret = wm_adsp_buffer_get_error(buf); 3373 if (ret < 0) { 3374 if (compr->buf->error) 3375 snd_compr_stop_error(stream, 3376 SNDRV_PCM_STATE_XRUN); 3377 goto out; 3378 } 3379 3380 ret = wm_adsp_buffer_reenable_irq(buf); 3381 if (ret < 0) { 3382 adsp_err(dsp, 3383 "Failed to re-enable buffer IRQ: %d\n", 3384 ret); 3385 goto out; 3386 } 3387 } 3388 } 3389 3390 tstamp->copied_total = compr->copied_total; 3391 tstamp->copied_total += buf->avail * WM_ADSP_DATA_WORD_SIZE; 3392 tstamp->sampling_rate = compr->sample_rate; 3393 3394 out: 3395 mutex_unlock(&dsp->pwr_lock); 3396 3397 return ret; 3398 } 3399 EXPORT_SYMBOL_GPL(wm_adsp_compr_pointer); 3400 3401 static int wm_adsp_buffer_capture_block(struct wm_adsp_compr *compr, int target) 3402 { 3403 struct wm_adsp_compr_buf *buf = compr->buf; 3404 u8 *pack_in = (u8 *)compr->raw_buf; 3405 u8 *pack_out = (u8 *)compr->raw_buf; 3406 unsigned int adsp_addr; 3407 int mem_type, nwords, max_read; 3408 int i, j, ret; 3409 3410 /* Calculate read parameters */ 3411 for (i = 0; i < wm_adsp_fw[buf->dsp->fw].caps->num_regions; ++i) 3412 if (buf->read_index < buf->regions[i].cumulative_size) 3413 break; 3414 3415 if (i == wm_adsp_fw[buf->dsp->fw].caps->num_regions) 3416 return -EINVAL; 3417 3418 mem_type = buf->regions[i].mem_type; 3419 adsp_addr = buf->regions[i].base_addr + 3420 (buf->read_index - buf->regions[i].offset); 3421 3422 max_read = wm_adsp_compr_frag_words(compr); 3423 nwords = buf->regions[i].cumulative_size - buf->read_index; 3424 3425 if (nwords > target) 3426 nwords = target; 3427 if (nwords > buf->avail) 3428 nwords = buf->avail; 3429 if (nwords > max_read) 3430 nwords = max_read; 3431 if (!nwords) 3432 return 0; 3433 3434 /* Read data from DSP */ 3435 ret = wm_adsp_read_data_block(buf->dsp, mem_type, adsp_addr, 3436 nwords, compr->raw_buf); 3437 if (ret < 0) 3438 return ret; 3439 3440 /* Remove the padding bytes from the data read from the DSP */ 3441 for (i = 0; i < nwords; i++) { 3442 for (j = 0; j < WM_ADSP_DATA_WORD_SIZE; j++) 3443 *pack_out++ = *pack_in++; 3444 3445 pack_in += sizeof(*(compr->raw_buf)) - WM_ADSP_DATA_WORD_SIZE; 3446 } 3447 3448 /* update read index to account for words read */ 3449 buf->read_index += nwords; 3450 if (buf->read_index == wm_adsp_buffer_size(buf)) 3451 buf->read_index = 0; 3452 3453 ret = wm_adsp_buffer_write(buf, HOST_BUFFER_FIELD(next_read_index), 3454 buf->read_index); 3455 if (ret < 0) 3456 return ret; 3457 3458 /* update avail to account for words read */ 3459 buf->avail -= nwords; 3460 3461 return nwords; 3462 } 3463 3464 static int wm_adsp_compr_read(struct wm_adsp_compr *compr, 3465 char __user *buf, size_t count) 3466 { 3467 struct wm_adsp *dsp = compr->dsp; 3468 int ntotal = 0; 3469 int nwords, nbytes; 3470 3471 adsp_dbg(dsp, "Requested read of %zu bytes\n", count); 3472 3473 if (!compr->buf || compr->buf->error) { 3474 snd_compr_stop_error(compr->stream, SNDRV_PCM_STATE_XRUN); 3475 return -EIO; 3476 } 3477 3478 count /= WM_ADSP_DATA_WORD_SIZE; 3479 3480 do { 3481 nwords = wm_adsp_buffer_capture_block(compr, count); 3482 if (nwords < 0) { 3483 adsp_err(dsp, "Failed to capture block: %d\n", nwords); 3484 return nwords; 3485 } 3486 3487 nbytes = nwords * WM_ADSP_DATA_WORD_SIZE; 3488 3489 adsp_dbg(dsp, "Read %d bytes\n", nbytes); 3490 3491 if (copy_to_user(buf + ntotal, compr->raw_buf, nbytes)) { 3492 adsp_err(dsp, "Failed to copy data to user: %d, %d\n", 3493 ntotal, nbytes); 3494 return -EFAULT; 3495 } 3496 3497 count -= nwords; 3498 ntotal += nbytes; 3499 } while (nwords > 0 && count > 0); 3500 3501 compr->copied_total += ntotal; 3502 3503 return ntotal; 3504 } 3505 3506 int wm_adsp_compr_copy(struct snd_compr_stream *stream, char __user *buf, 3507 size_t count) 3508 { 3509 struct wm_adsp_compr *compr = stream->runtime->private_data; 3510 struct wm_adsp *dsp = compr->dsp; 3511 int ret; 3512 3513 mutex_lock(&dsp->pwr_lock); 3514 3515 if (stream->direction == SND_COMPRESS_CAPTURE) 3516 ret = wm_adsp_compr_read(compr, buf, count); 3517 else 3518 ret = -ENOTSUPP; 3519 3520 mutex_unlock(&dsp->pwr_lock); 3521 3522 return ret; 3523 } 3524 EXPORT_SYMBOL_GPL(wm_adsp_compr_copy); 3525 3526 MODULE_LICENSE("GPL v2"); 3527