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.c294
1 files changed, 152 insertions, 142 deletions
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c
index f4b9e2b7ae8..e8de831f98b 100644
--- a/sound/pci/asihpi/asihpi.c
+++ b/sound/pci/asihpi/asihpi.c
@@ -23,8 +23,11 @@
23 */ 23 */
24 24
25#include "hpi_internal.h" 25#include "hpi_internal.h"
26#include "hpi_version.h"
26#include "hpimsginit.h" 27#include "hpimsginit.h"
27#include "hpioctl.h" 28#include "hpioctl.h"
29#include "hpicmn.h"
30
28 31
29#include <linux/pci.h> 32#include <linux/pci.h>
30#include <linux/init.h> 33#include <linux/init.h>
@@ -44,7 +47,8 @@
44 47
45MODULE_LICENSE("GPL"); 48MODULE_LICENSE("GPL");
46MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>"); 49MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>");
47MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx"); 50MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx "
51 HPI_VER_STRING);
48 52
49#if defined CONFIG_SND_DEBUG_VERBOSE 53#if defined CONFIG_SND_DEBUG_VERBOSE
50/** 54/**
@@ -63,8 +67,8 @@ MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx");
63 67
64static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */ 68static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */
65static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 69static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
66static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; 70static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
67static int enable_hpi_hwdep = 1; 71static bool enable_hpi_hwdep = 1;
68 72
69module_param_array(index, int, NULL, S_IRUGO); 73module_param_array(index, int, NULL, S_IRUGO);
70MODULE_PARM_DESC(index, "ALSA index value for AudioScience soundcard."); 74MODULE_PARM_DESC(index, "ALSA index value for AudioScience soundcard.");
@@ -119,12 +123,7 @@ struct clk_cache {
119struct snd_card_asihpi { 123struct snd_card_asihpi {
120 struct snd_card *card; 124 struct snd_card *card;
121 struct pci_dev *pci; 125 struct pci_dev *pci;
122 u16 adapter_index; 126 struct hpi_adapter *hpi;
123 u32 serial_number;
124 u16 type;
125 u16 version;
126 u16 num_outstreams;
127 u16 num_instreams;
128 127
129 u32 h_mixer; 128 u32 h_mixer;
130 struct clk_cache cc; 129 struct clk_cache cc;
@@ -135,6 +134,8 @@ struct snd_card_asihpi {
135 u16 update_interval_frames; 134 u16 update_interval_frames;
136 u16 in_max_chans; 135 u16 in_max_chans;
137 u16 out_max_chans; 136 u16 out_max_chans;
137 u16 in_min_chans;
138 u16 out_min_chans;
138}; 139};
139 140
140/* Per stream data */ 141/* Per stream data */
@@ -495,6 +496,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
495 496
496 snd_printdd("stream_host_buffer_attach status 0x%x\n", 497 snd_printdd("stream_host_buffer_attach status 0x%x\n",
497 dpcm->hpi_buffer_attached); 498 dpcm->hpi_buffer_attached);
499
498 } 500 }
499 bytes_per_sec = params_rate(params) * params_channels(params); 501 bytes_per_sec = params_rate(params) * params_channels(params);
500 width = snd_pcm_format_width(params_format(params)); 502 width = snd_pcm_format_width(params_format(params));
@@ -757,8 +759,7 @@ static void snd_card_asihpi_timer_function(unsigned long data)
757 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { 759 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
758 pcm_buf_dma_ofs = ds->pcm_buf_host_rw_ofs - bytes_avail; 760 pcm_buf_dma_ofs = ds->pcm_buf_host_rw_ofs - bytes_avail;
759 if (state == HPI_STATE_STOPPED) { 761 if (state == HPI_STATE_STOPPED) {
760 if ((bytes_avail == 0) && 762 if (bytes_avail == 0) {
761 (on_card_bytes < ds->pcm_buf_host_rw_ofs)) {
762 hpi_handle_error(hpi_stream_start(ds->h_stream)); 763 hpi_handle_error(hpi_stream_start(ds->h_stream));
763 snd_printdd("P%d start\n", s->number); 764 snd_printdd("P%d start\n", s->number);
764 ds->drained_count = 0; 765 ds->drained_count = 0;
@@ -767,7 +768,7 @@ static void snd_card_asihpi_timer_function(unsigned long data)
767 snd_printd(KERN_WARNING "P%d drained\n", 768 snd_printd(KERN_WARNING "P%d drained\n",
768 s->number); 769 s->number);
769 ds->drained_count++; 770 ds->drained_count++;
770 if (ds->drained_count > 2) { 771 if (ds->drained_count > 20) {
771 snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); 772 snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN);
772 continue; 773 continue;
773 } 774 }
@@ -888,8 +889,8 @@ static void snd_card_asihpi_timer_function(unsigned long data)
888 pd, xfer2)); 889 pd, xfer2));
889 } 890 }
890 } 891 }
891 ds->pcm_buf_host_rw_ofs = ds->pcm_buf_host_rw_ofs + xfercount; 892 ds->pcm_buf_host_rw_ofs += xfercount;
892 ds->pcm_buf_elapsed_dma_ofs = pcm_buf_dma_ofs; 893 ds->pcm_buf_elapsed_dma_ofs += xfercount;
893 snd_pcm_period_elapsed(s); 894 snd_pcm_period_elapsed(s);
894 } 895 }
895 } 896 }
@@ -902,7 +903,9 @@ static void snd_card_asihpi_timer_function(unsigned long data)
902static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream, 903static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream,
903 unsigned int cmd, void *arg) 904 unsigned int cmd, void *arg)
904{ 905{
905 snd_printddd(KERN_INFO "P%d ioctl %d\n", substream->number, cmd); 906 char name[16];
907 snd_pcm_debug_name(substream, name, sizeof(name));
908 snd_printddd(KERN_INFO "%s ioctl %d\n", name, cmd);
906 return snd_pcm_lib_ioctl(substream, cmd, arg); 909 return snd_pcm_lib_ioctl(substream, cmd, arg);
907} 910}
908 911
@@ -927,21 +930,23 @@ snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream)
927 struct snd_pcm_runtime *runtime = substream->runtime; 930 struct snd_pcm_runtime *runtime = substream->runtime;
928 struct snd_card_asihpi_pcm *dpcm = runtime->private_data; 931 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
929 snd_pcm_uframes_t ptr; 932 snd_pcm_uframes_t ptr;
933 char name[16];
934 snd_pcm_debug_name(substream, name, sizeof(name));
930 935
931 ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes); 936 ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes);
932 snd_printddd("P%d pointer = 0x%04lx\n", substream->number, (unsigned long)ptr); 937 snd_printddd("%s pointer = 0x%04lx\n", name, (unsigned long)ptr);
933 return ptr; 938 return ptr;
934} 939}
935 940
936static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi, 941static u64 snd_card_asihpi_playback_formats(struct snd_card_asihpi *asihpi,
937 u32 h_stream, 942 u32 h_stream)
938 struct snd_pcm_hardware *pcmhw)
939{ 943{
940 struct hpi_format hpi_format; 944 struct hpi_format hpi_format;
941 u16 format; 945 u16 format;
942 u16 err; 946 u16 err;
943 u32 h_control; 947 u32 h_control;
944 u32 sample_rate = 48000; 948 u32 sample_rate = 48000;
949 u64 formats = 0;
945 950
946 /* on cards without SRC, must query at valid rate, 951 /* on cards without SRC, must query at valid rate,
947 * maybe set by external sync 952 * maybe set by external sync
@@ -956,41 +961,29 @@ static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi,
956 961
957 for (format = HPI_FORMAT_PCM8_UNSIGNED; 962 for (format = HPI_FORMAT_PCM8_UNSIGNED;
958 format <= HPI_FORMAT_PCM24_SIGNED; format++) { 963 format <= HPI_FORMAT_PCM24_SIGNED; format++) {
959 err = hpi_format_create(&hpi_format, 964 err = hpi_format_create(&hpi_format, asihpi->out_max_chans,
960 2, format, sample_rate, 128000, 0); 965 format, sample_rate, 128000, 0);
961 if (!err) 966 if (!err)
962 err = hpi_outstream_query_format(h_stream, 967 err = hpi_outstream_query_format(h_stream, &hpi_format);
963 &hpi_format);
964 if (!err && (hpi_to_alsa_formats[format] != -1)) 968 if (!err && (hpi_to_alsa_formats[format] != -1))
965 pcmhw->formats |= 969 formats |= (1ULL << hpi_to_alsa_formats[format]);
966 (1ULL << hpi_to_alsa_formats[format]);
967 } 970 }
971 return formats;
968} 972}
969 973
970static struct snd_pcm_hardware snd_card_asihpi_playback = {
971 .channels_min = 1,
972 .channels_max = 2,
973 .buffer_bytes_max = BUFFER_BYTES_MAX,
974 .period_bytes_min = PERIOD_BYTES_MIN,
975 .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
976 .periods_min = PERIODS_MIN,
977 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
978 .fifo_size = 0,
979};
980
981static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream) 974static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
982{ 975{
983 struct snd_pcm_runtime *runtime = substream->runtime; 976 struct snd_pcm_runtime *runtime = substream->runtime;
984 struct snd_card_asihpi_pcm *dpcm; 977 struct snd_card_asihpi_pcm *dpcm;
985 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream); 978 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
979 struct snd_pcm_hardware snd_card_asihpi_playback;
986 int err; 980 int err;
987 981
988 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL); 982 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
989 if (dpcm == NULL) 983 if (dpcm == NULL)
990 return -ENOMEM; 984 return -ENOMEM;
991 985
992 err = 986 err = hpi_outstream_open(card->hpi->adapter->index,
993 hpi_outstream_open(card->adapter_index,
994 substream->number, &dpcm->h_stream); 987 substream->number, &dpcm->h_stream);
995 hpi_handle_error(err); 988 hpi_handle_error(err);
996 if (err) 989 if (err)
@@ -1012,12 +1005,19 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
1012 runtime->private_data = dpcm; 1005 runtime->private_data = dpcm;
1013 runtime->private_free = snd_card_asihpi_runtime_free; 1006 runtime->private_free = snd_card_asihpi_runtime_free;
1014 1007
1015 snd_card_asihpi_playback.channels_max = card->out_max_chans; 1008 memset(&snd_card_asihpi_playback, 0, sizeof(snd_card_asihpi_playback));
1009 snd_card_asihpi_playback.buffer_bytes_max = BUFFER_BYTES_MAX;
1010 snd_card_asihpi_playback.period_bytes_min = PERIOD_BYTES_MIN;
1016 /*?snd_card_asihpi_playback.period_bytes_min = 1011 /*?snd_card_asihpi_playback.period_bytes_min =
1017 card->out_max_chans * 4096; */ 1012 card->out_max_chans * 4096; */
1018 1013 snd_card_asihpi_playback.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN;
1019 snd_card_asihpi_playback_format(card, dpcm->h_stream, 1014 snd_card_asihpi_playback.periods_min = PERIODS_MIN;
1020 &snd_card_asihpi_playback); 1015 snd_card_asihpi_playback.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN;
1016 /* snd_card_asihpi_playback.fifo_size = 0; */
1017 snd_card_asihpi_playback.channels_max = card->out_max_chans;
1018 snd_card_asihpi_playback.channels_min = card->out_min_chans;
1019 snd_card_asihpi_playback.formats =
1020 snd_card_asihpi_playback_formats(card, dpcm->h_stream);
1021 1021
1022 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_playback); 1022 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_playback);
1023 1023
@@ -1029,8 +1029,10 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
1029 SNDRV_PCM_INFO_MMAP | 1029 SNDRV_PCM_INFO_MMAP |
1030 SNDRV_PCM_INFO_MMAP_VALID; 1030 SNDRV_PCM_INFO_MMAP_VALID;
1031 1031
1032 if (card->support_grouping) 1032 if (card->support_grouping) {
1033 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START; 1033 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START;
1034 snd_pcm_set_sync(substream);
1035 }
1034 1036
1035 /* struct is copied, so can create initializer dynamically */ 1037 /* struct is copied, so can create initializer dynamically */
1036 runtime->hw = snd_card_asihpi_playback; 1038 runtime->hw = snd_card_asihpi_playback;
@@ -1047,8 +1049,6 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
1047 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 1049 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1048 card->update_interval_frames * 2, UINT_MAX); 1050 card->update_interval_frames * 2, UINT_MAX);
1049 1051
1050 snd_pcm_set_sync(substream);
1051
1052 snd_printdd("playback open\n"); 1052 snd_printdd("playback open\n");
1053 1053
1054 return 0; 1054 return 0;
@@ -1114,15 +1114,15 @@ static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream)
1114 1114
1115 1115
1116 1116
1117static void snd_card_asihpi_capture_format(struct snd_card_asihpi *asihpi, 1117static u64 snd_card_asihpi_capture_formats(struct snd_card_asihpi *asihpi,
1118 u32 h_stream, 1118 u32 h_stream)
1119 struct snd_pcm_hardware *pcmhw)
1120{ 1119{
1121 struct hpi_format hpi_format; 1120 struct hpi_format hpi_format;
1122 u16 format; 1121 u16 format;
1123 u16 err; 1122 u16 err;
1124 u32 h_control; 1123 u32 h_control;
1125 u32 sample_rate = 48000; 1124 u32 sample_rate = 48000;
1125 u64 formats = 0;
1126 1126
1127 /* on cards without SRC, must query at valid rate, 1127 /* on cards without SRC, must query at valid rate,
1128 maybe set by external sync */ 1128 maybe set by external sync */
@@ -1137,34 +1137,22 @@ static void snd_card_asihpi_capture_format(struct snd_card_asihpi *asihpi,
1137 for (format = HPI_FORMAT_PCM8_UNSIGNED; 1137 for (format = HPI_FORMAT_PCM8_UNSIGNED;
1138 format <= HPI_FORMAT_PCM24_SIGNED; format++) { 1138 format <= HPI_FORMAT_PCM24_SIGNED; format++) {
1139 1139
1140 err = hpi_format_create(&hpi_format, 2, format, 1140 err = hpi_format_create(&hpi_format, asihpi->in_max_chans,
1141 sample_rate, 128000, 0); 1141 format, sample_rate, 128000, 0);
1142 if (!err) 1142 if (!err)
1143 err = hpi_instream_query_format(h_stream, 1143 err = hpi_instream_query_format(h_stream, &hpi_format);
1144 &hpi_format);
1145 if (!err) 1144 if (!err)
1146 pcmhw->formats |= 1145 formats |= (1ULL << hpi_to_alsa_formats[format]);
1147 (1ULL << hpi_to_alsa_formats[format]);
1148 } 1146 }
1147 return formats;
1149} 1148}
1150 1149
1151
1152static struct snd_pcm_hardware snd_card_asihpi_capture = {
1153 .channels_min = 1,
1154 .channels_max = 2,
1155 .buffer_bytes_max = BUFFER_BYTES_MAX,
1156 .period_bytes_min = PERIOD_BYTES_MIN,
1157 .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
1158 .periods_min = PERIODS_MIN,
1159 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
1160 .fifo_size = 0,
1161};
1162
1163static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream) 1150static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
1164{ 1151{
1165 struct snd_pcm_runtime *runtime = substream->runtime; 1152 struct snd_pcm_runtime *runtime = substream->runtime;
1166 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream); 1153 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
1167 struct snd_card_asihpi_pcm *dpcm; 1154 struct snd_card_asihpi_pcm *dpcm;
1155 struct snd_pcm_hardware snd_card_asihpi_capture;
1168 int err; 1156 int err;
1169 1157
1170 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL); 1158 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
@@ -1172,10 +1160,10 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
1172 return -ENOMEM; 1160 return -ENOMEM;
1173 1161
1174 snd_printdd("capture open adapter %d stream %d\n", 1162 snd_printdd("capture open adapter %d stream %d\n",
1175 card->adapter_index, substream->number); 1163 card->hpi->adapter->index, substream->number);
1176 1164
1177 err = hpi_handle_error( 1165 err = hpi_handle_error(
1178 hpi_instream_open(card->adapter_index, 1166 hpi_instream_open(card->hpi->adapter->index,
1179 substream->number, &dpcm->h_stream)); 1167 substream->number, &dpcm->h_stream));
1180 if (err) 1168 if (err)
1181 kfree(dpcm); 1169 kfree(dpcm);
@@ -1184,7 +1172,6 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
1184 if (err) 1172 if (err)
1185 return -EIO; 1173 return -EIO;
1186 1174
1187
1188 init_timer(&dpcm->timer); 1175 init_timer(&dpcm->timer);
1189 dpcm->timer.data = (unsigned long) dpcm; 1176 dpcm->timer.data = (unsigned long) dpcm;
1190 dpcm->timer.function = snd_card_asihpi_timer_function; 1177 dpcm->timer.function = snd_card_asihpi_timer_function;
@@ -1192,9 +1179,17 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
1192 runtime->private_data = dpcm; 1179 runtime->private_data = dpcm;
1193 runtime->private_free = snd_card_asihpi_runtime_free; 1180 runtime->private_free = snd_card_asihpi_runtime_free;
1194 1181
1182 memset(&snd_card_asihpi_capture, 0, sizeof(snd_card_asihpi_capture));
1183 snd_card_asihpi_capture.buffer_bytes_max = BUFFER_BYTES_MAX;
1184 snd_card_asihpi_capture.period_bytes_min = PERIOD_BYTES_MIN;
1185 snd_card_asihpi_capture.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN;
1186 snd_card_asihpi_capture.periods_min = PERIODS_MIN;
1187 snd_card_asihpi_capture.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN;
1188 /* snd_card_asihpi_capture.fifo_size = 0; */
1195 snd_card_asihpi_capture.channels_max = card->in_max_chans; 1189 snd_card_asihpi_capture.channels_max = card->in_max_chans;
1196 snd_card_asihpi_capture_format(card, dpcm->h_stream, 1190 snd_card_asihpi_capture.channels_min = card->in_min_chans;
1197 &snd_card_asihpi_capture); 1191 snd_card_asihpi_capture.formats =
1192 snd_card_asihpi_capture_formats(card, dpcm->h_stream);
1198 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture); 1193 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture);
1199 snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED | 1194 snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED |
1200 SNDRV_PCM_INFO_MMAP | 1195 SNDRV_PCM_INFO_MMAP |
@@ -1240,15 +1235,20 @@ static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = {
1240 .pointer = snd_card_asihpi_capture_pointer, 1235 .pointer = snd_card_asihpi_capture_pointer,
1241}; 1236};
1242 1237
1243static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi, 1238static int __devinit snd_card_asihpi_pcm_new(
1244 int device, int substreams) 1239 struct snd_card_asihpi *asihpi, int device)
1245{ 1240{
1246 struct snd_pcm *pcm; 1241 struct snd_pcm *pcm;
1247 int err; 1242 int err;
1243 u16 num_instreams, num_outstreams, x16;
1244 u32 x32;
1245
1246 err = hpi_adapter_get_info(asihpi->hpi->adapter->index,
1247 &num_outstreams, &num_instreams,
1248 &x16, &x32, &x16);
1248 1249
1249 err = snd_pcm_new(asihpi->card, "Asihpi PCM", device, 1250 err = snd_pcm_new(asihpi->card, "Asihpi PCM", device,
1250 asihpi->num_outstreams, asihpi->num_instreams, 1251 num_outstreams, num_instreams, &pcm);
1251 &pcm);
1252 if (err < 0) 1252 if (err < 0)
1253 return err; 1253 return err;
1254 /* pointer to ops struct is stored, dont change ops afterwards! */ 1254 /* pointer to ops struct is stored, dont change ops afterwards! */
@@ -1314,7 +1314,7 @@ static const char * const asihpi_src_names[] = {
1314 "Analog", 1314 "Analog",
1315 "Adapter", 1315 "Adapter",
1316 "RTP", 1316 "RTP",
1317 "GPI", 1317 "Internal"
1318}; 1318};
1319 1319
1320compile_time_assert( 1320compile_time_assert(
@@ -1332,7 +1332,6 @@ static const char * const asihpi_dst_names[] = {
1332 "Net", 1332 "Net",
1333 "Analog", 1333 "Analog",
1334 "RTP", 1334 "RTP",
1335 "GPO",
1336}; 1335};
1337 1336
1338compile_time_assert( 1337compile_time_assert(
@@ -1410,6 +1409,7 @@ static int snd_asihpi_volume_info(struct snd_kcontrol *kcontrol,
1410 struct snd_ctl_elem_info *uinfo) 1409 struct snd_ctl_elem_info *uinfo)
1411{ 1410{
1412 u32 h_control = kcontrol->private_value; 1411 u32 h_control = kcontrol->private_value;
1412 u32 count;
1413 u16 err; 1413 u16 err;
1414 /* native gains are in millibels */ 1414 /* native gains are in millibels */
1415 short min_gain_mB; 1415 short min_gain_mB;
@@ -1424,8 +1424,12 @@ static int snd_asihpi_volume_info(struct snd_kcontrol *kcontrol,
1424 step_gain_mB = VOL_STEP_mB; 1424 step_gain_mB = VOL_STEP_mB;
1425 } 1425 }
1426 1426
1427 err = hpi_meter_query_channels(h_control, &count);
1428 if (err)
1429 count = HPI_MAX_CHANNELS;
1430
1427 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 1431 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1428 uinfo->count = 2; 1432 uinfo->count = count;
1429 uinfo->value.integer.min = min_gain_mB / VOL_STEP_mB; 1433 uinfo->value.integer.min = min_gain_mB / VOL_STEP_mB;
1430 uinfo->value.integer.max = max_gain_mB / VOL_STEP_mB; 1434 uinfo->value.integer.max = max_gain_mB / VOL_STEP_mB;
1431 uinfo->value.integer.step = step_gain_mB / VOL_STEP_mB; 1435 uinfo->value.integer.step = step_gain_mB / VOL_STEP_mB;
@@ -2033,8 +2037,15 @@ static int __devinit snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi,
2033static int snd_asihpi_meter_info(struct snd_kcontrol *kcontrol, 2037static int snd_asihpi_meter_info(struct snd_kcontrol *kcontrol,
2034 struct snd_ctl_elem_info *uinfo) 2038 struct snd_ctl_elem_info *uinfo)
2035{ 2039{
2040 u32 h_control = kcontrol->private_value;
2041 u32 count;
2042 u16 err;
2043 err = hpi_meter_query_channels(h_control, &count);
2044 if (err)
2045 count = HPI_MAX_CHANNELS;
2046
2036 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 2047 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2037 uinfo->count = HPI_MAX_CHANNELS; 2048 uinfo->count = count;
2038 uinfo->value.integer.min = 0; 2049 uinfo->value.integer.min = 0;
2039 uinfo->value.integer.max = 0x7FFFFFFF; 2050 uinfo->value.integer.max = 0x7FFFFFFF;
2040 return 0; 2051 return 0;
@@ -2248,6 +2259,9 @@ static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol,
2248 valid_modes++; 2259 valid_modes++;
2249 } 2260 }
2250 2261
2262 if (!valid_modes)
2263 return -EINVAL;
2264
2251 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2265 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2252 uinfo->count = 1; 2266 uinfo->count = 1;
2253 uinfo->value.enumerated.items = valid_modes; 2267 uinfo->value.enumerated.items = valid_modes;
@@ -2547,7 +2561,7 @@ static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
2547 strcpy(card->mixername, "Asihpi Mixer"); 2561 strcpy(card->mixername, "Asihpi Mixer");
2548 2562
2549 err = 2563 err =
2550 hpi_mixer_open(asihpi->adapter_index, 2564 hpi_mixer_open(asihpi->hpi->adapter->index,
2551 &asihpi->h_mixer); 2565 &asihpi->h_mixer);
2552 hpi_handle_error(err); 2566 hpi_handle_error(err);
2553 if (err) 2567 if (err)
@@ -2665,24 +2679,33 @@ snd_asihpi_proc_read(struct snd_info_entry *entry,
2665 struct snd_info_buffer *buffer) 2679 struct snd_info_buffer *buffer)
2666{ 2680{
2667 struct snd_card_asihpi *asihpi = entry->private_data; 2681 struct snd_card_asihpi *asihpi = entry->private_data;
2668 u16 version;
2669 u32 h_control; 2682 u32 h_control;
2670 u32 rate = 0; 2683 u32 rate = 0;
2671 u16 source = 0; 2684 u16 source = 0;
2685
2686 u16 num_outstreams;
2687 u16 num_instreams;
2688 u16 version;
2689 u32 serial_number;
2690 u16 type;
2691
2672 int err; 2692 int err;
2673 2693
2674 snd_iprintf(buffer, "ASIHPI driver proc file\n"); 2694 snd_iprintf(buffer, "ASIHPI driver proc file\n");
2695
2696 hpi_handle_error(hpi_adapter_get_info(asihpi->hpi->adapter->index,
2697 &num_outstreams, &num_instreams,
2698 &version, &serial_number, &type));
2699
2675 snd_iprintf(buffer, 2700 snd_iprintf(buffer,
2676 "adapter ID=%4X\n_index=%d\n" 2701 "Adapter type ASI%4X\nHardware Index %d\n"
2677 "num_outstreams=%d\n_num_instreams=%d\n", 2702 "%d outstreams\n%d instreams\n",
2678 asihpi->type, asihpi->adapter_index, 2703 type, asihpi->hpi->adapter->index,
2679 asihpi->num_outstreams, asihpi->num_instreams); 2704 num_outstreams, num_instreams);
2680 2705
2681 version = asihpi->version;
2682 snd_iprintf(buffer, 2706 snd_iprintf(buffer,
2683 "serial#=%d\n_hw version %c%d\nDSP code version %03d\n", 2707 "Serial#%d\nHardware version %c%d\nDSP code version %03d\n",
2684 asihpi->serial_number, ((version >> 3) & 0xf) + 'A', 2708 serial_number, ((version >> 3) & 0xf) + 'A', version & 0x7,
2685 version & 0x7,
2686 ((version >> 13) * 100) + ((version >> 7) & 0x3f)); 2709 ((version >> 13) * 100) + ((version >> 7) & 0x3f));
2687 2710
2688 err = hpi_mixer_get_control(asihpi->h_mixer, 2711 err = hpi_mixer_get_control(asihpi->h_mixer,
@@ -2690,18 +2713,15 @@ snd_asihpi_proc_read(struct snd_info_entry *entry,
2690 HPI_CONTROL_SAMPLECLOCK, &h_control); 2713 HPI_CONTROL_SAMPLECLOCK, &h_control);
2691 2714
2692 if (!err) { 2715 if (!err) {
2693 err = hpi_sample_clock_get_sample_rate( 2716 err = hpi_sample_clock_get_sample_rate(h_control, &rate);
2694 h_control, &rate);
2695 err += hpi_sample_clock_get_source(h_control, &source); 2717 err += hpi_sample_clock_get_source(h_control, &source);
2696 2718
2697 if (!err) 2719 if (!err)
2698 snd_iprintf(buffer, "sample_clock=%d_hz, source %s\n", 2720 snd_iprintf(buffer, "Sample Clock %dHz, source %s\n",
2699 rate, sampleclock_sources[source]); 2721 rate, sampleclock_sources[source]);
2700 } 2722 }
2701
2702} 2723}
2703 2724
2704
2705static void __devinit snd_asihpi_proc_init(struct snd_card_asihpi *asihpi) 2725static void __devinit snd_asihpi_proc_init(struct snd_card_asihpi *asihpi)
2706{ 2726{
2707 struct snd_info_entry *entry; 2727 struct snd_info_entry *entry;
@@ -2773,35 +2793,34 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2773 const struct pci_device_id *pci_id) 2793 const struct pci_device_id *pci_id)
2774{ 2794{
2775 int err; 2795 int err;
2776 2796 struct hpi_adapter *hpi;
2777 u16 version;
2778 int pcm_substreams;
2779
2780 struct hpi_adapter *hpi_card;
2781 struct snd_card *card; 2797 struct snd_card *card;
2782 struct snd_card_asihpi *asihpi; 2798 struct snd_card_asihpi *asihpi;
2783 2799
2784 u32 h_control; 2800 u32 h_control;
2785 u32 h_stream; 2801 u32 h_stream;
2802 u32 adapter_index;
2786 2803
2787 static int dev; 2804 static int dev;
2788 if (dev >= SNDRV_CARDS) 2805 if (dev >= SNDRV_CARDS)
2789 return -ENODEV; 2806 return -ENODEV;
2790 2807
2791 /* Should this be enable[hpi_card->index] ? */ 2808 /* Should this be enable[hpi->index] ? */
2792 if (!enable[dev]) { 2809 if (!enable[dev]) {
2793 dev++; 2810 dev++;
2794 return -ENOENT; 2811 return -ENOENT;
2795 } 2812 }
2796 2813
2814 /* Initialise low-level HPI driver */
2797 err = asihpi_adapter_probe(pci_dev, pci_id); 2815 err = asihpi_adapter_probe(pci_dev, pci_id);
2798 if (err < 0) 2816 if (err < 0)
2799 return err; 2817 return err;
2800 2818
2801 hpi_card = pci_get_drvdata(pci_dev); 2819 hpi = pci_get_drvdata(pci_dev);
2820 adapter_index = hpi->adapter->index;
2802 /* first try to give the card the same index as its hardware index */ 2821 /* first try to give the card the same index as its hardware index */
2803 err = snd_card_create(hpi_card->index, 2822 err = snd_card_create(adapter_index,
2804 id[hpi_card->index], THIS_MODULE, 2823 id[adapter_index], THIS_MODULE,
2805 sizeof(struct snd_card_asihpi), 2824 sizeof(struct snd_card_asihpi),
2806 &card); 2825 &card);
2807 if (err < 0) { 2826 if (err < 0) {
@@ -2815,50 +2834,32 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2815 return err; 2834 return err;
2816 snd_printk(KERN_WARNING 2835 snd_printk(KERN_WARNING
2817 "**** WARNING **** Adapter index %d->ALSA index %d\n", 2836 "**** WARNING **** Adapter index %d->ALSA index %d\n",
2818 hpi_card->index, card->number); 2837 adapter_index, card->number);
2819 } 2838 }
2820 2839
2821 snd_card_set_dev(card, &pci_dev->dev); 2840 snd_card_set_dev(card, &pci_dev->dev);
2822 2841
2823 asihpi = (struct snd_card_asihpi *) card->private_data; 2842 asihpi = card->private_data;
2824 asihpi->card = card; 2843 asihpi->card = card;
2825 asihpi->pci = pci_dev; 2844 asihpi->pci = pci_dev;
2826 asihpi->adapter_index = hpi_card->index; 2845 asihpi->hpi = hpi;
2827 hpi_handle_error(hpi_adapter_get_info( 2846
2828 asihpi->adapter_index, 2847 snd_printk(KERN_INFO "adapter ID=%4X index=%d\n",
2829 &asihpi->num_outstreams, 2848 asihpi->hpi->adapter->type, adapter_index);
2830 &asihpi->num_instreams, 2849
2831 &asihpi->version, 2850 err = hpi_adapter_get_property(adapter_index,
2832 &asihpi->serial_number, &asihpi->type));
2833
2834 version = asihpi->version;
2835 snd_printk(KERN_INFO "adapter ID=%4X index=%d num_outstreams=%d "
2836 "num_instreams=%d S/N=%d\n"
2837 "Hw Version %c%d DSP code version %03d\n",
2838 asihpi->type, asihpi->adapter_index,
2839 asihpi->num_outstreams,
2840 asihpi->num_instreams, asihpi->serial_number,
2841 ((version >> 3) & 0xf) + 'A',
2842 version & 0x7,
2843 ((version >> 13) * 100) + ((version >> 7) & 0x3f));
2844
2845 pcm_substreams = asihpi->num_outstreams;
2846 if (pcm_substreams < asihpi->num_instreams)
2847 pcm_substreams = asihpi->num_instreams;
2848
2849 err = hpi_adapter_get_property(asihpi->adapter_index,
2850 HPI_ADAPTER_PROPERTY_CAPS1, 2851 HPI_ADAPTER_PROPERTY_CAPS1,
2851 NULL, &asihpi->support_grouping); 2852 NULL, &asihpi->support_grouping);
2852 if (err) 2853 if (err)
2853 asihpi->support_grouping = 0; 2854 asihpi->support_grouping = 0;
2854 2855
2855 err = hpi_adapter_get_property(asihpi->adapter_index, 2856 err = hpi_adapter_get_property(adapter_index,
2856 HPI_ADAPTER_PROPERTY_CAPS2, 2857 HPI_ADAPTER_PROPERTY_CAPS2,
2857 &asihpi->support_mrx, NULL); 2858 &asihpi->support_mrx, NULL);
2858 if (err) 2859 if (err)
2859 asihpi->support_mrx = 0; 2860 asihpi->support_mrx = 0;
2860 2861
2861 err = hpi_adapter_get_property(asihpi->adapter_index, 2862 err = hpi_adapter_get_property(adapter_index,
2862 HPI_ADAPTER_PROPERTY_INTERVAL, 2863 HPI_ADAPTER_PROPERTY_INTERVAL,
2863 NULL, &asihpi->update_interval_frames); 2864 NULL, &asihpi->update_interval_frames);
2864 if (err) 2865 if (err)
@@ -2867,7 +2868,7 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2867 if (!asihpi->can_dma) 2868 if (!asihpi->can_dma)
2868 asihpi->update_interval_frames *= 2; 2869 asihpi->update_interval_frames *= 2;
2869 2870
2870 hpi_handle_error(hpi_instream_open(asihpi->adapter_index, 2871 hpi_handle_error(hpi_instream_open(adapter_index,
2871 0, &h_stream)); 2872 0, &h_stream));
2872 2873
2873 err = hpi_instream_host_buffer_free(h_stream); 2874 err = hpi_instream_host_buffer_free(h_stream);
@@ -2875,7 +2876,7 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2875 2876
2876 hpi_handle_error(hpi_instream_close(h_stream)); 2877 hpi_handle_error(hpi_instream_close(h_stream));
2877 2878
2878 err = hpi_adapter_get_property(asihpi->adapter_index, 2879 err = hpi_adapter_get_property(adapter_index,
2879 HPI_ADAPTER_PROPERTY_CURCHANNELS, 2880 HPI_ADAPTER_PROPERTY_CURCHANNELS,
2880 &asihpi->in_max_chans, &asihpi->out_max_chans); 2881 &asihpi->in_max_chans, &asihpi->out_max_chans);
2881 if (err) { 2882 if (err) {
@@ -2883,13 +2884,22 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2883 asihpi->out_max_chans = 2; 2884 asihpi->out_max_chans = 2;
2884 } 2885 }
2885 2886
2886 snd_printk(KERN_INFO "has dma:%d, grouping:%d, mrx:%d\n", 2887 if (asihpi->out_max_chans > 2) { /* assume LL mode */
2888 asihpi->out_min_chans = asihpi->out_max_chans;
2889 asihpi->in_min_chans = asihpi->in_max_chans;
2890 asihpi->support_grouping = 0;
2891 } else {
2892 asihpi->out_min_chans = 1;
2893 asihpi->in_min_chans = 1;
2894 }
2895
2896 snd_printk(KERN_INFO "Has dma:%d, grouping:%d, mrx:%d\n",
2887 asihpi->can_dma, 2897 asihpi->can_dma,
2888 asihpi->support_grouping, 2898 asihpi->support_grouping,
2889 asihpi->support_mrx 2899 asihpi->support_mrx
2890 ); 2900 );
2891 2901
2892 err = snd_card_asihpi_pcm_new(asihpi, 0, pcm_substreams); 2902 err = snd_card_asihpi_pcm_new(asihpi, 0);
2893 if (err < 0) { 2903 if (err < 0) {
2894 snd_printk(KERN_ERR "pcm_new failed\n"); 2904 snd_printk(KERN_ERR "pcm_new failed\n");
2895 goto __nodev; 2905 goto __nodev;
@@ -2916,13 +2926,14 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2916 2926
2917 strcpy(card->driver, "ASIHPI"); 2927 strcpy(card->driver, "ASIHPI");
2918 2928
2919 sprintf(card->shortname, "AudioScience ASI%4X", asihpi->type); 2929 sprintf(card->shortname, "AudioScience ASI%4X",
2930 asihpi->hpi->adapter->type);
2920 sprintf(card->longname, "%s %i", 2931 sprintf(card->longname, "%s %i",
2921 card->shortname, asihpi->adapter_index); 2932 card->shortname, adapter_index);
2922 err = snd_card_register(card); 2933 err = snd_card_register(card);
2923 2934
2924 if (!err) { 2935 if (!err) {
2925 hpi_card->snd_card_asihpi = card; 2936 hpi->snd_card = card;
2926 dev++; 2937 dev++;
2927 return 0; 2938 return 0;
2928 } 2939 }
@@ -2935,10 +2946,9 @@ __nodev:
2935 2946
2936static void __devexit snd_asihpi_remove(struct pci_dev *pci_dev) 2947static void __devexit snd_asihpi_remove(struct pci_dev *pci_dev)
2937{ 2948{
2938 struct hpi_adapter *hpi_card = pci_get_drvdata(pci_dev); 2949 struct hpi_adapter *hpi = pci_get_drvdata(pci_dev);
2939 2950 snd_card_free(hpi->snd_card);
2940 snd_card_free(hpi_card->snd_card_asihpi); 2951 hpi->snd_card = NULL;
2941 hpi_card->snd_card_asihpi = NULL;
2942 asihpi_adapter_remove(pci_dev); 2952 asihpi_adapter_remove(pci_dev);
2943} 2953}
2944 2954