Modified: trunk/sound/soc/blackfin/bf5xx-ad73311.c (9703 => 9704)
--- trunk/sound/soc/blackfin/bf5xx-ad73311.c 2011-03-09 10:20:23 UTC (rev 9703)
+++ trunk/sound/soc/blackfin/bf5xx-ad73311.c 2011-03-10 10:18:08 UTC (rev 9704)
@@ -83,7 +83,7 @@
udelay(1);
}
-static int snd_ad73311_configure(void)
+static int snd_ad73311_configure(struct ad73311_snd_ctrls *ctrl)
{
unsigned short ctrl_regs[7];
unsigned short status = 0;
@@ -95,11 +95,11 @@
* Sample Rate = DMCLK/2048 = 8 KHz
*/
ctrl_regs[0] = AD_CONTROL | AD_WRITE | CTRL_REG_B | REGB_MCDIV(0) | \
- REGB_SCDIV(0) | REGB_DIRATE(0);
+ REGB_SCDIV(0) | REGB_DIRATE(ctrl->dirate);
ctrl_regs[1] = AD_CONTROL | AD_WRITE | CTRL_REG_C | REGC_PUDEV | \
REGC_PUADC | REGC_PUDAC | REGC_PUREF | REGC_REFUSE ;
- ctrl_regs[2] = AD_CONTROL | AD_WRITE | CTRL_REG_D | REGD_OGS(2) | \
- REGD_IGS(2);
+ ctrl_regs[2] = AD_CONTROL | AD_WRITE | CTRL_REG_D | REGD_OGS(ctrl->ogs) | \
+ REGD_IGS(ctrl->igs);
ctrl_regs[3] = AD_CONTROL | AD_WRITE | CTRL_REG_E | REGE_DA(0x1f);
ctrl_regs[4] = AD_CONTROL | AD_WRITE | CTRL_REG_F | REGF_SEEN ;
ctrl_regs[5] = AD_CONTROL | AD_WRITE | CTRL_REG_A | REGA_MODE_DATA;
@@ -154,9 +154,26 @@
return 0;
}
+static int snd_ad73311_write(void *control_data, const char *data, int len)
+{
+ return snd_ad73311_configure((struct ad73311_snd_ctrls *)data);
+}
+
+static int snd_ad73311_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_codec *codec = rtd->codec;
+ codec->hw_write = snd_ad73311_write;
+ return 0;
+}
+
static int bf5xx_probe(struct platform_device *pdev)
{
int err;
+ struct ad73311_snd_ctrls ctrl = {
+ .dirate = 0,
+ .igs = 2,
+ .ogs = 2,
+ };
if (gpio_request(GPIO_SE, "AD73311_SE")) {
printk(KERN_ERR "%s: Failed ro request GPIO_%d\n", __func__, GPIO_SE);
return -EBUSY;
@@ -173,7 +190,7 @@
gpio_direction_output(GPIO_SE, 0);
gpio_direction_output(GPIO_RESET, 0);
- err = snd_ad73311_configure();
+ err = snd_ad73311_configure(&ctrl);
if (err < 0)
return -EFAULT;
@@ -212,6 +229,7 @@
.codec_dai_name = "ad73311-hifi",
.platform_name = "bfin-pcm-audio",
.codec_name = "ad73311-codec",
+ .init = snd_ad73311_init,
.ops = &bf5xx_ad73311_ops,
},
{
@@ -221,6 +239,7 @@
.codec_dai_name = "ad73311-hifi",
.platform_name = "bfin-pcm-audio",
.codec_name = "ad73311-codec",
+ .init = snd_ad73311_init,
.ops = &bf5xx_ad73311_ops,
}
};
Modified: trunk/sound/soc/codecs/ad73311.c (9703 => 9704)
--- trunk/sound/soc/codecs/ad73311.c 2011-03-09 10:20:23 UTC (rev 9703)
+++ trunk/sound/soc/codecs/ad73311.c 2011-03-10 10:18:08 UTC (rev 9704)
@@ -39,8 +39,111 @@
.formats = SNDRV_PCM_FMTBIT_S16_LE, },
};
-static struct snd_soc_codec_driver soc_codec_dev_ad73311;
+#if CONFIG_SND_AD7XXXX_SELECT == 0
+static struct ad73311_snd_ctrls ad73311_ctrls = {
+ .dirate = 0,
+ .igs = 2,
+ .ogs = 2,
+};
+static int ad73311_ogs_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ if (ad73311_ctrls.ogs != ucontrol->value.integer.value[0]) {
+ ad73311_ctrls.ogs = ucontrol->value.integer.value[0];
+ return codec->hw_write(codec->control_data, (char *)&ad73311_ctrls,
+ sizeof(ad73311_ctrls));
+ }
+ return 0;
+}
+
+static int ad73311_ogs_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = ad73311_ctrls.ogs;
+ return 0;
+}
+
+static int ad73311_igs_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ if (ad73311_ctrls.igs != ucontrol->value.integer.value[0]) {
+ ad73311_ctrls.igs = ucontrol->value.integer.value[0];
+ return codec->hw_write(codec->control_data, (char *)&ad73311_ctrls,
+ sizeof(ad73311_ctrls));
+ }
+ return 0;
+}
+
+static int ad73311_igs_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = ad73311_ctrls.igs;
+ return 0;
+}
+
+static int ad73311_dirate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ unsigned int rate = SNDRV_PCM_RATE_8000;
+
+ if (ad73311_ctrls.dirate != ucontrol->value.integer.value[0]) {
+ ad73311_ctrls.dirate = ucontrol->value.integer.value[0];
+ switch (ad73311_ctrls.dirate) {
+ case 0:
+ rate = SNDRV_PCM_RATE_8000;
+ break;
+ case 1:
+ rate = SNDRV_PCM_RATE_16000;
+ break;
+ case 2:
+ rate = SNDRV_PCM_RATE_32000;
+ break;
+ case 3:
+ rate = SNDRV_PCM_RATE_64000;
+ break;
+ }
+ ad73311_dai.playback.rates = rate;
+ ad73311_dai.capture.rates = rate;
+ return codec->hw_write(codec->control_data, (char *)&ad73311_ctrls,
+ sizeof(ad73311_ctrls));
+ }
+ return 0;
+}
+
+static int ad73311_dirate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = ad73311_ctrls.dirate;
+ return 0;
+}
+
+static const struct snd_kcontrol_new ad73311_snd_controls[] = {
+ SOC_SINGLE_EXT("ADC Capture Volume", CTRL_REG_D, 0, 7, 0,
+ ad73311_igs_get, ad73311_igs_put),
+ SOC_SINGLE_EXT("DAC Playback Volume", CTRL_REG_D, 4, 7, 0,
+ ad73311_ogs_get, ad73311_ogs_put),
+ SOC_SINGLE_EXT("Decimation/Interpolation Rate", CTRL_REG_B, 0, 3, 0,
+ ad73311_dirate_get, ad73311_dirate_put),
+};
+#endif
+
+static int ad73311_soc_probe(struct snd_soc_codec *codec)
+{
+#if CONFIG_SND_AD7XXXX_SELECT == 0
+ snd_soc_add_controls(codec, ad73311_snd_controls,
+ ARRAY_SIZE(ad73311_snd_controls));
+#endif
+ return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_ad73311 = {
+ .probe = ad73311_soc_probe,
+};
+
static int ad73311_probe(struct platform_device *pdev)
{
return snd_soc_register_codec(&pdev->dev,
Modified: trunk/sound/soc/codecs/ad73311.h (9703 => 9704)
--- trunk/sound/soc/codecs/ad73311.h 2011-03-09 10:20:23 UTC (rev 9703)
+++ trunk/sound/soc/codecs/ad73311.h 2011-03-10 10:18:08 UTC (rev 9704)
@@ -141,4 +141,10 @@
#define CTRL_REG_G (6 << 11)
#endif
+struct ad73311_snd_ctrls {
+ char dirate; /* Decimation/Interpolation Rate */
+ char igs; /* Input Gain Select */
+ char ogs; /* Output Gain Select */
+};
+
#endif