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_generic"
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 #include <fcntl.h>
26
27 #include <cutils/log.h>
28 #include <cutils/str_parms.h>
29
30 #include <hardware/hardware.h>
31 #include <system/audio.h>
32 #include <hardware/audio.h>
33
34
35 #define AUDIO_DEVICE_NAME "/dev/eac"
36 #define OUT_SAMPLING_RATE 44100
37 #define OUT_BUFFER_SIZE 4096
38 #define OUT_LATENCY_MS 20
39 #define IN_SAMPLING_RATE 8000
40 #define IN_BUFFER_SIZE 320
41
42
43 struct generic_audio_device {
44 struct audio_hw_device device;
45 pthread_mutex_t lock;
46 struct audio_stream_out *output;
47 struct audio_stream_in *input;
48 int fd;
49 bool mic_mute;
50 };
51
52
53 struct generic_stream_out {
54 struct audio_stream_out stream;
55 struct generic_audio_device *dev;
56 audio_devices_t device;
57 };
58
59 struct generic_stream_in {
60 struct audio_stream_in stream;
61 struct generic_audio_device *dev;
62 audio_devices_t device;
63 };
64
65
out_get_sample_rate(const struct audio_stream * stream)66 static uint32_t out_get_sample_rate(const struct audio_stream *stream)
67 {
68 return OUT_SAMPLING_RATE;
69 }
70
out_set_sample_rate(struct audio_stream * stream,uint32_t rate)71 static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
72 {
73 return -ENOSYS;
74 }
75
out_get_buffer_size(const struct audio_stream * stream)76 static size_t out_get_buffer_size(const struct audio_stream *stream)
77 {
78 return OUT_BUFFER_SIZE;
79 }
80
out_get_channels(const struct audio_stream * stream)81 static audio_channel_mask_t out_get_channels(const struct audio_stream *stream)
82 {
83 return AUDIO_CHANNEL_OUT_STEREO;
84 }
85
out_get_format(const struct audio_stream * stream)86 static audio_format_t out_get_format(const struct audio_stream *stream)
87 {
88 return AUDIO_FORMAT_PCM_16_BIT;
89 }
90
out_set_format(struct audio_stream * stream,audio_format_t format)91 static int out_set_format(struct audio_stream *stream, audio_format_t format)
92 {
93 return -ENOSYS;
94 }
95
out_standby(struct audio_stream * stream)96 static int out_standby(struct audio_stream *stream)
97 {
98 // out_standby is a no op
99 return 0;
100 }
101
out_dump(const struct audio_stream * stream,int fd)102 static int out_dump(const struct audio_stream *stream, int fd)
103 {
104 struct generic_stream_out *out = (struct generic_stream_out *)stream;
105
106 dprintf(fd, "\tout_dump:\n"
107 "\t\tsample rate: %u\n"
108 "\t\tbuffer size: %u\n"
109 "\t\tchannel mask: %08x\n"
110 "\t\tformat: %d\n"
111 "\t\tdevice: %08x\n"
112 "\t\taudio dev: %p\n\n",
113 out_get_sample_rate(stream),
114 out_get_buffer_size(stream),
115 out_get_channels(stream),
116 out_get_format(stream),
117 out->device,
118 out->dev);
119
120 return 0;
121 }
122
out_set_parameters(struct audio_stream * stream,const char * kvpairs)123 static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
124 {
125 struct generic_stream_out *out = (struct generic_stream_out *)stream;
126 struct str_parms *parms;
127 char value[32];
128 int ret;
129 long val;
130 char *end;
131
132 parms = str_parms_create_str(kvpairs);
133
134 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING,
135 value, sizeof(value));
136 if (ret >= 0) {
137 errno = 0;
138 val = strtol(value, &end, 10);
139 if (errno == 0 && (end != NULL) && (*end == '\0') && ((int)val == val)) {
140 out->device = (int)val;
141 } else {
142 ret = -EINVAL;
143 }
144 }
145
146 str_parms_destroy(parms);
147 return ret;
148 }
149
out_get_parameters(const struct audio_stream * stream,const char * keys)150 static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
151 {
152 struct generic_stream_out *out = (struct generic_stream_out *)stream;
153 struct str_parms *query = str_parms_create_str(keys);
154 char *str;
155 char value[256];
156 struct str_parms *reply = str_parms_create();
157 int ret;
158
159 ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
160 if (ret >= 0) {
161 str_parms_add_int(reply, AUDIO_PARAMETER_STREAM_ROUTING, out->device);
162 str = strdup(str_parms_to_str(reply));
163 } else {
164 str = strdup(keys);
165 }
166
167 str_parms_destroy(query);
168 str_parms_destroy(reply);
169 return str;
170 }
171
out_get_latency(const struct audio_stream_out * stream)172 static uint32_t out_get_latency(const struct audio_stream_out *stream)
173 {
174 return OUT_LATENCY_MS;
175 }
176
out_set_volume(struct audio_stream_out * stream,float left,float right)177 static int out_set_volume(struct audio_stream_out *stream, float left,
178 float right)
179 {
180 return -ENOSYS;
181 }
182
out_write(struct audio_stream_out * stream,const void * buffer,size_t bytes)183 static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
184 size_t bytes)
185 {
186 struct generic_stream_out *out = (struct generic_stream_out *)stream;
187 struct generic_audio_device *adev = out->dev;
188
189 pthread_mutex_lock(&adev->lock);
190 if (adev->fd >= 0)
191 bytes = write(adev->fd, buffer, bytes);
192 pthread_mutex_unlock(&adev->lock);
193
194 return bytes;
195 }
196
out_get_render_position(const struct audio_stream_out * stream,uint32_t * dsp_frames)197 static int out_get_render_position(const struct audio_stream_out *stream,
198 uint32_t *dsp_frames)
199 {
200 return -ENOSYS;
201 }
202
out_add_audio_effect(const struct audio_stream * stream,effect_handle_t effect)203 static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
204 {
205 // out_add_audio_effect is a no op
206 return 0;
207 }
208
out_remove_audio_effect(const struct audio_stream * stream,effect_handle_t effect)209 static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
210 {
211 // out_remove_audio_effect is a no op
212 return 0;
213 }
214
out_get_next_write_timestamp(const struct audio_stream_out * stream,int64_t * timestamp)215 static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
216 int64_t *timestamp)
217 {
218 return -ENOSYS;
219 }
220
221 /** audio_stream_in implementation **/
in_get_sample_rate(const struct audio_stream * stream)222 static uint32_t in_get_sample_rate(const struct audio_stream *stream)
223 {
224 return IN_SAMPLING_RATE;
225 }
226
in_set_sample_rate(struct audio_stream * stream,uint32_t rate)227 static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
228 {
229 return -ENOSYS;
230 }
231
in_get_buffer_size(const struct audio_stream * stream)232 static size_t in_get_buffer_size(const struct audio_stream *stream)
233 {
234 return IN_BUFFER_SIZE;
235 }
236
in_get_channels(const struct audio_stream * stream)237 static audio_channel_mask_t in_get_channels(const struct audio_stream *stream)
238 {
239 return AUDIO_CHANNEL_IN_MONO;
240 }
241
in_get_format(const struct audio_stream * stream)242 static audio_format_t in_get_format(const struct audio_stream *stream)
243 {
244 return AUDIO_FORMAT_PCM_16_BIT;
245 }
246
in_set_format(struct audio_stream * stream,audio_format_t format)247 static int in_set_format(struct audio_stream *stream, audio_format_t format)
248 {
249 return -ENOSYS;
250 }
251
in_standby(struct audio_stream * stream)252 static int in_standby(struct audio_stream *stream)
253 {
254 // in_standby is a no op
255 return 0;
256 }
257
in_dump(const struct audio_stream * stream,int fd)258 static int in_dump(const struct audio_stream *stream, int fd)
259 {
260 struct generic_stream_in *in = (struct generic_stream_in *)stream;
261
262 dprintf(fd, "\tin_dump:\n"
263 "\t\tsample rate: %u\n"
264 "\t\tbuffer size: %u\n"
265 "\t\tchannel mask: %08x\n"
266 "\t\tformat: %d\n"
267 "\t\tdevice: %08x\n"
268 "\t\taudio dev: %p\n\n",
269 in_get_sample_rate(stream),
270 in_get_buffer_size(stream),
271 in_get_channels(stream),
272 in_get_format(stream),
273 in->device,
274 in->dev);
275
276 return 0;
277 }
278
in_set_parameters(struct audio_stream * stream,const char * kvpairs)279 static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
280 {
281 struct generic_stream_in *in = (struct generic_stream_in *)stream;
282 struct str_parms *parms;
283 char value[32];
284 int ret;
285 long val;
286 char *end;
287
288 parms = str_parms_create_str(kvpairs);
289
290 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING,
291 value, sizeof(value));
292 if (ret >= 0) {
293 errno = 0;
294 val = strtol(value, &end, 10);
295 if ((errno == 0) && (end != NULL) && (*end == '\0') && ((int)val == val)) {
296 in->device = (int)val;
297 } else {
298 ret = -EINVAL;
299 }
300 }
301
302 str_parms_destroy(parms);
303 return ret;
304 }
305
in_get_parameters(const struct audio_stream * stream,const char * keys)306 static char * in_get_parameters(const struct audio_stream *stream,
307 const char *keys)
308 {
309 struct generic_stream_in *in = (struct generic_stream_in *)stream;
310 struct str_parms *query = str_parms_create_str(keys);
311 char *str;
312 char value[256];
313 struct str_parms *reply = str_parms_create();
314 int ret;
315
316 ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
317 if (ret >= 0) {
318 str_parms_add_int(reply, AUDIO_PARAMETER_STREAM_ROUTING, in->device);
319 str = strdup(str_parms_to_str(reply));
320 } else {
321 str = strdup(keys);
322 }
323
324 str_parms_destroy(query);
325 str_parms_destroy(reply);
326 return str;
327 }
328
in_set_gain(struct audio_stream_in * stream,float gain)329 static int in_set_gain(struct audio_stream_in *stream, float gain)
330 {
331 // in_set_gain is a no op
332 return 0;
333 }
334
in_read(struct audio_stream_in * stream,void * buffer,size_t bytes)335 static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
336 size_t bytes)
337 {
338 struct generic_stream_in *in = (struct generic_stream_in *)stream;
339 struct generic_audio_device *adev = in->dev;
340
341 pthread_mutex_lock(&adev->lock);
342 if (adev->fd >= 0)
343 bytes = read(adev->fd, buffer, bytes);
344 if (adev->mic_mute && (bytes > 0)) {
345 memset(buffer, 0, bytes);
346 }
347 pthread_mutex_unlock(&adev->lock);
348
349 return bytes;
350 }
351
in_get_input_frames_lost(struct audio_stream_in * stream)352 static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
353 {
354 return 0;
355 }
356
in_add_audio_effect(const struct audio_stream * stream,effect_handle_t effect)357 static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
358 {
359 // in_add_audio_effect is a no op
360 return 0;
361 }
362
in_remove_audio_effect(const struct audio_stream * stream,effect_handle_t effect)363 static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
364 {
365 // in_add_audio_effect is a no op
366 return 0;
367 }
368
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,const char * address __unused)369 static int adev_open_output_stream(struct audio_hw_device *dev,
370 audio_io_handle_t handle,
371 audio_devices_t devices,
372 audio_output_flags_t flags,
373 struct audio_config *config,
374 struct audio_stream_out **stream_out,
375 const char *address __unused)
376 {
377 struct generic_audio_device *adev = (struct generic_audio_device *)dev;
378 struct generic_stream_out *out;
379 int ret = 0;
380
381 pthread_mutex_lock(&adev->lock);
382 if (adev->output != NULL) {
383 ret = -ENOSYS;
384 goto error;
385 }
386
387 if ((config->format != AUDIO_FORMAT_PCM_16_BIT) ||
388 (config->channel_mask != AUDIO_CHANNEL_OUT_STEREO) ||
389 (config->sample_rate != OUT_SAMPLING_RATE)) {
390 ALOGE("Error opening output stream format %d, channel_mask %04x, sample_rate %u",
391 config->format, config->channel_mask, config->sample_rate);
392 config->format = AUDIO_FORMAT_PCM_16_BIT;
393 config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
394 config->sample_rate = OUT_SAMPLING_RATE;
395 ret = -EINVAL;
396 goto error;
397 }
398
399 out = (struct generic_stream_out *)calloc(1, sizeof(struct generic_stream_out));
400
401 out->stream.common.get_sample_rate = out_get_sample_rate;
402 out->stream.common.set_sample_rate = out_set_sample_rate;
403 out->stream.common.get_buffer_size = out_get_buffer_size;
404 out->stream.common.get_channels = out_get_channels;
405 out->stream.common.get_format = out_get_format;
406 out->stream.common.set_format = out_set_format;
407 out->stream.common.standby = out_standby;
408 out->stream.common.dump = out_dump;
409 out->stream.common.set_parameters = out_set_parameters;
410 out->stream.common.get_parameters = out_get_parameters;
411 out->stream.common.add_audio_effect = out_add_audio_effect;
412 out->stream.common.remove_audio_effect = out_remove_audio_effect;
413 out->stream.get_latency = out_get_latency;
414 out->stream.set_volume = out_set_volume;
415 out->stream.write = out_write;
416 out->stream.get_render_position = out_get_render_position;
417 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
418
419 out->dev = adev;
420 out->device = devices;
421 adev->output = (struct audio_stream_out *)out;
422 *stream_out = &out->stream;
423
424 error:
425 pthread_mutex_unlock(&adev->lock);
426
427 return ret;
428 }
429
adev_close_output_stream(struct audio_hw_device * dev,struct audio_stream_out * stream)430 static void adev_close_output_stream(struct audio_hw_device *dev,
431 struct audio_stream_out *stream)
432 {
433 struct generic_audio_device *adev = (struct generic_audio_device *)dev;
434
435 pthread_mutex_lock(&adev->lock);
436 if (stream == adev->output) {
437 free(stream);
438 adev->output = NULL;
439 }
440 pthread_mutex_unlock(&adev->lock);
441 }
442
adev_set_parameters(struct audio_hw_device * dev,const char * kvpairs)443 static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
444 {
445 return 0;
446 }
447
adev_get_parameters(const struct audio_hw_device * dev,const char * keys)448 static char * adev_get_parameters(const struct audio_hw_device *dev,
449 const char *keys)
450 {
451 return strdup("");
452 }
453
adev_init_check(const struct audio_hw_device * dev)454 static int adev_init_check(const struct audio_hw_device *dev)
455 {
456 struct generic_audio_device *adev = (struct generic_audio_device *)dev;
457
458 if (adev->fd >= 0)
459 return 0;
460
461 return -ENODEV;
462 }
463
adev_set_voice_volume(struct audio_hw_device * dev,float volume)464 static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
465 {
466 // adev_set_voice_volume is a no op (simulates phones)
467 return 0;
468 }
469
adev_set_master_volume(struct audio_hw_device * dev,float volume)470 static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
471 {
472 return -ENOSYS;
473 }
474
adev_get_master_volume(struct audio_hw_device * dev,float * volume)475 static int adev_get_master_volume(struct audio_hw_device *dev, float *volume)
476 {
477 return -ENOSYS;
478 }
479
adev_set_master_mute(struct audio_hw_device * dev,bool muted)480 static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
481 {
482 return -ENOSYS;
483 }
484
adev_get_master_mute(struct audio_hw_device * dev,bool * muted)485 static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
486 {
487 return -ENOSYS;
488 }
489
adev_set_mode(struct audio_hw_device * dev,audio_mode_t mode)490 static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
491 {
492 // adev_set_mode is a no op (simulates phones)
493 return 0;
494 }
495
adev_set_mic_mute(struct audio_hw_device * dev,bool state)496 static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
497 {
498 struct generic_audio_device *adev = (struct generic_audio_device *)dev;
499
500 pthread_mutex_lock(&adev->lock);
501 adev->mic_mute = state;
502 pthread_mutex_unlock(&adev->lock);
503 return 0;
504 }
505
adev_get_mic_mute(const struct audio_hw_device * dev,bool * state)506 static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
507 {
508 struct generic_audio_device *adev = (struct generic_audio_device *)dev;
509
510 pthread_mutex_lock(&adev->lock);
511 *state = adev->mic_mute;
512 pthread_mutex_unlock(&adev->lock);
513
514 return 0;
515 }
516
adev_get_input_buffer_size(const struct audio_hw_device * dev,const struct audio_config * config)517 static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
518 const struct audio_config *config)
519 {
520 return IN_BUFFER_SIZE;
521 }
522
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,audio_input_flags_t flags __unused,const char * address __unused,audio_source_t source __unused)523 static int adev_open_input_stream(struct audio_hw_device *dev,
524 audio_io_handle_t handle,
525 audio_devices_t devices,
526 struct audio_config *config,
527 struct audio_stream_in **stream_in,
528 audio_input_flags_t flags __unused,
529 const char *address __unused,
530 audio_source_t source __unused)
531 {
532 struct generic_audio_device *adev = (struct generic_audio_device *)dev;
533 struct generic_stream_in *in;
534 int ret = 0;
535
536 pthread_mutex_lock(&adev->lock);
537 if (adev->input != NULL) {
538 ret = -ENOSYS;
539 goto error;
540 }
541
542 if ((config->format != AUDIO_FORMAT_PCM_16_BIT) ||
543 (config->channel_mask != AUDIO_CHANNEL_IN_MONO) ||
544 (config->sample_rate != IN_SAMPLING_RATE)) {
545 ALOGE("Error opening input stream format %d, channel_mask %04x, sample_rate %u",
546 config->format, config->channel_mask, config->sample_rate);
547 config->format = AUDIO_FORMAT_PCM_16_BIT;
548 config->channel_mask = AUDIO_CHANNEL_IN_MONO;
549 config->sample_rate = IN_SAMPLING_RATE;
550 ret = -EINVAL;
551 goto error;
552 }
553
554 in = (struct generic_stream_in *)calloc(1, sizeof(struct generic_stream_in));
555
556 in->stream.common.get_sample_rate = in_get_sample_rate;
557 in->stream.common.set_sample_rate = in_set_sample_rate;
558 in->stream.common.get_buffer_size = in_get_buffer_size;
559 in->stream.common.get_channels = in_get_channels;
560 in->stream.common.get_format = in_get_format;
561 in->stream.common.set_format = in_set_format;
562 in->stream.common.standby = in_standby;
563 in->stream.common.dump = in_dump;
564 in->stream.common.set_parameters = in_set_parameters;
565 in->stream.common.get_parameters = in_get_parameters;
566 in->stream.common.add_audio_effect = in_add_audio_effect;
567 in->stream.common.remove_audio_effect = in_remove_audio_effect;
568 in->stream.set_gain = in_set_gain;
569 in->stream.read = in_read;
570 in->stream.get_input_frames_lost = in_get_input_frames_lost;
571
572 in->dev = adev;
573 in->device = devices;
574 adev->input = (struct audio_stream_in *)in;
575 *stream_in = &in->stream;
576
577 error:
578 pthread_mutex_unlock(&adev->lock);
579
580 return ret;
581 }
582
adev_close_input_stream(struct audio_hw_device * dev,struct audio_stream_in * stream)583 static void adev_close_input_stream(struct audio_hw_device *dev,
584 struct audio_stream_in *stream)
585 {
586 struct generic_audio_device *adev = (struct generic_audio_device *)dev;
587
588 pthread_mutex_lock(&adev->lock);
589 if (stream == adev->input) {
590 free(stream);
591 adev->input = NULL;
592 }
593 pthread_mutex_unlock(&adev->lock);
594 }
595
adev_dump(const audio_hw_device_t * dev,int fd)596 static int adev_dump(const audio_hw_device_t *dev, int fd)
597 {
598 struct generic_audio_device *adev = (struct generic_audio_device *)dev;
599
600 const size_t SIZE = 256;
601 char buffer[SIZE];
602
603 dprintf(fd, "\nadev_dump:\n"
604 "\tfd: %d\n"
605 "\tmic_mute: %s\n"
606 "\toutput: %p\n"
607 "\tinput: %p\n\n",
608 adev->fd,
609 adev->mic_mute ? "true": "false",
610 adev->output,
611 adev->input);
612
613 if (adev->output != NULL)
614 out_dump((const struct audio_stream *)adev->output, fd);
615 if (adev->input != NULL)
616 in_dump((const struct audio_stream *)adev->input, fd);
617
618 return 0;
619 }
620
adev_close(hw_device_t * dev)621 static int adev_close(hw_device_t *dev)
622 {
623 struct generic_audio_device *adev = (struct generic_audio_device *)dev;
624
625 adev_close_output_stream((struct audio_hw_device *)dev, adev->output);
626 adev_close_input_stream((struct audio_hw_device *)dev, adev->input);
627
628 if (adev->fd >= 0)
629 close(adev->fd);
630
631 free(dev);
632 return 0;
633 }
634
adev_open(const hw_module_t * module,const char * name,hw_device_t ** device)635 static int adev_open(const hw_module_t* module, const char* name,
636 hw_device_t** device)
637 {
638 struct generic_audio_device *adev;
639 int fd;
640
641 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
642 return -EINVAL;
643
644 fd = open(AUDIO_DEVICE_NAME, O_RDWR);
645 if (fd < 0)
646 return -ENOSYS;
647
648 adev = calloc(1, sizeof(struct generic_audio_device));
649
650 adev->fd = fd;
651
652 adev->device.common.tag = HARDWARE_DEVICE_TAG;
653 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
654 adev->device.common.module = (struct hw_module_t *) module;
655 adev->device.common.close = adev_close;
656
657 adev->device.init_check = adev_init_check;
658 adev->device.set_voice_volume = adev_set_voice_volume;
659 adev->device.set_master_volume = adev_set_master_volume;
660 adev->device.get_master_volume = adev_get_master_volume;
661 adev->device.set_master_mute = adev_set_master_mute;
662 adev->device.get_master_mute = adev_get_master_mute;
663 adev->device.set_mode = adev_set_mode;
664 adev->device.set_mic_mute = adev_set_mic_mute;
665 adev->device.get_mic_mute = adev_get_mic_mute;
666 adev->device.set_parameters = adev_set_parameters;
667 adev->device.get_parameters = adev_get_parameters;
668 adev->device.get_input_buffer_size = adev_get_input_buffer_size;
669 adev->device.open_output_stream = adev_open_output_stream;
670 adev->device.close_output_stream = adev_close_output_stream;
671 adev->device.open_input_stream = adev_open_input_stream;
672 adev->device.close_input_stream = adev_close_input_stream;
673 adev->device.dump = adev_dump;
674
675 *device = &adev->device.common;
676
677 return 0;
678 }
679
680 static struct hw_module_methods_t hal_module_methods = {
681 .open = adev_open,
682 };
683
684 struct audio_module HAL_MODULE_INFO_SYM = {
685 .common = {
686 .tag = HARDWARE_MODULE_TAG,
687 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
688 .hal_api_version = HARDWARE_HAL_API_VERSION,
689 .id = AUDIO_HARDWARE_MODULE_ID,
690 .name = "Generic audio HW HAL",
691 .author = "The Android Open Source Project",
692 .methods = &hal_module_methods,
693 },
694 };
695