summaryrefslogtreecommitdiffstats
path: root/sound/soc/sh
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-10-25 17:32:05 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-25 17:32:05 +0200
commit33081adf8b89d5a716d7e1c60171768d39795b39 (patch)
tree275de58bbbb5f7ddffcdc087844cfc7fbe4315be /sound/soc/sh
parentMerge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/... (diff)
parentMerge branch 'topic/hda' into for-linus (diff)
downloadlinux-33081adf8b89d5a716d7e1c60171768d39795b39.tar.xz
linux-33081adf8b89d5a716d7e1c60171768d39795b39.zip
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6: (365 commits) ALSA: hda - Disable sticky PCM stream assignment for AD codecs ALSA: usb - Creative USB X-Fi volume knob support ALSA: ca0106: Use card specific dac id for mute controls. ALSA: ca0106: Allow different sound cards to use different SPI channel mappings. ALSA: ca0106: Create a nice spot for mapping channels to dacs. ALSA: ca0106: Move enabling of front dac out of hardcoded setup sequence. ALSA: ca0106: Pull out dac powering routine into separate function. ALSA: ca0106 - add Sound Blaster 5.1vx info. ASoC: tlv320dac33: Use usleep_range for delays ALSA: usb-audio: add Novation Launchpad support ALSA: hda - Add workarounds for CT-IBG controllers ALSA: hda - Fix wrong TLV mute bit for STAC/IDT codecs ASoC: tpa6130a2: Error handling for broken chip ASoC: max98088: Staticise m98088_eq_band ASoC: soc-core: Fix codec->name memory leak ALSA: hda - Apply ideapad quirk to Acer laptops with Cxt5066 ALSA: hda - Add some workarounds for Creative IBG ALSA: hda - Fix wrong SPDIF NID assignment for CA0110 ALSA: hda - Fix codec rename rules for ALC662-compatible codecs ALSA: hda - Add alc_init_jacks() call to other codecs ...
Diffstat (limited to 'sound/soc/sh')
-rw-r--r--sound/soc/sh/Kconfig11
-rw-r--r--sound/soc/sh/Makefile2
-rw-r--r--sound/soc/sh/dma-sh7760.c53
-rw-r--r--sound/soc/sh/fsi-ak4642.c31
-rw-r--r--sound/soc/sh/fsi-da7210.c24
-rw-r--r--sound/soc/sh/fsi-hdmi.c60
-rw-r--r--sound/soc/sh/fsi.c606
-rw-r--r--sound/soc/sh/hac.c46
-rw-r--r--sound/soc/sh/migor.c29
-rw-r--r--sound/soc/sh/sh7760-ac97.c25
-rw-r--r--sound/soc/sh/siu.h6
-rw-r--r--sound/soc/sh/siu_dai.c97
-rw-r--r--sound/soc/sh/siu_pcm.c32
-rw-r--r--sound/soc/sh/ssi.c55
14 files changed, 619 insertions, 458 deletions
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index 52d7e8ed9c1f..7f0a496e07ce 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -47,7 +47,7 @@ config SND_SH7760_AC97
AC97 unit of the SH7760.
config SND_FSI_AK4642
- bool "FSI-AK4642 sound support"
+ tristate "FSI-AK4642 sound support"
depends on SND_SOC_SH4_FSI && I2C_SH_MOBILE
select SND_SOC_AK4642
help
@@ -55,13 +55,20 @@ config SND_FSI_AK4642
FSI - AK4642 unit
config SND_FSI_DA7210
- bool "FSI-DA7210 sound support"
+ tristate "FSI-DA7210 sound support"
depends on SND_SOC_SH4_FSI && I2C_SH_MOBILE
select SND_SOC_DA7210
help
This option enables generic sound support for the
FSI - DA7210 unit
+config SND_FSI_HDMI
+ tristate "FSI-HDMI sound support"
+ depends on SND_SOC_SH4_FSI && FB_SH_MOBILE_HDMI
+ help
+ This option enables generic sound support for the
+ FSI - HDMI unit
+
config SND_SIU_MIGOR
tristate "SIU sound support on Migo-R"
depends on SH_MIGOR
diff --git a/sound/soc/sh/Makefile b/sound/soc/sh/Makefile
index 8a5a19293bda..94476d4c0fd5 100644
--- a/sound/soc/sh/Makefile
+++ b/sound/soc/sh/Makefile
@@ -16,9 +16,11 @@ obj-$(CONFIG_SND_SOC_SH4_SIU) += snd-soc-siu.o
snd-soc-sh7760-ac97-objs := sh7760-ac97.o
snd-soc-fsi-ak4642-objs := fsi-ak4642.o
snd-soc-fsi-da7210-objs := fsi-da7210.o
+snd-soc-fsi-hdmi-objs := fsi-hdmi.o
snd-soc-migor-objs := migor.o
obj-$(CONFIG_SND_SH7760_AC97) += snd-soc-sh7760-ac97.o
obj-$(CONFIG_SND_FSI_AK4642) += snd-soc-fsi-ak4642.o
obj-$(CONFIG_SND_FSI_DA7210) += snd-soc-fsi-da7210.o
+obj-$(CONFIG_SND_FSI_HDMI) += snd-soc-fsi-hdmi.o
obj-$(CONFIG_SND_SIU_MIGOR) += snd-soc-migor.o
diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c
index 0d8bdf07729c..c326d29992fe 100644
--- a/sound/soc/sh/dma-sh7760.c
+++ b/sound/soc/sh/dma-sh7760.c
@@ -137,7 +137,7 @@ static void camelot_rxdma(void *data)
static int camelot_pcm_open(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id];
+ struct camelot_pcm *cam = &cam_pcm_data[rtd->cpu_dai->id];
int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1;
int ret, dmairq;
@@ -150,7 +150,7 @@ static int camelot_pcm_open(struct snd_pcm_substream *substream)
ret = dmabrg_request_irq(dmairq, camelot_rxdma, cam);
if (unlikely(ret)) {
pr_debug("audio unit %d irqs already taken!\n",
- rtd->dai->cpu_dai->id);
+ rtd->cpu_dai->id);
return -EBUSY;
}
(void)dmabrg_request_irq(dmairq + 1,camelot_rxdma, cam);
@@ -159,7 +159,7 @@ static int camelot_pcm_open(struct snd_pcm_substream *substream)
ret = dmabrg_request_irq(dmairq, camelot_txdma, cam);
if (unlikely(ret)) {
pr_debug("audio unit %d irqs already taken!\n",
- rtd->dai->cpu_dai->id);
+ rtd->cpu_dai->id);
return -EBUSY;
}
(void)dmabrg_request_irq(dmairq + 1, camelot_txdma, cam);
@@ -170,7 +170,7 @@ static int camelot_pcm_open(struct snd_pcm_substream *substream)
static int camelot_pcm_close(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id];
+ struct camelot_pcm *cam = &cam_pcm_data[rtd->cpu_dai->id];
int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1;
int dmairq;
@@ -191,7 +191,7 @@ static int camelot_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id];
+ struct camelot_pcm *cam = &cam_pcm_data[rtd->cpu_dai->id];
int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1;
int ret;
@@ -219,7 +219,7 @@ static int camelot_prepare(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id];
+ struct camelot_pcm *cam = &cam_pcm_data[rtd->cpu_dai->id];
pr_debug("PCM data: addr 0x%08ulx len %d\n",
(u32)runtime->dma_addr, runtime->dma_bytes);
@@ -266,7 +266,7 @@ static inline void dmabrg_rec_dma_stop(struct camelot_pcm *cam)
static int camelot_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id];
+ struct camelot_pcm *cam = &cam_pcm_data[rtd->cpu_dai->id];
int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1;
switch (cmd) {
@@ -293,7 +293,7 @@ static snd_pcm_uframes_t camelot_pos(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id];
+ struct camelot_pcm *cam = &cam_pcm_data[rtd->cpu_dai->id];
int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1;
unsigned long pos;
@@ -342,25 +342,44 @@ static int camelot_pcm_new(struct snd_card *card,
return 0;
}
-struct snd_soc_platform sh7760_soc_platform = {
- .name = "sh7760-pcm",
+static struct snd_soc_platform sh7760_soc_platform = {
.pcm_ops = &camelot_pcm_ops,
.pcm_new = camelot_pcm_new,
.pcm_free = camelot_pcm_free,
};
-EXPORT_SYMBOL_GPL(sh7760_soc_platform);
-static int __init sh7760_soc_platform_init(void)
+static int __devinit sh7760_soc_platform_probe(struct platform_device *pdev)
{
- return snd_soc_register_platform(&sh7760_soc_platform);
+ return snd_soc_register_platform(&pdev->dev, &sh7760_soc_platform);
}
-module_init(sh7760_soc_platform_init);
-static void __exit sh7760_soc_platform_exit(void)
+static int __devexit sh7760_soc_platform_remove(struct platform_device *pdev)
{
- snd_soc_unregister_platform(&sh7760_soc_platform);
+ snd_soc_unregister_platform(&pdev->dev);
+ return 0;
+}
+
+static struct platform_driver sh7760_pcm_driver = {
+ .driver = {
+ .name = "sh7760-pcm-audio",
+ .owner = THIS_MODULE,
+ },
+
+ .probe = sh7760_soc_platform_probe,
+ .remove = __devexit_p(sh7760_soc_platform_remove),
+};
+
+static int __init snd_sh7760_pcm_init(void)
+{
+ return platform_driver_register(&sh7760_pcm_driver);
+}
+module_init(snd_sh7760_pcm_init);
+
+static void __exit snd_sh7760_pcm_exit(void)
+{
+ platform_driver_unregister(&sh7760_pcm_driver);
}
-module_exit(sh7760_soc_platform_exit);
+module_exit(snd_sh7760_pcm_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("SH7760 Audio DMA (DMABRG) driver");
diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c
index dad575a22622..d96602de71de 100644
--- a/sound/soc/sh/fsi-ak4642.c
+++ b/sound/soc/sh/fsi-ak4642.c
@@ -11,17 +11,17 @@
#include <linux/platform_device.h>
#include <sound/sh_fsi.h>
-#include <../sound/soc/codecs/ak4642.h>
-static int fsi_ak4642_dai_init(struct snd_soc_codec *codec)
+static int fsi_ak4642_dai_init(struct snd_soc_pcm_runtime *rtd)
{
+ struct snd_soc_dai *dai = rtd->codec_dai;
int ret;
- ret = snd_soc_dai_set_fmt(&ak4642_dai, SND_SOC_DAIFMT_CBM_CFM);
+ ret = snd_soc_dai_set_fmt(dai, SND_SOC_DAIFMT_CBM_CFM);
if (ret < 0)
return ret;
- ret = snd_soc_dai_set_sysclk(&ak4642_dai, 0, 11289600, 0);
+ ret = snd_soc_dai_set_sysclk(dai, 0, 11289600, 0);
return ret;
}
@@ -29,24 +29,25 @@ static int fsi_ak4642_dai_init(struct snd_soc_codec *codec)
static struct snd_soc_dai_link fsi_dai_link = {
.name = "AK4642",
.stream_name = "AK4642",
- .cpu_dai = &fsi_soc_dai[FSI_PORT_A],
- .codec_dai = &ak4642_dai,
+ .cpu_dai_name = "fsia-dai", /* fsi A */
+ .codec_dai_name = "ak4642-hifi",
+#ifdef CONFIG_MACH_AP4EVB
+ .platform_name = "sh_fsi2",
+ .codec_name = "ak4642-codec.0-0013",
+#else
+ .platform_name = "sh_fsi.0",
+ .codec_name = "ak4642-codec.0-0012",
+#endif
.init = fsi_ak4642_dai_init,
.ops = NULL,
};
static struct snd_soc_card fsi_soc_card = {
- .name = "FSI",
- .platform = &fsi_soc_platform,
+ .name = "FSI (AK4642)",
.dai_link = &fsi_dai_link,
.num_links = 1,
};
-static struct snd_soc_device fsi_snd_devdata = {
- .card = &fsi_soc_card,
- .codec_dev = &soc_codec_dev_ak4642,
-};
-
static struct platform_device *fsi_snd_device;
static int __init fsi_ak4642_init(void)
@@ -57,9 +58,7 @@ static int __init fsi_ak4642_init(void)
if (!fsi_snd_device)
goto out;
- platform_set_drvdata(fsi_snd_device,
- &fsi_snd_devdata);
- fsi_snd_devdata.dev = &fsi_snd_device->dev;
+ platform_set_drvdata(fsi_snd_device, &fsi_soc_card);
ret = platform_device_add(fsi_snd_device);
if (ret)
diff --git a/sound/soc/sh/fsi-da7210.c b/sound/soc/sh/fsi-da7210.c
index 121bbb07bb03..a6adb6e43250 100644
--- a/sound/soc/sh/fsi-da7210.c
+++ b/sound/soc/sh/fsi-da7210.c
@@ -12,11 +12,12 @@
#include <linux/platform_device.h>
#include <sound/sh_fsi.h>
-#include "../codecs/da7210.h"
-static int fsi_da7210_init(struct snd_soc_codec *codec)
+static int fsi_da7210_init(struct snd_soc_pcm_runtime *rtd)
{
- return snd_soc_dai_set_fmt(&da7210_dai,
+ struct snd_soc_dai *dai = rtd->codec_dai;
+
+ return snd_soc_dai_set_fmt(dai,
SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBM_CFM);
}
@@ -24,23 +25,19 @@ static int fsi_da7210_init(struct snd_soc_codec *codec)
static struct snd_soc_dai_link fsi_da7210_dai = {
.name = "DA7210",
.stream_name = "DA7210",
- .cpu_dai = &fsi_soc_dai[FSI_PORT_B],
- .codec_dai = &da7210_dai,
+ .cpu_dai_name = "fsib-dai", /* FSI B */
+ .codec_dai_name = "da7210-hifi",
+ .platform_name = "sh_fsi.0",
+ .codec_name = "da7210-codec.0-001a",
.init = fsi_da7210_init,
};
static struct snd_soc_card fsi_soc_card = {
- .name = "FSI",
- .platform = &fsi_soc_platform,
+ .name = "FSI (DA7210)",
.dai_link = &fsi_da7210_dai,
.num_links = 1,
};
-static struct snd_soc_device fsi_da7210_snd_devdata = {
- .card = &fsi_soc_card,
- .codec_dev = &soc_codec_dev_da7210,
-};
-
static struct platform_device *fsi_da7210_snd_device;
static int __init fsi_da7210_sound_init(void)
@@ -51,8 +48,7 @@ static int __init fsi_da7210_sound_init(void)
if (!fsi_da7210_snd_device)
return -ENOMEM;
- platform_set_drvdata(fsi_da7210_snd_device, &fsi_da7210_snd_devdata);
- fsi_da7210_snd_devdata.dev = &fsi_da7210_snd_device->dev;
+ platform_set_drvdata(fsi_da7210_snd_device, &fsi_soc_card);
ret = platform_device_add(fsi_da7210_snd_device);
if (ret)
platform_device_put(fsi_da7210_snd_device);
diff --git a/sound/soc/sh/fsi-hdmi.c b/sound/soc/sh/fsi-hdmi.c
new file mode 100644
index 000000000000..a52dd8ec71d3
--- /dev/null
+++ b/sound/soc/sh/fsi-hdmi.c
@@ -0,0 +1,60 @@
+/*
+ * FSI - HDMI sound support
+ *
+ * Copyright (C) 2010 Renesas Solutions Corp.
+ * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/platform_device.h>
+#include <sound/sh_fsi.h>
+
+static struct snd_soc_dai_link fsi_dai_link = {
+ .name = "HDMI",
+ .stream_name = "HDMI",
+ .cpu_dai_name = "fsib-dai", /* fsi B */
+ .codec_dai_name = "sh_mobile_hdmi-hifi",
+ .platform_name = "sh_fsi2",
+ .codec_name = "sh-mobile-hdmi",
+};
+
+static struct snd_soc_card fsi_soc_card = {
+ .name = "FSI (SH MOBILE HDMI)",
+ .dai_link = &fsi_dai_link,
+ .num_links = 1,
+};
+
+static struct platform_device *fsi_snd_device;
+
+static int __init fsi_hdmi_init(void)
+{
+ int ret = -ENOMEM;
+
+ fsi_snd_device = platform_device_alloc("soc-audio", FSI_PORT_B);
+ if (!fsi_snd_device)
+ goto out;
+
+ platform_set_drvdata(fsi_snd_device, &fsi_soc_card);
+ ret = platform_device_add(fsi_snd_device);
+
+ if (ret)
+ platform_device_put(fsi_snd_device);
+
+out:
+ return ret;
+}
+
+static void __exit fsi_hdmi_exit(void)
+{
+ platform_device_unregister(fsi_snd_device);
+}
+
+module_init(fsi_hdmi_init);
+module_exit(fsi_hdmi_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Generic SH4 FSI-HDMI sound card");
+MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 58c6bec642de..507e709f2807 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -80,11 +80,12 @@
#define B_CLK 0x00000010
#define A_CLK 0x00000001
-/* INT_ST */
-#define INT_B_IN (1 << 12)
-#define INT_B_OUT (1 << 8)
-#define INT_A_IN (1 << 4)
-#define INT_A_OUT (1 << 0)
+/* IO SHIFT / MACRO */
+#define BI_SHIFT 12
+#define BO_SHIFT 8
+#define AI_SHIFT 4
+#define AO_SHIFT 0
+#define AB_IO(param, shift) (param << shift)
/* SOFT_RST */
#define PBSR (1 << 12) /* Port B Software Reset */
@@ -93,33 +94,43 @@
#define FSISR (1 << 0) /* Software Reset */
/* FIFO_SZ */
-#define OUT_SZ_MASK 0x7
-#define BO_SZ_SHIFT 8
-#define AO_SZ_SHIFT 0
+#define FIFO_SZ_MASK 0x7
#define FSI_RATES SNDRV_PCM_RATE_8000_96000
#define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
-/************************************************************************
+/*
+ * FSI driver use below type name for variable
+ *
+ * xxx_len : data length
+ * xxx_width : data width
+ * xxx_offset : data offset
+ * xxx_num : number of data
+ */
+
+/*
+ * struct
+ */
+struct fsi_stream {
+ struct snd_pcm_substream *substream;
- struct
+ int fifo_max_num;
+ int chan_num;
+ int buff_offset;
+ int buff_len;
+ int period_len;
+ int period_num;
+};
-************************************************************************/
struct fsi_priv {
void __iomem *base;
- struct snd_pcm_substream *substream;
struct fsi_master *master;
- int fifo_max;
- int chan;
-
- int byte_offset;
- int period_len;
- int buffer_len;
- int periods;
+ struct fsi_stream playback;
+ struct fsi_stream capture;
u32 mst_ctrl;
};
@@ -142,13 +153,10 @@ struct fsi_master {
spinlock_t lock;
};
-/************************************************************************
-
-
- basic read write function
-
+/*
+ * basic read write function
+ */
-************************************************************************/
static void __fsi_reg_write(u32 reg, u32 data)
{
/* valid data area is 24bit */
@@ -251,13 +259,10 @@ static void fsi_master_mask_set(struct fsi_master *master,
spin_unlock_irqrestore(&master->lock, flags);
}
-/************************************************************************
-
-
- basic function
-
+/*
+ * basic function
+ */
-************************************************************************/
static struct fsi_master *fsi_get_master(struct fsi_priv *fsi)
{
return fsi->master;
@@ -271,16 +276,19 @@ static int fsi_is_port_a(struct fsi_priv *fsi)
static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai_link *machine = rtd->dai;
- return machine->cpu_dai;
+ return rtd->cpu_dai;
}
static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream)
{
struct snd_soc_dai *dai = fsi_get_dai(substream);
+ struct fsi_master *master = snd_soc_dai_get_drvdata(dai);
- return dai->private_data;
+ if (dai->id == 0)
+ return &master->fsia;
+ else
+ return &master->fsib;
}
static u32 fsi_get_info_flags(struct fsi_priv *fsi)
@@ -292,6 +300,22 @@ static u32 fsi_get_info_flags(struct fsi_priv *fsi)
master->info->portb_flags;
}
+static inline int fsi_stream_is_play(int stream)
+{
+ return stream == SNDRV_PCM_STREAM_PLAYBACK;
+}
+
+static inline int fsi_is_play(struct snd_pcm_substream *substream)
+{
+ return fsi_stream_is_play(substream->stream);
+}
+
+static inline struct fsi_stream *fsi_get_stream(struct fsi_priv *fsi,
+ int is_play)
+{
+ return is_play ? &fsi->playback : &fsi->capture;
+}
+
static int fsi_is_master_mode(struct fsi_priv *fsi, int is_play)
{
u32 mode;
@@ -307,63 +331,144 @@ static int fsi_is_master_mode(struct fsi_priv *fsi, int is_play)
return (mode & flags) != mode;
}
-static u32 fsi_port_ab_io_bit(struct fsi_priv *fsi, int is_play)
+static u32 fsi_get_port_shift(struct fsi_priv *fsi, int is_play)
{
int is_porta = fsi_is_port_a(fsi);
- u32 data;
+ u32 shift;
if (is_porta)
- data = is_play ? (1 << 0) : (1 << 4);
+ shift = is_play ? AO_SHIFT : AI_SHIFT;
else
- data = is_play ? (1 << 8) : (1 << 12);
+ shift = is_play ? BO_SHIFT : BI_SHIFT;
- return data;
+ return shift;
}
static void fsi_stream_push(struct fsi_priv *fsi,
+ int is_play,
struct snd_pcm_substream *substream,
u32 buffer_len,
u32 period_len)
{
- fsi->substream = substream;
- fsi->buffer_len = buffer_len;
- fsi->period_len = period_len;
- fsi->byte_offset = 0;
- fsi->periods = 0;
+ struct fsi_stream *io = fsi_get_stream(fsi, is_play);
+
+ io->substream = substream;
+ io->buff_len = buffer_len;
+ io->buff_offset = 0;
+ io->period_len = period_len;
+ io->period_num = 0;
}
-static void fsi_stream_pop(struct fsi_priv *fsi)
+static void fsi_stream_pop(struct fsi_priv *fsi, int is_play)
{
- fsi->substream = NULL;
- fsi->buffer_len = 0;
- fsi->period_len = 0;
- fsi->byte_offset = 0;
- fsi->periods = 0;
+ struct fsi_stream *io = fsi_get_stream(fsi, is_play);
+
+ io->substream = NULL;
+ io->buff_len = 0;
+ io->buff_offset = 0;
+ io->period_len = 0;
+ io->period_num = 0;
}
-static int fsi_get_fifo_residue(struct fsi_priv *fsi, int is_play)
+static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play)
{
u32 status;
u32 reg = is_play ? DOFF_ST : DIFF_ST;
- int residue;
+ struct fsi_stream *io = fsi_get_stream(fsi, is_play);
+ int data_num;
status = fsi_reg_read(fsi, reg);
- residue = 0x1ff & (status >> 8);
- residue *= fsi->chan;
+ data_num = 0x1ff & (status >> 8);
+ data_num *= io->chan_num;
+
+ return data_num;
+}
+
+static int fsi_len2num(int len, int width)
+{
+ return len / width;
+}
+
+#define fsi_num2offset(a, b) fsi_num2len(a, b)
+static int fsi_num2len(int num, int width)
+{
+ return num * width;
+}
+
+static int fsi_get_frame_width(struct fsi_priv *fsi, int is_play)
+{
+ struct fsi_stream *io = fsi_get_stream(fsi, is_play);
+ struct snd_pcm_substream *substream = io->substream;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ return frames_to_bytes(runtime, 1) / io->chan_num;
+}
+
+/*
+ * dma function
+ */
+
+static u8 *fsi_dma_get_area(struct fsi_priv *fsi, int stream)
+{
+ int is_play = fsi_stream_is_play(stream);
+ struct fsi_stream *io = fsi_get_stream(fsi, is_play);
+
+ return io->substream->runtime->dma_area + io->buff_offset;
+}
+
+static void fsi_dma_soft_push16(struct fsi_priv *fsi, int num)
+{
+ u16 *start;
+ int i;
+
+ start = (u16 *)fsi_dma_get_area(fsi, SNDRV_PCM_STREAM_PLAYBACK);
+
+ for (i = 0; i < num; i++)
+ fsi_reg_write(fsi, DODT, ((u32)*(start + i) << 8));
+}
+
+static void fsi_dma_soft_pop16(struct fsi_priv *fsi, int num)
+{
+ u16 *start;
+ int i;
- return residue;
+ start = (u16 *)fsi_dma_get_area(fsi, SNDRV_PCM_STREAM_CAPTURE);
+
+
+ for (i = 0; i < num; i++)
+ *(start + i) = (u16)(fsi_reg_read(fsi, DIDT) >> 8);
}
-/************************************************************************
+static void fsi_dma_soft_push32(struct fsi_priv *fsi, int num)
+{
+ u32 *start;
+ int i;
+
+ start = (u32 *)fsi_dma_get_area(fsi, SNDRV_PCM_STREAM_PLAYBACK);
+
+
+ for (i = 0; i < num; i++)
+ fsi_reg_write(fsi, DODT, *(start + i));
+}
+static void fsi_dma_soft_pop32(struct fsi_priv *fsi, int num)
+{
+ u32 *start;
+ int i;
- irq function
+ start = (u32 *)fsi_dma_get_area(fsi, SNDRV_PCM_STREAM_CAPTURE);
+ for (i = 0; i < num; i++)
+ *(start + i) = fsi_reg_read(fsi, DIDT);
+}
+
+/*
+ * irq function
+ */
-************************************************************************/
static void fsi_irq_enable(struct fsi_priv *fsi, int is_play)
{
- u32 data = fsi_port_ab_io_bit(fsi, is_play);
+ u32 data = AB_IO(1, fsi_get_port_shift(fsi, is_play));
struct fsi_master *master = fsi_get_master(fsi);
fsi_master_mask_set(master, master->core->imsk, data, data);
@@ -372,7 +477,7 @@ static void fsi_irq_enable(struct fsi_priv *fsi, int is_play)
static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
{
- u32 data = fsi_port_ab_io_bit(fsi, is_play);
+ u32 data = AB_IO(1, fsi_get_port_shift(fsi, is_play));
struct fsi_master *master = fsi_get_master(fsi);
fsi_master_mask_set(master, master->core->imsk, data, 0);
@@ -394,20 +499,18 @@ static void fsi_irq_clear_status(struct fsi_priv *fsi)
u32 data = 0;
struct fsi_master *master = fsi_get_master(fsi);
- data |= fsi_port_ab_io_bit(fsi, 0);
- data |= fsi_port_ab_io_bit(fsi, 1);
+ data |= AB_IO(1, fsi_get_port_shift(fsi, 0));
+ data |= AB_IO(1, fsi_get_port_shift(fsi, 1));
/* clear interrupt factor */
fsi_master_mask_set(master, master->core->int_st, data, 0);
}
-/************************************************************************
-
-
- SPDIF master clock function
-
-These functions are used later FSI2
-************************************************************************/
+/*
+ * SPDIF master clock function
+ *
+ * These functions are used later FSI2
+ */
static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable)
{
struct fsi_master *master = fsi_get_master(fsi);
@@ -424,13 +527,10 @@ static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable)
fsi_master_mask_set(master, fsi->mst_ctrl, val, 0);
}
-/************************************************************************
-
-
- ctrl function
-
+/*
+ * ctrl function
+ */
-************************************************************************/
static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable)
{
u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4);
@@ -447,14 +547,15 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
struct snd_soc_dai *dai)
{
struct fsi_master *master = fsi_get_master(fsi);
+ struct fsi_stream *io = fsi_get_stream(fsi, is_play);
u32 ctrl, shift, i;
/* get on-chip RAM capacity */
shift = fsi_master_read(master, FIFO_SZ);
- shift >>= fsi_is_port_a(fsi) ? AO_SZ_SHIFT : BO_SZ_SHIFT;
- shift &= OUT_SZ_MASK;
- fsi->fifo_max = 256 << shift;
- dev_dbg(dai->dev, "fifo = %d words\n", fsi->fifo_max);
+ shift >>= fsi_get_port_shift(fsi, is_play);
+ shift &= FIFO_SZ_MASK;
+ io->fifo_max_num = 256 << shift;
+ dev_dbg(dai->dev, "fifo = %d words\n", io->fifo_max_num);
/*
* The maximum number of sample data varies depending
@@ -475,9 +576,10 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
* 7 channels: 32 ( 32 x 7 = 224)
* 8 channels: 32 ( 32 x 8 = 256)
*/
- for (i = 1; i < fsi->chan; i <<= 1)
- fsi->fifo_max >>= 1;
- dev_dbg(dai->dev, "%d channel %d store\n", fsi->chan, fsi->fifo_max);
+ for (i = 1; i < io->chan_num; i <<= 1)
+ io->fifo_max_num >>= 1;
+ dev_dbg(dai->dev, "%d channel %d store\n",
+ io->chan_num, io->fifo_max_num);
ctrl = is_play ? DOFF_CTL : DIFF_CTL;
@@ -500,84 +602,114 @@ static void fsi_soft_all_reset(struct fsi_master *master)
mdelay(10);
}
-/* playback interrupt */
-static int fsi_data_push(struct fsi_priv *fsi, int startup)
+static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int startup, int stream)
{
struct snd_pcm_runtime *runtime;
struct snd_pcm_substream *substream = NULL;
- u32 status;
- int send;
- int fifo_free;
- int width;
- u8 *start;
- int i, over_period;
+ int is_play = fsi_stream_is_play(stream);
+ struct fsi_stream *io = fsi_get_stream(fsi, is_play);
+ u32 status_reg = is_play ? DOFF_ST : DIFF_ST;
+ int data_residue_num;
+ int data_num;
+ int data_num_max;
+ int ch_width;
+ int over_period;
+ void (*fn)(struct fsi_priv *fsi, int size);
if (!fsi ||
- !fsi->substream ||
- !fsi->substream->runtime)
+ !io->substream ||
+ !io->substream->runtime)
return -EINVAL;
over_period = 0;
- substream = fsi->substream;
+ substream = io->substream;
runtime = substream->runtime;
/* FSI FIFO has limit.
* So, this driver can not send periods data at a time
*/
- if (fsi->byte_offset >=
- fsi->period_len * (fsi->periods + 1)) {
+ if (io->buff_offset >=
+ fsi_num2offset(io->period_num + 1, io->period_len)) {
over_period = 1;
- fsi->periods = (fsi->periods + 1) % runtime->periods;
+ io->period_num = (io->period_num + 1) % runtime->periods;
- if (0 == fsi->periods)
- fsi->byte_offset = 0;
+ if (0 == io->period_num)
+ io->buff_offset = 0;
}
/* get 1 channel data width */
- width = frames_to_bytes(runtime, 1) / fsi->chan;
-
- /* get send size for alsa */
- send = (fsi->buffer_len - fsi->byte_offset) / width;
-
- /* get FIFO free size */
- fifo_free = (fsi->fifo_max * fsi->chan) - fsi_get_fifo_residue(fsi, 1);
-
- /* size check */
- if (fifo_free < send)
- send = fifo_free;
+ ch_width = fsi_get_frame_width(fsi, is_play);
+
+ /* get residue data number of alsa */
+ data_residue_num = fsi_len2num(io->buff_len - io->buff_offset,
+ ch_width);
+
+ if (is_play) {
+ /*
+ * for play-back
+ *
+ * data_num_max : number of FSI fifo free space
+ * data_num : number of ALSA residue data
+ */
+ data_num_max = io->fifo_max_num * io->chan_num;
+ data_num_max -= fsi_get_fifo_data_num(fsi, is_play);
+
+ data_num = data_residue_num;
+
+ switch (ch_width) {
+ case 2:
+ fn = fsi_dma_soft_push16;
+ break;
+ case 4:
+ fn = fsi_dma_soft_push32;
+ break;
+ default:
+ return -EINVAL;
+ }
+ } else {
+ /*
+ * for capture
+ *
+ * data_num_max : number of ALSA free space
+ * data_num : number of data in FSI fifo
+ */
+ data_num_max = data_residue_num;
+ data_num = fsi_get_fifo_data_num(fsi, is_play);
+
+ switch (ch_width) {
+ case 2:
+ fn = fsi_dma_soft_pop16;
+ break;
+ case 4:
+ fn = fsi_dma_soft_pop32;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
- start = runtime->dma_area;
- start += fsi->byte_offset;
+ data_num = min(data_num, data_num_max);
- switch (width) {
- case 2:
- for (i = 0; i < send; i++)
- fsi_reg_write(fsi, DODT,
- ((u32)*((u16 *)start + i) << 8));
- break;
- case 4:
- for (i = 0; i < send; i++)
- fsi_reg_write(fsi, DODT, *((u32 *)start + i));
- break;
- default:
- return -EINVAL;
- }
+ fn(fsi, data_num);
- fsi->byte_offset += send * width;
+ /* update buff_offset */
+ io->buff_offset += fsi_num2offset(data_num, ch_width);
- status = fsi_reg_read(fsi, DOFF_ST);
+ /* check fifo status */
if (!startup) {
struct snd_soc_dai *dai = fsi_get_dai(substream);
+ u32 status = fsi_reg_read(fsi, status_reg);
if (status & ERR_OVER)
dev_err(dai->dev, "over run\n");
if (status & ERR_UNDER)
dev_err(dai->dev, "under run\n");
}
- fsi_reg_write(fsi, DOFF_ST, 0);
+ fsi_reg_write(fsi, status_reg, 0);
- fsi_irq_enable(fsi, 1);
+ /* re-enable irq */
+ fsi_irq_enable(fsi, is_play);
if (over_period)
snd_pcm_period_elapsed(substream);
@@ -587,85 +719,12 @@ static int fsi_data_push(struct fsi_priv *fsi, int startup)
static int fsi_data_pop(struct fsi_priv *fsi, int startup)
{
- struct snd_pcm_runtime *runtime;
- struct snd_pcm_substream *substream = NULL;
- u32 status;
- int free;
- int fifo_fill;
- int width;
- u8 *start;
- int i, over_period;
-
- if (!fsi ||
- !fsi->substream ||
- !fsi->substream->runtime)
- return -EINVAL;
-
- over_period = 0;
- substream = fsi->substream;
- runtime = substream->runtime;
-
- /* FSI FIFO has limit.
- * So, this driver can not send periods data at a time
- */
- if (fsi->byte_offset >=
- fsi->period_len * (fsi->periods + 1)) {
-
- over_period = 1;
- fsi->periods = (fsi->periods + 1) % runtime->periods;
-
- if (0 == fsi->periods)
- fsi->byte_offset = 0;
- }
-
- /* get 1 channel data width */
- width = frames_to_bytes(runtime, 1) / fsi->chan;
-
- /* get free space for alsa */
- free = (fsi->buffer_len - fsi->byte_offset) / width;
-
- /* get recv size */
- fifo_fill = fsi_get_fifo_residue(fsi, 0);
-
- if (free < fifo_fill)
- fifo_fill = free;
-
- start = runtime->dma_area;
- start += fsi->byte_offset;
-
- switch (width) {
- case 2:
- for (i = 0; i < fifo_fill; i++)
- *((u16 *)start + i) =
- (u16)(fsi_reg_read(fsi, DIDT) >> 8);
- break;
- case 4:
- for (i = 0; i < fifo_fill; i++)
- *((u32 *)start + i) = fsi_reg_read(fsi, DIDT);
- break;
- default:
- return -EINVAL;
- }
-
- fsi->byte_offset += fifo_fill * width;
-
- status = fsi_reg_read(fsi, DIFF_ST);
- if (!startup) {
- struct snd_soc_dai *dai = fsi_get_dai(substream);
-
- if (status & ERR_OVER)
- dev_err(dai->dev, "over run\n");
- if (status & ERR_UNDER)
- dev_err(dai->dev, "under run\n");
- }
- fsi_reg_write(fsi, DIFF_ST, 0);
-
- fsi_irq_enable(fsi, 0);
-
- if (over_period)
- snd_pcm_period_elapsed(substream);
+ return fsi_fifo_data_ctrl(fsi, startup, SNDRV_PCM_STREAM_CAPTURE);
+}
- return 0;
+static int fsi_data_push(struct fsi_priv *fsi, int startup)
+{
+ return fsi_fifo_data_ctrl(fsi, startup, SNDRV_PCM_STREAM_PLAYBACK);
}
static irqreturn_t fsi_interrupt(int irq, void *data)
@@ -677,13 +736,13 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
fsi_master_mask_set(master, SOFT_RST, IR, 0);
fsi_master_mask_set(master, SOFT_RST, IR, IR);
- if (int_st & INT_A_OUT)
+ if (int_st & AB_IO(1, AO_SHIFT))
fsi_data_push(&master->fsia, 0);
- if (int_st & INT_B_OUT)
+ if (int_st & AB_IO(1, BO_SHIFT))
fsi_data_push(&master->fsib, 0);
- if (int_st & INT_A_IN)
+ if (int_st & AB_IO(1, AI_SHIFT))
fsi_data_pop(&master->fsia, 0);
- if (int_st & INT_B_IN)
+ if (int_st & AB_IO(1, BI_SHIFT))
fsi_data_pop(&master->fsib, 0);
fsi_irq_clear_all_status(master);
@@ -691,25 +750,24 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
return IRQ_HANDLED;
}
-/************************************************************************
-
-
- dai ops
-
+/*
+ * dai ops
+ */
-************************************************************************/
static int fsi_dai_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct fsi_priv *fsi = fsi_get_priv(substream);
- u32 flags = fsi_get_info_flags(fsi);
struct fsi_master *master = fsi_get_master(fsi);
+ struct fsi_stream *io;
+ u32 flags = fsi_get_info_flags(fsi);
u32 fmt;
u32 reg;
u32 data;
- int is_play = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
+ int is_play = fsi_is_play(substream);
int is_master;
- int ret = 0;
+
+ io = fsi_get_stream(fsi, is_play);
pm_runtime_get_sync(dai->dev);
@@ -741,29 +799,29 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
switch (fmt) {
case SH_FSI_FMT_MONO:
data = CR_MONO;
- fsi->chan = 1;
+ io->chan_num = 1;
break;
case SH_FSI_FMT_MONO_DELAY:
data = CR_MONO_D;
- fsi->chan = 1;
+ io->chan_num = 1;
break;
case SH_FSI_FMT_PCM:
data = CR_PCM;
- fsi->chan = 2;
+ io->chan_num = 2;
break;
case SH_FSI_FMT_I2S:
data = CR_I2S;
- fsi->chan = 2;
+ io->chan_num = 2;
break;
case SH_FSI_FMT_TDM:
- fsi->chan = is_play ?
+ io->chan_num = is_play ?
SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags);
- data = CR_TDM | (fsi->chan - 1);
+ data = CR_TDM | (io->chan_num - 1);
break;
case SH_FSI_FMT_TDM_DELAY:
- fsi->chan = is_play ?
+ io->chan_num = is_play ?
SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags);
- data = CR_TDM_D | (fsi->chan - 1);
+ data = CR_TDM_D | (io->chan_num - 1);
break;
case SH_FSI_FMT_SPDIF:
if (master->core->ver < 2) {
@@ -771,7 +829,7 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
return -EINVAL;
}
data = CR_SPDIF;
- fsi->chan = 2;
+ io->chan_num = 2;
fsi_spdif_clk_ctrl(fsi, 1);
fsi_reg_mask_set(fsi, OUT_SEL, 0x0010, 0x0010);
break;
@@ -788,14 +846,14 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
/* fifo init */
fsi_fifo_init(fsi, is_play, dai);
- return ret;
+ return 0;
}
static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct fsi_priv *fsi = fsi_get_priv(substream);
- int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+ int is_play = fsi_is_play(substream);
fsi_irq_disable(fsi, is_play);
fsi_clk_ctrl(fsi, 0);
@@ -808,19 +866,19 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
{
struct fsi_priv *fsi = fsi_get_priv(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
- int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+ int is_play = fsi_is_play(substream);
int ret = 0;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
- fsi_stream_push(fsi, substream,
+ fsi_stream_push(fsi, is_play, substream,
frames_to_bytes(runtime, runtime->buffer_size),
frames_to_bytes(runtime, runtime->period_size));
ret = is_play ? fsi_data_push(fsi, 1) : fsi_data_pop(fsi, 1);
break;
case SNDRV_PCM_TRIGGER_STOP:
fsi_irq_disable(fsi, is_play);
- fsi_stream_pop(fsi);
+ fsi_stream_pop(fsi, is_play);
break;
}
@@ -835,7 +893,7 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
struct fsi_master *master = fsi_get_master(fsi);
int (*set_rate)(int is_porta, int rate) = master->info->set_rate;
int fsi_ver = master->core->ver;
- int is_play = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
+ int is_play = fsi_is_play(substream);
int ret;
/* if slave mode, set_rate is not needed */
@@ -916,13 +974,10 @@ static struct snd_soc_dai_ops fsi_dai_ops = {
.hw_params = fsi_dai_hw_params,
};
-/************************************************************************
-
-
- pcm ops
-
+/*
+ * pcm ops
+ */
-************************************************************************/
static struct snd_pcm_hardware fsi_pcm_hardware = {
.info = SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP |
@@ -971,9 +1026,10 @@ static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct fsi_priv *fsi = fsi_get_priv(substream);
+ struct fsi_stream *io = fsi_get_stream(fsi, fsi_is_play(substream));
long location;
- location = (fsi->byte_offset - 1);
+ location = (io->buff_offset - 1);
if (location < 0)
location = 0;
@@ -988,13 +1044,10 @@ static struct snd_pcm_ops fsi_pcm_ops = {
.pointer = fsi_pointer,
};
-/************************************************************************
-
-
- snd_soc_platform
-
+/*
+ * snd_soc_platform
+ */
-************************************************************************/
#define PREALLOC_BUFFER (32 * 1024)
#define PREALLOC_BUFFER_MAX (32 * 1024)
@@ -1018,17 +1071,13 @@ static int fsi_pcm_new(struct snd_card *card,
PREALLOC_BUFFER, PREALLOC_BUFFER_MAX);
}
-/************************************************************************
-
-
- alsa struct
-
+/*
+ * alsa struct
+ */
-************************************************************************/
-struct snd_soc_dai fsi_soc_dai[] = {
+static struct snd_soc_dai_driver fsi_soc_dai[] = {
{
- .name = "FSIA",
- .id = 0,
+ .name = "fsia-dai",
.playback = {
.rates = FSI_RATES,
.formats = FSI_FMTS,
@@ -1044,8 +1093,7 @@ struct snd_soc_dai fsi_soc_dai[] = {
.ops = &fsi_dai_ops,
},
{
- .name = "FSIB",
- .id = 1,
+ .name = "fsib-dai",
.playback = {
.rates = FSI_RATES,
.formats = FSI_FMTS,
@@ -1061,23 +1109,17 @@ struct snd_soc_dai fsi_soc_dai[] = {
.ops = &fsi_dai_ops,
},
};
-EXPORT_SYMBOL_GPL(fsi_soc_dai);
-struct snd_soc_platform fsi_soc_platform = {
- .name = "fsi-pcm",
- .pcm_ops = &fsi_pcm_ops,
+static struct snd_soc_platform_driver fsi_soc_platform = {
+ .ops = &fsi_pcm_ops,
.pcm_new = fsi_pcm_new,
.pcm_free = fsi_pcm_free,
};
-EXPORT_SYMBOL_GPL(fsi_soc_platform);
-
-/************************************************************************
-
-
- platform function
+/*
+ * platform function
+ */
-************************************************************************/
static int fsi_probe(struct platform_device *pdev)
{
struct fsi_master *master;
@@ -1132,11 +1174,7 @@ static int fsi_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
pm_runtime_resume(&pdev->dev);
-
- fsi_soc_dai[0].dev = &pdev->dev;
- fsi_soc_dai[0].private_data = &master->fsia;
- fsi_soc_dai[1].dev = &pdev->dev;
- fsi_soc_dai[1].private_data = &master->fsib;
+ dev_set_drvdata(&pdev->dev, master);
fsi_soft_all_reset(master);
@@ -1147,13 +1185,13 @@ static int fsi_probe(struct platform_device *pdev)
goto exit_iounmap;
}
- ret = snd_soc_register_platform(&fsi_soc_platform);
+ ret = snd_soc_register_platform(&pdev->dev, &fsi_soc_platform);
if (ret < 0) {
dev_err(&pdev->dev, "cannot snd soc register\n");
goto exit_free_irq;
}
- return snd_soc_register_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai));
+ return snd_soc_register_dais(&pdev->dev, fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai));
exit_free_irq:
free_irq(irq, master);
@@ -1171,10 +1209,10 @@ static int fsi_remove(struct platform_device *pdev)
{
struct fsi_master *master;
- master = fsi_get_master(fsi_soc_dai[0].private_data);
+ master = dev_get_drvdata(&pdev->dev);
- snd_soc_unregister_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai));
- snd_soc_unregister_platform(&fsi_soc_platform);
+ snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(fsi_soc_dai));
+ snd_soc_unregister_platform(&pdev->dev);
pm_runtime_disable(&pdev->dev);
@@ -1183,11 +1221,6 @@ static int fsi_remove(struct platform_device *pdev)
iounmap(master->base);
kfree(master);
- fsi_soc_dai[0].dev = NULL;
- fsi_soc_dai[0].private_data = NULL;
- fsi_soc_dai[1].dev = NULL;
- fsi_soc_dai[1].private_data = NULL;
-
return 0;
}
@@ -1229,11 +1262,13 @@ static struct fsi_core fsi2_core = {
static struct platform_device_id fsi_id_table[] = {
{ "sh_fsi", (kernel_ulong_t)&fsi1_core },
{ "sh_fsi2", (kernel_ulong_t)&fsi2_core },
+ {},
};
+MODULE_DEVICE_TABLE(platform, fsi_id_table);
static struct platform_driver fsi_driver = {
.driver = {
- .name = "sh_fsi",
+ .name = "fsi-pcm-audio",
.pm = &fsi_pm_ops,
},
.probe = fsi_probe,
@@ -1250,6 +1285,7 @@ static void __exit fsi_mobile_exit(void)
{
platform_driver_unregister(&fsi_driver);
}
+
module_init(fsi_mobile_init);
module_exit(fsi_mobile_exit);
diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c
index 41db75af3c69..c87e3ff28a0a 100644
--- a/sound/soc/sh/hac.c
+++ b/sound/soc/sh/hac.c
@@ -239,8 +239,7 @@ static int hac_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct hac_priv *hac = &hac_cpu_data[rtd->dai->cpu_dai->id];
+ struct hac_priv *hac = &hac_cpu_data[dai->id];
int d = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
switch (params->msbits) {
@@ -271,10 +270,9 @@ static struct snd_soc_dai_ops hac_dai_ops = {
.hw_params = hac_hw_params,
};
-struct snd_soc_dai sh4_hac_dai[] = {
+static struct snd_soc_dai_driver sh4_hac_dai[] = {
{
- .name = "HAC0",
- .id = 0,
+ .name = "hac-dai.0",
.ac97_control = 1,
.playback = {
.rates = AC97_RATES,
@@ -292,8 +290,7 @@ struct snd_soc_dai sh4_hac_dai[] = {
},
#ifdef CONFIG_CPU_SUBTYPE_SH7760
{
- .name = "HAC1",
- .ac97_control = 1,
+ .name = "hac-dai.1",
.id = 1,
.playback = {
.rates = AC97_RATES,
@@ -312,19 +309,40 @@ struct snd_soc_dai sh4_hac_dai[] = {
},
#endif
};
-EXPORT_SYMBOL_GPL(sh4_hac_dai);
-static int __init sh4_hac_init(void)
+static int __devinit hac_soc_platform_probe(struct platform_device *pdev)
+{
+ return snd_soc_register_dais(&pdev->dev, sh4_hac_dai,
+ ARRAY_SIZE(sh4_hac_dai));
+}
+
+static int __devexit hac_soc_platform_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(sh4_hac_dai));
+ return 0;
+}
+
+static struct platform_driver hac_pcm_driver = {
+ .driver = {
+ .name = "hac-pcm-audio",
+ .owner = THIS_MODULE,
+ },
+
+ .probe = hac_soc_platform_probe,
+ .remove = __devexit_p(hac_soc_platform_remove),
+};
+
+static int __init sh4_hac_pcm_init(void)
{
- return snd_soc_register_dais(sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai));
+ return platform_driver_register(&hac_pcm_driver);
}
-module_init(sh4_hac_init);
+module_init(sh4_hac_pcm_init);
-static void __exit sh4_hac_exit(void)
+static void __exit sh4_hac_pcm_exit(void)
{
- snd_soc_unregister_dais(sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai));
+ platform_driver_unregister(&hac_pcm_driver);
}
-module_exit(sh4_hac_exit);
+module_exit(sh4_hac_pcm_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("SuperH onchip HAC (AC97) audio driver");
diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c
index 87e2b7fcbf17..ac6c49ce6fdf 100644
--- a/sound/soc/sh/migor.c
+++ b/sound/soc/sh/migor.c
@@ -51,7 +51,7 @@ static int migor_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
int ret;
unsigned int rate = params_rate(params);
@@ -69,7 +69,7 @@ static int migor_hw_params(struct snd_pcm_substream *substream,
if (ret < 0)
return ret;
- ret = snd_soc_dai_set_fmt(rtd->dai->cpu_dai, SND_SOC_DAIFMT_NB_IF |
+ ret = snd_soc_dai_set_fmt(rtd->cpu_dai, SND_SOC_DAIFMT_NB_IF |
SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS);
if (ret < 0)
return ret;
@@ -82,7 +82,7 @@ static int migor_hw_params(struct snd_pcm_substream *substream,
clk_set_rate(&siumckb_clk, codec_freq);
dev_dbg(codec_dai->dev, "%s: configure %luHz\n", __func__, codec_freq);
- ret = snd_soc_dai_set_sysclk(rtd->dai->cpu_dai, SIU_CLKB_EXT,
+ ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, SIU_CLKB_EXT,
codec_freq / 2, SND_SOC_CLOCK_IN);
if (!ret)
@@ -94,7 +94,7 @@ static int migor_hw_params(struct snd_pcm_substream *substream,
static int migor_hw_free(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
if (use_count) {
use_count--;
@@ -137,8 +137,10 @@ static const struct snd_soc_dapm_route audio_map[] = {
{ "Mic Bias", NULL, "External Microphone" },
};
-static int migor_dai_init(struct snd_soc_codec *codec)
+static int migor_dai_init(struct snd_soc_pcm_runtime *rtd)
{
+ struct snd_soc_codec *codec = rtd->codec;
+
snd_soc_dapm_new_controls(codec, migor_dapm_widgets,
ARRAY_SIZE(migor_dapm_widgets));
@@ -151,8 +153,10 @@ static int migor_dai_init(struct snd_soc_codec *codec)
static struct snd_soc_dai_link migor_dai = {
.name = "wm8978",
.stream_name = "WM8978",
- .cpu_dai = &siu_i2s_dai,
- .codec_dai = &wm8978_dai,
+ .cpu_dai_name = "siu-i2s-dai",
+ .codec_dai_name = "wm8978-hifi",
+ .platform_name = "siu-pcm-audio",
+ .codec_name = "wm8978.0-001a",
.ops = &migor_dai_ops,
.init = migor_dai_init,
};
@@ -160,17 +164,10 @@ static struct snd_soc_dai_link migor_dai = {
/* migor audio machine driver */
static struct snd_soc_card snd_soc_migor = {
.name = "Migo-R",
- .platform = &siu_platform,
.dai_link = &migor_dai,
.num_links = 1,
};
-/* migor audio subsystem */
-static struct snd_soc_device migor_snd_devdata = {
- .card = &snd_soc_migor,
- .codec_dev = &soc_codec_dev_wm8978,
-};
-
static struct platform_device *migor_snd_device;
static int __init migor_init(void)
@@ -195,9 +192,7 @@ static int __init migor_init(void)
goto epdevalloc;
}
- platform_set_drvdata(migor_snd_device, &migor_snd_devdata);
-
- migor_snd_devdata.dev = &migor_snd_device->dev;
+ platform_set_drvdata(migor_snd_device, &snd_soc_migor);
ret = platform_device_add(migor_snd_device);
if (ret)
diff --git a/sound/soc/sh/sh7760-ac97.c b/sound/soc/sh/sh7760-ac97.c
index ce7f95b59de3..b897f7b96d89 100644
--- a/sound/soc/sh/sh7760-ac97.c
+++ b/sound/soc/sh/sh7760-ac97.c
@@ -15,41 +15,35 @@
#include <sound/soc-dapm.h>
#include <asm/io.h>
-#include "../codecs/ac97.h"
-
#define IPSEL 0xFE400034
/* platform specific structs can be declared here */
-extern struct snd_soc_dai sh4_hac_dai[2];
-extern struct snd_soc_platform sh7760_soc_platform;
+extern struct snd_soc_dai_driver sh4_hac_dai[2];
+extern struct snd_soc_platform_driver sh7760_soc_platform;
-static int machine_init(struct snd_soc_codec *codec)
+static int machine_init(struct snd_soc_pcm_runtime *rtd)
{
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(rtd->codec);
return 0;
}
static struct snd_soc_dai_link sh7760_ac97_dai = {
.name = "AC97",
.stream_name = "AC97 HiFi",
- .cpu_dai = &sh4_hac_dai[0], /* HAC0 */
- .codec_dai = &ac97_dai,
+ .cpu_dai_name = "hac-dai.0", /* HAC0 */
+ .codec_dai_name = "ac97-hifi",
+ .platform_name = "sh7760-pcm-audio",
+ .codec_name = "ac97-codec",
.init = machine_init,
.ops = NULL,
};
static struct snd_soc_card sh7760_ac97_soc_machine = {
.name = "SH7760 AC97",
- .platform = &sh7760_soc_platform,
.dai_link = &sh7760_ac97_dai,
.num_links = 1,
};
-static struct snd_soc_device sh7760_ac97_snd_devdata = {
- .card = &sh7760_ac97_soc_machine,
- .codec_dev = &soc_codec_dev_ac97,
-};
-
static struct platform_device *sh7760_ac97_snd_device;
static int __init sh7760_ac97_init(void)
@@ -67,8 +61,7 @@ static int __init sh7760_ac97_init(void)
goto out;
platform_set_drvdata(sh7760_ac97_snd_device,
- &sh7760_ac97_snd_devdata);
- sh7760_ac97_snd_devdata.dev = &sh7760_ac97_snd_device->dev;
+ &sh7760_ac97_soc_machine);
ret = platform_device_add(sh7760_ac97_snd_device);
if (ret)
diff --git a/sound/soc/sh/siu.h b/sound/soc/sh/siu.h
index 492b1cae24cc..9f4dcb921ff0 100644
--- a/sound/soc/sh/siu.h
+++ b/sound/soc/sh/siu.h
@@ -98,7 +98,9 @@ enum {
SIU_CLKB_EXT
};
+struct device;
struct siu_info {
+ struct device *dev;
int port_id;
u32 __iomem *pram;
u32 __iomem *xram;
@@ -181,8 +183,8 @@ static inline u32 siu_read32(u32 __iomem *addr)
#define SIU_BRGBSEL (0x108 / sizeof(u32))
#define SIU_BRRB (0x10c / sizeof(u32))
-extern struct snd_soc_platform siu_platform;
-extern struct snd_soc_dai siu_i2s_dai;
+extern struct snd_soc_platform_driver siu_platform;
+extern struct siu_info *siu_i2s_data;
int siu_init_port(int port, struct siu_port **port_info, struct snd_card *card);
void siu_free_port(struct siu_port *port_info);
diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c
index eeed5edd722b..af53b64d8af2 100644
--- a/sound/soc/sh/siu_dai.c
+++ b/sound/soc/sh/siu_dai.c
@@ -71,6 +71,8 @@ struct port_flag {
struct format_flag capture;
};
+struct siu_info *siu_i2s_data;
+
static struct port_flag siu_flags[SIU_PORT_NUM] = {
[SIU_PORT_A] = {
.playback = {
@@ -104,13 +106,13 @@ static struct port_flag siu_flags[SIU_PORT_NUM] = {
static void siu_dai_start(struct siu_port *port_info)
{
- struct siu_info *info = siu_i2s_dai.private_data;
+ struct siu_info *info = siu_i2s_data;
u32 __iomem *base = info->reg;
dev_dbg(port_info->pcm->card->dev, "%s\n", __func__);
/* Turn on SIU clock */
- pm_runtime_get_sync(siu_i2s_dai.dev);
+ pm_runtime_get_sync(info->dev);
/* Issue software reset to siu */
siu_write32(base + SIU_SRCTL, 0);
@@ -148,21 +150,21 @@ static void siu_dai_start(struct siu_port *port_info)
siu_write32(base + SIU_SBDVCB, port_info->capture.volume);
}
-static void siu_dai_stop(void)
+static void siu_dai_stop(struct siu_port *port_info)
{
- struct siu_info *info = siu_i2s_dai.private_data;
+ struct siu_info *info = siu_i2s_data;
u32 __iomem *base = info->reg;
/* SIU software reset */
siu_write32(base + SIU_SRCTL, 0);
/* Turn off SIU clock */
- pm_runtime_put_sync(siu_i2s_dai.dev);
+ pm_runtime_put_sync(info->dev);
}
static void siu_dai_spbAselect(struct siu_port *port_info)
{
- struct siu_info *info = siu_i2s_dai.private_data;
+ struct siu_info *info = siu_i2s_data;
struct siu_firmware *fw = &info->fw;
u32 *ydef = fw->yram0;
u32 idx;
@@ -187,7 +189,7 @@ static void siu_dai_spbAselect(struct siu_port *port_info)
static void siu_dai_spbBselect(struct siu_port *port_info)
{
- struct siu_info *info = siu_i2s_dai.private_data;
+ struct siu_info *info = siu_i2s_data;
struct siu_firmware *fw = &info->fw;
u32 *ydef = fw->yram0;
u32 idx;
@@ -207,7 +209,7 @@ static void siu_dai_spbBselect(struct siu_port *port_info)
static void siu_dai_open(struct siu_stream *siu_stream)
{
- struct siu_info *info = siu_i2s_dai.private_data;
+ struct siu_info *info = siu_i2s_data;
u32 __iomem *base = info->reg;
u32 srctl, ifctl;
@@ -238,7 +240,7 @@ static void siu_dai_open(struct siu_stream *siu_stream)
*/
static void siu_dai_pcmdatapack(struct siu_stream *siu_stream)
{
- struct siu_info *info = siu_i2s_dai.private_data;
+ struct siu_info *info = siu_i2s_data;
u32 __iomem *base = info->reg;
u32 dpak;
@@ -258,7 +260,7 @@ static void siu_dai_pcmdatapack(struct siu_stream *siu_stream)
static int siu_dai_spbstart(struct siu_port *port_info)
{
- struct siu_info *info = siu_i2s_dai.private_data;
+ struct siu_info *info = siu_i2s_data;
u32 __iomem *base = info->reg;
struct siu_firmware *fw = &info->fw;
u32 *ydef = fw->yram0;
@@ -323,7 +325,7 @@ static int siu_dai_spbstart(struct siu_port *port_info)
static void siu_dai_spbstop(struct siu_port *port_info)
{
- struct siu_info *info = siu_i2s_dai.private_data;
+ struct siu_info *info = siu_i2s_data;
u32 __iomem *base = info->reg;
siu_write32(base + SIU_SBACTIV, 0);
@@ -402,7 +404,7 @@ static int siu_dai_put_volume(struct snd_kcontrol *kctrl,
{
struct siu_port *port_info = snd_kcontrol_chip(kctrl);
struct device *dev = port_info->pcm->card->dev;
- struct siu_info *info = siu_i2s_dai.private_data;
+ struct siu_info *info = siu_i2s_data;
u32 __iomem *base = info->reg;
u32 new_vol;
u32 cur_vol;
@@ -510,7 +512,7 @@ void siu_free_port(struct siu_port *port_info)
static int siu_dai_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
- struct siu_info *info = siu_i2s_dai.private_data;
+ struct siu_info *info = snd_soc_dai_get_drvdata(dai);
struct snd_pcm_runtime *rt = substream->runtime;
struct siu_port *port_info = siu_port_info(substream);
int ret;
@@ -532,7 +534,7 @@ static int siu_dai_startup(struct snd_pcm_substream *substream,
static void siu_dai_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
- struct siu_info *info = siu_i2s_dai.private_data;
+ struct siu_info *info = snd_soc_dai_get_drvdata(dai);
struct siu_port *port_info = siu_port_info(substream);
dev_dbg(substream->pcm->card->dev, "%s: port=%d@%p\n", __func__,
@@ -548,7 +550,7 @@ static void siu_dai_shutdown(struct snd_pcm_substream *substream,
/* during stmread or stmwrite ? */
BUG_ON(port_info->playback.rw_flg || port_info->capture.rw_flg);
siu_dai_spbstop(port_info);
- siu_dai_stop();
+ siu_dai_stop(port_info);
}
}
@@ -556,7 +558,7 @@ static void siu_dai_shutdown(struct snd_pcm_substream *substream,
static int siu_dai_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
- struct siu_info *info = siu_i2s_dai.private_data;
+ struct siu_info *info = snd_soc_dai_get_drvdata(dai);
struct snd_pcm_runtime *rt = substream->runtime;
struct siu_port *port_info = siu_port_info(substream);
struct siu_stream *siu_stream;
@@ -605,7 +607,7 @@ fail:
static int siu_dai_set_fmt(struct snd_soc_dai *dai,
unsigned int fmt)
{
- struct siu_info *info = siu_i2s_dai.private_data;
+ struct siu_info *info = snd_soc_dai_get_drvdata(dai);
u32 __iomem *base = info->reg;
u32 ifctl;
@@ -671,21 +673,37 @@ static int siu_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
return -EINVAL;
}
- siu_clk = clk_get(siu_i2s_dai.dev, siu_name);
- if (IS_ERR(siu_clk))
+ siu_clk = clk_get(dai->dev, siu_name);
+ if (IS_ERR(siu_clk)) {
+ dev_err(dai->dev, "%s: cannot get a SIU clock: %ld\n", __func__,
+ PTR_ERR(siu_clk));
return PTR_ERR(siu_clk);
+ }
+
+ parent_clk = clk_get(dai->dev, parent_name);
+ if (IS_ERR(parent_clk)) {
+ ret = PTR_ERR(parent_clk);
+ dev_err(dai->dev, "cannot get a SIU clock parent: %d\n", ret);
+ goto epclkget;
+ }
- parent_clk = clk_get(siu_i2s_dai.dev, parent_name);
- if (!IS_ERR(parent_clk)) {
- ret = clk_set_parent(siu_clk, parent_clk);
- if (!ret)
- clk_set_rate(siu_clk, freq);
- clk_put(parent_clk);
+ ret = clk_set_parent(siu_clk, parent_clk);
+ if (ret < 0) {
+ dev_err(dai->dev, "cannot reparent the SIU clock: %d\n", ret);
+ goto eclksetp;
}
+ ret = clk_set_rate(siu_clk, freq);
+ if (ret < 0)
+ dev_err(dai->dev, "cannot set SIU clock rate: %d\n", ret);
+
+ /* TODO: when clkdev gets reference counting we'll move these to siu_dai_shutdown() */
+eclksetp:
+ clk_put(parent_clk);
+epclkget:
clk_put(siu_clk);
- return 0;
+ return ret;
}
static struct snd_soc_dai_ops siu_dai_ops = {
@@ -696,9 +714,8 @@ static struct snd_soc_dai_ops siu_dai_ops = {
.set_fmt = siu_dai_set_fmt,
};
-struct snd_soc_dai siu_i2s_dai = {
- .name = "sh-siu",
- .id = 0,
+static struct snd_soc_dai_driver siu_i2s_dai = {
+ .name = "siu-i2s-dai",
.playback = {
.channels_min = 2,
.channels_max = 2,
@@ -713,7 +730,6 @@ struct snd_soc_dai siu_i2s_dai = {
},
.ops = &siu_dai_ops,
};
-EXPORT_SYMBOL_GPL(siu_i2s_dai);
static int __devinit siu_probe(struct platform_device *pdev)
{
@@ -725,6 +741,8 @@ static int __devinit siu_probe(struct platform_device *pdev)
info = kmalloc(sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
+ siu_i2s_data = info;
+ info->dev = &pdev->dev;
ret = request_firmware(&fw_entry, "siu_spb.bin", &pdev->dev);
if (ret)
@@ -767,14 +785,14 @@ static int __devinit siu_probe(struct platform_device *pdev)
if (!info->reg)
goto emapreg;
- siu_i2s_dai.dev = &pdev->dev;
- siu_i2s_dai.private_data = info;
+ dev_set_drvdata(&pdev->dev, info);
- ret = snd_soc_register_dais(&siu_i2s_dai, 1);
+ /* register using ARRAY version so we can keep dai name */
+ ret = snd_soc_register_dais(&pdev->dev, &siu_i2s_dai, 1);
if (ret < 0)
goto edaiinit;
- ret = snd_soc_register_platform(&siu_platform);
+ ret = snd_soc_register_platform(&pdev->dev, &siu_platform);
if (ret < 0)
goto esocregp;
@@ -783,7 +801,7 @@ static int __devinit siu_probe(struct platform_device *pdev)
return ret;
esocregp:
- snd_soc_unregister_dais(&siu_i2s_dai, 1);
+ snd_soc_unregister_dai(&pdev->dev);
edaiinit:
iounmap(info->reg);
emapreg:
@@ -804,13 +822,13 @@ ereqfw:
static int __devexit siu_remove(struct platform_device *pdev)
{
- struct siu_info *info = siu_i2s_dai.private_data;
+ struct siu_info *info = dev_get_drvdata(&pdev->dev);
struct resource *res;
pm_runtime_disable(&pdev->dev);
- snd_soc_unregister_platform(&siu_platform);
- snd_soc_unregister_dais(&siu_i2s_dai, 1);
+ snd_soc_unregister_platform(&pdev->dev);
+ snd_soc_unregister_dai(&pdev->dev);
iounmap(info->reg);
iounmap(info->yram);
@@ -826,7 +844,8 @@ static int __devexit siu_remove(struct platform_device *pdev)
static struct platform_driver siu_driver = {
.driver = {
- .name = "sh_siu",
+ .owner = THIS_MODULE,
+ .name = "siu-pcm-audio",
},
.probe = siu_probe,
.remove = __devexit_p(siu_remove),
diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c
index b0ccd0b862fc..ed29c9e1ed4e 100644
--- a/sound/soc/sh/siu_pcm.c
+++ b/sound/soc/sh/siu_pcm.c
@@ -48,7 +48,7 @@ struct siu_port *siu_ports[SIU_PORT_NUM];
/* transfersize is number of u32 dma transfers per period */
static int siu_pcm_stmwrite_stop(struct siu_port *port_info)
{
- struct siu_info *info = siu_i2s_dai.private_data;
+ struct siu_info *info = siu_i2s_data;
u32 __iomem *base = info->reg;
struct siu_stream *siu_stream = &port_info->playback;
u32 stfifo;
@@ -114,7 +114,7 @@ static void siu_dma_tx_complete(void *arg)
static int siu_pcm_wr_set(struct siu_port *port_info,
dma_addr_t buff, u32 size)
{
- struct siu_info *info = siu_i2s_dai.private_data;
+ struct siu_info *info = siu_i2s_data;
u32 __iomem *base = info->reg;
struct siu_stream *siu_stream = &port_info->playback;
struct snd_pcm_substream *substream = siu_stream->substream;
@@ -162,7 +162,7 @@ static int siu_pcm_wr_set(struct siu_port *port_info,
static int siu_pcm_rd_set(struct siu_port *port_info,
dma_addr_t buff, size_t size)
{
- struct siu_info *info = siu_i2s_dai.private_data;
+ struct siu_info *info = siu_i2s_data;
u32 __iomem *base = info->reg;
struct siu_stream *siu_stream = &port_info->capture;
struct snd_pcm_substream *substream = siu_stream->substream;
@@ -272,7 +272,7 @@ static int siu_pcm_stmread_start(struct siu_port *port_info)
static int siu_pcm_stmread_stop(struct siu_port *port_info)
{
- struct siu_info *info = siu_i2s_dai.private_data;
+ struct siu_info *info = siu_i2s_data;
u32 __iomem *base = info->reg;
struct siu_stream *siu_stream = &port_info->capture;
struct device *dev = siu_stream->substream->pcm->card->dev;
@@ -296,7 +296,7 @@ static int siu_pcm_stmread_stop(struct siu_port *port_info)
static int siu_pcm_hw_params(struct snd_pcm_substream *ss,
struct snd_pcm_hw_params *hw_params)
{
- struct siu_info *info = siu_i2s_dai.private_data;
+ struct siu_info *info = siu_i2s_data;
struct device *dev = ss->pcm->card->dev;
int ret;
@@ -311,7 +311,7 @@ static int siu_pcm_hw_params(struct snd_pcm_substream *ss,
static int siu_pcm_hw_free(struct snd_pcm_substream *ss)
{
- struct siu_info *info = siu_i2s_dai.private_data;
+ struct siu_info *info = siu_i2s_data;
struct siu_port *port_info = siu_port_info(ss);
struct device *dev = ss->pcm->card->dev;
struct siu_stream *siu_stream;
@@ -342,11 +342,12 @@ static bool filter(struct dma_chan *chan, void *slave)
static int siu_pcm_open(struct snd_pcm_substream *ss)
{
/* Playback / Capture */
- struct siu_info *info = siu_i2s_dai.private_data;
+ struct snd_soc_pcm_runtime *rtd = ss->private_data;
+ struct siu_platform *pdata = rtd->platform->dev->platform_data;
+ struct siu_info *info = siu_i2s_data;
struct siu_port *port_info = siu_port_info(ss);
struct siu_stream *siu_stream;
u32 port = info->port_id;
- struct siu_platform *pdata = siu_i2s_dai.dev->platform_data;
struct device *dev = ss->pcm->card->dev;
dma_cap_mask_t mask;
struct sh_dmae_slave *param;
@@ -383,7 +384,7 @@ static int siu_pcm_open(struct snd_pcm_substream *ss)
static int siu_pcm_close(struct snd_pcm_substream *ss)
{
- struct siu_info *info = siu_i2s_dai.private_data;
+ struct siu_info *info = siu_i2s_data;
struct device *dev = ss->pcm->card->dev;
struct siu_port *port_info = siu_port_info(ss);
struct siu_stream *siu_stream;
@@ -405,7 +406,7 @@ static int siu_pcm_close(struct snd_pcm_substream *ss)
static int siu_pcm_prepare(struct snd_pcm_substream *ss)
{
- struct siu_info *info = siu_i2s_dai.private_data;
+ struct siu_info *info = siu_i2s_data;
struct siu_port *port_info = siu_port_info(ss);
struct device *dev = ss->pcm->card->dev;
struct snd_pcm_runtime *rt = ss->runtime;
@@ -451,7 +452,7 @@ static int siu_pcm_prepare(struct snd_pcm_substream *ss)
static int siu_pcm_trigger(struct snd_pcm_substream *ss, int cmd)
{
- struct siu_info *info = siu_i2s_dai.private_data;
+ struct siu_info *info = siu_i2s_data;
struct device *dev = ss->pcm->card->dev;
struct siu_port *port_info = siu_port_info(ss);
int ret;
@@ -494,7 +495,7 @@ static int siu_pcm_trigger(struct snd_pcm_substream *ss, int cmd)
static snd_pcm_uframes_t siu_pcm_pointer_dma(struct snd_pcm_substream *ss)
{
struct device *dev = ss->pcm->card->dev;
- struct siu_info *info = siu_i2s_dai.private_data;
+ struct siu_info *info = siu_i2s_data;
u32 __iomem *base = info->reg;
struct siu_port *port_info = siu_port_info(ss);
struct snd_pcm_runtime *rt = ss->runtime;
@@ -530,7 +531,7 @@ static int siu_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
struct snd_pcm *pcm)
{
/* card->dev == socdev->dev, see snd_soc_new_pcms() */
- struct siu_info *info = siu_i2s_dai.private_data;
+ struct siu_info *info = siu_i2s_data;
struct platform_device *pdev = to_platform_device(card->dev);
int ret;
int i;
@@ -607,9 +608,8 @@ static struct snd_pcm_ops siu_pcm_ops = {
.pointer = siu_pcm_pointer_dma,
};
-struct snd_soc_platform siu_platform = {
- .name = "siu-audio",
- .pcm_ops = &siu_pcm_ops,
+struct snd_soc_platform_driver siu_platform = {
+ .ops = &siu_pcm_ops,
.pcm_new = siu_pcm_new,
.pcm_free = siu_pcm_free,
};
diff --git a/sound/soc/sh/ssi.c b/sound/soc/sh/ssi.c
index b378096cadb1..40bbdf1591dc 100644
--- a/sound/soc/sh/ssi.c
+++ b/sound/soc/sh/ssi.c
@@ -92,8 +92,7 @@ struct ssi_priv {
static int ssi_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
+ struct ssi_priv *ssi = &ssi_cpu_data[dai->id];
if (ssi->inuse) {
pr_debug("ssi: already in use!\n");
return -EBUSY;
@@ -105,8 +104,7 @@ static int ssi_startup(struct snd_pcm_substream *substream,
static void ssi_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
+ struct ssi_priv *ssi = &ssi_cpu_data[dai->id];
ssi->inuse = 0;
}
@@ -114,8 +112,7 @@ static void ssi_shutdown(struct snd_pcm_substream *substream,
static int ssi_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *dai)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
+ struct ssi_priv *ssi = &ssi_cpu_data[dai->id];
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
@@ -135,8 +132,7 @@ static int ssi_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
+ struct ssi_priv *ssi = &ssi_cpu_data[dai->id];
unsigned long ssicr = SSIREG(SSICR);
unsigned int bits, channels, swl, recv, i;
@@ -346,10 +342,9 @@ static struct snd_soc_dai_ops ssi_dai_ops = {
.set_fmt = ssi_set_fmt,
};
-struct snd_soc_dai sh4_ssi_dai[] = {
+struct snd_soc_dai_driver sh4_ssi_dai[] = {
{
- .name = "SSI0",
- .id = 0,
+ .name = "ssi-dai.0",
.playback = {
.rates = SSI_RATES,
.formats = SSI_FMTS,
@@ -366,8 +361,7 @@ struct snd_soc_dai sh4_ssi_dai[] = {
},
#ifdef CONFIG_CPU_SUBTYPE_SH7760
{
- .name = "SSI1",
- .id = 1,
+ .name = "ssi-dai.1",
.playback = {
.rates = SSI_RATES,
.formats = SSI_FMTS,
@@ -384,19 +378,40 @@ struct snd_soc_dai sh4_ssi_dai[] = {
},
#endif
};
-EXPORT_SYMBOL_GPL(sh4_ssi_dai);
-static int __init sh4_ssi_init(void)
+static int __devinit sh4_soc_dai_probe(struct platform_device *pdev)
+{
+ return snd_soc_register_dais(&pdev->dev, sh4_ssi_dai,
+ ARRAY_SIZE(sh4_ssi_dai));
+}
+
+static int __devexit sh4_soc_dai_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_dai(&pdev->dev, ARRAY_SIZE(sh4_ssi_dai));
+ return 0;
+}
+
+static struct platform_driver sh4_ssi_driver = {
+ .driver = {
+ .name = "sh4-ssi-dai",
+ .owner = THIS_MODULE,
+ },
+
+ .probe = sh4_soc_dai_probe,
+ .remove = __devexit_p(sh4_soc_dai_remove),
+};
+
+static int __init snd_sh4_ssi_init(void)
{
- return snd_soc_register_dais(sh4_ssi_dai, ARRAY_SIZE(sh4_ssi_dai));
+ return platform_driver_register(&sh4_ssi_driver);
}
-module_init(sh4_ssi_init);
+module_init(snd_sh4_ssi_init);
-static void __exit sh4_ssi_exit(void)
+static void __exit snd_sh4_ssi_exit(void)
{
- snd_soc_unregister_dais(sh4_ssi_dai, ARRAY_SIZE(sh4_ssi_dai));
+ platform_driver_unregister(&sh4_ssi_driver);
}
-module_exit(sh4_ssi_exit);
+module_exit(snd_sh4_ssi_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("SuperH onchip SSI (I2S) audio driver");