summaryrefslogtreecommitdiff
path: root/snd-alpx/snd-alpx/alpx_controls.c
diff options
context:
space:
mode:
Diffstat (limited to 'snd-alpx/snd-alpx/alpx_controls.c')
-rw-r--r--snd-alpx/snd-alpx/alpx_controls.c2096
1 files changed, 0 insertions, 2096 deletions
diff --git a/snd-alpx/snd-alpx/alpx_controls.c b/snd-alpx/snd-alpx/alpx_controls.c
deleted file mode 100644
index 397fe99..0000000
--- a/snd-alpx/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;
-}