Support single-rate no-SRC cards.
PATCH 1/3 Support single-rate no-SRC cards.
From: Eliot Blennerhassett <[email protected]>
Cards without settable local samplerate and without SRC still must have a valid samplerate.
This fixed rate is determined by reading the current rate for the card.
--- pci/asihpi/asihpi.c | 16 +++++++--------- 1 files changed, 7 insertions(+), 9 deletions(-)
pci/asihpi/asihpi.c +7 -9
@@ -381,13 +381,13 @@ static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi, "No local sampleclock, err %d\n", err); } -for (idx =0 ; idx <100 ; idx++) { -if (hpi_sample_clock_query_local_rate ( - h_control, idx, &sample_rate)) { -if (!idx) -snd_printk (KERN_ERR -"Local rate query failed\n" ); - +for (idx =-1 ; idx <100 ; idx++) { +if (idx ==-1 ) { +if (hpi_sample_clock_get_sample_rate (h_control, + &sample_rate)) +continue ; + }else if (hpi_sample_clock_query_local_rate (h_control, + idx, &sample_rate)) {break ; }
@@ -440,8 +440,6 @@ static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi, } } -/* printk(KERN_INFO "Supported rates %X %d %d\n", -rates, rate_min, rate_max); */ pcmhw->rates = rates; pcmhw->rate_min = rate_min; pcmhw->rate_max = rate_max;
Signature · 1 line
1.7.0.4
PATCH 2/3 Improve non-busmaster adapter operation.
From: Eliot Blennerhassett <[email protected]>
Make playback silence callback a no-op, card automatically outputs silence when written data runs out.
Increasing update interval and thus minimum period avoids xrun on startup or because of timer jitter.
--- pci/asihpi/asihpi.c | 21 ++++++++++----------- 1 files changed, 10 insertions(+), 11 deletions(-)
pci/asihpi/asihpi.c +10 -11
@@ -1012,6 +1012,7 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)snd_pcm_hw_constraint_step (runtime,0 ,SNDRV_PCM_HW_PARAM_PERIOD_SIZE , card->update_interval_frames); +snd_pcm_hw_constraint_minmax (runtime,SNDRV_PCM_HW_PARAM_PERIOD_SIZE , card->update_interval_frames *2 ,UINT_MAX );
@@ -1054,7 +1055,7 @@ static int snd_card_asihpi_playback_copy(struct snd_pcm_substream *substream,hpi_handle_error (hpi_outstream_write_buf (dpcm->h_stream, runtime->dma_area, len, &dpcm->format)); - dpcm->pcm_buf_host_rw_ofs = dpcm->pcm_buf_host_rw_ofs + len; + dpcm->pcm_buf_host_rw_ofs += len;return 0 ; }
@@ -1064,16 +1065,11 @@ static int snd_card_asihpi_playback_silence(struct snd_pcm_substream * snd_pcm_uframes_t pos, snd_pcm_uframes_t count) { -unsigned int len; -struct snd_pcm_runtime *runtime = substream->runtime; -struct snd_card_asihpi_pcm *dpcm = runtime->private_data; - - len =frames_to_bytes (runtime, count); -VPRINTK1 (KERN_INFO "playback silence %u bytes\n" , len); - -memset (runtime->dma_area,0 , len); -hpi_handle_error (hpi_outstream_write_buf (dpcm->h_stream, - runtime->dma_area, len, &dpcm->format)); +/* Usually writes silence to DMA buffer, which should be overwritten +by real audio later. Our fifos cannot be overwritten, and are not +free-running DMAs. Silence is output on fifo underflow. +This callback is still required to allow the copy callback to be used. +*/ return 0 ; }
@@ -2885,6 +2881,9 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,if (err) asihpi->update_interval_frames =512 ; +if (!asihpi->support_mmap) + asihpi->update_interval_frames *=2 ; +hpi_handle_error (hpi_instream_open (asihpi->adapter_index,0 , &h_stream));
Signature · 1 line
1.7.0.4
PATCH 3/3 Update verbose debug print macros.
In reply to [email protected]From: Eliot Blennerhassett <[email protected]>
Replace local VPRINTK1 with snd_printdd.
Create local snd_printddd instead of VPRINTK2 for most verbose debug. In most cases let snd_printk supply default level for messages.
--- pci/asihpi/asihpi.c | 100 ++++++++++++++++++++++++--------------------------- 1 files changed, 47 insertions(+), 53 deletions(-)
pci/asihpi/asihpi.c +47 -53
@@ -22,21 +22,6 @@* for any purpose including commercial applications. */ -/* >0: print Hw params, timer vars. >1: print stream write/copy sizes */ -#define REALLY_VERBOSE_LOGGING 0 - -#if REALLY_VERBOSE_LOGGING -#define VPRINTK1 snd_printd -#else -#define VPRINTK1 (...) -#endif - -#if REALLY_VERBOSE_LOGGING >1 -#define VPRINTK2 snd_printd -#else -#define VPRINTK2 (...) -#endif -#include "hpi_internal.h" #include "hpimsginit.h" #include "hpioctl.h"
@@ -57,11 +42,25 @@#include <sound/tlv.h> #include <sound/hwdep.h> -MODULE_LICENSE ("GPL" );MODULE_AUTHOR ("AudioScience inc. <[email protected]>" );MODULE_DESCRIPTION ("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx" ); +#if definedCONFIG_SND_DEBUG_VERBOSE +/** +* snd_printddd - very verbose debug printk +* @format: format string +* +* Works like snd_printk() for debugging purposes. +* Ignored when CONFIG_SND_DEBUG_VERBOSE is not set. +* Must set snd module debug parameter to 3 to enable at runtime. +*/ +#define snd_printddd(format, args...) \ + __snd_printk(3, __FILE__, __LINE__, format, ##args) +#else +#define snd_printddd(format, args...) do { } while (0) +#endif +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 ;
@@ -289,7 +288,6 @@ static u16 handle_error(u16 err, int line, char *filename)#define hpi_handle_error (x) handle_error(x, __LINE__, __FILE__)/***************************** GENERAL PCM ****************/ -#if REALLY_VERBOSE_LOGGING static void print_hwparams (struct snd_pcm_hw_params *p) {snd_printd ("HWPARAMS \n" );
@@ -304,9 +302,6 @@ static void print_hwparams(struct snd_pcm_hw_params *p)snd_printd ("periods %d \n" ,params_periods (p));snd_printd ("buffer_size %d \n" ,params_buffer_size (p)); } -#else -#define print_hwparams (x) -#endif static snd_pcm_format_t hpi_to_alsa_formats[] = {-1 ,/* INVALID */
@@ -464,7 +459,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,if (err)return err; -VPRINTK1 (KERN_INFO "format %d, %d chans, %d_hz\n" , +snd_printdd ("format %d, %d chans, %d_hz\n" , format,params_channels (params),params_rate (params));
@@ -487,13 +482,12 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, err =hpi_stream_host_buffer_attach (dpcm->h_stream,params_buffer_bytes (params), runtime->dma_addr);if (err ==0 ) { -VPRINTK1 (KERN_INFO +snd_printdd ("stream_host_buffer_attach succeeded %u %lu\n" ,params_buffer_bytes (params), (unsigned long )runtime->dma_addr); }else { -snd_printd (KERN_INFO -"stream_host_buffer_attach error %d\n" , +snd_printd ("stream_host_buffer_attach error %d\n" , err);return -ENOMEM ; }
@@ -502,7 +496,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, &dpcm->hpi_buffer_attached, NULL, NULL, NULL); -VPRINTK1 (KERN_INFO "stream_host_buffer_attach status 0x%x\n" , +snd_printdd ("stream_host_buffer_attach status 0x%x\n" , dpcm->hpi_buffer_attached); } bytes_per_sec =params_rate (params) *params_channels (params);
@@ -515,7 +509,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, dpcm->bytes_per_sec = bytes_per_sec; dpcm->buffer_bytes =params_buffer_bytes (params); dpcm->period_bytes =params_period_bytes (params); -VPRINTK1 (KERN_INFO "buffer_bytes=%d, period_bytes=%d, bps=%d\n" , +snd_printdd ("buffer_bytes=%d, period_bytes=%d, bps=%d\n" , dpcm->buffer_bytes, dpcm->period_bytes, bytes_per_sec);return 0 ;
@@ -571,7 +565,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,struct snd_pcm_substream *s;u16 e; -VPRINTK1 (KERN_INFO "%c%d trigger\n" , +snd_printdd ("%c%d trigger\n" ,SCHR (substream->stream), substream->number);switch (cmd) {case SNDRV_PCM_TRIGGER_START :
@@ -595,7 +589,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,* data?? */ unsigned int preload = ds->period_bytes *1 ; -VPRINTK2 (KERN_INFO "%d preload x%x\n" , s->number, preload); +snd_printddd ("%d preload x%x\n" , s->number, preload); hpi_handle_error(hpi_outstream_write_buf( ds->h_stream, &runtime->dma_area[0],
@@ -605,7 +599,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, }if (card->support_grouping) { -VPRINTK1 (KERN_INFO "\t%c%d group\n" , +snd_printdd ("\t%c%d group\n" ,SCHR (s->stream), s->number); e = hpi_stream_group_add(
@@ -620,7 +614,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, }else break ; } -VPRINTK1 (KERN_INFO "start\n" ); +snd_printdd ("start\n" );/* start the master stream */ snd_card_asihpi_pcm_timer_start (substream); if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) ||
@@ -642,14 +636,14 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, s->runtime->status->state =SNDRV_PCM_STATE_SETUP ;if (card->support_grouping) { -VPRINTK1 (KERN_INFO "\t%c%d group\n" , +snd_printdd ("\t%c%d group\n" ,SCHR (s->stream), s->number);snd_pcm_trigger_done (s, substream); }else break ; } -VPRINTK1 (KERN_INFO "stop\n" ); +snd_printdd ("stop\n" );/* _prepare and _hwparams reset the stream */ hpi_handle_error (hpi_stream_stop (dpcm->h_stream));
@@ -662,12 +656,12 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,break ;case SNDRV_PCM_TRIGGER_PAUSE_RELEASE : -VPRINTK1 (KERN_INFO "pause release\n" ); +snd_printdd ("pause release\n" );hpi_handle_error (hpi_stream_start (dpcm->h_stream));snd_card_asihpi_pcm_timer_start (substream);break ;case SNDRV_PCM_TRIGGER_PAUSE_PUSH : -VPRINTK1 (KERN_INFO "pause\n" ); +snd_printdd ("pause\n" );snd_card_asihpi_pcm_timer_stop (substream);hpi_handle_error (hpi_stream_stop (dpcm->h_stream));break ;
@@ -739,7 +733,7 @@ static void snd_card_asihpi_timer_function(unsigned long data)u16 state;u32 buffer_size, bytes_avail, samples_played, on_card_bytes; -VPRINTK1 (KERN_INFO "%c%d snd_card_asihpi_timer_function\n" , +snd_printdd ("%c%d snd_card_asihpi_timer_function\n" ,SCHR (substream->stream), substream->number);/* find minimum newdata and buffer pos in group */
@@ -768,10 +762,10 @@ static void snd_card_asihpi_timer_function(unsigned long data)if ((bytes_avail ==0 ) && (on_card_bytes < ds->pcm_buf_host_rw_ofs)) {hpi_handle_error (hpi_stream_start (ds->h_stream)); -VPRINTK1 (KERN_INFO "P%d start\n" , s->number); +snd_printdd ("P%d start\n" , s->number); } }else if (state ==HPI_STATE_DRAINED ) { -VPRINTK1 (KERN_WARNING "P%d drained\n" , +snd_printd (KERN_WARNING "P%d drained\n" , s->number);/*snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); continue; */
@@ -792,13 +786,13 @@ static void snd_card_asihpi_timer_function(unsigned long data) newdata); } -VPRINTK1 (KERN_INFO "PB timer hw_ptr x%04lX, appl_ptr x%04lX\n" , +snd_printdd ("hw_ptr x%04lX, appl_ptr x%04lX\n" , (unsigned long )frames_to_bytes (runtime, runtime->status->hw_ptr), (unsigned long )frames_to_bytes (runtime, runtime->control->appl_ptr)); - VPRINTK1(KERN_INFO "%d %c%d S=%d, rw=%04X, dma=x%04X, left=x%04X," + snd_printdd("%d %c%d S=%d, rw=%04X, dma=x%04X, left=x%04X," " aux=x%04X space=x%04X\n", loops, SCHR(s->stream), s->number, state, ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs, (int)bytes_avail,
@@ -820,7 +814,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) next_jiffies =max (next_jiffies,1U ); dpcm->timer.expires = jiffies + next_jiffies; -VPRINTK1 (KERN_INFO "jif %d buf pos x%04X newdata x%04X xfer x%04X\n" , +snd_printdd ("jif %d buf pos x%04X newdata x%04X xfer x%04X\n" , next_jiffies, pcm_buf_dma_ofs, newdata, xfercount);snd_pcm_group_for_each_entry (s, substream) {
@@ -835,7 +829,7 @@ static void snd_card_asihpi_timer_function(unsigned long data)if (xfercount && (on_card_bytes <= ds->period_bytes)) {if (card->support_mmap) {if (s->stream ==SNDRV_PCM_STREAM_PLAYBACK ) { -VPRINTK2 (KERN_INFO "P%d write x%04x\n" , +snd_printddd ("P%d write x%04x\n" , s->number, ds->period_bytes); hpi_handle_error(
@@ -846,7 +840,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) xfercount, &ds->format)); }else { -VPRINTK2 (KERN_INFO "C%d read x%04x\n" , +snd_printddd ("C%d read x%04x\n" , s->number, xfercount); hpi_handle_error(
@@ -869,7 +863,7 @@ 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_printd(KERN_INFO "Playback ioctl %d\n", cmd); */ +snd_printdd (KERN_INFO "Playback ioctl %d\n" , cmd);return snd_pcm_lib_ioctl (substream, cmd, arg); }
@@ -879,7 +873,7 @@ static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream *struct snd_pcm_runtime *runtime = substream->runtime;struct snd_card_asihpi_pcm *dpcm = runtime->private_data; -VPRINTK1 (KERN_INFO "playback prepare %d\n" , substream->number); +snd_printdd ("playback prepare %d\n" , substream->number);hpi_handle_error (hpi_outstream_reset (dpcm->h_stream)); dpcm->pcm_buf_host_rw_ofs =0 ;
@@ -896,7 +890,7 @@ snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream)snd_pcm_uframes_t ptr; ptr =bytes_to_frames (runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes); -/* VPRINTK2(KERN_INFO "playback_pointer=x%04lx\n", (unsigned long)ptr); */ +snd_printddd ("playback_pointer=x%04lx\n" , (unsigned long )ptr);return ptr; }
@@ -1018,7 +1012,7 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)snd_pcm_set_sync (substream); -VPRINTK1 (KERN_INFO "playback open\n" ); +snd_printdd ("playback open\n" );return 0 ; }
@@ -1029,7 +1023,7 @@ static int snd_card_asihpi_playback_close(struct snd_pcm_substream *substream)struct snd_card_asihpi_pcm *dpcm = runtime->private_data;hpi_handle_error (hpi_outstream_close (dpcm->h_stream)); -VPRINTK1 (KERN_INFO "playback close\n" ); +snd_printdd ("playback close\n" );return 0 ; }
@@ -1049,7 +1043,7 @@ static int snd_card_asihpi_playback_copy(struct snd_pcm_substream *substream,if (copy_from_user (runtime->dma_area, src, len))return -EFAULT ; -VPRINTK2 (KERN_DEBUG "playback copy%d %u bytes\n" , +snd_printddd ("playback copy%d %u bytes\n" , substream->number, len); hpi_handle_error(hpi_outstream_write_buf(dpcm->h_stream,
@@ -1104,7 +1098,7 @@ snd_card_asihpi_capture_pointer(struct snd_pcm_substream *substream)struct snd_pcm_runtime *runtime = substream->runtime;struct snd_card_asihpi_pcm *dpcm = runtime->private_data; -VPRINTK2 (KERN_INFO "capture pointer %d=%d\n" , +snd_printddd ("capture pointer %d=%d\n" , substream->number, dpcm->pcm_buf_dma_ofs);/* NOTE Unlike playback can't use actual samples_played for the capture position, because those samples aren't yet in
@@ -1129,7 +1123,7 @@ static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream) dpcm->pcm_buf_dma_ofs =0 ; dpcm->pcm_buf_elapsed_dma_ofs =0 ; -VPRINTK1 ("Capture Prepare %d\n" , substream->number); +snd_printdd ("Capture Prepare %d\n" , substream->number);return 0 ; }
@@ -1192,7 +1186,7 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)if (dpcm ==NULL )return -ENOMEM ; -VPRINTK1 ("hpi_instream_open adapter %d stream %d\n" , +snd_printdd ("capture open adapter %d stream %d\n" , card->adapter_index, substream->number); err = hpi_handle_error(
@@ -1262,7 +1256,7 @@ static int snd_card_asihpi_capture_copy(struct snd_pcm_substream *substream, len =frames_to_bytes (runtime, count); -VPRINTK2 (KERN_INFO "capture copy%d %d bytes\n" , substream->number, len); +snd_printddd ("capture copy%d %d bytes\n" , substream->number, len);hpi_handle_error (hpi_instream_read_buf (dpcm->h_stream, runtime->dma_area, len));
@@ -2906,7 +2900,6 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, asihpi->support_mrx ); - err =snd_card_asihpi_pcm_new (asihpi,0 , pcm_substreams);if (err <0 ) {snd_printk (KERN_ERR "pcm_new failed\n" );
@@ -2941,6 +2934,7 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,sprintf (card->longname,"%s %i" , card->shortname, asihpi->adapter_index); err =snd_card_register (card); +if (!err) { hpi_card->snd_card_asihpi = card; dev++;
Signature · 1 line
1.7.0.4
Takashi Iwai
AppliedAt Fri, 25 Mar 2011 15:25:46 +1300,
Quoted 8 lines · [email protected] wrote:
From: Eliot Blennerhassett <[email protected]>
Cards without settable local samplerate and without SRC still must have a valid samplerate.
This fixed rate is determined by reading the current rate for the card.Signed-off-by Eliot Blennerhassett <[email protected]>
Applied all 3 patches. Thanks.
Takashi