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