Revert "htcleo: add audio drivers, qdsp6 modifications and enhanced venc driver"
This reverts commit b739bce6290e5e21b4a90a3efaef4b3178c873fc. Conflicts: arch/arm/configs/htcleo_defconfig arch/arm/mach-msm/Makefile arch/arm/mach-msm/board-htcleo.c
This commit is contained in:
parent
92fe430b32
commit
8137654e8f
@ -220,8 +220,8 @@ CONFIG_MACH_HTCLEO=y
|
||||
CONFIG_HTC_35MM_JACK=y
|
||||
# CONFIG_HTC_PWRSPLY is not set
|
||||
# CONFIG_HTC_PWRSINK is not set
|
||||
CONFIG_MSM_DALRPC=y
|
||||
# CONFIG_MSM_DALRPC_TEST is not set
|
||||
# CONFIG_MSM_DALRPC is not set
|
||||
CONFIG_CACHE_FLUSH_RANGE_LIMIT=0x40000
|
||||
CONFIG_MSM7X00A_USE_GP_TIMER=y
|
||||
# CONFIG_MSM7X00A_USE_DG_TIMER is not set
|
||||
@ -251,10 +251,7 @@ CONFIG_MSM_RPCSERVERS=y
|
||||
# CONFIG_MSM_CPU_FREQ_SCREEN is not set
|
||||
# CONFIG_MSM_HW3D is not set
|
||||
CONFIG_MSM_QDSP6=y
|
||||
CONFIG_QSD_AUDIO=y
|
||||
CONFIG_QSD_HTC_FM=y
|
||||
# CONFIG_MSM_CLOCK_CTRL_DEBUG is not set
|
||||
CONFIG_ARCH_MSM_FLASHLIGHT=y
|
||||
CONFIG_WIFI_CONTROL_FUNC=y
|
||||
CONFIG_WIFI_MEM_PREALLOC=y
|
||||
CONFIG_WIFI_NVS_PROC_CREATE=y
|
||||
@ -265,8 +262,7 @@ CONFIG_HTCLEO_ENABLE_MULTI_TOUCH=y
|
||||
# CONFIG_ENABLE_BRAVO_UART_DRV is not set
|
||||
# CONFIG_ENABLE_USE_DESIRE_AMSS is not set
|
||||
CONFIG_PHYS_OFFSET=0x11800000
|
||||
# CONFIG_HTC_ACOUSTIC is not set
|
||||
# CONFIG_HTC_ACOUSTIC_QSD is not set
|
||||
|
||||
#
|
||||
# Processor Type
|
||||
#
|
||||
|
@ -112,7 +112,8 @@ obj-$(CONFIG_MACH_BRAVOC) += board-bravoc-microp.o clock.o
|
||||
|
||||
obj-$(CONFIG_MACH_HTCLEO) += board-htcleo.o board-htcleo-spi.o board-htcleo-panel.o board-htcleo-keypad.o
|
||||
obj-$(CONFIG_MACH_HTCLEO) += board-htcleo-ts.o board-htcleo-mmc.o ieee754-df.o board-htcleo-power.o
|
||||
obj-$(CONFIG_MACH_HTCLEO) += board-htcleo-battery.o board-htcleo-log.o board-htcleo-acoustic.o board-htcleo-audio.o
|
||||
|
||||
obj-$(CONFIG_MACH_HTCLEO) += board-htcleo-battery.o board-htcleo-log.o
|
||||
obj-$(CONFIG_MACH_HTCLEO) += board-htcleo-bt.o board-htcleo-microp.o board-htcleo-wifi.o
|
||||
obj-$(CONFIG_MACH_HTCLEO) += clock-wince.o
|
||||
|
||||
|
@ -1,247 +0,0 @@
|
||||
/* arch/arm/mach-msm/board-htcleo-acoustic.c
|
||||
*
|
||||
* Copyright (C) 2010 Cotulla
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
#include <linux/device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include <mach/msm_smd.h>
|
||||
#include <mach/msm_rpcrouter.h>
|
||||
#include <mach/msm_iomap.h>
|
||||
#include <mach/htc_acoustic_qsd.h>
|
||||
#include <mach/msm_qdsp6_audio.h>
|
||||
|
||||
#include "smd_private.h"
|
||||
#include "dex_comm.h"
|
||||
|
||||
#define ACOUSTIC_IOCTL_MAGIC 'p'
|
||||
#define ACOUSTIC_UPDATE_ADIE \
|
||||
_IOW(ACOUSTIC_IOCTL_MAGIC, 24, unsigned int)
|
||||
|
||||
|
||||
#define HTC_ACOUSTIC_TABLE_SIZE (0x20000)
|
||||
|
||||
#define D(fmt, args...) printk(KERN_INFO "htc-acoustic: "fmt, ##args)
|
||||
#define E(fmt, args...) printk(KERN_ERR "htc-acoustic: "fmt, ##args)
|
||||
|
||||
static uint32_t htc_acoustic_vir_addr;
|
||||
static struct mutex api_lock;
|
||||
static struct qsd_acoustic_ops *the_ops;
|
||||
|
||||
void acoustic_register_ops(struct qsd_acoustic_ops *ops)
|
||||
{
|
||||
the_ops = ops;
|
||||
}
|
||||
|
||||
int turn_mic_bias_on(int on)
|
||||
{
|
||||
D("%s called %d\n", __func__, on);
|
||||
if (the_ops->enable_mic_bias)
|
||||
the_ops->enable_mic_bias(on);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(turn_mic_bias_on);
|
||||
|
||||
int force_headset_speaker_on(int enable)
|
||||
{
|
||||
printk("force_headset_speaker_on((%d)\n", enable);
|
||||
|
||||
if (enable)
|
||||
dex_audio(0x53);
|
||||
else
|
||||
dex_audio(0x54);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(force_headset_speaker_on);
|
||||
|
||||
int enable_aux_loopback(uint32_t enable)
|
||||
{
|
||||
printk("enable_aux_loopback(%d)\n", enable);
|
||||
|
||||
if (enable)
|
||||
dex_audio(0x51);
|
||||
else
|
||||
dex_audio(0x52);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(enable_aux_loopback);
|
||||
|
||||
int set_aux_gain(int level)
|
||||
{
|
||||
/* struct aux_gain_req {
|
||||
struct rpc_request_hdr hdr;
|
||||
int level;
|
||||
} aux_req;
|
||||
|
||||
D("%s called %d\n", __func__, level);
|
||||
|
||||
if (is_rpc_connect() == -1)
|
||||
return -1;
|
||||
|
||||
aux_req.level = cpu_to_be32(level);
|
||||
return msm_rpc_call(endpoint,
|
||||
ONCRPC_SET_AUX_PGA_GAIN_PROC,
|
||||
&aux_req, sizeof(aux_req), 5 * HZ);*/
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(set_aux_gain);
|
||||
|
||||
|
||||
static int acoustic_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
{
|
||||
unsigned long pgoff;
|
||||
int rc = -EINVAL;
|
||||
size_t size;
|
||||
|
||||
D("mmap\n");
|
||||
|
||||
mutex_lock(&api_lock);
|
||||
|
||||
size = vma->vm_end - vma->vm_start;
|
||||
|
||||
if (vma->vm_pgoff != 0) {
|
||||
E("mmap failed: page offset %lx\n", vma->vm_pgoff);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!htc_acoustic_vir_addr) {
|
||||
E("mmap failed: smem region not allocated\n");
|
||||
rc = -EIO;
|
||||
goto done;
|
||||
}
|
||||
|
||||
pgoff = MSM_SHARED_RAM_PHYS +
|
||||
(htc_acoustic_vir_addr - (uint32_t)MSM_SHARED_RAM_BASE);
|
||||
pgoff = ((pgoff + 4095) & ~4095);
|
||||
htc_acoustic_vir_addr = ((htc_acoustic_vir_addr + 4095) & ~4095);
|
||||
|
||||
if (pgoff <= 0) {
|
||||
E("pgoff wrong. %ld\n", pgoff);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (size <= HTC_ACOUSTIC_TABLE_SIZE) {
|
||||
pgoff = pgoff >> PAGE_SHIFT;
|
||||
} else {
|
||||
E("size > HTC_ACOUSTIC_TABLE_SIZE %d\n", size);
|
||||
goto done;
|
||||
}
|
||||
|
||||
vma->vm_flags |= VM_IO | VM_RESERVED;
|
||||
rc = io_remap_pfn_range(vma, vma->vm_start, pgoff,
|
||||
size, vma->vm_page_prot);
|
||||
|
||||
if (rc < 0)
|
||||
E("mmap failed: remap error %d\n", rc);
|
||||
|
||||
done: mutex_unlock(&api_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int acoustic_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
int rc = -EIO;
|
||||
|
||||
D("open\n");
|
||||
|
||||
mutex_lock(&api_lock);
|
||||
|
||||
if (!htc_acoustic_vir_addr)
|
||||
{
|
||||
htc_acoustic_vir_addr = (uint32_t)MSM_SHARED_RAM_BASE + 0xF8000;
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
mutex_unlock(&api_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int acoustic_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
D("release\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long acoustic_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
D("ioctl\n");
|
||||
|
||||
mutex_lock(&api_lock);
|
||||
|
||||
switch (cmd) {
|
||||
case ACOUSTIC_UPDATE_ADIE:
|
||||
{
|
||||
unsigned data = 0xE5;
|
||||
|
||||
D("ioctl: ACOUSTIC_UPDATE_ADIE called %d.\n", current->pid);
|
||||
|
||||
// CotullaTODO: finish this code. if we need android tables really...
|
||||
|
||||
D("ioctl: done.\n");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
E("ioctl: invalid command\n");
|
||||
rc = -EINVAL;
|
||||
}
|
||||
|
||||
mutex_unlock(&api_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
struct rpc_set_uplink_mute_args {
|
||||
int mute;
|
||||
};
|
||||
|
||||
static struct file_operations acoustic_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = acoustic_open,
|
||||
.release = acoustic_release,
|
||||
.mmap = acoustic_mmap,
|
||||
.unlocked_ioctl = acoustic_ioctl,
|
||||
};
|
||||
|
||||
static struct miscdevice acoustic_misc = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = "htc-acoustic",
|
||||
.fops = &acoustic_fops,
|
||||
};
|
||||
|
||||
static int __init acoustic_init(void)
|
||||
{
|
||||
mutex_init(&api_lock);
|
||||
return misc_register(&acoustic_misc);
|
||||
}
|
||||
|
||||
static void __exit acoustic_exit(void)
|
||||
{
|
||||
misc_deregister(&acoustic_misc);
|
||||
}
|
||||
|
||||
module_init(acoustic_init);
|
||||
module_exit(acoustic_exit);
|
||||
|
@ -1,330 +0,0 @@
|
||||
/* arch/arm/mach-msm/board-htcleo-audio.c
|
||||
*
|
||||
* Copyright (C) 2010 Cotulla
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/delay.h>
|
||||
#include <mach/msm_qdsp6_audio.h>
|
||||
#include <mach/htc_acoustic_qsd.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <mach/gpio.h>
|
||||
|
||||
#include "board-htcleo.h"
|
||||
#include "devices.h"
|
||||
#include "dex_comm.h"
|
||||
#include "proc_comm.h"
|
||||
#include "pmic.h"
|
||||
|
||||
|
||||
#if 1
|
||||
#define D(fmt, args...) printk(KERN_INFO "Audio: "fmt, ##args)
|
||||
#else
|
||||
#define D(fmt, args...) do {} while (0)
|
||||
#endif
|
||||
|
||||
static struct mutex mic_lock;
|
||||
static struct mutex bt_sco_lock;
|
||||
|
||||
#if 1
|
||||
|
||||
// LEO
|
||||
static struct q6_hw_info q6_audio_hw[Q6_HW_COUNT] =
|
||||
{
|
||||
[Q6_HW_HANDSET] =
|
||||
{
|
||||
.min_gain = -2000,
|
||||
.max_gain = 0,
|
||||
},
|
||||
[Q6_HW_HEADSET] =
|
||||
{
|
||||
.min_gain = -2000,
|
||||
.max_gain = 0,
|
||||
},
|
||||
[Q6_HW_SPEAKER] =
|
||||
{
|
||||
.min_gain = -1000,
|
||||
.max_gain = 500,
|
||||
},
|
||||
[Q6_HW_TTY] =
|
||||
{
|
||||
.min_gain = 0,
|
||||
.max_gain = 0,
|
||||
},
|
||||
[Q6_HW_BT_SCO] =
|
||||
{
|
||||
.min_gain = -1100,
|
||||
.max_gain = 400,
|
||||
},
|
||||
[Q6_HW_BT_A2DP] =
|
||||
{
|
||||
.min_gain = -1100,
|
||||
.max_gain = 400,
|
||||
},
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
// old desire one
|
||||
static struct q6_hw_info q6_audio_hw[Q6_HW_COUNT] =
|
||||
{
|
||||
[Q6_HW_HANDSET] = {
|
||||
.min_gain = -2000,
|
||||
.max_gain = 0,
|
||||
},
|
||||
[Q6_HW_HEADSET] = {
|
||||
.min_gain = -2000,
|
||||
.max_gain = 0,
|
||||
},
|
||||
[Q6_HW_SPEAKER] = {
|
||||
.min_gain = -1500,
|
||||
.max_gain = 0,
|
||||
},
|
||||
[Q6_HW_TTY] = {
|
||||
.min_gain = -2000,
|
||||
.max_gain = 0,
|
||||
},
|
||||
[Q6_HW_BT_SCO] = {
|
||||
.min_gain = -2000,
|
||||
.max_gain = 0,
|
||||
},
|
||||
[Q6_HW_BT_A2DP] = {
|
||||
.min_gain = -2000,
|
||||
.max_gain = 0,
|
||||
},
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
void htcleo_headset_enable(int en)
|
||||
{
|
||||
D("%s %d\n", __func__, en);
|
||||
/* enable audio amp */
|
||||
if (en) mdelay(60);
|
||||
gpio_set_value(HTCLEO_AUD_JACKHP_EN, !!en);
|
||||
}
|
||||
|
||||
void htcleo_speaker_enable(int en)
|
||||
{
|
||||
struct spkr_config_mode scm;
|
||||
memset(&scm, 0, sizeof(scm));
|
||||
|
||||
D("%s %d\n", __func__, en);
|
||||
if (en)
|
||||
{
|
||||
scm.is_right_chan_en = 0;
|
||||
scm.is_left_chan_en = 1;
|
||||
scm.is_stereo_en = 0;
|
||||
scm.is_hpf_en = 0; //1; // CotullaTODO: check it
|
||||
pmic_spkr_en_mute(LEFT_SPKR, 0);
|
||||
pmic_spkr_en_mute(RIGHT_SPKR, 0);
|
||||
pmic_set_spkr_configuration(&scm);
|
||||
pmic_spkr_set_mux_hpf_corner_freq(SPKR_FREQ_0_76KHZ);
|
||||
pmic_spkr_en(LEFT_SPKR, 1);
|
||||
pmic_spkr_en(RIGHT_SPKR, 0);
|
||||
|
||||
pmic_spkr_en_hpf(ON_CMD); // +LEO
|
||||
|
||||
/* unmute */
|
||||
pmic_spkr_en_mute(LEFT_SPKR, 1);
|
||||
mdelay(40);
|
||||
}
|
||||
else
|
||||
{
|
||||
pmic_spkr_en_mute(LEFT_SPKR, 0);
|
||||
|
||||
pmic_spkr_en_hpf(OFF_CMD); // +LEO
|
||||
pmic_spkr_en(LEFT_SPKR, 0);
|
||||
pmic_spkr_en(RIGHT_SPKR, 0);
|
||||
|
||||
pmic_set_spkr_configuration(&scm);
|
||||
}
|
||||
}
|
||||
|
||||
void htcleo_receiver_enable(int en)
|
||||
{
|
||||
// if (is_cdma_version(system_rev) &&
|
||||
// ((system_rev == 0xC1) || (system_rev == 0xC2))) {
|
||||
struct spkr_config_mode scm;
|
||||
memset(&scm, 0, sizeof(scm));
|
||||
|
||||
D("%s %d\n", __func__, en);
|
||||
if (en)
|
||||
{
|
||||
scm.is_right_chan_en = 1;
|
||||
scm.is_left_chan_en = 0;
|
||||
scm.is_stereo_en = 0;
|
||||
scm.is_hpf_en = 1;
|
||||
pmic_spkr_en_mute(RIGHT_SPKR, 0);
|
||||
pmic_set_spkr_configuration(&scm);
|
||||
pmic_spkr_en(RIGHT_SPKR, 1);
|
||||
|
||||
/* unmute */
|
||||
pmic_spkr_en_mute(RIGHT_SPKR, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
pmic_spkr_en_mute(RIGHT_SPKR, 0);
|
||||
|
||||
pmic_spkr_en(RIGHT_SPKR, 0);
|
||||
|
||||
pmic_set_spkr_configuration(&scm);
|
||||
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
static uint32_t bt_sco_enable[] =
|
||||
{
|
||||
PCOM_GPIO_CFG(HTCLEO_BT_PCM_OUT, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA),
|
||||
PCOM_GPIO_CFG(HTCLEO_BT_PCM_IN, 1, GPIO_INPUT, GPIO_NO_PULL, GPIO_2MA),
|
||||
PCOM_GPIO_CFG(HTCLEO_BT_PCM_SYNC, 2, GPIO_INPUT, GPIO_NO_PULL, GPIO_2MA),
|
||||
PCOM_GPIO_CFG(HTCLEO_BT_PCM_CLK, 2, GPIO_INPUT, GPIO_NO_PULL, GPIO_2MA)
|
||||
};
|
||||
|
||||
static uint32_t bt_sco_disable[] =
|
||||
{
|
||||
PCOM_GPIO_CFG(HTCLEO_BT_PCM_OUT, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA),
|
||||
PCOM_GPIO_CFG(HTCLEO_BT_PCM_IN, 0, GPIO_INPUT, GPIO_NO_PULL, GPIO_2MA),
|
||||
PCOM_GPIO_CFG(HTCLEO_BT_PCM_SYNC, 0, GPIO_INPUT, GPIO_NO_PULL, GPIO_2MA),
|
||||
PCOM_GPIO_CFG(HTCLEO_BT_PCM_CLK, 0, GPIO_INPUT, GPIO_NO_PULL, GPIO_2MA)
|
||||
};
|
||||
|
||||
void htcleo_bt_sco_enable(int en)
|
||||
{
|
||||
static int bt_sco_refcount;
|
||||
D("%s %d\n", __func__, en);
|
||||
|
||||
mutex_lock(&bt_sco_lock);
|
||||
if (en)
|
||||
{
|
||||
if (++bt_sco_refcount == 1)
|
||||
{
|
||||
config_gpio_table(bt_sco_enable, ARRAY_SIZE(bt_sco_enable));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (--bt_sco_refcount == 0)
|
||||
{
|
||||
config_gpio_table(bt_sco_disable, ARRAY_SIZE(bt_sco_disable));
|
||||
gpio_set_value(HTCLEO_BT_PCM_OUT, 0);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&bt_sco_lock);
|
||||
}
|
||||
|
||||
void htcleo_mic_enable(int en)
|
||||
{
|
||||
static int old_state = 0, new_state = 0;
|
||||
|
||||
D("%s %d\n", __func__, en);
|
||||
|
||||
mutex_lock(&mic_lock);
|
||||
if (!!en)
|
||||
new_state++;
|
||||
else
|
||||
new_state--;
|
||||
|
||||
if (new_state == 1 && old_state == 0)
|
||||
{
|
||||
gpio_set_value(HTCLEO_AUD_2V5_EN, 1);
|
||||
mdelay(60);
|
||||
}
|
||||
else if (new_state == 0 && old_state == 1)
|
||||
{
|
||||
gpio_set_value(HTCLEO_AUD_2V5_EN, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
D("%s: do nothing %d %d\n", __func__, old_state, new_state);
|
||||
}
|
||||
|
||||
old_state = new_state;
|
||||
mutex_unlock(&mic_lock);
|
||||
}
|
||||
|
||||
|
||||
void htcleo_analog_init(void)
|
||||
{
|
||||
D("%s\n", __func__);
|
||||
/* stereo pmic init */
|
||||
pmic_spkr_set_gain(LEFT_SPKR, SPKR_GAIN_PLUS12DB);
|
||||
pmic_spkr_set_gain(RIGHT_SPKR, SPKR_GAIN_PLUS12DB);
|
||||
pmic_spkr_en_right_chan(OFF_CMD);
|
||||
pmic_spkr_en_left_chan(OFF_CMD);
|
||||
pmic_spkr_add_right_left_chan(OFF_CMD);
|
||||
pmic_spkr_en_stereo(OFF_CMD);
|
||||
pmic_spkr_select_usb_with_hpf_20hz(OFF_CMD);
|
||||
pmic_spkr_bypass_mux(OFF_CMD);
|
||||
pmic_spkr_en_hpf(OFF_CMD);
|
||||
pmic_spkr_en_sink_curr_from_ref_volt_cir(OFF_CMD);
|
||||
pmic_spkr_set_mux_hpf_corner_freq(SPKR_FREQ_0_76KHZ);
|
||||
pmic_mic_set_volt(MIC_VOLT_1_80V);
|
||||
|
||||
gpio_request(HTCLEO_AUD_JACKHP_EN, "aud_jackhp_en");
|
||||
gpio_request(HTCLEO_BT_PCM_OUT, "bt_pcm_out");
|
||||
|
||||
gpio_direction_output(HTCLEO_AUD_JACKHP_EN, 0);
|
||||
|
||||
mutex_lock(&bt_sco_lock);
|
||||
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)
|
||||
{
|
||||
int vol;
|
||||
|
||||
if (level > 100)
|
||||
level = 100;
|
||||
else if (level < 0)
|
||||
level = 0;
|
||||
|
||||
// TODO: is it correct?
|
||||
struct q6_hw_info *info;
|
||||
info = &q6_audio_hw[hw];
|
||||
vol = info->min_gain + ((info->max_gain - info->min_gain) * level) / 100;
|
||||
|
||||
D("%s %d\n", __func__, vol);
|
||||
return vol;
|
||||
}
|
||||
|
||||
static struct qsd_acoustic_ops acoustic =
|
||||
{
|
||||
.enable_mic_bias = htcleo_mic_enable,
|
||||
};
|
||||
|
||||
static struct q6audio_analog_ops ops =
|
||||
{
|
||||
.init = htcleo_analog_init,
|
||||
.speaker_enable = htcleo_speaker_enable,
|
||||
.headset_enable = htcleo_headset_enable,
|
||||
.receiver_enable = htcleo_receiver_enable,
|
||||
.bt_sco_enable = htcleo_bt_sco_enable,
|
||||
.int_mic_enable = htcleo_mic_enable,
|
||||
.ext_mic_enable = htcleo_mic_enable,
|
||||
.get_rx_vol = htcleo_get_rx_vol,
|
||||
};
|
||||
|
||||
void __init htcleo_audio_init(void)
|
||||
{
|
||||
mutex_init(&mic_lock);
|
||||
mutex_init(&bt_sco_lock);
|
||||
q6audio_register_analog_ops(&ops);
|
||||
acoustic_register_ops(&acoustic);
|
||||
// q6audio_set_acdb_file("default_PMIC.acdb");
|
||||
}
|
||||
|
||||
// END OF FILE
|
@ -1,351 +0,0 @@
|
||||
/* board-htcleo-hds.c
|
||||
*
|
||||
* Copyright (C) 2010 Cotulla
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/earlysuspend.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <mach/htc_35mm_jack.h>
|
||||
|
||||
#include "board-htcleo.h"
|
||||
#include "gpio_chip.h"
|
||||
|
||||
|
||||
int microp_get_remote_adc(uint32_t *val);
|
||||
int microp_set_adc_req(uint8_t value, int enable);
|
||||
|
||||
|
||||
static int headset_has_mic(void);
|
||||
static int enable_headset_plug_event(void);
|
||||
static int enable_key_event(void);
|
||||
static int disable_key_event(void);
|
||||
|
||||
static struct h35mm_platform_data htcleo_h35mm_data =
|
||||
{
|
||||
.plug_event_enable = enable_headset_plug_event,
|
||||
.headset_has_mic = headset_has_mic,
|
||||
.key_event_enable = enable_key_event,
|
||||
.key_event_disable = disable_key_event,
|
||||
};
|
||||
|
||||
static struct platform_device htcleo_h35mm =
|
||||
{
|
||||
.name = "htc_headset",
|
||||
.id = -1,
|
||||
.dev =
|
||||
{
|
||||
.platform_data = &htcleo_h35mm_data,
|
||||
},
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct hds_data
|
||||
{
|
||||
int inited;
|
||||
int gpio_mic;
|
||||
int gpio_det;
|
||||
int irq_mic;
|
||||
int irq_det;
|
||||
int headset_is_in;
|
||||
int is_hpin_pin_stable;
|
||||
int last_pressed_key;
|
||||
struct work_struct work_det;
|
||||
struct work_struct work_mic;
|
||||
struct delayed_work hpin_debounce_work;
|
||||
};
|
||||
|
||||
static struct hds_data hds;
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int headset_detect_mic(void)
|
||||
{
|
||||
return !gpio_get_value(hds.gpio_mic);
|
||||
}
|
||||
|
||||
static int headset_is_in(void)
|
||||
{
|
||||
return !gpio_get_value(hds.gpio_det);
|
||||
}
|
||||
|
||||
static int get_remote_keycode(int *keycode)
|
||||
{
|
||||
uint32_t val;
|
||||
uint32_t btn = 0;
|
||||
|
||||
microp_set_adc_req(1, 1);
|
||||
if (microp_get_remote_adc(&val))
|
||||
{
|
||||
// failed. who know why? ignore
|
||||
*keycode = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if((val >= 0) && (val <= 33))
|
||||
{
|
||||
btn = 1;
|
||||
}
|
||||
else if((val >= 38) && (val <= 82))
|
||||
{
|
||||
btn = 2;
|
||||
}
|
||||
else if((val >= 95) && (val <= 200))
|
||||
{
|
||||
btn = 3;
|
||||
}
|
||||
else if(val > 200)
|
||||
{
|
||||
// check previous key
|
||||
if (hds.last_pressed_key)
|
||||
{
|
||||
*keycode = hds.last_pressed_key | 0x80;
|
||||
hds.last_pressed_key = 0;
|
||||
return 0;
|
||||
}
|
||||
*keycode = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
hds.last_pressed_key = btn;
|
||||
*keycode = btn;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int headset_has_mic(void)
|
||||
{
|
||||
int mic1 = -1;
|
||||
int mic2 = -1;
|
||||
int count = 0;
|
||||
|
||||
mic2 = headset_detect_mic();
|
||||
|
||||
/* debounce the detection wait until 2 consecutive read are equal */
|
||||
while ((mic1 != mic2) && (count < 10))
|
||||
{
|
||||
mic1 = mic2;
|
||||
msleep(600);
|
||||
mic2 = headset_detect_mic();
|
||||
count++;
|
||||
}
|
||||
|
||||
printk("%s: microphone (%d) %s\n", __func__, count, mic1 ? "present" : "not present");
|
||||
|
||||
return mic1;
|
||||
}
|
||||
|
||||
static int enable_headset_plug_event(void)
|
||||
{
|
||||
uint16_t stat;
|
||||
|
||||
enable_irq(hds.irq_det);
|
||||
|
||||
// see if headset state has changed
|
||||
stat = headset_is_in();
|
||||
printk("headsetisin: old %d new %d\n", hds.headset_is_in, stat);
|
||||
if (hds.headset_is_in != stat)
|
||||
{
|
||||
hds.headset_is_in = stat;
|
||||
printk("Headset state changed\n");
|
||||
htc_35mm_jack_plug_event(stat, &hds.is_hpin_pin_stable);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int enable_key_event(void)
|
||||
{
|
||||
printk("enable_key_event\n");
|
||||
enable_irq(hds.irq_mic);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int disable_key_event(void)
|
||||
{
|
||||
printk("disable_key_event\n");
|
||||
disable_irq(hds.irq_mic);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hpin_debounce_do_work(struct work_struct *work)
|
||||
{
|
||||
int insert = 0;
|
||||
|
||||
insert = headset_is_in();
|
||||
printk("debonce new %d old %d\n", insert, hds.headset_is_in);
|
||||
if (insert != hds.headset_is_in)
|
||||
{
|
||||
// clear keypress state
|
||||
hds.last_pressed_key = 0;
|
||||
|
||||
hds.headset_is_in = insert;
|
||||
printk("headset %s\n", insert ? "inserted" : "removed");
|
||||
htc_35mm_jack_plug_event(hds.headset_is_in, &hds.is_hpin_pin_stable);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void det_intr_work_func(struct work_struct *work)
|
||||
{
|
||||
int value1;
|
||||
|
||||
printk("det_intr_work_func\n");
|
||||
hds.is_hpin_pin_stable = 0;
|
||||
// TODO:
|
||||
// wake_lock_timeout(µp_i2c_wakelock, 3 * HZ);
|
||||
if (!hds.headset_is_in)
|
||||
schedule_delayed_work(&hds.hpin_debounce_work, msecs_to_jiffies(500));
|
||||
else
|
||||
schedule_delayed_work(&hds.hpin_debounce_work, msecs_to_jiffies(300));
|
||||
}
|
||||
|
||||
static void mic_intr_work_func(struct work_struct *work)
|
||||
{
|
||||
int keycode = 0;
|
||||
int value1;
|
||||
|
||||
printk("mic_intr_work_func\n");
|
||||
if ((get_remote_keycode(&keycode) == 0) && (hds.is_hpin_pin_stable))
|
||||
{
|
||||
printk("keycode %d\n", keycode);
|
||||
htc_35mm_key_event(keycode, &hds.is_hpin_pin_stable);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static irqreturn_t detect_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
int value1, value2;
|
||||
int retry_limit = 10;
|
||||
|
||||
do
|
||||
{
|
||||
value1 = gpio_get_value(hds.gpio_det);
|
||||
set_irq_type(hds.irq_det, value1 ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH);
|
||||
value2 = gpio_get_value(hds.gpio_det);
|
||||
|
||||
} while (value1 != value2 && retry_limit-- > 0);
|
||||
|
||||
schedule_work(&hds.work_det);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t mic_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
int value1, value2;
|
||||
int retry_limit = 10;
|
||||
|
||||
do
|
||||
{
|
||||
value1 = gpio_get_value(hds.gpio_mic);
|
||||
set_irq_type(hds.irq_mic, value1 ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH);
|
||||
value2 = gpio_get_value(hds.gpio_mic);
|
||||
|
||||
} while (value1 != value2 && retry_limit-- > 0);
|
||||
|
||||
schedule_work(&hds.work_mic);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int htcleo_hds_probe(struct platform_device *pdev)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
printk("htcleo_hds_probe()\n");
|
||||
|
||||
// allow run it only once
|
||||
if (hds.inited != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
hds.last_pressed_key = 0;
|
||||
hds.inited = 1;
|
||||
hds.gpio_mic = HTCLEO_GPIO_HDS_MIC;
|
||||
hds.gpio_det = HTCLEO_GPIO_HDS_DET;
|
||||
|
||||
hds.irq_mic = gpio_to_irq(hds.gpio_mic);
|
||||
hds.irq_det = gpio_to_irq(hds.gpio_det);
|
||||
|
||||
gpio_request(hds.gpio_det, "hds_detect");
|
||||
gpio_request(hds.gpio_mic, "hds_mic");
|
||||
|
||||
gpio_direction_input(hds.gpio_det);
|
||||
gpio_direction_input(hds.gpio_mic);
|
||||
|
||||
hds.headset_is_in = 0;
|
||||
hds.is_hpin_pin_stable = 1;
|
||||
INIT_WORK(&hds.work_det, det_intr_work_func);
|
||||
INIT_WORK(&hds.work_mic, mic_intr_work_func);
|
||||
INIT_DELAYED_WORK(&hds.hpin_debounce_work, hpin_debounce_do_work);
|
||||
|
||||
|
||||
rc = request_irq(hds.irq_det, detect_irq_handler, IRQF_DISABLED | IRQF_TRIGGER_LOW, "hds_detect_intr", 0);
|
||||
rc = request_irq(hds.irq_mic, mic_irq_handler, IRQF_DISABLED | IRQF_TRIGGER_LOW, "hds_mic_intr", 0);
|
||||
disable_irq(hds.irq_mic);
|
||||
|
||||
platform_device_register(&htcleo_h35mm);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int htcleo_hds_remove(struct platform_device *dev)
|
||||
{
|
||||
platform_device_unregister(&htcleo_h35mm);
|
||||
|
||||
free_irq(hds.irq_det, 0);
|
||||
free_irq(hds.irq_mic, 0);
|
||||
|
||||
gpio_free(hds.gpio_det);
|
||||
gpio_free(hds.gpio_mic);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
static struct platform_driver htcleo_hds_driver =
|
||||
{
|
||||
.probe = htcleo_hds_probe,
|
||||
.remove = htcleo_hds_remove,
|
||||
.driver =
|
||||
{
|
||||
.name = "htcleo_hds",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init htcleo_hds_init(void)
|
||||
{
|
||||
return platform_driver_register(&htcleo_hds_driver);
|
||||
}
|
||||
|
||||
static void __exit htcleo_hds_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&htcleo_hds_driver);
|
||||
}
|
||||
|
||||
module_init(htcleo_hds_init);
|
||||
module_exit(htcleo_hds_exit);
|
||||
|
||||
MODULE_AUTHOR("Cotulla");
|
||||
MODULE_DESCRIPTION("HTC LEO headset driver");
|
||||
MODULE_LICENSE("GPL");
|
@ -58,7 +58,6 @@ void __init htcleo_microp_init(void);
|
||||
#endif
|
||||
|
||||
extern int __init htcleo_init_mmc(unsigned debug_uart);
|
||||
extern void __init htcleo_audio_init(void);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// SPI
|
||||
@ -741,7 +740,6 @@ static void __init htcleo_init(void)
|
||||
platform_device_register(&htcleo_timed_gpios);
|
||||
|
||||
htcleo_bt_init();
|
||||
htcleo_audio_init();
|
||||
|
||||
#ifdef CONFIG_USB_ANDROID
|
||||
msm_hsusb_set_vbus_state(htcleo_get_vbus_state());
|
||||
|
@ -33,8 +33,7 @@ struct audio_client {
|
||||
int dsp_buf; /* next buffer the DSP will touch */
|
||||
int running;
|
||||
int session;
|
||||
int open_done;
|
||||
int open_status;
|
||||
|
||||
wait_queue_head_t wait;
|
||||
struct dal_client *client;
|
||||
|
||||
@ -92,7 +91,6 @@ int q6audio_set_tx_mute(int mute);
|
||||
int q6audio_reinit_acdb(char* filename);
|
||||
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);
|
||||
|
||||
struct q6audio_analog_ops {
|
||||
|
@ -1,15 +1,11 @@
|
||||
obj-y += dal.o
|
||||
ifndef CONFIG_ARCH_HTCLEO
|
||||
obj-y += q6audio_htcleo.o
|
||||
else
|
||||
obj-y += q6audio.o
|
||||
endif
|
||||
obj-y += pcm_out.o
|
||||
obj-y += pcm_in.o
|
||||
obj-y += mp3.o
|
||||
obj-y += routing.o
|
||||
#obj-y += routing.o
|
||||
obj-y += audio_ctl.o
|
||||
obj-y += msm_q6vdec.o
|
||||
obj-y += msm_q6venc.o
|
||||
obj-y += aac_in.o
|
||||
obj-y += qcelp_in.o
|
||||
#obj-y += aac_in.o
|
||||
#obj-y += qcelp_in.o
|
||||
|
@ -1,217 +0,0 @@
|
||||
/* arch/arm/mach-msm/qdsp6/aac_in.c
|
||||
*
|
||||
* Copyright (C) 2009 Google, Inc.
|
||||
* Copyright (C) 2009 HTC Corporation
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/fs.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/msm_audio.h>
|
||||
#include <mach/msm_qdsp6_audio.h>
|
||||
|
||||
#define BUFSZ (4096)
|
||||
#define DMASZ (BUFSZ * 2)
|
||||
|
||||
#if 0
|
||||
#define TRACE(x...) pr_info("Q6: "x)
|
||||
#else
|
||||
#define TRACE(x...) do{}while(0)
|
||||
#endif
|
||||
|
||||
static DEFINE_MUTEX(aac_in_lock);
|
||||
static int aac_in_opened = 0;
|
||||
static struct aac_format *af;
|
||||
|
||||
void audio_client_dump(struct audio_client *ac);
|
||||
|
||||
static long aac_in_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case AUDIO_SET_VOLUME:
|
||||
break;
|
||||
case AUDIO_GET_STATS: {
|
||||
struct msm_audio_stats stats;
|
||||
memset(&stats, 0, sizeof(stats));
|
||||
if (copy_to_user((void*) arg, &stats, sizeof(stats)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
case AUDIO_START: {
|
||||
uint32_t acdb_id;
|
||||
rc = 0;
|
||||
|
||||
if (arg == 0) {
|
||||
acdb_id = 0;
|
||||
} else if (copy_from_user(&acdb_id,
|
||||
(void*) arg, sizeof(acdb_id))) {
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
mutex_lock(&aac_in_lock);
|
||||
if (file->private_data) {
|
||||
rc = -EBUSY;
|
||||
} else {
|
||||
file->private_data = q6audio_open_aac(
|
||||
BUFSZ, 48000, AUDIO_FLAG_READ, af, acdb_id);
|
||||
if (!file->private_data)
|
||||
rc = -ENOMEM;
|
||||
}
|
||||
mutex_unlock(&aac_in_lock);
|
||||
break;
|
||||
}
|
||||
case AUDIO_STOP:
|
||||
break;
|
||||
case AUDIO_FLUSH:
|
||||
break;
|
||||
case AUDIO_SET_CONFIG: {
|
||||
struct msm_audio_config config;
|
||||
if (copy_from_user(&config, (void*) arg, sizeof(config))) {
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
if (config.sample_rate != 48000)
|
||||
pr_info("only 48KHz AAC encode supported\n");
|
||||
af->channel_config = config.channel_count;
|
||||
break;
|
||||
}
|
||||
case AUDIO_GET_CONFIG: {
|
||||
struct msm_audio_config config;
|
||||
config.buffer_size = BUFSZ;
|
||||
config.buffer_count = 2;
|
||||
config.sample_rate = 48000;
|
||||
config.channel_count = af->channel_config;
|
||||
config.unused[0] = 0;
|
||||
config.unused[1] = 0;
|
||||
config.unused[2] = 0;
|
||||
if (copy_to_user((void*) arg, &config, sizeof(config))) {
|
||||
rc = -EFAULT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int aac_in_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
int rc;
|
||||
|
||||
pr_info("aac_in: open\n");
|
||||
mutex_lock(&aac_in_lock);
|
||||
if (aac_in_opened) {
|
||||
pr_err("aac_in: busy\n");
|
||||
rc = -EBUSY;
|
||||
} else {
|
||||
af = kzalloc(sizeof(*af), GFP_KERNEL);
|
||||
memset(af, 0, sizeof(struct aac_format));
|
||||
af->sample_rate = 3; /* 48000 */
|
||||
af->channel_config = 1;
|
||||
af->block_formats = AUDIO_AAC_FORMAT_ADTS;
|
||||
af->audio_object_type = 2; /* CAD to ADSP format */
|
||||
af->bit_rate = 192000;
|
||||
|
||||
aac_in_opened = 1;
|
||||
rc = 0;
|
||||
}
|
||||
mutex_unlock(&aac_in_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ssize_t aac_in_read(struct file *file, char __user *buf,
|
||||
size_t count, loff_t *pos)
|
||||
{
|
||||
struct audio_client *ac;
|
||||
struct audio_buffer *ab;
|
||||
const char __user *start = buf;
|
||||
int xfer, res = 0;
|
||||
|
||||
mutex_lock(&aac_in_lock);
|
||||
ac = file->private_data;
|
||||
if (!ac) {
|
||||
res = -ENODEV;
|
||||
goto fail;
|
||||
}
|
||||
while (count > 0) {
|
||||
ab = ac->buf + ac->cpu_buf;
|
||||
|
||||
if (ab->used)
|
||||
if (!wait_event_timeout(ac->wait, (ab->used == 0), 5*HZ)) {
|
||||
audio_client_dump(ac);
|
||||
pr_err("aac_read: timeout. dsp dead?\n");
|
||||
BUG();
|
||||
}
|
||||
|
||||
xfer = count;
|
||||
if (xfer > ab->size)
|
||||
xfer = ab->size;
|
||||
|
||||
if (copy_to_user(buf, ab->data, xfer)) {
|
||||
res = -EFAULT;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
buf += xfer;
|
||||
count -= xfer;
|
||||
|
||||
ab->used = 1;
|
||||
q6audio_read(ac, ab);
|
||||
ac->cpu_buf ^= 1;
|
||||
}
|
||||
fail:
|
||||
res = buf - start;
|
||||
mutex_unlock(&aac_in_lock);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int aac_in_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
int rc = 0;
|
||||
pr_info("aac_in: release\n");
|
||||
mutex_lock(&aac_in_lock);
|
||||
if (file->private_data)
|
||||
rc = q6audio_close(file->private_data);
|
||||
kfree(af);
|
||||
aac_in_opened = 0;
|
||||
mutex_unlock(&aac_in_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct file_operations aac_in_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = aac_in_open,
|
||||
.read = aac_in_read,
|
||||
.release = aac_in_release,
|
||||
.unlocked_ioctl = aac_in_ioctl,
|
||||
};
|
||||
|
||||
struct miscdevice aac_in_misc = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = "msm_aac_in",
|
||||
.fops = &aac_in_fops,
|
||||
};
|
||||
|
||||
static int __init aac_in_init(void) {
|
||||
return misc_register(&aac_in_misc);
|
||||
}
|
||||
|
||||
device_initcall(aac_in_init);
|
@ -25,20 +25,10 @@
|
||||
|
||||
#define BUFSZ (0)
|
||||
|
||||
#if 1
|
||||
#define AUDIO_INFO(x...) pr_info("Audio: "x)
|
||||
#else
|
||||
#define AUDIO_INFO(x...) do{}while(0)
|
||||
#endif
|
||||
|
||||
// from board-htcleo-accoustic
|
||||
extern int set_aux_gain(int level);
|
||||
|
||||
static DEFINE_MUTEX(voice_lock);
|
||||
static DEFINE_MUTEX(fm_lock);
|
||||
static int voice_started;
|
||||
static int fm_started;
|
||||
int global_now_phone_call;
|
||||
|
||||
static struct audio_client *voc_tx_clnt;
|
||||
static struct audio_client *voc_rx_clnt;
|
||||
@ -48,7 +38,6 @@ static int q6_voice_start(uint32_t rx_acdb_id, uint32_t tx_acdb_id)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
printk("VOICE START (%d %d)\n", rx_acdb_id, tx_acdb_id);
|
||||
mutex_lock(&voice_lock);
|
||||
|
||||
if (voice_started) {
|
||||
@ -56,7 +45,6 @@ static int q6_voice_start(uint32_t rx_acdb_id, uint32_t tx_acdb_id)
|
||||
rc = -EBUSY;
|
||||
goto done;
|
||||
}
|
||||
global_now_phone_call = 1;
|
||||
|
||||
voc_rx_clnt = q6voice_open(AUDIO_FLAG_WRITE, rx_acdb_id);
|
||||
if (!voc_rx_clnt) {
|
||||
@ -81,9 +69,7 @@ done:
|
||||
static int q6_voice_stop(void)
|
||||
{
|
||||
mutex_lock(&voice_lock);
|
||||
global_now_phone_call = 0;
|
||||
if (voice_started)
|
||||
{
|
||||
if (voice_started) {
|
||||
q6voice_close(voc_tx_clnt);
|
||||
q6voice_close(voc_rx_clnt);
|
||||
voice_started = 0;
|
||||
@ -141,12 +127,9 @@ static int q6_ioctl(struct inode *inode, struct file *file,
|
||||
uint32_t id[2];
|
||||
char filename[64];
|
||||
|
||||
// printk("$$$ AUDIO IOCTL=%08X\n", cmd);
|
||||
|
||||
switch (cmd) {
|
||||
case AUDIO_SWITCH_DEVICE:
|
||||
rc = copy_from_user(&id, (void *)arg, sizeof(id));
|
||||
AUDIO_INFO("SWITCH DEVICE %d, acdb %d\n", id[0], id[1]);
|
||||
if (!rc)
|
||||
rc = q6audio_do_routing(id[0], id[1]);
|
||||
break;
|
||||
@ -173,19 +156,15 @@ static int q6_ioctl(struct inode *inode, struct file *file,
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
AUDIO_INFO("voice: start\n");
|
||||
rc = q6_voice_start(id[0], id[1]);
|
||||
break;
|
||||
case AUDIO_STOP_VOICE:
|
||||
AUDIO_INFO("voice: stop\n");
|
||||
rc = q6_voice_stop();
|
||||
break;
|
||||
case AUDIO_START_FM:
|
||||
AUDIO_INFO("FM: start\n");
|
||||
rc = q6_fm_start();
|
||||
break;
|
||||
case AUDIO_STOP_FM:
|
||||
AUDIO_INFO("FM: stop\n");
|
||||
rc = q6_fm_stop();
|
||||
break;
|
||||
case AUDIO_REINIT_ACDB:
|
||||
@ -199,25 +178,9 @@ static int q6_ioctl(struct inode *inode, struct file *file,
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
AUDIO_INFO("audio_ctl: enable aux loopback %d\n", enable);
|
||||
rc = enable_aux_loopback(enable);
|
||||
break;
|
||||
}
|
||||
case AUDIO_SET_AUXPGA_GAIN: {
|
||||
int level;
|
||||
if (copy_from_user(&level, (void*) arg, sizeof(level))) {
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
AUDIO_INFO("audio_ctl: set aux gain %d\n", level);
|
||||
rc = set_aux_gain(level);
|
||||
break;
|
||||
}
|
||||
case AUDIO_SET_RX_MUTE:
|
||||
rc = copy_from_user(&n, (void *)arg, sizeof(n));
|
||||
if (!rc)
|
||||
rc = q6audio_set_rx_mute(n);
|
||||
break;
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
}
|
||||
|
@ -31,20 +31,20 @@
|
||||
#define DAL_TRACE 0
|
||||
|
||||
struct dal_hdr {
|
||||
uint32_t length:16; /* message length (header inclusive) */
|
||||
uint32_t version:8; /* DAL protocol version */
|
||||
uint32_t length:16; /* message length (header inclusive) */
|
||||
uint32_t version:8; /* DAL protocol version */
|
||||
uint32_t priority:7;
|
||||
uint32_t async:1;
|
||||
uint32_t ddi:16; /* DDI method number */
|
||||
uint32_t prototype:8; /* DDI serialization format */
|
||||
uint32_t msgid:8; /* message id (DDI, ATTACH, DETACH, ...) */
|
||||
uint32_t prototype:8; /* DDI serialization format */
|
||||
uint32_t msgid:8; /* message id (DDI, ATTACH, DETACH, ...) */
|
||||
void *from;
|
||||
void *to;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define TRACE_DATA_MAX 128
|
||||
#define TRACE_LOG_MAX 32
|
||||
#define TRACE_LOG_MASK (TRACE_LOG_MAX - 1)
|
||||
#define TRACE_DATA_MAX 128
|
||||
#define TRACE_LOG_MAX 32
|
||||
#define TRACE_LOG_MASK (TRACE_LOG_MAX - 1)
|
||||
|
||||
struct dal_trace {
|
||||
unsigned timestamp;
|
||||
@ -129,17 +129,17 @@ void dal_trace(struct dal_client *c)
|
||||
if (c->tr_log)
|
||||
return;
|
||||
c->tr_log = kzalloc(sizeof(struct dal_trace) * TRACE_LOG_MAX,
|
||||
GFP_KERNEL);
|
||||
GFP_KERNEL);
|
||||
}
|
||||
|
||||
void dal_trace_print(struct dal_hdr *hdr, unsigned *data, int len, unsigned when)
|
||||
{
|
||||
int i;
|
||||
printk("DAL %08x -> %08x L=%03x A=%d D=%04x P=%02x M=%02x T=%d",
|
||||
(unsigned) hdr->from, (unsigned) hdr->to,
|
||||
hdr->length, hdr->async,
|
||||
hdr->ddi, hdr->prototype, hdr->msgid,
|
||||
when);
|
||||
(unsigned) hdr->from, (unsigned) hdr->to,
|
||||
hdr->length, hdr->async,
|
||||
hdr->ddi, hdr->prototype, hdr->msgid,
|
||||
when);
|
||||
len /= 4;
|
||||
for (i = 0; i < len; i++) {
|
||||
if (!(i & 7))
|
||||
@ -226,7 +226,7 @@ again:
|
||||
}
|
||||
}
|
||||
pr_err("$$$ receiving unknown message len = %d $$$\n",
|
||||
dch->count);
|
||||
dch->count);
|
||||
dch->active = 0;
|
||||
dch->ptr = dch->data;
|
||||
}
|
||||
@ -262,7 +262,8 @@ check_data:
|
||||
if (client->event)
|
||||
client->event(dch->ptr, len, client->cookie);
|
||||
else
|
||||
pr_err("dal: client %p has no event handler\n", client);
|
||||
pr_err("dal: client %p has no event handler\n",
|
||||
client);
|
||||
goto again;
|
||||
}
|
||||
|
||||
@ -359,21 +360,20 @@ int dal_call_raw(struct dal_client *client,
|
||||
smd_write(dch->sch, data, data_len);
|
||||
spin_unlock_irqrestore(&dch->lock, flags);
|
||||
|
||||
if (!wait_event_timeout(client->wait, (client->status != -EBUSY), 5*HZ))
|
||||
{
|
||||
if (!wait_event_timeout(client->wait, (client->status != -EBUSY), 5*HZ)) {
|
||||
dal_trace_dump(client);
|
||||
pr_err("dal: call timed out. dsp is probably dead.\n");
|
||||
dal_trace_print(hdr, data, data_len, 0);
|
||||
// BUG();
|
||||
BUG();
|
||||
}
|
||||
|
||||
return client->status;
|
||||
}
|
||||
|
||||
int dal_call(struct dal_client *client,
|
||||
unsigned ddi, unsigned prototype,
|
||||
void *data, int data_len,
|
||||
void *reply, int reply_max)
|
||||
unsigned ddi, unsigned prototype,
|
||||
void *data, int data_len,
|
||||
void *reply, int reply_max)
|
||||
{
|
||||
struct dal_hdr hdr;
|
||||
int r;
|
||||
@ -394,11 +394,11 @@ int dal_call(struct dal_client *client,
|
||||
mutex_lock(&client->write_lock);
|
||||
r = dal_call_raw(client, &hdr, data, data_len, reply, reply_max);
|
||||
mutex_unlock(&client->write_lock);
|
||||
#if 1
|
||||
#if 0
|
||||
if ((r > 3) && (((uint32_t*) reply)[0] == 0)) {
|
||||
// pr_info("dal call OK\n");
|
||||
pr_info("dal call OK\n");
|
||||
} else {
|
||||
pr_info("dal call %d %d ERROR\n", ddi, prototype);
|
||||
pr_info("dal call ERROR\n");
|
||||
}
|
||||
#endif
|
||||
return r;
|
||||
@ -415,67 +415,8 @@ struct dal_reply_attach {
|
||||
char name[64];
|
||||
};
|
||||
|
||||
|
||||
struct dal_client *dal_attach_ex(uint32_t device_id, const char *aname, const char *name, dal_event_func_t func, void *cookie)
|
||||
{
|
||||
struct dal_hdr hdr;
|
||||
struct dal_msg_attach msg;
|
||||
struct dal_reply_attach reply;
|
||||
struct dal_channel *dch;
|
||||
struct dal_client *client;
|
||||
unsigned long flags;
|
||||
int r;
|
||||
|
||||
dch = dal_open_channel(name);
|
||||
if (!dch)
|
||||
return 0;
|
||||
|
||||
client = kzalloc(sizeof(*client), GFP_KERNEL);
|
||||
if (!client)
|
||||
return 0;
|
||||
|
||||
client->dch = dch;
|
||||
client->event = func;
|
||||
client->cookie = cookie;
|
||||
mutex_init(&client->write_lock);
|
||||
spin_lock_init(&client->tr_lock);
|
||||
init_waitqueue_head(&client->wait);
|
||||
|
||||
spin_lock_irqsave(&dch->lock, flags);
|
||||
list_add(&client->list, &dch->clients);
|
||||
spin_unlock_irqrestore(&dch->lock, flags);
|
||||
|
||||
memset(&hdr, 0, sizeof(hdr));
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
|
||||
hdr.length = sizeof(hdr) + sizeof(msg);
|
||||
hdr.version = DAL_VERSION;
|
||||
hdr.msgid = DAL_MSGID_ATTACH;
|
||||
hdr.from = client;
|
||||
msg.device_id = device_id;
|
||||
if (aname)
|
||||
strcpy(msg.attach, aname);
|
||||
|
||||
r = dal_call_raw(client, &hdr, &msg, sizeof(msg),
|
||||
&reply, sizeof(reply));
|
||||
|
||||
if ((r == sizeof(reply)) && (reply.status == 0)) {
|
||||
reply.name[63] = 0;
|
||||
pr_info("dal_attach: status = %d, name = '%s'\n",
|
||||
reply.status, reply.name);
|
||||
return client;
|
||||
}
|
||||
|
||||
pr_err("dal_attach: failure\n");
|
||||
|
||||
dal_detach(client);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct dal_client *dal_attach(uint32_t device_id, const char *name,
|
||||
dal_event_func_t func, void *cookie)
|
||||
dal_event_func_t func, void *cookie)
|
||||
{
|
||||
struct dal_hdr hdr;
|
||||
struct dal_msg_attach msg;
|
||||
@ -548,7 +489,7 @@ int dal_detach(struct dal_client *client)
|
||||
data = (uint32_t) client;
|
||||
|
||||
dal_call_raw(client, &hdr, &data, sizeof(data),
|
||||
&data, sizeof(data));
|
||||
&data, sizeof(data));
|
||||
}
|
||||
|
||||
dch = client->dch;
|
||||
@ -602,8 +543,7 @@ int dal_call_f1(struct dal_client *client, uint32_t ddi, uint32_t arg1, uint32_t
|
||||
|
||||
int dal_call_f5(struct dal_client *client, uint32_t ddi, void *ibuf, uint32_t ilen)
|
||||
{
|
||||
// uint32_t tmp[128];
|
||||
uint32_t tmp[DAL_DATA_MAX];
|
||||
uint32_t tmp[128];
|
||||
int res;
|
||||
int param_idx = 0;
|
||||
|
||||
@ -623,55 +563,23 @@ int dal_call_f5(struct dal_client *client, uint32_t ddi, void *ibuf, uint32_t il
|
||||
return res;
|
||||
}
|
||||
|
||||
int dal_call_f6(struct dal_client *client, uint32_t ddi, uint32_t cmd, void *ibuf, uint32_t ilen)
|
||||
{
|
||||
uint32_t tmp[DAL_DATA_MAX];
|
||||
int res;
|
||||
int param_idx = 0;
|
||||
|
||||
if (ilen + 4 > DAL_DATA_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
tmp[param_idx] = cmd;
|
||||
param_idx++;
|
||||
tmp[param_idx] = ilen;
|
||||
param_idx++;
|
||||
|
||||
memcpy(&tmp[param_idx], ibuf, ilen);
|
||||
param_idx += DIV_ROUND_UP(ilen, 4);
|
||||
|
||||
res = dal_call(client, ddi, 6, tmp, param_idx * 4, tmp, sizeof(tmp));
|
||||
|
||||
if (res >= 4)
|
||||
return (int) tmp[0];
|
||||
return res;
|
||||
}
|
||||
|
||||
int dal_call_f8(struct dal_client *client, uint32_t ddi, void *ibuf, uint32_t ilen, void *obuf, uint32_t olen)
|
||||
int dal_call_f9(struct dal_client *client, uint32_t ddi, void *obuf,
|
||||
uint32_t olen)
|
||||
{
|
||||
uint32_t tmp[128];
|
||||
int res;
|
||||
int param_idx = 0;
|
||||
|
||||
if (ilen + 8 > DAL_DATA_MAX)
|
||||
if (olen > sizeof(tmp) - 8)
|
||||
return -EINVAL;
|
||||
tmp[0] = olen;
|
||||
|
||||
tmp[param_idx] = ilen;
|
||||
param_idx++;
|
||||
|
||||
memcpy(&tmp[param_idx], ibuf, ilen);
|
||||
param_idx += DIV_ROUND_UP(ilen, 4);
|
||||
|
||||
tmp[param_idx++] = olen;
|
||||
res = dal_call(client, ddi, 8, tmp, param_idx * 4, tmp, sizeof(tmp));
|
||||
res = dal_call(client, ddi, 9, tmp, sizeof(uint32_t), tmp,
|
||||
sizeof(tmp));
|
||||
|
||||
if (res >= 4)
|
||||
{
|
||||
res = (int)tmp[0];
|
||||
}
|
||||
|
||||
if (!res)
|
||||
{
|
||||
if (!res) {
|
||||
if (tmp[1] > olen)
|
||||
return -EIO;
|
||||
memcpy(obuf, &tmp[2], tmp[1]);
|
||||
@ -679,37 +587,9 @@ int dal_call_f8(struct dal_client *client, uint32_t ddi, void *ibuf, uint32_t il
|
||||
return res;
|
||||
}
|
||||
|
||||
int dal_call_f9(struct dal_client *client, uint32_t ddi, void *obuf, uint32_t olen)
|
||||
{
|
||||
uint32_t tmp[128];
|
||||
int res;
|
||||
int param_idx = 0;
|
||||
|
||||
if (olen + 8 > DAL_DATA_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
tmp[param_idx++] = olen;
|
||||
res = dal_call(client, ddi, 9, tmp, param_idx * 4, tmp, sizeof(tmp));
|
||||
|
||||
if (res >= 4)
|
||||
{
|
||||
res = (int)tmp[0];
|
||||
}
|
||||
|
||||
if (!res)
|
||||
{
|
||||
if (tmp[1] > olen)
|
||||
return -EIO;
|
||||
memcpy(obuf, &tmp[2], tmp[1]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int dal_call_f13(struct dal_client *client, uint32_t ddi, void *ibuf1,
|
||||
uint32_t ilen1, void *ibuf2, uint32_t ilen2, void *obuf, uint32_t olen)
|
||||
uint32_t ilen1, void *ibuf2, uint32_t ilen2, void *obuf,
|
||||
uint32_t olen)
|
||||
{
|
||||
uint32_t tmp[128];
|
||||
int res;
|
||||
@ -742,5 +622,41 @@ int dal_call_f13(struct dal_client *client, uint32_t ddi, void *ibuf1,
|
||||
return res;
|
||||
}
|
||||
|
||||
int dal_call_f14(struct dal_client *client, uint32_t ddi, void *ibuf,
|
||||
uint32_t ilen, void *obuf1, uint32_t olen1, void *obuf2,
|
||||
uint32_t olen2, uint32_t *oalen2)
|
||||
{
|
||||
uint32_t tmp[128];
|
||||
int res;
|
||||
int param_idx = 0;
|
||||
|
||||
// END OF FILE
|
||||
if (olen1 + olen2 + 8 > DAL_DATA_MAX ||
|
||||
ilen + 12 > DAL_DATA_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
tmp[param_idx] = ilen;
|
||||
param_idx++;
|
||||
|
||||
memcpy(&tmp[param_idx], ibuf, ilen);
|
||||
param_idx += DIV_ROUND_UP(ilen, 4);
|
||||
|
||||
tmp[param_idx++] = olen1;
|
||||
tmp[param_idx++] = olen2;
|
||||
res = dal_call(client, ddi, 14, tmp, param_idx * 4, tmp, sizeof(tmp));
|
||||
|
||||
if (res >= 4)
|
||||
res = (int)tmp[0];
|
||||
|
||||
if (!res) {
|
||||
if (tmp[1] > olen1)
|
||||
return -EIO;
|
||||
param_idx = DIV_ROUND_UP(tmp[1], 4) + 2;
|
||||
if (tmp[param_idx] > olen2)
|
||||
return -EIO;
|
||||
|
||||
memcpy(obuf1, &tmp[2], tmp[1]);
|
||||
memcpy(obuf2, &tmp[param_idx+1], tmp[param_idx]);
|
||||
*oalen2 = tmp[param_idx];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -19,12 +19,16 @@
|
||||
|
||||
struct dal_client;
|
||||
|
||||
struct dal_info {
|
||||
uint32_t size;
|
||||
uint32_t version;
|
||||
char name[32];
|
||||
};
|
||||
|
||||
typedef void (*dal_event_func_t)(void *data, int len, void *cookie);
|
||||
|
||||
struct dal_client *dal_attach(uint32_t device_id, const char *name,
|
||||
dal_event_func_t func, void *cookie);
|
||||
struct dal_client *dal_attach_ex(uint32_t device_id, const char *aname,
|
||||
const char *name, dal_event_func_t func, void *cookie);
|
||||
|
||||
int dal_detach(struct dal_client *client);
|
||||
|
||||
@ -46,16 +50,14 @@ int dal_call_f1(struct dal_client *client, uint32_t ddi,
|
||||
uint32_t arg1, uint32_t arg2);
|
||||
int dal_call_f5(struct dal_client *client, uint32_t ddi,
|
||||
void *ibuf, uint32_t ilen);
|
||||
int dal_call_f6(struct dal_client *client, uint32_t ddi,
|
||||
uint32_t cmd, void *ibuf, uint32_t ilen);
|
||||
int dal_call_f8(struct dal_client *client, uint32_t ddi,
|
||||
void *ibuf, uint32_t ilen, void *obuf, uint32_t olen);
|
||||
int dal_call_f9(struct dal_client *client, uint32_t ddi,
|
||||
int dal_call_f9(struct dal_client *client, uint32_t ddi,
|
||||
void *obuf, uint32_t olen);
|
||||
|
||||
int dal_call_f13(struct dal_client *client, uint32_t ddi, void *ibuf1,
|
||||
uint32_t ilen1, void *ibuf2, uint32_t ilen2, void *obuf,
|
||||
uint32_t olen);
|
||||
int dal_call_f14(struct dal_client *client, uint32_t ddi, void *ibuf,
|
||||
uint32_t ilen, void *obuf1, uint32_t olen1, void *obuf2,
|
||||
uint32_t olen2, uint32_t *oalen2);
|
||||
|
||||
/* common DAL operations */
|
||||
enum {
|
||||
|
@ -27,11 +27,7 @@
|
||||
*/
|
||||
|
||||
#define ACDB_DAL_DEVICE 0x02000069
|
||||
#if defined(CONFIG_MACH_HTCLEO)
|
||||
#define ACDB_DAL_PORT "SMD_DAL00"
|
||||
#else
|
||||
#define ACDB_DAL_PORT "SMD_DAL_AM_AUD"
|
||||
#endif
|
||||
#define ACDB_DAL_PORT "SMD_DAL_AM_AUD"
|
||||
|
||||
#define ACDB_OP_IOCTL DAL_OP_FIRST_DEVICE_API
|
||||
|
||||
|
@ -32,11 +32,7 @@
|
||||
#include "dal.h"
|
||||
|
||||
#define ADIE_DAL_DEVICE 0x02000029
|
||||
#if defined(CONFIG_MACH_HTCLEO)
|
||||
#define ADIE_DAL_PORT "SMD_DAL00"
|
||||
#else
|
||||
#define ADIE_DAL_PORT "SMD_DAL_AM_AUD"
|
||||
#endif
|
||||
#define ADIE_DAL_PORT "SMD_DAL_AM_AUD"
|
||||
|
||||
enum {
|
||||
ADIE_OP_GET_NUM_PATHS = DAL_OP_FIRST_DEVICE_API,
|
||||
|
@ -2,15 +2,15 @@
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Code Aurora Forum nor
|
||||
* the names of its contributors may be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Code Aurora Forum nor
|
||||
* the names of its contributors may be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
@ -30,29 +30,15 @@
|
||||
#define __DAL_AUDIO_H__
|
||||
|
||||
#include "dal_audio_format.h"
|
||||
#include "dal.h"
|
||||
#include <mach/msm_qdsp6_audio.h>
|
||||
|
||||
#define AUDIO_DAL_DEVICE 0x02000028
|
||||
#define AUDIO_DAL_PORT "DSP_DAL_AQ_AUD"
|
||||
|
||||
enum
|
||||
{
|
||||
#if defined(CONFIG_MACH_HTCLEO)
|
||||
AUDIO_OP_OPEN = DAL_OP_FIRST_DEVICE_API,
|
||||
AUDIO_OP_WRITE,
|
||||
AUDIO_OP_READ,
|
||||
AUDIO_OP_IOCTL,
|
||||
AUDIO_OP_INIT,
|
||||
AUDIO_OP_CLOSE,
|
||||
AUDIO_OP_FLUSH
|
||||
#else
|
||||
enum {
|
||||
AUDIO_OP_CONTROL = DAL_OP_FIRST_DEVICE_API,
|
||||
AUDIO_OP_DATA,
|
||||
AUDIO_OP_INIT,
|
||||
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
/* ---- common audio structures ---- */
|
||||
|
||||
@ -60,37 +46,37 @@ enum
|
||||
/* buffer is a synchronization point or key frame, meaning no data */
|
||||
/* before it in the stream is required in order to render the stream */
|
||||
/* from this point onward. */
|
||||
#define ADSP_AUDIO_BUFFER_FLAG_SYNC_POINT 0x01
|
||||
#define ADSP_AUDIO_BUFFER_FLAG_SYNC_POINT 0x01
|
||||
|
||||
/* This flag, if set, indicates that the buffer object is using valid */
|
||||
/* physical address used to store the media data */
|
||||
#define ADSP_AUDIO_BUFFER_FLAG_PHYS_ADDR 0x04
|
||||
#define ADSP_AUDIO_BUFFER_FLAG_PHYS_ADDR 0x04
|
||||
|
||||
/* This flag, if set, indicates that a media start timestamp has been */
|
||||
/* set for a buffer. */
|
||||
#define ADSP_AUDIO_BUFFER_FLAG_START_SET 0x08
|
||||
#define ADSP_AUDIO_BUFFER_FLAG_START_SET 0x08
|
||||
|
||||
/* This flag, if set, indicates that a media stop timestamp has been set */
|
||||
/* for a buffer. */
|
||||
#define ADSP_AUDIO_BUFFER_FLAG_STOP_SET 0x10
|
||||
#define ADSP_AUDIO_BUFFER_FLAG_STOP_SET 0x10
|
||||
|
||||
/* This flag, if set, indicates that a preroll timestamp has been set */
|
||||
/* for a buffer. */
|
||||
#define ADSP_AUDIO_BUFFER_FLAG_PREROLL_SET 0x20
|
||||
#define ADSP_AUDIO_BUFFER_FLAG_PREROLL_SET 0x20
|
||||
|
||||
/* This flag, if set, indicates that the data in the buffer is a fragment of */
|
||||
/* a larger block of data, and will be continued by the data in the next */
|
||||
/* buffer to be delivered. */
|
||||
#define ADSP_AUDIO_BUFFER_FLAG_CONTINUATION 0x40
|
||||
#define ADSP_AUDIO_BUFFER_FLAG_CONTINUATION 0x40
|
||||
|
||||
struct adsp_audio_buffer {
|
||||
u32 addr; /* Physical Address of buffer */
|
||||
u32 max_size; /* Maximum size of buffer */
|
||||
u32 addr; /* Physical Address of buffer */
|
||||
u32 max_size; /* Maximum size of buffer */
|
||||
u32 actual_size; /* Actual size of valid data in the buffer */
|
||||
u32 offset; /* Offset to the first valid byte */
|
||||
u32 flags; /* ADSP_AUDIO_BUFFER_FLAGs that has been set */
|
||||
s64 start; /* Start timestamp, if any */
|
||||
s64 stop; /* Stop timestamp, if any */
|
||||
u32 offset; /* Offset to the first valid byte */
|
||||
u32 flags; /* ADSP_AUDIO_BUFFER_FLAGs that has been set */
|
||||
s64 start; /* Start timestamp, if any */
|
||||
s64 stop; /* Stop timestamp, if any */
|
||||
s64 preroll; /* Preroll timestamp, if any */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
@ -100,11 +86,10 @@ struct adsp_audio_buffer {
|
||||
|
||||
/* Command/event response types */
|
||||
#define ADSP_AUDIO_RESPONSE_COMMAND 0
|
||||
#define ADSP_AUDIO_RESPONSE_ASYNC 1
|
||||
#define ADSP_AUDIO_RESPONSE_ASYNC 1
|
||||
|
||||
#if !defined(CONFIG_MACH_HTCLEO)
|
||||
struct adsp_command_hdr {
|
||||
u32 size; /* sizeof(cmd) - sizeof(u32) */
|
||||
u32 size; /* sizeof(cmd) - sizeof(u32) */
|
||||
|
||||
u32 dst;
|
||||
u32 src;
|
||||
@ -119,21 +104,13 @@ struct adsp_command_hdr {
|
||||
u32 padding;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#else
|
||||
|
||||
struct adsp_command_hdr
|
||||
{
|
||||
u32 context;
|
||||
u32 data;
|
||||
} __attribute__ ((packed));
|
||||
#endif
|
||||
|
||||
#define AUDIO_DOMAIN_APP 0
|
||||
#define AUDIO_DOMAIN_MODEM 1
|
||||
#define AUDIO_DOMAIN_MODEM 1
|
||||
#define AUDIO_DOMAIN_DSP 2
|
||||
|
||||
#define AUDIO_SERVICE_AUDIO 0
|
||||
#define AUDIO_SERVICE_VIDEO 1 /* really? */
|
||||
#define AUDIO_SERVICE_AUDIO 0
|
||||
#define AUDIO_SERVICE_VIDEO 1 /* really? */
|
||||
|
||||
/* adsp audio addresses are (byte order) domain, service, major, minor */
|
||||
//#define AUDIO_ADDR(maj,min) ( (((maj) & 0xff) << 16) | (((min) & 0xff) << 24) | (1) )
|
||||
@ -147,17 +124,17 @@ struct adsp_command_hdr
|
||||
#define ADSP_AUDIO_ENC_ENHANCED_AAC_PLUS_MODE 2
|
||||
|
||||
struct adsp_audio_aac_enc_cfg {
|
||||
u32 bit_rate; /* bits per second */
|
||||
u32 encoder_mode; /* ADSP_AUDIO_ENC_* */
|
||||
u32 bit_rate; /* bits per second */
|
||||
u32 encoder_mode; /* ADSP_AUDIO_ENC_* */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define ADSP_AUDIO_ENC_SBC_ALLOCATION_METHOD_LOUNDNESS 0
|
||||
#define ADSP_AUDIO_ENC_SBC_ALLOCATION_METHOD_SNR 1
|
||||
#define ADSP_AUDIO_ENC_SBC_ALLOCATION_METHOD_LOUNDNESS 0
|
||||
#define ADSP_AUDIO_ENC_SBC_ALLOCATION_METHOD_SNR 1
|
||||
|
||||
#define ADSP_AUDIO_ENC_SBC_CHANNEL_MODE_MONO 1
|
||||
#define ADSP_AUDIO_ENC_SBC_CHANNEL_MODE_STEREO 2
|
||||
#define ADSP_AUDIO_ENC_SBC_CHANNEL_MODE_DUAL 8
|
||||
#define ADSP_AUDIO_ENC_SBC_CHANNEL_MODE_JOINT_STEREO 9
|
||||
#define ADSP_AUDIO_ENC_SBC_CHANNEL_MODE_MONO 1
|
||||
#define ADSP_AUDIO_ENC_SBC_CHANNEL_MODE_STEREO 2
|
||||
#define ADSP_AUDIO_ENC_SBC_CHANNEL_MODE_DUAL 8
|
||||
#define ADSP_AUDIO_ENC_SBC_CHANNEL_MODE_JOINT_STEREO 9
|
||||
|
||||
struct adsp_audio_sbc_encoder_cfg {
|
||||
u32 num_subbands;
|
||||
@ -168,36 +145,36 @@ struct adsp_audio_sbc_encoder_cfg {
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* AMR NB encoder modes */
|
||||
#define ADSP_AUDIO_AMR_MR475 0
|
||||
#define ADSP_AUDIO_AMR_MR515 1
|
||||
#define ADSP_AUDIO_AMR_MMR59 2
|
||||
#define ADSP_AUDIO_AMR_MMR67 3
|
||||
#define ADSP_AUDIO_AMR_MMR74 4
|
||||
#define ADSP_AUDIO_AMR_MMR795 5
|
||||
#define ADSP_AUDIO_AMR_MMR102 6
|
||||
#define ADSP_AUDIO_AMR_MMR122 7
|
||||
#define ADSP_AUDIO_AMR_MR475 0
|
||||
#define ADSP_AUDIO_AMR_MR515 1
|
||||
#define ADSP_AUDIO_AMR_MMR59 2
|
||||
#define ADSP_AUDIO_AMR_MMR67 3
|
||||
#define ADSP_AUDIO_AMR_MMR74 4
|
||||
#define ADSP_AUDIO_AMR_MMR795 5
|
||||
#define ADSP_AUDIO_AMR_MMR102 6
|
||||
#define ADSP_AUDIO_AMR_MMR122 7
|
||||
|
||||
/* The following are valid AMR NB DTX modes */
|
||||
#define ADSP_AUDIO_AMR_DTX_MODE_OFF 0
|
||||
#define ADSP_AUDIO_AMR_DTX_MODE_ON_VAD1 1
|
||||
#define ADSP_AUDIO_AMR_DTX_MODE_ON_VAD2 2
|
||||
#define ADSP_AUDIO_AMR_DTX_MODE_ON_AUTO 3
|
||||
#define ADSP_AUDIO_AMR_DTX_MODE_ON_VAD1 1
|
||||
#define ADSP_AUDIO_AMR_DTX_MODE_ON_VAD2 2
|
||||
#define ADSP_AUDIO_AMR_DTX_MODE_ON_AUTO 3
|
||||
|
||||
/* AMR Encoder configuration */
|
||||
struct adsp_audio_amr_enc_cfg {
|
||||
u32 mode; /* ADSP_AUDIO_AMR_MR* */
|
||||
u32 dtx_mode; /* ADSP_AUDIO_AMR_DTX_MODE* */
|
||||
u32 enable; /* 1 = enable, 0 = disable */
|
||||
u32 mode; /* ADSP_AUDIO_AMR_MR* */
|
||||
u32 dtx_mode; /* ADSP_AUDIO_AMR_DTX_MODE* */
|
||||
u32 enable; /* 1 = enable, 0 = disable */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct adsp_audio_qcelp13k_enc_cfg {
|
||||
u16 min_rate;
|
||||
u16 max_rate;
|
||||
u16 min_rate;
|
||||
u16 max_rate;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct adsp_audio_evrc_enc_cfg {
|
||||
u16 min_rate;
|
||||
u16 max_rate;
|
||||
u16 min_rate;
|
||||
u16 max_rate;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
union adsp_audio_codec_config {
|
||||
@ -220,9 +197,8 @@ union adsp_audio_codec_config {
|
||||
#define ADSP_AUDIO_OPEN_STREAM_MODE_SR_CM_NOTIFY 0x0002
|
||||
|
||||
/* This bit, if set, indicates that the sync clock is enabled */
|
||||
#define ADSP_AUDIO_OPEN_STREAM_MODE_ENABLE_SYNC_CLOCK 0x0004
|
||||
#define ADSP_AUDIO_OPEN_STREAM_MODE_ENABLE_SYNC_CLOCK 0x0004
|
||||
|
||||
#if !defined(CONFIG_MACH_HTCLEO)
|
||||
struct adsp_open_command {
|
||||
struct adsp_command_hdr hdr;
|
||||
|
||||
@ -238,52 +214,22 @@ struct adsp_open_command {
|
||||
union adsp_audio_codec_config config;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Opcode to open a device stream session to capture audio */
|
||||
#define ADSP_AUDIO_IOCTL_CMD_OPEN_READ 0x0108dd79
|
||||
|
||||
/* Opcode to open a device stream session to render audio */
|
||||
#define ADSP_AUDIO_IOCTL_CMD_OPEN_WRITE 0x0108dd7a
|
||||
|
||||
/* Opcode to open a device session, must open a device */
|
||||
#define ADSP_AUDIO_IOCTL_CMD_OPEN_DEVICE 0x0108dd7b
|
||||
|
||||
/* Close an existing stream or device */
|
||||
#define ADSP_AUDIO_IOCTL_CMD_CLOSE 0x0108d8bc
|
||||
|
||||
#else
|
||||
|
||||
struct adsp_open_command
|
||||
{
|
||||
struct adsp_command_hdr hdr;
|
||||
|
||||
u32 opcode;
|
||||
u32 numdev;
|
||||
u32 dev[4];
|
||||
u32 stream_context;
|
||||
|
||||
u32 format;
|
||||
u32 pblock;
|
||||
u32 blocklen;
|
||||
|
||||
u32 buf_max_size;
|
||||
u32 priority;
|
||||
|
||||
union adsp_audio_codec_config config;
|
||||
u32 mode;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* --- audio control and stream session ioctls ---- */
|
||||
|
||||
/* Opcode to open a device stream session to capture audio */
|
||||
#define ADSP_AUDIO_OPCODE_OPEN_READ 0x01
|
||||
#define ADSP_AUDIO_IOCTL_CMD_OPEN_READ 0x0108dd79
|
||||
|
||||
/* Opcode to open a device stream session to render audio */
|
||||
#define ADSP_AUDIO_OPCODE_OPEN_WRITE 0x02
|
||||
#define ADSP_AUDIO_IOCTL_CMD_OPEN_WRITE 0x0108dd7a
|
||||
|
||||
/* Opcode to open a device session, must open a device */
|
||||
#define ADSP_AUDIO_OPCODE_OPEN_DEV 0x04
|
||||
#define ADSP_AUDIO_IOCTL_CMD_OPEN_DEVICE 0x0108dd7b
|
||||
|
||||
/* Close an existing stream or device */
|
||||
#define ADSP_AUDIO_IOCTL_CMD_CLOSE 0x0108d8bc
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/* A device switch requires three IOCTL */
|
||||
/* commands in the following sequence: PREPARE, STANDBY, COMMIT */
|
||||
@ -320,7 +266,7 @@ struct adsp_device_switch_command {
|
||||
|
||||
#define ADSP_PATH_RX 0
|
||||
#define ADSP_PATH_TX 1
|
||||
#define ADSP_PATH_BOTH 2
|
||||
#define ADSP_PATH_BOTH 2
|
||||
|
||||
/* These commands will affect a logical device and all its associated */
|
||||
/* streams. */
|
||||
@ -405,13 +351,13 @@ struct adsp_buffer_command {
|
||||
|
||||
/* Do sample slipping/stuffing on AAC outputs. The payload of */
|
||||
/* this command is struct adsp_audio_slip_sample_command. */
|
||||
#define ADSP_AUDIO_IOCTL_CMD_STREAM_SLIPSAMPLE 0x0108d40e
|
||||
#define ADSP_AUDIO_IOCTL_CMD_STREAM_SLIPSAMPLE 0x0108d40e
|
||||
|
||||
/* Set stream volume. */
|
||||
/* This command has data payload, struct adsp_audio_set_volume_command. */
|
||||
#define ADSP_AUDIO_IOCTL_CMD_SET_STREAM_VOL 0x0108c0de
|
||||
|
||||
/* Set stream stereo volume. This command has data payl oad, */
|
||||
/* Set stream stereo volume. This command has data payload, */
|
||||
/* struct adsp_audio_set_stereo_volume_command. */
|
||||
#define ADSP_AUDIO_IOCTL_SET_STREAM_STEREO_VOL 0x0108dd7c
|
||||
|
||||
@ -469,39 +415,20 @@ struct adsp_buffer_command {
|
||||
|
||||
/* Set session stereo volume. This command has data payload, */
|
||||
/* struct adsp_audio_set_stereo_volume_command. */
|
||||
#define ADSP_AUDIO_IOCTL_SET_SESSION_STEREO_VOL 0x0108df3d
|
||||
#define ADSP_AUDIO_IOCTL_SET_SESSION_STEREO_VOL 0x0108df3d
|
||||
|
||||
/* Set L, R cross channel gain for a session. This command has */
|
||||
/* data payload, struct adsp_audio_set_x_chan_gain_command. */
|
||||
#define ADSP_AUDIO_IOCTL_SET_SESSION_XCHAN_GAIN 0x0108df3f
|
||||
#define ADSP_AUDIO_IOCTL_SET_SESSION_XCHAN_GAIN 0x0108df3f
|
||||
|
||||
/* Set Session mute state. */
|
||||
/* This command has data payload, struct adsp_audio_set_mute_command. */
|
||||
#define ADSP_AUDIO_IOCTL_SET_SESSION_MUTE 0x0108d8be
|
||||
#define ADSP_AUDIO_IOCTL_SET_SESSION_MUTE 0x0108d8be
|
||||
|
||||
/* Configure Equalizer for a stream. */
|
||||
/* This command has payload struct adsp_audio_set_equalizer_command. */
|
||||
#define ADSP_AUDIO_IOCTL_SET_SESSION_EQ_CONFIG 0x0108c0e0
|
||||
|
||||
#define ADSP_AUDIO_MAX_EQ_BANDS 12
|
||||
|
||||
/* Definition for any one band of Equalizer. */
|
||||
struct adsp_audio_eq_band {
|
||||
u16 band_idx;
|
||||
u32 filter_type;
|
||||
u32 center_freq_hz;
|
||||
s32 filter_gain;
|
||||
s32 q_factor;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct adsp_audio_set_equalizer_command {
|
||||
struct adsp_command_hdr hdr;
|
||||
u32 enable;
|
||||
u32 num_bands;
|
||||
struct adsp_audio_eq_band eq_bands[ADSP_AUDIO_MAX_EQ_BANDS];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/* Set Audio Video sync information. */
|
||||
/* This command has data payload, struct adsp_audio_set_av_sync_command. */
|
||||
#define ADSP_AUDIO_IOCTL_SET_SESSION_AVSYNC 0x0108d1e2
|
||||
@ -531,34 +458,33 @@ struct adsp_set_mute_command {
|
||||
/* event id after the IOCTL command has been executed. */
|
||||
|
||||
/* This event is generated after a media stream session is opened. */
|
||||
#define ADSP_AUDIO_EVT_STATUS_OPEN 0x0108c0d6
|
||||
#define ADSP_AUDIO_EVT_STATUS_OPEN 0x0108c0d6
|
||||
|
||||
/* This event is generated after a media stream session is closed. */
|
||||
#define ADSP_AUDIO_EVT_STATUS_CLOSE 0x0108c0d7
|
||||
#define ADSP_AUDIO_EVT_STATUS_CLOSE 0x0108c0d7
|
||||
|
||||
/* Asyncronous buffer consumption. This event is generated after a */
|
||||
/* recived buffer is consumed during rendering or filled during */
|
||||
/* capture opeartion. */
|
||||
#define ADSP_AUDIO_EVT_STATUS_BUF_DONE 0x0108c0d8
|
||||
#define ADSP_AUDIO_EVT_STATUS_BUF_DONE 0x0108c0d8
|
||||
|
||||
/* This event is generated when rendering operation is starving for */
|
||||
/* data. In order to avoid audio loss at the end of a plauback, the */
|
||||
/* client should wait for this event before issuing the close command. */
|
||||
#define ADSP_AUDIO_EVT_STATUS_BUF_UNDERRUN 0x0108c0d9
|
||||
#define ADSP_AUDIO_EVT_STATUS_BUF_UNDERRUN 0x0108c0d9
|
||||
|
||||
/* This event is generated during capture operation when there are no */
|
||||
/* buffers available to copy the captured audio data */
|
||||
#define ADSP_AUDIO_EVT_STATUS_BUF_OVERFLOW 0x0108c0da
|
||||
#define ADSP_AUDIO_EVT_STATUS_BUF_OVERFLOW 0x0108c0da
|
||||
|
||||
/* This asynchronous event is generated as a result of an input */
|
||||
/* sample rate change and/or channel mode change detected by the */
|
||||
/* decoder. The event payload data is an array of 2 uint32 */
|
||||
/* values containing the sample rate in Hz and channel mode. */
|
||||
#define ADSP_AUDIO_EVT_SR_CM_CHANGE 0x0108d329
|
||||
#define ADSP_AUDIO_EVT_SR_CM_CHANGE 0x0108d329
|
||||
|
||||
struct adsp_event_hdr
|
||||
{
|
||||
u32 evt_handle; /* DAL common header */
|
||||
struct adsp_event_hdr {
|
||||
u32 evt_handle; /* DAL common header */
|
||||
u32 evt_cookie;
|
||||
u32 evt_length;
|
||||
|
||||
@ -575,48 +501,17 @@ struct adsp_event_hdr
|
||||
u32 status;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#if defined(CONFIG_MACH_HTCLEO)
|
||||
union adsp_event_data
|
||||
{
|
||||
u32 val32;
|
||||
uint8_t data[32];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
struct adsp_audio_event
|
||||
{
|
||||
struct adsp_command_hdr hdr;
|
||||
u32 session;
|
||||
u32 event_id;
|
||||
u32 status;
|
||||
u32 datalen;
|
||||
union adsp_event_data data;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
struct adsp_audio_dal_event
|
||||
{
|
||||
u32 cb_evt;
|
||||
u32 loc_evt;
|
||||
u32 size;
|
||||
struct adsp_audio_event ae;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#else
|
||||
struct adsp_buffer_event
|
||||
{
|
||||
struct adsp_buffer_event {
|
||||
struct adsp_event_hdr hdr;
|
||||
struct adsp_audio_buffer buffer;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* ---- audio device IDs ---- */
|
||||
|
||||
/* Device direction Rx/Tx flag */
|
||||
#define ADSP_AUDIO_RX_DEVICE 0x00
|
||||
#define ADSP_AUDIO_TX_DEVICE 0x01
|
||||
#define ADSP_AUDIO_RX_DEVICE 0x00
|
||||
#define ADSP_AUDIO_TX_DEVICE 0x01
|
||||
|
||||
/* Default RX or TX device */
|
||||
#define ADSP_AUDIO_DEVICE_ID_DEFAULT 0x1081679
|
||||
@ -631,18 +526,18 @@ struct adsp_buffer_event
|
||||
|
||||
/* Special loopback pseudo device to be paired with an RX device */
|
||||
/* with usage ADSP_AUDIO_DEVICE_USAGE_MIXED_PCM_LOOPBACK */
|
||||
#define ADSP_AUDIO_DEVICE_ID_MIXED_PCM_LOOPBACK_TX 0x1089bf2
|
||||
#define ADSP_AUDIO_DEVICE_ID_MIXED_PCM_LOOPBACK_TX 0x1089bf2
|
||||
|
||||
/* Sink (RX) devices */
|
||||
#define ADSP_AUDIO_DEVICE_ID_HANDSET_SPKR 0x107ac88
|
||||
#define ADSP_AUDIO_DEVICE_ID_HEADSET_SPKR_MONO 0x1081511
|
||||
#define ADSP_AUDIO_DEVICE_ID_HEADSET_SPKR_STEREO 0x107ac8a
|
||||
#define ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MONO 0x1081513
|
||||
#define ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MONO_W_MONO_HEADSET 0x108c508
|
||||
#define ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MONO_W_MONO_HEADSET 0x108c508
|
||||
#define ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MONO_W_STEREO_HEADSET 0x108c894
|
||||
#define ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_STEREO 0x1081514
|
||||
#define ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_STEREO 0x1081514
|
||||
#define ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_STEREO_W_MONO_HEADSET 0x108c895
|
||||
#define ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_STEREO_W_STEREO_HEADSET 0x108c509
|
||||
#define ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_STEREO_W_STEREO_HEADSET 0x108c509
|
||||
#define ADSP_AUDIO_DEVICE_ID_BT_SCO_SPKR 0x1081519
|
||||
#define ADSP_AUDIO_DEVICE_ID_TTY_HEADSET_SPKR 0x108151c
|
||||
#define ADSP_AUDIO_DEVICE_ID_I2S_SPKR 0x1089bf4
|
||||
@ -652,11 +547,11 @@ struct adsp_buffer_event
|
||||
/* This device must be paired with */
|
||||
/* ADSP_AUDIO_DEVICE_ID_MIXED_PCM_LOOPBACK_TX using */
|
||||
/* ADSP_AUDIO_DEVICE_USAGE_MIXED_PCM_LOOPBACK mode */
|
||||
#define ADSP_AUDIO_DEVICE_ID_BT_A2DP_SPKR 0x108151a
|
||||
#define ADSP_AUDIO_DEVICE_ID_BT_A2DP_SPKR 0x108151a
|
||||
|
||||
/* Voice Destination identifier - specifically used for */
|
||||
/* controlling Voice module from the Device Control Session */
|
||||
#define ADSP_AUDIO_DEVICE_ID_VOICE 0x0108df3c
|
||||
#define ADSP_AUDIO_DEVICE_ID_VOICE 0x0108df3c
|
||||
|
||||
/* Audio device usage types. */
|
||||
/* This is a bit mask to determine which topology to use in the */
|
||||
@ -667,24 +562,4 @@ struct adsp_buffer_event
|
||||
#define ADSP_AUDIO_DEVICE_CONTEXT_RECORD 0x20
|
||||
#define ADSP_AUDIO_DEVICE_CONTEXT_PCM_LOOPBACK 0x40
|
||||
|
||||
/* for EQ */
|
||||
#define CAD_EQ_INVALID_DATA 0xFFFFFFFF
|
||||
|
||||
/* Equalizer filter band types */
|
||||
#define ADSP_AUDIO_EQUALIZER_TYPE_NONE 0
|
||||
#define ADSP_AUDIO_EQUALIZER_BASS_BOOST 1
|
||||
#define ADSP_AUDIO_EQUALIZER_BASS_CUT 2
|
||||
#define ADSP_AUDIO_EQUALIZER_TREBLE_BOOST 3
|
||||
#define ADSP_AUDIO_EQUALIZER_TREBLE_CUT 4
|
||||
#define ADSP_AUDIO_EQUALIZER_BAND_BOOST 5
|
||||
#define ADSP_AUDIO_EQUALIZER_BAND_CUT 6
|
||||
|
||||
struct cad_audio_eq_cfg {
|
||||
u32 enable;
|
||||
u32 num_bands;
|
||||
struct adsp_audio_eq_band eq_bands[ADSP_AUDIO_MAX_EQ_BANDS];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
int q6audio_set_stream_eq(struct audio_client *ac, struct cad_audio_eq_cfg *eq_cfg);
|
||||
|
||||
#endif
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include <linux/msm_audio.h>
|
||||
|
||||
#include <mach/msm_qdsp6_audio.h>
|
||||
#include "dal_audio.h"
|
||||
|
||||
#define BUFSZ (8192)
|
||||
#define DMASZ (BUFSZ * 2)
|
||||
@ -40,7 +39,6 @@ struct mp3 {
|
||||
static long mp3_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct mp3 *mp3 = file->private_data;
|
||||
struct cad_audio_eq_cfg eq_cfg;
|
||||
int rc = 0;
|
||||
|
||||
if (cmd == AUDIO_GET_STATS) {
|
||||
@ -62,14 +60,6 @@ static long mp3_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
rc = q6audio_set_stream_volume(mp3->ac, vol);
|
||||
break;
|
||||
}
|
||||
case AUDIO_SET_EQ: {
|
||||
if (copy_from_user(&eq_cfg, (void *)arg, sizeof(struct cad_audio_eq_cfg))) {
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
rc = q6audio_set_stream_eq(mp3->ac, &eq_cfg);
|
||||
break;
|
||||
}
|
||||
case AUDIO_START: {
|
||||
uint32_t acdb_id;
|
||||
if (arg == 0) {
|
||||
|
@ -66,35 +66,10 @@
|
||||
#define TRACE(fmt,x...) \
|
||||
do { pr_debug("%s:%d " fmt, __func__, __LINE__, ##x); } while (0)
|
||||
#else
|
||||
#define TRACE(fmt,x...) do { } while (0)
|
||||
#define TRACE(fmt, x...) do { } while (0)
|
||||
#endif
|
||||
|
||||
|
||||
static DEFINE_MUTEX(idlecount_lock);
|
||||
static int idlecount;
|
||||
static struct wake_lock wakelock;
|
||||
static struct wake_lock idlelock;
|
||||
|
||||
static void prevent_sleep(void)
|
||||
{
|
||||
mutex_lock(&idlecount_lock);
|
||||
if (++idlecount == 1) {
|
||||
wake_lock(&idlelock);
|
||||
wake_lock(&wakelock);
|
||||
}
|
||||
mutex_unlock(&idlecount_lock);
|
||||
}
|
||||
|
||||
static void allow_sleep(void)
|
||||
{
|
||||
mutex_lock(&idlecount_lock);
|
||||
if (--idlecount == 0) {
|
||||
wake_unlock(&idlelock);
|
||||
wake_unlock(&wakelock);
|
||||
}
|
||||
mutex_unlock(&idlecount_lock);
|
||||
}
|
||||
|
||||
#define MAX_SUPPORTED_INSTANCES 2
|
||||
|
||||
enum {
|
||||
VDEC_DALRPC_INITIALIZE = DAL_OP_FIRST_DEVICE_API,
|
||||
@ -162,6 +137,31 @@ static struct cdev vdec_cdev;
|
||||
static int ref_cnt;
|
||||
static DEFINE_MUTEX(vdec_ref_lock);
|
||||
|
||||
static DEFINE_MUTEX(idlecount_lock);
|
||||
static int idlecount;
|
||||
static struct wake_lock wakelock;
|
||||
static struct wake_lock idlelock;
|
||||
|
||||
static void prevent_sleep(void)
|
||||
{
|
||||
mutex_lock(&idlecount_lock);
|
||||
if (++idlecount == 1) {
|
||||
wake_lock(&idlelock);
|
||||
wake_lock(&wakelock);
|
||||
}
|
||||
mutex_unlock(&idlecount_lock);
|
||||
}
|
||||
|
||||
static void allow_sleep(void)
|
||||
{
|
||||
mutex_lock(&idlecount_lock);
|
||||
if (--idlecount == 0) {
|
||||
wake_unlock(&idlelock);
|
||||
wake_unlock(&wakelock);
|
||||
}
|
||||
mutex_unlock(&idlecount_lock);
|
||||
}
|
||||
|
||||
static inline int vdec_check_version(u32 client, u32 server)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
@ -447,6 +447,8 @@ static int vdec_queue(struct vdec_data *vd, void *argp)
|
||||
rpc.size = sizeof(struct vdec_input_buf_info);
|
||||
rpc.osize = sizeof(struct vdec_queue_status);
|
||||
|
||||
/* complete the writes to the buffer */
|
||||
wmb();
|
||||
ret = dal_call(vd->vdec_handle, VDEC_DALRPC_QUEUE, 8,
|
||||
&rpc, sizeof(rpc), &rpc_res, sizeof(rpc_res));
|
||||
if (ret < 4) {
|
||||
@ -587,6 +589,22 @@ static int vdec_freebuffers(struct vdec_data *vd, void *argp)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int vdec_getversion(struct vdec_data *vd, void *argp)
|
||||
{
|
||||
struct vdec_version ver_info;
|
||||
int ret = 0;
|
||||
|
||||
ver_info.major = VDEC_GET_MAJOR_VERSION(VDEC_INTERFACE_VERSION);
|
||||
ver_info.minor = VDEC_GET_MINOR_VERSION(VDEC_INTERFACE_VERSION);
|
||||
|
||||
ret = copy_to_user(((struct vdec_version *)argp),
|
||||
&ver_info, sizeof(ver_info));
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
static long vdec_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct vdec_data *vd = file->private_data;
|
||||
@ -638,6 +656,9 @@ static long vdec_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
|
||||
if (vd->close_decode)
|
||||
ret = -EINTR;
|
||||
else
|
||||
/* order the reads from the buffer */
|
||||
rmb();
|
||||
break;
|
||||
|
||||
case VDEC_IOCTL_CLOSE:
|
||||
@ -663,7 +684,15 @@ static long vdec_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
pr_err("%s: remote function failed (%d)\n",
|
||||
__func__, ret);
|
||||
break;
|
||||
case VDEC_IOCTL_GETVERSION:
|
||||
TRACE("VDEC_IOCTL_GETVERSION (pid=%d tid=%d)\n",
|
||||
current->group_leader->pid, current->pid);
|
||||
ret = vdec_getversion(vd, argp);
|
||||
|
||||
if (ret)
|
||||
pr_err("%s: remote function failed (%d)\n",
|
||||
__func__, ret);
|
||||
break;
|
||||
default:
|
||||
pr_err("%s: invalid ioctl!\n", __func__);
|
||||
ret = -EINVAL;
|
||||
@ -684,7 +713,8 @@ static void vdec_dcdone_handler(struct vdec_data *vd, void *frame,
|
||||
unsigned long flags;
|
||||
int found = 0;
|
||||
|
||||
if (frame_size != sizeof(struct vdec_frame_info)) {
|
||||
/*if (frame_size != sizeof(struct vdec_frame_info)) {*/
|
||||
if (frame_size < sizeof(struct vdec_frame_info)) {
|
||||
pr_warning("%s: msg size mismatch %d != %d\n", __func__,
|
||||
frame_size, sizeof(struct vdec_frame_info));
|
||||
return;
|
||||
@ -768,13 +798,14 @@ static int vdec_open(struct inode *inode, struct file *file)
|
||||
int i;
|
||||
struct vdec_msg_list *l;
|
||||
struct vdec_data *vd;
|
||||
struct dal_info version_info;
|
||||
|
||||
pr_info("q6vdec_open()\n");
|
||||
mutex_lock(&vdec_ref_lock);
|
||||
if (ref_cnt > 0) {
|
||||
pr_err("%s: Instance alredy running\n", __func__);
|
||||
if (ref_cnt >= MAX_SUPPORTED_INSTANCES) {
|
||||
pr_err("%s: Max allowed instances exceeded \n", __func__);
|
||||
mutex_unlock(&vdec_ref_lock);
|
||||
return -ENOMEM;
|
||||
return -EBUSY;
|
||||
}
|
||||
ref_cnt++;
|
||||
mutex_unlock(&vdec_ref_lock);
|
||||
@ -813,11 +844,26 @@ static int vdec_open(struct inode *inode, struct file *file)
|
||||
ret = -EIO;
|
||||
goto vdec_open_err_handle_list;
|
||||
}
|
||||
ret = dal_call_f9(vd->vdec_handle, DAL_OP_INFO,
|
||||
&version_info, sizeof(struct dal_info));
|
||||
|
||||
if (ret) {
|
||||
pr_err("%s: failed to get version \n", __func__);
|
||||
goto vdec_open_err_handle_version;
|
||||
}
|
||||
|
||||
TRACE("q6vdec_open() interface version 0x%x\n", version_info.version);
|
||||
if (vdec_check_version(VDEC_INTERFACE_VERSION,
|
||||
version_info.version)) {
|
||||
pr_err("%s: driver version mismatch !\n", __func__);
|
||||
goto vdec_open_err_handle_version;
|
||||
}
|
||||
|
||||
vd->running = 1;
|
||||
prevent_sleep();
|
||||
return 0;
|
||||
|
||||
vdec_open_err_handle_version:
|
||||
dal_detach(vd->vdec_handle);
|
||||
vdec_open_err_handle_list:
|
||||
{
|
||||
struct vdec_msg_list *l, *n;
|
||||
@ -827,6 +873,9 @@ vdec_open_err_handle_list:
|
||||
}
|
||||
}
|
||||
vdec_open_err_handle_vd:
|
||||
mutex_lock(&vdec_ref_lock);
|
||||
ref_cnt--;
|
||||
mutex_unlock(&vdec_ref_lock);
|
||||
kfree(vd);
|
||||
return ret;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -26,12 +26,12 @@
|
||||
|
||||
#include <mach/msm_qdsp6_audio.h>
|
||||
|
||||
#define BUFSZ (4096)
|
||||
#define DMASZ (BUFSZ * 2)
|
||||
#define BUFSZ (256)
|
||||
|
||||
static DEFINE_MUTEX(pcm_in_lock);
|
||||
static uint32_t sample_rate = 8000;
|
||||
static uint32_t channel_count = 1;
|
||||
static uint32_t buffer_size = BUFSZ;
|
||||
static int pcm_in_opened = 0;
|
||||
|
||||
void audio_client_dump(struct audio_client *ac);
|
||||
@ -66,7 +66,7 @@ static long q6_in_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
rc = -EBUSY;
|
||||
} else {
|
||||
file->private_data = q6audio_open_pcm(
|
||||
BUFSZ, sample_rate, channel_count,
|
||||
buffer_size, sample_rate, channel_count,
|
||||
AUDIO_FLAG_READ, acdb_id);
|
||||
if (!file->private_data)
|
||||
rc = -ENOMEM;
|
||||
@ -84,13 +84,26 @@ static long q6_in_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
if (!config.channel_count || config.channel_count > 2) {
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
if (config.sample_rate < 8000 || config.sample_rate > 48000) {
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
if (config.buffer_size < 128 || config.buffer_size > 8192) {
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
sample_rate = config.sample_rate;
|
||||
channel_count = config.channel_count;
|
||||
buffer_size = config.buffer_size;
|
||||
break;
|
||||
}
|
||||
case AUDIO_GET_CONFIG: {
|
||||
struct msm_audio_config config;
|
||||
config.buffer_size = BUFSZ;
|
||||
config.buffer_size = buffer_size;
|
||||
config.buffer_count = 2;
|
||||
config.sample_rate = sample_rate;
|
||||
config.channel_count = channel_count;
|
||||
@ -147,7 +160,7 @@ static ssize_t q6_in_read(struct file *file, char __user *buf,
|
||||
if (!wait_event_timeout(ac->wait, (ab->used == 0), 5*HZ)) {
|
||||
audio_client_dump(ac);
|
||||
pr_err("pcm_read: timeout. dsp dead?\n");
|
||||
// BUG();
|
||||
BUG();
|
||||
}
|
||||
|
||||
xfer = count;
|
||||
|
@ -25,33 +25,24 @@
|
||||
#include <linux/msm_audio.h>
|
||||
|
||||
#include <mach/msm_qdsp6_audio.h>
|
||||
#include "dal_audio.h"
|
||||
|
||||
#if 0
|
||||
#define AUDIO_INFO(x...) pr_info("Audio: "x)
|
||||
#else
|
||||
#define AUDIO_INFO(x...) do{}while(0)
|
||||
#endif
|
||||
|
||||
void audio_client_dump(struct audio_client *ac);
|
||||
|
||||
#define BUFSZ (4096) //(3072)
|
||||
#define DMASZ (BUFSZ * 2)
|
||||
#define BUFSZ (3072)
|
||||
|
||||
struct pcm {
|
||||
struct mutex lock;
|
||||
struct audio_client *ac;
|
||||
uint32_t sample_rate;
|
||||
uint32_t channel_count;
|
||||
size_t buffer_size;
|
||||
};
|
||||
|
||||
static long pcm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct pcm *pcm = file->private_data;
|
||||
struct cad_audio_eq_cfg eq_cfg;
|
||||
int rc = 0;
|
||||
|
||||
AUDIO_INFO("%s: %X %X\n", __func__, cmd, arg);
|
||||
if (cmd == AUDIO_GET_STATS) {
|
||||
struct msm_audio_stats stats;
|
||||
memset(&stats, 0, sizeof(stats));
|
||||
@ -71,14 +62,6 @@ static long pcm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
rc = q6audio_set_stream_volume(pcm->ac, vol);
|
||||
break;
|
||||
}
|
||||
case AUDIO_SET_EQ: {
|
||||
if (copy_from_user(&eq_cfg, (void *)arg, sizeof(struct cad_audio_eq_cfg))) {
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
rc = q6audio_set_stream_eq(pcm->ac, &eq_cfg);
|
||||
break;
|
||||
}
|
||||
case AUDIO_START: {
|
||||
uint32_t acdb_id;
|
||||
if (arg == 0) {
|
||||
@ -91,7 +74,7 @@ static long pcm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
if (pcm->ac) {
|
||||
rc = -EBUSY;
|
||||
} else {
|
||||
pcm->ac = q6audio_open_pcm(BUFSZ, pcm->sample_rate,
|
||||
pcm->ac = q6audio_open_pcm(pcm->buffer_size, pcm->sample_rate,
|
||||
pcm->channel_count,
|
||||
AUDIO_FLAG_WRITE, acdb_id);
|
||||
if (!pcm->ac)
|
||||
@ -117,13 +100,22 @@ static long pcm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
if (config.sample_rate < 8000 || config.sample_rate > 48000) {
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
if (config.buffer_size < 128 || config.buffer_size > 8192) {
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
pcm->sample_rate = config.sample_rate;
|
||||
pcm->channel_count = config.channel_count;
|
||||
pcm->buffer_size = config.buffer_size;
|
||||
break;
|
||||
}
|
||||
case AUDIO_GET_CONFIG: {
|
||||
struct msm_audio_config config;
|
||||
config.buffer_size = BUFSZ;
|
||||
config.buffer_size = pcm->buffer_size;
|
||||
config.buffer_count = 2;
|
||||
config.sample_rate = pcm->sample_rate;
|
||||
config.channel_count = pcm->channel_count;
|
||||
@ -146,7 +138,6 @@ static int pcm_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct pcm *pcm;
|
||||
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
pr_info("pcm_out: open\n");
|
||||
pcm = kzalloc(sizeof(struct pcm), GFP_KERNEL);
|
||||
|
||||
@ -156,6 +147,7 @@ static int pcm_open(struct inode *inode, struct file *file)
|
||||
mutex_init(&pcm->lock);
|
||||
pcm->channel_count = 2;
|
||||
pcm->sample_rate = 44100;
|
||||
pcm->buffer_size = BUFSZ;
|
||||
|
||||
file->private_data = pcm;
|
||||
return 0;
|
||||
@ -184,7 +176,7 @@ static ssize_t pcm_write(struct file *file, const char __user *buf,
|
||||
if (!wait_event_timeout(ac->wait, (ab->used == 0), 5*HZ)) {
|
||||
audio_client_dump(ac);
|
||||
pr_err("pcm_write: timeout. dsp dead?\n");
|
||||
// BUG();
|
||||
BUG();
|
||||
}
|
||||
|
||||
xfer = count;
|
||||
@ -207,7 +199,6 @@ static ssize_t pcm_write(struct file *file, const char __user *buf,
|
||||
|
||||
static int pcm_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
AUDIO_INFO("%s\n", __func__);
|
||||
struct pcm *pcm = file->private_data;
|
||||
if (pcm->ac)
|
||||
q6audio_close(pcm->ac);
|
||||
|
@ -31,7 +31,8 @@
|
||||
#include "dal_acdb.h"
|
||||
#include "dal_adie.h"
|
||||
#include <mach/msm_qdsp6_audio.h>
|
||||
|
||||
#include <mach/htc_acoustic_qsd.h>
|
||||
#include <mach/msm_audio_qcp.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include "q6audio_devices.h"
|
||||
@ -347,7 +348,7 @@ static int audio_ioctl(struct audio_client *ac, void *ptr, uint32_t len)
|
||||
if (!wait_event_timeout(ac->wait, (ac->cb_status != -EBUSY), 5*HZ)) {
|
||||
dal_trace_dump(ac->client);
|
||||
pr_err("audio_ioctl: timeout. dsp dead?\n");
|
||||
q6audio_dsp_not_responding();
|
||||
BUG();
|
||||
}
|
||||
return ac->cb_status;
|
||||
}
|
||||
@ -437,6 +438,156 @@ static int audio_mp3_open(struct audio_client *ac, uint32_t bufsz,
|
||||
return audio_ioctl(ac, &rpc, sizeof(rpc));
|
||||
}
|
||||
|
||||
static int audio_aac_open(struct audio_client *ac, uint32_t bufsz,
|
||||
void *data)
|
||||
{
|
||||
struct aac_format *af = data;
|
||||
struct adsp_open_command rpc;
|
||||
uint32_t *aac_type;
|
||||
int idx = sizeof(uint32_t);
|
||||
struct adsp_audio_binary_format *fmt = &(rpc.format.binary);
|
||||
|
||||
memset(&rpc, 0, sizeof(rpc));
|
||||
|
||||
fmt->format = ADSP_AUDIO_FORMAT_MPEG4_AAC;
|
||||
aac_type = (uint32_t *)(fmt->data);
|
||||
switch (af->block_formats) {
|
||||
case 0xffff:
|
||||
if (ac->flags & AUDIO_FLAG_WRITE)
|
||||
*aac_type = ADSP_AUDIO_AAC_ADTS;
|
||||
else
|
||||
*aac_type = ADSP_AUDIO_AAC_MPEG4_ADTS;
|
||||
break;
|
||||
case 0:
|
||||
if (ac->flags & AUDIO_FLAG_WRITE)
|
||||
*aac_type = ADSP_AUDIO_AAC_ADIF;
|
||||
else
|
||||
*aac_type = ADSP_AUDIO_AAC_RAW;
|
||||
break;
|
||||
case 1:
|
||||
*aac_type = ADSP_AUDIO_AAC_RAW;
|
||||
break;
|
||||
case 2:
|
||||
*aac_type = ADSP_AUDIO_AAC_LOAS;
|
||||
break;
|
||||
case 3:
|
||||
*aac_type = ADSP_AUDIO_AAC_FRAMED_RAW;
|
||||
break;
|
||||
case 4:
|
||||
*aac_type = ADSP_AUDIO_AAC_RAW;
|
||||
break;
|
||||
default:
|
||||
pr_err("unsupported AAC type %d\n", af->block_formats);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
TRACE("aac_open: type %x, obj %d, idx %d\n",
|
||||
*aac_type, af->audio_object_type, idx);
|
||||
fmt->data[idx++] = (u8)(((af->audio_object_type & 0x1F) << 3) |
|
||||
((af->sample_rate >> 1) & 0x7));
|
||||
fmt->data[idx] = (u8)(((af->sample_rate & 0x1) << 7) |
|
||||
((af->channel_config & 0x7) << 3));
|
||||
|
||||
switch (af->audio_object_type) {
|
||||
case AAC_OBJECT_ER_LC:
|
||||
case AAC_OBJECT_ER_LTP:
|
||||
case AAC_OBJECT_ER_LD:
|
||||
/* extension flag */
|
||||
fmt->data[idx++] |= 0x1;
|
||||
fmt->data[idx] = (u8)(
|
||||
((af->aac_section_data_resilience_flag & 0x1) << 7) |
|
||||
((af->aac_scalefactor_data_resilience_flag & 0x1) << 6) |
|
||||
((af->aac_spectral_data_resilience_flag & 0x1) << 5) |
|
||||
((af->ep_config & 0x3) << 2));
|
||||
break;
|
||||
|
||||
case AAC_OBJECT_ER_SCALABLE:
|
||||
fmt->data[idx++] |= 0x1;
|
||||
/* extension flag */
|
||||
fmt->data[idx++] = (u8)(
|
||||
((af->aac_section_data_resilience_flag & 0x1) << 4) |
|
||||
((af->aac_scalefactor_data_resilience_flag & 0x1) << 3) |
|
||||
((af->aac_spectral_data_resilience_flag & 0x1) << 2) |
|
||||
((af->ep_config >> 1) & 0x1));
|
||||
fmt->data[idx] = (u8)((af->ep_config & 0x1)
|
||||
<< 7);
|
||||
break;
|
||||
|
||||
case AAC_OBJECT_BSAC:
|
||||
fmt->data[++idx] = (u8)((af->ep_config & 0x3)
|
||||
<< 6);
|
||||
break;
|
||||
|
||||
default:
|
||||
pr_err("dbg unknown object type \n");
|
||||
break;
|
||||
}
|
||||
fmt->num_bytes = idx + 1;
|
||||
|
||||
TRACE("aac_open: format %x%x %x%x%x%x %x%x, \n",
|
||||
fmt->data[0], fmt->data[1], fmt->data[2], fmt->data[3],
|
||||
fmt->data[4], fmt->data[5], fmt->data[6], fmt->data[7]);
|
||||
|
||||
rpc.device = ADSP_AUDIO_DEVICE_ID_DEFAULT;
|
||||
rpc.config.aac.bit_rate = af->bit_rate;
|
||||
if (ac->flags & AUDIO_FLAG_WRITE) {
|
||||
rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_OPEN_WRITE;
|
||||
rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_PLAYBACK;
|
||||
} else {
|
||||
rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_OPEN_READ;
|
||||
rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_RECORD;
|
||||
}
|
||||
|
||||
if ((af->sbr_on_flag == 0) && (af->sbr_ps_on_flag == 0)) {
|
||||
rpc.config.aac.encoder_mode =
|
||||
ADSP_AUDIO_ENC_AAC_LC_ONLY_MODE;
|
||||
} else if ((af->sbr_on_flag == 1) && (af->sbr_ps_on_flag == 0)) {
|
||||
rpc.config.aac.encoder_mode =
|
||||
ADSP_AUDIO_ENC_AAC_PLUS_MODE;
|
||||
} else if ((af->sbr_on_flag == 1) && (af->sbr_ps_on_flag == 1)) {
|
||||
rpc.config.aac.encoder_mode =
|
||||
ADSP_AUDIO_ENC_ENHANCED_AAC_PLUS_MODE;
|
||||
} else {
|
||||
pr_err("unsupported SBR flag\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
rpc.buf_max_size = bufsz; /* XXX ??? */
|
||||
rpc.hdr.response_type = 0;
|
||||
|
||||
TRACE("aac_open: opcode %x, stream_context 0x%x, "
|
||||
"mode %d, bytes %d, bbuffer size %d\n",
|
||||
rpc.hdr.opcode, rpc.stream_context,
|
||||
rpc.config.aac.encoder_mode, fmt->num_bytes, bufsz);
|
||||
|
||||
return audio_ioctl(ac, &rpc, sizeof(rpc));
|
||||
}
|
||||
|
||||
static int audio_qcelp_open(struct audio_client *ac, uint32_t bufsz,
|
||||
void *data)
|
||||
{
|
||||
struct msm_audio_qcelp_config *qf = data;
|
||||
struct adsp_open_command rpc;
|
||||
struct adsp_audio_standard_format *fmt = &(rpc.format.standard);
|
||||
|
||||
memset(&rpc, 0, sizeof(rpc));
|
||||
|
||||
fmt->format = ADSP_AUDIO_FORMAT_V13K_FS;
|
||||
fmt->sampling_rate = 8000;
|
||||
fmt->channels = 1;
|
||||
fmt->bits_per_sample = 16;
|
||||
fmt->is_signed = 1;
|
||||
fmt->is_interleaved = 0;
|
||||
|
||||
rpc.device = ADSP_AUDIO_DEVICE_ID_DEFAULT;
|
||||
rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_OPEN_READ;
|
||||
rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_RECORD;
|
||||
rpc.config.qcelp13k.min_rate = (uint16_t) qf->min_bit_rate;
|
||||
rpc.config.qcelp13k.max_rate = (uint16_t) qf->max_bit_rate;
|
||||
rpc.buf_max_size = bufsz; /* XXX ??? */
|
||||
|
||||
return audio_ioctl(ac, &rpc, sizeof(rpc));
|
||||
}
|
||||
|
||||
static int audio_close(struct audio_client *ac)
|
||||
{
|
||||
TRACE("%p: close\n", ac);
|
||||
@ -583,7 +734,10 @@ static void callback(void *data, int len, void *cookie)
|
||||
{
|
||||
struct adsp_event_hdr *e = data;
|
||||
struct audio_client *ac;
|
||||
struct adsp_buffer_event *abe = data;
|
||||
|
||||
TRACE("audio callback: context %d, event 0x%x, status %d\n",
|
||||
e->context, e->event_id, e->status);
|
||||
|
||||
if (e->context >= SESSION_MAX) {
|
||||
pr_err("audio callback: bogus session %d\n",
|
||||
@ -610,6 +764,9 @@ static void callback(void *data, int len, void *cookie)
|
||||
|
||||
if (e->event_id == ADSP_AUDIO_EVT_STATUS_BUF_DONE) {
|
||||
TRACE("%p: CB done (%d)\n", ac, e->status);
|
||||
TRACE("%p: actual_size %d, buffer_size %d\n",
|
||||
ac, abe->buffer.actual_size, ac->buf[ac->dsp_buf].size);
|
||||
|
||||
if (e->status)
|
||||
pr_err("buffer status %d\n", e->status);
|
||||
ac->buf[ac->dsp_buf].used = 0;
|
||||
@ -891,6 +1048,10 @@ static void audio_rx_analog_enable(int en)
|
||||
if (analog_ops->receiver_enable)
|
||||
analog_ops->receiver_enable(en);
|
||||
break;
|
||||
case ADSP_AUDIO_DEVICE_ID_I2S_SPKR:
|
||||
if (analog_ops->i2s_enable)
|
||||
analog_ops->i2s_enable(en);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -936,7 +1097,8 @@ static int audio_update_acdb(uint32_t adev, uint32_t acdb_id)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
audio_set_table(ac_control, adev, sz);
|
||||
if (sz > 0)
|
||||
audio_set_table(ac_control, adev, sz);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1213,7 +1375,7 @@ int q6audio_reinit_acdb(char* filename) {
|
||||
return 0;
|
||||
|
||||
mutex_lock(&audio_path_lock);
|
||||
if (strlen(filename) < 0 || !strcmp(filename, acdb_file)) {
|
||||
if (strlen(filename) < 0) {
|
||||
res = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
@ -1447,7 +1609,7 @@ struct audio_client *q6audio_open_pcm(uint32_t bufsz, uint32_t rate,
|
||||
if (rc == 0)
|
||||
break;
|
||||
if (retry == 0)
|
||||
q6audio_dsp_not_responding();
|
||||
BUG();
|
||||
pr_err("q6audio: open pcm error %d, retrying\n", rc);
|
||||
msleep(1);
|
||||
}
|
||||
@ -1472,7 +1634,7 @@ struct audio_client *q6audio_open_pcm(uint32_t bufsz, uint32_t rate,
|
||||
if (rc == 0)
|
||||
break;
|
||||
if (retry == 0)
|
||||
q6audio_dsp_not_responding();
|
||||
BUG();
|
||||
pr_err("q6audio: stream start error %d, retrying\n", rc);
|
||||
}
|
||||
|
||||
@ -1512,9 +1674,10 @@ struct audio_client *q6voice_open(uint32_t flags, uint32_t acdb_id)
|
||||
return 0;
|
||||
|
||||
ac->flags = flags;
|
||||
if (ac->flags & AUDIO_FLAG_WRITE)
|
||||
if (ac->flags & AUDIO_FLAG_WRITE) {
|
||||
audio_rx_path_enable(1, acdb_id);
|
||||
else {
|
||||
audio_rx_mute(ac_control, ADSP_AUDIO_DEVICE_ID_VOICE, 0);
|
||||
} else {
|
||||
tx_clk_freq = 8000;
|
||||
audio_tx_path_enable(1, acdb_id);
|
||||
}
|
||||
@ -1524,9 +1687,10 @@ struct audio_client *q6voice_open(uint32_t flags, uint32_t acdb_id)
|
||||
|
||||
int q6voice_close(struct audio_client *ac)
|
||||
{
|
||||
if (ac->flags & AUDIO_FLAG_WRITE)
|
||||
if (ac->flags & AUDIO_FLAG_WRITE) {
|
||||
audio_rx_mute(ac_control, ADSP_AUDIO_DEVICE_ID_VOICE, 1);
|
||||
audio_rx_path_enable(0, 0);
|
||||
else
|
||||
} else
|
||||
audio_tx_path_enable(0, 0);
|
||||
|
||||
audio_client_free(ac);
|
||||
@ -1572,3 +1736,122 @@ int q6audio_async(struct audio_client *ac)
|
||||
rpc.response_type = ADSP_AUDIO_RESPONSE_ASYNC;
|
||||
return audio_ioctl(ac, &rpc, sizeof(rpc));
|
||||
}
|
||||
|
||||
struct audio_client *q6audio_open_aac(uint32_t bufsz, uint32_t rate,
|
||||
uint32_t flags, void *data, uint32_t acdb_id)
|
||||
{
|
||||
struct audio_client *ac;
|
||||
|
||||
TRACE("q6audio_open_aac flags=%d rate=%d\n", flags, rate);
|
||||
|
||||
if (q6audio_init())
|
||||
return 0;
|
||||
|
||||
ac = audio_client_alloc(bufsz);
|
||||
if (!ac)
|
||||
return 0;
|
||||
|
||||
ac->flags = flags;
|
||||
if (ac->flags & AUDIO_FLAG_WRITE)
|
||||
audio_rx_path_enable(1, acdb_id);
|
||||
else {
|
||||
/* TODO: consider concourrency with voice call */
|
||||
tx_clk_freq = rate;
|
||||
audio_tx_path_enable(1, acdb_id);
|
||||
}
|
||||
|
||||
audio_aac_open(ac, bufsz, data);
|
||||
audio_command(ac, ADSP_AUDIO_IOCTL_CMD_SESSION_START);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int q6audio_aac_close(struct audio_client *ac)
|
||||
{
|
||||
audio_close(ac);
|
||||
if (ac->flags & AUDIO_FLAG_WRITE)
|
||||
audio_rx_path_enable(0, 0);
|
||||
else
|
||||
audio_tx_path_enable(0, 0);
|
||||
|
||||
audio_client_free(ac);
|
||||
audio_allow_sleep();
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct audio_client *q6fm_open(void)
|
||||
{
|
||||
struct audio_client *ac;
|
||||
|
||||
printk("q6fm_open()\n");
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int q6fm_close(struct audio_client *ac)
|
||||
{
|
||||
audio_rx_path_enable(0, 0);
|
||||
enable_aux_loopback(0);
|
||||
audio_client_free(ac);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct audio_client *q6audio_open_qcelp(uint32_t bufsz, uint32_t rate,
|
||||
void *data, uint32_t acdb_id)
|
||||
{
|
||||
struct audio_client *ac;
|
||||
|
||||
if (q6audio_init())
|
||||
return 0;
|
||||
|
||||
ac = audio_client_alloc(bufsz);
|
||||
if (!ac)
|
||||
return 0;
|
||||
|
||||
ac->flags = AUDIO_FLAG_READ;
|
||||
tx_clk_freq = rate;
|
||||
audio_tx_path_enable(1, acdb_id);
|
||||
|
||||
audio_qcelp_open(ac, bufsz, data);
|
||||
audio_command(ac, ADSP_AUDIO_IOCTL_CMD_SESSION_START);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int q6audio_qcelp_close(struct audio_client *ac)
|
||||
{
|
||||
audio_close(ac);
|
||||
audio_tx_path_enable(0, 0);
|
||||
audio_client_free(ac);
|
||||
audio_allow_sleep();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,212 +0,0 @@
|
||||
/* arch/arm/mach-msm/qdsp6/qcelp_in.c
|
||||
*
|
||||
* Copyright (C) 2009 Google, Inc.
|
||||
* Copyright (C) 2009 HTC Corporation
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/fs.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/msm_audio.h>
|
||||
#include <mach/msm_qdsp6_audio.h>
|
||||
#include <mach/msm_audio_qcp.h>
|
||||
|
||||
#define BUFSZ (734)
|
||||
#define DMASZ (BUFSZ * 2)
|
||||
|
||||
#if 0
|
||||
#define TRACE(x...) pr_info("Q6: "x)
|
||||
#else
|
||||
#define TRACE(x...) do{}while(0)
|
||||
#endif
|
||||
|
||||
static DEFINE_MUTEX(qcelp_in_lock);
|
||||
static int qcelp_in_opened = 0;
|
||||
static struct msm_audio_qcelp_config *qf;
|
||||
|
||||
void audio_client_dump(struct audio_client *ac);
|
||||
|
||||
static long qcelp_in_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case AUDIO_SET_VOLUME:
|
||||
break;
|
||||
case AUDIO_GET_STATS: {
|
||||
struct msm_audio_stats stats;
|
||||
memset(&stats, 0, sizeof(stats));
|
||||
if (copy_to_user((void*) arg, &stats, sizeof(stats)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
case AUDIO_START: {
|
||||
uint32_t acdb_id;
|
||||
rc = 0;
|
||||
|
||||
if (arg == 0) {
|
||||
acdb_id = 0;
|
||||
} else if (copy_from_user(&acdb_id, (void*) arg, sizeof(acdb_id))) {
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
mutex_lock(&qcelp_in_lock);
|
||||
if (file->private_data) {
|
||||
rc = -EBUSY;
|
||||
} else {
|
||||
file->private_data = q6audio_open_qcelp(
|
||||
BUFSZ, 8000, qf, acdb_id);
|
||||
if (!file->private_data)
|
||||
rc = -ENOMEM;
|
||||
}
|
||||
mutex_unlock(&qcelp_in_lock);
|
||||
break;
|
||||
}
|
||||
case AUDIO_STOP:
|
||||
break;
|
||||
case AUDIO_FLUSH:
|
||||
break;
|
||||
case AUDIO_GET_CONFIG:
|
||||
if (copy_to_user((void *)arg, qf,
|
||||
sizeof(struct msm_audio_qcelp_config)))
|
||||
return -EFAULT;
|
||||
break;
|
||||
case AUDIO_SET_CONFIG:
|
||||
if (copy_from_user(qf, (void *)arg,
|
||||
sizeof(struct msm_audio_qcelp_config)))
|
||||
return -EFAULT;
|
||||
if (qf->min_bit_rate > 4 || qf->min_bit_rate < 1) {
|
||||
pr_err("invalid min bitrate\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (qf->max_bit_rate > 4 || qf->max_bit_rate < 1) {
|
||||
pr_err("invalid max bitrate\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (qf->cdma_rate > CDMA_RATE_ERASURE ||
|
||||
qf->cdma_rate < CDMA_RATE_BLANK) {
|
||||
pr_err("invalid qcelp cdma rate\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int qcelp_in_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
int rc;
|
||||
|
||||
pr_info("qcelp_in: open\n");
|
||||
mutex_lock(&qcelp_in_lock);
|
||||
if (qcelp_in_opened) {
|
||||
pr_err("qcelp_in: busy\n");
|
||||
rc = -EBUSY;
|
||||
} else {
|
||||
qf = kzalloc(sizeof(*qf), GFP_KERNEL);
|
||||
memset(qf, 0, sizeof(struct msm_audio_qcelp_config));
|
||||
qf->channels = 1;
|
||||
qf->cdma_rate = 0x04; /* CDMA_RATE_FULL */
|
||||
qf->min_bit_rate = 1;
|
||||
qf->max_bit_rate = 4;
|
||||
qcelp_in_opened = 1;
|
||||
rc = 0;
|
||||
}
|
||||
mutex_unlock(&qcelp_in_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ssize_t qcelp_in_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
|
||||
{
|
||||
struct audio_client *ac;
|
||||
struct audio_buffer *ab;
|
||||
const char __user *start = buf;
|
||||
int xfer, res = 0;
|
||||
|
||||
mutex_lock(&qcelp_in_lock);
|
||||
ac = file->private_data;
|
||||
if (!ac) {
|
||||
res = -ENODEV;
|
||||
pr_err("qcelp_in_read ac NULL\n");
|
||||
goto fail;
|
||||
}
|
||||
while (count > 0) {
|
||||
ab = ac->buf + ac->cpu_buf;
|
||||
TRACE("qcelp_in_read wait count=%d ab=%d ac->buf=%d cpu_buf=%d ac->buf[1]=%d\n",
|
||||
count, ab, ac->buf, ac->cpu_buf, &(ac->buf[1]));
|
||||
if (ab->used)
|
||||
wait_event(ac->wait, (ab->used == 0));
|
||||
TRACE(" qcelp_in_read event arrive ab->size=%d\n", ab->size);
|
||||
xfer = count;
|
||||
if (xfer > ab->size)
|
||||
xfer = ab->size;
|
||||
|
||||
if (copy_to_user(buf, ab->data, xfer)) {
|
||||
res = -EFAULT;
|
||||
pr_err("Tomdbg copy to user failed \n");
|
||||
goto fail;
|
||||
}
|
||||
TRACE("qcelp_in read buf = %d,xfer = %d,cnt = %d\n", buf, xfer, count);
|
||||
|
||||
buf += xfer;
|
||||
count -= xfer;
|
||||
|
||||
ab->used = 1;
|
||||
q6audio_read(ac, ab);
|
||||
ac->cpu_buf ^= 1;
|
||||
}
|
||||
fail:
|
||||
res = buf - start;
|
||||
mutex_unlock(&qcelp_in_lock);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int qcelp_in_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
int rc = 0;
|
||||
pr_info("qcelp_in: release\n");
|
||||
mutex_lock(&qcelp_in_lock);
|
||||
if (file->private_data)
|
||||
rc = q6audio_close(file->private_data);
|
||||
kfree(qf);
|
||||
qcelp_in_opened = 0;
|
||||
mutex_unlock(&qcelp_in_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct file_operations qcelp_in_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = qcelp_in_open,
|
||||
.read = qcelp_in_read,
|
||||
.release = qcelp_in_release,
|
||||
.unlocked_ioctl = qcelp_in_ioctl,
|
||||
};
|
||||
|
||||
struct miscdevice qcelp_in_misc = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = "msm_qcelp_in",
|
||||
.fops = &qcelp_in_fops,
|
||||
};
|
||||
|
||||
static int __init qcelp_in_init(void) {
|
||||
return misc_register(&qcelp_in_misc);
|
||||
}
|
||||
|
||||
device_initcall(qcelp_in_init);
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
|
||||
/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@ -7,119 +7,325 @@
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Code Aurora Forum nor
|
||||
* * Neither the name of Code Aurora nor
|
||||
* the names of its contributors may be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MSM_VENC_H_
|
||||
#define _MSM_VENC_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct venc_buf {
|
||||
unsigned int src_id;
|
||||
#define VENC_MAX_RECON_BUFFERS 2
|
||||
|
||||
#define VENC_FLAG_EOS 0x00000001
|
||||
#define VENC_FLAG_END_OF_FRAME 0x00000010
|
||||
#define VENC_FLAG_SYNC_FRAME 0x00000020
|
||||
#define VENC_FLAG_EXTRA_DATA 0x00000040
|
||||
#define VENC_FLAG_CODEC_CONFIG 0x00000080
|
||||
|
||||
enum venc_flush_type {
|
||||
VENC_FLUSH_INPUT,
|
||||
VENC_FLUSH_OUTPUT,
|
||||
VENC_FLUSH_ALL
|
||||
};
|
||||
|
||||
enum venc_state_type {
|
||||
VENC_STATE_PAUSE = 0x1,
|
||||
VENC_STATE_START = 0x2,
|
||||
VENC_STATE_STOP = 0x4
|
||||
};
|
||||
|
||||
enum venc_event_type_enum {
|
||||
VENC_EVENT_START_STATUS,
|
||||
VENC_EVENT_STOP_STATUS,
|
||||
VENC_EVENT_SUSPEND_STATUS,
|
||||
VENC_EVENT_RESUME_STATUS,
|
||||
VENC_EVENT_FLUSH_STATUS,
|
||||
VENC_EVENT_RELEASE_INPUT,
|
||||
VENC_EVENT_DELIVER_OUTPUT,
|
||||
VENC_EVENT_UNKNOWN_STATUS
|
||||
};
|
||||
|
||||
enum venc_status_code {
|
||||
VENC_STATUS_SUCCESS,
|
||||
VENC_STATUS_ERROR,
|
||||
VENC_STATUS_INVALID_STATE,
|
||||
VENC_STATUS_FLUSHING,
|
||||
VENC_STATUS_INVALID_PARAM,
|
||||
VENC_STATUS_CMD_QUEUE_FULL,
|
||||
VENC_STATUS_CRITICAL,
|
||||
VENC_STATUS_INSUFFICIENT_RESOURCES,
|
||||
VENC_STATUS_TIMEOUT
|
||||
};
|
||||
|
||||
enum venc_msg_code {
|
||||
VENC_MSG_INDICATION,
|
||||
VENC_MSG_INPUT_BUFFER_DONE,
|
||||
VENC_MSG_OUTPUT_BUFFER_DONE,
|
||||
VENC_MSG_NEED_OUTPUT_BUFFER,
|
||||
VENC_MSG_FLUSH,
|
||||
VENC_MSG_START,
|
||||
VENC_MSG_STOP,
|
||||
VENC_MSG_PAUSE,
|
||||
VENC_MSG_RESUME,
|
||||
VENC_MSG_STOP_READING_MSG
|
||||
};
|
||||
|
||||
enum venc_error_code {
|
||||
VENC_S_SUCCESS,
|
||||
VENC_S_EFAIL,
|
||||
VENC_S_EFATAL,
|
||||
VENC_S_EBADPARAM,
|
||||
VENC_S_EINVALSTATE,
|
||||
VENC_S_ENOSWRES,
|
||||
VENC_S_ENOHWRES,
|
||||
VENC_S_EBUFFREQ,
|
||||
VENC_S_EINVALCMD,
|
||||
VENC_S_ETIMEOUT,
|
||||
VENC_S_ENOREATMPT,
|
||||
VENC_S_ENOPREREQ,
|
||||
VENC_S_ECMDQFULL,
|
||||
VENC_S_ENOTSUPP,
|
||||
VENC_S_ENOTIMPL,
|
||||
VENC_S_ENOTPMEM,
|
||||
VENC_S_EFLUSHED,
|
||||
VENC_S_EINSUFBUF,
|
||||
VENC_S_ESAMESTATE,
|
||||
VENC_S_EINVALTRANS
|
||||
};
|
||||
|
||||
enum venc_mem_region_enum {
|
||||
VENC_PMEM_EBI1,
|
||||
VENC_PMEM_SMI
|
||||
};
|
||||
|
||||
struct venc_buf_type {
|
||||
unsigned int region;
|
||||
unsigned int phys;
|
||||
unsigned int size;
|
||||
int offset;
|
||||
};
|
||||
|
||||
struct venc_qp_range {
|
||||
unsigned int min_qp;
|
||||
unsigned int max_qp;
|
||||
};
|
||||
|
||||
struct venc_frame_rate {
|
||||
unsigned int frame_rate_num;
|
||||
unsigned int frame_rate_den;
|
||||
};
|
||||
|
||||
struct venc_slice_info {
|
||||
unsigned int slice_mode;
|
||||
unsigned int units_per_slice;
|
||||
};
|
||||
|
||||
struct venc_extra_data {
|
||||
unsigned int slice_extra_data_flag;
|
||||
unsigned int slice_client_data1;
|
||||
unsigned int slice_client_data2;
|
||||
unsigned int slice_client_data3;
|
||||
unsigned int none_extra_data_flag;
|
||||
unsigned int none_client_data1;
|
||||
unsigned int none_client_data2;
|
||||
unsigned int none_client_data3;
|
||||
};
|
||||
|
||||
struct venc_common_config {
|
||||
unsigned int standard;
|
||||
unsigned int input_frame_height;
|
||||
unsigned int input_frame_width;
|
||||
unsigned int output_frame_height;
|
||||
unsigned int output_frame_width;
|
||||
unsigned int rotation_angle;
|
||||
unsigned int intra_period;
|
||||
unsigned int rate_control;
|
||||
struct venc_frame_rate frame_rate;
|
||||
unsigned int bitrate;
|
||||
struct venc_qp_range qp_range;
|
||||
unsigned int iframe_qp;
|
||||
unsigned int pframe_qp;
|
||||
struct venc_slice_info slice_config;
|
||||
struct venc_extra_data extra_data;
|
||||
};
|
||||
|
||||
struct venc_nonio_buf_config {
|
||||
struct venc_buf_type recon_buf1;
|
||||
struct venc_buf_type recon_buf2;
|
||||
struct venc_buf_type wb_buf;
|
||||
struct venc_buf_type cmd_buf;
|
||||
struct venc_buf_type vlc_buf;
|
||||
};
|
||||
|
||||
struct venc_mpeg4_config {
|
||||
unsigned int profile;
|
||||
unsigned int level;
|
||||
unsigned int time_resolution;
|
||||
unsigned int ac_prediction;
|
||||
unsigned int hec_interval;
|
||||
unsigned int data_partition;
|
||||
unsigned int short_header;
|
||||
unsigned int rvlc_enable;
|
||||
};
|
||||
|
||||
struct venc_h263_config {
|
||||
unsigned int profile;
|
||||
unsigned int level;
|
||||
};
|
||||
|
||||
struct venc_h264_config {
|
||||
unsigned int profile;
|
||||
unsigned int level;
|
||||
unsigned int max_nal;
|
||||
unsigned int idr_period;
|
||||
};
|
||||
|
||||
struct venc_pmem {
|
||||
int src;
|
||||
int fd;
|
||||
unsigned long offset;
|
||||
unsigned long size;
|
||||
unsigned int offset;
|
||||
void *virt;
|
||||
void *phys;
|
||||
unsigned int size;
|
||||
};
|
||||
|
||||
struct q6_init_config {
|
||||
unsigned short venc_standard;
|
||||
unsigned short partial_run_length_flag;
|
||||
unsigned short h263_annex_ispt;
|
||||
unsigned short h263_annex_jspt;
|
||||
unsigned short h263_annex_tspt;
|
||||
unsigned short rc_flag;
|
||||
unsigned short one_mv_flag;
|
||||
unsigned short acdc_pred_enable;
|
||||
unsigned short rounding_bit_ctrl;
|
||||
unsigned short rotation_flag;
|
||||
unsigned short max_mvx;
|
||||
unsigned short max_mvy;
|
||||
unsigned short enc_frame_height_inmb;
|
||||
unsigned short enc_frame_width_inmb;
|
||||
unsigned short dvs_frame_height;
|
||||
unsigned short dvs_frame_width;
|
||||
struct venc_buffer {
|
||||
unsigned char *ptr_buffer;
|
||||
unsigned int size;
|
||||
unsigned int len;
|
||||
unsigned int offset;
|
||||
long long time_stamp;
|
||||
unsigned int flags;
|
||||
unsigned int client_data;
|
||||
|
||||
/* unused by userspace, filled in by kernel */
|
||||
unsigned int ref_frame_buf1_phy;
|
||||
unsigned int ref_frame_buf2_phy;
|
||||
unsigned int rlc_buf1_phy;
|
||||
unsigned int rlc_buf2_phy;
|
||||
unsigned int rlc_buf_length;
|
||||
};
|
||||
|
||||
struct init_config {
|
||||
struct venc_buf ref_frame_buf1;
|
||||
struct venc_buf ref_frame_buf2;
|
||||
struct venc_buf rlc_buf1;
|
||||
struct venc_buf rlc_buf2;
|
||||
struct q6_init_config q6_init_config;
|
||||
struct venc_buffers {
|
||||
struct venc_pmem recon_buf[VENC_MAX_RECON_BUFFERS];
|
||||
struct venc_pmem wb_buf;
|
||||
struct venc_pmem cmd_buf;
|
||||
struct venc_pmem vlc_buf;
|
||||
};
|
||||
|
||||
struct q6_encode_param {
|
||||
unsigned int luma_addr;
|
||||
unsigned int chroma_addr;
|
||||
unsigned int x_offset;
|
||||
unsigned int y_offset;
|
||||
unsigned int frame_rho_budget;
|
||||
unsigned int frame_type;
|
||||
unsigned int qp;
|
||||
struct venc_buffer_flush {
|
||||
unsigned int flush_mode;
|
||||
};
|
||||
|
||||
struct encode_param {
|
||||
struct venc_buf y_addr;
|
||||
unsigned long uv_offset;
|
||||
struct q6_encode_param q6_encode_param;
|
||||
union venc_msg_data {
|
||||
struct venc_buffer buf;
|
||||
struct venc_buffer_flush flush_ret;
|
||||
|
||||
};
|
||||
|
||||
struct intra_refresh {
|
||||
unsigned int intra_refresh_enable;
|
||||
unsigned int intra_mb_num;
|
||||
struct venc_msg {
|
||||
unsigned int status_code;
|
||||
unsigned int msg_code;
|
||||
union venc_msg_data msg_data;
|
||||
unsigned int msg_data_size;
|
||||
};
|
||||
|
||||
struct rc_config {
|
||||
unsigned short max_frame_qp_up_delta;
|
||||
unsigned short max_frame_qp_down_delta;
|
||||
unsigned short min_frame_qp;
|
||||
unsigned short max_frame_qp;
|
||||
union venc_codec_config {
|
||||
struct venc_mpeg4_config mpeg4_params;
|
||||
struct venc_h263_config h263_params;
|
||||
struct venc_h264_config h264_params;
|
||||
};
|
||||
|
||||
struct q6_frame_type {
|
||||
unsigned int frame_type;
|
||||
unsigned int frame_len;
|
||||
unsigned int frame_addr;
|
||||
unsigned int map_table;
|
||||
struct venc_q6_config {
|
||||
struct venc_common_config config_params;
|
||||
union venc_codec_config codec_params;
|
||||
struct venc_nonio_buf_config buf_params;
|
||||
void *callback_event;
|
||||
};
|
||||
|
||||
struct frame_type {
|
||||
struct venc_buf frame_addr;
|
||||
struct q6_frame_type q6_frame_type;
|
||||
struct venc_hdr_config {
|
||||
struct venc_common_config config_params;
|
||||
union venc_codec_config codec_params;
|
||||
};
|
||||
|
||||
struct venc_init_config {
|
||||
struct venc_q6_config q6_config;
|
||||
struct venc_buffers q6_bufs;
|
||||
};
|
||||
|
||||
struct venc_seq_config {
|
||||
int size;
|
||||
struct venc_pmem buf;
|
||||
struct venc_q6_config q6_config;
|
||||
};
|
||||
|
||||
struct venc_version {
|
||||
u32 major;
|
||||
u32 minor;
|
||||
};
|
||||
|
||||
#define VENC_IOCTL_MAGIC 'V'
|
||||
|
||||
#define VENC_IOCTL_INITIALIZE _IOW(VENC_IOCTL_MAGIC, 1, struct init_config)
|
||||
#define VENC_IOCTL_ENCODE _IOW(VENC_IOCTL_MAGIC, 2, struct encode_param)
|
||||
#define VENC_IOCTL_INTRA_REFRESH _IOW(VENC_IOCTL_MAGIC, 3, struct intra_refresh)
|
||||
#define VENC_IOCTL_RC_CONFIG _IOW(VENC_IOCTL_MAGIC, 4, struct rc_config)
|
||||
#define VENC_IOCTL_ENCODE_CONFIG _IOW(VENC_IOCTL_MAGIC, 5, struct init_config)
|
||||
#define VENC_IOCTL_STOP _IO(VENC_IOCTL_MAGIC, 6)
|
||||
#define VENC_IOCTL_WAIT_FOR_ENCODE _IOR(VENC_IOCTL_MAGIC, 7, struct frame_type)
|
||||
#define VENC_IOCTL_STOP_ENCODE _IO(VENC_IOCTL_MAGIC, 8)
|
||||
#define VENC_IOCTL_CMD_READ_NEXT_MSG \
|
||||
_IOWR(VENC_IOCTL_MAGIC, 1, struct venc_msg)
|
||||
|
||||
#endif /* _MSM_VENC_H_ */
|
||||
#define VENC_IOCTL_CMD_STOP_READ_MSG _IO(VENC_IOCTL_MAGIC, 2)
|
||||
|
||||
#define VENC_IOCTL_SET_INPUT_BUFFER \
|
||||
_IOW(VENC_IOCTL_MAGIC, 3, struct venc_pmem)
|
||||
|
||||
#define VENC_IOCTL_SET_OUTPUT_BUFFER \
|
||||
_IOW(VENC_IOCTL_MAGIC, 4, struct venc_pmem)
|
||||
|
||||
#define VENC_IOCTL_CMD_START _IOW(VENC_IOCTL_MAGIC, 5, struct venc_init_config)
|
||||
|
||||
#define VENC_IOCTL_CMD_ENCODE_FRAME \
|
||||
_IOW(VENC_IOCTL_MAGIC, 6, struct venc_buffer)
|
||||
|
||||
#define VENC_IOCTL_CMD_FILL_OUTPUT_BUFFER \
|
||||
_IOW(VENC_IOCTL_MAGIC, 7, struct venc_buffer)
|
||||
|
||||
#define VENC_IOCTL_CMD_FLUSH \
|
||||
_IOW(VENC_IOCTL_MAGIC, 8, struct venc_buffer_flush)
|
||||
|
||||
#define VENC_IOCTL_CMD_PAUSE _IO(VENC_IOCTL_MAGIC, 9)
|
||||
|
||||
#define VENC_IOCTL_CMD_RESUME _IO(VENC_IOCTL_MAGIC, 10)
|
||||
|
||||
#define VENC_IOCTL_CMD_STOP _IO(VENC_IOCTL_MAGIC, 11)
|
||||
|
||||
#define VENC_IOCTL_SET_INTRA_PERIOD \
|
||||
_IOW(VENC_IOCTL_MAGIC, 12, int)
|
||||
|
||||
#define VENC_IOCTL_CMD_REQUEST_IFRAME _IO(VENC_IOCTL_MAGIC, 13)
|
||||
|
||||
#define VENC_IOCTL_GET_SEQUENCE_HDR \
|
||||
_IOWR(VENC_IOCTL_MAGIC, 14, struct venc_seq_config)
|
||||
|
||||
#define VENC_IOCTL_SET_INTRA_REFRESH \
|
||||
_IOW(VENC_IOCTL_MAGIC, 15, int)
|
||||
|
||||
#define VENC_IOCTL_SET_FRAME_RATE \
|
||||
_IOW(VENC_IOCTL_MAGIC, 16, struct venc_frame_rate)
|
||||
|
||||
#define VENC_IOCTL_SET_TARGET_BITRATE \
|
||||
_IOW(VENC_IOCTL_MAGIC, 17, int)
|
||||
|
||||
#define VENC_IOCTL_SET_QP_RANGE \
|
||||
_IOW(VENC_IOCTL_MAGIC, 18, struct venc_qp_range)
|
||||
|
||||
#define VENC_IOCTL_GET_VERSION \
|
||||
_IOR(VENC_IOCTL_MAGIC, 19, struct venc_version)
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user