Revert "Import S928BXXS4AXJB audio-kernel changes"

This reverts commit 3563ee22f6.
This commit is contained in:
David Wronek 2024-12-08 18:28:49 +01:00
parent 3563ee22f6
commit 8ae7e1dcff
28 changed files with 15 additions and 8750 deletions

View File

@ -569,19 +569,7 @@ LOCAL_MODULE_DEBUG_ENABLE := true
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
include $(DLKM_DIR)/Build_external_kernelmodule.mk
endif
ifeq ($(PROJECT_NAME),$(filter $(PROJECT_NAME),q6q b6q q6aq))
##########################################################
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(AUDIO_SRC_FILES)
LOCAL_MODULE := tas25xx_dlkm.ko
LOCAL_MODULE_KBUILD_NAME := asoc/codecs/tas25xx/tas25xx_dlkm.ko
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_DEBUG_ENABLE := true
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
include $(DLKM_DIR)/Build_external_kernelmodule.mk
endif
###########################################################
endif # DLKM check
endif # supported target check
endif

View File

@ -40,8 +40,6 @@ LOCAL_MODULE_KO_DIRS += asoc/codecs/wcd939x/wcd939x_slave_dlkm.ko
LOCAL_MODULE_KO_DIRS += asoc/codecs/wcd9378/wcd9378_dlkm.ko
LOCAL_MODULE_KO_DIRS += asoc/codecs/wcd9378/wcd9378_slave_dlkm.ko
LOCAL_MODULE_KO_DIRS += asoc/codecs/hdmi_dlkm.ko
ifeq ($(PROJECT_NAME),$(filter $(PROJECT_NAME),q6q b6q q6aq))
LOCAL_MODULE_KO_DIRS += asoc/codecs/tas25xx/tas25xx_dlkm.ko
endif
ifeq ($(call is-board-platform-in-list,pitti),true)

View File

@ -285,11 +285,6 @@ ifeq ($(KERNEL_BUILD), 1)
obj-y += rouleur/
obj-y += ./
endif
ifdef CONFIG_SND_SOC_TAS25XX
obj-y += tas25xx/
endif
# Module information used by KBuild framework
obj-$(CONFIG_WCD9XXX_CODEC_CORE) += wcd_core_dlkm.o
obj-$(CONFIG_WCD9XXX_CODEC_CORE_V2) += wcd_core_dlkm.o

View File

@ -17,9 +17,6 @@
#include "lpass-cdc.h"
#include "lpass-cdc-registers.h"
#include "lpass-cdc-clk-rsc.h"
#if IS_ENABLED(CONFIG_SND_SOC_SAMSUNG_AUDIO)
#include <sound/samsung/snd_debug_proc.h>
#endif
#define AUTO_SUSPEND_DELAY 50 /* delay in msec */
#define LPASS_CDC_TX_MACRO_MAX_OFFSET 0x1000
@ -107,19 +104,6 @@ enum {
VA_MCLK,
};
/* Based on 9.6MHZ MCLK Freq */
enum {
CLK_DISABLED = 0,
CLK_2P4MHZ,
CLK_0P6MHZ,
};
static int dmic_clk_rate_div[] = {
[CLK_DISABLED] = 0,
[CLK_2P4MHZ] = LPASS_CDC_TX_MACRO_CLK_DIV_4,
[CLK_0P6MHZ] = LPASS_CDC_TX_MACRO_CLK_DIV_16,
};
struct lpass_cdc_tx_macro_reg_mask_val {
u16 reg;
u8 mask;
@ -165,15 +149,8 @@ struct lpass_cdc_tx_macro_priv {
int pcm_rate[NUM_DECIMATORS];
bool swr_dmic_enable;
int wlock_holders;
u32 dmic_rate_override;
};
static const char* const dmic_rate_override_text[] = {
"DISABLED", "CLK_2P4MHZ", "CLK_0P6MHZ"
};
static SOC_ENUM_SINGLE_EXT_DECL(dmic_rate_enum, dmic_rate_override_text);
static int lpass_cdc_tx_macro_wake_enable(struct lpass_cdc_tx_macro_priv *tx_priv,
bool wake_enable)
{
@ -225,48 +202,12 @@ static bool lpass_cdc_tx_macro_get_data(struct snd_soc_component *component,
return true;
}
static int lpass_cdc_dmic_rate_override_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component =
snd_soc_kcontrol_component(kcontrol);
struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
struct device *tx_dev = NULL;
if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
return -EINVAL;
ucontrol->value.enumerated.item[0] = tx_priv->dmic_rate_override;
dev_dbg(component->dev, "%s: dmic rate: %d\n",
__func__, tx_priv->dmic_rate_override);
return 0;
}
static int lpass_cdc_dmic_rate_override_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component =
snd_soc_kcontrol_component(kcontrol);
struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
struct device *tx_dev = NULL;
if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
return -EINVAL;
tx_priv->dmic_rate_override = ucontrol->value.enumerated.item[0];
dev_dbg(component->dev, "%s: dmic rate: %d\n",
__func__, tx_priv->dmic_rate_override);
return 0;
}
static int lpass_cdc_tx_macro_mclk_enable(
struct lpass_cdc_tx_macro_priv *tx_priv,
bool mclk_enable)
{
struct regmap *regmap = dev_get_regmap(tx_priv->dev->parent, NULL);
int ret = 0, rc = 0;
int ret = 0;
if (regmap == NULL) {
dev_err_ratelimited(tx_priv->dev, "%s: regmap is NULL\n", __func__);
@ -291,34 +232,16 @@ static int lpass_cdc_tx_macro_mclk_enable(
lpass_cdc_clk_rsc_fs_gen_request(tx_priv->dev,
true);
regcache_mark_dirty(regmap);
ret = regcache_sync_region(regmap,
regcache_sync_region(regmap,
TX_START_OFFSET,
TX_MAX_OFFSET);
if (ret < 0) {
dev_err_ratelimited(tx_priv->dev,
"%s: regcache_sync_region failed\n",
__func__);
#if IS_ENABLED(CONFIG_SND_SOC_SAMSUNG_AUDIO)
sdp_info_print("%s: regcache_sync_region failed\n",
__func__);
#endif
lpass_cdc_clk_rsc_fs_gen_request(tx_priv->dev,
false);
lpass_cdc_clk_rsc_request_clock(tx_priv->dev,
TX_CORE_CLK,
TX_CORE_CLK,
false);
goto exit;
}
if (tx_priv->tx_mclk_users == 0) {
rc = (rc | regmap_update_bits(regmap,
regmap_update_bits(regmap,
LPASS_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
0x01, 0x01));
rc = (rc | regmap_update_bits(regmap,
0x01, 0x01);
regmap_update_bits(regmap,
LPASS_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL,
0x01, 0x01));
0x01, 0x01);
}
tx_priv->tx_mclk_users++;
} else {
@ -330,26 +253,17 @@ static int lpass_cdc_tx_macro_mclk_enable(
}
tx_priv->tx_mclk_users--;
if (tx_priv->tx_mclk_users == 0) {
rc = (rc | regmap_update_bits(regmap,
regmap_update_bits(regmap,
LPASS_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL,
0x01, 0x00));
rc = (rc | regmap_update_bits(regmap,
0x01, 0x00);
regmap_update_bits(regmap,
LPASS_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
0x01, 0x00));
0x01, 0x00);
}
if (rc < 0) {
dev_err_ratelimited(tx_priv->dev, "%s: register writes failed\n",
__func__);
#if IS_ENABLED(CONFIG_SND_SOC_SAMSUNG_AUDIO)
sdp_info_print("%s: register writes failed\n",
__func__);
#endif
}
lpass_cdc_clk_rsc_fs_gen_request(tx_priv->dev,
false);
ret = lpass_cdc_clk_rsc_request_clock(tx_priv->dev,
lpass_cdc_clk_rsc_request_clock(tx_priv->dev,
TX_CORE_CLK,
TX_CORE_CLK,
false);
@ -1955,9 +1869,6 @@ static const struct snd_kcontrol_new lpass_cdc_tx_macro_snd_controls[] = {
SOC_ENUM_EXT("BCS CH_SEL", bcs_ch_sel_mux_enum,
lpass_cdc_tx_macro_get_bcs_ch_sel, lpass_cdc_tx_macro_put_bcs_ch_sel),
SOC_ENUM_EXT("DMIC_RATE OVERRIDE", dmic_rate_enum,
lpass_cdc_dmic_rate_override_get, lpass_cdc_dmic_rate_override_put),
};
static int lpass_cdc_tx_macro_clk_div_get(struct snd_soc_component *component)
@ -1968,9 +1879,6 @@ static int lpass_cdc_tx_macro_clk_div_get(struct snd_soc_component *component)
if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
return -EINVAL;
if (tx_priv->dmic_rate_override)
return dmic_clk_rate_div[tx_priv->dmic_rate_override];
return (int)tx_priv->dmic_clk_div;
}
@ -2027,9 +1935,6 @@ undefined_rate:
static const struct lpass_cdc_tx_macro_reg_mask_val
lpass_cdc_tx_macro_reg_init[] = {
{LPASS_CDC_TX0_TX_PATH_SEC7, 0x3F, 0x0A},
{LPASS_CDC_TX0_TX_PATH_CFG1, 0x0F, 0x0A},
{LPASS_CDC_TX1_TX_PATH_CFG1, 0x0F, 0x0A},
{LPASS_CDC_TX2_TX_PATH_CFG1, 0x0F, 0x0A},
};
static int lpass_cdc_tx_macro_init(struct snd_soc_component *component)

View File

@ -1,87 +0,0 @@
ifeq ($(MODNAME),)
KERNEL_BUILD := 1
else
KERNEL_BUILD := 0
endif
ifeq ($(KERNEL_BUILD), 1)
AUDIO_BLD_DIR := $(srctree)
AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio
endif
ifeq ($(KERNEL_BUILD), 0)
ifeq ($(CONFIG_ARCH_WAIPIO), y)
include $(AUDIO_ROOT)/config/waipioauto.conf
INCS += -include $(AUDIO_ROOT)/config/waipioautoconf.h
endif
endif
############ COMMON ############
COMMON_DIR := include
COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR)
ifdef CONFIG_SND_SOC_TAS25XX
TAS25XX_OBJS += src/tas25xx-codec.o
TAS25XX_OBJS += src/tas25xx-regmap.o
TAS25XX_OBJS += src/tas25xx.o
TAS25XX_OBJS += src/tas25xx-logic.o
TAS25XX_OBJS += src/tas25xx-regbin-parser.o
endif
ifneq ($(CONFIG_TAS25XX_ALGO),)
TAS25XX_OBJS += algo/src/tas25xx-algo-intf.o
TAS25XX_OBJS += algo/src/tas25xx-calib.o
TAS25XX_OBJS += algo/src/tas25xx-algo-common.o
endif
ifneq ($(CONFIG_PLATFORM_MTK),)
TAS25XX_OBJS += algo/platform/mtk/tas25xx-mtk-wrapper.o
endif
ifneq ($(CONFIG_TAS25XX_MISC),)
TAS25XX_OBJS += src/tas25xx-misc.o
endif
ifneq ($(CONFIG_PLATFORM_QCOM),)
TAS25XX_OBJS += algo/platform/qcom/tas25xx-algo-qdsp-intf.o
endif
ifneq ($(CONFIG_TISA_KBIN_INTF),)
TAS25XX_OBJS += algo/src/tas25xx-algo-kbin-intf.o
TAS25XX_OBJS += algo/src/tas25xx-algo-bin-utils.o
endif
ifneq ($(CONFIG_TAS25XX_CALIB_VAL_BIG),)
TAS25XX_OBJS += algo/src/tas25xx-calib-validation.o
endif
ifneq ($(CONFIG_TISA_SYSFS_INTF),)
TAS25XX_OBJS += algo/src/tas25xx-sysfs-debugfs-utils.o
TAS25XX_OBJS += algo/src/smartpa-debug-common.o
endif
ifneq ($(CONFIG_TISA_BIN_INTF),)
TAS25XX_OBJS += algo/src/tas25xx-algo-bin-intf.o
endif
ifneq ($(CONFIG_PLATFORM_EXYNOS),)
TAS25XX_OBJS += algo/platform/exynos/tas25xx-algo-exynos-dsp-intf.o
TAS25XX_OBJS += algo/platform/exynos/skinprot-sysfs-cb.o
endif
LINUX_INC += -Iinclude/linux
TAS25XX_INC = -I$(AUDIO_ROOT)/asoc/codecs/tas25xx
TAS25XX_INC += -I$(AUDIO_ROOT)/asoc/codecs/tas25xx/inc
INCS += $(COMMON_INC) $(TAS25XX_INC)
EXTRA_CFLAGS += $(INCS)
# Module information used by KBuild framework
obj-$(CONFIG_SND_SOC_TAS25XX) += tas25xx_dlkm.o
tas25xx_dlkm-y := $(TAS25XX_OBJS)
# inject some build related information
DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\"

View File

@ -1,107 +0,0 @@
menuconfig SND_SOC_TAS25XX
tristate "Texas Instruments TAS25XX SmartAmp(R)"
help
Enable the support for TAS driver.
This is the main config under which various
other configuration can be enabled based on
the below configurations.
if SND_SOC_TAS25XX
config PLATFORM_EXYNOS
bool "Exynos platform support"
depends on SND_SOC_TAS25XX
default n
help
Enable support for Exynos platform.
This enables the platform specific interface
which acts as abstraction layer to the algorithm
for Exynos platform.
config PLATFORM_MTK
bool "MTK platform support"
depends on SND_SOC_TAS25XX
default n
help
Enable support for MTK platform.
This enables the platform specific interface
which acts as abstraction layer to the algorithm
for MTK platform.
config TAS25XX_ALGO
bool "TAS25XX AP DSP Communication Support"
depends on SND_SOC_TAS25XX
help
Enable support for TAS25XX Calibration driver.
This includes TAS25XX Calibration driver interfaces
and functions also interfacing driver to corresponding
Platform/DSP
config PLATFORM_QCOM
bool "QCOM platform support"
depends on TAS25XX_ALGO
default n
help
Enable support for Qcom platform.
This enables the platform specific interface
which acts as abstraction layer to the algorithm
for Exynos platform.
config TISA_KBIN_INTF
bool "Kbin file method support"
depends on PLATFORM_QCOM
default n
help
Enable support for KBin file method
This is the algorithm specific configuration
where the binary file will be opened in the kernel
using request_firmware API. This interface currently supported
only on the Qualcomm platform
config TAS25XX_CALIB_VAL_BIG
bool "For bigdata & calibration support"
depends on TAS25XX_ALGO
default n
help
Enable support for bigdata & calibration.
Enables the support for sysfs entries under
/sys/class/tas25xx directory
for calibration, validataion and bigdata
config TAS25XX_IRQ_BD
bool "For bigdata IRQ data"
depends on SND_SOC_TAS25XX
default n
help
Enable support for bigdata & calibration.
Enables the support for sysfs entries under
/sys/class/tas25xx_dev/ directory
for irq related big data
config TISA_SYSFS_INTF
bool "sysfs interface for calibration and algo support"
depends on TAS25XX_ALGO
default n
help
Enable the support for sysfs based interfaces
for calibration and algo control
config TAS25XX_MISC
bool "Misc Driver support"
default y
help
Enable misc driver support.
Enable the misc driver "TAS25XX" which is
interface to communicate to device via register
read and write
endif # SND_SOC_TAS25XX

View File

@ -1,53 +0,0 @@
ccflags-y += -I$(srctree)/$(src)/inc/
ccflags-y += -I$(srctree)/sound/soc/codecs/uda20/driver/tas25xx_driver/inc/
ccflags-y += -I$(srctree)/sound/soc/mediatek/common/
ccflags-y += -I$(src)
obj-$(CONFIG_SND_SOC_TAS25XX) += snd-soc-tas25xx.o
snd-soc-tas25xx-$(CONFIG_SND_SOC_TAS25XX) := src/tas25xx-codec.o \
src/tas25xx-regmap.o \
src/tas25xx.o \
src/tas25xx-logic.o \
src/tas25xx-regbin-parser.o
ifneq ($(CONFIG_TAS25XX_ALGO),)
snd-soc-tas25xx-objs += algo/src/tas25xx-algo-intf.o \
algo/src/tas25xx-calib.o \
algo/src/tas25xx-algo-common.o
endif
ifneq ($(CONFIG_PLATFORM_MTK),)
snd-soc-tas25xx-objs += algo/platform/mtk/tas25xx-mtk-wrapper.o
endif
ifneq ($(CONFIG_TAS25XX_MISC),)
snd-soc-tas25xx-objs += src/tas25xx-misc.o
endif
ifneq ($(CONFIG_PLATFORM_QCOM),)
snd-soc-tas25xx-objs += algo/platform/qcom/tas25xx-algo-qdsp-intf.o
endif
ifneq ($(CONFIG_TISA_KBIN_INTF),)
snd-soc-tas25xx-objs += algo/src/tas25xx-algo-kbin-intf.o \
algo/src/tas25xx-algo-bin-utils.o
endif
ifneq ($(CONFIG_TAS25XX_CALIB_VAL_BIG),)
snd-soc-tas25xx-objs += algo/src/tas25xx-calib-validation.o
endif
ifneq ($(CONFIG_TISA_SYSFS_INTF),)
snd-soc-tas25xx-objs += algo/src/tas25xx-sysfs-debugfs-utils.o \
algo/src/smartpa-debug-common.o
endif
ifneq ($(CONFIG_TISA_BIN_INTF),)
snd-soc-tas25xx-objs += algo/src/tas25xx-algo-bin-intf.o
endif
ifneq ($(CONFIG_PLATFORM_EXYNOS),)
snd-soc-tas25xx-objs += algo/platform/exynos/tas25xx-algo-exynos-dsp-intf.o
snd-soc-tas25xx-objs += algo/platform/exynos/skinprot-sysfs-cb.o
endif

View File

@ -1,30 +0,0 @@
/*
* =============================================================================
* Copyright (c) 2016 Texas Instruments Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; version 2.
*
* 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.
*
* File:
* tas25xx-codec.h
*
* Description:
* header file for tas25xx-codec.c
*
* =============================================================================
*/
#ifndef _TAS25XX_CODEC_H
#define _TAS25XX_CODEC_H
#include "tas25xx.h"
int tas25xx_register_codec(struct tas25xx_priv *p_tas25xx);
int tas25xx_deregister_codec(struct tas25xx_priv *p_tas25xx);
#endif /* _TAS25XX_CODEC_H */

View File

@ -1,22 +0,0 @@
#ifndef __TAS25XX_DEVICE_
#define __TAS25XX_DEVICE_
#include "tas25xx.h"
int tas25xx_software_reset(struct tas25xx_priv *p_tas25xx, int ch);
int tas25xx_set_power_mute(struct tas25xx_priv *p_tas25xx, int ch);
int tas25xx_tx_set_edge(struct tas25xx_priv *p_tas25xx,
unsigned int tx_edge, int ch);
int tas25xx_tx_set_start_slot(struct tas25xx_priv *p_tas25xx,
unsigned int tx_start_slot, int ch);
int tas25xx_rx_set_edge(struct tas25xx_priv *p_tas25xx,
unsigned int rx_edge, int ch);
int tas25xx_rx_set_bitwidth(struct tas25xx_priv *p_tas25xx,
int bitwidth, int ch);
/* Interrupt Related Functions */
int tas_dev_interrupt_clear(struct tas25xx_priv *p_tas25xx, int ch);
int tas_dev_interrupt_enable(struct tas25xx_priv *p_tas25xx, int ch);
int tas_dev_interrupt_disable(struct tas25xx_priv *p_tas25xx, int ch);
int tas_dev_interrupt_read(struct tas25xx_priv *p_tas25xx, int ch, int *type);
#endif /* __TAS25XX_DEVICE_ */

View File

@ -1,43 +0,0 @@
/*
* ALSA SoC Texas Instruments TAS25XX High Performance Smart Amplifier
*
* Copyright (C) 2024 Texas Instruments, Inc.
*
* Author: Niranjan H Y
*
* This package is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#ifndef __TAS25XX_EXT_H__
#define __TAS25XX_EXT_H__
enum tas_amp_status_t {
TAS_AMP_ERR_EINVAL = -3, /* invalid parameter */
TAS_AMP_ERR_FW_LOAD = -2, /* amp fw download failure */
TAS_AMP_ERR_I2C = -1, /* amp i2c error */
TAS_AMP_STATE_UNINIT = 0, /* uninitialized state */
TAS_AMP_STATE_BOOT_SUCCESS = 1, /* amp first i2c successful */
TAS_AMP_STATE_FW_LOAD_SUCCESS = 2, /* amp fully initialized for playback */
};
enum tas_amp_error_t {
TAS_AMP_NO_ERR = 0,
TAS_AMP_SHORTCIRCUIT_ERR = 1,
TAS_AMP_ERR_MAX,
};
/* get the current amp status */
enum tas_amp_status_t tas25xx_get_state(uint32_t id);
/* error callback for i2c error */
void tas25xx_register_i2c_error_callback(void (*i2c_err_cb)(uint32_t i2caddr));
void tas25xx_register_amp_error_callback(void (*amp_err_cb)(int32_t i2caddr, int32_t err));
#endif /* __TAS25XX_EXT_H__ */

View File

@ -1,42 +0,0 @@
#ifndef __TAS25XX_LOGIC_
#define __TAS25XX_LOGIC_
#include "tas25xx.h"
#define TAS25XX_STREAM_PLAYBACK 0
#define TAS25XX_STREAM_CAPTURE 1
int tas25xx_register_device(struct tas25xx_priv *p_tas25xx);
int tas25xx_probe(struct tas25xx_priv *p_tas25xx);
void tas25xx_remove(struct tas25xx_priv *p_tas25xx);
int tas25xx_load_init(struct tas25xx_priv *p_tas25xx, int chn);
int tas25xx_irq_work_func(struct tas25xx_priv *p_tas25xx);
void tas25xx_load_config(struct tas25xx_priv *p_tas25xx, int chn);
int tas25xx_init_work_func(struct tas25xx_priv *p_tas25xx,
struct tas_device *dev_tas25xx);
int tas25xx_dc_work_func(struct tas25xx_priv *p_tas25xx, int chn);
void tas_reload(struct tas25xx_priv *p_tas25xx, int chn);
int tas25xx_set_power_state(struct tas25xx_priv *p_tas25xx,
enum tas_power_states_t state, uint32_t chbitmask);
int tas25xx_iv_vbat_slot_config(struct tas25xx_priv *p_tas25xx,
int mn_slot_width);
int tas25xx_set_bitwidth(struct tas25xx_priv *p_tas25xx,
int bitwidth, int stream);
int tas25xx_set_dai_fmt_for_fmt(struct tas25xx_priv *p_tas25xx,
unsigned int fmt);
int tas25xx_set_tdm_rx_slot(struct tas25xx_priv *p_tas25xx,
int slots, int slot_width);
int tas25xx_set_tdm_tx_slot(struct tas25xx_priv *p_tas25xx,
int slots, int slot_width);
int tas25xx_change_book(struct tas25xx_priv *p_tas25xx,
int32_t chn, int book);
#if IS_ENABLED(CONFIG_TAS25XX_IRQ_BD)
void tas25xx_log_interrupt_stats(struct tas25xx_priv *p_tas25xx);
void tas25xx_clear_interrupt_stats(struct tas25xx_priv *p_tas25xx);
#endif /* CONFIG_TAS25XX_IRQ_BD */
int tas25xx_get_drv_channel_opmode(void);
#endif /*__TAS25XX_LOGIC_*/

View File

@ -1,38 +0,0 @@
/*
* =============================================================================
* Copyright (c) 2016 Texas Instruments Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; version 2.
*
* 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.
*
* File:
* tas2562-misc.h
*
* Description:
* header file for tas2562-misc.c
*
* =============================================================================
*/
#ifndef _TAS25XX_MISC_H
#define _TAS25XX_MISC_H
#define TIAUDIO_CMD_REG_WITE 1
#define TIAUDIO_CMD_REG_READ 2
#define TIAUDIO_CMD_DEBUG_ON 3
#define TIAUDIO_CMD_CALIBRATION 7
#define TIAUDIO_CMD_SAMPLERATE 8
#define TIAUDIO_CMD_BITRATE 9
#define TIAUDIO_CMD_DACVOLUME 10
#define TIAUDIO_CMD_SPEAKER 11
int tas25xx_register_misc(struct tas25xx_priv *p_tas25xx);
int tas25xx_deregister_misc(struct tas25xx_priv *p_tas25xx);
#endif /* _TAS25XX_MISC_H */

View File

@ -1,120 +0,0 @@
/*
* ALSA SoC Texas Instruments TAS25XX High Performance 4W Smart Amplifier
*
* Copyright (C) 2021 Texas Instruments, Inc.
*
* Author: Vijeth P O
* Modified: 10-07-21
*
* This package is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#ifndef __TAS25XX_REGBIN_PARSER__
#define __TAS25XX_REGBIN_PARSER__
#define SampleRate_48000 0
#define SampleRate_44100 1
#define SampleRate_96000 2
#define FMT_INV_NB_NF 0
#define FMT_INV_IB_NF 1
#define FMT_INV_NB_IF 2
#define FMT_INV_IB_IF 3
#define FMT_MASK_I2S 0
#define FMT_MASK_DSP_A 1
#define FMT_MASK_DSP_B 2
#define FMT_MASK_LEFT_J 3
#define RX_SLOTS_16 0
#define RX_SLOTS_24 1
#define RX_SLOTS_32 2
#define TX_SLOTS_16 0
#define TX_SLOTS_24 1
#define TX_SLOTS_32 2
#define RX_BITWIDTH_16 0
#define RX_BITWIDTH_24 1
#define RX_BITWIDTH_32 2
#define RX_SLOTLEN_16 0
#define RX_SLOTLEN_24 1
#define RX_SLOTLEN_32 2
#define TX_SLOTLEN_16 0
#define TX_SLOTLEN_24 1
#define TX_SLOTLEN_32 2
#define SUPPORTED_BIN_VERSION 7
#define TAS25XX_DEFAULT 0xFFFFFFFF
enum kcntl_during_t {
KCNTR_ANYTIME = 0, /* instant update */
KCNTR_PRE_POWERUP = 1, /* during pre-power up */
KCNTR_POST_POWERUP = 2, /* during post-power up */
};
struct default_hw_params {
char sample_rate;
char fmt_inv;
char fmt_mask;
char rx_slots;
char tx_slots;
char rx_bitwidth;
char rx_slotlen;
char tx_slotlen;
};
struct tas_dev {
u8 device;
u8 i2c_addr;
};
struct bin_header {
u32 version;
u8 name[64];
u32 timestamp;
u32 size;
u32 channels;
struct tas_dev dev[MAX_CHANNELS];
u8 iv_width;
u8 vbat_mon;
u32 features;
} __attribute__((packed));
int32_t tas25xx_load_firmware(struct tas25xx_priv *p_tas25xx, int max_retry_count);
int32_t tas25xx_create_kcontrols(struct tas25xx_priv *p_tas25xx);
int32_t tas25xx_remove_binfile(struct tas25xx_priv *p_tas25xx);
int32_t tas25xx_set_init_params(struct tas25xx_priv *p_tas25xx, int32_t ch);
int32_t tas25xx_set_sample_rate(struct tas25xx_priv *p_tas25xx, int32_t ch, int32_t sample_rate);
int32_t tas25xx_set_fmt_inv(struct tas25xx_priv *p_tas25xx, int32_t ch, int32_t fmt_inv);
int32_t tas25xx_set_fmt_mask(struct tas25xx_priv *p_tas25xx, int32_t ch, int32_t fmt_mask);
int32_t tas25xx_set_rx_slots(struct tas25xx_priv *p_tas25xx, int32_t ch, int32_t rx_slot);
int32_t tas25xx_set_tx_slots(struct tas25xx_priv *p_tas25xx, int32_t ch, int32_t tx_slot);
int32_t tas25xx_set_rx_bitwidth(struct tas25xx_priv *p_tas25xx, int32_t ch, int32_t rx_bitwidth);
int32_t tas25xx_set_rx_slotlen(struct tas25xx_priv *p_tas25xx, int32_t ch, int32_t rx_slotlen);
int32_t tas25xx_set_tx_slotlen(struct tas25xx_priv *p_tas25xx, int32_t ch, int32_t tx_slotlen);
int32_t tas25xx_set_pre_powerup(struct tas25xx_priv *p_tas25xx, int32_t ch);
int32_t tas25xx_set_post_powerup(struct tas25xx_priv *p_tas25xx, int32_t ch);
int32_t tas25xx_set_pre_powerdown(struct tas25xx_priv *p_tas25xx, int32_t ch);
int32_t tas25xx_set_post_powerdown(struct tas25xx_priv *p_tas25xx, int32_t ch);
int32_t tas25xx_process_block(struct tas25xx_priv *p_tas25xx, char *mem, int32_t chn);
int32_t tas25xx_check_if_powered_on(struct tas25xx_priv *p_tas25xx, int *state, int ch);
int tas_write_init_config_params(struct tas25xx_priv *p_tas25xx, int number_of_channels);
int32_t tas25xx_update_kcontrol_data(struct tas25xx_priv *p_tas25xx, enum kcntl_during_t cur_state,
uint32_t chmask);
void tas25xx_prep_dev_for_calib(int start);
#endif /* __TAS25XX_REGBIN_PARSER__ */

View File

@ -1,26 +0,0 @@
#ifndef __TAS25XX_REGMAP__
#define __TAS25XX_REGMAP__
#include <linux/version.h>
#include "tas25xx.h"
struct linux_platform {
struct device *dev;
struct i2c_client *client;
struct regmap *regmap[MAX_CHANNELS];
struct hrtimer mtimer;
struct snd_soc_component *codec;
/* device is working, but system is suspended */
int (*runtime_suspend)(struct tas25xx_priv *p_tas25xx);
int (*runtime_resume)(struct tas25xx_priv *p_tas25xx);
bool mb_runtime_suspend;
bool i2c_suspend;
};
void tas25xx_select_cfg_blk(void *pContext, int conf_no,
unsigned char block_type);
void tas25xx_dump_regs(struct tas25xx_priv *p_tas25xx, int chn);
void tas25xx_register_i2c_error_callback(void (*i2c_err_cb)(uint32_t));
int tas25xx_check_last_i2c_error_n_reset(void);
#endif /*__TAS25XX_REGMAP__*/

View File

@ -1,420 +0,0 @@
/*
* ALSA SoC Texas Instruments TAS25XX High Performance 4W Smart Amplifier
*
* Copyright (C) 2022 Texas Instruments, Inc.
*
* Author: Niranjan H Y, Vijeth P O
*
* This package is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#ifndef __TAS25XX__
#define __TAS25XX__
#include <linux/mutex.h>
#include <linux/workqueue.h>
#include <linux/hrtimer.h>
#include <linux/printk.h>
#include <linux/delay.h>
#include <sound/soc.h>
#include <linux/version.h>
#define TAS25XX_DRIVER_TAG "UDA_0.0.21_6_K6.1"
#define MAX_CHANNELS 4
/* Page Control Register */
#define TAS25XX_PAGECTL_REG 0
/* Book Control Register (available in page0 of each book) */
#define TAS25XX_BOOKCTL_PAGE 0
#define TAS25XX_BOOKCTL_REG 127
#define TAS25XX_REG(book, page, reg) (((book * 256 * 128) + \
(page * 128)) + reg)
#define TAS25XX_BOOK_ID(reg) (reg / (256 * 128))
#define TAS25XX_PAGE_ID(reg) ((reg % (256 * 128)) / 128)
#define TAS25XX_BOOK_REG(reg) (reg % (256 * 128))
#define TAS25XX_PAGE_REG(reg) ((reg % (256 * 128)) % 128)
#define TAS25XX_REG_NO_BOOK(reg) (reg - (TAS25XX_BOOK_ID(reg) * 256 * 128))
/* Book */
#define TAS25XX_BOOK TAS25XX_REG(0x0, 0x0, 0x7F)
#define TAS25XX_BOOK_BOOK70_MASK (0xff << 0)
/* Rev Info */
#define TAS25XX_REVID_REG TAS25XX_REG(0x0, 0x0, 0x78)
/* data format */
#define TAS25XX_DATAFORMAT_SHIFT 2
#define TAS25XX_DATAFORMAT_I2S 0x0
#define TAS25XX_DATAFORMAT_DSP 0x1
#define TAS25XX_DATAFORMAT_RIGHT_J 0x2
#define TAS25XX_DATAFORMAT_LEFT_J 0x3
#define TAS25XX_DAI_FMT_MASK (0x7 << TAS25XX_DATAFORMAT_SHIFT)
#define ERROR_NONE 0x0000000
#define ERROR_PLL_ABSENT 0x0000001
#define ERROR_DEVA_I2C_COMM 0x0000002
#define ERROR_DEVB_I2C_COMM 0x0000004
#define ERROR_CLOCK 0x0000008
#define ERROR_YRAM_CRCCHK 0x0000010
#define ERROR_OVER_CURRENT 0x0000020
#define ERROR_DIE_OVERTEMP 0x0000040
#define ERROR_OVER_VOLTAGE 0x0000080
#define ERROR_UNDER_VOLTAGE 0x0000100
#define ERROR_BROWNOUT 0x0000200
#define ERROR_CLASSD_PWR 0x0000400
#define ERROR_FAILSAFE 0x0000800
#define TAS25XX_IRQ_DET_TIMEOUT 30000
#define TAS25XX_IRQ_DET_CNT_LIMIT 500
/* 5 second */
#define CHECK_PERIOD 5000
#define TAS25XX_I2C_RETRY_COUNT 3
#define TAS25XX_SWITCH 0x10000001
#define TAS25XX_RIGHT_SWITCH 0x10000002
#define RX_SCFG_LEFT 0x10000003
#define RX_SCFG_RIGHT 0x10000004
#define RESTART_MAX 3
#define MAX_CMD_LIST 5 /* sysfs cmd nodes */
struct tas25xx_priv;
struct snd_soc_component;
/* REGBIN related */
#define TAS25XX_CONFIG_SIZE (10)
#define TAS25XX_DEVICE_SUM (8)
#define TAS25XX_CMD_SING_W (0x1)
#define TAS25XX_CMD_BURST (0x2)
#define TAS25XX_CMD_DELAY (0x3)
#define TAS25XX_CMD_FIELD_W (0x4)
#define SMS_HTONS(a, b) ((((a)&0x00FF)<<8) | \
((b)&0x00FF))
#define SMS_HTONL(a, b, c, d) ((((a)&0x000000FF)<<24) |\
(((b)&0x000000FF)<<16) | \
(((c)&0x000000FF)<<8) | \
((d)&0x000000FF))
#define CMD_SINGLE_WRITE 0
#define CMD_BURST_WRITES 1
#define CMD_UPDATE_BITS 2
#define CMD_DELAY 3
#define CMD_SINGLE_WRITE_SZ 6
#define CMD_BURST_WRITES_SZ 9
#define CMD_UPDATE_BITS_SZ 7
#define CMD_DELAY_SZ 5
#define DSP_FW_LOAD_NTRIES 20
#define INTERRUPT_TYPE_CLOCK_BASED (1<<0)
#define INTERRUPT_TYPE_NON_CLOCK_BASED (1<<1)
enum tas_power_states_t {
TAS_POWER_ACTIVE = 0,
TAS_POWER_MUTE = 1,
TAS_POWER_SHUTDOWN = 2,
};
enum tas25xx_dsp_fw_state {
TAS25XX_DSP_FW_NONE = 0,
TAS25XX_DSP_FW_TRYLOAD,
TAS25XX_DSP_FW_PARSE_FAIL,
TAS25XX_DSP_FW_LOAD_FAIL,
TAS25XX_DSP_FW_OK,
};
enum tas25xx_bin_blk_type {
TAS25XX_BIN_BLK_COEFF = 1,
TAS25XX_BIN_BLK_POST_POWER_UP,
TAS25XX_BIN_BLK_PRE_SHUTDOWN,
TAS25XX_BIN_BLK_PRE_POWER_UP,
TAS25XX_BIN_BLK_POST_SHUTDOWN
};
enum tas_int_action_t {
TAS_INT_ACTION_NOACTION = 0,
TAS_INT_ACTION_SW_RESET = 1 << 0,
TAS_INT_ACTION_HW_RESET = 1 << 1,
TAS_INT_ACTION_POWER_ON = 1 << 2,
};
struct tas25xx_block_data {
unsigned char dev_idx;
unsigned char block_type;
unsigned short yram_checksum;
unsigned int block_size;
unsigned int nSublocks;
unsigned char *regdata;
};
struct tas25xx_config_info {
unsigned int nblocks;
unsigned int real_nblocks;
struct tas25xx_block_data **blk_data;
};
void tas25xx_select_cfg_blk(void *pContext, int conf_no,
unsigned char block_type);
int tas25xx_load_container(struct tas25xx_priv *pTAS256x);
void tas25xx_config_info_remove(void *pContext);
struct tas25xx_register {
int book;
int page;
int reg;
};
/* Used for Register Dump */
struct tas25xx_reg {
unsigned int reg_index;
unsigned int reg_val;
};
struct tas25xx_dai_cfg {
unsigned int dai_fmt;
unsigned int tdm_delay;
};
/*struct tas25xx_buf_cfg {
* unsigned short bufSize;
* unsigned char *buf;
*};
*/
//This should be removed or modified
enum ch_bitmask {
channel_left = 0x1 << 0,
channel_right = 0x1 << 1,
channel_both = channel_left|channel_right
};
/*
* device ops function structure
*/
struct tas_device_ops {
/**< init typically for loading optimal settings */
int (*tas_init)(struct tas25xx_priv *p_tas25xx, int chn);
int (*tas_probe)(struct tas25xx_priv *p_tas25xx,
struct snd_soc_component *codec, int chn);
/*TODO:*/
};
struct tas_device {
int mn_chip_id;
int mn_current_book;
int mn_addr;
int reset_gpio;
int irq_gpio;
int irq_no;
int device_id;
int channel_no;
int rx_mode;
int dvc_pcm;
int bst_vltg;
int bst_ilm;
int ampoutput_lvl;
int lim_switch;
int lim_max_attn;
int lim_thr_max;
int lim_thr_min;
int lim_att_rate;
int lim_rel_rate;
int lim_att_stp_size;
int lim_rel_stp_size;
int lim_max_thd;
int lim_min_thd;
int lim_infl_pt;
int lim_trk_slp;
int bop_enable;
int bop_thd;
int bop_att_rate;
int bop_att_stp_size;
int bop_hld_time;
int bop_mute;
int bosd_enable;
int bosd_thd;
int vbat_lpf;
int rx_cfg;
int classh_timer;
int reciever_enable;
int icn_sw;
int icn_thr;
int icn_hyst;
struct tas_device_ops dev_ops;
struct delayed_work init_work;
struct tas25xx_priv *prv_data;
/* interrupt count since interrupt enable */
uint8_t irq_count;
unsigned long jiffies;
/* Fail Safe */
unsigned int mn_restart;
};
struct tas25xx_intr_info {
char name[64];
int32_t reg;
int32_t mask;
int32_t action;
int32_t detected;
int32_t is_clock_based;
int32_t notify_int_val;
uint32_t count;
uint64_t count_persist;
struct device_attribute *dev_attr;
};
struct tas25xx_interrupts {
uint8_t count;
uint8_t *buf_intr_enable;
uint8_t *buf_intr_disable;
uint8_t *buf_intr_clear;
struct tas25xx_intr_info *intr_info;
uint32_t processing_delay;
};
struct tas_regbin_read_blok_t {
int32_t reg;
int32_t mask;
int32_t value;
};
struct tas_block_op_data_t {
uint32_t no_of_rx_blks;
uint32_t no_of_tx_blks;
uint8_t *sw_reset;
uint8_t *power_check;
uint8_t *mute;
uint8_t *cal_init;
uint8_t *cal_deinit;
uint8_t *rx_fmt_data;
uint8_t *tx_fmt_data;
};
#if IS_ENABLED(CONFIG_TAS25XX_IRQ_BD)
struct irq_bigdata {
struct device_attribute *p_dev_attr;
struct attribute **p_attr_arr;
struct device *irq_dev;
};
#endif
struct cmd_data {
struct device_attribute *p_dev_attr;
struct attribute **p_attr_arr;
struct device *cmd_dev;
};
struct tas25xx_priv {
struct linux_platform *platform_data;
struct kobject *k_obj;
int m_power_state;
int mn_frame_size;
int mn_ppg;
int mn_ch_size;
int mn_rx_width;
int mn_tx_slot_width;
int sample_rate;
int mn_iv_width;
int curr_mn_iv_width;
int mn_vbat;
int curr_mn_vbat;
int ch_count;
int mn_slots;
unsigned int mn_fmt;
int mn_fmt_mode;
int mn_frame_start;
int mn_rx_edge;
int mn_rx_offset;
int mn_tx_edge;
int mn_tx_offset;
int *ti_amp_state;
int dac_power; /* this is set based on the DAC events */
struct tas_device **devs;
int (*read)(struct tas25xx_priv *p_tas25xx, int32_t chn,
unsigned int reg, unsigned int *pValue);
int (*write)(struct tas25xx_priv *p_tas25xx, int32_t chn,
unsigned int reg, unsigned int Value);
int (*bulk_read)(struct tas25xx_priv *p_tas25xx, int32_t chn,
unsigned int reg, unsigned char *p_data, unsigned int len);
int (*bulk_write)(struct tas25xx_priv *p_tas25xx, int32_t chn,
unsigned int reg, unsigned char *p_data, unsigned int len);
int (*update_bits)(struct tas25xx_priv *p_tas25xx, int32_t chn,
unsigned int reg, unsigned int mask, unsigned int value);
void (*hw_reset)(struct tas25xx_priv *p_tas25xx);
void (*clear_irq)(struct tas25xx_priv *p_tas25xx);
void (*enable_irq)(struct tas25xx_priv *p_tas25xx);
void (*disable_irq)(struct tas25xx_priv *p_tas25xx);
unsigned int mn_err_code;
int (*plat_write)(void *plat_data,
unsigned int i2c_addr, unsigned int reg, unsigned int value,
unsigned int channel);
int (*plat_bulk_write)(void *plat_data, unsigned int i2c_addr,
unsigned int reg, unsigned char *pData,
unsigned int nLength, unsigned int channel);
int (*plat_read)(void *plat_data, unsigned int i2c_addr,
unsigned int reg, unsigned int *value, unsigned int channel);
int (*plat_bulk_read)(void *plat_data, unsigned int i2c_addr,
unsigned int reg, unsigned char *pData,
unsigned int nLength, unsigned int channel);
int (*plat_update_bits)(void *plat_data, unsigned int i2c_addr,
unsigned int reg, unsigned int mask,
unsigned int value, unsigned int channel);
void (*schedule_init_work)(struct tas25xx_priv *p_tas25xx, int ch);
void (*cancel_init_work) (struct tas25xx_priv *p_tas25xx, int ch);
struct mutex dev_lock;
struct mutex codec_lock;
struct mutex file_lock;
struct delayed_work irq_work;
struct delayed_work dc_work;
int iv_enable;
uint32_t dev_revid;
uint32_t fw_size;
uint8_t *fw_data;
struct delayed_work post_fw_load_work;
struct delayed_work fw_load_work;
wait_queue_head_t fw_wait;
int fw_load_retry_count;
atomic_t fw_state;
atomic_t fw_wait_complete;
wait_queue_head_t dev_init_wait;
atomic_t dev_init_status;
int device_used;
int irq_enabled[MAX_CHANNELS];
struct tas25xx_interrupts intr_data[MAX_CHANNELS];
#if IS_ENABLED(CONFIG_TAS25XX_IRQ_BD)
struct irq_bigdata irqdata;
#endif
struct class *class;
struct cmd_data cmd_data;
struct tas_block_op_data_t block_op_data[MAX_CHANNELS];
};
static inline int is_power_up_state(enum tas_power_states_t state)
{
if (state == TAS_POWER_ACTIVE)
return 1;
return 0;
}
#endif /* __TAS25XX__ */

View File

@ -1,716 +0,0 @@
/*
* =============================================================================
* Copyright (c) 2016 Texas Instruments Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; version 2.
*
* 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.
*
* File:
* tas25xx-codec.c
*
* Description:
* ALSA SoC driver for Texas Instruments TAS25XX High Performance 4W Smart
* Amplifier
*
* =============================================================================
*/
#define DEBUG 5
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/regulator/consumer.h>
#include <linux/firmware.h>
#include <linux/regmap.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/initval.h>
#include <sound/tlv.h>
#include <linux/version.h>
#include "../inc/tas25xx.h"
#include "../inc/tas25xx-ext.h"
#include "../inc/tas25xx-device.h"
#include "../inc/tas25xx-logic.h"
#include "../inc/tas25xx-regmap.h"
#include "../inc/tas25xx-regbin-parser.h"
#if IS_ENABLED(CONFIG_TAS25XX_ALGO)
#include "../algo/inc/tas_smart_amp_v2.h"
#include "../algo/inc/tas25xx-calib.h"
#endif /*CONFIG_TAS25XX_ALGO*/
static const char *irq_gpio_label[2] = {
"TAS25XX-IRQ", "TAS25XX-IRQ2"
};
static struct tas25xx_priv *s_tas25xx;
int tas25xx_start_fw_load(struct tas25xx_priv *p_tas25xx, int retry_count);
static unsigned int tas25xx_codec_read(struct snd_soc_component *codec,
unsigned int reg)
{
unsigned int value = 0;
struct tas25xx_priv *p_tas25xx = snd_soc_component_get_drvdata(codec);
int ret = -1;
struct linux_platform *plat_data =
(struct linux_platform *) p_tas25xx->platform_data;
switch (reg) {
case TAS25XX_SWITCH:
dev_dbg(plat_data->dev, "%s: %d, %d TAS25XX_SWITCH",
__func__, reg, value);
value = p_tas25xx->device_used;
break;
default:
dev_dbg(plat_data->dev, "%s: %d, %d default read",
__func__, reg, value);
ret = p_tas25xx->read(p_tas25xx, 0, reg, &value);
break;
}
dev_dbg(plat_data->dev, "%s, reg=%d, value=%d", __func__, reg, value);
if (ret == 0)
return value;
else
return ret;
}
static int tas25xx_codec_write(struct snd_soc_component *codec,
unsigned int reg, unsigned int value)
{
struct tas25xx_priv *p_tas25xx = snd_soc_component_get_drvdata(codec);
struct linux_platform *plat_data =
(struct linux_platform *) p_tas25xx->platform_data;
int ret = 0;
switch (reg) {
case TAS25XX_SWITCH:
dev_dbg(plat_data->dev, "%s: %d, %d TAS25XX_SWITCH",
__func__, reg, value);
p_tas25xx->device_used = value;
break;
default:
ret = -EINVAL;
dev_dbg(plat_data->dev, "%s: %d, %d UNIMPLEMENTED",
__func__, reg, value);
break;
}
return ret;
}
#if IS_ENABLED(CODEC_PM)
static int tas25xx_codec_suspend(struct snd_soc_component *codec)
{
struct tas25xx_priv *p_tas25xx = snd_soc_component_get_drvdata(codec);
struct linux_platform *plat_data =
(struct linux_platform *) p_tas25xx->platform_data;
int ret = -1;
dev_dbg(plat_data->dev, "%s\n", __func__);
mutex_lock(&p_tas25xx->codec_lock);
ret = plat_data->runtime_suspend(p_tas25xx);
mutex_unlock(&p_tas25xx->codec_lock);
return ret;
}
static int tas25xx_codec_resume(struct snd_soc_component *codec)
{
struct tas25xx_priv *p_tas25xx = snd_soc_component_get_drvdata(codec);
struct linux_platform *plat_data =
(struct linux_platform *) p_tas25xx->platform_data;
int ret = 0;
mutex_lock(&p_tas25xx->codec_lock);
dev_dbg(plat_data->dev, "%s\n", __func__);
ret = plat_data->runtime_resume(p_tas25xx);
mutex_unlock(&p_tas25xx->codec_lock);
return ret;
}
#endif
static int tas25xx_dac_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm);
struct tas25xx_priv *p_tas25xx = snd_soc_component_get_drvdata(codec);
struct linux_platform *plat_data =
(struct linux_platform *) p_tas25xx->platform_data;
int ret = -1;
mutex_lock(&p_tas25xx->codec_lock);
switch (event) {
case SND_SOC_DAPM_POST_PMU:
p_tas25xx->dac_power = 1;
dev_info(plat_data->dev, "SND_SOC_DAPM_POST_PMU\n");
ret = tas25xx_set_power_state(p_tas25xx, TAS_POWER_ACTIVE, 0xffff);
break;
case SND_SOC_DAPM_PRE_PMD:
p_tas25xx->dac_power = 0;
dev_info(plat_data->dev, "SND_SOC_DAPM_PRE_PMD\n");
if (p_tas25xx->m_power_state != TAS_POWER_SHUTDOWN)
ret = tas25xx_set_power_state(p_tas25xx, TAS_POWER_SHUTDOWN, 0xffff);
else
ret = 0;
break;
}
mutex_unlock(&p_tas25xx->codec_lock);
return ret;
}
static const struct snd_kcontrol_new dapm_switch =
SOC_DAPM_SINGLE("Switch", TAS25XX_SWITCH, 0, 1, 0);
static const struct snd_soc_dapm_widget tas25xx_dapm_widgets[] = {
SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_SWITCH("TAS25XX ASI", SND_SOC_NOPM, 0, 0, &dapm_switch),
SND_SOC_DAPM_AIF_OUT("Voltage Sense", "ASI1 Capture", 1,
SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_OUT("Current Sense", "ASI1 Capture", 0,
SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, tas25xx_dac_event,
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_OUTPUT("OUT"),
SND_SOC_DAPM_SIGGEN("VMON"),
SND_SOC_DAPM_SIGGEN("IMON")
};
static const struct snd_soc_dapm_route tas25xx_audio_map[] = {
{"DAC", NULL, "ASI1"},
{"TAS25XX ASI", "Switch", "DAC"},
{"OUT", NULL, "TAS25XX ASI"},
{"Voltage Sense", NULL, "VMON"},
{"Current Sense", NULL, "IMON"},
};
static bool fw_load_required(struct tas25xx_priv *p_tas25xx)
{
return (atomic_read(&p_tas25xx->fw_state) == TAS25XX_DSP_FW_LOAD_FAIL);
}
static int tas25xx_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
int i;
struct snd_soc_component *codec = dai->component;
struct tas25xx_priv *p_tas25xx
= snd_soc_component_get_drvdata(codec);
struct linux_platform *plat_data =
(struct linux_platform *) p_tas25xx->platform_data;
int bitwidth = 16;
int ret = -EINVAL;
unsigned int channels = params_channels(params);
if (fw_load_required(p_tas25xx)) {
dev_warn(plat_data->dev, "%s, firmware is not loaded, retry", __func__);
ret = tas25xx_start_fw_load(p_tas25xx, 3);
if (ret < 0) {
dev_err(plat_data->dev, "%s fw load failed", __func__);
return ret;
}
}
mutex_lock(&p_tas25xx->codec_lock);
dev_dbg(plat_data->dev, "%s, stream %s format: %d\n", __func__,
(substream->stream ==
SNDRV_PCM_STREAM_PLAYBACK) ? ("Playback") : ("Capture"),
params_format(params));
if (channels > 2) {
/* assume TDM mode */
p_tas25xx->mn_fmt_mode = 2;
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
bitwidth = 16;
break;
case SNDRV_PCM_FORMAT_S24_LE:
bitwidth = 24;
break;
case SNDRV_PCM_FORMAT_S32_LE:
bitwidth = 32;
break;
}
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
ret = tas25xx_set_tdm_rx_slot(p_tas25xx, channels,
bitwidth);
else /*Assumed Capture*/
ret = tas25xx_set_tdm_tx_slot(p_tas25xx, channels,
bitwidth);
} else {
/* assume I2S mode*/
p_tas25xx->mn_fmt_mode = 1;
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
bitwidth = 16;
break;
case SNDRV_PCM_FORMAT_S24_LE:
bitwidth = 24;
break;
case SNDRV_PCM_FORMAT_S32_LE:
bitwidth = 32;
break;
}
ret = tas25xx_set_bitwidth(p_tas25xx,
bitwidth, substream->stream);
if (ret < 0) {
dev_info(plat_data->dev, "set bitwidth failed, %d\n",
ret);
goto ret;
}
}
dev_info(plat_data->dev, "%s, stream %s sample rate: %d\n", __func__,
(substream->stream ==
SNDRV_PCM_STREAM_PLAYBACK) ? ("Playback") : ("Capture"),
params_rate(params));
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
for (i = 0; i < p_tas25xx->ch_count; i++)
ret = tas25xx_set_sample_rate(p_tas25xx, i, params_rate(params));
ret:
mutex_unlock(&p_tas25xx->codec_lock);
return ret;
}
static int tas25xx_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{
struct snd_soc_component *codec = dai->component;
struct tas25xx_priv *p_tas25xx = snd_soc_component_get_drvdata(codec);
struct linux_platform *plat_data =
(struct linux_platform *) p_tas25xx->platform_data;
int ret = -EINVAL;
if (fw_load_required(p_tas25xx)) {
dev_warn(plat_data->dev, "%s, firmware is not loaded, retry", __func__);
ret = tas25xx_start_fw_load(p_tas25xx, 3);
if (ret < 0) {
dev_err(plat_data->dev, "%s fw load failed", __func__);
return ret;
}
}
dev_info(plat_data->dev, "%s, format=0x%x\n", __func__, fmt);
p_tas25xx->mn_fmt = fmt;
ret = tas25xx_set_dai_fmt_for_fmt(p_tas25xx, fmt);
return ret;
}
static int tas25xx_set_dai_tdm_slot(struct snd_soc_dai *dai,
unsigned int tx_mask, unsigned int rx_mask,
int slots, int slot_width)
{
int ret = -EINVAL;
struct snd_soc_component *codec = dai->component;
struct tas25xx_priv *p_tas25xx = snd_soc_component_get_drvdata(codec);
struct linux_platform *plat_data =
(struct linux_platform *) p_tas25xx->platform_data;
if (fw_load_required(p_tas25xx)) {
dev_warn(plat_data->dev, "%s, firmware is not loaded, retry", __func__);
ret = tas25xx_start_fw_load(p_tas25xx, 3);
if (ret < 0) {
dev_err(plat_data->dev, "%s fw load failed", __func__);
return ret;
}
}
dev_dbg(plat_data->dev, "%s, tx_mask:%d, rx_mask:%d",
__func__, tx_mask, rx_mask);
dev_dbg(plat_data->dev, "%s, slots:%d,slot_width:%d",
__func__, slots, slot_width);
if (rx_mask) {
p_tas25xx->mn_fmt_mode = 2; /*TDM Mode*/
ret = tas25xx_set_tdm_rx_slot(p_tas25xx, slots, slot_width);
} else if (tx_mask) {
p_tas25xx->mn_fmt_mode = 2;
ret = tas25xx_set_tdm_tx_slot(p_tas25xx, slots, slot_width);
} else {
dev_err(plat_data->dev, "%s, Invalid Mask",
__func__);
p_tas25xx->mn_fmt_mode = 0;
}
return ret;
}
static int tas25xx_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
{
int ret = 0;
struct snd_soc_component *codec = dai->component;
struct tas25xx_priv *p_tas25xx = snd_soc_component_get_drvdata(codec);
struct linux_platform *plat_data =
(struct linux_platform *) p_tas25xx->platform_data;
if (fw_load_required(p_tas25xx)) {
dev_warn(plat_data->dev, "%s, firmware is not loaded, retry", __func__);
ret = tas25xx_start_fw_load(p_tas25xx, 3);
if (ret < 0) {
dev_err(plat_data->dev, "%s fw load failed", __func__);
return ret;
}
}
dev_dbg(plat_data->dev, "%s, stream %s mute %d\n", __func__,
(stream == SNDRV_PCM_STREAM_PLAYBACK) ? ("Playback") : ("Capture"),
mute);
if (stream != SNDRV_PCM_STREAM_PLAYBACK)
return ret;
mutex_lock(&p_tas25xx->codec_lock);
if (mute)
ret = tas25xx_set_power_state(p_tas25xx, TAS_POWER_MUTE,
(0xf & tas25xx_get_drv_channel_opmode()));
mutex_unlock(&p_tas25xx->codec_lock);
if (mute) {
#if IS_ENABLED(CONFIG_TAS25XX_ALGO)
tas25xx_stop_algo_processing();
#endif /* CONFIG_TAS25XX_ALGO */
#if IS_ENABLED(CONFIG_TAS25XX_IRQ_BD)
tas25xx_log_interrupt_stats(p_tas25xx);
#endif /* CONFIG_TAS25XX_IRQ_BD */
} else {
#if IS_ENABLED(CONFIG_TAS25XX_ALGO)
tas25xx_start_algo_processing(p_tas25xx->curr_mn_iv_width,
p_tas25xx->curr_mn_vbat);
#endif /* CONFIG_TAS25XX_ALGO */
#if IS_ENABLED(CONFIG_TAS25XX_IRQ_BD)
tas25xx_clear_interrupt_stats(p_tas25xx);
#endif /* CONFIG_TAS25XX_IRQ_BD */
}
return ret;
}
static struct snd_soc_dai_ops tas25xx_dai_ops = {
.hw_params = tas25xx_hw_params,
.set_fmt = tas25xx_set_dai_fmt,
.set_tdm_slot = tas25xx_set_dai_tdm_slot,
.mute_stream = tas25xx_mute_stream,
};
#define TAS25XX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE |\
SNDRV_PCM_FMTBIT_S32_LE)
static struct snd_soc_dai_driver tas25xx_dai_driver[] = {
{
.name = "tas25xx ASI1",
.id = 0,
.playback = {
.stream_name = "ASI1 Playback",
.channels_min = 1,
.channels_max = 8,
.rates = SNDRV_PCM_RATE_8000_192000,
.formats = TAS25XX_FORMATS,
},
.capture = {
.stream_name = "ASI1 Capture",
.channels_min = 1,
.channels_max = 8,
.rates = SNDRV_PCM_RATE_8000_192000,
.formats = TAS25XX_FORMATS,
},
.ops = &tas25xx_dai_ops,
.symmetric_rate = 1,
},
};
static irqreturn_t tas25xx_irq_handler(int irq, void *dev_id)
{
struct tas25xx_priv *p_tas25xx = (struct tas25xx_priv *)dev_id;
if (p_tas25xx != s_tas25xx)
return IRQ_NONE;
schedule_delayed_work(&p_tas25xx->irq_work,
msecs_to_jiffies(p_tas25xx->intr_data[0].processing_delay));
return IRQ_HANDLED;
}
static int tas25xx_setup_irq(struct tas25xx_priv *p_tas25xx)
{
int i, ret = -EINVAL;
struct linux_platform *plat_data =
(struct linux_platform *) p_tas25xx->platform_data;
if (!plat_data)
return ret;
/* register for interrupts */
for (i = 0; i < p_tas25xx->ch_count; i++) {
if (gpio_is_valid(p_tas25xx->devs[i]->irq_gpio)) {
ret = gpio_request(p_tas25xx->devs[i]->irq_gpio,
irq_gpio_label[i]);
if (ret) {
dev_err(plat_data->dev,
"%s:%u: ch 0x%02x: GPIO %d request error\n",
__func__, __LINE__,
p_tas25xx->devs[i]->mn_addr,
p_tas25xx->devs[i]->irq_gpio);
continue;
}
gpio_direction_input(p_tas25xx->devs[i]->irq_gpio);
p_tas25xx->devs[i]->irq_no =
gpio_to_irq(p_tas25xx->devs[i]->irq_gpio);
dev_info(plat_data->dev, "irq = %d\n",
p_tas25xx->devs[i]->irq_no);
ret = devm_request_threaded_irq(plat_data->dev,
p_tas25xx->devs[i]->irq_no, tas25xx_irq_handler, NULL,
IRQF_TRIGGER_FALLING | IRQF_ONESHOT | IRQF_SHARED,
"tas25xx", p_tas25xx);
if (ret) {
dev_err(plat_data->dev, "request_irq failed, error=%d\n", ret);
} else {
p_tas25xx->irq_enabled[i] = 1;
dev_info(plat_data->dev, "Interrupt registration successful!!!");
}
}
}
return ret;
}
static int init_dev_with_fw_data(struct tas25xx_priv *p_tas25xx)
{
int ret, i;
struct linux_platform *plat_data = NULL;
plat_data = (struct linux_platform *) p_tas25xx->platform_data;
/* software reset and initial writes */
for (i = 0; i < p_tas25xx->ch_count; i++) {
ret = tas25xx_software_reset(p_tas25xx, i);
if (ret < 0) {
dev_err(plat_data->dev, "I2c fail, %d\n", ret);
goto post_fw_load_work_done;
}
}
ret = tas_write_init_config_params(p_tas25xx, p_tas25xx->ch_count);
if (ret) {
dev_err(plat_data->dev, "Failed to initialize, error=%d", ret);
goto post_fw_load_work_done;
}
ret = tas25xx_probe(p_tas25xx);
if (ret) {
dev_err(plat_data->dev, "Failed to initialize, error=%d", ret);
goto post_fw_load_work_done;
}
ret = tas25xx_setup_irq(p_tas25xx);
if (ret) {
dev_err(plat_data->dev, "failed to initialize irq=%d", ret);
}
post_fw_load_work_done:
return ret;
}
static void fw_load_work_routine(struct work_struct *work)
{
int ret;
struct linux_platform *plat_data = NULL;
struct tas25xx_priv *p_tas25xx =
container_of(work, struct tas25xx_priv, fw_load_work.work);
plat_data = (struct linux_platform *) p_tas25xx->platform_data;
ret = tas25xx_load_firmware(p_tas25xx, p_tas25xx->fw_load_retry_count);
dev_info(plat_data->dev, "%s FW loading %s", __func__,
!ret ? "success" : "fail");
if (!ret) {
ret = init_dev_with_fw_data(p_tas25xx);
if (ret)
dev_err(plat_data->dev,
"%s fw dnld to device error=%d", __func__, ret);
else
atomic_set(&p_tas25xx->dev_init_status, 1);
}
if (ret)
atomic_set(&p_tas25xx->dev_init_status, ret);
wake_up(&p_tas25xx->dev_init_wait);
}
int tas25xx_start_fw_load(struct tas25xx_priv *p_tas25xx, int retry_count)
{
int i, ret, i2c_err, ch_count;
struct linux_platform *plat_data = NULL;
atomic_set(&p_tas25xx->dev_init_status, 0);
atomic_set(&p_tas25xx->fw_state, TAS25XX_DSP_FW_TRYLOAD);
p_tas25xx->fw_load_retry_count = retry_count;
plat_data = (struct linux_platform *) p_tas25xx->platform_data;
ch_count = p_tas25xx->ch_count;
tas25xx_check_last_i2c_error_n_reset();
INIT_DELAYED_WORK(&p_tas25xx->fw_load_work, fw_load_work_routine);
schedule_delayed_work(&p_tas25xx->fw_load_work, msecs_to_jiffies(0));
wait_event_interruptible(p_tas25xx->dev_init_wait,
atomic_read(&p_tas25xx->dev_init_status) != 0);
/* set -ve errno or success 1*/
ret = atomic_read(&p_tas25xx->dev_init_status);
if (ret == 1) {
for (i = 0; i < ch_count; i++)
p_tas25xx->ti_amp_state[i] = TAS_AMP_STATE_FW_LOAD_SUCCESS;
} else {
i2c_err = tas25xx_check_last_i2c_error_n_reset();
for (i = 0; i < ch_count; i++)
if (i2c_err)
p_tas25xx->ti_amp_state[i] = TAS_AMP_ERR_I2C;
else
p_tas25xx->ti_amp_state[i] = TAS_AMP_ERR_FW_LOAD;
}
return ret;
}
static int tas25xx_codec_probe(struct snd_soc_component *codec)
{
int ret = -1, i = 0;
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec);
struct tas25xx_priv *p_tas25xx = snd_soc_component_get_drvdata(codec);
struct linux_platform *plat_data =
(struct linux_platform *) p_tas25xx->platform_data;
char *w_name[4] = {NULL};
const char *prefix = codec->name_prefix;
int w_count = 0;
if (plat_data)
plat_data->codec = codec;
s_tas25xx = p_tas25xx;
/*Moved from machine driver to codec*/
if (prefix) {
w_name[0] = kasprintf(GFP_KERNEL, "%s %s",
prefix, "ASI1 Playback");
w_name[1] = kasprintf(GFP_KERNEL, "%s %s",
prefix, "ASI1 Capture");
w_name[2] = kasprintf(GFP_KERNEL, "%s %s",
prefix, "OUT");
w_count = 3;
} else {
w_name[0] = kasprintf(GFP_KERNEL, "%s", "ASI1 Playback");
w_name[1] = kasprintf(GFP_KERNEL, "%s", "ASI1 Capture");
w_name[2] = kasprintf(GFP_KERNEL, "%s", "OUT");
w_count = 3;
}
for (i = 0; i < w_count; i++) {
snd_soc_dapm_ignore_suspend(dapm, w_name[i]);
kfree(w_name[i]);
}
snd_soc_dapm_sync(dapm);
ret = tas25xx_start_fw_load(p_tas25xx, 800);
if (ret == -ENOENT)
ret = 0;
dev_info(plat_data->dev, "%s returning ret=%d\n",
__func__, ret);
return ret;
}
static void tas25xx_codec_remove(struct snd_soc_component *codec)
{
struct tas25xx_priv *p_tas25xx = snd_soc_component_get_drvdata(codec);
tas25xx_remove(p_tas25xx);
s_tas25xx = NULL;
}
static struct snd_soc_component_driver soc_codec_driver_tas25xx = {
.probe = tas25xx_codec_probe,
.remove = tas25xx_codec_remove,
.read = tas25xx_codec_read,
.write = tas25xx_codec_write,
#if IS_ENABLED(CODEC_PM)
.suspend = tas25xx_codec_suspend,
.resume = tas25xx_codec_resume,
#endif
.dapm_widgets = tas25xx_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(tas25xx_dapm_widgets),
.dapm_routes = tas25xx_audio_map,
.num_dapm_routes = ARRAY_SIZE(tas25xx_audio_map),
};
int tas25xx_register_codec(struct tas25xx_priv *p_tas25xx)
{
int ret = -1;
struct linux_platform *plat_data =
(struct linux_platform *) p_tas25xx->platform_data;
dev_info(plat_data->dev, "%s, enter\n", __func__);
ret = devm_snd_soc_register_component(plat_data->dev,
&soc_codec_driver_tas25xx,
tas25xx_dai_driver, ARRAY_SIZE(tas25xx_dai_driver));
return ret;
}
int tas25xx_deregister_codec(struct tas25xx_priv *p_tas25xx)
{
struct linux_platform *plat_data =
(struct linux_platform *) p_tas25xx->platform_data;
snd_soc_unregister_component(plat_data->dev);
return 0;
}
MODULE_AUTHOR("Texas Instruments Inc.");
MODULE_DESCRIPTION("TAS25XX ALSA SOC Smart Amplifier driver");
MODULE_LICENSE("GPL v2");

View File

@ -1,497 +0,0 @@
/*
* =============================================================================
* Copyright (c) 2016 Texas Instruments Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; version 2.
*
* 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.
* File:
* tas25xx-misc.c
*
* Description:
* misc driver for Texas Instruments
* TAS25XX High Performance 4W Smart Amplifier
*
* =============================================================================
*/
#define DEBUG
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/regulator/consumer.h>
#include <linux/firmware.h>
#include <linux/regmap.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/slab.h>
#include <linux/syscalls.h>
#include <linux/fcntl.h>
#include <linux/miscdevice.h>
#include <linux/uaccess.h>
#include "../inc/tas25xx.h"
#include "../inc/tas25xx-misc.h"
#include <linux/dma-mapping.h>
#define FMT "%02x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n"
#define MAX_FMT_COUNT 512
enum tas_devop_t {
OP_REG_READ = 0,
OP_PAGE_READ = 1,
OP_SNG_WRITE = 2,
OP_BURST_WRITE = 3,
};
struct tas_audio_dev {
uint8_t channel;
uint8_t book;
uint8_t page;
uint8_t reg;
uint8_t read_pending;
enum tas_devop_t op;
};
static struct tas_audio_dev s_tasdevop;
static uint32_t s_r[128];
static struct tas25xx_priv *g_tas25xx;
static int32_t tas25xx_file_open(struct inode *inode, struct file *file)
{
struct tas25xx_priv *p_tas25xx = g_tas25xx;
file->private_data = (void *)p_tas25xx;
pr_info("TAS25XX %s\n", __func__);
return 0;
}
static int32_t tas25xx_file_release(struct inode *inode, struct file *file)
{
pr_info("TAS25XX %s\n", __func__);
file->private_data = (void *)NULL;
return 0;
}
static ssize_t tas25xx_file_read(struct file *file,
char *buf, size_t count, loff_t *ppos)
{
struct tas25xx_priv *p_tas25xx =
(struct tas25xx_priv *)file->private_data;
int32_t ret = 0, i, count_l;
uint8_t *p_kbuf = NULL;
uint32_t reg = 0;
uint32_t len = 0;
uint32_t value = 0;
uint32_t channel = 0;
mutex_lock(&p_tas25xx->file_lock);
pr_info("%s size=%zu", __func__, count);
if (count > 8) {
uint8_t *ref_ptr;
if (!s_tasdevop.read_pending) {
count = 0;
goto done_read;
}
p_kbuf = kzalloc(MAX_FMT_COUNT, GFP_KERNEL);
if (p_kbuf == NULL)
goto done_read;
ref_ptr = p_kbuf;
channel = s_tasdevop.channel;
pr_info("%s ch=%d B:P %02x:%02x\n",
__func__, channel, s_tasdevop.book, s_tasdevop.page);
switch (s_tasdevop.op) {
case OP_REG_READ:
reg = TAS25XX_REG(s_tasdevop.book, s_tasdevop.page, s_tasdevop.reg);
ret = p_tas25xx->read(p_tas25xx, channel,
reg, &value);
if (ret < 0)
count = snprintf(ref_ptr, 64, "%s\n", "Error");
else
count = snprintf(ref_ptr, 64, "%02x\n", value);
ret = copy_to_user(buf, ref_ptr, count);
if (ret) {
pr_err("TAS25XX:%d reg read, copy to user buf ret= %d", __LINE__, ret);
count = ret;
} else {
pr_info("TAS25XX: %s ch=%d B:P:R %02x:%02x:%02x(%d) value=%d\n",
__func__, channel, s_tasdevop.book, s_tasdevop.page,
s_tasdevop.reg, reg, value);
}
break;
case OP_PAGE_READ:
reg = TAS25XX_REG(s_tasdevop.book, s_tasdevop.page, 0);
for (i = 0; i < 128; i++) {
ret = p_tas25xx->read(p_tas25xx, channel,
reg + i, &s_r[i]);
if (ret) {
memset(s_r, 0, sizeof(s_r));
break;
}
}
p_tas25xx->read(p_tas25xx, channel, reg, &s_r[0]);
if (ret) {
count = snprintf(ref_ptr, 64, "error=%d\n", ret);
} else {
count_l = 0;
if (count < ((52*8)+1)) {
count = snprintf(ref_ptr, 64,
"page dump not possible\n");
} else {
for (i = 0; i < 8; i++) {
count_l += snprintf(ref_ptr, 64, FMT, i, s_r[(i*16) + 0],
s_r[(i*16) + 1], s_r[(i*16) + 2], s_r[(i*16) + 3], s_r[(i*16) + 4],
s_r[(i*16) + 5], s_r[(i*16) + 6], s_r[(i*16) + 7], s_r[(i*16) + 8],
s_r[(i*16) + 9], s_r[(i*16) + 10], s_r[(i*16) + 11], s_r[(i*16) + 12],
s_r[(i*16) + 13], s_r[(i*16) + 14], s_r[(i*16) + 15]);
ref_ptr += 52;
}
count = count_l;
}
}
ret = copy_to_user(buf, p_kbuf, count);
if (ret) {
pr_err("TAS25XX:%s page read, copy buffer failed.\n", __func__);
count = ret;
}
break;
default:
count = snprintf(p_kbuf, 64, "%s\n", "invalid op");
ret = copy_to_user(buf, p_kbuf, count);
if (ret) {
pr_err("TAS25XX:%s invalid op, copy buffer failed.\n", __func__);
count = ret;
}
break;
}
s_tasdevop.read_pending = 0;
goto done_read;
} else if (count == 7) {
p_kbuf = kzalloc(count, GFP_KERNEL);
if (p_kbuf == NULL)
goto done_read;
ret = copy_from_user(p_kbuf, buf, count);
if (ret != 0) {
pr_err("TAS25XX copy_from_user failed.\n");
count = ret;
goto done_read;
}
if (p_kbuf[1] >= p_tas25xx->ch_count)
goto done_read;
channel = p_kbuf[1];
switch (p_kbuf[0]) {
case TIAUDIO_CMD_REG_READ:
{
reg = ((uint32_t)p_kbuf[2] << 24) +
((uint32_t)p_kbuf[3] << 16) +
((uint32_t)p_kbuf[4] << 8) +
(uint32_t)p_kbuf[5];
pr_info("TAS25XX TIAUDIO_CMD_REG_READ: current_reg = 0x%x, count=%d\n",
reg, (int)count-6);
len = count-6;
if (len == 1) {
value = 0;
ret = p_tas25xx->read(p_tas25xx, channel,
reg, &value);
if (ret < 0) {
pr_err("TAS25XX dev read fail %d\n", ret);
break;
}
p_kbuf[6] = value;
ret = copy_to_user(buf, p_kbuf, count);
if (ret) {
count = ret;
pr_err("TAS25XX TIAUDIO_CMD_REG_READ copy to user %d\n", ret);
}
} else if (len > 1) {
ret = p_tas25xx->bulk_read(p_tas25xx, channel,
reg, (uint8_t *)&p_kbuf[6], len);
if (ret < 0) {
pr_err("TAS25XX dev bulk read fail %d\n", ret);
} else {
ret = copy_to_user(buf, p_kbuf, count);
if (ret) {
count = ret;
pr_err("TAS25XX TIAUDIO_CMD_REG_READ copy to user fail %d\n",
ret);
}
}
}
}
break;
}
} else {
pr_err("TAS25XX:%d invalid size %zu", __LINE__, count);
goto done_read;
}
done_read:
kfree(p_kbuf);
mutex_unlock(&p_tas25xx->file_lock);
return count;
}
static int32_t handle_read_write(struct tas25xx_priv *p_tas25xx,
int32_t read_write_op, int32_t count, uint8_t *buf)
{
static uint8_t ch_bpr[8] = {0};
int32_t val, buf_sz, i;
int32_t ret = 0;
int32_t reg;
int8_t l_buf[3];
buf_sz = count - 2;
buf += 2;
i = 0;
l_buf[2] = 0;
while (buf_sz >= 2) {
memcpy(l_buf, buf, 2);
ret = kstrtoint(l_buf, 16, &val);
if (ret) {
pr_err("TAS25XX:%d Parsing err for %s, err=%d", __LINE__, l_buf, ret);
break;
}
if (i <= 7) {
pr_info("tas25xx: %s i=%d, val=%d\n", __func__, i, val);
ch_bpr[i] = (uint8_t)val;
} else {
pr_info("tas25xx: write supported only for 4 bytes,ignoring additional bytes\n");
break;
}
buf += 3;
buf_sz -= 3;
i++;
}
if (ret)
goto read_write_done;
pr_info("tas25xx: ch=%d, BPR %02x:%02x:%02x v=%d %d %d %d(cnt=%d)\n",
ch_bpr[0], ch_bpr[1], ch_bpr[2], ch_bpr[3],
ch_bpr[4], ch_bpr[5], ch_bpr[6], ch_bpr[7], i);
if (ch_bpr[0] >= p_tas25xx->ch_count) {
ret = -EINVAL;
goto read_write_done;
}
s_tasdevop.channel = ch_bpr[0];
s_tasdevop.book = ch_bpr[1];
s_tasdevop.page = ch_bpr[2];
s_tasdevop.reg = ch_bpr[3];
if (read_write_op == 1)
s_tasdevop.read_pending = 1;
else
s_tasdevop.read_pending = 0;
if (read_write_op == 1) {
if (i == 3) {
pr_info("tas25xx: page read\n");
s_tasdevop.op = OP_PAGE_READ;
} else if (i == 4) {
pr_info("tas25xx: single read\n");
s_tasdevop.op = OP_REG_READ;
} else {
pr_info("tas25xx: page/single read is supported\n");
s_tasdevop.read_pending = 0;
ret = -EINVAL;
}
} else if (read_write_op == 2) {
if (i == 5) {
pr_info("tas25xx: single write\n");
s_tasdevop.op = OP_SNG_WRITE;
} else if (i == 8) {
pr_info("tas25xx: burst write\n");
s_tasdevop.op = OP_BURST_WRITE;
} else {
pr_info("tas25xx: signle/burst write is supported\n");
ret = -EINVAL;
}
} else {
pr_info("tas25xx: Only read and write is supported\n");
ret = -EINVAL;
}
if (read_write_op == 2) {
val = ch_bpr[4];
reg = TAS25XX_REG(s_tasdevop.book, s_tasdevop.page, s_tasdevop.reg);
if (s_tasdevop.op == OP_SNG_WRITE) {
ret = p_tas25xx->write(p_tas25xx,
s_tasdevop.channel, reg, val);
} else if (s_tasdevop.op == OP_BURST_WRITE) {
ret = p_tas25xx->bulk_write(p_tas25xx,
s_tasdevop.channel, reg, &ch_bpr[4], 4);
}
}
read_write_done:
if (ret < 0)
count = ret;
return count;
}
static ssize_t tas25xx_file_write(struct file *file,
const char *buf, size_t count, loff_t *ppos)
{
struct tas25xx_priv *p_tas25xx =
(struct tas25xx_priv *)file->private_data;
int32_t ret = 0;
uint8_t *p_kbuf = NULL;
uint32_t reg = 0;
uint32_t len = 0;
uint32_t channel = 0;
int32_t read_write_op;
mutex_lock(&p_tas25xx->file_lock);
pr_info("%s size=%zu", __func__, count);
if (count < 7) {
pr_err("TAS25XX invalid size %zu\n", count);
ret = -EINVAL;
goto done_write;
}
p_kbuf = kzalloc(count, GFP_KERNEL);
if (p_kbuf == NULL) {
ret = -ENOMEM;
goto done_write;
}
ret = copy_from_user(p_kbuf, buf, count);
if (ret != 0) {
count = ret;
pr_err("TAS25XX copy_from_user failed.\n");
goto done_write;
}
if ((p_kbuf[0] == 'w' || p_kbuf[0] == 'W') && p_kbuf[1] == ' ')
read_write_op = 2;
else if ((p_kbuf[0] == 'r' || p_kbuf[0] == 'R') && p_kbuf[1] == ' ')
read_write_op = 1;
else
read_write_op = 0;
if (read_write_op) {
count = handle_read_write(p_tas25xx, read_write_op, count, p_kbuf);
goto done_write;
}
if (p_kbuf[1] >= p_tas25xx->ch_count) {
pr_err("TAS25XX: channel count exceeds actual chanel count\n");
goto done_write;
}
channel = p_kbuf[1];
switch (p_kbuf[0]) {
case TIAUDIO_CMD_REG_WITE:
if (count > 5) {
reg = ((uint32_t)p_kbuf[2] << 24) +
((uint32_t)p_kbuf[3] << 16) +
((uint32_t)p_kbuf[4] << 8) +
(uint32_t)p_kbuf[5];
len = count - 6;
pr_info("TAS25XX TIAUDIO_CMD_REG_WITE, Reg=0x%x, Val=0x%x\n",
reg, p_kbuf[6]);
if (len == 1) {
uint32_t value = 0;
value = p_kbuf[6];
ret = p_tas25xx->write(p_tas25xx, channel, reg,
value);
} else if (len > 1) {
ret = p_tas25xx->bulk_write(p_tas25xx, channel,
reg, &p_kbuf[6], len);
}
} else {
pr_err("TAS25XX %s, write len fail, count=%d.\n",
__func__, (int)count);
}
break;
}
done_write:
kfree(p_kbuf);
mutex_unlock(&p_tas25xx->file_lock);
return count;
}
static const struct file_operations fops = {
.owner = THIS_MODULE,
.read = tas25xx_file_read,
.write = tas25xx_file_write,
.unlocked_ioctl = NULL,
.open = tas25xx_file_open,
.release = tas25xx_file_release,
};
#define MODULE_NAME "tas_audio_dev"
static struct miscdevice tas25xx_misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = MODULE_NAME,
.fops = &fops,
};
int32_t tas25xx_register_misc(struct tas25xx_priv *p_tas25xx)
{
int32_t ret = 0;
g_tas25xx = p_tas25xx;
ret = misc_register(&tas25xx_misc);
if (ret)
pr_err("TI-SmartPA TAS25XX misc fail: %d\n", ret);
pr_info("TI-SmartPA %s, leave\n", __func__);
return ret;
}
EXPORT_SYMBOL(tas25xx_register_misc);
int32_t tas25xx_deregister_misc(struct tas25xx_priv *p_tas25xx)
{
misc_deregister(&tas25xx_misc);
g_tas25xx = NULL;
return 0;
}
EXPORT_SYMBOL(tas25xx_deregister_misc);
/*
* MODULE_AUTHOR("Texas Instruments Inc.");
* MODULE_DESCRIPTION("TAS25XX Misc Smart Amplifier driver");
* MODULE_LICENSE("GPL v2");
*/

View File

@ -1,212 +0,0 @@
/*
* ALSA SoC Texas Instruments TAS25XX High Performance 4W Smart Amplifier
*
* Copyright (C) 2022 Texas Instruments, Inc.
*
* Author: Niranjan H Y, Vijeth P O
*
* This package is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#include "../inc/tas25xx.h"
#include "../inc/tas25xx-device.h"
#include "../inc/tas25xx-regbin-parser.h"
#include "../inc/tas25xx-regmap.h"
#define TAS25XX_MDELAY 0xFFFFFFFE
#define TAS25XX_MSLEEP 0xFFFFFFFD
#define TAS25XX_IVSENSER_ENABLE 1
#define TAS25XX_IVSENSER_DISABLE 0
#define STR_RXBITS_SZ 5
#define STR_16BIT "16BIT"
#define STR_24BIT "24BIT"
#define STR_32BIT "32BIT"
#ifndef UINT64_MAX
#define UINT64_MAX ((u64)(~((u64)0)))
#endif
#ifndef UINT32_MAX
#define UINT32_MAX ((u32)(~((u32)0)))
#endif
int tas25xx_rx_set_bitwidth(struct tas25xx_priv *p_tas25xx,
int bitwidth, int ch)
{
int ret;
int32_t i;
uint32_t size, blk_count, sublk_sz;
uint8_t *rx_data = p_tas25xx->block_op_data[ch].rx_fmt_data;
uint8_t *fmt;
struct linux_platform *plat_data =
(struct linux_platform *) p_tas25xx->platform_data;
ret = 0;
size = *((uint32_t *)rx_data);
rx_data += sizeof(uint32_t);
blk_count = *((uint32_t *)rx_data);
rx_data += sizeof(uint32_t);
switch (bitwidth) {
case 16:
fmt = STR_16BIT;
break;
case 24:
fmt = STR_24BIT;
break;
case 32:
fmt = STR_32BIT;
break;
default:
fmt = NULL;
dev_info(plat_data->dev,
"Not supported params bitwidth %d",
bitwidth);
break;
}
if (!fmt)
return -EINVAL;
for (i = 0; i < blk_count; i++) {
if (memcmp(fmt, rx_data, STR_RXBITS_SZ) == 0) {
rx_data += STR_RXBITS_SZ;
break;
} else {
rx_data += STR_RXBITS_SZ;
sublk_sz = *((uint32_t *)rx_data);
rx_data += sizeof(uint32_t);
rx_data += sublk_sz;
}
}
if (i < blk_count)
ret = tas25xx_process_block(p_tas25xx, rx_data, ch);
else
ret = -EINVAL;
if (ret == 0)
p_tas25xx->mn_rx_width = bitwidth;
return ret;
}
int tas_dev_interrupt_clear(struct tas25xx_priv *p_tas25xx, int chn)
{
if (p_tas25xx->intr_data[chn].buf_intr_clear)
return tas25xx_process_block(p_tas25xx,
p_tas25xx->intr_data[chn].buf_intr_clear, chn);
return 0;
}
int tas_dev_interrupt_enable(struct tas25xx_priv *p_tas25xx, int chn)
{
p_tas25xx->devs[chn]->irq_count = 0;
if (p_tas25xx->intr_data[chn].buf_intr_enable)
return tas25xx_process_block(p_tas25xx,
p_tas25xx->intr_data[chn].buf_intr_enable, chn);
return 0;
}
int tas_dev_interrupt_disable(struct tas25xx_priv *p_tas25xx, int chn)
{
if (p_tas25xx->intr_data[chn].buf_intr_disable)
return tas25xx_process_block(p_tas25xx,
p_tas25xx->intr_data[chn].buf_intr_disable, chn);
return 0;
}
int tas_dev_interrupt_read(struct tas25xx_priv *p_tas25xx, int chn, int *type)
{
int32_t ret = 0;
int32_t i;
int32_t reg = -1;
int32_t intr_detected = 0;
uint32_t value = 0;
int32_t powered_up = 0;
struct tas25xx_intr_info *intr_info;
struct linux_platform *plat_data =
(struct linux_platform *) p_tas25xx->platform_data;
struct tas25xx_interrupts *intr_data = &p_tas25xx->intr_data[chn];
powered_up = is_power_up_state(p_tas25xx->m_power_state);
for (i = 0; i < intr_data->count; i++) {
intr_info = &intr_data->intr_info[i];
if (!powered_up && intr_info->is_clock_based) {
/* ignore clock based interrupt during power off state */
dev_dbg(plat_data->dev,
"INTR: not checking for %s, reason: not active state",
intr_info->name);
continue;
}
if ((reg != intr_info->reg) || ret) {
reg = intr_info->reg;
ret = p_tas25xx->read(p_tas25xx, chn, reg, &value);
if (!ret)
dev_err(plat_data->dev,
"INTR: ch=%d reg=0x%2x(%d), value=0x%2x(%d)",
chn, reg, reg, value, value);
} else {
dev_dbg(plat_data->dev, "INTR: skipping reading reg = %d",
intr_info->reg);
}
if (ret) {
dev_err(plat_data->dev,
"INTR: Error reading the interrupt reg=%d, err=%d", reg, ret);
} else {
if (value & intr_info->mask) {
if (powered_up && intr_info->is_clock_based)
*type |= INTERRUPT_TYPE_CLOCK_BASED;
else
*type |= INTERRUPT_TYPE_NON_CLOCK_BASED;
dev_err(plat_data->dev, "INTR: Detected, ch=%d, intr=%s",
chn, intr_info->name);
intr_info->detected = 1;
if (intr_info->count < UINT32_MAX)
intr_info->count++;
if (intr_info->count_persist < UINT64_MAX)
intr_info->count_persist++;
intr_detected |= 1;
}
}
}
return intr_detected;
}
int tas25xx_set_power_mute(struct tas25xx_priv *p_tas25xx, int ch)
{
return tas25xx_process_block(p_tas25xx,
p_tas25xx->block_op_data[ch].mute, ch);
}
int tas25xx_software_reset(struct tas25xx_priv *p_tas25xx, int ch)
{
int ret;
ret = tas25xx_process_block(p_tas25xx,
p_tas25xx->block_op_data[ch].sw_reset, ch);
p_tas25xx->devs[ch]->mn_current_book = -1;
usleep_range(10000, 10100);
return ret;
}

View File

@ -403,11 +403,6 @@ int msm_common_snd_hw_params(struct snd_pcm_substream *substream,
struct msm_common_pdata *pdata = msm_common_get_pdata(card);
int index = get_mi2s_tdm_auxpcm_intf_index(stream_name);
struct clk_cfg intf_clk_cfg;
#ifdef CONFIG_COMMON_AMP_CIRRUS
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
unsigned int num_codecs = rtd->dai_link->num_codecs;
int i;
#endif
dev_dbg(rtd->card->dev,
"%s: substream = %s stream = %d\n",
@ -452,28 +447,6 @@ int msm_common_snd_hw_params(struct snd_pcm_substream *substream,
__func__, ret);
goto done;
}
#ifdef CONFIG_COMMON_AMP_CIRRUS
for (i = 0; i < num_codecs; i++) {
codec_dai = asoc_rtd_to_codec(rtd, i);
ret = snd_soc_dai_set_sysclk(codec_dai, 0,
intf_clk_cfg.clk_freq_in_hz, SND_SOC_CLOCK_IN);
if (ret < 0)
pr_err("%s: failed to set codec tdm clk, err:%d\n",
__func__, ret);
ret = snd_soc_component_set_sysclk(codec_dai->component,
CLK_SRC_SCLK, 0, intf_clk_cfg.clk_freq_in_hz, SND_SOC_CLOCK_IN);
if (ret < 0)
pr_err("%s: failed to set component sys clk, err:%d\n",
__func__, ret);
ret = snd_soc_dai_set_tdm_slot(codec_dai, 0, 0, 0, 32);
if (ret < 0)
pr_err("%s: failed to set tdm slot, err:%d\n",
__func__, ret);
}
#endif
} else if ((strnstr(stream_name, "MI2S", strlen(stream_name)))) {
ret = get_mi2s_clk_id(index);

View File

@ -9,25 +9,6 @@
#include <sound/soc.h>
#include <sound/pcm.h>
#ifdef CONFIG_COMMON_AMP_CIRRUS
#define CLK_SRC_SCLK 0
#define CLK_SRC_LRCLK 1
#define CLK_SRC_PDM 2
#define CLK_SRC_SELF 3
#define CLK_SRC_MCLK 4
#define CLK_SRC_SWIRE 5
#define CLK_SRC_DAI 0
#define CLK_SRC_CODEC 1
#define CS35L43_MONO 0x31
#define CS35L43_STEREO 0x32
#define CS35L43_QUAD 0x34
#define CS35L45_MONO 0x51
#define CS35L45_STEREO 0x52
#define CS35L45_QUAD 0x54
#endif
enum {
MI2S = 0,
TDM,

View File

@ -262,11 +262,7 @@ SND_SOC_DAILINK_DEFS(pri_mi2s_tx,
SND_SOC_DAILINK_DEFS(sec_mi2s_rx,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
#ifdef CONFIG_USE_CS40L26
DAILINK_COMP_ARRAY(COMP_CODEC("cs40l26-codec", "cs40l26-pcm")),
#else
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
#endif
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
SND_SOC_DAILINK_DEFS(sec_mi2s_tx,
@ -646,33 +642,3 @@ SND_SOC_DAILINK_DEFS(hs_if4_tdm_tx_0_dummy,
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
#ifdef CONFIG_COMMON_AMP_CIRRUS
SND_SOC_DAILINK_DEFS(cirrus_pri_tdm_rx_0,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_DUMMY(),
COMP_DUMMY(),
COMP_DUMMY(),
COMP_DUMMY()),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
SND_SOC_DAILINK_DEFS(cirrus_pri_tdm_tx_0,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_DUMMY(),
COMP_DUMMY(),
COMP_DUMMY(),
COMP_DUMMY()),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
#endif
#ifdef CONFIG_SND_SOC_TAS25XX
SND_SOC_DAILINK_DEFS(tas25xx_pri_tdm_rx_0,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(
COMP_CODEC("tas25xx.18-0048", "tas25xx ASI1")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
SND_SOC_DAILINK_DEFS(tas25xx_pri_tdm_tx_0,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(
COMP_CODEC("tas25xx.18-0048", "tas25xx ASI1")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
#endif

File diff suppressed because it is too large Load Diff

View File

@ -75,9 +75,6 @@ ifeq ($(call is-board-platform-in-list, holi blair), true)
AUDIO_KERNEL_MODULES += $(KERNEL_MODULES_OUT)/wcd938x_dlkm.ko \
$(KERNEL_MODULES_OUT)/wcd938x_slave_dlkm.ko
endif
ifeq ($(PROJECT_NAME),$(filter $(PROJECT_NAME),q6q b6q q6aq))
AUDIO_KERNEL_MODULES += $(KERNEL_MODULES_OUT)/tas25xx_dlkm.ko
endif
endif
else
ifeq ($(call is-board-platform-in-list, gen4 msmnile), true)

View File

@ -60,9 +60,7 @@ ifeq ($(call is-board-platform-in-list, holi blair), true)
PRODUCT_PACKAGES += $(KERNEL_MODULES_OUT)/wcd938x_dlkm.ko \
$(KERNEL_MODULES_OUT)/wcd938x_slave_dlkm.ko
endif
ifeq ($(PROJECT_NAME),$(filter $(PROJECT_NAME),q6q b6q q6aq))
PRODUCT_PACKAGES += $(KERNEL_MODULES_OUT)/tas25xx_dlkm.ko
endif
ifeq ($(call is-board-platform-in-list, gen4 msmnile), true)
ifneq (,$(filter $(TARGET_BOARD_PLATFORM)$(TARGET_BOARD_SUFFIX), gen4_gvm msmnile_gvmq))
PRODUCT_PACKAGES += $(KERNEL_MODULES_OUT)/machine_dlkm.ko \

View File

@ -19,17 +19,12 @@
#include <linux/slab.h>
#include <linux/remoteproc.h>
#include <linux/remoteproc/qcom_rproc.h>
#if IS_ENABLED(CONFIG_SND_SOC_SAMSUNG_AUDIO)
#include <sound/samsung/snd_debug_proc.h>
#endif
#define Q6_PIL_GET_DELAY_MS 100
#define BOOT_CMD 1
#define SSR_RESET_CMD 1
#define IMAGE_UNLOAD_CMD 0
#if IS_ENABLED(CONFIG_SEC_SENSORS_SSC)
#define SUB_SNS_VDD_CHECK_CMD 0
#endif
#define MAX_FW_IMAGES 4
#define ADSP_LOADER_APM_TIMEOUT_MS 10000
@ -48,12 +43,6 @@ static ssize_t adsp_ssr_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count);
#if IS_ENABLED(CONFIG_SEC_SENSORS_SSC)
static ssize_t adsp_check_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count);
#endif
struct adsp_loader_private {
void *pil_h;
struct kobject *boot_adsp_obj;
@ -68,17 +57,9 @@ static struct kobj_attribute adsp_boot_attribute =
static struct kobj_attribute adsp_ssr_attribute =
__ATTR(ssr, 0220, NULL, adsp_ssr_store);
#if IS_ENABLED(CONFIG_SEC_SENSORS_SSC)
static struct kobj_attribute adsp_check_attribute =
__ATTR(check, 0220, NULL, adsp_check_store);
#endif
static struct attribute *attrs[] = {
&adsp_boot_attribute.attr,
&adsp_ssr_attribute.attr,
#if IS_ENABLED(CONFIG_SEC_SENSORS_SSC)
&adsp_check_attribute.attr,
#endif
NULL,
};
@ -191,10 +172,6 @@ load_adsp:
if (rc) {
dev_err(&pdev->dev, "%s: pil get failed,\n",
__func__);
#if IS_ENABLED(CONFIG_SND_SOC_SAMSUNG_AUDIO)
sdp_boot_print("%s: ADSP loadig is failed = %d\n",
__func__, rc);
#endif
goto fail;
}
} else if (adsp_state == SPF_SUBSYS_LOADED) {
@ -272,36 +249,6 @@ static ssize_t adsp_boot_store(struct kobject *kobj,
return count;
}
#if IS_ENABLED(CONFIG_SEC_SENSORS_SSC)
static ssize_t adsp_check_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf,
size_t count)
{
int check_command = 0;
if (kstrtoint(buf, 10, &check_command) < 0)
return -EINVAL;
if (check_command == SUB_SNS_VDD_CHECK_CMD) {
struct platform_device *pdev = adsp_private;
struct adsp_loader_private *priv = NULL;
struct rproc *adsp_rproc = NULL;
priv = platform_get_drvdata(pdev);
if (priv) {
adsp_rproc = (struct rproc *)priv->pil_h;
if (adsp_rproc) {
pr_info("check subsensor vdd\n");
adsp_init_subsensor_regulator(adsp_rproc,
NULL);
}
}
}
return count;
}
#endif
static void adsp_loader_unload(struct platform_device *pdev)
{
struct adsp_loader_private *priv = NULL;