diff options
| -rw-r--r-- | sound/usb/card.h | 1 | ||||
| -rw-r--r-- | sound/usb/endpoint.c | 15 |
2 files changed, 15 insertions, 1 deletions
diff --git a/sound/usb/card.h b/sound/usb/card.h index 9867ab866857..97acb906acc2 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h | |||
| @@ -92,6 +92,7 @@ struct snd_usb_endpoint { | |||
| 92 | unsigned int curframesize; /* current packet size in frames (for capture) */ | 92 | unsigned int curframesize; /* current packet size in frames (for capture) */ |
| 93 | unsigned int syncmaxsize; /* sync endpoint packet size */ | 93 | unsigned int syncmaxsize; /* sync endpoint packet size */ |
| 94 | unsigned int fill_max:1; /* fill max packet size always */ | 94 | unsigned int fill_max:1; /* fill max packet size always */ |
| 95 | unsigned int udh01_fb_quirk:1; /* corrupted feedback data */ | ||
| 95 | unsigned int datainterval; /* log_2 of data packet interval */ | 96 | unsigned int datainterval; /* log_2 of data packet interval */ |
| 96 | unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */ | 97 | unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */ |
| 97 | unsigned char silence_value; | 98 | unsigned char silence_value; |
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index e70a87e0d9fe..289f582c9130 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c | |||
| @@ -471,6 +471,10 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip, | |||
| 471 | ep->syncinterval = 3; | 471 | ep->syncinterval = 3; |
| 472 | 472 | ||
| 473 | ep->syncmaxsize = le16_to_cpu(get_endpoint(alts, 1)->wMaxPacketSize); | 473 | ep->syncmaxsize = le16_to_cpu(get_endpoint(alts, 1)->wMaxPacketSize); |
| 474 | |||
| 475 | if (chip->usb_id == USB_ID(0x0644, 0x8038) /* TEAC UD-H01 */ && | ||
| 476 | ep->syncmaxsize == 4) | ||
| 477 | ep->udh01_fb_quirk = 1; | ||
| 474 | } | 478 | } |
| 475 | 479 | ||
| 476 | list_add_tail(&ep->list, &chip->ep_list); | 480 | list_add_tail(&ep->list, &chip->ep_list); |
| @@ -1105,7 +1109,16 @@ void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep, | |||
| 1105 | if (f == 0) | 1109 | if (f == 0) |
| 1106 | return; | 1110 | return; |
| 1107 | 1111 | ||
| 1108 | if (unlikely(ep->freqshift == INT_MIN)) { | 1112 | if (unlikely(sender->udh01_fb_quirk)) { |
| 1113 | /* | ||
| 1114 | * The TEAC UD-H01 firmware sometimes changes the feedback value | ||
| 1115 | * by +/- 0x1.0000. | ||
| 1116 | */ | ||
| 1117 | if (f < ep->freqn - 0x8000) | ||
| 1118 | f += 0x10000; | ||
| 1119 | else if (f > ep->freqn + 0x8000) | ||
| 1120 | f -= 0x10000; | ||
| 1121 | } else if (unlikely(ep->freqshift == INT_MIN)) { | ||
| 1109 | /* | 1122 | /* |
| 1110 | * The first time we see a feedback value, determine its format | 1123 | * The first time we see a feedback value, determine its format |
| 1111 | * by shifting it left or right until it matches the nominal | 1124 | * by shifting it left or right until it matches the nominal |
