diff options
author | Takashi Iwai <tiwai@suse.de> | 2016-01-11 05:33:34 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2016-01-29 01:36:10 -0500 |
commit | 79289e24194a9d099bf18f200894832c5760cd83 (patch) | |
tree | 6a686fddaaeae99cdf85f6c2645d92891bceab74 | |
parent | 3ec622f40913ae036f218e5e7e92df9c1f1753d9 (diff) |
ALSA: usb-audio: Refer to chip->usb_id for quirks and MIDI creation
This is a preliminary patch for the later change to allow a better
quirk ID management. In the current USB-audio code, there are a few
places looking at usb_device idVendor and idProduct fields directly
even though we have already a static member in snd_usb_audio.usb_id.
This patch modifies such codes to refer to the latter field.
For achieving this, two slightly intensive changes have been done:
- The snd_usb_audio object is set/reset via dev_getdrv() for the given
USB device; it's needed for minimizing the changes for some existing
quirks that take only usb_device object.
- __snd_usbmidi_create() is introduced to receive the pre-given usb_id
argument. The exported snd_usbmidi_create() is unchanged by calling
this new function internally.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | sound/usb/card.c | 9 | ||||
-rw-r--r-- | sound/usb/midi.c | 15 | ||||
-rw-r--r-- | sound/usb/midi.h | 14 | ||||
-rw-r--r-- | sound/usb/quirks.c | 36 | ||||
-rw-r--r-- | sound/usb/quirks.h | 3 |
5 files changed, 50 insertions, 27 deletions
diff --git a/sound/usb/card.c b/sound/usb/card.c index 1f09d9591276..2c0269014b85 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c | |||
@@ -171,8 +171,9 @@ static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int int | |||
171 | if ((altsd->bInterfaceClass == USB_CLASS_AUDIO || | 171 | if ((altsd->bInterfaceClass == USB_CLASS_AUDIO || |
172 | altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) && | 172 | altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) && |
173 | altsd->bInterfaceSubClass == USB_SUBCLASS_MIDISTREAMING) { | 173 | altsd->bInterfaceSubClass == USB_SUBCLASS_MIDISTREAMING) { |
174 | int err = snd_usbmidi_create(chip->card, iface, | 174 | int err = __snd_usbmidi_create(chip->card, iface, |
175 | &chip->midi_list, NULL); | 175 | &chip->midi_list, NULL, |
176 | chip->usb_id); | ||
176 | if (err < 0) { | 177 | if (err < 0) { |
177 | dev_err(&dev->dev, | 178 | dev_err(&dev->dev, |
178 | "%u:%d: cannot create sequencer device\n", | 179 | "%u:%d: cannot create sequencer device\n", |
@@ -311,6 +312,7 @@ static int snd_usb_audio_free(struct snd_usb_audio *chip) | |||
311 | snd_usb_endpoint_free(ep); | 312 | snd_usb_endpoint_free(ep); |
312 | 313 | ||
313 | mutex_destroy(&chip->mutex); | 314 | mutex_destroy(&chip->mutex); |
315 | dev_set_drvdata(&chip->dev->dev, NULL); | ||
314 | kfree(chip); | 316 | kfree(chip); |
315 | return 0; | 317 | return 0; |
316 | } | 318 | } |
@@ -484,7 +486,7 @@ static int usb_audio_probe(struct usb_interface *intf, | |||
484 | if (quirk && quirk->ifnum >= 0 && ifnum != quirk->ifnum) | 486 | if (quirk && quirk->ifnum >= 0 && ifnum != quirk->ifnum) |
485 | return -ENXIO; | 487 | return -ENXIO; |
486 | 488 | ||
487 | err = snd_usb_apply_boot_quirk(dev, intf, quirk); | 489 | err = snd_usb_apply_boot_quirk(dev, intf, quirk, id); |
488 | if (err < 0) | 490 | if (err < 0) |
489 | return err; | 491 | return err; |
490 | 492 | ||
@@ -503,6 +505,7 @@ static int usb_audio_probe(struct usb_interface *intf, | |||
503 | goto __error; | 505 | goto __error; |
504 | } | 506 | } |
505 | chip = usb_chip[i]; | 507 | chip = usb_chip[i]; |
508 | dev_set_drvdata(&dev->dev, chip); | ||
506 | atomic_inc(&chip->active); /* avoid autopm */ | 509 | atomic_inc(&chip->active); /* avoid autopm */ |
507 | break; | 510 | break; |
508 | } | 511 | } |
diff --git a/sound/usb/midi.c b/sound/usb/midi.c index cc39f63299ef..b79875ebec1e 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c | |||
@@ -2320,10 +2320,11 @@ EXPORT_SYMBOL(snd_usbmidi_resume); | |||
2320 | /* | 2320 | /* |
2321 | * Creates and registers everything needed for a MIDI streaming interface. | 2321 | * Creates and registers everything needed for a MIDI streaming interface. |
2322 | */ | 2322 | */ |
2323 | int snd_usbmidi_create(struct snd_card *card, | 2323 | int __snd_usbmidi_create(struct snd_card *card, |
2324 | struct usb_interface *iface, | 2324 | struct usb_interface *iface, |
2325 | struct list_head *midi_list, | 2325 | struct list_head *midi_list, |
2326 | const struct snd_usb_audio_quirk *quirk) | 2326 | const struct snd_usb_audio_quirk *quirk, |
2327 | unsigned int usb_id) | ||
2327 | { | 2328 | { |
2328 | struct snd_usb_midi *umidi; | 2329 | struct snd_usb_midi *umidi; |
2329 | struct snd_usb_midi_endpoint_info endpoints[MIDI_MAX_ENDPOINTS]; | 2330 | struct snd_usb_midi_endpoint_info endpoints[MIDI_MAX_ENDPOINTS]; |
@@ -2341,8 +2342,10 @@ int snd_usbmidi_create(struct snd_card *card, | |||
2341 | spin_lock_init(&umidi->disc_lock); | 2342 | spin_lock_init(&umidi->disc_lock); |
2342 | init_rwsem(&umidi->disc_rwsem); | 2343 | init_rwsem(&umidi->disc_rwsem); |
2343 | mutex_init(&umidi->mutex); | 2344 | mutex_init(&umidi->mutex); |
2344 | umidi->usb_id = USB_ID(le16_to_cpu(umidi->dev->descriptor.idVendor), | 2345 | if (!usb_id) |
2346 | usb_id = USB_ID(le16_to_cpu(umidi->dev->descriptor.idVendor), | ||
2345 | le16_to_cpu(umidi->dev->descriptor.idProduct)); | 2347 | le16_to_cpu(umidi->dev->descriptor.idProduct)); |
2348 | umidi->usb_id = usb_id; | ||
2346 | setup_timer(&umidi->error_timer, snd_usbmidi_error_timer, | 2349 | setup_timer(&umidi->error_timer, snd_usbmidi_error_timer, |
2347 | (unsigned long)umidi); | 2350 | (unsigned long)umidi); |
2348 | 2351 | ||
@@ -2464,4 +2467,4 @@ int snd_usbmidi_create(struct snd_card *card, | |||
2464 | list_add_tail(&umidi->list, midi_list); | 2467 | list_add_tail(&umidi->list, midi_list); |
2465 | return 0; | 2468 | return 0; |
2466 | } | 2469 | } |
2467 | EXPORT_SYMBOL(snd_usbmidi_create); | 2470 | EXPORT_SYMBOL(__snd_usbmidi_create); |
diff --git a/sound/usb/midi.h b/sound/usb/midi.h index ad8a3211f8e7..5e25a3fd6c1d 100644 --- a/sound/usb/midi.h +++ b/sound/usb/midi.h | |||
@@ -39,10 +39,20 @@ struct snd_usb_midi_endpoint_info { | |||
39 | 39 | ||
40 | /* for QUIRK_MIDI_AKAI, data is NULL */ | 40 | /* for QUIRK_MIDI_AKAI, data is NULL */ |
41 | 41 | ||
42 | int snd_usbmidi_create(struct snd_card *card, | 42 | int __snd_usbmidi_create(struct snd_card *card, |
43 | struct usb_interface *iface, | ||
44 | struct list_head *midi_list, | ||
45 | const struct snd_usb_audio_quirk *quirk, | ||
46 | unsigned int usb_id); | ||
47 | |||
48 | static inline int snd_usbmidi_create(struct snd_card *card, | ||
43 | struct usb_interface *iface, | 49 | struct usb_interface *iface, |
44 | struct list_head *midi_list, | 50 | struct list_head *midi_list, |
45 | const struct snd_usb_audio_quirk *quirk); | 51 | const struct snd_usb_audio_quirk *quirk) |
52 | { | ||
53 | return __snd_usbmidi_create(card, iface, midi_list, quirk, 0); | ||
54 | } | ||
55 | |||
46 | void snd_usbmidi_input_stop(struct list_head *p); | 56 | void snd_usbmidi_input_stop(struct list_head *p); |
47 | void snd_usbmidi_input_start(struct list_head *p); | 57 | void snd_usbmidi_input_start(struct list_head *p); |
48 | void snd_usbmidi_disconnect(struct list_head *p); | 58 | void snd_usbmidi_disconnect(struct list_head *p); |
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index a75d9ce7d77a..16364d94f17b 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c | |||
@@ -446,8 +446,9 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip, | |||
446 | const struct snd_usb_audio_quirk *quirk = | 446 | const struct snd_usb_audio_quirk *quirk = |
447 | chip->usb_id == USB_ID(0x0582, 0x002b) | 447 | chip->usb_id == USB_ID(0x0582, 0x002b) |
448 | ? &ua700_quirk : &uaxx_quirk; | 448 | ? &ua700_quirk : &uaxx_quirk; |
449 | return snd_usbmidi_create(chip->card, iface, | 449 | return __snd_usbmidi_create(chip->card, iface, |
450 | &chip->midi_list, quirk); | 450 | &chip->midi_list, quirk, |
451 | chip->usb_id); | ||
451 | } | 452 | } |
452 | 453 | ||
453 | if (altsd->bNumEndpoints != 1) | 454 | if (altsd->bNumEndpoints != 1) |
@@ -974,11 +975,9 @@ int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip, | |||
974 | 975 | ||
975 | int snd_usb_apply_boot_quirk(struct usb_device *dev, | 976 | int snd_usb_apply_boot_quirk(struct usb_device *dev, |
976 | struct usb_interface *intf, | 977 | struct usb_interface *intf, |
977 | const struct snd_usb_audio_quirk *quirk) | 978 | const struct snd_usb_audio_quirk *quirk, |
979 | unsigned int id) | ||
978 | { | 980 | { |
979 | u32 id = USB_ID(le16_to_cpu(dev->descriptor.idVendor), | ||
980 | le16_to_cpu(dev->descriptor.idProduct)); | ||
981 | |||
982 | switch (id) { | 981 | switch (id) { |
983 | case USB_ID(0x041e, 0x3000): | 982 | case USB_ID(0x041e, 0x3000): |
984 | /* SB Extigy needs special boot-up sequence */ | 983 | /* SB Extigy needs special boot-up sequence */ |
@@ -1182,7 +1181,7 @@ void snd_usb_endpoint_start_quirk(struct snd_usb_endpoint *ep) | |||
1182 | * "Playback Design" products send bogus feedback data at the start | 1181 | * "Playback Design" products send bogus feedback data at the start |
1183 | * of the stream. Ignore them. | 1182 | * of the stream. Ignore them. |
1184 | */ | 1183 | */ |
1185 | if ((le16_to_cpu(ep->chip->dev->descriptor.idVendor) == 0x23ba) && | 1184 | if (USB_ID_VENDOR(ep->chip->usb_id) == 0x23ba && |
1186 | ep->type == SND_USB_ENDPOINT_TYPE_SYNC) | 1185 | ep->type == SND_USB_ENDPOINT_TYPE_SYNC) |
1187 | ep->skip_packets = 4; | 1186 | ep->skip_packets = 4; |
1188 | 1187 | ||
@@ -1201,11 +1200,15 @@ void snd_usb_endpoint_start_quirk(struct snd_usb_endpoint *ep) | |||
1201 | 1200 | ||
1202 | void snd_usb_set_interface_quirk(struct usb_device *dev) | 1201 | void snd_usb_set_interface_quirk(struct usb_device *dev) |
1203 | { | 1202 | { |
1203 | struct snd_usb_audio *chip = dev_get_drvdata(&dev->dev); | ||
1204 | |||
1205 | if (!chip) | ||
1206 | return; | ||
1204 | /* | 1207 | /* |
1205 | * "Playback Design" products need a 50ms delay after setting the | 1208 | * "Playback Design" products need a 50ms delay after setting the |
1206 | * USB interface. | 1209 | * USB interface. |
1207 | */ | 1210 | */ |
1208 | switch (le16_to_cpu(dev->descriptor.idVendor)) { | 1211 | switch (USB_ID_VENDOR(chip->usb_id)) { |
1209 | case 0x23ba: /* Playback Design */ | 1212 | case 0x23ba: /* Playback Design */ |
1210 | case 0x0644: /* TEAC Corp. */ | 1213 | case 0x0644: /* TEAC Corp. */ |
1211 | mdelay(50); | 1214 | mdelay(50); |
@@ -1213,15 +1216,20 @@ void snd_usb_set_interface_quirk(struct usb_device *dev) | |||
1213 | } | 1216 | } |
1214 | } | 1217 | } |
1215 | 1218 | ||
1219 | /* quirk applied after snd_usb_ctl_msg(); not applied during boot quirks */ | ||
1216 | void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe, | 1220 | void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe, |
1217 | __u8 request, __u8 requesttype, __u16 value, | 1221 | __u8 request, __u8 requesttype, __u16 value, |
1218 | __u16 index, void *data, __u16 size) | 1222 | __u16 index, void *data, __u16 size) |
1219 | { | 1223 | { |
1224 | struct snd_usb_audio *chip = dev_get_drvdata(&dev->dev); | ||
1225 | |||
1226 | if (!chip) | ||
1227 | return; | ||
1220 | /* | 1228 | /* |
1221 | * "Playback Design" products need a 20ms delay after each | 1229 | * "Playback Design" products need a 20ms delay after each |
1222 | * class compliant request | 1230 | * class compliant request |
1223 | */ | 1231 | */ |
1224 | if ((le16_to_cpu(dev->descriptor.idVendor) == 0x23ba) && | 1232 | if (USB_ID_VENDOR(chip->usb_id) == 0x23ba && |
1225 | (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) | 1233 | (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) |
1226 | mdelay(20); | 1234 | mdelay(20); |
1227 | 1235 | ||
@@ -1229,23 +1237,21 @@ void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe, | |||
1229 | * "TEAC Corp." products need a 20ms delay after each | 1237 | * "TEAC Corp." products need a 20ms delay after each |
1230 | * class compliant request | 1238 | * class compliant request |
1231 | */ | 1239 | */ |
1232 | if ((le16_to_cpu(dev->descriptor.idVendor) == 0x0644) && | 1240 | if (USB_ID_VENDOR(chip->usb_id) == 0x0644 && |
1233 | (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) | 1241 | (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) |
1234 | mdelay(20); | 1242 | mdelay(20); |
1235 | 1243 | ||
1236 | /* Marantz/Denon devices with USB DAC functionality need a delay | 1244 | /* Marantz/Denon devices with USB DAC functionality need a delay |
1237 | * after each class compliant request | 1245 | * after each class compliant request |
1238 | */ | 1246 | */ |
1239 | if (is_marantz_denon_dac(USB_ID(le16_to_cpu(dev->descriptor.idVendor), | 1247 | if (is_marantz_denon_dac(chip->usb_id) |
1240 | le16_to_cpu(dev->descriptor.idProduct))) | ||
1241 | && (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) | 1248 | && (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) |
1242 | mdelay(20); | 1249 | mdelay(20); |
1243 | 1250 | ||
1244 | /* Zoom R16/24 needs a tiny delay here, otherwise requests like | 1251 | /* Zoom R16/24 needs a tiny delay here, otherwise requests like |
1245 | * get/set frequency return as failed despite actually succeeding. | 1252 | * get/set frequency return as failed despite actually succeeding. |
1246 | */ | 1253 | */ |
1247 | if ((le16_to_cpu(dev->descriptor.idVendor) == 0x1686) && | 1254 | if (chip->usb_id == USB_ID(0x1686, 0x00dd) && |
1248 | (le16_to_cpu(dev->descriptor.idProduct) == 0x00dd) && | ||
1249 | (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) | 1255 | (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) |
1250 | mdelay(1); | 1256 | mdelay(1); |
1251 | } | 1257 | } |
@@ -1262,7 +1268,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, | |||
1262 | unsigned int sample_bytes) | 1268 | unsigned int sample_bytes) |
1263 | { | 1269 | { |
1264 | /* Playback Designs */ | 1270 | /* Playback Designs */ |
1265 | if (le16_to_cpu(chip->dev->descriptor.idVendor) == 0x23ba) { | 1271 | if (USB_ID_VENDOR(chip->usb_id) == 0x23ba) { |
1266 | switch (fp->altsetting) { | 1272 | switch (fp->altsetting) { |
1267 | case 1: | 1273 | case 1: |
1268 | fp->dsd_dop = true; | 1274 | fp->dsd_dop = true; |
diff --git a/sound/usb/quirks.h b/sound/usb/quirks.h index 2cd71ed1201f..192ff5ce9452 100644 --- a/sound/usb/quirks.h +++ b/sound/usb/quirks.h | |||
@@ -16,7 +16,8 @@ int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip, | |||
16 | 16 | ||
17 | int snd_usb_apply_boot_quirk(struct usb_device *dev, | 17 | int snd_usb_apply_boot_quirk(struct usb_device *dev, |
18 | struct usb_interface *intf, | 18 | struct usb_interface *intf, |
19 | const struct snd_usb_audio_quirk *quirk); | 19 | const struct snd_usb_audio_quirk *quirk, |
20 | unsigned int usb_id); | ||
20 | 21 | ||
21 | void snd_usb_set_format_quirk(struct snd_usb_substream *subs, | 22 | void snd_usb_set_format_quirk(struct snd_usb_substream *subs, |
22 | struct audioformat *fmt); | 23 | struct audioformat *fmt); |