summaryrefslogtreecommitdiffstats
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 f4b9e2b7ae87..e8de831f98bc 100644
--- a/sound/pci/asihpi/asihpi.c
+++ b/sound/pci/asihpi/asihpi.c
@@ -23,8 +23,11 @@
*/
#include "hpi_internal.h"
+#include "hpi_version.h"
#include "hpimsginit.h"
#include "hpioctl.h"
+#include "hpicmn.h"
+
#include <linux/pci.h>
#include <linux/init.h>
@@ -44,7 +47,8 @@
MODULE_LICENSE("GPL");
MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>");
-MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx");
+MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx "
+ HPI_VER_STRING);
#if defined CONFIG_SND_DEBUG_VERBOSE
/**
@@ -63,8 +67,8 @@ MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx");
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-static int enable_hpi_hwdep = 1;
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
+static bool enable_hpi_hwdep = 1;
module_param_array(index, int, NULL, S_IRUGO);
MODULE_PARM_DESC(index, "ALSA index value for AudioScience soundcard.");
@@ -119,12 +123,7 @@ struct clk_cache {
struct snd_card_asihpi {
struct snd_card *card;
struct pci_dev *pci;
- u16 adapter_index;
- u32 serial_number;
- u16 type;
- u16 version;
- u16 num_outstreams;
- u16 num_instreams;
+ struct hpi_adapter *hpi;
u32 h_mixer;
struct clk_cache cc;
@@ -135,6 +134,8 @@ struct snd_card_asihpi {
u16 update_interval_frames;
u16 in_max_chans;
u16 out_max_chans;
+ u16 in_min_chans;
+ u16 out_min_chans;
};
/* Per stream data */
@@ -495,6 +496,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
snd_printdd("stream_host_buffer_attach status 0x%x\n",
dpcm->hpi_buffer_attached);
+
}
bytes_per_sec = params_rate(params) * params_channels(params);
width = snd_pcm_format_width(params_format(params));
@@ -757,8 +759,7 @@ static void snd_card_asihpi_timer_function(unsigned long data)
if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
pcm_buf_dma_ofs = ds->pcm_buf_host_rw_ofs - bytes_avail;
if (state == HPI_STATE_STOPPED) {
- if ((bytes_avail == 0) &&
- (on_card_bytes < ds->pcm_buf_host_rw_ofs)) {
+ if (bytes_avail == 0) {
hpi_handle_error(hpi_stream_start(ds->h_stream));
snd_printdd("P%d start\n", s->number);
ds->drained_count = 0;
@@ -767,7 +768,7 @@ static void snd_card_asihpi_timer_function(unsigned long data)
snd_printd(KERN_WARNING "P%d drained\n",
s->number);
ds->drained_count++;
- if (ds->drained_count > 2) {
+ if (ds->drained_count > 20) {
snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN);
continue;
}
@@ -888,8 +889,8 @@ static void snd_card_asihpi_timer_function(unsigned long data)
pd, xfer2));
}
}
- ds->pcm_buf_host_rw_ofs = ds->pcm_buf_host_rw_ofs + xfercount;
- ds->pcm_buf_elapsed_dma_ofs = pcm_buf_dma_ofs;
+ ds->pcm_buf_host_rw_ofs += xfercount;
+ ds->pcm_buf_elapsed_dma_ofs += xfercount;
snd_pcm_period_elapsed(s);
}
}
@@ -902,7 +903,9 @@ static void snd_card_asihpi_timer_function(unsigned long data)
static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream,
unsigned int cmd, void *arg)
{
- snd_printddd(KERN_INFO "P%d ioctl %d\n", substream->number, cmd);
+ char name[16];
+ snd_pcm_debug_name(substream, name, sizeof(name));
+ snd_printddd(KERN_INFO "%s ioctl %d\n", name, cmd);
return snd_pcm_lib_ioctl(substream, cmd, arg);
}
@@ -927,21 +930,23 @@ snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
snd_pcm_uframes_t ptr;
+ char name[16];
+ snd_pcm_debug_name(substream, name, sizeof(name));
ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes);
- snd_printddd("P%d pointer = 0x%04lx\n", substream->number, (unsigned long)ptr);
+ snd_printddd("%s pointer = 0x%04lx\n", name, (unsigned long)ptr);
return ptr;
}
-static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi,
- u32 h_stream,
- struct snd_pcm_hardware *pcmhw)
+static u64 snd_card_asihpi_playback_formats(struct snd_card_asihpi *asihpi,
+ u32 h_stream)
{
struct hpi_format hpi_format;
u16 format;
u16 err;
u32 h_control;
u32 sample_rate = 48000;
+ u64 formats = 0;
/* on cards without SRC, must query at valid rate,
* maybe set by external sync
@@ -956,41 +961,29 @@ static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi,
for (format = HPI_FORMAT_PCM8_UNSIGNED;
format <= HPI_FORMAT_PCM24_SIGNED; format++) {
- err = hpi_format_create(&hpi_format,
- 2, format, sample_rate, 128000, 0);
+ err = hpi_format_create(&hpi_format, asihpi->out_max_chans,
+ format, sample_rate, 128000, 0);
if (!err)
- err = hpi_outstream_query_format(h_stream,
- &hpi_format);
+ err = hpi_outstream_query_format(h_stream, &hpi_format);
if (!err && (hpi_to_alsa_formats[format] != -1))
- pcmhw->formats |=
- (1ULL << hpi_to_alsa_formats[format]);
+ formats |= (1ULL << hpi_to_alsa_formats[format]);
}
+ return formats;
}
-static struct snd_pcm_hardware snd_card_asihpi_playback = {
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = BUFFER_BYTES_MAX,
- .period_bytes_min = PERIOD_BYTES_MIN,
- .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
- .periods_min = PERIODS_MIN,
- .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
- .fifo_size = 0,
-};
-
static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_card_asihpi_pcm *dpcm;
struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
+ struct snd_pcm_hardware snd_card_asihpi_playback;
int err;
dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
if (dpcm == NULL)
return -ENOMEM;
- err =
- hpi_outstream_open(card->adapter_index,
+ err = hpi_outstream_open(card->hpi->adapter->index,
substream->number, &dpcm->h_stream);
hpi_handle_error(err);
if (err)
@@ -1012,12 +1005,19 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
runtime->private_data = dpcm;
runtime->private_free = snd_card_asihpi_runtime_free;
- snd_card_asihpi_playback.channels_max = card->out_max_chans;
+ memset(&snd_card_asihpi_playback, 0, sizeof(snd_card_asihpi_playback));
+ snd_card_asihpi_playback.buffer_bytes_max = BUFFER_BYTES_MAX;
+ snd_card_asihpi_playback.period_bytes_min = PERIOD_BYTES_MIN;
/*?snd_card_asihpi_playback.period_bytes_min =
card->out_max_chans * 4096; */
-
- snd_card_asihpi_playback_format(card, dpcm->h_stream,
- &snd_card_asihpi_playback);
+ snd_card_asihpi_playback.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN;
+ snd_card_asihpi_playback.periods_min = PERIODS_MIN;
+ snd_card_asihpi_playback.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN;
+ /* snd_card_asihpi_playback.fifo_size = 0; */
+ snd_card_asihpi_playback.channels_max = card->out_max_chans;
+ snd_card_asihpi_playback.channels_min = card->out_min_chans;
+ snd_card_asihpi_playback.formats =
+ snd_card_asihpi_playback_formats(card, dpcm->h_stream);
snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_playback);
@@ -1029,8 +1029,10 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID;
- if (card->support_grouping)
+ if (card->support_grouping) {
snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START;
+ snd_pcm_set_sync(substream);
+ }
/* struct is copied, so can create initializer dynamically */
runtime->hw = snd_card_asihpi_playback;
@@ -1047,8 +1049,6 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
card->update_interval_frames * 2, UINT_MAX);
- snd_pcm_set_sync(substream);
-
snd_printdd("playback open\n");
return 0;
@@ -1114,15 +1114,15 @@ static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream)
-static void snd_card_asihpi_capture_format(struct snd_card_asihpi *asihpi,
- u32 h_stream,
- struct snd_pcm_hardware *pcmhw)
+static u64 snd_card_asihpi_capture_formats(struct snd_card_asihpi *asihpi,
+ u32 h_stream)
{
struct hpi_format hpi_format;
u16 format;
u16 err;
u32 h_control;
u32 sample_rate = 48000;
+ u64 formats = 0;
/* on cards without SRC, must query at valid rate,
maybe set by external sync */
@@ -1137,34 +1137,22 @@ static void snd_card_asihpi_capture_format(struct snd_card_asihpi *asihpi,
for (format = HPI_FORMAT_PCM8_UNSIGNED;
format <= HPI_FORMAT_PCM24_SIGNED; format++) {
- err = hpi_format_create(&hpi_format, 2, format,
- sample_rate, 128000, 0);
+ err = hpi_format_create(&hpi_format, asihpi->in_max_chans,
+ format, sample_rate, 128000, 0);
if (!err)
- err = hpi_instream_query_format(h_stream,
- &hpi_format);
+ err = hpi_instream_query_format(h_stream, &hpi_format);
if (!err)
- pcmhw->formats |=
- (1ULL << hpi_to_alsa_formats[format]);
+ formats |= (1ULL << hpi_to_alsa_formats[format]);
}
+ return formats;
}
-
-static struct snd_pcm_hardware snd_card_asihpi_capture = {
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = BUFFER_BYTES_MAX,
- .period_bytes_min = PERIOD_BYTES_MIN,
- .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
- .periods_min = PERIODS_MIN,
- .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
- .fifo_size = 0,
-};
-
static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
struct snd_card_asihpi_pcm *dpcm;
+ struct snd_pcm_hardware snd_card_asihpi_capture;
int err;
dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
@@ -1172,10 +1160,10 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
return -ENOMEM;
snd_printdd("capture open adapter %d stream %d\n",
- card->adapter_index, substream->number);
+ card->hpi->adapter->index, substream->number);
err = hpi_handle_error(
- hpi_instream_open(card->adapter_index,
+ hpi_instream_open(card->hpi->adapter->index,
substream->number, &dpcm->h_stream));
if (err)
kfree(dpcm);
@@ -1184,7 +1172,6 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
if (err)
return -EIO;
-
init_timer(&dpcm->timer);
dpcm->timer.data = (unsigned long) dpcm;
dpcm->timer.function = snd_card_asihpi_timer_function;
@@ -1192,9 +1179,17 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
runtime->private_data = dpcm;
runtime->private_free = snd_card_asihpi_runtime_free;
+ memset(&snd_card_asihpi_capture, 0, sizeof(snd_card_asihpi_capture));
+ snd_card_asihpi_capture.buffer_bytes_max = BUFFER_BYTES_MAX;
+ snd_card_asihpi_capture.period_bytes_min = PERIOD_BYTES_MIN;
+ snd_card_asihpi_capture.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN;
+ snd_card_asihpi_capture.periods_min = PERIODS_MIN;
+ snd_card_asihpi_capture.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN;
+ /* snd_card_asihpi_capture.fifo_size = 0; */
snd_card_asihpi_capture.channels_max = card->in_max_chans;
- snd_card_asihpi_capture_format(card, dpcm->h_stream,
- &snd_card_asihpi_capture);
+ snd_card_asihpi_capture.channels_min = card->in_min_chans;
+ snd_card_asihpi_capture.formats =
+ snd_card_asihpi_capture_formats(card, dpcm->h_stream);
snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture);
snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP |
@@ -1240,15 +1235,20 @@ static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = {
.pointer = snd_card_asihpi_capture_pointer,
};
-static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi,
- int device, int substreams)
+static int __devinit snd_card_asihpi_pcm_new(
+ struct snd_card_asihpi *asihpi, int device)
{
struct snd_pcm *pcm;
int err;
+ u16 num_instreams, num_outstreams, x16;
+ u32 x32;
+
+ err = hpi_adapter_get_info(asihpi->hpi->adapter->index,
+ &num_outstreams, &num_instreams,
+ &x16, &x32, &x16);
err = snd_pcm_new(asihpi->card, "Asihpi PCM", device,
- asihpi->num_outstreams, asihpi->num_instreams,
- &pcm);
+ num_outstreams, num_instreams, &pcm);
if (err < 0)
return err;
/* pointer to ops struct is stored, dont change ops afterwards! */
@@ -1314,7 +1314,7 @@ static const char * const asihpi_src_names[] = {
"Analog",
"Adapter",
"RTP",
- "GPI",
+ "Internal"
};
compile_time_assert(
@@ -1332,7 +1332,6 @@ static const char * const asihpi_dst_names[] = {
"Net",
"Analog",
"RTP",
- "GPO",
};
compile_time_assert(
@@ -1410,6 +1409,7 @@ static int snd_asihpi_volume_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
u32 h_control = kcontrol->private_value;
+ u32 count;
u16 err;
/* native gains are in millibels */
short min_gain_mB;
@@ -1424,8 +1424,12 @@ static int snd_asihpi_volume_info(struct snd_kcontrol *kcontrol,
step_gain_mB = VOL_STEP_mB;
}
+ err = hpi_meter_query_channels(h_control, &count);
+ if (err)
+ count = HPI_MAX_CHANNELS;
+
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
+ uinfo->count = count;
uinfo->value.integer.min = min_gain_mB / VOL_STEP_mB;
uinfo->value.integer.max = max_gain_mB / VOL_STEP_mB;
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,
static int snd_asihpi_meter_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
+ u32 h_control = kcontrol->private_value;
+ u32 count;
+ u16 err;
+ err = hpi_meter_query_channels(h_control, &count);
+ if (err)
+ count = HPI_MAX_CHANNELS;
+
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = HPI_MAX_CHANNELS;
+ uinfo->count = count;
uinfo->value.integer.min = 0;
uinfo->value.integer.max = 0x7FFFFFFF;
return 0;
@@ -2248,6 +2259,9 @@ static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol,
valid_modes++;
}
+ if (!valid_modes)
+ return -EINVAL;
+
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->count = 1;
uinfo->value.enumerated.items = valid_modes;
@@ -2547,7 +2561,7 @@ static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
strcpy(card->mixername, "Asihpi Mixer");
err =
- hpi_mixer_open(asihpi->adapter_index,
+ hpi_mixer_open(asihpi->hpi->adapter->index,
&asihpi->h_mixer);
hpi_handle_error(err);
if (err)
@@ -2665,24 +2679,33 @@ snd_asihpi_proc_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{
struct snd_card_asihpi *asihpi = entry->private_data;
- u16 version;
u32 h_control;
u32 rate = 0;
u16 source = 0;
+
+ u16 num_outstreams;
+ u16 num_instreams;
+ u16 version;
+ u32 serial_number;
+ u16 type;
+
int err;
snd_iprintf(buffer, "ASIHPI driver proc file\n");
+
+ hpi_handle_error(hpi_adapter_get_info(asihpi->hpi->adapter->index,
+ &num_outstreams, &num_instreams,
+ &version, &serial_number, &type));
+
snd_iprintf(buffer,
- "adapter ID=%4X\n_index=%d\n"
- "num_outstreams=%d\n_num_instreams=%d\n",
- asihpi->type, asihpi->adapter_index,
- asihpi->num_outstreams, asihpi->num_instreams);
+ "Adapter type ASI%4X\nHardware Index %d\n"
+ "%d outstreams\n%d instreams\n",
+ type, asihpi->hpi->adapter->index,
+ num_outstreams, num_instreams);
- version = asihpi->version;
snd_iprintf(buffer,
- "serial#=%d\n_hw version %c%d\nDSP code version %03d\n",
- asihpi->serial_number, ((version >> 3) & 0xf) + 'A',
- version & 0x7,
+ "Serial#%d\nHardware version %c%d\nDSP code version %03d\n",
+ serial_number, ((version >> 3) & 0xf) + 'A', version & 0x7,
((version >> 13) * 100) + ((version >> 7) & 0x3f));
err = hpi_mixer_get_control(asihpi->h_mixer,
@@ -2690,18 +2713,15 @@ snd_asihpi_proc_read(struct snd_info_entry *entry,
HPI_CONTROL_SAMPLECLOCK, &h_control);
if (!err) {
- err = hpi_sample_clock_get_sample_rate(
- h_control, &rate);
+ err = hpi_sample_clock_get_sample_rate(h_control, &rate);
err += hpi_sample_clock_get_source(h_control, &source);
if (!err)
- snd_iprintf(buffer, "sample_clock=%d_hz, source %s\n",
+ snd_iprintf(buffer, "Sample Clock %dHz, source %s\n",
rate, sampleclock_sources[source]);
}
-
}
-
static void __devinit snd_asihpi_proc_init(struct snd_card_asihpi *asihpi)
{
struct snd_info_entry *entry;
@@ -2773,35 +2793,34 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
const struct pci_device_id *pci_id)
{
int err;
-
- u16 version;
- int pcm_substreams;
-
- struct hpi_adapter *hpi_card;
+ struct hpi_adapter *hpi;
struct snd_card *card;
struct snd_card_asihpi *asihpi;
u32 h_control;
u32 h_stream;
+ u32 adapter_index;
static int dev;
if (dev >= SNDRV_CARDS)
return -ENODEV;
- /* Should this be enable[hpi_card->index] ? */
+ /* Should this be enable[hpi->index] ? */
if (!enable[dev]) {
dev++;
return -ENOENT;
}
+ /* Initialise low-level HPI driver */
err = asihpi_adapter_probe(pci_dev, pci_id);
if (err < 0)
return err;
- hpi_card = pci_get_drvdata(pci_dev);
+ hpi = pci_get_drvdata(pci_dev);
+ adapter_index = hpi->adapter->index;
/* first try to give the card the same index as its hardware index */
- err = snd_card_create(hpi_card->index,
- id[hpi_card->index], THIS_MODULE,
+ err = snd_card_create(adapter_index,
+ id[adapter_index], THIS_MODULE,
sizeof(struct snd_card_asihpi),
&card);
if (err < 0) {
@@ -2815,50 +2834,32 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
return err;
snd_printk(KERN_WARNING
"**** WARNING **** Adapter index %d->ALSA index %d\n",
- hpi_card->index, card->number);
+ adapter_index, card->number);
}
snd_card_set_dev(card, &pci_dev->dev);
- asihpi = (struct snd_card_asihpi *) card->private_data;
+ asihpi = card->private_data;
asihpi->card = card;
asihpi->pci = pci_dev;
- asihpi->adapter_index = hpi_card->index;
- hpi_handle_error(hpi_adapter_get_info(
- asihpi->adapter_index,
- &asihpi->num_outstreams,
- &asihpi->num_instreams,
- &asihpi->version,
- &asihpi->serial_number, &asihpi->type));
-
- version = asihpi->version;
- snd_printk(KERN_INFO "adapter ID=%4X index=%d num_outstreams=%d "
- "num_instreams=%d S/N=%d\n"
- "Hw Version %c%d DSP code version %03d\n",
- asihpi->type, asihpi->adapter_index,
- asihpi->num_outstreams,
- asihpi->num_instreams, asihpi->serial_number,
- ((version >> 3) & 0xf) + 'A',
- version & 0x7,
- ((version >> 13) * 100) + ((version >> 7) & 0x3f));
-
- pcm_substreams = asihpi->num_outstreams;
- if (pcm_substreams < asihpi->num_instreams)
- pcm_substreams = asihpi->num_instreams;
-
- err = hpi_adapter_get_property(asihpi->adapter_index,
+ asihpi->hpi = hpi;
+
+ snd_printk(KERN_INFO "adapter ID=%4X index=%d\n",
+ asihpi->hpi->adapter->type, adapter_index);
+
+ err = hpi_adapter_get_property(adapter_index,
HPI_ADAPTER_PROPERTY_CAPS1,
NULL, &asihpi->support_grouping);
if (err)
asihpi->support_grouping = 0;
- err = hpi_adapter_get_property(asihpi->adapter_index,
+ err = hpi_adapter_get_property(adapter_index,
HPI_ADAPTER_PROPERTY_CAPS2,
&asihpi->support_mrx, NULL);
if (err)
asihpi->support_mrx = 0;
- err = hpi_adapter_get_property(asihpi->adapter_index,
+ err = hpi_adapter_get_property(adapter_index,
HPI_ADAPTER_PROPERTY_INTERVAL,
NULL, &asihpi->update_interval_frames);
if (err)
@@ -2867,7 +2868,7 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
if (!asihpi->can_dma)
asihpi->update_interval_frames *= 2;
- hpi_handle_error(hpi_instream_open(asihpi->adapter_index,
+ hpi_handle_error(hpi_instream_open(adapter_index,
0, &h_stream));
err = hpi_instream_host_buffer_free(h_stream);
@@ -2875,7 +2876,7 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
hpi_handle_error(hpi_instream_close(h_stream));
- err = hpi_adapter_get_property(asihpi->adapter_index,
+ err = hpi_adapter_get_property(adapter_index,
HPI_ADAPTER_PROPERTY_CURCHANNELS,
&asihpi->in_max_chans, &asihpi->out_max_chans);
if (err) {
@@ -2883,13 +2884,22 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
asihpi->out_max_chans = 2;
}
- snd_printk(KERN_INFO "has dma:%d, grouping:%d, mrx:%d\n",
+ if (asihpi->out_max_chans > 2) { /* assume LL mode */
+ asihpi->out_min_chans = asihpi->out_max_chans;
+ asihpi->in_min_chans = asihpi->in_max_chans;
+ asihpi->support_grouping = 0;
+ } else {
+ asihpi->out_min_chans = 1;
+ asihpi->in_min_chans = 1;
+ }
+
+ snd_printk(KERN_INFO "Has dma:%d, grouping:%d, mrx:%d\n",
asihpi->can_dma,
asihpi->support_grouping,
asihpi->support_mrx
);
- err = snd_card_asihpi_pcm_new(asihpi, 0, pcm_substreams);
+ err = snd_card_asihpi_pcm_new(asihpi, 0);
if (err < 0) {
snd_printk(KERN_ERR "pcm_new failed\n");
goto __nodev;
@@ -2916,13 +2926,14 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
strcpy(card->driver, "ASIHPI");
- sprintf(card->shortname, "AudioScience ASI%4X", asihpi->type);
+ sprintf(card->shortname, "AudioScience ASI%4X",
+ asihpi->hpi->adapter->type);
sprintf(card->longname, "%s %i",
- card->shortname, asihpi->adapter_index);
+ card->shortname, adapter_index);
err = snd_card_register(card);
if (!err) {
- hpi_card->snd_card_asihpi = card;
+ hpi->snd_card = card;
dev++;
return 0;
}
@@ -2935,10 +2946,9 @@ __nodev:
static void __devexit snd_asihpi_remove(struct pci_dev *pci_dev)
{
- struct hpi_adapter *hpi_card = pci_get_drvdata(pci_dev);
-
- snd_card_free(hpi_card->snd_card_asihpi);
- hpi_card->snd_card_asihpi = NULL;
+ struct hpi_adapter *hpi = pci_get_drvdata(pci_dev);
+ snd_card_free(hpi->snd_card);
+ hpi->snd_card = NULL;
asihpi_adapter_remove(pci_dev);
}
diff --git a/sound/pci/asihpi/hpi.h b/sound/pci/asihpi/hpi.h
index f20727288994..20887241a3ae 100644
--- a/sound/pci/asihpi/hpi.h
+++ b/sound/pci/asihpi/hpi.h
@@ -30,26 +30,8 @@
#ifndef _HPI_H_
#define _HPI_H_
-/* HPI Version
-If HPI_VER_MINOR is odd then its a development release not intended for the
-public. If HPI_VER_MINOR is even then is a release version
-i.e 3.05.02 is a development version
-*/
-#define HPI_VERSION_CONSTRUCTOR(maj, min, rel) \
- ((maj << 16) + (min << 8) + rel)
-
-#define HPI_VER_MAJOR(v) ((int)(v >> 16))
-#define HPI_VER_MINOR(v) ((int)((v >> 8) & 0xFF))
-#define HPI_VER_RELEASE(v) ((int)(v & 0xFF))
-
-#define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 8, 0)
-#define HPI_VER_STRING "4.08.00"
-
-/* Library version as documented in hpi-api-versions.txt */
-#define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(10, 0, 0)
#include <linux/types.h>
-#define HPI_BUILD_EXCLUDE_DEPRECATED
#define HPI_BUILD_KERNEL_MODE
/******************************************************************************/
@@ -213,7 +195,7 @@ enum HPI_SOURCENODES {
/** RTP stream input node - This node is a destination for
packets of RTP audio samples from other devices. */
HPI_SOURCENODE_RTP_DESTINATION = 112,
- HPI_SOURCENODE_GP_IN = 113, /**< general purpose input. */
+ HPI_SOURCENODE_INTERNAL = 113, /**< node internal to the device. */
/* !!!Update this AND hpidebug.h if you add a new sourcenode type!!! */
HPI_SOURCENODE_LAST_INDEX = 113 /**< largest ID */
/* AX6 max sourcenode types = 15 */
@@ -242,9 +224,8 @@ enum HPI_DESTNODES {
/** RTP stream output node - This node is a source for
packets of RTP audio samples that are sent to other devices. */
HPI_DESTNODE_RTP_SOURCE = 208,
- HPI_DESTNODE_GP_OUT = 209, /**< general purpose output node. */
/* !!!Update this AND hpidebug.h if you add a new destnode type!!! */
- HPI_DESTNODE_LAST_INDEX = 209 /**< largest ID */
+ HPI_DESTNODE_LAST_INDEX = 208 /**< largest ID */
/* AX6 max destnode types = 15 */
};
@@ -450,7 +431,19 @@ Indicates that the adapter in it's current mode supports interrupts
across the host bus. Note, this does not imply that interrupts are
enabled. Instead it indicates that they can be enabled.
*/
- HPI_ADAPTER_PROPERTY_SUPPORTS_IRQ = 272
+ HPI_ADAPTER_PROPERTY_SUPPORTS_IRQ = 272,
+/** Readonly supports firmware updating.
+Indicates that the adapter implements an interface to update firmware
+on the adapter.
+*/
+ HPI_ADAPTER_PROPERTY_SUPPORTS_FW_UPDATE = 273,
+/** Readonly Firmware IDs
+Identifiy firmware independent of individual adapter type.
+May be used as a filter for firmware update images.
+Property 1 = Bootloader ID
+Property 2 = Main program ID
+*/
+ HPI_ADAPTER_PROPERTY_FIRMWARE_ID = 274
};
/** Adapter mode commands
@@ -638,7 +631,7 @@ enum HPI_MIXER_STORE_COMMAND {
HPI_MIXER_STORE_ENABLE = 4,
/** Disable auto storage of some control settings. */
HPI_MIXER_STORE_DISABLE = 5,
-/** Save the attributes of a single control. */
+/** Unimplemented - save the attributes of a single control. */
HPI_MIXER_STORE_SAVE_SINGLE = 6
};
@@ -941,7 +934,7 @@ enum HPI_ERROR_CODES {
HPI_ERROR_BAD_ADAPTER_NUMBER = 202,
/** 2 adapters with the same adapter number. */
HPI_ERROR_DUPLICATE_ADAPTER_NUMBER = 203,
- /** DSP code failed to bootload. (unused?) */
+ /** DSP code failed to bootload. Usually a DSP memory test failure. */
HPI_ERROR_DSP_BOOTLOAD = 204,
/** Couldn't find or open the DSP code file. */
HPI_ERROR_DSP_FILE_NOT_FOUND = 206,
@@ -978,6 +971,9 @@ enum HPI_ERROR_CODES {
HPI_ERROR_FLASH_VERIFY = 225,
HPI_ERROR_FLASH_TYPE = 226,
HPI_ERROR_FLASH_START = 227,
+ HPI_ERROR_FLASH_READ = 228,
+ HPI_ERROR_FLASH_READ_NO_FILE = 229,
+ HPI_ERROR_FLASH_SIZE = 230,
/** Reserved for OEMs. */
HPI_ERROR_RESERVED_1 = 290,
@@ -1020,6 +1016,8 @@ enum HPI_ERROR_CODES {
HPI_ERROR_NO_INTERDSP_GROUPS = 315,
/** Stream wait cancelled before threshold reached. */
HPI_ERROR_WAIT_CANCELLED = 316,
+ /** A character string is invalid. */
+ HPI_ERROR_INVALID_STRING = 317,
/** Invalid mixer node for this adapter. */
HPI_ERROR_INVALID_NODE = 400,
@@ -1046,11 +1044,15 @@ enum HPI_ERROR_CODES {
/** I2C */
HPI_ERROR_I2C_BAD_ADR = 460,
- /** Entity errors */
+ /** Entity type did not match requested type */
HPI_ERROR_ENTITY_TYPE_MISMATCH = 470,
+ /** Entity item count did not match requested count */
HPI_ERROR_ENTITY_ITEM_COUNT = 471,
+ /** Entity type is not one of the valid types */
HPI_ERROR_ENTITY_TYPE_INVALID = 472,
+ /** Entity role is not one of the valid roles */
HPI_ERROR_ENTITY_ROLE_INVALID = 473,
+ /** Entity size doesn't match target size */
HPI_ERROR_ENTITY_SIZE_MISMATCH = 474,
/* AES18 specific errors were 500..507 */
@@ -1078,8 +1080,7 @@ enum HPI_ERROR_CODES {
/** \defgroup maximums HPI maximum values
\{
*/
-/** Maximum number of adapters per HPI sub-system
- WARNING: modifying this value changes the response structure size.*/
+/** Maximum number of PCI HPI adapters */
#define HPI_MAX_ADAPTERS 20
/** Maximum number of in or out streams per adapter */
#define HPI_MAX_STREAMS 16
@@ -1090,6 +1091,9 @@ enum HPI_ERROR_CODES {
#define HPI_MAX_ANC_BYTES_PER_FRAME (64)
#define HPI_STRING_LEN 16
+/** Networked adapters have index >= 100 */
+#define HPI_MIN_NETWORK_ADAPTER_IDX 100
+
/** Velocity units */
#define HPI_OSTREAM_VELOCITY_UNITS 4096
/** OutStream timescale units */
@@ -1111,14 +1115,14 @@ enum HPI_ERROR_CODES {
struct hpi_format {
u32 sample_rate;
/**< 11025, 32000, 44100 ... */
- u32 bit_rate; /**< for MPEG */
+ u32 bit_rate; /**< for MPEG */
u32 attributes;
/**< Stereo/JointStereo/Mono */
u16 mode_legacy;
/**< Legacy ancillary mode or idle bit */
- u16 unused; /**< Unused */
- u16 channels; /**< 1,2..., (or ancillary mode or idle bit */
- u16 format; /**< HPI_FORMAT_PCM16, _MPEG etc. see #HPI_FORMATS. */
+ u16 unused; /**< Unused */
+ u16 channels; /**< 1,2..., (or ancillary mode or idle bit */
+ u16 format; /**< HPI_FORMAT_PCM16, _MPEG etc. see #HPI_FORMATS. */
};
struct hpi_anc_frame {
@@ -1144,9 +1148,6 @@ struct hpi_async_event {
} u;
};
-/* skip host side function declarations for
- DSP compile and documentation extraction */
-
#ifndef DISABLE_PRAGMA_PACK1
#pragma pack(pop)
#endif
@@ -1357,7 +1358,7 @@ u16 hpi_volume_get_mute(u32 h_control, u32 *mute);
u16 hpi_volume_query_range(u32 h_control, short *min_gain_01dB,
short *max_gain_01dB, short *step_gain_01dB);
-u16 hpi_volume_query_channels(const u32 h_volume, u32 *p_channels);
+u16 hpi_volume_query_channels(const u32 h_control, u32 *p_channels);
u16 hpi_volume_auto_fade(u32 h_control,
short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms);
@@ -1366,6 +1367,9 @@ u16 hpi_volume_auto_fade_profile(u32 h_control,
short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms,
u16 profile);
+u16 hpi_volume_query_auto_fade_profile(const u32 h_control, const u32 i,
+ u16 *profile);
+
/*****************/
/* Level control */
/*****************/
diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c
index 3cc6f11c20aa..2414d7a2239d 100644
--- a/sound/pci/asihpi/hpi6000.c
+++ b/sound/pci/asihpi/hpi6000.c
@@ -1,7 +1,7 @@
/******************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
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)
static void control_message(struct hpi_adapter_obj *pao,
struct hpi_message *phm, struct hpi_response *phr)
{
+ struct hpi_hw_obj *phw = pao->priv;
+
switch (phm->function) {
case HPI_CONTROL_GET_STATE:
if (pao->has_control_cache) {
@@ -248,17 +250,14 @@ static void control_message(struct hpi_adapter_obj *pao,
break;
}
- if (hpi_check_control_cache(((struct hpi_hw_obj *)
- pao->priv)->p_cache, phm,
- phr))
+ if (hpi_check_control_cache(phw->p_cache, phm, phr))
break;
}
hw_message(pao, phm, phr);
break;
case HPI_CONTROL_SET_STATE:
hw_message(pao, phm, phr);
- hpi_cmn_control_cache_sync_to_msg(((struct hpi_hw_obj *)pao->
- priv)->p_cache, phm, phr);
+ hpi_cmn_control_cache_sync_to_msg(phw->p_cache, phm, phr);
break;
case HPI_CONTROL_GET_INFO:
@@ -451,11 +450,11 @@ static void subsys_create_adapter(struct hpi_message *phm,
}
for (dsp_index = 0; dsp_index < MAX_DSPS; dsp_index++) {
- struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
+ struct hpi_hw_obj *phw = pao->priv;
phw->ado[dsp_index].pa_parent_adapter = pao;
}
- phr->u.s.adapter_type = ao.adapter_type;
+ phr->u.s.adapter_type = ao.type;
phr->u.s.adapter_index = ao.index;
phr->error = 0;
}
@@ -476,7 +475,7 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao,
u32 dsp_index = 0;
u32 control_cache_size = 0;
u32 control_cache_count = 0;
- struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
+ struct hpi_hw_obj *phw = pao->priv;
/* The PCI2040 has the following address map */
/* 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,
if (error)
return error;
}
- pao->adapter_type = hr0.u.ax.info.adapter_type;
+ pao->type = hr0.u.ax.info.adapter_type;
pao->index = hr0.u.ax.info.adapter_index;
}
@@ -584,9 +583,8 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao,
pao->has_control_cache = 1;
}
- HPI_DEBUG_LOG(DEBUG, "get adapter info ASI%04X index %d\n",
- pao->adapter_type, pao->index);
- pao->open = 0; /* upon creation the adapter is closed */
+ HPI_DEBUG_LOG(DEBUG, "get adapter info ASI%04X index %d\n", pao->type,
+ pao->index);
if (phw->p_cache)
phw->p_cache->adap_idx = pao->index;
@@ -596,7 +594,7 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao,
static void delete_adapter_obj(struct hpi_adapter_obj *pao)
{
- struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
+ struct hpi_hw_obj *phw = pao->priv;
if (pao->has_control_cache)
hpi_free_control_cache(phw->p_cache);
@@ -639,7 +637,7 @@ static void adapter_get_asserts(struct hpi_adapter_obj *pao,
static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
u32 *pos_error_code)
{
- struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
+ struct hpi_hw_obj *phw = pao->priv;
short error;
u32 timeout;
u32 read = 0;
@@ -1220,8 +1218,8 @@ static void hpi_read_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
static u16 hpi6000_dsp_block_write32(struct hpi_adapter_obj *pao,
u16 dsp_index, u32 hpi_address, u32 *source, u32 count)
{
- struct dsp_obj *pdo =
- &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
+ struct hpi_hw_obj *phw = pao->priv;
+ struct dsp_obj *pdo = &phw->ado[dsp_index];
u32 time_out = PCI_TIMEOUT;
int c6711_burst_size = 128;
u32 local_hpi_address = hpi_address;
@@ -1258,8 +1256,8 @@ static u16 hpi6000_dsp_block_write32(struct hpi_adapter_obj *pao,
static u16 hpi6000_dsp_block_read32(struct hpi_adapter_obj *pao,
u16 dsp_index, u32 hpi_address, u32 *dest, u32 count)
{
- struct dsp_obj *pdo =
- &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
+ struct hpi_hw_obj *phw = pao->priv;
+ struct dsp_obj *pdo = &phw->ado[dsp_index];
u32 time_out = PCI_TIMEOUT;
int c6711_burst_size = 16;
u32 local_hpi_address = hpi_address;
@@ -1298,7 +1296,7 @@ static u16 hpi6000_dsp_block_read32(struct hpi_adapter_obj *pao,
static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
u16 dsp_index, struct hpi_message *phm, struct hpi_response *phr)
{
- struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
+ struct hpi_hw_obj *phw = pao->priv;
struct dsp_obj *pdo = &phw->ado[dsp_index];
u32 timeout;
u16 ack;
@@ -1414,8 +1412,8 @@ static short hpi6000_send_data_check_adr(u32 address, u32 length_in_dwords)
static short hpi6000_send_data(struct hpi_adapter_obj *pao, u16 dsp_index,
struct hpi_message *phm, struct hpi_response *phr)
{
- struct dsp_obj *pdo =
- &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
+ struct hpi_hw_obj *phw = pao->priv;
+ struct dsp_obj *pdo = &phw->ado[dsp_index];
u32 data_sent = 0;
u16 ack;
u32 length, address;
@@ -1487,8 +1485,8 @@ static short hpi6000_send_data(struct hpi_adapter_obj *pao, u16 dsp_index,
static short hpi6000_get_data(struct hpi_adapter_obj *pao, u16 dsp_index,
struct hpi_message *phm, struct hpi_response *phr)
{
- struct dsp_obj *pdo =
- &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
+ struct hpi_hw_obj *phw = pao->priv;
+ struct dsp_obj *pdo = &phw->ado[dsp_index];
u32 data_got = 0;
u16 ack;
u32 length, address;
@@ -1551,8 +1549,8 @@ static void hpi6000_send_dsp_interrupt(struct dsp_obj *pdo)
static short hpi6000_send_host_command(struct hpi_adapter_obj *pao,
u16 dsp_index, u32 host_cmd)
{
- struct dsp_obj *pdo =
- &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
+ struct hpi_hw_obj *phw = pao->priv;
+ struct dsp_obj *pdo = &phw->ado[dsp_index];
u32 timeout = TIMEOUT;
/* set command */
@@ -1577,7 +1575,7 @@ static short hpi6000_check_PCI2040_error_flag(struct hpi_adapter_obj *pao,
{
u32 hPI_error;
- struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
+ struct hpi_hw_obj *phw = pao->priv;
/* read the error bits from the PCI2040 */
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,
static short hpi6000_wait_dsp_ack(struct hpi_adapter_obj *pao, u16 dsp_index,
u32 ack_value)
{
- struct dsp_obj *pdo =
- &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
+ struct hpi_hw_obj *phw = pao->priv;
+ struct dsp_obj *pdo = &phw->ado[dsp_index];
u32 ack = 0L;
u32 timeout;
u32 hPIC = 0L;
@@ -1640,7 +1638,7 @@ static short hpi6000_update_control_cache(struct hpi_adapter_obj *pao,
struct hpi_message *phm)
{
const u16 dsp_index = 0;
- struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
+ struct hpi_hw_obj *phw = pao->priv;
struct dsp_obj *pdo = &phw->ado[dsp_index];
u32 timeout;
u32 cache_dirty_flag;
@@ -1740,7 +1738,8 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
{
u16 error = 0;
u16 dsp_index = 0;
- u16 num_dsp = ((struct hpi_hw_obj *)pao->priv)->num_dsp;
+ struct hpi_hw_obj *phw = pao->priv;
+ u16 num_dsp = phw->num_dsp;
if (num_dsp < 2)
dsp_index = 0;
diff --git a/sound/pci/asihpi/hpi6000.h b/sound/pci/asihpi/hpi6000.h
index 4c7d507c0ecd..7e0deeff5e7c 100644
--- a/sound/pci/asihpi/hpi6000.h
+++ b/sound/pci/asihpi/hpi6000.h
@@ -1,7 +1,7 @@
/*****************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
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 e041a6ae1c5a..4f2873880b16 100644
--- a/sound/pci/asihpi/hpi6205.c
+++ b/sound/pci/asihpi/hpi6205.c
@@ -1,7 +1,7 @@
/******************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
@@ -45,18 +45,21 @@
#define HPI6205_ERROR_MSG_RESP_TIMEOUT 1016
/* initialization/bootload errors */
-#define HPI6205_ERROR_6205_NO_IRQ 1002
-#define HPI6205_ERROR_6205_INIT_FAILED 1003
-#define HPI6205_ERROR_6205_REG 1006
-#define HPI6205_ERROR_6205_DSPPAGE 1007
-#define HPI6205_ERROR_C6713_HPIC 1009
-#define HPI6205_ERROR_C6713_HPIA 1010
-#define HPI6205_ERROR_C6713_PLL 1011
-#define HPI6205_ERROR_DSP_INTMEM 1012
-#define HPI6205_ERROR_DSP_EXTMEM 1013
-#define HPI6205_ERROR_DSP_PLD 1014
-#define HPI6205_ERROR_6205_EEPROM 1017
-#define HPI6205_ERROR_DSP_EMIF 1018
+#define HPI6205_ERROR_6205_NO_IRQ 1002
+#define HPI6205_ERROR_6205_INIT_FAILED 1003
+#define HPI6205_ERROR_6205_REG 1006
+#define HPI6205_ERROR_6205_DSPPAGE 1007
+#define HPI6205_ERROR_C6713_HPIC 1009
+#define HPI6205_ERROR_C6713_HPIA 1010
+#define HPI6205_ERROR_C6713_PLL 1011
+#define HPI6205_ERROR_DSP_INTMEM 1012
+#define HPI6205_ERROR_DSP_EXTMEM 1013
+#define HPI6205_ERROR_DSP_PLD 1014
+#define HPI6205_ERROR_6205_EEPROM 1017
+#define HPI6205_ERROR_DSP_EMIF1 1018
+#define HPI6205_ERROR_DSP_EMIF2 1019
+#define HPI6205_ERROR_DSP_EMIF3 1020
+#define HPI6205_ERROR_DSP_EMIF4 1021
/*****************************************************************************/
/* for C6205 PCI i/f */
@@ -488,7 +491,7 @@ static void subsys_create_adapter(struct hpi_message *phm,
return;
}
- phr->u.s.adapter_type = ao.adapter_type;
+ phr->u.s.adapter_type = ao.type;
phr->u.s.adapter_index = ao.index;
phr->error = 0;
}
@@ -503,7 +506,7 @@ static void adapter_delete(struct hpi_adapter_obj *pao,
phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
return;
}
- phw = (struct hpi_hw_obj *)pao->priv;
+ phw = pao->priv;
/* reset adapter h/w */
/* Reset C6713 #1 */
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,
if (hr.error)
return hr.error;
- pao->adapter_type = hr.u.ax.info.adapter_type;
+ pao->type = hr.u.ax.info.adapter_type;
pao->index = hr.u.ax.info.adapter_index;
max_streams =
@@ -665,8 +668,6 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
hr.u.ax.info.serial_number);
}
- pao->open = 0; /* upon creation the adapter is closed */
-
if (phw->p_cache)
phw->p_cache->adap_idx = pao->index;
@@ -803,8 +804,8 @@ static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao,
obj_index];
status->samples_processed = 0;
status->stream_state = HPI_STATE_STOPPED;
- status->dSP_index = 0;
- status->host_index = status->dSP_index;
+ status->dsp_index = 0;
+ status->host_index = status->dsp_index;
status->size_in_bytes = phm->u.d.u.buffer.buffer_size;
status->auxiliary_data_available = 0;
@@ -878,7 +879,7 @@ static void outstream_host_buffer_free(struct hpi_adapter_obj *pao,
static u32 outstream_get_space_available(struct hpi_hostbuffer_status *status)
{
return status->size_in_bytes - (status->host_index -
- status->dSP_index);
+ status->dsp_index);
}
static void outstream_write(struct hpi_adapter_obj *pao,
@@ -1080,8 +1081,8 @@ static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
obj_index];
status->samples_processed = 0;
status->stream_state = HPI_STATE_STOPPED;
- status->dSP_index = 0;
- status->host_index = status->dSP_index;
+ status->dsp_index = 0;
+ status->host_index = status->dsp_index;
status->size_in_bytes = phm->u.d.u.buffer.buffer_size;
status->auxiliary_data_available = 0;
@@ -1162,7 +1163,7 @@ static void instream_start(struct hpi_adapter_obj *pao,
static u32 instream_get_bytes_available(struct hpi_hostbuffer_status *status)
{
- return status->dSP_index - status->host_index;
+ return status->dsp_index - status->host_index;
}
static 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)
boot_loader_write_mem32(pao, dsp_index, 0x01800008, setting);
if (setting != boot_loader_read_mem32(pao, dsp_index,
0x01800008))
- return HPI6205_ERROR_DSP_EMIF;
+ return HPI6205_ERROR_DSP_EMIF1;
/* EMIF CE1 setup - 32 bit async. This is 6713 #1 HPI, */
/* 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)
boot_loader_write_mem32(pao, dsp_index, 0x01800004, setting);
if (setting != boot_loader_read_mem32(pao, dsp_index,
0x01800004))
- return HPI6205_ERROR_DSP_EMIF;
+ return HPI6205_ERROR_DSP_EMIF2;
/* EMIF CE2 setup - 32 bit async. This is 6713 #2 HPI, */
/* 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)
boot_loader_write_mem32(pao, dsp_index, 0x01800010, setting);
if (setting != boot_loader_read_mem32(pao, dsp_index,
0x01800010))
- return HPI6205_ERROR_DSP_EMIF;
+ return HPI6205_ERROR_DSP_EMIF3;
/* EMIF CE3 setup - 32 bit async. */
/* 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)
boot_loader_write_mem32(pao, dsp_index, 0x01800014, setting);
if (setting != boot_loader_read_mem32(pao, dsp_index,
0x01800014))
- return HPI6205_ERROR_DSP_EMIF;
+ return HPI6205_ERROR_DSP_EMIF4;
/* set EMIF SDRAM control for 2Mx32 SDRAM (512x32x4 bank) */
/* 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 d497030c160f..4cc315daeda0 100644
--- a/sound/pci/asihpi/hpi_internal.h
+++ b/sound/pci/asihpi/hpi_internal.h
@@ -25,6 +25,7 @@ HPI internal definitions
#define _HPI_INTERNAL_H_
#include "hpi.h"
+
/** maximum number of memory regions mapped to an adapter */
#define HPI_MAX_ADAPTER_MEM_SPACES (2)
@@ -220,8 +221,6 @@ enum HPI_CONTROL_ATTRIBUTES {
HPI_COBRANET_SET = HPI_CTL_ATTR(COBRANET, 1),
HPI_COBRANET_GET = HPI_CTL_ATTR(COBRANET, 2),
- /*HPI_COBRANET_SET_DATA = HPI_CTL_ATTR(COBRANET, 3), */
- /*HPI_COBRANET_GET_DATA = HPI_CTL_ATTR(COBRANET, 4), */
HPI_COBRANET_GET_STATUS = HPI_CTL_ATTR(COBRANET, 5),
HPI_COBRANET_SEND_PACKET = HPI_CTL_ATTR(COBRANET, 6),
HPI_COBRANET_GET_PACKET = HPI_CTL_ATTR(COBRANET, 7),
@@ -241,7 +240,9 @@ enum HPI_CONTROL_ATTRIBUTES {
HPI_PAD_PROGRAM_TYPE = HPI_CTL_ATTR(PAD, 5),
HPI_PAD_PROGRAM_ID = HPI_CTL_ATTR(PAD, 6),
HPI_PAD_TA_SUPPORT = HPI_CTL_ATTR(PAD, 7),
- HPI_PAD_TA_ACTIVE = HPI_CTL_ATTR(PAD, 8)
+ HPI_PAD_TA_ACTIVE = HPI_CTL_ATTR(PAD, 8),
+
+ HPI_UNIVERSAL_ENTITY = HPI_CTL_ATTR(UNIVERSAL, 1)
};
#define HPI_POLARITY_POSITIVE 0
@@ -393,14 +394,10 @@ enum HPI_FUNCTION_IDS {
HPI_SUBSYS_OPEN = HPI_FUNC_ID(SUBSYSTEM, 1),
HPI_SUBSYS_GET_VERSION = HPI_FUNC_ID(SUBSYSTEM, 2),
HPI_SUBSYS_GET_INFO = HPI_FUNC_ID(SUBSYSTEM, 3),
- /* HPI_SUBSYS_FIND_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 4), */
HPI_SUBSYS_CREATE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 5),
HPI_SUBSYS_CLOSE = HPI_FUNC_ID(SUBSYSTEM, 6),
- /* HPI_SUBSYS_DELETE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 7), */
HPI_SUBSYS_DRIVER_LOAD = HPI_FUNC_ID(SUBSYSTEM, 8),
HPI_SUBSYS_DRIVER_UNLOAD = HPI_FUNC_ID(SUBSYSTEM, 9),
- /* HPI_SUBSYS_READ_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 10), */
- /* HPI_SUBSYS_WRITE_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 11), */
HPI_SUBSYS_GET_NUM_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 12),
HPI_SUBSYS_GET_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 13),
HPI_SUBSYS_SET_NETWORK_INTERFACE = HPI_FUNC_ID(SUBSYSTEM, 14),
@@ -430,7 +427,10 @@ enum HPI_FUNCTION_IDS {
HPI_ADAPTER_IRQ_QUERY_AND_CLEAR = HPI_FUNC_ID(ADAPTER, 19),
HPI_ADAPTER_IRQ_CALLBACK = HPI_FUNC_ID(ADAPTER, 20),
HPI_ADAPTER_DELETE = HPI_FUNC_ID(ADAPTER, 21),
-#define HPI_ADAPTER_FUNCTION_COUNT 21
+ HPI_ADAPTER_READ_FLASH = HPI_FUNC_ID(ADAPTER, 22),
+ HPI_ADAPTER_END_FLASH = HPI_FUNC_ID(ADAPTER, 23),
+ HPI_ADAPTER_FILESTORE_DELETE_ALL = HPI_FUNC_ID(ADAPTER, 24),
+#define HPI_ADAPTER_FUNCTION_COUNT 24
HPI_OSTREAM_OPEN = HPI_FUNC_ID(OSTREAM, 1),
HPI_OSTREAM_CLOSE = HPI_FUNC_ID(OSTREAM, 2),
@@ -495,7 +495,9 @@ enum HPI_FUNCTION_IDS {
HPI_MIXER_GET_CONTROL_MULTIPLE_VALUES = HPI_FUNC_ID(MIXER, 10),
HPI_MIXER_STORE = HPI_FUNC_ID(MIXER, 11),
HPI_MIXER_GET_CACHE_INFO = HPI_FUNC_ID(MIXER, 12),
-#define HPI_MIXER_FUNCTION_COUNT 12
+ HPI_MIXER_GET_BLOCK_HANDLE = HPI_FUNC_ID(MIXER, 13),
+ HPI_MIXER_GET_PARAMETER_HANDLE = HPI_FUNC_ID(MIXER, 14),
+#define HPI_MIXER_FUNCTION_COUNT 14
HPI_CONTROL_GET_INFO = HPI_FUNC_ID(CONTROL, 1),
HPI_CONTROL_GET_STATE = HPI_FUNC_ID(CONTROL, 2),
@@ -618,7 +620,7 @@ struct hpi_hostbuffer_status {
u32 auxiliary_data_available;
u32 stream_state;
/* DSP index in to the host bus master buffer. */
- u32 dSP_index;
+ u32 dsp_index;
/* Host index in to the host bus master buffer. */
u32 host_index;
u32 size_in_bytes;
@@ -661,13 +663,6 @@ union hpi_adapterx_msg {
u16 index;
} module_info;
struct {
- u32 checksum;
- u16 sequence;
- u16 length;
- u16 offset; /**< offset from start of msg to data */
- u16 unused;
- } program_flash;
- struct {
u16 index;
u16 what;
u16 property_index;
@@ -678,25 +673,18 @@ union hpi_adapterx_msg {
u16 parameter2;
} property_set;
struct {
- u32 offset;
- } query_flash;
- struct {
u32 pad32;
u16 key1;
u16 key2;
} restart;
struct {
- u32 offset;
- u32 length;
- u32 key;
- } start_flash;
- struct {
u32 pad32;
u16 value;
} test_assert;
struct {
u32 yes;
} irq_query;
+ u32 pad[3];
};
struct hpi_adapter_res {
@@ -724,18 +712,10 @@ union hpi_adapterx_res {
u32 adapter_mode;
} mode;
struct {
- u16 sequence;
- } program_flash;
- struct {
u16 parameter1;
u16 parameter2;
} property_get;
struct {
- u32 checksum;
- u32 length;
- u32 version;
- } query_flash;
- struct {
u32 yes;
} irq_query;
};
@@ -1150,74 +1130,9 @@ struct hpi_res_adapter_get_info {
struct hpi_adapter_res p;
};
-/* padding is so these are same size as v0 hpi_message */
-struct hpi_msg_adapter_query_flash {
- struct hpi_message_header h;
- u32 offset;
- u8 pad_to_version0_size[sizeof(struct hpi_message) - /* V0 res */
- sizeof(struct hpi_message_header) - 1 * sizeof(u32)];
-};
-
-/* padding is so these are same size as v0 hpi_response */
-struct hpi_res_adapter_query_flash {
- struct hpi_response_header h;
- u32 checksum;
- u32 length;
- u32 version;
- u8 pad_to_version0_size[sizeof(struct hpi_response) - /* V0 res */
- sizeof(struct hpi_response_header) - 3 * sizeof(u32)];
-};
-
-struct hpi_msg_adapter_start_flash {
- struct hpi_message_header h;
- u32 offset;
- u32 length;
- u32 key;
- u8 pad_to_version0_size[sizeof(struct hpi_message) - /* V0 res */
- sizeof(struct hpi_message_header) - 3 * sizeof(u32)];
-};
-
-struct hpi_res_adapter_start_flash {
- struct hpi_response_header h;
- u8 pad_to_version0_size[sizeof(struct hpi_response) - /* V0 res */
- sizeof(struct hpi_response_header)];
-};
-
-struct hpi_msg_adapter_program_flash_payload {
- u32 checksum;
- u16 sequence;
- u16 length;
- u16 offset; /**< offset from start of msg to data */
- u16 unused;
- /* ensure sizeof(header + payload) == sizeof(hpi_message_V0)
- because old firmware expects data after message of this size */
- u8 pad_to_version0_size[sizeof(struct hpi_message) - /* V0 message */
- sizeof(struct hpi_message_header) - sizeof(u32) -
- 4 * sizeof(u16)];
-};
-
-struct hpi_msg_adapter_program_flash {
- struct hpi_message_header h;
- struct hpi_msg_adapter_program_flash_payload p;
- u32 data[256];
-};
-
-struct hpi_res_adapter_program_flash {
- struct hpi_response_header h;
- u16 sequence;
- u8 pad_to_version0_size[sizeof(struct hpi_response) - /* V0 res */
- sizeof(struct hpi_response_header) - sizeof(u16)];
-};
-
-struct hpi_msg_adapter_debug_read {
- struct hpi_message_header h;
- u32 dsp_address;
- u32 count_bytes;
-};
-
struct hpi_res_adapter_debug_read {
struct hpi_response_header h;
- u8 bytes[256];
+ u8 bytes[1024];
};
struct hpi_msg_cobranet_hmi {
@@ -1461,7 +1376,7 @@ struct hpi_control_cache_pad {
/* 2^N sized FIFO buffer (internal to HPI<->DSP interaction) */
struct hpi_fifo_buffer {
u32 size;
- u32 dSP_index;
+ u32 dsp_index;
u32 host_index;
};
diff --git a/sound/pci/asihpi/hpi_version.h b/sound/pci/asihpi/hpi_version.h
new file mode 100644
index 000000000000..e9146e53bd50
--- /dev/null
+++ b/sound/pci/asihpi/hpi_version.h
@@ -0,0 +1,32 @@
+/** HPI Version Definitions
+Development releases have odd minor version.
+Production releases have even minor version.
+
+\file hpi_version.h
+*/
+
+#ifndef _HPI_VERSION_H
+#define _HPI_VERSION_H
+
+/* Use single digits for versions less that 10 to avoid octal. */
+/* *** HPI_VER is the only edit required to update version *** */
+/** HPI version */
+#define HPI_VER HPI_VERSION_CONSTRUCTOR(4, 10, 1)
+
+/** HPI version string in dotted decimal format */
+#define HPI_VER_STRING "4.10.01"
+
+/** Library version as documented in hpi-api-versions.txt */
+#define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(10, 2, 0)
+
+/** Construct hpi version number from major, minor, release numbers */
+#define HPI_VERSION_CONSTRUCTOR(maj, min, r) ((maj << 16) + (min << 8) + r)
+
+/** Extract major version from hpi version number */
+#define HPI_VER_MAJOR(v) ((int)(v >> 16))
+/** Extract minor version from hpi version number */
+#define HPI_VER_MINOR(v) ((int)((v >> 8) & 0xFF))
+/** Extract release from hpi version number */
+#define HPI_VER_RELEASE(v) ((int)(v & 0xFF))
+
+#endif
diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c
index bd47521b24ec..7ed5c26c3737 100644
--- a/sound/pci/asihpi/hpicmn.c
+++ b/sound/pci/asihpi/hpicmn.c
@@ -1,7 +1,7 @@
/******************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
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)
u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
{
u16 retval = 0;
- /*HPI_ASSERT(pao->wAdapterType); */
+ /*HPI_ASSERT(pao->type); */
hpios_alistlock_lock(&adapters);
@@ -77,13 +77,13 @@ u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
goto unlock;
}
- if (adapters.adapter[pao->index].adapter_type) {
+ if (adapters.adapter[pao->index].type) {
int a;
for (a = HPI_MAX_ADAPTERS - 1; a >= 0; a--) {
- if (!adapters.adapter[a].adapter_type) {
+ if (!adapters.adapter[a].type) {
HPI_DEBUG_LOG(WARNING,
"ASI%X duplicate index %d moved to %d\n",
- pao->adapter_type, pao->index, a);
+ pao->type, pao->index, a);
pao->index = a;
break;
}
@@ -104,13 +104,13 @@ unlock:
void hpi_delete_adapter(struct hpi_adapter_obj *pao)
{
- if (!pao->adapter_type) {
+ if (!pao->type) {
HPI_DEBUG_LOG(ERROR, "removing null adapter?\n");
return;
}
hpios_alistlock_lock(&adapters);
- if (adapters.adapter[pao->index].adapter_type)
+ if (adapters.adapter[pao->index].type)
adapters.gw_num_adapters--;
memset(&adapters.adapter[pao->index], 0, sizeof(adapters.adapter[0]));
hpios_alistlock_unlock(&adapters);
@@ -132,7 +132,7 @@ struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index)
}
pao = &adapters.adapter[adapter_index];
- if (pao->adapter_type != 0) {
+ if (pao->type != 0) {
/*
HPI_DEBUG_LOG(VERBOSE, "Found adapter index %d\n",
wAdapterIndex);
@@ -165,7 +165,7 @@ static void subsys_get_adapter(struct hpi_message *phm,
/* find the nCount'th nonzero adapter in array */
for (index = 0; index < HPI_MAX_ADAPTERS; index++) {
- if (adapters.adapter[index].adapter_type) {
+ if (adapters.adapter[index].type) {
if (!count)
break;
count--;
@@ -174,11 +174,11 @@ static void subsys_get_adapter(struct hpi_message *phm,
if (index < HPI_MAX_ADAPTERS) {
phr->u.s.adapter_index = adapters.adapter[index].index;
- phr->u.s.adapter_type = adapters.adapter[index].adapter_type;
+ phr->u.s.adapter_type = adapters.adapter[index].type;
} else {
phr->u.s.adapter_index = 0;
phr->u.s.adapter_type = 0;
- phr->error = HPI_ERROR_BAD_ADAPTER_NUMBER;
+ phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
}
}
@@ -324,6 +324,8 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
}
phr->error = 0;
+ phr->specific_error = 0;
+ phr->version = 0;
/* set the default response size */
response_size =
@@ -531,8 +533,12 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
found ? "Cached" : "Uncached", phm->adapter_index,
pI->control_index, pI->control_type, phm->u.c.attribute);
- if (found)
+ if (found) {
phr->size = (u16)response_size;
+ phr->type = HPI_TYPE_RESPONSE;
+ phr->object = phm->object;
+ phr->function = phm->function;
+ }
return found;
}
@@ -631,7 +637,7 @@ struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count,
if (!p_cache)
return NULL;
- p_cache->p_info = kzalloc(sizeof(*p_cache->p_info) * control_count,
+ p_cache->p_info = kcalloc(control_count, sizeof(*p_cache->p_info),
GFP_KERNEL);
if (!p_cache->p_info) {
kfree(p_cache);
diff --git a/sound/pci/asihpi/hpicmn.h b/sound/pci/asihpi/hpicmn.h
index d53cdf6e535f..e44121283047 100644
--- a/sound/pci/asihpi/hpicmn.h
+++ b/sound/pci/asihpi/hpicmn.h
@@ -1,7 +1,7 @@
/**
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
@@ -18,12 +18,15 @@
*/
+struct hpi_adapter_obj;
+
+/* a function that takes an adapter obj and returns an int */
+typedef int adapter_int_func(struct hpi_adapter_obj *pao);
+
struct hpi_adapter_obj {
struct hpi_pci pci; /* PCI info - bus#,dev#,address etc */
- u16 adapter_type; /* ASI6701 etc */
- u16 index; /* */
- u16 open; /* =1 when adapter open */
- u16 mixer_open;
+ u16 type; /* 0x6644 == ASI6644 etc */
+ u16 index;
struct hpios_spinlock dsp_lock;
diff --git a/sound/pci/asihpi/hpidebug.c b/sound/pci/asihpi/hpidebug.c
index b52baf62791e..ac86a1f1d3bf 100644
--- a/sound/pci/asihpi/hpidebug.c
+++ b/sound/pci/asihpi/hpidebug.c
@@ -1,7 +1,7 @@
/************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
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 940f54c3c538..2c9af2329d36 100644
--- a/sound/pci/asihpi/hpidebug.h
+++ b/sound/pci/asihpi/hpidebug.h
@@ -1,7 +1,7 @@
/*****************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
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 71d32c868c92..456a758f04f6 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
#define SOURCEFILE_NAME "hpidspcd.c"
#include "hpidspcd.h"
#include "hpidebug.h"
+#include "hpi_version.h"
struct dsp_code_private {
/** Firmware descriptor */
@@ -32,9 +33,6 @@ struct dsp_code_private {
struct pci_dev *dev;
};
-#define HPI_VER_DECIMAL ((int)(HPI_VER_MAJOR(HPI_VER) * 10000 + \
- HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER)))
-
/*-------------------------------------------------------------------*/
short hpi_dsp_code_open(u32 adapter, void *os_data, struct dsp_code *dsp_code,
u32 *os_error_code)
@@ -66,22 +64,25 @@ short hpi_dsp_code_open(u32 adapter, void *os_data, struct dsp_code *dsp_code,
if ((header.type != 0x45444F43) || /* "CODE" */
(header.adapter != adapter)
|| (header.size != firmware->size)) {
- dev_printk(KERN_ERR, &dev->dev, "Invalid firmware file\n");
+ dev_printk(KERN_ERR, &dev->dev,
+ "Invalid firmware header size %d != file %zd\n",
+ header.size, firmware->size);
goto error2;
}
- if ((header.version / 100 & ~1) != (HPI_VER_DECIMAL / 100 & ~1)) {
+ if ((header.version >> 9) != (HPI_VER >> 9)) {
+ /* Consider even and subsequent odd minor versions to be compatible */
dev_printk(KERN_ERR, &dev->dev,
"Incompatible firmware version "
- "DSP image %d != Driver %d\n", header.version,
- HPI_VER_DECIMAL);
+ "DSP image %X != Driver %X\n", header.version,
+ HPI_VER);
goto error2;
}
- if (header.version != HPI_VER_DECIMAL) {
- dev_printk(KERN_WARNING, &dev->dev,
- "Firmware: release version mismatch DSP image %d != Driver %d\n",
- header.version, HPI_VER_DECIMAL);
+ if (header.version != HPI_VER) {
+ dev_printk(KERN_INFO, &dev->dev,
+ "Firmware: release version mismatch DSP image %X != Driver %X\n",
+ header.version, HPI_VER);
}
HPI_DEBUG_LOG(DEBUG, "dsp code %s opened\n", fw_name);
@@ -108,11 +109,8 @@ error1:
/*-------------------------------------------------------------------*/
void hpi_dsp_code_close(struct dsp_code *dsp_code)
{
- if (dsp_code->pvt->firmware) {
- HPI_DEBUG_LOG(DEBUG, "dsp code closed\n");
- release_firmware(dsp_code->pvt->firmware);
- dsp_code->pvt->firmware = NULL;
- }
+ HPI_DEBUG_LOG(DEBUG, "dsp code closed\n");
+ release_firmware(dsp_code->pvt->firmware);
kfree(dsp_code->pvt);
}
diff --git a/sound/pci/asihpi/hpidspcd.h b/sound/pci/asihpi/hpidspcd.h
index b22881122f19..659d19ca6d42 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
#include "hpi_internal.h"
-/** Code header version is decimal encoded e.g. 4.06.10 is 40601 */
-#define HPI_VER_DECIMAL ((int)(HPI_VER_MAJOR(HPI_VER) * 10000 + \
-HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER)))
-
/** Header structure for dsp firmware file
This structure must match that used in s2bin.c for generation of asidsp.bin
*/
diff --git a/sound/pci/asihpi/hpifunc.c b/sound/pci/asihpi/hpifunc.c
index ebb568d695f1..510e56cffd31 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,
duration_ms, HPI_VOLUME_AUTOFADE_LOG);
}
+u16 hpi_volume_query_auto_fade_profile(const u32 h_volume, const u32 i,
+ u16 *profile)
+{
+ u16 e;
+ u32 u;
+ e = hpi_control_query(h_volume, HPI_VOLUME_AUTOFADE, i, 0, &u);
+ *profile = (u16)u;
+ return e;
+}
+
u16 hpi_vox_set_threshold(u32 h_control, short an_gain0_01dB)
{
struct hpi_message hm;
diff --git a/sound/pci/asihpi/hpimsginit.c b/sound/pci/asihpi/hpimsginit.c
index 52400a6b5f15..032d563e3708 100644
--- a/sound/pci/asihpi/hpimsginit.c
+++ b/sound/pci/asihpi/hpimsginit.c
@@ -1,7 +1,7 @@
/******************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
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 bfd330d78b58..5b48708c7d1e 100644
--- a/sound/pci/asihpi/hpimsginit.h
+++ b/sound/pci/asihpi/hpimsginit.h
@@ -1,7 +1,7 @@
/******************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
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 2e779421a618..d4790ddc225c 100644
--- a/sound/pci/asihpi/hpimsgx.c
+++ b/sound/pci/asihpi/hpimsgx.c
@@ -1,7 +1,7 @@
/******************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
@@ -22,6 +22,7 @@ Extended Message Function With Response Caching
*****************************************************************************/
#define SOURCEFILE_NAME "hpimsgx.c"
#include "hpi_internal.h"
+#include "hpi_version.h"
#include "hpimsginit.h"
#include "hpicmn.h"
#include "hpimsgx.h"
diff --git a/sound/pci/asihpi/hpimsgx.h b/sound/pci/asihpi/hpimsgx.h
index fd49e7542a88..37f3efd95a70 100644
--- a/sound/pci/asihpi/hpimsgx.h
+++ b/sound/pci/asihpi/hpimsgx.h
@@ -1,7 +1,7 @@
/******************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
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 f6b9517b4696..609156205562 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
#define SOURCEFILE_NAME "hpioctl.c"
#include "hpi_internal.h"
+#include "hpi_version.h"
#include "hpimsginit.h"
#include "hpidebug.h"
#include "hpimsgx.h"
@@ -65,9 +66,7 @@ static struct hpi_adapter adapters[HPI_MAX_ADAPTERS];
static void hpi_send_recv_f(struct hpi_message *phm, struct hpi_response *phr,
struct file *file)
{
- int adapter = phm->adapter_index;
-
- if ((adapter >= HPI_MAX_ADAPTERS || adapter < 0)
+ if ((phm->adapter_index >= HPI_MAX_ADAPTERS)
&& (phm->object != HPI_OBJ_SUBSYSTEM))
phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
else
@@ -178,19 +177,14 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
} else {
u16 __user *ptr = NULL;
u32 size = 0;
- u32 adapter_present;
/* -1=no data 0=read from user mem, 1=write to user mem */
int wrflag = -1;
- struct hpi_adapter *pa;
+ struct hpi_adapter *pa = NULL;
- if (hm->h.adapter_index < HPI_MAX_ADAPTERS) {
+ if (hm->h.adapter_index < ARRAY_SIZE(adapters))
pa = &adapters[hm->h.adapter_index];
- adapter_present = pa->type;
- } else {
- adapter_present = 0;
- }
- if (!adapter_present) {
+ if (!pa || !pa->adapter || !pa->adapter->type) {
hpi_init_response(&hr->r0, hm->h.object,
hm->h.function, HPI_ERROR_BAD_ADAPTER_NUMBER);
@@ -317,6 +311,7 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
const struct pci_device_id *pci_id)
{
int idx, nm;
+ int adapter_index;
unsigned int memlen;
struct hpi_message hm;
struct hpi_response hr;
@@ -345,8 +340,6 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
hm.adapter_index = HPI_ADAPTER_INDEX_INVALID;
- adapter.pci = pci_dev;
-
nm = HPI_MAX_ADAPTER_MEM_SPACES;
for (idx = 0; idx < nm; idx++) {
@@ -355,18 +348,16 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
if (pci_resource_flags(pci_dev, idx) & IORESOURCE_MEM) {
memlen = pci_resource_len(pci_dev, idx);
- adapter.ap_remapped_mem_base[idx] =
+ pci.ap_mem_base[idx] =
ioremap(pci_resource_start(pci_dev, idx),
memlen);
- if (!adapter.ap_remapped_mem_base[idx]) {
+ if (!pci.ap_mem_base[idx]) {
HPI_DEBUG_LOG(ERROR,
"ioremap failed, aborting\n");
/* unmap previously mapped pci mem space */
goto err;
}
}
-
- pci.ap_mem_base[idx] = adapter.ap_remapped_mem_base[idx];
}
pci.pci_dev = pci_dev;
@@ -378,6 +369,9 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
if (hr.error)
goto err;
+ adapter_index = hr.u.s.adapter_index;
+ adapter.adapter = hpi_find_adapter(adapter_index);
+
if (prealloc_stream_buf) {
adapter.p_buffer = vmalloc(prealloc_stream_buf);
if (!adapter.p_buffer) {
@@ -389,36 +383,32 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
}
}
- adapter.index = hr.u.s.adapter_index;
- adapter.type = hr.u.s.adapter_type;
-
hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
HPI_ADAPTER_OPEN);
- hm.adapter_index = adapter.index;
+ hm.adapter_index = adapter.adapter->index;
hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
if (hr.error)
goto err;
- adapter.snd_card_asihpi = NULL;
/* WARNING can't init mutex in 'adapter'
* and then copy it to adapters[] ?!?!
*/
- adapters[adapter.index] = adapter;
- mutex_init(&adapters[adapter.index].mutex);
- pci_set_drvdata(pci_dev, &adapters[adapter.index]);
+ adapters[adapter_index] = adapter;
+ mutex_init(&adapters[adapter_index].mutex);
+ pci_set_drvdata(pci_dev, &adapters[adapter_index]);
dev_printk(KERN_INFO, &pci_dev->dev,
- "probe succeeded for ASI%04X HPI index %d\n", adapter.type,
- adapter.index);
+ "probe succeeded for ASI%04X HPI index %d\n",
+ adapter.adapter->type, adapter_index);
return 0;
err:
for (idx = 0; idx < HPI_MAX_ADAPTER_MEM_SPACES; idx++) {
- if (adapter.ap_remapped_mem_base[idx]) {
- iounmap(adapter.ap_remapped_mem_base[idx]);
- adapter.ap_remapped_mem_base[idx] = NULL;
+ if (pci.ap_mem_base[idx]) {
+ iounmap(pci.ap_mem_base[idx]);
+ pci.ap_mem_base[idx] = NULL;
}
}
@@ -437,19 +427,20 @@ void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev)
struct hpi_message hm;
struct hpi_response hr;
struct hpi_adapter *pa;
+ struct hpi_pci pci;
+
pa = pci_get_drvdata(pci_dev);
+ pci = pa->adapter->pci;
hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
HPI_ADAPTER_DELETE);
- hm.adapter_index = pa->index;
+ hm.adapter_index = pa->adapter->index;
hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
/* unmap PCI memory space, mapped during device init. */
for (idx = 0; idx < HPI_MAX_ADAPTER_MEM_SPACES; idx++) {
- if (pa->ap_remapped_mem_base[idx]) {
- iounmap(pa->ap_remapped_mem_base[idx]);
- pa->ap_remapped_mem_base[idx] = NULL;
- }
+ if (pci.ap_mem_base[idx])
+ iounmap(pci.ap_mem_base[idx]);
}
if (pa->p_buffer)
@@ -461,7 +452,7 @@ void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev)
"remove %04x:%04x,%04x:%04x,%04x," " HPI index %d.\n",
pci_dev->vendor, pci_dev->device,
pci_dev->subsystem_vendor, pci_dev->subsystem_device,
- pci_dev->devfn, pa->index);
+ pci_dev->devfn, pa->adapter->index);
memset(pa, 0, sizeof(*pa));
}
diff --git a/sound/pci/asihpi/hpioctl.h b/sound/pci/asihpi/hpioctl.h
index 847f72f03fe1..2614aff672e2 100644
--- a/sound/pci/asihpi/hpioctl.h
+++ b/sound/pci/asihpi/hpioctl.h
@@ -1,7 +1,7 @@
/*******************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
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 ff2a19b544fa..2d7d1c2e1d0d 100644
--- a/sound/pci/asihpi/hpios.c
+++ b/sound/pci/asihpi/hpios.c
@@ -1,7 +1,7 @@
/******************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
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 2f605e34bad0..c5cef113c209 100644
--- a/sound/pci/asihpi/hpios.h
+++ b/sound/pci/asihpi/hpios.h
@@ -1,7 +1,7 @@
/******************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
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)
#define hpios_alistlock_lock(obj) spin_lock(&((obj)->list_lock.lock))
#define hpios_alistlock_unlock(obj) spin_unlock(&((obj)->list_lock.lock))
+struct snd_card;
+
+/** pci drvdata points to an instance of this struct */
struct hpi_adapter {
+ struct hpi_adapter_obj *adapter;
+ struct snd_card *snd_card;
+
/* mutex prevents contention for one card
between multiple user programs (via ioctl) */
struct mutex mutex;
- u16 index;
- u16 type;
-
- /* ALSA card structure */
- void *snd_card_asihpi;
-
char *p_buffer;
size_t buffer_size;
- struct pci_dev *pci;
- void __iomem *ap_remapped_mem_base[HPI_MAX_ADAPTER_MEM_SPACES];
};
#endif
diff --git a/sound/pci/asihpi/hpipcida.h b/sound/pci/asihpi/hpipcida.h
index bb30868ce1a3..db570ddf64b3 100644
--- a/sound/pci/asihpi/hpipcida.h
+++ b/sound/pci/asihpi/hpipcida.h
@@ -1,7 +1,7 @@
/******************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as