+
+ struct aic32x4_setup_data *setup;
+ struct device *dev;
+};
+
+static int aic32x4_get_mfp1_gpio(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ u8 val;
+
+ val = snd_soc_read(codec, AIC32X4_DINCTL);
+
+ ucontrol->value.integer.value[0] = (val & 0x01);
+
+ return 0;
+};
+
+static int aic32x4_set_mfp2_gpio(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ u8 val;
+ u8 gpio_check;
+
+ val = snd_soc_read(codec, AIC32X4_DOUTCTL);
+ gpio_check = (val & AIC32X4_MFP_GPIO_ENABLED);
+ if (gpio_check != AIC32X4_MFP_GPIO_ENABLED) {
+ printk(KERN_ERR "%s: MFP2 is not configure as a GPIO output\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (ucontrol->value.integer.value[0] == (val & AIC32X4_MFP2_GPIO_OUT_HIGH))
+ return 0;
+
+ if (ucontrol->value.integer.value[0])
+ val |= ucontrol->value.integer.value[0];
+ else
+ val &= ~AIC32X4_MFP2_GPIO_OUT_HIGH;
+
+ snd_soc_write(codec, AIC32X4_DOUTCTL, val);
+
+ return 0;
+};
+
+static int aic32x4_get_mfp3_gpio(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ u8 val;
+
+ val = snd_soc_read(codec, AIC32X4_SCLKCTL);
+
+ ucontrol->value.integer.value[0] = (val & 0x01);
+
+ return 0;
+};
+
+static int aic32x4_set_mfp4_gpio(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ u8 val;
+ u8 gpio_check;
+
+ val = snd_soc_read(codec, AIC32X4_MISOCTL);
+ gpio_check = (val & AIC32X4_MFP_GPIO_ENABLED);
+ if (gpio_check != AIC32X4_MFP_GPIO_ENABLED) {
+ printk(KERN_ERR "%s: MFP4 is not configure as a GPIO output\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (ucontrol->value.integer.value[0] == (val & AIC32X4_MFP5_GPIO_OUT_HIGH))
+ return 0;
+
+ if (ucontrol->value.integer.value[0])
+ val |= ucontrol->value.integer.value[0];
+ else
+ val &= ~AIC32X4_MFP5_GPIO_OUT_HIGH;
+
+ snd_soc_write(codec, AIC32X4_MISOCTL, val);
+
+ return 0;
+};
+
+static int aic32x4_get_mfp5_gpio(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ u8 val;
+
+ val = snd_soc_read(codec, AIC32X4_GPIOCTL);
+ ucontrol->value.integer.value[0] = ((val & 0x2) >> 1);
+
+ return 0;
+};
+
+static int aic32x4_set_mfp5_gpio(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ u8 val;
+ u8 gpio_check;
+
+ val = snd_soc_read(codec, AIC32X4_GPIOCTL);
+ gpio_check = (val & AIC32X4_MFP5_GPIO_OUTPUT);
+ if (gpio_check != AIC32X4_MFP5_GPIO_OUTPUT) {
+ printk(KERN_ERR "%s: MFP5 is not configure as a GPIO output\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (ucontrol->value.integer.value[0] == (val & 0x1))
+ return 0;
+
+ if (ucontrol->value.integer.value[0])
+ val |= ucontrol->value.integer.value[0];
+ else
+ val &= 0xfe;
+
+ snd_soc_write(codec, AIC32X4_GPIOCTL, val);
+
+ return 0;
+};
+
+static const struct snd_kcontrol_new aic32x4_mfp1[] = {
+ SOC_SINGLE_BOOL_EXT("MFP1 GPIO", 0, aic32x4_get_mfp1_gpio, NULL),
+};
+
+static const struct snd_kcontrol_new aic32x4_mfp2[] = {
+ SOC_SINGLE_BOOL_EXT("MFP2 GPIO", 0, NULL, aic32x4_set_mfp2_gpio),
+};
+
+static const struct snd_kcontrol_new aic32x4_mfp3[] = {
+ SOC_SINGLE_BOOL_EXT("MFP3 GPIO", 0, aic32x4_get_mfp3_gpio, NULL),
+};
+
+static const struct snd_kcontrol_new aic32x4_mfp4[] = {
+ SOC_SINGLE_BOOL_EXT("MFP4 GPIO", 0, NULL, aic32x4_set_mfp4_gpio),
+};
+
+static const struct snd_kcontrol_new aic32x4_mfp5[] = {
+ SOC_SINGLE_BOOL_EXT("MFP5 GPIO", 0, aic32x4_get_mfp5_gpio,
+ aic32x4_set_mfp5_gpio),