1 /*
2 * Copyright (C) 2012 The Android Open Source Project
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
20 #include <errno.h>
21 #include <pthread.h>
22 #include <stdint.h>
23 #include <stdlib.h>
24 #include <sys/time.h>
25
26 #include <cutils/log.h>
27 #include <cutils/properties.h>
28 #include <cutils/str_parms.h>
29
30 #include <hardware/audio.h>
31 #include <hardware/hardware.h>
32
33 #include <system/audio.h>
34
35 #include <tinyalsa/asoundlib.h>
36
37 #include <audio_utils/resampler.h>
38 #include <audio_route/audio_route.h>
39
40 #define PCM_CARD 1
41 #define PCM_DEVICE 0
42 #define PCM_DEVICE_SCO 2
43
44 #define MIXER_CARD 1
45
46 #define OUT_PERIOD_SIZE 512
47 #define OUT_SHORT_PERIOD_COUNT 2
48 #define OUT_LONG_PERIOD_COUNT 8
49 #define OUT_SAMPLING_RATE 44100
50
51 #define IN_PERIOD_SIZE 1024
52 #define IN_PERIOD_COUNT 4
53 #define IN_SAMPLING_RATE 44100
54
55 #define SCO_PERIOD_SIZE 256
56 #define SCO_PERIOD_COUNT 4
57 #define SCO_SAMPLING_RATE 8000
58
59 /* minimum sleep time in out_write() when write threshold is not reached */
60 #define MIN_WRITE_SLEEP_US 2000
61 #define MAX_WRITE_SLEEP_US ((OUT_PERIOD_SIZE * OUT_SHORT_PERIOD_COUNT * 1000000) \
62 / OUT_SAMPLING_RATE)
63
64 enum {
65 OUT_BUFFER_TYPE_UNKNOWN,
66 OUT_BUFFER_TYPE_SHORT,
67 OUT_BUFFER_TYPE_LONG,
68 };
69
70 struct pcm_config pcm_config_out = {
71 .channels = 2,
72 .rate = OUT_SAMPLING_RATE,
73 .period_size = OUT_PERIOD_SIZE,
74 .period_count = OUT_LONG_PERIOD_COUNT,
75 .format = PCM_FORMAT_S16_LE,
76 .start_threshold = OUT_PERIOD_SIZE * OUT_SHORT_PERIOD_COUNT,
77 };
78
79 struct pcm_config pcm_config_in = {
80 .channels = 2,
81 .rate = IN_SAMPLING_RATE,
82 .period_size = IN_PERIOD_SIZE,
83 .period_count = IN_PERIOD_COUNT,
84 .format = PCM_FORMAT_S16_LE,
85 .start_threshold = 1,
86 .stop_threshold = (IN_PERIOD_SIZE * IN_PERIOD_COUNT),
87 };
88
89 struct pcm_config pcm_config_sco = {
90 .channels = 1,
91 .rate = SCO_SAMPLING_RATE,
92 .period_size = SCO_PERIOD_SIZE,
93 .period_count = SCO_PERIOD_COUNT,
94 .format = PCM_FORMAT_S16_LE,
95 };
96
97 struct audio_device {
98 struct audio_hw_device hw_device;
99
100 pthread_mutex_t lock; /* see note below on mutex acquisition order */
101 unsigned int out_device;
102 unsigned int in_device;
103 bool standby;
104 bool mic_mute;
105 struct audio_route *ar;
106 int orientation;
107 bool screen_off;
108
109 struct stream_out *active_out;
110 struct stream_in *active_in;
111 };
112
113 struct stream_out {
114 struct audio_stream_out stream;
115
116 pthread_mutex_t lock; /* see note below on mutex acquisition order */
117 struct pcm *pcm;
118 struct pcm_config *pcm_config;
119 bool standby;
120 uint64_t written; /* total frames written, not cleared when entering standby */
121
122 struct resampler_itfe *resampler;
123 int16_t *buffer;
124 size_t buffer_frames;
125
126 int write_threshold;
127 int cur_write_threshold;
128 int buffer_type;
129
130 struct audio_device *dev;
131 };
132
133 struct stream_in {
134 struct audio_stream_in stream;
135
136 pthread_mutex_t lock; /* see note below on mutex acquisition order */
137 struct pcm *pcm;
138 struct pcm_config *pcm_config;
139 bool standby;
140
141 unsigned int requested_rate;
142 struct resampler_itfe *resampler;
143 struct resampler_buffer_provider buf_provider;
144 int16_t *buffer;
145 size_t buffer_size;
146 size_t frames_in;
147 int read_status;
148
149 struct audio_device *dev;
150 };
151
152 enum {
153 ORIENTATION_LANDSCAPE,
154 ORIENTATION_PORTRAIT,
155 ORIENTATION_SQUARE,
156 ORIENTATION_UNDEFINED,
157 };
158
159 static uint32_t out_get_sample_rate(const struct audio_stream *stream);
160 static size_t out_get_buffer_size(const struct audio_stream *stream);
161 static audio_format_t out_get_format(const struct audio_stream *stream);
162 static uint32_t in_get_sample_rate(const struct audio_stream *stream);
163 static size_t in_get_buffer_size(const struct audio_stream *stream);
164 static audio_format_t in_get_format(const struct audio_stream *stream);
165 static int get_next_buffer(struct resampler_buffer_provider *buffer_provider,
166 struct resampler_buffer* buffer);
167 static void release_buffer(struct resampler_buffer_provider *buffer_provider,
168 struct resampler_buffer* buffer);
169
170 /*
171 * NOTE: when multiple mutexes have to be acquired, always take the
172 * audio_device mutex first, followed by the stream_in and/or
173 * stream_out mutexes.
174 */
175
176 /* Helper functions */
177
select_devices(struct audio_device * adev)178 static void select_devices(struct audio_device *adev)
179 {
180 int headphone_on;
181 int speaker_on;
182 int docked;
183 int main_mic_on;
184
185 headphone_on = adev->out_device & (AUDIO_DEVICE_OUT_WIRED_HEADSET |
186 AUDIO_DEVICE_OUT_WIRED_HEADPHONE);
187 speaker_on = adev->out_device & AUDIO_DEVICE_OUT_SPEAKER;
188 docked = adev->out_device & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
189 main_mic_on = adev->in_device & AUDIO_DEVICE_IN_BUILTIN_MIC;
190
191 audio_route_reset(adev->ar);
192
193 if (speaker_on)
194 audio_route_apply_path(adev->ar, "speaker");
195 if (headphone_on)
196 audio_route_apply_path(adev->ar, "headphone");
197 if (docked)
198 audio_route_apply_path(adev->ar, "dock");
199 if (main_mic_on) {
200 if (adev->orientation == ORIENTATION_LANDSCAPE)
201 audio_route_apply_path(adev->ar, "main-mic-left");
202 else
203 audio_route_apply_path(adev->ar, "main-mic-top");
204 }
205
206 audio_route_update_mixer(adev->ar);
207
208 ALOGV("hp=%c speaker=%c dock=%c main-mic=%c", headphone_on ? 'y' : 'n',
209 speaker_on ? 'y' : 'n', docked ? 'y' : 'n', main_mic_on ? 'y' : 'n');
210 }
211
212 /* must be called with hw device and output stream mutexes locked */
do_out_standby(struct stream_out * out)213 static void do_out_standby(struct stream_out *out)
214 {
215 struct audio_device *adev = out->dev;
216
217 if (!out->standby) {
218 pcm_close(out->pcm);
219 out->pcm = NULL;
220 adev->active_out = NULL;
221 if (out->resampler) {
222 release_resampler(out->resampler);
223 out->resampler = NULL;
224 }
225 if (out->buffer) {
226 free(out->buffer);
227 out->buffer = NULL;
228 }
229 out->standby = true;
230 }
231 }
232
233 /* must be called with hw device and input stream mutexes locked */
do_in_standby(struct stream_in * in)234 static void do_in_standby(struct stream_in *in)
235 {
236 struct audio_device *adev = in->dev;
237
238 if (!in->standby) {
239 pcm_close(in->pcm);
240 in->pcm = NULL;
241 adev->active_in = NULL;
242 if (in->resampler) {
243 release_resampler(in->resampler);
244 in->resampler = NULL;
245 }
246 if (in->buffer) {
247 free(in->buffer);
248 in->buffer = NULL;
249 }
250 in->standby = true;
251 }
252 }
253
254 /* must be called with hw device and output stream mutexes locked */
start_output_stream(struct stream_out * out)255 static int start_output_stream(struct stream_out *out)
256 {
257 struct audio_device *adev = out->dev;
258 unsigned int device;
259 int ret;
260
261 /*
262 * Due to the lack of sample rate converters in the SoC,
263 * it greatly simplifies things to have only the main
264 * (speaker/headphone) PCM or the BC SCO PCM open at
265 * the same time.
266 */
267 if (adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
268 device = PCM_DEVICE_SCO;
269 out->pcm_config = &pcm_config_sco;
270 } else {
271 device = PCM_DEVICE;
272 out->pcm_config = &pcm_config_out;
273 out->buffer_type = OUT_BUFFER_TYPE_UNKNOWN;
274 }
275
276 /*
277 * All open PCMs can only use a single group of rates at once:
278 * Group 1: 11.025, 22.05, 44.1
279 * Group 2: 8, 16, 32, 48
280 * Group 1 is used for digital audio playback since 44.1 is
281 * the most common rate, but group 2 is required for SCO.
282 */
283 if (adev->active_in) {
284 struct stream_in *in = adev->active_in;
285 pthread_mutex_lock(&in->lock);
286 if (((out->pcm_config->rate % 8000 == 0) &&
287 (in->pcm_config->rate % 8000) != 0) ||
288 ((out->pcm_config->rate % 11025 == 0) &&
289 (in->pcm_config->rate % 11025) != 0))
290 do_in_standby(in);
291 pthread_mutex_unlock(&in->lock);
292 }
293
294 out->pcm = pcm_open(PCM_CARD, device, PCM_OUT | PCM_NORESTART | PCM_MONOTONIC, out->pcm_config);
295
296 if (out->pcm && !pcm_is_ready(out->pcm)) {
297 ALOGE("pcm_open(out) failed: %s", pcm_get_error(out->pcm));
298 pcm_close(out->pcm);
299 return -ENOMEM;
300 }
301
302 /*
303 * If the stream rate differs from the PCM rate, we need to
304 * create a resampler.
305 */
306 if (out_get_sample_rate(&out->stream.common) != out->pcm_config->rate) {
307 ret = create_resampler(out_get_sample_rate(&out->stream.common),
308 out->pcm_config->rate,
309 out->pcm_config->channels,
310 RESAMPLER_QUALITY_DEFAULT,
311 NULL,
312 &out->resampler);
313 out->buffer_frames = (pcm_config_out.period_size * out->pcm_config->rate) /
314 out_get_sample_rate(&out->stream.common) + 1;
315
316 out->buffer = malloc(pcm_frames_to_bytes(out->pcm, out->buffer_frames));
317 }
318
319 adev->active_out = out;
320
321 return 0;
322 }
323
324 /* must be called with hw device and input stream mutexes locked */
start_input_stream(struct stream_in * in)325 static int start_input_stream(struct stream_in *in)
326 {
327 struct audio_device *adev = in->dev;
328 unsigned int device;
329 int ret;
330
331 /*
332 * Due to the lack of sample rate converters in the SoC,
333 * it greatly simplifies things to have only the main
334 * mic PCM or the BC SCO PCM open at the same time.
335 */
336 if (adev->in_device & AUDIO_DEVICE_IN_ALL_SCO) {
337 device = PCM_DEVICE_SCO;
338 in->pcm_config = &pcm_config_sco;
339 } else {
340 device = PCM_DEVICE;
341 in->pcm_config = &pcm_config_in;
342 }
343
344 /*
345 * All open PCMs can only use a single group of rates at once:
346 * Group 1: 11.025, 22.05, 44.1
347 * Group 2: 8, 16, 32, 48
348 * Group 1 is used for digital audio playback since 44.1 is
349 * the most common rate, but group 2 is required for SCO.
350 */
351 if (adev->active_out) {
352 struct stream_out *out = adev->active_out;
353 pthread_mutex_lock(&out->lock);
354 if (((in->pcm_config->rate % 8000 == 0) &&
355 (out->pcm_config->rate % 8000) != 0) ||
356 ((in->pcm_config->rate % 11025 == 0) &&
357 (out->pcm_config->rate % 11025) != 0))
358 do_out_standby(out);
359 pthread_mutex_unlock(&out->lock);
360 }
361
362 in->pcm = pcm_open(PCM_CARD, device, PCM_IN, in->pcm_config);
363
364 if (in->pcm && !pcm_is_ready(in->pcm)) {
365 ALOGE("pcm_open(in) failed: %s", pcm_get_error(in->pcm));
366 pcm_close(in->pcm);
367 return -ENOMEM;
368 }
369
370 /*
371 * If the stream rate differs from the PCM rate, we need to
372 * create a resampler.
373 */
374 if (in_get_sample_rate(&in->stream.common) != in->pcm_config->rate) {
375 in->buf_provider.get_next_buffer = get_next_buffer;
376 in->buf_provider.release_buffer = release_buffer;
377
378 ret = create_resampler(in->pcm_config->rate,
379 in_get_sample_rate(&in->stream.common),
380 1,
381 RESAMPLER_QUALITY_DEFAULT,
382 &in->buf_provider,
383 &in->resampler);
384 }
385 in->buffer_size = pcm_frames_to_bytes(in->pcm,
386 in->pcm_config->period_size);
387 in->buffer = malloc(in->buffer_size);
388 in->frames_in = 0;
389
390 adev->active_in = in;
391
392 return 0;
393 }
394
get_next_buffer(struct resampler_buffer_provider * buffer_provider,struct resampler_buffer * buffer)395 static int get_next_buffer(struct resampler_buffer_provider *buffer_provider,
396 struct resampler_buffer* buffer)
397 {
398 struct stream_in *in;
399
400 if (buffer_provider == NULL || buffer == NULL)
401 return -EINVAL;
402
403 in = (struct stream_in *)((char *)buffer_provider -
404 offsetof(struct stream_in, buf_provider));
405
406 if (in->pcm == NULL) {
407 buffer->raw = NULL;
408 buffer->frame_count = 0;
409 in->read_status = -ENODEV;
410 return -ENODEV;
411 }
412
413 if (in->frames_in == 0) {
414 in->read_status = pcm_read(in->pcm,
415 (void*)in->buffer,
416 in->buffer_size);
417 if (in->read_status != 0) {
418 ALOGE("get_next_buffer() pcm_read error %d", in->read_status);
419 buffer->raw = NULL;
420 buffer->frame_count = 0;
421 return in->read_status;
422 }
423 in->frames_in = in->pcm_config->period_size;
424 if (in->pcm_config->channels == 2) {
425 unsigned int i;
426
427 /* Discard right channel */
428 for (i = 1; i < in->frames_in; i++)
429 in->buffer[i] = in->buffer[i * 2];
430 }
431 }
432
433 buffer->frame_count = (buffer->frame_count > in->frames_in) ?
434 in->frames_in : buffer->frame_count;
435 buffer->i16 = in->buffer + (in->pcm_config->period_size - in->frames_in);
436
437 return in->read_status;
438
439 }
440
release_buffer(struct resampler_buffer_provider * buffer_provider,struct resampler_buffer * buffer)441 static void release_buffer(struct resampler_buffer_provider *buffer_provider,
442 struct resampler_buffer* buffer)
443 {
444 struct stream_in *in;
445
446 if (buffer_provider == NULL || buffer == NULL)
447 return;
448
449 in = (struct stream_in *)((char *)buffer_provider -
450 offsetof(struct stream_in, buf_provider));
451
452 in->frames_in -= buffer->frame_count;
453 }
454
455 /* read_frames() reads frames from kernel driver, down samples to capture rate
456 * if necessary and output the number of frames requested to the buffer specified */
read_frames(struct stream_in * in,void * buffer,ssize_t frames)457 static ssize_t read_frames(struct stream_in *in, void *buffer, ssize_t frames)
458 {
459 ssize_t frames_wr = 0;
460
461 while (frames_wr < frames) {
462 size_t frames_rd = frames - frames_wr;
463 if (in->resampler != NULL) {
464 in->resampler->resample_from_provider(in->resampler,
465 (int16_t *)((char *)buffer +
466 frames_wr * audio_stream_frame_size(&in->stream.common)),
467 &frames_rd);
468 } else {
469 struct resampler_buffer buf = {
470 { raw : NULL, },
471 frame_count : frames_rd,
472 };
473 get_next_buffer(&in->buf_provider, &buf);
474 if (buf.raw != NULL) {
475 memcpy((char *)buffer +
476 frames_wr * audio_stream_frame_size(&in->stream.common),
477 buf.raw,
478 buf.frame_count * audio_stream_frame_size(&in->stream.common));
479 frames_rd = buf.frame_count;
480 }
481 release_buffer(&in->buf_provider, &buf);
482 }
483 /* in->read_status is updated by getNextBuffer() also called by
484 * in->resampler->resample_from_provider() */
485 if (in->read_status != 0)
486 return in->read_status;
487
488 frames_wr += frames_rd;
489 }
490 return frames_wr;
491 }
492
493 /* API functions */
494
out_get_sample_rate(const struct audio_stream * stream)495 static uint32_t out_get_sample_rate(const struct audio_stream *stream)
496 {
497 return pcm_config_out.rate;
498 }
499
out_set_sample_rate(struct audio_stream * stream,uint32_t rate)500 static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
501 {
502 return -ENOSYS;
503 }
504
out_get_buffer_size(const struct audio_stream * stream)505 static size_t out_get_buffer_size(const struct audio_stream *stream)
506 {
507 return pcm_config_out.period_size *
508 audio_stream_frame_size((struct audio_stream *)stream);
509 }
510
out_get_channels(const struct audio_stream * stream)511 static uint32_t out_get_channels(const struct audio_stream *stream)
512 {
513 return AUDIO_CHANNEL_OUT_STEREO;
514 }
515
out_get_format(const struct audio_stream * stream)516 static audio_format_t out_get_format(const struct audio_stream *stream)
517 {
518 return AUDIO_FORMAT_PCM_16_BIT;
519 }
520
out_set_format(struct audio_stream * stream,audio_format_t format)521 static int out_set_format(struct audio_stream *stream, audio_format_t format)
522 {
523 return -ENOSYS;
524 }
525
out_standby(struct audio_stream * stream)526 static int out_standby(struct audio_stream *stream)
527 {
528 struct stream_out *out = (struct stream_out *)stream;
529
530 pthread_mutex_lock(&out->dev->lock);
531 pthread_mutex_lock(&out->lock);
532 do_out_standby(out);
533 pthread_mutex_unlock(&out->lock);
534 pthread_mutex_unlock(&out->dev->lock);
535
536 return 0;
537 }
538
out_dump(const struct audio_stream * stream,int fd)539 static int out_dump(const struct audio_stream *stream, int fd)
540 {
541 return 0;
542 }
543
out_set_parameters(struct audio_stream * stream,const char * kvpairs)544 static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
545 {
546 struct stream_out *out = (struct stream_out *)stream;
547 struct audio_device *adev = out->dev;
548 struct str_parms *parms;
549 char value[32];
550 int ret;
551 unsigned int val;
552
553 parms = str_parms_create_str(kvpairs);
554
555 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING,
556 value, sizeof(value));
557 pthread_mutex_lock(&adev->lock);
558 if (ret >= 0) {
559 val = atoi(value);
560 if ((adev->out_device != val) && (val != 0)) {
561 /*
562 * If SCO is turned on/off, we need to put audio into standby
563 * because SCO uses a different PCM.
564 */
565 if ((val & AUDIO_DEVICE_OUT_ALL_SCO) ^
566 (adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO)) {
567 pthread_mutex_lock(&out->lock);
568 do_out_standby(out);
569 pthread_mutex_unlock(&out->lock);
570 }
571
572 adev->out_device = val;
573 select_devices(adev);
574 }
575 }
576 pthread_mutex_unlock(&adev->lock);
577
578 str_parms_destroy(parms);
579 return ret;
580 }
581
out_get_parameters(const struct audio_stream * stream,const char * keys)582 static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
583 {
584 return strdup("");
585 }
586
out_get_latency(const struct audio_stream_out * stream)587 static uint32_t out_get_latency(const struct audio_stream_out *stream)
588 {
589 struct stream_out *out = (struct stream_out *)stream;
590 struct audio_device *adev = out->dev;
591 size_t period_count;
592
593 pthread_mutex_lock(&adev->lock);
594
595 if (adev->screen_off && !adev->active_in && !(adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO))
596 period_count = OUT_LONG_PERIOD_COUNT;
597 else
598 period_count = OUT_SHORT_PERIOD_COUNT;
599
600 pthread_mutex_unlock(&adev->lock);
601
602 return (pcm_config_out.period_size * period_count * 1000) / pcm_config_out.rate;
603 }
604
out_set_volume(struct audio_stream_out * stream,float left,float right)605 static int out_set_volume(struct audio_stream_out *stream, float left,
606 float right)
607 {
608 return -ENOSYS;
609 }
610
out_write(struct audio_stream_out * stream,const void * buffer,size_t bytes)611 static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
612 size_t bytes)
613 {
614 int ret = 0;
615 struct stream_out *out = (struct stream_out *)stream;
616 struct audio_device *adev = out->dev;
617 size_t frame_size = audio_stream_frame_size(&out->stream.common);
618 int16_t *in_buffer = (int16_t *)buffer;
619 size_t in_frames = bytes / frame_size;
620 size_t out_frames;
621 int buffer_type;
622 int kernel_frames;
623 bool sco_on;
624
625 /*
626 * acquiring hw device mutex systematically is useful if a low
627 * priority thread is waiting on the output stream mutex - e.g.
628 * executing out_set_parameters() while holding the hw device
629 * mutex
630 */
631 pthread_mutex_lock(&adev->lock);
632 pthread_mutex_lock(&out->lock);
633 if (out->standby) {
634 ret = start_output_stream(out);
635 if (ret != 0) {
636 pthread_mutex_unlock(&adev->lock);
637 goto exit;
638 }
639 out->standby = false;
640 }
641 buffer_type = (adev->screen_off && !adev->active_in) ?
642 OUT_BUFFER_TYPE_LONG : OUT_BUFFER_TYPE_SHORT;
643 sco_on = (adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO);
644 pthread_mutex_unlock(&adev->lock);
645
646 /* detect changes in screen ON/OFF state and adapt buffer size
647 * if needed. Do not change buffer size when routed to SCO device. */
648 if (!sco_on && (buffer_type != out->buffer_type)) {
649 size_t period_count;
650
651 if (buffer_type == OUT_BUFFER_TYPE_LONG)
652 period_count = OUT_LONG_PERIOD_COUNT;
653 else
654 period_count = OUT_SHORT_PERIOD_COUNT;
655
656 out->write_threshold = out->pcm_config->period_size * period_count;
657 /* reset current threshold if exiting standby */
658 if (out->buffer_type == OUT_BUFFER_TYPE_UNKNOWN)
659 out->cur_write_threshold = out->write_threshold;
660 out->buffer_type = buffer_type;
661 }
662
663 /* Reduce number of channels, if necessary */
664 if (popcount(out_get_channels(&stream->common)) >
665 (int)out->pcm_config->channels) {
666 unsigned int i;
667
668 /* Discard right channel */
669 for (i = 1; i < in_frames; i++)
670 in_buffer[i] = in_buffer[i * 2];
671
672 /* The frame size is now half */
673 frame_size /= 2;
674 }
675
676 /* Change sample rate, if necessary */
677 if (out_get_sample_rate(&stream->common) != out->pcm_config->rate) {
678 out_frames = out->buffer_frames;
679 out->resampler->resample_from_input(out->resampler,
680 in_buffer, &in_frames,
681 out->buffer, &out_frames);
682 in_buffer = out->buffer;
683 } else {
684 out_frames = in_frames;
685 }
686
687 if (!sco_on) {
688 int total_sleep_time_us = 0;
689 size_t period_size = out->pcm_config->period_size;
690
691 /* do not allow more than out->cur_write_threshold frames in kernel
692 * pcm driver buffer */
693 do {
694 struct timespec time_stamp;
695 if (pcm_get_htimestamp(out->pcm,
696 (unsigned int *)&kernel_frames,
697 &time_stamp) < 0)
698 break;
699 kernel_frames = pcm_get_buffer_size(out->pcm) - kernel_frames;
700
701 if (kernel_frames > out->cur_write_threshold) {
702 int sleep_time_us =
703 (int)(((int64_t)(kernel_frames - out->cur_write_threshold)
704 * 1000000) / out->pcm_config->rate);
705 if (sleep_time_us < MIN_WRITE_SLEEP_US)
706 break;
707 total_sleep_time_us += sleep_time_us;
708 if (total_sleep_time_us > MAX_WRITE_SLEEP_US) {
709 ALOGW("out_write() limiting sleep time %d to %d",
710 total_sleep_time_us, MAX_WRITE_SLEEP_US);
711 sleep_time_us = MAX_WRITE_SLEEP_US -
712 (total_sleep_time_us - sleep_time_us);
713 }
714 usleep(sleep_time_us);
715 }
716
717 } while ((kernel_frames > out->cur_write_threshold) &&
718 (total_sleep_time_us <= MAX_WRITE_SLEEP_US));
719
720 /* do not allow abrupt changes on buffer size. Increasing/decreasing
721 * the threshold by steps of 1/4th of the buffer size keeps the write
722 * time within a reasonable range during transitions.
723 * Also reset current threshold just above current filling status when
724 * kernel buffer is really depleted to allow for smooth catching up with
725 * target threshold.
726 */
727 if (out->cur_write_threshold > out->write_threshold) {
728 out->cur_write_threshold -= period_size / 4;
729 if (out->cur_write_threshold < out->write_threshold) {
730 out->cur_write_threshold = out->write_threshold;
731 }
732 } else if (out->cur_write_threshold < out->write_threshold) {
733 out->cur_write_threshold += period_size / 4;
734 if (out->cur_write_threshold > out->write_threshold) {
735 out->cur_write_threshold = out->write_threshold;
736 }
737 } else if ((kernel_frames < out->write_threshold) &&
738 ((out->write_threshold - kernel_frames) >
739 (int)(period_size * OUT_SHORT_PERIOD_COUNT))) {
740 out->cur_write_threshold = (kernel_frames / period_size + 1) * period_size;
741 out->cur_write_threshold += period_size / 4;
742 }
743 }
744
745 ret = pcm_write(out->pcm, in_buffer, out_frames * frame_size);
746 if (ret == -EPIPE) {
747 /* In case of underrun, don't sleep since we want to catch up asap */
748 pthread_mutex_unlock(&out->lock);
749 return ret;
750 }
751 if (ret == 0) {
752 out->written += out_frames;
753 }
754
755 exit:
756 pthread_mutex_unlock(&out->lock);
757
758 if (ret != 0) {
759 usleep(bytes * 1000000 / audio_stream_frame_size(&stream->common) /
760 out_get_sample_rate(&stream->common));
761 }
762
763 return bytes;
764 }
765
out_get_render_position(const struct audio_stream_out * stream,uint32_t * dsp_frames)766 static int out_get_render_position(const struct audio_stream_out *stream,
767 uint32_t *dsp_frames)
768 {
769 return -EINVAL;
770 }
771
out_add_audio_effect(const struct audio_stream * stream,effect_handle_t effect)772 static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
773 {
774 return 0;
775 }
776
out_remove_audio_effect(const struct audio_stream * stream,effect_handle_t effect)777 static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
778 {
779 return 0;
780 }
781
out_get_next_write_timestamp(const struct audio_stream_out * stream,int64_t * timestamp)782 static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
783 int64_t *timestamp)
784 {
785 return -EINVAL;
786 }
787
out_get_presentation_position(const struct audio_stream_out * stream,uint64_t * frames,struct timespec * timestamp)788 static int out_get_presentation_position(const struct audio_stream_out *stream,
789 uint64_t *frames, struct timespec *timestamp)
790 {
791 struct stream_out *out = (struct stream_out *)stream;
792 int ret = -1;
793
794 pthread_mutex_lock(&out->lock);
795
796 size_t avail;
797 if (pcm_get_htimestamp(out->pcm, &avail, timestamp) == 0) {
798 size_t kernel_buffer_size = out->pcm_config->period_size * out->pcm_config->period_count;
799 // FIXME This calculation is incorrect if there is buffering after app processor
800 int64_t signed_frames = out->written - kernel_buffer_size + avail;
801 // It would be unusual for this value to be negative, but check just in case ...
802 if (signed_frames >= 0) {
803 *frames = signed_frames;
804 ret = 0;
805 }
806 }
807
808 pthread_mutex_unlock(&out->lock);
809
810 return ret;
811 }
812
813 /** audio_stream_in implementation **/
in_get_sample_rate(const struct audio_stream * stream)814 static uint32_t in_get_sample_rate(const struct audio_stream *stream)
815 {
816 struct stream_in *in = (struct stream_in *)stream;
817
818 return in->requested_rate;
819 }
820
in_set_sample_rate(struct audio_stream * stream,uint32_t rate)821 static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
822 {
823 return 0;
824 }
825
in_get_buffer_size(const struct audio_stream * stream)826 static size_t in_get_buffer_size(const struct audio_stream *stream)
827 {
828 struct stream_in *in = (struct stream_in *)stream;
829 size_t size;
830
831 /*
832 * take resampling into account and return the closest majoring
833 * multiple of 16 frames, as audioflinger expects audio buffers to
834 * be a multiple of 16 frames
835 */
836 size = (in->pcm_config->period_size * in_get_sample_rate(stream)) /
837 in->pcm_config->rate;
838 size = ((size + 15) / 16) * 16;
839
840 return size * audio_stream_frame_size((struct audio_stream *)stream);
841 }
842
in_get_channels(const struct audio_stream * stream)843 static uint32_t in_get_channels(const struct audio_stream *stream)
844 {
845 return AUDIO_CHANNEL_IN_MONO;
846 }
847
in_get_format(const struct audio_stream * stream)848 static audio_format_t in_get_format(const struct audio_stream *stream)
849 {
850 return AUDIO_FORMAT_PCM_16_BIT;
851 }
852
in_set_format(struct audio_stream * stream,audio_format_t format)853 static int in_set_format(struct audio_stream *stream, audio_format_t format)
854 {
855 return -ENOSYS;
856 }
857
in_standby(struct audio_stream * stream)858 static int in_standby(struct audio_stream *stream)
859 {
860 struct stream_in *in = (struct stream_in *)stream;
861
862 pthread_mutex_lock(&in->dev->lock);
863 pthread_mutex_lock(&in->lock);
864 do_in_standby(in);
865 pthread_mutex_unlock(&in->lock);
866 pthread_mutex_unlock(&in->dev->lock);
867
868 return 0;
869 }
870
in_dump(const struct audio_stream * stream,int fd)871 static int in_dump(const struct audio_stream *stream, int fd)
872 {
873 return 0;
874 }
875
in_set_parameters(struct audio_stream * stream,const char * kvpairs)876 static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
877 {
878 struct stream_in *in = (struct stream_in *)stream;
879 struct audio_device *adev = in->dev;
880 struct str_parms *parms;
881 char value[32];
882 int ret;
883 unsigned int val;
884
885 parms = str_parms_create_str(kvpairs);
886
887 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING,
888 value, sizeof(value));
889 pthread_mutex_lock(&adev->lock);
890 if (ret >= 0) {
891 val = atoi(value) & ~AUDIO_DEVICE_BIT_IN;
892 if ((adev->in_device != val) && (val != 0)) {
893 /*
894 * If SCO is turned on/off, we need to put audio into standby
895 * because SCO uses a different PCM.
896 */
897 if ((val & AUDIO_DEVICE_IN_ALL_SCO) ^
898 (adev->in_device & AUDIO_DEVICE_IN_ALL_SCO)) {
899 pthread_mutex_lock(&in->lock);
900 do_in_standby(in);
901 pthread_mutex_unlock(&in->lock);
902 }
903
904 adev->in_device = val;
905 select_devices(adev);
906 }
907 }
908 pthread_mutex_unlock(&adev->lock);
909
910 str_parms_destroy(parms);
911 return ret;
912 }
913
in_get_parameters(const struct audio_stream * stream,const char * keys)914 static char * in_get_parameters(const struct audio_stream *stream,
915 const char *keys)
916 {
917 return strdup("");
918 }
919
in_set_gain(struct audio_stream_in * stream,float gain)920 static int in_set_gain(struct audio_stream_in *stream, float gain)
921 {
922 return 0;
923 }
924
in_read(struct audio_stream_in * stream,void * buffer,size_t bytes)925 static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
926 size_t bytes)
927 {
928 int ret = 0;
929 struct stream_in *in = (struct stream_in *)stream;
930 struct audio_device *adev = in->dev;
931 size_t frames_rq = bytes / audio_stream_frame_size(&stream->common);
932
933 /*
934 * acquiring hw device mutex systematically is useful if a low
935 * priority thread is waiting on the input stream mutex - e.g.
936 * executing in_set_parameters() while holding the hw device
937 * mutex
938 */
939 pthread_mutex_lock(&adev->lock);
940 pthread_mutex_lock(&in->lock);
941 if (in->standby) {
942 ret = start_input_stream(in);
943 if (ret == 0)
944 in->standby = 0;
945 }
946 pthread_mutex_unlock(&adev->lock);
947
948 if (ret < 0)
949 goto exit;
950
951 /*if (in->num_preprocessors != 0) {
952 ret = process_frames(in, buffer, frames_rq);
953 } else */if (in->resampler != NULL) {
954 ret = read_frames(in, buffer, frames_rq);
955 } else if (in->pcm_config->channels == 2) {
956 /*
957 * If the PCM is stereo, capture twice as many frames and
958 * discard the right channel.
959 */
960 unsigned int i;
961 int16_t *in_buffer = (int16_t *)buffer;
962
963 ret = pcm_read(in->pcm, in->buffer, bytes * 2);
964
965 /* Discard right channel */
966 for (i = 0; i < frames_rq; i++)
967 in_buffer[i] = in->buffer[i * 2];
968 } else {
969 ret = pcm_read(in->pcm, buffer, bytes);
970 }
971
972 if (ret > 0)
973 ret = 0;
974
975 /*
976 * Instead of writing zeroes here, we could trust the hardware
977 * to always provide zeroes when muted.
978 */
979 if (ret == 0 && adev->mic_mute)
980 memset(buffer, 0, bytes);
981
982 exit:
983 if (ret < 0)
984 usleep(bytes * 1000000 / audio_stream_frame_size(&stream->common) /
985 in_get_sample_rate(&stream->common));
986
987 pthread_mutex_unlock(&in->lock);
988 return bytes;
989 }
990
in_get_input_frames_lost(struct audio_stream_in * stream)991 static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
992 {
993 return 0;
994 }
995
in_add_audio_effect(const struct audio_stream * stream,effect_handle_t effect)996 static int in_add_audio_effect(const struct audio_stream *stream,
997 effect_handle_t effect)
998 {
999 return 0;
1000 }
1001
in_remove_audio_effect(const struct audio_stream * stream,effect_handle_t effect)1002 static int in_remove_audio_effect(const struct audio_stream *stream,
1003 effect_handle_t effect)
1004 {
1005 return 0;
1006 }
1007
1008
adev_open_output_stream(struct audio_hw_device * dev,audio_io_handle_t handle,audio_devices_t devices,audio_output_flags_t flags,struct audio_config * config,struct audio_stream_out ** stream_out)1009 static int adev_open_output_stream(struct audio_hw_device *dev,
1010 audio_io_handle_t handle,
1011 audio_devices_t devices,
1012 audio_output_flags_t flags,
1013 struct audio_config *config,
1014 struct audio_stream_out **stream_out)
1015 {
1016 struct audio_device *adev = (struct audio_device *)dev;
1017 struct stream_out *out;
1018 int ret;
1019
1020 out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
1021 if (!out)
1022 return -ENOMEM;
1023
1024 out->stream.common.get_sample_rate = out_get_sample_rate;
1025 out->stream.common.set_sample_rate = out_set_sample_rate;
1026 out->stream.common.get_buffer_size = out_get_buffer_size;
1027 out->stream.common.get_channels = out_get_channels;
1028 out->stream.common.get_format = out_get_format;
1029 out->stream.common.set_format = out_set_format;
1030 out->stream.common.standby = out_standby;
1031 out->stream.common.dump = out_dump;
1032 out->stream.common.set_parameters = out_set_parameters;
1033 out->stream.common.get_parameters = out_get_parameters;
1034 out->stream.common.add_audio_effect = out_add_audio_effect;
1035 out->stream.common.remove_audio_effect = out_remove_audio_effect;
1036 out->stream.get_latency = out_get_latency;
1037 out->stream.set_volume = out_set_volume;
1038 out->stream.write = out_write;
1039 out->stream.get_render_position = out_get_render_position;
1040 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
1041 out->stream.get_presentation_position = out_get_presentation_position;
1042
1043 out->dev = adev;
1044
1045 config->format = out_get_format(&out->stream.common);
1046 config->channel_mask = out_get_channels(&out->stream.common);
1047 config->sample_rate = out_get_sample_rate(&out->stream.common);
1048
1049 out->standby = true;
1050 /* out->written = 0; by calloc() */
1051
1052 *stream_out = &out->stream;
1053 return 0;
1054
1055 err_open:
1056 free(out);
1057 *stream_out = NULL;
1058 return ret;
1059 }
1060
adev_close_output_stream(struct audio_hw_device * dev,struct audio_stream_out * stream)1061 static void adev_close_output_stream(struct audio_hw_device *dev,
1062 struct audio_stream_out *stream)
1063 {
1064 out_standby(&stream->common);
1065 free(stream);
1066 }
1067
adev_set_parameters(struct audio_hw_device * dev,const char * kvpairs)1068 static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
1069 {
1070 struct audio_device *adev = (struct audio_device *)dev;
1071 struct str_parms *parms;
1072 char *str;
1073 char value[32];
1074 int ret;
1075
1076 parms = str_parms_create_str(kvpairs);
1077 ret = str_parms_get_str(parms, "orientation", value, sizeof(value));
1078 if (ret >= 0) {
1079 int orientation;
1080
1081 if (strcmp(value, "landscape") == 0)
1082 orientation = ORIENTATION_LANDSCAPE;
1083 else if (strcmp(value, "portrait") == 0)
1084 orientation = ORIENTATION_PORTRAIT;
1085 else if (strcmp(value, "square") == 0)
1086 orientation = ORIENTATION_SQUARE;
1087 else
1088 orientation = ORIENTATION_UNDEFINED;
1089
1090 pthread_mutex_lock(&adev->lock);
1091 if (orientation != adev->orientation) {
1092 adev->orientation = orientation;
1093 /*
1094 * Orientation changes can occur with the input device
1095 * closed so we must call select_devices() here to set
1096 * up the mixer. This is because select_devices() will
1097 * not be called when the input device is opened if no
1098 * other input parameter is changed.
1099 */
1100 select_devices(adev);
1101 }
1102 pthread_mutex_unlock(&adev->lock);
1103 }
1104
1105 ret = str_parms_get_str(parms, "screen_state", value, sizeof(value));
1106 if (ret >= 0) {
1107 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
1108 adev->screen_off = false;
1109 else
1110 adev->screen_off = true;
1111 }
1112
1113 str_parms_destroy(parms);
1114 return ret;
1115 }
1116
adev_get_parameters(const struct audio_hw_device * dev,const char * keys)1117 static char * adev_get_parameters(const struct audio_hw_device *dev,
1118 const char *keys)
1119 {
1120 return strdup("");
1121 }
1122
adev_init_check(const struct audio_hw_device * dev)1123 static int adev_init_check(const struct audio_hw_device *dev)
1124 {
1125 return 0;
1126 }
1127
adev_set_voice_volume(struct audio_hw_device * dev,float volume)1128 static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
1129 {
1130 return -ENOSYS;
1131 }
1132
adev_set_master_volume(struct audio_hw_device * dev,float volume)1133 static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
1134 {
1135 return -ENOSYS;
1136 }
1137
adev_set_mode(struct audio_hw_device * dev,audio_mode_t mode)1138 static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
1139 {
1140 return 0;
1141 }
1142
adev_set_mic_mute(struct audio_hw_device * dev,bool state)1143 static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
1144 {
1145 struct audio_device *adev = (struct audio_device *)dev;
1146
1147 adev->mic_mute = state;
1148
1149 return 0;
1150 }
1151
adev_get_mic_mute(const struct audio_hw_device * dev,bool * state)1152 static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
1153 {
1154 struct audio_device *adev = (struct audio_device *)dev;
1155
1156 *state = adev->mic_mute;
1157
1158 return 0;
1159 }
1160
adev_get_input_buffer_size(const struct audio_hw_device * dev,const struct audio_config * config)1161 static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
1162 const struct audio_config *config)
1163 {
1164 size_t size;
1165
1166 /*
1167 * take resampling into account and return the closest majoring
1168 * multiple of 16 frames, as audioflinger expects audio buffers to
1169 * be a multiple of 16 frames
1170 */
1171 size = (pcm_config_in.period_size * config->sample_rate) / pcm_config_in.rate;
1172 size = ((size + 15) / 16) * 16;
1173
1174 return (size * popcount(config->channel_mask) *
1175 audio_bytes_per_sample(config->format));
1176 }
1177
adev_open_input_stream(struct audio_hw_device * dev,audio_io_handle_t handle,audio_devices_t devices,struct audio_config * config,struct audio_stream_in ** stream_in)1178 static int adev_open_input_stream(struct audio_hw_device *dev,
1179 audio_io_handle_t handle,
1180 audio_devices_t devices,
1181 struct audio_config *config,
1182 struct audio_stream_in **stream_in)
1183 {
1184 struct audio_device *adev = (struct audio_device *)dev;
1185 struct stream_in *in;
1186 int ret;
1187
1188 *stream_in = NULL;
1189
1190 /* Respond with a request for mono if a different format is given. */
1191 if (config->channel_mask != AUDIO_CHANNEL_IN_MONO) {
1192 config->channel_mask = AUDIO_CHANNEL_IN_MONO;
1193 return -EINVAL;
1194 }
1195
1196 in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
1197 if (!in)
1198 return -ENOMEM;
1199
1200 in->stream.common.get_sample_rate = in_get_sample_rate;
1201 in->stream.common.set_sample_rate = in_set_sample_rate;
1202 in->stream.common.get_buffer_size = in_get_buffer_size;
1203 in->stream.common.get_channels = in_get_channels;
1204 in->stream.common.get_format = in_get_format;
1205 in->stream.common.set_format = in_set_format;
1206 in->stream.common.standby = in_standby;
1207 in->stream.common.dump = in_dump;
1208 in->stream.common.set_parameters = in_set_parameters;
1209 in->stream.common.get_parameters = in_get_parameters;
1210 in->stream.common.add_audio_effect = in_add_audio_effect;
1211 in->stream.common.remove_audio_effect = in_remove_audio_effect;
1212 in->stream.set_gain = in_set_gain;
1213 in->stream.read = in_read;
1214 in->stream.get_input_frames_lost = in_get_input_frames_lost;
1215
1216 in->dev = adev;
1217 in->standby = true;
1218 in->requested_rate = config->sample_rate;
1219 in->pcm_config = &pcm_config_in; /* default PCM config */
1220
1221 *stream_in = &in->stream;
1222 return 0;
1223 }
1224
adev_close_input_stream(struct audio_hw_device * dev,struct audio_stream_in * stream)1225 static void adev_close_input_stream(struct audio_hw_device *dev,
1226 struct audio_stream_in *stream)
1227 {
1228 struct stream_in *in = (struct stream_in *)stream;
1229
1230 in_standby(&stream->common);
1231 free(stream);
1232 }
1233
adev_dump(const audio_hw_device_t * device,int fd)1234 static int adev_dump(const audio_hw_device_t *device, int fd)
1235 {
1236 return 0;
1237 }
1238
adev_close(hw_device_t * device)1239 static int adev_close(hw_device_t *device)
1240 {
1241 struct audio_device *adev = (struct audio_device *)device;
1242
1243 audio_route_free(adev->ar);
1244
1245 free(device);
1246 return 0;
1247 }
1248
adev_open(const hw_module_t * module,const char * name,hw_device_t ** device)1249 static int adev_open(const hw_module_t* module, const char* name,
1250 hw_device_t** device)
1251 {
1252 struct audio_device *adev;
1253 int ret;
1254
1255 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
1256 return -EINVAL;
1257
1258 adev = calloc(1, sizeof(struct audio_device));
1259 if (!adev)
1260 return -ENOMEM;
1261
1262 adev->hw_device.common.tag = HARDWARE_DEVICE_TAG;
1263 adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
1264 adev->hw_device.common.module = (struct hw_module_t *) module;
1265 adev->hw_device.common.close = adev_close;
1266
1267 adev->hw_device.init_check = adev_init_check;
1268 adev->hw_device.set_voice_volume = adev_set_voice_volume;
1269 adev->hw_device.set_master_volume = adev_set_master_volume;
1270 adev->hw_device.set_mode = adev_set_mode;
1271 adev->hw_device.set_mic_mute = adev_set_mic_mute;
1272 adev->hw_device.get_mic_mute = adev_get_mic_mute;
1273 adev->hw_device.set_parameters = adev_set_parameters;
1274 adev->hw_device.get_parameters = adev_get_parameters;
1275 adev->hw_device.get_input_buffer_size = adev_get_input_buffer_size;
1276 adev->hw_device.open_output_stream = adev_open_output_stream;
1277 adev->hw_device.close_output_stream = adev_close_output_stream;
1278 adev->hw_device.open_input_stream = adev_open_input_stream;
1279 adev->hw_device.close_input_stream = adev_close_input_stream;
1280 adev->hw_device.dump = adev_dump;
1281
1282 adev->ar = audio_route_init(MIXER_CARD, NULL);
1283 adev->orientation = ORIENTATION_UNDEFINED;
1284 adev->out_device = AUDIO_DEVICE_OUT_SPEAKER;
1285 adev->in_device = AUDIO_DEVICE_IN_BUILTIN_MIC & ~AUDIO_DEVICE_BIT_IN;
1286
1287 *device = &adev->hw_device.common;
1288
1289 return 0;
1290 }
1291
1292 static struct hw_module_methods_t hal_module_methods = {
1293 .open = adev_open,
1294 };
1295
1296 struct audio_module HAL_MODULE_INFO_SYM = {
1297 .common = {
1298 .tag = HARDWARE_MODULE_TAG,
1299 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
1300 .hal_api_version = HARDWARE_HAL_API_VERSION,
1301 .id = AUDIO_HARDWARE_MODULE_ID,
1302 .name = "Grouper audio HW HAL",
1303 .author = "The Android Open Source Project",
1304 .methods = &hal_module_methods,
1305 },
1306 };
1307