Merge "msm: msm8960-clock: Add the clock mapping for MI2S TX device" into msm-3.0
diff --git a/arch/arm/mach-msm/board-8064-gpiomux.c b/arch/arm/mach-msm/board-8064-gpiomux.c
index d9999e7..aa3cf23 100644
--- a/arch/arm/mach-msm/board-8064-gpiomux.c
+++ b/arch/arm/mach-msm/board-8064-gpiomux.c
@@ -433,33 +433,6 @@
.drv = GPIOMUX_DRV_12MA,
.pull = GPIOMUX_PULL_NONE,
};
-
-#ifdef CONFIG_USB_EHCI_MSM_HSIC
-static struct gpiomux_setting hsic_act_cfg = {
- .func = GPIOMUX_FUNC_1,
- .drv = GPIOMUX_DRV_8MA,
- .pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting hsic_sus_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_2MA,
- .pull = GPIOMUX_PULL_DOWN,
- .dir = GPIOMUX_OUT_LOW,
-};
-
-static struct gpiomux_setting cyts_resout_sus_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_6MA,
- .pull = GPIOMUX_PULL_UP,
-};
-
-static struct gpiomux_setting cyts_resout_act_cfg = {
- .func = GPIOMUX_FUNC_GPIO,
- .drv = GPIOMUX_DRV_6MA,
- .pull = GPIOMUX_PULL_UP,
-};
-
static struct gpiomux_setting cyts_sleep_sus_cfg = {
.func = GPIOMUX_FUNC_GPIO,
.drv = GPIOMUX_DRV_6MA,
@@ -499,15 +472,23 @@
[GPIOMUX_SUSPENDED] = &cyts_sleep_sus_cfg,
},
},
- { /* TS RESOUT */
- .gpio = 7,
- .settings = {
- [GPIOMUX_ACTIVE] = &cyts_resout_act_cfg,
- [GPIOMUX_SUSPENDED] = &cyts_resout_sus_cfg,
- },
- },
};
+#ifdef CONFIG_USB_EHCI_MSM_HSIC
+static struct gpiomux_setting hsic_act_cfg = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting hsic_sus_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+ .dir = GPIOMUX_OUT_LOW,
+};
+
+
static struct msm_gpiomux_config apq8064_hsic_configs[] = {
{
.gpio = 88, /*HSIC_STROBE */
diff --git a/arch/arm/mach-msm/board-8064-gpu.c b/arch/arm/mach-msm/board-8064-gpu.c
index f8aa9c0..2cab803 100644
--- a/arch/arm/mach-msm/board-8064-gpu.c
+++ b/arch/arm/mach-msm/board-8064-gpu.c
@@ -195,7 +195,7 @@
.bus_freq = 0,
},
},
- .init_level = 0,
+ .init_level = 1,
.num_levels = 4,
.set_grp_async = NULL,
.idle_timeout = HZ/10,
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 9bf16c9..0b1eafd 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -1123,7 +1123,6 @@
};
#endif
#define CYTTSP_TS_GPIO_IRQ 6
-#define CYTTSP_TS_GPIO_RESOUT 7
#define CYTTSP_TS_GPIO_SLEEP 33
static ssize_t tma340_vkeys_show(struct kobject *kobj,
@@ -1217,7 +1216,7 @@
*/
.lp_intrvl = CY_LP_INTRVL_DFLT,
.sleep_gpio = CYTTSP_TS_GPIO_SLEEP,
- .resout_gpio = CYTTSP_TS_GPIO_RESOUT,
+ .resout_gpio = -1,
.irq_gpio = CYTTSP_TS_GPIO_IRQ,
.regulator_info = cyttsp_regulator_data,
.num_regulators = ARRAY_SIZE(cyttsp_regulator_data),
@@ -2128,7 +2127,7 @@
};
static struct msm_i2c_platform_data apq8064_i2c_qup_gsbi3_pdata = {
- .clk_freq = 100000,
+ .clk_freq = 384000,
.src_clk_rate = 24000000,
};
diff --git a/arch/arm/mach-msm/board-msm8x60-camera.c b/arch/arm/mach-msm/board-msm8x60-camera.c
index c952782..9b3d9eb 100644
--- a/arch/arm/mach-msm/board-msm8x60-camera.c
+++ b/arch/arm/mach-msm/board-msm8x60-camera.c
@@ -413,14 +413,14 @@
static struct i2c_board_info imx074_actuator_i2c_info = {
- I2C_BOARD_INFO("imx074_act", 0x11),
+ I2C_BOARD_INFO("msm_actuator", 0x11),
};
static struct msm_actuator_info imx074_actuator_info = {
.board_info = &imx074_actuator_i2c_info,
+ .cam_name = MSM_ACTUATOR_MAIN_CAM_0,
.bus_id = MSM_GSBI4_QUP_I2C_BUS_ID,
- .vcm_pwd = 0,
- .vcm_enable = 1,
+ .vcm_enable = 0,
};
static struct msm_camera_sensor_flash_data flash_imx074 = {
diff --git a/arch/arm/mach-msm/qdsp6v2/amrwb_in.c b/arch/arm/mach-msm/qdsp6v2/amrwb_in.c
index 1dd90a7..5df976d 100644
--- a/arch/arm/mach-msm/qdsp6v2/amrwb_in.c
+++ b/arch/arm/mach-msm/qdsp6v2/amrwb_in.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, Code Aurora Forum. 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
@@ -201,8 +201,8 @@
audio->enc_cfg = kzalloc(sizeof(struct msm_audio_amrwb_enc_config),
GFP_KERNEL);
if (audio->enc_cfg == NULL) {
- pr_err("%s: Could not allocate memory for amrwb"
- "config param\n", __func__);
+ pr_err("%s:session id %d: Could not allocate memory for amrwb"
+ "config param\n", __func__, audio->ac->session);
kfree(audio);
return -ENOMEM;
}
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_aac.c b/arch/arm/mach-msm/qdsp6v2/audio_aac.c
index 438909a..88189f6 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_aac.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_aac.c
@@ -2,7 +2,7 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -274,10 +274,6 @@
goto fail;
}
rc = audio_aio_open(audio, file);
- if (IS_ERR_VALUE(rc)) {
- pr_err("%s: audio_aio_open failed\n", __func__);
- goto fail;
- }
#ifdef CONFIG_DEBUG_FS
snprintf(name, sizeof name, "msm_aac_%04x", audio->ac->session);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_amrnb.c b/arch/arm/mach-msm/qdsp6v2/audio_amrnb.c
index 9618adb..6768f7a 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_amrnb.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_amrnb.c
@@ -2,7 +2,7 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -138,10 +138,6 @@
goto fail;
}
rc = audio_aio_open(audio, file);
- if (IS_ERR_VALUE(rc)) {
- pr_err("%s: audio_aio_open failed\n", __func__);
- goto fail;
- }
#ifdef CONFIG_DEBUG_FS
snprintf(name, sizeof name, "msm_amrnb_%04x", audio->ac->session);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_amrwb.c b/arch/arm/mach-msm/qdsp6v2/audio_amrwb.c
index a15ab28..f95e191 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_amrwb.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_amrwb.c
@@ -2,7 +2,7 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -140,10 +140,6 @@
goto fail;
}
rc = audio_aio_open(audio, file);
- if (IS_ERR_VALUE(rc)) {
- pr_err("%s: audio_aio_open failed\n", __func__);
- goto fail;
- }
#ifdef CONFIG_DEBUG_FS
snprintf(name, sizeof name, "msm_amrwb_%04x", audio->ac->session);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_evrc.c b/arch/arm/mach-msm/qdsp6v2/audio_evrc.c
index 5a511c9..12c815d 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_evrc.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_evrc.c
@@ -2,7 +2,7 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -144,10 +144,6 @@
goto fail;
}
rc = audio_aio_open(audio, file);
- if (IS_ERR_VALUE(rc)) {
- pr_err("%s: audio_aio_open failed\n", __func__);
- goto fail;
- }
#ifdef CONFIG_DEBUG_FS
snprintf(name, sizeof name, "msm_evrc_%04x", audio->ac->session);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_mp3.c b/arch/arm/mach-msm/qdsp6v2/audio_mp3.c
index eff41cc..22552c6 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_mp3.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_mp3.c
@@ -2,7 +2,7 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -141,10 +141,6 @@
goto fail;
}
rc = audio_aio_open(audio, file);
- if (IS_ERR_VALUE(rc)) {
- pr_err("%s: audio_aio_open failed\n", __func__);
- goto fail;
- }
#ifdef CONFIG_DEBUG_FS
snprintf(name, sizeof name, "msm_mp3_%04x", audio->ac->session);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_multi_aac.c b/arch/arm/mach-msm/qdsp6v2/audio_multi_aac.c
index 0f6b5a6..ee32b80 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_multi_aac.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_multi_aac.c
@@ -2,7 +2,7 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -275,10 +275,6 @@
goto fail;
}
rc = audio_aio_open(audio, file);
- if (IS_ERR_VALUE(rc)) {
- pr_err("%s: audio_aio_open failed\n", __func__);
- goto fail;
- }
#ifdef CONFIG_DEBUG_FS
snprintf(name, sizeof name, "msm_multi_aac_%04x", audio->ac->session);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_qcelp.c b/arch/arm/mach-msm/qdsp6v2/audio_qcelp.c
index 8343beb..7b72c97 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_qcelp.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_qcelp.c
@@ -2,7 +2,7 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -150,10 +150,6 @@
goto fail;
}
rc = audio_aio_open(audio, file);
- if (IS_ERR_VALUE(rc)) {
- pr_err("%s: audio_aio_open failed\n", __func__);
- goto fail;
- }
#ifdef CONFIG_DEBUG_FS
snprintf(name, sizeof name, "msm_qcelp_%04x", audio->ac->session);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
index ba3129d8..644df2d 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
@@ -1188,19 +1188,21 @@
file->private_data = audio;
audio->codec_ioctl = audio_aio_ioctl;
- e_node = kmalloc(sizeof(struct audio_aio_event) * AUDIO_EVENT_NUM,
- GFP_KERNEL);
- if (e_node) {
- for (i = 0; i < AUDIO_EVENT_NUM; i++)
- list_add_tail(&e_node[i].list,
- &audio->free_event_queue);
- } else {
- pr_err("%s[%p]:event pkt alloc failed\n",
- __func__, audio);
- rc = -ENOMEM;
- goto fail;
+ for (i = 0; i < AUDIO_EVENT_NUM; i++) {
+ e_node = kmalloc(sizeof(struct audio_aio_event), GFP_KERNEL);
+ if (e_node)
+ list_add_tail(&e_node->list, &audio->free_event_queue);
+ else {
+ pr_err("%s[%p]:event pkt alloc failed\n",
+ __func__, audio);
+ break;
+ }
}
+ return 0;
fail:
+ q6asm_audio_client_free(audio->ac);
+ kfree(audio->codec_cfg);
+ kfree(audio);
return rc;
}
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_wma.c b/arch/arm/mach-msm/qdsp6v2/audio_wma.c
index 62d4393..bea0485 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_wma.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_wma.c
@@ -2,7 +2,7 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -185,10 +185,6 @@
goto fail;
}
rc = audio_aio_open(audio, file);
- if (IS_ERR_VALUE(rc)) {
- pr_err("%s: audio_aio_open failed\n", __func__);
- goto fail;
- }
#ifdef CONFIG_DEBUG_FS
snprintf(name, sizeof name, "msm_wma_%04x", audio->ac->session);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_wmapro.c b/arch/arm/mach-msm/qdsp6v2/audio_wmapro.c
index a83fce9..98d1b30 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_wmapro.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_wmapro.c
@@ -2,7 +2,7 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -245,10 +245,6 @@
goto fail;
}
rc = audio_aio_open(audio, file);
- if (IS_ERR_VALUE(rc)) {
- pr_err("%s: audio_aio_open failed\n", __func__);
- goto fail;
- }
#ifdef CONFIG_DEBUG_FS
snprintf(name, sizeof name, "msm_wmapro_%04x", audio->ac->session);
diff --git a/arch/arm/mach-msm/qdsp6v2/q6core.c b/arch/arm/mach-msm/qdsp6v2/q6core.c
index bfd4c48..edb1e7d 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6core.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, Code Aurora Forum. 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
@@ -249,6 +249,8 @@
int len;
static int t_len;
+ if (count < 0)
+ return 0;
len = count > 63 ? 63 : count;
if (copy_from_user(l_buf + 20 , buf, len)) {
pr_info("Unable to copy data from user space\n");
diff --git a/arch/arm/mach-msm/qdsp6v2/rtac.c b/arch/arm/mach-msm/qdsp6v2/rtac.c
index 9a7a41c..4ce9b030 100644
--- a/arch/arm/mach-msm/qdsp6v2/rtac.c
+++ b/arch/arm/mach-msm/qdsp6v2/rtac.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, Code Aurora Forum. 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
@@ -443,6 +443,7 @@
if (payload_size > MAX_PAYLOAD_SIZE) {
+
pr_err("%s: Invalid payload size = %d\n",
__func__, payload_size);
goto done;
@@ -613,6 +614,7 @@
}
if (payload_size > MAX_PAYLOAD_SIZE) {
+
pr_err("%s: Invalid payload size = %d\n",
__func__, payload_size);
goto done;
@@ -623,15 +625,17 @@
__func__);
goto done;
}
- if (session_id > SESSION_MAX) {
+ if (session_id > (SESSION_MAX + 1)) {
pr_err("%s: Invalid Session = %d\n", __func__, session_id);
goto done;
}
mutex_lock(&rtac_asm_apr_mutex);
- if (rtac_asm_apr_data[session_id].apr_handle == NULL) {
- pr_err("%s: APR not initialized\n", __func__);
- goto err;
+ if (session_id < SESSION_MAX+1) {
+ if (rtac_asm_apr_data[session_id].apr_handle == NULL) {
+ pr_err("%s: APR not initialized\n", __func__);
+ goto err;
+ }
}
/* Set globals for copy of returned payload */
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 87f259d..00dba96 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -169,10 +169,9 @@
};
-static irqreturn_t adreno_isr(int irq, void *data)
+static irqreturn_t adreno_irq_handler(struct kgsl_device *device)
{
irqreturn_t result;
- struct kgsl_device *device = data;
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
result = adreno_dev->gpudev->irq_handler(adreno_dev);
@@ -490,7 +489,7 @@
if (status != 0)
goto error;
- status = kgsl_device_platform_probe(device, adreno_isr);
+ status = kgsl_device_platform_probe(device);
if (status)
goto error_close_rb;
@@ -1444,6 +1443,7 @@
.irqctrl = adreno_irqctrl,
.gpuid = adreno_gpuid,
.snapshot = adreno_snapshot,
+ .irq_handler = adreno_irq_handler,
/* Optional functions */
.setstate = adreno_setstate,
.drawctxt_create = adreno_drawctxt_create,
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index e38037c..321c59e 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -2295,6 +2295,14 @@
return 0;
}
+static irqreturn_t kgsl_irq_handler(int irq, void *data)
+{
+ struct kgsl_device *device = data;
+
+ return device->ftbl->irq_handler(device);
+
+}
+
static const struct file_operations kgsl_fops = {
.owner = THIS_MODULE,
.release = kgsl_release,
@@ -2455,8 +2463,7 @@
}
EXPORT_SYMBOL(kgsl_register_device);
-int kgsl_device_platform_probe(struct kgsl_device *device,
- irqreturn_t (*dev_isr) (int, void*))
+int kgsl_device_platform_probe(struct kgsl_device *device)
{
int result;
int status = -EINVAL;
@@ -2504,7 +2511,7 @@
goto error_release_mem;
}
- status = request_irq(device->pwrctrl.interrupt_num, dev_isr,
+ status = request_irq(device->pwrctrl.interrupt_num, kgsl_irq_handler,
IRQF_TRIGGER_HIGH, device->name, device);
if (status) {
KGSL_DRV_ERR(device, "request_irq(%d) failed: %d\n",
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index 7d3cfca..b42e606 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -94,6 +94,7 @@
unsigned int (*gpuid)(struct kgsl_device *device);
void * (*snapshot)(struct kgsl_device *device, void *snapshot,
int *remain, int hang);
+ irqreturn_t (*irq_handler)(struct kgsl_device *device);
/* Optional functions - these functions are not mandatory. The
driver will check that the function pointer is not NULL before
calling the hook */
@@ -340,8 +341,8 @@
int kgsl_unregister_ts_notifier(struct kgsl_device *device,
struct notifier_block *nb);
-int kgsl_device_platform_probe(struct kgsl_device *device,
- irqreturn_t (*dev_isr) (int, void*));
+int kgsl_device_platform_probe(struct kgsl_device *device);
+
void kgsl_device_platform_remove(struct kgsl_device *device);
const char *kgsl_pwrstate_to_str(unsigned int state);
diff --git a/drivers/gpu/msm/z180.c b/drivers/gpu/msm/z180.c
index 8c29535..5902361 100644
--- a/drivers/gpu/msm/z180.c
+++ b/drivers/gpu/msm/z180.c
@@ -206,11 +206,10 @@
},
};
-static irqreturn_t z180_isr(int irq, void *data)
+static irqreturn_t z180_irq_handler(struct kgsl_device *device)
{
irqreturn_t result = IRQ_NONE;
unsigned int status;
- struct kgsl_device *device = (struct kgsl_device *) data;
struct z180_device *z180_dev = Z180_DEVICE(device);
z180_regread(device, ADDR_VGC_IRQSTATUS >> 2, &status);
@@ -546,7 +545,7 @@
if (status != 0)
goto error;
- status = kgsl_device_platform_probe(device, z180_isr);
+ status = kgsl_device_platform_probe(device);
if (status)
goto error_close_ringbuffer;
@@ -945,6 +944,7 @@
.power_stats = z180_power_stats,
.irqctrl = z180_irqctrl,
.gpuid = z180_gpuid,
+ .irq_handler = z180_irq_handler,
/* Optional functions */
.drawctxt_create = NULL,
.drawctxt_destroy = z180_drawctxt_destroy,
diff --git a/drivers/media/video/msm/msm_vfe31_v4l2.c b/drivers/media/video/msm/msm_vfe31_v4l2.c
index ff4f426..d60f4b7 100644
--- a/drivers/media/video/msm/msm_vfe31_v4l2.c
+++ b/drivers/media/video/msm/msm_vfe31_v4l2.c
@@ -2372,8 +2372,7 @@
/* later we need to add check for live snapshot mode. */
if (vfe31_ctrl->frame_skip_pattern & (0x1 <<
(vfe31_ctrl->snapshot_frame_cnt %
- vfe31_ctrl->frame_skip_cnt))) {
- vfe31_ctrl->vfe_capture_count--;
+ vfe31_ctrl->frame_skip_cnt))) {
/* if last frame to be captured: */
if (vfe31_ctrl->vfe_capture_count == 0) {
/* stop the bus output:write master enable = 0*/
@@ -2403,7 +2402,6 @@
vfe31_ctrl->frame_skip_pattern = 0xffffffff;
} /*if snapshot count is 0*/
} /*if frame is not being dropped*/
- vfe31_ctrl->snapshot_frame_cnt++;
/* then do reg_update. */
msm_camera_io_w(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
} /* if snapshot mode. */
@@ -2503,6 +2501,17 @@
else
vfe31_ctrl->sync_timer_repeat_count--;
}
+ if ((vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN) ||
+ (vfe31_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB) ||
+ (vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG) ||
+ (vfe31_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB)) {
+ if (vfe31_ctrl->frame_skip_pattern & (0x1 <<
+ (vfe31_ctrl->snapshot_frame_cnt %
+ vfe31_ctrl->frame_skip_cnt))) {
+ vfe31_ctrl->vfe_capture_count--;
+ }
+ vfe31_ctrl->snapshot_frame_cnt++;
+ }
}
static void vfe31_process_error_irq(uint32_t errStatus)
diff --git a/drivers/media/video/msm/wfd/enc-subdev.c b/drivers/media/video/msm/wfd/enc-subdev.c
index 77ad02e..a027a2d 100644
--- a/drivers/media/video/msm/wfd/enc-subdev.c
+++ b/drivers/media/video/msm/wfd/enc-subdev.c
@@ -73,7 +73,7 @@
u32 i;
u32 found = false;
- for (i = 0; i < VIDC_MAX_NUM_CLIENTS; i++) {
+ for (i = 0; i < VID_ENC_MAX_ENCODER_CLIENTS; i++) {
if (!venc_p.venc_clients[i].venc_client.vcd_handle) {
found = true;
break;
diff --git a/drivers/media/video/msm/wfd/wfd-ioctl.c b/drivers/media/video/msm/wfd/wfd-ioctl.c
index fb586be..c12636c 100644
--- a/drivers/media/video/msm/wfd/wfd-ioctl.c
+++ b/drivers/media/video/msm/wfd/wfd-ioctl.c
@@ -1341,10 +1341,10 @@
if (rc)
WFD_MSG_ERR("Failed to CLOSE vsg subdev: %d\n", rc);
+ wfd_stats_deinit(&inst->stats);
kfree(inst);
}
- wfd_stats_deinit(&inst->stats);
WFD_MSG_DBG("wfd_close: X\n");
return 0;
}
diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c
index 1d3cf17..420fc19 100644
--- a/drivers/video/msm/vidc/common/dec/vdec.c
+++ b/drivers/video/msm/vidc/common/dec/vdec.c
@@ -869,7 +869,7 @@
client_ctx->h264_mv_ion_handle = ion_import_fd(
client_ctx->user_ion_client,
vcd_h264_mv_buffer->pmem_fd);
- if (!client_ctx->h264_mv_ion_handle) {
+ if (IS_ERR_OR_NULL(client_ctx->h264_mv_ion_handle)) {
ERR("%s(): get_ION_handle failed\n", __func__);
goto import_ion_error;
}
@@ -916,12 +916,16 @@
else
return true;
ion_map_error:
- if (vcd_h264_mv_buffer->kernel_virtual_addr)
+ if (vcd_h264_mv_buffer->kernel_virtual_addr) {
ion_unmap_kernel(client_ctx->user_ion_client,
client_ctx->h264_mv_ion_handle);
- if (client_ctx->h264_mv_ion_handle)
+ vcd_h264_mv_buffer->kernel_virtual_addr = NULL;
+ }
+ if (!IS_ERR_OR_NULL(client_ctx->h264_mv_ion_handle)) {
ion_free(client_ctx->user_ion_client,
client_ctx->h264_mv_ion_handle);
+ client_ctx->h264_mv_ion_handle = NULL;
+ }
import_ion_error:
return false;
}
@@ -990,7 +994,7 @@
vcd_status = vcd_set_property(client_ctx->vcd_handle,
&vcd_property_hdr, &h264_mv_buffer_size);
- if (client_ctx->h264_mv_ion_handle != NULL) {
+ if (!IS_ERR_OR_NULL(client_ctx->h264_mv_ion_handle)) {
ion_unmap_kernel(client_ctx->user_ion_client,
client_ctx->h264_mv_ion_handle);
ion_unmap_iommu(client_ctx->user_ion_client,
@@ -999,6 +1003,7 @@
VIDEO_MAIN_POOL);
ion_free(client_ctx->user_ion_client,
client_ctx->h264_mv_ion_handle);
+ client_ctx->h264_mv_ion_handle = NULL;
}
if (vcd_status)
diff --git a/drivers/video/msm/vidc/common/init/vidc_init.c b/drivers/video/msm/vidc/common/init/vidc_init.c
index dda81ed..f633235 100644
--- a/drivers/video/msm/vidc/common/init/vidc_init.c
+++ b/drivers/video/msm/vidc/common/init/vidc_init.c
@@ -417,16 +417,21 @@
buf_addr_table[i].client_data);
buf_addr_table[i].client_data = NULL;
}
- if (buf_addr_table[i].buff_ion_handle) {
- ion_unmap_kernel(client_ctx->user_ion_client,
- buf_addr_table[i].buff_ion_handle);
- ion_unmap_iommu(client_ctx->user_ion_client,
- buf_addr_table[i].buff_ion_handle,
- VIDEO_DOMAIN,
- VIDEO_MAIN_POOL);
- ion_free(client_ctx->user_ion_client,
- buf_addr_table[i].buff_ion_handle);
- buf_addr_table[i].buff_ion_handle = NULL;
+ if (!IS_ERR_OR_NULL(buf_addr_table[i].buff_ion_handle)) {
+ if (!IS_ERR_OR_NULL(client_ctx->user_ion_client)) {
+ ion_unmap_kernel(client_ctx->user_ion_client,
+ buf_addr_table[i].
+ buff_ion_handle);
+ ion_unmap_iommu(client_ctx->user_ion_client,
+ buf_addr_table[i].
+ buff_ion_handle,
+ VIDEO_DOMAIN,
+ VIDEO_MAIN_POOL);
+ ion_free(client_ctx->user_ion_client,
+ buf_addr_table[i].
+ buff_ion_handle);
+ buf_addr_table[i].buff_ion_handle = NULL;
+ }
}
}
if (client_ctx->vcd_h264_mv_buffer.client_data) {
@@ -434,16 +439,18 @@
client_ctx->vcd_h264_mv_buffer.client_data);
client_ctx->vcd_h264_mv_buffer.client_data = NULL;
}
- if (client_ctx->h264_mv_ion_handle) {
- ion_unmap_kernel(client_ctx->user_ion_client,
- client_ctx->h264_mv_ion_handle);
- ion_unmap_iommu(client_ctx->user_ion_client,
- client_ctx->h264_mv_ion_handle,
- VIDEO_DOMAIN,
- VIDEO_MAIN_POOL);
- ion_free(client_ctx->user_ion_client,
- client_ctx->h264_mv_ion_handle);
- client_ctx->h264_mv_ion_handle = NULL;
+ if (!IS_ERR_OR_NULL(client_ctx->h264_mv_ion_handle)) {
+ if (!IS_ERR_OR_NULL(client_ctx->user_ion_client)) {
+ ion_unmap_kernel(client_ctx->user_ion_client,
+ client_ctx->h264_mv_ion_handle);
+ ion_unmap_iommu(client_ctx->user_ion_client,
+ client_ctx->h264_mv_ion_handle,
+ VIDEO_DOMAIN,
+ VIDEO_MAIN_POOL);
+ ion_free(client_ctx->user_ion_client,
+ client_ctx->h264_mv_ion_handle);
+ client_ctx->h264_mv_ion_handle = NULL;
+ }
}
bail_out_cleanup:
return;
diff --git a/include/linux/iopoll.h b/include/linux/iopoll.h
new file mode 100644
index 0000000..0104abc
--- /dev/null
+++ b/include/linux/iopoll.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2012 Code Aurora Forum. 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _LINUX_IOPOLL_H
+#define _LINUX_IOPOLL_H
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/jiffies.h>
+#include <linux/delay.h>
+#include <asm-generic/errno.h>
+#include <asm/io.h>
+
+/**
+ * readl_poll_timeout - Periodically poll an address until a condition is met or a timeout occurs
+ * @addr: Address to poll
+ * @val: Variable to read the value into
+ * @cond: Break condition (usually involving @val)
+ * @sleep_us: Maximum time to sleep between reads in uS (0 tight-loops)
+ * @timeout_us: Timeout in uS, 0 means never timeout
+ *
+ * Returns 0 on success and -ETIMEDOUT upon a timeout. In either
+ * case, the last read value at @addr is stored in @val. Must not
+ * be called from atomic context if sleep_us or timeout_us are used.
+ */
+#define readl_poll_timeout(addr, val, cond, sleep_us, timeout_us) \
+({ \
+ unsigned long timeout = jiffies + usecs_to_jiffies(timeout_us); \
+ might_sleep_if(timeout_us); \
+ for (;;) { \
+ (val) = readl(addr); \
+ if ((cond) || (timeout_us && time_after(jiffies, timeout))) \
+ break; \
+ if (sleep_us) \
+ usleep_range(1, sleep_us); \
+ } \
+ (cond) ? 0 : -ETIMEDOUT; \
+})
+
+/**
+ * readl_poll - Periodically poll an address until a condition is met
+ * @addr: Address to poll
+ * @val: Variable to read the value into
+ * @cond: Break condition (usually involving @val)
+ * @sleep_us: Maximum time to sleep between reads in uS (0 tight-loops)
+ *
+ * Must not be called from atomic context if sleep_us is used.
+ */
+#define readl_poll(addr, val, cond, sleep_us) \
+ readl_poll_timeout(addr, val, cond, sleep_us, 0)
+
+/**
+ * readl_tight_poll_timeout - Tight-loop on an address until a condition is met or a timeout occurs
+ * @addr: Address to poll
+ * @val: Variable to read the value into
+ * @cond: Break condition (usually involving @val)
+ * @timeout_us: Timeout in uS, 0 means never timeout
+ *
+ * Returns 0 on success and -ETIMEDOUT upon a timeout. In either
+ * case, the last read value at @addr is stored in @val. Must not
+ * be called from atomic context if timeout_us is used.
+ */
+#define readl_tight_poll_timeout(addr, val, cond, timeout_us) \
+ readl_poll_timeout(addr, val, cond, 0, timeout_us)
+
+/**
+ * readl_tight_poll - Tight-loop on an address until a condition is met
+ * @addr: Address to poll
+ * @val: Variable to read the value into
+ * @cond: Break condition (usually involving @val)
+ *
+ * May be called from atomic context.
+ */
+#define readl_tight_poll(addr, val, cond) \
+ readl_poll_timeout(addr, val, cond, 0, 0)
+
+#endif /* _LINUX_IOPOLL_H */
diff --git a/include/linux/mfd/wcd9xxx/wcd9304_registers.h b/include/linux/mfd/wcd9xxx/wcd9304_registers.h
index 65e4728..70902bc 100644
--- a/include/linux/mfd/wcd9xxx/wcd9304_registers.h
+++ b/include/linux/mfd/wcd9xxx/wcd9304_registers.h
@@ -517,7 +517,7 @@
#define SITAR_A_CDC_CLK_TX_I2S_CTL (0x306)
#define SITAR_A_CDC_CLK_TX_I2S_CTL__POR (0x00000003)
#define SITAR_A_CDC_CLK_OTHR_RESET_CTL (0x307)
-#define SITAR_A_CDC_CLK_OTHR_RESET_CTL__POR (0x00000000)
+#define SITAR_A_CDC_CLK_OTHR_RESET_CTL__POR (0x00000010)
#define SITAR_A_CDC_CLK_TX_CLK_EN_B1_CTL (0x308)
#define SITAR_A_CDC_CLK_TX_CLK_EN_B1_CTL__POR (0x00000000)
#define SITAR_A_CDC_CLK_OTHR_CTL (0x30A)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 3b5ad95..37ee9b1 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -5371,7 +5371,7 @@
release_sock(sk);
}
-int l2cap_logical_link_complete(struct hci_chan *chan, u8 status)
+static void l2cap_logical_link_complete(struct hci_chan *chan, u8 status)
{
struct l2cap_pinfo *pi;
struct sock *sk;
@@ -5385,11 +5385,14 @@
BT_DBG("sk %p", sk);
+ if (!sk)
+ return;
+
lock_sock(sk);
if (sk->sk_state != BT_CONNECTED && !l2cap_pi(sk)->amp_id) {
release_sock(sk);
- return 0;
+ return;
}
pi = l2cap_pi(sk);
@@ -5516,7 +5519,6 @@
}
release_sock(sk);
- return 0;
}
static void l2cap_logical_link_worker(struct work_struct *work)
diff --git a/sound/soc/codecs/wcd9304.c b/sound/soc/codecs/wcd9304.c
index 3229bce..1fe28a2 100644
--- a/sound/soc/codecs/wcd9304.c
+++ b/sound/soc/codecs/wcd9304.c
@@ -1474,6 +1474,8 @@
pr_err("%s %d\n", __func__, event);
switch (event) {
case SND_SOC_DAPM_POST_PMU:
+ snd_soc_update_bits(codec, SITAR_A_CDC_CLK_OTHR_RESET_CTL, 0x10,
+ 0x00);
snd_soc_update_bits(codec, SITAR_A_CDC_CLK_OTHR_CTL, 0x01,
0x01);
snd_soc_update_bits(codec, SITAR_A_CDC_CLSG_CTL, 0x08, 0x08);
@@ -1996,7 +1998,6 @@
snd_soc_update_bits(codec, SITAR_A_CLK_BUFF_EN1, 0x05, 0x05);
snd_soc_update_bits(codec, SITAR_A_CLK_BUFF_EN2, 0x02, 0x00);
snd_soc_update_bits(codec, SITAR_A_CLK_BUFF_EN2, 0x04, 0x04);
- snd_soc_update_bits(codec, SITAR_A_CDC_CLK_MCLK_CTL, 0x01, 0x01);
usleep_range(50, 50);
sitar->clock_active = true;
return 0;
@@ -2005,7 +2006,6 @@
{
struct sitar_priv *sitar = snd_soc_codec_get_drvdata(codec);
pr_err("%s\n", __func__);
- snd_soc_update_bits(codec, SITAR_A_CDC_CLK_MCLK_CTL, 0x01, 0x00);
snd_soc_update_bits(codec, SITAR_A_CLK_BUFF_EN2, 0x04, 0x00);
ndelay(160);
snd_soc_update_bits(codec, SITAR_A_CLK_BUFF_EN2, 0x02, 0x02);
@@ -3962,6 +3962,9 @@
/*enable HPF filter for TX paths */
{SITAR_A_CDC_TX1_MUX_CTL, 0x8, 0x0},
{SITAR_A_CDC_TX2_MUX_CTL, 0x8, 0x0},
+
+ /*enable External clock select*/
+ {SITAR_A_CDC_CLK_MCLK_CTL, 0x01, 0x01},
};
static void sitar_codec_init_reg(struct snd_soc_codec *codec)
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index 4c9cef9..3f86962 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -293,6 +293,28 @@
.ops = &msm_fe_dai_ops,
.name = "VOICE_STUB",
},
+ {
+ .playback = {
+ .stream_name = "VoLTE Playback",
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 1,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .capture = {
+ .stream_name = "VoLTE Capture",
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 1,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &msm_fe_dai_ops,
+ .name = "VoLTE",
+ },
};
static __devinit int msm_fe_dai_dev_probe(struct platform_device *pdev)
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 18f95f6..0f74afb 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -441,6 +441,8 @@
if (val == MSM_FRONTEND_DAI_CS_VOICE)
session_id = voc_get_session_id(VOICE_SESSION_NAME);
+ else if (val == MSM_FRONTEND_DAI_VOLTE)
+ session_id = voc_get_session_id(VOLTE_SESSION_NAME);
else
session_id = voc_get_session_id(VOIP_SESSION_NAME);
@@ -1060,6 +1062,9 @@
SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_PRI_I2S_RX,
MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_PRI_I2S_RX,
+ MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
};
static const struct snd_kcontrol_new sec_i2s_rx_voice_mixer_controls[] = {
@@ -1069,6 +1074,9 @@
SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SEC_I2S_RX,
MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_SEC_I2S_RX,
+ MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
};
static const struct snd_kcontrol_new slimbus_rx_voice_mixer_controls[] = {
@@ -1078,6 +1086,9 @@
SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
+ MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
};
static const struct snd_kcontrol_new bt_sco_rx_voice_mixer_controls[] = {
@@ -1090,6 +1101,9 @@
SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_INT_BT_SCO_RX,
MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_INT_BT_SCO_RX ,
+ MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
};
static const struct snd_kcontrol_new afe_pcm_rx_voice_mixer_controls[] = {
@@ -1102,6 +1116,9 @@
SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_AFE_PCM_RX,
MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_AFE_PCM_RX,
+ MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
};
static const struct snd_kcontrol_new aux_pcm_rx_voice_mixer_controls[] = {
@@ -1114,6 +1131,9 @@
SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_AUXPCM_RX,
MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_AUXPCM_RX,
+ MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
};
static const struct snd_kcontrol_new hdmi_rx_voice_mixer_controls[] = {
@@ -1123,6 +1143,9 @@
SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_HDMI_RX,
MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_HDMI_RX,
+ MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
};
static const struct snd_kcontrol_new stub_rx_mixer_controls[] = {
@@ -1155,6 +1178,24 @@
msm_routing_put_voice_mixer),
};
+static const struct snd_kcontrol_new tx_volte_mixer_controls[] = {
+ SOC_SINGLE_EXT("PRI_TX_VoLTE", MSM_BACKEND_DAI_PRI_I2S_TX,
+ MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("SLIM_0_TX_VoLTE", MSM_BACKEND_DAI_SLIMBUS_0_TX,
+ MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_VoLTE",
+ MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_VOLTE, 1, 0,
+ msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("AFE_PCM_TX_VoLTE", MSM_BACKEND_DAI_AFE_PCM_TX,
+ MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("AUX_PCM_TX_VoLTE", MSM_BACKEND_DAI_AUXPCM_TX,
+ MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
+};
+
static const struct snd_kcontrol_new tx_voip_mixer_controls[] = {
SOC_SINGLE_EXT("PRI_TX_Voip", MSM_BACKEND_DAI_PRI_I2S_TX,
MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
@@ -1446,6 +1487,8 @@
SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("CS-VOICE_DL1", "CS-VOICE Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("CS-VOICE_UL1", "CS-VOICE Capture", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("VoLTE_DL", "VoLTE Playback", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("VoLTE_UL", "VoLTE Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("VOIP_UL", "VoIP Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("SLIM0_DL_HL", "SLIMBUS0_HOSTLESS Playback",
0, 0, 0, 0),
@@ -1568,6 +1611,9 @@
SND_SOC_DAPM_MIXER("Voip_Tx Mixer",
SND_SOC_NOPM, 0, 0, tx_voip_mixer_controls,
ARRAY_SIZE(tx_voip_mixer_controls)),
+ SND_SOC_DAPM_MIXER("VoLTE_Tx Mixer",
+ SND_SOC_NOPM, 0, 0, tx_volte_mixer_controls,
+ ARRAY_SIZE(tx_volte_mixer_controls)),
SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
int_bt_sco_rx_mixer_controls, ARRAY_SIZE(int_bt_sco_rx_mixer_controls)),
SND_SOC_DAPM_MIXER("INTERNAL_FM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
@@ -1676,30 +1722,37 @@
{"AUX_PCM_RX", NULL, "AUX_PCM_RX Audio Mixer"},
{"PRI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
+ {"PRI_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
{"PRI_RX_Voice Mixer", "Voip", "VOIP_DL"},
{"PRI_I2S_RX", NULL, "PRI_RX_Voice Mixer"},
{"SEC_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
+ {"SEC_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
{"SEC_RX_Voice Mixer", "Voip", "VOIP_DL"},
{"SEC_I2S_RX", NULL, "SEC_RX_Voice Mixer"},
{"SLIM_0_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
+ {"SLIM_0_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
{"SLIM_0_RX_Voice Mixer", "Voip", "VOIP_DL"},
{"SLIMBUS_0_RX", NULL, "SLIM_0_RX_Voice Mixer"},
{"INTERNAL_BT_SCO_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
+ {"INTERNAL_BT_SCO_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
{"INTERNAL_BT_SCO_RX_Voice Mixer", "Voip", "VOIP_DL"},
{"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX_Voice Mixer"},
{"AFE_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
+ {"AFE_PCM_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
{"AFE_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"},
{"PCM_RX", NULL, "AFE_PCM_RX_Voice Mixer"},
{"AUX_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
+ {"AUX_PCM_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
{"AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"},
{"AUX_PCM_RX", NULL, "AUX_PCM_RX_Voice Mixer"},
{"HDMI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
+ {"HDMI_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
{"HDMI_RX_Voice Mixer", "Voip", "VOIP_DL"},
{"HDMI", NULL, "HDMI_RX_Voice Mixer"},
{"HDMI", NULL, "HDMI_DL_HL"},
@@ -1710,6 +1763,12 @@
{"Voice_Tx Mixer", "AFE_PCM_TX_Voice", "PCM_TX"},
{"Voice_Tx Mixer", "AUX_PCM_TX_Voice", "AUX_PCM_TX"},
{"CS-VOICE_UL1", NULL, "Voice_Tx Mixer"},
+ {"VoLTE_Tx Mixer", "PRI_TX_VoLTE", "PRI_I2S_TX"},
+ {"VoLTE_Tx Mixer", "SLIM_0_TX_VoLTE", "SLIMBUS_0_TX"},
+ {"VoLTE_Tx Mixer", "INTERNAL_BT_SCO_TX_VoLTE", "INT_BT_SCO_TX"},
+ {"VoLTE_Tx Mixer", "AFE_PCM_TX_VoLTE", "PCM_TX"},
+ {"VoLTE_Tx Mixer", "AUX_PCM_TX_VoLTE", "AUX_PCM_TX"},
+ {"VoLTE_UL", NULL, "VoLTE_Tx Mixer"},
{"Voip_Tx Mixer", "PRI_TX_Voip", "PRI_I2S_TX"},
{"Voip_Tx Mixer", "SLIM_0_TX_Voip", "SLIMBUS_0_TX"},
{"Voip_Tx Mixer", "INTERNAL_BT_SCO_TX_Voip", "INT_BT_SCO_TX"},
diff --git a/sound/soc/msm/msm-pcm-routing.h b/sound/soc/msm/msm-pcm-routing.h
index b254381..e5d8638 100644
--- a/sound/soc/msm/msm-pcm-routing.h
+++ b/sound/soc/msm/msm-pcm-routing.h
@@ -56,6 +56,7 @@
MSM_FRONTEND_DAI_AFE_RX,
MSM_FRONTEND_DAI_AFE_TX,
MSM_FRONTEND_DAI_VOICE_STUB,
+ MSM_FRONTEND_DAI_VOLTE,
MSM_FRONTEND_DAI_MAX,
};
diff --git a/sound/soc/msm/msm-pcm-voice.c b/sound/soc/msm/msm-pcm-voice.c
index 5a0f27a..59b8bbd 100644
--- a/sound/soc/msm/msm-pcm-voice.c
+++ b/sound/soc/msm/msm-pcm-voice.c
@@ -29,7 +29,7 @@
#include "msm-pcm-voice.h"
#include "qdsp6/q6voice.h"
-static struct msm_voice voice_info;
+static struct msm_voice voice_info[VOICE_SESSION_INDEX_MAX];
static struct snd_pcm_hardware msm_pcm_hardware = {
@@ -49,6 +49,13 @@
.fifo_size = 0,
};
+static int is_volte(struct msm_voice *pvolte)
+{
+ if (pvolte == &voice_info[VOLTE_SESSION_INDEX])
+ return true;
+ else
+ return false;
+}
static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream)
{
@@ -78,8 +85,17 @@
static int msm_pcm_open(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct msm_voice *voice = &voice_info;
+ struct msm_voice *voice;
+ if (!strncmp("VoLTE", substream->pcm->id, 5)) {
+ voice = &voice_info[VOLTE_SESSION_INDEX];
+ pr_debug("%s: Open VoLTE Substream Id=%s\n",
+ __func__, substream->pcm->id);
+ } else {
+ voice = &voice_info[VOICE_SESSION_INDEX];
+ pr_debug("%s: Open VOICE Substream Id=%s\n",
+ __func__, substream->pcm->id);
+ }
mutex_lock(&voice->lock);
runtime->hw = msm_pcm_hardware;
@@ -90,7 +106,8 @@
voice->capture_substream = substream;
voice->instance++;
- pr_debug(" %s: instance: %d\n", __func__ , voice->instance);
+ pr_debug("%s: Instance = %d, Stream ID = %s\n",
+ __func__ , voice->instance, substream->pcm->id);
runtime->private_data = voice;
mutex_unlock(&voice->lock);
@@ -129,6 +146,7 @@
struct snd_pcm_runtime *runtime = substream->runtime;
struct msm_voice *prtd = runtime->private_data;
+ uint16_t session_id = 0;
int ret = 0;
mutex_lock(&prtd->lock);
@@ -140,7 +158,11 @@
prtd->instance--;
if (!prtd->playback_start && !prtd->capture_start) {
pr_debug("end voice call\n");
- voc_end_voice_call(voc_get_session_id(VOICE_SESSION_NAME));
+ if (is_volte(prtd))
+ session_id = voc_get_session_id(VOLTE_SESSION_NAME);
+ else
+ session_id = voc_get_session_id(VOICE_SESSION_NAME);
+ voc_end_voice_call(session_id);
}
mutex_unlock(&prtd->lock);
@@ -151,6 +173,7 @@
int ret = 0;
struct snd_pcm_runtime *runtime = substream->runtime;
struct msm_voice *prtd = runtime->private_data;
+ uint16_t session_id = 0;
mutex_lock(&prtd->lock);
@@ -159,9 +182,13 @@
else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
ret = msm_pcm_capture_prepare(substream);
- if (prtd->playback_start && prtd->capture_start)
- voc_start_voice_call(voc_get_session_id(VOICE_SESSION_NAME));
-
+ if (prtd->playback_start && prtd->capture_start) {
+ if (is_volte(prtd))
+ session_id = voc_get_session_id(VOLTE_SESSION_NAME);
+ else
+ session_id = voc_get_session_id(VOICE_SESSION_NAME);
+ voc_start_voice_call(session_id);
+ }
mutex_unlock(&prtd->lock);
return ret;
@@ -189,12 +216,26 @@
struct snd_ctl_elem_value *ucontrol)
{
int volume = ucontrol->value.integer.value[0];
-
pr_debug("%s: volume: %d\n", __func__, volume);
-
voc_set_rx_vol_index(voc_get_session_id(VOICE_SESSION_NAME),
- RX_PATH,
- volume);
+ RX_PATH, volume);
+ return 0;
+}
+
+static int msm_volte_volume_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = 0;
+ return 0;
+}
+
+static int msm_volte_volume_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int volume = ucontrol->value.integer.value[0];
+ pr_debug("%s: volume: %d\n", __func__, volume);
+ voc_set_rx_vol_index(voc_get_session_id(VOLTE_SESSION_NAME),
+ RX_PATH, volume);
return 0;
}
@@ -217,6 +258,25 @@
return 0;
}
+static int msm_volte_mute_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = 0;
+ return 0;
+}
+
+static int msm_volte_mute_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int mute = ucontrol->value.integer.value[0];
+
+ pr_debug("%s: mute=%d\n", __func__, mute);
+
+ voc_set_tx_mute(voc_get_session_id(VOLTE_SESSION_NAME), TX_PATH, mute);
+
+ return 0;
+}
+
static int msm_voice_rx_device_mute_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -237,6 +297,26 @@
return 0;
}
+static int msm_volte_rx_device_mute_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] =
+ voc_get_rx_device_mute(voc_get_session_id(VOLTE_SESSION_NAME));
+ return 0;
+}
+
+static int msm_volte_rx_device_mute_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int mute = ucontrol->value.integer.value[0];
+
+ pr_debug("%s: mute=%d\n", __func__, mute);
+
+ voc_set_rx_device_mute(voc_get_session_id(VOLTE_SESSION_NAME), mute);
+
+ return 0;
+}
+
static const char const *tty_mode[] = {"OFF", "HCO", "VCO", "FULL"};
static const struct soc_enum msm_tty_mode_enum[] = {
SOC_ENUM_SINGLE_EXT(4, tty_mode),
@@ -343,6 +423,13 @@
msm_voice_slowtalk_get, msm_voice_slowtalk_put),
SOC_SINGLE_EXT("FENS Enable", SND_SOC_NOPM, 0, 1, 0,
msm_voice_fens_get, msm_voice_fens_put),
+ SOC_SINGLE_EXT("VoLTE Rx Device Mute", SND_SOC_NOPM, 0, 1, 0,
+ msm_volte_rx_device_mute_get,
+ msm_volte_rx_device_mute_put),
+ SOC_SINGLE_EXT("VoLTE Tx Mute", SND_SOC_NOPM, 0, 1, 0,
+ msm_volte_mute_get, msm_volte_mute_put),
+ SOC_SINGLE_EXT("VoLTE Rx Volume", SND_SOC_NOPM, 0, 5, 0,
+ msm_volte_volume_get, msm_volte_volume_put),
};
static struct snd_pcm_ops msm_pcm_ops = {
@@ -402,7 +489,8 @@
static int __init msm_soc_platform_init(void)
{
memset(&voice_info, 0, sizeof(voice_info));
- mutex_init(&voice_info.lock);
+ mutex_init(&voice_info[VOICE_SESSION_INDEX].lock);
+ mutex_init(&voice_info[VOLTE_SESSION_INDEX].lock);
return platform_driver_register(&msm_pcm_driver);
}
diff --git a/sound/soc/msm/msm-pcm-voice.h b/sound/soc/msm/msm-pcm-voice.h
index 71bdbc1..aa00577 100644
--- a/sound/soc/msm/msm-pcm-voice.h
+++ b/sound/soc/msm/msm-pcm-voice.h
@@ -13,6 +13,11 @@
#define _MSM_PCM_VOICE_H
#include <sound/apr_audio.h>
+enum {
+ VOICE_SESSION_INDEX,
+ VOLTE_SESSION_INDEX,
+ VOICE_SESSION_INDEX_MAX,
+};
struct msm_voice {
struct snd_pcm_substream *playback_substream;
diff --git a/sound/soc/msm/msm-pcm-voip.c b/sound/soc/msm/msm-pcm-voip.c
index aec1bb2..2301472 100644
--- a/sound/soc/msm/msm-pcm-voip.c
+++ b/sound/soc/msm/msm-pcm-voip.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, Code Aurora Forum. 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
@@ -691,7 +691,7 @@
int ret = 0;
struct snd_pcm_runtime *runtime = substream->runtime;
struct voip_drv_info *prtd = runtime->private_data;
- int32_t media_type = 0;
+ uint32_t media_type = 0;
uint32_t rate_type = 0;
mutex_lock(&prtd->lock);
@@ -988,7 +988,7 @@
static int voip_get_media_type(uint32_t mode,
unsigned int samp_rate)
{
- int32_t media_type;
+ uint32_t media_type;
pr_debug("%s: mode=%d, samp_rate=%d\n", __func__,
mode, samp_rate);
diff --git a/sound/soc/msm/msm8930.c b/sound/soc/msm/msm8930.c
index 9dad1bb..04b0fb0 100644
--- a/sound/soc/msm/msm8930.c
+++ b/sound/soc/msm/msm8930.c
@@ -129,8 +129,8 @@
if (!clk_users) {
pr_debug("%s: disabling MCLK. clk_users = %d\n",
__func__, clk_users);
- clk_disable_unprepare(codec_clk);
sitar_mclk_enable(codec, 0);
+ clk_disable_unprepare(codec_clk);
}
}
return 0;
diff --git a/sound/soc/msm/qdsp6/q6adm.c b/sound/soc/msm/qdsp6/q6adm.c
index 3745b17..676ecf1 100644
--- a/sound/soc/msm/qdsp6/q6adm.c
+++ b/sound/soc/msm/qdsp6/q6adm.c
@@ -143,14 +143,14 @@
s32 result = 0;
struct adm_set_params_command adm_params;
int index = afe_get_port_index(port_id);
-
- pr_debug("%s: Port id %d, index %d\n", __func__, port_id, index);
-
if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: invalid port idx %d portid %d\n",
__func__, index, port_id);
- goto done;
+ return 0;
}
+
+ pr_debug("%s: Port id %d, index %d\n", __func__, port_id, index);
+
if (!aud_cal || aud_cal->cal_size == 0) {
pr_debug("%s: No ADM cal to send for port_id = %d!\n",
__func__, port_id);
@@ -580,16 +580,15 @@
int ret = 0, i = 0;
/* Assumes port_ids have already been validated during adm_open */
int index = afe_get_port_index(copp_id);
+ if (index < 0 || index >= AFE_MAX_PORTS) {
+ pr_err("%s: invalid port idx %d token %d\n",
+ __func__, index, copp_id);
+ return 0;
+ }
pr_debug("%s: session 0x%x path:%d num_copps:%d port_id[0]:%d\n",
__func__, session_id, path, num_copps, port_id[0]);
- if (index < 0 || index >= AFE_MAX_PORTS) {
- pr_err("%s: invalid port idx %d token %d\n",
- __func__, index, copp_id);
- ret = -EINVAL;
- goto fail_cmd;
- }
route.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
route.hdr.pkt_size = sizeof(route);
@@ -614,7 +613,7 @@
pr_debug("%s: port_id[%d]: %d, index: %d\n", __func__, i,
port_id[i], tmp);
- if ((tmp >= 0) && (tmp < AFE_MAX_PORTS))
+ if (tmp >= 0 && tmp < AFE_MAX_PORTS)
route.session[0].copp_id[i] =
atomic_read(&this_adm.copp_id[tmp]);
}
diff --git a/sound/soc/msm/qdsp6/q6voice.c b/sound/soc/msm/qdsp6/q6voice.c
index 6050929..f4b4dd1 100644
--- a/sound/soc/msm/qdsp6/q6voice.c
+++ b/sound/soc/msm/qdsp6/q6voice.c
@@ -33,6 +33,7 @@
#define VOC_PATH_PASSIVE 0
#define VOC_PATH_FULL 1
+#define VOC_PATH_VOLTE_PASSIVE 2
/* CVP CAL Size: 245760 = 240 * 1024 */
#define CVP_CAL_SIZE 245760
@@ -145,6 +146,9 @@
if (name != NULL) {
if (!strncmp(name, "Voice session", 13))
session_id = common.voice[VOC_PATH_PASSIVE].session_id;
+ else if (!strncmp(name, "VoLTE session", 13))
+ session_id =
+ common.voice[VOC_PATH_VOLTE_PASSIVE].session_id;
else
session_id = common.voice[VOC_PATH_FULL].session_id;
@@ -180,6 +184,11 @@
return (session_id == common.voice[VOC_PATH_FULL].session_id);
}
+static bool is_volte_session(u16 session_id)
+{
+ return (session_id == common.voice[VOC_PATH_VOLTE_PASSIVE].session_id);
+}
+
static int voice_apr_register(void)
{
pr_debug("%s\n", __func__);
@@ -250,6 +259,65 @@
return -ENODEV;
}
+static int voice_send_dual_control_cmd(struct voice_data *v)
+{
+ int ret = 0;
+ struct mvm_modem_dual_control_session_cmd mvm_voice_ctl_cmd;
+ void *apr_mvm;
+ u16 mvm_handle;
+
+ if (v == NULL) {
+ pr_err("%s: v is NULL\n", __func__);
+ return -EINVAL;
+ }
+ apr_mvm = common.apr_q6_mvm;
+ if (!apr_mvm) {
+ pr_err("%s: apr_mvm is NULL.\n", __func__);
+ return -EINVAL;
+ }
+ pr_debug("%s: VoLTE command to MVM\n", __func__);
+ if (is_volte_session(v->session_id)) {
+ mvm_handle = voice_get_mvm_handle(v);
+ mvm_voice_ctl_cmd.hdr.hdr_field = APR_HDR_FIELD(
+ APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE),
+ APR_PKT_VER);
+ mvm_voice_ctl_cmd.hdr.pkt_size = APR_PKT_SIZE(
+ APR_HDR_SIZE,
+ sizeof(mvm_voice_ctl_cmd) -
+ APR_HDR_SIZE);
+ pr_debug("%s: send mvm Voice Ctl pkt size = %d\n",
+ __func__, mvm_voice_ctl_cmd.hdr.pkt_size);
+ mvm_voice_ctl_cmd.hdr.src_port = v->session_id;
+ mvm_voice_ctl_cmd.hdr.dest_port = mvm_handle;
+ mvm_voice_ctl_cmd.hdr.token = 0;
+ mvm_voice_ctl_cmd.hdr.opcode =
+ VSS_IMVM_CMD_SET_POLICY_DUAL_CONTROL;
+ mvm_voice_ctl_cmd.voice_ctl.enable_flag = true;
+ v->mvm_state = CMD_STATUS_FAIL;
+
+ ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_voice_ctl_cmd);
+ if (ret < 0) {
+ pr_err("%s: Error sending MVM Voice CTL CMD\n",
+ __func__);
+ ret = -EINVAL;
+ goto fail;
+ }
+ ret = wait_event_timeout(v->mvm_wait,
+ (v->mvm_state == CMD_STATUS_SUCCESS),
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret) {
+ pr_err("%s: wait_event timeout\n", __func__);
+ ret = -EINVAL;
+ goto fail;
+ }
+ }
+ ret = 0;
+fail:
+ return ret;
+}
+
+
static int voice_create_mvm_cvs_session(struct voice_data *v)
{
int ret = 0;
@@ -281,7 +349,8 @@
/* send cmd to create mvm session and wait for response */
if (!mvm_handle) {
- if (is_voice_session(v->session_id)) {
+ if (is_voice_session(v->session_id) ||
+ is_volte_session(v->session_id)) {
mvm_session_cmd.hdr.hdr_field = APR_HDR_FIELD(
APR_MSG_TYPE_SEQ_CMD,
APR_HDR_LEN(APR_HDR_SIZE),
@@ -297,9 +366,15 @@
mvm_session_cmd.hdr.token = 0;
mvm_session_cmd.hdr.opcode =
VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION;
+ if (is_volte_session(v->session_id)) {
+ strlcpy(mvm_session_cmd.mvm_session.name,
+ "default volte voice",
+ sizeof(mvm_session_cmd.mvm_session.name));
+ } else {
strlcpy(mvm_session_cmd.mvm_session.name,
"default modem voice",
sizeof(mvm_session_cmd.mvm_session.name));
+ }
v->mvm_state = CMD_STATUS_FAIL;
@@ -356,7 +431,8 @@
}
/* send cmd to create cvs session */
if (!cvs_handle) {
- if (is_voice_session(v->session_id)) {
+ if (is_voice_session(v->session_id) ||
+ is_volte_session(v->session_id)) {
pr_debug("%s: creating CVS passive session\n",
__func__);
@@ -373,10 +449,15 @@
cvs_session_cmd.hdr.token = 0;
cvs_session_cmd.hdr.opcode =
VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION;
+ if (is_volte_session(v->session_id)) {
+ strlcpy(mvm_session_cmd.mvm_session.name,
+ "default volte voice",
+ sizeof(mvm_session_cmd.mvm_session.name));
+ } else {
strlcpy(cvs_session_cmd.cvs_session.name,
"default modem voice",
sizeof(cvs_session_cmd.cvs_session.name));
-
+ }
v->cvs_state = CMD_STATUS_FAIL;
ret = apr_send_pkt(apr_cvs,
@@ -3350,6 +3431,11 @@
pr_err("create mvm and cvs failed\n");
goto fail;
}
+ ret = voice_send_dual_control_cmd(v);
+ if (ret < 0) {
+ pr_err("Err Dual command failed\n");
+ goto fail;
+ }
ret = voice_setup_vocproc(v);
if (ret < 0) {
pr_err("setup voice failed\n");
@@ -3373,7 +3459,6 @@
v->voc_state = VOC_RUN;
}
-
fail: mutex_unlock(&v->lock);
return ret;
}
@@ -3471,6 +3556,7 @@
case VSS_ICOMMON_CMD_SET_NETWORK:
case VSS_ICOMMON_CMD_SET_VOICE_TIMING:
case VSS_IWIDEVOICE_CMD_SET_WIDEVOICE:
+ case VSS_IMVM_CMD_SET_POLICY_DUAL_CONTROL:
pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
v->mvm_state = CMD_STATUS_SUCCESS;
wake_up(&v->mvm_wait);
diff --git a/sound/soc/msm/qdsp6/q6voice.h b/sound/soc/msm/qdsp6/q6voice.h
index 0fc7a01..3310abd 100644
--- a/sound/soc/msm/qdsp6/q6voice.h
+++ b/sound/soc/msm/qdsp6/q6voice.h
@@ -107,6 +107,15 @@
#define VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION 0x000110FF
/**< No payload. Wait for APRV2_IBASIC_RSP_RESULT response. */
+#define VSS_IMVM_CMD_SET_POLICY_DUAL_CONTROL 0x00011327
+/*
+ * VSS_IMVM_CMD_SET_POLICY_DUAL_CONTROL
+ * Description: This command is required to let MVM know
+ * who is in control of session.
+ * Payload: Defined by vss_imvm_cmd_set_policy_dual_control_t.
+ * Result: Wait for APRV2_IBASIC_RSP_RESULT response.
+ */
+
#define VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION 0x000110FE
/* Create a new full control MVM session. */
@@ -228,6 +237,12 @@
*/
} __packed;
+
+struct vss_imvm_cmd_set_policy_dual_control_t {
+ bool enable_flag;
+ /* Set to TRUE to enable modem state machine control */
+} __packed;
+
struct vss_iwidevoice_cmd_set_widevoice_t {
uint32_t enable;
/* WideVoice enable/disable; possible values:
@@ -251,6 +266,11 @@
struct vss_imvm_cmd_create_control_session_t mvm_session;
} __packed;
+struct mvm_modem_dual_control_session_cmd {
+ struct apr_hdr hdr;
+ struct vss_imvm_cmd_set_policy_dual_control_t voice_ctl;
+} __packed;
+
struct mvm_set_tty_mode_cmd {
struct apr_hdr hdr;
struct vss_istream_cmd_set_tty_mode_t tty_mode;
@@ -878,7 +898,7 @@
void *buf;
};
-#define MAX_VOC_SESSIONS 2
+#define MAX_VOC_SESSIONS 3
#define SESSION_ID_BASE 0xFFF0
struct common_data {
@@ -947,6 +967,7 @@
#define VOICE_SESSION_NAME "Voice session"
#define VOIP_SESSION_NAME "VoIP session"
+#define VOLTE_SESSION_NAME "VoLTE session"
uint16_t voc_get_session_id(char *name);
int voc_start_playback(uint32_t set);