static int acdb_get_config_table(uint32_t device_id, uint32_t sample_rate) { struct audio_config_database *db; int n, res; if (q6audio_init()) return 0; if (!acdb_data) { res = acdb_init(acdb_file); if (res) return res; } db = acdb_data; for (n = 0; n < db->entry_count; n++) { if (db->entry[n].device_id != device_id) continue; if (db->entry[n].sample_rate != sample_rate) continue; break; } if (n == db->entry_count) { pr_err("acdb: no entry for device %d, rate %d.\n", device_id, sample_rate); return 0; } pr_info("acdb: %d bytes for device %d, rate %d.\n", db->entry[n].length, device_id, sample_rate); memcpy(audio_data, acdb_data + db->entry[n].offset, db->entry[n].length); return db->entry[n].length; }
int q6audio_do_routing(uint32_t device_id, uint32_t acdb_id) { if (q6audio_init()) return 0; mutex_lock(&audio_path_lock); switch(q6_device_to_dir(device_id)) { case Q6_RX: do_rx_routing(device_id, acdb_id); break; case Q6_TX: do_tx_routing(device_id, acdb_id); break; } mutex_unlock(&audio_path_lock); return 0; }
int q6audio_reinit_acdb(char* filename) { int res; if (q6audio_init()) return 0; mutex_lock(&audio_path_lock); if (strlen(filename) < 0 || !strcmp(filename, acdb_file)) { res = -EINVAL; goto done; } res = acdb_init(filename); if (!res) strcpy(acdb_file, filename); done: mutex_unlock(&audio_path_lock); return res; }
int q6audio_set_rx_volume(int level) { uint32_t adev; int vol; if (q6audio_init()) return 0; if (level < 0 || level > 100) return -EINVAL; mutex_lock(&audio_path_lock); adev = ADSP_AUDIO_DEVICE_ID_VOICE; vol = q6_device_volume(audio_rx_device_id, level); audio_rx_mute(ac_control, adev, 0); audio_rx_volume(ac_control, adev, vol); rx_vol_level = level; mutex_unlock(&audio_path_lock); return 0; }
int q6audio_set_tx_mute(int mute) { uint32_t adev; if (q6audio_init()) return 0; mutex_lock(&audio_path_lock); if (mute == tx_mute_status) { mutex_unlock(&audio_path_lock); return 0; } adev = audio_tx_device_id; audio_tx_mute(ac_control, adev, mute); tx_mute_status = mute; mutex_unlock(&audio_path_lock); return 0; }
struct audio_client *q6fm_open(void) { struct audio_client *ac; if (q6audio_init()) return 0; /* if (audio_rx_device_id != ADSP_AUDIO_DEVICE_ID_HEADSET_SPKR_STEREO && audio_rx_device_id != ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MONO) return 0; */ ac = audio_client_alloc(0); if (!ac) return 0; ac->flags = AUDIO_FLAG_WRITE; audio_rx_path_enable(1, 0); enable_aux_loopback(1); return ac; }
struct audio_client *q6voice_open(uint32_t flags, uint32_t acdb_id) { struct audio_client *ac; if (q6audio_init()) return 0; ac = audio_client_alloc(0); if (!ac) return 0; ac->flags = flags; if (ac->flags & AUDIO_FLAG_WRITE) audio_rx_path_enable(1, acdb_id); else { tx_clk_freq = 8000; audio_tx_path_enable(1, acdb_id); } return ac; }
struct audio_client *q6audio_open_mp3(uint32_t bufsz, uint32_t rate, uint32_t channels, uint32_t acdb_id) { struct audio_client *ac; printk("q6audio_open_mp3()\n"); if (q6audio_init()) return 0; ac = audio_client_alloc(bufsz); if (!ac) return 0; ac->flags = AUDIO_FLAG_WRITE; audio_rx_path_enable(1, acdb_id); audio_mp3_open(ac, bufsz, rate, channels); audio_command(ac, ADSP_AUDIO_IOCTL_CMD_SESSION_START); return ac; }
int q6audio_update_acdb(uint32_t id_src, uint32_t id_dst) { int res; if (q6audio_init()) return 0; mutex_lock(&audio_path_lock); res = audio_update_acdb(id_dst, id_src); if (res) goto done; if (q6_device_to_dir(id_dst) == Q6_RX) qdsp6_devchg_notify(ac_control, ADSP_AUDIO_RX_DEVICE, id_dst); else qdsp6_devchg_notify(ac_control, ADSP_AUDIO_TX_DEVICE, id_dst); qdsp6_standby(ac_control); qdsp6_start(ac_control); done: mutex_unlock(&audio_path_lock); return res; }
struct audio_client *q6audio_open_pcm(uint32_t bufsz, uint32_t rate, uint32_t channels, uint32_t flags, uint32_t acdb_id) { int rc, retry = 5; struct audio_client *ac; if (q6audio_init()) return 0; ac = audio_client_alloc(bufsz); if (!ac) return 0; ac->flags = flags; mutex_lock(&audio_path_lock); if (ac->flags & AUDIO_FLAG_WRITE) { audio_rx_path_refcount++; if (audio_rx_path_refcount == 1) { _audio_rx_clk_enable(); #ifdef CONFIG_MSM_QDSP6_CALLREC q6_rx_path_enable(0, acdb_id); adie_rx_path_enable(acdb_id); #else audio_update_acdb(audio_rx_device_id, acdb_id); qdsp6_devchg_notify(ac_control, ADSP_AUDIO_RX_DEVICE, audio_rx_device_id); qdsp6_standby(ac_control); qdsp6_start(ac_control); #endif } } else { /* TODO: consider concurrency with voice call */ #ifdef CONFIG_MSM_QDSP6_CALLREC if (audio_tx_path_refcount > 0) { tx_clk_freq = 8000; } else { tx_clk_freq = rate; } #else tx_clk_freq = rate; #endif audio_tx_path_refcount++; if (audio_tx_path_refcount == 1) { #ifdef CONFIG_MSM_QDSP6_CALLREC tx_clk_freq = rate; #endif _audio_tx_clk_enable(); _audio_tx_path_enable(0, acdb_id); } } for (retry = 5;; retry--) { if (ac->flags & AUDIO_FLAG_WRITE) rc = audio_out_open(ac, bufsz, rate, channels); else #ifdef CONFIG_MSM_QDSP6_CALLREC rc = audio_in_open(ac, bufsz, flags, rate, channels); #else rc = audio_in_open(ac, bufsz, rate, channels); #endif if (rc == 0) break; if (retry == 0) q6audio_dsp_not_responding(); pr_err("q6audio: open pcm error %d, retrying\n", rc); msleep(1); } if (ac->flags & AUDIO_FLAG_WRITE) { if (audio_rx_path_refcount == 1) { #ifndef CONFIG_MSM_QDSP6_CALLREC adie_enable(); adie_set_path(adie, audio_rx_path_id, ADIE_PATH_RX); adie_set_path_freq_plan(adie, ADIE_PATH_RX, 48000); adie_proceed_to_stage(adie, ADIE_PATH_RX, ADIE_STAGE_DIGITAL_READY); adie_proceed_to_stage(adie, ADIE_PATH_RX, ADIE_STAGE_DIGITAL_ANALOG_READY); #endif audio_rx_analog_enable(1); } } mutex_unlock(&audio_path_lock); for (retry = 5;; retry--) { rc = audio_command(ac, ADSP_AUDIO_IOCTL_CMD_SESSION_START); if (rc == 0) break; if (retry == 0) q6audio_dsp_not_responding(); pr_err("q6audio: stream start error %d, retrying\n", rc); } if (!(ac->flags & AUDIO_FLAG_WRITE)) { ac->buf[0].used = 1; ac->buf[1].used = 1; q6audio_read(ac, &ac->buf[0]); q6audio_read(ac, &ac->buf[1]); } audio_prevent_sleep(); return ac; }