ASoC: New enum type: value_enum
This patch introduces a new enum type. In this enum type each enumerated items referred with a value. This new enum type can handle enums encoded in bitfield, or any other weird ways. twl4030 codec has several mux selection register, where the input/output mux is coded in a bitfield. With the normal enum type this type of mux can not be handled in a clean way. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Этот коммит содержится в:

коммит произвёл
Mark Brown

родитель
7961233688
Коммит
2e72f8e371
@@ -1584,6 +1584,113 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_soc_put_enum_double);
|
||||
|
||||
/**
|
||||
* snd_soc_info_value_enum_double - semi enumerated double mixer info callback
|
||||
* @kcontrol: mixer control
|
||||
* @uinfo: control element information
|
||||
*
|
||||
* Callback to provide information about a double semi enumerated
|
||||
* mixer control.
|
||||
*
|
||||
* Semi enumerated mixer: the enumerated items are referred as values. Can be
|
||||
* used for handling bitfield coded enumeration for example.
|
||||
*
|
||||
* Returns 0 for success.
|
||||
*/
|
||||
int snd_soc_info_value_enum_double(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
struct soc_value_enum *e = (struct soc_value_enum *)
|
||||
kcontrol->private_value;
|
||||
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
|
||||
uinfo->count = e->shift_l == e->shift_r ? 1 : 2;
|
||||
uinfo->value.enumerated.items = e->max;
|
||||
|
||||
if (uinfo->value.enumerated.item > e->max - 1)
|
||||
uinfo->value.enumerated.item = e->max - 1;
|
||||
strcpy(uinfo->value.enumerated.name,
|
||||
e->texts[uinfo->value.enumerated.item]);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_soc_info_value_enum_double);
|
||||
|
||||
/**
|
||||
* snd_soc_get_value_enum_double - semi enumerated double mixer get callback
|
||||
* @kcontrol: mixer control
|
||||
* @ucontrol: control element information
|
||||
*
|
||||
* Callback to get the value of a double semi enumerated mixer.
|
||||
*
|
||||
* Semi enumerated mixer: the enumerated items are referred as values. Can be
|
||||
* used for handling bitfield coded enumeration for example.
|
||||
*
|
||||
* Returns 0 for success.
|
||||
*/
|
||||
int snd_soc_get_value_enum_double(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
struct soc_value_enum *e = (struct soc_value_enum *)
|
||||
kcontrol->private_value;
|
||||
unsigned short reg_val, val, mux;
|
||||
|
||||
reg_val = snd_soc_read(codec, e->reg);
|
||||
val = (reg_val >> e->shift_l) & e->mask;
|
||||
for (mux = 0; mux < e->max; mux++) {
|
||||
if (val == e->values[mux])
|
||||
break;
|
||||
}
|
||||
ucontrol->value.enumerated.item[0] = mux;
|
||||
if (e->shift_l != e->shift_r) {
|
||||
val = (reg_val >> e->shift_r) & e->mask;
|
||||
for (mux = 0; mux < e->max; mux++) {
|
||||
if (val == e->values[mux])
|
||||
break;
|
||||
}
|
||||
ucontrol->value.enumerated.item[1] = mux;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_soc_get_value_enum_double);
|
||||
|
||||
/**
|
||||
* snd_soc_put_value_enum_double - semi enumerated double mixer put callback
|
||||
* @kcontrol: mixer control
|
||||
* @ucontrol: control element information
|
||||
*
|
||||
* Callback to set the value of a double semi enumerated mixer.
|
||||
*
|
||||
* Semi enumerated mixer: the enumerated items are referred as values. Can be
|
||||
* used for handling bitfield coded enumeration for example.
|
||||
*
|
||||
* Returns 0 for success.
|
||||
*/
|
||||
int snd_soc_put_value_enum_double(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
struct soc_value_enum *e = (struct soc_value_enum *)
|
||||
kcontrol->private_value;
|
||||
unsigned short val;
|
||||
unsigned short mask;
|
||||
|
||||
if (ucontrol->value.enumerated.item[0] > e->max - 1)
|
||||
return -EINVAL;
|
||||
val = e->values[ucontrol->value.enumerated.item[0]] << e->shift_l;
|
||||
mask = e->mask << e->shift_l;
|
||||
if (e->shift_l != e->shift_r) {
|
||||
if (ucontrol->value.enumerated.item[1] > e->max - 1)
|
||||
return -EINVAL;
|
||||
val |= e->values[ucontrol->value.enumerated.item[1]] << e->shift_r;
|
||||
mask |= e->mask << e->shift_r;
|
||||
}
|
||||
|
||||
return snd_soc_update_bits(codec, e->reg, mask, val);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_soc_put_value_enum_double);
|
||||
|
||||
/**
|
||||
* snd_soc_info_enum_ext - external enumerated single mixer info callback
|
||||
* @kcontrol: mixer control
|
||||
|
Ссылка в новой задаче
Block a user