Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ASoc: tas2783A: Add soundwire based codec driver

TAS2783 is mono digital input class-D Smart Amplifier
based on MIPI Alliance Soundwire interface. The driver
supports loading the algorithm coefficients for one
or more tas2783 chips.

Signed-off-by: Niranjan H Y <niranjan.hy@ti.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Link: https://patch.msgid.link/20250912083624.804-2-niranjan.hy@ti.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Niranjan H Y and committed by
Mark Brown
4cc9bd8d a0ce874c

+1457
+14
sound/soc/codecs/Kconfig
··· 268 268 imply SND_SOC_TAS2770 269 269 imply SND_SOC_TAS2780 270 270 imply SND_SOC_TAS2781_I2C 271 + imply SND_SOC_TAS2783_SDW 271 272 imply SND_SOC_TAS5086 272 273 imply SND_SOC_TAS571X 273 274 imply SND_SOC_TAS5720 ··· 2097 2096 Note the TAS2781 driver implements a flexible and configurable 2098 2097 algo coefficient setting, for one, two or even multiple TAS2781 2099 2098 chips. 2099 + 2100 + config SND_SOC_TAS2783_SDW 2101 + tristate "Texas Instruments TAS2783 speaker amplifier (sdw)" 2102 + depends on SOUNDWIRE 2103 + depends on EFI 2104 + select REGMAP_SOUNDWIRE 2105 + select REGMAP_SOUNDWIRE_MBQ 2106 + select CRC32 2107 + help 2108 + Enable support for Texas Instruments TAS2783A Digital input 2109 + mono Class-D and DSP-inside audio power amplifiers. TAS2783 2110 + driver implements a flexible and configurable algorithm 2111 + cofficient setting, for one, two or multiple TAS2783 chips. 2100 2112 2101 2113 config SND_SOC_TAS5086 2102 2114 tristate "Texas Instruments TAS5086 speaker amplifier"
+2
sound/soc/codecs/Makefile
··· 319 319 snd-soc-tas2781-comlib-i2c-y := tas2781-comlib-i2c.o 320 320 snd-soc-tas2781-fmwlib-y := tas2781-fmwlib.o 321 321 snd-soc-tas2781-i2c-y := tas2781-i2c.o 322 + snd-soc-tas2783-sdw-y := tas2783-sdw.o 322 323 snd-soc-tfa9879-y := tfa9879.o 323 324 snd-soc-tfa989x-y := tfa989x.o 324 325 snd-soc-tlv320adc3xxx-y := tlv320adc3xxx.o ··· 744 743 obj-$(CONFIG_SND_SOC_TAS2781_COMLIB_I2C) += snd-soc-tas2781-comlib-i2c.o 745 744 obj-$(CONFIG_SND_SOC_TAS2781_FMWLIB) += snd-soc-tas2781-fmwlib.o 746 745 obj-$(CONFIG_SND_SOC_TAS2781_I2C) += snd-soc-tas2781-i2c.o 746 + obj-$(CONFIG_SND_SOC_TAS2783_SDW) += snd-soc-tas2783-sdw.o 747 747 obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o 748 748 obj-$(CONFIG_SND_SOC_TAS571X) += snd-soc-tas571x.o 749 749 obj-$(CONFIG_SND_SOC_TAS5720) += snd-soc-tas5720.o
+1331
sound/soc/codecs/tas2783-sdw.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // ALSA SoC Texas Instruments TAS2783 Audio Smart Amplifier 4 + // 5 + // Copyright (C) 2025 Texas Instruments Incorporated 6 + // https://www.ti.com 7 + // 8 + // The TAS2783 driver implements a flexible and configurable 9 + // algo coefficient setting for single TAS2783 chips. 10 + // 11 + // Author: Niranjan H Y <niranjanhy@ti.com> 12 + // Author: Baojun Xu <baojun.xu@ti.com> 13 + // Author: Kevin Lu <kevin-lu@ti.com> 14 + 15 + #include <linux/unaligned.h> 16 + #include <linux/crc32.h> 17 + #include <linux/efi.h> 18 + #include <linux/err.h> 19 + #include <linux/firmware.h> 20 + #include <linux/init.h> 21 + #include <linux/module.h> 22 + #include <sound/pcm_params.h> 23 + #include <linux/pm.h> 24 + #include <linux/pm_runtime.h> 25 + #include <linux/regmap.h> 26 + #include <linux/wait.h> 27 + #include <linux/soundwire/sdw.h> 28 + #include <linux/soundwire/sdw_registers.h> 29 + #include <linux/soundwire/sdw_type.h> 30 + #include <sound/sdw.h> 31 + #include <sound/soc.h> 32 + #include <sound/tlv.h> 33 + #include <sound/tas2781-tlv.h> 34 + 35 + #include "tas2783.h" 36 + 37 + #define TIMEOUT_FW_DL_MS (3000) 38 + #define FW_DL_OFFSET 36 39 + #define FW_FL_HDR 12 40 + #define TAS2783_PROBE_TIMEOUT 5000 41 + #define TAS2783_CALI_GUID EFI_GUID(0x1f52d2a1, 0xbb3a, 0x457d, 0xbc, \ 42 + 0x09, 0x43, 0xa3, 0xf4, 0x31, 0x0a, 0x92) 43 + 44 + static const u32 tas2783_cali_reg[] = { 45 + TAS2783_CAL_R0, 46 + TAS2783_CAL_INVR0, 47 + TAS2783_CAL_R0LOW, 48 + TAS2783_CAL_POWER, 49 + TAS2783_CAL_TLIM, 50 + }; 51 + 52 + struct bin_header_t { 53 + u16 vendor_id; 54 + u16 version; 55 + u32 file_id; 56 + u32 length; 57 + }; 58 + 59 + struct calibration_data { 60 + u32 is_valid; 61 + unsigned long read_sz; 62 + u8 data[TAS2783_CALIB_DATA_SZ]; 63 + }; 64 + 65 + struct tas2783_prv { 66 + struct snd_soc_component *component; 67 + struct calibration_data cali_data; 68 + struct sdw_slave *sdw_peripheral; 69 + enum sdw_slave_status status; 70 + /* calibration */ 71 + struct mutex calib_lock; 72 + /* pde and firmware download */ 73 + struct mutex pde_lock; 74 + struct regmap *regmap; 75 + struct device *dev; 76 + struct class *class; 77 + struct attribute_group *cal_attr_groups; 78 + struct tm tm; 79 + u8 rca_binaryname[64]; 80 + u8 dev_name[32]; 81 + bool hw_init; 82 + /* wq for firmware download */ 83 + wait_queue_head_t fw_wait; 84 + bool fw_dl_task_done; 85 + bool fw_dl_success; 86 + }; 87 + 88 + static const struct reg_default tas2783_reg_default[] = { 89 + {TAS2783_AMP_LEVEL, 0x28}, 90 + {TASDEV_REG_SDW(0, 0, 0x03), 0x28}, 91 + {TASDEV_REG_SDW(0, 0, 0x04), 0x21}, 92 + {TASDEV_REG_SDW(0, 0, 0x05), 0x41}, 93 + {TASDEV_REG_SDW(0, 0, 0x06), 0x00}, 94 + {TASDEV_REG_SDW(0, 0, 0x07), 0x20}, 95 + {TASDEV_REG_SDW(0, 0, 0x08), 0x09}, 96 + {TASDEV_REG_SDW(0, 0, 0x09), 0x02}, 97 + {TASDEV_REG_SDW(0, 0, 0x0a), 0x0a}, 98 + {TASDEV_REG_SDW(0, 0, 0x0c), 0x10}, 99 + {TASDEV_REG_SDW(0, 0, 0x0d), 0x13}, 100 + {TASDEV_REG_SDW(0, 0, 0x0e), 0xc2}, 101 + {TASDEV_REG_SDW(0, 0, 0x0f), 0x40}, 102 + {TASDEV_REG_SDW(0, 0, 0x10), 0x04}, 103 + {TASDEV_REG_SDW(0, 0, 0x13), 0x13}, 104 + {TASDEV_REG_SDW(0, 0, 0x14), 0x12}, 105 + {TASDEV_REG_SDW(0, 0, 0x15), 0x00}, 106 + {TASDEV_REG_SDW(0, 0, 0x16), 0x12}, 107 + {TASDEV_REG_SDW(0, 0, 0x17), 0x80}, 108 + {TAS2783_DVC_LVL, 0x00}, 109 + {TASDEV_REG_SDW(0, 0, 0x1b), 0x61}, 110 + {TASDEV_REG_SDW(0, 0, 0x1c), 0x36}, 111 + {TASDEV_REG_SDW(0, 0, 0x1d), 0x00}, 112 + {TASDEV_REG_SDW(0, 0, 0x1f), 0x01}, 113 + {TASDEV_REG_SDW(0, 0, 0x20), 0x2e}, 114 + {TASDEV_REG_SDW(0, 0, 0x21), 0x00}, 115 + {TASDEV_REG_SDW(0, 0, 0x34), 0x06}, 116 + {TASDEV_REG_SDW(0, 0, 0x35), 0xbd}, 117 + {TASDEV_REG_SDW(0, 0, 0x36), 0xad}, 118 + {TASDEV_REG_SDW(0, 0, 0x37), 0xa8}, 119 + {TASDEV_REG_SDW(0, 0, 0x38), 0x00}, 120 + {TASDEV_REG_SDW(0, 0, 0x3b), 0xfc}, 121 + {TASDEV_REG_SDW(0, 0, 0x3d), 0xdd}, 122 + {TASDEV_REG_SDW(0, 0, 0x40), 0xf6}, 123 + {TASDEV_REG_SDW(0, 0, 0x41), 0x14}, 124 + {TASDEV_REG_SDW(0, 0, 0x5c), 0x19}, 125 + {TASDEV_REG_SDW(0, 0, 0x5d), 0x80}, 126 + {TASDEV_REG_SDW(0, 0, 0x63), 0x48}, 127 + {TASDEV_REG_SDW(0, 0, 0x65), 0x08}, 128 + {TASDEV_REG_SDW(0, 0, 0x66), 0xb2}, 129 + {TASDEV_REG_SDW(0, 0, 0x67), 0x00}, 130 + {TASDEV_REG_SDW(0, 0, 0x6a), 0x12}, 131 + {TASDEV_REG_SDW(0, 0, 0x6b), 0xfb}, 132 + {TASDEV_REG_SDW(0, 0, 0x6c), 0x00}, 133 + {TASDEV_REG_SDW(0, 0, 0x6d), 0x00}, 134 + {TASDEV_REG_SDW(0, 0, 0x6e), 0x1a}, 135 + {TASDEV_REG_SDW(0, 0, 0x6f), 0x00}, 136 + {TASDEV_REG_SDW(0, 0, 0x70), 0x96}, 137 + {TASDEV_REG_SDW(0, 0, 0x71), 0x02}, 138 + {TASDEV_REG_SDW(0, 0, 0x73), 0x08}, 139 + {TASDEV_REG_SDW(0, 0, 0x75), 0xe0}, 140 + {TASDEV_REG_SDW(0, 0, 0x7a), 0x60}, 141 + {TASDEV_REG_SDW(0, 0, 0x60), 0x21}, 142 + {TASDEV_REG_SDW(0, 1, 0x02), 0x00}, 143 + {TASDEV_REG_SDW(0, 1, 0x17), 0xc0}, 144 + {TASDEV_REG_SDW(0, 1, 0x19), 0x60}, 145 + {TASDEV_REG_SDW(0, 1, 0x35), 0x75}, 146 + {TASDEV_REG_SDW(0, 1, 0x3d), 0x00}, 147 + {TASDEV_REG_SDW(0, 1, 0x3e), 0x00}, 148 + {TASDEV_REG_SDW(0, 1, 0x3f), 0x00}, 149 + {TASDEV_REG_SDW(0, 1, 0x40), 0x00}, 150 + {TASDEV_REG_SDW(0, 1, 0x41), 0x00}, 151 + {TASDEV_REG_SDW(0, 1, 0x42), 0x00}, 152 + {TASDEV_REG_SDW(0, 1, 0x43), 0x00}, 153 + {TASDEV_REG_SDW(0, 1, 0x44), 0x00}, 154 + {TASDEV_REG_SDW(0, 1, 0x45), 0x00}, 155 + {TASDEV_REG_SDW(0, 1, 0x47), 0xab}, 156 + {TASDEV_REG_SDW(0, 0xfd, 0x0d), 0x0d}, 157 + {TASDEV_REG_SDW(0, 0xfd, 0x39), 0x00}, 158 + {TASDEV_REG_SDW(0, 0xfd, 0x3e), 0x00}, 159 + {TASDEV_REG_SDW(0, 0xfd, 0x45), 0x00}, 160 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS21, 0x02, 0), 0x0}, 161 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS21, 0x10, 0), 0x0}, 162 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS24, 0x02, 0), 0x0}, 163 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS24, 0x10, 0), 0x0}, 164 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS26, 0x02, 0), 0x0}, 165 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS26, 0x10, 0), 0x0}, 166 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS28, 0x02, 0), 0x0}, 167 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS28, 0x10, 0), 0x0}, 168 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS127, 0x02, 0), 0x0}, 169 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS127, 0x10, 0), 0x0}, 170 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU21, 0x01, 1), 0x1}, 171 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU21, 0x02, 1), 0x9c00}, 172 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU23, 0x01, 0), 0x1}, 173 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU23, 0x01, 1), 0x1}, 174 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU23, 0x0b, 1), 0x0}, 175 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU23, 0x10, 0), 0x0}, 176 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU26, 0x01, 1), 0x1}, 177 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU26, 0x01, 0), 0x1}, 178 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU26, 0x0b, 1), 0x0}, 179 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU26, 0x10, 0), 0x0}, 180 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU127, 0x01, 0), 0x1}, 181 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU127, 0x01, 1), 0x1}, 182 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU127, 0x01, 2), 0x1}, 183 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU127, 0x0b, 0), 0x0}, 184 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU127, 0x0b, 1), 0x0}, 185 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU127, 0x0b, 2), 0x0}, 186 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU127, 0x10, 0), 0x0}, 187 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT21, 0x04, 0), 0x0}, 188 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT21, 0x08, 0), 0x0}, 189 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT21, 0x10, 0), 0x0}, 190 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT21, 0x11, 0), 0x0}, 191 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT26, 0x04, 0), 0x0}, 192 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT26, 0x08, 0), 0x0}, 193 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT26, 0x10, 0), 0x0}, 194 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT26, 0x11, 0), 0x0}, 195 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT28, 0x04, 0), 0x0}, 196 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT28, 0x08, 0), 0x0}, 197 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT28, 0x10, 0), 0x0}, 198 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT28, 0x11, 0), 0x0}, 199 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT29, 0x04, 0), 0x0}, 200 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT29, 0x08, 0), 0x0}, 201 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT29, 0x10, 0), 0x0}, 202 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT29, 0x11, 0), 0x0}, 203 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU21, 0x01, 0), 0x0}, 204 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU21, 0x04, 0), 0x0}, 205 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU21, 0x05, 0), 0x1}, 206 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU21, 0x08, 0), 0x0}, 207 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU21, 0x10, 0), 0x0}, 208 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU21, 0x11, 0), 0x0}, 209 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU21, 0x12, 0), 0x0}, 210 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x01, 0), 0x0}, 211 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x04, 0), 0x0}, 212 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x05, 0), 0x1}, 213 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x08, 0), 0x0}, 214 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x10, 0), 0x0}, 215 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x11, 0), 0x0}, 216 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x12, 0), 0x0}, 217 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 0), 0x0}, 218 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 1), 0x0}, 219 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 2), 0x0}, 220 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 3), 0x0}, 221 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 4), 0x0}, 222 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 5), 0x0}, 223 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 6), 0x0}, 224 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 7), 0x0}, 225 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x06, 0), 0x0}, 226 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT23, 0x04, 0), 0x0}, 227 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT23, 0x08, 0), 0x0}, 228 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT24, 0x04, 0), 0x0}, 229 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT24, 0x08, 0), 0x0}, 230 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT24, 0x11, 0), 0x0}, 231 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT25, 0x04, 0), 0x0}, 232 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT25, 0x08, 0), 0x0}, 233 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT25, 0x11, 0), 0x0}, 234 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT28, 0x04, 0), 0x0}, 235 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT28, 0x08, 0), 0x0}, 236 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT28, 0x11, 0), 0x0}, 237 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x04, 0), 0x0}, 238 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x08, 0), 0x0}, 239 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x11, 0), 0x0}, 240 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 0), 0x0}, 241 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 1), 0x0}, 242 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 2), 0x0}, 243 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 3), 0x0}, 244 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 4), 0x0}, 245 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 5), 0x0}, 246 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 6), 0x0}, 247 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 7), 0x0}, 248 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 8), 0x0}, 249 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 9), 0x0}, 250 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 0xa), 0x0}, 251 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 0xb), 0x0}, 252 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 0xc), 0x0}, 253 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 0xd), 0x0}, 254 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 0xe), 0x0}, 255 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 0xf), 0x0}, 256 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PDE23, 0x1, 0), 0x3}, 257 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PDE23, 0x10, 0), 0x3}, 258 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU21, 0x06, 0), 0x0}, 259 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU21, 0x10, 0), 0x0}, 260 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU21, 0x11, 0), 0x0}, 261 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU21, 0x12, 0), 0x0}, 262 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU21, 0x13, 0), 0x0}, 263 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU26, 0x06, 0), 0x0}, 264 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU26, 0x10, 0), 0x0}, 265 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU26, 0x11, 0), 0x0}, 266 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU26, 0x12, 0), 0x0}, 267 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU26, 0x13, 0), 0x0}, 268 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_SAPU29, 0x05, 0), 0x0}, 269 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_SAPU29, 0x10, 0), 0x1}, 270 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_SAPU29, 0x11, 0), 0x0}, 271 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_SAPU29, 0x12, 0), 0x0}, 272 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_TG23, 0x10, 0), 0x0}, 273 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x01, 0), 0x1}, 274 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x06, 0), 0x0}, 275 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x07, 0), 0x0}, 276 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x08, 0), 0x0}, 277 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x09, 0), 0x0}, 278 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x0a, 0), 0x0}, 279 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x10, 0), 0x1}, 280 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x12, 0), 0x0}, 281 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x13, 0), 0x0}, 282 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x14, 0), 0x0}, 283 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x15, 0), 0x0}, 284 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x16, 0), 0x0}, 285 + {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_UDMPU23, 0x10, 0), 0x0}, 286 + }; 287 + 288 + static const struct reg_sequence tas2783_init_seq[] = { 289 + REG_SEQ0(SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU21, 0x10, 0x00), 0x04), 290 + REG_SEQ0(0x00800418, 0x00), 291 + REG_SEQ0(0x00800419, 0x00), 292 + REG_SEQ0(0x0080041a, 0x00), 293 + REG_SEQ0(0x0080041b, 0x00), 294 + REG_SEQ0(0x00800428, 0x40), 295 + REG_SEQ0(0x00800429, 0x00), 296 + REG_SEQ0(0x0080042a, 0x00), 297 + REG_SEQ0(0x0080042b, 0x00), 298 + REG_SEQ0(SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU23, 0x1, 0x00), 0x00), 299 + REG_SEQ0(0x0080005c, 0xD9), 300 + REG_SEQ0(0x00800082, 0x20), 301 + REG_SEQ0(0x008000a1, 0x00), 302 + REG_SEQ0(0x00800097, 0xc8), 303 + REG_SEQ0(0x00800099, 0x20), 304 + REG_SEQ0(0x008000c7, 0xaa), 305 + REG_SEQ0(0x008000b5, 0x74), 306 + REG_SEQ0(0x00800082, 0x20), 307 + REG_SEQ0(0x00807e8d, 0x0d), 308 + REG_SEQ0(0x00807eb9, 0x53), 309 + REG_SEQ0(0x00807ebe, 0x42), 310 + REG_SEQ0(0x00807ec5, 0x37), 311 + REG_SEQ0(0x00800066, 0x92), 312 + REG_SEQ0(0x00800003, 0x28), 313 + REG_SEQ0(0x00800004, 0x21), 314 + REG_SEQ0(0x00800005, 0x41), 315 + REG_SEQ0(0x00800006, 0x00), 316 + REG_SEQ0(0x00800007, 0x20), 317 + REG_SEQ0(0x0080000c, 0x10), 318 + REG_SEQ0(0x00800013, 0x08), 319 + REG_SEQ0(0x00800015, 0x00), 320 + REG_SEQ0(0x00800017, 0x80), 321 + REG_SEQ0(0x0080001a, 0x00), 322 + REG_SEQ0(0x0080001b, 0x22), 323 + REG_SEQ0(0x0080001c, 0x36), 324 + REG_SEQ0(0x0080001d, 0x01), 325 + REG_SEQ0(0x0080001f, 0x00), 326 + REG_SEQ0(0x00800020, 0x2e), 327 + REG_SEQ0(0x00800034, 0x06), 328 + REG_SEQ0(0x00800035, 0xb9), 329 + REG_SEQ0(0x00800036, 0xad), 330 + REG_SEQ0(0x00800037, 0xa8), 331 + REG_SEQ0(0x00800038, 0x00), 332 + REG_SEQ0(0x0080003b, 0xfc), 333 + REG_SEQ0(0x0080003d, 0xdd), 334 + REG_SEQ0(0x00800040, 0xf6), 335 + REG_SEQ0(0x00800041, 0x14), 336 + REG_SEQ0(0x0080005c, 0x19), 337 + REG_SEQ0(0x0080005d, 0x80), 338 + REG_SEQ0(0x00800063, 0x48), 339 + REG_SEQ0(0x00800065, 0x08), 340 + REG_SEQ0(0x00800067, 0x00), 341 + REG_SEQ0(0x0080006a, 0x12), 342 + REG_SEQ0(0x0080006b, 0x7b), 343 + REG_SEQ0(0x0080006c, 0x00), 344 + REG_SEQ0(0x0080006d, 0x00), 345 + REG_SEQ0(0x0080006e, 0x1a), 346 + REG_SEQ0(0x0080006f, 0x00), 347 + REG_SEQ0(0x00800070, 0x96), 348 + REG_SEQ0(0x00800071, 0x02), 349 + REG_SEQ0(0x00800073, 0x08), 350 + REG_SEQ0(0x00800075, 0xe0), 351 + REG_SEQ0(0x0080007a, 0x60), 352 + REG_SEQ0(0x008000bd, 0x00), 353 + REG_SEQ0(0x008000be, 0x00), 354 + REG_SEQ0(0x008000bf, 0x00), 355 + REG_SEQ0(0x008000c0, 0x00), 356 + REG_SEQ0(0x008000c1, 0x00), 357 + REG_SEQ0(0x008000c2, 0x00), 358 + REG_SEQ0(0x008000c3, 0x00), 359 + REG_SEQ0(0x008000c4, 0x00), 360 + REG_SEQ0(0x008000c5, 0x00), 361 + REG_SEQ0(0x00800008, 0x49), 362 + REG_SEQ0(0x00800009, 0x02), 363 + REG_SEQ0(0x0080000a, 0x1a), 364 + REG_SEQ0(0x0080000d, 0x93), 365 + REG_SEQ0(0x0080000e, 0x82), 366 + REG_SEQ0(0x0080000f, 0x42), 367 + REG_SEQ0(0x00800010, 0x84), 368 + REG_SEQ0(0x00800014, 0x0a), 369 + REG_SEQ0(0x00800016, 0x00), 370 + REG_SEQ0(0x00800060, 0x21), 371 + }; 372 + 373 + static int tas2783_sdca_mbq_size(struct device *dev, u32 reg) 374 + { 375 + switch (reg) { 376 + case 0x000 ... 0x080: /* Data port 0. */ 377 + case 0x100 ... 0x140: /* Data port 1. */ 378 + case 0x200 ... 0x240: /* Data port 2. */ 379 + case 0x300 ... 0x340: /* Data port 3. */ 380 + case 0x400 ... 0x440: /* Data port 4. */ 381 + case 0x500 ... 0x540: /* Data port 5. */ 382 + case 0x800000 ... 0x803fff: /* Page 0 ~ 127. */ 383 + case 0x807e80 ... 0x807eff: /* Page 253. */ 384 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_UDMPU23, 385 + TAS2783_SDCA_CTL_UDMPU_CLUSTER, 0): 386 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU21, TAS2783_SDCA_CTL_FU_MUTE, 387 + TAS2783_DEVICE_CHANNEL_LEFT): 388 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PDE23, 0x1, 0): 389 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PDE23, 0x10, 0): 390 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT21, 0x04, 0): 391 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_SAPU29, 0x10, 0): 392 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_SAPU29, 0x11, 0): 393 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_SAPU29, 0x12, 0): 394 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU21, 0x10, 0): 395 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU21, 0x11, 0): 396 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU26, 0x10, 0): 397 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU26, 0x11, 0): 398 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_TG23, 0x10, 0): 399 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x01, 0): 400 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x08, 0): 401 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x0a, 0): 402 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x10, 0): 403 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x14, 0): 404 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x15, 0): 405 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x16, 0): 406 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT26, 0x04, 0): 407 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT28, 0x04, 0): 408 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT29, 0x04, 0): 409 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT23, 0x04, 0): 410 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT24, 0x04, 0): 411 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT28, 0x04, 0): 412 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x04, 0): 413 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 0): 414 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 1): 415 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 2): 416 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 3): 417 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 4): 418 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 5): 419 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 6): 420 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 7): 421 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 8): 422 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 9): 423 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 0xa): 424 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 0xb): 425 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 0xc): 426 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 0xd): 427 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 0xe): 428 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 0xf): 429 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS21, 0x02, 0): 430 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS21, 0x10, 0): 431 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS24, 0x02, 0): 432 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS24, 0x10, 0): 433 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS25, 0x02, 0): 434 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS25, 0x10, 0): 435 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS127, 0x02, 0): 436 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS127, 0x10, 0): 437 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS26, 0x02, 0): 438 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS26, 0x10, 0): 439 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS28, 0x02, 0): 440 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS28, 0x10, 0): 441 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU21, 0x01, 0): 442 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU21, 0x04, 0): 443 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU21, 0x05, 0): 444 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU21, 0x10, 0): 445 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU21, 0x11, 0): 446 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU127, 0x01, 1): 447 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU127, 0x01, 2): 448 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU127, 0x01, 0): 449 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU26, 0x01, 1): 450 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU26, 0x01, 0): 451 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x01, 0): 452 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x04, 0): 453 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x05, 0): 454 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x10, 0): 455 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x11, 0): 456 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU23, 0x01, 0): 457 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU23, 0x01, 1): 458 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT25, 0x04, 0): 459 + return 1; 460 + 461 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT26, 0x10, 0): 462 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT26, 0x11, 0): 463 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT28, 0x10, 0): 464 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT28, 0x11, 0): 465 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT29, 0x10, 0): 466 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT29, 0x11, 0): 467 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT24, 0x11, 0): 468 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT25, 0x11, 0): 469 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT28, 0x11, 0): 470 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x11, 0): 471 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 0): 472 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 1): 473 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 2): 474 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 3): 475 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 4): 476 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 5): 477 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 6): 478 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 7): 479 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU21, 0x02, 1): 480 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU23, 0x0b, 1): 481 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU127, 0x0b, 1): 482 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU127, 0x0b, 2): 483 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU127, 0x0b, 0): 484 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU26, 0x0b, 0): 485 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU26, 0x0b, 1): 486 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x07, 0): 487 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x09, 0): 488 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU21, 0x12, 0): 489 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x12, 0): 490 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU21, 0x12, 0): 491 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU21, 0x13, 0): 492 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU26, 0x12, 0): 493 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU26, 0x13, 0): 494 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT21, 0x10, 0): 495 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT21, 0x11, 0): 496 + return 2; 497 + 498 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU23, 0x10, 0): 499 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT21, 0x08, 0): 500 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT26, 0x08, 0): 501 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT28, 0x08, 0): 502 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT29, 0x08, 0): 503 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT23, 0x08, 0): 504 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT24, 0x08, 0): 505 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT25, 0x08, 0): 506 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT28, 0x08, 0): 507 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x08, 0): 508 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x06, 0): 509 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU127, 0x10, 0): 510 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU26, 0x10, 0): 511 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x06, 0): 512 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x12, 0): 513 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x13, 0): 514 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU21, 0x08, 0): 515 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x08, 0): 516 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_SAPU29, 0x05, 0): 517 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU21, 0x06, 0): 518 + case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU26, 0x06, 0): 519 + return 4; 520 + 521 + default: 522 + return 0; 523 + } 524 + } 525 + 526 + static bool tas2783_readable_register(struct device *dev, unsigned int reg) 527 + { 528 + return tas2783_sdca_mbq_size(dev, reg) > 0; 529 + } 530 + 531 + static bool tas2783_volatile_register(struct device *dev, u32 reg) 532 + { 533 + switch (reg) { 534 + case 0x000 ... 0x080: /* Data port 0. */ 535 + case 0x100 ... 0x140: /* Data port 1. */ 536 + case 0x200 ... 0x240: /* Data port 2. */ 537 + case 0x300 ... 0x340: /* Data port 3. */ 538 + case 0x400 ... 0x440: /* Data port 4. */ 539 + case 0x500 ... 0x540: /* Data port 5. */ 540 + case 0x800001: 541 + return true; 542 + 543 + default: 544 + return false; 545 + } 546 + } 547 + 548 + static const struct regmap_config tas_regmap = { 549 + .reg_bits = 32, 550 + .val_bits = 8, 551 + .readable_reg = tas2783_readable_register, 552 + .volatile_reg = tas2783_volatile_register, 553 + .reg_defaults = tas2783_reg_default, 554 + .num_reg_defaults = ARRAY_SIZE(tas2783_reg_default), 555 + .max_register = 0x41008000 + TASDEV_REG_SDW(0xa1, 0x60, 0x7f), 556 + .cache_type = REGCACHE_MAPLE, 557 + .use_single_read = true, 558 + .use_single_write = true, 559 + }; 560 + 561 + static const struct regmap_sdw_mbq_cfg tas2783_mbq_cfg = { 562 + .mbq_size = tas2783_sdca_mbq_size, 563 + }; 564 + 565 + static s32 tas2783_digital_getvol(struct snd_kcontrol *kcontrol, 566 + struct snd_ctl_elem_value *ucontrol) 567 + { 568 + return snd_soc_get_volsw(kcontrol, ucontrol); 569 + } 570 + 571 + static s32 tas2783_digital_putvol(struct snd_kcontrol *kcontrol, 572 + struct snd_ctl_elem_value *ucontrol) 573 + { 574 + return snd_soc_put_volsw(kcontrol, ucontrol); 575 + } 576 + 577 + static s32 tas2783_amp_getvol(struct snd_kcontrol *kcontrol, 578 + struct snd_ctl_elem_value *ucontrol) 579 + { 580 + return snd_soc_get_volsw(kcontrol, ucontrol); 581 + } 582 + 583 + static s32 tas2783_amp_putvol(struct snd_kcontrol *kcontrol, 584 + struct snd_ctl_elem_value *ucontrol) 585 + { 586 + return snd_soc_put_volsw(kcontrol, ucontrol); 587 + } 588 + 589 + static const struct snd_kcontrol_new tas2783_snd_controls[] = { 590 + SOC_SINGLE_RANGE_EXT_TLV("Amp Volume", TAS2783_AMP_LEVEL, 591 + 1, 0, 20, 0, tas2783_amp_getvol, 592 + tas2783_amp_putvol, tas2781_amp_tlv), 593 + SOC_SINGLE_RANGE_EXT_TLV("Speaker Volume", TAS2783_DVC_LVL, 594 + 0, 0, 200, 1, tas2783_digital_getvol, 595 + tas2783_digital_putvol, tas2781_dvc_tlv), 596 + }; 597 + 598 + static s32 tas2783_validate_calibdata(struct tas2783_prv *tas_dev, 599 + u8 *data, u32 size) 600 + { 601 + u32 ts, spk_count, size_calculated; 602 + u32 crc_calculated, crc_read, i; 603 + u32 *tmp_val; 604 + struct tm tm; 605 + 606 + i = 0; 607 + tmp_val = (u32 *)data; 608 + if (tmp_val[i++] != 2783) { 609 + dev_err(tas_dev->dev, "cal data magic number mismatch"); 610 + return -EINVAL; 611 + } 612 + 613 + spk_count = tmp_val[i++]; 614 + if (spk_count > TAS2783_CALIB_MAX_SPK_COUNT) { 615 + dev_err(tas_dev->dev, "cal data spk_count too large"); 616 + return -EINVAL; 617 + } 618 + 619 + ts = tmp_val[i++]; 620 + time64_to_tm(ts, 0, &tm); 621 + dev_dbg(tas_dev->dev, "cal data timestamp: %ld-%d-%d %d:%d:%d", 622 + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 623 + tm.tm_hour, tm.tm_min, tm.tm_sec); 624 + 625 + size_calculated = 626 + (spk_count * TAS2783_CALIB_PARAMS * sizeof(u32)) + 627 + TAS2783_CALIB_HDR_SZ + TAS2783_CALIB_CRC_SZ; 628 + if (size_calculated > TAS2783_CALIB_DATA_SZ) { 629 + dev_err(tas_dev->dev, "cali data sz too large"); 630 + return -EINVAL; 631 + } else if (size < size_calculated) { 632 + dev_err(tas_dev->dev, "cali data size mismatch calc=%u vs %d\n", 633 + size, size_calculated); 634 + return -EINVAL; 635 + } 636 + 637 + crc_calculated = crc32(~0, data, 638 + size_calculated - TAS2783_CALIB_CRC_SZ) ^ ~0; 639 + crc_read = tmp_val[(size_calculated - TAS2783_CALIB_CRC_SZ) / sizeof(u32)]; 640 + if (crc_calculated != crc_read) { 641 + dev_err(tas_dev->dev, 642 + "calib data integrity check fail, 0x%08x vs 0x%08x\n", 643 + crc_calculated, crc_read); 644 + return -EINVAL; 645 + } 646 + 647 + return 0; 648 + } 649 + 650 + static void tas2783_set_calib_params_to_device(struct tas2783_prv *tas_dev, u32 *cali_data) 651 + { 652 + u32 dev_count, offset, i, device_num; 653 + u32 reg_value; 654 + u8 buf[4]; 655 + 656 + dev_count = cali_data[1]; 657 + offset = 3; 658 + 659 + for (device_num = 0; device_num < dev_count; device_num++) { 660 + if (cali_data[offset] != tas_dev->sdw_peripheral->id.unique_id) { 661 + offset += TAS2783_CALIB_PARAMS; 662 + continue; 663 + } 664 + offset++; 665 + 666 + for (i = 0; i < ARRAY_SIZE(tas2783_cali_reg); i++) { 667 + reg_value = cali_data[offset + i]; 668 + buf[0] = reg_value >> 24; 669 + buf[1] = reg_value >> 16; 670 + buf[2] = reg_value >> 8; 671 + buf[3] = reg_value & 0xff; 672 + regmap_bulk_write(tas_dev->regmap, tas2783_cali_reg[i], 673 + buf, sizeof(u32)); 674 + } 675 + break; 676 + } 677 + 678 + if (device_num == dev_count) 679 + dev_err(tas_dev->dev, "device not found\n"); 680 + else 681 + dev_dbg(tas_dev->dev, "calib data update done\n"); 682 + } 683 + 684 + static s32 tas2783_update_calibdata(struct tas2783_prv *tas_dev) 685 + { 686 + efi_guid_t efi_guid = TAS2783_CALI_GUID; 687 + u32 attr, i, *tmp_val; 688 + unsigned long size; 689 + s32 ret; 690 + efi_status_t status; 691 + static efi_char16_t efi_names[][32] = { 692 + L"SmartAmpCalibrationData", L"CALI_DATA"}; 693 + 694 + tmp_val = (u32 *)tas_dev->cali_data.data; 695 + attr = 0; 696 + i = 0; 697 + 698 + /* 699 + * In some cases, the calibration is performed in Windows, 700 + * and data was saved in UEFI. Linux can access it. 701 + */ 702 + for (i = 0; i < ARRAY_SIZE(efi_names); i++) { 703 + size = 0; 704 + status = efi.get_variable(efi_names[i], &efi_guid, &attr, 705 + &size, NULL); 706 + if (size > TAS2783_CALIB_DATA_SZ) { 707 + dev_err(tas_dev->dev, "cali data too large\n"); 708 + break; 709 + } 710 + 711 + tas_dev->cali_data.read_sz = size; 712 + if (status == EFI_BUFFER_TOO_SMALL) { 713 + status = efi.get_variable(efi_names[i], &efi_guid, &attr, 714 + &tas_dev->cali_data.read_sz, 715 + tas_dev->cali_data.data); 716 + dev_dbg(tas_dev->dev, "cali get %lu bytes result:%ld\n", 717 + tas_dev->cali_data.read_sz, status); 718 + } 719 + if (status == EFI_SUCCESS) 720 + break; 721 + } 722 + 723 + if (status != EFI_SUCCESS) { 724 + /* Failed got calibration data from EFI. */ 725 + dev_dbg(tas_dev->dev, "No calibration data in UEFI."); 726 + return 0; 727 + } 728 + 729 + mutex_lock(&tas_dev->calib_lock); 730 + ret = tas2783_validate_calibdata(tas_dev, tas_dev->cali_data.data, 731 + tas_dev->cali_data.read_sz); 732 + if (!ret) 733 + tas2783_set_calib_params_to_device(tas_dev, tmp_val); 734 + mutex_unlock(&tas_dev->calib_lock); 735 + 736 + return ret; 737 + } 738 + 739 + static s32 read_header(const u8 *data, struct bin_header_t *hdr) 740 + { 741 + hdr->vendor_id = get_unaligned_le16(&data[0]); 742 + hdr->file_id = get_unaligned_le32(&data[2]); 743 + hdr->version = get_unaligned_le16(&data[6]); 744 + hdr->length = get_unaligned_le32(&data[8]); 745 + return 12; 746 + } 747 + 748 + static void tas2783_fw_ready(const struct firmware *fmw, void *context) 749 + { 750 + struct tas2783_prv *tas_dev = 751 + (struct tas2783_prv *)context; 752 + const u8 *buf = NULL; 753 + s32 offset = 0, img_sz, file_blk_size, ret; 754 + struct bin_header_t hdr; 755 + 756 + if (!fmw || !fmw->data) { 757 + /* No firmware binary, devices will work in ROM mode. */ 758 + dev_err(tas_dev->dev, 759 + "Failed to read %s, no side-effect on driver running\n", 760 + tas_dev->rca_binaryname); 761 + ret = -EINVAL; 762 + goto out; 763 + } 764 + 765 + mutex_lock(&tas_dev->pde_lock); 766 + img_sz = fmw->size; 767 + buf = fmw->data; 768 + offset += FW_DL_OFFSET; 769 + while (offset < (img_sz - FW_FL_HDR)) { 770 + memset(&hdr, 0, sizeof(hdr)); 771 + offset += read_header(&buf[offset], &hdr); 772 + dev_dbg(tas_dev->dev, 773 + "vndr=%d, file=%d, version=%d, len=%d, off=%d\n", 774 + hdr.vendor_id, hdr.file_id, hdr.version, 775 + hdr.length, offset); 776 + /* size also includes the header */ 777 + file_blk_size = hdr.length - FW_FL_HDR; 778 + 779 + switch (hdr.file_id) { 780 + case 0: 781 + ret = sdw_nwrite_no_pm(tas_dev->sdw_peripheral, 782 + PRAM_ADDR_START, file_blk_size, 783 + &buf[offset]); 784 + if (ret < 0) 785 + dev_err(tas_dev->dev, 786 + "PRAM update failed: %d", ret); 787 + break; 788 + 789 + case 1: 790 + ret = sdw_nwrite_no_pm(tas_dev->sdw_peripheral, 791 + YRAM_ADDR_START, file_blk_size, 792 + &buf[offset]); 793 + if (ret < 0) 794 + dev_err(tas_dev->dev, 795 + "YRAM update failed: %d", ret); 796 + 797 + break; 798 + 799 + default: 800 + ret = -EINVAL; 801 + dev_err(tas_dev->dev, "Unsupported file"); 802 + break; 803 + } 804 + 805 + if (ret == 0) 806 + offset += file_blk_size; 807 + else 808 + break; 809 + }; 810 + mutex_unlock(&tas_dev->pde_lock); 811 + tas2783_update_calibdata(tas_dev); 812 + 813 + out: 814 + if (!ret) 815 + tas_dev->fw_dl_success = true; 816 + tas_dev->fw_dl_task_done = true; 817 + wake_up(&tas_dev->fw_wait); 818 + if (fmw) 819 + release_firmware(fmw); 820 + } 821 + 822 + static inline s32 tas_clear_latch(struct tas2783_prv *priv) 823 + { 824 + return regmap_update_bits(priv->regmap, 825 + TASDEV_REG_SDW(0, 0, 0x5c), 826 + 0x04, 0x04); 827 + } 828 + 829 + static s32 tas_fu21_event(struct snd_soc_dapm_widget *w, 830 + struct snd_kcontrol *k, s32 event) 831 + { 832 + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 833 + struct tas2783_prv *tas_dev = snd_soc_component_get_drvdata(component); 834 + s32 mute; 835 + 836 + switch (event) { 837 + case SND_SOC_DAPM_POST_PMU: 838 + mute = 0; 839 + break; 840 + 841 + case SND_SOC_DAPM_PRE_PMD: 842 + mute = 1; 843 + break; 844 + } 845 + 846 + return sdw_write_no_pm(tas_dev->sdw_peripheral, 847 + SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU21, 848 + TAS2783_SDCA_CTL_FU_MUTE, 1), mute); 849 + } 850 + 851 + static s32 tas_fu23_event(struct snd_soc_dapm_widget *w, 852 + struct snd_kcontrol *k, s32 event) 853 + { 854 + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 855 + struct tas2783_prv *tas_dev = snd_soc_component_get_drvdata(component); 856 + s32 mute; 857 + 858 + switch (event) { 859 + case SND_SOC_DAPM_POST_PMU: 860 + mute = 0; 861 + break; 862 + 863 + case SND_SOC_DAPM_PRE_PMD: 864 + mute = 1; 865 + break; 866 + } 867 + 868 + return sdw_write_no_pm(tas_dev->sdw_peripheral, 869 + SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU23, 870 + TAS2783_SDCA_CTL_FU_MUTE, 1), mute); 871 + } 872 + 873 + static const struct snd_soc_dapm_widget tas_dapm_widgets[] = { 874 + SND_SOC_DAPM_AIF_IN("ASI", "ASI Playback", 0, SND_SOC_NOPM, 0, 0), 875 + SND_SOC_DAPM_AIF_OUT("ASI OUT", "ASI Capture", 0, SND_SOC_NOPM, 876 + 0, 0), 877 + SND_SOC_DAPM_DAC_E("FU21", NULL, SND_SOC_NOPM, 0, 0, tas_fu21_event, 878 + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 879 + SND_SOC_DAPM_DAC_E("FU23", NULL, SND_SOC_NOPM, 0, 0, tas_fu23_event, 880 + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 881 + SND_SOC_DAPM_OUTPUT("SPK"), 882 + SND_SOC_DAPM_INPUT("DMIC"), 883 + }; 884 + 885 + static const struct snd_soc_dapm_route tas_audio_map[] = { 886 + {"FU21", NULL, "ASI"}, 887 + {"SPK", NULL, "FU21"}, 888 + {"FU23", NULL, "ASI"}, 889 + {"SPK", NULL, "FU23"}, 890 + {"ASI OUT", NULL, "DMIC"}, 891 + }; 892 + 893 + static s32 tas_set_sdw_stream(struct snd_soc_dai *dai, 894 + void *sdw_stream, s32 direction) 895 + { 896 + if (!sdw_stream) 897 + return 0; 898 + 899 + snd_soc_dai_dma_data_set(dai, direction, sdw_stream); 900 + 901 + return 0; 902 + } 903 + 904 + static void tas_sdw_shutdown(struct snd_pcm_substream *substream, 905 + struct snd_soc_dai *dai) 906 + { 907 + snd_soc_dai_set_dma_data(dai, substream, NULL); 908 + } 909 + 910 + static s32 tas_sdw_hw_params(struct snd_pcm_substream *substream, 911 + struct snd_pcm_hw_params *params, 912 + struct snd_soc_dai *dai) 913 + { 914 + struct snd_soc_component *component = dai->component; 915 + struct tas2783_prv *tas_dev = 916 + snd_soc_component_get_drvdata(component); 917 + struct sdw_stream_config stream_config = {0}; 918 + struct sdw_port_config port_config = {0}; 919 + struct sdw_stream_runtime *sdw_stream; 920 + struct sdw_slave *sdw_peripheral = tas_dev->sdw_peripheral; 921 + s32 ret, retry = 3; 922 + 923 + if (!tas_dev->fw_dl_success) { 924 + dev_err(tas_dev->dev, "error playback without fw download"); 925 + return -EINVAL; 926 + } 927 + 928 + sdw_stream = snd_soc_dai_get_dma_data(dai, substream); 929 + if (!sdw_stream) 930 + return -EINVAL; 931 + 932 + ret = tas_clear_latch(tas_dev); 933 + if (ret) 934 + dev_err(tas_dev->dev, 935 + "clear latch failed, err=%d", ret); 936 + 937 + mutex_lock(&tas_dev->pde_lock); 938 + /* 939 + * Sometimes, there is error returned during power on. 940 + * So added retry logic to ensure power on so that 941 + * port prepare succeeds 942 + */ 943 + do { 944 + ret = regmap_write(tas_dev->regmap, 945 + SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PDE23, 946 + TAS2783_SDCA_CTL_REQ_POW_STATE, 0), 947 + TAS2783_SDCA_POW_STATE_ON); 948 + if (!ret) 949 + break; 950 + usleep_range(2000, 2200); 951 + } while (retry--); 952 + mutex_unlock(&tas_dev->pde_lock); 953 + if (ret) 954 + return ret; 955 + 956 + /* SoundWire specific configuration */ 957 + snd_sdw_params_to_config(substream, params, 958 + &stream_config, &port_config); 959 + /* port 1 for playback */ 960 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 961 + port_config.num = 1; 962 + else 963 + port_config.num = 2; 964 + 965 + ret = sdw_stream_add_slave(sdw_peripheral, 966 + &stream_config, &port_config, 1, sdw_stream); 967 + if (ret) 968 + dev_err(dai->dev, "Unable to configure port\n"); 969 + 970 + return ret; 971 + } 972 + 973 + static s32 tas_sdw_pcm_hw_free(struct snd_pcm_substream *substream, 974 + struct snd_soc_dai *dai) 975 + { 976 + s32 ret; 977 + struct snd_soc_component *component = dai->component; 978 + struct tas2783_prv *tas_dev = 979 + snd_soc_component_get_drvdata(component); 980 + struct sdw_stream_runtime *sdw_stream = 981 + snd_soc_dai_get_dma_data(dai, substream); 982 + 983 + sdw_stream_remove_slave(tas_dev->sdw_peripheral, sdw_stream); 984 + 985 + mutex_lock(&tas_dev->pde_lock); 986 + ret = regmap_write(tas_dev->regmap, 987 + SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PDE23, 988 + TAS2783_SDCA_CTL_REQ_POW_STATE, 0), 989 + TAS2783_SDCA_POW_STATE_OFF); 990 + mutex_unlock(&tas_dev->pde_lock); 991 + 992 + return ret; 993 + } 994 + 995 + static const struct snd_soc_dai_ops tas_dai_ops = { 996 + .hw_params = tas_sdw_hw_params, 997 + .hw_free = tas_sdw_pcm_hw_free, 998 + .set_stream = tas_set_sdw_stream, 999 + .shutdown = tas_sdw_shutdown, 1000 + }; 1001 + 1002 + static struct snd_soc_dai_driver tas_dai_driver[] = { 1003 + { 1004 + .name = "tas2783-codec", 1005 + .id = 0, 1006 + .playback = { 1007 + .stream_name = "Playback", 1008 + .channels_min = 1, 1009 + .channels_max = 4, 1010 + .rates = TAS2783_DEVICE_RATES, 1011 + .formats = TAS2783_DEVICE_FORMATS, 1012 + }, 1013 + .capture = { 1014 + .stream_name = "Capture", 1015 + .channels_min = 1, 1016 + .channels_max = 4, 1017 + .rates = TAS2783_DEVICE_RATES, 1018 + .formats = TAS2783_DEVICE_FORMATS, 1019 + }, 1020 + .ops = &tas_dai_ops, 1021 + .symmetric_rate = 1, 1022 + }, 1023 + }; 1024 + 1025 + static s32 tas_component_probe(struct snd_soc_component *component) 1026 + { 1027 + struct tas2783_prv *tas_dev = 1028 + snd_soc_component_get_drvdata(component); 1029 + 1030 + tas_dev->component = component; 1031 + tas25xx_register_misc(tas_dev->sdw_peripheral); 1032 + 1033 + return 0; 1034 + } 1035 + 1036 + static void tas_component_remove(struct snd_soc_component *codec) 1037 + { 1038 + struct tas2783_prv *tas_dev = 1039 + snd_soc_component_get_drvdata(codec); 1040 + tas25xx_deregister_misc(); 1041 + tas_dev->component = NULL; 1042 + } 1043 + 1044 + static const struct snd_soc_component_driver soc_codec_driver_tasdevice = { 1045 + .probe = tas_component_probe, 1046 + .remove = tas_component_remove, 1047 + .controls = tas2783_snd_controls, 1048 + .num_controls = ARRAY_SIZE(tas2783_snd_controls), 1049 + .dapm_widgets = tas_dapm_widgets, 1050 + .num_dapm_widgets = ARRAY_SIZE(tas_dapm_widgets), 1051 + .dapm_routes = tas_audio_map, 1052 + .num_dapm_routes = ARRAY_SIZE(tas_audio_map), 1053 + .idle_bias_on = 1, 1054 + .endianness = 1, 1055 + }; 1056 + 1057 + static s32 tas_init(struct tas2783_prv *tas_dev) 1058 + { 1059 + s32 ret; 1060 + 1061 + dev_set_drvdata(tas_dev->dev, tas_dev); 1062 + ret = devm_snd_soc_register_component(tas_dev->dev, 1063 + &soc_codec_driver_tasdevice, 1064 + tas_dai_driver, 1065 + ARRAY_SIZE(tas_dai_driver)); 1066 + if (ret) { 1067 + dev_err(tas_dev->dev, "%s: codec register error:%d.\n", 1068 + __func__, ret); 1069 + return ret; 1070 + } 1071 + 1072 + /* set autosuspend parameters */ 1073 + pm_runtime_set_autosuspend_delay(tas_dev->dev, 3000); 1074 + pm_runtime_use_autosuspend(tas_dev->dev); 1075 + /* make sure the device does not suspend immediately */ 1076 + pm_runtime_mark_last_busy(tas_dev->dev); 1077 + pm_runtime_enable(tas_dev->dev); 1078 + 1079 + return ret; 1080 + } 1081 + 1082 + static s32 tas_read_prop(struct sdw_slave *slave) 1083 + { 1084 + struct sdw_slave_prop *prop = &slave->prop; 1085 + s32 nval; 1086 + s32 i, j; 1087 + u32 bit; 1088 + unsigned long addr; 1089 + struct sdw_dpn_prop *dpn; 1090 + 1091 + prop->scp_int1_mask = 1092 + SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY; 1093 + prop->quirks = SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY; 1094 + 1095 + prop->paging_support = true; 1096 + 1097 + /* first we need to allocate memory for set bits in port lists */ 1098 + prop->source_ports = 0x04; /* BITMAP: 00000100 */ 1099 + prop->sink_ports = 0x2; /* BITMAP: 00000010 */ 1100 + 1101 + nval = hweight32(prop->source_ports); 1102 + prop->src_dpn_prop = devm_kcalloc(&slave->dev, nval, 1103 + sizeof(*prop->src_dpn_prop), GFP_KERNEL); 1104 + if (!prop->src_dpn_prop) 1105 + return -ENOMEM; 1106 + 1107 + i = 0; 1108 + dpn = prop->src_dpn_prop; 1109 + addr = prop->source_ports; 1110 + for_each_set_bit(bit, &addr, 32) { 1111 + dpn[i].num = bit; 1112 + dpn[i].type = SDW_DPN_FULL; 1113 + dpn[i].simple_ch_prep_sm = false; 1114 + dpn[i].ch_prep_timeout = 10; 1115 + i++; 1116 + } 1117 + 1118 + /* do this again for sink now */ 1119 + nval = hweight32(prop->sink_ports); 1120 + prop->sink_dpn_prop = devm_kcalloc(&slave->dev, nval, 1121 + sizeof(*prop->sink_dpn_prop), GFP_KERNEL); 1122 + if (!prop->sink_dpn_prop) 1123 + return -ENOMEM; 1124 + 1125 + j = 0; 1126 + dpn = prop->sink_dpn_prop; 1127 + addr = prop->sink_ports; 1128 + for_each_set_bit(bit, &addr, 32) { 1129 + dpn[j].num = bit; 1130 + dpn[j].type = SDW_DPN_FULL; 1131 + dpn[j].simple_ch_prep_sm = false; 1132 + dpn[j].ch_prep_timeout = 10; 1133 + j++; 1134 + } 1135 + 1136 + /* set the timeout values */ 1137 + prop->clk_stop_timeout = 200; 1138 + 1139 + return 0; 1140 + } 1141 + 1142 + static s32 tas2783_sdca_dev_suspend(struct device *dev) 1143 + { 1144 + struct tas2783_prv *tas_dev = dev_get_drvdata(dev); 1145 + 1146 + if (!tas_dev->hw_init) 1147 + return 0; 1148 + 1149 + regcache_cache_only(tas_dev->regmap, true); 1150 + return 0; 1151 + } 1152 + 1153 + static s32 tas2783_sdca_dev_system_suspend(struct device *dev) 1154 + { 1155 + return tas2783_sdca_dev_suspend(dev); 1156 + } 1157 + 1158 + static s32 tas2783_sdca_dev_resume(struct device *dev) 1159 + { 1160 + struct sdw_slave *slave = dev_to_sdw_dev(dev); 1161 + struct tas2783_prv *tas_dev = dev_get_drvdata(dev); 1162 + unsigned long t; 1163 + 1164 + if (!slave->unattach_request) 1165 + goto regmap_sync; 1166 + 1167 + t = wait_for_completion_timeout(&slave->initialization_complete, 1168 + msecs_to_jiffies(TAS2783_PROBE_TIMEOUT)); 1169 + if (!t) { 1170 + dev_err(&slave->dev, "resume: initialization timed out\n"); 1171 + sdw_show_ping_status(slave->bus, true); 1172 + return -ETIMEDOUT; 1173 + } 1174 + 1175 + slave->unattach_request = 0; 1176 + 1177 + regmap_sync: 1178 + regcache_cache_only(tas_dev->regmap, false); 1179 + regcache_sync(tas_dev->regmap); 1180 + return 0; 1181 + } 1182 + 1183 + static const struct dev_pm_ops tas2783_sdca_pm = { 1184 + SYSTEM_SLEEP_PM_OPS(tas2783_sdca_dev_system_suspend, tas2783_sdca_dev_resume) 1185 + RUNTIME_PM_OPS(tas2783_sdca_dev_suspend, tas2783_sdca_dev_resume, NULL) 1186 + }; 1187 + 1188 + static s32 tas_io_init(struct device *dev, struct sdw_slave *slave) 1189 + { 1190 + struct tas2783_prv *tas_dev = dev_get_drvdata(dev); 1191 + s32 ret; 1192 + u8 unique_id = tas_dev->sdw_peripheral->id.unique_id; 1193 + 1194 + if (tas_dev->hw_init) 1195 + return 0; 1196 + 1197 + tas_dev->fw_dl_task_done = false; 1198 + tas_dev->fw_dl_success = false; 1199 + scnprintf(tas_dev->rca_binaryname, sizeof(tas_dev->rca_binaryname), 1200 + "tas2783-%01x.bin", unique_id); 1201 + 1202 + ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_UEVENT, 1203 + tas_dev->rca_binaryname, tas_dev->dev, 1204 + GFP_KERNEL, tas_dev, tas2783_fw_ready); 1205 + if (ret) { 1206 + dev_err(tas_dev->dev, 1207 + "firmware request failed for uid=%d, ret=%d\n", 1208 + unique_id, ret); 1209 + return ret; 1210 + } 1211 + 1212 + ret = wait_event_timeout(tas_dev->fw_wait, tas_dev->fw_dl_task_done, 1213 + msecs_to_jiffies(TIMEOUT_FW_DL_MS)); 1214 + if (!ret) { 1215 + dev_err(tas_dev->dev, "fw request, wait_event timeout\n"); 1216 + ret = -EAGAIN; 1217 + } else { 1218 + ret = regmap_multi_reg_write(tas_dev->regmap, tas2783_init_seq, 1219 + ARRAY_SIZE(tas2783_init_seq)); 1220 + tas_dev->hw_init = true; 1221 + } 1222 + 1223 + return ret; 1224 + } 1225 + 1226 + static s32 tas_update_status(struct sdw_slave *slave, 1227 + enum sdw_slave_status status) 1228 + { 1229 + struct tas2783_prv *tas_dev = dev_get_drvdata(&slave->dev); 1230 + struct device *dev = &slave->dev; 1231 + 1232 + dev_dbg(dev, "Perifpheral status = %s", 1233 + status == SDW_SLAVE_UNATTACHED ? "unattached" : 1234 + status == SDW_SLAVE_ATTACHED ? "attached" : "alert"); 1235 + 1236 + tas_dev->status = status; 1237 + if (status == SDW_SLAVE_UNATTACHED) 1238 + tas_dev->hw_init = false; 1239 + 1240 + /* Perform initialization only if slave status 1241 + * is present and hw_init flag is false 1242 + */ 1243 + if (tas_dev->hw_init || tas_dev->status != SDW_SLAVE_ATTACHED) 1244 + return 0; 1245 + 1246 + /* updated the cache data to device */ 1247 + regcache_cache_only(tas_dev->regmap, false); 1248 + regcache_sync(tas_dev->regmap); 1249 + 1250 + /* perform I/O transfers required for Slave initialization */ 1251 + return tas_io_init(&slave->dev, slave); 1252 + } 1253 + 1254 + static const struct sdw_slave_ops tas_sdw_ops = { 1255 + .read_prop = tas_read_prop, 1256 + .update_status = tas_update_status, 1257 + }; 1258 + 1259 + static void tas_remove(struct tas2783_prv *tas_dev) 1260 + { 1261 + snd_soc_unregister_component(tas_dev->dev); 1262 + } 1263 + 1264 + static s32 tas_sdw_probe(struct sdw_slave *peripheral, 1265 + const struct sdw_device_id *id) 1266 + { 1267 + struct regmap *regmap; 1268 + struct device *dev = &peripheral->dev; 1269 + struct tas2783_prv *tas_dev; 1270 + 1271 + tas_dev = devm_kzalloc(dev, sizeof(*tas_dev), GFP_KERNEL); 1272 + if (!tas_dev) 1273 + return dev_err_probe(dev, -ENOMEM, 1274 + "Failed devm_kzalloc"); 1275 + 1276 + tas_dev->dev = dev; 1277 + tas_dev->sdw_peripheral = peripheral; 1278 + tas_dev->hw_init = false; 1279 + mutex_init(&tas_dev->calib_lock); 1280 + mutex_init(&tas_dev->pde_lock); 1281 + 1282 + init_waitqueue_head(&tas_dev->fw_wait); 1283 + dev_set_drvdata(dev, tas_dev); 1284 + regmap = devm_regmap_init_sdw_mbq_cfg(peripheral, 1285 + &tas_regmap, 1286 + &tas2783_mbq_cfg); 1287 + if (IS_ERR(regmap)) 1288 + return dev_err_probe(dev, PTR_ERR(tas_dev->regmap), 1289 + "Failed devm_regmap_init_sdw."); 1290 + 1291 + /* keep in cache until the device is fully initialized */ 1292 + regcache_cache_only(regmap, true); 1293 + tas_dev->regmap = regmap; 1294 + return tas_init(tas_dev); 1295 + } 1296 + 1297 + static s32 tas_sdw_remove(struct sdw_slave *peripheral) 1298 + { 1299 + struct tas2783_prv *tas_dev = dev_get_drvdata(&peripheral->dev); 1300 + 1301 + pm_runtime_disable(tas_dev->dev); 1302 + tas_remove(tas_dev); 1303 + mutex_destroy(&tas_dev->calib_lock); 1304 + mutex_destroy(&tas_dev->pde_lock); 1305 + dev_set_drvdata(&peripheral->dev, NULL); 1306 + 1307 + return 0; 1308 + } 1309 + 1310 + static const struct sdw_device_id tas_sdw_id[] = { 1311 + /* chipid for the TAS2783 is 0x0000 */ 1312 + SDW_SLAVE_ENTRY(0x0102, 0x0000, 0), 1313 + {}, 1314 + }; 1315 + MODULE_DEVICE_TABLE(sdw, tas_sdw_id); 1316 + 1317 + static struct sdw_driver tas_sdw_driver = { 1318 + .driver = { 1319 + .name = "slave-tas2783", 1320 + .pm = pm_ptr(&tas2783_sdca_pm), 1321 + }, 1322 + .probe = tas_sdw_probe, 1323 + .remove = tas_sdw_remove, 1324 + .ops = &tas_sdw_ops, 1325 + .id_table = tas_sdw_id, 1326 + }; 1327 + module_sdw_driver(tas_sdw_driver); 1328 + 1329 + MODULE_AUTHOR("Texas Instruments Inc."); 1330 + MODULE_DESCRIPTION("ASoC TAS2783 SoundWire Driver"); 1331 + MODULE_LICENSE("GPL");
+110
sound/soc/codecs/tas2783.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 2 + * 3 + * ALSA SoC Texas Instruments TAS2783 Audio Smart Amplifier 4 + * 5 + * Copyright (C) 2025 Texas Instruments Incorporated 6 + * https://www.ti.com 7 + * 8 + * The TAS2783 driver implements a flexible and configurable 9 + * algo coefficient setting for single TAS2783 chips. 10 + * 11 + * Author: Niranjan H Y <niranjanhy@ti.com> 12 + * Author: Baojun Xu <baojun.xu@ti.com> 13 + */ 14 + #include <linux/workqueue.h> 15 + 16 + #ifndef __TAS2783_H__ 17 + #define __TAS2783_H__ 18 + 19 + #define TAS2783_DEVICE_RATES (SNDRV_PCM_RATE_44100 | \ 20 + SNDRV_PCM_RATE_48000 | \ 21 + SNDRV_PCM_RATE_96000 | \ 22 + SNDRV_PCM_RATE_88200) 23 + #define TAS2783_DEVICE_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ 24 + SNDRV_PCM_FMTBIT_S24_LE | \ 25 + SNDRV_PCM_FMTBIT_S32_LE) 26 + 27 + /* book, page, register */ 28 + #define TASDEV_REG_SDW(book, page, reg) (((book) * 256 * 128) + \ 29 + 0x800000 + ((page) * 128) + (reg)) 30 + 31 + /* Volume control */ 32 + #define TAS2783_DVC_LVL TASDEV_REG_SDW(0x0, 0x00, 0x1A) 33 + #define TAS2783_AMP_LEVEL TASDEV_REG_SDW(0x0, 0x00, 0x03) 34 + #define TAS2783_AMP_LEVEL_MASK GENMASK(5, 1) 35 + 36 + #define PRAM_ADDR_START TASDEV_REG_SDW(0x8c, 0x01, 0x8) 37 + #define PRAM_ADDR_END TASDEV_REG_SDW(0x8c, 0xff, 0x7f) 38 + #define YRAM_ADDR_START TASDEV_REG_SDW(0x00, 0x02, 0x8) 39 + #define YRAM_ADDR_END TASDEV_REG_SDW(0x00, 0x37, 0x7f) 40 + 41 + /* Calibration data */ 42 + #define TAS2783_CAL_R0 TASDEV_REG_SDW(0, 0x16, 0x4C) 43 + #define TAS2783_CAL_INVR0 TASDEV_REG_SDW(0, 0x16, 0x5C) 44 + #define TAS2783_CAL_R0LOW TASDEV_REG_SDW(0, 0x16, 0x64) 45 + #define TAS2783_CAL_POWER TASDEV_REG_SDW(0, 0x15, 0x44) 46 + #define TAS2783_CAL_TLIM TASDEV_REG_SDW(0, 0x17, 0x58) 47 + 48 + /* TAS2783 SDCA Control - function number */ 49 + #define FUNC_NUM_SMART_AMP 0x01 50 + 51 + /* TAS2783 SDCA entity */ 52 + 53 + #define TAS2783_SDCA_ENT_FU21 0x01 54 + #define TAS2783_SDCA_ENT_FU23 0x02 55 + #define TAS2783_SDCA_ENT_FU26 0x03 56 + #define TAS2783_SDCA_ENT_XU22 0x04 57 + #define TAS2783_SDCA_ENT_CS24 0x05 58 + #define TAS2783_SDCA_ENT_CS21 0x06 59 + #define TAS2783_SDCA_ENT_CS25 0x07 60 + #define TAS2783_SDCA_ENT_CS26 0x08 61 + #define TAS2783_SDCA_ENT_CS28 0x09 62 + #define TAS2783_SDCA_ENT_PDE23 0x0C 63 + #define TAS2783_SDCA_ENT_UDMPU23 0x0E 64 + #define TAS2783_SDCA_ENT_SAPU29 0x0F 65 + #define TAS2783_SDCA_ENT_PPU21 0x10 66 + #define TAS2783_SDCA_ENT_PPU26 0x11 67 + #define TAS2783_SDCA_ENT_TG23 0x12 68 + #define TAS2783_SDCA_ENT_IT21 0x13 69 + #define TAS2783_SDCA_ENT_IT29 0x14 70 + #define TAS2783_SDCA_ENT_IT26 0x15 71 + #define TAS2783_SDCA_ENT_IT28 0x16 72 + #define TAS2783_SDCA_ENT_OT24 0x17 73 + #define TAS2783_SDCA_ENT_OT23 0x18 74 + #define TAS2783_SDCA_ENT_OT25 0x19 75 + #define TAS2783_SDCA_ENT_OT28 0x1A 76 + #define TAS2783_SDCA_ENT_MU26 0x1b 77 + #define TAS2783_SDCA_ENT_OT127 0x1E 78 + #define TAS2783_SDCA_ENT_FU127 0x1F 79 + #define TAS2783_SDCA_ENT_CS127 0x20 80 + #define TAS2783_SDCA_ENT_MFPU21 0x22 81 + #define TAS2783_SDCA_ENT_MFPU26 0x23 82 + 83 + /* TAS2783 SDCA control */ 84 + #define TAS2783_SDCA_CTL_REQ_POW_STATE 0x01 85 + #define TAS2783_SDCA_CTL_FU_MUTE 0x01 86 + #define TAS2783_SDCA_CTL_UDMPU_CLUSTER 0x10 87 + 88 + #define TAS2783_DEVICE_CHANNEL_LEFT 1 89 + #define TAS2783_DEVICE_CHANNEL_RIGHT 2 90 + 91 + #define TAS2783_SDCA_POW_STATE_ON 0 92 + #define TAS2783_SDCA_POW_STATE_OFF 3 93 + 94 + /* calibration data */ 95 + #define TAS2783_CALIB_PARAMS 6 /* 5 + 1 unique id */ 96 + #define TAS2783_CALIB_MAX_SPK_COUNT 8 97 + #define TAS2783_CALIB_HDR_SZ 12 98 + #define TAS2783_CALIB_CRC_SZ 4 99 + #define TAS2783_CALIB_DATA_SZ ((TAS2783_CALIB_HDR_SZ) + TAS2783_CALIB_CRC_SZ + \ 100 + ((TAS2783_CALIB_PARAMS) * 4 * (TAS2783_CALIB_MAX_SPK_COUNT))) 101 + 102 + #if IS_ENABLED(CONFIG_SND_SOC_TAS2783_UTIL) 103 + int32_t tas25xx_register_misc(struct sdw_slave *peripheral); 104 + int32_t tas25xx_deregister_misc(void); 105 + #else 106 + static void tas25xx_register_misc(struct sdw_slave *peripheral) {} 107 + static void tas25xx_deregister_misc(void) {} 108 + #endif 109 + 110 + #endif /*__TAS2783_H__ */