aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/asihpi/asihpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/asihpi/asihpi.c')
-rw-r--r--sound/pci/asihpi/asihpi.c430
1 files changed, 203 insertions, 227 deletions
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c
index c80b0b863c54..31d7295f5c71 100644
--- a/sound/pci/asihpi/asihpi.c
+++ b/sound/pci/asihpi/asihpi.c
@@ -21,6 +21,7 @@
21 * would appreciate it if you grant us the right to use those modifications 21 * would appreciate it if you grant us the right to use those modifications
22 * for any purpose including commercial applications. 22 * for any purpose including commercial applications.
23 */ 23 */
24
24/* >0: print Hw params, timer vars. >1: print stream write/copy sizes */ 25/* >0: print Hw params, timer vars. >1: print stream write/copy sizes */
25#define REALLY_VERBOSE_LOGGING 0 26#define REALLY_VERBOSE_LOGGING 0
26 27
@@ -36,16 +37,12 @@
36#define VPRINTK2(...) 37#define VPRINTK2(...)
37#endif 38#endif
38 39
39#ifndef ASI_STYLE_NAMES
40/* not sure how ALSA style name should look */
41#define ASI_STYLE_NAMES 1
42#endif
43
44#include "hpi_internal.h" 40#include "hpi_internal.h"
45#include "hpimsginit.h" 41#include "hpimsginit.h"
46#include "hpioctl.h" 42#include "hpioctl.h"
47 43
48#include <linux/pci.h> 44#include <linux/pci.h>
45#include <linux/version.h>
49#include <linux/init.h> 46#include <linux/init.h>
50#include <linux/jiffies.h> 47#include <linux/jiffies.h>
51#include <linux/slab.h> 48#include <linux/slab.h>
@@ -85,11 +82,11 @@ MODULE_PARM_DESC(enable_hpi_hwdep,
85 82
86/* identify driver */ 83/* identify driver */
87#ifdef KERNEL_ALSA_BUILD 84#ifdef KERNEL_ALSA_BUILD
88static char *build_info = "built using headers from kernel source"; 85static char *build_info = "Built using headers from kernel source";
89module_param(build_info, charp, S_IRUGO); 86module_param(build_info, charp, S_IRUGO);
90MODULE_PARM_DESC(build_info, "built using headers from kernel source"); 87MODULE_PARM_DESC(build_info, "built using headers from kernel source");
91#else 88#else
92static char *build_info = "built within ALSA source"; 89static char *build_info = "Built within ALSA source";
93module_param(build_info, charp, S_IRUGO); 90module_param(build_info, charp, S_IRUGO);
94MODULE_PARM_DESC(build_info, "built within ALSA source"); 91MODULE_PARM_DESC(build_info, "built within ALSA source");
95#endif 92#endif
@@ -104,7 +101,7 @@ static struct hpi_hsubsys *ss; /* handle to HPI audio subsystem */
104 101
105/* defaults */ 102/* defaults */
106#define PERIODS_MIN 2 103#define PERIODS_MIN 2
107#define PERIOD_BYTES_MIN 2304 104#define PERIOD_BYTES_MIN 2048
108#define BUFFER_BYTES_MAX (512 * 1024) 105#define BUFFER_BYTES_MAX (512 * 1024)
109 106
110/*#define TIMER_MILLISECONDS 20 107/*#define TIMER_MILLISECONDS 20
@@ -155,8 +152,9 @@ struct snd_card_asihpi_pcm {
155 unsigned int pcm_size; 152 unsigned int pcm_size;
156 unsigned int pcm_count; 153 unsigned int pcm_count;
157 unsigned int bytes_per_sec; 154 unsigned int bytes_per_sec;
158 unsigned int pcm_irq_pos; /* IRQ position */ 155 unsigned int pcm_buf_host_rw_ofs; /* Host R/W pos */
159 unsigned int pcm_buf_pos; /* position in buffer */ 156 unsigned int pcm_buf_dma_ofs; /* DMA R/W offset in buffer */
157 unsigned int pcm_buf_elapsed_dma_ofs; /* DMA R/W offset in buffer */
160 struct snd_pcm_substream *substream; 158 struct snd_pcm_substream *substream;
161 u32 h_stream; 159 u32 h_stream;
162 struct hpi_format format; 160 struct hpi_format format;
@@ -244,14 +242,16 @@ static inline u16 hpi_stream_get_info_ex(
244 u32 *pauxiliary_data 242 u32 *pauxiliary_data
245) 243)
246{ 244{
245 u16 e;
247 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM) 246 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
248 return hpi_outstream_get_info_ex(hS, h_stream, pw_state, 247 e = hpi_outstream_get_info_ex(hS, h_stream, pw_state,
249 pbuffer_size, pdata_in_buffer, 248 pbuffer_size, pdata_in_buffer,
250 psample_count, pauxiliary_data); 249 psample_count, pauxiliary_data);
251 else 250 else
252 return hpi_instream_get_info_ex(hS, h_stream, pw_state, 251 e = hpi_instream_get_info_ex(hS, h_stream, pw_state,
253 pbuffer_size, pdata_in_buffer, 252 pbuffer_size, pdata_in_buffer,
254 psample_count, pauxiliary_data); 253 psample_count, pauxiliary_data);
254 return e;
255} 255}
256 256
257static inline u16 hpi_stream_group_add(struct hpi_hsubsys *hS, 257static inline u16 hpi_stream_group_add(struct hpi_hsubsys *hS,
@@ -299,11 +299,11 @@ static void print_hwparams(struct snd_pcm_hw_params *p)
299{ 299{
300 snd_printd("HWPARAMS \n"); 300 snd_printd("HWPARAMS \n");
301 snd_printd("samplerate %d \n", params_rate(p)); 301 snd_printd("samplerate %d \n", params_rate(p));
302 snd_printd("channels %d \n", params_channels(p)); 302 snd_printd("Channels %d \n", params_channels(p));
303 snd_printd("format %d \n", params_format(p)); 303 snd_printd("Format %d \n", params_format(p));
304 snd_printd("subformat %d \n", params_subformat(p)); 304 snd_printd("subformat %d \n", params_subformat(p));
305 snd_printd("buffer bytes %d \n", params_buffer_bytes(p)); 305 snd_printd("Buffer bytes %d \n", params_buffer_bytes(p));
306 snd_printd("period bytes %d \n", params_period_bytes(p)); 306 snd_printd("Period bytes %d \n", params_period_bytes(p));
307 snd_printd("access %d \n", params_access(p)); 307 snd_printd("access %d \n", params_access(p));
308 snd_printd("period_size %d \n", params_period_size(p)); 308 snd_printd("period_size %d \n", params_period_size(p));
309 snd_printd("periods %d \n", params_periods(p)); 309 snd_printd("periods %d \n", params_periods(p));
@@ -383,7 +383,7 @@ static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi,
383 HPI_CONTROL_SAMPLECLOCK, &h_control); 383 HPI_CONTROL_SAMPLECLOCK, &h_control);
384 if (err) { 384 if (err) {
385 snd_printk(KERN_ERR 385 snd_printk(KERN_ERR
386 "no local sampleclock, err %d\n", err); 386 "No local sampleclock, err %d\n", err);
387 } 387 }
388 388
389 for (idx = 0; idx < 100; idx++) { 389 for (idx = 0; idx < 100; idx++) {
@@ -391,7 +391,7 @@ static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi,
391 h_control, idx, &sample_rate)) { 391 h_control, idx, &sample_rate)) {
392 if (!idx) 392 if (!idx)
393 snd_printk(KERN_ERR 393 snd_printk(KERN_ERR
394 "local rate query failed\n"); 394 "Local rate query failed\n");
395 395
396 break; 396 break;
397 } 397 }
@@ -525,11 +525,27 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
525 snd_printd(KERN_INFO "pcm_size=%d, pcm_count=%d, bps=%d\n", 525 snd_printd(KERN_INFO "pcm_size=%d, pcm_count=%d, bps=%d\n",
526 dpcm->pcm_size, dpcm->pcm_count, bytes_per_sec); 526 dpcm->pcm_size, dpcm->pcm_count, bytes_per_sec);
527 527
528 dpcm->pcm_irq_pos = 0;
529 dpcm->pcm_buf_pos = 0;
530 return 0; 528 return 0;
531} 529}
532 530
531static int
532snd_card_asihpi_hw_free(struct snd_pcm_substream *substream)
533{
534 struct snd_pcm_runtime *runtime = substream->runtime;
535 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
536 if (dpcm->hpi_buffer_attached)
537 hpi_stream_host_buffer_detach(ss, dpcm->h_stream);
538
539 snd_pcm_lib_free_pages(substream);
540 return 0;
541}
542
543static void snd_card_asihpi_runtime_free(struct snd_pcm_runtime *runtime)
544{
545 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
546 kfree(dpcm);
547}
548
533static void snd_card_asihpi_pcm_timer_start(struct snd_pcm_substream * 549static void snd_card_asihpi_pcm_timer_start(struct snd_pcm_substream *
534 substream) 550 substream)
535{ 551{
@@ -537,9 +553,8 @@ static void snd_card_asihpi_pcm_timer_start(struct snd_pcm_substream *
537 struct snd_card_asihpi_pcm *dpcm = runtime->private_data; 553 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
538 int expiry; 554 int expiry;
539 555
540 expiry = (dpcm->pcm_count * HZ / dpcm->bytes_per_sec); 556 expiry = HZ / 100;; //? (dpcm->pcm_count * HZ / dpcm->bytes_per_sec);
541 /* wait longer the first time, for samples to propagate */ 557 expiry = max(expiry, 1); /* don't let it be zero! */
542 expiry = max(expiry, 20);
543 dpcm->timer.expires = jiffies + expiry; 558 dpcm->timer.expires = jiffies + expiry;
544 dpcm->respawn_timer = 1; 559 dpcm->respawn_timer = 1;
545 add_timer(&dpcm->timer); 560 add_timer(&dpcm->timer);
@@ -562,13 +577,13 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
562 struct snd_pcm_substream *s; 577 struct snd_pcm_substream *s;
563 u16 e; 578 u16 e;
564 579
565 snd_printd("trigger %dstream %d\n", 580 snd_printd("Trigger %dstream %d\n",
566 substream->stream, substream->number); 581 substream->stream, substream->number);
567 switch (cmd) { 582 switch (cmd) {
568 case SNDRV_PCM_TRIGGER_START: 583 case SNDRV_PCM_TRIGGER_START:
569 snd_pcm_group_for_each_entry(s, substream) { 584 snd_pcm_group_for_each_entry(s, substream) {
570 struct snd_card_asihpi_pcm *ds; 585 struct snd_pcm_runtime *runtime = s->runtime;
571 ds = s->runtime->private_data; 586 struct snd_card_asihpi_pcm *ds = runtime->private_data;
572 587
573 if (snd_pcm_substream_chip(s) != card) 588 if (snd_pcm_substream_chip(s) != card)
574 continue; 589 continue;
@@ -576,17 +591,19 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
576 if ((s->stream == SNDRV_PCM_STREAM_PLAYBACK) && 591 if ((s->stream == SNDRV_PCM_STREAM_PLAYBACK) &&
577 (card->support_mmap)) { 592 (card->support_mmap)) {
578 /* How do I know how much valid data is present 593 /* How do I know how much valid data is present
579 * in buffer? Just guessing 2 periods, but if 594 * in buffer? Must be at least one period!
595 * Guessing 2 periods, but if
580 * buffer is bigger it may contain even more 596 * buffer is bigger it may contain even more
581 * data?? 597 * data??
582 */ 598 */
583 unsigned int preload = ds->pcm_count * 2; 599 unsigned int preload = ds->pcm_count * 1;
584 VPRINTK2("preload %d\n", preload); 600 VPRINTK2("Preload x%x\n", preload);
585 hpi_handle_error(hpi_outstream_write_buf( 601 hpi_handle_error(hpi_outstream_write_buf(
586 ss, ds->h_stream, 602 ss, ds->h_stream,
587 &s->runtime->dma_area[0], 603 &runtime->dma_area[0],
588 preload, 604 preload,
589 &ds->format)); 605 &ds->format));
606 ds->pcm_buf_host_rw_ofs = preload;
590 } 607 }
591 608
592 if (card->support_grouping) { 609 if (card->support_grouping) {
@@ -604,7 +621,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
604 } else 621 } else
605 break; 622 break;
606 } 623 }
607 snd_printd("start\n"); 624 snd_printd("Start\n");
608 /* start the master stream */ 625 /* start the master stream */
609 snd_card_asihpi_pcm_timer_start(substream); 626 snd_card_asihpi_pcm_timer_start(substream);
610 hpi_handle_error(hpi_stream_start(ss, dpcm->h_stream)); 627 hpi_handle_error(hpi_stream_start(ss, dpcm->h_stream));
@@ -627,7 +644,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
627 } else 644 } else
628 break; 645 break;
629 } 646 }
630 snd_printd("stop\n"); 647 snd_printd("Stop\n");
631 648
632 /* _prepare and _hwparams reset the stream */ 649 /* _prepare and _hwparams reset the stream */
633 hpi_handle_error(hpi_stream_stop(ss, dpcm->h_stream)); 650 hpi_handle_error(hpi_stream_stop(ss, dpcm->h_stream));
@@ -641,12 +658,12 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
641 break; 658 break;
642 659
643 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 660 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
644 snd_printd("pause release\n"); 661 snd_printd("Pause release\n");
645 hpi_handle_error(hpi_stream_start(ss, dpcm->h_stream)); 662 hpi_handle_error(hpi_stream_start(ss, dpcm->h_stream));
646 snd_card_asihpi_pcm_timer_start(substream); 663 snd_card_asihpi_pcm_timer_start(substream);
647 break; 664 break;
648 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 665 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
649 snd_printd("pause\n"); 666 snd_printd("Pause\n");
650 snd_card_asihpi_pcm_timer_stop(substream); 667 snd_card_asihpi_pcm_timer_stop(substream);
651 hpi_handle_error(hpi_stream_stop(ss, dpcm->h_stream)); 668 hpi_handle_error(hpi_stream_stop(ss, dpcm->h_stream));
652 break; 669 break;
@@ -658,38 +675,20 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
658 return 0; 675 return 0;
659} 676}
660 677
661static int
662snd_card_asihpi_hw_free(struct snd_pcm_substream *substream)
663{
664 struct snd_pcm_runtime *runtime = substream->runtime;
665 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
666 if (dpcm->hpi_buffer_attached)
667 hpi_stream_host_buffer_detach(ss, dpcm->h_stream);
668
669 snd_pcm_lib_free_pages(substream);
670 return 0;
671}
672
673static void snd_card_asihpi_runtime_free(struct snd_pcm_runtime *runtime)
674{
675 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
676 kfree(dpcm);
677}
678
679/*algorithm outline 678/*algorithm outline
680 Without linking degenerates to getting single stream pos etc 679 Without linking degenerates to getting single stream pos etc
681 Without mmap 2nd loop degenerates to snd_pcm_period_elapsed 680 Without mmap 2nd loop degenerates to snd_pcm_period_elapsed
682*/ 681*/
683/* 682/*
684buf_pos=get_buf_pos(s); 683pcm_buf_dma_ofs=get_buf_pos(s);
685for_each_linked_stream(s) { 684for_each_linked_stream(s) {
686 buf_pos=get_buf_pos(s); 685 pcm_buf_dma_ofs=get_buf_pos(s);
687 min_buf_pos = modulo_min(min_buf_pos, buf_pos, pcm_size) 686 min_buf_pos = modulo_min(min_buf_pos, pcm_buf_dma_ofs, pcm_size)
688 new_data = min(new_data, calc_new_data(buf_pos,irq_pos) 687 new_data = min(new_data, calc_new_data(pcm_buf_dma_ofs,irq_pos)
689} 688}
690timer.expires = jiffies + predict_next_period_ready(min_buf_pos); 689timer.expires = jiffies + predict_next_period_ready(min_buf_pos);
691for_each_linked_stream(s) { 690for_each_linked_stream(s) {
692 s->buf_pos = min_buf_pos; 691 s->pcm_buf_dma_ofs = min_buf_pos;
693 if (new_data > pcm_count) { 692 if (new_data > pcm_count) {
694 if (mmap) { 693 if (mmap) {
695 irq_pos = (irq_pos + pcm_count) % pcm_size; 694 irq_pos = (irq_pos + pcm_count) % pcm_size;
@@ -728,11 +727,11 @@ static void snd_card_asihpi_timer_function(unsigned long data)
728 struct snd_pcm_runtime *runtime; 727 struct snd_pcm_runtime *runtime;
729 struct snd_pcm_substream *s; 728 struct snd_pcm_substream *s;
730 unsigned int newdata = 0; 729 unsigned int newdata = 0;
731 unsigned int buf_pos, min_buf_pos = 0; 730 unsigned int pcm_buf_dma_ofs, min_buf_pos = 0;
732 unsigned int remdata, xfercount, next_jiffies; 731 unsigned int remdata, xfercount, next_jiffies;
733 int first = 1; 732 int first = 1;
734 u16 state; 733 u16 state;
735 u32 buffer_size, data_avail, samples_played, aux; 734 u32 buffer_size, bytes_avail, samples_played, on_card_bytes;
736 735
737 /* find minimum newdata and buffer pos in group */ 736 /* find minimum newdata and buffer pos in group */
738 snd_pcm_group_for_each_entry(s, dpcm->substream) { 737 snd_pcm_group_for_each_entry(s, dpcm->substream) {
@@ -744,35 +743,34 @@ static void snd_card_asihpi_timer_function(unsigned long data)
744 743
745 hpi_handle_error(hpi_stream_get_info_ex(ss, 744 hpi_handle_error(hpi_stream_get_info_ex(ss,
746 ds->h_stream, &state, 745 ds->h_stream, &state,
747 &buffer_size, &data_avail, 746 &buffer_size, &bytes_avail,
748 &samples_played, &aux)); 747 &samples_played, &on_card_bytes));
749 748
750 /* number of bytes in on-card buffer */ 749 /* number of bytes in on-card buffer */
751 runtime->delay = aux; 750 runtime->delay = on_card_bytes;
752 751
753 if (state == HPI_STATE_DRAINED) { 752 if (state == HPI_STATE_DRAINED) {
754 snd_printd(KERN_WARNING "outstream %d drained\n", 753 snd_printd(KERN_WARNING "outstream %d drained\n",
755 s->number); 754 s->number);
756 snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); 755 //snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN);
757 return; 756 //return;
758 } 757 }
759 758
760 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { 759 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK)
761 buf_pos = frames_to_bytes(runtime, samples_played); 760 pcm_buf_dma_ofs = ds->pcm_buf_host_rw_ofs - bytes_avail;
762 } else { 761 else
763 buf_pos = data_avail + ds->pcm_irq_pos; 762 pcm_buf_dma_ofs = bytes_avail + ds->pcm_buf_host_rw_ofs;
764 }
765 763
766 if (first) { 764 if (first) {
767 /* can't statically init min when wrap is involved */ 765 /* can't statically init min when wrap is involved */
768 min_buf_pos = buf_pos; 766 min_buf_pos = pcm_buf_dma_ofs;
769 newdata = (buf_pos - ds->pcm_irq_pos) % ds->pcm_size; 767 newdata = (pcm_buf_dma_ofs - ds->pcm_buf_elapsed_dma_ofs) % ds->pcm_size;
770 first = 0; 768 first = 0;
771 } else { 769 } else {
772 min_buf_pos = 770 min_buf_pos =
773 modulo_min(min_buf_pos, buf_pos, UINT_MAX+1L); 771 modulo_min(min_buf_pos, pcm_buf_dma_ofs, UINT_MAX+1L);
774 newdata = min( 772 newdata = min(
775 (buf_pos - ds->pcm_irq_pos) % ds->pcm_size, 773 (pcm_buf_dma_ofs - ds->pcm_buf_elapsed_dma_ofs) % ds->pcm_size,
776 newdata); 774 newdata);
777 } 775 }
778 776
@@ -781,29 +779,40 @@ static void snd_card_asihpi_timer_function(unsigned long data)
781 runtime->status->hw_ptr), 779 runtime->status->hw_ptr),
782 (unsigned long)frames_to_bytes(runtime, 780 (unsigned long)frames_to_bytes(runtime,
783 runtime->control->appl_ptr)); 781 runtime->control->appl_ptr));
782
784 VPRINTK1("%d S=%d, irq=%04X, pos=x%04X, left=x%04X," 783 VPRINTK1("%d S=%d, irq=%04X, pos=x%04X, left=x%04X,"
785 " aux=x%04X space=x%04X\n", s->number, 784 " aux=x%04X space=x%04X\n", s->number,
786 state, ds->pcm_irq_pos, buf_pos, (int)data_avail, 785 state, ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs, (int)bytes_avail,
787 (int)aux, buffer_size-data_avail); 786 (int)on_card_bytes, buffer_size-bytes_avail);
788 } 787 }
788 pcm_buf_dma_ofs = min_buf_pos;
789 789
790 remdata = newdata % dpcm->pcm_count; 790 remdata = newdata % dpcm->pcm_count;
791 xfercount = newdata - remdata; /* a multiple of pcm_count */ 791 xfercount = newdata - remdata; /* a multiple of pcm_count */
792 next_jiffies = ((dpcm->pcm_count-remdata) * HZ / dpcm->bytes_per_sec)+1; 792 /* come back when on_card_bytes has decreased enough to allow
793 next_jiffies = max(next_jiffies, 2U * HZ / 1000U); 793 write to happen, or when data has been consumed to make another
794 period
795 */
796 if (xfercount && (on_card_bytes > dpcm->pcm_count))
797 next_jiffies = ((on_card_bytes - dpcm->pcm_count) * HZ / dpcm->bytes_per_sec);
798 else
799 next_jiffies = ((dpcm->pcm_count - remdata) * HZ / dpcm->bytes_per_sec);
800
801 next_jiffies = max(next_jiffies, 1U);
794 dpcm->timer.expires = jiffies + next_jiffies; 802 dpcm->timer.expires = jiffies + next_jiffies;
795 VPRINTK1("jif %d buf pos x%04X newdata x%04X xc x%04X\n", 803 VPRINTK1("jif %d buf pos x%04X newdata x%04X xfer x%04X\n",
796 next_jiffies, min_buf_pos, newdata, xfercount); 804 next_jiffies, pcm_buf_dma_ofs, newdata, xfercount);
805
797 806
798 snd_pcm_group_for_each_entry(s, dpcm->substream) { 807 snd_pcm_group_for_each_entry(s, dpcm->substream) {
799 struct snd_card_asihpi_pcm *ds = s->runtime->private_data; 808 struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
800 ds->pcm_buf_pos = min_buf_pos;
801 809
802 if (xfercount) { 810 ds->pcm_buf_dma_ofs = pcm_buf_dma_ofs;
811
812 if (xfercount && (on_card_bytes <= ds->pcm_count)) {
803 if (card->support_mmap) { 813 if (card->support_mmap) {
804 ds->pcm_irq_pos = ds->pcm_irq_pos + xfercount;
805 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { 814 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
806 VPRINTK2("write OS%d x%04x\n", 815 VPRINTK2("Write OS%d x%04x\n",
807 s->number, 816 s->number,
808 ds->pcm_count); 817 ds->pcm_count);
809 hpi_handle_error( 818 hpi_handle_error(
@@ -814,15 +823,17 @@ static void snd_card_asihpi_timer_function(unsigned long data)
814 xfercount, 823 xfercount,
815 &ds->format)); 824 &ds->format));
816 } else { 825 } else {
817 VPRINTK2("read IS%d x%04x\n", 826 VPRINTK2("Read IS%d x%04x\n",
818 s->number, 827 s->number,
819 dpcm->pcm_count); 828 xfercount);
820 hpi_handle_error( 829 hpi_handle_error(
821 hpi_instream_read_buf( 830 hpi_instream_read_buf(
822 ss, ds->h_stream, 831 ss, ds->h_stream,
823 NULL, xfercount)); 832 NULL, xfercount));
824 } 833 }
834 ds->pcm_buf_host_rw_ofs = ds->pcm_buf_host_rw_ofs + xfercount;
825 } /* else R/W will be handled by read/write callbacks */ 835 } /* else R/W will be handled by read/write callbacks */
836 ds->pcm_buf_elapsed_dma_ofs = pcm_buf_dma_ofs;
826 snd_pcm_period_elapsed(s); 837 snd_pcm_period_elapsed(s);
827 } 838 }
828 } 839 }
@@ -848,9 +859,9 @@ static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream *
848 snd_printd(KERN_INFO "playback prepare %d\n", substream->number); 859 snd_printd(KERN_INFO "playback prepare %d\n", substream->number);
849 860
850 hpi_handle_error(hpi_outstream_reset(ss, dpcm->h_stream)); 861 hpi_handle_error(hpi_outstream_reset(ss, dpcm->h_stream));
851 dpcm->pcm_irq_pos = 0; 862 dpcm->pcm_buf_host_rw_ofs = 0;
852 dpcm->pcm_buf_pos = 0; 863 dpcm->pcm_buf_dma_ofs = 0;
853 864 dpcm->pcm_buf_elapsed_dma_ofs = 0;
854 return 0; 865 return 0;
855} 866}
856 867
@@ -861,27 +872,8 @@ snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream)
861 struct snd_card_asihpi_pcm *dpcm = runtime->private_data; 872 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
862 snd_pcm_uframes_t ptr; 873 snd_pcm_uframes_t ptr;
863 874
864 u32 samples_played; 875 ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->pcm_size);
865 u16 err; 876 //VPRINTK2("playback_pointer=x%04lx\n", (unsigned long)ptr);
866
867 if (!snd_pcm_stream_linked(substream)) {
868 /* NOTE, can use samples played for playback position here and
869 * in timer fn because it LAGS the actual read pointer, and is a
870 * better representation of actual playout position
871 */
872 err = hpi_outstream_get_info_ex(ss, dpcm->h_stream, NULL,
873 NULL, NULL,
874 &samples_played, NULL);
875 hpi_handle_error(err);
876
877 dpcm->pcm_buf_pos = frames_to_bytes(runtime, samples_played);
878 }
879 /* else must return most conservative value found in timer func
880 * by looping over all streams
881 */
882
883 ptr = bytes_to_frames(runtime, dpcm->pcm_buf_pos % dpcm->pcm_size);
884 VPRINTK2("playback_pointer=%04ld\n", (unsigned long)ptr);
885 return ptr; 877 return ptr;
886} 878}
887 879
@@ -998,7 +990,7 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
998 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 990 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
999 card->update_interval_frames); 991 card->update_interval_frames);
1000 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 992 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1001 card->update_interval_frames * 4, UINT_MAX); 993 card->update_interval_frames * 2, UINT_MAX);
1002 994
1003 snd_pcm_set_sync(substream); 995 snd_pcm_set_sync(substream);
1004 996
@@ -1039,6 +1031,8 @@ static int snd_card_asihpi_playback_copy(struct snd_pcm_substream *substream,
1039 hpi_handle_error(hpi_outstream_write_buf(ss, dpcm->h_stream, 1031 hpi_handle_error(hpi_outstream_write_buf(ss, dpcm->h_stream,
1040 runtime->dma_area, len, &dpcm->format)); 1032 runtime->dma_area, len, &dpcm->format));
1041 1033
1034 dpcm->pcm_buf_host_rw_ofs = dpcm->pcm_buf_host_rw_ofs + len;
1035
1042 return 0; 1036 return 0;
1043} 1037}
1044 1038
@@ -1091,13 +1085,13 @@ snd_card_asihpi_capture_pointer(struct snd_pcm_substream *substream)
1091 struct snd_pcm_runtime *runtime = substream->runtime; 1085 struct snd_pcm_runtime *runtime = substream->runtime;
1092 struct snd_card_asihpi_pcm *dpcm = runtime->private_data; 1086 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1093 1087
1094 VPRINTK2("capture pointer %d=%d\n", 1088 VPRINTK2("Capture pointer %d=%d\n",
1095 substream->number, dpcm->pcm_buf_pos); 1089 substream->number, dpcm->pcm_buf_dma_ofs);
1096 /* NOTE Unlike playback can't use actual dwSamplesPlayed 1090 /* NOTE Unlike playback can't use actual samples_played
1097 for the capture position, because those samples aren't yet in 1091 for the capture position, because those samples aren't yet in
1098 the local buffer available for reading. 1092 the local buffer available for reading.
1099 */ 1093 */
1100 return bytes_to_frames(runtime, dpcm->pcm_buf_pos % dpcm->pcm_size); 1094 return bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->pcm_size);
1101} 1095}
1102 1096
1103static int snd_card_asihpi_capture_ioctl(struct snd_pcm_substream *substream, 1097static int snd_card_asihpi_capture_ioctl(struct snd_pcm_substream *substream,
@@ -1112,10 +1106,11 @@ static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream)
1112 struct snd_card_asihpi_pcm *dpcm = runtime->private_data; 1106 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1113 1107
1114 hpi_handle_error(hpi_instream_reset(ss, dpcm->h_stream)); 1108 hpi_handle_error(hpi_instream_reset(ss, dpcm->h_stream));
1115 dpcm->pcm_irq_pos = 0; 1109 dpcm->pcm_buf_host_rw_ofs = 0;
1116 dpcm->pcm_buf_pos = 0; 1110 dpcm->pcm_buf_dma_ofs = 0;
1111 dpcm->pcm_buf_elapsed_dma_ofs = 0;
1117 1112
1118 snd_printd("capture prepare %d\n", substream->number); 1113 snd_printd("Capture Prepare %d\n", substream->number);
1119 return 0; 1114 return 0;
1120} 1115}
1121 1116
@@ -1209,6 +1204,9 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
1209 snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_MMAP | 1204 snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_MMAP |
1210 SNDRV_PCM_INFO_MMAP_VALID; 1205 SNDRV_PCM_INFO_MMAP_VALID;
1211 1206
1207 if (card->support_grouping)
1208 snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_SYNC_START;
1209
1212 runtime->hw = snd_card_asihpi_capture; 1210 runtime->hw = snd_card_asihpi_capture;
1213 1211
1214 if (card->support_mmap) 1212 if (card->support_mmap)
@@ -1241,18 +1239,17 @@ static int snd_card_asihpi_capture_copy(struct snd_pcm_substream *substream,
1241{ 1239{
1242 struct snd_pcm_runtime *runtime = substream->runtime; 1240 struct snd_pcm_runtime *runtime = substream->runtime;
1243 struct snd_card_asihpi_pcm *dpcm = runtime->private_data; 1241 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1244 u32 data_size; 1242 u32 len;
1245 1243
1246 data_size = frames_to_bytes(runtime, count); 1244 len = frames_to_bytes(runtime, count);
1247 1245
1248 VPRINTK2("capture copy%d %d bytes\n", substream->number, data_size); 1246 VPRINTK2("Capture copy%d %d bytes\n", substream->number, len);
1249 hpi_handle_error(hpi_instream_read_buf(ss, dpcm->h_stream, 1247 hpi_handle_error(hpi_instream_read_buf(ss, dpcm->h_stream,
1250 runtime->dma_area, data_size)); 1248 runtime->dma_area, len));
1251 1249
1252 /* Used by capture_pointer */ 1250 dpcm->pcm_buf_host_rw_ofs = dpcm->pcm_buf_host_rw_ofs + len;
1253 dpcm->pcm_irq_pos = dpcm->pcm_irq_pos + data_size;
1254 1251
1255 if (copy_to_user(dst, runtime->dma_area, data_size)) 1252 if (copy_to_user(dst, runtime->dma_area, len))
1256 return -EFAULT; 1253 return -EFAULT;
1257 1254
1258 return 0; 1255 return 0;
@@ -1287,7 +1284,7 @@ static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi,
1287 struct snd_pcm *pcm; 1284 struct snd_pcm *pcm;
1288 int err; 1285 int err;
1289 1286
1290 err = snd_pcm_new(asihpi->card, "asihpi PCM", device, 1287 err = snd_pcm_new(asihpi->card, "Asihpi PCM", device,
1291 asihpi->num_outstreams, asihpi->num_instreams, 1288 asihpi->num_outstreams, asihpi->num_instreams,
1292 &pcm); 1289 &pcm);
1293 if (err < 0) 1290 if (err < 0)
@@ -1307,7 +1304,7 @@ static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi,
1307 1304
1308 pcm->private_data = asihpi; 1305 pcm->private_data = asihpi;
1309 pcm->info_flags = 0; 1306 pcm->info_flags = 0;
1310 strcpy(pcm->name, "asihpi PCM"); 1307 strcpy(pcm->name, "Asihpi PCM");
1311 1308
1312 /*? do we want to emulate MMAP for non-BBM cards? 1309 /*? do we want to emulate MMAP for non-BBM cards?
1313 Jack doesn't work with ALSAs MMAP emulation - WHY NOT? */ 1310 Jack doesn't work with ALSAs MMAP emulation - WHY NOT? */
@@ -1330,7 +1327,7 @@ struct hpi_control {
1330 char name[44]; /* copied to snd_ctl_elem_id.name[44]; */ 1327 char name[44]; /* copied to snd_ctl_elem_id.name[44]; */
1331}; 1328};
1332 1329
1333static char *asihpi_tuner_band_names[] = 1330static const char * const asihpi_tuner_band_names[] =
1334{ 1331{
1335 "invalid", 1332 "invalid",
1336 "AM", 1333 "AM",
@@ -1349,70 +1346,38 @@ compile_time_assert(
1349 (HPI_TUNER_BAND_LAST+1)), 1346 (HPI_TUNER_BAND_LAST+1)),
1350 assert_tuner_band_names_size); 1347 assert_tuner_band_names_size);
1351 1348
1352#if ASI_STYLE_NAMES 1349static const char * const asihpi_src_names[] =
1353static char *asihpi_src_names[] =
1354{ 1350{
1355 "no source", 1351 "no source",
1356 "outstream", 1352 "PCM",
1357 "line_in", 1353 "Line",
1358 "aes_in", 1354 "Digital",
1359 "tuner", 1355 "Tuner",
1360 "RF", 1356 "RF",
1361 "clock", 1357 "Clock",
1362 "bitstr", 1358 "Bitstream",
1363 "mic", 1359 "Microphone",
1364 "cobranet", 1360 "Cobranet",
1365 "analog_in", 1361 "Analog",
1366 "adapter", 1362 "Adapter",
1367}; 1363};
1368#else
1369static char *asihpi_src_names[] =
1370{
1371 "no source",
1372 "PCM playback",
1373 "line in",
1374 "digital in",
1375 "tuner",
1376 "RF",
1377 "clock",
1378 "bitstream",
1379 "mic",
1380 "cobranet in",
1381 "analog in",
1382 "adapter",
1383};
1384#endif
1385 1364
1386compile_time_assert( 1365compile_time_assert(
1387 (ARRAY_SIZE(asihpi_src_names) == 1366 (ARRAY_SIZE(asihpi_src_names) ==
1388 (HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_NONE+1)), 1367 (HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_NONE+1)),
1389 assert_src_names_size); 1368 assert_src_names_size);
1390 1369
1391#if ASI_STYLE_NAMES 1370static const char * const asihpi_dst_names[] =
1392static char *asihpi_dst_names[] =
1393{
1394 "no destination",
1395 "instream",
1396 "line_out",
1397 "aes_out",
1398 "RF",
1399 "speaker" ,
1400 "cobranet",
1401 "analog_out",
1402};
1403#else
1404static char *asihpi_dst_names[] =
1405{ 1371{
1406 "no destination", 1372 "no destination",
1407 "PCM capture", 1373 "PCM",
1408 "line out", 1374 "Line",
1409 "digital out", 1375 "Digital",
1410 "RF", 1376 "RF",
1411 "speaker", 1377 "Speaker",
1412 "cobranet out", 1378 "Cobranet Out",
1413 "analog out" 1379 "Analog"
1414}; 1380};
1415#endif
1416 1381
1417compile_time_assert( 1382compile_time_assert(
1418 (ARRAY_SIZE(asihpi_dst_names) == 1383 (ARRAY_SIZE(asihpi_dst_names) ==
@@ -1438,30 +1403,43 @@ static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control,
1438 struct hpi_control *hpi_ctl, 1403 struct hpi_control *hpi_ctl,
1439 char *name) 1404 char *name)
1440{ 1405{
1406 char *dir = "";
1441 memset(snd_control, 0, sizeof(*snd_control)); 1407 memset(snd_control, 0, sizeof(*snd_control));
1442 snd_control->name = hpi_ctl->name; 1408 snd_control->name = hpi_ctl->name;
1443 snd_control->private_value = hpi_ctl->h_control; 1409 snd_control->private_value = hpi_ctl->h_control;
1444 snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER; 1410 snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1445 snd_control->index = 0; 1411 snd_control->index = 0;
1446 1412
1413 if (hpi_ctl->dst_node_type + HPI_DESTNODE_NONE == HPI_DESTNODE_ISTREAM)
1414 dir = "Capture "; /* On or towards a PCM capture destination*/
1415 else if ((hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) &&
1416 (!hpi_ctl->dst_node_type))
1417 dir = "Capture "; /* On a source node that is not PCM playback */
1418 else if ((hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) &&
1419 (hpi_ctl->dst_node_type))
1420 dir = "Monitor Playback "; /* Between an input and an output */
1421 else
1422 dir = "Playback "; /* PCM Playback source, or output node */
1423
1447 if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type) 1424 if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type)
1448 sprintf(hpi_ctl->name, "%s%d to %s%d %s", 1425 sprintf(hpi_ctl->name, "%s%d %s%d %s%s",
1449 asihpi_src_names[hpi_ctl->src_node_type], 1426 asihpi_src_names[hpi_ctl->src_node_type],
1450 hpi_ctl->src_node_index, 1427 hpi_ctl->src_node_index,
1451 asihpi_dst_names[hpi_ctl->dst_node_type], 1428 asihpi_dst_names[hpi_ctl->dst_node_type],
1452 hpi_ctl->dst_node_index, 1429 hpi_ctl->dst_node_index,
1453 name); 1430 dir, name);
1454 else if (hpi_ctl->dst_node_type) { 1431 else if (hpi_ctl->dst_node_type) {
1455 sprintf(hpi_ctl->name, "%s%d %s", 1432 sprintf(hpi_ctl->name, "%s %d %s%s",
1456 asihpi_dst_names[hpi_ctl->dst_node_type], 1433 asihpi_dst_names[hpi_ctl->dst_node_type],
1457 hpi_ctl->dst_node_index, 1434 hpi_ctl->dst_node_index,
1458 name); 1435 dir, name);
1459 } else { 1436 } else {
1460 sprintf(hpi_ctl->name, "%s%d %s", 1437 sprintf(hpi_ctl->name, "%s %d %s%s",
1461 asihpi_src_names[hpi_ctl->src_node_type], 1438 asihpi_src_names[hpi_ctl->src_node_type],
1462 hpi_ctl->src_node_index, 1439 hpi_ctl->src_node_index,
1463 name); 1440 dir, name);
1464 } 1441 }
1442 // printk(KERN_INFO "adding %s %d to %d ", hpi_ctl->name, hpi_ctl->src_node_type, hpi_ctl->dst_node_type);
1465} 1443}
1466 1444
1467/*------------------------------------------------------------ 1445/*------------------------------------------------------------
@@ -1534,7 +1512,7 @@ static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
1534 struct snd_card *card = asihpi->card; 1512 struct snd_card *card = asihpi->card;
1535 struct snd_kcontrol_new snd_control; 1513 struct snd_kcontrol_new snd_control;
1536 1514
1537 asihpi_ctl_init(&snd_control, hpi_ctl, "volume"); 1515 asihpi_ctl_init(&snd_control, hpi_ctl, "Volume");
1538 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 1516 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1539 SNDRV_CTL_ELEM_ACCESS_TLV_READ; 1517 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1540 snd_control.info = snd_asihpi_volume_info; 1518 snd_control.info = snd_asihpi_volume_info;
@@ -1617,7 +1595,7 @@ static int __devinit snd_asihpi_level_add(struct snd_card_asihpi *asihpi,
1617 struct snd_kcontrol_new snd_control; 1595 struct snd_kcontrol_new snd_control;
1618 1596
1619 /* can't use 'volume' cos some nodes have volume as well */ 1597 /* can't use 'volume' cos some nodes have volume as well */
1620 asihpi_ctl_init(&snd_control, hpi_ctl, "level"); 1598 asihpi_ctl_init(&snd_control, hpi_ctl, "Level");
1621 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 1599 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1622 SNDRV_CTL_ELEM_ACCESS_TLV_READ; 1600 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1623 snd_control.info = snd_asihpi_level_info; 1601 snd_control.info = snd_asihpi_level_info;
@@ -1633,7 +1611,7 @@ static int __devinit snd_asihpi_level_add(struct snd_card_asihpi *asihpi,
1633 ------------------------------------------------------------*/ 1611 ------------------------------------------------------------*/
1634 1612
1635/* AESEBU format */ 1613/* AESEBU format */
1636static char *asihpi_aesebu_format_names[] = 1614static const char * const asihpi_aesebu_format_names[] =
1637{ 1615{
1638 "N/A", 1616 "N/A",
1639 "S/PDIF", 1617 "S/PDIF",
@@ -1742,7 +1720,7 @@ static int __devinit snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi,
1742 struct snd_card *card = asihpi->card; 1720 struct snd_card *card = asihpi->card;
1743 struct snd_kcontrol_new snd_control; 1721 struct snd_kcontrol_new snd_control;
1744 1722
1745 asihpi_ctl_init(&snd_control, hpi_ctl, "format"); 1723 asihpi_ctl_init(&snd_control, hpi_ctl, "Format");
1746 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; 1724 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1747 snd_control.info = snd_asihpi_aesebu_format_info; 1725 snd_control.info = snd_asihpi_aesebu_format_info;
1748 snd_control.get = snd_asihpi_aesebu_rx_format_get; 1726 snd_control.get = snd_asihpi_aesebu_rx_format_get;
@@ -1752,7 +1730,7 @@ static int __devinit snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi,
1752 if (ctl_add(card, &snd_control, asihpi) < 0) 1730 if (ctl_add(card, &snd_control, asihpi) < 0)
1753 return -EINVAL; 1731 return -EINVAL;
1754 1732
1755 asihpi_ctl_init(&snd_control, hpi_ctl, "status"); 1733 asihpi_ctl_init(&snd_control, hpi_ctl, "Status");
1756 snd_control.access = 1734 snd_control.access =
1757 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ; 1735 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
1758 snd_control.info = snd_asihpi_aesebu_rxstatus_info; 1736 snd_control.info = snd_asihpi_aesebu_rxstatus_info;
@@ -1780,7 +1758,7 @@ static int __devinit snd_asihpi_aesebu_tx_add(struct snd_card_asihpi *asihpi,
1780 struct snd_card *card = asihpi->card; 1758 struct snd_card *card = asihpi->card;
1781 struct snd_kcontrol_new snd_control; 1759 struct snd_kcontrol_new snd_control;
1782 1760
1783 asihpi_ctl_init(&snd_control, hpi_ctl, "format"); 1761 asihpi_ctl_init(&snd_control, hpi_ctl, "Format");
1784 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; 1762 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1785 snd_control.info = snd_asihpi_aesebu_format_info; 1763 snd_control.info = snd_asihpi_aesebu_format_info;
1786 snd_control.get = snd_asihpi_aesebu_tx_format_get; 1764 snd_control.get = snd_asihpi_aesebu_tx_format_get;
@@ -2027,7 +2005,7 @@ static int __devinit snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi,
2027 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; 2005 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2028 2006
2029 if (!hpi_tuner_get_gain(ss, hpi_ctl->h_control, NULL)) { 2007 if (!hpi_tuner_get_gain(ss, hpi_ctl->h_control, NULL)) {
2030 asihpi_ctl_init(&snd_control, hpi_ctl, "gain"); 2008 asihpi_ctl_init(&snd_control, hpi_ctl, "Gain");
2031 snd_control.info = snd_asihpi_tuner_gain_info; 2009 snd_control.info = snd_asihpi_tuner_gain_info;
2032 snd_control.get = snd_asihpi_tuner_gain_get; 2010 snd_control.get = snd_asihpi_tuner_gain_get;
2033 snd_control.put = snd_asihpi_tuner_gain_put; 2011 snd_control.put = snd_asihpi_tuner_gain_put;
@@ -2036,7 +2014,7 @@ static int __devinit snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi,
2036 return -EINVAL; 2014 return -EINVAL;
2037 } 2015 }
2038 2016
2039 asihpi_ctl_init(&snd_control, hpi_ctl, "band"); 2017 asihpi_ctl_init(&snd_control, hpi_ctl, "Band");
2040 snd_control.info = snd_asihpi_tuner_band_info; 2018 snd_control.info = snd_asihpi_tuner_band_info;
2041 snd_control.get = snd_asihpi_tuner_band_get; 2019 snd_control.get = snd_asihpi_tuner_band_get;
2042 snd_control.put = snd_asihpi_tuner_band_put; 2020 snd_control.put = snd_asihpi_tuner_band_put;
@@ -2044,7 +2022,7 @@ static int __devinit snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi,
2044 if (ctl_add(card, &snd_control, asihpi) < 0) 2022 if (ctl_add(card, &snd_control, asihpi) < 0)
2045 return -EINVAL; 2023 return -EINVAL;
2046 2024
2047 asihpi_ctl_init(&snd_control, hpi_ctl, "freq"); 2025 asihpi_ctl_init(&snd_control, hpi_ctl, "Freq");
2048 snd_control.info = snd_asihpi_tuner_freq_info; 2026 snd_control.info = snd_asihpi_tuner_freq_info;
2049 snd_control.get = snd_asihpi_tuner_freq_get; 2027 snd_control.get = snd_asihpi_tuner_freq_get;
2050 snd_control.put = snd_asihpi_tuner_freq_put; 2028 snd_control.put = snd_asihpi_tuner_freq_put;
@@ -2120,7 +2098,7 @@ static int __devinit snd_asihpi_meter_add(struct snd_card_asihpi *asihpi,
2120 struct snd_card *card = asihpi->card; 2098 struct snd_card *card = asihpi->card;
2121 struct snd_kcontrol_new snd_control; 2099 struct snd_kcontrol_new snd_control;
2122 2100
2123 asihpi_ctl_init(&snd_control, hpi_ctl, "meter"); 2101 asihpi_ctl_init(&snd_control, hpi_ctl, "Meter");
2124 snd_control.access = 2102 snd_control.access =
2125 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ; 2103 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
2126 snd_control.info = snd_asihpi_meter_info; 2104 snd_control.info = snd_asihpi_meter_info;
@@ -2201,7 +2179,7 @@ static int snd_asihpi_mux_get(struct snd_kcontrol *kcontrol,
2201 } 2179 }
2202 } 2180 }
2203 snd_printd(KERN_WARNING 2181 snd_printd(KERN_WARNING
2204 "control %x failed to match mux source %hu %hu\n", 2182 "Control %x failed to match mux source %hu %hu\n",
2205 h_control, source_type, source_index); 2183 h_control, source_type, source_index);
2206 ucontrol->value.enumerated.item[0] = 0; 2184 ucontrol->value.enumerated.item[0] = 0;
2207 return 0; 2185 return 0;
@@ -2234,11 +2212,7 @@ static int __devinit snd_asihpi_mux_add(struct snd_card_asihpi *asihpi,
2234 struct snd_card *card = asihpi->card; 2212 struct snd_card *card = asihpi->card;
2235 struct snd_kcontrol_new snd_control; 2213 struct snd_kcontrol_new snd_control;
2236 2214
2237#if ASI_STYLE_NAMES 2215 asihpi_ctl_init(&snd_control, hpi_ctl, "Route");
2238 asihpi_ctl_init(&snd_control, hpi_ctl, "multiplexer");
2239#else
2240 asihpi_ctl_init(&snd_control, hpi_ctl, "route");
2241#endif
2242 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; 2216 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2243 snd_control.info = snd_asihpi_mux_info; 2217 snd_control.info = snd_asihpi_mux_info;
2244 snd_control.get = snd_asihpi_mux_get; 2218 snd_control.get = snd_asihpi_mux_get;
@@ -2254,33 +2228,38 @@ static int __devinit snd_asihpi_mux_add(struct snd_card_asihpi *asihpi,
2254static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol, 2228static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol,
2255 struct snd_ctl_elem_info *uinfo) 2229 struct snd_ctl_elem_info *uinfo)
2256{ 2230{
2257 static char *mode_names[HPI_CHANNEL_MODE_LAST] = { 2231 static const char * const mode_names[HPI_CHANNEL_MODE_LAST + 1] = {
2258 "normal", "swap", 2232 "invalid",
2259 "from_left", "from_right", 2233 "Normal", "Swap",
2260 "to_left", "to_right" 2234 "From Left", "From Right",
2235 "To Left", "To Right"
2261 }; 2236 };
2262 2237
2263 u32 h_control = kcontrol->private_value; 2238 u32 h_control = kcontrol->private_value;
2264 u16 mode; 2239 u16 mode;
2265 int i; 2240 int i;
2241 u16 mode_map[6];
2242 int valid_modes = 0;
2266 2243
2267 /* HPI channel mode values can be from 1 to 6 2244 /* HPI channel mode values can be from 1 to 6
2268 Some adapters only support a contiguous subset 2245 Some adapters only support a contiguous subset
2269 */ 2246 */
2270 for (i = 0; i < HPI_CHANNEL_MODE_LAST; i++) 2247 for (i = 0; i < HPI_CHANNEL_MODE_LAST; i++)
2271 if (hpi_channel_mode_query_mode( 2248 if (!hpi_channel_mode_query_mode(
2272 ss, h_control, i, &mode)) 2249 ss, h_control, i, &mode)) {
2273 break; 2250 mode_map[valid_modes] = mode;
2251 valid_modes++;
2252 }
2274 2253
2275 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2254 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2276 uinfo->count = 1; 2255 uinfo->count = 1;
2277 uinfo->value.enumerated.items = i; 2256 uinfo->value.enumerated.items = valid_modes;
2278 2257
2279 if (uinfo->value.enumerated.item >= i) 2258 if (uinfo->value.enumerated.item >= valid_modes)
2280 uinfo->value.enumerated.item = i - 1; 2259 uinfo->value.enumerated.item = valid_modes - 1;
2281 2260
2282 strcpy(uinfo->value.enumerated.name, 2261 strcpy(uinfo->value.enumerated.name,
2283 mode_names[uinfo->value.enumerated.item]); 2262 mode_names[mode_map[uinfo->value.enumerated.item]]);
2284 2263
2285 return 0; 2264 return 0;
2286} 2265}
@@ -2319,7 +2298,7 @@ static int __devinit snd_asihpi_cmode_add(struct snd_card_asihpi *asihpi,
2319 struct snd_card *card = asihpi->card; 2298 struct snd_card *card = asihpi->card;
2320 struct snd_kcontrol_new snd_control; 2299 struct snd_kcontrol_new snd_control;
2321 2300
2322 asihpi_ctl_init(&snd_control, hpi_ctl, "channel mode"); 2301 asihpi_ctl_init(&snd_control, hpi_ctl, "Mode");
2323 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; 2302 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2324 snd_control.info = snd_asihpi_cmode_info; 2303 snd_control.info = snd_asihpi_cmode_info;
2325 snd_control.get = snd_asihpi_cmode_get; 2304 snd_control.get = snd_asihpi_cmode_get;
@@ -2331,15 +2310,12 @@ static int __devinit snd_asihpi_cmode_add(struct snd_card_asihpi *asihpi,
2331/*------------------------------------------------------------ 2310/*------------------------------------------------------------
2332 Sampleclock source controls 2311 Sampleclock source controls
2333 ------------------------------------------------------------*/ 2312 ------------------------------------------------------------*/
2334
2335static char *sampleclock_sources[MAX_CLOCKSOURCES] = 2313static char *sampleclock_sources[MAX_CLOCKSOURCES] =
2336 { "N/A", "local PLL", "AES/EBU sync", "word external", "word header", 2314{ "N/A", "Local PLL", "Digital Sync", "Word External", "Word Header",
2337 "SMPTE", "AES/EBU in1", "auto", "network", "invalid", 2315 "SMPTE", "Digital1", "Auto", "Network", "Invalid",
2338 "prev module", 2316 "Prev Module",
2339 "AES/EBU in2", "AES/EBU in3", "AES/EBU in4", "AES/EBU in5", 2317 "Digital2", "Digital3", "Digital4", "Digital5",
2340 "AES/EBU in6", "AES/EBU in7", "AES/EBU in8"}; 2318 "Digital6", "Digital7", "Digital8"};
2341
2342
2343 2319
2344static int snd_asihpi_clksrc_info(struct snd_kcontrol *kcontrol, 2320static int snd_asihpi_clksrc_info(struct snd_kcontrol *kcontrol,
2345 struct snd_ctl_elem_info *uinfo) 2321 struct snd_ctl_elem_info *uinfo)
@@ -2528,7 +2504,7 @@ static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
2528 } 2504 }
2529 clkcache->count = i; 2505 clkcache->count = i;
2530 2506
2531 asihpi_ctl_init(&snd_control, hpi_ctl, "source"); 2507 asihpi_ctl_init(&snd_control, hpi_ctl, "Source");
2532 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ; 2508 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
2533 snd_control.info = snd_asihpi_clksrc_info; 2509 snd_control.info = snd_asihpi_clksrc_info;
2534 snd_control.get = snd_asihpi_clksrc_get; 2510 snd_control.get = snd_asihpi_clksrc_get;
@@ -2538,7 +2514,7 @@ static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
2538 2514
2539 2515
2540 if (clkcache->has_local) { 2516 if (clkcache->has_local) {
2541 asihpi_ctl_init(&snd_control, hpi_ctl, "local_rate"); 2517 asihpi_ctl_init(&snd_control, hpi_ctl, "Localrate");
2542 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ; 2518 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
2543 snd_control.info = snd_asihpi_clklocal_info; 2519 snd_control.info = snd_asihpi_clklocal_info;
2544 snd_control.get = snd_asihpi_clklocal_get; 2520 snd_control.get = snd_asihpi_clklocal_get;
@@ -2549,7 +2525,7 @@ static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
2549 return -EINVAL; 2525 return -EINVAL;
2550 } 2526 }
2551 2527
2552 asihpi_ctl_init(&snd_control, hpi_ctl, "rate"); 2528 asihpi_ctl_init(&snd_control, hpi_ctl, "Rate");
2553 snd_control.access = 2529 snd_control.access =
2554 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ; 2530 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
2555 snd_control.info = snd_asihpi_clkrate_info; 2531 snd_control.info = snd_asihpi_clkrate_info;
@@ -2571,7 +2547,7 @@ static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
2571 2547
2572 if (snd_BUG_ON(!asihpi)) 2548 if (snd_BUG_ON(!asihpi))
2573 return -EINVAL; 2549 return -EINVAL;
2574 strcpy(card->mixername, "asihpi mixer"); 2550 strcpy(card->mixername, "Asihpi Mixer");
2575 2551
2576 err = 2552 err =
2577 hpi_mixer_open(ss, asihpi->adapter_index, 2553 hpi_mixer_open(ss, asihpi->adapter_index,
@@ -2597,7 +2573,7 @@ static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
2597 if (err == HPI_ERROR_CONTROL_DISABLED) { 2573 if (err == HPI_ERROR_CONTROL_DISABLED) {
2598 if (mixer_dump) 2574 if (mixer_dump)
2599 snd_printk(KERN_INFO 2575 snd_printk(KERN_INFO
2600 "disabled HPI control(%d)\n", 2576 "Disabled HPI Control(%d)\n",
2601 idx); 2577 idx);
2602 continue; 2578 continue;
2603 } else 2579 } else
@@ -2662,7 +2638,7 @@ static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
2662 default: 2638 default:
2663 if (mixer_dump) 2639 if (mixer_dump)
2664 snd_printk(KERN_INFO 2640 snd_printk(KERN_INFO
2665 "untranslated HPI control" 2641 "Untranslated HPI Control"
2666 "(%d) %d %d %d %d %d\n", 2642 "(%d) %d %d %d %d %d\n",
2667 idx, 2643 idx,
2668 hpi_ctl.control_type, 2644 hpi_ctl.control_type,
@@ -2841,7 +2817,7 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2841 if (err < 0) 2817 if (err < 0)
2842 return err; 2818 return err;
2843 snd_printk(KERN_WARNING 2819 snd_printk(KERN_WARNING
2844 "**** WARNING **** adapter index %d->ALSA index %d\n", 2820 "**** WARNING **** Adapter index %d->ALSA index %d\n",
2845 hpi_card->index, card->number); 2821 hpi_card->index, card->number);
2846 } 2822 }
2847 2823
@@ -2859,7 +2835,7 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2859 version = asihpi->version; 2835 version = asihpi->version;
2860 snd_printk(KERN_INFO "adapter ID=%4X index=%d num_outstreams=%d " 2836 snd_printk(KERN_INFO "adapter ID=%4X index=%d num_outstreams=%d "
2861 "num_instreams=%d S/N=%d\n" 2837 "num_instreams=%d S/N=%d\n"
2862 "hw version %c%d DSP code version %03d\n", 2838 "Hw Version %c%d DSP code version %03d\n",
2863 asihpi->type, asihpi->adapter_index, 2839 asihpi->type, asihpi->adapter_index,
2864 asihpi->num_outstreams, 2840 asihpi->num_outstreams,
2865 asihpi->num_instreams, asihpi->serial_number, 2841 asihpi->num_instreams, asihpi->serial_number,