* Problem using alsa to implement an Android dock [not found] <14938206.164554.1370852219153.JavaMail.root@openwide.fr> @ 2013-06-10 9:03 ` Jeremy Rosen 2013-06-10 12:02 ` Clemens Ladisch 2013-06-11 19:44 ` Clemens Ladisch 0 siblings, 2 replies; 9+ messages in thread From: Jeremy Rosen @ 2013-06-10 9:03 UTC (permalink / raw) To: alsa-devel [-- Attachment #1: Type: text/plain, Size: 1658 bytes --] Hello everybody I am trying to implement an android dock on linux, and there is some cases where alsa seems to not properly recognise the Android phone as a USB sound device... First a little bit of context since Android 4.1 it is possible to put an android phone (connected to a PC via USB) in "dock mode" Basically you send a couple of special USB packet to the phone and the phone will disconnect from the USB bus then reconnect as a USB sound device. You can then use any tool to handle it as an audio source and redirct the sound to your speaker. For those intereset the details can be found at http://source.android.com/tech/accessories/aoap/aoa2.html This works really well, no problem with that... However Android also has something called "accessory mode" which is used to create custom apps that communicate in "raw" mode with the host my problems arrive when both the dock mode and the accessory mode are enabled. in that case Alsa will not recognise the usb sound device exposed by android. It will create an entry for it in /proc/asound but there are no mixer or input stream I attach the output of lsusb -v in both cases and a small C program that I use to put the phone in the proper modes (there is a small section of code to (un)comment to en/disable accessory mode, it uses libusb for usb access and should be trivial to compile with it) At this point I am not sure how to proceed, is this a real bug or something not implemented ? what extra info do I need to provide ? any help would be welcome Regards Jérémy Rosen fight key loggers : write some perl using vim [-- Attachment #2: audio_accessory.txt --] [-- Type: text/plain, Size: 5845 bytes --] Bus 002 Device 010: ID 18d1:2d04 Google Inc. Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x18d1 Google Inc. idProduct 0x2d04 bcdDevice 2.28 iManufacturer 1 iProduct 2 iSerial 3 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 133 bNumInterfaces 3 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 500mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 255 Vendor Specific Subclass bInterfaceProtocol 0 iInterface 5 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 0 bNumEndpoints 0 bInterfaceClass 1 Audio bInterfaceSubClass 1 Control Device bInterfaceProtocol 0 iInterface 0 AudioControl Interface Descriptor: bLength 10 bDescriptorType 36 bDescriptorSubtype 1 (HEADER) bcdADC 1.00 wTotalLength 40 bInCollection 2 baInterfaceNr( 0) 0 baInterfaceNr( 1) 1 AudioControl Interface Descriptor: bLength 12 bDescriptorType 36 bDescriptorSubtype 2 (INPUT_TERMINAL) bTerminalID 1 wTerminalType 0x0201 Microphone bAssocTerminal 0 bNrChannels 2 wChannelConfig 0x0003 Left Front (L) Right Front (R) iChannelNames 0 iTerminal 0 AudioControl Interface Descriptor: bLength 9 bDescriptorType 36 bDescriptorSubtype 3 (OUTPUT_TERMINAL) bTerminalID 3 wTerminalType 0x0101 USB Streaming bAssocTerminal 2 bSourceID 2 iTerminal 0 AudioControl Interface Descriptor: bLength 9 bDescriptorType 36 bDescriptorSubtype 6 (FEATURE_UNIT) bUnitID 2 bSourceID 1 bControlSize 2 bmaControls( 0) 0x00 bmaControls( 0) 0x00 iFeature 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 0 bNumEndpoints 0 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 1 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 AudioStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 1 bDelay 1 frames wFormatTag 1 PCM AudioStreaming Interface Descriptor: bLength 11 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bNrChannels 2 bSubframeSize 2 bBitResolution 16 bSamFreqType 1 Discrete tSamFreq[ 0] 44100 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x83 EP 3 IN bmAttributes 13 Transfer Type Isochronous Synch Type Synchronous Usage Type Data wMaxPacketSize 0x0100 1x 256 bytes bInterval 4 bRefresh 0 bSynchAddress 0 AudioControl Endpoint Descriptor: bLength 7 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x01 Sampling Frequency bLockDelayUnits 1 Milliseconds wLockDelay 1 Milliseconds [-- Attachment #3: audio_only.txt --] [-- Type: text/plain, Size: 5099 bytes --] Bus 002 Device 008: ID 18d1:2d02 Google Inc. Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x18d1 Google Inc. idProduct 0x2d02 bcdDevice 2.28 iManufacturer 1 LGE iProduct 2 Nexus 4 iSerial 3 0076aa569a181282 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 110 bNumInterfaces 2 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 500mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 0 bInterfaceClass 1 Audio bInterfaceSubClass 1 Control Device bInterfaceProtocol 0 iInterface 0 AudioControl Interface Descriptor: bLength 10 bDescriptorType 36 bDescriptorSubtype 1 (HEADER) bcdADC 1.00 wTotalLength 40 bInCollection 2 baInterfaceNr( 0) 0 baInterfaceNr( 1) 1 AudioControl Interface Descriptor: bLength 12 bDescriptorType 36 bDescriptorSubtype 2 (INPUT_TERMINAL) bTerminalID 1 wTerminalType 0x0201 Microphone bAssocTerminal 0 bNrChannels 2 wChannelConfig 0x0003 Left Front (L) Right Front (R) iChannelNames 0 iTerminal 0 AudioControl Interface Descriptor: bLength 9 bDescriptorType 36 bDescriptorSubtype 3 (OUTPUT_TERMINAL) bTerminalID 3 wTerminalType 0x0101 USB Streaming bAssocTerminal 2 bSourceID 2 iTerminal 0 AudioControl Interface Descriptor: bLength 9 bDescriptorType 36 bDescriptorSubtype 6 (FEATURE_UNIT) bUnitID 2 bSourceID 1 bControlSize 2 bmaControls( 0) 0x00 bmaControls( 0) 0x00 iFeature 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 0 bNumEndpoints 0 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 1 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 AudioStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 1 bDelay 1 frames wFormatTag 1 PCM AudioStreaming Interface Descriptor: bLength 11 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bNrChannels 2 bSubframeSize 2 bBitResolution 16 bSamFreqType 1 Discrete tSamFreq[ 0] 44100 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 13 Transfer Type Isochronous Synch Type Synchronous Usage Type Data wMaxPacketSize 0x0100 1x 256 bytes bInterval 4 bRefresh 0 bSynchAddress 0 AudioControl Endpoint Descriptor: bLength 7 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x01 Sampling Frequency bLockDelayUnits 1 Milliseconds wLockDelay 1 Milliseconds Device Qualifier (for other device speed): bLength 10 bDescriptorType 6 bcdUSB 2.00 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 bNumConfigurations 1 Device Status: 0x0000 (Bus Powered) [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #4: usbAccConfig.c --] [-- Type: text/x-csrc; name=usbAccConfig.c, Size: 4818 bytes --] /* usbAccConfig.c copyright (c) 2013 Jeremy Rosen <jeremy.rosen@openwide.fr> usbAccConfig is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. usbAccConfig is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with usbAccConfig. If not, see <http://www.gnu.org/licenses/>. if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <stdio.h> #include <usb.h> #include <libusb.h> #include <string.h> #include <unistd.h> // VID and PID of phones in Android accessory mode #define GOOGLE_VID 0x18d1 #define ACCESSORY_PID_BASE 0x2D00 // Parameters passed to Android to recognise the device #define MANUFACTURER "Openwide" #define MODEL "TestUsbAccessory" #define DESCRIPTION "A simple program to test the accessory mode of Android phones" #define VERSION "1.0" #define URI "http://linuxembedded.fr" #define SERIAL "N/A" // Capabilities detected on the Android device #define CAPABILITY_ACC 1<<0 #define CAPABILITY_ADB 1<<1 #define CAPABILITY_AUDIO 1<<2 typedef struct { int vid; int pid; } usb_identifier; usb_identifier skipped_id[] = { // hardwired : list of embedded peripherals of the raspberry-pi {0x0424,0x9512}, {0x1d6b,0x0002}, {0x0424,0xec00}, {GOOGLE_VID,ACCESSORY_PID_BASE}, {GOOGLE_VID,ACCESSORY_PID_BASE + 1}, {GOOGLE_VID,ACCESSORY_PID_BASE + 2}, {GOOGLE_VID,ACCESSORY_PID_BASE + 3}, {GOOGLE_VID,ACCESSORY_PID_BASE + 4}, {GOOGLE_VID,ACCESSORY_PID_BASE + 5}, {0,0} }; static int pollDevice(int vid, int pid); int main (int argc, char *argv[]){ libusb_init(NULL); if(argc < 3) { printf("no device vid pid on command line\n"); return 0; } else { int vid = strtol(argv[1],NULL,0); int pid = strtol(argv[2],NULL,0); usb_identifier *id = skipped_id; while(id->pid || id->vid) { if(vid == id->vid && pid == id->pid) { printf("device skipped"); return 0; } id++; } if(!pollDevice(vid,pid)) { libusb_exit(NULL); printf("Given device isn't an android device\n"); return 0; } } printf( "Done, no errors. Device should reappear as an android accessory\n"); libusb_exit(NULL); return 0; } // sends the correct sequence to check if it is an android device // if it is, puts the device in accessory mode and return 1 // if it isn't, return 0 static int pollDevice(int vid, int pid) { unsigned char ioBuffer[2]; int devVersion; int response=0; struct libusb_device_handle* handle; if((handle = libusb_open_device_with_vid_pid(NULL, vid, pid)) == NULL) goto error; // poll protocol : is this an android device ? response = libusb_control_transfer( handle, 0xC0, 51, 0, 0, ioBuffer, 2, 0); if(response < 0) goto error; devVersion = ioBuffer[1] << 8 | ioBuffer[0]; printf("Version Code Device: %d\n", devVersion); if(devVersion == 0) { // not an android device goto error; } usleep(1000);//sometimes hangs on the next transfer :( /**** Comment the following block to disable Accessory mode ******/ #if 0 response = libusb_control_transfer(handle,0x40,52,0,0,(unsigned char*)MANUFACTURER,strlen(MANUFACTURER)+1,0); if(response < 0) goto error; response = libusb_control_transfer(handle,0x40,52,0,1,(unsigned char*)MODEL,strlen(MODEL)+1,0); if(response < 0) goto error; response = libusb_control_transfer(handle,0x40,52,0,2,(unsigned char*)DESCRIPTION,strlen(DESCRIPTION)+1,0); if(response < 0) goto error; response = libusb_control_transfer(handle,0x40,52,0,3,(unsigned char*)VERSION,strlen(VERSION)+1,0); if(response < 0) goto error; response = libusb_control_transfer(handle,0x40,52,0,4,(unsigned char*)URI,strlen(URI)+1,0); if(response < 0) goto error; response = libusb_control_transfer(handle,0x40,52,0,5,(unsigned char*)SERIAL,strlen(SERIAL)+1,0); if(response < 0) goto error; #endif /***** Comment the following block to disable audio accessory mode ***/ #if 1 if(devVersion >= 2) { printf("Sending Audio mode request\n"); response = libusb_control_transfer(handle,0x40,58,1,0,NULL,0,0); if(response < 0) goto error; } #endif /**** fin de la section à supprimer ****/ printf("Sending Accessory Identification \n"); response = libusb_control_transfer(handle,0x40,53,0,0,NULL,0,0); if(response < 0) goto error; libusb_close(handle); return 1; error: if(response) printf("USB error : %s\n",libusb_error_name(response)); libusb_close(handle); return 0; } [-- Attachment #5: Type: text/plain, Size: 0 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Problem using alsa to implement an Android dock 2013-06-10 9:03 ` Problem using alsa to implement an Android dock Jeremy Rosen @ 2013-06-10 12:02 ` Clemens Ladisch 2013-06-10 12:37 ` Jeremy Rosen 2013-06-11 19:44 ` Clemens Ladisch 1 sibling, 1 reply; 9+ messages in thread From: Clemens Ladisch @ 2013-06-10 12:02 UTC (permalink / raw) To: Jeremy Rosen; +Cc: alsa-devel Jeremy Rosen wrote: > my problems arrive when both the dock mode and the accessory mode are > enabled. in that case Alsa will not recognise the usb sound device exposed > by android. > bInterfaceNumber 1 > bInterfaceSubClass Control Device > AudioControl Interface Descriptor: > baInterfaceNr 0 > baInterfaceNr 1 > bInterfaceNumber 2 > bInterfaceSubClass Streaming This is a bug in the Android firmware: it says that the audio driver should look at interfaces 0 and 1, but the actual audio interfaces are 1 and 2. I'll look into this ... Regards, Clemens ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Problem using alsa to implement an Android dock 2013-06-10 12:02 ` Clemens Ladisch @ 2013-06-10 12:37 ` Jeremy Rosen 0 siblings, 0 replies; 9+ messages in thread From: Jeremy Rosen @ 2013-06-10 12:37 UTC (permalink / raw) To: Clemens Ladisch; +Cc: alsa-devel > > This is a bug in the Android firmware: it says that the audio driver > should look at interfaces 0 and 1, but the actual audio interfaces > are > 1 and 2. > > I'll look into this ... > hmmm interesting, i'll wait for you to investigate what you want to investigate and then i'll look into how to open a bug report on the android side... I have to admit my knowledge is not sufficiant to diagnose that sort of problems myself, thx for the help ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Problem using alsa to implement an Android dock 2013-06-10 9:03 ` Problem using alsa to implement an Android dock Jeremy Rosen 2013-06-10 12:02 ` Clemens Ladisch @ 2013-06-11 19:44 ` Clemens Ladisch 2013-06-12 15:16 ` Jeremy Rosen 1 sibling, 1 reply; 9+ messages in thread From: Clemens Ladisch @ 2013-06-11 19:44 UTC (permalink / raw) To: Jeremy Rosen; +Cc: alsa-devel Please try this patch: ALSA: usb-audio: work around Anroid accessory firmware bug When the Android firmware enables the audio interfaces in accessory mode, it always declares in the control interface's baInterfaceNr array that interfaces 0 and 1 belong to the audio function. However, the accessory interface itself, if also enabled, already is at index 0 and shifts the actual audio interface numbers to 1 and 2, which prevents the PCM streaming interface from being seen by the host driver. To get the PCM interface interface to work, detect when the descriptors point to the (for this driver useless) accessory interface, and redirect to the correct one. Reported-by: Jeremy Rosen <jeremy.rosen@openwide.fr> Not-yet-tested-by: Jeremy Rosen <jeremy.rosen@openwide.fr> Cc: <stable@vger.kernel.org> Signed-off-by: Clemens Ladisch <clemens@ladisch.de> --- sound/usb/card.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/sound/usb/card.c b/sound/usb/card.c index 563854a..f7a38ec 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -148,14 +148,31 @@ static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int int return -EINVAL; } + alts = &iface->altsetting[0]; + altsd = get_iface_desc(alts); + + /* + * Android with both accessory and audio interfaces enabled gets the + * interface numbers wrong. + */ + if ((chip->usb_id == USB_ID(0x18d1, 0x2d04) || + chip->usb_id == USB_ID(0x18d1, 0x2d05)) && + interface == 0 && + altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC && + altsd->bInterfaceSubClass == USB_SUBCLASS_VENDOR_SPEC) { + iface = usb_ifnum_to_if(dev, 2); + if (!iface) + return -EINVAL; + alts = &iface->altsetting[0]; + altsd = get_iface_desc(alts); + } + if (usb_interface_claimed(iface)) { snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n", dev->devnum, ctrlif, interface); return -EINVAL; } - alts = &iface->altsetting[0]; - altsd = get_iface_desc(alts); if ((altsd->bInterfaceClass == USB_CLASS_AUDIO || altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) && altsd->bInterfaceSubClass == USB_SUBCLASS_MIDISTREAMING) { ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: Problem using alsa to implement an Android dock 2013-06-11 19:44 ` Clemens Ladisch @ 2013-06-12 15:16 ` Jeremy Rosen 2013-06-12 15:30 ` Clemens Ladisch 2013-06-12 20:08 ` Clemens Ladisch 0 siblings, 2 replies; 9+ messages in thread From: Jeremy Rosen @ 2013-06-12 15:16 UTC (permalink / raw) To: Clemens Ladisch; +Cc: alsa-devel Ok I tested on my raspberry card (the card where I can easily test it) and it didn't seem to work I did some printk around and I do go correctly into the added code, but it doesn't seem to change anything the card still has no control according to amixer... I used a raspberry-pi kernel from https://github.com/raspberrypi/linux (branch rpi_3.9.y) the port didn't apply correctly there but I managed to get it in I'm quite new to this stuff. I am pretty sure I tested correctly, but appology if I didn't... any hint on what I can do to help is welcome at this point Cordialement Jérémy Rosen fight key loggers : write some perl using vim _______________________________________________ Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Problem using alsa to implement an Android dock 2013-06-12 15:16 ` Jeremy Rosen @ 2013-06-12 15:30 ` Clemens Ladisch 2013-06-12 15:43 ` Jeremy Rosen 2013-06-12 20:08 ` Clemens Ladisch 1 sibling, 1 reply; 9+ messages in thread From: Clemens Ladisch @ 2013-06-12 15:30 UTC (permalink / raw) To: Jeremy Rosen; +Cc: alsa-devel Jeremy Rosen wrote: > Ok I tested on my raspberry card (the card where I can easily test it) and it didn't seem to work > > the card still has no control according to amixer... Why should there be a mixer control? Does the PCM device exist now? Regards, Clemens ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Problem using alsa to implement an Android dock 2013-06-12 15:30 ` Clemens Ladisch @ 2013-06-12 15:43 ` Jeremy Rosen 0 siblings, 0 replies; 9+ messages in thread From: Jeremy Rosen @ 2013-06-12 15:43 UTC (permalink / raw) To: Clemens Ladisch; +Cc: alsa-devel ok, bad success criteria, I'm a bit walking blind here... however it is not working ls /proc/asound/N4 in audio only mode give # ls /proc/asound/N4/ id pcm0c stream0 usbbus usbid usbmixer and in audio+acc mode # ls /proc/asound/N4/ id usbbus usbid usbmixer is there anything else I can do to help ? Cordialement Jérémy Rosen fight key loggers : write some perl using vim ----- Mail original ----- > Jeremy Rosen wrote: > > Ok I tested on my raspberry card (the card where I can easily test > > it) and it didn't seem to work > > > > the card still has no control according to amixer... > > Why should there be a mixer control? > > Does the PCM device exist now? > > > Regards, > Clemens > _______________________________________________ Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Problem using alsa to implement an Android dock 2013-06-12 15:16 ` Jeremy Rosen 2013-06-12 15:30 ` Clemens Ladisch @ 2013-06-12 20:08 ` Clemens Ladisch 2013-06-13 8:24 ` Jeremy Rosen 1 sibling, 1 reply; 9+ messages in thread From: Clemens Ladisch @ 2013-06-12 20:08 UTC (permalink / raw) To: Jeremy Rosen; +Cc: alsa-devel Jeremy Rosen wrote: > it didn't seem to work Because the important code uses 'interface', not 'iface'. Try this one: ALSA: usb-audio: work around Anroid accessory firmware bug When the Android firmware enables the audio interfaces in accessory mode, it always declares in the control interface's baInterfaceNr array that interfaces 0 and 1 belong to the audio function. However, the accessory interface itself, if also enabled, already is at index 0 and shifts the actual audio interface numbers to 1 and 2, which prevents the PCM streaming interface from being seen by the host driver. To get the PCM interface interface to work, detect when the descriptors point to the (for this driver useless) accessory interface, and redirect to the correct one. Reported-by: Jeremy Rosen <jeremy.rosen@openwide.fr> Not-yet-tested-by: Jeremy Rosen <jeremy.rosen@openwide.fr> Cc: <stable@vger.kernel.org> Signed-off-by: Clemens Ladisch <clemens@ladisch.de> --- sound/usb/card.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/sound/usb/card.c b/sound/usb/card.c index 563854a..5a5153c 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -148,14 +148,32 @@ static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int int return -EINVAL; } + alts = &iface->altsetting[0]; + altsd = get_iface_desc(alts); + + /* + * Android with both accessory and audio interfaces enabled gets the + * interface numbers wrong. + */ + if ((chip->usb_id == USB_ID(0x18d1, 0x2d04) || + chip->usb_id == USB_ID(0x18d1, 0x2d05)) && + interface == 0 && + altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC && + altsd->bInterfaceSubClass == USB_SUBCLASS_VENDOR_SPEC) { + interface = 2; + iface = usb_ifnum_to_if(dev, interface); + if (!iface) + return -EINVAL; + alts = &iface->altsetting[0]; + altsd = get_iface_desc(alts); + } + if (usb_interface_claimed(iface)) { snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n", dev->devnum, ctrlif, interface); return -EINVAL; } - alts = &iface->altsetting[0]; - altsd = get_iface_desc(alts); if ((altsd->bInterfaceClass == USB_CLASS_AUDIO || altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) && altsd->bInterfaceSubClass == USB_SUBCLASS_MIDISTREAMING) { ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: Problem using alsa to implement an Android dock 2013-06-12 20:08 ` Clemens Ladisch @ 2013-06-13 8:24 ` Jeremy Rosen 0 siblings, 0 replies; 9+ messages in thread From: Jeremy Rosen @ 2013-06-13 8:24 UTC (permalink / raw) To: Clemens Ladisch; +Cc: alsa-devel Awesome, this works perfectly, thx a lot tested-by: Jeremy Rosen <jeremy.rosen@openwide.fr> Is there anything I need to do for the upstreaming ? I will still open a bug on the android side, though... Cordialement Jérémy Rosen fight key loggers : write some perl using vim ----- Mail original ----- > Jeremy Rosen wrote: > > it didn't seem to work > > Because the important code uses 'interface', not 'iface'. > Try this one: > > > ALSA: usb-audio: work around Anroid accessory firmware bug > > When the Android firmware enables the audio interfaces in accessory > mode, it always declares in the control interface's baInterfaceNr > array > that interfaces 0 and 1 belong to the audio function. However, the > accessory interface itself, if also enabled, already is at index 0 > and > shifts the actual audio interface numbers to 1 and 2, which prevents > the > PCM streaming interface from being seen by the host driver. > > To get the PCM interface interface to work, detect when the > descriptors > point to the (for this driver useless) accessory interface, and > redirect > to the correct one. > > Reported-by: Jeremy Rosen <jeremy.rosen@openwide.fr> > Not-yet-tested-by: Jeremy Rosen <jeremy.rosen@openwide.fr> > Cc: <stable@vger.kernel.org> > Signed-off-by: Clemens Ladisch <clemens@ladisch.de> > --- > sound/usb/card.c | 22 ++++++++++++++++++++-- > 1 file changed, 20 insertions(+), 2 deletions(-) > > diff --git a/sound/usb/card.c b/sound/usb/card.c > index 563854a..5a5153c 100644 > --- a/sound/usb/card.c > +++ b/sound/usb/card.c > @@ -148,14 +148,32 @@ static int snd_usb_create_stream(struct > snd_usb_audio *chip, int ctrlif, int int > return -EINVAL; > } > > + alts = &iface->altsetting[0]; > + altsd = get_iface_desc(alts); > + > + /* > + * Android with both accessory and audio interfaces enabled gets > the > + * interface numbers wrong. > + */ > + if ((chip->usb_id == USB_ID(0x18d1, 0x2d04) || > + chip->usb_id == USB_ID(0x18d1, 0x2d05)) && > + interface == 0 && > + altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC && > + altsd->bInterfaceSubClass == USB_SUBCLASS_VENDOR_SPEC) { > + interface = 2; > + iface = usb_ifnum_to_if(dev, interface); > + if (!iface) > + return -EINVAL; > + alts = &iface->altsetting[0]; > + altsd = get_iface_desc(alts); > + } > + > if (usb_interface_claimed(iface)) { > snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n", > dev->devnum, ctrlif, interface); > return -EINVAL; > } > > - alts = &iface->altsetting[0]; > - altsd = get_iface_desc(alts); > if ((altsd->bInterfaceClass == USB_CLASS_AUDIO || > altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) && > altsd->bInterfaceSubClass == USB_SUBCLASS_MIDISTREAMING) { > _______________________________________________ Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2013-06-13 8:24 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <14938206.164554.1370852219153.JavaMail.root@openwide.fr>
2013-06-10 9:03 ` Problem using alsa to implement an Android dock Jeremy Rosen
2013-06-10 12:02 ` Clemens Ladisch
2013-06-10 12:37 ` Jeremy Rosen
2013-06-11 19:44 ` Clemens Ladisch
2013-06-12 15:16 ` Jeremy Rosen
2013-06-12 15:30 ` Clemens Ladisch
2013-06-12 15:43 ` Jeremy Rosen
2013-06-12 20:08 ` Clemens Ladisch
2013-06-13 8:24 ` Jeremy Rosen
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.