summaryrefslogtreecommitdiff
path: root/sound/soc
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/codecs/Kconfig6
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/tfa9890.c476
-rw-r--r--sound/soc/codecs/tfa9890.h63
-rw-r--r--sound/soc/codecs/wcd-mbhc-v2.c20
-rw-r--r--sound/soc/codecs/wcd-mbhc-v2.h2
-rw-r--r--sound/soc/codecs/wcd9335.c7
-rw-r--r--sound/soc/msm/Kconfig5
-rw-r--r--sound/soc/msm/msm8996.c227
-rw-r--r--sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c87
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c6
-rw-r--r--sound/soc/msm/qdsp6v2/q6asm.c23
-rw-r--r--sound/soc/msm/qdsp6v2/q6core.c8
-rw-r--r--sound/soc/msm/qdsp6v2/q6lsm.c3
14 files changed, 901 insertions, 34 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 8f3e787501f1..edd84f0f9db3 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -994,6 +994,12 @@ config SND_SOC_MSM_HDMI_CODEC_RX
HDMI audio drivers should be built only if the platform
supports hdmi panel.
+config NXP_TFA98xx
+ depends on I2C
+ tristate "NXP TFA98xx Support"
+ ---help---
+ The NXP TFA98xx chip is used as a smart PA Controller.
+
source "sound/soc/codecs/sdm660_cdc/Kconfig"
source "sound/soc/codecs/msm_sdw/Kconfig"
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 5305cc6071e8..24d9c3b4106b 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -214,6 +214,7 @@ obj-$(CONFIG_SND_SOC_MSM_HDMI_CODEC_RX) := msm_hdmi_codec_rx.o
snd-soc-max9877-objs := max9877.o
snd-soc-tpa6130a2-objs := tpa6130a2.o
snd-soc-tas2552-objs := tas2552.o
+snd-soc-tfa98xx-objs := tfa9890.o
obj-$(CONFIG_SND_SOC_88PM860X) += snd-soc-88pm860x.o
obj-$(CONFIG_SND_SOC_AB8500_CODEC) += snd-soc-ab8500-codec.o
@@ -425,5 +426,6 @@ obj-$(CONFIG_SND_SOC_MSM_STUB) += snd-soc-msm-stub.o
# Amp
obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
+obj-$(CONFIG_NXP_TFA98xx) += snd-soc-tfa98xx.o
obj-y += sdm660_cdc/
obj-y += msm_sdw/
diff --git a/sound/soc/codecs/tfa9890.c b/sound/soc/codecs/tfa9890.c
new file mode 100644
index 000000000000..d5aa6975c453
--- /dev/null
+++ b/sound/soc/codecs/tfa9890.c
@@ -0,0 +1,476 @@
+/*
+ * Synaptics DSX touchscreen driver
+ *
+ * Copyright (C) 2012 Synaptics Incorporated
+ *
+ * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
+ * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <asm/uaccess.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/i2c-dev.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/miscdevice.h>
+#include <linux/regulator/consumer.h>
+#include <linux/of_gpio.h>
+#include "tfa9890.h"
+#ifdef KERNEL_ABOVE_2_6_38
+#include <linux/input/mt.h>
+#endif
+
+#define DRIVER_NAME "tfa9890"
+#define MAX_BUFFER_SIZE 512
+#define GPIO_SLEEP_LOW_US 10
+#define RESET_DELAY 500
+
+struct tfa9890_dev {
+ wait_queue_head_t read_wq;
+ struct mutex read_mutex;
+ struct device *dev;
+ struct i2c_client *i2c_client;
+ struct miscdevice tfa9890_device;
+ unsigned int ven_gpio;
+ unsigned int firm_gpio;
+ unsigned int irq_gpio;
+ unsigned int irq_flags;
+ unsigned int irq;
+ unsigned int reset_gpio;
+ unsigned int reset_flags;
+ bool i2c_pull_up;
+ struct regulator *vdd;
+ struct regulator *vcc_i2c;
+ bool do_reading;
+ bool irq_enabled;
+ bool cancel_read;
+ bool first_open;
+};
+
+static ssize_t tfa9890_dev_read(struct file *filp, char __user *buf,
+ size_t count, loff_t *offset)
+{
+ struct tfa9890_dev *tfa9890_dev = filp->private_data;
+ char tmp[MAX_BUFFER_SIZE];
+ int ret;
+
+ if (count > MAX_BUFFER_SIZE)
+ count = MAX_BUFFER_SIZE;
+
+
+ mutex_lock(&tfa9890_dev->read_mutex);
+
+ /* Read data */
+ ret = i2c_master_recv(tfa9890_dev->i2c_client, tmp, count);
+
+ if (ret < 0) {
+ pr_err("%s: i2c_master_recv returned %d\n", __func__, ret);
+ mutex_unlock(&tfa9890_dev->read_mutex);
+ return ret;
+ }
+ if (ret > count) {
+ pr_err("%s: received too many bytes from i2c (%d)\n",
+ __func__, ret);
+ mutex_unlock(&tfa9890_dev->read_mutex);
+ return -EIO;
+ }
+
+ if (copy_to_user(buf, tmp, ret)) {
+ pr_warning("%s : failed to copy to user space\n", __func__);
+ mutex_unlock(&tfa9890_dev->read_mutex);
+ return -EFAULT;
+ }
+ mutex_unlock(&tfa9890_dev->read_mutex);
+ return ret;
+
+}
+
+static ssize_t tfa9890_dev_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *offset)
+{
+ struct tfa9890_dev *tfa9890_dev = filp->private_data;
+ char tmp[MAX_BUFFER_SIZE];
+ int ret;
+
+ if (count > MAX_BUFFER_SIZE)
+ count = MAX_BUFFER_SIZE;
+
+ if (copy_from_user(tmp, buf, count)) {
+ pr_err("%s : failed to copy from user space\n", __func__);
+ return -EFAULT;
+ }
+
+ /* Write data */
+ ret = i2c_master_send(tfa9890_dev->i2c_client, tmp, count);
+ if (ret != count) {
+ pr_err("%s : i2c_master_send returned %d\n", __func__, ret);
+ ret = -EIO;
+ }
+ return ret;
+}
+
+static int tfa9890_dev_open(struct inode *inode, struct file *filp)
+{
+ int ret;
+
+ struct tfa9890_dev *tfa9890_dev = container_of(filp->private_data,
+ struct tfa9890_dev,
+ tfa9890_device);
+
+ filp->private_data = tfa9890_dev;
+ pr_err("%s : %d,%d\n", __func__, imajor(inode), iminor(inode));
+
+ if (tfa9890_dev->first_open) {
+ if (gpio_is_valid(tfa9890_dev->reset_gpio)) {
+ /* configure tfa9890s reset out gpio */
+ ret = gpio_request(tfa9890_dev->reset_gpio,
+ "tfa9890_reset_gpio");
+ if (ret) {
+ dev_err(&tfa9890_dev->i2c_client->dev, "unable to request gpio [%d]\n",
+ tfa9890_dev->reset_gpio);
+ goto err_reset_gpio_dir;
+ }
+
+ ret = gpio_direction_output(tfa9890_dev->reset_gpio, 1);
+ if (ret) {
+ dev_err(&tfa9890_dev->i2c_client->dev,
+ "unable to set direction for gpio [%d]\n",
+ tfa9890_dev->reset_gpio);
+ goto err_reset_gpio_dir;
+ }
+
+ gpio_set_value(tfa9890_dev->reset_gpio, 1);
+ mdelay(GPIO_SLEEP_LOW_US);
+ gpio_set_value(tfa9890_dev->reset_gpio, 0);
+ mdelay(RESET_DELAY);
+ }
+ tfa9890_dev->first_open = false;
+ printk("%s enter, reset PA at first open\n", __func__);
+ }
+
+ return 0;
+
+err_reset_gpio_dir:
+ if (gpio_is_valid(tfa9890_dev->reset_gpio))
+ gpio_free(tfa9890_dev->reset_gpio);
+
+ return ret;
+}
+
+static long tfa9890_dev_ioctl(struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ struct tfa9890_dev *tfa9890_dev = filp->private_data;
+ switch(cmd)
+ {
+ case I2C_SLAVE:
+ {
+ tfa9890_dev->i2c_client->addr = arg;
+ break;
+ }
+ case ENABLE_MI2S_CLK:
+ {
+ udelay(500);
+ msm_q6_enable_mi2s_clocks(arg);
+ //printk("[%s][%d]\n",__func__,__LINE__);
+ break;
+ }
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static const struct file_operations tfa9890_dev_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .read = tfa9890_dev_read,
+ .write = tfa9890_dev_write,
+ .open = tfa9890_dev_open,
+ .unlocked_ioctl = tfa9890_dev_ioctl,
+};
+
+static int tfa9890_parse_dt(struct device *dev,
+ struct tfa9890_i2c_platform_data *pdata)
+{
+ int ret = 0;
+ struct device_node *np = dev->of_node;
+
+ /* reset, irq gpio info */
+ pdata->reset_gpio = of_get_named_gpio_flags(np,
+ "reset-gpio", 0, &pdata->reset_flags);
+ pr_info("%s,pdata->reset_gpio = %d\n", __func__, pdata->reset_gpio);
+ pdata->irq_gpio = of_get_named_gpio_flags(np,
+ "irq-gpio", 0, &pdata->irq_flags);
+ pr_info("%s,pdata->irq_gpio = %d\n", __func__, pdata->irq_gpio);
+
+ pdata->i2c_pull_up = of_property_read_bool(np,
+ "tfa9890,i2c-pull-up");
+ pr_info("%s,pdata->i2c_pull_up = %d\n", __func__, pdata->i2c_pull_up);
+ return ret;
+}
+
+ /**
+ * nxp_tfa9890_probe()
+ *
+ * Called by the kernel when an association with an I2C device of the
+ * same name is made (after doing i2c_add_driver).
+ *
+ * This funtion allocates and initializes the resources for the driver
+ * as an input driver, turns on the power to the sensor, queries the
+ * sensor for its supported Functions and characteristics, registers
+ * the driver to the input subsystem, sets up the interrupt, handles
+ * the registration of the early_suspend and late_resume functions,
+ * and creates a work queue for detection of other expansion Function
+ * modules.
+ */
+static int nxp_tfa9890_probe(struct i2c_client *client,
+ const struct i2c_device_id *dev_id)
+{
+ int ret = 0;
+ struct tfa9890_i2c_platform_data *platform_data;
+ struct tfa9890_dev *tfa9890_dev;
+
+ printk("%s\n", __func__);
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ pr_err("%s: i2c check failed\n", __func__);
+ ret = -ENODEV;
+ goto err_i2c;
+ }
+
+ if (client->dev.of_node) {
+ platform_data = devm_kzalloc(&client->dev,
+ sizeof(*platform_data),
+ GFP_KERNEL);
+ if (!platform_data) {
+ dev_err(&client->dev, "Failed to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ ret = tfa9890_parse_dt(&client->dev, platform_data);
+ if (ret)
+ return ret;
+ } else {
+ platform_data = client->dev.platform_data;
+ }
+
+
+ tfa9890_dev = kzalloc(sizeof(*tfa9890_dev), GFP_KERNEL);
+ if (tfa9890_dev == NULL) {
+ pr_err("failed to allocate memory for module data\n");
+ ret = -ENOMEM;
+ goto err_exit;
+ }
+
+ tfa9890_dev->i2c_client = client;
+ tfa9890_dev->dev = &client->dev;
+ tfa9890_dev->do_reading = 0;
+
+ /* Initialise mutex and work queue */
+ init_waitqueue_head(&tfa9890_dev->read_wq);
+ mutex_init(&tfa9890_dev->read_mutex);
+
+ tfa9890_dev->irq_enabled = false;
+ tfa9890_dev->tfa9890_device.minor = MISC_DYNAMIC_MINOR;
+ tfa9890_dev->tfa9890_device.name = "tfa9890";
+ tfa9890_dev->tfa9890_device.fops = &tfa9890_dev_fops;
+
+ if (gpio_is_valid(platform_data->reset_gpio)) {
+ /* configure tfa9890s reset out gpio */
+ ret = gpio_request(platform_data->reset_gpio,
+ "tfa9890_reset_gpio");
+ if (ret) {
+ dev_err(&client->dev, "unable to request gpio [%d]\n",
+ platform_data->reset_gpio);
+ goto err_reset_gpio_dir;
+ }
+
+ ret = gpio_direction_output(platform_data->reset_gpio, 1);
+ if (ret) {
+ dev_err(&client->dev,
+ "unable to set direction for gpio [%d]\n",
+ platform_data->reset_gpio);
+ goto err_reset_gpio_dir;
+ }
+
+ gpio_set_value(platform_data->reset_gpio, 1);
+ mdelay(GPIO_SLEEP_LOW_US);
+ gpio_set_value(platform_data->reset_gpio, 0);
+ mdelay(RESET_DELAY);
+ }
+
+ ret = misc_register(&tfa9890_dev->tfa9890_device);
+ if (ret) {
+ pr_err("%s : misc_register failed\n", __FILE__);
+ goto err_misc_register;
+ }
+
+ printk("%s Done\n", __func__);
+
+ return 0;
+
+err_misc_register:
+ misc_deregister(&tfa9890_dev->tfa9890_device);
+ mutex_destroy(&tfa9890_dev->read_mutex);
+ kfree(tfa9890_dev);
+
+#if 1
+err_reset_gpio_dir:
+ if (gpio_is_valid(platform_data->reset_gpio))
+ gpio_free(platform_data->reset_gpio);
+#endif
+
+err_exit:
+err_i2c:
+ kfree(platform_data);
+
+ return ret;
+}
+
+ /**
+ * nxp_tfa9890_remove()
+ *
+ * Called by the kernel when the association with an I2C device of the
+ * same name is broken (when the driver is unloaded).
+ *
+ * This funtion terminates the work queue, stops sensor data acquisition,
+ * frees the interrupt, unregisters the driver from the input subsystem,
+ * turns off the power to the sensor, and frees other allocated resources.
+ */
+static int nxp_tfa9890_remove(struct i2c_client *client)
+{
+ struct tfa9890_dev *tfa9890_dev;
+
+ pr_info("%s\n", __func__);
+ tfa9890_dev = i2c_get_clientdata(client);
+ misc_deregister(&tfa9890_dev->tfa9890_device);
+ mutex_destroy(&tfa9890_dev->read_mutex);
+
+ kfree(tfa9890_dev);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+ /**
+ * nxp_tfa9890_suspend()
+ *
+ * Called by the kernel during the suspend phase when the system
+ * enters suspend.
+ *
+ * This function stops finger data acquisition and puts the sensor to
+ * sleep (if not already done so during the early suspend phase),
+ * disables the interrupt, and turns off the power to the sensor.
+ */
+static int nxp_tfa9890_suspend(struct device *dev)
+{
+ pr_info(KERN_ALERT "----------------suspend");
+
+ return 0;
+}
+
+ /**
+ * nxp_tfa9890_resume()
+ *
+ * Called by the kernel during the resume phase when the system
+ * wakes up from suspend.
+ *
+ * This function turns on the power to the sensor, wakes the sensor
+ * from sleep, enables the interrupt, and starts finger data
+ * acquisition.
+ */
+static int nxp_tfa9890_resume(struct device *dev)
+{
+ return 0;
+}
+
+static const struct dev_pm_ops nxp_tfa9890_dev_pm_ops = {
+ .suspend = nxp_tfa9890_suspend,
+ .resume = nxp_tfa9890_resume,
+};
+#endif
+
+static const struct i2c_device_id nxp_tfa9890_id_table[] = {
+ {DRIVER_NAME, 0},
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, nxp_tfa9890_id_table);
+
+#ifdef CONFIG_OF
+static struct of_device_id tfa9890_match_table[] = {
+ { .compatible = "nxp,tfa9890",},
+ { },
+};
+#else
+#define tfa9890_match_table NULL
+#endif
+
+static struct i2c_driver nxp_tfa9890_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = tfa9890_match_table,
+#ifdef CONFIG_PM
+ .pm = &nxp_tfa9890_dev_pm_ops,
+#endif
+ },
+ .probe = nxp_tfa9890_probe,
+ .remove =nxp_tfa9890_remove,
+ .id_table = nxp_tfa9890_id_table,
+};
+
+ /**
+ * nxp_tfa9890_init()
+ *
+ * Called by the kernel during do_initcalls (if built-in)
+ * or when the driver is loaded (if a module).
+ *
+ * This function registers the driver to the I2C subsystem.
+ *
+ */
+static int __init nxp_tfa9890_init(void)
+{
+ printk("%s\n",__func__);
+ return i2c_add_driver(&nxp_tfa9890_driver);
+}
+
+ /**
+ * nxp_tfa9890_exit()
+ *
+ * Called by the kernel when the driver is unloaded.
+ *
+ * This funtion unregisters the driver from the I2C subsystem.
+ *
+ */
+static void __exit nxp_tfa9890_exit(void)
+{
+ i2c_del_driver(&nxp_tfa9890_driver);
+
+ return;
+}
+
+module_init(nxp_tfa9890_init);
+module_exit(nxp_tfa9890_exit);
+
+MODULE_AUTHOR("NXP, Inc.");
+MODULE_DESCRIPTION("NXP TFA9885 I2C Touch Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/tfa9890.h b/sound/soc/codecs/tfa9890.h
new file mode 100644
index 000000000000..14932a2e14e0
--- /dev/null
+++ b/sound/soc/codecs/tfa9890.h
@@ -0,0 +1,63 @@
+/*
+ * Synaptics DSX touchscreen driver
+ *
+ * Copyright (C) 2012 Synaptics Incorporated
+ *
+ * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
+ * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 _NXP_TFA9890_I2C_H_
+#define _NXP_TFA9890_I2C_H_
+
+#include <linux/version.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38))
+#define KERNEL_ABOVE_2_6_38
+#endif
+
+#ifdef KERNEL_ABOVE_2_6_38
+#define sstrtoul(...) kstrtoul(__VA_ARGS__)
+#else
+#define sstrtoul(...) strict_strtoul(__VA_ARGS__)
+#endif
+
+#define TFA9890_VTG_MIN_UV 1800000
+#define TFA9890_VTG_MAX_UV 1800000
+#define TFA9890_ACTIVE_LOAD_UA 10000 //15000
+#define TFA9890_LPM_LOAD_UA 10
+
+#define TFA9890_I2C_VTG_MIN_UV 1800000
+#define TFA9890_I2C_VTG_MAX_UV 1800000
+#define TFA9890_I2C_LOAD_UA 10000
+#define TFA9890_I2C_LPM_LOAD_UA 10
+
+extern int msm_q6_enable_mi2s_clocks(bool enable);
+
+struct tfa9890_i2c_platform_data {
+ struct i2c_client *i2c_client;
+ bool i2c_pull_up;
+ bool regulator_en;
+ u32 reset_flags;
+ u32 irq_flags;
+ unsigned int irq;
+ unsigned int reset_gpio_test;
+ unsigned int reset_gpio;
+ unsigned int irq_gpio;
+ int (*driver_opened)(void);
+ void (*driver_closed)(void);
+};
+
+#endif
diff --git a/sound/soc/codecs/wcd-mbhc-v2.c b/sound/soc/codecs/wcd-mbhc-v2.c
index 997a623033fb..04f1c7b1276c 100644
--- a/sound/soc/codecs/wcd-mbhc-v2.c
+++ b/sound/soc/codecs/wcd-mbhc-v2.c
@@ -45,7 +45,7 @@
#define MBHC_BUTTON_PRESS_THRESHOLD_MIN 250
#define GND_MIC_SWAP_THRESHOLD 4
#define WCD_FAKE_REMOVAL_MIN_PERIOD_MS 100
-#define HS_VREF_MIN_VAL 1400
+#define HS_VREF_MIN_VAL 1200
#define FW_READ_ATTEMPTS 15
#define FW_READ_TIMEOUT 4000000
#define FAKE_REM_RETRY_ATTEMPTS 3
@@ -533,6 +533,11 @@ static void wcd_mbhc_set_and_turnoff_hph_padac(struct wcd_mbhc *mbhc)
WCD_MBHC_REG_READ(WCD_MBHC_HPH_CNP_WG_TIME, wg_time);
wg_time += 1;
+ if (mbhc->mbhc_cfg->default_gnd_mic &&
+ mbhc->mbhc_cfg->default_gnd_mic(mbhc->codec)) {
+ pr_debug("%s: US_EU gpio present,set to default switch\n"
+ , __func__);
+ }
/* If headphone PA is on, check if userspace receives
* removal event to sync-up PA's state */
@@ -1999,10 +2004,23 @@ static irqreturn_t wcd_mbhc_btn_press_handler(int irq, void *data)
struct wcd_mbhc *mbhc = data;
int mask;
unsigned long msec_val;
+ unsigned long msec_delta;
+ static unsigned long msec_first = 0;
pr_debug("%s: enter\n", __func__);
complete(&mbhc->btn_press_compl);
WCD_MBHC_RSC_LOCK(mbhc);
+
+ msec_delta = jiffies_to_msecs(jiffies - msec_first);
+ if(msec_delta < 100){
+ pr_err("%s:cancel repeat press,msec_delta = %ld\n", __func__,msec_delta);
+ goto done;
+ }
+ msec_first = jiffies;
+
+ /* send event to sw intr handler*/
+ mbhc->is_btn_press = true;
+
wcd_cancel_btn_work(mbhc);
if (wcd_swch_level_remove(mbhc)) {
pr_debug("%s: Switch level is low ", __func__);
diff --git a/sound/soc/codecs/wcd-mbhc-v2.h b/sound/soc/codecs/wcd-mbhc-v2.h
index 09b9307ad61d..4342a1b5122e 100644
--- a/sound/soc/codecs/wcd-mbhc-v2.h
+++ b/sound/soc/codecs/wcd-mbhc-v2.h
@@ -270,6 +270,7 @@ struct wcd_mbhc_config {
bool detect_extn_cable;
bool mono_stero_detection;
bool (*swap_gnd_mic)(struct snd_soc_codec *codec);
+ bool (*default_gnd_mic)(struct snd_soc_codec *codec);
bool hs_ext_micbias;
bool gnd_det_en;
int key_code[WCD_MBHC_KEYCODE_NUM];
@@ -280,6 +281,7 @@ struct wcd_mbhc_config {
bool enable_anc_mic_detect;
u32 enable_usbc_analog;
struct usbc_ana_audio_config usbc_analog_cfg;
+ struct regulator *vdd;
};
struct wcd_mbhc_intr {
diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c
index bb99e98f34e2..bc82d70c2852 100644
--- a/sound/soc/codecs/wcd9335.c
+++ b/sound/soc/codecs/wcd9335.c
@@ -5948,13 +5948,6 @@ static int tasha_codec_enable_dec(struct snd_soc_dapm_widget *w,
break;
case SND_SOC_DAPM_POST_PMU:
snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x00);
-
- if (decimator == 0) {
- snd_soc_write(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0x83);
- snd_soc_write(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0xA3);
- snd_soc_write(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0x83);
- snd_soc_write(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0x03);
- }
/* schedule work queue to Remove Mute */
schedule_delayed_work(&tasha->tx_mute_dwork[decimator].dwork,
msecs_to_jiffies(tx_unmute_delay));
diff --git a/sound/soc/msm/Kconfig b/sound/soc/msm/Kconfig
index 05ff48ff033a..884a49b26342 100644
--- a/sound/soc/msm/Kconfig
+++ b/sound/soc/msm/Kconfig
@@ -5,7 +5,7 @@ config SND_SOC_MSM_HOSTLESS_PCM
config SND_SOC_MSM_QDSP6V2_INTF
bool "SoC Q6 audio driver for MSM/APQ"
- depends on MSM_QDSP6_APRV2_GLINK
+ depends on MSM_QDSP6_APRV2 || MSM_QDSP6_APRV2_GLINK
help
To add support for SoC audio on MSM/APQ.
This will enable all the platform specific
@@ -184,8 +184,7 @@ config SND_SOC_MSM8996
select MSM_QDSP6_APRV2
select MSM_QDSP6V2_CODECS
select SND_SOC_WCD9335
- select SND_SOC_WSA881X
- select SND_SOC_MSM_HDMI_CODEC_RX if ARCH_MSM8996
+ select SND_SOC_WSA881X if !MACH_ZUK_Z2_ROW
select DTS_SRS_TM
select QTI_PP
select QTI_PP_AUDIOSPHERE
diff --git a/sound/soc/msm/msm8996.c b/sound/soc/msm/msm8996.c
index 47cd28af1b84..63ab59b89197 100644
--- a/sound/soc/msm/msm8996.c
+++ b/sound/soc/msm/msm8996.c
@@ -63,6 +63,24 @@
#define WSA8810_NAME_1 "wsa881x.20170211"
#define WSA8810_NAME_2 "wsa881x.20170212"
+#define NCX_VTG_MIN_UV 3000000
+#define NCX_VTG_MAX_UV 3000000
+#ifdef CONFIG_MACH_ZUK_Z2_ROW
+#define QUAT_MI2S_ENABLE
+#endif
+#ifdef QUAT_MI2S_ENABLE
+atomic_t quat_mi2s_rsc_ref;
+atomic_t quat_mi2s_clk_ref;
+static bool system_bootup = 1;
+static struct afe_clk_set mi2s_rx_clk = {
+ AFE_API_VERSION_I2S_CONFIG,
+ Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT,
+ Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
+ Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
+ Q6AFE_LPASS_CLK_ROOT_DEFAULT,
+ 0,
+};
+#endif
static int slim0_rx_sample_rate = SAMPLING_RATE_48KHZ;
static int slim0_tx_sample_rate = SAMPLING_RATE_48KHZ;
@@ -335,6 +353,9 @@ static int msm_hdmi_rx_ch = 2;
static int msm_proxy_rx_ch = 2;
static int hdmi_rx_sample_rate = SAMPLING_RATE_48KHZ;
static int msm_tert_mi2s_tx_ch = 2;
+#ifdef QUAT_MI2S_ENABLE
+static int msm_quat_mi2s_ch = 2;
+#endif
static bool codec_reg_done;
@@ -474,10 +495,10 @@ static struct wcd_mbhc_config wcd_mbhc_cfg = {
.mono_stero_detection = false,
.swap_gnd_mic = NULL,
.hs_ext_micbias = true,
- .key_code[0] = KEY_MEDIA,
- .key_code[1] = KEY_VOICECOMMAND,
- .key_code[2] = KEY_VOLUMEUP,
- .key_code[3] = KEY_VOLUMEDOWN,
+ .key_code[0] = BTN_0,
+ .key_code[1] = BTN_1,
+ .key_code[2] = BTN_2,
+ .key_code[3] = BTN_3,
.key_code[4] = 0,
.key_code[5] = 0,
.key_code[6] = 0,
@@ -489,6 +510,38 @@ static struct wcd_mbhc_config wcd_mbhc_cfg = {
.enable_anc_mic_detect = false,
};
+#define HEADSET_TYPE_STANDARD
+#ifdef HEADSET_TYPE_STANDARD
+static int gnd_mic_gpio_state = -1;
+static int headset_standard_get = 0;
+static int headset_type_standard = -1; // 0 America, 1 Europe standard
+static int headset_standard_get_parm_set(const char *val, struct kernel_param *kp)
+{
+ param_set_int(val, kp);
+ if (1 == headset_standard_get) {
+ if (-1 == gnd_mic_gpio_state)
+ headset_type_standard = 0;
+ else
+ headset_type_standard = gnd_mic_gpio_state;
+ printk(KERN_INFO "%s enter, headset_type_standard = %d\n",
+ __func__, headset_type_standard);
+ } else {
+ printk(KERN_INFO "enter %s, clear the headset/headphone type\n", __func__);
+ headset_type_standard = -1;
+ }
+ return 0;
+}
+module_param_call(headset_standard_get, headset_standard_get_parm_set, param_get_int,
+ &headset_standard_get, 0644);
+static int headset_type_standard_parm_set(const char *val, struct kernel_param *kp)
+{
+ param_set_int(val, kp);
+ return 0;
+}
+module_param_call(headset_type_standard, headset_type_standard_parm_set, param_get_int,
+ &headset_type_standard, 0644);
+#endif
+
static inline int param_is_mask(int p)
{
return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) &&
@@ -4341,6 +4394,66 @@ static int msm_slim_5_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
return rc;
}
+#ifdef QUAT_MI2S_ENABLE
+static int msm8996_quat_mi2s_startup(struct snd_pcm_substream *substream)
+{
+ int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ pr_info("%s: dai name %s %p\n", __func__, cpu_dai->name, cpu_dai->dev);
+ if (atomic_inc_return(&quat_mi2s_rsc_ref) == 1) {
+ pr_info("%s: acquire mi2s resources\n", __func__);
+ if (atomic_inc_return(&quat_mi2s_clk_ref) == 1) {
+ mi2s_rx_clk.enable = 1;
+ ret = afe_set_lpass_clock_v2(AFE_PORT_ID_QUATERNARY_MI2S_RX, &mi2s_rx_clk);
+ if (ret < 0) {
+ pr_err("%s: afe_set_lpass_clock failed\n", __func__);
+ return ret;
+ }
+ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS);
+ if (ret < 0)
+ dev_err(cpu_dai->dev, "set format for CPU dai"
+ " failed\n");
+ }
+ }
+ return ret;
+}
+static void msm8996_quat_mi2s_shutdown(struct snd_pcm_substream *substream)
+{
+ int ret = 0;
+ pr_debug("%s: substream = %s stream = %d\n", __func__,
+ substream->name, substream->stream);
+ if (atomic_dec_return(&quat_mi2s_rsc_ref) == 0) {
+ if (atomic_dec_return(&quat_mi2s_clk_ref) == 0) {
+ mi2s_rx_clk.enable = 0;
+ ret = afe_set_lpass_clock_v2(AFE_PORT_ID_QUATERNARY_MI2S_RX,
+ &mi2s_rx_clk);
+ if (ret < 0)
+ pr_err("%s: afe lpass clock failed, err:%d\n", __func__, ret);
+ }
+ }
+}
+static struct snd_soc_ops msm8996_quat_mi2s_be_ops = {
+ .startup = msm8996_quat_mi2s_startup,
+ .shutdown = msm8996_quat_mi2s_shutdown
+};
+
+static int msm_be_quat_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_interval *rate = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_RATE);
+ struct snd_interval *channels = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_CHANNELS);
+ pr_debug("%s: channel:%d\n", __func__, msm_quat_mi2s_ch);
+ rate->min = rate->max = SAMPLING_RATE_48KHZ;
+ channels->min = channels->max = msm_quat_mi2s_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ SNDRV_PCM_FORMAT_S16_LE);
+ return 0;
+}
+#endif
+
static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
@@ -5593,6 +5706,20 @@ static bool msm8996_swap_gnd_mic(struct snd_soc_codec *codec)
pr_debug("%s: swap select switch %d to %d\n", __func__, value, !value);
gpio_set_value_cansleep(pdata->us_euro_gpio, !value);
+ gnd_mic_gpio_state = !value;
+ return true;
+}
+
+static bool msm8996_default_gnd_mic(struct snd_soc_codec *codec)
+{
+ struct snd_soc_card *card = codec->component.card;
+ struct msm8996_asoc_mach_data *pdata =
+ snd_soc_card_get_drvdata(card);
+ int value = 0;
+
+ pr_debug("%s: set select switch to default value %d\n", __func__, value);
+ gpio_set_value_cansleep(pdata->us_euro_gpio, value);
+ gnd_mic_gpio_state = 0;
return true;
}
@@ -6910,6 +7037,23 @@ static struct snd_soc_dai_link msm8996_common_dai_links[] = {
.codec_name = "snd-soc-dummy",
.be_id = MSM_FRONTEND_DAI_VOICE2,
},
+#ifdef QUAT_MI2S_ENABLE
+ {
+ .name = "MI2S_TX Hostless",
+ .stream_name = "MI2S_TX Hostless",
+ .cpu_dai_name = "MI2S_TX_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+#endif
};
static struct snd_soc_dai_link msm8996_tdm_fe_dai_links[] = {
{
@@ -7635,7 +7779,37 @@ static struct snd_soc_dai_link msm8996_common_be_dai_links[] = {
.be_id = MSM_BACKEND_DAI_USB_TX,
.be_hw_params_fixup = msm_be_hw_params_fixup,
.ignore_suspend = 1,
- }
+ },
+#ifdef QUAT_MI2S_ENABLE
+ {
+ .name = LPASS_BE_QUAT_MI2S_RX,
+ .stream_name = "Quaternary MI2S Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.3",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX,
+ .be_hw_params_fixup = msm_be_quat_hw_params_fixup,
+ .ops = &msm8996_quat_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_MI2S_TX,
+ .stream_name = "Quaternary MI2S Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.3",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
+ .be_hw_params_fixup = msm_be_quat_hw_params_fixup,
+ .ops = &msm8996_quat_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+#endif
};
static struct snd_soc_dai_link msm8996_tasha_be_dai_links[] = {
@@ -8550,7 +8724,9 @@ static int msm8996_init_wsa_dev(struct platform_device *pdev,
int found = 0;
int i;
int ret;
-
+#ifndef CONFIG_SND_SOC_WSA881X
+ return -EINVAL;
+#endif
/* Get maximum WSA device count for this platform */
ret = of_property_read_u32(pdev->dev.of_node,
"qcom,wsa-max-devs", &wsa_max_devs);
@@ -8781,8 +8957,10 @@ static int msm8996_asoc_machine_probe(struct platform_device *pdev)
}
ret = msm8996_init_wsa_dev(pdev, card);
+#ifdef CONFIG_SND_SOC_WSA881X
if (ret)
goto err;
+#endif
pdata->hph_en1_gpio = of_get_named_gpio(pdev->dev.of_node,
"qcom,hph-en1-gpio", 0);
@@ -8801,6 +8979,13 @@ static int msm8996_asoc_machine_probe(struct platform_device *pdev)
if (ret)
dev_dbg(&pdev->dev, "msm8996_prepare_hifi failed (%d)\n",
ret);
+#ifdef QUAT_MI2S_ENABLE
+ if(system_bootup){
+ system_bootup = 0;
+ atomic_set(&quat_mi2s_rsc_ref, 0);
+ atomic_set(&quat_mi2s_clk_ref, 0);
+ }
+#endif
ret = snd_soc_register_card(card);
if (ret == -EPROBE_DEFER) {
@@ -8847,13 +9032,43 @@ static int msm8996_asoc_machine_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "%s detected %d",
"qcom,us-euro-gpios", pdata->us_euro_gpio);
wcd_mbhc_cfg.swap_gnd_mic = msm8996_swap_gnd_mic;
+ wcd_mbhc_cfg.default_gnd_mic = msm8996_default_gnd_mic;
}
ret = msm8996_prepare_us_euro(card);
if (ret)
dev_info(&pdev->dev, "msm8996_prepare_us_euro failed (%d)\n",
ret);
+#ifdef NCX8200
+ /* Enable VDD for NCX8200*/
+ wcd_mbhc_cfg.vdd = regulator_get(&pdev->dev, "ncx_vdd");
+ dev_info(&pdev->dev,
+ "Regulator get ncx_vdd ret=%d\n", ret);
+ if (IS_ERR(wcd_mbhc_cfg.vdd)) {
+ ret = PTR_ERR(wcd_mbhc_cfg.vdd);
+ dev_info(&pdev->dev,
+ "Regulator get failed vdd ret=%d\n", ret);
+ } else if (regulator_count_voltages(wcd_mbhc_cfg.vdd) > 0) {
+ ret = regulator_set_voltage(wcd_mbhc_cfg.vdd, NCX_VTG_MIN_UV, NCX_VTG_MAX_UV);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "Regulator set_vtg failed vdd ret=%d\n", ret);
+ goto err_vdd_put;
+ }
+ }
+ if (!IS_ERR(wcd_mbhc_cfg.vdd)) {
+ ret = regulator_enable(wcd_mbhc_cfg.vdd);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "Regulator vdd enable failed ret=%d\n", ret);
+ }
+ }
+#endif
return 0;
+#ifdef NCX8200
+ err_vdd_put:
+ regulator_put(wcd_mbhc_cfg.vdd);
+#endif
err:
if (pdata->us_euro_gpio > 0) {
dev_dbg(&pdev->dev, "%s free us_euro gpio %d\n",
diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
index ec590593e7c4..6318468cbbcf 100644
--- a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
@@ -77,6 +77,16 @@ static const struct afe_clk_cfg lpass_clk_cfg_default = {
Q6AFE_LPASS_MODE_CLK1_VALID,
0,
};
+
+static struct afe_clk_set q6_mi2s_rx_clk = {
+ AFE_API_VERSION_I2S_CONFIG,
+ Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT,
+ Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
+ Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
+ Q6AFE_LPASS_CLK_ROOT_DEFAULT,
+ 0,
+};
+
enum {
STATUS_PORT_STARTED, /* track if AFE port has started */
/* track AFE Tx port status for bi-directional transfers */
@@ -254,7 +264,8 @@ static const struct soc_enum tdm_config_enum[] = {
static DEFINE_MUTEX(tdm_mutex);
static atomic_t tdm_group_ref[IDX_GROUP_TDM_MAX];
-
+extern atomic_t quat_mi2s_clk_ref;
+static struct msm_dai_q6_mi2s_dai_data *mi2s_quat_dai_data;
/* cache of group cfg per parent node */
static struct afe_param_id_group_device_tdm_cfg tdm_group_cfg = {
AFE_API_VERSION_GROUP_DEVICE_TDM_CONFIG,
@@ -5644,6 +5655,9 @@ static int msm_dai_q6_mi2s_dev_probe(struct platform_device *pdev)
} else
dev_set_drvdata(&pdev->dev, dai_data);
+ if (mi2s_intf == MSM_QUAT_MI2S)
+ mi2s_quat_dai_data = dai_data;
+
pdev->dev.platform_data = mi2s_pdata;
rc = msm_dai_q6_mi2s_platform_data_validation(pdev,
@@ -5683,6 +5697,73 @@ static const struct snd_soc_component_driver msm_dai_q6_component = {
.name = "msm-dai-q6-dev",
};
+int msm_q6_enable_mi2s_clocks(bool enable)
+{
+ struct msm_dai_q6_dai_data *dai_data = &mi2s_quat_dai_data->rx_dai.mi2s_dai_data;
+ u16 port_id = 0;
+ int rc = 0;
+
+ if (msm_mi2s_get_port_id(MSM_QUAT_MI2S, SNDRV_PCM_STREAM_PLAYBACK, &port_id)) {
+ pr_debug(KERN_ERR"%s: invalid port id %#x\n", __func__, port_id);
+ return -EINVAL;
+ }
+ pr_debug("%s: afe port id = 0x%x\n"
+ "dai_data->channels = %u sample_rate = %u\n", __func__,
+ port_id, dai_data->channels, dai_data->rate);
+
+ if(enable){
+ if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
+ /* PORT START should be set if prepare called
+ * in active state.
+ */
+ q6_mi2s_rx_clk.enable = 1;
+ rc = afe_set_lpass_clock_v2(AFE_PORT_ID_QUATERNARY_MI2S_RX, &q6_mi2s_rx_clk);
+ if (rc < 0) {
+ pr_err("%s: afe_set_lpass_clock failed\n", __func__);
+ return rc;
+ }
+ dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_SD1;
+ if (dai_data->channels == 2)
+ dai_data->port_config.i2s.mono_stereo = MSM_AFE_CH_STEREO;
+ else
+ dai_data->port_config.i2s.mono_stereo = MSM_AFE_MONO;
+ dai_data->port_config.i2s.bit_width = 16;
+ dai_data->port_config.i2s.i2s_cfg_minor_version =
+ AFE_API_VERSION_I2S_CONFIG;
+ dai_data->port_config.i2s.sample_rate = 48000;
+ dai_data->port_config.i2s.ws_src = 1;
+ pr_debug("[%s][%d]afe_port_start[%d]\n", __func__, __LINE__,port_id);
+ rc = afe_port_start(port_id, &dai_data->port_config, dai_data->rate);
+ if (IS_ERR_VALUE(rc)){
+ printk(KERN_ERR"fail to open AFE port\n");
+ return -EINVAL;
+ }else
+ set_bit(STATUS_PORT_STARTED,dai_data->status_mask);
+ }
+ if (!test_bit(STATUS_PORT_STARTED, dai_data->hwfree_status)) {
+ set_bit(STATUS_PORT_STARTED, dai_data->hwfree_status);
+ pr_debug("%s: set hwfree_status to started\n", __func__);
+ }
+ }else{
+ if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
+ q6_mi2s_rx_clk.enable = 0;
+ rc = afe_set_lpass_clock_v2(AFE_PORT_ID_QUATERNARY_MI2S_RX, &q6_mi2s_rx_clk);
+ if (rc < 0) {
+ pr_err("%s: afe_set_lpass_clock failed\n", __func__);
+ }
+ rc = afe_close(port_id);
+ if (IS_ERR_VALUE(rc)){
+ printk(KERN_ERR"fail to close AFE port\n");
+ }
+ }
+ clear_bit(STATUS_PORT_STARTED, dai_data->status_mask);
+ if (test_bit(STATUS_PORT_STARTED, dai_data->hwfree_status))
+ clear_bit(STATUS_PORT_STARTED, dai_data->hwfree_status);
+ }
+ return rc;
+}
+EXPORT_SYMBOL(msm_q6_enable_mi2s_clocks);
+
static int msm_dai_q6_dev_probe(struct platform_device *pdev)
{
int rc, id, i, len;
@@ -9467,7 +9548,7 @@ static int msm_dai_q6_tdm_dev_probe(struct platform_device *pdev)
}
pdev->id = tdm_dev_id;
- dev_info(&pdev->dev, "%s: dev_name: %s dev_id: 0x%x\n",
+ dev_dbg(&pdev->dev, "%s: dev_name: %s dev_id: 0x%x\n",
__func__, dev_name(&pdev->dev), tdm_dev_id);
dai_data = kzalloc(sizeof(struct msm_dai_q6_tdm_dai_data),
@@ -9613,7 +9694,7 @@ static int msm_dai_q6_tdm_dev_probe(struct platform_device *pdev)
custom_tdm_header->header_type =
AFE_CUSTOM_TDM_HEADER_TYPE_INVALID;
} else {
- dev_info(&pdev->dev,
+ dev_dbg(&pdev->dev,
"%s: Custom tdm header not supported\n", __func__);
/* CUSTOM TDM HEADER CFG -- set default */
custom_tdm_header->header_type =
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 8e65e2ae3684..27f90c270e13 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -4052,25 +4052,31 @@ static int msm_routing_ext_ec_put(struct snd_kcontrol *kcontrol,
switch (msm_route_ext_ec_ref) {
case EXT_EC_REF_PRI_MI2S_TX:
ext_ec_ref_port_id = AFE_PORT_ID_PRIMARY_MI2S_TX;
+ msm_route_ext_ec_ref = 1;
break;
case EXT_EC_REF_SEC_MI2S_TX:
ext_ec_ref_port_id = AFE_PORT_ID_SECONDARY_MI2S_TX;
+ msm_route_ext_ec_ref = 2;
break;
case EXT_EC_REF_TERT_MI2S_TX:
ext_ec_ref_port_id = AFE_PORT_ID_TERTIARY_MI2S_TX;
+ msm_route_ext_ec_ref = 3;
break;
case EXT_EC_REF_QUAT_MI2S_TX:
ext_ec_ref_port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX;
+ msm_route_ext_ec_ref = 4;
break;
case EXT_EC_REF_QUIN_MI2S_TX:
ext_ec_ref_port_id = AFE_PORT_ID_QUINARY_MI2S_TX;
break;
case EXT_EC_REF_SLIM_1_TX:
ext_ec_ref_port_id = SLIMBUS_1_TX;
+ msm_route_ext_ec_ref = 5;
break;
case EXT_EC_REF_NONE:
default:
ext_ec_ref_port_id = AFE_PORT_INVALID;
+ msm_route_ext_ec_ref = 0;
state = false;
break;
}
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index eb3b42f47974..2f8c1e80ce32 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -2020,9 +2020,11 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
case ASM_DATA_CMD_REMOVE_TRAILING_SILENCE:
case ASM_SESSION_CMD_REGISTER_FOR_RX_UNDERFLOW_EVENTS:
case ASM_STREAM_CMD_OPEN_WRITE_COMPRESSED:
- if (data->payload_size >=
- 2 * sizeof(uint32_t) &&
- payload[1] != 0) {
+ if (data->payload_size <
+ 2 * sizeof(uint32_t)) {
+ pr_err("%s: payload size of %x is less than expected.\n",
+ __func__, data->payload_size);
+ } else if (payload[1] != 0) {
pr_debug("%s: session %d opcode 0x%x token 0x%x Payload = [0x%x] stat 0x%x src %d dest %d\n",
__func__, ac->session,
data->opcode, data->token,
@@ -2051,9 +2053,6 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
&(session[session_id].session_lock),
flags);
return 0;
- } else {
- pr_err("%s: payload size of %x is less than expected.\n",
- __func__, data->payload_size);
}
if ((is_adsp_reg_event(payload[0]) >= 0) ||
(payload[0] == ASM_STREAM_CMD_SET_PP_PARAMS_V2) ||
@@ -2104,7 +2103,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
pr_debug("%s: Watermark opcode[0x%x] status[0x%x]",
__func__, payload[0], payload[1]);
else
- pr_err("%s: payload size of %x is less than expected.\n",
+ pr_debug("%s: payload size of %x is less than expected.\n",
__func__, data->payload_size);
break;
}
@@ -2165,7 +2164,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
__func__, payload[0], payload[1],
data->token);
else
- dev_err(ac->dev, "%s: payload size of %x is less than expected.\n",
+ dev_vdbg(ac->dev, "%s: payload size of %x is less than expected.\n",
__func__, data->payload_size);
if (ac->io_mode & SYNC_IO_MODE) {
if (port->buf == NULL) {
@@ -2236,7 +2235,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
payload[2],
payload[3]);
else
- pr_err("%s: payload size of %x is less than expected.\n",
+ pr_debug("%s: payload size of %u is less than expected.\n",
__func__,
data->payload_size);
@@ -2359,7 +2358,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
(uint64_t)(((uint64_t)payload[2] << 32) |
payload[1]);
} else {
- dev_err(ac->dev, "%s: payload size of %x is less than expected.n",
+ dev_err(ac->dev, "%s: payload size of %x is less than expected.\n",
__func__, data->payload_size);
}
if (atomic_cmpxchg(&ac->time_flag, 1, 0))
@@ -2438,7 +2437,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
payload[2],
payload[1]);
else
- pr_err("%s: payload size of %x is less than expected.\n",
+ pr_debug("%s: payload size of %x is less than expected.\n",
__func__, data->payload_size);
wake_up(&ac->cmd_wait);
break;
@@ -2449,7 +2448,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
payload[0], payload[2],
payload[1]);
else
- pr_err("%s: payload size of %x is less than expected.\n",
+ pr_debug("%s: payload size of %x is less than expected.\n",
__func__, data->payload_size);
if (payload[0] == 0 &&
data->payload_size >=
diff --git a/sound/soc/msm/qdsp6v2/q6core.c b/sound/soc/msm/qdsp6v2/q6core.c
index 7ac3dcf6281a..417c5d0a12d1 100644
--- a/sound/soc/msm/qdsp6v2/q6core.c
+++ b/sound/soc/msm/qdsp6v2/q6core.c
@@ -375,6 +375,7 @@ struct cal_block_data *cal_utils_get_cal_block_by_key(
return NULL;
}
+#ifndef CONFIG_MACH_ZUK
static int q6core_send_get_avcs_fwk_ver_cmd(void)
{
struct apr_hdr avcs_ver_cmd;
@@ -535,6 +536,13 @@ done:
}
EXPORT_SYMBOL(q6core_get_fwk_version_size);
+#else
+int q6core_get_service_version(uint32_t service_id,
+ struct avcs_fwk_ver_info *ver_info,
+ size_t size) { return -1; }
+size_t q6core_get_fwk_version_size(uint32_t service_id)
+ { return -1; }
+#endif
int32_t core_set_license(uint32_t key, uint32_t module_id)
{
struct avcs_cmd_set_license *cmd_setl = NULL;
diff --git a/sound/soc/msm/qdsp6v2/q6lsm.c b/sound/soc/msm/qdsp6v2/q6lsm.c
index a19f0447c4b4..90822aada3b6 100644
--- a/sound/soc/msm/qdsp6v2/q6lsm.c
+++ b/sound/soc/msm/qdsp6v2/q6lsm.c
@@ -56,7 +56,6 @@ enum {
};
enum {
- LSM_INVALID_SESSION_ID = 0,
LSM_MIN_SESSION_ID = 1,
LSM_MAX_SESSION_ID = 8,
LSM_CONTROL_SESSION = 0x0F,
@@ -228,7 +227,7 @@ static void q6lsm_session_free(struct lsm_client *client)
spin_lock_irqsave(&lsm_session_lock, flags);
lsm_session[client->session] = NULL;
spin_unlock_irqrestore(&lsm_session_lock, flags);
- client->session = LSM_INVALID_SESSION_ID;
+ client->session = 0;
}
static void *q6lsm_mmap_apr_reg(void)