diff options
Diffstat (limited to 'sound/pci/asihpi')
| -rw-r--r-- | sound/pci/asihpi/asihpi.c | 473 | ||||
| -rw-r--r-- | sound/pci/asihpi/hpi.h | 86 | ||||
| -rw-r--r-- | sound/pci/asihpi/hpi6000.c | 72 | ||||
| -rw-r--r-- | sound/pci/asihpi/hpi6000.h | 2 | ||||
| -rw-r--r-- | sound/pci/asihpi/hpi6205.c | 109 | ||||
| -rw-r--r-- | sound/pci/asihpi/hpi6205.h | 25 | ||||
| -rw-r--r-- | sound/pci/asihpi/hpi_internal.h | 244 | ||||
| -rw-r--r-- | sound/pci/asihpi/hpi_version.h | 32 | ||||
| -rw-r--r-- | sound/pci/asihpi/hpicmn.c | 52 | ||||
| -rw-r--r-- | sound/pci/asihpi/hpicmn.h | 13 | ||||
| -rw-r--r-- | sound/pci/asihpi/hpidebug.c | 2 | ||||
| -rw-r--r-- | sound/pci/asihpi/hpidebug.h | 2 | ||||
| -rw-r--r-- | sound/pci/asihpi/hpidspcd.c | 161 | ||||
| -rw-r--r-- | sound/pci/asihpi/hpidspcd.h | 68 | ||||
| -rw-r--r-- | sound/pci/asihpi/hpifunc.c | 96 | ||||
| -rw-r--r-- | sound/pci/asihpi/hpimsginit.c | 6 | ||||
| -rw-r--r-- | sound/pci/asihpi/hpimsginit.h | 2 | ||||
| -rw-r--r-- | sound/pci/asihpi/hpimsgx.c | 9 | ||||
| -rw-r--r-- | sound/pci/asihpi/hpimsgx.h | 2 | ||||
| -rw-r--r-- | sound/pci/asihpi/hpioctl.c | 100 | ||||
| -rw-r--r-- | sound/pci/asihpi/hpioctl.h | 8 | ||||
| -rw-r--r-- | sound/pci/asihpi/hpios.c | 16 | ||||
| -rw-r--r-- | sound/pci/asihpi/hpios.h | 18 | ||||
| -rw-r--r-- | sound/pci/asihpi/hpipcida.h | 2 |
24 files changed, 739 insertions, 861 deletions
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index 2ca6f4f85b4..901c9490398 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c @@ -23,16 +23,19 @@ */ #include "hpi_internal.h" +#include "hpi_version.h" #include "hpimsginit.h" #include "hpioctl.h" +#include "hpicmn.h" + #include <linux/pci.h> -#include <linux/version.h> #include <linux/init.h> #include <linux/jiffies.h> #include <linux/slab.h> #include <linux/time.h> #include <linux/wait.h> +#include <linux/module.h> #include <sound/core.h> #include <sound/control.h> #include <sound/pcm.h> @@ -42,28 +45,10 @@ #include <sound/tlv.h> #include <sound/hwdep.h> - MODULE_LICENSE("GPL"); MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>"); -MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx"); - -#if defined CONFIG_SND_DEBUG -/* copied from pcm_lib.c, hope later patch will make that version public -and this copy can be removed */ -static void pcm_debug_name(struct snd_pcm_substream *substream, - char *name, size_t len) -{ - snprintf(name, len, "pcmC%dD%d%c:%d", - substream->pcm->card->number, - substream->pcm->device, - substream->stream ? 'c' : 'p', - substream->number); -} -#define DEBUG_NAME(substream, name) char name[16]; pcm_debug_name(substream, name, sizeof(name)) -#else -#define pcm_debug_name(s, n, l) do { } while (0) -#define DEBUG_NAME(name, substream) do { } while (0) -#endif +MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx " + HPI_VER_STRING); #if defined CONFIG_SND_DEBUG_VERBOSE /** @@ -82,8 +67,8 @@ static void pcm_debug_name(struct snd_pcm_substream *substream, 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."); @@ -138,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; @@ -154,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 */ @@ -305,7 +287,8 @@ static u16 handle_error(u16 err, int line, char *filename) static void print_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *p) { - DEBUG_NAME(substream, name); + char name[16]; + snd_pcm_debug_name(substream, name, sizeof(name)); snd_printd("%s HWPARAMS\n", name); snd_printd(" samplerate %d Hz\n", params_rate(p)); snd_printd(" channels %d\n", params_channels(p)); @@ -513,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)); @@ -577,8 +561,9 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, struct snd_card_asihpi *card = snd_pcm_substream_chip(substream); struct snd_pcm_substream *s; u16 e; - DEBUG_NAME(substream, name); + char name[16]; + snd_pcm_debug_name(substream, name, sizeof(name)); snd_printdd("%s trigger\n", name); switch (cmd) { @@ -742,7 +727,9 @@ static void snd_card_asihpi_timer_function(unsigned long data) int loops = 0; u16 state; u32 buffer_size, bytes_avail, samples_played, on_card_bytes; - DEBUG_NAME(substream, name); + char name[16]; + + snd_pcm_debug_name(substream, name, sizeof(name)); snd_printdd("%s snd_card_asihpi_timer_function\n", name); @@ -772,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; @@ -782,8 +768,11 @@ 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) { + unsigned long flags; + snd_pcm_stream_lock_irqsave(s, flags); snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); + snd_pcm_stream_unlock_irqrestore(s, flags); continue; } } else { @@ -903,8 +892,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); } } @@ -917,7 +906,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); } @@ -942,21 +933,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 @@ -971,41 +964,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 |= pcm_format_to_bits(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) @@ -1027,12 +1008,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); @@ -1044,8 +1032,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; @@ -1062,8 +1052,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; @@ -1129,15 +1117,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 */ @@ -1152,34 +1140,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); - if (!err) - err = hpi_instream_query_format(h_stream, - &hpi_format); + err = hpi_format_create(&hpi_format, asihpi->in_max_chans, + format, sample_rate, 128000, 0); if (!err) - pcmhw->formats |= - (1ULL << hpi_to_alsa_formats[format]); + err = hpi_instream_query_format(h_stream, &hpi_format); + if (!err && (hpi_to_alsa_formats[format] != -1)) + formats |= pcm_format_to_bits(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); @@ -1187,10 +1163,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); @@ -1199,7 +1175,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; @@ -1207,9 +1182,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 | @@ -1255,22 +1238,27 @@ 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 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! */ - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, - &snd_card_asihpi_playback_mmap_ops); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, - &snd_card_asihpi_capture_mmap_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, + &snd_card_asihpi_playback_mmap_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, + &snd_card_asihpi_capture_mmap_ops); pcm->private_data = asihpi; pcm->info_flags = 0; @@ -1294,7 +1282,7 @@ struct hpi_control { u16 dst_node_type; u16 dst_node_index; u16 band; - char name[44]; /* copied to snd_ctl_elem_id.name[44]; */ + char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; /* copied to snd_ctl_elem_id.name[44]; */ }; static const char * const asihpi_tuner_band_names[] = { @@ -1324,10 +1312,12 @@ static const char * const asihpi_src_names[] = { "RF", "Clock", "Bitstream", - "Microphone", - "Cobranet", + "Mic", + "Net", "Analog", "Adapter", + "RTP", + "Internal" }; compile_time_assert( @@ -1342,8 +1332,9 @@ static const char * const asihpi_dst_names[] = { "Digital", "RF", "Speaker", - "Cobranet Out", - "Analog" + "Net", + "Analog", + "RTP", }; compile_time_assert( @@ -1421,6 +1412,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; @@ -1435,8 +1427,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; @@ -1477,11 +1473,40 @@ static int snd_asihpi_volume_put(struct snd_kcontrol *kcontrol, static const DECLARE_TLV_DB_SCALE(db_scale_100, -10000, VOL_STEP_mB, 0); -static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi, - struct hpi_control *hpi_ctl) +#define snd_asihpi_volume_mute_info snd_ctl_boolean_mono_info + +static int snd_asihpi_volume_mute_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u32 h_control = kcontrol->private_value; + u32 mute; + + hpi_handle_error(hpi_volume_get_mute(h_control, &mute)); + ucontrol->value.integer.value[0] = mute ? 0 : 1; + + return 0; +} + +static int snd_asihpi_volume_mute_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u32 h_control = kcontrol->private_value; + int change = 1; + /* HPI currently only supports all or none muting of multichannel volume + ALSA Switch element has opposite sense to HPI mute: on==unmuted, off=muted + */ + int mute = ucontrol->value.integer.value[0] ? 0 : HPI_BITMASK_ALL_CHANNELS; + hpi_handle_error(hpi_volume_set_mute(h_control, mute)); + return change; +} + +static int snd_asihpi_volume_add(struct snd_card_asihpi *asihpi, + struct hpi_control *hpi_ctl) { struct snd_card *card = asihpi->card; struct snd_kcontrol_new snd_control; + int err; + u32 mute; asihpi_ctl_init(&snd_control, hpi_ctl, "Volume"); snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | @@ -1491,7 +1516,19 @@ static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi, snd_control.put = snd_asihpi_volume_put; snd_control.tlv.p = db_scale_100; - return ctl_add(card, &snd_control, asihpi); + err = ctl_add(card, &snd_control, asihpi); + if (err) + return err; + + if (hpi_volume_get_mute(hpi_ctl->h_control, &mute) == 0) { + asihpi_ctl_init(&snd_control, hpi_ctl, "Switch"); + snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; + snd_control.info = snd_asihpi_volume_mute_info; + snd_control.get = snd_asihpi_volume_mute_get; + snd_control.put = snd_asihpi_volume_mute_put; + err = ctl_add(card, &snd_control, asihpi); + } + return err; } /*------------------------------------------------------------ @@ -1559,8 +1596,8 @@ static int snd_asihpi_level_put(struct snd_kcontrol *kcontrol, static const DECLARE_TLV_DB_SCALE(db_scale_level, -1000, 100, 0); -static int __devinit snd_asihpi_level_add(struct snd_card_asihpi *asihpi, - struct hpi_control *hpi_ctl) +static int snd_asihpi_level_add(struct snd_card_asihpi *asihpi, + struct hpi_control *hpi_ctl) { struct snd_card *card = asihpi->card; struct snd_kcontrol_new snd_control; @@ -1681,8 +1718,8 @@ static int snd_asihpi_aesebu_rxstatus_get(struct snd_kcontrol *kcontrol, return 0; } -static int __devinit snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi, - struct hpi_control *hpi_ctl) +static int snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi, + struct hpi_control *hpi_ctl) { struct snd_card *card = asihpi->card; struct snd_kcontrol_new snd_control; @@ -1719,8 +1756,8 @@ static int snd_asihpi_aesebu_tx_format_put(struct snd_kcontrol *kcontrol, } -static int __devinit snd_asihpi_aesebu_tx_add(struct snd_card_asihpi *asihpi, - struct hpi_control *hpi_ctl) +static int snd_asihpi_aesebu_tx_add(struct snd_card_asihpi *asihpi, + struct hpi_control *hpi_ctl) { struct snd_card *card = asihpi->card; struct snd_kcontrol_new snd_control; @@ -1877,6 +1914,7 @@ static int snd_asihpi_tuner_band_put(struct snd_kcontrol *kcontrol, struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol); */ u32 h_control = kcontrol->private_value; + unsigned int idx; u16 band; u16 tuner_bands[HPI_TUNER_BAND_LAST]; u32 num_bands = 0; @@ -1884,7 +1922,10 @@ static int snd_asihpi_tuner_band_put(struct snd_kcontrol *kcontrol, num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands, HPI_TUNER_BAND_LAST); - band = tuner_bands[ucontrol->value.enumerated.item[0]]; + idx = ucontrol->value.enumerated.item[0]; + if (idx >= ARRAY_SIZE(tuner_bands)) + idx = ARRAY_SIZE(tuner_bands) - 1; + band = tuner_bands[idx]; hpi_handle_error(hpi_tuner_set_band(h_control, band)); return 1; @@ -1962,8 +2003,8 @@ static int snd_asihpi_tuner_freq_put(struct snd_kcontrol *kcontrol, } /* Tuner control group initializer */ -static int __devinit snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi, - struct hpi_control *hpi_ctl) +static int snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi, + struct hpi_control *hpi_ctl) { struct snd_card *card = asihpi->card; struct snd_kcontrol_new snd_control; @@ -2003,8 +2044,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; @@ -2059,8 +2107,8 @@ static int snd_asihpi_meter_get(struct snd_kcontrol *kcontrol, return 0; } -static int __devinit snd_asihpi_meter_add(struct snd_card_asihpi *asihpi, - struct hpi_control *hpi_ctl, int subidx) +static int snd_asihpi_meter_add(struct snd_card_asihpi *asihpi, + struct hpi_control *hpi_ctl, int subidx) { struct snd_card *card = asihpi->card; struct snd_kcontrol_new snd_control; @@ -2173,8 +2221,8 @@ static int snd_asihpi_mux_put(struct snd_kcontrol *kcontrol, } -static int __devinit snd_asihpi_mux_add(struct snd_card_asihpi *asihpi, - struct hpi_control *hpi_ctl) +static int snd_asihpi_mux_add(struct snd_card_asihpi *asihpi, + struct hpi_control *hpi_ctl) { struct snd_card *card = asihpi->card; struct snd_kcontrol_new snd_control; @@ -2218,6 +2266,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; @@ -2259,8 +2310,8 @@ static int snd_asihpi_cmode_put(struct snd_kcontrol *kcontrol, } -static int __devinit snd_asihpi_cmode_add(struct snd_card_asihpi *asihpi, - struct hpi_control *hpi_ctl) +static int snd_asihpi_cmode_add(struct snd_card_asihpi *asihpi, + struct hpi_control *hpi_ctl) { struct snd_card *card = asihpi->card; struct snd_kcontrol_new snd_control; @@ -2337,7 +2388,8 @@ static int snd_asihpi_clksrc_put(struct snd_kcontrol *kcontrol, struct snd_card_asihpi *asihpi = (struct snd_card_asihpi *)(kcontrol->private_data); struct clk_cache *clkcache = &asihpi->cc; - int change, item; + unsigned int item; + int change; u32 h_control = kcontrol->private_value; change = 1; @@ -2427,8 +2479,8 @@ static int snd_asihpi_clkrate_get(struct snd_kcontrol *kcontrol, return 0; } -static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi, - struct hpi_control *hpi_ctl) +static int snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi, + struct hpi_control *hpi_ctl) { struct snd_card *card = asihpi->card; struct snd_kcontrol_new snd_control; @@ -2504,9 +2556,9 @@ static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi, Mixer ------------------------------------------------------------*/ -static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi) +static int snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi) { - struct snd_card *card = asihpi->card; + struct snd_card *card; unsigned int idx = 0; unsigned int subindex = 0; int err; @@ -2514,10 +2566,11 @@ static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi) if (snd_BUG_ON(!asihpi)) return -EINVAL; + card = asihpi->card; 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) @@ -2614,7 +2667,7 @@ static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi) hpi_ctl.dst_node_type, hpi_ctl.dst_node_index); continue; - }; + } if (err < 0) return err; } @@ -2635,24 +2688,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, @@ -2660,19 +2722,16 @@ 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) +static void snd_asihpi_proc_init(struct snd_card_asihpi *asihpi) { struct snd_info_entry *entry; @@ -2714,8 +2773,8 @@ static int snd_asihpi_hpi_ioctl(struct snd_hwdep *hw, struct file *file, /* results in /dev/snd/hwC#D0 file for each card with index # also /proc/asound/hwdep will contain '#-00: asihpi (HPI) for each card' */ -static int __devinit snd_asihpi_hpi_new(struct snd_card_asihpi *asihpi, - int device, struct snd_hwdep **rhwdep) +static int snd_asihpi_hpi_new(struct snd_card_asihpi *asihpi, + int device, struct snd_hwdep **rhwdep) { struct snd_hwdep *hw; int err; @@ -2739,96 +2798,71 @@ static int __devinit snd_asihpi_hpi_new(struct snd_card_asihpi *asihpi, /*------------------------------------------------------------ CARD ------------------------------------------------------------*/ -static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, - const struct pci_device_id *pci_id) +static int 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, - sizeof(struct snd_card_asihpi), - &card); + err = snd_card_new(&pci_dev->dev, adapter_index, id[adapter_index], + THIS_MODULE, sizeof(struct snd_card_asihpi), &card); if (err < 0) { /* if that fails, try the default index==next available */ - err = - snd_card_create(index[dev], id[dev], - THIS_MODULE, - sizeof(struct snd_card_asihpi), - &card); + err = snd_card_new(&pci_dev->dev, index[dev], id[dev], + THIS_MODULE, sizeof(struct snd_card_asihpi), + &card); if (err < 0) 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) @@ -2837,7 +2871,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); @@ -2845,7 +2879,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) { @@ -2853,13 +2887,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; @@ -2886,13 +2929,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; } @@ -2903,12 +2947,11 @@ __nodev: } -static void __devexit snd_asihpi_remove(struct pci_dev *pci_dev) +static void 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); } @@ -2924,11 +2967,11 @@ static DEFINE_PCI_DEVICE_TABLE(asihpi_pci_tbl) = { MODULE_DEVICE_TABLE(pci, asihpi_pci_tbl); static struct pci_driver driver = { - .name = "asihpi", + .name = KBUILD_MODNAME, .id_table = asihpi_pci_tbl, .probe = snd_asihpi_probe, - .remove = __devexit_p(snd_asihpi_remove), -#ifdef CONFIG_PM + .remove = snd_asihpi_remove, +#ifdef CONFIG_PM_SLEEP /* .suspend = snd_asihpi_suspend, .resume = snd_asihpi_resume, */ #endif diff --git a/sound/pci/asihpi/hpi.h b/sound/pci/asihpi/hpi.h index 255429c32c1..20887241a3a 100644 --- a/sound/pci/asihpi/hpi.h +++ b/sound/pci/asihpi/hpi.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 @@ -30,27 +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)) - -/* Use single digits for versions less that 10 to avoid octal. */ -#define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 6, 0) -#define HPI_VER_STRING "4.06.00" - -/* Library version as documented in hpi-api-versions.txt */ -#define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(9, 0, 0) #include <linux/types.h> -#define HPI_BUILD_EXCLUDE_DEPRECATED #define HPI_BUILD_KERNEL_MODE /******************************************************************************/ @@ -211,8 +192,12 @@ enum HPI_SOURCENODES { HPI_SOURCENODE_COBRANET = 109, HPI_SOURCENODE_ANALOG = 110, /**< analog input node. */ HPI_SOURCENODE_ADAPTER = 111, /**< adapter node. */ + /** 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_INTERNAL = 113, /**< node internal to the device. */ /* !!!Update this AND hpidebug.h if you add a new sourcenode type!!! */ - HPI_SOURCENODE_LAST_INDEX = 111 /**< largest ID */ + HPI_SOURCENODE_LAST_INDEX = 113 /**< largest ID */ /* AX6 max sourcenode types = 15 */ }; @@ -228,7 +213,7 @@ enum HPI_DESTNODES { HPI_DESTNODE_NONE = 200, /** In Stream (Record) node. */ HPI_DESTNODE_ISTREAM = 201, - HPI_DESTNODE_LINEOUT = 202, /**< line out node. */ + HPI_DESTNODE_LINEOUT = 202, /**< line out node. */ HPI_DESTNODE_AESEBU_OUT = 203, /**< AES/EBU output node. */ HPI_DESTNODE_RF = 204, /**< RF output node. */ HPI_DESTNODE_SPEAKER = 205, /**< speaker output node. */ @@ -236,9 +221,11 @@ enum HPI_DESTNODES { Audio samples from the device are sent out on the Cobranet network.*/ HPI_DESTNODE_COBRANET = 206, HPI_DESTNODE_ANALOG = 207, /**< analog output node. */ - + /** 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, /* !!!Update this AND hpidebug.h if you add a new destnode type!!! */ - HPI_DESTNODE_LAST_INDEX = 207 /**< largest ID */ + HPI_DESTNODE_LAST_INDEX = 208 /**< largest ID */ /* AX6 max destnode types = 15 */ }; @@ -444,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 @@ -632,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 }; @@ -935,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, @@ -972,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, @@ -1014,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, @@ -1040,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 */ @@ -1072,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 @@ -1084,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 */ @@ -1105,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 { @@ -1138,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 @@ -1351,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); @@ -1360,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 df4aed5295d..2414d7a2239 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: @@ -359,7 +358,7 @@ void HPI_6000(struct hpi_message *phm, struct hpi_response *phr) HPI_ERROR_PROCESSING_MESSAGE); switch (phm->type) { - case HPI_TYPE_MESSAGE: + case HPI_TYPE_REQUEST: switch (phm->object) { case HPI_OBJ_SUBSYSTEM: subsys_message(phm, phr); @@ -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) */ @@ -538,7 +537,7 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao, HPI_DEBUG_LOG(VERBOSE, "send ADAPTER_GET_INFO\n"); memset(&hm, 0, sizeof(hm)); - hm.type = HPI_TYPE_MESSAGE; + hm.type = HPI_TYPE_REQUEST; hm.size = sizeof(struct hpi_message); hm.object = HPI_OBJ_ADAPTER; hm.function = HPI_ADAPTER_GET_INFO; @@ -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; @@ -946,11 +944,8 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao, } /* write the DSP code down into the DSPs memory */ - /*HpiDspCode_Open(nBootLoadFamily,&DspCode,pdwOsErrorCode); */ - dsp_code.ps_dev = pao->pci.pci_dev; - - error = hpi_dsp_code_open(boot_load_family, &dsp_code, - pos_error_code); + error = hpi_dsp_code_open(boot_load_family, pao->pci.pci_dev, + &dsp_code, pos_error_code); if (error) return error; @@ -1223,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; @@ -1261,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; @@ -1301,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; @@ -1417,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; @@ -1490,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; @@ -1554,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 */ @@ -1580,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); @@ -1600,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; @@ -1643,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; @@ -1743,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 4c7d507c0ec..7e0deeff5e7 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 9d5df54a6b4..4f2873880b1 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 */ @@ -373,6 +376,7 @@ static void instream_message(struct hpi_adapter_obj *pao, /** Entry point to this HPI backend * All calls to the HPI start here */ +static void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm, struct hpi_response *phr) { @@ -392,7 +396,7 @@ void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm, HPI_DEBUG_LOG(VERBOSE, "start of switch\n"); switch (phm->type) { - case HPI_TYPE_MESSAGE: + case HPI_TYPE_REQUEST: switch (phm->object) { case HPI_OBJ_SUBSYSTEM: subsys_message(pao, phm, phr); @@ -402,7 +406,6 @@ void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm, adapter_message(pao, phm, phr); break; - case HPI_OBJ_CONTROLEX: case HPI_OBJ_CONTROL: control_message(pao, phm, phr); break; @@ -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); @@ -634,11 +637,12 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, HPI_DEBUG_LOG(VERBOSE, "init ADAPTER_GET_INFO\n"); memset(&hm, 0, sizeof(hm)); - hm.type = HPI_TYPE_MESSAGE; + /* wAdapterIndex == version == 0 */ + hm.type = HPI_TYPE_REQUEST; hm.size = sizeof(hm); hm.object = HPI_OBJ_ADAPTER; hm.function = HPI_ADAPTER_GET_INFO; - hm.adapter_index = 0; + memset(&hr, 0, sizeof(hr)); hr.size = sizeof(hr); @@ -651,24 +655,19 @@ 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 = hr.u.ax.info.num_outstreams + hr.u.ax.info.num_instreams; - hpios_locked_mem_prepare((max_streams * 6) / 10, max_streams, - 65536, pao->pci.pci_dev); - HPI_DEBUG_LOG(VERBOSE, "got adapter info type %x index %d serial %d\n", hr.u.ax.info.adapter_type, hr.u.ax.info.adapter_index, 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; @@ -709,9 +708,6 @@ static void delete_adapter_obj(struct hpi_adapter_obj *pao) [i]); phw->outstream_host_buffer_size[i] = 0; } - - hpios_locked_mem_unprepare(pao->pci.pci_dev); - kfree(phw); } @@ -808,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; @@ -883,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, @@ -1085,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; @@ -1167,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, @@ -1371,9 +1367,8 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao, return err; /* write the DSP code down into the DSPs memory */ - dsp_code.ps_dev = pao->pci.pci_dev; - err = hpi_dsp_code_open(boot_code_id[dsp], &dsp_code, - pos_error_code); + err = hpi_dsp_code_open(boot_code_id[dsp], pao->pci.pci_dev, + &dsp_code, pos_error_code); if (err) return err; @@ -1620,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 */ @@ -1633,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 */ @@ -1645,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 */ @@ -1656,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? */ @@ -2084,13 +2079,13 @@ static u16 message_response_sequence(struct hpi_adapter_obj *pao, u16 err = 0; message_count++; - if (phm->size > sizeof(interface->u)) { + if (phm->size > sizeof(interface->u.message_buffer)) { phr->error = HPI_ERROR_MESSAGE_BUFFER_TOO_SMALL; - phr->specific_error = sizeof(interface->u); + phr->specific_error = sizeof(interface->u.message_buffer); phr->size = sizeof(struct hpi_response_header); HPI_DEBUG_LOG(ERROR, "message len %d too big for buffer %zd \n", phm->size, - sizeof(interface->u)); + sizeof(interface->u.message_buffer)); return 0; } @@ -2122,18 +2117,19 @@ static u16 message_response_sequence(struct hpi_adapter_obj *pao, /* read the result */ if (time_out) { - if (interface->u.response_buffer.size <= phr->size) + if (interface->u.response_buffer.response.size <= phr->size) memcpy(phr, &interface->u.response_buffer, - interface->u.response_buffer.size); + interface->u.response_buffer.response.size); else { HPI_DEBUG_LOG(ERROR, "response len %d too big for buffer %d\n", - interface->u.response_buffer.size, phr->size); + interface->u.response_buffer.response.size, + phr->size); memcpy(phr, &interface->u.response_buffer, sizeof(struct hpi_response_header)); phr->error = HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL; phr->specific_error = - interface->u.response_buffer.size; + interface->u.response_buffer.response.size; phr->size = sizeof(struct hpi_response_header); } } @@ -2202,23 +2198,6 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm, phm->u.d.u.data.data_size, H620_HIF_GET_DATA); break; - case HPI_CONTROL_SET_STATE: - if (phm->object == HPI_OBJ_CONTROLEX - && phm->u.cx.attribute == HPI_COBRANET_SET_DATA) - err = hpi6205_transfer_data(pao, - phm->u.cx.u.cobranet_bigdata.pb_data, - phm->u.cx.u.cobranet_bigdata.byte_count, - H620_HIF_SEND_DATA); - break; - - case HPI_CONTROL_GET_STATE: - if (phm->object == HPI_OBJ_CONTROLEX - && phm->u.cx.attribute == HPI_COBRANET_GET_DATA) - err = hpi6205_transfer_data(pao, - phm->u.cx.u.cobranet_bigdata.pb_data, - phr->u.cx.u.cobranet_data.byte_count, - H620_HIF_GET_DATA); - break; } phr->error = err; diff --git a/sound/pci/asihpi/hpi6205.h b/sound/pci/asihpi/hpi6205.h index df2f02c0c7b..ec0827b633a 100644 --- a/sound/pci/asihpi/hpi6205.h +++ b/sound/pci/asihpi/hpi6205.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 @@ -70,15 +70,28 @@ The Host located memory buffer that the 6205 will bus master in and out of. ************************************************************/ #define HPI6205_SIZEOF_DATA (16*1024) + +struct message_buffer_6205 { + struct hpi_message message; + char data[256]; +}; + +struct response_buffer_6205 { + struct hpi_response response; + char data[256]; +}; + +union buffer_6205 { + struct message_buffer_6205 message_buffer; + struct response_buffer_6205 response_buffer; + u8 b_data[HPI6205_SIZEOF_DATA]; +}; + struct bus_master_interface { u32 host_cmd; u32 dsp_ack; u32 transfer_size_in_bytes; - union { - struct hpi_message_header message_buffer; - struct hpi_response_header response_buffer; - u8 b_data[HPI6205_SIZEOF_DATA]; - } u; + union buffer_6205 u; struct controlcache_6205 control_cache; struct async_event_buffer_6205 async_buffer; struct hpi_hostbuffer_status diff --git a/sound/pci/asihpi/hpi_internal.h b/sound/pci/asihpi/hpi_internal.h index bf5eced76ba..bc86cb726d7 100644 --- a/sound/pci/asihpi/hpi_internal.h +++ b/sound/pci/asihpi/hpi_internal.h @@ -1,7 +1,7 @@ /****************************************************************************** AudioScience HPI driver - Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> + Copyright (C) 1997-2012 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 @@ -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) @@ -32,12 +33,6 @@ HPI internal definitions #include "hpios.h" /* physical memory allocation */ -void hpios_locked_mem_init(void - ); -void hpios_locked_mem_free_all(void - ); -#define hpios_locked_mem_prepare(a, b, c, d); -#define hpios_locked_mem_unprepare(a) /** Allocate and map an area of locked memory for bus master DMA operations. @@ -226,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), @@ -247,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 @@ -364,10 +359,12 @@ Used in DLL to indicate device not present #define HPI_ADAPTER_ASI(f) (f) enum HPI_MESSAGE_TYPES { - HPI_TYPE_MESSAGE = 1, + HPI_TYPE_REQUEST = 1, HPI_TYPE_RESPONSE = 2, HPI_TYPE_DATA = 3, - HPI_TYPE_SSX2BYPASS_MESSAGE = 4 + HPI_TYPE_SSX2BYPASS_MESSAGE = 4, + HPI_TYPE_COMMAND = 5, + HPI_TYPE_NOTIFICATION = 6 }; enum HPI_OBJECT_TYPES { @@ -383,7 +380,7 @@ enum HPI_OBJECT_TYPES { HPI_OBJ_WATCHDOG = 10, HPI_OBJ_CLOCK = 11, HPI_OBJ_PROFILE = 12, - HPI_OBJ_CONTROLEX = 13, + /* HPI_ OBJ_ CONTROLEX = 13, */ HPI_OBJ_ASYNCEVENT = 14 #define HPI_OBJ_MAXINDEX 14 }; @@ -397,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), @@ -434,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), @@ -499,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), @@ -608,7 +606,7 @@ struct hpi_data_compat32 { #endif struct hpi_buffer { - /** placehoder for backward compatibility (see dwBufferSize) */ + /** placeholder for backward compatibility (see dwBufferSize) */ struct hpi_msg_format reserved; u32 command; /**< HPI_BUFFER_CMD_xxx*/ u32 pci_address; /**< PCI physical address of buffer for DSP DMA */ @@ -622,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; @@ -665,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; @@ -682,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 { @@ -728,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; }; @@ -912,95 +888,13 @@ union hpi_control_union_res { u32 remaining_chars; } chars8; char c_data12[12]; -}; - -/* HPI_CONTROLX_STRUCTURES */ - -/* Message */ - -/** Used for all HMI variables where max length <= 8 bytes -*/ -struct hpi_controlx_msg_cobranet_data { - u32 hmi_address; - u32 byte_count; - u32 data[2]; -}; - -/** Used for string data, and for packet bridge -*/ -struct hpi_controlx_msg_cobranet_bigdata { - u32 hmi_address; - u32 byte_count; - u8 *pb_data; -#ifndef HPI64BIT - u32 padding; -#endif -}; - -/** Used for PADS control reading of string fields. -*/ -struct hpi_controlx_msg_pad_data { - u32 field; - u32 byte_count; - u8 *pb_data; -#ifndef HPI64BIT - u32 padding; -#endif -}; - -/** Used for generic data -*/ - -struct hpi_controlx_msg_generic { - u32 param1; - u32 param2; -}; - -struct hpi_controlx_msg { - u16 attribute; /* control attribute or property */ - u16 saved_index; union { - struct hpi_controlx_msg_cobranet_data cobranet_data; - struct hpi_controlx_msg_cobranet_bigdata cobranet_bigdata; - struct hpi_controlx_msg_generic generic; - struct hpi_controlx_msg_pad_data pad_data; - /*struct param_value universal_value; */ - /* nothing extra to send for status read */ - } u; -}; - -/* Response */ -/** -*/ -struct hpi_controlx_res_cobranet_data { - u32 byte_count; - u32 data[2]; -}; - -struct hpi_controlx_res_cobranet_bigdata { - u32 byte_count; -}; - -struct hpi_controlx_res_cobranet_status { - u32 status; - u32 readable_size; - u32 writeable_size; -}; - -struct hpi_controlx_res_generic { - u32 param1; - u32 param2; -}; - -struct hpi_controlx_res { - union { - struct hpi_controlx_res_cobranet_bigdata cobranet_bigdata; - struct hpi_controlx_res_cobranet_data cobranet_data; - struct hpi_controlx_res_cobranet_status cobranet_status; - struct hpi_controlx_res_generic generic; - /*struct param_info universal_info; */ - /*struct param_value universal_value; */ - } u; + struct { + u32 status; + u32 readable_size; + u32 writeable_size; + } status; + } cobranet; }; struct hpi_nvmemory_msg { @@ -1126,7 +1020,6 @@ struct hpi_message { /* identical to struct hpi_control_msg, but field naming is improved */ struct hpi_control_union_msg cu; - struct hpi_controlx_msg cx; /* extended mixer control; */ struct hpi_nvmemory_msg n; struct hpi_gpio_msg l; /* digital i/o */ struct hpi_watchdog_msg w; @@ -1151,7 +1044,7 @@ struct hpi_message { sizeof(struct hpi_message_header) + sizeof(struct hpi_watchdog_msg),\ sizeof(struct hpi_message_header) + sizeof(struct hpi_clock_msg),\ sizeof(struct hpi_message_header) + sizeof(struct hpi_profile_msg),\ - sizeof(struct hpi_message_header) + sizeof(struct hpi_controlx_msg),\ + sizeof(struct hpi_message_header), /* controlx obj removed */ \ sizeof(struct hpi_message_header) + sizeof(struct hpi_async_msg) \ } @@ -1188,7 +1081,6 @@ struct hpi_response { struct hpi_control_res c; /* mixer control; */ /* identical to hpi_control_res, but field naming is improved */ union hpi_control_union_res cu; - struct hpi_controlx_res cx; /* extended mixer control; */ struct hpi_nvmemory_res n; struct hpi_gpio_res l; /* digital i/o */ struct hpi_watchdog_res w; @@ -1213,7 +1105,7 @@ struct hpi_response { sizeof(struct hpi_response_header) + sizeof(struct hpi_watchdog_res),\ sizeof(struct hpi_response_header) + sizeof(struct hpi_clock_res),\ sizeof(struct hpi_response_header) + sizeof(struct hpi_profile_res),\ - sizeof(struct hpi_response_header) + sizeof(struct hpi_controlx_res),\ + sizeof(struct hpi_response_header), /* controlx obj removed */ \ sizeof(struct hpi_response_header) + sizeof(struct hpi_async_res) \ } @@ -1238,73 +1130,32 @@ 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_res_adapter_debug_read { struct hpi_response_header h; - u8 pad_to_version0_size[sizeof(struct hpi_response) - /* V0 res */ - sizeof(struct hpi_response_header)]; + u8 bytes[1024]; }; -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_cobranet_hmi { + u16 attribute; + u16 padding; + u32 hmi_address; + u32 byte_count; }; -struct hpi_msg_adapter_program_flash { +struct hpi_msg_cobranet_hmiwrite { 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_cobranet_hmi p; + u8 bytes[256]; }; -struct hpi_msg_adapter_debug_read { +struct hpi_msg_cobranet_hmiread { struct hpi_message_header h; - u32 dsp_address; - u32 count_bytes; + struct hpi_msg_cobranet_hmi p; }; -struct hpi_res_adapter_debug_read { +struct hpi_res_cobranet_hmiread { struct hpi_response_header h; + u32 byte_count; u8 bytes[256]; }; @@ -1338,7 +1189,6 @@ struct hpi_msg_payload_v0 { union hpi_mixerx_msg mx; struct hpi_control_msg c; struct hpi_control_union_msg cu; - struct hpi_controlx_msg cx; struct hpi_nvmemory_msg n; struct hpi_gpio_msg l; struct hpi_watchdog_msg w; @@ -1358,7 +1208,6 @@ struct hpi_res_payload_v0 { union hpi_mixerx_res mx; struct hpi_control_res c; union hpi_control_union_res cu; - struct hpi_controlx_res cx; struct hpi_nvmemory_res n; struct hpi_gpio_res l; struct hpi_watchdog_res w; @@ -1493,12 +1342,6 @@ struct hpi_control_cache_microphone { char temp_padding[6]; }; -struct hpi_control_cache_generic { - struct hpi_control_cache_info i; - u32 dw1; - u32 dw2; -}; - struct hpi_control_cache_single { union { struct hpi_control_cache_info i; @@ -1514,7 +1357,6 @@ struct hpi_control_cache_single { struct hpi_control_cache_silencedetector silence; struct hpi_control_cache_sampleclock clk; struct hpi_control_cache_microphone microphone; - struct hpi_control_cache_generic generic; } u; }; @@ -1534,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 00000000000..e9146e53bd5 --- /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 b15a02e91f8..7ed5c26c373 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 @@ -57,7 +57,7 @@ u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr) } if (phr->function != phm->function) { - HPI_DEBUG_LOG(ERROR, "header type %d invalid\n", + HPI_DEBUG_LOG(ERROR, "header function %d invalid\n", phr->function); return HPI_ERROR_INVALID_RESPONSE; } @@ -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; } } @@ -315,8 +315,7 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache, short found = 1; struct hpi_control_cache_info *pI; struct hpi_control_cache_single *pC; - struct hpi_control_cache_pad *p_pad; - + size_t response_size; if (!find_control(phm->obj_index, p_cache, &pI)) { HPI_DEBUG_LOG(VERBOSE, "HPICMN find_control() failed for adap %d\n", @@ -325,12 +324,18 @@ 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 = + sizeof(struct hpi_response_header) + + sizeof(struct hpi_control_res); /* pC is the default cached control strucure. May be cast to something else in the following switch statement. */ pC = (struct hpi_control_cache_single *)pI; - p_pad = (struct hpi_control_cache_pad *)pI; switch (pI->control_type) { @@ -528,10 +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) - phr->size = - sizeof(struct hpi_response_header) + - sizeof(struct hpi_control_res); + if (found) { + phr->size = (u16)response_size; + phr->type = HPI_TYPE_RESPONSE; + phr->object = phm->object; + phr->function = phm->function; + } return found; } @@ -630,13 +637,12 @@ struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count, if (!p_cache) return NULL; - p_cache->p_info = - kmalloc(sizeof(*p_cache->p_info) * control_count, GFP_KERNEL); + p_cache->p_info = kcalloc(control_count, sizeof(*p_cache->p_info), + GFP_KERNEL); if (!p_cache->p_info) { kfree(p_cache); return NULL; } - memset(p_cache->p_info, 0, sizeof(*p_cache->p_info) * control_count); p_cache->cache_size_in_bytes = size_in_bytes; p_cache->control_count = control_count; p_cache->p_cache = p_dsp_control_buffer; @@ -682,7 +688,7 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) void HPI_COMMON(struct hpi_message *phm, struct hpi_response *phr) { switch (phm->type) { - case HPI_TYPE_MESSAGE: + case HPI_TYPE_REQUEST: switch (phm->object) { case HPI_OBJ_SUBSYSTEM: subsys_message(phm, phr); 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 @@ /** 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 b52baf62791..ac86a1f1d3b 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 940f54c3c53..2c9af2329d3 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 5c6ea113d21..ac916377001 100644 --- a/sound/pci/asihpi/hpidspcd.c +++ b/sound/pci/asihpi/hpidspcd.c @@ -1,8 +1,8 @@ /***********************************************************************/ -/*! +/** 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,158 +18,127 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA \file -Functions for reading DSP code to load into DSP - -(Linux only:) If DSPCODE_FIRMWARE_LOADER is defined, code is read using +Functions for reading DSP code using hotplug firmware loader from individual dsp code files - -If neither of the above is defined, code is read from linked arrays. -DSPCODE_ARRAY is defined. - -HPI_INCLUDE_**** must be defined -and the appropriate hzz?????.c or hex?????.c linked in - - */ +*/ /***********************************************************************/ #define SOURCEFILE_NAME "hpidspcd.c" #include "hpidspcd.h" #include "hpidebug.h" +#include "hpi_version.h" -/** - Header structure for binary dsp code file (see asidsp.doc) - This structure must match that used in s2bin.c for generation of asidsp.bin - */ - -#ifndef DISABLE_PRAGMA_PACK1 -#pragma pack(push, 1) -#endif - -struct code_header { - u32 size; - char type[4]; - u32 adapter; - u32 version; - u32 crc; +struct dsp_code_private { + /** Firmware descriptor */ + const struct firmware *firmware; + struct pci_dev *dev; }; -#ifndef DISABLE_PRAGMA_PACK1 -#pragma pack(pop) -#endif - -#define HPI_VER_DECIMAL ((int)(HPI_VER_MAJOR(HPI_VER) * 10000 + \ - HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER))) - -/***********************************************************************/ -#include <linux/pci.h> /*-------------------------------------------------------------------*/ -short hpi_dsp_code_open(u32 adapter, struct dsp_code *ps_dsp_code, - u32 *pos_error_code) +short hpi_dsp_code_open(u32 adapter, void *os_data, struct dsp_code *dsp_code, + u32 *os_error_code) { - const struct firmware *ps_firmware = ps_dsp_code->ps_firmware; + const struct firmware *firmware; + struct pci_dev *dev = os_data; struct code_header header; char fw_name[20]; + short err_ret = HPI_ERROR_DSP_FILE_NOT_FOUND; int err; sprintf(fw_name, "asihpi/dsp%04x.bin", adapter); - err = request_firmware(&ps_firmware, fw_name, - &ps_dsp_code->ps_dev->dev); + err = request_firmware(&firmware, fw_name, &dev->dev); - if (err != 0) { - dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev, - "%d, request_firmware failed for %s\n", err, - fw_name); + if (err || !firmware) { + dev_err(&dev->dev, "%d, request_firmware failed for %s\n", + err, fw_name); goto error1; } - if (ps_firmware->size < sizeof(header)) { - dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev, - "Header size too small %s\n", fw_name); - goto error2; - } - memcpy(&header, ps_firmware->data, sizeof(header)); - if (header.adapter != adapter) { - dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev, - "Adapter type incorrect %4x != %4x\n", header.adapter, - adapter); + if (firmware->size < sizeof(header)) { + dev_err(&dev->dev, "Header size too small %s\n", fw_name); goto error2; } - if (header.size != ps_firmware->size) { - dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev, - "Code size wrong %d != %ld\n", header.size, - (unsigned long)ps_firmware->size); + memcpy(&header, firmware->data, sizeof(header)); + + if ((header.type != 0x45444F43) || /* "CODE" */ + (header.adapter != adapter) + || (header.size != firmware->size)) { + dev_err(&dev->dev, + "Invalid firmware header size %d != file %zd\n", + header.size, firmware->size); goto error2; } - if (header.version / 100 != HPI_VER_DECIMAL / 100) { - dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev, - "Incompatible firmware version " - "DSP image %d != Driver %d\n", header.version, - HPI_VER_DECIMAL); + if ((header.version >> 9) != (HPI_VER >> 9)) { + /* Consider even and subsequent odd minor versions to be compatible */ + dev_err(&dev->dev, "Incompatible firmware version DSP image %X != Driver %X\n", + header.version, HPI_VER); goto error2; } - if (header.version != HPI_VER_DECIMAL) { - dev_printk(KERN_WARNING, &ps_dsp_code->ps_dev->dev, - "Firmware: release version mismatch DSP image %d != Driver %d\n", - header.version, HPI_VER_DECIMAL); + if (header.version != HPI_VER) { + dev_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); - ps_dsp_code->ps_firmware = ps_firmware; - ps_dsp_code->block_length = header.size / sizeof(u32); - ps_dsp_code->word_count = sizeof(header) / sizeof(u32); - ps_dsp_code->version = header.version; - ps_dsp_code->crc = header.crc; + dsp_code->pvt = kmalloc(sizeof(*dsp_code->pvt), GFP_KERNEL); + if (!dsp_code->pvt) { + err_ret = HPI_ERROR_MEMORY_ALLOC; + goto error2; + } + + dsp_code->pvt->dev = dev; + dsp_code->pvt->firmware = firmware; + dsp_code->header = header; + dsp_code->block_length = header.size / sizeof(u32); + dsp_code->word_count = sizeof(header) / sizeof(u32); return 0; error2: - release_firmware(ps_firmware); + release_firmware(firmware); error1: - ps_dsp_code->ps_firmware = NULL; - ps_dsp_code->block_length = 0; - return HPI_ERROR_DSP_FILE_NOT_FOUND; + dsp_code->block_length = 0; + return err_ret; } /*-------------------------------------------------------------------*/ -void hpi_dsp_code_close(struct dsp_code *ps_dsp_code) +void hpi_dsp_code_close(struct dsp_code *dsp_code) { - if (ps_dsp_code->ps_firmware != NULL) { - HPI_DEBUG_LOG(DEBUG, "dsp code closed\n"); - release_firmware(ps_dsp_code->ps_firmware); - ps_dsp_code->ps_firmware = NULL; - } + HPI_DEBUG_LOG(DEBUG, "dsp code closed\n"); + release_firmware(dsp_code->pvt->firmware); + kfree(dsp_code->pvt); } /*-------------------------------------------------------------------*/ -void hpi_dsp_code_rewind(struct dsp_code *ps_dsp_code) +void hpi_dsp_code_rewind(struct dsp_code *dsp_code) { /* Go back to start of data, after header */ - ps_dsp_code->word_count = sizeof(struct code_header) / sizeof(u32); + dsp_code->word_count = sizeof(struct code_header) / sizeof(u32); } /*-------------------------------------------------------------------*/ -short hpi_dsp_code_read_word(struct dsp_code *ps_dsp_code, u32 *pword) +short hpi_dsp_code_read_word(struct dsp_code *dsp_code, u32 *pword) { - if (ps_dsp_code->word_count + 1 > ps_dsp_code->block_length) + if (dsp_code->word_count + 1 > dsp_code->block_length) return HPI_ERROR_DSP_FILE_FORMAT; - *pword = ((u32 *)(ps_dsp_code->ps_firmware->data))[ps_dsp_code-> + *pword = ((u32 *)(dsp_code->pvt->firmware->data))[dsp_code-> word_count]; - ps_dsp_code->word_count++; + dsp_code->word_count++; return 0; } /*-------------------------------------------------------------------*/ short hpi_dsp_code_read_block(size_t words_requested, - struct dsp_code *ps_dsp_code, u32 **ppblock) + struct dsp_code *dsp_code, u32 **ppblock) { - if (ps_dsp_code->word_count + words_requested > - ps_dsp_code->block_length) + if (dsp_code->word_count + words_requested > dsp_code->block_length) return HPI_ERROR_DSP_FILE_FORMAT; *ppblock = - ((u32 *)(ps_dsp_code->ps_firmware->data)) + - ps_dsp_code->word_count; - ps_dsp_code->word_count += words_requested; + ((u32 *)(dsp_code->pvt->firmware->data)) + + dsp_code->word_count; + dsp_code->word_count += words_requested; return 0; } diff --git a/sound/pci/asihpi/hpidspcd.h b/sound/pci/asihpi/hpidspcd.h index 65f0ca73270..659d19ca6d4 100644 --- a/sound/pci/asihpi/hpidspcd.h +++ b/sound/pci/asihpi/hpidspcd.h @@ -2,7 +2,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 @@ -20,19 +20,6 @@ \file Functions for reading DSP code to load into DSP - hpi_dspcode_defines HPI DSP code loading method -Define exactly one of these to select how the DSP code is supplied to -the adapter. - -End users writing applications that use the HPI interface do not have to -use any of the below defines; they are only necessary for building drivers - -HPI_DSPCODE_FILE: -DSP code is supplied as a file that is opened and read from by the driver. - -HPI_DSPCODE_FIRMWARE: -DSP code is read using the hotplug firmware loader module. - Only valid when compiling the HPI kernel driver under Linux. */ /***********************************************************************/ #ifndef _HPIDSPCD_H_ @@ -40,37 +27,52 @@ DSP code is read using the hotplug firmware loader module. #include "hpi_internal.h" -#ifndef DISABLE_PRAGMA_PACK1 -#pragma pack(push, 1) -#endif +/** Header structure for dsp firmware file + This structure must match that used in s2bin.c for generation of asidsp.bin + */ +/*#ifndef DISABLE_PRAGMA_PACK1 */ +/*#pragma pack(push, 1) */ +/*#endif */ +struct code_header { + /** Size in bytes including header */ + u32 size; + /** File type tag "CODE" == 0x45444F43 */ + u32 type; + /** Adapter model number */ + u32 adapter; + /** Firmware version*/ + u32 version; + /** Data checksum */ + u32 checksum; +}; +/*#ifndef DISABLE_PRAGMA_PACK1 */ +/*#pragma pack(pop) */ +/*#endif */ + +/*? Don't need the pragmas? */ +compile_time_assert((sizeof(struct code_header) == 20), code_header_size); /** Descriptor for dspcode from firmware loader */ struct dsp_code { - /** Firmware descriptor */ - const struct firmware *ps_firmware; - struct pci_dev *ps_dev; + /** copy of file header */ + struct code_header header; /** Expected number of words in the whole dsp code,INCL header */ - long int block_length; + u32 block_length; /** Number of words read so far */ - long int word_count; - /** Version read from dsp code file */ - u32 version; - /** CRC read from dsp code file */ - u32 crc; -}; + u32 word_count; -#ifndef DISABLE_PRAGMA_PACK1 -#pragma pack(pop) -#endif + /** internal state of DSP code reader */ + struct dsp_code_private *pvt; +}; -/** Prepare *psDspCode to refer to the requuested adapter. - Searches the file, or selects the appropriate linked array +/** Prepare *psDspCode to refer to the requested adapter's firmware. +Code file name is obtained from HpiOs_GetDspCodePath \return 0 for success, or error code if requested code is not available */ short hpi_dsp_code_open( /** Code identifier, usually adapter family */ - u32 adapter, + u32 adapter, void *pci_dev, /** Pointer to DSP code control structure */ struct dsp_code *ps_dsp_code, /** Pointer to dword to receive OS specific error code */ diff --git a/sound/pci/asihpi/hpifunc.c b/sound/pci/asihpi/hpifunc.c index 7397b169b89..510e56cffd3 100644 --- a/sound/pci/asihpi/hpifunc.c +++ b/sound/pci/asihpi/hpifunc.c @@ -1663,68 +1663,64 @@ u16 hpi_channel_mode_get(u32 h_control, u16 *mode) u16 hpi_cobranet_hmi_write(u32 h_control, u32 hmi_address, u32 byte_count, u8 *pb_data) { - struct hpi_message hm; - struct hpi_response hr; + struct hpi_msg_cobranet_hmiwrite hm; + struct hpi_response_header hr; - hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX, - HPI_CONTROL_SET_STATE); - if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index)) + hpi_init_message_responseV1(&hm.h, sizeof(hm), &hr, sizeof(hr), + HPI_OBJ_CONTROL, HPI_CONTROL_SET_STATE); + + if (hpi_handle_indexes(h_control, &hm.h.adapter_index, + &hm.h.obj_index)) return HPI_ERROR_INVALID_HANDLE; - hm.u.cx.u.cobranet_data.byte_count = byte_count; - hm.u.cx.u.cobranet_data.hmi_address = hmi_address; + if (byte_count > sizeof(hm.bytes)) + return HPI_ERROR_MESSAGE_BUFFER_TOO_SMALL; - if (byte_count <= 8) { - memcpy(hm.u.cx.u.cobranet_data.data, pb_data, byte_count); - hm.u.cx.attribute = HPI_COBRANET_SET; - } else { - hm.u.cx.u.cobranet_bigdata.pb_data = pb_data; - hm.u.cx.attribute = HPI_COBRANET_SET_DATA; - } - - hpi_send_recv(&hm, &hr); + hm.p.attribute = HPI_COBRANET_SET; + hm.p.byte_count = byte_count; + hm.p.hmi_address = hmi_address; + memcpy(hm.bytes, pb_data, byte_count); + hm.h.size = (u16)(sizeof(hm.h) + sizeof(hm.p) + byte_count); + hpi_send_recvV1(&hm.h, &hr); return hr.error; } u16 hpi_cobranet_hmi_read(u32 h_control, u32 hmi_address, u32 max_byte_count, u32 *pbyte_count, u8 *pb_data) { - struct hpi_message hm; - struct hpi_response hr; + struct hpi_msg_cobranet_hmiread hm; + struct hpi_res_cobranet_hmiread hr; - hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX, - HPI_CONTROL_GET_STATE); - if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index)) + hpi_init_message_responseV1(&hm.h, sizeof(hm), &hr.h, sizeof(hr), + HPI_OBJ_CONTROL, HPI_CONTROL_GET_STATE); + + if (hpi_handle_indexes(h_control, &hm.h.adapter_index, + &hm.h.obj_index)) return HPI_ERROR_INVALID_HANDLE; - hm.u.cx.u.cobranet_data.byte_count = max_byte_count; - hm.u.cx.u.cobranet_data.hmi_address = hmi_address; + if (max_byte_count > sizeof(hr.bytes)) + return HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL; - if (max_byte_count <= 8) { - hm.u.cx.attribute = HPI_COBRANET_GET; - } else { - hm.u.cx.u.cobranet_bigdata.pb_data = pb_data; - hm.u.cx.attribute = HPI_COBRANET_GET_DATA; - } + hm.p.attribute = HPI_COBRANET_GET; + hm.p.byte_count = max_byte_count; + hm.p.hmi_address = hmi_address; - hpi_send_recv(&hm, &hr); - if (!hr.error && pb_data) { + hpi_send_recvV1(&hm.h, &hr.h); - *pbyte_count = hr.u.cx.u.cobranet_data.byte_count; + if (!hr.h.error && pb_data) { + if (hr.byte_count > sizeof(hr.bytes)) - if (*pbyte_count < max_byte_count) - max_byte_count = *pbyte_count; + return HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL; - if (hm.u.cx.attribute == HPI_COBRANET_GET) { - memcpy(pb_data, hr.u.cx.u.cobranet_data.data, - max_byte_count); - } else { + *pbyte_count = hr.byte_count; - } + if (hr.byte_count < max_byte_count) + max_byte_count = *pbyte_count; + memcpy(pb_data, hr.bytes, max_byte_count); } - return hr.error; + return hr.h.error; } u16 hpi_cobranet_hmi_get_status(u32 h_control, u32 *pstatus, @@ -1733,23 +1729,23 @@ u16 hpi_cobranet_hmi_get_status(u32 h_control, u32 *pstatus, struct hpi_message hm; struct hpi_response hr; - hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX, + hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, HPI_CONTROL_GET_STATE); if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index)) return HPI_ERROR_INVALID_HANDLE; - hm.u.cx.attribute = HPI_COBRANET_GET_STATUS; + hm.u.c.attribute = HPI_COBRANET_GET_STATUS; hpi_send_recv(&hm, &hr); if (!hr.error) { if (pstatus) - *pstatus = hr.u.cx.u.cobranet_status.status; + *pstatus = hr.u.cu.cobranet.status.status; if (preadable_size) *preadable_size = - hr.u.cx.u.cobranet_status.readable_size; + hr.u.cu.cobranet.status.readable_size; if (pwriteable_size) *pwriteable_size = - hr.u.cx.u.cobranet_status.writeable_size; + hr.u.cu.cobranet.status.writeable_size; } return hr.error; } @@ -2830,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 628376ce4a4..032d563e370 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 @@ -46,7 +46,7 @@ static void hpi_init_message(struct hpi_message *phm, u16 object, if (gwSSX2_bypass) phm->type = HPI_TYPE_SSX2BYPASS_MESSAGE; else - phm->type = HPI_TYPE_MESSAGE; + phm->type = HPI_TYPE_REQUEST; phm->object = object; phm->function = function; phm->version = 0; @@ -89,7 +89,7 @@ static void hpi_init_messageV1(struct hpi_message_header *phm, u16 size, memset(phm, 0, sizeof(*phm)); if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) { phm->size = size; - phm->type = HPI_TYPE_MESSAGE; + phm->type = HPI_TYPE_REQUEST; phm->object = object; phm->function = function; phm->version = 1; 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 @@ /****************************************************************************** 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 7352a5f7b4f..d4790ddc225 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 @@ -16,12 +16,13 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -Extended Message Function With Response Cacheing +Extended Message Function With Response Caching (C) Copyright AudioScience Inc. 2002 *****************************************************************************/ #define SOURCEFILE_NAME "hpimsgx.c" #include "hpi_internal.h" +#include "hpi_version.h" #include "hpimsginit.h" #include "hpicmn.h" #include "hpimsgx.h" @@ -186,7 +187,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr, /* Initialize this module's internal state */ hpios_msgxlock_init(&msgx_lock); memset(&hpi_entry_points, 0, sizeof(hpi_entry_points)); - hpios_locked_mem_init(); /* Init subsys_findadapters response to no-adapters */ HPIMSGX__reset(HPIMSGX_ALLADAPTERS); hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, @@ -197,7 +197,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr, case HPI_SUBSYS_DRIVER_UNLOAD: HPI_COMMON(phm, phr); HPIMSGX__cleanup(HPIMSGX_ALLADAPTERS, h_owner); - hpios_locked_mem_free_all(); hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_DRIVER_UNLOAD, 0); return; @@ -315,7 +314,7 @@ void hpi_send_recv_ex(struct hpi_message *phm, struct hpi_response *phr, { HPI_DEBUG_MESSAGE(DEBUG, phm); - if (phm->type != HPI_TYPE_MESSAGE) { + if (phm->type != HPI_TYPE_REQUEST) { hpi_init_response(phr, phm->object, phm->function, HPI_ERROR_INVALID_TYPE); return; 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 @@ /****************************************************************************** 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 d8e7047512f..7f0272032fb 100644 --- a/sound/pci/asihpi/hpioctl.c +++ b/sound/pci/asihpi/hpioctl.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 @@ -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" @@ -33,6 +34,7 @@ Common Linux HPI ioctl and module probe/remove functions #include <asm/uaccess.h> #include <linux/pci.h> #include <linux/stringify.h> +#include <linux/module.h> #ifdef MODULE_FIRMWARE MODULE_FIRMWARE("asihpi/dsp5000.bin"); @@ -64,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 @@ -107,7 +107,6 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) union hpi_response_buffer_v1 *hr; u16 res_max_size; u32 uncopied_bytes; - struct hpi_adapter *pa = NULL; int err = 0; if (cmd != HPI_IOCTL_LINUX) @@ -157,11 +156,6 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) goto out; } - if (hm->h.adapter_index >= HPI_MAX_ADAPTERS) { - err = -EINVAL; - goto out; - } - switch (hm->h.function) { case HPI_SUBSYS_CREATE_ADAPTER: case HPI_ADAPTER_DELETE: @@ -183,16 +177,16 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } else { u16 __user *ptr = NULL; u32 size = 0; - /* -1=no data 0=read from user mem, 1=write to user mem */ int wrflag = -1; - u32 adapter = hm->h.adapter_index; - pa = &adapters[adapter]; + struct hpi_adapter *pa = NULL; + + if (hm->h.adapter_index < ARRAY_SIZE(adapters)) + pa = &adapters[hm->h.adapter_index]; - if ((adapter > HPI_MAX_ADAPTERS) || (!pa->type)) { - hpi_init_response(&hr->r0, HPI_OBJ_ADAPTER, - HPI_ADAPTER_OPEN, - HPI_ERROR_BAD_ADAPTER_NUMBER); + if (!pa || !pa->adapter || !pa->adapter->type) { + hpi_init_response(&hr->r0, hm->h.object, + hm->h.function, HPI_ERROR_BAD_ADAPTER_NUMBER); uncopied_bytes = copy_to_user(puhr, hr, sizeof(hr->h)); @@ -203,7 +197,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) goto out; } - if (mutex_lock_interruptible(&adapters[adapter].mutex)) { + if (mutex_lock_interruptible(&pa->mutex)) { err = -EINTR; goto out; } @@ -239,8 +233,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) "stream buffer size %d\n", size); - mutex_unlock(&adapters - [adapter].mutex); + mutex_unlock(&pa->mutex); err = -EINVAL; goto out; } @@ -281,7 +274,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) uncopied_bytes, size); } - mutex_unlock(&adapters[adapter].mutex); + mutex_unlock(&pa->mutex); } /* on return response size must be set */ @@ -314,10 +307,11 @@ out: return err; } -int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev, - const struct pci_device_id *pci_id) +int 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; @@ -332,7 +326,7 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev, pci_dev->subsystem_device, pci_dev->devfn); if (pci_enable_device(pci_dev) < 0) { - dev_printk(KERN_ERR, &pci_dev->dev, + dev_err(&pci_dev->dev, "pci_enable_device failed, disabling device\n"); return -EIO; } @@ -346,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++) { @@ -356,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; @@ -379,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) { @@ -390,36 +383,31 @@ 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); + dev_info(&pci_dev->dev, "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; } } @@ -432,37 +420,37 @@ err: return -ENODEV; } -void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev) +void asihpi_adapter_remove(struct pci_dev *pci_dev) { int idx; 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) vfree(pa->p_buffer); - pci_set_drvdata(pci_dev, NULL); if (1) - dev_printk(KERN_INFO, &pci_dev->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); + dev_info(&pci_dev->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->adapter->index); memset(pa, 0, sizeof(*pa)); } diff --git a/sound/pci/asihpi/hpioctl.h b/sound/pci/asihpi/hpioctl.h index 847f72f03fe..0d767e10ac4 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 @@ -19,9 +19,9 @@ Linux HPI ioctl, and shared module init functions *******************************************************************************/ -int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev, - const struct pci_device_id *pci_id); -void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev); +int asihpi_adapter_probe(struct pci_dev *pci_dev, + const struct pci_device_id *pci_id); +void asihpi_adapter_remove(struct pci_dev *pci_dev); void __init asihpi_init(void); void __exit asihpi_exit(void); diff --git a/sound/pci/asihpi/hpios.c b/sound/pci/asihpi/hpios.c index 742ee12a9e1..5ef4fe96436 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-2012 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 @@ -39,13 +39,9 @@ void hpios_delay_micro_seconds(u32 num_micro_sec) } -void hpios_locked_mem_init(void) -{ -} +/** Allocate an area of locked memory for bus master DMA operations. -/** Allocated an area of locked memory for bus master DMA operations. - -On error, return -ENOMEM, and *pMemArea.size = 0 +If allocation fails, return 1, and *pMemArea.size = 0 */ u16 hpios_locked_mem_alloc(struct consistent_dma_area *p_mem_area, u32 size, struct pci_dev *pdev) @@ -66,7 +62,7 @@ u16 hpios_locked_mem_alloc(struct consistent_dma_area *p_mem_area, u32 size, HPI_DEBUG_LOG(WARNING, "failed to allocate %d bytes locked memory\n", size); p_mem_area->size = 0; - return -ENOMEM; + return 1; } } @@ -85,7 +81,3 @@ u16 hpios_locked_mem_free(struct consistent_dma_area *p_mem_area) return 1; } } - -void hpios_locked_mem_free_all(void) -{ -} diff --git a/sound/pci/asihpi/hpios.h b/sound/pci/asihpi/hpios.h index 03273e729f9..d3fbd0d76c3 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 @@ -30,7 +30,6 @@ HPI Operating System Specific macros for Linux Kernel driver #define HPI_BUILD_KERNEL_MODE #include <linux/io.h> -#include <asm/system.h> #include <linux/ioctl.h> #include <linux/kernel.h> #include <linux/string.h> @@ -38,6 +37,7 @@ HPI Operating System Specific macros for Linux Kernel driver #include <linux/firmware.h> #include <linux/interrupt.h> #include <linux/pci.h> +#include <linux/mutex.h> #define HPI_NO_OS_FILE_OPS @@ -148,20 +148,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 bb30868ce1a..db570ddf64b 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 |
