summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMisael Lopez Cruz2017-10-19 01:52:02 -0500
committerMisael Lopez Cruz2017-10-25 11:19:23 -0500
commit999477e26912e4909900f418bf61f98a24256420 (patch)
treeb56b2e3658e0ac9e72e2b7ffff6575cc6a231d1b
parent772c3de8190401977c0abcc68738d8655820e9ef (diff)
downloaddevice-ti-jacinto6evm-999477e26912e4909900f418bf61f98a24256420.tar.gz
device-ti-jacinto6evm-999477e26912e4909900f418bf61f98a24256420.tar.xz
device-ti-jacinto6evm-999477e26912e4909900f418bf61f98a24256420.zip
audio: Combine the JAMR3 HAL into the primary HAL
JAMR3 line-in audio support was provided through a separate audio HAL which caused significant code duplication. Line-in audio support is now combined into the primary HAL. Change-Id: Ibd1d481954f1ebb71bb543c5a9d8dbd3ba61b002 Signed-off-by: Misael Lopez Cruz <misael.lopez@ti.com>
-rw-r--r--audio/jamr3/Android.mk43
-rw-r--r--audio/jamr3/jamr3_audio_hw.c970
-rw-r--r--audio/primary/audio_hw.c38
-rw-r--r--audio/primary/audio_policy_configuration.xml22
-rw-r--r--audio/primary/jamr3_mixer_paths.xml (renamed from audio/jamr3/jamr3_mixer_paths.xml)0
-rw-r--r--device.mk5
6 files changed, 48 insertions, 1030 deletions
diff --git a/audio/jamr3/Android.mk b/audio/jamr3/Android.mk
deleted file mode 100644
index 277745c..0000000
--- a/audio/jamr3/Android.mk
+++ /dev/null
@@ -1,43 +0,0 @@
1# Copyright (C) 2015 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 ($(TARGET_BOARD_PLATFORM), $(filter $(TARGET_BOARD_PLATFORM), jacinto6))
18
19include $(CLEAR_VARS)
20
21LOCAL_MODULE := audio.jamr3.$(TARGET_BOARD_PLATFORM)
22
23LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_SHARED_LIBRARIES)/hw
24LOCAL_SRC_FILES := jamr3_audio_hw.c
25
26LOCAL_C_INCLUDES += \
27 external/tinyalsa/include \
28 system/media/audio_route/include \
29 system/media/audio_utils/include \
30 system/media/audio_effects/include
31
32LOCAL_SHARED_LIBRARIES := \
33 liblog \
34 libcutils \
35 libtinyalsa \
36 libaudioutils \
37 libaudioroute
38
39LOCAL_MODULE_TAGS := optional
40
41include $(BUILD_SHARED_LIBRARY)
42
43endif
diff --git a/audio/jamr3/jamr3_audio_hw.c b/audio/jamr3/jamr3_audio_hw.c
deleted file mode 100644
index c7b5258..0000000
--- a/audio/jamr3/jamr3_audio_hw.c
+++ /dev/null
@@ -1,970 +0,0 @@
1/*
2 * Copyright (C) 2015 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 "jamr3_audio_hw"
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 <audio_route/audio_route.h>
37#include <system/audio.h>
38#include <hardware/hardware.h>
39#include <hardware/audio.h>
40#include <hardware/audio_effect.h>
41
42#include <tinyalsa/asoundlib.h>
43
44#define UNUSED(x) (void)(x)
45
46/* yet another definition of ARRAY_SIZE macro) */
47#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
48
49/*
50 * additional space in resampler buffer allowing for extra samples to be returned
51 * by speex resampler when sample rates ratio is not an integer
52 */
53#define RESAMPLER_HEADROOM_FRAMES 10
54
55/* buffer_remix: functor for doing in-place buffer manipulations.
56 *
57 * NB. When remix_func is called, the memory at `buf` must be at least
58 * as large as frames * sample_size * MAX(in_chans, out_chans).
59 */
60struct buffer_remix {
61 void (*remix_func)(struct buffer_remix *data, void *buf, size_t frames);
62 size_t sample_size; /* size of one audio sample, in bytes */
63 size_t in_chans; /* number of input channels */
64 size_t out_chans; /* number of output channels */
65};
66
67struct j6_audio_device {
68 struct audio_hw_device device;
69 struct j6_stream_in *in;
70 struct audio_route *route;
71 audio_devices_t in_device;
72 pthread_mutex_t lock;
73 unsigned int card;
74 unsigned int in_port;
75 bool mic_mute;
76};
77
78struct j6_stream_in {
79 struct audio_stream_in stream;
80 struct j6_audio_device *dev;
81 struct pcm_config config;
82 struct pcm *pcm;
83 struct buffer_remix *remix; /* adapt hw chan count to client */
84 struct resampler_itfe *resampler;
85 struct resampler_buffer_provider buf_provider;
86 int16_t *buffer;
87 size_t frames_in;
88 size_t hw_frame_size;
89 unsigned int requested_rate;
90 unsigned int requested_channels;
91 int read_status;
92 pthread_mutex_t lock;
93 bool standby;
94 int read; /* total frames read, cleared when entering standby */
95};
96
97static const char *supported_cards[] = {
98 "DRA7xx-JAMR3",
99};
100
101#define MAX_CARD_COUNT 10
102
103#define SUPPORTED_IN_DEVICES AUDIO_DEVICE_IN_LINE
104
105#define CAPTURE_SAMPLE_RATE 44100
106#define CAPTURE_PERIOD_SIZE 256
107#define CAPTURE_PERIOD_COUNT 4
108#define CAPTURE_BUFFER_SIZE (CAPTURE_PERIOD_SIZE * CAPTURE_PERIOD_COUNT)
109
110#define MIXER_XML_PATH "/vendor/etc/jamr3_mixer_paths.xml"
111
112struct pcm_config pcm_config_capture = {
113 .channels = 2,
114 .rate = CAPTURE_SAMPLE_RATE,
115 .format = PCM_FORMAT_S16_LE,
116 .period_size = CAPTURE_PERIOD_SIZE,
117 .period_count = CAPTURE_PERIOD_COUNT,
118 .start_threshold = 1,
119 .stop_threshold = CAPTURE_BUFFER_SIZE,
120};
121
122static int find_card_index(const char *supported_cards[], int num_supported)
123{
124 struct mixer *mixer;
125 const char *name;
126 int card = 0;
127 int found = 0;
128 int i;
129
130 do {
131 /* returns an error after last valid card */
132 mixer = mixer_open(card);
133 if (!mixer)
134 break;
135
136 name = mixer_get_name(mixer);
137
138 for (i = 0; i < num_supported; ++i) {
139 if (supported_cards[i] && !strcmp(name, supported_cards[i])) {
140 ALOGV("Supported card '%s' found at %d", name, card);
141 found = 1;
142 break;
143 }
144 }
145
146 mixer_close(mixer);
147 } while (!found && (card++ < MAX_CARD_COUNT));
148
149 /* Use default card number if not found */
150 if (!found)
151 card = 2;
152
153 return card;
154}
155
156/* must be called with device lock held */
157static void select_input_device(struct j6_audio_device *adev)
158{
159 if (adev->in_device & ~SUPPORTED_IN_DEVICES)
160 ALOGW("select_input_device() device not supported, will use default device");
161}
162
163static size_t get_input_buffer_size(uint32_t sample_rate, int format, int channel_count)
164{
165 size_t size;
166
167 /*
168 * take resampling into account and return the closest majoring
169 * multiple of 16 frames, as audioflinger expects audio buffers to
170 * be a multiple of 16 frames
171 */
172 size = (pcm_config_capture.period_size * sample_rate) / pcm_config_capture.rate;
173 size = ((size + 15) / 16) * 16;
174
175 return size * channel_count * audio_bytes_per_sample(format);
176}
177
178/*
179 * Implementation of buffer_remix::remix_func that removes
180 * channels in place without doing any other processing. The
181 * extra channels are truncated.
182 */
183static void remove_channels_from_buf(struct buffer_remix *data, void *buf, size_t frames)
184{
185 size_t samp_size, in_frame, out_frame;
186 size_t N, c;
187 char *s, *d;
188
189 ALOGVV("remove_channels_from_buf() remix=%p buf=%p frames=%u",
190 data, buf, frames);
191
192 if (frames == 0)
193 return;
194
195 samp_size = data->sample_size;
196 in_frame = data->in_chans * samp_size;
197 out_frame = data->out_chans * samp_size;
198
199 if (out_frame >= in_frame) {
200 ALOGE("BUG: remove_channels_from_buf() can not add channels to a buffer.\n");
201 return;
202 }
203
204 N = frames - 1;
205 d = (char*)buf + out_frame;
206 s = (char*)buf + in_frame;
207
208 /* take the first several channels and truncate the rest */
209 while (N--) {
210 for (c = 0; c < out_frame; ++c)
211 d[c] = s[c];
212 d += out_frame;
213 s += in_frame;
214 }
215}
216
217static int setup_stereo_to_mono_input_remix(struct j6_stream_in *in)
218{
219 ALOGV("setup_stereo_to_mono_input_remix() stream=%p", in);
220
221 struct buffer_remix *br = (struct buffer_remix *)calloc(1, sizeof(struct buffer_remix));
222 if (!br)
223 return -ENOMEM;
224
225 br->remix_func = remove_channels_from_buf;
226 br->sample_size = sizeof(int16_t);
227 br->in_chans = 2;
228 br->out_chans = 1;
229 in->remix = br;
230
231 return 0;
232}
233
234/*
235 * Implementation of buffer_remix::remix_func that duplicates the first
236 * channel into the rest of channels in the frame without doing any other
237 * processing
238 */
239static void duplicate_channels_from_mono(struct buffer_remix *data, void *buf, size_t frames)
240{
241 int samp_size, in_frame, out_frame;
242 int N, c;
243 char *s, *d;
244
245 ALOGVV("duplicate_channels_from_mono() remix=%p buf=%p frames=%u",
246 data, buf, frames);
247
248 if (frames == 0)
249 return;
250
251 samp_size = data->sample_size;
252 in_frame = data->in_chans * samp_size;
253 out_frame = data->out_chans * samp_size;
254
255 if (in_frame >= out_frame) {
256 ALOGE("BUG: duplicate_channels_from_mono() can not drop channels\n");
257 return;
258 }
259
260 N = frames - 1;
261 d = (char*)buf + N * out_frame;
262 s = (char*)buf + N * in_frame;
263
264 /* duplicate first channel into the rest of channels in the frame */
265 while (N-- >= 0) {
266 for (c = 0; c < out_frame; ++c)
267 d[c] = s[c % in_frame];
268 d -= out_frame;
269 s -= in_frame;
270 }
271}
272
273/** audio_stream_in implementation **/
274static uint32_t in_get_sample_rate(const struct audio_stream *stream)
275{
276 const struct j6_stream_in *in = (const struct j6_stream_in *)(stream);
277
278 ALOGVV("in_get_sample_rate() stream=%p rate=%u", stream, in->requested_rate);
279
280 return in->requested_rate;
281}
282
283static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
284{
285 ALOGV("in_set_sample_rate() stream=%p rate=%u", stream, rate);
286
287 return 0;
288}
289
290static size_t in_get_buffer_size(const struct audio_stream *stream)
291{
292 const struct j6_stream_in *in = (const struct j6_stream_in *)(stream);
293
294 size_t bytes = get_input_buffer_size(in->requested_rate,
295 AUDIO_FORMAT_PCM_16_BIT,
296 in->requested_channels);
297
298 ALOGVV("in_get_buffer_size() stream=%p bytes=%u", in, bytes);
299
300 return bytes;
301}
302
303static audio_channel_mask_t in_get_channels(const struct audio_stream *stream)
304{
305 const struct j6_stream_in *in = (const struct j6_stream_in *)(stream);
306 audio_channel_mask_t channels = audio_channel_in_mask_from_count(in->requested_channels);
307
308 ALOGVV("in_get_channels() stream=%p channels=%u", in, in->requested_channels);
309
310 return channels;
311}
312
313static audio_format_t in_get_format(const struct audio_stream *stream)
314{
315 audio_format_t format = AUDIO_FORMAT_PCM_16_BIT;
316
317 UNUSED(stream);
318 ALOGVV("in_set_format() stream=%p format=0x%08x (%u bits/sample)",
319 stream, format, audio_bytes_per_sample(format) << 3);
320
321 return format;
322}
323
324static int in_set_format(struct audio_stream *stream, audio_format_t format)
325{
326 UNUSED(stream);
327 ALOGV("in_set_format() stream=%p format=0x%08x (%u bits/sample)",
328 stream, format, audio_bytes_per_sample(format) << 3);
329
330 if (format != AUDIO_FORMAT_PCM_16_BIT) {
331 return -ENOSYS;
332 } else {
333 return 0;
334 }
335}
336
337/* must be called with locks held */
338static void do_in_standby(struct j6_stream_in *in)
339{
340 struct j6_audio_device *adev = in->dev;
341
342 if (!in->standby) {
343 ALOGI("do_in_standby() close card %u port %u", adev->card, adev->in_port);
344 pcm_close(in->pcm);
345 in->pcm = NULL;
346 in->standby = true;
347 }
348}
349
350static int in_standby(struct audio_stream *stream)
351{
352 struct j6_stream_in *in = (struct j6_stream_in *)(stream);
353 struct j6_audio_device *adev = in->dev;
354
355 ALOGV("in_standby() stream=%p", in);
356 pthread_mutex_lock(&adev->lock);
357 pthread_mutex_lock(&in->lock);
358 do_in_standby(in);
359 pthread_mutex_unlock(&in->lock);
360 pthread_mutex_unlock(&adev->lock);
361
362 return 0;
363}
364
365static int in_dump(const struct audio_stream *stream, int fd)
366{
367 UNUSED(stream);
368 UNUSED(fd);
369
370 return 0;
371}
372
373static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
374{
375 struct j6_stream_in *in = (struct j6_stream_in *)(stream);
376 struct j6_audio_device *adev = in->dev;
377 struct str_parms *parms;
378 char value[32];
379 int ret;
380 uint32_t val = 0;
381
382 ALOGV("in_set_parameters() stream=%p parameter='%s'", stream, kvpairs);
383
384 parms = str_parms_create_str(kvpairs);
385
386 /* Nothing to do for AUDIO_PARAMETER_STREAM_INPUT_SOURCE, so it's ignored */
387
388 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
389 if (ret >= 0) {
390 val = atoi(value);
391 pthread_mutex_lock(&adev->lock);
392 pthread_mutex_lock(&in->lock);
393 if (val != 0) {
394 if ((adev->in_device & AUDIO_DEVICE_IN_ALL) != val)
395 do_in_standby(in);
396
397 /* set the active input device */
398 adev->in_device = val;
399 select_input_device(adev);
400 }
401 pthread_mutex_unlock(&in->lock);
402 pthread_mutex_unlock(&adev->lock);
403 }
404
405 return 0;
406}
407
408static char * in_get_parameters(const struct audio_stream *stream,
409 const char *keys)
410{
411 UNUSED(stream);
412 UNUSED(keys);
413
414 return strdup("");
415}
416
417static int in_set_gain(struct audio_stream_in *stream, float gain)
418{
419 UNUSED(stream);
420 UNUSED(gain);
421
422 return 0;
423}
424
425static int get_next_buffer(struct resampler_buffer_provider *buffer_provider,
426 struct resampler_buffer* buffer)
427{
428 struct j6_stream_in *in;
429 struct buffer_remix *remix;
430
431 if (buffer_provider == NULL || buffer == NULL)
432 return -EINVAL;
433
434 in = (struct j6_stream_in *)((char *)buffer_provider -
435 offsetof(struct j6_stream_in, buf_provider));
436
437 if (in->pcm == NULL) {
438 buffer->raw = NULL;
439 buffer->frame_count = 0;
440 in->read_status = -ENODEV;
441 return -ENODEV;
442 }
443
444 if (in->frames_in == 0) {
445 in->read_status = pcm_read(in->pcm,
446 (void*)in->buffer,
447 buffer->frame_count * in->hw_frame_size);
448 if (in->read_status != 0) {
449 ALOGE("get_next_buffer() pcm_read error %d", in->read_status);
450 buffer->raw = NULL;
451 buffer->frame_count = 0;
452 return in->read_status;
453 }
454 in->frames_in = buffer->frame_count;
455
456 remix = in->remix;
457 if (remix)
458 remix->remix_func(remix, in->buffer, in->frames_in);
459 }
460
461 buffer->frame_count = (buffer->frame_count > in->frames_in) ?
462 in->frames_in : buffer->frame_count;
463 buffer->i16 = in->buffer;
464
465 return in->read_status;
466}
467
468static void release_buffer(struct resampler_buffer_provider *buffer_provider,
469 struct resampler_buffer* buffer)
470{
471 struct j6_stream_in *in;
472
473 if (buffer_provider == NULL || buffer == NULL)
474 return;
475
476 in = (struct j6_stream_in *)((char *)buffer_provider -
477 offsetof(struct j6_stream_in, buf_provider));
478
479 in->frames_in -= buffer->frame_count;
480}
481
482/*
483 * read_frames() reads frames from kernel driver, down samples to capture rate
484 * if necessary and output the number of frames requested to the buffer specified
485 */
486static ssize_t read_frames(struct j6_stream_in *in, void *buffer, ssize_t frames)
487{
488 const struct audio_stream_in *s = (const struct audio_stream_in *)in;
489 ssize_t frames_wr = 0;
490 size_t frame_size;
491
492 ALOGVV("read_frames() stream=%p frames=%u", in, frames);
493
494 if (in->remix)
495 frame_size = audio_stream_in_frame_size(s);
496 else
497 frame_size = in->hw_frame_size;
498
499 while (frames_wr < frames) {
500 size_t frames_rd = frames - frames_wr;
501
502 in->resampler->resample_from_provider(in->resampler,
503 (int16_t *)((char *)buffer + frames_wr * frame_size),
504 &frames_rd);
505 /* in->read_status is updated by getNextBuffer() also called by
506 * in->resampler->resample_from_provider() */
507 if (in->read_status != 0)
508 return in->read_status;
509
510 frames_wr += frames_rd;
511 }
512
513 return frames_wr;
514}
515
516static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
517 size_t bytes)
518{
519 const struct audio_stream_in *s = (const struct audio_stream_in *)stream;
520 struct j6_stream_in *in = (struct j6_stream_in *)(stream);
521 struct j6_audio_device *adev = in->dev;
522 const size_t frame_size = audio_stream_in_frame_size(stream);
523 const size_t frames = bytes / frame_size;
524 uint32_t rate = in_get_sample_rate(&stream->common);
525 uint32_t read_usecs = frames * 1000000 / rate;
526 int ret;
527
528 ALOGVV("in_read() stream=%p buffer=%p size=%u/%u time=%u usecs",
529 stream, buffer, frames, rate, read_usecs);
530
531 pthread_mutex_lock(&adev->lock);
532 pthread_mutex_lock(&in->lock);
533
534 if (in->standby) {
535 select_input_device(adev);
536
537 ALOGI("in_read() open card %u port %u", adev->card, adev->in_port);
538 in->pcm = pcm_open(adev->card, adev->in_port,
539 PCM_IN | PCM_MONOTONIC,
540 &in->config);
541 if (!pcm_is_ready(in->pcm)) {
542 ALOGE("in_read() failed to open pcm in: %s", pcm_get_error(in->pcm));
543 pcm_close(in->pcm);
544 in->pcm = NULL;
545 usleep(read_usecs); /* limits the rate of error messages */
546 pthread_mutex_unlock(&in->lock);
547 pthread_mutex_unlock(&adev->lock);
548 return -ENODEV;
549 }
550
551 /* if no supported sample rate is available, use the resampler */
552 if (in->resampler) {
553 in->resampler->reset(in->resampler);
554 in->frames_in = 0;
555 }
556
557 in->standby = false;
558 in->read = 0;
559 }
560
561 pthread_mutex_unlock(&adev->lock);
562
563 if (in->resampler || in->remix)
564 ret = read_frames(in, buffer, frames);
565 else
566 ret = pcm_read(in->pcm, buffer, bytes);
567
568 if (ret < 0) {
569 ALOGE("in_read() failed to read audio data %d", ret);
570 usleep(read_usecs); /* limits the rate of error messages */
571 memset(buffer, 0, bytes);
572 } else {
573 in->read += frames;
574 if (adev->mic_mute)
575 memset(buffer, 0, bytes);
576 }
577
578 pthread_mutex_unlock(&in->lock);
579
580 return bytes;
581}
582
583static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
584{
585 UNUSED(stream);
586 ALOGVV("in_get_input_frames_lost() stream=%p frames=%u", stream, 0);
587
588 return 0;
589}
590
591static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
592{
593 UNUSED(stream);
594 UNUSED(effect);
595
596 return 0;
597}
598
599static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
600{
601 UNUSED(stream);
602 UNUSED(effect);
603
604 return 0;
605}
606
607static int adev_open_output_stream(struct audio_hw_device *dev,
608 audio_io_handle_t handle,
609 audio_devices_t devices,
610 audio_output_flags_t flags,
611 struct audio_config *config,
612 struct audio_stream_out **stream_out,
613 const char *address)
614{
615 UNUSED(dev);
616 UNUSED(handle);
617 UNUSED(devices);
618 UNUSED(flags);
619 UNUSED(config);
620 UNUSED(stream_out);
621 UNUSED(address);
622
623 ALOGE("adev_open_output_stream() output stream is not supported");
624
625 return -ENOSYS;
626}
627
628static void adev_close_output_stream(struct audio_hw_device *dev,
629 struct audio_stream_out *stream)
630{
631 UNUSED(dev);
632 UNUSED(stream);
633
634 ALOGE("adev_close_output_stream() output stream is not supported");
635}
636
637static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
638{
639 UNUSED(dev);
640 UNUSED(kvpairs);
641
642 return -ENOSYS;
643}
644
645static char * adev_get_parameters(const struct audio_hw_device *dev,
646 const char *keys)
647{
648 UNUSED(dev);
649 UNUSED(keys);
650
651 return strdup("");;
652}
653
654static int adev_init_check(const struct audio_hw_device *dev)
655{
656 UNUSED(dev);
657
658 return 0;
659}
660
661static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
662{
663 UNUSED(dev);
664 UNUSED(volume);
665
666 return -ENOSYS;
667}
668
669static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
670{
671 UNUSED(dev);
672 UNUSED(volume);
673
674 return -ENOSYS;
675}
676
677static int adev_get_master_volume(struct audio_hw_device *dev, float *volume)
678{
679 UNUSED(dev);
680 UNUSED(volume);
681
682 return -ENOSYS;
683}
684
685static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
686{
687 UNUSED(dev);
688 UNUSED(muted);
689
690 return -ENOSYS;
691}
692
693static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
694{
695 UNUSED(dev);
696 UNUSED(muted);
697
698 return -ENOSYS;
699}
700
701static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
702{
703 UNUSED(dev);
704 UNUSED(mode);
705
706 ALOGV("adev_set_mode() mode=0x%08x", mode);
707
708 return 0;
709}
710
711static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
712{
713 struct j6_audio_device *adev = (struct j6_audio_device *)dev;
714
715 ALOGV("adev_set_mic_mute() state=%s", state ? "mute" : "unmute");
716 adev->mic_mute = state;
717
718 return 0;
719}
720
721static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
722{
723 const struct j6_audio_device *adev = (const struct j6_audio_device *)dev;
724
725 *state = adev->mic_mute;
726 ALOGV("adev_get_mic_mute() state=%s", *state ? "mute" : "unmute");
727
728 return 0;
729}
730
731static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
732 const struct audio_config *config)
733{
734 UNUSED(dev);
735
736 size_t bytes = get_input_buffer_size(config->sample_rate,
737 config->format,
738 popcount(config->channel_mask));
739
740 ALOGVV("adev_in_get_buffer_size() bytes=%u", bytes);
741
742 return bytes;
743}
744
745static int adev_open_input_stream(struct audio_hw_device *dev,
746 audio_io_handle_t handle,
747 audio_devices_t devices,
748 struct audio_config *config,
749 struct audio_stream_in **stream_in,
750 audio_input_flags_t flags,
751 const char *address,
752 audio_source_t source)
753{
754 struct j6_audio_device *adev = (struct j6_audio_device *)dev;
755 struct j6_stream_in *in;
756 int ret;
757
758 UNUSED(handle);
759 UNUSED(devices);
760 UNUSED(flags);
761 UNUSED(address);
762 UNUSED(source);
763
764 in = (struct j6_stream_in *)calloc(1, sizeof(struct j6_stream_in));
765 if (!in)
766 return -ENOMEM;
767
768 ALOGI("adev_open_input_stream() stream=%p rate=%u channels=%u format=0x%08x",
769 in, config->sample_rate, popcount(config->channel_mask), config->format);
770
771 pthread_mutex_init(&in->lock, NULL);
772
773 in->stream.common.get_sample_rate = in_get_sample_rate;
774 in->stream.common.set_sample_rate = in_set_sample_rate;
775 in->stream.common.get_buffer_size = in_get_buffer_size;
776 in->stream.common.get_channels = in_get_channels;
777 in->stream.common.get_format = in_get_format;
778 in->stream.common.set_format = in_set_format;
779 in->stream.common.standby = in_standby;
780 in->stream.common.dump = in_dump;
781 in->stream.common.set_parameters = in_set_parameters;
782 in->stream.common.get_parameters = in_get_parameters;
783 in->stream.common.add_audio_effect = in_add_audio_effect;
784 in->stream.common.remove_audio_effect = in_remove_audio_effect;
785 in->stream.set_gain = in_set_gain;
786 in->stream.read = in_read;
787 in->stream.get_input_frames_lost = in_get_input_frames_lost;
788
789 in->dev = adev;
790 in->standby = true;
791 in->config = pcm_config_capture;
792 in->requested_rate = config->sample_rate;
793 in->requested_channels = popcount(config->channel_mask);
794 in->hw_frame_size = in->config.channels * sizeof(int16_t);
795 in->remix = NULL;
796 in->resampler = NULL;
797 in->buffer = NULL;
798 adev->in = in;
799
800 /* in-place stereo-to-mono remix since capture stream is stereo */
801 if (in->requested_channels == 1) {
802 ALOGV("adev_open_input_stream() stereo-to-mono remix needed");
803
804 /*
805 * buffer size is already enough to allow stereo-to-mono remix
806 * and resample if needed
807 */
808 in->buffer = malloc(2 * in->config.period_size * in->hw_frame_size);
809 if (!in->buffer) {
810 ret = -ENOMEM;
811 goto err1;
812 }
813
814 ret = setup_stereo_to_mono_input_remix(in);
815 if (ret) {
816 ALOGE("adev_open_input_stream() failed to setup remix %d", ret);
817 goto err2;
818 }
819 }
820
821 if (in->requested_rate != in->config.rate) {
822 ALOGV("adev_open_input_stream() resample needed, req=%uHz got=%uHz",
823 in->requested_rate, in->config.rate);
824
825 in->buf_provider.get_next_buffer = get_next_buffer;
826 in->buf_provider.release_buffer = release_buffer;
827 ret = create_resampler(in->config.rate,
828 in->requested_rate,
829 in->requested_channels,
830 RESAMPLER_QUALITY_DEFAULT,
831 &in->buf_provider,
832 &in->resampler);
833 if (ret) {
834 ALOGE("adev_open_input_stream() failed to create resampler %d", ret);
835 goto err3;
836 }
837 }
838
839 *stream_in = &in->stream;
840
841 return 0;
842
843 err3:
844 free(in->remix);
845 err2:
846 free(in->buffer);
847 err1:
848 free(in);
849 return ret;
850}
851
852static void adev_close_input_stream(struct audio_hw_device *dev,
853 struct audio_stream_in *stream)
854{
855 struct j6_audio_device *adev = (struct j6_audio_device *)dev;
856 struct j6_stream_in *in = (struct j6_stream_in *)(stream);
857
858 ALOGV("adev_close_input_stream() stream=%p", stream);
859
860 in_standby(&stream->common);
861
862 if (in->resampler)
863 release_resampler(in->resampler);
864 in->resampler = NULL;
865
866 if (in->remix)
867 free(in->remix);
868 in->remix = NULL;
869
870 in->dev = NULL;
871 adev->in = NULL;
872
873 free(in->buffer);
874 free(in);
875}
876
877static int adev_dump(const audio_hw_device_t *device, int fd)
878{
879 UNUSED(device);
880 UNUSED(fd);
881
882 return 0;
883}
884
885static int adev_close(hw_device_t *device)
886{
887 struct j6_audio_device *adev = (struct j6_audio_device *)device;
888
889 ALOGI("adev_close()");
890
891 audio_route_free(adev->route);
892 free(device);
893
894 return 0;
895}
896
897static int adev_open(const hw_module_t* module, const char* name,
898 hw_device_t** device)
899{
900 struct j6_audio_device *adev;
901
902 ALOGI("adev_open() %s", name);
903
904 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
905 return -EINVAL;
906
907 adev = (struct j6_audio_device*)calloc(1, sizeof(struct j6_audio_device));
908 if (!adev)
909 return -ENOMEM;
910
911 pthread_mutex_init(&adev->lock, NULL);
912
913 adev->device.common.tag = HARDWARE_DEVICE_TAG;
914 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
915 adev->device.common.module = (struct hw_module_t *) module;
916 adev->device.common.close = adev_close;
917
918 adev->device.init_check = adev_init_check;
919 adev->device.set_voice_volume = adev_set_voice_volume;
920 adev->device.set_master_volume = adev_set_master_volume;
921 adev->device.get_master_volume = adev_get_master_volume;
922 adev->device.set_master_mute = adev_set_master_mute;
923 adev->device.get_master_mute = adev_get_master_mute;
924 adev->device.set_mode = adev_set_mode;
925 adev->device.set_mic_mute = adev_set_mic_mute;
926 adev->device.get_mic_mute = adev_get_mic_mute;
927 adev->device.set_parameters = adev_set_parameters;
928 adev->device.get_parameters = adev_get_parameters;
929 adev->device.get_input_buffer_size = adev_get_input_buffer_size;
930 adev->device.open_output_stream = adev_open_output_stream;
931 adev->device.close_output_stream = adev_close_output_stream;
932 adev->device.open_input_stream = adev_open_input_stream;
933 adev->device.close_input_stream = adev_close_input_stream;
934 adev->device.dump = adev_dump;
935
936 adev->in_device = AUDIO_DEVICE_IN_BUILTIN_MIC;
937 adev->card = find_card_index(supported_cards,
938 ARRAY_SIZE(supported_cards));
939 adev->in_port = 0;
940 ALOGI("JAMR3 card is hw:%d\n", adev->card);
941
942 adev->mic_mute = false;
943
944 adev->route = audio_route_init(adev->card, MIXER_XML_PATH);
945 if (!adev->route) {
946 ALOGE("Unable to initialize audio routes");
947 free(adev);
948 return -EINVAL;
949 }
950
951 *device = &adev->device.common;
952
953 return 0;
954}
955
956static struct hw_module_methods_t hal_module_methods = {
957 .open = adev_open,
958};
959
960struct audio_module HAL_MODULE_INFO_SYM = {
961 .common = {
962 .tag = HARDWARE_MODULE_TAG,
963 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
964 .hal_api_version = HARDWARE_HAL_API_VERSION,
965 .id = AUDIO_HARDWARE_MODULE_ID,
966 .name = "Jacinto6 JAMR3 Audio HAL",
967 .author = "Texas Instruments Inc.",
968 .methods = &hal_module_methods,
969 },
970};
diff --git a/audio/primary/audio_hw.c b/audio/primary/audio_hw.c
index 0ae1f54..13dca21 100644
--- a/audio/primary/audio_hw.c
+++ b/audio/primary/audio_hw.c
@@ -94,6 +94,7 @@ struct j6_audio_device {
94 struct j6_stream_out *out; 94 struct j6_stream_out *out;
95 struct j6_voice voice; 95 struct j6_voice voice;
96 struct audio_route *route; 96 struct audio_route *route;
97 struct audio_route *jamr_route;
97 audio_devices_t in_device; 98 audio_devices_t in_device;
98 audio_devices_t out_device; 99 audio_devices_t out_device;
99 pthread_mutex_t lock; 100 pthread_mutex_t lock;
@@ -102,6 +103,8 @@ struct j6_audio_device {
102 unsigned int out_port; 103 unsigned int out_port;
103 unsigned int bt_card; 104 unsigned int bt_card;
104 unsigned int bt_port; 105 unsigned int bt_port;
106 unsigned int jamr_card;
107 unsigned int jamr_port;
105 bool mic_mute; 108 bool mic_mute;
106 bool in_call; 109 bool in_call;
107 audio_mode_t mode; 110 audio_mode_t mode;
@@ -120,6 +123,8 @@ struct j6_stream_in {
120 size_t hw_frame_size; 123 size_t hw_frame_size;
121 unsigned int requested_rate; 124 unsigned int requested_rate;
122 unsigned int requested_channels; 125 unsigned int requested_channels;
126 unsigned int card;
127 unsigned int port;
123 int read_status; 128 int read_status;
124 pthread_mutex_t lock; 129 pthread_mutex_t lock;
125 bool standby; 130 bool standby;
@@ -147,10 +152,15 @@ static const char *supported_bt_cards[] = {
147 "DRA7xxWiLink", 152 "DRA7xxWiLink",
148}; 153};
149 154
155static const char *supported_jamr_cards[] = {
156 "DRA7xx-JAMR3",
157};
158
150#define MAX_CARD_COUNT 10 159#define MAX_CARD_COUNT 10
151 160
152#define SUPPORTED_IN_DEVICES (AUDIO_DEVICE_IN_BUILTIN_MIC | \ 161#define SUPPORTED_IN_DEVICES (AUDIO_DEVICE_IN_BUILTIN_MIC | \
153 AUDIO_DEVICE_IN_WIRED_HEADSET | \ 162 AUDIO_DEVICE_IN_WIRED_HEADSET | \
163 AUDIO_DEVICE_IN_LINE | \
154 AUDIO_DEVICE_IN_DEFAULT) 164 AUDIO_DEVICE_IN_DEFAULT)
155#define SUPPORTED_OUT_DEVICES (AUDIO_DEVICE_OUT_SPEAKER | \ 165#define SUPPORTED_OUT_DEVICES (AUDIO_DEVICE_OUT_SPEAKER | \
156 AUDIO_DEVICE_OUT_WIRED_HEADSET | \ 166 AUDIO_DEVICE_OUT_WIRED_HEADSET | \
@@ -173,6 +183,7 @@ static const char *supported_bt_cards[] = {
173#define BT_BUFFER_SIZE (BT_PERIOD_SIZE * BT_PERIOD_COUNT) 183#define BT_BUFFER_SIZE (BT_PERIOD_SIZE * BT_PERIOD_COUNT)
174 184
175#define MIXER_XML_PATH "/vendor/etc/mixer_paths.xml" 185#define MIXER_XML_PATH "/vendor/etc/mixer_paths.xml"
186#define JAMR_MIXER_XML_PATH "/vendor/etc/jamr3_mixer_paths.xml"
176 187
177struct pcm_config pcm_config_capture = { 188struct pcm_config pcm_config_capture = {
178 .channels = 2, 189 .channels = 2,
@@ -1295,8 +1306,8 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
1295 if (in->standby) { 1306 if (in->standby) {
1296 select_input_device(adev); 1307 select_input_device(adev);
1297 1308
1298 ALOGI("in_read() open card %u port %u", adev->card, adev->in_port); 1309 ALOGI("in_read() open card %u port %u", in->card, in->port);
1299 in->pcm = pcm_open(adev->card, adev->in_port, 1310 in->pcm = pcm_open(in->card, in->port,
1300 PCM_IN | PCM_MONOTONIC, 1311 PCM_IN | PCM_MONOTONIC,
1301 &in->config); 1312 &in->config);
1302 if (!pcm_is_ready(in->pcm)) { 1313 if (!pcm_is_ready(in->pcm)) {
@@ -1624,6 +1635,8 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
1624 in->remix = NULL; 1635 in->remix = NULL;
1625 in->resampler = NULL; 1636 in->resampler = NULL;
1626 in->buffer = NULL; 1637 in->buffer = NULL;
1638 in->card = (devices == AUDIO_DEVICE_IN_LINE) ? adev->jamr_card : adev->card;
1639 in->port = 0;
1627 adev->in = in; 1640 adev->in = in;
1628 1641
1629 /* in-place stereo-to-mono remix since capture stream is stereo */ 1642 /* in-place stereo-to-mono remix since capture stream is stereo */
@@ -1721,6 +1734,7 @@ static int adev_close(hw_device_t *device)
1721 ALOGI("adev_close()"); 1734 ALOGI("adev_close()");
1722 1735
1723 audio_route_free(adev->route); 1736 audio_route_free(adev->route);
1737 audio_route_free(adev->jamr_route);
1724 free(device); 1738 free(device);
1725 1739
1726 return 0; 1740 return 0;
@@ -1778,6 +1792,11 @@ static int adev_open(const hw_module_t* module, const char* name,
1778 adev->bt_port = 0; 1792 adev->bt_port = 0;
1779 ALOGI("Bluetooth SCO card is hw:%d\n", adev->bt_card); 1793 ALOGI("Bluetooth SCO card is hw:%d\n", adev->bt_card);
1780 1794
1795 adev->jamr_card = find_card_index(supported_jamr_cards,
1796 ARRAY_SIZE(supported_jamr_cards));
1797 adev->jamr_port = 0;
1798 ALOGI("JAMR card is hw:%d\n", adev->jamr_card);
1799
1781 adev->mic_mute = false; 1800 adev->mic_mute = false;
1782 adev->in_call = false; 1801 adev->in_call = false;
1783 adev->mode = AUDIO_MODE_NORMAL; 1802 adev->mode = AUDIO_MODE_NORMAL;
@@ -1785,13 +1804,24 @@ static int adev_open(const hw_module_t* module, const char* name,
1785 adev->route = audio_route_init(adev->card, MIXER_XML_PATH); 1804 adev->route = audio_route_init(adev->card, MIXER_XML_PATH);
1786 if (!adev->route) { 1805 if (!adev->route) {
1787 ALOGE("Unable to initialize audio routes"); 1806 ALOGE("Unable to initialize audio routes");
1788 free(adev); 1807 goto err1;
1789 return -EINVAL; 1808 }
1809
1810 adev->jamr_route = audio_route_init(adev->jamr_card, JAMR_MIXER_XML_PATH);
1811 if (!adev->jamr_route) {
1812 ALOGE("Unable to initialize JAMR audio routes");
1813 goto err2;
1790 } 1814 }
1791 1815
1792 *device = &adev->device.common; 1816 *device = &adev->device.common;
1793 1817
1794 return 0; 1818 return 0;
1819
1820 err2:
1821 audio_route_free(adev->route);
1822 err1:
1823 free(adev);
1824 return -ENODEV;
1795} 1825}
1796 1826
1797static struct hw_module_methods_t hal_module_methods = { 1827static struct hw_module_methods_t hal_module_methods = {
diff --git a/audio/primary/audio_policy_configuration.xml b/audio/primary/audio_policy_configuration.xml
index f13d1bb..c5fb06e 100644
--- a/audio/primary/audio_policy_configuration.xml
+++ b/audio/primary/audio_policy_configuration.xml
@@ -4,6 +4,7 @@
4 <attachedDevices> 4 <attachedDevices>
5 <item>Speaker</item> 5 <item>Speaker</item>
6 <item>Built-In Mic</item> 6 <item>Built-In Mic</item>
7 <item>Line In</item>
7 </attachedDevices> 8 </attachedDevices>
8 9
9 <defaultOutputDevice>Speaker</defaultOutputDevice> 10 <defaultOutputDevice>Speaker</defaultOutputDevice>
@@ -19,7 +20,11 @@
19 channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/> 20 channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
20 </mixPort> 21 </mixPort>
21 </mixPorts> 22 </mixPorts>
22 23 <mixPort name="line input" role="sink">
24 <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
25 samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
26 channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
27 </mixPort>
23 <devicePorts> 28 <devicePorts>
24 <devicePort tagName="Speaker" type="AUDIO_DEVICE_OUT_SPEAKER" role="sink"> 29 <devicePort tagName="Speaker" type="AUDIO_DEVICE_OUT_SPEAKER" role="sink">
25 </devicePort> 30 </devicePort>
@@ -30,18 +35,17 @@
30 35
31 <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source"> 36 <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
32 </devicePort> 37 </devicePort>
38 <devicePort tagName="Line In" type="AUDIO_DEVICE_IN_LINE" role="source">
39 </devicePort>
33 </devicePorts> 40 </devicePorts>
34 41
35 <routes> 42 <routes>
36 <route type="mux" sink="Speaker" 43 <route type="mux" sink="Speaker" sources="primary output"/>
37 sources="primary output"/> 44 <route type="mux" sink="Wired Headset" sources="primary output"/>
38 <route type="mux" sink="Wired Headset" 45 <route type="mux" sink="Wired Headphones" sources="primary output"/>
39 sources="primary output"/>
40 <route type="mux" sink="Wired Headphones"
41 sources="primary output"/>
42 46
43 <route type="mix" sink="primary input" 47 <route type="mix" sink="primary input" sources="Built-In Mic"/>
44 sources="Built-In Mic"/> 48 <route type="mix" sink="line input" sources="Line In"/>
45 </routes> 49 </routes>
46</module> 50</module>
47 51
diff --git a/audio/jamr3/jamr3_mixer_paths.xml b/audio/primary/jamr3_mixer_paths.xml
index 1277a32..1277a32 100644
--- a/audio/jamr3/jamr3_mixer_paths.xml
+++ b/audio/primary/jamr3_mixer_paths.xml
diff --git a/device.mk b/device.mk
index 69f4dfa..5a9d2f4 100644
--- a/device.mk
+++ b/device.mk
@@ -96,6 +96,7 @@ PRODUCT_COPY_FILES += \
96else 96else
97PRODUCT_COPY_FILES += \ 97PRODUCT_COPY_FILES += \
98 device/ti/jacinto6evm/audio/primary/mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths.xml \ 98 device/ti/jacinto6evm/audio/primary/mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths.xml \
99 device/ti/jacinto6evm/audio/primary/jamr3_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/jamr3_mixer_paths.xml \
99 device/ti/jacinto6evm/audio/primary/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/primary_audio_policy_configuration.xml \ 100 device/ti/jacinto6evm/audio/primary/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/primary_audio_policy_configuration.xml \
100 device/ti/jacinto6evm/audio/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml 101 device/ti/jacinto6evm/audio/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml
101endif 102endif
@@ -161,10 +162,6 @@ PRODUCT_PACKAGES += audio.hdmi.jacinto6
161PRODUCT_PACKAGES += audio.a2dp.default 162PRODUCT_PACKAGES += audio.a2dp.default
162# Remote submix 163# Remote submix
163PRODUCT_PACKAGES += audio.r_submix.default 164PRODUCT_PACKAGES += audio.r_submix.default
164# JAMR3 Audio HAL module
165ifneq ($(APPE_AUDIO),true)
166PRODUCT_PACKAGES += audio.jamr3.jacinto6
167endif
168 165
169PRODUCT_PACKAGES += \ 166PRODUCT_PACKAGES += \
170 tinymix \ 167 tinymix \