diff options
Diffstat (limited to 'sound/soc/omap/omap-hdmi.c')
-rw-r--r-- | sound/soc/omap/omap-hdmi.c | 77 |
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 | ||
40 | struct hdmi_priv { | 41 | struct 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 | ||
44 | static int omap_hdmi_dai_startup(struct snd_pcm_substream *substream, | 46 | static 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 | ||
62 | static 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 | |||
60 | static int omap_hdmi_dai_hw_params(struct snd_pcm_substream *substream, | 70 | static 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 | ||
96 | static 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 | |||
119 | static 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 | |||
86 | static const struct snd_soc_dai_ops omap_hdmi_dai_ops = { | 127 | static 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 | ||
137 | static int __devexit omap_hdmi_remove(struct platform_device *pdev) | 205 | static 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 | ||