aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/sh_mobile_hdmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/sh_mobile_hdmi.c')
-rw-r--r--drivers/video/sh_mobile_hdmi.c84
1 files changed, 83 insertions, 1 deletions
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c
index 2fde08cc66bf..ef989d94511c 100644
--- a/drivers/video/sh_mobile_hdmi.c
+++ b/drivers/video/sh_mobile_hdmi.c
@@ -22,6 +22,8 @@
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/types.h> 23#include <linux/types.h>
24#include <linux/workqueue.h> 24#include <linux/workqueue.h>
25#include <sound/soc-dapm.h>
26#include <sound/initval.h>
25 27
26#include <video/sh_mobile_hdmi.h> 28#include <video/sh_mobile_hdmi.h>
27#include <video/sh_mobile_lcdc.h> 29#include <video/sh_mobile_lcdc.h>
@@ -222,6 +224,58 @@ static u8 hdmi_read(struct sh_hdmi *hdmi, u8 reg)
222 return ioread8(hdmi->base + reg); 224 return ioread8(hdmi->base + reg);
223} 225}
224 226
227/*
228 * HDMI sound
229 */
230static unsigned int sh_hdmi_snd_read(struct snd_soc_codec *codec,
231 unsigned int reg)
232{
233 struct sh_hdmi *hdmi = snd_soc_codec_get_drvdata(codec);
234
235 return hdmi_read(hdmi, reg);
236}
237
238static int sh_hdmi_snd_write(struct snd_soc_codec *codec,
239 unsigned int reg,
240 unsigned int value)
241{
242 struct sh_hdmi *hdmi = snd_soc_codec_get_drvdata(codec);
243
244 hdmi_write(hdmi, value, reg);
245 return 0;
246}
247
248static struct snd_soc_dai_driver sh_hdmi_dai = {
249 .name = "sh_mobile_hdmi-hifi",
250 .playback = {
251 .stream_name = "Playback",
252 .channels_min = 2,
253 .channels_max = 8,
254 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
255 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
256 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
257 SNDRV_PCM_RATE_192000,
258 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
259 },
260};
261
262static int sh_hdmi_snd_probe(struct snd_soc_codec *codec)
263{
264 dev_info(codec->dev, "SH Mobile HDMI Audio Codec");
265
266 return 0;
267}
268
269static struct snd_soc_codec_driver soc_codec_dev_sh_hdmi = {
270 .probe = sh_hdmi_snd_probe,
271 .read = sh_hdmi_snd_read,
272 .write = sh_hdmi_snd_write,
273};
274
275/*
276 * HDMI video
277 */
278
225/* External video parameter settings */ 279/* External video parameter settings */
226static void hdmi_external_video_param(struct sh_hdmi *hdmi) 280static void hdmi_external_video_param(struct sh_hdmi *hdmi)
227{ 281{
@@ -318,6 +372,9 @@ static void sh_hdmi_video_config(struct sh_hdmi *hdmi)
318 */ 372 */
319static void sh_hdmi_audio_config(struct sh_hdmi *hdmi) 373static void sh_hdmi_audio_config(struct sh_hdmi *hdmi)
320{ 374{
375 u8 data;
376 struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
377
321 /* 378 /*
322 * [7:4] L/R data swap control 379 * [7:4] L/R data swap control
323 * [3:0] appropriate N[19:16] 380 * [3:0] appropriate N[19:16]
@@ -335,7 +392,23 @@ static void sh_hdmi_audio_config(struct sh_hdmi *hdmi)
335 * [6:5] set required down sampling rate if required 392 * [6:5] set required down sampling rate if required
336 * [4:3] set required audio source 393 * [4:3] set required audio source
337 */ 394 */
338 hdmi_write(hdmi, 0x00, HDMI_AUDIO_SETTING_1); 395 switch (pdata->flags & HDMI_SND_SRC_MASK) {
396 default:
397 /* fall through */
398 case HDMI_SND_SRC_I2S:
399 data = 0x0 << 3;
400 break;
401 case HDMI_SND_SRC_SPDIF:
402 data = 0x1 << 3;
403 break;
404 case HDMI_SND_SRC_DSD:
405 data = 0x2 << 3;
406 break;
407 case HDMI_SND_SRC_HBR:
408 data = 0x3 << 3;
409 break;
410 }
411 hdmi_write(hdmi, data, HDMI_AUDIO_SETTING_1);
339 412
340 /* [3:0] set sending channel number for channel status */ 413 /* [3:0] set sending channel number for channel status */
341 hdmi_write(hdmi, 0x40, HDMI_AUDIO_SETTING_2); 414 hdmi_write(hdmi, 0x40, HDMI_AUDIO_SETTING_2);
@@ -891,6 +964,11 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
891 return -ENOMEM; 964 return -ENOMEM;
892 } 965 }
893 966
967 ret = snd_soc_register_codec(&pdev->dev,
968 &soc_codec_dev_sh_hdmi, &sh_hdmi_dai, 1);
969 if (ret < 0)
970 goto esndreg;
971
894 hdmi->dev = &pdev->dev; 972 hdmi->dev = &pdev->dev;
895 973
896 hdmi->hdmi_clk = clk_get(&pdev->dev, "ick"); 974 hdmi->hdmi_clk = clk_get(&pdev->dev, "ick");
@@ -976,6 +1054,8 @@ eclkenable:
976erate: 1054erate:
977 clk_put(hdmi->hdmi_clk); 1055 clk_put(hdmi->hdmi_clk);
978egetclk: 1056egetclk:
1057 snd_soc_unregister_codec(&pdev->dev);
1058esndreg:
979 kfree(hdmi); 1059 kfree(hdmi);
980 1060
981 return ret; 1061 return ret;
@@ -988,6 +1068,8 @@ static int __exit sh_hdmi_remove(struct platform_device *pdev)
988 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1068 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
989 int irq = platform_get_irq(pdev, 0); 1069 int irq = platform_get_irq(pdev, 0);
990 1070
1071 snd_soc_unregister_codec(&pdev->dev);
1072
991 pdata->lcd_chan->board_cfg.display_on = NULL; 1073 pdata->lcd_chan->board_cfg.display_on = NULL;
992 pdata->lcd_chan->board_cfg.display_off = NULL; 1074 pdata->lcd_chan->board_cfg.display_off = NULL;
993 pdata->lcd_chan->board_cfg.board_data = NULL; 1075 pdata->lcd_chan->board_cfg.board_data = NULL;