blob: 51abcedfde830c9ce8fb7b52e06ddc86def7fe29 [file] [log] [blame]
Eduardo Valentin78673bc2008-07-03 12:24:40 +03001/*
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>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090019#include <linux/slab.h>
Eduardo Valentin78673bc2008-07-03 12:24:40 +030020
Tony Lindgrendd7667a2009-01-15 13:09:51 +020021#include <mach/irqs.h>
Tony Lindgrence491cf2009-10-20 09:40:47 -070022#include <plat/dma.h>
Tony Lindgrence491cf2009-10-20 09:40:47 -070023#include <plat/cpu.h>
24#include <plat/mcbsp.h>
Paul Walmsleycf4c87a2010-10-08 11:40:19 -060025#include <plat/control.h>
Eduardo Valentin78673bc2008-07-03 12:24:40 +030026
Paul Walmsleycf4c87a2010-10-08 11:40:19 -060027/* McBSP internal signal muxing functions */
28
29void 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}
40EXPORT_SYMBOL(omap2_mcbsp1_mux_clkr_src);
41
42void 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}
53EXPORT_SYMBOL(omap2_mcbsp1_mux_fsr_src);
54
Paul Walmsleyd1358652010-10-08 11:40:19 -060055/* McBSP CLKS source switching function */
56
57int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id)
58{
59 struct omap_mcbsp *mcbsp;
60 struct clk *fck_src;
61 char *fck_src_name;
62 int r;
63
64 if (!omap_mcbsp_check_valid_id(id)) {
65 pr_err("%s: Invalid id (%d)\n", __func__, id + 1);
66 return -EINVAL;
67 }
68 mcbsp = id_to_mcbsp_ptr(id);
69
70 if (fck_src_id == MCBSP_CLKS_PAD_SRC)
71 fck_src_name = "pad_fck";
72 else if (fck_src_id == MCBSP_CLKS_PRCM_SRC)
73 fck_src_name = "prcm_fck";
74 else
75 return -EINVAL;
76
77 fck_src = clk_get(mcbsp->dev, fck_src_name);
78 if (IS_ERR_OR_NULL(fck_src)) {
79 pr_err("omap-mcbsp: %s: could not clk_get() %s\n", "clks",
80 fck_src_name);
81 return -EINVAL;
82 }
83
84 clk_disable(mcbsp->fclk);
85
86 r = clk_set_parent(mcbsp->fclk, fck_src);
87 if (IS_ERR_VALUE(r)) {
88 pr_err("omap-mcbsp: %s: could not clk_set_parent() to %s\n",
89 "clks", fck_src_name);
90 clk_put(fck_src);
91 return -EINVAL;
92 }
93
94 clk_enable(mcbsp->fclk);
95
96 clk_put(fck_src);
97
98 return 0;
99}
100EXPORT_SYMBOL(omap2_mcbsp_set_clks_src);
101
102
Paul Walmsleycf4c87a2010-10-08 11:40:19 -0600103/* Platform data */
Eduardo Valentin78673bc2008-07-03 12:24:40 +0300104
Jarkko Nikula05228c32008-10-08 10:01:40 +0300105#ifdef CONFIG_ARCH_OMAP2420
106static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = {
Eduardo Valentin78673bc2008-07-03 12:24:40 +0300107 {
Russell King65846902008-09-03 23:46:18 +0100108 .phys_base = OMAP24XX_MCBSP1_BASE,
Eduardo Valentin78673bc2008-07-03 12:24:40 +0300109 .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX,
110 .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX,
111 .rx_irq = INT_24XX_MCBSP1_IRQ_RX,
112 .tx_irq = INT_24XX_MCBSP1_IRQ_TX,
Eduardo Valentin78673bc2008-07-03 12:24:40 +0300113 },
114 {
Russell King65846902008-09-03 23:46:18 +0100115 .phys_base = OMAP24XX_MCBSP2_BASE,
Eduardo Valentin78673bc2008-07-03 12:24:40 +0300116 .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX,
117 .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX,
118 .rx_irq = INT_24XX_MCBSP2_IRQ_RX,
119 .tx_irq = INT_24XX_MCBSP2_IRQ_TX,
Eduardo Valentin78673bc2008-07-03 12:24:40 +0300120 },
121};
Jarkko Nikula05228c32008-10-08 10:01:40 +0300122#define OMAP2420_MCBSP_PDATA_SZ ARRAY_SIZE(omap2420_mcbsp_pdata)
Janusz Krzysztofikc8c99692010-02-15 10:03:33 -0800123#define OMAP2420_MCBSP_REG_NUM (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
Eduardo Valentin78673bc2008-07-03 12:24:40 +0300124#else
Jarkko Nikula05228c32008-10-08 10:01:40 +0300125#define omap2420_mcbsp_pdata NULL
126#define OMAP2420_MCBSP_PDATA_SZ 0
Janusz Krzysztofikc8c99692010-02-15 10:03:33 -0800127#define OMAP2420_MCBSP_REG_NUM 0
Jarkko Nikula05228c32008-10-08 10:01:40 +0300128#endif
129
130#ifdef CONFIG_ARCH_OMAP2430
131static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
132 {
133 .phys_base = OMAP24XX_MCBSP1_BASE,
134 .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX,
135 .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX,
136 .rx_irq = INT_24XX_MCBSP1_IRQ_RX,
137 .tx_irq = INT_24XX_MCBSP1_IRQ_TX,
Jarkko Nikula05228c32008-10-08 10:01:40 +0300138 },
139 {
140 .phys_base = OMAP24XX_MCBSP2_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,
Jarkko Nikula05228c32008-10-08 10:01:40 +0300145 },
146 {
147 .phys_base = OMAP2430_MCBSP3_BASE,
148 .dma_rx_sync = OMAP24XX_DMA_MCBSP3_RX,
149 .dma_tx_sync = OMAP24XX_DMA_MCBSP3_TX,
150 .rx_irq = INT_24XX_MCBSP3_IRQ_RX,
151 .tx_irq = INT_24XX_MCBSP3_IRQ_TX,
Jarkko Nikula05228c32008-10-08 10:01:40 +0300152 },
153 {
154 .phys_base = OMAP2430_MCBSP4_BASE,
155 .dma_rx_sync = OMAP24XX_DMA_MCBSP4_RX,
156 .dma_tx_sync = OMAP24XX_DMA_MCBSP4_TX,
157 .rx_irq = INT_24XX_MCBSP4_IRQ_RX,
158 .tx_irq = INT_24XX_MCBSP4_IRQ_TX,
Jarkko Nikula05228c32008-10-08 10:01:40 +0300159 },
160 {
161 .phys_base = OMAP2430_MCBSP5_BASE,
162 .dma_rx_sync = OMAP24XX_DMA_MCBSP5_RX,
163 .dma_tx_sync = OMAP24XX_DMA_MCBSP5_TX,
164 .rx_irq = INT_24XX_MCBSP5_IRQ_RX,
165 .tx_irq = INT_24XX_MCBSP5_IRQ_TX,
Jarkko Nikula05228c32008-10-08 10:01:40 +0300166 },
167};
168#define OMAP2430_MCBSP_PDATA_SZ ARRAY_SIZE(omap2430_mcbsp_pdata)
Janusz Krzysztofikc8c99692010-02-15 10:03:33 -0800169#define OMAP2430_MCBSP_REG_NUM (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
Jarkko Nikula05228c32008-10-08 10:01:40 +0300170#else
171#define omap2430_mcbsp_pdata NULL
172#define OMAP2430_MCBSP_PDATA_SZ 0
Janusz Krzysztofikc8c99692010-02-15 10:03:33 -0800173#define OMAP2430_MCBSP_REG_NUM 0
Eduardo Valentin78673bc2008-07-03 12:24:40 +0300174#endif
175
Tony Lindgrena8eb7ca2010-02-12 12:26:48 -0800176#ifdef CONFIG_ARCH_OMAP3
Eduardo Valentin78673bc2008-07-03 12:24:40 +0300177static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
178 {
Russell King65846902008-09-03 23:46:18 +0100179 .phys_base = OMAP34XX_MCBSP1_BASE,
Eduardo Valentin78673bc2008-07-03 12:24:40 +0300180 .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX,
181 .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX,
182 .rx_irq = INT_24XX_MCBSP1_IRQ_RX,
183 .tx_irq = INT_24XX_MCBSP1_IRQ_TX,
Peter Ujfalusi451fd822010-06-03 07:39:33 +0300184 .buffer_size = 0x80, /* The FIFO has 128 locations */
Eduardo Valentin78673bc2008-07-03 12:24:40 +0300185 },
186 {
Russell King65846902008-09-03 23:46:18 +0100187 .phys_base = OMAP34XX_MCBSP2_BASE,
Eero Nurkkalad912fa92010-02-22 12:21:11 +0000188 .phys_base_st = OMAP34XX_MCBSP2_ST_BASE,
Eduardo Valentin78673bc2008-07-03 12:24:40 +0300189 .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX,
190 .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX,
191 .rx_irq = INT_24XX_MCBSP2_IRQ_RX,
192 .tx_irq = INT_24XX_MCBSP2_IRQ_TX,
Peter Ujfalusi451fd822010-06-03 07:39:33 +0300193 .buffer_size = 0x500, /* The FIFO has 1024 + 256 locations */
Eduardo Valentin78673bc2008-07-03 12:24:40 +0300194 },
Chandra Shekhar9c8e3a02008-10-08 10:01:40 +0300195 {
196 .phys_base = OMAP34XX_MCBSP3_BASE,
Eero Nurkkalad912fa92010-02-22 12:21:11 +0000197 .phys_base_st = OMAP34XX_MCBSP3_ST_BASE,
Chandra Shekhar9c8e3a02008-10-08 10:01:40 +0300198 .dma_rx_sync = OMAP24XX_DMA_MCBSP3_RX,
199 .dma_tx_sync = OMAP24XX_DMA_MCBSP3_TX,
200 .rx_irq = INT_24XX_MCBSP3_IRQ_RX,
201 .tx_irq = INT_24XX_MCBSP3_IRQ_TX,
Peter Ujfalusi451fd822010-06-03 07:39:33 +0300202 .buffer_size = 0x80, /* The FIFO has 128 locations */
Chandra Shekhar9c8e3a02008-10-08 10:01:40 +0300203 },
204 {
205 .phys_base = OMAP34XX_MCBSP4_BASE,
206 .dma_rx_sync = OMAP24XX_DMA_MCBSP4_RX,
207 .dma_tx_sync = OMAP24XX_DMA_MCBSP4_TX,
208 .rx_irq = INT_24XX_MCBSP4_IRQ_RX,
209 .tx_irq = INT_24XX_MCBSP4_IRQ_TX,
Peter Ujfalusi451fd822010-06-03 07:39:33 +0300210 .buffer_size = 0x80, /* The FIFO has 128 locations */
Chandra Shekhar9c8e3a02008-10-08 10:01:40 +0300211 },
212 {
213 .phys_base = OMAP34XX_MCBSP5_BASE,
214 .dma_rx_sync = OMAP24XX_DMA_MCBSP5_RX,
215 .dma_tx_sync = OMAP24XX_DMA_MCBSP5_TX,
216 .rx_irq = INT_24XX_MCBSP5_IRQ_RX,
217 .tx_irq = INT_24XX_MCBSP5_IRQ_TX,
Peter Ujfalusi451fd822010-06-03 07:39:33 +0300218 .buffer_size = 0x80, /* The FIFO has 128 locations */
Chandra Shekhar9c8e3a02008-10-08 10:01:40 +0300219 },
Eduardo Valentin78673bc2008-07-03 12:24:40 +0300220};
221#define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata)
Janusz Krzysztofikc8c99692010-02-15 10:03:33 -0800222#define OMAP34XX_MCBSP_REG_NUM (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
Eduardo Valentin78673bc2008-07-03 12:24:40 +0300223#else
224#define omap34xx_mcbsp_pdata NULL
225#define OMAP34XX_MCBSP_PDATA_SZ 0
Janusz Krzysztofikc8c99692010-02-15 10:03:33 -0800226#define OMAP34XX_MCBSP_REG_NUM 0
Eduardo Valentin78673bc2008-07-03 12:24:40 +0300227#endif
228
Syed Rafiuddina5b92cc2009-07-28 18:57:10 +0530229static struct omap_mcbsp_platform_data omap44xx_mcbsp_pdata[] = {
230 {
231 .phys_base = OMAP44XX_MCBSP1_BASE,
232 .dma_rx_sync = OMAP44XX_DMA_MCBSP1_RX,
233 .dma_tx_sync = OMAP44XX_DMA_MCBSP1_TX,
Jorge Eduardo Candelaria9319b9d2010-05-12 12:18:39 -0500234 .tx_irq = OMAP44XX_IRQ_MCBSP1,
Syed Rafiuddina5b92cc2009-07-28 18:57:10 +0530235 },
236 {
237 .phys_base = OMAP44XX_MCBSP2_BASE,
238 .dma_rx_sync = OMAP44XX_DMA_MCBSP2_RX,
239 .dma_tx_sync = OMAP44XX_DMA_MCBSP2_TX,
Jorge Eduardo Candelaria9319b9d2010-05-12 12:18:39 -0500240 .tx_irq = OMAP44XX_IRQ_MCBSP2,
Paul Walmsleyd1358652010-10-08 11:40:19 -0600241 /* XXX .ops ? */
Syed Rafiuddina5b92cc2009-07-28 18:57:10 +0530242 },
243 {
244 .phys_base = OMAP44XX_MCBSP3_BASE,
245 .dma_rx_sync = OMAP44XX_DMA_MCBSP3_RX,
246 .dma_tx_sync = OMAP44XX_DMA_MCBSP3_TX,
Jorge Eduardo Candelaria9319b9d2010-05-12 12:18:39 -0500247 .tx_irq = OMAP44XX_IRQ_MCBSP3,
Paul Walmsleyd1358652010-10-08 11:40:19 -0600248 /* XXX .ops ? */
Syed Rafiuddina5b92cc2009-07-28 18:57:10 +0530249 },
250 {
251 .phys_base = OMAP44XX_MCBSP4_BASE,
252 .dma_rx_sync = OMAP44XX_DMA_MCBSP4_RX,
253 .dma_tx_sync = OMAP44XX_DMA_MCBSP4_TX,
Jorge Eduardo Candelaria9319b9d2010-05-12 12:18:39 -0500254 .tx_irq = OMAP44XX_IRQ_MCBSP4,
Paul Walmsleyd1358652010-10-08 11:40:19 -0600255 /* XXX .ops ? */
Syed Rafiuddina5b92cc2009-07-28 18:57:10 +0530256 },
257};
258#define OMAP44XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap44xx_mcbsp_pdata)
Janusz Krzysztofikc8c99692010-02-15 10:03:33 -0800259#define OMAP44XX_MCBSP_REG_NUM (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
Syed Rafiuddina5b92cc2009-07-28 18:57:10 +0530260
Chandra Shekharb4b58f52008-10-08 10:01:39 +0300261static int __init omap2_mcbsp_init(void)
Eduardo Valentin78673bc2008-07-03 12:24:40 +0300262{
Janusz Krzysztofikc8c99692010-02-15 10:03:33 -0800263 if (cpu_is_omap2420()) {
Jarkko Nikula05228c32008-10-08 10:01:40 +0300264 omap_mcbsp_count = OMAP2420_MCBSP_PDATA_SZ;
Janusz Krzysztofikc8c99692010-02-15 10:03:33 -0800265 omap_mcbsp_cache_size = OMAP2420_MCBSP_REG_NUM * sizeof(u16);
266 } else if (cpu_is_omap2430()) {
Jarkko Nikula05228c32008-10-08 10:01:40 +0300267 omap_mcbsp_count = OMAP2430_MCBSP_PDATA_SZ;
Janusz Krzysztofikc8c99692010-02-15 10:03:33 -0800268 omap_mcbsp_cache_size = OMAP2430_MCBSP_REG_NUM * sizeof(u32);
269 } else if (cpu_is_omap34xx()) {
Chandra Shekharb4b58f52008-10-08 10:01:39 +0300270 omap_mcbsp_count = OMAP34XX_MCBSP_PDATA_SZ;
Janusz Krzysztofikc8c99692010-02-15 10:03:33 -0800271 omap_mcbsp_cache_size = OMAP34XX_MCBSP_REG_NUM * sizeof(u32);
272 } else if (cpu_is_omap44xx()) {
Syed Rafiuddina5b92cc2009-07-28 18:57:10 +0530273 omap_mcbsp_count = OMAP44XX_MCBSP_PDATA_SZ;
Janusz Krzysztofikc8c99692010-02-15 10:03:33 -0800274 omap_mcbsp_cache_size = OMAP44XX_MCBSP_REG_NUM * sizeof(u32);
275 }
Chandra Shekharb4b58f52008-10-08 10:01:39 +0300276
277 mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *),
278 GFP_KERNEL);
279 if (!mcbsp_ptr)
280 return -ENOMEM;
281
Jarkko Nikula05228c32008-10-08 10:01:40 +0300282 if (cpu_is_omap2420())
283 omap_mcbsp_register_board_cfg(omap2420_mcbsp_pdata,
284 OMAP2420_MCBSP_PDATA_SZ);
285 if (cpu_is_omap2430())
286 omap_mcbsp_register_board_cfg(omap2430_mcbsp_pdata,
287 OMAP2430_MCBSP_PDATA_SZ);
Chandra Shekhar9c8e3a02008-10-08 10:01:40 +0300288 if (cpu_is_omap34xx())
289 omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata,
290 OMAP34XX_MCBSP_PDATA_SZ);
Syed Rafiuddina5b92cc2009-07-28 18:57:10 +0530291 if (cpu_is_omap44xx())
292 omap_mcbsp_register_board_cfg(omap44xx_mcbsp_pdata,
293 OMAP44XX_MCBSP_PDATA_SZ);
Eduardo Valentin78673bc2008-07-03 12:24:40 +0300294
Eduardo Valentin78673bc2008-07-03 12:24:40 +0300295 return omap_mcbsp_init();
296}
297arch_initcall(omap2_mcbsp_init);