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