aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-mxc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-mxc')
-rw-r--r--arch/arm/plat-mxc/Makefile4
-rw-r--r--arch/arm/plat-mxc/audmux-v2.c137
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx31lite.h2
-rw-r--r--arch/arm/plat-mxc/include/mach/common.h2
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx35.h2
-rw-r--r--arch/arm/plat-mxc/include/mach/irqs.h5
-rw-r--r--arch/arm/plat-mxc/ssi-fiq-ksym.c20
-rw-r--r--arch/arm/plat-mxc/ssi-fiq.S134
8 files changed, 303 insertions, 3 deletions
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
index 996cbac6932c..6cee38df58b2 100644
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -13,3 +13,7 @@ obj-$(CONFIG_USB_EHCI_MXC) += ehci.o
13obj-$(CONFIG_MXC_ULPI) += ulpi.o 13obj-$(CONFIG_MXC_ULPI) += ulpi.o
14obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o 14obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o
15obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o 15obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o
16ifdef CONFIG_SND_IMX_SOC
17obj-y += ssi-fiq.o
18obj-y += ssi-fiq-ksym.o
19endif
diff --git a/arch/arm/plat-mxc/audmux-v2.c b/arch/arm/plat-mxc/audmux-v2.c
index 6f21096086fd..b06954a84436 100644
--- a/arch/arm/plat-mxc/audmux-v2.c
+++ b/arch/arm/plat-mxc/audmux-v2.c
@@ -23,6 +23,7 @@
23#include <linux/err.h> 23#include <linux/err.h>
24#include <linux/io.h> 24#include <linux/io.h>
25#include <linux/clk.h> 25#include <linux/clk.h>
26#include <linux/debugfs.h>
26#include <mach/audmux.h> 27#include <mach/audmux.h>
27#include <mach/hardware.h> 28#include <mach/hardware.h>
28 29
@@ -32,6 +33,140 @@ static void __iomem *audmux_base;
32#define MXC_AUDMUX_V2_PTCR(x) ((x) * 8) 33#define MXC_AUDMUX_V2_PTCR(x) ((x) * 8)
33#define MXC_AUDMUX_V2_PDCR(x) ((x) * 8 + 4) 34#define MXC_AUDMUX_V2_PDCR(x) ((x) * 8 + 4)
34 35
36#ifdef CONFIG_DEBUG_FS
37static struct dentry *audmux_debugfs_root;
38
39static int audmux_open_file(struct inode *inode, struct file *file)
40{
41 file->private_data = inode->i_private;
42 return 0;
43}
44
45/* There is an annoying discontinuity in the SSI numbering with regard
46 * to the Linux number of the devices */
47static const char *audmux_port_string(int port)
48{
49 switch (port) {
50 case MX31_AUDMUX_PORT1_SSI0:
51 return "imx-ssi.0";
52 case MX31_AUDMUX_PORT2_SSI1:
53 return "imx-ssi.1";
54 case MX31_AUDMUX_PORT3_SSI_PINS_3:
55 return "SSI3";
56 case MX31_AUDMUX_PORT4_SSI_PINS_4:
57 return "SSI4";
58 case MX31_AUDMUX_PORT5_SSI_PINS_5:
59 return "SSI5";
60 case MX31_AUDMUX_PORT6_SSI_PINS_6:
61 return "SSI6";
62 default:
63 return "UNKNOWN";
64 }
65}
66
67static ssize_t audmux_read_file(struct file *file, char __user *user_buf,
68 size_t count, loff_t *ppos)
69{
70 ssize_t ret;
71 char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
72 int port = (int)file->private_data;
73 u32 pdcr, ptcr;
74
75 if (!buf)
76 return -ENOMEM;
77
78 if (audmux_clk)
79 clk_enable(audmux_clk);
80
81 ptcr = readl(audmux_base + MXC_AUDMUX_V2_PTCR(port));
82 pdcr = readl(audmux_base + MXC_AUDMUX_V2_PDCR(port));
83
84 if (audmux_clk)
85 clk_disable(audmux_clk);
86
87 ret = snprintf(buf, PAGE_SIZE, "PDCR: %08x\nPTCR: %08x\n",
88 pdcr, ptcr);
89
90 if (ptcr & MXC_AUDMUX_V2_PTCR_TFSDIR)
91 ret += snprintf(buf + ret, PAGE_SIZE - ret,
92 "TxFS output from %s, ",
93 audmux_port_string((ptcr >> 27) & 0x7));
94 else
95 ret += snprintf(buf + ret, PAGE_SIZE - ret,
96 "TxFS input, ");
97
98 if (ptcr & MXC_AUDMUX_V2_PTCR_TCLKDIR)
99 ret += snprintf(buf + ret, PAGE_SIZE - ret,
100 "TxClk output from %s",
101 audmux_port_string((ptcr >> 22) & 0x7));
102 else
103 ret += snprintf(buf + ret, PAGE_SIZE - ret,
104 "TxClk input");
105
106 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
107
108 if (ptcr & MXC_AUDMUX_V2_PTCR_SYN) {
109 ret += snprintf(buf + ret, PAGE_SIZE - ret,
110 "Port is symmetric");
111 } else {
112 if (ptcr & MXC_AUDMUX_V2_PTCR_RFSDIR)
113 ret += snprintf(buf + ret, PAGE_SIZE - ret,
114 "RxFS output from %s, ",
115 audmux_port_string((ptcr >> 17) & 0x7));
116 else
117 ret += snprintf(buf + ret, PAGE_SIZE - ret,
118 "RxFS input, ");
119
120 if (ptcr & MXC_AUDMUX_V2_PTCR_RCLKDIR)
121 ret += snprintf(buf + ret, PAGE_SIZE - ret,
122 "RxClk output from %s",
123 audmux_port_string((ptcr >> 12) & 0x7));
124 else
125 ret += snprintf(buf + ret, PAGE_SIZE - ret,
126 "RxClk input");
127 }
128
129 ret += snprintf(buf + ret, PAGE_SIZE - ret,
130 "\nData received from %s\n",
131 audmux_port_string((pdcr >> 13) & 0x7));
132
133 ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
134
135 kfree(buf);
136
137 return ret;
138}
139
140static const struct file_operations audmux_debugfs_fops = {
141 .open = audmux_open_file,
142 .read = audmux_read_file,
143};
144
145static void audmux_debugfs_init(void)
146{
147 int i;
148 char buf[20];
149
150 audmux_debugfs_root = debugfs_create_dir("audmux", NULL);
151 if (!audmux_debugfs_root) {
152 pr_warning("Failed to create AUDMUX debugfs root\n");
153 return;
154 }
155
156 for (i = 1; i < 8; i++) {
157 snprintf(buf, sizeof(buf), "ssi%d", i);
158 if (!debugfs_create_file(buf, 0444, audmux_debugfs_root,
159 (void *)i, &audmux_debugfs_fops))
160 pr_warning("Failed to create AUDMUX port %d debugfs file\n",
161 i);
162 }
163}
164#else
165static inline void audmux_debugfs_init(void)
166{
167}
168#endif
169
35int mxc_audmux_v2_configure_port(unsigned int port, unsigned int ptcr, 170int mxc_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
36 unsigned int pdcr) 171 unsigned int pdcr)
37{ 172{
@@ -68,6 +203,8 @@ static int mxc_audmux_v2_init(void)
68 if (cpu_is_mx31() || cpu_is_mx35()) 203 if (cpu_is_mx31() || cpu_is_mx35())
69 audmux_base = IO_ADDRESS(AUDMUX_BASE_ADDR); 204 audmux_base = IO_ADDRESS(AUDMUX_BASE_ADDR);
70 205
206 audmux_debugfs_init();
207
71 return 0; 208 return 0;
72} 209}
73 210
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31lite.h b/arch/arm/plat-mxc/include/mach/board-mx31lite.h
index 0184b638c268..2b2da0367578 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx31lite.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx31lite.h
@@ -25,7 +25,7 @@
25 25
26#ifndef __ASSEMBLY__ 26#ifndef __ASSEMBLY__
27 27
28enum mx31lilly_boards { 28enum mx31lite_boards {
29 MX31LITE_NOBOARD = 0, 29 MX31LITE_NOBOARD = 0,
30 MX31LITE_DB = 1, 30 MX31LITE_DB = 1,
31}; 31};
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index 286cb9b0a25b..4bf1068ffad9 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -32,7 +32,7 @@ extern void mxc91231_init_irq(void);
32extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int); 32extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int);
33extern int mx1_clocks_init(unsigned long fref); 33extern int mx1_clocks_init(unsigned long fref);
34extern int mx21_clocks_init(unsigned long lref, unsigned long fref); 34extern int mx21_clocks_init(unsigned long lref, unsigned long fref);
35extern int mx25_clocks_init(unsigned long fref); 35extern int mx25_clocks_init(void);
36extern int mx27_clocks_init(unsigned long fref); 36extern int mx27_clocks_init(unsigned long fref);
37extern int mx31_clocks_init(unsigned long fref); 37extern int mx31_clocks_init(unsigned long fref);
38extern int mx35_clocks_init(void); 38extern int mx35_clocks_init(void);
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx35.h b/arch/arm/plat-mxc/include/mach/iomux-mx35.h
index 00b0ac1db225..c88d40795f7a 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx35.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx35.h
@@ -671,7 +671,7 @@
671#define MX35_PAD_LD8__SDMA_SDMA_DEBUG_PC_8 IOMUX_PAD(0x634, 0x1d0, 6, 0x0, 0, NO_PAD_CTRL) 671#define MX35_PAD_LD8__SDMA_SDMA_DEBUG_PC_8 IOMUX_PAD(0x634, 0x1d0, 6, 0x0, 0, NO_PAD_CTRL)
672 672
673#define MX35_PAD_LD9__IPU_DISPB_DAT_9 IOMUX_PAD(0x638, 0x1d4, 0, 0x0, 0, NO_PAD_CTRL) 673#define MX35_PAD_LD9__IPU_DISPB_DAT_9 IOMUX_PAD(0x638, 0x1d4, 0, 0x0, 0, NO_PAD_CTRL)
674#define MX35_PAD_LD9__GPIO2_9 IOMUX_PAD(0x638, 0x1d4, 5, 0x8e4 0, NO_PAD_CTRL) 674#define MX35_PAD_LD9__GPIO2_9 IOMUX_PAD(0x638, 0x1d4, 5, 0x8e4, 0, NO_PAD_CTRL)
675#define MX35_PAD_LD9__SDMA_SDMA_DEBUG_PC_9 IOMUX_PAD(0x638, 0x1d4, 6, 0x0, 0, NO_PAD_CTRL) 675#define MX35_PAD_LD9__SDMA_SDMA_DEBUG_PC_9 IOMUX_PAD(0x638, 0x1d4, 6, 0x0, 0, NO_PAD_CTRL)
676 676
677#define MX35_PAD_LD10__IPU_DISPB_DAT_10 IOMUX_PAD(0x63c, 0x1d8, 0, 0x0, 0, NO_PAD_CTRL) 677#define MX35_PAD_LD10__IPU_DISPB_DAT_10 IOMUX_PAD(0x63c, 0x1d8, 0, 0x0, 0, NO_PAD_CTRL)
diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h
index ead9d592168d..0cb347645db4 100644
--- a/arch/arm/plat-mxc/include/mach/irqs.h
+++ b/arch/arm/plat-mxc/include/mach/irqs.h
@@ -37,7 +37,12 @@
37 * within sensible limits. 37 * within sensible limits.
38 */ 38 */
39#define MXC_BOARD_IRQ_START (MXC_INTERNAL_IRQS + MXC_GPIO_IRQS) 39#define MXC_BOARD_IRQ_START (MXC_INTERNAL_IRQS + MXC_GPIO_IRQS)
40
41#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
42#define MXC_BOARD_IRQS 80
43#else
40#define MXC_BOARD_IRQS 16 44#define MXC_BOARD_IRQS 16
45#endif
41 46
42#define MXC_IPU_IRQ_START (MXC_BOARD_IRQ_START + MXC_BOARD_IRQS) 47#define MXC_IPU_IRQ_START (MXC_BOARD_IRQ_START + MXC_BOARD_IRQS)
43 48
diff --git a/arch/arm/plat-mxc/ssi-fiq-ksym.c b/arch/arm/plat-mxc/ssi-fiq-ksym.c
new file mode 100644
index 000000000000..b5fad454da78
--- /dev/null
+++ b/arch/arm/plat-mxc/ssi-fiq-ksym.c
@@ -0,0 +1,20 @@
1/*
2 * Exported ksyms for the SSI FIQ handler
3 *
4 * Copyright (C) 2009, Sascha Hauer <s.hauer@pengutronix.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/module.h>
12
13#include <mach/ssi.h>
14
15EXPORT_SYMBOL(imx_ssi_fiq_tx_buffer);
16EXPORT_SYMBOL(imx_ssi_fiq_rx_buffer);
17EXPORT_SYMBOL(imx_ssi_fiq_start);
18EXPORT_SYMBOL(imx_ssi_fiq_end);
19EXPORT_SYMBOL(imx_ssi_fiq_base);
20
diff --git a/arch/arm/plat-mxc/ssi-fiq.S b/arch/arm/plat-mxc/ssi-fiq.S
new file mode 100644
index 000000000000..4ddce565b353
--- /dev/null
+++ b/arch/arm/plat-mxc/ssi-fiq.S
@@ -0,0 +1,134 @@
1/*
2 * Copyright (C) 2009 Sascha Hauer <s.hauer@pengutronix.de>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/linkage.h>
10#include <asm/assembler.h>
11
12/*
13 * r8 = bit 0-15: tx offset, bit 16-31: tx buffer size
14 * r9 = bit 0-15: rx offset, bit 16-31: rx buffer size
15 */
16
17#define SSI_STX0 0x00
18#define SSI_SRX0 0x08
19#define SSI_SISR 0x14
20#define SSI_SIER 0x18
21#define SSI_SACNT 0x38
22
23#define SSI_SACNT_AC97EN (1 << 0)
24
25#define SSI_SIER_TFE0_EN (1 << 0)
26#define SSI_SISR_TFE0 (1 << 0)
27#define SSI_SISR_RFF0 (1 << 2)
28#define SSI_SIER_RFF0_EN (1 << 2)
29
30 .text
31 .global imx_ssi_fiq_start
32 .global imx_ssi_fiq_end
33 .global imx_ssi_fiq_base
34 .global imx_ssi_fiq_rx_buffer
35 .global imx_ssi_fiq_tx_buffer
36
37imx_ssi_fiq_start:
38 ldr r12, imx_ssi_fiq_base
39
40 /* TX */
41 ldr r11, imx_ssi_fiq_tx_buffer
42
43 /* shall we send? */
44 ldr r13, [r12, #SSI_SIER]
45 tst r13, #SSI_SIER_TFE0_EN
46 beq 1f
47
48 /* TX FIFO empty? */
49 ldr r13, [r12, #SSI_SISR]
50 tst r13, #SSI_SISR_TFE0
51 beq 1f
52
53 mov r10, #0x10000
54 sub r10, #1
55 and r10, r10, r8 /* r10: current buffer offset */
56
57 add r11, r11, r10
58
59 ldrh r13, [r11]
60 strh r13, [r12, #SSI_STX0]
61
62 ldrh r13, [r11, #2]
63 strh r13, [r12, #SSI_STX0]
64
65 ldrh r13, [r11, #4]
66 strh r13, [r12, #SSI_STX0]
67
68 ldrh r13, [r11, #6]
69 strh r13, [r12, #SSI_STX0]
70
71 add r10, #8
72 lsr r13, r8, #16 /* r13: buffer size */
73 cmp r10, r13
74 lslgt r8, r13, #16
75 addle r8, #8
761:
77 /* RX */
78
79 /* shall we receive? */
80 ldr r13, [r12, #SSI_SIER]
81 tst r13, #SSI_SIER_RFF0_EN
82 beq 1f
83
84 /* RX FIFO full? */
85 ldr r13, [r12, #SSI_SISR]
86 tst r13, #SSI_SISR_RFF0
87 beq 1f
88
89 ldr r11, imx_ssi_fiq_rx_buffer
90
91 mov r10, #0x10000
92 sub r10, #1
93 and r10, r10, r9 /* r10: current buffer offset */
94
95 add r11, r11, r10
96
97 ldr r13, [r12, #SSI_SACNT]
98 tst r13, #SSI_SACNT_AC97EN
99
100 ldr r13, [r12, #SSI_SRX0]
101 strh r13, [r11]
102
103 ldr r13, [r12, #SSI_SRX0]
104 strh r13, [r11, #2]
105
106 /* dummy read to skip slot 12 */
107 ldrne r13, [r12, #SSI_SRX0]
108
109 ldr r13, [r12, #SSI_SRX0]
110 strh r13, [r11, #4]
111
112 ldr r13, [r12, #SSI_SRX0]
113 strh r13, [r11, #6]
114
115 /* dummy read to skip slot 12 */
116 ldrne r13, [r12, #SSI_SRX0]
117
118 add r10, #8
119 lsr r13, r9, #16 /* r13: buffer size */
120 cmp r10, r13
121 lslgt r9, r13, #16
122 addle r9, #8
123
1241:
125 @ return from FIQ
126 subs pc, lr, #4
127imx_ssi_fiq_base:
128 .word 0x0
129imx_ssi_fiq_rx_buffer:
130 .word 0x0
131imx_ssi_fiq_tx_buffer:
132 .word 0x0
133imx_ssi_fiq_end:
134