Merge "Add WBS support on Bluedroid (4/6)"
diff --git a/include/hardware/bluetooth.h b/include/hardware/bluetooth.h
index c3256ba..a074f4f 100644
--- a/include/hardware/bluetooth.h
+++ b/include/hardware/bluetooth.h
@@ -87,7 +87,8 @@
     BT_STATUS_PARM_INVALID,
     BT_STATUS_UNHANDLED,
     BT_STATUS_AUTH_FAILURE,
-    BT_STATUS_RMT_DEV_DOWN
+    BT_STATUS_RMT_DEV_DOWN,
+    BT_STATUS_AUTH_REJECTED
 
 } bt_status_t;
 
diff --git a/include/hardware/bt_gatt_client.h b/include/hardware/bt_gatt_client.h
index d650671..c96789b 100644
--- a/include/hardware/bt_gatt_client.h
+++ b/include/hardware/bt_gatt_client.h
@@ -152,7 +152,7 @@
                                           int rssi, int status);
 
 /**
- * Callback indicationg the status of a listen() operation
+ * Callback indicating the status of a listen() operation
  */
 typedef void (*listen_callback)(int status, int server_if);
 
@@ -160,7 +160,19 @@
 typedef void (*configure_mtu_callback)(int conn_id, int status, int mtu);
 
 /** Callback invoked when a scan filter configuration command has completed */
-typedef void (*scan_filter_callback)(int action, int status);
+typedef void (*scan_filter_cfg_callback)(int action, int client_if, int status, int filt_type,
+                                         int avbl_space);
+
+/** Callback invoked when scan param has been added, cleared, or deleted */
+typedef void (*scan_filter_param_callback)(int action, int client_if, int status,
+                                         int avbl_space);
+
+/** Callback invoked when a scan filter configuration command has completed */
+typedef void (*scan_filter_status_callback)(int enable, int client_if, int status);
+
+/** Track ADV VSE callback invoked when tracked device is found or lost */
+typedef void (*track_adv_event_callback)(int client_if, int filt_index, int addr_type,
+                                             bt_bdaddr_t* bda, int adv_state);
 
 /** Callback invoked when multi-adv enable operation has completed */
 typedef void (*multi_adv_enable_callback)(int client_if, int status);
@@ -174,6 +186,26 @@
 /** Callback invoked when multi-adv disable operation has completed */
 typedef void (*multi_adv_disable_callback)(int client_if, int status);
 
+/**
+ * Callback notifying an application that a remote device connection is currently congested
+ * and cannot receive any more data. An application should avoid sending more data until
+ * a further callback is received indicating the congestion status has been cleared.
+ */
+typedef void (*congestion_callback)(int conn_id, bool congested);
+/** Callback invoked when batchscan storage config operation has completed */
+typedef void (*batchscan_cfg_storage_callback)(int client_if, int status);
+
+/** Callback invoked when batchscan enable / disable operation has completed */
+typedef void (*batchscan_enable_disable_callback)(int action, int client_if, int status);
+
+/** Callback invoked when batchscan reports are obtained */
+typedef void (*batchscan_reports_callback)(int client_if, int status, int report_format,
+                                           int num_records, int data_len, uint8_t* rep_data);
+
+/** Callback invoked when batchscan storage threshold limit is crossed */
+typedef void (*batchscan_threshold_callback)(int client_if);
+
+
 typedef struct {
     register_client_callback            register_client_cb;
     scan_result_callback                scan_result_cb;
@@ -194,11 +226,19 @@
     read_remote_rssi_callback           read_remote_rssi_cb;
     listen_callback                     listen_cb;
     configure_mtu_callback              configure_mtu_cb;
-    scan_filter_callback                scan_filter_cb;
+    scan_filter_cfg_callback            scan_filter_cfg_cb;
+    scan_filter_param_callback          scan_filter_param_cb;
+    scan_filter_status_callback         scan_filter_status_cb;
     multi_adv_enable_callback           multi_adv_enable_cb;
     multi_adv_update_callback           multi_adv_update_cb;
     multi_adv_data_callback             multi_adv_data_cb;
     multi_adv_disable_callback          multi_adv_disable_cb;
+    congestion_callback                 congestion_cb;
+    batchscan_cfg_storage_callback      batchscan_cfg_storage_cb;
+    batchscan_enable_disable_callback   batchscan_enb_disable_cb;
+    batchscan_reports_callback          batchscan_reports_cb;
+    batchscan_threshold_callback        batchscan_threshold_cb;
+    track_adv_event_callback            track_adv_event_cb;
 } btgatt_client_callbacks_t;
 
 /** Represents the standard BT-GATT client interface. */
@@ -296,16 +336,26 @@
     /** Request RSSI for a given remote device */
     bt_status_t (*read_remote_rssi)( int client_if, const bt_bdaddr_t *bd_addr);
 
-    /** Enable or disable scan filtering */
-    bt_status_t (*scan_filter_enable)( int enable );
+    /** Setup scan filter params */
+    bt_status_t (*scan_filter_param_setup)(int client_if, int action, int filt_index, int feat_seln,
+                                      int list_logic_type, int filt_logic_type, int rssi_high_thres,
+                                      int rssi_low_thres, int dely_mode, int found_timeout,
+                                      int lost_timeout, int found_timeout_cnt);
+
 
     /** Configure a scan filter condition  */
-    bt_status_t (*scan_filter_add)(int type, int company_id, int company_mask,
-                                   int len, const bt_uuid_t *p_uuid, const bt_uuid_t *p_uuid_mask,
-                                   const bt_bdaddr_t *bd_addr, char addr_type, const char* p_value);
+    bt_status_t (*scan_filter_add_remove)(int client_if, int action, int filt_type,
+                                   int filt_index, int company_id,
+                                   int company_id_mask, const bt_uuid_t *p_uuid,
+                                   const bt_uuid_t *p_uuid_mask, const bt_bdaddr_t *bd_addr,
+                                   char addr_type, int data_len, char* p_data, int mask_len,
+                                   char* p_mask);
 
-    /** Clear all scan filter conditions */
-    bt_status_t (*scan_filter_clear)();
+    /** Clear all scan filter conditions for specific filter index*/
+    bt_status_t (*scan_filter_clear)(int client_if, int filt_index);
+
+    /** Enable / disable scan filter feature*/
+    bt_status_t (*scan_filter_enable)(int client_if, bool enable);
 
     /** Determine the type of the remote device (LE, BR/EDR, Dual-mode) */
     int (*get_device_type)( const bt_bdaddr_t *bd_addr );
@@ -333,13 +383,27 @@
 
     /* Setup the data for the specified instance */
     bt_status_t (*multi_adv_set_inst_data)(int client_if, bool set_scan_rsp, bool include_name,
-                    bool include_txpower, int appearance, uint16_t manufacturer_len,
-                    char* manufacturer_data, uint16_t service_data_len, char* service_data,
-                    uint16_t service_uuid_len, char* service_uuid);
+                    bool incl_txpower, int appearance, uint16_t manufacturer_len,
+                    char* manufacturer_data, uint16_t service_data_len,
+                    char* service_data, uint16_t service_uuid_len, char* service_uuid);
 
     /* Disable the multi adv instance */
     bt_status_t (*multi_adv_disable)(int client_if);
 
+    /* Configure the batchscan storage */
+    bt_status_t (*batchscan_cfg_storage)(int client_if, int batch_scan_full_max,
+        int batch_scan_trunc_max, int batch_scan_notify_threshold);
+
+    /* Enable batchscan */
+    bt_status_t (*batchscan_enb_batch_scan)(int client_if, int scan_mode,
+        int scan_interval, int scan_window, int addr_type, int discard_rule);
+
+    /* Disable batchscan */
+    bt_status_t (*batchscan_dis_batch_scan)(int client_if);
+
+    /* Read out batchscan reports */
+    bt_status_t (*batchscan_read_reports)(int client_if, int scan_mode);
+
     /** Test mode interface */
     bt_status_t (*test_command)( int command, btgatt_test_params_t* params);
 
diff --git a/include/hardware/bt_gatt_server.h b/include/hardware/bt_gatt_server.h
index 32f8ef6..2b1de27 100644
--- a/include/hardware/bt_gatt_server.h
+++ b/include/hardware/bt_gatt_server.h
@@ -104,6 +104,19 @@
  */
 typedef void (*response_confirmation_callback)(int status, int handle);
 
+/**
+ * Callback confirming that a notification or indication has been sent
+ * to a remote device.
+ */
+typedef void (*indication_sent_callback)(int conn_id, int status);
+
+/**
+ * Callback notifying an application that a remote device connection is currently congested
+ * and cannot receive any more data. An application should avoid sending more data until
+ * a further callback is received indicating the congestion status has been cleared.
+ */
+typedef void (*congestion_callback)(int conn_id, bool congested);
+
 typedef struct {
     register_server_callback        register_server_cb;
     connection_callback             connection_cb;
@@ -118,6 +131,8 @@
     request_write_callback          request_write_cb;
     request_exec_write_callback     request_exec_write_cb;
     response_confirmation_callback  response_confirmation_cb;
+    indication_sent_callback        indication_sent_cb;
+    congestion_callback             congestion_cb;
 } btgatt_server_callbacks_t;
 
 /** Represents the standard BT-GATT server interface. */
diff --git a/modules/sensors/Android.mk b/modules/sensors/Android.mk
index 5b787d4..65f699b 100644
--- a/modules/sensors/Android.mk
+++ b/modules/sensors/Android.mk
@@ -49,4 +49,4 @@
 
 endif # USE_SENSOR_MULTI_HAL
 
-include $(call all-subdir-makefiles)
+include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/modules/usbaudio/audio_hw.c b/modules/usbaudio/audio_hw.c
index b88fa53..7b65014 100644
--- a/modules/usbaudio/audio_hw.c
+++ b/modules/usbaudio/audio_hw.c
@@ -28,9 +28,11 @@
 #include <cutils/str_parms.h>
 #include <cutils/properties.h>
 
-#include <hardware/hardware.h>
-#include <system/audio.h>
 #include <hardware/audio.h>
+#include <hardware/audio_alsaops.h>
+#include <hardware/hardware.h>
+
+#include <system/audio.h>
 
 #include <tinyalsa/asoundlib.h>
 
@@ -141,69 +143,9 @@
  * Utility
  */
 /*
- * Translates from ALSA format ID to ANDROID_AUDIO_CORE format ID
- * (see master/system/core/include/core/audio.h)
- * TODO(pmclean) Replace with audio_format_from_pcm_format() (in hardware/audio_alsaops.h).
- *   post-integration.
- */
-static audio_format_t alsa_to_fw_format_id(int alsa_fmt_id)
-{
-    switch (alsa_fmt_id) {
-    case PCM_FORMAT_S8:
-        return AUDIO_FORMAT_PCM_8_BIT;
-
-    case PCM_FORMAT_S24_3LE:
-        //TODO(pmclean) make sure this is the 'right' sort of 24-bit
-        return AUDIO_FORMAT_PCM_8_24_BIT;
-
-    case PCM_FORMAT_S32_LE:
-    case PCM_FORMAT_S24_LE:
-        return AUDIO_FORMAT_PCM_32_BIT;
-    }
-
-    return AUDIO_FORMAT_PCM_16_BIT;
-}
-
-/*
  * Data Conversions
  */
 /*
- * Convert a buffer of PCM16LE samples to packed (3-byte) PCM24LE samples.
- *   in_buff points to the buffer of PCM16 samples
- *   num_in_samples size of input buffer in SAMPLES
- *   out_buff points to the buffer to receive converted PCM24 LE samples.
- * returns
- *   the number of BYTES of output data.
- * We are doing this since we *always* present to The Framework as A PCM16LE device, but need to
- * support PCM24_3LE (24-bit, packed).
- * NOTE:
- *   We're just filling the low-order byte of the PCM24LE samples with 0.
- *   This conversion is safe to do in-place (in_buff == out_buff).
- * TODO(pmclean, hung) Move this to a utilities module.
- */
-static size_t convert_16_to_24_3(const short * in_buff, size_t num_in_samples, unsigned char * out_buff) {
-    /*
-     * Move from back to front so that the conversion can be done in-place
-     * i.e. in_buff == out_buff
-     */
-    int in_buff_size_in_bytes = num_in_samples * 2;
-    /* we need 3 bytes in the output for every 2 bytes in the input */
-    int out_buff_size_in_bytes = ((3 * in_buff_size_in_bytes) / 2);
-    unsigned char* dst_ptr = out_buff + out_buff_size_in_bytes - 1;
-    size_t src_smpl_index;
-    const unsigned char* src_ptr = ((const unsigned char *)in_buff) + in_buff_size_in_bytes - 1;
-    for (src_smpl_index = 0; src_smpl_index < num_in_samples; src_smpl_index++) {
-        *dst_ptr-- = *src_ptr--; /* hi-byte */
-        *dst_ptr-- = *src_ptr--; /* low-byte */
-        /*TODO(pmclean) - we might want to consider dithering the lowest byte. */
-        *dst_ptr-- = 0;          /* zero-byte */
-    }
-
-    /* return number of *bytes* generated */
-    return out_buff_size_in_bytes;
-}
-
-/*
  * Convert a buffer of packed (3-byte) PCM24LE samples to PCM16LE samples.
  *   in_buff points to the buffer of PCM24LE samples
  *   num_in_samples size of input buffer in SAMPLES
@@ -215,9 +157,11 @@
  * NOTE:
  *   We're just filling the low-order byte of the PCM24LE samples with 0.
  *   This conversion is safe to do in-place (in_buff == out_buff).
- * TODO(pmclean, hung) Move this to a utilities module.
+ * TODO Move this to a utilities module.
  */
-static size_t convert_24_3_to_16(const unsigned char * in_buff, size_t num_in_samples, short * out_buff) {
+static size_t convert_24_3_to_16(const unsigned char * in_buff, size_t num_in_samples,
+                                 short * out_buff)
+{
     /*
      * Move from front to back so that the conversion can be done in-place
      * i.e. in_buff == out_buff
@@ -251,11 +195,12 @@
  *   This conversion is safe to do in-place (in_buff == out_buff)
  * We are doing this since we *always* present to The Framework as STEREO device, but need to
  * support 4-channel devices.
- * TODO(pmclean, hung) Move this to a utilities module.
+ * TODO Move this to a utilities module.
  */
 static size_t expand_channels_16(const short* in_buff, int in_buff_chans,
                                  short* out_buff, int out_buff_chans,
-                                 size_t num_in_samples) {
+                                 size_t num_in_samples)
+{
     /*
      * Move from back to front so that the conversion can be done in-place
      * i.e. in_buff == out_buff
@@ -269,10 +214,10 @@
     int num_zero_chans = out_buff_chans - in_buff_chans;
     for (src_index = 0; src_index < num_in_samples; src_index += in_buff_chans) {
         int dst_offset;
-        for(dst_offset = 0; dst_offset < num_zero_chans; dst_offset++) {
+        for (dst_offset = 0; dst_offset < num_zero_chans; dst_offset++) {
             *dst_ptr-- = 0;
         }
-        for(; dst_offset < out_buff_chans; dst_offset++) {
+        for (; dst_offset < out_buff_chans; dst_offset++) {
             *dst_ptr-- = *src_ptr--;
         }
     }
@@ -296,11 +241,12 @@
  *   This conversion is safe to do in-place (in_buff == out_buff)
  * We are doing this since we *always* present to The Framework as STEREO device, but need to
  * support 4-channel devices.
- * TODO(pmclean, hung) Move this to a utilities module.
+ * TODO Move this to a utilities module.
  */
 static size_t contract_channels_16(short* in_buff, int in_buff_chans,
                                    short* out_buff, int out_buff_chans,
-                                   size_t num_in_samples) {
+                                   size_t num_in_samples)
+{
     /*
      * Move from front to back so that the conversion can be done in-place
      * i.e. in_buff == out_buff
@@ -315,7 +261,7 @@
     size_t src_index;
     for (src_index = 0; src_index < num_in_samples; src_index += in_buff_chans) {
         int dst_offset;
-        for(dst_offset = 0; dst_offset < out_buff_chans; dst_offset++) {
+        for (dst_offset = 0; dst_offset < out_buff_chans; dst_offset++) {
             *dst_ptr++ = *src_ptr++;
         }
         src_ptr += num_skip_samples;
@@ -328,19 +274,292 @@
 /*
  * ALSA Utilities
  */
+/*TODO This table and the function that uses it should be moved to a utilities module (probably) */
 /*
- * gets the ALSA bit-format flag from a bits-per-sample value.
- * TODO(pmclean, hung) Move this to a utilities module.
+ * Maps bit-positions in a pcm_mask to the corresponding AUDIO_ format string.
  */
-static int bits_to_alsa_format(unsigned int bits_per_sample, int default_format)
+static const char * const format_string_map[] = {
+    "AUDIO_FORMAT_PCM_8_BIT",           /* 00 - SNDRV_PCM_FORMAT_S8 */
+    "AUDIO_FORMAT_PCM_8_BIT",           /* 01 - SNDRV_PCM_FORMAT_U8 */
+    "AUDIO_FORMAT_PCM_16_BIT",          /* 02 - SNDRV_PCM_FORMAT_S16_LE */
+    NULL,                               /* 03 - SNDRV_PCM_FORMAT_S16_BE */
+    NULL,                               /* 04 - SNDRV_PCM_FORMAT_U16_LE */
+    NULL,                               /* 05 - SNDRV_PCM_FORMAT_U16_BE */
+    "AUDIO_FORMAT_PCM_24_BIT_PACKED",   /* 06 - SNDRV_PCM_FORMAT_S24_LE */
+    NULL,                               /* 07 - SNDRV_PCM_FORMAT_S24_BE */
+    NULL,                               /* 08 - SNDRV_PCM_FORMAT_U24_LE */
+    NULL,                               /* 09 - SNDRV_PCM_FORMAT_U24_BE */
+    "AUDIO_FORMAT_PCM_32_BIT",          /* 10 - SNDRV_PCM_FORMAT_S32_LE */
+    NULL,                               /* 11 - SNDRV_PCM_FORMAT_S32_BE */
+    NULL,                               /* 12 - SNDRV_PCM_FORMAT_U32_LE */
+    NULL,                               /* 13 - SNDRV_PCM_FORMAT_U32_BE */
+    "AUDIO_FORMAT_PCM_FLOAT",           /* 14 - SNDRV_PCM_FORMAT_FLOAT_LE */
+    NULL,                               /* 15 - SNDRV_PCM_FORMAT_FLOAT_BE */
+    NULL,                               /* 16 - SNDRV_PCM_FORMAT_FLOAT64_LE */
+    NULL,                               /* 17 - SNDRV_PCM_FORMAT_FLOAT64_BE */
+    NULL,                               /* 18 - SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE */
+    NULL,                               /* 19 - SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE */
+    NULL,                               /* 20 - SNDRV_PCM_FORMAT_MU_LAW */
+    NULL,                               /* 21 - SNDRV_PCM_FORMAT_A_LAW */
+    NULL,                               /* 22 - SNDRV_PCM_FORMAT_IMA_ADPCM */
+    NULL,                               /* 23 - SNDRV_PCM_FORMAT_MPEG */
+    NULL,                               /* 24 - SNDRV_PCM_FORMAT_GSM */
+    NULL, NULL, NULL, NULL, NULL, NULL, /* 25 -> 30 (not assigned) */
+    NULL,                               /* 31 - SNDRV_PCM_FORMAT_SPECIAL */
+    "AUDIO_FORMAT_PCM_24_BIT_PACKED",   /* 32 - SNDRV_PCM_FORMAT_S24_3LE */ /* ??? */
+    NULL,                               /* 33 - SNDRV_PCM_FORMAT_S24_3BE */
+    NULL,                               /* 34 - SNDRV_PCM_FORMAT_U24_3LE */
+    NULL,                               /* 35 - SNDRV_PCM_FORMAT_U24_3BE */
+    NULL,                               /* 36 - SNDRV_PCM_FORMAT_S20_3LE */
+    NULL,                               /* 37 - SNDRV_PCM_FORMAT_S20_3BE */
+    NULL,                               /* 38 - SNDRV_PCM_FORMAT_U20_3LE */
+    NULL,                               /* 39 - SNDRV_PCM_FORMAT_U20_3BE */
+    NULL,                               /* 40 - SNDRV_PCM_FORMAT_S18_3LE */
+    NULL,                               /* 41 - SNDRV_PCM_FORMAT_S18_3BE */
+    NULL,                               /* 42 - SNDRV_PCM_FORMAT_U18_3LE */
+    NULL,                               /* 43 - SNDRV_PCM_FORMAT_U18_3BE */
+    NULL,                               /* 44 - SNDRV_PCM_FORMAT_G723_24 */
+    NULL,                               /* 45 - SNDRV_PCM_FORMAT_G723_24_1B */
+    NULL,                               /* 46 - SNDRV_PCM_FORMAT_G723_40 */
+    NULL,                               /* 47 - SNDRV_PCM_FORMAT_G723_40_1B */
+    NULL,                               /* 48 - SNDRV_PCM_FORMAT_DSD_U8 */
+    NULL                                /* 49 - SNDRV_PCM_FORMAT_DSD_U16_LE */
+};
+
+/*
+ * Generate string containing a bar ("|") delimited list of AUDIO_ formats specified in
+ * the mask parameter.
+ *
+ */
+static char* get_format_str_for_mask(struct pcm_mask* mask)
 {
-    enum pcm_format format;
-    for (format = PCM_FORMAT_S16_LE; format < PCM_FORMAT_MAX; format++) {
-        if (pcm_format_to_bits(format) == bits_per_sample) {
-            return format;
+    char buffer[256];
+    int buffer_size = sizeof(buffer) / sizeof(buffer[0]);
+    buffer[0] = '\0';
+
+    int num_slots = sizeof(mask->bits) / sizeof(mask->bits[0]);
+    int bits_per_slot = sizeof(mask->bits[0]) * 8;
+
+    const char* format_str = NULL;
+    int table_size = sizeof(format_string_map)/sizeof(format_string_map[0]);
+
+    int slot_index, bit_index, table_index;
+    table_index = 0;
+    int num_written = 0;
+    for (slot_index = 0; slot_index < num_slots; slot_index++) {
+        unsigned bit_mask = 1;
+        for (bit_index = 0; bit_index < bits_per_slot; bit_index++) {
+            if ((mask->bits[slot_index] & bit_mask) != 0) {
+                format_str = table_index < table_size
+                                ? format_string_map[table_index]
+                                : NULL;
+                if (format_str != NULL) {
+                    if (num_written != 0) {
+                        num_written += snprintf(buffer + num_written,
+                                                buffer_size - num_written, "|");
+                    }
+                    num_written += snprintf(buffer + num_written, buffer_size - num_written,
+                                            "%s", format_str);
+                }
+            }
+            bit_mask <<= 1;
+            table_index++;
         }
     }
-    return default_format;
+
+    return strdup(buffer);
+}
+
+/*
+ * Maps from bit position in pcm_mask to AUDIO_ format constants.
+ */
+static int const format_value_map[] = {
+    AUDIO_FORMAT_PCM_8_BIT,           /* 00 - SNDRV_PCM_FORMAT_S8 */
+    AUDIO_FORMAT_PCM_8_BIT,           /* 01 - SNDRV_PCM_FORMAT_U8 */
+    AUDIO_FORMAT_PCM_16_BIT,          /* 02 - SNDRV_PCM_FORMAT_S16_LE */
+    AUDIO_FORMAT_INVALID,             /* 03 - SNDRV_PCM_FORMAT_S16_BE */
+    AUDIO_FORMAT_INVALID,             /* 04 - SNDRV_PCM_FORMAT_U16_LE */
+    AUDIO_FORMAT_INVALID,             /* 05 - SNDRV_PCM_FORMAT_U16_BE */
+    AUDIO_FORMAT_PCM_24_BIT_PACKED,   /* 06 - SNDRV_PCM_FORMAT_S24_LE */
+    AUDIO_FORMAT_INVALID,             /* 07 - SNDRV_PCM_FORMAT_S24_BE */
+    AUDIO_FORMAT_INVALID,             /* 08 - SNDRV_PCM_FORMAT_U24_LE */
+    AUDIO_FORMAT_INVALID,             /* 09 - SNDRV_PCM_FORMAT_U24_BE */
+    AUDIO_FORMAT_PCM_32_BIT,          /* 10 - SNDRV_PCM_FORMAT_S32_LE */
+    AUDIO_FORMAT_INVALID,             /* 11 - SNDRV_PCM_FORMAT_S32_BE */
+    AUDIO_FORMAT_INVALID,             /* 12 - SNDRV_PCM_FORMAT_U32_LE */
+    AUDIO_FORMAT_INVALID,             /* 13 - SNDRV_PCM_FORMAT_U32_BE */
+    AUDIO_FORMAT_PCM_FLOAT,           /* 14 - SNDRV_PCM_FORMAT_FLOAT_LE */
+    AUDIO_FORMAT_INVALID,             /* 15 - SNDRV_PCM_FORMAT_FLOAT_BE */
+    AUDIO_FORMAT_INVALID,             /* 16 - SNDRV_PCM_FORMAT_FLOAT64_LE */
+    AUDIO_FORMAT_INVALID,             /* 17 - SNDRV_PCM_FORMAT_FLOAT64_BE */
+    AUDIO_FORMAT_INVALID,             /* 18 - SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE */
+    AUDIO_FORMAT_INVALID,             /* 19 - SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE */
+    AUDIO_FORMAT_INVALID,             /* 20 - SNDRV_PCM_FORMAT_MU_LAW */
+    AUDIO_FORMAT_INVALID,             /* 21 - SNDRV_PCM_FORMAT_A_LAW */
+    AUDIO_FORMAT_INVALID,             /* 22 - SNDRV_PCM_FORMAT_IMA_ADPCM */
+    AUDIO_FORMAT_INVALID,             /* 23 - SNDRV_PCM_FORMAT_MPEG */
+    AUDIO_FORMAT_INVALID,             /* 24 - SNDRV_PCM_FORMAT_GSM */
+    AUDIO_FORMAT_INVALID,             /* 25 -> 30 (not assigned) */
+    AUDIO_FORMAT_INVALID,
+    AUDIO_FORMAT_INVALID,
+    AUDIO_FORMAT_INVALID,
+    AUDIO_FORMAT_INVALID,
+    AUDIO_FORMAT_INVALID,
+    AUDIO_FORMAT_INVALID,             /* 31 - SNDRV_PCM_FORMAT_SPECIAL */
+    AUDIO_FORMAT_PCM_24_BIT_PACKED,   /* 32 - SNDRV_PCM_FORMAT_S24_3LE */ /* ??? */
+    AUDIO_FORMAT_INVALID,             /* 33 - SNDRV_PCM_FORMAT_S24_3BE */
+    AUDIO_FORMAT_INVALID,             /* 34 - SNDRV_PCM_FORMAT_U24_3LE */
+    AUDIO_FORMAT_INVALID,             /* 35 - SNDRV_PCM_FORMAT_U24_3BE */
+    AUDIO_FORMAT_INVALID,             /* 36 - SNDRV_PCM_FORMAT_S20_3LE */
+    AUDIO_FORMAT_INVALID,             /* 37 - SNDRV_PCM_FORMAT_S20_3BE */
+    AUDIO_FORMAT_INVALID,             /* 38 - SNDRV_PCM_FORMAT_U20_3LE */
+    AUDIO_FORMAT_INVALID,             /* 39 - SNDRV_PCM_FORMAT_U20_3BE */
+    AUDIO_FORMAT_INVALID,             /* 40 - SNDRV_PCM_FORMAT_S18_3LE */
+    AUDIO_FORMAT_INVALID,             /* 41 - SNDRV_PCM_FORMAT_S18_3BE */
+    AUDIO_FORMAT_INVALID,             /* 42 - SNDRV_PCM_FORMAT_U18_3LE */
+    AUDIO_FORMAT_INVALID,             /* 43 - SNDRV_PCM_FORMAT_U18_3BE */
+    AUDIO_FORMAT_INVALID,             /* 44 - SNDRV_PCM_FORMAT_G723_24 */
+    AUDIO_FORMAT_INVALID,             /* 45 - SNDRV_PCM_FORMAT_G723_24_1B */
+    AUDIO_FORMAT_INVALID,             /* 46 - SNDRV_PCM_FORMAT_G723_40 */
+    AUDIO_FORMAT_INVALID,             /* 47 - SNDRV_PCM_FORMAT_G723_40_1B */
+    AUDIO_FORMAT_INVALID,             /* 48 - SNDRV_PCM_FORMAT_DSD_U8 */
+    AUDIO_FORMAT_INVALID              /* 49 - SNDRV_PCM_FORMAT_DSD_U16_LE */
+};
+
+static int get_format_for_mask(struct pcm_mask* mask)
+{
+    int num_slots = sizeof(mask->bits)/ sizeof(mask->bits[0]);
+    int bits_per_slot = sizeof(mask->bits[0]) * 8;
+
+    int table_size = sizeof(format_value_map) / sizeof(format_value_map[0]);
+
+    int slot_index, bit_index, table_index;
+    table_index = 0;
+    int num_written = 0;
+    for (slot_index = 0; slot_index < num_slots; slot_index++) {
+        unsigned bit_mask = 1;
+        for (bit_index = 0; bit_index < bits_per_slot; bit_index++) {
+            if ((mask->bits[slot_index] & bit_mask) != 0) {
+                /* just return the first one */
+                return table_index < table_size
+                           ? format_value_map[table_index]
+                           : AUDIO_FORMAT_INVALID;
+            }
+            bit_mask <<= 1;
+            table_index++;
+        }
+    }
+
+    return AUDIO_FORMAT_INVALID;
+}
+
+/*
+ * Maps from bit position in pcm_mask to AUDIO_ format constants.
+ */
+static int const pcm_format_value_map[] = {
+    PCM_FORMAT_S8,          /* 00 - SNDRV_PCM_FORMAT_S8 */
+    0,                      /* 01 - SNDRV_PCM_FORMAT_U8 */
+    PCM_FORMAT_S16_LE,      /* 02 - SNDRV_PCM_FORMAT_S16_LE */
+    0,                      /* 03 - SNDRV_PCM_FORMAT_S16_BE */
+    0,                      /* 04 - SNDRV_PCM_FORMAT_U16_LE */
+    0,                      /* 05 - SNDRV_PCM_FORMAT_U16_BE */
+    PCM_FORMAT_S24_3LE,     /* 06 - SNDRV_PCM_FORMAT_S24_LE */
+    0,                      /* 07 - SNDRV_PCM_FORMAT_S24_BE */
+    0,                      /* 08 - SNDRV_PCM_FORMAT_U24_LE */
+    0,                      /* 09 - SNDRV_PCM_FORMAT_U24_BE */
+    PCM_FORMAT_S32_LE,      /* 10 - SNDRV_PCM_FORMAT_S32_LE */
+    0,                      /* 11 - SNDRV_PCM_FORMAT_S32_BE */
+    0,                      /* 12 - SNDRV_PCM_FORMAT_U32_LE */
+    0,                      /* 13 - SNDRV_PCM_FORMAT_U32_BE */
+    0,                      /* 14 - SNDRV_PCM_FORMAT_FLOAT_LE */
+    0,                      /* 15 - SNDRV_PCM_FORMAT_FLOAT_BE */
+    0,                      /* 16 - SNDRV_PCM_FORMAT_FLOAT64_LE */
+    0,                      /* 17 - SNDRV_PCM_FORMAT_FLOAT64_BE */
+    0,                      /* 18 - SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE */
+    0,                      /* 19 - SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE */
+    0,                      /* 20 - SNDRV_PCM_FORMAT_MU_LAW */
+    0,                      /* 21 - SNDRV_PCM_FORMAT_A_LAW */
+    0,                      /* 22 - SNDRV_PCM_FORMAT_IMA_ADPCM */
+    0,                      /* 23 - SNDRV_PCM_FORMAT_MPEG */
+    0,                      /* 24 - SNDRV_PCM_FORMAT_GSM */
+    0,                      /* 25 -> 30 (not assigned) */
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,                      /* 31 - SNDRV_PCM_FORMAT_SPECIAL */
+    PCM_FORMAT_S24_3LE,     /* 32 - SNDRV_PCM_FORMAT_S24_3LE */ /* ??? */
+    0,                      /* 33 - SNDRV_PCM_FORMAT_S24_3BE */
+    0,                      /* 34 - SNDRV_PCM_FORMAT_U24_3LE */
+    0,                      /* 35 - SNDRV_PCM_FORMAT_U24_3BE */
+    0,                      /* 36 - SNDRV_PCM_FORMAT_S20_3LE */
+    0,                      /* 37 - SNDRV_PCM_FORMAT_S20_3BE */
+    0,                      /* 38 - SNDRV_PCM_FORMAT_U20_3LE */
+    0,                      /* 39 - SNDRV_PCM_FORMAT_U20_3BE */
+    0,                      /* 40 - SNDRV_PCM_FORMAT_S18_3LE */
+    0,                      /* 41 - SNDRV_PCM_FORMAT_S18_3BE */
+    0,                      /* 42 - SNDRV_PCM_FORMAT_U18_3LE */
+    0,                      /* 43 - SNDRV_PCM_FORMAT_U18_3BE */
+    0,                      /* 44 - SNDRV_PCM_FORMAT_G723_24 */
+    0,                      /* 45 - SNDRV_PCM_FORMAT_G723_24_1B */
+    0,                      /* 46 - SNDRV_PCM_FORMAT_G723_40 */
+    0,                      /* 47 - SNDRV_PCM_FORMAT_G723_40_1B */
+    0,                      /* 48 - SNDRV_PCM_FORMAT_DSD_U8 */
+    0                       /* 49 - SNDRV_PCM_FORMAT_DSD_U16_LE */
+};
+
+static int get_pcm_format_for_mask(struct pcm_mask* mask) {
+    int num_slots = sizeof(mask->bits)/ sizeof(mask->bits[0]);
+    int bits_per_slot = sizeof(mask->bits[0]) * 8;
+
+    int table_size = sizeof(pcm_format_value_map) / sizeof(pcm_format_value_map[0]);
+
+    int slot_index, bit_index, table_index;
+    table_index = 0;
+    int num_written = 0;
+    for (slot_index = 0; slot_index < num_slots; slot_index++) {
+        unsigned bit_mask = 1;
+        for (bit_index = 0; bit_index < bits_per_slot; bit_index++) {
+            if ((mask->bits[slot_index] & bit_mask) != 0) {
+                /* just return the first one */
+                return table_index < table_size
+                           ? pcm_format_value_map[table_index]
+                           : AUDIO_FORMAT_INVALID;
+            }
+            bit_mask <<= 1;
+            table_index++;
+        }
+    }
+
+    return 0; // is this right?
+}
+
+static void log_pcm_mask(const char* mask_name, struct pcm_mask* mask) {
+    char buff[512];
+    char bit_buff[32];
+    int buffSize = sizeof(buff)/sizeof(buff[0]);
+
+    buff[0] = '\0';
+
+    int num_slots = sizeof(mask->bits) / sizeof(mask->bits[0]);
+    int bits_per_slot = sizeof(mask->bits[0]) * 8;
+
+    int slot_index, bit_index;
+    strcat(buff, "[");
+    for (slot_index = 0; slot_index < num_slots; slot_index++) {
+        unsigned bit_mask = 1;
+        for (bit_index = 0; bit_index < bits_per_slot; bit_index++) {
+            strcat(buff, (mask->bits[slot_index] & bit_mask) != 0 ? "1" : "0");
+            bit_mask <<= 1;
+        }
+        if (slot_index < num_slots - 1) {
+            strcat(buff, ",");
+        }
+    }
+    strcat(buff, "]");
+
+    ALOGV("usb:audio_hw - %s mask:%s", mask_name, buff);
 }
 
 static void log_pcm_params(struct pcm_params * alsa_hw_params) {
@@ -350,6 +569,8 @@
     ALOGV("usb:audio_hw - PCM_PARAM_FRAME_BITS min:%u, max:%u",
           pcm_params_get_min(alsa_hw_params, PCM_PARAM_FRAME_BITS),
           pcm_params_get_max(alsa_hw_params, PCM_PARAM_FRAME_BITS));
+    log_pcm_mask("PCM_PARAM_FORMAT", pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT));
+    log_pcm_mask("PCM_PARAM_SUBFORMAT", pcm_params_get_mask(alsa_hw_params, PCM_PARAM_SUBFORMAT));
     ALOGV("usb:audio_hw - PCM_PARAM_CHANNELS min:%u, max:%u",
           pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS),
           pcm_params_get_max(alsa_hw_params, PCM_PARAM_CHANNELS));
@@ -389,7 +610,7 @@
     return (size + 15) & 0xFFFFFFF0;
 }
 
-/*TODO(pmclean) - Evaluate if this value should/can be retrieved from a device-specific property */
+/*TODO - Evaluate if this value should/can be retrieved from a device-specific property */
 #define MIN_BUFF_TIME   5   /* milliseconds */
 
 /*
@@ -433,9 +654,7 @@
     }
     config->period_count = pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIODS);
 
-    unsigned int bits_per_sample = pcm_params_get_min(alsa_hw_params, PCM_PARAM_SAMPLE_BITS);
-    config->format = bits_to_alsa_format(bits_per_sample, PCM_FORMAT_S16_LE);
-
+    config->format = get_pcm_format_for_mask(pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT));
     return 0;
 }
 
@@ -466,21 +685,19 @@
 static uint32_t out_get_channels(const struct audio_stream *stream)
 {
     // Always Stero for now. We will do *some* conversions in this HAL.
-    // TODO(pmclean) When AudioPolicyManager & AudioFlinger supports arbitrary channels
-    // rewrite this to return the ACTUAL channel format
+    /* TODO When AudioPolicyManager & AudioFlinger supports arbitrary channels
+       rewrite this to return the ACTUAL channel format */
     return AUDIO_CHANNEL_OUT_STEREO;
 }
 
 static audio_format_t out_get_format(const struct audio_stream *stream)
 {
-    // Always return 16-bit PCM. We will do *some* conversions in this HAL.
-    // TODO(pmclean) When AudioPolicyManager & AudioFlinger supports arbitrary PCM formats
-    // rewrite this to return the ACTUAL data format
-    return AUDIO_FORMAT_PCM_16_BIT;
+    return audio_format_from_pcm_format(cached_output_hardware_config.format);
 }
 
 static int out_set_format(struct audio_stream *stream, audio_format_t format)
 {
+    cached_output_hardware_config.format = pcm_format_from_audio_format(format);
     return 0;
 }
 
@@ -548,8 +765,8 @@
     return ret_value;
 }
 
-//TODO(pmclean) it seems like both out_get_parameters() and in_get_parameters()
-// could be written in terms of a get_device_parameters(io_type)
+/*TODO it seems like both out_get_parameters() and in_get_parameters()
+  could be written in terms of a get_device_parameters(io_type) */
 
 static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
 {
@@ -591,6 +808,7 @@
     // supported channel counts
     if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS)) {
         // Similarly for output channels count
+        /* TODO - This is wrong, we need format strings, not numbers (another CL) */
         min = pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS);
         max = pcm_params_get_max(alsa_hw_params, PCM_PARAM_CHANNELS);
         num_written = snprintf(buffer, buffer_size, "%u", min);
@@ -602,15 +820,10 @@
 
     // supported sample formats
     if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_FORMATS)) {
-        // Similarly for output channels count
-        //TODO(pmclean): this is wrong.
-        min = pcm_params_get_min(alsa_hw_params, PCM_PARAM_SAMPLE_BITS);
-        max = pcm_params_get_max(alsa_hw_params, PCM_PARAM_SAMPLE_BITS);
-        num_written = snprintf(buffer, buffer_size, "%u", min);
-        if (min != max) {
-            snprintf(buffer + num_written, buffer_size - num_written, "|%u", max);
-        }
-        str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_FORMATS, buffer);
+        char * format_params =
+            get_format_str_for_mask(pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT));
+        str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_FORMATS, format_params);
+        free(format_params);
     }  // AUDIO_PARAMETER_STREAM_SUP_FORMATS
 
     result_str = str_parms_to_str(result);
@@ -619,6 +832,8 @@
     str_parms_destroy(query);
     str_parms_destroy(result);
 
+    ALOGV("usb:audio_hw::out out_get_parameters() = %s", result_str);
+
     return result_str;
 }
 
@@ -626,10 +841,10 @@
 {
     struct stream_out *out = (struct stream_out *) stream;
 
-    //TODO(pmclean): Do we need a term here for the USB latency
-    // (as reported in the USB descriptors)?
+    /*TODO Do we need a term here for the USB latency (as reported in the USB descriptors)? */
     uint32_t latency = (cached_output_hardware_config.period_size
-            * cached_output_hardware_config.period_count * 1000) / out_get_sample_rate(&stream->common);
+                    * cached_output_hardware_config.period_count * 1000)
+                    / out_get_sample_rate(&stream->common);
     return latency;
 }
 
@@ -648,6 +863,7 @@
           adev->out_card, adev->out_device);
 
     out->pcm = pcm_open(adev->out_card, adev->out_device, PCM_OUT, &cached_output_hardware_config);
+
     if (out->pcm == NULL) {
         return -ENOMEM;
     }
@@ -682,8 +898,8 @@
     // * 3/2 for 16bit -> 24 bit conversion
     size_t required_conversion_buffer_size = (bytes * 3 * 2) / 2;
     if (required_conversion_buffer_size > out->conversion_buffer_size) {
-        //TODO(pmclean) - remove this when AudioPolicyManger/AudioFlinger support arbitrary formats
-        // (and do these conversions themselves)
+        /* TODO Remove this when AudioPolicyManger/AudioFlinger support arbitrary formats
+           (and do these conversions themselves) */
         out->conversion_buffer_size = required_conversion_buffer_size;
         out->conversion_buffer = realloc(out->conversion_buffer, out->conversion_buffer_size);
     }
@@ -704,28 +920,6 @@
         write_buff = out->conversion_buffer;
     }
 
-    /*
-     *  16 vs 24-bit logic here
-     */
-    switch (cached_output_hardware_config.format) {
-    case PCM_FORMAT_S16_LE:
-        // the output format is the same as the input format, so just write it out
-        break;
-
-    case PCM_FORMAT_S24_3LE:
-        // 16-bit LE2 - 24-bit LE3
-        num_write_buff_bytes = convert_16_to_24_3(write_buff,
-                                                  num_write_buff_bytes / sizeof(short),
-                                                  out->conversion_buffer);
-        write_buff = out->conversion_buffer;
-        break;
-
-    default:
-        // hmmmmm.....
-        ALOGV("usb:Unknown Format!!!");
-        break;
-    }
-
     if (write_buff != NULL && num_write_buff_bytes != 0) {
         pcm_write(out->pcm, write_buff, num_write_buff_bytes);
     }
@@ -808,20 +1002,14 @@
     if (output_hardware_config_is_cached) {
         config->sample_rate = cached_output_hardware_config.rate;
 
-        config->format = alsa_to_fw_format_id(cached_output_hardware_config.format);
-        if (config->format != AUDIO_FORMAT_PCM_16_BIT) {
-            // Always report PCM16 for now. AudioPolicyManagerBase/AudioFlinger dont' understand
-            // formats with more other format, so we won't get chosen (say with a 24bit DAC).
-            //TODO(pmclean) remove this when the above restriction is removed.
-            config->format = AUDIO_FORMAT_PCM_16_BIT;
-        }
+        config->format = audio_format_from_pcm_format(cached_output_hardware_config.format);
 
         config->channel_mask =
                 audio_channel_out_mask_from_count(cached_output_hardware_config.channels);
         if (config->channel_mask != AUDIO_CHANNEL_OUT_STEREO) {
             // Always report STEREO for now.  AudioPolicyManagerBase/AudioFlinger dont' understand
             // formats with more channels, so we won't get chosen (say with a 4-channel DAC).
-            //TODO(pmclean) remove this when the above restriction is removed.
+            /*TODO remove this when the above restriction is removed. */
             config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
         }
     } else {
@@ -852,8 +1040,7 @@
     ALOGV("usb:audio_hw::out adev_close_output_stream()");
     struct stream_out *out = (struct stream_out *)stream;
 
-    //TODO(pmclean) why are we doing this when stream get's freed at the end
-    // because it closes the pcm device
+    // Close the pcm device
     out_standby(&stream->common);
 
     free(out->conversion_buffer);
@@ -925,7 +1112,6 @@
     ALOGV("usb: in_get_buffer_size() = %zu",
           cached_input_hardware_config.period_size * audio_stream_frame_size(stream));
     return cached_input_hardware_config.period_size * audio_stream_frame_size(stream);
-
 }
 
 static uint32_t in_get_channels(const struct audio_stream *stream)
@@ -936,8 +1122,7 @@
 
 static audio_format_t in_get_format(const struct audio_stream *stream)
 {
-    // just report 16-bit, pcm for now.
-    return AUDIO_FORMAT_PCM_16_BIT;
+    return audio_format_from_pcm_format(cached_input_hardware_config.format);
 }
 
 static int in_set_format(struct audio_stream *stream, audio_format_t format)
@@ -1011,8 +1196,8 @@
     return ret_value;
 }
 
-//TODO(pmclean) it seems like both out_get_parameters() and in_get_parameters()
-// could be written in terms of a get_device_parameters(io_type)
+/*TODO it seems like both out_get_parameters() and in_get_parameters()
+   could be written in terms of a get_device_parameters(io_type) */
 
 static char * in_get_parameters(const struct audio_stream *stream, const char *keys) {
     ALOGV("usb:audio_hw::in in_get_parameters() keys:%s", keys);
@@ -1054,6 +1239,7 @@
     // supported channel counts
     if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS)) {
         // Similarly for output channels count
+        // TODO This is wrong, we need format strings, not numbers (another CL)
         min = pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS);
         max = pcm_params_get_max(alsa_hw_params, PCM_PARAM_CHANNELS);
         num_written = snprintf(buffer, buffer_size, "%u", min);
@@ -1065,7 +1251,8 @@
 
     // supported sample formats
     if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_FORMATS)) {
-        //TODO(pmclean): this is wrong.
+        /*TODO This is wrong.  It needs to return AUDIO_ format constants (as strings)
+          as in audio_policy.conf */
         min = pcm_params_get_min(alsa_hw_params, PCM_PARAM_SAMPLE_BITS);
         max = pcm_params_get_max(alsa_hw_params, PCM_PARAM_SAMPLE_BITS);
         num_written = snprintf(buffer, buffer_size, "%u", min);
@@ -1122,7 +1309,7 @@
     return 0;
 }
 
-//TODO(pmclean) mutex stuff here (see out_write)
+/* TODO mutex stuff here (see out_write) */
 static ssize_t in_read(struct audio_stream_in *stream, void* buffer, size_t bytes)
 {
     size_t num_read_buff_bytes = 0;
@@ -1131,8 +1318,6 @@
 
     struct stream_in * in = (struct stream_in *) stream;
 
-    ALOGV("usb: in_read(%d)", bytes);
-
     pthread_mutex_lock(&in->dev->lock);
     pthread_mutex_lock(&in->lock);
 
@@ -1160,8 +1345,8 @@
     // Setup/Realloc the conversion buffer (if necessary).
     if (num_read_buff_bytes != bytes) {
         if (num_read_buff_bytes > in->conversion_buffer_size) {
-            //TODO(pmclean) - remove this when AudioPolicyManger/AudioFlinger support arbitrary formats
-            // (and do these conversions themselves)
+            /*TODO Remove this when AudioPolicyManger/AudioFlinger support arbitrary formats
+              (and do these conversions themselves) */
             in->conversion_buffer_size = num_read_buff_bytes;
             in->conversion_buffer = realloc(in->conversion_buffer, in->conversion_buffer_size);
         }
@@ -1188,14 +1373,14 @@
             /* Num Channels conversion */
             if (num_device_channels < num_req_channels) {
                 num_read_buff_bytes =
-                    contract_channels_16(read_buff, num_device_channels,
-                                         out_buff, num_req_channels,
-                                         num_read_buff_bytes / sizeof(short));
-            } else {
-                num_read_buff_bytes =
                     expand_channels_16(read_buff, num_device_channels,
                                        out_buff, num_req_channels,
                                        num_read_buff_bytes / sizeof(short));
+            } else {
+                num_read_buff_bytes =
+                    contract_channels_16(read_buff, num_device_channels,
+                                         out_buff, num_req_channels,
+                                         num_read_buff_bytes / sizeof(short));
             }
         }
     }
@@ -1253,11 +1438,11 @@
     if (input_hardware_config_is_cached) {
         config->sample_rate = cached_input_hardware_config.rate;
 
-        config->format = alsa_to_fw_format_id(cached_input_hardware_config.format);
+        config->format = audio_format_from_pcm_format(cached_input_hardware_config.format);
         if (config->format != AUDIO_FORMAT_PCM_16_BIT) {
             // Always report PCM16 for now. AudioPolicyManagerBase/AudioFlinger dont' understand
             // formats with more other format, so we won't get chosen (say with a 24bit DAC).
-            //TODO(pmclean) remove this when the above restriction is removed.
+            /* TODO Remove this when the above restriction is removed. */
             config->format = AUDIO_FORMAT_PCM_16_BIT;
         }
 
@@ -1266,7 +1451,7 @@
         if (config->channel_mask != AUDIO_CHANNEL_IN_STEREO) {
             // Always report STEREO for now.  AudioPolicyManagerBase/AudioFlinger dont' understand
             // formats with more channels, so we won't get chosen (say with a 4-channel DAC).
-            //TODO(pmclean) remove this when the above restriction is removed.
+            /* TODO Remove this when the above restriction is removed. */
             config->channel_mask = AUDIO_CHANNEL_IN_STEREO;
         }
     } else {
@@ -1291,8 +1476,7 @@
 {
     struct stream_in *in = (struct stream_in *)stream;
 
-    //TODO(pmclean) why are we doing this when stream get's freed at the end
-    // because it closes the pcm device
+    // Close the pcm device
     in_standby(&stream->common);
 
     free(in->conversion_buffer);