aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/asihpi
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/asihpi')
-rw-r--r--sound/pci/asihpi/asihpi.c294
-rw-r--r--sound/pci/asihpi/hpi.h74
-rw-r--r--sound/pci/asihpi/hpi6000.c61
-rw-r--r--sound/pci/asihpi/hpi6000.h2
-rw-r--r--sound/pci/asihpi/hpi6205.c57
-rw-r--r--sound/pci/asihpi/hpi_internal.h115
-rw-r--r--sound/pci/asihpi/hpi_version.h32
-rw-r--r--sound/pci/asihpi/hpicmn.c32
-rw-r--r--sound/pci/asihpi/hpicmn.h13
-rw-r--r--sound/pci/asihpi/hpidebug.c2
-rw-r--r--sound/pci/asihpi/hpidebug.h2
-rw-r--r--sound/pci/asihpi/hpidspcd.c30
-rw-r--r--sound/pci/asihpi/hpidspcd.h4
-rw-r--r--sound/pci/asihpi/hpifunc.c10
-rw-r--r--sound/pci/asihpi/hpimsginit.c2
-rw-r--r--sound/pci/asihpi/hpimsginit.h2
-rw-r--r--sound/pci/asihpi/hpimsgx.c3
-rw-r--r--sound/pci/asihpi/hpimsgx.h2
-rw-r--r--sound/pci/asihpi/hpioctl.c63
-rw-r--r--sound/pci/asihpi/hpioctl.h2
-rw-r--r--sound/pci/asihpi/hpios.c2
-rw-r--r--sound/pci/asihpi/hpios.h16
-rw-r--r--sound/pci/asihpi/hpipcida.h2
23 files changed, 393 insertions, 429 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
diff --git a/sound/pci/asihpi/hpi.h b/sound/pci/asihpi/hpi.h
index f2072728899..20887241a3a 100644
--- a/sound/pci/asihpi/hpi.h
+++ b/sound/pci/asihpi/hpi.h
@@ -30,26 +30,8 @@
30 30
31#ifndef _HPI_H_ 31#ifndef _HPI_H_
32#define _HPI_H_ 32#define _HPI_H_
33/* HPI Version
34If HPI_VER_MINOR is odd then its a development release not intended for the
35public. If HPI_VER_MINOR is even then is a release version
36i.e 3.05.02 is a development version
37*/
38#define HPI_VERSION_CONSTRUCTOR(maj, min, rel) \
39 ((maj << 16) + (min << 8) + rel)
40
41#define HPI_VER_MAJOR(v) ((int)(v >> 16))
42#define HPI_VER_MINOR(v) ((int)((v >> 8) & 0xFF))
43#define HPI_VER_RELEASE(v) ((int)(v & 0xFF))
44
45#define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 8, 0)
46#define HPI_VER_STRING "4.08.00"
47
48/* Library version as documented in hpi-api-versions.txt */
49#define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(10, 0, 0)
50 33
51#include <linux/types.h> 34#include <linux/types.h>
52#define HPI_BUILD_EXCLUDE_DEPRECATED
53#define HPI_BUILD_KERNEL_MODE 35#define HPI_BUILD_KERNEL_MODE
54 36
55/******************************************************************************/ 37/******************************************************************************/
@@ -213,7 +195,7 @@ enum HPI_SOURCENODES {
213 /** RTP stream input node - This node is a destination for 195 /** RTP stream input node - This node is a destination for
214 packets of RTP audio samples from other devices. */ 196 packets of RTP audio samples from other devices. */
215 HPI_SOURCENODE_RTP_DESTINATION = 112, 197 HPI_SOURCENODE_RTP_DESTINATION = 112,
216 HPI_SOURCENODE_GP_IN = 113, /**< general purpose input. */ 198 HPI_SOURCENODE_INTERNAL = 113, /**< node internal to the device. */
217 /* !!!Update this AND hpidebug.h if you add a new sourcenode type!!! */ 199 /* !!!Update this AND hpidebug.h if you add a new sourcenode type!!! */
218 HPI_SOURCENODE_LAST_INDEX = 113 /**< largest ID */ 200 HPI_SOURCENODE_LAST_INDEX = 113 /**< largest ID */
219 /* AX6 max sourcenode types = 15 */ 201 /* AX6 max sourcenode types = 15 */
@@ -242,9 +224,8 @@ enum HPI_DESTNODES {
242 /** RTP stream output node - This node is a source for 224 /** RTP stream output node - This node is a source for
243 packets of RTP audio samples that are sent to other devices. */ 225 packets of RTP audio samples that are sent to other devices. */
244 HPI_DESTNODE_RTP_SOURCE = 208, 226 HPI_DESTNODE_RTP_SOURCE = 208,
245 HPI_DESTNODE_GP_OUT = 209, /**< general purpose output node. */
246 /* !!!Update this AND hpidebug.h if you add a new destnode type!!! */ 227 /* !!!Update this AND hpidebug.h if you add a new destnode type!!! */
247 HPI_DESTNODE_LAST_INDEX = 209 /**< largest ID */ 228 HPI_DESTNODE_LAST_INDEX = 208 /**< largest ID */
248 /* AX6 max destnode types = 15 */ 229 /* AX6 max destnode types = 15 */
249}; 230};
250 231
@@ -450,7 +431,19 @@ Indicates that the adapter in it's current mode supports interrupts
450across the host bus. Note, this does not imply that interrupts are 431across the host bus. Note, this does not imply that interrupts are
451enabled. Instead it indicates that they can be enabled. 432enabled. Instead it indicates that they can be enabled.
452*/ 433*/
453 HPI_ADAPTER_PROPERTY_SUPPORTS_IRQ = 272 434 HPI_ADAPTER_PROPERTY_SUPPORTS_IRQ = 272,
435/** Readonly supports firmware updating.
436Indicates that the adapter implements an interface to update firmware
437on the adapter.
438*/
439 HPI_ADAPTER_PROPERTY_SUPPORTS_FW_UPDATE = 273,
440/** Readonly Firmware IDs
441Identifiy firmware independent of individual adapter type.
442May be used as a filter for firmware update images.
443Property 1 = Bootloader ID
444Property 2 = Main program ID
445*/
446 HPI_ADAPTER_PROPERTY_FIRMWARE_ID = 274
454}; 447};
455 448
456/** Adapter mode commands 449/** Adapter mode commands
@@ -638,7 +631,7 @@ enum HPI_MIXER_STORE_COMMAND {
638 HPI_MIXER_STORE_ENABLE = 4, 631 HPI_MIXER_STORE_ENABLE = 4,
639/** Disable auto storage of some control settings. */ 632/** Disable auto storage of some control settings. */
640 HPI_MIXER_STORE_DISABLE = 5, 633 HPI_MIXER_STORE_DISABLE = 5,
641/** Save the attributes of a single control. */ 634/** Unimplemented - save the attributes of a single control. */
642 HPI_MIXER_STORE_SAVE_SINGLE = 6 635 HPI_MIXER_STORE_SAVE_SINGLE = 6
643}; 636};
644 637
@@ -941,7 +934,7 @@ enum HPI_ERROR_CODES {
941 HPI_ERROR_BAD_ADAPTER_NUMBER = 202, 934 HPI_ERROR_BAD_ADAPTER_NUMBER = 202,
942 /** 2 adapters with the same adapter number. */ 935 /** 2 adapters with the same adapter number. */
943 HPI_ERROR_DUPLICATE_ADAPTER_NUMBER = 203, 936 HPI_ERROR_DUPLICATE_ADAPTER_NUMBER = 203,
944 /** DSP code failed to bootload. (unused?) */ 937 /** DSP code failed to bootload. Usually a DSP memory test failure. */
945 HPI_ERROR_DSP_BOOTLOAD = 204, 938 HPI_ERROR_DSP_BOOTLOAD = 204,
946 /** Couldn't find or open the DSP code file. */ 939 /** Couldn't find or open the DSP code file. */
947 HPI_ERROR_DSP_FILE_NOT_FOUND = 206, 940 HPI_ERROR_DSP_FILE_NOT_FOUND = 206,
@@ -978,6 +971,9 @@ enum HPI_ERROR_CODES {
978 HPI_ERROR_FLASH_VERIFY = 225, 971 HPI_ERROR_FLASH_VERIFY = 225,
979 HPI_ERROR_FLASH_TYPE = 226, 972 HPI_ERROR_FLASH_TYPE = 226,
980 HPI_ERROR_FLASH_START = 227, 973 HPI_ERROR_FLASH_START = 227,
974 HPI_ERROR_FLASH_READ = 228,
975 HPI_ERROR_FLASH_READ_NO_FILE = 229,
976 HPI_ERROR_FLASH_SIZE = 230,
981 977
982 /** Reserved for OEMs. */ 978 /** Reserved for OEMs. */
983 HPI_ERROR_RESERVED_1 = 290, 979 HPI_ERROR_RESERVED_1 = 290,
@@ -1020,6 +1016,8 @@ enum HPI_ERROR_CODES {
1020 HPI_ERROR_NO_INTERDSP_GROUPS = 315, 1016 HPI_ERROR_NO_INTERDSP_GROUPS = 315,
1021 /** Stream wait cancelled before threshold reached. */ 1017 /** Stream wait cancelled before threshold reached. */
1022 HPI_ERROR_WAIT_CANCELLED = 316, 1018 HPI_ERROR_WAIT_CANCELLED = 316,
1019 /** A character string is invalid. */
1020 HPI_ERROR_INVALID_STRING = 317,
1023 1021
1024 /** Invalid mixer node for this adapter. */ 1022 /** Invalid mixer node for this adapter. */
1025 HPI_ERROR_INVALID_NODE = 400, 1023 HPI_ERROR_INVALID_NODE = 400,
@@ -1046,11 +1044,15 @@ enum HPI_ERROR_CODES {
1046 /** I2C */ 1044 /** I2C */
1047 HPI_ERROR_I2C_BAD_ADR = 460, 1045 HPI_ERROR_I2C_BAD_ADR = 460,
1048 1046
1049 /** Entity errors */ 1047 /** Entity type did not match requested type */
1050 HPI_ERROR_ENTITY_TYPE_MISMATCH = 470, 1048 HPI_ERROR_ENTITY_TYPE_MISMATCH = 470,
1049 /** Entity item count did not match requested count */
1051 HPI_ERROR_ENTITY_ITEM_COUNT = 471, 1050 HPI_ERROR_ENTITY_ITEM_COUNT = 471,
1051 /** Entity type is not one of the valid types */
1052 HPI_ERROR_ENTITY_TYPE_INVALID = 472, 1052 HPI_ERROR_ENTITY_TYPE_INVALID = 472,
1053 /** Entity role is not one of the valid roles */
1053 HPI_ERROR_ENTITY_ROLE_INVALID = 473, 1054 HPI_ERROR_ENTITY_ROLE_INVALID = 473,
1055 /** Entity size doesn't match target size */
1054 HPI_ERROR_ENTITY_SIZE_MISMATCH = 474, 1056 HPI_ERROR_ENTITY_SIZE_MISMATCH = 474,
1055 1057
1056 /* AES18 specific errors were 500..507 */ 1058 /* AES18 specific errors were 500..507 */
@@ -1078,8 +1080,7 @@ enum HPI_ERROR_CODES {
1078/** \defgroup maximums HPI maximum values 1080/** \defgroup maximums HPI maximum values
1079\{ 1081\{
1080*/ 1082*/
1081/** Maximum number of adapters per HPI sub-system 1083/** Maximum number of PCI HPI adapters */
1082 WARNING: modifying this value changes the response structure size.*/
1083#define HPI_MAX_ADAPTERS 20 1084#define HPI_MAX_ADAPTERS 20
1084/** Maximum number of in or out streams per adapter */ 1085/** Maximum number of in or out streams per adapter */
1085#define HPI_MAX_STREAMS 16 1086#define HPI_MAX_STREAMS 16
@@ -1090,6 +1091,9 @@ enum HPI_ERROR_CODES {
1090#define HPI_MAX_ANC_BYTES_PER_FRAME (64) 1091#define HPI_MAX_ANC_BYTES_PER_FRAME (64)
1091#define HPI_STRING_LEN 16 1092#define HPI_STRING_LEN 16
1092 1093
1094/** Networked adapters have index >= 100 */
1095#define HPI_MIN_NETWORK_ADAPTER_IDX 100
1096
1093/** Velocity units */ 1097/** Velocity units */
1094#define HPI_OSTREAM_VELOCITY_UNITS 4096 1098#define HPI_OSTREAM_VELOCITY_UNITS 4096
1095/** OutStream timescale units */ 1099/** OutStream timescale units */
@@ -1111,14 +1115,14 @@ enum HPI_ERROR_CODES {
1111struct hpi_format { 1115struct hpi_format {
1112 u32 sample_rate; 1116 u32 sample_rate;
1113 /**< 11025, 32000, 44100 ... */ 1117 /**< 11025, 32000, 44100 ... */
1114 u32 bit_rate; /**< for MPEG */ 1118 u32 bit_rate; /**< for MPEG */
1115 u32 attributes; 1119 u32 attributes;
1116 /**< Stereo/JointStereo/Mono */ 1120 /**< Stereo/JointStereo/Mono */
1117 u16 mode_legacy; 1121 u16 mode_legacy;
1118 /**< Legacy ancillary mode or idle bit */ 1122 /**< Legacy ancillary mode or idle bit */
1119 u16 unused; /**< Unused */ 1123 u16 unused; /**< Unused */
1120 u16 channels; /**< 1,2..., (or ancillary mode or idle bit */ 1124 u16 channels; /**< 1,2..., (or ancillary mode or idle bit */
1121 u16 format; /**< HPI_FORMAT_PCM16, _MPEG etc. see #HPI_FORMATS. */ 1125 u16 format; /**< HPI_FORMAT_PCM16, _MPEG etc. see #HPI_FORMATS. */
1122}; 1126};
1123 1127
1124struct hpi_anc_frame { 1128struct hpi_anc_frame {
@@ -1144,9 +1148,6 @@ struct hpi_async_event {
1144 } u; 1148 } u;
1145}; 1149};
1146 1150
1147/* skip host side function declarations for
1148 DSP compile and documentation extraction */
1149
1150#ifndef DISABLE_PRAGMA_PACK1 1151#ifndef DISABLE_PRAGMA_PACK1
1151#pragma pack(pop) 1152#pragma pack(pop)
1152#endif 1153#endif
@@ -1357,7 +1358,7 @@ u16 hpi_volume_get_mute(u32 h_control, u32 *mute);
1357u16 hpi_volume_query_range(u32 h_control, short *min_gain_01dB, 1358u16 hpi_volume_query_range(u32 h_control, short *min_gain_01dB,
1358 short *max_gain_01dB, short *step_gain_01dB); 1359 short *max_gain_01dB, short *step_gain_01dB);
1359 1360
1360u16 hpi_volume_query_channels(const u32 h_volume, u32 *p_channels); 1361u16 hpi_volume_query_channels(const u32 h_control, u32 *p_channels);
1361 1362
1362u16 hpi_volume_auto_fade(u32 h_control, 1363u16 hpi_volume_auto_fade(u32 h_control,
1363 short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms); 1364 short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms);
@@ -1366,6 +1367,9 @@ u16 hpi_volume_auto_fade_profile(u32 h_control,
1366 short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms, 1367 short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms,
1367 u16 profile); 1368 u16 profile);
1368 1369
1370u16 hpi_volume_query_auto_fade_profile(const u32 h_control, const u32 i,
1371 u16 *profile);
1372
1369/*****************/ 1373/*****************/
1370/* Level control */ 1374/* Level control */
1371/*****************/ 1375/*****************/
diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c
index 3cc6f11c20a..2414d7a2239 100644
--- a/sound/pci/asihpi/hpi6000.c
+++ b/sound/pci/asihpi/hpi6000.c
@@ -1,7 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 AudioScience HPI driver 3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> 4 Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as 7 it under the terms of version 2 of the GNU General Public License as
@@ -231,6 +231,8 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
231static void control_message(struct hpi_adapter_obj *pao, 231static void control_message(struct hpi_adapter_obj *pao,
232 struct hpi_message *phm, struct hpi_response *phr) 232 struct hpi_message *phm, struct hpi_response *phr)
233{ 233{
234 struct hpi_hw_obj *phw = pao->priv;
235
234 switch (phm->function) { 236 switch (phm->function) {
235 case HPI_CONTROL_GET_STATE: 237 case HPI_CONTROL_GET_STATE:
236 if (pao->has_control_cache) { 238 if (pao->has_control_cache) {
@@ -248,17 +250,14 @@ static void control_message(struct hpi_adapter_obj *pao,
248 break; 250 break;
249 } 251 }
250 252
251 if (hpi_check_control_cache(((struct hpi_hw_obj *) 253 if (hpi_check_control_cache(phw->p_cache, phm, phr))
252 pao->priv)->p_cache, phm,
253 phr))
254 break; 254 break;
255 } 255 }
256 hw_message(pao, phm, phr); 256 hw_message(pao, phm, phr);
257 break; 257 break;
258 case HPI_CONTROL_SET_STATE: 258 case HPI_CONTROL_SET_STATE:
259 hw_message(pao, phm, phr); 259 hw_message(pao, phm, phr);
260 hpi_cmn_control_cache_sync_to_msg(((struct hpi_hw_obj *)pao-> 260 hpi_cmn_control_cache_sync_to_msg(phw->p_cache, phm, phr);
261 priv)->p_cache, phm, phr);
262 break; 261 break;
263 262
264 case HPI_CONTROL_GET_INFO: 263 case HPI_CONTROL_GET_INFO:
@@ -451,11 +450,11 @@ static void subsys_create_adapter(struct hpi_message *phm,
451 } 450 }
452 451
453 for (dsp_index = 0; dsp_index < MAX_DSPS; dsp_index++) { 452 for (dsp_index = 0; dsp_index < MAX_DSPS; dsp_index++) {
454 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; 453 struct hpi_hw_obj *phw = pao->priv;
455 phw->ado[dsp_index].pa_parent_adapter = pao; 454 phw->ado[dsp_index].pa_parent_adapter = pao;
456 } 455 }
457 456
458 phr->u.s.adapter_type = ao.adapter_type; 457 phr->u.s.adapter_type = ao.type;
459 phr->u.s.adapter_index = ao.index; 458 phr->u.s.adapter_index = ao.index;
460 phr->error = 0; 459 phr->error = 0;
461} 460}
@@ -476,7 +475,7 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao,
476 u32 dsp_index = 0; 475 u32 dsp_index = 0;
477 u32 control_cache_size = 0; 476 u32 control_cache_size = 0;
478 u32 control_cache_count = 0; 477 u32 control_cache_count = 0;
479 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; 478 struct hpi_hw_obj *phw = pao->priv;
480 479
481 /* The PCI2040 has the following address map */ 480 /* The PCI2040 has the following address map */
482 /* BAR0 - 4K = HPI control and status registers on PCI2040 (HPI CSR) */ 481 /* BAR0 - 4K = HPI control and status registers on PCI2040 (HPI CSR) */
@@ -559,7 +558,7 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao,
559 if (error) 558 if (error)
560 return error; 559 return error;
561 } 560 }
562 pao->adapter_type = hr0.u.ax.info.adapter_type; 561 pao->type = hr0.u.ax.info.adapter_type;
563 pao->index = hr0.u.ax.info.adapter_index; 562 pao->index = hr0.u.ax.info.adapter_index;
564 } 563 }
565 564
@@ -584,9 +583,8 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao,
584 pao->has_control_cache = 1; 583 pao->has_control_cache = 1;
585 } 584 }
586 585
587 HPI_DEBUG_LOG(DEBUG, "get adapter info ASI%04X index %d\n", 586 HPI_DEBUG_LOG(DEBUG, "get adapter info ASI%04X index %d\n", pao->type,
588 pao->adapter_type, pao->index); 587 pao->index);
589 pao->open = 0; /* upon creation the adapter is closed */
590 588
591 if (phw->p_cache) 589 if (phw->p_cache)
592 phw->p_cache->adap_idx = pao->index; 590 phw->p_cache->adap_idx = pao->index;
@@ -596,7 +594,7 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao,
596 594
597static void delete_adapter_obj(struct hpi_adapter_obj *pao) 595static void delete_adapter_obj(struct hpi_adapter_obj *pao)
598{ 596{
599 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; 597 struct hpi_hw_obj *phw = pao->priv;
600 598
601 if (pao->has_control_cache) 599 if (pao->has_control_cache)
602 hpi_free_control_cache(phw->p_cache); 600 hpi_free_control_cache(phw->p_cache);
@@ -639,7 +637,7 @@ static void adapter_get_asserts(struct hpi_adapter_obj *pao,
639static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao, 637static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
640 u32 *pos_error_code) 638 u32 *pos_error_code)
641{ 639{
642 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; 640 struct hpi_hw_obj *phw = pao->priv;
643 short error; 641 short error;
644 u32 timeout; 642 u32 timeout;
645 u32 read = 0; 643 u32 read = 0;
@@ -1220,8 +1218,8 @@ static void hpi_read_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
1220static u16 hpi6000_dsp_block_write32(struct hpi_adapter_obj *pao, 1218static u16 hpi6000_dsp_block_write32(struct hpi_adapter_obj *pao,
1221 u16 dsp_index, u32 hpi_address, u32 *source, u32 count) 1219 u16 dsp_index, u32 hpi_address, u32 *source, u32 count)
1222{ 1220{
1223 struct dsp_obj *pdo = 1221 struct hpi_hw_obj *phw = pao->priv;
1224 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index]; 1222 struct dsp_obj *pdo = &phw->ado[dsp_index];
1225 u32 time_out = PCI_TIMEOUT; 1223 u32 time_out = PCI_TIMEOUT;
1226 int c6711_burst_size = 128; 1224 int c6711_burst_size = 128;
1227 u32 local_hpi_address = hpi_address; 1225 u32 local_hpi_address = hpi_address;
@@ -1258,8 +1256,8 @@ static u16 hpi6000_dsp_block_write32(struct hpi_adapter_obj *pao,
1258static u16 hpi6000_dsp_block_read32(struct hpi_adapter_obj *pao, 1256static u16 hpi6000_dsp_block_read32(struct hpi_adapter_obj *pao,
1259 u16 dsp_index, u32 hpi_address, u32 *dest, u32 count) 1257 u16 dsp_index, u32 hpi_address, u32 *dest, u32 count)
1260{ 1258{
1261 struct dsp_obj *pdo = 1259 struct hpi_hw_obj *phw = pao->priv;
1262 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index]; 1260 struct dsp_obj *pdo = &phw->ado[dsp_index];
1263 u32 time_out = PCI_TIMEOUT; 1261 u32 time_out = PCI_TIMEOUT;
1264 int c6711_burst_size = 16; 1262 int c6711_burst_size = 16;
1265 u32 local_hpi_address = hpi_address; 1263 u32 local_hpi_address = hpi_address;
@@ -1298,7 +1296,7 @@ static u16 hpi6000_dsp_block_read32(struct hpi_adapter_obj *pao,
1298static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao, 1296static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
1299 u16 dsp_index, struct hpi_message *phm, struct hpi_response *phr) 1297 u16 dsp_index, struct hpi_message *phm, struct hpi_response *phr)
1300{ 1298{
1301 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; 1299 struct hpi_hw_obj *phw = pao->priv;
1302 struct dsp_obj *pdo = &phw->ado[dsp_index]; 1300 struct dsp_obj *pdo = &phw->ado[dsp_index];
1303 u32 timeout; 1301 u32 timeout;
1304 u16 ack; 1302 u16 ack;
@@ -1414,8 +1412,8 @@ static short hpi6000_send_data_check_adr(u32 address, u32 length_in_dwords)
1414static short hpi6000_send_data(struct hpi_adapter_obj *pao, u16 dsp_index, 1412static short hpi6000_send_data(struct hpi_adapter_obj *pao, u16 dsp_index,
1415 struct hpi_message *phm, struct hpi_response *phr) 1413 struct hpi_message *phm, struct hpi_response *phr)
1416{ 1414{
1417 struct dsp_obj *pdo = 1415 struct hpi_hw_obj *phw = pao->priv;
1418 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index]; 1416 struct dsp_obj *pdo = &phw->ado[dsp_index];
1419 u32 data_sent = 0; 1417 u32 data_sent = 0;
1420 u16 ack; 1418 u16 ack;
1421 u32 length, address; 1419 u32 length, address;
@@ -1487,8 +1485,8 @@ static short hpi6000_send_data(struct hpi_adapter_obj *pao, u16 dsp_index,
1487static short hpi6000_get_data(struct hpi_adapter_obj *pao, u16 dsp_index, 1485static short hpi6000_get_data(struct hpi_adapter_obj *pao, u16 dsp_index,
1488 struct hpi_message *phm, struct hpi_response *phr) 1486 struct hpi_message *phm, struct hpi_response *phr)
1489{ 1487{
1490 struct dsp_obj *pdo = 1488 struct hpi_hw_obj *phw = pao->priv;
1491 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index]; 1489 struct dsp_obj *pdo = &phw->ado[dsp_index];
1492 u32 data_got = 0; 1490 u32 data_got = 0;
1493 u16 ack; 1491 u16 ack;
1494 u32 length, address; 1492 u32 length, address;
@@ -1551,8 +1549,8 @@ static void hpi6000_send_dsp_interrupt(struct dsp_obj *pdo)
1551static short hpi6000_send_host_command(struct hpi_adapter_obj *pao, 1549static short hpi6000_send_host_command(struct hpi_adapter_obj *pao,
1552 u16 dsp_index, u32 host_cmd) 1550 u16 dsp_index, u32 host_cmd)
1553{ 1551{
1554 struct dsp_obj *pdo = 1552 struct hpi_hw_obj *phw = pao->priv;
1555 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index]; 1553 struct dsp_obj *pdo = &phw->ado[dsp_index];
1556 u32 timeout = TIMEOUT; 1554 u32 timeout = TIMEOUT;
1557 1555
1558 /* set command */ 1556 /* set command */
@@ -1577,7 +1575,7 @@ static short hpi6000_check_PCI2040_error_flag(struct hpi_adapter_obj *pao,
1577{ 1575{
1578 u32 hPI_error; 1576 u32 hPI_error;
1579 1577
1580 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; 1578 struct hpi_hw_obj *phw = pao->priv;
1581 1579
1582 /* read the error bits from the PCI2040 */ 1580 /* read the error bits from the PCI2040 */
1583 hPI_error = ioread32(phw->dw2040_HPICSR + HPI_ERROR_REPORT); 1581 hPI_error = ioread32(phw->dw2040_HPICSR + HPI_ERROR_REPORT);
@@ -1597,8 +1595,8 @@ static short hpi6000_check_PCI2040_error_flag(struct hpi_adapter_obj *pao,
1597static short hpi6000_wait_dsp_ack(struct hpi_adapter_obj *pao, u16 dsp_index, 1595static short hpi6000_wait_dsp_ack(struct hpi_adapter_obj *pao, u16 dsp_index,
1598 u32 ack_value) 1596 u32 ack_value)
1599{ 1597{
1600 struct dsp_obj *pdo = 1598 struct hpi_hw_obj *phw = pao->priv;
1601 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index]; 1599 struct dsp_obj *pdo = &phw->ado[dsp_index];
1602 u32 ack = 0L; 1600 u32 ack = 0L;
1603 u32 timeout; 1601 u32 timeout;
1604 u32 hPIC = 0L; 1602 u32 hPIC = 0L;
@@ -1640,7 +1638,7 @@ static short hpi6000_update_control_cache(struct hpi_adapter_obj *pao,
1640 struct hpi_message *phm) 1638 struct hpi_message *phm)
1641{ 1639{
1642 const u16 dsp_index = 0; 1640 const u16 dsp_index = 0;
1643 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; 1641 struct hpi_hw_obj *phw = pao->priv;
1644 struct dsp_obj *pdo = &phw->ado[dsp_index]; 1642 struct dsp_obj *pdo = &phw->ado[dsp_index];
1645 u32 timeout; 1643 u32 timeout;
1646 u32 cache_dirty_flag; 1644 u32 cache_dirty_flag;
@@ -1740,7 +1738,8 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
1740{ 1738{
1741 u16 error = 0; 1739 u16 error = 0;
1742 u16 dsp_index = 0; 1740 u16 dsp_index = 0;
1743 u16 num_dsp = ((struct hpi_hw_obj *)pao->priv)->num_dsp; 1741 struct hpi_hw_obj *phw = pao->priv;
1742 u16 num_dsp = phw->num_dsp;
1744 1743
1745 if (num_dsp < 2) 1744 if (num_dsp < 2)
1746 dsp_index = 0; 1745 dsp_index = 0;
diff --git a/sound/pci/asihpi/hpi6000.h b/sound/pci/asihpi/hpi6000.h
index 4c7d507c0ec..7e0deeff5e7 100644
--- a/sound/pci/asihpi/hpi6000.h
+++ b/sound/pci/asihpi/hpi6000.h
@@ -1,7 +1,7 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 AudioScience HPI driver 3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> 4 Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as 7 it under the terms of version 2 of the GNU General Public License as
diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c
index e041a6ae1c5..4f2873880b1 100644
--- a/sound/pci/asihpi/hpi6205.c
+++ b/sound/pci/asihpi/hpi6205.c
@@ -1,7 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 AudioScience HPI driver 3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> 4 Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as 7 it under the terms of version 2 of the GNU General Public License as
@@ -45,18 +45,21 @@
45#define HPI6205_ERROR_MSG_RESP_TIMEOUT 1016 45#define HPI6205_ERROR_MSG_RESP_TIMEOUT 1016
46 46
47/* initialization/bootload errors */ 47/* initialization/bootload errors */
48#define HPI6205_ERROR_6205_NO_IRQ 1002 48#define HPI6205_ERROR_6205_NO_IRQ 1002
49#define HPI6205_ERROR_6205_INIT_FAILED 1003 49#define HPI6205_ERROR_6205_INIT_FAILED 1003
50#define HPI6205_ERROR_6205_REG 1006 50#define HPI6205_ERROR_6205_REG 1006
51#define HPI6205_ERROR_6205_DSPPAGE 1007 51#define HPI6205_ERROR_6205_DSPPAGE 1007
52#define HPI6205_ERROR_C6713_HPIC 1009 52#define HPI6205_ERROR_C6713_HPIC 1009
53#define HPI6205_ERROR_C6713_HPIA 1010 53#define HPI6205_ERROR_C6713_HPIA 1010
54#define HPI6205_ERROR_C6713_PLL 1011 54#define HPI6205_ERROR_C6713_PLL 1011
55#define HPI6205_ERROR_DSP_INTMEM 1012 55#define HPI6205_ERROR_DSP_INTMEM 1012
56#define HPI6205_ERROR_DSP_EXTMEM 1013 56#define HPI6205_ERROR_DSP_EXTMEM 1013
57#define HPI6205_ERROR_DSP_PLD 1014 57#define HPI6205_ERROR_DSP_PLD 1014
58#define HPI6205_ERROR_6205_EEPROM 1017 58#define HPI6205_ERROR_6205_EEPROM 1017
59#define HPI6205_ERROR_DSP_EMIF 1018 59#define HPI6205_ERROR_DSP_EMIF1 1018
60#define HPI6205_ERROR_DSP_EMIF2 1019
61#define HPI6205_ERROR_DSP_EMIF3 1020
62#define HPI6205_ERROR_DSP_EMIF4 1021
60 63
61/*****************************************************************************/ 64/*****************************************************************************/
62/* for C6205 PCI i/f */ 65/* for C6205 PCI i/f */
@@ -488,7 +491,7 @@ static void subsys_create_adapter(struct hpi_message *phm,
488 return; 491 return;
489 } 492 }
490 493
491 phr->u.s.adapter_type = ao.adapter_type; 494 phr->u.s.adapter_type = ao.type;
492 phr->u.s.adapter_index = ao.index; 495 phr->u.s.adapter_index = ao.index;
493 phr->error = 0; 496 phr->error = 0;
494} 497}
@@ -503,7 +506,7 @@ static void adapter_delete(struct hpi_adapter_obj *pao,
503 phr->error = HPI_ERROR_INVALID_OBJ_INDEX; 506 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
504 return; 507 return;
505 } 508 }
506 phw = (struct hpi_hw_obj *)pao->priv; 509 phw = pao->priv;
507 /* reset adapter h/w */ 510 /* reset adapter h/w */
508 /* Reset C6713 #1 */ 511 /* Reset C6713 #1 */
509 boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 0); 512 boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 0);
@@ -652,7 +655,7 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
652 if (hr.error) 655 if (hr.error)
653 return hr.error; 656 return hr.error;
654 657
655 pao->adapter_type = hr.u.ax.info.adapter_type; 658 pao->type = hr.u.ax.info.adapter_type;
656 pao->index = hr.u.ax.info.adapter_index; 659 pao->index = hr.u.ax.info.adapter_index;
657 660
658 max_streams = 661 max_streams =
@@ -665,8 +668,6 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
665 hr.u.ax.info.serial_number); 668 hr.u.ax.info.serial_number);
666 } 669 }
667 670
668 pao->open = 0; /* upon creation the adapter is closed */
669
670 if (phw->p_cache) 671 if (phw->p_cache)
671 phw->p_cache->adap_idx = pao->index; 672 phw->p_cache->adap_idx = pao->index;
672 673
@@ -803,8 +804,8 @@ static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao,
803 obj_index]; 804 obj_index];
804 status->samples_processed = 0; 805 status->samples_processed = 0;
805 status->stream_state = HPI_STATE_STOPPED; 806 status->stream_state = HPI_STATE_STOPPED;
806 status->dSP_index = 0; 807 status->dsp_index = 0;
807 status->host_index = status->dSP_index; 808 status->host_index = status->dsp_index;
808 status->size_in_bytes = phm->u.d.u.buffer.buffer_size; 809 status->size_in_bytes = phm->u.d.u.buffer.buffer_size;
809 status->auxiliary_data_available = 0; 810 status->auxiliary_data_available = 0;
810 811
@@ -878,7 +879,7 @@ static void outstream_host_buffer_free(struct hpi_adapter_obj *pao,
878static u32 outstream_get_space_available(struct hpi_hostbuffer_status *status) 879static u32 outstream_get_space_available(struct hpi_hostbuffer_status *status)
879{ 880{
880 return status->size_in_bytes - (status->host_index - 881 return status->size_in_bytes - (status->host_index -
881 status->dSP_index); 882 status->dsp_index);
882} 883}
883 884
884static void outstream_write(struct hpi_adapter_obj *pao, 885static void outstream_write(struct hpi_adapter_obj *pao,
@@ -1080,8 +1081,8 @@ static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
1080 obj_index]; 1081 obj_index];
1081 status->samples_processed = 0; 1082 status->samples_processed = 0;
1082 status->stream_state = HPI_STATE_STOPPED; 1083 status->stream_state = HPI_STATE_STOPPED;
1083 status->dSP_index = 0; 1084 status->dsp_index = 0;
1084 status->host_index = status->dSP_index; 1085 status->host_index = status->dsp_index;
1085 status->size_in_bytes = phm->u.d.u.buffer.buffer_size; 1086 status->size_in_bytes = phm->u.d.u.buffer.buffer_size;
1086 status->auxiliary_data_available = 0; 1087 status->auxiliary_data_available = 0;
1087 1088
@@ -1162,7 +1163,7 @@ static void instream_start(struct hpi_adapter_obj *pao,
1162 1163
1163static u32 instream_get_bytes_available(struct hpi_hostbuffer_status *status) 1164static u32 instream_get_bytes_available(struct hpi_hostbuffer_status *status)
1164{ 1165{
1165 return status->dSP_index - status->host_index; 1166 return status->dsp_index - status->host_index;
1166} 1167}
1167 1168
1168static void instream_read(struct hpi_adapter_obj *pao, 1169static void instream_read(struct hpi_adapter_obj *pao,
@@ -1614,7 +1615,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1614 boot_loader_write_mem32(pao, dsp_index, 0x01800008, setting); 1615 boot_loader_write_mem32(pao, dsp_index, 0x01800008, setting);
1615 if (setting != boot_loader_read_mem32(pao, dsp_index, 1616 if (setting != boot_loader_read_mem32(pao, dsp_index,
1616 0x01800008)) 1617 0x01800008))
1617 return HPI6205_ERROR_DSP_EMIF; 1618 return HPI6205_ERROR_DSP_EMIF1;
1618 1619
1619 /* EMIF CE1 setup - 32 bit async. This is 6713 #1 HPI, */ 1620 /* EMIF CE1 setup - 32 bit async. This is 6713 #1 HPI, */
1620 /* which occupies D15..0. 6713 starts at 27MHz, so need */ 1621 /* which occupies D15..0. 6713 starts at 27MHz, so need */
@@ -1627,7 +1628,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1627 boot_loader_write_mem32(pao, dsp_index, 0x01800004, setting); 1628 boot_loader_write_mem32(pao, dsp_index, 0x01800004, setting);
1628 if (setting != boot_loader_read_mem32(pao, dsp_index, 1629 if (setting != boot_loader_read_mem32(pao, dsp_index,
1629 0x01800004)) 1630 0x01800004))
1630 return HPI6205_ERROR_DSP_EMIF; 1631 return HPI6205_ERROR_DSP_EMIF2;
1631 1632
1632 /* EMIF CE2 setup - 32 bit async. This is 6713 #2 HPI, */ 1633 /* EMIF CE2 setup - 32 bit async. This is 6713 #2 HPI, */
1633 /* which occupies D15..0. 6713 starts at 27MHz, so need */ 1634 /* which occupies D15..0. 6713 starts at 27MHz, so need */
@@ -1639,7 +1640,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1639 boot_loader_write_mem32(pao, dsp_index, 0x01800010, setting); 1640 boot_loader_write_mem32(pao, dsp_index, 0x01800010, setting);
1640 if (setting != boot_loader_read_mem32(pao, dsp_index, 1641 if (setting != boot_loader_read_mem32(pao, dsp_index,
1641 0x01800010)) 1642 0x01800010))
1642 return HPI6205_ERROR_DSP_EMIF; 1643 return HPI6205_ERROR_DSP_EMIF3;
1643 1644
1644 /* EMIF CE3 setup - 32 bit async. */ 1645 /* EMIF CE3 setup - 32 bit async. */
1645 /* This is the PLD on the ASI5000 cards only */ 1646 /* This is the PLD on the ASI5000 cards only */
@@ -1650,7 +1651,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1650 boot_loader_write_mem32(pao, dsp_index, 0x01800014, setting); 1651 boot_loader_write_mem32(pao, dsp_index, 0x01800014, setting);
1651 if (setting != boot_loader_read_mem32(pao, dsp_index, 1652 if (setting != boot_loader_read_mem32(pao, dsp_index,
1652 0x01800014)) 1653 0x01800014))
1653 return HPI6205_ERROR_DSP_EMIF; 1654 return HPI6205_ERROR_DSP_EMIF4;
1654 1655
1655 /* set EMIF SDRAM control for 2Mx32 SDRAM (512x32x4 bank) */ 1656 /* set EMIF SDRAM control for 2Mx32 SDRAM (512x32x4 bank) */
1656 /* need to use this else DSP code crashes? */ 1657 /* need to use this else DSP code crashes? */
diff --git a/sound/pci/asihpi/hpi_internal.h b/sound/pci/asihpi/hpi_internal.h
index d497030c160..4cc315daeda 100644
--- a/sound/pci/asihpi/hpi_internal.h
+++ b/sound/pci/asihpi/hpi_internal.h
@@ -25,6 +25,7 @@ HPI internal definitions
25#define _HPI_INTERNAL_H_ 25#define _HPI_INTERNAL_H_
26 26
27#include "hpi.h" 27#include "hpi.h"
28
28/** maximum number of memory regions mapped to an adapter */ 29/** maximum number of memory regions mapped to an adapter */
29#define HPI_MAX_ADAPTER_MEM_SPACES (2) 30#define HPI_MAX_ADAPTER_MEM_SPACES (2)
30 31
@@ -220,8 +221,6 @@ enum HPI_CONTROL_ATTRIBUTES {
220 221
221 HPI_COBRANET_SET = HPI_CTL_ATTR(COBRANET, 1), 222 HPI_COBRANET_SET = HPI_CTL_ATTR(COBRANET, 1),
222 HPI_COBRANET_GET = HPI_CTL_ATTR(COBRANET, 2), 223 HPI_COBRANET_GET = HPI_CTL_ATTR(COBRANET, 2),
223 /*HPI_COBRANET_SET_DATA = HPI_CTL_ATTR(COBRANET, 3), */
224 /*HPI_COBRANET_GET_DATA = HPI_CTL_ATTR(COBRANET, 4), */
225 HPI_COBRANET_GET_STATUS = HPI_CTL_ATTR(COBRANET, 5), 224 HPI_COBRANET_GET_STATUS = HPI_CTL_ATTR(COBRANET, 5),
226 HPI_COBRANET_SEND_PACKET = HPI_CTL_ATTR(COBRANET, 6), 225 HPI_COBRANET_SEND_PACKET = HPI_CTL_ATTR(COBRANET, 6),
227 HPI_COBRANET_GET_PACKET = HPI_CTL_ATTR(COBRANET, 7), 226 HPI_COBRANET_GET_PACKET = HPI_CTL_ATTR(COBRANET, 7),
@@ -241,7 +240,9 @@ enum HPI_CONTROL_ATTRIBUTES {
241 HPI_PAD_PROGRAM_TYPE = HPI_CTL_ATTR(PAD, 5), 240 HPI_PAD_PROGRAM_TYPE = HPI_CTL_ATTR(PAD, 5),
242 HPI_PAD_PROGRAM_ID = HPI_CTL_ATTR(PAD, 6), 241 HPI_PAD_PROGRAM_ID = HPI_CTL_ATTR(PAD, 6),
243 HPI_PAD_TA_SUPPORT = HPI_CTL_ATTR(PAD, 7), 242 HPI_PAD_TA_SUPPORT = HPI_CTL_ATTR(PAD, 7),
244 HPI_PAD_TA_ACTIVE = HPI_CTL_ATTR(PAD, 8) 243 HPI_PAD_TA_ACTIVE = HPI_CTL_ATTR(PAD, 8),
244
245 HPI_UNIVERSAL_ENTITY = HPI_CTL_ATTR(UNIVERSAL, 1)
245}; 246};
246 247
247#define HPI_POLARITY_POSITIVE 0 248#define HPI_POLARITY_POSITIVE 0
@@ -393,14 +394,10 @@ enum HPI_FUNCTION_IDS {
393 HPI_SUBSYS_OPEN = HPI_FUNC_ID(SUBSYSTEM, 1), 394 HPI_SUBSYS_OPEN = HPI_FUNC_ID(SUBSYSTEM, 1),
394 HPI_SUBSYS_GET_VERSION = HPI_FUNC_ID(SUBSYSTEM, 2), 395 HPI_SUBSYS_GET_VERSION = HPI_FUNC_ID(SUBSYSTEM, 2),
395 HPI_SUBSYS_GET_INFO = HPI_FUNC_ID(SUBSYSTEM, 3), 396 HPI_SUBSYS_GET_INFO = HPI_FUNC_ID(SUBSYSTEM, 3),
396 /* HPI_SUBSYS_FIND_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 4), */
397 HPI_SUBSYS_CREATE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 5), 397 HPI_SUBSYS_CREATE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 5),
398 HPI_SUBSYS_CLOSE = HPI_FUNC_ID(SUBSYSTEM, 6), 398 HPI_SUBSYS_CLOSE = HPI_FUNC_ID(SUBSYSTEM, 6),
399 /* HPI_SUBSYS_DELETE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 7), */
400 HPI_SUBSYS_DRIVER_LOAD = HPI_FUNC_ID(SUBSYSTEM, 8), 399 HPI_SUBSYS_DRIVER_LOAD = HPI_FUNC_ID(SUBSYSTEM, 8),
401 HPI_SUBSYS_DRIVER_UNLOAD = HPI_FUNC_ID(SUBSYSTEM, 9), 400 HPI_SUBSYS_DRIVER_UNLOAD = HPI_FUNC_ID(SUBSYSTEM, 9),
402 /* HPI_SUBSYS_READ_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 10), */
403 /* HPI_SUBSYS_WRITE_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 11), */
404 HPI_SUBSYS_GET_NUM_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 12), 401 HPI_SUBSYS_GET_NUM_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 12),
405 HPI_SUBSYS_GET_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 13), 402 HPI_SUBSYS_GET_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 13),
406 HPI_SUBSYS_SET_NETWORK_INTERFACE = HPI_FUNC_ID(SUBSYSTEM, 14), 403 HPI_SUBSYS_SET_NETWORK_INTERFACE = HPI_FUNC_ID(SUBSYSTEM, 14),
@@ -430,7 +427,10 @@ enum HPI_FUNCTION_IDS {
430 HPI_ADAPTER_IRQ_QUERY_AND_CLEAR = HPI_FUNC_ID(ADAPTER, 19), 427 HPI_ADAPTER_IRQ_QUERY_AND_CLEAR = HPI_FUNC_ID(ADAPTER, 19),
431 HPI_ADAPTER_IRQ_CALLBACK = HPI_FUNC_ID(ADAPTER, 20), 428 HPI_ADAPTER_IRQ_CALLBACK = HPI_FUNC_ID(ADAPTER, 20),
432 HPI_ADAPTER_DELETE = HPI_FUNC_ID(ADAPTER, 21), 429 HPI_ADAPTER_DELETE = HPI_FUNC_ID(ADAPTER, 21),
433#define HPI_ADAPTER_FUNCTION_COUNT 21 430 HPI_ADAPTER_READ_FLASH = HPI_FUNC_ID(ADAPTER, 22),
431 HPI_ADAPTER_END_FLASH = HPI_FUNC_ID(ADAPTER, 23),
432 HPI_ADAPTER_FILESTORE_DELETE_ALL = HPI_FUNC_ID(ADAPTER, 24),
433#define HPI_ADAPTER_FUNCTION_COUNT 24
434 434
435 HPI_OSTREAM_OPEN = HPI_FUNC_ID(OSTREAM, 1), 435 HPI_OSTREAM_OPEN = HPI_FUNC_ID(OSTREAM, 1),
436 HPI_OSTREAM_CLOSE = HPI_FUNC_ID(OSTREAM, 2), 436 HPI_OSTREAM_CLOSE = HPI_FUNC_ID(OSTREAM, 2),
@@ -495,7 +495,9 @@ enum HPI_FUNCTION_IDS {
495 HPI_MIXER_GET_CONTROL_MULTIPLE_VALUES = HPI_FUNC_ID(MIXER, 10), 495 HPI_MIXER_GET_CONTROL_MULTIPLE_VALUES = HPI_FUNC_ID(MIXER, 10),
496 HPI_MIXER_STORE = HPI_FUNC_ID(MIXER, 11), 496 HPI_MIXER_STORE = HPI_FUNC_ID(MIXER, 11),
497 HPI_MIXER_GET_CACHE_INFO = HPI_FUNC_ID(MIXER, 12), 497 HPI_MIXER_GET_CACHE_INFO = HPI_FUNC_ID(MIXER, 12),
498#define HPI_MIXER_FUNCTION_COUNT 12 498 HPI_MIXER_GET_BLOCK_HANDLE = HPI_FUNC_ID(MIXER, 13),
499 HPI_MIXER_GET_PARAMETER_HANDLE = HPI_FUNC_ID(MIXER, 14),
500#define HPI_MIXER_FUNCTION_COUNT 14
499 501
500 HPI_CONTROL_GET_INFO = HPI_FUNC_ID(CONTROL, 1), 502 HPI_CONTROL_GET_INFO = HPI_FUNC_ID(CONTROL, 1),
501 HPI_CONTROL_GET_STATE = HPI_FUNC_ID(CONTROL, 2), 503 HPI_CONTROL_GET_STATE = HPI_FUNC_ID(CONTROL, 2),
@@ -618,7 +620,7 @@ struct hpi_hostbuffer_status {
618 u32 auxiliary_data_available; 620 u32 auxiliary_data_available;
619 u32 stream_state; 621 u32 stream_state;
620 /* DSP index in to the host bus master buffer. */ 622 /* DSP index in to the host bus master buffer. */
621 u32 dSP_index; 623 u32 dsp_index;
622 /* Host index in to the host bus master buffer. */ 624 /* Host index in to the host bus master buffer. */
623 u32 host_index; 625 u32 host_index;
624 u32 size_in_bytes; 626 u32 size_in_bytes;
@@ -661,13 +663,6 @@ union hpi_adapterx_msg {
661 u16 index; 663 u16 index;
662 } module_info; 664 } module_info;
663 struct { 665 struct {
664 u32 checksum;
665 u16 sequence;
666 u16 length;
667 u16 offset; /**< offset from start of msg to data */
668 u16 unused;
669 } program_flash;
670 struct {
671 u16 index; 666 u16 index;
672 u16 what; 667 u16 what;
673 u16 property_index; 668 u16 property_index;
@@ -678,25 +673,18 @@ union hpi_adapterx_msg {
678 u16 parameter2; 673 u16 parameter2;
679 } property_set; 674 } property_set;
680 struct { 675 struct {
681 u32 offset;
682 } query_flash;
683 struct {
684 u32 pad32; 676 u32 pad32;
685 u16 key1; 677 u16 key1;
686 u16 key2; 678 u16 key2;
687 } restart; 679 } restart;
688 struct { 680 struct {
689 u32 offset;
690 u32 length;
691 u32 key;
692 } start_flash;
693 struct {
694 u32 pad32; 681 u32 pad32;
695 u16 value; 682 u16 value;
696 } test_assert; 683 } test_assert;
697 struct { 684 struct {
698 u32 yes; 685 u32 yes;
699 } irq_query; 686 } irq_query;
687 u32 pad[3];
700}; 688};
701 689
702struct hpi_adapter_res { 690struct hpi_adapter_res {
@@ -724,18 +712,10 @@ union hpi_adapterx_res {
724 u32 adapter_mode; 712 u32 adapter_mode;
725 } mode; 713 } mode;
726 struct { 714 struct {
727 u16 sequence;
728 } program_flash;
729 struct {
730 u16 parameter1; 715 u16 parameter1;
731 u16 parameter2; 716 u16 parameter2;
732 } property_get; 717 } property_get;
733 struct { 718 struct {
734 u32 checksum;
735 u32 length;
736 u32 version;
737 } query_flash;
738 struct {
739 u32 yes; 719 u32 yes;
740 } irq_query; 720 } irq_query;
741}; 721};
@@ -1150,74 +1130,9 @@ struct hpi_res_adapter_get_info {
1150 struct hpi_adapter_res p; 1130 struct hpi_adapter_res p;
1151}; 1131};
1152 1132
1153/* padding is so these are same size as v0 hpi_message */
1154struct hpi_msg_adapter_query_flash {
1155 struct hpi_message_header h;
1156 u32 offset;
1157 u8 pad_to_version0_size[sizeof(struct hpi_message) - /* V0 res */
1158 sizeof(struct hpi_message_header) - 1 * sizeof(u32)];
1159};
1160
1161/* padding is so these are same size as v0 hpi_response */
1162struct hpi_res_adapter_query_flash {
1163 struct hpi_response_header h;
1164 u32 checksum;
1165 u32 length;
1166 u32 version;
1167 u8 pad_to_version0_size[sizeof(struct hpi_response) - /* V0 res */
1168 sizeof(struct hpi_response_header) - 3 * sizeof(u32)];
1169};
1170
1171struct hpi_msg_adapter_start_flash {
1172 struct hpi_message_header h;
1173 u32 offset;
1174 u32 length;
1175 u32 key;
1176 u8 pad_to_version0_size[sizeof(struct hpi_message) - /* V0 res */
1177 sizeof(struct hpi_message_header) - 3 * sizeof(u32)];
1178};
1179
1180struct hpi_res_adapter_start_flash {
1181 struct hpi_response_header h;
1182 u8 pad_to_version0_size[sizeof(struct hpi_response) - /* V0 res */
1183 sizeof(struct hpi_response_header)];
1184};
1185
1186struct hpi_msg_adapter_program_flash_payload {
1187 u32 checksum;
1188 u16 sequence;
1189 u16 length;
1190 u16 offset; /**< offset from start of msg to data */
1191 u16 unused;
1192 /* ensure sizeof(header + payload) == sizeof(hpi_message_V0)
1193 because old firmware expects data after message of this size */
1194 u8 pad_to_version0_size[sizeof(struct hpi_message) - /* V0 message */
1195 sizeof(struct hpi_message_header) - sizeof(u32) -
1196 4 * sizeof(u16)];
1197};
1198
1199struct hpi_msg_adapter_program_flash {
1200 struct hpi_message_header h;
1201 struct hpi_msg_adapter_program_flash_payload p;
1202 u32 data[256];
1203};
1204
1205struct hpi_res_adapter_program_flash {
1206 struct hpi_response_header h;
1207 u16 sequence;
1208 u8 pad_to_version0_size[sizeof(struct hpi_response) - /* V0 res */
1209 sizeof(struct hpi_response_header) - sizeof(u16)];
1210};
1211
1212struct hpi_msg_adapter_debug_read {
1213 struct hpi_message_header h;
1214 u32 dsp_address;
1215 u32 count_bytes;
1216};
1217
1218struct hpi_res_adapter_debug_read { 1133struct hpi_res_adapter_debug_read {
1219 struct hpi_response_header h; 1134 struct hpi_response_header h;
1220 u8 bytes[256]; 1135 u8 bytes[1024];
1221}; 1136};
1222 1137
1223struct hpi_msg_cobranet_hmi { 1138struct hpi_msg_cobranet_hmi {
@@ -1461,7 +1376,7 @@ struct hpi_control_cache_pad {
1461/* 2^N sized FIFO buffer (internal to HPI<->DSP interaction) */ 1376/* 2^N sized FIFO buffer (internal to HPI<->DSP interaction) */
1462struct hpi_fifo_buffer { 1377struct hpi_fifo_buffer {
1463 u32 size; 1378 u32 size;
1464 u32 dSP_index; 1379 u32 dsp_index;
1465 u32 host_index; 1380 u32 host_index;
1466}; 1381};
1467 1382
diff --git a/sound/pci/asihpi/hpi_version.h b/sound/pci/asihpi/hpi_version.h
new file mode 100644
index 00000000000..e9146e53bd5
--- /dev/null
+++ b/sound/pci/asihpi/hpi_version.h
@@ -0,0 +1,32 @@
1/** HPI Version Definitions
2Development releases have odd minor version.
3Production releases have even minor version.
4
5\file hpi_version.h
6*/
7
8#ifndef _HPI_VERSION_H
9#define _HPI_VERSION_H
10
11/* Use single digits for versions less that 10 to avoid octal. */
12/* *** HPI_VER is the only edit required to update version *** */
13/** HPI version */
14#define HPI_VER HPI_VERSION_CONSTRUCTOR(4, 10, 1)
15
16/** HPI version string in dotted decimal format */
17#define HPI_VER_STRING "4.10.01"
18
19/** Library version as documented in hpi-api-versions.txt */
20#define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(10, 2, 0)
21
22/** Construct hpi version number from major, minor, release numbers */
23#define HPI_VERSION_CONSTRUCTOR(maj, min, r) ((maj << 16) + (min << 8) + r)
24
25/** Extract major version from hpi version number */
26#define HPI_VER_MAJOR(v) ((int)(v >> 16))
27/** Extract minor version from hpi version number */
28#define HPI_VER_MINOR(v) ((int)((v >> 8) & 0xFF))
29/** Extract release from hpi version number */
30#define HPI_VER_RELEASE(v) ((int)(v & 0xFF))
31
32#endif
diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c
index bd47521b24e..7ed5c26c373 100644
--- a/sound/pci/asihpi/hpicmn.c
+++ b/sound/pci/asihpi/hpicmn.c
@@ -1,7 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 AudioScience HPI driver 3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> 4 Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as 7 it under the terms of version 2 of the GNU General Public License as
@@ -68,7 +68,7 @@ u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr)
68u16 hpi_add_adapter(struct hpi_adapter_obj *pao) 68u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
69{ 69{
70 u16 retval = 0; 70 u16 retval = 0;
71 /*HPI_ASSERT(pao->wAdapterType); */ 71 /*HPI_ASSERT(pao->type); */
72 72
73 hpios_alistlock_lock(&adapters); 73 hpios_alistlock_lock(&adapters);
74 74
@@ -77,13 +77,13 @@ u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
77 goto unlock; 77 goto unlock;
78 } 78 }
79 79
80 if (adapters.adapter[pao->index].adapter_type) { 80 if (adapters.adapter[pao->index].type) {
81 int a; 81 int a;
82 for (a = HPI_MAX_ADAPTERS - 1; a >= 0; a--) { 82 for (a = HPI_MAX_ADAPTERS - 1; a >= 0; a--) {
83 if (!adapters.adapter[a].adapter_type) { 83 if (!adapters.adapter[a].type) {
84 HPI_DEBUG_LOG(WARNING, 84 HPI_DEBUG_LOG(WARNING,
85 "ASI%X duplicate index %d moved to %d\n", 85 "ASI%X duplicate index %d moved to %d\n",
86 pao->adapter_type, pao->index, a); 86 pao->type, pao->index, a);
87 pao->index = a; 87 pao->index = a;
88 break; 88 break;
89 } 89 }
@@ -104,13 +104,13 @@ unlock:
104 104
105void hpi_delete_adapter(struct hpi_adapter_obj *pao) 105void hpi_delete_adapter(struct hpi_adapter_obj *pao)
106{ 106{
107 if (!pao->adapter_type) { 107 if (!pao->type) {
108 HPI_DEBUG_LOG(ERROR, "removing null adapter?\n"); 108 HPI_DEBUG_LOG(ERROR, "removing null adapter?\n");
109 return; 109 return;
110 } 110 }
111 111
112 hpios_alistlock_lock(&adapters); 112 hpios_alistlock_lock(&adapters);
113 if (adapters.adapter[pao->index].adapter_type) 113 if (adapters.adapter[pao->index].type)
114 adapters.gw_num_adapters--; 114 adapters.gw_num_adapters--;
115 memset(&adapters.adapter[pao->index], 0, sizeof(adapters.adapter[0])); 115 memset(&adapters.adapter[pao->index], 0, sizeof(adapters.adapter[0]));
116 hpios_alistlock_unlock(&adapters); 116 hpios_alistlock_unlock(&adapters);
@@ -132,7 +132,7 @@ struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index)
132 } 132 }
133 133
134 pao = &adapters.adapter[adapter_index]; 134 pao = &adapters.adapter[adapter_index];
135 if (pao->adapter_type != 0) { 135 if (pao->type != 0) {
136 /* 136 /*
137 HPI_DEBUG_LOG(VERBOSE, "Found adapter index %d\n", 137 HPI_DEBUG_LOG(VERBOSE, "Found adapter index %d\n",
138 wAdapterIndex); 138 wAdapterIndex);
@@ -165,7 +165,7 @@ static void subsys_get_adapter(struct hpi_message *phm,
165 165
166 /* find the nCount'th nonzero adapter in array */ 166 /* find the nCount'th nonzero adapter in array */
167 for (index = 0; index < HPI_MAX_ADAPTERS; index++) { 167 for (index = 0; index < HPI_MAX_ADAPTERS; index++) {
168 if (adapters.adapter[index].adapter_type) { 168 if (adapters.adapter[index].type) {
169 if (!count) 169 if (!count)
170 break; 170 break;
171 count--; 171 count--;
@@ -174,11 +174,11 @@ static void subsys_get_adapter(struct hpi_message *phm,
174 174
175 if (index < HPI_MAX_ADAPTERS) { 175 if (index < HPI_MAX_ADAPTERS) {
176 phr->u.s.adapter_index = adapters.adapter[index].index; 176 phr->u.s.adapter_index = adapters.adapter[index].index;
177 phr->u.s.adapter_type = adapters.adapter[index].adapter_type; 177 phr->u.s.adapter_type = adapters.adapter[index].type;
178 } else { 178 } else {
179 phr->u.s.adapter_index = 0; 179 phr->u.s.adapter_index = 0;
180 phr->u.s.adapter_type = 0; 180 phr->u.s.adapter_type = 0;
181 phr->error = HPI_ERROR_BAD_ADAPTER_NUMBER; 181 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
182 } 182 }
183} 183}
184 184
@@ -324,6 +324,8 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
324 } 324 }
325 325
326 phr->error = 0; 326 phr->error = 0;
327 phr->specific_error = 0;
328 phr->version = 0;
327 329
328 /* set the default response size */ 330 /* set the default response size */
329 response_size = 331 response_size =
@@ -531,8 +533,12 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
531 found ? "Cached" : "Uncached", phm->adapter_index, 533 found ? "Cached" : "Uncached", phm->adapter_index,
532 pI->control_index, pI->control_type, phm->u.c.attribute); 534 pI->control_index, pI->control_type, phm->u.c.attribute);
533 535
534 if (found) 536 if (found) {
535 phr->size = (u16)response_size; 537 phr->size = (u16)response_size;
538 phr->type = HPI_TYPE_RESPONSE;
539 phr->object = phm->object;
540 phr->function = phm->function;
541 }
536 542
537 return found; 543 return found;
538} 544}
@@ -631,7 +637,7 @@ struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count,
631 if (!p_cache) 637 if (!p_cache)
632 return NULL; 638 return NULL;
633 639
634 p_cache->p_info = kzalloc(sizeof(*p_cache->p_info) * control_count, 640 p_cache->p_info = kcalloc(control_count, sizeof(*p_cache->p_info),
635 GFP_KERNEL); 641 GFP_KERNEL);
636 if (!p_cache->p_info) { 642 if (!p_cache->p_info) {
637 kfree(p_cache); 643 kfree(p_cache);
diff --git a/sound/pci/asihpi/hpicmn.h b/sound/pci/asihpi/hpicmn.h
index d53cdf6e535..e4412128304 100644
--- a/sound/pci/asihpi/hpicmn.h
+++ b/sound/pci/asihpi/hpicmn.h
@@ -1,7 +1,7 @@
1/** 1/**
2 2
3 AudioScience HPI driver 3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> 4 Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as 7 it under the terms of version 2 of the GNU General Public License as
@@ -18,12 +18,15 @@
18 18
19*/ 19*/
20 20
21struct hpi_adapter_obj;
22
23/* a function that takes an adapter obj and returns an int */
24typedef int adapter_int_func(struct hpi_adapter_obj *pao);
25
21struct hpi_adapter_obj { 26struct hpi_adapter_obj {
22 struct hpi_pci pci; /* PCI info - bus#,dev#,address etc */ 27 struct hpi_pci pci; /* PCI info - bus#,dev#,address etc */
23 u16 adapter_type; /* ASI6701 etc */ 28 u16 type; /* 0x6644 == ASI6644 etc */
24 u16 index; /* */ 29 u16 index;
25 u16 open; /* =1 when adapter open */
26 u16 mixer_open;
27 30
28 struct hpios_spinlock dsp_lock; 31 struct hpios_spinlock dsp_lock;
29 32
diff --git a/sound/pci/asihpi/hpidebug.c b/sound/pci/asihpi/hpidebug.c
index b52baf62791..ac86a1f1d3b 100644
--- a/sound/pci/asihpi/hpidebug.c
+++ b/sound/pci/asihpi/hpidebug.c
@@ -1,7 +1,7 @@
1/************************************************************************ 1/************************************************************************
2 2
3 AudioScience HPI driver 3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> 4 Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as 7 it under the terms of version 2 of the GNU General Public License as
diff --git a/sound/pci/asihpi/hpidebug.h b/sound/pci/asihpi/hpidebug.h
index 940f54c3c53..2c9af2329d3 100644
--- a/sound/pci/asihpi/hpidebug.h
+++ b/sound/pci/asihpi/hpidebug.h
@@ -1,7 +1,7 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 AudioScience HPI driver 3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> 4 Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as 7 it under the terms of version 2 of the GNU General Public License as
diff --git a/sound/pci/asihpi/hpidspcd.c b/sound/pci/asihpi/hpidspcd.c
index 71d32c868c9..456a758f04f 100644
--- a/sound/pci/asihpi/hpidspcd.c
+++ b/sound/pci/asihpi/hpidspcd.c
@@ -25,6 +25,7 @@ hotplug firmware loader from individual dsp code files
25#define SOURCEFILE_NAME "hpidspcd.c" 25#define SOURCEFILE_NAME "hpidspcd.c"
26#include "hpidspcd.h" 26#include "hpidspcd.h"
27#include "hpidebug.h" 27#include "hpidebug.h"
28#include "hpi_version.h"
28 29
29struct dsp_code_private { 30struct dsp_code_private {
30 /** Firmware descriptor */ 31 /** Firmware descriptor */
@@ -32,9 +33,6 @@ struct dsp_code_private {
32 struct pci_dev *dev; 33 struct pci_dev *dev;
33}; 34};
34 35
35#define HPI_VER_DECIMAL ((int)(HPI_VER_MAJOR(HPI_VER) * 10000 + \
36 HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER)))
37
38/*-------------------------------------------------------------------*/ 36/*-------------------------------------------------------------------*/
39short hpi_dsp_code_open(u32 adapter, void *os_data, struct dsp_code *dsp_code, 37short hpi_dsp_code_open(u32 adapter, void *os_data, struct dsp_code *dsp_code,
40 u32 *os_error_code) 38 u32 *os_error_code)
@@ -66,22 +64,25 @@ short hpi_dsp_code_open(u32 adapter, void *os_data, struct dsp_code *dsp_code,
66 if ((header.type != 0x45444F43) || /* "CODE" */ 64 if ((header.type != 0x45444F43) || /* "CODE" */
67 (header.adapter != adapter) 65 (header.adapter != adapter)
68 || (header.size != firmware->size)) { 66 || (header.size != firmware->size)) {
69 dev_printk(KERN_ERR, &dev->dev, "Invalid firmware file\n"); 67 dev_printk(KERN_ERR, &dev->dev,
68 "Invalid firmware header size %d != file %zd\n",
69 header.size, firmware->size);
70 goto error2; 70 goto error2;
71 } 71 }
72 72
73 if ((header.version / 100 & ~1) != (HPI_VER_DECIMAL / 100 & ~1)) { 73 if ((header.version >> 9) != (HPI_VER >> 9)) {
74 /* Consider even and subsequent odd minor versions to be compatible */
74 dev_printk(KERN_ERR, &dev->dev, 75 dev_printk(KERN_ERR, &dev->dev,
75 "Incompatible firmware version " 76 "Incompatible firmware version "
76 "DSP image %d != Driver %d\n", header.version, 77 "DSP image %X != Driver %X\n", header.version,
77 HPI_VER_DECIMAL); 78 HPI_VER);
78 goto error2; 79 goto error2;
79 } 80 }
80 81
81 if (header.version != HPI_VER_DECIMAL) { 82 if (header.version != HPI_VER) {
82 dev_printk(KERN_WARNING, &dev->dev, 83 dev_printk(KERN_INFO, &dev->dev,
83 "Firmware: release version mismatch DSP image %d != Driver %d\n", 84 "Firmware: release version mismatch DSP image %X != Driver %X\n",
84 header.version, HPI_VER_DECIMAL); 85 header.version, HPI_VER);
85 } 86 }
86 87
87 HPI_DEBUG_LOG(DEBUG, "dsp code %s opened\n", fw_name); 88 HPI_DEBUG_LOG(DEBUG, "dsp code %s opened\n", fw_name);
@@ -108,11 +109,8 @@ error1:
108/*-------------------------------------------------------------------*/ 109/*-------------------------------------------------------------------*/
109void hpi_dsp_code_close(struct dsp_code *dsp_code) 110void hpi_dsp_code_close(struct dsp_code *dsp_code)
110{ 111{
111 if (dsp_code->pvt->firmware) { 112 HPI_DEBUG_LOG(DEBUG, "dsp code closed\n");
112 HPI_DEBUG_LOG(DEBUG, "dsp code closed\n"); 113 release_firmware(dsp_code->pvt->firmware);
113 release_firmware(dsp_code->pvt->firmware);
114 dsp_code->pvt->firmware = NULL;
115 }
116 kfree(dsp_code->pvt); 114 kfree(dsp_code->pvt);
117} 115}
118 116
diff --git a/sound/pci/asihpi/hpidspcd.h b/sound/pci/asihpi/hpidspcd.h
index b22881122f1..659d19ca6d4 100644
--- a/sound/pci/asihpi/hpidspcd.h
+++ b/sound/pci/asihpi/hpidspcd.h
@@ -27,10 +27,6 @@ Functions for reading DSP code to load into DSP
27 27
28#include "hpi_internal.h" 28#include "hpi_internal.h"
29 29
30/** Code header version is decimal encoded e.g. 4.06.10 is 40601 */
31#define HPI_VER_DECIMAL ((int)(HPI_VER_MAJOR(HPI_VER) * 10000 + \
32HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER)))
33
34/** Header structure for dsp firmware file 30/** Header structure for dsp firmware file
35 This structure must match that used in s2bin.c for generation of asidsp.bin 31 This structure must match that used in s2bin.c for generation of asidsp.bin
36 */ 32 */
diff --git a/sound/pci/asihpi/hpifunc.c b/sound/pci/asihpi/hpifunc.c
index ebb568d695f..510e56cffd3 100644
--- a/sound/pci/asihpi/hpifunc.c
+++ b/sound/pci/asihpi/hpifunc.c
@@ -2826,6 +2826,16 @@ u16 hpi_volume_auto_fade(u32 h_control,
2826 duration_ms, HPI_VOLUME_AUTOFADE_LOG); 2826 duration_ms, HPI_VOLUME_AUTOFADE_LOG);
2827} 2827}
2828 2828
2829u16 hpi_volume_query_auto_fade_profile(const u32 h_volume, const u32 i,
2830 u16 *profile)
2831{
2832 u16 e;
2833 u32 u;
2834 e = hpi_control_query(h_volume, HPI_VOLUME_AUTOFADE, i, 0, &u);
2835 *profile = (u16)u;
2836 return e;
2837}
2838
2829u16 hpi_vox_set_threshold(u32 h_control, short an_gain0_01dB) 2839u16 hpi_vox_set_threshold(u32 h_control, short an_gain0_01dB)
2830{ 2840{
2831 struct hpi_message hm; 2841 struct hpi_message hm;
diff --git a/sound/pci/asihpi/hpimsginit.c b/sound/pci/asihpi/hpimsginit.c
index 52400a6b5f1..032d563e370 100644
--- a/sound/pci/asihpi/hpimsginit.c
+++ b/sound/pci/asihpi/hpimsginit.c
@@ -1,7 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 AudioScience HPI driver 3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> 4 Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as 7 it under the terms of version 2 of the GNU General Public License as
diff --git a/sound/pci/asihpi/hpimsginit.h b/sound/pci/asihpi/hpimsginit.h
index bfd330d78b5..5b48708c7d1 100644
--- a/sound/pci/asihpi/hpimsginit.h
+++ b/sound/pci/asihpi/hpimsginit.h
@@ -1,7 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 AudioScience HPI driver 3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> 4 Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as 7 it under the terms of version 2 of the GNU General Public License as
diff --git a/sound/pci/asihpi/hpimsgx.c b/sound/pci/asihpi/hpimsgx.c
index 2e779421a61..d4790ddc225 100644
--- a/sound/pci/asihpi/hpimsgx.c
+++ b/sound/pci/asihpi/hpimsgx.c
@@ -1,7 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 AudioScience HPI driver 3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> 4 Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as 7 it under the terms of version 2 of the GNU General Public License as
@@ -22,6 +22,7 @@ Extended Message Function With Response Caching
22*****************************************************************************/ 22*****************************************************************************/
23#define SOURCEFILE_NAME "hpimsgx.c" 23#define SOURCEFILE_NAME "hpimsgx.c"
24#include "hpi_internal.h" 24#include "hpi_internal.h"
25#include "hpi_version.h"
25#include "hpimsginit.h" 26#include "hpimsginit.h"
26#include "hpicmn.h" 27#include "hpicmn.h"
27#include "hpimsgx.h" 28#include "hpimsgx.h"
diff --git a/sound/pci/asihpi/hpimsgx.h b/sound/pci/asihpi/hpimsgx.h
index fd49e7542a8..37f3efd95a7 100644
--- a/sound/pci/asihpi/hpimsgx.h
+++ b/sound/pci/asihpi/hpimsgx.h
@@ -1,7 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 AudioScience HPI driver 3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> 4 Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as 7 it under the terms of version 2 of the GNU General Public License as
diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c
index f6b9517b469..60915620556 100644
--- a/sound/pci/asihpi/hpioctl.c
+++ b/sound/pci/asihpi/hpioctl.c
@@ -21,6 +21,7 @@ Common Linux HPI ioctl and module probe/remove functions
21#define SOURCEFILE_NAME "hpioctl.c" 21#define SOURCEFILE_NAME "hpioctl.c"
22 22
23#include "hpi_internal.h" 23#include "hpi_internal.h"
24#include "hpi_version.h"
24#include "hpimsginit.h" 25#include "hpimsginit.h"
25#include "hpidebug.h" 26#include "hpidebug.h"
26#include "hpimsgx.h" 27#include "hpimsgx.h"
@@ -65,9 +66,7 @@ static struct hpi_adapter adapters[HPI_MAX_ADAPTERS];
65static void hpi_send_recv_f(struct hpi_message *phm, struct hpi_response *phr, 66static void hpi_send_recv_f(struct hpi_message *phm, struct hpi_response *phr,
66 struct file *file) 67 struct file *file)
67{ 68{
68 int adapter = phm->adapter_index; 69 if ((phm->adapter_index >= HPI_MAX_ADAPTERS)
69
70 if ((adapter >= HPI_MAX_ADAPTERS || adapter < 0)
71 && (phm->object != HPI_OBJ_SUBSYSTEM)) 70 && (phm->object != HPI_OBJ_SUBSYSTEM))
72 phr->error = HPI_ERROR_INVALID_OBJ_INDEX; 71 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
73 else 72 else
@@ -178,19 +177,14 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
178 } else { 177 } else {
179 u16 __user *ptr = NULL; 178 u16 __user *ptr = NULL;
180 u32 size = 0; 179 u32 size = 0;
181 u32 adapter_present;
182 /* -1=no data 0=read from user mem, 1=write to user mem */ 180 /* -1=no data 0=read from user mem, 1=write to user mem */
183 int wrflag = -1; 181 int wrflag = -1;
184 struct hpi_adapter *pa; 182 struct hpi_adapter *pa = NULL;
185 183
186 if (hm->h.adapter_index < HPI_MAX_ADAPTERS) { 184 if (hm->h.adapter_index < ARRAY_SIZE(adapters))
187 pa = &adapters[hm->h.adapter_index]; 185 pa = &adapters[hm->h.adapter_index];
188 adapter_present = pa->type;
189 } else {
190 adapter_present = 0;
191 }
192 186
193 if (!adapter_present) { 187 if (!pa || !pa->adapter || !pa->adapter->type) {
194 hpi_init_response(&hr->r0, hm->h.object, 188 hpi_init_response(&hr->r0, hm->h.object,
195 hm->h.function, HPI_ERROR_BAD_ADAPTER_NUMBER); 189 hm->h.function, HPI_ERROR_BAD_ADAPTER_NUMBER);
196 190
@@ -317,6 +311,7 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
317 const struct pci_device_id *pci_id) 311 const struct pci_device_id *pci_id)
318{ 312{
319 int idx, nm; 313 int idx, nm;
314 int adapter_index;
320 unsigned int memlen; 315 unsigned int memlen;
321 struct hpi_message hm; 316 struct hpi_message hm;
322 struct hpi_response hr; 317 struct hpi_response hr;
@@ -345,8 +340,6 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
345 340
346 hm.adapter_index = HPI_ADAPTER_INDEX_INVALID; 341 hm.adapter_index = HPI_ADAPTER_INDEX_INVALID;
347 342
348 adapter.pci = pci_dev;
349
350 nm = HPI_MAX_ADAPTER_MEM_SPACES; 343 nm = HPI_MAX_ADAPTER_MEM_SPACES;
351 344
352 for (idx = 0; idx < nm; idx++) { 345 for (idx = 0; idx < nm; idx++) {
@@ -355,18 +348,16 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
355 348
356 if (pci_resource_flags(pci_dev, idx) & IORESOURCE_MEM) { 349 if (pci_resource_flags(pci_dev, idx) & IORESOURCE_MEM) {
357 memlen = pci_resource_len(pci_dev, idx); 350 memlen = pci_resource_len(pci_dev, idx);
358 adapter.ap_remapped_mem_base[idx] = 351 pci.ap_mem_base[idx] =
359 ioremap(pci_resource_start(pci_dev, idx), 352 ioremap(pci_resource_start(pci_dev, idx),
360 memlen); 353 memlen);
361 if (!adapter.ap_remapped_mem_base[idx]) { 354 if (!pci.ap_mem_base[idx]) {
362 HPI_DEBUG_LOG(ERROR, 355 HPI_DEBUG_LOG(ERROR,
363 "ioremap failed, aborting\n"); 356 "ioremap failed, aborting\n");
364 /* unmap previously mapped pci mem space */ 357 /* unmap previously mapped pci mem space */
365 goto err; 358 goto err;
366 } 359 }
367 } 360 }
368
369 pci.ap_mem_base[idx] = adapter.ap_remapped_mem_base[idx];
370 } 361 }
371 362
372 pci.pci_dev = pci_dev; 363 pci.pci_dev = pci_dev;
@@ -378,6 +369,9 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
378 if (hr.error) 369 if (hr.error)
379 goto err; 370 goto err;
380 371
372 adapter_index = hr.u.s.adapter_index;
373 adapter.adapter = hpi_find_adapter(adapter_index);
374
381 if (prealloc_stream_buf) { 375 if (prealloc_stream_buf) {
382 adapter.p_buffer = vmalloc(prealloc_stream_buf); 376 adapter.p_buffer = vmalloc(prealloc_stream_buf);
383 if (!adapter.p_buffer) { 377 if (!adapter.p_buffer) {
@@ -389,36 +383,32 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
389 } 383 }
390 } 384 }
391 385
392 adapter.index = hr.u.s.adapter_index;
393 adapter.type = hr.u.s.adapter_type;
394
395 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, 386 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
396 HPI_ADAPTER_OPEN); 387 HPI_ADAPTER_OPEN);
397 hm.adapter_index = adapter.index; 388 hm.adapter_index = adapter.adapter->index;
398 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); 389 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
399 390
400 if (hr.error) 391 if (hr.error)
401 goto err; 392 goto err;
402 393
403 adapter.snd_card_asihpi = NULL;
404 /* WARNING can't init mutex in 'adapter' 394 /* WARNING can't init mutex in 'adapter'
405 * and then copy it to adapters[] ?!?! 395 * and then copy it to adapters[] ?!?!
406 */ 396 */
407 adapters[adapter.index] = adapter; 397 adapters[adapter_index] = adapter;
408 mutex_init(&adapters[adapter.index].mutex); 398 mutex_init(&adapters[adapter_index].mutex);
409 pci_set_drvdata(pci_dev, &adapters[adapter.index]); 399 pci_set_drvdata(pci_dev, &adapters[adapter_index]);
410 400
411 dev_printk(KERN_INFO, &pci_dev->dev, 401 dev_printk(KERN_INFO, &pci_dev->dev,
412 "probe succeeded for ASI%04X HPI index %d\n", adapter.type, 402 "probe succeeded for ASI%04X HPI index %d\n",
413 adapter.index); 403 adapter.adapter->type, adapter_index);
414 404
415 return 0; 405 return 0;
416 406
417err: 407err:
418 for (idx = 0; idx < HPI_MAX_ADAPTER_MEM_SPACES; idx++) { 408 for (idx = 0; idx < HPI_MAX_ADAPTER_MEM_SPACES; idx++) {
419 if (adapter.ap_remapped_mem_base[idx]) { 409 if (pci.ap_mem_base[idx]) {
420 iounmap(adapter.ap_remapped_mem_base[idx]); 410 iounmap(pci.ap_mem_base[idx]);
421 adapter.ap_remapped_mem_base[idx] = NULL; 411 pci.ap_mem_base[idx] = NULL;
422 } 412 }
423 } 413 }
424 414
@@ -437,19 +427,20 @@ void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev)
437 struct hpi_message hm; 427 struct hpi_message hm;
438 struct hpi_response hr; 428 struct hpi_response hr;
439 struct hpi_adapter *pa; 429 struct hpi_adapter *pa;
430 struct hpi_pci pci;
431
440 pa = pci_get_drvdata(pci_dev); 432 pa = pci_get_drvdata(pci_dev);
433 pci = pa->adapter->pci;
441 434
442 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, 435 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
443 HPI_ADAPTER_DELETE); 436 HPI_ADAPTER_DELETE);
444 hm.adapter_index = pa->index; 437 hm.adapter_index = pa->adapter->index;
445 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); 438 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
446 439
447 /* unmap PCI memory space, mapped during device init. */ 440 /* unmap PCI memory space, mapped during device init. */
448 for (idx = 0; idx < HPI_MAX_ADAPTER_MEM_SPACES; idx++) { 441 for (idx = 0; idx < HPI_MAX_ADAPTER_MEM_SPACES; idx++) {
449 if (pa->ap_remapped_mem_base[idx]) { 442 if (pci.ap_mem_base[idx])
450 iounmap(pa->ap_remapped_mem_base[idx]); 443 iounmap(pci.ap_mem_base[idx]);
451 pa->ap_remapped_mem_base[idx] = NULL;
452 }
453 } 444 }
454 445
455 if (pa->p_buffer) 446 if (pa->p_buffer)
@@ -461,7 +452,7 @@ void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev)
461 "remove %04x:%04x,%04x:%04x,%04x," " HPI index %d.\n", 452 "remove %04x:%04x,%04x:%04x,%04x," " HPI index %d.\n",
462 pci_dev->vendor, pci_dev->device, 453 pci_dev->vendor, pci_dev->device,
463 pci_dev->subsystem_vendor, pci_dev->subsystem_device, 454 pci_dev->subsystem_vendor, pci_dev->subsystem_device,
464 pci_dev->devfn, pa->index); 455 pci_dev->devfn, pa->adapter->index);
465 456
466 memset(pa, 0, sizeof(*pa)); 457 memset(pa, 0, sizeof(*pa));
467} 458}
diff --git a/sound/pci/asihpi/hpioctl.h b/sound/pci/asihpi/hpioctl.h
index 847f72f03fe..2614aff672e 100644
--- a/sound/pci/asihpi/hpioctl.h
+++ b/sound/pci/asihpi/hpioctl.h
@@ -1,7 +1,7 @@
1/******************************************************************************* 1/*******************************************************************************
2 2
3 AudioScience HPI driver 3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> 4 Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as 7 it under the terms of version 2 of the GNU General Public License as
diff --git a/sound/pci/asihpi/hpios.c b/sound/pci/asihpi/hpios.c
index ff2a19b544f..2d7d1c2e1d0 100644
--- a/sound/pci/asihpi/hpios.c
+++ b/sound/pci/asihpi/hpios.c
@@ -1,7 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 AudioScience HPI driver 3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> 4 Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as 7 it under the terms of version 2 of the GNU General Public License as
diff --git a/sound/pci/asihpi/hpios.h b/sound/pci/asihpi/hpios.h
index 2f605e34bad..c5cef113c20 100644
--- a/sound/pci/asihpi/hpios.h
+++ b/sound/pci/asihpi/hpios.h
@@ -1,7 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 AudioScience HPI driver 3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> 4 Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as 7 it under the terms of version 2 of the GNU General Public License as
@@ -149,20 +149,18 @@ static inline void cond_unlock(struct hpios_spinlock *l)
149#define hpios_alistlock_lock(obj) spin_lock(&((obj)->list_lock.lock)) 149#define hpios_alistlock_lock(obj) spin_lock(&((obj)->list_lock.lock))
150#define hpios_alistlock_unlock(obj) spin_unlock(&((obj)->list_lock.lock)) 150#define hpios_alistlock_unlock(obj) spin_unlock(&((obj)->list_lock.lock))
151 151
152struct snd_card;
153
154/** pci drvdata points to an instance of this struct */
152struct hpi_adapter { 155struct hpi_adapter {
156 struct hpi_adapter_obj *adapter;
157 struct snd_card *snd_card;
158
153 /* mutex prevents contention for one card 159 /* mutex prevents contention for one card
154 between multiple user programs (via ioctl) */ 160 between multiple user programs (via ioctl) */
155 struct mutex mutex; 161 struct mutex mutex;
156 u16 index;
157 u16 type;
158
159 /* ALSA card structure */
160 void *snd_card_asihpi;
161
162 char *p_buffer; 162 char *p_buffer;
163 size_t buffer_size; 163 size_t buffer_size;
164 struct pci_dev *pci;
165 void __iomem *ap_remapped_mem_base[HPI_MAX_ADAPTER_MEM_SPACES];
166}; 164};
167 165
168#endif 166#endif
diff --git a/sound/pci/asihpi/hpipcida.h b/sound/pci/asihpi/hpipcida.h
index bb30868ce1a..db570ddf64b 100644
--- a/sound/pci/asihpi/hpipcida.h
+++ b/sound/pci/asihpi/hpipcida.h
@@ -1,7 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 AudioScience HPI driver 3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> 4 Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as 7 it under the terms of version 2 of the GNU General Public License as