diff options
author | Axel Castaneda Gonzalez <x0055901@ti.com> | 2012-01-22 18:02:48 -0600 |
---|---|---|
committer | Simon Wilson <simonwilson@google.com> | 2012-05-01 13:24:04 -0700 |
commit | f51c66d7d95c8188658973e29b1607b1fed4a52b (patch) | |
tree | 42bc8e77645605743b2f4407ff0d733808032c7b /sound | |
parent | 067daf59e3921c3093ab56cfd46a6edcb13a94c3 (diff) | |
download | kernel_samsung_tuna-f51c66d7d95c8188658973e29b1607b1fed4a52b.zip kernel_samsung_tuna-f51c66d7d95c8188658973e29b1607b1fed4a52b.tar.gz kernel_samsung_tuna-f51c66d7d95c8188658973e29b1607b1fed4a52b.tar.bz2 |
ASoC: OMAP: HDMI: Defer audio transfer start
Defer audio transfer after HDMI AUDIO wrapper is enabled.
If audio transmit was started along with audio wrapper enabling,
spurious data (zeros) was sent at the beginning of the transfer
as part of the of audio sample packets, due an AUDIO FIFO UNDERFLOW,
which was shifting audio channels.
Change-Id: I48d8c02c0467dd3158ac748eb0720173d3b209ca
Signed-off-by: Axel Castaneda Gonzalez <x0055901@ti.com>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/omap-hdmi-codec.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/sound/soc/codecs/omap-hdmi-codec.c b/sound/soc/codecs/omap-hdmi-codec.c index b30e6cd..b1f3c72 100644 --- a/sound/soc/codecs/omap-hdmi-codec.c +++ b/sound/soc/codecs/omap-hdmi-codec.c @@ -67,6 +67,8 @@ struct hdmi_codec_data { struct omap_dss_device *dssdev; struct notifier_block notifier; struct hdmi_params params; + struct delayed_work delayed_work; + struct workqueue_struct *workqueue; int active; } hdmi_data; @@ -247,19 +249,26 @@ int hdmi_audio_notifier_callback(struct notifier_block *nb, if (state == OMAP_DSS_DISPLAY_ACTIVE) { /* this happens just after hdmi_power_on */ - if (hdmi_data.active) - hdmi_ti_4xxx_audio_enable(&hdmi_data.ip_data, 0); hdmi_audio_set_configuration(&hdmi_data); if (hdmi_data.active) { omap_hwmod_set_slave_idlemode(hdmi_data.oh, HWMOD_IDLEMODE_NO); - hdmi_ti_4xxx_audio_enable(&hdmi_data.ip_data, 1); - + hdmi_ti_4xxx_wp_audio_enable(&hdmi_data.ip_data, 1); + queue_delayed_work(hdmi_data.workqueue, + &hdmi_data.delayed_work, + msecs_to_jiffies(1)); } + } else { + cancel_delayed_work(&hdmi_data.delayed_work); } return 0; } +static void hdmi_audio_work(struct work_struct *work) +{ + hdmi_ti_4xxx_audio_transfer_en(&hdmi_data.ip_data, 1); +} + int hdmi_audio_match(struct omap_dss_device *dssdev, void *arg) { return sysfs_streq(dssdev->name , "hdmi"); @@ -297,14 +306,19 @@ static int hdmi_audio_trigger(struct snd_pcm_substream *substream, int cmd, */ omap_hwmod_set_slave_idlemode(priv->oh, HWMOD_IDLEMODE_NO); - hdmi_ti_4xxx_audio_enable(&priv->ip_data, 1); + hdmi_ti_4xxx_wp_audio_enable(&priv->ip_data, 1); + queue_delayed_work(priv->workqueue, &priv->delayed_work, + msecs_to_jiffies(1)); + priv->active = 1; break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + cancel_delayed_work(&hdmi_data.delayed_work); priv->active = 0; - hdmi_ti_4xxx_audio_enable(&priv->ip_data, 0); + hdmi_ti_4xxx_audio_transfer_en(&priv->ip_data, 0); + hdmi_ti_4xxx_wp_audio_enable(&priv->ip_data, 0); /* * switch back to smart-idle & wakeup capable * after audio activity stops @@ -379,6 +393,10 @@ static int hdmi_probe(struct snd_soc_codec *codec) blocking_notifier_chain_register(&hdmi_data.dssdev->state_notifiers, &hdmi_data.notifier); + hdmi_data.workqueue = create_singlethread_workqueue("hdmi-codec"); + + INIT_DELAYED_WORK(&hdmi_data.delayed_work, hdmi_audio_work); + return 0; dssdev_err: |