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:
		| @@ -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"); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user