Skip to content

Commit

Permalink
ALSA: usbmixer - introduce /proc/asound/card#/usbmixer file
Browse files Browse the repository at this point in the history
The usbmixer proc file contains mapping between ALSA control API and
USB mixer control units. The purpose of this file is for debugging
and a problem diagnostics.

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
  • Loading branch information
Jaroslav Kysela committed Feb 16, 2010
1 parent b8f1f59 commit ebfdeea
Showing 1 changed file with 61 additions and 14 deletions.
75 changes: 61 additions & 14 deletions sound/usb/usbmixer.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,16 @@ static const struct rc_config {
{ USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */
};

#define MAX_ID_ELEMS 256

struct usb_mixer_interface {
struct snd_usb_audio *chip;
unsigned int ctrlif;
struct list_head list;
unsigned int ignore_ctl_error;
struct urb *urb;
struct usb_mixer_elem_info **id_elems; /* array[256], indexed by unit id */
/* array[MAX_ID_ELEMS], indexed by unit id */
struct usb_mixer_elem_info **id_elems;

/* Sound Blaster remote control stuff */
const struct rc_config *rc_cfg;
Expand Down Expand Up @@ -1825,6 +1828,45 @@ static void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer,
info->elem_id);
}

static void snd_usb_mixer_dump_cval(struct snd_info_buffer *buffer,
int unitid,
struct usb_mixer_elem_info *cval)
{
static char *val_types[] = {"BOOLEAN", "INV_BOOLEAN",
"S8", "U8", "S16", "U16"};
snd_iprintf(buffer, " Unit: %i\n", unitid);
if (cval->elem_id)
snd_iprintf(buffer, " Control: name=\"%s\", index=%i\n",
cval->elem_id->name, cval->elem_id->index);
snd_iprintf(buffer, " Info: id=%i, control=%i, cmask=0x%x, "
"channels=%i, type=\"%s\"\n", cval->id,
cval->control, cval->cmask, cval->channels,
val_types[cval->val_type]);
snd_iprintf(buffer, " Volume: min=%i, max=%i, dBmin=%i, dBmax=%i\n",
cval->min, cval->max, cval->dBmin, cval->dBmax);
}

static void snd_usb_mixer_proc_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{
struct snd_usb_audio *chip = entry->private_data;
struct usb_mixer_interface *mixer;
struct usb_mixer_elem_info *cval;
int unitid;

list_for_each_entry(mixer, &chip->mixer_list, list) {
snd_iprintf(buffer,
"USB Mixer: ctrlif=%i, ctlerr=%i\n",
mixer->ctrlif, mixer->ignore_ctl_error);
snd_iprintf(buffer, "Card: %s\n", chip->card->longname);
for (unitid = 0; unitid < MAX_ID_ELEMS; unitid++) {
for (cval = mixer->id_elems[unitid]; cval;
cval = cval->next_id_elem)
snd_usb_mixer_dump_cval(buffer, unitid, cval);
}
}
}

static void snd_usb_mixer_memory_change(struct usb_mixer_interface *mixer,
int unitid)
{
Expand Down Expand Up @@ -2187,20 +2229,21 @@ static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer)
}

void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
unsigned char samplerate_id)
unsigned char samplerate_id)
{
struct usb_mixer_interface *mixer;
struct usb_mixer_elem_info *cval;
int unitid = 12; /* SamleRate ExtensionUnit ID */
struct usb_mixer_interface *mixer;
struct usb_mixer_elem_info *cval;
int unitid = 12; /* SamleRate ExtensionUnit ID */

list_for_each_entry(mixer, &chip->mixer_list, list) {
cval = mixer->id_elems[unitid];
if (cval) {
set_cur_ctl_value(cval, cval->control << 8, samplerate_id);
list_for_each_entry(mixer, &chip->mixer_list, list) {
cval = mixer->id_elems[unitid];
if (cval) {
set_cur_ctl_value(cval, cval->control << 8,
samplerate_id);
snd_usb_mixer_notify_id(mixer, unitid);
}
break;
}
}
break;
}
}

int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
Expand All @@ -2210,6 +2253,7 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
.dev_free = snd_usb_mixer_dev_free
};
struct usb_mixer_interface *mixer;
struct snd_info_entry *entry;
int err;

strcpy(chip->card->mixername, "USB Mixer");
Expand All @@ -2236,8 +2280,6 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020) ||
mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
mixer->chip->usb_id == USB_ID(0x041e, 0x3048)) {
struct snd_info_entry *entry;

if ((err = snd_audigy2nx_controls_create(mixer)) < 0)
goto _error;
if (!snd_card_proc_new(chip->card, "audigy2nx", &entry))
Expand All @@ -2255,6 +2297,11 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
err = snd_device_new(chip->card, SNDRV_DEV_LOWLEVEL, mixer, &dev_ops);
if (err < 0)
goto _error;

if (list_empty(&chip->mixer_list) &&
!snd_card_proc_new(chip->card, "usbmixer", &entry))
snd_info_set_text_ops(entry, chip, snd_usb_mixer_proc_read);

list_add(&mixer->list, &chip->mixer_list);
return 0;

Expand Down

0 comments on commit ebfdeea

Please sign in to comment.