Merge "hal: Support for multi-channel for AFE_PROXY"
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index 176df8c..3f457d2 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -143,6 +143,77 @@
#define audio_extn_set_afe_proxy_parameters(parms) (0)
#define audio_extn_get_afe_proxy_parameters(query, reply) (0)
#else
+/* Front left channel. */
+#define PCM_CHANNEL_FL 1
+
+/* Front right channel. */
+#define PCM_CHANNEL_FR 2
+
+/* Front center channel. */
+#define PCM_CHANNEL_FC 3
+
+/* Left surround channel.*/
+#define PCM_CHANNEL_LS 4
+
+/* Right surround channel.*/
+#define PCM_CHANNEL_RS 5
+
+/* Low frequency effect channel. */
+#define PCM_CHANNEL_LFE 6
+
+/* Left back channel; Rear left channel. */
+#define PCM_CHANNEL_LB 8
+
+/* Right back channel; Rear right channel. */
+#define PCM_CHANNEL_RB 9
+
+static int32_t afe_proxy_set_channel_mapping(struct audio_device *adev,
+ int channel_count)
+{
+ struct mixer_ctl *ctl;
+ const char *mixer_ctl_name = "Playback Channel Map";
+ int set_values[8] = {0};
+ int ret;
+ ALOGV("%s channel_count:%d",__func__, channel_count);
+
+ switch (channel_count) {
+ case 6:
+ set_values[0] = PCM_CHANNEL_FL;
+ set_values[1] = PCM_CHANNEL_FR;
+ set_values[2] = PCM_CHANNEL_FC;
+ set_values[3] = PCM_CHANNEL_LFE;
+ set_values[4] = PCM_CHANNEL_LS;
+ set_values[5] = PCM_CHANNEL_RS;
+ break;
+ case 8:
+ set_values[0] = PCM_CHANNEL_FL;
+ set_values[1] = PCM_CHANNEL_FR;
+ set_values[2] = PCM_CHANNEL_FC;
+ set_values[3] = PCM_CHANNEL_LFE;
+ set_values[4] = PCM_CHANNEL_LS;
+ set_values[5] = PCM_CHANNEL_RS;
+ set_values[6] = PCM_CHANNEL_LB;
+ set_values[7] = PCM_CHANNEL_RB;
+ break;
+ default:
+ ALOGE("unsupported channels(%d) for setting channel map",
+ channel_count);
+ return -EINVAL;
+ }
+
+ ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ if (!ctl) {
+ ALOGE("%s: Could not get ctl for mixer cmd - %s",
+ __func__, mixer_ctl_name);
+ return -EINVAL;
+ }
+ ALOGV("AFE: set mapping(%d %d %d %d %d %d %d %d) for channel:%d",
+ set_values[0], set_values[1], set_values[2], set_values[3], set_values[4],
+ set_values[5], set_values[6], set_values[7], channel_count);
+ ret = mixer_ctl_set_array(ctl, set_values, channel_count);
+ return ret;
+}
+
int32_t audio_extn_set_afe_proxy_channel_mixer(struct audio_device *adev)
{
int32_t ret = 0;
@@ -150,7 +221,6 @@
struct mixer_ctl *ctl = NULL;
const char *mixer_ctl_name = "PROXY_RX Channels";
-
ALOGD("%s: entry", __func__);
/* use the existing channel count set by hardware params to
configure the back end for stereo as usb/a2dp would be
@@ -177,6 +247,11 @@
}
mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);
+ if (aextnmod.proxy_channel_num == 6 ||
+ aextnmod.proxy_channel_num == 8)
+ ret = afe_proxy_set_channel_mapping(adev,
+ aextnmod.proxy_channel_num);
+
ALOGD("%s: exit", __func__);
return ret;
}
@@ -215,6 +290,34 @@
return 0;
}
+
+/* must be called with hw device mutex locked */
+int32_t audio_extn_read_afe_proxy_channel_masks(struct stream_out *out)
+{
+ int ret = 0;
+ int channels = aextnmod.proxy_channel_num;
+
+ switch (channels) {
+ /*
+ * Do not handle stereo output in Multi-channel cases
+ * Stereo case is handled in normal playback path
+ */
+ case 6:
+ ALOGV("%s: AFE PROXY supports 5.1", __func__);
+ out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_5POINT1;
+ break;
+ case 8:
+ ALOGV("%s: AFE PROXY supports 5.1 and 7.1 channels", __func__);
+ out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_5POINT1;
+ out->supported_channel_masks[1] = AUDIO_CHANNEL_OUT_7POINT1;
+ break;
+ default:
+ ALOGE("AFE PROXY does not support multi channel playback");
+ ret = -ENOSYS;
+ break;
+ }
+ return ret;
+}
#endif /* AFE_PROXY_ENABLED */
void audio_extn_set_parameters(struct audio_device *adev,
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index e6db5c1..c6d06df 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -41,8 +41,10 @@
#ifndef AFE_PROXY_ENABLED
#define audio_extn_set_afe_proxy_channel_mixer(adev) (0)
+#define audio_extn_read_afe_proxy_channel_masks(out) (0)
#else
int32_t audio_extn_set_afe_proxy_channel_mixer(struct audio_device *adev);
+int32_t audio_extn_read_afe_proxy_channel_masks(struct stream_out *out);
#endif
#ifndef USB_HEADSET_ENABLED
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 937c79b..b8195b4 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -2008,10 +2008,16 @@
out->handle = handle;
/* Init use case and pcm_config */
- if (out->flags == AUDIO_OUTPUT_FLAG_DIRECT &&
- out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
+ if ((out->flags == AUDIO_OUTPUT_FLAG_DIRECT) &&
+ (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL ||
+ out->devices & AUDIO_DEVICE_OUT_PROXY)) {
+
pthread_mutex_lock(&adev->lock);
- ret = read_hdmi_channel_masks(out);
+ if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)
+ ret = read_hdmi_channel_masks(out);
+
+ if (out->devices & AUDIO_DEVICE_OUT_PROXY)
+ ret = audio_extn_read_afe_proxy_channel_masks(out);
pthread_mutex_unlock(&adev->lock);
if (ret != 0)
goto error_open;