{
u8 *cache = codec->reg_cache;
+ if (reg >= TWL4030_CACHEREGNUM)
+ return -EIO;
+
return cache[reg];
}
/* Earpiece */
static const char *twl4030_earpiece_texts[] =
- {"Off", "DACL1", "DACL2", "Invalid", "DACR1"};
+ {"Off", "DACL1", "DACL2", "DACR1"};
+
+static const unsigned int twl4030_earpiece_values[] =
+ {0x0, 0x1, 0x2, 0x4};
static const struct soc_enum twl4030_earpiece_enum =
- SOC_ENUM_SINGLE(TWL4030_REG_EAR_CTL, 1,
+ SOC_VALUE_ENUM_SINGLE(TWL4030_REG_EAR_CTL, 1, 0x7,
ARRAY_SIZE(twl4030_earpiece_texts),
- twl4030_earpiece_texts);
+ twl4030_earpiece_texts,
+ twl4030_earpiece_values);
static const struct snd_kcontrol_new twl4030_dapm_earpiece_control =
-SOC_DAPM_ENUM("Route", twl4030_earpiece_enum);
+SOC_DAPM_VALUE_ENUM("Route", twl4030_earpiece_enum);
/* PreDrive Left */
static const char *twl4030_predrivel_texts[] =
- {"Off", "DACL1", "DACL2", "Invalid", "DACR2"};
+ {"Off", "DACL1", "DACL2", "DACR2"};
+
+static const unsigned int twl4030_predrivel_values[] =
+ {0x0, 0x1, 0x2, 0x4};
static const struct soc_enum twl4030_predrivel_enum =
- SOC_ENUM_SINGLE(TWL4030_REG_PREDL_CTL, 1,
+ SOC_VALUE_ENUM_SINGLE(TWL4030_REG_PREDL_CTL, 1, 0x7,
ARRAY_SIZE(twl4030_predrivel_texts),
- twl4030_predrivel_texts);
+ twl4030_predrivel_texts,
+ twl4030_predrivel_values);
static const struct snd_kcontrol_new twl4030_dapm_predrivel_control =
-SOC_DAPM_ENUM("Route", twl4030_predrivel_enum);
+SOC_DAPM_VALUE_ENUM("Route", twl4030_predrivel_enum);
/* PreDrive Right */
static const char *twl4030_predriver_texts[] =
- {"Off", "DACR1", "DACR2", "Invalid", "DACL2"};
+ {"Off", "DACR1", "DACR2", "DACL2"};
+
+static const unsigned int twl4030_predriver_values[] =
+ {0x0, 0x1, 0x2, 0x4};
static const struct soc_enum twl4030_predriver_enum =
- SOC_ENUM_SINGLE(TWL4030_REG_PREDR_CTL, 1,
+ SOC_VALUE_ENUM_SINGLE(TWL4030_REG_PREDR_CTL, 1, 0x7,
ARRAY_SIZE(twl4030_predriver_texts),
- twl4030_predriver_texts);
+ twl4030_predriver_texts,
+ twl4030_predriver_values);
static const struct snd_kcontrol_new twl4030_dapm_predriver_control =
-SOC_DAPM_ENUM("Route", twl4030_predriver_enum);
+SOC_DAPM_VALUE_ENUM("Route", twl4030_predriver_enum);
/* Headset Left */
static const char *twl4030_hsol_texts[] =
/* Left analog microphone selection */
static const char *twl4030_analoglmic_texts[] =
- {"Off", "Main mic", "Headset mic", "Invalid", "AUXL",
- "Invalid", "Invalid", "Invalid", "Carkit mic"};
+ {"Off", "Main mic", "Headset mic", "AUXL", "Carkit mic"};
+
+static const unsigned int twl4030_analoglmic_values[] =
+ {0x0, 0x1, 0x2, 0x4, 0x8};
static const struct soc_enum twl4030_analoglmic_enum =
- SOC_ENUM_SINGLE(TWL4030_REG_ANAMICL, 0,
+ SOC_VALUE_ENUM_SINGLE(TWL4030_REG_ANAMICL, 0, 0xf,
ARRAY_SIZE(twl4030_analoglmic_texts),
- twl4030_analoglmic_texts);
+ twl4030_analoglmic_texts,
+ twl4030_analoglmic_values);
static const struct snd_kcontrol_new twl4030_dapm_analoglmic_control =
-SOC_DAPM_ENUM("Route", twl4030_analoglmic_enum);
+SOC_DAPM_VALUE_ENUM("Route", twl4030_analoglmic_enum);
/* Right analog microphone selection */
static const char *twl4030_analogrmic_texts[] =
- {"Off", "Sub mic", "Invalid", "Invalid", "AUXR"};
+ {"Off", "Sub mic", "AUXR"};
+
+static const unsigned int twl4030_analogrmic_values[] =
+ {0x0, 0x1, 0x4};
static const struct soc_enum twl4030_analogrmic_enum =
- SOC_ENUM_SINGLE(TWL4030_REG_ANAMICR, 0,
+ SOC_VALUE_ENUM_SINGLE(TWL4030_REG_ANAMICR, 0, 0x5,
ARRAY_SIZE(twl4030_analogrmic_texts),
- twl4030_analogrmic_texts);
+ twl4030_analogrmic_texts,
+ twl4030_analogrmic_values);
static const struct snd_kcontrol_new twl4030_dapm_analogrmic_control =
-SOC_DAPM_ENUM("Route", twl4030_analogrmic_enum);
+SOC_DAPM_VALUE_ENUM("Route", twl4030_analogrmic_enum);
/* TX1 L/R Analog/Digital microphone selection */
static const char *twl4030_micpathtx1_texts[] =
static const struct snd_kcontrol_new twl4030_dapm_micpathtx2_control =
SOC_DAPM_ENUM("Route", twl4030_micpathtx2_enum);
-/*
- * This function filters out the non valid mux settings, named as "Invalid"
- * in the enum texts.
- * Just refuse to set an invalid mux mode.
- */
-static int twl4030_enum_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- int ret = 0;
- int val;
-
- val = w->value >> e->shift_l;
- if (!strcmp("Invalid", e->texts[val])) {
- printk(KERN_WARNING "Invalid MUX setting on 0x%02x (%d)\n",
- e->reg, val);
- ret = -1;
- }
-
- return ret;
-}
-
static int micpath_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
0, 3, 5, 0, input_gain_tlv),
};
-/* add non dapm controls */
-static int twl4030_add_controls(struct snd_soc_codec *codec)
-{
- int err, i;
-
- for (i = 0; i < ARRAY_SIZE(twl4030_snd_controls); i++) {
- err = snd_ctl_add(codec->card,
- snd_soc_cnew(&twl4030_snd_controls[i],
- codec, NULL));
- if (err < 0)
- return err;
- }
-
- return 0;
-}
-
static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
/* Left channel inputs */
SND_SOC_DAPM_INPUT("MAINMIC"),
/* Output MUX controls */
/* Earpiece */
- SND_SOC_DAPM_MUX_E("Earpiece Mux", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_earpiece_control, twl4030_enum_event,
- SND_SOC_DAPM_PRE_REG),
+ SND_SOC_DAPM_VALUE_MUX("Earpiece Mux", SND_SOC_NOPM, 0, 0,
+ &twl4030_dapm_earpiece_control),
/* PreDrivL/R */
- SND_SOC_DAPM_MUX_E("PredriveL Mux", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_predrivel_control, twl4030_enum_event,
- SND_SOC_DAPM_PRE_REG),
- SND_SOC_DAPM_MUX_E("PredriveR Mux", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_predriver_control, twl4030_enum_event,
- SND_SOC_DAPM_PRE_REG),
+ SND_SOC_DAPM_VALUE_MUX("PredriveL Mux", SND_SOC_NOPM, 0, 0,
+ &twl4030_dapm_predrivel_control),
+ SND_SOC_DAPM_VALUE_MUX("PredriveR Mux", SND_SOC_NOPM, 0, 0,
+ &twl4030_dapm_predriver_control),
/* HeadsetL/R */
SND_SOC_DAPM_MUX("HeadsetL Mux", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_hsol_control),
SND_SOC_DAPM_POST_REG),
/* Analog input muxes with power switch for the physical ADCL/R */
- SND_SOC_DAPM_MUX_E("Analog Left Capture Route",
- TWL4030_REG_AVADC_CTL, 3, 0, &twl4030_dapm_analoglmic_control,
- twl4030_enum_event, SND_SOC_DAPM_PRE_REG),
- SND_SOC_DAPM_MUX_E("Analog Right Capture Route",
- TWL4030_REG_AVADC_CTL, 1, 0, &twl4030_dapm_analogrmic_control,
- twl4030_enum_event, SND_SOC_DAPM_PRE_REG),
+ SND_SOC_DAPM_VALUE_MUX("Analog Left Capture Route",
+ TWL4030_REG_AVADC_CTL, 3, 0, &twl4030_dapm_analoglmic_control),
+ SND_SOC_DAPM_VALUE_MUX("Analog Right Capture Route",
+ TWL4030_REG_AVADC_CTL, 1, 0, &twl4030_dapm_analogrmic_control),
SND_SOC_DAPM_PGA("Analog Left Amplifier",
TWL4030_REG_ANAMICL, 4, 0, NULL, 0),
/* power on device */
twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- twl4030_add_controls(codec);
+ snd_soc_add_controls(codec, twl4030_snd_controls,
+ ARRAY_SIZE(twl4030_snd_controls));
twl4030_add_widgets(codec);
ret = snd_soc_init_card(socdev);
struct snd_soc_codec *codec = socdev->codec;
printk(KERN_INFO "TWL4030 Audio Codec remove\n");
+ snd_soc_free_pcms(socdev);
+ snd_soc_dapm_free(socdev);
kfree(codec);
return 0;