saa7134-alsa.c 25.1 KB
Newer Older
1
/*
2
 *   SAA713x ALSA support for V4L
3 4
 *
 *
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
 *   Caveats:
 *        - Volume doesn't work (it's always at max)
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, version 2
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
20 21 22 23
 *
 */

#include <sound/driver.h>
24 25 26 27 28 29
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/wait.h>
#include <linux/moduleparam.h>
#include <linux/module.h>
30 31
#include <sound/core.h>
#include <sound/control.h>
32
#include <sound/pcm.h>
33
#include <sound/pcm_params.h>
34
#include <sound/initval.h>
35
#include <linux/interrupt.h>
36 37 38 39

#include "saa7134.h"
#include "saa7134-reg.h"

40 41 42 43
static unsigned int debug  = 0;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug,"enable debug messages [alsa]");

44 45 46 47
/*
 * Configuration macros
 */

48
/* defaults */
49 50 51 52
#define MIXER_ADDR_TVTUNER	0
#define MIXER_ADDR_LINE1	1
#define MIXER_ADDR_LINE2	2
#define MIXER_ADDR_LAST		2
53

54

55 56 57 58
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};

59 60 61
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s).");

62
#define dprintk(fmt, arg...)    if (debug) \
63
	printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ##arg)
64 65


66

67 68 69
/*
 * Main chip structure
 */
70

71 72 73 74 75
typedef struct snd_card_saa7134 {
	snd_card_t *card;
	spinlock_t mixer_lock;
	int mixer_volume[MIXER_ADDR_LAST+1][2];
	int capture_source[MIXER_ADDR_LAST+1][2];
76
	struct pci_dev *pci;
77
	struct saa7134_dev *dev;
78

79 80
	unsigned long iobase;
	int irq;
81 82 83 84

	spinlock_t lock;
} snd_card_saa7134_t;

85 86


87 88 89 90
/*
 * PCM structure
 */

91
typedef struct snd_card_saa7134_pcm {
92
	struct saa7134_dev *dev;
93 94

	spinlock_t lock;
95

96 97
	snd_pcm_substream_t *substream;
} snd_card_saa7134_pcm_t;
98

99
static snd_card_t *snd_saa7134_cards[SNDRV_CARDS];
100

101

102 103 104 105 106
/*
 * saa7134 DMA audio stop
 *
 *   Called when the capture device is released or the buffer overflows
 *
107
 *   - Copied verbatim from saa7134-oss's dsp_dma_stop.
108 109 110
 *
 */

111 112
static void saa7134_dma_stop(struct saa7134_dev *dev)
{
113 114
	dev->dmasound.dma_blk     = -1;
	dev->dmasound.dma_running = 0;
115
	saa7134_set_dmabits(dev);
116
}
117

118 119 120 121 122
/*
 * saa7134 DMA audio start
 *
 *   Called when preparing the capture device for use
 *
123
 *   - Copied verbatim from saa7134-oss's dsp_dma_start.
124 125 126
 *
 */

127 128
static void saa7134_dma_start(struct saa7134_dev *dev)
{
129 130
	dev->dmasound.dma_blk     = 0;
	dev->dmasound.dma_running = 1;
131
	saa7134_set_dmabits(dev);
132
}
133

134 135 136 137 138 139 140 141 142 143 144
/*
 * saa7134 audio DMA IRQ handler
 *
 *   Called whenever we get an SAA7134_IRQ_REPORT_DONE_RA3 interrupt
 *   Handles shifting between the 2 buffers, manages the read counters,
 *  and notifies ALSA when periods elapse
 *
 *   - Mostly copied from saa7134-oss's saa7134_irq_oss_done.
 *
 */

145 146
static void saa7134_irq_alsa_done(struct saa7134_dev *dev,
				  unsigned long status)
147 148
{
	int next_blk, reg = 0;
149

150
	spin_lock(&dev->slock);
151
	if (UNSET == dev->dmasound.dma_blk) {
152 153 154 155 156 157 158
		dprintk("irq: recording stopped\n");
		goto done;
	}
	if (0 != (status & 0x0f000000))
		dprintk("irq: lost %ld\n", (status >> 24) & 0x0f);
	if (0 == (status & 0x10000000)) {
		/* odd */
159
		if (0 == (dev->dmasound.dma_blk & 0x01))
160 161 162
			reg = SAA7134_RS_BA1(6);
	} else {
		/* even */
163
		if (1 == (dev->dmasound.dma_blk & 0x01))
164 165 166 167 168 169 170
			reg = SAA7134_RS_BA2(6);
	}
	if (0 == reg) {
		dprintk("irq: field oops [%s]\n",
			(status & 0x10000000) ? "even" : "odd");
		goto done;
	}
171

172 173 174
	if (dev->dmasound.read_count >= dev->dmasound.blksize * (dev->dmasound.blocks-2)) {
		dprintk("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->dmasound.read_count,
			dev->dmasound.bufsize, dev->dmasound.blocks);
175
		spin_unlock(&dev->slock);
176
		snd_pcm_stop(dev->dmasound.substream,SNDRV_PCM_STATE_XRUN);
177
		return;
178
	}
179

180
	/* next block addr */
181 182
	next_blk = (dev->dmasound.dma_blk + 2) % dev->dmasound.blocks;
	saa_writel(reg,next_blk * dev->dmasound.blksize);
183
	if (debug > 2)
184 185
		dprintk("irq: ok, %s, next_blk=%d, addr=%x, blocks=%u, size=%u, read=%u\n",
			(status & 0x10000000) ? "even" : "odd ", next_blk,
186
			next_blk * dev->dmasound.blksize, dev->dmasound.blocks, dev->dmasound.blksize, dev->dmasound.read_count);
187

188
	/* update status & wake waiting readers */
189 190
	dev->dmasound.dma_blk = (dev->dmasound.dma_blk + 1) % dev->dmasound.blocks;
	dev->dmasound.read_count += dev->dmasound.blksize;
191

192
	dev->dmasound.recording_on = reg;
193

194
	if (dev->dmasound.read_count >= snd_pcm_lib_period_bytes(dev->dmasound.substream)) {
195
		spin_unlock(&dev->slock);
196
		snd_pcm_period_elapsed(dev->dmasound.substream);
197
		spin_lock(&dev->slock);
198
	}
199

200
 done:
201
	spin_unlock(&dev->slock);
202

203
}
204

205 206 207 208 209 210 211 212 213 214
/*
 * IRQ request handler
 *
 *   Runs along with saa7134's IRQ handler, discards anything that isn't
 *   DMA sound
 *
 */

static irqreturn_t saa7134_alsa_irq(int irq, void *dev_id, struct pt_regs *regs)
{
215 216
	struct saa7134_dmasound *dmasound = dev_id;
	struct saa7134_dev *dev = dmasound->priv_data;
217

218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
	unsigned long report, status;
	int loop, handled = 0;

	for (loop = 0; loop < 10; loop++) {
		report = saa_readl(SAA7134_IRQ_REPORT);
		status = saa_readl(SAA7134_IRQ_STATUS);

		if (report & SAA7134_IRQ_REPORT_DONE_RA3) {
			handled = 1;
			saa_writel(SAA7134_IRQ_REPORT,report);
			saa7134_irq_alsa_done(dev, status);
		} else {
			goto out;
		}
	}

	if (loop == 10) {
		dprintk("error! looping IRQ!");
	}

out:
	return IRQ_RETVAL(handled);
}

242 243 244 245 246 247 248 249 250
/*
 * ALSA capture trigger
 *
 *   - One of the ALSA capture callbacks.
 *
 *   Called whenever a capture is started or stopped. Must be defined,
 *   but there's nothing we want to do here
 *
 */
251

252 253
static int snd_card_saa7134_capture_trigger(snd_pcm_substream_t * substream,
					  int cmd)
254
{
255
	snd_pcm_runtime_t *runtime = substream->runtime;
256 257
	snd_card_saa7134_pcm_t *pcm = runtime->private_data;
	struct saa7134_dev *dev=pcm->dev;
258 259
	int err = 0;

260
	spin_lock(&dev->slock);
261
	if (cmd == SNDRV_PCM_TRIGGER_START) {
262 263
		/* start dma */
		saa7134_dma_start(dev);
264
	} else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
265 266
		/* stop dma */
		saa7134_dma_stop(dev);
267 268 269
	} else {
		err = -EINVAL;
	}
270
	spin_unlock(&dev->slock);
271

272
	return err;
273 274
}

275 276 277 278 279 280 281
/*
 * DMA buffer initialization
 *
 *   Uses V4L functions to initialize the DMA. Shouldn't be necessary in
 *  ALSA, but I was unable to use ALSA's own DMA, and had to force the
 *  usage of V4L's
 *
282 283
 *   - Copied verbatim from saa7134-oss.
 *
284 285
 */

286
static int dsp_buffer_init(struct saa7134_dev *dev)
287
{
288 289
	int err;

290 291
	BUG_ON(!dev->dmasound.bufsize);

292 293 294
	videobuf_dma_init(&dev->dmasound.dma);
	err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE,
				       (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
295 296 297
	if (0 != err)
		return err;
	return 0;
298 299
}

300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321
/*
 * DMA buffer release
 *
 *   Called after closing the device, during snd_card_saa7134_capture_close
 *
 */

static int dsp_buffer_free(struct saa7134_dev *dev)
{
	if (!dev->dmasound.blksize)
		BUG();

	videobuf_dma_free(&dev->dmasound.dma);

	dev->dmasound.blocks  = 0;
	dev->dmasound.blksize = 0;
	dev->dmasound.bufsize = 0;

       return 0;
}


322 323 324 325 326 327 328 329 330 331 332
/*
 * ALSA PCM preparation
 *
 *   - One of the ALSA capture callbacks.
 *
 *   Called right after the capture device is opened, this function configures
 *  the buffer using the previously defined functions, allocates the memory,
 *  sets up the hardware registers, and then starts the DMA. When this function
 *  returns, the audio should be flowing.
 *
 */
333

334
static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream)
335
{
336
	snd_pcm_runtime_t *runtime = substream->runtime;
337
	int bswap, sign;
338
	u32 fmt, control;
339
	snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
340
	struct saa7134_dev *dev;
341
	snd_card_saa7134_pcm_t *pcm = runtime->private_data;
342

343
	pcm->dev->dmasound.substream = substream;
344

345
	dev = saa7134->dev;
346

347
	if (snd_pcm_format_width(runtime->format) == 8)
348
		fmt = 0x00;
349
	else
350
		fmt = 0x01;
351

352
	if (snd_pcm_format_signed(runtime->format))
353
		sign = 1;
354
	else
355 356
		sign = 0;

357 358 359 360
	if (snd_pcm_format_big_endian(runtime->format))
		bswap = 1;
	else
		bswap = 0;
361 362 363 364 365 366 367 368 369 370

	switch (dev->pci->device) {
	  case PCI_DEVICE_ID_PHILIPS_SAA7134:
		if (1 == runtime->channels)
			fmt |= (1 << 3);
		if (2 == runtime->channels)
			fmt |= (3 << 3);
		if (sign)
			fmt |= 0x04;

371 372 373 374
		fmt |= (MIXER_ADDR_TVTUNER == dev->dmasound.input) ? 0xc0 : 0x80;
		saa_writeb(SAA7134_NUM_SAMPLES0, ((dev->dmasound.blksize - 1) & 0x0000ff));
		saa_writeb(SAA7134_NUM_SAMPLES1, ((dev->dmasound.blksize - 1) & 0x00ff00) >>  8);
		saa_writeb(SAA7134_NUM_SAMPLES2, ((dev->dmasound.blksize - 1) & 0xff0000) >> 16);
375 376 377 378 379 380 381 382 383 384 385
		saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt);

		break;
	  case PCI_DEVICE_ID_PHILIPS_SAA7133:
	  case PCI_DEVICE_ID_PHILIPS_SAA7135:
		if (1 == runtime->channels)
			fmt |= (1 << 4);
		if (2 == runtime->channels)
			fmt |= (2 << 4);
		if (!sign)
			fmt |= 0x04;
386
		saa_writel(SAA7133_NUM_SAMPLES, dev->dmasound.blksize -1);
387 388 389 390 391 392 393 394 395 396
		saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210 | (fmt << 24));
		break;
	}

	dprintk("rec_start: afmt=%d ch=%d  =>  fmt=0x%x swap=%c\n",
		runtime->format, runtime->channels, fmt,
		bswap ? 'b' : '-');
	/* dma: setup channel 6 (= AUDIO) */
	control = SAA7134_RS_CONTROL_BURST_16 |
		SAA7134_RS_CONTROL_ME |
397
		(dev->dmasound.pt.dma >> 12);
398 399
	if (bswap)
		control |= SAA7134_RS_CONTROL_BSWAP;
400

401
	saa_writel(SAA7134_RS_BA1(6),0);
402
	saa_writel(SAA7134_RS_BA2(6),dev->dmasound.blksize);
403 404
	saa_writel(SAA7134_RS_PITCH(6),0);
	saa_writel(SAA7134_RS_CONTROL(6),control);
405

406
	dev->dmasound.rate = runtime->rate;
407

408
	return 0;
409

410
}
411

412 413 414 415 416 417 418 419 420 421
/*
 * ALSA pointer fetching
 *
 *   - One of the ALSA capture callbacks.
 *
 *   Called whenever a period elapses, it must return the current hardware
 *  position of the buffer.
 *   Also resets the read counter used to prevent overruns
 *
 */
422

423
static snd_pcm_uframes_t snd_card_saa7134_capture_pointer(snd_pcm_substream_t * substream)
424 425
{
	snd_pcm_runtime_t *runtime = substream->runtime;
426 427
	snd_card_saa7134_pcm_t *pcm = runtime->private_data;
	struct saa7134_dev *dev=pcm->dev;
428

429 430 431 432 433
	if (dev->dmasound.read_count) {
		dev->dmasound.read_count  -= snd_pcm_lib_period_bytes(substream);
		dev->dmasound.read_offset += snd_pcm_lib_period_bytes(substream);
		if (dev->dmasound.read_offset == dev->dmasound.bufsize)
			dev->dmasound.read_offset = 0;
434
	}
435

436
	return bytes_to_frames(runtime, dev->dmasound.read_offset);
437
}
438

439 440 441
/*
 * ALSA hardware capabilities definition
 */
442

443
static snd_pcm_hardware_t snd_card_saa7134_capture =
444
{
445
	.info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
446 447
				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
				 SNDRV_PCM_INFO_MMAP_VALID),
448 449 450 451 452 453 454 455 456 457 458 459
	.formats =		SNDRV_PCM_FMTBIT_S16_LE | \
				SNDRV_PCM_FMTBIT_S16_BE | \
				SNDRV_PCM_FMTBIT_S8 | \
				SNDRV_PCM_FMTBIT_U8 | \
				SNDRV_PCM_FMTBIT_U16_LE | \
				SNDRV_PCM_FMTBIT_U16_BE,
	.rates =		SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
	.rate_min =		32000,
	.rate_max =		48000,
	.channels_min =		1,
	.channels_max =		2,
	.buffer_bytes_max =	(256*1024),
460
	.period_bytes_min =	64,
461 462 463
	.period_bytes_max =	(256*1024),
	.periods_min =		2,
	.periods_max =		1024,
464
};
465

466 467
static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime)
{
468
	snd_card_saa7134_pcm_t *pcm = runtime->private_data;
469

470
	kfree(pcm);
471 472
}

473

474 475 476 477 478 479 480 481 482
/*
 * ALSA hardware params
 *
 *   - One of the ALSA capture callbacks.
 *
 *   Called on initialization, right before the PCM preparation
 *
 */

483 484
static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream,
				    snd_pcm_hw_params_t * hw_params)
485
{
486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549
	snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
	struct saa7134_dev *dev;
	unsigned int period_size, periods;
	int err;

	period_size = params_period_bytes(hw_params);
	periods = params_periods(hw_params);

	snd_assert(period_size >= 0x100 && period_size <= 0x10000,
		   return -EINVAL);
	snd_assert(periods >= 2, return -EINVAL);
	snd_assert(period_size * periods <= 1024 * 1024, return -EINVAL);

	dev = saa7134->dev;

	if (dev->dmasound.blocks == periods &&
	    dev->dmasound.blksize == period_size)
		return 0;

	/* release the old buffer */
	if (substream->runtime->dma_area) {
		saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
		videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma);
		dsp_buffer_free(dev);
		substream->runtime->dma_area = NULL;
	}
	dev->dmasound.blocks  = periods;
	dev->dmasound.blksize = period_size;
	dev->dmasound.bufsize = period_size * periods;

	err = dsp_buffer_init(dev);
	if (0 != err) {
		dev->dmasound.blocks  = 0;
		dev->dmasound.blksize = 0;
		dev->dmasound.bufsize = 0;
		return err;
	}

	if (0 != (err = videobuf_dma_pci_map(dev->pci, &dev->dmasound.dma))) {
		dsp_buffer_free(dev);
		return err;
	}
	if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt))) {
		videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma);
		dsp_buffer_free(dev);
		return err;
	}
	if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt,
						dev->dmasound.dma.sglist,
						dev->dmasound.dma.sglen,
						0))) {
		saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
		videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma);
		dsp_buffer_free(dev);
		return err;
	}

	/* I should be able to use runtime->dma_addr in the control
	   byte, but it doesn't work. So I allocate the DMA using the
	   V4L functions, and force ALSA to use that as the DMA area */

	substream->runtime->dma_area = dev->dmasound.dma.vmalloc;

	return 1;
550

551 552
}

553 554 555 556 557 558
/*
 * ALSA hardware release
 *
 *   - One of the ALSA capture callbacks.
 *
 *   Called after closing the device, but before snd_card_saa7134_capture_close
559
 *   It stops the DMA audio and releases the buffers.
560 561 562
 *
 */

563
static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream)
564
{
565 566
	snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
	struct saa7134_dev *dev;
567

568
	dev = saa7134->dev;
569

570 571 572 573 574 575
	if (substream->runtime->dma_area) {
		saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
		videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma);
		dsp_buffer_free(dev);
		substream->runtime->dma_area = NULL;
	}
576

577
	return 0;
578 579
}

580 581 582 583 584
/*
 * ALSA capture finish
 *
 *   - One of the ALSA capture callbacks.
 *
585
 *   Called after closing the device.
586 587
 *
 */
588

589
static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream)
590
{
591
	return 0;
592 593
}

594 595 596 597 598 599 600 601 602
/*
 * ALSA capture start
 *
 *   - One of the ALSA capture callbacks.
 *
 *   Called when opening the device. It creates and populates the PCM
 *  structure
 *
 */
603

604 605 606
static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream)
{
	snd_pcm_runtime_t *runtime = substream->runtime;
607
	snd_card_saa7134_pcm_t *pcm;
608
	snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
609
	struct saa7134_dev *dev = saa7134->dev;
610
	int err;
611

612
	down(&dev->dmasound.lock);
613

614 615
	dev->dmasound.read_count  = 0;
	dev->dmasound.read_offset = 0;
616

617
	up(&dev->dmasound.lock);
618

619 620
	pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
	if (pcm == NULL)
621 622
		return -ENOMEM;

623 624 625
	pcm->dev=saa7134->dev;

	spin_lock_init(&pcm->lock);
626

627 628
	pcm->substream = substream;
	runtime->private_data = pcm;
629 630 631
	runtime->private_free = snd_card_saa7134_runtime_free;
	runtime->hw = snd_card_saa7134_capture;

632 633
	if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
		return err;
634 635 636 637

	return 0;
}

638 639 640
/*
 * ALSA capture callbacks definition
 */
641

642 643 644 645 646 647 648 649 650
static snd_pcm_ops_t snd_card_saa7134_capture_ops = {
	.open =			snd_card_saa7134_capture_open,
	.close =		snd_card_saa7134_capture_close,
	.ioctl =		snd_pcm_lib_ioctl,
	.hw_params =		snd_card_saa7134_hw_params,
	.hw_free =		snd_card_saa7134_hw_free,
	.prepare =		snd_card_saa7134_capture_prepare,
	.trigger =		snd_card_saa7134_capture_trigger,
	.pointer =		snd_card_saa7134_capture_pointer,
651 652
};

653 654 655 656 657 658 659 660 661
/*
 * ALSA PCM setup
 *
 *   Called when initializing the board. Sets up the name and hooks up
 *  the callbacks
 *
 */

static int snd_card_saa7134_pcm(snd_card_saa7134_t *saa7134, int device)
662 663 664
{
	snd_pcm_t *pcm;
	int err;
665

666 667 668 669 670 671 672 673
	if ((err = snd_pcm_new(saa7134->card, "SAA7134 PCM", device, 0, 1, &pcm)) < 0)
		return err;
	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_card_saa7134_capture_ops);
	pcm->private_data = saa7134;
	pcm->info_flags = 0;
	strcpy(pcm->name, "SAA7134 PCM");
	return 0;
}
674

675 676 677 678 679
#define SAA713x_VOLUME(xname, xindex, addr) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
  .info = snd_saa7134_volume_info, \
  .get = snd_saa7134_volume_get, .put = snd_saa7134_volume_put, \
  .private_value = addr }
680

681 682 683 684 685 686 687 688
static int snd_saa7134_volume_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = 2;
	uinfo->value.integer.min = 0;
	uinfo->value.integer.max = 20;
	return 0;
}
689

690 691 692 693 694 695 696 697 698
static int snd_saa7134_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
	snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
	int addr = kcontrol->private_value;

	ucontrol->value.integer.value[0] = chip->mixer_volume[addr][0];
	ucontrol->value.integer.value[1] = chip->mixer_volume[addr][1];
	return 0;
}
699

700
static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
701
{
702 703 704 705 706 707 708 709 710 711 712 713 714 715
	snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
	int change, addr = kcontrol->private_value;
	int left, right;

	left = ucontrol->value.integer.value[0];
	if (left < 0)
		left = 0;
	if (left > 20)
		left = 20;
	right = ucontrol->value.integer.value[1];
	if (right < 0)
		right = 0;
	if (right > 20)
		right = 20;
716
	spin_lock_irq(&chip->mixer_lock);
717
	change = chip->mixer_volume[addr][0] != left ||
718
		 chip->mixer_volume[addr][1] != right;
719 720
	chip->mixer_volume[addr][0] = left;
	chip->mixer_volume[addr][1] = right;
721
	spin_unlock_irq(&chip->mixer_lock);
722 723
	return change;
}
724

725 726 727 728 729
#define SAA713x_CAPSRC(xname, xindex, addr) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
  .info = snd_saa7134_capsrc_info, \
  .get = snd_saa7134_capsrc_get, .put = snd_saa7134_capsrc_put, \
  .private_value = addr }
730

731 732 733
static int snd_saa7134_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
734
	uinfo->count = 2;
735 736 737 738
	uinfo->value.integer.min = 0;
	uinfo->value.integer.max = 1;
	return 0;
}
739

740 741 742 743 744
static int snd_saa7134_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
	snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
	int addr = kcontrol->private_value;

745
	spin_lock_irq(&chip->mixer_lock);
746 747
	ucontrol->value.integer.value[0] = chip->capture_source[addr][0];
	ucontrol->value.integer.value[1] = chip->capture_source[addr][1];
748
	spin_unlock_irq(&chip->mixer_lock);
749

750 751 752
	return 0;
}

753
static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
754
{
755 756 757
	snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
	int change, addr = kcontrol->private_value;
	int left, right;
758
	u32 anabar, xbarin;
759 760 761
	int analog_io, rate;
	struct saa7134_dev *dev;

762
	dev = chip->dev;
763 764 765

	left = ucontrol->value.integer.value[0] & 1;
	right = ucontrol->value.integer.value[1] & 1;
766
	spin_lock_irq(&chip->mixer_lock);
767

768
	change = chip->capture_source[addr][0] != left ||
769
		 chip->capture_source[addr][1] != right;
770 771
	chip->capture_source[addr][0] = left;
	chip->capture_source[addr][1] = right;
772
	dev->dmasound.input=addr;
773
	spin_unlock_irq(&chip->mixer_lock);
774 775


776
	if (change) {
777
	  switch (dev->pci->device) {
778 779

	   case PCI_DEVICE_ID_PHILIPS_SAA7134:
780 781 782 783 784 785 786 787
		switch (addr) {
			case MIXER_ADDR_TVTUNER:
				saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0);
				saa_andorb(SAA7134_SIF_SAMPLE_FREQ,   0x03, 0x00);
				break;
			case MIXER_ADDR_LINE1:
			case MIXER_ADDR_LINE2:
				analog_io = (MIXER_ADDR_LINE1 == addr) ? 0x00 : 0x08;
788
				rate = (32000 == dev->dmasound.rate) ? 0x01 : 0x03;
789 790 791 792 793 794 795
				saa_andorb(SAA7134_ANALOG_IO_SELECT,  0x08, analog_io);
				saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80);
				saa_andorb(SAA7134_SIF_SAMPLE_FREQ,   0x03, rate);
				break;
		}

		break;
796 797
	   case PCI_DEVICE_ID_PHILIPS_SAA7133:
	   case PCI_DEVICE_ID_PHILIPS_SAA7135:
798
		xbarin = 0x03; // adc
799
		anabar = 0;
800 801 802 803 804 805 806 807 808 809 810 811
		switch (addr) {
			case MIXER_ADDR_TVTUNER:
				xbarin = 0; // Demodulator
				anabar = 2; // DACs
				break;
			case MIXER_ADDR_LINE1:
				anabar = 0;  // aux1, aux1
				break;
			case MIXER_ADDR_LINE2:
				anabar = 9;  // aux2, aux2
				break;
		}
812 813

	    	/* output xbar always main channel */
814
		saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL1, 0xbbbb10);
815 816

		if (left || right) { // We've got data, turn the input on
817 818
		  saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, xbarin);
		  saa_writel(SAA7133_ANALOG_IO_SELECT, anabar);
819
		} else {
820 821
		  saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, 0);
		  saa_writel(SAA7133_ANALOG_IO_SELECT, 0);
822
		}
823
		break;
824
	  }
825
	}
826 827

	return change;
828 829
}

830 831 832 833 834 835 836 837
static snd_kcontrol_new_t snd_saa7134_controls[] = {
SAA713x_VOLUME("Video Volume", 0, MIXER_ADDR_TVTUNER),
SAA713x_CAPSRC("Video Capture Switch", 0, MIXER_ADDR_TVTUNER),
SAA713x_VOLUME("Line Volume", 1, MIXER_ADDR_LINE1),
SAA713x_CAPSRC("Line Capture Switch", 1, MIXER_ADDR_LINE1),
SAA713x_VOLUME("Line Volume", 2, MIXER_ADDR_LINE2),
SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2),
};
838

839 840 841 842 843 844 845 846 847
/*
 * ALSA mixer setup
 *
 *   Called when initializing the board. Sets up the name and hooks up
 *  the callbacks
 *
 */

static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip)
848 849 850 851 852 853 854
{
	snd_card_t *card = chip->card;
	unsigned int idx;
	int err;

	snd_assert(chip != NULL, return -EINVAL);
	strcpy(card->mixername, "SAA7134 Mixer");
855

856 857 858 859 860 861 862
	for (idx = 0; idx < ARRAY_SIZE(snd_saa7134_controls); idx++) {
		if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_saa7134_controls[idx], chip))) < 0)
			return err;
	}
	return 0;
}

863
static void snd_saa7134_free(snd_card_t * card)
864
{
865
	snd_card_saa7134_t *chip = card->private_data;
866

867
	if (chip->dev->dmasound.priv_data == NULL)
868
		return;
869

870 871
	if (chip->irq >= 0) {
		synchronize_irq(chip->irq);
872
		free_irq(chip->irq, &chip->dev->dmasound);
873 874
	}

875 876
	chip->dev->dmasound.priv_data = NULL;

877
}
878

879 880 881
/*
 * ALSA initialization
 *
882 883
 *   Called by the init routine, once for each saa7134 device present,
 *  it creates the basic structures and registers the ALSA devices
884 885 886
 *
 */

887
static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)
888
{
889

890
	snd_card_t *card;
891
	snd_card_saa7134_t *chip;
892
	int err;
893

894

895
	if (devnum >= SNDRV_CARDS)
896
		return -ENODEV;
897
	if (!enable[devnum])
898
		return -ENODEV;
899

900
	card = snd_card_new(index[devnum], id[devnum], THIS_MODULE, sizeof(snd_card_saa7134_t));
901

902 903
	if (card == NULL)
		return -ENOMEM;
904

905
	strcpy(card->driver, "SAA7134");
906

907
	/* Card "creation" */
908

909 910
	card->private_free = snd_saa7134_free;
	chip = (snd_card_saa7134_t *) card->private_data;
911

912
	spin_lock_init(&chip->lock);
913
	spin_lock_init(&chip->mixer_lock);
914

915
	chip->dev = dev;
916

917
	chip->card = card;
918

919 920 921
	chip->pci = dev->pci;
	chip->iobase = pci_resource_start(dev->pci, 0);

922

923 924 925
	err = request_irq(dev->pci->irq, saa7134_alsa_irq,
				SA_SHIRQ | SA_INTERRUPT, dev->name,
				(void*) &dev->dmasound);
926 927 928

	if (err < 0) {
		printk(KERN_ERR "%s: can't get IRQ %d for ALSA\n",
929
			dev->name, dev->pci->irq);
930
		goto __nodev;
931 932
	}

933
	chip->irq = dev->pci->irq;
934

935
	init_MUTEX(&dev->dmasound.lock);
936

937 938
	if ((err = snd_card_saa7134_new_mixer(chip)) < 0)
		goto __nodev;
939

940 941
	if ((err = snd_card_saa7134_pcm(chip, 0)) < 0)
		goto __nodev;
942

943
	snd_card_set_dev(card, &chip->pci->dev);
944

945
	/* End of "creation" */
946

947
	strcpy(card->shortname, "SAA7134");
948
	sprintf(card->longname, "%s at 0x%lx irq %d",
949
		chip->dev->name, chip->iobase, chip->irq);
950

951 952
	printk(KERN_INFO "%s/alsa: %s registered as card %d\n",dev->name,card->longname,index[devnum]);

953
	if ((err = snd_card_register(card)) == 0) {
954
		snd_saa7134_cards[devnum] = card;
955 956 957 958 959 960
		return 0;
	}

__nodev:
	snd_card_free(card);
	return err;
961 962
}

963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978

static int alsa_device_init(struct saa7134_dev *dev)
{
	dev->dmasound.priv_data = dev;
	alsa_card_saa7134_create(dev,dev->nr);
	return 1;
}

static int alsa_device_exit(struct saa7134_dev *dev)
{

	snd_card_free(snd_saa7134_cards[dev->nr]);
	snd_saa7134_cards[dev->nr] = NULL;
	return 1;
}

979 980 981 982 983 984 985 986 987 988
/*
 * Module initializer
 *
 * Loops through present saa7134 cards, and assigns an ALSA device
 * to each one
 *
 */

static int saa7134_alsa_init(void)
{
989
	struct saa7134_dev *dev = NULL;
990
	struct list_head *list;
991

992 993 994 995 996 997 998 999
	if (!dmasound_init && !dmasound_exit) {
		dmasound_init = alsa_device_init;
		dmasound_exit = alsa_device_exit;
	} else {
		printk(KERN_WARNING "saa7134 ALSA: can't load, DMA sound handler already assigned (probably to OSS)\n");
		return -EBUSY;
	}

1000
	printk(KERN_INFO "saa7134 ALSA driver for DMA sound loaded\n");
1001 1002

	list_for_each(list,&saa7134_devlist) {
1003 1004
		dev = list_entry(list, struct saa7134_dev, devlist);
		if (dev->dmasound.priv_data == NULL) {
1005
			alsa_device_init(dev);
1006 1007 1008 1009
		} else {
			printk(KERN_ERR "saa7134 ALSA: DMA sound is being handled by OSS. ignoring %s\n",dev->name);
			return -EBUSY;
		}
1010
	}
1011

1012
	if (dev == NULL)
1013 1014 1015
		printk(KERN_INFO "saa7134 ALSA: no saa7134 cards found\n");

	return 0;
1016

1017 1018 1019 1020 1021 1022
}

/*
 * Module destructor
 */

1023
static void saa7134_alsa_exit(void)
1024
{
1025
	int idx;
1026

1027
	for (idx = 0; idx < SNDRV_CARDS; idx++) {
1028
		snd_card_free(snd_saa7134_cards[idx]);
1029
	}
1030

1031 1032
	dmasound_init = NULL;
	dmasound_exit = NULL;
1033
	printk(KERN_INFO "saa7134 ALSA driver for DMA sound unloaded\n");
1034

1035
	return;
1036
}
1037

1038 1039
/* We initialize this late, to make sure the sound system is up and running */
late_initcall(saa7134_alsa_init);
1040 1041 1042
module_exit(saa7134_alsa_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Ricardo Cerqueira");
1043 1044 1045