blob: cdfa2a1e05a322e0085d2d519c4d5dbfb1ae81d5 [file] [log] [blame]
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -08001/*
2 * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
3 * 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
24#include <errno.h>
25#include <cutils/properties.h>
26#include <stdlib.h>
27#include <dlfcn.h>
28#include <cutils/str_parms.h>
29#include <cutils/log.h>
30
31#include "audio_hw.h"
32#include "platform.h"
33#include "platform_api.h"
34#include "audio_extn.h"
35#include "sound/compress_params.h"
Ashish Jain8ec50472014-10-16 13:56:28 +053036#include "sound/devdep_params.h"
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -080037
38#ifdef DS1_DOLBY_DDP_ENABLED
39
40#define AUDIO_PARAMETER_DDP_DEV "ddp_device"
41#define AUDIO_PARAMETER_DDP_CH_CAP "ddp_chancap"
42#define AUDIO_PARAMETER_DDP_MAX_OUT_CHAN "ddp_maxoutchan"
43#define AUDIO_PARAMETER_DDP_OUT_MODE "ddp_outmode"
44#define AUDIO_PARAMETER_DDP_OUT_LFE_ON "ddp_outlfeon"
45#define AUDIO_PARAMETER_DDP_COMP_MODE "ddp_compmode"
46#define AUDIO_PARAMETER_DDP_STEREO_MODE "ddp_stereomode"
47
48#define PARAM_ID_MAX_OUTPUT_CHANNELS 0x00010DE2
49#define PARAM_ID_CTL_RUNNING_MODE 0x0
50#define PARAM_ID_CTL_ERROR_CONCEAL 0x00010DE3
51#define PARAM_ID_CTL_ERROR_MAX_RPTS 0x00010DE4
52#define PARAM_ID_CNV_ERROR_CONCEAL 0x00010DE5
53#define PARAM_ID_CTL_SUBSTREAM_SELECT 0x00010DE6
54#define PARAM_ID_CTL_INPUT_MODE 0x0
55#define PARAM_ID_OUT_CTL_OUTMODE 0x00010DE0
56#define PARAM_ID_OUT_CTL_OUTLFE_ON 0x00010DE1
57#define PARAM_ID_OUT_CTL_COMPMODE 0x00010D74
58#define PARAM_ID_OUT_CTL_STEREO_MODE 0x00010D76
59#define PARAM_ID_OUT_CTL_DUAL_MODE 0x00010D75
60#define PARAM_ID_OUT_CTL_DRCSCALE_HIGH 0x00010D7A
61#define PARAM_ID_OUT_CTL_DRCSCALE_LOW 0x00010D79
62#define PARAM_ID_OUT_CTL_OUT_PCMSCALE 0x00010D78
63#define PARAM_ID_OUT_CTL_MDCT_BANDLIMIT 0x00010DE7
64#define PARAM_ID_OUT_CTL_DRC_SUPPRESS 0x00010DE8
65
66/* DS1-DDP Endp Params */
67#define DDP_ENDP_NUM_PARAMS 17
Mingming Yin0acba992014-06-02 22:38:35 -070068#define DDP_ENDP_NUM_DEVICES 21
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -080069static int ddp_endp_params_id[DDP_ENDP_NUM_PARAMS] = {
70 PARAM_ID_MAX_OUTPUT_CHANNELS, PARAM_ID_CTL_RUNNING_MODE,
71 PARAM_ID_CTL_ERROR_CONCEAL, PARAM_ID_CTL_ERROR_MAX_RPTS,
72 PARAM_ID_CNV_ERROR_CONCEAL, PARAM_ID_CTL_SUBSTREAM_SELECT,
73 PARAM_ID_CTL_INPUT_MODE, PARAM_ID_OUT_CTL_OUTMODE,
74 PARAM_ID_OUT_CTL_OUTLFE_ON, PARAM_ID_OUT_CTL_COMPMODE,
75 PARAM_ID_OUT_CTL_STEREO_MODE, PARAM_ID_OUT_CTL_DUAL_MODE,
76 PARAM_ID_OUT_CTL_DRCSCALE_HIGH, PARAM_ID_OUT_CTL_DRCSCALE_LOW,
77 PARAM_ID_OUT_CTL_OUT_PCMSCALE, PARAM_ID_OUT_CTL_MDCT_BANDLIMIT,
78 PARAM_ID_OUT_CTL_DRC_SUPPRESS
79};
80
81static struct ddp_endp_params {
82 int device;
83 int dev_ch_cap;
84 int param_val[DDP_ENDP_NUM_PARAMS];
85 bool is_param_valid[DDP_ENDP_NUM_PARAMS];
86} ddp_endp_params[DDP_ENDP_NUM_DEVICES] = {
87 {AUDIO_DEVICE_OUT_EARPIECE, 2,
88 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
89 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 } },
90 {AUDIO_DEVICE_OUT_SPEAKER, 2,
91 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
92 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
93 {AUDIO_DEVICE_OUT_WIRED_HEADSET, 2,
94 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
95 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
96 {AUDIO_DEVICE_OUT_WIRED_HEADPHONE, 2,
97 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
98 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
99 {AUDIO_DEVICE_OUT_BLUETOOTH_SCO, 2,
100 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
101 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
102 {AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET, 2,
103 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
104 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
105 {AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT, 2,
106 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
107 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
108 {AUDIO_DEVICE_OUT_BLUETOOTH_A2DP, 2,
109 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
110 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
111 {AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES, 2,
112 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
113 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
114 {AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, 2,
115 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
116 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
117 {AUDIO_DEVICE_OUT_AUX_DIGITAL, 2,
118 {8, 0, 0, 0, 0, 0, 0, 21, 1, 2, 0, 0, 0, 0, 0, 0, 0},
119 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
120 {AUDIO_DEVICE_OUT_AUX_DIGITAL, 6,
121 {8, 0, 0, 0, 0, 0, 0, 21, 1, 2, 0, 0, 0, 0, 0, 0, 0},
122 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
123 {AUDIO_DEVICE_OUT_AUX_DIGITAL, 8,
124 {8, 0, 0, 0, 0, 0, 0, 21, 1, 2, 0, 0, 0, 0, 0, 0, 0},
125 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
126 {AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET, 2,
127 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
128 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
129 {AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET, 2,
130 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
131 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
132 {AUDIO_DEVICE_OUT_USB_ACCESSORY, 2,
133 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
134 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
135 {AUDIO_DEVICE_OUT_USB_DEVICE, 2,
136 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
137 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
138 {AUDIO_DEVICE_OUT_FM, 2,
139 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
140 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
141 {AUDIO_DEVICE_OUT_FM_TX, 2,
142 {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
143 {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 -0800144 {AUDIO_DEVICE_OUT_PROXY, 2,
Krishnankutty Kolathappilly0b2de1c2014-02-14 14:45:49 -0800145 {8, 0, 0, 0, 0, 0, 0, 21, 1, 2, 0, 0, 0, 0, 0, 0, 0},
146 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
147 {AUDIO_DEVICE_OUT_PROXY, 6,
148 {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 -0800149 {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
150};
151
152int update_ddp_endp_table(int device, int dev_ch_cap, int param_id,
153 int param_val)
154{
155 int idx = 0;
156 int param_idx = 0;
157 ALOGV("%s: dev 0x%x dev_ch_cap %d param_id 0x%x param_val %d",
158 __func__, device, dev_ch_cap , param_id, param_val);
159
160 for(idx=0; idx<DDP_ENDP_NUM_DEVICES; idx++) {
161 if(ddp_endp_params[idx].device == device) {
162 if(ddp_endp_params[idx].dev_ch_cap == dev_ch_cap) {
163 break;
164 }
165 }
166 }
167
168 if(idx>=DDP_ENDP_NUM_DEVICES) {
169 ALOGE("%s: device not available in DDP endp config table", __func__);
170 return -EINVAL;
171 }
172
173 for(param_idx=0; param_idx<DDP_ENDP_NUM_PARAMS; param_idx++) {
174 if (ddp_endp_params_id[param_idx] == param_id) {
175 break;
176 }
177 }
178
179 if(param_idx>=DDP_ENDP_NUM_PARAMS) {
180 ALOGE("param not available in DDP endp config table");
181 return -EINVAL;
182 }
183
184 ALOGV("ddp_endp_params[%d].param_val[%d] = %d", idx, param_idx, param_val);
185 ddp_endp_params[idx].param_val[param_idx] = param_val;
186 return 0;
187}
188
189void send_ddp_endp_params_stream(struct stream_out *out,
190 int device, int dev_ch_cap,
Ravi Kumar Alamandabdf14162014-09-05 16:14:17 -0700191 bool set_cache __unused)
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800192{
193 int idx, i;
194 int ddp_endp_params_data[2*DDP_ENDP_NUM_PARAMS + 1];
195 int length = 0;
196 for(idx=0; idx<DDP_ENDP_NUM_DEVICES; idx++) {
197 if(ddp_endp_params[idx].device & device) {
198 if(ddp_endp_params[idx].dev_ch_cap == dev_ch_cap) {
199 break;
200 }
201 }
202 }
203 if(idx>=DDP_ENDP_NUM_DEVICES) {
204 ALOGE("device not available in DDP endp config table");
205 return;
206 }
207
208 length += 1; /* offset 0 is for num of parameter. increase offset by 1 */
209 for (i=0; i<DDP_ENDP_NUM_PARAMS; i++) {
210 if(ddp_endp_params[idx].is_param_valid[i]) {
211 ddp_endp_params_data[length++] = ddp_endp_params_id[i];
212 ddp_endp_params_data[length++] = ddp_endp_params[idx].param_val[i];
213 }
214 }
215 ddp_endp_params_data[0] = (length-1)/2;
216 if(length) {
217 char mixer_ctl_name[128];
218 struct audio_device *adev = out->dev;
219 struct mixer_ctl *ctl;
220 int pcm_device_id = platform_get_pcm_device_id(out->usecase,
221 PCM_PLAYBACK);
222 snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
223 "Audio Stream %d Dec Params", pcm_device_id);
224 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
225 if (!ctl) {
226 ALOGE("%s: Could not get ctl for mixer cmd - %s",
227 __func__, mixer_ctl_name);
228 return;
229 }
230 mixer_ctl_set_array(ctl, ddp_endp_params_data, length);
231 }
232 return;
233}
234
235void send_ddp_endp_params(struct audio_device *adev,
236 int ddp_dev, int dev_ch_cap)
237{
238 struct listnode *node;
239 struct audio_usecase *usecase;
240
241 list_for_each(node, &adev->usecase_list) {
242 usecase = node_to_item(node, struct audio_usecase, list);
243 if ((usecase->type == PCM_PLAYBACK) &&
244 (usecase->devices & ddp_dev) &&
245 (usecase->stream.out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
246 ((usecase->stream.out->format == AUDIO_FORMAT_AC3) ||
Pradnya Chaphekar8a9dcd82014-09-09 09:49:10 -0700247 (usecase->stream.out->format == AUDIO_FORMAT_E_AC3) ||
248 (usecase->stream.out->format == AUDIO_FORMAT_E_AC3_JOC))) {
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800249 send_ddp_endp_params_stream(usecase->stream.out, ddp_dev,
250 dev_ch_cap, false /* set cache */);
251 }
252 }
253}
254
255void audio_extn_dolby_send_ddp_endp_params(struct audio_device *adev)
256{
257 struct listnode *node;
258 struct audio_usecase *usecase;
259 list_for_each(node, &adev->usecase_list) {
260 usecase = node_to_item(node, struct audio_usecase, list);
261 if ((usecase->type == PCM_PLAYBACK) &&
262 (usecase->devices & AUDIO_DEVICE_OUT_ALL) &&
263 (usecase->stream.out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
264 ((usecase->stream.out->format == AUDIO_FORMAT_AC3) ||
Pradnya Chaphekar8a9dcd82014-09-09 09:49:10 -0700265 (usecase->stream.out->format == AUDIO_FORMAT_E_AC3) ||
266 (usecase->stream.out->format == AUDIO_FORMAT_E_AC3_JOC))) {
Krishnankutty Kolathappilly0b2de1c2014-02-14 14:45:49 -0800267 /*
268 * Use wfd /hdmi sink channel cap for dolby params if device is wfd
269 * or hdmi. Otherwise use stereo configuration
270 */
271 int channel_cap = usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL ?
272 adev->cur_hdmi_channels :
273 usecase->devices & AUDIO_DEVICE_OUT_PROXY ?
274 adev->cur_wfd_channels : 2;
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800275 send_ddp_endp_params_stream(usecase->stream.out, usecase->devices,
Krishnankutty Kolathappilly0b2de1c2014-02-14 14:45:49 -0800276 channel_cap, false /* set cache */);
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800277 }
278 }
279}
280
281void audio_extn_ddp_set_parameters(struct audio_device *adev,
282 struct str_parms *parms)
283{
284 int ddp_dev, dev_ch_cap;
285 int val, ret;
286 char value[32]={0};
Dhananjay Kumar89ea3bd2014-04-29 15:45:57 +0530287
288 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SND_CARD_STATUS, value,
289 sizeof(value));
290 if (ret >= 0) {
291 char *snd_card_status = value + 2;
292 if (strncmp(snd_card_status, "ONLINE", sizeof("ONLINE")) == 0)
293 audio_extn_dolby_set_license(adev);
294 }
295
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800296 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DDP_DEV, value,
297 sizeof(value));
298 if (ret >= 0) {
299 ddp_dev = atoi(value);
300 if (!(AUDIO_DEVICE_OUT_ALL & ddp_dev))
301 return;
302 } else
303 return;
304
305 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DDP_CH_CAP, value,
306 sizeof(value));
307 if (ret >= 0) {
308 dev_ch_cap = atoi(value);
309 if ((dev_ch_cap != 2) && (dev_ch_cap != 6) && (dev_ch_cap != 8))
310 return;
311 } else
312 return;
313
314 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DDP_MAX_OUT_CHAN, value,
315 sizeof(value));
316 if (ret >= 0) {
317 val = atoi(value);
318 update_ddp_endp_table(ddp_dev, dev_ch_cap,
319 PARAM_ID_MAX_OUTPUT_CHANNELS, val);
320 }
321
322 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DDP_OUT_MODE, value,
323 sizeof(value));
324 if (ret >= 0) {
325 val = atoi(value);
326 update_ddp_endp_table(ddp_dev, dev_ch_cap,
327 PARAM_ID_OUT_CTL_OUTMODE, val);
328 }
329
330 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DDP_OUT_LFE_ON, value,
331 sizeof(value));
332 if (ret >= 0) {
333 val = atoi(value);
334 update_ddp_endp_table(ddp_dev, dev_ch_cap,
335 PARAM_ID_OUT_CTL_OUTLFE_ON, val);
336 }
337
338 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DDP_COMP_MODE, value,
339 sizeof(value));
340 if (ret >= 0) {
341 val = atoi(value);
342 update_ddp_endp_table(ddp_dev, dev_ch_cap,
343 PARAM_ID_OUT_CTL_COMPMODE, val);
344 }
345
346 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DDP_STEREO_MODE, value,
347 sizeof(value));
348 if (ret >= 0) {
349 val = atoi(value);
350 update_ddp_endp_table(ddp_dev, dev_ch_cap,
351 PARAM_ID_OUT_CTL_STEREO_MODE, val);
352 }
Krishnankutty Kolathappilly0b2de1c2014-02-14 14:45:49 -0800353 /* TODO: Do we need device channel caps here?
354 * We dont have that information as this is from dolby modules
355 */
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800356 send_ddp_endp_params(adev, ddp_dev, dev_ch_cap);
357}
Pradnya Chaphekar8a9dcd82014-09-09 09:49:10 -0700358#endif /* DS1_DOLBY_DDP_ENABLED */
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800359
Pradnya Chaphekar8a9dcd82014-09-09 09:49:10 -0700360#if defined(DS1_DOLBY_DDP_ENABLED) || defined(DS2_DOLBY_DAP_ENABLED)
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800361int audio_extn_dolby_get_snd_codec_id(struct audio_device *adev,
362 struct stream_out *out,
363 audio_format_t format)
364{
365 int id = 0;
Krishnankutty Kolathappilly0b2de1c2014-02-14 14:45:49 -0800366 /*
367 * Use wfd /hdmi sink channel cap for dolby params if device is wfd
368 * or hdmi. Otherwise use stereo configuration
369 */
370 int channel_cap = out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL ?
371 adev->cur_hdmi_channels :
372 out->devices & AUDIO_DEVICE_OUT_PROXY ?
373 adev->cur_wfd_channels : 2;
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800374
375 switch (format) {
376 case AUDIO_FORMAT_AC3:
377 id = SND_AUDIOCODEC_AC3;
Pradnya Chaphekar8a9dcd82014-09-09 09:49:10 -0700378#ifdef DS1_DOLBY_DDP_ENABLED
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800379 send_ddp_endp_params_stream(out, out->devices,
Krishnankutty Kolathappilly0b2de1c2014-02-14 14:45:49 -0800380 channel_cap, true /* set_cache */);
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800381#endif
Pradnya Chaphekar8a9dcd82014-09-09 09:49:10 -0700382 audio_extn_dolby_set_dmid(adev);
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800383 break;
Mingming Yinae3530f2014-07-03 16:50:18 -0700384 case AUDIO_FORMAT_E_AC3:
Pradnya Chaphekar8a9dcd82014-09-09 09:49:10 -0700385 case AUDIO_FORMAT_E_AC3_JOC:
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800386 id = SND_AUDIOCODEC_EAC3;
Pradnya Chaphekar8a9dcd82014-09-09 09:49:10 -0700387#ifdef DS1_DOLBY_DDP_ENABLED
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800388 send_ddp_endp_params_stream(out, out->devices,
Krishnankutty Kolathappilly0b2de1c2014-02-14 14:45:49 -0800389 channel_cap, true /* set_cache */);
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800390#endif
Pradnya Chaphekar8a9dcd82014-09-09 09:49:10 -0700391 audio_extn_dolby_set_dmid(adev);
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800392 break;
393 default:
394 ALOGE("%s: Unsupported audio format :%x", __func__, format);
395 }
396
397 return id;
398}
399
400bool audio_extn_is_dolby_format(audio_format_t format)
401{
402 if (format == AUDIO_FORMAT_AC3 ||
Pradnya Chaphekar8a9dcd82014-09-09 09:49:10 -0700403 format == AUDIO_FORMAT_E_AC3 ||
404 format == AUDIO_FORMAT_E_AC3_JOC)
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800405 return true;
406 else
407 return false;
408}
Pradnya Chaphekar8a9dcd82014-09-09 09:49:10 -0700409#endif /* DS1_DOLBY_DDP_ENABLED || DS2_DOLBY_DAP_ENABLED */
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800410
Pradnya Chaphekar80a8cfb2014-10-20 16:17:01 -0700411#ifdef HDMI_PASSTHROUGH_ENABLED
412int audio_extn_dolby_update_passt_formats(struct audio_device *adev,
413 struct stream_out *out) {
414 int32_t i = 0, ret = -ENOSYS;
415
416 if (platform_is_edid_supported_format(adev->platform, AUDIO_FORMAT_AC3) ||
417 platform_is_edid_supported_format(adev->platform, AUDIO_FORMAT_E_AC3)) {
418 out->supported_formats[i++] = AUDIO_FORMAT_AC3;
419 out->supported_formats[i++] = AUDIO_FORMAT_E_AC3;
420 /* Reciever must support JOC and advertise, otherwise JOC is treated as DDP */
421 out->supported_formats[i++] = AUDIO_FORMAT_E_AC3_JOC;
422 ret = 0;
423 }
424 ALOGV("%s: ret = %d", __func__, ret);
425 return ret;
426}
427
428bool audio_extn_dolby_is_passt_convert_supported(struct audio_device *adev,
429 struct stream_out *out) {
430
431 bool convert = false;
432 switch (out->format) {
433 case AUDIO_FORMAT_E_AC3:
434 case AUDIO_FORMAT_E_AC3_JOC:
435 if (!platform_is_edid_supported_format(adev->platform,
436 AUDIO_FORMAT_E_AC3)) {
437 ALOGV("%s:PASSTHROUGH_CONVERT supported", __func__);
438 convert = true;
439 }
440 break;
441 default:
442 ALOGE("%s: PASSTHROUGH_CONVERT not supported for format 0x%x",
443 __func__, out->format);
444 break;
445 }
446 ALOGE("%s: convert %d", __func__, convert);
447 return convert;
448}
449
450bool audio_extn_dolby_is_passt_supported(struct audio_device *adev,
451 struct stream_out *out) {
452 bool passt = false;
453 switch (out->format) {
454 case AUDIO_FORMAT_E_AC3:
455 if (platform_is_edid_supported_format(adev->platform, out->format)) {
456 ALOGV("%s:PASSTHROUGH supported for format %x",
457 __func__, out->format);
458 passt = true;
459 }
460 break;
461 case AUDIO_FORMAT_AC3:
462 if (platform_is_edid_supported_format(adev->platform, AUDIO_FORMAT_AC3)
463 || platform_is_edid_supported_format(adev->platform,
464 AUDIO_FORMAT_E_AC3)) {
465 ALOGV("%s:PASSTHROUGH supported for format %x",
466 __func__, out->format);
467 passt = true;
468 }
469 break;
470 case AUDIO_FORMAT_E_AC3_JOC:
471 /* Check for DDP capability in edid for JOC contents.*/
472 if (platform_is_edid_supported_format(adev->platform,
473 AUDIO_FORMAT_E_AC3)) {
474 ALOGV("%s:PASSTHROUGH supported for format %x",
475 __func__, out->format);
476 passt = true;
477 }
478 default:
479 ALOGV("%s:Passthrough not supported", __func__);
480 }
481 return passt;
482}
483
484void audio_extn_dolby_update_passt_stream_configuration(
485 struct audio_device *adev, struct stream_out *out) {
486 if (audio_extn_dolby_is_passt_supported(adev, out)) {
487 ALOGV("%s:PASSTHROUGH", __func__);
488 out->compr_config.codec->compr_passthr = PASSTHROUGH;
489 } else if (audio_extn_dolby_is_passt_convert_supported(adev, out)){
490 ALOGV("%s:PASSTHROUGH CONVERT", __func__);
491 out->compr_config.codec->compr_passthr = PASSTHROUGH_CONVERT;
492 } else {
493 ALOGV("%s:NO PASSTHROUGH", __func__);
494 out->compr_config.codec->compr_passthr = LEGACY_PCM;
495 }
496}
497
498bool audio_extn_dolby_is_passthrough_stream(int flags) {
499
500 if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH)
501 return true;
502 return false;
503}
504
505int audio_extn_dolby_set_hdmi_config(struct audio_device *adev,
506 struct stream_out *out) {
507 return platform_set_hdmi_config(out);
508}
509
510int audio_extn_dolby_get_passt_buffer_size(audio_offload_info_t* info) {
511 return platform_get_compress_passthrough_buffer_size(info);
512}
513
514int audio_extn_dolby_set_passt_volume(struct stream_out *out, int mute) {
515 return platform_set_device_params(out, DEVICE_PARAM_MUTE_ID, mute);
516}
517
518int audio_extn_dolby_set_passt_latency(struct stream_out *out, int latency) {
519 return platform_set_device_params(out, DEVICE_PARAM_LATENCY_ID, latency);
520}
521#endif /* HDMI_PASSTHROUGH_ENABLED */
522
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800523#ifdef DS1_DOLBY_DAP_ENABLED
524void audio_extn_dolby_set_endpoint(struct audio_device *adev)
525{
526 struct listnode *node;
527 struct audio_usecase *usecase;
528 struct mixer_ctl *ctl;
529 const char *mixer_ctl_name = "DS1 DAP Endpoint";
530 int endpoint = 0, ret;
531 bool send = false;
532
533 list_for_each(node, &adev->usecase_list) {
534 usecase = node_to_item(node, struct audio_usecase, list);
535 if ((usecase->type == PCM_PLAYBACK) &&
536 (usecase->id != USECASE_AUDIO_PLAYBACK_LOW_LATENCY)) {
537 endpoint |= usecase->devices & AUDIO_DEVICE_OUT_ALL;
538 send = true;
539 }
540 }
541 if (!send)
542 return;
543
544 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
545 if (!ctl) {
546 ALOGE("%s: Could not get ctl for mixer cmd - %s",
547 __func__, mixer_ctl_name);
548 return;
549 }
550 ret = mixer_ctl_set_value(ctl, 0, endpoint);
551 if (ret)
552 ALOGE("%s: Dolby set endpint cannot be set error:%d",__func__, ret);
553
554 return;
555}
556#endif /* DS1_DOLBY_DAP_ENABLED */
557
558
559#if defined(DS1_DOLBY_DDP_ENABLED) || defined(DS1_DOLBY_DAP_ENABLED)
560void audio_extn_dolby_set_dmid(struct audio_device *adev)
561{
562 struct listnode *node;
563 struct audio_usecase *usecase;
564 struct mixer_ctl *ctl;
565 const char *mixer_ctl_name = "DS1 Security";
566 char c_dmid[128] = {0};
567 int i_dmid, ret;
568 bool send = false;
569
570 list_for_each(node, &adev->usecase_list) {
571 usecase = node_to_item(node, struct audio_usecase, list);
Mingming Yinc7d048a2014-02-25 13:34:07 -0800572 if (usecase->type == PCM_PLAYBACK)
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800573 send = true;
574 }
575 if (!send)
576 return;
577
578 property_get("dmid",c_dmid,"0");
579 i_dmid = atoi(c_dmid);
580
581 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
582 if (!ctl) {
583 ALOGE("%s: Could not get ctl for mixer cmd - %s",
584 __func__, mixer_ctl_name);
585 return;
586 }
587 ALOGV("%s Dolby device manufacturer id is:%d",__func__,i_dmid);
588 ret = mixer_ctl_set_value(ctl, 0, i_dmid);
589 if (ret)
590 ALOGE("%s: Dolby DMID cannot be set error:%d",__func__, ret);
591
592 return;
593}
Dhananjay Kumar89ea3bd2014-04-29 15:45:57 +0530594
Ashish Jain8ec50472014-10-16 13:56:28 +0530595#ifndef DS2_DOLBY_DAP_ENABLED
Dhananjay Kumar89ea3bd2014-04-29 15:45:57 +0530596void audio_extn_dolby_set_license(struct audio_device *adev)
597{
598 int ret, key=0;
599 char value[128] = {0};
600 struct mixer_ctl *ctl;
601 const char *mixer_ctl_name = "DS1 License";
602
603 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
604 if (!ctl) {
605 ALOGE("%s: Could not get ctl for mixer cmd - %s",
606 __func__, mixer_ctl_name);
607 return;
608 }
609
610 property_get("audio.ds1.metainfo.key",value,"0");
Ashish Jain8ec50472014-10-16 13:56:28 +0530611#ifdef DOLBY_ACDB_LICENSE
Dhananjay Kumar89ea3bd2014-04-29 15:45:57 +0530612 key = atoi(value);
Ashish Jain8ec50472014-10-16 13:56:28 +0530613#endif
Dhananjay Kumar89ea3bd2014-04-29 15:45:57 +0530614 ALOGV("%s Setting DS1 License, key:0x%x",__func__, key);
615 ret = mixer_ctl_set_value(ctl, 0, key);
616 if (ret)
617 ALOGE("%s: cannot set license, error:%d",__func__, ret);
618
619 return;
620}
Ashish Jain8ec50472014-10-16 13:56:28 +0530621#endif
Subhash Chandra Bose Naripeddy7690c562013-12-14 00:34:53 -0800622#endif /* DS1_DOLBY_DDP_ENABLED || DS1_DOLBY_DAP_ENABLED */
Pradnya Chaphekar8a9dcd82014-09-09 09:49:10 -0700623
624#ifdef DS2_DOLBY_DAP_ENABLED
625struct ds2_extn_module {
626 void *ds2_handle;
627 dap_hal_set_hw_info_t dap_hal_set_hw_info;
628};
629
630static struct ds2_extn_module ds2extnmod = {
631 .ds2_handle = NULL,
632 .dap_hal_set_hw_info = NULL,
633};
634
635int audio_extn_dap_hal_init(int snd_card) {
636 char c_dmid[128] = {0};
637 void *handle = NULL;
638 int i_dmid, ret = -EINVAL;
639 dap_hal_device_be_id_map_t device_be_id_map;
640
641 ALOGV("%s: opening DAP HAL lib\n", __func__);
642 ds2extnmod.ds2_handle = dlopen(LIB_DS2_DAP_HAL, RTLD_NOW);
643 if (ds2extnmod.ds2_handle == NULL) {
644 ALOGE("%s: DLOPEN failed for %s error %s", __func__, LIB_DS2_DAP_HAL,
645 dlerror());
646 goto ret;
647 }
648 ds2extnmod.dap_hal_set_hw_info = (dap_hal_set_hw_info_t)dlsym(ds2extnmod.ds2_handle, SET_HW_INFO_FUNC);
649 if (ds2extnmod.dap_hal_set_hw_info == NULL) {
650 ALOGE("%s: dlsym error %s for %s", __func__, SET_HW_INFO_FUNC,
651 dlerror());
652 goto close;
653 }
654 ds2extnmod.dap_hal_set_hw_info(SND_CARD, (void*)(&snd_card));
655 ALOGV("%s Sound card number is:%d",__func__,snd_card);
656
Pradnya Chaphekar8a9dcd82014-09-09 09:49:10 -0700657 platform_get_device_to_be_id_map(&device_be_id_map.device_id_to_be_id, &device_be_id_map.len);
658 ds2extnmod.dap_hal_set_hw_info(DEVICE_BE_ID_MAP, (void*)(&device_be_id_map));
659 ALOGV("%s Set be id map len:%d",__func__,device_be_id_map.len);
660 ret = 0;
661 goto ret;
662
663close:
664 dlclose(ds2extnmod.ds2_handle);
665 ds2extnmod.ds2_handle = NULL;
666 ds2extnmod.dap_hal_set_hw_info = NULL;
667ret:
668 return ret;
669}
670
671int audio_extn_dap_hal_deinit() {
672 if (ds2extnmod.ds2_handle != NULL) {
673 dlclose(ds2extnmod.ds2_handle);
674 ds2extnmod.ds2_handle = NULL;
675 }
676 ds2extnmod.dap_hal_set_hw_info = NULL;
677 return 0;
678}
679
680void audio_extn_dolby_ds2_set_endpoint(struct audio_device *adev) {
681 struct listnode *node;
682 struct audio_usecase *usecase;
683 struct mixer_ctl *ctl;
684 const char *mixer_ctl_name = "DS1 DAP Endpoint";
685 int endpoint = 0, ret;
686 bool send = false;
687
688 list_for_each(node, &adev->usecase_list) {
689 usecase = node_to_item(node, struct audio_usecase, list);
690 if ((usecase->type == PCM_PLAYBACK) &&
691 (usecase->id != USECASE_AUDIO_PLAYBACK_LOW_LATENCY)) {
692 endpoint |= usecase->devices & AUDIO_DEVICE_OUT_ALL;
693 send = true;
694 }
695 }
696 if (!send)
697 return;
698
699 if (ds2extnmod.dap_hal_set_hw_info) {
700 ds2extnmod.dap_hal_set_hw_info(HW_ENDPOINT, (void*)(&endpoint));
701 ALOGE("%s: Dolby set endpint :0x%x",__func__, endpoint);
702 } else {
703 ALOGE("%s: dap_hal_set_hw_info is NULL",__func__);
704 }
705
706 return;
707}
708
709int audio_extn_ds2_enable(struct audio_device *adev) {
710
711 char value[PROPERTY_VALUE_MAX] = {0};
712 bool ds2_enabled = false;
713 const char *mixer_ctl_name = "DS2 OnOff";
714 struct mixer_ctl *ctl;
715
716 property_get("audio.dolby.ds2.enabled", value, NULL);
717 ds2_enabled = atoi(value) || !strncmp("true", value, 4);
718
719 ALOGV("%s:", __func__);
720 if(ds2_enabled) {
721 ALOGD("%s:ds2_enabled %d", __func__, ds2_enabled);
722 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
723 if (!ctl) {
724 ALOGE("%s: Could not get ctl for mixer cmd - %s",
725 __func__, mixer_ctl_name);
726 return -EINVAL;
727 }
728
729 if (mixer_ctl_set_value(ctl, 0, ds2_enabled) < 0) {
730 ALOGE("%s: Could not set ds2 enable %d",
731 __func__, ds2_enabled);
732 return -EINVAL;
733 }
734 }
735 return 0;
736}
737
738int audio_extn_dolby_set_dap_bypass(struct audio_device *adev, int state) {
739
740 ALOGV("%s: state %d", __func__, state);
741 if (ds2extnmod.dap_hal_set_hw_info) {
742 ds2extnmod.dap_hal_set_hw_info(DAP_BYPASS, (void*)(&state));
743 ALOGV("%s: Dolby set bypas :0x%x", __func__, state);
744 } else {
745 ALOGV("%s: dap_hal_set_hw_info is NULL", __func__);
746 }
747 return 0;
748}
Ashish Jain8ec50472014-10-16 13:56:28 +0530749
750void audio_extn_dolby_set_license(struct audio_device *adev)
751{
752 int i_key;
753 char c_key[128] = {0};
754 char c_dmid[128] = {0};
755 int i_dmid, ret = -EINVAL;
756 struct dolby_param_license dolby_license;
757
758#ifdef DOLBY_ACDB_LICENSE
759 property_get("audio.ds1.metainfo.key",c_key,"0");
760 i_key = atoi(c_key);
761#else
762 /* As ACDB based license mechanism is disabled, force set the license key to 0*/
763 i_key = 0;
764#endif
765 property_get("dmid",c_dmid,"0");
766 i_dmid = atoi(c_dmid);
767 ALOGV("%s Setting DS1 License, key:0x%x dmid %d",__func__, i_key,i_dmid);
768 dolby_license.dmid = i_dmid;
769 dolby_license.license_key = i_key;
770 if (ds2extnmod.dap_hal_set_hw_info) {
771 ds2extnmod.dap_hal_set_hw_info(DMID, (void*)(&dolby_license.dmid));
772 } else {
773 ALOGV("%s: dap_hal_set_hw_info is NULL", __func__);
774 return ret;
775 }
776 return 0;
777}
778
779
780void audio_extn_ds2_set_parameters(struct audio_device *adev,
781 struct str_parms *parms)
782{
783 int val, ret;
784 char value[32]={0};
785
786 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SND_CARD_STATUS, value,
787 sizeof(value));
788 if (ret >= 0) {
789 char *snd_card_status = value + 2;
790 if (strncmp(snd_card_status, "ONLINE", sizeof("ONLINE")) == 0){
791 audio_extn_dolby_set_license(adev);
792 }
793 }
794}
Pradnya Chaphekar8a9dcd82014-09-09 09:49:10 -0700795#endif