Merge remote branch 'alsa/devel' into topic/misc
This commit is contained in:
commit
a540e13386
3 changed files with 273 additions and 165 deletions
|
@ -45,109 +45,23 @@ MODULE_SUPPORTED_DEVICE("{{ALSA,Dummy soundcard}}");
|
||||||
#define MAX_PCM_SUBSTREAMS 128
|
#define MAX_PCM_SUBSTREAMS 128
|
||||||
#define MAX_MIDI_DEVICES 2
|
#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 */
|
/* defaults */
|
||||||
#ifndef MAX_BUFFER_SIZE
|
|
||||||
#define MAX_BUFFER_SIZE (64*1024)
|
#define MAX_BUFFER_SIZE (64*1024)
|
||||||
#endif
|
#define MIN_PERIOD_SIZE 64
|
||||||
#ifndef MAX_PERIOD_SIZE
|
|
||||||
#define MAX_PERIOD_SIZE MAX_BUFFER_SIZE
|
#define MAX_PERIOD_SIZE MAX_BUFFER_SIZE
|
||||||
#endif
|
|
||||||
#ifndef USE_FORMATS
|
|
||||||
#define USE_FORMATS (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE)
|
#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 SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000
|
||||||
#define USE_RATE_MIN 5500
|
#define USE_RATE_MIN 5500
|
||||||
#define USE_RATE_MAX 48000
|
#define USE_RATE_MAX 48000
|
||||||
#endif
|
|
||||||
#ifndef USE_CHANNELS_MIN
|
|
||||||
#define USE_CHANNELS_MIN 1
|
#define USE_CHANNELS_MIN 1
|
||||||
#endif
|
|
||||||
#ifndef USE_CHANNELS_MAX
|
|
||||||
#define USE_CHANNELS_MAX 2
|
#define USE_CHANNELS_MAX 2
|
||||||
#endif
|
|
||||||
#ifndef USE_PERIODS_MIN
|
|
||||||
#define USE_PERIODS_MIN 1
|
#define USE_PERIODS_MIN 1
|
||||||
#endif
|
|
||||||
#ifndef USE_PERIODS_MAX
|
|
||||||
#define USE_PERIODS_MAX 1024
|
#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 int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
|
||||||
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
|
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
|
||||||
static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
|
static int 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_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
|
||||||
static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8};
|
static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8};
|
||||||
//static int midi_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
|
//static int midi_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
|
||||||
|
@ -162,6 +76,8 @@ module_param_array(id, charp, NULL, 0444);
|
||||||
MODULE_PARM_DESC(id, "ID string for dummy soundcard.");
|
MODULE_PARM_DESC(id, "ID string for dummy soundcard.");
|
||||||
module_param_array(enable, bool, NULL, 0444);
|
module_param_array(enable, bool, NULL, 0444);
|
||||||
MODULE_PARM_DESC(enable, "Enable this dummy soundcard.");
|
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_param_array(pcm_devs, int, NULL, 0444);
|
||||||
MODULE_PARM_DESC(pcm_devs, "PCM devices # (0-4) for dummy driver.");
|
MODULE_PARM_DESC(pcm_devs, "PCM devices # (0-4) for dummy driver.");
|
||||||
module_param_array(pcm_substreams, int, NULL, 0444);
|
module_param_array(pcm_substreams, int, NULL, 0444);
|
||||||
|
@ -193,15 +109,120 @@ struct dummy_timer_ops {
|
||||||
snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *);
|
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_dummy {
|
||||||
struct snd_card *card;
|
struct snd_card *card;
|
||||||
|
struct dummy_model *model;
|
||||||
struct snd_pcm *pcm;
|
struct snd_pcm *pcm;
|
||||||
|
struct snd_pcm_hardware pcm_hw;
|
||||||
spinlock_t mixer_lock;
|
spinlock_t mixer_lock;
|
||||||
int mixer_volume[MIXER_ADDR_LAST+1][2];
|
int mixer_volume[MIXER_ADDR_LAST+1][2];
|
||||||
int capture_source[MIXER_ADDR_LAST+1][2];
|
int capture_source[MIXER_ADDR_LAST+1][2];
|
||||||
const struct dummy_timer_ops *timer_ops;
|
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
|
* system timer interface
|
||||||
*/
|
*/
|
||||||
|
@ -509,7 +530,7 @@ static struct snd_pcm_hardware dummy_pcm_hardware = {
|
||||||
.channels_min = USE_CHANNELS_MIN,
|
.channels_min = USE_CHANNELS_MIN,
|
||||||
.channels_max = USE_CHANNELS_MAX,
|
.channels_max = USE_CHANNELS_MAX,
|
||||||
.buffer_bytes_max = MAX_BUFFER_SIZE,
|
.buffer_bytes_max = MAX_BUFFER_SIZE,
|
||||||
.period_bytes_min = 64,
|
.period_bytes_min = MIN_PERIOD_SIZE,
|
||||||
.period_bytes_max = MAX_PERIOD_SIZE,
|
.period_bytes_max = MAX_PERIOD_SIZE,
|
||||||
.periods_min = USE_PERIODS_MIN,
|
.periods_min = USE_PERIODS_MIN,
|
||||||
.periods_max = USE_PERIODS_MAX,
|
.periods_max = USE_PERIODS_MAX,
|
||||||
|
@ -538,6 +559,7 @@ static int dummy_pcm_hw_free(struct snd_pcm_substream *substream)
|
||||||
static int dummy_pcm_open(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 snd_dummy *dummy = snd_pcm_substream_chip(substream);
|
||||||
|
struct dummy_model *model = dummy->model;
|
||||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -551,7 +573,7 @@ static int dummy_pcm_open(struct snd_pcm_substream *substream)
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
runtime->hw = dummy_pcm_hardware;
|
runtime->hw = dummy->pcm_hw;
|
||||||
if (substream->pcm->device & 1) {
|
if (substream->pcm->device & 1) {
|
||||||
runtime->hw.info &= ~SNDRV_PCM_INFO_INTERLEAVED;
|
runtime->hw.info &= ~SNDRV_PCM_INFO_INTERLEAVED;
|
||||||
runtime->hw.info |= SNDRV_PCM_INFO_NONINTERLEAVED;
|
runtime->hw.info |= SNDRV_PCM_INFO_NONINTERLEAVED;
|
||||||
|
@ -560,10 +582,16 @@ static int dummy_pcm_open(struct snd_pcm_substream *substream)
|
||||||
runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP |
|
runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP |
|
||||||
SNDRV_PCM_INFO_MMAP_VALID);
|
SNDRV_PCM_INFO_MMAP_VALID);
|
||||||
|
|
||||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
if (model == NULL)
|
||||||
err = add_playback_constraints(substream->runtime);
|
return 0;
|
||||||
else
|
|
||||||
err = add_capture_constraints(substream->runtime);
|
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) {
|
if (err < 0) {
|
||||||
dummy->timer_ops->free(substream);
|
dummy->timer_ops->free(substream);
|
||||||
return err;
|
return err;
|
||||||
|
@ -823,17 +851,19 @@ static int __devinit snd_card_dummy_new_mixer(struct snd_dummy *dummy)
|
||||||
/*
|
/*
|
||||||
* proc interface
|
* 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;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < SNDRV_PCM_FORMAT_LAST; 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));
|
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[] = {
|
static int rates[] = {
|
||||||
5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000,
|
5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000,
|
||||||
|
@ -841,19 +871,19 @@ static void print_rates(struct snd_info_buffer *buffer)
|
||||||
};
|
};
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (dummy_pcm_hardware.rates & SNDRV_PCM_RATE_CONTINUOUS)
|
if (dummy->pcm_hw.rates & SNDRV_PCM_RATE_CONTINUOUS)
|
||||||
snd_iprintf(buffer, " 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");
|
snd_iprintf(buffer, " knot");
|
||||||
for (i = 0; i < ARRAY_SIZE(rates); i++)
|
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]);
|
snd_iprintf(buffer, " %d", rates[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define get_dummy_int_ptr(ofs) \
|
#define get_dummy_int_ptr(dummy, ofs) \
|
||||||
(unsigned int *)((char *)&dummy_pcm_hardware + (ofs))
|
(unsigned int *)((char *)&((dummy)->pcm_hw) + (ofs))
|
||||||
#define get_dummy_ll_ptr(ofs) \
|
#define get_dummy_ll_ptr(dummy, ofs) \
|
||||||
(unsigned long long *)((char *)&dummy_pcm_hardware + (ofs))
|
(unsigned long long *)((char *)&((dummy)->pcm_hw) + (ofs))
|
||||||
|
|
||||||
struct dummy_hw_field {
|
struct dummy_hw_field {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
@ -884,20 +914,21 @@ static struct dummy_hw_field fields[] = {
|
||||||
static void dummy_proc_read(struct snd_info_entry *entry,
|
static void dummy_proc_read(struct snd_info_entry *entry,
|
||||||
struct snd_info_buffer *buffer)
|
struct snd_info_buffer *buffer)
|
||||||
{
|
{
|
||||||
|
struct snd_dummy *dummy = entry->private_data;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(fields); i++) {
|
for (i = 0; i < ARRAY_SIZE(fields); i++) {
|
||||||
snd_iprintf(buffer, "%s ", fields[i].name);
|
snd_iprintf(buffer, "%s ", fields[i].name);
|
||||||
if (fields[i].size == sizeof(int))
|
if (fields[i].size == sizeof(int))
|
||||||
snd_iprintf(buffer, fields[i].format,
|
snd_iprintf(buffer, fields[i].format,
|
||||||
*get_dummy_int_ptr(fields[i].offset));
|
*get_dummy_int_ptr(dummy, fields[i].offset));
|
||||||
else
|
else
|
||||||
snd_iprintf(buffer, fields[i].format,
|
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"))
|
if (!strcmp(fields[i].name, "formats"))
|
||||||
print_formats(buffer);
|
print_formats(dummy, buffer);
|
||||||
else if (!strcmp(fields[i].name, "rates"))
|
else if (!strcmp(fields[i].name, "rates"))
|
||||||
print_rates(buffer);
|
print_rates(dummy, buffer);
|
||||||
snd_iprintf(buffer, "\n");
|
snd_iprintf(buffer, "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -905,6 +936,7 @@ static void dummy_proc_read(struct snd_info_entry *entry,
|
||||||
static void dummy_proc_write(struct snd_info_entry *entry,
|
static void dummy_proc_write(struct snd_info_entry *entry,
|
||||||
struct snd_info_buffer *buffer)
|
struct snd_info_buffer *buffer)
|
||||||
{
|
{
|
||||||
|
struct snd_dummy *dummy = entry->private_data;
|
||||||
char line[64];
|
char line[64];
|
||||||
|
|
||||||
while (!snd_info_get_line(buffer, line, sizeof(line))) {
|
while (!snd_info_get_line(buffer, line, sizeof(line))) {
|
||||||
|
@ -924,9 +956,9 @@ static void dummy_proc_write(struct snd_info_entry *entry,
|
||||||
if (strict_strtoull(item, 0, &val))
|
if (strict_strtoull(item, 0, &val))
|
||||||
continue;
|
continue;
|
||||||
if (fields[i].size == sizeof(int))
|
if (fields[i].size == sizeof(int))
|
||||||
*get_dummy_int_ptr(fields[i].offset) = val;
|
*get_dummy_int_ptr(dummy, fields[i].offset) = val;
|
||||||
else
|
else
|
||||||
*get_dummy_ll_ptr(fields[i].offset) = val;
|
*get_dummy_ll_ptr(dummy, fields[i].offset) = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -938,6 +970,7 @@ static void __devinit dummy_proc_init(struct snd_dummy *chip)
|
||||||
snd_info_set_text_ops(entry, chip, dummy_proc_read);
|
snd_info_set_text_ops(entry, chip, dummy_proc_read);
|
||||||
entry->c.text.write = dummy_proc_write;
|
entry->c.text.write = dummy_proc_write;
|
||||||
entry->mode |= S_IWUSR;
|
entry->mode |= S_IWUSR;
|
||||||
|
entry->private_data = chip;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -948,6 +981,7 @@ static int __devinit snd_dummy_probe(struct platform_device *devptr)
|
||||||
{
|
{
|
||||||
struct snd_card *card;
|
struct snd_card *card;
|
||||||
struct snd_dummy *dummy;
|
struct snd_dummy *dummy;
|
||||||
|
struct dummy_model *m = NULL, **mdl;
|
||||||
int idx, err;
|
int idx, err;
|
||||||
int dev = devptr->id;
|
int dev = devptr->id;
|
||||||
|
|
||||||
|
@ -957,6 +991,15 @@ static int __devinit snd_dummy_probe(struct platform_device *devptr)
|
||||||
return err;
|
return err;
|
||||||
dummy = card->private_data;
|
dummy = card->private_data;
|
||||||
dummy->card = card;
|
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++) {
|
for (idx = 0; idx < MAX_PCM_DEVICES && idx < pcm_devs[dev]; idx++) {
|
||||||
if (pcm_substreams[dev] < 1)
|
if (pcm_substreams[dev] < 1)
|
||||||
pcm_substreams[dev] = 1;
|
pcm_substreams[dev] = 1;
|
||||||
|
@ -966,6 +1009,33 @@ static int __devinit snd_dummy_probe(struct platform_device *devptr)
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto __nodev;
|
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);
|
err = snd_card_dummy_new_mixer(dummy);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto __nodev;
|
goto __nodev;
|
||||||
|
|
|
@ -123,6 +123,7 @@ struct usb_mixer_elem_info {
|
||||||
int channels;
|
int channels;
|
||||||
int val_type;
|
int val_type;
|
||||||
int min, max, res;
|
int min, max, res;
|
||||||
|
int dBmin, dBmax;
|
||||||
int cached;
|
int cached;
|
||||||
int cache_val[MAX_CHANNELS];
|
int cache_val[MAX_CHANNELS];
|
||||||
u8 initialized;
|
u8 initialized;
|
||||||
|
@ -209,42 +210,50 @@ enum {
|
||||||
*/
|
*/
|
||||||
#include "usbmixer_maps.c"
|
#include "usbmixer_maps.c"
|
||||||
|
|
||||||
/* get the mapped name if the unit matches */
|
static const struct usbmix_name_map *
|
||||||
static int check_mapped_name(struct mixer_build *state, int unitid, int control, char *buf, int buflen)
|
find_map(struct mixer_build *state, int unitid, int control)
|
||||||
{
|
{
|
||||||
const struct usbmix_name_map *p;
|
const struct usbmix_name_map *p = state->map;
|
||||||
|
|
||||||
if (! state->map)
|
if (!p)
|
||||||
return 0;
|
return NULL;
|
||||||
|
|
||||||
for (p = state->map; p->id; p++) {
|
for (p = state->map; p->id; p++) {
|
||||||
if (p->id == unitid && p->name &&
|
if (p->id == unitid &&
|
||||||
(! control || ! p->control || control == p->control)) {
|
(!control || !p->control || control == p->control))
|
||||||
buflen--;
|
return p;
|
||||||
return strlcpy(buf, p->name, buflen);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the mapped name if the unit matches */
|
||||||
|
static int
|
||||||
|
check_mapped_name(const struct usbmix_name_map *p, char *buf, int buflen)
|
||||||
|
{
|
||||||
|
if (!p || !p->name)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
buflen--;
|
||||||
|
return strlcpy(buf, p->name, buflen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check whether the control should be ignored */
|
/* check whether the control should be ignored */
|
||||||
static int check_ignored_ctl(struct mixer_build *state, int unitid, int control)
|
static inline int
|
||||||
|
check_ignored_ctl(const struct usbmix_name_map *p)
|
||||||
{
|
{
|
||||||
const struct usbmix_name_map *p;
|
if (!p || p->name || p->dB)
|
||||||
|
|
||||||
if (! state->map)
|
|
||||||
return 0;
|
return 0;
|
||||||
for (p = state->map; p->id; p++) {
|
return 1;
|
||||||
if (p->id == unitid && ! p->name &&
|
}
|
||||||
(! control || ! p->control || control == p->control)) {
|
|
||||||
/*
|
/* dB mapping */
|
||||||
printk(KERN_DEBUG "ignored control %d:%d\n",
|
static inline void check_mapped_dB(const struct usbmix_name_map *p,
|
||||||
unitid, control);
|
struct usb_mixer_elem_info *cval)
|
||||||
*/
|
{
|
||||||
return 1;
|
if (p && p->dB) {
|
||||||
}
|
cval->dBmin = p->dB->min;
|
||||||
|
cval->dBmax = p->dB->max;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the mapped selector source name */
|
/* get the mapped selector source name */
|
||||||
|
@ -481,20 +490,8 @@ static int mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
|
||||||
|
|
||||||
if (size < sizeof(scale))
|
if (size < sizeof(scale))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
/* USB descriptions contain the dB scale in 1/256 dB unit
|
scale[2] = cval->dBmin;
|
||||||
* while ALSA TLV contains in 1/100 dB unit
|
scale[3] = cval->dBmax;
|
||||||
*/
|
|
||||||
scale[2] = (convert_signed_value(cval, cval->min) * 100) / 256;
|
|
||||||
scale[3] = (convert_signed_value(cval, cval->max) * 100) / 256;
|
|
||||||
if (scale[3] <= scale[2]) {
|
|
||||||
/* something is wrong; assume it's either from/to 0dB */
|
|
||||||
if (scale[2] < 0)
|
|
||||||
scale[3] = 0;
|
|
||||||
else if (scale[2] > 0)
|
|
||||||
scale[2] = 0;
|
|
||||||
else /* totally crap, return an error */
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
if (copy_to_user(_tlv, scale, sizeof(scale)))
|
if (copy_to_user(_tlv, scale, sizeof(scale)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -735,6 +732,7 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
|
||||||
cval->min = default_min;
|
cval->min = default_min;
|
||||||
cval->max = cval->min + 1;
|
cval->max = cval->min + 1;
|
||||||
cval->res = 1;
|
cval->res = 1;
|
||||||
|
cval->dBmin = cval->dBmax = 0;
|
||||||
|
|
||||||
if (cval->val_type == USB_MIXER_BOOLEAN ||
|
if (cval->val_type == USB_MIXER_BOOLEAN ||
|
||||||
cval->val_type == USB_MIXER_INV_BOOLEAN) {
|
cval->val_type == USB_MIXER_INV_BOOLEAN) {
|
||||||
|
@ -802,6 +800,24 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
|
||||||
|
|
||||||
cval->initialized = 1;
|
cval->initialized = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* USB descriptions contain the dB scale in 1/256 dB unit
|
||||||
|
* while ALSA TLV contains in 1/100 dB unit
|
||||||
|
*/
|
||||||
|
cval->dBmin = (convert_signed_value(cval, cval->min) * 100) / 256;
|
||||||
|
cval->dBmax = (convert_signed_value(cval, cval->max) * 100) / 256;
|
||||||
|
if (cval->dBmin > cval->dBmax) {
|
||||||
|
/* something is wrong; assume it's either from/to 0dB */
|
||||||
|
if (cval->dBmin < 0)
|
||||||
|
cval->dBmax = 0;
|
||||||
|
else if (cval->dBmin > 0)
|
||||||
|
cval->dBmin = 0;
|
||||||
|
if (cval->dBmin > cval->dBmax) {
|
||||||
|
/* totally crap, return an error */
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -927,6 +943,7 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
|
||||||
int nameid = desc[desc[0] - 1];
|
int nameid = desc[desc[0] - 1];
|
||||||
struct snd_kcontrol *kctl;
|
struct snd_kcontrol *kctl;
|
||||||
struct usb_mixer_elem_info *cval;
|
struct usb_mixer_elem_info *cval;
|
||||||
|
const struct usbmix_name_map *map;
|
||||||
|
|
||||||
control++; /* change from zero-based to 1-based value */
|
control++; /* change from zero-based to 1-based value */
|
||||||
|
|
||||||
|
@ -935,7 +952,8 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check_ignored_ctl(state, unitid, control))
|
map = find_map(state, unitid, control);
|
||||||
|
if (check_ignored_ctl(map))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cval = kzalloc(sizeof(*cval), GFP_KERNEL);
|
cval = kzalloc(sizeof(*cval), GFP_KERNEL);
|
||||||
|
@ -969,10 +987,11 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
|
||||||
}
|
}
|
||||||
kctl->private_free = usb_mixer_elem_free;
|
kctl->private_free = usb_mixer_elem_free;
|
||||||
|
|
||||||
len = check_mapped_name(state, unitid, control, kctl->id.name, sizeof(kctl->id.name));
|
len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
|
||||||
mapped_name = len != 0;
|
mapped_name = len != 0;
|
||||||
if (! len && nameid)
|
if (! len && nameid)
|
||||||
len = snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name));
|
len = snd_usb_copy_string_desc(state, nameid,
|
||||||
|
kctl->id.name, sizeof(kctl->id.name));
|
||||||
|
|
||||||
switch (control) {
|
switch (control) {
|
||||||
case USB_FEATURE_MUTE:
|
case USB_FEATURE_MUTE:
|
||||||
|
@ -1010,6 +1029,7 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
|
||||||
kctl->vd[0].access |=
|
kctl->vd[0].access |=
|
||||||
SNDRV_CTL_ELEM_ACCESS_TLV_READ |
|
SNDRV_CTL_ELEM_ACCESS_TLV_READ |
|
||||||
SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
|
SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
|
||||||
|
check_mapped_dB(map, cval);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1137,8 +1157,10 @@ static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc,
|
||||||
unsigned int num_outs = desc[5 + input_pins];
|
unsigned int num_outs = desc[5 + input_pins];
|
||||||
unsigned int i, len;
|
unsigned int i, len;
|
||||||
struct snd_kcontrol *kctl;
|
struct snd_kcontrol *kctl;
|
||||||
|
const struct usbmix_name_map *map;
|
||||||
|
|
||||||
if (check_ignored_ctl(state, unitid, 0))
|
map = find_map(state, unitid, 0);
|
||||||
|
if (check_ignored_ctl(map))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cval = kzalloc(sizeof(*cval), GFP_KERNEL);
|
cval = kzalloc(sizeof(*cval), GFP_KERNEL);
|
||||||
|
@ -1167,7 +1189,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc,
|
||||||
}
|
}
|
||||||
kctl->private_free = usb_mixer_elem_free;
|
kctl->private_free = usb_mixer_elem_free;
|
||||||
|
|
||||||
len = check_mapped_name(state, unitid, 0, kctl->id.name, sizeof(kctl->id.name));
|
len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
|
||||||
if (! len)
|
if (! len)
|
||||||
len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 0);
|
len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 0);
|
||||||
if (! len)
|
if (! len)
|
||||||
|
@ -1382,6 +1404,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
|
||||||
int i, err, nameid, type, len;
|
int i, err, nameid, type, len;
|
||||||
struct procunit_info *info;
|
struct procunit_info *info;
|
||||||
struct procunit_value_info *valinfo;
|
struct procunit_value_info *valinfo;
|
||||||
|
const struct usbmix_name_map *map;
|
||||||
static struct procunit_value_info default_value_info[] = {
|
static struct procunit_value_info default_value_info[] = {
|
||||||
{ 0x01, "Switch", USB_MIXER_BOOLEAN },
|
{ 0x01, "Switch", USB_MIXER_BOOLEAN },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
|
@ -1411,7 +1434,8 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
|
||||||
/* FIXME: bitmap might be longer than 8bit */
|
/* FIXME: bitmap might be longer than 8bit */
|
||||||
if (! (dsc[12 + num_ins] & (1 << (valinfo->control - 1))))
|
if (! (dsc[12 + num_ins] & (1 << (valinfo->control - 1))))
|
||||||
continue;
|
continue;
|
||||||
if (check_ignored_ctl(state, unitid, valinfo->control))
|
map = find_map(state, unitid, valinfo->control);
|
||||||
|
if (check_ignored_ctl(map))
|
||||||
continue;
|
continue;
|
||||||
cval = kzalloc(sizeof(*cval), GFP_KERNEL);
|
cval = kzalloc(sizeof(*cval), GFP_KERNEL);
|
||||||
if (! cval) {
|
if (! cval) {
|
||||||
|
@ -1452,8 +1476,9 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
|
||||||
}
|
}
|
||||||
kctl->private_free = usb_mixer_elem_free;
|
kctl->private_free = usb_mixer_elem_free;
|
||||||
|
|
||||||
if (check_mapped_name(state, unitid, cval->control, kctl->id.name, sizeof(kctl->id.name)))
|
if (check_mapped_name(map, kctl->id.name,
|
||||||
;
|
sizeof(kctl->id.name)))
|
||||||
|
/* nothing */ ;
|
||||||
else if (info->name)
|
else if (info->name)
|
||||||
strlcpy(kctl->id.name, info->name, sizeof(kctl->id.name));
|
strlcpy(kctl->id.name, info->name, sizeof(kctl->id.name));
|
||||||
else {
|
else {
|
||||||
|
@ -1592,6 +1617,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
|
||||||
int err;
|
int err;
|
||||||
struct usb_mixer_elem_info *cval;
|
struct usb_mixer_elem_info *cval;
|
||||||
struct snd_kcontrol *kctl;
|
struct snd_kcontrol *kctl;
|
||||||
|
const struct usbmix_name_map *map;
|
||||||
char **namelist;
|
char **namelist;
|
||||||
|
|
||||||
if (! num_ins || desc[0] < 5 + num_ins) {
|
if (! num_ins || desc[0] < 5 + num_ins) {
|
||||||
|
@ -1607,7 +1633,8 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
|
||||||
if (num_ins == 1) /* only one ? nonsense! */
|
if (num_ins == 1) /* only one ? nonsense! */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (check_ignored_ctl(state, unitid, 0))
|
map = find_map(state, unitid, 0);
|
||||||
|
if (check_ignored_ctl(map))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cval = kzalloc(sizeof(*cval), GFP_KERNEL);
|
cval = kzalloc(sizeof(*cval), GFP_KERNEL);
|
||||||
|
@ -1662,7 +1689,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
|
||||||
kctl->private_free = usb_mixer_selector_elem_free;
|
kctl->private_free = usb_mixer_selector_elem_free;
|
||||||
|
|
||||||
nameid = desc[desc[0] - 1];
|
nameid = desc[desc[0] - 1];
|
||||||
len = check_mapped_name(state, unitid, 0, kctl->id.name, sizeof(kctl->id.name));
|
len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
|
||||||
if (len)
|
if (len)
|
||||||
;
|
;
|
||||||
else if (nameid)
|
else if (nameid)
|
||||||
|
|
|
@ -19,11 +19,16 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
struct usbmix_dB_map {
|
||||||
|
u32 min;
|
||||||
|
u32 max;
|
||||||
|
};
|
||||||
|
|
||||||
struct usbmix_name_map {
|
struct usbmix_name_map {
|
||||||
int id;
|
int id;
|
||||||
const char *name;
|
const char *name;
|
||||||
int control;
|
int control;
|
||||||
|
struct usbmix_dB_map *dB;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct usbmix_selector_map {
|
struct usbmix_selector_map {
|
||||||
|
@ -72,7 +77,7 @@ static struct usbmix_name_map extigy_map[] = {
|
||||||
{ 8, "Line Playback" }, /* FU */
|
{ 8, "Line Playback" }, /* FU */
|
||||||
/* 9: IT mic */
|
/* 9: IT mic */
|
||||||
{ 10, "Mic Playback" }, /* FU */
|
{ 10, "Mic Playback" }, /* FU */
|
||||||
{ 11, "Capture Input Source" }, /* SU */
|
{ 11, "Capture Source" }, /* SU */
|
||||||
{ 12, "Capture" }, /* FU */
|
{ 12, "Capture" }, /* FU */
|
||||||
/* 13: OT pcm capture */
|
/* 13: OT pcm capture */
|
||||||
/* 14: MU (w/o controls) */
|
/* 14: MU (w/o controls) */
|
||||||
|
@ -102,6 +107,9 @@ static struct usbmix_name_map extigy_map[] = {
|
||||||
* e.g. no Master and fake PCM volume
|
* e.g. no Master and fake PCM volume
|
||||||
* Pavel Mihaylov <bin@bash.info>
|
* Pavel Mihaylov <bin@bash.info>
|
||||||
*/
|
*/
|
||||||
|
static struct usbmix_dB_map mp3plus_dB_1 = {-4781, 0}; /* just guess */
|
||||||
|
static struct usbmix_dB_map mp3plus_dB_2 = {-1781, 618}; /* just guess */
|
||||||
|
|
||||||
static struct usbmix_name_map mp3plus_map[] = {
|
static struct usbmix_name_map mp3plus_map[] = {
|
||||||
/* 1: IT pcm */
|
/* 1: IT pcm */
|
||||||
/* 2: IT mic */
|
/* 2: IT mic */
|
||||||
|
@ -110,16 +118,19 @@ static struct usbmix_name_map mp3plus_map[] = {
|
||||||
/* 5: OT digital out */
|
/* 5: OT digital out */
|
||||||
/* 6: OT speaker */
|
/* 6: OT speaker */
|
||||||
/* 7: OT pcm capture */
|
/* 7: OT pcm capture */
|
||||||
{ 8, "Capture Input Source" }, /* FU, default PCM Capture Source */
|
{ 8, "Capture Source" }, /* FU, default PCM Capture Source */
|
||||||
/* (Mic, Input 1 = Line input, Input 2 = Optical input) */
|
/* (Mic, Input 1 = Line input, Input 2 = Optical input) */
|
||||||
{ 9, "Master Playback" }, /* FU, default Speaker 1 */
|
{ 9, "Master Playback" }, /* FU, default Speaker 1 */
|
||||||
/* { 10, "Mic Capture", 1 }, */ /* FU, Mic Capture */
|
/* { 10, "Mic Capture", 1 }, */ /* FU, Mic Capture */
|
||||||
/* { 10, "Mic Capture", 2 }, */ /* FU, Mic Capture */
|
{ 10, /* "Mic Capture", */ NULL, 2, .dB = &mp3plus_dB_2 },
|
||||||
|
/* FU, Mic Capture */
|
||||||
{ 10, "Mic Boost", 7 }, /* FU, default Auto Gain Input */
|
{ 10, "Mic Boost", 7 }, /* FU, default Auto Gain Input */
|
||||||
{ 11, "Line Capture" }, /* FU, default PCM Capture */
|
{ 11, "Line Capture", .dB = &mp3plus_dB_2 },
|
||||||
|
/* FU, default PCM Capture */
|
||||||
{ 12, "Digital In Playback" }, /* FU, default PCM 1 */
|
{ 12, "Digital In Playback" }, /* FU, default PCM 1 */
|
||||||
/* { 13, "Mic Playback" }, */ /* FU, default Mic Playback */
|
{ 13, /* "Mic Playback", */ .dB = &mp3plus_dB_1 },
|
||||||
{ 14, "Line Playback" }, /* FU, default Speaker */
|
/* FU, default Mic Playback */
|
||||||
|
{ 14, "Line Playback", .dB = &mp3plus_dB_1 }, /* FU, default Speaker */
|
||||||
/* 15: MU */
|
/* 15: MU */
|
||||||
{ 0 } /* terminator */
|
{ 0 } /* terminator */
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue