aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorSimon Wilson <simonwilson@google.com>2012-05-29 18:58:49 -0700
committerSimon Wilson <simonwilson@google.com>2012-06-05 13:33:45 -0700
commitfa8795ab5da299d0f5f35add0774820cd1dcfff2 (patch)
tree6c3236b60374610a51984c42a1bba5a9b030a5ca /sound/soc
parentab044b54371929576a57db27e8a20066801f1812 (diff)
downloadkernel_samsung_tuna-fa8795ab5da299d0f5f35add0774820cd1dcfff2.zip
kernel_samsung_tuna-fa8795ab5da299d0f5f35add0774820cd1dcfff2.tar.gz
kernel_samsung_tuna-fa8795ab5da299d0f5f35add0774820cd1dcfff2.tar.bz2
ASoC: OMAP4: HDMI: add mixer control to get LPCM channels
Also fix a potential race condition where the state could have changed during the sleep. Change-Id: I189d0cd17ea56f5e0c2315061ab18acfcff2c91c Signed-off-by: Simon Wilson <simonwilson@google.com>
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/omap/omap4-hdmi-card.c77
1 files changed, 71 insertions, 6 deletions
diff --git a/sound/soc/omap/omap4-hdmi-card.c b/sound/soc/omap/omap4-hdmi-card.c
index 9024735..7a0e749 100644
--- a/sound/soc/omap/omap4-hdmi-card.c
+++ b/sound/soc/omap/omap4-hdmi-card.c
@@ -29,12 +29,10 @@
#define DRV_NAME "omap4-hdmi-audio"
-static int omap4_hdmi_dai_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
+static struct omap_overlay_manager *omap4_hdmi_get_overlay_mgr(void)
{
- int i, count = 0;
+ int i;
struct omap_overlay_manager *mgr = NULL;
- struct device *dev = substream->pcm->card->dev;
/* Find DSS HDMI device */
for (i = 0; i < omap_dss_get_num_overlay_managers(); i++) {
@@ -44,7 +42,21 @@ static int omap4_hdmi_dai_hw_params(struct snd_pcm_substream *substream,
break;
}
- if (i == omap_dss_get_num_overlay_managers()) {
+ if (i == omap_dss_get_num_overlay_managers())
+ mgr = NULL;
+
+ return mgr;
+}
+
+static int omap4_hdmi_dai_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ int count = 0;
+ struct omap_overlay_manager *mgr;
+ struct device *dev = substream->pcm->card->dev;
+
+ mgr = omap4_hdmi_get_overlay_mgr();
+ if (mgr == NULL) {
dev_err(dev, "HDMI display device not found!\n");
return -ENODEV;
}
@@ -52,7 +64,9 @@ static int omap4_hdmi_dai_hw_params(struct snd_pcm_substream *substream,
/* Make sure HDMI is power-on to avoid L3 interconnect errors */
while (mgr->device->state != OMAP_DSS_DISPLAY_ACTIVE) {
msleep(50);
- if (count > 5)
+ if (mgr->device->state == OMAP_DSS_DISPLAY_ACTIVE)
+ break;
+ else if (count > 5)
return -EIO;
dev_err(dev, "HDMI display is not active!\n");
count++;
@@ -75,10 +89,61 @@ static struct snd_soc_dai_link omap4_hdmi_dai = {
.ops = &omap4_hdmi_dai_ops,
};
+static int hdmi_max_chan_ctl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 8;
+
+ return 0;
+}
+
+static int hdmi_max_chan_ctl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct omap_overlay_manager *mgr;
+ struct fb_monspecs *monspecs;
+ int i;
+ int max = 0;
+
+ mgr = omap4_hdmi_get_overlay_mgr();
+ if (mgr == NULL) {
+ /* HDMI audio not supported */
+ goto out;
+ }
+
+ monspecs = &mgr->device->panel.monspecs;
+ for (i = 0; i < monspecs->audiodb_len; i++) {
+ if (monspecs->audiodb[i].format != FB_AUDIO_LPCM)
+ continue;
+
+ if (max < monspecs->audiodb[i].channel_count)
+ max = monspecs->audiodb[i].channel_count;
+ }
+
+out:
+ ucontrol->value.integer.value[0] = max;
+
+ return 0;
+}
+
+static struct snd_kcontrol_new hdmi_max_chan_ctl = {
+ .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = "Maximum LPCM channels",
+ .info = hdmi_max_chan_ctl_info,
+ .get = hdmi_max_chan_ctl_get,
+};
+
static struct snd_soc_card snd_soc_omap4_hdmi = {
.name = "OMAP4HDMI",
.dai_link = &omap4_hdmi_dai,
.num_links = 1,
+
+ .controls = &hdmi_max_chan_ctl,
+ .num_controls = 1,
};
static __devinit int omap4_hdmi_probe(struct platform_device *pdev)