ASoC: qcom: qdsp6v2: update the audio native drivers to 64bit

Add support for compat ioctls in audio native drivers.

Change-Id: I1e84777ee8775b91f2daddc99da327bb3b08cb15
Signed-off-by: Aravind Kumar <akumark@codeaurora.org>
This commit is contained in:
Aravind Kumar 2014-04-08 11:42:05 +05:30
parent 8c0c40d987
commit bdede7a49d
18 changed files with 2690 additions and 454 deletions

View file

@ -20,6 +20,7 @@
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/msm_audio_aac.h>
#include <linux/compat.h>
#include <asm/atomic.h>
#include <asm/ioctls.h>
#include "audio_utils.h"
@ -33,9 +34,7 @@
#define AAC_FORMAT_ADTS 65535
/* ------------------- device --------------------- */
static long aac_in_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
static long aac_in_ioctl_shared(struct file *file, unsigned int cmd, void *arg)
{
struct q6audio_in *audio = file->private_data;
int rc = 0;
@ -150,52 +149,61 @@ static long aac_in_ioctl(struct file *file,
break;
}
case AUDIO_GET_AAC_ENC_CONFIG: {
struct msm_audio_aac_enc_config cfg;
struct msm_audio_aac_enc_config *cfg;
struct msm_audio_aac_enc_config *enc_cfg;
memset(&cfg, 0, sizeof(cfg));
cfg = (struct msm_audio_aac_enc_config *)arg;
if (cfg == NULL) {
pr_err("%s: NULL config pointer for %s\n",
__func__, "AUDIO_GET_AAC_CONFIG");
rc = -EINVAL;
break;
}
memset(cfg, 0, sizeof(*cfg));
enc_cfg = audio->enc_cfg;
if (enc_cfg->channels == CH_MODE_MONO)
cfg.channels = 1;
cfg->channels = 1;
else
cfg.channels = 2;
cfg.sample_rate = enc_cfg->sample_rate;
cfg.bit_rate = enc_cfg->bit_rate;
cfg->channels = 2;
cfg->sample_rate = enc_cfg->sample_rate;
cfg->bit_rate = enc_cfg->bit_rate;
switch (enc_cfg->stream_format) {
case 0x00:
cfg.stream_format = AUDIO_AAC_FORMAT_ADTS;
cfg->stream_format = AUDIO_AAC_FORMAT_ADTS;
break;
case 0x01:
cfg.stream_format = AUDIO_AAC_FORMAT_LOAS;
cfg->stream_format = AUDIO_AAC_FORMAT_LOAS;
break;
case 0x02:
cfg.stream_format = AUDIO_AAC_FORMAT_ADIF;
cfg->stream_format = AUDIO_AAC_FORMAT_ADIF;
break;
default:
case 0x03:
cfg.stream_format = AUDIO_AAC_FORMAT_RAW;
cfg->stream_format = AUDIO_AAC_FORMAT_RAW;
}
pr_debug("%s:session id %d: Get-aac-cfg: format=%d sr=%d"
"bitrate=%d\n", __func__, audio->ac->session,
cfg.stream_format, cfg.sample_rate, cfg.bit_rate);
if (copy_to_user((void *)arg, &cfg, sizeof(cfg)))
rc = -EFAULT;
cfg->stream_format, cfg->sample_rate, cfg->bit_rate);
break;
}
case AUDIO_SET_AAC_ENC_CONFIG: {
struct msm_audio_aac_enc_config cfg;
struct msm_audio_aac_enc_config *cfg;
struct msm_audio_aac_enc_config *enc_cfg;
uint32_t min_bitrate, max_bitrate;
enc_cfg = audio->enc_cfg;
if (copy_from_user(&cfg, (void *)arg, sizeof(cfg))) {
rc = -EFAULT;
cfg = (struct msm_audio_aac_enc_config *)arg;
if (cfg == NULL) {
pr_err("%s: NULL config pointer for %s\n",
"AUDIO_SET_AAC_ENC_CONFIG", __func__);
rc = -EINVAL;
break;
}
enc_cfg = audio->enc_cfg;
pr_debug("%s:session id %d: Set-aac-cfg: stream=%d\n", __func__,
audio->ac->session, cfg.stream_format);
audio->ac->session, cfg->stream_format);
switch (cfg.stream_format) {
switch (cfg->stream_format) {
case AUDIO_AAC_FORMAT_ADTS:
enc_cfg->stream_format = 0x00;
break;
@ -211,46 +219,47 @@ static long aac_in_ioctl(struct file *file,
default:
pr_err("%s:session id %d: unsupported AAC format %d\n",
__func__, audio->ac->session,
cfg.stream_format);
cfg->stream_format);
rc = -EINVAL;
break;
}
if (cfg.channels == 1) {
cfg.channels = CH_MODE_MONO;
} else if (cfg.channels == 2) {
cfg.channels = CH_MODE_STEREO;
if (cfg->channels == 1) {
cfg->channels = CH_MODE_MONO;
} else if (cfg->channels == 2) {
cfg->channels = CH_MODE_STEREO;
} else {
rc = -EINVAL;
break;
}
if ((cfg.sample_rate < 8000) || (cfg.sample_rate > 48000)) {
pr_err("%s: ERROR in setting samplerate = %d\n",
__func__, cfg.sample_rate);
min_bitrate = ((cfg->sample_rate)*(cfg->channels))/2;
if (min_bitrate < 24000)
min_bitrate = 24000;
max_bitrate = 6*(cfg->sample_rate)*(cfg->channels);
if (max_bitrate > 192000)
max_bitrate = 192000;
if ((cfg->bit_rate < min_bitrate) ||
(cfg->bit_rate > max_bitrate)) {
pr_err("%s: bitrate permissible: max=%d, min=%d\n",
__func__, max_bitrate, min_bitrate);
pr_err("%s: ERROR in setting bitrate = %d\n",
__func__, cfg->bit_rate);
rc = -EINVAL;
break;
}
/* For aac-lc, min_bit_rate = min(24Kbps, 0.5*SR*num_chan);
max_bi_rate = min(192Kbps, 6*SR*num_chan);
min_sample_rate = 8000Hz, max_rate=48000 */
min_bitrate = ((cfg.sample_rate)*(cfg.channels))/2;
if (min_bitrate < 24000)
min_bitrate = 24000;
max_bitrate = 6*(cfg.sample_rate)*(cfg.channels);
if (max_bitrate > 192000)
max_bitrate = 192000;
if ((cfg.bit_rate < min_bitrate) ||
(cfg.bit_rate > max_bitrate)) {
pr_err("%s: bitrate permissible: max=%d, min=%d\n",
__func__, max_bitrate, min_bitrate);
if ((cfg->bit_rate < 24000) || (cfg->bit_rate > 192000)) {
pr_err("%s: ERROR in setting bitrate = %d\n",
__func__, cfg.bit_rate);
__func__, cfg->bit_rate);
rc = -EINVAL;
break;
}
enc_cfg->sample_rate = cfg.sample_rate;
enc_cfg->channels = cfg.channels;
enc_cfg->bit_rate = cfg.bit_rate;
enc_cfg->sample_rate = cfg->sample_rate;
enc_cfg->channels = cfg->channels;
enc_cfg->bit_rate = cfg->bit_rate;
pr_debug("%s:session id %d: Set-aac-cfg:SR= 0x%x ch=0x%x"
"bitrate=0x%x, format(adts/raw) = %d\n",
__func__, audio->ac->session, enc_cfg->sample_rate,
@ -258,32 +267,25 @@ static long aac_in_ioctl(struct file *file,
enc_cfg->stream_format);
break;
}
case AUDIO_GET_AAC_CONFIG: {
if (copy_to_user((void *)arg, &audio->codec_cfg,
sizeof(struct msm_audio_aac_config))) {
rc = -EFAULT;
break;
}
break;
}
case AUDIO_SET_AAC_CONFIG: {
struct msm_audio_aac_config aac_cfg;
struct msm_audio_aac_config *aac_cfg;
struct msm_audio_aac_config *audio_aac_cfg;
struct msm_audio_aac_enc_config *enc_cfg;
enc_cfg = audio->enc_cfg;
audio_aac_cfg = audio->codec_cfg;
aac_cfg = (struct msm_audio_aac_config *)arg;
if (copy_from_user(&aac_cfg, (void *)arg,
sizeof(struct msm_audio_aac_config))) {
rc = -EFAULT;
if (aac_cfg == NULL) {
pr_err("%s: NULL config pointer %s\n",
__func__, "AUDIO_SET_AAC_CONFIG");
rc = -EINVAL;
break;
}
pr_debug("%s:session id %d: AUDIO_SET_AAC_CONFIG: sbr_flag = %d"
" sbr_ps_flag = %d\n", __func__,
audio->ac->session, aac_cfg.sbr_on_flag,
aac_cfg.sbr_ps_on_flag);
audio_aac_cfg->sbr_on_flag = aac_cfg.sbr_on_flag;
audio_aac_cfg->sbr_ps_on_flag = aac_cfg.sbr_ps_on_flag;
pr_debug("%s:session id %d: AUDIO_SET_AAC_CONFIG: sbr_flag = %d sbr_ps_flag = %d\n",
__func__, audio->ac->session, aac_cfg->sbr_on_flag,
aac_cfg->sbr_ps_on_flag);
audio_aac_cfg->sbr_on_flag = aac_cfg->sbr_on_flag;
audio_aac_cfg->sbr_ps_on_flag = aac_cfg->sbr_ps_on_flag;
if ((audio_aac_cfg->sbr_on_flag == 1) ||
(audio_aac_cfg->sbr_ps_on_flag == 1)) {
if (enc_cfg->sample_rate < 24000) {
@ -296,11 +298,247 @@ static long aac_in_ioctl(struct file *file,
break;
}
default:
pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd);
rc = -EINVAL;
}
return rc;
}
static long aac_in_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct q6audio_in *audio = file->private_data;
int rc = 0;
switch (cmd) {
case AUDIO_START:
case AUDIO_STOP: {
rc = aac_in_ioctl_shared(file, cmd, NULL);
break;
}
case AUDIO_GET_AAC_ENC_CONFIG: {
struct msm_audio_aac_enc_config cfg;
rc = aac_in_ioctl_shared(file, cmd, &cfg);
if (rc) {
pr_err("%s:AUDIO_GET_AAC_ENC_CONFIG failed. rc=%d\n",
__func__, rc);
break;
}
if (copy_to_user((void *)arg, &cfg, sizeof(cfg))) {
pr_err("%s: copy_to_user for AUDIO_GET_AAC_ENC_CONFIG failed\n",
__func__);
rc = -EFAULT;
}
break;
}
case AUDIO_SET_AAC_ENC_CONFIG: {
struct msm_audio_aac_enc_config cfg;
if (copy_from_user(&cfg, (void *)arg, sizeof(cfg))) {
pr_err("%s: copy_from_user for AUDIO_SET_AAC_ENC_CONFIG failed\n",
__func__);
rc = -EFAULT;
break;
}
rc = aac_in_ioctl_shared(file, cmd, &cfg);
if (rc)
pr_err("%s:AUDIO_SET_AAC_ENC_CONFIG failed. rc=%d\n",
__func__, rc);
break;
}
case AUDIO_GET_AAC_CONFIG: {
if (copy_to_user((void *)arg, &audio->codec_cfg,
sizeof(struct msm_audio_aac_config))) {
pr_err("%s: copy_to_user for AUDIO_GET_AAC_CONFIG failed\n",
__func__);
rc = -EFAULT;
break;
}
break;
}
case AUDIO_SET_AAC_CONFIG: {
struct msm_audio_aac_config aac_cfg;
if (copy_from_user(&aac_cfg, (void *)arg,
sizeof(struct msm_audio_aac_config))) {
pr_err("%s: copy_to_user for AUDIO_SET_CONFIG failed\n",
__func__);
rc = -EFAULT;
break;
}
rc = aac_in_ioctl_shared(file, cmd, &aac_cfg);
if (rc)
pr_err("%s:AUDIO_SET_AAC_CONFIG failed. rc=%d\n",
__func__, rc);
break;
}
default:
pr_err("%s: Unknown ioctl cmd=%d\n", __func__, cmd);
rc = -EINVAL;
}
return rc;
}
#ifdef CONFIG_COMPAT
struct msm_audio_aac_enc_config32 {
u32 channels;
u32 sample_rate;
u32 bit_rate;
u32 stream_format;
};
struct msm_audio_aac_config32 {
s16 format;
u16 audio_object;
u16 ep_config; /* 0 ~ 3 useful only obj = ERLC */
u16 aac_section_data_resilience_flag;
u16 aac_scalefactor_data_resilience_flag;
u16 aac_spectral_data_resilience_flag;
u16 sbr_on_flag;
u16 sbr_ps_on_flag;
u16 dual_mono_mode;
u16 channel_configuration;
u16 sample_rate;
};
enum {
AUDIO_SET_AAC_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC,
(AUDIO_MAX_COMMON_IOCTL_NUM+0), struct msm_audio_aac_config32),
AUDIO_GET_AAC_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC,
(AUDIO_MAX_COMMON_IOCTL_NUM+1), struct msm_audio_aac_config32),
AUDIO_SET_AAC_ENC_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC,
(AUDIO_MAX_COMMON_IOCTL_NUM+3), struct msm_audio_aac_enc_config32),
AUDIO_GET_AAC_ENC_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC,
(AUDIO_MAX_COMMON_IOCTL_NUM+4), struct msm_audio_aac_enc_config32)
};
static long aac_in_compat_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
struct q6audio_in *audio = file->private_data;
int rc = 0;
switch (cmd) {
case AUDIO_START:
case AUDIO_STOP: {
rc = aac_in_ioctl_shared(file, cmd, NULL);
break;
}
case AUDIO_GET_AAC_ENC_CONFIG_32: {
struct msm_audio_aac_enc_config cfg;
struct msm_audio_aac_enc_config32 cfg_32;
cmd = AUDIO_GET_AAC_ENC_CONFIG;
rc = aac_in_ioctl_shared(file, cmd, &cfg);
if (rc) {
pr_err("%s:AUDIO_GET_AAC_ENC_CONFIG_32 failed. Rc= %d\n",
__func__, rc);
break;
}
cfg_32.channels = cfg.channels;
cfg_32.sample_rate = cfg.sample_rate;
cfg_32.bit_rate = cfg.bit_rate;
cfg_32.stream_format = cfg.stream_format;
if (copy_to_user((void *)arg, &cfg_32, sizeof(cfg_32))) {
pr_err("%s: copy_to_user for AUDIO_GET_AAC_ENC_CONFIG_32 failed\n",
__func__);
rc = -EFAULT;
}
break;
}
case AUDIO_SET_AAC_ENC_CONFIG_32: {
struct msm_audio_aac_enc_config cfg;
struct msm_audio_aac_enc_config32 cfg_32;
if (copy_from_user(&cfg_32, (void *)arg, sizeof(cfg_32))) {
pr_err("%s: copy_from_user for AUDIO_GET_AAC_ENC_CONFIG_32 failed\n",
__func__);
rc = -EFAULT;
break;
}
cfg.channels = cfg_32.channels;
cfg.sample_rate = cfg_32.sample_rate;
cfg.bit_rate = cfg_32.bit_rate;
cfg.stream_format = cfg_32.stream_format;
/* The command should be converted from 32 bit to normal
* before the shared ioctl is called as shared ioctl
* can process only normal commands */
cmd = AUDIO_SET_AAC_ENC_CONFIG;
rc = aac_in_ioctl_shared(file, cmd, &cfg);
if (rc)
pr_err("%s:AUDIO_SET_AAC_ENC_CONFIG_32 failed. rc=%d\n",
__func__, rc);
break;
}
case AUDIO_GET_AAC_CONFIG_32: {
struct msm_audio_aac_config *aac_config;
struct msm_audio_aac_config32 aac_config_32;
aac_config = (struct msm_audio_aac_config *)audio->codec_cfg;
aac_config_32.format = aac_config->format;
aac_config_32.audio_object = aac_config->audio_object;
aac_config_32.ep_config = aac_config->ep_config;
aac_config_32.aac_section_data_resilience_flag =
aac_config->aac_section_data_resilience_flag;
aac_config_32.aac_scalefactor_data_resilience_flag =
aac_config->aac_scalefactor_data_resilience_flag;
aac_config_32.aac_spectral_data_resilience_flag =
aac_config->aac_spectral_data_resilience_flag;
aac_config_32.sbr_on_flag = aac_config->sbr_on_flag;
aac_config_32.sbr_ps_on_flag = aac_config->sbr_ps_on_flag;
aac_config_32.dual_mono_mode = aac_config->dual_mono_mode;
aac_config_32.channel_configuration =
aac_config->channel_configuration;
aac_config_32.sample_rate = aac_config->sample_rate;
if (copy_to_user((void *)arg, &aac_config_32,
sizeof(aac_config_32))) {
pr_err("%s: copy_to_user for AUDIO_GET_AAC_CONFIG_32 failed\n",
__func__);
rc = -EFAULT;
break;
}
break;
}
case AUDIO_SET_AAC_CONFIG_32: {
struct msm_audio_aac_config aac_cfg;
struct msm_audio_aac_config32 aac_cfg_32;
if (copy_from_user(&aac_cfg_32, (void *)arg,
sizeof(aac_cfg_32))) {
pr_err("%s: copy_from_user for AUDIO_SET_AAC_CONFIG_32 failed\n",
__func__);
rc = -EFAULT;
break;
}
aac_cfg.format = aac_cfg_32.format;
aac_cfg.audio_object = aac_cfg_32.audio_object;
aac_cfg.ep_config = aac_cfg_32.ep_config;
aac_cfg.aac_section_data_resilience_flag =
aac_cfg_32.aac_section_data_resilience_flag;
aac_cfg.aac_scalefactor_data_resilience_flag =
aac_cfg_32.aac_scalefactor_data_resilience_flag;
aac_cfg.aac_spectral_data_resilience_flag =
aac_cfg_32.aac_spectral_data_resilience_flag;
aac_cfg.sbr_on_flag = aac_cfg_32.sbr_on_flag;
aac_cfg.sbr_ps_on_flag = aac_cfg_32.sbr_ps_on_flag;
aac_cfg.dual_mono_mode = aac_cfg_32.dual_mono_mode;
aac_cfg.channel_configuration =
aac_cfg_32.channel_configuration;
aac_cfg.sample_rate = aac_cfg_32.sample_rate;
cmd = AUDIO_SET_AAC_CONFIG;
rc = aac_in_ioctl_shared(file, cmd, &aac_cfg);
if (rc)
pr_err("%s:AUDIO_SET_AAC_CONFIG failed. Rc= %d\n",
__func__, rc);
break;
}
default:
pr_err("%s: Unknown ioctl cmd = %d\n", __func__, cmd);
rc = -EINVAL;
}
return rc;
}
#else
#define aac_in_compat_ioctl NULL
#endif
static int aac_in_open(struct inode *inode, struct file *file)
{
struct q6audio_in *audio = NULL;
@ -426,6 +664,7 @@ static int aac_in_open(struct inode *inode, struct file *file)
audio->opened = 1;
atomic_set(&audio->in_count, PCM_BUF_COUNT);
atomic_set(&audio->out_count, 0x00);
audio->enc_compat_ioctl = aac_in_compat_ioctl;
audio->enc_ioctl = aac_in_ioctl;
file->private_data = audio;
@ -446,6 +685,7 @@ static const struct file_operations audio_in_fops = {
.read = audio_in_read,
.write = audio_in_write,
.unlocked_ioctl = audio_in_ioctl,
.compat_ioctl = audio_in_compat_ioctl
};
struct miscdevice audio_aac_in_misc = {

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
/* Copyright (c) 2010-2012, 2014 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -20,6 +20,7 @@
#include <linux/wait.h>
#include <linux/dma-mapping.h>
#include <linux/msm_audio_amrnb.h>
#include <linux/compat.h>
#include <asm/atomic.h>
#include <asm/ioctls.h>
#include "audio_utils.h"
@ -30,9 +31,8 @@
/* Maximum 10 frames in buffer with meta */
#define FRAME_SIZE (1 + ((32+sizeof(struct meta_out_dsp)) * 10))
/* ------------------- device --------------------- */
static long amrnb_in_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
static long amrnb_in_ioctl_shared(struct file *file,
unsigned int cmd, void *arg)
{
struct q6audio_in *audio = file->private_data;
int rc = 0;
@ -108,23 +108,21 @@ static long amrnb_in_ioctl(struct file *file,
}
break;
}
case AUDIO_GET_AMRNB_ENC_CONFIG_V2: {
if (copy_to_user((void *)arg, audio->enc_cfg,
sizeof(struct msm_audio_amrnb_enc_config_v2)))
rc = -EFAULT;
break;
}
case AUDIO_SET_AMRNB_ENC_CONFIG_V2: {
struct msm_audio_amrnb_enc_config_v2 cfg;
struct msm_audio_amrnb_enc_config_v2 *cfg;
struct msm_audio_amrnb_enc_config_v2 *enc_cfg;
enc_cfg = audio->enc_cfg;
if (copy_from_user(&cfg, (void *) arg,
sizeof(struct msm_audio_amrnb_enc_config_v2))) {
rc = -EFAULT;
cfg = (struct msm_audio_amrnb_enc_config_v2 *)arg;
if (cfg == NULL) {
pr_err("%s: NULL config pointer for %s\n",
__func__,
"AUDIO_SET_AMRNB_ENC_CONFIG_V2");
rc = -EINVAL;
break;
}
if (cfg.band_mode > 8 ||
cfg.band_mode < 1) {
enc_cfg = audio->enc_cfg;
if (cfg->band_mode > 8 ||
cfg->band_mode < 1) {
pr_err("%s:session id %d: invalid band mode\n",
__func__, audio->ac->session);
rc = -EINVAL;
@ -133,8 +131,8 @@ static long amrnb_in_ioctl(struct file *file,
/* AMR NB encoder accepts values between 0-7
while openmax provides value between 1-8
as per spec */
enc_cfg->band_mode = (cfg.band_mode - 1);
enc_cfg->dtx_enable = (cfg.dtx_enable ? 1 : 0);
enc_cfg->band_mode = (cfg->band_mode - 1);
enc_cfg->dtx_enable = (cfg->dtx_enable ? 1 : 0);
enc_cfg->frame_format = 0;
pr_debug("%s:session id %d: band_mode = 0x%x dtx_enable=0x%x\n",
__func__, audio->ac->session,
@ -142,11 +140,127 @@ static long amrnb_in_ioctl(struct file *file,
break;
}
default:
pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd);
rc = -EINVAL;
}
return rc;
}
static long amrnb_in_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
struct q6audio_in *audio = file->private_data;
int rc = 0;
switch (cmd) {
case AUDIO_START:
case AUDIO_STOP: {
rc = amrnb_in_ioctl_shared(file, cmd, NULL);
break;
}
case AUDIO_GET_AMRNB_ENC_CONFIG_V2: {
if (copy_to_user((void *)arg, audio->enc_cfg,
sizeof(struct msm_audio_amrnb_enc_config_v2))) {
pr_err("%s: copy_to_user for AUDIO_GET_AMRNB_ENC_CONFIG_V2 failed\n",
__func__);
rc = -EFAULT;
}
break;
}
case AUDIO_SET_AMRNB_ENC_CONFIG_V2: {
struct msm_audio_amrnb_enc_config_v2 cfg;
if (copy_from_user(&cfg, (void *) arg,
sizeof(cfg))) {
pr_err("%s: copy_from_user for AUDIO_SET_AMRNB_ENC_CONFIG_V2 failed\n",
__func__);
rc = -EFAULT;
break;
}
rc = amrnb_in_ioctl_shared(file, cmd, &cfg);
if (rc)
pr_err("%s: AUDIO_SET_AMRNB_ENC_CONFIG_V2 failed. rc=%d\n",
__func__, rc);
break;
}
default:
pr_err("%s: Unknown ioctl cmd=%d", __func__, cmd);
rc = -EINVAL;
}
return rc;
}
#ifdef CONFIG_COMPAT
struct msm_audio_amrnb_enc_config_v2_32 {
u32 band_mode;
u32 dtx_enable;
u32 frame_format;
};
enum {
AUDIO_GET_AMRNB_ENC_CONFIG_V2_32 = _IOW(AUDIO_IOCTL_MAGIC,
(AUDIO_MAX_COMMON_IOCTL_NUM+2),
struct msm_audio_amrnb_enc_config_v2_32),
AUDIO_SET_AMRNB_ENC_CONFIG_V2_32 = _IOR(AUDIO_IOCTL_MAGIC,
(AUDIO_MAX_COMMON_IOCTL_NUM+3),
struct msm_audio_amrnb_enc_config_v2_32)
};
static long amrnb_in_compat_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
struct q6audio_in *audio = file->private_data;
int rc = 0;
switch (cmd) {
case AUDIO_START:
case AUDIO_STOP: {
rc = amrnb_in_ioctl_shared(file, cmd, NULL);
break;
}
case AUDIO_GET_AMRNB_ENC_CONFIG_V2_32: {
struct msm_audio_amrnb_enc_config_v2 *amrnb_config;
struct msm_audio_amrnb_enc_config_v2_32 amrnb_config_32;
amrnb_config =
(struct msm_audio_amrnb_enc_config_v2 *)audio->enc_cfg;
amrnb_config_32.band_mode = amrnb_config->band_mode;
amrnb_config_32.dtx_enable = amrnb_config->dtx_enable;
amrnb_config_32.frame_format = amrnb_config->frame_format;
if (copy_to_user((void *)arg, &amrnb_config_32,
sizeof(amrnb_config_32))) {
pr_err("%s: copy_to_user for AUDIO_GET_AMRNB_ENC_CONFIG_V2_32 failed",
__func__);
rc = -EFAULT;
}
break;
}
case AUDIO_SET_AMRNB_ENC_CONFIG_V2_32: {
struct msm_audio_amrnb_enc_config_v2_32 cfg_32;
if (copy_from_user(&cfg_32, (void *) arg,
sizeof(cfg_32))) {
pr_err("%s: copy_from_user for AUDIO_SET_AMRNB_ENC_CONFIG_V2_32 failed\n",
__func__);
rc = -EFAULT;
break;
}
cmd = AUDIO_SET_AMRNB_ENC_CONFIG_V2;
rc = amrnb_in_ioctl_shared(file, cmd, &cfg_32);
if (rc)
pr_err("%s:AUDIO_SET_AMRNB_ENC_CONFIG_V2 failed rc= %d\n",
__func__, rc);
break;
}
default:
pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd);
rc = -EINVAL;
}
return rc;
}
#else
#define amrnb_in_compat_ioctl NULL
#endif
static int amrnb_in_open(struct inode *inode, struct file *file)
{
struct q6audio_in *audio = NULL;
@ -250,6 +364,7 @@ static int amrnb_in_open(struct inode *inode, struct file *file)
audio->opened = 1;
atomic_set(&audio->in_count, PCM_BUF_COUNT);
atomic_set(&audio->out_count, 0x00);
audio->enc_compat_ioctl = amrnb_in_compat_ioctl;
audio->enc_ioctl = amrnb_in_ioctl;
file->private_data = audio;
@ -269,6 +384,7 @@ static const struct file_operations audio_in_fops = {
.read = audio_in_read,
.write = audio_in_write,
.unlocked_ioctl = audio_in_ioctl,
.compat_ioctl = audio_in_compat_ioctl
};
struct miscdevice audio_amrnb_in_misc = {

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-2012, 2014 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -19,6 +19,7 @@
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/wait.h>
#include <linux/compat.h>
#include <asm/atomic.h>
#include <asm/ioctls.h>
#include "audio_utils.h"
@ -29,9 +30,8 @@
/* Maximum 10 frames in buffer with meta */
#define FRAME_SIZE (1 + ((61+sizeof(struct meta_out_dsp)) * 10))
/* ------------------- device --------------------- */
static long amrwb_in_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
static long amrwb_in_ioctl_shared(struct file *file,
unsigned int cmd, void *arg)
{
struct q6audio_in *audio = file->private_data;
int rc = 0;
@ -105,22 +105,19 @@ static long amrwb_in_ioctl(struct file *file,
}
break;
}
case AUDIO_GET_AMRWB_ENC_CONFIG: {
if (copy_to_user((void *)arg, audio->enc_cfg,
sizeof(struct msm_audio_amrwb_enc_config)))
rc = -EFAULT;
break;
}
case AUDIO_SET_AMRWB_ENC_CONFIG: {
struct msm_audio_amrwb_enc_config cfg;
struct msm_audio_amrwb_enc_config *cfg;
struct msm_audio_amrwb_enc_config *enc_cfg;
enc_cfg = audio->enc_cfg;
if (copy_from_user(&cfg, (void *) arg,
sizeof(struct msm_audio_amrwb_enc_config))) {
rc = -EFAULT;
cfg = (struct msm_audio_amrwb_enc_config *)arg;
if (cfg == NULL) {
pr_err("%s: NULL config pointer for %s\n",
__func__, "AUDIO_SET_AMRWB_ENC_CONFIG");
rc = -EINVAL;
break;
}
if (cfg.band_mode > 8) {
if (cfg->band_mode > 8) {
pr_err("%s:session id %d: invalid band mode\n",
__func__, audio->ac->session);
rc = -EINVAL;
@ -129,8 +126,8 @@ static long amrwb_in_ioctl(struct file *file,
/* ToDo: AMR WB encoder accepts values between 0-8
while openmax provides value between 9-17
as per spec */
enc_cfg->band_mode = cfg.band_mode;
enc_cfg->dtx_enable = (cfg.dtx_enable ? 1 : 0);
enc_cfg->band_mode = cfg->band_mode;
enc_cfg->dtx_enable = (cfg->dtx_enable ? 1 : 0);
/* Currently DSP does not support different frameformat */
enc_cfg->frame_format = 0;
pr_debug("%s:session id %d: band_mode = 0x%x dtx_enable=0x%x\n",
@ -139,11 +136,126 @@ static long amrwb_in_ioctl(struct file *file,
break;
}
default:
pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd);
rc = -EINVAL;
}
return rc;
}
static long amrwb_in_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
struct q6audio_in *audio = file->private_data;
int rc = 0;
switch (cmd) {
case AUDIO_START:
case AUDIO_STOP: {
rc = amrwb_in_ioctl_shared(file, cmd, NULL);
break;
}
case AUDIO_GET_AMRWB_ENC_CONFIG: {
if (copy_to_user((void *)arg, audio->enc_cfg,
sizeof(struct msm_audio_amrwb_enc_config)))
pr_err("%s: copy_to_user for AUDIO_GET_AMRWB_ENC_CONFIG failed\n",
__func__);
rc = -EFAULT;
break;
}
case AUDIO_SET_AMRWB_ENC_CONFIG: {
struct msm_audio_amrwb_enc_config cfg;
if (copy_from_user(&cfg, (void *) arg,
sizeof(cfg))) {
pr_err("%s: copy_from_user for AUDIO_SET_AMRWB_ENC_CONFIG failed\n",
__func__);
rc = -EFAULT;
break;
}
rc = amrwb_in_ioctl_shared(file, cmd, &cfg);
if (rc)
pr_err("%s:AUDIO_SET_AAC_ENC_CONFIG failed. rc=%d\n",
__func__, rc);
break;
}
default:
pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd);
rc = -EINVAL;
}
return rc;
}
#ifdef CONFIG_COMPAT
struct msm_audio_amrwb_enc_config_32 {
u32 band_mode;
u32 dtx_enable;
u32 frame_format;
};
enum {
AUDIO_GET_AMRWB_ENC_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC,
(AUDIO_MAX_COMMON_IOCTL_NUM+0),
struct msm_audio_amrwb_enc_config_32),
AUDIO_SET_AMRWB_ENC_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC,
(AUDIO_MAX_COMMON_IOCTL_NUM+1),
struct msm_audio_amrwb_enc_config_32)
};
static long amrwb_in_compat_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
struct q6audio_in *audio = file->private_data;
int rc = 0;
switch (cmd) {
case AUDIO_START:
case AUDIO_STOP: {
rc = amrwb_in_ioctl_shared(file, cmd, NULL);
break;
}
case AUDIO_GET_AMRWB_ENC_CONFIG_32: {
struct msm_audio_amrwb_enc_config *amrwb_config;
struct msm_audio_amrwb_enc_config_32 amrwb_config_32;
amrwb_config =
(struct msm_audio_amrwb_enc_config *)audio->enc_cfg;
amrwb_config_32.band_mode = amrwb_config->band_mode;
amrwb_config_32.dtx_enable = amrwb_config->dtx_enable;
amrwb_config_32.frame_format = amrwb_config->frame_format;
if (copy_to_user((void *)arg, &amrwb_config_32,
sizeof(struct msm_audio_amrwb_enc_config_32))) {
pr_err("%s: copy_to_user for AUDIO_GET_AMRWB_ENC_CONFIG_32 failed\n",
__func__);
rc = -EFAULT;
}
break;
}
case AUDIO_SET_AMRWB_ENC_CONFIG_32: {
struct msm_audio_amrwb_enc_config cfg_32;
if (copy_from_user(&cfg_32, (void *) arg,
sizeof(cfg_32))) {
pr_err("%s: copy_from_user for AUDIO_SET_AMRWB_ENC_CONFIG_32 failed\n",
__func__);
rc = -EFAULT;
break;
}
cmd = AUDIO_SET_AMRWB_ENC_CONFIG;
rc = amrwb_in_ioctl_shared(file, cmd, &cfg_32);
if (rc)
pr_err("%s:AUDIO_SET_AAC_ENC_CONFIG failed. rc=%d\n",
__func__, rc);
break;
}
default:
pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd);
rc = -EINVAL;
}
return rc;
}
#else
#define amrwb_in_compat_ioctl NULL
#endif
static int amrwb_in_open(struct inode *inode, struct file *file)
{
struct q6audio_in *audio = NULL;
@ -247,6 +359,7 @@ static int amrwb_in_open(struct inode *inode, struct file *file)
audio->opened = 1;
atomic_set(&audio->in_count, PCM_BUF_COUNT);
atomic_set(&audio->out_count, 0x00);
audio->enc_compat_ioctl = amrwb_in_compat_ioctl;
audio->enc_ioctl = amrwb_in_ioctl;
file->private_data = audio;
@ -266,6 +379,7 @@ static const struct file_operations audio_in_fops = {
.read = audio_in_read,
.write = audio_in_write,
.unlocked_ioctl = audio_in_ioctl,
.compat_ioctl = audio_in_compat_ioctl
};
struct miscdevice audio_amrwb_in_misc = {

View file

@ -2,7 +2,7 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
* Copyright (c) 2010-2014, The Linux Foundation. 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
@ -16,6 +16,7 @@
*/
#include <linux/msm_audio_aac.h>
#include <linux/compat.h>
#include "audio_utils_aio.h"
#define AUDIO_AAC_DUAL_MONO_INVALID -1
@ -28,7 +29,8 @@ static const struct file_operations audio_aac_debug_fops = {
};
#endif
static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
static long audio_ioctl_shared(struct file *file, unsigned int cmd,
void *arg)
{
struct q6audio_aio *audio = file->private_data;
int rc = 0;
@ -122,75 +124,220 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
audio->stopped = 0;
break;
}
case AUDIO_SET_AAC_CONFIG: {
struct msm_audio_aac_config *aac_config;
uint16_t sce_left = 1, sce_right = 2;
pr_debug("%s: AUDIO_SET_AAC_CONFIG\n", __func__);
aac_config = (struct msm_audio_aac_config *)arg;
if (aac_config == NULL) {
pr_err("%s: Invalid config pointer\n", __func__);
rc = -EINVAL;
break;
}
memcpy(audio->codec_cfg, aac_config,
sizeof(struct msm_audio_aac_config));
/* PL_PR is 0 only need to check PL_SR */
if (aac_config->dual_mono_mode >
AUDIO_AAC_DUAL_MONO_PL_SR) {
pr_err("%s:Invalid dual_mono mode =%d\n", __func__,
aac_config->dual_mono_mode);
} else {
/* convert the data from user into sce_left
* and sce_right based on the definitions
*/
pr_debug("%s: modify dual_mono mode =%d\n", __func__,
aac_config->dual_mono_mode);
switch (aac_config->dual_mono_mode) {
case AUDIO_AAC_DUAL_MONO_PL_PR:
sce_left = 1;
sce_right = 1;
break;
case AUDIO_AAC_DUAL_MONO_SL_SR:
sce_left = 2;
sce_right = 2;
break;
case AUDIO_AAC_DUAL_MONO_SL_PR:
sce_left = 2;
sce_right = 1;
break;
case AUDIO_AAC_DUAL_MONO_PL_SR:
default:
sce_left = 1;
sce_right = 2;
break;
}
rc = q6asm_cfg_dual_mono_aac(audio->ac,
sce_left, sce_right);
if (rc < 0)
pr_err("%s:asm cmd dualmono failed rc=%d\n",
__func__, rc);
}
break;
}
default:
pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd);
break;
}
return rc;
}
static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct q6audio_aio *audio = file->private_data;
int rc = 0;
switch (cmd) {
case AUDIO_START: {
rc = audio_ioctl_shared(file, cmd, (void *)arg);
break;
}
case AUDIO_GET_AAC_CONFIG: {
if (copy_to_user((void *)arg, audio->codec_cfg,
sizeof(struct msm_audio_aac_config))) {
pr_err("%s: copy_to_user for AUDIO_GET_AAC_CONFIG failed\n",
__func__);
rc = -EFAULT;
break;
}
break;
}
case AUDIO_SET_AAC_CONFIG: {
struct msm_audio_aac_config *aac_config;
struct msm_audio_aac_config aac_config;
pr_debug("%s: AUDIO_SET_AAC_CONFIG\n", __func__);
if (copy_from_user(audio->codec_cfg, (void *)arg,
sizeof(struct msm_audio_aac_config))) {
if (copy_from_user(&aac_config, (void *)arg,
sizeof(aac_config))) {
pr_err("%s: copy_from_user for AUDIO_SET_AAC_CONFIG failed\n",
__func__);
rc = -EFAULT;
break;
} else {
uint16_t sce_left = 1, sce_right = 2;
aac_config = audio->codec_cfg;
/* PL_PR is 0 only need to check PL_SR */
if (aac_config->dual_mono_mode >
AUDIO_AAC_DUAL_MONO_PL_SR) {
pr_err("%s:AUDIO_SET_AAC_CONFIG: Invalid"
"dual_mono mode =%d\n", __func__,
aac_config->dual_mono_mode);
} else {
/* convert the data from user into sce_left
* and sce_right based on the definitions
*/
pr_debug("%s: AUDIO_SET_AAC_CONFIG: modify"
"dual_mono mode =%d\n", __func__,
aac_config->dual_mono_mode);
switch (aac_config->dual_mono_mode) {
case AUDIO_AAC_DUAL_MONO_PL_PR:
sce_left = 1;
sce_right = 1;
break;
case AUDIO_AAC_DUAL_MONO_SL_SR:
sce_left = 2;
sce_right = 2;
break;
case AUDIO_AAC_DUAL_MONO_SL_PR:
sce_left = 2;
sce_right = 1;
break;
case AUDIO_AAC_DUAL_MONO_PL_SR:
default:
sce_left = 1;
sce_right = 2;
break;
}
rc = q6asm_cfg_dual_mono_aac(audio->ac,
sce_left, sce_right);
if (rc < 0)
pr_err("%s: asm cmd dualmono failed"
" rc=%d\n", __func__, rc);
}
}
rc = audio_ioctl_shared(file, cmd, &aac_config);
if (rc)
pr_err("%s:AUDIO_SET_AAC_CONFIG failed. Rc= %d\n",
__func__, rc);
break;
}
default:
default: {
pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio);
rc = audio->codec_ioctl(file, cmd, arg);
if (rc)
pr_err("%s[%p]:Failed in utils_ioctl: %d\n",
__func__, audio, rc);
}
}
return rc;
}
#ifdef CONFIG_COMPAT
struct msm_audio_aac_config32 {
s16 format;
u16 audio_object;
u16 ep_config; /* 0 ~ 3 useful only obj = ERLC */
u16 aac_section_data_resilience_flag;
u16 aac_scalefactor_data_resilience_flag;
u16 aac_spectral_data_resilience_flag;
u16 sbr_on_flag;
u16 sbr_ps_on_flag;
u16 dual_mono_mode;
u16 channel_configuration;
u16 sample_rate;
};
enum {
AUDIO_SET_AAC_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC,
(AUDIO_MAX_COMMON_IOCTL_NUM+0), struct msm_audio_aac_config32),
AUDIO_GET_AAC_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC,
(AUDIO_MAX_COMMON_IOCTL_NUM+1), struct msm_audio_aac_config32)
};
static long audio_compat_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
struct q6audio_aio *audio = file->private_data;
int rc = 0;
switch (cmd) {
case AUDIO_START: {
rc = audio_ioctl_shared(file, cmd, (void *)arg);
break;
}
case AUDIO_GET_AAC_CONFIG_32: {
struct msm_audio_aac_config *aac_config;
struct msm_audio_aac_config32 aac_config_32;
aac_config = (struct msm_audio_aac_config *)audio->codec_cfg;
aac_config_32.format = aac_config->format;
aac_config_32.audio_object = aac_config->audio_object;
aac_config_32.ep_config = aac_config->ep_config;
aac_config_32.aac_section_data_resilience_flag =
aac_config->aac_section_data_resilience_flag;
aac_config_32.aac_scalefactor_data_resilience_flag =
aac_config->aac_scalefactor_data_resilience_flag;
aac_config_32.aac_spectral_data_resilience_flag =
aac_config->aac_spectral_data_resilience_flag;
aac_config_32.sbr_on_flag = aac_config->sbr_on_flag;
aac_config_32.sbr_ps_on_flag = aac_config->sbr_ps_on_flag;
aac_config_32.dual_mono_mode = aac_config->dual_mono_mode;
aac_config_32.channel_configuration =
aac_config->channel_configuration;
aac_config_32.sample_rate = aac_config->sample_rate;
if (copy_to_user((void *)arg, &aac_config_32,
sizeof(aac_config_32))) {
pr_err("%s: copy_to_user for AUDIO_GET_AAC_CONFIG_32 failed\n",
__func__);
rc = -EFAULT;
break;
}
break;
}
case AUDIO_SET_AAC_CONFIG_32: {
struct msm_audio_aac_config aac_config;
struct msm_audio_aac_config32 aac_config_32;
pr_debug("%s: AUDIO_SET_AAC_CONFIG\n", __func__);
if (copy_from_user(&aac_config_32, (void *)arg,
sizeof(aac_config_32))) {
pr_err("%s: copy_from_user for AUDIO_SET_AAC_CONFIG_32 failed\n",
__func__);
rc = -EFAULT;
break;
}
aac_config.format = aac_config_32.format;
aac_config.audio_object = aac_config_32.audio_object;
aac_config.ep_config = aac_config_32.ep_config;
aac_config.aac_section_data_resilience_flag =
aac_config_32.aac_section_data_resilience_flag;
aac_config.aac_scalefactor_data_resilience_flag =
aac_config_32.aac_scalefactor_data_resilience_flag;
aac_config.aac_spectral_data_resilience_flag =
aac_config_32.aac_spectral_data_resilience_flag;
aac_config.sbr_on_flag = aac_config_32.sbr_on_flag;
aac_config.sbr_ps_on_flag = aac_config_32.sbr_ps_on_flag;
aac_config.dual_mono_mode = aac_config_32.dual_mono_mode;
aac_config.channel_configuration =
aac_config_32.channel_configuration;
aac_config.sample_rate = aac_config_32.sample_rate;
cmd = AUDIO_SET_AAC_CONFIG;
rc = audio_ioctl_shared(file, cmd, &aac_config);
if (rc)
pr_err("%s:AUDIO_SET_AAC_CONFIG failed. Rc= %d\n",
__func__, rc);
break;
}
default: {
pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio);
rc = audio->codec_compat_ioctl(file, cmd, arg);
if (rc)
pr_err("%s[%p]:Failed in utils_ioctl: %d\n",
__func__, audio, rc);
}
}
return rc;
}
#else
#define audio_compat_ioctl NULL
#endif
static int audio_open(struct inode *inode, struct file *file)
{
struct q6audio_aio *audio = NULL;
@ -293,6 +440,7 @@ static const struct file_operations audio_aac_fops = {
.release = audio_aio_release,
.unlocked_ioctl = audio_ioctl,
.fsync = audio_aio_fsync,
.compat_ioctl = audio_compat_ioctl
};
struct miscdevice audio_aac_misc = {

View file

@ -2,7 +2,7 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
* Copyright (c) 2010-2014, The Linux Foundation. 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
@ -15,6 +15,7 @@
*
*/
#include <linux/msm_audio_amrwbplus.h>
#include <linux/compat.h>
#include "audio_utils_aio.h"
#ifdef CONFIG_DEBUG_FS
@ -41,7 +42,8 @@ static void config_debug_fs(struct q6audio_aio *audio)
}
#endif
static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
static long audio_ioctl_shared(struct file *file, unsigned int cmd,
void *arg)
{
struct asm_amrwbplus_cfg q6_amrwbplus_cfg;
struct msm_audio_amrwbplus_config_v2 *amrwbplus_drv_config;
@ -103,16 +105,37 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
audio->stopped = 0;
break;
}
default:
pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd);
rc = -EINVAL;
break;
}
return rc;
}
static long audio_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
struct q6audio_aio *audio = file->private_data;
int rc = 0;
switch (cmd) {
case AUDIO_START: {
rc = audio_ioctl_shared(file, cmd, (void *)arg);
break;
}
case AUDIO_GET_AMRWBPLUS_CONFIG_V2: {
if ((audio) && (arg) && (audio->codec_cfg)) {
if (copy_to_user((void *)arg, audio->codec_cfg,
sizeof(struct msm_audio_amrwbplus_config_v2))) {
rc = -EFAULT;
pr_err("wb+ config get copy_to_user failed");
pr_err("%s: copy_to_user for AUDIO_GET_AMRWBPLUS_CONFIG_V2 failed\n",
__func__);
break;
}
} else {
pr_err("wb+ config v2 invalid parameters..");
pr_err("%s: wb+ config v2 invalid parameters\n"
, __func__);
rc = -EFAULT;
break;
}
@ -121,24 +144,143 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case AUDIO_SET_AMRWBPLUS_CONFIG_V2: {
if ((audio) && (arg) && (audio->codec_cfg)) {
if (copy_from_user(audio->codec_cfg, (void *)arg,
sizeof(struct msm_audio_amrwbplus_config_v2))) {
sizeof(struct msm_audio_amrwbplus_config_v2))) {
rc = -EFAULT;
pr_err("wb+ config set copy_to_user_failed");
pr_err("%s: copy_from_user for AUDIO_SET_AMRWBPLUS_CONFIG_V2 failed\n",
__func__);
break;
}
} else {
pr_err("wb+ config invalid parameters..");
pr_err("%s: wb+ config invalid parameters\n",
__func__);
rc = -EFAULT;
break;
}
break;
}
default:
default: {
pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio);
rc = audio->codec_ioctl(file, cmd, arg);
break;
}
}
return rc;
}
#ifdef CONFIG_COMPAT
struct msm_audio_amrwbplus_config_v2_32 {
u32 size_bytes;
u32 version;
u32 num_channels;
u32 amr_band_mode;
u32 amr_dtx_mode;
u32 amr_frame_fmt;
u32 amr_lsf_idx;
};
enum {
AUDIO_GET_AMRWBPLUS_CONFIG_V2_32 = _IOR(AUDIO_IOCTL_MAGIC,
(AUDIO_MAX_COMMON_IOCTL_NUM+2),
struct msm_audio_amrwbplus_config_v2_32),
AUDIO_SET_AMRWBPLUS_CONFIG_V2_32 = _IOW(AUDIO_IOCTL_MAGIC,
(AUDIO_MAX_COMMON_IOCTL_NUM+3),
struct msm_audio_amrwbplus_config_v2_32)
};
static long audio_compat_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
struct q6audio_aio *audio = file->private_data;
int rc = 0;
switch (cmd) {
case AUDIO_START: {
rc = audio_ioctl_shared(file, cmd, (void *)arg);
break;
}
case AUDIO_GET_AMRWBPLUS_CONFIG_V2_32: {
if (audio && arg && (audio->codec_cfg)) {
struct msm_audio_amrwbplus_config_v2 *amrwbplus_config;
struct msm_audio_amrwbplus_config_v2_32
amrwbplus_config_32;
amrwbplus_config =
(struct msm_audio_amrwbplus_config_v2 *)
audio->codec_cfg;
amrwbplus_config_32.size_bytes =
amrwbplus_config->size_bytes;
amrwbplus_config_32.version =
amrwbplus_config->version;
amrwbplus_config_32.num_channels =
amrwbplus_config->num_channels;
amrwbplus_config_32.amr_band_mode =
amrwbplus_config->amr_band_mode;
amrwbplus_config_32.amr_dtx_mode =
amrwbplus_config->amr_dtx_mode;
amrwbplus_config_32.amr_frame_fmt =
amrwbplus_config->amr_frame_fmt;
amrwbplus_config_32.amr_lsf_idx =
amrwbplus_config->amr_lsf_idx;
if (copy_to_user((void *)arg, &amrwbplus_config_32,
sizeof(amrwbplus_config_32))) {
rc = -EFAULT;
pr_err("%s: copy_to_user for AUDIO_GET_AMRWBPLUS_CONFIG_V2_32 failed\n"
, __func__);
}
} else {
pr_err("%s: wb+ Get config v2 invalid parameters\n"
, __func__);
rc = -EFAULT;
}
break;
}
case AUDIO_SET_AMRWBPLUS_CONFIG_V2_32: {
if ((audio) && (arg) && (audio->codec_cfg)) {
struct msm_audio_amrwbplus_config_v2 *amrwbplus_config;
struct msm_audio_amrwbplus_config_v2_32
amrwbplus_config_32;
if (copy_from_user(&amrwbplus_config_32, (void *)arg,
sizeof(struct msm_audio_amrwbplus_config_v2_32))) {
rc = -EFAULT;
pr_err("%s: copy_from_user for AUDIO_SET_AMRWBPLUS_CONFIG_V2_32 failed\n"
, __func__);
break;
}
amrwbplus_config =
(struct msm_audio_amrwbplus_config_v2 *)
audio->codec_cfg;
amrwbplus_config->size_bytes =
amrwbplus_config_32.size_bytes;
amrwbplus_config->version =
amrwbplus_config_32.version;
amrwbplus_config->num_channels =
amrwbplus_config_32.num_channels;
amrwbplus_config->amr_band_mode =
amrwbplus_config_32.amr_band_mode;
amrwbplus_config->amr_dtx_mode =
amrwbplus_config_32.amr_dtx_mode;
amrwbplus_config->amr_frame_fmt =
amrwbplus_config_32.amr_frame_fmt;
amrwbplus_config->amr_lsf_idx =
amrwbplus_config_32.amr_lsf_idx;
} else {
pr_err("%s: wb+ config invalid parameters\n",
__func__);
rc = -EFAULT;
}
break;
}
default: {
pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio);
rc = audio->codec_compat_ioctl(file, cmd, arg);
break;
}
}
return rc;
}
#else
#define audio_compat_ioctl NULL
#endif
static int audio_open(struct inode *inode, struct file *file)
{
@ -222,6 +364,7 @@ static const struct file_operations audio_amrwbplus_fops = {
.release = audio_aio_release,
.unlocked_ioctl = audio_ioctl,
.fsync = audio_aio_fsync,
.compat_ioctl = audio_compat_ioctl
};
struct miscdevice audio_amrwbplus_misc = {

View file

@ -16,6 +16,7 @@
*/
#include <linux/msm_audio_aac.h>
#include <linux/compat.h>
#include <soc/qcom/socinfo.h>
#include "audio_utils_aio.h"
@ -32,7 +33,8 @@ static const struct file_operations audio_aac_debug_fops = {
};
#endif
static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
static long audio_ioctl_shared(struct file *file, unsigned int cmd,
void *arg)
{
struct q6audio_aio *audio = file->private_data;
int rc = 0;
@ -131,86 +133,263 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
audio->stopped = 0;
break;
}
case AUDIO_SET_AAC_CONFIG: {
struct msm_audio_aac_config *aac_config;
uint16_t sce_left = 1, sce_right = 2;
if (arg == NULL) {
pr_err("%s: NULL config pointer\n", __func__);
rc = -EINVAL;
break;
}
memcpy(audio->codec_cfg, arg,
sizeof(struct msm_audio_aac_config));
aac_config = audio->codec_cfg;
if (aac_config->dual_mono_mode >
AUDIO_AAC_DUAL_MONO_PL_SR) {
pr_err("%s:AUDIO_SET_AAC_CONFIG: Invalid dual_mono mode =%d\n",
__func__, aac_config->dual_mono_mode);
} else {
/* convert the data from user into sce_left
* and sce_right based on the definitions
*/
pr_debug("%s: AUDIO_SET_AAC_CONFIG: modify dual_mono mode =%d\n",
__func__, aac_config->dual_mono_mode);
switch (aac_config->dual_mono_mode) {
case AUDIO_AAC_DUAL_MONO_PL_PR:
sce_left = 1;
sce_right = 1;
break;
case AUDIO_AAC_DUAL_MONO_SL_SR:
sce_left = 2;
sce_right = 2;
break;
case AUDIO_AAC_DUAL_MONO_SL_PR:
sce_left = 2;
sce_right = 1;
break;
case AUDIO_AAC_DUAL_MONO_PL_SR:
default:
sce_left = 1;
sce_right = 2;
break;
}
rc = q6asm_cfg_dual_mono_aac(audio->ac,
sce_left, sce_right);
if (rc < 0)
pr_err("%s: asm cmd dualmono failed rc=%d\n",
__func__, rc);
} break;
break;
}
case AUDIO_SET_AAC_MIX_CONFIG: {
u32 *mix_coeff = (u32 *)arg;
if (!arg) {
pr_err("%s: Invalid param for %s\n",
__func__, "AUDIO_SET_AAC_MIX_CONFIG");
rc = -EINVAL;
break;
}
pr_debug("%s, AUDIO_SET_AAC_MIX_CONFIG", __func__);
pr_debug("%s, value of coeff = %d",
__func__, *mix_coeff);
q6asm_cfg_aac_sel_mix_coef(audio->ac, *mix_coeff);
if (rc < 0)
pr_err("%s asm aac_sel_mix_coef failed rc=%d\n",
__func__, rc);
break;
}
default:
pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd);
rc = -EINVAL;
break;
}
return rc;
}
static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct q6audio_aio *audio = file->private_data;
int rc = 0;
switch (cmd) {
case AUDIO_START: {
rc = audio_ioctl_shared(file, cmd, (void *)arg);
break;
}
case AUDIO_GET_AAC_CONFIG: {
if (copy_to_user((void *)arg, audio->codec_cfg,
sizeof(struct msm_audio_aac_config))) {
pr_err("%s: copy_to_user for AUDIO_GET_AAC_CONFIG failed\n"
, __func__);
rc = -EFAULT;
break;
}
break;
}
case AUDIO_SET_AAC_CONFIG: {
struct msm_audio_aac_config *aac_config;
if (copy_from_user(audio->codec_cfg, (void *)arg,
sizeof(struct msm_audio_aac_config))) {
struct msm_audio_aac_config aac_config;
if (copy_from_user(&aac_config, (void *)arg,
sizeof(aac_config))) {
pr_err("%s: copy_from_user for AUDIO_SET_AAC_CONFIG failed\n"
, __func__);
rc = -EFAULT;
} else {
uint16_t sce_left = 1, sce_right = 2;
aac_config = audio->codec_cfg;
if (aac_config->dual_mono_mode >
AUDIO_AAC_DUAL_MONO_PL_SR) {
pr_err("%s:AUDIO_SET_AAC_CONFIG: Invalid dual_mono mode =%d\n",
__func__, aac_config->dual_mono_mode);
} else {
/* convert the data from user into sce_left
* and sce_right based on the definitions
*/
pr_debug("%s: AUDIO_SET_AAC_CONFIG: modify dual_mono mode =%d\n",
__func__, aac_config->dual_mono_mode);
switch (aac_config->dual_mono_mode) {
case AUDIO_AAC_DUAL_MONO_PL_PR:
sce_left = 1;
sce_right = 1;
break;
case AUDIO_AAC_DUAL_MONO_SL_SR:
sce_left = 2;
sce_right = 2;
break;
case AUDIO_AAC_DUAL_MONO_SL_PR:
sce_left = 2;
sce_right = 1;
break;
case AUDIO_AAC_DUAL_MONO_PL_SR:
default:
sce_left = 1;
sce_right = 2;
break;
}
rc = q6asm_cfg_dual_mono_aac(audio->ac,
sce_left, sce_right);
if (rc < 0)
pr_err("%s: asm cmd dualmono failed rc=%d\n",
__func__, rc);
} break;
}
rc = audio_ioctl_shared(file, cmd, &aac_config);
if (rc)
pr_err("%s:AUDIO_SET_AAC_CONFIG failed. Rc= %d\n",
__func__, rc);
break;
}
case AUDIO_SET_AAC_MIX_CONFIG: {
u32 mix_config;
pr_debug("%s, AUDIO_SET_AAC_MIX_CONFIG", __func__);
if (copy_from_user(audio->codec_cfg, (void *)arg,
sizeof(unsigned long))) {
if (copy_from_user(&mix_config, (void *)arg,
sizeof(u32))) {
pr_err("%s: copy_from_user for AUDIO_SET_AAC_MIX_CONFIG failed\n",
__func__);
rc = -EFAULT;
break;
} else {
unsigned long *mix_coeff =
(unsigned long *)audio->codec_cfg;
pr_debug("%s, value of coeff = %lu",
__func__, *mix_coeff);
q6asm_cfg_aac_sel_mix_coef(audio->ac, *mix_coeff);
if (rc < 0)
pr_err("%s asm aac_sel_mix_coef failed rc=%d\n",
__func__, rc);
break;
}
rc = audio_ioctl_shared(file, cmd, &mix_config);
if (rc)
pr_err("%s:AUDIO_SET_AAC_CONFIG failed. Rc= %d\n",
__func__, rc);
break;
}
default:
default: {
pr_debug("Calling utils ioctl\n");
rc = audio->codec_ioctl(file, cmd, arg);
}
}
return rc;
}
#ifdef CONFIG_COMPAT
struct msm_audio_aac_config32 {
s16 format;
u16 audio_object;
u16 ep_config; /* 0 ~ 3 useful only obj = ERLC */
u16 aac_section_data_resilience_flag;
u16 aac_scalefactor_data_resilience_flag;
u16 aac_spectral_data_resilience_flag;
u16 sbr_on_flag;
u16 sbr_ps_on_flag;
u16 dual_mono_mode;
u16 channel_configuration;
u16 sample_rate;
};
enum {
AUDIO_SET_AAC_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC,
(AUDIO_MAX_COMMON_IOCTL_NUM+0), struct msm_audio_aac_config32),
AUDIO_GET_AAC_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC,
(AUDIO_MAX_COMMON_IOCTL_NUM+1), struct msm_audio_aac_config32),
};
static long audio_compat_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
struct q6audio_aio *audio = file->private_data;
int rc = 0;
switch (cmd) {
case AUDIO_START: {
rc = audio_ioctl_shared(file, cmd, (void *)arg);
break;
}
case AUDIO_GET_AAC_CONFIG_32: {
struct msm_audio_aac_config *aac_config;
struct msm_audio_aac_config32 aac_config_32;
aac_config = (struct msm_audio_aac_config *)audio->codec_cfg;
aac_config_32.format = aac_config->format;
aac_config_32.audio_object = aac_config->audio_object;
aac_config_32.ep_config = aac_config->ep_config;
aac_config_32.aac_section_data_resilience_flag =
aac_config->aac_section_data_resilience_flag;
aac_config_32.aac_scalefactor_data_resilience_flag =
aac_config->aac_scalefactor_data_resilience_flag;
aac_config_32.aac_spectral_data_resilience_flag =
aac_config->aac_spectral_data_resilience_flag;
aac_config_32.sbr_on_flag = aac_config->sbr_on_flag;
aac_config_32.sbr_ps_on_flag = aac_config->sbr_ps_on_flag;
aac_config_32.dual_mono_mode = aac_config->dual_mono_mode;
aac_config_32.channel_configuration =
aac_config->channel_configuration;
aac_config_32.sample_rate = aac_config->sample_rate;
if (copy_to_user((void *)arg, &aac_config_32,
sizeof(aac_config_32))) {
pr_err("%s: copy_to_user for AUDIO_GET_AAC_CONFIG_32 failed\n",
__func__);
rc = -EFAULT;
break;
}
break;
}
case AUDIO_SET_AAC_CONFIG_32: {
struct msm_audio_aac_config aac_config;
struct msm_audio_aac_config32 aac_config_32;
pr_debug("%s: AUDIO_SET_AAC_CONFIG\n", __func__);
if (copy_from_user(&aac_config_32, (void *)arg,
sizeof(aac_config_32))) {
pr_err(
"%s: copy_from_user for AUDIO_SET_AAC_CONFIG_32 failed",
__func__);
rc = -EFAULT;
break;
}
aac_config.format = aac_config_32.format;
aac_config.audio_object = aac_config_32.audio_object;
aac_config.ep_config = aac_config_32.ep_config;
aac_config.aac_section_data_resilience_flag =
aac_config_32.aac_section_data_resilience_flag;
aac_config.aac_scalefactor_data_resilience_flag =
aac_config_32.aac_scalefactor_data_resilience_flag;
aac_config.aac_spectral_data_resilience_flag =
aac_config_32.aac_spectral_data_resilience_flag;
aac_config.sbr_on_flag = aac_config_32.sbr_on_flag;
aac_config.sbr_ps_on_flag = aac_config_32.sbr_ps_on_flag;
aac_config.dual_mono_mode = aac_config_32.dual_mono_mode;
aac_config.channel_configuration =
aac_config_32.channel_configuration;
aac_config.sample_rate = aac_config_32.sample_rate;
cmd = AUDIO_SET_AAC_CONFIG;
rc = audio_ioctl_shared(file, cmd, &aac_config);
if (rc)
pr_err("%s:AUDIO_SET_AAC_CONFIG failed. rc= %d\n",
__func__, rc);
break;
}
case AUDIO_SET_AAC_MIX_CONFIG: {
u32 mix_config;
pr_debug("%s, AUDIO_SET_AAC_MIX_CONFIG\n", __func__);
if (copy_from_user(&mix_config, (void *)arg,
sizeof(u32))) {
pr_err("%s: copy_from_user for AUDIO_SET_AAC_MIX_CONFIG failed\n"
, __func__);
rc = -EFAULT;
break;
}
rc = audio_ioctl_shared(file, cmd, &mix_config);
if (rc)
pr_err("%s:AUDIO_SET_AAC_CONFIG failed. Rc= %d\n",
__func__, rc);
break;
}
default: {
pr_debug("Calling utils ioctl\n");
rc = audio->codec_compat_ioctl(file, cmd, arg);
}
}
return rc;
}
#else
#define audio_compat_ioctl NULL
#endif
static int audio_open(struct inode *inode, struct file *file)
{
@ -312,6 +491,7 @@ static const struct file_operations audio_aac_fops = {
.release = audio_aio_release,
.unlocked_ioctl = audio_ioctl,
.fsync = audio_aio_fsync,
.compat_ioctl = audio_compat_ioctl
};
struct miscdevice audio_multiaac_misc = {

View file

@ -20,6 +20,7 @@
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/atomic.h>
#include <linux/compat.h>
#include <asm/ioctls.h>
#include "audio_utils.h"
@ -188,7 +189,95 @@ int audio_in_buf_alloc(struct q6audio_in *audio)
return rc;
}
int audio_in_set_config(struct file *file,
struct msm_audio_config *cfg)
{
int rc = 0;
struct q6audio_in *audio = file->private_data;
if (audio->feedback != NON_TUNNEL_MODE) {
pr_err("%s:session id %d: Not sufficient permission to change the record mode\n",
__func__, audio->ac->session);
rc = -EACCES;
goto ret;
}
if ((cfg->buffer_count > PCM_BUF_COUNT) ||
(cfg->buffer_count == 1))
cfg->buffer_count = PCM_BUF_COUNT;
audio->pcm_cfg.buffer_count = cfg->buffer_count;
audio->pcm_cfg.buffer_size = cfg->buffer_size;
audio->pcm_cfg.channel_count = cfg->channel_count;
audio->pcm_cfg.sample_rate = cfg->sample_rate;
if (audio->opened && audio->feedback == NON_TUNNEL_MODE) {
rc = q6asm_audio_client_buf_alloc(IN, audio->ac,
ALIGN_BUF_SIZE(audio->pcm_cfg.buffer_size),
audio->pcm_cfg.buffer_count);
if (rc < 0) {
pr_err("%s:session id %d: Buffer Alloc failed\n",
__func__, audio->ac->session);
rc = -ENOMEM;
goto ret;
}
}
audio->buf_alloc |= BUF_ALLOC_IN;
rc = 0;
pr_debug("%s:session id %d: AUDIO_SET_CONFIG %d %d\n", __func__,
audio->ac->session, audio->pcm_cfg.buffer_count,
audio->pcm_cfg.buffer_size);
ret:
return rc;
}
/* ------------------- device --------------------- */
static long audio_in_ioctl_shared(struct file *file,
unsigned int cmd, unsigned long arg)
{
struct q6audio_in *audio = file->private_data;
int rc = 0;
switch (cmd) {
case AUDIO_FLUSH: {
/* Make sure we're stopped and we wake any threads
* that might be blocked holding the read_lock.
* While audio->stopped read threads will always
* exit immediately.
*/
rc = audio_in_flush(audio);
if (rc < 0)
pr_err("%s:session id %d: Flush Fail rc=%d\n",
__func__, audio->ac->session, rc);
else { /* Register back the flushed read buffer with DSP */
int cnt = 0;
while (cnt++ < audio->str_cfg.buffer_count)
q6asm_read(audio->ac); /* Push buffer to DSP */
pr_debug("register the read buffer\n");
}
break;
}
case AUDIO_PAUSE: {
pr_debug("%s:session id %d: AUDIO_PAUSE\n", __func__,
audio->ac->session);
if (audio->enabled)
audio_in_pause(audio);
break;
}
case AUDIO_GET_SESSION_ID: {
if (copy_to_user((void *) arg, &audio->ac->session,
sizeof(u16))) {
pr_err("%s: copy_to_user for AUDIO_GET_SESSION_ID failed\n",
__func__);
rc = -EFAULT;
}
break;
}
default:
pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd);
rc = -EINVAL;
}
return rc;
}
long audio_in_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
@ -207,31 +296,11 @@ long audio_in_ioctl(struct file *file,
mutex_lock(&audio->lock);
switch (cmd) {
case AUDIO_FLUSH: {
/* Make sure we're stopped and we wake any threads
* that might be blocked holding the read_lock.
* While audio->stopped read threads will always
* exit immediately.
*/
rc = audio_in_flush(audio);
if (rc < 0)
pr_err("%s:session id %d: Flush Fail rc=%d\n",
__func__, audio->ac->session, rc);
else { /* Register back the flushed read buffer with DSP */
int cnt = 0;
while (cnt++ < audio->str_cfg.buffer_count)
q6asm_read(audio->ac); /* Push buffer to DSP */
pr_debug("register the read buffer\n");
}
case AUDIO_FLUSH:
case AUDIO_PAUSE:
case AUDIO_GET_SESSION_ID:
rc = audio_in_ioctl_shared(file, cmd, arg);
break;
}
case AUDIO_PAUSE: {
pr_debug("%s:session id %d: AUDIO_PAUSE\n", __func__,
audio->ac->session);
if (audio->enabled)
audio_in_pause(audio);
break;
}
case AUDIO_GET_STREAM_CONFIG: {
struct msm_audio_stream_config cfg;
memset(&cfg, 0, sizeof(cfg));
@ -247,6 +316,8 @@ long audio_in_ioctl(struct file *file,
case AUDIO_SET_STREAM_CONFIG: {
struct msm_audio_stream_config cfg;
if (copy_from_user(&cfg, (void *)arg, sizeof(cfg))) {
pr_err("%s: copy_from_user for AUDIO_SET_STREAM_CONFIG failed\n"
, __func__);
rc = -EFAULT;
break;
}
@ -264,11 +335,11 @@ long audio_in_ioctl(struct file *file,
rc = q6asm_audio_client_buf_alloc(OUT, audio->ac,
ALIGN_BUF_SIZE(audio->str_cfg.buffer_size),
audio->str_cfg.buffer_count);
if (rc < 0) {
pr_err("%s: session id %d: Buffer Alloc failed rc=%d\n",
__func__, audio->ac->session, rc);
rc = -ENOMEM;
break;
if (rc < 0) {
pr_err("%s: session id %d: Buffer Alloc failed rc=%d\n",
__func__, audio->ac->session, rc);
rc = -ENOMEM;
break;
}
}
audio->buf_alloc |= BUF_ALLOC_OUT;
@ -279,13 +350,6 @@ long audio_in_ioctl(struct file *file,
audio->str_cfg.buffer_count);
break;
}
case AUDIO_GET_SESSION_ID: {
if (copy_to_user((void *) arg, &audio->ac->session,
sizeof(unsigned short))) {
rc = -EFAULT;
}
break;
}
case AUDIO_SET_BUF_CFG: {
struct msm_audio_buf_cfg cfg;
if (copy_from_user(&cfg, (void *)arg, sizeof(cfg))) {
@ -333,40 +397,12 @@ long audio_in_ioctl(struct file *file,
case AUDIO_SET_CONFIG: {
struct msm_audio_config cfg;
if (copy_from_user(&cfg, (void *)arg, sizeof(cfg))) {
pr_err("%s: copy_from_user for AUDIO_SET_CONFIG failed\n",
__func__);
rc = -EFAULT;
break;
}
if (audio->feedback != NON_TUNNEL_MODE) {
pr_err("%s:session id %d: Not sufficient permission to change the record mode\n",
__func__,
audio->ac->session);
rc = -EACCES;
break;
}
if ((cfg.buffer_count > PCM_BUF_COUNT) ||
(cfg.buffer_count == 1))
cfg.buffer_count = PCM_BUF_COUNT;
audio->pcm_cfg.buffer_count = cfg.buffer_count;
audio->pcm_cfg.buffer_size = cfg.buffer_size;
audio->pcm_cfg.channel_count = cfg.channel_count;
audio->pcm_cfg.sample_rate = cfg.sample_rate;
if (audio->opened && audio->feedback == NON_TUNNEL_MODE) {
rc = q6asm_audio_client_buf_alloc(IN, audio->ac,
ALIGN_BUF_SIZE(audio->pcm_cfg.buffer_size),
audio->pcm_cfg.buffer_count);
if (rc < 0) {
pr_err("%s:session id %d: Buffer Alloc failed\n",
__func__, audio->ac->session);
rc = -ENOMEM;
break;
}
}
audio->buf_alloc |= BUF_ALLOC_IN;
rc = 0;
pr_debug("%s:session id %d: AUDIO_SET_CONFIG %d %d\n", __func__,
audio->ac->session, audio->pcm_cfg.buffer_count,
audio->pcm_cfg.buffer_size);
rc = audio_in_set_config(file, &cfg);
break;
}
default:
@ -377,6 +413,223 @@ long audio_in_ioctl(struct file *file,
return rc;
}
#ifdef CONFIG_COMPAT
struct msm_audio_stats32 {
u32 byte_count;
u32 sample_count;
u32 unused[2];
};
struct msm_audio_stream_config32 {
u32 buffer_size;
u32 buffer_count;
};
struct msm_audio_config32 {
u32 buffer_size;
u32 buffer_count;
u32 channel_count;
u32 sample_rate;
u32 type;
u32 meta_field;
u32 bits;
u32 unused[3];
};
struct msm_audio_buf_cfg32 {
u32 meta_info_enable;
u32 frames_per_buf;
};
enum {
AUDIO_GET_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC, 3,
struct msm_audio_config32),
AUDIO_SET_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC, 4,
struct msm_audio_config32),
AUDIO_GET_STATS_32 = _IOR(AUDIO_IOCTL_MAGIC, 5,
struct msm_audio_stats32),
AUDIO_SET_STREAM_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC, 80,
struct msm_audio_stream_config32),
AUDIO_GET_STREAM_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC, 81,
struct msm_audio_stream_config32),
AUDIO_SET_BUF_CFG_32 = _IOW(AUDIO_IOCTL_MAGIC, 94,
struct msm_audio_buf_cfg32),
AUDIO_GET_BUF_CFG_32 = _IOW(AUDIO_IOCTL_MAGIC, 93,
struct msm_audio_buf_cfg32),
};
long audio_in_compat_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
struct q6audio_in *audio = file->private_data;
int rc = 0;
if (cmd == AUDIO_GET_STATS_32) {
struct msm_audio_stats32 stats_32;
memset(&stats_32, 0, sizeof(stats_32));
stats_32.byte_count = atomic_read(&audio->in_bytes);
stats_32.sample_count = atomic_read(&audio->in_samples);
if (copy_to_user((void *) arg, &stats_32, sizeof(stats_32))) {
pr_err("%s: copy_to_user failed for AUDIO_GET_STATS_32\n",
__func__);
return -EFAULT;
}
return rc;
}
mutex_lock(&audio->lock);
switch (cmd) {
case AUDIO_FLUSH:
case AUDIO_PAUSE:
case AUDIO_GET_SESSION_ID:
rc = audio_in_ioctl_shared(file, cmd, arg);
break;
case AUDIO_GET_STREAM_CONFIG_32: {
struct msm_audio_stream_config32 cfg_32;
memset(&cfg_32, 0, sizeof(cfg_32));
cfg_32.buffer_size = audio->str_cfg.buffer_size;
cfg_32.buffer_count = audio->str_cfg.buffer_count;
if (copy_to_user((void *)arg, &cfg_32, sizeof(cfg_32))) {
pr_err("%s: Copy to user failed\n", __func__);
rc = -EFAULT;
}
pr_debug("%s:session id %d: AUDIO_GET_STREAM_CONFIG %d %d\n",
__func__, audio->ac->session,
cfg_32.buffer_size,
cfg_32.buffer_count);
break;
}
case AUDIO_SET_STREAM_CONFIG_32: {
struct msm_audio_stream_config32 cfg_32;
struct msm_audio_stream_config cfg;
if (copy_from_user(&cfg_32, (void *)arg, sizeof(cfg_32))) {
pr_err("%s: copy_from_user for AUDIO_SET_STREAM_CONFIG_32 failed\n",
__func__);
rc = -EFAULT;
break;
}
cfg.buffer_size = cfg_32.buffer_size;
cfg.buffer_count = cfg_32.buffer_count;
/* Minimum single frame size,
* but with in maximum frames number */
if ((cfg.buffer_size < (audio->min_frame_size +
sizeof(struct meta_out_dsp))) ||
(cfg.buffer_count < FRAME_NUM)) {
rc = -EINVAL;
break;
}
audio->str_cfg.buffer_size = cfg.buffer_size;
audio->str_cfg.buffer_count = cfg.buffer_count;
if (audio->opened) {
rc = q6asm_audio_client_buf_alloc(OUT, audio->ac,
ALIGN_BUF_SIZE(audio->str_cfg.buffer_size),
audio->str_cfg.buffer_count);
if (rc < 0) {
pr_err("%s: session id %d:\n",
__func__, audio->ac->session);
pr_err("Buffer Alloc failed rc=%d\n", rc);
rc = -ENOMEM;
break;
}
}
audio->buf_alloc |= BUF_ALLOC_OUT;
pr_debug("%s:session id %d: AUDIO_SET_STREAM_CONFIG %d %d\n",
__func__, audio->ac->session,
audio->str_cfg.buffer_size,
audio->str_cfg.buffer_count);
break;
}
case AUDIO_SET_BUF_CFG_32: {
struct msm_audio_buf_cfg32 cfg_32;
struct msm_audio_buf_cfg cfg;
if (copy_from_user(&cfg_32, (void *)arg, sizeof(cfg_32))) {
pr_err("%s: copy_from_user for AUDIO_SET_BUG_CFG_32 failed",
__func__);
rc = -EFAULT;
break;
}
cfg.meta_info_enable = cfg_32.meta_info_enable;
cfg.frames_per_buf = cfg_32.frames_per_buf;
if ((audio->feedback == NON_TUNNEL_MODE) &&
!cfg.meta_info_enable) {
rc = -EFAULT;
break;
}
/* Restrict the num of frames per buf to coincide with
* default buf size */
if (cfg.frames_per_buf > audio->max_frames_per_buf) {
rc = -EFAULT;
break;
}
audio->buf_cfg.meta_info_enable = cfg.meta_info_enable;
audio->buf_cfg.frames_per_buf = cfg.frames_per_buf;
pr_debug("%s:session id %d: Set-buf-cfg: meta[%d] framesperbuf[%d]\n",
__func__, audio->ac->session, cfg.meta_info_enable,
cfg.frames_per_buf);
break;
}
case AUDIO_GET_BUF_CFG_32: {
struct msm_audio_buf_cfg32 cfg_32;
pr_debug("%s:session id %d: Get-buf-cfg: meta[%d] framesperbuf[%d]\n",
__func__,
audio->ac->session, audio->buf_cfg.meta_info_enable,
audio->buf_cfg.frames_per_buf);
cfg_32.meta_info_enable = audio->buf_cfg.meta_info_enable;
cfg_32.frames_per_buf = audio->buf_cfg.frames_per_buf;
if (copy_to_user((void *)arg, &cfg_32,
sizeof(struct msm_audio_buf_cfg32))) {
pr_err("%s: Copy to user failed\n", __func__);
rc = -EFAULT;
}
break;
}
case AUDIO_GET_CONFIG_32: {
struct msm_audio_config32 cfg_32;
cfg_32.buffer_size = audio->pcm_cfg.buffer_size;
cfg_32.buffer_count = audio->pcm_cfg.buffer_count;
cfg_32.channel_count = audio->pcm_cfg.channel_count;
cfg_32.sample_rate = audio->pcm_cfg.sample_rate;
cfg_32.type = audio->pcm_cfg.type;
cfg_32.meta_field = audio->pcm_cfg.meta_field;
cfg_32.bits = audio->pcm_cfg.bits;
if (copy_to_user((void *)arg, &cfg_32,
sizeof(struct msm_audio_config32))) {
pr_err("%s: Copy to user failed\n", __func__);
rc = -EFAULT;
}
break;
}
case AUDIO_SET_CONFIG_32: {
struct msm_audio_config32 cfg_32;
struct msm_audio_config cfg;
if (copy_from_user(&cfg_32, (void *)arg, sizeof(cfg_32))) {
pr_err("%s: copy_from_user for AUDIO_SET_CONFIG_32 failed\n",
__func__);
rc = -EFAULT;
break;
}
cfg.buffer_size = cfg_32.buffer_size;
cfg.buffer_count = cfg_32.buffer_count;
cfg.channel_count = cfg_32.channel_count;
cfg.sample_rate = cfg_32.sample_rate;
cfg.type = cfg_32.type;
cfg.meta_field = cfg_32.meta_field;
cfg.bits = cfg_32.bits;
rc = audio_in_set_config(file, &cfg);
}
default:
/* call codec specific ioctl */
rc = audio->enc_compat_ioctl(file, cmd, arg);
}
mutex_unlock(&audio->lock);
return rc;
}
#endif
ssize_t audio_in_read(struct file *file,
char __user *buf,
size_t count, loff_t *pos)

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -11,6 +11,7 @@
*
*/
#include <linux/msm_audio.h>
#include <linux/compat.h>
#include "q6audio_common.h"
#define FRAME_NUM (8)
@ -28,8 +29,8 @@
#define ALIGN_BUF_SIZE(size) ((size + 4095) & (~4095))
struct timestamp {
unsigned long lowpart;
unsigned long highpart;
u32 lowpart;
u32 highpart;
} __packed;
struct meta_in {
@ -89,6 +90,7 @@ struct q6audio_in {
uint16_t min_frame_size;
uint16_t max_frames_per_buf;
long (*enc_ioctl)(struct file *, unsigned int, unsigned long);
long (*enc_compat_ioctl)(struct file *, unsigned int, unsigned long);
};
int audio_in_enable(struct q6audio_in *audio);
@ -96,9 +98,16 @@ int audio_in_disable(struct q6audio_in *audio);
int audio_in_buf_alloc(struct q6audio_in *audio);
long audio_in_ioctl(struct file *file,
unsigned int cmd, unsigned long arg);
#ifdef CONFIG_COMPAT
long audio_in_compat_ioctl(struct file *file,
unsigned int cmd, unsigned long arg);
#else
#define audio_in_compat_ioctl NULL
#endif
ssize_t audio_in_read(struct file *file, char __user *buf,
size_t count, loff_t *pos);
ssize_t audio_in_write(struct file *file, const char __user *buf,
size_t count, loff_t *pos);
int audio_in_release(struct inode *inode, struct file *file);
int audio_in_set_config(struct file *file, struct msm_audio_config *cfg);

View file

@ -25,6 +25,7 @@
#include <asm/ioctls.h>
#include <linux/debugfs.h>
#include <linux/msm_audio_ion.h>
#include <linux/compat.h>
#include "audio_utils_aio.h"
#ifdef CONFIG_USE_DEV_CTRL_VOLUME
#include <linux/qdsp6v2/audio_dev_ctl.h>
@ -70,6 +71,14 @@ ssize_t audio_aio_debug_read(struct file *file, char __user *buf,
}
#endif
static long audio_aio_ioctl(struct file *file, unsigned int cmd,
unsigned long arg);
#ifdef CONFIG_COMPAT
static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd,
unsigned long arg);
#else
#define audio_aio_compat_ioctl NULL
#endif
int insert_eos_buf(struct q6audio_aio *audio,
struct audio_aio_buffer_node *buf_node)
{
@ -140,11 +149,11 @@ static int audio_aio_ion_lookup_vaddr(struct q6audio_aio *audio, void *addr,
return *region ? 0 : -1;
}
static unsigned long audio_aio_ion_fixup(struct q6audio_aio *audio, void *addr,
static phys_addr_t audio_aio_ion_fixup(struct q6audio_aio *audio, void *addr,
unsigned long len, int ref_up, void **kvaddr)
{
struct audio_aio_ion_region *region;
unsigned long paddr;
phys_addr_t paddr;
int ret;
ret = audio_aio_ion_lookup_vaddr(audio, addr, len, &region);
@ -675,19 +684,15 @@ static int audio_aio_events_pending(struct q6audio_aio *audio)
return empty || audio->event_abort;
}
static long audio_aio_process_event_req(struct q6audio_aio *audio,
void __user *arg)
static long audio_aio_process_event_req_common(struct q6audio_aio *audio,
struct msm_audio_event *usr_evt)
{
long rc;
struct msm_audio_event usr_evt;
struct audio_aio_event *drv_evt = NULL;
int timeout;
unsigned long flags;
if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event)))
return -EFAULT;
timeout = (int)usr_evt.timeout_ms;
timeout = usr_evt->timeout_ms;
if (timeout > 0) {
rc = wait_event_interruptible_timeout(audio->event_wait,
@ -718,8 +723,8 @@ static long audio_aio_process_event_req(struct q6audio_aio *audio,
list_del(&drv_evt->list);
}
if (drv_evt) {
usr_evt.event_type = drv_evt->event_type;
usr_evt.event_payload = drv_evt->payload;
usr_evt->event_type = drv_evt->event_type;
usr_evt->event_payload = drv_evt->payload;
list_add_tail(&drv_evt->list, &audio->free_event_queue);
} else {
pr_err("%s[%p]:Unexpected path\n", __func__, audio);
@ -753,12 +758,134 @@ static long audio_aio_process_event_req(struct q6audio_aio *audio,
audio_aio_flush(audio);
}
if (copy_to_user(arg, &usr_evt, sizeof(usr_evt)))
rc = -EFAULT;
return rc;
}
static long audio_aio_process_event_req(struct q6audio_aio *audio,
void __user *arg)
{
long rc;
struct msm_audio_event usr_evt;
if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event))) {
pr_err("%s: copy_from_user failed\n", __func__);
return -EFAULT;
}
rc = audio_aio_process_event_req_common(audio, &usr_evt);
if (copy_to_user(arg, &usr_evt, sizeof(usr_evt))) {
pr_err("%s: copy_to_user failed\n", __func__);
rc = -EFAULT;
}
return rc;
}
#ifdef CONFIG_COMPAT
struct msm_audio_aio_buf32 {
compat_uptr_t buf_addr;
u32 buf_len;
u32 data_len;
compat_uptr_t private_data;
u16 mfield_sz; /*only useful for data has meta field */
};
struct msm_audio_bitstream_info32 {
u32 codec_type;
u32 chan_info;
u32 sample_rate;
u32 bit_stream_info;
u32 bit_rate;
u32 unused[3];
};
struct msm_audio_bitstream_error_info32 {
u32 dec_id;
u32 err_msg_indicator;
u32 err_type;
};
union msm_audio_event_payload32 {
struct msm_audio_aio_buf32 aio_buf;
struct msm_audio_bitstream_info32 stream_info;
struct msm_audio_bitstream_error_info32 error_info;
s32 reserved;
};
struct msm_audio_event32 {
s32 event_type;
s32 timeout_ms;
union msm_audio_event_payload32 event_payload;
};
static long audio_aio_process_event_req_compat(struct q6audio_aio *audio,
void __user *arg)
{
long rc;
struct msm_audio_event32 usr_evt_32;
struct msm_audio_event usr_evt;
if (copy_from_user(&usr_evt_32, arg,
sizeof(struct msm_audio_event32))) {
pr_err("%s: copy_from_user failed\n", __func__);
return -EFAULT;
}
usr_evt.timeout_ms = usr_evt_32.timeout_ms;
rc = audio_aio_process_event_req_common(audio, &usr_evt);
usr_evt_32.event_type = usr_evt.event_type;
switch (usr_evt_32.event_type) {
case AUDIO_EVENT_SUSPEND:
case AUDIO_EVENT_RESUME:
case AUDIO_EVENT_WRITE_DONE:
case AUDIO_EVENT_READ_DONE:
usr_evt_32.event_payload.aio_buf.buf_addr =
ptr_to_compat(usr_evt.event_payload.aio_buf.buf_addr);
usr_evt_32.event_payload.aio_buf.buf_len =
usr_evt.event_payload.aio_buf.buf_len;
usr_evt_32.event_payload.aio_buf.data_len =
usr_evt.event_payload.aio_buf.data_len;
usr_evt_32.event_payload.aio_buf.private_data =
ptr_to_compat(usr_evt.event_payload.aio_buf.private_data);
usr_evt_32.event_payload.aio_buf.mfield_sz =
usr_evt.event_payload.aio_buf.mfield_sz;
break;
case AUDIO_EVENT_STREAM_INFO:
usr_evt_32.event_payload.stream_info.codec_type =
usr_evt.event_payload.stream_info.codec_type;
usr_evt_32.event_payload.stream_info.chan_info =
usr_evt.event_payload.stream_info.chan_info;
usr_evt_32.event_payload.stream_info.sample_rate =
usr_evt.event_payload.stream_info.sample_rate;
usr_evt_32.event_payload.stream_info.bit_stream_info =
usr_evt.event_payload.stream_info.bit_stream_info;
usr_evt_32.event_payload.stream_info.bit_rate =
usr_evt.event_payload.stream_info.bit_rate;
break;
case AUDIO_EVENT_BITSTREAM_ERROR_INFO:
usr_evt_32.event_payload.error_info.dec_id =
usr_evt.event_payload.error_info.dec_id;
usr_evt_32.event_payload.error_info.err_msg_indicator =
usr_evt.event_payload.error_info.err_msg_indicator;
usr_evt_32.event_payload.error_info.err_type =
usr_evt.event_payload.error_info.err_type;
break;
default:
pr_err("%s: unknown audio event type = %d",
__func__, usr_evt_32.event_type);
rc = -EINVAL;
return rc;
}
if (copy_to_user(arg, &usr_evt_32, sizeof(usr_evt_32))) {
pr_err("%s: copy_to_user failed\n", __func__);
rc = -EFAULT;
}
return rc;
}
#endif
static int audio_aio_ion_check(struct q6audio_aio *audio,
void *vaddr, unsigned long len)
{
@ -984,22 +1111,10 @@ static void audio_aio_async_read(struct q6audio_aio *audio,
pr_err("%s[%p]:failed\n", __func__, audio);
}
static int audio_aio_buf_add(struct q6audio_aio *audio, unsigned dir,
void __user *arg)
static int audio_aio_buf_add_shared(struct q6audio_aio *audio, u32 dir,
struct audio_aio_buffer_node *buf_node)
{
unsigned long flags;
struct audio_aio_buffer_node *buf_node;
buf_node = kzalloc(sizeof(*buf_node), GFP_KERNEL);
if (!buf_node)
return -ENOMEM;
if (copy_from_user(&buf_node->buf, arg, sizeof(buf_node->buf))) {
kfree(buf_node);
return -EFAULT;
}
pr_debug("%s[%p]:node %p dir %x buf_addr %p buf_len %d data_len %d\n",
__func__, audio, buf_node, dir, buf_node->buf.buf_addr,
@ -1081,6 +1196,57 @@ static int audio_aio_buf_add(struct q6audio_aio *audio, unsigned dir,
}
return 0;
}
#ifdef CONFIG_COMPAT
static int audio_aio_buf_add_compat(struct q6audio_aio *audio, u32 dir,
void __user *arg)
{
struct audio_aio_buffer_node *buf_node;
struct msm_audio_aio_buf32 aio_buf_32;
buf_node = kzalloc(sizeof(*buf_node), GFP_KERNEL);
if (!buf_node) {
pr_err("%s: Buffer node alloc failed\n", __func__);
return -ENOMEM;
}
if (copy_from_user(&aio_buf_32, arg, sizeof(aio_buf_32))) {
kfree(buf_node);
pr_err("%s: copy_from_user failed\n", __func__);
return -EFAULT;
}
buf_node->buf.buf_addr = compat_ptr(aio_buf_32.buf_addr);
buf_node->buf.buf_len = aio_buf_32.buf_len;
buf_node->buf.data_len = aio_buf_32.data_len;
buf_node->buf.private_data = compat_ptr(aio_buf_32.private_data);
buf_node->buf.mfield_sz = aio_buf_32.mfield_sz;
return audio_aio_buf_add_shared(audio, dir, buf_node);
}
#endif
static int audio_aio_buf_add(struct q6audio_aio *audio, u32 dir,
void __user *arg)
{
struct audio_aio_buffer_node *buf_node;
buf_node = kzalloc(sizeof(*buf_node), GFP_KERNEL);
if (!buf_node) {
pr_err("%s: Buffer node alloc failed\n", __func__);
return -ENOMEM;
}
if (copy_from_user(&buf_node->buf, arg, sizeof(buf_node->buf))) {
kfree(buf_node);
pr_err("%s: copy_from_user failed\n", __func__);
return -EFAULT;
}
return audio_aio_buf_add_shared(audio, dir, buf_node);
}
void audio_aio_ioport_reset(struct q6audio_aio *audio)
{
@ -1149,7 +1315,7 @@ int audio_aio_open(struct q6audio_aio *audio, struct file *file)
audio->opened = 1;
file->private_data = audio;
audio->codec_ioctl = audio_aio_ioctl;
audio->codec_compat_ioctl = audio_aio_compat_ioctl;
for (i = 0; i < AUDIO_EVENT_NUM; i++) {
e_node = kmalloc(sizeof(struct audio_aio_event), GFP_KERNEL);
if (e_node)
@ -1189,66 +1355,18 @@ fail:
return rc;
}
long audio_aio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
static long audio_aio_shared_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
struct q6audio_aio *audio = file->private_data;
int rc = 0;
switch (cmd) {
case AUDIO_GET_STATS: {
struct msm_audio_stats stats;
uint64_t timestamp;
memset(&stats, 0, sizeof(struct msm_audio_stats));
stats.byte_count = atomic_read(&audio->in_bytes);
stats.sample_count = atomic_read(&audio->in_samples);
rc = q6asm_get_session_time(audio->ac, &timestamp);
if (rc >= 0)
memcpy(&stats.unused[0], &timestamp, sizeof(timestamp));
else
pr_debug("Error while getting timestamp\n");
if (copy_to_user((void *)arg, &stats, sizeof(stats)))
rc = -EFAULT;
break;
}
case AUDIO_GET_EVENT: {
pr_debug("%s[%p]:AUDIO_GET_EVENT\n", __func__, audio);
if (mutex_trylock(&audio->get_event_lock)) {
rc = audio_aio_process_event_req(audio,
(void __user *)arg);
mutex_unlock(&audio->get_event_lock);
} else
rc = -EBUSY;
break;
}
case AUDIO_ABORT_GET_EVENT: {
audio->event_abort = 1;
wake_up(&audio->event_wait);
break;
}
case AUDIO_ASYNC_WRITE: {
mutex_lock(&audio->write_lock);
if (audio->drv_status & ADRV_STATUS_FSYNC)
rc = -EBUSY;
else {
if (audio->enabled)
rc = audio_aio_buf_add(audio, 1,
(void __user *)arg);
else
rc = -EPERM;
}
mutex_unlock(&audio->write_lock);
break;
}
case AUDIO_ASYNC_READ: {
mutex_lock(&audio->read_lock);
if ((audio->feedback) && (audio->enabled))
rc = audio_aio_buf_add(audio, 0,
(void __user *)arg);
else
rc = -EPERM;
mutex_unlock(&audio->read_lock);
break;
}
case AUDIO_OUTPORT_FLUSH: {
pr_debug("%s[%p]:AUDIO_OUTPORT_FLUSH\n", __func__, audio);
mutex_lock(&audio->read_lock);
@ -1342,28 +1460,93 @@ long audio_aio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
mutex_unlock(&audio->lock);
break;
}
case AUDIO_REGISTER_ION: {
struct msm_audio_ion_info info;
pr_debug("%s[%p]:AUDIO_REGISTER_ION\n", __func__, audio);
case AUDIO_GET_SESSION_ID: {
mutex_lock(&audio->lock);
if (copy_from_user(&info, (void *)arg, sizeof(info)))
if (copy_to_user((void *)arg, &audio->ac->session,
sizeof(u16))) {
pr_err("%s: copy_to_user for AUDIO_GET_SESSION_ID failed\n",
__func__);
rc = -EFAULT;
else
rc = audio_aio_ion_add(audio, &info);
}
mutex_unlock(&audio->lock);
break;
}
case AUDIO_DEREGISTER_ION: {
struct msm_audio_ion_info info;
mutex_lock(&audio->lock);
pr_debug("%s[%p]:AUDIO_DEREGISTER_ION\n", __func__, audio);
if (copy_from_user(&info, (void *)arg, sizeof(info)))
rc = -EFAULT;
default:
pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd);
rc = -EINVAL;
}
return rc;
}
static long audio_aio_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
struct q6audio_aio *audio = file->private_data;
int rc = 0;
switch (cmd) {
case AUDIO_ABORT_GET_EVENT:
case AUDIO_OUTPORT_FLUSH:
case AUDIO_STOP:
case AUDIO_PAUSE:
case AUDIO_FLUSH:
rc = audio_aio_shared_ioctl(file, cmd, arg);
break;
case AUDIO_GET_STATS: {
struct msm_audio_stats stats;
uint64_t timestamp;
memset(&stats, 0, sizeof(struct msm_audio_stats));
stats.byte_count = atomic_read(&audio->in_bytes);
stats.sample_count = atomic_read(&audio->in_samples);
rc = q6asm_get_session_time(audio->ac, &timestamp);
if (rc >= 0)
memcpy(&stats.unused[0], &timestamp, sizeof(timestamp));
else
rc = audio_aio_ion_remove(audio, &info);
mutex_unlock(&audio->lock);
pr_debug("Error while getting timestamp\n");
if (copy_to_user((void *)arg, &stats, sizeof(stats))) {
pr_err("%s: copy_frm_user for AUDIO_GET_STATS failed\n",
__func__);
rc = -EFAULT;
}
break;
}
case AUDIO_GET_EVENT: {
pr_debug("%s[%p]:AUDIO_GET_EVENT\n", __func__, audio);
if (mutex_trylock(&audio->get_event_lock)) {
rc = audio_aio_process_event_req(audio,
(void __user *)arg);
mutex_unlock(&audio->get_event_lock);
} else
rc = -EBUSY;
break;
}
case AUDIO_ASYNC_WRITE: {
mutex_lock(&audio->write_lock);
if (audio->drv_status & ADRV_STATUS_FSYNC)
rc = -EBUSY;
else {
if (audio->enabled)
rc = audio_aio_buf_add(audio, 1,
(void __user *)arg);
else
rc = -EPERM;
}
mutex_unlock(&audio->write_lock);
break;
}
case AUDIO_ASYNC_READ: {
mutex_lock(&audio->read_lock);
if ((audio->feedback) && (audio->enabled))
rc = audio_aio_buf_add(audio, 0,
(void __user *)arg);
else
rc = -EPERM;
mutex_unlock(&audio->read_lock);
break;
}
case AUDIO_GET_STREAM_CONFIG: {
struct msm_audio_stream_config cfg;
mutex_lock(&audio->lock);
@ -1372,8 +1555,12 @@ long audio_aio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
cfg.buffer_count = audio->str_cfg.buffer_count;
pr_debug("%s[%p]:GET STREAM CFG %d %d\n",
__func__, audio, cfg.buffer_size, cfg.buffer_count);
if (copy_to_user((void *)arg, &cfg, sizeof(cfg)))
if (copy_to_user((void *)arg, &cfg, sizeof(cfg))) {
pr_err(
"%s: copy_to_user for AUDIO_GET_STREAM_CONFIG failed\n",
__func__);
rc = -EFAULT;
}
mutex_unlock(&audio->lock);
break;
}
@ -1382,6 +1569,9 @@ long audio_aio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
pr_debug("%s[%p]:SET STREAM CONFIG\n", __func__, audio);
mutex_lock(&audio->lock);
if (copy_from_user(&cfg, (void *)arg, sizeof(cfg))) {
pr_err(
"%s: copy_from_user for AUDIO_SET_STREAM_CONFIG failed\n",
__func__);
rc = -EFAULT;
mutex_unlock(&audio->lock);
break;
@ -1395,8 +1585,12 @@ long audio_aio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case AUDIO_GET_CONFIG: {
struct msm_audio_config cfg;
mutex_lock(&audio->lock);
if (copy_to_user((void *)arg, &audio->pcm_cfg, sizeof(cfg)))
if (copy_to_user((void *)arg, &audio->pcm_cfg, sizeof(cfg))) {
pr_err(
"%s: copy_to_user for AUDIO_GET_CONFIG failed\n",
__func__);
rc = -EFAULT;
}
mutex_unlock(&audio->lock);
break;
}
@ -1405,6 +1599,9 @@ long audio_aio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
pr_err("%s[%p]:AUDIO_SET_CONFIG\n", __func__, audio);
mutex_lock(&audio->lock);
if (copy_from_user(&config, (void *)arg, sizeof(config))) {
pr_err(
"%s: copy_from_user for AUDIO_SET_CONFIG failed\n",
__func__);
rc = -EFAULT;
mutex_unlock(&audio->lock);
break;
@ -1435,6 +1632,9 @@ long audio_aio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
struct msm_audio_buf_cfg cfg;
mutex_lock(&audio->lock);
if (copy_from_user(&cfg, (void *)arg, sizeof(cfg))) {
pr_err(
"%s: copy_from_user for AUDIO_GET_BUF CONFIG failed\n",
__func__);
rc = -EFAULT;
mutex_unlock(&audio->lock);
break;
@ -1461,22 +1661,365 @@ long audio_aio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
mutex_lock(&audio->lock);
if (copy_to_user((void *)arg, &audio->buf_cfg,
sizeof(struct msm_audio_buf_cfg)))
rc = -EFAULT;
mutex_unlock(&audio->lock);
break;
}
case AUDIO_GET_SESSION_ID: {
mutex_lock(&audio->lock);
if (copy_to_user((void *)arg, &audio->ac->session,
sizeof(unsigned short))) {
sizeof(struct msm_audio_buf_cfg))) {
pr_err(
"%s: copy_to_user for AUDIO_GET_BUF_CONFIG failed\n",
__func__);
rc = -EFAULT;
}
mutex_unlock(&audio->lock);
break;
}
case AUDIO_REGISTER_ION: {
struct msm_audio_ion_info info;
pr_debug("%s[%p]:AUDIO_REGISTER_ION\n", __func__, audio);
mutex_lock(&audio->lock);
if (copy_from_user(&info, (void *)arg, sizeof(info))) {
pr_err(
"%s: copy_from_user for AUDIO_REGISTER_ION failed\n",
__func__);
rc = -EFAULT;
} else {
rc = audio_aio_ion_add(audio, &info);
}
mutex_unlock(&audio->lock);
break;
}
case AUDIO_DEREGISTER_ION: {
struct msm_audio_ion_info info;
mutex_lock(&audio->lock);
pr_debug("%s[%p]:AUDIO_DEREGISTER_ION\n", __func__, audio);
if (copy_from_user(&info, (void *)arg, sizeof(info))) {
pr_err(
"%s: copy_from_user for AUDIO_DEREGISTER_ION failed\n",
__func__);
rc = -EFAULT;
} else {
rc = audio_aio_ion_remove(audio, &info);
}
mutex_unlock(&audio->lock);
break;
}
default:
pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd);
rc = -EINVAL;
}
return rc;
}
#ifdef CONFIG_COMPAT
struct msm_audio_stream_config32 {
u32 buffer_size;
u32 buffer_count;
};
struct msm_audio_stats32 {
u32 byte_count;
u32 sample_count;
u32 unused[2];
};
struct msm_audio_config32 {
u32 buffer_size;
u32 buffer_count;
u32 channel_count;
u32 sample_rate;
u32 type;
u32 meta_field;
u32 bits;
u32 unused[3];
};
struct msm_audio_buf_cfg32 {
u32 meta_info_enable;
u32 frames_per_buf;
};
struct msm_audio_ion_info32 {
int fd;
compat_uptr_t vaddr;
};
enum {
AUDIO_GET_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC, 3,
struct msm_audio_config32),
AUDIO_SET_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC, 4,
struct msm_audio_config32),
AUDIO_GET_STATS_32 = _IOR(AUDIO_IOCTL_MAGIC, 5,
struct msm_audio_stats32),
AUDIO_GET_EVENT_32 = _IOR(AUDIO_IOCTL_MAGIC, 13,
struct msm_audio_event32),
AUDIO_ASYNC_WRITE_32 = _IOW(AUDIO_IOCTL_MAGIC, 17,
struct msm_audio_aio_buf32),
AUDIO_ASYNC_READ_32 = _IOW(AUDIO_IOCTL_MAGIC, 18,
struct msm_audio_aio_buf32),
AUDIO_SET_STREAM_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC, 80,
struct msm_audio_stream_config32),
AUDIO_GET_STREAM_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC, 81,
struct msm_audio_stream_config32),
AUDIO_GET_BUF_CFG_32 = _IOW(AUDIO_IOCTL_MAGIC, 93,
struct msm_audio_buf_cfg32),
AUDIO_SET_BUF_CFG_32 = _IOW(AUDIO_IOCTL_MAGIC, 94,
struct msm_audio_buf_cfg32),
AUDIO_REGISTER_ION_32 = _IOW(AUDIO_IOCTL_MAGIC, 97,
struct msm_audio_ion_info32),
AUDIO_DEREGISTER_ION_32 = _IOW(AUDIO_IOCTL_MAGIC, 98,
struct msm_audio_ion_info32),
};
static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
struct q6audio_aio *audio = file->private_data;
int rc = 0;
switch (cmd) {
case AUDIO_ABORT_GET_EVENT:
case AUDIO_OUTPORT_FLUSH:
case AUDIO_STOP:
case AUDIO_PAUSE:
case AUDIO_FLUSH:
rc = audio_aio_shared_ioctl(file, cmd, arg);
break;
case AUDIO_GET_STATS_32: {
struct msm_audio_stats32 stats;
uint64_t timestamp;
memset(&stats, 0, sizeof(struct msm_audio_stats32));
stats.byte_count = atomic_read(&audio->in_bytes);
stats.sample_count = atomic_read(&audio->in_samples);
rc = q6asm_get_session_time(audio->ac, &timestamp);
if (rc >= 0)
memcpy(&stats.unused[0], &timestamp, sizeof(timestamp));
else
pr_debug("Error while getting timestamp\n");
if (copy_to_user((void *)arg, &stats, sizeof(stats))) {
pr_err(
"%s: copy_to_user for AUDIO_GET_STATS_32 failed\n",
__func__);
rc = -EFAULT;
}
break;
}
case AUDIO_GET_EVENT_32: {
pr_debug("%s[%p]:AUDIO_GET_EVENT\n", __func__, audio);
if (mutex_trylock(&audio->get_event_lock)) {
rc = audio_aio_process_event_req_compat(audio,
(void __user *)arg);
mutex_unlock(&audio->get_event_lock);
} else
rc = -EBUSY;
break;
}
case AUDIO_ASYNC_WRITE_32: {
mutex_lock(&audio->write_lock);
if (audio->drv_status & ADRV_STATUS_FSYNC)
rc = -EBUSY;
else {
if (audio->enabled)
rc = audio_aio_buf_add_compat(audio, 1,
(void __user *)arg);
else
rc = -EPERM;
}
mutex_unlock(&audio->write_lock);
break;
}
case AUDIO_ASYNC_READ_32: {
mutex_lock(&audio->read_lock);
if ((audio->feedback) && (audio->enabled))
rc = audio_aio_buf_add_compat(audio, 0,
(void __user *)arg);
else
rc = -EPERM;
mutex_unlock(&audio->read_lock);
break;
}
case AUDIO_GET_STREAM_CONFIG_32: {
struct msm_audio_stream_config32 cfg;
mutex_lock(&audio->lock);
memset(&cfg, 0, sizeof(cfg));
cfg.buffer_size = audio->str_cfg.buffer_size;
cfg.buffer_count = audio->str_cfg.buffer_count;
pr_debug("%s[%p]:GET STREAM CFG %d %d\n",
__func__, audio, cfg.buffer_size, cfg.buffer_count);
if (copy_to_user((void *)arg, &cfg, sizeof(cfg))) {
pr_err("%s: copy_to_user for AUDIO_GET_STREAM_CONFIG_32 failed\n",
__func__);
rc = -EFAULT;
}
mutex_unlock(&audio->lock);
break;
}
case AUDIO_SET_STREAM_CONFIG_32: {
struct msm_audio_stream_config32 cfg_32;
struct msm_audio_stream_config cfg;
pr_debug("%s[%p]:SET STREAM CONFIG\n", __func__, audio);
mutex_lock(&audio->lock);
if (copy_from_user(&cfg_32, (void *)arg, sizeof(cfg_32))) {
pr_err("%s: copy_from_user for AUDIO_SET_STREAM_CONFIG_32 failed\n",
__func__);
rc = -EFAULT;
mutex_unlock(&audio->lock);
break;
}
cfg.buffer_size = cfg_32.buffer_size;
cfg.buffer_count = cfg_32.buffer_count;
audio->str_cfg.buffer_size = FRAME_SIZE;
audio->str_cfg.buffer_count = FRAME_NUM;
rc = 0;
mutex_unlock(&audio->lock);
break;
}
case AUDIO_GET_CONFIG_32: {
struct msm_audio_config32 cfg_32;
mutex_lock(&audio->lock);
cfg_32.buffer_size = audio->pcm_cfg.buffer_size;
cfg_32.buffer_count = audio->pcm_cfg.buffer_count;
cfg_32.channel_count = audio->pcm_cfg.channel_count;
cfg_32.sample_rate = audio->pcm_cfg.sample_rate;
cfg_32.type = audio->pcm_cfg.type;
cfg_32.meta_field = audio->pcm_cfg.meta_field;
cfg_32.bits = audio->pcm_cfg.bits;
if (copy_to_user((void *)arg, &cfg_32, sizeof(cfg_32))) {
pr_err("%s: copy_to_user for AUDIO_GET_CONFIG_32 failed\n",
__func__);
rc = -EFAULT;
}
mutex_unlock(&audio->lock);
break;
}
case AUDIO_SET_CONFIG_32: {
struct msm_audio_config config;
struct msm_audio_config32 config_32;
mutex_lock(&audio->lock);
if (audio->feedback != NON_TUNNEL_MODE) {
pr_err("%s[%p]:Not sufficient permission to change the playback mode\n",
__func__, audio);
rc = -EACCES;
mutex_unlock(&audio->lock);
break;
}
pr_err("%s[%p]:AUDIO_SET_CONFIG\n", __func__, audio);
if (copy_from_user(&config_32, (void *)arg,
sizeof(config_32))) {
pr_err("%s: copy_from_user for AUDIO_SET_CONFIG_32 failed\n",
__func__);
rc = -EFAULT;
mutex_unlock(&audio->lock);
break;
}
config.buffer_size = config_32.buffer_size;
config.buffer_count = config_32.buffer_count;
config.channel_count = config_32.channel_count;
config.sample_rate = config_32.sample_rate;
config.type = config_32.type;
config.meta_field = config_32.meta_field;
config.bits = config_32.bits;
if ((config.buffer_count > PCM_BUF_COUNT) ||
(config.buffer_count == 1))
config.buffer_count = PCM_BUF_COUNT;
if (config.buffer_size < PCM_BUFSZ_MIN)
config.buffer_size = PCM_BUFSZ_MIN;
audio->pcm_cfg.buffer_count = config.buffer_count;
audio->pcm_cfg.buffer_size = config.buffer_size;
audio->pcm_cfg.channel_count = config.channel_count;
audio->pcm_cfg.sample_rate = config.sample_rate;
rc = 0;
mutex_unlock(&audio->lock);
break;
}
case AUDIO_SET_BUF_CFG_32: {
struct msm_audio_buf_cfg cfg;
struct msm_audio_buf_cfg32 cfg_32;
mutex_lock(&audio->lock);
if (copy_from_user(&cfg, (void *)arg, sizeof(cfg))) {
pr_err("%s: copy_from_user for AUDIO_SET_CONFIG_32 failed\n",
__func__);
rc = -EFAULT;
mutex_unlock(&audio->lock);
break;
}
cfg.meta_info_enable = cfg_32.meta_info_enable;
cfg.frames_per_buf = cfg_32.frames_per_buf;
if ((audio->feedback == NON_TUNNEL_MODE) &&
!cfg.meta_info_enable) {
rc = -EFAULT;
mutex_unlock(&audio->lock);
break;
}
audio->buf_cfg.meta_info_enable = cfg.meta_info_enable;
pr_debug("%s[%p]:session id %d: Set-buf-cfg: meta[%d]",
__func__, audio,
audio->ac->session, cfg.meta_info_enable);
mutex_unlock(&audio->lock);
break;
}
case AUDIO_GET_BUF_CFG_32: {
struct msm_audio_buf_cfg32 cfg_32;
pr_debug("%s[%p]:session id %d: Get-buf-cfg: meta[%d] framesperbuf[%d]\n",
__func__, audio,
audio->ac->session, audio->buf_cfg.meta_info_enable,
audio->buf_cfg.frames_per_buf);
mutex_lock(&audio->lock);
cfg_32.meta_info_enable = audio->buf_cfg.meta_info_enable;
cfg_32.frames_per_buf = audio->buf_cfg.frames_per_buf;
if (copy_to_user((void *)arg, &cfg_32,
sizeof(struct msm_audio_buf_cfg32))) {
pr_err("%s: copy_to_user for AUDIO_GET_BUF_CFG_32 failed\n",
__func__);
rc = -EFAULT;
}
mutex_unlock(&audio->lock);
break;
}
case AUDIO_REGISTER_ION_32: {
struct msm_audio_ion_info32 info_32;
struct msm_audio_ion_info info;
pr_debug("%s[%p]:AUDIO_REGISTER_ION\n", __func__, audio);
mutex_lock(&audio->lock);
if (copy_from_user(&info_32, (void *)arg, sizeof(info_32))) {
pr_err("%s: copy_from_user for AUDIO_REGISTER_ION_32 failed\n",
__func__);
rc = -EFAULT;
} else {
info.fd = info_32.fd;
info.vaddr = compat_ptr(info_32.vaddr);
rc = audio_aio_ion_add(audio, &info);
}
mutex_unlock(&audio->lock);
break;
}
case AUDIO_DEREGISTER_ION_32: {
struct msm_audio_ion_info32 info_32;
struct msm_audio_ion_info info;
mutex_lock(&audio->lock);
pr_debug("%s[%p]:AUDIO_DEREGISTER_ION\n", __func__, audio);
if (copy_from_user(&info_32, (void *)arg, sizeof(info_32))) {
pr_err("%s: copy_from_user for AUDIO_DEREGISTER_ION_32 failed\n",
__func__);
rc = -EFAULT;
} else {
info.fd = info_32.fd;
info.vaddr = compat_ptr(info_32.vaddr);
rc = audio_aio_ion_remove(audio, &info);
}
mutex_unlock(&audio->lock);
break;
}
default:
pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd);
rc = -EINVAL;
}
return rc;
}
#endif

View file

@ -71,8 +71,8 @@
})
struct timestamp {
unsigned long lowpart;
unsigned long highpart;
u32 lowpart;
u32 highpart;
} __packed;
struct meta_out_dsp {
@ -189,6 +189,7 @@ struct q6audio_aio {
int rflush; /* Read flush */
int wflush; /* Write flush */
long (*codec_ioctl)(struct file *, unsigned int, unsigned long);
long (*codec_compat_ioctl)(struct file *, unsigned int, unsigned long);
};
void audio_aio_async_write_ack(struct q6audio_aio *audio, uint32_t token,
@ -208,7 +209,6 @@ int audio_aio_enable(struct q6audio_aio *audio);
void audio_aio_post_event(struct q6audio_aio *audio, int type,
union msm_audio_event_payload payload);
int audio_aio_release(struct inode *inode, struct file *file);
long audio_aio_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
int audio_aio_fsync(struct file *file, loff_t start, loff_t end, int datasync);
void audio_aio_async_out_flush(struct q6audio_aio *audio);
void audio_aio_async_in_flush(struct q6audio_aio *audio);

View file

@ -2,7 +2,7 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
* Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
* Copyright (c) 2009-2014, The Linux Foundation. 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
@ -17,6 +17,7 @@
#include <linux/types.h>
#include <linux/msm_audio_wma.h>
#include <linux/compat.h>
#include "audio_utils_aio.h"
#ifdef CONFIG_DEBUG_FS
@ -26,7 +27,8 @@ static const struct file_operations audio_wma_debug_fops = {
};
#endif
static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
static long audio_ioctl_shared(struct file *file, unsigned int cmd,
void *arg)
{
struct q6audio_aio *audio = file->private_data;
int rc = 0;
@ -78,9 +80,27 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
audio->stopped = 0;
break;
}
default:
break;
}
return rc;
}
static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct q6audio_aio *audio = file->private_data;
int rc = 0;
switch (cmd) {
case AUDIO_START: {
rc = audio_ioctl_shared(file, cmd, (void *)arg);
break;
}
case AUDIO_GET_WMA_CONFIG_V2: {
if (copy_to_user((void *)arg, audio->codec_cfg,
sizeof(struct msm_audio_wma_config_v2))) {
pr_err("%s:copy_to_user for AUDIO_SET_WMA_CONFIG_V2 failed\n",
__func__);
rc = -EFAULT;
break;
}
@ -89,20 +109,114 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case AUDIO_SET_WMA_CONFIG_V2: {
if (copy_from_user(audio->codec_cfg, (void *)arg,
sizeof(struct msm_audio_wma_config_v2))) {
pr_err("%s:copy_from_user for AUDIO_SET_WMA_CONFIG_V2 failed\n",
__func__);
rc = -EFAULT;
break;
}
break;
}
default:
default: {
pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio);
rc = audio->codec_ioctl(file, cmd, arg);
if (rc)
pr_err("Failed in utils_ioctl: %d\n", rc);
break;
}
}
return rc;
}
#ifdef CONFIG_COMPAT
struct msm_audio_wma_config_v2_32 {
u16 format_tag;
u16 numchannels;
u32 samplingrate;
u32 avgbytespersecond;
u16 block_align;
u16 validbitspersample;
u32 channelmask;
u16 encodeopt;
};
enum {
AUDIO_GET_WMA_CONFIG_V2_32 = _IOR(AUDIO_IOCTL_MAGIC,
(AUDIO_MAX_COMMON_IOCTL_NUM+2), struct msm_audio_wma_config_v2_32),
AUDIO_SET_WMA_CONFIG_V2_32 = _IOW(AUDIO_IOCTL_MAGIC,
(AUDIO_MAX_COMMON_IOCTL_NUM+3), struct msm_audio_wma_config_v2_32)
};
static long audio_compat_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
struct q6audio_aio *audio = file->private_data;
int rc = 0;
switch (cmd) {
case AUDIO_START: {
rc = audio_ioctl_shared(file, cmd, (void *)arg);
break;
}
case AUDIO_GET_WMA_CONFIG_V2_32: {
struct msm_audio_wma_config_v2 *wma_config;
struct msm_audio_wma_config_v2_32 wma_config_32;
wma_config = (struct msm_audio_wma_config_v2 *)audio->codec_cfg;
wma_config_32.format_tag = wma_config->format_tag;
wma_config_32.numchannels = wma_config->numchannels;
wma_config_32.samplingrate = wma_config->samplingrate;
wma_config_32.avgbytespersecond = wma_config->avgbytespersecond;
wma_config_32.block_align = wma_config->block_align;
wma_config_32.validbitspersample =
wma_config->validbitspersample;
wma_config_32.channelmask = wma_config->channelmask;
wma_config_32.encodeopt = wma_config->encodeopt;
if (copy_to_user((void *)arg, &wma_config_32,
sizeof(wma_config_32))) {
pr_err("%s: copy_to_user for GET_WMA_CONFIG_V2_32 failed\n",
__func__);
rc = -EFAULT;
break;
}
break;
}
case AUDIO_SET_WMA_CONFIG_V2_32: {
struct msm_audio_wma_config_v2 *wma_config;
struct msm_audio_wma_config_v2_32 wma_config_32;
if (copy_from_user(&wma_config_32, (void *)arg,
sizeof(wma_config_32))) {
pr_err("%s: copy_from_user for SET_WMA_CONFIG_V2_32 failed\n"
, __func__);
rc = -EFAULT;
break;
}
wma_config = (struct msm_audio_wma_config_v2 *)audio->codec_cfg;
wma_config->format_tag = wma_config_32.format_tag;
wma_config->numchannels = wma_config_32.numchannels;
wma_config->samplingrate = wma_config_32.samplingrate;
wma_config->avgbytespersecond = wma_config_32.avgbytespersecond;
wma_config->block_align = wma_config_32.block_align;
wma_config->validbitspersample =
wma_config_32.validbitspersample;
wma_config->channelmask = wma_config_32.channelmask;
wma_config->encodeopt = wma_config_32.encodeopt;
break;
}
default: {
pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio);
rc = audio->codec_compat_ioctl(file, cmd, arg);
if (rc)
pr_err("Failed in utils_ioctl: %d\n", rc);
break;
}
}
return rc;
}
#else
#define audio_compat_ioctl NULL
#endif
static int audio_open(struct inode *inode, struct file *file)
{
struct q6audio_aio *audio = NULL;
@ -198,6 +312,7 @@ static const struct file_operations audio_wma_fops = {
.release = audio_aio_release,
.unlocked_ioctl = audio_ioctl,
.fsync = audio_aio_fsync,
.compat_ioctl = audio_compat_ioctl
};
struct miscdevice audio_wma_misc = {

View file

@ -2,7 +2,7 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
* Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
* Copyright (c) 2009-2014, The Linux Foundation. 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
@ -17,6 +17,7 @@
#include <linux/types.h>
#include <linux/msm_audio_wmapro.h>
#include <linux/compat.h>
#include "audio_utils_aio.h"
#ifdef CONFIG_DEBUG_FS
@ -26,7 +27,8 @@ static const struct file_operations audio_wmapro_debug_fops = {
};
#endif
static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
static long audio_ioctl_shared(struct file *file, unsigned int cmd,
void *arg)
{
struct q6audio_aio *audio = file->private_data;
int rc = 0;
@ -97,8 +99,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
wmapro_config->validbitspersample;
} else {
pr_err("%s:AUDIO_START failed: bitspersample = %d\n",
__func__,
wmapro_config->validbitspersample);
__func__, wmapro_config->validbitspersample);
rc = -EINVAL;
break;
}
@ -137,9 +138,25 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
audio->stopped = 0;
break;
}
default:
pr_err("%s: Unkown ioctl cmd %d\n", __func__, cmd);
rc = -EINVAL;
break;
}
return rc;
}
static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct q6audio_aio *audio = file->private_data;
int rc = 0;
switch (cmd) {
case AUDIO_GET_WMAPRO_CONFIG: {
if (copy_to_user((void *)arg, audio->codec_cfg,
sizeof(struct msm_audio_wmapro_config))) {
pr_err("%s: copy_to_user for AUDIO_GET_WMAPRO_CONFIG failed\n",
__func__);
rc = -EFAULT;
}
break;
@ -147,20 +164,139 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case AUDIO_SET_WMAPRO_CONFIG: {
if (copy_from_user(audio->codec_cfg, (void *)arg,
sizeof(struct msm_audio_wmapro_config))) {
pr_err("%s: copy_from_user for AUDIO_SET_WMAPRO_CONFIG_V2 failed\n",
__func__);
rc = -EFAULT;
break;
}
break;
}
default:
case AUDIO_START: {
rc = audio_ioctl_shared(file, cmd, (void *)arg);
break;
}
default: {
pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio);
rc = audio->codec_ioctl(file, cmd, arg);
if (rc)
pr_err("Failed in utils_ioctl: %d\n", rc);
break;
}
}
return rc;
}
#ifdef CONFIG_COMPAT
struct msm_audio_wmapro_config32 {
u16 armdatareqthr;
u8 validbitspersample;
u8 numchannels;
u16 formattag;
u16 samplingrate;
u16 avgbytespersecond;
u16 asfpacketlength;
u16 channelmask;
u16 encodeopt;
u16 advancedencodeopt;
u32 advancedencodeopt2;
};
enum {
AUDIO_GET_WMAPRO_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC,
(AUDIO_MAX_COMMON_IOCTL_NUM+0), struct msm_audio_wmapro_config32),
AUDIO_SET_WMAPRO_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC,
(AUDIO_MAX_COMMON_IOCTL_NUM+1), struct msm_audio_wmapro_config32)
};
static long audio_compat_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
struct q6audio_aio *audio = file->private_data;
int rc = 0;
switch (cmd) {
case AUDIO_GET_WMAPRO_CONFIG_32: {
struct msm_audio_wmapro_config *wmapro_config;
struct msm_audio_wmapro_config32 wmapro_config_32;
wmapro_config =
(struct msm_audio_wmapro_config *)audio->codec_cfg;
wmapro_config_32.armdatareqthr = wmapro_config->armdatareqthr;
wmapro_config_32.validbitspersample =
wmapro_config->validbitspersample;
wmapro_config_32.numchannels = wmapro_config->numchannels;
wmapro_config_32.formattag = wmapro_config->formattag;
wmapro_config_32.samplingrate = wmapro_config->samplingrate;
wmapro_config_32.avgbytespersecond =
wmapro_config->avgbytespersecond;
wmapro_config_32.asfpacketlength =
wmapro_config->asfpacketlength;
wmapro_config_32.channelmask = wmapro_config->channelmask;
wmapro_config_32.encodeopt = wmapro_config->encodeopt;
wmapro_config_32.advancedencodeopt =
wmapro_config->advancedencodeopt;
wmapro_config_32.advancedencodeopt2 =
wmapro_config->advancedencodeopt2;
if (copy_to_user((void *)arg, &wmapro_config_32,
sizeof(struct msm_audio_wmapro_config32))) {
pr_err("%s: copy_to_user for AUDIO_GET_WMAPRO_CONFIG_V2_32 failed\n",
__func__);
rc = -EFAULT;
}
break;
}
case AUDIO_SET_WMAPRO_CONFIG_32: {
struct msm_audio_wmapro_config *wmapro_config;
struct msm_audio_wmapro_config32 wmapro_config_32;
if (copy_from_user(&wmapro_config_32, (void *)arg,
sizeof(struct msm_audio_wmapro_config32))) {
pr_err(
"%s: copy_from_user for AUDIO_SET_WMAPRO_CONFG_V2_32 failed\n",
__func__);
rc = -EFAULT;
break;
}
wmapro_config =
(struct msm_audio_wmapro_config *)audio->codec_cfg;
wmapro_config->armdatareqthr = wmapro_config_32.armdatareqthr;
wmapro_config->validbitspersample =
wmapro_config_32.validbitspersample;
wmapro_config->numchannels = wmapro_config_32.numchannels;
wmapro_config->formattag = wmapro_config_32.formattag;
wmapro_config->samplingrate = wmapro_config_32.samplingrate;
wmapro_config->avgbytespersecond =
wmapro_config_32.avgbytespersecond;
wmapro_config->asfpacketlength =
wmapro_config_32.asfpacketlength;
wmapro_config->channelmask = wmapro_config_32.channelmask;
wmapro_config->encodeopt = wmapro_config_32.encodeopt;
wmapro_config->advancedencodeopt =
wmapro_config_32.advancedencodeopt;
wmapro_config->advancedencodeopt2 =
wmapro_config_32.advancedencodeopt2;
break;
}
case AUDIO_START: {
rc = audio_ioctl_shared(file, cmd, (void *)arg);
break;
}
default: {
pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio);
rc = audio->codec_compat_ioctl(file, cmd, arg);
if (rc)
pr_err("Failed in utils_ioctl: %d\n", rc);
break;
}
}
return rc;
}
#else
#define audio_compat_ioctl NULL
#endif
static int audio_open(struct inode *inode, struct file *file)
{
struct q6audio_aio *audio = NULL;
@ -257,6 +393,7 @@ static const struct file_operations audio_wmapro_fops = {
.release = audio_aio_release,
.unlocked_ioctl = audio_ioctl,
.fsync = audio_aio_fsync,
.compat_ioctl = audio_compat_ioctl
};
struct miscdevice audio_wmapro_misc = {

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -21,6 +21,7 @@
#include <linux/slab.h>
#include <linux/msm_audio_qcp.h>
#include <linux/atomic.h>
#include <linux/compat.h>
#include <asm/ioctls.h>
#include "audio_utils.h"
@ -30,8 +31,7 @@
/* Maximum 10 frames in buffer with meta */
#define FRAME_SIZE (1 + ((23+sizeof(struct meta_out_dsp)) * 10))
/* ------------------- device --------------------- */
static long evrc_in_ioctl(struct file *file,
static long evrc_in_ioctl_shared(struct file *file,
unsigned int cmd, unsigned long arg)
{
struct q6audio_in *audio = file->private_data;
@ -108,41 +108,36 @@ static long evrc_in_ioctl(struct file *file,
}
break;
}
case AUDIO_GET_EVRC_ENC_CONFIG: {
if (copy_to_user((void *)arg, audio->enc_cfg,
sizeof(struct msm_audio_evrc_enc_config)))
rc = -EFAULT;
break;
}
case AUDIO_SET_EVRC_ENC_CONFIG: {
struct msm_audio_evrc_enc_config cfg;
struct msm_audio_evrc_enc_config *cfg;
struct msm_audio_evrc_enc_config *enc_cfg;
enc_cfg = audio->enc_cfg;
if (copy_from_user(&cfg, (void *) arg,
sizeof(struct msm_audio_evrc_enc_config))) {
rc = -EFAULT;
cfg = (struct msm_audio_evrc_enc_config *)arg;
if (cfg == NULL) {
pr_err("%s: NULL config pointer for %s\n",
__func__, "AUDIO_SET_EVRC_ENC_CONFIG");
rc = -EINVAL;
break;
}
if (cfg.min_bit_rate > 4 ||
cfg.min_bit_rate < 1 ||
(cfg.min_bit_rate == 2)) {
if (cfg->min_bit_rate > 4 ||
cfg->min_bit_rate < 1 ||
(cfg->min_bit_rate == 2)) {
pr_err("%s:session id %d: invalid min bitrate\n",
__func__, audio->ac->session);
rc = -EINVAL;
break;
}
if (cfg.max_bit_rate > 4 ||
cfg.max_bit_rate < 1 ||
(cfg.max_bit_rate == 2)) {
if (cfg->max_bit_rate > 4 ||
cfg->max_bit_rate < 1 ||
(cfg->max_bit_rate == 2)) {
pr_err("%s:session id %d: invalid max bitrate\n",
__func__, audio->ac->session);
rc = -EINVAL;
break;
}
enc_cfg->min_bit_rate = cfg.min_bit_rate;
enc_cfg->max_bit_rate = cfg.max_bit_rate;
enc_cfg->min_bit_rate = cfg->min_bit_rate;
enc_cfg->max_bit_rate = cfg->max_bit_rate;
pr_debug("%s:session id %d: min_bit_rate= 0x%x max_bit_rate=0x%x\n",
__func__,
audio->ac->session, enc_cfg->min_bit_rate,
@ -150,11 +145,128 @@ static long evrc_in_ioctl(struct file *file,
break;
}
default:
pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd);
rc = -EINVAL;
}
return rc;
}
static long evrc_in_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
struct q6audio_in *audio = file->private_data;
int rc = 0;
switch (cmd) {
case AUDIO_START:
case AUDIO_STOP: {
rc = evrc_in_ioctl_shared(file, cmd, arg);
break;
}
case AUDIO_GET_EVRC_ENC_CONFIG: {
if (copy_to_user((void *)arg, audio->enc_cfg,
sizeof(struct msm_audio_evrc_enc_config))) {
pr_err("%s: copy_to_user for AUDIO_GET_EVRC_ENC_CONFIG failed\n",
__func__);
rc = -EFAULT;
}
break;
}
case AUDIO_SET_EVRC_ENC_CONFIG: {
struct msm_audio_evrc_enc_config cfg;
if (copy_from_user(&cfg, (void *) arg,
sizeof(struct msm_audio_evrc_enc_config))) {
pr_err("%s: copy_from_user for AUDIO_SET_EVRC_ENC_CONFIG failed\n",
__func__);
rc = -EFAULT;
break;
}
rc = evrc_in_ioctl_shared(file, cmd, (unsigned long)&cfg);
if (rc)
pr_err("%s:AUDIO_SET_EVRC_ENC_CONFIG failed. rc= %d\n",
__func__, rc);
break;
}
default:
pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd);
rc = -EINVAL;
}
return rc;
}
#ifdef CONFIG_COMPAT
struct msm_audio_evrc_enc_config32 {
u32 cdma_rate;
u32 min_bit_rate;
u32 max_bit_rate;
};
enum {
AUDIO_SET_EVRC_ENC_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC,
2, struct msm_audio_evrc_enc_config32),
AUDIO_GET_EVRC_ENC_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC,
3, struct msm_audio_evrc_enc_config32)
};
static long evrc_in_compat_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
struct q6audio_in *audio = file->private_data;
int rc = 0;
switch (cmd) {
case AUDIO_START:
case AUDIO_STOP: {
rc = evrc_in_ioctl_shared(file, cmd, arg);
break;
}
case AUDIO_GET_EVRC_ENC_CONFIG_32: {
struct msm_audio_evrc_enc_config32 cfg_32;
struct msm_audio_evrc_enc_config *enc_cfg;
enc_cfg = audio->enc_cfg;
cfg_32.cdma_rate = enc_cfg->cdma_rate;
cfg_32.min_bit_rate = enc_cfg->min_bit_rate;
cfg_32.max_bit_rate = enc_cfg->max_bit_rate;
if (copy_to_user((void *)arg, &cfg_32,
sizeof(cfg_32))) {
pr_err("%s: copy_to_user for AUDIO_GET_EVRC_ENC_CONFIG_32 failed\n",
__func__);
rc = -EFAULT;
}
break;
}
case AUDIO_SET_EVRC_ENC_CONFIG_32: {
struct msm_audio_evrc_enc_config cfg;
struct msm_audio_evrc_enc_config32 cfg_32;
if (copy_from_user(&cfg_32, (void *) arg,
sizeof(cfg_32))) {
pr_err("%s: copy_from_user for AUDIO_SET_EVRC_ENC_CONFIG_32 failed\n",
__func__);
rc = -EFAULT;
break;
}
cfg.cdma_rate = cfg_32.cdma_rate;
cfg.min_bit_rate = cfg_32.min_bit_rate;
cfg.max_bit_rate = cfg_32.max_bit_rate;
cmd = AUDIO_SET_EVRC_ENC_CONFIG;
rc = evrc_in_ioctl_shared(file, cmd, (unsigned long)&cfg);
if (rc)
pr_err("%s:AUDIO_SET_EVRC_ENC_CONFIG failed. rc= %d\n",
__func__, rc);
break;
}
default:
pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd);
rc = -EINVAL;
}
return rc;
}
#else
#define evrc_in_compat_ioctl NULL
#endif
static int evrc_in_open(struct inode *inode, struct file *file)
{
struct q6audio_in *audio = NULL;
@ -258,6 +370,7 @@ static int evrc_in_open(struct inode *inode, struct file *file)
audio->opened = 1;
atomic_set(&audio->in_count, PCM_BUF_COUNT);
atomic_set(&audio->out_count, 0x00);
audio->enc_compat_ioctl = evrc_in_compat_ioctl;
audio->enc_ioctl = evrc_in_ioctl;
file->private_data = audio;
@ -277,6 +390,7 @@ static const struct file_operations audio_in_fops = {
.read = audio_in_read,
.write = audio_in_write,
.unlocked_ioctl = audio_in_ioctl,
.compat_ioctl = audio_in_compat_ioctl
};
struct miscdevice audio_evrc_in_misc = {

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -129,7 +129,7 @@ void extract_meta_out_info(struct q6audio_aio *audio,
else
memset(&buf_node->meta_info.meta_in,
0, sizeof(struct dec_meta_in));
pr_debug("%s[%p]:i/p: msw_ts 0x%lx lsw_ts 0x%lx nflags 0x%8x\n",
pr_debug("%s[%p]:i/p: msw_ts 0x%d lsw_ts 0x%d nflags 0x%8x\n",
__func__, audio,
buf_node->meta_info.meta_in.ntimestamp.highpart,
buf_node->meta_info.meta_in.ntimestamp.lowpart,
@ -144,7 +144,7 @@ void extract_meta_out_info(struct q6audio_aio *audio,
meta_data->meta_out_dsp[0].lsw_ts;
meta_data->meta_out_dsp[0].lsw_ts = temp;
pr_debug("%s[%p]:o/p: msw_ts 0x%8x lsw_ts 0x%8x nflags 0x%8x, num_frames = %d\n",
pr_debug("%s[%p]:o/p: msw_ts 0x%d lsw_ts 0x%d nflags 0x%8x, num_frames = %d\n",
__func__, audio,
((struct dec_meta_out *)buf_node->kvaddr)->\
meta_out_dsp[0].msw_ts,

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -21,6 +21,7 @@
#include <linux/slab.h>
#include <linux/msm_audio_qcp.h>
#include <linux/atomic.h>
#include <linux/compat.h>
#include <asm/ioctls.h>
#include "audio_utils.h"
@ -30,8 +31,7 @@
/* Maximum 10 frames in buffer with meta */
#define FRAME_SIZE (1 + ((35+sizeof(struct meta_out_dsp)) * 10))
/* ------------------- device --------------------- */
static long qcelp_in_ioctl(struct file *file,
static long qcelp_in_ioctl_shared(struct file *file,
unsigned int cmd, unsigned long arg)
{
struct q6audio_in *audio = file->private_data;
@ -109,38 +109,34 @@ static long qcelp_in_ioctl(struct file *file,
}
break;
}
case AUDIO_GET_QCELP_ENC_CONFIG: {
if (copy_to_user((void *)arg, audio->enc_cfg,
sizeof(struct msm_audio_qcelp_enc_config)))
rc = -EFAULT;
break;
}
case AUDIO_SET_QCELP_ENC_CONFIG: {
struct msm_audio_qcelp_enc_config cfg;
struct msm_audio_qcelp_enc_config *cfg;
struct msm_audio_qcelp_enc_config *enc_cfg;
enc_cfg = audio->enc_cfg;
if (copy_from_user(&cfg, (void *) arg,
sizeof(struct msm_audio_qcelp_enc_config))) {
rc = -EFAULT;
cfg = (struct msm_audio_qcelp_enc_config *)arg;
if (cfg == NULL) {
pr_err("%s: NULL config pointer\n", __func__);
rc = -EINVAL;
break;
}
if (cfg.min_bit_rate > 4 ||
cfg.min_bit_rate < 1) {
if (cfg->min_bit_rate > 4 ||
cfg->min_bit_rate < 1) {
pr_err("%s:session id %d: invalid min bitrate\n",
__func__, audio->ac->session);
rc = -EINVAL;
break;
}
if (cfg.max_bit_rate > 4 ||
cfg.max_bit_rate < 1) {
if (cfg->max_bit_rate > 4 ||
cfg->max_bit_rate < 1) {
pr_err("%s:session id %d: invalid max bitrate\n",
__func__, audio->ac->session);
rc = -EINVAL;
break;
}
enc_cfg->min_bit_rate = cfg.min_bit_rate;
enc_cfg->max_bit_rate = cfg.max_bit_rate;
enc_cfg->cdma_rate = cfg->cdma_rate;
enc_cfg->min_bit_rate = cfg->min_bit_rate;
enc_cfg->max_bit_rate = cfg->max_bit_rate;
pr_debug("%s:session id %d: min_bit_rate= 0x%x max_bit_rate=0x%x\n",
__func__,
audio->ac->session, enc_cfg->min_bit_rate,
@ -148,11 +144,129 @@ static long qcelp_in_ioctl(struct file *file,
break;
}
default:
pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd);
rc = -EINVAL;
}
return rc;
}
static long qcelp_in_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
struct q6audio_in *audio = file->private_data;
int rc = 0;
switch (cmd) {
case AUDIO_START:
case AUDIO_STOP: {
rc = qcelp_in_ioctl_shared(file, cmd, arg);
break;
}
case AUDIO_GET_QCELP_ENC_CONFIG: {
if (copy_to_user((void *)arg, audio->enc_cfg,
sizeof(struct msm_audio_qcelp_enc_config))) {
pr_err(
"%s: copy_to_user for AUDIO_GET_QCELP_ENC_CONFIG failed",
__func__);
rc = -EFAULT;
}
break;
}
case AUDIO_SET_QCELP_ENC_CONFIG: {
struct msm_audio_qcelp_enc_config cfg;
if (copy_from_user(&cfg, (void *) arg,
sizeof(cfg))) {
pr_err(
"%s: copy_from_user for AUDIO_SET_QCELP_ENC_CONFIG failed",
__func__);
rc = -EFAULT;
break;
}
rc = qcelp_in_ioctl_shared(file, cmd, (unsigned long)&cfg);
if (rc)
pr_err("%s:AUDIO_SET_QCELP_ENC_CONFIG failed. Rc= %d\n",
__func__, rc);
break;
}
default:
pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd);
rc = -EINVAL;
}
return rc;
}
#ifdef CONFIG_COMPAT
struct msm_audio_qcelp_enc_config32 {
u32 cdma_rate;
u32 min_bit_rate;
u32 max_bit_rate;
};
enum {
AUDIO_SET_QCELP_ENC_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC,
0, struct msm_audio_qcelp_enc_config32),
AUDIO_GET_QCELP_ENC_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC,
1, struct msm_audio_qcelp_enc_config32)
};
static long qcelp_in_compat_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
struct q6audio_in *audio = file->private_data;
int rc = 0;
switch (cmd) {
case AUDIO_START:
case AUDIO_STOP: {
rc = qcelp_in_ioctl_shared(file, cmd, arg);
break;
}
case AUDIO_GET_QCELP_ENC_CONFIG_32: {
struct msm_audio_qcelp_enc_config32 cfg_32;
struct msm_audio_qcelp_enc_config *enc_cfg;
enc_cfg = (struct msm_audio_qcelp_enc_config *)audio->enc_cfg;
cfg_32.cdma_rate = enc_cfg->cdma_rate;
cfg_32.min_bit_rate = enc_cfg->min_bit_rate;
cfg_32.max_bit_rate = enc_cfg->max_bit_rate;
if (copy_to_user((void *)arg, &cfg_32,
sizeof(cfg_32))) {
pr_err("%s: copy_to_user for AUDIO_GET_QCELP_ENC_CONFIG_32 failed\n",
__func__);
rc = -EFAULT;
}
break;
}
case AUDIO_SET_QCELP_ENC_CONFIG_32: {
struct msm_audio_qcelp_enc_config32 cfg_32;
struct msm_audio_qcelp_enc_config cfg;
if (copy_from_user(&cfg_32, (void *) arg,
sizeof(cfg_32))) {
pr_err("%s: copy_from_user for AUDIO_SET_QCELP_ENC_CONFIG_32 failed\n",
__func__);
rc = -EFAULT;
break;
}
cfg.cdma_rate = cfg_32.cdma_rate;
cfg.min_bit_rate = cfg_32.min_bit_rate;
cfg.max_bit_rate = cfg_32.max_bit_rate;
cmd = AUDIO_SET_QCELP_ENC_CONFIG;
rc = qcelp_in_ioctl_shared(file, cmd, (unsigned long)&cfg);
if (rc)
pr_err("%s:AUDIO_SET_QCELP_ENC_CONFIG failed. rc= %d\n",
__func__, rc);
break;
}
default:
pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd);
rc = -EINVAL;
}
return rc;
}
#else
#define qcelp_in_compat_ioctl NULL
#endif
static int qcelp_in_open(struct inode *inode, struct file *file)
{
struct q6audio_in *audio = NULL;
@ -256,6 +370,7 @@ static int qcelp_in_open(struct inode *inode, struct file *file)
audio->opened = 1;
atomic_set(&audio->in_count, PCM_BUF_COUNT);
atomic_set(&audio->out_count, 0x00);
audio->enc_compat_ioctl = qcelp_in_compat_ioctl;
audio->enc_ioctl = qcelp_in_ioctl;
file->private_data = audio;
@ -275,6 +390,7 @@ static const struct file_operations audio_in_fops = {
.read = audio_in_read,
.write = audio_in_write,
.unlocked_ioctl = audio_in_ioctl,
.compat_ioctl = audio_in_compat_ioctl
};
struct miscdevice audio_qcelp_in_misc = {

View file

@ -27,9 +27,12 @@
#define AUDIO_START _IOW(AUDIO_IOCTL_MAGIC, 0, unsigned)
#define AUDIO_STOP _IOW(AUDIO_IOCTL_MAGIC, 1, unsigned)
#define AUDIO_FLUSH _IOW(AUDIO_IOCTL_MAGIC, 2, unsigned)
#define AUDIO_GET_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 3, unsigned)
#define AUDIO_SET_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 4, unsigned)
#define AUDIO_GET_STATS _IOR(AUDIO_IOCTL_MAGIC, 5, unsigned)
#define AUDIO_GET_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 3, \
struct msm_audio_config)
#define AUDIO_SET_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 4, \
struct msm_audio_config)
#define AUDIO_GET_STATS _IOR(AUDIO_IOCTL_MAGIC, 5, \
struct msm_audio_stats)
#define AUDIO_ENABLE_AUDPP _IOW(AUDIO_IOCTL_MAGIC, 6, unsigned)
#define AUDIO_SET_ADRC _IOW(AUDIO_IOCTL_MAGIC, 7, unsigned)
#define AUDIO_SET_EQ _IOW(AUDIO_IOCTL_MAGIC, 8, unsigned)
@ -37,12 +40,15 @@
#define AUDIO_SET_VOLUME _IOW(AUDIO_IOCTL_MAGIC, 10, unsigned)
#define AUDIO_PAUSE _IOW(AUDIO_IOCTL_MAGIC, 11, unsigned)
#define AUDIO_PLAY_DTMF _IOW(AUDIO_IOCTL_MAGIC, 12, unsigned)
#define AUDIO_GET_EVENT _IOR(AUDIO_IOCTL_MAGIC, 13, unsigned)
#define AUDIO_GET_EVENT _IOR(AUDIO_IOCTL_MAGIC, 13, \
struct msm_audio_event)
#define AUDIO_ABORT_GET_EVENT _IOW(AUDIO_IOCTL_MAGIC, 14, unsigned)
#define AUDIO_REGISTER_PMEM _IOW(AUDIO_IOCTL_MAGIC, 15, unsigned)
#define AUDIO_DEREGISTER_PMEM _IOW(AUDIO_IOCTL_MAGIC, 16, unsigned)
#define AUDIO_ASYNC_WRITE _IOW(AUDIO_IOCTL_MAGIC, 17, unsigned)
#define AUDIO_ASYNC_READ _IOW(AUDIO_IOCTL_MAGIC, 18, unsigned)
#define AUDIO_ASYNC_WRITE _IOW(AUDIO_IOCTL_MAGIC, 17, \
struct msm_audio_aio_buf)
#define AUDIO_ASYNC_READ _IOW(AUDIO_IOCTL_MAGIC, 18, \
struct msm_audio_aio_buf)
#define AUDIO_SET_INCALL _IOW(AUDIO_IOCTL_MAGIC, 19, struct msm_voicerec_mode)
#define AUDIO_GET_NUM_SND_DEVICE _IOR(AUDIO_IOCTL_MAGIC, 20, unsigned)
#define AUDIO_GET_SND_DEVICES _IOWR(AUDIO_IOCTL_MAGIC, 21, \
@ -94,8 +100,10 @@
#define AUDIO_GET_ACDB_BLK _IOW(AUDIO_IOCTL_MAGIC, 96, \
struct msm_acdb_cmd_device)
#define AUDIO_REGISTER_ION _IOW(AUDIO_IOCTL_MAGIC, 97, unsigned)
#define AUDIO_DEREGISTER_ION _IOW(AUDIO_IOCTL_MAGIC, 98, unsigned)
#define AUDIO_REGISTER_ION _IOW(AUDIO_IOCTL_MAGIC, 97, \
struct msm_audio_ion_info)
#define AUDIO_DEREGISTER_ION _IOW(AUDIO_IOCTL_MAGIC, 98, \
struct msm_audio_ion_info)
#define AUDIO_MAX_COMMON_IOCTL_NUM 100

View file

@ -4,18 +4,18 @@
#include <linux/msm_audio.h>
#define AUDIO_SET_AAC_CONFIG _IOW(AUDIO_IOCTL_MAGIC, \
(AUDIO_MAX_COMMON_IOCTL_NUM+0), unsigned)
(AUDIO_MAX_COMMON_IOCTL_NUM+0), struct msm_audio_aac_config)
#define AUDIO_GET_AAC_CONFIG _IOR(AUDIO_IOCTL_MAGIC, \
(AUDIO_MAX_COMMON_IOCTL_NUM+1), unsigned)
(AUDIO_MAX_COMMON_IOCTL_NUM+1), struct msm_audio_aac_config)
#define AUDIO_SET_AAC_ENC_CONFIG _IOW(AUDIO_IOCTL_MAGIC, \
(AUDIO_MAX_COMMON_IOCTL_NUM+3), struct msm_audio_aac_enc_config)
(AUDIO_MAX_COMMON_IOCTL_NUM+3), struct msm_audio_aac_enc_config)
#define AUDIO_GET_AAC_ENC_CONFIG _IOR(AUDIO_IOCTL_MAGIC, \
(AUDIO_MAX_COMMON_IOCTL_NUM+4), struct msm_audio_aac_enc_config)
(AUDIO_MAX_COMMON_IOCTL_NUM+4), struct msm_audio_aac_enc_config)
#define AUDIO_SET_AAC_MIX_CONFIG _IOR(AUDIO_IOCTL_MAGIC, \
(AUDIO_MAX_COMMON_IOCTL_NUM+5), unsigned)
(AUDIO_MAX_COMMON_IOCTL_NUM+5), uint32_t)
#define AUDIO_AAC_FORMAT_ADTS -1
#define AUDIO_AAC_FORMAT_RAW 0x0000

View file

@ -2,9 +2,9 @@
#define _UAPI_MSM_AUDIO_WMAPRO_H
#define AUDIO_GET_WMAPRO_CONFIG _IOR(AUDIO_IOCTL_MAGIC, \
(AUDIO_MAX_COMMON_IOCTL_NUM+0), unsigned)
(AUDIO_MAX_COMMON_IOCTL_NUM+0), struct msm_audio_wmapro_config)
#define AUDIO_SET_WMAPRO_CONFIG _IOW(AUDIO_IOCTL_MAGIC, \
(AUDIO_MAX_COMMON_IOCTL_NUM+1), unsigned)
(AUDIO_MAX_COMMON_IOCTL_NUM+1), struct msm_audio_wmapro_config)
struct msm_audio_wmapro_config {
unsigned short armdatareqthr;