static int hdmi_audio_config(struct device *dev, struct omap_dss_audio *dss_audio) { struct omap_hdmi *hd = dev_get_drvdata(dev); int ret; mutex_lock(&hd->lock); if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) { ret = -EPERM; goto out; } ret = hdmi5_audio_config(&hd->core, &hd->wp, dss_audio, hd->cfg.timings.pixelclock); if (!ret) { hd->audio_configured = true; hd->audio_config = *dss_audio; } out: mutex_unlock(&hd->lock); return ret; }
static void hdmi_audio_stop(struct device *dev) { struct omap_hdmi *hd = dev_get_drvdata(dev); WARN_ON(!hdmi_mode_has_audio(&hd->cfg)); WARN_ON(!hd->display_enabled); hdmi_wp_audio_core_req_enable(&hd->wp, false); hdmi_wp_audio_enable(&hd->wp, false); /* Playback stopped, restore original idlemode */ REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, hd->wp_idlemode, 3, 2); }
static void hdmi_audio_stop(struct device *dev) { struct omap_hdmi *hd = dev_get_drvdata(dev); unsigned long flags; WARN_ON(!hdmi_mode_has_audio(&hd->cfg)); spin_lock_irqsave(&hd->audio_playing_lock, flags); if (hd->display_enabled) hdmi_stop_audio_stream(hd); hd->audio_playing = false; spin_unlock_irqrestore(&hd->audio_playing_lock, flags); }
static int hdmi_audio_start(struct device *dev) { struct omap_hdmi *hd = dev_get_drvdata(dev); WARN_ON(!hdmi_mode_has_audio(&hd->cfg)); WARN_ON(!hd->display_enabled); /* No-idle while playing audio, store the old value */ hd->wp_idlemode = REG_GET(hdmi.wp.base, HDMI_WP_SYSCONFIG, 3, 2); REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2); hdmi_wp_audio_enable(&hd->wp, true); hdmi_wp_audio_core_req_enable(&hd->wp, true); return 0; }
/* Audio callbacks */ static int hdmi_audio_startup(struct device *dev, void (*abort_cb)(struct device *dev)) { struct omap_hdmi *hd = dev_get_drvdata(dev); int ret = 0; mutex_lock(&hd->lock); if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) { ret = -EPERM; goto out; } hd->audio_abort_cb = abort_cb; out: mutex_unlock(&hd->lock); return ret; }