Lines Matching +full:ctrl +full:- +full:len

1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Copyright 2009-2014 Analog Devices Inc.
87 __le16 len; member
93 const uint8_t data[], size_t len) in sigmadsp_write() argument
95 return sigmadsp->write(sigmadsp->control_data, addr, data, len); in sigmadsp_write()
99 uint8_t data[], size_t len) in sigmadsp_read() argument
101 return sigmadsp->read(sigmadsp->control_data, addr, data, len); in sigmadsp_read()
107 struct sigmadsp_control *ctrl = (void *)kcontrol->private_value; in sigmadsp_ctrl_info() local
109 info->type = SNDRV_CTL_ELEM_TYPE_BYTES; in sigmadsp_ctrl_info()
110 info->count = ctrl->num_bytes; in sigmadsp_ctrl_info()
116 struct sigmadsp_control *ctrl, void *data) in sigmadsp_ctrl_write() argument
119 if (ctrl->num_bytes <= 20 && sigmadsp->ops && sigmadsp->ops->safeload) in sigmadsp_ctrl_write()
120 return sigmadsp->ops->safeload(sigmadsp, ctrl->addr, data, in sigmadsp_ctrl_write()
121 ctrl->num_bytes); in sigmadsp_ctrl_write()
123 return sigmadsp_write(sigmadsp, ctrl->addr, data, in sigmadsp_ctrl_write()
124 ctrl->num_bytes); in sigmadsp_ctrl_write()
130 struct sigmadsp_control *ctrl = (void *)kcontrol->private_value; in sigmadsp_ctrl_put() local
135 mutex_lock(&sigmadsp->lock); in sigmadsp_ctrl_put()
137 data = ucontrol->value.bytes.data; in sigmadsp_ctrl_put()
139 if (!(kcontrol->vd[0].access & SNDRV_CTL_ELEM_ACCESS_INACTIVE)) in sigmadsp_ctrl_put()
140 ret = sigmadsp_ctrl_write(sigmadsp, ctrl, data); in sigmadsp_ctrl_put()
143 memcpy(ctrl->cache, data, ctrl->num_bytes); in sigmadsp_ctrl_put()
144 ctrl->cached = true; in sigmadsp_ctrl_put()
147 mutex_unlock(&sigmadsp->lock); in sigmadsp_ctrl_put()
155 struct sigmadsp_control *ctrl = (void *)kcontrol->private_value; in sigmadsp_ctrl_get() local
159 mutex_lock(&sigmadsp->lock); in sigmadsp_ctrl_get()
161 if (!ctrl->cached) { in sigmadsp_ctrl_get()
162 ret = sigmadsp_read(sigmadsp, ctrl->addr, ctrl->cache, in sigmadsp_ctrl_get()
163 ctrl->num_bytes); in sigmadsp_ctrl_get()
167 ctrl->cached = true; in sigmadsp_ctrl_get()
168 memcpy(ucontrol->value.bytes.data, ctrl->cache, in sigmadsp_ctrl_get()
169 ctrl->num_bytes); in sigmadsp_ctrl_get()
172 mutex_unlock(&sigmadsp->lock); in sigmadsp_ctrl_get()
179 struct sigmadsp_control *ctrl = (void *)kcontrol->private_value; in sigmadsp_control_free() local
181 ctrl->kcontrol = NULL; in sigmadsp_control_free()
184 static bool sigma_fw_validate_control_name(const char *name, unsigned int len) in sigma_fw_validate_control_name() argument
188 for (i = 0; i < len; i++) { in sigma_fw_validate_control_name()
201 struct sigmadsp_control *ctrl; in sigma_fw_load_control() local
208 return -EINVAL; in sigma_fw_load_control()
212 name_len = length - sizeof(*ctrl_chunk); in sigma_fw_load_control()
214 name_len = SNDRV_CTL_ELEM_ID_NAME_MAXLEN - 1; in sigma_fw_load_control()
216 /* Make sure there are no non-displayable characaters in the string */ in sigma_fw_load_control()
217 if (!sigma_fw_validate_control_name(ctrl_chunk->name, name_len)) in sigma_fw_load_control()
218 return -EINVAL; in sigma_fw_load_control()
220 num_bytes = le16_to_cpu(ctrl_chunk->num_bytes); in sigma_fw_load_control()
221 ctrl = kzalloc(sizeof(*ctrl) + num_bytes, GFP_KERNEL); in sigma_fw_load_control()
222 if (!ctrl) in sigma_fw_load_control()
223 return -ENOMEM; in sigma_fw_load_control()
227 ret = -ENOMEM; in sigma_fw_load_control()
230 memcpy(name, ctrl_chunk->name, name_len); in sigma_fw_load_control()
232 ctrl->name = name; in sigma_fw_load_control()
234 ctrl->addr = le16_to_cpu(ctrl_chunk->addr); in sigma_fw_load_control()
235 ctrl->num_bytes = num_bytes; in sigma_fw_load_control()
236 ctrl->samplerates = le32_to_cpu(chunk->samplerates); in sigma_fw_load_control()
238 list_add_tail(&ctrl->head, &sigmadsp->ctrl_list); in sigma_fw_load_control()
243 kfree(ctrl); in sigma_fw_load_control()
255 return -EINVAL; in sigma_fw_load_data()
259 length -= sizeof(*data_chunk); in sigma_fw_load_data()
263 return -ENOMEM; in sigma_fw_load_data()
265 data->addr = le16_to_cpu(data_chunk->addr); in sigma_fw_load_data()
266 data->length = length; in sigma_fw_load_data()
267 data->samplerates = le32_to_cpu(chunk->samplerates); in sigma_fw_load_data()
268 memcpy(data->data, data_chunk->data, length); in sigma_fw_load_data()
269 list_add_tail(&data->head, &sigmadsp->data_list); in sigma_fw_load_data()
284 num_rates = (length - sizeof(*rate_chunk)) / sizeof(__le32); in sigma_fw_load_samplerates()
287 return -EINVAL; in sigma_fw_load_samplerates()
290 if (sigmadsp->rate_constraints.count) in sigma_fw_load_samplerates()
291 return -EINVAL; in sigma_fw_load_samplerates()
295 return -ENOMEM; in sigma_fw_load_samplerates()
298 rates[i] = le32_to_cpu(rate_chunk->samplerates[i]); in sigma_fw_load_samplerates()
300 sigmadsp->rate_constraints.count = num_rates; in sigma_fw_load_samplerates()
301 sigmadsp->rate_constraints.list = rates; in sigma_fw_load_samplerates()
317 if (fw->size < sizeof(*chunk) + sizeof(struct sigma_firmware_header)) in sigmadsp_fw_load_v2()
322 while (pos < fw->size - sizeof(*chunk)) { in sigmadsp_fw_load_v2()
323 chunk = (struct sigma_fw_chunk *)(fw->data + pos); in sigmadsp_fw_load_v2()
325 length = le32_to_cpu(chunk->length); in sigmadsp_fw_load_v2()
327 if (length > fw->size - pos || length < sizeof(*chunk)) in sigmadsp_fw_load_v2()
328 return -EINVAL; in sigmadsp_fw_load_v2()
330 switch (le32_to_cpu(chunk->tag)) { in sigmadsp_fw_load_v2()
341 dev_warn(sigmadsp->dev, "Unknown chunk type: %d\n", in sigmadsp_fw_load_v2()
342 chunk->tag); in sigmadsp_fw_load_v2()
362 return (sa->len_hi << 16) | le16_to_cpu(sa->len); in sigma_action_len()
369 switch (sa->instr) { in sigma_action_size()
391 size_t len = sigma_action_len(sa); in process_sigma_action() local
394 pr_debug("%s: instr:%i addr:%#x len:%zu\n", __func__, in process_sigma_action()
395 sa->instr, sa->addr, len); in process_sigma_action()
397 switch (sa->instr) { in process_sigma_action()
401 if (len < 3) in process_sigma_action()
402 return -EINVAL; in process_sigma_action()
404 data = kzalloc(sizeof(*data) + len - 2, GFP_KERNEL); in process_sigma_action()
406 return -ENOMEM; in process_sigma_action()
408 data->addr = be16_to_cpu(sa->addr); in process_sigma_action()
409 data->length = len - 2; in process_sigma_action()
410 memcpy(data->data, sa->payload, data->length); in process_sigma_action()
411 list_add_tail(&data->head, &sigmadsp->data_list); in process_sigma_action()
416 return -EINVAL; in process_sigma_action()
431 while (pos + sizeof(*sa) <= fw->size) { in sigmadsp_fw_load_v1()
432 sa = (struct sigma_action *)(fw->data + pos); in sigmadsp_fw_load_v1()
436 if (pos > fw->size || size == 0) in sigmadsp_fw_load_v1()
447 if (pos != fw->size) in sigmadsp_fw_load_v1()
448 return -EINVAL; in sigmadsp_fw_load_v1()
455 struct sigmadsp_control *ctrl, *_ctrl; in sigmadsp_firmware_release() local
458 list_for_each_entry_safe(ctrl, _ctrl, &sigmadsp->ctrl_list, head) { in sigmadsp_firmware_release()
459 kfree(ctrl->name); in sigmadsp_firmware_release()
460 kfree(ctrl); in sigmadsp_firmware_release()
463 list_for_each_entry_safe(data, _data, &sigmadsp->data_list, head) in sigmadsp_firmware_release()
466 INIT_LIST_HEAD(&sigmadsp->ctrl_list); in sigmadsp_firmware_release()
467 INIT_LIST_HEAD(&sigmadsp->data_list); in sigmadsp_firmware_release()
483 ret = request_firmware(&fw, name, sigmadsp->dev); in sigmadsp_firmware_load()
490 ret = -EINVAL; in sigmadsp_firmware_load()
498 if (fw->size < sizeof(*ssfw_head) || fw->size >= 0x4000000) { in sigmadsp_firmware_load()
499 dev_err(sigmadsp->dev, "Failed to load firmware: Invalid size\n"); in sigmadsp_firmware_load()
503 ssfw_head = (void *)fw->data; in sigmadsp_firmware_load()
504 if (memcmp(ssfw_head->magic, SIGMA_MAGIC, ARRAY_SIZE(ssfw_head->magic))) { in sigmadsp_firmware_load()
505 dev_err(sigmadsp->dev, "Failed to load firmware: Invalid magic\n"); in sigmadsp_firmware_load()
509 crc = crc32(0, fw->data + sizeof(*ssfw_head), in sigmadsp_firmware_load()
510 fw->size - sizeof(*ssfw_head)); in sigmadsp_firmware_load()
512 if (crc != le32_to_cpu(ssfw_head->crc)) { in sigmadsp_firmware_load()
513 dev_err(sigmadsp->dev, "Failed to load firmware: Wrong crc checksum: expected %x got %x\n", in sigmadsp_firmware_load()
514 le32_to_cpu(ssfw_head->crc), crc); in sigmadsp_firmware_load()
518 switch (ssfw_head->version) { in sigmadsp_firmware_load()
526 dev_err(sigmadsp->dev, in sigmadsp_firmware_load()
528 ssfw_head->version); in sigmadsp_firmware_load()
529 ret = -EINVAL; in sigmadsp_firmware_load()
545 sigmadsp->ops = ops; in sigmadsp_init()
546 sigmadsp->dev = dev; in sigmadsp_init()
548 INIT_LIST_HEAD(&sigmadsp->ctrl_list); in sigmadsp_init()
549 INIT_LIST_HEAD(&sigmadsp->data_list); in sigmadsp_init()
550 mutex_init(&sigmadsp->lock); in sigmadsp_init()
556 * devm_sigmadsp_init() - Initialize SigmaDSP instance
574 return ERR_PTR(-ENOMEM); in devm_sigmadsp_init()
592 for (i = 0; i < sigmadsp->rate_constraints.count; i++) { in sigmadsp_rate_to_index()
593 if (sigmadsp->rate_constraints.list[i] == rate) in sigmadsp_rate_to_index()
597 return -EINVAL; in sigmadsp_rate_to_index()
608 if (sigmadsp->rate_constraints.count) { in sigmadsp_get_samplerate_mask()
630 struct sigmadsp_control *ctrl, unsigned int samplerate_mask) in sigmadsp_alloc_control() argument
637 template.name = ctrl->name; in sigmadsp_alloc_control()
641 template.private_value = (unsigned long)ctrl; in sigmadsp_alloc_control()
643 if (!sigmadsp_samplerate_valid(ctrl->samplerates, samplerate_mask)) in sigmadsp_alloc_control()
648 return -ENOMEM; in sigmadsp_alloc_control()
650 kcontrol->private_free = sigmadsp_control_free; in sigmadsp_alloc_control()
651 ctrl->kcontrol = kcontrol; in sigmadsp_alloc_control()
653 return snd_ctl_add(sigmadsp->component->card->snd_card, kcontrol); in sigmadsp_alloc_control()
657 struct sigmadsp_control *ctrl, unsigned int samplerate_mask) in sigmadsp_activate_ctrl() argument
659 struct snd_card *card = sigmadsp->component->card->snd_card; in sigmadsp_activate_ctrl()
665 active = sigmadsp_samplerate_valid(ctrl->samplerates, samplerate_mask); in sigmadsp_activate_ctrl()
667 down_write(&card->controls_rwsem); in sigmadsp_activate_ctrl()
668 if (!ctrl->kcontrol) { in sigmadsp_activate_ctrl()
669 up_write(&card->controls_rwsem); in sigmadsp_activate_ctrl()
673 id = ctrl->kcontrol->id; in sigmadsp_activate_ctrl()
674 vd = &ctrl->kcontrol->vd[0]; in sigmadsp_activate_ctrl()
675 if (active == (bool)(vd->access & SNDRV_CTL_ELEM_ACCESS_INACTIVE)) { in sigmadsp_activate_ctrl()
676 vd->access ^= SNDRV_CTL_ELEM_ACCESS_INACTIVE; in sigmadsp_activate_ctrl()
679 up_write(&card->controls_rwsem); in sigmadsp_activate_ctrl()
682 mutex_lock(&sigmadsp->lock); in sigmadsp_activate_ctrl()
683 if (ctrl->cached) in sigmadsp_activate_ctrl()
684 sigmadsp_ctrl_write(sigmadsp, ctrl, ctrl->cache); in sigmadsp_activate_ctrl()
685 mutex_unlock(&sigmadsp->lock); in sigmadsp_activate_ctrl()
693 * sigmadsp_attach() - Attach a sigmadsp instance to a ASoC component
706 struct sigmadsp_control *ctrl; in sigmadsp_attach() local
710 sigmadsp->component = component; in sigmadsp_attach()
713 sigmadsp->current_samplerate); in sigmadsp_attach()
715 list_for_each_entry(ctrl, &sigmadsp->ctrl_list, head) { in sigmadsp_attach()
716 ret = sigmadsp_alloc_control(sigmadsp, ctrl, samplerate_mask); in sigmadsp_attach()
726 * sigmadsp_setup() - Setup the DSP for the specified samplerate
738 struct sigmadsp_control *ctrl; in sigmadsp_setup() local
743 if (sigmadsp->current_samplerate == samplerate) in sigmadsp_setup()
748 return -EINVAL; in sigmadsp_setup()
750 list_for_each_entry(data, &sigmadsp->data_list, head) { in sigmadsp_setup()
751 if (!sigmadsp_samplerate_valid(data->samplerates, in sigmadsp_setup()
754 ret = sigmadsp_write(sigmadsp, data->addr, data->data, in sigmadsp_setup()
755 data->length); in sigmadsp_setup()
760 list_for_each_entry(ctrl, &sigmadsp->ctrl_list, head) in sigmadsp_setup()
761 sigmadsp_activate_ctrl(sigmadsp, ctrl, samplerate_mask); in sigmadsp_setup()
763 sigmadsp->current_samplerate = samplerate; in sigmadsp_setup()
774 * sigmadsp_reset() - Notify the sigmadsp instance that the DSP has been reset
778 * memory need to be re-loaded.
782 struct sigmadsp_control *ctrl; in sigmadsp_reset() local
784 list_for_each_entry(ctrl, &sigmadsp->ctrl_list, head) in sigmadsp_reset()
785 sigmadsp_activate_ctrl(sigmadsp, ctrl, false); in sigmadsp_reset()
787 sigmadsp->current_samplerate = 0; in sigmadsp_reset()
792 * sigmadsp_restrict_params() - Applies DSP firmware specific constraints
804 if (sigmadsp->rate_constraints.count == 0) in sigmadsp_restrict_params()
807 return snd_pcm_hw_constraint_list(substream->runtime, 0, in sigmadsp_restrict_params()
808 SNDRV_PCM_HW_PARAM_RATE, &sigmadsp->rate_constraints); in sigmadsp_restrict_params()