aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb
diff options
context:
space:
mode:
authorEldad Zack <eldad@fogrefinery.com>2013-04-03 17:18:54 -0400
committerTakashi Iwai <tiwai@suse.de>2013-04-04 02:30:59 -0400
commit06ffc1ebddbed88662a47646ff6aa6a2b41f0aec (patch)
tree7090ac76f3cb113cc077090375162ab9765a35a5 /sound/usb
parentf6a8bc70f85fdc49c5a3eca687c6018ffee8f050 (diff)
ALSA: usb-audio: UAC2: do clock validity check earlier
Move the check that parse_audio_format_rates_v2() do after receiving the clock source entity ID directly into the find function and add a validation flag to the function. This patch does not introduce any logic flow change. It is provided to allow introducing automatic clock switching easier later. By moving this uac_clock_source_is_valid callsite, 2 additional callsites can be avoided. Signed-off-by: Eldad Zack <eldad@fogrefinery.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb')
-rw-r--r--sound/usb/clock.c34
-rw-r--r--sound/usb/clock.h3
-rw-r--r--sound/usb/format.c2
3 files changed, 21 insertions, 18 deletions
diff --git a/sound/usb/clock.c b/sound/usb/clock.c
index 013b346f045d..0c98f52a1c9c 100644
--- a/sound/usb/clock.c
+++ b/sound/usb/clock.c
@@ -131,7 +131,8 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id)
131} 131}
132 132
133static int __uac_clock_find_source(struct snd_usb_audio *chip, 133static int __uac_clock_find_source(struct snd_usb_audio *chip,
134 int entity_id, unsigned long *visited) 134 int entity_id, unsigned long *visited,
135 bool validate)
135{ 136{
136 struct uac_clock_source_descriptor *source; 137 struct uac_clock_source_descriptor *source;
137 struct uac_clock_selector_descriptor *selector; 138 struct uac_clock_selector_descriptor *selector;
@@ -148,8 +149,15 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
148 149
149 /* first, see if the ID we're looking for is a clock source already */ 150 /* first, see if the ID we're looking for is a clock source already */
150 source = snd_usb_find_clock_source(chip->ctrl_intf, entity_id); 151 source = snd_usb_find_clock_source(chip->ctrl_intf, entity_id);
151 if (source) 152 if (source) {
152 return source->bClockID; 153 entity_id = source->bClockID;
154 if (validate && !uac_clock_source_is_valid(chip, entity_id)) {
155 snd_printk(KERN_ERR "usb-audio:%d: clock source %d is not valid, cannot use\n",
156 chip->dev->devnum, entity_id);
157 return -ENXIO;
158 }
159 return entity_id;
160 }
153 161
154 selector = snd_usb_find_clock_selector(chip->ctrl_intf, entity_id); 162 selector = snd_usb_find_clock_selector(chip->ctrl_intf, entity_id);
155 if (selector) { 163 if (selector) {
@@ -164,7 +172,7 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
164 /* Selector values are one-based */ 172 /* Selector values are one-based */
165 173
166 if (ret > selector->bNrInPins || ret < 1) { 174 if (ret > selector->bNrInPins || ret < 1) {
167 printk(KERN_ERR 175 snd_printk(KERN_ERR
168 "%s(): selector reported illegal value, id %d, ret %d\n", 176 "%s(): selector reported illegal value, id %d, ret %d\n",
169 __func__, selector->bClockID, ret); 177 __func__, selector->bClockID, ret);
170 178
@@ -172,14 +180,14 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
172 } 180 }
173 181
174 return __uac_clock_find_source(chip, selector->baCSourceID[ret-1], 182 return __uac_clock_find_source(chip, selector->baCSourceID[ret-1],
175 visited); 183 visited, validate);
176 } 184 }
177 185
178 /* FIXME: multipliers only act as pass-thru element for now */ 186 /* FIXME: multipliers only act as pass-thru element for now */
179 multiplier = snd_usb_find_clock_multiplier(chip->ctrl_intf, entity_id); 187 multiplier = snd_usb_find_clock_multiplier(chip->ctrl_intf, entity_id);
180 if (multiplier) 188 if (multiplier)
181 return __uac_clock_find_source(chip, multiplier->bCSourceID, 189 return __uac_clock_find_source(chip, multiplier->bCSourceID,
182 visited); 190 visited, validate);
183 191
184 return -EINVAL; 192 return -EINVAL;
185} 193}
@@ -195,11 +203,12 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
195 * 203 *
196 * Returns the clock source UnitID (>=0) on success, or an error. 204 * Returns the clock source UnitID (>=0) on success, or an error.
197 */ 205 */
198int snd_usb_clock_find_source(struct snd_usb_audio *chip, int entity_id) 206int snd_usb_clock_find_source(struct snd_usb_audio *chip, int entity_id,
207 bool validate)
199{ 208{
200 DECLARE_BITMAP(visited, 256); 209 DECLARE_BITMAP(visited, 256);
201 memset(visited, 0, sizeof(visited)); 210 memset(visited, 0, sizeof(visited));
202 return __uac_clock_find_source(chip, entity_id, visited); 211 return __uac_clock_find_source(chip, entity_id, visited, validate);
203} 212}
204 213
205static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface, 214static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
@@ -275,18 +284,11 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
275 struct usb_device *dev = chip->dev; 284 struct usb_device *dev = chip->dev;
276 __le32 data; 285 __le32 data;
277 int err, cur_rate, prev_rate; 286 int err, cur_rate, prev_rate;
278 int clock = snd_usb_clock_find_source(chip, fmt->clock); 287 int clock = snd_usb_clock_find_source(chip, fmt->clock, true);
279 288
280 if (clock < 0) 289 if (clock < 0)
281 return clock; 290 return clock;
282 291
283 if (!uac_clock_source_is_valid(chip, clock)) {
284 /* TODO: should we try to find valid clock setups by ourself? */
285 snd_printk(KERN_ERR "%d:%d:%d: clock source %d is not valid, cannot use\n",
286 dev->devnum, iface, fmt->altsetting, clock);
287 return -ENXIO;
288 }
289
290 prev_rate = get_sample_rate_v2(chip, iface, fmt->altsetting, clock); 292 prev_rate = get_sample_rate_v2(chip, iface, fmt->altsetting, clock);
291 293
292 data = cpu_to_le32(rate); 294 data = cpu_to_le32(rate);
diff --git a/sound/usb/clock.h b/sound/usb/clock.h
index 46630936d31f..d592e4a29856 100644
--- a/sound/usb/clock.h
+++ b/sound/usb/clock.h
@@ -5,6 +5,7 @@ int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,
5 struct usb_host_interface *alts, 5 struct usb_host_interface *alts,
6 struct audioformat *fmt, int rate); 6 struct audioformat *fmt, int rate);
7 7
8int snd_usb_clock_find_source(struct snd_usb_audio *chip, int entity_id); 8int snd_usb_clock_find_source(struct snd_usb_audio *chip, int entity_id,
9 bool validate);
9 10
10#endif /* __USBAUDIO_CLOCK_H */ 11#endif /* __USBAUDIO_CLOCK_H */
diff --git a/sound/usb/format.c b/sound/usb/format.c
index a695cafc0599..20c775170959 100644
--- a/sound/usb/format.c
+++ b/sound/usb/format.c
@@ -280,7 +280,7 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
280 struct usb_device *dev = chip->dev; 280 struct usb_device *dev = chip->dev;
281 unsigned char tmp[2], *data; 281 unsigned char tmp[2], *data;
282 int nr_triplets, data_size, ret = 0; 282 int nr_triplets, data_size, ret = 0;
283 int clock = snd_usb_clock_find_source(chip, fp->clock); 283 int clock = snd_usb_clock_find_source(chip, fp->clock, false);
284 284
285 if (clock < 0) { 285 if (clock < 0) {
286 snd_printk(KERN_ERR "%s(): unable to find clock source (clock %d)\n", 286 snd_printk(KERN_ERR "%s(): unable to find clock source (clock %d)\n",