Alsa-devel
Threads by month
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
May 2014
- 130 participants
- 291 discussions
Hi,
I see the ALSA framework is capable of detecting and recovering from ring
buffer xrun conditions. What I'm not sure about is whether it is possible
to recover from a DAI xrun error as well.
Let's take the example of an I2S interface operating in tx mode. If the
tx fifo overruns, one or more words will be discarded by the interface.
If an odd number of words gets discarded, this may result in the left and
right word being swapped. This is actually a quite common weakness in I2S
controllers.
Is there a mechanism to notify the ALSA subsystem that a DAI xrun
condition has occurred?
Regards
Josef
1
0
This patch fixes polling in alsa-to-jack plugin.
It makes poll()+_poll_revents() return correct values
when there's something to read/write.
It also makes jack pcm survive snd_pcm_recover(-EPIPE).
---
jack/pcm_jack.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 55 insertions(+), 7 deletions(-)
diff --git a/jack/pcm_jack.c b/jack/pcm_jack.c
index 7a8b24d..36fbdc9 100644
--- a/jack/pcm_jack.c
+++ b/jack/pcm_jack.c
@@ -42,6 +42,7 @@ typedef struct {
unsigned int num_ports;
unsigned int hw_ptr;
unsigned int sample_bits;
+ snd_pcm_uframes_t min_avail;
unsigned int channels;
snd_pcm_channel_area_t *areas;
@@ -50,6 +51,41 @@ typedef struct {
jack_client_t *client;
} snd_pcm_jack_t;
+static int snd_pcm_jack_stop(snd_pcm_ioplug_t *io);
+
+static int pcm_poll_block_check(snd_pcm_ioplug_t *io)
+{
+ static char buf[32];
+ snd_pcm_sframes_t avail;
+ snd_pcm_jack_t *jack = io->private_data;
+
+ if (io->state == SND_PCM_STATE_RUNNING ||
+ (io->state == SND_PCM_STATE_PREPARED && io->stream == SND_PCM_STREAM_CAPTURE)) {
+ avail = snd_pcm_avail_update(io->pcm);
+ if (avail >= 0 && avail < jack->min_avail) {
+ while (read(io->poll_fd, &buf, sizeof(buf)) == sizeof(buf));
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int pcm_poll_unblock_check(snd_pcm_ioplug_t *io)
+{
+ static char buf[1];
+ snd_pcm_sframes_t avail;
+ snd_pcm_jack_t *jack = io->private_data;
+
+ avail = snd_pcm_avail_update(io->pcm);
+ if (avail < 0 || avail >= jack->min_avail) {
+ write(jack->fd, &buf, 1);
+ return 1;
+ }
+
+ return 0;
+}
+
static void snd_pcm_jack_free(snd_pcm_jack_t *jack)
{
if (jack) {
@@ -81,14 +117,10 @@ static int snd_pcm_jack_poll_revents(snd_pcm_ioplug_t *io,
struct pollfd *pfds, unsigned int nfds,
unsigned short *revents)
{
- static char buf[1];
-
assert(pfds && nfds == 1 && revents);
- read(pfds[0].fd, buf, 1);
-
*revents = pfds[0].revents & ~(POLLIN | POLLOUT);
- if (pfds[0].revents & POLLIN)
+ if (pfds[0].revents & POLLIN && !pcm_poll_block_check(io))
*revents |= (io->stream == SND_PCM_STREAM_PLAYBACK) ? POLLOUT : POLLIN;
return 0;
}
@@ -105,7 +137,6 @@ snd_pcm_jack_process_cb(jack_nframes_t nframes, snd_pcm_ioplug_t *io)
snd_pcm_jack_t *jack = io->private_data;
const snd_pcm_channel_area_t *areas;
snd_pcm_uframes_t xfer = 0;
- static char buf[1];
unsigned int channel;
for (channel = 0; channel < io->channels; channel++) {
@@ -145,7 +176,7 @@ snd_pcm_jack_process_cb(jack_nframes_t nframes, snd_pcm_ioplug_t *io)
xfer += frames;
}
- write(jack->fd, buf, 1); /* for polling */
+ pcm_poll_unblock_check(io); /* unblock socket for polling if needed */
return 0;
}
@@ -154,9 +185,26 @@ static int snd_pcm_jack_prepare(snd_pcm_ioplug_t *io)
{
snd_pcm_jack_t *jack = io->private_data;
unsigned int i;
+ snd_pcm_sw_params_t *swparams;
+ int err;
jack->hw_ptr = 0;
+ jack->min_avail = io->period_size;
+ snd_pcm_sw_params_alloca(&swparams);
+ err = snd_pcm_sw_params_current(io->pcm, swparams);
+ if (err == 0) {
+ snd_pcm_sw_params_get_avail_min(swparams, &jack->min_avail);
+ }
+
+ /* deactivate jack connections if this is XRUN recovery */
+ snd_pcm_jack_stop(io);
+
+ if (io->stream == SND_PCM_STREAM_PLAYBACK)
+ pcm_poll_unblock_check(io); /* playback pcm initially accepts writes */
+ else
+ pcm_poll_block_check(io); /* block capture pcm if that's XRUN recovery */
+
if (jack->ports)
return 0;
--
1.7.10.4
1
0
25 May '14
Shorten some over-long lines, multi-line comments, spurious whitespaces,
curly brakets etc. No functional change.
Signed-off-by: Daniel Mack <zonque(a)gmail.com>
---
sound/usb/mixer.c | 400 +++++++++++++++++++++++++++++++++---------------------
1 file changed, 246 insertions(+), 154 deletions(-)
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 6fe83e4..9765e1c 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -162,7 +162,7 @@ static int check_mapped_selector_name(struct mixer_build *state, int unitid,
{
const struct usbmix_selector_map *p;
- if (! state->selector_map)
+ if (!state->selector_map)
return 0;
for (p = state->selector_map; p->id; p++) {
if (p->id == unitid && index < p->count)
@@ -174,7 +174,8 @@ static int check_mapped_selector_name(struct mixer_build *state, int unitid,
/*
* find an audio control unit with the given unit id
*/
-static void *find_audio_control_unit(struct mixer_build *state, unsigned char unit)
+static void *find_audio_control_unit(struct mixer_build *state,
+ unsigned char unit)
{
/* we just parse the header */
struct uac_feature_unit_descriptor *hdr = NULL;
@@ -194,7 +195,8 @@ static void *find_audio_control_unit(struct mixer_build *state, unsigned char un
/*
* copy a string with the given id
*/
-static int snd_usb_copy_string_desc(struct mixer_build *state, int index, char *buf, int maxlen)
+static int snd_usb_copy_string_desc(struct mixer_build *state,
+ int index, char *buf, int maxlen)
{
int len = usb_string(state->chip->dev, index, buf, maxlen - 1);
buf[len] = 0;
@@ -253,7 +255,7 @@ static int convert_bytes_value(struct usb_mixer_elem_info *cval, int val)
static int get_relative_value(struct usb_mixer_elem_info *cval, int val)
{
- if (! cval->res)
+ if (!cval->res)
cval->res = 1;
if (val < cval->min)
return 0;
@@ -267,7 +269,7 @@ static int get_abs_value(struct usb_mixer_elem_info *cval, int val)
{
if (val < 0)
return cval->min;
- if (! cval->res)
+ if (!cval->res)
cval->res = 1;
val *= cval->res;
val += cval->min;
@@ -281,7 +283,8 @@ static int get_abs_value(struct usb_mixer_elem_info *cval, int val)
* retrieve a mixer value
*/
-static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
+static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request,
+ int validx, int *value_ret)
{
struct snd_usb_audio *chip = cval->mixer->chip;
unsigned char buf[2];
@@ -292,6 +295,7 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v
err = snd_usb_autoresume(cval->mixer->chip);
if (err < 0)
return -EIO;
+
down_read(&chip->shutdown_rwsem);
while (timeout-- > 0) {
if (chip->shutdown)
@@ -316,10 +320,11 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v
return err;
}
-static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
+static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request,
+ int validx, int *value_ret)
{
struct snd_usb_audio *chip = cval->mixer->chip;
- unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */
+ unsigned char buf[2 + 3 * sizeof(__u16)]; /* enough space for one range */
unsigned char *val;
int idx = 0, ret, size;
__u8 bRequest;
@@ -339,9 +344,9 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v
goto error;
down_read(&chip->shutdown_rwsem);
- if (chip->shutdown)
+ if (chip->shutdown) {
ret = -ENODEV;
- else {
+ } else {
idx = snd_usb_ctrl_intf(chip) | (cval->id << 8);
ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
@@ -382,7 +387,8 @@ error:
return 0;
}
-static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
+static int get_ctl_value(struct usb_mixer_elem_info *cval, int request,
+ int validx, int *value_ret)
{
validx += cval->idx_off;
@@ -391,7 +397,8 @@ static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int vali
get_ctl_value_v2(cval, request, validx, value_ret);
}
-static int get_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int *value)
+static int get_cur_ctl_value(struct usb_mixer_elem_info *cval,
+ int validx, int *value)
{
return get_ctl_value(cval, UAC_GET_CUR, validx, value);
}
@@ -400,7 +407,9 @@ static int get_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int *
static inline int get_cur_mix_raw(struct usb_mixer_elem_info *cval,
int channel, int *value)
{
- return get_ctl_value(cval, UAC_GET_CUR, (cval->control << 8) | channel, value);
+ return get_ctl_value(cval, UAC_GET_CUR,
+ (cval->control << 8) | channel,
+ value);
}
static int get_cur_mix_value(struct usb_mixer_elem_info *cval,
@@ -417,7 +426,7 @@ static int get_cur_mix_value(struct usb_mixer_elem_info *cval,
if (!cval->mixer->ignore_ctl_error)
usb_audio_dbg(cval->mixer->chip,
"cannot get current value for control %d ch %d: err = %d\n",
- cval->control, channel, err);
+ cval->control, channel, err);
return err;
}
cval->cached |= 1 << channel;
@@ -425,7 +434,6 @@ static int get_cur_mix_value(struct usb_mixer_elem_info *cval,
return 0;
}
-
/*
* set a mixer value
*/
@@ -474,7 +482,7 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
}
}
usb_audio_dbg(chip, "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n",
- request, validx, idx, cval->val_type, buf[0], buf[1]);
+ request, validx, idx, cval->val_type, buf[0], buf[1]);
err = -EINVAL;
out:
@@ -483,7 +491,8 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
return err;
}
-static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value)
+static int set_cur_ctl_value(struct usb_mixer_elem_info *cval,
+ int validx, int value)
{
return snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, validx, value);
}
@@ -503,8 +512,9 @@ static int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel,
return 0;
}
- err = snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, (cval->control << 8) | channel,
- value);
+ err = snd_usb_mixer_set_ctl_value(cval,
+ UAC_SET_CUR, (cval->control << 8) | channel,
+ value);
if (err < 0)
return err;
cval->cached |= 1 << channel;
@@ -541,13 +551,13 @@ static int parse_audio_unit(struct mixer_build *state, int unitid);
* check if the input/output channel routing is enabled on the given bitmap.
* used for mixer unit parser
*/
-static int check_matrix_bitmap(unsigned char *bmap, int ich, int och, int num_outs)
+static int check_matrix_bitmap(unsigned char *bmap,
+ int ich, int och, int num_outs)
{
int idx = ich * num_outs + och;
return bmap[idx >> 3] & (0x80 >> (idx & 7));
}
-
/*
* add an alsa control element
* search and increment the index until an empty slot is found.
@@ -564,7 +574,8 @@ int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer,
while (snd_ctl_find_id(mixer->chip->card, &kctl->id))
kctl->id.index++;
if ((err = snd_ctl_add(mixer->chip->card, kctl)) < 0) {
- usb_audio_dbg(mixer->chip, "cannot add control (err = %d)\n", err);
+ usb_audio_dbg(mixer->chip, "cannot add control (err = %d)\n",
+ err);
return err;
}
cval->elem_id = &kctl->id;
@@ -573,7 +584,6 @@ int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer,
return 0;
}
-
/*
* get a terminal name string
*/
@@ -627,7 +637,8 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm
struct iterm_name_combo *names;
if (iterm->name)
- return snd_usb_copy_string_desc(state, iterm->name, name, maxlen);
+ return snd_usb_copy_string_desc(state, iterm->name,
+ name, maxlen);
/* virtual type - not a real terminal */
if (iterm->type >> 16) {
@@ -635,13 +646,17 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm
return 0;
switch (iterm->type >> 16) {
case UAC_SELECTOR_UNIT:
- strcpy(name, "Selector"); return 8;
+ strcpy(name, "Selector");
+ return 8;
case UAC1_PROCESSING_UNIT:
- strcpy(name, "Process Unit"); return 12;
+ strcpy(name, "Process Unit");
+ return 12;
case UAC1_EXTENSION_UNIT:
- strcpy(name, "Ext Unit"); return 8;
+ strcpy(name, "Ext Unit");
+ return 8;
case UAC_MIXER_UNIT:
- strcpy(name, "Mixer"); return 5;
+ strcpy(name, "Mixer");
+ return 5;
default:
return sprintf(name, "Unit %d", iterm->id);
}
@@ -649,29 +664,35 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm
switch (iterm->type & 0xff00) {
case 0x0100:
- strcpy(name, "PCM"); return 3;
+ strcpy(name, "PCM");
+ return 3;
case 0x0200:
- strcpy(name, "Mic"); return 3;
+ strcpy(name, "Mic");
+ return 3;
case 0x0400:
- strcpy(name, "Headset"); return 7;
+ strcpy(name, "Headset");
+ return 7;
case 0x0500:
- strcpy(name, "Phone"); return 5;
+ strcpy(name, "Phone");
+ return 5;
}
- for (names = iterm_names; names->type; names++)
+ for (names = iterm_names; names->type; names++) {
if (names->type == iterm->type) {
strcpy(name, names->name);
return strlen(names->name);
}
+ }
+
return 0;
}
-
/*
* parse the source unit recursively until it reaches to a terminal
* or a branched unit.
*/
-static int check_input_term(struct mixer_build *state, int id, struct usb_audio_term *term)
+static int check_input_term(struct mixer_build *state, int id,
+ struct usb_audio_term *term)
{
int err;
void *p1;
@@ -766,7 +787,6 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_
return -ENODEV;
}
-
/*
* Feature Unit
*/
@@ -794,7 +814,6 @@ static struct usb_feature_control_info audio_feature_info[] = {
{ "Phase Inverter Control", USB_MIXER_BOOLEAN },
};
-
/* private_free callback */
static void usb_mixer_elem_free(struct snd_kcontrol *kctl)
{
@@ -802,7 +821,6 @@ static void usb_mixer_elem_free(struct snd_kcontrol *kctl)
kctl->private_data = NULL;
}
-
/*
* interface to ALSA control for feature/mixer units
*/
@@ -906,7 +924,6 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,
cval->res = 384;
}
break;
-
}
}
@@ -939,21 +956,26 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,
get_ctl_value(cval, UAC_GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) {
usb_audio_err(cval->mixer->chip,
"%d:%d: cannot get min/max values for control %d (id %d)\n",
- cval->id, snd_usb_ctrl_intf(cval->mixer->chip), cval->control, cval->id);
+ cval->id, snd_usb_ctrl_intf(cval->mixer->chip),
+ cval->control, cval->id);
return -EINVAL;
}
- if (get_ctl_value(cval, UAC_GET_RES, (cval->control << 8) | minchn, &cval->res) < 0) {
+ if (get_ctl_value(cval, UAC_GET_RES,
+ (cval->control << 8) | minchn,
+ &cval->res) < 0) {
cval->res = 1;
} else {
int last_valid_res = cval->res;
while (cval->res > 1) {
if (snd_usb_mixer_set_ctl_value(cval, UAC_SET_RES,
- (cval->control << 8) | minchn, cval->res / 2) < 0)
+ (cval->control << 8) | minchn,
+ cval->res / 2) < 0)
break;
cval->res /= 2;
}
- if (get_ctl_value(cval, UAC_GET_RES, (cval->control << 8) | minchn, &cval->res) < 0)
+ if (get_ctl_value(cval, UAC_GET_RES,
+ (cval->control << 8) | minchn, &cval->res) < 0)
cval->res = last_valid_res;
}
if (cval->res == 0)
@@ -1017,7 +1039,8 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,
#define get_min_max(cval, def) get_min_max_with_quirks(cval, def, NULL)
/* get a feature/mixer unit info */
-static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
{
struct usb_mixer_elem_info *cval = kcontrol->private_data;
@@ -1051,7 +1074,8 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_
}
/* get the current value from feature/mixer unit */
-static int mixer_ctl_feature_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int mixer_ctl_feature_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct usb_mixer_elem_info *cval = kcontrol->private_data;
int c, cnt, val, err;
@@ -1082,7 +1106,8 @@ static int mixer_ctl_feature_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
}
/* put the current value to feature/mixer unit */
-static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct usb_mixer_elem_info *cval = kcontrol->private_data;
int c, cnt, val, oval, err;
@@ -1136,22 +1161,25 @@ static struct snd_kcontrol_new usb_feature_unit_ctl_ro = {
.put = NULL,
};
-/* This symbol is exported in order to allow the mixer quirks to
- * hook up to the standard feature unit control mechanism */
+/*
+ * This symbol is exported in order to allow the mixer quirks to
+ * hook up to the standard feature unit control mechanism
+ */
struct snd_kcontrol_new *snd_usb_feature_unit_ctl = &usb_feature_unit_ctl;
/*
* build a feature control
*/
-
static size_t append_ctl_name(struct snd_kcontrol *kctl, const char *str)
{
return strlcat(kctl->id.name, str, sizeof(kctl->id.name));
}
-/* A lot of headsets/headphones have a "Speaker" mixer. Make sure we
- rename it to "Headphone". We determine if something is a headphone
- similar to how udev determines form factor. */
+/*
+ * A lot of headsets/headphones have a "Speaker" mixer. Make sure we
+ * rename it to "Headphone". We determine if something is a headphone
+ * similar to how udev determines form factor.
+ */
static void check_no_speaker_on_headset(struct snd_kcontrol *kctl,
struct snd_card *card)
{
@@ -1201,7 +1229,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
return;
cval = kzalloc(sizeof(*cval), GFP_KERNEL);
- if (! cval) {
+ if (!cval) {
usb_audio_err(state->chip, "cannot malloc kcontrol\n");
return;
}
@@ -1222,15 +1250,17 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
cval->ch_readonly = readonly_mask;
}
- /* if all channels in the mask are marked read-only, make the control
+ /*
+ * If all channels in the mask are marked read-only, make the control
* read-only. set_cur_mix_value() will check the mask again and won't
- * issue write commands to read-only channels. */
+ * issue write commands to read-only channels.
+ */
if (cval->channels == readonly_mask)
kctl = snd_ctl_new1(&usb_feature_unit_ctl_ro, cval);
else
kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
- if (! kctl) {
+ if (!kctl) {
usb_audio_err(state->chip, "cannot malloc kcontrol\n");
kfree(cval);
return;
@@ -1239,48 +1269,53 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
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));
switch (control) {
case UAC_FU_MUTE:
case UAC_FU_VOLUME:
- /* determine the control name. the rule is:
+ /*
+ * determine the control name. the rule is:
* - if a name id is given in descriptor, use it.
* - if the connected input can be determined, then use the name
* of terminal type.
* - if the connected output can be determined, use it.
* - otherwise, anonymous name.
*/
- if (! len) {
- len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 1);
- if (! len)
- len = get_term_name(state, &state->oterm, kctl->id.name, sizeof(kctl->id.name), 1);
- if (! len)
- len = snprintf(kctl->id.name, sizeof(kctl->id.name),
+ if (!len) {
+ len = get_term_name(state, iterm, kctl->id.name,
+ sizeof(kctl->id.name), 1);
+ if (!len)
+ len = get_term_name(state, &state->oterm,
+ kctl->id.name,
+ sizeof(kctl->id.name), 1);
+ if (!len)
+ len = snprintf(kctl->id.name,
+ sizeof(kctl->id.name),
"Feature %d", unitid);
}
if (!mapped_name)
check_no_speaker_on_headset(kctl, state->mixer->chip->card);
- /* determine the stream direction:
+ /*
+ * determine the stream direction:
* if the connected output is USB stream, then it's likely a
* capture stream. otherwise it should be playback (hopefully :)
*/
- if (! mapped_name && ! (state->oterm.type >> 16)) {
- if ((state->oterm.type & 0xff00) == 0x0100) {
+ if (!mapped_name && !(state->oterm.type >> 16)) {
+ if ((state->oterm.type & 0xff00) == 0x0100)
len = append_ctl_name(kctl, " Capture");
- } else {
+ else
len = append_ctl_name(kctl, " Playback");
- }
}
append_ctl_name(kctl, control == UAC_FU_MUTE ?
" Switch" : " Volume");
break;
default:
- if (! len)
+ if (!len)
strlcpy(kctl->id.name, audio_feature_info[control-1].name,
sizeof(kctl->id.name));
break;
@@ -1300,33 +1335,35 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
}
range = (cval->max - cval->min) / cval->res;
- /* Are there devices with volume range more than 255? I use a bit more
+ /*
+ * Are there devices with volume range more than 255? I use a bit more
* to be sure. 384 is a resolution magic number found on Logitech
* devices. It will definitively catch all buggy Logitech devices.
*/
if (range > 384) {
- usb_audio_warn(state->chip, "Warning! Unlikely big "
- "volume range (=%u), cval->res is probably wrong.",
- range);
+ usb_audio_warn(state->chip,
+ "Warning! Unlikely big volume range (=%u), "
+ "cval->res is probably wrong.",
+ range);
usb_audio_warn(state->chip, "[%d] FU [%s] ch = %d, "
- "val = %d/%d/%d", cval->id,
- kctl->id.name, cval->channels,
- cval->min, cval->max, cval->res);
+ "val = %d/%d/%d", cval->id,
+ kctl->id.name, cval->channels,
+ cval->min, cval->max, cval->res);
}
usb_audio_dbg(state->chip, "[%d] FU [%s] ch = %d, val = %d/%d/%d\n",
- cval->id, kctl->id.name, cval->channels, cval->min, cval->max, cval->res);
+ cval->id, kctl->id.name, cval->channels,
+ cval->min, cval->max, cval->res);
snd_usb_mixer_add_control(state->mixer, kctl);
}
-
-
/*
* parse a feature unit
*
* most of controls are defined here.
*/
-static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void *_ftr)
+static int parse_audio_feature_unit(struct mixer_build *state, int unitid,
+ void *_ftr)
{
int channels, i, j;
struct usb_audio_term iterm;
@@ -1400,15 +1437,25 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
for (i = 0; i < 10; i++) {
unsigned int ch_bits = 0;
for (j = 0; j < channels; j++) {
- unsigned int mask = snd_usb_combine_bytes(bmaControls + csize * (j+1), csize);
+ unsigned int mask;
+
+ mask = snd_usb_combine_bytes(bmaControls +
+ csize * (j+1), csize);
if (mask & (1 << i))
ch_bits |= (1 << j);
}
/* audio class v1 controls are never read-only */
- if (ch_bits & 1) /* the first channel must be set (for ease of programming) */
- build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid, 0);
+
+ /*
+ * The first channel must be set
+ * (for ease of programming).
+ */
+ if (ch_bits & 1)
+ build_feature_ctl(state, _ftr, ch_bits, i,
+ &iterm, unitid, 0);
if (master_bits & (1 << i))
- build_feature_ctl(state, _ftr, 0, i, &iterm, unitid, 0);
+ build_feature_ctl(state, _ftr, 0, i, &iterm,
+ unitid, 0);
}
} else { /* UAC_VERSION_2 */
for (i = 0; i < ARRAY_SIZE(audio_feature_info); i++) {
@@ -1416,7 +1463,10 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
unsigned int ch_read_only = 0;
for (j = 0; j < channels; j++) {
- unsigned int mask = snd_usb_combine_bytes(bmaControls + csize * (j+1), csize);
+ unsigned int mask;
+
+ mask = snd_usb_combine_bytes(bmaControls +
+ csize * (j+1), csize);
if (uac2_control_is_readable(mask, i)) {
ch_bits |= (1 << j);
if (!uac2_control_is_writeable(mask, i))
@@ -1424,12 +1474,22 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
}
}
- /* NOTE: build_feature_ctl() will mark the control read-only if all channels
- * are marked read-only in the descriptors. Otherwise, the control will be
- * reported as writeable, but the driver will not actually issue a write
- * command for read-only channels */
- if (ch_bits & 1) /* the first channel must be set (for ease of programming) */
- build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid, ch_read_only);
+ /*
+ * NOTE: build_feature_ctl() will mark the control
+ * read-only if all channels are marked read-only in
+ * the descriptors. Otherwise, the control will be
+ * reported as writeable, but the driver will not
+ * actually issue a write command for read-only
+ * channels.
+ */
+
+ /*
+ * The first channel must be set
+ * (for ease of programming).
+ */
+ if (ch_bits & 1)
+ build_feature_ctl(state, _ftr, ch_bits, i,
+ &iterm, unitid, ch_read_only);
if (uac2_control_is_readable(master_bits, i))
build_feature_ctl(state, _ftr, 0, i, &iterm, unitid,
!uac2_control_is_writeable(master_bits, i));
@@ -1439,7 +1499,6 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
return 0;
}
-
/*
* Mixer Unit
*/
@@ -1450,7 +1509,6 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
* the callbacks are identical with feature unit.
* input channel number (zero based) is given in control field instead.
*/
-
static void build_mixer_unit_ctl(struct mixer_build *state,
struct uac_mixer_unit_descriptor *desc,
int in_pin, int in_ch, int unitid,
@@ -1467,7 +1525,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state,
return;
cval = kzalloc(sizeof(*cval), GFP_KERNEL);
- if (! cval)
+ if (!cval)
return;
cval->mixer = state->mixer;
@@ -1475,7 +1533,9 @@ static void build_mixer_unit_ctl(struct mixer_build *state,
cval->control = in_ch + 1; /* based on 1 */
cval->val_type = USB_MIXER_S16;
for (i = 0; i < num_outs; i++) {
- if (check_matrix_bitmap(uac_mixer_unit_bmControls(desc, state->mixer->protocol), in_ch, i, num_outs)) {
+ __u8 *c = uac_mixer_unit_bmControls(desc, state->mixer->protocol);
+
+ if (check_matrix_bitmap(c, in_ch, i, num_outs)) {
cval->cmask |= (1 << i);
cval->channels++;
}
@@ -1485,7 +1545,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state,
get_min_max(cval, 0);
kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
- if (! kctl) {
+ if (!kctl) {
usb_audio_err(state->chip, "cannot malloc kcontrol\n");
kfree(cval);
return;
@@ -1493,9 +1553,10 @@ static void build_mixer_unit_ctl(struct mixer_build *state,
kctl->private_free = usb_mixer_elem_free;
len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
- if (! len)
- len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 0);
- if (! len)
+ if (!len)
+ len = get_term_name(state, iterm, kctl->id.name,
+ sizeof(kctl->id.name), 0);
+ if (!len)
len = sprintf(kctl->id.name, "Mixer Source %d", in_ch + 1);
append_ctl_name(kctl, " Volume");
@@ -1504,24 +1565,28 @@ static void build_mixer_unit_ctl(struct mixer_build *state,
snd_usb_mixer_add_control(state->mixer, kctl);
}
-
/*
* parse a mixer unit
*/
-static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, void *raw_desc)
+static int parse_audio_mixer_unit(struct mixer_build *state, int unitid,
+ void *raw_desc)
{
struct uac_mixer_unit_descriptor *desc = raw_desc;
struct usb_audio_term iterm;
int input_pins, num_ins, num_outs;
int pin, ich, err;
- if (desc->bLength < 11 || ! (input_pins = desc->bNrInPins) || ! (num_outs = uac_mixer_unit_bNrChannels(desc))) {
- usb_audio_err(state->chip, "invalid MIXER UNIT descriptor %d\n", unitid);
+ if (desc->bLength < 11 || !(input_pins = desc->bNrInPins) ||
+ !(num_outs = uac_mixer_unit_bNrChannels(desc))) {
+ usb_audio_err(state->chip,
+ "invalid MIXER UNIT descriptor %d\n",
+ unitid);
return -EINVAL;
}
/* no bmControls field (e.g. Maya44) -> ignore */
if (desc->bLength <= 10 + input_pins) {
- usb_audio_dbg(state->chip, "MU %d has no bmControls field\n", unitid);
+ usb_audio_dbg(state->chip, "MU %d has no bmControls field\n",
+ unitid);
return 0;
}
@@ -1535,12 +1600,14 @@ static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, void *r
if (err < 0)
return err;
num_ins += iterm.channels;
- for (; ich < num_ins; ++ich) {
+ for (; ich < num_ins; ich++) {
int och, ich_has_controls = 0;
- for (och = 0; och < num_outs; ++och) {
- if (check_matrix_bitmap(uac_mixer_unit_bmControls(desc, state->mixer->protocol),
- ich, och, num_outs)) {
+ for (och = 0; och < num_outs; och++) {
+ __u8 *c = uac_mixer_unit_bmControls(desc,
+ state->mixer->protocol);
+
+ if (check_matrix_bitmap(c, ich, och, num_outs)) {
ich_has_controls = 1;
break;
}
@@ -1553,13 +1620,13 @@ static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, void *r
return 0;
}
-
/*
* Processing Unit / Extension Unit
*/
/* get callback for processing/extension unit */
-static int mixer_ctl_procunit_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int mixer_ctl_procunit_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct usb_mixer_elem_info *cval = kcontrol->private_data;
int err, val;
@@ -1577,7 +1644,8 @@ static int mixer_ctl_procunit_get(struct snd_kcontrol *kcontrol, struct snd_ctl_
}
/* put callback for processing/extension unit */
-static int mixer_ctl_procunit_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int mixer_ctl_procunit_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct usb_mixer_elem_info *cval = kcontrol->private_data;
int val, oval, err;
@@ -1606,7 +1674,6 @@ static struct snd_kcontrol_new mixer_procunit_ctl = {
.put = mixer_ctl_procunit_put,
};
-
/*
* predefined data for processing units
*/
@@ -1697,10 +1764,13 @@ static struct procunit_info extunits[] = {
{ USB_XU_DEVICE_OPTIONS, "AnalogueIn Soft Limit", soft_limit_xu_info },
{ 0 }
};
+
/*
* build a processing/extension unit
*/
-static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw_desc, struct procunit_info *list, char *name)
+static int build_audio_procunit(struct mixer_build *state, int unitid,
+ void *raw_desc, struct procunit_info *list,
+ char *name)
{
struct uac_processing_unit_descriptor *desc = raw_desc;
int num_ins = desc->bNrInPins;
@@ -1733,19 +1803,19 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw
for (info = list; info && info->type; info++)
if (info->type == type)
break;
- if (! info || ! info->type)
+ if (!info || !info->type)
info = &default_info;
for (valinfo = info->values; valinfo->control; valinfo++) {
__u8 *controls = uac_processing_unit_bmControls(desc, state->mixer->protocol);
- if (! (controls[valinfo->control / 8] & (1 << ((valinfo->control % 8) - 1))))
+ if (!(controls[valinfo->control / 8] & (1 << ((valinfo->control % 8) - 1))))
continue;
map = find_map(state, unitid, valinfo->control);
if (check_ignored_ctl(map))
continue;
cval = kzalloc(sizeof(*cval), GFP_KERNEL);
- if (! cval) {
+ if (!cval) {
usb_audio_err(state->chip, "cannot malloc kcontrol\n");
return -ENOMEM;
}
@@ -1765,7 +1835,8 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw
cval->initialized = 1;
} else {
if (type == USB_XU_CLOCK_RATE) {
- /* E-Mu USB 0404/0202/TrackerPre/0204
+ /*
+ * E-Mu USB 0404/0202/TrackerPre/0204
* samplerate control quirk
*/
cval->min = 0;
@@ -1777,60 +1848,70 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw
}
kctl = snd_ctl_new1(&mixer_procunit_ctl, cval);
- if (! kctl) {
+ if (!kctl) {
usb_audio_err(state->chip, "cannot malloc kcontrol\n");
kfree(cval);
return -ENOMEM;
}
kctl->private_free = usb_mixer_elem_free;
- if (check_mapped_name(map, 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));
- else {
+ } else {
nameid = uac_processing_unit_iProcessing(desc, state->mixer->protocol);
len = 0;
if (nameid)
- len = snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name));
- if (! len)
+ len = snd_usb_copy_string_desc(state, nameid,
+ kctl->id.name,
+ sizeof(kctl->id.name));
+ if (!len)
strlcpy(kctl->id.name, name, sizeof(kctl->id.name));
}
append_ctl_name(kctl, " ");
append_ctl_name(kctl, valinfo->suffix);
usb_audio_dbg(state->chip,
- "[%d] PU [%s] ch = %d, val = %d/%d\n",
- cval->id, kctl->id.name, cval->channels, cval->min, cval->max);
- if ((err = snd_usb_mixer_add_control(state->mixer, kctl)) < 0)
+ "[%d] PU [%s] ch = %d, val = %d/%d\n",
+ cval->id, kctl->id.name, cval->channels,
+ cval->min, cval->max);
+
+ err = snd_usb_mixer_add_control(state->mixer, kctl);
+ if (err < 0)
return err;
}
return 0;
}
-
-static int parse_audio_processing_unit(struct mixer_build *state, int unitid, void *raw_desc)
+static int parse_audio_processing_unit(struct mixer_build *state, int unitid,
+ void *raw_desc)
{
- return build_audio_procunit(state, unitid, raw_desc, procunits, "Processing Unit");
+ return build_audio_procunit(state, unitid, raw_desc,
+ procunits, "Processing Unit");
}
-static int parse_audio_extension_unit(struct mixer_build *state, int unitid, void *raw_desc)
+static int parse_audio_extension_unit(struct mixer_build *state, int unitid,
+ void *raw_desc)
{
- /* Note that we parse extension units with processing unit descriptors.
- * That's ok as the layout is the same */
- return build_audio_procunit(state, unitid, raw_desc, extunits, "Extension Unit");
+ /*
+ * Note that we parse extension units with processing unit descriptors.
+ * That's ok as the layout is the same.
+ */
+ return build_audio_procunit(state, unitid, raw_desc,
+ extunits, "Extension Unit");
}
-
/*
* Selector Unit
*/
-/* info callback for selector unit
+/*
+ * info callback for selector unit
* use an enumerator type for routing
*/
-static int mixer_ctl_selector_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int mixer_ctl_selector_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
{
struct usb_mixer_elem_info *cval = kcontrol->private_data;
const char **itemlist = (const char **)kcontrol->private_value;
@@ -1841,7 +1922,8 @@ static int mixer_ctl_selector_info(struct snd_kcontrol *kcontrol, struct snd_ctl
}
/* get callback for selector unit */
-static int mixer_ctl_selector_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int mixer_ctl_selector_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct usb_mixer_elem_info *cval = kcontrol->private_data;
int val, err;
@@ -1860,7 +1942,8 @@ static int mixer_ctl_selector_get(struct snd_kcontrol *kcontrol, struct snd_ctl_
}
/* put callback for selector unit */
-static int mixer_ctl_selector_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int mixer_ctl_selector_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct usb_mixer_elem_info *cval = kcontrol->private_data;
int val, oval, err;
@@ -1889,8 +1972,8 @@ static struct snd_kcontrol_new mixer_selectunit_ctl = {
.put = mixer_ctl_selector_put,
};
-
-/* private free callback.
+/*
+ * private free callback.
* free both private_data and private_value
*/
static void usb_mixer_selector_elem_free(struct snd_kcontrol *kctl)
@@ -1915,7 +1998,8 @@ static void usb_mixer_selector_elem_free(struct snd_kcontrol *kctl)
/*
* parse a selector unit
*/
-static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void *raw_desc)
+static int parse_audio_selector_unit(struct mixer_build *state, int unitid,
+ void *raw_desc)
{
struct uac_selector_unit_descriptor *desc = raw_desc;
unsigned int i, nameid, len;
@@ -1944,7 +2028,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void
return 0;
cval = kzalloc(sizeof(*cval), GFP_KERNEL);
- if (! cval) {
+ if (!cval) {
usb_audio_err(state->chip, "cannot malloc kcontrol\n");
return -ENOMEM;
}
@@ -1963,7 +2047,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void
cval->control = 0;
namelist = kmalloc(sizeof(char *) * desc->bNrInPins, GFP_KERNEL);
- if (! namelist) {
+ if (!namelist) {
usb_audio_err(state->chip, "cannot malloc\n");
kfree(cval);
return -ENOMEM;
@@ -1973,7 +2057,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void
struct usb_audio_term iterm;
len = 0;
namelist[i] = kmalloc(MAX_ITEM_NAME_LEN, GFP_KERNEL);
- if (! namelist[i]) {
+ if (!namelist[i]) {
usb_audio_err(state->chip, "cannot malloc\n");
while (i--)
kfree(namelist[i]);
@@ -2004,11 +2088,12 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void
if (len)
;
else if (nameid)
- snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name));
+ snd_usb_copy_string_desc(state, nameid, kctl->id.name,
+ sizeof(kctl->id.name));
else {
len = get_term_name(state, &state->oterm,
kctl->id.name, sizeof(kctl->id.name), 0);
- if (! len)
+ if (!len)
strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name));
if (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR)
@@ -2027,7 +2112,6 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void
return 0;
}
-
/*
* parse an audio unit recursively
*/
@@ -2125,14 +2209,16 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
}
p = NULL;
- while ((p = snd_usb_find_csint_desc(mixer->hostif->extra, mixer->hostif->extralen,
+ while ((p = snd_usb_find_csint_desc(mixer->hostif->extra,
+ mixer->hostif->extralen,
p, UAC_OUTPUT_TERMINAL)) != NULL) {
if (mixer->protocol == UAC_VERSION_1) {
struct uac1_output_terminal_descriptor *desc = p;
if (desc->bLength < sizeof(*desc))
continue; /* invalid descriptor? */
- set_bit(desc->bTerminalID, state.unitbitmap); /* mark terminal ID as visited */
+ /* mark terminal ID as visited */
+ set_bit(desc->bTerminalID, state.unitbitmap);
state.oterm.id = desc->bTerminalID;
state.oterm.type = le16_to_cpu(desc->wTerminalType);
state.oterm.name = desc->iTerminal;
@@ -2144,7 +2230,8 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
if (desc->bLength < sizeof(*desc))
continue; /* invalid descriptor? */
- set_bit(desc->bTerminalID, state.unitbitmap); /* mark terminal ID as visited */
+ /* mark terminal ID as visited */
+ set_bit(desc->bTerminalID, state.unitbitmap);
state.oterm.id = desc->bTerminalID;
state.oterm.type = le16_to_cpu(desc->wTerminalType);
state.oterm.name = desc->iTerminal;
@@ -2152,7 +2239,10 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
if (err < 0 && err != -EINVAL)
return err;
- /* for UAC2, use the same approach to also add the clock selectors */
+ /*
+ * For UAC2, use the same approach to also add the
+ * clock selectors
+ */
err = parse_audio_unit(&state, desc->bCSourceID);
if (err < 0 && err != -EINVAL)
return err;
@@ -2306,7 +2396,9 @@ static void snd_usb_mixer_interrupt(struct urb *urb)
}
requeue:
- if (ustatus != -ENOENT && ustatus != -ECONNRESET && ustatus != -ESHUTDOWN) {
+ if (ustatus != -ENOENT &&
+ ustatus != -ECONNRESET &&
+ ustatus != -ESHUTDOWN) {
urb->dev = mixer->chip->dev;
usb_submit_urb(urb, GFP_ATOMIC);
}
--
1.9.0
2
2
24 May '14
To whom it may be of concern.https://bugzilla.kernel.org/show_bug.cgi?id=76841
1
0
24 May '14
From: Fabio Estevam <fabio.estevam(a)freescale.com>
Since commit e5d80e82e32e (ASoC: sgtl5000: Convert to use regmap directly) a
kernel oops is observed after a suspend/resume sequence.
According to Mark Brown:
"Yes, reg_cache isn't there if we're not using ASoC level caching. The
fix should just be to replace the direct cache references with
snd_soc_read()s which will end up in a cache lookup if the register is
cached."
Do as suggested and also complete the cache array with the missing registers
so that sgtl5000_restore_regs() can properly cache the all the registers it
needs.
Reported-by: Shawn Guo <shawn.guo(a)freescale.com>
Signed-off-by: Fabio Estevam <fabio.estevam(a)freescale.com>
---
Changes since v2:
- Use regmap_update_bits
Changes since v1:
- Also fix sgtl5000_set_bias_level so that suspend/resume/play sequence does
not fail after several interactions
sound/soc/codecs/sgtl5000.c | 61 +++++++++++++++++++++++++--------------------
sound/soc/codecs/sgtl5000.h | 2 ++
2 files changed, 36 insertions(+), 27 deletions(-)
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index 9626ee0..6b4bf9a 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -36,18 +36,32 @@
/* default value of sgtl5000 registers */
static const struct reg_default sgtl5000_reg_defaults[] = {
+ { SGTL5000_CHIP_DIG_POWER, 0x0000 },
{ SGTL5000_CHIP_CLK_CTRL, 0x0008 },
{ SGTL5000_CHIP_I2S_CTRL, 0x0010 },
{ SGTL5000_CHIP_SSS_CTRL, 0x0010 },
+ { SGTL5000_CHIP_ADCDAC_CTRL, 0x020c },
{ SGTL5000_CHIP_DAC_VOL, 0x3c3c },
{ SGTL5000_CHIP_PAD_STRENGTH, 0x015f },
+ { SGTL5000_CHIP_ANA_ADC_CTRL, 0x0000 },
{ SGTL5000_CHIP_ANA_HP_CTRL, 0x1818 },
{ SGTL5000_CHIP_ANA_CTRL, 0x0111 },
+ { SGTL5000_CHIP_LINREG_CTRL, 0x0000 },
+ { SGTL5000_CHIP_REF_CTRL, 0x0000 },
+ { SGTL5000_CHIP_MIC_CTRL, 0x0000 },
+ { SGTL5000_CHIP_LINE_OUT_CTRL, 0x0000 },
{ SGTL5000_CHIP_LINE_OUT_VOL, 0x0404 },
{ SGTL5000_CHIP_ANA_POWER, 0x7060 },
{ SGTL5000_CHIP_PLL_CTRL, 0x5000 },
+ { SGTL5000_CHIP_CLK_TOP_CTRL, 0x0000 },
+ { SGTL5000_CHIP_ANA_STATUS, 0x0000 },
+ { SGTL5000_CHIP_SHORT_CTRL, 0x0000 },
+ { SGTL5000_CHIP_ANA_TEST2, 0x0000 },
+ { SGTL5000_DAP_CTRL, 0x0000 },
+ { SGTL5000_DAP_PEQ, 0x0000 },
{ SGTL5000_DAP_BASS_ENHANCE, 0x0040 },
{ SGTL5000_DAP_BASS_ENHANCE_CTRL, 0x051f },
+ { SGTL5000_DAP_AUDIO_EQ, 0x0000 },
{ SGTL5000_DAP_SURROUND, 0x0040 },
{ SGTL5000_DAP_EQ_BASS_BAND0, 0x002f },
{ SGTL5000_DAP_EQ_BASS_BAND1, 0x002f },
@@ -55,6 +69,7 @@ static const struct reg_default sgtl5000_reg_defaults[] = {
{ SGTL5000_DAP_EQ_BASS_BAND3, 0x002f },
{ SGTL5000_DAP_EQ_BASS_BAND4, 0x002f },
{ SGTL5000_DAP_MAIN_CHAN, 0x8000 },
+ { SGTL5000_DAP_MIX_CHAN, 0x0000 },
{ SGTL5000_DAP_AVC_CTRL, 0x0510 },
{ SGTL5000_DAP_AVC_THRESHOLD, 0x1473 },
{ SGTL5000_DAP_AVC_ATTACK, 0x0028 },
@@ -924,20 +939,6 @@ static int sgtl5000_set_bias_level(struct snd_soc_codec *codec,
if (ret)
return ret;
udelay(10);
-
- regcache_cache_only(sgtl5000->regmap, false);
-
- ret = regcache_sync(sgtl5000->regmap);
- if (ret != 0) {
- dev_err(codec->dev,
- "Failed to restore cache: %d\n", ret);
-
- regcache_cache_only(sgtl5000->regmap, true);
- regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
- sgtl5000->supplies);
-
- return ret;
- }
}
break;
@@ -1063,7 +1064,10 @@ static bool sgtl5000_readable(struct device *dev, unsigned int reg)
#ifdef CONFIG_SUSPEND
static int sgtl5000_suspend(struct snd_soc_codec *codec)
{
+ struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
+
sgtl5000_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ regcache_cache_only(sgtl5000->regmap, true);
return 0;
}
@@ -1075,8 +1079,8 @@ static int sgtl5000_suspend(struct snd_soc_codec *codec)
*/
static int sgtl5000_restore_regs(struct snd_soc_codec *codec)
{
- u16 *cache = codec->reg_cache;
u16 reg;
+ struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
/* restore regular registers */
for (reg = 0; reg <= SGTL5000_CHIP_SHORT_CTRL; reg += 2) {
@@ -1089,12 +1093,12 @@ static int sgtl5000_restore_regs(struct snd_soc_codec *codec)
reg == SGTL5000_CHIP_REF_CTRL)
continue;
- snd_soc_write(codec, reg, cache[reg]);
+ regmap_update_bits(sgtl5000->regmap, reg, reg, 0);
}
/* restore dap registers */
for (reg = SGTL5000_DAP_REG_OFFSET; reg < SGTL5000_MAX_REG_OFFSET; reg += 2)
- snd_soc_write(codec, reg, cache[reg]);
+ regmap_update_bits(sgtl5000->regmap, reg, reg, 0);
/*
* restore these regs according to the power setting sequence in
@@ -1109,30 +1113,33 @@ static int sgtl5000_restore_regs(struct snd_soc_codec *codec)
* 3. SGTL5000_CHIP_REF_CTRL controls Analog Ground Voltage,
* prefer to resotre it after SGTL5000_CHIP_ANA_POWER restored
*/
- snd_soc_write(codec, SGTL5000_CHIP_LINREG_CTRL,
- cache[SGTL5000_CHIP_LINREG_CTRL]);
+ regmap_update_bits(sgtl5000->regmap, SGTL5000_CHIP_LINREG_CTRL,
+ SGTL5000_CHIP_LINREG_CTRL, 0);
- snd_soc_write(codec, SGTL5000_CHIP_ANA_POWER,
- cache[SGTL5000_CHIP_ANA_POWER]);
+ regmap_update_bits(sgtl5000->regmap, SGTL5000_CHIP_ANA_POWER,
+ SGTL5000_PLL_POWERUP_BIT, 0);
- snd_soc_write(codec, SGTL5000_CHIP_CLK_CTRL,
- cache[SGTL5000_CHIP_CLK_CTRL]);
+ regmap_update_bits(sgtl5000->regmap, SGTL5000_CHIP_CLK_CTRL,
+ SGTL5000_MCLK_FREQ_PLL, 0);
- snd_soc_write(codec, SGTL5000_CHIP_REF_CTRL,
- cache[SGTL5000_CHIP_REF_CTRL]);
+ regmap_update_bits(sgtl5000->regmap, SGTL5000_CHIP_REF_CTRL,
+ SGTL5000_CHIP_REF_CTRL, 0);
- snd_soc_write(codec, SGTL5000_CHIP_LINE_OUT_CTRL,
- cache[SGTL5000_CHIP_LINE_OUT_CTRL]);
+ regmap_update_bits(sgtl5000->regmap, SGTL5000_CHIP_LINE_OUT_CTRL,
+ SGTL5000_CHIP_LINE_OUT_CTRL, 0);
return 0;
}
static int sgtl5000_resume(struct snd_soc_codec *codec)
{
+ struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
/* Bring the codec back up to standby to enable regulators */
sgtl5000_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
/* Restore registers by cached in memory */
sgtl5000_restore_regs(codec);
+
+ regcache_cache_only(sgtl5000->regmap, false);
return 0;
}
#else
diff --git a/sound/soc/codecs/sgtl5000.h b/sound/soc/codecs/sgtl5000.h
index 2f8c889..72b68c0 100644
--- a/sound/soc/codecs/sgtl5000.h
+++ b/sound/soc/codecs/sgtl5000.h
@@ -341,6 +341,8 @@
#define SGTL5000_ADC_POWERUP 0x0002
#define SGTL5000_LINE_OUT_POWERUP 0x0001
+#define SGTL5000_PLL_POWERUP_BIT 10
+
/*
* SGTL5000_CHIP_PLL_CTRL
*/
--
1.8.3.2
2
2
Hi there,
Today I received a MiniDSP USBStreamer Box.
(http://www.minidsp.com/products/usb-audio-interface/usbstreamer-box)
It's an USB to ADAT optical interface and claims to be UAC2 compliant.
It's based on a XMOS L2 core.
Audio worked out of the box!
8-Channels In & Out :)
But the alsamixer controls seem to be bogus.
Here's a screenshot of qasmixer:
icem.folkwang-uni.de/~jb/geheim/usbstreamer_qasmixer.png
All controls are named "USBStreamer Clock Selector"...
The first control always snaps back to zero.
The following 8 Multi-Controls don't have any effect.
Only the last two Input/Ouput Master controls work as expected.
The most important problem is that I cannot set the clock source:
> amixer -D hw:USBStreamer cset numid=7 1
numid=7,iface=MIXER,name='USBStreamer Clock Selector'
; type=ENUMERATED,access=rw------,values=1,items=2
; Item #0 'USBStreamer Internal Clock'
; Item #1 'USBStreamer ADAT Clock'
: values=0
The value always stays 0 (internal).
On OS X 10.8.5 without installing any driver I see 8 Input/Output
Volume Sliders + Master Sliders and a working Clock Selector.
I'm running debian testing with a 3.13-1-amd64 stock kernel.
Any ideas? I've attached lsusb and amixer infos below...
Cheers & Thanks,
Jan
_________________________________________________
> amixer -D hw:USBStreamer controls
numid=7,iface=MIXER,name='USBStreamer Clock Selector'
numid=8,iface=MIXER,name='USBStreamer Clock Selector Capture Switch'
numid=9,iface=MIXER,name='USBStreamer Clock Selector Capture
Switch',index=1
numid=10,iface=MIXER,name='USBStreamer Clock Selector Capture Volume'
numid=11,iface=MIXER,name='USBStreamer Clock Selector Capture
Volume',index=1
numid=3,iface=MIXER,name='USBStreamer Clock Selector Playback Switch'
numid=4,iface=MIXER,name='USBStreamer Clock Selector Playback
Switch',index=1
numid=5,iface=MIXER,name='USBStreamer Clock Selector Playback Volume'
numid=6,iface=MIXER,name='USBStreamer Clock Selector Playback
Volume',index=1
numid=2,iface=PCM,name='Capture Channel Map'
numid=1,iface=PCM,name='Playback Channel Map'
______________________________________________________________-
> amixer -D hw:USBStreamer contents
numid=7,iface=MIXER,name='USBStreamer Clock Selector'
; type=ENUMERATED,access=rw------,values=1,items=2
; Item #0 'USBStreamer Internal Clock'
; Item #1 'USBStreamer ADAT Clock'
: values=0
numid=8,iface=MIXER,name='USBStreamer Clock Selector Capture Switch'
; type=BOOLEAN,access=rw------,values=8
: values=on,on,on,on,on,on,on,on
numid=9,iface=MIXER,name='USBStreamer Clock Selector Capture
Switch',index=1
; type=BOOLEAN,access=rw------,values=1
: values=on
numid=10,iface=MIXER,name='USBStreamer Clock Selector Capture Volume'
; type=INTEGER,access=rw---R--,values=8,min=0,max=255,step=0
: values=255,255,255,255,255,255,255,255
| dBminmax-min=-127.50dB,max=0.00dB
numid=11,iface=MIXER,name='USBStreamer Clock Selector Capture
Volume',index=1
; type=INTEGER,access=rw---R--,values=1,min=0,max=255,step=0
: values=255
| dBminmax-min=-127.50dB,max=0.00dB
numid=3,iface=MIXER,name='USBStreamer Clock Selector Playback Switch'
; type=BOOLEAN,access=rw------,values=8
: values=on,on,on,on,on,on,on,on
numid=4,iface=MIXER,name='USBStreamer Clock Selector Playback
Switch',index=1
; type=BOOLEAN,access=rw------,values=1
: values=on
numid=5,iface=MIXER,name='USBStreamer Clock Selector Playback Volume'
; type=INTEGER,access=rw---R--,values=8,min=0,max=255,step=0
: values=255,255,255,255,255,255,255,255
| dBminmax-min=-127.50dB,max=0.00dB
numid=6,iface=MIXER,name='USBStreamer Clock Selector Playback
Volume',index=1
; type=INTEGER,access=rw---R--,values=1,min=0,max=255,step=0
: values=255
| dBminmax-min=-127.50dB,max=0.00dB
numid=2,iface=PCM,name='Capture Channel Map'
; type=INTEGER,access=r----R--,values=8,min=0,max=36,step=0
: values=0,0,0,0,0,0,0,0
| | chmap-fixed=FL,FR,FC,LFE,RL,RR,FLC,FRC
numid=1,iface=PCM,name='Playback Channel Map'
; type=INTEGER,access=r----R--,values=8,min=0,max=36,step=0
: values=0,0,0,0,0,0,0,0
| | chmap-fixed=FL,FR,FC,LFE,RL,RR,FLC,FRC
______________________________________________________________
> lsusb -s 3:10 -v
Bus 003 Device 010: ID 2752:0016
Couldn't open device, some information will be missing
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 239 Miscellaneous Device
bDeviceSubClass 2 ?
bDeviceProtocol 1 Interface Association
bMaxPacketSize0 64
idVendor 0x2752
idProduct 0x0016
bcdDevice 5.30
iManufacturer 1
iProduct 2
iSerial 3
bNumConfigurations 2
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 524
bNumInterfaces 4
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 500mA
Interface Association:
bLength 8
bDescriptorType 11
bFirstInterface 0
bInterfaceCount 3
bFunctionClass 1 Audio
bFunctionSubClass 0
bFunctionProtocol 32
iFunction 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 1 Audio
bInterfaceSubClass 1 Control Device
bInterfaceProtocol 32
iInterface 2
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 1 (HEADER)
bcdADC 2.00
bCategory 8
wTotalLength 257
bmControl 0x00
AudioControl Interface Descriptor:
bLength 8
bDescriptorType 36
bDescriptorSubtype 10 (CLOCK_SOURCE)
bClockID 41
bmAttributes 0x03 Internal programmable Clock
bmControls 0x07
Clock Frequency Control (read/write)
Clock Validity Control (read-only)
bAssocTerminal 0
iClockSource 9
AudioControl Interface Descriptor:
bLength 8
bDescriptorType 36
bDescriptorSubtype 10 (CLOCK_SOURCE)
bClockID 43
bmAttributes 0x00 External Clock
bmControls 0x07
Clock Frequency Control (read/write)
Clock Validity Control (read-only)
bAssocTerminal 0
iClockSource 11
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 11 (CLOCK_SELECTOR)
bUnitID 40
bNrInPins 2
baCSourceID( 0) 41
baCSourceID( 1) 43
bmControls 0x03
Clock Selector Control (read/write)
iClockSelector 8
AudioControl Interface Descriptor:
bLength 17
bDescriptorType 36
bDescriptorSubtype 2 (INPUT_TERMINAL)
bTerminalID 2
wTerminalType 0x0101 USB Streaming
bAssocTerminal 0
bCSourceID 40
bNrChannels 8
bmChannelConfig 0x00000000
bmControls 0x0000
iChannelNames 15
iTerminal 6
AudioControl Interface Descriptor:
bLength 16
bDescriptorType 36
bDescriptorSubtype 9 (EXTENSION_UNIT)
Warning: Descriptor too short
bUnitID 51
wExtensionCode 0
bNrPins 1
baSourceID( 0) 2
bNrChannels 8
wChannelConfig 0
iChannelNames 3
bmControls 0x00
iExtension 42
AudioControl Interface Descriptor:
bLength 42
bDescriptorType 36
bDescriptorSubtype 6 (FEATURE_UNIT)
bUnitID 10
bSourceID 51
bmaControls( 0) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 1) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 2) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 3) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 4) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 5) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 6) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 7) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 8) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
iFeature 0
AudioControl Interface Descriptor:
bLength 12
bDescriptorType 36
bDescriptorSubtype 3 (OUTPUT_TERMINAL)
bTerminalID 20
wTerminalType 0x0301 Speaker
bAssocTerminal 0
bSourceID 10
bCSourceID 40
bmControls 0x0000
iTerminal 0
AudioControl Interface Descriptor:
bLength 17
bDescriptorType 36
bDescriptorSubtype 2 (INPUT_TERMINAL)
bTerminalID 1
wTerminalType 0x0201 Microphone
bAssocTerminal 0
bCSourceID 40
bNrChannels 8
bmChannelConfig 0x00000000
bmControls 0x0000
iChannelNames 33
iTerminal 0
AudioControl Interface Descriptor:
bLength 16
bDescriptorType 36
bDescriptorSubtype 9 (EXTENSION_UNIT)
Warning: Descriptor too short
bUnitID 52
wExtensionCode 0
bNrPins 1
baSourceID( 0) 1
bNrChannels 8
wChannelConfig 0
iChannelNames 3
bmControls 0x00
iExtension 42
AudioControl Interface Descriptor:
bLength 42
bDescriptorType 36
bDescriptorSubtype 6 (FEATURE_UNIT)
bUnitID 11
bSourceID 52
bmaControls( 0) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 1) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 2) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 3) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 4) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 5) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 6) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 7) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 8) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
iFeature 0
AudioControl Interface Descriptor:
bLength 12
bDescriptorType 36
bDescriptorSubtype 3 (OUTPUT_TERMINAL)
bTerminalID 22
wTerminalType 0x0101 USB Streaming
bAssocTerminal 0
bSourceID 11
bCSourceID 40
bmControls 0x0000
iTerminal 7
AudioControl Interface Descriptor:
bLength 17
bDescriptorType 36
bDescriptorSubtype 9 (EXTENSION_UNIT)
Warning: Descriptor too short
bUnitID 50
wExtensionCode 0
bNrPins 2
baSourceID( 0) 2
baSourceID( 1) 1
bNrChannels 18
wChannelConfig 0
iChannelNames 3
bmControls 0x00
iExtension 32
AudioControl Interface Descriptor:
bLength 32
bDescriptorType 36
bDescriptorSubtype 4 (MIXER_UNIT)
bUnitID 60
bNrPins 1
baSourceID( 0) 50
bNrChannels 8
bmChannelConfig 0x00000000
iChannelNames 49
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bmControls 00
iMixer 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x84 EP 4 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0006 1x 6 bytes
bInterval 8
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 32
iInterface 4
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 1
bNumEndpoints 2
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 32
iInterface 4
AudioStreaming Interface Descriptor:
bLength 16
bDescriptorType 36
bDescriptorSubtype 1 (AS_GENERAL)
bTerminalLink 2
bmControls 0x00
bFormatType 1
bmFormats 0x00000001
PCM
bNrChannels 8
bmChannelConfig 0x00000000
iChannelNames 15
AudioStreaming Interface Descriptor:
bLength 6
bDescriptorType 36
bDescriptorSubtype 2 (FORMAT_TYPE)
bFormatType 1 (FORMAT_TYPE_I)
bSubslotSize 4
bBitResolution 24
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 1
AudioControl Endpoint Descriptor:
bLength 8
bDescriptorType 37
bDescriptorSubtype 1 (EP_GENERAL)
bmAttributes 0x00
bmControls 0x00
bLockDelayUnits 2 Decoded PCM samples
wLockDelay 8
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 17
Transfer Type Isochronous
Synch Type None
Usage Type Feedback
wMaxPacketSize 0x0004 1x 4 bytes
bInterval 4
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 2
bNumEndpoints 2
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 32
iInterface 4
AudioStreaming Interface Descriptor:
bLength 16
bDescriptorType 36
bDescriptorSubtype 1 (AS_GENERAL)
bTerminalLink 2
bmControls 0x00
bFormatType 1
bmFormats 0x00000001
PCM
bNrChannels 8
bmChannelConfig 0x00000000
iChannelNames 15
AudioStreaming Interface Descriptor:
bLength 6
bDescriptorType 36
bDescriptorSubtype 2 (FORMAT_TYPE)
bFormatType 1 (FORMAT_TYPE_I)
bSubslotSize 4
bBitResolution 24
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 1
AudioControl Endpoint Descriptor:
bLength 8
bDescriptorType 37
bDescriptorSubtype 1 (EP_GENERAL)
bmAttributes 0x00
bmControls 0x00
bLockDelayUnits 2 Decoded PCM samples
wLockDelay 8
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 17
Transfer Type Isochronous
Synch Type None
Usage Type Feedback
wMaxPacketSize 0x0004 1x 4 bytes
bInterval 8
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 32
iInterface 5
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 1
bNumEndpoints 1
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 32
iInterface 5
AudioStreaming Interface Descriptor:
bLength 16
bDescriptorType 36
bDescriptorSubtype 1 (AS_GENERAL)
bTerminalLink 22
bmControls 0x00
bFormatType 1
bmFormats 0x00000001
PCM
bNrChannels 8
bmChannelConfig 0x00000000
iChannelNames 33
AudioStreaming Interface Descriptor:
bLength 6
bDescriptorType 36
bDescriptorSubtype 2 (FORMAT_TYPE)
bFormatType 1 (FORMAT_TYPE_I)
bSubslotSize 4
bBitResolution 24
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 1
AudioControl Endpoint Descriptor:
bLength 8
bDescriptorType 37
bDescriptorSubtype 1 (EP_GENERAL)
bmAttributes 0x00
bmControls 0x00
bLockDelayUnits 2 Decoded PCM samples
wLockDelay 8
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 2
bNumEndpoints 1
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 32
iInterface 5
AudioStreaming Interface Descriptor:
bLength 16
bDescriptorType 36
bDescriptorSubtype 1 (AS_GENERAL)
bTerminalLink 22
bmControls 0x00
bFormatType 1
bmFormats 0x00000001
PCM
bNrChannels 4
bmChannelConfig 0x00000000
iChannelNames 33
AudioStreaming Interface Descriptor:
bLength 6
bDescriptorType 36
bDescriptorSubtype 2 (FORMAT_TYPE)
bFormatType 1 (FORMAT_TYPE_I)
bSubslotSize 4
bBitResolution 24
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 1
AudioControl Endpoint Descriptor:
bLength 8
bDescriptorType 37
bDescriptorSubtype 1 (EP_GENERAL)
bmAttributes 0x00
bmControls 0x00
bLockDelayUnits 2 Decoded PCM samples
wLockDelay 8
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 3
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 254 Application Specific Interface
bInterfaceSubClass 1 Device Firmware Update
bInterfaceProtocol 1
iInterface 12
Device Firmware Upgrade Interface Descriptor:
bLength 9
bDescriptorType 33
bmAttributes 7
Will Not Detach
Manifestation Tolerant
Upload Supported
Download Supported
wDetachTimeout 250 milliseconds
wTransferSize 64 bytes
bcdDFUVersion 1.10
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 524
bNumInterfaces 4
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 500mA
Interface Association:
bLength 8
bDescriptorType 11
bFirstInterface 0
bInterfaceCount 3
bFunctionClass 1 Audio
bFunctionSubClass 0
bFunctionProtocol 32
iFunction 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 1 Audio
bInterfaceSubClass 1 Control Device
bInterfaceProtocol 32
iInterface 2
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 1 (HEADER)
bcdADC 2.00
bCategory 8
wTotalLength 257
bmControl 0x00
AudioControl Interface Descriptor:
bLength 8
bDescriptorType 36
bDescriptorSubtype 10 (CLOCK_SOURCE)
bClockID 41
bmAttributes 0x03 Internal programmable Clock
bmControls 0x07
Clock Frequency Control (read/write)
Clock Validity Control (read-only)
bAssocTerminal 0
iClockSource 9
AudioControl Interface Descriptor:
bLength 8
bDescriptorType 36
bDescriptorSubtype 10 (CLOCK_SOURCE)
bClockID 43
bmAttributes 0x00 External Clock
bmControls 0x07
Clock Frequency Control (read/write)
Clock Validity Control (read-only)
bAssocTerminal 0
iClockSource 11
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 11 (CLOCK_SELECTOR)
bUnitID 40
bNrInPins 2
baCSourceID( 0) 41
baCSourceID( 1) 43
bmControls 0x03
Clock Selector Control (read/write)
iClockSelector 8
AudioControl Interface Descriptor:
bLength 17
bDescriptorType 36
bDescriptorSubtype 2 (INPUT_TERMINAL)
bTerminalID 2
wTerminalType 0x0101 USB Streaming
bAssocTerminal 0
bCSourceID 40
bNrChannels 8
bmChannelConfig 0x00000000
bmControls 0x0000
iChannelNames 15
iTerminal 6
AudioControl Interface Descriptor:
bLength 16
bDescriptorType 36
bDescriptorSubtype 9 (EXTENSION_UNIT)
Warning: Descriptor too short
bUnitID 51
wExtensionCode 0
bNrPins 1
baSourceID( 0) 2
bNrChannels 8
wChannelConfig 0
iChannelNames 3
bmControls 0x00
iExtension 42
AudioControl Interface Descriptor:
bLength 42
bDescriptorType 36
bDescriptorSubtype 6 (FEATURE_UNIT)
bUnitID 10
bSourceID 51
bmaControls( 0) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 1) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 2) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 3) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 4) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 5) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 6) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 7) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 8) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
iFeature 0
AudioControl Interface Descriptor:
bLength 12
bDescriptorType 36
bDescriptorSubtype 3 (OUTPUT_TERMINAL)
bTerminalID 20
wTerminalType 0x0301 Speaker
bAssocTerminal 0
bSourceID 10
bCSourceID 40
bmControls 0x0000
iTerminal 0
AudioControl Interface Descriptor:
bLength 17
bDescriptorType 36
bDescriptorSubtype 2 (INPUT_TERMINAL)
bTerminalID 1
wTerminalType 0x0201 Microphone
bAssocTerminal 0
bCSourceID 40
bNrChannels 8
bmChannelConfig 0x00000000
bmControls 0x0000
iChannelNames 33
iTerminal 0
AudioControl Interface Descriptor:
bLength 16
bDescriptorType 36
bDescriptorSubtype 9 (EXTENSION_UNIT)
Warning: Descriptor too short
bUnitID 52
wExtensionCode 0
bNrPins 1
baSourceID( 0) 1
bNrChannels 8
wChannelConfig 0
iChannelNames 3
bmControls 0x00
iExtension 42
AudioControl Interface Descriptor:
bLength 42
bDescriptorType 36
bDescriptorSubtype 6 (FEATURE_UNIT)
bUnitID 11
bSourceID 52
bmaControls( 0) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 1) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 2) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 3) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 4) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 5) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 6) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 7) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
bmaControls( 8) 0x0000000f
Mute Control (read/write)
Volume Control (read/write)
iFeature 0
AudioControl Interface Descriptor:
bLength 12
bDescriptorType 36
bDescriptorSubtype 3 (OUTPUT_TERMINAL)
bTerminalID 22
wTerminalType 0x0101 USB Streaming
bAssocTerminal 0
bSourceID 11
bCSourceID 40
bmControls 0x0000
iTerminal 7
AudioControl Interface Descriptor:
bLength 17
bDescriptorType 36
bDescriptorSubtype 9 (EXTENSION_UNIT)
Warning: Descriptor too short
bUnitID 50
wExtensionCode 0
bNrPins 2
baSourceID( 0) 2
baSourceID( 1) 1
bNrChannels 18
wChannelConfig 0
iChannelNames 3
bmControls 0x00
iExtension 32
AudioControl Interface Descriptor:
bLength 32
bDescriptorType 36
bDescriptorSubtype 4 (MIXER_UNIT)
bUnitID 60
bNrPins 1
baSourceID( 0) 50
bNrChannels 8
bmChannelConfig 0x00000000
iChannelNames 49
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bmControls 00
iMixer 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x84 EP 4 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0006 1x 6 bytes
bInterval 8
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 32
iInterface 4
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 1
bNumEndpoints 2
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 32
iInterface 4
AudioStreaming Interface Descriptor:
bLength 16
bDescriptorType 36
bDescriptorSubtype 1 (AS_GENERAL)
bTerminalLink 2
bmControls 0x00
bFormatType 1
bmFormats 0x00000001
PCM
bNrChannels 8
bmChannelConfig 0x00000000
iChannelNames 15
AudioStreaming Interface Descriptor:
bLength 6
bDescriptorType 36
bDescriptorSubtype 2 (FORMAT_TYPE)
bFormatType 1 (FORMAT_TYPE_I)
bSubslotSize 4
bBitResolution 24
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 1
AudioControl Endpoint Descriptor:
bLength 8
bDescriptorType 37
bDescriptorSubtype 1 (EP_GENERAL)
bmAttributes 0x00
bmControls 0x00
bLockDelayUnits 2 Decoded PCM samples
wLockDelay 8
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 17
Transfer Type Isochronous
Synch Type None
Usage Type Feedback
wMaxPacketSize 0x0004 1x 4 bytes
bInterval 4
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 2
bNumEndpoints 2
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 32
iInterface 4
AudioStreaming Interface Descriptor:
bLength 16
bDescriptorType 36
bDescriptorSubtype 1 (AS_GENERAL)
bTerminalLink 2
bmControls 0x00
bFormatType 1
bmFormats 0x00000001
PCM
bNrChannels 8
bmChannelConfig 0x00000000
iChannelNames 15
AudioStreaming Interface Descriptor:
bLength 6
bDescriptorType 36
bDescriptorSubtype 2 (FORMAT_TYPE)
bFormatType 1 (FORMAT_TYPE_I)
bSubslotSize 4
bBitResolution 24
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 1
AudioControl Endpoint Descriptor:
bLength 8
bDescriptorType 37
bDescriptorSubtype 1 (EP_GENERAL)
bmAttributes 0x00
bmControls 0x00
bLockDelayUnits 2 Decoded PCM samples
wLockDelay 8
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 17
Transfer Type Isochronous
Synch Type None
Usage Type Feedback
wMaxPacketSize 0x0004 1x 4 bytes
bInterval 8
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 32
iInterface 5
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 1
bNumEndpoints 1
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 32
iInterface 5
AudioStreaming Interface Descriptor:
bLength 16
bDescriptorType 36
bDescriptorSubtype 1 (AS_GENERAL)
bTerminalLink 22
bmControls 0x00
bFormatType 1
bmFormats 0x00000001
PCM
bNrChannels 8
bmChannelConfig 0x00000000
iChannelNames 33
AudioStreaming Interface Descriptor:
bLength 6
bDescriptorType 36
bDescriptorSubtype 2 (FORMAT_TYPE)
bFormatType 1 (FORMAT_TYPE_I)
bSubslotSize 4
bBitResolution 24
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 1
AudioControl Endpoint Descriptor:
bLength 8
bDescriptorType 37
bDescriptorSubtype 1 (EP_GENERAL)
bmAttributes 0x00
bmControls 0x00
bLockDelayUnits 2 Decoded PCM samples
wLockDelay 8
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 2
bNumEndpoints 1
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 32
iInterface 5
AudioStreaming Interface Descriptor:
bLength 16
bDescriptorType 36
bDescriptorSubtype 1 (AS_GENERAL)
bTerminalLink 22
bmControls 0x00
bFormatType 1
bmFormats 0x00000001
PCM
bNrChannels 4
bmChannelConfig 0x00000000
iChannelNames 33
AudioStreaming Interface Descriptor:
bLength 6
bDescriptorType 36
bDescriptorSubtype 2 (FORMAT_TYPE)
bFormatType 1 (FORMAT_TYPE_I)
bSubslotSize 4
bBitResolution 24
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 1
AudioControl Endpoint Descriptor:
bLength 8
bDescriptorType 37
bDescriptorSubtype 1 (EP_GENERAL)
bmAttributes 0x00
bmControls 0x00
bLockDelayUnits 2 Decoded PCM samples
wLockDelay 8
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 3
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 254 Application Specific Interface
bInterfaceSubClass 1 Device Firmware Update
bInterfaceProtocol 1
iInterface 12
Device Firmware Upgrade Interface Descriptor:
bLength 9
bDescriptorType 33
bmAttributes 7
Will Not Detach
Manifestation Tolerant
Upload Supported
Download Supported
wDetachTimeout 250 milliseconds
wTransferSize 64 bytes
bcdDFUVersion 1.10
2
3
24 May '14
Shorten some over-long lines, multi-line comments, spurious whitespaces,
curly brakets etc. No functional change.
Signed-off-by: Daniel Mack <zonque(a)gmail.com>
---
sound/usb/mixer.c | 406 +++++++++++++++++++++++++++++++++---------------------
1 file changed, 249 insertions(+), 157 deletions(-)
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index d40a285..e13e0c1 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -162,7 +162,7 @@ static int check_mapped_selector_name(struct mixer_build *state, int unitid,
{
const struct usbmix_selector_map *p;
- if (! state->selector_map)
+ if (!state->selector_map)
return 0;
for (p = state->selector_map; p->id; p++) {
if (p->id == unitid && index < p->count)
@@ -174,7 +174,8 @@ static int check_mapped_selector_name(struct mixer_build *state, int unitid,
/*
* find an audio control unit with the given unit id
*/
-static void *find_audio_control_unit(struct mixer_build *state, unsigned char unit)
+static void *find_audio_control_unit(struct mixer_build *state,
+ unsigned char unit)
{
/* we just parse the header */
struct uac_feature_unit_descriptor *hdr = NULL;
@@ -194,7 +195,8 @@ static void *find_audio_control_unit(struct mixer_build *state, unsigned char un
/*
* copy a string with the given id
*/
-static int snd_usb_copy_string_desc(struct mixer_build *state, int index, char *buf, int maxlen)
+static int snd_usb_copy_string_desc(struct mixer_build *state,
+ int index, char *buf, int maxlen)
{
int len = usb_string(state->chip->dev, index, buf, maxlen - 1);
buf[len] = 0;
@@ -253,7 +255,7 @@ static int convert_bytes_value(struct usb_mixer_elem_info *cval, int val)
static int get_relative_value(struct usb_mixer_elem_info *cval, int val)
{
- if (! cval->res)
+ if (!cval->res)
cval->res = 1;
if (val < cval->min)
return 0;
@@ -267,7 +269,7 @@ static int get_abs_value(struct usb_mixer_elem_info *cval, int val)
{
if (val < 0)
return cval->min;
- if (! cval->res)
+ if (!cval->res)
cval->res = 1;
val *= cval->res;
val += cval->min;
@@ -281,7 +283,8 @@ static int get_abs_value(struct usb_mixer_elem_info *cval, int val)
* retrieve a mixer value
*/
-static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
+static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request,
+ int validx, int *value_ret)
{
struct snd_usb_audio *chip = cval->mixer->chip;
unsigned char buf[2];
@@ -292,6 +295,7 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v
err = snd_usb_autoresume(cval->mixer->chip);
if (err < 0)
return -EIO;
+
down_read(&chip->shutdown_rwsem);
while (timeout-- > 0) {
if (chip->shutdown)
@@ -316,10 +320,11 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v
return err;
}
-static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
+static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request,
+ int validx, int *value_ret)
{
struct snd_usb_audio *chip = cval->mixer->chip;
- unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */
+ unsigned char buf[2 + 3 * sizeof(__u16)]; /* enough space for one range */
unsigned char *val;
int idx = 0, ret, size;
__u8 bRequest;
@@ -339,9 +344,9 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v
goto error;
down_read(&chip->shutdown_rwsem);
- if (chip->shutdown)
+ if (chip->shutdown) {
ret = -ENODEV;
- else {
+ } else {
idx = snd_usb_ctrl_intf(chip) | (cval->id << 8);
ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
@@ -382,7 +387,8 @@ error:
return 0;
}
-static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
+static int get_ctl_value(struct usb_mixer_elem_info *cval, int request,
+ int validx, int *value_ret)
{
validx += cval->idx_off;
@@ -391,7 +397,8 @@ static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int vali
get_ctl_value_v2(cval, request, validx, value_ret);
}
-static int get_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int *value)
+static int get_cur_ctl_value(struct usb_mixer_elem_info *cval,
+ int validx, int *value)
{
return get_ctl_value(cval, UAC_GET_CUR, validx, value);
}
@@ -400,7 +407,9 @@ static int get_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int *
static inline int get_cur_mix_raw(struct usb_mixer_elem_info *cval,
int channel, int *value)
{
- return get_ctl_value(cval, UAC_GET_CUR, (cval->control << 8) | channel, value);
+ return get_ctl_value(cval, UAC_GET_CUR,
+ (cval->control << 8) | channel,
+ value);
}
static int get_cur_mix_value(struct usb_mixer_elem_info *cval,
@@ -417,7 +426,7 @@ static int get_cur_mix_value(struct usb_mixer_elem_info *cval,
if (!cval->mixer->ignore_ctl_error)
usb_audio_dbg(cval->mixer->chip,
"cannot get current value for control %d ch %d: err = %d\n",
- cval->control, channel, err);
+ cval->control, channel, err);
return err;
}
cval->cached |= 1 << channel;
@@ -425,7 +434,6 @@ static int get_cur_mix_value(struct usb_mixer_elem_info *cval,
return 0;
}
-
/*
* set a mixer value
*/
@@ -474,7 +482,7 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
}
}
usb_audio_dbg(chip, "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n",
- request, validx, idx, cval->val_type, buf[0], buf[1]);
+ request, validx, idx, cval->val_type, buf[0], buf[1]);
err = -EINVAL;
out:
@@ -483,7 +491,8 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
return err;
}
-static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value)
+static int set_cur_ctl_value(struct usb_mixer_elem_info *cval,
+ int validx, int value)
{
return snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, validx, value);
}
@@ -503,8 +512,9 @@ static int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel,
return 0;
}
- err = snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, (cval->control << 8) | channel,
- value);
+ err = snd_usb_mixer_set_ctl_value(cval,
+ UAC_SET_CUR, (cval->control << 8) | channel,
+ value);
if (err < 0)
return err;
cval->cached |= 1 << channel;
@@ -541,13 +551,13 @@ static int parse_audio_unit(struct mixer_build *state, int unitid);
* check if the input/output channel routing is enabled on the given bitmap.
* used for mixer unit parser
*/
-static int check_matrix_bitmap(unsigned char *bmap, int ich, int och, int num_outs)
+static int check_matrix_bitmap(unsigned char *bmap,
+ int ich, int och, int num_outs)
{
int idx = ich * num_outs + och;
return bmap[idx >> 3] & (0x80 >> (idx & 7));
}
-
/*
* add an alsa control element
* search and increment the index until an empty slot is found.
@@ -564,7 +574,8 @@ int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer,
while (snd_ctl_find_id(mixer->chip->card, &kctl->id))
kctl->id.index++;
if ((err = snd_ctl_add(mixer->chip->card, kctl)) < 0) {
- usb_audio_dbg(mixer->chip, "cannot add control (err = %d)\n", err);
+ usb_audio_dbg(mixer->chip, "cannot add control (err = %d)\n",
+ err);
return err;
}
cval->elem_id = &kctl->id;
@@ -573,7 +584,6 @@ int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer,
return 0;
}
-
/*
* get a terminal name string
*/
@@ -627,7 +637,8 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm
struct iterm_name_combo *names;
if (iterm->name)
- return snd_usb_copy_string_desc(state, iterm->name, name, maxlen);
+ return snd_usb_copy_string_desc(state, iterm->name,
+ name, maxlen);
/* virtual type - not a real terminal */
if (iterm->type >> 16) {
@@ -635,13 +646,17 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm
return 0;
switch (iterm->type >> 16) {
case UAC_SELECTOR_UNIT:
- strcpy(name, "Selector"); return 8;
+ strcpy(name, "Selector");
+ return 8;
case UAC1_PROCESSING_UNIT:
- strcpy(name, "Process Unit"); return 12;
+ strcpy(name, "Process Unit");
+ return 12;
case UAC1_EXTENSION_UNIT:
- strcpy(name, "Ext Unit"); return 8;
+ strcpy(name, "Ext Unit");
+ return 8;
case UAC_MIXER_UNIT:
- strcpy(name, "Mixer"); return 5;
+ strcpy(name, "Mixer");
+ return 5;
default:
return sprintf(name, "Unit %d", iterm->id);
}
@@ -649,29 +664,35 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm
switch (iterm->type & 0xff00) {
case 0x0100:
- strcpy(name, "PCM"); return 3;
+ strcpy(name, "PCM");
+ return 3;
case 0x0200:
- strcpy(name, "Mic"); return 3;
+ strcpy(name, "Mic");
+ return 3;
case 0x0400:
- strcpy(name, "Headset"); return 7;
+ strcpy(name, "Headset");
+ return 7;
case 0x0500:
- strcpy(name, "Phone"); return 5;
+ strcpy(name, "Phone");
+ return 5;
}
- for (names = iterm_names; names->type; names++)
+ for (names = iterm_names; names->type; names++) {
if (names->type == iterm->type) {
strcpy(name, names->name);
return strlen(names->name);
}
+ }
+
return 0;
}
-
/*
* parse the source unit recursively until it reaches to a terminal
* or a branched unit.
*/
-static int check_input_term(struct mixer_build *state, int id, struct usb_audio_term *term)
+static int check_input_term(struct mixer_build *state, int id,
+ struct usb_audio_term *term)
{
int err;
void *p1;
@@ -766,7 +787,6 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_
return -ENODEV;
}
-
/*
* Feature Unit
*/
@@ -794,7 +814,6 @@ static struct usb_feature_control_info audio_feature_info[] = {
{ "Phase Inverter Control", USB_MIXER_BOOLEAN },
};
-
/* private_free callback */
static void usb_mixer_elem_free(struct snd_kcontrol *kctl)
{
@@ -802,7 +821,6 @@ static void usb_mixer_elem_free(struct snd_kcontrol *kctl)
kctl->private_data = NULL;
}
-
/*
* interface to ALSA control for feature/mixer units
*/
@@ -906,7 +924,6 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,
cval->res = 384;
}
break;
-
}
}
@@ -939,21 +956,26 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,
get_ctl_value(cval, UAC_GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) {
usb_audio_err(cval->mixer->chip,
"%d:%d: cannot get min/max values for control %d (id %d)\n",
- cval->id, snd_usb_ctrl_intf(cval->mixer->chip), cval->control, cval->id);
+ cval->id, snd_usb_ctrl_intf(cval->mixer->chip),
+ cval->control, cval->id);
return -EINVAL;
}
- if (get_ctl_value(cval, UAC_GET_RES, (cval->control << 8) | minchn, &cval->res) < 0) {
+ if (get_ctl_value(cval, UAC_GET_RES,
+ (cval->control << 8) | minchn,
+ &cval->res) < 0) {
cval->res = 1;
} else {
int last_valid_res = cval->res;
while (cval->res > 1) {
if (snd_usb_mixer_set_ctl_value(cval, UAC_SET_RES,
- (cval->control << 8) | minchn, cval->res / 2) < 0)
+ (cval->control << 8) | minchn,
+ cval->res / 2) < 0)
break;
cval->res /= 2;
}
- if (get_ctl_value(cval, UAC_GET_RES, (cval->control << 8) | minchn, &cval->res) < 0)
+ if (get_ctl_value(cval, UAC_GET_RES,
+ (cval->control << 8) | minchn, &cval->res) < 0)
cval->res = last_valid_res;
}
if (cval->res == 0)
@@ -1017,7 +1039,8 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,
#define get_min_max(cval, def) get_min_max_with_quirks(cval, def, NULL)
/* get a feature/mixer unit info */
-static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
{
struct usb_mixer_elem_info *cval = kcontrol->private_data;
@@ -1051,7 +1074,8 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_
}
/* get the current value from feature/mixer unit */
-static int mixer_ctl_feature_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int mixer_ctl_feature_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct usb_mixer_elem_info *cval = kcontrol->private_data;
int c, cnt, val, err;
@@ -1082,7 +1106,8 @@ static int mixer_ctl_feature_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
}
/* put the current value to feature/mixer unit */
-static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct usb_mixer_elem_info *cval = kcontrol->private_data;
int c, cnt, val, oval, err;
@@ -1136,22 +1161,25 @@ static struct snd_kcontrol_new usb_feature_unit_ctl_ro = {
.put = NULL,
};
-/* This symbol is exported in order to allow the mixer quirks to
- * hook up to the standard feature unit control mechanism */
+/*
+ * This symbol is exported in order to allow the mixer quirks to
+ * hook up to the standard feature unit control mechanism
+ */
struct snd_kcontrol_new *snd_usb_feature_unit_ctl = &usb_feature_unit_ctl;
/*
* build a feature control
*/
-
static size_t append_ctl_name(struct snd_kcontrol *kctl, const char *str)
{
return strlcat(kctl->id.name, str, sizeof(kctl->id.name));
}
-/* A lot of headsets/headphones have a "Speaker" mixer. Make sure we
- rename it to "Headphone". We determine if something is a headphone
- similar to how udev determines form factor. */
+/*
+ * A lot of headsets/headphones have a "Speaker" mixer. Make sure we
+ * rename it to "Headphone". We determine if something is a headphone
+ * similar to how udev determines form factor.
+ */
static void check_no_speaker_on_headset(struct snd_kcontrol *kctl,
struct snd_card *card)
{
@@ -1201,7 +1229,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
return;
cval = kzalloc(sizeof(*cval), GFP_KERNEL);
- if (! cval) {
+ if (!cval) {
usb_audio_err(state->chip, "cannot malloc kcontrol\n");
return;
}
@@ -1222,15 +1250,17 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
cval->ch_readonly = readonly_mask;
}
- /* if all channels in the mask are marked read-only, make the control
+ /*
+ * If all channels in the mask are marked read-only, make the control
* read-only. set_cur_mix_value() will check the mask again and won't
- * issue write commands to read-only channels. */
+ * issue write commands to read-only channels.
+ */
if (cval->channels == readonly_mask)
kctl = snd_ctl_new1(&usb_feature_unit_ctl_ro, cval);
else
kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
- if (! kctl) {
+ if (!kctl) {
usb_audio_err(state->chip, "cannot malloc kcontrol\n");
kfree(cval);
return;
@@ -1239,48 +1269,53 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
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));
switch (control) {
case UAC_FU_MUTE:
case UAC_FU_VOLUME:
- /* determine the control name. the rule is:
+ /*
+ * determine the control name. the rule is:
* - if a name id is given in descriptor, use it.
* - if the connected input can be determined, then use the name
* of terminal type.
* - if the connected output can be determined, use it.
* - otherwise, anonymous name.
*/
- if (! len) {
- len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 1);
- if (! len)
- len = get_term_name(state, &state->oterm, kctl->id.name, sizeof(kctl->id.name), 1);
- if (! len)
- len = snprintf(kctl->id.name, sizeof(kctl->id.name),
+ if (!len) {
+ len = get_term_name(state, iterm, kctl->id.name,
+ sizeof(kctl->id.name), 1);
+ if (!len)
+ len = get_term_name(state, &state->oterm,
+ kctl->id.name,
+ sizeof(kctl->id.name), 1);
+ if (!len)
+ len = snprintf(kctl->id.name,
+ sizeof(kctl->id.name),
"Feature %d", unitid);
}
if (!mapped_name)
check_no_speaker_on_headset(kctl, state->mixer->chip->card);
- /* determine the stream direction:
+ /*
+ * determine the stream direction:
* if the connected output is USB stream, then it's likely a
* capture stream. otherwise it should be playback (hopefully :)
*/
- if (! mapped_name && ! (state->oterm.type >> 16)) {
- if ((state->oterm.type & 0xff00) == 0x0100) {
+ if (!mapped_name && !(state->oterm.type >> 16)) {
+ if ((state->oterm.type & 0xff00) == 0x0100)
len = append_ctl_name(kctl, " Capture");
- } else {
+ else
len = append_ctl_name(kctl, " Playback");
- }
}
append_ctl_name(kctl, control == UAC_FU_MUTE ?
" Switch" : " Volume");
break;
default:
- if (! len)
+ if (!len)
strlcpy(kctl->id.name, audio_feature_info[control-1].name,
sizeof(kctl->id.name));
break;
@@ -1300,33 +1335,35 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
}
range = (cval->max - cval->min) / cval->res;
- /* Are there devices with volume range more than 255? I use a bit more
+ /*
+ * Are there devices with volume range more than 255? I use a bit more
* to be sure. 384 is a resolution magic number found on Logitech
* devices. It will definitively catch all buggy Logitech devices.
*/
if (range > 384) {
- usb_audio_warn(state->chip, "Warning! Unlikely big "
- "volume range (=%u), cval->res is probably wrong.",
- range);
+ usb_audio_warn(state->chip,
+ "Warning! Unlikely big volume range (=%u), "
+ "cval->res is probably wrong.",
+ range);
usb_audio_warn(state->chip, "[%d] FU [%s] ch = %d, "
- "val = %d/%d/%d", cval->id,
- kctl->id.name, cval->channels,
- cval->min, cval->max, cval->res);
+ "val = %d/%d/%d", cval->id,
+ kctl->id.name, cval->channels,
+ cval->min, cval->max, cval->res);
}
usb_audio_dbg(state->chip, "[%d] FU [%s] ch = %d, val = %d/%d/%d\n",
- cval->id, kctl->id.name, cval->channels, cval->min, cval->max, cval->res);
+ cval->id, kctl->id.name, cval->channels,
+ cval->min, cval->max, cval->res);
snd_usb_mixer_add_control(state->mixer, kctl);
}
-
-
/*
* parse a feature unit
*
* most of controls are defined here.
*/
-static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void *_ftr)
+static int parse_audio_feature_unit(struct mixer_build *state, int unitid,
+ void *_ftr)
{
int channels, i, j;
struct usb_audio_term iterm;
@@ -1400,15 +1437,25 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
for (i = 0; i < 10; i++) {
unsigned int ch_bits = 0;
for (j = 0; j < channels; j++) {
- unsigned int mask = snd_usb_combine_bytes(bmaControls + csize * (j+1), csize);
+ unsigned int mask;
+
+ mask = snd_usb_combine_bytes(bmaControls +
+ csize * (j+1), csize);
if (mask & (1 << i))
ch_bits |= (1 << j);
}
/* audio class v1 controls are never read-only */
- if (ch_bits & 1) /* the first channel must be set (for ease of programming) */
- build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid, 0);
+
+ /*
+ * The first channel must be set
+ * (for ease of programming).
+ */
+ if (ch_bits & 1)
+ build_feature_ctl(state, _ftr, ch_bits, i,
+ &iterm, unitid, 0);
if (master_bits & (1 << i))
- build_feature_ctl(state, _ftr, 0, i, &iterm, unitid, 0);
+ build_feature_ctl(state, _ftr, 0, i, &iterm,
+ unitid, 0);
}
} else { /* UAC_VERSION_2 */
for (i = 0; i < ARRAY_SIZE(audio_feature_info); i++) {
@@ -1416,7 +1463,10 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
unsigned int ch_read_only = 0;
for (j = 0; j < channels; j++) {
- unsigned int mask = snd_usb_combine_bytes(bmaControls + csize * (j+1), csize);
+ unsigned int mask;
+
+ mask = snd_usb_combine_bytes(bmaControls +
+ csize * (j+1), csize);
if (uac2_control_is_readable(mask, i)) {
ch_bits |= (1 << j);
if (!uac2_control_is_writeable(mask, i))
@@ -1424,12 +1474,22 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
}
}
- /* NOTE: build_feature_ctl() will mark the control read-only if all channels
- * are marked read-only in the descriptors. Otherwise, the control will be
- * reported as writeable, but the driver will not actually issue a write
- * command for read-only channels */
- if (ch_bits & 1) /* the first channel must be set (for ease of programming) */
- build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid, ch_read_only);
+ /*
+ * NOTE: build_feature_ctl() will mark the control
+ * read-only if all channels are marked read-only in
+ * the descriptors. Otherwise, the control will be
+ * reported as writeable, but the driver will not
+ * actually issue a write command for read-only
+ * channels.
+ */
+
+ /*
+ * The first channel must be set
+ * (for ease of programming).
+ */
+ if (ch_bits & 1)
+ build_feature_ctl(state, _ftr, ch_bits, i,
+ &iterm, unitid, ch_read_only);
if (uac2_control_is_readable(master_bits, i))
build_feature_ctl(state, _ftr, 0, i, &iterm, unitid,
!uac2_control_is_writeable(master_bits, i));
@@ -1439,7 +1499,6 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
return 0;
}
-
/*
* Mixer Unit
*/
@@ -1450,7 +1509,6 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
* the callbacks are identical with feature unit.
* input channel number (zero based) is given in control field instead.
*/
-
static void build_mixer_unit_ctl(struct mixer_build *state,
struct uac_mixer_unit_descriptor *desc,
int in_pin, int in_ch, int unitid,
@@ -1467,7 +1525,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state,
return;
cval = kzalloc(sizeof(*cval), GFP_KERNEL);
- if (! cval)
+ if (!cval)
return;
cval->mixer = state->mixer;
@@ -1475,7 +1533,9 @@ static void build_mixer_unit_ctl(struct mixer_build *state,
cval->control = in_ch + 1; /* based on 1 */
cval->val_type = USB_MIXER_S16;
for (i = 0; i < num_outs; i++) {
- if (check_matrix_bitmap(uac_mixer_unit_bmControls(desc, state->mixer->protocol), in_ch, i, num_outs)) {
+ __u8 *c = uac_mixer_unit_bmControls(desc, state->mixer->protocol);
+
+ if (check_matrix_bitmap(c, in_ch, i, num_outs)) {
cval->cmask |= (1 << i);
cval->channels++;
}
@@ -1485,7 +1545,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state,
get_min_max(cval, 0);
kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
- if (! kctl) {
+ if (!kctl) {
usb_audio_err(state->chip, "cannot malloc kcontrol\n");
kfree(cval);
return;
@@ -1493,9 +1553,10 @@ static void build_mixer_unit_ctl(struct mixer_build *state,
kctl->private_free = usb_mixer_elem_free;
len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
- if (! len)
- len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 0);
- if (! len)
+ if (!len)
+ len = get_term_name(state, iterm, kctl->id.name,
+ sizeof(kctl->id.name), 0);
+ if (!len)
len = sprintf(kctl->id.name, "Mixer Source %d", in_ch + 1);
append_ctl_name(kctl, " Volume");
@@ -1504,24 +1565,28 @@ static void build_mixer_unit_ctl(struct mixer_build *state,
snd_usb_mixer_add_control(state->mixer, kctl);
}
-
/*
* parse a mixer unit
*/
-static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, void *raw_desc)
+static int parse_audio_mixer_unit(struct mixer_build *state, int unitid,
+ void *raw_desc)
{
struct uac_mixer_unit_descriptor *desc = raw_desc;
struct usb_audio_term iterm;
int input_pins, num_ins, num_outs;
int pin, ich, err;
- if (desc->bLength < 11 || ! (input_pins = desc->bNrInPins) || ! (num_outs = uac_mixer_unit_bNrChannels(desc))) {
- usb_audio_err(state->chip, "invalid MIXER UNIT descriptor %d\n", unitid);
+ if (desc->bLength < 11 || !(input_pins = desc->bNrInPins) ||
+ !(num_outs = uac_mixer_unit_bNrChannels(desc))) {
+ usb_audio_err(state->chip,
+ "invalid MIXER UNIT descriptor %d\n",
+ unitid);
return -EINVAL;
}
/* no bmControls field (e.g. Maya44) -> ignore */
if (desc->bLength <= 10 + input_pins) {
- usb_audio_dbg(state->chip, "MU %d has no bmControls field\n", unitid);
+ usb_audio_dbg(state->chip, "MU %d has no bmControls field\n",
+ unitid);
return 0;
}
@@ -1535,12 +1600,14 @@ static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, void *r
if (err < 0)
return err;
num_ins += iterm.channels;
- for (; ich < num_ins; ++ich) {
+ for (; ich < num_ins; ich++) {
int och, ich_has_controls = 0;
- for (och = 0; och < num_outs; ++och) {
- if (check_matrix_bitmap(uac_mixer_unit_bmControls(desc, state->mixer->protocol),
- ich, och, num_outs)) {
+ for (och = 0; och < num_outs; och++) {
+ __u8 *c = uac_mixer_unit_bmControls(desc,
+ state->mixer->protocol);
+
+ if (check_matrix_bitmap(c, ich, och, num_outs)) {
ich_has_controls = 1;
break;
}
@@ -1553,13 +1620,13 @@ static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, void *r
return 0;
}
-
/*
* Processing Unit / Extension Unit
*/
/* get callback for processing/extension unit */
-static int mixer_ctl_procunit_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int mixer_ctl_procunit_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct usb_mixer_elem_info *cval = kcontrol->private_data;
int err, val;
@@ -1577,7 +1644,8 @@ static int mixer_ctl_procunit_get(struct snd_kcontrol *kcontrol, struct snd_ctl_
}
/* put callback for processing/extension unit */
-static int mixer_ctl_procunit_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int mixer_ctl_procunit_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct usb_mixer_elem_info *cval = kcontrol->private_data;
int val, oval, err;
@@ -1606,7 +1674,6 @@ static struct snd_kcontrol_new mixer_procunit_ctl = {
.put = mixer_ctl_procunit_put,
};
-
/*
* predefined data for processing units
*/
@@ -1697,10 +1764,13 @@ static struct procunit_info extunits[] = {
{ USB_XU_DEVICE_OPTIONS, "AnalogueIn Soft Limit", soft_limit_xu_info },
{ 0 }
};
+
/*
* build a processing/extension unit
*/
-static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw_desc, struct procunit_info *list, char *name)
+static int build_audio_procunit(struct mixer_build *state, int unitid,
+ void *raw_desc, struct procunit_info *list,
+ char *name)
{
struct uac_processing_unit_descriptor *desc = raw_desc;
int num_ins = desc->bNrInPins;
@@ -1733,19 +1803,19 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw
for (info = list; info && info->type; info++)
if (info->type == type)
break;
- if (! info || ! info->type)
+ if (!info || !info->type)
info = &default_info;
for (valinfo = info->values; valinfo->control; valinfo++) {
__u8 *controls = uac_processing_unit_bmControls(desc, state->mixer->protocol);
- if (! (controls[valinfo->control / 8] & (1 << ((valinfo->control % 8) - 1))))
+ if (!(controls[valinfo->control / 8] & (1 << ((valinfo->control % 8) - 1))))
continue;
map = find_map(state, unitid, valinfo->control);
if (check_ignored_ctl(map))
continue;
cval = kzalloc(sizeof(*cval), GFP_KERNEL);
- if (! cval) {
+ if (!cval) {
usb_audio_err(state->chip, "cannot malloc kcontrol\n");
return -ENOMEM;
}
@@ -1765,7 +1835,8 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw
cval->initialized = 1;
} else {
if (type == USB_XU_CLOCK_RATE) {
- /* E-Mu USB 0404/0202/TrackerPre/0204
+ /*
+ * E-Mu USB 0404/0202/TrackerPre/0204
* samplerate control quirk
*/
cval->min = 0;
@@ -1777,60 +1848,70 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw
}
kctl = snd_ctl_new1(&mixer_procunit_ctl, cval);
- if (! kctl) {
+ if (!kctl) {
usb_audio_err(state->chip, "cannot malloc kcontrol\n");
kfree(cval);
return -ENOMEM;
}
kctl->private_free = usb_mixer_elem_free;
- if (check_mapped_name(map, 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));
- else {
+ } else {
nameid = uac_processing_unit_iProcessing(desc, state->mixer->protocol);
len = 0;
if (nameid)
- len = snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name));
- if (! len)
+ len = snd_usb_copy_string_desc(state, nameid,
+ kctl->id.name,
+ sizeof(kctl->id.name));
+ if (!len)
strlcpy(kctl->id.name, name, sizeof(kctl->id.name));
}
append_ctl_name(kctl, " ");
append_ctl_name(kctl, valinfo->suffix);
usb_audio_dbg(state->chip,
- "[%d] PU [%s] ch = %d, val = %d/%d\n",
- cval->id, kctl->id.name, cval->channels, cval->min, cval->max);
- if ((err = snd_usb_mixer_add_control(state->mixer, kctl)) < 0)
+ "[%d] PU [%s] ch = %d, val = %d/%d\n",
+ cval->id, kctl->id.name, cval->channels,
+ cval->min, cval->max);
+
+ err = snd_usb_mixer_add_control(state->mixer, kctl);
+ if (err < 0)
return err;
}
return 0;
}
-
-static int parse_audio_processing_unit(struct mixer_build *state, int unitid, void *raw_desc)
+static int parse_audio_processing_unit(struct mixer_build *state, int unitid,
+ void *raw_desc)
{
- return build_audio_procunit(state, unitid, raw_desc, procunits, "Processing Unit");
+ return build_audio_procunit(state, unitid, raw_desc,
+ procunits, "Processing Unit");
}
-static int parse_audio_extension_unit(struct mixer_build *state, int unitid, void *raw_desc)
+static int parse_audio_extension_unit(struct mixer_build *state, int unitid,
+ void *raw_desc)
{
- /* Note that we parse extension units with processing unit descriptors.
- * That's ok as the layout is the same */
- return build_audio_procunit(state, unitid, raw_desc, extunits, "Extension Unit");
+ /*
+ * Note that we parse extension units with processing unit descriptors.
+ * That's ok as the layout is the same.
+ */
+ return build_audio_procunit(state, unitid, raw_desc,
+ extunits, "Extension Unit");
}
-
/*
* Selector Unit
*/
-/* info callback for selector unit
+/*
+ * info callback for selector unit
* use an enumerator type for routing
*/
-static int mixer_ctl_selector_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int mixer_ctl_selector_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
{
struct usb_mixer_elem_info *cval = kcontrol->private_data;
const char **itemlist = (const char **)kcontrol->private_value;
@@ -1841,7 +1922,8 @@ static int mixer_ctl_selector_info(struct snd_kcontrol *kcontrol, struct snd_ctl
}
/* get callback for selector unit */
-static int mixer_ctl_selector_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int mixer_ctl_selector_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct usb_mixer_elem_info *cval = kcontrol->private_data;
int val, err;
@@ -1860,7 +1942,8 @@ static int mixer_ctl_selector_get(struct snd_kcontrol *kcontrol, struct snd_ctl_
}
/* put callback for selector unit */
-static int mixer_ctl_selector_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int mixer_ctl_selector_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct usb_mixer_elem_info *cval = kcontrol->private_data;
int val, oval, err;
@@ -1889,8 +1972,8 @@ static struct snd_kcontrol_new mixer_selectunit_ctl = {
.put = mixer_ctl_selector_put,
};
-
-/* private free callback.
+/*
+ * private free callback.
* free both private_data and private_value
*/
static void usb_mixer_selector_elem_free(struct snd_kcontrol *kctl)
@@ -1915,7 +1998,8 @@ static void usb_mixer_selector_elem_free(struct snd_kcontrol *kctl)
/*
* parse a selector unit
*/
-static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void *raw_desc)
+static int parse_audio_selector_unit(struct mixer_build *state, int unitid,
+ void *raw_desc)
{
struct uac_selector_unit_descriptor *desc = raw_desc;
unsigned int i, nameid, len;
@@ -1944,7 +2028,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void
return 0;
cval = kzalloc(sizeof(*cval), GFP_KERNEL);
- if (! cval) {
+ if (!cval) {
usb_audio_err(state->chip, "cannot malloc kcontrol\n");
return -ENOMEM;
}
@@ -1963,7 +2047,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void
cval->control = 0;
namelist = kmalloc(sizeof(char *) * desc->bNrInPins, GFP_KERNEL);
- if (! namelist) {
+ if (!namelist) {
usb_audio_err(state->chip, "cannot malloc\n");
kfree(cval);
return -ENOMEM;
@@ -1973,7 +2057,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void
struct usb_audio_term iterm;
len = 0;
namelist[i] = kmalloc(MAX_ITEM_NAME_LEN, GFP_KERNEL);
- if (! namelist[i]) {
+ if (!namelist[i]) {
usb_audio_err(state->chip, "cannot malloc\n");
while (i--)
kfree(namelist[i]);
@@ -1983,14 +2067,14 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void
}
len = check_mapped_selector_name(state, unitid, i, namelist[i],
MAX_ITEM_NAME_LEN);
- if (! len && check_input_term(state, desc->baSourceID[i], &iterm) >= 0)
+ if (!len && check_input_term(state, desc->baSourceID[i], &iterm) >= 0)
len = get_term_name(state, &iterm, namelist[i], MAX_ITEM_NAME_LEN, 0);
- if (! len)
+ if (!len)
sprintf(namelist[i], "Input %d", i);
}
kctl = snd_ctl_new1(&mixer_selectunit_ctl, cval);
- if (! kctl) {
+ if (!kctl) {
usb_audio_err(state->chip, "cannot malloc kcontrol\n");
kfree(namelist);
kfree(cval);
@@ -2004,11 +2088,12 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void
if (len)
;
else if (nameid)
- snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name));
+ snd_usb_copy_string_desc(state, nameid, kctl->id.name,
+ sizeof(kctl->id.name));
else {
len = get_term_name(state, &state->oterm,
kctl->id.name, sizeof(kctl->id.name), 0);
- if (! len)
+ if (!len)
strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name));
if (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR)
@@ -2027,7 +2112,6 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void
return 0;
}
-
/*
* parse an audio unit recursively
*/
@@ -2125,14 +2209,16 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
}
p = NULL;
- while ((p = snd_usb_find_csint_desc(mixer->hostif->extra, mixer->hostif->extralen,
+ while ((p = snd_usb_find_csint_desc(mixer->hostif->extra,
+ mixer->hostif->extralen,
p, UAC_OUTPUT_TERMINAL)) != NULL) {
if (mixer->protocol == UAC_VERSION_1) {
struct uac1_output_terminal_descriptor *desc = p;
if (desc->bLength < sizeof(*desc))
continue; /* invalid descriptor? */
- set_bit(desc->bTerminalID, state.unitbitmap); /* mark terminal ID as visited */
+ /* mark terminal ID as visited */
+ set_bit(desc->bTerminalID, state.unitbitmap);
state.oterm.id = desc->bTerminalID;
state.oterm.type = le16_to_cpu(desc->wTerminalType);
state.oterm.name = desc->iTerminal;
@@ -2144,7 +2230,8 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
if (desc->bLength < sizeof(*desc))
continue; /* invalid descriptor? */
- set_bit(desc->bTerminalID, state.unitbitmap); /* mark terminal ID as visited */
+ /* mark terminal ID as visited */
+ set_bit(desc->bTerminalID, state.unitbitmap);
state.oterm.id = desc->bTerminalID;
state.oterm.type = le16_to_cpu(desc->wTerminalType);
state.oterm.name = desc->iTerminal;
@@ -2152,7 +2239,10 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
if (err < 0 && err != -EINVAL)
return err;
- /* for UAC2, use the same approach to also add the clock selectors */
+ /*
+ * For UAC2, use the same approach to also add the
+ * clock selectors
+ */
err = parse_audio_unit(&state, desc->bCSourceID);
if (err < 0 && err != -EINVAL)
return err;
@@ -2306,7 +2396,9 @@ static void snd_usb_mixer_interrupt(struct urb *urb)
}
requeue:
- if (ustatus != -ENOENT && ustatus != -ECONNRESET && ustatus != -ESHUTDOWN) {
+ if (ustatus != -ENOENT &&
+ ustatus != -ECONNRESET &&
+ ustatus != -ESHUTDOWN) {
urb->dev = mixer->chip->dev;
usb_submit_urb(urb, GFP_ATOMIC);
}
--
1.9.0
2
3
Hi,
Need an input from you guys please.
Is there a possibility to play out an audio using aplay or any alsa
tools without the presence of the codec driver
In our target platform, we have the SoC's I2S platform driver working,
and a dummy codec driver is registered
The actual codec chip sits on a external board and connected to the
main SoC via I2S and I2C lines. And that codec chip is configured via a
middleware package(not alsa)
So we do not have a codec driver at the kernel space, we have just
provided a plain I2C interface driver for the middleware package. so
that it can send I2C commands directly to the audio codec chip. Based
on the requirement have to give the control interface of the codec chip
to the middleware package
In this case is there a possibility to play out an audio file using
alsa tools(eg. aplay)
Just a raw PCM format should be enough.
Thanks,
Babu
::DISCLAIMER::
-----------------------------------------------------------------------
-----------------------------------------------------------------------
------
The contents of this e-mail and any attachment(s) are confidential and
intended for the named recipient(s) only.
E-mail transmission is not guaranteed to be secure or error-free as
information could be intercepted, corrupted,
lost, destroyed, arrive late or incomplete, or may contain viruses in
transmission. The e mail and its contents
(with or without referred errors) shall therefore not attach any
liability on the originator or HCL or its affiliates.
Views or opinions, if any, presented in this email are solely those of
the author and may not necessarily reflect the
views or opinions of HCL or its affiliates. Any form of reproduction,
dissemination, copying, disclosure, modification,
distribution and / or publication of this message without the prior
written consent of authorized representative of
HCL is strictly prohibited. If you have received this email in error
please delete it and notify the sender immediately.
Before opening any email and/or attachments, please check them for
viruses and other defects.
-----------------------------------------------------------------------
-----------------------------------------------------------------------
------
1
0
This patch set fixes the resource sharing problems between
omap-hdmi-dai driver and OMAPDSS HDMI driver. It does it by
registering the OMAP HDMI audio related ASoC drivers from OMAPDSS HDMI
driver. Platform data structs have been added for omap-hdmi-dai and
omap-hdmi-card drivers to pass the information and resources from
OMAPDSS HDMI driver.
The idea of this patch set is to fix HDMI audio for the next release
after it got broken by OMAPDSS DT changes. It does not mean that I
have abandoned the patch set that integrates the omap-hdmi-dai driver
into OMAPDSS HDMI driver. The OMAPDSS side of those patches just had
some dependencies to the recent ASoC side patches that would have
caused problems in the next merge. I'll mail a revised and rebased
version of those patches soon.
Best regards,
Jyri
Jyri Sarha (13):
ARM: omap4.dtsi: Add audio related parametes to hdmi node
ARM: omap5.dtsi: Add audio related parameters to hdmi node
ARM: OMAP2+: Remove non working OMAP HDMI audio initialization
OMAPDSS: hdmi_wp: Add function for getting hdmi_wp physical base
address
OMAPDSS: hdmi_audio: Add hdmi_audio.c for registering HDMI audio
support
ASoC: omap-hdmi-dai: Add platform data struct for omap-hdmi-dai
driver
ASoC: omap-hdmi-card: Add platform data stuct for omap-hdmi-card
driver
ASoC: omap-hdmi: Changes for registeing the driver from OMAPDSS
ASoC: omap-hdmi-card: Changes for registeing the driver from OMAPDSS
OMAPDSS: hdmi4: Register HDMI audio ASoC drivers from HDMI driver
OMAPDSS: hdmi.h: Add HDMI_AUDIO_LAYOUT_6CH enum value
OMAPDSS: hdmi5: Register HDMI audio ASoC drivers from HDMI driver
ASoC: omap: Add Kconfig option for OMAP5 HDMI audio
arch/arm/boot/dts/omap4.dtsi | 2 +
arch/arm/boot/dts/omap5.dtsi | 2 +
arch/arm/mach-omap2/devices.c | 28 ---------
drivers/video/fbdev/omap2/dss/Makefile | 2 +-
drivers/video/fbdev/omap2/dss/hdmi.h | 17 ++++-
drivers/video/fbdev/omap2/dss/hdmi4.c | 15 +++++
drivers/video/fbdev/omap2/dss/hdmi5.c | 15 +++++
drivers/video/fbdev/omap2/dss/hdmi_audio.c | 92 ++++++++++++++++++++++++++++
drivers/video/fbdev/omap2/dss/hdmi_wp.c | 6 ++
include/sound/omap-hdmi-card-pdata.h | 28 +++++++++
include/sound/omap-hdmi-dai-pdata.h | 31 ++++++++++
sound/soc/omap/Kconfig | 13 +++-
sound/soc/omap/omap-hdmi-card.c | 20 ++++--
sound/soc/omap/omap-hdmi.c | 65 +++++---------------
14 files changed, 253 insertions(+), 83 deletions(-)
create mode 100644 drivers/video/fbdev/omap2/dss/hdmi_audio.c
create mode 100644 include/sound/omap-hdmi-card-pdata.h
create mode 100644 include/sound/omap-hdmi-dai-pdata.h
--
1.7.9.5
1
13
Re: [alsa-devel] [PATCH] ASoC: fsl: Remove dependencies of boards for SND_SOC_EUKREA_TLV320
by Mark Brown 23 May '14
by Mark Brown 23 May '14
23 May '14
On Fri, May 23, 2014 at 07:19:27PM +0400, Alexander Shiyan wrote:
> Yes, now I see.
> So on my opinion the true method is transform this board (for DT case) is
> to use generic sound card. In this patch , I just try to remove non-existent
> symbol dependencies, so if we have is_machine_xx checks I do not know
> the true way, since cannot test this.
Yes, transitioning to simple-card would be ideal if you can do that. I
guess we can apply this one for now since it doesn't make things any
worse at least.
1
0