xref: /linux/arch/arm/mach-omap2/mcbsp.c (revision cc4589ebfae6f8dbb5cf880a0a67eedab3416492)
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 
26 #include "mux.h"
27 
28 static void omap2_mcbsp2_mux_setup(void)
29 {
30 	omap_mux_init_signal("eac_ac_sclk.mcbsp2_clkx", OMAP_PULL_ENA);
31 	omap_mux_init_signal("eac_ac_fs.mcbsp2_fsx", OMAP_PULL_ENA);
32 	omap_mux_init_signal("eac_ac_din.mcbsp2_dr", OMAP_PULL_ENA);
33 	omap_mux_init_signal("eac_ac_dout.mcbsp2_dx", OMAP_PULL_ENA);
34 	omap_mux_init_gpio(117, OMAP_PULL_ENA);
35 	/*
36 	 * TODO: Need to add MUX settings for OMAP 2430 SDP
37 	 */
38 }
39 
40 static void omap2_mcbsp_request(unsigned int id)
41 {
42 	if (cpu_is_omap2420() && (id == OMAP_MCBSP2))
43 		omap2_mcbsp2_mux_setup();
44 }
45 
46 static struct omap_mcbsp_ops omap2_mcbsp_ops = {
47 	.request	= omap2_mcbsp_request,
48 };
49 
50 #ifdef CONFIG_ARCH_OMAP2420
51 static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = {
52 	{
53 		.phys_base	= OMAP24XX_MCBSP1_BASE,
54 		.dma_rx_sync	= OMAP24XX_DMA_MCBSP1_RX,
55 		.dma_tx_sync	= OMAP24XX_DMA_MCBSP1_TX,
56 		.rx_irq		= INT_24XX_MCBSP1_IRQ_RX,
57 		.tx_irq		= INT_24XX_MCBSP1_IRQ_TX,
58 		.ops		= &omap2_mcbsp_ops,
59 	},
60 	{
61 		.phys_base	= OMAP24XX_MCBSP2_BASE,
62 		.dma_rx_sync	= OMAP24XX_DMA_MCBSP2_RX,
63 		.dma_tx_sync	= OMAP24XX_DMA_MCBSP2_TX,
64 		.rx_irq		= INT_24XX_MCBSP2_IRQ_RX,
65 		.tx_irq		= INT_24XX_MCBSP2_IRQ_TX,
66 		.ops		= &omap2_mcbsp_ops,
67 	},
68 };
69 #define OMAP2420_MCBSP_PDATA_SZ		ARRAY_SIZE(omap2420_mcbsp_pdata)
70 #define OMAP2420_MCBSP_REG_NUM		(OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
71 #else
72 #define omap2420_mcbsp_pdata		NULL
73 #define OMAP2420_MCBSP_PDATA_SZ		0
74 #define OMAP2420_MCBSP_REG_NUM		0
75 #endif
76 
77 #ifdef CONFIG_ARCH_OMAP2430
78 static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
79 	{
80 		.phys_base	= OMAP24XX_MCBSP1_BASE,
81 		.dma_rx_sync	= OMAP24XX_DMA_MCBSP1_RX,
82 		.dma_tx_sync	= OMAP24XX_DMA_MCBSP1_TX,
83 		.rx_irq		= INT_24XX_MCBSP1_IRQ_RX,
84 		.tx_irq		= INT_24XX_MCBSP1_IRQ_TX,
85 		.ops		= &omap2_mcbsp_ops,
86 	},
87 	{
88 		.phys_base	= OMAP24XX_MCBSP2_BASE,
89 		.dma_rx_sync	= OMAP24XX_DMA_MCBSP2_RX,
90 		.dma_tx_sync	= OMAP24XX_DMA_MCBSP2_TX,
91 		.rx_irq		= INT_24XX_MCBSP2_IRQ_RX,
92 		.tx_irq		= INT_24XX_MCBSP2_IRQ_TX,
93 		.ops		= &omap2_mcbsp_ops,
94 	},
95 	{
96 		.phys_base	= OMAP2430_MCBSP3_BASE,
97 		.dma_rx_sync	= OMAP24XX_DMA_MCBSP3_RX,
98 		.dma_tx_sync	= OMAP24XX_DMA_MCBSP3_TX,
99 		.rx_irq		= INT_24XX_MCBSP3_IRQ_RX,
100 		.tx_irq		= INT_24XX_MCBSP3_IRQ_TX,
101 		.ops		= &omap2_mcbsp_ops,
102 	},
103 	{
104 		.phys_base	= OMAP2430_MCBSP4_BASE,
105 		.dma_rx_sync	= OMAP24XX_DMA_MCBSP4_RX,
106 		.dma_tx_sync	= OMAP24XX_DMA_MCBSP4_TX,
107 		.rx_irq		= INT_24XX_MCBSP4_IRQ_RX,
108 		.tx_irq		= INT_24XX_MCBSP4_IRQ_TX,
109 		.ops		= &omap2_mcbsp_ops,
110 	},
111 	{
112 		.phys_base	= OMAP2430_MCBSP5_BASE,
113 		.dma_rx_sync	= OMAP24XX_DMA_MCBSP5_RX,
114 		.dma_tx_sync	= OMAP24XX_DMA_MCBSP5_TX,
115 		.rx_irq		= INT_24XX_MCBSP5_IRQ_RX,
116 		.tx_irq		= INT_24XX_MCBSP5_IRQ_TX,
117 		.ops		= &omap2_mcbsp_ops,
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 		.ops		= &omap2_mcbsp_ops,
137 		.buffer_size	= 0x80, /* The FIFO has 128 locations */
138 	},
139 	{
140 		.phys_base	= OMAP34XX_MCBSP2_BASE,
141 		.phys_base_st	= OMAP34XX_MCBSP2_ST_BASE,
142 		.dma_rx_sync	= OMAP24XX_DMA_MCBSP2_RX,
143 		.dma_tx_sync	= OMAP24XX_DMA_MCBSP2_TX,
144 		.rx_irq		= INT_24XX_MCBSP2_IRQ_RX,
145 		.tx_irq		= INT_24XX_MCBSP2_IRQ_TX,
146 		.ops		= &omap2_mcbsp_ops,
147 		.buffer_size	= 0x500, /* The FIFO has 1024 + 256 locations */
148 	},
149 	{
150 		.phys_base	= OMAP34XX_MCBSP3_BASE,
151 		.phys_base_st	= OMAP34XX_MCBSP3_ST_BASE,
152 		.dma_rx_sync	= OMAP24XX_DMA_MCBSP3_RX,
153 		.dma_tx_sync	= OMAP24XX_DMA_MCBSP3_TX,
154 		.rx_irq		= INT_24XX_MCBSP3_IRQ_RX,
155 		.tx_irq		= INT_24XX_MCBSP3_IRQ_TX,
156 		.ops		= &omap2_mcbsp_ops,
157 		.buffer_size	= 0x80, /* The FIFO has 128 locations */
158 	},
159 	{
160 		.phys_base	= OMAP34XX_MCBSP4_BASE,
161 		.dma_rx_sync	= OMAP24XX_DMA_MCBSP4_RX,
162 		.dma_tx_sync	= OMAP24XX_DMA_MCBSP4_TX,
163 		.rx_irq		= INT_24XX_MCBSP4_IRQ_RX,
164 		.tx_irq		= INT_24XX_MCBSP4_IRQ_TX,
165 		.ops		= &omap2_mcbsp_ops,
166 		.buffer_size	= 0x80, /* The FIFO has 128 locations */
167 	},
168 	{
169 		.phys_base	= OMAP34XX_MCBSP5_BASE,
170 		.dma_rx_sync	= OMAP24XX_DMA_MCBSP5_RX,
171 		.dma_tx_sync	= OMAP24XX_DMA_MCBSP5_TX,
172 		.rx_irq		= INT_24XX_MCBSP5_IRQ_RX,
173 		.tx_irq		= INT_24XX_MCBSP5_IRQ_TX,
174 		.ops		= &omap2_mcbsp_ops,
175 		.buffer_size	= 0x80, /* The FIFO has 128 locations */
176 	},
177 };
178 #define OMAP34XX_MCBSP_PDATA_SZ		ARRAY_SIZE(omap34xx_mcbsp_pdata)
179 #define OMAP34XX_MCBSP_REG_NUM		(OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
180 #else
181 #define omap34xx_mcbsp_pdata		NULL
182 #define OMAP34XX_MCBSP_PDATA_SZ		0
183 #define OMAP34XX_MCBSP_REG_NUM		0
184 #endif
185 
186 static struct omap_mcbsp_platform_data omap44xx_mcbsp_pdata[] = {
187 	{
188 		.phys_base      = OMAP44XX_MCBSP1_BASE,
189 		.dma_rx_sync    = OMAP44XX_DMA_MCBSP1_RX,
190 		.dma_tx_sync    = OMAP44XX_DMA_MCBSP1_TX,
191 		.tx_irq         = OMAP44XX_IRQ_MCBSP1,
192 		.ops            = &omap2_mcbsp_ops,
193 	},
194 	{
195 		.phys_base      = OMAP44XX_MCBSP2_BASE,
196 		.dma_rx_sync    = OMAP44XX_DMA_MCBSP2_RX,
197 		.dma_tx_sync    = OMAP44XX_DMA_MCBSP2_TX,
198 		.tx_irq         = OMAP44XX_IRQ_MCBSP2,
199 		.ops            = &omap2_mcbsp_ops,
200 	},
201 	{
202 		.phys_base      = OMAP44XX_MCBSP3_BASE,
203 		.dma_rx_sync    = OMAP44XX_DMA_MCBSP3_RX,
204 		.dma_tx_sync    = OMAP44XX_DMA_MCBSP3_TX,
205 		.tx_irq         = OMAP44XX_IRQ_MCBSP3,
206 		.ops            = &omap2_mcbsp_ops,
207 	},
208 	{
209 		.phys_base      = OMAP44XX_MCBSP4_BASE,
210 		.dma_rx_sync    = OMAP44XX_DMA_MCBSP4_RX,
211 		.dma_tx_sync    = OMAP44XX_DMA_MCBSP4_TX,
212 		.tx_irq         = OMAP44XX_IRQ_MCBSP4,
213 		.ops            = &omap2_mcbsp_ops,
214 	},
215 };
216 #define OMAP44XX_MCBSP_PDATA_SZ		ARRAY_SIZE(omap44xx_mcbsp_pdata)
217 #define OMAP44XX_MCBSP_REG_NUM		(OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
218 
219 static int __init omap2_mcbsp_init(void)
220 {
221 	if (cpu_is_omap2420()) {
222 		omap_mcbsp_count = OMAP2420_MCBSP_PDATA_SZ;
223 		omap_mcbsp_cache_size = OMAP2420_MCBSP_REG_NUM * sizeof(u16);
224 	} else if (cpu_is_omap2430()) {
225 		omap_mcbsp_count = OMAP2430_MCBSP_PDATA_SZ;
226 		omap_mcbsp_cache_size = OMAP2430_MCBSP_REG_NUM * sizeof(u32);
227 	} else if (cpu_is_omap34xx()) {
228 		omap_mcbsp_count = OMAP34XX_MCBSP_PDATA_SZ;
229 		omap_mcbsp_cache_size = OMAP34XX_MCBSP_REG_NUM * sizeof(u32);
230 	} else if (cpu_is_omap44xx()) {
231 		omap_mcbsp_count = OMAP44XX_MCBSP_PDATA_SZ;
232 		omap_mcbsp_cache_size = OMAP44XX_MCBSP_REG_NUM * sizeof(u32);
233 	}
234 
235 	mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *),
236 								GFP_KERNEL);
237 	if (!mcbsp_ptr)
238 		return -ENOMEM;
239 
240 	if (cpu_is_omap2420())
241 		omap_mcbsp_register_board_cfg(omap2420_mcbsp_pdata,
242 						OMAP2420_MCBSP_PDATA_SZ);
243 	if (cpu_is_omap2430())
244 		omap_mcbsp_register_board_cfg(omap2430_mcbsp_pdata,
245 						OMAP2430_MCBSP_PDATA_SZ);
246 	if (cpu_is_omap34xx())
247 		omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata,
248 						OMAP34XX_MCBSP_PDATA_SZ);
249 	if (cpu_is_omap44xx())
250 		omap_mcbsp_register_board_cfg(omap44xx_mcbsp_pdata,
251 						OMAP44XX_MCBSP_PDATA_SZ);
252 
253 	return omap_mcbsp_init();
254 }
255 arch_initcall(omap2_mcbsp_init);
256