mcbsp.c 45.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*
 * linux/arch/arm/plat-omap/mcbsp.c
 *
 * Copyright (C) 2004 Nokia Corporation
 * Author: Samuel Ortiz <samuel.ortiz@nokia.com>
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * Multichannel mode not supported.
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
18
#include <linux/platform_device.h>
19 20 21 22
#include <linux/wait.h>
#include <linux/completion.h>
#include <linux/interrupt.h>
#include <linux/err.h>
23
#include <linux/clk.h>
24
#include <linux/delay.h>
25
#include <linux/io.h>
26
#include <linux/slab.h>
27

28 29
#include <plat/dma.h>
#include <plat/mcbsp.h>
30

31 32
/* XXX These "sideways" includes are a sign that something is wrong */
#include "../mach-omap2/cm2xxx_3xxx.h"
33 34
#include "../mach-omap2/cm-regbits-34xx.h"

35
struct omap_mcbsp **mcbsp_ptr;
36
int omap_mcbsp_count, omap_mcbsp_cache_size;
37

38
static void omap_mcbsp_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
39
{
40 41
	if (cpu_class_is_omap1()) {
		((u16 *)mcbsp->reg_cache)[reg / sizeof(u16)] = (u16)val;
42
		__raw_writew((u16)val, mcbsp->io_base + reg);
43 44 45 46 47
	} else if (cpu_is_omap2420()) {
		((u16 *)mcbsp->reg_cache)[reg / sizeof(u32)] = (u16)val;
		__raw_writew((u16)val, mcbsp->io_base + reg);
	} else {
		((u32 *)mcbsp->reg_cache)[reg / sizeof(u32)] = val;
48
		__raw_writel(val, mcbsp->io_base + reg);
49
	}
50 51
}

52
static int omap_mcbsp_read(struct omap_mcbsp *mcbsp, u16 reg, bool from_cache)
53
{
54 55 56 57 58 59 60 61 62 63
	if (cpu_class_is_omap1()) {
		return !from_cache ? __raw_readw(mcbsp->io_base + reg) :
				((u16 *)mcbsp->reg_cache)[reg / sizeof(u16)];
	} else if (cpu_is_omap2420()) {
		return !from_cache ? __raw_readw(mcbsp->io_base + reg) :
				((u16 *)mcbsp->reg_cache)[reg / sizeof(u32)];
	} else {
		return !from_cache ? __raw_readl(mcbsp->io_base + reg) :
				((u32 *)mcbsp->reg_cache)[reg / sizeof(u32)];
	}
64 65
}

66
#ifdef CONFIG_ARCH_OMAP3
67
static void omap_mcbsp_st_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
68 69 70 71
{
	__raw_writel(val, mcbsp->st_data->io_base_st + reg);
}

72
static int omap_mcbsp_st_read(struct omap_mcbsp *mcbsp, u16 reg)
73 74 75 76 77
{
	return __raw_readl(mcbsp->st_data->io_base_st + reg);
}
#endif

78
#define MCBSP_READ(mcbsp, reg) \
79
		omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 0)
80 81
#define MCBSP_WRITE(mcbsp, reg, val) \
		omap_mcbsp_write(mcbsp, OMAP_MCBSP_REG_##reg, val)
82 83
#define MCBSP_READ_CACHE(mcbsp, reg) \
		omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 1)
84

85 86 87 88 89
#define MCBSP_ST_READ(mcbsp, reg) \
			omap_mcbsp_st_read(mcbsp, OMAP_ST_REG_##reg)
#define MCBSP_ST_WRITE(mcbsp, reg, val) \
			omap_mcbsp_st_write(mcbsp, OMAP_ST_REG_##reg, val)

90 91
static void omap_mcbsp_dump_reg(u8 id)
{
92 93 94 95
	struct omap_mcbsp *mcbsp = id_to_mcbsp_ptr(id);

	dev_dbg(mcbsp->dev, "**** McBSP%d regs ****\n", mcbsp->id);
	dev_dbg(mcbsp->dev, "DRR2:  0x%04x\n",
96
			MCBSP_READ(mcbsp, DRR2));
97
	dev_dbg(mcbsp->dev, "DRR1:  0x%04x\n",
98
			MCBSP_READ(mcbsp, DRR1));
99
	dev_dbg(mcbsp->dev, "DXR2:  0x%04x\n",
100
			MCBSP_READ(mcbsp, DXR2));
101
	dev_dbg(mcbsp->dev, "DXR1:  0x%04x\n",
102
			MCBSP_READ(mcbsp, DXR1));
103
	dev_dbg(mcbsp->dev, "SPCR2: 0x%04x\n",
104
			MCBSP_READ(mcbsp, SPCR2));
105
	dev_dbg(mcbsp->dev, "SPCR1: 0x%04x\n",
106
			MCBSP_READ(mcbsp, SPCR1));
107
	dev_dbg(mcbsp->dev, "RCR2:  0x%04x\n",
108
			MCBSP_READ(mcbsp, RCR2));
109
	dev_dbg(mcbsp->dev, "RCR1:  0x%04x\n",
110
			MCBSP_READ(mcbsp, RCR1));
111
	dev_dbg(mcbsp->dev, "XCR2:  0x%04x\n",
112
			MCBSP_READ(mcbsp, XCR2));
113
	dev_dbg(mcbsp->dev, "XCR1:  0x%04x\n",
114
			MCBSP_READ(mcbsp, XCR1));
115
	dev_dbg(mcbsp->dev, "SRGR2: 0x%04x\n",
116
			MCBSP_READ(mcbsp, SRGR2));
117
	dev_dbg(mcbsp->dev, "SRGR1: 0x%04x\n",
118
			MCBSP_READ(mcbsp, SRGR1));
119
	dev_dbg(mcbsp->dev, "PCR0:  0x%04x\n",
120
			MCBSP_READ(mcbsp, PCR0));
121
	dev_dbg(mcbsp->dev, "***********************\n");
122 123
}

124
static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
125
{
126
	struct omap_mcbsp *mcbsp_tx = dev_id;
127
	u16 irqst_spcr2;
128

129
	irqst_spcr2 = MCBSP_READ(mcbsp_tx, SPCR2);
130
	dev_dbg(mcbsp_tx->dev, "TX IRQ callback : 0x%x\n", irqst_spcr2);
131

132 133 134 135
	if (irqst_spcr2 & XSYNC_ERR) {
		dev_err(mcbsp_tx->dev, "TX Frame Sync Error! : 0x%x\n",
			irqst_spcr2);
		/* Writing zero to XSYNC_ERR clears the IRQ */
136
		MCBSP_WRITE(mcbsp_tx, SPCR2, MCBSP_READ_CACHE(mcbsp_tx, SPCR2));
137 138 139
	} else {
		complete(&mcbsp_tx->tx_irq_completion);
	}
140

141 142 143
	return IRQ_HANDLED;
}

144
static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)
145
{
146
	struct omap_mcbsp *mcbsp_rx = dev_id;
147 148
	u16 irqst_spcr1;

149
	irqst_spcr1 = MCBSP_READ(mcbsp_rx, SPCR1);
150 151 152 153 154 155
	dev_dbg(mcbsp_rx->dev, "RX IRQ callback : 0x%x\n", irqst_spcr1);

	if (irqst_spcr1 & RSYNC_ERR) {
		dev_err(mcbsp_rx->dev, "RX Frame Sync Error! : 0x%x\n",
			irqst_spcr1);
		/* Writing zero to RSYNC_ERR clears the IRQ */
156
		MCBSP_WRITE(mcbsp_rx, SPCR1, MCBSP_READ_CACHE(mcbsp_rx, SPCR1));
157
	} else {
158
		complete(&mcbsp_rx->rx_irq_completion);
159
	}
160

161 162 163 164 165
	return IRQ_HANDLED;
}

static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data)
{
166
	struct omap_mcbsp *mcbsp_dma_tx = data;
167

168
	dev_dbg(mcbsp_dma_tx->dev, "TX DMA callback : 0x%x\n",
169
		MCBSP_READ(mcbsp_dma_tx, SPCR2));
170 171 172 173 174 175 176 177 178 179

	/* We can free the channels */
	omap_free_dma(mcbsp_dma_tx->dma_tx_lch);
	mcbsp_dma_tx->dma_tx_lch = -1;

	complete(&mcbsp_dma_tx->tx_dma_completion);
}

static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
{
180
	struct omap_mcbsp *mcbsp_dma_rx = data;
181

182
	dev_dbg(mcbsp_dma_rx->dev, "RX DMA callback : 0x%x\n",
183
		MCBSP_READ(mcbsp_dma_rx, SPCR2));
184 185 186 187 188 189 190 191 192 193 194 195 196 197

	/* We can free the channels */
	omap_free_dma(mcbsp_dma_rx->dma_rx_lch);
	mcbsp_dma_rx->dma_rx_lch = -1;

	complete(&mcbsp_dma_rx->rx_dma_completion);
}

/*
 * omap_mcbsp_config simply write a config to the
 * appropriate McBSP.
 * You either call this function or set the McBSP registers
 * by yourself before calling omap_mcbsp_start().
 */
198
void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config)
199
{
200
	struct omap_mcbsp *mcbsp;
201

202 203 204 205
	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
		return;
	}
206
	mcbsp = id_to_mcbsp_ptr(id);
207

208 209
	dev_dbg(mcbsp->dev, "Configuring McBSP%d  phys_base: 0x%08lx\n",
			mcbsp->id, mcbsp->phys_base);
210 211

	/* We write the given config */
212 213 214 215 216 217 218 219 220 221 222
	MCBSP_WRITE(mcbsp, SPCR2, config->spcr2);
	MCBSP_WRITE(mcbsp, SPCR1, config->spcr1);
	MCBSP_WRITE(mcbsp, RCR2, config->rcr2);
	MCBSP_WRITE(mcbsp, RCR1, config->rcr1);
	MCBSP_WRITE(mcbsp, XCR2, config->xcr2);
	MCBSP_WRITE(mcbsp, XCR1, config->xcr1);
	MCBSP_WRITE(mcbsp, SRGR2, config->srgr2);
	MCBSP_WRITE(mcbsp, SRGR1, config->srgr1);
	MCBSP_WRITE(mcbsp, MCR2, config->mcr2);
	MCBSP_WRITE(mcbsp, MCR1, config->mcr1);
	MCBSP_WRITE(mcbsp, PCR0, config->pcr0);
S
Syed Rafiuddin 已提交
223
	if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
224 225
		MCBSP_WRITE(mcbsp, XCCR, config->xccr);
		MCBSP_WRITE(mcbsp, RCCR, config->rccr);
226
	}
227
}
228
EXPORT_SYMBOL(omap_mcbsp_config);
229

230
#ifdef CONFIG_ARCH_OMAP3
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481
static void omap_st_on(struct omap_mcbsp *mcbsp)
{
	unsigned int w;

	/*
	 * Sidetone uses McBSP ICLK - which must not idle when sidetones
	 * are enabled or sidetones start sounding ugly.
	 */
	w = cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
	w &= ~(1 << (mcbsp->id - 2));
	cm_write_mod_reg(w, OMAP3430_PER_MOD, CM_AUTOIDLE);

	/* Enable McBSP Sidetone */
	w = MCBSP_READ(mcbsp, SSELCR);
	MCBSP_WRITE(mcbsp, SSELCR, w | SIDETONEEN);

	w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
	MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w & ~(ST_AUTOIDLE));

	/* Enable Sidetone from Sidetone Core */
	w = MCBSP_ST_READ(mcbsp, SSELCR);
	MCBSP_ST_WRITE(mcbsp, SSELCR, w | ST_SIDETONEEN);
}

static void omap_st_off(struct omap_mcbsp *mcbsp)
{
	unsigned int w;

	w = MCBSP_ST_READ(mcbsp, SSELCR);
	MCBSP_ST_WRITE(mcbsp, SSELCR, w & ~(ST_SIDETONEEN));

	w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
	MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w | ST_AUTOIDLE);

	w = MCBSP_READ(mcbsp, SSELCR);
	MCBSP_WRITE(mcbsp, SSELCR, w & ~(SIDETONEEN));

	w = cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
	w |= 1 << (mcbsp->id - 2);
	cm_write_mod_reg(w, OMAP3430_PER_MOD, CM_AUTOIDLE);
}

static void omap_st_fir_write(struct omap_mcbsp *mcbsp, s16 *fir)
{
	u16 val, i;

	val = MCBSP_ST_READ(mcbsp, SYSCONFIG);
	MCBSP_ST_WRITE(mcbsp, SYSCONFIG, val & ~(ST_AUTOIDLE));

	val = MCBSP_ST_READ(mcbsp, SSELCR);

	if (val & ST_COEFFWREN)
		MCBSP_ST_WRITE(mcbsp, SSELCR, val & ~(ST_COEFFWREN));

	MCBSP_ST_WRITE(mcbsp, SSELCR, val | ST_COEFFWREN);

	for (i = 0; i < 128; i++)
		MCBSP_ST_WRITE(mcbsp, SFIRCR, fir[i]);

	i = 0;

	val = MCBSP_ST_READ(mcbsp, SSELCR);
	while (!(val & ST_COEFFWRDONE) && (++i < 1000))
		val = MCBSP_ST_READ(mcbsp, SSELCR);

	MCBSP_ST_WRITE(mcbsp, SSELCR, val & ~(ST_COEFFWREN));

	if (i == 1000)
		dev_err(mcbsp->dev, "McBSP FIR load error!\n");
}

static void omap_st_chgain(struct omap_mcbsp *mcbsp)
{
	u16 w;
	struct omap_mcbsp_st_data *st_data = mcbsp->st_data;

	w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
	MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w & ~(ST_AUTOIDLE));

	w = MCBSP_ST_READ(mcbsp, SSELCR);

	MCBSP_ST_WRITE(mcbsp, SGAINCR, ST_CH0GAIN(st_data->ch0gain) | \
		      ST_CH1GAIN(st_data->ch1gain));
}

int omap_st_set_chgain(unsigned int id, int channel, s16 chgain)
{
	struct omap_mcbsp *mcbsp;
	struct omap_mcbsp_st_data *st_data;
	int ret = 0;

	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
		return -ENODEV;
	}

	mcbsp = id_to_mcbsp_ptr(id);
	st_data = mcbsp->st_data;

	if (!st_data)
		return -ENOENT;

	spin_lock_irq(&mcbsp->lock);
	if (channel == 0)
		st_data->ch0gain = chgain;
	else if (channel == 1)
		st_data->ch1gain = chgain;
	else
		ret = -EINVAL;

	if (st_data->enabled)
		omap_st_chgain(mcbsp);
	spin_unlock_irq(&mcbsp->lock);

	return ret;
}
EXPORT_SYMBOL(omap_st_set_chgain);

int omap_st_get_chgain(unsigned int id, int channel, s16 *chgain)
{
	struct omap_mcbsp *mcbsp;
	struct omap_mcbsp_st_data *st_data;
	int ret = 0;

	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
		return -ENODEV;
	}

	mcbsp = id_to_mcbsp_ptr(id);
	st_data = mcbsp->st_data;

	if (!st_data)
		return -ENOENT;

	spin_lock_irq(&mcbsp->lock);
	if (channel == 0)
		*chgain = st_data->ch0gain;
	else if (channel == 1)
		*chgain = st_data->ch1gain;
	else
		ret = -EINVAL;
	spin_unlock_irq(&mcbsp->lock);

	return ret;
}
EXPORT_SYMBOL(omap_st_get_chgain);

static int omap_st_start(struct omap_mcbsp *mcbsp)
{
	struct omap_mcbsp_st_data *st_data = mcbsp->st_data;

	if (st_data && st_data->enabled && !st_data->running) {
		omap_st_fir_write(mcbsp, st_data->taps);
		omap_st_chgain(mcbsp);

		if (!mcbsp->free) {
			omap_st_on(mcbsp);
			st_data->running = 1;
		}
	}

	return 0;
}

int omap_st_enable(unsigned int id)
{
	struct omap_mcbsp *mcbsp;
	struct omap_mcbsp_st_data *st_data;

	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
		return -ENODEV;
	}

	mcbsp = id_to_mcbsp_ptr(id);
	st_data = mcbsp->st_data;

	if (!st_data)
		return -ENODEV;

	spin_lock_irq(&mcbsp->lock);
	st_data->enabled = 1;
	omap_st_start(mcbsp);
	spin_unlock_irq(&mcbsp->lock);

	return 0;
}
EXPORT_SYMBOL(omap_st_enable);

static int omap_st_stop(struct omap_mcbsp *mcbsp)
{
	struct omap_mcbsp_st_data *st_data = mcbsp->st_data;

	if (st_data && st_data->running) {
		if (!mcbsp->free) {
			omap_st_off(mcbsp);
			st_data->running = 0;
		}
	}

	return 0;
}

int omap_st_disable(unsigned int id)
{
	struct omap_mcbsp *mcbsp;
	struct omap_mcbsp_st_data *st_data;
	int ret = 0;

	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
		return -ENODEV;
	}

	mcbsp = id_to_mcbsp_ptr(id);
	st_data = mcbsp->st_data;

	if (!st_data)
		return -ENODEV;

	spin_lock_irq(&mcbsp->lock);
	omap_st_stop(mcbsp);
	st_data->enabled = 0;
	spin_unlock_irq(&mcbsp->lock);

	return ret;
}
EXPORT_SYMBOL(omap_st_disable);

int omap_st_is_enabled(unsigned int id)
{
	struct omap_mcbsp *mcbsp;
	struct omap_mcbsp_st_data *st_data;

	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
		return -ENODEV;
	}

	mcbsp = id_to_mcbsp_ptr(id);
	st_data = mcbsp->st_data;

	if (!st_data)
		return -ENODEV;


	return st_data->enabled;
}
EXPORT_SYMBOL(omap_st_is_enabled);

482
/*
483 484 485
 * omap_mcbsp_set_rx_threshold configures the transmit threshold in words.
 * The threshold parameter is 1 based, and it is converted (threshold - 1)
 * for the THRSH2 register.
486 487 488 489 490
 */
void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
{
	struct omap_mcbsp *mcbsp;

491
	if (!cpu_is_omap34xx() && !cpu_is_omap44xx())
492 493 494 495 496 497 498 499
		return;

	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
		return;
	}
	mcbsp = id_to_mcbsp_ptr(id);

500 501
	if (threshold && threshold <= mcbsp->max_tx_thres)
		MCBSP_WRITE(mcbsp, THRSH2, threshold - 1);
502 503 504 505
}
EXPORT_SYMBOL(omap_mcbsp_set_tx_threshold);

/*
506 507 508
 * omap_mcbsp_set_rx_threshold configures the receive threshold in words.
 * The threshold parameter is 1 based, and it is converted (threshold - 1)
 * for the THRSH1 register.
509 510 511 512 513
 */
void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
{
	struct omap_mcbsp *mcbsp;

514
	if (!cpu_is_omap34xx() && !cpu_is_omap44xx())
515 516 517 518 519 520 521 522
		return;

	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
		return;
	}
	mcbsp = id_to_mcbsp_ptr(id);

523 524
	if (threshold && threshold <= mcbsp->max_rx_thres)
		MCBSP_WRITE(mcbsp, THRSH1, threshold - 1);
525 526
}
EXPORT_SYMBOL(omap_mcbsp_set_rx_threshold);
527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562

/*
 * omap_mcbsp_get_max_tx_thres just return the current configured
 * maximum threshold for transmission
 */
u16 omap_mcbsp_get_max_tx_threshold(unsigned int id)
{
	struct omap_mcbsp *mcbsp;

	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
		return -ENODEV;
	}
	mcbsp = id_to_mcbsp_ptr(id);

	return mcbsp->max_tx_thres;
}
EXPORT_SYMBOL(omap_mcbsp_get_max_tx_threshold);

/*
 * omap_mcbsp_get_max_rx_thres just return the current configured
 * maximum threshold for reception
 */
u16 omap_mcbsp_get_max_rx_threshold(unsigned int id)
{
	struct omap_mcbsp *mcbsp;

	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
		return -ENODEV;
	}
	mcbsp = id_to_mcbsp_ptr(id);

	return mcbsp->max_rx_thres;
}
EXPORT_SYMBOL(omap_mcbsp_get_max_rx_threshold);
563

564 565 566 567 568 569 570 571 572 573 574 575 576 577
u16 omap_mcbsp_get_fifo_size(unsigned int id)
{
	struct omap_mcbsp *mcbsp;

	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
		return -ENODEV;
	}
	mcbsp = id_to_mcbsp_ptr(id);

	return mcbsp->pdata->buffer_size;
}
EXPORT_SYMBOL(omap_mcbsp_get_fifo_size);

578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595
/*
 * omap_mcbsp_get_tx_delay returns the number of used slots in the McBSP FIFO
 */
u16 omap_mcbsp_get_tx_delay(unsigned int id)
{
	struct omap_mcbsp *mcbsp;
	u16 buffstat;

	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
		return -ENODEV;
	}
	mcbsp = id_to_mcbsp_ptr(id);

	/* Returns the number of free locations in the buffer */
	buffstat = MCBSP_READ(mcbsp, XBUFFSTAT);

	/* Number of slots are different in McBSP ports */
596
	return mcbsp->pdata->buffer_size - buffstat;
597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627
}
EXPORT_SYMBOL(omap_mcbsp_get_tx_delay);

/*
 * omap_mcbsp_get_rx_delay returns the number of free slots in the McBSP FIFO
 * to reach the threshold value (when the DMA will be triggered to read it)
 */
u16 omap_mcbsp_get_rx_delay(unsigned int id)
{
	struct omap_mcbsp *mcbsp;
	u16 buffstat, threshold;

	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
		return -ENODEV;
	}
	mcbsp = id_to_mcbsp_ptr(id);

	/* Returns the number of used locations in the buffer */
	buffstat = MCBSP_READ(mcbsp, RBUFFSTAT);
	/* RX threshold */
	threshold = MCBSP_READ(mcbsp, THRSH1);

	/* Return the number of location till we reach the threshold limit */
	if (threshold <= buffstat)
		return 0;
	else
		return threshold - buffstat;
}
EXPORT_SYMBOL(omap_mcbsp_get_rx_delay);

628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647
/*
 * omap_mcbsp_get_dma_op_mode just return the current configured
 * operating mode for the mcbsp channel
 */
int omap_mcbsp_get_dma_op_mode(unsigned int id)
{
	struct omap_mcbsp *mcbsp;
	int dma_op_mode;

	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%u)\n", __func__, id + 1);
		return -ENODEV;
	}
	mcbsp = id_to_mcbsp_ptr(id);

	dma_op_mode = mcbsp->dma_op_mode;

	return dma_op_mode;
}
EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode);
E
Eero Nurkkala 已提交
648 649 650 651 652 653 654

static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp)
{
	/*
	 * Enable wakup behavior, smart idle and all wakeups
	 * REVISIT: some wakeups may be unnecessary
	 */
655
	if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
E
Eero Nurkkala 已提交
656 657
		u16 syscon;

658
		syscon = MCBSP_READ(mcbsp, SYSCON);
659
		syscon &= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03));
660

661 662 663
		if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) {
			syscon |= (ENAWAKEUP | SIDLEMODE(0x02) |
					CLOCKACTIVITY(0x02));
664
			MCBSP_WRITE(mcbsp, WAKEUPEN, XRDYEN | RRDYEN);
665
		} else {
666
			syscon |= SIDLEMODE(0x01);
667
		}
668

669
		MCBSP_WRITE(mcbsp, SYSCON, syscon);
E
Eero Nurkkala 已提交
670 671 672 673 674 675 676 677
	}
}

static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp)
{
	/*
	 * Disable wakup behavior, smart idle and all wakeups
	 */
678
	if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
E
Eero Nurkkala 已提交
679 680
		u16 syscon;

681
		syscon = MCBSP_READ(mcbsp, SYSCON);
682
		syscon &= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03));
683 684 685 686 687 688
		/*
		 * HW bug workaround - If no_idle mode is taken, we need to
		 * go to smart_idle before going to always_idle, or the
		 * device will not hit retention anymore.
		 */
		syscon |= SIDLEMODE(0x02);
689
		MCBSP_WRITE(mcbsp, SYSCON, syscon);
690 691

		syscon &= ~(SIDLEMODE(0x03));
692
		MCBSP_WRITE(mcbsp, SYSCON, syscon);
E
Eero Nurkkala 已提交
693

694
		MCBSP_WRITE(mcbsp, WAKEUPEN, 0);
E
Eero Nurkkala 已提交
695 696 697 698 699
	}
}
#else
static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp) {}
static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp) {}
700 701
static inline void omap_st_start(struct omap_mcbsp *mcbsp) {}
static inline void omap_st_stop(struct omap_mcbsp *mcbsp) {}
702 703
#endif

704 705 706 707 708 709
/*
 * We can choose between IRQ based or polled IO.
 * This needs to be called before omap_mcbsp_request().
 */
int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type)
{
710 711
	struct omap_mcbsp *mcbsp;

712 713 714 715
	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
		return -ENODEV;
	}
716
	mcbsp = id_to_mcbsp_ptr(id);
717

718
	spin_lock(&mcbsp->lock);
719

720 721 722 723
	if (!mcbsp->free) {
		dev_err(mcbsp->dev, "McBSP%d is currently in use\n",
			mcbsp->id);
		spin_unlock(&mcbsp->lock);
724 725 726
		return -EINVAL;
	}

727
	mcbsp->io_type = io_type;
728

729
	spin_unlock(&mcbsp->lock);
730 731 732

	return 0;
}
733
EXPORT_SYMBOL(omap_mcbsp_set_io_type);
734 735 736

int omap_mcbsp_request(unsigned int id)
{
737
	struct omap_mcbsp *mcbsp;
738
	void *reg_cache;
739 740
	int err;

741 742 743
	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
		return -ENODEV;
744
	}
745
	mcbsp = id_to_mcbsp_ptr(id);
746

747 748 749 750 751
	reg_cache = kzalloc(omap_mcbsp_cache_size, GFP_KERNEL);
	if (!reg_cache) {
		return -ENOMEM;
	}

752 753 754 755
	spin_lock(&mcbsp->lock);
	if (!mcbsp->free) {
		dev_err(mcbsp->dev, "McBSP%d is currently in use\n",
			mcbsp->id);
756 757
		err = -EBUSY;
		goto err_kfree;
758 759
	}

760
	mcbsp->free = false;
761
	mcbsp->reg_cache = reg_cache;
762
	spin_unlock(&mcbsp->lock);
763

764 765 766 767 768 769
	if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request)
		mcbsp->pdata->ops->request(id);

	clk_enable(mcbsp->iclk);
	clk_enable(mcbsp->fclk);

E
Eero Nurkkala 已提交
770 771 772
	/* Do procedure specific to omap34xx arch, if applicable */
	omap34xx_mcbsp_request(mcbsp);

773 774 775 776
	/*
	 * Make sure that transmitter, receiver and sample-rate generator are
	 * not running before activating IRQs.
	 */
777 778
	MCBSP_WRITE(mcbsp, SPCR1, 0);
	MCBSP_WRITE(mcbsp, SPCR2, 0);
779

780
	if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
781
		/* We need to get IRQs here */
782
		init_completion(&mcbsp->tx_irq_completion);
783 784
		err = request_irq(mcbsp->tx_irq, omap_mcbsp_tx_irq_handler,
					0, "McBSP", (void *)mcbsp);
785
		if (err != 0) {
786 787 788
			dev_err(mcbsp->dev, "Unable to request TX IRQ %d "
					"for McBSP%d\n", mcbsp->tx_irq,
					mcbsp->id);
789
			goto err_clk_disable;
790
		}
791

792 793 794 795
		if (mcbsp->rx_irq) {
			init_completion(&mcbsp->rx_irq_completion);
			err = request_irq(mcbsp->rx_irq,
					omap_mcbsp_rx_irq_handler,
796
					0, "McBSP", (void *)mcbsp);
797 798 799 800 801 802
			if (err != 0) {
				dev_err(mcbsp->dev, "Unable to request RX IRQ %d "
						"for McBSP%d\n", mcbsp->rx_irq,
						mcbsp->id);
				goto err_free_irq;
			}
803
		}
804 805 806
	}

	return 0;
807
err_free_irq:
808
	free_irq(mcbsp->tx_irq, (void *)mcbsp);
809
err_clk_disable:
810
	if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
811
		mcbsp->pdata->ops->free(id);
812 813 814 815 816 817 818

	/* Do procedure specific to omap34xx arch, if applicable */
	omap34xx_mcbsp_free(mcbsp);

	clk_disable(mcbsp->fclk);
	clk_disable(mcbsp->iclk);

819
	spin_lock(&mcbsp->lock);
820
	mcbsp->free = true;
821 822 823 824
	mcbsp->reg_cache = NULL;
err_kfree:
	spin_unlock(&mcbsp->lock);
	kfree(reg_cache);
825 826

	return err;
827
}
828
EXPORT_SYMBOL(omap_mcbsp_request);
829 830 831

void omap_mcbsp_free(unsigned int id)
{
832
	struct omap_mcbsp *mcbsp;
833
	void *reg_cache;
834

835 836
	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
837
		return;
838
	}
839
	mcbsp = id_to_mcbsp_ptr(id);
840

841 842
	if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
		mcbsp->pdata->ops->free(id);
843

E
Eero Nurkkala 已提交
844 845 846
	/* Do procedure specific to omap34xx arch, if applicable */
	omap34xx_mcbsp_free(mcbsp);

847 848 849 850 851
	clk_disable(mcbsp->fclk);
	clk_disable(mcbsp->iclk);

	if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
		/* Free IRQs */
852 853
		if (mcbsp->rx_irq)
			free_irq(mcbsp->rx_irq, (void *)mcbsp);
854 855
		free_irq(mcbsp->tx_irq, (void *)mcbsp);
	}
856

857
	reg_cache = mcbsp->reg_cache;
858

859 860 861 862
	spin_lock(&mcbsp->lock);
	if (mcbsp->free)
		dev_err(mcbsp->dev, "McBSP%d was not reserved\n", mcbsp->id);
	else
863
		mcbsp->free = true;
864
	mcbsp->reg_cache = NULL;
865
	spin_unlock(&mcbsp->lock);
866 867 868

	if (reg_cache)
		kfree(reg_cache);
869
}
870
EXPORT_SYMBOL(omap_mcbsp_free);
871 872

/*
873 874 875
 * Here we start the McBSP, by enabling transmitter, receiver or both.
 * If no transmitter or receiver is active prior calling, then sample-rate
 * generator and frame sync are started.
876
 */
877
void omap_mcbsp_start(unsigned int id, int tx, int rx)
878
{
879
	struct omap_mcbsp *mcbsp;
880
	int enable_srg = 0;
881 882
	u16 w;

883 884
	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
885
		return;
886
	}
887
	mcbsp = id_to_mcbsp_ptr(id);
888

889 890 891
	if (cpu_is_omap34xx())
		omap_st_start(mcbsp);

892 893
	mcbsp->rx_word_length = (MCBSP_READ_CACHE(mcbsp, RCR1) >> 5) & 0x7;
	mcbsp->tx_word_length = (MCBSP_READ_CACHE(mcbsp, XCR1) >> 5) & 0x7;
894

895 896 897 898 899
	/* Only enable SRG, if McBSP is master */
	w = MCBSP_READ_CACHE(mcbsp, PCR0);
	if (w & (FSXM | FSRM | CLKXM | CLKRM))
		enable_srg = !((MCBSP_READ_CACHE(mcbsp, SPCR2) |
				MCBSP_READ_CACHE(mcbsp, SPCR1)) & 1);
900

901
	if (enable_srg) {
902
		/* Start the sample generator */
903
		w = MCBSP_READ_CACHE(mcbsp, SPCR2);
904
		MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 6));
905
	}
906 907

	/* Enable transmitter and receiver */
908
	tx &= 1;
909
	w = MCBSP_READ_CACHE(mcbsp, SPCR2);
910
	MCBSP_WRITE(mcbsp, SPCR2, w | tx);
911

912
	rx &= 1;
913
	w = MCBSP_READ_CACHE(mcbsp, SPCR1);
914
	MCBSP_WRITE(mcbsp, SPCR1, w | rx);
915

916 917 918 919 920 921 922
	/*
	 * Worst case: CLKSRG*2 = 8000khz: (1/8000) * 2 * 2 usec
	 * REVISIT: 100us may give enough time for two CLKSRG, however
	 * due to some unknown PM related, clock gating etc. reason it
	 * is now at 500us.
	 */
	udelay(500);
923

924
	if (enable_srg) {
925
		/* Start frame sync */
926
		w = MCBSP_READ_CACHE(mcbsp, SPCR2);
927
		MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 7));
928
	}
929

930
	if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
931
		/* Release the transmitter and receiver */
932
		w = MCBSP_READ_CACHE(mcbsp, XCCR);
933
		w &= ~(tx ? XDISABLE : 0);
934
		MCBSP_WRITE(mcbsp, XCCR, w);
935
		w = MCBSP_READ_CACHE(mcbsp, RCCR);
936
		w &= ~(rx ? RDISABLE : 0);
937
		MCBSP_WRITE(mcbsp, RCCR, w);
938 939
	}

940 941 942
	/* Dump McBSP Regs */
	omap_mcbsp_dump_reg(id);
}
943
EXPORT_SYMBOL(omap_mcbsp_start);
944

945
void omap_mcbsp_stop(unsigned int id, int tx, int rx)
946
{
947
	struct omap_mcbsp *mcbsp;
948
	int idle;
949 950
	u16 w;

951 952
	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
953
		return;
954
	}
955

956
	mcbsp = id_to_mcbsp_ptr(id);
957

958
	/* Reset transmitter */
959
	tx &= 1;
960
	if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
961
		w = MCBSP_READ_CACHE(mcbsp, XCCR);
962
		w |= (tx ? XDISABLE : 0);
963
		MCBSP_WRITE(mcbsp, XCCR, w);
964
	}
965
	w = MCBSP_READ_CACHE(mcbsp, SPCR2);
966
	MCBSP_WRITE(mcbsp, SPCR2, w & ~tx);
967 968

	/* Reset receiver */
969
	rx &= 1;
970
	if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
971
		w = MCBSP_READ_CACHE(mcbsp, RCCR);
972
		w |= (rx ? RDISABLE : 0);
973
		MCBSP_WRITE(mcbsp, RCCR, w);
974
	}
975
	w = MCBSP_READ_CACHE(mcbsp, SPCR1);
976
	MCBSP_WRITE(mcbsp, SPCR1, w & ~rx);
977

978 979
	idle = !((MCBSP_READ_CACHE(mcbsp, SPCR2) |
			MCBSP_READ_CACHE(mcbsp, SPCR1)) & 1);
980 981 982

	if (idle) {
		/* Reset the sample rate generator */
983
		w = MCBSP_READ_CACHE(mcbsp, SPCR2);
984
		MCBSP_WRITE(mcbsp, SPCR2, w & ~(1 << 6));
985
	}
986 987 988

	if (cpu_is_omap34xx())
		omap_st_stop(mcbsp);
989
}
990
EXPORT_SYMBOL(omap_mcbsp_stop);
991

992 993 994
/* polled mcbsp i/o operations */
int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
{
995
	struct omap_mcbsp *mcbsp;
996 997 998 999 1000 1001

	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
		return -ENODEV;
	}

1002 1003
	mcbsp = id_to_mcbsp_ptr(id);

1004
	MCBSP_WRITE(mcbsp, DXR1, buf);
1005
	/* if frame sync error - clear the error */
1006
	if (MCBSP_READ(mcbsp, SPCR2) & XSYNC_ERR) {
1007
		/* clear error */
1008
		MCBSP_WRITE(mcbsp, SPCR2, MCBSP_READ_CACHE(mcbsp, SPCR2));
1009 1010 1011 1012 1013
		/* resend */
		return -1;
	} else {
		/* wait for transmit confirmation */
		int attemps = 0;
1014
		while (!(MCBSP_READ(mcbsp, SPCR2) & XRDY)) {
1015
			if (attemps++ > 1000) {
1016
				MCBSP_WRITE(mcbsp, SPCR2,
1017 1018
						MCBSP_READ_CACHE(mcbsp, SPCR2) &
						(~XRST));
1019
				udelay(10);
1020
				MCBSP_WRITE(mcbsp, SPCR2,
1021 1022
						MCBSP_READ_CACHE(mcbsp, SPCR2) |
						(XRST));
1023
				udelay(10);
1024 1025
				dev_err(mcbsp->dev, "Could not write to"
					" McBSP%d Register\n", mcbsp->id);
1026 1027 1028 1029
				return -2;
			}
		}
	}
1030

1031 1032
	return 0;
}
1033
EXPORT_SYMBOL(omap_mcbsp_pollwrite);
1034

1035
int omap_mcbsp_pollread(unsigned int id, u16 *buf)
1036
{
1037
	struct omap_mcbsp *mcbsp;
1038 1039 1040 1041 1042

	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
		return -ENODEV;
	}
1043
	mcbsp = id_to_mcbsp_ptr(id);
1044

1045
	/* if frame sync error - clear the error */
1046
	if (MCBSP_READ(mcbsp, SPCR1) & RSYNC_ERR) {
1047
		/* clear error */
1048
		MCBSP_WRITE(mcbsp, SPCR1, MCBSP_READ_CACHE(mcbsp, SPCR1));
1049 1050 1051 1052 1053
		/* resend */
		return -1;
	} else {
		/* wait for recieve confirmation */
		int attemps = 0;
1054
		while (!(MCBSP_READ(mcbsp, SPCR1) & RRDY)) {
1055
			if (attemps++ > 1000) {
1056
				MCBSP_WRITE(mcbsp, SPCR1,
1057 1058
						MCBSP_READ_CACHE(mcbsp, SPCR1) &
						(~RRST));
1059
				udelay(10);
1060
				MCBSP_WRITE(mcbsp, SPCR1,
1061 1062
						MCBSP_READ_CACHE(mcbsp, SPCR1) |
						(RRST));
1063
				udelay(10);
1064 1065
				dev_err(mcbsp->dev, "Could not read from"
					" McBSP%d Register\n", mcbsp->id);
1066 1067 1068 1069
				return -2;
			}
		}
	}
1070
	*buf = MCBSP_READ(mcbsp, DRR1);
1071

1072 1073
	return 0;
}
1074
EXPORT_SYMBOL(omap_mcbsp_pollread);
1075

1076 1077 1078 1079 1080
/*
 * IRQ based word transmission.
 */
void omap_mcbsp_xmit_word(unsigned int id, u32 word)
{
1081
	struct omap_mcbsp *mcbsp;
1082
	omap_mcbsp_word_length word_length;
1083

1084 1085
	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
1086
		return;
1087
	}
1088

1089 1090
	mcbsp = id_to_mcbsp_ptr(id);
	word_length = mcbsp->tx_word_length;
1091

1092
	wait_for_completion(&mcbsp->tx_irq_completion);
1093 1094

	if (word_length > OMAP_MCBSP_WORD_16)
1095 1096
		MCBSP_WRITE(mcbsp, DXR2, word >> 16);
	MCBSP_WRITE(mcbsp, DXR1, word & 0xffff);
1097
}
1098
EXPORT_SYMBOL(omap_mcbsp_xmit_word);
1099 1100 1101

u32 omap_mcbsp_recv_word(unsigned int id)
{
1102
	struct omap_mcbsp *mcbsp;
1103
	u16 word_lsb, word_msb = 0;
1104
	omap_mcbsp_word_length word_length;
1105

1106 1107 1108 1109
	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
		return -ENODEV;
	}
1110
	mcbsp = id_to_mcbsp_ptr(id);
1111

1112
	word_length = mcbsp->rx_word_length;
1113

1114
	wait_for_completion(&mcbsp->rx_irq_completion);
1115 1116

	if (word_length > OMAP_MCBSP_WORD_16)
1117 1118
		word_msb = MCBSP_READ(mcbsp, DRR2);
	word_lsb = MCBSP_READ(mcbsp, DRR1);
1119 1120 1121

	return (word_lsb | (word_msb << 16));
}
1122
EXPORT_SYMBOL(omap_mcbsp_recv_word);
1123

1124 1125
int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
{
1126
	struct omap_mcbsp *mcbsp;
1127 1128
	omap_mcbsp_word_length tx_word_length;
	omap_mcbsp_word_length rx_word_length;
1129 1130
	u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;

1131 1132 1133 1134
	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
		return -ENODEV;
	}
1135 1136 1137
	mcbsp = id_to_mcbsp_ptr(id);
	tx_word_length = mcbsp->tx_word_length;
	rx_word_length = mcbsp->rx_word_length;
1138

1139 1140 1141 1142
	if (tx_word_length != rx_word_length)
		return -EINVAL;

	/* First we wait for the transmitter to be ready */
1143
	spcr2 = MCBSP_READ(mcbsp, SPCR2);
1144
	while (!(spcr2 & XRDY)) {
1145
		spcr2 = MCBSP_READ(mcbsp, SPCR2);
1146 1147
		if (attempts++ > 1000) {
			/* We must reset the transmitter */
1148 1149
			MCBSP_WRITE(mcbsp, SPCR2,
				    MCBSP_READ_CACHE(mcbsp, SPCR2) & (~XRST));
1150
			udelay(10);
1151 1152
			MCBSP_WRITE(mcbsp, SPCR2,
				    MCBSP_READ_CACHE(mcbsp, SPCR2) | XRST);
1153
			udelay(10);
1154 1155
			dev_err(mcbsp->dev, "McBSP%d transmitter not "
				"ready\n", mcbsp->id);
1156 1157 1158 1159 1160 1161
			return -EAGAIN;
		}
	}

	/* Now we can push the data */
	if (tx_word_length > OMAP_MCBSP_WORD_16)
1162 1163
		MCBSP_WRITE(mcbsp, DXR2, word >> 16);
	MCBSP_WRITE(mcbsp, DXR1, word & 0xffff);
1164 1165

	/* We wait for the receiver to be ready */
1166
	spcr1 = MCBSP_READ(mcbsp, SPCR1);
1167
	while (!(spcr1 & RRDY)) {
1168
		spcr1 = MCBSP_READ(mcbsp, SPCR1);
1169 1170
		if (attempts++ > 1000) {
			/* We must reset the receiver */
1171 1172
			MCBSP_WRITE(mcbsp, SPCR1,
				    MCBSP_READ_CACHE(mcbsp, SPCR1) & (~RRST));
1173
			udelay(10);
1174 1175
			MCBSP_WRITE(mcbsp, SPCR1,
				    MCBSP_READ_CACHE(mcbsp, SPCR1) | RRST);
1176
			udelay(10);
1177 1178
			dev_err(mcbsp->dev, "McBSP%d receiver not "
				"ready\n", mcbsp->id);
1179 1180 1181 1182 1183 1184
			return -EAGAIN;
		}
	}

	/* Receiver is ready, let's read the dummy data */
	if (rx_word_length > OMAP_MCBSP_WORD_16)
1185 1186
		word_msb = MCBSP_READ(mcbsp, DRR2);
	word_lsb = MCBSP_READ(mcbsp, DRR1);
1187 1188 1189

	return 0;
}
1190
EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll);
1191

1192
int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
1193
{
1194
	struct omap_mcbsp *mcbsp;
1195
	u32 clock_word = 0;
1196 1197
	omap_mcbsp_word_length tx_word_length;
	omap_mcbsp_word_length rx_word_length;
1198 1199
	u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;

1200 1201 1202 1203 1204
	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
		return -ENODEV;
	}

1205 1206 1207 1208
	mcbsp = id_to_mcbsp_ptr(id);

	tx_word_length = mcbsp->tx_word_length;
	rx_word_length = mcbsp->rx_word_length;
1209

1210 1211 1212 1213
	if (tx_word_length != rx_word_length)
		return -EINVAL;

	/* First we wait for the transmitter to be ready */
1214
	spcr2 = MCBSP_READ(mcbsp, SPCR2);
1215
	while (!(spcr2 & XRDY)) {
1216
		spcr2 = MCBSP_READ(mcbsp, SPCR2);
1217 1218
		if (attempts++ > 1000) {
			/* We must reset the transmitter */
1219 1220
			MCBSP_WRITE(mcbsp, SPCR2,
				    MCBSP_READ_CACHE(mcbsp, SPCR2) & (~XRST));
1221
			udelay(10);
1222 1223
			MCBSP_WRITE(mcbsp, SPCR2,
				    MCBSP_READ_CACHE(mcbsp, SPCR2) | XRST);
1224
			udelay(10);
1225 1226
			dev_err(mcbsp->dev, "McBSP%d transmitter not "
				"ready\n", mcbsp->id);
1227 1228 1229 1230 1231 1232
			return -EAGAIN;
		}
	}

	/* We first need to enable the bus clock */
	if (tx_word_length > OMAP_MCBSP_WORD_16)
1233 1234
		MCBSP_WRITE(mcbsp, DXR2, clock_word >> 16);
	MCBSP_WRITE(mcbsp, DXR1, clock_word & 0xffff);
1235 1236

	/* We wait for the receiver to be ready */
1237
	spcr1 = MCBSP_READ(mcbsp, SPCR1);
1238
	while (!(spcr1 & RRDY)) {
1239
		spcr1 = MCBSP_READ(mcbsp, SPCR1);
1240 1241
		if (attempts++ > 1000) {
			/* We must reset the receiver */
1242 1243
			MCBSP_WRITE(mcbsp, SPCR1,
				    MCBSP_READ_CACHE(mcbsp, SPCR1) & (~RRST));
1244
			udelay(10);
1245 1246
			MCBSP_WRITE(mcbsp, SPCR1,
				    MCBSP_READ_CACHE(mcbsp, SPCR1) | RRST);
1247
			udelay(10);
1248 1249
			dev_err(mcbsp->dev, "McBSP%d receiver not "
				"ready\n", mcbsp->id);
1250 1251 1252 1253 1254 1255
			return -EAGAIN;
		}
	}

	/* Receiver is ready, there is something for us */
	if (rx_word_length > OMAP_MCBSP_WORD_16)
1256 1257
		word_msb = MCBSP_READ(mcbsp, DRR2);
	word_lsb = MCBSP_READ(mcbsp, DRR1);
1258 1259 1260 1261 1262

	word[0] = (word_lsb | (word_msb << 16));

	return 0;
}
1263
EXPORT_SYMBOL(omap_mcbsp_spi_master_recv_word_poll);
1264

1265 1266 1267 1268 1269 1270 1271
/*
 * Simple DMA based buffer rx/tx routines.
 * Nothing fancy, just a single buffer tx/rx through DMA.
 * The DMA resources are released once the transfer is done.
 * For anything fancier, you should use your own customized DMA
 * routines and callbacks.
 */
1272 1273
int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer,
				unsigned int length)
1274
{
1275
	struct omap_mcbsp *mcbsp;
1276
	int dma_tx_ch;
1277 1278 1279
	int src_port = 0;
	int dest_port = 0;
	int sync_dev = 0;
1280

1281 1282 1283 1284
	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
		return -ENODEV;
	}
1285
	mcbsp = id_to_mcbsp_ptr(id);
1286

1287
	if (omap_request_dma(mcbsp->dma_tx_sync, "McBSP TX",
1288
				omap_mcbsp_tx_dma_callback,
1289
				mcbsp,
1290
				&dma_tx_ch)) {
1291
		dev_err(mcbsp->dev, " Unable to request DMA channel for "
1292
				"McBSP%d TX. Trying IRQ based TX\n",
1293
				mcbsp->id);
1294 1295
		return -EAGAIN;
	}
1296
	mcbsp->dma_tx_lch = dma_tx_ch;
1297

1298
	dev_err(mcbsp->dev, "McBSP%d TX DMA on channel %d\n", mcbsp->id,
1299
		dma_tx_ch);
1300

1301
	init_completion(&mcbsp->tx_dma_completion);
1302

1303 1304 1305 1306
	if (cpu_class_is_omap1()) {
		src_port = OMAP_DMA_PORT_TIPB;
		dest_port = OMAP_DMA_PORT_EMIFF;
	}
1307
	if (cpu_class_is_omap2())
1308
		sync_dev = mcbsp->dma_tx_sync;
1309

1310
	omap_set_dma_transfer_params(mcbsp->dma_tx_lch,
1311 1312
				     OMAP_DMA_DATA_TYPE_S16,
				     length >> 1, 1,
1313
				     OMAP_DMA_SYNC_ELEMENT,
1314
	 sync_dev, 0);
1315

1316
	omap_set_dma_dest_params(mcbsp->dma_tx_lch,
1317
				 src_port,
1318
				 OMAP_DMA_AMODE_CONSTANT,
1319
				 mcbsp->phys_base + OMAP_MCBSP_REG_DXR1,
1320
				 0, 0);
1321

1322
	omap_set_dma_src_params(mcbsp->dma_tx_lch,
1323
				dest_port,
1324
				OMAP_DMA_AMODE_POST_INC,
1325 1326
				buffer,
				0, 0);
1327

1328 1329
	omap_start_dma(mcbsp->dma_tx_lch);
	wait_for_completion(&mcbsp->tx_dma_completion);
1330

1331 1332
	return 0;
}
1333
EXPORT_SYMBOL(omap_mcbsp_xmit_buffer);
1334

1335 1336
int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer,
				unsigned int length)
1337
{
1338
	struct omap_mcbsp *mcbsp;
1339
	int dma_rx_ch;
1340 1341 1342
	int src_port = 0;
	int dest_port = 0;
	int sync_dev = 0;
1343

1344 1345 1346 1347
	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
		return -ENODEV;
	}
1348
	mcbsp = id_to_mcbsp_ptr(id);
1349

1350
	if (omap_request_dma(mcbsp->dma_rx_sync, "McBSP RX",
1351
				omap_mcbsp_rx_dma_callback,
1352
				mcbsp,
1353
				&dma_rx_ch)) {
1354
		dev_err(mcbsp->dev, "Unable to request DMA channel for "
1355
				"McBSP%d RX. Trying IRQ based RX\n",
1356
				mcbsp->id);
1357 1358
		return -EAGAIN;
	}
1359
	mcbsp->dma_rx_lch = dma_rx_ch;
1360

1361
	dev_err(mcbsp->dev, "McBSP%d RX DMA on channel %d\n", mcbsp->id,
1362
		dma_rx_ch);
1363

1364
	init_completion(&mcbsp->rx_dma_completion);
1365

1366 1367 1368 1369
	if (cpu_class_is_omap1()) {
		src_port = OMAP_DMA_PORT_TIPB;
		dest_port = OMAP_DMA_PORT_EMIFF;
	}
1370
	if (cpu_class_is_omap2())
1371
		sync_dev = mcbsp->dma_rx_sync;
1372

1373
	omap_set_dma_transfer_params(mcbsp->dma_rx_lch,
1374 1375 1376 1377
					OMAP_DMA_DATA_TYPE_S16,
					length >> 1, 1,
					OMAP_DMA_SYNC_ELEMENT,
					sync_dev, 0);
1378

1379
	omap_set_dma_src_params(mcbsp->dma_rx_lch,
1380
				src_port,
1381
				OMAP_DMA_AMODE_CONSTANT,
1382
				mcbsp->phys_base + OMAP_MCBSP_REG_DRR1,
1383
				0, 0);
1384

1385
	omap_set_dma_dest_params(mcbsp->dma_rx_lch,
1386 1387 1388 1389
					dest_port,
					OMAP_DMA_AMODE_POST_INC,
					buffer,
					0, 0);
1390

1391 1392
	omap_start_dma(mcbsp->dma_rx_lch);
	wait_for_completion(&mcbsp->rx_dma_completion);
1393

1394 1395
	return 0;
}
1396
EXPORT_SYMBOL(omap_mcbsp_recv_buffer);
1397 1398 1399 1400 1401 1402 1403

/*
 * SPI wrapper.
 * Since SPI setup is much simpler than the generic McBSP one,
 * this wrapper just need an omap_mcbsp_spi_cfg structure as an input.
 * Once this is done, you can call omap_mcbsp_start().
 */
1404 1405
void omap_mcbsp_set_spi_mode(unsigned int id,
				const struct omap_mcbsp_spi_cfg *spi_cfg)
1406
{
1407
	struct omap_mcbsp *mcbsp;
1408 1409
	struct omap_mcbsp_reg_cfg mcbsp_cfg;

1410 1411
	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
1412
		return;
1413
	}
1414
	mcbsp = id_to_mcbsp_ptr(id);
1415 1416 1417 1418 1419 1420 1421

	memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg));

	/* SPI has only one frame */
	mcbsp_cfg.rcr1 |= (RWDLEN1(spi_cfg->word_length) | RFRLEN1(0));
	mcbsp_cfg.xcr1 |= (XWDLEN1(spi_cfg->word_length) | XFRLEN1(0));

1422
	/* Clock stop mode */
1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450
	if (spi_cfg->clk_stp_mode == OMAP_MCBSP_CLK_STP_MODE_NO_DELAY)
		mcbsp_cfg.spcr1 |= (1 << 12);
	else
		mcbsp_cfg.spcr1 |= (3 << 11);

	/* Set clock parities */
	if (spi_cfg->rx_clock_polarity == OMAP_MCBSP_CLK_RISING)
		mcbsp_cfg.pcr0 |= CLKRP;
	else
		mcbsp_cfg.pcr0 &= ~CLKRP;

	if (spi_cfg->tx_clock_polarity == OMAP_MCBSP_CLK_RISING)
		mcbsp_cfg.pcr0 &= ~CLKXP;
	else
		mcbsp_cfg.pcr0 |= CLKXP;

	/* Set SCLKME to 0 and CLKSM to 1 */
	mcbsp_cfg.pcr0 &= ~SCLKME;
	mcbsp_cfg.srgr2 |= CLKSM;

	/* Set FSXP */
	if (spi_cfg->fsx_polarity == OMAP_MCBSP_FS_ACTIVE_HIGH)
		mcbsp_cfg.pcr0 &= ~FSXP;
	else
		mcbsp_cfg.pcr0 |= FSXP;

	if (spi_cfg->spi_mode == OMAP_MCBSP_SPI_MASTER) {
		mcbsp_cfg.pcr0 |= CLKXM;
1451
		mcbsp_cfg.srgr1 |= CLKGDV(spi_cfg->clk_div - 1);
1452 1453 1454 1455
		mcbsp_cfg.pcr0 |= FSXM;
		mcbsp_cfg.srgr2 &= ~FSGM;
		mcbsp_cfg.xcr2 |= XDATDLY(1);
		mcbsp_cfg.rcr2 |= RDATDLY(1);
1456
	} else {
1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468
		mcbsp_cfg.pcr0 &= ~CLKXM;
		mcbsp_cfg.srgr1 |= CLKGDV(1);
		mcbsp_cfg.pcr0 &= ~FSXM;
		mcbsp_cfg.xcr2 &= ~XDATDLY(3);
		mcbsp_cfg.rcr2 &= ~RDATDLY(3);
	}

	mcbsp_cfg.xcr2 &= ~XPHASE;
	mcbsp_cfg.rcr2 &= ~RPHASE;

	omap_mcbsp_config(id, &mcbsp_cfg);
}
1469
EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
1470

1471
#ifdef CONFIG_ARCH_OMAP3
1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506
#define max_thres(m)			(mcbsp->pdata->buffer_size)
#define valid_threshold(m, val)		((val) <= max_thres(m))
#define THRESHOLD_PROP_BUILDER(prop)					\
static ssize_t prop##_show(struct device *dev,				\
			struct device_attribute *attr, char *buf)	\
{									\
	struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);		\
									\
	return sprintf(buf, "%u\n", mcbsp->prop);			\
}									\
									\
static ssize_t prop##_store(struct device *dev,				\
				struct device_attribute *attr,		\
				const char *buf, size_t size)		\
{									\
	struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);		\
	unsigned long val;						\
	int status;							\
									\
	status = strict_strtoul(buf, 0, &val);				\
	if (status)							\
		return status;						\
									\
	if (!valid_threshold(mcbsp, val))				\
		return -EDOM;						\
									\
	mcbsp->prop = val;						\
	return size;							\
}									\
									\
static DEVICE_ATTR(prop, 0644, prop##_show, prop##_store);

THRESHOLD_PROP_BUILDER(max_tx_thres);
THRESHOLD_PROP_BUILDER(max_rx_thres);

1507 1508 1509 1510
static const char *dma_op_modes[] = {
	"element", "threshold", "frame",
};

1511 1512 1513 1514
static ssize_t dma_op_mode_show(struct device *dev,
			struct device_attribute *attr, char *buf)
{
	struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
1515 1516 1517
	int dma_op_mode, i = 0;
	ssize_t len = 0;
	const char * const *s;
1518 1519 1520

	dma_op_mode = mcbsp->dma_op_mode;

1521 1522 1523 1524 1525 1526 1527 1528 1529
	for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++) {
		if (dma_op_mode == i)
			len += sprintf(buf + len, "[%s] ", *s);
		else
			len += sprintf(buf + len, "%s ", *s);
	}
	len += sprintf(buf + len, "\n");

	return len;
1530 1531 1532 1533 1534 1535 1536
}

static ssize_t dma_op_mode_store(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t size)
{
	struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
1537 1538
	const char * const *s;
	int i = 0;
1539

1540 1541 1542
	for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++)
		if (sysfs_streq(buf, *s))
			break;
1543

1544 1545
	if (i == ARRAY_SIZE(dma_op_modes))
		return -EINVAL;
1546

1547
	spin_lock_irq(&mcbsp->lock);
1548 1549 1550 1551
	if (!mcbsp->free) {
		size = -EBUSY;
		goto unlock;
	}
1552
	mcbsp->dma_op_mode = i;
1553 1554 1555 1556 1557 1558 1559 1560 1561

unlock:
	spin_unlock_irq(&mcbsp->lock);

	return size;
}

static DEVICE_ATTR(dma_op_mode, 0644, dma_op_mode_show, dma_op_mode_store);

1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619
static ssize_t st_taps_show(struct device *dev,
			    struct device_attribute *attr, char *buf)
{
	struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
	struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
	ssize_t status = 0;
	int i;

	spin_lock_irq(&mcbsp->lock);
	for (i = 0; i < st_data->nr_taps; i++)
		status += sprintf(&buf[status], (i ? ", %d" : "%d"),
				  st_data->taps[i]);
	if (i)
		status += sprintf(&buf[status], "\n");
	spin_unlock_irq(&mcbsp->lock);

	return status;
}

static ssize_t st_taps_store(struct device *dev,
			     struct device_attribute *attr,
			     const char *buf, size_t size)
{
	struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
	struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
	int val, tmp, status, i = 0;

	spin_lock_irq(&mcbsp->lock);
	memset(st_data->taps, 0, sizeof(st_data->taps));
	st_data->nr_taps = 0;

	do {
		status = sscanf(buf, "%d%n", &val, &tmp);
		if (status < 0 || status == 0) {
			size = -EINVAL;
			goto out;
		}
		if (val < -32768 || val > 32767) {
			size = -EINVAL;
			goto out;
		}
		st_data->taps[i++] = val;
		buf += tmp;
		if (*buf != ',')
			break;
		buf++;
	} while (1);

	st_data->nr_taps = i;

out:
	spin_unlock_irq(&mcbsp->lock);

	return size;
}

static DEVICE_ATTR(st_taps, 0644, st_taps_show, st_taps_store);

1620
static const struct attribute *additional_attrs[] = {
1621 1622
	&dev_attr_max_tx_thres.attr,
	&dev_attr_max_rx_thres.attr,
1623
	&dev_attr_dma_op_mode.attr,
1624 1625 1626
	NULL,
};

1627 1628
static const struct attribute_group additional_attr_group = {
	.attrs = (struct attribute **)additional_attrs,
1629 1630
};

1631
static inline int __devinit omap_additional_add(struct device *dev)
1632
{
1633
	return sysfs_create_group(&dev->kobj, &additional_attr_group);
1634 1635
}

1636
static inline void __devexit omap_additional_remove(struct device *dev)
1637
{
1638
	sysfs_remove_group(&dev->kobj, &additional_attr_group);
1639 1640
}

1641 1642 1643 1644 1645 1646 1647 1648 1649
static const struct attribute *sidetone_attrs[] = {
	&dev_attr_st_taps.attr,
	NULL,
};

static const struct attribute_group sidetone_attr_group = {
	.attrs = (struct attribute **)sidetone_attrs,
};

1650
static int __devinit omap_st_add(struct omap_mcbsp *mcbsp)
1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694
{
	struct omap_mcbsp_platform_data *pdata = mcbsp->pdata;
	struct omap_mcbsp_st_data *st_data;
	int err;

	st_data = kzalloc(sizeof(*mcbsp->st_data), GFP_KERNEL);
	if (!st_data) {
		err = -ENOMEM;
		goto err1;
	}

	st_data->io_base_st = ioremap(pdata->phys_base_st, SZ_4K);
	if (!st_data->io_base_st) {
		err = -ENOMEM;
		goto err2;
	}

	err = sysfs_create_group(&mcbsp->dev->kobj, &sidetone_attr_group);
	if (err)
		goto err3;

	mcbsp->st_data = st_data;
	return 0;

err3:
	iounmap(st_data->io_base_st);
err2:
	kfree(st_data);
err1:
	return err;

}

static void __devexit omap_st_remove(struct omap_mcbsp *mcbsp)
{
	struct omap_mcbsp_st_data *st_data = mcbsp->st_data;

	if (st_data) {
		sysfs_remove_group(&mcbsp->dev->kobj, &sidetone_attr_group);
		iounmap(st_data->io_base_st);
		kfree(st_data);
	}
}

1695 1696
static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp)
{
1697
	mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
1698
	if (cpu_is_omap34xx()) {
1699 1700 1701 1702 1703 1704 1705 1706 1707 1708
		/*
		 * Initially configure the maximum thresholds to a safe value.
		 * The McBSP FIFO usage with these values should not go under
		 * 16 locations.
		 * If the whole FIFO without safety buffer is used, than there
		 * is a possibility that the DMA will be not able to push the
		 * new data on time, causing channel shifts in runtime.
		 */
		mcbsp->max_tx_thres = max_thres(mcbsp) - 0x10;
		mcbsp->max_rx_thres = max_thres(mcbsp) - 0x10;
1709 1710 1711 1712
		/*
		 * REVISIT: Set dmap_op_mode to THRESHOLD as default
		 * for mcbsp2 instances.
		 */
1713
		if (omap_additional_add(mcbsp->dev))
1714
			dev_warn(mcbsp->dev,
1715
				"Unable to create additional controls\n");
1716 1717 1718 1719 1720 1721

		if (mcbsp->id == 2 || mcbsp->id == 3)
			if (omap_st_add(mcbsp))
				dev_warn(mcbsp->dev,
				 "Unable to create sidetone controls\n");

1722 1723 1724 1725 1726 1727 1728 1729
	} else {
		mcbsp->max_tx_thres = -EINVAL;
		mcbsp->max_rx_thres = -EINVAL;
	}
}

static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp)
{
1730
	if (cpu_is_omap34xx()) {
1731
		omap_additional_remove(mcbsp->dev);
1732 1733 1734 1735

		if (mcbsp->id == 2 || mcbsp->id == 3)
			omap_st_remove(mcbsp);
	}
1736 1737 1738 1739
}
#else
static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) {}
static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp) {}
1740
#endif /* CONFIG_ARCH_OMAP3 */
1741

1742 1743 1744 1745
/*
 * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
 * 730 has only 2 McBSP, and both of them are MPU peripherals.
 */
1746
static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
1747 1748
{
	struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data;
1749
	struct omap_mcbsp *mcbsp;
1750 1751
	int id = pdev->id - 1;
	int ret = 0;
1752

1753 1754 1755 1756 1757 1758 1759 1760 1761
	if (!pdata) {
		dev_err(&pdev->dev, "McBSP device initialized without"
				"platform data\n");
		ret = -EINVAL;
		goto exit;
	}

	dev_dbg(&pdev->dev, "Initializing OMAP McBSP (%d).\n", pdev->id);

1762
	if (id >= omap_mcbsp_count) {
1763 1764 1765 1766 1767
		dev_err(&pdev->dev, "Invalid McBSP device id (%d)\n", id);
		ret = -EINVAL;
		goto exit;
	}

1768 1769 1770 1771 1772 1773 1774 1775
	mcbsp = kzalloc(sizeof(struct omap_mcbsp), GFP_KERNEL);
	if (!mcbsp) {
		ret = -ENOMEM;
		goto exit;
	}

	spin_lock_init(&mcbsp->lock);
	mcbsp->id = id + 1;
1776
	mcbsp->free = true;
1777 1778
	mcbsp->dma_tx_lch = -1;
	mcbsp->dma_rx_lch = -1;
1779

1780 1781 1782
	mcbsp->phys_base = pdata->phys_base;
	mcbsp->io_base = ioremap(pdata->phys_base, SZ_4K);
	if (!mcbsp->io_base) {
1783 1784 1785 1786
		ret = -ENOMEM;
		goto err_ioremap;
	}

1787
	/* Default I/O is IRQ based */
1788 1789 1790 1791 1792
	mcbsp->io_type = OMAP_MCBSP_IRQ_IO;
	mcbsp->tx_irq = pdata->tx_irq;
	mcbsp->rx_irq = pdata->rx_irq;
	mcbsp->dma_rx_sync = pdata->dma_rx_sync;
	mcbsp->dma_tx_sync = pdata->dma_tx_sync;
1793

1794 1795 1796 1797 1798 1799
	mcbsp->iclk = clk_get(&pdev->dev, "ick");
	if (IS_ERR(mcbsp->iclk)) {
		ret = PTR_ERR(mcbsp->iclk);
		dev_err(&pdev->dev, "unable to get ick: %d\n", ret);
		goto err_iclk;
	}
1800

1801 1802 1803 1804 1805
	mcbsp->fclk = clk_get(&pdev->dev, "fck");
	if (IS_ERR(mcbsp->fclk)) {
		ret = PTR_ERR(mcbsp->fclk);
		dev_err(&pdev->dev, "unable to get fck: %d\n", ret);
		goto err_fclk;
1806 1807
	}

1808 1809
	mcbsp->pdata = pdata;
	mcbsp->dev = &pdev->dev;
1810
	mcbsp_ptr[id] = mcbsp;
1811
	platform_set_drvdata(pdev, mcbsp);
1812 1813 1814 1815

	/* Initialize mcbsp properties for OMAP34XX if needed / applicable */
	omap34xx_device_init(mcbsp);

1816
	return 0;
1817

1818 1819 1820
err_fclk:
	clk_put(mcbsp->iclk);
err_iclk:
1821
	iounmap(mcbsp->io_base);
1822
err_ioremap:
1823
	kfree(mcbsp);
1824 1825 1826
exit:
	return ret;
}
1827

1828
static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
1829
{
1830
	struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
1831

1832 1833
	platform_set_drvdata(pdev, NULL);
	if (mcbsp) {
1834

1835 1836 1837
		if (mcbsp->pdata && mcbsp->pdata->ops &&
				mcbsp->pdata->ops->free)
			mcbsp->pdata->ops->free(mcbsp->id);
1838

1839 1840
		omap34xx_device_exit(mcbsp);

1841 1842
		clk_put(mcbsp->fclk);
		clk_put(mcbsp->iclk);
1843

1844
		iounmap(mcbsp->io_base);
1845
		kfree(mcbsp);
1846 1847 1848 1849 1850
	}

	return 0;
}

1851 1852
static struct platform_driver omap_mcbsp_driver = {
	.probe		= omap_mcbsp_probe,
1853
	.remove		= __devexit_p(omap_mcbsp_remove),
1854 1855 1856 1857 1858 1859 1860 1861 1862 1863
	.driver		= {
		.name	= "omap-mcbsp",
	},
};

int __init omap_mcbsp_init(void)
{
	/* Register the McBSP driver */
	return platform_driver_register(&omap_mcbsp_driver);
}