Lines Matching +full:spk +full:- +full:fmt
1 // SPDX-License-Identifier: GPL-2.0-only
3 * wm_adsp.c -- Wolfson ADSP support
36 #define adsp_crit(_dsp, fmt, ...) \
37 dev_crit(_dsp->cs_dsp.dev, "%s: " fmt, _dsp->cs_dsp.name, ##__VA_ARGS__)
38 #define adsp_err(_dsp, fmt, ...) \
39 dev_err(_dsp->cs_dsp.dev, "%s: " fmt, _dsp->cs_dsp.name, ##__VA_ARGS__)
40 #define adsp_warn(_dsp, fmt, ...) \
41 dev_warn(_dsp->cs_dsp.dev, "%s: " fmt, _dsp->cs_dsp.name, ##__VA_ARGS__)
42 #define adsp_info(_dsp, fmt, ...) \
43 dev_info(_dsp->cs_dsp.dev, "%s: " fmt, _dsp->cs_dsp.name, ##__VA_ARGS__)
44 #define adsp_dbg(_dsp, fmt, ...) \
45 dev_dbg(_dsp->cs_dsp.dev, "%s: " fmt, _dsp->cs_dsp.name, ##__VA_ARGS__)
47 #define compr_err(_obj, fmt, ...) \
48 adsp_err(_obj->dsp, "%s: " fmt, _obj->name ? _obj->name : "legacy", \
50 #define compr_dbg(_obj, fmt, ...) \
51 adsp_dbg(_obj->dsp, "%s: " fmt, _obj->name ? _obj->name : "legacy", \
135 __be32 irq_count; /* bits 1-31 count IRQ assertions */
281 [WM_ADSP_FW_MBC_VSS] = { .file = "mbc-vss" },
284 [WM_ADSP_FW_TX_SPK] = { .file = "tx-spk" },
286 [WM_ADSP_FW_RX_ANC] = { .file = "rx-anc" },
302 .file = "spk-prot",
307 [WM_ADSP_FW_SPK_CALI] = { .file = "spk-cali" },
308 [WM_ADSP_FW_SPK_DIAG] = { .file = "spk-diag" },
323 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
326 ucontrol->value.enumerated.item[0] = dsp[e->shift_l].fw;
336 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
340 if (ucontrol->value.enumerated.item[0] == dsp[e->shift_l].fw)
343 if (ucontrol->value.enumerated.item[0] >= WM_ADSP_NUM_FW)
344 return -EINVAL;
346 mutex_lock(&dsp[e->shift_l].cs_dsp.pwr_lock);
348 if (dsp[e->shift_l].cs_dsp.booted || !list_empty(&dsp[e->shift_l].compr_list))
349 ret = -EBUSY;
351 dsp[e->shift_l].fw = ucontrol->value.enumerated.item[0];
353 mutex_unlock(&dsp[e->shift_l].cs_dsp.pwr_lock);
379 (struct soc_bytes_ext *)kctl->private_value;
381 struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl;
383 switch (cs_ctl->type) {
385 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
386 uinfo->value.integer.min = CS_DSP_ACKED_CTL_MIN_VALUE;
387 uinfo->value.integer.max = CS_DSP_ACKED_CTL_MAX_VALUE;
388 uinfo->value.integer.step = 1;
389 uinfo->count = 1;
392 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
393 uinfo->count = cs_ctl->len;
404 (struct soc_bytes_ext *)kctl->private_value;
406 struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl;
407 char *p = ucontrol->value.bytes.data;
409 return cs_dsp_coeff_lock_and_write_ctrl(cs_ctl, 0, p, cs_ctl->len);
416 (struct soc_bytes_ext *)kctl->private_value;
418 struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl;
431 (struct soc_bytes_ext *)kctl->private_value;
433 struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl;
434 unsigned int val = ucontrol->value.integer.value[0];
440 mutex_lock(&cs_ctl->dsp->pwr_lock);
442 if (cs_ctl->enabled)
445 ret = -EPERM;
447 mutex_unlock(&cs_ctl->dsp->pwr_lock);
459 (struct soc_bytes_ext *)kctl->private_value;
461 struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl;
462 char *p = ucontrol->value.bytes.data;
464 return cs_dsp_coeff_lock_and_read_ctrl(cs_ctl, 0, p, cs_ctl->len);
471 (struct soc_bytes_ext *)kctl->private_value;
473 struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl;
476 mutex_lock(&cs_ctl->dsp->pwr_lock);
478 ret = cs_dsp_coeff_read_ctrl(cs_ctl, 0, cs_ctl->cache, size);
480 if (!ret && copy_to_user(bytes, cs_ctl->cache, size))
481 ret = -EFAULT;
483 mutex_unlock(&cs_ctl->dsp->pwr_lock);
493 * user-side assumptions that all controls are readable and that a
498 ucontrol->value.integer.value[0] = 0;
539 struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl;
540 struct wm_adsp *dsp = container_of(cs_ctl->dsp,
549 kcontrol->name = ctl->name;
550 kcontrol->info = wm_coeff_info;
551 kcontrol->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
552 kcontrol->tlv.c = snd_soc_bytes_tlv_callback;
553 kcontrol->private_value = (unsigned long)&ctl->bytes_ext;
554 kcontrol->access = wmfw_convert_flags(cs_ctl->flags, cs_ctl->len);
556 switch (cs_ctl->type) {
558 kcontrol->get = wm_coeff_get_acked;
559 kcontrol->put = wm_coeff_put_acked;
562 if (kcontrol->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
563 ctl->bytes_ext.max = cs_ctl->len;
564 ctl->bytes_ext.get = wm_coeff_tlv_get;
565 ctl->bytes_ext.put = wm_coeff_tlv_put;
567 kcontrol->get = wm_coeff_get;
568 kcontrol->put = wm_coeff_put;
573 snd_soc_add_component_controls(dsp->component, kcontrol, 1);
580 struct wm_adsp *dsp = container_of(cs_ctl->dsp, struct wm_adsp, cs_dsp);
581 struct cs_dsp *cs_dsp = &dsp->cs_dsp;
587 if (cs_ctl->flags & WMFW_CTL_FLAG_SYS)
590 region_name = cs_dsp_mem_region_name(cs_ctl->alg_region.type);
592 adsp_err(dsp, "Unknown region type: %d\n", cs_ctl->alg_region.type);
593 return -EINVAL;
596 switch (cs_dsp->wmfw_ver) {
600 "%s %s %x", cs_dsp->name, region_name,
601 cs_ctl->alg_region.alg);
605 "%s%c %.12s %x", cs_dsp->name, *region_name,
606 wm_adsp_fw_text[dsp->fw], cs_ctl->alg_region.alg);
610 "%s %.12s %x", cs_dsp->name,
611 wm_adsp_fw_text[dsp->fw], cs_ctl->alg_region.alg);
615 if (cs_ctl->subname) {
616 int avail = SNDRV_CTL_ELEM_ID_NAME_MAXLEN - ret - 2;
619 if (dsp->component->name_prefix)
620 avail -= strlen(dsp->component->name_prefix) + 1;
623 if (cs_ctl->subname_len > avail)
624 skip = cs_ctl->subname_len - avail;
626 snprintf(name + ret, SNDRV_CTL_ELEM_ID_NAME_MAXLEN - ret,
627 " %.*s", cs_ctl->subname_len - skip, cs_ctl->subname + skip);
632 return -ENOMEM;
633 ctl->cs_ctl = cs_ctl;
635 ctl->name = kmemdup(name, strlen(name) + 1, GFP_KERNEL);
636 if (!ctl->name) {
637 ret = -ENOMEM;
641 cs_ctl->priv = ctl;
643 INIT_WORK(&ctl->work, wm_adsp_ctl_work);
644 schedule_work(&ctl->work);
657 struct wm_adsp *dsp = container_of(cs_ctl->dsp, struct wm_adsp, cs_dsp);
659 if (dsp->control_add)
660 return (dsp->control_add)(dsp, cs_ctl);
667 struct wm_coeff_ctl *ctl = cs_ctl->priv;
669 cancel_work_sync(&ctl->work);
671 kfree(ctl->name);
681 mutex_lock(&dsp->cs_dsp.pwr_lock);
682 cs_ctl = cs_dsp_get_ctl(&dsp->cs_dsp, name, type, alg);
684 mutex_unlock(&dsp->cs_dsp.pwr_lock);
698 mutex_lock(&dsp->cs_dsp.pwr_lock);
699 ret = cs_dsp_coeff_read_ctrl(cs_dsp_get_ctl(&dsp->cs_dsp, name, type, alg),
701 mutex_unlock(&dsp->cs_dsp.pwr_lock);
726 struct cs_dsp *cs_dsp = &dsp->cs_dsp;
731 if (dsp->fwf_name)
732 fwf = dsp->fwf_name;
734 fwf = dsp->cs_dsp.name;
737 *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-%s.%s", dir, dsp->part,
738 fwf, wm_adsp_fw[dsp->fw].file, system_name,
741 *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s.%s", dir, dsp->part,
742 fwf, wm_adsp_fw[dsp->fw].file, system_name,
745 *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s.%s", dir, dsp->part, fwf,
746 wm_adsp_fw[dsp->fw].file, filetype);
749 return -ENOMEM;
752 * Make sure that filename is lower-case and any non alpha-numeric
762 *s = '-';
766 ret = firmware_request_nowarn(firmware, *filename, cs_dsp->dev);
785 const char *system_name = dsp->system_name;
786 const char *suffix = dsp->component->name_prefix;
789 if (dsp->fwf_suffix)
790 suffix = dsp->fwf_suffix;
820 /* Check system-specific bin without wmfw before falling back to generic */
821 if (dsp->wmfw_optional && system_name) {
847 if (!ret || dsp->wmfw_optional) {
853 adsp_err(dsp, "Failed to request firmware <%s>%s-%s-%s<-%s<%s>>.wmfw\n",
854 cirrus_dir, dsp->part,
855 dsp->fwf_name ? dsp->fwf_name : dsp->cs_dsp.name,
856 wm_adsp_fw[dsp->fw].file, system_name, suffix);
858 return -ENOENT;
863 INIT_LIST_HEAD(&dsp->compr_list);
864 INIT_LIST_HEAD(&dsp->buffer_list);
873 dsp->cs_dsp.client_ops = &wm_adsp1_client_ops;
875 ret = cs_dsp_adsp1_init(&dsp->cs_dsp);
887 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
889 struct wm_adsp *dsp = &dsps[w->shift];
896 dsp->component = component;
906 ret = cs_dsp_adsp1_power_up(&dsp->cs_dsp,
909 wm_adsp_fw_text[dsp->fw]);
916 cs_dsp_adsp1_power_down(&dsp->cs_dsp);
928 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
930 struct wm_adsp *dsp = &dsps[w->shift];
932 return cs_dsp_set_dspclk(&dsp->cs_dsp, freq);
942 (struct soc_mixer_control *)kcontrol->private_value;
943 struct wm_adsp *dsp = &dsps[mc->shift - 1];
945 ucontrol->value.integer.value[0] = dsp->preloaded;
958 (struct soc_mixer_control *)kcontrol->private_value;
959 struct wm_adsp *dsp = &dsps[mc->shift - 1];
962 if (dsp->preloaded == ucontrol->value.integer.value[0])
965 snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->cs_dsp.name);
967 if (ucontrol->value.integer.value[0] || dsp->toggle_preload)
974 flush_work(&dsp->boot_work);
976 dsp->preloaded = ucontrol->value.integer.value[0];
978 if (dsp->toggle_preload) {
1003 if (dsp->bin_mandatory && !coeff_firmware) {
1004 ret = -ENOENT;
1008 ret = cs_dsp_power_up(&dsp->cs_dsp,
1011 wm_adsp_fw_text[dsp->fw]);
1024 cs_dsp_power_down(&dsp->cs_dsp);
1040 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1042 struct wm_adsp *dsp = &dsps[w->shift];
1046 queue_work(system_dfl_wq, &dsp->boot_work);
1063 if (!dsp->pre_run)
1066 return (*dsp->pre_run)(dsp);
1073 if (wm_adsp_fw[dsp->fw].num_caps != 0)
1083 if (wm_adsp_fw[dsp->fw].num_caps != 0)
1086 dsp->fatal_error = false;
1091 flush_work(&dsp->boot_work);
1093 return cs_dsp_run(&dsp->cs_dsp);
1099 cs_dsp_stop(&dsp->cs_dsp);
1106 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1108 struct wm_adsp *dsp = &dsps[w->shift];
1126 if (!dsp->cs_dsp.no_core_startstop) {
1127 snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->cs_dsp.name);
1131 cs_dsp_init_debugfs(&dsp->cs_dsp, component->debugfs_root);
1133 dsp->component = component;
1141 cs_dsp_cleanup_debugfs(&dsp->cs_dsp);
1151 INIT_WORK(&dsp->boot_work, wm_adsp_boot_work);
1153 dsp->sys_config_size = sizeof(struct wm_adsp_system_config_xm_hdr);
1154 dsp->cs_dsp.client_ops = &wm_adsp2_client_ops;
1156 ret = cs_dsp_adsp2_init(&dsp->cs_dsp);
1168 INIT_WORK(&dsp->boot_work, wm_adsp_boot_work);
1170 dsp->sys_config_size = sizeof(struct wm_halo_system_config_xm_hdr);
1171 dsp->cs_dsp.client_ops = &wm_adsp2_client_ops;
1173 ret = cs_dsp_halo_init(&dsp->cs_dsp);
1183 cs_dsp_remove(&dsp->cs_dsp);
1189 return compr->buf != NULL;
1196 if (compr->dsp->fatal_error)
1197 return -EINVAL;
1199 list_for_each_entry(tmp, &compr->dsp->buffer_list, list) {
1200 if (!tmp->name || !strcmp(compr->name, tmp->name)) {
1207 return -EINVAL;
1209 compr->buf = buf;
1210 buf->compr = compr;
1221 if (compr->stream)
1222 snd_compr_fragment_elapsed(compr->stream);
1225 compr->buf->compr = NULL;
1226 compr->buf = NULL;
1233 struct snd_soc_pcm_runtime *rtd = stream->private_data;
1236 mutex_lock(&dsp->cs_dsp.pwr_lock);
1238 if (wm_adsp_fw[dsp->fw].num_caps == 0) {
1240 snd_soc_rtd_to_codec(rtd, 0)->name);
1241 ret = -ENXIO;
1245 if (wm_adsp_fw[dsp->fw].compr_direction != stream->direction) {
1247 snd_soc_rtd_to_codec(rtd, 0)->name);
1248 ret = -EINVAL;
1252 list_for_each_entry(tmp, &dsp->compr_list, list) {
1253 if (!strcmp(tmp->name, snd_soc_rtd_to_codec(rtd, 0)->name)) {
1255 snd_soc_rtd_to_codec(rtd, 0)->name);
1256 ret = -EBUSY;
1263 ret = -ENOMEM;
1267 compr->dsp = dsp;
1268 compr->stream = stream;
1269 compr->name = snd_soc_rtd_to_codec(rtd, 0)->name;
1271 list_add_tail(&compr->list, &dsp->compr_list);
1273 stream->runtime->private_data = compr;
1276 mutex_unlock(&dsp->cs_dsp.pwr_lock);
1285 struct wm_adsp_compr *compr = stream->runtime->private_data;
1286 struct wm_adsp *dsp = compr->dsp;
1288 mutex_lock(&dsp->cs_dsp.pwr_lock);
1291 list_del(&compr->list);
1293 kfree(compr->raw_buf);
1296 mutex_unlock(&dsp->cs_dsp.pwr_lock);
1305 struct wm_adsp_compr *compr = stream->runtime->private_data;
1306 struct wm_adsp *dsp = compr->dsp;
1311 if (params->buffer.fragment_size < WM_ADSP_MIN_FRAGMENT_SIZE ||
1312 params->buffer.fragment_size > WM_ADSP_MAX_FRAGMENT_SIZE ||
1313 params->buffer.fragments < WM_ADSP_MIN_FRAGMENTS ||
1314 params->buffer.fragments > WM_ADSP_MAX_FRAGMENTS ||
1315 params->buffer.fragment_size % CS_DSP_DATA_WORD_SIZE) {
1317 params->buffer.fragment_size,
1318 params->buffer.fragments);
1320 return -EINVAL;
1323 for (i = 0; i < wm_adsp_fw[dsp->fw].num_caps; i++) {
1324 caps = &wm_adsp_fw[dsp->fw].caps[i];
1325 desc = &caps->desc;
1327 if (caps->id != params->codec.id)
1330 if (stream->direction == SND_COMPRESS_PLAYBACK) {
1331 if (desc->max_ch < params->codec.ch_out)
1334 if (desc->max_ch < params->codec.ch_in)
1338 if (!(desc->formats & (1 << params->codec.format)))
1341 for (j = 0; j < desc->num_sample_rates; ++j)
1342 if (desc->sample_rates[j] == params->codec.sample_rate)
1346 compr_err(compr, "Invalid params id=%u ch=%u,%u rate=%u fmt=%u\n",
1347 params->codec.id, params->codec.ch_in, params->codec.ch_out,
1348 params->codec.sample_rate, params->codec.format);
1349 return -EINVAL;
1354 return compr->size.fragment_size / CS_DSP_DATA_WORD_SIZE;
1361 struct wm_adsp_compr *compr = stream->runtime->private_data;
1369 compr->size = params->buffer;
1372 compr->size.fragment_size, compr->size.fragments);
1374 size = wm_adsp_compr_frag_words(compr) * sizeof(*compr->raw_buf);
1375 compr->raw_buf = kmalloc(size, GFP_DMA | GFP_KERNEL);
1376 if (!compr->raw_buf)
1377 return -ENOMEM;
1379 compr->sample_rate = params->codec.sample_rate;
1389 struct wm_adsp_compr *compr = stream->runtime->private_data;
1390 int fw = compr->dsp->fw;
1395 caps->codecs[i] = wm_adsp_fw[fw].caps[i].id;
1397 caps->num_codecs = i;
1398 caps->direction = wm_adsp_fw[fw].compr_direction;
1400 caps->min_fragment_size = WM_ADSP_MIN_FRAGMENT_SIZE;
1401 caps->max_fragment_size = WM_ADSP_MAX_FRAGMENT_SIZE;
1402 caps->min_fragments = WM_ADSP_MIN_FRAGMENTS;
1403 caps->max_fragments = WM_ADSP_MAX_FRAGMENTS;
1413 return cs_dsp_read_data_word(&buf->dsp->cs_dsp, buf->host_buf_mem_type,
1414 buf->host_buf_ptr + field_offset, data);
1420 return cs_dsp_write_data_word(&buf->dsp->cs_dsp, buf->host_buf_mem_type,
1421 buf->host_buf_ptr + field_offset,
1427 const struct wm_adsp_fw_caps *caps = wm_adsp_fw[buf->dsp->fw].caps;
1432 buf->regions = kcalloc(caps->num_regions, sizeof(*buf->regions),
1434 if (!buf->regions)
1435 return -ENOMEM;
1437 for (i = 0; i < caps->num_regions; ++i) {
1438 region = &buf->regions[i];
1440 region->offset = offset;
1441 region->mem_type = caps->region_defs[i].mem_type;
1443 ret = wm_adsp_buffer_read(buf, caps->region_defs[i].base_offset,
1444 ®ion->base_addr);
1448 ret = wm_adsp_buffer_read(buf, caps->region_defs[i].size_offset,
1453 region->cumulative_size = offset;
1457 i, region->mem_type, region->base_addr,
1458 region->offset, region->cumulative_size);
1464 kfree(buf->regions);
1470 buf->irq_count = 0xFFFFFFFF;
1471 buf->read_index = -1;
1472 buf->avail = 0;
1483 buf->dsp = dsp;
1497 alg_region = cs_dsp_find_alg_region(&dsp->cs_dsp, WMFW_ADSP2_XM, dsp->cs_dsp.fw_id);
1500 return -EINVAL;
1503 xmalg = dsp->sys_config_size / sizeof(__be32);
1505 addr = alg_region->base + xmalg + ALG_XM_FIELD(magic);
1506 ret = cs_dsp_read_data_word(&dsp->cs_dsp, WMFW_ADSP2_XM, addr, &magic);
1511 return -ENODEV;
1515 return -ENOMEM;
1517 addr = alg_region->base + xmalg + ALG_XM_FIELD(host_buf_ptr);
1519 ret = cs_dsp_read_data_word(&dsp->cs_dsp, WMFW_ADSP2_XM, addr,
1520 &buf->host_buf_ptr);
1524 if (buf->host_buf_ptr)
1530 if (!buf->host_buf_ptr) {
1531 ret = -EIO;
1535 buf->host_buf_mem_type = WMFW_ADSP2_XM;
1541 list_add_tail(&buf->list, &dsp->buffer_list);
1543 compr_dbg(buf, "legacy host_buf_ptr=%x\n", buf->host_buf_ptr);
1557 struct wm_adsp *dsp = container_of(cs_ctl->dsp, struct wm_adsp, cs_dsp);
1563 min(cs_ctl->len, sizeof(coeff_v1)));
1575 return -EIO;
1580 return -ENOMEM;
1582 buf->host_buf_mem_type = cs_ctl->alg_region.type;
1583 buf->host_buf_ptr = be32_to_cpu(coeff_v1.host_buf_ptr);
1593 if (cs_ctl->len == 4)
1603 ret = -EINVAL;
1609 buf->name = kasprintf(GFP_KERNEL, "%s-dsp-%s", dsp->part,
1613 list_add_tail(&buf->list, &dsp->buffer_list);
1616 buf->host_buf_ptr, version);
1631 list_for_each_entry(cs_ctl, &dsp->cs_dsp.ctl_list, list) {
1632 if (cs_ctl->type != WMFW_CTL_TYPE_HOST_BUFFER)
1635 if (!cs_ctl->enabled)
1648 if (list_empty(&dsp->buffer_list)) {
1651 if (ret == -ENODEV)
1668 list_for_each_entry_safe(buf, tmp, &dsp->buffer_list, list) {
1669 wm_adsp_compr_detach(buf->compr);
1671 kfree(buf->name);
1672 kfree(buf->regions);
1673 list_del(&buf->list);
1684 ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(error), &buf->error);
1689 if (buf->error != 0) {
1690 compr_err(buf, "Buffer error occurred: %d\n", buf->error);
1691 return -EIO;
1700 struct wm_adsp_compr *compr = stream->runtime->private_data;
1701 struct wm_adsp *dsp = compr->dsp;
1706 mutex_lock(&dsp->cs_dsp.pwr_lock);
1719 ret = wm_adsp_buffer_get_error(compr->buf);
1724 ret = wm_adsp_buffer_write(compr->buf,
1735 wm_adsp_buffer_clear(compr->buf);
1738 ret = -EINVAL;
1742 mutex_unlock(&dsp->cs_dsp.pwr_lock);
1750 int last_region = wm_adsp_fw[buf->dsp->fw].caps->num_regions - 1;
1752 return buf->regions[last_region].cumulative_size;
1762 if (buf->read_index < 0) {
1776 buf->read_index = read_index;
1786 avail = write_index - buf->read_index;
1791 buf->read_index, write_index, avail * CS_DSP_DATA_WORD_SIZE);
1793 buf->avail = avail;
1804 mutex_lock(&dsp->cs_dsp.pwr_lock);
1806 if (list_empty(&dsp->buffer_list)) {
1807 ret = -ENODEV;
1813 list_for_each_entry(buf, &dsp->buffer_list, list) {
1814 compr = buf->compr;
1821 &buf->irq_count);
1833 if (wm_adsp_fw[dsp->fw].voice_trigger && buf->irq_count == 2)
1837 if (compr && compr->stream)
1838 snd_compr_fragment_elapsed(compr->stream);
1842 mutex_unlock(&dsp->cs_dsp.pwr_lock);
1850 if (buf->irq_count & 0x01)
1853 compr_dbg(buf, "Enable IRQ(0x%x) for next fragment\n", buf->irq_count);
1855 buf->irq_count |= 0x01;
1858 buf->irq_count);
1865 struct wm_adsp_compr *compr = stream->runtime->private_data;
1866 struct wm_adsp *dsp = compr->dsp;
1872 mutex_lock(&dsp->cs_dsp.pwr_lock);
1874 buf = compr->buf;
1876 if (dsp->fatal_error || !buf || buf->error) {
1878 ret = -EIO;
1882 if (buf->avail < wm_adsp_compr_frag_words(compr)) {
1893 if (buf->avail < wm_adsp_compr_frag_words(compr)) {
1896 if (buf->error)
1904 compr_err(compr, "Failed to re-enable buffer IRQ: %d\n",
1911 tstamp->copied_total = compr->copied_total;
1912 tstamp->copied_total += buf->avail * CS_DSP_DATA_WORD_SIZE;
1913 tstamp->sampling_rate = compr->sample_rate;
1916 mutex_unlock(&dsp->cs_dsp.pwr_lock);
1924 struct wm_adsp_compr_buf *buf = compr->buf;
1930 for (i = 0; i < wm_adsp_fw[buf->dsp->fw].caps->num_regions; ++i)
1931 if (buf->read_index < buf->regions[i].cumulative_size)
1934 if (i == wm_adsp_fw[buf->dsp->fw].caps->num_regions)
1935 return -EINVAL;
1937 mem_type = buf->regions[i].mem_type;
1938 adsp_addr = buf->regions[i].base_addr +
1939 (buf->read_index - buf->regions[i].offset);
1942 nwords = buf->regions[i].cumulative_size - buf->read_index;
1946 if (nwords > buf->avail)
1947 nwords = buf->avail;
1954 ret = cs_dsp_read_raw_data_block(&buf->dsp->cs_dsp, mem_type, adsp_addr,
1955 nwords, (__be32 *)compr->raw_buf);
1959 cs_dsp_remove_padding(compr->raw_buf, nwords);
1962 buf->read_index += nwords;
1963 if (buf->read_index == wm_adsp_buffer_size(buf))
1964 buf->read_index = 0;
1967 buf->read_index);
1972 buf->avail -= nwords;
1980 struct wm_adsp *dsp = compr->dsp;
1986 if (dsp->fatal_error || !compr->buf || compr->buf->error) {
1987 snd_compr_stop_error(compr->stream, SNDRV_PCM_STATE_XRUN);
1988 return -EIO;
2005 if (copy_to_user(buf + ntotal, compr->raw_buf, nbytes)) {
2008 return -EFAULT;
2011 count -= nwords;
2015 compr->copied_total += ntotal;
2024 struct wm_adsp_compr *compr = stream->runtime->private_data;
2025 struct wm_adsp *dsp = compr->dsp;
2028 mutex_lock(&dsp->cs_dsp.pwr_lock);
2030 if (stream->direction == SND_COMPRESS_CAPTURE)
2033 ret = -ENOTSUPP;
2035 mutex_unlock(&dsp->cs_dsp.pwr_lock);
2046 dsp->fatal_error = true;
2048 list_for_each_entry(compr, &dsp->compr_list, list) {
2049 if (compr->stream)
2050 snd_compr_fragment_elapsed(compr->stream);
2058 cs_dsp_adsp2_bus_error(&dsp->cs_dsp);
2068 cs_dsp_halo_bus_error(&dsp->cs_dsp);
2078 cs_dsp_halo_wdt_expire(&dsp->cs_dsp);