Update of /cvsroot/alsa/alsa-kernel/parisc
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16528

Modified Files:
        harmony.c 
Log Message:
- fixed the buffer allocation with the new API.
- optimized the rate and format setting.
- removed redundant call of buffer release.
- removed invalid __devinit prefix.



Index: harmony.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/parisc/harmony.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- harmony.c   24 Apr 2004 20:01:49 -0000      1.9
+++ harmony.c   7 May 2004 17:04:31 -0000       1.10
@@ -96,16 +96,14 @@
 #define MAX_PCM_SUBSTREAMS     4
 #define MAX_MIDI_DEVICES       0
 
-#define BUFFER_SIZE                    4096
-#define MAX_BUFS                       10
+#define HARMONY_BUF_SIZE       4096
+#define MAX_BUFS               10
+#define MAX_BUFFER_SIZE                (MAX_BUFS * HARMONY_BUF_SIZE)
 
 /* number of silence & graveyard buffers */
 #define GRAVEYARD_BUFS         3
 #define SILENCE_BUFS           3
 
-#define MAX_BUFFER_SIZE                (MAX_BUFS * BUFFER_SIZE)
-#define HARMONY_BUF_SIZE       BUFFER_SIZE
-
 #define HARMONY_CNTL_C         0x80000000
 
 #define HARMONY_DSTATUS_PN     0x00000200
@@ -200,18 +198,16 @@
 
        struct parisc_device *pa_dev;
 
+       struct snd_dma_device dma_dev;
+
        /* the graveyard buffer is used as recording buffer when playback, 
         * because harmony always want a buffer to put recorded data */
-
-       unsigned char *graveyard_addr;
-       dma_addr_t graveyard_dma;
+       struct snd_dma_buffer graveyard_dma;
        int graveyard_count;
        
        /* same thing for silence buffer */
-       unsigned char *silence_addr;
-       dma_addr_t silence_dma;
+       struct snd_dma_buffer silence_dma;
        int silence_count;
-       struct snd_dma_device dma_dev;
 
        /* alsa stuff */
        snd_card_t *card;
@@ -270,6 +266,15 @@
 #define HARMONY_SR_33KHZ       0x16
 #define HARMONY_SR_6KHZ                0x17
 
+/* bits corresponding to the entries of snd_card_harmony_rates */
+static unsigned int rate_bits[14] = {
+       HARMONY_SR_5KHZ, HARMONY_SR_6KHZ, HARMONY_SR_8KHZ,
+       HARMONY_SR_9KHZ, HARMONY_SR_11KHZ, HARMONY_SR_16KHZ,
+       HARMONY_SR_18KHZ, HARMONY_SR_22KHZ, HARMONY_SR_27KHZ,
+       HARMONY_SR_32KHZ, HARMONY_SR_33KHZ, HARMONY_SR_37KHZ,
+       HARMONY_SR_44KHZ, HARMONY_SR_48KHZ
+};
+
 /* snd_card_harmony_rate_bits
  * @rate:      index of current data rate in list
  * returns: harmony hex code for registers
@@ -279,26 +284,9 @@
        unsigned int idx;
        
        for (idx = 0; idx <= RATES; idx++)
-               if (snd_card_harmony_rates[idx] == rate) break;
-       
-       switch (idx) {
-               case 0: return HARMONY_SR_5KHZ;
-               case 1: return HARMONY_SR_6KHZ;
-               case 2: return HARMONY_SR_8KHZ;
-               case 3: return HARMONY_SR_9KHZ;
-               case 4: return HARMONY_SR_11KHZ;
-               case 5: return HARMONY_SR_16KHZ;
-               case 6: return HARMONY_SR_18KHZ;
-               case 7: return HARMONY_SR_22KHZ;
-               case 8: return HARMONY_SR_27KHZ;
-               case 9: return HARMONY_SR_32KHZ;
-               case 10: return HARMONY_SR_33KHZ;
-               case 11: return HARMONY_SR_37KHZ;
-               case 12: return HARMONY_SR_44KHZ;
-               case 13: return HARMONY_SR_48KHZ;
-               default:  /* fallback */
-                               return HARMONY_SR_44KHZ;
-       }
+               if (snd_card_harmony_rates[idx] == rate)
+                       return rate_bits[idx];
+       return HARMONY_SR_44KHZ; /* fallback */
 }
 
 /*
@@ -323,27 +311,6 @@
 }
 
 /*
- * silence a buffer
- * XXX: alsa could probably do this by itself
- * XXX: memset hpmc, commented.
- */
-
-void snd_harmony_silence(snd_card_harmony_t *harmony,
-               void *addr, int length)
-{
-       u8 silence_char;
-       
-       switch(harmony->data_format) {
-                       case HARMONY_DF_8BIT_ULAW: silence_char = 0x55; break;
-                       case HARMONY_DF_8BIT_ALAW: silence_char = 0xff; break;
-                       case HARMONY_DF_16BIT_LINEAR:
-                       default:
-                                                                          
silence_char = 0;
-       }
-       //memset(addr, silence_char, length);
-}
-
-/*
  * interruption controls routines
  */
 
@@ -391,9 +358,9 @@
                        snd_pcm_period_elapsed(harmony->playback_substream);
                        harmony->ply_total++;
                } else {
-                       gsc_writel(harmony->silence_dma + 
-                                       (HARMONY_BUF_SIZE*harmony->silence_count),
-                                       hpa+REG_PNXTADD);
+                       gsc_writel(harmony->silence_dma.addr + 
+                                  (HARMONY_BUF_SIZE*harmony->silence_count),
+                                  hpa+REG_PNXTADD);
                        harmony->silence_count++;
                        harmony->silence_count %= SILENCE_BUFS;
                }
@@ -412,9 +379,9 @@
                        harmony->cap_total++;
                } else {
                        /* graveyard buffer */
-                       gsc_writel(harmony->graveyard_dma +
-                                               
(HARMONY_BUF_SIZE*harmony->graveyard_count),
-                                               hpa+REG_RNXTADD);
+                       gsc_writel(harmony->graveyard_dma.addr +
+                                  (HARMONY_BUF_SIZE*harmony->graveyard_count),
+                                  hpa+REG_RNXTADD);
                        harmony->graveyard_count++;
                        harmony->graveyard_count %= GRAVEYARD_BUFS;
                }
@@ -471,26 +438,8 @@
 {
        snd_info_entry_t *entry;
        
-       if ((entry = snd_info_create_card_entry(harmony->card, "harmony", 
harmony->card->proc_root)) != NULL) {
-               entry->content = SNDRV_INFO_CONTENT_TEXT;
-               entry->private_data = harmony;
-               entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
-               entry->c.text.read_size = 2048;  /* should be enough */
-               entry->c.text.read = snd_harmony_proc_read;
-               if (snd_info_register(entry) < 0) {
-                       snd_info_free_entry(entry);
-                       entry = NULL;
-               }
-       }
-       harmony->proc_entry = entry;
-}
-
-static void snd_harmony_proc_done(snd_card_harmony_t *harmony)
-{
-       if (harmony->proc_entry) {
-               snd_info_unregister(harmony->proc_entry);
-               harmony->proc_entry = NULL;
-       }
+       if (! snd_card_proc_new(harmony->card, "harmony", &entry))
+               snd_info_set_text_ops(entry, harmony, 2048, snd_harmony_proc_read);
 }
 
 /* 
@@ -569,6 +518,30 @@
        return 0;
 }
 
+/* set data format */
+static int snd_harmony_set_data_format(snd_card_harmony_t *harmony, int pcm_format)
+{
+       int old_format = harmony->data_format;
+       int new_format = old_format;
+       switch (pcm_format) {
+       case SNDRV_PCM_FORMAT_S16_BE:
+               new_format = HARMONY_DF_16BIT_LINEAR;
+               break;
+       case SNDRV_PCM_FORMAT_A_LAW:
+               new_format = HARMONY_DF_8BIT_ALAW;
+               break;
+       case SNDRV_PCM_FORMAT_MU_LAW:
+               new_format = HARMONY_DF_8BIT_ULAW;
+               break;
+       }
+       /* re-initialize silence buffer if needed */
+       if (old_format != new_format)
+               snd_pcm_format_set_silence(pcm_format, harmony->silence_dma.area,
+                                          (HARMONY_BUF_SIZE * SILENCE_BUFS * 8) / 
snd_pcm_format_width(pcm_format));
+
+       return new_format;
+}
+
 static int snd_card_harmony_playback_prepare(snd_pcm_substream_t * substream)
 {
        snd_card_harmony_t *harmony = snd_pcm_substream_chip(substream);
@@ -583,12 +556,13 @@
        harmony->sample_rate = snd_card_harmony_rate_bits(runtime->rate);
 
        /* data format */
-       if (snd_pcm_format_width(runtime->format) == 16) harmony->data_format = 
HARMONY_DF_16BIT_LINEAR;
-       else harmony->data_format = HARMONY_DF_8BIT_ULAW;
-       
+       harmony->data_format = snd_harmony_set_data_format(haromny, runtime->format);
+
        /* number of channels */
-       if (runtime->channels == 2) harmony->stereo_select = HARMONY_SS_STEREO;
-       else harmony->stereo_select = HARMONY_SS_MONO;
+       if (runtime->channels == 2)
+               harmony->stereo_select = HARMONY_SS_STEREO;
+       else
+               harmony->stereo_select = HARMONY_SS_MONO;
        
        DPRINTK(KERN_INFO PFX "Playback_prepare, sr=%d(%x), df=%x, ss=%x hpa=%lx\n", 
runtime->rate,
                                harmony->sample_rate, harmony->data_format, 
harmony->stereo_select, harmony->hpa);
@@ -613,12 +587,13 @@
        harmony->sample_rate = snd_card_harmony_rate_bits(runtime->rate);
        
        /* data format */
-       if (snd_pcm_format_width(runtime->format) == 16) harmony->data_format = 
HARMONY_DF_16BIT_LINEAR;
-       else harmony->data_format = HARMONY_DF_8BIT_ULAW;
+       harmony->data_format = snd_harmony_set_data_format(haromny, runtime->format);
        
        /* number of channels */
-       if (runtime->channels == 1) harmony->stereo_select = HARMONY_SS_MONO;
-       else if (runtime->channels == 2) harmony->stereo_select = HARMONY_SS_STEREO;
+       if (runtime->channels == 1)
+               harmony->stereo_select = HARMONY_SS_MONO;
+       else if (runtime->channels == 2)
+               harmony->stereo_select = HARMONY_SS_STEREO;
                
        snd_harmony_update_control(harmony);
        harmony->format_initialized = 1;
@@ -743,7 +718,6 @@
 static int snd_card_harmony_playback_close(snd_pcm_substream_t * substream)
 {
        snd_card_harmony_t *harmony = snd_pcm_substream_chip(substream);
-       snd_pcm_lib_free_pages(substream);
        
        harmony->playback_substream = NULL;
        harmony->ply_size                       = 0;
@@ -760,8 +734,6 @@
 {
        snd_card_harmony_t *harmony = snd_pcm_substream_chip(substream);
        
-       snd_pcm_lib_free_pages(substream);
-       
        harmony->capture_substream = NULL;
        harmony->cap_size                       = 0;
        harmony->cap_buf                        = 0;
@@ -839,13 +811,17 @@
        /* initialize graveyard buffer */
        harmony->dma_dev.type = SNDRV_DMA_TYPE_DEV;
        harmony->dma_dev.dev = &harmony->pa_dev->dev;
-       harmony->graveyard_addr = snd_dma_alloc_pages(&chip->dma_dev,
-                       HARMONY_BUF_SIZE*GRAVEYARD_BUFS, &harmony->graveyard_dma);
+       err = snd_dma_alloc_pages(&harmony->dma_dev, HARMONY_BUF_SIZE*GRAVEYARD_BUFS,
+                                 &harmony->graveyard_dma);
+       if (err < 0)
+               return err;
        harmony->graveyard_count = 0;
        
        /* initialize silence buffers */
-       harmony->silence_addr = snd_dma_alloc_pages(&chip->dma_dev,
-                       HARMONY_BUF_SIZE*SILENCE_BUFS, &harmony->silence_dma);
+       err = snd_dma_alloc_pages(&harmony->dma_dev, HARMONY_BUF_SIZE*SILENCE_BUFS,
+                                 &harmony->silence_dma);
+       if (err < 0)
+               return err;
        harmony->silence_count = 0;
 
        harmony->ply_stopped = harmony->cap_stopped = 1;
@@ -856,7 +832,7 @@
        
        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
                                              &harmony->pa_dev->dev,
-                                             64 * 1024, 128 * 1024);
+                                             MAX_BUFFER_SIZE, MAX_BUFFER_SIZE);
 
        return 0;
 }
@@ -953,7 +929,7 @@
 HARMONY_VOLUME("PCM Playback Volume", 6, 0, 0x3f, 1),
 };
 
-static void snd_harmony_reset_codec(snd_card_harmony_t *harmony)
+static void __init snd_harmony_reset_codec(snd_card_harmony_t *harmony)
 {
        snd_harmony_wait_cntl(harmony);
        gsc_writel(1, harmony->hpa+REG_RESET);
@@ -975,7 +951,7 @@
 }
 
 
-int __init snd_card_harmony_mixer_init(snd_card_harmony_t *harmony)
+static int __init snd_card_harmony_mixer_init(snd_card_harmony_t *harmony)
 {
        snd_card_t *card = harmony->card;
        int idx, err;
@@ -1039,7 +1015,7 @@
        snd_card_t *card;
        int err;
        
-    if (dev >= SNDRV_CARDS)
+       if (dev >= SNDRV_CARDS)
                return -ENODEV;
        if (!enable[dev]) {
                dev++;
@@ -1053,6 +1029,8 @@
        if (card == NULL)
                return -ENOMEM;
        chip = (struct snd_card_harmony *)card->private_data;
+       spin_lock_init(&chip->control_lock);
+       spin_lock_init(&chip->mixer_lock);
        
        if ((err = snd_card_harmony_create(card, pa_dev, chip)) < 0) {
                printk(KERN_ERR PFX "Creation failed\n");
@@ -1133,7 +1111,6 @@
                {       
                        DPRINTK(KERN_INFO PFX "Freeing card %d\n", idx);
                        harmony = snd_harmony_cards[idx]->private_data;
-                       snd_harmony_proc_done(harmony);
                        free_irq(harmony->irq, snd_card_harmony_interrupt);
                        printk(KERN_INFO PFX "Card unloaded %d, irq=%d\n", idx, 
harmony->irq);
                        snd_card_free(snd_harmony_cards[idx]);



-------------------------------------------------------
This SF.Net email is sponsored by Sleepycat Software
Learn developer strategies Cisco, Motorola, Ericsson & Lucent use to deliver
higher performing products faster, at low TCO.
http://www.sleepycat.com/telcomwpreg.php?From=osdnemail3
_______________________________________________
Alsa-cvslog mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-cvslog

Reply via email to