policy_hal: hal: add support to enable Direct PCM

- add support for direct pcm output
- add support for direct pcm in hal
  if output flag is direct_pcm choose compress offload path
- add support for direct pcm in custom audio policy manager
  force add direct flag when we detect pcm track in music and
  game use case

Change-Id: Ie69c988ef9cd0477efa77611ceddccdd6b17a163
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 1dadf0f..6951fe4 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -177,6 +177,8 @@
     [USECASE_AUDIO_PLAYBACK_OFFLOAD8] = "compress-offload-playback8",
     [USECASE_AUDIO_PLAYBACK_OFFLOAD9] = "compress-offload-playback9",
 #endif
+    [USECASE_AUDIO_DIRECT_PCM_OFFLOAD] = "compress-offload-playback2",
+
     [USECASE_AUDIO_RECORD] = "audio-record",
     [USECASE_AUDIO_RECORD_COMPRESS] = "audio-record-compress",
     [USECASE_AUDIO_RECORD_LOW_LATENCY] = "low-latency-record",
@@ -221,6 +223,7 @@
     USECASE_AUDIO_PLAYBACK_OFFLOAD8,
     USECASE_AUDIO_PLAYBACK_OFFLOAD9,
 #endif
+    USECASE_AUDIO_DIRECT_PCM_OFFLOAD,
 };
 
 #define STRING_TO_ENUM(string) { #string, string }
@@ -307,6 +310,7 @@
         format == AUDIO_FORMAT_AAC_HE_V2 ||
         format == AUDIO_FORMAT_PCM_16_BIT_OFFLOAD ||
         format == AUDIO_FORMAT_PCM_24_BIT_OFFLOAD ||
+        format == AUDIO_FORMAT_PCM_16_BIT ||
         format == AUDIO_FORMAT_FLAC ||
         format == AUDIO_FORMAT_ALAC ||
         format == AUDIO_FORMAT_APE ||
@@ -330,6 +334,7 @@
         id = SND_AUDIOCODEC_AAC;
         break;
     case AUDIO_FORMAT_PCM_OFFLOAD:
+    case AUDIO_FORMAT_PCM:
         id = SND_AUDIOCODEC_PCM;
         break;
     case AUDIO_FORMAT_FLAC:
@@ -2774,7 +2779,7 @@
 
     if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
              (SND_CARD_STATE_OFFLINE == get_snd_card_state(adev))) {
-        ALOGE(" sound card is not active rejecting compress output open request");
+        ALOGE("sound card is not active rejecting compress output open request");
         return -EINVAL;
     }
 
@@ -2844,7 +2849,9 @@
                   __func__, ret);
             goto error_open;
         }
-    } else if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
+    } else if ((out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) ||
+               (out->flags & AUDIO_OUTPUT_FLAG_DIRECT_PCM)) {
+
         if (config->offload_info.version != AUDIO_INFO_INITIALIZER.version ||
             config->offload_info.size != AUDIO_INFO_INITIALIZER.size) {
             ALOGE("%s: Unsupported Offload information", __func__);
@@ -2865,7 +2872,7 @@
 
         if (!is_supported_format(config->offload_info.format) &&
                 !audio_extn_is_dolby_format(config->offload_info.format)) {
-            ALOGE("%s: Unsupported audio format", __func__);
+            ALOGE("%s: Unsupported audio format %x " , __func__, config->offload_info.format);
             ret = -EINVAL;
             goto error_open;
         }
@@ -2878,7 +2885,13 @@
             goto error_open;
         }
 
-        out->usecase = get_offload_usecase(adev);
+        if (out->flags & AUDIO_OUTPUT_FLAG_DIRECT_PCM) {
+            ALOGV("%s:: inserting DIRECT_PCM _USECASE", __func__);
+            out->usecase = USECASE_AUDIO_DIRECT_PCM_OFFLOAD;
+        } else {
+            ALOGV("%s:: inserting OFFLOAD_USECASE", __func__);
+            out->usecase = get_offload_usecase(adev);
+        }
         if (config->offload_info.channel_mask)
             out->channel_mask = config->offload_info.channel_mask;
         else if (config->channel_mask) {
@@ -2902,7 +2915,9 @@
         else
             out->compr_config.codec->id =
                 get_snd_codec_id(config->offload_info.format);
-        if ((config->offload_info.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_PCM_OFFLOAD) {
+
+        if (((config->offload_info.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_PCM_OFFLOAD)||
+             ((config->offload_info.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_PCM)) {
             out->compr_config.fragment_size =
                platform_get_pcm_offload_buffer_size(&config->offload_info);
         } else if (audio_extn_dolby_is_passthrough_stream(out->flags)) {
@@ -2928,8 +2943,10 @@
             out->compr_config.codec->format = SND_AUDIOSTREAMFORMAT_RAW;
         if (config->offload_info.format == AUDIO_FORMAT_PCM_16_BIT_OFFLOAD)
             out->compr_config.codec->format = SNDRV_PCM_FORMAT_S16_LE;
-        if(config->offload_info.format == AUDIO_FORMAT_PCM_24_BIT_OFFLOAD)
+        if (config->offload_info.format == AUDIO_FORMAT_PCM_24_BIT_OFFLOAD)
             out->compr_config.codec->format = SNDRV_PCM_FORMAT_S24_LE;
+        if (config->offload_info.format == AUDIO_FORMAT_PCM_16_BIT)
+            out->compr_config.codec->format = SNDRV_PCM_FORMAT_S16_LE;
 
         if (out->bit_width == 24) {
             out->compr_config.codec->format = SNDRV_PCM_FORMAT_S24_LE;
@@ -3070,7 +3087,7 @@
 
     *stream_out = &out->stream;
     ALOGD("%s: Stream (%p) picks up usecase (%s)", __func__, &out->stream,
-        use_case_table[out->usecase]);
+           use_case_table[out->usecase]);
 
     if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)
         audio_extn_dts_notify_playback_state(out->usecase, 0, out->sample_rate,