aboutsummaryrefslogtreecommitdiff
path: root/sound/drivers/dummy.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/drivers/dummy.c')
-rw-r--r--sound/drivers/dummy.c417
1 files changed, 278 insertions, 139 deletions
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index 252e04ce602..fab90bd2bd5 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -27,7 +27,7 @@
#include <linux/wait.h>
#include <linux/hrtimer.h>
#include <linux/math64.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
#include <sound/core.h>
#include <sound/control.h>
#include <sound/tlv.h>
@@ -45,116 +45,30 @@ MODULE_SUPPORTED_DEVICE("{{ALSA,Dummy soundcard}}");
#define MAX_PCM_SUBSTREAMS 128
#define MAX_MIDI_DEVICES 2
-#if 0 /* emu10k1 emulation */
-#define MAX_BUFFER_SIZE (128 * 1024)
-static int emu10k1_playback_constraints(struct snd_pcm_runtime *runtime)
-{
- int err;
- err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
- if (err < 0)
- return err;
- err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256, UINT_MAX);
- if (err < 0)
- return err;
- return 0;
-}
-#define add_playback_constraints emu10k1_playback_constraints
-#endif
-
-#if 0 /* RME9652 emulation */
-#define MAX_BUFFER_SIZE (26 * 64 * 1024)
-#define USE_FORMATS SNDRV_PCM_FMTBIT_S32_LE
-#define USE_CHANNELS_MIN 26
-#define USE_CHANNELS_MAX 26
-#define USE_PERIODS_MIN 2
-#define USE_PERIODS_MAX 2
-#endif
-
-#if 0 /* ICE1712 emulation */
-#define MAX_BUFFER_SIZE (256 * 1024)
-#define USE_FORMATS SNDRV_PCM_FMTBIT_S32_LE
-#define USE_CHANNELS_MIN 10
-#define USE_CHANNELS_MAX 10
-#define USE_PERIODS_MIN 1
-#define USE_PERIODS_MAX 1024
-#endif
-
-#if 0 /* UDA1341 emulation */
-#define MAX_BUFFER_SIZE (16380)
-#define USE_FORMATS SNDRV_PCM_FMTBIT_S16_LE
-#define USE_CHANNELS_MIN 2
-#define USE_CHANNELS_MAX 2
-#define USE_PERIODS_MIN 2
-#define USE_PERIODS_MAX 255
-#endif
-
-#if 0 /* simple AC97 bridge (intel8x0) with 48kHz AC97 only codec */
-#define USE_FORMATS SNDRV_PCM_FMTBIT_S16_LE
-#define USE_CHANNELS_MIN 2
-#define USE_CHANNELS_MAX 2
-#define USE_RATE SNDRV_PCM_RATE_48000
-#define USE_RATE_MIN 48000
-#define USE_RATE_MAX 48000
-#endif
-
-#if 0 /* CA0106 */
-#define USE_FORMATS SNDRV_PCM_FMTBIT_S16_LE
-#define USE_CHANNELS_MIN 2
-#define USE_CHANNELS_MAX 2
-#define USE_RATE (SNDRV_PCM_RATE_48000|SNDRV_PCM_RATE_96000|SNDRV_PCM_RATE_192000)
-#define USE_RATE_MIN 48000
-#define USE_RATE_MAX 192000
-#define MAX_BUFFER_SIZE ((65536-64)*8)
-#define MAX_PERIOD_SIZE (65536-64)
-#define USE_PERIODS_MIN 2
-#define USE_PERIODS_MAX 8
-#endif
-
-
/* defaults */
-#ifndef MAX_BUFFER_SIZE
#define MAX_BUFFER_SIZE (64*1024)
-#endif
-#ifndef MAX_PERIOD_SIZE
+#define MIN_PERIOD_SIZE 64
#define MAX_PERIOD_SIZE MAX_BUFFER_SIZE
-#endif
-#ifndef USE_FORMATS
#define USE_FORMATS (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE)
-#endif
-#ifndef USE_RATE
#define USE_RATE SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000
#define USE_RATE_MIN 5500
#define USE_RATE_MAX 48000
-#endif
-#ifndef USE_CHANNELS_MIN
#define USE_CHANNELS_MIN 1
-#endif
-#ifndef USE_CHANNELS_MAX
#define USE_CHANNELS_MAX 2
-#endif
-#ifndef USE_PERIODS_MIN
#define USE_PERIODS_MIN 1
-#endif
-#ifndef USE_PERIODS_MAX
#define USE_PERIODS_MAX 1024
-#endif
-#ifndef add_playback_constraints
-#define add_playback_constraints(x) 0
-#endif
-#ifndef add_capture_constraints
-#define add_capture_constraints(x) 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] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
+static bool enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
+static char *model[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = NULL};
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};
#ifdef CONFIG_HIGH_RES_TIMERS
-static int hrtimer = 1;
+static bool hrtimer = 1;
#endif
-static int fake_buffer = 1;
+static bool fake_buffer = 1;
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for dummy soundcard.");
@@ -162,6 +76,8 @@ module_param_array(id, charp, NULL, 0444);
MODULE_PARM_DESC(id, "ID string for dummy soundcard.");
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable this dummy soundcard.");
+module_param_array(model, charp, NULL, 0444);
+MODULE_PARM_DESC(model, "Soundcard model.");
module_param_array(pcm_devs, int, NULL, 0444);
MODULE_PARM_DESC(pcm_devs, "PCM devices # (0-4) for dummy driver.");
module_param_array(pcm_substreams, int, NULL, 0444);
@@ -193,16 +109,124 @@ struct dummy_timer_ops {
snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *);
};
+struct dummy_model {
+ const char *name;
+ int (*playback_constraints)(struct snd_pcm_runtime *runtime);
+ int (*capture_constraints)(struct snd_pcm_runtime *runtime);
+ u64 formats;
+ size_t buffer_bytes_max;
+ size_t period_bytes_min;
+ size_t period_bytes_max;
+ unsigned int periods_min;
+ unsigned int periods_max;
+ unsigned int rates;
+ unsigned int rate_min;
+ unsigned int rate_max;
+ unsigned int channels_min;
+ unsigned int channels_max;
+};
+
struct snd_dummy {
struct snd_card *card;
+ struct dummy_model *model;
struct snd_pcm *pcm;
+ struct snd_pcm_hardware pcm_hw;
spinlock_t mixer_lock;
int mixer_volume[MIXER_ADDR_LAST+1][2];
int capture_source[MIXER_ADDR_LAST+1][2];
+ int iobox;
+ struct snd_kcontrol *cd_volume_ctl;
+ struct snd_kcontrol *cd_switch_ctl;
const struct dummy_timer_ops *timer_ops;
};
/*
+ * card models
+ */
+
+static int emu10k1_playback_constraints(struct snd_pcm_runtime *runtime)
+{
+ int err;
+ err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+ if (err < 0)
+ return err;
+ err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256, UINT_MAX);
+ if (err < 0)
+ return err;
+ return 0;
+}
+
+struct dummy_model model_emu10k1 = {
+ .name = "emu10k1",
+ .playback_constraints = emu10k1_playback_constraints,
+ .buffer_bytes_max = 128 * 1024,
+};
+
+struct dummy_model model_rme9652 = {
+ .name = "rme9652",
+ .buffer_bytes_max = 26 * 64 * 1024,
+ .formats = SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 26,
+ .channels_max = 26,
+ .periods_min = 2,
+ .periods_max = 2,
+};
+
+struct dummy_model model_ice1712 = {
+ .name = "ice1712",
+ .buffer_bytes_max = 256 * 1024,
+ .formats = SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 10,
+ .channels_max = 10,
+ .periods_min = 1,
+ .periods_max = 1024,
+};
+
+struct dummy_model model_uda1341 = {
+ .name = "uda1341",
+ .buffer_bytes_max = 16380,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .periods_min = 2,
+ .periods_max = 255,
+};
+
+struct dummy_model model_ac97 = {
+ .name = "ac97",
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_48000,
+ .rate_min = 48000,
+ .rate_max = 48000,
+};
+
+struct dummy_model model_ca0106 = {
+ .name = "ca0106",
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .buffer_bytes_max = ((65536-64)*8),
+ .period_bytes_max = (65536-64),
+ .periods_min = 2,
+ .periods_max = 8,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_48000|SNDRV_PCM_RATE_96000|SNDRV_PCM_RATE_192000,
+ .rate_min = 48000,
+ .rate_max = 192000,
+};
+
+struct dummy_model *dummy_models[] = {
+ &model_emu10k1,
+ &model_rme9652,
+ &model_ice1712,
+ &model_uda1341,
+ &model_ac97,
+ &model_ca0106,
+ NULL
+};
+
+/*
* system timer interface
*/
@@ -509,7 +533,7 @@ static struct snd_pcm_hardware dummy_pcm_hardware = {
.channels_min = USE_CHANNELS_MIN,
.channels_max = USE_CHANNELS_MAX,
.buffer_bytes_max = MAX_BUFFER_SIZE,
- .period_bytes_min = 64,
+ .period_bytes_min = MIN_PERIOD_SIZE,
.period_bytes_max = MAX_PERIOD_SIZE,
.periods_min = USE_PERIODS_MIN,
.periods_max = USE_PERIODS_MAX,
@@ -538,6 +562,7 @@ static int dummy_pcm_hw_free(struct snd_pcm_substream *substream)
static int dummy_pcm_open(struct snd_pcm_substream *substream)
{
struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
+ struct dummy_model *model = dummy->model;
struct snd_pcm_runtime *runtime = substream->runtime;
int err;
@@ -551,7 +576,7 @@ static int dummy_pcm_open(struct snd_pcm_substream *substream)
if (err < 0)
return err;
- runtime->hw = dummy_pcm_hardware;
+ runtime->hw = dummy->pcm_hw;
if (substream->pcm->device & 1) {
runtime->hw.info &= ~SNDRV_PCM_INFO_INTERLEAVED;
runtime->hw.info |= SNDRV_PCM_INFO_NONINTERLEAVED;
@@ -560,10 +585,16 @@ static int dummy_pcm_open(struct snd_pcm_substream *substream)
runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- err = add_playback_constraints(substream->runtime);
- else
- err = add_capture_constraints(substream->runtime);
+ if (model == NULL)
+ return 0;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ if (model->playback_constraints)
+ err = model->playback_constraints(substream->runtime);
+ } else {
+ if (model->capture_constraints)
+ err = model->capture_constraints(substream->runtime);
+ }
if (err < 0) {
dummy->timer_ops->free(substream);
return err;
@@ -657,8 +688,8 @@ static struct snd_pcm_ops dummy_pcm_ops_no_buf = {
.page = dummy_pcm_page,
};
-static int __devinit snd_card_dummy_pcm(struct snd_dummy *dummy, int device,
- int substreams)
+static int snd_card_dummy_pcm(struct snd_dummy *dummy, int device,
+ int substreams)
{
struct snd_pcm *pcm;
struct snd_pcm_ops *ops;
@@ -789,6 +820,57 @@ static int snd_dummy_capsrc_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el
return change;
}
+static int snd_dummy_iobox_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *info)
+{
+ const char *const names[] = { "None", "CD Player" };
+
+ return snd_ctl_enum_info(info, 1, 2, names);
+}
+
+static int snd_dummy_iobox_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *value)
+{
+ struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
+
+ value->value.enumerated.item[0] = dummy->iobox;
+ return 0;
+}
+
+static int snd_dummy_iobox_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *value)
+{
+ struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
+ int changed;
+
+ if (value->value.enumerated.item[0] > 1)
+ return -EINVAL;
+
+ changed = value->value.enumerated.item[0] != dummy->iobox;
+ if (changed) {
+ dummy->iobox = value->value.enumerated.item[0];
+
+ if (dummy->iobox) {
+ dummy->cd_volume_ctl->vd[0].access &=
+ ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+ dummy->cd_switch_ctl->vd[0].access &=
+ ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+ } else {
+ dummy->cd_volume_ctl->vd[0].access |=
+ SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+ dummy->cd_switch_ctl->vd[0].access |=
+ SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+ }
+
+ snd_ctl_notify(dummy->card, SNDRV_CTL_EVENT_MASK_INFO,
+ &dummy->cd_volume_ctl->id);
+ snd_ctl_notify(dummy->card, SNDRV_CTL_EVENT_MASK_INFO,
+ &dummy->cd_switch_ctl->id);
+ }
+
+ return changed;
+}
+
static struct snd_kcontrol_new snd_dummy_controls[] = {
DUMMY_VOLUME("Master Volume", 0, MIXER_ADDR_MASTER),
DUMMY_CAPSRC("Master Capture Switch", 0, MIXER_ADDR_MASTER),
@@ -799,22 +881,37 @@ DUMMY_CAPSRC("Line Capture Switch", 0, MIXER_ADDR_LINE),
DUMMY_VOLUME("Mic Volume", 0, MIXER_ADDR_MIC),
DUMMY_CAPSRC("Mic Capture Switch", 0, MIXER_ADDR_MIC),
DUMMY_VOLUME("CD Volume", 0, MIXER_ADDR_CD),
-DUMMY_CAPSRC("CD Capture Switch", 0, MIXER_ADDR_CD)
+DUMMY_CAPSRC("CD Capture Switch", 0, MIXER_ADDR_CD),
+{
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "External I/O Box",
+ .info = snd_dummy_iobox_info,
+ .get = snd_dummy_iobox_get,
+ .put = snd_dummy_iobox_put,
+},
};
-static int __devinit snd_card_dummy_new_mixer(struct snd_dummy *dummy)
+static int snd_card_dummy_new_mixer(struct snd_dummy *dummy)
{
struct snd_card *card = dummy->card;
+ struct snd_kcontrol *kcontrol;
unsigned int idx;
int err;
spin_lock_init(&dummy->mixer_lock);
strcpy(card->mixername, "Dummy Mixer");
+ dummy->iobox = 1;
for (idx = 0; idx < ARRAY_SIZE(snd_dummy_controls); idx++) {
- err = snd_ctl_add(card, snd_ctl_new1(&snd_dummy_controls[idx], dummy));
+ kcontrol = snd_ctl_new1(&snd_dummy_controls[idx], dummy);
+ err = snd_ctl_add(card, kcontrol);
if (err < 0)
return err;
+ if (!strcmp(kcontrol->id.name, "CD Volume"))
+ dummy->cd_volume_ctl = kcontrol;
+ else if (!strcmp(kcontrol->id.name, "CD Capture Switch"))
+ dummy->cd_switch_ctl = kcontrol;
+
}
return 0;
}
@@ -823,17 +920,19 @@ static int __devinit snd_card_dummy_new_mixer(struct snd_dummy *dummy)
/*
* proc interface
*/
-static void print_formats(struct snd_info_buffer *buffer)
+static void print_formats(struct snd_dummy *dummy,
+ struct snd_info_buffer *buffer)
{
int i;
for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) {
- if (dummy_pcm_hardware.formats & (1ULL << i))
+ if (dummy->pcm_hw.formats & (1ULL << i))
snd_iprintf(buffer, " %s", snd_pcm_format_name(i));
}
}
-static void print_rates(struct snd_info_buffer *buffer)
+static void print_rates(struct snd_dummy *dummy,
+ struct snd_info_buffer *buffer)
{
static int rates[] = {
5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000,
@@ -841,19 +940,19 @@ static void print_rates(struct snd_info_buffer *buffer)
};
int i;
- if (dummy_pcm_hardware.rates & SNDRV_PCM_RATE_CONTINUOUS)
+ if (dummy->pcm_hw.rates & SNDRV_PCM_RATE_CONTINUOUS)
snd_iprintf(buffer, " continuous");
- if (dummy_pcm_hardware.rates & SNDRV_PCM_RATE_KNOT)
+ if (dummy->pcm_hw.rates & SNDRV_PCM_RATE_KNOT)
snd_iprintf(buffer, " knot");
for (i = 0; i < ARRAY_SIZE(rates); i++)
- if (dummy_pcm_hardware.rates & (1 << i))
+ if (dummy->pcm_hw.rates & (1 << i))
snd_iprintf(buffer, " %d", rates[i]);
}
-#define get_dummy_int_ptr(ofs) \
- (unsigned int *)((char *)&dummy_pcm_hardware + (ofs))
-#define get_dummy_ll_ptr(ofs) \
- (unsigned long long *)((char *)&dummy_pcm_hardware + (ofs))
+#define get_dummy_int_ptr(dummy, ofs) \
+ (unsigned int *)((char *)&((dummy)->pcm_hw) + (ofs))
+#define get_dummy_ll_ptr(dummy, ofs) \
+ (unsigned long long *)((char *)&((dummy)->pcm_hw) + (ofs))
struct dummy_hw_field {
const char *name;
@@ -884,20 +983,21 @@ static struct dummy_hw_field fields[] = {
static void dummy_proc_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{
+ struct snd_dummy *dummy = entry->private_data;
int i;
for (i = 0; i < ARRAY_SIZE(fields); i++) {
snd_iprintf(buffer, "%s ", fields[i].name);
if (fields[i].size == sizeof(int))
snd_iprintf(buffer, fields[i].format,
- *get_dummy_int_ptr(fields[i].offset));
+ *get_dummy_int_ptr(dummy, fields[i].offset));
else
snd_iprintf(buffer, fields[i].format,
- *get_dummy_ll_ptr(fields[i].offset));
+ *get_dummy_ll_ptr(dummy, fields[i].offset));
if (!strcmp(fields[i].name, "formats"))
- print_formats(buffer);
+ print_formats(dummy, buffer);
else if (!strcmp(fields[i].name, "rates"))
- print_rates(buffer);
+ print_rates(dummy, buffer);
snd_iprintf(buffer, "\n");
}
}
@@ -905,6 +1005,7 @@ static void dummy_proc_read(struct snd_info_entry *entry,
static void dummy_proc_write(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{
+ struct snd_dummy *dummy = entry->private_data;
char line[64];
while (!snd_info_get_line(buffer, line, sizeof(line))) {
@@ -921,16 +1022,16 @@ static void dummy_proc_write(struct snd_info_entry *entry,
if (i >= ARRAY_SIZE(fields))
continue;
snd_info_get_str(item, ptr, sizeof(item));
- if (strict_strtoull(item, 0, &val))
+ if (kstrtoull(item, 0, &val))
continue;
if (fields[i].size == sizeof(int))
- *get_dummy_int_ptr(fields[i].offset) = val;
+ *get_dummy_int_ptr(dummy, fields[i].offset) = val;
else
- *get_dummy_ll_ptr(fields[i].offset) = val;
+ *get_dummy_ll_ptr(dummy, fields[i].offset) = val;
}
}
-static void __devinit dummy_proc_init(struct snd_dummy *chip)
+static void dummy_proc_init(struct snd_dummy *chip)
{
struct snd_info_entry *entry;
@@ -938,25 +1039,36 @@ static void __devinit dummy_proc_init(struct snd_dummy *chip)
snd_info_set_text_ops(entry, chip, dummy_proc_read);
entry->c.text.write = dummy_proc_write;
entry->mode |= S_IWUSR;
+ entry->private_data = chip;
}
}
#else
#define dummy_proc_init(x)
#endif /* CONFIG_SND_DEBUG && CONFIG_PROC_FS */
-static int __devinit snd_dummy_probe(struct platform_device *devptr)
+static int snd_dummy_probe(struct platform_device *devptr)
{
struct snd_card *card;
struct snd_dummy *dummy;
+ struct dummy_model *m = NULL, **mdl;
int idx, err;
int dev = devptr->id;
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct snd_dummy), &card);
+ err = snd_card_new(&devptr->dev, index[dev], id[dev], THIS_MODULE,
+ sizeof(struct snd_dummy), &card);
if (err < 0)
return err;
dummy = card->private_data;
dummy->card = card;
+ for (mdl = dummy_models; *mdl && model[dev]; mdl++) {
+ if (strcmp(model[dev], (*mdl)->name) == 0) {
+ printk(KERN_INFO
+ "snd-dummy: Using model '%s' for card %i\n",
+ (*mdl)->name, card->number);
+ m = dummy->model = *mdl;
+ break;
+ }
+ }
for (idx = 0; idx < MAX_PCM_DEVICES && idx < pcm_devs[dev]; idx++) {
if (pcm_substreams[dev] < 1)
pcm_substreams[dev] = 1;
@@ -966,6 +1078,33 @@ static int __devinit snd_dummy_probe(struct platform_device *devptr)
if (err < 0)
goto __nodev;
}
+
+ dummy->pcm_hw = dummy_pcm_hardware;
+ if (m) {
+ if (m->formats)
+ dummy->pcm_hw.formats = m->formats;
+ if (m->buffer_bytes_max)
+ dummy->pcm_hw.buffer_bytes_max = m->buffer_bytes_max;
+ if (m->period_bytes_min)
+ dummy->pcm_hw.period_bytes_min = m->period_bytes_min;
+ if (m->period_bytes_max)
+ dummy->pcm_hw.period_bytes_max = m->period_bytes_max;
+ if (m->periods_min)
+ dummy->pcm_hw.periods_min = m->periods_min;
+ if (m->periods_max)
+ dummy->pcm_hw.periods_max = m->periods_max;
+ if (m->rates)
+ dummy->pcm_hw.rates = m->rates;
+ if (m->rate_min)
+ dummy->pcm_hw.rate_min = m->rate_min;
+ if (m->rate_max)
+ dummy->pcm_hw.rate_max = m->rate_max;
+ if (m->channels_min)
+ dummy->pcm_hw.channels_min = m->channels_min;
+ if (m->channels_max)
+ dummy->pcm_hw.channels_max = m->channels_max;
+ }
+
err = snd_card_dummy_new_mixer(dummy);
if (err < 0)
goto __nodev;
@@ -975,8 +1114,6 @@ static int __devinit snd_dummy_probe(struct platform_device *devptr)
dummy_proc_init(dummy);
- snd_card_set_dev(card, &devptr->dev);
-
err = snd_card_register(card);
if (err == 0) {
platform_set_drvdata(devptr, card);
@@ -987,17 +1124,16 @@ static int __devinit snd_dummy_probe(struct platform_device *devptr)
return err;
}
-static int __devexit snd_dummy_remove(struct platform_device *devptr)
+static int snd_dummy_remove(struct platform_device *devptr)
{
snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
return 0;
}
-#ifdef CONFIG_PM
-static int snd_dummy_suspend(struct platform_device *pdev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int snd_dummy_suspend(struct device *pdev)
{
- struct snd_card *card = platform_get_drvdata(pdev);
+ struct snd_card *card = dev_get_drvdata(pdev);
struct snd_dummy *dummy = card->private_data;
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
@@ -1005,26 +1141,29 @@ static int snd_dummy_suspend(struct platform_device *pdev, pm_message_t state)
return 0;
}
-static int snd_dummy_resume(struct platform_device *pdev)
+static int snd_dummy_resume(struct device *pdev)
{
- struct snd_card *card = platform_get_drvdata(pdev);
+ struct snd_card *card = dev_get_drvdata(pdev);
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
return 0;
}
+
+static SIMPLE_DEV_PM_OPS(snd_dummy_pm, snd_dummy_suspend, snd_dummy_resume);
+#define SND_DUMMY_PM_OPS &snd_dummy_pm
+#else
+#define SND_DUMMY_PM_OPS NULL
#endif
#define SND_DUMMY_DRIVER "snd_dummy"
static struct platform_driver snd_dummy_driver = {
.probe = snd_dummy_probe,
- .remove = __devexit_p(snd_dummy_remove),
-#ifdef CONFIG_PM
- .suspend = snd_dummy_suspend,
- .resume = snd_dummy_resume,
-#endif
+ .remove = snd_dummy_remove,
.driver = {
- .name = SND_DUMMY_DRIVER
+ .name = SND_DUMMY_DRIVER,
+ .owner = THIS_MODULE,
+ .pm = SND_DUMMY_PM_OPS,
},
};