am c750b06b: Merge "audio: add bluetooth sco support" into jb-mr1-dev
* commit 'c750b06b27d22a70658ef681f86db0a202f8a832':
audio: add bluetooth sco support
diff --git a/audio/audio_hw.c b/audio/audio_hw.c
index 926741a..b7656af 100644
--- a/audio/audio_hw.c
+++ b/audio/audio_hw.c
@@ -43,6 +43,8 @@
#define PCM_TOTAL 2
#define PCM_DEVICE 0
+#define PCM_DEVICE_VOICE 2
+#define PCM_DEVICE_SCO 3
/* duration in ms of volume ramp applied when starting capture to remove plop */
#define CAPTURE_START_RAMP_MS 100
@@ -55,6 +57,14 @@
.format = PCM_FORMAT_S16_LE,
};
+struct pcm_config pcm_config_sco = {
+ .channels = 1,
+ .rate = 8000,
+ .period_size = 128,
+ .period_count = 2,
+ .format = PCM_FORMAT_S16_LE,
+};
+
struct audio_device {
struct audio_hw_device hw_device;
@@ -65,6 +75,10 @@
audio_source_t input_source;
int cur_route_id; /* current route ID: combination of input source
* and output device IDs */
+ struct pcm *pcm_voice_out;
+ struct pcm *pcm_sco_out;
+ struct pcm *pcm_voice_in;
+ struct pcm *pcm_sco_in;
};
struct stream_out {
@@ -336,7 +350,8 @@
if (out->device & (AUDIO_DEVICE_OUT_SPEAKER |
AUDIO_DEVICE_OUT_WIRED_HEADSET |
AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
- AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
+ AUDIO_DEVICE_OUT_AUX_DIGITAL |
+ AUDIO_DEVICE_OUT_ALL_SCO)) {
out->pcm[PCM_CARD] = pcm_open(PCM_CARD, PCM_DEVICE,
PCM_OUT, &pcm_config);
@@ -396,6 +411,62 @@
return 0;
}
+/* must be called with the hw device mutex locked, OK to hold other mutexes */
+static void start_bt_sco(struct audio_device *adev) {
+ adev->pcm_voice_out = pcm_open(PCM_CARD, PCM_DEVICE_VOICE, PCM_OUT,
+ &pcm_config_sco);
+ if (adev->pcm_voice_out && !pcm_is_ready(adev->pcm_voice_out)) {
+ ALOGE("pcm_open(VOICE_OUT) failed: %s", pcm_get_error(adev->pcm_voice_out));
+ goto err_voice_out;
+ }
+ adev->pcm_sco_out = pcm_open(PCM_CARD, PCM_DEVICE_SCO, PCM_OUT,
+ &pcm_config_sco);
+ if (adev->pcm_sco_out && !pcm_is_ready(adev->pcm_sco_out)) {
+ ALOGE("pcm_open(SCO_OUT) failed: %s", pcm_get_error(adev->pcm_sco_out));
+ goto err_sco_out;
+ }
+ adev->pcm_voice_in = pcm_open(PCM_CARD, PCM_DEVICE_VOICE, PCM_IN,
+ &pcm_config_sco);
+ if (adev->pcm_voice_in && !pcm_is_ready(adev->pcm_voice_in)) {
+ ALOGE("pcm_open(VOICE_IN) failed: %s", pcm_get_error(adev->pcm_voice_in));
+ goto err_voice_in;
+ }
+ adev->pcm_sco_in = pcm_open(PCM_CARD, PCM_DEVICE_SCO, PCM_IN,
+ &pcm_config_sco);
+ if (adev->pcm_sco_in && !pcm_is_ready(adev->pcm_sco_in)) {
+ ALOGE("pcm_open(SCO_IN) failed: %s", pcm_get_error(adev->pcm_sco_in));
+ goto err_sco_in;
+ }
+
+ pcm_start(adev->pcm_voice_out);
+ pcm_start(adev->pcm_sco_out);
+ pcm_start(adev->pcm_voice_in);
+ pcm_start(adev->pcm_sco_in);
+
+ return;
+
+err_sco_in:
+ pcm_close(adev->pcm_sco_in);
+err_voice_in:
+ pcm_close(adev->pcm_voice_in);
+err_sco_out:
+ pcm_close(adev->pcm_sco_out);
+err_voice_out:
+ pcm_close(adev->pcm_voice_out);
+}
+
+/* must be called with the hw device mutex locked, OK to hold other mutexes */
+static void stop_bt_sco(struct audio_device *adev) {
+ pcm_stop(adev->pcm_voice_out);
+ pcm_stop(adev->pcm_sco_out);
+ pcm_stop(adev->pcm_voice_in);
+ pcm_stop(adev->pcm_sco_in);
+
+ pcm_close(adev->pcm_voice_out);
+ pcm_close(adev->pcm_sco_out);
+ pcm_close(adev->pcm_voice_in);
+ pcm_close(adev->pcm_sco_in);
+}
static size_t get_input_buffer_size(unsigned int sample_rate,
audio_format_t format,
@@ -613,6 +684,15 @@
do_out_standby(out);
}
+ /* Start/stop the BT SCO stream */
+ if ((val & AUDIO_DEVICE_OUT_ALL_SCO) ^
+ (adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO)) {
+ if (val & AUDIO_DEVICE_OUT_ALL_SCO)
+ start_bt_sco(adev);
+ else
+ stop_bt_sco(adev);
+ }
+
out->device = val;
if (!out->standby) {
adev->out_device = out->device;
diff --git a/mixer_paths.xml b/mixer_paths.xml
index c7c16fd..57da918 100644
--- a/mixer_paths.xml
+++ b/mixer_paths.xml
@@ -3,6 +3,7 @@
<ctl name="DAC1R Mixer AIF1.1 Switch" value="0" />
<ctl name="DAC1L Mixer AIF1.1 Switch" value="0" />
<ctl name="DAC1 Switch" value="0" />
+ <ctl name="DAC2 Switch" value="0" />
<ctl name="AIF1DRC1 Mode" value="Default" />
<ctl name="AIF1DAC1 DRC Switch" value="0" />
@@ -39,8 +40,15 @@
<ctl name="AIF2DACL Mux" value="AIF3" />
<ctl name="AIF2DACR Mux" value="AIF3" />
- <ctl name="AIF3ADC Mux" value="Mono PCM" />
- <ctl name="Mono PCM Out Mux" value="AIF2ADCL" />
+ <ctl name="AIF2DAC Mux" value="AIF3DACDAT" />
+ <ctl name="AIF3ADC Mux" value="AIF2ADCDAT" />
+
+ <ctl name="AIF1ADC1L Mixer AIF2 Switch" value="0" />
+ <ctl name="AIF1ADC1R Mixer AIF2 Switch" value="0" />
+ <ctl name="AIF1ADC2L Mixer AIF2 Switch" value="0" />
+ <ctl name="AIF1ADC2R Mixer AIF2 Switch" value="0" />
+ <ctl name="AIF1ADC1L Mixer ADC/DMIC Switch" value="0" />
+ <ctl name="AIF1ADC1R Mixer ADC/DMIC Switch" value="0" />
<!-- These are commonly used control sequences -->
<path name="dac1">
@@ -49,6 +57,12 @@
<ctl name="DAC1 Switch" value="1" />
</path>
+ <path name="dac2">
+ <ctl name="AIF2DAC2L Mixer AIF1.1 Switch" value="1" />
+ <ctl name="AIF2DAC2R Mixer AIF1.1 Switch" value="1" />
+ <ctl name="DAC2 Switch" value="1" />
+ </path>
+
<path name="eq-speaker">
<ctl name="AIF1DAC1 EQ Switch" value="1" />
<ctl name="AIF1DAC1 EQ1 Volume" value="3" />
@@ -87,15 +101,13 @@
<path name="adc-to-aif1adc">
<ctl name="AIF1ADC1L Mixer ADC/DMIC Switch" value="1" />
<ctl name="AIF1ADC1R Mixer ADC/DMIC Switch" value="1" />
- <ctl name="AIF1ADC1L Mixer AIF2 Switch" value="0" />
- <ctl name="AIF1ADC1R Mixer AIF2 Switch" value="0" />
</path>
<path name="aif2-to-aif1adc">
- <ctl name="AIF1ADC1L Mixer ADC/DMIC Switch" value="0" />
- <ctl name="AIF1ADC1R Mixer ADC/DMIC Switch" value="0" />
<ctl name="AIF1ADC1L Mixer AIF2 Switch" value="1" />
<ctl name="AIF1ADC1R Mixer AIF2 Switch" value="1" />
+ <ctl name="AIF1ADC2L Mixer AIF2 Switch" value="1" />
+ <ctl name="AIF1ADC2R Mixer AIF2 Switch" value="1" />
</path>
<path name="main-mic">
@@ -189,8 +201,7 @@
</path>
<path name="bt-sco-headset">
- <ctl name="AIF2DAC2L Mixer AIF1.1 Switch" value="1" />
- <ctl name="AIF2DAC2R Mixer AIF1.1 Switch" value="1" />
+ <path name="dac2" />
</path>
<!-- Capture paths -->
@@ -233,6 +244,10 @@
<ctl name="AIF1ADC1 HPF Mode" value="HiFi" />
</path>
+ <path name="bt-sco-mic">
+ <path name="aif2-to-aif1adc" />
+ </path>
+
<!-- TODO headset paths not properly configured yet -->
<path name="voice-rec-headset-mic">
<path name="headset-mic" />
@@ -246,8 +261,4 @@
<ctl name="AIF1ADC1 HPF Mode" value="Voice 1" />
</path>
- <path name="bt-sco-mic">
- <path name="aif2-to-aif1adc" />
- </path>
-
</mixer>