summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAngela Stegmaier2013-10-21 14:14:33 -0500
committerMisael Lopez Cruz2013-11-01 01:47:04 -0500
commitacd259ce699578c3d2f6fc075fbaa3d5a5cbba5f (patch)
tree408372ae244888df49b1fd16bd8f3991e1eb1fd6 /audio/legacy
parentc795bdfa151f6643f968b5f23408032ae79be22a (diff)
downloaddevice-ti-jacinto6evm-acd259ce699578c3d2f6fc075fbaa3d5a5cbba5f.tar.gz
device-ti-jacinto6evm-acd259ce699578c3d2f6fc075fbaa3d5a5cbba5f.tar.xz
device-ti-jacinto6evm-acd259ce699578c3d2f6fc075fbaa3d5a5cbba5f.zip
audio: Move jacinto6evm Audio HAL to new folder
The existing Audio HAL is moved to a new folder named "legacy". This change is done in preparation for adding the multizone support to the same audio folder. Change-Id: Id8c7417a1b5f4fba59ab021bc136e7f451aac551 Signed-off-by: Angela Stegmaier <a0866189@ti.com>
Diffstat (limited to 'audio/legacy')
-rw-r--r--audio/legacy/Android.mk41
-rw-r--r--audio/legacy/audio_hw.c1301
-rw-r--r--audio/legacy/audio_policy.conf94
3 files changed, 1436 insertions, 0 deletions
diff --git a/audio/legacy/Android.mk b/audio/legacy/Android.mk
new file mode 100644
index 0000000..a374c56
--- /dev/null
+++ b/audio/legacy/Android.mk
@@ -0,0 +1,41 @@
1# Copyright (C) 2013 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 jacinto6, $(TARGET_BOARD_PLATFORM)),jacinto6)
18
19include $(CLEAR_VARS)
20
21LOCAL_MODULE := audio.primary.$(TARGET_BOARD_PLATFORM)
22
23LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
24LOCAL_SRC_FILES := audio_hw.c
25
26LOCAL_C_INCLUDES += \
27 external/tinyalsa/include \
28 system/media/audio_utils/include \
29 system/media/audio_effects/include
30
31LOCAL_SHARED_LIBRARIES := \
32 liblog \
33 libcutils \
34 libtinyalsa \
35 libaudioutils
36
37LOCAL_MODULE_TAGS := optional
38
39include $(BUILD_SHARED_LIBRARY)
40
41endif
diff --git a/audio/legacy/audio_hw.c b/audio/legacy/audio_hw.c
new file mode 100644
index 0000000..671c83a
--- /dev/null
+++ b/audio/legacy/audio_hw.c
@@ -0,0 +1,1301 @@
1/*
2 * Copyright (C) 2013 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 <sys/time.h>
30
31#include <cutils/log.h>
32#include <cutils/str_parms.h>
33#include <cutils/properties.h>
34
35#include <audio_utils/resampler.h>
36#include <system/audio.h>
37#include <hardware/hardware.h>
38#include <hardware/audio.h>
39#include <hardware/audio_effect.h>
40
41#include <tinyalsa/asoundlib.h>
42
43/* yet another definition of ARRAY_SIZE macro) */
44#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
45
46/* buffer_remix: functor for doing in-place buffer manipulations.
47 *
48 * NB. When remix_func is called, the memory at `buf` must be at least
49 * as large as frames * sample_size * MAX(in_chans, out_chans).
50 */
51struct buffer_remix {
52 void (*remix_func)(struct buffer_remix *data, void *buf, size_t frames);
53 size_t sample_size; /* size of one audio sample, in bytes */
54 size_t in_chans; /* number of input channels */
55 size_t out_chans; /* number of output channels */
56};
57
58struct j6_audio_device {
59 struct audio_hw_device device;
60 struct j6_stream_in *in;
61 struct j6_stream_out *out;
62 struct mixer *mixer;
63 audio_devices_t in_device;
64 audio_devices_t out_device;
65 pthread_mutex_t lock;
66 unsigned int card;
67 unsigned int in_port;
68 unsigned int out_port;
69 bool mic_mute;
70};
71
72struct j6_stream_in {
73 struct audio_stream_in stream;
74 struct j6_audio_device *dev;
75 struct pcm_config config;
76 struct pcm *pcm;
77 struct buffer_remix *remix; /* adapt hw chan count to client */
78 struct resampler_itfe *resampler;
79 struct resampler_buffer_provider buf_provider;
80 int16_t *buffer;
81 size_t frames_in;
82 size_t hw_frame_size;
83 unsigned int requested_rate;
84 unsigned int requested_channels;
85 int read_status;
86 pthread_mutex_t lock;
87 bool standby;
88};
89
90struct j6_stream_out {
91 struct audio_stream_out stream;
92 struct j6_audio_device *dev;
93 struct pcm_config config;
94 struct pcm *pcm;
95 pthread_mutex_t lock;
96 bool standby;
97};
98
99
100static const char *supported_cards[] = {
101 "dra7evm",
102 "VayuEVM",
103};
104
105#define SUPPORTED_IN_DEVICES (AUDIO_DEVICE_IN_BUILTIN_MIC | \
106 AUDIO_DEVICE_IN_WIRED_HEADSET | \
107 AUDIO_DEVICE_IN_DEFAULT)
108#define SUPPORTED_OUT_DEVICES (AUDIO_DEVICE_OUT_SPEAKER | \
109 AUDIO_DEVICE_OUT_WIRED_HEADSET | \
110 AUDIO_DEVICE_OUT_WIRED_HEADPHONE | \
111 AUDIO_DEVICE_OUT_DEFAULT)
112
113#define CAPTURE_SAMPLE_RATE 44100
114#define CAPTURE_PERIOD_SIZE 320
115#define CAPTURE_PERIOD_COUNT 2
116#define CAPTURE_BUFFER_SIZE (CAPTURE_PERIOD_SIZE * CAPTURE_PERIOD_COUNT)
117
118#define PLAYBACK_SAMPLE_RATE 44100
119#define PLAYBACK_PERIOD_SIZE 960
120#define PLAYBACK_PERIOD_COUNT 4
121#define PLAYBACK_BUFFER_SIZE (PLAYBACK_PERIOD_SIZE * PLAYBACK_PERIOD_COUNT)
122
123struct pcm_config pcm_config_capture = {
124 .channels = 2,
125 .rate = CAPTURE_SAMPLE_RATE,
126 .format = PCM_FORMAT_S16_LE,
127 .period_size = CAPTURE_PERIOD_SIZE,
128 .period_count = CAPTURE_PERIOD_COUNT,
129 .start_threshold = 1,
130 .stop_threshold = CAPTURE_BUFFER_SIZE,
131};
132
133struct pcm_config pcm_config_playback = {
134 .channels = 2,
135 .rate = PLAYBACK_SAMPLE_RATE,
136 .format = PCM_FORMAT_S16_LE,
137 .period_size = PLAYBACK_PERIOD_SIZE,
138 .period_count = PLAYBACK_PERIOD_COUNT,
139 .start_threshold = PLAYBACK_BUFFER_SIZE / 2,
140 .stop_threshold = PLAYBACK_BUFFER_SIZE,
141 .avail_min = PLAYBACK_PERIOD_SIZE,
142};
143
144/* Mixer control names */
145
146/* Capture */
147#define MIXER_PGA_CAPTURE_SWITCH "PGA Capture Switch"
148#define MIXER_PGA_CAPTURE_VOLUME "PGA Capture Volume"
149
150/* Capture gain (0dB, 59.5dB) step=0.5 */
151#define CAPTURE_DB_TO_VAL(x) ((int)(2 * (float)(x)))
152
153/* Microphone specific */
154#define MIXER_LEFT_PGA_MIC3L_SWITCH "Left PGA Mixer Mic3L Switch"
155#define MIXER_RIGHT_PGA_MIC3R_SWITCH "Right PGA Mixer Mic3R Switch"
156
157/* Line-In specific */
158#define MIXER_LEFT_PGA_LINE1L_SWITCH "Left PGA Mixer Line1L Switch"
159#define MIXER_RIGHT_PGA_LINE1R_SWITCH "Right PGA Mixer Line1R Switch"
160#define MIXER_LEFT_LINE1L_MUX "Left Line1L Mux"
161#define MIXER_RIGHT_LINE1L_MUX "Right Line1L Mux"
162#define MIXER_LEFT_LINE1R_MUX "Left Line1R Mux"
163#define MIXER_RIGHT_LINE1R_MUX "Right Line1R Mux"
164#define MIXER_LINE_IN_SINGLE_ENDED "single-ended"
165#define MIXER_LINE_IN_DIFFERENTIAL "differential"
166
167/* Playback */
168#define MIXER_LEFT_DAC_MUX "Left DAC Mux"
169#define MIXER_RIGHT_DAC_MUX "Right DAC Mux"
170#define MIXER_MUX_DAC_L1 "DAC_L1"
171#define MIXER_MUX_DAC_R1 "DAC_R1"
172#define MIXER_PCM_PLAYBACK_VOLUME "PCM Playback Volume"
173
174 /* Playback gain (-63.5dB, 0dB) step=0.5dB */
175#define PLAYBACK_DB_TO_VAL(x) ((int)(2 * ((float)(x) + 63.5)))
176
177/* Headphone specific */
178#define MIXER_HP_PLAYBACK_SWITCH "HP Playback Switch"
179#define MIXER_LEFT_HP_DACL1_SWITCH "Left HP Mixer DACL1 Switch"
180#define MIXER_RIGHT_HP_DACR1_SWITCH "Right HP Mixer DACR1 Switch"
181#define HP_PLAYBACK_VOLUME "HP DAC Playback Volume"
182#define HP_DRIVER_POWER_ON_TIME "Output Driver Power-On time"
183#define HP_DRIVER_DELAY "200ms"
184
185/* Line-Out specific */
186#define MIXER_LINE_PLAYBACK_SWITCH "Line Playback Switch"
187#define MIXER_LEFT_LINE_DACL1_SWITCH "Left Line Mixer DACL1 Switch"
188#define MIXER_RIGHT_LINE_DACR1_SWITCH "Right Line Mixer DACR1 Switch"
189#define LINE_PLAYBACK_VOLUME "Line DAC Playback Volume"
190
191 /* Output stage gain (-59.0dB, 0dB) step=0.5dB */
192#define OUTPUT_DB_TO_VAL(x) ((int)(2 * ((float)(x) + 59.0)))
193
194struct route_setting {
195 char *ctl_name;
196 int intval;
197 char *strval;
198};
199
200#define RS_STR(ctrl, str) { .ctl_name = ctrl, .strval = str }
201#define RS_INT(ctrl, val) { .ctl_name = ctrl, .intval = val }
202#define RS_END { .ctl_name = NULL, .strval = NULL }
203
204/* These are values that never change */
205static struct route_setting rs_defaults[] = {
206 /* Capture: Mic */
207 RS_INT(MIXER_LEFT_PGA_MIC3L_SWITCH, 1),
208 RS_INT(MIXER_RIGHT_PGA_MIC3R_SWITCH, 1),
209 RS_INT(MIXER_PGA_CAPTURE_SWITCH, 1),
210 RS_INT(MIXER_PGA_CAPTURE_VOLUME, CAPTURE_DB_TO_VAL(12)), /* 12dB */
211 RS_STR(MIXER_LEFT_LINE1L_MUX, MIXER_LINE_IN_SINGLE_ENDED),
212 RS_STR(MIXER_RIGHT_LINE1L_MUX, MIXER_LINE_IN_SINGLE_ENDED),
213 RS_STR(MIXER_LEFT_LINE1R_MUX, MIXER_LINE_IN_SINGLE_ENDED),
214 RS_STR(MIXER_RIGHT_LINE1R_MUX, MIXER_LINE_IN_SINGLE_ENDED),
215
216 /* Playback: Line-Out and Headphone */
217 RS_STR(MIXER_LEFT_DAC_MUX, MIXER_MUX_DAC_L1),
218 RS_STR(MIXER_RIGHT_DAC_MUX, MIXER_MUX_DAC_R1),
219 RS_INT(MIXER_PCM_PLAYBACK_VOLUME, PLAYBACK_DB_TO_VAL(0)), /* 0dB */
220
221 RS_INT(MIXER_LEFT_HP_DACL1_SWITCH, 1),
222 RS_INT(MIXER_RIGHT_HP_DACR1_SWITCH, 1),
223 RS_INT(MIXER_HP_PLAYBACK_SWITCH, 1),
224 RS_INT(HP_PLAYBACK_VOLUME, OUTPUT_DB_TO_VAL(0)), /* 0 dB */
225 RS_STR(HP_DRIVER_POWER_ON_TIME, HP_DRIVER_DELAY),
226
227 RS_INT(MIXER_LEFT_LINE_DACL1_SWITCH, 1),
228 RS_INT(MIXER_RIGHT_LINE_DACR1_SWITCH, 1),
229 RS_INT(MIXER_LINE_PLAYBACK_SWITCH, 1),
230 RS_INT(LINE_PLAYBACK_VOLUME, OUTPUT_DB_TO_VAL(0)), /* 0 dB */
231};
232
233/* Capture switch used for mic mute */
234static struct route_setting rs_capture[] = {
235 RS_INT(MIXER_PGA_CAPTURE_SWITCH, 1),
236 RS_END
237};
238
239/*
240 * The enable flag when 0 makes the assumption that enums are disabled by
241 * "Off" and integers/booleans by 0
242 */
243static int set_route_by_array(struct mixer *mixer, struct route_setting *route,
244 int enable)
245{
246 struct mixer_ctl *ctl;
247 unsigned int i, j;
248
249 ALOGV("set_route_by_array() route=%p %s", route, enable ? "enable" : "disable");
250
251 /* Go through the route array and set each value */
252 i = 0;
253 while (route[i].ctl_name) {
254 ctl = mixer_get_ctl_by_name(mixer, route[i].ctl_name);
255 if (!ctl) {
256 ALOGE("set_route_by_array() failed to get control '%s'", route[i].ctl_name);
257 return -EINVAL;
258 }
259
260 if (route[i].strval) {
261 ALOGV("set_route_by_array() control='%s' val='%s'",
262 route[i].ctl_name, enable ? route[i].strval: "Off");
263
264 if (enable)
265 mixer_ctl_set_enum_by_string(ctl, route[i].strval);
266 else
267 mixer_ctl_set_enum_by_string(ctl, "Off");
268 } else {
269 ALOGV("set_route_by_array() control='%s' val=%d",
270 route[i].ctl_name, route[i].intval);
271
272 /* This ensures multiple (i.e. stereo) values are set jointly */
273 for (j = 0; j < mixer_ctl_get_num_values(ctl); j++) {
274 if (enable)
275 mixer_ctl_set_value(ctl, j, route[i].intval);
276 else
277 mixer_ctl_set_value(ctl, j, 0);
278 }
279 }
280 i++;
281 }
282
283 return 0;
284}
285
286static int find_supported_card(void)
287{
288 char name[256] = "";
289 int card = 0;
290 int found = 0;
291 unsigned int i;
292
293 do {
294 /* returns an error after last valid card */
295 int ret = mixer_get_card_name(card, name, sizeof(name));
296 if (ret)
297 break;
298
299 for (i = 0; i < ARRAY_SIZE(supported_cards); ++i) {
300 if (supported_cards[i] && !strcmp(name, supported_cards[i])) {
301 ALOGV("Supported card '%s' found at %d", name, card);
302 found = 1;
303 break;
304 }
305 }
306 } while (!found && (card++ < MAX_CARD_COUNT));
307
308 /* Use default card number if not found */
309 if (!found)
310 card = 1;
311
312 return card;
313}
314
315/* must be called with device lock held */
316static void select_input_device(struct j6_audio_device *adev)
317{
318 if (adev->in_device & ~SUPPORTED_IN_DEVICES)
319 ALOGW("select_input_device() device not supported, will use default device");
320}
321
322/* must be called with device lock held */
323static void select_output_device(struct j6_audio_device *adev)
324{
325 if (adev->out_device & ~SUPPORTED_OUT_DEVICES)
326 ALOGW("select_output_device() device(s) not supported, will use default devices");
327}
328
329static size_t get_input_buffer_size(uint32_t sample_rate, int format, int channel_count)
330{
331 size_t size;
332
333 /*
334 * take resampling into account and return the closest majoring
335 * multiple of 16 frames, as audioflinger expects audio buffers to
336 * be a multiple of 16 frames
337 */
338 size = (pcm_config_capture.period_size * sample_rate) / pcm_config_capture.rate;
339 size = ((size + 15) / 16) * 16;
340
341 return size * channel_count * sizeof(int16_t);
342}
343
344/*
345 * Implementation of buffer_remix::remix_func that removes
346 * channels in place without doing any other processing. The
347 * extra channels are truncated.
348 */
349static void remove_channels_from_buf(struct buffer_remix *data, void *buf, size_t frames)
350{
351 size_t samp_size, in_frame, out_frame;
352 size_t N, c;
353 char *s, *d;
354
355 ALOGVV("remove_channels_from_buf() remix=%p buf=%p frames=%u",
356 data, buf, frames);
357
358 if (frames == 0)
359 return;
360
361 samp_size = data->sample_size;
362 in_frame = data->in_chans * samp_size;
363 out_frame = data->out_chans * samp_size;
364
365 if (out_frame >= in_frame) {
366 ALOGE("BUG: remove_channels_from_buf() can not add channels to a buffer.\n");
367 return;
368 }
369
370 N = frames - 1;
371 d = (char*)buf + out_frame;
372 s = (char*)buf + in_frame;
373
374 /* take the first several channels and truncate the rest */
375 while (N--) {
376 for (c = 0; c < out_frame; ++c)
377 d[c] = s[c];
378 d += out_frame;
379 s += in_frame;
380 }
381}
382
383static int setup_stereo_to_mono_input_remix(struct j6_stream_in *in)
384{
385 ALOGV("setup_stereo_to_mono_input_remix() stream=%p", in);
386
387 struct buffer_remix *br = (struct buffer_remix *)malloc(sizeof(struct buffer_remix));
388 if (!br)
389 return -ENOMEM;
390
391 br->remix_func = remove_channels_from_buf;
392 br->sample_size = sizeof(int16_t);
393 br->in_chans = 2;
394 br->out_chans = 1;
395 in->remix = br;
396
397 return 0;
398}
399
400/* audio HAL functions */
401
402static uint32_t out_get_sample_rate(const struct audio_stream *stream)
403{
404 uint32_t rate = PLAYBACK_SAMPLE_RATE;
405
406 ALOGVV("out_get_sample_rate() stream=%p rate=%u", stream, rate);
407
408 return rate;
409}
410
411static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
412{
413 ALOGVV("out_set_sample_rate() stream=%p rate=%u", stream, rate);
414
415 return 0;
416}
417
418static size_t out_get_buffer_size(const struct audio_stream *stream)
419{
420 uint32_t frames = ((PLAYBACK_PERIOD_SIZE + 15) / 16) * 16;
421 size_t bytes = frames * audio_stream_frame_size(stream);
422
423 ALOGVV("out_get_buffer_size() stream=%p frames=%u bytes=%u", stream, frames, bytes);
424
425 return bytes;
426}
427
428static audio_channel_mask_t out_get_channels(const struct audio_stream *stream)
429{
430 audio_channel_mask_t channels = AUDIO_CHANNEL_OUT_STEREO;
431
432 ALOGVV("out_get_channels() stream=%p channels=%u", stream, popcount(channels));
433
434 return channels;
435}
436
437static audio_format_t out_get_format(const struct audio_stream *stream)
438{
439 audio_format_t format = AUDIO_FORMAT_PCM_16_BIT;
440
441 ALOGVV("out_set_format() stream=%p format=0x%08x (%u bits/sample)",
442 stream, format, audio_bytes_per_sample(format) << 3);
443
444 return format;
445}
446
447static int out_set_format(struct audio_stream *stream, audio_format_t format)
448{
449 ALOGVV("out_set_format() stream=%p format=0x%08x (%u bits/sample)",
450 stream, format, audio_bytes_per_sample(format) << 3);
451
452 if (format != AUDIO_FORMAT_PCM_16_BIT) {
453 return -ENOSYS;
454 } else {
455 return 0;
456 }
457}
458
459/* must be called with locks held */
460static void do_out_standby(struct j6_stream_out *out)
461{
462 struct j6_audio_device *adev = out->dev;
463
464 if (!out->standby) {
465 ALOGI("do_out_standby() close card %u port %u", adev->card, adev->out_port);
466 pcm_close(out->pcm);
467 out->pcm = NULL;
468 out->standby = true;
469 }
470}
471
472static int out_standby(struct audio_stream *stream)
473{
474 struct j6_stream_out *out = (struct j6_stream_out *)(stream);
475 struct j6_audio_device *adev = out->dev;
476
477 ALOGV("out_standby() stream=%p", out);
478 pthread_mutex_lock(&adev->lock);
479 pthread_mutex_lock(&out->lock);
480 do_out_standby(out);
481 pthread_mutex_unlock(&out->lock);
482 pthread_mutex_unlock(&adev->lock);
483
484 return 0;
485}
486
487static int out_dump(const struct audio_stream *stream, int fd)
488{
489 return 0;
490}
491
492static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
493{
494 struct j6_stream_out *out = (struct j6_stream_out *)(stream);
495 struct j6_audio_device *adev = out->dev;
496 struct str_parms *parms;
497 char value[32];
498 int ret;
499 uint32_t val = 0;
500
501 ALOGV("out_set_parameters() stream=%p parameter='%s'", out, kvpairs);
502
503 parms = str_parms_create_str(kvpairs);
504
505 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
506 if (ret >= 0) {
507 val = atoi(value);
508 pthread_mutex_lock(&adev->lock);
509 pthread_mutex_lock(&out->lock);
510 if (val != 0) {
511 if ((adev->out_device & AUDIO_DEVICE_OUT_ALL) != val)
512 do_out_standby(out);
513
514 /* set the active output device */
515 adev->out_device = val;
516 select_output_device(adev);
517 }
518 pthread_mutex_unlock(&out->lock);
519 pthread_mutex_unlock(&adev->lock);
520 }
521
522 return 0;
523}
524
525static char* out_get_parameters(const struct audio_stream *stream, const char *keys)
526{
527 return strdup("");
528}
529
530static uint32_t out_get_latency(const struct audio_stream_out *stream)
531{
532 const struct j6_stream_out *out = (const struct j6_stream_out *)(stream);
533 uint32_t frames = PLAYBACK_BUFFER_SIZE;
534 uint32_t latency = (frames * 1000) / PLAYBACK_SAMPLE_RATE;
535
536 ALOGVV("out_get_latency() stream=%p latency=%u msecs", out, latency);
537
538 return latency;
539}
540
541static int out_set_volume(struct audio_stream_out *stream, float left,
542 float right)
543{
544 return -ENOSYS;
545}
546
547static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
548 size_t bytes)
549{
550 struct j6_stream_out *out = (struct j6_stream_out *)(stream);
551 struct j6_audio_device *adev = out->dev;
552 const size_t frame_size = audio_stream_frame_size(&stream->common);
553 const size_t frames = bytes / frame_size;
554 uint32_t rate = out->config.rate;
555 uint32_t write_usecs = frames * 1000000 / rate;
556
557 ALOGVV("out_write() stream=%p buffer=%p size=%u/%u time=%u usecs",
558 out, buffer, frames, rate, write_usecs);
559
560 pthread_mutex_lock(&adev->lock);
561 pthread_mutex_lock(&out->lock);
562
563 if (out->standby) {
564 select_output_device(adev);
565
566 ALOGI("out_write() open card %u port %u", adev->card, adev->out_port);
567 out->pcm = pcm_open(adev->card, adev->out_port, PCM_OUT | PCM_MMAP, &out->config);
568 if (!pcm_is_ready(out->pcm)) {
569 ALOGE("out_write() failed to open pcm out: %s", pcm_get_error(out->pcm));
570 pcm_close(out->pcm);
571 out->pcm = NULL;
572 usleep(write_usecs); /* limits the rate of error messages */
573 pthread_mutex_unlock(&out->lock);
574 pthread_mutex_unlock(&adev->lock);
575 return -ENODEV;
576 }
577
578 out->standby = false;
579 }
580
581 pthread_mutex_unlock(&adev->lock);
582
583 int ret = pcm_mmap_write(out->pcm, buffer, bytes);
584 if (ret) {
585 ALOGE("out_write() failed to write audio data %d", ret);
586 usleep(write_usecs); /* limits the rate of error messages */
587 }
588
589 pthread_mutex_unlock(&out->lock);
590
591 return bytes;
592}
593
594static int out_get_render_position(const struct audio_stream_out *stream,
595 uint32_t *dsp_frames)
596{
597 return -EINVAL;
598}
599
600static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
601{
602 return 0;
603}
604
605static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
606{
607 return 0;
608}
609
610static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
611 int64_t *timestamp)
612{
613 return -EINVAL;
614}
615
616/** audio_stream_in implementation **/
617static uint32_t in_get_sample_rate(const struct audio_stream *stream)
618{
619 const struct j6_stream_in *in = (const struct j6_stream_in *)(stream);
620
621 ALOGVV("in_get_sample_rate() stream=%p rate=%u", stream, in->requested_rate);
622
623 return in->requested_rate;
624}
625
626static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
627{
628 ALOGV("in_set_sample_rate() stream=%p rate=%u", stream, rate);
629
630 return 0;
631}
632
633static size_t in_get_buffer_size(const struct audio_stream *stream)
634{
635 const struct j6_stream_in *in = (const struct j6_stream_in *)(stream);
636
637 size_t bytes = get_input_buffer_size(in->requested_rate,
638 AUDIO_FORMAT_PCM_16_BIT,
639 in->requested_channels);
640
641 ALOGVV("in_get_buffer_size() stream=%p bytes=%u", in, bytes);
642
643 return bytes;
644}
645
646static audio_channel_mask_t in_get_channels(const struct audio_stream *stream)
647{
648 const struct j6_stream_in *in = (const struct j6_stream_in *)(stream);
649 audio_channel_mask_t channels = audio_channel_out_mask_from_count(in->requested_channels);
650
651 ALOGVV("in_get_channels() stream=%p channels=%u", in, in->requested_channels);
652
653 return channels;
654}
655
656static audio_format_t in_get_format(const struct audio_stream *stream)
657{
658 audio_format_t format = AUDIO_FORMAT_PCM_16_BIT;
659
660 ALOGVV("in_set_format() stream=%p format=0x%08x (%u bits/sample)",
661 stream, format, audio_bytes_per_sample(format) << 3);
662
663 return format;
664}
665
666static int in_set_format(struct audio_stream *stream, audio_format_t format)
667{
668 ALOGV("in_set_format() stream=%p format=0x%08x (%u bits/sample)",
669 stream, format, audio_bytes_per_sample(format) << 3);
670
671 if (format != AUDIO_FORMAT_PCM_16_BIT) {
672 return -ENOSYS;
673 } else {
674 return 0;
675 }
676}
677
678/* must be called with locks held */
679static void do_in_standby(struct j6_stream_in *in)
680{
681 struct j6_audio_device *adev = in->dev;
682
683 if (!in->standby) {
684 ALOGI("do_in_standby() close card %u port %u", adev->card, adev->out_port);
685 pcm_close(in->pcm);
686 in->pcm = NULL;
687 in->standby = true;
688 }
689}
690
691static int in_standby(struct audio_stream *stream)
692{
693 struct j6_stream_in *in = (struct j6_stream_in *)(stream);
694 struct j6_audio_device *adev = in->dev;
695
696 ALOGV("in_standby() stream=%p", in);
697 pthread_mutex_lock(&adev->lock);
698 pthread_mutex_lock(&in->lock);
699 do_in_standby(in);
700 pthread_mutex_unlock(&in->lock);
701 pthread_mutex_unlock(&adev->lock);
702
703 return 0;
704}
705
706static int in_dump(const struct audio_stream *stream, int fd)
707{
708 return 0;
709}
710
711static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
712{
713 struct j6_stream_in *in = (struct j6_stream_in *)(stream);
714 struct j6_audio_device *adev = in->dev;
715 struct str_parms *parms;
716 char value[32];
717 int ret;
718 uint32_t val = 0;
719
720 ALOGV("in_set_parameters() stream=%p parameter='%s'", stream, kvpairs);
721
722 parms = str_parms_create_str(kvpairs);
723
724 /* Nothing to do for AUDIO_PARAMETER_STREAM_INPUT_SOURCE, so it's ignored */
725
726 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
727 if (ret >= 0) {
728 val = atoi(value);
729 pthread_mutex_lock(&adev->lock);
730 pthread_mutex_lock(&in->lock);
731 if (val != 0) {
732 if ((adev->in_device & AUDIO_DEVICE_IN_ALL) != val)
733 do_in_standby(in);
734
735 /* set the active input device */
736 adev->in_device = val;
737 select_input_device(adev);
738 }
739 pthread_mutex_unlock(&in->lock);
740 pthread_mutex_unlock(&adev->lock);
741 }
742
743 return 0;
744}
745
746static char * in_get_parameters(const struct audio_stream *stream,
747 const char *keys)
748{
749 return strdup("");
750}
751
752static int in_set_gain(struct audio_stream_in *stream, float gain)
753{
754 return 0;
755}
756
757static int get_next_buffer(struct resampler_buffer_provider *buffer_provider,
758 struct resampler_buffer* buffer)
759{
760 struct j6_stream_in *in;
761 struct buffer_remix *remix;
762
763 if (buffer_provider == NULL || buffer == NULL)
764 return -EINVAL;
765
766 in = (struct j6_stream_in *)((char *)buffer_provider -
767 offsetof(struct j6_stream_in, buf_provider));
768
769 if (in->pcm == NULL) {
770 buffer->raw = NULL;
771 buffer->frame_count = 0;
772 in->read_status = -ENODEV;
773 return -ENODEV;
774 }
775
776 if (in->frames_in == 0) {
777 in->read_status = pcm_read(in->pcm,
778 (void*)in->buffer,
779 buffer->frame_count * in->hw_frame_size);
780 if (in->read_status != 0) {
781 ALOGE("get_next_buffer() pcm_read error %d", in->read_status);
782 buffer->raw = NULL;
783 buffer->frame_count = 0;
784 return in->read_status;
785 }
786 in->frames_in = buffer->frame_count;
787
788 remix = in->remix;
789 if (remix)
790 remix->remix_func(remix, in->buffer, in->frames_in);
791 }
792
793 buffer->frame_count = (buffer->frame_count > in->frames_in) ?
794 in->frames_in : buffer->frame_count;
795 buffer->i16 = in->buffer;
796
797 return in->read_status;
798}
799
800static void release_buffer(struct resampler_buffer_provider *buffer_provider,
801 struct resampler_buffer* buffer)
802{
803 struct j6_stream_in *in;
804
805 if (buffer_provider == NULL || buffer == NULL)
806 return;
807
808 in = (struct j6_stream_in *)((char *)buffer_provider -
809 offsetof(struct j6_stream_in, buf_provider));
810
811 in->frames_in -= buffer->frame_count;
812}
813
814/*
815 * read_frames() reads frames from kernel driver, down samples to capture rate
816 * if necessary and output the number of frames requested to the buffer specified
817 */
818static ssize_t read_frames(struct j6_stream_in *in, void *buffer, ssize_t frames)
819{
820 ssize_t frames_wr = 0;
821 size_t frame_size;
822
823 ALOGVV("read_frames() stream=%p frames=%u", in, frames);
824
825 if (in->remix)
826 frame_size = audio_stream_frame_size(&in->stream.common);
827 else
828 frame_size = in->hw_frame_size;
829
830 while (frames_wr < frames) {
831 size_t frames_rd = frames - frames_wr;
832
833 in->resampler->resample_from_provider(in->resampler,
834 (int16_t *)((char *)buffer + frames_wr * frame_size),
835 &frames_rd);
836 /* in->read_status is updated by getNextBuffer() also called by
837 * in->resampler->resample_from_provider() */
838 if (in->read_status != 0)
839 return in->read_status;
840
841 frames_wr += frames_rd;
842 }
843
844 return frames_wr;
845}
846
847static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
848 size_t bytes)
849{
850 struct j6_stream_in *in = (struct j6_stream_in *)(stream);
851 struct j6_audio_device *adev = in->dev;
852 const size_t frame_size = audio_stream_frame_size(&stream->common);
853 const size_t frames = bytes / frame_size;
854 uint32_t rate = in_get_sample_rate(&stream->common);
855 uint32_t read_usecs = frames * 1000000 / rate;
856 int ret;
857
858 ALOGVV("in_read() stream=%p buffer=%p size=%u/%u time=%u usecs",
859 stream, buffer, frames, rate, read_usecs);
860
861 pthread_mutex_lock(&adev->lock);
862 pthread_mutex_lock(&in->lock);
863
864 if (in->standby) {
865 select_input_device(adev);
866
867 ALOGI("in_read() open card %u port %u", adev->card, adev->in_port);
868 in->pcm = pcm_open(adev->card, adev->in_port, PCM_IN, &in->config);
869 if (!pcm_is_ready(in->pcm)) {
870 ALOGE("in_read() failed to open pcm in: %s", pcm_get_error(in->pcm));
871 pcm_close(in->pcm);
872 in->pcm = NULL;
873 usleep(read_usecs); /* limits the rate of error messages */
874 pthread_mutex_unlock(&in->lock);
875 pthread_mutex_unlock(&adev->lock);
876 return -ENODEV;
877 }
878
879 /* if no supported sample rate is available, use the resampler */
880 if (in->resampler) {
881 in->resampler->reset(in->resampler);
882 in->frames_in = 0;
883 }
884
885 in->standby = false;
886 }
887
888 pthread_mutex_unlock(&adev->lock);
889
890 if (in->resampler || in->remix)
891 ret = read_frames(in, buffer, frames);
892 else
893 ret = pcm_read(in->pcm, buffer, bytes);
894
895 if (ret < 0) {
896 ALOGE("in_read() failed to read audio data %d", ret);
897 usleep(read_usecs); /* limits the rate of error messages */
898 memset(buffer, 0, bytes);
899 }
900
901 pthread_mutex_unlock(&in->lock);
902
903 return bytes;
904}
905
906static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
907{
908 ALOGVV("in_get_input_frames_lost() stream=%p frames=%u", stream, 0);
909 return 0;
910}
911
912static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
913{
914 return 0;
915}
916
917static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
918{
919 return 0;
920}
921
922static int adev_open_output_stream(struct audio_hw_device *dev,
923 audio_io_handle_t handle,
924 audio_devices_t devices,
925 audio_output_flags_t flags,
926 struct audio_config *config,
927 struct audio_stream_out **stream_out)
928{
929 struct j6_audio_device *adev = (struct j6_audio_device *)dev;
930 struct j6_stream_out *out;
931
932 out = (struct j6_stream_out *)malloc(sizeof(struct j6_stream_out));
933 if (!out)
934 return -ENOMEM;
935
936 ALOGV("adev_open_output_stream() stream=%p rate=%u channels=%u "
937 "format=0x%08x flags=0x%08x",
938 out, config->sample_rate, popcount(config->channel_mask),
939 config->format, flags);
940
941 pthread_mutex_init(&out->lock, NULL);
942
943 out->stream.common.get_sample_rate = out_get_sample_rate;
944 out->stream.common.set_sample_rate = out_set_sample_rate;
945 out->stream.common.get_buffer_size = out_get_buffer_size;
946 out->stream.common.get_channels = out_get_channels;
947 out->stream.common.get_format = out_get_format;
948 out->stream.common.set_format = out_set_format;
949 out->stream.common.standby = out_standby;
950 out->stream.common.dump = out_dump;
951 out->stream.common.set_parameters = out_set_parameters;
952 out->stream.common.get_parameters = out_get_parameters;
953 out->stream.common.add_audio_effect = out_add_audio_effect;
954 out->stream.common.remove_audio_effect = out_remove_audio_effect;
955 out->stream.get_latency = out_get_latency;
956 out->stream.set_volume = out_set_volume;
957 out->stream.write = out_write;
958 out->stream.get_render_position = out_get_render_position;
959 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
960
961 out->dev = adev;
962 out->standby = true;
963 out->config = pcm_config_playback;
964 adev->out = out;
965
966 config->format = out_get_format(&out->stream.common);
967 config->channel_mask = out_get_channels(&out->stream.common);
968 config->sample_rate = out_get_sample_rate(&out->stream.common);
969
970 *stream_out = &out->stream;
971
972 return 0;
973}
974
975static void adev_close_output_stream(struct audio_hw_device *dev,
976 struct audio_stream_out *stream)
977{
978 struct j6_audio_device *adev = (struct j6_audio_device *)dev;
979 struct j6_stream_out *out = (struct j6_stream_out *)(stream);
980
981 ALOGV("adev_close_output_stream() stream=%p", out);
982
983 out_standby(&stream->common);
984 out->dev = NULL;
985 adev->out = NULL;
986
987 free(stream);
988}
989
990static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
991{
992 return -ENOSYS;
993}
994
995static char * adev_get_parameters(const struct audio_hw_device *dev,
996 const char *keys)
997{
998 return strdup("");;
999}
1000
1001static int adev_init_check(const struct audio_hw_device *dev)
1002{
1003 return 0;
1004}
1005
1006static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
1007{
1008 return -ENOSYS;
1009}
1010
1011static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
1012{
1013 return -ENOSYS;
1014}
1015
1016static int adev_get_master_volume(struct audio_hw_device *dev, float *volume)
1017{
1018 return -ENOSYS;
1019}
1020
1021static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
1022{
1023 return -ENOSYS;
1024}
1025
1026static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
1027{
1028 return -ENOSYS;
1029}
1030
1031static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
1032{
1033 ALOGV("adev_set_mode() mode=0x%08x", mode);
1034
1035 return 0;
1036}
1037
1038static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
1039{
1040 struct j6_audio_device *adev = (struct j6_audio_device *)dev;
1041
1042 ALOGV("adev_set_mic_mute() state=%s", state ? "mute" : "unmute");
1043
1044 pthread_mutex_lock(&adev->lock);
1045 set_route_by_array(adev->mixer, rs_capture, state);
1046 adev->mic_mute = state;
1047 pthread_mutex_unlock(&adev->lock);
1048
1049 return 0;
1050}
1051
1052static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
1053{
1054 const struct j6_audio_device *adev = (const struct j6_audio_device *)dev;
1055
1056 *state = adev->mic_mute;
1057 ALOGV("adev_get_mic_mute() state=%s", *state ? "mute" : "unmute");
1058
1059 return 0;
1060}
1061
1062static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
1063 const struct audio_config *config)
1064{
1065 size_t bytes = get_input_buffer_size(config->sample_rate,
1066 config->format,
1067 popcount(config->channel_mask));
1068
1069 ALOGVV("adev_in_get_buffer_size() bytes=%u", bytes);
1070
1071 return bytes;
1072}
1073
1074static int adev_open_input_stream(struct audio_hw_device *dev,
1075 audio_io_handle_t handle,
1076 audio_devices_t devices,
1077 struct audio_config *config,
1078 struct audio_stream_in **stream_in)
1079{
1080 struct j6_audio_device *adev = (struct j6_audio_device *)dev;
1081 struct j6_stream_in *in;
1082 int ret;
1083
1084 in = (struct j6_stream_in *)malloc(sizeof(struct j6_stream_in));
1085 if (!in)
1086 return -ENOMEM;
1087
1088 ALOGV("adev_open_input_stream() stream=%p rate=%u channels=%u format=0x%08x",
1089 in, config->sample_rate, popcount(config->channel_mask), config->format);
1090
1091 pthread_mutex_init(&in->lock, NULL);
1092
1093 in->stream.common.get_sample_rate = in_get_sample_rate;
1094 in->stream.common.set_sample_rate = in_set_sample_rate;
1095 in->stream.common.get_buffer_size = in_get_buffer_size;
1096 in->stream.common.get_channels = in_get_channels;
1097 in->stream.common.get_format = in_get_format;
1098 in->stream.common.set_format = in_set_format;
1099 in->stream.common.standby = in_standby;
1100 in->stream.common.dump = in_dump;
1101 in->stream.common.set_parameters = in_set_parameters;
1102 in->stream.common.get_parameters = in_get_parameters;
1103 in->stream.common.add_audio_effect = in_add_audio_effect;
1104 in->stream.common.remove_audio_effect = in_remove_audio_effect;
1105 in->stream.set_gain = in_set_gain;
1106 in->stream.read = in_read;
1107 in->stream.get_input_frames_lost = in_get_input_frames_lost;
1108
1109 in->dev = adev;
1110 in->standby = true;
1111 in->config = pcm_config_capture;
1112 in->requested_rate = config->sample_rate;
1113 in->requested_channels = popcount(config->channel_mask);
1114 in->hw_frame_size = in->config.channels * sizeof(int16_t);
1115 in->remix = NULL;
1116 adev->in = in;
1117
1118 /* in-place stereo-to-mono remix since capture stream is stereo */
1119 if (in->requested_channels == 1) {
1120 ALOGV("adev_open_input_stream() stereo-to-mono remix needed");
1121
1122 /*
1123 * buffer size is already enough to allow stereo-to-mono remix
1124 * and resample if needed
1125 */
1126 in->buffer = malloc(2 * in->config.period_size * in->hw_frame_size);
1127 if (!in->buffer) {
1128 ret = -ENOMEM;
1129 goto err1;
1130 }
1131
1132 ret = setup_stereo_to_mono_input_remix(in);
1133 if (ret) {
1134 ALOGE("adev_open_input_stream() failed to setup remix %d", ret);
1135 goto err2;
1136 }
1137 }
1138
1139 if (in->requested_rate != in->config.rate) {
1140 ALOGV("adev_open_input_stream() resample needed, req=%uHz got=%uHz",
1141 in->requested_rate, in->config.rate);
1142
1143 in->buf_provider.get_next_buffer = get_next_buffer;
1144 in->buf_provider.release_buffer = release_buffer;
1145 ret = create_resampler(in->config.rate,
1146 in->requested_rate,
1147 in->requested_channels,
1148 RESAMPLER_QUALITY_DEFAULT,
1149 &in->buf_provider,
1150 &in->resampler);
1151 if (ret) {
1152 ALOGE("adev_open_input_stream() failed to create resampler %d", ret);
1153 goto err3;
1154 }
1155 }
1156
1157 *stream_in = &in->stream;
1158
1159 return 0;
1160
1161 err3:
1162 free(in->remix);
1163 err2:
1164 free(in->buffer);
1165 err1:
1166 free(in);
1167 return ret;
1168}
1169
1170static void adev_close_input_stream(struct audio_hw_device *dev,
1171 struct audio_stream_in *stream)
1172{
1173 struct j6_audio_device *adev = (struct j6_audio_device *)dev;
1174 struct j6_stream_in *in = (struct j6_stream_in *)(stream);
1175
1176 ALOGV("adev_close_input_stream() stream=%p", stream);
1177
1178 in_standby(&stream->common);
1179
1180 if (in->resampler)
1181 release_resampler(in->resampler);
1182 in->resampler = NULL;
1183
1184 if (in->remix)
1185 free(in->remix);
1186 in->remix = NULL;
1187
1188 in->dev = NULL;
1189 adev->in = NULL;
1190
1191 free(in->buffer);
1192 free(in);
1193}
1194
1195static int adev_dump(const audio_hw_device_t *device, int fd)
1196{
1197 return 0;
1198}
1199
1200/*
1201 * should not be needed for API version 2.0 but AudioFlinger uses it to find
1202 * suitable hw device, so we keep it
1203 */
1204static uint32_t adev_get_supported_devices(const struct audio_hw_device *dev)
1205{
1206 uint32_t devices = SUPPORTED_IN_DEVICES | SUPPORTED_OUT_DEVICES;
1207
1208 ALOGV("adev_get_supported_devices() devices=0x%08x", devices);
1209
1210 return devices;
1211}
1212
1213static int adev_close(hw_device_t *device)
1214{
1215 struct j6_audio_device *adev = (struct j6_audio_device *)device;
1216
1217 ALOGI("adev_close()");
1218
1219 mixer_close(adev->mixer);
1220 adev->mixer = NULL;
1221 free(device);
1222
1223 return 0;
1224}
1225
1226static int adev_open(const hw_module_t* module, const char* name,
1227 hw_device_t** device)
1228{
1229 struct j6_audio_device *adev;
1230
1231 ALOGI("adev_open() %s", name);
1232
1233 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
1234 return -EINVAL;
1235
1236 adev = (struct j6_audio_device*)malloc(sizeof(struct j6_audio_device));
1237 if (!adev)
1238 return -ENOMEM;
1239
1240 pthread_mutex_init(&adev->lock, NULL);
1241
1242 adev->device.common.tag = HARDWARE_DEVICE_TAG;
1243 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
1244 adev->device.common.module = (struct hw_module_t *) module;
1245 adev->device.common.close = adev_close;
1246
1247 adev->device.get_supported_devices = adev_get_supported_devices;
1248 adev->device.init_check = adev_init_check;
1249 adev->device.set_voice_volume = adev_set_voice_volume;
1250 adev->device.set_master_volume = adev_set_master_volume;
1251 adev->device.get_master_volume = adev_get_master_volume;
1252 adev->device.set_master_mute = adev_set_master_mute;
1253 adev->device.get_master_mute = adev_get_master_mute;
1254 adev->device.set_mode = adev_set_mode;
1255 adev->device.set_mic_mute = adev_set_mic_mute;
1256 adev->device.get_mic_mute = adev_get_mic_mute;
1257 adev->device.set_parameters = adev_set_parameters;
1258 adev->device.get_parameters = adev_get_parameters;
1259 adev->device.get_input_buffer_size = adev_get_input_buffer_size;
1260 adev->device.open_output_stream = adev_open_output_stream;
1261 adev->device.close_output_stream = adev_close_output_stream;
1262 adev->device.open_input_stream = adev_open_input_stream;
1263 adev->device.close_input_stream = adev_close_input_stream;
1264 adev->device.dump = adev_dump;
1265
1266 adev->in_device = AUDIO_DEVICE_IN_BUILTIN_MIC;
1267 adev->out_device = AUDIO_DEVICE_OUT_SPEAKER;
1268 adev->card = find_supported_card();
1269 adev->in_port = 0;
1270 adev->out_port = 0;
1271 adev->mic_mute = false;
1272
1273 adev->mixer = mixer_open(adev->card);
1274 if (!adev->mixer) {
1275 free(adev);
1276 ALOGE("Unable to open the mixer, aborting.");
1277 return -EINVAL;
1278 }
1279
1280 *device = &adev->device.common;
1281
1282 set_route_by_array(adev->mixer, rs_defaults, 1);
1283
1284 return 0;
1285}
1286
1287static struct hw_module_methods_t hal_module_methods = {
1288 .open = adev_open,
1289};
1290
1291struct audio_module HAL_MODULE_INFO_SYM = {
1292 .common = {
1293 .tag = HARDWARE_MODULE_TAG,
1294 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
1295 .hal_api_version = HARDWARE_HAL_API_VERSION,
1296 .id = AUDIO_HARDWARE_MODULE_ID,
1297 .name = "Jacinto6 Audio HAL",
1298 .author = "Texas Instruments Inc.",
1299 .methods = &hal_module_methods,
1300 },
1301};
diff --git a/audio/legacy/audio_policy.conf b/audio/legacy/audio_policy.conf
new file mode 100644
index 0000000..a806163
--- /dev/null
+++ b/audio/legacy/audio_policy.conf
@@ -0,0 +1,94 @@
1# Global configuration section: lists input and output devices always present on the device
2# as well as the output device selected by default.
3# Devices are designated by a string that corresponds to the enum in audio.h
4
5global_configuration {
6 attached_output_devices AUDIO_DEVICE_OUT_SPEAKER
7 default_output_device AUDIO_DEVICE_OUT_SPEAKER
8 attached_input_devices AUDIO_DEVICE_IN_BUILTIN_MIC
9}
10
11# audio hardware module section: contains descriptors for all audio hw modules present on the
12# device. Each hw module node is named after the corresponding hw module library base name.
13# For instance, "primary" corresponds to audio.primary.<device>.so.
14# The "primary" module is mandatory and must include at least one output with
15# AUDIO_OUTPUT_FLAG_PRIMARY flag.
16# Each module descriptor contains one or more output profile descriptors and zero or more
17# input profile descriptors. Each profile lists all the parameters supported by a given output
18# or input stream category.
19# The "channel_masks", "formats", "devices" and "flags" are specified using strings corresponding
20# to enums in audio.h and audio_policy.h. They are concatenated by use of "|" without space or "\n".
21
22audio_hw_modules {
23 primary {
24 outputs {
25 primary {
26 sampling_rates 44100
27 channel_masks AUDIO_CHANNEL_OUT_STEREO
28 formats AUDIO_FORMAT_PCM_16_BIT
29 devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE
30 flags AUDIO_OUTPUT_FLAG_PRIMARY
31 }
32 }
33 inputs {
34 primary {
35 sampling_rates 8000|11025|16000|22050|32000|44100|48000
36 channel_masks AUDIO_CHANNEL_IN_MONO|AUDIO_CHANNEL_IN_STEREO
37 formats AUDIO_FORMAT_PCM_16_BIT
38 devices AUDIO_DEVICE_IN_BUILTIN_MIC
39 }
40 }
41 }
42 hdmi {
43 outputs {
44 stereo {
45 sampling_rates 44100|48000
46 channel_masks AUDIO_CHANNEL_OUT_STEREO
47 formats AUDIO_FORMAT_PCM_16_BIT
48 devices AUDIO_DEVICE_OUT_AUX_DIGITAL
49 }
50 multichannel {
51 sampling_rates 44100|48000
52 channel_masks dynamic
53 formats AUDIO_FORMAT_PCM_16_BIT
54 devices AUDIO_DEVICE_OUT_AUX_DIGITAL
55 flags AUDIO_OUTPUT_FLAG_DIRECT
56 }
57 }
58 }
59 a2dp {
60 outputs {
61 a2dp {
62 sampling_rates 44100
63 channel_masks AUDIO_CHANNEL_OUT_STEREO
64 formats AUDIO_FORMAT_PCM_16_BIT
65 devices AUDIO_DEVICE_OUT_ALL_A2DP
66 }
67 }
68 }
69 r_submix {
70 outputs {
71 r_submix {
72 sampling_rates 44100|48000
73 channel_masks AUDIO_CHANNEL_OUT_STEREO
74 formats AUDIO_FORMAT_PCM_16_BIT
75 devices AUDIO_DEVICE_OUT_REMOTE_SUBMIX
76 }
77 multichannel {
78 sampling_rates 44100|48000
79 channel_masks AUDIO_CHANNEL_OUT_5POINT1
80 formats AUDIO_FORMAT_PCM_16_BIT
81 devices AUDIO_DEVICE_OUT_REMOTE_SUBMIX
82 flags AUDIO_OUTPUT_FLAG_DIRECT
83 }
84 }
85 inputs {
86 r_submix {
87 sampling_rates 44100|48000
88 channel_masks AUDIO_CHANNEL_IN_MONO|AUDIO_CHANNEL_IN_STEREO|AUDIO_CHANNEL_IN_5POINT1EMUL
89 formats AUDIO_FORMAT_PCM_16_BIT
90 devices AUDIO_DEVICE_IN_REMOTE_SUBMIX
91 }
92 }
93 }
94}