audio hal: Reverse speaker LR channels at 180 rotation

RT5677 I2S2 ADC3 data swap control is used to swap LR
when the device is rotated 180 degrees. RT5677 I2S2 only
goes to MAX98357A so the swap does not affect headphones.

Verifed speaker and headphone playback with device
rotation at 0/90/180/270.

Bug: 31060805

Change-Id: I3ad3925a94e92fe1b8f086ad2ebbf767aa0d7401
Signed-off-by: Ben Zhang <benzh@google.com>
(cherry picked from commit a758f09e4cadc7f0c9597b07cab8dc617d458fcf)
diff --git a/audio/hal/audio_hw.c b/audio/hal/audio_hw.c
index 0fddcff..70a9a41 100644
--- a/audio/hal/audio_hw.c
+++ b/audio/hal/audio_hw.c
@@ -2867,15 +2867,16 @@
     if (ret >= 0) {
         bool reverse_speakers = false;
         switch(val) {
-        /* FIXME: note that the code below assumes that the speakers are in the correct placement
-             relative to the user when the device is rotated 90deg from its default rotation. This
-             assumption is device-specific, not platform-specific like this code. */
-        case 270:
+        /* Assume 0deg rotation means the front camera is up with the usb port
+         * on the lower left when the user is facing the screen. This assumption
+         * is device-specific, not platform-specific like this code.
+         */
+        case 180:
             reverse_speakers = true;
             break;
         case 0:
         case 90:
-        case 180:
+        case 270:
             break;
         default:
             ALOGE("%s: unexpected rotation of %d", __func__, val);
@@ -2883,17 +2884,12 @@
         pthread_mutex_lock(&adev->lock);
         if (adev->speaker_lr_swap != reverse_speakers) {
             adev->speaker_lr_swap = reverse_speakers;
-            /* only update the selected device if there is active pcm playback */
-            struct audio_usecase *usecase;
-            struct listnode *node;
-            list_for_each(node, &adev->usecase_list) {
-                usecase = node_to_item(node, struct audio_usecase, adev_list_node);
-                if (usecase->type == PCM_PLAYBACK) {
-                    select_devices(adev, usecase->id);
-                    /* TODO(dgreid) speaker flip */
-                    break;
-                }
-            }
+            struct mixer_card *mixer_card;
+            mixer_card = adev_get_mixer_for_card(adev, SOUND_CARD);
+            if (mixer_card)
+                audio_route_apply_and_update_path(mixer_card->audio_route,
+                        reverse_speakers ? "speaker-lr-reverse" :
+                                           "speaker-lr-normal");
         }
         pthread_mutex_unlock(&adev->lock);
     }
diff --git a/mixer_paths_0.xml b/mixer_paths_0.xml
index cd79b20..cf6eeba 100644
--- a/mixer_paths_0.xml
+++ b/mixer_paths_0.xml
@@ -139,4 +139,12 @@
     <ctl name="Int Spk Switch" value="1"/>
     <ctl name="Headphone Jack Switch" value="1"/>
   </path>
+
+  <path name="speaker-lr-normal">
+    <ctl name="IF2 ADC3 Swap Mux" value="L/R"/>
+  </path>
+
+  <path name="speaker-lr-reverse">
+    <ctl name="IF2 ADC3 Swap Mux" value="R/L"/>
+  </path>
 </mixer>