Add ACCESSORY_SET_AUDIO_MODE control request and ioctl
Mike Lockwood [Fri, 11 May 2012 16:00:40 +0000 (09:00 -0700)]
The control request will be used by the host to enable/disable USB audio
and the ioctl will be used by userspace to read the audio mode

Bug 1026047

Signed-off-by: Mike Lockwood <lockwood@google.com>
(cherry picked from commit 3e1ff6142761eef148c667e540381d1fbc437d4f)

Signed-off-by: Rakesh Bodla <rbodla@nvidia.com>
Change-Id: I5f449de230ca8f44e2dae30a0f87772310b68f20
Reviewed-on: http://git-master/r/123341
Reviewed-by: Venkat Moganty <vmoganty@nvidia.com>

drivers/usb/gadget/f_accessory.c
include/linux/usb/f_accessory.h

index 58c653f..bb6bee1 100644 (file)
@@ -40,7 +40,7 @@
 #define BULK_BUFFER_SIZE    16384
 #define ACC_STRING_SIZE     256
 
-#define PROTOCOL_VERSION    1
+#define PROTOCOL_VERSION    2
 
 /* String IDs */
 #define INTERFACE_STRING_INDEX 0
@@ -78,6 +78,8 @@ struct acc_dev {
        /* set to 1 if we have a pending start request */
        int start_requested;
 
+       int audio_mode;
+
        /* synchronize access to our device file */
        atomic_t open_excl;
 
@@ -510,6 +512,8 @@ static long acc_ioctl(struct file *fp, unsigned code, unsigned long value)
                break;
        case ACCESSORY_IS_START_REQUESTED:
                return dev->start_requested;
+       case ACCESSORY_GET_AUDIO_MODE:
+               return dev->audio_mode;
        }
        if (!src)
                return -EINVAL;
@@ -586,6 +590,10 @@ static int acc_ctrlrequest(struct usb_composite_dev *cdev,
                        cdev->gadget->ep0->driver_data = dev;
                        cdev->req->complete = acc_complete_set_string;
                        value = w_length;
+               } else if (b_request == ACCESSORY_SET_AUDIO_MODE &&
+                               w_index == 0 && w_length == 0) {
+                       dev->audio_mode = w_value;
+                       value = 0;
                }
        } else if (b_requestType == (USB_DIR_IN | USB_TYPE_VENDOR)) {
                if (b_request == ACCESSORY_GET_PROTOCOL) {
@@ -600,6 +608,7 @@ static int acc_ctrlrequest(struct usb_composite_dev *cdev,
                        memset(dev->uri, 0, sizeof(dev->uri));
                        memset(dev->serial, 0, sizeof(dev->serial));
                        dev->start_requested = 0;
+                       dev->audio_mode = 0;
                }
        }
 
index 5b2dcf9..ddb2fd0 100644 (file)
 #define ACCESSORY_STRING_URI            4
 #define ACCESSORY_STRING_SERIAL         5
 
-/* Control request for retrieving device's protocol version (currently 1)
+/* Control request for retrieving device's protocol version
  *
  *     requestType:    USB_DIR_IN | USB_TYPE_VENDOR
  *     request:        ACCESSORY_GET_PROTOCOL
  *     value:          0
  *     index:          0
  *     data            version number (16 bits little endian)
+ *                     1 for original accessory support
+ *                     2 adds device to host audio support
  */
 #define ACCESSORY_GET_PROTOCOL  51
 
  */
 #define ACCESSORY_START         53
 
+/* Control request for setting the audio mode.
+ *
+ *     requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
+ *     request:        ACCESSORY_SET_AUDIO_MODE
+ *     value:          0 - no audio
+ *                     1 - device to host, 44100 16-bit stereo PCM
+ *     index:          0
+ *     data            none
+ */
+#define ACCESSORY_SET_AUDIO_MODE         58
+
 /* ioctls for retrieving strings set by the host */
 #define ACCESSORY_GET_STRING_MANUFACTURER   _IOW('M', 1, char[256])
 #define ACCESSORY_GET_STRING_MODEL          _IOW('M', 2, char[256])
@@ -79,5 +92,7 @@
 #define ACCESSORY_GET_STRING_SERIAL         _IOW('M', 6, char[256])
 /* returns 1 if there is a start request pending */
 #define ACCESSORY_IS_START_REQUESTED        _IO('M', 7)
+/* returns audio mode (set via the ACCESSORY_SET_AUDIO_MODE control request) */
+#define ACCESSORY_GET_AUDIO_MODE            _IO('M', 8)
 
 #endif /* __LINUX_USB_F_ACCESSORY_H */