blob: ad8f8a483ef882cfc1b850ad4e3a7d7f66678871 [file] [log] [blame]
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -08001/*
Leena Winterrowdf98e42f2016-01-26 13:47:36 -08002 * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -08003 * Not a Contribution.
4 *
5 * Copyright (C) 2010 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20#define LOG_TAG "audio_hw_dolby"
Ashish Jain8ec50472014-10-16 13:56:28 +053021//#define LOG_NDEBUG 0
22//#define LOG_NDDEBUG 0
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -080023#include <errno.h>
24#include <cutils/properties.h>
25#include <stdlib.h>
26#include <dlfcn.h>
27#include <cutils/str_parms.h>
28#include <cutils/log.h>
29
30#include "audio_hw.h"
31#include "platform.h"
32#include "platform_api.h"
33#include "audio_extn.h"
34#include "sound/compress_params.h"
Ashish Jainedb6a912014-10-16 13:56:28 +053035#include "sound/devdep_params.h"
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -080036
37#ifdef DS1_DOLBY_DDP_ENABLED
38
39#define AUDIO_PARAMETER_DDP_DEV "ddp_device"
40#define AUDIO_PARAMETER_DDP_CH_CAP "ddp_chancap"
41#define AUDIO_PARAMETER_DDP_MAX_OUT_CHAN "ddp_maxoutchan"
42#define AUDIO_PARAMETER_DDP_OUT_MODE "ddp_outmode"
43#define AUDIO_PARAMETER_DDP_OUT_LFE_ON "ddp_outlfeon"
44#define AUDIO_PARAMETER_DDP_COMP_MODE "ddp_compmode"
45#define AUDIO_PARAMETER_DDP_STEREO_MODE "ddp_stereomode"
46
47#define PARAM_ID_MAX_OUTPUT_CHANNELS 0x00010DE2
48#define PARAM_ID_CTL_RUNNING_MODE 0x0
49#define PARAM_ID_CTL_ERROR_CONCEAL 0x00010DE3
50#define PARAM_ID_CTL_ERROR_MAX_RPTS 0x00010DE4
51#define PARAM_ID_CNV_ERROR_CONCEAL 0x00010DE5
52#define PARAM_ID_CTL_SUBSTREAM_SELECT 0x00010DE6
53#define PARAM_ID_CTL_INPUT_MODE 0x0
54#define PARAM_ID_OUT_CTL_OUTMODE 0x00010DE0
55#define PARAM_ID_OUT_CTL_OUTLFE_ON 0x00010DE1
56#define PARAM_ID_OUT_CTL_COMPMODE 0x00010D74
57#define PARAM_ID_OUT_CTL_STEREO_MODE 0x00010D76
58#define PARAM_ID_OUT_CTL_DUAL_MODE 0x00010D75
59#define PARAM_ID_OUT_CTL_DRCSCALE_HIGH 0x00010D7A
60#define PARAM_ID_OUT_CTL_DRCSCALE_LOW 0x00010D79
61#define PARAM_ID_OUT_CTL_OUT_PCMSCALE 0x00010D78
62#define PARAM_ID_OUT_CTL_MDCT_BANDLIMIT 0x00010DE7
63#define PARAM_ID_OUT_CTL_DRC_SUPPRESS 0x00010DE8
64
65/* DS1-DDP Endp Params */
66#define DDP_ENDP_NUM_PARAMS 17
Mingming Yin0acba992014-06-02 22:38:35 -070067#define DDP_ENDP_NUM_DEVICES 21
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -080068static int ddp_endp_params_id[DDP_ENDP_NUM_PARAMS] = {
69 PARAM_ID_MAX_OUTPUT_CHANNELS, PARAM_ID_CTL_RUNNING_MODE,
70 PARAM_ID_CTL_ERROR_CONCEAL, PARAM_ID_CTL_ERROR_MAX_RPTS,
71 PARAM_ID_CNV_ERROR_CONCEAL, PARAM_ID_CTL_SUBSTREAM_SELECT,
72 PARAM_ID_CTL_INPUT_MODE, PARAM_ID_OUT_CTL_OUTMODE,
73 PARAM_ID_OUT_CTL_OUTLFE_ON, PARAM_ID_OUT_CTL_COMPMODE,
74 PARAM_ID_OUT_CTL_STEREO_MODE, PARAM_ID_OUT_CTL_DUAL_MODE,
75 PARAM_ID_OUT_CTL_DRCSCALE_HIGH, PARAM_ID_OUT_CTL_DRCSCALE_LOW,
76 PARAM_ID_OUT_CTL_OUT_PCMSCALE, PARAM_ID_OUT_CTL_MDCT_BANDLIMIT,
77 PARAM_ID_OUT_CTL_DRC_SUPPRESS
78};
79
80static struct ddp_endp_params {
81 int device;
82 int dev_ch_cap;
83 int param_val[DDP_ENDP_NUM_PARAMS];
84 bool is_param_valid[DDP_ENDP_NUM_PARAMS];
85} ddp_endp_params[DDP_ENDP_NUM_DEVICES] = {
86 {AUDIO_DEVICE_OUT_EARPIECE, 2,
87 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
88 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 } },
89 {AUDIO_DEVICE_OUT_SPEAKER, 2,
90 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
91 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
92 {AUDIO_DEVICE_OUT_WIRED_HEADSET, 2,
93 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
94 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
95 {AUDIO_DEVICE_OUT_WIRED_HEADPHONE, 2,
96 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
97 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
98 {AUDIO_DEVICE_OUT_BLUETOOTH_SCO, 2,
99 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
100 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
101 {AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET, 2,
102 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
103 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
104 {AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT, 2,
105 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
106 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
107 {AUDIO_DEVICE_OUT_BLUETOOTH_A2DP, 2,
108 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
109 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
110 {AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES, 2,
111 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
112 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
113 {AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, 2,
114 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
115 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
116 {AUDIO_DEVICE_OUT_AUX_DIGITAL, 2,
117 {8, 0, 0, 0, 0, 0, 0, 21, 1, 2, 0, 0, 0, 0, 0, 0, 0},
118 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
119 {AUDIO_DEVICE_OUT_AUX_DIGITAL, 6,
120 {8, 0, 0, 0, 0, 0, 0, 21, 1, 2, 0, 0, 0, 0, 0, 0, 0},
121 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
122 {AUDIO_DEVICE_OUT_AUX_DIGITAL, 8,
123 {8, 0, 0, 0, 0, 0, 0, 21, 1, 2, 0, 0, 0, 0, 0, 0, 0},
124 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
125 {AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET, 2,
126 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
127 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
128 {AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET, 2,
129 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
130 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
131 {AUDIO_DEVICE_OUT_USB_ACCESSORY, 2,
132 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
133 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
134 {AUDIO_DEVICE_OUT_USB_DEVICE, 2,
135 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
136 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
137 {AUDIO_DEVICE_OUT_FM, 2,
138 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
139 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
140 {AUDIO_DEVICE_OUT_FM_TX, 2,
141 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
142 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800143 {AUDIO_DEVICE_OUT_PROXY, 2,
Krishnankutty Kolathappilly0b2de1c2014-02-14 14:45:49 -0800144 {8, 0, 0, 0, 0, 0, 0, 21, 1, 2, 0, 0, 0, 0, 0, 0, 0},
145 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
146 {AUDIO_DEVICE_OUT_PROXY, 6,
147 {8, 0, 0, 0, 0, 0, 0, 21, 1, 2, 0, 0, 0, 0, 0, 0, 0},
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800148 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
149};
150
151int update_ddp_endp_table(int device, int dev_ch_cap, int param_id,
152 int param_val)
153{
154 int idx = 0;
155 int param_idx = 0;
156 ALOGV("%s: dev 0x%x dev_ch_cap %d param_id 0x%x param_val %d",
157 __func__, device, dev_ch_cap , param_id, param_val);
158
159 for(idx=0; idx<DDP_ENDP_NUM_DEVICES; idx++) {
160 if(ddp_endp_params[idx].device == device) {
161 if(ddp_endp_params[idx].dev_ch_cap == dev_ch_cap) {
162 break;
163 }
164 }
165 }
166
167 if(idx>=DDP_ENDP_NUM_DEVICES) {
168 ALOGE("%s: device not available in DDP endp config table", __func__);
169 return -EINVAL;
170 }
171
172 for(param_idx=0; param_idx<DDP_ENDP_NUM_PARAMS; param_idx++) {
173 if (ddp_endp_params_id[param_idx] == param_id) {
174 break;
175 }
176 }
177
178 if(param_idx>=DDP_ENDP_NUM_PARAMS) {
179 ALOGE("param not available in DDP endp config table");
180 return -EINVAL;
181 }
182
183 ALOGV("ddp_endp_params[%d].param_val[%d] = %d", idx, param_idx, param_val);
184 ddp_endp_params[idx].param_val[param_idx] = param_val;
185 return 0;
186}
187
188void send_ddp_endp_params_stream(struct stream_out *out,
189 int device, int dev_ch_cap,
Ravi Kumar Alamandabdf14162014-09-05 16:14:17 -0700190 bool set_cache __unused)
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800191{
192 int idx, i;
193 int ddp_endp_params_data[2*DDP_ENDP_NUM_PARAMS + 1];
194 int length = 0;
195 for(idx=0; idx<DDP_ENDP_NUM_DEVICES; idx++) {
196 if(ddp_endp_params[idx].device & device) {
197 if(ddp_endp_params[idx].dev_ch_cap == dev_ch_cap) {
198 break;
199 }
200 }
201 }
202 if(idx>=DDP_ENDP_NUM_DEVICES) {
203 ALOGE("device not available in DDP endp config table");
204 return;
205 }
206
207 length += 1; /* offset 0 is for num of parameter. increase offset by 1 */
208 for (i=0; i<DDP_ENDP_NUM_PARAMS; i++) {
209 if(ddp_endp_params[idx].is_param_valid[i]) {
210 ddp_endp_params_data[length++] = ddp_endp_params_id[i];
211 ddp_endp_params_data[length++] = ddp_endp_params[idx].param_val[i];
212 }
213 }
214 ddp_endp_params_data[0] = (length-1)/2;
215 if(length) {
216 char mixer_ctl_name[128];
217 struct audio_device *adev = out->dev;
218 struct mixer_ctl *ctl;
219 int pcm_device_id = platform_get_pcm_device_id(out->usecase,
220 PCM_PLAYBACK);
221 snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
222 "Audio Stream %d Dec Params", pcm_device_id);
223 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
224 if (!ctl) {
225 ALOGE("%s: Could not get ctl for mixer cmd - %s",
226 __func__, mixer_ctl_name);
227 return;
228 }
229 mixer_ctl_set_array(ctl, ddp_endp_params_data, length);
230 }
231 return;
232}
233
234void send_ddp_endp_params(struct audio_device *adev,
235 int ddp_dev, int dev_ch_cap)
236{
237 struct listnode *node;
238 struct audio_usecase *usecase;
239
240 list_for_each(node, &adev->usecase_list) {
241 usecase = node_to_item(node, struct audio_usecase, list);
242 if ((usecase->type == PCM_PLAYBACK) &&
243 (usecase->devices & ddp_dev) &&
244 (usecase->stream.out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
245 ((usecase->stream.out->format == AUDIO_FORMAT_AC3) ||
Pradnya Chaphekar659affa2014-09-09 09:49:10 -0700246 (usecase->stream.out->format == AUDIO_FORMAT_E_AC3) ||
247 (usecase->stream.out->format == AUDIO_FORMAT_E_AC3_JOC))) {
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800248 send_ddp_endp_params_stream(usecase->stream.out, ddp_dev,
249 dev_ch_cap, false /* set cache */);
250 }
251 }
252}
253
254void audio_extn_dolby_send_ddp_endp_params(struct audio_device *adev)
255{
256 struct listnode *node;
257 struct audio_usecase *usecase;
258 list_for_each(node, &adev->usecase_list) {
259 usecase = node_to_item(node, struct audio_usecase, list);
260 if ((usecase->type == PCM_PLAYBACK) &&
261 (usecase->devices & AUDIO_DEVICE_OUT_ALL) &&
262 (usecase->stream.out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
263 ((usecase->stream.out->format == AUDIO_FORMAT_AC3) ||
Pradnya Chaphekar659affa2014-09-09 09:49:10 -0700264 (usecase->stream.out->format == AUDIO_FORMAT_E_AC3) ||
265 (usecase->stream.out->format == AUDIO_FORMAT_E_AC3_JOC))) {
Krishnankutty Kolathappilly0b2de1c2014-02-14 14:45:49 -0800266 /*
267 * Use wfd /hdmi sink channel cap for dolby params if device is wfd
268 * or hdmi. Otherwise use stereo configuration
269 */
270 int channel_cap = usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL ?
271 adev->cur_hdmi_channels :
272 usecase->devices & AUDIO_DEVICE_OUT_PROXY ?
273 adev->cur_wfd_channels : 2;
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800274 send_ddp_endp_params_stream(usecase->stream.out, usecase->devices,
Krishnankutty Kolathappilly0b2de1c2014-02-14 14:45:49 -0800275 channel_cap, false /* set cache */);
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800276 }
277 }
278}
279
280void audio_extn_ddp_set_parameters(struct audio_device *adev,
281 struct str_parms *parms)
282{
283 int ddp_dev, dev_ch_cap;
284 int val, ret;
285 char value[32]={0};
Dhananjay Kumar89ea3bd2014-04-29 15:45:57 +0530286
287 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SND_CARD_STATUS, value,
288 sizeof(value));
289 if (ret >= 0) {
290 char *snd_card_status = value + 2;
291 if (strncmp(snd_card_status, "ONLINE", sizeof("ONLINE")) == 0)
292 audio_extn_dolby_set_license(adev);
293 }
294
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800295 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DDP_DEV, value,
296 sizeof(value));
297 if (ret >= 0) {
298 ddp_dev = atoi(value);
299 if (!(AUDIO_DEVICE_OUT_ALL & ddp_dev))
300 return;
301 } else
302 return;
303
304 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DDP_CH_CAP, value,
305 sizeof(value));
306 if (ret >= 0) {
307 dev_ch_cap = atoi(value);
308 if ((dev_ch_cap != 2) && (dev_ch_cap != 6) && (dev_ch_cap != 8))
309 return;
310 } else
311 return;
312
313 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DDP_MAX_OUT_CHAN, value,
314 sizeof(value));
315 if (ret >= 0) {
316 val = atoi(value);
317 update_ddp_endp_table(ddp_dev, dev_ch_cap,
318 PARAM_ID_MAX_OUTPUT_CHANNELS, val);
319 }
320
321 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DDP_OUT_MODE, value,
322 sizeof(value));
323 if (ret >= 0) {
324 val = atoi(value);
325 update_ddp_endp_table(ddp_dev, dev_ch_cap,
326 PARAM_ID_OUT_CTL_OUTMODE, val);
327 }
328
329 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DDP_OUT_LFE_ON, value,
330 sizeof(value));
331 if (ret >= 0) {
332 val = atoi(value);
333 update_ddp_endp_table(ddp_dev, dev_ch_cap,
334 PARAM_ID_OUT_CTL_OUTLFE_ON, val);
335 }
336
337 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DDP_COMP_MODE, value,
338 sizeof(value));
339 if (ret >= 0) {
340 val = atoi(value);
341 update_ddp_endp_table(ddp_dev, dev_ch_cap,
342 PARAM_ID_OUT_CTL_COMPMODE, val);
343 }
344
345 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DDP_STEREO_MODE, value,
346 sizeof(value));
347 if (ret >= 0) {
348 val = atoi(value);
349 update_ddp_endp_table(ddp_dev, dev_ch_cap,
350 PARAM_ID_OUT_CTL_STEREO_MODE, val);
351 }
Krishnankutty Kolathappilly0b2de1c2014-02-14 14:45:49 -0800352 /* TODO: Do we need device channel caps here?
353 * We dont have that information as this is from dolby modules
354 */
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800355 send_ddp_endp_params(adev, ddp_dev, dev_ch_cap);
356}
Pradnya Chaphekar659affa2014-09-09 09:49:10 -0700357#endif /* DS1_DOLBY_DDP_ENABLED */
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800358
Pradnya Chaphekar659affa2014-09-09 09:49:10 -0700359#if defined(DS1_DOLBY_DDP_ENABLED) || defined(DS2_DOLBY_DAP_ENABLED)
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800360int audio_extn_dolby_get_snd_codec_id(struct audio_device *adev,
361 struct stream_out *out,
362 audio_format_t format)
363{
364 int id = 0;
Krishnankutty Kolathappilly0b2de1c2014-02-14 14:45:49 -0800365 /*
366 * Use wfd /hdmi sink channel cap for dolby params if device is wfd
367 * or hdmi. Otherwise use stereo configuration
368 */
369 int channel_cap = out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL ?
370 adev->cur_hdmi_channels :
371 out->devices & AUDIO_DEVICE_OUT_PROXY ?
372 adev->cur_wfd_channels : 2;
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800373
374 switch (format) {
375 case AUDIO_FORMAT_AC3:
376 id = SND_AUDIOCODEC_AC3;
Pradnya Chaphekar659affa2014-09-09 09:49:10 -0700377#ifdef DS1_DOLBY_DDP_ENABLED
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800378 send_ddp_endp_params_stream(out, out->devices,
Krishnankutty Kolathappilly0b2de1c2014-02-14 14:45:49 -0800379 channel_cap, true /* set_cache */);
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800380#endif
Pradnya Chaphekar659affa2014-09-09 09:49:10 -0700381 audio_extn_dolby_set_dmid(adev);
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800382 break;
Mingming Yinae3530f2014-07-03 16:50:18 -0700383 case AUDIO_FORMAT_E_AC3:
Pradnya Chaphekar659affa2014-09-09 09:49:10 -0700384 case AUDIO_FORMAT_E_AC3_JOC:
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800385 id = SND_AUDIOCODEC_EAC3;
Pradnya Chaphekar659affa2014-09-09 09:49:10 -0700386#ifdef DS1_DOLBY_DDP_ENABLED
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800387 send_ddp_endp_params_stream(out, out->devices,
Krishnankutty Kolathappilly0b2de1c2014-02-14 14:45:49 -0800388 channel_cap, true /* set_cache */);
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800389#endif
Pradnya Chaphekar659affa2014-09-09 09:49:10 -0700390 audio_extn_dolby_set_dmid(adev);
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800391 break;
392 default:
393 ALOGE("%s: Unsupported audio format :%x", __func__, format);
394 }
395
396 return id;
397}
398
399bool audio_extn_is_dolby_format(audio_format_t format)
400{
401 if (format == AUDIO_FORMAT_AC3 ||
Pradnya Chaphekar659affa2014-09-09 09:49:10 -0700402 format == AUDIO_FORMAT_E_AC3 ||
403 format == AUDIO_FORMAT_E_AC3_JOC)
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800404 return true;
405 else
406 return false;
407}
Pradnya Chaphekar659affa2014-09-09 09:49:10 -0700408#endif /* DS1_DOLBY_DDP_ENABLED || DS2_DOLBY_DAP_ENABLED */
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800409
Pradnya Chaphekar80a8cfb2014-10-20 16:17:01 -0700410#ifdef HDMI_PASSTHROUGH_ENABLED
Pradnya Chaphekar80a8cfb2014-10-20 16:17:01 -0700411bool audio_extn_dolby_is_passt_convert_supported(struct audio_device *adev,
412 struct stream_out *out) {
413
414 bool convert = false;
415 switch (out->format) {
416 case AUDIO_FORMAT_E_AC3:
417 case AUDIO_FORMAT_E_AC3_JOC:
418 if (!platform_is_edid_supported_format(adev->platform,
419 AUDIO_FORMAT_E_AC3)) {
420 ALOGV("%s:PASSTHROUGH_CONVERT supported", __func__);
421 convert = true;
422 }
423 break;
424 default:
425 ALOGE("%s: PASSTHROUGH_CONVERT not supported for format 0x%x",
426 __func__, out->format);
427 break;
428 }
429 ALOGE("%s: convert %d", __func__, convert);
430 return convert;
431}
432
433bool audio_extn_dolby_is_passt_supported(struct audio_device *adev,
434 struct stream_out *out) {
435 bool passt = false;
436 switch (out->format) {
437 case AUDIO_FORMAT_E_AC3:
438 if (platform_is_edid_supported_format(adev->platform, out->format)) {
439 ALOGV("%s:PASSTHROUGH supported for format %x",
440 __func__, out->format);
441 passt = true;
442 }
443 break;
444 case AUDIO_FORMAT_AC3:
445 if (platform_is_edid_supported_format(adev->platform, AUDIO_FORMAT_AC3)
446 || platform_is_edid_supported_format(adev->platform,
447 AUDIO_FORMAT_E_AC3)) {
448 ALOGV("%s:PASSTHROUGH supported for format %x",
449 __func__, out->format);
450 passt = true;
451 }
452 break;
453 case AUDIO_FORMAT_E_AC3_JOC:
454 /* Check for DDP capability in edid for JOC contents.*/
455 if (platform_is_edid_supported_format(adev->platform,
456 AUDIO_FORMAT_E_AC3)) {
457 ALOGV("%s:PASSTHROUGH supported for format %x",
458 __func__, out->format);
459 passt = true;
460 }
461 default:
462 ALOGV("%s:Passthrough not supported", __func__);
463 }
464 return passt;
465}
466
467void audio_extn_dolby_update_passt_stream_configuration(
468 struct audio_device *adev, struct stream_out *out) {
469 if (audio_extn_dolby_is_passt_supported(adev, out)) {
470 ALOGV("%s:PASSTHROUGH", __func__);
471 out->compr_config.codec->compr_passthr = PASSTHROUGH;
472 } else if (audio_extn_dolby_is_passt_convert_supported(adev, out)){
473 ALOGV("%s:PASSTHROUGH CONVERT", __func__);
474 out->compr_config.codec->compr_passthr = PASSTHROUGH_CONVERT;
475 } else {
476 ALOGV("%s:NO PASSTHROUGH", __func__);
477 out->compr_config.codec->compr_passthr = LEGACY_PCM;
478 }
479}
480
Mingming Yin21854652016-04-13 11:54:02 -0700481bool audio_extn_dolby_is_passthrough_stream(struct stream_out *out) {
Pradnya Chaphekar80a8cfb2014-10-20 16:17:01 -0700482
Mingming Yin21854652016-04-13 11:54:02 -0700483 //check passthrough system property
484 if (!property_get_bool("audio.offload.passthrough", false)) {
485 return false;
486 }
487
488 //check supported device, currently only on HDMI.
489 if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
490 //passthrough flag
491 if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH)
492 return true;
493 //direct flag, check supported formats.
494 if (out->flags & AUDIO_OUTPUT_FLAG_DIRECT) {
495 if (audio_extn_passthru_is_supported_format(out->format)) {
496 if (platform_is_edid_supported_format(out->dev->platform,
497 out->format)) {
498 return true;
499 } else if (audio_extn_is_dolby_format(out->format) &&
500 platform_is_edid_supported_format(out->dev->platform,
501 AUDIO_FORMAT_AC3)){
502 //return true for EAC3/EAC3_JOC formats
503 //if sink supports only AC3
504 return true;
505 }
506 }
507 }
508 }
509
Pradnya Chaphekar80a8cfb2014-10-20 16:17:01 -0700510 return false;
511}
512
Pradnya Chaphekar80a8cfb2014-10-20 16:17:01 -0700513int audio_extn_dolby_get_passt_buffer_size(audio_offload_info_t* info) {
514 return platform_get_compress_passthrough_buffer_size(info);
515}
516
517int audio_extn_dolby_set_passt_volume(struct stream_out *out, int mute) {
518 return platform_set_device_params(out, DEVICE_PARAM_MUTE_ID, mute);
519}
520
521int audio_extn_dolby_set_passt_latency(struct stream_out *out, int latency) {
522 return platform_set_device_params(out, DEVICE_PARAM_LATENCY_ID, latency);
523}
524#endif /* HDMI_PASSTHROUGH_ENABLED */
525
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800526#ifdef DS1_DOLBY_DAP_ENABLED
527void audio_extn_dolby_set_endpoint(struct audio_device *adev)
528{
529 struct listnode *node;
530 struct audio_usecase *usecase;
531 struct mixer_ctl *ctl;
532 const char *mixer_ctl_name = "DS1 DAP Endpoint";
533 int endpoint = 0, ret;
534 bool send = false;
535
536 list_for_each(node, &adev->usecase_list) {
537 usecase = node_to_item(node, struct audio_usecase, list);
538 if ((usecase->type == PCM_PLAYBACK) &&
539 (usecase->id != USECASE_AUDIO_PLAYBACK_LOW_LATENCY)) {
540 endpoint |= usecase->devices & AUDIO_DEVICE_OUT_ALL;
541 send = true;
542 }
543 }
544 if (!send)
545 return;
546
547 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
548 if (!ctl) {
549 ALOGE("%s: Could not get ctl for mixer cmd - %s",
550 __func__, mixer_ctl_name);
551 return;
552 }
553 ret = mixer_ctl_set_value(ctl, 0, endpoint);
554 if (ret)
555 ALOGE("%s: Dolby set endpint cannot be set error:%d",__func__, ret);
556
557 return;
558}
559#endif /* DS1_DOLBY_DAP_ENABLED */
560
561
562#if defined(DS1_DOLBY_DDP_ENABLED) || defined(DS1_DOLBY_DAP_ENABLED)
563void audio_extn_dolby_set_dmid(struct audio_device *adev)
564{
565 struct listnode *node;
566 struct audio_usecase *usecase;
567 struct mixer_ctl *ctl;
568 const char *mixer_ctl_name = "DS1 Security";
569 char c_dmid[128] = {0};
570 int i_dmid, ret;
571 bool send = false;
572
573 list_for_each(node, &adev->usecase_list) {
574 usecase = node_to_item(node, struct audio_usecase, list);
Mingming Yinc7d048a2014-02-25 13:34:07 -0800575 if (usecase->type == PCM_PLAYBACK)
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800576 send = true;
577 }
578 if (!send)
579 return;
580
581 property_get("dmid",c_dmid,"0");
Ashish Jain1dff3212015-02-10 12:16:48 +0530582 i_dmid = atoll(c_dmid);
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800583
584 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
585 if (!ctl) {
586 ALOGE("%s: Could not get ctl for mixer cmd - %s",
587 __func__, mixer_ctl_name);
588 return;
589 }
590 ALOGV("%s Dolby device manufacturer id is:%d",__func__,i_dmid);
591 ret = mixer_ctl_set_value(ctl, 0, i_dmid);
592 if (ret)
593 ALOGE("%s: Dolby DMID cannot be set error:%d",__func__, ret);
594
595 return;
596}
Dhananjay Kumar89ea3bd2014-04-29 15:45:57 +0530597
Ashish Jainedb6a912014-10-16 13:56:28 +0530598#ifndef DS2_DOLBY_DAP_ENABLED
Dhananjay Kumar89ea3bd2014-04-29 15:45:57 +0530599void audio_extn_dolby_set_license(struct audio_device *adev)
600{
601 int ret, key=0;
602 char value[128] = {0};
603 struct mixer_ctl *ctl;
604 const char *mixer_ctl_name = "DS1 License";
605
606 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
607 if (!ctl) {
608 ALOGE("%s: Could not get ctl for mixer cmd - %s",
609 __func__, mixer_ctl_name);
610 return;
611 }
612
613 property_get("audio.ds1.metainfo.key",value,"0");
Ashish Jainedb6a912014-10-16 13:56:28 +0530614#ifdef DOLBY_ACDB_LICENSE
Dhananjay Kumar89ea3bd2014-04-29 15:45:57 +0530615 key = atoi(value);
Ashish Jainedb6a912014-10-16 13:56:28 +0530616#else
617 key = 0;
618#endif
Dhananjay Kumar89ea3bd2014-04-29 15:45:57 +0530619 ALOGV("%s Setting DS1 License, key:0x%x",__func__, key);
620 ret = mixer_ctl_set_value(ctl, 0, key);
621 if (ret)
622 ALOGE("%s: cannot set license, error:%d",__func__, ret);
623
624 return;
625}
Ashish Jainedb6a912014-10-16 13:56:28 +0530626#endif
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800627#endif /* DS1_DOLBY_DDP_ENABLED || DS1_DOLBY_DAP_ENABLED */
Pradnya Chaphekar659affa2014-09-09 09:49:10 -0700628
629#ifdef DS2_DOLBY_DAP_ENABLED
630struct ds2_extn_module {
631 void *ds2_handle;
632 dap_hal_set_hw_info_t dap_hal_set_hw_info;
633};
634
635static struct ds2_extn_module ds2extnmod = {
636 .ds2_handle = NULL,
637 .dap_hal_set_hw_info = NULL,
638};
639
640int audio_extn_dap_hal_init(int snd_card) {
641 char c_dmid[128] = {0};
642 void *handle = NULL;
643 int i_dmid, ret = -EINVAL;
644 dap_hal_device_be_id_map_t device_be_id_map;
645
646 ALOGV("%s: opening DAP HAL lib\n", __func__);
647 ds2extnmod.ds2_handle = dlopen(LIB_DS2_DAP_HAL, RTLD_NOW);
648 if (ds2extnmod.ds2_handle == NULL) {
649 ALOGE("%s: DLOPEN failed for %s error %s", __func__, LIB_DS2_DAP_HAL,
650 dlerror());
651 goto ret;
652 }
653 ds2extnmod.dap_hal_set_hw_info = (dap_hal_set_hw_info_t)dlsym(ds2extnmod.ds2_handle, SET_HW_INFO_FUNC);
654 if (ds2extnmod.dap_hal_set_hw_info == NULL) {
655 ALOGE("%s: dlsym error %s for %s", __func__, SET_HW_INFO_FUNC,
656 dlerror());
657 goto close;
658 }
659 ds2extnmod.dap_hal_set_hw_info(SND_CARD, (void*)(&snd_card));
660 ALOGV("%s Sound card number is:%d",__func__,snd_card);
661
Alexy Josephb1379942016-01-29 15:49:38 -0800662 platform_get_device_to_be_id_map((int**)&device_be_id_map.device_id_to_be_id,
663 &device_be_id_map.len);
Pradnya Chaphekar659affa2014-09-09 09:49:10 -0700664 ds2extnmod.dap_hal_set_hw_info(DEVICE_BE_ID_MAP, (void*)(&device_be_id_map));
665 ALOGV("%s Set be id map len:%d",__func__,device_be_id_map.len);
666 ret = 0;
667 goto ret;
668
669close:
670 dlclose(ds2extnmod.ds2_handle);
671 ds2extnmod.ds2_handle = NULL;
672 ds2extnmod.dap_hal_set_hw_info = NULL;
673ret:
674 return ret;
675}
676
677int audio_extn_dap_hal_deinit() {
678 if (ds2extnmod.ds2_handle != NULL) {
679 dlclose(ds2extnmod.ds2_handle);
680 ds2extnmod.ds2_handle = NULL;
681 }
682 ds2extnmod.dap_hal_set_hw_info = NULL;
683 return 0;
684}
685
686void audio_extn_dolby_ds2_set_endpoint(struct audio_device *adev) {
687 struct listnode *node;
688 struct audio_usecase *usecase;
689 struct mixer_ctl *ctl;
690 const char *mixer_ctl_name = "DS1 DAP Endpoint";
691 int endpoint = 0, ret;
692 bool send = false;
693
694 list_for_each(node, &adev->usecase_list) {
695 usecase = node_to_item(node, struct audio_usecase, list);
696 if ((usecase->type == PCM_PLAYBACK) &&
697 (usecase->id != USECASE_AUDIO_PLAYBACK_LOW_LATENCY)) {
698 endpoint |= usecase->devices & AUDIO_DEVICE_OUT_ALL;
699 send = true;
700 }
701 }
702 if (!send)
703 return;
704
705 if (ds2extnmod.dap_hal_set_hw_info) {
706 ds2extnmod.dap_hal_set_hw_info(HW_ENDPOINT, (void*)(&endpoint));
707 ALOGE("%s: Dolby set endpint :0x%x",__func__, endpoint);
708 } else {
709 ALOGE("%s: dap_hal_set_hw_info is NULL",__func__);
710 }
711
712 return;
713}
714
715int audio_extn_ds2_enable(struct audio_device *adev) {
716
717 char value[PROPERTY_VALUE_MAX] = {0};
718 bool ds2_enabled = false;
719 const char *mixer_ctl_name = "DS2 OnOff";
720 struct mixer_ctl *ctl;
721
722 property_get("audio.dolby.ds2.enabled", value, NULL);
723 ds2_enabled = atoi(value) || !strncmp("true", value, 4);
724
725 ALOGV("%s:", __func__);
726 if(ds2_enabled) {
727 ALOGD("%s:ds2_enabled %d", __func__, ds2_enabled);
728 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
729 if (!ctl) {
730 ALOGE("%s: Could not get ctl for mixer cmd - %s",
731 __func__, mixer_ctl_name);
732 return -EINVAL;
733 }
734
735 if (mixer_ctl_set_value(ctl, 0, ds2_enabled) < 0) {
736 ALOGE("%s: Could not set ds2 enable %d",
737 __func__, ds2_enabled);
738 return -EINVAL;
739 }
740 }
741 return 0;
742}
743
744int audio_extn_dolby_set_dap_bypass(struct audio_device *adev, int state) {
745
746 ALOGV("%s: state %d", __func__, state);
747 if (ds2extnmod.dap_hal_set_hw_info) {
748 ds2extnmod.dap_hal_set_hw_info(DAP_BYPASS, (void*)(&state));
749 ALOGV("%s: Dolby set bypas :0x%x", __func__, state);
750 } else {
751 ALOGV("%s: dap_hal_set_hw_info is NULL", __func__);
752 }
753 return 0;
754}
Ashish Jainedb6a912014-10-16 13:56:28 +0530755
756void audio_extn_dolby_set_license(struct audio_device *adev)
757{
758 int i_key=0;
759 char c_key[128] = {0};
760 char c_dmid[128] = {0};
761 int i_dmid, ret = -EINVAL;
762 struct dolby_param_license dolby_license;
763
764#ifdef DOLBY_ACDB_LICENSE
765 property_get("audio.ds1.metainfo.key",c_key,"0");
766 i_key = atoi(c_key);
767#else
768 /* As ACDB based license mechanism is disabled, force set the license key to 0*/
769 i_key = 0;
770#endif
771 property_get("dmid",c_dmid,"0");
Ashish Jain1dff3212015-02-10 12:16:48 +0530772 i_dmid = atoll(c_dmid);
Ashish Jainedb6a912014-10-16 13:56:28 +0530773 ALOGV("%s Setting DS1 License, key:0x%x dmid %d",__func__, i_key,i_dmid);
774 dolby_license.dmid = i_dmid;
775 dolby_license.license_key = i_key;
776 if (ds2extnmod.dap_hal_set_hw_info) {
777 ds2extnmod.dap_hal_set_hw_info(DMID, (void*)(&dolby_license.dmid));
778 } else {
Alexy Josephb1379942016-01-29 15:49:38 -0800779 ALOGE("%s: dap_hal_set_hw_info is NULL", __func__);
Ashish Jainedb6a912014-10-16 13:56:28 +0530780 }
Alexy Josephb1379942016-01-29 15:49:38 -0800781 return;
Ashish Jainedb6a912014-10-16 13:56:28 +0530782}
783
784
785void audio_extn_ds2_set_parameters(struct audio_device *adev,
786 struct str_parms *parms)
787{
788 int val, ret;
789 char value[32]={0};
790
791 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SND_CARD_STATUS, value,
792 sizeof(value));
793 if (ret >= 0) {
794 char *snd_card_status = value + 2;
795 if (strncmp(snd_card_status, "ONLINE", sizeof("ONLINE")) == 0){
796 audio_extn_dolby_set_license(adev);
797 }
798 }
799}
Pradnya Chaphekar659affa2014-09-09 09:49:10 -0700800#endif