diff options
Diffstat (limited to 'sound/soc/sh')
-rw-r--r-- | sound/soc/sh/Kconfig | 24 | ||||
-rw-r--r-- | sound/soc/sh/Makefile | 6 | ||||
-rw-r--r-- | sound/soc/sh/fsi-ak4642.c | 108 | ||||
-rw-r--r-- | sound/soc/sh/fsi-da7210.c | 81 | ||||
-rw-r--r-- | sound/soc/sh/fsi-hdmi.c | 118 | ||||
-rw-r--r-- | sound/soc/sh/fsi.c | 224 |
6 files changed, 159 insertions, 402 deletions
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig index d8e06a607a2..6bcb1164d59 100644 --- a/sound/soc/sh/Kconfig +++ b/sound/soc/sh/Kconfig @@ -22,6 +22,7 @@ config SND_SOC_SH4_SSI config SND_SOC_SH4_FSI tristate "SH4 FSI support" + select SND_SIMPLE_CARD help This option enables FSI sound support @@ -46,29 +47,6 @@ config SND_SH7760_AC97 This option enables generic sound support for the first AC97 unit of the SH7760. -config SND_FSI_AK4642 - tristate "FSI-AK4642 sound support" - depends on SND_SOC_SH4_FSI && I2C - select SND_SOC_AK4642 - help - This option enables generic sound support for the - FSI - AK4642 unit - -config SND_FSI_DA7210 - tristate "FSI-DA7210 sound support" - depends on SND_SOC_SH4_FSI && I2C - 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 94476d4c0fd..849b387d17d 100644 --- a/sound/soc/sh/Makefile +++ b/sound/soc/sh/Makefile @@ -14,13 +14,7 @@ obj-$(CONFIG_SND_SOC_SH4_SIU) += snd-soc-siu.o ## boards 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/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c deleted file mode 100644 index 97f540aabbd..00000000000 --- a/sound/soc/sh/fsi-ak4642.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * FSI-AK464x sound support for ms7724se - * - * Copyright (C) 2009 Renesas Solutions Corp. - * Kuninori Morimoto <morimoto.kuninori@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 <linux/module.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; - int id; -}; - -static int fsi_ak4642_dai_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_dai *codec = rtd->codec_dai; - struct snd_soc_dai *cpu = rtd->cpu_dai; - int ret; - - ret = snd_soc_dai_set_fmt(codec, SND_SOC_DAIFMT_LEFT_J | - SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_sysclk(codec, 0, 11289600, 0); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_LEFT_J | - SND_SOC_DAIFMT_CBS_CFS); - - return ret; -} - -static struct snd_soc_dai_link fsi_dai_link = { - .codec_dai_name = "ak4642-hifi", - .init = fsi_ak4642_dai_init, -}; - -static struct snd_soc_card fsi_soc_card = { - .owner = THIS_MODULE, - .dai_link = &fsi_dai_link, - .num_links = 1, -}; - -static struct platform_device *fsi_snd_device; - -static int fsi_ak4642_probe(struct platform_device *pdev) -{ - int ret = -ENOMEM; - struct fsi_ak4642_info *pinfo = pdev->dev.platform_data; - - if (!pinfo) { - dev_err(&pdev->dev, "no info for fsi ak4642\n"); - goto out; - } - - fsi_snd_device = platform_device_alloc("soc-audio", pinfo->id); - if (!fsi_snd_device) - goto out; - - fsi_dai_link.name = pinfo->name; - fsi_dai_link.stream_name = pinfo->name; - fsi_dai_link.cpu_dai_name = pinfo->cpu_dai; - fsi_dai_link.platform_name = pinfo->platform; - fsi_dai_link.codec_name = pinfo->codec; - fsi_soc_card.name = pinfo->card; - - 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 int fsi_ak4642_remove(struct platform_device *pdev) -{ - platform_device_unregister(fsi_snd_device); - return 0; -} - -static struct platform_driver fsi_ak4642 = { - .driver = { - .name = "fsi-ak4642-audio", - }, - .probe = fsi_ak4642_probe, - .remove = fsi_ak4642_remove, -}; - -module_platform_driver(fsi_ak4642); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Generic SH4 FSI-AK4642 sound card"); -MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>"); diff --git a/sound/soc/sh/fsi-da7210.c b/sound/soc/sh/fsi-da7210.c deleted file mode 100644 index 1dd3354c741..00000000000 --- a/sound/soc/sh/fsi-da7210.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * fsi-da7210.c - * - * Copyright (C) 2009 Renesas Solutions Corp. - * Kuninori Morimoto <morimoto.kuninori@renesas.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include <linux/platform_device.h> -#include <linux/module.h> -#include <sound/sh_fsi.h> - -static int fsi_da7210_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_dai *codec = rtd->codec_dai; - struct snd_soc_dai *cpu = rtd->cpu_dai; - int ret; - - ret = snd_soc_dai_set_fmt(codec, - SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_CBS_CFS); - - return ret; -} - -static struct snd_soc_dai_link fsi_da7210_dai = { - .name = "DA7210", - .stream_name = "DA7210", - .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-DA7210", - .owner = THIS_MODULE, - .dai_link = &fsi_da7210_dai, - .num_links = 1, -}; - -static struct platform_device *fsi_da7210_snd_device; - -static int __init fsi_da7210_sound_init(void) -{ - int ret; - - fsi_da7210_snd_device = platform_device_alloc("soc-audio", FSI_PORT_B); - if (!fsi_da7210_snd_device) - return -ENOMEM; - - 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); - - return ret; -} - -static void __exit fsi_da7210_sound_exit(void) -{ - platform_device_unregister(fsi_da7210_snd_device); -} - -module_init(fsi_da7210_sound_init); -module_exit(fsi_da7210_sound_exit); - -/* Module information */ -MODULE_DESCRIPTION("ALSA SoC FSI DA2710"); -MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/sh/fsi-hdmi.c b/sound/soc/sh/fsi-hdmi.c deleted file mode 100644 index 6e41908323e..00000000000 --- a/sound/soc/sh/fsi-hdmi.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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 <linux/module.h> -#include <sound/sh_fsi.h> - -struct fsi_hdmi_data { - const char *cpu_dai; - const char *card; - int id; -}; - -static int fsi_hdmi_dai_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_dai *cpu = rtd->cpu_dai; - int ret; - - ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_CBM_CFM); - - return ret; -} - -static struct snd_soc_dai_link fsi_dai_link = { - .name = "HDMI", - .stream_name = "HDMI", - .codec_dai_name = "sh_mobile_hdmi-hifi", - .platform_name = "sh_fsi2", - .codec_name = "sh-mobile-hdmi", - .init = fsi_hdmi_dai_init, -}; - -static struct snd_soc_card fsi_soc_card = { - .owner = THIS_MODULE, - .dai_link = &fsi_dai_link, - .num_links = 1, -}; - -static struct platform_device *fsi_snd_device; - -static int fsi_hdmi_probe(struct platform_device *pdev) -{ - int ret = -ENOMEM; - const struct platform_device_id *id_entry; - struct fsi_hdmi_data *pdata; - - id_entry = pdev->id_entry; - if (!id_entry) { - dev_err(&pdev->dev, "unknown fsi hdmi\n"); - return -ENODEV; - } - - pdata = (struct fsi_hdmi_data *)id_entry->driver_data; - - fsi_snd_device = platform_device_alloc("soc-audio", pdata->id); - if (!fsi_snd_device) - goto out; - - fsi_dai_link.cpu_dai_name = pdata->cpu_dai; - fsi_soc_card.name = pdata->card; - - 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 int fsi_hdmi_remove(struct platform_device *pdev) -{ - platform_device_unregister(fsi_snd_device); - return 0; -} - -static struct fsi_hdmi_data fsi2_a_hdmi = { - .cpu_dai = "fsia-dai", - .card = "FSI2A-HDMI", - .id = FSI_PORT_A, -}; - -static struct fsi_hdmi_data fsi2_b_hdmi = { - .cpu_dai = "fsib-dai", - .card = "FSI2B-HDMI", - .id = FSI_PORT_B, -}; - -static struct platform_device_id fsi_id_table[] = { - /* FSI 2 */ - { "sh_fsi2_a_hdmi", (kernel_ulong_t)&fsi2_a_hdmi }, - { "sh_fsi2_b_hdmi", (kernel_ulong_t)&fsi2_b_hdmi }, - {}, -}; - -static struct platform_driver fsi_hdmi = { - .driver = { - .name = "fsi-hdmi-audio", - }, - .probe = fsi_hdmi_probe, - .remove = fsi_hdmi_remove, - .id_table = fsi_id_table, -}; - -module_platform_driver(fsi_hdmi); - -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 74ed2dffbff..7cee22515d9 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -132,6 +132,25 @@ typedef int (*set_rate_func)(struct device *dev, int rate, int enable); /* + * bus options + * + * 0x000000BA + * + * A : sample widtht 16bit setting + * B : sample widtht 24bit setting + */ + +#define SHIFT_16DATA 0 +#define SHIFT_24DATA 4 + +#define PACKAGE_24BITBUS_BACK 0 +#define PACKAGE_24BITBUS_FRONT 1 +#define PACKAGE_16BITBUS_STREAM 2 + +#define BUSOP_SET(s, a) ((a) << SHIFT_ ## s ## DATA) +#define BUSOP_GET(s, a) (((a) >> SHIFT_ ## s ## DATA) & 0xF) + +/* * FSI driver use below type name for variable * * xxx_num : number of data @@ -189,6 +208,11 @@ struct fsi_stream { int oerr_num; /* + * bus options + */ + u32 bus_option; + + /* * thse are initialized by fsi_handler_init() */ struct fsi_stream_handler *handler; @@ -211,8 +235,7 @@ struct fsi_priv { struct fsi_stream playback; struct fsi_stream capture; - u32 do_fmt; - u32 di_fmt; + u32 fmt; int chan_num:16; int clk_master:1; @@ -321,6 +344,10 @@ static void _fsi_master_mask_set(struct fsi_master *master, /* * basic function */ +static int fsi_version(struct fsi_master *master) +{ + return master->core->ver; +} static struct fsi_master *fsi_get_master(struct fsi_priv *fsi) { @@ -495,6 +522,7 @@ static void fsi_stream_init(struct fsi_priv *fsi, io->period_samples = fsi_frame2sample(fsi, runtime->period_size); io->period_pos = 0; io->sample_width = samples_to_bytes(runtime, 1); + io->bus_option = 0; io->oerr_num = -1; /* ignore 1st err */ io->uerr_num = -1; /* ignore 1st err */ fsi_stream_handler_call(io, init, fsi, io); @@ -522,6 +550,7 @@ static void fsi_stream_quit(struct fsi_priv *fsi, struct fsi_stream *io) io->period_samples = 0; io->period_pos = 0; io->sample_width = 0; + io->bus_option = 0; io->oerr_num = 0; io->uerr_num = 0; spin_unlock_irqrestore(&master->lock, flags); @@ -581,6 +610,53 @@ static int fsi_stream_remove(struct fsi_priv *fsi) } /* + * format/bus/dma setting + */ +static void fsi_format_bus_setup(struct fsi_priv *fsi, struct fsi_stream *io, + u32 bus, struct device *dev) +{ + struct fsi_master *master = fsi_get_master(fsi); + int is_play = fsi_stream_is_play(fsi, io); + u32 fmt = fsi->fmt; + + if (fsi_version(master) >= 2) { + u32 dma = 0; + + /* + * FSI2 needs DMA/Bus setting + */ + switch (bus) { + case PACKAGE_24BITBUS_FRONT: + fmt |= CR_BWS_24; + dma |= VDMD_FRONT; + dev_dbg(dev, "24bit bus / package in front\n"); + break; + case PACKAGE_16BITBUS_STREAM: + fmt |= CR_BWS_16; + dma |= VDMD_STREAM; + dev_dbg(dev, "16bit bus / stream mode\n"); + break; + case PACKAGE_24BITBUS_BACK: + default: + fmt |= CR_BWS_24; + dma |= VDMD_BACK; + dev_dbg(dev, "24bit bus / package in back\n"); + break; + } + + if (is_play) + fsi_reg_write(fsi, OUT_DMAC, dma); + else + fsi_reg_write(fsi, IN_DMAC, dma); + } + + if (is_play) + fsi_reg_write(fsi, DO_FMT, fmt); + else + fsi_reg_write(fsi, DI_FMT, fmt); +} + +/* * irq function */ @@ -629,11 +705,6 @@ static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable) struct fsi_master *master = fsi_get_master(fsi); u32 mask, val; - if (master->core->ver < 2) { - pr_err("fsi: register access err (%s)\n", __func__); - return; - } - mask = BP | SE; val = enable ? mask : 0; @@ -648,9 +719,7 @@ static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable) static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, long rate, int enable) { - struct fsi_master *master = fsi_get_master(fsi); set_rate_func set_rate = fsi_get_info_set_rate(fsi); - int fsi_ver = master->core->ver; int ret; if (!set_rate) @@ -682,10 +751,7 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, data |= (0x3 << 12); break; case SH_FSI_ACKMD_32: - if (fsi_ver < 2) - dev_err(dev, "unsupported ACKMD\n"); - else - data |= (0x4 << 12); + data |= (0x4 << 12); break; } @@ -708,10 +774,7 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, data |= (0x4 << 8); break; case SH_FSI_BPFMD_16: - if (fsi_ver < 2) - dev_err(dev, "unsupported ACKMD\n"); - else - data |= (0x7 << 8); + data |= (0x7 << 8); break; } @@ -728,11 +791,26 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, */ static void fsi_pio_push16(struct fsi_priv *fsi, u8 *_buf, int samples) { - u16 *buf = (u16 *)_buf; + u32 enable_stream = fsi_get_info_flags(fsi) & SH_FSI_ENABLE_STREAM_MODE; int i; - for (i = 0; i < samples; i++) - fsi_reg_write(fsi, DODT, ((u32)*(buf + i) << 8)); + if (enable_stream) { + /* + * stream mode + * see + * fsi_pio_push_init() + */ + u32 *buf = (u32 *)_buf; + + for (i = 0; i < samples / 2; i++) + fsi_reg_write(fsi, DODT, buf[i]); + } else { + /* normal mode */ + u16 *buf = (u16 *)_buf; + + for (i = 0; i < samples; i++) + fsi_reg_write(fsi, DODT, ((u32)*(buf + i) << 8)); + } } static void fsi_pio_pop16(struct fsi_priv *fsi, u8 *_buf, int samples) @@ -872,12 +950,44 @@ static void fsi_pio_start_stop(struct fsi_priv *fsi, struct fsi_stream *io, fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0); } +static int fsi_pio_push_init(struct fsi_priv *fsi, struct fsi_stream *io) +{ + u32 enable_stream = fsi_get_info_flags(fsi) & SH_FSI_ENABLE_STREAM_MODE; + + /* + * we can use 16bit stream mode + * when "playback" and "16bit data" + * and platform allows "stream mode" + * see + * fsi_pio_push16() + */ + if (enable_stream) + io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) | + BUSOP_SET(16, PACKAGE_16BITBUS_STREAM); + else + io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) | + BUSOP_SET(16, PACKAGE_24BITBUS_BACK); + return 0; +} + +static int fsi_pio_pop_init(struct fsi_priv *fsi, struct fsi_stream *io) +{ + /* + * always 24bit bus, package back when "capture" + */ + io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) | + BUSOP_SET(16, PACKAGE_24BITBUS_BACK); + return 0; +} + static struct fsi_stream_handler fsi_pio_push_handler = { + .init = fsi_pio_push_init, .transfer = fsi_pio_push, .start_stop = fsi_pio_start_stop, }; static struct fsi_stream_handler fsi_pio_pop_handler = { + .init = fsi_pio_pop_init, .transfer = fsi_pio_pop, .start_stop = fsi_pio_start_stop, }; @@ -919,6 +1029,13 @@ static int fsi_dma_init(struct fsi_priv *fsi, struct fsi_stream *io) enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ? DMA_TO_DEVICE : DMA_FROM_DEVICE; + /* + * 24bit data : 24bit bus / package in back + * 16bit data : 16bit bus / stream mode + */ + io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) | + BUSOP_SET(16, PACKAGE_16BITBUS_STREAM); + io->dma = dma_map_single(dai->dev, runtime->dma_area, snd_pcm_lib_buffer_bytes(io->substream), dir); return 0; @@ -1055,25 +1172,9 @@ static int fsi_dma_transfer(struct fsi_priv *fsi, struct fsi_stream *io) static void fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io, int start) { - u32 bws; - u32 dma; + u32 enable = start ? DMA_ON : 0; - switch (io->sample_width * start) { - case 2: - bws = CR_BWS_16; - dma = VDMD_STREAM | DMA_ON; - break; - case 4: - bws = CR_BWS_24; - dma = VDMD_BACK | DMA_ON; - break; - default: - bws = 0; - dma = 0; - } - - fsi_reg_mask_set(fsi, DO_FMT, CR_BWS_MASK, bws); - fsi_reg_write(fsi, OUT_DMAC, dma); + fsi_reg_mask_set(fsi, OUT_DMAC, DMA_ON, enable); } static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io) @@ -1176,8 +1277,6 @@ static int fsi_hw_startup(struct fsi_priv *fsi, struct fsi_stream *io, struct device *dev) { - struct fsi_master *master = fsi_get_master(fsi); - int fsi_ver = master->core->ver; u32 flags = fsi_get_info_flags(fsi); u32 data = 0; @@ -1200,10 +1299,6 @@ static int fsi_hw_startup(struct fsi_priv *fsi, fsi_reg_write(fsi, CKG2, data); - /* set format */ - fsi_reg_write(fsi, DO_FMT, fsi->do_fmt); - fsi_reg_write(fsi, DI_FMT, fsi->di_fmt); - /* spdif ? */ if (fsi_is_spdif(fsi)) { fsi_spdif_clk_ctrl(fsi, 1); @@ -1211,15 +1306,18 @@ static int fsi_hw_startup(struct fsi_priv *fsi, } /* - * FIXME - * - * FSI driver assumed that data package is in-back. - * FSI2 chip can select it. + * get bus settings */ - if (fsi_ver >= 2) { - fsi_reg_write(fsi, OUT_DMAC, (1 << 4)); - fsi_reg_write(fsi, IN_DMAC, (1 << 4)); + data = 0; + switch (io->sample_width) { + case 2: + data = BUSOP_GET(16, io->bus_option); + break; + case 4: + data = BUSOP_GET(24, io->bus_option); + break; } + fsi_format_bus_setup(fsi, io, data, dev); /* irq clear */ fsi_irq_disable(fsi, io); @@ -1243,7 +1341,9 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, { struct fsi_priv *fsi = fsi_get_priv(substream); - return fsi_hw_startup(fsi, fsi_stream_get(fsi, substream), dai->dev); + fsi->rate = 0; + + return 0; } static void fsi_dai_shutdown(struct snd_pcm_substream *substream, @@ -1251,7 +1351,6 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream, { struct fsi_priv *fsi = fsi_get_priv(substream); - fsi_hw_shutdown(fsi, dai->dev); fsi->rate = 0; } @@ -1265,11 +1364,13 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, switch (cmd) { case SNDRV_PCM_TRIGGER_START: fsi_stream_init(fsi, io, substream); + fsi_hw_startup(fsi, io, dai->dev); ret = fsi_stream_transfer(io); if (0 == ret) fsi_stream_start(fsi, io); break; case SNDRV_PCM_TRIGGER_STOP: + fsi_hw_shutdown(fsi, dai->dev); fsi_stream_stop(fsi, io); fsi_stream_quit(fsi, io); break; @@ -1280,42 +1381,33 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, static int fsi_set_fmt_dai(struct fsi_priv *fsi, unsigned int fmt) { - u32 data = 0; - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: - data = CR_I2S; + fsi->fmt = CR_I2S; fsi->chan_num = 2; break; case SND_SOC_DAIFMT_LEFT_J: - data = CR_PCM; + fsi->fmt = CR_PCM; fsi->chan_num = 2; break; default: return -EINVAL; } - fsi->do_fmt = data; - fsi->di_fmt = data; - return 0; } static int fsi_set_fmt_spdif(struct fsi_priv *fsi) { struct fsi_master *master = fsi_get_master(fsi); - u32 data = 0; - if (master->core->ver < 2) + if (fsi_version(master) < 2) return -EINVAL; - data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM; + fsi->fmt = CR_DTMD_SPDIF_PCM | CR_PCM; fsi->chan_num = 2; fsi->spdif = 1; - fsi->do_fmt = data; - fsi->di_fmt = data; - return 0; } |