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