summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChandrashekhar Urkeri2019-10-09 20:55:22 -0500
committerPraneeth Bajjuri2019-10-09 15:48:40 -0500
commitfb8a507ecb7d8dfd435691c9c6a45bd9bc86daa7 (patch)
tree072a8f63522481c52f3122a908e24af6fe5e0c63
parent5bee3a1f601fe5b00ee200aa3fd7bbe4f257ad87 (diff)
downloadhardware-ti-dra7xx-d-pie-core-release.tar.gz
hardware-ti-dra7xx-d-pie-core-release.tar.xz
hardware-ti-dra7xx-d-pie-core-release.zip
AudioHAL:Implement primary Audio HAL library for j721e.d-pie-core-released-android10-core-release
This audio HAL implements audio HIDL Version 4.0.Android's audio Hardware Abstraction Layer (HAL) connects the higher-level, audio-specific framework APIs in android.media to the underlying audio driver and hardware. Audio policy configuration file format (XML) is used for describing your audio topology.This XML file enables defining the number and types of output and input stream profiles, devices usable for playback and capture, and audio attributes. The audio HAL mainly implementations the API's defined in the below header file. hardware/libhardware/include/hardware/audio.h The base implementation is taken from the J6 Audio HAL library. This audio hal generates the library for primary audio device i.e. audio.primary.j721e.so The current implementation will play and record at 48KHz For more info on Android audio hal please check below link. https://source.android.com/devices/audio Testing: Playback testing is done using the default Android music player with different audio formats. Record testing is done via test recorder app or the default Android Sound recorder app. TODO: 1.Implement the empty functions which handles changing of volume,audio effects,mute functions and debug dumps etc. 2.Multi channel audio playback. 3.Voice call handling. 4.BT voice call handling. 5.Changes required for CDD compliance. Acked-By: Misael Lopez Cruz <misael.lopez@ti.com> Signed-off-by: Chandrashekhar Urkeri <x1048305@ti.com> [corrected the mixer path ctrl names] Signed-off-by: Vishal Mahaveer <vishalm@ti.com>
-rw-r--r--audio/Android.mk17
-rw-r--r--audio/audio_policy_configuration.xml18
-rw-r--r--audio/primary/Android.mk48
-rw-r--r--audio/primary/audio_hw.c1071
-rw-r--r--audio/primary/audio_policy_configuration.xml34
-rw-r--r--audio/primary/mixer_paths.xml13
-rw-r--r--j721e.mk1
7 files changed, 1202 insertions, 0 deletions
diff --git a/audio/Android.mk b/audio/Android.mk
new file mode 100644
index 0000000..f5e4b26
--- /dev/null
+++ b/audio/Android.mk
@@ -0,0 +1,17 @@
1# Copyright (C) 2019 Texas Instruments
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15LOCAL_PATH := $(call my-dir)
16
17include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/audio/audio_policy_configuration.xml b/audio/audio_policy_configuration.xml
new file mode 100644
index 0000000..576804e
--- /dev/null
+++ b/audio/audio_policy_configuration.xml
@@ -0,0 +1,18 @@
1<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
3 <!-- Global configuration Declaration -->
4 <globalConfiguration speaker_drc_enabled="false"/>
5
6 <modules>
7 <!-- Primary Audio HAL -->
8 <xi:include href="primary_audio_policy_configuration.xml"/>
9
10 <!-- Remote Submix Audio HAL -->
11 <xi:include href="r_submix_audio_policy_configuration.xml"/>
12 </modules>
13
14 <!-- Volume section -->
15 <xi:include href="audio_policy_volumes.xml"/>
16 <xi:include href="default_volume_tables.xml"/>
17
18</audioPolicyConfiguration>
diff --git a/audio/primary/Android.mk b/audio/primary/Android.mk
new file mode 100644
index 0000000..551025c
--- /dev/null
+++ b/audio/primary/Android.mk
@@ -0,0 +1,48 @@
1# Copyright (C) 2019 Texas Instruments
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15LOCAL_PATH := $(call my-dir)
16
17ifeq ($(findstring j721e, $(TARGET_BOARD_PLATFORM)),j721e)
18
19include $(CLEAR_VARS)
20
21LOCAL_MODULE := audio.primary.$(TARGET_BOARD_PLATFORM)
22
23LOCAL_MODULE_RELATIVE_PATH := hw
24LOCAL_VENDOR_MODULE := true
25LOCAL_SRC_FILES := audio_hw.c
26
27LOCAL_C_INCLUDES += \
28 external/tinyalsa/include \
29 system/media/audio_route/include \
30 system/media/audio_utils/include \
31 system/media/audio_effects/include
32
33LOCAL_HEADER_LIBRARIES += libhardware_headers
34
35LOCAL_CFLAGS += -Wno-implicit-function-declaration -Wno-unused-variable
36
37LOCAL_SHARED_LIBRARIES := \
38 liblog \
39 libcutils \
40 libtinyalsa \
41 libaudioroute \
42 libaudioutils
43
44LOCAL_MODULE_TAGS := optional
45
46include $(BUILD_SHARED_LIBRARY)
47
48endif
diff --git a/audio/primary/audio_hw.c b/audio/primary/audio_hw.c
new file mode 100644
index 0000000..9c40f41
--- /dev/null
+++ b/audio/primary/audio_hw.c
@@ -0,0 +1,1071 @@
1/*
2 * Copyright (C) 2019 Texas Instruments
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "audio_hw_primary"
18//#define LOG_NDEBUG 0
19//#define VERY_VERBOSE_LOGGING
20#ifdef VERY_VERBOSE_LOGGING
21#define ALOGVV ALOGV
22#else
23#define ALOGVV(a...) do { } while(0)
24#endif
25
26#include <errno.h>
27#include <stdint.h>
28#include <stdlib.h>
29#include <pthread.h>
30#include <unistd.h>
31#include <sys/time.h>
32
33#include <log/log.h>
34#include <cutils/str_parms.h>
35#include <cutils/properties.h>
36
37#include <audio_utils/resampler.h>
38#include <audio_route/audio_route.h>
39#include <system/audio.h>
40#include <hardware/hardware.h>
41#include <hardware/audio.h>
42#include <hardware/audio_effect.h>
43
44#include <tinyalsa/asoundlib.h>
45
46#define UNUSED(x) (void)(x)
47
48/* yet another definition of ARRAY_SIZE macro) */
49#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
50
51#define DEFAULT_AUDIO_FORMAT AUDIO_FORMAT_PCM_24_BIT_PACKED
52
53struct j7_audio_device {
54 struct audio_hw_device device;
55 struct j7_stream_in *in;
56 struct j7_stream_out *out;
57 struct audio_route *route;
58 pthread_mutex_t lock;
59 unsigned int card;
60 bool mic_mute;
61 audio_mode_t mode;
62};
63
64struct j7_stream_in {
65 struct audio_stream_in stream;
66 struct j7_audio_device *dev;
67 struct pcm_config config;
68 struct pcm *pcm;
69 struct resampler_buffer_provider buf_provider;
70 size_t frames_in;
71 size_t hw_frame_size;
72 unsigned int requested_rate;
73 unsigned int requested_channels;
74 unsigned int card;
75 unsigned int port;
76 audio_devices_t device;
77 int read_status;
78 pthread_mutex_t lock;
79 bool standby;
80};
81
82struct j7_stream_out {
83 struct audio_stream_out stream;
84 struct j7_audio_device *dev;
85 struct pcm_config config;
86 struct pcm *pcm;
87 struct timespec last;
88 pthread_mutex_t lock;
89 size_t hw_frame_size;
90 unsigned int requested_rate;
91 unsigned int requested_channels;
92 unsigned int card;
93 unsigned int port;
94 audio_devices_t device;
95 bool standby;
96 int64_t written; /* total frames written, not cleared when entering standby */
97};
98
99static const char *supported_media_cards[] = {
100 "j721e-cpb-analog",
101};
102
103#define MAX_CARD_COUNT 1
104#define BYTES_PER_SAMPLE (3 * sizeof(int8_t)) //for 24 bit 3 bytes are required
105
106#define SUPPORTED_IN_DEVICES (AUDIO_DEVICE_IN_WIRED_HEADSET | \
107 AUDIO_DEVICE_IN_DEFAULT)
108
109#define SUPPORTED_OUT_DEVICES (AUDIO_DEVICE_OUT_SPEAKER | \
110 AUDIO_DEVICE_OUT_DEFAULT)
111
112#define CAPTURE_SAMPLE_RATE 48000 /* 48K Hz*/
113#define CAPTURE_PERIOD_SIZE 256
114#define CAPTURE_PERIOD_COUNT 4
115#define CAPTURE_BUFFER_SIZE (CAPTURE_PERIOD_SIZE * CAPTURE_PERIOD_COUNT)
116
117#define PLAYBACK_SAMPLE_RATE 48000 /* 48K Hz*/
118#define PLAYBACK_PERIOD_SIZE 256
119#define PLAYBACK_PERIOD_COUNT 4
120#define PLAYBACK_BUFFER_SIZE (PLAYBACK_PERIOD_SIZE * PLAYBACK_PERIOD_COUNT)
121
122#define MIXER_XML_PATH "/vendor/etc/mixer_paths.xml"
123
124struct pcm_config pcm_config_capture = {
125 .channels = 2,/* Stereo mode */
126 .rate = CAPTURE_SAMPLE_RATE,/* 48K Hz*/
127 .format = PCM_FORMAT_S24_3LE,
128 .period_size = CAPTURE_PERIOD_SIZE,
129 .period_count = CAPTURE_PERIOD_COUNT,
130 .start_threshold = 1,
131 .stop_threshold = CAPTURE_BUFFER_SIZE,
132};
133
134struct pcm_config pcm_config_playback = {
135 .channels = 2,/* Stereo mode */
136 .rate = PLAYBACK_SAMPLE_RATE,/* 48K Hz*/
137 .format = PCM_FORMAT_S24_3LE,
138 .period_size = PLAYBACK_PERIOD_SIZE,
139 .period_count = PLAYBACK_PERIOD_COUNT,
140 .start_threshold = PLAYBACK_BUFFER_SIZE / 2,
141 .stop_threshold = PLAYBACK_BUFFER_SIZE,
142 .avail_min = PLAYBACK_PERIOD_SIZE,
143};
144
145/*
146 * Recommended buffer sizes for the mandatory sampling frequencies.
147 * The buffer sizes were specifically chosen to avoid multiple
148 * resample_from_input() calls to consume an output buffer, which
149 * simplifies the HAL's write() function.
150 * The hardware natively supports 48kHz, but the rate of
151 * the playback and capture streams must be symmetric (they share the
152 * same FSYNC).
153 */
154static inline uint32_t output_buffer_size(uint32_t rate)
155{
156 uint32_t samples;
157
158 if (rate == 48000){
159 return PLAYBACK_PERIOD_SIZE;
160 }
161 else{
162 /*
163 * take resampling into account and return the closest majoring
164 * multiple of 16 frames, as audioflinger expects audio buffers to
165 * be a multiple of 16 frames
166 */
167 samples = (rate * PLAYBACK_PERIOD_SIZE) / PLAYBACK_SAMPLE_RATE;
168 samples = ((samples + 15) / 16) * 16;
169 ALOGE("output_buffer_size() samples=%d\n",samples);
170 }
171 return samples;
172}
173
174static void do_out_standby(struct j7_stream_out *out);
175
176static size_t get_input_buffer_size(uint32_t sample_rate, int format, int channel_count)
177{
178 size_t size;
179
180 /*
181 * take resampling into account and return the closest majoring
182 * multiple of 16 frames, as audioflinger expects audio buffers to
183 * be a multiple of 16 frames
184 */
185 size = (pcm_config_capture.period_size * sample_rate) / pcm_config_capture.rate;
186 size = ((size + 15) / 16) * 16;
187
188 return size * channel_count * audio_bytes_per_sample(format);
189}
190/* audio HAL functions */
191
192static uint32_t out_get_sample_rate(const struct audio_stream *stream)
193{
194 const struct j7_stream_out *out = (const struct j7_stream_out *)stream;
195
196 ALOGVV("out_get_sample_rate() stream=%p rate=%u", stream, out->requested_rate);
197
198 return out->requested_rate;
199}
200
201static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
202{
203 UNUSED(stream);
204 UNUSED(rate);
205 ALOGVV("out_set_sample_rate() stream=%p rate=%u", stream, rate);
206 /* Only 48KHz is supported so we simply return 0 */
207 return 0;
208}
209
210static size_t out_get_buffer_size(const struct audio_stream *stream)
211{
212 const struct j7_stream_out *out = (const struct j7_stream_out *)stream;
213 uint32_t frames = output_buffer_size(out->requested_rate);
214 size_t bytes = frames * out->requested_channels * audio_bytes_per_sample(DEFAULT_AUDIO_FORMAT);
215
216 ALOGE("out_get_buffer_size() stream=%p frames=%u bytes=%zu", stream, frames, bytes);
217
218 return bytes;
219}
220
221static audio_channel_mask_t out_get_channels(const struct audio_stream *stream)
222{
223 const struct j7_stream_out *out = (const struct j7_stream_out *)stream;
224
225 ALOGVV("out_get_channels() stream=%p channels=%u", stream, out->requested_channels);
226
227 return audio_channel_out_mask_from_count(out->requested_channels);
228}
229
230static audio_format_t out_get_format(const struct audio_stream *stream)
231{
232 audio_format_t format = DEFAULT_AUDIO_FORMAT;
233 UNUSED(stream);
234 ALOGVV("out_get_format() stream=%p format=0x%08x (%zu bits/sample)",
235 stream, format, audio_bytes_per_sample(format) << 3);
236 return format;
237}
238
239static int out_set_format(struct audio_stream *stream, audio_format_t format)
240{
241 UNUSED(stream);
242 ALOGVV("out_set_format() stream=%p format=0x%08x (%zu bits/sample)",
243 stream, format, audio_bytes_per_sample(format) << 3);
244
245 if (format != DEFAULT_AUDIO_FORMAT) {
246 return -ENOSYS;
247 } else {
248 return 0;
249 }
250}
251
252/* must be called with locks held */
253static void do_out_standby(struct j7_stream_out *out)
254{
255 struct j7_audio_device *adev = out->dev;
256
257 if (!out->standby) {
258 ALOGV("do_out_standby() close card %u port %u", out->card, out->port);
259 pcm_close(out->pcm);
260 out->pcm = NULL;
261 out->standby = true;
262 }
263}
264
265static int out_standby(struct audio_stream *stream)
266{
267 struct j7_stream_out *out = (struct j7_stream_out *)(stream);
268 struct j7_audio_device *adev = out->dev;
269
270 ALOGV("out_standby() stream=%p", out);
271 pthread_mutex_lock(&adev->lock);
272 pthread_mutex_lock(&out->lock);
273 do_out_standby(out);
274 pthread_mutex_unlock(&out->lock);
275 pthread_mutex_unlock(&adev->lock);
276
277 return 0;
278}
279
280static int out_dump(const struct audio_stream *stream, int fd)
281{
282 UNUSED(stream);
283 UNUSED(fd);
284 /* As of now nothing to dump any debug data */
285 return 0;
286}
287
288static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
289{
290 struct j7_stream_out *out = (struct j7_stream_out *)(stream);
291 struct j7_audio_device *adev = out->dev;
292 struct str_parms *parms;
293 char value[32];
294 int ret;
295 uint32_t val = 0;
296
297 ALOGV("out_set_parameters() stream=%p parameter='%s'", out, kvpairs);
298
299 parms = str_parms_create_str(kvpairs);
300
301 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
302 if (ret >= 0) {
303 /* Here the value is properly checked and filled by the framework */
304 val = atoi(value);
305 pthread_mutex_lock(&adev->lock);
306 pthread_mutex_lock(&out->lock);
307 if (val != 0) {
308 if ((out->device & AUDIO_DEVICE_OUT_ALL) != val) {
309 ALOGI("out_set_parameters() forcing standby");
310 do_out_standby(out);
311 }
312
313 /* set the active output device */
314 out->device = val;
315 }
316 pthread_mutex_unlock(&out->lock);
317 pthread_mutex_unlock(&adev->lock);
318 }
319 str_parms_destroy(parms);
320 return 0;
321}
322
323static char* out_get_parameters(const struct audio_stream *stream, const char *keys)
324{
325 UNUSED(stream);
326 UNUSED(keys);
327 /* Caller will be freeing this memory */
328 return strdup("");
329}
330
331static uint32_t out_get_latency(const struct audio_stream_out *stream)
332{
333 const struct j7_stream_out *out = (const struct j7_stream_out *)(stream);
334 uint32_t frames = PLAYBACK_BUFFER_SIZE;
335 uint32_t latency = (frames * 1000) / PLAYBACK_SAMPLE_RATE;
336
337 ALOGVV("out_get_latency() stream=%p latency=%u msecs", out, latency);
338
339 return latency;
340}
341
342static int out_set_volume(struct audio_stream_out *stream, float left,
343 float right)
344{
345 UNUSED(stream);
346 UNUSED(left);
347 UNUSED(right);
348 /* As of now we dont support this operation */
349 return -ENOSYS;
350}
351
352static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
353 size_t bytes)
354{
355 const struct audio_stream_out *s = (const struct audio_stream_out *)stream;
356 struct j7_stream_out *out = (struct j7_stream_out *)(stream);
357 struct j7_audio_device *adev = out->dev;
358 struct timespec now;
359 const size_t frame_size = audio_stream_out_frame_size(s);
360 size_t frames = bytes / frame_size;
361 size_t hw_frames;
362 uint32_t rate = out->requested_rate;
363 uint32_t write_usecs = frames * 1000000 / rate;
364 uint32_t diff_usecs;
365 const void *hw_buf;
366 void *in_buf;
367 int ret = 0;
368
369 ALOGVV("out_write() stream=%p buffer=%p size=%zu/%u time=%u usecs",
370 out, buffer, frames, rate, write_usecs);
371
372 pthread_mutex_lock(&adev->lock);
373 pthread_mutex_lock(&out->lock);
374
375 if (out->standby) {
376 ALOGI("out_write() open card %u port %u", out->card, out->port);
377
378 out->pcm = pcm_open(out->card, out->port,
379 PCM_OUT | PCM_MONOTONIC,
380 &out->config);
381 if (!pcm_is_ready(out->pcm)) {
382 ALOGE("out_write() failed to open pcm out: %s", pcm_get_error(out->pcm));
383 pcm_close(out->pcm);
384 out->pcm = NULL;
385 ret = -ENODEV;
386 }
387 if (ret) {
388 usleep(write_usecs); /* limits the rate of error messages */
389 pthread_mutex_unlock(&out->lock);
390 pthread_mutex_unlock(&adev->lock);
391 return ret;
392 }
393
394 out->standby = false;
395 }
396
397 pthread_mutex_unlock(&adev->lock);
398
399 hw_frames = frames;
400 hw_buf = buffer;
401
402 ret = pcm_write(out->pcm, hw_buf, hw_frames * out->hw_frame_size);
403 if (ret) {
404 ALOGE("out_write() failed to write audio data %d", ret);
405 usleep(write_usecs); /* limits the rate of error messages */
406 }
407
408 out->written += frames;
409
410 pthread_mutex_unlock(&out->lock);
411
412 return bytes;
413}
414
415static int out_get_render_position(const struct audio_stream_out *stream,
416 uint32_t *dsp_frames)
417{
418 UNUSED(stream);
419 UNUSED(dsp_frames);
420 /* As of now we dont support this operation */
421 return -ENOSYS;
422}
423
424static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
425{
426 UNUSED(stream);
427 UNUSED(effect);
428 /* As of now we dont support this operation */
429 return 0;
430}
431
432static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
433{
434 UNUSED(stream);
435 UNUSED(effect);
436 /* As of now we dont support this operation */
437 return 0;
438}
439
440static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
441 int64_t *timestamp)
442{
443 UNUSED(stream);
444 UNUSED(timestamp);
445 /* As of now we dont support this operation */
446 return -ENOSYS;
447}
448
449static int out_get_presentation_position(const struct audio_stream_out *stream,
450 uint64_t *frames, struct timespec *timestamp)
451{
452 struct j7_stream_out *out = (struct j7_stream_out *)(stream);
453 struct j7_audio_device *adev = out->dev;
454 int64_t signed_frames = -1;
455 uint32_t avail;
456 int ret = -1;
457
458 pthread_mutex_lock(&out->lock);
459
460 if (out->pcm &&
461 (pcm_get_htimestamp(out->pcm, &avail, timestamp) == 0)) {
462 signed_frames = out->written - pcm_get_buffer_size(out->pcm) + avail;
463 }
464
465 /* It would be unusual for this value to be negative, but check just in case ... */
466 if (signed_frames >= 0) {
467 *frames = signed_frames;
468 ret = 0;
469 }
470
471 pthread_mutex_unlock(&out->lock);
472
473 return ret;
474}
475
476/** audio_stream_in implementation **/
477static uint32_t in_get_sample_rate(const struct audio_stream *stream)
478{
479 const struct j7_stream_in *in = (const struct j7_stream_in *)(stream);
480
481 ALOGVV("in_get_sample_rate() stream=%p rate=%u", stream, in->requested_rate);
482
483 return in->requested_rate;
484}
485
486static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
487{
488 ALOGV("in_set_sample_rate() stream=%p rate=%u", stream, rate);
489 /* Only 48KHz is supported so we simply return 0 */
490 return 0;
491}
492
493static size_t in_get_buffer_size(const struct audio_stream *stream)
494{
495 const struct j7_stream_in *in = (const struct j7_stream_in *)(stream);
496
497 size_t bytes = get_input_buffer_size(in->requested_rate,
498 DEFAULT_AUDIO_FORMAT,
499 in->requested_channels);
500
501 ALOGE("in_get_buffer_size() stream=%p bytes=%zu", in, bytes);
502
503 return bytes;
504}
505
506static audio_channel_mask_t in_get_channels(const struct audio_stream *stream)
507{
508 const struct j7_stream_in *in = (const struct j7_stream_in *)(stream);
509 audio_channel_mask_t channels = audio_channel_in_mask_from_count(in->requested_channels);
510
511 ALOGVV("in_get_channels() stream=%p channels=%u", in, in->requested_channels);
512
513 return channels;
514}
515
516static audio_format_t in_get_format(const struct audio_stream *stream)
517{
518 audio_format_t format = DEFAULT_AUDIO_FORMAT;
519
520 UNUSED(stream);
521 ALOGVV("in_set_format() stream=%p format=0x%08x (%zu bits/sample)",
522 stream, format, audio_bytes_per_sample(format) << 3);
523
524 return format;
525}
526
527static int in_set_format(struct audio_stream *stream, audio_format_t format)
528{
529 UNUSED(stream);
530 ALOGV("in_set_format() stream=%p format=0x%08x (%zu bits/sample)",
531 stream, format, audio_bytes_per_sample(format) << 3);
532
533 if (format != DEFAULT_AUDIO_FORMAT) {
534 return -ENOSYS;
535 } else {
536 return 0;
537 }
538}
539
540/* must be called with locks held */
541static void do_in_standby(struct j7_stream_in *in)
542{
543 struct j7_audio_device *adev = in->dev;
544
545 if (!in->standby) {
546 ALOGI("do_in_standby() close card %u port %u", in->card, in->port);
547 pcm_close(in->pcm);
548 in->pcm = NULL;
549 in->standby = true;
550 }
551}
552
553static int in_standby(struct audio_stream *stream)
554{
555 struct j7_stream_in *in = (struct j7_stream_in *)(stream);
556 struct j7_audio_device *adev = in->dev;
557
558 ALOGV("in_standby() stream=%p", in);
559 pthread_mutex_lock(&adev->lock);
560 pthread_mutex_lock(&in->lock);
561 do_in_standby(in);
562 pthread_mutex_unlock(&in->lock);
563 pthread_mutex_unlock(&adev->lock);
564
565 return 0;
566}
567
568static int in_dump(const struct audio_stream *stream, int fd)
569{
570 UNUSED(stream);
571 UNUSED(fd);
572 /* As of now nothing to dump anu debug data */
573 return 0;
574}
575
576static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
577{
578 struct j7_stream_in *in = (struct j7_stream_in *)(stream);
579 struct j7_audio_device *adev = in->dev;
580 struct str_parms *parms;
581 char value[32];
582 int ret;
583 uint32_t val = 0;
584
585 ALOGV("in_set_parameters() stream=%p parameter='%s'", stream, kvpairs);
586
587 parms = str_parms_create_str(kvpairs);
588
589 /* Nothing to do for AUDIO_PARAMETER_STREAM_INPUT_SOURCE, so it's ignored */
590
591 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
592 if (ret >= 0) {
593 /* Here the value is properly checked and filled by the framework */
594 val = atoi(value);
595 pthread_mutex_lock(&adev->lock);
596 pthread_mutex_lock(&in->lock);
597 if (val != 0) {
598 if ((in->device & AUDIO_DEVICE_IN_ALL) != val)
599 do_in_standby(in);
600
601 /* set the active input device */
602 in->device = val;
603 }
604 pthread_mutex_unlock(&in->lock);
605 pthread_mutex_unlock(&adev->lock);
606 }
607 str_parms_destroy(parms);
608 return 0;
609}
610
611static char * in_get_parameters(const struct audio_stream *stream,
612 const char *keys)
613{
614 UNUSED(stream);
615 UNUSED(keys);
616 /* As of now we dont support this operation */
617 return strdup("");
618}
619
620static int in_set_gain(struct audio_stream_in *stream, float gain)
621{
622 UNUSED(stream);
623 UNUSED(gain);
624 /* As of now we dont support this operation */
625 return 0;
626}
627
628static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
629 size_t bytes)
630{
631 const struct audio_stream_in *s = (const struct audio_stream_in *)stream;
632 struct j7_stream_in *in = (struct j7_stream_in *)(stream);
633 struct j7_audio_device *adev = in->dev;
634 const size_t frame_size = audio_stream_in_frame_size(stream);
635 const size_t frames = bytes / frame_size;
636 uint32_t rate = in_get_sample_rate(&stream->common);
637 uint32_t read_usecs = frames * 1000000 / rate;
638 int ret;
639
640 ALOGVV("in_read() stream=%p buffer=%p size=%zu/%u time=%u usecs",
641 stream, buffer, frames, rate, read_usecs);
642
643 pthread_mutex_lock(&adev->lock);
644 pthread_mutex_lock(&in->lock);
645
646 if (in->standby) {
647 ALOGE("in_read() open card %u port %u", in->card, in->port);
648 in->pcm = pcm_open(in->card, in->port,
649 PCM_IN | PCM_MONOTONIC,
650 &in->config);
651 if (!pcm_is_ready(in->pcm)) {
652 ALOGE("in_read() failed to open pcm in: %s", pcm_get_error(in->pcm));
653 pcm_close(in->pcm);
654 in->pcm = NULL;
655 usleep(read_usecs); /* limits the rate of error messages */
656 pthread_mutex_unlock(&in->lock);
657 pthread_mutex_unlock(&adev->lock);
658 return -ENODEV;
659 }
660 in->standby = false;
661 }
662
663 pthread_mutex_unlock(&adev->lock);
664 ret = pcm_read(in->pcm, buffer, bytes);
665
666 if (ret < 0) {
667 ALOGE("in_read() failed to read audio data %d", ret);
668 usleep(read_usecs); /* limits the rate of error messages */
669 memset(buffer, 0, bytes);
670 } else if (adev->mic_mute) {
671 memset(buffer, 0, bytes);
672 }
673
674 pthread_mutex_unlock(&in->lock);
675
676 return bytes;
677}
678
679static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
680{
681 UNUSED(stream);
682 ALOGVV("in_get_input_frames_lost() stream=%p frames=%u", stream, 0);
683 /* As of now we dont support this operation */
684 return 0;
685}
686
687static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
688{
689 UNUSED(stream);
690 UNUSED(effect);
691 /* As of now we dont support this operation */
692 return 0;
693}
694
695static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
696{
697 UNUSED(stream);
698 UNUSED(effect);
699 /* As of now we dont support this operation */
700 return 0;
701}
702
703static int adev_open_output_stream(struct audio_hw_device *dev,
704 audio_io_handle_t handle,
705 audio_devices_t devices,
706 audio_output_flags_t flags,
707 struct audio_config *config,
708 struct audio_stream_out **stream_out,
709 const char *address)
710{
711 struct j7_audio_device *adev = (struct j7_audio_device *)dev;
712 struct j7_stream_out *out;
713 int buffer_size;
714 int ret;
715
716 UNUSED(handle);
717 UNUSED(devices);
718 UNUSED(address);
719
720 out = (struct j7_stream_out *)calloc(1, sizeof(struct j7_stream_out));
721 if (!out)
722 return -ENOMEM;
723
724 ALOGV("adev_open_output_stream() stream=%p rate=%u channels=%u "
725 "format=0x%08x flags=0x%08x",
726 out, config->sample_rate, popcount(config->channel_mask),
727 config->format, flags);
728
729 pthread_mutex_init(&out->lock, NULL);
730
731 out->stream.common.get_sample_rate = out_get_sample_rate;
732 out->stream.common.set_sample_rate = out_set_sample_rate;
733 out->stream.common.get_buffer_size = out_get_buffer_size;
734 out->stream.common.get_channels = out_get_channels;
735 out->stream.common.get_format = out_get_format;
736 out->stream.common.set_format = out_set_format;
737 out->stream.common.standby = out_standby;
738 out->stream.common.dump = out_dump;
739 out->stream.common.set_parameters = out_set_parameters;
740 out->stream.common.get_parameters = out_get_parameters;
741 out->stream.common.add_audio_effect = out_add_audio_effect;
742 out->stream.common.remove_audio_effect = out_remove_audio_effect;
743 out->stream.get_latency = out_get_latency;
744 out->stream.set_volume = out_set_volume;
745 out->stream.write = out_write;
746 out->stream.get_render_position = out_get_render_position;
747 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
748 out->stream.get_presentation_position = out_get_presentation_position;
749
750 out->dev = adev;
751 out->standby = true;
752 out->config = pcm_config_playback;
753 out->requested_rate = config->sample_rate;
754 out->requested_channels = popcount(config->channel_mask);
755 out->hw_frame_size = out->config.channels * BYTES_PER_SAMPLE;
756 out->written = 0;
757 out->card = adev->card;
758 out->port = 0;
759 out->device = devices;
760 adev->out = out;
761 *stream_out = &out->stream;
762
763 return 0;
764}
765
766static void adev_close_output_stream(struct audio_hw_device *dev,
767 struct audio_stream_out *stream)
768{
769 struct j7_audio_device *adev = (struct j7_audio_device *)dev;
770 struct j7_stream_out *out = (struct j7_stream_out *)(stream);
771
772 ALOGV("adev_close_output_stream() stream=%p", out);
773
774 out_standby(&stream->common);
775
776 free(out);
777 adev->out = NULL;
778}
779
780static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
781{
782 UNUSED(dev);
783 UNUSED(kvpairs);
784
785 ALOGV("adev_set_parameters() parameter='%s'", kvpairs);
786 /* As of now we dont support this operation */
787 return 0;
788}
789
790static char * adev_get_parameters(const struct audio_hw_device *dev,
791 const char *keys)
792{
793 UNUSED(dev);
794 UNUSED(keys);
795 /* As of now we dont support this operation */
796 return strdup("");;
797}
798
799static int adev_init_check(const struct audio_hw_device *dev)
800{
801 UNUSED(dev);
802 /* As of now we dont support this operation */
803 return 0;
804}
805
806static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
807{
808 UNUSED(dev);
809 UNUSED(volume);
810 /* As of now we dont support this operation */
811 return 0;
812}
813
814static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
815{
816 UNUSED(dev);
817 UNUSED(volume);
818 /* As of now we dont support this operation */
819 return -ENOSYS;
820}
821
822static int adev_get_master_volume(struct audio_hw_device *dev, float *volume)
823{
824 UNUSED(dev);
825 UNUSED(volume);
826 /* As of now we dont support this operation */
827 return -ENOSYS;
828}
829
830static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
831{
832 UNUSED(dev);
833 UNUSED(muted);
834 /* As of now we dont support this operation */
835 return -ENOSYS;
836}
837
838static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
839{
840 UNUSED(dev);
841 UNUSED(muted);
842 /* As of now we dont support this operation */
843 return -ENOSYS;
844}
845
846static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
847{
848 struct j7_audio_device *adev = (struct j7_audio_device *)dev;
849 int ret = 0;
850
851 ALOGV("adev_set_mode() mode=0x%08x", mode);
852
853 pthread_mutex_lock(&adev->lock);
854
855 if (adev->mode == mode) {
856 ALOGV("adev_set_mode() already in mode=0x%08x", mode);
857 goto out;
858 }
859
860 adev->mode = mode;
861
862out:
863 pthread_mutex_unlock(&adev->lock);
864
865 return ret;
866}
867
868static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
869{
870 struct j7_audio_device *adev = (struct j7_audio_device *)dev;
871
872 ALOGV("adev_set_mic_mute() state=%s", state ? "mute" : "unmute");
873 adev->mic_mute = state;
874
875 return 0;
876}
877
878static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
879{
880 const struct j7_audio_device *adev = (const struct j7_audio_device *)dev;
881
882 *state = adev->mic_mute;
883 ALOGV("adev_get_mic_mute() state=%s", *state ? "mute" : "unmute");
884
885 return 0;
886}
887
888static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
889 const struct audio_config *config)
890{
891 UNUSED(dev);
892
893 size_t bytes = get_input_buffer_size(config->sample_rate,
894 config->format,
895 popcount(config->channel_mask));
896
897 ALOGVV("adev_in_get_buffer_size() bytes=%zu", bytes);
898
899 return bytes;
900}
901
902static int adev_open_input_stream(struct audio_hw_device *dev,
903 audio_io_handle_t handle,
904 audio_devices_t devices,
905 struct audio_config *config,
906 struct audio_stream_in **stream_in,
907 audio_input_flags_t flags,
908 const char *address,
909 audio_source_t source)
910{
911 struct j7_audio_device *adev = (struct j7_audio_device *)dev;
912 struct j7_stream_in *in;
913 int buffer_size;
914 int ret;
915
916 UNUSED(handle);
917 UNUSED(flags);
918 UNUSED(address);
919 UNUSED(source);
920
921 in = (struct j7_stream_in *)calloc(1, sizeof(struct j7_stream_in));
922 if (!in)
923 return -ENOMEM;
924
925 ALOGE("adev_open_input_stream() stream=%p rate=%u channels=%u format=0x%08x",
926 in, config->sample_rate, popcount(config->channel_mask), config->format);
927
928 pthread_mutex_init(&in->lock, NULL);
929
930 in->stream.common.get_sample_rate = in_get_sample_rate;
931 in->stream.common.set_sample_rate = in_set_sample_rate;
932 in->stream.common.get_buffer_size = in_get_buffer_size;
933 in->stream.common.get_channels = in_get_channels;
934 in->stream.common.get_format = in_get_format;
935 in->stream.common.set_format = in_set_format;
936 in->stream.common.standby = in_standby;
937 in->stream.common.dump = in_dump;
938 in->stream.common.set_parameters = in_set_parameters;
939 in->stream.common.get_parameters = in_get_parameters;
940 in->stream.common.add_audio_effect = in_add_audio_effect;
941 in->stream.common.remove_audio_effect = in_remove_audio_effect;
942 in->stream.set_gain = in_set_gain;
943 in->stream.read = in_read;
944 in->stream.get_input_frames_lost = in_get_input_frames_lost;
945
946 in->dev = adev;
947 in->standby = true;
948 in->config = pcm_config_capture;
949 in->requested_rate = config->sample_rate;
950 in->requested_channels = popcount(config->channel_mask);
951 in->hw_frame_size = in->config.channels * BYTES_PER_SAMPLE;
952 in->card = adev->card;
953 in->port = 1;
954 in->device = devices;
955 adev->in = in;
956 *stream_in = &in->stream;
957
958 return 0;
959}
960
961static void adev_close_input_stream(struct audio_hw_device *dev,
962 struct audio_stream_in *stream)
963{
964 struct j7_audio_device *adev = (struct j7_audio_device *)dev;
965 struct j7_stream_in *in = (struct j7_stream_in *)(stream);
966
967 ALOGE("adev_close_input_stream() stream=%p", stream);
968
969 in_standby(&stream->common);
970
971 free(in);
972 adev->in = NULL;
973}
974
975static int adev_dump(const audio_hw_device_t *device, int fd)
976{
977 UNUSED(device);
978 UNUSED(fd);
979 /* As of now nothing to dump any debug data */
980 return 0;
981}
982
983static int adev_close(hw_device_t *device)
984{
985 struct j7_audio_device *adev = (struct j7_audio_device *)device;
986
987 ALOGI("adev_close()");
988
989 audio_route_free(adev->route);
990
991 free(device);
992
993 return 0;
994}
995
996static int adev_open(const hw_module_t* module, const char* name,
997 hw_device_t** device)
998{
999 struct j7_audio_device *adev;
1000
1001 ALOGI("adev_open() %s", name);
1002
1003 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
1004 return -EINVAL;
1005
1006 adev = (struct j7_audio_device*)calloc(1, sizeof(struct j7_audio_device));
1007 if (!adev)
1008 return -ENOMEM;
1009
1010 pthread_mutex_init(&adev->lock, NULL);
1011
1012 adev->device.common.tag = HARDWARE_DEVICE_TAG;
1013 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
1014 adev->device.common.module = (struct hw_module_t *) module;
1015 adev->device.common.close = adev_close;
1016 adev->device.init_check = adev_init_check;
1017 adev->device.set_voice_volume = adev_set_voice_volume;
1018 adev->device.set_master_volume = adev_set_master_volume;
1019 adev->device.get_master_volume = adev_get_master_volume;
1020 adev->device.set_master_mute = adev_set_master_mute;
1021 adev->device.get_master_mute = adev_get_master_mute;
1022 adev->device.set_mode = adev_set_mode;
1023 adev->device.set_mic_mute = adev_set_mic_mute;
1024 adev->device.get_mic_mute = adev_get_mic_mute;
1025 adev->device.set_parameters = adev_set_parameters;
1026 adev->device.get_parameters = adev_get_parameters;
1027 adev->device.get_input_buffer_size = adev_get_input_buffer_size;
1028 adev->device.open_output_stream = adev_open_output_stream;
1029 adev->device.close_output_stream = adev_close_output_stream;
1030 adev->device.open_input_stream = adev_open_input_stream;
1031 adev->device.close_input_stream = adev_close_input_stream;
1032 adev->device.dump = adev_dump;
1033 adev->card = 0;
1034
1035 ALOGI("adev_open() media card is hw:%d", adev->card);
1036
1037 adev->mic_mute = false;
1038
1039 adev->mode = AUDIO_MODE_NORMAL;
1040
1041 adev->route = audio_route_init(adev->card, MIXER_XML_PATH);
1042 if (!adev->route) {
1043 ALOGE("adev_open() unable to initialize audio routes");
1044 goto err1;
1045 }
1046
1047 *device = &adev->device.common;
1048
1049 return 0;
1050
1051 audio_route_free(adev->route);
1052 err1:
1053 free(adev);
1054 return -ENODEV;
1055}
1056
1057static struct hw_module_methods_t hal_module_methods = {
1058 .open = adev_open,
1059};
1060
1061struct audio_module HAL_MODULE_INFO_SYM = {
1062 .common = {
1063 .tag = HARDWARE_MODULE_TAG,
1064 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
1065 .hal_api_version = HARDWARE_HAL_API_VERSION,
1066 .id = AUDIO_HARDWARE_MODULE_ID,
1067 .name = "Jacinto7 Audio HAL",
1068 .author = "Texas Instruments Inc.",
1069 .methods = &hal_module_methods,
1070 },
1071};
diff --git a/audio/primary/audio_policy_configuration.xml b/audio/primary/audio_policy_configuration.xml
new file mode 100644
index 0000000..a4fc066
--- /dev/null
+++ b/audio/primary/audio_policy_configuration.xml
@@ -0,0 +1,34 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<!-- Primary Audio HAL Module Audio Policy Configuration include file -->
3<module name="primary" halVersion="2.0">
4 <attachedDevices>
5 <item>Speaker</item>
6 <item>Built-In Mic</item>
7 </attachedDevices>
8
9 <defaultOutputDevice>Speaker</defaultOutputDevice>
10
11 <mixPorts>
12 <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
13 <profile name="" format="AUDIO_FORMAT_PCM_24_BIT_PACKED"
14 samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
15 </mixPort>
16 <mixPort name="primary input" role="sink">
17 <profile name="" format="AUDIO_FORMAT_PCM_24_BIT_PACKED"
18 samplingRates="48000"
19 channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
20 </mixPort>
21 </mixPorts>
22
23 <devicePorts>
24 <devicePort tagName="Speaker" type="AUDIO_DEVICE_OUT_SPEAKER" role="sink">
25 </devicePort>
26 <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
27 </devicePort>
28 </devicePorts>
29
30 <routes>
31 <route type="mux" sink="Speaker" sources="primary output"/>
32 <route type="mix" sink="primary input" sources="Built-In Mic"/>
33 </routes>
34</module>
diff --git a/audio/primary/mixer_paths.xml b/audio/primary/mixer_paths.xml
new file mode 100644
index 0000000..3f37eea
--- /dev/null
+++ b/audio/primary/mixer_paths.xml
@@ -0,0 +1,13 @@
1<mixer>
2
3<!-- Card default routes -->
4
5<!-- Capture: Mic -->
6<ctl name="codec1 Master Capture Volume" value="197" />
7<ctl name="codec1 ADC1 Capture Volume" value="197" />
8
9<!-- Playback: Line-Out and Headphone -->
10<ctl name="codec1 Master Playback Volume" value="201" />
11<ctl name="codec1 DAC1 Playback Volume" value="201" />
12
13</mixer>
diff --git a/j721e.mk b/j721e.mk
index cb3ff33..7324f59 100644
--- a/j721e.mk
+++ b/j721e.mk
@@ -16,3 +16,4 @@
16 16
17PRODUCT_PACKAGES += \ 17PRODUCT_PACKAGES += \
18 hwcomposer.j721e \ 18 hwcomposer.j721e \
19 audio.primary.j721e \