diff options
author | Christian Pointner <equinox@helsinki.at> | 2024-05-10 18:52:23 (GMT) |
---|---|---|
committer | Christian Pointner <equinox@helsinki.at> | 2024-05-10 18:52:23 (GMT) |
commit | a641800acf13b5fb1463d4280c3ee7fc267143fb (patch) | |
tree | 248b647a682f71d9eb90d14d24081368ea905a42 /snd-alpx/alpx_controls.c | |
parent | cc4badffe0e02d159c21eb90ea080a6a2f90cb4b (diff) |
import whole driver package
Diffstat (limited to 'snd-alpx/alpx_controls.c')
-rw-r--r-- | snd-alpx/alpx_controls.c | 2096 |
1 files changed, 0 insertions, 2096 deletions
diff --git a/snd-alpx/alpx_controls.c b/snd-alpx/alpx_controls.c deleted file mode 100644 index 397fe99..0000000 --- a/snd-alpx/alpx_controls.c +++ /dev/null @@ -1,2096 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* -* Support for Digigram AlpX PCI-e boards -* -* Copyright (c) 2024 Digigram Digital (info@digigram.com) -*/ - -#include "alpx_controls.h" -#include "alpx_variants_stereo.h" -#include "alpx_variants_mc.h" -#include "alpx_variants_dead.h" -#include "alpx_variants_madi.h" - -#include <sound/core.h> -#include <sound/control.h> -#include <sound/tlv.h> -#include <linux/slab.h> - -/* Amplifiers */ - -static int alpx_control_amplifier_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *info) -{ - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - const unsigned long control_index = kcontrol->private_value; - - const struct alpx_control* control = &alpx_dev->controls[control_index]; - - const struct alpx_control_descriptor_amplifier* descr = - (struct alpx_control_descriptor_amplifier*) &control->descriptor->data.ampli; - - dev_dbg( alpx_dev->dev," for volume[%u] (controls[%lu]){%p}.\n", - control->data.ampli.idx, - control_index, - control); - - info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - info->count = 1; //Single channel amplifier - info->value.integer.min = descr->reg_gain_min; - info->value.integer.max = descr->reg_gain_max; - - return 0; -} - -static int alpx_control_amplifier_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *elem_value) -{ - const struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - unsigned int control_index = kcontrol->private_value; - const struct alpx_control* control = &alpx_dev->controls[control_index]; - - const struct alpx_control_amplifier* ampli = &control->data.ampli; - - const u32 offset = control->descriptor->base + ALP_INDEX_TO_REG_OFFSET(ampli->idx); - - u32 value; - - value = readl(alpx_dev->base + offset); - - dev_dbg( alpx_dev->dev," volume[%u](controls[%u]){%p} : 0x%x <= [0x%p:%x:%x]\n", - control->data.ampli.idx, - control_index, - control, - value, - alpx_dev->base, - control->descriptor->base, - ALP_INDEX_TO_REG_OFFSET(ampli->idx)); - - elem_value->value.integer.value[0] = value; - - return 0; -} - -static int alpx_control_amplifier_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *elem_value) -{ - const struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - unsigned int control_index = kcontrol->private_value; - const struct alpx_control* control = &alpx_dev->controls[control_index]; - const struct alpx_control_amplifier* ampli = &control->data.ampli; - - const u32 offset = control->descriptor->base + ALP_INDEX_TO_REG_OFFSET(ampli->idx); - const u32 value = elem_value->value.integer.value[0]; - - dev_dbg( alpx_dev->dev," volume[%u](controls[%u]){%p} : 0x%x => [0x%p:%x:%x]\n", - control->data.ampli.idx, - control_index, - control, - value, - alpx_dev->base, - control->descriptor->base, - ALP_INDEX_TO_REG_OFFSET(ampli->idx)); - - writel(value, alpx_dev->base + offset); - - return 1; /* Value changed */ -} - - -static struct snd_kcontrol_new alpx_control_amplifier = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - - .info = alpx_control_amplifier_info, - .get = alpx_control_amplifier_get, - .put = alpx_control_amplifier_put, -}; - -static int alpx_control_amplifier_register(struct snd_card *card, - struct alpx_control_descriptor *descriptor, - unsigned int idx) -{ - struct alpx_device *alpx_dev = card->private_data; - char name[64] = { 0 }; - const unsigned int control_index = alpx_dev->controls_index; - struct alpx_control *control = &alpx_dev->controls[control_index]; - int ret; - - control->descriptor = descriptor; - control->data.ampli.idx = idx; - - snprintf(name, sizeof(name), "%s Volume", /* Just add FUNCTION, see alsa driver guide */ - control->descriptor->prefix); - - dev_dbg( alpx_dev->dev,"creating amplifier %s[%u] in controls[%u] linked to [0x%x:0x%x].\n", - name, - control->data.ampli.idx, - control_index, - control->descriptor->base, - ALP_INDEX_TO_REG_OFFSET(control->data.ampli.idx)); - - alpx_control_amplifier.name = name; - alpx_control_amplifier.private_value = control_index; - alpx_control_amplifier.index = control->data.ampli.idx; - alpx_control_amplifier.access = descriptor->access; - alpx_control_amplifier.tlv.p = descriptor->data.ampli.gains_scale; - - ret = snd_ctl_add(card, snd_ctl_new1(&alpx_control_amplifier, alpx_dev)); - if (ret) - return ret; - - alpx_dev->controls_index++; - - return 0; -} - -static int alpx_controls_amplifier_register(struct snd_card *card, - struct alpx_control_descriptor *descriptor) -{ - const unsigned int items_count = descriptor->data.ampli.lines_count; - unsigned int i; - int ret; - - for (i = 0; i < items_count; i++) { - ret = alpx_control_amplifier_register(card, descriptor, i); - if (ret) - return ret; - } - - return ret; -} - -/* Codec : analog equalization*/ - -static int alpx_control_codec_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *info) -{ - const struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - const unsigned int control_index = kcontrol->private_value; - const struct alpx_control *control = &alpx_dev->controls[control_index]; - const struct alpx_control_descriptor_codec* descr = &control->descriptor->data.codec; - - info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - info->count = 1; /* single line */ - info->value.integer.min = descr->reg_gain_min; - info->value.integer.max = descr->reg_gain_max; - - return 0; -} - -static int alpx_control_codec_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *elem_value) -{ - const struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - const unsigned int control_index = kcontrol->private_value; - const struct alpx_control *control = &alpx_dev->controls[control_index]; - const unsigned int idx = control->data.codec.idx; - - const u32 offset = control->descriptor->base + control->descriptor->data.codec.offset + - ALPX_CODEC_CTRL_GAIN_REG(idx); - - elem_value->value.integer.value[0] = readl(alpx_dev->base + offset); - - - dev_dbg( alpx_dev->dev,"0x%lx <= [0x%x:%x]\n", - elem_value->value.integer.value[0], - control->descriptor->base, - control->descriptor->data.codec.offset + ALPX_CODEC_CTRL_GAIN_REG(idx)); - - return 0; -} - -static int alpx_control_codec_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *elem_value) -{ - const struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - const unsigned int control_index = kcontrol->private_value; - const struct alpx_control *control = &alpx_dev->controls[control_index]; - const unsigned int idx = control->data.codec.idx; - - const u32 offset = control->descriptor->base + control->descriptor->data.codec.offset + - ALPX_CODEC_CTRL_GAIN_REG(idx); - - const u32 value = elem_value->value.integer.value[0]; - - dev_dbg( alpx_dev->dev," 0x%x => [0x%x:%x]\n", - value, - control->descriptor->base, - control->descriptor->data.codec.offset + ALPX_CODEC_CTRL_GAIN_REG(idx)); - - writel(value, alpx_dev->base + offset); - - return 1; -} - - -static struct snd_kcontrol_new alpx_control_codec = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - - .info = alpx_control_codec_info, - .get = alpx_control_codec_get, - .put = alpx_control_codec_put, -}; - -static int alpx_control_codec_register(struct snd_card *card, - struct alpx_control_descriptor *descriptor, - unsigned int idx) -{ - struct alpx_device *alpx_dev = card->private_data; - char name[64] = { 0 }; - unsigned int control_index = alpx_dev->controls_index; - struct alpx_control *control = &alpx_dev->controls[control_index]; - int ret; - - control->descriptor = descriptor; - control->data.codec.idx = idx; - - snprintf(name, sizeof(name), "%s Volume", descriptor->prefix); - - alpx_control_codec.name = name; - alpx_control_codec.private_value = control_index; - alpx_control_codec.index = control->data.codec.idx; - alpx_control_codec.access = descriptor->access; - alpx_control_codec.tlv.p = descriptor->data.codec.gains_scale; - - dev_dbg( alpx_dev->dev," creating codec eq %s[%u] in controls[%u] linked to [0x%x:0x%x].\n", - name, - control->data.codec.idx, - control_index, - control->descriptor->base, - ALPX_CODEC_CTRL_GAIN_REG(control->data.codec.idx)); - - ret = snd_ctl_add(card, snd_ctl_new1(&alpx_control_codec, alpx_dev)); - if (ret) - return ret; - - alpx_dev->controls_index++; - - return 0; -} - -static int alpx_controls_codec_register(struct snd_card *card, - struct alpx_control_descriptor *descriptor) -{ - const unsigned int items_count = descriptor->data.codec.lines_count; - unsigned int i; - int ret; - - for (i = 0; i < items_count; i++) { - ret = alpx_control_codec_register(card, descriptor, i); - if (ret) - return ret; - } - - return ret; -} - -/* Router */ - -static int alpx_control_router_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *info) -{ - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - unsigned int control_index = kcontrol->private_value; - struct alpx_control *control = &alpx_dev->controls[control_index]; - struct alpx_control_descriptor_router *router = - &control->descriptor->data.router; - - return snd_ctl_enum_info(info, 1, router->entries_count, router->entries); -} - -static int alpx_control_router_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *elem_value) -{ - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - unsigned int control_index = kcontrol->private_value; - struct alpx_control *control = &alpx_dev->controls[control_index]; - unsigned int index = control->data.router.index; - unsigned int index_value; - u32 offset, value; - - offset = control->descriptor->base + ALPX_ROUTER_REG(index); - value = readl(alpx_dev->base + offset); - - dev_dbg( alpx_dev->dev,"0x%x <= [0x%p:%x:%x]\n", - value, - alpx_dev->base, - control->descriptor->base, - ALPX_ROUTER_REG(index)); - - index_value = ALPX_ROUTER_VALUE(index, value); - elem_value->value.enumerated.item[0] = index_value; - - return 0; -} - -static int alpx_control_router_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *elem_value) -{ - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - unsigned int control_index = kcontrol->private_value; - struct alpx_control *control = &alpx_dev->controls[control_index]; - unsigned int index = control->data.router.index; - unsigned int index_value; - u32 offset, value; - - offset = control->descriptor->base + ALPX_ROUTER_REG(index); - value = readl(alpx_dev->base + offset); - index_value = ALPX_ROUTER_VALUE(index, value); - -#if defined(CONFIG_ALPX_LOG_CONTROLS) - dev_dbg( alpx_dev->dev," 0x%x => [0x%p:%x:%x:%d]\n", - value, - alpx_dev->base, - control->descriptor->base, - ALPX_ROUTER_REG(index), - index_value); -#endif - - if (index_value == elem_value->value.enumerated.item[0]) - return 0; - - index_value = elem_value->value.enumerated.item[0]; - - value &= ~ALPX_ROUTER_MASK(index); - value |= ALPX_ROUTER_SEL(index, index_value); - - writel(value, alpx_dev->base + offset); - - return 1; -} - -static struct snd_kcontrol_new alpx_control_router = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - - .info = alpx_control_router_info, - .get = alpx_control_router_get, - .put = alpx_control_router_put, -}; - -static int alpx_control_router_register(struct snd_card *card, - struct alpx_control_descriptor *descriptor, - unsigned int index) -{ - struct alpx_device *alpx_dev = card->private_data; - char name[64] = { 0 }; - unsigned int control_index = alpx_dev->controls_index; - struct alpx_control *control = &alpx_dev->controls[control_index]; - int ret; - - control->descriptor = descriptor; - control->data.router.index = index; - - snprintf(name, sizeof(name), "%s Route", descriptor->prefix); - - alpx_control_router.name = name; - alpx_control_router.private_value = control_index; - alpx_control_router.index = index; - alpx_control_router.access = descriptor->access; - - ret = snd_ctl_add(card, snd_ctl_new1(&alpx_control_router, alpx_dev)); - if (ret) - return ret; - - alpx_dev->controls_index++; - - return 0; -} -/* RESERVED controls */ -static int alpx_control_reserved_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *info) -{ - info->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - info->count = 1; - info->value.integer.min = 0; - info->value.integer.max = 1; - - return 0; -} - -static int alpx_control_reserved_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *elem_value) -{ - elem_value->value.integer.value[0] = 0; - return 0; -} - -static int alpx_control_reserved_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *elem_value) -{ - return 0; -} - -static struct snd_kcontrol_new alpx_control_reserved = { - .iface = SNDRV_CTL_ELEM_IFACE_CARD, - - .info = alpx_control_reserved_info, - .get = alpx_control_reserved_get, - .put = alpx_control_reserved_put, -}; - -static int alpx_control_reserved_register(struct snd_card *card, - struct alpx_control_descriptor *descriptor) -{ - struct alpx_device *alpx_dev = card->private_data; - char name[64] = { 0 }; - unsigned int control_index = alpx_dev->controls_index; - struct alpx_control *control = &alpx_dev->controls[control_index]; - int ret; - - control->descriptor = descriptor; - snprintf(name, sizeof(name), "%s", descriptor->prefix); - - alpx_control_reserved.name = name; - alpx_control_reserved.private_value = control_index; - alpx_control_reserved.index = 0; - alpx_control_reserved.access = SNDRV_CTL_ELEM_ACCESS_INACTIVE; - - ret = snd_ctl_add(card, snd_ctl_new1(&alpx_control_reserved, alpx_dev)); - if (ret) - return ret; - - alpx_dev->controls_index++; - - return 0; - -} - -/* Constant */ -static int alpx_control_constant_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *info) -{ - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - const unsigned long control_index = kcontrol->private_value; - - const struct alpx_control* control = &alpx_dev->controls[control_index]; - - const struct alpx_control_descriptor_constant* descr = - (struct alpx_control_descriptor_constant*) &control->descriptor->data.constant; - - dev_dbg(alpx_dev->dev, "INFO constant control \n"); - - info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - info->count = 1; - info->value.integer.min = descr->value; - info->value.integer.max = descr->value; - - return 0; -} - -static int alpx_control_constant_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *elem_value) -{ - - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - const unsigned long control_index = kcontrol->private_value; - - const struct alpx_control* control = &alpx_dev->controls[control_index]; - - const struct alpx_control_descriptor_constant* descr = - (struct alpx_control_descriptor_constant*) &control->descriptor->data.constant; - - dev_dbg(alpx_dev->dev, "GET constant control \n"); - - elem_value->value.integer.value[0] = descr->value; - return 0; -} - - -static struct snd_kcontrol_new alpx_control_constant = { - .iface = SNDRV_CTL_ELEM_IFACE_CARD, - - .info = alpx_control_constant_info, - .get = alpx_control_constant_get, - .put = NULL, -}; - -static int alpx_control_constant_register(struct snd_card *card, - struct alpx_control_descriptor *descriptor) -{ - struct alpx_device *alpx_dev = card->private_data; - char name[64] = { 0 }; - unsigned int control_index = alpx_dev->controls_index; - struct alpx_control *control = &alpx_dev->controls[control_index]; - int ret; - - dev_dbg(alpx_dev->dev, "Registering constant control for %s\n", card->longname); - - control->descriptor = descriptor; - snprintf(name, sizeof(name), "%s", descriptor->prefix); - - alpx_control_constant.name = name; - alpx_control_constant.private_value = control_index; - alpx_control_constant.index = 0; - alpx_control_constant.access = SNDRV_CTL_ELEM_ACCESS_READ; /* ENFORCE Read only */ - - ret = snd_ctl_add(card, snd_ctl_new1(&alpx_control_constant, alpx_dev)); - if (ret) - return ret; - - alpx_dev->controls_index++; - - return 0; -} - -/* AXCMem Relative choice control */ -static int alpx_control_axcmem_rel_choice_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *info) -{ - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - const unsigned long control_index = kcontrol->private_value; - - const struct alpx_control* control = &alpx_dev->controls[control_index]; - - const struct alpx_control_descriptor_axcmem_rel_choice* choice_descr = - (struct alpx_control_descriptor_axcmem_rel_choice*) &control->descriptor->data.axcmem_rel_choice; - - dev_dbg(alpx_dev->dev, "INFO choice control\n"); - - return snd_ctl_enum_info(info, 1, choice_descr->entries_count, choice_descr->entries); -} - -static int alpx_control_axcmem_rel_choice_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *elem_value) -{ - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - const unsigned long control_index = kcontrol->private_value; - - const struct alpx_control* control = &alpx_dev->controls[control_index]; - - const struct alpx_control_descriptor_axcmem_rel_choice* choice_descr = - (struct alpx_control_descriptor_axcmem_rel_choice*) &control->descriptor->data.axcmem_rel_choice; - - const unsigned int choice_index = elem_value->value.enumerated.item[0]; - - unsigned int reg_value = choice_descr->getter(alpx_axcmem_getPointedRegAddrByRefLoc(alpx_dev, - &choice_descr->base_loc, - &choice_descr->reg_loc)); - - unsigned int choice_value = 0; - - if (choice_index >= choice_descr->entries_count ) { - dev_err(alpx_dev->dev, "Index out of bound : %d > %d !\n", choice_index, choice_descr->entries_count - 1); - return -EINVAL; - } - - choice_value = (control->descriptor->data.axcmem_rel_choice.entries_values[choice_index] << choice_descr->pos); - - reg_value &= choice_descr->mask; - reg_value |= choice_value; - - choice_descr->setter(alpx_axcmem_getPointedRegAddrByRefLoc(alpx_dev, - &choice_descr->base_loc, - &choice_descr->reg_loc), - reg_value); - - dev_dbg(alpx_dev->dev, "%s: index = %d, value = 0x%x, mask: 0x%08x => reg_value=0x%08x\n", - control->descriptor->prefix, - elem_value->value.enumerated.item[0], - choice_value, - choice_descr->mask, - choice_descr->getter(alpx_axcmem_getPointedRegAddrByRefLoc(alpx_dev, - &choice_descr->base_loc, - &choice_descr->reg_loc))); - return 0; -} - -static int alpx_control_axcmem_rel_choice_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *elem_value) -{ - - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - const unsigned long control_index = kcontrol->private_value; - - const struct alpx_control* control = &alpx_dev->controls[control_index]; - - const struct alpx_control_descriptor_axcmem_rel_choice* choice = - (struct alpx_control_descriptor_axcmem_rel_choice*) &control->descriptor->data.axcmem_rel_choice; - - const unsigned int reg_value = choice->getter(alpx_axcmem_getPointedRegAddrByRefLoc(alpx_dev, - &choice->base_loc, - &choice->reg_loc)); - - const unsigned int read_value = (reg_value & choice->mask) >> choice->pos; - unsigned int value_index = 0; - - for (value_index = 0; value_index < choice->entries_count; ++value_index) { - u32 entry_value = choice->entries_values[value_index]; - - if (read_value == entry_value) { - elem_value->value.enumerated.item[0] = value_index; - dev_dbg(alpx_dev->dev, "%s: reg_value=0x%08x, mask: 0x%08x => index = %d\n", - control->descriptor->prefix, - reg_value, - choice->mask, - value_index); - return 0; - } - } - - dev_err(alpx_dev->dev, "%s: unknown choice for: reg_value=0x%08x, mask: 0x%08x => value = %d\n", - control->descriptor->prefix, - reg_value, - choice->mask, - (reg_value & choice->mask)>>choice->pos); - - return -EINVAL; -} - -static struct snd_kcontrol_new alpx_control_axcmem_rel_choice = { - .iface = SNDRV_CTL_ELEM_IFACE_CARD, - .info = alpx_control_axcmem_rel_choice_info, - .get = alpx_control_axcmem_rel_choice_get, - .put = alpx_control_axcmem_rel_choice_put, -}; - -int alpx_control_axcmem_rel_choice_register (struct snd_card *card, - struct alpx_control_descriptor *descriptor) -{ - struct alpx_device *alpx_dev = card->private_data; - char name[64] = { 0 }; - unsigned int control_index = alpx_dev->controls_index; - struct alpx_control *control = &alpx_dev->controls[control_index]; - int ret; - - dev_dbg(alpx_dev->dev, "Registering choice control for %s\n", card->longname); - - control->descriptor = descriptor; - snprintf(name, sizeof(name), "%s", descriptor->prefix); - - alpx_control_axcmem_rel_choice.name = name; - alpx_control_axcmem_rel_choice.private_value = control_index; - alpx_control_axcmem_rel_choice.index = 0; - alpx_control_axcmem_rel_choice.access = descriptor->access; - - ret = snd_ctl_add(card, snd_ctl_new1(&alpx_control_axcmem_rel_choice, alpx_dev)); - if (ret) - return ret; - - alpx_dev->controls_index++; - - return 0; - -} - -/* AxCMem Value */ -static int alpx_control_axcmem_rel_value_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *info) -{ - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - const unsigned long control_index = kcontrol->private_value; - - const struct alpx_control* control = &alpx_dev->controls[control_index]; - - const struct alpx_control_descriptor_axcmem_rel_value* value_descr = - (struct alpx_control_descriptor_axcmem_rel_value*) &control->descriptor->data.axcmem_rel_value; - - dev_dbg(alpx_dev->dev, "INFO Value control \n"); - - info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - info->count = 1; - info->value.integer.min = value_descr->min; - info->value.integer.max = value_descr->max; - - return 0; -} - -static int alpx_control_axcmem_rel_value_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *elem_value) -{ - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - const unsigned long control_index = kcontrol->private_value; - - const struct alpx_control* control = &alpx_dev->controls[control_index]; - - const struct alpx_control_descriptor_axcmem_rel_value* value_descr = - (struct alpx_control_descriptor_axcmem_rel_value*) &control->descriptor->data.axcmem_rel_value; - - unsigned int reg_value = value_descr->getter(alpx_axcmem_getPointedRegAddrByRefLoc(alpx_dev, - &value_descr->base_loc, - &value_descr->reg_loc)); - - reg_value &= value_descr->mask; - reg_value |= ((elem_value->value.integer.value[0] & value_descr->mask) << value_descr->pos); - - value_descr->setter(alpx_axcmem_getPointedRegAddrByRefLoc(alpx_dev, - &value_descr->base_loc, - &value_descr->reg_loc), - reg_value); - - dev_dbg(alpx_dev->dev, "%s: reg_value=0x%08x, mask: 0x%08x => index = %ld\n", - control->descriptor->prefix, - value_descr->getter(alpx_axcmem_getPointedRegAddrByRefLoc(alpx_dev, - &value_descr->base_loc, - &value_descr->reg_loc)), - value_descr->mask, - elem_value->value.integer.value[0]); - - return 0; -} - -static int alpx_control_axcmem_rel_value_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *elem_value) -{ - - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - const unsigned long control_index = kcontrol->private_value; - - const struct alpx_control* control = &alpx_dev->controls[control_index]; - - const struct alpx_control_descriptor_axcmem_rel_value* value_descr = - (struct alpx_control_descriptor_axcmem_rel_value*) &control->descriptor->data.axcmem_rel_value; - - const unsigned int reg_value = value_descr->getter(alpx_axcmem_getPointedRegAddrByRefLoc(alpx_dev, - &value_descr->base_loc, - &value_descr->reg_loc)); - - elem_value->value.integer.value[0] = (reg_value & value_descr->mask) >> value_descr->pos; - - dev_dbg(alpx_dev->dev, "%s: reg_value=0x%08x, mask: 0x%08x => value: 0x%lx\n", - control->descriptor->prefix, - reg_value, - value_descr->mask, - elem_value->value.integer.value[0]); - - return 0; -} - -static struct snd_kcontrol_new alpx_control_axcmem_rel_value = { - .iface = SNDRV_CTL_ELEM_IFACE_CARD, - .info = alpx_control_axcmem_rel_value_info, - .get = alpx_control_axcmem_rel_value_get, - .put = alpx_control_axcmem_rel_value_put, -}; - -int alpx_control_axcmem_rel_value_register (struct snd_card *card, - struct alpx_control_descriptor *descriptor) -{ - struct alpx_device *alpx_dev = card->private_data; - char name[64] = { 0 }; - unsigned int control_index = alpx_dev->controls_index; - struct alpx_control *control = &alpx_dev->controls[control_index]; - int ret; - - dev_dbg(alpx_dev->dev, "Registering VALUE control for %s\n", card->longname); - - control->descriptor = descriptor; - snprintf(name, sizeof(name), "%s", descriptor->prefix); - - alpx_control_axcmem_rel_value.name = name; - alpx_control_axcmem_rel_value.private_value = control_index; - alpx_control_axcmem_rel_value.index = 0; - alpx_control_axcmem_rel_value.access = descriptor->access; - - ret = snd_ctl_add(card, snd_ctl_new1(&alpx_control_axcmem_rel_value, alpx_dev)); - if (ret) - return ret; - - alpx_dev->controls_index++; - return 0; -} - -/* Mixer */ - -static int alpx_control_mixer_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *info) -{ - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - const unsigned long control_index = kcontrol->private_value; - - const struct alpx_control* control = &alpx_dev->controls[control_index]; - - const struct alpx_control_descriptor_mixer* descr = - (struct alpx_control_descriptor_mixer*) &control->descriptor->data.mixer; - - - - - info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - info->count = 1; - info->value.integer.min = descr->reg_gain_min; - info->value.integer.max = descr->reg_gain_max; - - return 0; -} - -static int alpx_control_mixer_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *elem_value) -{ - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - unsigned int control_index = kcontrol->private_value; - struct alpx_control *control = &alpx_dev->controls[control_index]; - unsigned int lines_count = control->descriptor->data.mixer.lines_count; - unsigned int mixer_in = control->data.mixer.mixer_in; - unsigned int mixer_out = control->data.mixer.mixer_out; - u32 offset, reg_value; - - //Registers layout depends on the card's variant - switch(alpx_dev->variant->model) { - case ALPX_VARIANT_MODEL_ALP882: - case ALPX_VARIANT_MODEL_ALP882_MIC: - case ALPX_VARIANT_MODEL_ALP442: - case ALPX_VARIANT_MODEL_ALP442_MIC: - offset = control->descriptor->base + - ALPMC_MIXER_GAIN_REG(lines_count, mixer_in, mixer_out); - reg_value = readl(alpx_dev->base + offset); - elem_value->value.integer.value[0] = ALPMC_MIXER_GAIN_VALUE(reg_value); - - #if defined(CONFIG_ALPX_LOG_CONTROLS) - dev_dbg( alpx_dev->dev," %ld (0x%lx <= 0x%x)<= (%d,%d,%d)[REG:%x:%02x]\n", - elem_value->value.integer.value[0], - ALPMC_MIXER_GAIN_VALUE(reg_value), - reg_value, - lines_count, mixer_in, mixer_out, - control->descriptor->base, - ALPMC_MIXER_GAIN_REG(lines_count, mixer_in, mixer_out)); - #endif - break; - - case ALPX_VARIANT_MODEL_ALP222: - case ALPX_VARIANT_MODEL_ALP222_MIC: - offset = control->descriptor->base + - ALP222_MIXER_GAIN_REG(lines_count, mixer_in, mixer_out); - reg_value = readl(alpx_dev->base + offset); - elem_value->value.integer.value[0] = ALP222_MIXER_GAIN_VALUE(mixer_in, reg_value); - - #if defined(CONFIG_ALPX_LOG_CONTROLS) - dev_dbg( alpx_dev->dev," %ld (0x%lx <= 0x%x)<= (%d,%d,%d)[REG:%x:%02x]\n", - elem_value->value.integer.value[0], - ALP222_MIXER_GAIN_VALUE(mixer_in, reg_value), - reg_value, - lines_count, mixer_in, mixer_out, - control->descriptor->base, - ALP222_MIXER_GAIN_REG(lines_count, mixer_in, mixer_out)); - #endif - break; - - default: - //No mixer by default ! - elem_value->value.integer.value[0] = 0; - return 0; - }; - - - return 0; -} - -static int alpx_control_mixer_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *elem_value) -{ - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - unsigned int control_index = kcontrol->private_value; - struct alpx_control *control = &alpx_dev->controls[control_index]; - unsigned int lines_count = control->descriptor->data.mixer.lines_count; - unsigned int mixer_in = control->data.mixer.mixer_in; - unsigned int mixer_out = control->data.mixer.mixer_out; - unsigned int mixer_value; - u32 offset, reg_value; - - mixer_value = elem_value->value.integer.value[0]; - - switch(alpx_dev->variant->model) { - case ALPX_VARIANT_MODEL_ALP882: - case ALPX_VARIANT_MODEL_ALP882_MIC: - case ALPX_VARIANT_MODEL_ALP442: - case ALPX_VARIANT_MODEL_ALP442_MIC: - offset = control->descriptor->base + - ALPMC_MIXER_GAIN_REG(lines_count, mixer_in, mixer_out); - reg_value = readl(alpx_dev->base + offset); - - reg_value &= ~ALPMC_MIXER_GAIN_MASK; - - #if defined(CONFIG_ALPX_LOG_CONTROLS) - dev_dbg( alpx_dev->dev," 0x%x (0x%lx => 0x%x)=> (%d,%d,%d)[REG:%x:%02x]\n", - mixer_value, - ALPMC_MIXER_GAIN_SEL(mixer_value), - reg_value, - lines_count, mixer_in, mixer_out, - control->descriptor->base, - ALPMC_MIXER_GAIN_REG(lines_count, mixer_in, mixer_out)); - #endif - - reg_value |= ALPMC_MIXER_GAIN_SEL(mixer_value); - break; - - case ALPX_VARIANT_MODEL_ALP222: - case ALPX_VARIANT_MODEL_ALP222_MIC: - offset = control->descriptor->base + - ALP222_MIXER_GAIN_REG(lines_count, mixer_in, mixer_out); - reg_value = readl(alpx_dev->base + offset); - - reg_value &= ~ALP222_MIXER_GAIN_MASK(mixer_in); - - #if defined(CONFIG_ALPX_LOG_CONTROLS) - dev_dbg( alpx_dev->dev," 0x%x (0x%lx => 0x%x)=> (%d,%d,%d)[REG:%x:%02x]\n", - mixer_value, - ALP222_MIXER_GAIN_SEL(mixer_in, mixer_value), - reg_value, - lines_count, mixer_in, mixer_out, - control->descriptor->base, - ALP222_MIXER_GAIN_REG(lines_count, mixer_in, mixer_out)); - #endif - - reg_value |= ALP222_MIXER_GAIN_SEL(mixer_in, mixer_value); - - break; - default: - //Nothing to do for others cards yet - return 0; - } - - - - writel(reg_value, alpx_dev->base + offset); - - return 1; -} - -static struct snd_kcontrol_new alpx_control_mixer = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ, - - .info = alpx_control_mixer_info, - .get = alpx_control_mixer_get, - .put = alpx_control_mixer_put, -}; - -static int alpx_control_mixer_register(struct snd_card *card, - struct alpx_control_descriptor *descriptor, - unsigned int mixer_in, - unsigned int mixer_out) -{ - struct alpx_device* const alpx_dev = card->private_data; - const unsigned int control_index = alpx_dev->controls_index; - struct alpx_control* const control = &alpx_dev->controls[control_index]; -#if defined(CONFIG_ALPX_LOG_CONTROLS) - const unsigned int lines_count = descriptor->data.mixer.lines_count; -#endif - char name[64] = { 0 }; - int ret; - - control->descriptor = descriptor; - control->data.mixer.mixer_in = mixer_in; - control->data.mixer.mixer_out = mixer_out; - - snprintf(name, sizeof(name), "%s %u/%u Playback Volume", descriptor->prefix, - mixer_in, mixer_out); - - alpx_control_mixer.name = name; - alpx_control_mixer.private_value = control_index; - alpx_control_mixer.access = descriptor->access; - alpx_control_mixer.tlv.p = descriptor->data.mixer.gains_scale; - -#if defined(CONFIG_ALPX_LOG_CONTROLS) - dev_dbg( alpx_dev->dev," creating mixer %s in controls[%u] linked to [0x%x:0x%x].\n", - name, - control_index, - control->descriptor->base, - ALP222_MIXER_GAIN_REG(lines_count, mixer_in, mixer_out)); -#endif - - ret = snd_ctl_add(card, snd_ctl_new1(&alpx_control_mixer, alpx_dev)); - if (ret) - return ret; - - alpx_dev->controls_index++; - - return 0; -} -/* Field */ - -static int alpx_control_choice_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *info) -{ - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - unsigned int control_index = kcontrol->private_value; - struct alpx_control *control = &alpx_dev->controls[control_index]; - struct alpx_control_descriptor_choice *choice = - &control->descriptor->data.choice; - -#if defined(CONFIG_ALPX_LOG_CONTROLS) - dev_dbg( alpx_dev->dev," Field %d entries.\n", choice->entries_count); -#endif - - return snd_ctl_enum_info(info, 1, choice->entries_count, choice->entries); -} - -static int alpx_control_choice_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *elem_value) -{ - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - unsigned int control_index = kcontrol->private_value; - struct alpx_control *control = &alpx_dev->controls[control_index]; - u32 offset, value; - unsigned int i; - - offset = control->descriptor->base + - control->descriptor->data.choice.offset; - - value = readl(alpx_dev->base + offset); - value &= control->descriptor->data.choice.mask; - value >>= control->descriptor->data.choice.pos; - -#if defined(CONFIG_ALPX_LOG_CONTROLS) - dev_info( alpx_dev->dev," GET[%d] 0x%x (0x%x)<= [0x%p:%x:%x]\n", - control_index, - value, - readl(alpx_dev->base + offset), - alpx_dev->base, - control->descriptor->base, - control->descriptor->data.choice.offset); -#endif - - for (i = 0; i < control->descriptor->data.choice.entries_count; i++) { - u32 entry_value = - control->descriptor->data.choice.entries_values[i]; - - if (value == entry_value) { - elem_value->value.enumerated.item[0] = i; - - dev_info( alpx_dev->dev,"GET[%d]: Reg: %d => Sync[%d] (%s) \n", - control_index, - value, - i, - control->descriptor->data.translated_choice.entries[i]); - - return 0; - } - } - - return -EINVAL; -} - -static int alpx_control_choice_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *elem_value) -{ - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - unsigned int control_index = kcontrol->private_value; - struct alpx_control *control = &alpx_dev->controls[control_index]; - unsigned int index_value; - u32 offset, reg_value; - - offset = control->descriptor->base + - control->descriptor->data.choice.offset; - reg_value = readl(alpx_dev->base + offset); - - reg_value &= ~control->descriptor->data.choice.mask; - - index_value = elem_value->value.enumerated.item[0]; - reg_value |= control->descriptor->data.choice.entries_values[index_value] << control->descriptor->data.choice.pos ; - - -#if defined(CONFIG_ALPX_LOG_CONTROLS) - dev_info( alpx_dev->dev,"PUT[%d] 0x%x ->([%d]0x%x) 0x%x => [0x%p:%x:%x]\n", - control_index, - readl(alpx_dev->base + offset), - index_value, - control->descriptor->data.choice.entries_values[index_value], - reg_value, - alpx_dev->base, - control->descriptor->base, - control->descriptor->data.choice.offset); -#endif - - dev_info( alpx_dev->dev,"PUT[%d]: Sync[%d] (%s) => Reg: %d\n", - control_index, - index_value, - control->descriptor->data.choice.entries[index_value], - control->descriptor->data.choice.entries_values[index_value]); - - writel(reg_value, alpx_dev->base + offset); - - return 1; -} - -static struct snd_kcontrol_new alpx_control_choice = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - - .info = alpx_control_choice_info, - .get = alpx_control_choice_get, - .put = alpx_control_choice_put, -}; - -static int alpx_control_choice_register(struct snd_card *card, - struct alpx_control_descriptor *descriptor) -{ - struct alpx_device *alpx_dev = card->private_data; - unsigned int control_index = alpx_dev->controls_index; - struct alpx_control *control = &alpx_dev->controls[control_index]; - int ret = 0; - - control->descriptor = descriptor; - - alpx_control_choice.name = descriptor->prefix; - alpx_control_choice.private_value = control_index; - alpx_control_choice.access = descriptor->access; - -#if defined(CONFIG_ALPX_LOG_CONTROLS) - dev_dbg( alpx_dev->dev,"registering CHOICE %s[%d]\n", - alpx_control_choice.name, - control_index); -#endif - - ret = snd_ctl_add(card, snd_ctl_new1(&alpx_control_choice, alpx_dev)); - if (ret) - return ret; - - alpx_dev->controls_index++; - - return 0; -} - -/* Translated choice */ - - -static int alpx_control_translated_choice_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *info) -{ - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - unsigned int control_index = kcontrol->private_value; - struct alpx_control *control = &alpx_dev->controls[control_index]; - struct alpx_control_descriptor_translated_choice *choice = - &control->descriptor->data.translated_choice; - -#if defined(CONFIG_ALPX_LOG_CONTROLS) - dev_dbg( alpx_dev->dev," Field %d entries.\n", choice->entries_count); -#endif - - return snd_ctl_enum_info(info, 1, choice->entries_count, choice->entries); -} - -static int alpx_control_translated_choice_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *elem_value) -{ - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - unsigned int control_index = kcontrol->private_value; - struct alpx_control *control = &alpx_dev->controls[control_index]; - u32 offset, value; - - offset = control->descriptor->base + - control->descriptor->data.translated_choice.offset; - - value = readl(alpx_dev->base + offset); - value &= control->descriptor->data.translated_choice.mask; - value >>= control->descriptor->data.translated_choice.pos; - -#if defined(CONFIG_ALPX_LOG_CONTROLS) - dev_dbg( alpx_dev->dev," 0x%x (0x%x)<= [0x%p:%x:%x]\n", - value, - readl(alpx_dev->base + offset), - alpx_dev->base, - control->descriptor->base, - control->descriptor->data.translated_choice.offset); -#endif - - - if (value < control->descriptor->data.translated_choice.card_entries_count) { - const unsigned int app_value = control->descriptor->data.translated_choice.card_entries_values[value]; - dev_info( alpx_dev->dev,"GET[%d]: Reg: %d => %d: App Sync: %s \n", - control_index, - value, - app_value, - control->descriptor->data.translated_choice.entries[app_value]); - elem_value->value.enumerated.item[0] = app_value; - return 0; - } - - return -EINVAL; -} - -static int alpx_control_translated_choice_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *elem_value) -{ - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - unsigned int control_index = kcontrol->private_value; - struct alpx_control *control = &alpx_dev->controls[control_index]; - unsigned int index_value; - u32 offset, reg_value; - - offset = control->descriptor->base + - control->descriptor->data.translated_choice.offset; - reg_value = readl(alpx_dev->base + offset); - - reg_value &= ~control->descriptor->data.translated_choice.mask; - - index_value = elem_value->value.enumerated.item[0]; - - //Avoid error :RESET the source if BUGGED !! - if (index_value >= control->descriptor->data.translated_choice.entries_count) - index_value = 0; - - reg_value |= control->descriptor->data.translated_choice.entries_values[index_value] << control->descriptor->data.translated_choice.pos ; - -#if defined(CONFIG_ALPX_LOG_CONTROLS) - dev_dbg( alpx_dev->dev,"0x%x ->([%d]0x%x) 0x%x => [0x%p:%x:%x]\n", - readl(alpx_dev->base + offset), - index_value, - control->descriptor->data.translated_choice.entries_values[index_value], - reg_value, - alpx_dev->base, - control->descriptor->base, - control->descriptor->data.translated_choice.offset); -#endif - - dev_info( alpx_dev->dev,"PUT[%d]: App Sync[%d] (%s) => Reg: %d\n", - control_index, - index_value, - control->descriptor->data.translated_choice.entries[index_value], - control->descriptor->data.translated_choice.entries_values[index_value]); - - //Avoid out of range values - if (control->descriptor->data.translated_choice.entries_values[index_value] <= ALP222_CLK_MANAGER_CLK_SRC_MAX) { - writel(reg_value, alpx_dev->base + offset); - } - - return 1; -} - - -static struct snd_kcontrol_new alpx_control_translated_choice = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - - .info = alpx_control_translated_choice_info, - .get = alpx_control_translated_choice_get, - .put = alpx_control_translated_choice_put, -}; - -static int alpx_control_translated_choice_register(struct snd_card *card, - struct alpx_control_descriptor *descriptor) -{ - struct alpx_device *alpx_dev = card->private_data; - unsigned int control_index = alpx_dev->controls_index; - struct alpx_control *control = &alpx_dev->controls[control_index]; - int ret = 0; - - control->descriptor = descriptor; - - alpx_control_translated_choice.name = descriptor->prefix; - alpx_control_translated_choice.private_value = control_index; - alpx_control_translated_choice.access = descriptor->access; - -#if defined(CONFIG_ALPX_LOG_CONTROLS) - dev_dbg( alpx_dev->dev,"registering Translated CHOICE %s[%d]\n", - alpx_control_translated_choice.name, - control_index); -#endif - - ret = snd_ctl_add(card, snd_ctl_new1(&alpx_control_translated_choice, alpx_dev)); - if (ret) - return ret; - - alpx_dev->controls_index++; - - return 0; -} - -/* Flags */ -static int alpx_control_flag_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *info) -{ -#if defined(CONFIG_ALPX_LOG_CONTROLS) - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - unsigned int control_index = kcontrol->private_value; - struct alpx_control *control = &alpx_dev->controls[control_index]; - struct alpx_control_descriptor_choice *choice = - &control->descriptor->data.choice; - - dev_dbg( alpx_dev->dev," Flag %d entries.\n", choice->entries_count); -#endif - - info->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - info->count = 1; - info->value.integer.min = 0; - info->value.integer.max = 1; - - return 0; -} - -static int alpx_control_flag_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *elem_value) -{ - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - unsigned int control_index = kcontrol->private_value; - struct alpx_control *control = &alpx_dev->controls[control_index]; - u32 offset, value; - - offset = control->descriptor->base + - control->descriptor->data.flag.offset; - - value = readl(alpx_dev->base + offset); - value &= control->descriptor->data.flag.mask; - value >>= control->descriptor->data.flag.pos; - -#if defined(CONFIG_ALPX_LOG_CONTROLS) - dev_dbg( alpx_dev->dev,"0x%x (0x%x)<= [0x%p:%x:%x]\n", - value, - readl(alpx_dev->base + offset), - alpx_dev->base, - control->descriptor->base, - control->descriptor->data.flag.offset); -#endif - - elem_value->value.enumerated.item[0] = value; - - return 0; -} - -static int alpx_control_flag_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *elem_value) -{ - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - unsigned int control_index = kcontrol->private_value; - struct alpx_control *control = &alpx_dev->controls[control_index]; - unsigned int new_value; - u32 offset, reg_value; - - offset = control->descriptor->base + - control->descriptor->data.flag.offset; - reg_value = readl(alpx_dev->base + offset); - - reg_value &= ~control->descriptor->data.flag.mask; - - new_value = elem_value->value.enumerated.item[0]; - reg_value |= new_value << control->descriptor->data.flag.pos; - -#if defined(CONFIG_ALPX_LOG_CONTROLS) - dev_dbg( alpx_dev->dev,"0x%x -> 0x%x => [0x%p:%x:%x]\n", - readl(alpx_dev->base + offset), - reg_value, - alpx_dev->base, - control->descriptor->base, - control->descriptor->data.flag.offset); -#endif - - writel(reg_value, alpx_dev->base + offset); - - return 1; -} - -static struct snd_kcontrol_new alpx_control_flag = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - - .info = alpx_control_flag_info, - .get = alpx_control_flag_get, - .put = alpx_control_flag_put, -}; - - -static int alpx_control_flag_register(struct snd_card *card, - struct alpx_control_descriptor *descriptor) -{ - struct alpx_device *alpx_dev = card->private_data; - unsigned int control_index = alpx_dev->controls_index; - struct alpx_control *control = &alpx_dev->controls[control_index]; - int ret; - - control->descriptor = descriptor; - - alpx_control_flag.name = descriptor->prefix; - alpx_control_flag.private_value = control_index; - alpx_control_flag.access = descriptor->access; - - ret = snd_ctl_add(card, snd_ctl_new1(&alpx_control_flag, alpx_dev)); - if (ret) - return ret; - - alpx_dev->controls_index++; - - return 0; -} - -/* Flags_channels */ -static struct alpx_control* alpx_lookup_codec_pga_control(struct alpx_device * alpx_dev, unsigned int side) -{ - //Lookup the LINE PGA associated to the given side - unsigned int ctrl_idx = 0; -dev_dbg(alpx_dev->dev," alpx_dev->controls_count = %d, side:%d\n", alpx_dev->controls_count, side); - - for (ctrl_idx = 0 ; ctrl_idx < (alpx_dev->controls_count - 1) ; ctrl_idx++) { - if ((alpx_dev->controls[ctrl_idx].descriptor->type == ALPX_CONTROL_TYPE_ANALOG_EQ) && - (alpx_dev->controls[ctrl_idx].data.codec.idx == side)){ - dev_dbg(alpx_dev->dev," found LINE EQ ctrl[%d]{%d: 0x%x:%x}\n", - ctrl_idx, alpx_dev->controls[ctrl_idx].data.codec.idx, - alpx_dev->controls[ctrl_idx].descriptor->base, ALPX_CODEC_CTRL_GAIN_REG(side)); - - //return alpx_dev->controls[ctrl_idx].descriptor->base + ALPX_CODEC_CTRL_GAIN_REG(side); - return &alpx_dev->controls[ctrl_idx]; - } - } - dev_err(alpx_dev->dev," NOTHING FOUND\n"); - return NULL; -} - - -static struct alpx_control* alpx_lookup_codec_mic_gain_control(struct alpx_device * alpx_dev, unsigned int pos) -{ - //Lookup the LINE PGA associated to the given side - unsigned int ctrl_idx = 0; -dev_dbg(alpx_dev->dev," alpx_dev->controls_count = %d, pos:%d\n", alpx_dev->controls_count, pos); - - for (ctrl_idx = 0 ; ctrl_idx < (alpx_dev->controls_count - 1) ; ctrl_idx++) { -#if 0 - dev_dbg(alpx_dev->dev,"idx:%d, descriptor : %p (%s), t:%d\n", - ctrl_idx, - &alpx_dev->controls[ctrl_idx].descriptor, - alpx_dev->controls[ctrl_idx].descriptor->prefix, - alpx_dev->controls[ctrl_idx].descriptor->type); -#endif - if ((alpx_dev->controls[ctrl_idx].descriptor->type == ALPX_CONTROL_TYPE_GAINS_EMBEDDED) && - (alpx_dev->controls[ctrl_idx].descriptor->data.mic_gains.pos == pos)){ - dev_dbg(alpx_dev->dev," found MIC Gain ctrl[%d]{0x%x:%x}\n", ctrl_idx, - alpx_dev->controls[ctrl_idx].descriptor->base, alpx_dev->controls[ctrl_idx].descriptor->data.mic_gains.offset); - - //return alpx_dev->controls[ctrl_idx].descriptor->base + alpx_dev->controls[ctrl_idx].descriptor->data.mic_gains.offset; - return &alpx_dev->controls[ctrl_idx]; - } - } - dev_err(alpx_dev->dev,"NOTHING FOUND\n"); - return NULL; -} - -static void alpx_mic_handle_activate_change(struct alpx_device * alpx_dev, struct alpx_control * mic_control, u32 mic_pos, unsigned int is_mic_on) -{ - struct alpx_control* mic_gain_ctrl = NULL; - struct alpx_control* line_eq_gain_ctrl = NULL; - u32 line_codec_reg_offset = 0; - u32 mic_gain_offset; - u32 mic_gain_mask; - u32 line_side = 0; - u32 mic_side_pos = 0; - - - dev_dbg(alpx_dev->dev,"%s(%p, %p,%d,%d) : CALLED\n",__func__, - alpx_dev, - mic_control, - mic_pos, - is_mic_on); - - //Find the right LINE PGA register - switch(mic_pos) { - case ALP222_MIC_EN_L_POS: - dev_dbg(alpx_dev->dev,"LEFT %s\n", is_mic_on ? "On" : "Off"); - line_side = 0; - mic_side_pos = ALP222_MIC_GAIN_L_POS; - break; - case ALP222_MIC_EN_R_POS: - dev_dbg(alpx_dev->dev," RIGHT %s\n",is_mic_on ? "On" : "Off"); - line_side = 1; - mic_side_pos = ALP222_MIC_GAIN_R_POS; - break; - default: - dev_dbg(alpx_dev->dev," Unknown mic position %d !!\n", mic_pos); - return; - }; - - - line_eq_gain_ctrl = alpx_lookup_codec_pga_control(alpx_dev, line_side); - line_codec_reg_offset = line_eq_gain_ctrl->descriptor->base + ALPX_CODEC_CTRL_GAIN_REG(line_side); - mic_gain_ctrl = alpx_lookup_codec_mic_gain_control(alpx_dev, mic_side_pos); - - if (line_eq_gain_ctrl == NULL){ - dev_warn(alpx_dev->dev,"No line EQ ctrl found !\n"); - return; - } - - if ( mic_gain_ctrl == NULL){ - dev_warn(alpx_dev->dev,"No MIC ctrl found !!\n"); - return; - } - - mic_gain_mask = mic_gain_ctrl->descriptor->data.mic_gains.mask; - mic_gain_offset = mic_gain_ctrl->descriptor->base + mic_gain_ctrl->descriptor->data.mic_gains.offset; - - - dev_dbg(alpx_dev->dev,"PGA offset :0x%x, MIC %s offset : 0x%x, MIC mask: 0x%08x\n", - line_codec_reg_offset, - mic_control->descriptor->prefix, - mic_gain_offset, - mic_gain_mask); - -#if 1 - dev_dbg(alpx_dev->dev,"BEFORE MIC %s stored:0X%x, regMIC:0x%x, regPGA:0x%x\n", - is_mic_on ? "On" : "Off", - mic_control->data.mic.stored_gain_in_reg, - readl(alpx_dev->base + mic_gain_offset), - readl(alpx_dev->base + line_codec_reg_offset)); - - //Now handle the mute state change - if (is_mic_on == 0) { - //MIC is going to be MUTED - //restore the LINE gain and store the current MIC gain. - writel(mic_control->data.mic.stored_gain_in_reg, alpx_dev->base + line_codec_reg_offset); - mic_control->data.mic.stored_gain_in_reg = readl(alpx_dev->base + mic_gain_offset); - //MUTE with MIC with ZERO in gain - writel(mic_control->data.mic.stored_gain_in_reg & ~mic_gain_mask, alpx_dev->base + mic_gain_offset); - //Keep the gain only - mic_control->data.mic.stored_gain_in_reg &= mic_gain_mask; - - } else { - //LINE is going to be MUTED - //Restore the MIC gain and store the line gain and MUTE line - u32 mic_reg_value = readl(alpx_dev->base + mic_gain_offset); - writel(mic_control->data.mic.stored_gain_in_reg | (mic_reg_value & ~mic_gain_mask), alpx_dev->base + mic_gain_offset); - mic_control->data.mic.stored_gain_in_reg = readl(alpx_dev->base + line_codec_reg_offset); - //MUTE LINE with 0 in LINE - writel(0, alpx_dev->base + line_codec_reg_offset); - } - - dev_dbg(alpx_dev->dev," AFTER MIC %s stored: 0x%x, regMIC:0x%x, regPGA:0x%x\n", - is_mic_on ? "On" : "Off", - mic_control->data.mic.stored_gain_in_reg, - readl(alpx_dev->base + mic_gain_offset), - readl(alpx_dev->base + line_codec_reg_offset)); -#endif -} - -static int alpx_control_flags_embedded_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *info) -{ - - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - unsigned int control_index = kcontrol->private_value; - struct alpx_control *control = &alpx_dev->controls[control_index]; - struct alpx_control_descriptor *control_desc = control->descriptor; - -#if defined(CONFIG_ALPX_LOG_CONTROLS) - dev_dbg( alpx_dev->dev,"Flags %d entries.\n", control_desc->data.mic_flags.lines_count); -#endif - - info->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - info->count = 1; //One line per control - info->value.integer.min = 0; - info->value.integer.max = 1; - return 0; -} - -static int alpx_control_flags_embedded_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *elem_value) -{ - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - unsigned int control_index = kcontrol->private_value; - struct alpx_control *control = &alpx_dev->controls[control_index]; - struct alpx_control_descriptor *control_desc = control->descriptor; - u32 offset, value; - - /* read the composite register */ - offset = control_desc->base + - control_desc->data.mic_flags.offset; - - value = readl(alpx_dev->base + offset); - - -#if defined(CONFIG_ALPX_LOG_CONTROLS) - dev_dbg( alpx_dev->dev,"0x%x (0x%x)<= [0x%p:%x:%x]\n", - value, - readl(alpx_dev->base + offset), - alpx_dev->base, - control_desc->base, - control_desc->data.mic_flags.offset); -#endif - - elem_value->value.enumerated.item[0] = value & control_desc->data.mic_flags.mask; - elem_value->value.enumerated.item[0] >>= control_desc->data.mic_flags.pos; - -#if defined(CONFIG_ALPX_LOG_CONTROLS) - dev_dbg( alpx_dev->dev,"item[0]=%d\n", - elem_value->value.enumerated.item[0]); -#endif - - return 0; -} - -static int alpx_control_flags_embedded_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *elem_value) -{ - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - unsigned int control_index = kcontrol->private_value; - struct alpx_control *control = &alpx_dev->controls[control_index]; - struct alpx_control_descriptor *control_desc = control->descriptor; - const unsigned int new_state = elem_value->value.enumerated.item[0]; - const u32 offset = control_desc->base + - control_desc->data.mic_flags.offset; - u32 reg_value; - u32 current_state; - - - reg_value = readl(alpx_dev->base + offset); - - dev_dbg(alpx_dev->dev," ctrl[%d]=>%p{name:%s pos:%d reg:0x%08x} : %d\n", control_index, control, control_desc->prefix, control_desc->data.mic_flags.pos, reg_value, new_state); - - current_state = (reg_value & control_desc->data.mic_flags.mask) >> control_desc->data.mic_flags.pos; - - if (current_state == new_state) { - dev_dbg(alpx_dev->dev,"EXIT W/O state change\n"); - return 0; - } - - //* SET the bit according to the associated line */ - reg_value &= ~control_desc->data.mic_flags.mask; - reg_value |= new_state << control_desc->data.mic_flags.pos; - writel(reg_value, alpx_dev->base + offset); - - //Handle the MUTE state transition Only for MIC enable/disable - if ((control_desc->data.mic_flags.pos == ALP222_MIC_EN_L_POS) || - (control_desc->data.mic_flags.pos == ALP222_MIC_EN_R_POS)){ - alpx_mic_handle_activate_change(alpx_dev, control,control_desc->data.mic_flags.pos, new_state); - } - - -#if defined(CONFIG_ALPX_LOG_CONTROLS) - dev_dbg( alpx_dev->dev," item[0]=%d\n", - elem_value->value.enumerated.item[0]); - dev_dbg( alpx_dev->dev," 0x%x -> 0x%x => [0x%p:%x:%x]\n", - readl(alpx_dev->base + offset), - reg_value, - alpx_dev->base, - control_desc->base, - control_desc->data.mic_flags.offset); -#endif - - dev_dbg(alpx_dev->dev," EXIT\n"); - return 1; -} - -static struct snd_kcontrol_new alpx_control_flags_embedded = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - - .info = alpx_control_flags_embedded_info, - .get = alpx_control_flags_embedded_get, - .put = alpx_control_flags_embedded_put, -}; - -static int alpx_control_flags_embedded_register(struct snd_card *card, - struct alpx_control_descriptor *descriptor) -{ - struct alpx_device *alpx_dev = card->private_data; - unsigned int control_index = alpx_dev->controls_index; - struct alpx_control *control = &alpx_dev->controls[control_index]; - int ret; - - control->descriptor = descriptor; - - alpx_control_flags_embedded.name = descriptor->prefix; - alpx_control_flags_embedded.private_value = control_index; - alpx_control_flags_embedded.access = descriptor->access; - - ret = snd_ctl_add(card, snd_ctl_new1(&alpx_control_flags_embedded, alpx_dev)); - if (ret) - return ret; - - alpx_dev->controls_index++; - - //Mut the MIC - alpx_mic_handle_activate_change(alpx_dev, control, descriptor->data.mic_flags.pos, 0); - - return 0; -} - -/* Gains mixed */ - -static u32 alpx_mic_gain_db_to_reg (u32 db) -{ - /* Gain range is 10 to 65, skip special value 0*/ - if (db <= ALP222_MIC_GAINS_MIN_REG_VAL){ - return 1; - } else if (db < ALP222_MIC_GAINS_MAX_REG_VAL){ - return db - ALP222_MIC_REG_GAIN_SHIFT; - } else { - return (ALP222_MIC_GAINS_MAX_REG_VAL + 1 - ALP222_MIC_REG_GAIN_SHIFT); - } -} - -static u32 alpx_mic_gain_reg_to_db (u32 reg) -{ - /* Skip reg == 0 */ - if (reg <= 1) { - return ALP222_MIC_GAINS_MIN_REG_VAL; - } else if (reg < (ALP222_MIC_GAINS_MAX_REG_VAL + 1 - ALP222_MIC_REG_GAIN_SHIFT)) { - return reg + ALP222_MIC_REG_GAIN_SHIFT; - } else { - return ALP222_MIC_GAINS_MAX_REG_VAL; - } -} - -static int alpx_control_gains_embedded_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *info) -{ - - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - unsigned int control_index = kcontrol->private_value; - struct alpx_control *control = &alpx_dev->controls[control_index]; - struct alpx_control_descriptor *control_desc = control->descriptor; - -#if defined(CONFIG_ALPX_LOG_CONTROLS) - dev_dbg( alpx_dev->dev," Gains %d entries.\n", control_desc->data.mic_gains.lines_count); -#endif - - info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - info->count = 1; //One control per item ! - info->value.integer.min = control_desc->data.mic_gains.min; - info->value.integer.max = control_desc->data.mic_gains.max; - - return 0; -} - -static int alpx_control_gains_embedded_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *elem_value) -{ - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - unsigned int control_index = kcontrol->private_value; - struct alpx_control *control = &alpx_dev->controls[control_index]; - u32 offset, reg_value, raw_value; - struct alpx_control_descriptor *control_desc = control->descriptor; - - /* read the composite register */ - offset = control_desc->base + control_desc->data.mic_gains.offset; - - reg_value = readl(alpx_dev->base + offset); - - - -#if defined(CONFIG_ALPX_LOG_CONTROLS) - dev_dbg( alpx_dev->dev," 0x%x (0x%x)<= [0x%p:%x:%x]\n", - reg_value, - readl(alpx_dev->base + offset), - alpx_dev->base, - control_desc->base, - control_desc->data.mic_gains.offset); -#endif - //* GET the bit according to the associated line */ - raw_value = reg_value & (control_desc->data.mic_gains.mask); - raw_value >>= (control_desc->data.mic_gains.pos); - //Convert Raw value into dB - elem_value->value.integer.value[0] = alpx_mic_gain_reg_to_db(raw_value); - - #if defined(CONFIG_ALPX_LOG_CONTROLS) - dev_dbg( alpx_dev->dev,"value[0]=%ld / raw: 0x%x\n", - elem_value->value.integer.value[0], - raw_value); -#endif - - return 0; -} - -static int alpx_control_gains_embedded_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *elem_value) -{ - struct alpx_device *alpx_dev = snd_kcontrol_chip(kcontrol); - unsigned int control_index = kcontrol->private_value; - struct alpx_control *control = &alpx_dev->controls[control_index]; - const unsigned int new_value = alpx_mic_gain_db_to_reg(elem_value->value.integer.value[0]); - u32 offset, reg_value; - struct alpx_control_descriptor *control_desc = control->descriptor; - - offset = control_desc->base + - control_desc->data.mic_gains.offset; - reg_value = readl(alpx_dev->base + offset); - - //* SET the bit according to the associated line */ - reg_value &= ~(control_desc->data.mic_gains.mask); - reg_value |= new_value << (control_desc->data.mic_gains.pos); - - - - -#if defined(CONFIG_ALPX_LOG_CONTROLS) - dev_dbg( alpx_dev->dev,"value[0]=%ld, reg_value: 0x%x\n", - elem_value->value.integer.value[0], - reg_value ); - dev_dbg( alpx_dev->dev,"0x%x -> 0x%x => [0x%p:%x:%x]\n", - readl(alpx_dev->base + offset), - reg_value, - alpx_dev->base, - control_desc->base, - control_desc->data.mic_gains.offset); -#endif - - writel(reg_value, alpx_dev->base + offset); - - - return 1; -} - - -static struct snd_kcontrol_new alpx_control_gains_embedded = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - - .info = alpx_control_gains_embedded_info, - .get = alpx_control_gains_embedded_get, - .put = alpx_control_gains_embedded_put, -}; - -static int alpx_control_gains_embedded_register(struct snd_card *card, - struct alpx_control_descriptor *alp_descriptor) -{ - struct alpx_device *alpx_dev = card->private_data; - unsigned int control_index = alpx_dev->controls_index; - struct alpx_control *control = &alpx_dev->controls[control_index]; - int ret; - char name[64] = { 0 }; - control->descriptor = alp_descriptor; - - snprintf(name, sizeof(name), "%s Volume", alp_descriptor->prefix); - - alpx_control_gains_embedded.name = name; - alpx_control_gains_embedded.private_value = control_index; - alpx_control_gains_embedded.access = alp_descriptor->access; - alpx_control_gains_embedded.tlv.p = alp_descriptor->data.mic_gains.gains_scale; - - - dev_dbg(alpx_dev->dev," mic: %s, gain offset : 0x%x, gains scale : %p\n", - name, - alp_descriptor->data.mic_gains.offset, - alp_descriptor->data.mic_gains.gains_scale); - - ret = snd_ctl_add(card, snd_ctl_new1(&alpx_control_gains_embedded, alpx_dev)); - if (ret) - return ret; - - alpx_dev->controls_index++; - - return 0; -} - -/* Controls */ - -static int alpx_controls_router_register(struct snd_card *card, - struct alpx_control_descriptor *descriptor) -{ - unsigned int i; - int ret; - - for (i = 0; i < descriptor->data.router.lines_count; i++) { - ret = alpx_control_router_register(card, descriptor, i); - if (ret) - return ret; - } - - return 0; -} - -static int alpx_controls_mixer_register(struct snd_card *card, - struct alpx_control_descriptor *descriptor) -{ - unsigned int lines_count = descriptor->data.mixer.lines_count; - unsigned int i, o; - int ret; - - for (o = 0; o < lines_count; o++) { - for (i = 0; i < lines_count; i++) { - ret = alpx_control_mixer_register(card, descriptor, i, o); - if (ret) - return ret; - } - } - - return 0; -} - -#if 0 -static int alpx_controls_gains_embedded_register(struct snd_card *card, - struct alpx_control_descriptor *descriptor) -{ - unsigned int lines_count = descriptor->data.mixer.lines_count; - unsigned int i; - int ret = 0; - - for (i = 0; !ret && i < lines_count; i++) { - ret = alpx_control_gains_embedded_register(card, descriptor, i); - } - - return ret; -} - -static int alpx_controls_flags_embedded_register(struct snd_card *card, - struct alpx_control_descriptor *descriptor) -{ - unsigned int lines_count = descriptor->data.mixer.lines_count; - unsigned int i, o; - int ret = 0; - - for (i = 0;!ret && i < lines_count; i++) { - ret = alpx_control_flags_embedded_register(card, descriptor, i, o); - } - - return ret; -} -#endif - - -/* AlpX Controls */ -int alpx_controls_register(struct snd_card *card) -{ - struct alpx_device *alpx_dev = card->private_data; - const struct alpx_variant *variant = alpx_dev->variant; - unsigned int controls_count = 0; - unsigned int i; - int ret; - - dev_dbg(alpx_dev->dev, "Registering controls for %s\n", card->longname); - - if (alpx_dev->controls) - return -EBUSY; - - for (i = 0; i < variant->control_descriptors_count; i++) { - struct alpx_control_descriptor *descriptor = - &variant->control_descriptors[i]; - - switch (descriptor->type) { - case ALPX_CONTROL_TYPE_CHOICE: - case ALPX_CONTROL_TYPE_FLAG: - case ALPX_CONTROL_TYPE_TRANSLATED_CHOICE: - /* One control for each descriptor. */ - controls_count++; - break; - case ALPX_CONTROL_TYPE_AMPLIFIER: - /* Amplified lines */ - controls_count += descriptor->data.ampli.lines_count; - break; - case ALPX_CONTROL_TYPE_ROUTER: - /* One control for each router line. */ - controls_count += descriptor->data.router.lines_count; - break; - case ALPX_CONTROL_TYPE_MIXER: - /* One control for each mixer line intersection. */ - controls_count += descriptor->data.mixer.lines_count * - descriptor->data.mixer.lines_count; - break; - case ALPX_CONTROL_TYPE_ANALOG_EQ: - controls_count += descriptor->data.codec.lines_count; - break; - case ALPX_CONTROL_TYPE_GAINS_EMBEDDED: - controls_count += descriptor->data.mic_gains.lines_count; - break; - case ALPX_CONTROL_TYPE_FLAGS_EMBEDDED: - controls_count += descriptor->data.mic_flags.lines_count; - break; - case ALPX_CONTROL_RESERVED: - controls_count ++; - break; - case ALPX_CONTROL_TYPE_CONSTANT: - controls_count++; - break; - case ALPX_CONTROL_TYPE_AXCMEM_REL_CHOICE: - controls_count++; - break; - case ALPX_CONTROL_TYPE_AXCMEM_REL_VALUE: - controls_count++; - break; - default: - return -EINVAL; - } - } - - alpx_dev->controls = kcalloc(controls_count, - sizeof(struct alpx_control), GFP_KERNEL); - - if (!alpx_dev->controls) - return -ENOMEM; - - alpx_dev->controls_count = controls_count; - - dev_dbg(alpx_dev->dev," alpx_dev->controls_count = %d\n", alpx_dev->controls_count); - - for (i = 0; i < variant->control_descriptors_count; i++) { - struct alpx_control_descriptor *alp_descriptor = - &variant->control_descriptors[i]; - - dev_dbg(alpx_dev->dev,"descriptor[%d]:{%d, %s}\n", - i, alp_descriptor->type, alp_descriptor->prefix); - - switch (alp_descriptor->type) { - case ALPX_CONTROL_TYPE_AMPLIFIER: - ret = alpx_controls_amplifier_register(card, alp_descriptor); - if (ret) - return ret; - break; - case ALPX_CONTROL_TYPE_ANALOG_EQ: - ret = alpx_controls_codec_register(card, alp_descriptor); - if (ret) - return ret; - break; - case ALPX_CONTROL_TYPE_ROUTER: - ret = alpx_controls_router_register(card, alp_descriptor); - if (ret) - return ret; - break; - case ALPX_CONTROL_TYPE_MIXER: - ret = alpx_controls_mixer_register(card, alp_descriptor); - if (ret) - return ret; - break; - case ALPX_CONTROL_TYPE_CHOICE: - ret = alpx_control_choice_register(card, alp_descriptor); - if (ret) - return ret; - break; - case ALPX_CONTROL_TYPE_TRANSLATED_CHOICE: - ret = alpx_control_translated_choice_register(card, alp_descriptor); - if (ret) - return ret; - break; - case ALPX_CONTROL_TYPE_FLAG: - ret = alpx_control_flag_register(card, alp_descriptor); - if (ret) - return ret; - break; - case ALPX_CONTROL_TYPE_GAINS_EMBEDDED: - ret = alpx_control_gains_embedded_register(card, alp_descriptor); - if (ret) - return ret; - break; - case ALPX_CONTROL_TYPE_FLAGS_EMBEDDED: - ret = alpx_control_flags_embedded_register(card, alp_descriptor); - if (ret) - return ret; - break; - case ALPX_CONTROL_RESERVED: - ret = alpx_control_reserved_register(card, alp_descriptor); - if (ret) - return ret; - break; - case ALPX_CONTROL_TYPE_CONSTANT: - ret = alpx_control_constant_register(card, alp_descriptor); - if (ret) - return ret; - break; - case ALPX_CONTROL_TYPE_AXCMEM_REL_CHOICE: - ret = alpx_control_axcmem_rel_choice_register(card, alp_descriptor); - if (ret) - return ret; - break; - case ALPX_CONTROL_TYPE_AXCMEM_REL_VALUE: - ret = alpx_control_axcmem_rel_value_register(card, alp_descriptor); - if (ret) - return ret; - break; - } - } - return 0; -} - -int alp222_mic_controls_default_config(struct alpx_device * alpx_dev) -{ - //By default CM is enabled and DC is disabled - uint32_t ctrl_reg = readl(alpx_dev->base + ALP222_CONTROL_BASE + ALP222_MIC_CONTROL_REG); - - dev_dbg(alpx_dev->dev," mic::ctrl_reg[0x%08x:%x]=0x%08x\n", - ALP222_CONTROL_BASE, ALP222_MIC_CONTROL_REG, - readl(alpx_dev->base + ALP222_CONTROL_BASE + ALP222_MIC_CONTROL_REG)); - - //remove DC and CM bits - ctrl_reg &= ~(ALP222_MIC_DC_L_MASK | ALP222_MIC_DC_R_MASK); - ctrl_reg &= ~(ALP222_MIC_CM_L_MASK | ALP222_MIC_CM_R_MASK); - - //Then set the default value, only CM - ctrl_reg |= (1<<ALP222_MIC_CM_L_POS) | (1<<ALP222_MIC_CM_R_POS); - - writel(ctrl_reg, alpx_dev->base + ALP222_CONTROL_BASE + ALP222_MIC_CONTROL_REG); - - dev_dbg(alpx_dev->dev," mic::ctrl_reg[0x%08x:%x]=0x%08x\n", - ALP222_CONTROL_BASE, ALP222_MIC_CONTROL_REG, - readl(alpx_dev->base + ALP222_CONTROL_BASE + ALP222_MIC_CONTROL_REG)); - - return 0; -} |