AudioHardware.cpp revision a3a947cc7e1bfaf7b5cfc85b71f602edf562836d
1/*
2** Copyright 2008, Google Inc.
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#include <math.h>
18
19// #define LOG_NDEBUG 0
20#define LOG_TAG "AudioHardwareMSM72XX"
21#include <utils/Log.h>
22#include <utils/String8.h>
23
24#include <stdio.h>
25#include <unistd.h>
26#include <sys/ioctl.h>
27#include <sys/types.h>
28#include <sys/stat.h>
29#include <dlfcn.h>
30#include <fcntl.h>
31
32// hardware specific functions
33
34#include "BluetoothHeadsetTable.h"
35#include "AudioHardware.h"
36
37#define LOG_SND_RPC 0  // Set to 1 to log sound RPC's
38
39namespace android {
40
41/* When this macro is non-zero, we initialize playback and recording
42 * only once--when we construct the AudioHardwareMSM72xx class--and
43 * deinitialize them in this class' destructor.  When the macro is
44 * set to zero, we initialize playback and recording before we start
45 * the respective operation, and deinitialize them after we stop that
46 * operation.
47 */
48#define INIT_AUDIO_ONCE (0)
49static int get_audpp_filter(void);
50static int msm72xx_enable_audpp(uint16_t enable_mask);
51
52static uint16_t adrc_flag;
53static uint16_t eq_flag;
54static uint16_t rx_iir_flag;
55static bool audpp_filter_inited = false;
56
57// ----------------------------------------------------------------------------
58
59AudioHardware::AudioHardware() :
60    mInit(false), mStandby(false), mOutputStandby(true),
61    mMicMute(true), mBluetoothNrec(true), mBluetoothId(0), mOutput(0),
62    mInput(0), mSndEndpoints(NULL),
63    SND_DEVICE_CURRENT(-1),
64    SND_DEVICE_HANDSET(-1),
65    SND_DEVICE_SPEAKER(-1),
66    SND_DEVICE_BT(-1),
67    SND_DEVICE_BT_EC_OFF(-1),
68    SND_DEVICE_HEADSET(-1),
69    SND_DEVICE_HEADSET_AND_SPEAKER(-1)
70{
71    if (get_audpp_filter() == 0)
72        audpp_filter_inited = true;
73
74#if INIT_AUDIO_ONCE
75    if (msm72xx_init_record())
76        LOGE("msm72xx_init_record failed");
77    else
78#endif
79    {
80        int fd = open("/dev/msm_snd", O_RDWR);
81        if (fd >= 0) {
82            int rc = ioctl(fd, SND_GET_ENDPOINTS, NULL);
83            rc /= sizeof(snd_endpoint);
84            if (rc >= 0) {
85                mSndEndpoints = new snd_endpoint[rc];
86                mNumSndEndpoints = rc;
87                LOGI("++++ NUMBER OF ENDPOINTS: %d", rc);
88                if (ioctl(fd, SND_GET_ENDPOINTS, mSndEndpoints) < 0) {
89                    LOGE("Could not retrieve MSM SND endpoints.");
90                }
91                else {
92                    mInit = true;
93                    LOGV("constructed");
94                    struct snd_endpoint *ept = mSndEndpoints;
95                    for (int cnt = 0; cnt < mNumSndEndpoints; cnt++, ept++) {
96                        LOGI("[%s] [%d]", ept->name, ept->id);
97#define CHECK_FOR(desc) \
98do { \
99    if (!strcmp(ept->name, #desc)) { \
100        LOGI("++++ [%s] [%d] HIT", ept->name, ept->id); \
101        SND_DEVICE_##desc = ept->id; \
102    } \
103} while(0)
104                        CHECK_FOR(CURRENT);
105                        CHECK_FOR(HANDSET);
106                        CHECK_FOR(SPEAKER);
107                        CHECK_FOR(BT);
108                        CHECK_FOR(BT_EC_OFF);
109                        CHECK_FOR(HEADSET);
110                        CHECK_FOR(HEADSET_AND_SPEAKER);
111#undef CHECK_FOR
112                        mBluetoothId = 0;
113                        for (unsigned hs = 0;
114                                 hs < sizeof(KNOWN_HEADSETS) /
115                                      sizeof(KNOWN_HEADSETS[0]);
116                                 hs++) {
117                            if (KNOWN_HEADSETS[hs].id < 0 &&
118                                    !strcmp(ept->name,
119                                            KNOWN_HEADSETS[hs].probe)) {
120                                LOGI("++BT [%s] [%d] HIT", ept->name, ept->id);
121                                KNOWN_HEADSETS[hs].id = ept->id;
122                            }
123                        }
124                    }
125                }
126            }
127            else LOGE("Could not retrieve number of MSM SND endpoints.");
128            close(fd);
129        }
130        else LOGE("Could not open MSM SND driver.");
131    }
132}
133
134AudioHardware::~AudioHardware()
135{
136    delete mInput;
137    delete mOutput;
138    delete [] mSndEndpoints;
139
140#if INIT_AUDIO_ONCE
141    msm72xx_deinit_record();
142#endif
143    mInit = false;
144}
145
146status_t AudioHardware::initCheck()
147{
148    return mInit ? NO_ERROR : NO_INIT;
149}
150
151AudioStreamOut* AudioHardware::openOutputStream(
152        int format, int channelCount, uint32_t sampleRate)
153{
154    Mutex::Autolock lock(mLock);
155
156    // only one output stream allowed
157    if (mOutput) return 0;
158
159    // create new output stream
160    AudioStreamOutMSM72xx* out = new AudioStreamOutMSM72xx();
161    if (out->set(this, format, channelCount, sampleRate) == NO_ERROR) {
162        mOutput = out;
163        standby_nosync();
164    } else {
165        delete out;
166    }
167    return mOutput;
168}
169
170void AudioHardware::closeOutputStream(AudioStreamOutMSM72xx* out) {
171    Mutex::Autolock lock(mLock);
172    if (mOutput != out) {
173        LOGW("Attempt to close invalid output stream");
174    }
175    else {
176        mOutput = 0;
177    }
178}
179
180AudioStreamIn* AudioHardware::openInputStream(
181        int format, int channelCount, uint32_t sampleRate)
182{
183    Mutex::Autolock lock(mLock);
184
185    // input stream already open?
186    if (mInput) return 0;
187
188    AudioStreamInMSM72xx* in = new AudioStreamInMSM72xx();
189    if (in->set(this, format, channelCount, sampleRate) != NO_ERROR) {
190        delete in;
191        return 0;
192    }
193
194    mInput = in;
195    return mInput;
196}
197
198void AudioHardware::closeInputStream(AudioStreamInMSM72xx* in) {
199    Mutex::Autolock lock(mLock);
200    if (mInput != in) {
201        LOGW("Attempt to close invalid input stream");
202    }
203    else {
204        mInput = 0;
205    }
206}
207
208// always call this with mutex held
209status_t AudioHardware::standby_nosync()
210{
211    if (mStandby == false) {
212        LOGD("Going to standby");
213        mStandby = true;
214        return mOutput->standby();
215    }
216    return NO_ERROR;
217}
218
219// always call with mutex held
220status_t AudioHardware::checkStandby()
221{
222    // don't go into standby if audio is active
223    if (!mOutputStandby) return NO_ERROR;
224    return standby_nosync();
225}
226
227status_t AudioHardware::standby()
228{
229    Mutex::Autolock lock(mLock);
230    mOutputStandby = true;
231    return checkStandby();
232}
233
234status_t AudioHardware::setMicMute(bool state)
235{
236    Mutex::Autolock lock(mLock);
237    return setMicMute_nosync(state);
238}
239
240// always call with mutex held
241status_t AudioHardware::setMicMute_nosync(bool state)
242{
243    if (mMicMute != state) {
244        mMicMute = state;
245        return doAudioRouteOrMute(SND_DEVICE_CURRENT);
246    }
247    return NO_ERROR;
248}
249
250status_t AudioHardware::getMicMute(bool* state)
251{
252    *state = mMicMute;
253    return NO_ERROR;
254}
255
256status_t AudioHardware::setParameter(const char *key, const char *value)
257{
258    LOGV("%s key = %s value = %s\n", __FUNCTION__, key, value);
259
260    if (key == NULL || value == NULL) {
261        LOGE("%s called with null argument, ignoring (key = %s, value = %s",
262             __FUNCTION__, key, value);
263        return BAD_VALUE;
264    }
265
266    const char BT_NREC_KEY[] = "bt_headset_nrec";
267    const char BT_NAME_KEY[] = "bt_headset_name";
268    const char BT_NREC_VALUE_ON[] = "on";
269
270    if (!strncmp(key, BT_NREC_KEY, sizeof(BT_NREC_KEY))) {
271        if (!strncmp(value, BT_NREC_VALUE_ON, sizeof(BT_NREC_VALUE_ON))) {
272            mBluetoothNrec = true;
273        } else {
274            mBluetoothNrec = false;
275            LOGI("Turning noise reduction and echo cancellation off for BT "
276                 "headset");
277        }
278        doRouting();
279    } else if (!strncmp(key, BT_NAME_KEY, sizeof(BT_NAME_KEY))) {
280        mBluetoothId = 0;
281        for (uint32_t i = 0; i < sizeof(KNOWN_HEADSETS) / sizeof(KNOWN_HEADSETS[0]);
282                i++) {
283            if (!strncasecmp(value, KNOWN_HEADSETS[i].name,
284                             sizeof(KNOWN_HEADSETS[i].name)) &&
285                KNOWN_HEADSETS[i].id >= 0) {
286                mBluetoothId = KNOWN_HEADSETS[i].id;
287                LOGI("Using custom acoustic parameters for %s", value);
288                break;
289            }
290        }
291        if (mBluetoothId == 0) {
292            LOGI("Using default acoustic parameters "
293                 "(%s not in acoustic database)", value);
294            doRouting();
295        }
296    }
297
298    return NO_ERROR;
299}
300
301int check_and_set_audpp_parameters(char *buf, int size)
302{
303    char *p, *ps;
304    static const char *const seps = ",";
305    int table_num;
306    int i, j;
307    uint16_t adrc_filter[8];
308    eq_filter_type eq[12];
309    rx_iir_filter iir_cfg;
310    eqalizer eqalizer;
311    int fd;
312    void *audioeq;
313    void *(*eq_cal)(int32_t, int32_t, int32_t, uint16_t, int32_t, int32_t *, int32_t *, uint16_t *);
314    uint16_t numerator[6];
315    uint16_t denominator[4];
316    uint16_t shift[2];
317
318    fd = open("/dev/msm_pcm_ctl", O_RDWR);
319    if (fd < 0) {
320        LOGE("Cannot open audio device");
321        return -EPERM;
322    }
323    if (buf[0] == 'A' && buf[1] == '1') {
324        /* IIR filter */
325	if (!(p = strtok(buf, ",")))
326            goto token_err;
327
328	/* Table header */
329        table_num = strtol(p + 1, &ps, 10);
330        if (!(p = strtok(NULL, seps)))
331            goto token_err;
332    	/* Table description */
333    	if (!(p = strtok(NULL, seps)))
334            goto token_err;
335
336	for (i = 0; i < 48; i++) {
337	    j = (i >= 40)? i : ((i % 2)? (i - 1) : (i + 1));
338            iir_cfg.iir_params[j] = (uint16_t)strtol(p, &ps, 16);
339	    if (!(p = strtok(NULL, seps)))
340                goto token_err;
341        }
342        rx_iir_flag = (uint16_t)strtol(p, &ps, 16);
343	if (!(p = strtok(NULL, seps)))
344            goto token_err;
345	iir_cfg.num_bands = (uint16_t)strtol(p, &ps, 16);
346
347        if (ioctl(fd, AUDIO_SET_RX_IIR, &iir_cfg) < 0) {
348            LOGE("set rx iir filter error.");
349            return -EIO;
350        }
351    } else if (buf[0] == 'B' && buf[1] == '1') {
352        /* This is the ADRC record we are looking for.  Tokenize it */
353        if (!(p = strtok(buf, ",")))
354            goto token_err;
355
356        /* Table header */
357        table_num = strtol(p + 1, &ps, 10);
358        if (!(p = strtok(NULL, seps)))
359            goto token_err;
360
361        /* Table description */
362        if (!(p = strtok(NULL, seps)))
363            goto token_err;
364        adrc_flag = (uint16_t)strtol(p, &ps, 16);
365
366        if (!(p = strtok(NULL, seps)))
367            goto token_err;
368        adrc_filter[0] = (uint16_t)strtol(p, &ps, 16);
369
370        if (!(p = strtok(NULL, seps)))
371            goto token_err;
372        adrc_filter[1] = (uint16_t)strtol(p, &ps, 16);
373
374        if (!(p = strtok(NULL, seps)))
375            goto token_err;
376        adrc_filter[2] = (uint16_t)strtol(p, &ps, 16);
377
378        if (!(p = strtok(NULL, seps)))
379            goto token_err;
380        adrc_filter[3] = (uint16_t)strtol(p, &ps, 16);
381
382        if (!(p = strtok(NULL, seps)))
383            goto token_err;
384        adrc_filter[4] = (uint16_t)strtol(p, &ps, 16);
385
386        if (!(p = strtok(NULL, seps)))
387            goto token_err;
388        adrc_filter[5] = (uint16_t)strtol(p, &ps, 16);
389
390        if (!(p = strtok(NULL, seps)))
391            goto token_err;
392        adrc_filter[6] = (uint16_t)strtol(p, &ps, 16);
393
394        if (!(p = strtok(NULL, seps)))
395            goto token_err;
396        adrc_filter[7] = (uint16_t)strtol(p, &ps, 16);
397
398        if (!(p = strtok(NULL, seps)))
399            goto token_err;
400
401        LOGI("ADRC Filter ADRC FLAG = %02x.", adrc_flag);
402        LOGI("ADRC Filter COMP THRESHOLD = %02x.", adrc_filter[0]);
403        LOGI("ADRC Filter COMP SLOPE = %02x.", adrc_filter[1]);
404        LOGI("ADRC Filter COMP RMS TIME = %02x.", adrc_filter[2]);
405        LOGI("ADRC Filter COMP ATTACK[0] = %02x.", adrc_filter[3]);
406        LOGI("ADRC Filter COMP ATTACK[1] = %02x.", adrc_filter[4]);
407        LOGI("ADRC Filter COMP RELEASE[0] = %02x.", adrc_filter[5]);
408        LOGI("ADRC Filter COMP RELEASE[1] = %02x.", adrc_filter[6]);
409        LOGI("ADRC Filter COMP DELAY = %02x.", adrc_filter[7]);
410
411        if (ioctl(fd, AUDIO_SET_ADRC, &adrc_filter) < 0) {
412            LOGE("set adrc filter error.");
413            return -EIO;
414        }
415    } else if (buf[0] == 'C' && buf[1] == '1') {
416        /* This is the EQ record we are looking for.  Tokenize it */
417        if (!(p = strtok(buf, ",")))
418            goto token_err;
419
420        /* Table header */
421        table_num = strtol(p + 1, &ps, 10);
422        if (!(p = strtok(NULL, seps)))
423            goto token_err;
424        /* Table description */
425        if (!(p = strtok(NULL, seps)))
426            goto token_err;
427
428        eq_flag = (uint16_t)strtol(p, &ps, 16);
429        if (!(p = strtok(NULL, seps)))
430            goto token_err;
431        LOGI("EQ flag = %02x.", eq_flag);
432
433        audioeq = ::dlopen("/system/lib/libaudioeq.so", RTLD_NOW);
434        if (audioeq == NULL) {
435            LOGE("audioeq library open failure");
436            return -1;
437        }
438        eq_cal = (void *(*) (int32_t, int32_t, int32_t, uint16_t, int32_t, int32_t *, int32_t *, uint16_t *))::dlsym(audioeq, "audioeq_calccoefs");
439        memset(&eqalizer, 0, sizeof(eqalizer));
440        /* Temp add the bands here */
441        eqalizer.bands = 8;
442        for (i = 0; i < eqalizer.bands; i++) {
443
444            eq[i].gain = (uint16_t)strtol(p, &ps, 16);
445
446            if (!(p = strtok(NULL, seps)))
447                goto token_err;
448            eq[i].freq = (uint16_t)strtol(p, &ps, 16);
449
450            if (!(p = strtok(NULL, seps)))
451                goto token_err;
452            eq[i].type = (uint16_t)strtol(p, &ps, 16);
453
454            if (!(p = strtok(NULL, seps)))
455                goto token_err;
456            eq[i].qf = (uint16_t)strtol(p, &ps, 16);
457
458            if (!(p = strtok(NULL, seps)))
459                goto token_err;
460            //LOGI("gain[%d] = %d", i, eq[i].gain);
461            //LOGI("freq[%d] = %d", i, eq[i].freq);
462            //LOGI("type[%d] = %d", i, eq[i].type);
463            //LOGI("  qf[%d] = %d", i, eq[i].qf);
464            eq_cal(eq[i].gain, eq[i].freq, 48000, eq[i].type, eq[i].qf, (int32_t*)numerator, (int32_t *)denominator, shift);
465            for (j = 0; j < 6; j++) {
466                eqalizer.params[ ( i * 6) + j] = numerator[j];
467            }
468            for (j = 0; j < 4; j++) {
469                eqalizer.params[(eqalizer.bands * 6) + (i * 4) + j] = denominator[j];
470            }
471            eqalizer.params[(eqalizer.bands * 10) + i] = shift[0];
472        }
473        ::dlclose(audioeq);
474
475        if (ioctl(fd, AUDIO_SET_EQ, &eqalizer) < 0) {
476            LOGE("set Equalizer error.");
477            return -EIO;
478        }
479    }
480    close(fd);
481    return 0;
482
483token_err:
484    LOGE("malformatted pcm control buffer");
485    return -EINVAL;
486}
487
488static int get_audpp_filter(void)
489{
490    struct stat st;
491    char *read_buf;
492    char *next_str, *current_str;
493    int csvfd;
494
495    LOGI("get_audpp_filter");
496    static const char *const path =
497        "/system/etc/AudioFilter.csv";
498    csvfd = open(path, O_RDONLY);
499    if (csvfd < 0) {
500        /* failed to open normal acoustic file ... */
501        LOGE("failed to open AUDIO_NORMAL_FILTER %s: %s (%d).",
502             path, strerror(errno), errno);
503        return -1;
504    } else LOGI("open %s success.", path);
505
506    if (fstat(csvfd, &st) < 0) {
507        LOGE("failed to stat %s: %s (%d).",
508             path, strerror(errno), errno);
509        close(csvfd);
510        return -1;
511    }
512
513    read_buf = (char *) mmap(0, st.st_size,
514                    PROT_READ | PROT_WRITE,
515                    MAP_PRIVATE,
516                    csvfd, 0);
517
518    if (read_buf == MAP_FAILED) {
519        LOGE("failed to mmap parameters file: %s (%d)",
520             strerror(errno), errno);
521        close(csvfd);
522        return -1;
523    }
524
525    current_str = read_buf;
526
527    while (1) {
528        int len;
529        next_str = strchr(current_str, '\n');
530        if (!next_str)
531           break;
532        len = next_str - current_str;
533        *next_str++ = '\0';
534        if (check_and_set_audpp_parameters(current_str, len)) {
535            LOGI("failed to set audpp parameters, exiting.");
536            munmap(read_buf, st.st_size);
537	    close(csvfd);
538	    return -1;
539        }
540        current_str = next_str;
541    }
542
543    munmap(read_buf, st.st_size);
544    close(csvfd);
545    return 0;
546}
547
548static int msm72xx_enable_audpp(uint16_t enable_mask)
549{
550    int fd;
551
552    if (!audpp_filter_inited) return -EINVAL;
553
554    fd = open("/dev/msm_pcm_ctl", O_RDWR);
555    if (fd < 0) {
556        LOGE("Cannot open audio device");
557        return -EPERM;
558    }
559
560    if (adrc_flag == 0 && (enable_mask & ADRC_ENABLE))
561       	enable_mask &= ~ADRC_ENABLE;
562    if (eq_flag == 0 && (enable_mask & EQ_ENABLE))
563	enable_mask &= ~EQ_ENABLE;
564    if (rx_iir_flag == 0 && (enable_mask & IIR_ENABLE))
565        enable_mask &= ~IIR_ENABLE;
566
567    LOGD("msm72xx_enable_audpp: 0x%04x", enable_mask);
568    if (ioctl(fd, AUDIO_ENABLE_AUDPP, &enable_mask) < 0) {
569        LOGE("enable audpp error");
570        close(fd);
571        return -EPERM;
572    }
573
574    close(fd);
575    return 0;
576}
577
578static status_t set_volume_rpc(uint32_t device,
579                               uint32_t method,
580                               uint32_t volume)
581{
582    int fd;
583#if LOG_SND_RPC
584    LOGD("rpc_snd_set_volume(%d, %d, %d)\n", device, method, volume);
585#endif
586
587    if (device == -1UL) return NO_ERROR;
588
589    fd = open("/dev/msm_snd", O_RDWR);
590    if (fd < 0) {
591        LOGE("Can not open snd device");
592        return -EPERM;
593    }
594    /* rpc_snd_set_volume(
595     *     device,            # Any hardware device enum, including
596     *                        # SND_DEVICE_CURRENT
597     *     method,            # must be SND_METHOD_VOICE to do anything useful
598     *     volume,            # integer volume level, in range [0,5].
599     *                        # note that 0 is audible (not quite muted)
600     *  )
601     * rpc_snd_set_volume only works for in-call sound volume.
602     */
603    struct snd_volume_config args;
604    args.device = device;
605    args.method = method;
606    args.volume = volume;
607
608    if (ioctl(fd, SND_SET_VOLUME, &args) < 0) {
609        LOGE("snd_set_volume error.");
610        close(fd);
611        return -EIO;
612    }
613
614    close(fd);
615    return NO_ERROR;
616}
617
618status_t AudioHardware::setVoiceVolume(float v)
619{
620    if (v < 0.0) {
621        LOGW("setVoiceVolume(%f) under 0.0, assuming 0.0\n", v);
622        v = 0.0;
623    } else if (v > 1.0) {
624        LOGW("setVoiceVolume(%f) over 1.0, assuming 1.0\n", v);
625        v = 1.0;
626    }
627
628    int vol = lrint(v * 5.0);
629    LOGD("setVoiceVolume(%f)\n", v);
630    LOGI("Setting in-call volume to %d (available range is 0 to 5)\n", vol);
631
632    set_volume_rpc(SND_DEVICE_CURRENT, SND_METHOD_VOICE, vol);
633    return NO_ERROR;
634}
635
636status_t AudioHardware::setMasterVolume(float v)
637{
638    Mutex::Autolock lock(mLock);
639    int vol = ceil(v * 5.0);
640    LOGI("Set master volume to %d.\n", vol);
641
642    set_volume_rpc(SND_DEVICE_HANDSET, SND_METHOD_VOICE, vol);
643    set_volume_rpc(SND_DEVICE_SPEAKER, SND_METHOD_VOICE, vol);
644    set_volume_rpc(SND_DEVICE_BT,      SND_METHOD_VOICE, vol);
645    set_volume_rpc(SND_DEVICE_HEADSET, SND_METHOD_VOICE, vol);
646    // We return an error code here to let the audioflinger do in-software
647    // volume on top of the maximum volume that we set through the SND API.
648    // return error - software mixer will handle it
649    return -1;
650}
651
652static status_t do_route_audio_rpc(uint32_t device,
653                                   bool ear_mute, bool mic_mute)
654{
655    if (device == -1UL)
656        return NO_ERROR;
657
658    int fd;
659#if LOG_SND_RPC
660    LOGD("rpc_snd_set_device(%d, %d, %d)\n", device, ear_mute, mic_mute);
661#endif
662
663    fd = open("/dev/msm_snd", O_RDWR);
664    if (fd < 0) {
665        LOGE("Can not open snd device");
666        return -EPERM;
667    }
668    // RPC call to switch audio path
669    /* rpc_snd_set_device(
670     *     device,            # Hardware device enum to use
671     *     ear_mute,          # Set mute for outgoing voice audio
672     *                        # this should only be unmuted when in-call
673     *     mic_mute,          # Set mute for incoming voice audio
674     *                        # this should only be unmuted when in-call or
675     *                        # recording.
676     *  )
677     */
678    struct snd_device_config args;
679    args.device = device;
680    args.ear_mute = ear_mute ? SND_MUTE_MUTED : SND_MUTE_UNMUTED;
681    args.mic_mute = mic_mute ? SND_MUTE_MUTED : SND_MUTE_UNMUTED;
682
683    if (ioctl(fd, SND_SET_DEVICE, &args) < 0) {
684        LOGE("snd_set_device error.");
685        close(fd);
686        return -EIO;
687    }
688
689    close(fd);
690    return NO_ERROR;
691}
692
693// always call with mutex held
694status_t AudioHardware::doAudioRouteOrMute(uint32_t device)
695{
696    if (device == (uint32_t)SND_DEVICE_BT) {
697        if (mBluetoothId) {
698            device = mBluetoothId;
699        } else if (!mBluetoothNrec) {
700            device = SND_DEVICE_BT_EC_OFF;
701        }
702    }
703    return do_route_audio_rpc(device,
704            mMode != AudioSystem::MODE_IN_CALL, mMicMute);
705}
706
707static int count_bits(uint32_t vector)
708{
709    int bits;
710    for (bits = 0; vector; bits++) {
711        vector &= vector - 1;
712    }
713    return bits;
714}
715
716status_t AudioHardware::doRouting()
717{
718    Mutex::Autolock lock(mLock);
719    uint32_t routes = mRoutes[mMode];
720    if (count_bits(routes) > 1) {
721        if (routes !=
722                (AudioSystem::ROUTE_HEADSET | AudioSystem::ROUTE_SPEAKER)) {
723            LOGW("Hardware does not support requested route combination (%#X),"
724                 " picking closest possible route...", routes);
725        }
726    }
727
728    status_t ret = NO_ERROR;
729    if (routes & AudioSystem::ROUTE_BLUETOOTH) {
730        LOGI("Routing audio to Bluetooth PCM\n");
731        ret = doAudioRouteOrMute(SND_DEVICE_BT);
732        msm72xx_enable_audpp(ADRC_DISABLE | EQ_DISABLE | IIR_DISABLE);
733    } else if ((routes & AudioSystem::ROUTE_HEADSET) &&
734               (routes & AudioSystem::ROUTE_SPEAKER)) {
735        LOGI("Routing audio to Wired Headset and Speaker\n");
736        ret = doAudioRouteOrMute(SND_DEVICE_HEADSET_AND_SPEAKER);
737        msm72xx_enable_audpp(ADRC_ENABLE | EQ_ENABLE | IIR_ENABLE);
738    } else if (routes & AudioSystem::ROUTE_HEADSET) {
739        LOGI("Routing audio to Wired Headset\n");
740        ret = doAudioRouteOrMute(SND_DEVICE_HEADSET);
741        msm72xx_enable_audpp(ADRC_DISABLE | EQ_DISABLE | IIR_DISABLE);
742    } else if (routes & AudioSystem::ROUTE_SPEAKER) {
743        LOGI("Routing audio to Speakerphone\n");
744        ret = doAudioRouteOrMute(SND_DEVICE_SPEAKER);
745        msm72xx_enable_audpp(ADRC_ENABLE | EQ_ENABLE | IIR_ENABLE);
746    } else {
747        LOGI("Routing audio to Handset\n");
748        ret = doAudioRouteOrMute(SND_DEVICE_HANDSET);
749        msm72xx_enable_audpp(ADRC_DISABLE | EQ_DISABLE | IIR_DISABLE);
750    }
751
752    // check for standby
753    checkStandby();
754
755    return ret;
756}
757
758status_t AudioHardware::checkMicMute()
759{
760    Mutex::Autolock lock(mLock);
761    if (mMode != AudioSystem::MODE_IN_CALL) {
762        setMicMute_nosync(true);
763    }
764
765    return NO_ERROR;
766}
767
768status_t AudioHardware::dumpInternals(int fd, const Vector<String16>& args)
769{
770    const size_t SIZE = 256;
771    char buffer[SIZE];
772    String8 result;
773    result.append("AudioHardware::dumpInternals\n");
774    snprintf(buffer, SIZE, "\tmInit: %s\n", mInit? "true": "false");
775    result.append(buffer);
776    snprintf(buffer, SIZE, "\tmStandby: %s\n", mStandby? "true": "false");
777    result.append(buffer);
778    snprintf(buffer, SIZE, "\tmOutputStandby: %s\n", mOutputStandby? "true": "false");
779    result.append(buffer);
780    snprintf(buffer, SIZE, "\tmMicMute: %s\n", mMicMute? "true": "false");
781    result.append(buffer);
782    snprintf(buffer, SIZE, "\tmBluetoothNrec: %s\n", mBluetoothNrec? "true": "false");
783    result.append(buffer);
784    snprintf(buffer, SIZE, "\tmBluetoothId: %d\n", mBluetoothId);
785    result.append(buffer);
786    ::write(fd, result.string(), result.size());
787    return NO_ERROR;
788}
789
790status_t AudioHardware::dump(int fd, const Vector<String16>& args)
791{
792    dumpInternals(fd, args);
793    if (mInput) {
794        mInput->dump(fd, args);
795    }
796    if (mOutput) {
797        mOutput->dump(fd, args);
798    }
799    return NO_ERROR;
800}
801
802// ----------------------------------------------------------------------------
803
804AudioHardware::AudioStreamOutMSM72xx::AudioStreamOutMSM72xx() :
805    mHardware(0), mFd(-1), mStartCount(0), mRetryCount(0)
806{
807}
808
809status_t AudioHardware::AudioStreamOutMSM72xx::set(
810        AudioHardware* hw, int format, int channels, uint32_t rate)
811{
812    // fix up defaults
813    if (format == 0) format = AudioSystem::PCM_16_BIT;
814    if (channels == 0) channels = channelCount();
815    if (rate == 0) rate = sampleRate();
816
817    // check values
818    if ((format != AudioSystem::PCM_16_BIT) ||
819            (channels != channelCount()) ||
820            (rate != sampleRate()))
821        return BAD_VALUE;
822
823    mHardware = hw;
824
825    return NO_ERROR;
826}
827
828AudioHardware::AudioStreamOutMSM72xx::~AudioStreamOutMSM72xx()
829{
830    if (!mHardware->mStandby) {
831        if (mFd > 0) close(mFd);
832    }
833    mHardware->closeOutputStream(this);
834}
835
836ssize_t AudioHardware::AudioStreamOutMSM72xx::write(const void* buffer, size_t bytes)
837{
838    // LOGD("AudioStreamOutMSM72xx::write(%p, %u)", buffer, bytes);
839    status_t status = NO_INIT;
840    size_t count = bytes;
841    const uint8_t* p = static_cast<const uint8_t*>(buffer);
842
843    mHardware->mOutputStandby = false;
844    if (mHardware->mStandby) {
845
846        // open driver
847        LOGV("open driver");
848        status = ::open("/dev/msm_pcm_out", O_RDWR);
849        if (status < 0) {
850            LOGE("Cannot open audio device");
851            goto Error;
852        }
853        mFd = status;
854
855        // configuration
856        LOGV("get config");
857        struct msm_audio_config config;
858        status = ioctl(mFd, AUDIO_GET_CONFIG, &config);
859        if (status < 0) {
860            LOGE("Cannot read config");
861            goto Error;
862        }
863
864        LOGV("set config");
865        config.channel_count = channelCount();
866        config.sample_rate = sampleRate();
867        config.buffer_size = bufferSize();
868        config.buffer_count = 2;
869        config.codec_type = CODEC_TYPE_PCM;
870        status = ioctl(mFd, AUDIO_SET_CONFIG, &config);
871        if (status < 0) {
872            LOGE("Cannot set config");
873            goto Error;
874        }
875
876        LOGV("buffer_size: %u", config.buffer_size);
877        LOGV("buffer_count: %u", config.buffer_count);
878        LOGV("channel_count: %u", config.channel_count);
879        LOGV("sample_rate: %u", config.sample_rate);
880
881        // fill 2 buffers before AUDIO_START
882        mStartCount = 2;
883        mHardware->mStandby = false;
884    }
885
886    while (count) {
887        ssize_t written = ::write(mFd, p, count);
888        if (written >= 0) {
889            count -= written;
890            p += written;
891        } else {
892            if (errno != EAGAIN) return written;
893            mRetryCount++;
894            LOGW("EAGAIN - retry");
895        }
896    }
897
898    // start audio after we fill 2 buffers
899    if (mStartCount) {
900        if (--mStartCount == 0) {
901            ioctl(mFd, AUDIO_START, 0);
902        }
903    }
904    return bytes;
905
906Error:
907    if (mFd > 0) {
908        ::close(mFd);
909        mFd = -1;
910    }
911    // Simulate audio output timing in case of error
912    usleep(bytes * 1000000 / sizeof(int16_t) / channelCount() / sampleRate());
913
914    return status;
915}
916
917status_t AudioHardware::AudioStreamOutMSM72xx::standby()
918{
919    status_t status = NO_ERROR;
920    if (mFd > 0) {
921        ::close(mFd);
922        mFd = -1;
923    }
924    mHardware->mStandby = true;
925    return status;
926}
927
928status_t AudioHardware::AudioStreamOutMSM72xx::dump(int fd, const Vector<String16>& args)
929{
930    const size_t SIZE = 256;
931    char buffer[SIZE];
932    String8 result;
933    result.append("AudioStreamOutMSM72xx::dump\n");
934    snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
935    result.append(buffer);
936    snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
937    result.append(buffer);
938    snprintf(buffer, SIZE, "\tchannel count: %d\n", channelCount());
939    result.append(buffer);
940    snprintf(buffer, SIZE, "\tformat: %d\n", format());
941    result.append(buffer);
942    snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware);
943    result.append(buffer);
944    snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
945    result.append(buffer);
946    snprintf(buffer, SIZE, "\tmStartCount: %d\n", mStartCount);
947    result.append(buffer);
948    snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount);
949    result.append(buffer);
950    ::write(fd, result.string(), result.size());
951    return NO_ERROR;
952}
953
954// ----------------------------------------------------------------------------
955
956AudioHardware::AudioStreamInMSM72xx::AudioStreamInMSM72xx() :
957    mHardware(0), mFd(-1), mRecordEnabled(false), mRetryCount(0)
958{
959}
960
961status_t AudioHardware::AudioStreamInMSM72xx::set(
962        AudioHardware* hw, int format, int channelCount, uint32_t sampleRate)
963{
964    LOGV("AudioStreamInMSM72xx::set(%d, %d, %u)", format, channelCount, sampleRate);
965    if (mFd >= 0) {
966        LOGE("Audio record already open");
967        return -EPERM;
968    }
969
970    // open audio input device
971    status_t status = ::open("/dev/msm_pcm_in", O_RDWR);
972    if (status < 0) {
973        LOGE("Cannot open audio device");
974        goto Error;
975    }
976    mFd = status;
977
978    // configuration
979    LOGV("get config");
980    struct msm_audio_config config;
981    status = ioctl(mFd, AUDIO_GET_CONFIG, &config);
982    if (status < 0) {
983        LOGE("Cannot read config");
984        goto Error;
985    }
986
987    LOGV("set config");
988    config.channel_count = channelCount;
989    config.sample_rate = sampleRate;
990    config.buffer_size = bufferSize();
991    config.buffer_count = 2;
992    config.codec_type = CODEC_TYPE_PCM;
993    status = ioctl(mFd, AUDIO_SET_CONFIG, &config);
994    if (status < 0) {
995        LOGE("Cannot set config");
996        goto Error;
997    }
998
999    LOGV("confirm config");
1000    status = ioctl(mFd, AUDIO_GET_CONFIG, &config);
1001    if (status < 0) {
1002        LOGE("Cannot read config");
1003        goto Error;
1004    }
1005    LOGV("buffer_size: %u", config.buffer_size);
1006    LOGV("buffer_count: %u", config.buffer_count);
1007    LOGV("channel_count: %u", config.channel_count);
1008    LOGV("sample_rate: %u", config.sample_rate);
1009
1010    mHardware = hw;
1011    mHardware->setMicMute_nosync(false);
1012    mRecordEnabled = false;
1013    return NO_ERROR;
1014
1015Error:
1016    if (mFd > 0) {
1017        ::close(mFd);
1018        mFd = -1;
1019    }
1020    return status;
1021}
1022
1023AudioHardware::AudioStreamInMSM72xx::~AudioStreamInMSM72xx()
1024{
1025    LOGV("AudioHardware::closeRecord");
1026    if (mFd < 0) return;
1027    mHardware->checkMicMute();
1028    ::close(mFd);
1029    mRecordEnabled = false;
1030    mHardware->closeInputStream(this);
1031}
1032
1033ssize_t AudioHardware::AudioStreamInMSM72xx::read( void* buffer, ssize_t bytes)
1034{
1035    LOGV("AudioStreamInMSM72xx::read(%p, %u)", buffer, bytes);
1036    if (mFd < 0) return NO_INIT;
1037
1038    size_t count = bytes;
1039    uint8_t* p = static_cast<uint8_t*>(buffer);
1040
1041    if (!mRecordEnabled) {
1042        if (ioctl(mFd, AUDIO_START, 0)) {
1043            LOGE("Error starting record");
1044            return -1;
1045        }
1046        mRecordEnabled = 1;
1047    }
1048
1049    while (count) {
1050        ssize_t bytesRead = ::read(mFd, buffer, count);
1051        if (bytesRead >= 0) {
1052            count -= bytesRead;
1053            p += bytesRead;
1054        } else {
1055            if (errno != EAGAIN) return bytesRead;
1056            mRetryCount++;
1057            LOGW("EAGAIN - retrying");
1058        }
1059    }
1060    return bytes;
1061}
1062
1063status_t AudioHardware::AudioStreamInMSM72xx::dump(int fd, const Vector<String16>& args)
1064{
1065    const size_t SIZE = 256;
1066    char buffer[SIZE];
1067    String8 result;
1068    result.append("AudioStreamInMSM72xx::dump\n");
1069    snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
1070    result.append(buffer);
1071    snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
1072    result.append(buffer);
1073    snprintf(buffer, SIZE, "\tchannel count: %d\n", channelCount());
1074    result.append(buffer);
1075    snprintf(buffer, SIZE, "\tformat: %d\n", format());
1076    result.append(buffer);
1077    snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware);
1078    result.append(buffer);
1079    snprintf(buffer, SIZE, "\tmFd count: %d\n", mFd);
1080    result.append(buffer);
1081    snprintf(buffer, SIZE, "\tmRecordEnabled: %s\n", mRecordEnabled? "true": "false");
1082    result.append(buffer);
1083    snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount);
1084    result.append(buffer);
1085    ::write(fd, result.string(), result.size());
1086    return NO_ERROR;
1087}
1088
1089// ----------------------------------------------------------------------------
1090
1091extern "C" AudioHardwareInterface* createAudioHardware(void) {
1092    return new AudioHardware();
1093}
1094
1095}; // namespace android
1096