]> git.neil.brown.name Git - history.git/commitdiff
ALSA update
authorJaroslav Kysela <perex@suse.cz>
Sun, 10 Nov 2002 21:47:30 +0000 (22:47 +0100)
committerJaroslav Kysela <perex@suse.cz>
Sun, 10 Nov 2002 21:47:30 +0000 (22:47 +0100)
  - Moved initialization of card->id to card_register() function.
    The new default id is composed from the shortname given by driver.
  - ES18xx - Fixed power management defines
  - VIA82xx - The SG table is build inside hw_params (outside spinlock - memory allocation).

include/sound/info.h
sound/core/info.c
sound/core/init.c
sound/isa/es18xx.c
sound/pci/via82xx.c

index b45b422063e285afb006579334f8126b2d10a9be..6984c6e736dc3b5fe20e65cae28fdf533c8cf862 100644 (file)
@@ -130,8 +130,9 @@ void snd_info_free_device(snd_info_entry_t * entry);
 int snd_info_store_text(snd_info_entry_t * entry);
 int snd_info_restore_text(snd_info_entry_t * entry);
 
+int snd_info_card_create(snd_card_t * card);
 int snd_info_card_register(snd_card_t * card);
-int snd_info_card_unregister(snd_card_t * card);
+int snd_info_card_free(snd_card_t * card);
 int snd_info_register(snd_info_entry_t * entry);
 int snd_info_unregister(snd_info_entry_t * entry);
 
index 0e1bfb625ddf7f67f420677a4ceaf0774858d543..9792d9ee75a136a0ad117c6f62c1c51753c373ad 100644 (file)
@@ -699,12 +699,10 @@ int __exit snd_info_done(void)
  */
 
 
-int snd_info_card_register(snd_card_t * card)
+int snd_info_card_create(snd_card_t * card)
 {
        char str[8];
-       char *s;
        snd_info_entry_t *entry;
-       struct proc_dir_entry *p;
 
        snd_assert(card != NULL, return -ENXIO);
 
@@ -717,11 +715,20 @@ int snd_info_card_register(snd_card_t * card)
                return -ENOMEM;
        }
        card->proc_root = entry;
+       return 0;
+}
+
+int snd_info_card_register(snd_card_t * card)
+{
+       char *s;
+       struct proc_dir_entry *p;
+
+       snd_assert(card != NULL, return -ENXIO);
 
-       if (!strcmp(card->id, str))
+       if (!strcmp(card->id, card->proc_root->name))
                return 0;
 
-       s = snd_kmalloc_strdup(str, GFP_KERNEL);
+       s = snd_kmalloc_strdup(card->proc_root->name, GFP_KERNEL);
        if (s == NULL)
                return -ENOMEM;
        p = snd_create_proc_entry(card->id, S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO, snd_proc_root);
@@ -738,7 +745,7 @@ int snd_info_card_register(snd_card_t * card)
        return 0;
 }
 
-int snd_info_card_unregister(snd_card_t * card)
+int snd_info_card_free(snd_card_t * card)
 {
        void *data;
 
index 3e15f1a4fe615aebce78c5a66023d8a7db9bd5ca..77565af5ba45a60a4835f2599469e2835e10d1bc 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/time.h>
+#include <linux/ctype.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/info.h>
@@ -45,7 +46,6 @@ snd_card_t *snd_card_new(int idx, const char *xid,
                         struct module *module, int extra_size)
 {
        snd_card_t *card;
-       snd_info_entry_t *entry;
        int err;
 
        if (extra_size < 0)
@@ -79,8 +79,6 @@ snd_card_t *snd_card_new(int idx, const char *xid,
        snd_cards_lock |= 1 << idx;             /* lock it */
        write_unlock(&snd_card_rwlock);
        card->number = idx;
-       if (!card->id[0])
-               sprintf(card->id, "card%i", card->number);
        card->module = module;
        INIT_LIST_HEAD(&card->devices);
        rwlock_init(&card->control_rwlock);
@@ -97,28 +95,14 @@ snd_card_t *snd_card_new(int idx, const char *xid,
                snd_printd("unable to register control minors\n");
                goto __error;
        }
-       if ((err = snd_info_card_register(card)) < 0) {
-               snd_printd("unable to register card info\n");
+       if ((err = snd_info_card_create(card)) < 0) {
+               snd_printd("unable to create card info\n");
                goto __error_ctl;
        }
-       if ((entry = snd_info_create_card_entry(card, "id", card->proc_root)) == NULL) {
-               snd_printd("unable to create card entry\n");
-               goto __error_info;
-       }
-       entry->content = SNDRV_INFO_CONTENT_TEXT;
-       entry->c.text.read_size = PAGE_SIZE;
-       entry->c.text.read = snd_card_id_read;
-       if (snd_info_register(entry) < 0) {
-               snd_info_free_entry(entry);
-               goto __error_info;
-       }
-       card->proc_id = entry;
        if (extra_size > 0)
                card->private_data = (char *)card + sizeof(snd_card_t);
        return card;
 
-      __error_info:
-       snd_info_card_unregister(card);
       __error_ctl:
        snd_ctl_unregister(card);
       __error:
@@ -157,8 +141,8 @@ int snd_card_free(snd_card_t * card)
        if (card->private_free)
                card->private_free(card);
        snd_info_free_entry(card->proc_id);
-       if (snd_info_card_unregister(card) < 0) {
-               snd_printk(KERN_WARNING "unable to unregister card info\n");
+       if (snd_info_card_free(card) < 0) {
+               snd_printk(KERN_WARNING "unable to free card info\n");
                /* Not fatal error */
        }
        write_lock(&snd_card_rwlock);
@@ -168,9 +152,66 @@ int snd_card_free(snd_card_t * card)
        return 0;
 }
 
+static void choose_default_id(snd_card_t *card)
+{
+       int i, len, idx_flag = 0, loops = 8;
+       char *id, *spos;
+       
+       id = spos = card->shortname;    
+       while (*id != '\0') {
+               if (*id == ' ')
+                       spos = id + 1;
+               id++;
+       }
+       id = card->id;
+       while (*spos != '\0' && id - card->id < sizeof(card->id) - 1) {
+               if (isalnum(*spos))
+                       *id++ = *spos;
+               spos++;
+       }
+       *id = '\0';
+
+       id = card->id;
+
+       while (1) {
+               if (loops-- == 0) {
+                       snd_printk(KERN_ERR "unable to choose default card id (%s)", id);
+                       strcpy(card->id, card->proc_root->name);
+                       return;
+               }
+               if (!snd_info_check_reserved_words(id))
+                       goto __change;
+               for (i = 0; i < snd_ecards_limit; i++) {
+                       if (snd_cards[i] && !strcmp(snd_cards[i]->id, id))
+                               goto __change;
+               }
+               break;
+
+             __change:
+               len = strlen(id);
+               if (idx_flag)
+                       id[len-1]++;
+               else if (len <= sizeof(card->id) - 3) {
+                       strcat(id, "_1");
+                       idx_flag++;
+               } else {
+                       spos = id + len - 2;
+                       if (len <= sizeof(card->id) - 2)
+                               spos++;
+                       *spos++ = '_';
+                       *spos++ = '1';
+                       *spos++ = '\0';
+                       idx_flag++;
+               }
+       }
+               
+       strcpy(card->id, id);
+}
+
 int snd_card_register(snd_card_t * card)
 {
        int err;
+       snd_info_entry_t *entry;
 
        snd_runtime_check(card != NULL, return -EINVAL);
        if ((err = snd_device_register_all(card)) < 0)
@@ -181,9 +222,28 @@ int snd_card_register(snd_card_t * card)
                write_unlock(&snd_card_rwlock);
                return 0;
        }
+       if (!card->id[0])
+               choose_default_id(card);
        snd_cards[card->number] = card;
        snd_cards_count++;
        write_unlock(&snd_card_rwlock);
+       if ((err = snd_info_card_register(card)) < 0) {
+               snd_printd("unable to create card info\n");
+               goto __skip_info;
+       }
+       if ((entry = snd_info_create_card_entry(card, "id", card->proc_root)) == NULL) {
+               snd_printd("unable to create card entry\n");
+               goto __skip_info;
+       }
+       entry->content = SNDRV_INFO_CONTENT_TEXT;
+       entry->c.text.read_size = PAGE_SIZE;
+       entry->c.text.read = snd_card_id_read;
+       if (snd_info_register(entry) < 0) {
+               snd_info_free_entry(entry);
+               entry = NULL;
+       }
+       card->proc_id = entry;
+      __skip_info:
 #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
        if (snd_mixer_oss_notify_callback)
                snd_mixer_oss_notify_callback(card, 0);
index 900b36f662564c1381cad613e736e5683a969108..67bc35c4066134efe375a32cbf3d9bc30fe0af87 100644 (file)
@@ -154,10 +154,10 @@ struct _snd_es18xx {
 #define ES18XX_PM      0x07
 #define ES18XX_PM_GPO0 0x01
 #define ES18XX_PM_GPO1 0x02
-#define ES18XX_PM_PDR  0x03
-#define ES18XX_PM_ANA  0x04
-#define ES18XX_PM_FM   0x06
-#define ES18XX_PM_SUS  0x08
+#define ES18XX_PM_PDR  0x04
+#define ES18XX_PM_ANA  0x08
+#define ES18XX_PM_FM   0x020
+#define ES18XX_PM_SUS  0x080
 
 typedef struct _snd_es18xx es18xx_t;
 
index b7cb6b04aaacd32e0217ff7f21ebdee9ba298dc4..3cff7ac49a531c44bbdc1a6c6aa16990993027d2 100644 (file)
@@ -201,11 +201,16 @@ typedef struct {
 } viadev_t;
 
 
+/*
+ * allocate and initialize the descriptor buffers
+ * periods = number of periods
+ * fragsize = period size in bytes
+ */
 static int build_via_table(viadev_t *dev, snd_pcm_substream_t *substream,
-                          struct pci_dev *pci)
+                          struct pci_dev *pci,
+                          int periods, int fragsize)
 {
-       int i, idx, ofs, rest, fragsize;
-       snd_pcm_runtime_t *runtime = substream->runtime;
+       int i, idx, ofs, rest;
        struct snd_sg_buf *sgbuf = snd_magic_cast(snd_pcm_sgbuf_t, substream->dma_private, return -EINVAL);
 
        if (! dev->table) {
@@ -223,10 +228,9 @@ static int build_via_table(viadev_t *dev, snd_pcm_substream_t *substream,
        }
 
        /* fill the entries */
-       fragsize = snd_pcm_lib_period_bytes(substream);
        idx = 0;
        ofs = 0;
-       for (i = 0; i < runtime->periods; i++) {
+       for (i = 0; i < periods; i++) {
                rest = fragsize;
                /* fill descriptors for a period.
                 * a period can be split to several descriptors if it's
@@ -241,7 +245,7 @@ static int build_via_table(viadev_t *dev, snd_pcm_substream_t *substream,
                                r = rest;
                        rest -= r;
                        if (! rest) {
-                               if (i == runtime->periods - 1)
+                               if (i == periods - 1)
                                        flag = VIA_TBL_BIT_EOL; /* buffer boundary */
                                else
                                        flag = VIA_TBL_BIT_FLAG; /* period boundary */
@@ -472,19 +476,14 @@ static int snd_via82xx_trigger(via82xx_t *chip, viadev_t *viadev, int cmd)
 }
 
 
-static int snd_via82xx_setup_periods(via82xx_t *chip, viadev_t *viadev,
-                                    snd_pcm_substream_t *substream)
+static int snd_via82xx_set_format(via82xx_t *chip, viadev_t *viadev,
+                                 snd_pcm_substream_t *substream)
 {
        snd_pcm_runtime_t *runtime = substream->runtime;
        unsigned long port = chip->port + viadev->reg_offset;
-       int err;
 
        snd_via82xx_channel_reset(chip, viadev);
 
-       err = build_via_table(viadev, substream, chip->pci);
-       if (err < 0)
-               return err;
-
        outl((u32)viadev->table_addr, port + VIA_REG_OFFSET_TABLE_PTR);
        switch (chip->chip_type) {
        case TYPE_VIA686:
@@ -583,11 +582,28 @@ static int snd_via82xx_capture_trigger(snd_pcm_substream_t * substream,
 static int snd_via82xx_hw_params(snd_pcm_substream_t * substream,
                                 snd_pcm_hw_params_t * hw_params)
 {
-       return snd_pcm_sgbuf_alloc(substream, params_buffer_bytes(hw_params));
+       via82xx_t *chip = snd_pcm_substream_chip(substream);
+       viadev_t *viadev = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? &chip->playback : &chip->capture;
+       int err;
+
+       err = snd_pcm_sgbuf_alloc(substream, params_buffer_bytes(hw_params));
+       if (err < 0)
+               return err;
+       err = build_via_table(viadev, substream, chip->pci,
+                             params_periods(hw_params),
+                             params_period_bytes(hw_params));
+       if (err < 0)
+               return err;
+       return err;
 }
 
 static int snd_via82xx_hw_free(snd_pcm_substream_t * substream)
 {
+       via82xx_t *chip = snd_pcm_substream_chip(substream);
+       viadev_t *viadev = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? &chip->playback : &chip->capture;
+
+       clean_via_table(viadev, substream, chip->pci);
+       snd_pcm_sgbuf_free(substream);
        return 0;
 }
 
@@ -606,7 +622,7 @@ static int snd_via82xx_playback_prepare(snd_pcm_substream_t * substream)
                tmp = inl(VIAREG(chip, PLAYBACK_STOP_IDX)) & ~0xfffff;
                outl(tmp | (0xffff * runtime->rate)/(48000/16), VIAREG(chip, PLAYBACK_STOP_IDX));
        }
-       return snd_via82xx_setup_periods(chip, &chip->playback, substream);
+       return snd_via82xx_set_format(chip, &chip->playback, substream);
 }
 
 static int snd_via82xx_capture_prepare(snd_pcm_substream_t * substream)
@@ -617,7 +633,7 @@ static int snd_via82xx_capture_prepare(snd_pcm_substream_t * substream)
        snd_ac97_set_rate(chip->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate);
        if (chip->chip_type == TYPE_VIA8233)
                outb(VIA_REG_CAPTURE_FIFO_ENABLE, VIAREG(chip, CAPTURE_FIFO));
-       return snd_via82xx_setup_periods(chip, &chip->capture, substream);
+       return snd_via82xx_set_format(chip, &chip->capture, substream);
 }
 
 static inline unsigned int snd_via82xx_cur_ptr(via82xx_t *chip, viadev_t *viadev)
@@ -761,20 +777,16 @@ static int snd_via82xx_capture_open(snd_pcm_substream_t * substream)
 static int snd_via82xx_playback_close(snd_pcm_substream_t * substream)
 {
        via82xx_t *chip = snd_pcm_substream_chip(substream);
-
-       clean_via_table(&chip->playback, substream, chip->pci);
-       snd_pcm_sgbuf_delete(substream);
        chip->playback.substream = NULL;
+       snd_pcm_sgbuf_delete(substream);
        return 0;
 }
 
 static int snd_via82xx_capture_close(snd_pcm_substream_t * substream)
 {
        via82xx_t *chip = snd_pcm_substream_chip(substream);
-
-       clean_via_table(&chip->capture, substream, chip->pci);
-       snd_pcm_sgbuf_delete(substream);
        chip->capture.substream = NULL;
+       snd_pcm_sgbuf_delete(substream);
        return 0;
 }