OMAP: McBSP: implement McBSP CLKR and FSR signal muxing via mach-omap2/mcbsp.c
[pandora-kernel.git] / arch / arm / mach-omap2 / mcbsp.c
1 /*
2  * linux/arch/arm/mach-omap2/mcbsp.c
3  *
4  * Copyright (C) 2008 Instituto Nokia de Tecnologia
5  * Contact: Eduardo Valentin <eduardo.valentin@indt.org.br>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  *
11  * Multichannel mode not supported.
12  */
13 #include <linux/module.h>
14 #include <linux/init.h>
15 #include <linux/clk.h>
16 #include <linux/err.h>
17 #include <linux/io.h>
18 #include <linux/platform_device.h>
19 #include <linux/slab.h>
20
21 #include <mach/irqs.h>
22 #include <plat/dma.h>
23 #include <plat/cpu.h>
24 #include <plat/mcbsp.h>
25 #include <plat/control.h>
26
27 /* McBSP internal signal muxing functions */
28
29 void omap2_mcbsp1_mux_clkr_src(u8 mux)
30 {
31         u32 v;
32
33         v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
34         if (mux == CLKR_SRC_CLKR)
35                 v &= OMAP2_MCBSP1_CLKR_MASK;
36         else if (mux == CLKR_SRC_CLKX)
37                 v |= OMAP2_MCBSP1_CLKR_MASK;
38         omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
39 }
40 EXPORT_SYMBOL(omap2_mcbsp1_mux_clkr_src);
41
42 void omap2_mcbsp1_mux_fsr_src(u8 mux)
43 {
44         u32 v;
45
46         v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
47         if (mux == FSR_SRC_FSR)
48                 v &= OMAP2_MCBSP1_FSR_MASK;
49         else if (mux == FSR_SRC_FSX)
50                 v |= OMAP2_MCBSP1_FSR_MASK;
51         omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
52 }
53 EXPORT_SYMBOL(omap2_mcbsp1_mux_fsr_src);
54
55 /* Platform data */
56
57 #ifdef CONFIG_ARCH_OMAP2420
58 static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = {
59         {
60                 .phys_base      = OMAP24XX_MCBSP1_BASE,
61                 .dma_rx_sync    = OMAP24XX_DMA_MCBSP1_RX,
62                 .dma_tx_sync    = OMAP24XX_DMA_MCBSP1_TX,
63                 .rx_irq         = INT_24XX_MCBSP1_IRQ_RX,
64                 .tx_irq         = INT_24XX_MCBSP1_IRQ_TX,
65         },
66         {
67                 .phys_base      = OMAP24XX_MCBSP2_BASE,
68                 .dma_rx_sync    = OMAP24XX_DMA_MCBSP2_RX,
69                 .dma_tx_sync    = OMAP24XX_DMA_MCBSP2_TX,
70                 .rx_irq         = INT_24XX_MCBSP2_IRQ_RX,
71                 .tx_irq         = INT_24XX_MCBSP2_IRQ_TX,
72         },
73 };
74 #define OMAP2420_MCBSP_PDATA_SZ         ARRAY_SIZE(omap2420_mcbsp_pdata)
75 #define OMAP2420_MCBSP_REG_NUM          (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
76 #else
77 #define omap2420_mcbsp_pdata            NULL
78 #define OMAP2420_MCBSP_PDATA_SZ         0
79 #define OMAP2420_MCBSP_REG_NUM          0
80 #endif
81
82 #ifdef CONFIG_ARCH_OMAP2430
83 static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
84         {
85                 .phys_base      = OMAP24XX_MCBSP1_BASE,
86                 .dma_rx_sync    = OMAP24XX_DMA_MCBSP1_RX,
87                 .dma_tx_sync    = OMAP24XX_DMA_MCBSP1_TX,
88                 .rx_irq         = INT_24XX_MCBSP1_IRQ_RX,
89                 .tx_irq         = INT_24XX_MCBSP1_IRQ_TX,
90         },
91         {
92                 .phys_base      = OMAP24XX_MCBSP2_BASE,
93                 .dma_rx_sync    = OMAP24XX_DMA_MCBSP2_RX,
94                 .dma_tx_sync    = OMAP24XX_DMA_MCBSP2_TX,
95                 .rx_irq         = INT_24XX_MCBSP2_IRQ_RX,
96                 .tx_irq         = INT_24XX_MCBSP2_IRQ_TX,
97         },
98         {
99                 .phys_base      = OMAP2430_MCBSP3_BASE,
100                 .dma_rx_sync    = OMAP24XX_DMA_MCBSP3_RX,
101                 .dma_tx_sync    = OMAP24XX_DMA_MCBSP3_TX,
102                 .rx_irq         = INT_24XX_MCBSP3_IRQ_RX,
103                 .tx_irq         = INT_24XX_MCBSP3_IRQ_TX,
104         },
105         {
106                 .phys_base      = OMAP2430_MCBSP4_BASE,
107                 .dma_rx_sync    = OMAP24XX_DMA_MCBSP4_RX,
108                 .dma_tx_sync    = OMAP24XX_DMA_MCBSP4_TX,
109                 .rx_irq         = INT_24XX_MCBSP4_IRQ_RX,
110                 .tx_irq         = INT_24XX_MCBSP4_IRQ_TX,
111         },
112         {
113                 .phys_base      = OMAP2430_MCBSP5_BASE,
114                 .dma_rx_sync    = OMAP24XX_DMA_MCBSP5_RX,
115                 .dma_tx_sync    = OMAP24XX_DMA_MCBSP5_TX,
116                 .rx_irq         = INT_24XX_MCBSP5_IRQ_RX,
117                 .tx_irq         = INT_24XX_MCBSP5_IRQ_TX,
118         },
119 };
120 #define OMAP2430_MCBSP_PDATA_SZ         ARRAY_SIZE(omap2430_mcbsp_pdata)
121 #define OMAP2430_MCBSP_REG_NUM          (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
122 #else
123 #define omap2430_mcbsp_pdata            NULL
124 #define OMAP2430_MCBSP_PDATA_SZ         0
125 #define OMAP2430_MCBSP_REG_NUM          0
126 #endif
127
128 #ifdef CONFIG_ARCH_OMAP3
129 static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
130         {
131                 .phys_base      = OMAP34XX_MCBSP1_BASE,
132                 .dma_rx_sync    = OMAP24XX_DMA_MCBSP1_RX,
133                 .dma_tx_sync    = OMAP24XX_DMA_MCBSP1_TX,
134                 .rx_irq         = INT_24XX_MCBSP1_IRQ_RX,
135                 .tx_irq         = INT_24XX_MCBSP1_IRQ_TX,
136                 .buffer_size    = 0x80, /* The FIFO has 128 locations */
137         },
138         {
139                 .phys_base      = OMAP34XX_MCBSP2_BASE,
140                 .phys_base_st   = OMAP34XX_MCBSP2_ST_BASE,
141                 .dma_rx_sync    = OMAP24XX_DMA_MCBSP2_RX,
142                 .dma_tx_sync    = OMAP24XX_DMA_MCBSP2_TX,
143                 .rx_irq         = INT_24XX_MCBSP2_IRQ_RX,
144                 .tx_irq         = INT_24XX_MCBSP2_IRQ_TX,
145                 .buffer_size    = 0x500, /* The FIFO has 1024 + 256 locations */
146         },
147         {
148                 .phys_base      = OMAP34XX_MCBSP3_BASE,
149                 .phys_base_st   = OMAP34XX_MCBSP3_ST_BASE,
150                 .dma_rx_sync    = OMAP24XX_DMA_MCBSP3_RX,
151                 .dma_tx_sync    = OMAP24XX_DMA_MCBSP3_TX,
152                 .rx_irq         = INT_24XX_MCBSP3_IRQ_RX,
153                 .tx_irq         = INT_24XX_MCBSP3_IRQ_TX,
154                 .buffer_size    = 0x80, /* The FIFO has 128 locations */
155         },
156         {
157                 .phys_base      = OMAP34XX_MCBSP4_BASE,
158                 .dma_rx_sync    = OMAP24XX_DMA_MCBSP4_RX,
159                 .dma_tx_sync    = OMAP24XX_DMA_MCBSP4_TX,
160                 .rx_irq         = INT_24XX_MCBSP4_IRQ_RX,
161                 .tx_irq         = INT_24XX_MCBSP4_IRQ_TX,
162                 .buffer_size    = 0x80, /* The FIFO has 128 locations */
163         },
164         {
165                 .phys_base      = OMAP34XX_MCBSP5_BASE,
166                 .dma_rx_sync    = OMAP24XX_DMA_MCBSP5_RX,
167                 .dma_tx_sync    = OMAP24XX_DMA_MCBSP5_TX,
168                 .rx_irq         = INT_24XX_MCBSP5_IRQ_RX,
169                 .tx_irq         = INT_24XX_MCBSP5_IRQ_TX,
170                 .buffer_size    = 0x80, /* The FIFO has 128 locations */
171         },
172 };
173 #define OMAP34XX_MCBSP_PDATA_SZ         ARRAY_SIZE(omap34xx_mcbsp_pdata)
174 #define OMAP34XX_MCBSP_REG_NUM          (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
175 #else
176 #define omap34xx_mcbsp_pdata            NULL
177 #define OMAP34XX_MCBSP_PDATA_SZ         0
178 #define OMAP34XX_MCBSP_REG_NUM          0
179 #endif
180
181 static struct omap_mcbsp_platform_data omap44xx_mcbsp_pdata[] = {
182         {
183                 .phys_base      = OMAP44XX_MCBSP1_BASE,
184                 .dma_rx_sync    = OMAP44XX_DMA_MCBSP1_RX,
185                 .dma_tx_sync    = OMAP44XX_DMA_MCBSP1_TX,
186                 .tx_irq         = OMAP44XX_IRQ_MCBSP1,
187         },
188         {
189                 .phys_base      = OMAP44XX_MCBSP2_BASE,
190                 .dma_rx_sync    = OMAP44XX_DMA_MCBSP2_RX,
191                 .dma_tx_sync    = OMAP44XX_DMA_MCBSP2_TX,
192                 .tx_irq         = OMAP44XX_IRQ_MCBSP2,
193         },
194         {
195                 .phys_base      = OMAP44XX_MCBSP3_BASE,
196                 .dma_rx_sync    = OMAP44XX_DMA_MCBSP3_RX,
197                 .dma_tx_sync    = OMAP44XX_DMA_MCBSP3_TX,
198                 .tx_irq         = OMAP44XX_IRQ_MCBSP3,
199         },
200         {
201                 .phys_base      = OMAP44XX_MCBSP4_BASE,
202                 .dma_rx_sync    = OMAP44XX_DMA_MCBSP4_RX,
203                 .dma_tx_sync    = OMAP44XX_DMA_MCBSP4_TX,
204                 .tx_irq         = OMAP44XX_IRQ_MCBSP4,
205         },
206 };
207 #define OMAP44XX_MCBSP_PDATA_SZ         ARRAY_SIZE(omap44xx_mcbsp_pdata)
208 #define OMAP44XX_MCBSP_REG_NUM          (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
209
210 static int __init omap2_mcbsp_init(void)
211 {
212         if (cpu_is_omap2420()) {
213                 omap_mcbsp_count = OMAP2420_MCBSP_PDATA_SZ;
214                 omap_mcbsp_cache_size = OMAP2420_MCBSP_REG_NUM * sizeof(u16);
215         } else if (cpu_is_omap2430()) {
216                 omap_mcbsp_count = OMAP2430_MCBSP_PDATA_SZ;
217                 omap_mcbsp_cache_size = OMAP2430_MCBSP_REG_NUM * sizeof(u32);
218         } else if (cpu_is_omap34xx()) {
219                 omap_mcbsp_count = OMAP34XX_MCBSP_PDATA_SZ;
220                 omap_mcbsp_cache_size = OMAP34XX_MCBSP_REG_NUM * sizeof(u32);
221         } else if (cpu_is_omap44xx()) {
222                 omap_mcbsp_count = OMAP44XX_MCBSP_PDATA_SZ;
223                 omap_mcbsp_cache_size = OMAP44XX_MCBSP_REG_NUM * sizeof(u32);
224         }
225
226         mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *),
227                                                                 GFP_KERNEL);
228         if (!mcbsp_ptr)
229                 return -ENOMEM;
230
231         if (cpu_is_omap2420())
232                 omap_mcbsp_register_board_cfg(omap2420_mcbsp_pdata,
233                                                 OMAP2420_MCBSP_PDATA_SZ);
234         if (cpu_is_omap2430())
235                 omap_mcbsp_register_board_cfg(omap2430_mcbsp_pdata,
236                                                 OMAP2430_MCBSP_PDATA_SZ);
237         if (cpu_is_omap34xx())
238                 omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata,
239                                                 OMAP34XX_MCBSP_PDATA_SZ);
240         if (cpu_is_omap44xx())
241                 omap_mcbsp_register_board_cfg(omap44xx_mcbsp_pdata,
242                                                 OMAP44XX_MCBSP_PDATA_SZ);
243
244         return omap_mcbsp_init();
245 }
246 arch_initcall(omap2_mcbsp_init);