diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/Kconfig | 6 | ||||
-rw-r--r-- | sound/soc/codecs/Makefile | 2 | ||||
-rw-r--r-- | sound/soc/codecs/tfa9890.c | 476 | ||||
-rw-r--r-- | sound/soc/codecs/tfa9890.h | 63 | ||||
-rw-r--r-- | sound/soc/codecs/wcd-mbhc-v2.c | 20 | ||||
-rw-r--r-- | sound/soc/codecs/wcd-mbhc-v2.h | 2 | ||||
-rw-r--r-- | sound/soc/codecs/wcd9335.c | 7 | ||||
-rw-r--r-- | sound/soc/msm/Kconfig | 5 | ||||
-rw-r--r-- | sound/soc/msm/msm8996.c | 227 | ||||
-rw-r--r-- | sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c | 87 | ||||
-rw-r--r-- | sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c | 6 | ||||
-rw-r--r-- | sound/soc/msm/qdsp6v2/q6asm.c | 23 | ||||
-rw-r--r-- | sound/soc/msm/qdsp6v2/q6core.c | 8 | ||||
-rw-r--r-- | sound/soc/msm/qdsp6v2/q6lsm.c | 3 |
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 dd4e3533a015..69b4c0ecd83f 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..cb7bb1f34492 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, const 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, const 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 d84afdb4a6a6..96c59cad19c3 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c @@ -4057,25 +4057,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 91854735bb0f..70ae79f5f6d1 100644 --- a/sound/soc/msm/qdsp6v2/q6asm.c +++ b/sound/soc/msm/qdsp6v2/q6asm.c @@ -2022,9 +2022,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, @@ -2053,9 +2055,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) || @@ -2106,7 +2105,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; } @@ -2167,7 +2166,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) { @@ -2238,7 +2237,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); @@ -2370,7 +2369,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)) @@ -2457,7 +2456,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; @@ -2468,7 +2467,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 a0ecc1ce277c..8e1cb3a8b43b 100644 --- a/sound/soc/msm/qdsp6v2/q6core.c +++ b/sound/soc/msm/qdsp6v2/q6core.c @@ -376,6 +376,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; @@ -536,6 +537,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 4b80c042ed95..807a4df9a2ba 100644 --- a/sound/soc/msm/qdsp6v2/q6lsm.c +++ b/sound/soc/msm/qdsp6v2/q6lsm.c @@ -57,7 +57,6 @@ enum { }; enum { - LSM_INVALID_SESSION_ID = 0, LSM_MIN_SESSION_ID = 1, LSM_MAX_SESSION_ID = 8, LSM_CONTROL_SESSION = 0x0F, @@ -229,7 +228,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) |