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