diff options
author | Simon Wilson <simonwilson@google.com> | 2012-05-29 18:58:49 -0700 |
---|---|---|
committer | Simon Wilson <simonwilson@google.com> | 2012-06-05 13:33:45 -0700 |
commit | fa8795ab5da299d0f5f35add0774820cd1dcfff2 (patch) | |
tree | 6c3236b60374610a51984c42a1bba5a9b030a5ca /sound/soc | |
parent | ab044b54371929576a57db27e8a20066801f1812 (diff) | |
download | kernel_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.c | 77 |
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) |