mirror of
https://github.com/LineageOS/android_kernel_samsung_msm8226.git
synced 2026-09-29 00:00:25 +02:00
qdsp5: Add driver to support for CAD based sound Devices
CAD(Common Application Devices) support is added on modem. Add new CAD sound driver to support CAD devices to support the same. Change-Id: I05eff9f0da92911848e2ed304e4dae489d3765fb Signed-off-by: Manish Dewangan <manish@codeaurora.org>
This commit is contained in:
@@ -14,7 +14,7 @@ obj-$(CONFIG_MSM7X27A_AUDIO) += audio_aac_in.o audio_evrc_in.o audio_qcelp_in.o
|
||||
obj-y += audio_out.o audio_mp3.o audmgr.o audpp.o audrec.o audpreproc.o
|
||||
obj-y += audio_evrc.o audio_qcelp.o audio_amrnb.o audio_aac.o audio_amrnb_in.o
|
||||
obj-y += audio_wma.o audio_voicememo.o audio_pcm.o audio_amrwb.o audio_wmapro.o
|
||||
obj-y += snd.o snd_adie.o
|
||||
obj-y += snd.o snd_cad.o snd_adie.o
|
||||
obj-$(CONFIG_ARCH_MSM7X27A) += audio_fm.o
|
||||
obj-$(CONFIG_ARCH_MSM7X27A) += audio_mvs.o
|
||||
obj-$(CONFIG_ARCH_MSM7X27A) += audio_lpa.o audio_ac3.o
|
||||
|
||||
@@ -0,0 +1,490 @@
|
||||
/* arch/arm/mach-msm/qdsp5/snd_cad.c
|
||||
*
|
||||
* interface to "snd" service on the baseband cpu
|
||||
* This code also borrows from snd.c, which is
|
||||
* Copyright (C) 2008 HTC Corporation
|
||||
* Copyright (c) 2009, 2012 Code Aurora Forum. All rights reserved.
|
||||
*
|
||||
* 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/module.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/msm_audio.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/ioctls.h>
|
||||
#include <mach/board.h>
|
||||
#include <mach/msm_rpcrouter.h>
|
||||
#include <mach/debug_mm.h>
|
||||
|
||||
struct snd_cad_ctxt {
|
||||
struct mutex lock;
|
||||
int opened;
|
||||
struct msm_rpc_endpoint *ept;
|
||||
struct msm_cad_endpoints *cad_epts;
|
||||
};
|
||||
|
||||
struct snd_cad_sys_ctxt {
|
||||
struct mutex lock;
|
||||
struct msm_rpc_endpoint *ept;
|
||||
};
|
||||
|
||||
struct snd_curr_dev_info {
|
||||
int rx_dev;
|
||||
int tx_dev;
|
||||
};
|
||||
|
||||
static struct snd_cad_sys_ctxt the_snd_cad_sys;
|
||||
|
||||
static struct snd_cad_ctxt the_snd;
|
||||
static struct snd_curr_dev_info curr_dev;
|
||||
|
||||
#define RPC_SND_PROG 0x30000002
|
||||
#define RPC_SND_CB_PROG 0x31000002
|
||||
|
||||
#define RPC_SND_VERS 0x00030003
|
||||
|
||||
#define SND_CAD_SET_DEVICE_PROC 40
|
||||
#define SND_CAD_SET_VOLUME_PROC 39
|
||||
|
||||
struct rpc_cad_set_device_args {
|
||||
struct cad_devices_type device;
|
||||
uint32_t ear_mute;
|
||||
uint32_t mic_mute;
|
||||
|
||||
uint32_t cb_func;
|
||||
uint32_t client_data;
|
||||
};
|
||||
|
||||
struct rpc_cad_set_volume_args {
|
||||
struct cad_devices_type device;
|
||||
uint32_t method;
|
||||
uint32_t volume;
|
||||
|
||||
uint32_t cb_func;
|
||||
uint32_t client_data;
|
||||
};
|
||||
|
||||
struct snd_cad_set_device_msg {
|
||||
struct rpc_request_hdr hdr;
|
||||
struct rpc_cad_set_device_args args;
|
||||
};
|
||||
|
||||
struct snd_cad_set_volume_msg {
|
||||
struct rpc_request_hdr hdr;
|
||||
struct rpc_cad_set_volume_args args;
|
||||
};
|
||||
|
||||
struct cad_endpoint *get_cad_endpoints(int *size);
|
||||
|
||||
static inline int check_mute(int mute)
|
||||
{
|
||||
return (mute == SND_MUTE_MUTED ||
|
||||
mute == SND_MUTE_UNMUTED) ? 0 : -EINVAL;
|
||||
}
|
||||
|
||||
static int get_endpoint(struct snd_cad_ctxt *snd, unsigned long arg)
|
||||
{
|
||||
int rc = 0, index;
|
||||
struct msm_cad_endpoint ept;
|
||||
|
||||
if (copy_from_user(&ept, (void __user *)arg, sizeof(ept))) {
|
||||
MM_ERR("cad_ioctl get endpoint: invalid read pointer\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
index = ept.id;
|
||||
if (index < 0 || index >= snd->cad_epts->num) {
|
||||
MM_ERR("snd_ioctl get endpoint: invalid index!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ept.id = snd->cad_epts->endpoints[index].id;
|
||||
strlcpy(ept.name,
|
||||
snd->cad_epts->endpoints[index].name,
|
||||
sizeof(ept.name));
|
||||
|
||||
if (copy_to_user((void __user *)arg, &ept, sizeof(ept))) {
|
||||
MM_ERR("snd_ioctl get endpoint: invalid write pointer\n");
|
||||
rc = -EFAULT;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static long snd_cad_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
struct snd_cad_set_device_msg dmsg;
|
||||
struct snd_cad_set_volume_msg vmsg;
|
||||
|
||||
struct msm_cad_device_config dev;
|
||||
struct msm_cad_volume_config vol;
|
||||
struct snd_cad_ctxt *snd = file->private_data;
|
||||
int rc = 0;
|
||||
|
||||
mutex_lock(&snd->lock);
|
||||
switch (cmd) {
|
||||
case SND_SET_DEVICE:
|
||||
if (copy_from_user(&dev, (void __user *) arg, sizeof(dev))) {
|
||||
MM_ERR("set device: invalid pointer\n");
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
dmsg.args.device.rx_device = cpu_to_be32(dev.device.rx_device);
|
||||
dmsg.args.device.tx_device = cpu_to_be32(dev.device.tx_device);
|
||||
dmsg.args.device.pathtype = cpu_to_be32(dev.device.pathtype);
|
||||
dmsg.args.ear_mute = cpu_to_be32(dev.ear_mute);
|
||||
dmsg.args.mic_mute = cpu_to_be32(dev.mic_mute);
|
||||
if (check_mute(dev.ear_mute) < 0 ||
|
||||
check_mute(dev.mic_mute) < 0) {
|
||||
MM_ERR("set device: invalid mute status\n");
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
dmsg.args.cb_func = -1;
|
||||
dmsg.args.client_data = 0;
|
||||
curr_dev.tx_dev = dev.device.tx_device;
|
||||
curr_dev.rx_dev = dev.device.rx_device;
|
||||
MM_ERR("snd_cad_set_device %d %d %d %d\n", dev.device.rx_device,
|
||||
dev.device.tx_device, dev.ear_mute, dev.mic_mute);
|
||||
|
||||
rc = msm_rpc_call(snd->ept,
|
||||
SND_CAD_SET_DEVICE_PROC,
|
||||
&dmsg, sizeof(dmsg), 5 * HZ);
|
||||
break;
|
||||
|
||||
case SND_SET_VOLUME:
|
||||
if (copy_from_user(&vol, (void __user *) arg, sizeof(vol))) {
|
||||
MM_ERR("set volume: invalid pointer\n");
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
vmsg.args.device.rx_device = cpu_to_be32(dev.device.rx_device);
|
||||
vmsg.args.device.tx_device = cpu_to_be32(dev.device.tx_device);
|
||||
vmsg.args.method = cpu_to_be32(vol.method);
|
||||
if (vol.method != SND_METHOD_VOICE) {
|
||||
MM_ERR("set volume: invalid method\n");
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
vmsg.args.volume = cpu_to_be32(vol.volume);
|
||||
vmsg.args.cb_func = -1;
|
||||
vmsg.args.client_data = 0;
|
||||
|
||||
MM_ERR("snd_cad_set_volume %d %d %d %d\n", vol.device.rx_device,
|
||||
vol.device.tx_device, vol.method, vol.volume);
|
||||
|
||||
rc = msm_rpc_call(snd->ept,
|
||||
SND_CAD_SET_VOLUME_PROC,
|
||||
&vmsg, sizeof(vmsg), 5 * HZ);
|
||||
|
||||
break;
|
||||
|
||||
case SND_GET_NUM_ENDPOINTS:
|
||||
if (copy_to_user((void __user *)arg,
|
||||
&snd->cad_epts->num, sizeof(unsigned))) {
|
||||
MM_ERR("get endpoint: invalid pointer\n");
|
||||
rc = -EFAULT;
|
||||
}
|
||||
break;
|
||||
|
||||
case SND_GET_ENDPOINT:
|
||||
rc = get_endpoint(snd, arg);
|
||||
break;
|
||||
|
||||
default:
|
||||
MM_ERR("unknown command\n");
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
mutex_unlock(&snd->lock);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int snd_cad_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct snd_cad_ctxt *snd = file->private_data;
|
||||
int rc;
|
||||
|
||||
mutex_lock(&snd->lock);
|
||||
rc = msm_rpc_close(snd->ept);
|
||||
if (rc < 0)
|
||||
MM_ERR("msm_rpc_close failed\n");
|
||||
snd->ept = NULL;
|
||||
snd->opened = 0;
|
||||
mutex_unlock(&snd->lock);
|
||||
return 0;
|
||||
}
|
||||
static int snd_cad_sys_release(void)
|
||||
{
|
||||
struct snd_cad_sys_ctxt *snd_cad_sys = &the_snd_cad_sys;
|
||||
int rc = 0;
|
||||
|
||||
mutex_lock(&snd_cad_sys->lock);
|
||||
rc = msm_rpc_close(snd_cad_sys->ept);
|
||||
if (rc < 0)
|
||||
MM_ERR("msm_rpc_close failed\n");
|
||||
snd_cad_sys->ept = NULL;
|
||||
mutex_unlock(&snd_cad_sys->lock);
|
||||
return rc;
|
||||
}
|
||||
static int snd_cad_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct snd_cad_ctxt *snd = &the_snd;
|
||||
int rc = 0;
|
||||
|
||||
mutex_lock(&snd->lock);
|
||||
if (snd->opened == 0) {
|
||||
if (snd->ept == NULL) {
|
||||
snd->ept = msm_rpc_connect_compatible(RPC_SND_PROG,
|
||||
RPC_SND_VERS, 0);
|
||||
if (IS_ERR(snd->ept)) {
|
||||
rc = PTR_ERR(snd->ept);
|
||||
snd->ept = NULL;
|
||||
MM_ERR("cad connect failed with VERS %x\n",
|
||||
RPC_SND_VERS);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
file->private_data = snd;
|
||||
snd->opened = 1;
|
||||
} else {
|
||||
MM_ERR("snd already opened\n");
|
||||
rc = -EBUSY;
|
||||
}
|
||||
|
||||
err:
|
||||
mutex_unlock(&snd->lock);
|
||||
return rc;
|
||||
}
|
||||
static int snd_cad_sys_open(void)
|
||||
{
|
||||
struct snd_cad_sys_ctxt *snd_cad_sys = &the_snd_cad_sys;
|
||||
int rc = 0;
|
||||
|
||||
mutex_lock(&snd_cad_sys->lock);
|
||||
if (snd_cad_sys->ept == NULL) {
|
||||
snd_cad_sys->ept = msm_rpc_connect_compatible(RPC_SND_PROG,
|
||||
RPC_SND_VERS, 0);
|
||||
if (IS_ERR(snd_cad_sys->ept)) {
|
||||
rc = PTR_ERR(snd_cad_sys->ept);
|
||||
snd_cad_sys->ept = NULL;
|
||||
MM_ERR("func %s : cad connect failed with VERS %x\n",
|
||||
__func__, RPC_SND_VERS);
|
||||
goto err;
|
||||
}
|
||||
} else
|
||||
MM_DBG("snd already opened\n");
|
||||
err:
|
||||
mutex_unlock(&snd_cad_sys->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const struct file_operations snd_cad_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = snd_cad_open,
|
||||
.release = snd_cad_release,
|
||||
.unlocked_ioctl = snd_cad_ioctl,
|
||||
};
|
||||
|
||||
struct miscdevice snd_cad_misc = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = "msm_cad",
|
||||
.fops = &snd_cad_fops,
|
||||
};
|
||||
|
||||
static long snd_cad_vol_enable(const char *arg)
|
||||
{
|
||||
struct snd_cad_sys_ctxt *snd_cad_sys = &the_snd_cad_sys;
|
||||
struct snd_cad_set_volume_msg vmsg;
|
||||
struct msm_cad_volume_config vol;
|
||||
int rc = 0;
|
||||
|
||||
rc = sscanf(arg, "%d %d %d %d", &vol.device.rx_device,
|
||||
&vol.device.tx_device, &vol.method, &vol.volume);
|
||||
if (rc != 4) {
|
||||
MM_ERR("Invalid arguments. Usage: <rx_device> <tx_device>" \
|
||||
"method> <volume>\n");
|
||||
rc = -EINVAL;
|
||||
return rc;
|
||||
}
|
||||
|
||||
vmsg.args.device.rx_device = cpu_to_be32(vol.device.rx_device);
|
||||
vmsg.args.device.tx_device = cpu_to_be32(vol.device.tx_device);
|
||||
vmsg.args.method = cpu_to_be32(vol.method);
|
||||
if (vol.method != SND_METHOD_VOICE) {
|
||||
MM_ERR("snd_cad_ioctl set volume: invalid method\n");
|
||||
rc = -EINVAL;
|
||||
return rc;
|
||||
}
|
||||
|
||||
vmsg.args.volume = cpu_to_be32(vol.volume);
|
||||
vmsg.args.cb_func = -1;
|
||||
vmsg.args.client_data = 0;
|
||||
|
||||
MM_DBG("snd_cad_set_volume %d %d %d %d\n", vol.device.rx_device,
|
||||
vol.device.rx_device, vol.method, vol.volume);
|
||||
|
||||
rc = msm_rpc_call(snd_cad_sys->ept,
|
||||
SND_CAD_SET_VOLUME_PROC,
|
||||
&vmsg, sizeof(vmsg), 5 * HZ);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static long snd_cad_dev_enable(const char *arg)
|
||||
{
|
||||
struct snd_cad_sys_ctxt *snd_cad_sys = &the_snd_cad_sys;
|
||||
struct snd_cad_set_device_msg dmsg;
|
||||
struct msm_cad_device_config dev;
|
||||
int rc = 0;
|
||||
|
||||
|
||||
rc = sscanf(arg, "%d %d %d %d", &dev.device.rx_device,
|
||||
&dev.device.tx_device, &dev.ear_mute, &dev.mic_mute);
|
||||
if (rc != 4) {
|
||||
MM_ERR("Invalid arguments. Usage: <rx_device> <tx_device> "\
|
||||
"<ear_mute> <mic_mute>\n");
|
||||
rc = -EINVAL;
|
||||
return rc;
|
||||
}
|
||||
dmsg.args.device.rx_device = cpu_to_be32(dev.device.rx_device);
|
||||
dmsg.args.device.tx_device = cpu_to_be32(dev.device.tx_device);
|
||||
dmsg.args.device.pathtype = cpu_to_be32(CAD_DEVICE_PATH_RX_TX);
|
||||
dmsg.args.ear_mute = cpu_to_be32(dev.ear_mute);
|
||||
dmsg.args.mic_mute = cpu_to_be32(dev.mic_mute);
|
||||
if (check_mute(dev.ear_mute) < 0 ||
|
||||
check_mute(dev.mic_mute) < 0) {
|
||||
MM_ERR("snd_cad_ioctl set device: invalid mute status\n");
|
||||
rc = -EINVAL;
|
||||
return rc;
|
||||
}
|
||||
dmsg.args.cb_func = -1;
|
||||
dmsg.args.client_data = 0;
|
||||
curr_dev.tx_dev = dev.device.tx_device;
|
||||
curr_dev.rx_dev = dev.device.rx_device;
|
||||
|
||||
MM_INFO("snd_cad_set_device %d %d %d %d\n", dev.device.rx_device,
|
||||
dev.device.tx_device, dev.ear_mute, dev.mic_mute);
|
||||
|
||||
rc = msm_rpc_call(snd_cad_sys->ept,
|
||||
SND_CAD_SET_DEVICE_PROC,
|
||||
&dmsg, sizeof(dmsg), 5 * HZ);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ssize_t snd_cad_dev_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t size)
|
||||
{
|
||||
ssize_t status;
|
||||
struct snd_cad_sys_ctxt *snd_cad_sys = &the_snd_cad_sys;
|
||||
int rc = 0;
|
||||
|
||||
rc = snd_cad_sys_open();
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
mutex_lock(&snd_cad_sys->lock);
|
||||
status = snd_cad_dev_enable(buf);
|
||||
mutex_unlock(&snd_cad_sys->lock);
|
||||
|
||||
rc = snd_cad_sys_release();
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
return status ? : size;
|
||||
}
|
||||
|
||||
static ssize_t snd_cad_vol_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t size)
|
||||
{
|
||||
ssize_t status;
|
||||
struct snd_cad_sys_ctxt *snd_cad_sys = &the_snd_cad_sys;
|
||||
int rc = 0;
|
||||
|
||||
rc = snd_cad_sys_open();
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
mutex_lock(&snd_cad_sys->lock);
|
||||
status = snd_cad_vol_enable(buf);
|
||||
mutex_unlock(&snd_cad_sys->lock);
|
||||
|
||||
rc = snd_cad_sys_release();
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
return status ? : size;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(device, S_IWUSR | S_IRUGO,
|
||||
NULL, snd_cad_dev_store);
|
||||
|
||||
static DEVICE_ATTR(volume, S_IWUSR | S_IRUGO,
|
||||
NULL, snd_cad_vol_store);
|
||||
|
||||
static int snd_cad_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_cad_ctxt *snd = &the_snd;
|
||||
struct snd_cad_sys_ctxt *snd_cad_sys = &the_snd_cad_sys;
|
||||
int rc = 0;
|
||||
|
||||
mutex_init(&snd->lock);
|
||||
mutex_init(&snd_cad_sys->lock);
|
||||
snd_cad_sys->ept = NULL;
|
||||
snd->cad_epts =
|
||||
(struct msm_cad_endpoints *)pdev->dev.platform_data;
|
||||
rc = misc_register(&snd_cad_misc);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = device_create_file(snd_cad_misc.this_device, &dev_attr_device);
|
||||
if (rc) {
|
||||
misc_deregister(&snd_cad_misc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = device_create_file(snd_cad_misc.this_device, &dev_attr_volume);
|
||||
if (rc) {
|
||||
device_remove_file(snd_cad_misc.this_device,
|
||||
&dev_attr_device);
|
||||
misc_deregister(&snd_cad_misc);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct platform_driver snd_cad_plat_driver = {
|
||||
.probe = snd_cad_probe,
|
||||
.driver = {
|
||||
.name = "msm_cad",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init snd_cad_init(void)
|
||||
{
|
||||
return platform_driver_register(&snd_cad_plat_driver);
|
||||
}
|
||||
|
||||
module_init(snd_cad_init);
|
||||
|
||||
MODULE_DESCRIPTION("MSM CAD SND driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
@@ -222,6 +222,28 @@ struct msm_snd_device_config {
|
||||
|
||||
#define SND_SET_DEVICE _IOW(SND_IOCTL_MAGIC, 2, struct msm_device_config *)
|
||||
|
||||
enum cad_device_path_type {
|
||||
CAD_DEVICE_PATH_RX, /*For Decoding session*/
|
||||
CAD_DEVICE_PATH_TX, /* For Encoding session*/
|
||||
CAD_DEVICE_PATH_RX_TX, /* For Voice call */
|
||||
CAD_DEVICE_PATH_LB, /* For loopback (FM Analog)*/
|
||||
CAD_DEVICE_PATH_MAX
|
||||
};
|
||||
|
||||
struct cad_devices_type {
|
||||
uint32_t rx_device;
|
||||
uint32_t tx_device;
|
||||
enum cad_device_path_type pathtype;
|
||||
};
|
||||
|
||||
struct msm_cad_device_config {
|
||||
struct cad_devices_type device;
|
||||
uint32_t ear_mute;
|
||||
uint32_t mic_mute;
|
||||
};
|
||||
|
||||
#define CAD_SET_DEVICE _IOW(SND_IOCTL_MAGIC, 2, struct msm_cad_device_config *)
|
||||
|
||||
#define SND_METHOD_VOICE 0
|
||||
|
||||
struct msm_snd_volume_config {
|
||||
@@ -232,6 +254,14 @@ struct msm_snd_volume_config {
|
||||
|
||||
#define SND_SET_VOLUME _IOW(SND_IOCTL_MAGIC, 3, struct msm_snd_volume_config *)
|
||||
|
||||
struct msm_cad_volume_config {
|
||||
struct cad_devices_type device;
|
||||
uint32_t method;
|
||||
uint32_t volume;
|
||||
};
|
||||
|
||||
#define CAD_SET_VOLUME _IOW(SND_IOCTL_MAGIC, 3, struct msm_cad_volume_config *)
|
||||
|
||||
/* Returns the number of SND endpoints supported. */
|
||||
|
||||
#define SND_GET_NUM_ENDPOINTS _IOR(SND_IOCTL_MAGIC, 4, unsigned *)
|
||||
@@ -254,6 +284,24 @@ struct msm_snd_endpoint {
|
||||
#define SND_AVC_CTL _IOW(SND_IOCTL_MAGIC, 6, unsigned *)
|
||||
#define SND_AGC_CTL _IOW(SND_IOCTL_MAGIC, 7, unsigned *)
|
||||
|
||||
/*return the number of CAD endpoints supported. */
|
||||
|
||||
#define CAD_GET_NUM_ENDPOINTS _IOR(SND_IOCTL_MAGIC, 4, unsigned *)
|
||||
|
||||
struct msm_cad_endpoint {
|
||||
int id; /* input and output */
|
||||
char name[64]; /* output only */
|
||||
};
|
||||
|
||||
/* Takes an index between 0 and one less than the number returned by
|
||||
* SND_GET_NUM_ENDPOINTS, and returns the CAD index and name of a
|
||||
* CAD endpoint. On input, the .id field contains the number of the
|
||||
* endpoint, and on exit it contains the SND index, while .name contains
|
||||
* the description of the endpoint.
|
||||
*/
|
||||
|
||||
#define CAD_GET_ENDPOINT _IOWR(SND_IOCTL_MAGIC, 5, struct msm_cad_endpoint *)
|
||||
|
||||
struct msm_audio_pcm_config {
|
||||
uint32_t pcm_feedback; /* 0 - disable > 0 - enable */
|
||||
uint32_t buffer_count; /* Number of buffers to allocate */
|
||||
|
||||
Reference in New Issue
Block a user