[alsa-devel] [PATCH 2/4] ASoC: Add sh_mobile_hdmi sound support
Kuninori Morimoto
kuninori.morimoto.gx at renesas.com
Mon Aug 30 07:05:26 CEST 2010
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
---
drivers/video/sh_mobile_hdmi.c | 153 ++++++++++++++++++++++++++++++++++++++++
include/video/sh_mobile_hdmi.h | 3 +
2 files changed, 156 insertions(+), 0 deletions(-)
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c
index d25e348..f31d570 100644
--- a/drivers/video/sh_mobile_hdmi.c
+++ b/drivers/video/sh_mobile_hdmi.c
@@ -22,6 +22,8 @@
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/workqueue.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
#include <video/sh_mobile_hdmi.h>
#include <video/sh_mobile_lcdc.h>
@@ -202,6 +204,8 @@ enum hotplug_state {
HDMI_HOTPLUG_EDID_DONE,
};
+static struct snd_soc_codec *sh_hdmi_codec;
+
struct sh_hdmi {
void __iomem *base;
enum hotplug_state hp_state;
@@ -210,6 +214,7 @@ struct sh_hdmi {
struct fb_info *info;
struct delayed_work edid_work;
struct fb_var_screeninfo var;
+ struct snd_soc_codec codec;
};
static void hdmi_write(struct sh_hdmi *hdmi, u8 data, u8 reg)
@@ -222,6 +227,101 @@ static u8 hdmi_read(struct sh_hdmi *hdmi, u8 reg)
return ioread8(hdmi->base + reg);
}
+/************************************************************************
+
+
+ HDMI sound
+
+
+************************************************************************/
+static unsigned int sh_hdmi_snd_read(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ struct sh_hdmi *hdmi;
+
+ codec = sh_hdmi_codec;
+ hdmi = codec->control_data;
+
+ return hdmi_read(hdmi, reg);
+}
+
+static int sh_hdmi_snd_write(struct snd_soc_codec *codec,
+ unsigned int reg,
+ unsigned int value)
+{
+ struct sh_hdmi *hdmi;
+
+ codec = sh_hdmi_codec;
+ hdmi = codec->control_data;
+
+ hdmi_write(hdmi, value, reg);
+ return 0;
+}
+
+struct snd_soc_dai sh_hdmi_dai = {
+ .name = "SH MOBILE HDMI",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
+ },
+};
+EXPORT_SYMBOL_GPL(sh_hdmi_dai);
+
+/*
+ * initialise the driver
+ * register the mixer and dsp interfaces with the kernel
+ */
+static int sh_hdmi_snd_init(struct sh_hdmi *hdmi)
+{
+ struct snd_soc_codec *codec = &hdmi->codec;
+ int ret = 0;
+
+ if (sh_hdmi_codec) {
+ dev_err(codec->dev, "Another hdmi is registered\n");
+ return -EINVAL;
+ }
+
+ mutex_init(&codec->mutex);
+ INIT_LIST_HEAD(&codec->dapm_widgets);
+ INIT_LIST_HEAD(&codec->dapm_paths);
+
+ snd_soc_codec_set_drvdata(codec, hdmi);
+ codec->name = "SH MOBILE HDMI";
+ codec->owner = THIS_MODULE;
+ codec->read = sh_hdmi_snd_read;
+ codec->write = sh_hdmi_snd_write;
+ codec->dai = &sh_hdmi_dai;
+ codec->num_dai = 1;
+
+ sh_hdmi_dai.dev = codec->dev;
+ sh_hdmi_codec = codec;
+
+ ret = snd_soc_register_codec(codec);
+ if (ret) {
+ dev_err(codec->dev, "Failed to register codec: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_register_dai(&sh_hdmi_dai);
+ if (ret) {
+ dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
+ snd_soc_unregister_codec(codec);
+ return ret;
+ }
+
+ return ret;
+}
+
+/************************************************************************
+
+
+ HDMI video
+
+
+************************************************************************/
/* External video parameter settings */
static void hdmi_external_video_param(struct sh_hdmi *hdmi)
{
@@ -792,6 +892,7 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data;
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
int irq = platform_get_irq(pdev, 0), ret;
+ struct snd_soc_codec *codec;
struct sh_hdmi *hdmi;
long rate;
@@ -806,6 +907,15 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
hdmi->dev = &pdev->dev;
+ codec = &hdmi->codec;
+ codec->dev = &pdev->dev;
+ codec->control_data = hdmi;
+ ret = sh_hdmi_snd_init(hdmi);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to sound initialise\n");
+ goto egetclk;
+ }
+
hdmi->hdmi_clk = clk_get(&pdev->dev, "ick");
if (IS_ERR(hdmi->hdmi_clk)) {
ret = PTR_ERR(hdmi->hdmi_clk);
@@ -901,6 +1011,10 @@ static int __exit sh_hdmi_remove(struct platform_device *pdev)
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
int irq = platform_get_irq(pdev, 0);
+ snd_soc_unregister_dai(&sh_hdmi_dai);
+ snd_soc_unregister_codec(&hdmi->codec);
+ sh_hdmi_codec = NULL;
+
pdata->lcd_chan->board_cfg.display_on = NULL;
pdata->lcd_chan->board_cfg.display_off = NULL;
pdata->lcd_chan->board_cfg.board_data = NULL;
@@ -917,6 +1031,45 @@ static int __exit sh_hdmi_remove(struct platform_device *pdev)
return 0;
}
+static int sh_hdmi_snd_probe(struct platform_device *pdev)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ int ret;
+
+ if (!sh_hdmi_codec) {
+ dev_err(&pdev->dev, "Codec device not registered\n");
+ return -ENODEV;
+ }
+
+ socdev->card->codec = sh_hdmi_codec;
+
+ /* register pcms */
+ ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to create pcms\n");
+ return ret;
+ }
+
+ dev_info(&pdev->dev, "sh_mobile_hdmi Audio Codec");
+ return ret;
+}
+
+static int sh_hdmi_snd_remove(struct platform_device *pdev)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+
+ snd_soc_free_pcms(socdev);
+ snd_soc_dapm_free(socdev);
+
+ return 0;
+}
+
+struct snd_soc_codec_device soc_codec_dev_sh_hdmi = {
+ .probe = sh_hdmi_snd_probe,
+ .remove = sh_hdmi_snd_remove,
+};
+EXPORT_SYMBOL_GPL(soc_codec_dev_sh_hdmi);
+
static struct platform_driver sh_hdmi_driver = {
.remove = __exit_p(sh_hdmi_remove),
.driver = {
diff --git a/include/video/sh_mobile_hdmi.h b/include/video/sh_mobile_hdmi.h
index 929c2d3..7b9fe18 100644
--- a/include/video/sh_mobile_hdmi.h
+++ b/include/video/sh_mobile_hdmi.h
@@ -35,4 +35,7 @@ struct sh_mobile_hdmi_info {
unsigned int flags;
};
+extern struct snd_soc_dai sh_hdmi_dai;
+extern struct snd_soc_codec_device soc_codec_dev_sh_hdmi;
+
#endif
--
1.7.0.4
More information about the Alsa-devel
mailing list