summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorPhilippe Langlais <philippe.langlais@stericsson.com>2011-10-11 09:28:24 +0200
committerPhilippe Langlais <philippe.langlais@linaro.org>2012-03-19 09:00:46 +0100
commit9d4c4a89237cbe82418eaeabea55a85aee0ca284 (patch)
treefdc3e5eb3cb73e3751ae1d5d891ff37d757ec5d7 /arch
parent28e71d184c3462aa4fd4b763eb72551deafb6226 (diff)
mach-ux500: add msp board file
Signed-off-by: Philippe Langlais <philippe.langlais@stericsson.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-ux500/board-mop500-msp.c225
1 files changed, 225 insertions, 0 deletions
diff --git a/arch/arm/mach-ux500/board-mop500-msp.c b/arch/arm/mach-ux500/board-mop500-msp.c
new file mode 100644
index 00000000000..8867dded7aa
--- /dev/null
+++ b/arch/arm/mach-ux500/board-mop500-msp.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/platform_device.h>
+#include <linux/i2s/i2s.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+
+#include <plat/ste_dma40.h>
+#include <plat/pincfg.h>
+
+#include <mach/devices.h>
+#include <mach/ste-dma40-db8500.h>
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/msp.h>
+
+#include "board-mop500.h"
+#include "devices-db8500.h"
+#include "pins-db8500.h"
+
+/* MSP1/3 Tx/Rx usage protection */
+static DEFINE_SPINLOCK(msp_rxtx_lock);
+
+/* Reference Count */
+static int msp_rxtx_ref;
+
+static pin_cfg_t mop500_msp1_pins[] = {
+ GPIO33_MSP1_TXD | PIN_OUTPUT_LOW,
+ GPIO34_MSP1_TFS | PIN_INPUT_NOPULL,
+ GPIO35_MSP1_TCK | PIN_INPUT_NOPULL,
+ GPIO36_MSP1_RXD | PIN_INPUT_NOPULL,
+};
+
+int msp13_i2s_init(void)
+{
+ int retval = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&msp_rxtx_lock, flags);
+ if (msp_rxtx_ref == 0)
+ retval = nmk_config_pins(
+ ARRAY_AND_SIZE(mop500_msp1_pins));
+ if (!retval)
+ msp_rxtx_ref++;
+ spin_unlock_irqrestore(&msp_rxtx_lock, flags);
+
+ return retval;
+}
+
+int msp13_i2s_exit(void)
+{
+ int retval = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&msp_rxtx_lock, flags);
+ WARN_ON(!msp_rxtx_ref);
+ msp_rxtx_ref--;
+ if (msp_rxtx_ref == 0)
+ retval = nmk_config_pins_sleep(
+ ARRAY_AND_SIZE(mop500_msp1_pins));
+ spin_unlock_irqrestore(&msp_rxtx_lock, flags);
+
+ return retval;
+}
+
+static struct stedma40_chan_cfg msp0_dma_rx = {
+ .high_priority = true,
+ .dir = STEDMA40_PERIPH_TO_MEM,
+
+ .src_dev_type = DB8500_DMA_DEV31_MSP0_RX_SLIM0_CH0_RX,
+ .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+
+ .src_info.psize = STEDMA40_PSIZE_LOG_4,
+ .dst_info.psize = STEDMA40_PSIZE_LOG_4,
+
+ /* data_width is set during configuration */
+};
+
+static struct stedma40_chan_cfg msp0_dma_tx = {
+ .high_priority = true,
+ .dir = STEDMA40_MEM_TO_PERIPH,
+
+ .src_dev_type = STEDMA40_DEV_DST_MEMORY,
+ .dst_dev_type = DB8500_DMA_DEV31_MSP0_TX_SLIM0_CH0_TX,
+
+ .src_info.psize = STEDMA40_PSIZE_LOG_4,
+ .dst_info.psize = STEDMA40_PSIZE_LOG_4,
+
+ /* data_width is set during configuration */
+};
+
+static struct msp_i2s_platform_data msp0_platform_data = {
+ .id = MSP_0_I2S_CONTROLLER,
+ .msp_i2s_dma_rx = &msp0_dma_rx,
+ .msp_i2s_dma_tx = &msp0_dma_tx,
+};
+
+static struct stedma40_chan_cfg msp1_dma_rx = {
+ .high_priority = true,
+ .dir = STEDMA40_PERIPH_TO_MEM,
+
+ .src_dev_type = DB8500_DMA_DEV30_MSP1_RX, /* v2: MSP3 RX */
+ .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+
+ .src_info.psize = STEDMA40_PSIZE_LOG_4,
+ .dst_info.psize = STEDMA40_PSIZE_LOG_4,
+
+ /* data_width is set during configuration */
+};
+
+static struct stedma40_chan_cfg msp1_dma_tx = {
+ .high_priority = true,
+ .dir = STEDMA40_MEM_TO_PERIPH,
+
+ .src_dev_type = STEDMA40_DEV_DST_MEMORY,
+ .dst_dev_type = DB8500_DMA_DEV30_MSP1_TX,
+
+ .src_info.psize = STEDMA40_PSIZE_LOG_4,
+ .dst_info.psize = STEDMA40_PSIZE_LOG_4,
+
+ /* data_width is set during configuration */
+};
+
+static struct msp_i2s_platform_data msp1_platform_data = {
+ .id = MSP_1_I2S_CONTROLLER,
+ .msp_i2s_dma_rx = &msp1_dma_rx,
+ .msp_i2s_dma_tx = &msp1_dma_tx,
+ .msp_i2s_init = msp13_i2s_init,
+ .msp_i2s_exit = msp13_i2s_exit,
+};
+
+static struct stedma40_chan_cfg msp2_dma_rx = {
+ .high_priority = true,
+ .dir = STEDMA40_PERIPH_TO_MEM,
+
+ .src_dev_type = DB8500_DMA_DEV14_MSP2_RX,
+ .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+
+ .src_info.psize = STEDMA40_PSIZE_LOG_4,
+ .dst_info.psize = STEDMA40_PSIZE_LOG_4,
+
+ /* data_width is set during configuration */
+};
+
+static struct stedma40_chan_cfg msp2_dma_tx = {
+ .high_priority = true,
+ .dir = STEDMA40_MEM_TO_PERIPH,
+
+ .src_dev_type = STEDMA40_DEV_DST_MEMORY,
+ .dst_dev_type = DB8500_DMA_DEV14_MSP2_TX,
+
+ .src_info.psize = STEDMA40_PSIZE_LOG_4,
+ .dst_info.psize = STEDMA40_PSIZE_LOG_4,
+
+ /* data_width is set during configuration */
+};
+
+static struct msp_i2s_platform_data msp2_platform_data = {
+ .id = MSP_2_I2S_CONTROLLER,
+ .msp_i2s_dma_rx = &msp2_dma_rx,
+ .msp_i2s_dma_tx = &msp2_dma_tx,
+};
+
+static struct msp_i2s_platform_data msp3_platform_data = {
+ .id = MSP_3_I2S_CONTROLLER,
+ .msp_i2s_dma_rx = &msp1_dma_rx,
+ .msp_i2s_dma_tx = NULL,
+ .msp_i2s_init = msp13_i2s_init,
+ .msp_i2s_exit = msp13_i2s_exit,
+};
+
+static struct i2s_board_info stm_i2s_board_info[] __initdata = {
+ {
+ .modalias = "i2s_device.0",
+ .id = 0,
+ .chip_select = 0,
+ },
+ {
+ .modalias = "i2s_device.1",
+ .id = 1,
+ .chip_select = 1,
+ },
+ {
+ .modalias = "i2s_device.2",
+ .id = 2,
+ .chip_select = 2,
+ },
+ {
+ .modalias = "i2s_device.3",
+ .id = 3,
+ .chip_select = 3,
+ },
+};
+
+static void __init mop500_msp_fixup(void)
+{
+ if (cpu_is_u8500ed() || cpu_is_u8500v1())
+ return;
+
+ /* DMA Rx is moved to MSP3 on DB8500v2 */
+ msp1_platform_data.msp_i2s_dma_rx = NULL;
+
+ /* MSP2 DMA doesn't work with PSIZE == 4 on DB8500v2 */
+ msp2_dma_rx.src_info.psize = STEDMA40_PSIZE_LOG_1;
+ msp2_dma_rx.dst_info.psize = STEDMA40_PSIZE_LOG_1;
+}
+
+void __init mop500_msp_init(void)
+{
+ mop500_msp_fixup();
+
+ db8500_add_msp0_i2s(&msp0_platform_data);
+ db8500_add_msp1_i2s(&msp1_platform_data);
+ db8500_add_msp2_i2s(&msp2_platform_data);
+
+ if (cpu_is_u8500v2())
+ db8500_add_msp3_i2s(&msp3_platform_data);
+
+ i2s_register_board_info(stm_i2s_board_info,
+ ARRAY_SIZE(stm_i2s_board_info));
+}