Skip to contentSkip to conversation

ALSA SoC: Texas Instruments TAS2781 Audio Smart Amp

PATCH In review Kevin Lu 2 participants 2 messages Dec 20, 2022

Subsystems (3)
lore
Share & tools
lore

Kevin Lu

author
#0 lore raw

PATCH 1/1 ALSA SoC: Texas Instruments TAS2781 Audio Smart Amp

The TAS2781 driver implements a flexible and configurable register setting for one, two, even multiple TAS2781 chips. All the register setting are in a bin file. Almost no specific register setting can be found in the code.

---
 sound/soc/codecs/Kconfig       |   13 +
 sound/soc/codecs/Makefile      |    2 +
 sound/soc/codecs/tas2781-dsp.c | 2483 ++++++++++++++++++++++++++++++++
 sound/soc/codecs/tas2781-dsp.h |  213 +++
 sound/soc/codecs/tas2781-i2c.c | 2143 +++++++++++++++++++++++++++
 sound/soc/codecs/tas2781.h     |  208 +++
 6 files changed, 5062 insertions(+)
 create mode 100644 sound/soc/codecs/tas2781-dsp.c
 create mode 100644 sound/soc/codecs/tas2781-dsp.h
 create mode 100644 sound/soc/codecs/tas2781-i2c.c
 create mode 100644 sound/soc/codecs/tas2781.h
sound/soc/codecs/Kconfig +13 -0
index 7022e6286..31d2d9594 100644
@@ -222,6 +222,7 @@ config SND_SOC_ALL_CODECS
 	imply SND_SOC_TAS2764
 	imply SND_SOC_TAS2770
 	imply SND_SOC_TAS2780
+	imply SND_SOC_TAS2781
 	imply SND_SOC_TAS5086
 	imply SND_SOC_TAS571X
 	imply SND_SOC_TAS5720
@@ -1573,6 +1574,18 @@ config SND_SOC_TAS2780
 	  Enable support for Texas Instruments TAS2780 high-efficiency
 	  digital input mono Class-D audio power amplifiers.
 
+config SND_SOC_TAS2781
+	tristate "Texas Instruments TAS2781 speaker amplifier"
+	depends on I2C
+	select REGMAP_I2C
+	help
+	  Enable support for Texas Instruments TAS2781 Smart Amplifier
+	  Digital input mono Class-D and DSP-inside audio power amplifiers.
+	  Note the TAS2781 driver implements a flexible and configurable
+	  register setting, for one, two, even multiple TAS2781 chips.
+	  All the register setting are in a bin file. Almost no specific
+	  register setting can be found in the code.
+
 config SND_SOC_TAS5086
 	tristate "Texas Instruments TAS5086 speaker amplifier"
 	depends on I2C
sound/soc/codecs/Makefile +2 -0
index 9170ee144..088fed9e7 100644
@@ -354,6 +354,7 @@ snd-soc-tas2552-objs := tas2552.o
 snd-soc-tas2562-objs := tas2562.o
 snd-soc-tas2764-objs := tas2764.o
 snd-soc-tas2780-objs := tas2780.o
+snd-soc-tas2781-objs :=	tas2781-i2c.o tas2781-dsp.o
 # Mux
 snd-soc-simple-mux-objs := simple-mux.o
 
@@ -604,6 +605,7 @@ obj-$(CONFIG_SND_SOC_TAS2552)	+= snd-soc-tas2552.o
 obj-$(CONFIG_SND_SOC_TAS2562)	+= snd-soc-tas2562.o
 obj-$(CONFIG_SND_SOC_TAS2764)	+= snd-soc-tas2764.o
 obj-$(CONFIG_SND_SOC_TAS2780)	+= snd-soc-tas2780.o
+obj-$(CONFIG_SND_SOC_TAS2781)	+= snd-soc-tas2781.o
 obj-$(CONFIG_SND_SOC_TAS5086)	+= snd-soc-tas5086.o
 obj-$(CONFIG_SND_SOC_TAS571X)	+= snd-soc-tas571x.o
 obj-$(CONFIG_SND_SOC_TAS5720)	+= snd-soc-tas5720.o
sound/soc/codecs/tas2781-dsp.c new file +2483 -0

2,483 lines not on this page · raw message

sound/soc/codecs/tas2781-dsp.h new file +213 -0

213 lines not on this page · raw message

sound/soc/codecs/tas2781-i2c.c new file +2143 -0

265 lines not on this page · raw message

sound/soc/codecs/tas2781.h new file +208 -0

208 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Signature · 1 line
2.17.1

Part of the diff is not shown here. View the raw message.

#1 lore raw
Quoted 5 lines · Kevin Lu

The TAS2781 driver implements a flexible and configurable register setting for one, two, even multiple TAS2781 chips. All the register setting are in a bin file. Almost no specific register setting can be found in the code.

Quoted 12 lines
---
 sound/soc/codecs/Kconfig       |   13 +
 sound/soc/codecs/Makefile      |    2 +
 sound/soc/codecs/tas2781-dsp.c | 2483 ++++++++++++++++++++++++++++++++
 sound/soc/codecs/tas2781-dsp.h |  213 +++
 sound/soc/codecs/tas2781-i2c.c | 2143 +++++++++++++++++++++++++++
 sound/soc/codecs/tas2781.h     |  208 +++
 6 files changed, 5062 insertions(+)
 create mode 100644 sound/soc/codecs/tas2781-dsp.c
 create mode 100644 sound/soc/codecs/tas2781-dsp.h
 create mode 100644 sound/soc/codecs/tas2781-i2c.c
 create mode 100644 sound/soc/codecs/tas2781.h

Your threading and patch formatting is broken. Read before sending patches:
https://elixir.bootlin.com/linux/v5.19-rc5/source/Documentation/process/submitting-patches.rst

Quoted 17 lines
sound/soc/codecs/Kconfig +1 -0
index 7022e6286..31d2d9594 100644
@@ -222,6 +222,7 @@ config SND_SOC_ALL_CODECS
 	imply SND_SOC_TAS2764
 	imply SND_SOC_TAS2770
 	imply SND_SOC_TAS2780
+	imply SND_SOC_TAS2781
 	imply SND_SOC_TAS5086
 	imply SND_SOC_TAS571X
 	imply SND_SOC_TAS5720
@@ -1573,6 +1574,18 @@ config SND_SOC_TAS2780
 	  Enable support for Texas Instruments TAS2780 high-efficiency
 	  digital input mono Class-D audio power amplifiers.
 

(...)

Quoted 35 lines
sound/soc/codecs/Kconfig +18 -0
+static struct i2c_driver tasdevice_i2c_driver = {
+	.driver = {
+		.name = "tas2781-codec",
+		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(tasdevice_of_match),
+		.pm = &tasdevice_pm_ops,
+	},
+	.probe	= tasdevice_i2c_probe,
+	.remove = tasdevice_i2c_remove,
+	.id_table = tasdevice_id,
+};
+
+module_i2c_driver(tasdevice_i2c_driver);
+
+MODULE_AUTHOR("Shenghao Ding <[email protected]>");
+MODULE_AUTHOR("Kevin Lu <[email protected]>");
+MODULE_DESCRIPTION("ASoC TAS2781 Driver");
+MODULE_LICENSE("GPL");
sound/soc/codecs/tas2781.h new file +11 -0
new file mode 100644
index 000000000..db4ec752b
@@ -0,0 +1,208 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * ALSA SoC Texas Instruments TAS2781 Audio Smart Amplifier
+ *
+ * Copyright (C) 2022 - 2023 Texas Instruments Incorporated
+ * https://www.ti.com
+ *
+ * The TAS2781 driver implements a flexible and configurable register setting
+ * for one, two, even multiple TAS2781 chips. All the register setting are in
+ * a bin file. Almost no specific register setting can be found in the code.
+ *

sound/soc/codecs/tas2781.h line 21

Quoted 10 lines
sound/soc/codecs/tas2781.h new file +10 -0
+ * Author: Shenghao Ding <[email protected]>
+ *         Kevin Lu <[email protected]>
+ */
+
+#ifndef __TAS2781_H__
+#define __TAS2781_H__
+
+#include "tas2781-dsp.h"
+
+#define SMARTAMP_MODULE_NAME	("tas2781")

This does not belong to headers.

sound/soc/codecs/tas2781.h line 22

Quoted 1 line
sound/soc/codecs/tas2781.h new file +1 -0
+#define MAX_LENGTH				(128)

Why () ?

Quoted 4 lines
sound/soc/codecs/tas2781.h new file +4 -0
+
+#define TASDEVICE_RETRY_COUNT	(3)
+#define TASDEVICE_ERROR_FAILED	(-2)
+

sound/soc/codecs/tas2781.h line 36

Quoted 10 lines
sound/soc/codecs/tas2781.h new file +10 -0
+#define TASDEVICE_RATES	(SNDRV_PCM_RATE_44100 |\
+	SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |\
+	SNDRV_PCM_RATE_88200)
+#define TASDEVICE_MAX_CHANNELS (8)
+
+#define TASDEVICE_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | \
+	SNDRV_PCM_FMTBIT_S24_LE | \
+	SNDRV_PCM_FMTBIT_S32_LE)
+
+/*PAGE Control Register (available in page0 of each book) */

Missing space

sound/soc/codecs/tas2781.h line 46

Quoted 10 lines
sound/soc/codecs/tas2781.h new file +10 -0
+#define TASDEVICE_PAGE_SELECT	(0x00)
+#define TASDEVICE_BOOKCTL_PAGE	(0x00)
+#define TASDEVICE_BOOKCTL_REG	(127)
+#define TASDEVICE_BOOK_ID(reg)		(reg / (256 * 128))
+#define TASDEVICE_PAGE_ID(reg)		((reg % (256 * 128)) / 128)
+#define TASDEVICE_PAGE_REG(reg)		((reg % (256 * 128)) % 128)
+#define TASDEVICE_REG(book, page, reg)	(((book * 256 * 128) + \
+					(page * 128)) + reg)
+
+	/*Software Reset */

Wrong coding style.

sound/soc/codecs/tas2781.h line 50

Quoted 4 lines
sound/soc/codecs/tas2781.h new file +4 -0
+#define TAS2871_REG_SWRESET  TASDEVICE_REG(0x0, 0X0, 0x02)
+#define TAS2871_REG_SWRESET_RESET  (0x1 << 0)
+
+	/* Enable Global addresses */

Wrong coding style.

Quoted 126 lines
sound/soc/codecs/tas2781.h new file +126 -0
+#define TAS2871_MISC_CFG2  TASDEVICE_REG(0x0, 0X0, 0x07)
+#define TAS2871_GLOBAL_MASK (0x1 << 1)
+
+#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))
+
+	/*I2C Checksum */
+#define TASDEVICE_I2CChecksum  TASDEVICE_REG(0x0, 0x0, 0x7E)
+
+	/* Volume control */
+#define TAS2781_DVC_LVL TASDEVICE_REG(0x0, 0x0, 0x1A)
+#define TAS2781_AMP_LEVEL TASDEVICE_REG(0x0, 0x0, 0x03)
+#define TAS2781_AMP_LEVEL_MASK GENMASK(5, 1)
+
+#define TASDEVICE_CMD_SING_W  (0x1)
+#define TASDEVICE_CMD_BURST  (0x2)
+#define TASDEVICE_CMD_DELAY  (0x3)
+#define TASDEVICE_CMD_FIELD_W  (0x4)
+
+enum audio_device {
+	GENERAL_AUDEV = 0,
+	TAS2781	  = 1,
+};
+
+struct smartpa_gpio_info {
+	unsigned char ndev;
+	int mnResetGpio[MaxChn];
+};
+
+#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))
+
+struct Tbookpage {
+	unsigned char mnBook;
+	unsigned char mnPage;
+};
+
+struct Ttasdevice {
+	unsigned int mnDevAddr;
+	unsigned int mnErrCode;
+	short mnCurrentProgram;
+	short mnCurrentConfiguration;
+	short mnCurrentRegConf;
+	int mnIRQGPIO;
+	int mnResetGpio;
+	int mn_irq;
+	int PowerStatus;
+	bool bDSPBypass;
+	bool bIrq_enabled;
+	bool bLoading;
+	bool bLoaderr;
+	bool mbCalibrationLoaded;
+	struct Tbookpage mnBkPg;
+	struct TFirmware *mpCalFirmware;
+};
+
+struct global_addr {
+	struct Tbookpage mnBkPg;
+	unsigned int mnDevAddr;
+	int ref_cnt;
+};
+
+struct tas_control {
+	struct snd_kcontrol_new *tasdevice_profile_controls;
+	int nr_controls;
+};
+
+struct tasdevice_irqinfo {
+	int mn_irq_gpio;
+	int mn_irq;
+	struct delayed_work irq_work;
+	bool mb_irq_enable;
+};
+
+struct tasdevice_priv {
+	struct device *dev;
+	void *client;
+	struct regmap *regmap;
+	struct mutex codec_lock;
+	struct mutex dev_lock;
+	struct Ttasdevice tasdevice[MaxChn];
+	struct TFirmware *mpFirmware;
+	struct tasdevice_regbin mtRegbin;
+	struct smartpa_gpio_info mtRstGPIOs;
+	struct tasdevice_irqinfo mIrqInfo;
+	struct tas_control tas_ctrl;
+	struct global_addr glb_addr;
+	int mnCurrentProgram;
+	int mnCurrentConfiguration;
+	unsigned int chip_id;
+	int (*read)(struct tasdevice_priv *tas_dev, enum channel chn,
+		unsigned int reg, unsigned int *pValue);
+	int (*write)(struct tasdevice_priv *tas_dev, enum channel chn,
+		unsigned int reg, unsigned int Value);
+	int (*bulk_read)(struct tasdevice_priv *tas_dev, enum channel chn,
+		unsigned int reg, unsigned char *pData, unsigned int len);
+	int (*bulk_write)(struct tasdevice_priv *tas_dev, enum channel chn,
+		unsigned int reg, unsigned char *pData, unsigned int len);
+	int (*set_calibration)(void *tas_dev, enum channel chl,
+		int calibration);
+	void (*tas2781_reset)(struct tasdevice_priv *tas_dev);
+	void (*tas2781_set_global)(struct tasdevice_priv *tas_dev);
+	int (*fw_parse_variable_header)(struct tasdevice_priv *tas_dev,
+		const struct firmware *pFW, int offset);
+	int (*fw_parse_program_data)(struct tasdevice_priv *tas_dev,
+		struct TFirmware *pFirmware,
+		const struct firmware *pFW, int offset);
+	int (*fw_parse_configuration_data)(struct tasdevice_priv *tas_dev,
+		struct TFirmware *pFirmware,
+		const struct firmware *pFW, int offset);
+	int (*tasdevice_load_block)(struct tasdevice_priv *tas_dev,
+		struct TBlock *pBlock);
+	int (*fw_parse_calibration_data)(struct tasdevice_priv *tas_dev,
+		struct TFirmware *pFirmware,
+		const struct firmware *pFW, int offset);
+	void (*irq_work_func)(struct tasdevice_priv *tas_dev);
+	int fw_state;
+	unsigned int magic_num;
+	unsigned char ndev;
+	unsigned char dev_name[32];

sound/soc/codecs/tas2781.h line 186

Quoted 10 lines
sound/soc/codecs/tas2781.h new file +10 -0
+	unsigned char regbin_binaryname[64];
+	unsigned char dsp_binaryname[64];
+	unsigned char cal_binaryname[MaxChn][64];
+	bool mb_runtime_suspend;
+	struct delayed_work powercontrol_work;
+	void *codec;
+	int sysclk;
+	int pstream;
+	int cstream;
+	bool mbCalibrationLoaded;

You need to adjust your coding style to Linux. This is some C++ crap.

Best regards,
Krzysztof