vserver 1.9.3
[linux-2.6.git] / sound / drivers / dummy.c
index e707b8f..fb469d9 100644 (file)
 #include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/wait.h>
+#include <linux/moduleparam.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/pcm.h>
 #include <sound/rawmidi.h>
-#define SNDRV_GET_ID
 #include <sound/initval.h>
 
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
 MODULE_DESCRIPTION("Dummy soundcard (/dev/null)");
 MODULE_LICENSE("GPL");
-MODULE_CLASSES("{sound}");
-MODULE_DEVICES("{{ALSA,Dummy soundcard}}");
+MODULE_SUPPORTED_DEVICE("{{ALSA,Dummy soundcard}}");
 
 #define MAX_PCM_DEVICES                4
 #define MAX_PCM_SUBSTREAMS     16
@@ -129,25 +128,20 @@ static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
 static int pcm_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
 static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8};
 //static int midi_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
+static int boot_devs;
 
-MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+module_param_array(index, int, boot_devs, 0444);
 MODULE_PARM_DESC(index, "Index value for dummy soundcard.");
-MODULE_PARM_SYNTAX(index, SNDRV_INDEX_DESC);
-MODULE_PARM(id, "1-" __MODULE_STRING(SNDRV_CARDS) "s");
+module_param_array(id, charp, boot_devs, 0444);
 MODULE_PARM_DESC(id, "ID string for dummy soundcard.");
-MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC);
-MODULE_PARM(enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+module_param_array(enable, bool, boot_devs, 0444);
 MODULE_PARM_DESC(enable, "Enable this dummy soundcard.");
-MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
-MODULE_PARM(pcm_devs, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+module_param_array(pcm_devs, int, boot_devs, 0444);
 MODULE_PARM_DESC(pcm_devs, "PCM devices # (0-4) for dummy driver.");
-MODULE_PARM_SYNTAX(pcm_devs, SNDRV_ENABLED ",allows:{{0,4}},default:1,dialog:list");
-MODULE_PARM(pcm_substreams, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+module_param_array(pcm_substreams, int, boot_devs, 0444);
 MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-16) for dummy driver.");
-MODULE_PARM_SYNTAX(pcm_substreams, SNDRV_ENABLED ",allows:{{1,16}},default:8,dialog:list");
-//MODULE_PARM(midi_devs, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+//module_param_array(midi_devs, int, boot_devs, 0444);
 //MODULE_PARM_DESC(midi_devs, "MIDI devices # (0-2) for dummy driver.");
-//MODULE_PARM_SYNTAX(midi_devs, SNDRV_ENABLED ",allows:{{0,2}},default:8,dialog:list");
 
 #define MIXER_ADDR_MASTER      0
 #define MIXER_ADDR_LINE                1
@@ -179,24 +173,10 @@ typedef struct snd_card_dummy_pcm {
 static snd_card_t *snd_dummy_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
 
 
-static int snd_card_dummy_playback_ioctl(snd_pcm_substream_t * substream,
-                                        unsigned int cmd,
-                                        void *arg)
-{
-       return snd_pcm_lib_ioctl(substream, cmd, arg);
-}
-
-static int snd_card_dummy_capture_ioctl(snd_pcm_substream_t * substream,
-                                       unsigned int cmd,
-                                       void *arg)
-{
-       return snd_pcm_lib_ioctl(substream, cmd, arg);
-}
-
 static void snd_card_dummy_pcm_timer_start(snd_pcm_substream_t * substream)
 {
        snd_pcm_runtime_t *runtime = substream->runtime;
-       snd_card_dummy_pcm_t *dpcm = snd_magic_cast(snd_card_dummy_pcm_t, runtime->private_data, return);
+       snd_card_dummy_pcm_t *dpcm = runtime->private_data;
 
        dpcm->timer.expires = 1 + jiffies;
        add_timer(&dpcm->timer);
@@ -205,7 +185,7 @@ static void snd_card_dummy_pcm_timer_start(snd_pcm_substream_t * substream)
 static void snd_card_dummy_pcm_timer_stop(snd_pcm_substream_t * substream)
 {
        snd_pcm_runtime_t *runtime = substream->runtime;
-       snd_card_dummy_pcm_t *dpcm = snd_magic_cast(snd_card_dummy_pcm_t, runtime->private_data, return);
+       snd_card_dummy_pcm_t *dpcm = runtime->private_data;
 
        del_timer(&dpcm->timer);
 }
@@ -239,7 +219,7 @@ static int snd_card_dummy_capture_trigger(snd_pcm_substream_t * substream,
 static int snd_card_dummy_pcm_prepare(snd_pcm_substream_t * substream)
 {
        snd_pcm_runtime_t *runtime = substream->runtime;
-       snd_card_dummy_pcm_t *dpcm = snd_magic_cast(snd_card_dummy_pcm_t, runtime->private_data, return -ENXIO);
+       snd_card_dummy_pcm_t *dpcm = runtime->private_data;
        unsigned int bps;
 
        bps = runtime->rate * runtime->channels;
@@ -268,7 +248,7 @@ static int snd_card_dummy_capture_prepare(snd_pcm_substream_t * substream)
 
 static void snd_card_dummy_pcm_timer_function(unsigned long data)
 {
-       snd_card_dummy_pcm_t *dpcm = snd_magic_cast(snd_card_dummy_pcm_t, (void *)data, return);
+       snd_card_dummy_pcm_t *dpcm = (snd_card_dummy_pcm_t *)data;
        
        dpcm->timer.expires = 1 + jiffies;
        add_timer(&dpcm->timer);
@@ -286,7 +266,7 @@ static void snd_card_dummy_pcm_timer_function(unsigned long data)
 static snd_pcm_uframes_t snd_card_dummy_playback_pointer(snd_pcm_substream_t * substream)
 {
        snd_pcm_runtime_t *runtime = substream->runtime;
-       snd_card_dummy_pcm_t *dpcm = snd_magic_cast(snd_card_dummy_pcm_t, runtime->private_data, return -ENXIO);
+       snd_card_dummy_pcm_t *dpcm = runtime->private_data;
 
        return bytes_to_frames(runtime, dpcm->pcm_buf_pos);
 }
@@ -294,7 +274,7 @@ static snd_pcm_uframes_t snd_card_dummy_playback_pointer(snd_pcm_substream_t * s
 static snd_pcm_uframes_t snd_card_dummy_capture_pointer(snd_pcm_substream_t * substream)
 {
        snd_pcm_runtime_t *runtime = substream->runtime;
-       snd_card_dummy_pcm_t *dpcm = snd_magic_cast(snd_card_dummy_pcm_t, runtime->private_data, return -ENXIO);
+       snd_card_dummy_pcm_t *dpcm = runtime->private_data;
 
        return bytes_to_frames(runtime, dpcm->pcm_buf_pos);
 }
@@ -337,8 +317,19 @@ static snd_pcm_hardware_t snd_card_dummy_capture =
 
 static void snd_card_dummy_runtime_free(snd_pcm_runtime_t *runtime)
 {
-       snd_card_dummy_pcm_t *dpcm = snd_magic_cast(snd_card_dummy_pcm_t, runtime->private_data, return);
-       snd_magic_kfree(dpcm);
+       snd_card_dummy_pcm_t *dpcm = runtime->private_data;
+       kfree(dpcm);
+}
+
+static int snd_card_dummy_hw_params(snd_pcm_substream_t * substream,
+                                   snd_pcm_hw_params_t * hw_params)
+{
+       return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
+}
+
+static int snd_card_dummy_hw_free(snd_pcm_substream_t * substream)
+{
+       return snd_pcm_lib_free_pages(substream);
 }
 
 static int snd_card_dummy_playback_open(snd_pcm_substream_t * substream)
@@ -347,13 +338,9 @@ static int snd_card_dummy_playback_open(snd_pcm_substream_t * substream)
        snd_card_dummy_pcm_t *dpcm;
        int err;
 
-       dpcm = snd_magic_kcalloc(snd_card_dummy_pcm_t, 0, GFP_KERNEL);
+       dpcm = kcalloc(1, sizeof(*dpcm), GFP_KERNEL);
        if (dpcm == NULL)
                return -ENOMEM;
-       if ((runtime->dma_area = snd_malloc_pages_fallback(MAX_BUFFER_SIZE, GFP_KERNEL, &runtime->dma_bytes)) == NULL) {
-               snd_magic_kfree(dpcm);
-               return -ENOMEM;
-       }
        init_timer(&dpcm->timer);
        dpcm->timer.data = (unsigned long) dpcm;
        dpcm->timer.function = snd_card_dummy_pcm_timer_function;
@@ -369,7 +356,7 @@ static int snd_card_dummy_playback_open(snd_pcm_substream_t * substream)
        if (substream->pcm->device & 2)
                runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID);
        if ((err = add_playback_constraints(runtime)) < 0) {
-               snd_magic_kfree(dpcm);
+               kfree(dpcm);
                return err;
        }
 
@@ -382,14 +369,9 @@ static int snd_card_dummy_capture_open(snd_pcm_substream_t * substream)
        snd_card_dummy_pcm_t *dpcm;
        int err;
 
-       dpcm = snd_magic_kcalloc(snd_card_dummy_pcm_t, 0, GFP_KERNEL);
+       dpcm = kcalloc(1, sizeof(*dpcm), GFP_KERNEL);
        if (dpcm == NULL)
                return -ENOMEM;
-       if ((runtime->dma_area = snd_malloc_pages_fallback(MAX_BUFFER_SIZE, GFP_KERNEL, &runtime->dma_bytes)) == NULL) {
-               snd_magic_kfree(dpcm);
-               return -ENOMEM;
-       }
-       memset(runtime->dma_area, 0, runtime->dma_bytes);
        init_timer(&dpcm->timer);
        dpcm->timer.data = (unsigned long) dpcm;
        dpcm->timer.function = snd_card_dummy_pcm_timer_function;
@@ -405,7 +387,7 @@ static int snd_card_dummy_capture_open(snd_pcm_substream_t * substream)
        if (substream->pcm->device & 2)
                runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID);
        if ((err = add_capture_constraints(runtime)) < 0) {
-               snd_magic_kfree(dpcm);
+               kfree(dpcm);
                return err;
        }
 
@@ -414,24 +396,20 @@ static int snd_card_dummy_capture_open(snd_pcm_substream_t * substream)
 
 static int snd_card_dummy_playback_close(snd_pcm_substream_t * substream)
 {
-       snd_pcm_runtime_t *runtime = substream->runtime;
-
-       snd_free_pages(runtime->dma_area, runtime->dma_bytes);
        return 0;
 }
 
 static int snd_card_dummy_capture_close(snd_pcm_substream_t * substream)
 {
-       snd_pcm_runtime_t *runtime = substream->runtime;
-
-       snd_free_pages(runtime->dma_area, runtime->dma_bytes);
        return 0;
 }
 
 static snd_pcm_ops_t snd_card_dummy_playback_ops = {
        .open =                 snd_card_dummy_playback_open,
        .close =                snd_card_dummy_playback_close,
-       .ioctl =                snd_card_dummy_playback_ioctl,
+       .ioctl =                snd_pcm_lib_ioctl,
+       .hw_params =            snd_card_dummy_hw_params,
+       .hw_free =              snd_card_dummy_hw_free,
        .prepare =              snd_card_dummy_playback_prepare,
        .trigger =              snd_card_dummy_playback_trigger,
        .pointer =              snd_card_dummy_playback_pointer,
@@ -440,7 +418,9 @@ static snd_pcm_ops_t snd_card_dummy_playback_ops = {
 static snd_pcm_ops_t snd_card_dummy_capture_ops = {
        .open =                 snd_card_dummy_capture_open,
        .close =                snd_card_dummy_capture_close,
-       .ioctl =                snd_card_dummy_capture_ioctl,
+       .ioctl =                snd_pcm_lib_ioctl,
+       .hw_params =            snd_card_dummy_hw_params,
+       .hw_free =              snd_card_dummy_hw_free,
        .prepare =              snd_card_dummy_capture_prepare,
        .trigger =              snd_card_dummy_capture_trigger,
        .pointer =              snd_card_dummy_capture_pointer,
@@ -458,6 +438,9 @@ static int __init snd_card_dummy_pcm(snd_card_dummy_t *dummy, int device, int su
        pcm->private_data = dummy;
        pcm->info_flags = 0;
        strcpy(pcm->name, "Dummy PCM");
+       snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
+                                             snd_dma_continuous_data(GFP_KERNEL),
+                                             0, 64*1024);
        return 0;
 }
 
@@ -478,7 +461,7 @@ static int snd_dummy_volume_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t
  
 static int snd_dummy_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       snd_card_dummy_t *dummy = _snd_kcontrol_chip(kcontrol);
+       snd_card_dummy_t *dummy = snd_kcontrol_chip(kcontrol);
        unsigned long flags;
        int addr = kcontrol->private_value;
 
@@ -487,11 +470,11 @@ static int snd_dummy_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
        ucontrol->value.integer.value[1] = dummy->mixer_volume[addr][1];
        spin_unlock_irqrestore(&dummy->mixer_lock, flags);
        return 0;
-}                                                                                                                                                                                                                                                                                                            
+}
 
 static int snd_dummy_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       snd_card_dummy_t *dummy = _snd_kcontrol_chip(kcontrol);
+       snd_card_dummy_t *dummy = snd_kcontrol_chip(kcontrol);
        unsigned long flags;
        int change, addr = kcontrol->private_value;
        int left, right;
@@ -513,7 +496,7 @@ static int snd_dummy_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
        dummy->mixer_volume[addr][1] = right;
        spin_unlock_irqrestore(&dummy->mixer_lock, flags);
        return change;
-}                                                                                                                                                                                                                                                                                                            
+}
 
 #define DUMMY_CAPSRC(xname, xindex, addr) \
 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
@@ -532,7 +515,7 @@ static int snd_dummy_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t
  
 static int snd_dummy_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       snd_card_dummy_t *dummy = _snd_kcontrol_chip(kcontrol);
+       snd_card_dummy_t *dummy = snd_kcontrol_chip(kcontrol);
        unsigned long flags;
        int addr = kcontrol->private_value;
 
@@ -545,7 +528,7 @@ static int snd_dummy_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
 
 static int snd_dummy_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-       snd_card_dummy_t *dummy = _snd_kcontrol_chip(kcontrol);
+       snd_card_dummy_t *dummy = snd_kcontrol_chip(kcontrol);
        unsigned long flags;
        int change, addr = kcontrol->private_value;
        int left, right;
@@ -559,9 +542,7 @@ static int snd_dummy_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
        dummy->capture_source[addr][1] = right;
        spin_unlock_irqrestore(&dummy->mixer_lock, flags);
        return change;
-}                                                                                                                                                                                                                                                                                                            
-
-#define DUMMY_CONTROLS (sizeof(snd_dummy_controls)/sizeof(snd_kcontrol_new_t))
+}
 
 static snd_kcontrol_new_t snd_dummy_controls[] = {
 DUMMY_VOLUME("Master Volume", 0, MIXER_ADDR_MASTER),
@@ -586,7 +567,7 @@ int __init snd_card_dummy_new_mixer(snd_card_dummy_t * dummy)
        spin_lock_init(&dummy->mixer_lock);
        strcpy(card->mixername, "Dummy Mixer");
 
-       for (idx = 0; idx < DUMMY_CONTROLS; idx++) {
+       for (idx = 0; idx < ARRAY_SIZE(snd_dummy_controls); idx++) {
                if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_dummy_controls[idx], dummy))) < 0)
                        return err;
        }
@@ -661,27 +642,3 @@ static void __exit alsa_card_dummy_exit(void)
 
 module_init(alsa_card_dummy_init)
 module_exit(alsa_card_dummy_exit)
-
-#ifndef MODULE
-
-/* format is: snd-dummy=enable,index,id,
-                       pcm_devs,pcm_substreams */
-
-static int __init alsa_card_dummy_setup(char *str)
-{
-       static unsigned __initdata nr_dev = 0;
-
-       if (nr_dev >= SNDRV_CARDS)
-               return 0;
-       (void)(get_option(&str,&enable[nr_dev]) == 2 &&
-              get_option(&str,&index[nr_dev]) == 2 &&
-              get_id(&str,&id[nr_dev]) == 2 &&
-              get_option(&str,&pcm_devs[nr_dev]) == 2 &&
-              get_option(&str,&pcm_substreams[nr_dev]) == 2);
-       nr_dev++;
-       return 1;
-}
-
-__setup("snd-dummy=", alsa_card_dummy_setup);
-
-#endif /* ifndef MODULE */