aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/omap/omap-hdmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/omap/omap-hdmi.c')
-rw-r--r--sound/soc/omap/omap-hdmi.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/sound/soc/omap/omap-hdmi.c b/sound/soc/omap/omap-hdmi.c
index a6656b2a7353..ff6132a9b7e8 100644
--- a/sound/soc/omap/omap-hdmi.c
+++ b/sound/soc/omap/omap-hdmi.c
@@ -30,6 +30,7 @@
30#include <sound/pcm_params.h> 30#include <sound/pcm_params.h>
31#include <sound/initval.h> 31#include <sound/initval.h>
32#include <sound/soc.h> 32#include <sound/soc.h>
33#include <video/omapdss.h>
33 34
34#include <plat/dma.h> 35#include <plat/dma.h>
35#include "omap-pcm.h" 36#include "omap-pcm.h"
@@ -39,6 +40,7 @@
39 40
40struct hdmi_priv { 41struct hdmi_priv {
41 struct omap_pcm_dma_data dma_params; 42 struct omap_pcm_dma_data dma_params;
43 struct omap_dss_device *dssdev;
42}; 44};
43 45
44static int omap_hdmi_dai_startup(struct snd_pcm_substream *substream, 46static int omap_hdmi_dai_startup(struct snd_pcm_substream *substream,
@@ -57,6 +59,14 @@ static int omap_hdmi_dai_startup(struct snd_pcm_substream *substream,
57 return 0; 59 return 0;
58} 60}
59 61
62static int omap_hdmi_dai_prepare(struct snd_pcm_substream *substream,
63 struct snd_soc_dai *dai)
64{
65 struct hdmi_priv *priv = snd_soc_dai_get_drvdata(dai);
66
67 return priv->dssdev->driver->audio_enable(priv->dssdev);
68}
69
60static int omap_hdmi_dai_hw_params(struct snd_pcm_substream *substream, 70static int omap_hdmi_dai_hw_params(struct snd_pcm_substream *substream,
61 struct snd_pcm_hw_params *params, 71 struct snd_pcm_hw_params *params,
62 struct snd_soc_dai *dai) 72 struct snd_soc_dai *dai)
@@ -83,6 +93,37 @@ static int omap_hdmi_dai_hw_params(struct snd_pcm_substream *substream,
83 return err; 93 return err;
84} 94}
85 95
96static int omap_hdmi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
97 struct snd_soc_dai *dai)
98{
99 struct hdmi_priv *priv = snd_soc_dai_get_drvdata(dai);
100 int err = 0;
101
102 switch (cmd) {
103 case SNDRV_PCM_TRIGGER_START:
104 case SNDRV_PCM_TRIGGER_RESUME:
105 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
106 err = priv->dssdev->driver->audio_start(priv->dssdev);
107 break;
108 case SNDRV_PCM_TRIGGER_STOP:
109 case SNDRV_PCM_TRIGGER_SUSPEND:
110 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
111 priv->dssdev->driver->audio_stop(priv->dssdev);
112 break;
113 default:
114 err = -EINVAL;
115 }
116 return err;
117}
118
119static void omap_hdmi_dai_shutdown(struct snd_pcm_substream *substream,
120 struct snd_soc_dai *dai)
121{
122 struct hdmi_priv *priv = snd_soc_dai_get_drvdata(dai);
123
124 priv->dssdev->driver->audio_disable(priv->dssdev);
125}
126
86static const struct snd_soc_dai_ops omap_hdmi_dai_ops = { 127static const struct snd_soc_dai_ops omap_hdmi_dai_ops = {
87 .startup = omap_hdmi_dai_startup, 128 .startup = omap_hdmi_dai_startup,
88 .hw_params = omap_hdmi_dai_hw_params, 129 .hw_params = omap_hdmi_dai_hw_params,
@@ -103,6 +144,7 @@ static __devinit int omap_hdmi_probe(struct platform_device *pdev)
103 int ret; 144 int ret;
104 struct resource *hdmi_rsrc; 145 struct resource *hdmi_rsrc;
105 struct hdmi_priv *hdmi_data; 146 struct hdmi_priv *hdmi_data;
147 bool hdmi_dev_found = false;
106 148
107 hdmi_data = devm_kzalloc(&pdev->dev, sizeof(*hdmi_data), GFP_KERNEL); 149 hdmi_data = devm_kzalloc(&pdev->dev, sizeof(*hdmi_data), GFP_KERNEL);
108 if (hdmi_data == NULL) { 150 if (hdmi_data == NULL) {
@@ -129,14 +171,49 @@ static __devinit int omap_hdmi_probe(struct platform_device *pdev)
129 hdmi_data->dma_params.name = "HDMI playback"; 171 hdmi_data->dma_params.name = "HDMI playback";
130 hdmi_data->dma_params.sync_mode = OMAP_DMA_SYNC_PACKET; 172 hdmi_data->dma_params.sync_mode = OMAP_DMA_SYNC_PACKET;
131 173
174 /*
175 * TODO: We assume that there is only one DSS HDMI device. Future
176 * OMAP implementations may support more than one HDMI devices and
177 * we should provided separate audio support for all of them.
178 */
179 /* Find an HDMI device. */
180 for_each_dss_dev(hdmi_data->dssdev) {
181 omap_dss_get_device(hdmi_data->dssdev);
182
183 if (!hdmi_data->dssdev->driver) {
184 omap_dss_put_device(hdmi_data->dssdev);
185 continue;
186 }
187
188 if (hdmi_data->dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
189 hdmi_dev_found = true;
190 break;
191 }
192 }
193
194 if (!hdmi_dev_found) {
195 dev_err(&pdev->dev, "no driver for HDMI display found\n");
196 return -ENODEV;
197 }
198
132 dev_set_drvdata(&pdev->dev, hdmi_data); 199 dev_set_drvdata(&pdev->dev, hdmi_data);
133 ret = snd_soc_register_dai(&pdev->dev, &omap_hdmi_dai); 200 ret = snd_soc_register_dai(&pdev->dev, &omap_hdmi_dai);
201
134 return ret; 202 return ret;
135} 203}
136 204
137static int __devexit omap_hdmi_remove(struct platform_device *pdev) 205static int __devexit omap_hdmi_remove(struct platform_device *pdev)
138{ 206{
207 struct hdmi_priv *hdmi_data = dev_get_drvdata(&pdev->dev);
208
139 snd_soc_unregister_dai(&pdev->dev); 209 snd_soc_unregister_dai(&pdev->dev);
210
211 if (hdmi_data == NULL) {
212 dev_err(&pdev->dev, "cannot obtain HDMi data\n");
213 return -ENODEV;
214 }
215
216 omap_dss_put_device(hdmi_data->dssdev);
140 return 0; 217 return 0;
141} 218}
142 219