diff --git a/asoc/Makefile b/asoc/Makefile index 3fccff6726..cc28148dcf 100644 --- a/asoc/Makefile +++ b/asoc/Makefile @@ -11,10 +11,6 @@ obj-$(CONFIG_SND_SOC_QDSP6V2) += snd-soc-qdsp6v2.o snd-soc-cpe-objs := msm-cpe-lsm.o obj-$(CONFIG_SND_SOC_CPE) += snd-soc-cpe.o -# for MSM8996 sound card driver -snd-soc-msm8996-objs := msm8996.o -obj-$(CONFIG_SND_SOC_MSM8996) += snd-soc-msm8996.o - # for MSM8998 sound card driver snd-soc-msm8998-objs := msm8998.o obj-$(CONFIG_SND_SOC_MACHINE_MSM8998) += snd-soc-msm8998.o diff --git a/asoc/codecs/Makefile b/asoc/codecs/Makefile index f0477f7eeb..9b02c8a51c 100644 --- a/asoc/codecs/Makefile +++ b/asoc/codecs/Makefile @@ -1,4 +1,6 @@ -snd-soc-wcd9xxx-v2-objs := wcd9xxx-common-v2.o wcd9xxx-resmgr-v2.o wcdcal-hwdep.o wcd9xxx-soc-init.o +snd-soc-wcd9xxx-objs := wcd9xxx-common-v2.o wcd9xxx-resmgr-v2.o \ + wcdcal-hwdep.o wcd9xxx-soc-init.o wcd-dsp-utils.o \ + wcd-dsp-mgr.o audio-ext-clk-up.o snd-soc-wcd-cpe-objs := wcd_cpe_services.o wcd_cpe_core.o snd-soc-wsa881x-objs := wsa881x.o wsa881x-tables.o wsa881x-regmap.o wsa881x-temp-sensor.o snd-soc-wcd-mbhc-objs := wcd-mbhc-v2.o @@ -8,8 +10,6 @@ endif ifneq (,$(filter $(CONFIG_SND_SOC_WCD_MBHC_ADC),y m)) snd-soc-wcd-mbhc-objs += wcd-mbhc-adc.o endif -snd-soc-wcd-dsp-utils-objs := wcd-dsp-utils.o -snd-soc-wcd-dsp-mgr-objs := wcd-dsp-mgr.o snd-soc-wcd-spi-objs := wcd-spi.o snd-soc-wcd9335-objs := wcd9335.o snd-soc-wcd-cpe-objs := wcd_cpe_services.o wcd_cpe_core.o @@ -19,18 +19,10 @@ obj-$(CONFIG_SND_SOC_WCD_CPE) += snd-soc-wcd-cpe.o obj-$(CONFIG_SND_SOC_WCD934X) += wcd934x/ obj-$(CONFIG_SND_SOC_SDM660_CDC) += sdm660_cdc/ obj-$(CONFIG_SND_SOC_MSM_SDW) += msm_sdw/ -ifeq ($(CONFIG_COMMON_CLK_MSM), y) - obj-$(CONFIG_AUDIO_EXT_CLK) += audio-ext-clk.o -endif -ifeq ($(CONFIG_COMMON_CLK_QCOM), y) - obj-$(CONFIG_AUDIO_EXT_CLK) += audio-ext-clk-up.o -endif -obj-$(CONFIG_SND_SOC_WCD9XXX_V2) += snd-soc-wcd9xxx-v2.o -obj-$(CONFIG_SND_SOC_WCD_CPE) += snd-soc-wcd-cpe.o +obj-$(CONFIG_SND_SOC_WCD9XXX_V2) += snd-soc-wcd9xxx.o obj-$(CONFIG_SND_SOC_WCD_MBHC) += snd-soc-wcd-mbhc.o obj-$(CONFIG_SND_SOC_WSA881X) += snd-soc-wsa881x.o -obj-$(CONFIG_SND_SOC_WCD_DSP_MGR) += snd-soc-wcd-dsp-mgr.o snd-soc-wcd-dsp-utils.o obj-$(CONFIG_SND_SOC_WCD_SPI) += snd-soc-wcd-spi.o snd-soc-msm-stub-objs := msm_stub.o @@ -41,5 +33,8 @@ wcd-core-objs := wcd9xxx-rst.o wcd9xxx-core-init.o \ wcd9xxx-slimslave.o wcd9xxx-utils.o \ wcd9335-regmap.o wcd9335-tables.o \ msm-cdc-pinctrl.o msm-cdc-supply.o +wcd-core-objs += wcd934x/wcd934x-regmap.o +wcd-core-objs += wcd934x/wcd934x-tables.o + obj-$(CONFIG_WCD9XXX_CODEC_CORE) += wcd-core.o obj-$(CONFIG_SND_SOC_MSM_HDMI_CODEC_RX) += msm_hdmi_codec_rx.o diff --git a/asoc/codecs/wcd934x/Makefile b/asoc/codecs/wcd934x/Makefile index c4db59b0e9..12781f6d45 100644 --- a/asoc/codecs/wcd934x/Makefile +++ b/asoc/codecs/wcd934x/Makefile @@ -2,6 +2,5 @@ # Makefile for wcd934x codec driver. # snd-soc-wcd934x-objs := wcd934x.o wcd934x-dsp-cntl.o \ - wcd934x-mbhc.o wcd934x-dsd.o \ - wcd934x-regmap.o wcd934x-tables.o + wcd934x-mbhc.o wcd934x-dsd.o obj-$(CONFIG_SND_SOC_WCD934X) += snd-soc-wcd934x.o diff --git a/asoc/codecs/wsa881x-analog.c b/asoc/codecs/wsa881x-analog.c deleted file mode 100644 index 4de9624977..0000000000 --- a/asoc/codecs/wsa881x-analog.c +++ /dev/null @@ -1,1446 +0,0 @@ -/* - * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "wsa881x-analog.h" -#include "wsa881x-temp-sensor.h" -#include "../msm/msm-audio-pinctrl.h" - -#define SPK_GAIN_12DB 4 -#define WIDGET_NAME_MAX_SIZE 80 - -/* - * Private data Structure for wsa881x. All parameters related to - * WSA881X codec needs to be defined here. - */ -struct wsa881x_pdata { - struct regmap *regmap[2]; - struct i2c_client *client[2]; - struct snd_soc_codec *codec; - - /* track wsa881x status during probe */ - int status; - bool boost_enable; - bool visense_enable; - int spk_pa_gain; - struct i2c_msg xfer_msg[2]; - struct mutex xfer_lock; - bool regmap_flag; - bool wsa_active; - int index; - int (*enable_mclk)(struct snd_soc_card *, bool); - struct wsa881x_tz_priv tz_pdata; - int bg_cnt; - int clk_cnt; - int enable_cnt; - int version; - struct mutex bg_lock; - struct mutex res_lock; - struct delayed_work ocp_ctl_work; -}; - -enum { - WSA881X_STATUS_PROBING, - WSA881X_STATUS_I2C, -}; - -#define WSA881X_OCP_CTL_TIMER_SEC 2 -#define WSA881X_OCP_CTL_TEMP_CELSIUS 25 -#define WSA881X_OCP_CTL_POLL_TIMER_SEC 60 - -static int wsa881x_ocp_poll_timer_sec = WSA881X_OCP_CTL_POLL_TIMER_SEC; -module_param(wsa881x_ocp_poll_timer_sec, int, 0664); -MODULE_PARM_DESC(wsa881x_ocp_poll_timer_sec, "timer for ocp ctl polling"); - -static int32_t wsa881x_resource_acquire(struct snd_soc_codec *codec, - bool enable); - -const char *wsa_tz_names[] = {"wsa881x.0e", "wsa881x.0f"}; - -struct wsa881x_pdata wsa_pdata[MAX_WSA881X_DEVICE]; - -static bool pinctrl_init; - -static int wsa881x_populate_dt_pdata(struct device *dev); -static int wsa881x_reset(struct wsa881x_pdata *pdata, bool enable); -static int wsa881x_startup(struct wsa881x_pdata *pdata); -static int wsa881x_shutdown(struct wsa881x_pdata *pdata); - -static int delay_array_msec[] = {10, 20, 30, 40, 50}; - -static int wsa881x_i2c_addr = -1; -static int wsa881x_probing_count; -static int wsa881x_presence_count; - -static const char * const wsa881x_spk_pa_gain_text[] = { -"POS_13P5_DB", "POS_12_DB", "POS_10P5_DB", "POS_9_DB", "POS_7P5_DB", -"POS_6_DB", "POS_4P5_DB", "POS_3_DB", "POS_1P5_DB", "POS_0_DB"}; - -static const struct soc_enum wsa881x_spk_pa_gain_enum[] = { - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wsa881x_spk_pa_gain_text), - wsa881x_spk_pa_gain_text), -}; - -static int wsa881x_spk_pa_gain_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = wsa881x->spk_pa_gain; - - dev_dbg(codec->dev, "%s: spk_pa_gain = %ld\n", __func__, - ucontrol->value.integer.value[0]); - - return 0; -} - -static int wsa881x_spk_pa_gain_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - - if (ucontrol->value.integer.value[0] < 0 || - ucontrol->value.integer.value[0] > 0xC) { - dev_err(codec->dev, "%s: Unsupported gain val %ld\n", - __func__, ucontrol->value.integer.value[0]); - return -EINVAL; - } - wsa881x->spk_pa_gain = ucontrol->value.integer.value[0]; - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", - __func__, ucontrol->value.integer.value[0]); - - return 0; -} - -static int get_i2c_wsa881x_device_index(u16 reg) -{ - u16 mask = 0x0f00; - int value = 0; - - value = ((reg & mask) >> 8) & 0x000f; - - switch (value) { - case 0: - return 0; - case 1: - return 1; - default: - break; - } - return -EINVAL; -} - -static int wsa881x_i2c_write_device(struct wsa881x_pdata *wsa881x, - unsigned int reg, unsigned int val) -{ - int i = 0, rc = 0; - int wsa881x_index; - struct i2c_msg *msg; - int ret = 0; - int bytes = 1; - u8 reg_addr = 0; - u8 data[bytes + 1]; - - wsa881x_index = get_i2c_wsa881x_device_index(reg); - if (wsa881x_index < 0) { - pr_err("%s:invalid register to write\n", __func__); - return -EINVAL; - } - if (wsa881x->regmap_flag) { - rc = regmap_write(wsa881x->regmap[wsa881x_index], reg, val); - for (i = 0; rc && i < ARRAY_SIZE(delay_array_msec); i++) { - pr_err("Failed writing reg=%u - retry(%d)\n", reg, i); - /* retry after delay of increasing order */ - msleep(delay_array_msec[i]); - rc = regmap_write(wsa881x->regmap[wsa881x_index], - reg, val); - } - if (rc) - pr_err("Failed writing reg=%u rc=%d\n", reg, rc); - else - pr_err("write success register = %x val = %x\n", - reg, val); - } else { - reg_addr = (u8)reg; - msg = &wsa881x->xfer_msg[0]; - msg->addr = wsa881x->client[wsa881x_index]->addr; - msg->len = bytes + 1; - msg->flags = 0; - data[0] = reg; - data[1] = (u8)val; - msg->buf = data; - ret = i2c_transfer(wsa881x->client[wsa881x_index]->adapter, - wsa881x->xfer_msg, 1); - /* Try again if the write fails */ - if (ret != 1) { - ret = i2c_transfer( - wsa881x->client[wsa881x_index]->adapter, - wsa881x->xfer_msg, 1); - if (ret != 1) { - pr_err("failed to write the device\n"); - return ret; - } - } - pr_debug("write success reg = %x val = %x\n", reg, data[1]); - } - return rc; -} - -static int wsa881x_i2c_read_device(struct wsa881x_pdata *wsa881x, - unsigned int reg) -{ - int wsa881x_index; - int i = 0, rc = 0; - unsigned int val; - struct i2c_msg *msg; - int ret = 0; - u8 reg_addr = 0; - u8 dest[5]; - - wsa881x_index = get_i2c_wsa881x_device_index(reg); - if (wsa881x_index < 0) { - pr_err("%s:invalid register to read\n", __func__); - return -EINVAL; - } - if (wsa881x->regmap_flag) { - rc = regmap_read(wsa881x->regmap[wsa881x_index], reg, &val); - for (i = 0; rc && i < ARRAY_SIZE(delay_array_msec); i++) { - pr_err("Failed reading reg=%u - retry(%d)\n", reg, i); - /* retry after delay of increasing order */ - msleep(delay_array_msec[i]); - rc = regmap_read(wsa881x->regmap[wsa881x_index], - reg, &val); - } - if (rc) { - pr_err("Failed reading reg=%u rc=%d\n", reg, rc); - return rc; - } - pr_debug("read success reg = %x val = %x\n", - reg, val); - } else { - reg_addr = (u8)reg; - msg = &wsa881x->xfer_msg[0]; - msg->addr = wsa881x->client[wsa881x_index]->addr; - msg->len = 1; - msg->flags = 0; - msg->buf = ®_addr; - - msg = &wsa881x->xfer_msg[1]; - msg->addr = wsa881x->client[wsa881x_index]->addr; - msg->len = 1; - msg->flags = I2C_M_RD; - msg->buf = dest; - ret = i2c_transfer(wsa881x->client[wsa881x_index]->adapter, - wsa881x->xfer_msg, 2); - - /* Try again if read fails first time */ - if (ret != 2) { - ret = i2c_transfer( - wsa881x->client[wsa881x_index]->adapter, - wsa881x->xfer_msg, 2); - if (ret != 2) { - pr_err("failed to read wsa register:%d\n", - reg); - return ret; - } - } - val = dest[0]; - } - return val; -} - -static unsigned int wsa881x_i2c_read(struct snd_soc_codec *codec, - unsigned int reg) -{ - struct wsa881x_pdata *wsa881x; - unsigned int val; - int ret; - - if (codec == NULL) { - pr_err("%s: invalid codec\n", __func__); - return -EINVAL; - } - wsa881x = snd_soc_codec_get_drvdata(codec); - if (!wsa881x->wsa_active) { - ret = snd_soc_cache_read(codec, reg, &val); - if (ret >= 0) - return val; - dev_err(codec->dev, - "cache read failed for reg: 0x%x ret: %d\n", - reg, ret); - return ret; - } - return wsa881x_i2c_read_device(wsa881x, reg); -} - -static int wsa881x_i2c_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int val) -{ - struct wsa881x_pdata *wsa881x; - int ret = 0; - - if (codec == NULL) { - pr_err("%s: invalid codec\n", __func__); - return -EINVAL; - } - wsa881x = snd_soc_codec_get_drvdata(codec); - if (!wsa881x->wsa_active) { - ret = snd_soc_cache_write(codec, reg, val); - if (ret != 0) - dev_err(codec->dev, "cache write to %x failed: %d\n", - reg, ret); - return ret; - } - return wsa881x_i2c_write_device(wsa881x, reg, val); -} - -static int wsa881x_i2c_get_client_index(struct i2c_client *client, - int *wsa881x_index) -{ - int ret = 0; - - switch (client->addr) { - case WSA881X_I2C_SPK0_SLAVE0_ADDR: - case WSA881X_I2C_SPK0_SLAVE1_ADDR: - *wsa881x_index = WSA881X_I2C_SPK0_SLAVE0; - break; - case WSA881X_I2C_SPK1_SLAVE0_ADDR: - case WSA881X_I2C_SPK1_SLAVE1_ADDR: - *wsa881x_index = WSA881X_I2C_SPK1_SLAVE0; - break; - default: - ret = -EINVAL; - break; - } - return ret; -} - -static int wsa881x_boost_ctrl(struct snd_soc_codec *codec, bool enable) -{ - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - - pr_debug("%s: enable:%d\n", __func__, enable); - if (enable) { - if (!WSA881X_IS_2_0(wsa881x->version)) { - snd_soc_update_bits(codec, WSA881X_ANA_CTL, - 0x01, 0x01); - snd_soc_update_bits(codec, WSA881X_ANA_CTL, - 0x04, 0x04); - snd_soc_update_bits(codec, WSA881X_BOOST_PS_CTL, - 0x40, 0x00); - snd_soc_update_bits(codec, WSA881X_BOOST_PRESET_OUT1, - 0xF0, 0xB0); - snd_soc_update_bits(codec, WSA881X_BOOST_ZX_CTL, - 0x20, 0x00); - snd_soc_update_bits(codec, WSA881X_BOOST_EN_CTL, - 0x80, 0x80); - } else { - snd_soc_update_bits(codec, WSA881X_BOOST_LOOP_STABILITY, - 0x03, 0x03); - snd_soc_update_bits(codec, WSA881X_BOOST_MISC2_CTL, - 0xFF, 0x14); - snd_soc_update_bits(codec, WSA881X_BOOST_START_CTL, - 0x80, 0x80); - snd_soc_update_bits(codec, WSA881X_BOOST_START_CTL, - 0x03, 0x00); - snd_soc_update_bits(codec, - WSA881X_BOOST_SLOPE_COMP_ISENSE_FB, - 0x0C, 0x04); - snd_soc_update_bits(codec, - WSA881X_BOOST_SLOPE_COMP_ISENSE_FB, - 0x03, 0x00); - snd_soc_update_bits(codec, WSA881X_BOOST_PRESET_OUT1, - 0xF0, 0x70); - snd_soc_update_bits(codec, WSA881X_ANA_CTL, 0x03, 0x01); - snd_soc_update_bits(codec, WSA881X_SPKR_DRV_EN, - 0x08, 0x08); - snd_soc_update_bits(codec, WSA881X_ANA_CTL, 0x04, 0x04); - snd_soc_update_bits(codec, WSA881X_BOOST_CURRENT_LIMIT, - 0x0F, 0x08); - snd_soc_update_bits(codec, WSA881X_BOOST_EN_CTL, - 0x80, 0x80); - } - /* For WSA8810, start-up time is 1500us as per qcrg sequence */ - usleep_range(1500, 1510); - } else { - /* ENSURE: Class-D amp is shutdown. CLK is still on */ - snd_soc_update_bits(codec, WSA881X_BOOST_EN_CTL, 0x80, 0x00); - /* boost settle time is 1500us as per qcrg sequence */ - usleep_range(1500, 1510); - } - return 0; -} - -static int wsa881x_visense_txfe_ctrl(struct snd_soc_codec *codec, bool enable, - u8 isense1_gain, u8 isense2_gain, - u8 vsense_gain) -{ - u8 value = 0; - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - - pr_debug("%s: enable:%d\n", __func__, enable); - - if (enable) { - if (WSA881X_IS_2_0(wsa881x->version)) { - snd_soc_update_bits(codec, WSA881X_OTP_REG_28, - 0x3F, 0x3A); - snd_soc_update_bits(codec, WSA881X_BONGO_RESRV_REG1, - 0xFF, 0xB2); - snd_soc_update_bits(codec, WSA881X_BONGO_RESRV_REG2, - 0xFF, 0x05); - } - snd_soc_update_bits(codec, WSA881X_SPKR_PROT_FE_VSENSE_VCM, - 0x08, 0x00); - if (WSA881X_IS_2_0(wsa881x->version)) { - snd_soc_update_bits(codec, WSA881X_SPKR_PROT_ATEST2, - 0x1C, 0x04); - } else { - snd_soc_update_bits(codec, WSA881X_SPKR_PROT_ATEST2, - 0x08, 0x08); - snd_soc_update_bits(codec, WSA881X_SPKR_PROT_ATEST2, - 0x02, 0x02); - } - value = ((isense2_gain << 6) | (isense1_gain << 4) | - (vsense_gain << 3)); - snd_soc_update_bits(codec, WSA881X_SPKR_PROT_FE_GAIN, - 0xF8, value); - snd_soc_update_bits(codec, WSA881X_SPKR_PROT_FE_GAIN, - 0x01, 0x01); - } else { - if (WSA881X_IS_2_0(wsa881x->version)) - snd_soc_update_bits(codec, - WSA881X_SPKR_PROT_FE_VSENSE_VCM, 0x10, 0x10); - else - snd_soc_update_bits(codec, - WSA881X_SPKR_PROT_FE_VSENSE_VCM, 0x08, 0x08); - /* - * 200us sleep is needed after visense txfe disable as per - * HW requirement. - */ - usleep_range(200, 210); - - snd_soc_update_bits(codec, WSA881X_SPKR_PROT_FE_GAIN, - 0x01, 0x00); - } - return 0; -} - -static int wsa881x_visense_adc_ctrl(struct snd_soc_codec *codec, bool enable) -{ - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - - pr_debug("%s: enable:%d\n", __func__, enable); - if (enable) { - if (!WSA881X_IS_2_0(wsa881x->version)) - snd_soc_update_bits(codec, WSA881X_ADC_SEL_IBIAS, - 0x70, 0x40); - snd_soc_update_bits(codec, WSA881X_ADC_EN_SEL_IBIAS, - 0x07, 0x04); - snd_soc_update_bits(codec, WSA881X_ADC_EN_MODU_V, 0x80, 0x80); - snd_soc_update_bits(codec, WSA881X_ADC_EN_MODU_I, 0x80, 0x80); - } else { - /* Ensure: Speaker Protection has been stopped */ - snd_soc_update_bits(codec, WSA881X_ADC_EN_MODU_V, 0x80, 0x00); - snd_soc_update_bits(codec, WSA881X_ADC_EN_MODU_I, 0x80, 0x00); - } - - return 0; -} - -static void wsa881x_bandgap_ctrl(struct snd_soc_codec *codec, bool enable) -{ - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - - dev_dbg(codec->dev, "%s: enable:%d, bg_count:%d\n", __func__, - enable, wsa881x->bg_cnt); - mutex_lock(&wsa881x->bg_lock); - if (enable) { - ++wsa881x->bg_cnt; - if (wsa881x->bg_cnt == 1) { - snd_soc_update_bits(codec, WSA881X_TEMP_OP, - 0x08, 0x08); - /* 400usec sleep is needed as per HW requirement */ - usleep_range(400, 410); - snd_soc_update_bits(codec, WSA881X_TEMP_OP, 0x04, 0x04); - } - } else { - --wsa881x->bg_cnt; - if (wsa881x->bg_cnt <= 0) { - WARN_ON(wsa881x->bg_cnt < 0); - wsa881x->bg_cnt = 0; - snd_soc_update_bits(codec, WSA881X_TEMP_OP, 0x04, 0x00); - snd_soc_update_bits(codec, WSA881X_TEMP_OP, 0x08, 0x00); - } - } - mutex_unlock(&wsa881x->bg_lock); -} - -static void wsa881x_clk_ctrl(struct snd_soc_codec *codec, bool enable) -{ - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - - dev_dbg(codec->dev, "%s:ss enable:%d, clk_count:%d\n", __func__, - enable, wsa881x->clk_cnt); - mutex_lock(&wsa881x->res_lock); - if (enable) { - ++wsa881x->clk_cnt; - if (wsa881x->clk_cnt == 1) { - snd_soc_write(codec, WSA881X_CDC_RST_CTL, 0x02); - snd_soc_write(codec, WSA881X_CDC_RST_CTL, 0x03); - snd_soc_write(codec, WSA881X_CLOCK_CONFIG, 0x01); - snd_soc_write(codec, WSA881X_CDC_DIG_CLK_CTL, 0x01); - snd_soc_write(codec, WSA881X_CDC_ANA_CLK_CTL, 0x01); - } - } else { - --wsa881x->clk_cnt; - if (wsa881x->clk_cnt <= 0) { - WARN_ON(wsa881x->clk_cnt < 0); - wsa881x->clk_cnt = 0; - snd_soc_write(codec, WSA881X_CDC_ANA_CLK_CTL, 0x00); - snd_soc_write(codec, WSA881X_CDC_DIG_CLK_CTL, 0x00); - if (WSA881X_IS_2_0(wsa881x->version)) - snd_soc_update_bits(codec, - WSA881X_CDC_TOP_CLK_CTL, 0x01, 0x00); - } - } - mutex_unlock(&wsa881x->res_lock); -} - -static int wsa881x_rdac_ctrl(struct snd_soc_codec *codec, bool enable) -{ - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - - pr_debug("%s: enable:%d\n", __func__, enable); - if (enable) { - snd_soc_update_bits(codec, WSA881X_ANA_CTL, 0x08, 0x00); - snd_soc_update_bits(codec, WSA881X_SPKR_DRV_GAIN, 0x08, 0x08); - snd_soc_update_bits(codec, WSA881X_SPKR_DAC_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, WSA881X_SPKR_DAC_CTL, 0x20, 0x00); - snd_soc_update_bits(codec, WSA881X_SPKR_DAC_CTL, 0x40, 0x40); - snd_soc_update_bits(codec, WSA881X_SPKR_DAC_CTL, 0x80, 0x80); - if (WSA881X_IS_2_0(wsa881x->version)) { - snd_soc_update_bits(codec, WSA881X_SPKR_BIAS_CAL, - 0x01, 0x01); - snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, - 0x30, 0x30); - snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, - 0x0C, 0x00); - } - snd_soc_update_bits(codec, WSA881X_SPKR_DRV_GAIN, 0xF0, 0x40); - snd_soc_update_bits(codec, WSA881X_SPKR_MISC_CTL1, 0x01, 0x01); - } else { - /* Ensure class-D amp is off */ - snd_soc_update_bits(codec, WSA881X_SPKR_DAC_CTL, 0x80, 0x00); - } - return 0; -} - -static int wsa881x_spkr_pa_ctrl(struct snd_soc_codec *codec, bool enable) -{ - int ret = 0; - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - - pr_debug("%s: enable:%d\n", __func__, enable); - if (enable) { - /* - * Ensure: Boost is enabled and stable, Analog input is up - * and outputting silence - */ - if (!WSA881X_IS_2_0(wsa881x->version)) { - snd_soc_update_bits(codec, WSA881X_ADC_EN_DET_TEST_I, - 0xFF, 0x01); - snd_soc_update_bits(codec, WSA881X_ADC_EN_MODU_V, - 0x02, 0x02); - snd_soc_update_bits(codec, WSA881X_ADC_EN_DET_TEST_V, - 0xFF, 0x10); - snd_soc_update_bits(codec, WSA881X_SPKR_PWRSTG_DBG, - 0xA0, 0xA0); - snd_soc_update_bits(codec, WSA881X_SPKR_DRV_EN, - 0x80, 0x80); - usleep_range(700, 710); - snd_soc_update_bits(codec, WSA881X_SPKR_PWRSTG_DBG, - 0x00, 0x00); - snd_soc_update_bits(codec, WSA881X_ADC_EN_DET_TEST_V, - 0xFF, 0x00); - snd_soc_update_bits(codec, WSA881X_ADC_EN_MODU_V, - 0x02, 0x00); - snd_soc_update_bits(codec, WSA881X_ADC_EN_DET_TEST_I, - 0xFF, 0x00); - } else - snd_soc_update_bits(codec, WSA881X_SPKR_DRV_EN, - 0x80, 0x80); - /* add 1000us delay as per qcrg */ - usleep_range(1000, 1010); - snd_soc_update_bits(codec, WSA881X_SPKR_DRV_EN, 0x01, 0x01); - if (WSA881X_IS_2_0(wsa881x->version)) - snd_soc_update_bits(codec, WSA881X_SPKR_BIAS_CAL, - 0x01, 0x00); - usleep_range(1000, 1010); - snd_soc_update_bits(codec, WSA881X_SPKR_DRV_GAIN, 0xF0, - (wsa881x->spk_pa_gain << 4)); - if (wsa881x->visense_enable) { - ret = msm_gpioset_activate(CLIENT_WSA_BONGO_1, - "wsa_vi"); - if (ret) { - pr_err("%s: gpio set cannot be activated %s\n", - __func__, "wsa_vi"); - return ret; - } - wsa881x_visense_txfe_ctrl(codec, true, - 0x00, 0x01, 0x00); - wsa881x_visense_adc_ctrl(codec, true); - } - } else { - /* - * Ensure: Boost is still on, Stream from Analog input and - * Speaker Protection has been stopped and input is at 0V - */ - if (WSA881X_IS_2_0(wsa881x->version)) { - snd_soc_update_bits(codec, WSA881X_SPKR_BIAS_CAL, - 0x01, 0x01); - usleep_range(1000, 1010); - snd_soc_update_bits(codec, WSA881X_SPKR_BIAS_CAL, - 0x01, 0x00); - msleep(20); - snd_soc_update_bits(codec, WSA881X_ANA_CTL, - 0x03, 0x00); - usleep_range(200, 210); - } - snd_soc_update_bits(codec, WSA881X_SPKR_DRV_EN, 0x80, 0x00); - } - return 0; -} - -static int wsa881x_get_boost(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = wsa881x->boost_enable; - return 0; -} - -static int wsa881x_set_boost(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - int value = ucontrol->value.integer.value[0]; - - dev_dbg(codec->dev, "%s: Boost enable current %d, new %d\n", - __func__, wsa881x->boost_enable, value); - wsa881x->boost_enable = value; - return 0; -} - -static int wsa881x_get_visense(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = wsa881x->visense_enable; - return 0; -} - -static int wsa881x_set_visense(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - int value = ucontrol->value.integer.value[0]; - - dev_dbg(codec->dev, "%s: VIsense enable current %d, new %d\n", - __func__, wsa881x->visense_enable, value); - wsa881x->visense_enable = value; - return 0; -} - -static const struct snd_kcontrol_new wsa881x_snd_controls[] = { - SOC_SINGLE_EXT("BOOST Switch", SND_SOC_NOPM, 0, 1, 0, - wsa881x_get_boost, wsa881x_set_boost), - - SOC_SINGLE_EXT("VISENSE Switch", SND_SOC_NOPM, 0, 1, 0, - wsa881x_get_visense, wsa881x_set_visense), - - SOC_ENUM_EXT("WSA_SPK PA Gain", wsa881x_spk_pa_gain_enum[0], - wsa881x_spk_pa_gain_get, wsa881x_spk_pa_gain_put), -}; - -static const char * const rdac_text[] = { - "ZERO", "Switch", -}; - -static const struct soc_enum rdac_enum = - SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(rdac_text), rdac_text); - -static const struct snd_kcontrol_new rdac_mux[] = { - SOC_DAPM_ENUM("RDAC", rdac_enum) -}; - -static int wsa881x_rdac_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - int ret = 0; - - dev_dbg(codec->dev, "%s: %s %d boost %d visense %d\n", - __func__, w->name, event, - wsa881x->boost_enable, wsa881x->visense_enable); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - ret = wsa881x_startup(wsa881x); - if (ret) { - pr_err("%s: wsa startup failed ret: %d", __func__, ret); - return ret; - } - wsa881x_clk_ctrl(codec, true); - snd_soc_update_bits(codec, WSA881X_SPKR_DAC_CTL, 0x02, 0x02); - if (!WSA881X_IS_2_0(wsa881x->version)) - snd_soc_update_bits(codec, WSA881X_BIAS_REF_CTRL, - 0x0F, 0x08); - wsa881x_bandgap_ctrl(codec, true); - if (!WSA881X_IS_2_0(wsa881x->version)) - snd_soc_update_bits(codec, WSA881X_SPKR_BBM_CTL, - 0x02, 0x02); - snd_soc_update_bits(codec, WSA881X_SPKR_MISC_CTL1, 0xC0, 0x80); - snd_soc_update_bits(codec, WSA881X_SPKR_MISC_CTL1, 0x06, 0x06); - if (!WSA881X_IS_2_0(wsa881x->version)) { - snd_soc_update_bits(codec, WSA881X_SPKR_MISC_CTL2, - 0x04, 0x04); - snd_soc_update_bits(codec, WSA881X_SPKR_BIAS_INT, - 0x09, 0x09); - } - snd_soc_update_bits(codec, WSA881X_SPKR_PA_INT, 0xF0, 0x20); - if (WSA881X_IS_2_0(wsa881x->version)) - snd_soc_update_bits(codec, WSA881X_SPKR_PA_INT, - 0x0E, 0x0E); - if (wsa881x->boost_enable) - wsa881x_boost_ctrl(codec, true); - break; - case SND_SOC_DAPM_POST_PMU: - wsa881x_rdac_ctrl(codec, true); - break; - case SND_SOC_DAPM_PRE_PMD: - wsa881x_rdac_ctrl(codec, false); - if (wsa881x->visense_enable) { - wsa881x_visense_adc_ctrl(codec, false); - wsa881x_visense_txfe_ctrl(codec, false, - 0x00, 0x01, 0x00); - ret = msm_gpioset_suspend(CLIENT_WSA_BONGO_1, - "wsa_vi"); - if (ret) { - pr_err("%s: gpio set cannot be suspended %s\n", - __func__, "wsa_vi"); - return ret; - } - } - break; - case SND_SOC_DAPM_POST_PMD: - if (wsa881x->boost_enable) - wsa881x_boost_ctrl(codec, false); - wsa881x_clk_ctrl(codec, false); - wsa881x_bandgap_ctrl(codec, false); - ret = wsa881x_shutdown(wsa881x); - if (ret < 0) { - pr_err("%s: wsa shutdown failed ret: %d", - __func__, ret); - return ret; - } - break; - default: - pr_err("%s: invalid event:%d\n", __func__, event); - return -EINVAL; - } - return 0; -} - -static void wsa881x_ocp_ctl_work(struct work_struct *work) -{ - struct wsa881x_pdata *wsa881x; - struct delayed_work *dwork; - struct snd_soc_codec *codec; - unsigned long temp_val; - - dwork = to_delayed_work(work); - wsa881x = container_of(dwork, struct wsa881x_pdata, ocp_ctl_work); - - if (!wsa881x) - return; - - codec = wsa881x->codec; - wsa881x_get_temp(wsa881x->tz_pdata.tz_dev, &temp_val); - dev_dbg(codec->dev, " temp = %ld\n", temp_val); - - if (temp_val <= WSA881X_OCP_CTL_TEMP_CELSIUS) - snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0x00); - else - snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0xC0); - - schedule_delayed_work(&wsa881x->ocp_ctl_work, - msecs_to_jiffies(wsa881x_ocp_poll_timer_sec * 1000)); -} - -static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - - pr_debug("%s: %s %d\n", __func__, w->name, event); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0x80); - break; - case SND_SOC_DAPM_POST_PMU: - wsa881x_spkr_pa_ctrl(codec, true); - schedule_delayed_work(&wsa881x->ocp_ctl_work, - msecs_to_jiffies(WSA881X_OCP_CTL_TIMER_SEC * 1000)); - break; - case SND_SOC_DAPM_PRE_PMD: - wsa881x_spkr_pa_ctrl(codec, false); - break; - case SND_SOC_DAPM_POST_PMD: - cancel_delayed_work_sync(&wsa881x->ocp_ctl_work); - snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0xC0); - break; - default: - pr_err("%s: invalid event:%d\n", __func__, event); - return -EINVAL; - } - return 0; -} - - -static const struct snd_soc_dapm_widget wsa881x_dapm_widgets[] = { - SND_SOC_DAPM_INPUT("WSA_IN"), - - SND_SOC_DAPM_DAC_E("RDAC Analog", NULL, SND_SOC_NOPM, 0, 0, - wsa881x_rdac_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_MUX("WSA_RDAC", SND_SOC_NOPM, 0, 0, - rdac_mux), - - SND_SOC_DAPM_PGA_S("WSA_SPKR PGA", 1, SND_SOC_NOPM, 0, 0, - wsa881x_spkr_pa_event, - SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | - SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_OUTPUT("WSA_SPKR"), -}; - -static const struct snd_soc_dapm_route wsa881x_audio_map[] = { - {"WSA_RDAC", "Switch", "WSA_IN"}, - {"RDAC Analog", NULL, "WSA_RDAC"}, - {"WSA_SPKR PGA", NULL, "RDAC Analog"}, - {"WSA_SPKR", NULL, "WSA_SPKR PGA"}, -}; - - -static int wsa881x_startup(struct wsa881x_pdata *pdata) -{ - int ret = 0; - struct snd_soc_codec *codec = pdata->codec; - struct snd_soc_card *card = codec->component.card; - - pr_debug("%s(): wsa startup, enable_cnt:%d\n", __func__, - pdata->enable_cnt); - - if (pdata->enable_cnt++ > 0) - return 0; - ret = msm_gpioset_activate(CLIENT_WSA_BONGO_1, "wsa_clk"); - if (ret) { - pr_err("%s: gpio set cannot be activated %s\n", - __func__, "wsa_clk"); - return ret; - } - if (pdata->enable_mclk) { - ret = pdata->enable_mclk(card, true); - if (ret < 0) { - dev_err_ratelimited(codec->dev, - "%s: mclk enable failed %d\n", - __func__, ret); - return ret; - } - } - ret = wsa881x_reset(pdata, true); - return ret; -} - -static int wsa881x_shutdown(struct wsa881x_pdata *pdata) -{ - int ret = 0, reg; - struct snd_soc_codec *codec = pdata->codec; - struct snd_soc_card *card = codec->component.card; - - pr_debug("%s(): wsa shutdown, enable_cnt:%d\n", __func__, - pdata->enable_cnt); - if (--pdata->enable_cnt > 0) - return 0; - ret = wsa881x_reset(pdata, false); - if (ret) { - pr_err("%s: wsa reset failed suspend %d\n", - __func__, ret); - return ret; - } - - if (pdata->enable_mclk) { - ret = pdata->enable_mclk(card, false); - if (ret < 0) { - pr_err("%s: mclk disable failed %d\n", - __func__, ret); - return ret; - } - } - - ret = msm_gpioset_suspend(CLIENT_WSA_BONGO_1, "wsa_clk"); - if (ret) { - pr_err("%s: gpio set cannot be suspended %s\n", - __func__, "wsa_clk"); - return ret; - } - if (pdata->codec) { - /* restore defaults to cache */ - for (reg = 0; reg < ARRAY_SIZE(wsa881x_ana_reg_defaults); - reg++) { - if (wsa881x_ana_reg_readable[reg]) - snd_soc_cache_write(pdata->codec, - wsa881x_ana_reg_defaults[reg].reg, - wsa881x_ana_reg_defaults[reg].def); - } - } - return 0; -} - -static int32_t wsa881x_resource_acquire(struct snd_soc_codec *codec, - bool enable) -{ - int ret = 0; - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - - if (enable) { - ret = wsa881x_startup(wsa881x); - if (ret < 0) { - dev_err_ratelimited(codec->dev, - "%s: failed to startup\n", __func__); - return ret; - } - } - wsa881x_clk_ctrl(codec, enable); - wsa881x_bandgap_ctrl(codec, enable); - if (!enable) { - ret = wsa881x_shutdown(wsa881x); - if (ret < 0) - dev_err_ratelimited(codec->dev, - "%s: failed to shutdown\n", __func__); - } - return ret; -} - -static int32_t wsa881x_temp_reg_read(struct snd_soc_codec *codec, - struct wsa_temp_register *wsa_temp_reg) -{ - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - int ret = 0; - - if (!wsa881x) { - dev_err(codec->dev, "%s: wsa881x is NULL\n", __func__); - return -EINVAL; - } - ret = wsa881x_resource_acquire(codec, true); - if (ret) { - dev_err_ratelimited(codec->dev, - "%s: resource acquire fail\n", __func__); - return ret; - } - - if (WSA881X_IS_2_0(wsa881x->version)) { - snd_soc_update_bits(codec, WSA881X_TADC_VALUE_CTL, 0x01, 0x00); - wsa_temp_reg->dmeas_msb = snd_soc_read(codec, WSA881X_TEMP_MSB); - wsa_temp_reg->dmeas_lsb = snd_soc_read(codec, WSA881X_TEMP_LSB); - snd_soc_update_bits(codec, WSA881X_TADC_VALUE_CTL, 0x01, 0x01); - } else { - wsa_temp_reg->dmeas_msb = snd_soc_read(codec, - WSA881X_TEMP_DOUT_MSB); - wsa_temp_reg->dmeas_lsb = snd_soc_read(codec, - WSA881X_TEMP_DOUT_LSB); - } - wsa_temp_reg->d1_msb = snd_soc_read(codec, WSA881X_OTP_REG_1); - wsa_temp_reg->d1_lsb = snd_soc_read(codec, WSA881X_OTP_REG_2); - wsa_temp_reg->d2_msb = snd_soc_read(codec, WSA881X_OTP_REG_3); - wsa_temp_reg->d2_lsb = snd_soc_read(codec, WSA881X_OTP_REG_4); - - ret = wsa881x_resource_acquire(codec, false); - if (ret) - dev_err_ratelimited(codec->dev, - "%s: resource release fail\n", __func__); - - return ret; -} - -static int wsa881x_probe(struct snd_soc_codec *codec) -{ - struct i2c_client *client; - int ret = 0; - int wsa881x_index = 0; - struct snd_soc_dapm_context *dapm = &codec->dapm; - char *widget_name = NULL; - struct snd_soc_card *card = codec->component.card; - struct snd_soc_codec_conf *codec_conf = card->codec_conf; - - client = dev_get_drvdata(codec->dev); - ret = wsa881x_i2c_get_client_index(client, &wsa881x_index); - if (ret != 0) { - dev_err(&client->dev, "%s: I2C get codec I2C\n" - "client failed\n", __func__); - return ret; - } - mutex_init(&wsa_pdata[wsa881x_index].bg_lock); - mutex_init(&wsa_pdata[wsa881x_index].res_lock); - snprintf(wsa_pdata[wsa881x_index].tz_pdata.name, 100, "%s", - wsa_tz_names[wsa881x_index]); - wsa_pdata[wsa881x_index].codec = codec; - wsa_pdata[wsa881x_index].spk_pa_gain = SPK_GAIN_12DB; - wsa_pdata[wsa881x_index].codec = codec; - wsa_pdata[wsa881x_index].tz_pdata.codec = codec; - wsa_pdata[wsa881x_index].tz_pdata.wsa_temp_reg_read = - wsa881x_temp_reg_read; - snd_soc_codec_set_drvdata(codec, &wsa_pdata[wsa881x_index]); - wsa881x_init_thermal(&wsa_pdata[wsa881x_index].tz_pdata); - INIT_DELAYED_WORK(&wsa_pdata[wsa881x_index].ocp_ctl_work, - wsa881x_ocp_ctl_work); - - if (codec_conf->name_prefix) { - widget_name = kcalloc(WIDGET_NAME_MAX_SIZE, sizeof(char), - GFP_KERNEL); - if (!widget_name) - return -ENOMEM; - - snprintf(widget_name, WIDGET_NAME_MAX_SIZE, - "%s WSA_SPKR", codec_conf->name_prefix); - snd_soc_dapm_ignore_suspend(dapm, widget_name); - snprintf(widget_name, WIDGET_NAME_MAX_SIZE, - "%s WSA_IN", codec_conf->name_prefix); - snd_soc_dapm_ignore_suspend(dapm, widget_name); - kfree(widget_name); - } else { - snd_soc_dapm_ignore_suspend(dapm, "WSA_SPKR"); - snd_soc_dapm_ignore_suspend(dapm, "WSA_IN"); - } - - snd_soc_dapm_sync(dapm); - return 0; -} - -static int wsa881x_remove(struct snd_soc_codec *codec) -{ - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - - if (wsa881x->tz_pdata.tz_dev) - wsa881x_deinit_thermal(wsa881x->tz_pdata.tz_dev); - - mutex_destroy(&wsa881x->bg_lock); - mutex_destroy(&wsa881x->res_lock); - return 0; -} - -static struct snd_soc_codec_driver soc_codec_dev_wsa881x = { - .probe = wsa881x_probe, - .remove = wsa881x_remove, - - .read = wsa881x_i2c_read, - .write = wsa881x_i2c_write, - - .reg_cache_size = WSA881X_CACHE_SIZE, - .reg_cache_default = wsa881x_ana_reg_defaults, - .reg_word_size = 1, - - .component_driver = { - .controls = wsa881x_snd_controls, - .num_controls = ARRAY_SIZE(wsa881x_snd_controls), - .dapm_widgets = wsa881x_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(wsa881x_dapm_widgets), - .dapm_routes = wsa881x_audio_map, - .num_dapm_routes = ARRAY_SIZE(wsa881x_audio_map), - }, -}; - -static int wsa881x_reset(struct wsa881x_pdata *pdata, bool enable) -{ - int ret = 0; - - /* - * shutdown the GPIOs WSA_EN, WSA_MCLK, regulators - * and restore defaults in soc cache when shutdown. - * Enable regulators, GPIOs WSA_MCLK, WSA_EN when powerup. - */ - if (enable) { - if (pdata->wsa_active) - return 0; - ret = msm_gpioset_activate(CLIENT_WSA_BONGO_1, "wsa_reset"); - if (ret) { - pr_err("%s: gpio set cannot be activated %s\n", - __func__, "wsa_reset"); - return ret; - } - ret = msm_gpioset_suspend(CLIENT_WSA_BONGO_1, "wsa_reset"); - if (ret) { - pr_err("%s: gpio set cannot be suspended(powerup) %s\n", - __func__, "wsa_reset"); - return ret; - } - ret = msm_gpioset_activate(CLIENT_WSA_BONGO_1, "wsa_reset"); - if (ret) { - pr_err("%s: gpio set cannot be activated %s\n", - __func__, "wsa_reset"); - return ret; - } - pdata->wsa_active = true; - } else { - if (!pdata->wsa_active) - return 0; - ret = msm_gpioset_suspend(CLIENT_WSA_BONGO_1, "wsa_reset"); - if (ret) { - pr_err("%s: gpio set cannot be suspended %s\n", - __func__, "wsa_reset"); - return ret; - } - pdata->wsa_active = false; - } - return ret; -} - -int wsa881x_get_client_index(void) -{ - return wsa881x_i2c_addr; -} -EXPORT_SYMBOL(wsa881x_get_client_index); - -int wsa881x_get_probing_count(void) -{ - return wsa881x_probing_count; -} -EXPORT_SYMBOL(wsa881x_get_probing_count); - -int wsa881x_get_presence_count(void) -{ - return wsa881x_presence_count; -} -EXPORT_SYMBOL(wsa881x_get_presence_count); - -int wsa881x_set_mclk_callback( - int (*enable_mclk_callback)(struct snd_soc_card *, bool)) -{ - int i; - - for (i = 0; i < MAX_WSA881X_DEVICE; i++) { - if (wsa_pdata[i].status == WSA881X_STATUS_I2C) - wsa_pdata[i].enable_mclk = enable_mclk_callback; - } - return 0; -} -EXPORT_SYMBOL(wsa881x_set_mclk_callback); - -static int check_wsa881x_presence(struct i2c_client *client) -{ - int ret = 0; - int wsa881x_index = 0; - - ret = wsa881x_i2c_get_client_index(client, &wsa881x_index); - if (ret != 0) { - dev_err(&client->dev, "%s: I2C get codec I2C\n" - "client failed\n", __func__); - return ret; - } - ret = wsa881x_i2c_read_device(&wsa_pdata[wsa881x_index], - WSA881X_CDC_RST_CTL); - if (ret < 0) { - dev_err(&client->dev, "failed to read wsa881x with addr %x\n", - client->addr); - return ret; - } - ret = wsa881x_i2c_write_device(&wsa_pdata[wsa881x_index], - WSA881X_CDC_RST_CTL, 0x01); - if (ret < 0) { - dev_err(&client->dev, "failed write addr %x reg:0x5 val:0x1\n", - client->addr); - return ret; - } - /* allow 20ms before trigger next write to verify WSA881x presence */ - msleep(20); - ret = wsa881x_i2c_write_device(&wsa_pdata[wsa881x_index], - WSA881X_CDC_RST_CTL, 0x00); - if (ret < 0) { - dev_err(&client->dev, "failed write addr %x reg:0x5 val:0x0\n", - client->addr); - return ret; - } - return ret; -} - -static int wsa881x_populate_dt_pdata(struct device *dev) -{ - int ret = 0; - - /* reading the gpio configurations from dtsi file */ - if (!pinctrl_init) { - ret = msm_gpioset_initialize(CLIENT_WSA_BONGO_1, dev); - if (ret < 0) { - dev_err(dev, - "%s: error reading dtsi files%d\n", __func__, ret); - goto err; - } - pinctrl_init = true; - } -err: - return ret; -} - -static int wsa881x_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - int ret = 0; - int wsa881x_index = 0; - struct wsa881x_pdata *pdata = NULL; - - ret = wsa881x_i2c_get_client_index(client, &wsa881x_index); - if (ret != 0) { - dev_err(&client->dev, "%s: I2C get codec I2C\n" - "client failed\n", __func__); - return ret; - } - - pdata = &wsa_pdata[wsa881x_index]; - - if ((client->addr == WSA881X_I2C_SPK0_SLAVE1_ADDR || - client->addr == WSA881X_I2C_SPK1_SLAVE1_ADDR) && - (pdata->status == WSA881X_STATUS_PROBING)) - return ret; - - if (pdata->status == WSA881X_STATUS_I2C) { - dev_dbg(&client->dev, "%s:probe for other slaves\n" - "devices of codec I2C slave Addr = %x\n", - __func__, client->addr); - - dev_dbg(&client->dev, "%s:wsa_idx = %d SLAVE = %d\n", - __func__, wsa881x_index, WSA881X_ANALOG_SLAVE); - pdata->regmap[WSA881X_ANALOG_SLAVE] = - devm_regmap_init_i2c( - client, - &wsa881x_ana_regmap_config[WSA881X_ANALOG_SLAVE]); - regcache_cache_bypass(pdata->regmap[WSA881X_ANALOG_SLAVE], - true); - if (IS_ERR(pdata->regmap[WSA881X_ANALOG_SLAVE])) { - ret = PTR_ERR(pdata->regmap[WSA881X_ANALOG_SLAVE]); - dev_err(&client->dev, - "%s: regmap_init failed %d\n", - __func__, ret); - } - client->dev.platform_data = pdata; - i2c_set_clientdata(client, pdata); - pdata->client[WSA881X_ANALOG_SLAVE] = client; - if (pdata->version == WSA881X_2_0) - wsa881x_update_regmap_2_0( - pdata->regmap[WSA881X_ANALOG_SLAVE], - WSA881X_ANALOG_SLAVE); - - return ret; - } else if (pdata->status == WSA881X_STATUS_PROBING) { - pdata->index = wsa881x_index; - if (client->dev.of_node) { - dev_dbg(&client->dev, "%s:Platform data\n" - "from device tree\n", __func__); - ret = wsa881x_populate_dt_pdata(&client->dev); - if (ret < 0) { - dev_err(&client->dev, - "%s: Fail to obtain pdata from device tree\n", - __func__); - ret = -EINVAL; - goto err; - } - client->dev.platform_data = pdata; - } else { - dev_dbg(&client->dev, "%s:Platform data from\n" - "board file\n", __func__); - pdata = client->dev.platform_data; - } - if (!pdata) { - dev_dbg(&client->dev, "no platform data?\n"); - ret = -EINVAL; - goto err; - } - i2c_set_clientdata(client, pdata); - dev_set_drvdata(&client->dev, client); - - pdata->regmap[WSA881X_DIGITAL_SLAVE] = - devm_regmap_init_i2c( - client, - &wsa881x_ana_regmap_config[WSA881X_DIGITAL_SLAVE]); - regcache_cache_bypass(pdata->regmap[WSA881X_DIGITAL_SLAVE], - true); - if (IS_ERR(pdata->regmap[WSA881X_DIGITAL_SLAVE])) { - ret = PTR_ERR(pdata->regmap[WSA881X_DIGITAL_SLAVE]); - dev_err(&client->dev, "%s: regmap_init failed %d\n", - __func__, ret); - goto err; - } - /* bus reset sequence */ - ret = wsa881x_reset(pdata, true); - if (ret < 0) { - dev_err(&client->dev, "%s: WSA enable Failed %d\n", - __func__, ret); - goto err; - } - pdata->client[WSA881X_DIGITAL_SLAVE] = client; - pdata->regmap_flag = true; - ret = check_wsa881x_presence(client); - if (ret < 0) { - dev_err(&client->dev, - "failed to ping wsa with addr:%x, ret = %d\n", - client->addr, ret); - wsa881x_probing_count++; - goto err1; - } - pdata->version = wsa881x_i2c_read_device(pdata, - WSA881X_CHIP_ID1); - pr_debug("%s: wsa881x version: %d\n", __func__, pdata->version); - if (pdata->version == WSA881X_2_0) { - wsa881x_update_reg_defaults_2_0(); - wsa881x_update_regmap_2_0( - pdata->regmap[WSA881X_DIGITAL_SLAVE], - WSA881X_DIGITAL_SLAVE); - } - wsa881x_presence_count++; - wsa881x_probing_count++; - ret = snd_soc_register_codec(&client->dev, - &soc_codec_dev_wsa881x, - NULL, 0); - if (ret < 0) - goto err1; - pdata->status = WSA881X_STATUS_I2C; - } -err1: - wsa881x_reset(pdata, false); -err: - return 0; -} - -static int wsa881x_i2c_remove(struct i2c_client *client) -{ - struct wsa881x_pdata *wsa881x = i2c_get_clientdata(client); - - snd_soc_unregister_codec(&client->dev); - i2c_set_clientdata(client, NULL); - kfree(wsa881x); - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int wsa881x_i2c_suspend(struct device *dev) -{ - pr_debug("%s: system suspend\n", __func__); - return 0; -} - -static int wsa881x_i2c_resume(struct device *dev) -{ - pr_debug("%s: system resume\n", __func__); - return 0; -} - -static const struct dev_pm_ops wsa881x_i2c_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(wsa881x_i2c_suspend, wsa881x_i2c_resume) -}; -#endif /* CONFIG_PM_SLEEP */ - -static const struct i2c_device_id wsa881x_i2c_id[] = { - {"wsa881x-i2c-dev", WSA881X_I2C_SPK0_SLAVE0_ADDR}, - {"wsa881x-i2c-dev", WSA881X_I2C_SPK0_SLAVE1_ADDR}, - {"wsa881x-i2c-dev", WSA881X_I2C_SPK1_SLAVE0_ADDR}, - {"wsa881x-i2c-dev", WSA881X_I2C_SPK1_SLAVE1_ADDR}, - {} -}; - -MODULE_DEVICE_TABLE(i2c, wsa881x_i2c_id); - - -static const struct of_device_id msm_match_table[] = { - {.compatible = "qcom,wsa881x-i2c-codec"}, - {} -}; -MODULE_DEVICE_TABLE(of, msm_match_table); - -static struct i2c_driver wsa881x_codec_driver = { - .driver = { - .name = "wsa881x-i2c-codec", - .owner = THIS_MODULE, -#ifdef CONFIG_PM_SLEEP - .pm = &wsa881x_i2c_pm_ops, -#endif - .of_match_table = msm_match_table, - }, - .id_table = wsa881x_i2c_id, - .probe = wsa881x_i2c_probe, - .remove = wsa881x_i2c_remove, -}; - -static int __init wsa881x_codec_init(void) -{ - int i = 0; - - for (i = 0; i < MAX_WSA881X_DEVICE; i++) - wsa_pdata[i].status = WSA881X_STATUS_PROBING; - return i2c_add_driver(&wsa881x_codec_driver); -} -module_init(wsa881x_codec_init); - -static void __exit wsa881x_codec_exit(void) -{ - i2c_del_driver(&wsa881x_codec_driver); -} - -module_exit(wsa881x_codec_exit); - -MODULE_DESCRIPTION("WSA881x Codec driver"); -MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/wsa881x-analog.h b/asoc/codecs/wsa881x-analog.h deleted file mode 100644 index a2ef2a284c..0000000000 --- a/asoc/codecs/wsa881x-analog.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright (c) 2015, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * 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 _WSA881X_H -#define _WSA881X_H - -#include -#include "wsa881x-registers-analog.h" -#include - -#define WSA881X_I2C_SPK0_SLAVE0_ADDR 0x0E -#define WSA881X_I2C_SPK0_SLAVE1_ADDR 0x44 -#define WSA881X_I2C_SPK1_SLAVE0_ADDR 0x0F -#define WSA881X_I2C_SPK1_SLAVE1_ADDR 0x45 - -#define WSA881X_I2C_SPK0_SLAVE0 0 -#define WSA881X_I2C_SPK1_SLAVE0 1 -#define MAX_WSA881X_DEVICE 2 -#define WSA881X_DIGITAL_SLAVE 0 -#define WSA881X_ANALOG_SLAVE 1 - -enum { - WSA881X_1_X = 0, - WSA881X_2_0, -}; - -#define WSA881X_IS_2_0(ver) \ - ((ver == WSA881X_2_0) ? 1 : 0) - -extern const u8 wsa881x_ana_reg_readable[WSA881X_CACHE_SIZE]; -extern struct reg_default wsa881x_ana_reg_defaults[WSA881X_CACHE_SIZE]; -extern struct regmap_config wsa881x_ana_regmap_config[2]; -int wsa881x_get_client_index(void); -int wsa881x_get_probing_count(void); -int wsa881x_get_presence_count(void); -int wsa881x_set_mclk_callback( - int (*enable_mclk_callback)(struct snd_soc_card *, bool)); -void wsa881x_update_reg_defaults_2_0(void); -void wsa881x_update_regmap_2_0(struct regmap *regmap, int flag); - -#endif /* _WSA881X_H */ diff --git a/asoc/codecs/wsa881x-irq.c b/asoc/codecs/wsa881x-irq.c deleted file mode 100644 index 9afbd92b8f..0000000000 --- a/asoc/codecs/wsa881x-irq.c +++ /dev/null @@ -1,610 +0,0 @@ -/* Copyright (c) 2015, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "wsa881x-irq.h" -#include "wsa881x-registers-analog.h" - -#define BYTE_BIT_MASK(nr) (1UL << ((nr) % BITS_PER_BYTE)) -#define BIT_BYTE(nr) ((nr) / BITS_PER_BYTE) - - -#define WSA_MAX_NUM_IRQS 8 - -#ifndef NO_IRQ -#define NO_IRQ (-1) -#endif - -static int virq_to_phyirq( - struct wsa_resource *wsa_res, int virq); -static int phyirq_to_virq( - struct wsa_resource *wsa_res, int irq); -static unsigned int wsa_irq_get_upstream_irq( - struct wsa_resource *wsa_res); -static void wsa_irq_put_upstream_irq( - struct wsa_resource *wsa_res); -static int wsa_map_irq( - struct wsa_resource *wsa_res, int irq); - -static struct snd_soc_codec *ptr_codec; - -/** - * wsa_set_codec() - to update codec pointer - * @codec: codec pointer. - * - * To update the codec pointer, which is used to read/write - * wsa register. - * - * Return: void. - */ -void wsa_set_codec(struct snd_soc_codec *codec) -{ - if (codec == NULL) { - pr_err("%s: codec pointer is NULL\n", __func__); - ptr_codec = NULL; - return; - } - ptr_codec = codec; - /* Initialize interrupt mask and level registers */ - snd_soc_write(codec, WSA881X_INTR_LEVEL, 0x8F); - snd_soc_write(codec, WSA881X_INTR_MASK, 0x8F); -} - -static void wsa_irq_lock(struct irq_data *data) -{ - struct wsa_resource *wsa_res = - irq_data_get_irq_chip_data(data); - - if (wsa_res == NULL) { - pr_err("%s: wsa_res pointer is NULL\n", __func__); - return; - } - mutex_lock(&wsa_res->irq_lock); -} - -static void wsa_irq_sync_unlock(struct irq_data *data) -{ - struct wsa_resource *wsa_res = - irq_data_get_irq_chip_data(data); - - if (wsa_res == NULL) { - pr_err("%s: wsa_res pointer is NULL\n", __func__); - return; - } - if (wsa_res->codec == NULL) { - pr_err("%s: codec pointer not registered\n", __func__); - if (ptr_codec == NULL) { - pr_err("%s: did not receive valid codec pointer\n", - __func__); - goto unlock; - } else { - wsa_res->codec = ptr_codec; - } - } - - /* - * If there's been a change in the mask write it back - * to the hardware. - */ - if (wsa_res->irq_masks_cur != - wsa_res->irq_masks_cache) { - - wsa_res->irq_masks_cache = - wsa_res->irq_masks_cur; - snd_soc_write(wsa_res->codec, - WSA881X_INTR_MASK, - wsa_res->irq_masks_cur); - } -unlock: - mutex_unlock(&wsa_res->irq_lock); -} - -static void wsa_irq_enable(struct irq_data *data) -{ - struct wsa_resource *wsa_res = - irq_data_get_irq_chip_data(data); - int wsa_irq; - - if (wsa_res == NULL) { - pr_err("%s: wsa_res pointer is NULL\n", __func__); - return; - } - wsa_irq = virq_to_phyirq(wsa_res, data->irq); - pr_debug("%s: wsa_irq = %d\n", __func__, wsa_irq); - wsa_res->irq_masks_cur &= - ~(BYTE_BIT_MASK(wsa_irq)); -} - -static void wsa_irq_disable(struct irq_data *data) -{ - struct wsa_resource *wsa_res = - irq_data_get_irq_chip_data(data); - int wsa_irq; - - if (wsa_res == NULL) { - pr_err("%s: wsa_res pointer is NULL\n", __func__); - return; - } - wsa_irq = virq_to_phyirq(wsa_res, data->irq); - pr_debug("%s: wsa_irq = %d\n", __func__, wsa_irq); - wsa_res->irq_masks_cur - |= BYTE_BIT_MASK(wsa_irq); -} - -static void wsa_irq_ack(struct irq_data *data) -{ - int wsa_irq = 0; - struct wsa_resource *wsa_res = - irq_data_get_irq_chip_data(data); - - if (wsa_res == NULL) { - pr_err("%s: wsa_res is NULL\n", __func__); - return; - } - wsa_irq = virq_to_phyirq(wsa_res, data->irq); - pr_debug("%s: IRQ_ACK called for WCD9XXX IRQ: %d\n", - __func__, wsa_irq); -} - -static void wsa_irq_mask(struct irq_data *d) -{ - /* do nothing but required as linux calls irq_mask without NULL check */ -} - -static struct irq_chip wsa_irq_chip = { - .name = "wsa", - .irq_bus_lock = wsa_irq_lock, - .irq_bus_sync_unlock = wsa_irq_sync_unlock, - .irq_disable = wsa_irq_disable, - .irq_enable = wsa_irq_enable, - .irq_mask = wsa_irq_mask, - .irq_ack = wsa_irq_ack, -}; - -static irqreturn_t wsa_irq_thread(int irq, void *data) -{ - struct wsa_resource *wsa_res = data; - int i; - u8 status; - - if (wsa_res == NULL) { - pr_err("%s: wsa_res is NULL\n", __func__); - return IRQ_HANDLED; - } - if (wsa_res->codec == NULL) { - pr_err("%s: codec pointer not registered\n", __func__); - if (ptr_codec == NULL) { - pr_err("%s: did not receive valid codec pointer\n", - __func__); - return IRQ_HANDLED; - } - wsa_res->codec = ptr_codec; - } - status = snd_soc_read(wsa_res->codec, WSA881X_INTR_STATUS); - /* Apply masking */ - status &= ~wsa_res->irq_masks_cur; - - for (i = 0; i < wsa_res->num_irqs; i++) { - if (status & BYTE_BIT_MASK(i)) { - mutex_lock(&wsa_res->nested_irq_lock); - handle_nested_irq(phyirq_to_virq(wsa_res, i)); - mutex_unlock(&wsa_res->nested_irq_lock); - } - } - - return IRQ_HANDLED; -} - -/** - * wsa_free_irq() - to free an interrupt - * @irq: interrupt number. - * @data: pointer to wsa resource. - * - * To free already requested interrupt. - * - * Return: void. - */ -void wsa_free_irq(int irq, void *data) -{ - struct wsa_resource *wsa_res = data; - - if (wsa_res == NULL) { - pr_err("%s: wsa_res is NULL\n", __func__); - return; - } - free_irq(phyirq_to_virq(wsa_res, irq), data); -} - -/** - * wsa_enable_irq() - to enable an interrupt - * @wsa_res: pointer to wsa resource. - * @irq: interrupt number. - * - * This function is to enable an interrupt. - * - * Return: void. - */ -void wsa_enable_irq(struct wsa_resource *wsa_res, int irq) -{ - if (wsa_res == NULL) { - pr_err("%s: wsa_res is NULL\n", __func__); - return; - } - enable_irq(phyirq_to_virq(wsa_res, irq)); -} - -/** - * wsa_disable_irq() - to disable an interrupt - * @wsa_res: pointer to wsa resource. - * @irq: interrupt number. - * - * To disable an interrupt without waiting for executing - * handler to complete. - * - * Return: void. - */ -void wsa_disable_irq(struct wsa_resource *wsa_res, int irq) -{ - if (wsa_res == NULL) { - pr_err("%s: wsa_res is NULL\n", __func__); - return; - } - disable_irq_nosync(phyirq_to_virq(wsa_res, irq)); -} - -/** - * wsa_disable_irq_sync() - to disable an interrupt - * @wsa_res: pointer to wsa resource. - * @irq: interrupt number. - * - * To disable an interrupt, wait for executing IRQ - * handler to complete. - * - * Return: void. - */ -void wsa_disable_irq_sync( - struct wsa_resource *wsa_res, int irq) -{ - if (wsa_res == NULL) { - pr_err("%s: wsa_res is NULL\n", __func__); - return; - } - disable_irq(phyirq_to_virq(wsa_res, irq)); -} - -static int wsa_irq_setup_downstream_irq(struct wsa_resource *wsa_res) -{ - int irq, virq, ret; - - if (wsa_res == NULL) { - pr_err("%s: wsa_res is NULL\n", __func__); - return -EINVAL; - } - pr_debug("%s: enter\n", __func__); - - for (irq = 0; irq < wsa_res->num_irqs; irq++) { - /* Map OF irq */ - virq = wsa_map_irq(wsa_res, irq); - pr_debug("%s: irq %d -> %d\n", __func__, irq, virq); - if (virq == NO_IRQ) { - pr_err("%s, No interrupt specifier for irq %d\n", - __func__, irq); - return NO_IRQ; - } - - ret = irq_set_chip_data(virq, wsa_res); - if (ret) { - pr_err("%s: Failed to configure irq %d (%d)\n", - __func__, irq, ret); - return ret; - } - - if (wsa_res->irq_level_high[irq]) - irq_set_chip_and_handler(virq, &wsa_irq_chip, - handle_level_irq); - else - irq_set_chip_and_handler(virq, &wsa_irq_chip, - handle_edge_irq); - - irq_set_nested_thread(virq, 1); - } - - pr_debug("%s: leave\n", __func__); - - return 0; -} - -static int wsa_irq_init(struct wsa_resource *wsa_res) -{ - int i, ret; - - if (wsa_res == NULL) { - pr_err("%s: wsa_res is NULL\n", __func__); - return -EINVAL; - } - mutex_init(&wsa_res->irq_lock); - mutex_init(&wsa_res->nested_irq_lock); - - wsa_res->irq = wsa_irq_get_upstream_irq(wsa_res); - if (!wsa_res->irq) { - pr_warn("%s: irq driver is not yet initialized\n", __func__); - mutex_destroy(&wsa_res->irq_lock); - mutex_destroy(&wsa_res->nested_irq_lock); - return -EPROBE_DEFER; - } - pr_debug("%s: probed irq %d\n", __func__, wsa_res->irq); - - /* Setup downstream IRQs */ - ret = wsa_irq_setup_downstream_irq(wsa_res); - if (ret) { - pr_err("%s: Failed to setup downstream IRQ\n", __func__); - goto fail_irq_init; - } - - /* mask all the interrupts */ - for (i = 0; i < wsa_res->num_irqs; i++) { - wsa_res->irq_masks_cur |= BYTE_BIT_MASK(i); - wsa_res->irq_masks_cache |= BYTE_BIT_MASK(i); - } - - ret = request_threaded_irq(wsa_res->irq, NULL, wsa_irq_thread, - IRQF_TRIGGER_HIGH | IRQF_ONESHOT, - "wsa", wsa_res); - if (ret != 0) { - dev_err(wsa_res->dev, "Failed to request IRQ %d: %d\n", - wsa_res->irq, ret); - } else { - ret = enable_irq_wake(wsa_res->irq); - if (ret) { - dev_err(wsa_res->dev, - "Failed to set wake interrupt on IRQ %d: %d\n", - wsa_res->irq, ret); - free_irq(wsa_res->irq, wsa_res); - } - } - - if (ret) - goto fail_irq_init; - - return ret; - -fail_irq_init: - dev_err(wsa_res->dev, - "%s: Failed to init wsa irq\n", __func__); - wsa_irq_put_upstream_irq(wsa_res); - mutex_destroy(&wsa_res->irq_lock); - mutex_destroy(&wsa_res->nested_irq_lock); - return ret; -} - -/** - * wsa_request_irq() - to request/register an interrupt - * @wsa_res: pointer to wsa_resource. - * @irq: interrupt number. - * @handler: interrupt handler function pointer. - * @name: interrupt name. - * @data: device info. - * - * Convert physical irq to virtual irq and then - * reguest for threaded handler. - * - * Return: Retuns success/failure. - */ -int wsa_request_irq(struct wsa_resource *wsa_res, - int irq, irq_handler_t handler, - const char *name, void *data) -{ - int virq; - - if (wsa_res == NULL) { - pr_err("%s: wsa_res is NULL\n", __func__); - return -EINVAL; - } - virq = phyirq_to_virq(wsa_res, irq); - - /* - * ARM needs us to explicitly flag the IRQ as valid - * and will set them noprobe when we do so. - */ -#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) - set_irq_flags(virq, IRQF_VALID); -#else - set_irq_noprobe(virq); -#endif - - return request_threaded_irq(virq, NULL, handler, IRQF_TRIGGER_RISING, - name, data); -} - -/** - * wsa_irq_exit() - to disable/clear interrupt/resources - * @wsa_res: pointer to wsa_resource - * - * Disable and free the interrupts and then release resources. - * - * Return: void. - */ -void wsa_irq_exit(struct wsa_resource *wsa_res) -{ - if (wsa_res == NULL) { - pr_err("%s: wsa_res is NULL\n", __func__); - return; - } - dev_dbg(wsa_res->dev, "%s: Cleaning up irq %d\n", __func__, - wsa_res->irq); - - if (wsa_res->irq) { - disable_irq_wake(wsa_res->irq); - free_irq(wsa_res->irq, wsa_res); - /* Release parent's of node */ - wsa_irq_put_upstream_irq(wsa_res); - } - mutex_destroy(&wsa_res->irq_lock); - mutex_destroy(&wsa_res->nested_irq_lock); -} - -static int phyirq_to_virq(struct wsa_resource *wsa_res, int offset) -{ - if (wsa_res == NULL) { - pr_err("%s: wsa_res is NULL\n", __func__); - return -EINVAL; - } - return irq_linear_revmap(wsa_res->domain, offset); -} - -static int virq_to_phyirq(struct wsa_resource *wsa_res, int virq) -{ - struct irq_data *irq_data = irq_get_irq_data(virq); - - if (unlikely(!irq_data)) { - pr_err("%s: irq_data is NULL\n", __func__); - return -EINVAL; - } - return irq_data->hwirq; -} - -static unsigned int wsa_irq_get_upstream_irq(struct wsa_resource *wsa_res) -{ - if (wsa_res == NULL) { - pr_err("%s: wsa_res is NULL\n", __func__); - return -EINVAL; - } - return wsa_res->irq; -} - -static void wsa_irq_put_upstream_irq(struct wsa_resource *wsa_res) -{ - if (wsa_res == NULL) { - pr_err("%s: wsa_res is NULL\n", __func__); - return; - } - /* Hold parent's of node */ - of_node_put(wsa_res->dev->of_node); -} - -static int wsa_map_irq(struct wsa_resource *wsa_res, int irq) -{ - if (wsa_res == NULL) { - pr_err("%s: wsa_res is NULL\n", __func__); - return -EINVAL; - } - return of_irq_to_resource(wsa_res->dev->of_node, irq, NULL); -} - -static int wsa_irq_probe(struct platform_device *pdev) -{ - int irq; - struct wsa_resource *wsa_res = NULL; - int ret = -EINVAL; - - irq = platform_get_irq_byname(pdev, "wsa-int"); - if (irq < 0) { - dev_err(&pdev->dev, "%s: Couldn't find wsa-int node(%d)\n", - __func__, irq); - return -EINVAL; - } - pr_debug("%s: node %s\n", __func__, pdev->name); - wsa_res = kzalloc(sizeof(*wsa_res), GFP_KERNEL); - if (!wsa_res) { - pr_err("%s: could not allocate memory\n", __func__); - return -ENOMEM; - } - /* - * wsa interrupt controller supports N to N irq mapping with - * single cell binding with irq numbers(offsets) only. - * Use irq_domain_simple_ops that has irq_domain_simple_map and - * irq_domain_xlate_onetwocell. - */ - wsa_res->dev = &pdev->dev; - wsa_res->domain = irq_domain_add_linear(wsa_res->dev->of_node, - WSA_MAX_NUM_IRQS, &irq_domain_simple_ops, - wsa_res); - if (!wsa_res->domain) { - dev_err(&pdev->dev, "%s: domain is NULL\n", __func__); - ret = -ENOMEM; - goto err; - } - wsa_res->dev = &pdev->dev; - - dev_dbg(&pdev->dev, "%s: virq = %d\n", __func__, irq); - wsa_res->irq = irq; - wsa_res->num_irq_regs = 1; - wsa_res->num_irqs = WSA_NUM_IRQS; - ret = wsa_irq_init(wsa_res); - if (ret < 0) { - dev_err(&pdev->dev, "%s: failed to do irq init %d\n", - __func__, ret); - goto err; - } - - return ret; -err: - kfree(wsa_res); - return ret; -} - -static int wsa_irq_remove(struct platform_device *pdev) -{ - struct irq_domain *domain; - struct wsa_resource *data; - - domain = irq_find_host(pdev->dev.of_node); - if (unlikely(!domain)) { - pr_err("%s: domain is NULL\n", __func__); - return -EINVAL; - } - data = (struct wsa_resource *)domain->host_data; - data->irq = 0; - - return 0; -} - -static const struct of_device_id of_match[] = { - { .compatible = "qcom,wsa-irq" }, - { } -}; - -static struct platform_driver wsa_irq_driver = { - .probe = wsa_irq_probe, - .remove = wsa_irq_remove, - .driver = { - .name = "wsa_intc", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(of_match), - }, -}; - -static int wsa_irq_drv_init(void) -{ - return platform_driver_register(&wsa_irq_driver); -} -subsys_initcall(wsa_irq_drv_init); - -static void wsa_irq_drv_exit(void) -{ - platform_driver_unregister(&wsa_irq_driver); -} -module_exit(wsa_irq_drv_exit); - -MODULE_DESCRIPTION("WSA881x IRQ driver"); -MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/wsa881x-irq.h b/asoc/codecs/wsa881x-irq.h deleted file mode 100644 index 270eb917a6..0000000000 --- a/asoc/codecs/wsa881x-irq.h +++ /dev/null @@ -1,82 +0,0 @@ -/* Copyright (c) 2015, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * 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 __WSA881X_IRQ_H__ -#define __WSA881X_IRQ_H__ - -#include -#include -#include - -/** - * enum wsa_interrupts - wsa interrupt number - * @WSA_INT_SAF2WAR: Temp irq interrupt, from safe state to warning state. - * @WSA_INT_WAR2SAF: Temp irq interrupt, from warning state to safe state. - * @WSA_INT_DISABLE: Disable Temp sensor interrupts. - * @WSA_INT_OCP: OCP interrupt. - * @WSA_INT_CLIP: CLIP detect interrupt. - * @WSA_NUM_IRQS: MAX Interrupt number. - * - * WSA IRQ Interrupt numbers. - */ -enum wsa_interrupts { - WSA_INT_SAF2WAR = 0, - WSA_INT_WAR2SAF, - WSA_INT_DISABLE, - WSA_INT_OCP, - WSA_INT_CLIP, - WSA_NUM_IRQS, -}; - -/** - * struct wsa_resource - the basic wsa_resource structure - * @irq_lock: lock used by irq_chip functions. - * @nested_irq_lock: lock used while handling nested interrupts. - * @irq: interrupt number. - * @irq_masks_cur: current mask value to be written to mask registers. - * @irq_masks_cache: cached mask value. - * @num_irqs: number of supported interrupts. - * @num_irq_regs: number of irq registers. - * @parent: parent pointer. - * @dev: device pointer. - * @domain: irq domain pointer. - * codec: codec pointer. - * - * Contains required members used in wsa irq driver. - */ - -struct wsa_resource { - struct mutex irq_lock; - struct mutex nested_irq_lock; - unsigned int irq; - u8 irq_masks_cur; - u8 irq_masks_cache; - bool irq_level_high[8]; - int num_irqs; - int num_irq_regs; - void *parent; - struct device *dev; - struct irq_domain *domain; - struct snd_soc_codec *codec; -}; - -void wsa_set_codec(struct snd_soc_codec *codec); -void wsa_free_irq(int irq, void *data); -void wsa_enable_irq(struct wsa_resource *wsa_res, int irq); -void wsa_disable_irq(struct wsa_resource *wsa_res, int irq); -void wsa_disable_irq_sync(struct wsa_resource *wsa_res, int irq); -int wsa_request_irq(struct wsa_resource *wsa_res, - int irq, irq_handler_t handler, - const char *name, void *data); - -void wsa_irq_exit(struct wsa_resource *wsa_res); - -#endif /* __WSA881X_IRQ_H__ */ diff --git a/asoc/codecs/wsa881x-registers-analog.h b/asoc/codecs/wsa881x-registers-analog.h deleted file mode 100644 index a5ebf8e1aa..0000000000 --- a/asoc/codecs/wsa881x-registers-analog.h +++ /dev/null @@ -1,206 +0,0 @@ -/* Copyright (c) 2015, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * 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 WSA881X_REGISTERS_H -#define WSA881X_REGISTERS_H - -#define WSA881X_DIGITAL_BASE 0x0000 -#define WSA881X_ANALOG_BASE 0x0100 - -#define WSA881X_CHIP_ID0 (WSA881X_DIGITAL_BASE+0x0000) -#define WSA881X_CHIP_ID1 (WSA881X_DIGITAL_BASE+0x0001) -#define WSA881X_CHIP_ID2 (WSA881X_DIGITAL_BASE+0x0002) -#define WSA881X_CHIP_ID3 (WSA881X_DIGITAL_BASE+0x0003) -#define WSA881X_BUS_ID (WSA881X_DIGITAL_BASE+0x0004) -#define WSA881X_CDC_RST_CTL (WSA881X_DIGITAL_BASE+0x0005) -#define WSA881X_CDC_TOP_CLK_CTL (WSA881X_DIGITAL_BASE+0x0006) -#define WSA881X_CDC_ANA_CLK_CTL (WSA881X_DIGITAL_BASE+0x0007) -#define WSA881X_CDC_DIG_CLK_CTL (WSA881X_DIGITAL_BASE+0x0008) -#define WSA881X_CLOCK_CONFIG (WSA881X_DIGITAL_BASE+0x0009) -#define WSA881X_ANA_CTL (WSA881X_DIGITAL_BASE+0x000A) -#define WSA881X_SWR_RESET_EN (WSA881X_DIGITAL_BASE+0x000B) -#define WSA881X_RESET_CTL (WSA881X_DIGITAL_BASE+0x000C) -#define WSA881X_TADC_VALUE_CTL (WSA881X_DIGITAL_BASE+0x000F) -#define WSA881X_TEMP_DETECT_CTL (WSA881X_DIGITAL_BASE+0x0010) -#define WSA881X_TEMP_MSB (WSA881X_DIGITAL_BASE+0x0011) -#define WSA881X_TEMP_LSB (WSA881X_DIGITAL_BASE+0x0012) -#define WSA881X_TEMP_CONFIG0 (WSA881X_DIGITAL_BASE+0x0013) -#define WSA881X_TEMP_CONFIG1 (WSA881X_DIGITAL_BASE+0x0014) -#define WSA881X_CDC_CLIP_CTL (WSA881X_DIGITAL_BASE+0x0015) -#define WSA881X_SDM_PDM9_LSB (WSA881X_DIGITAL_BASE+0x0016) -#define WSA881X_SDM_PDM9_MSB (WSA881X_DIGITAL_BASE+0x0017) -#define WSA881X_CDC_RX_CTL (WSA881X_DIGITAL_BASE+0x0018) -#define WSA881X_DEM_BYPASS_DATA0 (WSA881X_DIGITAL_BASE+0x0019) -#define WSA881X_DEM_BYPASS_DATA1 (WSA881X_DIGITAL_BASE+0x001A) -#define WSA881X_DEM_BYPASS_DATA2 (WSA881X_DIGITAL_BASE+0x001B) -#define WSA881X_DEM_BYPASS_DATA3 (WSA881X_DIGITAL_BASE+0x001C) -#define WSA881X_OTP_CTRL0 (WSA881X_DIGITAL_BASE+0x001D) -#define WSA881X_OTP_CTRL1 (WSA881X_DIGITAL_BASE+0x001E) -#define WSA881X_HDRIVE_CTL_GROUP1 (WSA881X_DIGITAL_BASE+0x001F) -#define WSA881X_INTR_MODE (WSA881X_DIGITAL_BASE+0x0020) -#define WSA881X_INTR_MASK (WSA881X_DIGITAL_BASE+0x0021) -#define WSA881X_INTR_STATUS (WSA881X_DIGITAL_BASE+0x0022) -#define WSA881X_INTR_CLEAR (WSA881X_DIGITAL_BASE+0x0023) -#define WSA881X_INTR_LEVEL (WSA881X_DIGITAL_BASE+0x0024) -#define WSA881X_INTR_SET (WSA881X_DIGITAL_BASE+0x0025) -#define WSA881X_INTR_TEST (WSA881X_DIGITAL_BASE+0x0026) -#define WSA881X_PDM_TEST_MODE (WSA881X_DIGITAL_BASE+0x0030) -#define WSA881X_ATE_TEST_MODE (WSA881X_DIGITAL_BASE+0x0031) -#define WSA881X_PIN_CTL_MODE (WSA881X_DIGITAL_BASE+0x0032) -#define WSA881X_PIN_CTL_OE (WSA881X_DIGITAL_BASE+0x0033) -#define WSA881X_PIN_WDATA_IOPAD (WSA881X_DIGITAL_BASE+0x0034) -#define WSA881X_PIN_STATUS (WSA881X_DIGITAL_BASE+0x0035) -#define WSA881X_DIG_DEBUG_MODE (WSA881X_DIGITAL_BASE+0x0037) -#define WSA881X_DIG_DEBUG_SEL (WSA881X_DIGITAL_BASE+0x0038) -#define WSA881X_DIG_DEBUG_EN (WSA881X_DIGITAL_BASE+0x0039) -#define WSA881X_SWR_HM_TEST1 (WSA881X_DIGITAL_BASE+0x003B) -#define WSA881X_SWR_HM_TEST2 (WSA881X_DIGITAL_BASE+0x003C) -#define WSA881X_TEMP_DETECT_DBG_CTL (WSA881X_DIGITAL_BASE+0x003D) -#define WSA881X_TEMP_DEBUG_MSB (WSA881X_DIGITAL_BASE+0x003E) -#define WSA881X_TEMP_DEBUG_LSB (WSA881X_DIGITAL_BASE+0x003F) -#define WSA881X_SAMPLE_EDGE_SEL (WSA881X_DIGITAL_BASE+0x0044) -#define WSA881X_IOPAD_CTL (WSA881X_DIGITAL_BASE+0x0045) -#define WSA881X_SPARE_0 (WSA881X_DIGITAL_BASE+0x0050) -#define WSA881X_SPARE_1 (WSA881X_DIGITAL_BASE+0x0051) -#define WSA881X_SPARE_2 (WSA881X_DIGITAL_BASE+0x0052) -#define WSA881X_OTP_REG_0 (WSA881X_DIGITAL_BASE+0x0080) -#define WSA881X_OTP_REG_1 (WSA881X_DIGITAL_BASE+0x0081) -#define WSA881X_OTP_REG_2 (WSA881X_DIGITAL_BASE+0x0082) -#define WSA881X_OTP_REG_3 (WSA881X_DIGITAL_BASE+0x0083) -#define WSA881X_OTP_REG_4 (WSA881X_DIGITAL_BASE+0x0084) -#define WSA881X_OTP_REG_5 (WSA881X_DIGITAL_BASE+0x0085) -#define WSA881X_OTP_REG_6 (WSA881X_DIGITAL_BASE+0x0086) -#define WSA881X_OTP_REG_7 (WSA881X_DIGITAL_BASE+0x0087) -#define WSA881X_OTP_REG_8 (WSA881X_DIGITAL_BASE+0x0088) -#define WSA881X_OTP_REG_9 (WSA881X_DIGITAL_BASE+0x0089) -#define WSA881X_OTP_REG_10 (WSA881X_DIGITAL_BASE+0x008A) -#define WSA881X_OTP_REG_11 (WSA881X_DIGITAL_BASE+0x008B) -#define WSA881X_OTP_REG_12 (WSA881X_DIGITAL_BASE+0x008C) -#define WSA881X_OTP_REG_13 (WSA881X_DIGITAL_BASE+0x008D) -#define WSA881X_OTP_REG_14 (WSA881X_DIGITAL_BASE+0x008E) -#define WSA881X_OTP_REG_15 (WSA881X_DIGITAL_BASE+0x008F) -#define WSA881X_OTP_REG_16 (WSA881X_DIGITAL_BASE+0x0090) -#define WSA881X_OTP_REG_17 (WSA881X_DIGITAL_BASE+0x0091) -#define WSA881X_OTP_REG_18 (WSA881X_DIGITAL_BASE+0x0092) -#define WSA881X_OTP_REG_19 (WSA881X_DIGITAL_BASE+0x0093) -#define WSA881X_OTP_REG_20 (WSA881X_DIGITAL_BASE+0x0094) -#define WSA881X_OTP_REG_21 (WSA881X_DIGITAL_BASE+0x0095) -#define WSA881X_OTP_REG_22 (WSA881X_DIGITAL_BASE+0x0096) -#define WSA881X_OTP_REG_23 (WSA881X_DIGITAL_BASE+0x0097) -#define WSA881X_OTP_REG_24 (WSA881X_DIGITAL_BASE+0x0098) -#define WSA881X_OTP_REG_25 (WSA881X_DIGITAL_BASE+0x0099) -#define WSA881X_OTP_REG_26 (WSA881X_DIGITAL_BASE+0x009A) -#define WSA881X_OTP_REG_27 (WSA881X_DIGITAL_BASE+0x009B) -#define WSA881X_OTP_REG_28 (WSA881X_DIGITAL_BASE+0x009C) -#define WSA881X_OTP_REG_29 (WSA881X_DIGITAL_BASE+0x009D) -#define WSA881X_OTP_REG_30 (WSA881X_DIGITAL_BASE+0x009E) -#define WSA881X_OTP_REG_31 (WSA881X_DIGITAL_BASE+0x009F) -#define WSA881X_OTP_REG_32 (WSA881X_DIGITAL_BASE+0x00A0) -#define WSA881X_OTP_REG_33 (WSA881X_DIGITAL_BASE+0x00A1) -#define WSA881X_OTP_REG_34 (WSA881X_DIGITAL_BASE+0x00A2) -#define WSA881X_OTP_REG_35 (WSA881X_DIGITAL_BASE+0x00A3) -#define WSA881X_OTP_REG_36 (WSA881X_DIGITAL_BASE+0x00A4) -#define WSA881X_OTP_REG_37 (WSA881X_DIGITAL_BASE+0x00A5) -#define WSA881X_OTP_REG_38 (WSA881X_DIGITAL_BASE+0x00A6) -#define WSA881X_OTP_REG_39 (WSA881X_DIGITAL_BASE+0x00A7) -#define WSA881X_OTP_REG_40 (WSA881X_DIGITAL_BASE+0x00A8) -#define WSA881X_OTP_REG_41 (WSA881X_DIGITAL_BASE+0x00A9) -#define WSA881X_OTP_REG_42 (WSA881X_DIGITAL_BASE+0x00AA) -#define WSA881X_OTP_REG_43 (WSA881X_DIGITAL_BASE+0x00AB) -#define WSA881X_OTP_REG_44 (WSA881X_DIGITAL_BASE+0x00AC) -#define WSA881X_OTP_REG_45 (WSA881X_DIGITAL_BASE+0x00AD) -#define WSA881X_OTP_REG_46 (WSA881X_DIGITAL_BASE+0x00AE) -#define WSA881X_OTP_REG_47 (WSA881X_DIGITAL_BASE+0x00AF) -#define WSA881X_OTP_REG_48 (WSA881X_DIGITAL_BASE+0x00B0) -#define WSA881X_OTP_REG_49 (WSA881X_DIGITAL_BASE+0x00B1) -#define WSA881X_OTP_REG_50 (WSA881X_DIGITAL_BASE+0x00B2) -#define WSA881X_OTP_REG_51 (WSA881X_DIGITAL_BASE+0x00B3) -#define WSA881X_OTP_REG_52 (WSA881X_DIGITAL_BASE+0x00B4) -#define WSA881X_OTP_REG_53 (WSA881X_DIGITAL_BASE+0x00B5) -#define WSA881X_OTP_REG_54 (WSA881X_DIGITAL_BASE+0x00B6) -#define WSA881X_OTP_REG_55 (WSA881X_DIGITAL_BASE+0x00B7) -#define WSA881X_OTP_REG_56 (WSA881X_DIGITAL_BASE+0x00B8) -#define WSA881X_OTP_REG_57 (WSA881X_DIGITAL_BASE+0x00B9) -#define WSA881X_OTP_REG_58 (WSA881X_DIGITAL_BASE+0x00BA) -#define WSA881X_OTP_REG_59 (WSA881X_DIGITAL_BASE+0x00BB) -#define WSA881X_OTP_REG_60 (WSA881X_DIGITAL_BASE+0x00BC) -#define WSA881X_OTP_REG_61 (WSA881X_DIGITAL_BASE+0x00BD) -#define WSA881X_OTP_REG_62 (WSA881X_DIGITAL_BASE+0x00BE) -#define WSA881X_OTP_REG_63 (WSA881X_DIGITAL_BASE+0x00BF) -/* Analog Register address space */ -#define WSA881X_BIAS_REF_CTRL (WSA881X_ANALOG_BASE+0x0000) -#define WSA881X_BIAS_TEST (WSA881X_ANALOG_BASE+0x0001) -#define WSA881X_BIAS_BIAS (WSA881X_ANALOG_BASE+0x0002) -#define WSA881X_TEMP_OP (WSA881X_ANALOG_BASE+0x0003) -#define WSA881X_TEMP_IREF_CTRL (WSA881X_ANALOG_BASE+0x0004) -#define WSA881X_TEMP_ISENS_CTRL (WSA881X_ANALOG_BASE+0x0005) -#define WSA881X_TEMP_CLK_CTRL (WSA881X_ANALOG_BASE+0x0006) -#define WSA881X_TEMP_TEST (WSA881X_ANALOG_BASE+0x0007) -#define WSA881X_TEMP_BIAS (WSA881X_ANALOG_BASE+0x0008) -#define WSA881X_TEMP_ADC_CTRL (WSA881X_ANALOG_BASE+0x0009) -#define WSA881X_TEMP_DOUT_MSB (WSA881X_ANALOG_BASE+0x000A) -#define WSA881X_TEMP_DOUT_LSB (WSA881X_ANALOG_BASE+0x000B) -#define WSA881X_ADC_EN_MODU_V (WSA881X_ANALOG_BASE+0x0010) -#define WSA881X_ADC_EN_MODU_I (WSA881X_ANALOG_BASE+0x0011) -#define WSA881X_ADC_EN_DET_TEST_V (WSA881X_ANALOG_BASE+0x0012) -#define WSA881X_ADC_EN_DET_TEST_I (WSA881X_ANALOG_BASE+0x0013) -#define WSA881X_ADC_SEL_IBIAS (WSA881X_ANALOG_BASE+0x0014) -#define WSA881X_ADC_EN_SEL_IBIAS (WSA881X_ANALOG_BASE+0x0015) -#define WSA881X_SPKR_DRV_EN (WSA881X_ANALOG_BASE+0x001A) -#define WSA881X_SPKR_DRV_GAIN (WSA881X_ANALOG_BASE+0x001B) -#define WSA881X_SPKR_DAC_CTL (WSA881X_ANALOG_BASE+0x001C) -#define WSA881X_SPKR_DRV_DBG (WSA881X_ANALOG_BASE+0x001D) -#define WSA881X_SPKR_PWRSTG_DBG (WSA881X_ANALOG_BASE+0x001E) -#define WSA881X_SPKR_OCP_CTL (WSA881X_ANALOG_BASE+0x001F) -#define WSA881X_SPKR_CLIP_CTL (WSA881X_ANALOG_BASE+0x0020) -#define WSA881X_SPKR_BBM_CTL (WSA881X_ANALOG_BASE+0x0021) -#define WSA881X_SPKR_MISC_CTL1 (WSA881X_ANALOG_BASE+0x0022) -#define WSA881X_SPKR_MISC_CTL2 (WSA881X_ANALOG_BASE+0x0023) -#define WSA881X_SPKR_BIAS_INT (WSA881X_ANALOG_BASE+0x0024) -#define WSA881X_SPKR_PA_INT (WSA881X_ANALOG_BASE+0x0025) -#define WSA881X_SPKR_BIAS_CAL (WSA881X_ANALOG_BASE+0x0026) -#define WSA881X_SPKR_BIAS_PSRR (WSA881X_ANALOG_BASE+0x0027) -#define WSA881X_SPKR_STATUS1 (WSA881X_ANALOG_BASE+0x0028) -#define WSA881X_SPKR_STATUS2 (WSA881X_ANALOG_BASE+0x0029) -#define WSA881X_BOOST_EN_CTL (WSA881X_ANALOG_BASE+0x002A) -#define WSA881X_BOOST_CURRENT_LIMIT (WSA881X_ANALOG_BASE+0x002B) -#define WSA881X_BOOST_PS_CTL (WSA881X_ANALOG_BASE+0x002C) -#define WSA881X_BOOST_PRESET_OUT1 (WSA881X_ANALOG_BASE+0x002D) -#define WSA881X_BOOST_PRESET_OUT2 (WSA881X_ANALOG_BASE+0x002E) -#define WSA881X_BOOST_FORCE_OUT (WSA881X_ANALOG_BASE+0x002F) -#define WSA881X_BOOST_LDO_PROG (WSA881X_ANALOG_BASE+0x0030) -#define WSA881X_BOOST_SLOPE_COMP_ISENSE_FB (WSA881X_ANALOG_BASE+0x0031) -#define WSA881X_BOOST_RON_CTL (WSA881X_ANALOG_BASE+0x0032) -#define WSA881X_BOOST_LOOP_STABILITY (WSA881X_ANALOG_BASE+0x0033) -#define WSA881X_BOOST_ZX_CTL (WSA881X_ANALOG_BASE+0x0034) -#define WSA881X_BOOST_START_CTL (WSA881X_ANALOG_BASE+0x0035) -#define WSA881X_BOOST_MISC1_CTL (WSA881X_ANALOG_BASE+0x0036) -#define WSA881X_BOOST_MISC2_CTL (WSA881X_ANALOG_BASE+0x0037) -#define WSA881X_BOOST_MISC3_CTL (WSA881X_ANALOG_BASE+0x0038) -#define WSA881X_BOOST_ATEST_CTL (WSA881X_ANALOG_BASE+0x0039) -#define WSA881X_SPKR_PROT_FE_GAIN (WSA881X_ANALOG_BASE+0x003A) -#define WSA881X_SPKR_PROT_FE_CM_LDO_SET (WSA881X_ANALOG_BASE+0x003B) -#define WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1 (WSA881X_ANALOG_BASE+0x003C) -#define WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2 (WSA881X_ANALOG_BASE+0x003D) -#define WSA881X_SPKR_PROT_ATEST1 (WSA881X_ANALOG_BASE+0x003E) -#define WSA881X_SPKR_PROT_ATEST2 (WSA881X_ANALOG_BASE+0x003F) -#define WSA881X_SPKR_PROT_FE_VSENSE_VCM (WSA881X_ANALOG_BASE+0x0040) -#define WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1 (WSA881X_ANALOG_BASE+0x0041) -#define WSA881X_BONGO_RESRV_REG1 (WSA881X_ANALOG_BASE+0x0042) -#define WSA881X_BONGO_RESRV_REG2 (WSA881X_ANALOG_BASE+0x0043) -#define WSA881X_SPKR_PROT_SAR (WSA881X_ANALOG_BASE+0x0044) -#define WSA881X_SPKR_STATUS3 (WSA881X_ANALOG_BASE+0x0045) - -#define WSA881X_NUM_REGISTERS (WSA881X_SPKR_STATUS3+1) -#define WSA881X_MAX_REGISTER (WSA881X_NUM_REGISTERS-1) -#define WSA881X_CACHE_SIZE WSA881X_NUM_REGISTERS -#endif /* WSA881X_REGISTERS_H */ diff --git a/asoc/codecs/wsa881x-regmap-analog.c b/asoc/codecs/wsa881x-regmap-analog.c deleted file mode 100644 index 2bc3c9eb70..0000000000 --- a/asoc/codecs/wsa881x-regmap-analog.c +++ /dev/null @@ -1,499 +0,0 @@ -/* - * Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * 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. - */ - -#include -#include -#include "wsa881x-registers-analog.h" -#include "wsa881x-analog.h" - -struct reg_default wsa881x_ana_reg_defaults[] = { - {WSA881X_CHIP_ID0, 0x00}, - {WSA881X_CHIP_ID1, 0x00}, - {WSA881X_CHIP_ID2, 0x00}, - {WSA881X_CHIP_ID3, 0x02}, - {WSA881X_BUS_ID, 0x00}, - {WSA881X_CDC_RST_CTL, 0x00}, - {WSA881X_CDC_TOP_CLK_CTL, 0x03}, - {WSA881X_CDC_ANA_CLK_CTL, 0x00}, - {WSA881X_CDC_DIG_CLK_CTL, 0x00}, - {WSA881X_CLOCK_CONFIG, 0x00}, - {WSA881X_ANA_CTL, 0x08}, - {WSA881X_SWR_RESET_EN, 0x00}, - {WSA881X_TEMP_DETECT_CTL, 0x01}, - {WSA881X_TEMP_MSB, 0x00}, - {WSA881X_TEMP_LSB, 0x00}, - {WSA881X_TEMP_CONFIG0, 0x00}, - {WSA881X_TEMP_CONFIG1, 0x00}, - {WSA881X_CDC_CLIP_CTL, 0x03}, - {WSA881X_SDM_PDM9_LSB, 0x00}, - {WSA881X_SDM_PDM9_MSB, 0x00}, - {WSA881X_CDC_RX_CTL, 0x7E}, - {WSA881X_DEM_BYPASS_DATA0, 0x00}, - {WSA881X_DEM_BYPASS_DATA1, 0x00}, - {WSA881X_DEM_BYPASS_DATA2, 0x00}, - {WSA881X_DEM_BYPASS_DATA3, 0x00}, - {WSA881X_OTP_CTRL0, 0x00}, - {WSA881X_OTP_CTRL1, 0x00}, - {WSA881X_HDRIVE_CTL_GROUP1, 0x00}, - {WSA881X_INTR_MODE, 0x00}, - {WSA881X_INTR_MASK, 0x1F}, - {WSA881X_INTR_STATUS, 0x00}, - {WSA881X_INTR_CLEAR, 0x00}, - {WSA881X_INTR_LEVEL, 0x00}, - {WSA881X_INTR_SET, 0x00}, - {WSA881X_INTR_TEST, 0x00}, - {WSA881X_PDM_TEST_MODE, 0x00}, - {WSA881X_ATE_TEST_MODE, 0x00}, - {WSA881X_PIN_CTL_MODE, 0x00}, - {WSA881X_PIN_CTL_OE, 0x00}, - {WSA881X_PIN_WDATA_IOPAD, 0x00}, - {WSA881X_PIN_STATUS, 0x00}, - {WSA881X_DIG_DEBUG_MODE, 0x00}, - {WSA881X_DIG_DEBUG_SEL, 0x00}, - {WSA881X_DIG_DEBUG_EN, 0x00}, - {WSA881X_SWR_HM_TEST1, 0x08}, - {WSA881X_SWR_HM_TEST2, 0x00}, - {WSA881X_TEMP_DETECT_DBG_CTL, 0x00}, - {WSA881X_TEMP_DEBUG_MSB, 0x00}, - {WSA881X_TEMP_DEBUG_LSB, 0x00}, - {WSA881X_SAMPLE_EDGE_SEL, 0x0C}, - {WSA881X_SPARE_0, 0x00}, - {WSA881X_SPARE_1, 0x00}, - {WSA881X_SPARE_2, 0x00}, - {WSA881X_OTP_REG_0, 0x01}, - {WSA881X_OTP_REG_1, 0xFF}, - {WSA881X_OTP_REG_2, 0xC0}, - {WSA881X_OTP_REG_3, 0xFF}, - {WSA881X_OTP_REG_4, 0xC0}, - {WSA881X_OTP_REG_5, 0xFF}, - {WSA881X_OTP_REG_6, 0xFF}, - {WSA881X_OTP_REG_7, 0xFF}, - {WSA881X_OTP_REG_8, 0xFF}, - {WSA881X_OTP_REG_9, 0xFF}, - {WSA881X_OTP_REG_10, 0xFF}, - {WSA881X_OTP_REG_11, 0xFF}, - {WSA881X_OTP_REG_12, 0xFF}, - {WSA881X_OTP_REG_13, 0xFF}, - {WSA881X_OTP_REG_14, 0xFF}, - {WSA881X_OTP_REG_15, 0xFF}, - {WSA881X_OTP_REG_16, 0xFF}, - {WSA881X_OTP_REG_17, 0xFF}, - {WSA881X_OTP_REG_18, 0xFF}, - {WSA881X_OTP_REG_19, 0xFF}, - {WSA881X_OTP_REG_20, 0xFF}, - {WSA881X_OTP_REG_21, 0xFF}, - {WSA881X_OTP_REG_22, 0xFF}, - {WSA881X_OTP_REG_23, 0xFF}, - {WSA881X_OTP_REG_24, 0x03}, - {WSA881X_OTP_REG_25, 0x01}, - {WSA881X_OTP_REG_26, 0x03}, - {WSA881X_OTP_REG_27, 0x11}, - {WSA881X_OTP_REG_28, 0xFF}, - {WSA881X_OTP_REG_29, 0xFF}, - {WSA881X_OTP_REG_30, 0xFF}, - {WSA881X_OTP_REG_31, 0xFF}, - {WSA881X_OTP_REG_63, 0x40}, - /* WSA881x Analog registers */ - {WSA881X_BIAS_REF_CTRL, 0x6C}, - {WSA881X_BIAS_TEST, 0x16}, - {WSA881X_BIAS_BIAS, 0xF0}, - {WSA881X_TEMP_OP, 0x00}, - {WSA881X_TEMP_IREF_CTRL, 0x56}, - {WSA881X_TEMP_ISENS_CTRL, 0x47}, - {WSA881X_TEMP_CLK_CTRL, 0x87}, - {WSA881X_TEMP_TEST, 0x00}, - {WSA881X_TEMP_BIAS, 0x51}, - {WSA881X_TEMP_ADC_CTRL, 0x00}, - {WSA881X_TEMP_DOUT_MSB, 0x00}, - {WSA881X_TEMP_DOUT_LSB, 0x00}, - {WSA881X_ADC_EN_MODU_V, 0x00}, - {WSA881X_ADC_EN_MODU_I, 0x00}, - {WSA881X_ADC_EN_DET_TEST_V, 0x00}, - {WSA881X_ADC_EN_DET_TEST_I, 0x00}, - {WSA881X_ADC_SEL_IBIAS, 0x25}, - {WSA881X_ADC_EN_SEL_IBIAS, 0x10}, - {WSA881X_SPKR_DRV_EN, 0x74}, - {WSA881X_SPKR_DRV_GAIN, 0x01}, - {WSA881X_SPKR_DAC_CTL, 0x40}, - {WSA881X_SPKR_DRV_DBG, 0x15}, - {WSA881X_SPKR_PWRSTG_DBG, 0x00}, - {WSA881X_SPKR_OCP_CTL, 0xD4}, - {WSA881X_SPKR_CLIP_CTL, 0x90}, - {WSA881X_SPKR_BBM_CTL, 0x00}, - {WSA881X_SPKR_MISC_CTL1, 0x80}, - {WSA881X_SPKR_MISC_CTL2, 0x00}, - {WSA881X_SPKR_BIAS_INT, 0x56}, - {WSA881X_SPKR_PA_INT, 0x54}, - {WSA881X_SPKR_BIAS_CAL, 0xAC}, - {WSA881X_SPKR_BIAS_PSRR, 0x54}, - {WSA881X_SPKR_STATUS1, 0x00}, - {WSA881X_SPKR_STATUS2, 0x00}, - {WSA881X_BOOST_EN_CTL, 0x18}, - {WSA881X_BOOST_CURRENT_LIMIT, 0x7A}, - {WSA881X_BOOST_PS_CTL, 0xC0}, - {WSA881X_BOOST_PRESET_OUT1, 0x77}, - {WSA881X_BOOST_PRESET_OUT2, 0x70}, - {WSA881X_BOOST_FORCE_OUT, 0x0E}, - {WSA881X_BOOST_LDO_PROG, 0x16}, - {WSA881X_BOOST_SLOPE_COMP_ISENSE_FB, 0x71}, - {WSA881X_BOOST_RON_CTL, 0x0F}, - {WSA881X_BOOST_LOOP_STABILITY, 0xAD}, - {WSA881X_BOOST_ZX_CTL, 0x34}, - {WSA881X_BOOST_START_CTL, 0x23}, - {WSA881X_BOOST_MISC1_CTL, 0x80}, - {WSA881X_BOOST_MISC2_CTL, 0x00}, - {WSA881X_BOOST_MISC3_CTL, 0x00}, - {WSA881X_BOOST_ATEST_CTL, 0x00}, - {WSA881X_SPKR_PROT_FE_GAIN, 0x46}, - {WSA881X_SPKR_PROT_FE_CM_LDO_SET, 0x3B}, - {WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1, 0x8D}, - {WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2, 0x8D}, - {WSA881X_SPKR_PROT_ATEST1, 0x01}, - {WSA881X_SPKR_PROT_ATEST2, 0x00}, - {WSA881X_SPKR_PROT_FE_VSENSE_VCM, 0x8D}, - {WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1, 0x4D}, - {WSA881X_BONGO_RESRV_REG1, 0x00}, - {WSA881X_BONGO_RESRV_REG2, 0x00}, - {WSA881X_SPKR_PROT_SAR, 0x00}, - {WSA881X_SPKR_STATUS3, 0x00}, -}; - -struct reg_default wsa881x_ana_reg_defaults_0[] = { - {WSA881X_CHIP_ID0, 0x00}, - {WSA881X_CHIP_ID1, 0x00}, - {WSA881X_CHIP_ID2, 0x00}, - {WSA881X_CHIP_ID3, 0x02}, - {WSA881X_BUS_ID, 0x00}, - {WSA881X_CDC_RST_CTL, 0x00}, - {WSA881X_CDC_TOP_CLK_CTL, 0x03}, - {WSA881X_CDC_ANA_CLK_CTL, 0x00}, - {WSA881X_CDC_DIG_CLK_CTL, 0x00}, - {WSA881X_CLOCK_CONFIG, 0x00}, - {WSA881X_ANA_CTL, 0x08}, - {WSA881X_SWR_RESET_EN, 0x00}, - {WSA881X_TEMP_DETECT_CTL, 0x01}, - {WSA881X_TEMP_MSB, 0x00}, - {WSA881X_TEMP_LSB, 0x00}, - {WSA881X_TEMP_CONFIG0, 0x00}, - {WSA881X_TEMP_CONFIG1, 0x00}, - {WSA881X_CDC_CLIP_CTL, 0x03}, - {WSA881X_SDM_PDM9_LSB, 0x00}, - {WSA881X_SDM_PDM9_MSB, 0x00}, - {WSA881X_CDC_RX_CTL, 0x7E}, - {WSA881X_DEM_BYPASS_DATA0, 0x00}, - {WSA881X_DEM_BYPASS_DATA1, 0x00}, - {WSA881X_DEM_BYPASS_DATA2, 0x00}, - {WSA881X_DEM_BYPASS_DATA3, 0x00}, - {WSA881X_OTP_CTRL0, 0x00}, - {WSA881X_OTP_CTRL1, 0x00}, - {WSA881X_HDRIVE_CTL_GROUP1, 0x00}, - {WSA881X_INTR_MODE, 0x00}, - {WSA881X_INTR_MASK, 0x1F}, - {WSA881X_INTR_STATUS, 0x00}, - {WSA881X_INTR_CLEAR, 0x00}, - {WSA881X_INTR_LEVEL, 0x00}, - {WSA881X_INTR_SET, 0x00}, - {WSA881X_INTR_TEST, 0x00}, - {WSA881X_PDM_TEST_MODE, 0x00}, - {WSA881X_ATE_TEST_MODE, 0x00}, - {WSA881X_PIN_CTL_MODE, 0x00}, - {WSA881X_PIN_CTL_OE, 0x00}, - {WSA881X_PIN_WDATA_IOPAD, 0x00}, - {WSA881X_PIN_STATUS, 0x00}, - {WSA881X_DIG_DEBUG_MODE, 0x00}, - {WSA881X_DIG_DEBUG_SEL, 0x00}, - {WSA881X_DIG_DEBUG_EN, 0x00}, - {WSA881X_SWR_HM_TEST1, 0x08}, - {WSA881X_SWR_HM_TEST2, 0x00}, - {WSA881X_TEMP_DETECT_DBG_CTL, 0x00}, - {WSA881X_TEMP_DEBUG_MSB, 0x00}, - {WSA881X_TEMP_DEBUG_LSB, 0x00}, - {WSA881X_SAMPLE_EDGE_SEL, 0x0C}, - {WSA881X_SPARE_0, 0x00}, - {WSA881X_SPARE_1, 0x00}, - {WSA881X_SPARE_2, 0x00}, - {WSA881X_OTP_REG_0, 0x01}, - {WSA881X_OTP_REG_1, 0xFF}, - {WSA881X_OTP_REG_2, 0xC0}, - {WSA881X_OTP_REG_3, 0xFF}, - {WSA881X_OTP_REG_4, 0xC0}, - {WSA881X_OTP_REG_5, 0xFF}, - {WSA881X_OTP_REG_6, 0xFF}, - {WSA881X_OTP_REG_7, 0xFF}, - {WSA881X_OTP_REG_8, 0xFF}, - {WSA881X_OTP_REG_9, 0xFF}, - {WSA881X_OTP_REG_10, 0xFF}, - {WSA881X_OTP_REG_11, 0xFF}, - {WSA881X_OTP_REG_12, 0xFF}, - {WSA881X_OTP_REG_13, 0xFF}, - {WSA881X_OTP_REG_14, 0xFF}, - {WSA881X_OTP_REG_15, 0xFF}, - {WSA881X_OTP_REG_16, 0xFF}, - {WSA881X_OTP_REG_17, 0xFF}, - {WSA881X_OTP_REG_18, 0xFF}, - {WSA881X_OTP_REG_19, 0xFF}, - {WSA881X_OTP_REG_20, 0xFF}, - {WSA881X_OTP_REG_21, 0xFF}, - {WSA881X_OTP_REG_22, 0xFF}, - {WSA881X_OTP_REG_23, 0xFF}, - {WSA881X_OTP_REG_24, 0x03}, - {WSA881X_OTP_REG_25, 0x01}, - {WSA881X_OTP_REG_26, 0x03}, - {WSA881X_OTP_REG_27, 0x11}, - {WSA881X_OTP_REG_28, 0xFF}, - {WSA881X_OTP_REG_29, 0xFF}, - {WSA881X_OTP_REG_30, 0xFF}, - {WSA881X_OTP_REG_31, 0xFF}, - {WSA881X_OTP_REG_63, 0x40}, -}; - -struct reg_default wsa881x_ana_reg_defaults_1[] = { - {WSA881X_BIAS_REF_CTRL - WSA881X_ANALOG_BASE, 0x6C}, - {WSA881X_BIAS_TEST - WSA881X_ANALOG_BASE, 0x16}, - {WSA881X_BIAS_BIAS - WSA881X_ANALOG_BASE, 0xF0}, - {WSA881X_TEMP_OP - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_TEMP_IREF_CTRL - WSA881X_ANALOG_BASE, 0x56}, - {WSA881X_TEMP_ISENS_CTRL - WSA881X_ANALOG_BASE, 0x47}, - {WSA881X_TEMP_CLK_CTRL - WSA881X_ANALOG_BASE, 0x87}, - {WSA881X_TEMP_TEST - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_TEMP_BIAS - WSA881X_ANALOG_BASE, 0x51}, - {WSA881X_TEMP_ADC_CTRL - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_TEMP_DOUT_MSB - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_TEMP_DOUT_LSB - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_ADC_EN_MODU_V - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_ADC_EN_MODU_I - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_ADC_EN_DET_TEST_V - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_ADC_EN_DET_TEST_I - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_ADC_SEL_IBIAS - WSA881X_ANALOG_BASE, 0x25}, - {WSA881X_ADC_EN_SEL_IBIAS - WSA881X_ANALOG_BASE, 0x10}, - {WSA881X_SPKR_DRV_EN - WSA881X_ANALOG_BASE, 0x74}, - {WSA881X_SPKR_DRV_GAIN - WSA881X_ANALOG_BASE, 0x01}, - {WSA881X_SPKR_DAC_CTL - WSA881X_ANALOG_BASE, 0x40}, - {WSA881X_SPKR_DRV_DBG - WSA881X_ANALOG_BASE, 0x15}, - {WSA881X_SPKR_PWRSTG_DBG - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_SPKR_OCP_CTL - WSA881X_ANALOG_BASE, 0xD4}, - {WSA881X_SPKR_CLIP_CTL - WSA881X_ANALOG_BASE, 0x90}, - {WSA881X_SPKR_BBM_CTL - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_SPKR_MISC_CTL1 - WSA881X_ANALOG_BASE, 0x80}, - {WSA881X_SPKR_MISC_CTL2 - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_SPKR_BIAS_INT - WSA881X_ANALOG_BASE, 0x56}, - {WSA881X_SPKR_PA_INT - WSA881X_ANALOG_BASE, 0x54}, - {WSA881X_SPKR_BIAS_CAL - WSA881X_ANALOG_BASE, 0xAC}, - {WSA881X_SPKR_BIAS_PSRR - WSA881X_ANALOG_BASE, 0x54}, - {WSA881X_SPKR_STATUS1 - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_SPKR_STATUS2 - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_BOOST_EN_CTL - WSA881X_ANALOG_BASE, 0x18}, - {WSA881X_BOOST_CURRENT_LIMIT - WSA881X_ANALOG_BASE, 0x7A}, - {WSA881X_BOOST_PS_CTL - WSA881X_ANALOG_BASE, 0xC0}, - {WSA881X_BOOST_PRESET_OUT1 - WSA881X_ANALOG_BASE, 0x77}, - {WSA881X_BOOST_PRESET_OUT2 - WSA881X_ANALOG_BASE, 0x70}, - {WSA881X_BOOST_FORCE_OUT - WSA881X_ANALOG_BASE, 0x0E}, - {WSA881X_BOOST_LDO_PROG - WSA881X_ANALOG_BASE, 0x16}, - {WSA881X_BOOST_SLOPE_COMP_ISENSE_FB - WSA881X_ANALOG_BASE, 0x71}, - {WSA881X_BOOST_RON_CTL - WSA881X_ANALOG_BASE, 0x0F}, - {WSA881X_BOOST_LOOP_STABILITY - WSA881X_ANALOG_BASE, 0xAD}, - {WSA881X_BOOST_ZX_CTL - WSA881X_ANALOG_BASE, 0x34}, - {WSA881X_BOOST_START_CTL - WSA881X_ANALOG_BASE, 0x23}, - {WSA881X_BOOST_MISC1_CTL - WSA881X_ANALOG_BASE, 0x80}, - {WSA881X_BOOST_MISC2_CTL - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_BOOST_MISC3_CTL - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_BOOST_ATEST_CTL - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_SPKR_PROT_FE_GAIN - WSA881X_ANALOG_BASE, 0x46}, - {WSA881X_SPKR_PROT_FE_CM_LDO_SET - WSA881X_ANALOG_BASE, 0x3B}, - {WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1 - WSA881X_ANALOG_BASE, 0x8D}, - {WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2 - WSA881X_ANALOG_BASE, 0x8D}, - {WSA881X_SPKR_PROT_ATEST1 - WSA881X_ANALOG_BASE, 0x01}, - {WSA881X_SPKR_PROT_ATEST2 - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_SPKR_PROT_FE_VSENSE_VCM - WSA881X_ANALOG_BASE, 0x8D}, - {WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1 - WSA881X_ANALOG_BASE, 0x4D}, - {WSA881X_BONGO_RESRV_REG1 - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_BONGO_RESRV_REG2 - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_SPKR_PROT_SAR - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_SPKR_STATUS3 - WSA881X_ANALOG_BASE, 0x00}, -}; - -struct reg_default wsa881x_rev_2_0_dig[] = { - {WSA881X_RESET_CTL, 0x00}, - {WSA881X_TADC_VALUE_CTL, 0x01}, - {WSA881X_INTR_MASK, 0x1B}, - {WSA881X_IOPAD_CTL, 0x00}, - {WSA881X_OTP_REG_28, 0x3F}, - {WSA881X_OTP_REG_29, 0x3F}, - {WSA881X_OTP_REG_30, 0x01}, - {WSA881X_OTP_REG_31, 0x01}, -}; - -struct reg_default wsa881x_rev_2_0_ana[] = { - {WSA881X_TEMP_ADC_CTRL, 0x03}, - {WSA881X_ADC_SEL_IBIAS, 0x45}, - {WSA881X_SPKR_DRV_GAIN, 0xC1}, - {WSA881X_SPKR_DAC_CTL, 0x42}, - {WSA881X_SPKR_BBM_CTL, 0x02}, - {WSA881X_SPKR_MISC_CTL1, 0x40}, - {WSA881X_SPKR_MISC_CTL2, 0x07}, - {WSA881X_SPKR_BIAS_INT, 0x5F}, - {WSA881X_SPKR_BIAS_PSRR, 0x44}, - {WSA881X_BOOST_PS_CTL, 0xA0}, - {WSA881X_BOOST_PRESET_OUT1, 0xB7}, - {WSA881X_BOOST_LOOP_STABILITY, 0x8D}, - {WSA881X_SPKR_PROT_ATEST2, 0x02}, - {WSA881X_BONGO_RESRV_REG1, 0x5E}, - {WSA881X_BONGO_RESRV_REG2, 0x07}, -}; - -struct reg_default wsa881x_rev_2_0_regmap_ana[] = { - {WSA881X_TEMP_ADC_CTRL - WSA881X_ANALOG_BASE, 0x03}, - {WSA881X_ADC_SEL_IBIAS - WSA881X_ANALOG_BASE, 0x45}, - {WSA881X_SPKR_DRV_GAIN - WSA881X_ANALOG_BASE, 0xC1}, - {WSA881X_SPKR_DAC_CTL - WSA881X_ANALOG_BASE, 0x42}, - {WSA881X_SPKR_BBM_CTL - WSA881X_ANALOG_BASE, 0x02}, - {WSA881X_SPKR_MISC_CTL1 - WSA881X_ANALOG_BASE, 0x40}, - {WSA881X_SPKR_MISC_CTL2 - WSA881X_ANALOG_BASE, 0x07}, - {WSA881X_SPKR_BIAS_INT - WSA881X_ANALOG_BASE, 0x5F}, - {WSA881X_SPKR_BIAS_PSRR - WSA881X_ANALOG_BASE, 0x44}, - {WSA881X_BOOST_PS_CTL - WSA881X_ANALOG_BASE, 0xA0}, - {WSA881X_BOOST_PRESET_OUT1 - WSA881X_ANALOG_BASE, 0xB7}, - {WSA881X_BOOST_LOOP_STABILITY - WSA881X_ANALOG_BASE, 0x8D}, - {WSA881X_SPKR_PROT_ATEST2 - WSA881X_ANALOG_BASE, 0x02}, - {WSA881X_BONGO_RESRV_REG1 - WSA881X_ANALOG_BASE, 0x5E}, - {WSA881X_BONGO_RESRV_REG2 - WSA881X_ANALOG_BASE, 0x07}, -}; - -/** - * wsa881x_update_reg_defaults_2_0 - update default values of regs for v2.0 - * - * WSA881x v2.0 has different default values for certain analog and digital - * registers compared to v1.x. Therefore, update the values of these registers - * with the values from tables defined above for v2.0. - */ -void wsa881x_update_reg_defaults_2_0(void) -{ - int i, j; - - for (i = 0; i < ARRAY_SIZE(wsa881x_rev_2_0_dig); i++) { - for (j = 0; j < ARRAY_SIZE(wsa881x_ana_reg_defaults); j++) - if (wsa881x_ana_reg_defaults[j].reg == - wsa881x_rev_2_0_dig[i].reg) - wsa881x_ana_reg_defaults[j].def = - wsa881x_rev_2_0_dig[i].def; - } - for (i = 0; i < ARRAY_SIZE(wsa881x_rev_2_0_ana); i++) { - for (j = 0; j < ARRAY_SIZE(wsa881x_ana_reg_defaults); j++) - if (wsa881x_ana_reg_defaults[j].reg == - wsa881x_rev_2_0_ana[i].reg) - wsa881x_ana_reg_defaults[j].def = - wsa881x_rev_2_0_ana[i].def; - } -} -EXPORT_SYMBOL(wsa881x_update_reg_defaults_2_0); - -/** - * wsa881x_update_regmap_2_0 - update regmap framework with new tables - * @regmap: pointer to WSA881x regmap structure - * @flag: indicates digital or analog WSA881x slave - * - * WSA881x v2.0 has some new registers for both analog and digital slaves. - * Update the regmap framework with all the new registers. - */ -void wsa881x_update_regmap_2_0(struct regmap *regmap, int flag) -{ - u16 ret = 0; - - switch (flag) { - case WSA881X_DIGITAL_SLAVE: - ret = regmap_register_patch(regmap, wsa881x_rev_2_0_dig, - ARRAY_SIZE(wsa881x_rev_2_0_dig)); - break; - case WSA881X_ANALOG_SLAVE: - ret = regmap_register_patch(regmap, wsa881x_rev_2_0_ana, - ARRAY_SIZE(wsa881x_rev_2_0_ana)); - break; - default: - pr_debug("%s: unknown version", __func__); - ret = -EINVAL; - break; - } - if (ret) - pr_err("%s: Failed to update regmap defaults ret= %d\n", - __func__, ret); -} -EXPORT_SYMBOL(wsa881x_update_regmap_2_0); - -static bool wsa881x_readable_register(struct device *dev, unsigned int reg) -{ - return wsa881x_ana_reg_readable[reg]; -} - -static bool wsa881x_volatile_register(struct device *dev, unsigned int reg) -{ - switch (reg) { - case WSA881X_CHIP_ID0: - case WSA881X_CHIP_ID1: - case WSA881X_CHIP_ID2: - case WSA881X_CHIP_ID3: - case WSA881X_BUS_ID: - case WSA881X_TEMP_MSB: - case WSA881X_TEMP_LSB: - case WSA881X_SDM_PDM9_LSB: - case WSA881X_SDM_PDM9_MSB: - case WSA881X_OTP_REG_0: - case WSA881X_OTP_REG_1: - case WSA881X_OTP_REG_2: - case WSA881X_OTP_REG_3: - case WSA881X_OTP_REG_4: - case WSA881X_OTP_REG_5: - case WSA881X_OTP_REG_31: - case WSA881X_TEMP_DOUT_MSB: - case WSA881X_TEMP_DOUT_LSB: - case WSA881X_TEMP_OP: - case WSA881X_OTP_CTRL1: - case WSA881X_INTR_STATUS: - case WSA881X_ATE_TEST_MODE: - case WSA881X_PIN_STATUS: - case WSA881X_SWR_HM_TEST2: - case WSA881X_SPKR_STATUS1: - case WSA881X_SPKR_STATUS2: - case WSA881X_SPKR_STATUS3: - case WSA881X_SPKR_PROT_SAR: - return true; - default: - return false; - } -} - -struct regmap_config wsa881x_ana_regmap_config[] = { -{ - .reg_bits = 8, - .val_bits = 8, - .cache_type = REGCACHE_NONE, - .reg_defaults = wsa881x_ana_reg_defaults_0, - .num_reg_defaults = ARRAY_SIZE(wsa881x_ana_reg_defaults_0), - .max_register = WSA881X_MAX_REGISTER, - .volatile_reg = wsa881x_volatile_register, - .readable_reg = wsa881x_readable_register, - .reg_format_endian = REGMAP_ENDIAN_NATIVE, - .val_format_endian = REGMAP_ENDIAN_NATIVE, -}, -{ - .reg_bits = 8, - .val_bits = 8, - .cache_type = REGCACHE_NONE, - .reg_defaults = wsa881x_ana_reg_defaults_1, - .num_reg_defaults = ARRAY_SIZE(wsa881x_ana_reg_defaults_1), - .max_register = WSA881X_MAX_REGISTER, - .volatile_reg = wsa881x_volatile_register, - .readable_reg = wsa881x_readable_register, - .reg_format_endian = REGMAP_ENDIAN_NATIVE, - .val_format_endian = REGMAP_ENDIAN_NATIVE, -} -}; diff --git a/asoc/codecs/wsa881x-tables-analog.c b/asoc/codecs/wsa881x-tables-analog.c deleted file mode 100644 index 061ed6fff7..0000000000 --- a/asoc/codecs/wsa881x-tables-analog.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (c) 2015, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * 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. - */ - -#include -#include -#include "wsa881x-registers-analog.h" - -const u8 wsa881x_ana_reg_readable[WSA881X_CACHE_SIZE] = { - [WSA881X_CHIP_ID0] = 1, - [WSA881X_CHIP_ID1] = 1, - [WSA881X_CHIP_ID2] = 1, - [WSA881X_CHIP_ID3] = 1, - [WSA881X_BUS_ID] = 1, - [WSA881X_CDC_RST_CTL] = 1, - [WSA881X_CDC_TOP_CLK_CTL] = 1, - [WSA881X_CDC_ANA_CLK_CTL] = 1, - [WSA881X_CDC_DIG_CLK_CTL] = 1, - [WSA881X_CLOCK_CONFIG] = 1, - [WSA881X_ANA_CTL] = 1, - [WSA881X_SWR_RESET_EN] = 1, - [WSA881X_RESET_CTL] = 1, - [WSA881X_TADC_VALUE_CTL] = 1, - [WSA881X_TEMP_DETECT_CTL] = 1, - [WSA881X_TEMP_MSB] = 1, - [WSA881X_TEMP_LSB] = 1, - [WSA881X_TEMP_CONFIG0] = 1, - [WSA881X_TEMP_CONFIG1] = 1, - [WSA881X_CDC_CLIP_CTL] = 1, - [WSA881X_SDM_PDM9_LSB] = 1, - [WSA881X_SDM_PDM9_MSB] = 1, - [WSA881X_CDC_RX_CTL] = 1, - [WSA881X_DEM_BYPASS_DATA0] = 1, - [WSA881X_DEM_BYPASS_DATA1] = 1, - [WSA881X_DEM_BYPASS_DATA2] = 1, - [WSA881X_DEM_BYPASS_DATA3] = 1, - [WSA881X_OTP_CTRL0] = 1, - [WSA881X_OTP_CTRL1] = 1, - [WSA881X_HDRIVE_CTL_GROUP1] = 1, - [WSA881X_INTR_MODE] = 1, - [WSA881X_INTR_MASK] = 1, - [WSA881X_INTR_STATUS] = 1, - [WSA881X_INTR_CLEAR] = 1, - [WSA881X_INTR_LEVEL] = 1, - [WSA881X_INTR_SET] = 1, - [WSA881X_INTR_TEST] = 1, - [WSA881X_PDM_TEST_MODE] = 1, - [WSA881X_ATE_TEST_MODE] = 1, - [WSA881X_PIN_CTL_MODE] = 1, - [WSA881X_PIN_CTL_OE] = 1, - [WSA881X_PIN_WDATA_IOPAD] = 1, - [WSA881X_PIN_STATUS] = 1, - [WSA881X_DIG_DEBUG_MODE] = 1, - [WSA881X_DIG_DEBUG_SEL] = 1, - [WSA881X_DIG_DEBUG_EN] = 1, - [WSA881X_SWR_HM_TEST1] = 1, - [WSA881X_SWR_HM_TEST2] = 1, - [WSA881X_TEMP_DETECT_DBG_CTL] = 1, - [WSA881X_TEMP_DEBUG_MSB] = 1, - [WSA881X_TEMP_DEBUG_LSB] = 1, - [WSA881X_SAMPLE_EDGE_SEL] = 1, - [WSA881X_IOPAD_CTL] = 1, - [WSA881X_SPARE_0] = 1, - [WSA881X_SPARE_1] = 1, - [WSA881X_SPARE_2] = 1, - [WSA881X_OTP_REG_0] = 1, - [WSA881X_OTP_REG_1] = 1, - [WSA881X_OTP_REG_2] = 1, - [WSA881X_OTP_REG_3] = 1, - [WSA881X_OTP_REG_4] = 1, - [WSA881X_OTP_REG_5] = 1, - [WSA881X_OTP_REG_6] = 1, - [WSA881X_OTP_REG_7] = 1, - [WSA881X_OTP_REG_8] = 1, - [WSA881X_OTP_REG_9] = 1, - [WSA881X_OTP_REG_10] = 1, - [WSA881X_OTP_REG_11] = 1, - [WSA881X_OTP_REG_12] = 1, - [WSA881X_OTP_REG_13] = 1, - [WSA881X_OTP_REG_14] = 1, - [WSA881X_OTP_REG_15] = 1, - [WSA881X_OTP_REG_16] = 1, - [WSA881X_OTP_REG_17] = 1, - [WSA881X_OTP_REG_18] = 1, - [WSA881X_OTP_REG_19] = 1, - [WSA881X_OTP_REG_20] = 1, - [WSA881X_OTP_REG_21] = 1, - [WSA881X_OTP_REG_22] = 1, - [WSA881X_OTP_REG_23] = 1, - [WSA881X_OTP_REG_24] = 1, - [WSA881X_OTP_REG_25] = 1, - [WSA881X_OTP_REG_26] = 1, - [WSA881X_OTP_REG_27] = 1, - [WSA881X_OTP_REG_28] = 1, - [WSA881X_OTP_REG_29] = 1, - [WSA881X_OTP_REG_30] = 1, - [WSA881X_OTP_REG_31] = 1, - [WSA881X_OTP_REG_63] = 1, - /* Analog Registers */ - [WSA881X_BIAS_REF_CTRL] = 1, - [WSA881X_BIAS_TEST] = 1, - [WSA881X_BIAS_BIAS] = 1, - [WSA881X_TEMP_OP] = 1, - [WSA881X_TEMP_IREF_CTRL] = 1, - [WSA881X_TEMP_ISENS_CTRL] = 1, - [WSA881X_TEMP_CLK_CTRL] = 1, - [WSA881X_TEMP_TEST] = 1, - [WSA881X_TEMP_BIAS] = 1, - [WSA881X_TEMP_ADC_CTRL] = 1, - [WSA881X_TEMP_DOUT_MSB] = 1, - [WSA881X_TEMP_DOUT_LSB] = 1, - [WSA881X_ADC_EN_MODU_V] = 1, - [WSA881X_ADC_EN_MODU_I] = 1, - [WSA881X_ADC_EN_DET_TEST_V] = 1, - [WSA881X_ADC_EN_DET_TEST_I] = 1, - [WSA881X_ADC_SEL_IBIAS] = 1, - [WSA881X_ADC_EN_SEL_IBIAS] = 1, - [WSA881X_SPKR_DRV_EN] = 1, - [WSA881X_SPKR_DRV_GAIN] = 1, - [WSA881X_SPKR_DAC_CTL] = 1, - [WSA881X_SPKR_DRV_DBG] = 1, - [WSA881X_SPKR_PWRSTG_DBG] = 1, - [WSA881X_SPKR_OCP_CTL] = 1, - [WSA881X_SPKR_CLIP_CTL] = 1, - [WSA881X_SPKR_BBM_CTL] = 1, - [WSA881X_SPKR_MISC_CTL1] = 1, - [WSA881X_SPKR_MISC_CTL2] = 1, - [WSA881X_SPKR_BIAS_INT] = 1, - [WSA881X_SPKR_PA_INT] = 1, - [WSA881X_SPKR_BIAS_CAL] = 1, - [WSA881X_SPKR_BIAS_PSRR] = 1, - [WSA881X_SPKR_STATUS1] = 1, - [WSA881X_SPKR_STATUS2] = 1, - [WSA881X_BOOST_EN_CTL] = 1, - [WSA881X_BOOST_CURRENT_LIMIT] = 1, - [WSA881X_BOOST_PS_CTL] = 1, - [WSA881X_BOOST_PRESET_OUT1] = 1, - [WSA881X_BOOST_PRESET_OUT2] = 1, - [WSA881X_BOOST_FORCE_OUT] = 1, - [WSA881X_BOOST_LDO_PROG] = 1, - [WSA881X_BOOST_SLOPE_COMP_ISENSE_FB] = 1, - [WSA881X_BOOST_RON_CTL] = 1, - [WSA881X_BOOST_LOOP_STABILITY] = 1, - [WSA881X_BOOST_ZX_CTL] = 1, - [WSA881X_BOOST_START_CTL] = 1, - [WSA881X_BOOST_MISC1_CTL] = 1, - [WSA881X_BOOST_MISC2_CTL] = 1, - [WSA881X_BOOST_MISC3_CTL] = 1, - [WSA881X_BOOST_ATEST_CTL] = 1, - [WSA881X_SPKR_PROT_FE_GAIN] = 1, - [WSA881X_SPKR_PROT_FE_CM_LDO_SET] = 1, - [WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1] = 1, - [WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2] = 1, - [WSA881X_SPKR_PROT_ATEST1] = 1, - [WSA881X_SPKR_PROT_ATEST2] = 1, - [WSA881X_SPKR_PROT_FE_VSENSE_VCM] = 1, - [WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1] = 1, - [WSA881X_BONGO_RESRV_REG1] = 1, - [WSA881X_BONGO_RESRV_REG2] = 1, - [WSA881X_SPKR_PROT_SAR] = 1, - [WSA881X_SPKR_STATUS3] = 1, -}; diff --git a/asoc/msm-audio-pinctrl.c b/asoc/msm-audio-pinctrl.c deleted file mode 100644 index f0fba840eb..0000000000 --- a/asoc/msm-audio-pinctrl.c +++ /dev/null @@ -1,316 +0,0 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * 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. - */ - -#include -#include -#include -#include "msm-audio-pinctrl.h" - -/* - * pinctrl -- handle to query pinctrl apis - * cdc lines -- stores pinctrl handles for pinctrl states - * active_set -- maintain the overall pinctrl state - */ -struct cdc_pinctrl_info { - struct pinctrl *pinctrl; - struct pinctrl_state **cdc_lines; - int active_set; -}; - -/* - * gpiosets -- stores all gpiosets mentioned in dtsi file - * gpiosets_comb_names -- stores all possible gpioset combinations - * gpioset_state -- maintains counter for each gpioset - * gpiosets_max -- maintain the total supported gpiosets - * gpiosets_comb_max -- maintain the total gpiosets combinations - */ -struct cdc_gpioset_info { - char **gpiosets; - char **gpiosets_comb_names; - uint8_t *gpioset_state; - int gpiosets_max; - int gpiosets_comb_max; -}; - -static struct cdc_pinctrl_info pinctrl_info[MAX_PINCTRL_CLIENT]; -static struct cdc_gpioset_info gpioset_info[MAX_PINCTRL_CLIENT]; - -/* Finds the index for the gpio set in the dtsi file */ -int msm_get_gpioset_index(enum pinctrl_client client, char *keyword) -{ - int i; - - for (i = 0; i < gpioset_info[client].gpiosets_max; i++) { - if (!(strcmp(gpioset_info[client].gpiosets[i], keyword))) - break; - } - /* Checking if the keyword is present in dtsi or not */ - if (i != gpioset_info[client].gpiosets_max) - return i; - else - return -EINVAL; -} - -/* - * This function reads the following from dtsi file - * 1. All gpio sets - * 2. All combinations of gpio sets - * 3. Pinctrl handles to gpio sets - * - * Returns error if there is - * 1. Problem reading from dtsi file - * 2. Memory allocation failure - */ -int msm_gpioset_initialize(enum pinctrl_client client, - struct device *dev) -{ - struct pinctrl *pinctrl; - const char *gpioset_names = "qcom,msm-gpios"; - const char *gpioset_combinations = "qcom,pinctrl-names"; - const char *gpioset_names_str = NULL; - const char *gpioset_comb_str = NULL; - int num_strings = 0; - int ret = 0; - int i = 0; - - pr_debug("%s\n", __func__); - pinctrl = devm_pinctrl_get(dev); - if (IS_ERR(pinctrl)) { - pr_err("%s: Unable to get pinctrl handle\n", - __func__); - return -EINVAL; - } - pinctrl_info[client].pinctrl = pinctrl; - - /* Reading of gpio sets */ - num_strings = of_property_count_strings(dev->of_node, - gpioset_names); - if (num_strings < 0) { - dev_err(dev, - "%s: missing %s in dt node or length is incorrect\n", - __func__, gpioset_names); - goto err; - } - gpioset_info[client].gpiosets_max = num_strings; - gpioset_info[client].gpiosets = devm_kzalloc(dev, - gpioset_info[client].gpiosets_max * - sizeof(char *), GFP_KERNEL); - if (!gpioset_info[client].gpiosets) { - dev_err(dev, "Can't allocate memory for gpio set names\n"); - ret = -ENOMEM; - goto err; - } - - for (i = 0; i < num_strings; i++) { - ret = of_property_read_string_index(dev->of_node, - gpioset_names, i, &gpioset_names_str); - - gpioset_info[client].gpiosets[i] = devm_kzalloc(dev, - (strlen(gpioset_names_str) + 1), GFP_KERNEL); - - if (!gpioset_info[client].gpiosets[i]) { - dev_err(dev, "%s: Can't allocate gpiosets[%d] data\n", - __func__, i); - ret = -ENOMEM; - goto err; - } - strlcpy(gpioset_info[client].gpiosets[i], - gpioset_names_str, strlen(gpioset_names_str)+1); - gpioset_names_str = NULL; - } - num_strings = 0; - - /* Allocating memory for gpio set counter */ - gpioset_info[client].gpioset_state = devm_kzalloc(dev, - gpioset_info[client].gpiosets_max * - sizeof(uint8_t), GFP_KERNEL); - if (!gpioset_info[client].gpioset_state) { - dev_err(dev, "Can't allocate memory for gpio set counter\n"); - ret = -ENOMEM; - goto err; - } - - /* Reading of all combinations of gpio sets */ - num_strings = of_property_count_strings(dev->of_node, - gpioset_combinations); - if (num_strings < 0) { - dev_err(dev, - "%s: missing %s in dt node or length is incorrect\n", - __func__, gpioset_combinations); - goto err; - } - gpioset_info[client].gpiosets_comb_max = num_strings; - gpioset_info[client].gpiosets_comb_names = devm_kzalloc(dev, - num_strings * sizeof(char *), GFP_KERNEL); - if (!gpioset_info[client].gpiosets_comb_names) { - ret = -ENOMEM; - goto err; - } - - for (i = 0; i < gpioset_info[client].gpiosets_comb_max; i++) { - ret = of_property_read_string_index(dev->of_node, - gpioset_combinations, i, &gpioset_comb_str); - - gpioset_info[client].gpiosets_comb_names[i] = devm_kzalloc(dev, - (strlen(gpioset_comb_str) + 1), GFP_KERNEL); - if (!gpioset_info[client].gpiosets_comb_names[i]) { - ret = -ENOMEM; - goto err; - } - - strlcpy(gpioset_info[client].gpiosets_comb_names[i], - gpioset_comb_str, - strlen(gpioset_comb_str)+1); - pr_debug("%s: GPIO configuration %s\n", - __func__, - gpioset_info[client].gpiosets_comb_names[i]); - gpioset_comb_str = NULL; - } - - /* Allocating memory for handles to pinctrl states */ - pinctrl_info[client].cdc_lines = devm_kzalloc(dev, - num_strings * sizeof(char *), GFP_KERNEL); - if (!pinctrl_info[client].cdc_lines) { - ret = -ENOMEM; - goto err; - } - - /* Get pinctrl handles for gpio sets in dtsi file */ - for (i = 0; i < num_strings; i++) { - pinctrl_info[client].cdc_lines[i] = pinctrl_lookup_state( - pinctrl, - (const char *)gpioset_info[client]. - gpiosets_comb_names[i]); - if (IS_ERR(pinctrl_info[client].cdc_lines[i])) - pr_err("%s: Unable to get pinctrl handle for %s\n", - __func__, gpioset_info[client]. - gpiosets_comb_names[i]); - } - goto success; - -err: - /* Free up memory allocated for gpio set combinations */ - for (i = 0; i < gpioset_info[client].gpiosets_max; i++) { - if (gpioset_info[client].gpiosets[i] != NULL) { - devm_kfree(dev, gpioset_info[client].gpiosets[i]); - gpioset_info[client].gpiosets[i] = NULL; - } - } - if (gpioset_info[client].gpiosets != NULL) { - devm_kfree(dev, gpioset_info[client].gpiosets); - gpioset_info[client].gpiosets = NULL; - } - - /* Free up memory allocated for gpio set combinations */ - for (i = 0; i < gpioset_info[client].gpiosets_comb_max; i++) { - if (gpioset_info[client].gpiosets_comb_names[i] != NULL) { - devm_kfree(dev, - gpioset_info[client].gpiosets_comb_names[i]); - gpioset_info[client].gpiosets_comb_names[i] = NULL; - } - } - if (gpioset_info[client].gpiosets_comb_names != NULL) { - devm_kfree(dev, gpioset_info[client].gpiosets_comb_names); - gpioset_info[client].gpiosets_comb_names = NULL; - } - - /* Free up memory allocated for handles to pinctrl states */ - if (pinctrl_info[client].cdc_lines != NULL) { - devm_kfree(dev, pinctrl_info[client].cdc_lines); - pinctrl_info[client].cdc_lines = NULL; - } - - /* Free up memory allocated for counter of gpio sets */ - if (gpioset_info[client].gpioset_state != NULL) { - devm_kfree(dev, gpioset_info[client].gpioset_state); - gpioset_info[client].gpioset_state = NULL; - } - -success: - return ret; -} - -int msm_gpioset_activate(enum pinctrl_client client, char *keyword) -{ - int ret = 0; - int gp_set = 0; - int active_set = 0; - - gp_set = msm_get_gpioset_index(client, keyword); - if (gp_set < 0) { - pr_err("%s: gpio set name does not exist\n", - __func__); - return gp_set; - } - - if (!gpioset_info[client].gpioset_state[gp_set]) { - /* - * If pinctrl pointer is not valid, - * no need to proceed further - */ - active_set = pinctrl_info[client].active_set; - if (IS_ERR(pinctrl_info[client].cdc_lines[active_set])) - return 0; - - pinctrl_info[client].active_set |= (1 << gp_set); - active_set = pinctrl_info[client].active_set; - pr_debug("%s: pinctrl.active_set: %d\n", __func__, active_set); - - /* Select the appropriate pinctrl state */ - ret = pinctrl_select_state(pinctrl_info[client].pinctrl, - pinctrl_info[client].cdc_lines[active_set]); - } - gpioset_info[client].gpioset_state[gp_set]++; - - return ret; -} - -int msm_gpioset_suspend(enum pinctrl_client client, char *keyword) -{ - int ret = 0; - int gp_set = 0; - int active_set = 0; - - gp_set = msm_get_gpioset_index(client, keyword); - if (gp_set < 0) { - pr_err("%s: gpio set name does not exist\n", - __func__); - return gp_set; - } - - if (gpioset_info[client].gpioset_state[gp_set] == 1) { - pinctrl_info[client].active_set &= ~(1 << gp_set); - /* - * If pinctrl pointer is not valid, - * no need to proceed further - */ - active_set = pinctrl_info[client].active_set; - if (IS_ERR(pinctrl_info[client].cdc_lines[active_set])) - return -EINVAL; - - pr_debug("%s: pinctrl.active_set: %d\n", __func__, - pinctrl_info[client].active_set); - /* Select the appropriate pinctrl state */ - ret = pinctrl_select_state(pinctrl_info[client].pinctrl, - pinctrl_info[client].cdc_lines[pinctrl_info[client]. - active_set]); - } - if (!(gpioset_info[client].gpioset_state[gp_set])) { - pr_err("%s: Invalid call to de activate gpios: %d\n", __func__, - gpioset_info[client].gpioset_state[gp_set]); - return -EINVAL; - } - - gpioset_info[client].gpioset_state[gp_set]--; - - return ret; -} diff --git a/asoc/msm-audio-pinctrl.h b/asoc/msm-audio-pinctrl.h deleted file mode 100644 index ec7c6aafda..0000000000 --- a/asoc/msm-audio-pinctrl.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * 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 __MSM_AUDIO_PINCTRL_H -#define __MSM_AUDIO_PINCTRL_H - -enum pinctrl_client { - CLIENT_WCD, - CLIENT_WSA_BONGO_1, - CLIENT_WSA_BONGO_2, - MAX_PINCTRL_CLIENT, -}; - - -/* finds the index for the gpio set in the dtsi file */ -int msm_get_gpioset_index(enum pinctrl_client client, char *keyword); - -/* - * this function reads the following from dtsi file - * 1. all gpio sets - * 2. all combinations of gpio sets - * 3. pinctrl handles to gpio sets - * - * returns error if there is - * 1. problem reading from dtsi file - * 2. memory allocation failure - */ -int msm_gpioset_initialize(enum pinctrl_client client, struct device *dev); - -int msm_gpioset_activate(enum pinctrl_client client, char *keyword); - -int msm_gpioset_suspend(enum pinctrl_client client, char *keyword); - -#endif /* __MSM_AUDIO_PINCTRL_H */ diff --git a/asoc/msm8996.c b/asoc/msm8996.c deleted file mode 100644 index 08900372a2..0000000000 --- a/asoc/msm8996.c +++ /dev/null @@ -1,4007 +0,0 @@ -/* - * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "qdsp6v2/msm-pcm-routing-v2.h" -#include "../codecs/wcd9xxx-common.h" -#include "../codecs/wcd9330.h" -#include "../codecs/wcd9335.h" -#include "../codecs/wsa881x.h" - -#define DRV_NAME "msm8996-asoc-snd" - -#define SAMPLING_RATE_8KHZ 8000 -#define SAMPLING_RATE_16KHZ 16000 -#define SAMPLING_RATE_32KHZ 32000 -#define SAMPLING_RATE_48KHZ 48000 -#define SAMPLING_RATE_96KHZ 96000 -#define SAMPLING_RATE_192KHZ 192000 -#define SAMPLING_RATE_44P1KHZ 44100 - -#define MSM8996_SPK_ON 1 -#define MSM8996_HIFI_ON 1 - -#define WCD9XXX_MBHC_DEF_BUTTONS 8 -#define WCD9XXX_MBHC_DEF_RLOADS 5 -#define CODEC_EXT_CLK_RATE 9600000 -#define ADSP_STATE_READY_TIMEOUT_MS 3000 -#define DEV_NAME_STR_LEN 32 - -#define WSA8810_NAME_1 "wsa881x.20170211" -#define WSA8810_NAME_2 "wsa881x.20170212" - -static int slim0_rx_sample_rate = SAMPLING_RATE_48KHZ; -static int slim0_tx_sample_rate = SAMPLING_RATE_48KHZ; -static int slim1_tx_sample_rate = SAMPLING_RATE_48KHZ; -static int slim0_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE; -static int slim0_tx_bit_format = SNDRV_PCM_FORMAT_S16_LE; -static int slim1_tx_bit_format = SNDRV_PCM_FORMAT_S16_LE; -static int hdmi_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE; -static int msm8996_auxpcm_rate = SAMPLING_RATE_8KHZ; -static int slim5_rx_sample_rate = SAMPLING_RATE_48KHZ; -static int slim5_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE; -static int slim6_rx_sample_rate = SAMPLING_RATE_48KHZ; -static int slim6_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE; - -static struct platform_device *spdev; -static int ext_us_amp_gpio = -1; -static int msm8996_spk_control = 1; -static int msm_slim_0_rx_ch = 1; -static int msm_slim_0_tx_ch = 1; -static int msm_slim_1_tx_ch = 1; -static int msm_slim_5_rx_ch = 1; -static int msm_slim_6_rx_ch = 1; -static int msm_hifi_control; -static int msm_vi_feed_tx_ch = 2; - -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; - -static bool codec_reg_done; - -static const char *const hifi_function[] = {"Off", "On"}; -static const char *const pin_states[] = {"Disable", "active"}; -static const char *const spk_function[] = {"Off", "On"}; -static const char *const slim0_rx_ch_text[] = {"One", "Two"}; -static const char *const slim5_rx_ch_text[] = {"One", "Two"}; -static const char *const slim6_rx_ch_text[] = {"One", "Two"}; -static const char *const slim0_tx_ch_text[] = {"One", "Two", "Three", "Four", - "Five", "Six", "Seven", - "Eight"}; -static const char *const vi_feed_ch_text[] = {"One", "Two"}; -static char const *hdmi_rx_ch_text[] = {"Two", "Three", "Four", "Five", - "Six", "Seven", "Eight"}; -static char const *rx_bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE"}; -static char const *slim5_rx_bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE"}; -static char const *slim6_rx_bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE"}; -static char const *slim0_rx_sample_rate_text[] = {"KHZ_48", "KHZ_96", - "KHZ_192", "KHZ_44P1", "KHZ_8", - "KHZ_16", "KHZ_32"}; -static char const *slim5_rx_sample_rate_text[] = {"KHZ_48", "KHZ_96", - "KHZ_192", "KHZ_44P1"}; -static char const *slim6_rx_sample_rate_text[] = {"KHZ_48", "KHZ_96", - "KHZ_192", "KHZ_44P1"}; -static const char *const proxy_rx_ch_text[] = {"One", "Two", "Three", "Four", - "Five", "Six", "Seven", "Eight"}; - -static char const *hdmi_rx_sample_rate_text[] = {"KHZ_48", "KHZ_96", - "KHZ_192"}; - -static const char *const auxpcm_rate_text[] = {"8000", "16000"}; -static const struct soc_enum msm8996_auxpcm_enum[] = { - SOC_ENUM_SINGLE_EXT(2, auxpcm_rate_text), -}; - -static struct afe_clk_set mi2s_tx_clk = { - AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT, - Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, -}; - -struct msm8996_wsa881x_dev_info { - struct device_node *of_node; - u32 index; -}; - -static struct snd_soc_aux_dev *msm8996_aux_dev; -static struct snd_soc_codec_conf *msm8996_codec_conf; - -struct msm8996_asoc_mach_data { - u32 mclk_freq; - int us_euro_gpio; - int hph_en1_gpio; - int hph_en0_gpio; - struct snd_info_entry *codec_root; -}; - -struct msm8996_asoc_wcd93xx_codec { - void* (*get_afe_config_fn)(struct snd_soc_codec *codec, - enum afe_config_type config_type); - void (*mbhc_hs_detect_exit)(struct snd_soc_codec *codec); -}; - -static struct msm8996_asoc_wcd93xx_codec msm8996_codec_fn; - -struct msm8996_liquid_dock_dev { - int dock_plug_gpio; - int dock_plug_irq; - int dock_plug_det; - struct work_struct irq_work; - struct switch_dev audio_sdev; -}; -static struct msm8996_liquid_dock_dev *msm8996_liquid_dock_dev; - -static void *adsp_state_notifier; -static void *def_tasha_mbhc_cal(void); -static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, - int enable, bool dapm); -static int msm8996_wsa881x_init(struct snd_soc_component *component); - -/* - * Need to report LINEIN - * if R/L channel impedance is larger than 5K ohm - */ -static struct wcd_mbhc_config wcd_mbhc_cfg = { - .read_fw_bin = false, - .calibration = NULL, - .detect_extn_cable = true, - .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[4] = 0, - .key_code[5] = 0, - .key_code[6] = 0, - .key_code[7] = 0, - .linein_th = 5000, - .moisture_en = true, - .mbhc_micbias = MIC_BIAS_2, - .anc_micbias = MIC_BIAS_2, - .enable_anc_mic_detect = false, -}; - -static inline int param_is_mask(int p) -{ - return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && - (p <= SNDRV_PCM_HW_PARAM_LAST_MASK); -} - -static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, - int n) -{ - return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]); -} - -static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned int bit) -{ - if (bit >= SNDRV_MASK_MAX) - return; - if (param_is_mask(n)) { - struct snd_mask *m = param_to_mask(p, n); - - m->bits[0] = 0; - m->bits[1] = 0; - m->bits[bit >> 5] |= (1 << (bit & 31)); - } -} - -static void msm8996_liquid_docking_irq_work(struct work_struct *work) -{ - struct msm8996_liquid_dock_dev *dock_dev = - container_of(work, struct msm8996_liquid_dock_dev, - irq_work); - - dock_dev->dock_plug_det = - gpio_get_value(dock_dev->dock_plug_gpio); - - switch_set_state(&dock_dev->audio_sdev, dock_dev->dock_plug_det); - /* notify to audio daemon */ - sysfs_notify(&dock_dev->audio_sdev.dev->kobj, NULL, "state"); -} - -static irqreturn_t msm8996_liquid_docking_irq_handler(int irq, void *dev) -{ - struct msm8996_liquid_dock_dev *dock_dev = dev; - - /* switch speakers should not run in interrupt context */ - schedule_work(&dock_dev->irq_work); - return IRQ_HANDLED; -} - -static int msm8996_liquid_init_docking(void) -{ - int ret = 0; - int dock_plug_gpio = 0; - - /* plug in docking speaker+plug in device OR unplug one of them */ - u32 dock_plug_irq_flags = IRQF_TRIGGER_RISING | - IRQF_TRIGGER_FALLING | - IRQF_SHARED; - - dock_plug_gpio = of_get_named_gpio(spdev->dev.of_node, - "qcom,dock-plug-det-irq", 0); - - if (dock_plug_gpio >= 0) { - msm8996_liquid_dock_dev = - kzalloc(sizeof(*msm8996_liquid_dock_dev), GFP_KERNEL); - if (!msm8996_liquid_dock_dev) { - ret = -ENOMEM; - goto exit; - } - - msm8996_liquid_dock_dev->dock_plug_gpio = dock_plug_gpio; - - ret = gpio_request(msm8996_liquid_dock_dev->dock_plug_gpio, - "dock-plug-det-irq"); - if (ret) { - pr_err("%s:failed request msm8996_liquid_dock_plug_gpio err = %d\n", - __func__, ret); - ret = -EINVAL; - goto fail_dock_gpio; - } - - msm8996_liquid_dock_dev->dock_plug_det = - gpio_get_value( - msm8996_liquid_dock_dev->dock_plug_gpio); - msm8996_liquid_dock_dev->dock_plug_irq = - gpio_to_irq( - msm8996_liquid_dock_dev->dock_plug_gpio); - - ret = request_irq(msm8996_liquid_dock_dev->dock_plug_irq, - msm8996_liquid_docking_irq_handler, - dock_plug_irq_flags, - "liquid_dock_plug_irq", - msm8996_liquid_dock_dev); - if (ret < 0) { - pr_err("%s: Request Irq Failed err = %d\n", - __func__, ret); - goto fail_dock_gpio; - } - - msm8996_liquid_dock_dev->audio_sdev.name = - QC_AUDIO_EXTERNAL_SPK_1_EVENT; - - if (switch_dev_register( - &msm8996_liquid_dock_dev->audio_sdev) < 0) { - pr_err("%s: dock device register in switch diretory failed\n", - __func__); - goto fail_switch_dev; - } - - INIT_WORK( - &msm8996_liquid_dock_dev->irq_work, - msm8996_liquid_docking_irq_work); - } - return 0; - -fail_switch_dev: - free_irq(msm8996_liquid_dock_dev->dock_plug_irq, - msm8996_liquid_dock_dev); -fail_dock_gpio: - gpio_free(msm8996_liquid_dock_dev->dock_plug_gpio); -exit: - kfree(msm8996_liquid_dock_dev); - msm8996_liquid_dock_dev = NULL; - return ret; -} - -static void msm8996_ext_control(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); - - pr_debug("%s: msm8996_spk_control = %d", __func__, - msm8996_spk_control); - if (msm8996_spk_control == MSM8996_SPK_ON) { - snd_soc_dapm_enable_pin(dapm, "Lineout_1 amp"); - snd_soc_dapm_enable_pin(dapm, "Lineout_2 amp"); - } else { - snd_soc_dapm_disable_pin(dapm, "Lineout_1 amp"); - snd_soc_dapm_disable_pin(dapm, "Lineout_2 amp"); - } - snd_soc_dapm_sync(dapm); -} - -static int msm8996_get_spk(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: msm8996_spk_control = %d\n", - __func__, msm8996_spk_control); - ucontrol->value.integer.value[0] = msm8996_spk_control; - return 0; -} - -static int msm8996_set_spk(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - - pr_debug("%s() ucontrol->value.integer.value[0] = %ld\n", - __func__, ucontrol->value.integer.value[0]); - if (msm8996_spk_control == ucontrol->value.integer.value[0]) - return 0; - - msm8996_spk_control = ucontrol->value.integer.value[0]; - msm8996_ext_control(codec); - return 1; -} - -static int msm8996_hifi_ctrl(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); - struct snd_soc_card *card = codec->component.card; - struct msm8996_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(card); - - pr_debug("%s: msm_hifi_control = %d", __func__, - msm_hifi_control); - if (pdata->hph_en1_gpio < 0) { - pr_err("%s: hph_en1_gpio is invalid\n", __func__); - return -EINVAL; - } - if (msm_hifi_control == MSM8996_HIFI_ON) { - gpio_direction_output(pdata->hph_en1_gpio, 1); - /* 5msec delay needed as per HW requirement */ - usleep_range(5000, 5010); - } else { - gpio_direction_output(pdata->hph_en1_gpio, 0); - } - snd_soc_dapm_sync(dapm); - return 0; -} - -static int msm8996_hifi_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: msm_hifi_control = %d\n", - __func__, msm_hifi_control); - ucontrol->value.integer.value[0] = msm_hifi_control; - return 0; -} - -static int msm8996_hifi_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - - pr_debug("%s() ucontrol->value.integer.value[0] = %ld\n", - __func__, ucontrol->value.integer.value[0]); - - msm_hifi_control = ucontrol->value.integer.value[0]; - msm8996_hifi_ctrl(codec); - return 1; -} - -static int msm8996_ext_us_amp_init(void) -{ - int ret = 0; - - ext_us_amp_gpio = of_get_named_gpio(spdev->dev.of_node, - "qcom,ext-ult-spk-amp-gpio", 0); - if (ext_us_amp_gpio >= 0) { - ret = gpio_request(ext_us_amp_gpio, "ext_us_amp_gpio"); - if (ret) { - pr_err("%s: ext_us_amp_gpio request failed, ret:%d\n", - __func__, ret); - return ret; - } - gpio_direction_output(ext_us_amp_gpio, 0); - } - return ret; -} - -static void msm8996_ext_us_amp_enable(u32 on) -{ - if (on) - gpio_direction_output(ext_us_amp_gpio, 1); - else - gpio_direction_output(ext_us_amp_gpio, 0); - - pr_debug("%s: US Emitter GPIO enable:%s\n", __func__, - on ? "Enable" : "Disable"); -} - -static int msm_ext_ultrasound_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - pr_debug("%s()\n", __func__); - if (strcmp(w->name, "ultrasound amp")) { - if (!gpio_is_valid(ext_us_amp_gpio)) { - pr_err("%s: ext_us_amp_gpio isn't configured\n", - __func__); - return -EINVAL; - } - if (SND_SOC_DAPM_EVENT_ON(event)) - msm8996_ext_us_amp_enable(1); - else - msm8996_ext_us_amp_enable(0); - } else { - pr_err("%s() Invalid Widget = %s\n", - __func__, w->name); - return -EINVAL; - } - return 0; -} - -static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, - int enable, bool dapm) -{ - int ret = 0; - - if (!strcmp(dev_name(codec->dev), "tasha_codec")) { - ret = tasha_cdc_mclk_enable(codec, enable, dapm); - } else { - dev_err(codec->dev, "%s: unknown codec to enable ext clk\n", - __func__); - ret = -EINVAL; - } - - return ret; -} - -static int msm8996_mclk_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - - pr_debug("%s: event = %d\n", __func__, event); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - return msm_snd_enable_codec_ext_clk(codec, 1, true); - case SND_SOC_DAPM_POST_PMD: - return msm_snd_enable_codec_ext_clk(codec, 0, true); - } - return 0; -} - -static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_codec *codec, - int enable, bool dapm) -{ - int ret = 0; - - if (!strcmp(dev_name(codec->dev), "tasha_codec")) - ret = tasha_cdc_mclk_tx_enable(codec, enable, dapm); - else { - dev_err(codec->dev, "%s: unknown codec to enable ext clk\n", - __func__); - ret = -EINVAL; - } - return ret; -} - -static int msm8996_mclk_tx_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - - pr_debug("%s: event = %d\n", __func__, event); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - return msm_snd_enable_codec_ext_tx_clk(codec, 1, true); - case SND_SOC_DAPM_POST_PMD: - return msm_snd_enable_codec_ext_tx_clk(codec, 0, true); - } - return 0; -} - -static int msm_hifi_ctrl_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct snd_soc_card *card = codec->component.card; - struct msm8996_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(card); - int ret = 0; - - pr_debug("%s: msm_hifi_control = %d", __func__, - msm_hifi_control); - switch (event) { - case SND_SOC_DAPM_POST_PMU: - if (msm_hifi_control == MSM8996_HIFI_ON) { - if (pdata->hph_en0_gpio < 0) { - pr_err("%s: hph_en0_gpio is invalid\n", - __func__); - ret = -EINVAL; - goto err; - } - gpio_direction_output(pdata->hph_en0_gpio, 1); - } - break; - case SND_SOC_DAPM_PRE_PMD: - if (msm_hifi_control == MSM8996_HIFI_ON) { - if (pdata->hph_en0_gpio < 0) { - pr_err("%s: hph_en0_gpio is invalid\n", - __func__); - ret = -EINVAL; - goto err; - } - gpio_direction_output(pdata->hph_en0_gpio, 0); - } - break; - } -err: - return ret; -} - -static const struct snd_soc_dapm_widget msm8996_dapm_widgets[] = { - - SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0, - msm8996_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_SUPPLY("MCLK TX", SND_SOC_NOPM, 0, 0, - msm8996_mclk_tx_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_SPK("Lineout_1 amp", NULL), - SND_SOC_DAPM_SPK("Lineout_3 amp", NULL), - SND_SOC_DAPM_SPK("Lineout_2 amp", NULL), - SND_SOC_DAPM_SPK("Lineout_4 amp", NULL), - SND_SOC_DAPM_SPK("ultrasound amp", msm_ext_ultrasound_event), - SND_SOC_DAPM_SPK("hifi amp", msm_hifi_ctrl_event), - SND_SOC_DAPM_MIC("Handset Mic", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL), - SND_SOC_DAPM_MIC("ANCLeft Headset Mic", NULL), - SND_SOC_DAPM_MIC("Analog Mic4", NULL), - SND_SOC_DAPM_MIC("Analog Mic6", NULL), - SND_SOC_DAPM_MIC("Analog Mic7", NULL), - SND_SOC_DAPM_MIC("Analog Mic8", NULL), - - SND_SOC_DAPM_MIC("Digital Mic0", NULL), - SND_SOC_DAPM_MIC("Digital Mic1", NULL), - SND_SOC_DAPM_MIC("Digital Mic2", NULL), - SND_SOC_DAPM_MIC("Digital Mic3", NULL), - SND_SOC_DAPM_MIC("Digital Mic4", NULL), - SND_SOC_DAPM_MIC("Digital Mic5", NULL), - SND_SOC_DAPM_MIC("Digital Mic6", NULL), -}; - -static struct snd_soc_dapm_route wcd9335_audio_paths[] = { - {"MIC BIAS1", NULL, "MCLK TX"}, - {"MIC BIAS2", NULL, "MCLK TX"}, - {"MIC BIAS3", NULL, "MCLK TX"}, - {"MIC BIAS4", NULL, "MCLK TX"}, -}; - -static int slim5_rx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int sample_rate_val = 0; - - switch (slim5_rx_sample_rate) { - case SAMPLING_RATE_44P1KHZ: - sample_rate_val = 3; - break; - - case SAMPLING_RATE_192KHZ: - sample_rate_val = 2; - break; - - case SAMPLING_RATE_96KHZ: - sample_rate_val = 1; - break; - - case SAMPLING_RATE_48KHZ: - default: - sample_rate_val = 0; - break; - } - - ucontrol->value.integer.value[0] = sample_rate_val; - pr_debug("%s: slim5_rx_sample_rate = %d\n", __func__, - slim5_rx_sample_rate); - - return 0; -} - -static int slim5_rx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: ucontrol value = %ld\n", __func__, - ucontrol->value.integer.value[0]); - - switch (ucontrol->value.integer.value[0]) { - case 3: - slim5_rx_sample_rate = SAMPLING_RATE_44P1KHZ; - break; - case 2: - slim5_rx_sample_rate = SAMPLING_RATE_192KHZ; - break; - case 1: - slim5_rx_sample_rate = SAMPLING_RATE_96KHZ; - break; - case 0: - default: - slim5_rx_sample_rate = SAMPLING_RATE_48KHZ; - } - - pr_debug("%s: slim5_rx_sample_rate = %d\n", __func__, - slim5_rx_sample_rate); - - return 0; -} - -static int slim6_rx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int sample_rate_val = 0; - - switch (slim6_rx_sample_rate) { - case SAMPLING_RATE_44P1KHZ: - sample_rate_val = 3; - break; - - case SAMPLING_RATE_192KHZ: - sample_rate_val = 2; - break; - - case SAMPLING_RATE_96KHZ: - sample_rate_val = 1; - break; - - case SAMPLING_RATE_48KHZ: - default: - sample_rate_val = 0; - break; - } - - ucontrol->value.integer.value[0] = sample_rate_val; - pr_debug("%s: slim6_rx_sample_rate = %d\n", __func__, - slim6_rx_sample_rate); - - return 0; -} - -static int slim6_rx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (ucontrol->value.integer.value[0]) { - case 3: - slim6_rx_sample_rate = SAMPLING_RATE_44P1KHZ; - break; - case 2: - slim6_rx_sample_rate = SAMPLING_RATE_192KHZ; - break; - case 1: - slim6_rx_sample_rate = SAMPLING_RATE_96KHZ; - break; - case 0: - default: - slim6_rx_sample_rate = SAMPLING_RATE_48KHZ; - break; - } - - pr_debug("%s: ucontrol value = %ld, slim6_rx_sample_rate = %d\n", - __func__, ucontrol->value.integer.value[0], - slim6_rx_sample_rate); - - return 0; -} - -static int slim0_tx_bit_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (slim0_tx_bit_format) { - case SNDRV_PCM_FORMAT_S24_3LE: - ucontrol->value.integer.value[0] = 2; - break; - case SNDRV_PCM_FORMAT_S24_LE: - ucontrol->value.integer.value[0] = 1; - break; - case SNDRV_PCM_FORMAT_S16_LE: - default: - ucontrol->value.integer.value[0] = 0; - break; - } - - pr_debug("%s: slim0_tx_bit_format = %d, ucontrol value = %ld\n", - __func__, slim0_tx_bit_format, - ucontrol->value.integer.value[0]); - return 0; -} - -static int slim0_tx_bit_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int rc = 0; - - switch (ucontrol->value.integer.value[0]) { - case 2: - slim0_tx_bit_format = SNDRV_PCM_FORMAT_S24_3LE; - break; - case 1: - slim0_tx_bit_format = SNDRV_PCM_FORMAT_S24_LE; - break; - case 0: - slim0_tx_bit_format = SNDRV_PCM_FORMAT_S16_LE; - break; - default: - pr_err("%s: invalid value %ld\n", __func__, - ucontrol->value.integer.value[0]); - rc = -EINVAL; - break; - } - - pr_debug("%s: ucontrol value = %ld, slim0_tx_bit_format = %d\n", - __func__, ucontrol->value.integer.value[0], - slim0_tx_bit_format); - - return rc; -} - -static int slim0_rx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int sample_rate_val = 0; - - switch (slim0_rx_sample_rate) { - case SAMPLING_RATE_32KHZ: - sample_rate_val = 6; - break; - - case SAMPLING_RATE_16KHZ: - sample_rate_val = 5; - break; - - case SAMPLING_RATE_8KHZ: - sample_rate_val = 4; - break; - - case SAMPLING_RATE_44P1KHZ: - sample_rate_val = 3; - break; - - case SAMPLING_RATE_192KHZ: - sample_rate_val = 2; - break; - - case SAMPLING_RATE_96KHZ: - sample_rate_val = 1; - break; - - case SAMPLING_RATE_48KHZ: - default: - sample_rate_val = 0; - break; - } - - ucontrol->value.integer.value[0] = sample_rate_val; - pr_debug("%s: slim0_rx_sample_rate = %d\n", __func__, - slim0_rx_sample_rate); - - return 0; -} - -static int slim0_rx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: ucontrol value = %ld\n", __func__, - ucontrol->value.integer.value[0]); - - switch (ucontrol->value.integer.value[0]) { - case 6: - slim0_rx_sample_rate = SAMPLING_RATE_32KHZ; - break; - case 5: - slim0_rx_sample_rate = SAMPLING_RATE_16KHZ; - break; - case 4: - slim0_rx_sample_rate = SAMPLING_RATE_8KHZ; - break; - case 3: - slim0_rx_sample_rate = SAMPLING_RATE_44P1KHZ; - break; - case 2: - slim0_rx_sample_rate = SAMPLING_RATE_192KHZ; - break; - case 1: - slim0_rx_sample_rate = SAMPLING_RATE_96KHZ; - break; - case 0: - default: - slim0_rx_sample_rate = SAMPLING_RATE_48KHZ; - } - - pr_debug("%s: slim0_rx_sample_rate = %d\n", __func__, - slim0_rx_sample_rate); - - return 0; -} - -static int slim0_tx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int sample_rate_val = 0; - - switch (slim0_tx_sample_rate) { - case SAMPLING_RATE_192KHZ: - sample_rate_val = 2; - break; - case SAMPLING_RATE_96KHZ: - sample_rate_val = 1; - break; - case SAMPLING_RATE_48KHZ: - default: - sample_rate_val = 0; - break; - } - - ucontrol->value.integer.value[0] = sample_rate_val; - pr_debug("%s: slim0_tx_sample_rate = %d\n", __func__, - slim0_tx_sample_rate); - return 0; -} - -static int slim0_tx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int rc = 0; - - pr_debug("%s: ucontrol value = %ld\n", __func__, - ucontrol->value.integer.value[0]); - - switch (ucontrol->value.integer.value[0]) { - case 2: - slim0_tx_sample_rate = SAMPLING_RATE_192KHZ; - break; - case 1: - slim0_tx_sample_rate = SAMPLING_RATE_96KHZ; - break; - case 0: - slim0_tx_sample_rate = SAMPLING_RATE_48KHZ; - break; - default: - rc = -EINVAL; - pr_err("%s: invalid sample rate being passed\n", __func__); - break; - } - - pr_debug("%s: slim0_tx_sample_rate = %d\n", __func__, - slim0_tx_sample_rate); - return rc; -} - -static int slim5_rx_bit_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - - switch (slim5_rx_bit_format) { - case SNDRV_PCM_FORMAT_S24_3LE: - ucontrol->value.integer.value[0] = 2; - break; - - case SNDRV_PCM_FORMAT_S24_LE: - ucontrol->value.integer.value[0] = 1; - break; - - case SNDRV_PCM_FORMAT_S16_LE: - default: - ucontrol->value.integer.value[0] = 0; - break; - } - - pr_debug("%s: slim5_rx_bit_format = %d, ucontrol value = %ld\n", - __func__, slim5_rx_bit_format, - ucontrol->value.integer.value[0]); - - return 0; -} - -static int slim5_rx_bit_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (ucontrol->value.integer.value[0]) { - case 2: - slim5_rx_bit_format = SNDRV_PCM_FORMAT_S24_3LE; - break; - case 1: - slim5_rx_bit_format = SNDRV_PCM_FORMAT_S24_LE; - break; - case 0: - default: - slim5_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE; - break; - } - return 0; -} - -static int slim6_rx_bit_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - - switch (slim6_rx_bit_format) { - case SNDRV_PCM_FORMAT_S24_3LE: - ucontrol->value.integer.value[0] = 2; - break; - - case SNDRV_PCM_FORMAT_S24_LE: - ucontrol->value.integer.value[0] = 1; - break; - - case SNDRV_PCM_FORMAT_S16_LE: - default: - ucontrol->value.integer.value[0] = 0; - break; - } - - pr_debug("%s: slim6_rx_bit_format = %d, ucontrol value = %ld\n", - __func__, slim6_rx_bit_format, - ucontrol->value.integer.value[0]); - - return 0; -} - -static int slim6_rx_bit_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (ucontrol->value.integer.value[0]) { - case 2: - slim6_rx_bit_format = SNDRV_PCM_FORMAT_S24_3LE; - break; - case 1: - slim6_rx_bit_format = SNDRV_PCM_FORMAT_S24_LE; - break; - case 0: - default: - slim6_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE; - break; - } - return 0; -} - -static int slim0_rx_bit_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - - switch (slim0_rx_bit_format) { - case SNDRV_PCM_FORMAT_S24_3LE: - ucontrol->value.integer.value[0] = 2; - break; - - case SNDRV_PCM_FORMAT_S24_LE: - ucontrol->value.integer.value[0] = 1; - break; - - case SNDRV_PCM_FORMAT_S16_LE: - default: - ucontrol->value.integer.value[0] = 0; - break; - } - - pr_debug("%s: slim0_rx_bit_format = %d, ucontrol value = %ld\n", - __func__, slim0_rx_bit_format, - ucontrol->value.integer.value[0]); - - return 0; -} - -static int slim0_rx_bit_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (ucontrol->value.integer.value[0]) { - case 2: - slim0_rx_bit_format = SNDRV_PCM_FORMAT_S24_3LE; - break; - case 1: - slim0_rx_bit_format = SNDRV_PCM_FORMAT_S24_LE; - break; - case 0: - default: - slim0_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE; - break; - } - return 0; -} - -static int msm_slim_5_rx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: msm_slim_5_rx_ch = %d\n", __func__, - msm_slim_5_rx_ch); - ucontrol->value.integer.value[0] = msm_slim_5_rx_ch - 1; - return 0; -} - -static int msm_slim_5_rx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - msm_slim_5_rx_ch = ucontrol->value.integer.value[0] + 1; - pr_debug("%s: msm_slim_5_rx_ch = %d\n", __func__, - msm_slim_5_rx_ch); - return 1; -} - -static int msm_slim_6_rx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: msm_slim_6_rx_ch = %d\n", __func__, - msm_slim_6_rx_ch); - ucontrol->value.integer.value[0] = msm_slim_6_rx_ch - 1; - return 0; -} - -static int msm_slim_6_rx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - msm_slim_6_rx_ch = ucontrol->value.integer.value[0] + 1; - pr_debug("%s: msm_slim_6_rx_ch = %d\n", __func__, - msm_slim_6_rx_ch); - return 1; -} - -static int msm_slim_0_rx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: msm_slim_0_rx_ch = %d\n", __func__, - msm_slim_0_rx_ch); - ucontrol->value.integer.value[0] = msm_slim_0_rx_ch - 1; - return 0; -} - -static int msm_slim_0_rx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - msm_slim_0_rx_ch = ucontrol->value.integer.value[0] + 1; - pr_debug("%s: msm_slim_0_rx_ch = %d\n", __func__, - msm_slim_0_rx_ch); - return 1; -} - -static int msm_slim_0_tx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: msm_slim_0_tx_ch = %d\n", __func__, - msm_slim_0_tx_ch); - ucontrol->value.integer.value[0] = msm_slim_0_tx_ch - 1; - return 0; -} - -static int msm_slim_0_tx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - msm_slim_0_tx_ch = ucontrol->value.integer.value[0] + 1; - pr_debug("%s: msm_slim_0_tx_ch = %d\n", __func__, msm_slim_0_tx_ch); - return 1; -} - -static int msm_slim_1_tx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: msm_slim_1_tx_ch = %d\n", __func__, - msm_slim_1_tx_ch); - ucontrol->value.integer.value[0] = msm_slim_1_tx_ch - 1; - return 0; -} - -static int msm_slim_1_tx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - msm_slim_1_tx_ch = ucontrol->value.integer.value[0] + 1; - - pr_debug("%s: msm_slim_1_tx_ch = %d\n", __func__, msm_slim_1_tx_ch); - return 1; -} - -static int msm_vi_feed_tx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = msm_vi_feed_tx_ch - 1; - pr_debug("%s: msm_vi_feed_tx_ch = %ld\n", __func__, - ucontrol->value.integer.value[0]); - return 0; -} - -static int msm_vi_feed_tx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - msm_vi_feed_tx_ch = ucontrol->value.integer.value[0] + 1; - - pr_debug("%s: msm_vi_feed_tx_ch = %d\n", __func__, msm_vi_feed_tx_ch); - return 1; -} - -static int hdmi_rx_bit_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - - switch (hdmi_rx_bit_format) { - case SNDRV_PCM_FORMAT_S24_3LE: - ucontrol->value.integer.value[0] = 2; - break; - - case SNDRV_PCM_FORMAT_S24_LE: - ucontrol->value.integer.value[0] = 1; - break; - - case SNDRV_PCM_FORMAT_S16_LE: - default: - ucontrol->value.integer.value[0] = 0; - break; - } - - pr_debug("%s: hdmi_rx_bit_format = %d, ucontrol value = %ld\n", - __func__, hdmi_rx_bit_format, - ucontrol->value.integer.value[0]); - - return 0; -} - -static int hdmi_rx_bit_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (ucontrol->value.integer.value[0]) { - case 2: - hdmi_rx_bit_format = SNDRV_PCM_FORMAT_S24_3LE; - break; - case 1: - hdmi_rx_bit_format = SNDRV_PCM_FORMAT_S24_LE; - break; - case 0: - default: - hdmi_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE; - break; - } - pr_debug("%s: hdmi_rx_bit_format = %d, ucontrol value = %ld\n", - __func__, hdmi_rx_bit_format, - ucontrol->value.integer.value[0]); - return 0; -} - -static int msm_hdmi_rx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: msm_hdmi_rx_ch = %d\n", __func__, - msm_hdmi_rx_ch); - ucontrol->value.integer.value[0] = msm_hdmi_rx_ch - 2; - - return 0; -} - -static int msm_hdmi_rx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - msm_hdmi_rx_ch = ucontrol->value.integer.value[0] + 2; - if (msm_hdmi_rx_ch > 8) { - pr_err("%s: channels %d exceeded 8.Limiting to max chs-8\n", - __func__, msm_hdmi_rx_ch); - msm_hdmi_rx_ch = 8; - } - pr_debug("%s: msm_hdmi_rx_ch = %d\n", __func__, msm_hdmi_rx_ch); - - return 1; -} - -static int hdmi_rx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int sample_rate_val = 0; - - switch (hdmi_rx_sample_rate) { - case SAMPLING_RATE_192KHZ: - sample_rate_val = 2; - break; - - case SAMPLING_RATE_96KHZ: - sample_rate_val = 1; - break; - - case SAMPLING_RATE_48KHZ: - default: - sample_rate_val = 0; - break; - } - - ucontrol->value.integer.value[0] = sample_rate_val; - pr_debug("%s: hdmi_rx_sample_rate = %d\n", __func__, - hdmi_rx_sample_rate); - - return 0; -} - -static int hdmi_rx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: ucontrol value = %ld\n", __func__, - ucontrol->value.integer.value[0]); - - switch (ucontrol->value.integer.value[0]) { - case 2: - hdmi_rx_sample_rate = SAMPLING_RATE_192KHZ; - break; - case 1: - hdmi_rx_sample_rate = SAMPLING_RATE_96KHZ; - break; - case 0: - default: - hdmi_rx_sample_rate = SAMPLING_RATE_48KHZ; - } - - pr_debug("%s: hdmi_rx_sample_rate = %d\n", __func__, - hdmi_rx_sample_rate); - - return 0; -} - -static int msm8996_auxpcm_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = msm8996_auxpcm_rate; - return 0; -} - -static int msm8996_auxpcm_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (ucontrol->value.integer.value[0]) { - case 0: - msm8996_auxpcm_rate = SAMPLING_RATE_8KHZ; - break; - case 1: - msm8996_auxpcm_rate = SAMPLING_RATE_16KHZ; - break; - default: - msm8996_auxpcm_rate = SAMPLING_RATE_8KHZ; - break; - } - return 0; -} - -static int msm_proxy_rx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: msm_proxy_rx_ch = %d\n", __func__, msm_proxy_rx_ch); - ucontrol->value.integer.value[0] = msm_proxy_rx_ch - 1; - return 0; -} - -static int msm_proxy_rx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - msm_proxy_rx_ch = ucontrol->value.integer.value[0] + 1; - pr_debug("%s: msm_proxy_rx_ch = %d\n", __func__, msm_proxy_rx_ch); - return 1; -} - -static int msm_auxpcm_be_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); - - rate->min = rate->max = msm8996_auxpcm_rate; - channels->min = channels->max = 1; - - return 0; -} - -static int msm_proxy_rx_be_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: msm_proxy_rx_ch =%d\n", __func__, msm_proxy_rx_ch); - - if (channels->max < 2) - channels->min = channels->max = 2; - channels->min = channels->max = msm_proxy_rx_ch; - rate->min = rate->max = SAMPLING_RATE_48KHZ; - return 0; -} - -static int msm_proxy_tx_be_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); - - rate->min = rate->max = SAMPLING_RATE_48KHZ; - return 0; -} - -static int msm8996_hdmi_be_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 channels->min %u channels->max %u ()\n", __func__, - channels->min, channels->max); - - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - hdmi_rx_bit_format); - if (channels->max < 2) - channels->min = channels->max = 2; - rate->min = rate->max = hdmi_rx_sample_rate; - channels->min = channels->max = msm_hdmi_rx_ch; - - return 0; -} - -static int msm_tx_be_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_tert_mi2s_tx_ch); - rate->min = rate->max = SAMPLING_RATE_48KHZ; - channels->min = channels->max = msm_tert_mi2s_tx_ch; - return 0; -} - -static int msm8996_mi2s_snd_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_debug("%s: substream = %s stream = %d\n", __func__, - substream->name, substream->stream); - - mi2s_tx_clk.enable = 1; - ret = afe_set_lpass_clock_v2(AFE_PORT_ID_TERTIARY_MI2S_TX, - &mi2s_tx_clk); - if (ret < 0) { - pr_err("%s: afe lpass clock failed, err:%d\n", __func__, ret); - goto err; - } - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - pr_err("%s: set fmt cpu dai failed, err:%d\n", __func__, ret); -err: - return ret; -} - -static void msm8996_mi2s_snd_shutdown(struct snd_pcm_substream *substream) -{ - int ret = 0; - - pr_debug("%s: substream = %s stream = %d\n", __func__, - substream->name, substream->stream); - - mi2s_tx_clk.enable = 0; - ret = afe_set_lpass_clock_v2(AFE_PORT_ID_TERTIARY_MI2S_TX, - &mi2s_tx_clk); - if (ret < 0) - pr_err("%s: afe lpass clock failed, err:%d\n", __func__, ret); -} - -static struct snd_soc_ops msm8996_mi2s_be_ops = { - .startup = msm8996_mi2s_snd_startup, - .shutdown = msm8996_mi2s_snd_shutdown, -}; - -static int msm_slim_5_rx_be_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); - - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - slim5_rx_bit_format); - rate->min = rate->max = slim5_rx_sample_rate; - channels->min = channels->max = msm_slim_5_rx_ch; - - pr_debug("%s: format = %d, rate = %d, channels = %d\n", - __func__, params_format(params), params_rate(params), - msm_slim_5_rx_ch); - - return 0; -} - -static int msm_slim_6_rx_be_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); - - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - slim6_rx_bit_format); - rate->min = rate->max = slim6_rx_sample_rate; - channels->min = channels->max = msm_slim_6_rx_ch; - - pr_debug("%s: format = %d, rate = %d, channels = %d\n", - __func__, params_format(params), params_rate(params), - msm_slim_6_rx_ch); - - return 0; -} - -static int msm_slim_0_rx_be_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); - - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - slim0_rx_bit_format); - rate->min = rate->max = slim0_rx_sample_rate; - channels->min = channels->max = msm_slim_0_rx_ch; - - pr_debug("%s: format = %d, rate = %d, channels = %d\n", - __func__, params_format(params), params_rate(params), - msm_slim_0_rx_ch); - - return 0; -} - -static int msm_slim_0_tx_be_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()\n", __func__); - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, slim0_tx_bit_format); - rate->min = rate->max = slim0_tx_sample_rate; - channels->min = channels->max = msm_slim_0_tx_ch; - - return 0; -} - -static int msm_slim_1_tx_be_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()\n", __func__); - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, slim1_tx_bit_format); - rate->min = rate->max = slim1_tx_sample_rate; - channels->min = channels->max = msm_slim_1_tx_ch; - - return 0; -} - -static int msm_slim_4_tx_be_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); - - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - SNDRV_PCM_FORMAT_S32_LE); - - rate->min = rate->max = SAMPLING_RATE_8KHZ; - channels->min = channels->max = msm_vi_feed_tx_ch; - pr_debug("%s: msm_vi_feed_tx_ch: %d\n", __func__, msm_vi_feed_tx_ch); - - return 0; -} - -static int msm_slim_5_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - int rc = 0; - void *config = NULL; - struct snd_soc_codec *codec = rtd->codec; - 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: enter\n", __func__); - rate->min = rate->max = SAMPLING_RATE_16KHZ; - channels->min = channels->max = 1; - - config = msm8996_codec_fn.get_afe_config_fn(codec, - AFE_SLIMBUS_SLAVE_PORT_CONFIG); - if (config) { - rc = afe_set_config(AFE_SLIMBUS_SLAVE_PORT_CONFIG, config, - SLIMBUS_5_TX); - if (rc) { - pr_err("%s: Failed to set slimbus slave port config %d\n", - __func__, rc); - } - } - - return rc; -} - -static int msm_be_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); - - pr_debug("%s:\n", __func__); - rate->min = rate->max = SAMPLING_RATE_48KHZ; - return 0; -} - -static const struct soc_enum msm_snd_enum[] = { - SOC_ENUM_SINGLE_EXT(2, spk_function), - SOC_ENUM_SINGLE_EXT(2, slim0_rx_ch_text), - SOC_ENUM_SINGLE_EXT(8, slim0_tx_ch_text), - SOC_ENUM_SINGLE_EXT(7, hdmi_rx_ch_text), - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_bit_format_text), - rx_bit_format_text), - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim0_rx_sample_rate_text), - slim0_rx_sample_rate_text), - SOC_ENUM_SINGLE_EXT(8, proxy_rx_ch_text), - SOC_ENUM_SINGLE_EXT(3, hdmi_rx_sample_rate_text), - SOC_ENUM_SINGLE_EXT(4, slim5_rx_sample_rate_text), - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim5_rx_bit_format_text), - slim5_rx_bit_format_text), - SOC_ENUM_SINGLE_EXT(2, slim5_rx_ch_text), - SOC_ENUM_SINGLE_EXT(2, hifi_function), - SOC_ENUM_SINGLE_EXT(2, vi_feed_ch_text), - SOC_ENUM_SINGLE_EXT(4, slim6_rx_sample_rate_text), - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim6_rx_bit_format_text), - slim6_rx_bit_format_text), - SOC_ENUM_SINGLE_EXT(2, slim6_rx_ch_text), -}; - -static const struct snd_kcontrol_new msm_snd_controls[] = { - SOC_ENUM_EXT("Speaker Function", msm_snd_enum[0], msm8996_get_spk, - msm8996_set_spk), - SOC_ENUM_EXT("SLIM_0_RX Channels", msm_snd_enum[1], - msm_slim_0_rx_ch_get, msm_slim_0_rx_ch_put), - SOC_ENUM_EXT("SLIM_5_RX Channels", msm_snd_enum[10], - msm_slim_5_rx_ch_get, msm_slim_5_rx_ch_put), - SOC_ENUM_EXT("SLIM_6_RX Channels", msm_snd_enum[15], - msm_slim_6_rx_ch_get, msm_slim_6_rx_ch_put), - SOC_ENUM_EXT("SLIM_0_TX Channels", msm_snd_enum[2], - msm_slim_0_tx_ch_get, msm_slim_0_tx_ch_put), - SOC_ENUM_EXT("SLIM_1_TX Channels", msm_snd_enum[2], - msm_slim_1_tx_ch_get, msm_slim_1_tx_ch_put), - SOC_ENUM_EXT("AUX PCM SampleRate", msm8996_auxpcm_enum[0], - msm8996_auxpcm_rate_get, - msm8996_auxpcm_rate_put), - SOC_ENUM_EXT("HDMI_RX Channels", msm_snd_enum[3], - msm_hdmi_rx_ch_get, msm_hdmi_rx_ch_put), - SOC_ENUM_EXT("SLIM_0_RX Format", msm_snd_enum[4], - slim0_rx_bit_format_get, slim0_rx_bit_format_put), - SOC_ENUM_EXT("SLIM_5_RX Format", msm_snd_enum[9], - slim5_rx_bit_format_get, slim5_rx_bit_format_put), - SOC_ENUM_EXT("SLIM_6_RX Format", msm_snd_enum[14], - slim6_rx_bit_format_get, slim6_rx_bit_format_put), - SOC_ENUM_EXT("SLIM_0_RX SampleRate", msm_snd_enum[5], - slim0_rx_sample_rate_get, slim0_rx_sample_rate_put), - SOC_ENUM_EXT("SLIM_5_RX SampleRate", msm_snd_enum[8], - slim5_rx_sample_rate_get, slim5_rx_sample_rate_put), - SOC_ENUM_EXT("SLIM_6_RX SampleRate", msm_snd_enum[13], - slim6_rx_sample_rate_get, slim6_rx_sample_rate_put), - SOC_ENUM_EXT("HDMI_RX Bit Format", msm_snd_enum[4], - hdmi_rx_bit_format_get, hdmi_rx_bit_format_put), - SOC_ENUM_EXT("PROXY_RX Channels", msm_snd_enum[6], - msm_proxy_rx_ch_get, msm_proxy_rx_ch_put), - SOC_ENUM_EXT("HDMI_RX SampleRate", msm_snd_enum[7], - hdmi_rx_sample_rate_get, hdmi_rx_sample_rate_put), - SOC_ENUM_EXT("SLIM_0_TX SampleRate", msm_snd_enum[5], - slim0_tx_sample_rate_get, slim0_tx_sample_rate_put), - SOC_ENUM_EXT("SLIM_0_TX Format", msm_snd_enum[4], - slim0_tx_bit_format_get, slim0_tx_bit_format_put), - SOC_ENUM_EXT("HiFi Function", msm_snd_enum[11], msm8996_hifi_get, - msm8996_hifi_put), - SOC_ENUM_EXT("VI_FEED_TX Channels", msm_snd_enum[12], - msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put), -}; - -static bool msm8996_swap_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 = gpio_get_value_cansleep(pdata->us_euro_gpio); - - pr_debug("%s: swap select switch %d to %d\n", __func__, value, !value); - gpio_set_value_cansleep(pdata->us_euro_gpio, !value); - return true; -} - -static int msm_afe_set_config(struct snd_soc_codec *codec) -{ - int rc; - void *config_data = NULL; - - pr_debug("%s: enter\n", __func__); - - if (!msm8996_codec_fn.get_afe_config_fn) { - dev_err(codec->dev, "%s: codec get afe config not init'ed\n", - __func__); - return -EINVAL; - } - - config_data = msm8996_codec_fn.get_afe_config_fn(codec, - AFE_CDC_REGISTERS_CONFIG); - if (config_data) { - rc = afe_set_config(AFE_CDC_REGISTERS_CONFIG, config_data, 0); - if (rc) { - pr_err("%s: Failed to set codec registers config %d\n", - __func__, rc); - return rc; - } - } - - config_data = msm8996_codec_fn.get_afe_config_fn(codec, - AFE_CDC_REGISTER_PAGE_CONFIG); - if (config_data) { - rc = afe_set_config(AFE_CDC_REGISTER_PAGE_CONFIG, config_data, - 0); - if (rc) - pr_err("%s: Failed to set cdc register page config\n", - __func__); - } - - config_data = msm8996_codec_fn.get_afe_config_fn(codec, - AFE_SLIMBUS_SLAVE_CONFIG); - if (config_data) { - rc = afe_set_config(AFE_SLIMBUS_SLAVE_CONFIG, config_data, 0); - if (rc) { - pr_err("%s: Failed to set slimbus slave config %d\n", - __func__, rc); - return rc; - } - } - - return 0; -} - -static void msm_afe_clear_config(void) -{ - afe_clear_config(AFE_CDC_REGISTERS_CONFIG); - afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG); -} - -static int msm8996_adsp_state_callback(struct notifier_block *nb, - unsigned long value, void *priv) -{ - if (value == SUBSYS_BEFORE_SHUTDOWN) { - pr_debug("%s: ADSP is about to shutdown. Clearing AFE config\n", - __func__); - msm_afe_clear_config(); - } else if (value == SUBSYS_AFTER_POWERUP) { - pr_debug("%s: ADSP is up\n", __func__); - } - - return NOTIFY_OK; -} - -static struct notifier_block adsp_state_notifier_block = { - .notifier_call = msm8996_adsp_state_callback, - .priority = -INT_MAX, -}; - -static int msm8996_wcd93xx_codec_up(struct snd_soc_codec *codec) -{ - int err; - unsigned long timeout; - int adsp_ready = 0; - - timeout = jiffies + - msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); - - do { - if (!q6core_is_adsp_ready()) { - pr_err_ratelimited("%s: ADSP Audio isn't ready\n", - __func__); - /* - * ADSP will be coming up after subsystem restart and - * it might not be fully up when the control reaches - * here. So, wait for 50msec before checking ADSP state - */ - msleep(50); - } else { - pr_debug("%s: ADSP Audio is ready\n", __func__); - adsp_ready = 1; - break; - } - } while (time_after(timeout, jiffies)); - - if (!adsp_ready) { - pr_err("%s: timed out waiting for ADSP Audio\n", __func__); - return -ETIMEDOUT; - } - - err = msm_afe_set_config(codec); - if (err) - pr_err("%s: Failed to set AFE config. err %d\n", - __func__, err); - return err; -} - -static int msm8996_tasha_codec_event_cb(struct snd_soc_codec *codec, - enum wcd9335_codec_event codec_event) -{ - switch (codec_event) { - case WCD9335_CODEC_EVENT_CODEC_UP: - return msm8996_wcd93xx_codec_up(codec); - default: - pr_err("%s: UnSupported codec event %d\n", - __func__, codec_event); - return -EINVAL; - } -} - -static int msm8996_config_hph_en0_gpio(struct snd_soc_codec *codec, bool high) -{ - struct snd_soc_card *card = codec->component.card; - struct msm8996_asoc_mach_data *pdata; - int val; - - if (!card) - return 0; - - pdata = snd_soc_card_get_drvdata(card); - if (!pdata || !gpio_is_valid(pdata->hph_en0_gpio)) - return 0; - - val = gpio_get_value_cansleep(pdata->hph_en0_gpio); - if ((!!val) == high) - return 0; - - gpio_direction_output(pdata->hph_en0_gpio, (int)high); - - return 1; -} - -static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) -{ - int err; - void *config_data; - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_component *aux_comp; - void *mbhc_calibration; - struct snd_card *card; - struct snd_info_entry *entry; - struct msm8996_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(rtd->card); - - /* Codec SLIMBUS configuration - * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8, RX9, RX10, RX11, RX12, RX13 - * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13 - * TX14, TX15, TX16 - */ - unsigned int rx_ch[TASHA_RX_MAX] = {144, 145, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, 156}; - unsigned int tx_ch[TASHA_TX_MAX] = {128, 129, 130, 131, 132, 133, - 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143}; - - pr_info("%s: dev_name%s\n", __func__, dev_name(cpu_dai->dev)); - - rtd->pmdown_time = 0; - - err = snd_soc_add_codec_controls(codec, msm_snd_controls, - ARRAY_SIZE(msm_snd_controls)); - if (err < 0) { - pr_err("%s: add_codec_controls failed, err %d\n", - __func__, err); - return err; - } - - err = msm8996_liquid_init_docking(); - if (err) { - pr_err("%s: 8996 init Docking stat IRQ failed (%d)\n", - __func__, err); - return err; - } - - err = msm8996_ext_us_amp_init(); - if (err) { - pr_err("%s: 8996 US Emitter GPIO init failed (%d)\n", - __func__, err); - return err; - } - - snd_soc_dapm_new_controls(dapm, msm8996_dapm_widgets, - ARRAY_SIZE(msm8996_dapm_widgets)); - - snd_soc_dapm_add_routes(dapm, wcd9335_audio_paths, - ARRAY_SIZE(wcd9335_audio_paths)); - snd_soc_dapm_enable_pin(dapm, "Lineout_1 amp"); - snd_soc_dapm_enable_pin(dapm, "Lineout_3 amp"); - snd_soc_dapm_enable_pin(dapm, "Lineout_2 amp"); - snd_soc_dapm_enable_pin(dapm, "Lineout_4 amp"); - - snd_soc_dapm_ignore_suspend(dapm, "Lineout_1 amp"); - snd_soc_dapm_ignore_suspend(dapm, "Lineout_3 amp"); - snd_soc_dapm_ignore_suspend(dapm, "Lineout_2 amp"); - snd_soc_dapm_ignore_suspend(dapm, "Lineout_4 amp"); - snd_soc_dapm_ignore_suspend(dapm, "ultrasound amp"); - snd_soc_dapm_ignore_suspend(dapm, "Handset Mic"); - snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); - snd_soc_dapm_ignore_suspend(dapm, "ANCRight Headset Mic"); - snd_soc_dapm_ignore_suspend(dapm, "ANCLeft Headset Mic"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic4"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic5"); - snd_soc_dapm_ignore_suspend(dapm, "Analog Mic4"); - snd_soc_dapm_ignore_suspend(dapm, "Analog Mic6"); - snd_soc_dapm_ignore_suspend(dapm, "Analog Mic7"); - snd_soc_dapm_ignore_suspend(dapm, "Analog Mic8"); - snd_soc_dapm_ignore_suspend(dapm, "MADINPUT"); - snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_INPUT"); - snd_soc_dapm_ignore_suspend(dapm, "EAR"); - snd_soc_dapm_ignore_suspend(dapm, "LINEOUT1"); - snd_soc_dapm_ignore_suspend(dapm, "LINEOUT2"); - snd_soc_dapm_ignore_suspend(dapm, "LINEOUT3"); - snd_soc_dapm_ignore_suspend(dapm, "LINEOUT4"); - snd_soc_dapm_ignore_suspend(dapm, "ANC EAR"); - snd_soc_dapm_ignore_suspend(dapm, "AMIC1"); - snd_soc_dapm_ignore_suspend(dapm, "AMIC2"); - snd_soc_dapm_ignore_suspend(dapm, "AMIC3"); - snd_soc_dapm_ignore_suspend(dapm, "AMIC4"); - snd_soc_dapm_ignore_suspend(dapm, "AMIC5"); - snd_soc_dapm_ignore_suspend(dapm, "AMIC6"); - snd_soc_dapm_ignore_suspend(dapm, "DMIC1"); - snd_soc_dapm_ignore_suspend(dapm, "DMIC2"); - snd_soc_dapm_ignore_suspend(dapm, "DMIC3"); - snd_soc_dapm_ignore_suspend(dapm, "DMIC4"); - snd_soc_dapm_ignore_suspend(dapm, "DMIC5"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0"); - snd_soc_dapm_ignore_suspend(dapm, "DMIC0"); - snd_soc_dapm_ignore_suspend(dapm, "SPK1 OUT"); - snd_soc_dapm_ignore_suspend(dapm, "SPK2 OUT"); - snd_soc_dapm_ignore_suspend(dapm, "HPHL"); - snd_soc_dapm_ignore_suspend(dapm, "HPHR"); - snd_soc_dapm_ignore_suspend(dapm, "ANC HPHL"); - snd_soc_dapm_ignore_suspend(dapm, "ANC HPHR"); - snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT1"); - snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT2"); - snd_soc_dapm_ignore_suspend(dapm, "AIF4 VI"); - snd_soc_dapm_ignore_suspend(dapm, "VIINPUT"); - - snd_soc_dapm_sync(dapm); - - snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), - tx_ch, ARRAY_SIZE(rx_ch), rx_ch); - - msm8996_codec_fn.get_afe_config_fn = tasha_get_afe_config; - msm8996_codec_fn.mbhc_hs_detect_exit = tasha_mbhc_hs_detect_exit; - - err = msm_afe_set_config(codec); - if (err) { - pr_err("%s: Failed to set AFE config %d\n", __func__, err); - goto out; - } - - config_data = msm8996_codec_fn.get_afe_config_fn(codec, - AFE_AANC_VERSION); - if (config_data) { - err = afe_set_config(AFE_AANC_VERSION, config_data, 0); - if (err) { - pr_err("%s: Failed to set aanc version %d\n", - __func__, err); - goto out; - } - } - config_data = msm8996_codec_fn.get_afe_config_fn(codec, - AFE_CDC_CLIP_REGISTERS_CONFIG); - if (config_data) { - err = afe_set_config(AFE_CDC_CLIP_REGISTERS_CONFIG, - config_data, 0); - if (err) { - pr_err("%s: Failed to set clip registers %d\n", - __func__, err); - goto out; - } - } - config_data = msm8996_codec_fn.get_afe_config_fn(codec, - AFE_CLIP_BANK_SEL); - if (config_data) { - err = afe_set_config(AFE_CLIP_BANK_SEL, config_data, 0); - if (err) { - pr_err("%s: Failed to set AFE bank selection %d\n", - __func__, err); - goto out; - } - } - /* Start mbhc */ - tasha_mbhc_zdet_gpio_ctrl(msm8996_config_hph_en0_gpio, rtd->codec); - mbhc_calibration = def_tasha_mbhc_cal(); - if (mbhc_calibration) { - wcd_mbhc_cfg.calibration = mbhc_calibration; - err = tasha_mbhc_hs_detect(codec, &wcd_mbhc_cfg); - if (err) { - pr_err("%s: mbhc hs detect failed, err:%d\n", - __func__, err); - goto out; - } - } else { - pr_err("%s: mbhc_cfg calibration is NULL\n", __func__); - err = -ENOMEM; - goto out; - } - adsp_state_notifier = subsys_notif_register_notifier("adsp", - &adsp_state_notifier_block); - if (!adsp_state_notifier) { - pr_err("%s: Failed to register adsp state notifier\n", - __func__); - err = -EFAULT; - msm8996_codec_fn.mbhc_hs_detect_exit(codec); - goto out; - } - - tasha_event_register(msm8996_tasha_codec_event_cb, rtd->codec); - - /* - * Send speaker configuration only for WSA8810. - * Defalut configuration is for WSA8815. - */ - if (!list_empty(&rtd->card->aux_comp_list)) { - aux_comp = list_first_entry(&rtd->card->aux_comp_list, - struct snd_soc_component, list_aux); - if (!strcmp(aux_comp->name, WSA8810_NAME_1) || - !strcmp(aux_comp->name, WSA8810_NAME_2)) { - tasha_set_spkr_mode(rtd->codec, SPKR_MODE_1); - tasha_set_spkr_gain_offset(rtd->codec, - RX_GAIN_OFFSET_M1P5_DB); - } - } - codec_reg_done = true; - - card = rtd->card->snd_card; - entry = snd_info_create_subdir(card->module, "codecs", - card->proc_root); - if (!entry) { - pr_debug("%s: Cannot create codecs module entry\n", - __func__); - err = 0; - goto out; - } - pdata->codec_root = entry; - tasha_codec_info_create_codec_entry(pdata->codec_root, codec); - - return 0; -out: - return err; -} - -static void *def_tasha_mbhc_cal(void) -{ - void *tasha_wcd_cal; - struct wcd_mbhc_btn_detect_cfg *btn_cfg; - u16 *btn_high; - - tasha_wcd_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS, - WCD9XXX_MBHC_DEF_RLOADS), GFP_KERNEL); - if (!tasha_wcd_cal) - return NULL; - -#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(tasha_wcd_cal)->X) = (Y)) - S(v_hs_max, 1500); -#undef S -#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(tasha_wcd_cal)->X) = (Y)) - S(num_btn, WCD_MBHC_DEF_BUTTONS); -#undef S - - btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(tasha_wcd_cal); - btn_high = ((void *)&btn_cfg->_v_btn_low) + - (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn); - - btn_high[0] = 75; - btn_high[1] = 150; - btn_high[2] = 237; - btn_high[3] = 500; - btn_high[4] = 500; - btn_high[5] = 500; - btn_high[6] = 500; - btn_high[7] = 500; - - return tasha_wcd_cal; -} - -static int msm_snd_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_dai_link *dai_link = rtd->dai_link; - - int ret = 0; - u32 rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; - u32 rx_ch_cnt = 0, tx_ch_cnt = 0; - u32 user_set_tx_ch = 0; - u32 rx_ch_count; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); - if (ret < 0) { - pr_err("%s: failed to get codec chan map, err:%d\n", - __func__, ret); - goto end; - } - if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_5_RX) { - pr_debug("%s: rx_5_ch=%d\n", __func__, - msm_slim_5_rx_ch); - rx_ch_count = msm_slim_5_rx_ch; - } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_6_RX) { - pr_debug("%s: rx_6_ch=%d\n", __func__, - msm_slim_6_rx_ch); - rx_ch_count = msm_slim_6_rx_ch; - } else { - pr_debug("%s: rx_0_ch=%d\n", __func__, - msm_slim_0_rx_ch); - rx_ch_count = msm_slim_0_rx_ch; - } - ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, - rx_ch_count, rx_ch); - if (ret < 0) { - pr_err("%s: failed to set cpu chan map, err:%d\n", - __func__, ret); - goto end; - } - } else { - - pr_debug("%s: %s_tx_dai_id_%d_ch=%d\n", __func__, - codec_dai->name, codec_dai->id, user_set_tx_ch); - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); - if (ret < 0) { - pr_err("%s: failed to get codec chan map\n, err:%d\n", - __func__, ret); - goto end; - } - /* For _tx1 case */ - if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_0_TX) - user_set_tx_ch = msm_slim_0_tx_ch; - /* For _tx3 case */ - else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_1_TX) - user_set_tx_ch = msm_slim_1_tx_ch; - else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_3_TX) - /* DAI 5 is used for external EC reference from codec. - * Since Rx is fed as reference for EC, the config of - * this DAI is based on that of the Rx path. - */ - user_set_tx_ch = msm_slim_0_rx_ch; - else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_4_TX) - user_set_tx_ch = msm_vi_feed_tx_ch; - else - user_set_tx_ch = tx_ch_cnt; - - pr_debug("%s: msm_slim_0_tx_ch(%d) user_set_tx_ch(%d) tx_ch_cnt(%d), BE id (%d)\n", - __func__, msm_slim_0_tx_ch, user_set_tx_ch, - tx_ch_cnt, dai_link->id); - - ret = snd_soc_dai_set_channel_map(cpu_dai, - user_set_tx_ch, tx_ch, 0, 0); - if (ret < 0) { - pr_err("%s: failed to set cpu chan map, err:%d\n", - __func__, ret); - goto end; - } - } -end: - return ret; -} - -static int msm_snd_cpe_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_dai_link *dai_link = rtd->dai_link; - - int ret = 0; - u32 tx_ch[SLIM_MAX_TX_PORTS]; - u32 tx_ch_cnt = 0; - u32 user_set_tx_ch = 0; - - if (substream->stream != SNDRV_PCM_STREAM_CAPTURE) { - pr_err("%s: Invalid stream type %d\n", - __func__, substream->stream); - ret = -EINVAL; - goto end; - } - - pr_debug("%s: %s_tx_dai_id_%d\n", __func__, - codec_dai->name, codec_dai->id); - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, NULL, NULL); - if (ret < 0) { - pr_err("%s: failed to get codec chan map\n, err:%d\n", - __func__, ret); - goto end; - } - - user_set_tx_ch = tx_ch_cnt; - - pr_debug("%s: tx_ch_cnt(%d) BE id %d\n", - __func__, tx_ch_cnt, dai_link->id); - - ret = snd_soc_dai_set_channel_map(cpu_dai, - user_set_tx_ch, tx_ch, 0, 0); - if (ret < 0) - pr_err("%s: failed to set cpu chan map, err:%d\n", - __func__, ret); -end: - return ret; -} - -static struct snd_soc_ops msm8996_be_ops = { - .hw_params = msm_snd_hw_params, -}; - -static struct snd_soc_ops msm8996_cpe_ops = { - .hw_params = msm_snd_cpe_hw_params, -}; - -static int msm8996_slimbus_2_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int ret = 0; - unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; - unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0; - unsigned int num_tx_ch = 0; - unsigned int num_rx_ch = 0; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - num_rx_ch = params_channels(params); - pr_debug("%s: %s rx_dai_id = %d num_ch = %d\n", __func__, - codec_dai->name, codec_dai->id, num_rx_ch); - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); - if (ret < 0) { - pr_err("%s: failed to get codec chan map, err:%d\n", - __func__, ret); - goto end; - } - ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, - num_rx_ch, rx_ch); - if (ret < 0) { - pr_err("%s: failed to set cpu chan map, err:%d\n", - __func__, ret); - goto end; - } - } else { - num_tx_ch = params_channels(params); - pr_debug("%s: %s tx_dai_id = %d num_ch = %d\n", __func__, - codec_dai->name, codec_dai->id, num_tx_ch); - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); - if (ret < 0) { - pr_err("%s: failed to get codec chan map, err:%d\n", - __func__, ret); - goto end; - } - ret = snd_soc_dai_set_channel_map(cpu_dai, - num_tx_ch, tx_ch, 0, 0); - if (ret < 0) { - pr_err("%s: failed to set cpu chan map, err:%d\n", - __func__, ret); - goto end; - } - } -end: - return ret; -} - -static struct snd_soc_ops msm8996_slimbus_2_be_ops = { - .hw_params = msm8996_slimbus_2_hw_params, -}; - -static int msm8996_get_ll_qos_val(struct snd_pcm_runtime *runtime) -{ - int usecs; - - /* take 10% of period time as the deadline */ - usecs = (100000 / runtime->rate) * runtime->period_size; - usecs += ((100000 % runtime->rate) * runtime->period_size) / - runtime->rate; - - return usecs; -} - -static int msm8996_mm5_prepare(struct snd_pcm_substream *substream) -{ - if (pm_qos_request_active(&substream->latency_pm_qos_req)) - pm_qos_remove_request(&substream->latency_pm_qos_req); - pm_qos_add_request(&substream->latency_pm_qos_req, - PM_QOS_CPU_DMA_LATENCY, - msm8996_get_ll_qos_val(substream->runtime)); - return 0; -} - -static struct snd_soc_ops msm8996_mm5_ops = { - .prepare = msm8996_mm5_prepare, -}; - -/* Digital audio interface glue - connects codec <---> CPU */ -static struct snd_soc_dai_link msm8996_common_dai_links[] = { - /* FrontEnd DAI Links */ - { - .name = "MSM8996 Media1", - .stream_name = "MultiMedia1", - .cpu_dai_name = "MultiMedia1", - .platform_name = "msm-pcm-dsp.0", - .dynamic = 1, - .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA1 - }, - { - .name = "MSM8996 Media2", - .stream_name = "MultiMedia2", - .cpu_dai_name = "MultiMedia2", - .platform_name = "msm-pcm-dsp.0", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA2, - }, - { - .name = "VoiceMMode1", - .stream_name = "VoiceMMode1", - .cpu_dai_name = "VoiceMMode1", - .platform_name = "msm-pcm-voice", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_VOICEMMODE1, - }, - { - .name = "MSM VoIP", - .stream_name = "VoIP", - .cpu_dai_name = "VoIP", - .platform_name = "msm-voip-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_VOIP, - }, - { - .name = "MSM8996 ULL", - .stream_name = "MultiMedia3", - .cpu_dai_name = "MultiMedia3", - .platform_name = "msm-pcm-dsp.2", - .dynamic = 1, - .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA3, - }, - /* Hostless PCM purpose */ - { - .name = "SLIMBUS_0 Hostless", - .stream_name = "SLIMBUS_0 Hostless", - .cpu_dai_name = "SLIMBUS0_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 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 dailink has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - { - .name = "Tertiary MI2S TX_Hostless", - .stream_name = "Tertiary MI2S_TX Hostless Capture", - .cpu_dai_name = "TERT_MI2S_TX_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - { - .name = "MSM AFE-PCM RX", - .stream_name = "AFE-PROXY RX", - .cpu_dai_name = "msm-dai-q6-dev.241", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .platform_name = "msm-pcm-afe", - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - }, - { - .name = "MSM AFE-PCM TX", - .stream_name = "AFE-PROXY TX", - .cpu_dai_name = "msm-dai-q6-dev.240", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .platform_name = "msm-pcm-afe", - .ignore_suspend = 1, - }, - { - .name = "MSM8996 Compress1", - .stream_name = "Compress1", - .cpu_dai_name = "MultiMedia4", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA4, - }, - { - .name = "AUXPCM Hostless", - .stream_name = "AUXPCM Hostless", - .cpu_dai_name = "AUXPCM_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 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", - }, - { - .name = "SLIMBUS_1 Hostless", - .stream_name = "SLIMBUS_1 Hostless", - .cpu_dai_name = "SLIMBUS1_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 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 dailink has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - { - .name = "SLIMBUS_3 Hostless", - .stream_name = "SLIMBUS_3 Hostless", - .cpu_dai_name = "SLIMBUS3_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 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 dailink has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - { - .name = "SLIMBUS_4 Hostless", - .stream_name = "SLIMBUS_4 Hostless", - .cpu_dai_name = "SLIMBUS4_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 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 dailink has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - { - .name = "VoLTE", - .stream_name = "VoLTE", - .cpu_dai_name = "VoLTE", - .platform_name = "msm-pcm-voice", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 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", - .id = MSM_FRONTEND_DAI_VOLTE, - }, - { - .name = "MSM8996 LowLatency", - .stream_name = "MultiMedia5", - .cpu_dai_name = "MultiMedia5", - .platform_name = "msm-pcm-dsp.1", - .dynamic = 1, - .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, - .dpcm_playback = 1, - .dpcm_capture = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA5, - .ops = &msm8996_mm5_ops, - }, - { - .name = "Listen 1 Audio Service", - .stream_name = "Listen 1 Audio Service", - .cpu_dai_name = "LSM1", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM1, - }, - /* Multiple Tunnel instances */ - { - .name = "MSM8996 Compress2", - .stream_name = "Compress2", - .cpu_dai_name = "MultiMedia7", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA7, - }, - { - .name = "MSM8996 Compress3", - .stream_name = "Compress3", - .cpu_dai_name = "MultiMedia10", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA10, - }, - { - .name = "MSM8996 ULL NOIRQ", - .stream_name = "MM_NOIRQ", - .cpu_dai_name = "MultiMedia8", - .platform_name = "msm-pcm-dsp-noirq", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA8, - }, - { - .name = "QCHAT", - .stream_name = "QCHAT", - .cpu_dai_name = "QCHAT", - .platform_name = "msm-pcm-voice", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 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", - .id = MSM_FRONTEND_DAI_QCHAT, - }, - /* HDMI Hostless */ - { - .name = "HDMI_RX_HOSTLESS", - .stream_name = "HDMI_RX_HOSTLESS", - .cpu_dai_name = "HDMI_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - { - .name = "VoiceMMode2", - .stream_name = "VoiceMMode2", - .cpu_dai_name = "VoiceMMode2", - .platform_name = "msm-pcm-voice", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_VOICEMMODE2, - }, - { - .name = "INT_HFP_BT Hostless", - .stream_name = "INT_HFP_BT Hostless", - .cpu_dai_name = "INT_HFP_BT_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 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", - }, - { - .name = "MSM8996 HFP TX", - .stream_name = "MultiMedia6", - .cpu_dai_name = "MultiMedia6", - .platform_name = "msm-pcm-loopback", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .ignore_suspend = 1, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA6, - }, - /* LSM FE */ - { - .name = "Listen 2 Audio Service", - .stream_name = "Listen 2 Audio Service", - .cpu_dai_name = "LSM2", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM2, - }, - { - .name = "Listen 3 Audio Service", - .stream_name = "Listen 3 Audio Service", - .cpu_dai_name = "LSM3", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM3, - }, - { - .name = "Listen 4 Audio Service", - .stream_name = "Listen 4 Audio Service", - .cpu_dai_name = "LSM4", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM4, - }, - { - .name = "Listen 5 Audio Service", - .stream_name = "Listen 5 Audio Service", - .cpu_dai_name = "LSM5", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM5, - }, - { - .name = "Listen 6 Audio Service", - .stream_name = "Listen 6 Audio Service", - .cpu_dai_name = "LSM6", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM6, - }, - { - .name = "Listen 7 Audio Service", - .stream_name = "Listen 7 Audio Service", - .cpu_dai_name = "LSM7", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM7, - }, - { - .name = "Listen 8 Audio Service", - .stream_name = "Listen 8 Audio Service", - .cpu_dai_name = "LSM8", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM8, - }, - { - .name = "MSM8996 Media9", - .stream_name = "MultiMedia9", - .cpu_dai_name = "MultiMedia9", - .platform_name = "msm-pcm-dsp.0", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA9, - }, - { - .name = "VoWLAN", - .stream_name = "VoWLAN", - .cpu_dai_name = "VoWLAN", - .platform_name = "msm-pcm-voice", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_VOWLAN, - }, - { - .name = "MSM8996 Compress4", - .stream_name = "Compress4", - .cpu_dai_name = "MultiMedia11", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA11, - }, - { - .name = "MSM8996 Compress5", - .stream_name = "Compress5", - .cpu_dai_name = "MultiMedia12", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA12, - }, - { - .name = "MSM8996 Compress6", - .stream_name = "Compress6", - .cpu_dai_name = "MultiMedia13", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA13, - }, - { - .name = "MSM8996 Compress7", - .stream_name = "Compress7", - .cpu_dai_name = "MultiMedia14", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA14, - }, - { - .name = "MSM8996 Compress8", - .stream_name = "Compress8", - .cpu_dai_name = "MultiMedia15", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA15, - }, - { - .name = "MSM8996 ULL NOIRQ_2", - .stream_name = "MM_NOIRQ_2", - .cpu_dai_name = "MultiMedia16", - .platform_name = "msm-pcm-dsp-noirq", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA16, - }, - { - .name = "Circuit-Switch Voice", - .stream_name = "CS-Voice", - .cpu_dai_name = "CS-VOICE", - .platform_name = "msm-pcm-voice", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .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, - .id = MSM_FRONTEND_DAI_CS_VOICE, - }, - { - .name = "Voice2", - .stream_name = "Voice2", - .cpu_dai_name = "Voice2", - .platform_name = "msm-pcm-voice", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 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", - .id = MSM_FRONTEND_DAI_VOICE2, - }, -}; - -static struct snd_soc_dai_link msm8996_tasha_fe_dai_links[] = { - { - .name = LPASS_BE_SLIMBUS_4_TX, - .stream_name = "Slimbus4 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16393", - .platform_name = "msm-pcm-hostless", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_vifeedback", - .id = MSM_BACKEND_DAI_SLIMBUS_4_TX, - .be_hw_params_fixup = msm_slim_4_tx_be_hw_params_fixup, - .ops = &msm8996_be_ops, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - }, - /* Ultrasound RX DAI Link */ - { - .name = "SLIMBUS_2 Hostless Playback", - .stream_name = "SLIMBUS_2 Hostless Playback", - .cpu_dai_name = "msm-dai-q6-dev.16388", - .platform_name = "msm-pcm-hostless", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_rx2", - .ignore_suspend = 1, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ops = &msm8996_slimbus_2_be_ops, - }, - /* Ultrasound TX DAI Link */ - { - .name = "SLIMBUS_2 Hostless Capture", - .stream_name = "SLIMBUS_2 Hostless Capture", - .cpu_dai_name = "msm-dai-q6-dev.16389", - .platform_name = "msm-pcm-hostless", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_tx2", - .ignore_suspend = 1, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ops = &msm8996_slimbus_2_be_ops, - }, - /* CPE LSM direct dai-link */ - { - .name = "CPE Listen service", - .stream_name = "CPE Listen Audio Service", - .cpu_dai_name = "msm-dai-slim", - .platform_name = "msm-cpe-lsm", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "tasha_mad1", - .codec_name = "tasha_codec", - .ops = &msm8996_cpe_ops, - }, - /* slimbus rx 6 hostless */ - { - .name = "SLIMBUS_6 Hostless Playback", - .stream_name = "SLIMBUS_6 Hostless", - .cpu_dai_name = "SLIMBUS6_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 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 dailink has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - /* CPE LSM EC PP direct dai-link */ - { - .name = "CPE Listen service ECPP", - .stream_name = "CPE Listen Audio Service ECPP", - .cpu_dai_name = "CPE_LSM_NOHOST", - .platform_name = "msm-cpe-lsm.3", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "tasha_cpe", - .codec_name = "tasha_codec", - }, -}; - -static struct snd_soc_dai_link msm8996_common_be_dai_links[] = { - /* Backend AFE DAI Links */ - { - .name = LPASS_BE_AFE_PCM_RX, - .stream_name = "AFE Playback", - .cpu_dai_name = "msm-dai-q6-dev.224", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_AFE_PCM_RX, - .be_hw_params_fixup = msm_proxy_rx_be_hw_params_fixup, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_AFE_PCM_TX, - .stream_name = "AFE Capture", - .cpu_dai_name = "msm-dai-q6-dev.225", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_AFE_PCM_TX, - .be_hw_params_fixup = msm_proxy_tx_be_hw_params_fixup, - .ignore_suspend = 1, - }, - /* Primary AUX PCM Backend DAI Links */ - { - .name = LPASS_BE_AUXPCM_RX, - .stream_name = "AUX PCM Playback", - .cpu_dai_name = "msm-dai-q6-auxpcm.1", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_AUXPCM_RX, - .be_hw_params_fixup = msm_auxpcm_be_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - /* this dainlink has playback support */ - }, - { - .name = LPASS_BE_AUXPCM_TX, - .stream_name = "AUX PCM Capture", - .cpu_dai_name = "msm-dai-q6-auxpcm.1", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_AUXPCM_TX, - .be_hw_params_fixup = msm_auxpcm_be_params_fixup, - .ignore_suspend = 1, - }, - /* Incall Record Uplink BACK END DAI Link */ - { - .name = LPASS_BE_INCALL_RECORD_TX, - .stream_name = "Voice Uplink Capture", - .cpu_dai_name = "msm-dai-q6-dev.32772", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_INCALL_RECORD_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - }, - /* Incall Record Downlink BACK END DAI Link */ - { - .name = LPASS_BE_INCALL_RECORD_RX, - .stream_name = "Voice Downlink Capture", - .cpu_dai_name = "msm-dai-q6-dev.32771", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_INCALL_RECORD_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - }, - /* Incall Music BACK END DAI Link */ - { - .name = LPASS_BE_VOICE_PLAYBACK_TX, - .stream_name = "Voice Farend Playback", - .cpu_dai_name = "msm-dai-q6-dev.32773", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - }, - /* Incall Music 2 BACK END DAI Link */ - { - .name = LPASS_BE_VOICE2_PLAYBACK_TX, - .stream_name = "Voice2 Farend Playback", - .cpu_dai_name = "msm-dai-q6-dev.32770", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_TERT_MI2S_TX, - .stream_name = "Tertiary MI2S Capture", - .cpu_dai_name = "msm-dai-q6-mi2s.2", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - .be_hw_params_fixup = msm_tx_be_hw_params_fixup, - .ops = &msm8996_mi2s_be_ops, - .ignore_suspend = 1, - } -}; - -static struct snd_soc_dai_link msm8996_tasha_be_dai_links[] = { - /* Backend DAI Links */ - { - .name = LPASS_BE_SLIMBUS_0_RX, - .stream_name = "Slimbus Playback", - .cpu_dai_name = "msm-dai-q6-dev.16384", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_mix_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, - .init = &msm_audrx_init, - .be_hw_params_fixup = msm_slim_0_rx_be_hw_params_fixup, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - .ops = &msm8996_be_ops, - }, - { - .name = LPASS_BE_SLIMBUS_0_TX, - .stream_name = "Slimbus Capture", - .cpu_dai_name = "msm-dai-q6-dev.16385", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_tx1", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, - .be_hw_params_fixup = msm_slim_0_tx_be_hw_params_fixup, - .ignore_suspend = 1, - .ops = &msm8996_be_ops, - }, - { - .name = LPASS_BE_SLIMBUS_1_RX, - .stream_name = "Slimbus1 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16386", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_mix_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_1_RX, - .be_hw_params_fixup = msm_slim_0_rx_be_hw_params_fixup, - .ops = &msm8996_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_1_TX, - .stream_name = "Slimbus1 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16387", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_tx3", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_1_TX, - .be_hw_params_fixup = msm_slim_1_tx_be_hw_params_fixup, - .ops = &msm8996_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_3_RX, - .stream_name = "Slimbus3 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16390", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_mix_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_3_RX, - .be_hw_params_fixup = msm_slim_0_rx_be_hw_params_fixup, - .ops = &msm8996_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_3_TX, - .stream_name = "Slimbus3 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16391", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_tx1", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_3_TX, - .be_hw_params_fixup = msm_slim_0_tx_be_hw_params_fixup, - .ops = &msm8996_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_4_RX, - .stream_name = "Slimbus4 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16392", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_mix_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_4_RX, - .be_hw_params_fixup = msm_slim_0_rx_be_hw_params_fixup, - .ops = &msm8996_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_5_RX, - .stream_name = "Slimbus5 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16394", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_rx3", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_5_RX, - .be_hw_params_fixup = msm_slim_5_rx_be_hw_params_fixup, - .ops = &msm8996_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - /* MAD BE */ - { - .name = LPASS_BE_SLIMBUS_5_TX, - .stream_name = "Slimbus5 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16395", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_mad1", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_5_TX, - .be_hw_params_fixup = msm_slim_5_tx_be_hw_params_fixup, - .ops = &msm8996_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_6_RX, - .stream_name = "Slimbus6 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16396", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_rx4", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_6_RX, - .be_hw_params_fixup = msm_slim_6_rx_be_hw_params_fixup, - .ops = &msm8996_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, -}; - -static struct snd_soc_dai_link msm8996_hdmi_dai_link[] = { - /* HDMI BACK END DAI Link */ - { - .name = LPASS_BE_HDMI, - .stream_name = "HDMI Playback", - .cpu_dai_name = "msm-dai-q6-hdmi.8", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-hdmi-audio-codec-rx", - .codec_dai_name = "msm_hdmi_audio_codec_rx_dai", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_HDMI_RX, - .be_hw_params_fixup = msm8996_hdmi_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, -}; - -static struct snd_soc_dai_link msm8996_tasha_dai_links[ - ARRAY_SIZE(msm8996_common_dai_links) + - ARRAY_SIZE(msm8996_tasha_fe_dai_links) + - ARRAY_SIZE(msm8996_common_be_dai_links) + - ARRAY_SIZE(msm8996_tasha_be_dai_links) + - ARRAY_SIZE(msm8996_hdmi_dai_link)]; - -static int msm8996_wsa881x_init(struct snd_soc_component *component) -{ - u8 spkleft_ports[WSA881X_MAX_SWR_PORTS] = {100, 101, 102, 106}; - u8 spkright_ports[WSA881X_MAX_SWR_PORTS] = {103, 104, 105, 107}; - unsigned int ch_rate[WSA881X_MAX_SWR_PORTS] = {2400, 600, 300, 1200}; - unsigned int ch_mask[WSA881X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3}; - struct snd_soc_codec *codec = snd_soc_component_to_codec(component); - struct msm8996_asoc_mach_data *pdata; - struct snd_soc_dapm_context *dapm; - - if (!codec) { - pr_err("%s codec is NULL\n", __func__); - return -EINVAL; - } - - dapm = snd_soc_codec_get_dapm(codec); - - if (!strcmp(component->name_prefix, "SpkrLeft")) { - dev_dbg(codec->dev, "%s: setting left ch map to codec %s\n", - __func__, codec->component.name); - wsa881x_set_channel_map(codec, &spkleft_ports[0], - WSA881X_MAX_SWR_PORTS, &ch_mask[0], - &ch_rate[0]); - if (dapm->component) { - snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN"); - snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR"); - } - } else if (!strcmp(component->name_prefix, "SpkrRight")) { - dev_dbg(codec->dev, "%s: setting right ch map to codec %s\n", - __func__, codec->component.name); - wsa881x_set_channel_map(codec, &spkright_ports[0], - WSA881X_MAX_SWR_PORTS, &ch_mask[0], - &ch_rate[0]); - if (dapm->component) { - snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN"); - snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR"); - } - } else { - dev_err(codec->dev, "%s: wrong codec name %s\n", __func__, - codec->component.name); - return -EINVAL; - } - pdata = snd_soc_card_get_drvdata(component->card); - if (pdata && pdata->codec_root) - wsa881x_codec_info_create_codec_entry(pdata->codec_root, - codec); - - return 0; -} - -struct snd_soc_card snd_soc_card_tasha_msm8996 = { - .name = "msm8996-tasha-snd-card", -}; - -static int msm8996_populate_dai_link_component_of_node( - struct snd_soc_card *card) -{ - int i, index, ret = 0; - struct device *cdev = card->dev; - struct snd_soc_dai_link *dai_link = card->dai_link; - struct device_node *np; - - if (!cdev) { - pr_err("%s: Sound card device memory NULL\n", __func__); - return -ENODEV; - } - - for (i = 0; i < card->num_links; i++) { - if (dai_link[i].platform_of_node && dai_link[i].cpu_of_node) - continue; - - /* populate platform_of_node for snd card dai links */ - if (dai_link[i].platform_name && - !dai_link[i].platform_of_node) { - index = of_property_match_string(cdev->of_node, - "asoc-platform-names", - dai_link[i].platform_name); - if (index < 0) { - pr_err("%s: No match found for platform name: %s\n", - __func__, dai_link[i].platform_name); - ret = index; - goto err; - } - np = of_parse_phandle(cdev->of_node, "asoc-platform", - index); - if (!np) { - pr_err("%s: retrieving phandle for platform %s, index %d failed\n", - __func__, dai_link[i].platform_name, - index); - ret = -ENODEV; - goto err; - } - dai_link[i].platform_of_node = np; - dai_link[i].platform_name = NULL; - } - - /* populate cpu_of_node for snd card dai links */ - if (dai_link[i].cpu_dai_name && !dai_link[i].cpu_of_node) { - index = of_property_match_string(cdev->of_node, - "asoc-cpu-names", - dai_link[i].cpu_dai_name); - if (index >= 0) { - np = of_parse_phandle(cdev->of_node, "asoc-cpu", - index); - if (!np) { - pr_err("%s: retrieving phandle for cpu dai %s failed\n", - __func__, - dai_link[i].cpu_dai_name); - ret = -ENODEV; - goto err; - } - dai_link[i].cpu_of_node = np; - dai_link[i].cpu_dai_name = NULL; - } - } - - /* populate codec_of_node for snd card dai links */ - if (dai_link[i].codec_name && !dai_link[i].codec_of_node) { - index = of_property_match_string(cdev->of_node, - "asoc-codec-names", - dai_link[i].codec_name); - if (index < 0) - continue; - np = of_parse_phandle(cdev->of_node, "asoc-codec", - index); - if (!np) { - pr_err("%s: retrieving phandle for codec %s failed\n", - __func__, dai_link[i].codec_name); - ret = -ENODEV; - goto err; - } - dai_link[i].codec_of_node = np; - dai_link[i].codec_name = NULL; - } - } - -err: - return ret; -} - -static int msm8996_prepare_us_euro(struct snd_soc_card *card) -{ - struct msm8996_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(card); - int ret; - - if (pdata->us_euro_gpio >= 0) { - dev_dbg(card->dev, "%s: us_euro gpio request %d", __func__, - pdata->us_euro_gpio); - ret = gpio_request(pdata->us_euro_gpio, "TASHA_CODEC_US_EURO"); - if (ret) { - dev_err(card->dev, - "%s: Failed to request codec US/EURO gpio %d error %d\n", - __func__, pdata->us_euro_gpio, ret); - return ret; - } - } - - return 0; -} - -static int msm8996_prepare_hifi(struct snd_soc_card *card) -{ - struct msm8996_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(card); - int ret; - - if (gpio_is_valid(pdata->hph_en1_gpio)) { - dev_dbg(card->dev, "%s: hph_en1_gpio request %d\n", __func__, - pdata->hph_en1_gpio); - ret = gpio_request(pdata->hph_en1_gpio, "hph_en1_gpio"); - if (ret) { - dev_err(card->dev, - "%s: hph_en1_gpio request failed, ret:%d\n", - __func__, ret); - return ret; - } - } - if (gpio_is_valid(pdata->hph_en0_gpio)) { - dev_dbg(card->dev, "%s: hph_en0_gpio request %d\n", __func__, - pdata->hph_en0_gpio); - ret = gpio_request(pdata->hph_en0_gpio, "hph_en0_gpio"); - if (ret) { - dev_err(card->dev, - "%s: hph_en0_gpio request failed, ret:%d\n", - __func__, ret); - return ret; - } - } - return 0; -} - -static const struct of_device_id msm8996_asoc_machine_of_match[] = { - { .compatible = "qcom,msm8996-asoc-snd-tasha", - .data = "tasha_codec"}, - {}, -}; - -static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) -{ - struct snd_soc_card *card = NULL; - struct snd_soc_dai_link *dailink; - int len_1, len_2, len_3, len_4; - const struct of_device_id *match; - - match = of_match_node(msm8996_asoc_machine_of_match, dev->of_node); - if (!match) { - dev_err(dev, "%s: No DT match found for sound card\n", - __func__); - return NULL; - } - - if (!strcmp(match->data, "tasha_codec")) { - card = &snd_soc_card_tasha_msm8996; - len_1 = ARRAY_SIZE(msm8996_common_dai_links); - len_2 = len_1 + ARRAY_SIZE(msm8996_tasha_fe_dai_links); - len_3 = len_2 + ARRAY_SIZE(msm8996_common_be_dai_links); - - memcpy(msm8996_tasha_dai_links, - msm8996_common_dai_links, - sizeof(msm8996_common_dai_links)); - memcpy(msm8996_tasha_dai_links + len_1, - msm8996_tasha_fe_dai_links, - sizeof(msm8996_tasha_fe_dai_links)); - memcpy(msm8996_tasha_dai_links + len_2, - msm8996_common_be_dai_links, - sizeof(msm8996_common_be_dai_links)); - memcpy(msm8996_tasha_dai_links + len_3, - msm8996_tasha_be_dai_links, - sizeof(msm8996_tasha_be_dai_links)); - - dailink = msm8996_tasha_dai_links; - len_4 = len_3 + ARRAY_SIZE(msm8996_tasha_be_dai_links); - } - - if (of_property_read_bool(dev->of_node, "qcom,hdmi-audio-rx")) { - dev_dbg(dev, "%s(): hdmi audio support present\n", - __func__); - memcpy(dailink + len_4, msm8996_hdmi_dai_link, - sizeof(msm8996_hdmi_dai_link)); - len_4 += ARRAY_SIZE(msm8996_hdmi_dai_link); - } else { - dev_dbg(dev, "%s(): No hdmi audio support\n", __func__); - } - - if (card) { - card->dai_link = dailink; - card->num_links = len_4; - } - - return card; -} - -static int msm8996_init_wsa_dev(struct platform_device *pdev, - struct snd_soc_card *card) -{ - struct device_node *wsa_of_node; - u32 wsa_max_devs; - u32 wsa_dev_cnt; - char *dev_name_str = NULL; - struct msm8996_wsa881x_dev_info *wsa881x_dev_info; - const char *wsa_auxdev_name_prefix[1]; - int found = 0; - int i; - int ret; - - /* Get maximum WSA device count for this platform */ - ret = of_property_read_u32(pdev->dev.of_node, - "qcom,wsa-max-devs", &wsa_max_devs); - if (ret) { - dev_dbg(&pdev->dev, - "%s: wsa-max-devs property missing in DT %s, ret = %d\n", - __func__, pdev->dev.of_node->full_name, ret); - return 0; - } - if (wsa_max_devs == 0) { - dev_warn(&pdev->dev, - "%s: Max WSA devices is 0 for this target?\n", - __func__); - return 0; - } - - /* Get count of WSA device phandles for this platform */ - wsa_dev_cnt = of_count_phandle_with_args(pdev->dev.of_node, - "qcom,wsa-devs", NULL); - if (wsa_dev_cnt == -ENOENT) { - dev_warn(&pdev->dev, "%s: No wsa device defined in DT.\n", - __func__); - return 0; - } else if (wsa_dev_cnt <= 0) { - dev_err(&pdev->dev, - "%s: Error reading wsa device from DT. wsa_dev_cnt = %d\n", - __func__, wsa_dev_cnt); - return -EINVAL; - } - - /* - * Expect total phandles count to be NOT less than maximum possible - * WSA count. However, if it is less, then assign same value to - * max count as well. - */ - if (wsa_dev_cnt < wsa_max_devs) { - dev_dbg(&pdev->dev, - "%s: wsa_max_devs = %d cannot exceed wsa_dev_cnt = %d\n", - __func__, wsa_max_devs, wsa_dev_cnt); - wsa_max_devs = wsa_dev_cnt; - } - - /* Make sure prefix string passed for each WSA device */ - ret = of_property_count_strings(pdev->dev.of_node, - "qcom,wsa-aux-dev-prefix"); - if (ret != wsa_dev_cnt) { - dev_err(&pdev->dev, - "%s: expecting %d wsa prefix. Defined only %d in DT\n", - __func__, wsa_dev_cnt, ret); - return -EINVAL; - } - - /* - * Alloc mem to store phandle and index info of WSA device, if already - * registered with ALSA core - */ - wsa881x_dev_info = devm_kcalloc(&pdev->dev, wsa_max_devs, - sizeof(struct msm8996_wsa881x_dev_info), - GFP_KERNEL); - if (!wsa881x_dev_info) - return -ENOMEM; - - /* - * search and check whether all WSA devices are already - * registered with ALSA core or not. If found a node, store - * the node and the index in a local array of struct for later - * use. - */ - for (i = 0; i < wsa_dev_cnt; i++) { - wsa_of_node = of_parse_phandle(pdev->dev.of_node, - "qcom,wsa-devs", i); - if (unlikely(!wsa_of_node)) { - /* we should not be here */ - dev_err(&pdev->dev, - "%s: wsa dev node is not present\n", - __func__); - return -EINVAL; - } - if (soc_find_component(wsa_of_node, NULL)) { - /* WSA device registered with ALSA core */ - wsa881x_dev_info[found].of_node = wsa_of_node; - wsa881x_dev_info[found].index = i; - found++; - if (found == wsa_max_devs) - break; - } - } - - if (found < wsa_max_devs) { - dev_dbg(&pdev->dev, - "%s: failed to find %d components. Found only %d\n", - __func__, wsa_max_devs, found); - return -EPROBE_DEFER; - } - dev_info(&pdev->dev, - "%s: found %d wsa881x devices registered with ALSA core\n", - __func__, found); - - card->num_aux_devs = wsa_max_devs; - card->num_configs = wsa_max_devs; - - /* Alloc array of AUX devs struct */ - msm8996_aux_dev = devm_kcalloc(&pdev->dev, card->num_aux_devs, - sizeof(struct snd_soc_aux_dev), - GFP_KERNEL); - if (!msm8996_aux_dev) - return -ENOMEM; - - /* Alloc array of codec conf struct */ - msm8996_codec_conf = devm_kcalloc(&pdev->dev, card->num_aux_devs, - sizeof(struct snd_soc_codec_conf), - GFP_KERNEL); - if (!msm8996_codec_conf) - return -ENOMEM; - - for (i = 0; i < card->num_aux_devs; i++) { - dev_name_str = devm_kzalloc(&pdev->dev, DEV_NAME_STR_LEN, - GFP_KERNEL); - if (!dev_name_str) - return -ENOMEM; - - ret = of_property_read_string_index(pdev->dev.of_node, - "qcom,wsa-aux-dev-prefix", - wsa881x_dev_info[i].index, - wsa_auxdev_name_prefix); - if (ret) { - dev_err(&pdev->dev, - "%s: failed to read wsa aux dev prefix, ret = %d\n", - __func__, ret); - return -EINVAL; - } - - snprintf(dev_name_str, strlen("wsa881x.%d"), "wsa881x.%d", i); - msm8996_aux_dev[i].name = dev_name_str; - msm8996_aux_dev[i].codec_name = NULL; - msm8996_aux_dev[i].codec_of_node = - wsa881x_dev_info[i].of_node; - msm8996_aux_dev[i].init = msm8996_wsa881x_init; - msm8996_codec_conf[i].dev_name = NULL; - msm8996_codec_conf[i].name_prefix = wsa_auxdev_name_prefix[0]; - msm8996_codec_conf[i].of_node = - wsa881x_dev_info[i].of_node; - } - card->codec_conf = msm8996_codec_conf; - card->aux_dev = msm8996_aux_dev; - - return 0; -} - -static int msm8996_asoc_machine_probe(struct platform_device *pdev) -{ - struct snd_soc_card *card; - struct msm8996_asoc_mach_data *pdata; - const char *mbhc_audio_jack_type = NULL; - char *mclk_freq_prop_name; - const struct of_device_id *match; - int ret; - - if (!pdev->dev.of_node) { - dev_err(&pdev->dev, "No platform supplied from device tree\n"); - return -EINVAL; - } - - pdata = devm_kzalloc(&pdev->dev, - sizeof(struct msm8996_asoc_mach_data), GFP_KERNEL); - if (!pdata) - return -ENOMEM; - - card = populate_snd_card_dailinks(&pdev->dev); - if (!card) { - dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__); - ret = -EINVAL; - goto err; - } - card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); - snd_soc_card_set_drvdata(card, pdata); - - ret = snd_soc_of_parse_card_name(card, "qcom,model"); - if (ret) { - dev_err(&pdev->dev, "parse card name failed, err:%d\n", - ret); - goto err; - } - - ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing"); - if (ret) { - dev_err(&pdev->dev, "parse audio routing failed, err:%d\n", - ret); - goto err; - } - - match = of_match_node(msm8996_asoc_machine_of_match, - pdev->dev.of_node); - if (!match) { - dev_err(&pdev->dev, "%s: no matched codec is found.\n", - __func__); - goto err; - } - - mclk_freq_prop_name = "qcom,tasha-mclk-clk-freq"; - - ret = of_property_read_u32(pdev->dev.of_node, - mclk_freq_prop_name, &pdata->mclk_freq); - if (ret) { - dev_err(&pdev->dev, - "Looking up %s property in node %s failed, err%d\n", - mclk_freq_prop_name, - pdev->dev.of_node->full_name, ret); - goto err; - } - - if (pdata->mclk_freq != CODEC_EXT_CLK_RATE) { - dev_err(&pdev->dev, "unsupported mclk freq %u\n", - pdata->mclk_freq); - ret = -EINVAL; - goto err; - } - - spdev = pdev; - - ret = msm8996_populate_dai_link_component_of_node(card); - if (ret) { - ret = -EPROBE_DEFER; - goto err; - } - - ret = msm8996_init_wsa_dev(pdev, card); - if (ret) - goto err; - - pdata->hph_en1_gpio = of_get_named_gpio(pdev->dev.of_node, - "qcom,hph-en1-gpio", 0); - if (pdata->hph_en1_gpio < 0) { - dev_dbg(&pdev->dev, "%s: %s property not found %d\n", - __func__, "qcom,hph-en1-gpio", pdata->hph_en1_gpio); - } - - pdata->hph_en0_gpio = of_get_named_gpio(pdev->dev.of_node, - "qcom,hph-en0-gpio", 0); - if (pdata->hph_en0_gpio < 0) { - dev_dbg(&pdev->dev, "%s: %s property not found %d\n", - __func__, "qcom,hph-en0-gpio", pdata->hph_en0_gpio); - } - ret = msm8996_prepare_hifi(card); - if (ret) - dev_dbg(&pdev->dev, "msm8996_prepare_hifi failed (%d)\n", - ret); - - ret = snd_soc_register_card(card); - if (ret == -EPROBE_DEFER) { - if (codec_reg_done) - ret = -EINVAL; - goto err; - } else if (ret) { - dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", - ret); - goto err; - } - dev_info(&pdev->dev, "Sound card %s registered\n", card->name); - - ret = of_property_read_string(pdev->dev.of_node, - "qcom,mbhc-audio-jack-type", &mbhc_audio_jack_type); - if (ret) { - dev_dbg(&pdev->dev, "Looking up %s property in node %s failed", - "qcom,mbhc-audio-jack-type", - pdev->dev.of_node->full_name); - dev_dbg(&pdev->dev, "Jack type properties set to default"); - } else { - if (!strcmp(mbhc_audio_jack_type, "4-pole-jack")) - dev_dbg(&pdev->dev, "This hardware has 4 pole jack"); - else if (!strcmp(mbhc_audio_jack_type, "5-pole-jack")) - dev_dbg(&pdev->dev, "This hardware has 5 pole jack"); - else if (!strcmp(mbhc_audio_jack_type, "6-pole-jack")) - dev_dbg(&pdev->dev, "This hardware has 6 pole jack"); - else - dev_dbg(&pdev->dev, "Unknown value, set to default"); - } - /* - * Parse US-Euro gpio info from DT. Report no error if us-euro - * entry is not found in DT file as some targets do not support - * US-Euro detection - */ - pdata->us_euro_gpio = of_get_named_gpio(pdev->dev.of_node, - "qcom,us-euro-gpios", 0); - if (pdata->us_euro_gpio < 0) { - dev_info(&pdev->dev, "property %s not detected in node %s", - "qcom,us-euro-gpios", - pdev->dev.of_node->full_name); - } else { - 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; - } - - ret = msm8996_prepare_us_euro(card); - if (ret) - dev_info(&pdev->dev, "msm8996_prepare_us_euro failed (%d)\n", - ret); - return 0; -err: - if (pdata->us_euro_gpio > 0) { - dev_dbg(&pdev->dev, "%s free us_euro gpio %d\n", - __func__, pdata->us_euro_gpio); - gpio_free(pdata->us_euro_gpio); - pdata->us_euro_gpio = 0; - } - if (pdata->hph_en1_gpio > 0) { - dev_dbg(&pdev->dev, "%s free hph_en1_gpio %d\n", - __func__, pdata->hph_en1_gpio); - gpio_free(pdata->hph_en1_gpio); - pdata->hph_en1_gpio = 0; - } - if (pdata->hph_en0_gpio > 0) { - dev_dbg(&pdev->dev, "%s free hph_en0_gpio %d\n", - __func__, pdata->hph_en0_gpio); - gpio_free(pdata->hph_en0_gpio); - pdata->hph_en0_gpio = 0; - } - devm_kfree(&pdev->dev, pdata); - return ret; -} - -static int msm8996_asoc_machine_remove(struct platform_device *pdev) -{ - struct snd_soc_card *card = platform_get_drvdata(pdev); - struct msm8996_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(card); - - if (gpio_is_valid(ext_us_amp_gpio)) - gpio_free(ext_us_amp_gpio); - - gpio_free(pdata->us_euro_gpio); - gpio_free(pdata->hph_en1_gpio); - gpio_free(pdata->hph_en0_gpio); - - if (msm8996_liquid_dock_dev != NULL) { - switch_dev_unregister(&msm8996_liquid_dock_dev->audio_sdev); - - if (msm8996_liquid_dock_dev->dock_plug_irq) - free_irq(msm8996_liquid_dock_dev->dock_plug_irq, - msm8996_liquid_dock_dev); - - if (msm8996_liquid_dock_dev->dock_plug_gpio) - gpio_free(msm8996_liquid_dock_dev->dock_plug_gpio); - - kfree(msm8996_liquid_dock_dev); - msm8996_liquid_dock_dev = NULL; - } - snd_soc_unregister_card(card); - - return 0; -} - -static struct platform_driver msm8996_asoc_machine_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .pm = &snd_soc_pm_ops, - .of_match_table = msm8996_asoc_machine_of_match, - }, - .probe = msm8996_asoc_machine_probe, - .remove = msm8996_asoc_machine_remove, -}; -module_platform_driver(msm8996_asoc_machine_driver); - -MODULE_DESCRIPTION("ALSA SoC msm"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:" DRV_NAME); -MODULE_DEVICE_TABLE(of, msm8996_asoc_machine_of_match); diff --git a/asoc/sdm660-external.c b/asoc/sdm660-external.c index 0358ad8ad9..1c12bfd732 100644 --- a/asoc/sdm660-external.c +++ b/asoc/sdm660-external.c @@ -20,7 +20,6 @@ #include #include #include "msm-pcm-routing-v2.h" -#include "msm-audio-pinctrl.h" #include "sdm660-common.h" #include "sdm660-external.h" #include "codecs/wcd9335.h"