htcleo: audio: add proc file interface /proc/mic_level and fix mic gain (Credits to mdebeljuh and jdivic)
Apply the diff file from http://forum.xda-developers.com/showpost.php?p=17031938&postcount=97 Disable debug output and fix typo by tytung. Usage: echo 'device_id level' > /proc/mic_level Level range: 0-1000; -1 use level from acdb Current levels (device_id): HANDSET (0): -1 SPKR_PHONE (1): -1 HEADSET (2): -1 TTY_HEADSET (3): -1 BT_SCO (4): -1
This commit is contained in:
parent
343845b70a
commit
ca26744fe2
@ -31,6 +31,11 @@
|
||||
#include "proc_comm.h"
|
||||
#include "pmic.h"
|
||||
|
||||
#include <linux/proc_fs.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#define PROCFS_MAX_SIZE 1024
|
||||
#define PROCFS_NAME "mic_level"
|
||||
|
||||
#if 1
|
||||
#define D(fmt, args...) printk(KERN_INFO "Audio: "fmt, ##args)
|
||||
@ -38,6 +43,8 @@
|
||||
#define D(fmt, args...) do {} while (0)
|
||||
#endif
|
||||
|
||||
static struct proc_dir_entry* mic_gain_file;
|
||||
|
||||
static struct mutex mic_lock;
|
||||
static struct mutex bt_sco_lock;
|
||||
|
||||
@ -111,6 +118,71 @@ static struct q6_hw_info q6_audio_hw[Q6_HW_COUNT] =
|
||||
|
||||
#endif
|
||||
|
||||
//-----------proc file interface--------------------------------
|
||||
/**
|
||||
* This function is called then the /proc file is read
|
||||
*
|
||||
*/
|
||||
int
|
||||
mic_level_read(char *buffer,
|
||||
char **buffer_location,
|
||||
off_t offset, int buffer_length, int *eof, void *data)
|
||||
{
|
||||
int ret;
|
||||
char temp_buff[1024];
|
||||
printk(KERN_INFO "mic_level_read (/proc/%s) called\n", PROCFS_NAME);
|
||||
|
||||
if (offset > 0) {
|
||||
/* we have finished to read, return 0 */
|
||||
ret = 0;
|
||||
} else {
|
||||
/* fill the buffer, return the buffer size */
|
||||
sprintf(buffer, "Usage: echo 'device_id level' > /proc/mic_level\n");
|
||||
strcat(buffer, "Level range: 0-1000; -1 use level from acdb\n");
|
||||
strcat(buffer, "Current levels (device_id):\n");
|
||||
sprintf(temp_buff, "HANDSET (%d): %d\n", DEVICE_ID_HANDSET_MIC, q6audio_get_tx_dev_volume(DEVICE_ID_HANDSET_MIC));
|
||||
strcat(buffer, temp_buff);
|
||||
sprintf(temp_buff, "SPKR_PHONE (%d): %d\n", DEVICE_ID_SPKR_PHONE_MIC, q6audio_get_tx_dev_volume(DEVICE_ID_SPKR_PHONE_MIC));
|
||||
strcat(buffer, temp_buff);
|
||||
sprintf(temp_buff, "HEADSET (%d): %d\n", DEVICE_ID_HEADSET_MIC, q6audio_get_tx_dev_volume(DEVICE_ID_HEADSET_MIC));
|
||||
strcat(buffer, temp_buff);
|
||||
sprintf(temp_buff, "TTY_HEADSET (%d): %d\n", DEVICE_ID_TTY_HEADSET_MIC, q6audio_get_tx_dev_volume(DEVICE_ID_TTY_HEADSET_MIC));
|
||||
strcat(buffer, temp_buff);
|
||||
sprintf(temp_buff, "BT_SCO (%d): %d\n", DEVICE_ID_BT_SCO_MIC, q6audio_get_tx_dev_volume(DEVICE_ID_BT_SCO_MIC));
|
||||
strcat(buffer, temp_buff);
|
||||
ret = strlen(buffer);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called with the /proc file is written
|
||||
*
|
||||
*/
|
||||
int mic_level_write(struct file *file, const char *buffer, unsigned long count,
|
||||
void *data)
|
||||
{
|
||||
char temp_buff[512];
|
||||
int device_id=0, level=0, ret, procfs_buffer_size;
|
||||
/* get buffer size */
|
||||
procfs_buffer_size = count;
|
||||
if (procfs_buffer_size > 512 ) {
|
||||
procfs_buffer_size = 512;
|
||||
}
|
||||
|
||||
/* write data to the buffer */
|
||||
if ( copy_from_user(temp_buff, buffer, procfs_buffer_size) ) {
|
||||
return -EFAULT;
|
||||
}
|
||||
sscanf(temp_buff, "%d %d", &device_id, &level);
|
||||
ret = q6audio_set_tx_dev_volume(device_id, level);
|
||||
if (ret<0)
|
||||
return -EFAULT;
|
||||
procfs_buffer_size=strlen(temp_buff);
|
||||
return procfs_buffer_size;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
|
||||
void htcleo_headset_enable(int en)
|
||||
{
|
||||
D("%s %d\n", __func__, en);
|
||||
@ -286,6 +358,7 @@ void htcleo_analog_init(void)
|
||||
config_gpio_table(bt_sco_disable, ARRAY_SIZE(bt_sco_disable));
|
||||
gpio_direction_output(HTCLEO_BT_PCM_OUT, 0);
|
||||
mutex_unlock(&bt_sco_lock);
|
||||
|
||||
}
|
||||
|
||||
int htcleo_get_rx_vol(uint8_t hw, int level)
|
||||
@ -338,6 +411,23 @@ void __init htcleo_audio_init(void)
|
||||
q6audio_register_analog_ops(&ops);
|
||||
acoustic_register_ops(&acoustic);
|
||||
hs_mic_register();
|
||||
|
||||
mic_gain_file = create_proc_entry(PROCFS_NAME, 0644, NULL);
|
||||
|
||||
if (mic_gain_file == NULL) {
|
||||
remove_proc_entry(PROCFS_NAME, NULL);
|
||||
printk(KERN_ALERT "Error: Could not initialize /proc/%s\n",
|
||||
PROCFS_NAME);
|
||||
return;
|
||||
}
|
||||
|
||||
mic_gain_file->read_proc = mic_level_read;
|
||||
mic_gain_file->write_proc = mic_level_write;
|
||||
//mic_gain_file->mode = S_IFREG | S_IRUGO;
|
||||
mic_gain_file->uid = 0;
|
||||
mic_gain_file->gid = 0;
|
||||
|
||||
printk(KERN_INFO "/proc/%s created\n", PROCFS_NAME);
|
||||
// q6audio_set_acdb_file("default_PMIC.acdb");
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,14 @@ struct audio_client {
|
||||
|
||||
#define Q6_HW_COUNT 6
|
||||
|
||||
#define DEVICE_ID_HANDSET_MIC 0
|
||||
#define DEVICE_ID_SPKR_PHONE_MIC 1
|
||||
#define DEVICE_ID_HEADSET_MIC 2
|
||||
#define DEVICE_ID_TTY_HEADSET_MIC 3
|
||||
#define DEVICE_ID_BT_SCO_MIC 4
|
||||
#define DEVICE_ID_MIC_COUNT 5
|
||||
#define MAX_MIC_LEVEL 1000
|
||||
|
||||
struct q6_hw_info {
|
||||
int min_gain;
|
||||
int max_gain;
|
||||
@ -95,6 +103,8 @@ int q6audio_update_acdb(uint32_t id_src, uint32_t id_dst);
|
||||
int q6audio_set_rx_volume(int level);
|
||||
int q6audio_set_rx_mute(int mute);
|
||||
int q6audio_set_stream_volume(struct audio_client *ac, int vol);
|
||||
int q6audio_set_tx_dev_volume(int device_id, int level);
|
||||
int q6audio_get_tx_dev_volume(int device_id);
|
||||
|
||||
struct q6audio_analog_ops {
|
||||
void (*init)(void);
|
||||
|
@ -56,6 +56,46 @@
|
||||
|
||||
#define CB_EVENT_COOKIE 0xC00CE13E
|
||||
|
||||
struct mic_level{
|
||||
int device_id;
|
||||
int level;
|
||||
};
|
||||
|
||||
// same gain range is used for every mic
|
||||
static int min_mic_gain = -5000;
|
||||
static int max_mic_gain = 1500;
|
||||
/*
|
||||
* level range 0 - 1000
|
||||
* level -1 -> level is not defined by user so default value(gain) is set through acbd firmware
|
||||
*/
|
||||
static struct mic_level user_mic_levels[DEVICE_ID_MIC_COUNT] =
|
||||
{
|
||||
[0] =
|
||||
{
|
||||
.device_id = ADSP_AUDIO_DEVICE_ID_HANDSET_MIC,
|
||||
.level = -1
|
||||
},
|
||||
[1] =
|
||||
{
|
||||
.device_id = ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MIC,
|
||||
.level = -1
|
||||
},
|
||||
[2] =
|
||||
{
|
||||
.device_id = ADSP_AUDIO_DEVICE_ID_HEADSET_MIC,
|
||||
.level = -1
|
||||
},
|
||||
[3] =
|
||||
{
|
||||
.device_id = ADSP_AUDIO_DEVICE_ID_TTY_HEADSET_MIC,
|
||||
.level = -1
|
||||
},
|
||||
[4] =
|
||||
{
|
||||
.device_id = ADSP_AUDIO_DEVICE_ID_BT_SCO_MIC,
|
||||
.level = -1
|
||||
}
|
||||
};
|
||||
|
||||
#if 1
|
||||
|
||||
@ -141,6 +181,7 @@ static DEFINE_MUTEX(idlecount_lock);
|
||||
|
||||
void audio_prevent_sleep(void)
|
||||
{
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
mutex_lock(&idlecount_lock);
|
||||
if (++idlecount == 1) {
|
||||
wake_lock(&wakelock);
|
||||
@ -151,6 +192,7 @@ void audio_prevent_sleep(void)
|
||||
|
||||
void audio_allow_sleep(void)
|
||||
{
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
mutex_lock(&idlecount_lock);
|
||||
if (--idlecount == 0) {
|
||||
wake_unlock(&idlelock);
|
||||
@ -181,12 +223,14 @@ static int acdb_use_map = 0;
|
||||
|
||||
void q6audio_register_analog_ops(struct q6audio_analog_ops *ops)
|
||||
{
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
pr_info("register analog ops = %p\n", ops);
|
||||
analog_ops = ops;
|
||||
}
|
||||
|
||||
void q6audio_set_acdb_file(char* filename)
|
||||
{
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
if (filename) {
|
||||
pr_info("audio: set acdb file as %s\n", filename);
|
||||
strncpy(acdb_file, filename, sizeof(acdb_file)-1);
|
||||
@ -196,6 +240,7 @@ void q6audio_set_acdb_file(char* filename)
|
||||
static struct q6_device_info *q6_lookup_device(uint32_t device_id)
|
||||
{
|
||||
struct q6_device_info *di = q6_audio_devices;
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
for (;;) {
|
||||
if (di->id == device_id)
|
||||
return di;
|
||||
@ -211,36 +256,42 @@ static struct q6_device_info *q6_lookup_device(uint32_t device_id)
|
||||
static uint32_t q6_device_to_codec(uint32_t device_id)
|
||||
{
|
||||
struct q6_device_info *di = q6_lookup_device(device_id);
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
return di->codec;
|
||||
}
|
||||
|
||||
static uint32_t q6_device_to_dir(uint32_t device_id)
|
||||
{
|
||||
struct q6_device_info *di = q6_lookup_device(device_id);
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
return di->dir;
|
||||
}
|
||||
|
||||
static uint32_t q6_device_to_cad_id(uint32_t device_id)
|
||||
{
|
||||
struct q6_device_info *di = q6_lookup_device(device_id);
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
return di->cad_id;
|
||||
}
|
||||
|
||||
static uint32_t q6_device_to_path(uint32_t device_id)
|
||||
{
|
||||
struct q6_device_info *di = q6_lookup_device(device_id);
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
return di->path;
|
||||
}
|
||||
|
||||
static uint32_t q6_device_to_rate(uint32_t device_id)
|
||||
{
|
||||
struct q6_device_info *di = q6_lookup_device(device_id);
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
return di->rate;
|
||||
}
|
||||
|
||||
int q6_device_volume(uint32_t device_id, int level)
|
||||
{
|
||||
struct q6_device_info *di = q6_lookup_device(device_id);
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
if (analog_ops->get_rx_vol)
|
||||
return analog_ops->get_rx_vol(di->hw, level);
|
||||
else {
|
||||
@ -267,12 +318,14 @@ static inline int adie_close(struct dal_client *client)
|
||||
static inline int adie_set_path(struct dal_client *client,
|
||||
uint32_t id, uint32_t path_type)
|
||||
{
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
return dal_call_f1(client, ADIE_OP_SET_PATH, id, path_type);
|
||||
}
|
||||
|
||||
static inline int adie_set_path_freq_plan(struct dal_client *client,
|
||||
uint32_t path_type, uint32_t plan)
|
||||
{
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
return dal_call_f1(client, ADIE_OP_SET_PATH_FREQUENCY_PLAN,
|
||||
path_type, plan);
|
||||
}
|
||||
@ -280,6 +333,7 @@ static inline int adie_set_path_freq_plan(struct dal_client *client,
|
||||
static inline int adie_proceed_to_stage(struct dal_client *client,
|
||||
uint32_t path_type, uint32_t stage)
|
||||
{
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
return dal_call_f1(client, ADIE_OP_PROCEED_TO_STAGE,
|
||||
path_type, stage);
|
||||
}
|
||||
@ -287,6 +341,7 @@ static inline int adie_proceed_to_stage(struct dal_client *client,
|
||||
static inline int adie_mute_path(struct dal_client *client,
|
||||
uint32_t path_type, uint32_t mute_state)
|
||||
{
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
return dal_call_f1(client, ADIE_OP_MUTE_PATH, path_type, mute_state);
|
||||
}
|
||||
|
||||
@ -298,6 +353,7 @@ static struct dal_client *acdb;
|
||||
|
||||
static int adie_enable(void)
|
||||
{
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
adie_refcount++;
|
||||
if (adie_refcount == 1)
|
||||
adie_open(adie);
|
||||
@ -306,6 +362,7 @@ static int adie_enable(void)
|
||||
|
||||
static int adie_disable(void)
|
||||
{
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
adie_refcount--;
|
||||
if (adie_refcount == 0)
|
||||
adie_close(adie);
|
||||
@ -336,6 +393,7 @@ static int session_alloc(struct audio_client *ac)
|
||||
{
|
||||
int n;
|
||||
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
mutex_lock(&session_lock);
|
||||
for (n = SESSION_MIN; n < SESSION_MAX; n++) {
|
||||
if (!session[n]) {
|
||||
@ -350,6 +408,7 @@ static int session_alloc(struct audio_client *ac)
|
||||
|
||||
static void session_free(int n, struct audio_client *ac)
|
||||
{
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
mutex_lock(&session_lock);
|
||||
if (session[n] == ac)
|
||||
session[n] = 0;
|
||||
@ -358,6 +417,7 @@ static void session_free(int n, struct audio_client *ac)
|
||||
|
||||
void audio_client_dump(struct audio_client *ac)
|
||||
{
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
dal_trace_dump(ac->client);
|
||||
}
|
||||
|
||||
@ -452,6 +512,7 @@ fail_session:
|
||||
static int audio_ioctl(struct audio_client *ac, uint32_t cmd, void *ptr, uint32_t len)
|
||||
{
|
||||
int r;
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
r = dal_call_f6(ac->client, AUDIO_OP_IOCTL, cmd, ptr, len);
|
||||
return r;
|
||||
}
|
||||
@ -459,6 +520,7 @@ static int audio_ioctl(struct audio_client *ac, uint32_t cmd, void *ptr, uint32_
|
||||
static int audio_command(struct audio_client *ac, uint32_t cmd)
|
||||
{
|
||||
struct adsp_command_hdr rpc;
|
||||
AUDIO_INFO("%s %x\n", __func__, cmd);
|
||||
memset(&rpc, 0, sizeof(rpc));
|
||||
return audio_ioctl(ac, cmd, NULL, 0);
|
||||
}
|
||||
@ -468,6 +530,7 @@ static int audio_open_control(struct audio_client *ac)
|
||||
int r;
|
||||
struct adsp_open_command rpc;
|
||||
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
memset(&rpc, 0, sizeof(rpc));
|
||||
|
||||
rpc.opcode = ADSP_AUDIO_OPCODE_OPEN_DEV;
|
||||
@ -494,6 +557,7 @@ static int audio_out_open(struct audio_client *ac, uint32_t bufsz,
|
||||
struct adsp_open_command rpc;
|
||||
union adsp_audio_format *ptr;
|
||||
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
printk("audio_out_open: %x %d %d\n", bufsz, rate, channels);
|
||||
mutex_lock(&open_mem_lock);
|
||||
|
||||
@ -536,6 +600,7 @@ static int audio_out_open(struct audio_client *ac, uint32_t bufsz,
|
||||
// return r;
|
||||
return ac->open_status;
|
||||
}
|
||||
static void update_all_audio_tx_volume(struct audio_client *ac);
|
||||
|
||||
static int audio_in_open(struct audio_client *ac, uint32_t bufsz,
|
||||
#ifdef CONFIG_QSD_AUDIO_CALLREC
|
||||
@ -547,6 +612,7 @@ static int audio_in_open(struct audio_client *ac, uint32_t bufsz,
|
||||
struct adsp_open_command rpc;
|
||||
union adsp_audio_format *ptr;
|
||||
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
printk("audio_in_open: %x %d %d\n", bufsz, rate, channels);
|
||||
mutex_lock(&open_mem_lock);
|
||||
memset(&rpc, 0, sizeof(rpc));
|
||||
@ -598,6 +664,7 @@ static int audio_mp3_open(struct audio_client *ac, uint32_t bufsz,
|
||||
struct adsp_open_command rpc;
|
||||
union adsp_audio_format *ptr;
|
||||
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
printk("audio_mp3_open: %x %d %d\n", bufsz, rate, channels);
|
||||
mutex_lock(&open_mem_lock);
|
||||
memset(&rpc, 0, sizeof(rpc));
|
||||
@ -644,6 +711,7 @@ static int audio_aac_open(struct audio_client *ac, uint32_t bufsz, void *data)
|
||||
union adsp_audio_format *ptr;
|
||||
|
||||
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
mutex_lock(&open_mem_lock);
|
||||
memset(&rpc, 0, sizeof(rpc));
|
||||
ptr = (union adsp_audio_format*)params_data;
|
||||
@ -783,13 +851,14 @@ static int audio_qcelp_open(struct audio_client *ac, uint32_t bufsz,
|
||||
struct msm_audio_qcelp_config *qf = data;
|
||||
struct adsp_open_command rpc;
|
||||
struct adsp_audio_standard_format *fmt;
|
||||
union adsp_audio_format *ptr;
|
||||
// union adsp_audio_format *ptr;
|
||||
|
||||
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
mutex_lock(&open_mem_lock);
|
||||
memset(&rpc, 0, sizeof(rpc));
|
||||
fmt = (struct adsp_audio_standard_format *)params_data;
|
||||
memset(ptr, 0, sizeof(struct adsp_audio_standard_format));
|
||||
memset(fmt, 0, sizeof(struct adsp_audio_standard_format));
|
||||
|
||||
rpc.numdev = 1;
|
||||
rpc.dev[0] = ADSP_AUDIO_DEVICE_ID_DEFAULT;
|
||||
@ -818,6 +887,7 @@ static int audio_qcelp_open(struct audio_client *ac, uint32_t bufsz,
|
||||
|
||||
static int audio_close(struct audio_client *ac)
|
||||
{
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
AUDIO_INFO("%p: close\n", ac);
|
||||
audio_command(ac, ADSP_AUDIO_IOCTL_CMD_STREAM_STOP);
|
||||
// audio_command(ac, ADSP_AUDIO_IOCTL_CMD_CLOSE);
|
||||
@ -893,7 +963,7 @@ static int audio_rx_volume(struct audio_client *ac, uint32_t dev_id, int32_t vol
|
||||
{
|
||||
struct adsp_set_dev_volume_command rpc;
|
||||
|
||||
AUDIO_INFO("%s: dev_id 0x%08x, volume = %d\n", __func__, dev_id , volume);
|
||||
AUDIO_INFO("%s: ac: %p dev_id 0x%08x, volume = %d\n", __func__, ac, dev_id , volume);
|
||||
|
||||
memset(&rpc, 0, sizeof(rpc));
|
||||
rpc.device_id = dev_id;
|
||||
@ -906,7 +976,7 @@ static int audio_tx_volume(struct audio_client *ac, uint32_t dev_id, int32_t vol
|
||||
{
|
||||
struct adsp_set_dev_volume_command rpc;
|
||||
|
||||
AUDIO_INFO("%s: dev_id 0x%08x, volume = %d\n", __func__, dev_id , volume);
|
||||
AUDIO_INFO("%s: %p dev_id 0x%08x, volume = %d\n", __func__, ac, dev_id , volume);
|
||||
|
||||
memset(&rpc, 0, sizeof(rpc));
|
||||
rpc.device_id = dev_id;
|
||||
@ -1012,6 +1082,7 @@ static void callback(void *data, int len, void *cookie)
|
||||
struct adsp_audio_event* ae;
|
||||
|
||||
// printk("dal event\n");
|
||||
AUDIO_INFO("%s audio callback: CB: %X LOC: %X SIZE=%X, event_id = %X\n", __func__, e->cb_evt, e->loc_evt, e->size, e->ae.event_id);
|
||||
TRACE("audio callback: CB: %X LOC: %X SIZE=%X\n", e->cb_evt, e->loc_evt, e->size);
|
||||
|
||||
if (e->cb_evt != CB_EVENT_COOKIE)
|
||||
@ -1162,7 +1233,7 @@ static int acdb_init(char *filename)
|
||||
int n;
|
||||
|
||||
// return -ENODEV;
|
||||
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
#ifdef CONFIG_MACH_HTCLEO
|
||||
pr_info("acdb: trying htcleo.acdb\n");
|
||||
if(request_firmware(&fw, "htcleo.acdb", q6_control_device.this_device) < 0) {
|
||||
@ -1234,6 +1305,7 @@ static int q6audio_init(void)
|
||||
if (ac_control)
|
||||
{
|
||||
res = 0;
|
||||
AUDIO_INFO("%s no init all done\n", __func__);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -1245,6 +1317,7 @@ static int q6audio_init(void)
|
||||
sdac_clk = clk_get(0, "sdac_clk");
|
||||
audio_data = dma_alloc_coherent(NULL, 4096, &audio_phys, GFP_KERNEL);
|
||||
params_data = dma_alloc_coherent(NULL, 4096, ¶ms_phys, GFP_KERNEL);
|
||||
AUDIO_INFO("%s allocated", __func__);
|
||||
// printk("allocated: %p %x\n", params_data, params_phys);
|
||||
|
||||
// pr_info("audio: init: INIT\n");
|
||||
@ -1326,6 +1399,7 @@ done:
|
||||
|
||||
static int map_cad_dev_to_virtual(int cd)
|
||||
{
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
if (global_now_phone_call)
|
||||
{
|
||||
return cd;
|
||||
@ -1535,7 +1609,7 @@ static int audio_update_acdb(uint32_t adev, uint32_t acdb_id)
|
||||
int sz = -1;
|
||||
|
||||
printk("%s (%d, %d)\n", __func__, adev, acdb_id);
|
||||
AUDIO_INFO("%s (%d, %d)\n", __func__, adev, acdb_id);
|
||||
AUDIO_INFO("%s (%x, %d)\n", __func__, adev, acdb_id);
|
||||
// dex_comm(PCOM_UPDATE_ACDB, 0, 0);
|
||||
sample_rate = q6_device_to_rate(adev);
|
||||
|
||||
@ -1553,12 +1627,14 @@ static int audio_update_acdb(uint32_t adev, uint32_t acdb_id)
|
||||
{
|
||||
acdb_id = q6_device_to_cad_id(adev);
|
||||
printk(" new acdb = %d\n", acdb_id);
|
||||
AUDIO_INFO(" new acdb = %d\n", acdb_id);
|
||||
sz = acdb_get_config_table(acdb_id, sample_rate);
|
||||
}
|
||||
printk("res2 = %d\n", sz);
|
||||
if (sz > 0)
|
||||
{
|
||||
printk("call audio_set_table\n");
|
||||
AUDIO_INFO("call audio_set_table\n");
|
||||
audio_set_table(ac_control, adev, sz);
|
||||
}
|
||||
return 0;
|
||||
@ -1567,6 +1643,7 @@ static int audio_update_acdb(uint32_t adev, uint32_t acdb_id)
|
||||
#ifdef CONFIG_QSD_AUDIO_CALLREC
|
||||
static void adie_rx_path_enable(uint32_t acdb_id)
|
||||
{
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
if (audio_rx_path_id) {
|
||||
adie_enable();
|
||||
adie_set_path(adie, audio_rx_path_id, ADIE_PATH_RX);
|
||||
@ -1581,6 +1658,7 @@ static void adie_rx_path_enable(uint32_t acdb_id)
|
||||
|
||||
static void q6_rx_path_enable(int reconf, uint32_t acdb_id)
|
||||
{
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
audio_update_acdb(audio_rx_device_id, acdb_id);
|
||||
if (!reconf)
|
||||
qdsp6_devchg_notify(ac_control, ADSP_AUDIO_RX_DEVICE, audio_rx_device_id);
|
||||
@ -1609,6 +1687,56 @@ static void _audio_rx_path_enable(int reconf, uint32_t acdb_id)
|
||||
|
||||
audio_rx_analog_enable(1);
|
||||
}
|
||||
//function to calculate mic gain; for now we use the same gain range for all mic
|
||||
static int get_audio_tx_volume(uint32_t device_id, int level)
|
||||
{
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
return min_mic_gain + ((max_mic_gain - min_mic_gain) * level) / MAX_MIC_LEVEL;
|
||||
}
|
||||
|
||||
static DEFINE_MUTEX(audio_path_lock);
|
||||
static int audio_rx_path_refcount;
|
||||
static int audio_tx_path_refcount;
|
||||
|
||||
static void _update_audio_tx_volume(struct audio_client *ac, uint32_t dev_id)
|
||||
{
|
||||
int i, level = -1, volume, ret;
|
||||
AUDIO_INFO("%s device_id %x\n", __func__, dev_id);
|
||||
for (i = 0; i < DEVICE_ID_MIC_COUNT; i++ ) {
|
||||
if (user_mic_levels[i].device_id == dev_id)
|
||||
{
|
||||
level = user_mic_levels[i].level;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (level==-1)
|
||||
{
|
||||
AUDIO_INFO("%s returning level = -1\n", __func__);
|
||||
return;
|
||||
}
|
||||
volume = get_audio_tx_volume(dev_id, level);
|
||||
ret = audio_tx_volume(ac, dev_id, volume);
|
||||
AUDIO_INFO("%s device_id = %x, level= %d, volume= %d, ret = %d", __func__, dev_id, level, volume, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
static void update_all_audio_tx_volume(struct audio_client *ac)
|
||||
{
|
||||
int i, volume, ret;
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
for (i = 0; i < DEVICE_ID_MIC_COUNT; i++ ) {
|
||||
if (user_mic_levels[i].level==-1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
mutex_lock(&audio_path_lock);
|
||||
volume = get_audio_tx_volume(user_mic_levels[i].device_id, user_mic_levels[i].level);
|
||||
ret = audio_tx_volume(ac, user_mic_levels[i].device_id, volume);
|
||||
mutex_unlock(&audio_path_lock);
|
||||
AUDIO_INFO("%s device_id = %x, level= %d, volume= %d, ret = %d", __func__, user_mic_levels[i].device_id, user_mic_levels[i].level, volume, ret);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void _audio_tx_path_enable(int reconf, uint32_t acdb_id)
|
||||
{
|
||||
@ -1632,8 +1760,8 @@ static void _audio_tx_path_enable(int reconf, uint32_t acdb_id)
|
||||
qdsp6_devchg_notify(ac_control, ADSP_AUDIO_TX_DEVICE, audio_tx_device_id);
|
||||
qdsp6_standby(ac_control);
|
||||
qdsp6_start(ac_control);
|
||||
|
||||
audio_tx_mute(ac_control, audio_tx_device_id, tx_mute_status);
|
||||
_update_audio_tx_volume(ac_control, audio_tx_device_id);
|
||||
}
|
||||
|
||||
static void _audio_rx_path_disable(void)
|
||||
@ -1860,9 +1988,6 @@ static void _audio_tx_clk_reinit(uint32_t tx_device)
|
||||
_audio_tx_clk_enable();
|
||||
}
|
||||
|
||||
static DEFINE_MUTEX(audio_path_lock);
|
||||
static int audio_rx_path_refcount;
|
||||
static int audio_tx_path_refcount;
|
||||
|
||||
static int audio_rx_path_enable(int en, uint32_t acdb_id)
|
||||
{
|
||||
@ -1910,6 +2035,7 @@ int q6audio_reinit_acdb(char* filename)
|
||||
{
|
||||
int res;
|
||||
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
if (q6audio_init())
|
||||
return 0;
|
||||
|
||||
@ -1931,6 +2057,7 @@ int q6audio_update_acdb(uint32_t id_src, uint32_t id_dst)
|
||||
{
|
||||
int res;
|
||||
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
if (q6audio_init())
|
||||
return 0;
|
||||
|
||||
@ -1950,11 +2077,49 @@ done:
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
int q6audio_get_tx_dev_volume(int device_id)
|
||||
{
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
if (device_id > DEVICE_ID_MIC_COUNT || device_id < 0)
|
||||
{
|
||||
pr_err("unsupported device id %d\n", device_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
return user_mic_levels[device_id].level;
|
||||
}
|
||||
|
||||
|
||||
int q6audio_set_tx_dev_volume(int device_id, int level)
|
||||
{
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
if (level < -1)
|
||||
level = -1;
|
||||
if (level > MAX_MIC_LEVEL)
|
||||
level = MAX_MIC_LEVEL;
|
||||
if (device_id > DEVICE_ID_MIC_COUNT || device_id < 0)
|
||||
{
|
||||
AUDIO_INFO("%s unsupported device id %d\n", __func__, device_id);
|
||||
pr_err("unsupported device id %d\n", device_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
user_mic_levels[device_id].level = level;
|
||||
if (ac_control)
|
||||
{
|
||||
mutex_lock(&audio_path_lock);
|
||||
_update_audio_tx_volume(ac_control, user_mic_levels[device_id].device_id);
|
||||
mutex_unlock(&audio_path_lock);
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int q6audio_set_tx_mute(int mute)
|
||||
{
|
||||
uint32_t adev;
|
||||
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
AUDIO_INFO("%s mute= %d\n", __func__, mute);
|
||||
if (q6audio_init())
|
||||
return 0;
|
||||
|
||||
@ -1962,19 +2127,22 @@ int q6audio_set_tx_mute(int mute)
|
||||
|
||||
if (mute == tx_mute_status) {
|
||||
mutex_unlock(&audio_path_lock);
|
||||
AUDIO_INFO("%s no change %d\n", __func__, mute);
|
||||
return 0;
|
||||
}
|
||||
|
||||
adev = audio_tx_device_id;
|
||||
audio_tx_mute(ac_control, adev, mute);
|
||||
tx_mute_status = mute;
|
||||
if (!mute)
|
||||
_update_audio_tx_volume(ac_control, audio_tx_device_id);
|
||||
mutex_unlock(&audio_path_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int q6audio_set_stream_volume(struct audio_client *ac, int vol)
|
||||
{
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
AUDIO_INFO("%s %d\n", __func__, vol);
|
||||
if (vol > 1200 || vol < -4000) {
|
||||
pr_err("unsupported volume level %d\n", vol);
|
||||
return -EINVAL;
|
||||
@ -2007,7 +2175,10 @@ int q6audio_set_rx_dev_volume(int level)
|
||||
vol = q6_device_volume(audio_rx_device_id, level);
|
||||
printk("$$ DEV=%08X: vol is %d\n", audio_rx_device_id, vol);
|
||||
audio_rx_volume(ac_control, audio_rx_device_id, vol);
|
||||
|
||||
//this is needed beacause some audio library don't do
|
||||
// mic mute -> mic unmute when the call is made,
|
||||
// instead library is constantly seting audio volume
|
||||
_update_audio_tx_volume(ac_control, audio_tx_device_id);
|
||||
mutex_unlock(&audio_path_lock);
|
||||
return 0;
|
||||
}
|
||||
@ -2034,6 +2205,7 @@ int q6audio_set_rx_volume(int level)
|
||||
rx_vol_level = level;
|
||||
mutex_unlock(&audio_path_lock);
|
||||
#else
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
q6audio_set_rx_dev_volume(level);
|
||||
#endif
|
||||
return 0;
|
||||
@ -2118,6 +2290,8 @@ static void do_tx_routing(uint32_t device_id, uint32_t acdb_id)
|
||||
qdsp6_standby(ac_control);
|
||||
qdsp6_start(ac_control);
|
||||
}
|
||||
AUDIO_INFO("%s, update_tx_volume", __func__);
|
||||
_update_audio_tx_volume(ac_control, device_id);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2129,6 +2303,8 @@ static void do_tx_routing(uint32_t device_id, uint32_t acdb_id)
|
||||
} else {
|
||||
audio_tx_device_id = device_id;
|
||||
audio_tx_path_id = q6_device_to_path(device_id);
|
||||
AUDIO_INFO("%s, update_tx_volume2", __func__);
|
||||
_update_audio_tx_volume(ac_control, audio_tx_device_id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2195,7 +2371,7 @@ struct audio_client *q6audio_open_pcm(uint32_t bufsz, uint32_t rate,
|
||||
int rc, retry = 5;
|
||||
struct audio_client *ac;
|
||||
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
AUDIO_INFO("%s write= %d \n", __func__, flags& AUDIO_FLAG_WRITE);
|
||||
if (q6audio_init())
|
||||
return 0;
|
||||
|
||||
@ -2341,6 +2517,11 @@ struct audio_client *q6audio_open_pcm(uint32_t bufsz, uint32_t rate,
|
||||
}
|
||||
|
||||
audio_prevent_sleep();
|
||||
if (!(ac->flags & AUDIO_FLAG_WRITE))
|
||||
{
|
||||
update_all_audio_tx_volume(ac_control);
|
||||
}
|
||||
|
||||
return ac;
|
||||
#else
|
||||
return audio_test();
|
||||
@ -2380,6 +2561,10 @@ struct audio_client *q6voice_open(uint32_t flags, uint32_t acdb_id)
|
||||
} else {
|
||||
tx_clk_freq = 8000;
|
||||
audio_tx_path_enable(1, acdb_id);
|
||||
AUDIO_INFO("%s start session\n", __func__);
|
||||
// this is a good location for updating the mic gain but
|
||||
// for some reason this doesn't work (too early to set mic gain)
|
||||
//update_all_audio_tx_volume(ac_control);
|
||||
}
|
||||
|
||||
return ac;
|
||||
@ -2403,6 +2588,7 @@ struct audio_client *q6audio_open_mp3(uint32_t bufsz, uint32_t rate,
|
||||
{
|
||||
struct audio_client *ac;
|
||||
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
printk("q6audio_open_mp3()\n");
|
||||
|
||||
if (q6audio_init())
|
||||
@ -2433,6 +2619,7 @@ int q6audio_mp3_close(struct audio_client *ac)
|
||||
int q6audio_async(struct audio_client *ac)
|
||||
{
|
||||
struct adsp_command_hdr rpc;
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
memset(&rpc, 0, sizeof(rpc));
|
||||
// rpc.response_type = ADSP_AUDIO_RESPONSE_ASYNC;
|
||||
return audio_ioctl(ac, ADSP_AUDIO_IOCTL_CMD_STREAM_EOS, &rpc, sizeof(rpc));
|
||||
@ -2445,6 +2632,7 @@ struct audio_client *q6audio_open_aac(uint32_t bufsz, uint32_t rate,
|
||||
{
|
||||
struct audio_client *ac;
|
||||
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
TRACE("q6audio_open_aac flags=%d rate=%d\n", flags, rate);
|
||||
|
||||
if (q6audio_init())
|
||||
@ -2478,6 +2666,7 @@ struct audio_client *q6audio_open_aac(uint32_t bufsz, uint32_t rate,
|
||||
|
||||
int q6audio_aac_close(struct audio_client *ac)
|
||||
{
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
audio_close(ac);
|
||||
if (ac->flags & AUDIO_FLAG_WRITE)
|
||||
audio_rx_path_enable(0, 0);
|
||||
@ -2493,6 +2682,7 @@ struct audio_client *q6fm_open(void)
|
||||
{
|
||||
struct audio_client *ac;
|
||||
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
printk("q6fm_open()\n");
|
||||
|
||||
if (q6audio_init())
|
||||
@ -2515,6 +2705,7 @@ struct audio_client *q6fm_open(void)
|
||||
|
||||
int q6fm_close(struct audio_client *ac)
|
||||
{
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
printk("q6fm_close\n");
|
||||
|
||||
audio_rx_path_enable(0, 0);
|
||||
@ -2551,11 +2742,13 @@ struct audio_client *q6audio_open_qcelp(uint32_t bufsz, uint32_t rate,
|
||||
q6audio_read(ac, &ac->buf[1]);
|
||||
|
||||
audio_prevent_sleep();
|
||||
update_all_audio_tx_volume(ac_control);
|
||||
return ac;
|
||||
}
|
||||
|
||||
int q6audio_qcelp_close(struct audio_client *ac)
|
||||
{
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
audio_close(ac);
|
||||
audio_tx_path_enable(0, 0);
|
||||
audio_client_free(ac);
|
||||
@ -2571,6 +2764,7 @@ int acdb_get_table(int dev_id, int sample_rate)
|
||||
struct acdb_result res;
|
||||
int r;
|
||||
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
memset(audio_data, 0, 4096);
|
||||
memset(&rpc, 0, sizeof(rpc));
|
||||
|
||||
@ -2600,6 +2794,7 @@ static struct audio_client * audio_test(void)
|
||||
int size;
|
||||
struct rpc_info info;
|
||||
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
pr_info("audio: init: codecs\n");
|
||||
icodec_rx_clk = clk_get(0, "icodec_rx_clk");
|
||||
icodec_tx_clk = clk_get(0, "icodec_tx_clk");
|
||||
|
Loading…
Reference in New Issue
Block a user