diff options
Diffstat (limited to 'sound/atmel/ac97c.c')
-rw-r--r-- | sound/atmel/ac97c.c | 355 |
1 files changed, 266 insertions, 89 deletions
diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c index 0c0f8771656a..428121a7e705 100644 --- a/sound/atmel/ac97c.c +++ b/sound/atmel/ac97c.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/device.h> | 13 | #include <linux/device.h> |
14 | #include <linux/dmaengine.h> | 14 | #include <linux/dmaengine.h> |
15 | #include <linux/dma-mapping.h> | 15 | #include <linux/dma-mapping.h> |
16 | #include <linux/atmel_pdc.h> | ||
16 | #include <linux/init.h> | 17 | #include <linux/init.h> |
17 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
18 | #include <linux/module.h> | 19 | #include <linux/module.h> |
@@ -31,6 +32,10 @@ | |||
31 | 32 | ||
32 | #include <linux/dw_dmac.h> | 33 | #include <linux/dw_dmac.h> |
33 | 34 | ||
35 | #include <mach/cpu.h> | ||
36 | #include <mach/hardware.h> | ||
37 | #include <mach/gpio.h> | ||
38 | |||
34 | #include "ac97c.h" | 39 | #include "ac97c.h" |
35 | 40 | ||
36 | enum { | 41 | enum { |
@@ -63,6 +68,7 @@ struct atmel_ac97c { | |||
63 | u64 cur_format; | 68 | u64 cur_format; |
64 | unsigned int cur_rate; | 69 | unsigned int cur_rate; |
65 | unsigned long flags; | 70 | unsigned long flags; |
71 | int playback_period, capture_period; | ||
66 | /* Serialize access to opened variable */ | 72 | /* Serialize access to opened variable */ |
67 | spinlock_t lock; | 73 | spinlock_t lock; |
68 | void __iomem *regs; | 74 | void __iomem *regs; |
@@ -242,10 +248,12 @@ static int atmel_ac97c_playback_hw_params(struct snd_pcm_substream *substream, | |||
242 | if (retval < 0) | 248 | if (retval < 0) |
243 | return retval; | 249 | return retval; |
244 | /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ | 250 | /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ |
245 | if (retval == 1) | 251 | if (cpu_is_at32ap7000()) { |
246 | if (test_and_clear_bit(DMA_TX_READY, &chip->flags)) | 252 | /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ |
247 | dw_dma_cyclic_free(chip->dma.tx_chan); | 253 | if (retval == 1) |
248 | 254 | if (test_and_clear_bit(DMA_TX_READY, &chip->flags)) | |
255 | dw_dma_cyclic_free(chip->dma.tx_chan); | ||
256 | } | ||
249 | /* Set restrictions to params. */ | 257 | /* Set restrictions to params. */ |
250 | mutex_lock(&opened_mutex); | 258 | mutex_lock(&opened_mutex); |
251 | chip->cur_rate = params_rate(hw_params); | 259 | chip->cur_rate = params_rate(hw_params); |
@@ -266,9 +274,14 @@ static int atmel_ac97c_capture_hw_params(struct snd_pcm_substream *substream, | |||
266 | if (retval < 0) | 274 | if (retval < 0) |
267 | return retval; | 275 | return retval; |
268 | /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ | 276 | /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ |
269 | if (retval == 1) | 277 | if (cpu_is_at32ap7000()) { |
270 | if (test_and_clear_bit(DMA_RX_READY, &chip->flags)) | 278 | if (retval < 0) |
271 | dw_dma_cyclic_free(chip->dma.rx_chan); | 279 | return retval; |
280 | /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ | ||
281 | if (retval == 1) | ||
282 | if (test_and_clear_bit(DMA_RX_READY, &chip->flags)) | ||
283 | dw_dma_cyclic_free(chip->dma.rx_chan); | ||
284 | } | ||
272 | 285 | ||
273 | /* Set restrictions to params. */ | 286 | /* Set restrictions to params. */ |
274 | mutex_lock(&opened_mutex); | 287 | mutex_lock(&opened_mutex); |
@@ -282,16 +295,20 @@ static int atmel_ac97c_capture_hw_params(struct snd_pcm_substream *substream, | |||
282 | static int atmel_ac97c_playback_hw_free(struct snd_pcm_substream *substream) | 295 | static int atmel_ac97c_playback_hw_free(struct snd_pcm_substream *substream) |
283 | { | 296 | { |
284 | struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); | 297 | struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); |
285 | if (test_and_clear_bit(DMA_TX_READY, &chip->flags)) | 298 | if (cpu_is_at32ap7000()) { |
286 | dw_dma_cyclic_free(chip->dma.tx_chan); | 299 | if (test_and_clear_bit(DMA_TX_READY, &chip->flags)) |
300 | dw_dma_cyclic_free(chip->dma.tx_chan); | ||
301 | } | ||
287 | return snd_pcm_lib_free_pages(substream); | 302 | return snd_pcm_lib_free_pages(substream); |
288 | } | 303 | } |
289 | 304 | ||
290 | static int atmel_ac97c_capture_hw_free(struct snd_pcm_substream *substream) | 305 | static int atmel_ac97c_capture_hw_free(struct snd_pcm_substream *substream) |
291 | { | 306 | { |
292 | struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); | 307 | struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); |
293 | if (test_and_clear_bit(DMA_RX_READY, &chip->flags)) | 308 | if (cpu_is_at32ap7000()) { |
294 | dw_dma_cyclic_free(chip->dma.rx_chan); | 309 | if (test_and_clear_bit(DMA_RX_READY, &chip->flags)) |
310 | dw_dma_cyclic_free(chip->dma.rx_chan); | ||
311 | } | ||
295 | return snd_pcm_lib_free_pages(substream); | 312 | return snd_pcm_lib_free_pages(substream); |
296 | } | 313 | } |
297 | 314 | ||
@@ -299,9 +316,11 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream) | |||
299 | { | 316 | { |
300 | struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); | 317 | struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); |
301 | struct snd_pcm_runtime *runtime = substream->runtime; | 318 | struct snd_pcm_runtime *runtime = substream->runtime; |
319 | int block_size = frames_to_bytes(runtime, runtime->period_size); | ||
302 | unsigned long word = ac97c_readl(chip, OCA); | 320 | unsigned long word = ac97c_readl(chip, OCA); |
303 | int retval; | 321 | int retval; |
304 | 322 | ||
323 | chip->playback_period = 0; | ||
305 | word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT)); | 324 | word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT)); |
306 | 325 | ||
307 | /* assign channels to AC97C channel A */ | 326 | /* assign channels to AC97C channel A */ |
@@ -320,11 +339,16 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream) | |||
320 | ac97c_writel(chip, OCA, word); | 339 | ac97c_writel(chip, OCA, word); |
321 | 340 | ||
322 | /* configure sample format and size */ | 341 | /* configure sample format and size */ |
323 | word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16; | 342 | word = ac97c_readl(chip, CAMR); |
343 | if (chip->opened <= 1) | ||
344 | word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16; | ||
345 | else | ||
346 | word |= AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16; | ||
324 | 347 | ||
325 | switch (runtime->format) { | 348 | switch (runtime->format) { |
326 | case SNDRV_PCM_FORMAT_S16_LE: | 349 | case SNDRV_PCM_FORMAT_S16_LE: |
327 | word |= AC97C_CMR_CEM_LITTLE; | 350 | if (cpu_is_at32ap7000()) |
351 | word |= AC97C_CMR_CEM_LITTLE; | ||
328 | break; | 352 | break; |
329 | case SNDRV_PCM_FORMAT_S16_BE: /* fall through */ | 353 | case SNDRV_PCM_FORMAT_S16_BE: /* fall through */ |
330 | word &= ~(AC97C_CMR_CEM_LITTLE); | 354 | word &= ~(AC97C_CMR_CEM_LITTLE); |
@@ -363,9 +387,18 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream) | |||
363 | dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n", | 387 | dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n", |
364 | runtime->rate); | 388 | runtime->rate); |
365 | 389 | ||
366 | if (!test_bit(DMA_TX_READY, &chip->flags)) | 390 | if (cpu_is_at32ap7000()) { |
367 | retval = atmel_ac97c_prepare_dma(chip, substream, | 391 | if (!test_bit(DMA_TX_READY, &chip->flags)) |
368 | DMA_TO_DEVICE); | 392 | retval = atmel_ac97c_prepare_dma(chip, substream, |
393 | DMA_TO_DEVICE); | ||
394 | } else { | ||
395 | /* Initialize and start the PDC */ | ||
396 | writel(runtime->dma_addr, chip->regs + ATMEL_PDC_TPR); | ||
397 | writel(block_size / 2, chip->regs + ATMEL_PDC_TCR); | ||
398 | writel(runtime->dma_addr + block_size, | ||
399 | chip->regs + ATMEL_PDC_TNPR); | ||
400 | writel(block_size / 2, chip->regs + ATMEL_PDC_TNCR); | ||
401 | } | ||
369 | 402 | ||
370 | return retval; | 403 | return retval; |
371 | } | 404 | } |
@@ -374,9 +407,11 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream) | |||
374 | { | 407 | { |
375 | struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); | 408 | struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); |
376 | struct snd_pcm_runtime *runtime = substream->runtime; | 409 | struct snd_pcm_runtime *runtime = substream->runtime; |
410 | int block_size = frames_to_bytes(runtime, runtime->period_size); | ||
377 | unsigned long word = ac97c_readl(chip, ICA); | 411 | unsigned long word = ac97c_readl(chip, ICA); |
378 | int retval; | 412 | int retval; |
379 | 413 | ||
414 | chip->capture_period = 0; | ||
380 | word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT)); | 415 | word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT)); |
381 | 416 | ||
382 | /* assign channels to AC97C channel A */ | 417 | /* assign channels to AC97C channel A */ |
@@ -395,11 +430,16 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream) | |||
395 | ac97c_writel(chip, ICA, word); | 430 | ac97c_writel(chip, ICA, word); |
396 | 431 | ||
397 | /* configure sample format and size */ | 432 | /* configure sample format and size */ |
398 | word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16; | 433 | word = ac97c_readl(chip, CAMR); |
434 | if (chip->opened <= 1) | ||
435 | word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16; | ||
436 | else | ||
437 | word |= AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16; | ||
399 | 438 | ||
400 | switch (runtime->format) { | 439 | switch (runtime->format) { |
401 | case SNDRV_PCM_FORMAT_S16_LE: | 440 | case SNDRV_PCM_FORMAT_S16_LE: |
402 | word |= AC97C_CMR_CEM_LITTLE; | 441 | if (cpu_is_at32ap7000()) |
442 | word |= AC97C_CMR_CEM_LITTLE; | ||
403 | break; | 443 | break; |
404 | case SNDRV_PCM_FORMAT_S16_BE: /* fall through */ | 444 | case SNDRV_PCM_FORMAT_S16_BE: /* fall through */ |
405 | word &= ~(AC97C_CMR_CEM_LITTLE); | 445 | word &= ~(AC97C_CMR_CEM_LITTLE); |
@@ -438,9 +478,18 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream) | |||
438 | dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n", | 478 | dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n", |
439 | runtime->rate); | 479 | runtime->rate); |
440 | 480 | ||
441 | if (!test_bit(DMA_RX_READY, &chip->flags)) | 481 | if (cpu_is_at32ap7000()) { |
442 | retval = atmel_ac97c_prepare_dma(chip, substream, | 482 | if (!test_bit(DMA_RX_READY, &chip->flags)) |
443 | DMA_FROM_DEVICE); | 483 | retval = atmel_ac97c_prepare_dma(chip, substream, |
484 | DMA_FROM_DEVICE); | ||
485 | } else { | ||
486 | /* Initialize and start the PDC */ | ||
487 | writel(runtime->dma_addr, chip->regs + ATMEL_PDC_RPR); | ||
488 | writel(block_size / 2, chip->regs + ATMEL_PDC_RCR); | ||
489 | writel(runtime->dma_addr + block_size, | ||
490 | chip->regs + ATMEL_PDC_RNPR); | ||
491 | writel(block_size / 2, chip->regs + ATMEL_PDC_RNCR); | ||
492 | } | ||
444 | 493 | ||
445 | return retval; | 494 | return retval; |
446 | } | 495 | } |
@@ -449,7 +498,7 @@ static int | |||
449 | atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd) | 498 | atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd) |
450 | { | 499 | { |
451 | struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); | 500 | struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); |
452 | unsigned long camr; | 501 | unsigned long camr, ptcr = 0; |
453 | int retval = 0; | 502 | int retval = 0; |
454 | 503 | ||
455 | camr = ac97c_readl(chip, CAMR); | 504 | camr = ac97c_readl(chip, CAMR); |
@@ -458,15 +507,22 @@ atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd) | |||
458 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ | 507 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ |
459 | case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ | 508 | case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ |
460 | case SNDRV_PCM_TRIGGER_START: | 509 | case SNDRV_PCM_TRIGGER_START: |
461 | retval = dw_dma_cyclic_start(chip->dma.tx_chan); | 510 | if (cpu_is_at32ap7000()) { |
462 | if (retval) | 511 | retval = dw_dma_cyclic_start(chip->dma.tx_chan); |
463 | goto out; | 512 | if (retval) |
464 | camr |= AC97C_CMR_CENA; | 513 | goto out; |
514 | } else { | ||
515 | ptcr = ATMEL_PDC_TXTEN; | ||
516 | } | ||
517 | camr |= AC97C_CMR_CENA | AC97C_CSR_ENDTX; | ||
465 | break; | 518 | break; |
466 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ | 519 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ |
467 | case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ | 520 | case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ |
468 | case SNDRV_PCM_TRIGGER_STOP: | 521 | case SNDRV_PCM_TRIGGER_STOP: |
469 | dw_dma_cyclic_stop(chip->dma.tx_chan); | 522 | if (cpu_is_at32ap7000()) |
523 | dw_dma_cyclic_stop(chip->dma.tx_chan); | ||
524 | else | ||
525 | ptcr |= ATMEL_PDC_TXTDIS; | ||
470 | if (chip->opened <= 1) | 526 | if (chip->opened <= 1) |
471 | camr &= ~AC97C_CMR_CENA; | 527 | camr &= ~AC97C_CMR_CENA; |
472 | break; | 528 | break; |
@@ -476,6 +532,8 @@ atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd) | |||
476 | } | 532 | } |
477 | 533 | ||
478 | ac97c_writel(chip, CAMR, camr); | 534 | ac97c_writel(chip, CAMR, camr); |
535 | if (!cpu_is_at32ap7000()) | ||
536 | writel(ptcr, chip->regs + ATMEL_PDC_PTCR); | ||
479 | out: | 537 | out: |
480 | return retval; | 538 | return retval; |
481 | } | 539 | } |
@@ -484,24 +542,32 @@ static int | |||
484 | atmel_ac97c_capture_trigger(struct snd_pcm_substream *substream, int cmd) | 542 | atmel_ac97c_capture_trigger(struct snd_pcm_substream *substream, int cmd) |
485 | { | 543 | { |
486 | struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); | 544 | struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); |
487 | unsigned long camr; | 545 | unsigned long camr, ptcr = 0; |
488 | int retval = 0; | 546 | int retval = 0; |
489 | 547 | ||
490 | camr = ac97c_readl(chip, CAMR); | 548 | camr = ac97c_readl(chip, CAMR); |
549 | ptcr = readl(chip->regs + ATMEL_PDC_PTSR); | ||
491 | 550 | ||
492 | switch (cmd) { | 551 | switch (cmd) { |
493 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ | 552 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ |
494 | case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ | 553 | case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ |
495 | case SNDRV_PCM_TRIGGER_START: | 554 | case SNDRV_PCM_TRIGGER_START: |
496 | retval = dw_dma_cyclic_start(chip->dma.rx_chan); | 555 | if (cpu_is_at32ap7000()) { |
497 | if (retval) | 556 | retval = dw_dma_cyclic_start(chip->dma.rx_chan); |
498 | goto out; | 557 | if (retval) |
499 | camr |= AC97C_CMR_CENA; | 558 | goto out; |
559 | } else { | ||
560 | ptcr = ATMEL_PDC_RXTEN; | ||
561 | } | ||
562 | camr |= AC97C_CMR_CENA | AC97C_CSR_ENDRX; | ||
500 | break; | 563 | break; |
501 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ | 564 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ |
502 | case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ | 565 | case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ |
503 | case SNDRV_PCM_TRIGGER_STOP: | 566 | case SNDRV_PCM_TRIGGER_STOP: |
504 | dw_dma_cyclic_stop(chip->dma.rx_chan); | 567 | if (cpu_is_at32ap7000()) |
568 | dw_dma_cyclic_stop(chip->dma.rx_chan); | ||
569 | else | ||
570 | ptcr |= (ATMEL_PDC_RXTDIS); | ||
505 | if (chip->opened <= 1) | 571 | if (chip->opened <= 1) |
506 | camr &= ~AC97C_CMR_CENA; | 572 | camr &= ~AC97C_CMR_CENA; |
507 | break; | 573 | break; |
@@ -511,6 +577,8 @@ atmel_ac97c_capture_trigger(struct snd_pcm_substream *substream, int cmd) | |||
511 | } | 577 | } |
512 | 578 | ||
513 | ac97c_writel(chip, CAMR, camr); | 579 | ac97c_writel(chip, CAMR, camr); |
580 | if (!cpu_is_at32ap7000()) | ||
581 | writel(ptcr, chip->regs + ATMEL_PDC_PTCR); | ||
514 | out: | 582 | out: |
515 | return retval; | 583 | return retval; |
516 | } | 584 | } |
@@ -523,7 +591,10 @@ atmel_ac97c_playback_pointer(struct snd_pcm_substream *substream) | |||
523 | snd_pcm_uframes_t frames; | 591 | snd_pcm_uframes_t frames; |
524 | unsigned long bytes; | 592 | unsigned long bytes; |
525 | 593 | ||
526 | bytes = dw_dma_get_src_addr(chip->dma.tx_chan); | 594 | if (cpu_is_at32ap7000()) |
595 | bytes = dw_dma_get_src_addr(chip->dma.tx_chan); | ||
596 | else | ||
597 | bytes = readl(chip->regs + ATMEL_PDC_TPR); | ||
527 | bytes -= runtime->dma_addr; | 598 | bytes -= runtime->dma_addr; |
528 | 599 | ||
529 | frames = bytes_to_frames(runtime, bytes); | 600 | frames = bytes_to_frames(runtime, bytes); |
@@ -540,7 +611,10 @@ atmel_ac97c_capture_pointer(struct snd_pcm_substream *substream) | |||
540 | snd_pcm_uframes_t frames; | 611 | snd_pcm_uframes_t frames; |
541 | unsigned long bytes; | 612 | unsigned long bytes; |
542 | 613 | ||
543 | bytes = dw_dma_get_dst_addr(chip->dma.rx_chan); | 614 | if (cpu_is_at32ap7000()) |
615 | bytes = dw_dma_get_dst_addr(chip->dma.rx_chan); | ||
616 | else | ||
617 | bytes = readl(chip->regs + ATMEL_PDC_RPR); | ||
544 | bytes -= runtime->dma_addr; | 618 | bytes -= runtime->dma_addr; |
545 | 619 | ||
546 | frames = bytes_to_frames(runtime, bytes); | 620 | frames = bytes_to_frames(runtime, bytes); |
@@ -578,8 +652,11 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev) | |||
578 | u32 sr = ac97c_readl(chip, SR); | 652 | u32 sr = ac97c_readl(chip, SR); |
579 | u32 casr = ac97c_readl(chip, CASR); | 653 | u32 casr = ac97c_readl(chip, CASR); |
580 | u32 cosr = ac97c_readl(chip, COSR); | 654 | u32 cosr = ac97c_readl(chip, COSR); |
655 | u32 camr = ac97c_readl(chip, CAMR); | ||
581 | 656 | ||
582 | if (sr & AC97C_SR_CAEVT) { | 657 | if (sr & AC97C_SR_CAEVT) { |
658 | struct snd_pcm_runtime *runtime; | ||
659 | int offset, next_period, block_size; | ||
583 | dev_info(&chip->pdev->dev, "channel A event%s%s%s%s%s%s\n", | 660 | dev_info(&chip->pdev->dev, "channel A event%s%s%s%s%s%s\n", |
584 | casr & AC97C_CSR_OVRUN ? " OVRUN" : "", | 661 | casr & AC97C_CSR_OVRUN ? " OVRUN" : "", |
585 | casr & AC97C_CSR_RXRDY ? " RXRDY" : "", | 662 | casr & AC97C_CSR_RXRDY ? " RXRDY" : "", |
@@ -587,6 +664,50 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev) | |||
587 | casr & AC97C_CSR_TXEMPTY ? " TXEMPTY" : "", | 664 | casr & AC97C_CSR_TXEMPTY ? " TXEMPTY" : "", |
588 | casr & AC97C_CSR_TXRDY ? " TXRDY" : "", | 665 | casr & AC97C_CSR_TXRDY ? " TXRDY" : "", |
589 | !casr ? " NONE" : ""); | 666 | !casr ? " NONE" : ""); |
667 | if (!cpu_is_at32ap7000()) { | ||
668 | if ((casr & camr) & AC97C_CSR_ENDTX) { | ||
669 | runtime = chip->playback_substream->runtime; | ||
670 | block_size = frames_to_bytes(runtime, | ||
671 | runtime->period_size); | ||
672 | chip->playback_period++; | ||
673 | |||
674 | if (chip->playback_period == runtime->periods) | ||
675 | chip->playback_period = 0; | ||
676 | next_period = chip->playback_period + 1; | ||
677 | if (next_period == runtime->periods) | ||
678 | next_period = 0; | ||
679 | |||
680 | offset = block_size * next_period; | ||
681 | |||
682 | writel(runtime->dma_addr + offset, | ||
683 | chip->regs + ATMEL_PDC_TNPR); | ||
684 | writel(block_size / 2, | ||
685 | chip->regs + ATMEL_PDC_TNCR); | ||
686 | |||
687 | snd_pcm_period_elapsed( | ||
688 | chip->playback_substream); | ||
689 | } | ||
690 | if ((casr & camr) & AC97C_CSR_ENDRX) { | ||
691 | runtime = chip->capture_substream->runtime; | ||
692 | block_size = frames_to_bytes(runtime, | ||
693 | runtime->period_size); | ||
694 | chip->capture_period++; | ||
695 | |||
696 | if (chip->capture_period == runtime->periods) | ||
697 | chip->capture_period = 0; | ||
698 | next_period = chip->capture_period + 1; | ||
699 | if (next_period == runtime->periods) | ||
700 | next_period = 0; | ||
701 | |||
702 | offset = block_size * next_period; | ||
703 | |||
704 | writel(runtime->dma_addr + offset, | ||
705 | chip->regs + ATMEL_PDC_RNPR); | ||
706 | writel(block_size / 2, | ||
707 | chip->regs + ATMEL_PDC_RNCR); | ||
708 | snd_pcm_period_elapsed(chip->capture_substream); | ||
709 | } | ||
710 | } | ||
590 | retval = IRQ_HANDLED; | 711 | retval = IRQ_HANDLED; |
591 | } | 712 | } |
592 | 713 | ||
@@ -608,15 +729,50 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev) | |||
608 | return retval; | 729 | return retval; |
609 | } | 730 | } |
610 | 731 | ||
732 | static struct ac97_pcm at91_ac97_pcm_defs[] __devinitdata = { | ||
733 | /* Playback */ | ||
734 | { | ||
735 | .exclusive = 1, | ||
736 | .r = { { | ||
737 | .slots = ((1 << AC97_SLOT_PCM_LEFT) | ||
738 | | (1 << AC97_SLOT_PCM_RIGHT)), | ||
739 | } }, | ||
740 | }, | ||
741 | /* PCM in */ | ||
742 | { | ||
743 | .stream = 1, | ||
744 | .exclusive = 1, | ||
745 | .r = { { | ||
746 | .slots = ((1 << AC97_SLOT_PCM_LEFT) | ||
747 | | (1 << AC97_SLOT_PCM_RIGHT)), | ||
748 | } } | ||
749 | }, | ||
750 | /* Mic in */ | ||
751 | { | ||
752 | .stream = 1, | ||
753 | .exclusive = 1, | ||
754 | .r = { { | ||
755 | .slots = (1<<AC97_SLOT_MIC), | ||
756 | } } | ||
757 | }, | ||
758 | }; | ||
759 | |||
611 | static int __devinit atmel_ac97c_pcm_new(struct atmel_ac97c *chip) | 760 | static int __devinit atmel_ac97c_pcm_new(struct atmel_ac97c *chip) |
612 | { | 761 | { |
613 | struct snd_pcm *pcm; | 762 | struct snd_pcm *pcm; |
614 | struct snd_pcm_hardware hw = atmel_ac97c_hw; | 763 | struct snd_pcm_hardware hw = atmel_ac97c_hw; |
615 | int capture, playback, retval; | 764 | int capture, playback, retval, err; |
616 | 765 | ||
617 | capture = test_bit(DMA_RX_CHAN_PRESENT, &chip->flags); | 766 | capture = test_bit(DMA_RX_CHAN_PRESENT, &chip->flags); |
618 | playback = test_bit(DMA_TX_CHAN_PRESENT, &chip->flags); | 767 | playback = test_bit(DMA_TX_CHAN_PRESENT, &chip->flags); |
619 | 768 | ||
769 | if (!cpu_is_at32ap7000()) { | ||
770 | err = snd_ac97_pcm_assign(chip->ac97_bus, | ||
771 | ARRAY_SIZE(at91_ac97_pcm_defs), | ||
772 | at91_ac97_pcm_defs); | ||
773 | if (err) | ||
774 | return err; | ||
775 | } | ||
620 | retval = snd_pcm_new(chip->card, chip->card->shortname, | 776 | retval = snd_pcm_new(chip->card, chip->card->shortname, |
621 | chip->pdev->id, playback, capture, &pcm); | 777 | chip->pdev->id, playback, capture, &pcm); |
622 | if (retval) | 778 | if (retval) |
@@ -775,7 +931,12 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev) | |||
775 | return -ENXIO; | 931 | return -ENXIO; |
776 | } | 932 | } |
777 | 933 | ||
778 | pclk = clk_get(&pdev->dev, "pclk"); | 934 | if (cpu_is_at32ap7000()) { |
935 | pclk = clk_get(&pdev->dev, "pclk"); | ||
936 | } else { | ||
937 | pclk = clk_get(&pdev->dev, "ac97_clk"); | ||
938 | } | ||
939 | |||
779 | if (IS_ERR(pclk)) { | 940 | if (IS_ERR(pclk)) { |
780 | dev_dbg(&pdev->dev, "no peripheral clock\n"); | 941 | dev_dbg(&pdev->dev, "no peripheral clock\n"); |
781 | return PTR_ERR(pclk); | 942 | return PTR_ERR(pclk); |
@@ -844,43 +1005,52 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev) | |||
844 | goto err_ac97_bus; | 1005 | goto err_ac97_bus; |
845 | } | 1006 | } |
846 | 1007 | ||
847 | if (pdata->rx_dws.dma_dev) { | 1008 | if (cpu_is_at32ap7000()) { |
848 | struct dw_dma_slave *dws = &pdata->rx_dws; | 1009 | if (pdata->rx_dws.dma_dev) { |
849 | dma_cap_mask_t mask; | 1010 | struct dw_dma_slave *dws = &pdata->rx_dws; |
1011 | dma_cap_mask_t mask; | ||
850 | 1012 | ||
851 | dws->rx_reg = regs->start + AC97C_CARHR + 2; | 1013 | dws->rx_reg = regs->start + AC97C_CARHR + 2; |
852 | 1014 | ||
853 | dma_cap_zero(mask); | 1015 | dma_cap_zero(mask); |
854 | dma_cap_set(DMA_SLAVE, mask); | 1016 | dma_cap_set(DMA_SLAVE, mask); |
855 | 1017 | ||
856 | chip->dma.rx_chan = dma_request_channel(mask, filter, dws); | 1018 | chip->dma.rx_chan = dma_request_channel(mask, filter, |
1019 | dws); | ||
857 | 1020 | ||
858 | dev_info(&chip->pdev->dev, "using %s for DMA RX\n", | 1021 | dev_info(&chip->pdev->dev, "using %s for DMA RX\n", |
859 | dev_name(&chip->dma.rx_chan->dev->device)); | 1022 | dev_name(&chip->dma.rx_chan->dev->device)); |
860 | set_bit(DMA_RX_CHAN_PRESENT, &chip->flags); | 1023 | set_bit(DMA_RX_CHAN_PRESENT, &chip->flags); |
861 | } | 1024 | } |
862 | 1025 | ||
863 | if (pdata->tx_dws.dma_dev) { | 1026 | if (pdata->tx_dws.dma_dev) { |
864 | struct dw_dma_slave *dws = &pdata->tx_dws; | 1027 | struct dw_dma_slave *dws = &pdata->tx_dws; |
865 | dma_cap_mask_t mask; | 1028 | dma_cap_mask_t mask; |
866 | 1029 | ||
867 | dws->tx_reg = regs->start + AC97C_CATHR + 2; | 1030 | dws->tx_reg = regs->start + AC97C_CATHR + 2; |
868 | 1031 | ||
869 | dma_cap_zero(mask); | 1032 | dma_cap_zero(mask); |
870 | dma_cap_set(DMA_SLAVE, mask); | 1033 | dma_cap_set(DMA_SLAVE, mask); |
871 | 1034 | ||
872 | chip->dma.tx_chan = dma_request_channel(mask, filter, dws); | 1035 | chip->dma.tx_chan = dma_request_channel(mask, filter, |
1036 | dws); | ||
873 | 1037 | ||
874 | dev_info(&chip->pdev->dev, "using %s for DMA TX\n", | 1038 | dev_info(&chip->pdev->dev, "using %s for DMA TX\n", |
875 | dev_name(&chip->dma.tx_chan->dev->device)); | 1039 | dev_name(&chip->dma.tx_chan->dev->device)); |
876 | set_bit(DMA_TX_CHAN_PRESENT, &chip->flags); | 1040 | set_bit(DMA_TX_CHAN_PRESENT, &chip->flags); |
877 | } | 1041 | } |
878 | 1042 | ||
879 | if (!test_bit(DMA_RX_CHAN_PRESENT, &chip->flags) && | 1043 | if (!test_bit(DMA_RX_CHAN_PRESENT, &chip->flags) && |
880 | !test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) { | 1044 | !test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) { |
881 | dev_dbg(&pdev->dev, "DMA not available\n"); | 1045 | dev_dbg(&pdev->dev, "DMA not available\n"); |
882 | retval = -ENODEV; | 1046 | retval = -ENODEV; |
883 | goto err_dma; | 1047 | goto err_dma; |
1048 | } | ||
1049 | } else { | ||
1050 | /* Just pretend that we have DMA channel(for at91 i is actually | ||
1051 | * the PDC) */ | ||
1052 | set_bit(DMA_RX_CHAN_PRESENT, &chip->flags); | ||
1053 | set_bit(DMA_TX_CHAN_PRESENT, &chip->flags); | ||
884 | } | 1054 | } |
885 | 1055 | ||
886 | retval = atmel_ac97c_pcm_new(chip); | 1056 | retval = atmel_ac97c_pcm_new(chip); |
@@ -897,20 +1067,22 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev) | |||
897 | 1067 | ||
898 | platform_set_drvdata(pdev, card); | 1068 | platform_set_drvdata(pdev, card); |
899 | 1069 | ||
900 | dev_info(&pdev->dev, "Atmel AC97 controller at 0x%p\n", | 1070 | dev_info(&pdev->dev, "Atmel AC97 controller at 0x%p, irq = %d\n", |
901 | chip->regs); | 1071 | chip->regs, irq); |
902 | 1072 | ||
903 | return 0; | 1073 | return 0; |
904 | 1074 | ||
905 | err_dma: | 1075 | err_dma: |
906 | if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags)) | 1076 | if (cpu_is_at32ap7000()) { |
907 | dma_release_channel(chip->dma.rx_chan); | 1077 | if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags)) |
908 | if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) | 1078 | dma_release_channel(chip->dma.rx_chan); |
909 | dma_release_channel(chip->dma.tx_chan); | 1079 | if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) |
910 | clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags); | 1080 | dma_release_channel(chip->dma.tx_chan); |
911 | clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags); | 1081 | clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags); |
912 | chip->dma.rx_chan = NULL; | 1082 | clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags); |
913 | chip->dma.tx_chan = NULL; | 1083 | chip->dma.rx_chan = NULL; |
1084 | chip->dma.tx_chan = NULL; | ||
1085 | } | ||
914 | err_ac97_bus: | 1086 | err_ac97_bus: |
915 | snd_card_set_dev(card, NULL); | 1087 | snd_card_set_dev(card, NULL); |
916 | 1088 | ||
@@ -934,10 +1106,12 @@ static int atmel_ac97c_suspend(struct platform_device *pdev, pm_message_t msg) | |||
934 | struct snd_card *card = platform_get_drvdata(pdev); | 1106 | struct snd_card *card = platform_get_drvdata(pdev); |
935 | struct atmel_ac97c *chip = card->private_data; | 1107 | struct atmel_ac97c *chip = card->private_data; |
936 | 1108 | ||
937 | if (test_bit(DMA_RX_READY, &chip->flags)) | 1109 | if (cpu_is_at32ap7000()) { |
938 | dw_dma_cyclic_stop(chip->dma.rx_chan); | 1110 | if (test_bit(DMA_RX_READY, &chip->flags)) |
939 | if (test_bit(DMA_TX_READY, &chip->flags)) | 1111 | dw_dma_cyclic_stop(chip->dma.rx_chan); |
940 | dw_dma_cyclic_stop(chip->dma.tx_chan); | 1112 | if (test_bit(DMA_TX_READY, &chip->flags)) |
1113 | dw_dma_cyclic_stop(chip->dma.tx_chan); | ||
1114 | } | ||
941 | clk_disable(chip->pclk); | 1115 | clk_disable(chip->pclk); |
942 | 1116 | ||
943 | return 0; | 1117 | return 0; |
@@ -949,11 +1123,12 @@ static int atmel_ac97c_resume(struct platform_device *pdev) | |||
949 | struct atmel_ac97c *chip = card->private_data; | 1123 | struct atmel_ac97c *chip = card->private_data; |
950 | 1124 | ||
951 | clk_enable(chip->pclk); | 1125 | clk_enable(chip->pclk); |
952 | if (test_bit(DMA_RX_READY, &chip->flags)) | 1126 | if (cpu_is_at32ap7000()) { |
953 | dw_dma_cyclic_start(chip->dma.rx_chan); | 1127 | if (test_bit(DMA_RX_READY, &chip->flags)) |
954 | if (test_bit(DMA_TX_READY, &chip->flags)) | 1128 | dw_dma_cyclic_start(chip->dma.rx_chan); |
955 | dw_dma_cyclic_start(chip->dma.tx_chan); | 1129 | if (test_bit(DMA_TX_READY, &chip->flags)) |
956 | 1130 | dw_dma_cyclic_start(chip->dma.tx_chan); | |
1131 | } | ||
957 | return 0; | 1132 | return 0; |
958 | } | 1133 | } |
959 | #else | 1134 | #else |
@@ -978,14 +1153,16 @@ static int __devexit atmel_ac97c_remove(struct platform_device *pdev) | |||
978 | iounmap(chip->regs); | 1153 | iounmap(chip->regs); |
979 | free_irq(chip->irq, chip); | 1154 | free_irq(chip->irq, chip); |
980 | 1155 | ||
981 | if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags)) | 1156 | if (cpu_is_at32ap7000()) { |
982 | dma_release_channel(chip->dma.rx_chan); | 1157 | if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags)) |
983 | if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) | 1158 | dma_release_channel(chip->dma.rx_chan); |
984 | dma_release_channel(chip->dma.tx_chan); | 1159 | if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) |
985 | clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags); | 1160 | dma_release_channel(chip->dma.tx_chan); |
986 | clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags); | 1161 | clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags); |
987 | chip->dma.rx_chan = NULL; | 1162 | clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags); |
988 | chip->dma.tx_chan = NULL; | 1163 | chip->dma.rx_chan = NULL; |
1164 | chip->dma.tx_chan = NULL; | ||
1165 | } | ||
989 | 1166 | ||
990 | snd_card_set_dev(card, NULL); | 1167 | snd_card_set_dev(card, NULL); |
991 | snd_card_free(card); | 1168 | snd_card_free(card); |