summaryrefslogtreecommitdiffstats
path: root/sound/soc/sh
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/sh')
-rw-r--r--sound/soc/sh/Kconfig4
-rw-r--r--sound/soc/sh/fsi-ak4642.c140
-rw-r--r--sound/soc/sh/fsi-da7210.c2
-rw-r--r--sound/soc/sh/fsi.c296
-rw-r--r--sound/soc/sh/migor.c8
-rw-r--r--sound/soc/sh/sh7760-ac97.c3
-rw-r--r--sound/soc/sh/siu.h2
-rw-r--r--sound/soc/sh/siu_dai.c2
-rw-r--r--sound/soc/sh/siu_pcm.c2
9 files changed, 287 insertions, 172 deletions
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index 7f0a496..d8e06a6 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -48,7 +48,7 @@ config SND_SH7760_AC97
config SND_FSI_AK4642
tristate "FSI-AK4642 sound support"
- depends on SND_SOC_SH4_FSI && I2C_SH_MOBILE
+ depends on SND_SOC_SH4_FSI && I2C
select SND_SOC_AK4642
help
This option enables generic sound support for the
@@ -56,7 +56,7 @@ config SND_FSI_AK4642
config SND_FSI_DA7210
tristate "FSI-DA7210 sound support"
- depends on SND_SOC_SH4_FSI && I2C_SH_MOBILE
+ depends on SND_SOC_SH4_FSI && I2C
select SND_SOC_DA7210
help
This option enables generic sound support for the
diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c
index d96602d..a14820a 100644
--- a/sound/soc/sh/fsi-ak4642.c
+++ b/sound/soc/sh/fsi-ak4642.c
@@ -12,6 +12,14 @@
#include <linux/platform_device.h>
#include <sound/sh_fsi.h>
+struct fsi_ak4642_data {
+ const char *name;
+ const char *card;
+ const char *cpu_dai;
+ const char *codec;
+ const char *platform;
+};
+
static int fsi_ak4642_dai_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_dai *dai = rtd->codec_dai;
@@ -27,37 +35,42 @@ static int fsi_ak4642_dai_init(struct snd_soc_pcm_runtime *rtd)
}
static struct snd_soc_dai_link fsi_dai_link = {
- .name = "AK4642",
- .stream_name = "AK4642",
- .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 (AK4642)",
.dai_link = &fsi_dai_link,
.num_links = 1,
};
static struct platform_device *fsi_snd_device;
-static int __init fsi_ak4642_init(void)
+static int fsi_ak4642_probe(struct platform_device *pdev)
{
int ret = -ENOMEM;
+ const struct platform_device_id *id_entry;
+ struct fsi_ak4642_data *pdata;
+
+ id_entry = pdev->id_entry;
+ if (!id_entry) {
+ dev_err(&pdev->dev, "unknown fsi ak4642\n");
+ return -ENODEV;
+ }
+
+ pdata = (struct fsi_ak4642_data *)id_entry->driver_data;
fsi_snd_device = platform_device_alloc("soc-audio", FSI_PORT_A);
if (!fsi_snd_device)
goto out;
+ fsi_dai_link.name = pdata->name;
+ fsi_dai_link.stream_name = pdata->name;
+ fsi_dai_link.cpu_dai_name = pdata->cpu_dai;
+ fsi_dai_link.platform_name = pdata->platform;
+ fsi_dai_link.codec_name = pdata->codec;
+ fsi_soc_card.name = pdata->card;
+
platform_set_drvdata(fsi_snd_device, &fsi_soc_card);
ret = platform_device_add(fsi_snd_device);
@@ -68,9 +81,108 @@ out:
return ret;
}
-static void __exit fsi_ak4642_exit(void)
+static int fsi_ak4642_remove(struct platform_device *pdev)
{
platform_device_unregister(fsi_snd_device);
+ return 0;
+}
+
+static struct fsi_ak4642_data fsi_a_ak4642 = {
+ .name = "AK4642",
+ .card = "FSIA (AK4642)",
+ .cpu_dai = "fsia-dai",
+ .codec = "ak4642-codec.0-0012",
+ .platform = "sh_fsi.0",
+};
+
+static struct fsi_ak4642_data fsi_b_ak4642 = {
+ .name = "AK4642",
+ .card = "FSIB (AK4642)",
+ .cpu_dai = "fsib-dai",
+ .codec = "ak4642-codec.0-0012",
+ .platform = "sh_fsi.0",
+};
+
+static struct fsi_ak4642_data fsi_a_ak4643 = {
+ .name = "AK4643",
+ .card = "FSIA (AK4643)",
+ .cpu_dai = "fsia-dai",
+ .codec = "ak4642-codec.0-0013",
+ .platform = "sh_fsi.0",
+};
+
+static struct fsi_ak4642_data fsi_b_ak4643 = {
+ .name = "AK4643",
+ .card = "FSIB (AK4643)",
+ .cpu_dai = "fsib-dai",
+ .codec = "ak4642-codec.0-0013",
+ .platform = "sh_fsi.0",
+};
+
+static struct fsi_ak4642_data fsi2_a_ak4642 = {
+ .name = "AK4642",
+ .card = "FSI2A (AK4642)",
+ .cpu_dai = "fsia-dai",
+ .codec = "ak4642-codec.0-0012",
+ .platform = "sh_fsi2",
+};
+
+static struct fsi_ak4642_data fsi2_b_ak4642 = {
+ .name = "AK4642",
+ .card = "FSI2B (AK4642)",
+ .cpu_dai = "fsib-dai",
+ .codec = "ak4642-codec.0-0012",
+ .platform = "sh_fsi2",
+};
+
+static struct fsi_ak4642_data fsi2_a_ak4643 = {
+ .name = "AK4643",
+ .card = "FSI2A (AK4643)",
+ .cpu_dai = "fsia-dai",
+ .codec = "ak4642-codec.0-0013",
+ .platform = "sh_fsi2",
+};
+
+static struct fsi_ak4642_data fsi2_b_ak4643 = {
+ .name = "AK4643",
+ .card = "FSI2B (AK4643)",
+ .cpu_dai = "fsib-dai",
+ .codec = "ak4642-codec.0-0013",
+ .platform = "sh_fsi2",
+};
+
+static struct platform_device_id fsi_id_table[] = {
+ /* FSI */
+ { "sh_fsi_a_ak4642", (kernel_ulong_t)&fsi_a_ak4642 },
+ { "sh_fsi_b_ak4642", (kernel_ulong_t)&fsi_b_ak4642 },
+ { "sh_fsi_a_ak4643", (kernel_ulong_t)&fsi_a_ak4643 },
+ { "sh_fsi_b_ak4643", (kernel_ulong_t)&fsi_b_ak4643 },
+
+ /* FSI 2 */
+ { "sh_fsi2_a_ak4642", (kernel_ulong_t)&fsi2_a_ak4642 },
+ { "sh_fsi2_b_ak4642", (kernel_ulong_t)&fsi2_b_ak4642 },
+ { "sh_fsi2_a_ak4643", (kernel_ulong_t)&fsi2_a_ak4643 },
+ { "sh_fsi2_b_ak4643", (kernel_ulong_t)&fsi2_b_ak4643 },
+ {},
+};
+
+static struct platform_driver fsi_ak4642 = {
+ .driver = {
+ .name = "fsi-ak4642-audio",
+ },
+ .probe = fsi_ak4642_probe,
+ .remove = fsi_ak4642_remove,
+ .id_table = fsi_id_table,
+};
+
+static int __init fsi_ak4642_init(void)
+{
+ return platform_driver_register(&fsi_ak4642);
+}
+
+static void __exit fsi_ak4642_exit(void)
+{
+ platform_driver_unregister(&fsi_ak4642);
}
module_init(fsi_ak4642_init);
diff --git a/sound/soc/sh/fsi-da7210.c b/sound/soc/sh/fsi-da7210.c
index a6adb6e..e8df9da 100644
--- a/sound/soc/sh/fsi-da7210.c
+++ b/sound/soc/sh/fsi-da7210.c
@@ -18,7 +18,7 @@ static int fsi_da7210_init(struct snd_soc_pcm_runtime *rtd)
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_I2S |
SND_SOC_DAIFMT_CBM_CFM);
}
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 507e709..2b06402 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -19,20 +19,26 @@
#include <sound/soc.h>
#include <sound/sh_fsi.h>
-#define DO_FMT 0x0000
-#define DOFF_CTL 0x0004
-#define DOFF_ST 0x0008
-#define DI_FMT 0x000C
-#define DIFF_CTL 0x0010
-#define DIFF_ST 0x0014
-#define CKG1 0x0018
-#define CKG2 0x001C
-#define DIDT 0x0020
-#define DODT 0x0024
-#define MUTE_ST 0x0028
-#define OUT_SEL 0x0030
-#define REG_END OUT_SEL
-
+/* PortA/PortB register */
+#define REG_DO_FMT 0x0000
+#define REG_DOFF_CTL 0x0004
+#define REG_DOFF_ST 0x0008
+#define REG_DI_FMT 0x000C
+#define REG_DIFF_CTL 0x0010
+#define REG_DIFF_ST 0x0014
+#define REG_CKG1 0x0018
+#define REG_CKG2 0x001C
+#define REG_DIDT 0x0020
+#define REG_DODT 0x0024
+#define REG_MUTE_ST 0x0028
+#define REG_OUT_SEL 0x0030
+
+/* master register */
+#define MST_CLK_RST 0x0210
+#define MST_SOFT_RST 0x0214
+#define MST_FIFO_SZ 0x0218
+
+/* core register (depend on FSI version) */
#define A_MST_CTLR 0x0180
#define B_MST_CTLR 0x01A0
#define CPU_INT_ST 0x01F4
@@ -41,22 +47,23 @@
#define INT_ST 0x0200
#define IEMSK 0x0204
#define IMSK 0x0208
-#define MUTE 0x020C
-#define CLK_RST 0x0210
-#define SOFT_RST 0x0214
-#define FIFO_SZ 0x0218
-#define MREG_START A_MST_CTLR
-#define MREG_END FIFO_SZ
/* DO_FMT */
/* DI_FMT */
+#define CR_BWS_24 (0x0 << 20) /* FSI2 */
+#define CR_BWS_16 (0x1 << 20) /* FSI2 */
+#define CR_BWS_20 (0x2 << 20) /* FSI2 */
+
+#define CR_DTMD_PCM (0x0 << 8) /* FSI2 */
+#define CR_DTMD_SPDIF_PCM (0x1 << 8) /* FSI2 */
+#define CR_DTMD_SPDIF_STREAM (0x2 << 8) /* FSI2 */
+
#define CR_MONO (0x0 << 4)
#define CR_MONO_D (0x1 << 4)
#define CR_PCM (0x2 << 4)
#define CR_I2S (0x3 << 4)
#define CR_TDM (0x4 << 4)
#define CR_TDM_D (0x5 << 4)
-#define CR_SPDIF 0x00100120
/* DOFF_CTL */
/* DIFF_CTL */
@@ -93,6 +100,10 @@
#define IR (1 << 4) /* Interrupt Reset */
#define FSISR (1 << 0) /* Software Reset */
+/* OUT_SEL (FSI2) */
+#define DMMD (1 << 4) /* SPDIF output timing 0: Biphase only */
+ /* 1: Biphase and serial */
+
/* FIFO_SZ */
#define FIFO_SZ_MASK 0x7
@@ -123,6 +134,9 @@ struct fsi_stream {
int buff_len;
int period_len;
int period_num;
+
+ int uerr_num;
+ int oerr_num;
};
struct fsi_priv {
@@ -132,7 +146,7 @@ struct fsi_priv {
struct fsi_stream playback;
struct fsi_stream capture;
- u32 mst_ctrl;
+ long rate;
};
struct fsi_core {
@@ -141,6 +155,8 @@ struct fsi_core {
u32 int_st;
u32 iemsk;
u32 imsk;
+ u32 a_mclk;
+ u32 b_mclk;
};
struct fsi_master {
@@ -180,62 +196,22 @@ static void __fsi_reg_mask_set(u32 reg, u32 mask, u32 data)
__fsi_reg_write(reg, val);
}
-static void fsi_reg_write(struct fsi_priv *fsi, u32 reg, u32 data)
-{
- if (reg > REG_END) {
- pr_err("fsi: register access err (%s)\n", __func__);
- return;
- }
-
- __fsi_reg_write((u32)(fsi->base + reg), data);
-}
+#define fsi_reg_write(p, r, d)\
+ __fsi_reg_write((u32)(p->base + REG_##r), d)
-static u32 fsi_reg_read(struct fsi_priv *fsi, u32 reg)
-{
- if (reg > REG_END) {
- pr_err("fsi: register access err (%s)\n", __func__);
- return 0;
- }
+#define fsi_reg_read(p, r)\
+ __fsi_reg_read((u32)(p->base + REG_##r))
- return __fsi_reg_read((u32)(fsi->base + reg));
-}
+#define fsi_reg_mask_set(p, r, m, d)\
+ __fsi_reg_mask_set((u32)(p->base + REG_##r), m, d)
-static void fsi_reg_mask_set(struct fsi_priv *fsi, u32 reg, u32 mask, u32 data)
-{
- if (reg > REG_END) {
- pr_err("fsi: register access err (%s)\n", __func__);
- return;
- }
-
- __fsi_reg_mask_set((u32)(fsi->base + reg), mask, data);
-}
-
-static void fsi_master_write(struct fsi_master *master, u32 reg, u32 data)
-{
- unsigned long flags;
-
- if ((reg < MREG_START) ||
- (reg > MREG_END)) {
- pr_err("fsi: register access err (%s)\n", __func__);
- return;
- }
-
- spin_lock_irqsave(&master->lock, flags);
- __fsi_reg_write((u32)(master->base + reg), data);
- spin_unlock_irqrestore(&master->lock, flags);
-}
-
-static u32 fsi_master_read(struct fsi_master *master, u32 reg)
+#define fsi_master_read(p, r) _fsi_master_read(p, MST_##r)
+#define fsi_core_read(p, r) _fsi_master_read(p, p->core->r)
+static u32 _fsi_master_read(struct fsi_master *master, u32 reg)
{
u32 ret;
unsigned long flags;
- if ((reg < MREG_START) ||
- (reg > MREG_END)) {
- pr_err("fsi: register access err (%s)\n", __func__);
- return 0;
- }
-
spin_lock_irqsave(&master->lock, flags);
ret = __fsi_reg_read((u32)(master->base + reg));
spin_unlock_irqrestore(&master->lock, flags);
@@ -243,17 +219,13 @@ static u32 fsi_master_read(struct fsi_master *master, u32 reg)
return ret;
}
-static void fsi_master_mask_set(struct fsi_master *master,
+#define fsi_master_mask_set(p, r, m, d) _fsi_master_mask_set(p, MST_##r, m, d)
+#define fsi_core_mask_set(p, r, m, d) _fsi_master_mask_set(p, p->core->r, m, d)
+static void _fsi_master_mask_set(struct fsi_master *master,
u32 reg, u32 mask, u32 data)
{
unsigned long flags;
- if ((reg < MREG_START) ||
- (reg > MREG_END)) {
- pr_err("fsi: register access err (%s)\n", __func__);
- return;
- }
-
spin_lock_irqsave(&master->lock, flags);
__fsi_reg_mask_set((u32)(master->base + reg), mask, data);
spin_unlock_irqrestore(&master->lock, flags);
@@ -357,27 +329,41 @@ static void fsi_stream_push(struct fsi_priv *fsi,
io->buff_offset = 0;
io->period_len = period_len;
io->period_num = 0;
+ io->oerr_num = -1; /* ignore 1st err */
+ io->uerr_num = -1; /* ignore 1st err */
}
static void fsi_stream_pop(struct fsi_priv *fsi, int is_play)
{
struct fsi_stream *io = fsi_get_stream(fsi, is_play);
+ struct snd_soc_dai *dai = fsi_get_dai(io->substream);
+
+
+ if (io->oerr_num > 0)
+ dev_err(dai->dev, "over_run = %d\n", io->oerr_num);
+
+ if (io->uerr_num > 0)
+ dev_err(dai->dev, "under_run = %d\n", io->uerr_num);
io->substream = NULL;
io->buff_len = 0;
io->buff_offset = 0;
io->period_len = 0;
io->period_num = 0;
+ io->oerr_num = 0;
+ io->uerr_num = 0;
}
static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play)
{
u32 status;
- u32 reg = is_play ? DOFF_ST : DIFF_ST;
struct fsi_stream *io = fsi_get_stream(fsi, is_play);
int data_num;
- status = fsi_reg_read(fsi, reg);
+ status = is_play ?
+ fsi_reg_read(fsi, DOFF_ST) :
+ fsi_reg_read(fsi, DIFF_ST);
+
data_num = 0x1ff & (status >> 8);
data_num *= io->chan_num;
@@ -404,6 +390,27 @@ static int fsi_get_frame_width(struct fsi_priv *fsi, int is_play)
return frames_to_bytes(runtime, 1) / io->chan_num;
}
+static void fsi_count_fifo_err(struct fsi_priv *fsi)
+{
+ u32 ostatus = fsi_reg_read(fsi, DOFF_ST);
+ u32 istatus = fsi_reg_read(fsi, DIFF_ST);
+
+ if (ostatus & ERR_OVER)
+ fsi->playback.oerr_num++;
+
+ if (ostatus & ERR_UNDER)
+ fsi->playback.uerr_num++;
+
+ if (istatus & ERR_OVER)
+ fsi->capture.oerr_num++;
+
+ if (istatus & ERR_UNDER)
+ fsi->capture.uerr_num++;
+
+ fsi_reg_write(fsi, DOFF_ST, 0);
+ fsi_reg_write(fsi, DIFF_ST, 0);
+}
+
/*
* dma function
*/
@@ -471,8 +478,8 @@ static void fsi_irq_enable(struct fsi_priv *fsi, int 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);
- fsi_master_mask_set(master, master->core->iemsk, data, data);
+ fsi_core_mask_set(master, imsk, data, data);
+ fsi_core_mask_set(master, iemsk, data, data);
}
static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
@@ -480,18 +487,13 @@ static void fsi_irq_disable(struct fsi_priv *fsi, int 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);
- fsi_master_mask_set(master, master->core->iemsk, data, 0);
+ fsi_core_mask_set(master, imsk, data, 0);
+ fsi_core_mask_set(master, iemsk, data, 0);
}
static u32 fsi_irq_get_status(struct fsi_master *master)
{
- return fsi_master_read(master, master->core->int_st);
-}
-
-static void fsi_irq_clear_all_status(struct fsi_master *master)
-{
- fsi_master_write(master, master->core->int_st, 0);
+ return fsi_core_read(master, int_st);
}
static void fsi_irq_clear_status(struct fsi_priv *fsi)
@@ -503,7 +505,7 @@ static void fsi_irq_clear_status(struct fsi_priv *fsi)
data |= AB_IO(1, fsi_get_port_shift(fsi, 1));
/* clear interrupt factor */
- fsi_master_mask_set(master, master->core->int_st, data, 0);
+ fsi_core_mask_set(master, int_st, data, 0);
}
/*
@@ -514,17 +516,19 @@ static void fsi_irq_clear_status(struct fsi_priv *fsi)
static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable)
{
struct fsi_master *master = fsi_get_master(fsi);
- u32 val = BP | SE;
+ u32 mask, val;
if (master->core->ver < 2) {
pr_err("fsi: register access err (%s)\n", __func__);
return;
}
- if (enable)
- fsi_master_mask_set(master, fsi->mst_ctrl, val, val);
- else
- fsi_master_mask_set(master, fsi->mst_ctrl, val, 0);
+ mask = BP | SE;
+ val = enable ? mask : 0;
+
+ fsi_is_port_a(fsi) ?
+ fsi_core_mask_set(master, a_mclk, mask, val) :
+ fsi_core_mask_set(master, b_mclk, mask, val);
}
/*
@@ -548,7 +552,7 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
{
struct fsi_master *master = fsi_get_master(fsi);
struct fsi_stream *io = fsi_get_stream(fsi, is_play);
- u32 ctrl, shift, i;
+ u32 shift, i;
/* get on-chip RAM capacity */
shift = fsi_master_read(master, FIFO_SZ);
@@ -581,13 +585,17 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
dev_dbg(dai->dev, "%d channel %d store\n",
io->chan_num, io->fifo_max_num);
- ctrl = is_play ? DOFF_CTL : DIFF_CTL;
-
- /* set interrupt generation factor */
- fsi_reg_write(fsi, ctrl, IRQ_HALF);
-
- /* clear FIFO */
- fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR);
+ /*
+ * set interrupt generation factor
+ * clear FIFO
+ */
+ if (is_play) {
+ fsi_reg_write(fsi, DOFF_CTL, IRQ_HALF);
+ fsi_reg_mask_set(fsi, DOFF_CTL, FIFO_CLR, FIFO_CLR);
+ } else {
+ fsi_reg_write(fsi, DIFF_CTL, IRQ_HALF);
+ fsi_reg_mask_set(fsi, DIFF_CTL, FIFO_CLR, FIFO_CLR);
+ }
}
static void fsi_soft_all_reset(struct fsi_master *master)
@@ -602,13 +610,12 @@ static void fsi_soft_all_reset(struct fsi_master *master)
mdelay(10);
}
-static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int startup, int stream)
+static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
{
struct snd_pcm_runtime *runtime;
struct snd_pcm_substream *substream = NULL;
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;
@@ -696,35 +703,20 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int startup, int stream)
/* update buff_offset */
io->buff_offset += fsi_num2offset(data_num, ch_width);
- /* 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, status_reg, 0);
-
- /* re-enable irq */
- fsi_irq_enable(fsi, is_play);
-
if (over_period)
snd_pcm_period_elapsed(substream);
return 0;
}
-static int fsi_data_pop(struct fsi_priv *fsi, int startup)
+static int fsi_data_pop(struct fsi_priv *fsi)
{
- return fsi_fifo_data_ctrl(fsi, startup, SNDRV_PCM_STREAM_CAPTURE);
+ return fsi_fifo_data_ctrl(fsi, SNDRV_PCM_STREAM_CAPTURE);
}
-static int fsi_data_push(struct fsi_priv *fsi, int startup)
+static int fsi_data_push(struct fsi_priv *fsi)
{
- return fsi_fifo_data_ctrl(fsi, startup, SNDRV_PCM_STREAM_PLAYBACK);
+ return fsi_fifo_data_ctrl(fsi, SNDRV_PCM_STREAM_PLAYBACK);
}
static irqreturn_t fsi_interrupt(int irq, void *data)
@@ -737,15 +729,19 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
fsi_master_mask_set(master, SOFT_RST, IR, IR);
if (int_st & AB_IO(1, AO_SHIFT))
- fsi_data_push(&master->fsia, 0);
+ fsi_data_push(&master->fsia);
if (int_st & AB_IO(1, BO_SHIFT))
- fsi_data_push(&master->fsib, 0);
+ fsi_data_push(&master->fsib);
if (int_st & AB_IO(1, AI_SHIFT))
- fsi_data_pop(&master->fsia, 0);
+ fsi_data_pop(&master->fsia);
if (int_st & AB_IO(1, BI_SHIFT))
- fsi_data_pop(&master->fsib, 0);
+ fsi_data_pop(&master->fsib);
- fsi_irq_clear_all_status(master);
+ fsi_count_fifo_err(&master->fsia);
+ fsi_count_fifo_err(&master->fsib);
+
+ fsi_irq_clear_status(&master->fsia);
+ fsi_irq_clear_status(&master->fsib);
return IRQ_HANDLED;
}
@@ -762,7 +758,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
struct fsi_stream *io;
u32 flags = fsi_get_info_flags(fsi);
u32 fmt;
- u32 reg;
u32 data;
int is_play = fsi_is_play(substream);
int is_master;
@@ -794,7 +789,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
/* do fmt, di fmt */
data = 0;
- reg = is_play ? DO_FMT : DI_FMT;
fmt = is_play ? SH_FSI_GET_OFMT(flags) : SH_FSI_GET_IFMT(flags);
switch (fmt) {
case SH_FSI_FMT_MONO:
@@ -828,16 +822,18 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
dev_err(dai->dev, "This FSI can not use SPDIF\n");
return -EINVAL;
}
- data = CR_SPDIF;
+ data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM;
io->chan_num = 2;
fsi_spdif_clk_ctrl(fsi, 1);
- fsi_reg_mask_set(fsi, OUT_SEL, 0x0010, 0x0010);
+ fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD);
break;
default:
dev_err(dai->dev, "unknown format.\n");
return -EINVAL;
}
- fsi_reg_write(fsi, reg, data);
+ is_play ?
+ fsi_reg_write(fsi, DO_FMT, data) :
+ fsi_reg_write(fsi, DI_FMT, data);
/* irq clear */
fsi_irq_disable(fsi, is_play);
@@ -854,10 +850,17 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
{
struct fsi_priv *fsi = fsi_get_priv(substream);
int is_play = fsi_is_play(substream);
+ struct fsi_master *master = fsi_get_master(fsi);
+ int (*set_rate)(struct device *dev, int is_porta, int rate, int enable);
fsi_irq_disable(fsi, is_play);
fsi_clk_ctrl(fsi, 0);
+ set_rate = master->info->set_rate;
+ if (set_rate && fsi->rate)
+ set_rate(dai->dev, fsi_is_port_a(fsi), fsi->rate, 0);
+ fsi->rate = 0;
+
pm_runtime_put_sync(dai->dev);
}
@@ -874,7 +877,8 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
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);
+ ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi);
+ fsi_irq_enable(fsi, is_play);
break;
case SNDRV_PCM_TRIGGER_STOP:
fsi_irq_disable(fsi, is_play);
@@ -891,20 +895,20 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
{
struct fsi_priv *fsi = fsi_get_priv(substream);
struct fsi_master *master = fsi_get_master(fsi);
- int (*set_rate)(int is_porta, int rate) = master->info->set_rate;
+ int (*set_rate)(struct device *dev, int is_porta, int rate, int enable);
int fsi_ver = master->core->ver;
- int is_play = fsi_is_play(substream);
+ long rate = params_rate(params);
int ret;
- /* if slave mode, set_rate is not needed */
- if (!fsi_is_master_mode(fsi, is_play))
+ set_rate = master->info->set_rate;
+ if (!set_rate)
return 0;
- /* it is error if no set_rate */
- if (!set_rate)
- return -EIO;
+ ret = set_rate(dai->dev, fsi_is_port_a(fsi), rate, 1);
+ if (ret < 0) /* error */
+ return ret;
- ret = set_rate(fsi_is_port_a(fsi), params_rate(params));
+ fsi->rate = rate;
if (ret > 0) {
u32 data = 0;
@@ -1165,12 +1169,10 @@ static int fsi_probe(struct platform_device *pdev)
/* FSI A setting */
master->fsia.base = master->base;
master->fsia.master = master;
- master->fsia.mst_ctrl = A_MST_CTLR;
/* FSI B setting */
master->fsib.base = master->base + 0x40;
master->fsib.master = master;
- master->fsib.mst_ctrl = B_MST_CTLR;
pm_runtime_enable(&pdev->dev);
pm_runtime_resume(&pdev->dev);
@@ -1257,6 +1259,8 @@ static struct fsi_core fsi2_core = {
.int_st = CPU_INT_ST,
.iemsk = CPU_IEMSK,
.imsk = CPU_IMSK,
+ .a_mclk = A_MST_CTLR,
+ .b_mclk = B_MST_CTLR,
};
static struct platform_device_id fsi_id_table[] = {
diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c
index ac6c49c..6088a6a 100644
--- a/sound/soc/sh/migor.c
+++ b/sound/soc/sh/migor.c
@@ -8,11 +8,11 @@
* published by the Free Software Foundation.
*/
+#include <linux/clkdev.h>
#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/module.h>
-#include <asm/clkdev.h>
#include <asm/clock.h>
#include <cpu/sh7722.h>
@@ -20,7 +20,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include "../codecs/wm8978.h"
#include "siu.h"
@@ -140,11 +139,12 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int migor_dai_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_new_controls(codec, migor_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, migor_dapm_widgets,
ARRAY_SIZE(migor_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
diff --git a/sound/soc/sh/sh7760-ac97.c b/sound/soc/sh/sh7760-ac97.c
index f8e0ab8..917d3ce 100644
--- a/sound/soc/sh/sh7760-ac97.c
+++ b/sound/soc/sh/sh7760-ac97.c
@@ -12,7 +12,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/io.h>
#define IPSEL 0xFE400034
@@ -23,7 +22,7 @@ extern struct snd_soc_platform_driver sh7760_soc_platform;
static int machine_init(struct snd_soc_pcm_runtime *rtd)
{
- snd_soc_dapm_sync(rtd->codec);
+ snd_soc_dapm_sync(&rtd->codec->dapm);
return 0;
}
diff --git a/sound/soc/sh/siu.h b/sound/soc/sh/siu.h
index 9f4dcb9..83c3430 100644
--- a/sound/soc/sh/siu.h
+++ b/sound/soc/sh/siu.h
@@ -75,7 +75,7 @@ struct siu_firmware {
#include <sound/core.h>
#include <sound/pcm.h>
-#include <sound/soc-dai.h>
+#include <sound/soc.h>
#define SIU_PERIOD_BYTES_MAX 8192 /* DMA transfer/period size */
#define SIU_PERIOD_BYTES_MIN 256 /* DMA transfer/period size */
diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c
index af53b64..4973c29 100644
--- a/sound/soc/sh/siu_dai.c
+++ b/sound/soc/sh/siu_dai.c
@@ -28,7 +28,7 @@
#include <asm/siu.h>
#include <sound/control.h>
-#include <sound/soc-dai.h>
+#include <sound/soc.h>
#include "siu.h"
diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c
index ed29c9e..a423bab 100644
--- a/sound/soc/sh/siu_pcm.c
+++ b/sound/soc/sh/siu_pcm.c
@@ -29,7 +29,7 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
-#include <sound/soc-dai.h>
+#include <sound/soc.h>
#include <asm/siu.h>
OpenPOWER on IntegriCloud