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

1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Copyright 2009-2014 Analog Devices Inc.
90 __le16 len; member
96 const uint8_t data[], size_t len) in sigmadsp_write() argument
98 return sigmadsp->write(sigmadsp->control_data, addr, data, len); in sigmadsp_write()
102 uint8_t data[], size_t len) in sigmadsp_read() argument
104 return sigmadsp->read(sigmadsp->control_data, addr, data, len); in sigmadsp_read()
110 struct sigmadsp_control *ctrl = (void *)kcontrol->private_value; in sigmadsp_ctrl_info() local
112 info->type = SNDRV_CTL_ELEM_TYPE_BYTES; in sigmadsp_ctrl_info()
113 info->count = ctrl->num_bytes; in sigmadsp_ctrl_info()
119 struct sigmadsp_control *ctrl, void *data) in sigmadsp_ctrl_write() argument
122 if (ctrl->num_bytes <= 20 && sigmadsp->ops && sigmadsp->ops->safeload) in sigmadsp_ctrl_write()
123 return sigmadsp->ops->safeload(sigmadsp, ctrl->addr, data, in sigmadsp_ctrl_write()
124 ctrl->num_bytes); in sigmadsp_ctrl_write()
126 return sigmadsp_write(sigmadsp, ctrl->addr, data, in sigmadsp_ctrl_write()
127 ctrl->num_bytes); in sigmadsp_ctrl_write()
133 struct sigmadsp_control *ctrl = (void *)kcontrol->private_value; in sigmadsp_ctrl_put() local
138 mutex_lock(&sigmadsp->lock); in sigmadsp_ctrl_put()
140 data = ucontrol->value.bytes.data; in sigmadsp_ctrl_put()
142 if (!(kcontrol->vd[0].access & SNDRV_CTL_ELEM_ACCESS_INACTIVE)) in sigmadsp_ctrl_put()
143 ret = sigmadsp_ctrl_write(sigmadsp, ctrl, data); in sigmadsp_ctrl_put()
146 memcpy(ctrl->cache, data, ctrl->num_bytes); in sigmadsp_ctrl_put()
147 if (!ctrl->is_readback) in sigmadsp_ctrl_put()
148 ctrl->cached = true; in sigmadsp_ctrl_put()
151 mutex_unlock(&sigmadsp->lock); in sigmadsp_ctrl_put()
159 struct sigmadsp_control *ctrl = (void *)kcontrol->private_value; in sigmadsp_ctrl_get() local
163 mutex_lock(&sigmadsp->lock); in sigmadsp_ctrl_get()
165 if (!ctrl->cached) { in sigmadsp_ctrl_get()
166 ret = sigmadsp_read(sigmadsp, ctrl->addr, ctrl->cache, in sigmadsp_ctrl_get()
167 ctrl->num_bytes); in sigmadsp_ctrl_get()
171 if (!ctrl->is_readback) in sigmadsp_ctrl_get()
172 ctrl->cached = true; in sigmadsp_ctrl_get()
173 memcpy(ucontrol->value.bytes.data, ctrl->cache, in sigmadsp_ctrl_get()
174 ctrl->num_bytes); in sigmadsp_ctrl_get()
177 mutex_unlock(&sigmadsp->lock); in sigmadsp_ctrl_get()
184 struct sigmadsp_control *ctrl = (void *)kcontrol->private_value; in sigmadsp_control_free() local
186 ctrl->kcontrol = NULL; in sigmadsp_control_free()
189 static bool sigma_fw_validate_control_name(const char *name, unsigned int len) in sigma_fw_validate_control_name() argument
193 for (i = 0; i < len; i++) { in sigma_fw_validate_control_name()
206 struct sigmadsp_control *ctrl; in sigma_fw_load_control() local
213 return -EINVAL; in sigma_fw_load_control()
217 name_len = length - sizeof(*ctrl_chunk); in sigma_fw_load_control()
219 name_len = SNDRV_CTL_ELEM_ID_NAME_MAXLEN - 1; in sigma_fw_load_control()
221 /* Make sure there are no non-displayable characaters in the string */ in sigma_fw_load_control()
222 if (!sigma_fw_validate_control_name(ctrl_chunk->name, name_len)) in sigma_fw_load_control()
223 return -EINVAL; in sigma_fw_load_control()
225 num_bytes = le16_to_cpu(ctrl_chunk->num_bytes); in sigma_fw_load_control()
226 ctrl = kzalloc(sizeof(*ctrl) + num_bytes, GFP_KERNEL); in sigma_fw_load_control()
227 if (!ctrl) in sigma_fw_load_control()
228 return -ENOMEM; in sigma_fw_load_control()
230 name = kmemdup_nul(ctrl_chunk->name, name_len, GFP_KERNEL); in sigma_fw_load_control()
232 ret = -ENOMEM; in sigma_fw_load_control()
235 ctrl->name = name; in sigma_fw_load_control()
238 * Readbacks doesn't work with non-volatile controls, since the in sigma_fw_load_control()
242 if (ctrl->name && strncmp(ctrl->name, READBACK_CTRL_NAME, in sigma_fw_load_control()
243 (sizeof(READBACK_CTRL_NAME) - 1)) == 0) in sigma_fw_load_control()
244 ctrl->is_readback = true; in sigma_fw_load_control()
246 ctrl->addr = le16_to_cpu(ctrl_chunk->addr); in sigma_fw_load_control()
247 ctrl->num_bytes = num_bytes; in sigma_fw_load_control()
248 ctrl->samplerates = le32_to_cpu(chunk->samplerates); in sigma_fw_load_control()
250 list_add_tail(&ctrl->head, &sigmadsp->ctrl_list); in sigma_fw_load_control()
255 kfree(ctrl); in sigma_fw_load_control()
267 return -EINVAL; in sigma_fw_load_data()
271 length -= sizeof(*data_chunk); in sigma_fw_load_data()
275 return -ENOMEM; in sigma_fw_load_data()
277 data->addr = le16_to_cpu(data_chunk->addr); in sigma_fw_load_data()
278 data->length = length; in sigma_fw_load_data()
279 data->samplerates = le32_to_cpu(chunk->samplerates); in sigma_fw_load_data()
280 memcpy(data->data, data_chunk->data, length); in sigma_fw_load_data()
281 list_add_tail(&data->head, &sigmadsp->data_list); in sigma_fw_load_data()
296 num_rates = (length - sizeof(*rate_chunk)) / sizeof(__le32); in sigma_fw_load_samplerates()
299 return -EINVAL; in sigma_fw_load_samplerates()
302 if (sigmadsp->rate_constraints.count) in sigma_fw_load_samplerates()
303 return -EINVAL; in sigma_fw_load_samplerates()
307 return -ENOMEM; in sigma_fw_load_samplerates()
310 rates[i] = le32_to_cpu(rate_chunk->samplerates[i]); in sigma_fw_load_samplerates()
312 sigmadsp->rate_constraints.count = num_rates; in sigma_fw_load_samplerates()
313 sigmadsp->rate_constraints.list = rates; in sigma_fw_load_samplerates()
329 if (fw->size < sizeof(*chunk) + sizeof(struct sigma_firmware_header)) in sigmadsp_fw_load_v2()
334 while (pos < fw->size - sizeof(*chunk)) { in sigmadsp_fw_load_v2()
335 chunk = (struct sigma_fw_chunk *)(fw->data + pos); in sigmadsp_fw_load_v2()
337 length = le32_to_cpu(chunk->length); in sigmadsp_fw_load_v2()
339 if (length > fw->size - pos || length < sizeof(*chunk)) in sigmadsp_fw_load_v2()
340 return -EINVAL; in sigmadsp_fw_load_v2()
342 switch (le32_to_cpu(chunk->tag)) { in sigmadsp_fw_load_v2()
353 dev_warn(sigmadsp->dev, "Unknown chunk type: %d\n", in sigmadsp_fw_load_v2()
354 chunk->tag); in sigmadsp_fw_load_v2()
374 return (sa->len_hi << 16) | le16_to_cpu(sa->len); in sigma_action_len()
381 switch (sa->instr) { in sigma_action_size()
403 size_t len = sigma_action_len(sa); in process_sigma_action() local
406 pr_debug("%s: instr:%i addr:%#x len:%zu\n", __func__, in process_sigma_action()
407 sa->instr, sa->addr, len); in process_sigma_action()
409 switch (sa->instr) { in process_sigma_action()
413 if (len < 3) in process_sigma_action()
414 return -EINVAL; in process_sigma_action()
416 data = kzalloc(struct_size(data, data, size_sub(len, 2)), in process_sigma_action()
419 return -ENOMEM; in process_sigma_action()
421 data->addr = be16_to_cpu(sa->addr); in process_sigma_action()
422 data->length = len - 2; in process_sigma_action()
423 memcpy(data->data, sa->payload, data->length); in process_sigma_action()
424 list_add_tail(&data->head, &sigmadsp->data_list); in process_sigma_action()
429 return -EINVAL; in process_sigma_action()
444 while (pos + sizeof(*sa) <= fw->size) { in sigmadsp_fw_load_v1()
445 sa = (struct sigma_action *)(fw->data + pos); in sigmadsp_fw_load_v1()
449 if (pos > fw->size || size == 0) in sigmadsp_fw_load_v1()
460 if (pos != fw->size) in sigmadsp_fw_load_v1()
461 return -EINVAL; in sigmadsp_fw_load_v1()
468 struct sigmadsp_control *ctrl, *_ctrl; in sigmadsp_firmware_release() local
471 list_for_each_entry_safe(ctrl, _ctrl, &sigmadsp->ctrl_list, head) { in sigmadsp_firmware_release()
472 kfree(ctrl->name); in sigmadsp_firmware_release()
473 kfree(ctrl); in sigmadsp_firmware_release()
476 list_for_each_entry_safe(data, _data, &sigmadsp->data_list, head) in sigmadsp_firmware_release()
479 INIT_LIST_HEAD(&sigmadsp->ctrl_list); in sigmadsp_firmware_release()
480 INIT_LIST_HEAD(&sigmadsp->data_list); in sigmadsp_firmware_release()
496 ret = request_firmware(&fw, name, sigmadsp->dev); in sigmadsp_firmware_load()
503 ret = -EINVAL; in sigmadsp_firmware_load()
511 if (fw->size < sizeof(*ssfw_head) || fw->size >= 0x4000000) { in sigmadsp_firmware_load()
512 dev_err(sigmadsp->dev, "Failed to load firmware: Invalid size\n"); in sigmadsp_firmware_load()
516 ssfw_head = (void *)fw->data; in sigmadsp_firmware_load()
517 if (memcmp(ssfw_head->magic, SIGMA_MAGIC, ARRAY_SIZE(ssfw_head->magic))) { in sigmadsp_firmware_load()
518 dev_err(sigmadsp->dev, "Failed to load firmware: Invalid magic\n"); in sigmadsp_firmware_load()
522 crc = crc32(0, fw->data + sizeof(*ssfw_head), in sigmadsp_firmware_load()
523 fw->size - sizeof(*ssfw_head)); in sigmadsp_firmware_load()
525 if (crc != le32_to_cpu(ssfw_head->crc)) { in sigmadsp_firmware_load()
526 dev_err(sigmadsp->dev, "Failed to load firmware: Wrong crc checksum: expected %x got %x\n", in sigmadsp_firmware_load()
527 le32_to_cpu(ssfw_head->crc), crc); in sigmadsp_firmware_load()
531 switch (ssfw_head->version) { in sigmadsp_firmware_load()
539 dev_err(sigmadsp->dev, in sigmadsp_firmware_load()
541 ssfw_head->version); in sigmadsp_firmware_load()
542 ret = -EINVAL; in sigmadsp_firmware_load()
558 sigmadsp->ops = ops; in sigmadsp_init()
559 sigmadsp->dev = dev; in sigmadsp_init()
561 INIT_LIST_HEAD(&sigmadsp->ctrl_list); in sigmadsp_init()
562 INIT_LIST_HEAD(&sigmadsp->data_list); in sigmadsp_init()
563 mutex_init(&sigmadsp->lock); in sigmadsp_init()
569 * devm_sigmadsp_init() - Initialize SigmaDSP instance
587 return ERR_PTR(-ENOMEM); in devm_sigmadsp_init()
605 for (i = 0; i < sigmadsp->rate_constraints.count; i++) { in sigmadsp_rate_to_index()
606 if (sigmadsp->rate_constraints.list[i] == rate) in sigmadsp_rate_to_index()
610 return -EINVAL; in sigmadsp_rate_to_index()
621 if (sigmadsp->rate_constraints.count) { in sigmadsp_get_samplerate_mask()
643 struct sigmadsp_control *ctrl, unsigned int samplerate_mask) in sigmadsp_alloc_control() argument
650 template.name = ctrl->name; in sigmadsp_alloc_control()
654 template.private_value = (unsigned long)ctrl; in sigmadsp_alloc_control()
656 if (!sigmadsp_samplerate_valid(ctrl->samplerates, samplerate_mask)) in sigmadsp_alloc_control()
661 return -ENOMEM; in sigmadsp_alloc_control()
663 kcontrol->private_free = sigmadsp_control_free; in sigmadsp_alloc_control()
664 ctrl->kcontrol = kcontrol; in sigmadsp_alloc_control()
666 return snd_ctl_add(sigmadsp->component->card->snd_card, kcontrol); in sigmadsp_alloc_control()
670 struct sigmadsp_control *ctrl, unsigned int samplerate_mask) in sigmadsp_activate_ctrl() argument
672 struct snd_card *card = sigmadsp->component->card->snd_card; in sigmadsp_activate_ctrl()
676 active = sigmadsp_samplerate_valid(ctrl->samplerates, samplerate_mask); in sigmadsp_activate_ctrl()
677 if (!ctrl->kcontrol) in sigmadsp_activate_ctrl()
679 changed = snd_ctl_activate_id(card, &ctrl->kcontrol->id, active); in sigmadsp_activate_ctrl()
681 mutex_lock(&sigmadsp->lock); in sigmadsp_activate_ctrl()
682 if (ctrl->cached) in sigmadsp_activate_ctrl()
683 sigmadsp_ctrl_write(sigmadsp, ctrl, ctrl->cache); in sigmadsp_activate_ctrl()
684 mutex_unlock(&sigmadsp->lock); in sigmadsp_activate_ctrl()
689 * sigmadsp_attach() - Attach a sigmadsp instance to a ASoC component
702 struct sigmadsp_control *ctrl; in sigmadsp_attach() local
706 sigmadsp->component = component; in sigmadsp_attach()
709 sigmadsp->current_samplerate); in sigmadsp_attach()
711 list_for_each_entry(ctrl, &sigmadsp->ctrl_list, head) { in sigmadsp_attach()
712 ret = sigmadsp_alloc_control(sigmadsp, ctrl, samplerate_mask); in sigmadsp_attach()
722 * sigmadsp_setup() - Setup the DSP for the specified samplerate
734 struct sigmadsp_control *ctrl; in sigmadsp_setup() local
739 if (sigmadsp->current_samplerate == samplerate) in sigmadsp_setup()
744 return -EINVAL; in sigmadsp_setup()
746 list_for_each_entry(data, &sigmadsp->data_list, head) { in sigmadsp_setup()
747 if (!sigmadsp_samplerate_valid(data->samplerates, in sigmadsp_setup()
750 ret = sigmadsp_write(sigmadsp, data->addr, data->data, in sigmadsp_setup()
751 data->length); in sigmadsp_setup()
756 list_for_each_entry(ctrl, &sigmadsp->ctrl_list, head) in sigmadsp_setup()
757 sigmadsp_activate_ctrl(sigmadsp, ctrl, samplerate_mask); in sigmadsp_setup()
759 sigmadsp->current_samplerate = samplerate; in sigmadsp_setup()
770 * sigmadsp_reset() - Notify the sigmadsp instance that the DSP has been reset
774 * memory need to be re-loaded.
778 struct sigmadsp_control *ctrl; in sigmadsp_reset() local
780 list_for_each_entry(ctrl, &sigmadsp->ctrl_list, head) in sigmadsp_reset()
781 sigmadsp_activate_ctrl(sigmadsp, ctrl, false); in sigmadsp_reset()
783 sigmadsp->current_samplerate = 0; in sigmadsp_reset()
788 * sigmadsp_restrict_params() - Applies DSP firmware specific constraints
800 if (sigmadsp->rate_constraints.count == 0) in sigmadsp_restrict_params()
803 return snd_pcm_hw_constraint_list(substream->runtime, 0, in sigmadsp_restrict_params()
804 SNDRV_PCM_HW_PARAM_RATE, &sigmadsp->rate_constraints); in sigmadsp_restrict_params()