• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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