aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap
diff options
context:
space:
mode:
authorEduardo Valentin <eduardo.valentin@indt.org.br>2008-07-03 05:24:39 -0400
committerTony Lindgren <tony@atomide.com>2008-07-03 05:24:39 -0400
commitbc5d0c89c88df67f92d5d5882c27437379e9e8af (patch)
tree56ed4beca70ed8485244e8c1a494e72d06ca367d /arch/arm/plat-omap
parentfb78d80808a75213f399b7b10048d72a0b39b494 (diff)
ARM: OMAP: McBSP: Prepare for splitting into omap1 and omap2 code
This patch transform mcbsp code to use platform data from arch/arm/plat-omap/devices.c It also gets ride of ifdefs on mcbsp.c code. To do it, a platform data structure was defined. Signed-off-by: Eduardo Valentin <eduardo.valentin@indt.org.br> Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r--arch/arm/plat-omap/devices.c48
-rw-r--r--arch/arm/plat-omap/mcbsp.c662
2 files changed, 301 insertions, 409 deletions
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index 4a53f9ba6c43..81002b722da1 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -24,6 +24,7 @@
24#include <asm/arch/mux.h> 24#include <asm/arch/mux.h>
25#include <asm/arch/gpio.h> 25#include <asm/arch/gpio.h>
26#include <asm/arch/menelaus.h> 26#include <asm/arch/menelaus.h>
27#include <asm/arch/mcbsp.h>
27 28
28#if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE) 29#if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE)
29 30
@@ -145,6 +146,53 @@ static inline void omap_init_kp(void) {}
145#endif 146#endif
146 147
147/*-------------------------------------------------------------------------*/ 148/*-------------------------------------------------------------------------*/
149#if defined(CONFIG_OMAP_MCBSP) || defined(CONFIG_OMAP_MCBSP_MODULE)
150
151static struct platform_device **omap_mcbsp_devices;
152
153void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
154 int size)
155{
156 int i;
157
158 if (size > OMAP_MAX_MCBSP_COUNT) {
159 printk(KERN_WARNING "Registered too many McBSPs platform_data."
160 " Using maximum (%d) available.\n",
161 OMAP_MAX_MCBSP_COUNT);
162 size = OMAP_MAX_MCBSP_COUNT;
163 }
164
165 omap_mcbsp_devices = kzalloc(size * sizeof(struct platform_device *),
166 GFP_KERNEL);
167 if (!omap_mcbsp_devices) {
168 printk(KERN_ERR "Could not register McBSP devices\n");
169 return;
170 }
171
172 for (i = 0; i < size; i++) {
173 struct platform_device *new_mcbsp;
174 int ret;
175
176 new_mcbsp = platform_device_alloc("omap-mcbsp", i + 1);
177 if (!new_mcbsp)
178 continue;
179 new_mcbsp->dev.platform_data = &config[i];
180 ret = platform_device_add(new_mcbsp);
181 if (ret) {
182 platform_device_put(new_mcbsp);
183 continue;
184 }
185 omap_mcbsp_devices[i] = new_mcbsp;
186 }
187}
188
189#else
190void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
191 int size)
192{ }
193#endif
194
195/*-------------------------------------------------------------------------*/
148 196
149#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) 197#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
150 198
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index c0018b1b6673..c7f74064696c 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -15,6 +15,7 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/device.h> 17#include <linux/device.h>
18#include <linux/platform_device.h>
18#include <linux/wait.h> 19#include <linux/wait.h>
19#include <linux/completion.h> 20#include <linux/completion.h>
20#include <linux/interrupt.h> 21#include <linux/interrupt.h>
@@ -24,83 +25,53 @@
24#include <linux/io.h> 25#include <linux/io.h>
25 26
26#include <asm/arch/dma.h> 27#include <asm/arch/dma.h>
27#include <asm/arch/mux.h>
28#include <asm/arch/irqs.h>
29#include <asm/arch/dsp_common.h>
30#include <asm/arch/mcbsp.h> 28#include <asm/arch/mcbsp.h>
31 29
32#ifdef CONFIG_MCBSP_DEBUG
33#define DBG(x...) printk(x)
34#else
35#define DBG(x...) do { } while (0)
36#endif
37
38struct omap_mcbsp {
39 u32 io_base;
40 u8 id;
41 u8 free;
42 omap_mcbsp_word_length rx_word_length;
43 omap_mcbsp_word_length tx_word_length;
44
45 omap_mcbsp_io_type_t io_type; /* IRQ or poll */
46 /* IRQ based TX/RX */
47 int rx_irq;
48 int tx_irq;
49
50 /* DMA stuff */
51 u8 dma_rx_sync;
52 short dma_rx_lch;
53 u8 dma_tx_sync;
54 short dma_tx_lch;
55
56 /* Completion queues */
57 struct completion tx_irq_completion;
58 struct completion rx_irq_completion;
59 struct completion tx_dma_completion;
60 struct completion rx_dma_completion;
61
62 /* Protect the field .free, while checking if the mcbsp is in use */
63 spinlock_t lock;
64};
65
66static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT]; 30static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT];
67#ifdef CONFIG_ARCH_OMAP1 31
68static struct clk *mcbsp_dsp_ck; 32#define omap_mcbsp_check_valid_id(id) (mcbsp[id].pdata && \
69static struct clk *mcbsp_api_ck; 33 mcbsp[id].pdata->ops && \
70static struct clk *mcbsp_dspxor_ck; 34 mcbsp[id].pdata->ops->check && \
71#endif 35 (mcbsp[id].pdata->ops->check(id) == 0))
72#ifdef CONFIG_ARCH_OMAP2
73static struct clk *mcbsp1_ick;
74static struct clk *mcbsp1_fck;
75static struct clk *mcbsp2_ick;
76static struct clk *mcbsp2_fck;
77#endif
78 36
79static void omap_mcbsp_dump_reg(u8 id) 37static void omap_mcbsp_dump_reg(u8 id)
80{ 38{
81 DBG("**** MCBSP%d regs ****\n", mcbsp[id].id); 39 dev_dbg(mcbsp[id].dev, "**** McBSP%d regs ****\n", mcbsp[id].id);
82 DBG("DRR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2)); 40 dev_dbg(mcbsp[id].dev, "DRR2: 0x%04x\n",
83 DBG("DRR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1)); 41 OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2));
84 DBG("DXR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2)); 42 dev_dbg(mcbsp[id].dev, "DRR1: 0x%04x\n",
85 DBG("DXR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1)); 43 OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1));
86 DBG("SPCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2)); 44 dev_dbg(mcbsp[id].dev, "DXR2: 0x%04x\n",
87 DBG("SPCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1)); 45 OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2));
88 DBG("RCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2)); 46 dev_dbg(mcbsp[id].dev, "DXR1: 0x%04x\n",
89 DBG("RCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1)); 47 OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1));
90 DBG("XCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2)); 48 dev_dbg(mcbsp[id].dev, "SPCR2: 0x%04x\n",
91 DBG("XCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1)); 49 OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2));
92 DBG("SRGR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2)); 50 dev_dbg(mcbsp[id].dev, "SPCR1: 0x%04x\n",
93 DBG("SRGR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1)); 51 OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1));
94 DBG("PCR0: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0)); 52 dev_dbg(mcbsp[id].dev, "RCR2: 0x%04x\n",
95 DBG("***********************\n"); 53 OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2));
54 dev_dbg(mcbsp[id].dev, "RCR1: 0x%04x\n",
55 OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1));
56 dev_dbg(mcbsp[id].dev, "XCR2: 0x%04x\n",
57 OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2));
58 dev_dbg(mcbsp[id].dev, "XCR1: 0x%04x\n",
59 OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1));
60 dev_dbg(mcbsp[id].dev, "SRGR2: 0x%04x\n",
61 OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2));
62 dev_dbg(mcbsp[id].dev, "SRGR1: 0x%04x\n",
63 OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1));
64 dev_dbg(mcbsp[id].dev, "PCR0: 0x%04x\n",
65 OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0));
66 dev_dbg(mcbsp[id].dev, "***********************\n");
96} 67}
97 68
98static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id) 69static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
99{ 70{
100 struct omap_mcbsp *mcbsp_tx = dev_id; 71 struct omap_mcbsp *mcbsp_tx = dev_id;
101 72
102 DBG("TX IRQ callback : 0x%x\n", 73 dev_dbg(mcbsp_tx->dev, "TX IRQ callback : 0x%x\n",
103 OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2)); 74 OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2));
104 75
105 complete(&mcbsp_tx->tx_irq_completion); 76 complete(&mcbsp_tx->tx_irq_completion);
106 77
@@ -111,8 +82,8 @@ static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)
111{ 82{
112 struct omap_mcbsp *mcbsp_rx = dev_id; 83 struct omap_mcbsp *mcbsp_rx = dev_id;
113 84
114 DBG("RX IRQ callback : 0x%x\n", 85 dev_dbg(mcbsp_rx->dev, "RX IRQ callback : 0x%x\n",
115 OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2)); 86 OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2));
116 87
117 complete(&mcbsp_rx->rx_irq_completion); 88 complete(&mcbsp_rx->rx_irq_completion);
118 89
@@ -123,8 +94,8 @@ static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data)
123{ 94{
124 struct omap_mcbsp *mcbsp_dma_tx = data; 95 struct omap_mcbsp *mcbsp_dma_tx = data;
125 96
126 DBG("TX DMA callback : 0x%x\n", 97 dev_dbg(mcbsp_dma_tx->dev, "TX DMA callback : 0x%x\n",
127 OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2)); 98 OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2));
128 99
129 /* We can free the channels */ 100 /* We can free the channels */
130 omap_free_dma(mcbsp_dma_tx->dma_tx_lch); 101 omap_free_dma(mcbsp_dma_tx->dma_tx_lch);
@@ -137,8 +108,8 @@ static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
137{ 108{
138 struct omap_mcbsp *mcbsp_dma_rx = data; 109 struct omap_mcbsp *mcbsp_dma_rx = data;
139 110
140 DBG("RX DMA callback : 0x%x\n", 111 dev_dbg(mcbsp_dma_rx->dev, "RX DMA callback : 0x%x\n",
141 OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2)); 112 OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2));
142 113
143 /* We can free the channels */ 114 /* We can free the channels */
144 omap_free_dma(mcbsp_dma_rx->dma_rx_lch); 115 omap_free_dma(mcbsp_dma_rx->dma_rx_lch);
@@ -155,9 +126,16 @@ static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
155 */ 126 */
156void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config) 127void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config)
157{ 128{
158 u32 io_base = mcbsp[id].io_base; 129 u32 io_base;
159 130
160 DBG("OMAP-McBSP: McBSP%d io_base: 0x%8x\n", id + 1, io_base); 131 if (!omap_mcbsp_check_valid_id(id)) {
132 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
133 return;
134 }
135
136 io_base = mcbsp[id].io_base;
137 dev_dbg(mcbsp[id].dev, "Configuring McBSP%d io_base: 0x%8x\n",
138 mcbsp[id].id, io_base);
161 139
162 /* We write the given config */ 140 /* We write the given config */
163 OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2); 141 OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2);
@@ -174,97 +152,22 @@ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config)
174} 152}
175EXPORT_SYMBOL(omap_mcbsp_config); 153EXPORT_SYMBOL(omap_mcbsp_config);
176 154
177static int omap_mcbsp_check(unsigned int id)
178{
179 if (cpu_is_omap730()) {
180 if (id > OMAP_MAX_MCBSP_COUNT - 1) {
181 printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n",
182 id + 1);
183 return -1;
184 }
185 return 0;
186 }
187
188 if (cpu_is_omap15xx() || cpu_is_omap16xx() || cpu_is_omap24xx()) {
189 if (id > OMAP_MAX_MCBSP_COUNT) {
190 printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n",
191 id + 1);
192 return -1;
193 }
194 return 0;
195 }
196
197 return -1;
198}
199
200#ifdef CONFIG_ARCH_OMAP1
201static void omap_mcbsp_dsp_request(void)
202{
203 if (cpu_is_omap15xx() || cpu_is_omap16xx()) {
204 int ret;
205
206 ret = omap_dsp_request_mem();
207 if (ret < 0) {
208 printk(KERN_ERR "Could not get dsp memory: %i\n", ret);
209 return;
210 }
211
212 clk_enable(mcbsp_dsp_ck);
213 clk_enable(mcbsp_api_ck);
214
215 /* enable 12MHz clock to mcbsp 1 & 3 */
216 clk_enable(mcbsp_dspxor_ck);
217
218 /*
219 * DSP external peripheral reset
220 * FIXME: This should be moved to dsp code
221 */
222 __raw_writew(__raw_readw(DSP_RSTCT2) | 1 | 1 << 1,
223 DSP_RSTCT2);
224 }
225}
226
227static void omap_mcbsp_dsp_free(void)
228{
229 if (cpu_is_omap15xx() || cpu_is_omap16xx()) {
230 omap_dsp_release_mem();
231 clk_disable(mcbsp_dspxor_ck);
232 clk_disable(mcbsp_dsp_ck);
233 clk_disable(mcbsp_api_ck);
234 }
235}
236#endif
237
238#ifdef CONFIG_ARCH_OMAP2
239static void omap2_mcbsp2_mux_setup(void)
240{
241 if (cpu_is_omap2420()) {
242 omap_cfg_reg(Y15_24XX_MCBSP2_CLKX);
243 omap_cfg_reg(R14_24XX_MCBSP2_FSX);
244 omap_cfg_reg(W15_24XX_MCBSP2_DR);
245 omap_cfg_reg(V15_24XX_MCBSP2_DX);
246 omap_cfg_reg(V14_24XX_GPIO117);
247 }
248 /*
249 * Need to add MUX settings for OMAP 2430 SDP
250 */
251}
252#endif
253
254/* 155/*
255 * We can choose between IRQ based or polled IO. 156 * We can choose between IRQ based or polled IO.
256 * This needs to be called before omap_mcbsp_request(). 157 * This needs to be called before omap_mcbsp_request().
257 */ 158 */
258int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type) 159int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type)
259{ 160{
260 if (omap_mcbsp_check(id) < 0) 161 if (!omap_mcbsp_check_valid_id(id)) {
261 return -EINVAL; 162 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
163 return -ENODEV;
164 }
262 165
263 spin_lock(&mcbsp[id].lock); 166 spin_lock(&mcbsp[id].lock);
264 167
265 if (!mcbsp[id].free) { 168 if (!mcbsp[id].free) {
266 printk(KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", 169 dev_err(mcbsp[id].dev, "McBSP%d is currently in use\n",
267 id + 1); 170 mcbsp[id].id);
268 spin_unlock(&mcbsp[id].lock); 171 spin_unlock(&mcbsp[id].lock);
269 return -EINVAL; 172 return -EINVAL;
270 } 173 }
@@ -281,34 +184,20 @@ int omap_mcbsp_request(unsigned int id)
281{ 184{
282 int err; 185 int err;
283 186
284 if (omap_mcbsp_check(id) < 0) 187 if (!omap_mcbsp_check_valid_id(id)) {
285 return -EINVAL; 188 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
286 189 return -ENODEV;
287#ifdef CONFIG_ARCH_OMAP1
288 /*
289 * On 1510, 1610 and 1710, McBSP1 and McBSP3
290 * are DSP public peripherals.
291 */
292 if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
293 omap_mcbsp_dsp_request();
294#endif
295
296#ifdef CONFIG_ARCH_OMAP2
297 if (cpu_is_omap24xx()) {
298 if (id == OMAP_MCBSP1) {
299 clk_enable(mcbsp1_ick);
300 clk_enable(mcbsp1_fck);
301 } else {
302 clk_enable(mcbsp2_ick);
303 clk_enable(mcbsp2_fck);
304 }
305 } 190 }
306#endif 191
192 if (mcbsp[id].pdata->ops->request)
193 mcbsp[id].pdata->ops->request(id);
194
195 clk_enable(mcbsp[id].clk);
307 196
308 spin_lock(&mcbsp[id].lock); 197 spin_lock(&mcbsp[id].lock);
309 if (!mcbsp[id].free) { 198 if (!mcbsp[id].free) {
310 printk(KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", 199 dev_err(mcbsp[id].dev, "McBSP%d is currently in use\n",
311 id + 1); 200 mcbsp[id].id);
312 spin_unlock(&mcbsp[id].lock); 201 spin_unlock(&mcbsp[id].lock);
313 return -1; 202 return -1;
314 } 203 }
@@ -321,9 +210,9 @@ int omap_mcbsp_request(unsigned int id)
321 err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, 210 err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler,
322 0, "McBSP", (void *) (&mcbsp[id])); 211 0, "McBSP", (void *) (&mcbsp[id]));
323 if (err != 0) { 212 if (err != 0) {
324 printk(KERN_ERR "OMAP-McBSP: Unable to " 213 dev_err(mcbsp[id].dev, "Unable to request TX IRQ %d "
325 "request TX IRQ %d for McBSP%d\n", 214 "for McBSP%d\n", mcbsp[id].tx_irq,
326 mcbsp[id].tx_irq, mcbsp[id].id); 215 mcbsp[id].id);
327 return err; 216 return err;
328 } 217 }
329 218
@@ -332,9 +221,9 @@ int omap_mcbsp_request(unsigned int id)
332 err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, 221 err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler,
333 0, "McBSP", (void *) (&mcbsp[id])); 222 0, "McBSP", (void *) (&mcbsp[id]));
334 if (err != 0) { 223 if (err != 0) {
335 printk(KERN_ERR "OMAP-McBSP: Unable to " 224 dev_err(mcbsp[id].dev, "Unable to request RX IRQ %d "
336 "request RX IRQ %d for McBSP%d\n", 225 "for McBSP%d\n", mcbsp[id].rx_irq,
337 mcbsp[id].rx_irq, mcbsp[id].id); 226 mcbsp[id].id);
338 free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); 227 free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
339 return err; 228 return err;
340 } 229 }
@@ -348,32 +237,20 @@ EXPORT_SYMBOL(omap_mcbsp_request);
348 237
349void omap_mcbsp_free(unsigned int id) 238void omap_mcbsp_free(unsigned int id)
350{ 239{
351 if (omap_mcbsp_check(id) < 0) 240 if (!omap_mcbsp_check_valid_id(id)) {
241 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
352 return; 242 return;
353
354#ifdef CONFIG_ARCH_OMAP1
355 if (cpu_class_is_omap1()) {
356 if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
357 omap_mcbsp_dsp_free();
358 } 243 }
359#endif 244
360 245 if (mcbsp[id].pdata->ops->free)
361#ifdef CONFIG_ARCH_OMAP2 246 mcbsp[id].pdata->ops->free(id);
362 if (cpu_is_omap24xx()) { 247
363 if (id == OMAP_MCBSP1) { 248 clk_disable(mcbsp[id].clk);
364 clk_disable(mcbsp1_ick);
365 clk_disable(mcbsp1_fck);
366 } else {
367 clk_disable(mcbsp2_ick);
368 clk_disable(mcbsp2_fck);
369 }
370 }
371#endif
372 249
373 spin_lock(&mcbsp[id].lock); 250 spin_lock(&mcbsp[id].lock);
374 if (mcbsp[id].free) { 251 if (mcbsp[id].free) {
375 printk(KERN_ERR "OMAP-McBSP: McBSP%d was not reserved\n", 252 dev_err(mcbsp[id].dev, "McBSP%d was not reserved\n",
376 id + 1); 253 mcbsp[id].id);
377 spin_unlock(&mcbsp[id].lock); 254 spin_unlock(&mcbsp[id].lock);
378 return; 255 return;
379 } 256 }
@@ -399,8 +276,10 @@ void omap_mcbsp_start(unsigned int id)
399 u32 io_base; 276 u32 io_base;
400 u16 w; 277 u16 w;
401 278
402 if (omap_mcbsp_check(id) < 0) 279 if (!omap_mcbsp_check_valid_id(id)) {
280 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
403 return; 281 return;
282 }
404 283
405 io_base = mcbsp[id].io_base; 284 io_base = mcbsp[id].io_base;
406 285
@@ -434,8 +313,10 @@ void omap_mcbsp_stop(unsigned int id)
434 u32 io_base; 313 u32 io_base;
435 u16 w; 314 u16 w;
436 315
437 if (omap_mcbsp_check(id) < 0) 316 if (!omap_mcbsp_check_valid_id(id)) {
317 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
438 return; 318 return;
319 }
439 320
440 io_base = mcbsp[id].io_base; 321 io_base = mcbsp[id].io_base;
441 322
@@ -456,7 +337,14 @@ EXPORT_SYMBOL(omap_mcbsp_stop);
456/* polled mcbsp i/o operations */ 337/* polled mcbsp i/o operations */
457int omap_mcbsp_pollwrite(unsigned int id, u16 buf) 338int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
458{ 339{
459 u32 base = mcbsp[id].io_base; 340 u32 base;
341
342 if (!omap_mcbsp_check_valid_id(id)) {
343 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
344 return -ENODEV;
345 }
346
347 base = mcbsp[id].io_base;
460 writew(buf, base + OMAP_MCBSP_REG_DXR1); 348 writew(buf, base + OMAP_MCBSP_REG_DXR1);
461 /* if frame sync error - clear the error */ 349 /* if frame sync error - clear the error */
462 if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) { 350 if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) {
@@ -478,8 +366,8 @@ int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
478 (XRST), 366 (XRST),
479 base + OMAP_MCBSP_REG_SPCR2); 367 base + OMAP_MCBSP_REG_SPCR2);
480 udelay(10); 368 udelay(10);
481 printk(KERN_ERR 369 dev_err(mcbsp[id].dev, "Could not write to"
482 " Could not write to McBSP Register\n"); 370 " McBSP%d Register\n", mcbsp[id].id);
483 return -2; 371 return -2;
484 } 372 }
485 } 373 }
@@ -491,7 +379,14 @@ EXPORT_SYMBOL(omap_mcbsp_pollwrite);
491 379
492int omap_mcbsp_pollread(unsigned int id, u16 *buf) 380int omap_mcbsp_pollread(unsigned int id, u16 *buf)
493{ 381{
494 u32 base = mcbsp[id].io_base; 382 u32 base;
383
384 if (!omap_mcbsp_check_valid_id(id)) {
385 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
386 return -ENODEV;
387 }
388
389 base = mcbsp[id].io_base;
495 /* if frame sync error - clear the error */ 390 /* if frame sync error - clear the error */
496 if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) { 391 if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) {
497 /* clear error */ 392 /* clear error */
@@ -512,8 +407,8 @@ int omap_mcbsp_pollread(unsigned int id, u16 *buf)
512 (RRST), 407 (RRST),
513 base + OMAP_MCBSP_REG_SPCR1); 408 base + OMAP_MCBSP_REG_SPCR1);
514 udelay(10); 409 udelay(10);
515 printk(KERN_ERR 410 dev_err(mcbsp[id].dev, "Could not read from"
516 " Could not read from McBSP Register\n"); 411 " McBSP%d Register\n", mcbsp[id].id);
517 return -2; 412 return -2;
518 } 413 }
519 } 414 }
@@ -530,12 +425,15 @@ EXPORT_SYMBOL(omap_mcbsp_pollread);
530void omap_mcbsp_xmit_word(unsigned int id, u32 word) 425void omap_mcbsp_xmit_word(unsigned int id, u32 word)
531{ 426{
532 u32 io_base; 427 u32 io_base;
533 omap_mcbsp_word_length word_length = mcbsp[id].tx_word_length; 428 omap_mcbsp_word_length word_length;
534 429
535 if (omap_mcbsp_check(id) < 0) 430 if (!omap_mcbsp_check_valid_id(id)) {
431 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
536 return; 432 return;
433 }
537 434
538 io_base = mcbsp[id].io_base; 435 io_base = mcbsp[id].io_base;
436 word_length = mcbsp[id].tx_word_length;
539 437
540 wait_for_completion(&(mcbsp[id].tx_irq_completion)); 438 wait_for_completion(&(mcbsp[id].tx_irq_completion));
541 439
@@ -549,11 +447,14 @@ u32 omap_mcbsp_recv_word(unsigned int id)
549{ 447{
550 u32 io_base; 448 u32 io_base;
551 u16 word_lsb, word_msb = 0; 449 u16 word_lsb, word_msb = 0;
552 omap_mcbsp_word_length word_length = mcbsp[id].rx_word_length; 450 omap_mcbsp_word_length word_length;
553 451
554 if (omap_mcbsp_check(id) < 0) 452 if (!omap_mcbsp_check_valid_id(id)) {
555 return -EINVAL; 453 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
454 return -ENODEV;
455 }
556 456
457 word_length = mcbsp[id].rx_word_length;
557 io_base = mcbsp[id].io_base; 458 io_base = mcbsp[id].io_base;
558 459
559 wait_for_completion(&(mcbsp[id].rx_irq_completion)); 460 wait_for_completion(&(mcbsp[id].rx_irq_completion));
@@ -568,11 +469,20 @@ EXPORT_SYMBOL(omap_mcbsp_recv_word);
568 469
569int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) 470int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
570{ 471{
571 u32 io_base = mcbsp[id].io_base; 472 u32 io_base;
572 omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length; 473 omap_mcbsp_word_length tx_word_length;
573 omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length; 474 omap_mcbsp_word_length rx_word_length;
574 u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0; 475 u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
575 476
477 if (!omap_mcbsp_check_valid_id(id)) {
478 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
479 return -ENODEV;
480 }
481
482 io_base = mcbsp[id].io_base;
483 tx_word_length = mcbsp[id].tx_word_length;
484 rx_word_length = mcbsp[id].rx_word_length;
485
576 if (tx_word_length != rx_word_length) 486 if (tx_word_length != rx_word_length)
577 return -EINVAL; 487 return -EINVAL;
578 488
@@ -586,7 +496,8 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
586 udelay(10); 496 udelay(10);
587 OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); 497 OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);
588 udelay(10); 498 udelay(10);
589 printk(KERN_ERR "McBSP transmitter not ready\n"); 499 dev_err(mcbsp[id].dev, "McBSP%d transmitter not "
500 "ready\n", mcbsp[id].id);
590 return -EAGAIN; 501 return -EAGAIN;
591 } 502 }
592 } 503 }
@@ -606,7 +517,8 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
606 udelay(10); 517 udelay(10);
607 OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); 518 OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);
608 udelay(10); 519 udelay(10);
609 printk(KERN_ERR "McBSP receiver not ready\n"); 520 dev_err(mcbsp[id].dev, "McBSP%d receiver not "
521 "ready\n", mcbsp[id].id);
610 return -EAGAIN; 522 return -EAGAIN;
611 } 523 }
612 } 524 }
@@ -622,11 +534,20 @@ EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll);
622 534
623int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word) 535int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
624{ 536{
625 u32 io_base = mcbsp[id].io_base, clock_word = 0; 537 u32 io_base, clock_word = 0;
626 omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length; 538 omap_mcbsp_word_length tx_word_length;
627 omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length; 539 omap_mcbsp_word_length rx_word_length;
628 u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0; 540 u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
629 541
542 if (!omap_mcbsp_check_valid_id(id)) {
543 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
544 return -ENODEV;
545 }
546
547 io_base = mcbsp[id].io_base;
548 tx_word_length = mcbsp[id].tx_word_length;
549 rx_word_length = mcbsp[id].rx_word_length;
550
630 if (tx_word_length != rx_word_length) 551 if (tx_word_length != rx_word_length)
631 return -EINVAL; 552 return -EINVAL;
632 553
@@ -640,7 +561,8 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
640 udelay(10); 561 udelay(10);
641 OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); 562 OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);
642 udelay(10); 563 udelay(10);
643 printk(KERN_ERR "McBSP transmitter not ready\n"); 564 dev_err(mcbsp[id].dev, "McBSP%d transmitter not "
565 "ready\n", mcbsp[id].id);
644 return -EAGAIN; 566 return -EAGAIN;
645 } 567 }
646 } 568 }
@@ -660,7 +582,8 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
660 udelay(10); 582 udelay(10);
661 OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); 583 OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);
662 udelay(10); 584 udelay(10);
663 printk(KERN_ERR "McBSP receiver not ready\n"); 585 dev_err(mcbsp[id].dev, "McBSP%d receiver not "
586 "ready\n", mcbsp[id].id);
664 return -EAGAIN; 587 return -EAGAIN;
665 } 588 }
666 } 589 }
@@ -691,20 +614,24 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer,
691 int dest_port = 0; 614 int dest_port = 0;
692 int sync_dev = 0; 615 int sync_dev = 0;
693 616
694 if (omap_mcbsp_check(id) < 0) 617 if (!omap_mcbsp_check_valid_id(id)) {
695 return -EINVAL; 618 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
619 return -ENODEV;
620 }
696 621
697 if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX", 622 if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX",
698 omap_mcbsp_tx_dma_callback, 623 omap_mcbsp_tx_dma_callback,
699 &mcbsp[id], 624 &mcbsp[id],
700 &dma_tx_ch)) { 625 &dma_tx_ch)) {
701 printk(KERN_ERR "OMAP-McBSP: Unable to request DMA channel for" 626 dev_err(mcbsp[id].dev, " Unable to request DMA channel for "
702 " McBSP%d TX. Trying IRQ based TX\n", id + 1); 627 "McBSP%d TX. Trying IRQ based TX\n",
628 mcbsp[id].id);
703 return -EAGAIN; 629 return -EAGAIN;
704 } 630 }
705 mcbsp[id].dma_tx_lch = dma_tx_ch; 631 mcbsp[id].dma_tx_lch = dma_tx_ch;
706 632
707 DBG("TX DMA on channel %d\n", dma_tx_ch); 633 dev_err(mcbsp[id].dev, "McBSP%d TX DMA on channel %d\n", mcbsp[id].id,
634 dma_tx_ch);
708 635
709 init_completion(&(mcbsp[id].tx_dma_completion)); 636 init_completion(&(mcbsp[id].tx_dma_completion));
710 637
@@ -712,7 +639,7 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer,
712 src_port = OMAP_DMA_PORT_TIPB; 639 src_port = OMAP_DMA_PORT_TIPB;
713 dest_port = OMAP_DMA_PORT_EMIFF; 640 dest_port = OMAP_DMA_PORT_EMIFF;
714 } 641 }
715 if (cpu_is_omap24xx()) 642 if (cpu_class_is_omap2())
716 sync_dev = mcbsp[id].dma_tx_sync; 643 sync_dev = mcbsp[id].dma_tx_sync;
717 644
718 omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch, 645 omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch,
@@ -748,20 +675,24 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer,
748 int dest_port = 0; 675 int dest_port = 0;
749 int sync_dev = 0; 676 int sync_dev = 0;
750 677
751 if (omap_mcbsp_check(id) < 0) 678 if (!omap_mcbsp_check_valid_id(id)) {
752 return -EINVAL; 679 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
680 return -ENODEV;
681 }
753 682
754 if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX", 683 if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX",
755 omap_mcbsp_rx_dma_callback, 684 omap_mcbsp_rx_dma_callback,
756 &mcbsp[id], 685 &mcbsp[id],
757 &dma_rx_ch)) { 686 &dma_rx_ch)) {
758 printk(KERN_ERR "Unable to request DMA channel for McBSP%d RX." 687 dev_err(mcbsp[id].dev, "Unable to request DMA channel for "
759 " Trying IRQ based RX\n", id + 1); 688 "McBSP%d RX. Trying IRQ based RX\n",
689 mcbsp[id].id);
760 return -EAGAIN; 690 return -EAGAIN;
761 } 691 }
762 mcbsp[id].dma_rx_lch = dma_rx_ch; 692 mcbsp[id].dma_rx_lch = dma_rx_ch;
763 693
764 DBG("RX DMA on channel %d\n", dma_rx_ch); 694 dev_err(mcbsp[id].dev, "McBSP%d RX DMA on channel %d\n", mcbsp[id].id,
695 dma_rx_ch);
765 696
766 init_completion(&(mcbsp[id].rx_dma_completion)); 697 init_completion(&(mcbsp[id].rx_dma_completion));
767 698
@@ -769,7 +700,7 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer,
769 src_port = OMAP_DMA_PORT_TIPB; 700 src_port = OMAP_DMA_PORT_TIPB;
770 dest_port = OMAP_DMA_PORT_EMIFF; 701 dest_port = OMAP_DMA_PORT_EMIFF;
771 } 702 }
772 if (cpu_is_omap24xx()) 703 if (cpu_class_is_omap2())
773 sync_dev = mcbsp[id].dma_rx_sync; 704 sync_dev = mcbsp[id].dma_rx_sync;
774 705
775 omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch, 706 omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch,
@@ -808,8 +739,10 @@ void omap_mcbsp_set_spi_mode(unsigned int id,
808{ 739{
809 struct omap_mcbsp_reg_cfg mcbsp_cfg; 740 struct omap_mcbsp_reg_cfg mcbsp_cfg;
810 741
811 if (omap_mcbsp_check(id) < 0) 742 if (!omap_mcbsp_check_valid_id(id)) {
743 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
812 return; 744 return;
745 }
813 746
814 memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg)); 747 memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg));
815 748
@@ -870,182 +803,93 @@ EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
870 * McBSP1 and McBSP3 are directly mapped on 1610 and 1510. 803 * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
871 * 730 has only 2 McBSP, and both of them are MPU peripherals. 804 * 730 has only 2 McBSP, and both of them are MPU peripherals.
872 */ 805 */
873struct omap_mcbsp_info { 806static int __init omap_mcbsp_probe(struct platform_device *pdev)
874 u32 virt_base; 807{
875 u8 dma_rx_sync, dma_tx_sync; 808 struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data;
876 u16 rx_irq, tx_irq; 809 int id = pdev->id - 1;
877}; 810 int ret = 0;
878 811
879#ifdef CONFIG_ARCH_OMAP730 812 if (!pdata) {
880static const struct omap_mcbsp_info mcbsp_730[] = { 813 dev_err(&pdev->dev, "McBSP device initialized without"
881 [0] = { .virt_base = io_p2v(OMAP730_MCBSP1_BASE), 814 "platform data\n");
882 .dma_rx_sync = OMAP_DMA_MCBSP1_RX, 815 ret = -EINVAL;
883 .dma_tx_sync = OMAP_DMA_MCBSP1_TX, 816 goto exit;
884 .rx_irq = INT_730_McBSP1RX, 817 }
885 .tx_irq = INT_730_McBSP1TX }, 818
886 [1] = { .virt_base = io_p2v(OMAP730_MCBSP2_BASE), 819 dev_dbg(&pdev->dev, "Initializing OMAP McBSP (%d).\n", pdev->id);
887 .dma_rx_sync = OMAP_DMA_MCBSP3_RX, 820
888 .dma_tx_sync = OMAP_DMA_MCBSP3_TX, 821 if (id >= OMAP_MAX_MCBSP_COUNT) {
889 .rx_irq = INT_730_McBSP2RX, 822 dev_err(&pdev->dev, "Invalid McBSP device id (%d)\n", id);
890 .tx_irq = INT_730_McBSP2TX }, 823 ret = -EINVAL;
891}; 824 goto exit;
892#endif 825 }
893 826
894#ifdef CONFIG_ARCH_OMAP15XX 827 spin_lock_init(&mcbsp[id].lock);
895static const struct omap_mcbsp_info mcbsp_1510[] = { 828 mcbsp[id].id = id + 1;
896 [0] = { .virt_base = OMAP1510_MCBSP1_BASE, 829 mcbsp[id].free = 1;
897 .dma_rx_sync = OMAP_DMA_MCBSP1_RX, 830 mcbsp[id].dma_tx_lch = -1;
898 .dma_tx_sync = OMAP_DMA_MCBSP1_TX, 831 mcbsp[id].dma_rx_lch = -1;
899 .rx_irq = INT_McBSP1RX, 832
900 .tx_irq = INT_McBSP1TX }, 833 mcbsp[id].io_base = pdata->virt_base;
901 [1] = { .virt_base = io_p2v(OMAP1510_MCBSP2_BASE), 834 /* Default I/O is IRQ based */
902 .dma_rx_sync = OMAP_DMA_MCBSP2_RX, 835 mcbsp[id].io_type = OMAP_MCBSP_IRQ_IO;
903 .dma_tx_sync = OMAP_DMA_MCBSP2_TX, 836 mcbsp[id].tx_irq = pdata->tx_irq;
904 .rx_irq = INT_1510_SPI_RX, 837 mcbsp[id].rx_irq = pdata->rx_irq;
905 .tx_irq = INT_1510_SPI_TX }, 838 mcbsp[id].dma_rx_sync = pdata->dma_rx_sync;
906 [2] = { .virt_base = OMAP1510_MCBSP3_BASE, 839 mcbsp[id].dma_tx_sync = pdata->dma_tx_sync;
907 .dma_rx_sync = OMAP_DMA_MCBSP3_RX, 840
908 .dma_tx_sync = OMAP_DMA_MCBSP3_TX, 841 if (pdata->clk_name)
909 .rx_irq = INT_McBSP3RX, 842 mcbsp[id].clk = clk_get(&pdev->dev, pdata->clk_name);
910 .tx_irq = INT_McBSP3TX }, 843 if (IS_ERR(mcbsp[id].clk)) {
911}; 844 mcbsp[id].free = 0;
912#endif 845 dev_err(&pdev->dev,
913 846 "Invalid clock configuration for McBSP%d.\n",
914#if defined(CONFIG_ARCH_OMAP16XX) 847 mcbsp[id].id);
915static const struct omap_mcbsp_info mcbsp_1610[] = { 848 ret = -EINVAL;
916 [0] = { .virt_base = OMAP1610_MCBSP1_BASE, 849 goto exit;
917 .dma_rx_sync = OMAP_DMA_MCBSP1_RX, 850 }
918 .dma_tx_sync = OMAP_DMA_MCBSP1_TX, 851
919 .rx_irq = INT_McBSP1RX, 852 mcbsp[id].pdata = pdata;
920 .tx_irq = INT_McBSP1TX }, 853 mcbsp[id].dev = &pdev->dev;
921 [1] = { .virt_base = io_p2v(OMAP1610_MCBSP2_BASE), 854 platform_set_drvdata(pdev, &mcbsp[id]);
922 .dma_rx_sync = OMAP_DMA_MCBSP2_RX, 855
923 .dma_tx_sync = OMAP_DMA_MCBSP2_TX, 856exit:
924 .rx_irq = INT_1610_McBSP2_RX, 857 return ret;
925 .tx_irq = INT_1610_McBSP2_TX }, 858}
926 [2] = { .virt_base = OMAP1610_MCBSP3_BASE,
927 .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
928 .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
929 .rx_irq = INT_McBSP3RX,
930 .tx_irq = INT_McBSP3TX },
931};
932#endif
933
934#if defined(CONFIG_ARCH_OMAP24XX)
935static const struct omap_mcbsp_info mcbsp_24xx[] = {
936 [0] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP1_BASE),
937 .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX,
938 .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX,
939 .rx_irq = INT_24XX_MCBSP1_IRQ_RX,
940 .tx_irq = INT_24XX_MCBSP1_IRQ_TX,
941 },
942 [1] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP2_BASE),
943 .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX,
944 .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX,
945 .rx_irq = INT_24XX_MCBSP2_IRQ_RX,
946 .tx_irq = INT_24XX_MCBSP2_IRQ_TX,
947 },
948};
949#endif
950 859
951static int __init omap_mcbsp_init(void) 860static int omap_mcbsp_remove(struct platform_device *pdev)
952{ 861{
953 int mcbsp_count = 0, i; 862 struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
954 static const struct omap_mcbsp_info *mcbsp_info;
955 863
956 printk(KERN_INFO "Initializing OMAP McBSP system\n"); 864 platform_set_drvdata(pdev, NULL);
865 if (mcbsp) {
957 866
958#ifdef CONFIG_ARCH_OMAP1 867 if (mcbsp->pdata && mcbsp->pdata->ops &&
959 mcbsp_dsp_ck = clk_get(0, "dsp_ck"); 868 mcbsp->pdata->ops->free)
960 if (IS_ERR(mcbsp_dsp_ck)) { 869 mcbsp->pdata->ops->free(mcbsp->id);
961 printk(KERN_ERR "mcbsp: could not acquire dsp_ck handle.\n");
962 return PTR_ERR(mcbsp_dsp_ck);
963 }
964 mcbsp_api_ck = clk_get(0, "api_ck");
965 if (IS_ERR(mcbsp_api_ck)) {
966 printk(KERN_ERR "mcbsp: could not acquire api_ck handle.\n");
967 return PTR_ERR(mcbsp_api_ck);
968 }
969 mcbsp_dspxor_ck = clk_get(0, "dspxor_ck");
970 if (IS_ERR(mcbsp_dspxor_ck)) {
971 printk(KERN_ERR "mcbsp: could not acquire dspxor_ck handle.\n");
972 return PTR_ERR(mcbsp_dspxor_ck);
973 }
974#endif
975#ifdef CONFIG_ARCH_OMAP2
976 mcbsp1_ick = clk_get(0, "mcbsp1_ick");
977 if (IS_ERR(mcbsp1_ick)) {
978 printk(KERN_ERR "mcbsp: could not acquire "
979 "mcbsp1_ick handle.\n");
980 return PTR_ERR(mcbsp1_ick);
981 }
982 mcbsp1_fck = clk_get(0, "mcbsp1_fck");
983 if (IS_ERR(mcbsp1_fck)) {
984 printk(KERN_ERR "mcbsp: could not acquire "
985 "mcbsp1_fck handle.\n");
986 return PTR_ERR(mcbsp1_fck);
987 }
988 mcbsp2_ick = clk_get(0, "mcbsp2_ick");
989 if (IS_ERR(mcbsp2_ick)) {
990 printk(KERN_ERR "mcbsp: could not acquire "
991 "mcbsp2_ick handle.\n");
992 return PTR_ERR(mcbsp2_ick);
993 }
994 mcbsp2_fck = clk_get(0, "mcbsp2_fck");
995 if (IS_ERR(mcbsp2_fck)) {
996 printk(KERN_ERR "mcbsp: could not acquire "
997 "mcbsp2_fck handle.\n");
998 return PTR_ERR(mcbsp2_fck);
999 }
1000#endif
1001 870
1002#ifdef CONFIG_ARCH_OMAP730 871 clk_disable(mcbsp->clk);
1003 if (cpu_is_omap730()) { 872 clk_put(mcbsp->clk);
1004 mcbsp_info = mcbsp_730; 873
1005 mcbsp_count = ARRAY_SIZE(mcbsp_730); 874 mcbsp->clk = NULL;
1006 } 875 mcbsp->free = 0;
1007#endif 876 mcbsp->dev = NULL;
1008#ifdef CONFIG_ARCH_OMAP15XX
1009 if (cpu_is_omap15xx()) {
1010 mcbsp_info = mcbsp_1510;
1011 mcbsp_count = ARRAY_SIZE(mcbsp_1510);
1012 }
1013#endif
1014#if defined(CONFIG_ARCH_OMAP16XX)
1015 if (cpu_is_omap16xx()) {
1016 mcbsp_info = mcbsp_1610;
1017 mcbsp_count = ARRAY_SIZE(mcbsp_1610);
1018 }
1019#endif
1020#if defined(CONFIG_ARCH_OMAP24XX)
1021 if (cpu_is_omap24xx()) {
1022 mcbsp_info = mcbsp_24xx;
1023 mcbsp_count = ARRAY_SIZE(mcbsp_24xx);
1024 omap2_mcbsp2_mux_setup();
1025 }
1026#endif
1027 for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) {
1028 if (i >= mcbsp_count) {
1029 mcbsp[i].io_base = 0;
1030 mcbsp[i].free = 0;
1031 continue;
1032 }
1033 mcbsp[i].id = i + 1;
1034 mcbsp[i].free = 1;
1035 mcbsp[i].dma_tx_lch = -1;
1036 mcbsp[i].dma_rx_lch = -1;
1037
1038 mcbsp[i].io_base = mcbsp_info[i].virt_base;
1039 /* Default I/O is IRQ based */
1040 mcbsp[i].io_type = OMAP_MCBSP_IRQ_IO;
1041 mcbsp[i].tx_irq = mcbsp_info[i].tx_irq;
1042 mcbsp[i].rx_irq = mcbsp_info[i].rx_irq;
1043 mcbsp[i].dma_rx_sync = mcbsp_info[i].dma_rx_sync;
1044 mcbsp[i].dma_tx_sync = mcbsp_info[i].dma_tx_sync;
1045 spin_lock_init(&mcbsp[i].lock);
1046 } 877 }
1047 878
1048 return 0; 879 return 0;
1049} 880}
1050 881
1051arch_initcall(omap_mcbsp_init); 882static struct platform_driver omap_mcbsp_driver = {
883 .probe = omap_mcbsp_probe,
884 .remove = omap_mcbsp_remove,
885 .driver = {
886 .name = "omap-mcbsp",
887 },
888};
889
890int __init omap_mcbsp_init(void)
891{
892 /* Register the McBSP driver */
893 return platform_driver_register(&omap_mcbsp_driver);
894}
895