From ed85ff32100063b05cdc15c9c6bb0f2b98827583 Mon Sep 17 00:00:00 2001 From: Alan Tull Date: Wed, 18 May 2011 16:32:35 -0500 Subject: ENGR00139461-1 mxc alsa soc spdif driver BugLink: http://bugs.launchpad.net/bugs/837155 S/PDIF tx and rx using ASoC layer. Signed-off-by: Alan Tull Signed-off-by: Eric Miao --- arch/arm/configs/imx5_defconfig | 3 + arch/arm/mach-mx5/Kconfig | 2 + arch/arm/mach-mx5/board-mx51_3ds.c | 20 ++++++- arch/arm/mach-mx5/board-mx51_babbage.c | 18 ++++++ arch/arm/mach-mx5/board-mx53_ard.c | 18 ++++++ arch/arm/mach-mx5/board-mx53_evk.c | 16 ++++++ arch/arm/mach-mx5/board-mx53_loco.c | 19 +++++++ arch/arm/mach-mx5/board-mx53_smd.c | 22 ++++++++ arch/arm/mach-mx5/clock.c | 4 +- arch/arm/mach-mx5/devices-imx51.h | 8 +++ arch/arm/mach-mx5/devices-imx53.h | 7 +++ arch/arm/plat-mxc/devices/Kconfig | 3 + arch/arm/plat-mxc/devices/Makefile | 4 +- .../plat-mxc/devices/platform-imx-spdif-audio.c | 29 ++++++++++ arch/arm/plat-mxc/devices/platform-imx-spdif-dai.c | 65 ++++++++++++++++++++++ arch/arm/plat-mxc/devices/platform-imx-spdif.c | 64 +++++++++++++++++++++ arch/arm/plat-mxc/include/mach/devices-common.h | 17 ++++++ arch/arm/plat-mxc/include/mach/dma.h | 7 +++ arch/arm/plat-mxc/include/mach/mx51.h | 2 +- 19 files changed, 323 insertions(+), 5 deletions(-) create mode 100644 arch/arm/plat-mxc/devices/platform-imx-spdif-audio.c create mode 100644 arch/arm/plat-mxc/devices/platform-imx-spdif-dai.c create mode 100644 arch/arm/plat-mxc/devices/platform-imx-spdif.c diff --git a/arch/arm/configs/imx5_defconfig b/arch/arm/configs/imx5_defconfig index c26e9c2d35a0..79937ac23b7b 100644 --- a/arch/arm/configs/imx5_defconfig +++ b/arch/arm/configs/imx5_defconfig @@ -279,6 +279,7 @@ CONFIG_IMX_HAVE_PLATFORM_IMX_DCP=y CONFIG_IMX_HAVE_PLATFORM_RANDOM_RNGC=y CONFIG_IMX_HAVE_PLATFORM_PERFMON=y CONFIG_IMX_HAVE_PLATFORM_LDB=y +CONFIG_IMX_HAVE_PLATFORM_IMX_SPDIF=y # # Freescale MXC Implementations @@ -1551,6 +1552,8 @@ CONFIG_SND_SOC_AC97_BUS=y CONFIG_SND_IMX_SOC=y CONFIG_SND_MXC_SOC_MX2=y CONFIG_SND_SOC_IMX_SGTL5000=y +CONFIG_SND_MXC_SOC_SPDIF_DAI=y +CONFIG_SND_SOC_IMX_SPDIF=y CONFIG_SND_SOC_I2C_AND_SPI=y # CONFIG_SND_SOC_ALL_CODECS is not set CONFIG_SND_SOC_SGTL5000=y diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig index ce2ad6c72407..aa4910e923b8 100644 --- a/arch/arm/mach-mx5/Kconfig +++ b/arch/arm/mach-mx5/Kconfig @@ -35,6 +35,7 @@ config SOC_IMX51 select IMX_HAVE_PLATFORM_IMX_DVFS select IMX_HAVE_PLATFORM_IMX_SSI select IMX_HAVE_PLATFORM_IMX_IIM + select IMX_HAVE_PLATFORM_IMX_SPDIF config SOC_IMX53 bool @@ -51,6 +52,7 @@ config SOC_IMX53 select IMX_HAVE_PLATFORM_IMX_SSI select IMX_HAVE_PLATFORM_IMX_IIM select IMX_HAVE_PLATFORM_LDB + select IMX_HAVE_PLATFORM_IMX_SPDIF config FORCE_MAX_ZONEORDER int "MAX_ORDER" diff --git a/arch/arm/mach-mx5/board-mx51_3ds.c b/arch/arm/mach-mx5/board-mx51_3ds.c index 63dfbeafbc1e..c279555bf2d7 100644 --- a/arch/arm/mach-mx5/board-mx51_3ds.c +++ b/arch/arm/mach-mx5/board-mx51_3ds.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved. * Copyright (C) 2010 Jason Wang * * The code contained herein is licensed under the GNU General Public @@ -68,6 +68,8 @@ static iomux_v3_cfg_t mx51_3ds_pads[] = { MX51_PAD_NANDF_RB3__ECSPI2_MISO, MX51_PAD_NANDF_D15__ECSPI2_MOSI, MX51_PAD_NANDF_D12__GPIO3_28, + + MX51_PAD_GPIO1_7__SPDIF_OUT, }; /* Serial ports */ @@ -130,6 +132,15 @@ static struct spi_board_info mx51_3ds_spi_nor_device[] = { .platform_data = NULL,}, }; +static struct mxc_spdif_platform_data mxc_spdif_data = { + .spdif_tx = 1, + .spdif_rx = 0, + .spdif_clk_44100 = 0, /* spdif_ext_clk source for 44.1KHz */ + .spdif_clk_48000 = 7, /* audio osc source */ + .spdif_clkid = 0, + .spdif_clk = NULL, /* spdif bus clk */ +}; + /* * Board specific initialization. */ @@ -142,6 +153,9 @@ static void __init mx51_3ds_init(void) imx51_add_imx_uart(1, &uart_pdata); imx51_add_imx_uart(2, &uart_pdata); + mxc_spdif_data.spdif_core_clk = clk_get(NULL, "spdif_xtal_clk"); + clk_put(mxc_spdif_data.spdif_core_clk); + imx51_add_ecspi(1, &mx51_3ds_ecspi2_pdata); spi_register_board_info(mx51_3ds_spi_nor_device, ARRAY_SIZE(mx51_3ds_spi_nor_device)); @@ -153,6 +167,10 @@ static void __init mx51_3ds_init(void) imx51_add_sdhci_esdhc_imx(0, NULL); imx51_add_imx_keypad(&mx51_3ds_map_data); imx51_add_imx2_wdt(0, NULL); + + imx51_add_spdif(&mxc_spdif_data); + imx51_add_spdif_dai(); + imx51_add_spdif_audio_device(); } static void __init mx51_3ds_timer_init(void) diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c index 56c5383dc88e..9acc20ca4f7f 100644 --- a/arch/arm/mach-mx5/board-mx51_babbage.c +++ b/arch/arm/mach-mx5/board-mx51_babbage.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include @@ -226,6 +227,8 @@ static iomux_v3_cfg_t mx51babbage_pads[] = { MX51_PAD_AUD3_BB_RXD__AUD3_RXD, MX51_PAD_AUD3_BB_CK__AUD3_TXC, MX51_PAD_AUD3_BB_FS__AUD3_TXFS, + + MX51_PAD_OWIRE_LINE__SPDIF_OUT, }; /* Serial ports */ @@ -561,6 +564,14 @@ static void __init mx51_bbg_init_usb(void) mx5_usb_dr_init(); mx5_usbh1_init(); } +static struct mxc_spdif_platform_data mxc_spdif_data = { + .spdif_tx = 1, + .spdif_rx = 0, + .spdif_clk_44100 = 0, /* spdif_ext_clk source for 44.1KHz */ + .spdif_clk_48000 = 7, /* audio osc source */ + .spdif_clkid = 0, + .spdif_clk = NULL, /* spdif bus clk */ +}; /* * Board specific initialization. @@ -573,6 +584,9 @@ static void __init mx51_babbage_init(void) mxc_iomux_v3_setup_multiple_pads(mx51babbage_pads, ARRAY_SIZE(mx51babbage_pads)); + mxc_spdif_data.spdif_core_clk = clk_get(NULL, "spdif_xtal_clk"); + clk_put(mxc_spdif_data.spdif_core_clk); + imx51_add_imx_uart(0, &uart_pdata); imx51_add_imx_uart(1, &uart_pdata); imx51_add_imx_uart(2, &uart_pdata); @@ -597,6 +611,10 @@ static void __init mx51_babbage_init(void) imx51_add_imx_i2c(0, &babbage_i2c_data); imx51_add_imx_i2c(1, &babbage_i2c_data); + imx51_add_spdif(&mxc_spdif_data); + imx51_add_spdif_dai(); + imx51_add_spdif_audio_device(); + mxc_register_device(&mxc_hsi2c_device, &babbage_hsi2c_data); mxc_register_device(&mxc_pm_device, &babbage_pm_data); i2c_register_board_info(1, mxc_i2c1_board_info, diff --git a/arch/arm/mach-mx5/board-mx53_ard.c b/arch/arm/mach-mx5/board-mx53_ard.c index 9ffb0bbad2eb..91e023bc77a4 100644 --- a/arch/arm/mach-mx5/board-mx53_ard.c +++ b/arch/arm/mach-mx5/board-mx53_ard.c @@ -126,6 +126,9 @@ static iomux_v3_cfg_t mx53_ard_pads[] = { /* TOUCH_INT_B */ MX53_PAD_GPIO_17__GPIO7_12, + + /* MAINBRD_SPDIF_IN */ + MX53_PAD_KEY_COL3__SPDIF_IN1, }; /* Config CS1 settings for ethernet controller */ @@ -214,6 +217,15 @@ static struct i2c_board_info mxc_i2c2_board_info[] __initdata = { }, }; +static struct mxc_spdif_platform_data mxc_spdif_data = { + .spdif_tx = 0, + .spdif_rx = 1, + .spdif_clk_44100 = 0, /* Souce from CKIH1 for 44.1K */ + .spdif_clk_48000 = 7, /* Source from CKIH2 for 48k and 32k */ + .spdif_clkid = 0, + .spdif_clk = NULL, /* spdif bus clk */ +}; + static inline void mx53_ard_init_uart(void) { imx53_add_imx_uart(0, NULL); @@ -291,6 +303,8 @@ static void __init mx53_ard_board_init(void) vga = MX53_PAD_EIM_RW__IPU_DI1_PIN8; mxc_iomux_v3_setup_pad(vga); + mxc_spdif_data.spdif_core_clk = clk_get(NULL, "spdif_xtal_clk"); + clk_put(mxc_spdif_data.spdif_core_clk); mx53_ard_init_uart(); imx53_add_ipuv3(&ipu_data); @@ -309,6 +323,10 @@ static void __init mx53_ard_board_init(void) imx53_add_imx_i2c(1, &mx53_ard_i2c1_data); imx53_add_imx_i2c(2, &mx53_ard_i2c2_data); + imx53_add_spdif(&mxc_spdif_data); + imx53_add_spdif_dai(); + imx53_add_spdif_audio_device(); + i2c_register_board_info(1, mxc_i2c1_board_info, ARRAY_SIZE(mxc_i2c1_board_info)); i2c_register_board_info(2, mxc_i2c2_board_info, diff --git a/arch/arm/mach-mx5/board-mx53_evk.c b/arch/arm/mach-mx5/board-mx53_evk.c index 300d56e75c2c..42319341f9eb 100644 --- a/arch/arm/mach-mx5/board-mx53_evk.c +++ b/arch/arm/mach-mx5/board-mx53_evk.c @@ -720,10 +720,22 @@ static void __init mx53_evk_io_init(void) } } +static struct mxc_spdif_platform_data mxc_spdif_data = { + .spdif_tx = 1, + .spdif_rx = 0, + .spdif_clk_44100 = 0, /* Souce from CKIH1 for 44.1K */ + .spdif_clk_48000 = 7, /* Source from CKIH2 for 48k and 32k */ + .spdif_clkid = 0, + .spdif_clk = NULL, /* spdif bus clk */ +}; + static void __init mx53_evk_board_init(void) { mx53_evk_io_init(); + mxc_spdif_data.spdif_core_clk = clk_get(NULL, "spdif_xtal_clk"); + clk_put(mxc_spdif_data.spdif_core_clk); + mx53_evk_init_uart(); imx53_add_srtc(); mx53_evk_fec_reset(); @@ -756,6 +768,10 @@ static void __init mx53_evk_board_init(void) imx53_add_ecspi(0, &mx53_evk_spi_data); imx53_add_imx2_wdt(0, NULL); + imx53_add_spdif(&mxc_spdif_data); + imx53_add_spdif_dai(); + imx53_add_spdif_audio_device(); + /* this call required to release SCC RAM partition held by ROM * during boot, even if SCC2 driver is not part of the image */ diff --git a/arch/arm/mach-mx5/board-mx53_loco.c b/arch/arm/mach-mx5/board-mx53_loco.c index ec32e9fac8df..4aa775a82ce7 100644 --- a/arch/arm/mach-mx5/board-mx53_loco.c +++ b/arch/arm/mach-mx5/board-mx53_loco.c @@ -735,6 +735,18 @@ static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags, } } +static struct mxc_spdif_platform_data mxc_spdif_data = { + .spdif_tx = 1, + .spdif_rx = 0, + .spdif_clk_44100 = -1, /* No source for 44.1K */ + /* Source from CCM spdif_clk (24M) for 48k and 32k + * It's not accurate: for 48Khz it is actually 46875Hz (2.3% off) + */ + .spdif_clk_48000 = 1, + .spdif_clkid = 0, + .spdif_clk = NULL, /* spdif bus clk */ +}; + static void __init mx53_loco_board_init(void) { mx53_loco_io_init(); @@ -743,6 +755,9 @@ static void __init mx53_loco_board_init(void) mx53_loco_fec_reset(); imx53_add_fec(&mx53_loco_fec_data); + mxc_spdif_data.spdif_core_clk = clk_get(NULL, "spdif_xtal_clk"); + clk_put(mxc_spdif_data.spdif_core_clk); + mxc_register_device(&mxc_pm_device, &loco_pm_data); imx53_add_ipuv3(&ipu_data); @@ -780,6 +795,10 @@ static void __init mx53_loco_board_init(void) mxc_register_device(&loco_audio_device, &loco_audio_data); imx53_add_imx_ssi(1, &loco_ssi_pdata); + imx53_add_spdif(&mxc_spdif_data); + imx53_add_spdif_dai(); + imx53_add_spdif_audio_device(); + /*GPU*/ if (mx53_revision() >= IMX_CHIP_REVISION_2_0) gpu_data.z160_revision = 1; diff --git a/arch/arm/mach-mx5/board-mx53_smd.c b/arch/arm/mach-mx5/board-mx53_smd.c index 9f644b1e1215..c88641116a88 100644 --- a/arch/arm/mach-mx5/board-mx53_smd.c +++ b/arch/arm/mach-mx5/board-mx53_smd.c @@ -172,6 +172,8 @@ static iomux_v3_cfg_t mx53_smd_pads[] = { MX53_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK, MX53_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1, MX53_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0, + + MX53_PAD_GPIO_17__SPDIF_OUT1, }; #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) @@ -674,10 +676,26 @@ static struct fsl_mxc_ldb_platform_data ldb_data = { .boot_enable = MXC_LDBDI1, }; +static struct mxc_spdif_platform_data mxc_spdif_data = { + .spdif_tx = 1, + .spdif_rx = 0, + .spdif_clk_44100 = 0, /* Souce from CKIH1 for 44.1K */ + /* Source from CCM spdif_clk (24M) for 48k and 32k + * It's not accurate + */ + .spdif_clk_48000 = 1, + .spdif_clkid = 0, + .spdif_clk = NULL, /* spdif bus clk */ +}; + static void __init mx53_smd_board_init(void) { mxc_iomux_v3_setup_multiple_pads(mx53_smd_pads, ARRAY_SIZE(mx53_smd_pads)); + + mxc_spdif_data.spdif_core_clk = clk_get(NULL, "spdif_xtal_clk"); + clk_put(mxc_spdif_data.spdif_core_clk); + mx53_smd_init_uart(); mx53_smd_fec_reset(); mxc_register_device(&mxc_pm_device, &smd_pm_data); @@ -723,6 +741,10 @@ static void __init mx53_smd_board_init(void) mxc_register_device(&imx_bt_rfkill, &imx_bt_rfkill_data); imx53_add_imx_ssi(1, &smd_ssi_pdata); + imx53_add_spdif(&mxc_spdif_data); + imx53_add_spdif_dai(); + imx53_add_spdif_audio_device(); + /* this call required to release SCC RAM partition held by ROM * during boot, even if SCC2 driver is not part of the image */ diff --git a/arch/arm/mach-mx5/clock.c b/arch/arm/mach-mx5/clock.c index 0a5e1e9a04cf..f57335a3c4d5 100644 --- a/arch/arm/mach-mx5/clock.c +++ b/arch/arm/mach-mx5/clock.c @@ -4470,7 +4470,7 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK(NULL, "emi_intr_clk.0", emi_intr_clk[0]), _REGISTER_CLOCK(NULL, "emi_intr_clk.1", emi_intr_clk[1]), _REGISTER_CLOCK(NULL, "spdif_xtal_clk", spdif_xtal_clk), - _REGISTER_CLOCK("mxc_alsa_spdif.0", NULL, spdif0_clk[0]), + _REGISTER_CLOCK("mxc_spdif.0", NULL, spdif0_clk[0]), _REGISTER_CLOCK("mxc_vpu.0", NULL, vpu_clk[0]), _REGISTER_CLOCK(NULL, "lpsr_clk", lpsr_clk), _REGISTER_CLOCK("mxc_rtc.0", NULL, rtc_clk), @@ -4490,7 +4490,7 @@ static struct clk_lookup lookups[] = { static struct clk_lookup mx51_lookups[] = { _REGISTER_CLOCK("mxc_i2c_hs.3", NULL, hsi2c_serial_clk), _REGISTER_CLOCK("mxc_sim.0", NULL, sim_clk[0]), - _REGISTER_CLOCK("mxc_alsa_spdif.0", NULL, spdif1_clk[0]), + _REGISTER_CLOCK("mxc_spdif.0", NULL, spdif1_clk[0]), _REGISTER_CLOCK(NULL, "mipi_hsp_clk", mipi_hsp_clk), _REGISTER_CLOCK(NULL, "ddr_hf_clk", ddr_hf_clk), _REGISTER_CLOCK("imx51-ecspi.0", NULL, cspi1_clk[0]), diff --git a/arch/arm/mach-mx5/devices-imx51.h b/arch/arm/mach-mx5/devices-imx51.h index e7f9dc2cc847..3f5bfc9e7444 100644 --- a/arch/arm/mach-mx5/devices-imx51.h +++ b/arch/arm/mach-mx5/devices-imx51.h @@ -93,3 +93,11 @@ extern const struct imx_tve_data imx51_tve_data __initconst; #define imx51_add_v4l2_capture(id) \ platform_device_register_resndata(NULL, "mxc_v4l2_capture",\ id, NULL, 0, NULL, 0); + +extern const struct imx_spdif_data imx51_imx_spdif_data __initconst; +#define imx51_add_spdif(pdata) imx_add_spdif(&imx51_imx_spdif_data, pdata) + +extern const struct imx_spdif_dai_data imx51_spdif_dai_data __initconst; +#define imx51_add_spdif_dai() imx_add_spdif_dai(&imx51_spdif_dai_data) + +#define imx51_add_spdif_audio_device(pdata) imx_add_spdif_audio_device() diff --git a/arch/arm/mach-mx5/devices-imx53.h b/arch/arm/mach-mx5/devices-imx53.h index bc781b9dd944..c588546e59ac 100644 --- a/arch/arm/mach-mx5/devices-imx53.h +++ b/arch/arm/mach-mx5/devices-imx53.h @@ -94,3 +94,10 @@ extern const struct imx_mxc_scc2_data imx53_mxc_scc2_data __initconst; #define imx53_add_mxc_scc2() \ imx_add_mxc_scc2(&imx53_mxc_scc2_data) +extern const struct imx_spdif_data imx53_imx_spdif_data __initconst; +#define imx53_add_spdif(pdata) imx_add_spdif(&imx53_imx_spdif_data, pdata) + +extern const struct imx_spdif_dai_data imx53_spdif_dai_data __initconst; +#define imx53_add_spdif_dai() imx_add_spdif_dai(&imx53_spdif_dai_data) + +#define imx53_add_spdif_audio_device(pdata) imx_add_spdif_audio_device() diff --git a/arch/arm/plat-mxc/devices/Kconfig b/arch/arm/plat-mxc/devices/Kconfig index 92d29376248e..9eedc159c025 100644 --- a/arch/arm/plat-mxc/devices/Kconfig +++ b/arch/arm/plat-mxc/devices/Kconfig @@ -109,3 +109,6 @@ config IMX_HAVE_PLATFORM_PERFMON config IMX_HAVE_PLATFORM_LDB bool + +config IMX_HAVE_PLATFORM_IMX_SPDIF + bool diff --git a/arch/arm/plat-mxc/devices/Makefile b/arch/arm/plat-mxc/devices/Makefile index 81f270548df2..6d08cf726608 100644 --- a/arch/arm/plat-mxc/devices/Makefile +++ b/arch/arm/plat-mxc/devices/Makefile @@ -36,4 +36,6 @@ obj-$(CONFIG_IMX_HAVE_PLATFORM_RANDOM_RNGC) += platform-imx-rngb.o obj-$(CONFIG_IMX_HAVE_PLATFORM_PERFMON) += platform-imx-perfmon.o obj-$(CONFIG_IMX_HAVE_PLATFORM_LDB) += platform-imx_ldb.o obj-y += platform-imx-scc2.o - +obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_SPDIF) += platform-imx-spdif.o +obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_SPDIF) += platform-imx-spdif-dai.o +obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_SPDIF) += platform-imx-spdif-audio.o diff --git a/arch/arm/plat-mxc/devices/platform-imx-spdif-audio.c b/arch/arm/plat-mxc/devices/platform-imx-spdif-audio.c new file mode 100644 index 000000000000..4a0cb7bf9a1f --- /dev/null +++ b/arch/arm/plat-mxc/devices/platform-imx-spdif-audio.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * 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. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include + +struct platform_device *__init imx_add_spdif_audio_device(void) +{ + return imx_add_platform_device("imx-spdif-audio-device", 0, + NULL, 0, NULL, 0); +} + diff --git a/arch/arm/plat-mxc/devices/platform-imx-spdif-dai.c b/arch/arm/plat-mxc/devices/platform-imx-spdif-dai.c new file mode 100644 index 000000000000..516ebc52467f --- /dev/null +++ b/arch/arm/plat-mxc/devices/platform-imx-spdif-dai.c @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2010 Pengutronix + * Uwe Kleine-Koenig + * + * Copyright (C) 2011 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. + */ +#include +#include + +#define MXC_SPDIF_TX_REG 0x2C +#define MXC_SPDIF_RX_REG 0x14 + +#define imx_spdif_dai_data_entry(soc) \ + { \ + .iobase = soc ## _SPDIF_BASE_ADDR, \ + .dmatx = soc ## _DMA_REQ_SPDIF_TX, \ + .dmarx = soc ## _DMA_REQ_SPDIF_RX, \ + } + +#ifdef CONFIG_SOC_IMX51 +const struct imx_spdif_dai_data imx51_spdif_dai_data __initconst = { + .iobase = MX51_SPDIF_BASE_ADDR, + .dmatx = MX51_DMA_REQ_SPDIF, + }; +#endif /* ifdef CONFIG_SOC_IMX51 */ + +#ifdef CONFIG_SOC_IMX53 +const struct imx_spdif_dai_data imx53_spdif_dai_data __initconst = + imx_spdif_dai_data_entry(MX53); +#endif /* ifdef CONFIG_SOC_IMX53 */ + +struct platform_device *__init imx_add_spdif_dai( + const struct imx_spdif_dai_data *data) +{ + struct resource res[] = { + { + .name = "tx_reg", + .start = data->iobase + MXC_SPDIF_TX_REG, + .end = data->iobase + MXC_SPDIF_TX_REG, + .flags = IORESOURCE_DMA, + }, { + .name = "rx_reg", + .start = data->iobase + MXC_SPDIF_RX_REG, + .end = data->iobase + MXC_SPDIF_RX_REG, + .flags = IORESOURCE_DMA, + }, { + .name = "tx", + .start = data->dmatx, + .end = data->dmatx, + .flags = IORESOURCE_DMA, + }, { + .name = "rx", + .start = data->dmarx, + .end = data->dmarx, + .flags = IORESOURCE_DMA, + }, + }; + + return imx_add_platform_device("imx-spdif-dai", 0, + res, ARRAY_SIZE(res), NULL, 0); +} diff --git a/arch/arm/plat-mxc/devices/platform-imx-spdif.c b/arch/arm/plat-mxc/devices/platform-imx-spdif.c new file mode 100644 index 000000000000..80a5e782067e --- /dev/null +++ b/arch/arm/plat-mxc/devices/platform-imx-spdif.c @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * 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. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include + +#define imx5_spdif_data_entry_single(soc) \ + { \ + .iobase = soc ## _SPDIF_BASE_ADDR, \ + .irq = soc ## _INT_SPDIF, \ + } + +#ifdef CONFIG_SOC_IMX50 +const struct imx_spdif_data imx50_imx_spdif_data __initconst = + imx5_spdif_data_entry_single(MX53); +#endif /* ifdef CONFIG_SOC_IMX50 */ + +#ifdef CONFIG_SOC_IMX51 +const struct imx_spdif_data imx51_imx_spdif_data __initconst = + imx5_spdif_data_entry_single(MX51); +#endif /* ifdef CONFIG_SOC_IMX51 */ + +#ifdef CONFIG_SOC_IMX53 +const struct imx_spdif_data imx53_imx_spdif_data __initconst = + imx5_spdif_data_entry_single(MX53); +#endif /* ifdef CONFIG_SOC_IMX53 */ + +struct platform_device *__init imx_add_spdif( + const struct imx_spdif_data *data, + const struct mxc_spdif_platform_data *pdata) +{ + struct resource res[] = { + { + .start = data->iobase, + .end = data->iobase + 0x50, + .flags = IORESOURCE_MEM, + }, { + .start = data->irq, + .end = data->irq, + .flags = IORESOURCE_IRQ, + }, + }; + + return imx_add_platform_device("mxc_spdif", 0, + res, ARRAY_SIZE(res), pdata, sizeof(*pdata)); +} + diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h index 1baf909fc98a..86c1d896d353 100644 --- a/arch/arm/plat-mxc/include/mach/devices-common.h +++ b/arch/arm/plat-mxc/include/mach/devices-common.h @@ -401,3 +401,20 @@ struct imx_mxc_scc2_data { struct platform_device *__init imx_add_mxc_scc2( const struct imx_mxc_scc2_data *data); +struct imx_spdif_data { + resource_size_t iobase; + resource_size_t irq; +}; +struct platform_device *__init imx_add_spdif( + const struct imx_spdif_data *data, + const struct mxc_spdif_platform_data *pdata); + +struct imx_spdif_dai_data { + resource_size_t iobase; + resource_size_t dmatx; + resource_size_t dmarx; +}; +struct platform_device *__init imx_add_spdif_dai( + const struct imx_spdif_dai_data *data); + +struct platform_device *__init imx_add_spdif_audio_device(void); diff --git a/arch/arm/plat-mxc/include/mach/dma.h b/arch/arm/plat-mxc/include/mach/dma.h index ef7751546f5f..2d5c7e2eff4b 100644 --- a/arch/arm/plat-mxc/include/mach/dma.h +++ b/arch/arm/plat-mxc/include/mach/dma.h @@ -53,6 +53,13 @@ struct imx_dma_data { int priority; }; +struct imx_pcm_dma_params { + enum sdma_peripheral_type peripheral_type; + int dma; + unsigned long dma_addr; + int burstsize; +}; + static inline int imx_dma_is_ipu(struct dma_chan *chan) { return !strcmp(dev_name(chan->device->dev), "ipu-core"); diff --git a/arch/arm/plat-mxc/include/mach/mx51.h b/arch/arm/plat-mxc/include/mach/mx51.h index a2ee1d90c280..9db86a193ed2 100644 --- a/arch/arm/plat-mxc/include/mach/mx51.h +++ b/arch/arm/plat-mxc/include/mach/mx51.h @@ -358,7 +358,7 @@ #define MX51_MXC_INT_OWIRE 88 #define MX51_MXC_INT_CTI1_TG2 89 #define MX51_MXC_INT_SJC 90 -#define MX51_MXC_INT_SPDIF 91 +#define MX51_INT_SPDIF 91 #define MX51_INT_TVE 92 #define MX51_MXC_INT_FIRI 93 #define MX51_INT_PWM2 94 -- cgit v1.2.3